Crypt-Bear

 view release on metacpan or  search on metacpan

include/bearssl_pem.h  view on Meta::CPAN

 * with `br_pem_decoder_push()`. The decoder stops accepting bytes when
 * it reaches an "event", which is either the start of an object, the
 * end of an object, or a decoding error within an object.
 *
 * The `br_pem_decoder_event()` function is used to obtain the current
 * event; it also clears it, thus allowing the decoder to accept more
 * bytes. When a object start event is raised, the decoder context
 * offers the found object name (normalised to ASCII uppercase).
 *
 * When an object is reached, the caller must set an appropriate callback
 * function, which will receive (by chunks) the decoded object data.
 *
 * Since the decoder context makes no dynamic allocation, it requires
 * no explicit deallocation.
 */

/**
 * \brief PEM decoder context.
 *
 * Contents are opaque (they should not be accessed directly).
 */

include/bearssl_pem.h  view on Meta::CPAN

 *
 * \param ctx    decoder context.
 * \param data   new data bytes.
 * \param len    number of new data bytes.
 * \return  the number of bytes actually received (may be less than `len`).
 */
size_t br_pem_decoder_push(br_pem_decoder_context *ctx,
	const void *data, size_t len);

/**
 * \brief Set the receiver for decoded data.
 *
 * When an object is entered, the provided function (with opaque context
 * pointer) will be called repeatedly with successive chunks of decoded
 * data for that object. If `dest` is set to 0, then decoded data is
 * simply ignored. The receiver can be set at any time, but, in practice,
 * it should be called immediately after receiving a "start of object"
 * event.
 *
 * \param ctx        decoder context.
 * \param dest       callback for receiving decoded data.
 * \param dest_ctx   opaque context pointer for the `dest` callback.
 */
static inline void
br_pem_decoder_setdest(br_pem_decoder_context *ctx,
	void (*dest)(void *dest_ctx, const void *src, size_t len),
	void *dest_ctx)
{
	ctx->dest = dest;
	ctx->dest_ctx = dest_ctx;
}

include/bearssl_ssl.h  view on Meta::CPAN

	 *
	 *   - 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.

include/bearssl_x509.h  view on Meta::CPAN

 *   - 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

include/bearssl_x509.h  view on Meta::CPAN

	 * error codes, though other values may be possible.
	 *
	 * \param ctx   validation context.
	 * \return  0 on success, or a non-zero error code.
	 */
	unsigned (*end_chain)(const br_x509_class **ctx);

	/**
	 * \brief Get the resulting end-entity public key.
	 *
	 * The decoded public key is returned. The returned pointer
	 * may be valid only as long as the context structure is
	 * unmodified, i.e. it may cease to be valid if the context
	 * is released or reused.
	 *
	 * This function _may_ return `NULL` if the validation failed.
	 * However, returning a public key does not mean that the
	 * validation was wholly successful; some engines may return
	 * a decoded public key even if the chain did not end on a
	 * trusted anchor.
	 *
	 * If validation succeeded and `usage` is not `NULL`, then
	 * `*usage` is filled with a combination of `BR_KEYTYPE_SIGN`
	 * and/or `BR_KEYTYPE_KEYX` that specifies the validated key
	 * usage types. It is the caller's responsibility to check
	 * that value against the intended use of the public key.
	 *
	 * \param ctx   validation context.
	 * \return  the end-entity public key, or `NULL`.

include/bearssl_x509.h  view on Meta::CPAN

	 * \brief Length (in bytes) of the destination buffer.
	 *
	 * The buffer MUST NOT be smaller than 1 byte.
	 */
	size_t len;

	/**
	 * \brief Decoding status.
	 *
	 * Status is 0 if the name element was not found, 1 if it was
	 * found and decoded, or -1 on error. Error conditions include
	 * an unrecognised encoding, an invalid encoding, or a string
	 * too large for the destination buffer.
	 */
	int status;

} br_name_element;

/**
 * \brief Callback for validity date checks.
 *

include/bearssl_x509.h  view on Meta::CPAN

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

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

	/* Buffer for EE public key data. */
	unsigned char ee_pkey_data[BR_X509_BUFSIZE_KEY];

	/* Buffer for currently decoded public key. */
	unsigned char pkey_data[BR_X509_BUFSIZE_KEY];

	/* Signature type: signer key type, offset to the hash
	   function OID (in the T0 data block) and hash function
	   output length (TBS hash length). */
	unsigned char cert_signer_key_type;
	uint16_t cert_sig_hash_oid;
	unsigned char cert_sig_hash_len;

	/* Current/last certificate signature. */

