+int br_ssl_key_export(br_ssl_engine_context *cc,
+ void *dst, size_t len, const char *label,
+ const void *context, size_t context_len);
+
+/*
+ * Pre-declaration for the SSL client context.
+ */
+typedef struct br_ssl_client_context_ br_ssl_client_context;
+
+/**
+ * \brief Type for the client certificate, if requested by the server.
+ */
+typedef struct {
+ /**
+ * \brief Authentication type.
+ *
+ * This is either `BR_AUTH_RSA` (RSA signature), `BR_AUTH_ECDSA`
+ * (ECDSA signature), or `BR_AUTH_ECDH` (static ECDH key exchange).
+ */
+ int auth_type;
+
+ /**
+ * \brief Hash function for computing the CertificateVerify.
+ *
+ * This is the symbolic identifier for the hash function that
+ * will be used to produce the hash of handshake messages, to
+ * be signed into the CertificateVerify. For full static ECDH
+ * (client and server certificates are both EC in the same
+ * curve, and static ECDH is used), this value is set to -1.
+ *
+ * Take care that with TLS 1.0 and 1.1, that value MUST match
+ * the protocol requirements: value must be 0 (MD5+SHA-1) for
+ * a RSA signature, or 2 (SHA-1) for an ECDSA signature. Only
+ * TLS 1.2 allows for other hash functions.
+ */
+ int hash_id;
+
+ /**
+ * \brief Certificate chain to send to the server.
+ *
+ * This is an array of `br_x509_certificate` objects, each
+ * normally containing a DER-encoded certificate. The client
+ * code does not try to decode these elements. If there is no
+ * chain to send to the server, then this pointer shall be
+ * set to `NULL`.
+ */
+ const br_x509_certificate *chain;
+
+ /**
+ * \brief Certificate chain length (number of certificates).
+ *
+ * If there is no chain to send to the server, then this value
+ * shall be set to 0.
+ */
+ size_t chain_len;
+
+} br_ssl_client_certificate;
+
+/*
+ * Note: the constants below for signatures match the TLS constants.
+ */
+
+/** \brief Client authentication type: static ECDH. */
+#define BR_AUTH_ECDH 0
+/** \brief Client authentication type: RSA signature. */
+#define BR_AUTH_RSA 1
+/** \brief Client authentication type: ECDSA signature. */
+#define BR_AUTH_ECDSA 3
+
+/**
+ * \brief Class type for a certificate handler (client side).
+ *
+ * A certificate handler selects a client certificate chain to send to
+ * the server, upon explicit request from that server. It receives
+ * the list of trust anchor DN from the server, and supported types
+ * of certificates and signatures, and returns the chain to use. It
+ * is also invoked to perform the corresponding private key operation
+ * (a signature, or an ECDH computation).
+ *
+ * The SSL client engine will first push the trust anchor DN with
+ * `start_name_list()`, `start_name()`, `append_name()`, `end_name()`
+ * and `end_name_list()`. Then it will call `choose()`, to select the
+ * actual chain (and signature/hash algorithms). Finally, it will call
+ * either `do_sign()` or `do_keyx()`, depending on the algorithm choices.
+ */
+typedef struct br_ssl_client_certificate_class_ br_ssl_client_certificate_class;
+struct br_ssl_client_certificate_class_ {
+ /**
+ * \brief Context size (in bytes).
+ */
+ size_t context_size;
+
+ /**
+ * \brief Begin reception of a list of trust anchor names. This
+ * is called while parsing the incoming CertificateRequest.
+ *
+ * \param pctx certificate handler context.
+ */
+ void (*start_name_list)(const br_ssl_client_certificate_class **pctx);
+
+ /**
+ * \brief Begin reception of a new trust anchor name.
+ *
+ * The total encoded name length is provided; it is less than
+ * 65535 bytes.
+ *
+ * \param pctx certificate handler context.
+ * \param len encoded name length (in bytes).
+ */
+ void (*start_name)(const br_ssl_client_certificate_class **pctx,
+ size_t len);
+
+ /**
+ * \brief Receive some more bytes for the current trust anchor name.
+ *
+ * The provided reference (`data`) points to a transient buffer
+ * they may be reused as soon as this function returns. The chunk
+ * length (`len`) is never zero.
+ *
+ * \param pctx certificate handler context.
+ * \param data anchor name chunk.
+ * \param len anchor name chunk length (in bytes).
+ */
+ void (*append_name)(const br_ssl_client_certificate_class **pctx,
+ const unsigned char *data, size_t len);
+
+ /**
+ * \brief End current trust anchor name.
+ *
+ * This function is called when all the encoded anchor name data
+ * has been provided.
+ *
+ * \param pctx certificate handler context.
+ */
+ void (*end_name)(const br_ssl_client_certificate_class **pctx);
+
+ /**
+ * \brief End list of trust anchor names.
+ *
+ * This function is called when all the anchor names in the
+ * CertificateRequest message have been obtained.
+ *
+ * \param pctx certificate handler context.
+ */
+ void (*end_name_list)(const br_ssl_client_certificate_class **pctx);
+
+ /**
+ * \brief Select client certificate and algorithms.
+ *
+ * This callback function shall fill the provided `choices`
+ * structure with the selected algorithms and certificate chain.
+ * The `hash_id`, `chain` and `chain_len` fields must be set. If
+ * the client cannot or does not wish to send a certificate,
+ * then it shall set `chain` to `NULL` and `chain_len` to 0.
+ *
+ * The `auth_types` parameter describes the authentication types,
+ * signature algorithms and hash functions that are supported by
+ * both the client context and the server, and compatible with
+ * the current protocol version. This is a bit field with the
+ * following contents:
+ *
+ * - If RSA signatures with hash function x are supported, then
+ * bit x is set.
+ *
+ * - If ECDSA signatures with hash function x are supported,
+ * then bit 8+x is set.
+ *
+ * - If static ECDH is supported, with a RSA-signed certificate,
+ * then bit 16 is set.
+ *
+ * - If static ECDH is supported, with an ECDSA-signed certificate,
+ * then bit 17 is set.
+ *
+ * Notes:
+ *
+ * - When using TLS 1.0 or 1.1, the hash function for RSA
+ * signatures is always the special MD5+SHA-1 (id 0), and the
+ * hash function for ECDSA signatures is always SHA-1 (id 2).
+ *
+ * - When using TLS 1.2, the list of hash functions is trimmed
+ * down to include only hash functions that the client context
+ * can support. The actual server list can be obtained with
+ * `br_ssl_client_get_server_hashes()`; that list may be used
+ * to select the certificate chain to send to the server.
+ *
+ * \param pctx certificate handler context.
+ * \param cc SSL client context.
+ * \param auth_types supported authentication types and algorithms.
+ * \param choices destination structure for the policy choices.
+ */
+ void (*choose)(const br_ssl_client_certificate_class **pctx,
+ const br_ssl_client_context *cc, uint32_t auth_types,
+ br_ssl_client_certificate *choices);
+
+ /**
+ * \brief Perform key exchange (client part).
+ *
+ * This callback is invoked in case of a full static ECDH key
+ * exchange:
+ *
+ * - the cipher suite uses `ECDH_RSA` or `ECDH_ECDSA`;
+ *
+ * - the server requests a client certificate;
+ *
+ * - the client has, and sends, a client certificate that
+ * uses an EC key in the same curve as the server's key,
+ * and chooses static ECDH (the `hash_id` field in the choice
+ * structure was set to -1).
+ *
+ * In that situation, this callback is invoked to compute the
+ * client-side ECDH: the provided `data` (of length `*len` bytes)
+ * is the server's public key point (as decoded from its
+ * certificate), and the client shall multiply that point with
+ * its own private key, and write back the X coordinate of the
+ * resulting point in the same buffer, starting at offset 0.
+ * The `*len` value shall be modified to designate the actual
+ * length of the X coordinate.
+ *
+ * The callback must uphold the following:
+ *
+ * - If the input array does not have the proper length for
+ * an encoded curve point, then an error (0) shall be reported.
+ *
+ * - If the input array has the proper length, then processing
+ * MUST be constant-time, even if the data is not a valid
+ * encoded point.
+ *
+ * - This callback MUST check that the input point is valid.
+ *
+ * Returned value is 1 on success, 0 on error.
+ *
+ * \param pctx certificate handler context.
+ * \param data server public key point.
+ * \param len public key point length / X coordinate length.
+ * \return 1 on success, 0 on error.
+ */
+ uint32_t (*do_keyx)(const br_ssl_client_certificate_class **pctx,
+ unsigned char *data, size_t *len);
+
+ /**
+ * \brief Perform a signature (client authentication).
+ *
+ * This callback is invoked when a client certificate was sent,
+ * and static ECDH is not used. It shall compute a signature,
+ * using the client's private key, over the provided hash value
+ * (which is the hash of all previous handshake messages).
+ *
+ * On input, the hash value to sign is in `data`, of size
+ * `hv_len`; the involved hash function is identified by
+ * `hash_id`. The signature shall be computed and written
+ * back into `data`; the total size of that buffer is `len`
+ * bytes.
+ *
+ * This callback shall verify that the signature length does not
+ * exceed `len` bytes, and abstain from writing the signature if
+ * it does not fit.
+ *
+ * For RSA signatures, the `hash_id` may be 0, in which case
+ * this is the special header-less signature specified in TLS 1.0
+ * and 1.1, with a 36-byte hash value. Otherwise, normal PKCS#1
+ * v1.5 signatures shall be computed.
+ *
+ * For ECDSA signatures, the signature value shall use the ASN.1
+ * based encoding.
+ *
+ * Returned value is the signature length (in bytes), or 0 on error.
+ *
+ * \param pctx certificate handler context.
+ * \param hash_id hash function identifier.
+ * \param hv_len hash value length (in bytes).
+ * \param data input/output buffer (hash value, then signature).
+ * \param len total buffer length (in bytes).
+ * \return signature length (in bytes) on success, or 0 on error.
+ */
+ size_t (*do_sign)(const br_ssl_client_certificate_class **pctx,
+ int hash_id, size_t hv_len, unsigned char *data, size_t len);
+};
+
+/**
+ * \brief A single-chain RSA client certificate handler.
+ *
+ * This handler uses a single certificate chain, with a RSA
+ * signature. The list of trust anchor DN is ignored.
+ *
+ * Apart from the first field (vtable pointer), its contents are
+ * opaque and shall not be accessed directly.
+ */
+typedef struct {
+ /** \brief Pointer to vtable. */
+ const br_ssl_client_certificate_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
+ const br_x509_certificate *chain;
+ size_t chain_len;
+ const br_rsa_private_key *sk;
+ br_rsa_pkcs1_sign irsasign;
+#endif
+} br_ssl_client_certificate_rsa_context;
+
+/**
+ * \brief A single-chain EC client certificate handler.
+ *
+ * This handler uses a single certificate chain, with a RSA
+ * signature. The list of trust anchor DN is ignored.
+ *
+ * This handler may support both static ECDH, and ECDSA signatures
+ * (either usage may be selectively disabled).
+ *
+ * Apart from the first field (vtable pointer), its contents are
+ * opaque and shall not be accessed directly.
+ */
+typedef struct {
+ /** \brief Pointer to vtable. */
+ const br_ssl_client_certificate_class *vtable;
+#ifndef BR_DOXYGEN_IGNORE
+ const br_x509_certificate *chain;
+ size_t chain_len;
+ const br_ec_private_key *sk;
+ unsigned allowed_usages;
+ unsigned issuer_key_type;
+ const br_multihash_context *mhash;
+ const br_ec_impl *iec;
+ br_ecdsa_sign iecdsa;
+#endif
+} br_ssl_client_certificate_ec_context;
+
+/**
+ * \brief Context structure for a SSL client.
+ *
+ * The first field (called `eng`) is the SSL engine; all functions that
+ * work on a `br_ssl_engine_context` structure shall take as parameter
+ * a pointer to that field. The other structure fields are opaque and
+ * must not be accessed directly.
+ */
+struct br_ssl_client_context_ {
+ /**
+ * \brief The encapsulated engine context.
+ */
+ br_ssl_engine_context eng;