x509-1.4.5: X509 reader and writer

Portability | unknown
Stability | experimental
Maintainer | Vincent Hanquez <vincent@snarc.org>
Safe Haskell | None

Data.X509

Contents

- Types
- Common extension usually found in x509v3
- Accessor turning extension into a specific one
- Certificate Revocation List (CRL)
- Naming
- Certificate Chain
- marshall between CertificateChain and CertificateChainRaw
- Signed types and marshalling
- Parametrized Signed accessor
- Hash distinguished names related function

Description

Read/Write X509 Certificate, CRL and their signed equivalents.

Follows RFC5280 / RFC6818

Synopsis

- type SignedCertificate = SignedExact Certificate
- type SignedCRL = SignedExact CRL
- data Certificate = Certificate {
  - certVersion :: Int
  - certSerial :: Integer
  - certSignatureAlg :: SignatureALG
  - certIssuerDN :: DistinguishedName
  - certValidity :: (UTCTime, UTCTime)
  - certSubjectDN :: DistinguishedName
  - certPubKey :: PubKey
  - certExtensions :: Extensions
  }
- data PubKey
  - = PubKeyRSA PublicKey
  - | PubKeyDSA PublicKey
  - | PubKeyDH (Integer, Integer, Integer, Maybe Integer, ([Word8], Integer))
  - | PubKeyECDSA CurveName ByteString
  - | PubKeyUnknown OID ByteString
- data PrivKey
  - = PrivKeyRSA PrivateKey
  - | PrivKeyDSA PrivateKey
- pubkeyToAlg :: PubKey -> PubKeyALG
- privkeyToAlg :: PrivKey -> PubKeyALG
- data HashALG
  - = HashMD2
  - | HashMD5
  - | HashSHA1
  - | HashSHA224
  - | HashSHA256
  - | HashSHA384
  - | HashSHA512
- data PubKeyALG
  - = PubKeyALG_RSA
  - | PubKeyALG_DSA
  - | PubKeyALG_ECDSA
  - | PubKeyALG_DH
  - | PubKeyALG_Unknown OID
- data SignatureALG
  - = SignatureALG HashALG PubKeyALG
  - | SignatureALG_Unknown OID
- class Extension a where
  - extOID :: a -> OID
  - extEncode :: a -> [ASN1]
  - extDecode :: [ASN1] -> Either String a
- data ExtBasicConstraints = ExtBasicConstraints Bool (Maybe Integer)
- data ExtKeyUsage = ExtKeyUsage [ExtKeyUsageFlag]
- data ExtKeyUsageFlag
  - = KeyUsage_digitalSignature
  - | KeyUsage_nonRepudiation
  - | KeyUsage_keyEncipherment
  - | KeyUsage_dataEncipherment
  - | KeyUsage_keyAgreement
  - | KeyUsage_keyCertSign
  - | KeyUsage_cRLSign
  - | KeyUsage_encipherOnly
  - | KeyUsage_decipherOnly
- data ExtSubjectKeyId = ExtSubjectKeyId ByteString
- data ExtSubjectAltName = ExtSubjectAltName [AltName]
- data ExtAuthorityKeyId = ExtAuthorityKeyId ByteString
- data ExtCrlDistributionPoints = ExtCrlDistributionPoints [DistributionPoint]
- data AltName
  - = AltNameRFC822 String
  - | AltNameDNS String
  - | AltNameURI String
  - | AltNameIP ByteString
- data DistributionPoint
  - = DistributionPointFullName [AltName]
  - | DistributionNameRelative DistinguishedName
- data ReasonFlag
  - = Reason_Unused
  - | Reason_KeyCompromise
  - | Reason_CACompromise
  - | Reason_AffiliationChanged
  - | Reason_Superseded
  - | Reason_CessationOfOperation
  - | Reason_CertificateHold
  - | Reason_PrivilegeWithdrawn
  - | Reason_AACompromise