include/bearssl_x509.h  view on Meta::CPAN

		const unsigned char *ip;
	} cpu;
	uint32_t dp_stack[32];
	uint32_t rp_stack[32];
	int err;

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

	/* Flag set when decoding succeeds. */
	unsigned char decoded;

	/* Validity dates. */
	uint32_t notbefore_days, notbefore_seconds;
	uint32_t notafter_days, notafter_seconds;

	/* The "CA" flag. This is set to true if the certificate contains
	   a Basic Constraints extension that asserts CA status. */
	unsigned char isCA;

	/* DN processing: the subject DN is extracted and pushed to the
	   provided callback. */
	unsigned char copy_dn;
	void *append_dn_ctx;
	void (*append_dn)(void *ctx, const void *buf, size_t len);

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

	/* Buffer for decoded public key. */
	unsigned char pkey_data[BR_X509_BUFSIZE_KEY];

	/* Type of key and hash function used in the certificate signature. */
	unsigned char signer_key_type;
	unsigned char signer_hash_id;
#endif

} br_x509_decoder_context;

/**

include/bearssl_x509.h  view on Meta::CPAN

 * `data`, into the provided decoder context.
 *
 * \param ctx    X.509 decoder context.
 * \param data   certificate data chunk.
 * \param len    certificate data chunk length (in bytes).
 */
void br_x509_decoder_push(br_x509_decoder_context *ctx,
	const void *data, size_t len);

/**
 * \brief 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.
 *
 * \param ctx   X.509 decoder context.
 * \return  the public key, or `NULL` on unfinished/error.
 */
static inline br_x509_pkey *
br_x509_decoder_get_pkey(br_x509_decoder_context *ctx)
{
	if (ctx->decoded && ctx->err == 0) {
		return &ctx->pkey;
	} else {
		return NULL;
	}
}

/**
 * \brief Get decoder error status.
 *
 * If no error was reported yet but the certificate decoding is not

include/bearssl_x509.h  view on Meta::CPAN

 *
 * \param ctx   X.509 decoder context.
 * \return  0 on successful decoding, or a non-zero error code.
 */
static inline int
br_x509_decoder_last_error(br_x509_decoder_context *ctx)
{
	if (ctx->err != 0) {
		return ctx->err;
	}
	if (!ctx->decoded) {
		return BR_ERR_X509_TRUNCATED;
	}
	return 0;
}

/**
 * \brief 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.
 *
 * \param ctx   X.509 decoder context.
 * \return  the "isCA" flag.
 */
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)
{

include/bearssl_x509.h  view on Meta::CPAN

	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;
	}
}

lib/Crypt/Bear/AEAD.pm  view on Meta::CPAN


 $aead->reset($iv);
 $aead->aad_inject($aad);
 $aead->flip;
 my $ciphertext = $aead->run($plaintext, 1);
 my $tag = $aead->get_tag;

 $aead->reset($iv);
 $aead->aad_inject($aad);
 $aead->flip;
 my $decoded = $aead->run($ciphertext, 0);

=head1 DESCRIPTION

This is a base-class for Authenticated encryption with additional data, such as L<GCM|Crypt::Bear::GCM>, L<CCM|Crypt::Bear::CCM> and L<EAX|Crypt::Bear::EAX>. These are typtically used with a block cipher such as C<AES>.

=head1 METHODS

=head2 reset($nonce)

Start a new AEAD computation. The nonce value is provided as parameter to this function.

lib/Crypt/Bear/EAX.pm  view on Meta::CPAN


 $aead->reset($iv);
 $aead->aad_inject($aad);
 $aead->flip;
 my $ciphertext = $aead->run($plaintext, 1);
 my $tag = $aead->get_tag;

 $aead->reset($iv);
 $aead->aad_inject($aad);
 $aead->flip;
 my $decoded = $aead->run($ciphertext, 0);
 $aead->check_tag($tag)

=head1 DESCRIPTION

