1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
module OpenSSL.X509.SystemStore.MacOSX
( contextLoadSystemCerts
) where
import System.Process (createProcess, waitForProcess, proc,
CreateProcess(std_out), StdStream(CreatePipe))
import System.IO (hGetLine, hIsEOF)
import Control.Monad ((>=>))
import Control.Exception (throwIO, ErrorCall(ErrorCall))
import OpenSSL.Session (SSLContext, contextGetCAStore)
import OpenSSL.X509 (X509)
import OpenSSL.X509.Store (addCertToStore)
import OpenSSL.PEM (readX509)
contextLoadSystemCerts :: SSLContext -> IO ()
contextLoadSystemCerts ctx = do
st <- contextGetCAStore ctx
iterSystemCertsX509 (addCertToStore st)
iterSystemCertsX509 :: (X509 -> IO ()) -> IO ()
iterSystemCertsX509 action =
iterSystemCertsPEM (readX509 >=> action)
iterSystemCertsPEM :: (String -> IO ()) -> IO ()
iterSystemCertsPEM action = do
(_, Just hdl, _, ph) <- createProcess cmd {std_out = CreatePipe}
loop [] hdl
_ <- waitForProcess ph
return ()
where
loop ls hdl = do
eof <- hIsEOF hdl
if not eof then do
s <- hGetLine hdl
let ls' = s : ls
if s == endCert then do
action (unlines $ reverse ls')
loop [] hdl
else
loop ls' hdl
else if null ls then
return ()
else
throwIO $ ErrorCall "Incomplete certificate"
endCert = "-----END CERTIFICATE-----"
cmd = proc "security"
["export", "-t", "certs", "-f", "pemseq", "-k", rootCAKeyChain]
rootCAKeyChain = "/System/Library/Keychains/SystemRootCertificates.keychain"
|