x509-ocsp 0.5.0.0 → 0.5.1.0
raw patch · 3 files changed
+52/−48 lines, 3 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Data.X509.OCSP: CertId :: OID -> ByteString -> ByteString -> Integer -> CertId
- Data.X509.OCSP: [certIdHashAlgorithm] :: CertId -> OID
- Data.X509.OCSP: [certIdIssuerKeyHash] :: CertId -> ByteString
- Data.X509.OCSP: [certIdIssuerNameHash] :: CertId -> ByteString
- Data.X509.OCSP: [certIdSerialNumber] :: CertId -> Integer
Files
- Changelog.md +5/−0
- Data/X509/OCSP.hs +46/−47
- x509-ocsp.cabal +1/−1
Changelog.md view
@@ -1,3 +1,8 @@+### 0.5.1.0++- Hide the constructor of *CertId*.+- Refactor function *getOCSPResponseVerificationData'*.+ ### 0.5.0.0 - Migrate from *cryptohash-sha1* to *crypton* and *ram*.
Data/X509/OCSP.hs view
@@ -18,7 +18,7 @@ module Data.X509.OCSP ( -- * Shared data- CertId (..)+ CertId -- * OCSP request ,encodeOCSPRequestASN1 ,encodeOCSPRequest@@ -57,28 +57,11 @@ pattern OidBasicOCSPResponse :: OID pattern OidBasicOCSPResponse = [1, 3, 6, 1, 5, 5, 7, 48, 1, 1] -derLWidth :: Word8 -> Int64-derLWidth x | testBit x 7 = succ $ fromIntegral $ x .&. 0x7f- | otherwise = 1--issuerDNHash :: HashAlgorithm a => Certificate -> Digest a-issuerDNHash cert = hashlazy $ encodeASN1 DER dn- where dn = toASN1 (certIssuerDN cert) []-{-# SPECIALIZE issuerDNHash :: Certificate -> Digest SHA1 #-}--pubKeyHash :: HashAlgorithm a => Certificate -> Digest a-pubKeyHash cert = hashlazy $ L.drop (succ $ derLWidth $ L.head pk) pk- where pk = case toASN1 (certPubKey cert) [] of- Start Sequence- : Start Sequence- : OID _- : (skipCurrentContainer -> v@BitString {} : _) ->- L.drop 1 $ encodeASN1 DER $ pure v- _ -> error "bad pubkey sequence"-{-# SPECIALIZE pubKeyHash :: Certificate -> Digest SHA1 #-}- -- | Certificate Id. --+-- Corresponds to /CertId/ from /rfc6960/. Contains /hashAlgorithm/,+-- /issuerNameHash/, /issuerKeyHash/, and /serialNumber/.+-- -- This data is used when building OCSP requests and parsing OCSP responses. data CertId = CertId { certIdHashAlgorithm :: OID -- ^ Value of /hashAlgorithm/ as defined in /rfc6960/@@ -108,19 +91,44 @@ fromASN1 (Asn1CertId alg h1 h2 sn xs) = Right (CertId alg h1 h2 sn, xs) fromASN1 _ = Left "fromASN1: CertId: unexpected format" +derLWidth :: Word8 -> Int64+derLWidth x | testBit x 7 = succ $ fromIntegral $ x .&. 0x7f+ | otherwise = 1++issuerDNHash :: HashAlgorithm a => Certificate -> Digest a+issuerDNHash cert = hashlazy $ encodeASN1 DER dn+ where dn = toASN1 (certIssuerDN cert) []+{-# SPECIALIZE issuerDNHash :: Certificate -> Digest SHA1 #-}++pubKeyHash :: HashAlgorithm a => Certificate -> Digest a+pubKeyHash cert = hashlazy $ L.drop (succ $ derLWidth $ L.head pk) pk+ where pk = case toASN1 (certPubKey cert) [] of+ Start Sequence+ : Start Sequence+ : OID _+ : (skipCurrentContainer -> v@BitString {} : _) ->+ L.drop 1 $ encodeASN1 DER $ pure v+ _ -> error "bad pubkey sequence"+{-# SPECIALIZE pubKeyHash :: Certificate -> Digest SHA1 #-}++toCertId :: Certificate -> Certificate -> CertId+toCertId cert issuerCert =+ let h1 = BA.convert $ issuerDNHash @SHA1 cert+ h2 = BA.convert $ pubKeyHash @SHA1 issuerCert+ sn = certSerial cert+ in CertId OidAlgorithmSHA1 h1 h2 sn+ -- | Build and encode OCSP request in ASN.1 format. -- -- The returned value contains the encoded request and an object of type--- t'CertId' with hashes calculated by the SHA1 algorithm.+-- t'CertId' with hashes calculated by the SHA1 algorithm. The returned+-- /CertId/ must be passed in 'decodeOCSPResponse'. encodeOCSPRequestASN1 :: Certificate -- ^ Certificate -> Certificate -- ^ Issuer certificate -> ([ASN1], CertId) encodeOCSPRequestASN1 cert issuerCert =- let h1 = BA.convert $ issuerDNHash @SHA1 cert- h2 = BA.convert $ pubKeyHash @SHA1 issuerCert- sn = certSerial cert- certId = CertId OidAlgorithmSHA1 h1 h2 sn+ let certId = toCertId cert issuerCert in ( Start Sequence : Start Sequence : Start Sequence@@ -132,7 +140,8 @@ -- | Build and encode OCSP request in ASN.1\/DER format. -- -- The returned value contains the encoded request and an object of type--- t'CertId' with hashes calculated by the SHA1 algorithm.+-- t'CertId' with hashes calculated by the SHA1 algorithm. The returned+-- /CertId/ must be passed in 'decodeOCSPResponse'. encodeOCSPRequest :: Certificate -- ^ Certificate -> Certificate -- ^ Issuer certificate@@ -191,7 +200,7 @@ -- The /Right/ value with /Nothing/ gets returned on unexpected ASN.1 contents. decodeOCSPResponse :: CertId -- ^ Certificate Id- -> L.ByteString -- ^ OCSP response+ -> L.ByteString -- ^ Raw encoded OCSP response -> Either ASN1Error (Maybe OCSPResponse) decodeOCSPResponse certId resp = decodeASN1 DER resp >>= \case [ Start Sequence@@ -314,10 +323,9 @@ :: [ASN1] -- ^ OCSP response payload -> Maybe OCSPResponseVerificationData getOCSPResponseVerificationData' (Start Sequence : Start Sequence : c1)- | (resp, Start Sequence : c2) <- getConstructedEnd 0 c1- , (alg, BitString (BitArray _ sig) : c3) <- getConstructedEnd 0 c2 = do- (alg', []) <- fromASN1' $ wrapInSequence alg- let der = encodeASN1' DER $ wrapInSequence resp+ | (resp, c2) <- getConstructedEnd 0 c1+ , Right (alg, BitString (BitArray _ sig) : c3) <- fromASN1 c2 = do+ let der = encodeASN1' DER $ Start Sequence : resp ++ [End Sequence] case c3 of [End Sequence] -> Just [] _ | Start (Container Context 0)@@ -326,23 +334,17 @@ getCurrentContainerContents c3 -> reverse <$> collectCerts certs [] | otherwise -> Nothing- >>= Just . OCSPResponseVerificationData der alg' sig+ >>= Just . OCSPResponseVerificationData der alg sig where collectCerts (Start Sequence : c4) certs- | (Start Sequence : cert, c5) <- getConstructedEnd 0 c4- , (cert', Start Sequence : c6) <- getConstructedEnd 0 cert- , (alg, [BitString (BitArray _ sig)]) <-- getConstructedEnd 0 c6 = do- (alg', []) <- fromASN1' $ wrapInSequence alg- (cert'', []) <- fromASN1' cert'- collectCerts c5 $- ( Signed cert'' alg' sig- , encodeASN1' DER $ wrapInSequence cert'- ) : certs+ | (c5@(Start Sequence : c6), next) <- getConstructedEnd 0 c4+ , Right (cert, End Sequence : c7) <- fromASN1 c6+ , Right (alg, [BitString (BitArray _ sig)]) <- fromASN1 c7 =+ collectCerts next $+ (Signed cert alg sig, encodeASN1' DER c5) : certs collectCerts [End Sequence, End (Container Context 0)] certs = Just certs collectCerts _ _ = Nothing- wrapInSequence = (Start Sequence :) . (++ [End Sequence]) getOCSPResponseVerificationData' _ = Nothing getCurrentContainerContents :: [ASN1] -> [ASN1]@@ -350,7 +352,4 @@ skipCurrentContainer :: [ASN1] -> [ASN1] skipCurrentContainer = snd . getConstructedEnd 0--fromASN1' :: ASN1Object a => [ASN1] -> Maybe (a, [ASN1])-fromASN1' = either (const Nothing) Just . fromASN1
x509-ocsp.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name: x509-ocsp-version: 0.5.0.0+version: 0.5.1.0 synopsis: Basic X509 OCSP implementation description: Build X509 OCSP requests and parse responses homepage: https://github.com/lyokha/x509-ocsp