{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LANGUAGE CApiFFI #-}
{-# OPTIONS_HADDOCK prune #-}
module OpenSSL.X509.Request
(
X509Req
, X509_REQ
, newX509Req
, wrapX509Req
, withX509ReqPtr
, signX509Req
, verifyX509Req
, printX509Req
, writeX509ReqDER
, makeX509FromReq
, getVersion
, setVersion
, getSubjectName
, setSubjectName
, getPublicKey
, setPublicKey
, addExtensions
, addExtensionToX509
)
where
import Control.Monad
import Data.Maybe
import Foreign
import Foreign.C
import OpenSSL.BIO
import OpenSSL.EVP.Digest hiding (digest)
import OpenSSL.EVP.PKey
import OpenSSL.EVP.Verify
import OpenSSL.EVP.Internal
import OpenSSL.Utils
import OpenSSL.X509 (X509)
import qualified OpenSSL.X509 as Cert
import OpenSSL.X509.Name
import Data.ByteString.Lazy (ByteString)
import OpenSSL.Stack
newtype X509Req = X509Req (ForeignPtr X509_REQ)
data {-# CTYPE "openssl/x509.h" "X509_REQ" #-} X509_REQ
data X509_EXT
foreign import capi unsafe "openssl/x509.h X509_REQ_new"
_new :: IO (Ptr X509_REQ)
foreign import capi unsafe "openssl/x509.h &X509_REQ_free"
_free :: FunPtr (Ptr X509_REQ -> IO ())
foreign import capi unsafe "openssl/x509.h X509_REQ_sign"
_sign :: Ptr X509_REQ -> Ptr EVP_PKEY -> Ptr EVP_MD -> IO CInt
foreign import capi unsafe "openssl/x509.h X509_REQ_verify"
_verify :: Ptr X509_REQ -> Ptr EVP_PKEY -> IO CInt
foreign import capi unsafe "openssl/x509.h X509_REQ_print"
_print :: Ptr BIO_ -> Ptr X509_REQ -> IO CInt
foreign import capi unsafe "openssl/x509.h i2d_X509_REQ_bio"
_req_to_der :: Ptr BIO_ -> Ptr X509_REQ -> IO CInt
foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_X509_REQ_get_version"
_get_version :: Ptr X509_REQ -> IO CLong
foreign import capi unsafe "openssl/x509.h X509_REQ_set_version"
_set_version :: Ptr X509_REQ -> CLong -> IO CInt
foreign import capi unsafe "HsOpenSSL.h HsOpenSSL_X509_REQ_get_subject_name"
_get_subject_name :: Ptr X509_REQ -> IO (Ptr X509_NAME)
foreign import capi unsafe "openssl/x509.h X509_REQ_set_subject_name"
_set_subject_name :: Ptr X509_REQ -> Ptr X509_NAME -> IO CInt
foreign import capi unsafe "openssl/x509.h X509_REQ_get_pubkey"
_get_pubkey :: Ptr X509_REQ -> IO (Ptr EVP_PKEY)
foreign import capi unsafe "openssl/x509.h X509_REQ_set_pubkey"
_set_pubkey :: Ptr X509_REQ -> Ptr EVP_PKEY -> IO CInt
foreign import capi unsafe "openssl/x509v3.h X509V3_EXT_nconf_nid"
_ext_create :: Ptr a -> Ptr b -> CInt -> CString -> IO (Ptr X509_EXT)
foreign import capi unsafe "openssl/x509.h X509_REQ_add_extensions"
_req_add_extensions :: Ptr X509_REQ -> Ptr STACK -> IO CInt
foreign import capi unsafe "openssl/x509.h X509_add_ext"
_X509_add_ext :: Ptr Cert.X509_ -> Ptr X509_EXT -> CInt -> IO CInt
newX509Req :: IO X509Req
newX509Req :: IO X509Req
newX509Req = IO (Ptr X509_REQ)
_new IO (Ptr X509_REQ) -> (Ptr X509_REQ -> IO X509Req) -> IO X509Req
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr X509_REQ -> IO X509Req
wrapX509Req
wrapX509Req :: Ptr X509_REQ -> IO X509Req
wrapX509Req :: Ptr X509_REQ -> IO X509Req
wrapX509Req = (ForeignPtr X509_REQ -> X509Req)
-> IO (ForeignPtr X509_REQ) -> IO X509Req
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ForeignPtr X509_REQ -> X509Req
X509Req (IO (ForeignPtr X509_REQ) -> IO X509Req)
-> (Ptr X509_REQ -> IO (ForeignPtr X509_REQ))
-> Ptr X509_REQ
-> IO X509Req
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FinalizerPtr X509_REQ -> Ptr X509_REQ -> IO (ForeignPtr X509_REQ)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr X509_REQ
_free
withX509ReqPtr :: X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr :: forall a. X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr (X509Req ForeignPtr X509_REQ
req) = ForeignPtr X509_REQ -> (Ptr X509_REQ -> IO a) -> IO a
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr X509_REQ
req
signX509Req :: KeyPair key =>
X509Req
-> key
-> Maybe Digest
-> IO ()
signX509Req :: forall key. KeyPair key => X509Req -> key -> Maybe Digest -> IO ()
signX509Req X509Req
req key
pkey Maybe Digest
mDigest
= X509Req -> (Ptr X509_REQ -> IO ()) -> IO ()
forall a. X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr X509Req
req ((Ptr X509_REQ -> IO ()) -> IO ())
-> (Ptr X509_REQ -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr X509_REQ
reqPtr ->
key -> (Ptr EVP_PKEY -> IO ()) -> IO ()
forall k a. PKey k => k -> (Ptr EVP_PKEY -> IO a) -> IO a
withPKeyPtr' key
pkey ((Ptr EVP_PKEY -> IO ()) -> IO ())
-> (Ptr EVP_PKEY -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr EVP_PKEY
pkeyPtr ->
do digest <- case Maybe Digest
mDigest of
Just Digest
md -> Digest -> IO Digest
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Digest
md
Maybe Digest
Nothing -> key -> IO Digest
forall k. PKey k => k -> IO Digest
pkeyDefaultMD key
pkey
withMDPtr digest $ \ Ptr EVP_MD
digestPtr ->
Ptr X509_REQ -> Ptr EVP_PKEY -> Ptr EVP_MD -> IO CInt
_sign Ptr X509_REQ
reqPtr Ptr EVP_PKEY
pkeyPtr Ptr EVP_MD
digestPtr
IO CInt -> (CInt -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (CInt -> Bool) -> CInt -> IO ()
forall a. (a -> Bool) -> a -> IO ()
failIf_ (CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
== CInt
0)
verifyX509Req :: PublicKey key =>
X509Req
-> key
-> IO VerifyStatus
verifyX509Req :: forall key. PublicKey key => X509Req -> key -> IO VerifyStatus
verifyX509Req X509Req
req key
pkey
= X509Req -> (Ptr X509_REQ -> IO VerifyStatus) -> IO VerifyStatus
forall a. X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr X509Req
req ((Ptr X509_REQ -> IO VerifyStatus) -> IO VerifyStatus)
-> (Ptr X509_REQ -> IO VerifyStatus) -> IO VerifyStatus
forall a b. (a -> b) -> a -> b
$ \ Ptr X509_REQ
reqPtr ->
key -> (Ptr EVP_PKEY -> IO VerifyStatus) -> IO VerifyStatus
forall k a. PKey k => k -> (Ptr EVP_PKEY -> IO a) -> IO a
withPKeyPtr' key
pkey ((Ptr EVP_PKEY -> IO VerifyStatus) -> IO VerifyStatus)
-> (Ptr EVP_PKEY -> IO VerifyStatus) -> IO VerifyStatus
forall a b. (a -> b) -> a -> b
$ \ Ptr EVP_PKEY
pkeyPtr ->
Ptr X509_REQ -> Ptr EVP_PKEY -> IO CInt
_verify Ptr X509_REQ
reqPtr Ptr EVP_PKEY
pkeyPtr
IO CInt -> (CInt -> IO VerifyStatus) -> IO VerifyStatus
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= CInt -> IO VerifyStatus
interpret
where
interpret :: CInt -> IO VerifyStatus
interpret :: CInt -> IO VerifyStatus
interpret CInt
1 = VerifyStatus -> IO VerifyStatus
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return VerifyStatus
VerifySuccess
interpret CInt
0 = VerifyStatus -> IO VerifyStatus
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return VerifyStatus
VerifyFailure
interpret CInt
_ = IO VerifyStatus
forall a. IO a
raiseOpenSSLError
printX509Req :: X509Req -> IO String
printX509Req :: X509Req -> IO String
printX509Req X509Req
req
= do mem <- IO BIO
newMem
withBioPtr mem $ \ Ptr BIO_
memPtr ->
X509Req -> (Ptr X509_REQ -> IO ()) -> IO ()
forall a. X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr X509Req
req ((Ptr X509_REQ -> IO ()) -> IO ())
-> (Ptr X509_REQ -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr X509_REQ
reqPtr ->
Ptr BIO_ -> Ptr X509_REQ -> IO CInt
_print Ptr BIO_
memPtr Ptr X509_REQ
reqPtr
IO CInt -> (CInt -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (CInt -> Bool) -> CInt -> IO ()
forall a. (a -> Bool) -> a -> IO ()
failIf_ (CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CInt
1)
bioRead mem
writeX509ReqDER :: X509Req -> IO ByteString
writeX509ReqDER :: X509Req -> IO ByteString
writeX509ReqDER X509Req
req
= do mem <- IO BIO
newMem
withBioPtr mem $ \ Ptr BIO_
memPtr ->
X509Req -> (Ptr X509_REQ -> IO ()) -> IO ()
forall a. X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr X509Req
req ((Ptr X509_REQ -> IO ()) -> IO ())
-> (Ptr X509_REQ -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr X509_REQ
reqPtr ->
Ptr BIO_ -> Ptr X509_REQ -> IO CInt
_req_to_der Ptr BIO_
memPtr Ptr X509_REQ
reqPtr
IO CInt -> (CInt -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (CInt -> Bool) -> CInt -> IO ()
forall a. (a -> Bool) -> a -> IO ()
failIf_ (CInt -> CInt -> Bool
forall a. Ord a => a -> a -> Bool
< CInt
0)
bioReadLBS mem
getVersion :: X509Req -> IO Int
getVersion :: X509Req -> IO Int
getVersion X509Req
req
= X509Req -> (Ptr X509_REQ -> IO Int) -> IO Int
forall a. X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr X509Req
req ((Ptr X509_REQ -> IO Int) -> IO Int)
-> (Ptr X509_REQ -> IO Int) -> IO Int
forall a b. (a -> b) -> a -> b
$ \ Ptr X509_REQ
reqPtr ->
(CLong -> Int) -> IO CLong -> IO Int
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM CLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (IO CLong -> IO Int) -> IO CLong -> IO Int
forall a b. (a -> b) -> a -> b
$ Ptr X509_REQ -> IO CLong
_get_version Ptr X509_REQ
reqPtr
setVersion :: X509Req -> Int -> IO ()
setVersion :: X509Req -> Int -> IO ()
setVersion X509Req
req Int
ver
= X509Req -> (Ptr X509_REQ -> IO ()) -> IO ()
forall a. X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr X509Req
req ((Ptr X509_REQ -> IO ()) -> IO ())
-> (Ptr X509_REQ -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr X509_REQ
reqPtr ->
Ptr X509_REQ -> CLong -> IO CInt
_set_version Ptr X509_REQ
reqPtr (Int -> CLong
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
ver)
IO CInt -> (CInt -> IO CInt) -> IO CInt
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (CInt -> Bool) -> CInt -> IO CInt
forall a. (a -> Bool) -> a -> IO a
failIf (CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CInt
1)
IO CInt -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
getSubjectName :: X509Req -> Bool -> IO [(String, String)]
getSubjectName :: X509Req -> Bool -> IO [(String, String)]
getSubjectName X509Req
req Bool
wantLongName
= X509Req
-> (Ptr X509_REQ -> IO [(String, String)]) -> IO [(String, String)]
forall a. X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr X509Req
req ((Ptr X509_REQ -> IO [(String, String)]) -> IO [(String, String)])
-> (Ptr X509_REQ -> IO [(String, String)]) -> IO [(String, String)]
forall a b. (a -> b) -> a -> b
$ \ Ptr X509_REQ
reqPtr ->
do namePtr <- Ptr X509_REQ -> IO (Ptr X509_NAME)
_get_subject_name Ptr X509_REQ
reqPtr
peekX509Name namePtr wantLongName
setSubjectName :: X509Req -> [(String, String)] -> IO ()
setSubjectName :: X509Req -> [(String, String)] -> IO ()
setSubjectName X509Req
req [(String, String)]
subject
= X509Req -> (Ptr X509_REQ -> IO ()) -> IO ()
forall a. X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr X509Req
req ((Ptr X509_REQ -> IO ()) -> IO ())
-> (Ptr X509_REQ -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr X509_REQ
reqPtr ->
[(String, String)] -> (Ptr X509_NAME -> IO ()) -> IO ()
forall a. [(String, String)] -> (Ptr X509_NAME -> IO a) -> IO a
withX509Name [(String, String)]
subject ((Ptr X509_NAME -> IO ()) -> IO ())
-> (Ptr X509_NAME -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr X509_NAME
namePtr ->
Ptr X509_REQ -> Ptr X509_NAME -> IO CInt
_set_subject_name Ptr X509_REQ
reqPtr Ptr X509_NAME
namePtr
IO CInt -> (CInt -> IO CInt) -> IO CInt
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (CInt -> Bool) -> CInt -> IO CInt
forall a. (a -> Bool) -> a -> IO a
failIf (CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CInt
1)
IO CInt -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
getPublicKey :: X509Req -> IO SomePublicKey
getPublicKey :: X509Req -> IO SomePublicKey
getPublicKey X509Req
req
= X509Req -> (Ptr X509_REQ -> IO SomePublicKey) -> IO SomePublicKey
forall a. X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr X509Req
req ((Ptr X509_REQ -> IO SomePublicKey) -> IO SomePublicKey)
-> (Ptr X509_REQ -> IO SomePublicKey) -> IO SomePublicKey
forall a b. (a -> b) -> a -> b
$ \ Ptr X509_REQ
reqPtr ->
(Maybe SomePublicKey -> SomePublicKey)
-> IO (Maybe SomePublicKey) -> IO SomePublicKey
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe SomePublicKey -> SomePublicKey
forall a. HasCallStack => Maybe a -> a
fromJust
( Ptr X509_REQ -> IO (Ptr EVP_PKEY)
_get_pubkey Ptr X509_REQ
reqPtr
IO (Ptr EVP_PKEY)
-> (Ptr EVP_PKEY -> IO (Ptr EVP_PKEY)) -> IO (Ptr EVP_PKEY)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr EVP_PKEY -> IO (Ptr EVP_PKEY)
forall a. Ptr a -> IO (Ptr a)
failIfNull
IO (Ptr EVP_PKEY) -> (Ptr EVP_PKEY -> IO VaguePKey) -> IO VaguePKey
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr EVP_PKEY -> IO VaguePKey
wrapPKeyPtr
IO VaguePKey
-> (VaguePKey -> IO (Maybe SomePublicKey))
-> IO (Maybe SomePublicKey)
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= VaguePKey -> IO (Maybe SomePublicKey)
forall k. PKey k => VaguePKey -> IO (Maybe k)
fromPKey
)
setPublicKey :: PublicKey key => X509Req -> key -> IO ()
setPublicKey :: forall key. PublicKey key => X509Req -> key -> IO ()
setPublicKey X509Req
req key
pkey
= X509Req -> (Ptr X509_REQ -> IO ()) -> IO ()
forall a. X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr X509Req
req ((Ptr X509_REQ -> IO ()) -> IO ())
-> (Ptr X509_REQ -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr X509_REQ
reqPtr ->
key -> (Ptr EVP_PKEY -> IO ()) -> IO ()
forall k a. PKey k => k -> (Ptr EVP_PKEY -> IO a) -> IO a
withPKeyPtr' key
pkey ((Ptr EVP_PKEY -> IO ()) -> IO ())
-> (Ptr EVP_PKEY -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ Ptr EVP_PKEY
pkeyPtr ->
Ptr X509_REQ -> Ptr EVP_PKEY -> IO CInt
_set_pubkey Ptr X509_REQ
reqPtr Ptr EVP_PKEY
pkeyPtr
IO CInt -> (CInt -> IO CInt) -> IO CInt
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (CInt -> Bool) -> CInt -> IO CInt
forall a. (a -> Bool) -> a -> IO a
failIf (CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CInt
1)
IO CInt -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
addExtensions :: X509Req -> [(Int, String)] -> IO CInt
addExtensions :: X509Req -> [(Int, String)] -> IO CInt
addExtensions X509Req
req [(Int, String)]
exts =
X509Req -> (Ptr X509_REQ -> IO CInt) -> IO CInt
forall a. X509Req -> (Ptr X509_REQ -> IO a) -> IO a
withX509ReqPtr X509Req
req ((Ptr X509_REQ -> IO CInt) -> IO CInt)
-> (Ptr X509_REQ -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \Ptr X509_REQ
reqPtr -> do
extPtrs <- [(Int, String)]
-> ((Int, String) -> IO (Ptr X509_EXT)) -> IO [Ptr X509_EXT]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(Int, String)]
exts (Int, String) -> IO (Ptr X509_EXT)
forall {a}. Integral a => (a, String) -> IO (Ptr X509_EXT)
make
withStack extPtrs $ _req_add_extensions reqPtr
where
make :: (a, String) -> IO (Ptr X509_EXT)
make (a
nid, String
str) = String -> (CString -> IO (Ptr X509_EXT)) -> IO (Ptr X509_EXT)
forall a. String -> (CString -> IO a) -> IO a
withCString String
str ((CString -> IO (Ptr X509_EXT)) -> IO (Ptr X509_EXT))
-> (CString -> IO (Ptr X509_EXT)) -> IO (Ptr X509_EXT)
forall a b. (a -> b) -> a -> b
$ Ptr (ZonkAny 3)
-> Ptr (ZonkAny 2) -> CInt -> CString -> IO (Ptr X509_EXT)
forall a b. Ptr a -> Ptr b -> CInt -> CString -> IO (Ptr X509_EXT)
_ext_create Ptr (ZonkAny 3)
forall a. Ptr a
nullPtr Ptr (ZonkAny 2)
forall a. Ptr a
nullPtr (a -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
nid)
makeX509FromReq :: X509Req
-> X509
-> IO X509
makeX509FromReq :: X509Req -> X509 -> IO X509
makeX509FromReq X509Req
req X509
caCert
= do reqPubKey <- X509Req -> IO SomePublicKey
getPublicKey X509Req
req
verified <- verifyX509Req req reqPubKey
when (verified == VerifyFailure)
$ fail "makeX509FromReq: the request isn't properly signed by its own key."
cert <- Cert.newX509
Cert.setVersion cert 2
Cert.setIssuerName cert =<< Cert.getSubjectName caCert False
Cert.setSubjectName cert =<< getSubjectName req False
Cert.setPublicKey cert =<< getPublicKey req
return cert
addExtensionToX509 :: X509 -> Int -> String -> IO Bool
addExtensionToX509 :: X509 -> Int -> String -> IO Bool
addExtensionToX509 (Cert.X509 ForeignPtr X509_
certFPtr) Int
nid String
value = do
result <- ForeignPtr X509_ -> (Ptr X509_ -> IO Bool) -> IO Bool
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr X509_
certFPtr ((Ptr X509_ -> IO Bool) -> IO Bool)
-> (Ptr X509_ -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \Ptr X509_
certPtr ->
String -> (CString -> IO Bool) -> IO Bool
forall a. String -> (CString -> IO a) -> IO a
withCString String
value ((CString -> IO Bool) -> IO Bool)
-> (CString -> IO Bool) -> IO Bool
forall a b. (a -> b) -> a -> b
$ \CString
cValue -> do
extPtr <- Ptr (ZonkAny 1)
-> Ptr (ZonkAny 0) -> CInt -> CString -> IO (Ptr X509_EXT)
forall a b. Ptr a -> Ptr b -> CInt -> CString -> IO (Ptr X509_EXT)
_ext_create Ptr (ZonkAny 1)
forall a. Ptr a
nullPtr Ptr (ZonkAny 0)
forall a. Ptr a
nullPtr (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nid) CString
cValue
if extPtr /= nullPtr
then do
res <- _X509_add_ext certPtr extPtr (-1)
return (res == 0)
else return False
return result