static int hkdf_expand_label(uint8_t *out, const EVP_MD *digest, const uint8_t *secret, size_t secret_len, const uint8_t *label, size_t label_len, const uint8_t *hash, size_t hash_len, size_t len) { static const char kTLS13LabelVersion[] = "TLS 1.3, "; CBB cbb, child; uint8_t *hkdf_label; size_t hkdf_label_len; if (!CBB_init(&cbb, 2 + 1 + strlen(kTLS13LabelVersion) + label_len + 1 + hash_len) || !CBB_add_u16(&cbb, len) || !CBB_add_u8_length_prefixed(&cbb, &child) || !CBB_add_bytes(&child, (const uint8_t *)kTLS13LabelVersion, strlen(kTLS13LabelVersion)) || !CBB_add_bytes(&child, label, label_len) || !CBB_add_u8_length_prefixed(&cbb, &child) || !CBB_add_bytes(&child, hash, hash_len) || !CBB_finish(&cbb, &hkdf_label, &hkdf_label_len)) { CBB_cleanup(&cbb); return 0; } int ret = HKDF_expand(out, len, digest, secret, secret_len, hkdf_label, hkdf_label_len); OPENSSL_free(hkdf_label); return ret; }
static int test_cbb_prefixed(void) { static const uint8_t kExpected[] = {0, 1, 1, 0, 2, 2, 3, 0, 0, 3, 4, 5, 6, 5, 4, 1, 0, 1, 2}; uint8_t *buf; size_t buf_len; CBB cbb, contents, inner_contents, inner_inner_contents; int ok; if (!CBB_init(&cbb, 0) || !CBB_add_u8_length_prefixed(&cbb, &contents) || !CBB_add_u8_length_prefixed(&cbb, &contents) || !CBB_add_u8(&contents, 1) || !CBB_add_u16_length_prefixed(&cbb, &contents) || !CBB_add_u16(&contents, 0x203) || !CBB_add_u24_length_prefixed(&cbb, &contents) || !CBB_add_u24(&contents, 0x40506) || !CBB_add_u8_length_prefixed(&cbb, &contents) || !CBB_add_u8_length_prefixed(&contents, &inner_contents) || !CBB_add_u8(&inner_contents, 1) || !CBB_add_u16_length_prefixed(&inner_contents, &inner_inner_contents) || !CBB_add_u8(&inner_inner_contents, 2) || !CBB_finish(&cbb, &buf, &buf_len)) { return 0; } ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0; free(buf); return ok; }
static int test_cbb_misuse(void) { CBB cbb, child, contents; uint8_t *buf; size_t buf_len; if (!CBB_init(&cbb, 0) || !CBB_add_u8_length_prefixed(&cbb, &child) || !CBB_add_u8(&child, 1) || !CBB_add_u8(&cbb, 2)) { return 0; } /* Since we wrote to |cbb|, |child| is now invalid and attempts to write to * it should fail. */ if (CBB_add_u8(&child, 1) || CBB_add_u16(&child, 1) || CBB_add_u24(&child, 1) || CBB_add_u8_length_prefixed(&child, &contents) || CBB_add_u16_length_prefixed(&child, &contents) || CBB_add_asn1(&child, &contents, 1) || CBB_add_bytes(&child, (const uint8_t*) "a", 1)) { fprintf(stderr, "CBB operation on invalid CBB did not fail.\n"); return 0; } if (!CBB_finish(&cbb, &buf, &buf_len) || buf_len != 3 || memcmp(buf, "\x01\x01\x02", 3) != 0) { return 0; } free(buf); return 1; }
int tls13_prepare_certificate(SSL *ssl) { CBB cbb, body, context; if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CERTIFICATE) || !CBB_add_u8_length_prefixed(&body, &context) || !CBB_add_bytes(&context, ssl->s3->hs->cert_context, ssl->s3->hs->cert_context_len) || !ssl_add_cert_chain(ssl, &body) || !ssl->method->finish_message(ssl, &cbb)) { CBB_cleanup(&cbb); return 0; } return 1; }
static int test_cbb_finish_child(void) { CBB cbb, child; uint8_t *out_buf; size_t out_size; if (!CBB_init(&cbb, 16) || !CBB_add_u8_length_prefixed(&cbb, &child) || CBB_finish(&child, &out_buf, &out_size) || !CBB_finish(&cbb, &out_buf, &out_size) || out_size != 1 || out_buf[0] != 0) { return 0; } free(out_buf); return 1; }