certificate 1.2.5 → 1.2.6
raw patch · 8 files changed
+70/−147 lines, 8 filesdep ~asn1-datadep ~basePVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: asn1-data, base
API changes (from Hackage documentation)
+ Data.Certificate.X509: type DistinguishedName = [(OID, ASN1String)]
+ Data.Certificate.X509.Cert: type DistinguishedName = [(OID, ASN1String)]
- Data.Certificate.X509: Certificate :: Int -> Integer -> SignatureALG -> [(OID, ASN1String)] -> [(OID, ASN1String)] -> (Time, Time) -> PubKey -> Maybe [ExtensionRaw] -> Certificate
+ Data.Certificate.X509: Certificate :: Int -> Integer -> SignatureALG -> DistinguishedName -> DistinguishedName -> (Time, Time) -> PubKey -> Maybe [ExtensionRaw] -> Certificate
- Data.Certificate.X509: certIssuerDN :: Certificate -> [(OID, ASN1String)]
+ Data.Certificate.X509: certIssuerDN :: Certificate -> DistinguishedName
- Data.Certificate.X509: certSubjectDN :: Certificate -> [(OID, ASN1String)]
+ Data.Certificate.X509: certSubjectDN :: Certificate -> DistinguishedName
- Data.Certificate.X509: decodeDN :: ByteString -> Either String [(OID, ASN1String)]
+ Data.Certificate.X509: decodeDN :: ByteString -> Either String DistinguishedName
- Data.Certificate.X509: encodeDN :: [(OID, ASN1String)] -> Either String ByteString
+ Data.Certificate.X509: encodeDN :: DistinguishedName -> ByteString
- Data.Certificate.X509.Cert: Certificate :: Int -> Integer -> SignatureALG -> [(OID, ASN1String)] -> [(OID, ASN1String)] -> (Time, Time) -> PubKey -> Maybe [ExtensionRaw] -> Certificate
+ Data.Certificate.X509.Cert: Certificate :: Int -> Integer -> SignatureALG -> DistinguishedName -> DistinguishedName -> (Time, Time) -> PubKey -> Maybe [ExtensionRaw] -> Certificate
- Data.Certificate.X509.Cert: certIssuerDN :: Certificate -> [(OID, ASN1String)]
+ Data.Certificate.X509.Cert: certIssuerDN :: Certificate -> DistinguishedName
- Data.Certificate.X509.Cert: certSubjectDN :: Certificate -> [(OID, ASN1String)]
+ Data.Certificate.X509.Cert: certSubjectDN :: Certificate -> DistinguishedName
Files
- Certificate.hs +5/−3
- Data/Certificate/KeyDSA.hs +5/−7
- Data/Certificate/KeyRSA.hs +18/−26
- Data/Certificate/X509.hs +14/−16
- Data/Certificate/X509/Cert.hs +21/−16
- Data/Certificate/X509/Ext.hs +2/−1
- Data/Certificate/X509/Internal.hs +3/−76
- certificate.cabal +2/−2
Certificate.hs view
@@ -25,7 +25,9 @@ import qualified Crypto.Cipher.RSA as RSA import qualified Crypto.Cipher.DSA as DSA -import Data.ASN1.DER (decodeASN1Stream, ASN1(..), ASN1ConstructionType(..))+import Data.ASN1.Encoding+import Data.ASN1.BinaryEncoding+import Data.ASN1.Stream import Data.ASN1.BitArray import Text.Printf import Numeric@@ -79,7 +81,7 @@ X509.PubKeyUnknown oid ws -> do printf "public key unknown: %s\n" (show oid) printf " raw bytes: %s\n" (show ws)- case decodeASN1Stream $ L.pack ws of+ case decodeASN1 BER $ L.pack ws of Left err -> printf " asn1 decoding failed: %s\n" (show err) Right l -> printf " asn1 decoding:\n" >> showASN1 4 l pk ->@@ -160,7 +162,7 @@ processCert opts (cert, x509) = do when (raw opts) $ putStrLn $ hexdump $ L.fromChunks [cert]- when (asn1 opts) $ case decodeASN1Stream $ L.fromChunks [cert] of+ when (asn1 opts) $ case decodeASN1' BER cert of Left err -> error ("decoding ASN1 failed: " ++ show err) Right asn1 -> showASN1 0 asn1
Data/Certificate/KeyDSA.hs view
@@ -13,8 +13,9 @@ , encodePrivate ) where -import Data.ASN1.DER (encodeASN1Stream, ASN1(..), ASN1ConstructionType(..))-import Data.ASN1.BER (decodeASN1Stream)+import Data.ASN1.Stream+import Data.ASN1.Encoding+import Data.ASN1.BinaryEncoding import qualified Data.ByteString.Lazy as L import qualified Crypto.Types.PubKey.DSA as DSA @@ -34,13 +35,10 @@ parsePrivate _ = Left "unexpected format" decodePrivate :: L.ByteString -> Either String (DSA.PublicKey, DSA.PrivateKey)-decodePrivate dat = either (Left . show) parsePrivate $ decodeASN1Stream dat+decodePrivate dat = either (Left . show) parsePrivate $ decodeASN1 BER dat encodePrivate :: (DSA.PublicKey, DSA.PrivateKey) -> L.ByteString-encodePrivate (pubkey, privkey) =- case encodeASN1Stream pkseq of- Left err -> error $ show err- Right lbs -> lbs+encodePrivate (pubkey, privkey) = encodeASN1 DER pkseq where pkseq = [ Start Sequence , IntVal 0
Data/Certificate/KeyRSA.hs view
@@ -16,8 +16,9 @@ , parse_RSA ) where -import Data.ASN1.DER (encodeASN1Stream, ASN1(..), ASN1ConstructionType(..))-import Data.ASN1.BER (decodeASN1Stream)+import Data.ASN1.Stream+import Data.ASN1.Encoding+import Data.ASN1.BinaryEncoding import Data.ASN1.BitArray import qualified Data.ByteString.Lazy as L import qualified Crypto.Types.PubKey.RSA as RSA@@ -34,28 +35,22 @@ parsePublic _ = Left "unexpected format" decodePublic :: L.ByteString -> Either String RSA.PublicKey-decodePublic dat = either (Left . show) parsePublic $ decodeASN1Stream dat+decodePublic dat = either (Left . show) parsePublic $ decodeASN1 BER dat encodePublic :: RSA.PublicKey -> L.ByteString-encodePublic p =- let innerSeq = encodeASN1Stream+encodePublic p = encodeASN1 DER [ Start Sequence- , IntVal $ RSA.public_n p- , IntVal $ RSA.public_e p+ , Start Sequence+ , OID [1,2,840,113549,1,1,1] -- PubKeyALG_RSA+ , Null , End Sequence- ]- in case innerSeq of- Left err -> error $ show err- Right bs -> case encodeASN1Stream- [ Start Sequence- , Start Sequence- , OID [1,2,840,113549,1,1,1] -- PubKeyALG_RSA- , Null- , End Sequence- , BitString $ toBitArray bs 0- , End Sequence ] of- Left err -> error $ show err- Right ibs -> ibs+ , BitString $ toBitArray innerSeq 0+ , End Sequence ]+ where innerSeq = encodeASN1 DER [ Start Sequence+ , IntVal $ RSA.public_n p+ , IntVal $ RSA.public_e p+ , End Sequence+ ] parsePrivate :: [ASN1] -> Either String (RSA.PublicKey, RSA.PrivateKey) parsePrivate@@ -89,13 +84,10 @@ parsePrivate _ = Left "unexpected format" decodePrivate :: L.ByteString -> Either String (RSA.PublicKey, RSA.PrivateKey)-decodePrivate dat = either (Left . show) parsePrivate $ decodeASN1Stream dat+decodePrivate dat = either (Left . show) parsePrivate $ decodeASN1 BER dat encodePrivate :: (RSA.PublicKey, RSA.PrivateKey) -> L.ByteString-encodePrivate (pubkey, privkey) =- case encodeASN1Stream pkseq of- Left err -> error $ show err- Right lbs -> lbs+encodePrivate (pubkey, privkey) = encodeASN1 DER pkseq where pkseq = [ Start Sequence , IntVal 0@@ -114,7 +106,7 @@ - return RSA.PublicKey (len-modulus, modulus, e) if successful -} parse_RSA :: L.ByteString -> Either String RSA.PublicKey parse_RSA bits =- case decodeASN1Stream $ bits of+ case decodeASN1 BER bits of Right [Start Sequence, IntVal modulus, IntVal pubexp, End Sequence] -> Right $ RSA.PublicKey { RSA.public_size = calculate_modulus modulus 1
Data/Certificate/X509.hs view
@@ -20,6 +20,7 @@ , OID , ASN1StringType(..) , ASN1String+ , DistinguishedName , Certificate(..) , module Data.Certificate.X509.Ext @@ -36,9 +37,10 @@ ) where import Data.Word-import Data.ASN1.DER-import Data.ASN1.Stream (getConstructedEndRepr)-import Data.ASN1.Raw (toBytes)+import Data.ASN1.Encoding+import Data.ASN1.BinaryEncoding+import qualified Data.ASN1.BinaryEncoding.Raw as Raw (toLazyByteString)+import Data.ASN1.Stream import Data.ASN1.BitArray import qualified Data.ByteString.Lazy as L @@ -66,10 +68,8 @@ - which is either the cached data or the encoded certificate -} getSigningData :: X509 -> L.ByteString getSigningData (X509 _ (Just e) _ _ _) = e-getSigningData (X509 cert Nothing _ _ _) = e- where- (Right e) = encodeASN1Stream header- header = asn1Container Sequence $ encodeCertificateHeader cert+getSigningData (X509 cert Nothing _ _ _) = encodeASN1 DER header+ where header = asn1Container Sequence $ encodeCertificateHeader cert {- | decode an X509 from a bytestring - the structure is the following:@@ -78,7 +78,7 @@ - Certificate Signature -} decodeCertificate :: L.ByteString -> Either String X509-decodeCertificate by = either (Left . show) parseRootASN1 $ decodeASN1StreamRepr by+decodeCertificate by = either (Left . show) parseRootASN1 $ decodeASN1Repr BER by where {- | parse root structure of a x509 certificate. this has to be a sequence of 3 objects : - * the header@@ -91,7 +91,7 @@ let cert = onContainer certrepr (runParseASN1 parseCertificate . map fst) in case (cert, map fst sigseq) of (Right c, [BitString b]) ->- let certevs = toBytes $ concatMap snd certrepr in+ let certevs = Raw.toLazyByteString $ concatMap snd certrepr in let sigalg = onContainer sigalgseq (parseSigAlg . map fst) in Right $ X509 c (Just certevs) (Just by) sigalg (L.unpack $ bitArrayGetData b) (Left err, _) -> Left $ ("certificate error: " ++ show err)@@ -111,17 +111,15 @@ {-| encode a X509 certificate to a bytestring -} encodeCertificate :: X509 -> L.ByteString encodeCertificate (X509 _ _ (Just lbs) _ _ ) = lbs-encodeCertificate (X509 cert _ Nothing sigalg sigbits) = case encodeASN1Stream rootSeq of- Right x -> x- Left err -> error (show err)+encodeCertificate (X509 cert _ Nothing sigalg sigbits) = encodeASN1 DER rootSeq where esigalg = asn1Container Sequence [OID (sigOID sigalg), Null] esig = BitString $ toBitArray (L.pack sigbits) 0 header = asn1Container Sequence $ encodeCertificateHeader cert rootSeq = asn1Container Sequence (header ++ esigalg ++ [esig]) -decodeDN :: L.ByteString -> Either String [(OID, ASN1String)]-decodeDN by = either (Left . show) (runParseASN1 parseDN) $ decodeASN1Stream by+decodeDN :: L.ByteString -> Either String DistinguishedName+decodeDN by = either (Left . show) (runParseASN1 parseDN) $ decodeASN1 BER by -encodeDN :: [(OID, ASN1String)] -> Either String L.ByteString-encodeDN dn = either (Left . show) Right $ encodeASN1Stream $ Cert.encodeDN dn+encodeDN :: DistinguishedName -> L.ByteString+encodeDN dn = encodeASN1 DER $ Cert.encodeDN dn
Data/Certificate/X509/Cert.hs view
@@ -8,6 +8,7 @@ , ASN1StringType(..) , ASN1String , Certificate(..)+ , DistinguishedName , OID -- various OID@@ -34,7 +35,9 @@ import Data.Word import Data.List (find, sortBy)-import Data.ASN1.DER+import Data.ASN1.Stream+import Data.ASN1.Encoding+import Data.ASN1.BinaryEncoding import Data.ASN1.BitArray import Data.Maybe import Data.Time.Calendar@@ -100,12 +103,14 @@ data ASN1StringType = UTF8 | Printable | Univ | BMP | IA5 | T61 deriving (Show,Eq) type ASN1String = (ASN1StringType, String) +type DistinguishedName = [(OID, ASN1String)]+ data Certificate = Certificate { certVersion :: Int -- ^ Certificate Version , certSerial :: Integer -- ^ Certificate Serial number , certSignatureAlg :: SignatureALG -- ^ Certificate Signature algorithm- , certIssuerDN :: [ (OID, ASN1String) ] -- ^ Certificate Issuer DN- , certSubjectDN :: [ (OID, ASN1String) ] -- ^ Certificate Subject DN+ , certIssuerDN :: DistinguishedName -- ^ Certificate Issuer DN+ , certSubjectDN :: DistinguishedName -- ^ Certificate Subject DN , certValidity :: (Time, Time) -- ^ Certificate Validity period , certPubKey :: PubKey -- ^ Certificate Public key , certExtensions :: Maybe [ExtensionRaw] -- ^ Certificate Extensions@@ -119,7 +124,7 @@ parse_ECDSA :: ByteString -> ParseASN1 PubKey parse_ECDSA bits =- case decodeASN1Stream bits of+ case decodeASN1 BER bits of Right l -> return $ PubKeyECDSA l Left _ -> return $ PubKeyUnknown (pubkeyalgOID PubKeyALG_ECDSA) (L.unpack bits) @@ -253,7 +258,7 @@ _ -> return $ PubKeyUnknown pkalg $ L.unpack bits [OID pkalg,Start Sequence,IntVal p,IntVal q,IntVal g,End Sequence] -> do let sig = oidPubKey pkalg- case decodeASN1Stream bits of+ case decodeASN1 BER bits of Right [IntVal dsapub] -> return $ PubKeyDSA $ DSA.PublicKey { DSA.public_params = (p, q, g), DSA.public_y = dsapub } _ -> return $ PubKeyUnknown pkalg $ L.unpack bits@@ -273,10 +278,10 @@ if n then getNextContainer Sequence >>= \sq -> liftM (sq :) getSequences else return []- extractExtension [OID oid,Boolean True,OctetString obj] = case decodeASN1Stream obj of+ extractExtension [OID oid,Boolean True,OctetString obj] = case decodeASN1 BER obj of Left _ -> Nothing Right r -> Just (oid, True, r)- extractExtension [OID oid,OctetString obj] = case decodeASN1Stream obj of+ extractExtension [OID oid,OctetString obj] = case decodeASN1 BER obj of Left _ -> Nothing Right r -> Just (oid, False, r) extractExtension _ = Nothing@@ -332,16 +337,16 @@ encodePK k@(PubKeyRSA pubkey) = asn1Container Sequence (asn1Container Sequence [pkalg,Null] ++ [BitString $ toBitArray bits 0]) where- pkalg = OID $ pubkeyalgOID $ pubkeyToAlg k- (Right bits) = encodeASN1Stream $ asn1Container Sequence [IntVal (RSA.public_n pubkey), IntVal (RSA.public_e pubkey)]+ pkalg = OID $ pubkeyalgOID $ pubkeyToAlg k+ bits = encodeASN1 DER $ asn1Container Sequence [IntVal (RSA.public_n pubkey), IntVal (RSA.public_e pubkey)] encodePK k@(PubKeyDSA pubkey) = asn1Container Sequence (asn1Container Sequence ([pkalg] ++ dsaseq) ++ [BitString $ toBitArray bits 0]) where- pkalg = OID $ pubkeyalgOID $ pubkeyToAlg k- dsaseq = asn1Container Sequence [IntVal p,IntVal q,IntVal g]- (p,q,g) = DSA.public_params pubkey- (Right bits) = encodeASN1Stream [IntVal $ DSA.public_y pubkey]+ pkalg = OID $ pubkeyalgOID $ pubkeyToAlg k+ dsaseq = asn1Container Sequence [IntVal p,IntVal q,IntVal g]+ (p,q,g) = DSA.public_params pubkey+ bits = encodeASN1 DER [IntVal $ DSA.public_y pubkey] encodePK k@(PubKeyUnknown _ l) = asn1Container Sequence (asn1Container Sequence [pkalg,Null] ++ [BitString $ toBitArray (L.pack l) 0])@@ -351,9 +356,9 @@ encodeExts :: Maybe [ExtensionRaw] -> [ASN1] encodeExts Nothing = [] encodeExts (Just l) = asn1Container (Container Context 3) $ concatMap encodeExt l- where encodeExt (oid, critical, asn1) = case encodeASN1Stream asn1 of- Left _ -> error "cannot encode asn1 extension"- Right bs -> asn1Container Sequence ([OID oid] ++ (if critical then [Boolean True] else []) ++ [OctetString bs])+ where encodeExt (oid, critical, asn1) =+ let bs = encodeASN1 DER asn1+ in asn1Container Sequence ([OID oid] ++ (if critical then [Boolean True] else []) ++ [OctetString bs]) encodeCertificateHeader :: Certificate -> [ASN1] encodeCertificateHeader cert =
Data/Certificate/X509/Ext.hs view
@@ -24,7 +24,8 @@ import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as BC import qualified Data.ByteString.Lazy as L-import Data.ASN1.DER+import Data.ASN1.Types+import Data.ASN1.Stream import Data.ASN1.BitArray import Data.Certificate.X509.Internal
Data/Certificate/X509/Internal.hs view
@@ -1,87 +1,14 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}- module Data.Certificate.X509.Internal- ( ParseASN1- , runParseASN1- , onNextContainer- , onNextContainerMaybe- , getNextContainer- , getNextContainerMaybe- , getNext- , hasNext+ ( module Data.ASN1.Parse , makeASN1Sequence , asn1Container , OID ) where -import Data.ASN1.DER-import Data.ASN1.Stream (getConstructedEnd)-import Control.Monad.State-import Control.Monad.Error+import Data.ASN1.Stream+import Data.ASN1.Parse type OID = [Integer]--newtype ParseASN1 a = P { runP :: ErrorT String (State [ASN1]) a }- deriving (Functor, Monad, MonadError String)--runParseASN1 :: ParseASN1 a -> [ASN1] -> Either String a-runParseASN1 f s =- case runState (runErrorT (runP f)) s of- (Left err, _) -> Left err- (Right r, _) -> Right r--getNext :: ParseASN1 ASN1-getNext = do- list <- P (lift get)- case list of- [] -> throwError "empty"- (h:l) -> P (lift (put l)) >> return h--getNextContainer :: ASN1ConstructionType -> ParseASN1 [ASN1]-getNextContainer ty = do- list <- P (lift get)- case list of- [] -> throwError "empty"- (h:l) -> if h == Start ty- then do- let (l1, l2) = getConstructedEnd 0 l- P (lift $ put l2) >> return l1- else throwError "not an expected container"---onNextContainer :: ASN1ConstructionType -> ParseASN1 a -> ParseASN1 a-onNextContainer ty f = do- n <- getNextContainer ty- case runParseASN1 f n of- Left err -> throwError err- Right r -> return r--getNextContainerMaybe :: ASN1ConstructionType -> ParseASN1 (Maybe [ASN1])-getNextContainerMaybe ty = do- list <- P (lift get)- case list of- [] -> return Nothing- (h:l) -> if h == Start ty- then do- let (l1, l2) = getConstructedEnd 0 l- P (lift $ put l2) >> return (Just l1)- else return Nothing--onNextContainerMaybe :: ASN1ConstructionType -> ParseASN1 a -> ParseASN1 (Maybe a)-onNextContainerMaybe ty f = do- n <- getNextContainerMaybe ty- case n of- Just l -> case runParseASN1 f l of- Left err -> throwError err- Right r -> return $ Just r- Nothing -> return Nothing--hasNext :: ParseASN1 Bool-hasNext = do- list <- P (lift get)- case list of- [] -> return False- _ -> return True asn1Container :: ASN1ConstructionType -> [ASN1] -> [ASN1] asn1Container ty l = [Start ty] ++ l ++ [End ty]
certificate.cabal view
@@ -1,5 +1,5 @@ Name: certificate-Version: 1.2.5+Version: 1.2.6 Description: Certificates and Key reader/writer .@@ -30,7 +30,7 @@ , bytestring , mtl , pem >= 0.1 && < 0.2- , asn1-data >= 0.6.1.3 && < 0.7+ , asn1-data >= 0.7.1 , crypto-pubkey-types >= 0.1 && < 0.2 , directory , process