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