xref: /freebsd/contrib/bearssl/inc/bearssl_x509.h (revision cc9e6590)
10957b409SSimon J. Gerraty /*
20957b409SSimon J. Gerraty  * Copyright (c) 2016 Thomas Pornin <pornin@bolet.org>
30957b409SSimon J. Gerraty  *
40957b409SSimon J. Gerraty  * Permission is hereby granted, free of charge, to any person obtaining
50957b409SSimon J. Gerraty  * a copy of this software and associated documentation files (the
60957b409SSimon J. Gerraty  * "Software"), to deal in the Software without restriction, including
70957b409SSimon J. Gerraty  * without limitation the rights to use, copy, modify, merge, publish,
80957b409SSimon J. Gerraty  * distribute, sublicense, and/or sell copies of the Software, and to
90957b409SSimon J. Gerraty  * permit persons to whom the Software is furnished to do so, subject to
100957b409SSimon J. Gerraty  * the following conditions:
110957b409SSimon J. Gerraty  *
120957b409SSimon J. Gerraty  * The above copyright notice and this permission notice shall be
130957b409SSimon J. Gerraty  * included in all copies or substantial portions of the Software.
140957b409SSimon J. Gerraty  *
150957b409SSimon J. Gerraty  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
160957b409SSimon J. Gerraty  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
170957b409SSimon J. Gerraty  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
180957b409SSimon J. Gerraty  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
190957b409SSimon J. Gerraty  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
200957b409SSimon J. Gerraty  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
210957b409SSimon J. Gerraty  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
220957b409SSimon J. Gerraty  * SOFTWARE.
230957b409SSimon J. Gerraty  */
240957b409SSimon J. Gerraty 
250957b409SSimon J. Gerraty #ifndef BR_BEARSSL_X509_H__
260957b409SSimon J. Gerraty #define BR_BEARSSL_X509_H__
270957b409SSimon J. Gerraty 
280957b409SSimon J. Gerraty #include <stddef.h>
290957b409SSimon J. Gerraty #include <stdint.h>
300957b409SSimon J. Gerraty 
310957b409SSimon J. Gerraty #include "bearssl_ec.h"
320957b409SSimon J. Gerraty #include "bearssl_hash.h"
330957b409SSimon J. Gerraty #include "bearssl_rsa.h"
340957b409SSimon J. Gerraty 
350957b409SSimon J. Gerraty #ifdef __cplusplus
360957b409SSimon J. Gerraty extern "C" {
370957b409SSimon J. Gerraty #endif
380957b409SSimon J. Gerraty 
390957b409SSimon J. Gerraty /** \file bearssl_x509.h
400957b409SSimon J. Gerraty  *
410957b409SSimon J. Gerraty  * # X.509 Certificate Chain Processing
420957b409SSimon J. Gerraty  *
430957b409SSimon J. Gerraty  * An X.509 processing engine receives an X.509 chain, chunk by chunk,
440957b409SSimon J. Gerraty  * as received from a SSL/TLS client or server (the client receives the
450957b409SSimon J. Gerraty  * server's certificate chain, and the server receives the client's
460957b409SSimon J. Gerraty  * certificate chain if it requested a client certificate). The chain
470957b409SSimon J. Gerraty  * is thus injected in the engine in SSL order (end-entity first).
480957b409SSimon J. Gerraty  *
490957b409SSimon J. Gerraty  * The engine's job is to return the public key to use for SSL/TLS.
500957b409SSimon J. Gerraty  * How exactly that key is obtained and verified is entirely up to the
510957b409SSimon J. Gerraty  * engine.
520957b409SSimon J. Gerraty  *
530957b409SSimon J. Gerraty  * **The "known key" engine** returns a public key which is already known
540957b409SSimon J. Gerraty  * from out-of-band information (e.g. the client _remembers_ the key from
550957b409SSimon J. Gerraty  * a previous connection, as in the usual SSH model). This is the simplest
560957b409SSimon J. Gerraty  * engine since it simply ignores the chain, thereby avoiding the need
570957b409SSimon J. Gerraty  * for any decoding logic.
580957b409SSimon J. Gerraty  *
590957b409SSimon J. Gerraty  * **The "minimal" engine** implements minimal X.509 decoding and chain
600957b409SSimon J. Gerraty  * validation:
610957b409SSimon J. Gerraty  *
620957b409SSimon J. Gerraty  *   - The provided chain should validate "as is". There is no attempt
630957b409SSimon J. Gerraty  *     at reordering, skipping or downloading extra certificates.
640957b409SSimon J. Gerraty  *
650957b409SSimon J. Gerraty  *   - X.509 v1, v2 and v3 certificates are supported.
660957b409SSimon J. Gerraty  *
670957b409SSimon J. Gerraty  *   - Trust anchors are a DN and a public key. Each anchor is either a
680957b409SSimon J. Gerraty  *     "CA" anchor, or a non-CA.
690957b409SSimon J. Gerraty  *
700957b409SSimon J. Gerraty  *   - If the end-entity certificate matches a non-CA anchor (subject DN
710957b409SSimon J. Gerraty  *     is equal to the non-CA name, and public key is also identical to
720957b409SSimon J. Gerraty  *     the anchor key), then this is a _direct trust_ case and the
730957b409SSimon J. Gerraty  *     remaining certificates are ignored.
740957b409SSimon J. Gerraty  *
750957b409SSimon J. Gerraty  *   - Unless direct trust is applied, the chain must be verifiable up to
760957b409SSimon J. Gerraty  *     a certificate whose issuer DN matches the DN from a "CA" trust anchor,
770957b409SSimon J. Gerraty  *     and whose signature is verifiable against that anchor's public key.
780957b409SSimon J. Gerraty  *     Subsequent certificates in the chain are ignored.
790957b409SSimon J. Gerraty  *
800957b409SSimon J. Gerraty  *   - The engine verifies subject/issuer DN matching, and enforces
810957b409SSimon J. Gerraty  *     processing of Basic Constraints and Key Usage extensions. The
820957b409SSimon J. Gerraty  *     Authority Key Identifier, Subject Key Identifier, Issuer Alt Name,
830957b409SSimon J. Gerraty  *     Subject Directory Attribute, CRL Distribution Points, Freshest CRL,
840957b409SSimon J. Gerraty  *     Authority Info Access and Subject Info Access extensions are
850957b409SSimon J. Gerraty  *     ignored. The Subject Alt Name is decoded for the end-entity
860957b409SSimon J. Gerraty  *     certificate under some conditions (see below). Other extensions
870957b409SSimon J. Gerraty  *     are ignored if non-critical, or imply chain rejection if critical.
880957b409SSimon J. Gerraty  *
890957b409SSimon J. Gerraty  *   - The Subject Alt Name extension is parsed for names of type `dNSName`
900957b409SSimon J. Gerraty  *     when decoding the end-entity certificate, and only if there is a
910957b409SSimon J. Gerraty  *     server name to match. If there is no SAN extension, then the
920957b409SSimon J. Gerraty  *     Common Name from the subjectDN is used. That name matching is
930957b409SSimon J. Gerraty  *     case-insensitive and honours a single starting wildcard (i.e. if
940957b409SSimon J. Gerraty  *     the name in the certificate starts with "`*.`" then this matches
950957b409SSimon J. Gerraty  *     any word as first element). Note: this name matching is performed
960957b409SSimon J. Gerraty  *     also in the "direct trust" model.
970957b409SSimon J. Gerraty  *
980957b409SSimon J. Gerraty  *   - DN matching is byte-to-byte equality (a future version might
990957b409SSimon J. Gerraty  *     include some limited processing for case-insensitive matching and
1000957b409SSimon J. Gerraty  *     whitespace normalisation).
1010957b409SSimon J. Gerraty  *
1020957b409SSimon J. Gerraty  *   - Successful validation produces a public key type but also a set
1030957b409SSimon J. Gerraty  *     of allowed usages (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`).
1040957b409SSimon J. Gerraty  *     The caller is responsible for checking that the key type and
1050957b409SSimon J. Gerraty  *     usages are compatible with the expected values (e.g. with the
1060957b409SSimon J. Gerraty  *     selected cipher suite, when the client validates the server's
1070957b409SSimon J. Gerraty  *     certificate).
1080957b409SSimon J. Gerraty  *
1090957b409SSimon J. Gerraty  * **Important caveats:**
1100957b409SSimon J. Gerraty  *
1110957b409SSimon J. Gerraty  *   - The "minimal" engine does not check revocation status. The relevant
1120957b409SSimon J. Gerraty  *     extensions are ignored, and CRL or OCSP responses are not gathered
1130957b409SSimon J. Gerraty  *     or checked.
1140957b409SSimon J. Gerraty  *
1150957b409SSimon J. Gerraty  *   - The "minimal" engine does not currently support Name Constraints
1160957b409SSimon J. Gerraty  *     (some basic functionality to handle sub-domains may be added in a
1170957b409SSimon J. Gerraty  *     later version).
1180957b409SSimon J. Gerraty  *
1190957b409SSimon J. Gerraty  *   - The decoder is not "validating" in the sense that it won't reject
1200957b409SSimon J. Gerraty  *     some certificates with invalid field values when these fields are
1210957b409SSimon J. Gerraty  *     not actually processed.
1220957b409SSimon J. Gerraty  */
1230957b409SSimon J. Gerraty 
1240957b409SSimon J. Gerraty /*
1250957b409SSimon J. Gerraty  * X.509 error codes are in the 32..63 range.
1260957b409SSimon J. Gerraty  */
1270957b409SSimon J. Gerraty 
1280957b409SSimon J. Gerraty /** \brief X.509 status: validation was successful; this is not actually
1290957b409SSimon J. Gerraty     an error. */
1300957b409SSimon J. Gerraty #define BR_ERR_X509_OK                    32
1310957b409SSimon J. Gerraty 
1320957b409SSimon J. Gerraty /** \brief X.509 status: invalid value in an ASN.1 structure. */
1330957b409SSimon J. Gerraty #define BR_ERR_X509_INVALID_VALUE         33
1340957b409SSimon J. Gerraty 
1350957b409SSimon J. Gerraty /** \brief X.509 status: truncated certificate. */
1360957b409SSimon J. Gerraty #define BR_ERR_X509_TRUNCATED             34
1370957b409SSimon J. Gerraty 
1380957b409SSimon J. Gerraty /** \brief X.509 status: empty certificate chain (no certificate at all). */
1390957b409SSimon J. Gerraty #define BR_ERR_X509_EMPTY_CHAIN           35
1400957b409SSimon J. Gerraty 
1410957b409SSimon J. Gerraty /** \brief X.509 status: decoding error: inner element extends beyond
1420957b409SSimon J. Gerraty     outer element size. */
1430957b409SSimon J. Gerraty #define BR_ERR_X509_INNER_TRUNC           36
1440957b409SSimon J. Gerraty 
1450957b409SSimon J. Gerraty /** \brief X.509 status: decoding error: unsupported tag class (application
1460957b409SSimon J. Gerraty     or private). */
1470957b409SSimon J. Gerraty #define BR_ERR_X509_BAD_TAG_CLASS         37
1480957b409SSimon J. Gerraty 
1490957b409SSimon J. Gerraty /** \brief X.509 status: decoding error: unsupported tag value. */
1500957b409SSimon J. Gerraty #define BR_ERR_X509_BAD_TAG_VALUE         38
1510957b409SSimon J. Gerraty 
1520957b409SSimon J. Gerraty /** \brief X.509 status: decoding error: indefinite length. */
1530957b409SSimon J. Gerraty #define BR_ERR_X509_INDEFINITE_LENGTH     39
1540957b409SSimon J. Gerraty 
1550957b409SSimon J. Gerraty /** \brief X.509 status: decoding error: extraneous element. */
1560957b409SSimon J. Gerraty #define BR_ERR_X509_EXTRA_ELEMENT         40
1570957b409SSimon J. Gerraty 
1580957b409SSimon J. Gerraty /** \brief X.509 status: decoding error: unexpected element. */
1590957b409SSimon J. Gerraty #define BR_ERR_X509_UNEXPECTED            41
1600957b409SSimon J. Gerraty 
1610957b409SSimon J. Gerraty /** \brief X.509 status: decoding error: expected constructed element, but
1620957b409SSimon J. Gerraty     is primitive. */
1630957b409SSimon J. Gerraty #define BR_ERR_X509_NOT_CONSTRUCTED       42
1640957b409SSimon J. Gerraty 
1650957b409SSimon J. Gerraty /** \brief X.509 status: decoding error: expected primitive element, but
1660957b409SSimon J. Gerraty     is constructed. */
1670957b409SSimon J. Gerraty #define BR_ERR_X509_NOT_PRIMITIVE         43
1680957b409SSimon J. Gerraty 
1690957b409SSimon J. Gerraty /** \brief X.509 status: decoding error: BIT STRING length is not multiple
1700957b409SSimon J. Gerraty     of 8. */
1710957b409SSimon J. Gerraty #define BR_ERR_X509_PARTIAL_BYTE          44
1720957b409SSimon J. Gerraty 
1730957b409SSimon J. Gerraty /** \brief X.509 status: decoding error: BOOLEAN value has invalid length. */
1740957b409SSimon J. Gerraty #define BR_ERR_X509_BAD_BOOLEAN           45
1750957b409SSimon J. Gerraty 
1760957b409SSimon J. Gerraty /** \brief X.509 status: decoding error: value is off-limits. */
1770957b409SSimon J. Gerraty #define BR_ERR_X509_OVERFLOW              46
1780957b409SSimon J. Gerraty 
1790957b409SSimon J. Gerraty /** \brief X.509 status: invalid distinguished name. */
1800957b409SSimon J. Gerraty #define BR_ERR_X509_BAD_DN                47
1810957b409SSimon J. Gerraty 
1820957b409SSimon J. Gerraty /** \brief X.509 status: invalid date/time representation. */
1830957b409SSimon J. Gerraty #define BR_ERR_X509_BAD_TIME              48
1840957b409SSimon J. Gerraty 
1850957b409SSimon J. Gerraty /** \brief X.509 status: certificate contains unsupported features that
1860957b409SSimon J. Gerraty     cannot be ignored. */
1870957b409SSimon J. Gerraty #define BR_ERR_X509_UNSUPPORTED           49
1880957b409SSimon J. Gerraty 
1890957b409SSimon J. Gerraty /** \brief X.509 status: key or signature size exceeds internal limits. */
1900957b409SSimon J. Gerraty #define BR_ERR_X509_LIMIT_EXCEEDED        50
1910957b409SSimon J. Gerraty 
1920957b409SSimon J. Gerraty /** \brief X.509 status: key type does not match that which was expected. */
1930957b409SSimon J. Gerraty #define BR_ERR_X509_WRONG_KEY_TYPE        51
1940957b409SSimon J. Gerraty 
1950957b409SSimon J. Gerraty /** \brief X.509 status: signature is invalid. */
1960957b409SSimon J. Gerraty #define BR_ERR_X509_BAD_SIGNATURE         52
1970957b409SSimon J. Gerraty 
1980957b409SSimon J. Gerraty /** \brief X.509 status: validation time is unknown. */
1990957b409SSimon J. Gerraty #define BR_ERR_X509_TIME_UNKNOWN          53
2000957b409SSimon J. Gerraty 
2010957b409SSimon J. Gerraty /** \brief X.509 status: certificate is expired or not yet valid. */
2020957b409SSimon J. Gerraty #define BR_ERR_X509_EXPIRED               54
2030957b409SSimon J. Gerraty 
2040957b409SSimon J. Gerraty /** \brief X.509 status: issuer/subject DN mismatch in the chain. */
2050957b409SSimon J. Gerraty #define BR_ERR_X509_DN_MISMATCH           55
2060957b409SSimon J. Gerraty 
2070957b409SSimon J. Gerraty /** \brief X.509 status: expected server name was not found in the chain. */
2080957b409SSimon J. Gerraty #define BR_ERR_X509_BAD_SERVER_NAME       56
2090957b409SSimon J. Gerraty 
2100957b409SSimon J. Gerraty /** \brief X.509 status: unknown critical extension in certificate. */
2110957b409SSimon J. Gerraty #define BR_ERR_X509_CRITICAL_EXTENSION    57
2120957b409SSimon J. Gerraty 
2130957b409SSimon J. Gerraty /** \brief X.509 status: not a CA, or path length constraint violation */
2140957b409SSimon J. Gerraty #define BR_ERR_X509_NOT_CA                58
2150957b409SSimon J. Gerraty 
2160957b409SSimon J. Gerraty /** \brief X.509 status: Key Usage extension prohibits intended usage. */
2170957b409SSimon J. Gerraty #define BR_ERR_X509_FORBIDDEN_KEY_USAGE   59
2180957b409SSimon J. Gerraty 
2190957b409SSimon J. Gerraty /** \brief X.509 status: public key found in certificate is too small. */
2200957b409SSimon J. Gerraty #define BR_ERR_X509_WEAK_PUBLIC_KEY       60
2210957b409SSimon J. Gerraty 
2220957b409SSimon J. Gerraty /** \brief X.509 status: chain could not be linked to a trust anchor. */
2230957b409SSimon J. Gerraty #define BR_ERR_X509_NOT_TRUSTED           62
2240957b409SSimon J. Gerraty 
2250957b409SSimon J. Gerraty /**
2260957b409SSimon J. Gerraty  * \brief Aggregate structure for public keys.
2270957b409SSimon J. Gerraty  */
2280957b409SSimon J. Gerraty typedef struct {
2290957b409SSimon J. Gerraty 	/** \brief Key type: `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC` */
2300957b409SSimon J. Gerraty 	unsigned char key_type;
2310957b409SSimon J. Gerraty 	/** \brief Actual public key. */
2320957b409SSimon J. Gerraty 	union {
2330957b409SSimon J. Gerraty 		/** \brief RSA public key. */
2340957b409SSimon J. Gerraty 		br_rsa_public_key rsa;
2350957b409SSimon J. Gerraty 		/** \brief EC public key. */
2360957b409SSimon J. Gerraty 		br_ec_public_key ec;
2370957b409SSimon J. Gerraty 	} key;
2380957b409SSimon J. Gerraty } br_x509_pkey;
2390957b409SSimon J. Gerraty 
2400957b409SSimon J. Gerraty /**
2410957b409SSimon J. Gerraty  * \brief Distinguished Name (X.500) structure.
2420957b409SSimon J. Gerraty  *
2430957b409SSimon J. Gerraty  * The DN is DER-encoded.
2440957b409SSimon J. Gerraty  */
2450957b409SSimon J. Gerraty typedef struct {
2460957b409SSimon J. Gerraty 	/** \brief Encoded DN data. */
2470957b409SSimon J. Gerraty 	unsigned char *data;
2480957b409SSimon J. Gerraty 	/** \brief Encoded DN length (in bytes). */
2490957b409SSimon J. Gerraty 	size_t len;
2500957b409SSimon J. Gerraty } br_x500_name;
2510957b409SSimon J. Gerraty 
2520957b409SSimon J. Gerraty /**
2530957b409SSimon J. Gerraty  * \brief Trust anchor structure.
2540957b409SSimon J. Gerraty  */
2550957b409SSimon J. Gerraty typedef struct {
2560957b409SSimon J. Gerraty 	/** \brief Encoded DN (X.500 name). */
2570957b409SSimon J. Gerraty 	br_x500_name dn;
2580957b409SSimon J. Gerraty 	/** \brief Anchor flags (e.g. `BR_X509_TA_CA`). */
2590957b409SSimon J. Gerraty 	unsigned flags;
2600957b409SSimon J. Gerraty 	/** \brief Anchor public key. */
2610957b409SSimon J. Gerraty 	br_x509_pkey pkey;
2620957b409SSimon J. Gerraty } br_x509_trust_anchor;
2630957b409SSimon J. Gerraty 
2640957b409SSimon J. Gerraty /**
2650957b409SSimon J. Gerraty  * \brief Trust anchor flag: CA.
2660957b409SSimon J. Gerraty  *
2670957b409SSimon J. Gerraty  * A "CA" anchor is deemed fit to verify signatures on certificates.
2680957b409SSimon J. Gerraty  * A "non-CA" anchor is accepted only for direct trust (server's
2690957b409SSimon J. Gerraty  * certificate name and key match the anchor).
2700957b409SSimon J. Gerraty  */
2710957b409SSimon J. Gerraty #define BR_X509_TA_CA        0x0001
2720957b409SSimon J. Gerraty 
2730957b409SSimon J. Gerraty /*
2740957b409SSimon J. Gerraty  * Key type: combination of a basic key type (low 4 bits) and some
2750957b409SSimon J. Gerraty  * optional flags.
2760957b409SSimon J. Gerraty  *
2770957b409SSimon J. Gerraty  * For a public key, the basic key type only is set.
2780957b409SSimon J. Gerraty  *
2790957b409SSimon J. Gerraty  * For an expected key type, the flags indicate the intended purpose(s)
2800957b409SSimon J. Gerraty  * for the key; the basic key type may be set to 0 to indicate that any
2810957b409SSimon J. Gerraty  * key type compatible with the indicated purpose is acceptable.
2820957b409SSimon J. Gerraty  */
2830957b409SSimon J. Gerraty /** \brief Key type: algorithm is RSA. */
2840957b409SSimon J. Gerraty #define BR_KEYTYPE_RSA    1
2850957b409SSimon J. Gerraty /** \brief Key type: algorithm is EC. */
2860957b409SSimon J. Gerraty #define BR_KEYTYPE_EC     2
2870957b409SSimon J. Gerraty 
2880957b409SSimon J. Gerraty /**
2890957b409SSimon J. Gerraty  * \brief Key type: usage is "key exchange".
2900957b409SSimon J. Gerraty  *
2910957b409SSimon J. Gerraty  * This value is combined (with bitwise OR) with the algorithm
2920957b409SSimon J. Gerraty  * (`BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`) when informing the X.509
2930957b409SSimon J. Gerraty  * validation engine that it should find a public key of that type,
2940957b409SSimon J. Gerraty  * fit for key exchanges (e.g. `TLS_RSA_*` and `TLS_ECDH_*` cipher
2950957b409SSimon J. Gerraty  * suites).
2960957b409SSimon J. Gerraty  */
2970957b409SSimon J. Gerraty #define BR_KEYTYPE_KEYX   0x10
2980957b409SSimon J. Gerraty 
2990957b409SSimon J. Gerraty /**
3000957b409SSimon J. Gerraty  * \brief Key type: usage is "signature".
3010957b409SSimon J. Gerraty  *
3020957b409SSimon J. Gerraty  * This value is combined (with bitwise OR) with the algorithm
3030957b409SSimon J. Gerraty  * (`BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`) when informing the X.509
3040957b409SSimon J. Gerraty  * validation engine that it should find a public key of that type,
3050957b409SSimon J. Gerraty  * fit for signatures (e.g. `TLS_ECDHE_*` cipher suites).
3060957b409SSimon J. Gerraty  */
3070957b409SSimon J. Gerraty #define BR_KEYTYPE_SIGN   0x20
3080957b409SSimon J. Gerraty 
3090957b409SSimon J. Gerraty /*
3100957b409SSimon J. Gerraty  * start_chain   Called when a new chain is started. If 'server_name'
3110957b409SSimon J. Gerraty  *               is not NULL and non-empty, then it is a name that
3120957b409SSimon J. Gerraty  *               should be looked for in the EE certificate (in the
3130957b409SSimon J. Gerraty  *               SAN extension as dNSName, or in the subjectDN's CN
3140957b409SSimon J. Gerraty  *               if there is no SAN extension).
3150957b409SSimon J. Gerraty  *               The caller ensures that the provided 'server_name'
3160957b409SSimon J. Gerraty  *               pointer remains valid throughout validation.
3170957b409SSimon J. Gerraty  *
3180957b409SSimon J. Gerraty  * start_cert    Begins a new certificate in the chain. The provided
3190957b409SSimon J. Gerraty  *               length is in bytes; this is the total certificate length.
3200957b409SSimon J. Gerraty  *
3210957b409SSimon J. Gerraty  * append        Get some additional bytes for the current certificate.
3220957b409SSimon J. Gerraty  *
3230957b409SSimon J. Gerraty  * end_cert      Ends the current certificate.
3240957b409SSimon J. Gerraty  *
3250957b409SSimon J. Gerraty  * end_chain     Called at the end of the chain. Returned value is
3260957b409SSimon J. Gerraty  *               0 on success, or a non-zero error code.
3270957b409SSimon J. Gerraty  *
3280957b409SSimon J. Gerraty  * get_pkey      Returns the EE certificate public key.
3290957b409SSimon J. Gerraty  *
3300957b409SSimon J. Gerraty  * For a complete chain, start_chain() and end_chain() are always
3310957b409SSimon J. Gerraty  * called. For each certificate, start_cert(), some append() calls, then
3320957b409SSimon J. Gerraty  * end_cert() are called, in that order. There may be no append() call
3330957b409SSimon J. Gerraty  * at all if the certificate is empty (which is not valid but may happen
3340957b409SSimon J. Gerraty  * if the peer sends exactly that).
3350957b409SSimon J. Gerraty  *
3360957b409SSimon J. Gerraty  * get_pkey() shall return a pointer to a structure that is valid as
3370957b409SSimon J. Gerraty  * long as a new chain is not started. This may be a sub-structure
3380957b409SSimon J. Gerraty  * within the context for the engine. This function MAY return a valid
3390957b409SSimon J. Gerraty  * pointer to a public key even in some cases of validation failure,
3400957b409SSimon J. Gerraty  * depending on the validation engine.
3410957b409SSimon J. Gerraty  */
3420957b409SSimon J. Gerraty 
3430957b409SSimon J. Gerraty /**
3440957b409SSimon J. Gerraty  * \brief Class type for an X.509 engine.
3450957b409SSimon J. Gerraty  *
3460957b409SSimon J. Gerraty  * A certificate chain validation uses a caller-allocated context, which
3470957b409SSimon J. Gerraty  * contains the running state for that validation. Methods are called
3480957b409SSimon J. Gerraty  * in due order:
3490957b409SSimon J. Gerraty  *
3500957b409SSimon J. Gerraty  *   - `start_chain()` is called at the start of the validation.
3510957b409SSimon J. Gerraty  *   - Certificates are processed one by one, in SSL order (end-entity
3520957b409SSimon J. Gerraty  *     comes first). For each certificate, the following methods are
3530957b409SSimon J. Gerraty  *     called:
3540957b409SSimon J. Gerraty  *
3550957b409SSimon J. Gerraty  *       - `start_cert()` at the beginning of the certificate.
3560957b409SSimon J. Gerraty  *       - `append()` is called zero, one or more times, to provide
3570957b409SSimon J. Gerraty  *         the certificate (possibly in chunks).
3580957b409SSimon J. Gerraty  *       - `end_cert()` at the end of the certificate.
3590957b409SSimon J. Gerraty  *
3600957b409SSimon J. Gerraty  *   - `end_chain()` is called when the last certificate in the chain
3610957b409SSimon J. Gerraty  *     was processed.
3620957b409SSimon J. Gerraty  *   - `get_pkey()` is called after chain processing, if the chain
3630957b409SSimon J. Gerraty  *     validation was successful.
3640957b409SSimon J. Gerraty  *
3650957b409SSimon J. Gerraty  * A context structure may be reused; the `start_chain()` method shall
3660957b409SSimon J. Gerraty  * ensure (re)initialisation.
3670957b409SSimon J. Gerraty  */
3680957b409SSimon J. Gerraty typedef struct br_x509_class_ br_x509_class;
3690957b409SSimon J. Gerraty struct br_x509_class_ {
3700957b409SSimon J. Gerraty 	/**
3710957b409SSimon J. Gerraty 	 * \brief X.509 context size, in bytes.
3720957b409SSimon J. Gerraty 	 */
3730957b409SSimon J. Gerraty 	size_t context_size;
3740957b409SSimon J. Gerraty 
3750957b409SSimon J. Gerraty 	/**
3760957b409SSimon J. Gerraty 	 * \brief Start a new chain.
3770957b409SSimon J. Gerraty 	 *
3780957b409SSimon J. Gerraty 	 * This method shall set the vtable (first field) of the context
3790957b409SSimon J. Gerraty 	 * structure.
3800957b409SSimon J. Gerraty 	 *
3810957b409SSimon J. Gerraty 	 * The `server_name`, if not `NULL`, will be considered as a
3820957b409SSimon J. Gerraty 	 * fully qualified domain name, to be matched against the `dNSName`
3830957b409SSimon J. Gerraty 	 * elements of the end-entity certificate's SAN extension (if there
3840957b409SSimon J. Gerraty 	 * is no SAN, then the Common Name from the subjectDN will be used).
3850957b409SSimon J. Gerraty 	 * If `server_name` is `NULL` then no such matching is performed.
3860957b409SSimon J. Gerraty 	 *
3870957b409SSimon J. Gerraty 	 * \param ctx           validation context.
3880957b409SSimon J. Gerraty 	 * \param server_name   server name to match (or `NULL`).
3890957b409SSimon J. Gerraty 	 */
3900957b409SSimon J. Gerraty 	void (*start_chain)(const br_x509_class **ctx,
3910957b409SSimon J. Gerraty 		const char *server_name);
3920957b409SSimon J. Gerraty 
3930957b409SSimon J. Gerraty 	/**
3940957b409SSimon J. Gerraty 	 * \brief Start a new certificate.
3950957b409SSimon J. Gerraty 	 *
3960957b409SSimon J. Gerraty 	 * \param ctx      validation context.
3970957b409SSimon J. Gerraty 	 * \param length   new certificate length (in bytes).
3980957b409SSimon J. Gerraty 	 */
3990957b409SSimon J. Gerraty 	void (*start_cert)(const br_x509_class **ctx, uint32_t length);
4000957b409SSimon J. Gerraty 
4010957b409SSimon J. Gerraty 	/**
4020957b409SSimon J. Gerraty 	 * \brief Receive some bytes for the current certificate.
4030957b409SSimon J. Gerraty 	 *
4040957b409SSimon J. Gerraty 	 * This function may be called several times in succession for
4050957b409SSimon J. Gerraty 	 * a given certificate. The caller guarantees that for each
4060957b409SSimon J. Gerraty 	 * call, `len` is not zero, and the sum of all chunk lengths
4070957b409SSimon J. Gerraty 	 * for a certificate matches the total certificate length which
4080957b409SSimon J. Gerraty 	 * was provided in the previous `start_cert()` call.
4090957b409SSimon J. Gerraty 	 *
4100957b409SSimon J. Gerraty 	 * If the new certificate is empty (no byte at all) then this
4110957b409SSimon J. Gerraty 	 * function won't be called at all.
4120957b409SSimon J. Gerraty 	 *
4130957b409SSimon J. Gerraty 	 * \param ctx   validation context.
4140957b409SSimon J. Gerraty 	 * \param buf   certificate data chunk.
4150957b409SSimon J. Gerraty 	 * \param len   certificate data chunk length (in bytes).
4160957b409SSimon J. Gerraty 	 */
4170957b409SSimon J. Gerraty 	void (*append)(const br_x509_class **ctx,
4180957b409SSimon J. Gerraty 		const unsigned char *buf, size_t len);
4190957b409SSimon J. Gerraty 
4200957b409SSimon J. Gerraty 	/**
4210957b409SSimon J. Gerraty 	 * \brief Finish the current certificate.
4220957b409SSimon J. Gerraty 	 *
4230957b409SSimon J. Gerraty 	 * This function is called when the end of the current certificate
4240957b409SSimon J. Gerraty 	 * is reached.
4250957b409SSimon J. Gerraty 	 *
4260957b409SSimon J. Gerraty 	 * \param ctx   validation context.
4270957b409SSimon J. Gerraty 	 */
4280957b409SSimon J. Gerraty 	void (*end_cert)(const br_x509_class **ctx);
4290957b409SSimon J. Gerraty 
4300957b409SSimon J. Gerraty 	/**
4310957b409SSimon J. Gerraty 	 * \brief Finish the chain.
4320957b409SSimon J. Gerraty 	 *
4330957b409SSimon J. Gerraty 	 * This function is called at the end of the chain. It shall
4340957b409SSimon J. Gerraty 	 * return either 0 if the validation was successful, or a
4350957b409SSimon J. Gerraty 	 * non-zero error code. The `BR_ERR_X509_*` constants are
4360957b409SSimon J. Gerraty 	 * error codes, though other values may be possible.
4370957b409SSimon J. Gerraty 	 *
4380957b409SSimon J. Gerraty 	 * \param ctx   validation context.
4390957b409SSimon J. Gerraty 	 * \return  0 on success, or a non-zero error code.
4400957b409SSimon J. Gerraty 	 */
4410957b409SSimon J. Gerraty 	unsigned (*end_chain)(const br_x509_class **ctx);
4420957b409SSimon J. Gerraty 
4430957b409SSimon J. Gerraty 	/**
4440957b409SSimon J. Gerraty 	 * \brief Get the resulting end-entity public key.
4450957b409SSimon J. Gerraty 	 *
4460957b409SSimon J. Gerraty 	 * The decoded public key is returned. The returned pointer
4470957b409SSimon J. Gerraty 	 * may be valid only as long as the context structure is
4480957b409SSimon J. Gerraty 	 * unmodified, i.e. it may cease to be valid if the context
4490957b409SSimon J. Gerraty 	 * is released or reused.
4500957b409SSimon J. Gerraty 	 *
4510957b409SSimon J. Gerraty 	 * This function _may_ return `NULL` if the validation failed.
4520957b409SSimon J. Gerraty 	 * However, returning a public key does not mean that the
4530957b409SSimon J. Gerraty 	 * validation was wholly successful; some engines may return
4540957b409SSimon J. Gerraty 	 * a decoded public key even if the chain did not end on a
4550957b409SSimon J. Gerraty 	 * trusted anchor.
4560957b409SSimon J. Gerraty 	 *
4570957b409SSimon J. Gerraty 	 * If validation succeeded and `usage` is not `NULL`, then
4580957b409SSimon J. Gerraty 	 * `*usage` is filled with a combination of `BR_KEYTYPE_SIGN`
4590957b409SSimon J. Gerraty 	 * and/or `BR_KEYTYPE_KEYX` that specifies the validated key
4600957b409SSimon J. Gerraty 	 * usage types. It is the caller's responsibility to check
4610957b409SSimon J. Gerraty 	 * that value against the intended use of the public key.
4620957b409SSimon J. Gerraty 	 *
4630957b409SSimon J. Gerraty 	 * \param ctx   validation context.
4640957b409SSimon J. Gerraty 	 * \return  the end-entity public key, or `NULL`.
4650957b409SSimon J. Gerraty 	 */
4660957b409SSimon J. Gerraty 	const br_x509_pkey *(*get_pkey)(
4670957b409SSimon J. Gerraty 		const br_x509_class *const *ctx, unsigned *usages);
4680957b409SSimon J. Gerraty };
4690957b409SSimon J. Gerraty 
4700957b409SSimon J. Gerraty /**
4710957b409SSimon J. Gerraty  * \brief The "known key" X.509 engine structure.
4720957b409SSimon J. Gerraty  *
4730957b409SSimon J. Gerraty  * The structure contents are opaque (they shall not be accessed directly),
4740957b409SSimon J. Gerraty  * except for the first field (the vtable).
4750957b409SSimon J. Gerraty  *
4760957b409SSimon J. Gerraty  * The "known key" engine returns an externally configured public key,
4770957b409SSimon J. Gerraty  * and totally ignores the certificate contents.
4780957b409SSimon J. Gerraty  */
4790957b409SSimon J. Gerraty typedef struct {
4800957b409SSimon J. Gerraty 	/** \brief Reference to the context vtable. */
4810957b409SSimon J. Gerraty 	const br_x509_class *vtable;
4820957b409SSimon J. Gerraty #ifndef BR_DOXYGEN_IGNORE
4830957b409SSimon J. Gerraty 	br_x509_pkey pkey;
4840957b409SSimon J. Gerraty 	unsigned usages;
4850957b409SSimon J. Gerraty #endif
4860957b409SSimon J. Gerraty } br_x509_knownkey_context;
4870957b409SSimon J. Gerraty 
4880957b409SSimon J. Gerraty /**
4890957b409SSimon J. Gerraty  * \brief Class instance for the "known key" X.509 engine.
4900957b409SSimon J. Gerraty  */
4910957b409SSimon J. Gerraty extern const br_x509_class br_x509_knownkey_vtable;
4920957b409SSimon J. Gerraty 
4930957b409SSimon J. Gerraty /**
4940957b409SSimon J. Gerraty  * \brief Initialize a "known key" X.509 engine with a known RSA public key.
4950957b409SSimon J. Gerraty  *
4960957b409SSimon J. Gerraty  * The `usages` parameter indicates the allowed key usages for that key
4970957b409SSimon J. Gerraty  * (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`).
4980957b409SSimon J. Gerraty  *
4990957b409SSimon J. Gerraty  * The provided pointers are linked in, not copied, so they must remain
5000957b409SSimon J. Gerraty  * valid while the public key may be in usage.
5010957b409SSimon J. Gerraty  *
5020957b409SSimon J. Gerraty  * \param ctx      context to initialise.
5030957b409SSimon J. Gerraty  * \param pk       known public key.
5040957b409SSimon J. Gerraty  * \param usages   allowed key usages.
5050957b409SSimon J. Gerraty  */
5060957b409SSimon J. Gerraty void br_x509_knownkey_init_rsa(br_x509_knownkey_context *ctx,
5070957b409SSimon J. Gerraty 	const br_rsa_public_key *pk, unsigned usages);
5080957b409SSimon J. Gerraty 
5090957b409SSimon J. Gerraty /**
5100957b409SSimon J. Gerraty  * \brief Initialize a "known key" X.509 engine with a known EC public key.
5110957b409SSimon J. Gerraty  *
5120957b409SSimon J. Gerraty  * The `usages` parameter indicates the allowed key usages for that key
5130957b409SSimon J. Gerraty  * (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`).
5140957b409SSimon J. Gerraty  *
5150957b409SSimon J. Gerraty  * The provided pointers are linked in, not copied, so they must remain
5160957b409SSimon J. Gerraty  * valid while the public key may be in usage.
5170957b409SSimon J. Gerraty  *
5180957b409SSimon J. Gerraty  * \param ctx      context to initialise.
5190957b409SSimon J. Gerraty  * \param pk       known public key.
5200957b409SSimon J. Gerraty  * \param usages   allowed key usages.
5210957b409SSimon J. Gerraty  */
5220957b409SSimon J. Gerraty void br_x509_knownkey_init_ec(br_x509_knownkey_context *ctx,
5230957b409SSimon J. Gerraty 	const br_ec_public_key *pk, unsigned usages);
5240957b409SSimon J. Gerraty 
5250957b409SSimon J. Gerraty #ifndef BR_DOXYGEN_IGNORE
5260957b409SSimon J. Gerraty /*
5270957b409SSimon J. Gerraty  * The minimal X.509 engine has some state buffers which must be large
5280957b409SSimon J. Gerraty  * enough to simultaneously accommodate:
5290957b409SSimon J. Gerraty  * -- the public key extracted from the current certificate;
5300957b409SSimon J. Gerraty  * -- the signature on the current certificate or on the previous
5310957b409SSimon J. Gerraty  *    certificate;
5320957b409SSimon J. Gerraty  * -- the public key extracted from the EE certificate.
5330957b409SSimon J. Gerraty  *
5340957b409SSimon J. Gerraty  * We store public key elements in their raw unsigned big-endian
5350957b409SSimon J. Gerraty  * encoding. We want to support up to RSA-4096 with a short (up to 64
5360957b409SSimon J. Gerraty  * bits) public exponent, thus a buffer for a public key must have
5370957b409SSimon J. Gerraty  * length at least 520 bytes. Similarly, a RSA-4096 signature has length
5380957b409SSimon J. Gerraty  * 512 bytes.
5390957b409SSimon J. Gerraty  *
5400957b409SSimon J. Gerraty  * Though RSA public exponents can formally be as large as the modulus
5410957b409SSimon J. Gerraty  * (mathematically, even larger exponents would work, but PKCS#1 forbids
5420957b409SSimon J. Gerraty  * them), exponents that do not fit on 32 bits are extremely rare,
5430957b409SSimon J. Gerraty  * notably because some widespread implementations (e.g. Microsoft's
5440957b409SSimon J. Gerraty  * CryptoAPI) don't support them. Moreover, large public exponent do not
5450957b409SSimon J. Gerraty  * seem to imply any tangible security benefit, and they increase the
5460957b409SSimon J. Gerraty  * cost of public key operations. The X.509 "minimal" engine will tolerate
5470957b409SSimon J. Gerraty  * public exponents of arbitrary size as long as the modulus and the
5480957b409SSimon J. Gerraty  * exponent can fit together in the dedicated buffer.
5490957b409SSimon J. Gerraty  *
5500957b409SSimon J. Gerraty  * EC public keys are shorter than RSA public keys; even with curve
5510957b409SSimon J. Gerraty  * NIST P-521 (the largest curve we care to support), a public key is
5520957b409SSimon J. Gerraty  * encoded over 133 bytes only.
5530957b409SSimon J. Gerraty  */
5540957b409SSimon J. Gerraty #define BR_X509_BUFSIZE_KEY   520
5550957b409SSimon J. Gerraty #define BR_X509_BUFSIZE_SIG   512
5560957b409SSimon J. Gerraty #endif
5570957b409SSimon J. Gerraty 
5580957b409SSimon J. Gerraty /**
5590957b409SSimon J. Gerraty  * \brief Type for receiving a name element.
5600957b409SSimon J. Gerraty  *
5610957b409SSimon J. Gerraty  * An array of such structures can be provided to the X.509 decoding
5620957b409SSimon J. Gerraty  * engines. If the specified elements are found in the certificate
5630957b409SSimon J. Gerraty  * subject DN or the SAN extension, then the name contents are copied
5640957b409SSimon J. Gerraty  * as zero-terminated strings into the buffer.
5650957b409SSimon J. Gerraty  *
5660957b409SSimon J. Gerraty  * The decoder converts TeletexString and BMPString to UTF8String, and
5670957b409SSimon J. Gerraty  * ensures that the resulting string is zero-terminated. If the string
5680957b409SSimon J. Gerraty  * does not fit in the provided buffer, then the copy is aborted and an
5690957b409SSimon J. Gerraty  * error is reported.
5700957b409SSimon J. Gerraty  */
5710957b409SSimon J. Gerraty typedef struct {
5720957b409SSimon J. Gerraty 	/**
5730957b409SSimon J. Gerraty 	 * \brief Element OID.
5740957b409SSimon J. Gerraty 	 *
5750957b409SSimon J. Gerraty 	 * For X.500 name elements (to be extracted from the subject DN),
5760957b409SSimon J. Gerraty 	 * this is the encoded OID for the requested name element; the
5770957b409SSimon J. Gerraty 	 * first byte shall contain the length of the DER-encoded OID
5780957b409SSimon J. Gerraty 	 * value, followed by the OID value (for instance, OID 2.5.4.3,
5790957b409SSimon J. Gerraty 	 * for id-at-commonName, will be `03 55 04 03`). This is
5800957b409SSimon J. Gerraty 	 * equivalent to full DER encoding with the length but without
5810957b409SSimon J. Gerraty 	 * the tag.
5820957b409SSimon J. Gerraty 	 *
5830957b409SSimon J. Gerraty 	 * For SAN name elements, the first byte (`oid[0]`) has value 0,
5840957b409SSimon J. Gerraty 	 * followed by another byte that matches the expected GeneralName
5850957b409SSimon J. Gerraty 	 * tag. Allowed second byte values are then:
5860957b409SSimon J. Gerraty 	 *
5870957b409SSimon J. Gerraty 	 *   - 1: `rfc822Name`
5880957b409SSimon J. Gerraty 	 *
5890957b409SSimon J. Gerraty 	 *   - 2: `dNSName`
5900957b409SSimon J. Gerraty 	 *
5910957b409SSimon J. Gerraty 	 *   - 6: `uniformResourceIdentifier`
5920957b409SSimon J. Gerraty 	 *
5930957b409SSimon J. Gerraty 	 *   - 0: `otherName`
5940957b409SSimon J. Gerraty 	 *
5950957b409SSimon J. Gerraty 	 * If first and second byte are 0, then this is a SAN element of
5960957b409SSimon J. Gerraty 	 * type `otherName`; the `oid[]` array should then contain, right
5970957b409SSimon J. Gerraty 	 * after the two bytes of value 0, an encoded OID (with the same
5980957b409SSimon J. Gerraty 	 * conventions as for X.500 name elements). If a match is found
5990957b409SSimon J. Gerraty 	 * for that OID, then the corresponding name element will be
6000957b409SSimon J. Gerraty 	 * extracted, as long as it is a supported string type.
6010957b409SSimon J. Gerraty 	 */
6020957b409SSimon J. Gerraty 	const unsigned char *oid;
6030957b409SSimon J. Gerraty 
6040957b409SSimon J. Gerraty 	/**
6050957b409SSimon J. Gerraty 	 * \brief Destination buffer.
6060957b409SSimon J. Gerraty 	 */
6070957b409SSimon J. Gerraty 	char *buf;
6080957b409SSimon J. Gerraty 
6090957b409SSimon J. Gerraty 	/**
6100957b409SSimon J. Gerraty 	 * \brief Length (in bytes) of the destination buffer.
6110957b409SSimon J. Gerraty 	 *
6120957b409SSimon J. Gerraty 	 * The buffer MUST NOT be smaller than 1 byte.
6130957b409SSimon J. Gerraty 	 */
6140957b409SSimon J. Gerraty 	size_t len;
6150957b409SSimon J. Gerraty 
6160957b409SSimon J. Gerraty 	/**
6170957b409SSimon J. Gerraty 	 * \brief Decoding status.
6180957b409SSimon J. Gerraty 	 *
6190957b409SSimon J. Gerraty 	 * Status is 0 if the name element was not found, 1 if it was
6200957b409SSimon J. Gerraty 	 * found and decoded, or -1 on error. Error conditions include
6210957b409SSimon J. Gerraty 	 * an unrecognised encoding, an invalid encoding, or a string
6220957b409SSimon J. Gerraty 	 * too large for the destination buffer.
6230957b409SSimon J. Gerraty 	 */
6240957b409SSimon J. Gerraty 	int status;
6250957b409SSimon J. Gerraty 
6260957b409SSimon J. Gerraty } br_name_element;
6270957b409SSimon J. Gerraty 
6280957b409SSimon J. Gerraty /**
629*cc9e6590SSimon J. Gerraty  * \brief Callback for validity date checks.
630*cc9e6590SSimon J. Gerraty  *
631*cc9e6590SSimon J. Gerraty  * The function receives as parameter an arbitrary user-provided context,
632*cc9e6590SSimon J. Gerraty  * and the notBefore and notAfter dates specified in an X.509 certificate,
633*cc9e6590SSimon J. Gerraty  * both expressed as a number of days and a number of seconds:
634*cc9e6590SSimon J. Gerraty  *
635*cc9e6590SSimon J. Gerraty  *   - Days are counted in a proleptic Gregorian calendar since
636*cc9e6590SSimon J. Gerraty  *     January 1st, 0 AD. Year "0 AD" is the one that preceded "1 AD";
637*cc9e6590SSimon J. Gerraty  *     it is also traditionally known as "1 BC".
638*cc9e6590SSimon J. Gerraty  *
639*cc9e6590SSimon J. Gerraty  *   - Seconds are counted since midnight, from 0 to 86400 (a count of
640*cc9e6590SSimon J. Gerraty  *     86400 is possible only if a leap second happened).
641*cc9e6590SSimon J. Gerraty  *
642*cc9e6590SSimon J. Gerraty  * Each date and time is understood in the UTC time zone. The "Unix
643*cc9e6590SSimon J. Gerraty  * Epoch" (January 1st, 1970, 00:00 UTC) corresponds to days=719528 and
644*cc9e6590SSimon J. Gerraty  * seconds=0; the "Windows Epoch" (January 1st, 1601, 00:00 UTC) is
645*cc9e6590SSimon J. Gerraty  * days=584754, seconds=0.
646*cc9e6590SSimon J. Gerraty  *
647*cc9e6590SSimon J. Gerraty  * This function must return -1 if the current date is strictly before
648*cc9e6590SSimon J. Gerraty  * the "notBefore" time, or +1 if the current date is strictly after the
649*cc9e6590SSimon J. Gerraty  * "notAfter" time. If neither condition holds, then the function returns
650*cc9e6590SSimon J. Gerraty  * 0, which means that the current date falls within the validity range of
651*cc9e6590SSimon J. Gerraty  * the certificate. If the function returns a value distinct from -1, 0
652*cc9e6590SSimon J. Gerraty  * and +1, then this is interpreted as an unavailability of the current
653*cc9e6590SSimon J. Gerraty  * time, which normally ends the validation process with a
654*cc9e6590SSimon J. Gerraty  * `BR_ERR_X509_TIME_UNKNOWN` error.
655*cc9e6590SSimon J. Gerraty  *
656*cc9e6590SSimon J. Gerraty  * During path validation, this callback will be invoked for each
657*cc9e6590SSimon J. Gerraty  * considered X.509 certificate. Validation fails if any of the calls
658*cc9e6590SSimon J. Gerraty  * returns a non-zero value.
659*cc9e6590SSimon J. Gerraty  *
660*cc9e6590SSimon J. Gerraty  * The context value is an abritrary pointer set by the caller when
661*cc9e6590SSimon J. Gerraty  * configuring this callback.
662*cc9e6590SSimon J. Gerraty  *
663*cc9e6590SSimon J. Gerraty  * \param tctx                 context pointer.
664*cc9e6590SSimon J. Gerraty  * \param not_before_days      notBefore date (days since Jan 1st, 0 AD).
665*cc9e6590SSimon J. Gerraty  * \param not_before_seconds   notBefore time (seconds, at most 86400).
666*cc9e6590SSimon J. Gerraty  * \param not_after_days       notAfter date (days since Jan 1st, 0 AD).
667*cc9e6590SSimon J. Gerraty  * \param not_after_seconds    notAfter time (seconds, at most 86400).
668*cc9e6590SSimon J. Gerraty  * \return  -1, 0 or +1.
669*cc9e6590SSimon J. Gerraty  */
670*cc9e6590SSimon J. Gerraty typedef int (*br_x509_time_check)(void *tctx,
671*cc9e6590SSimon J. Gerraty 	uint32_t not_before_days, uint32_t not_before_seconds,
672*cc9e6590SSimon J. Gerraty 	uint32_t not_after_days, uint32_t not_after_seconds);
673*cc9e6590SSimon J. Gerraty 
674*cc9e6590SSimon J. Gerraty /**
6750957b409SSimon J. Gerraty  * \brief The "minimal" X.509 engine structure.
6760957b409SSimon J. Gerraty  *
6770957b409SSimon J. Gerraty  * The structure contents are opaque (they shall not be accessed directly),
6780957b409SSimon J. Gerraty  * except for the first field (the vtable).
6790957b409SSimon J. Gerraty  *
6800957b409SSimon J. Gerraty  * The "minimal" engine performs a rudimentary but serviceable X.509 path
6810957b409SSimon J. Gerraty  * validation.
6820957b409SSimon J. Gerraty  */
6830957b409SSimon J. Gerraty typedef struct {
6840957b409SSimon J. Gerraty 	const br_x509_class *vtable;
6850957b409SSimon J. Gerraty 
6860957b409SSimon J. Gerraty #ifndef BR_DOXYGEN_IGNORE
6870957b409SSimon J. Gerraty 	/* Structure for returning the EE public key. */
6880957b409SSimon J. Gerraty 	br_x509_pkey pkey;
6890957b409SSimon J. Gerraty 
6900957b409SSimon J. Gerraty 	/* CPU for the T0 virtual machine. */
6910957b409SSimon J. Gerraty 	struct {
6920957b409SSimon J. Gerraty 		uint32_t *dp;
6930957b409SSimon J. Gerraty 		uint32_t *rp;
6940957b409SSimon J. Gerraty 		const unsigned char *ip;
6950957b409SSimon J. Gerraty 	} cpu;
696*cc9e6590SSimon J. Gerraty 	uint32_t dp_stack[31];
697*cc9e6590SSimon J. Gerraty 	uint32_t rp_stack[31];
6980957b409SSimon J. Gerraty 	int err;
6990957b409SSimon J. Gerraty 
7000957b409SSimon J. Gerraty 	/* Server name to match with the SAN / CN of the EE certificate. */
7010957b409SSimon J. Gerraty 	const char *server_name;
7020957b409SSimon J. Gerraty 
7030957b409SSimon J. Gerraty 	/* Validated key usages. */
7040957b409SSimon J. Gerraty 	unsigned char key_usages;
7050957b409SSimon J. Gerraty 
7060957b409SSimon J. Gerraty 	/* Explicitly set date and time. */
7070957b409SSimon J. Gerraty 	uint32_t days, seconds;
7080957b409SSimon J. Gerraty 
7090957b409SSimon J. Gerraty 	/* Current certificate length (in bytes). Set to 0 when the
7100957b409SSimon J. Gerraty 	   certificate has been fully processed. */
7110957b409SSimon J. Gerraty 	uint32_t cert_length;
7120957b409SSimon J. Gerraty 
7130957b409SSimon J. Gerraty 	/* Number of certificates processed so far in the current chain.
7140957b409SSimon J. Gerraty 	   It is incremented at the end of the processing of a certificate,
7150957b409SSimon J. Gerraty 	   so it is 0 for the EE. */
7160957b409SSimon J. Gerraty 	uint32_t num_certs;
7170957b409SSimon J. Gerraty 
7180957b409SSimon J. Gerraty 	/* Certificate data chunk. */
7190957b409SSimon J. Gerraty 	const unsigned char *hbuf;
7200957b409SSimon J. Gerraty 	size_t hlen;
7210957b409SSimon J. Gerraty 
7220957b409SSimon J. Gerraty 	/* The pad serves as destination for various operations. */
7230957b409SSimon J. Gerraty 	unsigned char pad[256];
7240957b409SSimon J. Gerraty 
7250957b409SSimon J. Gerraty 	/* Buffer for EE public key data. */
7260957b409SSimon J. Gerraty 	unsigned char ee_pkey_data[BR_X509_BUFSIZE_KEY];
7270957b409SSimon J. Gerraty 
7280957b409SSimon J. Gerraty 	/* Buffer for currently decoded public key. */
7290957b409SSimon J. Gerraty 	unsigned char pkey_data[BR_X509_BUFSIZE_KEY];
7300957b409SSimon J. Gerraty 
7310957b409SSimon J. Gerraty 	/* Signature type: signer key type, offset to the hash
7320957b409SSimon J. Gerraty 	   function OID (in the T0 data block) and hash function
7330957b409SSimon J. Gerraty 	   output length (TBS hash length). */
7340957b409SSimon J. Gerraty 	unsigned char cert_signer_key_type;
7350957b409SSimon J. Gerraty 	uint16_t cert_sig_hash_oid;
7360957b409SSimon J. Gerraty 	unsigned char cert_sig_hash_len;
7370957b409SSimon J. Gerraty 
7380957b409SSimon J. Gerraty 	/* Current/last certificate signature. */
7390957b409SSimon J. Gerraty 	unsigned char cert_sig[BR_X509_BUFSIZE_SIG];
7400957b409SSimon J. Gerraty 	uint16_t cert_sig_len;
7410957b409SSimon J. Gerraty 
7420957b409SSimon J. Gerraty 	/* Minimum RSA key length (difference in bytes from 128). */
7430957b409SSimon J. Gerraty 	int16_t min_rsa_size;
7440957b409SSimon J. Gerraty 
7450957b409SSimon J. Gerraty 	/* Configured trust anchors. */
7460957b409SSimon J. Gerraty 	const br_x509_trust_anchor *trust_anchors;
7470957b409SSimon J. Gerraty 	size_t trust_anchors_num;
7480957b409SSimon J. Gerraty 
7490957b409SSimon J. Gerraty 	/*
7500957b409SSimon J. Gerraty 	 * Multi-hasher for the TBS.
7510957b409SSimon J. Gerraty 	 */
7520957b409SSimon J. Gerraty 	unsigned char do_mhash;
7530957b409SSimon J. Gerraty 	br_multihash_context mhash;
7540957b409SSimon J. Gerraty 	unsigned char tbs_hash[64];
7550957b409SSimon J. Gerraty 
7560957b409SSimon J. Gerraty 	/*
7570957b409SSimon J. Gerraty 	 * Simple hasher for the subject/issuer DN.
7580957b409SSimon J. Gerraty 	 */
7590957b409SSimon J. Gerraty 	unsigned char do_dn_hash;
7600957b409SSimon J. Gerraty 	const br_hash_class *dn_hash_impl;
7610957b409SSimon J. Gerraty 	br_hash_compat_context dn_hash;
7620957b409SSimon J. Gerraty 	unsigned char current_dn_hash[64];
7630957b409SSimon J. Gerraty 	unsigned char next_dn_hash[64];
7640957b409SSimon J. Gerraty 	unsigned char saved_dn_hash[64];
7650957b409SSimon J. Gerraty 
7660957b409SSimon J. Gerraty 	/*
7670957b409SSimon J. Gerraty 	 * Name elements to gather.
7680957b409SSimon J. Gerraty 	 */
7690957b409SSimon J. Gerraty 	br_name_element *name_elts;
7700957b409SSimon J. Gerraty 	size_t num_name_elts;
7710957b409SSimon J. Gerraty 
7720957b409SSimon J. Gerraty 	/*
773*cc9e6590SSimon J. Gerraty 	 * Callback function (and context) to get the current date.
774*cc9e6590SSimon J. Gerraty 	 */
775*cc9e6590SSimon J. Gerraty 	void *itime_ctx;
776*cc9e6590SSimon J. Gerraty 	br_x509_time_check itime;
777*cc9e6590SSimon J. Gerraty 
778*cc9e6590SSimon J. Gerraty 	/*
7790957b409SSimon J. Gerraty 	 * Public key cryptography implementations (signature verification).
7800957b409SSimon J. Gerraty 	 */
7810957b409SSimon J. Gerraty 	br_rsa_pkcs1_vrfy irsa;
7820957b409SSimon J. Gerraty 	br_ecdsa_vrfy iecdsa;
7830957b409SSimon J. Gerraty 	const br_ec_impl *iec;
7840957b409SSimon J. Gerraty #endif
7850957b409SSimon J. Gerraty 
7860957b409SSimon J. Gerraty } br_x509_minimal_context;
7870957b409SSimon J. Gerraty 
7880957b409SSimon J. Gerraty /**
7890957b409SSimon J. Gerraty  * \brief Class instance for the "minimal" X.509 engine.
7900957b409SSimon J. Gerraty  */
7910957b409SSimon J. Gerraty extern const br_x509_class br_x509_minimal_vtable;
7920957b409SSimon J. Gerraty 
7930957b409SSimon J. Gerraty /**
7940957b409SSimon J. Gerraty  * \brief Initialise a "minimal" X.509 engine.
7950957b409SSimon J. Gerraty  *
7960957b409SSimon J. Gerraty  * The `dn_hash_impl` parameter shall be a hash function internally used
7970957b409SSimon J. Gerraty  * to match X.500 names (subject/issuer DN, and anchor names). Any standard
7980957b409SSimon J. Gerraty  * hash function may be used, but a collision-resistant hash function is
7990957b409SSimon J. Gerraty  * advised.
8000957b409SSimon J. Gerraty  *
8010957b409SSimon J. Gerraty  * After initialization, some implementations for signature verification
8020957b409SSimon J. Gerraty  * (hash functions and signature algorithms) MUST be added.
8030957b409SSimon J. Gerraty  *
8040957b409SSimon J. Gerraty  * \param ctx                 context to initialise.
8050957b409SSimon J. Gerraty  * \param dn_hash_impl        hash function for DN comparisons.
8060957b409SSimon J. Gerraty  * \param trust_anchors       trust anchors.
8070957b409SSimon J. Gerraty  * \param trust_anchors_num   number of trust anchors.
8080957b409SSimon J. Gerraty  */
8090957b409SSimon J. Gerraty void br_x509_minimal_init(br_x509_minimal_context *ctx,
8100957b409SSimon J. Gerraty 	const br_hash_class *dn_hash_impl,
8110957b409SSimon J. Gerraty 	const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num);
8120957b409SSimon J. Gerraty 
8130957b409SSimon J. Gerraty /**
8140957b409SSimon J. Gerraty  * \brief Set a supported hash function in an X.509 "minimal" engine.
8150957b409SSimon J. Gerraty  *
8160957b409SSimon J. Gerraty  * Hash functions are used with signature verification algorithms.
8170957b409SSimon J. Gerraty  * Once initialised (with `br_x509_minimal_init()`), the context must
8180957b409SSimon J. Gerraty  * be configured with the hash functions it shall support for that
8190957b409SSimon J. Gerraty  * purpose. The hash function identifier MUST be one of the standard
8200957b409SSimon J. Gerraty  * hash function identifiers (1 to 6, for MD5, SHA-1, SHA-224, SHA-256,
8210957b409SSimon J. Gerraty  * SHA-384 and SHA-512).
8220957b409SSimon J. Gerraty  *
8230957b409SSimon J. Gerraty  * If `impl` is `NULL`, this _removes_ support for the designated
8240957b409SSimon J. Gerraty  * hash function.
8250957b409SSimon J. Gerraty  *
8260957b409SSimon J. Gerraty  * \param ctx    validation context.
8270957b409SSimon J. Gerraty  * \param id     hash function identifier (from 1 to 6).
8280957b409SSimon J. Gerraty  * \param impl   hash function implementation (or `NULL`).
8290957b409SSimon J. Gerraty  */
8300957b409SSimon J. Gerraty static inline void
br_x509_minimal_set_hash(br_x509_minimal_context * ctx,int id,const br_hash_class * impl)8310957b409SSimon J. Gerraty br_x509_minimal_set_hash(br_x509_minimal_context *ctx,
8320957b409SSimon J. Gerraty 	int id, const br_hash_class *impl)
8330957b409SSimon J. Gerraty {
8340957b409SSimon J. Gerraty 	br_multihash_setimpl(&ctx->mhash, id, impl);
8350957b409SSimon J. Gerraty }
8360957b409SSimon J. Gerraty 
8370957b409SSimon J. Gerraty /**
8380957b409SSimon J. Gerraty  * \brief Set a RSA signature verification implementation in the X.509
8390957b409SSimon J. Gerraty  * "minimal" engine.
8400957b409SSimon J. Gerraty  *
8410957b409SSimon J. Gerraty  * Once initialised (with `br_x509_minimal_init()`), the context must
8420957b409SSimon J. Gerraty  * be configured with the signature verification implementations that
8430957b409SSimon J. Gerraty  * it is supposed to support. If `irsa` is `0`, then the RSA support
8440957b409SSimon J. Gerraty  * is disabled.
8450957b409SSimon J. Gerraty  *
8460957b409SSimon J. Gerraty  * \param ctx    validation context.
8470957b409SSimon J. Gerraty  * \param irsa   RSA signature verification implementation (or `0`).
8480957b409SSimon J. Gerraty  */
8490957b409SSimon J. Gerraty static inline void
br_x509_minimal_set_rsa(br_x509_minimal_context * ctx,br_rsa_pkcs1_vrfy irsa)8500957b409SSimon J. Gerraty br_x509_minimal_set_rsa(br_x509_minimal_context *ctx,
8510957b409SSimon J. Gerraty 	br_rsa_pkcs1_vrfy irsa)
8520957b409SSimon J. Gerraty {
8530957b409SSimon J. Gerraty 	ctx->irsa = irsa;
8540957b409SSimon J. Gerraty }
8550957b409SSimon J. Gerraty 
8560957b409SSimon J. Gerraty /**
8570957b409SSimon J. Gerraty  * \brief Set a ECDSA signature verification implementation in the X.509
8580957b409SSimon J. Gerraty  * "minimal" engine.
8590957b409SSimon J. Gerraty  *
8600957b409SSimon J. Gerraty  * Once initialised (with `br_x509_minimal_init()`), the context must
8610957b409SSimon J. Gerraty  * be configured with the signature verification implementations that
8620957b409SSimon J. Gerraty  * it is supposed to support.
8630957b409SSimon J. Gerraty  *
8640957b409SSimon J. Gerraty  * If `iecdsa` is `0`, then this call disables ECDSA support; in that
8650957b409SSimon J. Gerraty  * case, `iec` may be `NULL`. Otherwise, `iecdsa` MUST point to a function
8660957b409SSimon J. Gerraty  * that verifies ECDSA signatures with format "asn1", and it will use
8670957b409SSimon J. Gerraty  * `iec` as underlying elliptic curve support.
8680957b409SSimon J. Gerraty  *
8690957b409SSimon J. Gerraty  * \param ctx      validation context.
8700957b409SSimon J. Gerraty  * \param iec      elliptic curve implementation (or `NULL`).
8710957b409SSimon J. Gerraty  * \param iecdsa   ECDSA implementation (or `0`).
8720957b409SSimon J. Gerraty  */
8730957b409SSimon J. Gerraty static inline void
br_x509_minimal_set_ecdsa(br_x509_minimal_context * ctx,const br_ec_impl * iec,br_ecdsa_vrfy iecdsa)8740957b409SSimon J. Gerraty br_x509_minimal_set_ecdsa(br_x509_minimal_context *ctx,
8750957b409SSimon J. Gerraty 	const br_ec_impl *iec, br_ecdsa_vrfy iecdsa)
8760957b409SSimon J. Gerraty {
8770957b409SSimon J. Gerraty 	ctx->iecdsa = iecdsa;
8780957b409SSimon J. Gerraty 	ctx->iec = iec;
8790957b409SSimon J. Gerraty }
8800957b409SSimon J. Gerraty 
8810957b409SSimon J. Gerraty /**
8820957b409SSimon J. Gerraty  * \brief Initialise a "minimal" X.509 engine with default algorithms.
8830957b409SSimon J. Gerraty  *
8840957b409SSimon J. Gerraty  * This function performs the same job as `br_x509_minimal_init()`, but
8850957b409SSimon J. Gerraty  * also sets implementations for RSA, ECDSA, and the standard hash
8860957b409SSimon J. Gerraty  * functions.
8870957b409SSimon J. Gerraty  *
8880957b409SSimon J. Gerraty  * \param ctx                 context to initialise.
8890957b409SSimon J. Gerraty  * \param trust_anchors       trust anchors.
8900957b409SSimon J. Gerraty  * \param trust_anchors_num   number of trust anchors.
8910957b409SSimon J. Gerraty  */
8920957b409SSimon J. Gerraty void br_x509_minimal_init_full(br_x509_minimal_context *ctx,
8930957b409SSimon J. Gerraty 	const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num);
8940957b409SSimon J. Gerraty 
8950957b409SSimon J. Gerraty /**
8960957b409SSimon J. Gerraty  * \brief Set the validation time for the X.509 "minimal" engine.
8970957b409SSimon J. Gerraty  *
8980957b409SSimon J. Gerraty  * The validation time is set as two 32-bit integers, for days and
8990957b409SSimon J. Gerraty  * seconds since a fixed epoch:
9000957b409SSimon J. Gerraty  *
9010957b409SSimon J. Gerraty  *   - Days are counted in a proleptic Gregorian calendar since
9020957b409SSimon J. Gerraty  *     January 1st, 0 AD. Year "0 AD" is the one that preceded "1 AD";
9030957b409SSimon J. Gerraty  *     it is also traditionally known as "1 BC".
9040957b409SSimon J. Gerraty  *
9050957b409SSimon J. Gerraty  *   - Seconds are counted since midnight, from 0 to 86400 (a count of
9060957b409SSimon J. Gerraty  *     86400 is possible only if a leap second happened).
9070957b409SSimon J. Gerraty  *
908*cc9e6590SSimon J. Gerraty  * The validation date and time is understood in the UTC time zone. The
909*cc9e6590SSimon J. Gerraty  * "Unix Epoch" (January 1st, 1970, 00:00 UTC) corresponds to days=719528
910*cc9e6590SSimon J. Gerraty  * and seconds=0; the "Windows Epoch" (January 1st, 1601, 00:00 UTC) is
911*cc9e6590SSimon J. Gerraty  * days=584754, seconds=0.
9120957b409SSimon J. Gerraty  *
9130957b409SSimon J. Gerraty  * If the validation date and time are not explicitly set, but BearSSL
9140957b409SSimon J. Gerraty  * was compiled with support for the system clock on the underlying
9150957b409SSimon J. Gerraty  * platform, then the current time will automatically be used. Otherwise,
9160957b409SSimon J. Gerraty  * not setting the validation date and time implies a validation
9170957b409SSimon J. Gerraty  * failure (except in case of direct trust of the EE key).
9180957b409SSimon J. Gerraty  *
9190957b409SSimon J. Gerraty  * \param ctx       validation context.
9200957b409SSimon J. Gerraty  * \param days      days since January 1st, 0 AD (Gregorian calendar).
9210957b409SSimon J. Gerraty  * \param seconds   seconds since midnight (0 to 86400).
9220957b409SSimon J. Gerraty  */
9230957b409SSimon J. Gerraty static inline void
br_x509_minimal_set_time(br_x509_minimal_context * ctx,uint32_t days,uint32_t seconds)9240957b409SSimon J. Gerraty br_x509_minimal_set_time(br_x509_minimal_context *ctx,
9250957b409SSimon J. Gerraty 	uint32_t days, uint32_t seconds)
9260957b409SSimon J. Gerraty {
9270957b409SSimon J. Gerraty 	ctx->days = days;
9280957b409SSimon J. Gerraty 	ctx->seconds = seconds;
929*cc9e6590SSimon J. Gerraty 	ctx->itime = 0;
930*cc9e6590SSimon J. Gerraty }
931*cc9e6590SSimon J. Gerraty 
932*cc9e6590SSimon J. Gerraty /**
933*cc9e6590SSimon J. Gerraty  * \brief Set the validity range callback function for the X.509
934*cc9e6590SSimon J. Gerraty  * "minimal" engine.
935*cc9e6590SSimon J. Gerraty  *
936*cc9e6590SSimon J. Gerraty  * The provided function will be invoked to check whether the validation
937*cc9e6590SSimon J. Gerraty  * date is within the validity range for a given X.509 certificate; a
938*cc9e6590SSimon J. Gerraty  * call will be issued for each considered certificate. The provided
939*cc9e6590SSimon J. Gerraty  * context pointer (itime_ctx) will be passed as first parameter to the
940*cc9e6590SSimon J. Gerraty  * callback.
941*cc9e6590SSimon J. Gerraty  *
942*cc9e6590SSimon J. Gerraty  * \param tctx   context for callback invocation.
943*cc9e6590SSimon J. Gerraty  * \param cb     callback function.
944*cc9e6590SSimon J. Gerraty  */
945*cc9e6590SSimon J. Gerraty static inline void
br_x509_minimal_set_time_callback(br_x509_minimal_context * ctx,void * itime_ctx,br_x509_time_check itime)946*cc9e6590SSimon J. Gerraty br_x509_minimal_set_time_callback(br_x509_minimal_context *ctx,
947*cc9e6590SSimon J. Gerraty 	void *itime_ctx, br_x509_time_check itime)
948*cc9e6590SSimon J. Gerraty {
949*cc9e6590SSimon J. Gerraty 	ctx->itime_ctx = itime_ctx;
950*cc9e6590SSimon J. Gerraty 	ctx->itime = itime;
9510957b409SSimon J. Gerraty }
9520957b409SSimon J. Gerraty 
9530957b409SSimon J. Gerraty /**
9540957b409SSimon J. Gerraty  * \brief Set the minimal acceptable length for RSA keys (X.509 "minimal"
9550957b409SSimon J. Gerraty  * engine).
9560957b409SSimon J. Gerraty  *
9570957b409SSimon J. Gerraty  * The RSA key length is expressed in bytes. The default minimum key
9580957b409SSimon J. Gerraty  * length is 128 bytes, corresponding to 1017 bits. RSA keys shorter
9590957b409SSimon J. Gerraty  * than the configured length will be rejected, implying validation
9600957b409SSimon J. Gerraty  * failure. This setting applies to keys extracted from certificates
9610957b409SSimon J. Gerraty  * (both end-entity, and intermediate CA) but not to "CA" trust anchors.
9620957b409SSimon J. Gerraty  *
9630957b409SSimon J. Gerraty  * \param ctx           validation context.
9640957b409SSimon J. Gerraty  * \param byte_length   minimum RSA key length, **in bytes** (not bits).
9650957b409SSimon J. Gerraty  */
9660957b409SSimon J. Gerraty static inline void
br_x509_minimal_set_minrsa(br_x509_minimal_context * ctx,int byte_length)9670957b409SSimon J. Gerraty br_x509_minimal_set_minrsa(br_x509_minimal_context *ctx, int byte_length)
9680957b409SSimon J. Gerraty {
9690957b409SSimon J. Gerraty 	ctx->min_rsa_size = (int16_t)(byte_length - 128);
9700957b409SSimon J. Gerraty }
9710957b409SSimon J. Gerraty 
9720957b409SSimon J. Gerraty /**
9730957b409SSimon J. Gerraty  * \brief Set the name elements to gather.
9740957b409SSimon J. Gerraty  *
9750957b409SSimon J. Gerraty  * The provided array is linked in the context. The elements are
9760957b409SSimon J. Gerraty  * gathered from the EE certificate. If the same element type is
9770957b409SSimon J. Gerraty  * requested several times, then the relevant structures will be filled
9780957b409SSimon J. Gerraty  * in the order the matching values are encountered in the certificate.
9790957b409SSimon J. Gerraty  *
9800957b409SSimon J. Gerraty  * \param ctx        validation context.
9810957b409SSimon J. Gerraty  * \param elts       array of name element structures to fill.
9820957b409SSimon J. Gerraty  * \param num_elts   number of name element structures to fill.
9830957b409SSimon J. Gerraty  */
9840957b409SSimon J. Gerraty static inline void
br_x509_minimal_set_name_elements(br_x509_minimal_context * ctx,br_name_element * elts,size_t num_elts)9850957b409SSimon J. Gerraty br_x509_minimal_set_name_elements(br_x509_minimal_context *ctx,
9860957b409SSimon J. Gerraty 	br_name_element *elts, size_t num_elts)
9870957b409SSimon J. Gerraty {
9880957b409SSimon J. Gerraty 	ctx->name_elts = elts;
9890957b409SSimon J. Gerraty 	ctx->num_name_elts = num_elts;
9900957b409SSimon J. Gerraty }
9910957b409SSimon J. Gerraty 
9920957b409SSimon J. Gerraty /**
9930957b409SSimon J. Gerraty  * \brief X.509 decoder context.
9940957b409SSimon J. Gerraty  *
9950957b409SSimon J. Gerraty  * This structure is _not_ for X.509 validation, but for extracting
9960957b409SSimon J. Gerraty  * names and public keys from encoded certificates. Intended usage is
9970957b409SSimon J. Gerraty  * to use (self-signed) certificates as trust anchors.
9980957b409SSimon J. Gerraty  *
9990957b409SSimon J. Gerraty  * Contents are opaque and shall not be accessed directly.
10000957b409SSimon J. Gerraty  */
10010957b409SSimon J. Gerraty typedef struct {
10020957b409SSimon J. Gerraty 
10030957b409SSimon J. Gerraty #ifndef BR_DOXYGEN_IGNORE
10040957b409SSimon J. Gerraty 	/* Structure for returning the public key. */
10050957b409SSimon J. Gerraty 	br_x509_pkey pkey;
10060957b409SSimon J. Gerraty 
10070957b409SSimon J. Gerraty 	/* CPU for the T0 virtual machine. */
10080957b409SSimon J. Gerraty 	struct {
10090957b409SSimon J. Gerraty 		uint32_t *dp;
10100957b409SSimon J. Gerraty 		uint32_t *rp;
10110957b409SSimon J. Gerraty 		const unsigned char *ip;
10120957b409SSimon J. Gerraty 	} cpu;
10130957b409SSimon J. Gerraty 	uint32_t dp_stack[32];
10140957b409SSimon J. Gerraty 	uint32_t rp_stack[32];
10150957b409SSimon J. Gerraty 	int err;
10160957b409SSimon J. Gerraty 
10170957b409SSimon J. Gerraty 	/* The pad serves as destination for various operations. */
10180957b409SSimon J. Gerraty 	unsigned char pad[256];
10190957b409SSimon J. Gerraty 
10200957b409SSimon J. Gerraty 	/* Flag set when decoding succeeds. */
10210957b409SSimon J. Gerraty 	unsigned char decoded;
10220957b409SSimon J. Gerraty 
10230957b409SSimon J. Gerraty 	/* Validity dates. */
10240957b409SSimon J. Gerraty 	uint32_t notbefore_days, notbefore_seconds;
10250957b409SSimon J. Gerraty 	uint32_t notafter_days, notafter_seconds;
10260957b409SSimon J. Gerraty 
10270957b409SSimon J. Gerraty 	/* The "CA" flag. This is set to true if the certificate contains
10280957b409SSimon J. Gerraty 	   a Basic Constraints extension that asserts CA status. */
10290957b409SSimon J. Gerraty 	unsigned char isCA;
10300957b409SSimon J. Gerraty 
10310957b409SSimon J. Gerraty 	/* DN processing: the subject DN is extracted and pushed to the
10320957b409SSimon J. Gerraty 	   provided callback. */
10330957b409SSimon J. Gerraty 	unsigned char copy_dn;
10340957b409SSimon J. Gerraty 	void *append_dn_ctx;
10350957b409SSimon J. Gerraty 	void (*append_dn)(void *ctx, const void *buf, size_t len);
10360957b409SSimon J. Gerraty 
10370957b409SSimon J. Gerraty 	/* Certificate data chunk. */
10380957b409SSimon J. Gerraty 	const unsigned char *hbuf;
10390957b409SSimon J. Gerraty 	size_t hlen;
10400957b409SSimon J. Gerraty 
10410957b409SSimon J. Gerraty 	/* Buffer for decoded public key. */
10420957b409SSimon J. Gerraty 	unsigned char pkey_data[BR_X509_BUFSIZE_KEY];
10430957b409SSimon J. Gerraty 
10440957b409SSimon J. Gerraty 	/* Type of key and hash function used in the certificate signature. */
10450957b409SSimon J. Gerraty 	unsigned char signer_key_type;
10460957b409SSimon J. Gerraty 	unsigned char signer_hash_id;
10470957b409SSimon J. Gerraty #endif
10480957b409SSimon J. Gerraty 
10490957b409SSimon J. Gerraty } br_x509_decoder_context;
10500957b409SSimon J. Gerraty 
10510957b409SSimon J. Gerraty /**
10520957b409SSimon J. Gerraty  * \brief Initialise an X.509 decoder context for processing a new
10530957b409SSimon J. Gerraty  * certificate.
10540957b409SSimon J. Gerraty  *
10550957b409SSimon J. Gerraty  * The `append_dn()` callback (with opaque context `append_dn_ctx`)
10560957b409SSimon J. Gerraty  * will be invoked to receive, chunk by chunk, the certificate's
10570957b409SSimon J. Gerraty  * subject DN. If `append_dn` is `0` then the subject DN will be
10580957b409SSimon J. Gerraty  * ignored.
10590957b409SSimon J. Gerraty  *
10600957b409SSimon J. Gerraty  * \param ctx             X.509 decoder context to initialise.
10610957b409SSimon J. Gerraty  * \param append_dn       DN receiver callback (or `0`).
10620957b409SSimon J. Gerraty  * \param append_dn_ctx   context for the DN receiver callback.
10630957b409SSimon J. Gerraty  */
10640957b409SSimon J. Gerraty void br_x509_decoder_init(br_x509_decoder_context *ctx,
10650957b409SSimon J. Gerraty 	void (*append_dn)(void *ctx, const void *buf, size_t len),
10660957b409SSimon J. Gerraty 	void *append_dn_ctx);
10670957b409SSimon J. Gerraty 
10680957b409SSimon J. Gerraty /**
10690957b409SSimon J. Gerraty  * \brief Push some certificate bytes into a decoder context.
10700957b409SSimon J. Gerraty  *
10710957b409SSimon J. Gerraty  * If `len` is non-zero, then that many bytes are pushed, from address
10720957b409SSimon J. Gerraty  * `data`, into the provided decoder context.
10730957b409SSimon J. Gerraty  *
10740957b409SSimon J. Gerraty  * \param ctx    X.509 decoder context.
10750957b409SSimon J. Gerraty  * \param data   certificate data chunk.
10760957b409SSimon J. Gerraty  * \param len    certificate data chunk length (in bytes).
10770957b409SSimon J. Gerraty  */
10780957b409SSimon J. Gerraty void br_x509_decoder_push(br_x509_decoder_context *ctx,
10790957b409SSimon J. Gerraty 	const void *data, size_t len);
10800957b409SSimon J. Gerraty 
10810957b409SSimon J. Gerraty /**
10820957b409SSimon J. Gerraty  * \brief Obtain the decoded public key.
10830957b409SSimon J. Gerraty  *
10840957b409SSimon J. Gerraty  * Returned value is a pointer to a structure internal to the decoder
10850957b409SSimon J. Gerraty  * context; releasing or reusing the decoder context invalidates that
10860957b409SSimon J. Gerraty  * structure.
10870957b409SSimon J. Gerraty  *
10880957b409SSimon J. Gerraty  * If decoding was not finished, or failed, then `NULL` is returned.
10890957b409SSimon J. Gerraty  *
10900957b409SSimon J. Gerraty  * \param ctx   X.509 decoder context.
10910957b409SSimon J. Gerraty  * \return  the public key, or `NULL` on unfinished/error.
10920957b409SSimon J. Gerraty  */
10930957b409SSimon J. Gerraty static inline br_x509_pkey *
br_x509_decoder_get_pkey(br_x509_decoder_context * ctx)10940957b409SSimon J. Gerraty br_x509_decoder_get_pkey(br_x509_decoder_context *ctx)
10950957b409SSimon J. Gerraty {
10960957b409SSimon J. Gerraty 	if (ctx->decoded && ctx->err == 0) {
10970957b409SSimon J. Gerraty 		return &ctx->pkey;
10980957b409SSimon J. Gerraty 	} else {
10990957b409SSimon J. Gerraty 		return NULL;
11000957b409SSimon J. Gerraty 	}
11010957b409SSimon J. Gerraty }
11020957b409SSimon J. Gerraty 
11030957b409SSimon J. Gerraty /**
11040957b409SSimon J. Gerraty  * \brief Get decoder error status.
11050957b409SSimon J. Gerraty  *
11060957b409SSimon J. Gerraty  * If no error was reported yet but the certificate decoding is not
11070957b409SSimon J. Gerraty  * finished, then the error code is `BR_ERR_X509_TRUNCATED`. If decoding
11080957b409SSimon J. Gerraty  * was successful, then 0 is returned.
11090957b409SSimon J. Gerraty  *
11100957b409SSimon J. Gerraty  * \param ctx   X.509 decoder context.
11110957b409SSimon J. Gerraty  * \return  0 on successful decoding, or a non-zero error code.
11120957b409SSimon J. Gerraty  */
11130957b409SSimon J. Gerraty static inline int
br_x509_decoder_last_error(br_x509_decoder_context * ctx)11140957b409SSimon J. Gerraty br_x509_decoder_last_error(br_x509_decoder_context *ctx)
11150957b409SSimon J. Gerraty {
11160957b409SSimon J. Gerraty 	if (ctx->err != 0) {
11170957b409SSimon J. Gerraty 		return ctx->err;
11180957b409SSimon J. Gerraty 	}
11190957b409SSimon J. Gerraty 	if (!ctx->decoded) {
11200957b409SSimon J. Gerraty 		return BR_ERR_X509_TRUNCATED;
11210957b409SSimon J. Gerraty 	}
11220957b409SSimon J. Gerraty 	return 0;
11230957b409SSimon J. Gerraty }
11240957b409SSimon J. Gerraty 
11250957b409SSimon J. Gerraty /**
11260957b409SSimon J. Gerraty  * \brief Get the "isCA" flag from an X.509 decoder context.
11270957b409SSimon J. Gerraty  *
11280957b409SSimon J. Gerraty  * This flag is set if the decoded certificate claims to be a CA through
11290957b409SSimon J. Gerraty  * a Basic Constraints extension. This flag should not be read before
11300957b409SSimon J. Gerraty  * decoding completed successfully.
11310957b409SSimon J. Gerraty  *
11320957b409SSimon J. Gerraty  * \param ctx   X.509 decoder context.
11330957b409SSimon J. Gerraty  * \return  the "isCA" flag.
11340957b409SSimon J. Gerraty  */
11350957b409SSimon J. Gerraty static inline int
br_x509_decoder_isCA(br_x509_decoder_context * ctx)11360957b409SSimon J. Gerraty br_x509_decoder_isCA(br_x509_decoder_context *ctx)
11370957b409SSimon J. Gerraty {
11380957b409SSimon J. Gerraty 	return ctx->isCA;
11390957b409SSimon J. Gerraty }
11400957b409SSimon J. Gerraty 
11410957b409SSimon J. Gerraty /**
11420957b409SSimon J. Gerraty  * \brief Get the issuing CA key type (type of algorithm used to sign the
11430957b409SSimon J. Gerraty  * decoded certificate).
11440957b409SSimon J. Gerraty  *
11450957b409SSimon J. Gerraty  * This is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. The value 0 is returned
11460957b409SSimon J. Gerraty  * if the signature type was not recognised.
11470957b409SSimon J. Gerraty  *
11480957b409SSimon J. Gerraty  * \param ctx   X.509 decoder context.
11490957b409SSimon J. Gerraty  * \return  the issuing CA key type.
11500957b409SSimon J. Gerraty  */
11510957b409SSimon J. Gerraty static inline int
br_x509_decoder_get_signer_key_type(br_x509_decoder_context * ctx)11520957b409SSimon J. Gerraty br_x509_decoder_get_signer_key_type(br_x509_decoder_context *ctx)
11530957b409SSimon J. Gerraty {
11540957b409SSimon J. Gerraty 	return ctx->signer_key_type;
11550957b409SSimon J. Gerraty }
11560957b409SSimon J. Gerraty 
11570957b409SSimon J. Gerraty /**
11580957b409SSimon J. Gerraty  * \brief Get the identifier for the hash function used to sign the decoded
11590957b409SSimon J. Gerraty  * certificate.
11600957b409SSimon J. Gerraty  *
11610957b409SSimon J. Gerraty  * This is 0 if the hash function was not recognised.
11620957b409SSimon J. Gerraty  *
11630957b409SSimon J. Gerraty  * \param ctx   X.509 decoder context.
11640957b409SSimon J. Gerraty  * \return  the signature hash function identifier.
11650957b409SSimon J. Gerraty  */
11660957b409SSimon J. Gerraty static inline int
br_x509_decoder_get_signer_hash_id(br_x509_decoder_context * ctx)11670957b409SSimon J. Gerraty br_x509_decoder_get_signer_hash_id(br_x509_decoder_context *ctx)
11680957b409SSimon J. Gerraty {
11690957b409SSimon J. Gerraty 	return ctx->signer_hash_id;
11700957b409SSimon J. Gerraty }
11710957b409SSimon J. Gerraty 
11720957b409SSimon J. Gerraty /**
11730957b409SSimon J. Gerraty  * \brief Type for an X.509 certificate (DER-encoded).
11740957b409SSimon J. Gerraty  */
11750957b409SSimon J. Gerraty typedef struct {
11760957b409SSimon J. Gerraty 	/** \brief The DER-encoded certificate data. */
11770957b409SSimon J. Gerraty 	unsigned char *data;
11780957b409SSimon J. Gerraty 	/** \brief The DER-encoded certificate length (in bytes). */
11790957b409SSimon J. Gerraty 	size_t data_len;
11800957b409SSimon J. Gerraty } br_x509_certificate;
11810957b409SSimon J. Gerraty 
11820957b409SSimon J. Gerraty /**
11830957b409SSimon J. Gerraty  * \brief Private key decoder context.
11840957b409SSimon J. Gerraty  *
11850957b409SSimon J. Gerraty  * The private key decoder recognises RSA and EC private keys, either in
11860957b409SSimon J. Gerraty  * their raw, DER-encoded format, or wrapped in an unencrypted PKCS#8
11870957b409SSimon J. Gerraty  * archive (again DER-encoded).
11880957b409SSimon J. Gerraty  *
11890957b409SSimon J. Gerraty  * Structure contents are opaque and shall not be accessed directly.
11900957b409SSimon J. Gerraty  */
11910957b409SSimon J. Gerraty typedef struct {
11920957b409SSimon J. Gerraty #ifndef BR_DOXYGEN_IGNORE
11930957b409SSimon J. Gerraty 	/* Structure for returning the private key. */
11940957b409SSimon J. Gerraty 	union {
11950957b409SSimon J. Gerraty 		br_rsa_private_key rsa;
11960957b409SSimon J. Gerraty 		br_ec_private_key ec;
11970957b409SSimon J. Gerraty 	} key;
11980957b409SSimon J. Gerraty 
11990957b409SSimon J. Gerraty 	/* CPU for the T0 virtual machine. */
12000957b409SSimon J. Gerraty 	struct {
12010957b409SSimon J. Gerraty 		uint32_t *dp;
12020957b409SSimon J. Gerraty 		uint32_t *rp;
12030957b409SSimon J. Gerraty 		const unsigned char *ip;
12040957b409SSimon J. Gerraty 	} cpu;
12050957b409SSimon J. Gerraty 	uint32_t dp_stack[32];
12060957b409SSimon J. Gerraty 	uint32_t rp_stack[32];
12070957b409SSimon J. Gerraty 	int err;
12080957b409SSimon J. Gerraty 
12090957b409SSimon J. Gerraty 	/* Private key data chunk. */
12100957b409SSimon J. Gerraty 	const unsigned char *hbuf;
12110957b409SSimon J. Gerraty 	size_t hlen;
12120957b409SSimon J. Gerraty 
12130957b409SSimon J. Gerraty 	/* The pad serves as destination for various operations. */
12140957b409SSimon J. Gerraty 	unsigned char pad[256];
12150957b409SSimon J. Gerraty 
12160957b409SSimon J. Gerraty 	/* Decoded key type; 0 until decoding is complete. */
12170957b409SSimon J. Gerraty 	unsigned char key_type;
12180957b409SSimon J. Gerraty 
12190957b409SSimon J. Gerraty 	/* Buffer for the private key elements. It shall be large enough
12200957b409SSimon J. Gerraty 	   to accommodate all elements for a RSA-4096 private key (roughly
12210957b409SSimon J. Gerraty 	   five 2048-bit integers, possibly a bit more). */
12220957b409SSimon J. Gerraty 	unsigned char key_data[3 * BR_X509_BUFSIZE_SIG];
12230957b409SSimon J. Gerraty #endif
12240957b409SSimon J. Gerraty } br_skey_decoder_context;
12250957b409SSimon J. Gerraty 
12260957b409SSimon J. Gerraty /**
12270957b409SSimon J. Gerraty  * \brief Initialise a private key decoder context.
12280957b409SSimon J. Gerraty  *
12290957b409SSimon J. Gerraty  * \param ctx   key decoder context to initialise.
12300957b409SSimon J. Gerraty  */
12310957b409SSimon J. Gerraty void br_skey_decoder_init(br_skey_decoder_context *ctx);
12320957b409SSimon J. Gerraty 
12330957b409SSimon J. Gerraty /**
12340957b409SSimon J. Gerraty  * \brief Push some data bytes into a private key decoder context.
12350957b409SSimon J. Gerraty  *
12360957b409SSimon J. Gerraty  * If `len` is non-zero, then that many data bytes, starting at address
12370957b409SSimon J. Gerraty  * `data`, are pushed into the decoder.
12380957b409SSimon J. Gerraty  *
12390957b409SSimon J. Gerraty  * \param ctx    key decoder context.
12400957b409SSimon J. Gerraty  * \param data   private key data chunk.
12410957b409SSimon J. Gerraty  * \param len    private key data chunk length (in bytes).
12420957b409SSimon J. Gerraty  */
12430957b409SSimon J. Gerraty void br_skey_decoder_push(br_skey_decoder_context *ctx,
12440957b409SSimon J. Gerraty 	const void *data, size_t len);
12450957b409SSimon J. Gerraty 
12460957b409SSimon J. Gerraty /**
12470957b409SSimon J. Gerraty  * \brief Get the decoding status for a private key.
12480957b409SSimon J. Gerraty  *
12490957b409SSimon J. Gerraty  * Decoding status is 0 on success, or a non-zero error code. If the
12500957b409SSimon J. Gerraty  * decoding is unfinished when this function is called, then the
12510957b409SSimon J. Gerraty  * status code `BR_ERR_X509_TRUNCATED` is returned.
12520957b409SSimon J. Gerraty  *
12530957b409SSimon J. Gerraty  * \param ctx   key decoder context.
12540957b409SSimon J. Gerraty  * \return  0 on successful decoding, or a non-zero error code.
12550957b409SSimon J. Gerraty  */
12560957b409SSimon J. Gerraty static inline int
br_skey_decoder_last_error(const br_skey_decoder_context * ctx)12570957b409SSimon J. Gerraty br_skey_decoder_last_error(const br_skey_decoder_context *ctx)
12580957b409SSimon J. Gerraty {
12590957b409SSimon J. Gerraty 	if (ctx->err != 0) {
12600957b409SSimon J. Gerraty 		return ctx->err;
12610957b409SSimon J. Gerraty 	}
12620957b409SSimon J. Gerraty 	if (ctx->key_type == 0) {
12630957b409SSimon J. Gerraty 		return BR_ERR_X509_TRUNCATED;
12640957b409SSimon J. Gerraty 	}
12650957b409SSimon J. Gerraty 	return 0;
12660957b409SSimon J. Gerraty }
12670957b409SSimon J. Gerraty 
12680957b409SSimon J. Gerraty /**
12690957b409SSimon J. Gerraty  * \brief Get the decoded private key type.
12700957b409SSimon J. Gerraty  *
12710957b409SSimon J. Gerraty  * Private key type is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. If decoding is
12720957b409SSimon J. Gerraty  * not finished or failed, then 0 is returned.
12730957b409SSimon J. Gerraty  *
12740957b409SSimon J. Gerraty  * \param ctx   key decoder context.
12750957b409SSimon J. Gerraty  * \return  decoded private key type, or 0.
12760957b409SSimon J. Gerraty  */
12770957b409SSimon J. Gerraty static inline int
br_skey_decoder_key_type(const br_skey_decoder_context * ctx)12780957b409SSimon J. Gerraty br_skey_decoder_key_type(const br_skey_decoder_context *ctx)
12790957b409SSimon J. Gerraty {
12800957b409SSimon J. Gerraty 	if (ctx->err == 0) {
12810957b409SSimon J. Gerraty 		return ctx->key_type;
12820957b409SSimon J. Gerraty 	} else {
12830957b409SSimon J. Gerraty 		return 0;
12840957b409SSimon J. Gerraty 	}
12850957b409SSimon J. Gerraty }
12860957b409SSimon J. Gerraty 
12870957b409SSimon J. Gerraty /**
12880957b409SSimon J. Gerraty  * \brief Get the decoded RSA private key.
12890957b409SSimon J. Gerraty  *
12900957b409SSimon J. Gerraty  * This function returns `NULL` if the decoding failed, or is not
12910957b409SSimon J. Gerraty  * finished, or the key is not RSA. The returned pointer references
12920957b409SSimon J. Gerraty  * structures within the context that can become invalid if the context
12930957b409SSimon J. Gerraty  * is reused or released.
12940957b409SSimon J. Gerraty  *
12950957b409SSimon J. Gerraty  * \param ctx   key decoder context.
12960957b409SSimon J. Gerraty  * \return  decoded RSA private key, or `NULL`.
12970957b409SSimon J. Gerraty  */
12980957b409SSimon J. Gerraty static inline const br_rsa_private_key *
br_skey_decoder_get_rsa(const br_skey_decoder_context * ctx)12990957b409SSimon J. Gerraty br_skey_decoder_get_rsa(const br_skey_decoder_context *ctx)
13000957b409SSimon J. Gerraty {
13010957b409SSimon J. Gerraty 	if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_RSA) {
13020957b409SSimon J. Gerraty 		return &ctx->key.rsa;
13030957b409SSimon J. Gerraty 	} else {
13040957b409SSimon J. Gerraty 		return NULL;
13050957b409SSimon J. Gerraty 	}
13060957b409SSimon J. Gerraty }
13070957b409SSimon J. Gerraty 
13080957b409SSimon J. Gerraty /**
13090957b409SSimon J. Gerraty  * \brief Get the decoded EC private key.
13100957b409SSimon J. Gerraty  *
13110957b409SSimon J. Gerraty  * This function returns `NULL` if the decoding failed, or is not
13120957b409SSimon J. Gerraty  * finished, or the key is not EC. The returned pointer references
13130957b409SSimon J. Gerraty  * structures within the context that can become invalid if the context
13140957b409SSimon J. Gerraty  * is reused or released.
13150957b409SSimon J. Gerraty  *
13160957b409SSimon J. Gerraty  * \param ctx   key decoder context.
13170957b409SSimon J. Gerraty  * \return  decoded EC private key, or `NULL`.
13180957b409SSimon J. Gerraty  */
13190957b409SSimon J. Gerraty static inline const br_ec_private_key *
br_skey_decoder_get_ec(const br_skey_decoder_context * ctx)13200957b409SSimon J. Gerraty br_skey_decoder_get_ec(const br_skey_decoder_context *ctx)
13210957b409SSimon J. Gerraty {
13220957b409SSimon J. Gerraty 	if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_EC) {
13230957b409SSimon J. Gerraty 		return &ctx->key.ec;
13240957b409SSimon J. Gerraty 	} else {
13250957b409SSimon J. Gerraty 		return NULL;
13260957b409SSimon J. Gerraty 	}
13270957b409SSimon J. Gerraty }
13280957b409SSimon J. Gerraty 
13290957b409SSimon J. Gerraty /**
13300957b409SSimon J. Gerraty  * \brief Encode an RSA private key (raw DER format).
13310957b409SSimon J. Gerraty  *
13320957b409SSimon J. Gerraty  * This function encodes the provided key into the "raw" format specified
13330957b409SSimon J. Gerraty  * in PKCS#1 (RFC 8017, Appendix C, type `RSAPrivateKey`), with DER
13340957b409SSimon J. Gerraty  * encoding rules.
13350957b409SSimon J. Gerraty  *
13360957b409SSimon J. Gerraty  * The key elements are:
13370957b409SSimon J. Gerraty  *
13380957b409SSimon J. Gerraty  *  - `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`)
13390957b409SSimon J. Gerraty  *
13400957b409SSimon J. Gerraty  *  - `pk`: the public key (`n` and `e`)
13410957b409SSimon J. Gerraty  *
13420957b409SSimon J. Gerraty  *  - `d` (size: `dlen` bytes): the private exponent
13430957b409SSimon J. Gerraty  *
13440957b409SSimon J. Gerraty  * The public key elements, and the private exponent `d`, can be
13450957b409SSimon J. Gerraty  * recomputed from the private key (see `br_rsa_compute_modulus()`,
13460957b409SSimon J. Gerraty  * `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`).
13470957b409SSimon J. Gerraty  *
13480957b409SSimon J. Gerraty  * If `dest` is not `NULL`, then the encoded key is written at that
13490957b409SSimon J. Gerraty  * address, and the encoded length (in bytes) is returned. If `dest` is
13500957b409SSimon J. Gerraty  * `NULL`, then nothing is written, but the encoded length is still
13510957b409SSimon J. Gerraty  * computed and returned.
13520957b409SSimon J. Gerraty  *
13530957b409SSimon J. Gerraty  * \param dest   the destination buffer (or `NULL`).
13540957b409SSimon J. Gerraty  * \param sk     the RSA private key.
13550957b409SSimon J. Gerraty  * \param pk     the RSA public key.
13560957b409SSimon J. Gerraty  * \param d      the RSA private exponent.
13570957b409SSimon J. Gerraty  * \param dlen   the RSA private exponent length (in bytes).
13580957b409SSimon J. Gerraty  * \return  the encoded key length (in bytes).
13590957b409SSimon J. Gerraty  */
13600957b409SSimon J. Gerraty size_t br_encode_rsa_raw_der(void *dest, const br_rsa_private_key *sk,
13610957b409SSimon J. Gerraty 	const br_rsa_public_key *pk, const void *d, size_t dlen);
13620957b409SSimon J. Gerraty 
13630957b409SSimon J. Gerraty /**
13640957b409SSimon J. Gerraty  * \brief Encode an RSA private key (PKCS#8 DER format).
13650957b409SSimon J. Gerraty  *
13660957b409SSimon J. Gerraty  * This function encodes the provided key into the PKCS#8 format
13670957b409SSimon J. Gerraty  * (RFC 5958, type `OneAsymmetricKey`). It wraps around the "raw DER"
13680957b409SSimon J. Gerraty  * format for the RSA key, as implemented by `br_encode_rsa_raw_der()`.
13690957b409SSimon J. Gerraty  *
13700957b409SSimon J. Gerraty  * The key elements are:
13710957b409SSimon J. Gerraty  *
13720957b409SSimon J. Gerraty  *  - `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`)
13730957b409SSimon J. Gerraty  *
13740957b409SSimon J. Gerraty  *  - `pk`: the public key (`n` and `e`)
13750957b409SSimon J. Gerraty  *
13760957b409SSimon J. Gerraty  *  - `d` (size: `dlen` bytes): the private exponent
13770957b409SSimon J. Gerraty  *
13780957b409SSimon J. Gerraty  * The public key elements, and the private exponent `d`, can be
13790957b409SSimon J. Gerraty  * recomputed from the private key (see `br_rsa_compute_modulus()`,
13800957b409SSimon J. Gerraty  * `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`).
13810957b409SSimon J. Gerraty  *
13820957b409SSimon J. Gerraty  * If `dest` is not `NULL`, then the encoded key is written at that
13830957b409SSimon J. Gerraty  * address, and the encoded length (in bytes) is returned. If `dest` is
13840957b409SSimon J. Gerraty  * `NULL`, then nothing is written, but the encoded length is still
13850957b409SSimon J. Gerraty  * computed and returned.
13860957b409SSimon J. Gerraty  *
13870957b409SSimon J. Gerraty  * \param dest   the destination buffer (or `NULL`).
13880957b409SSimon J. Gerraty  * \param sk     the RSA private key.
13890957b409SSimon J. Gerraty  * \param pk     the RSA public key.
13900957b409SSimon J. Gerraty  * \param d      the RSA private exponent.
13910957b409SSimon J. Gerraty  * \param dlen   the RSA private exponent length (in bytes).
13920957b409SSimon J. Gerraty  * \return  the encoded key length (in bytes).
13930957b409SSimon J. Gerraty  */
13940957b409SSimon J. Gerraty size_t br_encode_rsa_pkcs8_der(void *dest, const br_rsa_private_key *sk,
13950957b409SSimon J. Gerraty 	const br_rsa_public_key *pk, const void *d, size_t dlen);
13960957b409SSimon J. Gerraty 
13970957b409SSimon J. Gerraty /**
13980957b409SSimon J. Gerraty  * \brief Encode an EC private key (raw DER format).
13990957b409SSimon J. Gerraty  *
14000957b409SSimon J. Gerraty  * This function encodes the provided key into the "raw" format specified
14010957b409SSimon J. Gerraty  * in RFC 5915 (type `ECPrivateKey`), with DER encoding rules.
14020957b409SSimon J. Gerraty  *
14030957b409SSimon J. Gerraty  * The private key is provided in `sk`, the public key being `pk`. If
14040957b409SSimon J. Gerraty  * `pk` is `NULL`, then the encoded key will not include the public key
14050957b409SSimon J. Gerraty  * in its `publicKey` field (which is nominally optional).
14060957b409SSimon J. Gerraty  *
14070957b409SSimon J. Gerraty  * If `dest` is not `NULL`, then the encoded key is written at that
14080957b409SSimon J. Gerraty  * address, and the encoded length (in bytes) is returned. If `dest` is
14090957b409SSimon J. Gerraty  * `NULL`, then nothing is written, but the encoded length is still
14100957b409SSimon J. Gerraty  * computed and returned.
14110957b409SSimon J. Gerraty  *
14120957b409SSimon J. Gerraty  * If the key cannot be encoded (e.g. because there is no known OBJECT
14130957b409SSimon J. Gerraty  * IDENTIFIER for the used curve), then 0 is returned.
14140957b409SSimon J. Gerraty  *
14150957b409SSimon J. Gerraty  * \param dest   the destination buffer (or `NULL`).
14160957b409SSimon J. Gerraty  * \param sk     the EC private key.
14170957b409SSimon J. Gerraty  * \param pk     the EC public key (or `NULL`).
14180957b409SSimon J. Gerraty  * \return  the encoded key length (in bytes), or 0.
14190957b409SSimon J. Gerraty  */
14200957b409SSimon J. Gerraty size_t br_encode_ec_raw_der(void *dest,
14210957b409SSimon J. Gerraty 	const br_ec_private_key *sk, const br_ec_public_key *pk);
14220957b409SSimon J. Gerraty 
14230957b409SSimon J. Gerraty /**
14240957b409SSimon J. Gerraty  * \brief Encode an EC private key (PKCS#8 DER format).
14250957b409SSimon J. Gerraty  *
14260957b409SSimon J. Gerraty  * This function encodes the provided key into the PKCS#8 format
14270957b409SSimon J. Gerraty  * (RFC 5958, type `OneAsymmetricKey`). The curve is identified
14280957b409SSimon J. Gerraty  * by an OID provided as parameters to the `privateKeyAlgorithm`
14290957b409SSimon J. Gerraty  * field. The private key value (contents of the `privateKey` field)
14300957b409SSimon J. Gerraty  * contains the DER encoding of the `ECPrivateKey` type defined in
14310957b409SSimon J. Gerraty  * RFC 5915, without the `parameters` field (since they would be
14320957b409SSimon J. Gerraty  * redundant with the information in `privateKeyAlgorithm`).
14330957b409SSimon J. Gerraty  *
14340957b409SSimon J. Gerraty  * The private key is provided in `sk`, the public key being `pk`. If
14350957b409SSimon J. Gerraty  * `pk` is not `NULL`, then the encoded public key is included in the
14360957b409SSimon J. Gerraty  * `publicKey` field of the private key value (but not in the `publicKey`
14370957b409SSimon J. Gerraty  * field of the PKCS#8 `OneAsymmetricKey` wrapper).
14380957b409SSimon J. Gerraty  *
14390957b409SSimon J. Gerraty  * If `dest` is not `NULL`, then the encoded key is written at that
14400957b409SSimon J. Gerraty  * address, and the encoded length (in bytes) is returned. If `dest` is
14410957b409SSimon J. Gerraty  * `NULL`, then nothing is written, but the encoded length is still
14420957b409SSimon J. Gerraty  * computed and returned.
14430957b409SSimon J. Gerraty  *
14440957b409SSimon J. Gerraty  * If the key cannot be encoded (e.g. because there is no known OBJECT
14450957b409SSimon J. Gerraty  * IDENTIFIER for the used curve), then 0 is returned.
14460957b409SSimon J. Gerraty  *
14470957b409SSimon J. Gerraty  * \param dest   the destination buffer (or `NULL`).
14480957b409SSimon J. Gerraty  * \param sk     the EC private key.
14490957b409SSimon J. Gerraty  * \param pk     the EC public key (or `NULL`).
14500957b409SSimon J. Gerraty  * \return  the encoded key length (in bytes), or 0.
14510957b409SSimon J. Gerraty  */
14520957b409SSimon J. Gerraty size_t br_encode_ec_pkcs8_der(void *dest,
14530957b409SSimon J. Gerraty 	const br_ec_private_key *sk, const br_ec_public_key *pk);
14540957b409SSimon J. Gerraty 
14550957b409SSimon J. Gerraty /**
14560957b409SSimon J. Gerraty  * \brief PEM banner for RSA private key (raw).
14570957b409SSimon J. Gerraty  */
14580957b409SSimon J. Gerraty #define BR_ENCODE_PEM_RSA_RAW      "RSA PRIVATE KEY"
14590957b409SSimon J. Gerraty 
14600957b409SSimon J. Gerraty /**
14610957b409SSimon J. Gerraty  * \brief PEM banner for EC private key (raw).
14620957b409SSimon J. Gerraty  */
14630957b409SSimon J. Gerraty #define BR_ENCODE_PEM_EC_RAW       "EC PRIVATE KEY"
14640957b409SSimon J. Gerraty 
14650957b409SSimon J. Gerraty /**
14660957b409SSimon J. Gerraty  * \brief PEM banner for an RSA or EC private key in PKCS#8 format.
14670957b409SSimon J. Gerraty  */
14680957b409SSimon J. Gerraty #define BR_ENCODE_PEM_PKCS8        "PRIVATE KEY"
14690957b409SSimon J. Gerraty 
14700957b409SSimon J. Gerraty #ifdef __cplusplus
14710957b409SSimon J. Gerraty }
14720957b409SSimon J. Gerraty #endif
14730957b409SSimon J. Gerraty 
14740957b409SSimon J. Gerraty #endif
1475