HsOpenSSL 0.11.1.1 → 0.11.2
raw patch · 20 files changed
+263/−42 lines, 20 filesdep −old-localedep ~HUnitdep ~basedep ~timenew-uploaderPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies removed: old-locale
Dependency ranges changed: HUnit, base, time
API changes (from Hackage documentation)
- OpenSSL.Cipher: instance Eq Mode
- OpenSSL.Cipher: instance Show Mode
- OpenSSL.DH: instance Eq DHGen
- OpenSSL.DH: instance Ord DHGen
- OpenSSL.DH: instance Show DHGen
- OpenSSL.DSA: instance DSAKey DSAKeyPair
- OpenSSL.DSA: instance DSAKey DSAPubKey
- OpenSSL.DSA: instance Eq DSAKeyPair
- OpenSSL.DSA: instance Eq DSAPubKey
- OpenSSL.DSA: instance Ord DSAKeyPair
- OpenSSL.DSA: instance Ord DSAPubKey
- OpenSSL.DSA: instance Show DSAKeyPair
- OpenSSL.DSA: instance Show DSAPubKey
- OpenSSL.DSA: instance Typeable DSAKeyPair
- OpenSSL.DSA: instance Typeable DSAPubKey
- OpenSSL.EVP.PKey: instance Eq SomeKeyPair
- OpenSSL.EVP.PKey: instance Eq SomePublicKey
- OpenSSL.EVP.PKey: instance KeyPair DSAKeyPair
- OpenSSL.EVP.PKey: instance KeyPair RSAKeyPair
- OpenSSL.EVP.PKey: instance KeyPair SomeKeyPair
- OpenSSL.EVP.PKey: instance PKey DSAKeyPair
- OpenSSL.EVP.PKey: instance PKey DSAPubKey
- OpenSSL.EVP.PKey: instance PKey RSAKeyPair
- OpenSSL.EVP.PKey: instance PKey RSAPubKey
- OpenSSL.EVP.PKey: instance PKey SomeKeyPair
- OpenSSL.EVP.PKey: instance PKey SomePublicKey
- OpenSSL.EVP.PKey: instance PublicKey DSAKeyPair
- OpenSSL.EVP.PKey: instance PublicKey DSAPubKey
- OpenSSL.EVP.PKey: instance PublicKey RSAKeyPair
- OpenSSL.EVP.PKey: instance PublicKey RSAPubKey
- OpenSSL.EVP.PKey: instance PublicKey SomeKeyPair
- OpenSSL.EVP.PKey: instance PublicKey SomePublicKey
- OpenSSL.EVP.PKey: instance Typeable SomeKeyPair
- OpenSSL.EVP.PKey: instance Typeable SomePublicKey
- OpenSSL.EVP.Verify: instance Eq VerifyStatus
- OpenSSL.EVP.Verify: instance Show VerifyStatus
- OpenSSL.EVP.Verify: instance Typeable VerifyStatus
- OpenSSL.PKCS7: instance Eq Pkcs7Flag
- OpenSSL.PKCS7: instance Eq Pkcs7VerifyStatus
- OpenSSL.PKCS7: instance Show Pkcs7Flag
- OpenSSL.PKCS7: instance Show Pkcs7VerifyStatus
- OpenSSL.PKCS7: instance Typeable Pkcs7Flag
- OpenSSL.PKCS7: instance Typeable Pkcs7VerifyStatus
- OpenSSL.RSA: instance Eq RSAKeyPair
- OpenSSL.RSA: instance Eq RSAPubKey
- OpenSSL.RSA: instance Ord RSAKeyPair
- OpenSSL.RSA: instance Ord RSAPubKey
- OpenSSL.RSA: instance RSAKey RSAKeyPair
- OpenSSL.RSA: instance RSAKey RSAPubKey
- OpenSSL.RSA: instance Show RSAKeyPair
- OpenSSL.RSA: instance Show RSAPubKey
- OpenSSL.RSA: instance Typeable RSAKeyPair
- OpenSSL.RSA: instance Typeable RSAPubKey
- OpenSSL.Session: instance Eq ConnectionAbruptlyTerminated
- OpenSSL.Session: instance Eq ProtocolError
- OpenSSL.Session: instance Eq ShutdownType
- OpenSSL.Session: instance Eq a => Eq (SSLResult a)
- OpenSSL.Session: instance Exception ConnectionAbruptlyTerminated
- OpenSSL.Session: instance Exception ProtocolError
- OpenSSL.Session: instance Exception SomeSSLException
- OpenSSL.Session: instance Foldable SSLResult
- OpenSSL.Session: instance Functor SSLResult
- OpenSSL.Session: instance Show ConnectionAbruptlyTerminated
- OpenSSL.Session: instance Show ProtocolError
- OpenSSL.Session: instance Show ShutdownType
- OpenSSL.Session: instance Show SomeSSLException
- OpenSSL.Session: instance Show a => Show (SSLResult a)
- OpenSSL.Session: instance Traversable SSLResult
- OpenSSL.Session: instance Typeable ConnectionAbruptlyTerminated
- OpenSSL.Session: instance Typeable ProtocolError
- OpenSSL.Session: instance Typeable SSL
- OpenSSL.Session: instance Typeable SSLContext
- OpenSSL.Session: instance Typeable SSLResult
- OpenSSL.Session: instance Typeable ShutdownType
- OpenSSL.Session: instance Typeable SomeSSLException
- OpenSSL.Session: instance Typeable VerificationMode
- OpenSSL.Session: vpCallback :: VerificationMode -> Maybe (Bool -> X509StoreCtx -> IO Bool)
- OpenSSL.Session: vpClientOnce :: VerificationMode -> Bool
- OpenSSL.Session: vpFailIfNoPeerCert :: VerificationMode -> Bool
- OpenSSL.X509.Revocation: instance Eq RevokedCertificate
- OpenSSL.X509.Revocation: instance Show RevokedCertificate
- OpenSSL.X509.Revocation: instance Typeable RevokedCertificate
- OpenSSL.X509.Revocation: revRevocationDate :: RevokedCertificate -> UTCTime
- OpenSSL.X509.Revocation: revSerialNumber :: RevokedCertificate -> Integer
+ OpenSSL.Cipher: instance GHC.Classes.Eq OpenSSL.Cipher.Mode
+ OpenSSL.Cipher: instance GHC.Show.Show OpenSSL.Cipher.Mode
+ OpenSSL.DH: instance GHC.Classes.Eq OpenSSL.DH.DHGen
+ OpenSSL.DH: instance GHC.Classes.Ord OpenSSL.DH.DHGen
+ OpenSSL.DH: instance GHC.Show.Show OpenSSL.DH.DHGen
+ OpenSSL.DSA: instance GHC.Classes.Eq OpenSSL.DSA.DSAKeyPair
+ OpenSSL.DSA: instance GHC.Classes.Eq OpenSSL.DSA.DSAPubKey
+ OpenSSL.DSA: instance GHC.Classes.Ord OpenSSL.DSA.DSAKeyPair
+ OpenSSL.DSA: instance GHC.Classes.Ord OpenSSL.DSA.DSAPubKey
+ OpenSSL.DSA: instance GHC.Show.Show OpenSSL.DSA.DSAKeyPair
+ OpenSSL.DSA: instance GHC.Show.Show OpenSSL.DSA.DSAPubKey
+ OpenSSL.DSA: instance OpenSSL.DSA.DSAKey OpenSSL.DSA.DSAKeyPair
+ OpenSSL.DSA: instance OpenSSL.DSA.DSAKey OpenSSL.DSA.DSAPubKey
+ OpenSSL.EVP.Internal: cipherSetPadding :: CipherCtx -> Int -> IO CipherCtx
+ OpenSSL.EVP.PKey: instance GHC.Classes.Eq OpenSSL.EVP.PKey.SomeKeyPair
+ OpenSSL.EVP.PKey: instance GHC.Classes.Eq OpenSSL.EVP.PKey.SomePublicKey
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.Internal.PKey OpenSSL.DSA.DSAKeyPair
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.Internal.PKey OpenSSL.DSA.DSAPubKey
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.Internal.PKey OpenSSL.EVP.PKey.SomeKeyPair
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.Internal.PKey OpenSSL.EVP.PKey.SomePublicKey
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.Internal.PKey OpenSSL.RSA.RSAKeyPair
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.Internal.PKey OpenSSL.RSA.RSAPubKey
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.PKey.KeyPair OpenSSL.DSA.DSAKeyPair
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.PKey.KeyPair OpenSSL.EVP.PKey.SomeKeyPair
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.PKey.KeyPair OpenSSL.RSA.RSAKeyPair
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.PKey.PublicKey OpenSSL.DSA.DSAKeyPair
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.PKey.PublicKey OpenSSL.DSA.DSAPubKey
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.PKey.PublicKey OpenSSL.EVP.PKey.SomeKeyPair
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.PKey.PublicKey OpenSSL.EVP.PKey.SomePublicKey
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.PKey.PublicKey OpenSSL.RSA.RSAKeyPair
+ OpenSSL.EVP.PKey: instance OpenSSL.EVP.PKey.PublicKey OpenSSL.RSA.RSAPubKey
+ OpenSSL.EVP.Verify: instance GHC.Classes.Eq OpenSSL.EVP.Verify.VerifyStatus
+ OpenSSL.EVP.Verify: instance GHC.Show.Show OpenSSL.EVP.Verify.VerifyStatus
+ OpenSSL.PKCS7: instance GHC.Classes.Eq OpenSSL.PKCS7.Pkcs7Flag
+ OpenSSL.PKCS7: instance GHC.Classes.Eq OpenSSL.PKCS7.Pkcs7VerifyStatus
+ OpenSSL.PKCS7: instance GHC.Show.Show OpenSSL.PKCS7.Pkcs7Flag
+ OpenSSL.PKCS7: instance GHC.Show.Show OpenSSL.PKCS7.Pkcs7VerifyStatus
+ OpenSSL.RSA: fromDERPub :: ByteString -> Maybe RSAPubKey
+ OpenSSL.RSA: instance GHC.Classes.Eq OpenSSL.RSA.RSAKeyPair
+ OpenSSL.RSA: instance GHC.Classes.Eq OpenSSL.RSA.RSAPubKey
+ OpenSSL.RSA: instance GHC.Classes.Ord OpenSSL.RSA.RSAKeyPair
+ OpenSSL.RSA: instance GHC.Classes.Ord OpenSSL.RSA.RSAPubKey
+ OpenSSL.RSA: instance GHC.Show.Show OpenSSL.RSA.RSAKeyPair
+ OpenSSL.RSA: instance GHC.Show.Show OpenSSL.RSA.RSAPubKey
+ OpenSSL.RSA: instance OpenSSL.RSA.RSAKey OpenSSL.RSA.RSAKeyPair
+ OpenSSL.RSA: instance OpenSSL.RSA.RSAKey OpenSSL.RSA.RSAPubKey
+ OpenSSL.RSA: toDERPub :: RSAKey k => k -> ByteString
+ OpenSSL.Session: [vpCallback] :: VerificationMode -> Maybe (Bool -> X509StoreCtx -> IO Bool)
+ OpenSSL.Session: [vpClientOnce] :: VerificationMode -> Bool
+ OpenSSL.Session: [vpFailIfNoPeerCert] :: VerificationMode -> Bool
+ OpenSSL.Session: instance Data.Foldable.Foldable OpenSSL.Session.SSLResult
+ OpenSSL.Session: instance Data.Traversable.Traversable OpenSSL.Session.SSLResult
+ OpenSSL.Session: instance GHC.Base.Functor OpenSSL.Session.SSLResult
+ OpenSSL.Session: instance GHC.Classes.Eq OpenSSL.Session.ConnectionAbruptlyTerminated
+ OpenSSL.Session: instance GHC.Classes.Eq OpenSSL.Session.ProtocolError
+ OpenSSL.Session: instance GHC.Classes.Eq OpenSSL.Session.ShutdownType
+ OpenSSL.Session: instance GHC.Classes.Eq a => GHC.Classes.Eq (OpenSSL.Session.SSLResult a)
+ OpenSSL.Session: instance GHC.Exception.Exception OpenSSL.Session.ConnectionAbruptlyTerminated
+ OpenSSL.Session: instance GHC.Exception.Exception OpenSSL.Session.ProtocolError
+ OpenSSL.Session: instance GHC.Exception.Exception OpenSSL.Session.SomeSSLException
+ OpenSSL.Session: instance GHC.Show.Show OpenSSL.Session.ConnectionAbruptlyTerminated
+ OpenSSL.Session: instance GHC.Show.Show OpenSSL.Session.ProtocolError
+ OpenSSL.Session: instance GHC.Show.Show OpenSSL.Session.ShutdownType
+ OpenSSL.Session: instance GHC.Show.Show OpenSSL.Session.SomeSSLException
+ OpenSSL.Session: instance GHC.Show.Show a => GHC.Show.Show (OpenSSL.Session.SSLResult a)
+ OpenSSL.Session: setTlsextHostName :: SSL -> String -> IO ()
+ OpenSSL.X509: readDerX509 :: ByteString -> IO X509
+ OpenSSL.X509: writeDerX509 :: X509 -> IO ByteString
+ OpenSSL.X509.Request: addExtensions :: X509Req -> [(Int, String)] -> IO CInt
+ OpenSSL.X509.Request: writeX509ReqDER :: X509Req -> IO ByteString
+ OpenSSL.X509.Revocation: [revRevocationDate] :: RevokedCertificate -> UTCTime
+ OpenSSL.X509.Revocation: [revSerialNumber] :: RevokedCertificate -> Integer
+ OpenSSL.X509.Revocation: instance GHC.Classes.Eq OpenSSL.X509.Revocation.RevokedCertificate
+ OpenSSL.X509.Revocation: instance GHC.Show.Show OpenSSL.X509.Revocation.RevokedCertificate
Files
- ChangeLog +28/−0
- HsOpenSSL.cabal +34/−13
- OpenSSL/ASN1.hsc +0/−12
- OpenSSL/BN.hsc +1/−1
- OpenSSL/DH.hs +2/−1
- OpenSSL/DH/Internal.hs +5/−2
- OpenSSL/EVP/Base64.hs +2/−2
- OpenSSL/EVP/Cipher.hs +5/−2
- OpenSSL/EVP/Digest.hsc +3/−1
- OpenSSL/EVP/Internal.hsc +13/−0
- OpenSSL/EVP/Sign.hs +3/−1
- OpenSSL/RSA.hsc +35/−2
- OpenSSL/Session.hsc +19/−3
- OpenSSL/X509.hs +40/−0
- OpenSSL/X509/Request.hs +44/−0
- OpenSSL/X509/Store.hs +3/−1
- Test/OpenSSL/RSA.hs +14/−0
- cbits/HsOpenSSL.c +9/−0
- cbits/HsOpenSSL.h +1/−0
- examples/Makefile +2/−1
ChangeLog view
@@ -1,3 +1,31 @@+2016-10-04 Vladimir Shabanov <vshabanoff@gmail.com>++ * HsOpenSSL.cabal (Version): Bump version to 0.11.2++ * HsOpenSSL.cabal: New maintainer and GitHub repo path.++ * HsOpenSSL.cabal: removed old-locale dependency (requires time >= 1.5).++ * examples/Client.hs: Added client example, by @mirokuratczyk (#7).++ * OpenSSL/EVP/Internal.hsc: Added cipherSetPadding function,+ by @SX91 (#6).++ * OpenSSL/BN.hsc: prandInteger functions now use BN_pseudo_rand_range,+ by @Pamelloes (#5).++ * OpenSSL/RSA.hsc, OpenSSL/X509.hs, OpenSSL/X509/Request.hs, Test/OpenSSL/RSA.hs, HsOpenSSL.cabal:+ DER reading/writing for X509, X509Req & RSA,+ by @newsham, @shak-mar, @afcady (#4)++ * HsOpenSSL.cabal (Includes): Added openssl/asn1.h, by phadej (#3).++ * HsOpenSSL.cabal (Build-Depends): Bump HUnit upper bound,+ by phadej (#2).++ * 10 files: Fixed GHC 7.10 warnings,+ by Mikhail Glushenkov @23Skidoo (#1).+ 2015-01-06 PHO <pho@cielonegro.org> * HsOpenSSL.cabal (Version): Bump version to 0.11.1.1
HsOpenSSL.cabal view
@@ -12,17 +12,17 @@ <http://hackage.haskell.org/package/tls>, which is a pure Haskell implementation of SSL. .-Version: 0.11.1.1+Version: 0.11.2 License: PublicDomain License-File: COPYING Author: Adam Langley, Mikhail Vorozhtsov, PHO, Taru Karttunen-Maintainer: PHO <pho at cielonegro dot org>+Maintainer: Vladimir Shabanov <vshabanoff@gmail.com> Stability: stable-Homepage: https://github.com/phonohawk/HsOpenSSL-Bug-Reports: https://github.com/phonohawk/HsOpenSSL/issues+Homepage: https://github.com/vshabanov/HsOpenSSL+Bug-Reports: https://github.com/vshabanov/HsOpenSSL/issues Category: Cryptography Tested-With: GHC == 7.6.2-Cabal-Version: >= 1.8+Cabal-Version: >= 1.10 Build-Type: Simple Extra-Source-Files: AUTHORS@@ -40,7 +40,7 @@ Source-Repository head Type: git- Location: git://github.com/phonohawk/HsOpenSSL.git+ Location: git://github.com/vshabanov/HsOpenSSL.git Flag fast-bignum Description:@@ -53,10 +53,7 @@ base == 4.*, bytestring >= 0.9 && < 0.11, network >= 2.1 && < 2.7,- old-locale >= 1.0 && < 1.1,- time >= 1.1.1 && < 1.6- -- old-locale is only needed if time < 1.5, but Cabal does not- -- allow us to express conditional dependencies like this.+ time >= 1.5 && < 1.7 if flag(fast-bignum) CPP-Options: -DFAST_BIGNUM@@ -64,6 +61,7 @@ -- TODO: integer-gmp >= 1 is not supported yet. -- https://github.com/phonohawk/HsOpenSSL/issues/36 Build-Depends: integer-gmp >= 0.2 && < 1+ -- Doesn't work since GHC 7.10.1 (integer-gmp-1.0.0.0) else Build-Depends: ghc-prim, integer @@ -113,23 +111,29 @@ OpenSSL.Utils OpenSSL.X509.Name OpenSSL.DH.Internal+ Default-Language:+ Haskell2010 GHC-Options: -Wall C-Sources: cbits/HsOpenSSL.c Include-Dirs: cbits+ Includes:+ openssl/asn1.h Test-Suite test-cipher Type: exitcode-stdio-1.0 Main-Is: Test/OpenSSL/Cipher.hs Build-Depends: HsOpenSSL,- HUnit >= 1.0 && < 1.3,+ HUnit >= 1.0 && < 1.4, base == 4.*, bytestring >= 0.9 && < 0.11, test-framework >= 0.8 && < 0.9, test-framework-hunit >= 0.3 && < 0.4+ Default-Language:+ Haskell2010 GHC-Options: -Wall @@ -138,23 +142,40 @@ Main-Is: Test/OpenSSL/DSA.hs Build-Depends: HsOpenSSL,- HUnit >= 1.0 && < 1.3,+ HUnit >= 1.0 && < 1.4, base == 4.*, bytestring >= 0.9 && < 0.11, test-framework >= 0.8 && < 0.9, test-framework-hunit >= 0.3 && < 0.4+ Default-Language:+ Haskell2010 GHC-Options: -Wall +Test-Suite test-rsa+ Type: exitcode-stdio-1.0+ Main-Is: Test/OpenSSL/RSA.hs+ Build-Depends:+ HsOpenSSL,+ HUnit >= 1.0 && < 1.4,+ base == 4.*,+ bytestring >= 0.9 && < 0.11,+ test-framework >= 0.8 && < 0.9,+ test-framework-hunit >= 0.3 && < 0.4+ GHC-Options:+ -Wall+ Test-Suite test-evp-base64 Type: exitcode-stdio-1.0 Main-Is: Test/OpenSSL/EVP/Base64.hs Build-Depends: HsOpenSSL,- HUnit >= 1.0 && < 1.3,+ HUnit >= 1.0 && < 1.4, base == 4.*, bytestring >= 0.9 && < 0.11, test-framework >= 0.8 && < 0.9, test-framework-hunit >= 0.3 && < 0.4+ Default-Language:+ Haskell2010 GHC-Options: -Wall
OpenSSL/ASN1.hsc view
@@ -28,9 +28,6 @@ import OpenSSL.BIO import OpenSSL.BN import OpenSSL.Utils-#if !MIN_VERSION_time(1,5,0)-import System.Locale-#endif {- ASN1_OBJECT --------------------------------------------------------------- -} @@ -128,11 +125,7 @@ _ASN1_TIME_print bioPtr time >>= failIf_ (/= 1) timeStr <- bioRead bio-#if MIN_VERSION_time(1,5,0) case parseTimeM True locale "%b %e %H:%M:%S %Y %Z" timeStr of-#else- case parseTime locale "%b %e %H:%M:%S %Y %Z" timeStr of-#endif Just utc -> return utc Nothing -> fail ("peekASN1Time: failed to parse time string: " ++ timeStr) where@@ -144,17 +137,12 @@ , "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ] ]-#if !MIN_VERSION_time(1,5,0)- , intervals = undefined-#endif , amPm = undefined , dateTimeFmt = undefined , dateFmt = undefined , timeFmt = undefined , time12Fmt = undefined-#if MIN_VERSION_time(1,5,0) , knownTimeZones = []-#endif }
OpenSSL/BN.hsc view
@@ -339,7 +339,7 @@ prandIntegerUptoNMinusOneSuchThat f range = withBN range (\bnRange -> (do r <- newBN 0 let try = do- _BN_rand_range (unwrapBN r) (unwrapBN bnRange) >>= failIf_ (/= 1)+ _BN_pseudo_rand_range (unwrapBN r) (unwrapBN bnRange) >>= failIf_ (/= 1) i <- bnToInteger r if f i then return i
OpenSSL/DH.hs view
@@ -17,7 +17,9 @@ import Data.Word (Word8) import Data.ByteString (ByteString) import qualified Data.ByteString.Internal as BS+#if !MIN_VERSION_base(4,8,0) import Control.Applicative ((<$>))+#endif import Foreign.Ptr (Ptr, nullPtr) #if MIN_VERSION_base(4,5,0) import Foreign.C.Types (CInt(..))@@ -96,4 +98,3 @@ _DH_get_pub_key :: Ptr DH_ -> IO (Ptr BIGNUM) foreign import ccall unsafe "HsOpenSSL_DH_length" _DH_length :: Ptr DH_ -> IO CInt-
OpenSSL/DH/Internal.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE ForeignFunctionInterface #-} module OpenSSL.DH.Internal (@@ -14,11 +15,14 @@ asDHP ) where -import Control.Applicative ((<$>)) import Foreign.Ptr (Ptr) import Foreign.ForeignPtr (ForeignPtr, withForeignPtr) import qualified Foreign.Concurrent as FC +#if !MIN_VERSION_base(4,8,0)+import Control.Applicative ((<$>))+#endif+ data DH_ newtype DHP = DHP (ForeignPtr DH_) @@ -50,4 +54,3 @@ foreign import ccall "DH_free" _DH_free :: Ptr DH_ -> IO ()-
OpenSSL/EVP/Base64.hs view
@@ -93,7 +93,7 @@ remain = if B8.null leftover then remain' else- L8.fromChunks [leftover] `L8.append` remain'+ L8.fromChunks [leftover] `L8.append` remain' encodedBlock = encodeBlock block encodedRemain = encodeBase64LBS remain in@@ -143,7 +143,7 @@ remain = if B8.null leftover then remain' else- L8.fromChunks [leftover] `L8.append` remain'+ L8.fromChunks [leftover] `L8.append` remain' decodedBlock = decodeBlock block decodedRemain = decodeBase64LBS remain in
OpenSSL/EVP/Cipher.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-} -- |An interface to symmetric cipher algorithms. module OpenSSL.EVP.Cipher@@ -15,12 +16,15 @@ where import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy.Char8 as L8-import Data.Monoid import Foreign import Foreign.C import OpenSSL.Objects import OpenSSL.EVP.Internal +#if !MIN_VERSION_base(4,8,0)+import Data.Monoid+#endif+ foreign import ccall unsafe "EVP_get_cipherbyname" _get_cipherbyname :: CString -> IO (Ptr EVP_CIPHER) @@ -93,4 +97,3 @@ cipherLBS c key iv mode input = do ctx <- cipherInitBS c key iv mode cipherLazily ctx input-
OpenSSL/EVP/Digest.hsc view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-} -- |An interface to message digest algorithms. module OpenSSL.EVP.Digest@@ -18,7 +19,9 @@ import Data.ByteString.Unsafe (unsafeUseAsCStringLen) import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy.Char8 as L8+#if !MIN_VERSION_base(4,8,0) import Control.Applicative ((<$>))+#endif import Foreign.C.String (CString, withCString) #if MIN_VERSION_base(4,5,0) import Foreign.C.Types (CChar(..), CInt(..), CSize(..), CUInt(..))@@ -118,4 +121,3 @@ -> Ptr CChar -> CInt -> CInt -> CInt -> Ptr CChar -> IO CInt-
OpenSSL/EVP/Internal.hsc view
@@ -14,6 +14,7 @@ withNewCipherCtxPtr, CryptoMode(..),+ cipherSetPadding, cipherInitBS, cipherUpdateBS, cipherFinalBS,@@ -52,7 +53,9 @@ import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy.Char8 as L8 import qualified Data.ByteString.Lazy.Internal as L8+#if !MIN_VERSION_base(4,8,0) import Control.Applicative ((<$>))+#endif import Control.Exception (mask, mask_, bracket_, onException) import Foreign.C.Types (CChar) #if MIN_VERSION_base(4,5,0)@@ -131,6 +134,16 @@ fromCryptoMode :: Num a => CryptoMode -> a fromCryptoMode Encrypt = 1 fromCryptoMode Decrypt = 0++foreign import ccall unsafe "EVP_CIPHER_CTX_set_padding"+ _SetPadding :: Ptr EVP_CIPHER_CTX -> CInt -> IO CInt++cipherSetPadding :: CipherCtx -> Int -> IO CipherCtx+cipherSetPadding ctx pad + = do withCipherCtxPtr ctx $ \ctxPtr ->+ _SetPadding ctxPtr (fromIntegral pad)+ >>= failIf_ (/= 1)+ return ctx foreign import ccall unsafe "EVP_CipherInit" _CipherInit :: Ptr EVP_CIPHER_CTX
OpenSSL/EVP/Sign.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-} -- |Message signing using asymmetric cipher and message digest -- algorithm. This is an opposite of "OpenSSL.EVP.Verify".@@ -10,7 +11,9 @@ import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Internal as B8 import qualified Data.ByteString.Lazy.Char8 as L8+#if !MIN_VERSION_base(4,8,0) import Control.Applicative ((<$>))+#endif import Foreign import Foreign.C import OpenSSL.EVP.Digest@@ -64,4 +67,3 @@ = do ctx <- digestLazily md input sig <- signFinal ctx pkey return $ L8.fromChunks [sig]-
OpenSSL/RSA.hsc view
@@ -24,19 +24,28 @@ , rsaIQMP , rsaCopyPublic , rsaKeyPairFinalize -- private+ -- * DER encoding+ , fromDERPub+ , toDERPub ) where #include "HsOpenSSL.h" import Control.Monad+import Data.ByteString (ByteString)+import qualified Data.ByteString as B (useAsCStringLen)+import qualified Data.ByteString.Internal as BI (createAndTrim) import Data.Typeable+import Foreign.C.String (CString) #if MIN_VERSION_base(4,5,0)-import Foreign.C.Types (CInt(..))+import Foreign.C.Types (CInt(..), CLong(..)) #else-import Foreign.C.Types (CInt)+import Foreign.C.Types (CInt, CLong) #endif import Foreign.ForeignPtr (ForeignPtr, finalizeForeignPtr, newForeignPtr, withForeignPtr)+import Foreign.Marshal.Alloc (alloca) import Foreign.Ptr (FunPtr, Ptr, freeHaskellFunPtr, nullFunPtr, nullPtr) import Foreign.Storable (Storable(..))+import GHC.Word (Word8) import OpenSSL.BN import OpenSSL.Utils import System.IO.Unsafe (unsafePerformIO)@@ -233,6 +242,30 @@ rsaIQMP :: RSAKeyPair -> Maybe Integer rsaIQMP = peekMI (#peek RSA, iqmp) +{- DER encoding ------------------------------------------------------------- -}++foreign import ccall unsafe "d2i_RSAPublicKey"+ _fromDERPub :: Ptr (Ptr RSA) -> Ptr CString -> CLong -> IO (Ptr RSA)++foreign import ccall unsafe "i2d_RSAPublicKey"+ _toDERPub :: Ptr RSA -> Ptr (Ptr Word8) -> IO CInt++-- |Parse a public key from ASN.1 DER format+fromDERPub :: ByteString -> Maybe RSAPubKey+fromDERPub bs = unsafePerformIO . usingConvedBS $ \(csPtr, ci) -> do+ rsaPtr <- _fromDERPub nullPtr csPtr ci+ if rsaPtr == nullPtr then return Nothing else absorbRSAPtr rsaPtr+ where usingConvedBS io = B.useAsCStringLen bs $ \(cs, len) ->+ alloca $ \csPtr -> poke csPtr cs >> io (csPtr, fromIntegral len)++-- |Dump a public key to ASN.1 DER format+toDERPub :: RSAKey k => k -> ByteString+toDERPub k = unsafePerformIO $ do+ requiredSize <- withRSAPtr k $ flip _toDERPub nullPtr+ BI.createAndTrim (fromIntegral requiredSize) $ \ptr ->+ alloca $ \pptr ->+ (fromIntegral <$>) $ withRSAPtr k $ \key ->+ poke pptr ptr >> _toDERPub key pptr {- instances ---------------------------------------------------------------- -}
OpenSSL/Session.hsc view
@@ -37,6 +37,7 @@ , fdConnection , addOption , removeOption+ , setTlsextHostName , accept , tryAccept , connect@@ -78,11 +79,10 @@ import Control.Concurrent (threadWaitWrite, threadWaitRead, runInBoundThread) import Control.Concurrent.MVar import Control.Exception-import Control.Applicative ((<$>), (<$)) import Control.Monad (unless)+import Data.Foldable (mapM_, forM_)+import Data.Traversable (mapM) import Data.Typeable-import Data.Foldable (Foldable, mapM_, forM_)-import Data.Traversable (Traversable, mapM) import Data.Maybe (fromMaybe) import Data.IORef import Foreign@@ -96,6 +96,12 @@ import System.Posix.Types (Fd(..)) import Network.Socket (Socket(..)) +#if !MIN_VERSION_base(4,8,0)+import Control.Applicative ((<$>), (<$))+import Data.Foldable (Foldable)+import Data.Traversable (Traversable)+#endif+ import OpenSSL.ERR import OpenSSL.EVP.PKey import OpenSSL.EVP.Internal@@ -379,6 +385,9 @@ foreign import ccall unsafe "HsOpenSSL_SSL_clear_options" _SSL_clear_options :: Ptr SSL_ -> CLong -> IO CLong +foreign import ccall unsafe "HsOpenSSL_SSL_set_tlsext_host_name"+ _SSL_set_tlsext_host_name :: Ptr SSL_ -> CString -> IO CLong+ -- | Add a protocol option to the SSL connection. addOption :: SSL -> SSLOption -> IO () addOption ssl opt =@@ -390,6 +399,13 @@ removeOption ssl opt = withSSL ssl $ \sslPtr -> _SSL_clear_options sslPtr (optionToIntegral opt) >> return ()++-- | Set host name for Server Name Indication (SNI)+setTlsextHostName :: SSL -> String -> IO ()+setTlsextHostName ssl h =+ withSSL ssl $ \sslPtr ->+ withCString h $ \ hPtr ->+ _SSL_set_tlsext_host_name sslPtr hPtr >> return () foreign import ccall "SSL_accept" _ssl_accept :: Ptr SSL_ -> IO CInt foreign import ccall "SSL_connect" _ssl_connect :: Ptr SSL_ -> IO CInt
OpenSSL/X509.hs view
@@ -16,6 +16,8 @@ , unsafeX509ToPtr -- private , touchX509 -- private + , writeDerX509+ , readDerX509 , compareX509 , signX509@@ -68,6 +70,7 @@ import OpenSSL.Utils import OpenSSL.Stack import OpenSSL.X509.Name+import Data.ByteString.Lazy (ByteString) -- |@'X509'@ is an opaque object that represents X.509 certificate. newtype X509 = X509 (ForeignPtr X509_)@@ -140,6 +143,16 @@ foreign import ccall unsafe "X509_verify" _verify :: Ptr X509_ -> Ptr EVP_PKEY -> IO CInt +foreign import ccall safe "i2d_X509_bio"+ _write_bio_X509 :: Ptr BIO_+ -> Ptr X509_+ -> IO CInt++foreign import ccall safe "d2i_X509_bio"+ _read_bio_X509 :: Ptr BIO_+ -> Ptr (Ptr X509_)+ -> IO (Ptr X509_)+ -- |@'newX509'@ creates an empty certificate. You must set the -- following properties to and sign it (see 'signX509') to actually -- use the certificate.@@ -178,6 +191,33 @@ touchX509 :: X509 -> IO () touchX509 (X509 x509) = touchForeignPtr x509++writeX509' :: BIO -> X509 -> IO ()+writeX509' bio x509+ = withBioPtr bio $ \ bioPtr ->+ withX509Ptr x509 $ \ x509Ptr ->+ _write_bio_X509 bioPtr x509Ptr+ >>= failIf (< 0)+ >> return ()++-- |@'writeDerX509' cert@ writes an X.509 certificate to DER string.+writeDerX509 :: X509 -> IO ByteString+writeDerX509 x509+ = do mem <- newMem+ writeX509' mem x509+ bioReadLBS mem++readX509' :: BIO -> IO X509+readX509' bio+ = withBioPtr bio $ \ bioPtr ->+ _read_bio_X509 bioPtr nullPtr + >>= failIfNull+ >>= wrapX509 ++-- |@'readDerX509' der@ reads in a certificate.+readDerX509 :: ByteString -> IO X509+readDerX509 derStr+ = newConstMemLBS derStr >>= readX509' -- |@'compareX509' cert1 cert2@ compares two certificates. compareX509 :: X509 -> X509 -> IO Ordering
OpenSSL/X509/Request.hs view
@@ -16,6 +16,7 @@ , verifyX509Req , printX509Req+ , writeX509ReqDER , makeX509FromReq @@ -28,6 +29,8 @@ , getPublicKey , setPublicKey++ , addExtensions ) where @@ -44,12 +47,15 @@ import OpenSSL.X509 (X509) import qualified OpenSSL.X509 as Cert import OpenSSL.X509.Name+import Data.ByteString.Lazy (ByteString)+import OpenSSL.Stack -- |@'X509Req'@ is an opaque object that represents PKCS#10 -- certificate request. newtype X509Req = X509Req (ForeignPtr X509_REQ) data X509_REQ +data X509_EXT foreign import ccall unsafe "X509_REQ_new" _new :: IO (Ptr X509_REQ)@@ -66,6 +72,9 @@ foreign import ccall unsafe "X509_REQ_print" _print :: Ptr BIO_ -> Ptr X509_REQ -> IO CInt +foreign import ccall unsafe "i2d_X509_REQ_bio"+ _req_to_der :: Ptr BIO_ -> Ptr X509_REQ -> IO CInt+ foreign import ccall unsafe "HsOpenSSL_X509_REQ_get_version" _get_version :: Ptr X509_REQ -> IO CLong @@ -84,6 +93,13 @@ foreign import ccall unsafe "X509_REQ_set_pubkey" _set_pubkey :: Ptr X509_REQ -> Ptr EVP_PKEY -> IO CInt +foreign import ccall unsafe "X509V3_EXT_nconf_nid"+ _ext_create :: Ptr a -> Ptr b -> CInt -> CString -> IO (Ptr X509_EXT)++foreign import ccall unsafe "X509_REQ_add_extensions"+ _req_add_extensions :: Ptr X509_REQ -> Ptr STACK -> IO CInt++ -- |@'newX509Req'@ creates an empty certificate request. You must set -- the following properties to and sign it (see 'signX509Req') to -- actually use the certificate request.@@ -152,6 +168,19 @@ >>= failIf_ (/= 1) bioRead mem +{- DER encoding ------------------------------------------------------------- -}++-- |@'writeX509ReqDER' req@ writes a PKCS#10 certificate request to DER string.+writeX509ReqDER :: X509Req -> IO ByteString+writeX509ReqDER req+ = do mem <- newMem+ withBioPtr mem $ \ memPtr ->+ withX509ReqPtr req $ \ reqPtr ->+ _req_to_der memPtr reqPtr+ >>= failIf_ (< 0)+ bioReadLBS mem++ -- |@'getVersion' req@ returns the version number of certificate -- request. getVersion :: X509Req -> IO Int@@ -209,6 +238,21 @@ _set_pubkey reqPtr pkeyPtr >>= failIf (/= 1) >> return ()+++-- |@'addExtensions' req [(nid, str)]@+--+-- E.g., nid 85 = 'subjectAltName' http://osxr.org:8080/openssl/source/crypto/objects/objects.h#0476+--+-- (TODO: more docs; NID type)+addExtensions :: X509Req -> [(Int, String)] -> IO CInt+addExtensions req exts =+ withX509ReqPtr req $ \reqPtr -> do+ extPtrs <- forM exts make+ withStack extPtrs $ _req_add_extensions reqPtr++ where+ make (nid, str) = withCString str $ _ext_create nullPtr nullPtr (fromIntegral nid) -- |@'makeX509FromReq' req cert@ creates an empty X.509 certificate
OpenSSL/X509/Store.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE CPP #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE ForeignFunctionInterface #-} {-# OPTIONS_HADDOCK prune #-}@@ -26,7 +27,9 @@ , getStoreCtxChain ) where+#if !MIN_VERSION_base(4,8,0) import Control.Applicative ((<$>))+#endif import Control.Exception (throwIO, mask_) import Foreign import Foreign.C@@ -142,4 +145,3 @@ getStoreCtxChain ctx = withX509StoreCtxPtr ctx $ \pCtx -> do stack <- _store_ctx_get_chain pCtx (`mapStack` stack) $ \pCert -> mask_ $ _x509_ref pCert >> wrapX509 pCert-
+ Test/OpenSSL/RSA.hs view
@@ -0,0 +1,14 @@+module Main (main) where+import OpenSSL.RSA+import qualified Test.Framework as TF+import qualified Test.Framework.Providers.HUnit as TF+import Test.HUnit++test_encodeDecodeEqual :: Test+test_encodeDecodeEqual = TestCase $ do+ keyPair <- generateRSAKey 1024 3 Nothing+ pubKey <- rsaCopyPublic keyPair+ assertEqual "encodeDecode" (Just pubKey) (fromDERPub (toDERPub keyPair))++main :: IO ()+main = TF.defaultMain $ TF.hUnitTestToTests test_encodeDecodeEqual
cbits/HsOpenSSL.c view
@@ -282,6 +282,15 @@ return SSL_set_options(ssl, options); } +/* OpenSSL < 1.0.0 does not have SSL_set_tlsext_host_name() */+long HsOpenSSL_SSL_set_tlsext_host_name(SSL* ssl, char* host_name) {+#if defined(SSL_set_tlsext_host_name)+ return SSL_set_tlsext_host_name(ssl, host_name);+#else+ return 0;+#endif+}+ /* OpenSSL < 0.9.8m does not have SSL_clear_options() */ long HsOpenSSL_SSL_clear_options(SSL* ssl, long options) { #if defined(SSL_clear_options)
cbits/HsOpenSSL.h view
@@ -93,5 +93,6 @@ long HsOpenSSL_SSL_CTX_clear_options(SSL_CTX* ctx, long options); long HsOpenSSL_SSL_set_options(SSL* ssl, long options); long HsOpenSSL_SSL_clear_options(SSL* ssl, long options);+long HsOpenSSL_SSL_set_tlsext_host_name(SSL* ssl, char* host_name); #endif
examples/Makefile view
@@ -5,12 +5,13 @@ ghc $(GHCFLAGS) --make HelloWorld ghc $(GHCFLAGS) --make PKCS7 ghc $(GHCFLAGS) --make -threaded Server+ ghc $(GHCFLAGS) --make Client run: build ./PKCS7 # ./HelloWorld clean:- rm -f HelloWorld GenRSAKey PKCS7 Server *.hi *.o+ rm -f HelloWorld GenRSAKey PKCS7 Server Client *.hi *.o .PHONY: build run clean