- extensionGet :: Extension a => Extensions -> Maybe a
- extensionDecode :: Extension a => ExtensionRaw -> Maybe (Either String a)
- data ExtensionRaw = ExtensionRaw {
  - extRawOID :: OID
  - extRawCritical :: Bool
  - extRawASN1 :: [ASN1]
  }
- newtype Extensions = Extensions (Maybe [ExtensionRaw])
- data CRL = CRL {
  - crlVersion :: Integer
  - crlSignatureAlg :: SignatureALG
  - crlIssuer :: DistinguishedName
  - crlThisUpdate :: UTCTime
  - crlNextUpdate :: Maybe UTCTime
  - crlRevokedCertificates :: [RevokedCertificate]
  - crlExtensions :: Extensions
  }
- data RevokedCertificate = RevokedCertificate {
  - revokedSerialNumber :: Integer
  - revokedDate :: UTCTime
  - revokedExtensions :: Extensions
  }
- newtype DistinguishedName = DistinguishedName {
  - getDistinguishedElements :: [(OID, ASN1CharacterString)]
  }
- data DnElement
  - = DnCommonName
  - | DnCountry
  - | DnOrganization
  - | DnOrganizationUnit
- data ASN1CharacterString = ASN1CharacterString {
  - characterEncoding :: ASN1StringEncoding
  - getCharacterStringRawData :: ByteString
  }
- getDnElement :: DnElement -> DistinguishedName -> Maybe ASN1CharacterString
- newtype CertificateChain = CertificateChain [SignedExact Certificate]
- newtype CertificateChainRaw = CertificateChainRaw [ByteString]
- decodeCertificateChain :: CertificateChainRaw -> Either (Int, String) CertificateChain
- encodeCertificateChain :: CertificateChain -> CertificateChainRaw
- data (Show a, Eq a, ASN1Object a) => Signed a = Signed {
  - signedObject :: a
  - signedAlg :: SignatureALG
  - signedSignature :: ByteString
  }
- data (Show a, Eq a, ASN1Object a) => SignedExact a
- getSigned :: SignedExact a -> Signed a
- getSignedData :: (Show a, Eq a, ASN1Object a) => SignedExact a -> ByteString
- objectToSignedExact :: (Show a, Eq a, ASN1Object a) => (ByteString -> (ByteString, SignatureALG, r)) -> a -> (SignedExact a, r)
- encodeSignedObject :: SignedExact a -> ByteString
- decodeSignedObject :: (Show a, Eq a, ASN1Object a) => ByteString -> Either String (SignedExact a)
- getCertificate :: SignedCertificate -> Certificate
- getCRL :: SignedCRL -> CRL
- decodeSignedCertificate :: ByteString -> Either String SignedCertificate
- decodeSignedCRL :: ByteString -> Either String SignedCRL
- hashDN :: DistinguishedName -> ByteString
- hashDN_old :: DistinguishedName -> ByteString

# Types

type SignedCertificate = SignedExact Certificate Source

A Signed Certificate

type SignedCRL = SignedExact CRL Source

A Signed CRL

data Certificate Source

X.509 Certificate type.

This type doesn't include the signature, it's describe in the RFC as tbsCertificate.

Constructors

Certificate |

Fields

certVersion :: Int

  Version

certSerial :: Integer

  Serial number

certSignatureAlg :: SignatureALG

  Signature algorithm

certIssuerDN :: DistinguishedName

  Issuer DN

certValidity :: (UTCTime, UTCTime)

  Validity period

certSubjectDN :: DistinguishedName

  Subject DN

certPubKey :: PubKey

  Public key

certExtensions :: Extensions

  Extensions

Instances

Eq Certificate |
Show Certificate |
ASN1Object Certificate |

data PubKey Source

Public key types known and used in X.509

Constructors

PubKeyRSA PublicKey | RSA public key
PubKeyDSA PublicKey | DSA public key
PubKeyDH (Integer, Integer, Integer, Maybe Integer, ([Word8], Integer)) | DH format with (p,g,q,j,(seed,pgenCounter))
PubKeyECDSA CurveName ByteString |
PubKeyUnknown OID ByteString | unrecognized format

