botan-low-0.0.2.0: src/Botan/Low/X509/Path.hs
module Botan.Low.X509.Path where
import Foreign.Marshal.Utils
import Botan.Low.Error
import Botan.Low.Make
import Botan.Low.Prelude
import Botan.Low.X509
import Botan.Low.X509.Store
import Botan.Bindings.X509
import Botan.Bindings.X509.Path
newtype X509PathRestrictions = MkX509PathRestrictions { getX509PathRestrictionsForeignPtr :: ForeignPtr X509PathRestrictionsStruct }
withX509PathRestrictionsPtr :: X509PathRestrictions -> (X509PathRestrictionsPtr -> IO a) -> IO a
withX509PathRestrictionsPtr = withForeignPtr . getX509PathRestrictionsForeignPtr
x509PathRestrictionsDestroy :: X509PathRestrictions -> IO ()
x509PathRestrictionsDestroy restrictions = finalizeForeignPtr (getX509PathRestrictionsForeignPtr restrictions)
x509PathRestrictionsCreate :: Bool -> Int -> Bool -> Word64 -> X509CertStore -> IO X509PathRestrictions
x509PathRestrictionsCreate require_rev minimum_key_strength ocsp_all_intermediates max_ocsp_age trusted_ocsp_responders = do
withX509CertStorePtr trusted_ocsp_responders $ \ trustedStorePtr -> do
mkInit
MkX509PathRestrictions
(\ pvPtr -> botan_x509_path_restrictions_create
pvPtr
(fromBool require_rev)
(fromIntegral minimum_key_strength)
(fromBool ocsp_all_intermediates)
max_ocsp_age
trustedStorePtr
)
botan_x509_path_restrictions_destroy
-- TODO: x509PathRestrictionsCreateTrustedHashes
newtype X509PathValidation = MkX509PathValidation { getX509PathValidationForeignPtr :: ForeignPtr X509PathValidationStruct }
withX509PathValidationPtr :: X509PathValidation -> (X509PathValidationPtr -> IO a) -> IO a
withX509PathValidationPtr = withForeignPtr . getX509PathValidationForeignPtr
x509PathValidationDestroy :: X509PathValidation -> IO ()
x509PathValidationDestroy validation = finalizeForeignPtr (getX509PathValidationForeignPtr validation)
-- NOTE: OCSPResponse not yet implemented
x509PathValidate :: X509Cert -> X509PathRestrictions -> X509CertStore -> ByteString -> Word32 -> Word64 -> Word64 -> Ptr () -> IO X509PathValidation
x509PathValidate cert restrictions store hostname usage validationTime ocspTimeout ocspResponse = do
withX509Cert cert $ \ certPtr -> do
withX509PathRestrictionsPtr restrictions $ \ restrictionsPtr -> do
withX509CertStorePtr store $ \ storePtr -> do
asCString hostname $ \ hostnamePtr -> do
mkInit
MkX509PathValidation
(\ pvPtr -> botan_x509_path_validate
pvPtr
certPtr
restrictionsPtr
storePtr
hostnamePtr
(fromIntegral usage)
validationTime
ocspTimeout
ocspResponse
)
botan_x509_path_validation_destroy
x509PathValidationSuccessfulValidation :: X509PathValidation -> IO Bool
x509PathValidationSuccessfulValidation pv = withX509PathValidationPtr pv $ \ pvPtr -> do
throwBotanCatchingSuccess $ botan_x509_path_validation_successful_validation pvPtr
x509PathValidationResultString :: X509PathValidation -> IO ByteString
x509PathValidationResultString pv = withX509PathValidationPtr pv $ \ pvPtr -> do
allocBytesQueryingCString $ \ resultPtr resultLen -> do
botan_x509_path_validation_result_string resultPtr resultLen pvPtr
x509PathValidationTrustRoot :: X509PathValidation -> IO X509Cert
x509PathValidationTrustRoot pv = withX509PathValidationPtr pv $ \ pvPtr -> do
mkInit
MkX509Cert
(\ certPtr -> botan_x509_path_validation_trust_root certPtr pvPtr)
botan_x509_cert_destroy
-- TODO: Need some sort of allocArrayQuerying, or a mkArrayInit
x509PathValidationCertPath :: X509PathValidation -> IO [X509Cert]
x509PathValidationCertPath pv = withX509PathValidationPtr pv $ \ pvPtr -> do
let fn arrPtr szPtr = botan_x509_path_validation_cert_path arrPtr szPtr pvPtr
alloca $ \ szPtr -> do
code <- fn nullPtr szPtr
case code of
InsufficientBufferSpace -> do
sz <- fromIntegral <$> peek szPtr
allocaArray sz $ \ arrPtr -> do
throwBotanIfNegative_ $ fn arrPtr szPtr
certPtrs <- peekArray sz arrPtr
-- NOTE: Cannot use mkInit because that performs an alloca and a peek,
-- whereas we have already performed that work here
forM certPtrs $ \ certPtr -> do
foreignPtr <- newForeignPtr botan_x509_cert_destroy certPtr
return $ MkX509Cert foreignPtr
_ -> throwBotanError code
type X509PathValidationStatusCode = Int
x509PathValidationStatusCode :: X509PathValidation -> IO X509PathValidationStatusCode
x509PathValidationStatusCode pv = withX509PathValidationPtr pv $ \ pvPtr -> do
alloca $ \ statusCodePtr -> do
throwBotanIfNegative_ $ botan_x509_path_validation_status_code statusCodePtr pvPtr
fromIntegral <$> peek statusCodePtr
-- TODO: Need some sort of allocArrayQuerying, or a mkArrayInit
x509PathValidationAllStatusCodes :: X509PathValidation -> IO [X509PathValidationStatusCode]
x509PathValidationAllStatusCodes pv = withX509PathValidationPtr pv $ \ pvPtr -> do
let fn arrPtr szPtr = botan_x509_path_validation_all_status_codes arrPtr szPtr pvPtr
alloca $ \ szPtr -> do
code <- fn nullPtr szPtr
case code of
InsufficientBufferSpace -> do
sz <- fromIntegral <$> peek szPtr
allocaArray sz $ \ arrPtr -> do
throwBotanIfNegative_ $ fn arrPtr szPtr
fmap fromIntegral <$> peekArray sz arrPtr
_ -> throwBotanError code
-- NOTE: Array of strings - extra tricky, not finished yet, will be reused
-- NOTE: Similar to x509DNGetAttribute / x509DNGetContents
x509PathValidationTrustedHashes :: X509PathValidation -> IO [ByteString]
x509PathValidationTrustedHashes pv = withX509PathValidationPtr pv $ \ pvPtr -> do
let fn arrPtr sizesPtr szPtr = botan_x509_path_validation_trusted_hashes arrPtr sizesPtr szPtr pvPtr
alloca $ \ szPtr -> do
code <- fn nullPtr nullPtr szPtr
case code of
InsufficientBufferSpace -> do
sz <- fromIntegral <$> peek szPtr
allocaArray sz $ \ sizesPtr -> do
code' <- fn nullPtr sizesPtr szPtr
case code' of
-- TODO: Actually fill out array of strings
_ -> undefined
_ -> throwBotanError code