This is a subclass of L<Crypt::Bear::AEAD> that implements EAX mode. It needs a L<Crypt::Bear::CTRCBC> such as L<Crypt::Bear::AES_CTRCBC> for this.

=head1 METHODS

=head2 new($ctrcbc)

lib/Crypt/Bear/GCM.pm  view on Meta::CPAN


 $aead->reset($iv);
 $aead->aad_inject($aad);
 $aead->flip;
 my $ciphertext = $aead->run($plaintext, 1);
 my $tag = $aead->get_tag;

 $aead->reset($iv);
 $aead->aad_inject($aad);
 $aead->flip;
 my $decoded = $aead->run($ciphertext, 0);
 $aead->check_tag($tag)

=head1 DESCRIPTION

This is a subclass of L<Crypt::Bear::AEAD> that implements GCM mode. It needs a L<Crypt::Bear::CTR> such as L<Crypt::Bear::AES_CTR> for this.

=head1 METHODS

=head2 new($ctr)

src/ec/ec_prime_i15.c  view on Meta::CPAN

	 */
	MMUL(t1, P1z, P2z),
	MMUL(P1z, t1, t2),

	ENDCODE
};

/*
 * Check that the point is on the curve. This code snippet assumes the
 * following conventions:
 * -- Coordinates x and y have been freshly decoded in P1 (but not
 * converted to Montgomery coordinates yet).
 * -- P2x, P2y and P2z are set to, respectively, R^2, b*R and 1.
 */
static const uint16_t code_check[] = {

	/* Convert x and y to Montgomery representation. */
	MMUL(t1, P1x, P2x),
	MMUL(t2, P1y, P2x),
	MSET(P1x, t1),
	MSET(P1y, t2),

src/ec/ec_prime_i31.c  view on Meta::CPAN

	 */
	MMUL(t1, P1z, P2z),
	MMUL(P1z, t1, t2),

	ENDCODE
};

/*
 * Check that the point is on the curve. This code snippet assumes the
 * following conventions:
 * -- Coordinates x and y have been freshly decoded in P1 (but not
 * converted to Montgomery coordinates yet).
 * -- P2x, P2y and P2z are set to, respectively, R^2, b*R and 1.
 */
