Skip to content
Browse files

I think I have entirely written the document.

darcs-hash:20070704165813-62b54-9f54272f65ceafd80add86cb0be18b6d6cc59065.gz
  • Loading branch information...
1 parent 2fb4c2a commit 2e1ce267a00f40b2fbc7d95e9e83ba811ab39a00 @phonohawk committed Jul 5, 2007
View
17 OpenSSL.hsc
@@ -22,8 +22,8 @@
-- [/Key generation of DSA and Diffie-Hellman algorithms/] Only RSA
-- keys can currently be generated.
--
--- [/X.509 certificate handling/] No operations related to X.509 are
--- currently supported. They should be supported in the future.
+-- [/X.509 v3 extension handling/] It shoule be supported in the
+-- future.
--
-- [/HMAC message authentication/]
--
@@ -33,21 +33,16 @@
-- [/pseudo-random number generator/] rand(3) functionalities are
-- uncovered, but OpenSSL works very well by default.
--
--- [/API to ASN.1, PKCS\#7 and PKCS\#12 functionalities/] They
--- should be covered someday, but there seems no documents for those
--- APIs.
+-- [/API to PKCS\#12 functionality/] It should be covered someday.
--
--- [/BIO/] BIO isn't needed because we are Haskell hackers.
+-- [/BIO/] BIO isn't needed because we are Haskell hackers. Though
+-- HsOpenSSL itself uses BIO internally.
--
-- [/ENGINE cryptographic module/] The default implementations work
-- very well, don't they?
--
--- [/bn(3), buffer(3), lhash(3), objects(3), stack(3) and txt_db(3)/]
--- These internal functions are rarely used by application
--- programmers.
---
-- So if you find out some features you want aren't supported, you
--- must write your own patch. Happy hacking.
+-- must write your own patch (then please. Happy hacking.
#include "HsOpenSSL.h"
View
4 OpenSSL/ASN1.hsc
@@ -1,5 +1,9 @@
{- -*- haskell -*- -}
+
+-- #hide
+
#include "HsOpenSSL.h"
+
module OpenSSL.ASN1
( ASN1_OBJECT
, obj2nid
View
4 OpenSSL/BIO.hsc
@@ -90,11 +90,11 @@ import System.IO.Unsafe
{- bio ---------------------------------------------------------------------- -}
-data BIO_METHOD = BIO_METHOD
+data BIO_METHOD
-- |@BIO@ is a @ForeignPtr@ to an opaque BIO object. They are created by newXXX actions.
newtype BIO = BIO (ForeignPtr BIO_)
-data BIO_ = BIO_
+data BIO_
foreign import ccall unsafe "BIO_new"
_new :: Ptr BIO_METHOD -> IO (Ptr BIO_)
View
26 OpenSSL/EVP/Base64.hsc
@@ -1,10 +1,16 @@
{- -*- haskell -*- -}
+
+-- |An interface to Base64 codec.
+
#include "HsOpenSSL.h"
+
module OpenSSL.EVP.Base64
- ( encodeBase64
+ ( -- * Encoding
+ encodeBase64
, encodeBase64BS
, encodeBase64LBS
+ -- * Decoding
, decodeBase64
, decodeBase64BS
, decodeBase64LBS
@@ -53,14 +59,19 @@ encodeBlock inBS
inputLen = B.length inBS
+-- |@'encodeBase64' str@ lazilly encodes a stream of data to
+-- Base64. The string doesn't have to be finite. Note that the string
+-- must not contain any letters which aren't in the range of U+0000 -
+-- U+00FF.
encodeBase64 :: String -> String
encodeBase64 = L8.unpack . encodeBase64LBS . L8.pack
-
+-- |@'encodeBase64BS' bs@ strictly encodes a chunk of data to Base64.
encodeBase64BS :: ByteString -> ByteString
encodeBase64BS = encodeBlock
-
+-- |@'encodeBase64LBS' lbs@ lazilly encodes a stream of data to
+-- Base64. The string doesn't have to be finite.
encodeBase64LBS :: LazyByteString -> LazyByteString
encodeBase64LBS inLBS
| L8.null inLBS = L8.empty
@@ -98,15 +109,18 @@ decodeBlock inBS
createAndTrim (B.length inBS) $ \ outBuf ->
_DecodeBlock (unsafeCoercePtr outBuf) inBuf inLen
-
+-- |@'decodeBase64' str@ lazilly decodes a stream of data from
+-- Base64. The string doesn't have to be finite.
decodeBase64 :: String -> String
decodeBase64 = L8.unpack . decodeBase64LBS . L8.pack
-
+-- |@'decodeBase64BS' bs@ strictly decodes a chunk of data from
+-- Base64.
decodeBase64BS :: ByteString -> ByteString
decodeBase64BS = decodeBlock
-
+-- |@'decodeBase64LBS' lbs@ lazilly decodes a stream of data from
+-- Base64. The string doesn't have to be finite.
decodeBase64LBS :: LazyByteString -> LazyByteString
decodeBase64LBS inLBS
| L8.null inLBS = L8.empty
View
116 OpenSSL/EVP/Cipher.hsc
@@ -1,17 +1,23 @@
{- -*- haskell -*- -}
+
+-- #prune
+
+-- |An interface to symmetric cipher algorithms.
+
#include "HsOpenSSL.h"
+
module OpenSSL.EVP.Cipher
- ( EvpCipher
- , EVP_CIPHER
- , withCipherPtr
+ ( Cipher
+ , EVP_CIPHER -- private
+ , withCipherPtr -- private
, getCipherByName
, getCipherNames
, cipherIvLength -- private
- , EvpCipherCtx
- , EVP_CIPHER_CTX
+ , CipherCtx -- private
+ , EVP_CIPHER_CTX -- private
, newCtx -- private
, withCipherCtxPtr -- private
@@ -40,8 +46,10 @@ import System.IO.Unsafe
{- EVP_CIPHER ---------------------------------------------------------------- -}
-newtype EvpCipher = EvpCipher (Ptr EVP_CIPHER)
-data EVP_CIPHER = EVP_CIPHER
+-- |@Cipher@ is an opaque object that represents an algorithm of
+-- symmetric cipher.
+newtype Cipher = Cipher (Ptr EVP_CIPHER)
+data EVP_CIPHER
foreign import ccall unsafe "EVP_get_cipherbyname"
@@ -52,32 +60,35 @@ foreign import ccall unsafe "HsOpenSSL_EVP_CIPHER_iv_length"
_iv_length :: Ptr EVP_CIPHER -> Int
-withCipherPtr :: EvpCipher -> (Ptr EVP_CIPHER -> IO a) -> IO a
-withCipherPtr (EvpCipher cipher) f = f cipher
-
+withCipherPtr :: Cipher -> (Ptr EVP_CIPHER -> IO a) -> IO a
+withCipherPtr (Cipher cipher) f = f cipher
-getCipherByName :: String -> IO (Maybe EvpCipher)
+-- |@'getCipherByName' name@ returns a symmetric cipher algorithm
+-- whose name is @name@. If no algorithms are found, the result is
+-- @Nothing@.
+getCipherByName :: String -> IO (Maybe Cipher)
getCipherByName name
= withCString name $ \ namePtr ->
do ptr <- _get_cipherbyname namePtr
if ptr == nullPtr then
return Nothing
else
- return $ Just $ EvpCipher ptr
-
+ return $ Just $ Cipher ptr
+-- |@'getCipherNames'@ returns a list of name of symmetric cipher
+-- algorithms.
getCipherNames :: IO [String]
getCipherNames = getObjNames CipherMethodType True
-cipherIvLength :: EvpCipher -> Int
-cipherIvLength (EvpCipher cipher) = _iv_length cipher
+cipherIvLength :: Cipher -> Int
+cipherIvLength (Cipher cipher) = _iv_length cipher
{- EVP_CIPHER_CTX ------------------------------------------------------------ -}
-newtype EvpCipherCtx = EvpCipherCtx (ForeignPtr EVP_CIPHER_CTX)
-data EVP_CIPHER_CTX = EVP_CIPHER_CTX
+newtype CipherCtx = CipherCtx (ForeignPtr EVP_CIPHER_CTX)
+data EVP_CIPHER_CTX
foreign import ccall unsafe "EVP_CIPHER_CTX_init"
@@ -90,22 +101,22 @@ foreign import ccall unsafe "HsOpenSSL_EVP_CIPHER_CTX_block_size"
_ctx_block_size :: Ptr EVP_CIPHER_CTX -> Int
-newCtx :: IO EvpCipherCtx
+newCtx :: IO CipherCtx
newCtx = do ctx <- mallocForeignPtrBytes (#size EVP_CIPHER_CTX)
withForeignPtr ctx $ \ ctxPtr ->
_ctx_init ctxPtr
addForeignPtrFinalizer _ctx_cleanup ctx
- return $ EvpCipherCtx ctx
+ return $ CipherCtx ctx
-withCipherCtxPtr :: EvpCipherCtx -> (Ptr EVP_CIPHER_CTX -> IO a) -> IO a
-withCipherCtxPtr (EvpCipherCtx ctx) = withForeignPtr ctx
+withCipherCtxPtr :: CipherCtx -> (Ptr EVP_CIPHER_CTX -> IO a) -> IO a
+withCipherCtxPtr (CipherCtx ctx) = withForeignPtr ctx
{- encrypt/decrypt ----------------------------------------------------------- -}
-data CryptoMode = Encrypt
- | Decrypt
+-- |@CryptoMode@ represents instruction to 'cipher' and such like.
+data CryptoMode = Encrypt | Decrypt
foreign import ccall unsafe "EVP_CipherInit"
@@ -123,8 +134,8 @@ cryptoModeToInt Encrypt = 1
cryptoModeToInt Decrypt = 0
-cipherInit :: EvpCipher -> String -> String -> CryptoMode -> IO EvpCipherCtx
-cipherInit (EvpCipher c) key iv mode
+cipherInit :: Cipher -> String -> String -> CryptoMode -> IO CipherCtx
+cipherInit (Cipher c) key iv mode
= do ctx <- newCtx
withCipherCtxPtr ctx $ \ ctxPtr ->
withCString key $ \ keyPtr ->
@@ -134,7 +145,7 @@ cipherInit (EvpCipher c) key iv mode
return ctx
-cipherUpdateBS :: EvpCipherCtx -> ByteString -> IO ByteString
+cipherUpdateBS :: CipherCtx -> ByteString -> IO ByteString
cipherUpdateBS ctx inBS
= withCipherCtxPtr ctx $ \ ctxPtr ->
unsafeUseAsCStringLen inBS $ \ (inBuf, inLen) ->
@@ -145,7 +156,7 @@ cipherUpdateBS ctx inBS
>> peek outLenPtr
-cipherFinalBS :: EvpCipherCtx -> IO ByteString
+cipherFinalBS :: CipherCtx -> IO ByteString
cipherFinalBS ctx
= withCipherCtxPtr ctx $ \ ctxPtr ->
createAndTrim (_ctx_block_size ctxPtr) $ \ outBuf ->
@@ -154,47 +165,52 @@ cipherFinalBS ctx
>>= failIf (/= 1)
>> peek outLenPtr
-
-cipher :: EvpCipher
- -> String
- -> String
- -> CryptoMode
- -> String
- -> IO String
+-- |@'cipher'@ lazilly encrypts or decrypts a stream of data. The
+-- input string doesn't necessarily have to be finite.
+cipher :: Cipher -- ^ algorithm to use
+ -> String -- ^ symmetric key
+ -> String -- ^ IV
+ -> CryptoMode -- ^ operation
+ -> String -- ^ An input string to encrypt\/decrypt. Note
+ -- that the string must not contain any letters
+ -- which aren't in the range of U+0000 -
+ -- U+00FF.
+ -> IO String -- ^ the result string
cipher c key iv mode input
= liftM L8.unpack $ cipherLBS c key iv mode $ L8.pack input
-
-cipherBS :: EvpCipher
- -> String
- -> String
- -> CryptoMode
- -> ByteString
- -> IO ByteString
+-- |@'cipherBS'@ strictly encrypts or decrypts a chunk of data.
+cipherBS :: Cipher -- ^ algorithm to use
+ -> String -- ^ symmetric key
+ -> String -- ^ IV
+ -> CryptoMode -- ^ operation
+ -> ByteString -- ^ input string to encrypt\/decrypt
+ -> IO ByteString -- ^ the result string
cipherBS c key iv mode input
= do ctx <- cipherInit c key iv mode
cipherStrictly ctx input
-
-cipherLBS :: EvpCipher
- -> String
- -> String
- -> CryptoMode
- -> LazyByteString
- -> IO LazyByteString
+-- |@'cipherLBS'@ lazilly encrypts or decrypts a stream of data. The
+-- input string doesn't necessarily have to be finite.
+cipherLBS :: Cipher -- ^ algorithm to use
+ -> String -- ^ symmetric key
+ -> String -- ^ IV
+ -> CryptoMode -- ^ operation
+ -> LazyByteString -- ^ input string to encrypt\/decrypt
+ -> IO LazyByteString -- ^ the result string
cipherLBS c key iv mode input
= do ctx <- cipherInit c key iv mode
cipherLazily ctx input
-cipherStrictly :: EvpCipherCtx -> ByteString -> IO ByteString
+cipherStrictly :: CipherCtx -> ByteString -> IO ByteString
cipherStrictly ctx input
= do output' <- cipherUpdateBS ctx input
output'' <- cipherFinalBS ctx
return $ B.append output' output''
-cipherLazily :: EvpCipherCtx -> LazyByteString -> IO LazyByteString
+cipherLazily :: CipherCtx -> LazyByteString -> IO LazyByteString
cipherLazily ctx (LPS [])
= cipherFinalBS ctx >>= \ bs -> (return . LPS) [bs]
View
85 OpenSSL/EVP/Digest.hsc
@@ -1,16 +1,22 @@
{- -*- haskell -*- -}
+
+-- #prune
+
+-- |An interface to message digest algorithms.
+
#include "HsOpenSSL.h"
+
module OpenSSL.EVP.Digest
- ( EvpMD
- , EVP_MD
- , withMDPtr
+ ( Digest
+ , EVP_MD -- private
+ , withMDPtr -- private
, getDigestByName
, getDigestNames
- , EvpMDCtx
- , EVP_MD_CTX
- , withDigestCtxPtr
+ , DigestCtx -- private
+ , EVP_MD_CTX -- private
+ , withDigestCtxPtr -- private
, digestStrictly -- private
, digestLazily -- private
@@ -33,8 +39,10 @@ import OpenSSL.Utils
{- EVP_MD -------------------------------------------------------------------- -}
-newtype EvpMD = EvpMD (Ptr EVP_MD)
-data EVP_MD = EVP_MD
+-- |@Digest@ is an opaque object that represents an algorithm of
+-- message digest.
+newtype Digest = Digest (Ptr EVP_MD)
+data EVP_MD
foreign import ccall unsafe "EVP_get_digestbyname"
@@ -44,28 +52,31 @@ foreign import ccall unsafe "HsOpenSSL_EVP_MD_size"
mdSize :: Ptr EVP_MD -> Int
-withMDPtr :: EvpMD -> (Ptr EVP_MD -> IO a) -> IO a
-withMDPtr (EvpMD mdPtr) f = f mdPtr
-
+withMDPtr :: Digest -> (Ptr EVP_MD -> IO a) -> IO a
+withMDPtr (Digest mdPtr) f = f mdPtr
-getDigestByName :: String -> IO (Maybe EvpMD)
+-- |@'getDigestByName' name@ returns a message digest algorithm whose
+-- name is @name@. If no algorithms are found, the result is
+-- @Nothing@.
+getDigestByName :: String -> IO (Maybe Digest)
getDigestByName name
= withCString name $ \ namePtr ->
do ptr <- _get_digestbyname namePtr
if ptr == nullPtr then
return Nothing
else
- return $ Just $ EvpMD ptr
-
+ return $ Just $ Digest ptr
+-- |@'getDigestNames'@ returns a list of name of message digest
+-- algorithms.
getDigestNames :: IO [String]
getDigestNames = getObjNames MDMethodType True
{- EVP_MD_CTX ---------------------------------------------------------------- -}
-newtype EvpMDCtx = EvpMDCtx (ForeignPtr EVP_MD_CTX)
-data EVP_MD_CTX = EVP_MD_CTX
+newtype DigestCtx = DigestCtx (ForeignPtr EVP_MD_CTX)
+data EVP_MD_CTX
foreign import ccall unsafe "EVP_MD_CTX_init"
@@ -75,16 +86,16 @@ foreign import ccall unsafe "&EVP_MD_CTX_cleanup"
_ctx_cleanup :: FunPtr (Ptr EVP_MD_CTX -> IO ())
-newCtx :: IO EvpMDCtx
+newCtx :: IO DigestCtx
newCtx = do ctx <- mallocForeignPtrBytes (#size EVP_MD_CTX)
withForeignPtr ctx $ \ ctxPtr ->
_ctx_init ctxPtr
addForeignPtrFinalizer _ctx_cleanup ctx
- return $ EvpMDCtx ctx
+ return $ DigestCtx ctx
-withDigestCtxPtr :: EvpMDCtx -> (Ptr EVP_MD_CTX -> IO a) -> IO a
-withDigestCtxPtr (EvpMDCtx ctx) = withForeignPtr ctx
+withDigestCtxPtr :: DigestCtx -> (Ptr EVP_MD_CTX -> IO a) -> IO a
+withDigestCtxPtr (DigestCtx ctx) = withForeignPtr ctx
{- digest -------------------------------------------------------------------- -}
@@ -99,27 +110,27 @@ foreign import ccall unsafe "EVP_DigestFinal"
_DigestFinal :: Ptr EVP_MD_CTX -> Ptr CChar -> Ptr CUInt -> IO Int
-digestInit :: EvpMD -> IO EvpMDCtx
-digestInit (EvpMD md)
+digestInit :: Digest -> IO DigestCtx
+digestInit (Digest md)
= do ctx <- newCtx
withDigestCtxPtr ctx $ \ ctxPtr ->
_DigestInit ctxPtr md >>= failIf (/= 1)
return ctx
-digestUpdateBS :: EvpMDCtx -> ByteString -> IO ()
+digestUpdateBS :: DigestCtx -> ByteString -> IO ()
digestUpdateBS ctx bs
= withDigestCtxPtr ctx $ \ ctxPtr ->
unsafeUseAsCStringLen bs $ \ (buf, len) ->
_DigestUpdate ctxPtr buf (fromIntegral len) >>= failIf (/= 1) >> return ()
-digestUpdateLBS :: EvpMDCtx -> LazyByteString -> IO ()
+digestUpdateLBS :: DigestCtx -> LazyByteString -> IO ()
digestUpdateLBS ctx (LPS chunks)
= mapM_ (digestUpdateBS ctx) chunks
-digestFinal :: EvpMDCtx -> IO String
+digestFinal :: DigestCtx -> IO String
digestFinal ctx
= withDigestCtxPtr ctx $ \ ctxPtr ->
allocaArray (#const EVP_MAX_MD_SIZE) $ \ bufPtr ->
@@ -129,32 +140,36 @@ digestFinal ctx
peekCStringLen (bufPtr, bufLen)
-digestStrictly :: EvpMD -> ByteString -> IO EvpMDCtx
+digestStrictly :: Digest -> ByteString -> IO DigestCtx
digestStrictly md input
= do ctx <- digestInit md
digestUpdateBS ctx input
return ctx
-digestLazily :: EvpMD -> LazyByteString -> IO EvpMDCtx
+digestLazily :: Digest -> LazyByteString -> IO DigestCtx
digestLazily md (LPS input)
= do ctx <- digestInit md
mapM_ (digestUpdateBS ctx) input
return ctx
-
-digest :: EvpMD -> String -> IO String
+-- |@'digest'@ digests a stream of data. The string must
+-- not contain any letters which aren't in the range of U+0000 -
+-- U+00FF.
+digest :: Digest -> String -> String
digest md input
= digestLBS md $ L8.pack input
-
-digestBS :: EvpMD -> ByteString -> IO String
+-- |@'digestBS'@ digests a chunk of data.
+digestBS :: Digest -> ByteString -> String
digestBS md input
- = do ctx <- digestStrictly md input
+ = unsafePerformIO $
+ do ctx <- digestStrictly md input
digestFinal ctx
-
-digestLBS :: EvpMD -> LazyByteString -> IO String
+-- |@'digestLBS'@ digests a stream of data.
+digestLBS :: Digest -> LazyByteString -> String
digestLBS md input
- = do ctx <- digestLazily md input
+ = unsafePerformIO $
+ do ctx <- digestLazily md input
digestFinal ctx
View
61 OpenSSL/EVP/Open.hsc
@@ -1,5 +1,10 @@
{- -*- haskell -*- -}
+
#include "HsOpenSSL.h"
+
+-- |Asymmetric cipher decryption using encrypted symmetric key. This
+-- is an opposite of "OpenSSL.EVP.Seal".
+
module OpenSSL.EVP.Open
( open
, openBS
@@ -21,15 +26,15 @@ import OpenSSL.Utils
foreign import ccall unsafe "EVP_OpenInit"
_OpenInit :: Ptr EVP_CIPHER_CTX
- -> EvpCipher
+ -> Cipher
-> Ptr CChar
-> Int
-> CString
-> Ptr EVP_PKEY
-> IO Int
-openInit :: EvpCipher -> String -> String -> EvpPKey -> IO EvpCipherCtx
+openInit :: Cipher -> String -> String -> PKey -> IO CipherCtx
openInit cipher encKey iv pkey
= do ctx <- newCtx
withCipherCtxPtr ctx $ \ ctxPtr ->
@@ -40,34 +45,38 @@ openInit cipher encKey iv pkey
>>= failIf (== 0)
return ctx
-
-open :: EvpCipher
- -> String
- -> String
- -> EvpPKey
- -> String
- -> IO String
+-- |@'open'@ lazilly decrypts a stream of data. The input string
+-- doesn't necessarily have to be finite.
+open :: Cipher -- ^ symmetric cipher algorithm to use
+ -> String -- ^ encrypted symmetric key to decrypt the input string
+ -> String -- ^ IV
+ -> PKey -- ^ private key to decrypt the symmetric key
+ -> String -- ^ input string to decrypt
+ -> String -- ^ decrypted string
open cipher encKey iv pkey input
- = liftM L8.unpack $ openLBS cipher encKey iv pkey $ L8.pack input
-
+ = L8.unpack $ openLBS cipher encKey iv pkey $ L8.pack input
-openBS :: EvpCipher
- -> String
- -> String
- -> EvpPKey
- -> ByteString
- -> IO ByteString
+-- |@'openBS'@ decrypts a chunk of data.
+openBS :: Cipher -- ^ symmetric cipher algorithm to use
+ -> String -- ^ encrypted symmetric key to decrypt the input string
+ -> String -- ^ IV
+ -> PKey -- ^ private key to decrypt the symmetric key
+ -> ByteString -- ^ input string to decrypt
+ -> ByteString -- ^ decrypted string
openBS cipher encKey iv pkey input
- = do ctx <- openInit cipher encKey iv pkey
+ = unsafePerformIO $
+ do ctx <- openInit cipher encKey iv pkey
cipherStrictly ctx input
-
-openLBS :: EvpCipher
- -> String
- -> String
- -> EvpPKey
- -> LazyByteString
- -> IO LazyByteString
+-- |@'openLBS'@ lazilly decrypts a stream of data. The input string
+-- doesn't necessarily have to be finite.
+openLBS :: Cipher -- ^ symmetric cipher algorithm to use
+ -> String -- ^ encrypted symmetric key to decrypt the input string
+ -> String -- ^ IV
+ -> PKey -- ^ private key to decrypt the symmetric key
+ -> LazyByteString -- ^ input string to decrypt
+ -> LazyByteString -- ^ decrypted string
openLBS cipher encKey iv pkey input
- = do ctx <- openInit cipher encKey iv pkey
+ = unsafePerformIO $
+ do ctx <- openInit cipher encKey iv pkey
cipherLazily ctx input
View
45 OpenSSL/EVP/PKey.hsc
@@ -1,8 +1,14 @@
{- -*- haskell -*- -}
+
+-- #prune
+
+-- |An interface to asymmetric cipher keypair.
+
#include "HsOpenSSL.h"
+
module OpenSSL.EVP.PKey
- ( EvpPKey
- , EVP_PKEY
+ ( PKey
+ , EVP_PKEY -- private
, wrapPKeyPtr -- private
, withPKeyPtr -- private
@@ -18,16 +24,17 @@ module OpenSSL.EVP.PKey
)
where
-
import Foreign
import Foreign.C
import OpenSSL.EVP.Digest
import OpenSSL.RSA
import OpenSSL.Utils
-
-newtype EvpPKey = EvpPKey (ForeignPtr EVP_PKEY)
-data EVP_PKEY = EVP_PKEY
+-- |@PKey@ is an opaque object that represents either public key or
+-- public\/private keypair. The concrete algorithm of asymmetric
+-- cipher is hidden in the object.
+newtype PKey = PKey (ForeignPtr EVP_PKEY)
+data EVP_PKEY
foreign import ccall unsafe "EVP_PKEY_new"
@@ -40,30 +47,30 @@ foreign import ccall unsafe "EVP_PKEY_size"
_pkey_size :: Ptr EVP_PKEY -> IO Int
-wrapPKeyPtr :: Ptr EVP_PKEY -> IO EvpPKey
+wrapPKeyPtr :: Ptr EVP_PKEY -> IO PKey
wrapPKeyPtr pkeyPtr
- = newForeignPtr _pkey_free pkeyPtr >>= return . EvpPKey
+ = newForeignPtr _pkey_free pkeyPtr >>= return . PKey
-withPKeyPtr :: EvpPKey -> (Ptr EVP_PKEY -> IO a) -> IO a
-withPKeyPtr (EvpPKey pkey) = withForeignPtr pkey
+withPKeyPtr :: PKey -> (Ptr EVP_PKEY -> IO a) -> IO a
+withPKeyPtr (PKey pkey) = withForeignPtr pkey
-unsafePKeyToPtr :: EvpPKey -> Ptr EVP_PKEY
-unsafePKeyToPtr (EvpPKey pkey) = unsafeForeignPtrToPtr pkey
+unsafePKeyToPtr :: PKey -> Ptr EVP_PKEY
+unsafePKeyToPtr (PKey pkey) = unsafeForeignPtrToPtr pkey
-touchPKey :: EvpPKey -> IO ()
-touchPKey (EvpPKey pkey) = touchForeignPtr pkey
+touchPKey :: PKey -> IO ()
+touchPKey (PKey pkey) = touchForeignPtr pkey
-pkeySize :: EvpPKey -> IO Int
+pkeySize :: PKey -> IO Int
pkeySize pkey
= withPKeyPtr pkey $ \ pkeyPtr ->
_pkey_size pkeyPtr
-pkeyDefaultMD :: EvpPKey -> IO EvpMD
+pkeyDefaultMD :: PKey -> IO Digest
pkeyDefaultMD pkey
= withPKeyPtr pkey $ \ pkeyPtr ->
do pkeyType <- (#peek EVP_PKEY, type) pkeyPtr :: IO Int
@@ -85,9 +92,11 @@ pkeyDefaultMD pkey
foreign import ccall unsafe "EVP_PKEY_set1_RSA"
_set1_RSA :: Ptr EVP_PKEY -> Ptr RSA_ -> IO Int
-newPKeyRSA :: RSA -> IO EvpPKey
+-- |@'newPKeyRSA' rsa@ encapsulates an 'RSA' key into 'PKey'.
+newPKeyRSA :: RSA -> PKey
newPKeyRSA rsa
- = withRSAPtr rsa $ \ rsaPtr ->
+ = unsafePerformIO $
+ withRSAPtr rsa $ \ rsaPtr ->
do pkeyPtr <- _pkey_new >>= failIfNull
_set1_RSA pkeyPtr rsaPtr >>= failIf (/= 1)
wrapPKeyPtr pkeyPtr
View
72 OpenSSL/EVP/Seal.hsc
@@ -1,5 +1,10 @@
{- -*- haskell -*- -}
+
#include "HsOpenSSL.h"
+
+-- |Asymmetric cipher decryption using encrypted symmetric key. This
+-- is an opposite of "OpenSSL.EVP.Open".
+
module OpenSSL.EVP.Seal
( seal
, sealBS
@@ -21,7 +26,7 @@ import OpenSSL.Utils
foreign import ccall unsafe "EVP_SealInit"
_SealInit :: Ptr EVP_CIPHER_CTX
- -> EvpCipher
+ -> Cipher
-> Ptr (Ptr CChar)
-> Ptr Int
-> CString
@@ -30,7 +35,7 @@ foreign import ccall unsafe "EVP_SealInit"
-> IO Int
-sealInit :: EvpCipher -> [EvpPKey] -> IO (EvpCipherCtx, [String], String)
+sealInit :: Cipher -> [PKey] -> IO (CipherCtx, [String], String)
sealInit _ []
= fail "sealInit: at least one public key is required"
@@ -52,8 +57,8 @@ sealInit cipher pubKeys
-- IV の書き込まれる場所を作る。
ivPtr <- mallocArray (cipherIvLength cipher)
- -- [EvpPKey] から Ptr (Ptr EVP_PKEY) を作る。後でそれぞれの
- -- EvpPKey を touchForeignPtr する事を忘れてはならない。
+ -- [PKey] から Ptr (Ptr EVP_PKEY) を作る。後でそれぞれの
+ -- PKey を touchForeignPtr する事を忘れてはならない。
pubKeysPtr <- newArray $ map unsafePKeyToPtr pubKeys
-- 確保した領域を解放する IO アクションを作って置く
@@ -80,43 +85,52 @@ sealInit cipher pubKeys
nKeys :: Int
nKeys = length pubKeys
- mallocEncKeyBuf :: Storable a => EvpPKey -> IO (Ptr a)
+ mallocEncKeyBuf :: Storable a => PKey -> IO (Ptr a)
mallocEncKeyBuf pubKey
= pkeySize pubKey >>= mallocArray
-
-seal :: EvpCipher
- -> [EvpPKey]
- -> String
- -> IO ( String
- , [String]
- , String
- )
+-- |@'seal'@ lazilly encrypts a stream of data. The input string
+-- doesn't necessarily have to be finite.
+seal :: Cipher -- ^ symmetric cipher algorithm to use
+ -> [PKey] -- ^ A list of public keys to encrypt a
+ -- symmetric key. At least one public key must
+ -- be supplied. If two or more keys are given,
+ -- the symmetric key are encrypted by each
+ -- public keys so that any of the
+ -- corresponding private keys can decrypt the
+ -- message.
+ -> String -- ^ input string to encrypt
+ -> IO (String, [String], String) -- ^ (encrypted string, list of
+ -- encrypted asymmetric keys,
+ -- IV)
seal cipher pubKeys input
= do (output, encKeys, iv) <- sealLBS cipher pubKeys $ L8.pack input
return (L8.unpack output, encKeys, iv)
-
-sealBS :: EvpCipher
- -> [EvpPKey]
- -> ByteString
- -> IO ( ByteString
- , [String]
- , String
- )
+-- |@'sealBS'@ strictly encrypts a chunk of data.
+sealBS :: Cipher -- ^ symmetric cipher algorithm to use
+ -> [PKey] -- ^ list of public keys to encrypt a symmetric
+ -- key
+ -> ByteString -- ^ input string to encrypt
+ -> IO (ByteString, [String], String) -- ^ (encrypted string,
+ -- list of encrypted
+ -- asymmetric keys, IV)
sealBS cipher pubKeys input
= do (ctx, encKeys, iv) <- sealInit cipher pubKeys
output <- cipherStrictly ctx input
return (output, encKeys, iv)
-
-sealLBS :: EvpCipher
- -> [EvpPKey]
- -> LazyByteString
- -> IO ( LazyByteString
- , [String]
- , String
- )
+-- |@'sealLBS'@ lazilly encrypts a stream of data. The input string
+-- doesn't necessarily have to be finite.
+sealLBS :: Cipher -- ^ symmetric cipher algorithm to use
+ -> [PKey] -- ^ list of public keys to encrypt a
+ -- symmetric key
+ -> LazyByteString -- ^ input string to encrypt
+ -> IO (LazyByteString, [String], String) -- ^ (encrypted
+ -- string, list of
+ -- encrypted
+ -- asymmetric keys,
+ -- IV)
sealLBS cipher pubKeys input
= do (ctx, encKeys, iv) <- sealInit cipher pubKeys
output <- cipherLazily ctx input
View
29 OpenSSL/EVP/Sign.hsc
@@ -1,5 +1,10 @@
{- -*- haskell -*- -}
+
#include "HsOpenSSL.h"
+
+-- |Message signing using asymmetric cipher and message digest
+-- algorithm. This is an opposite of "OpenSSL.EVP.Verify".
+
module OpenSSL.EVP.Sign
( sign
, signBS
@@ -22,7 +27,7 @@ foreign import ccall unsafe "EVP_SignFinal"
_SignFinal :: Ptr EVP_MD_CTX -> Ptr CChar -> Ptr CUInt -> Ptr EVP_PKEY -> IO Int
-signFinal :: EvpMDCtx -> EvpPKey -> IO String
+signFinal :: DigestCtx -> PKey -> IO String
signFinal ctx pkey
= do maxLen <- pkeySize pkey
withDigestCtxPtr ctx $ \ ctxPtr ->
@@ -35,18 +40,30 @@ signFinal ctx pkey
peekCStringLen (bufPtr, bufLen)
-sign :: EvpMD -> EvpPKey -> String -> IO String
+-- |@'sign'@ generates a signature from a stream of data. The string
+-- must not contain any letters which aren't in the range of U+0000 -
+-- U+00FF.
+sign :: Digest -- ^ message digest algorithm to use
+ -> PKey -- ^ private key to sign the message digest
+ -> String -- ^ input string
+ -> IO String -- ^ the result signature
sign md pkey input
= signLBS md pkey $ L8.pack input
-
-signBS :: EvpMD -> EvpPKey -> ByteString -> IO String
+-- |@'signBS'@ generates a signature from a chunk of data.
+signBS :: Digest -- ^ message digest algorithm to use
+ -> PKey -- ^ private key to sign the message digest
+ -> ByteString -- ^ input string
+ -> IO String -- ^ the result signature
signBS md pkey input
= do ctx <- digestStrictly md input
signFinal ctx pkey
-
-signLBS :: EvpMD -> EvpPKey -> LazyByteString -> IO String
+-- |@'signLBS'@ generates a signature from a stream of data.
+signLBS :: Digest -- ^ message digest algorithm to use
+ -> PKey -- ^ private key to sign the message digest
+ -> LazyByteString -- ^ input string
+ -> IO String -- ^ the result signature
signLBS md pkey input
= do ctx <- digestLazily md input
signFinal ctx pkey
View
37 OpenSSL/EVP/Verify.hsc
@@ -1,7 +1,13 @@
{- -*- haskell -*- -}
+
#include "HsOpenSSL.h"
+
+-- |Message verification using asymmetric cipher and message digest
+-- algorithm. This is an opposite of "OpenSSL.EVP.Sign".
+
module OpenSSL.EVP.Verify
- ( verify
+ ( VerifyStatus(..)
+ , verify
, verifyBS
, verifyLBS
)
@@ -19,6 +25,7 @@ import OpenSSL.EVP.Digest
import OpenSSL.EVP.PKey
import OpenSSL.Utils
+-- |@'VerifyStatus'@ represents a result of verification.
data VerifyStatus = VerifySuccess
| VerifyFailure
deriving (Show, Eq, Typeable)
@@ -28,7 +35,7 @@ foreign import ccall unsafe "EVP_VerifyFinal"
_VerifyFinal :: Ptr EVP_MD_CTX -> Ptr CChar -> CUInt -> Ptr EVP_PKEY -> IO Int
-verifyFinalBS :: EvpMDCtx -> String -> EvpPKey -> IO VerifyStatus
+verifyFinalBS :: DigestCtx -> String -> PKey -> IO VerifyStatus
verifyFinalBS ctx sig pkey
= withDigestCtxPtr ctx $ \ ctxPtr ->
withCStringLen sig $ \ (buf, len) ->
@@ -40,19 +47,33 @@ verifyFinalBS ctx sig pkey
interpret 0 = return VerifyFailure
interpret _ = raiseOpenSSLError
-
-verify :: EvpMD -> String -> EvpPKey -> String -> IO VerifyStatus
+-- |@'verify'@ verifies a signature and a stream of data. The string
+-- must not contain any letters which aren't in the range of U+0000 -
+-- U+00FF.
+verify :: Digest -- ^ message digest algorithm to use
+ -> String -- ^ message signature
+ -> PKey -- ^ public key to verify the signature
+ -> String -- ^ input string to verify
+ -> IO VerifyStatus -- ^ the result of verification
verify md sig pkey input
= verifyLBS md sig pkey (L8.pack input)
-
-verifyBS :: EvpMD -> String -> EvpPKey -> ByteString -> IO VerifyStatus
+-- |@'verifyBS'@ verifies a signature and a chunk of data.
+verifyBS :: Digest -- ^ message digest algorithm to use
+ -> String -- ^ message signature
+ -> PKey -- ^ public key to verify the signature
+ -> ByteString -- ^ input string to verify
+ -> IO VerifyStatus -- ^ the result of verification
verifyBS md sig pkey input
= do ctx <- digestStrictly md input
verifyFinalBS ctx sig pkey
-
-verifyLBS :: EvpMD -> String -> EvpPKey -> LazyByteString -> IO VerifyStatus
+-- |@'verifyLBS'@ verifies a signature of a stream of data.
+verifyLBS :: Digest -- ^ message digest algorithm to use
+ -> String -- ^ message signature
+ -> PKey -- ^ public key to verify the signature
+ -> LazyByteString -- ^ input string to verify
+ -> IO VerifyStatus -- ^ the result of verification
verifyLBS md sig pkey input
= do ctx <- digestLazily md input
verifyFinalBS ctx sig pkey
View
4 OpenSSL/Objects.hsc
@@ -1,5 +1,9 @@
{- -*- haskell -*- -}
+
+-- #hide
+
#include "HsOpenSSL.h"
+
module OpenSSL.Objects
( ObjNameType(..)
, getObjNames
View
160 OpenSSL/PEM.hsc
@@ -1,30 +1,42 @@
{- -*- haskell -*- -}
+
+-- |An interface to PEM routines.
+
+#include "HsOpenSSL.h"
+
module OpenSSL.PEM
- ( PemPasswordRWState(..)
+ ( -- * Password supply
+ PemPasswordCallback
+ , PemPasswordRWState(..)
, PemPasswordSupply(..)
+ -- * Private key
, writePKCS8PrivateKey
, readPrivateKey
+ -- * Public key
, writePublicKey
, readPublicKey
+ -- * X.509 certificate
, writeX509
, readX509
+ -- * PKCS#10 certificate request
+ , PemX509ReqFormat(..)
, writeX509Req
, readX509Req
+ -- * Certificate Revocation List
, writeCRL
, readCRL
+ -- * PKCS#7 structure
, writePkcs7
, readPkcs7
)
where
-#include "HsOpenSSL.h"
-
import Control.Exception
import Control.Monad
import Foreign
@@ -41,28 +53,50 @@ import Prelude hiding (catch)
import System.IO
-type PemPasswordCallback = Ptr CChar -> Int -> Int -> Ptr () -> IO Int
+-- |@'PemPasswordCallback'@ represents a callback function to supply a
+-- password.
+type PemPasswordCallback
+ = Int -- ^ maximum length of the password to be
+ -- accepted
+ -> PemPasswordRWState -- ^ context
+ -> IO String -- ^ the result password
+
+type PemPasswordCallback' = Ptr CChar -> Int -> Int -> Ptr () -> IO Int
+
+
+-- |@'PemPasswordRWState'@ represents a context of
+-- 'PemPasswordCallback'.
+data PemPasswordRWState = PwRead -- ^ The callback was called to get
+ -- a password to read something
+ -- encrypted.
+ | PwWrite -- ^ The callback was called to get
+ -- a password to encrypt
+ -- something.
+
+-- |@'PemPasswordSupply'@ represents a way to supply password.
+--
+-- FIXME: using PwTTY causes an error but I don't know why:
+-- \"error:0906406D:PEM routines:DEF_CALLBACK:problems getting
+-- password\"
+data PemPasswordSupply = PwNone -- ^ no password
+ | PwStr String -- ^ password in a static string
+ | PwCallback PemPasswordCallback -- ^ get a
+ -- password
+ -- by a
+ -- callback
+ | PwTTY -- ^ read a password from TTY
-data PemPasswordRWState = PwRead
- | PwWrite
-
--- FIXME: using PwTTY causes an error but I don't know why.
--- error:0906406D:PEM routines:DEF_CALLBACK:problems getting password
-data PemPasswordSupply = PwNone
- | PwStr String
- | PwCallback (Int -> PemPasswordRWState -> IO String)
- | PwTTY
foreign import ccall "wrapper"
- mkPemPasswordCallback :: PemPasswordCallback -> IO (FunPtr PemPasswordCallback)
+ mkPemPasswordCallback :: PemPasswordCallback' -> IO (FunPtr PemPasswordCallback')
rwflagToState :: Int -> PemPasswordRWState
rwflagToState 0 = PwRead
rwflagToState 1 = PwWrite
-callPasswordCB :: (Int -> PemPasswordRWState -> IO String) -> PemPasswordCallback
+callPasswordCB :: PemPasswordCallback -> PemPasswordCallback'
callPasswordCB cb buf bufLen rwflag _
= let mode = rwflagToState rwflag
try = do passStr <- cb bufLen mode
@@ -92,13 +126,13 @@ foreign import ccall safe "PEM_write_bio_PKCS8PrivateKey"
-> Ptr EVP_CIPHER
-> Ptr CChar
-> Int
- -> FunPtr PemPasswordCallback
+ -> FunPtr PemPasswordCallback'
-> Ptr a
-> IO Int
writePKCS8PrivateKey' :: BIO
- -> EvpPKey
- -> Maybe (EvpCipher, PemPasswordSupply)
+ -> PKey
+ -> Maybe (Cipher, PemPasswordSupply)
-> IO ()
writePKCS8PrivateKey' bio pkey encryption
= withBioPtr bio $ \ bioPtr ->
@@ -128,8 +162,17 @@ writePKCS8PrivateKey' bio pkey encryption
failIf (/= 1) ret
return ()
-
-writePKCS8PrivateKey :: EvpPKey -> Maybe (EvpCipher, PemPasswordSupply) -> IO String
+-- |@'writePKCS8PrivateKey'@ writes a private key to PEM string in
+-- PKCS#8 format.
+writePKCS8PrivateKey
+ :: PKey -- ^ private key to write
+ -> Maybe (Cipher, PemPasswordSupply) -- ^ Either (symmetric cipher
+ -- algorithm, password
+ -- supply) or @Nothing@. If
+ -- @Nothing@ is given the
+ -- private key is not
+ -- encrypted.
+ -> IO String -- ^ the result PEM string
writePKCS8PrivateKey pkey encryption
= do mem <- newMem
writePKCS8PrivateKey' mem pkey encryption
@@ -139,11 +182,11 @@ writePKCS8PrivateKey pkey encryption
foreign import ccall safe "PEM_read_bio_PrivateKey"
_read_bio_PrivateKey :: Ptr BIO_
-> Ptr (Ptr EVP_PKEY)
- -> FunPtr PemPasswordCallback
+ -> FunPtr PemPasswordCallback'
-> Ptr ()
-> IO (Ptr EVP_PKEY)
-readPrivateKey' :: BIO -> PemPasswordSupply -> IO EvpPKey
+readPrivateKey' :: BIO -> PemPasswordSupply -> IO PKey
readPrivateKey' bio supply
= withBioPtr bio $ \ bioPtr ->
do pkeyPtr <- case supply of
@@ -168,8 +211,8 @@ readPrivateKey' bio supply
failIfNull pkeyPtr
wrapPKeyPtr pkeyPtr
-
-readPrivateKey :: String -> PemPasswordSupply -> IO EvpPKey
+-- |@'readPrivateKey' pem supply@ reads a private key in PEM string.
+readPrivateKey :: String -> PemPasswordSupply -> IO PKey
readPrivateKey pemStr supply
= do mem <- newConstMem pemStr
readPrivateKey' mem supply
@@ -183,36 +226,36 @@ foreign import ccall unsafe "PEM_write_bio_PUBKEY"
foreign import ccall unsafe "PEM_read_bio_PUBKEY"
_read_bio_PUBKEY :: Ptr BIO_
-> Ptr (Ptr EVP_PKEY)
- -> FunPtr PemPasswordCallback
+ -> FunPtr PemPasswordCallback'
-> Ptr ()
-> IO (Ptr EVP_PKEY)
-writePublicKey' :: BIO -> EvpPKey -> IO ()
+writePublicKey' :: BIO -> PKey -> IO ()
writePublicKey' bio pkey
= withBioPtr bio $ \ bioPtr ->
withPKeyPtr pkey $ \ pkeyPtr ->
_write_bio_PUBKEY bioPtr pkeyPtr >>= failIf (/= 1) >> return ()
-
-writePublicKey :: EvpPKey -> IO String
+-- |@'writePublicKey' pubkey@ writes a public to PEM string.
+writePublicKey :: PKey -> IO String
writePublicKey pkey
= do mem <- newMem
writePublicKey' mem pkey
bioRead mem
-- Why the heck PEM_read_bio_PUBKEY takes pem_password_cb? Is there
-- any form of encrypted public key?
-readPublicKey' :: BIO -> IO EvpPKey
+readPublicKey' :: BIO -> IO PKey
readPublicKey' bio
= withBioPtr bio $ \ bioPtr ->
withCString "" $ \ passPtr ->
_read_bio_PUBKEY bioPtr nullPtr nullFunPtr (unsafeCoercePtr passPtr)
>>= failIfNull
>>= wrapPKeyPtr
-
-readPublicKey :: String -> IO EvpPKey
+-- |@'readPublicKey' pem@ reads a public key in PEM string.
+readPublicKey :: String -> IO PKey
readPublicKey pemStr
= newConstMem pemStr >>= readPublicKey'
@@ -227,7 +270,7 @@ foreign import ccall unsafe "PEM_write_bio_X509_AUX"
foreign import ccall safe "PEM_read_bio_X509_AUX"
_read_bio_X509_AUX :: Ptr BIO_
-> Ptr (Ptr X509_)
- -> FunPtr PemPasswordCallback
+ -> FunPtr PemPasswordCallback'
-> Ptr ()
-> IO (Ptr X509_)
@@ -239,7 +282,7 @@ writeX509' bio x509
>>= failIf (/= 1)
>> return ()
-
+-- |@'writeX509' cert@ writes an X.509 certificate to PEM string.
writeX509 :: X509 -> IO String
writeX509 x509
= do mem <- newMem
@@ -256,7 +299,7 @@ readX509' bio
>>= failIfNull
>>= wrapX509
-
+-- |@'readX509' pem@ reads an X.509 certificate in PEM string.
readX509 :: String -> IO X509
readX509 pemStr
= newConstMem pemStr >>= readX509'
@@ -277,29 +320,39 @@ foreign import ccall unsafe "PEM_write_bio_X509_REQ_NEW"
foreign import ccall safe "PEM_read_bio_X509_REQ"
_read_bio_X509_REQ :: Ptr BIO_
-> Ptr (Ptr X509_REQ)
- -> FunPtr PemPasswordCallback
+ -> FunPtr PemPasswordCallback'
-> Ptr ()
-> IO (Ptr X509_REQ)
+-- |@'PemX509ReqFormat'@ represents format of PKCS#10 certificate
+-- request.
+data PemX509ReqFormat
+ = ReqNewFormat -- ^ The new format, whose header is \"NEW
+ -- CERTIFICATE REQUEST\".
+ | ReqOldFormat -- ^ The old format, whose header is \"CERTIFICATE
+ -- REQUEST\".
+
-writeX509Req' :: BIO -> X509Req -> Bool -> IO ()
-writeX509Req' bio req new
+writeX509Req' :: BIO -> X509Req -> PemX509ReqFormat -> IO ()
+writeX509Req' bio req format
= withBioPtr bio $ \ bioPtr ->
withX509ReqPtr req $ \ reqPtr ->
writer bioPtr reqPtr
>>= failIf (/= 1)
>> return ()
where
- writer = if new then
- _write_bio_X509_REQ_NEW
- else
- _write_bio_X509_REQ
-
-
-writeX509Req :: X509Req -> Bool -> IO String
-writeX509Req req new
+ writer = case format of
+ ReqNewFormat -> _write_bio_X509_REQ_NEW
+ ReqOldFormat -> _write_bio_X509_REQ
+
+-- |@'writeX509Req'@ writes a PKCS#10 certificate request to PEM
+-- string.
+writeX509Req :: X509Req -- ^ request
+ -> PemX509ReqFormat -- ^ format
+ -> IO String -- ^ the result PEM string
+writeX509Req req format
= do mem <- newMem
- writeX509Req' mem req new
+ writeX509Req' mem req format
bioRead mem
@@ -311,7 +364,7 @@ readX509Req' bio
>>= failIfNull
>>= wrapX509Req
-
+-- |@'readX509Req'@ reads a PKCS#10 certificate request in PEM string.
readX509Req :: String -> IO X509Req
readX509Req pemStr
= newConstMem pemStr >>= readX509Req'
@@ -327,7 +380,7 @@ foreign import ccall unsafe "PEM_write_bio_X509_CRL"
foreign import ccall safe "PEM_read_bio_X509_CRL"
_read_bio_X509_CRL :: Ptr BIO_
-> Ptr (Ptr X509_CRL)
- -> FunPtr PemPasswordCallback
+ -> FunPtr PemPasswordCallback'
-> Ptr ()
-> IO (Ptr X509_CRL)
@@ -340,7 +393,8 @@ writeCRL' bio crl
>>= failIf (/= 1)
>> return ()
-
+-- |@'writeCRL' crl@ writes a Certificate Revocation List to PEM
+-- string.
writeCRL :: CRL -> IO String
writeCRL crl
= do mem <- newMem
@@ -356,7 +410,7 @@ readCRL' bio
>>= failIfNull
>>= wrapCRL
-
+-- |@'readCRL' pem@ reads a Certificate Revocation List in PEM string.
readCRL :: String -> IO CRL
readCRL pemStr
= newConstMem pemStr >>= readCRL'
@@ -372,7 +426,7 @@ foreign import ccall unsafe "PEM_write_bio_PKCS7"
foreign import ccall safe "PEM_read_bio_PKCS7"
_read_bio_PKCS7 :: Ptr BIO_
-> Ptr (Ptr PKCS7)
- -> FunPtr PemPasswordCallback
+ -> FunPtr PemPasswordCallback'
-> Ptr ()
-> IO (Ptr PKCS7)
@@ -385,7 +439,7 @@ writePkcs7' bio pkcs7
>>= failIf (/= 1)
>> return ()
-
+-- |@'writePkcs7' p7@ writes a PKCS#7 structure to PEM string.
writePkcs7 :: Pkcs7 -> IO String
writePkcs7 pkcs7
= do mem <- newMem
@@ -401,7 +455,7 @@ readPkcs7' bio
>>= failIfNull
>>= wrapPkcs7Ptr
-
+-- |@'readPkcs7' pem@ reads a PKCS#7 structure in PEM string.
readPkcs7 :: String -> IO Pkcs7
readPkcs7 pemStr
= newConstMem pemStr >>= readPkcs7'
View
224 OpenSSL/PKCS7.hsc
@@ -1,21 +1,27 @@
{- -*- haskell -*- -}
+-- #prune
+
+-- |An interface to PKCS#7 structure and S\/MIME message.
+
#include "HsOpenSSL.h"
module OpenSSL.PKCS7
- ( Pkcs7
- , PKCS7
+ ( -- * Types
+ Pkcs7
+ , PKCS7 -- private
, Pkcs7Flag(..)
+ , Pkcs7VerifyStatus(..)
, wrapPkcs7Ptr -- private
, withPkcs7Ptr -- private
- , isDetachedSignature
-
+ -- * Encryption and Signing
, pkcs7Sign
, pkcs7Verify
, pkcs7Encrypt
, pkcs7Decrypt
+ -- * S\/MIME
, writeSmime
, readSmime
)
@@ -42,9 +48,15 @@ import OpenSSL.X509.Store
{- PKCS#7 -------------------------------------------------------------------- -}
+-- |@'Pkcs7'@ represents an abstract PKCS#7 structure. The concrete
+-- type of structure is hidden in the object: such polymorphism isn't
+-- very haskellish but please get it out of your mind since OpenSSL is
+-- written in C.
newtype Pkcs7 = Pkcs7 (ForeignPtr PKCS7)
-data PKCS7 = PKCS7
+data PKCS7
+-- |@'Pkcs7Flag'@ is a set of flags that are used in many operations
+-- related to PKCS#7.
data Pkcs7Flag = Pkcs7Text
| Pkcs7NoCerts
| Pkcs7NoSigs
@@ -73,10 +85,15 @@ flagToInt Pkcs7NoSmimeCap = #const PKCS7_NOSMIMECAP
flagToInt Pkcs7NoOldMimeType = #const PKCS7_NOOLDMIMETYPE
flagToInt Pkcs7CRLFEOL = #const PKCS7_CRLFEOL
-
-data VerifyStatus = VerifySuccess (Maybe String)
- | VerifyFailure
- deriving (Show, Eq, Typeable)
+-- |@'Pkcs7VerifyStatus'@ represents a result of PKCS#7
+-- verification. See 'pkcs7Verify'.
+data Pkcs7VerifyStatus
+ = Pkcs7VerifySuccess (Maybe String) -- ^ Nothing if the PKCS#7
+ -- signature was a detached
+ -- signature, and @Just content@
+ -- if it wasn't.
+ | Pkcs7VerifyFailure
+ deriving (Show, Eq, Typeable)
flagListToInt :: [Pkcs7Flag] -> Int
@@ -117,7 +134,7 @@ isDetachedSignature pkcs7
>>= return . (== 1)
-pkcs7Sign' :: X509 -> EvpPKey -> [X509] -> BIO -> [Pkcs7Flag] -> IO Pkcs7
+pkcs7Sign' :: X509 -> PKey -> [X509] -> BIO -> [Pkcs7Flag] -> IO Pkcs7
pkcs7Sign' signCert pkey certs input flagList
= withX509Ptr signCert $ \ signCertPtr ->
withPKeyPtr pkey $ \ pkeyPtr ->
@@ -127,8 +144,64 @@ pkcs7Sign' signCert pkey certs input flagList
>>= failIfNull
>>= wrapPkcs7Ptr
-
-pkcs7Sign :: X509 -> EvpPKey -> [X509] -> String -> [Pkcs7Flag] -> IO Pkcs7
+-- |@'pkcs7Sign'@ creates a PKCS#7 signedData structure.
+pkcs7Sign :: X509 -- ^ certificate to sign with
+ -> PKey -- ^ corresponding private key
+ -> [X509] -- ^ optional additional set of certificates
+ -- to include in the PKCS#7 structure (for
+ -- example any intermediate CAs in the
+ -- chain)
+ -> String -- ^ data to be signed
+ -> [Pkcs7Flag] -- ^ An optional set of flags:
+ --
+ -- ['Pkcs7Text'] Many S\/MIME clients
+ -- expect the signed content to include
+ -- valid MIME headers. If the 'Pkcs7Text'
+ -- flag is set MIME headers for type
+ -- \"text\/plain\" are prepended to the
+ -- data.
+ --
+ -- ['Pkcs7NoCerts'] If 'Pkcs7NoCerts' is
+ -- set the signer's certificate will not be
+ -- included in the PKCS#7 structure, the
+ -- signer's certificate must still be
+ -- supplied in the parameter though. This
+ -- can reduce the size of the signature if
+ -- the signer's certificate can be obtained
+ -- by other means: for example a previously
+ -- signed message.
+ --
+ -- ['Pkcs7Detached'] The data being signed
+ -- is included in the PKCS#7 structure,
+ -- unless 'Pkcs7Detached' is set in which
+ -- case it is ommited. This is used for
+ -- PKCS#7 detached signatures which are
+ -- used in S\/MIME plaintext signed message
+ -- for example.
+ --
+ -- ['Pkcs7Binary'] Normally the supplied
+ -- content is translated into MIME
+ -- canonical format (as required by the
+ -- S\/MIME specifications) but if
+ -- 'Pkcs7Binary' is set no translation
+ -- occurs. This option should be uesd if
+ -- the supplied data is in binary format
+ -- otherwise the translation will corrupt
+ -- it.
+ --
+ -- ['Pkcs7NoAttr']
+ --
+ -- ['Pkcs7NoSmimeCap'] The signedData
+ -- structure includes several PKCS#7
+ -- authenticatedAttributes including the
+ -- signing time, the PKCS#7 content type
+ -- and the supported list of ciphers in an
+ -- SMIMECapabilities attribute. If
+ -- 'Pkcs7NoAttr' is set then no
+ -- authenticatedAttributes will be used. If
+ -- Pkcs7NoSmimeCap is set then just the
+ -- SMIMECapabilities are omitted.
+ -> IO Pkcs7
pkcs7Sign signCert pkey certs input flagList
= do mem <- newConstMem input
pkcs7Sign' signCert pkey certs mem flagList
@@ -153,19 +226,63 @@ pkcs7Verify' pkcs7 certs store inData flagList
interpret bio 1 = return (bio , True )
interpret _ _ = return (Nothing, False)
-
-pkcs7Verify :: Pkcs7 -> [X509] -> X509Store -> Maybe String -> [Pkcs7Flag] -> IO VerifyStatus
+-- |@'pkcs7Verify'@ verifies a PKCS#7 signedData structure.
+pkcs7Verify :: Pkcs7 -- ^ A PKCS#7 structure to verify.
+ -> [X509] -- ^ Set of certificates in which to
+ -- search for the signer's
+ -- certificate.
+ -> X509Store -- ^ Trusted certificate store (used
+ -- for chain verification).
+ -> Maybe String -- ^ Signed data if the content is not
+ -- present in the PKCS#7 structure
+ -- (that is it is detached).
+ -> [Pkcs7Flag] -- ^ An optional set of flags:
+ --
+ -- ['Pkcs7NoIntern'] If
+ -- 'Pkcs7NoIntern' is set the
+ -- certificates in the message itself
+ -- are not searched when locating the
+ -- signer's certificate. This means
+ -- that all the signers certificates
+ -- must be in the second argument
+ -- (['X509']).
+ --
+ -- ['Pkcs7Text'] If the 'Pkcs7Text'
+ -- flag is set MIME headers for type
+ -- \"text\/plain\" are deleted from
+ -- the content. If the content is not
+ -- of type \"text\/plain\" then an
+ -- error is returned.
+ --
+ -- ['Pkcs7NoVerify'] If
+ -- 'Pkcs7NoVerify' is set the
+ -- signer's certificates are not
+ -- chain verified.
+ --
+ -- ['Pkcs7NoChain'] If 'Pkcs7NoChain'
+ -- is set then the certificates
+ -- contained in the message are not
+ -- used as untrusted CAs. This means
+ -- that the whole verify chain (apart
+ -- from the signer's certificate)
+ -- must be contained in the trusted
+ -- store.
+ --
+ -- ['Pkcs7NoSigs'] If 'Pkcs7NoSigs'
+ -- is set then the signatures on the
+ -- data are not checked.
+ -> IO Pkcs7VerifyStatus
pkcs7Verify pkcs7 certs store inData flagList
= do inDataBio <- forM inData newConstMem
(outDataBio, isSuccess) <- pkcs7Verify' pkcs7 certs store inDataBio flagList
if isSuccess then
do outData <- forM outDataBio bioRead
- return $ VerifySuccess outData
+ return $ Pkcs7VerifySuccess outData
else
- return VerifyFailure
+ return Pkcs7VerifyFailure
-pkcs7Encrypt' :: [X509] -> BIO -> EvpCipher -> [Pkcs7Flag] -> IO Pkcs7
+pkcs7Encrypt' :: [X509] -> BIO -> Cipher -> [Pkcs7Flag] -> IO Pkcs7
pkcs7Encrypt' certs input cipher flagList
= withX509Stack certs $ \ certsPtr ->
withBioPtr input $ \ inputPtr ->
@@ -174,14 +291,34 @@ pkcs7Encrypt' certs input cipher flagList
>>= failIfNull
>>= wrapPkcs7Ptr
-
-pkcs7Encrypt :: [X509] -> String -> EvpCipher -> [Pkcs7Flag] -> IO Pkcs7
+-- |@'pkcs7Encrypt'@ creates a PKCS#7 envelopedData structure.
+pkcs7Encrypt :: [X509] -- ^ A list of recipient certificates.
+ -> String -- ^ The content to be encrypted.
+ -> Cipher -- ^ The symmetric cipher to use.
+ -> [Pkcs7Flag] -- ^ An optional set of flags:
+ --
+ -- ['Pkcs7Text'] If the 'Pkcs7Text' flag
+ -- is set MIME headers for type
+ -- \"text\/plain\" are prepended to the
+ -- data.
+ --
+ -- ['Pkcs7Binary'] Normally the supplied
+ -- content is translated into MIME
+ -- canonical format (as required by the
+ -- S\/MIME specifications) if
+ -- 'Pkcs7Binary' is set no translation
+ -- occurs. This option should be used if
+ -- the supplied data is in binary format
+ -- otherwise the translation will
+ -- corrupt it. If 'Pkcs7Binary' is set
+ -- then 'Pkcs7Text' is ignored.
+ -> IO Pkcs7
pkcs7Encrypt certs input cipher flagList
= do mem <- newConstMem input
pkcs7Encrypt' certs mem cipher flagList
-pkcs7Decrypt' :: Pkcs7 -> EvpPKey -> X509 -> BIO -> [Pkcs7Flag] -> IO ()
+pkcs7Decrypt' :: Pkcs7 -> PKey -> X509 -> BIO -> [Pkcs7Flag] -> IO ()
pkcs7Decrypt' pkcs7 pkey cert output flagList
= withPkcs7Ptr pkcs7 $ \ pkcs7Ptr ->
withPKeyPtr pkey $ \ pkeyPtr ->
@@ -191,8 +328,20 @@ pkcs7Decrypt' pkcs7 pkey cert output flagList
>>= failIf (/= 1)
>> return ()
-
-pkcs7Decrypt :: Pkcs7 -> EvpPKey -> X509 -> [Pkcs7Flag] -> IO String
+-- |@'pkcs7Decrypt'@ decrypts content from PKCS#7 envelopedData
+-- structure.
+pkcs7Decrypt :: Pkcs7 -- ^ The PKCS#7 structure to decrypt.
+ -> PKey -- ^ The private key of the recipient.
+ -> X509 -- ^ The recipient's certificate.
+ -> [Pkcs7Flag] -- ^ An optional set of flags:
+ --
+ -- ['Pkcs7Text'] If the 'Pkcs7Text' flag
+ -- is set MIME headers for type
+ -- \"text\/plain\" are deleted from the
+ -- content. If the content is not of
+ -- type \"text\/plain\" then an error is
+ -- thrown.
+ -> IO String -- ^ The decrypted content.
pkcs7Decrypt pkcs7 pkey cert flagList
= do mem <- newMem
pkcs7Decrypt' pkcs7 pkey cert mem flagList
@@ -207,8 +356,26 @@ foreign import ccall unsafe "SMIME_write_PKCS7"
foreign import ccall unsafe "SMIME_read_PKCS7"
_SMIME_read_PKCS7 :: Ptr BIO_ -> Ptr (Ptr BIO_) -> IO (Ptr PKCS7)
-
-writeSmime :: Pkcs7 -> Maybe String -> [Pkcs7Flag] -> IO String
+-- |@'writeSmime'@ writes PKCS#7 structure to S\/MIME message.
+writeSmime :: Pkcs7 -- ^ A PKCS#7 structure to be written.
+ -> Maybe String -- ^ If cleartext signing
+ -- (multipart\/signed) is being used then
+ -- the signed data must be supplied here.
+ -> [Pkcs7Flag] -- ^ An optional set of flags:
+ --
+ -- ['Pkcs7Detached'] If 'Pkcs7Detached'
+ -- is set then cleartext signing will be
+ -- used, this option only makes sense for
+ -- signedData where 'Pkcs7Detached' is
+ -- also set when 'pkcs7Sign' is also
+ -- called.
+ --
+ -- ['Pkcs7Text'] If the 'Pkcs7Text' flag
+ -- is set MIME headers for type
+ -- \"text\/plain\" are added to the
+ -- content, this only makes sense if
+ -- 'Pkcs7Detached' is also set.
+ -> IO String -- ^ The result S\/MIME message.
writeSmime pkcs7 dataStr flagList
= do outBio <- newMem
dataBio <- forM dataStr newConstMem
@@ -225,8 +392,13 @@ writeSmime' outBio pkcs7 dataBio flagList
>>= failIf (/= 1)
>> return ()
-
-readSmime :: String -> IO (Pkcs7, Maybe String)
+-- |@'readSmime'@ parses S\/MIME message.
+readSmime :: String -- ^ The message to be read.
+ -> IO (Pkcs7, Maybe String) -- ^ (The result PKCS#7
+ -- structure, @Just content@
+ -- if the PKCS#7 structure was
+ -- a cleartext signature and
+ -- @Nothing@ if it wasn't.)
readSmime input
= do inBio <- newConstMem input
(pkcs7, outBio) <- readSmime' inBio
View
68 OpenSSL/RSA.hsc
@@ -1,11 +1,22 @@
{- -*- haskell -*- -}
+
+#include "HsOpenSSL.h"
+
+-- #prune
+
+-- |An interface to RSA public key generator.
+
module OpenSSL.RSA
- ( RSA
- , RSA_
- , withRSAPtr
+ ( -- * Type
+ RSA
+ , RSA_ -- private
+ , withRSAPtr -- private
+ -- * Generating keypair
+ , RSAGenKeyCallback
, generateKey
+ -- * Exploring keypair
, rsaN
, rsaE
, rsaD
@@ -17,17 +28,16 @@ module OpenSSL.RSA
)
where
-#include "HsOpenSSL.h"
-
import Control.Monad
import Foreign
import Foreign.C
import OpenSSL.BN
import OpenSSL.Utils
-
+-- |@'RSA'@ is an opaque object that represents either RSA public key
+-- or public\/private keypair.
newtype RSA = RSA (ForeignPtr RSA_)
-data RSA_ = RSA_
+data RSA_
foreign import ccall unsafe "&RSA_free"
@@ -40,17 +50,41 @@ withRSAPtr (RSA rsa) = withForeignPtr rsa
{- generation --------------------------------------------------------------- -}
-type GenKeyCallback = Int -> Int -> Ptr () -> IO ()
+-- |@'RSAGenKeyCallback'@ represents a callback function to get
+-- informed the progress of RSA key generation.
+--
+-- * @callback 0 i@ is called after generating the @i@-th potential
+-- prime number.
+--
+-- * While the number is being tested for primality, @callback 1 j@ is
+-- called after the @j@-th iteration (j = 0, 1, ...).
+--
+-- * When the @n@-th randomly generated prime is rejected as not
+-- suitable for the key, @callback 2 n@ is called.
+--
+-- * When a random @p@ has been found with @p@-1 relatively prime to
+-- @e@, it is called as @callback 3 0@.
+--
+-- * The process is then repeated for prime @q@ with @callback 3 1@.
+type RSAGenKeyCallback = Int -> Int -> IO ()
+
+type RSAGenKeyCallback' = Int -> Int -> Ptr () -> IO ()
foreign import ccall "wrapper"
- mkGenKeyCallback :: GenKeyCallback -> IO (FunPtr GenKeyCallback)
+ mkGenKeyCallback :: RSAGenKeyCallback' -> IO (FunPtr RSAGenKeyCallback')
foreign import ccall safe "RSA_generate_key"
- _generate_key :: Int -> Int -> FunPtr GenKeyCallback -> Ptr a -> IO (Ptr RSA_)
+ _generate_key :: Int -> Int -> FunPtr RSAGenKeyCallback' -> Ptr a -> IO (Ptr RSA_)
-
-generateKey :: Int -> Int -> Maybe (Int -> Int -> IO ()) -> IO RSA
+-- |@'generateKey'@ generates an RSA keypair.
+generateKey :: Int -- ^ The number of bits of the public modulus
+ -- (i.e. key size). Key sizes with @n < 1024@
+ -- should be considered insecure.
+ -> Int -- ^ The public exponent. It is an odd number,
+ -- typically 3, 17 or 65537.
+ -> Maybe RSAGenKeyCallback -- ^ A callback function.
+ -> IO RSA -- ^ The generated keypair.
generateKey nbits e Nothing
= do ptr <- _generate_key nbits e nullFunPtr nullPtr
@@ -85,27 +119,35 @@ peekRSAPrivate peeker rsa
else
peekBN bn >>= return . Just
-
+-- |@'rsaN' pubKey@ returns the public modulus of the key.
rsaN :: RSA -> IO Integer
rsaN = peekRSAPublic (#peek RSA, n)
+-- |@'rsaE' pubKey@ returns the public exponent of the key.
rsaE :: RSA -> IO Integer
rsaE = peekRSAPublic (#peek RSA, e)
+-- |@'rsaD' privKey@ returns the private exponent of the key. If
+-- @privKey@ is not really a private key, the result is @Nothing@.
rsaD :: RSA -> IO (Maybe Integer)
rsaD = peekRSAPrivate (#peek RSA, d)
+-- |@'rsaP' privkey@ returns the secret prime factor @p@ of the key.
rsaP :: RSA -> IO (Maybe Integer)
rsaP = peekRSAPrivate (#peek RSA, p)
+-- |@'rsaQ' privkey@ returns the secret prime factor @q@ of the key.
rsaQ :: RSA -> IO (Maybe Integer)
rsaQ = peekRSAPrivate (#peek RSA, q)
+-- |@'rsaDMP1' privkey@ returns @d mod (p-1)@ of the key.
rsaDMP1 :: RSA -> IO (Maybe Integer)
rsaDMP1 = peekRSAPrivate (#peek RSA, dmp1)
+-- |@'rsaDMQ1' privkey@ returns @d mod (q-1)@ of the key.
rsaDMQ1 :: RSA -> IO (Maybe Integer)
rsaDMQ1 = peekRSAPrivate (#peek RSA, dmq1)
+-- |@'rsaIQMP' privkey@ returns @q^-1 mod p@ of the key.
rsaIQMP :: RSA -> IO (Maybe Integer)
rsaIQMP = peekRSAPrivate (#peek RSA, iqmp)
View
4 OpenSSL/Stack.hsc
@@ -1,5 +1,9 @@
{- -*- haskell -*- -}
+
+-- #hide
+
#include "HsOpenSSL.h"
+
module OpenSSL.Stack
( STACK
, mapStack
View
117 OpenSSL/X509.hsc
@@ -1,8 +1,17 @@
{- -*- haskell -*- -}
+
+-- #prune
+
+-- |An interface to X.509 certificate.
+
#include "HsOpenSSL.h"
+
module OpenSSL.X509
- ( X509
+ ( -- * Type
+ X509
, X509_
+
+ -- * Functions to manipulate certificate
, newX509
, wrapX509 -- private
, withX509Ptr -- private
@@ -17,6 +26,7 @@ module OpenSSL.X509
, printX509
+ -- * Accessors
, getVersion
, setVersion
@@ -50,13 +60,14 @@ import OpenSSL.ASN1
import OpenSSL.BIO
import OpenSSL.EVP.Digest
import OpenSSL.EVP.PKey
+import OpenSSL.EVP.Verify
import OpenSSL.Utils
import OpenSSL.Stack
import OpenSSL.X509.Name
-
+-- |@'X509'@ is an opaque object that represents X.509 certificate.
newtype X509 = X509 (ForeignPtr X509_)
-data X509_ = X509_
+data X509_
foreign import ccall unsafe "X509_new"
@@ -125,7 +136,22 @@ foreign import ccall unsafe "X509_sign"
foreign import ccall unsafe "X509_verify"
_verify :: Ptr X509_ -> Ptr EVP_PKEY -> IO Int
-
+-- |@'newX509'@ creates an empty certificate. You must set the
+-- following properties to and sign it (see 'signX509') to actually
+-- use the certificate.
+--
+-- [/Version/] See 'setVersion'.
+--
+-- [/Serial number/] See 'setSerialNumber'.
+--
+-- [/Issuer name/] See 'setIssuerName'.
+--
+-- [/Subject name/] See 'setSubjectName'.
+--
+-- [/Validity/] See 'setNotBefore' and 'setNotAfter'.
+--
+-- [/Public Key/] See 'setPublicKey'.
+--
newX509 :: IO X509
newX509 = _new >>= failIfNull >>= wrapX509
@@ -149,7 +175,7 @@ unsafeX509ToPtr (X509 x509) = unsafeForeignPtrToPtr x509
touchX509 :: X509 -> IO ()
touchX509 (X509 x509) = touchForeignPtr x509
-
+-- |@'compareX509' cert1 cert2@ compares two certificates.
compareX509 :: X509 -> X509 -> IO Ordering
compareX509 cert1 cert2
= withX509Ptr cert1 $ \ cert1Ptr ->
@@ -162,8 +188,13 @@ compareX509 cert1 cert2
| n < 0 = LT
| otherwise = EQ
-
-signX509 :: X509 -> EvpPKey -> Maybe EvpMD -> IO ()
+-- |@'signX509'@ signs a certificate with an issuer private key.
+signX509 :: X509 -- ^ The certificate to be signed.
+ -> PKey -- ^ The private key to sign with.
+ -> Maybe Digest -- ^ A hashing algorithm to use. If @Nothing@
+ -- the most suitable algorithm for the key
+ -- is automatically used.
+ -> IO ()
signX509 x509 pkey mDigest
= withX509Ptr x509 $ \ x509Ptr ->
withPKeyPtr pkey $ \ pkeyPtr ->
@@ -175,20 +206,24 @@ signX509 x509 pkey mDigest
>>= failIf (== 0)
return ()
-
-verifyX509 :: X509 -> EvpPKey -> IO Bool
+-- |@'verifyX509'@ verifies a signature of certificate with an issuer
+-- public key.
+verifyX509 :: X509 -- ^ The certificate to be verified.
+ -> PKey -- ^ The public key to verify with.
+ -> IO VerifyStatus
verifyX509 x509 pkey
= withX509Ptr x509 $ \ x509Ptr ->
withPKeyPtr pkey $ \ pkeyPtr ->
_verify x509Ptr pkeyPtr
>>= interpret
where
- interpret :: Int -> IO Bool
- interpret 1 = return True
- interpret 0 = return False
+ interpret :: Int -> IO VerifyStatus
+ interpret 1 = return VerifySuccess
+ interpret 0 = return VerifyFailure
interpret _ = raiseOpenSSLError
-
+-- |@'printX509' cert@ translates a certificate into human-readable
+-- format.
printX509 :: X509 -> IO String
printX509 x509
= do mem <- newMem
@@ -198,28 +233,30 @@ printX509 x509
>>= failIf (/= 1)
bioRead mem
-
+-- |@'getVersion' cert@ returns the version number of certificate. It
+-- seems the number is 0-origin: version 2 means X.509 v3.
getVersion :: X509 -> IO Int
getVersion x509
= withX509Ptr x509 $ \ x509Ptr ->
liftM fromIntegral $ _get_version x509Ptr
-
+-- |@'setVersion' cert ver@ updates the version number of certificate.
setVersion :: X509 -> Int -> IO ()
setVersion x509 ver
= withX509Ptr x509 $ \ x509Ptr ->
_set_version x509Ptr (fromIntegral ver)
>>= failIf (/= 1)
>> return ()
-
+-- |@'getSerialNumber' cert@ returns the serial number of certificate.
getSerialNumber :: X509 -> IO Integer
getSerialNumber x509
= withX509Ptr x509 $ \ x509Ptr ->
_get_serialNumber x509Ptr
>>= peekASN1Integer
-
+-- |@'setSerialNumber' cert num@ updates the serial number of
+-- certificate.
setSerialNumber :: X509 -> Integer -> IO ()
setSerialNumber x509 serial
= withX509Ptr x509 $ \ x509Ptr ->
@@ -228,14 +265,23 @@ setSerialNumber x509 serial
>>= failIf (/= 1)
>> return ()
-
-getIssuerName :: X509 -> Bool -> IO [(String, String)]
+-- |@'getIssuerName'@ returns the issuer name of certificate.
+getIssuerName :: X509 -- ^ The certificate to examine.
+ -> Bool -- ^ @True@ if you want the keys of each parts
+ -- to be of long form (e.g. \"commonName\"),
+ -- or @False@ if you don't (e.g. \"CN\").
+ -> IO [(String, String)] -- ^ Pairs of key and value,
+ -- for example \[(\"C\",
+ -- \"JP\"), (\"ST\",
+ -- \"Some-State\"), ...\].
getIssuerName x509 wantLongName
= withX509Ptr x509 $ \ x509Ptr ->
do namePtr <- _get_issuer_name x509Ptr
peekX509Name namePtr wantLongName
-
+-- |@'setIssuerName' cert name@ updates the issuer name of
+-- certificate. Keys of each parts may be of either long form or short
+-- form. See 'getIssuerName'.
setIssuerName :: X509 -> [(String, String)] -> IO ()
setIssuerName x509 issuer
= withX509Ptr x509 $ \ x509Ptr ->
@@ -244,14 +290,16 @@ setIssuerName x509 issuer
>>= failIf (/= 1)
>> return ()
-
+-- |@'getSubjectName' cert wantLongName@ returns the subject name of
+-- certificate. See 'getIssuerName'.
getSubjectName :: X509 -> Bool -> IO [(String, String)]
getSubjectName x509 wantLongName
= withX509Ptr x509 $ \ x509Ptr ->
do namePtr <- _get_subject_name x509Ptr
peekX509Name namePtr wantLongName
-
+-- |@'setSubjectName' cert name@ updates the subject name of
+-- certificate. See 'setIssuerName'.
setSubjectName :: X509 -> [(String, String)] -> IO ()
setSubjectName x509 subject
= withX509Ptr x509 $ \ x509Ptr ->
@@ -260,14 +308,16 @@ setSubjectName x509 subject
>>= failIf (/= 1)
>> return ()
-
+-- |@'getNotBefore' cert@ returns the time when the certificate begins
+-- to be valid.
getNotBefore :: X509 -> IO UTCTime
getNotBefore x509
= withX509Ptr x509 $ \ x509Ptr ->
_get_notBefore x509Ptr
>>= peekASN1Time
-
+-- |@'setNotBefore' cert utc@ updates the time when the certificate
+-- begins to be valid.
setNotBefore :: X509 -> UTCTime -> IO ()
setNotBefore x509 utc
= withX509Ptr x509 $ \ x509Ptr ->