Crypt-Bear

 view release on metacpan or  search on metacpan

include/bearssl_x509.h  view on Meta::CPAN

static inline int
br_x509_decoder_isCA(br_x509_decoder_context *ctx)
{
	return ctx->isCA;
}

/**
 * \brief 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.
 *
 * \param ctx   X.509 decoder context.
 * \return  the issuing CA key type.
 */
static inline int
br_x509_decoder_get_signer_key_type(br_x509_decoder_context *ctx)
{
	return ctx->signer_key_type;
}

/**
 * \brief Get the identifier for the hash function used to sign the decoded
 * certificate.
 *
 * This is 0 if the hash function was not recognised.
 *
 * \param ctx   X.509 decoder context.
 * \return  the signature hash function identifier.
 */
static inline int
br_x509_decoder_get_signer_hash_id(br_x509_decoder_context *ctx)
{
	return ctx->signer_hash_id;
}

/**
 * \brief Type for an X.509 certificate (DER-encoded).
 */
typedef struct {
	/** \brief The DER-encoded certificate data. */
	unsigned char *data;
	/** \brief The DER-encoded certificate length (in bytes). */
	size_t data_len;
} br_x509_certificate;

/**
 * \brief Private key decoder context.
 *
 * The private key decoder recognises RSA and EC private keys, either in
 * their raw, DER-encoded format, or wrapped in an unencrypted PKCS#8
 * archive (again DER-encoded).
 *
 * Structure contents are opaque and shall not be accessed directly.
 */
typedef struct {
#ifndef BR_DOXYGEN_IGNORE
	/* Structure for returning the private key. */
	union {
		br_rsa_private_key rsa;
		br_ec_private_key ec;
	} key;

	/* CPU for the T0 virtual machine. */
	struct {
		uint32_t *dp;
		uint32_t *rp;
		const unsigned char *ip;
	} cpu;
	uint32_t dp_stack[32];
	uint32_t rp_stack[32];
	int err;

	/* Private key data chunk. */
	const unsigned char *hbuf;
	size_t hlen;

	/* The pad serves as destination for various operations. */
	unsigned char pad[256];

	/* Decoded key type; 0 until decoding is complete. */
	unsigned char key_type;

	/* Buffer for the private key elements. It shall be large enough
	   to accommodate all elements for a RSA-4096 private key (roughly
	   five 2048-bit integers, possibly a bit more). */
	unsigned char key_data[3 * BR_X509_BUFSIZE_SIG];
#endif
} br_skey_decoder_context;

/**
 * \brief Initialise a private key decoder context.
 *
 * \param ctx   key decoder context to initialise.
 */
void br_skey_decoder_init(br_skey_decoder_context *ctx);

/**
 * \brief 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.
 *
 * \param ctx    key decoder context.
 * \param data   private key data chunk.
 * \param len    private key data chunk length (in bytes).
 */
void br_skey_decoder_push(br_skey_decoder_context *ctx,
	const void *data, size_t len);

/**
 * \brief 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.
 *
 * \param ctx   key decoder context.
 * \return  0 on successful decoding, or a non-zero error code.
 */
static inline int
br_skey_decoder_last_error(const br_skey_decoder_context *ctx)
{
	if (ctx->err != 0) {
		return ctx->err;
	}
	if (ctx->key_type == 0) {
		return BR_ERR_X509_TRUNCATED;
	}
	return 0;
}

/**
 * \brief 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.
 *
 * \param ctx   key decoder context.
 * \return  decoded private key type, or 0.
 */
static inline int
br_skey_decoder_key_type(const br_skey_decoder_context *ctx)
{
	if (ctx->err == 0) {
		return ctx->key_type;
	} else {
		return 0;
	}
}

/**
 * \brief 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.
 *
 * \param ctx   key decoder context.
 * \return  decoded RSA private key, or `NULL`.
 */
static inline const br_rsa_private_key *
br_skey_decoder_get_rsa(const br_skey_decoder_context *ctx)
{
	if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_RSA) {
		return &ctx->key.rsa;
	} else {
		return NULL;
	}
}

/**
 * \brief 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.
 *
 * \param ctx   key decoder context.
 * \return  decoded EC private key, or `NULL`.
 */
static inline const br_ec_private_key *
br_skey_decoder_get_ec(const br_skey_decoder_context *ctx)
{
	if (ctx->err == 0 && ctx->key_type == BR_KEYTYPE_EC) {
		return &ctx->key.ec;
	} else {
		return NULL;
	}
}

/**
 * \brief 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.
 *
 * \param dest   the destination buffer (or `NULL`).
 * \param sk     the RSA private key.
 * \param pk     the RSA public key.
 * \param d      the RSA private exponent.
 * \param dlen   the RSA private exponent length (in bytes).
 * \return  the encoded key length (in bytes).
 */
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);

/**
 * \brief 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.
 *
 * \param dest   the destination buffer (or `NULL`).
 * \param sk     the RSA private key.
 * \param pk     the RSA public key.
 * \param d      the RSA private exponent.
 * \param dlen   the RSA private exponent length (in bytes).
 * \return  the encoded key length (in bytes).
 */
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);

/**
 * \brief 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.
 *
 * \param dest   the destination buffer (or `NULL`).
 * \param sk     the EC private key.
 * \param pk     the EC public key (or `NULL`).
 * \return  the encoded key length (in bytes), or 0.
 */
size_t br_encode_ec_raw_der(void *dest,
	const br_ec_private_key *sk, const br_ec_public_key *pk);

/**
 * \brief 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.
 *
 * \param dest   the destination buffer (or `NULL`).
 * \param sk     the EC private key.
 * \param pk     the EC public key (or `NULL`).
 * \return  the encoded key length (in bytes), or 0.
 */
size_t br_encode_ec_pkcs8_der(void *dest,
	const br_ec_private_key *sk, const br_ec_public_key *pk);

/**
 * \brief PEM banner for RSA private key (raw).
 */
#define BR_ENCODE_PEM_RSA_RAW      "RSA PRIVATE KEY"

/**
 * \brief PEM banner for EC private key (raw).
 */
#define BR_ENCODE_PEM_EC_RAW       "EC PRIVATE KEY"

/**
 * \brief PEM banner for an RSA or EC private key in PKCS#8 format.
 */
#define BR_ENCODE_PEM_PKCS8        "PRIVATE KEY"

#ifdef __cplusplus
}
#endif

#endif



( run in 0.626 second using v1.01-cache-2.11-cpan-5a3173703d6 )