packages feed

certificate 0.8.0 → 0.8.1

raw patch · 4 files changed

+159/−1 lines, 4 filesdep ~base

Dependency ranges changed: base

Files

+ System/Certificate/X509/MacOS.hs view
@@ -0,0 +1,14 @@+module System.Certificate.X509.MacOS+	( getSystemPath+	, readAll+	, findCertificate+	) where++getSystemPath :: IO FilePath+getSystemPath = undefined++readAll :: IO [Either ReadErr X509]+readAll = undefined++findCertificate :: (X509 -> Bool) -> IO (Maybe X509)+findCertificate f = undefined
+ System/Certificate/X509/Unix.hs view
@@ -0,0 +1,81 @@+-- |+-- Module      : System.Certificate.X509+-- License     : BSD-style+-- Maintainer  : Vincent Hanquez <vincent@snarc.org>+-- Stability   : experimental+-- Portability : unix only+--+-- this module is portable to unix system where there is usually+-- a /etc/ssl/certs with system X509 certificates.+--+-- the path can be dynamically override using the environment variable+-- defined by envPathOverride in the module, which by+-- default is SYSTEM_CERTIFICATE_PATH+--+module System.Certificate.X509.Unix+	( getSystemPath+	, readAll+	, findCertificate+	) where++import System.Directory (getDirectoryContents)+import System.Environment (getEnv)+import Data.List (isPrefixOf)++import Data.Either+import Data.Certificate.X509+import Data.Certificate.PEM+import qualified Data.ByteString as B+import qualified Data.ByteString.Lazy as L++import Control.Applicative ((<$>))+import Control.Exception+import Control.Monad++import Prelude hiding (catch)++defaultSystemPath :: FilePath+defaultSystemPath = "/etc/ssl/certs/"++envPathOverride :: String+envPathOverride = "SYSTEM_CERTIFICATE_PATH"++getSystemPath :: IO FilePath+getSystemPath = catch (getEnv envPathOverride) inDefault+	where+		inDefault :: IOException -> IO FilePath+		inDefault _ = return defaultSystemPath++data ReadErr =+	  Exception IOException+	| CertError String+	deriving (Show,Eq)++readCertificate :: FilePath -> IO (Either ReadErr X509)+readCertificate file = do+	rawdata <- try $ B.readFile file :: IO (Either IOException B.ByteString)+	either (return . Left . Exception) parseCert $ rawdata+	where+		parseCert pemdata = case parsePEMCert pemdata of+			Nothing       -> return $ Left $ CertError "certificate not in PEM format"+			Just certdata -> do+				return $ either (Left . CertError) Right $ decodeCertificate $ L.fromChunks [certdata]++readAll :: IO [Either ReadErr X509]+readAll = do+	path      <- getSystemPath+	certfiles <- filter (not . isPrefixOf ".") <$> getDirectoryContents path+	forM certfiles $ \certfile -> readCertificate (path ++ certfile)++findCertificate :: (X509 -> Bool) -> IO (Maybe X509)+findCertificate f = do+	path      <- getSystemPath+	certfiles <- filter (not . isPrefixOf ".") <$> getDirectoryContents path+	loop $ map (path ++) certfiles+	where+		loop []     = return Nothing+		loop (x:xs) = do+			ox509 <- readCertificate x+			case ox509 of+				Left _     -> loop xs+				Right x509 -> if f x509 then return $ Just x509 else loop xs
+ System/Certificate/X509/Win32.hs view
@@ -0,0 +1,60 @@+module System.Certificate.X509.Win32+	( findCertificate+	) where++import Foreign.Marshal.Alloc (allocaBytes)+import Foreign.Ptr (castPtr)++import Control.Exception (bracket, IOException)+import Control.Applicative ((<$>))++import System.Win32.Registry++import qualified Data.ByteString as B+import qualified Data.ByteString.Internal as B+import qualified Data.ByteString.Lazy as L++import Data.Certificate.X509+import Data.Certificate.X509Cert++import Data.Bits++defaultSystemPath :: FilePath+defaultSystemPath = "SOFTWARE\\Microsoft\\SystemCertificates\\CA\\Certificates"++listSubDirectories path = bracket openKey regCloseKey regEnumKeys+	where openKey = regOpenKeyEx hKEY_LOCAL_MACHINE path (kEY_ENUMERATE_SUB_KEYS .|. kEY_READ)++openValue path key toByteS = bracket openKey regCloseKey $ \hkey -> allocaBytes 4096 $ \mem -> do+		regQueryValueEx hkey key mem 4096 >>= toByteS mem+	where openKey = regOpenKeyEx hKEY_LOCAL_MACHINE path kEY_QUERY_VALUE++fromBlob mem ty+	| ty == rEG_BINARY = do+		len <- B.c_strlen (castPtr mem)+		B.create (fromIntegral len) (\bptr -> B.memcpy bptr mem len)+	| otherwise        = error "certificate blob have unexpected type"++getSystemPath :: IO FilePath+getSystemPath = undefined++data ReadErr =+	  Exception IOException+	| CertError String+	deriving (Show,Eq)++findCertificate :: (X509 -> Bool) -> IO (Maybe X509)+findCertificate f = do+	hashes <- listSubDirectories defaultSystemPath+	loop hashes+	where+		readCertificate path = do+			b <- openValue path "Blob" fromBlob+			return $ decodeCertificate $ L.fromChunks [b]++		loop []     = return Nothing+		loop (x:xs) = do+			cert <- readCertificate (defaultSystemPath ++ "\\" ++ x)+			case cert of+				Left _ -> loop xs+				Right x509 -> if f x509 then return $ Just x509 else loop xs
certificate.cabal view
@@ -1,5 +1,5 @@ Name:                certificate-Version:             0.8.0+Version:             0.8.1 Description:     Certificates and Key reader/writer     .@@ -39,12 +39,15 @@                      Data.Certificate.KeyRSA                      System.Certificate.X509   Other-modules:     Data.Certificate.X509Internal+                     System.Certificate.X509.Unix   ghc-options:       -Wall   if os(windows)      cpp-options: -DWINDOWS      Build-Depends:  Win32+     Other-modules:  System.Certificate.X509.Win32   if os(OSX)      cpp-options: -DMACOSX+     Other-modules:  System.Certificate.X509.MacOS  Executable           certificate   Main-Is:           Certificate.hs