Instances

Eq PubKey |
Show PubKey |
ASN1Object PubKey |

data PrivKey Source

Private key types known and used in X.509

Constructors

PrivKeyRSA PrivateKey | RSA private key
PrivKeyDSA PrivateKey | DSA private key

Instances

Eq PrivKey |
Show PrivKey |

pubkeyToAlg :: PubKey -> PubKeyALG Source

Convert a Public key to the Public Key Algorithm type

privkeyToAlg :: PrivKey -> PubKeyALG Source

Convert a Public key to the Public Key Algorithm type

data HashALG Source

Hash Algorithm

Constructors

HashMD2 |
HashMD5 |
HashSHA1 |
HashSHA224 |
HashSHA256 |
HashSHA384 |
HashSHA512 |

Instances

Eq HashALG |
Show HashALG |

data PubKeyALG Source

Public Key Algorithm

Constructors

PubKeyALG_RSA | RSA Public Key algorithm
PubKeyALG_DSA | DSA Public Key algorithm
PubKeyALG_ECDSA | ECDSA Public Key algorithm
PubKeyALG_DH | Diffie Hellman Public Key algorithm
PubKeyALG_Unknown OID | Unknown Public Key algorithm

Instances

Eq PubKeyALG |
Show PubKeyALG |
OIDable PubKeyALG |

data SignatureALG Source

Signature Algorithm often composed of a public key algorithm and a hash algorithm

Constructors

SignatureALG HashALG PubKeyALG |
SignatureALG_Unknown OID |

Instances

Eq SignatureALG |
Show SignatureALG |
ASN1Object SignatureALG |

class Extension a where Source

Extension class.

each extension have a unique OID associated, and a way to encode and decode an ASN1 stream.

Methods

extOID :: a -> OID Source

extEncode :: a -> [ASN1]Source

extDecode :: [ASN1] -> Either String aSource

Instances

Extension ExtCrlDistributionPoints |
Extension ExtAuthorityKeyId |
Extension ExtSubjectAltName |
Extension ExtSubjectKeyId |
Extension ExtKeyUsage |
Extension ExtBasicConstraints |

# Common extension usually found in x509v3

data ExtBasicConstraints Source

Basic Constraints

Constructors

ExtBasicConstraints Bool (Maybe Integer) |

Instances

Eq ExtBasicConstraints |
Show ExtBasicConstraints |
Extension ExtBasicConstraints |

data ExtKeyUsage Source

Describe key usage

Constructors

ExtKeyUsage [ExtKeyUsageFlag] |

Instances

Eq ExtKeyUsage |
Show ExtKeyUsage |
Extension ExtKeyUsage |

data ExtKeyUsageFlag Source

key usage flag that is found in the key usage extension field.

Constructors

KeyUsage_digitalSignature |
KeyUsage_nonRepudiation |
KeyUsage_keyEncipherment |
KeyUsage_dataEncipherment |
KeyUsage_keyAgreement |
KeyUsage_keyCertSign |
KeyUsage_cRLSign |
KeyUsage_encipherOnly |
KeyUsage_decipherOnly |

Instances

Enum ExtKeyUsageFlag |
Eq ExtKeyUsageFlag |
Ord ExtKeyUsageFlag |
Show ExtKeyUsageFlag |

data ExtSubjectKeyId Source

Provide a way to identify a public key by a short hash.

Constructors

ExtSubjectKeyId ByteString |

Instances

Eq ExtSubjectKeyId |
Show ExtSubjectKeyId |
Extension ExtSubjectKeyId |

data ExtSubjectAltName Source

Provide a way to supply alternate name that can be used for matching host name.

Constructors

ExtSubjectAltName [AltName] |

Instances

Eq ExtSubjectAltName |
Ord ExtSubjectAltName |
Show ExtSubjectAltName |
Extension ExtSubjectAltName |

data ExtAuthorityKeyId Source