static const uint16_t code_check[] = {

	/* Convert x and y to Montgomery representation. */
	MMUL(t1, P1x, P2x),
	MMUL(t2, P1y, P2x),
	MSET(P1x, t1),
	MSET(P1y, t2),

src/inner.h  view on Meta::CPAN

 * of q0..q7 are spread over all words: for a byte x that occurs
 * at rank i in q[j] (byte x uses bits 8*i to 8*i+7 in q[j]), the bit
 * of rank k in x (0 <= k <= 7) goes to q[k] at rank 8*i+j.
 *
 * This operation is an involution.
 */
void br_aes_ct64_ortho(uint64_t *q);

/*
 * Interleave bytes for an AES input block. If input bytes are
 * denoted 0123456789ABCDEF, and have been decoded with little-endian
 * convention (w[0] contains 0123, with '3' being most significant;
 * w[1] contains 4567, and so on), then output word q0 will be
 * set to 08192A3B (again little-endian convention) and q1 will
 * be set to 4C5D6E7F.
 */
void br_aes_ct64_interleave_in(uint64_t *q0, uint64_t *q1, const uint32_t *w);

/*
 * Perform the opposite of br_aes_ct64_interleave_in().
 */

src/int/i32_decred.c  view on Meta::CPAN


	/*
	 * First decode directly as many bytes as possible without
	 * reduction, taking care to leave a number of bytes which
	 * is a multiple of 4.
	 */
	mblen = (m_bitlen + 7) >> 3;
	k = mblen - 1;

	/*
	 * Up to k bytes can be safely decoded.
	 */
	if (k >= len) {
		br_i32_decode(x, src, len);
		x[0] = m_bitlen;
		return;
	}

	/*
	 * We want to first inject some bytes with direct decoding,
	 * then extra bytes by whole 32-bit words. First compute

src/rsa/rsa_i15_priv.c  view on Meta::CPAN

	while (u > 0) {
		uint32_t wn, wx;

		u --;
		wn = ((unsigned char *)t3)[u];
		wx = x[u];
		r = ((wx - (wn + r)) >> 8) & 1;
	}

	/*
	 * Move the decoded p to another temporary buffer.
	 */
	mp = mq + 2 * fwlen;
	memmove(mp, t1, fwlen * sizeof *t1);

	/*
	 * Compute s2 = x^dq mod q.
	 */
	q0i = br_i15_ninv15(mq[1]);
	s2 = mq + fwlen;
	br_i15_decode_reduce(s2, x, xlen, mq);

src/rsa/rsa_i15_pub.c  view on Meta::CPAN

	while (z > 0) {
		z -= 15;
		fwlen ++;
	}
	/*
	 * Round up length to an even number.
	 */
	fwlen += (fwlen & 1);

	/*
	 * The modulus gets decoded into m[].
	 * The value to exponentiate goes into a[].
	 * The temporaries for modular exponentiations are in t[].
	 *
	 * We want the first value word of each integer to be aligned
	 * on a 32-bit boundary.
	 */
	m = tmp;
	if (((uintptr_t)m & 2) == 0) {
		m ++;
	}

src/rsa/rsa_i31_priv.c  view on Meta::CPAN

	while (u > 0) {
		uint32_t wn, wx;

		u --;
		wn = ((unsigned char *)t3)[u];
		wx = x[u];
		r = ((wx - (wn + r)) >> 8) & 1;
	}

	/*
	 * Move the decoded p to another temporary buffer.
	 */
	mp = mq + 2 * fwlen;
	memmove(mp, t1, fwlen * sizeof *t1);

	/*
	 * Compute s2 = x^dq mod q.
	 */
	q0i = br_i31_ninv31(mq[1]);
	s2 = mq + fwlen;
	br_i31_decode_reduce(s2, x, xlen, mq);

src/rsa/rsa_i31_pub.c  view on Meta::CPAN

	while (z > 0) {
		z -= 31;
		fwlen ++;
	}
	/*
	 * Round up length to an even number.
	 */
	fwlen += (fwlen & 1);

	/*
	 * The modulus gets decoded into m[].
	 * The value to exponentiate goes into a[].
	 * The temporaries for modular exponentiation are in t[].
	 */
	m = tmp;
	a = m + fwlen;
	t = m + 2 * fwlen;

	/*
	 * Decode the modulus.
	 */

src/rsa/rsa_i62_priv.c  view on Meta::CPAN

	while (u > 0) {
		uint32_t wn, wx;

		u --;
		wn = ((unsigned char *)t3)[u];
		wx = x[u];
		r = ((wx - (wn + r)) >> 8) & 1;
	}

	/*
	 * Move the decoded p to another temporary buffer.
	 */
	mp = (uint32_t *)(tmp + 2 * fwlen);
	memmove(mp, t1, 2 * fwlen * sizeof *t1);

	/*
	 * Compute s2 = x^dq mod q.
	 */
	q0i = br_i31_ninv31(mq[1]);
	s2 = (uint32_t *)(tmp + fwlen);
	br_i31_decode_reduce(s2, x, xlen, mq);

src/rsa/rsa_i62_pub.c  view on Meta::CPAN

	while (z > 0) {
		z -= 31;
		fwlen ++;
	}
	/*
	 * Convert fwlen to a count in 62-bit words.
	 */
	fwlen = (fwlen + 1) >> 1;

	/*
	 * The modulus gets decoded into m[].
	 * The value to exponentiate goes into a[].
	 */
	m = (uint32_t *)tmp;
	a = (uint32_t *)(tmp + fwlen);

	/*
	 * Decode the modulus.
	 */
	br_i31_decode(m, n, nlen);
	m0i = br_i31_ninv31(m[1]);

src/symcipher/poly1305_i15.c  view on Meta::CPAN

		 * Decode next block and apply the "high bit". Since
		 * decoding is little-endian, we must byte-swap the buffer.
		 */
		for (i = 0; i < 16; i ++) {
			rev[i] = buf[15 - i];
		}
		br_i15_decode_mod(b, rev, sizeof rev, P1305);
		b[9] |= 0x0100;

		/*
		 * Add the accumulator to the decoded block (modular
		 * addition).
		 */
		ctl = br_i15_add(b, a, 1);
		ctl |= NOT(br_i15_sub(b, P1305, 0));
		br_i15_sub(b, P1305, ctl);

		/*
		 * Multiply by r, result is the new accumulator value.
		 */
		br_i15_montymul(a, b, r, P1305, P0I);

src/x509/asn1.t0  view on Meta::CPAN


	\ The time zone should be 'Z', not followed by anything. Other
	\ time zone indications are not DER and thus not supposed to
	\ appear in certificates.
	`Z <> if ERR_X509_BAD_TIME fail then
	close-elt
	days seconds ;

\ Read an INTEGER (tag, length and value). The INTEGER is supposed to be
\ positive; its unsigned big-endian encoding is stored in the provided
\ in-context buffer. Returned value is the decoded length. If the integer
\ did not fit, or the value is negative, then an error is reported.
: read-integer ( lim addr len -- lim dlen )
	rot read-tag 0x02 check-tag-primitive -rot
	read-integer-next ;

\ Identical to read-integer, but the tag has already been read and checked.
: read-integer-next ( lim addr len -- lim dlen )
	dup { addr len origlen }
	read-length-open-elt
	\ Read first byte; sign bit must be 0.

src/x509/x509_decoder.c  view on Meta::CPAN

	T0_INT1(BR_ERR_X509_INNER_TRUNC), 0x00, 0x00, 0x01,
	T0_INT1(BR_ERR_X509_LIMIT_EXCEEDED), 0x00, 0x00, 0x01,
	T0_INT1(BR_ERR_X509_NOT_CONSTRUCTED), 0x00, 0x00, 0x01,
	T0_INT1(BR_ERR_X509_NOT_PRIMITIVE), 0x00, 0x00, 0x01,
	T0_INT1(BR_ERR_X509_OVERFLOW), 0x00, 0x00, 0x01,
	T0_INT1(BR_ERR_X509_PARTIAL_BYTE), 0x00, 0x00, 0x01,
	T0_INT1(BR_ERR_X509_UNEXPECTED), 0x00, 0x00, 0x01,
	T0_INT1(BR_ERR_X509_UNSUPPORTED), 0x00, 0x00, 0x01,
	T0_INT1(BR_KEYTYPE_EC), 0x00, 0x00, 0x01, T0_INT1(BR_KEYTYPE_RSA),
	0x00, 0x00, 0x01, T0_INT2(offsetof(CONTEXT_NAME, copy_dn)), 0x00, 0x00,
	0x01, T0_INT2(offsetof(CONTEXT_NAME, decoded)), 0x00, 0x00, 0x01,
	T0_INT2(offsetof(CONTEXT_NAME, isCA)), 0x00, 0x00, 0x01,
	T0_INT2(offsetof(br_x509_decoder_context, pkey_data)), 0x01,
	T0_INT2(BR_X509_BUFSIZE_KEY), 0x00, 0x00, 0x01,
	T0_INT2(offsetof(CONTEXT_NAME, notafter_days)), 0x00, 0x00, 0x01,
	T0_INT2(offsetof(CONTEXT_NAME, notafter_seconds)), 0x00, 0x00, 0x01,
	T0_INT2(offsetof(CONTEXT_NAME, notbefore_days)), 0x00, 0x00, 0x01,
	T0_INT2(offsetof(CONTEXT_NAME, notbefore_seconds)), 0x00, 0x00, 0x01,
	T0_INT2(offsetof(CONTEXT_NAME, pad)), 0x00, 0x00, 0x01,
	T0_INT2(offsetof(CONTEXT_NAME, signer_hash_id)), 0x00, 0x00, 0x01,
	T0_INT2(offsetof(CONTEXT_NAME, signer_key_type)), 0x00, 0x00, 0x01,

src/x509/x509_decoder.t0  view on Meta::CPAN

br_x509_decoder_push(br_x509_decoder_context *ctx,
	const void *data, size_t len)
{
	ctx->hbuf = data;
	ctx->hlen = len;
	br_x509_decoder_run(&ctx->cpu);
}

}

addr: decoded
addr: notbefore_days
addr: notbefore_seconds
addr: notafter_days
addr: notafter_seconds
addr: isCA
addr: copy_dn
addr: signer_key_type
addr: signer_hash_id

cc: read8-low ( -- x ) {

src/x509/x509_decoder.t0  view on Meta::CPAN

	else
		2drop
	then
	skip-close-elt
	;

\ Decode a certificate.
: main ( -- ! )

	\ Initialise state flags.
	0 addr-decoded set8
	0 addr-copy_dn set8

	\ An arbitrary limit for the total certificate size.
	0xFFFFFF

	\ Open the outer SEQUENCE.
	read-sequence-open

	\ TBS
	read-sequence-open

src/x509/x509_decoder.t0  view on Meta::CPAN

	\ read-sequence-open skip-close-elt

	\ signature value
	read-bits-open skip-close-elt

	\ Close the outer SEQUENCE.
	close-elt
	drop

	\ Mark the decoding as successful.
	1 addr-decoded set8

	\ Read one byte, then fail: if the read succeeds, then there is
	\ some trailing byte.
	read8-nc ERR_X509_EXTRA_ELEMENT fail
	;

src/x509/x509_minimal.c  view on Meta::CPAN


/*
 * Implementation Notes
 * --------------------
 *
 * The C code pushes the data by chunks; all decoding is done in the
 * T0 code. The cert_length value is set to the certificate length when
 * a new certificate is started; the T0 code picks it up as outer limit,
 * and decoding functions use it to ensure that no attempt is made at
 * reading past it. The T0 code also checks that once the certificate is
 * decoded, there are no trailing bytes.
 *
 * The T0 code sets cert_length to 0 when the certificate is fully
 * decoded.
 *
 * The C code must still perform two checks:
 *
 *  -- If the certificate length is 0, then the T0 code will not be
 *  invoked at all. This invalid condition must thus be reported by the
 *  C code.
 *
 *  -- When reaching the end of certificate, the C code must verify that
 *  the certificate length has been set to 0, thereby signaling that
 *  the T0 code properly decoded a certificate.
 *
 * Processing of a chain works in the following way:
 *
 *  -- The error flag is set to a non-zero value when validation is
 *  finished. The value is either BR_ERR_X509_OK (validation is
 *  successful) or another non-zero error code. When a non-zero error
 *  code is obtained, the remaining bytes in the current certificate and
 *  the subsequent certificates (if any) are completely ignored.
 *
 *  -- Each certificate is decoded in due course, with the following
 *  "interesting points":
 *
 *     -- Start of the TBS: the multihash engine is reset and activated.
 *
 *     -- Start of the issuer DN: the secondary hash engine is started,
 *     to process the encoded issuer DN.
 *
 *     -- End of the issuer DN: the secondary hash engine is stopped. The
 *     resulting hash value is computed and then copied into the
 *     next_dn_hash[] buffer.

src/x509/x509_minimal.c  view on Meta::CPAN

 *
 *        -- Otherwise, the hashed subject DN is compared with the saved
 *        hash value (in saved_dn_hash[]). They must match.
 *
 *     Either way, the next_dn_hash[] value is then copied into the
 *     saved_dn_hash[] value. Thus, at that point, saved_dn_hash[]
 *     contains the hash of the issuer DN for the current certificate,
 *     and current_dn_hash[] contains the hash of the subject DN for the
 *     current certificate.
 *
 *     -- Public key: it is decoded into the cert_pkey[] buffer. Unknown
 *     key types are reported at that point.
 *
 *        -- If this is the EE certificate, then the key type is compared
 *        with the expected key type (initialization parameter). The public
 *        key data is copied to ee_pkey_data[]. The key and hashed subject
 *        DN are also compared with the "direct trust" keys; if the key
 *        and DN are matched, then validation ends with a success.
 *
 *        -- Otherwise, the saved signature (cert_sig[]) is verified
 *        against the saved TBS hash (tbs_hash[]) and that freshly
 *        decoded public key. Failure here ends validation with an error.
 *
 *     -- Extensions: extension values are processed in due order.
 *
 *        -- Basic Constraints: for all certificates except EE, must be
 *        present, indicate a CA, and have a path length compatible with
 *        the chain length so far.
 *
 *        -- Key Usage: for the EE, if present, must allow signatures
 *        or encryption/key exchange, as required for the cipher suite.
 *        For non-EE, if present, must have the "certificate sign" bit.

src/x509/x509_minimal.c  view on Meta::CPAN

 *        informative data, or they relate to revocation processing, which
 *        we explicitly do not support.
 *
 *        -- All other extensions are ignored if non-critical. If a
 *        critical extension other than the ones above is encountered,
 *        then a failure is reported.
 *
 *     -- End of the TBS: the multihash engine is stopped.
 *
 *     -- Signature algorithm: the signature algorithm on the
 *     certificate is decoded. A failure is reported if that algorithm
 *     is unknown. The hashed TBS corresponding to the signature hash
 *     function is computed and stored in tbs_hash[] (if not supported,
 *     then a failure is reported). The hash OID and length are stored
 *     in cert_sig_hash_oid and cert_sig_hash_len.
 *
 *     -- Signature value: the signature value is copied into the
 *     cert_sig[] array.
 *
 *     -- Certificate end: the hashed issuer DN (saved_dn_hash[]) is
 *     looked up in the trust store (CA trust anchors only); for all

src/x509/x509_minimal.t0  view on Meta::CPAN


/*
 * Implementation Notes
 * --------------------
 *
 * The C code pushes the data by chunks; all decoding is done in the
 * T0 code. The cert_length value is set to the certificate length when
 * a new certificate is started; the T0 code picks it up as outer limit,
 * and decoding functions use it to ensure that no attempt is made at
 * reading past it. The T0 code also checks that once the certificate is
 * decoded, there are no trailing bytes.
 *
 * The T0 code sets cert_length to 0 when the certificate is fully
 * decoded.
 *
 * The C code must still perform two checks:
 *
 *  -- If the certificate length is 0, then the T0 code will not be
 *  invoked at all. This invalid condition must thus be reported by the
 *  C code.
 *
 *  -- When reaching the end of certificate, the C code must verify that
 *  the certificate length has been set to 0, thereby signaling that
 *  the T0 code properly decoded a certificate.
 *
 * Processing of a chain works in the following way:
 *
 *  -- The error flag is set to a non-zero value when validation is
 *  finished. The value is either BR_ERR_X509_OK (validation is
 *  successful) or another non-zero error code. When a non-zero error
 *  code is obtained, the remaining bytes in the current certificate and
 *  the subsequent certificates (if any) are completely ignored.
 *
 *  -- Each certificate is decoded in due course, with the following
 *  "interesting points":
 *
 *     -- Start of the TBS: the multihash engine is reset and activated.
 *
 *     -- Start of the issuer DN: the secondary hash engine is started,
 *     to process the encoded issuer DN.
 *
 *     -- End of the issuer DN: the secondary hash engine is stopped. The
 *     resulting hash value is computed and then copied into the
 *     next_dn_hash[] buffer.

src/x509/x509_minimal.t0  view on Meta::CPAN

 *
 *        -- Otherwise, the hashed subject DN is compared with the saved
 *        hash value (in saved_dn_hash[]). They must match.
 *
 *     Either way, the next_dn_hash[] value is then copied into the
 *     saved_dn_hash[] value. Thus, at that point, saved_dn_hash[]
 *     contains the hash of the issuer DN for the current certificate,
 *     and current_dn_hash[] contains the hash of the subject DN for the
 *     current certificate.
 *
 *     -- Public key: it is decoded into the cert_pkey[] buffer. Unknown
 *     key types are reported at that point.
 *
 *        -- If this is the EE certificate, then the key type is compared
 *        with the expected key type (initialization parameter). The public
 *        key data is copied to ee_pkey_data[]. The key and hashed subject
 *        DN are also compared with the "direct trust" keys; if the key
 *        and DN are matched, then validation ends with a success.
 *
 *        -- Otherwise, the saved signature (cert_sig[]) is verified
 *        against the saved TBS hash (tbs_hash[]) and that freshly
 *        decoded public key. Failure here ends validation with an error.
 *
 *     -- Extensions: extension values are processed in due order.
 *
 *        -- Basic Constraints: for all certificates except EE, must be
 *        present, indicate a CA, and have a path length compatible with
 *        the chain length so far.
 *
 *        -- Key Usage: for the EE, if present, must allow signatures
 *        or encryption/key exchange, as required for the cipher suite.
 *        For non-EE, if present, must have the "certificate sign" bit.

src/x509/x509_minimal.t0  view on Meta::CPAN

 *        informative data, or they relate to revocation processing, which
 *        we explicitly do not support.
 *
 *        -- All other extensions are ignored if non-critical. If a
 *        critical extension other than the ones above is encountered,
 *        then a failure is reported.
 *
 *     -- End of the TBS: the multihash engine is stopped.
 *
 *     -- Signature algorithm: the signature algorithm on the
 *     certificate is decoded. A failure is reported if that algorithm
 *     is unknown. The hashed TBS corresponding to the signature hash
 *     function is computed and stored in tbs_hash[] (if not supported,
 *     then a failure is reported). The hash OID and length are stored
 *     in cert_sig_hash_oid and cert_sig_hash_len.
 *
 *     -- Signature value: the signature value is copied into the
 *     cert_sig[] array.
 *
 *     -- Certificate end: the hashed issuer DN (saved_dn_hash[]) is
 *     looked up in the trust store (CA trust anchors only); for all

src/x509/x509_minimal.t0  view on Meta::CPAN

			\ applicable).
			id-at-commonName eqOID { isCN }

			\ Get offset for reception buffer for that element
			\ (or -1).
			0 offset-name-element { offbuf }

			\ Try to read the value as a string.
			read-string

			\ If the value could be decoded as a string,
			\ copy it and/or match it, as appropriate.
			dup isCN and if
				match-server-name if
					-1 >eename-matches
				then
			then
			offbuf copy-name-element

			\ Close the SEQUENCE
			close-elt

src/x509/x509_minimal.t0  view on Meta::CPAN

		if (memcmp(hashed_DN, CTX->saved_dn_hash, DNHASH_LEN)) {
			continue;
		}
		if (verify_signature(CTX, &ta->pkey) == 0) {
			CTX->err = BR_ERR_X509_OK;
			T0_CO();
		}
	}
}

\ Verify RSA signature. This uses the public key that was just decoded
\ into CTX->pkey_data; the modulus and exponent length are provided as
\ parameters. The resulting hash value is compared with the one in
\ tbs_hash. Returned value is 0 on success, or a non-zero error code.
cc: do-rsa-vrfy ( nlen elen -- err ) {
	size_t elen = T0_POP();
	size_t nlen = T0_POP();
	br_x509_pkey pk;

	pk.key_type = BR_KEYTYPE_RSA;
	pk.key.rsa.n = CTX->pkey_data;
	pk.key.rsa.nlen = nlen;
	pk.key.rsa.e = CTX->pkey_data + nlen;
	pk.key.rsa.elen = elen;
	T0_PUSH(verify_signature(CTX, &pk));
}

\ Verify ECDSA signature. This uses the public key that was just decoded
\ into CTX->pkey_dayta; the curve ID and public point length are provided
\ as parameters. The hash value in tbs_hash is used. Returned value is 0
\ on success, or non-zero error code.
cc: do-ecdsa-vrfy ( curve qlen -- err ) {
	size_t qlen = T0_POP();
	int curve = T0_POP();
	br_x509_pkey pk;

	pk.key_type = BR_KEYTYPE_EC;
	pk.key.ec.curve = curve;

t/50_pem.t  view on Meta::CPAN


use Test::More;

use Crypt::Bear::PEM ':all';
use Crypt::Bear::PEM::Decoder;

my $payload = 'blablabla';

my $encoded = pem_encode('CERTIFICATE', $payload);

my ($name, $decoded) = pem_decode($encoded);

is $name, 'CERTIFICATE', 'Banner is as expected';
is $payload, $decoded, 'Payload is as expected';

done_testing;

t/60_client_server.t  view on Meta::CPAN

		my $to_client = $server->pull_send;
		$client->push_received($to_client);

		die if $count++ > 100;
	}
	1;
};

my $payload1 = 'Hello world!';
my $rec1 = $client->push_send($payload1, !!1);
my $decoded1 = $server->push_received($rec1);
is $decoded1, $payload1;

my $payload2 = 'Welcome back';
my $rec2 = $server->push_send($payload2, !!1);
my $decoded2 = $client->push_received($rec2);
is $decoded2, $payload2;

$client->close;
is $server->push_received($client->pull_send), '';
is $client->push_received($server->pull_send), '';
ok $server->is_closed;
ok $client->is_closed;

done_testing;



( run in 0.619 second using v1.01-cache-2.11-cpan-a9ef4e587e4 )