BearSSL

Data Structures | Macros | Functions | Variables
bearssl_x509.h File Reference
Include dependency graph for bearssl_x509.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

## Data Structures
struct | br_x509_pkey
| Aggregate structure for public keys. More...
struct | br_x500_name
| Distinguished Name (X.500) structure. More...
struct | br_x509_trust_anchor
| Trust anchor structure. More...
struct | br_x509_class
| Class type for an X.509 engine. More...
struct | br_x509_knownkey_context
| The "known key" X.509 engine structure. More...
struct | br_name_element
| Type for receiving a name element. More...
struct | br_x509_minimal_context
| The "minimal" X.509 engine structure. More...
struct | br_x509_decoder_context
| X.509 decoder context. More...
struct | br_x509_certificate
| Type for an X.509 certificate (DER-encoded). More...
struct | br_skey_decoder_context
| Private key decoder context. More...

## Macros
#define | BR_ERR_X509_OK 32
| X.509 status: validation was successful; this is not actually an error. More...
#define | BR_ERR_X509_INVALID_VALUE 33
| X.509 status: invalid value in an ASN.1 structure. More...
#define | BR_ERR_X509_TRUNCATED 34
| X.509 status: truncated certificate. More...
#define | BR_ERR_X509_EMPTY_CHAIN 35
| X.509 status: empty certificate chain (no certificate at all). More...
#define | BR_ERR_X509_INNER_TRUNC 36
| X.509 status: decoding error: inner element extends beyond outer element size. More...
#define | BR_ERR_X509_BAD_TAG_CLASS 37
| X.509 status: decoding error: unsupported tag class (application or private). More...
#define | BR_ERR_X509_BAD_TAG_VALUE 38
| X.509 status: decoding error: unsupported tag value. More...
#define | BR_ERR_X509_INDEFINITE_LENGTH 39
| X.509 status: decoding error: indefinite length. More...
#define | BR_ERR_X509_EXTRA_ELEMENT 40
| X.509 status: decoding error: extraneous element. More...
#define | BR_ERR_X509_UNEXPECTED 41
| X.509 status: decoding error: unexpected element. More...
#define | BR_ERR_X509_NOT_CONSTRUCTED 42
| X.509 status: decoding error: expected constructed element, but is primitive. More...
#define | BR_ERR_X509_NOT_PRIMITIVE 43
| X.509 status: decoding error: expected primitive element, but is constructed. More...
#define | BR_ERR_X509_PARTIAL_BYTE 44
| X.509 status: decoding error: BIT STRING length is not multiple of 8. More...
#define | BR_ERR_X509_BAD_BOOLEAN 45
| X.509 status: decoding error: BOOLEAN value has invalid length. More...
#define | BR_ERR_X509_OVERFLOW 46
| X.509 status: decoding error: value is off-limits. More...
#define | BR_ERR_X509_BAD_DN 47
| X.509 status: invalid distinguished name. More...
#define | BR_ERR_X509_BAD_TIME 48
| X.509 status: invalid date/time representation. More...
#define | BR_ERR_X509_UNSUPPORTED 49
| X.509 status: certificate contains unsupported features that cannot be ignored. More...
#define | BR_ERR_X509_LIMIT_EXCEEDED 50
| X.509 status: key or signature size exceeds internal limits. More...
#define | BR_ERR_X509_WRONG_KEY_TYPE 51
| X.509 status: key type does not match that which was expected. More...
#define | BR_ERR_X509_BAD_SIGNATURE 52
| X.509 status: signature is invalid. More...
#define | BR_ERR_X509_TIME_UNKNOWN 53
| X.509 status: validation time is unknown. More...
#define | BR_ERR_X509_EXPIRED 54
| X.509 status: certificate is expired or not yet valid. More...
#define | BR_ERR_X509_DN_MISMATCH 55
| X.509 status: issuer/subject DN mismatch in the chain. More...
#define | BR_ERR_X509_BAD_SERVER_NAME 56
| X.509 status: expected server name was not found in the chain. More...
#define | BR_ERR_X509_CRITICAL_EXTENSION 57
| X.509 status: unknown critical extension in certificate. More...
#define | BR_ERR_X509_NOT_CA 58
| X.509 status: not a CA, or path length constraint violation. More...
#define | BR_ERR_X509_FORBIDDEN_KEY_USAGE 59
| X.509 status: Key Usage extension prohibits intended usage. More...
#define | BR_ERR_X509_WEAK_PUBLIC_KEY 60
| X.509 status: public key found in certificate is too small. More...
#define | BR_ERR_X509_NOT_TRUSTED 62
| X.509 status: chain could not be linked to a trust anchor. More...
#define | BR_X509_TA_CA 0x0001
| Trust anchor flag: CA. More...
#define | BR_KEYTYPE_RSA 1
| Key type: algorithm is RSA. More...
#define | BR_KEYTYPE_EC 2
| Key type: algorithm is EC. More...
#define | BR_KEYTYPE_KEYX 0x10
| Key type: usage is "key exchange". More...
#define | BR_KEYTYPE_SIGN 0x20
| Key type: usage is "signature". More...
#define | BR_ENCODE_PEM_RSA_RAW "RSA PRIVATE KEY"
| PEM banner for RSA private key (raw). More...
#define | BR_ENCODE_PEM_EC_RAW "EC PRIVATE KEY"
| PEM banner for EC private key (raw). More...
#define | BR_ENCODE_PEM_PKCS8 "PRIVATE KEY"
| PEM banner for an RSA or EC private key in PKCS#8 format. More...