Provide a mean to identify the public key corresponding to the private key used to signed a certificate.

Constructors

ExtAuthorityKeyId ByteString |

Instances

Eq ExtAuthorityKeyId |
Show ExtAuthorityKeyId |
Extension ExtAuthorityKeyId |

data ExtCrlDistributionPoints Source

Identify how CRL information is obtained

Constructors

ExtCrlDistributionPoints [DistributionPoint] |

Instances

Eq ExtCrlDistributionPoints |
Show ExtCrlDistributionPoints |
Extension ExtCrlDistributionPoints |

data AltName Source

Different naming scheme use by the extension.

Not all name types are available, missing: otherName x400Address directoryName ediPartyName registeredID

Constructors

AltNameRFC822 String |
AltNameDNS String |
AltNameURI String |
AltNameIP ByteString |

Instances

Eq AltName |
Ord AltName |
Show AltName |

data DistributionPoint Source

Distribution point as either some GeneralNames or a DN

Constructors

DistributionPointFullName [AltName] |
DistributionNameRelative DistinguishedName |

Instances

Eq DistributionPoint |
Show DistributionPoint |

data ReasonFlag Source

Reason flag for the CRL

Constructors

Reason_Unused |
Reason_KeyCompromise |
Reason_CACompromise |
Reason_AffiliationChanged |
Reason_Superseded |
Reason_CessationOfOperation |
Reason_CertificateHold |
Reason_PrivilegeWithdrawn |
Reason_AACompromise |

Instances

Enum ReasonFlag |
Eq ReasonFlag |
Ord ReasonFlag |
Show ReasonFlag |

# Accessor turning extension into a specific one

extensionGet :: Extension a => Extensions -> Maybe aSource

Get a specific extension from a lists of raw extensions

extensionDecode :: Extension a => ExtensionRaw -> Maybe (Either String a)Source

Try to decode an ExtensionRaw.

If this function return: * Nothing, the OID doesn't match * Just Left, the OID matched, but the extension couldn't be decoded * Just Right, the OID matched, and the extension has been succesfully decoded

data ExtensionRaw Source

An undecoded extension

Constructors

ExtensionRaw |

Fields

extRawOID :: OID

  OID of this extension

extRawCritical :: Bool

  if this extension is critical

extRawASN1 :: [ASN1]

  the associated ASN1

Instances

Eq ExtensionRaw |
Show ExtensionRaw |
ASN1Object ExtensionRaw |

newtype Extensions Source

a Set of `ExtensionRaw`

Constructors

Extensions (Maybe [ExtensionRaw]) |

Instances

Eq Extensions |
Show Extensions |
ASN1Object Extensions |

# Certificate Revocation List (CRL)

data CRL Source

Describe a Certificate revocation list

Constructors

CRL |

Fields

crlVersion :: Integer
crlSignatureAlg :: SignatureALG
crlIssuer :: DistinguishedName
crlThisUpdate :: UTCTime
crlNextUpdate :: Maybe UTCTime
crlRevokedCertificates :: [RevokedCertificate]
crlExtensions :: Extensions

Instances

Eq CRL |
Show CRL |
ASN1Object CRL |

data RevokedCertificate Source

Describe a revoked certificate identifiable by serial number.

Constructors

RevokedCertificate |

Fields

revokedSerialNumber :: Integer
revokedDate :: UTCTime
revokedExtensions :: Extensions

Instances

Eq RevokedCertificate |
Show RevokedCertificate |
ASN1Object RevokedCertificate |

# Naming

newtype DistinguishedName Source

A list of OID and strings.

Constructors

DistinguishedName |

Fields

getDistinguishedElements :: [(OID, ASN1CharacterString)]

Instances

Eq DistinguishedName |
Ord DistinguishedName |
Show DistinguishedName |
ASN1Object DistinguishedName |
Monoid DistinguishedName |

data DnElement Source

Elements commonly available in a `DistinguishedName` structure

Constructors

