diff options
author | lloyd <[email protected]> | 2011-04-04 05:18:02 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2011-04-04 05:18:02 +0000 |
commit | ca350f3da57240d03e4372a91130552096af79c4 (patch) | |
tree | 7fd52134d722931b8228c0f0d60003c4b1841d50 /doc/x509.txt | |
parent | a9d19548778e11a5fdcea1bd72f96dd649dc3f96 (diff) |
Refer the user to the Doxygen output as well.
Lots of cleanups in the certificate documentation, which was still
just the raw output of my hacked up LaTeX to RST script.
Diffstat (limited to 'doc/x509.txt')
-rw-r--r-- | doc/x509.txt | 278 |
1 files changed, 130 insertions, 148 deletions
diff --git a/doc/x509.txt b/doc/x509.txt index 3243928de..64189ed0d 100644 --- a/doc/x509.txt +++ b/doc/x509.txt @@ -32,29 +32,27 @@ 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 the section ``Importing and Exporting PK -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 -and DSA 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. +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:`pk_import_export`. 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. +(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. Botan doesn't currently support any of the Unicode variants used in ASN.1 (UTF-8, UCS-2, and UCS-4), any of which could be used for the @@ -77,15 +75,14 @@ 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 +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``. +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``. @@ -148,13 +145,17 @@ which format without any extra information. For example:: X509_CRL crl2(in); After that, pass the ``X509_CRL`` object to a ``X509_Store`` object -with ``X509_Code`` ``add_crl``(``X509_CRL``), and all future -verifications will take into account the certificates listed, assuming -``add_crl`` returns ``VERIFIED``. If it doesn't return -``VERIFIED``, then the return value is an error code signifying that the CRL -could not be processed due to some problem (which could range from the issuing -certificate not being found, to the CRL having some format problem). For more -about the ``X509_Store`` API, read the section later in this chapter. +with + +.. cpp:function:: X509_Code X509_Store::add_crl(const X509_CRL& crl) + +and all future verifications will take into account the certificates +listed, assuming ``add_crl`` returns ``VERIFIED``. If it doesn't +return ``VERIFIED``, then the return value is an error code signifying +that the CRL could not be processed due to some problem (which could +be something like the issuing certificate could not being found, an +invalid signature, or the CRL having some format problem). For more +about the ``X509_Store`` API, read :ref:`x509_store`. Reading Certificates --------------------------------- @@ -162,6 +163,8 @@ Reading Certificates ``X509_Certificate`` has two constructors, each of which takes a source of data; a filename to read, and a ``DataSource&``. +.. _x509_store: + Storing and Using Certificates --------------------------------- @@ -184,113 +187,89 @@ Adding Certificates You can add new certificates to a certificate store using any of these functions: -``add_cert``(``const X509_Certificate&`` ``cert``, - ``bool`` ``trusted`` ``= false``) +.. cpp:function:: void add_cert(const X509_Certificate& cert, bool trusted = false) -``add_certs``(``DataSource&`` ``source``) +.. cpp:function:: void add_cert(DataSource& source) -``add_trusted_certs``(``DataSource&`` ``source``) +.. cpp:function:: void add_trusted_certs(DataSource& source) The versions that take a ``DataSource&`` will add all the certificates that it can find in that source. -All of them add the cert(s) to the store. The 'trusted' certificates are the -ones that you have some reason to trust are genuine. For example, say your -application is working with certificates that are owned by employees of some -company, and all of their certificates are signed by the company CA, whose -certificate is in turned signed by a commercial root CA. What you would then do -is include the certificate of the commercial CA with your application, and read -it in as a trusted certificate. From there, you could verify the company CA's -certificate, and then use that to verify the end user's certificates. Only -self-signed certificates may be considered trusted. +All of them add the cert(s) to the store. The "trusted" certificates +are the ones that you are willing to trust for certification +purposes. For example, say your application is working with +certificates that are owned by employees of some company, and all of +their certificates are signed by the company CA, whose certificate is +in turned signed by a commercial root CA. What you would then do is +include the certificate of the commercial CA with your application, +and read it in as a trusted certificate. From there, you could verify +the company CA's certificate, and then use that to verify the end +user's certificates. Only self-signed certificates may be considered +trusted. Adding CRLs ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -``X509_Code`` ``add_crl``(``const X509_CRL&`` ``crl``); +.. cpp:function:: X509_Code add_crl(const X509_CRL& crl) -This will process the CRL and mark the revoked certificates. This will also -work if a revoked certificate is added to the store sometime after the CRL is -processed. The function can return an error code (listed later), or will return -``VERIFIED`` if everything completed successfully. +This will process the CRL and mark the revoked certificates. This will +also work if a revoked certificate is added to the store sometime +after the CRL is processed. The function can return an error code +(listed later), or will return ``VERIFIED`` if everything completed +successfully. Storing Certificates ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You can output a set of certificates by calling ``PEM_encode``, which -will return a ``std::string`` containing each of the certificates in the -store, PEM encoded and concatenated. This simple format can easily be read by -both Botan and other libraries/applications. - -Searching for Certificates -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -You can find certificates in the store with a series of functions contained -in the ``X509_Store_Search`` namespace:: - - std::vector<X509_Certificate> by_email(const X509_Store& store, - const std::string& email_addr); - std::vector<X509_Certificate> by_name(const X509_Store& store, - const std::string& name); - std::vector<X509_Certificate> by_dns(const X509_Store&, - const std::string& dns_name); - -These functions will return a (possibly empty) vector of certificates from -``store`` matching your search criteria. The email address and DNS name -searches are case-insensitive but are sensitive to extra whitespace and so -on. The name search will do case-insensitive substring matching, so, for -example, calling ``X509_Store_Search::by_name``(``your_store``, -"dob") will return certificates for ``J.R. 'Bob' Dobbs'' and -``H. Dobbertin'', assuming both of those certificates are in ``your_store``. - -You could then display the results to a user, and allow them to select the -appropriate one. Searching using an email address as the key is usually more -effective than the name, since email addresses are rarely shared. +will return a ``std::string`` containing each of the certificates in +the store, PEM encoded and concatenated. This simple format can easily +be read by both Botan and other libraries/applications. Certificate Stores ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -An object of type ``Certificate_Store`` is a generalized interface -to an external source for certificates (and CRLs). Examples of such a +An object of type ``Certificate_Store`` is a generalized interface to +an external source for certificates (and CRLs). Examples of such a store would be one that looked up the certificates in a SQL database, or by contacting a CGI script running on a HTTP server. There are currently three mechanisms for looking up a certificate, and one for retrieving CRLs. By default, most of these mechanisms will return an -empty ``std::vector`` of ``X509_Certificate``. This storage -mechanism is *only* queried when doing certificate validation: it -allows you to distribute only the root key with an application, and -let some online method handle getting all the other certificates that -are needed to validate an end entity certificate. In particular, the -search routines will not attempt to access the external database. +empty ``std::vector`` of ``X509_Certificate``. This storage mechanism +is *only* queried when doing certificate validation: it allows you to +distribute only the root key with an application, and let some online +method handle getting all the other certificates that are needed to +validate an end entity certificate. In particular, the search routines +will not attempt to access the external database. The three certificate lookup methods are ``by_SKID`` (Subject Key -Identifier), ``by_name`` (the CommonName DN entry), and -``by_email`` (stored in either the distinguished name, or in a +Identifier), ``by_name`` (the CommonName DN entry), and ``by_email`` +(stored in either the distinguished name, or in a subjectAlternativeName extension). The name and email versions take a ``std::string``, while the SKID version takes a ``SecureVector<byte>`` -containing the subject key identifier in raw binary. You can choose not to -implement ``by_name`` or ``by_email``, but ``by_SKID`` -is mandatory to implement, and, currently, is the only version that is used by -``X509_Store``. - -Finally, there is a method for finding CRLs, called -``get_crls_for``, that takes an ``X509_Certificate`` -object, and returns a ``std::vector`` of ``X509_CRL``. While -normally there will be only one CRL, the use of the vector makes it -easy to return no CRLs (eg, if the certificate store doesn't support -retrieving them), or return multiple ones (for example, if the -certificate store can't determine precisely which key was used to sign -the certificate). Implementing the function is optional, and by -default will return no CRLs. If it is available, it will be used by -``X509_CRL``. +containing the subject key identifier in raw binary. You can choose +not to implement ``by_name`` or ``by_email``, but ``by_SKID`` is +mandatory to implement, and, currently, is the only version that is +used by ``X509_Store``. + +Finally, there is a method for finding CRLs, called ``get_crls_for``, +that takes an ``X509_Certificate`` object, and returns a +``std::vector`` of ``X509_CRL``. While normally there will be only one +CRL, the use of the vector makes it easy to return no CRLs (eg, if the +certificate store doesn't support retrieving them), or return multiple +ones (for example, if the certificate store can't determine precisely +which key was used to sign the certificate). Implementing the function +is optional, and by default will return no CRLs. If it is available, +it will be used by ``X509_CRL``. As for using such a store, you have to tell ``X509_Store`` about it, by calling the ``X509_Store`` member function -``add_new_certstore``(``Certificate_Store``* ``new_store``) +.. cpp:function:: void add_new_certstore(Certificate_Store* new_store) -The argument, ``new_store``, will be deleted by ``X509_Store``'s -destructor, so make sure to allocate it with ``new``. + The store object will be owned by (and deleted by) ``X509_Store``, + so make sure to allocate it with ``new``. Verifying Certificates ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -411,33 +390,35 @@ available at all times. Of course, you might be wondering what to do if no certificates have been revoked. Never fear; empty CRLs, which revoke nothing at all, can -be issued. To generate a new, empty CRL, just call ``X509_CRL`` -``X509_CA::new_crl``(``size_t``~``seconds``~=~0)~--~it -will create a new, empty, CRL. If ``seconds`` is the default 0, then -the normal default CRL next update time (the value of the -``x509/crl/next_update'') will be used. If not, then ``seconds`` -specifies how long (in seconds) it will be until the CRL's next update -time (after this time, most clients will reject the CRL as too old). +be issued. To generate a new, empty CRL, just call + +.. cpp:function:: X509_CRL X509_CA::new_crl(u32bit seconds_to_expiration = 0) + + This function will return a new, empty CRL. The + ``seconds_to_expiration`` parameter is the number of seconds before + the CRL expires. If it is set to the (default) value of zero, then a + reasonable default (currently 7 days) will be used. On the other hand, you may have issued a CRL before. In that case, you will want to issue a new CRL that contains all previously revoked -certificates, along with any new ones. This is done by calling the -``X509_CA`` member function -``update_crl``(``X509_CRL``~``old_crl``, -``std::vector<CRL_Entry>``~``new_revoked``, -``size_t``~``seconds``~=~0), where ``X509_CRL`` is the last CRL this -CA issued, and ``new_revoked`` is a list of any newly revoked certificates. -The function returns a new ``X509_CRL`` to make available for clients. The -semantics for the ``seconds`` argument is the same as ``new_crl``. +certificates, along with any new ones. This is done by calling + +.. cpp:function:: X509_CRL X509_CA::update_crl(const X509_CRL& old_crl, std::vector<CRL_Entry> new_revoked, size_t seconds_to_expiration = 0) + + Where ``X509_CRL`` is the last CRL this CA issued, and + ``new_revoked`` is a list of any newly revoked certificates. The + function returns a new ``X509_CRL`` to make available for + clients. The ``CRL_Entry`` type is a structure that contains, at a minimum, the -serial number of the revoked certificate. As serial numbers are never repeated, -the pairing of an issuer and a serial number (should) distinctly identify any -certificate. In this case, we represent the serial number as a -``SecureVector<byte>`` called ``serial``. There are two additional -(optional) values, an enumeration called ``CRL_Code`` that specifies the -reason for revocation (``reason``), and an object that represents the time -that the certificate became invalid (if this information is known). +serial number of the revoked certificate. As serial numbers are never +repeated, the pairing of an issuer and a serial number (should) +distinctly identify any certificate. In this case, we represent the +serial number as a ``SecureVector<byte>`` called ``serial``. There are +two additional (optional) values, an enumeration called ``CRL_Code`` +that specifies the reason for revocation (``reason``), and an object +that represents the time that the certificate became invalid (if this +information is known). If you wish to remove an old entry from the CRL, insert a new entry for the same cert, with a ``reason`` code of ``DELETE_CRL_ENTRY``. For example, @@ -465,32 +446,33 @@ Creating PKCS #10 Requests ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Also in ``x509self.h``, there is a function for generating new PKCS #10 -certificate requests:: +certificate requests: -.. cpp:function:: PKCS10_Request create_cert_req(const X509_Cert_Options&, const Private_Key&) +.. cpp:function:: PKCS10_Request create_cert_req(const X509_Cert_Options& opts, const Private_Key& key) This function acts quite similarly to ``create_self_signed_cert``, -except it instead returns a PKCS #10 certificate request. After creating it, -one would typically transmit it to a CA, who signs it and returns a freshly -minted X.509 certificate. There is an example of using this function in the -``pkcs10`` example. +except it instead returns a PKCS #10 certificate request. After +creating it, one would typically transmit it to a CA, who signs it and +returns a freshly minted X.509 certificate. There is an example of +using this function in the ``pkcs10`` example. Certificate Options ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -What is this ``X509_Cert_Options`` thing we've been passing -around? It's a class representing a bunch of information that will end -up being stored into the certificate. This information comes in 3 -major flavors: information about the subject (CA or end-user), the -validity period of the certificate, and restrictions on the usage of -the certificate. +What is this ``X509_Cert_Options`` thing we've been passing around? +It's a class representing a bunch of information that will end up +being stored into the certificate. This information comes in 3 major +flavors: information about the subject (CA or end-user), the validity +period of the certificate, and restrictions on the usage of the +certificate. -First and foremost is a number of ``std::string`` members, which contains -various bits of information about the user: ``common_name``, +First and foremost is a number of ``std::string`` members, which +contains various bits of information about the user: ``common_name``, ``serial_number``, ``country``, ``organization``, ``org_unit``, -``locality``, ``state``, ``email``, ``dns_name``, and ``uri``. As -many of these as possible should be filled it (especially an email address), -though the only required ones are ``common_name`` and ``country``. +``locality``, ``state``, ``email``, ``dns_name``, and ``uri``. As many +of these as possible should be filled it (especially an email +address), though the only required ones are ``common_name`` and +``country``. There is another value that is only useful when creating a PKCS #10 request, which is called ``challenge``. This is a challenge password, which you can @@ -539,5 +521,5 @@ are named "PKIX.ServerAuth" (for TLS server authentication), "PKIX.EmailProtection" (most likely for use with S/MIME), "PKIX.IPsecUser", "PKIX.IPsecTunnel", "PKIX.IPsecEndSystem", and "PKIX.TimeStamping". You can call "add_ex_constraints" any number of -times~--~each new OID will be added to the list to include in the +times - each new OID will be added to the list to include in the certificate. |