## Functions
void | br_x509_knownkey_init_rsa (br_x509_knownkey_context *ctx, const br_rsa_public_key *pk, unsigned usages)
| Initialize a "known key" X.509 engine with a known RSA public key. More...
void | br_x509_knownkey_init_ec (br_x509_knownkey_context *ctx, const br_ec_public_key *pk, unsigned usages)
| Initialize a "known key" X.509 engine with a known EC public key. More...
void | br_x509_minimal_init (br_x509_minimal_context *ctx, const br_hash_class *dn_hash_impl, const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num)
| Initialise a "minimal" X.509 engine. More...
static void | br_x509_minimal_set_hash (br_x509_minimal_context *ctx, int id, const br_hash_class *impl)
| Set a supported hash function in an X.509 "minimal" engine. More...
static void | br_x509_minimal_set_rsa (br_x509_minimal_context *ctx, br_rsa_pkcs1_vrfy irsa)
| Set a RSA signature verification implementation in the X.509 "minimal" engine. More...
static void | br_x509_minimal_set_ecdsa (br_x509_minimal_context *ctx, const br_ec_impl *iec, br_ecdsa_vrfy iecdsa)
| Set a ECDSA signature verification implementation in the X.509 "minimal" engine. More...
void | br_x509_minimal_init_full (br_x509_minimal_context *ctx, const br_x509_trust_anchor *trust_anchors, size_t trust_anchors_num)
| Initialise a "minimal" X.509 engine with default algorithms. More...
static void | br_x509_minimal_set_time (br_x509_minimal_context *ctx, uint32_t days, uint32_t seconds)
| Set the validation time for the X.509 "minimal" engine. More...
static void | br_x509_minimal_set_minrsa (br_x509_minimal_context *ctx, int byte_length)
| Set the minimal acceptable length for RSA keys (X.509 "minimal" engine). More...
static void | br_x509_minimal_set_name_elements (br_x509_minimal_context *ctx, br_name_element *elts, size_t num_elts)
| Set the name elements to gather. More...
void | br_x509_decoder_init (br_x509_decoder_context *ctx, void(*append_dn)(void *ctx, const void *buf, size_t len), void *append_dn_ctx)
| Initialise an X.509 decoder context for processing a new certificate. More...
void | br_x509_decoder_push (br_x509_decoder_context *ctx, const void *data, size_t len)
| Push some certificate bytes into a decoder context. More...
static br_x509_pkey * | br_x509_decoder_get_pkey (br_x509_decoder_context *ctx)
| Obtain the decoded public key. More...
static int | br_x509_decoder_last_error (br_x509_decoder_context *ctx)
| Get decoder error status. More...
static int | br_x509_decoder_isCA (br_x509_decoder_context *ctx)
| Get the "isCA" flag from an X.509 decoder context. More...
static int | br_x509_decoder_get_signer_key_type (br_x509_decoder_context *ctx)
| Get the issuing CA key type (type of algorithm used to sign the decoded certificate). More...
static int | br_x509_decoder_get_signer_hash_id (br_x509_decoder_context *ctx)
| Get the identifier for the hash function used to sign the decoded certificate. More...
void | br_skey_decoder_init (br_skey_decoder_context *ctx)
| Initialise a private key decoder context. More...
void | br_skey_decoder_push (br_skey_decoder_context *ctx, const void *data, size_t len)
| Push some data bytes into a private key decoder context. More...
static int | br_skey_decoder_last_error (const br_skey_decoder_context *ctx)
| Get the decoding status for a private key. More...
static int | br_skey_decoder_key_type (const br_skey_decoder_context *ctx)
| Get the decoded private key type. More...
static const br_rsa_private_key * | br_skey_decoder_get_rsa (const br_skey_decoder_context *ctx)
| Get the decoded RSA private key. More...
static const br_ec_private_key * | br_skey_decoder_get_ec (const br_skey_decoder_context *ctx)
| Get the decoded EC private key. More...
size_t | br_encode_rsa_raw_der (void *dest, const br_rsa_private_key *sk, const br_rsa_public_key *pk, const void *d, size_t dlen)
| Encode an RSA private key (raw DER format). More...
size_t | br_encode_rsa_pkcs8_der (void *dest, const br_rsa_private_key *sk, const br_rsa_public_key *pk, const void *d, size_t dlen)
| Encode an RSA private key (PKCS#8 DER format). More...
size_t | br_encode_ec_raw_der (void *dest, const br_ec_private_key *sk, const br_ec_public_key *pk)
| Encode an EC private key (raw DER format). More...
size_t | br_encode_ec_pkcs8_der (void *dest, const br_ec_private_key *sk, const br_ec_public_key *pk)
| Encode an EC private key (PKCS#8 DER format). More...

## Variables
const br_x509_class | br_x509_knownkey_vtable
| Class instance for the "known key" X.509 engine. More...
const br_x509_class | br_x509_minimal_vtable
| Class instance for the "minimal" X.509 engine. More...

## Detailed Description

# X.509 Certificate Chain Processing

An X.509 processing engine receives an X.509 chain, chunk by chunk, as received from a SSL/TLS client or server (the client receives the server's certificate chain, and the server receives the client's certificate chain if it requested a client certificate). The chain is thus injected in the engine in SSL order (end-entity first).

The engine's job is to return the public key to use for SSL/TLS. How exactly that key is obtained and verified is entirely up to the engine.

The "known key" engine returns a public key which is already known from out-of-band information (e.g. the client remembers the key from a previous connection, as in the usual SSH model). This is the simplest engine since it simply ignores the chain, thereby avoiding the need for any decoding logic.

The "minimal" engine implements minimal X.509 decoding and chain validation:

- The provided chain should validate "as is". There is no attempt at reordering, skipping or downloading extra certificates.
- X.509 v1, v2 and v3 certificates are supported.
- Trust anchors are a DN and a public key. Each anchor is either a "CA" anchor, or a non-CA.
- If the end-entity certificate matches a non-CA anchor (subject DN is equal to the non-CA name, and public key is also identical to the anchor key), then this is a direct trust case and the remaining certificates are ignored.
- Unless direct trust is applied, the chain must be verifiable up to a certificate whose issuer DN matches the DN from a "CA" trust anchor, and whose signature is verifiable against that anchor's public key. Subsequent certificates in the chain are ignored.
- The engine verifies subject/issuer DN matching, and enforces processing of Basic Constraints and Key Usage extensions. The Authority Key Identifier, Subject Key Identifier, Issuer Alt Name, Subject Directory Attribute, CRL Distribution Points, Freshest CRL, Authority Info Access and Subject Info Access extensions are ignored. The Subject Alt Name is decoded for the end-entity certificate under some conditions (see below). Other extensions are ignored if non-critical, or imply chain rejection if critical.
- The Subject Alt Name extension is parsed for names of type `dNSName` when decoding the end-entity certificate, and only if there is a server name to match. If there is no SAN extension, then the Common Name from the subjectDN is used. That name matching is case-insensitive and honours a single starting wildcard (i.e. if the name in the certificate starts with "`*.`" then this matches any word as first element). Note: this name matching is performed also in the "direct trust" model.
- DN matching is byte-to-byte equality (a future version might include some limited processing for case-insensitive matching and whitespace normalisation).
- Successful validation produces a public key type but also a set of allowed usages (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`). The caller is responsible for checking that the key type and usages are compatible with the expected values (e.g. with the selected cipher suite, when the client validates the server's certificate).

Important caveats:

- The "minimal" engine does not check revocation status. The relevant extensions are ignored, and CRL or OCSP responses are not gathered or checked.
- The "minimal" engine does not currently support Name Constraints (some basic functionality to handle sub-domains may be added in a later version).
- The decoder is not "validating" in the sense that it won't reject some certificates with invalid field values when these fields are not actually processed.

## Macro Definition Documentation

## ◆ BR_ENCODE_PEM_EC_RAW

#define BR_ENCODE_PEM_EC_RAW "EC PRIVATE KEY"

PEM banner for EC private key (raw).

## ◆ BR_ENCODE_PEM_PKCS8

#define BR_ENCODE_PEM_PKCS8 "PRIVATE KEY"

PEM banner for an RSA or EC private key in PKCS#8 format.

## ◆ BR_ENCODE_PEM_RSA_RAW

#define BR_ENCODE_PEM_RSA_RAW "RSA PRIVATE KEY"

PEM banner for RSA private key (raw).

## ◆ BR_ERR_X509_BAD_BOOLEAN

#define BR_ERR_X509_BAD_BOOLEAN 45

X.509 status: decoding error: BOOLEAN value has invalid length.

## ◆ BR_ERR_X509_BAD_DN

#define BR_ERR_X509_BAD_DN 47

X.509 status: invalid distinguished name.

## ◆ BR_ERR_X509_BAD_SERVER_NAME

#define BR_ERR_X509_BAD_SERVER_NAME 56

X.509 status: expected server name was not found in the chain.

## ◆ BR_ERR_X509_BAD_SIGNATURE

#define BR_ERR_X509_BAD_SIGNATURE 52

X.509 status: signature is invalid.

## ◆ BR_ERR_X509_BAD_TAG_CLASS

#define BR_ERR_X509_BAD_TAG_CLASS 37

X.509 status: decoding error: unsupported tag class (application or private).

## ◆ BR_ERR_X509_BAD_TAG_VALUE

#define BR_ERR_X509_BAD_TAG_VALUE 38

X.509 status: decoding error: unsupported tag value.

## ◆ BR_ERR_X509_BAD_TIME

#define BR_ERR_X509_BAD_TIME 48

X.509 status: invalid date/time representation.

## ◆ BR_ERR_X509_CRITICAL_EXTENSION

#define BR_ERR_X509_CRITICAL_EXTENSION 57

X.509 status: unknown critical extension in certificate.

## ◆ BR_ERR_X509_DN_MISMATCH

#define BR_ERR_X509_DN_MISMATCH 55

X.509 status: issuer/subject DN mismatch in the chain.

## ◆ BR_ERR_X509_EMPTY_CHAIN

#define BR_ERR_X509_EMPTY_CHAIN 35

X.509 status: empty certificate chain (no certificate at all).

## ◆ BR_ERR_X509_EXPIRED

#define BR_ERR_X509_EXPIRED 54

X.509 status: certificate is expired or not yet valid.

## ◆ BR_ERR_X509_EXTRA_ELEMENT

#define BR_ERR_X509_EXTRA_ELEMENT 40

X.509 status: decoding error: extraneous element.

## ◆ BR_ERR_X509_FORBIDDEN_KEY_USAGE

#define BR_ERR_X509_FORBIDDEN_KEY_USAGE 59

X.509 status: Key Usage extension prohibits intended usage.

## ◆ BR_ERR_X509_INDEFINITE_LENGTH

#define BR_ERR_X509_INDEFINITE_LENGTH 39

X.509 status: decoding error: indefinite length.

## ◆ BR_ERR_X509_INNER_TRUNC

#define BR_ERR_X509_INNER_TRUNC 36

X.509 status: decoding error: inner element extends beyond outer element size.

## ◆ BR_ERR_X509_INVALID_VALUE

#define BR_ERR_X509_INVALID_VALUE 33

X.509 status: invalid value in an ASN.1 structure.

## ◆ BR_ERR_X509_LIMIT_EXCEEDED

#define BR_ERR_X509_LIMIT_EXCEEDED 50

X.509 status: key or signature size exceeds internal limits.

## ◆ BR_ERR_X509_NOT_CA

#define BR_ERR_X509_NOT_CA 58

X.509 status: not a CA, or path length constraint violation.

## ◆ BR_ERR_X509_NOT_CONSTRUCTED

#define BR_ERR_X509_NOT_CONSTRUCTED 42

X.509 status: decoding error: expected constructed element, but is primitive.

## ◆ BR_ERR_X509_NOT_PRIMITIVE

#define BR_ERR_X509_NOT_PRIMITIVE 43

X.509 status: decoding error: expected primitive element, but is constructed.

## ◆ BR_ERR_X509_NOT_TRUSTED

#define BR_ERR_X509_NOT_TRUSTED 62

X.509 status: chain could not be linked to a trust anchor.

## ◆ BR_ERR_X509_OK

#define BR_ERR_X509_OK 32

X.509 status: validation was successful; this is not actually an error.

## ◆ BR_ERR_X509_OVERFLOW

#define BR_ERR_X509_OVERFLOW 46

X.509 status: decoding error: value is off-limits.

## ◆ BR_ERR_X509_PARTIAL_BYTE

#define BR_ERR_X509_PARTIAL_BYTE 44

X.509 status: decoding error: BIT STRING length is not multiple of 8.

## ◆ BR_ERR_X509_TIME_UNKNOWN

#define BR_ERR_X509_TIME_UNKNOWN 53

X.509 status: validation time is unknown.

## ◆ BR_ERR_X509_TRUNCATED

#define BR_ERR_X509_TRUNCATED 34

X.509 status: truncated certificate.

## ◆ BR_ERR_X509_UNEXPECTED

#define BR_ERR_X509_UNEXPECTED 41

X.509 status: decoding error: unexpected element.

## ◆ BR_ERR_X509_UNSUPPORTED

#define BR_ERR_X509_UNSUPPORTED 49

X.509 status: certificate contains unsupported features that cannot be ignored.

## ◆ BR_ERR_X509_WEAK_PUBLIC_KEY

#define BR_ERR_X509_WEAK_PUBLIC_KEY 60

X.509 status: public key found in certificate is too small.

## ◆ BR_ERR_X509_WRONG_KEY_TYPE

#define BR_ERR_X509_WRONG_KEY_TYPE 51

X.509 status: key type does not match that which was expected.

## ◆ BR_KEYTYPE_EC

#define BR_KEYTYPE_EC 2

Key type: algorithm is EC.

## ◆ BR_KEYTYPE_KEYX

#define BR_KEYTYPE_KEYX 0x10

Key type: usage is "key exchange".

This value is combined (with bitwise OR) with the algorithm (`BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`) when informing the X.509 validation engine that it should find a public key of that type, fit for key exchanges (e.g. `TLS_RSA_*` and `TLS_ECDH_*` cipher suites).

## ◆ BR_KEYTYPE_RSA

#define BR_KEYTYPE_RSA 1

Key type: algorithm is RSA.

## ◆ BR_KEYTYPE_SIGN

#define BR_KEYTYPE_SIGN 0x20

Key type: usage is "signature".

This value is combined (with bitwise OR) with the algorithm (`BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`) when informing the X.509 validation engine that it should find a public key of that type, fit for signatures (e.g. `TLS_ECDHE_*` cipher suites).

## ◆ BR_X509_TA_CA

#define BR_X509_TA_CA 0x0001

Trust anchor flag: CA.

A "CA" anchor is deemed fit to verify signatures on certificates. A "non-CA" anchor is accepted only for direct trust (server's certificate name and key match the anchor).

## Function Documentation

## ◆ br_encode_ec_pkcs8_der()

size_t br_encode_ec_pkcs8_der | ( | void * | dest,
|  | const br_ec_private_key * | sk,
|  | const br_ec_public_key * | pk
| ) |  |

Encode an EC private key (PKCS#8 DER format).

This function encodes the provided key into the PKCS#8 format (RFC 5958, type `OneAsymmetricKey`). The curve is identified by an OID provided as parameters to the `privateKeyAlgorithm` field. The private key value (contents of the `privateKey` field) contains the DER encoding of the `ECPrivateKey` type defined in RFC 5915, without the `parameters` field (since they would be redundant with the information in `privateKeyAlgorithm`).

The private key is provided in `sk`, the public key being `pk`. If `pk` is not `NULL`, then the encoded public key is included in the `publicKey` field of the private key value (but not in the `publicKey` field of the PKCS#8 `OneAsymmetricKey` wrapper).

If `dest` is not `NULL`, then the encoded key is written at that address, and the encoded length (in bytes) is returned. If `dest` is `NULL`, then nothing is written, but the encoded length is still computed and returned.

If the key cannot be encoded (e.g. because there is no known OBJECT IDENTIFIER for the used curve), then 0 is returned.

Parameters

  dest | the destination buffer (or `NULL`).
  sk | the EC private key.
  pk | the EC public key (or `NULL`).

Returns
  the encoded key length (in bytes), or 0.

## ◆ br_encode_ec_raw_der()

size_t br_encode_ec_raw_der | ( | void * | dest,
|  | const br_ec_private_key * | sk,
|  | const br_ec_public_key * | pk
| ) |  |

Encode an EC private key (raw DER format).

This function encodes the provided key into the "raw" format specified in RFC 5915 (type `ECPrivateKey`), with DER encoding rules.

The private key is provided in `sk`, the public key being `pk`. If `pk` is `NULL`, then the encoded key will not include the public key in its `publicKey` field (which is nominally optional).

If `dest` is not `NULL`, then the encoded key is written at that address, and the encoded length (in bytes) is returned. If `dest` is `NULL`, then nothing is written, but the encoded length is still computed and returned.

If the key cannot be encoded (e.g. because there is no known OBJECT IDENTIFIER for the used curve), then 0 is returned.

Parameters

  dest | the destination buffer (or `NULL`).
  sk | the EC private key.
  pk | the EC public key (or `NULL`).

Returns
  the encoded key length (in bytes), or 0.

## ◆ br_encode_rsa_pkcs8_der()

size_t br_encode_rsa_pkcs8_der | ( | void * | dest,
|  | const br_rsa_private_key * | sk,
|  | const br_rsa_public_key * | pk,
|  | const void * | d,
|  | size_t | dlen
| ) |  |

Encode an RSA private key (PKCS#8 DER format).

This function encodes the provided key into the PKCS#8 format (RFC 5958, type `OneAsymmetricKey`). It wraps around the "raw DER" format for the RSA key, as implemented by `br_encode_rsa_raw_der()`.

The key elements are:

- `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`)
- `pk`: the public key (`n` and `e`)
- `d` (size: `dlen` bytes): the private exponent

The public key elements, and the private exponent `d`, can be recomputed from the private key (see `br_rsa_compute_modulus()`, `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`).

If `dest` is not `NULL`, then the encoded key is written at that address, and the encoded length (in bytes) is returned. If `dest` is `NULL`, then nothing is written, but the encoded length is still computed and returned.

Parameters

  dest | the destination buffer (or `NULL`).
  sk | the RSA private key.
  pk | the RSA public key.
  d | the RSA private exponent.
  dlen | the RSA private exponent length (in bytes).

Returns
  the encoded key length (in bytes).

## ◆ br_encode_rsa_raw_der()

size_t br_encode_rsa_raw_der | ( | void * | dest,
|  | const br_rsa_private_key * | sk,
|  | const br_rsa_public_key * | pk,
|  | const void * | d,
|  | size_t | dlen
| ) |  |

Encode an RSA private key (raw DER format).

This function encodes the provided key into the "raw" format specified in PKCS#1 (RFC 8017, Appendix C, type `RSAPrivateKey`), with DER encoding rules.

The key elements are:

- `sk`: the private key (`p`, `q`, `dp`, `dq` and `iq`)
- `pk`: the public key (`n` and `e`)
- `d` (size: `dlen` bytes): the private exponent

The public key elements, and the private exponent `d`, can be recomputed from the private key (see `br_rsa_compute_modulus()`, `br_rsa_compute_pubexp()` and `br_rsa_compute_privexp()`).

If `dest` is not `NULL`, then the encoded key is written at that address, and the encoded length (in bytes) is returned. If `dest` is `NULL`, then nothing is written, but the encoded length is still computed and returned.

Parameters

  dest | the destination buffer (or `NULL`).
  sk | the RSA private key.
  pk | the RSA public key.
  d | the RSA private exponent.
  dlen | the RSA private exponent length (in bytes).

Returns
  the encoded key length (in bytes).

## ◆ br_skey_decoder_get_ec()

static const br_ec_private_key * br_skey_decoder_get_ec | ( | const br_skey_decoder_context * | ctx | ) |
| inline static

Get the decoded EC private key.

This function returns `NULL` if the decoding failed, or is not finished, or the key is not EC. The returned pointer references structures within the context that can become invalid if the context is reused or released.

Parameters

  ctx | key decoder context.

Returns
  decoded EC private key, or `NULL`.

## ◆ br_skey_decoder_get_rsa()

static const br_rsa_private_key * br_skey_decoder_get_rsa | ( | const br_skey_decoder_context * | ctx | ) |
| inline static

Get the decoded RSA private key.

This function returns `NULL` if the decoding failed, or is not finished, or the key is not RSA. The returned pointer references structures within the context that can become invalid if the context is reused or released.

Parameters

  ctx | key decoder context.

Returns
  decoded RSA private key, or `NULL`.

## ◆ br_skey_decoder_init()

void br_skey_decoder_init | ( | br_skey_decoder_context * | ctx | ) |

Initialise a private key decoder context.

Parameters

  ctx | key decoder context to initialise.

## ◆ br_skey_decoder_key_type()

static int br_skey_decoder_key_type | ( | const br_skey_decoder_context * | ctx | ) |
| inline static

Get the decoded private key type.

Private key type is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. If decoding is not finished or failed, then 0 is returned.

Parameters

  ctx | key decoder context.

Returns
  decoded private key type, or 0.

## ◆ br_skey_decoder_last_error()

static int br_skey_decoder_last_error | ( | const br_skey_decoder_context * | ctx | ) |
| inline static

Get the decoding status for a private key.

Decoding status is 0 on success, or a non-zero error code. If the decoding is unfinished when this function is called, then the status code `BR_ERR_X509_TRUNCATED` is returned.

Parameters

  ctx | key decoder context.

Returns
  0 on successful decoding, or a non-zero error code.

## ◆ br_skey_decoder_push()

void br_skey_decoder_push | ( | br_skey_decoder_context * | ctx,
|  | const void * | data,
|  | size_t | len
| ) |  |

Push some data bytes into a private key decoder context.

If `len` is non-zero, then that many data bytes, starting at address `data`, are pushed into the decoder.

Parameters

  ctx | key decoder context.
  data | private key data chunk.
  len | private key data chunk length (in bytes).

## ◆ br_x509_decoder_get_pkey()

static br_x509_pkey * br_x509_decoder_get_pkey | ( | br_x509_decoder_context * | ctx | ) |
| inline static

Obtain the decoded public key.

Returned value is a pointer to a structure internal to the decoder context; releasing or reusing the decoder context invalidates that structure.

If decoding was not finished, or failed, then `NULL` is returned.

Parameters

  ctx | X.509 decoder context.

Returns
  the public key, or `NULL` on unfinished/error.

## ◆ br_x509_decoder_get_signer_hash_id()

static int br_x509_decoder_get_signer_hash_id | ( | br_x509_decoder_context * | ctx | ) |
| inline static

Get the identifier for the hash function used to sign the decoded certificate.

This is 0 if the hash function was not recognised.

Parameters

  ctx | X.509 decoder context.

Returns
  the signature hash function identifier.

## ◆ br_x509_decoder_get_signer_key_type()

static int br_x509_decoder_get_signer_key_type | ( | br_x509_decoder_context * | ctx | ) |
| inline static

Get the issuing CA key type (type of algorithm used to sign the decoded certificate).

This is `BR_KEYTYPE_RSA` or `BR_KEYTYPE_EC`. The value 0 is returned if the signature type was not recognised.

Parameters

  ctx | X.509 decoder context.

Returns
  the issuing CA key type.

## ◆ br_x509_decoder_init()

void br_x509_decoder_init | ( | br_x509_decoder_context * | ctx,
|  | void(*)(void *ctx, const void *buf, size_t len) | append_dn,
|  | void * | append_dn_ctx
| ) |  |

Initialise an X.509 decoder context for processing a new certificate.

The `append_dn()` callback (with opaque context `append_dn_ctx`) will be invoked to receive, chunk by chunk, the certificate's subject DN. If `append_dn` is `0` then the subject DN will be ignored.

Parameters

  ctx | X.509 decoder context to initialise.
  append_dn | DN receiver callback (or `0`).
  append_dn_ctx | context for the DN receiver callback.

## ◆ br_x509_decoder_isCA()

static int br_x509_decoder_isCA | ( | br_x509_decoder_context * | ctx | ) |
| inline static

Get the "isCA" flag from an X.509 decoder context.

This flag is set if the decoded certificate claims to be a CA through a Basic Constraints extension. This flag should not be read before decoding completed successfully.

Parameters

  ctx | X.509 decoder context.

Returns
  the "isCA" flag.

## ◆ br_x509_decoder_last_error()

static int br_x509_decoder_last_error | ( | br_x509_decoder_context * | ctx | ) |
| inline static

Get decoder error status.

If no error was reported yet but the certificate decoding is not finished, then the error code is `BR_ERR_X509_TRUNCATED`. If decoding was successful, then 0 is returned.

Parameters

  ctx | X.509 decoder context.

Returns
  0 on successful decoding, or a non-zero error code.

## ◆ br_x509_decoder_push()

void br_x509_decoder_push | ( | br_x509_decoder_context * | ctx,
|  | const void * | data,
|  | size_t | len
| ) |  |

Push some certificate bytes into a decoder context.

If `len` is non-zero, then that many bytes are pushed, from address `data`, into the provided decoder context.

Parameters

  ctx | X.509 decoder context.
  data | certificate data chunk.
  len | certificate data chunk length (in bytes).

## ◆ br_x509_knownkey_init_ec()

void br_x509_knownkey_init_ec | ( | br_x509_knownkey_context * | ctx,
|  | const br_ec_public_key * | pk,
|  | unsigned | usages
| ) |  |

Initialize a "known key" X.509 engine with a known EC public key.

The `usages` parameter indicates the allowed key usages for that key (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`).

The provided pointers are linked in, not copied, so they must remain valid while the public key may be in usage.

Parameters

  ctx | context to initialise.
  pk | known public key.
  usages | allowed key usages.

## ◆ br_x509_knownkey_init_rsa()

void br_x509_knownkey_init_rsa | ( | br_x509_knownkey_context * | ctx,
|  | const br_rsa_public_key * | pk,
|  | unsigned | usages
| ) |  |

Initialize a "known key" X.509 engine with a known RSA public key.

The `usages` parameter indicates the allowed key usages for that key (`BR_KEYTYPE_KEYX` and/or `BR_KEYTYPE_SIGN`).

The provided pointers are linked in, not copied, so they must remain valid while the public key may be in usage.

Parameters

  ctx | context to initialise.
  pk | known public key.
  usages | allowed key usages.

## ◆ br_x509_minimal_init()

void br_x509_minimal_init | ( | br_x509_minimal_context * | ctx,
|  | const br_hash_class * | dn_hash_impl,
|  | const br_x509_trust_anchor * | trust_anchors,
|  | size_t | trust_anchors_num
| ) |  |

Initialise a "minimal" X.509 engine.

The `dn_hash_impl` parameter shall be a hash function internally used to match X.500 names (subject/issuer DN, and anchor names). Any standard hash function may be used, but a collision-resistant hash function is advised.

After initialization, some implementations for signature verification (hash functions and signature algorithms) MUST be added.

Parameters

  ctx | context to initialise.
  dn_hash_impl | hash function for DN comparisons.
  trust_anchors | trust anchors.
  trust_anchors_num | number of trust anchors.

## ◆ br_x509_minimal_init_full()

void br_x509_minimal_init_full | ( | br_x509_minimal_context * | ctx,
|  | const br_x509_trust_anchor * | trust_anchors,
|  | size_t | trust_anchors_num
| ) |  |

Initialise a "minimal" X.509 engine with default algorithms.

This function performs the same job as `br_x509_minimal_init()`, but also sets implementations for RSA, ECDSA, and the standard hash functions.

Parameters

  ctx | context to initialise.
  trust_anchors | trust anchors.
  trust_anchors_num | number of trust anchors.

## ◆ br_x509_minimal_set_ecdsa()

static void br_x509_minimal_set_ecdsa | ( | br_x509_minimal_context * | ctx,
|  | const br_ec_impl * | iec,
|  | br_ecdsa_vrfy | iecdsa
| ) |  |
| inline static

Set a ECDSA signature verification implementation in the X.509 "minimal" engine.

Once initialised (with `br_x509_minimal_init()`), the context must be configured with the signature verification implementations that it is supposed to support.

If `iecdsa` is `0`, then this call disables ECDSA support; in that case, `iec` may be `NULL`. Otherwise, `iecdsa` MUST point to a function that verifies ECDSA signatures with format "asn1", and it will use `iec` as underlying elliptic curve support.

Parameters

  ctx | validation context.
  iec | elliptic curve implementation (or `NULL`).
  iecdsa | ECDSA implementation (or `0`).

## ◆ br_x509_minimal_set_hash()

static void br_x509_minimal_set_hash | ( | br_x509_minimal_context * | ctx,
|  | int | id,
|  | const br_hash_class * | impl
| ) |  |
| inline static

Set a supported hash function in an X.509 "minimal" engine.

Hash functions are used with signature verification algorithms. Once initialised (with `br_x509_minimal_init()`), the context must be configured with the hash functions it shall support for that purpose. The hash function identifier MUST be one of the standard hash function identifiers (1 to 6, for MD5, SHA-1, SHA-224, SHA-256, SHA-384 and SHA-512).

If `impl` is `NULL`, this removes support for the designated hash function.

Parameters

  ctx | validation context.
  id | hash function identifier (from 1 to 6).
  impl | hash function implementation (or `NULL`).

## ◆ br_x509_minimal_set_minrsa()

static void br_x509_minimal_set_minrsa | ( | br_x509_minimal_context * | ctx,
|  | int | byte_length
| ) |  |
| inline static

Set the minimal acceptable length for RSA keys (X.509 "minimal" engine).

The RSA key length is expressed in bytes. The default minimum key length is 128 bytes, corresponding to 1017 bits. RSA keys shorter than the configured length will be rejected, implying validation failure. This setting applies to keys extracted from certificates (both end-entity, and intermediate CA) but not to "CA" trust anchors.

Parameters

  ctx | validation context.
  byte_length | minimum RSA key length, in bytes (not bits).

## ◆ br_x509_minimal_set_name_elements()

static void br_x509_minimal_set_name_elements | ( | br_x509_minimal_context * | ctx,
|  | br_name_element * | elts,
|  | size_t | num_elts
| ) |  |
| inline static

Set the name elements to gather.

The provided array is linked in the context. The elements are gathered from the EE certificate. If the same element type is requested several times, then the relevant structures will be filled in the order the matching values are encountered in the certificate.

Parameters

  ctx | validation context.
  elts | array of name element structures to fill.
  num_elts | number of name element structures to fill.

## ◆ br_x509_minimal_set_rsa()

static void br_x509_minimal_set_rsa | ( | br_x509_minimal_context * | ctx,
|  | br_rsa_pkcs1_vrfy | irsa
| ) |  |
| inline static

Set a RSA signature verification implementation in the X.509 "minimal" engine.

Once initialised (with `br_x509_minimal_init()`), the context must be configured with the signature verification implementations that it is supposed to support. If `irsa` is `0`, then the RSA support is disabled.

Parameters

  ctx | validation context.
  irsa | RSA signature verification implementation (or `0`).

## ◆ br_x509_minimal_set_time()

static void br_x509_minimal_set_time | ( | br_x509_minimal_context * | ctx,
|  | uint32_t | days,
|  | uint32_t | seconds
| ) |  |
| inline static

Set the validation time for the X.509 "minimal" engine.

The validation time is set as two 32-bit integers, for days and seconds since a fixed epoch:

- Days are counted in a proleptic Gregorian calendar since January 1st, 0 AD. Year "0 AD" is the one that preceded "1 AD"; it is also traditionally known as "1 BC".
- Seconds are counted since midnight, from 0 to 86400 (a count of 86400 is possible only if a leap second happened).

The validation date and time is understood in the UTC time zone.

If the validation date and time are not explicitly set, but BearSSL was compiled with support for the system clock on the underlying platform, then the current time will automatically be used. Otherwise, not setting the validation date and time implies a validation failure (except in case of direct trust of the EE key).

Parameters

  ctx | validation context.
  days | days since January 1st, 0 AD (Gregorian calendar).
  seconds | seconds since midnight (0 to 86400).

## Variable Documentation

## ◆ br_x509_knownkey_vtable

const br_x509_class br_x509_knownkey_vtable
| extern

Class instance for the "known key" X.509 engine.

## ◆ br_x509_minimal_vtable

const br_x509_class br_x509_minimal_vtable
| extern

Class instance for the "minimal" X.509 engine.