DnCommonName | CN
DnCountry | Country
DnOrganization | O
DnOrganizationUnit | OU

Instances

Eq DnElement |
Show DnElement |
OIDable DnElement |

data ASN1CharacterString

ASN1 Character String with encoding

Constructors

ASN1CharacterString |

Fields

characterEncoding :: ASN1StringEncoding
getCharacterStringRawData :: ByteString

Instances

Eq ASN1CharacterString |
Ord ASN1CharacterString |
Show ASN1CharacterString |
IsString ASN1CharacterString |

getDnElement :: DnElement -> DistinguishedName -> Maybe ASN1CharacterString Source

Try to get a specific element in a `DistinguishedName` structure

# Certificate Chain

newtype CertificateChain Source

A chain of X.509 certificates in exact form.

Constructors

CertificateChain [SignedExact Certificate] |

Instances

Eq CertificateChain |
Show CertificateChain |

newtype CertificateChainRaw Source

Represent a chain of X.509 certificates in bytestring form.

Constructors

CertificateChainRaw [ByteString] |

Instances

Eq CertificateChainRaw |
Show CertificateChainRaw |

# marshall between CertificateChain and CertificateChainRaw

decodeCertificateChain :: CertificateChainRaw -> Either (Int, String) CertificateChain Source

Decode a CertificateChainRaw into a CertificateChain if every raw certificate are decoded correctly, otherwise return the index of the failed certificate and the error associated.

encodeCertificateChain :: CertificateChain -> CertificateChainRaw Source

Convert a CertificateChain into a CertificateChainRaw

# Signed types and marshalling

data (Show a, Eq a, ASN1Object a) => Signed a Source

Represent a signed object using a traditional X509 structure.

When dealing with external certificate, use the SignedExact structure not this one.

Constructors

Signed |

Fields

signedObject :: a

  Object to sign

signedAlg :: SignatureALG

  Signature Algorithm used

signedSignature :: ByteString

  Signature as bytes

Instances

(Eq a, Show a, ASN1Object a) => Eq (Signed a) |
(Eq a, Show a, ASN1Object a) => Show (Signed a) |

data (Show a, Eq a, ASN1Object a) => SignedExact a Source

Represent the signed object plus the raw data that we need to keep around for non compliant case to be able to verify signature.

Instances

(Eq a, Show a, ASN1Object a) => Eq (SignedExact a) |
(Eq a, Show a, ASN1Object a) => Show (SignedExact a) |

getSigned :: SignedExact a -> Signed aSource

get the decoded Signed data

getSignedData :: (Show a, Eq a, ASN1Object a) => SignedExact a -> ByteString Source

Get the signed data for the signature

objectToSignedExact Source

Arguments

:: (Show a, Eq a, ASN1Object a) |
=> (ByteString -> (ByteString, SignatureALG, r)) | signature function
-> a | object to sign
-> (SignedExact a, r) |

Transform an object into a `SignedExact` object

encodeSignedObject :: SignedExact a -> ByteString Source

The raw representation of the whole signed structure

decodeSignedObject :: (Show a, Eq a, ASN1Object a) => ByteString -> Either String (SignedExact a)Source

Try to parse a bytestring that use the typical X509 signed structure format

# Parametrized Signed accessor

getCertificate :: SignedCertificate -> Certificate Source

Get the Certificate associated to a SignedCertificate

getCRL :: SignedCRL -> CRL Source

Get the CRL associated to a SignedCRL

decodeSignedCertificate :: ByteString -> Either String SignedCertificate Source

Try to decode a bytestring to a SignedCertificate

decodeSignedCRL :: ByteString -> Either String SignedCRL Source

Try to decode a bytestring to a SignedCRL

# Hash distinguished names related function

hashDN :: DistinguishedName -> ByteString Source

Make an OpenSSL style hash of distinguished name

OpenSSL algorithm is odd, and has been replicated here somewhat. only lower the case of ascii character.

hashDN_old :: DistinguishedName -> ByteString Source

Create an openssl style old hash of distinguished name