x509-ocsp 0.4.1.0 → 0.5.0.0
raw patch · 5 files changed
+69/−60 lines, 5 filesdep +cryptondep +ramdep −cryptohash-sha1dep ~crypton-x509dep ~crypton-x509-validationPVP ok
version bump matches the API change (PVP)
Dependencies added: crypton, ram
Dependencies removed: cryptohash-sha1
Dependency ranges changed: crypton-x509, crypton-x509-validation
API changes (from Hackage documentation)
+ Data.X509.OCSP: [certIdHashAlgorithm] :: CertId -> OID
+ Data.X509.OCSP: instance Data.ASN1.Types.ASN1Object Data.X509.OCSP.CertId
- Data.X509.OCSP: CertId :: ByteString -> ByteString -> Integer -> CertId
+ Data.X509.OCSP: CertId :: OID -> ByteString -> ByteString -> Integer -> CertId
Files
- Changelog.md +7/−0
- Data/X509/AIA.hs +3/−3
- Data/X509/OCSP.hs +48/−48
- test/test-ocsp.hs +3/−3
- x509-ocsp.cabal +8/−6
Changelog.md view
@@ -1,3 +1,10 @@+### 0.5.0.0++- Migrate from *cryptohash-sha1* to *crypton* and *ram*.+- Now *CertId* contains the hash algorithm used to calculate the hashes and+ implements an instance of class *ASN1Object*.+- Various improvements in the code.+ ### 0.4.1.0 - Migrate from _asn1-\*_, *pem*, *hourglass* to _crypton-asn1-\*_,
Data/X509/AIA.hs view
@@ -25,13 +25,13 @@ import Data.ASN1.Stream import Data.ByteString (ByteString) -pattern OidAIA :: [Integer]+pattern OidAIA :: OID pattern OidAIA = [1, 3, 6, 1, 5, 5, 7, 1, 1] -pattern OidOCSP :: [Integer]+pattern OidOCSP :: OID pattern OidOCSP = [1, 3, 6, 1, 5, 5, 7, 48, 1] -pattern OidCAIssuers :: [Integer]+pattern OidCAIssuers :: OID pattern OidCAIssuers = [1, 3, 6, 1, 5, 5, 7, 48, 2] -- | Authority Info Access description.
Data/X509/OCSP.hs view
@@ -1,4 +1,5 @@-{-# LANGUAGE PatternSynonyms, ViewPatterns, LambdaCase #-}+{-# LANGUAGE PatternSynonyms, ViewPatterns, TypeApplications, LambdaCase #-}+{-# LANGUAGE ImportQualifiedPost #-} ----------------------------------------------------------------------------- -- |@@ -42,43 +43,46 @@ import Data.ASN1.Stream import Data.ASN1.Error import Data.ByteString (ByteString)-import qualified Data.ByteString.Lazy as L+import Data.ByteString.Lazy qualified as L import Data.Int import Data.Word import Data.Bits-import Crypto.Hash.SHA1-import Control.Arrow+import Data.Bifunctor+import Data.ByteArray qualified as BA+import Crypto.Hash -pattern OidAlgorithmSHA1 :: [Integer]+pattern OidAlgorithmSHA1 :: OID pattern OidAlgorithmSHA1 = [1, 3, 14, 3, 2, 26] -pattern OidBasicOCSPResponse :: [Integer]+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 :: Certificate -> ByteString+issuerDNHash :: HashAlgorithm a => Certificate -> Digest a issuerDNHash cert = hashlazy $ encodeASN1 DER dn where dn = toASN1 (certIssuerDN cert) []+{-# SPECIALIZE issuerDNHash :: Certificate -> Digest SHA1 #-} -pubKeyHash :: Certificate -> ByteString+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 _- : _- : End Sequence- : v@BitString {}- : _ -> L.drop 1 $ encodeASN1 DER $ pure v+ : (skipCurrentContainer -> v@BitString {} : _) ->+ L.drop 1 $ encodeASN1 DER $ pure v _ -> error "bad pubkey sequence"+{-# SPECIALIZE pubKeyHash :: Certificate -> Digest SHA1 #-} -- | Certificate Id. -- -- This data is used when building OCSP requests and parsing OCSP responses.-data CertId = CertId { certIdIssuerNameHash :: ByteString+data CertId = CertId { certIdHashAlgorithm :: OID+ -- ^ Value of /hashAlgorithm/ as defined in /rfc6960/+ , certIdIssuerNameHash :: ByteString -- ^ Value of /issuerNameHash/ as defined in /rfc6960/ , certIdIssuerKeyHash :: ByteString -- ^ Value of /issuerKeyHash/ as defined in /rfc6960/@@ -86,6 +90,24 @@ -- ^ Certificate serial number } deriving (Show, Eq) +pattern Asn1CertId :: OID -> ByteString -> ByteString -> Integer -> ASN1S+pattern Asn1CertId alg h1 h2 sn xs =+ Start Sequence+ : Start Sequence+ : OID alg+ : Null+ : End Sequence+ : OctetString h1+ : OctetString h2+ : IntVal sn+ : End Sequence+ : xs++instance ASN1Object CertId where+ toASN1 (CertId alg h1 h2 sn) = Asn1CertId alg h1 h2 sn+ fromASN1 (Asn1CertId alg h1 h2 sn xs) = Right (CertId alg h1 h2 sn, xs)+ fromASN1 _ = Left "fromASN1: CertId: unexpected format"+ -- | Build and encode OCSP request in ASN.1 format. -- -- The returned value contains the encoded request and an object of type@@ -95,28 +117,16 @@ -> Certificate -- ^ Issuer certificate -> ([ASN1], CertId) encodeOCSPRequestASN1 cert issuerCert =- let h1 = issuerDNHash cert- h2 = pubKeyHash issuerCert+ let h1 = BA.convert $ issuerDNHash @SHA1 cert+ h2 = BA.convert $ pubKeyHash @SHA1 issuerCert sn = certSerial cert- in ( [ Start Sequence- , Start Sequence- , Start Sequence- , Start Sequence- , Start Sequence- , Start Sequence- , OID OidAlgorithmSHA1- , Null- , End Sequence- , OctetString h1- , OctetString h2- , IntVal sn- , End Sequence- , End Sequence- , End Sequence- , End Sequence- , End Sequence- ]- , CertId h1 h2 sn+ certId = CertId OidAlgorithmSHA1 h1 h2 sn+ in ( Start Sequence+ : Start Sequence+ : Start Sequence+ : Start Sequence+ : toASN1 certId (replicate 4 $ End Sequence)+ , certId ) -- | Build and encode OCSP request in ASN.1\/DER format.@@ -205,25 +215,15 @@ : Start Sequence : Start (Container Context ctx) : c1 | ctx `elem` [0..2] -> do- let skipVersion =- if ctx == 0- then drop 1 . skipCurrentContainer- else id+ let skipVersion+ | ctx == 0 = drop 1 . skipCurrentContainer+ | otherwise = id Just $ getCurrentContainerContents $ drop 2 $ skipCurrentContainer $ skipVersion c1 _ -> Nothing >>= \case Start Sequence- : Start Sequence- : Start Sequence- : OID _- : _- : End Sequence- : OctetString h1- : OctetString h2- : IntVal sn- : End Sequence- : c2 | CertId h1 h2 sn == certId ->+ : (fromASN1 -> Right (cId, c2)) | cId == certId -> case c2 of Other Context (toEnum -> n) _ : c3 -> Just (n, c3)
test/test-ocsp.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE RecordWildCards, OverloadedStrings #-}+{-# LANGUAGE RecordWildCards, OverloadedStrings, ImportQualifiedPost #-} module Main where @@ -9,8 +9,8 @@ import Data.PEM import Test.HUnit import Data.ByteString (ByteString)-import qualified Data.ByteString as B-import qualified Data.ByteString.Lazy as L+import Data.ByteString qualified as B+import Data.ByteString.Lazy qualified as L import Data.ASN1.Types import Data.ASN1.Encoding import Data.ASN1.BinaryEncoding
x509-ocsp.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.4 name: x509-ocsp-version: 0.4.1.0+version: 0.5.0.0 synopsis: Basic X509 OCSP implementation description: Build X509 OCSP requests and parse responses homepage: https://github.com/lyokha/x509-ocsp@@ -24,14 +24,16 @@ default-language: Haskell2010 build-depends: base >= 4.8 && < 5 , bytestring- , crypton-x509+ , crypton >= 1.1.0+ , crypton-x509 >= 1.9.0 , crypton-asn1-encoding , crypton-asn1-types- , cryptohash-sha1 -- only needed for haddock to hyperlink entities in code examples:- , crypton-x509-validation+ , crypton-x509-validation >= 1.9.0 + , ram+ exposed-modules: Data.X509.AIA , Data.X509.OCSP @@ -42,8 +44,8 @@ build-depends: base >= 4.8 && < 5 , HUnit >= 1.6.1.0 , bytestring- , crypton-x509- , crypton-x509-validation+ , crypton-x509 >= 1.9.0+ , crypton-x509-validation >= 1.9.0 , crypton-asn1-encoding , crypton-asn1-types , crypton-pem