certificate 1.1.1 → 1.2.0
raw patch · 6 files changed
+80/−173 lines, 6 filesdep +pemdep −base64-bytestringPVP ok
version bump matches the API change (PVP)
Dependencies added: pem
Dependencies removed: base64-bytestring
API changes (from Hackage documentation)
- Data.Certificate.KeyDSA: Private :: Int -> Integer -> Integer -> Integer -> Integer -> Integer -> Private
- Data.Certificate.KeyDSA: data Private
- Data.Certificate.KeyDSA: g :: Private -> Integer
- Data.Certificate.KeyDSA: p :: Private -> Integer
- Data.Certificate.KeyDSA: priv :: Private -> Integer
- Data.Certificate.KeyDSA: pub :: Private -> Integer
- Data.Certificate.KeyDSA: q :: Private -> Integer
- Data.Certificate.KeyDSA: version :: Private -> Int
- Data.Certificate.PEM: findPEM :: String -> [PEM] -> Maybe ByteString
- Data.Certificate.PEM: parsePEMCert :: ByteString -> Maybe ByteString
- Data.Certificate.PEM: parsePEMCertReq :: ByteString -> Maybe ByteString
- Data.Certificate.PEM: parsePEMKey :: ByteString -> Maybe ByteString
- Data.Certificate.PEM: parsePEMKeyDSA :: ByteString -> Maybe ByteString
- Data.Certificate.PEM: parsePEMKeyRSA :: ByteString -> Maybe ByteString
- Data.Certificate.PEM: parsePEMs :: ByteString -> [PEM]
- Data.Certificate.KeyDSA: decodePrivate :: ByteString -> Either String Private
+ Data.Certificate.KeyDSA: decodePrivate :: ByteString -> Either String (PublicKey, PrivateKey)
- Data.Certificate.KeyDSA: encodePrivate :: Private -> ByteString
+ Data.Certificate.KeyDSA: encodePrivate :: (PublicKey, PrivateKey) -> ByteString
Files
- Certificate.hs +22/−23
- Data/Certificate/KeyDSA.hs +32/−41
- Data/Certificate/PEM.hs +0/−67
- System/Certificate/X509/MacOS.hs +0/−1
- System/Certificate/X509/Unix.hs +24/−38
- certificate.cabal +2/−3
Certificate.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE DeriveDataTypeable, OverloadedStrings #-} +import Data.Either import qualified Data.ByteString.Lazy as L import qualified Data.ByteString.Lazy.Char8 as LC import qualified Data.ByteString as B@@ -8,7 +9,8 @@ import qualified Data.Certificate.X509 as X509 import Data.Certificate.KeyRSA as KeyRSA import Data.Certificate.KeyDSA as KeyDSA-import Data.Certificate.PEM+import Data.List (find)+import Data.PEM (pemParseBS, pemContent, pemName) import System.Console.CmdArgs import Control.Monad import Control.Applicative ((<$>))@@ -104,15 +106,15 @@ , "coefficient: " ++ (show $ RSA.private_qinv privkey) ] -showDSAKey :: KeyDSA.Private -> String-showDSAKey key = unlines- [ "version: " ++ (show $ KeyDSA.version key)- , "priv " ++ (show $ KeyDSA.priv key)- , "pub: " ++ (show $ KeyDSA.pub key)- , "p: " ++ (show $ KeyDSA.p key)- , "q: " ++ (show $ KeyDSA.q key)- , "g: " ++ (show $ KeyDSA.g key)+showDSAKey :: (DSA.PublicKey,DSA.PrivateKey) -> String+showDSAKey (pubkey,privkey) = unlines+ [ "priv " ++ (show $ DSA.private_x privkey)+ , "pub: " ++ (show $ DSA.public_y pubkey)+ , "p: " ++ (show p)+ , "q: " ++ (show g)+ , "g: " ++ (show q) ]+ where (p,g,q) = DSA.private_params privkey showASN1 :: Int -> [ASN1] -> IO () showASN1 at = prettyPrint at where@@ -153,22 +155,17 @@ p (BMPString t) = putStr ("bmpstring: " ++ t) p (Other tc tn x) = putStr "other" -doMain :: CertMainOpts -> IO ()-doMain opts@(X509 _ _ _ _ _) = do- cert <- maybe (error "cannot read PEM certificate") (id) . parsePEMCert <$> B.readFile (head $ files opts)+parsePEMCert = either (const []) (rights . map getCert) . pemParseBS+ where getCert pem = either Left (\x -> Right (pemContent pem,x)) $ X509.decodeCertificate $ L.fromChunks [pemContent pem] +processCert opts (cert, x509) = do when (raw opts) $ putStrLn $ hexdump $ L.fromChunks [cert] when (asn1 opts) $ case decodeASN1Stream $ L.fromChunks [cert] of Left err -> error ("decoding ASN1 failed: " ++ show err) Right asn1 -> showASN1 0 asn1 - let x509o = X509.decodeCertificate $ L.fromChunks [cert]- let x509 = case x509o of- Left err -> error ("decoding certificate failed: " ++ show err)- Right c -> c when (text opts || not (or [asn1 opts,raw opts])) $ showCert x509 when (verify opts) $ verifyCert x509- exitSuccess where verifyCert x509@(X509.X509 cert _ _ sigalg sig) = do sysx509 <- SysCert.findCertificate (matchsysX509 cert)@@ -208,20 +205,22 @@ let x = X509.certSubjectDN syscert let y = X509.certIssuerDN cert x == y++doMain :: CertMainOpts -> IO ()+doMain opts@(X509 {}) = B.readFile (head $ files opts) >>= mapM_ (processCert opts) . parsePEMCert doMain (Key files) = do- content <- B.readFile $ head files- let pems = parsePEMs content- let rsadata = findPEM "RSA PRIVATE KEY" pems- let dsadata = findPEM "DSA PRIVATE KEY" pems+ pems <- either error id . pemParseBS <$> B.readFile (head files)+ let rsadata = find ((== "RSA PRIVATE KEY") . pemName) pems+ let dsadata = find ((== "DSA PRIVATE KEY") . pemName) pems case (rsadata, dsadata) of (Just x, _) -> do- let rsaKey = KeyRSA.decodePrivate $ L.fromChunks [x]+ let rsaKey = KeyRSA.decodePrivate $ L.fromChunks [pemContent x] case rsaKey of Left err -> error err Right k -> putStrLn $ showRSAKey k (_, Just x) -> do- let rsaKey = KeyDSA.decodePrivate $ L.fromChunks [x]+ let rsaKey = KeyDSA.decodePrivate $ L.fromChunks [pemContent x] case rsaKey of Left err -> error err Right k -> putStrLn $ showDSAKey k
Data/Certificate/KeyDSA.hs view
@@ -9,55 +9,46 @@ -- module Data.Certificate.KeyDSA- ( Private(..)- , decodePrivate- , encodePrivate- ) where+ ( decodePrivate+ , encodePrivate+ ) where import Data.ASN1.DER (encodeASN1Stream, ASN1(..), ASN1ConstructionType(..)) import Data.ASN1.BER (decodeASN1Stream) import qualified Data.ByteString.Lazy as L--data Private = Private- { version :: Int- , priv :: Integer- , pub :: Integer- , p :: Integer- , q :: Integer- , g :: Integer- }+import qualified Crypto.Types.PubKey.DSA as DSA -parsePrivate :: [ASN1] -> Either String Private+parsePrivate :: [ASN1] -> Either String (DSA.PublicKey, DSA.PrivateKey) parsePrivate- [ Start Sequence- , IntVal ver, IntVal p_pub, IntVal p_priv, IntVal p_p, IntVal p_g, IntVal p_q- , End Sequence ] =- Right $ Private- { version = fromIntegral ver- , priv = p_priv- , pub = p_pub- , p = p_p- , q = p_q- , g = p_g- }+ [ Start Sequence+ , IntVal 0, IntVal pub, IntVal priv, IntVal p, IntVal g, IntVal q+ , End Sequence ] = Right (pubkey, privkey)+ where+ privkey = DSA.PrivateKey { DSA.private_params = params, DSA.private_x = priv }+ pubkey = DSA.PublicKey { DSA.public_params = params, DSA.public_y = pub }+ params = (p,g,q) +parsePrivate (Start Sequence : IntVal n : _)+ | n == 0 = Left "DSA key format: not recognized"+ | otherwise = Left ("DSA key format: unknown version " ++ show n) parsePrivate _ = Left "unexpected format" -decodePrivate :: L.ByteString -> Either String Private+decodePrivate :: L.ByteString -> Either String (DSA.PublicKey, DSA.PrivateKey) decodePrivate dat = either (Left . show) parsePrivate $ decodeASN1Stream dat -encodePrivate :: Private -> L.ByteString-encodePrivate pk =- case encodeASN1Stream pkseq of- Left err -> error $ show err- Right lbs -> lbs- where pkseq =- [ Start Sequence- , IntVal $ fromIntegral $ version pk- , IntVal $ pub pk- , IntVal $ priv pk- , IntVal $ p pk- , IntVal $ g pk- , IntVal $ q pk- , End Sequence- ]+encodePrivate :: (DSA.PublicKey, DSA.PrivateKey) -> L.ByteString+encodePrivate (pubkey, privkey) =+ case encodeASN1Stream pkseq of+ Left err -> error $ show err+ Right lbs -> lbs+ where pkseq =+ [ Start Sequence+ , IntVal 0+ , IntVal $ DSA.public_y pubkey+ , IntVal $ DSA.private_x privkey+ , IntVal p+ , IntVal g+ , IntVal q+ , End Sequence+ ]+ (p,g,q) = DSA.private_params privkey
− Data/Certificate/PEM.hs
@@ -1,67 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}---- |--- Module : Data.Certificate.PEM--- License : BSD-style--- Maintainer : Vincent Hanquez <vincent@snarc.org>--- Stability : experimental--- Portability : unknown------ Read PEM files----module Data.Certificate.PEM- ( parsePEMCert- , parsePEMCertReq- , parsePEMKey- , parsePEMKeyRSA- , parsePEMKeyDSA- , parsePEMs- , findPEM- ) where--import Data.ByteString (ByteString)-import qualified Data.ByteString as B-import qualified Data.ByteString.Char8 as BC-import Data.ByteString.Base64-import Data.List--type PEM = (String, ByteString)--takeTillEnd :: [ByteString] -> ([ByteString], [ByteString])-takeTillEnd ls = break (BC.isPrefixOf "-----END ") ls--findSectionName :: ByteString -> String-findSectionName s = BC.unpack $ B.take (B.length x - 5) x- where x = B.drop 11 s--parsePEMSections :: [ByteString] -> [PEM]-parsePEMSections [] = []-parsePEMSections (x:xs)- | "-----BEGIN " `B.isPrefixOf` x =- let (content, rest) = takeTillEnd xs in- case decode $ B.concat content of- Left _ -> parsePEMSections rest- Right y -> (findSectionName x, y) : parsePEMSections rest- | otherwise = parsePEMSections xs--parsePEMs :: ByteString -> [PEM]-parsePEMs content = parsePEMSections $ BC.lines content--findPEM :: String -> [PEM] -> Maybe ByteString-findPEM name = maybe Nothing (Just . snd) . find ((==) name . fst)--parsePEMCert :: ByteString -> Maybe ByteString-parsePEMCert = findPEM "CERTIFICATE" . parsePEMs--parsePEMCertReq :: ByteString -> Maybe ByteString-parsePEMCertReq = findPEM "CERTIFICATE REQUEST" . parsePEMs--parsePEMKeyRSA :: ByteString -> Maybe ByteString-parsePEMKeyRSA = findPEM "RSA PRIVATE KEY" . parsePEMs--parsePEMKeyDSA :: ByteString -> Maybe ByteString-parsePEMKeyDSA = findPEM "DSA PRIVATE KEY" . parsePEMs--{-# DEPRECATED parsePEMKey "use parsePEMKeyRSA now" #-}-parsePEMKey :: ByteString -> Maybe ByteString-parsePEMKey = parsePEMKeyRSA
System/Certificate/X509/MacOS.hs view
@@ -3,7 +3,6 @@ ) where import Data.Certificate.X509-import Data.Certificate.PEM import System.Process import Data.ByteString hiding (filter, map) import qualified Data.ByteString.Lazy as LBS
System/Certificate/X509/Unix.hs view
@@ -13,18 +13,18 @@ -- default is SYSTEM_CERTIFICATE_PATH -- module System.Certificate.X509.Unix- ( getSystemPath- , readAll- , findCertificate- ) where+ ( getSystemPath+ , readAll+ , findCertificate+ ) where import System.Directory (getDirectoryContents) import System.Environment (getEnv)-import Data.List (isPrefixOf)+import Data.List (isPrefixOf, find) +import Data.PEM (PEM(..), pemParseBS) import Data.Either import Data.Certificate.X509-import Data.Certificate.PEM import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as L @@ -40,42 +40,28 @@ envPathOverride :: String envPathOverride = "SYSTEM_CERTIFICATE_PATH" +listSystemCertificates :: IO [FilePath]+listSystemCertificates = do+ path <- getSystemPath+ map (path ++) . filter (not . isPrefixOf ".") <$> getDirectoryContents 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)+ where+ inDefault :: IOException -> IO FilePath+ inDefault _ = return defaultSystemPath -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]+readCertificates :: FilePath -> IO [X509]+readCertificates file = either (const []) (rights . map getCert) . pemParseBS <$> B.readFile file+ where getCert pem = decodeCertificate $ L.fromChunks [pemContent pem] -readAll :: IO [Either ReadErr X509]+readAll :: IO [X509] readAll = do- path <- getSystemPath- certfiles <- filter (not . isPrefixOf ".") <$> getDirectoryContents path- forM certfiles $ \certfile -> readCertificate (path ++ certfile)+ certfiles <- listSystemCertificates+ concat . rights <$> mapM (trySE . readCertificates) certfiles 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+findCertificate f = find f <$> readAll++trySE :: IO a -> IO (Either SomeException a)+trySE = try
certificate.cabal view
@@ -1,5 +1,5 @@ Name: certificate-Version: 1.1.1+Version: 1.2.0 Description: Certificates and Key reader/writer .@@ -29,15 +29,14 @@ Build-Depends: base >= 3 && < 5 , bytestring , mtl+ , pem >= 0.1 && < 0.2 , asn1-data >= 0.6.1.3 && < 0.7- , base64-bytestring , crypto-pubkey-types , directory , time Exposed-modules: Data.Certificate.X509 Data.Certificate.X509.Cert Data.Certificate.X509.Ext- Data.Certificate.PEM Data.Certificate.KeyDSA Data.Certificate.KeyRSA System.Certificate.X509