diff options
author | Jack Lloyd <[email protected]> | 2018-01-24 12:58:27 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-01-29 05:36:54 -0500 |
commit | 38a8939f9cf04bf5a76c270d99fe922cde152ff5 (patch) | |
tree | fd767bbdd3e6df872ae17a5549167a6fbb945bd2 /doc | |
parent | 65ab80df80333acedf7f8c7dfc16b3da0daa6bd9 (diff) |
Improve X.509 documentation
GH #1428
Diffstat (limited to 'doc')
-rw-r--r-- | doc/manual/x509.rst | 226 |
1 files changed, 141 insertions, 85 deletions
diff --git a/doc/manual/x509.rst b/doc/manual/x509.rst index f9431c362..7bbce5e2e 100644 --- a/doc/manual/x509.rst +++ b/doc/manual/x509.rst @@ -10,24 +10,50 @@ signature on the certificate, which is placed there by some authority 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 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) + .. 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) + .. cpp:function:: X509_Certificate(const std::vector<uint8_t>& in) Load a certificate from a byte string. - .. cpp:function:: X509_Certificate(DataSource& source) + .. cpp:function:: X509_Certificate(DataSource& source) Load a certificate from an abstract ``DataSource``. - .. cpp:function:: std::unique_ptr<Public_Key> load_subject_public_key() const + .. 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 @@ -38,45 +64,72 @@ in the :doc:`tls` protocol. A X.509 certificate is represented by 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> serial_number() const + .. 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:: X509_DN subject_dn() const + .. cpp:function:: std::vector<uint8> raw_subject_dn() const - Returns the distinguished name (DN) of the certificate's subject. + Return the binary encoding of the subject DN. - .. cpp:function:: X509_DN issuer_dn() const + .. cpp:function:: std::vector<uint8> raw_issuer_dn() const - Returns the distinguished name (DN) of the certificate's issuer + Return the binary encoding of the issuer DN. - .. cpp:function:: X509_Time not_before() const + .. cpp:function:: X509_Time not_before() const Returns the point in time the certificate becomes valid - .. cpp:function:: X509_Time not_after() const + .. cpp:function:: X509_Time not_after() const Returns the point in time the certificate expires - .. cpp:function:: const Extensions& v3_extensions() const + .. 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:: const AlternativeName& subject_alt_name() const + .. cpp:function:: std::vector<uint8_t> authority_key_id() const - Return the subjects alternative name. This is used to store - values like associated URIs, DNS addresses, and email addresses. + 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:: const AlternativeName& issuer_alt_name() const + .. cpp:function:: std::vector<uint8_t> subject_key_id() const - Return alternative names for the issuer. + 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 - .. cpp:function:: std::string fingerprint(const std::string& hash_name = "SHA-1") const + Return the list of extended key usages. May be empty. - Return a fingerprint for the certificate. + .. 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:: bool matches_dns_name(const std::string& name) const + + Returns true if ``name`` matches the DNS name in the certificate. This function + accounts for wildcard certificates. .. cpp:function:: Key_Constraints constraints() const @@ -99,64 +152,51 @@ in the :doc:`tls` protocol. A X.509 certificate is represented by Returns a free-form human readable string describing the certificate. -The ``X509_Certificate`` class has several other functions not described here. -See the header ``x509cert.h`` for details. - -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. - -So what's in an X.509 certificate? ------------------------------------ - -Obviously, you want to be able to get the public key. This is achieved -by calling the member function ``subject_public_key``, which will -return a ``Public_Key``\*. As to what to do with this, read about -``load_key`` in :ref:`serializing_public_keys`. In the general case, -this could be any kind of public key, though 99% of the time it will -be an RSA key. However, Diffie-Hellman, DSA, and ECDSA keys are also -supported, so be careful about how you treat this. It is also a wise -idea to examine the value returned by ``constraints``, to see what -uses the public key is approved for. - -The second major piece of information you'll want is the -name/email/etc of the person to whom this certificate is -assigned. Here is where things get a little nasty. X.509v3 has two -(well, mostly just two...) different places where you can stick -information about the user: the *subject* field, and in an extension -called *subjectAlternativeName*. The *subject* field is supposed to -only included the following information: country, organization, an -organizational sub-unit name, and a so-called common name. The common -name is usually the name of the person, or it could be a title -associated with a position of some sort in the organization. It may -also include fields for state/province and locality. What a locality -is, nobody knows, but it's usually given as a city name. - -Like the distinguished names, subject alternative names can contain a lot of -things that Botan will flat out ignore (most of which you would likely never -want to use). However, there are three very useful pieces of information that -this extension might hold: an email address ([email protected]), a DNS name -(somehost.example.com), or a URI (http://www.example.com). - -So, how to get the information? Call ``subject_info`` with the name of -the piece of information you want, and it will return a -``std::string`` that is either empty (signifying that the certificate -doesn't have this information), or has the information -requested. There are several names for each possible item, but the -most easily readable ones are: "Name", "Country", "Organization", -"Organizational Unit", "Locality", "State", "RFC822", "URI", and -"DNS". These values are returned as a ``std::string``. - -You can also get information about the issuer of the certificate in the same -way, using ``issuer_info``. +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:: 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_attributes``, but the OIDs are decoded to strings. + + .. cpp:function:: void add_attribute(const std::string& key, const std::string& val) + + Add an attribute to a DN. + + .. cpp:function:: void add_attribute(const OID& oid, const std::string& val) + + Add an attribute to a DN using an OID instead of string-valued attribute type. + +The ``X509_DN`` type also supports iostream extraction and insertion operators, +for formatted input and output. X.509v3 Extensions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -X.509v3 specifies a large number of possible extensions. Botan -supports some, but by no means all of them. -The following listing lists which X.509v3 extensions are supported -and notes areas where there may be problems with the handling. +X.509v3 specifies a large number of possible extensions. Botan supports some, +but by no means all of them. The following listing lists which X.509v3 +extensions are supported and notes areas where there may be problems with the +handling. - Key Usage and Extended Key Usage: No problems known. @@ -199,10 +239,16 @@ functions are provided to search them. .. cpp:function:: void add(Certificate_Extension* extn, bool critical = false) - Adds a new extension to the list. ``critical`` specifies whether the extension - should be marked as critical. + Adds a new extension to the extensions object. If an extension of the same + type already exists, ``extn`` will replace it. If ``critical`` is true the + extension will be marked as critical in the encoding. - .. cpp:function:: replace(Certificate_Extension* extn, bool critical = false) + .. cpp:function:: bool add_new(Certificate_Extension* extn, bool critical = false) + + Like ``add`` but an existing extension will not be replaced. Returns true if the + extension was used, false if an extension of the same type was already in place. + + .. cpp:function:: void replace(Certificate_Extension* extn, bool critical = false) Adds an extension to the list or replaces it, if the same extension was already added @@ -641,6 +687,20 @@ This function acts quite similarly to transmit it to a CA, who signs it and returns a freshly minted X.509 certificate. +.. cpp:function:: PKCS10_Request PKCS10_Request::create(const Private_Key& key, \ + const X509_DN& subject_dn, \ + const Extensions& extensions, \ + const std::string& hash_fn, \ + RandomNumberGenerator& rng, \ + const std::string& padding_scheme = "", \ + const std::string& challenge = "") + + This function (added in 2.5) is similar to ``create_cert_req`` but allows + specifying all the parameters directly. In fact ``create_cert_req`` just + creates the DN and extensions from the options, then uses this call to + actually create the ``PKCS10_Request`` object. + + Certificate Options ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -718,13 +778,9 @@ are named "PKIX.ServerAuth" (for TLS server authentication), times - each new OID will be added to the list to include in the certificate. -Lastly, you can add any X.509v3 extensions in the `extensions` -member. This is really only useful if you want to encode custom -extensions in the certificate. Most users probably won't need this. -Note that extensions added this way will be overwritten by an -``X509_CA`` if also added by the ``X509_CA`` itself. This currently -includes the Basic Constraints, Key Usage, Authority Key ID, Subject -Key ID, Subject Alternative Name and Extended Key Usage extension. +Lastly, you can add any X.509v3 extensions in the `extensions` member, which is +useful if you want to encode a custom extension, or encode an extension in a way +differently from how Botan defaults. OCSP Requests ---------------------------------------- |