.. _x509_certificates:

X.509 Certificates and CRLs
=================================

A certificate is a binding between some identifying information
(called a *subject*) and a public key. This binding is asserted by a
signature on the certificate, which is placed there by some authority
(the *issuer*) that at least claims that it knows the subject named in
the certificate really "owns" the private key corresponding to the
public key in the certificate.

The major certificate format in use today is X.509v3, used for instance in the
:doc:`tls` protocol. A X.509 certificate is represented by the class
``X509_Certificate``. The data of an X.509 certificate is stored as a
``shared_ptr`` to a structure containing the decoded information. So copying
``X509_Certificate`` objects is quite cheap.


.. cpp:class:: X509_Certificate

  .. cpp:function:: X509_Certificate(const std::string& filename)

     Load a certificate from a file. PEM or DER is accepted.

  .. cpp:function:: X509_Certificate(const std::vector<uint8_t>& in)

     Load a certificate from a byte string.

  .. cpp:function:: X509_Certificate(DataSource& source)

     Load a certificate from an abstract ``DataSource``.

  .. cpp:function:: X509_DN subject_dn() const

     Returns the distinguished name (DN) of the certificate's subject. This is
     the primary place where information about the subject of the certificate is
     stored. However "modern" information that doesn't fit in the X.500
     framework, such as DNS name, email, IP address, or XMPP address, appears
     instead in the subject alternative name.

  .. cpp:function:: X509_DN issuer_dn() const

     Returns the distinguished name (DN) of the certificate's issuer, ie the CA
     that issued this certificate.

  .. cpp:function:: const AlternativeName& subject_alt_name() const

      Return the subjects alternative name. This is used to store
      values like associated URIs, DNS addresses, and email addresses.

  .. cpp:function:: const AlternativeName& issuer_alt_name() const

      Return alternative names for the issuer.

  .. cpp:function:: std::unique_ptr<Public_Key> load_subject_public_key() const

     Deserialize the stored public key and return a new object. This
     might throw, if it happens that the public key object stored in
     the certificate is malformed in some way, or in the case that the
     public key algorithm used is not supported by the library.

     See :ref:`serializing_public_keys` for more information about what to do
     with the returned object. It may be any type of key, in principle, though
     RSA and ECDSA are most common.

  .. cpp:function:: std::vector<uint8_t> subject_public_key_bits() const

     Return the binary encoding of the subject public key. This value (or a hash of
     it) is used in various protocols, eg for public key pinning.

  .. cpp:function:: AlgorithmIdentifier subject_public_key_algo() const

     Return an algorithm identifier that identifies the algorithm used in the
     subject's public key.

  .. cpp:function:: std::vector<uint8_t> serial_number() const

     Return the certificates serial number. The tuple of issuer DN and
     serial number should be unique.

  .. cpp:function:: std::vector<uint8> raw_subject_dn() const

     Return the binary encoding of the subject DN.

  .. cpp:function:: std::vector<uint8> raw_issuer_dn() const

     Return the binary encoding of the issuer DN.

  .. cpp:function:: X509_Time not_before() const

     Returns the point in time the certificate becomes valid

  .. cpp:function:: X509_Time not_after() const

     Returns the point in time the certificate expires

  .. cpp:function:: const Extensions& v3_extensions() const

     Returns all extensions of this certificate. You can use this
     to examine any extension data associated with the certificate,
     including custom extensions the library doesn't know about.

  .. cpp:function:: std::vector<uint8_t> authority_key_id() const

      Return the authority key id, if set. This is an arbitrary string; in the
      issuing certificate this will be the subject key id.

  .. cpp:function:: std::vector<uint8_t> subject_key_id() const

      Return the subject key id, if set.

  .. cpp:function:: bool allowed_extended_usage(const OID& usage) const

      Return true if and only if the usage OID appears in the extended key usage
      extension. Also will return true if the extended key usage extension is
      not used in the current certificate.

  .. cpp:function:: std::vector<OID> extended_key_usage() const

      Return the list of extended key usages. May be empty.

  .. cpp:function:: std::string fingerprint(const std::string& hash_fn = "SHA-1") const

      Return a fingerprint for the certificate, which is basically just a hash
      of the binary contents. Normally SHA-1 or SHA-256 is used, but any hash
      function is allowed.

  .. cpp:function:: Key_Constraints constraints() const

      Returns a basic list of constraints which govern usage of the
      key embedded in this certificate.

      The Key_Constraints is a class that behaves somewhat like an
      ``enum``. The easiest way to use it is with its ``includes``
      method. For example::

        constraints().includes(Key_Constraints::DigitalSignature)

      checks if the certificate key is valid for generating digital
      signatures.

  .. cpp:function:: bool matches_dns_name(const std::string& name) const

      Check if the certificate's subject alternative name DNS fields
      match ``name``. This function also handles wildcard certificates.

  .. cpp:function:: std::string to_string() const

      Returns a free-form human readable string describing the certificate.

  .. cpp:function:: std::string PEM_encode() const

      Returns the PEM encoding of the certificate

  .. cpp:function:: std::vector<uint8_t> BER_encode() const

      Returns the DER/BER encoding of the certificate

X.509 Distinguished Names
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. cpp:class:: X509_DN

  .. cpp:function:: bool has_field(const std::string& attr) const

      Returns true if ``get_attribute`` or ``get_first_attribute`` will return a value.

  .. cpp:function:: const std::vector<std::pair<OID, ASN1_String>>& dn_info() const

      Return the DN components as a vector of OID and ASN1_String pairs. Note that
      the order of the components is preserved only when using the initializer list constructor.

  .. cpp:function:: std::vector<std::string> get_attribute(const std::string& attr) const

      Return all attributes associated with a certain attribute type.

  .. cpp:function:: std::string get_first_attribute(const std::string& attr) const

      Like ``get_attribute`` but returns just the first attribute, or
      empty if the DN has no attribute of the specified type.

  .. cpp:function:: std::multimap<OID, std::string> get_attributes() const

      Get all attributes of the DN. The OID maps to a DN component such as
      2.5.4.10 ("Organization"), and the strings are UTF-8 encoded.

  .. cpp:function:: std::multimap<std::string, std::string> contents() const

      Similar to ``get_attribut                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     