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; }
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_fixed(void) { CBB cbb; uint8_t buf[1]; uint8_t *out_buf; size_t out_size; if (!CBB_init_fixed(&cbb, NULL, 0) || CBB_add_u8(&cbb, 1) || !CBB_finish(&cbb, &out_buf, &out_size) || out_buf != NULL || out_size != 0) { return 0; } if (!CBB_init_fixed(&cbb, buf, 1) || !CBB_add_u8(&cbb, 1) || CBB_add_u8(&cbb, 2) || !CBB_finish(&cbb, &out_buf, &out_size) || out_buf != buf || out_size != 1 || buf[0] != 1) { return 0; } return 1; }
int BN_bn2cbb(CBB *cbb, const BIGNUM *bn) { /* Negative numbers are unsupported. */ if (BN_is_negative(bn)) { OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); return 0; } CBB child; if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) { OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR); return 0; } /* The number must be padded with a leading zero if the high bit would * otherwise be set (or |bn| is zero). */ if (BN_num_bits(bn) % 8 == 0 && !CBB_add_u8(&child, 0x00)) { OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR); return 0; } uint8_t *out; if (!CBB_add_space(&child, &out, BN_num_bytes(bn))) { OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR); return 0; } BN_bn2bin(bn, out); if (!CBB_flush(cbb)) { OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR); return 0; } return 1; }
static int test_cbb_basic(void) { static const uint8_t kExpected[] = {1, 2, 3, 4, 5, 6, 7, 8}; uint8_t *buf; size_t buf_len; int ok; CBB cbb; if (!CBB_init(&cbb, 100)) { return 0; } CBB_cleanup(&cbb); if (!CBB_init(&cbb, 0) || !CBB_add_u8(&cbb, 1) || !CBB_add_u16(&cbb, 0x203) || !CBB_add_u24(&cbb, 0x40506) || !CBB_add_bytes(&cbb, (const uint8_t*) "\x07\x08", 2) || !CBB_finish(&cbb, &buf, &buf_len)) { return 0; } ok = buf_len == sizeof(kExpected) && memcmp(buf, kExpected, buf_len) == 0; free(buf); return ok; }
int tls13_get_cert_verify_signature_input( SSL *ssl, uint8_t **out, size_t *out_len, enum ssl_cert_verify_context_t cert_verify_context) { CBB cbb; if (!CBB_init(&cbb, 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) { goto err; } for (size_t i = 0; i < 64; i++) { if (!CBB_add_u8(&cbb, 0x20)) { goto err; } } const uint8_t *context; size_t context_len; if (cert_verify_context == ssl_cert_verify_server) { /* Include the NUL byte. */ static const char kContext[] = "TLS 1.3, server CertificateVerify"; context = (const uint8_t *)kContext; context_len = sizeof(kContext); } else if (cert_verify_context == ssl_cert_verify_client) { static const char kContext[] = "TLS 1.3, client CertificateVerify"; context = (const uint8_t *)kContext; context_len = sizeof(kContext); } else if (cert_verify_context == ssl_cert_verify_channel_id) { static const char kContext[] = "TLS 1.3, Channel ID"; context = (const uint8_t *)kContext; context_len = sizeof(kContext); } else { goto err; } if (!CBB_add_bytes(&cbb, context, context_len)) { goto err; } uint8_t context_hash[EVP_MAX_MD_SIZE]; size_t context_hash_len; if (!tls13_get_context_hash(ssl, context_hash, &context_hash_len) || !CBB_add_bytes(&cbb, context_hash, context_hash_len) || !CBB_finish(&cbb, out, out_len)) { goto err; } return 1; err: OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); CBB_cleanup(&cbb); return 0; }
int tls13_prepare_certificate(SSL *ssl) { CBB cbb, body; if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CERTIFICATE) || /* The request context is always empty in the handshake. */ !CBB_add_u8(&body, 0) || !ssl_add_cert_chain(ssl, &body) || !ssl->method->finish_message(ssl, &cbb)) { CBB_cleanup(&cbb); return 0; } return 1; }
int mono_btls_ssl_ctx_set_ciphers (MonoBtlsSslCtx *ctx, int count, const uint16_t *data, int allow_unsupported) { CBB cbb; int i, ret = 0; if (!CBB_init (&cbb, 64)) goto err; /* Assemble a cipher string with the specified ciphers' names. */ for (i = 0; i < count; i++) { const char *name; const SSL_CIPHER *cipher = SSL_get_cipher_by_value (data [i]); if (!cipher) { debug_printf (ctx, "mono_btls_ssl_ctx_set_ciphers(): unknown cipher %02x", data [i]); if (!allow_unsupported) goto err; continue; } name = SSL_CIPHER_get_name (cipher); if (i > 0 && !CBB_add_u8 (&cbb, ':')) goto err; if (!CBB_add_bytes (&cbb, (const uint8_t *)name, strlen(name))) goto err; } /* NUL-terminate the string. */ if (!CBB_add_u8 (&cbb, 0)) goto err; ret = SSL_CTX_set_cipher_list (ctx->ctx, (const char *)CBB_data (&cbb)); err: CBB_cleanup (&cbb); return ret; }
static enum ssl_hs_wait_t do_send_certificate_request(SSL *ssl, SSL_HANDSHAKE *hs) { /* Determine whether to request a client certificate. */ ssl->s3->tmp.cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER); /* CertificateRequest may only be sent in certificate-based ciphers. */ if (!ssl_cipher_uses_certificate_auth(ssl->s3->tmp.new_cipher)) { ssl->s3->tmp.cert_request = 0; } if (!ssl->s3->tmp.cert_request) { /* Skip this state. */ hs->state = state_send_server_certificate; return ssl_hs_ok; } CBB cbb, body, sigalgs_cbb; if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CERTIFICATE_REQUEST) || !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) { goto err; } const uint16_t *sigalgs; size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs); if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) { goto err; } for (size_t i = 0; i < sigalgs_len; i++) { if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) { goto err; } } if (!ssl_add_client_CA_list(ssl, &body) || !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) || !ssl->method->finish_message(ssl, &cbb)) { goto err; } hs->state = state_send_server_certificate; return ssl_hs_write_message; err: CBB_cleanup(&cbb); return ssl_hs_error; }
static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { // See RFC 3279, section 2.3.1. CBB spki, algorithm, oid, null, key_bitstring; if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) || !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || !CBB_add_u8(&key_bitstring, 0 /* padding */) || !RSA_marshal_public_key(&key_bitstring, key->pkey.rsa) || !CBB_flush(out)) { OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); return 0; } return 1; }
static int tls13_get_cert_verify_signature_input(SSL *ssl, uint8_t **out, size_t *out_len, int server) { CBB cbb; if (!CBB_init(&cbb, 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) { goto err; } for (size_t i = 0; i < 64; i++) { if (!CBB_add_u8(&cbb, 0x20)) { goto err; } } if (server) { /* Include the NUL byte. */ static const char kContext[] = "TLS 1.3, server CertificateVerify"; if (!CBB_add_bytes(&cbb, (const uint8_t *)kContext, sizeof(kContext))) { goto err; } } else { static const char kContext[] = "TLS 1.3, client CertificateVerify"; if (!CBB_add_bytes(&cbb, (const uint8_t *)kContext, sizeof(kContext))) { goto err; } } uint8_t context_hashes[2 * EVP_MAX_MD_SIZE]; size_t context_hashes_len; if (!tls13_get_context_hashes(ssl, context_hashes, &context_hashes_len) || !CBB_add_bytes(&cbb, context_hashes, context_hashes_len) || !CBB_finish(&cbb, out, out_len)) { goto err; } return 1; err: OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); CBB_cleanup(&cbb); return 0; }
static int eckey_pub_encode(CBB *out, const EVP_PKEY *key) { const EC_KEY *ec_key = key->pkey.ec; const EC_GROUP *group = EC_KEY_get0_group(ec_key); const EC_POINT *public_key = EC_KEY_get0_public_key(ec_key); // See RFC 5480, section 2. CBB spki, algorithm, oid, key_bitstring; if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) || !EC_KEY_marshal_curve_name(&algorithm, group) || !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || !CBB_add_u8(&key_bitstring, 0 /* padding */) || !EC_POINT_point2cbb(&key_bitstring, group, public_key, POINT_CONVERSION_UNCOMPRESSED, NULL) || !CBB_flush(out)) { OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); return 0; } return 1; }
int tls13_prepare_certificate(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; CBB cbb, body, certificate_list; if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CERTIFICATE) || /* The request context is always empty in the handshake. */ !CBB_add_u8(&body, 0) || !CBB_add_u24_length_prefixed(&body, &certificate_list)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); goto err; } if (!ssl_has_certificate(ssl)) { if (!ssl_complete_message(ssl, &cbb)) { goto err; } return 1; } CERT *cert = ssl->cert; CBB leaf, extensions; if (!CBB_add_u24_length_prefixed(&certificate_list, &leaf) || !ssl_add_cert_to_cbb(&leaf, cert->x509_leaf) || !CBB_add_u16_length_prefixed(&certificate_list, &extensions)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); goto err; } if (hs->scts_requested && ssl->ctx->signed_cert_timestamp_list_length != 0) { CBB contents; if (!CBB_add_u16(&extensions, TLSEXT_TYPE_certificate_timestamp) || !CBB_add_u16_length_prefixed(&extensions, &contents) || !CBB_add_bytes(&contents, ssl->ctx->signed_cert_timestamp_list, ssl->ctx->signed_cert_timestamp_list_length) || !CBB_flush(&extensions)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); goto err; } } if (hs->ocsp_stapling_requested && ssl->ocsp_response != NULL) { CBB contents, ocsp_response; if (!CBB_add_u16(&extensions, TLSEXT_TYPE_status_request) || !CBB_add_u16_length_prefixed(&extensions, &contents) || !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) || !CBB_add_u24_length_prefixed(&contents, &ocsp_response) || !CBB_add_bytes(&ocsp_response, CRYPTO_BUFFER_data(ssl->ocsp_response), CRYPTO_BUFFER_len(ssl->ocsp_response)) || !CBB_flush(&extensions)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); goto err; } } for (size_t i = 0; i < sk_X509_num(cert->x509_chain); i++) { CBB child; if (!CBB_add_u24_length_prefixed(&certificate_list, &child) || !ssl_add_cert_to_cbb(&child, sk_X509_value(cert->x509_chain, i)) || !CBB_add_u16(&certificate_list, 0 /* no extensions */)) { OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); goto err; } } if (!ssl_complete_message(ssl, &cbb)) { goto err; } return 1; err: CBB_cleanup(&cbb); return 0; }
static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, uint8_t **out_data, size_t *out_len, int for_ticket) { CBB cbb, session, child, child2; if (in == NULL || in->cipher == NULL) { return 0; } CBB_zero(&cbb); if (!CBB_init(&cbb, 0) || !CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE) || !CBB_add_asn1_uint64(&session, kVersion) || !CBB_add_asn1_uint64(&session, in->ssl_version) || !CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) || !CBB_add_u16(&child, (uint16_t)(in->cipher->id & 0xffff)) || !CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) || /* The session ID is irrelevant for a session ticket. */ !CBB_add_bytes(&child, in->session_id, for_ticket ? 0 : in->session_id_length) || !CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) || !CBB_add_bytes(&child, in->master_key, in->master_key_length) || !CBB_add_asn1(&session, &child, kTimeTag) || !CBB_add_asn1_uint64(&child, in->time) || !CBB_add_asn1(&session, &child, kTimeoutTag) || !CBB_add_asn1_uint64(&child, in->timeout)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } /* The peer certificate is only serialized if the SHA-256 isn't * serialized instead. */ if (sk_CRYPTO_BUFFER_num(in->certs) > 0 && !in->peer_sha256_valid) { const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs, 0); if (!CBB_add_asn1(&session, &child, kPeerTag) || !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), CRYPTO_BUFFER_len(buffer))) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } /* Although it is OPTIONAL and usually empty, OpenSSL has * historically always encoded the sid_ctx. */ if (!CBB_add_asn1(&session, &child, kSessionIDContextTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || !CBB_add_bytes(&child2, in->sid_ctx, in->sid_ctx_length)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } if (in->verify_result != X509_V_OK) { if (!CBB_add_asn1(&session, &child, kVerifyResultTag) || !CBB_add_asn1_uint64(&child, in->verify_result)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (in->tlsext_hostname) { if (!CBB_add_asn1(&session, &child, kHostNameTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || !CBB_add_bytes(&child2, (const uint8_t *)in->tlsext_hostname, strlen(in->tlsext_hostname))) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (in->psk_identity) { if (!CBB_add_asn1(&session, &child, kPSKIdentityTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || !CBB_add_bytes(&child2, (const uint8_t *)in->psk_identity, strlen(in->psk_identity))) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (in->tlsext_tick_lifetime_hint > 0) { if (!CBB_add_asn1(&session, &child, kTicketLifetimeHintTag) || !CBB_add_asn1_uint64(&child, in->tlsext_tick_lifetime_hint)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (in->tlsext_tick && !for_ticket) { if (!CBB_add_asn1(&session, &child, kTicketTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || !CBB_add_bytes(&child2, in->tlsext_tick, in->tlsext_ticklen)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (in->peer_sha256_valid) { if (!CBB_add_asn1(&session, &child, kPeerSHA256Tag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || !CBB_add_bytes(&child2, in->peer_sha256, sizeof(in->peer_sha256))) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (in->original_handshake_hash_len > 0) { if (!CBB_add_asn1(&session, &child, kOriginalHandshakeHashTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || !CBB_add_bytes(&child2, in->original_handshake_hash, in->original_handshake_hash_len)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (in->tlsext_signed_cert_timestamp_list_length > 0) { if (!CBB_add_asn1(&session, &child, kSignedCertTimestampListTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || !CBB_add_bytes(&child2, in->tlsext_signed_cert_timestamp_list, in->tlsext_signed_cert_timestamp_list_length)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (in->ocsp_response_length > 0) { if (!CBB_add_asn1(&session, &child, kOCSPResponseTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || !CBB_add_bytes(&child2, in->ocsp_response, in->ocsp_response_length)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (in->extended_master_secret) { if (!CBB_add_asn1(&session, &child, kExtendedMasterSecretTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_BOOLEAN) || !CBB_add_u8(&child2, 0xff)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (in->group_id > 0 && (!CBB_add_asn1(&session, &child, kGroupIDTag) || !CBB_add_asn1_uint64(&child, in->group_id))) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } /* The certificate chain is only serialized if the leaf's SHA-256 isn't * serialized instead. */ if (in->certs != NULL && !in->peer_sha256_valid && sk_CRYPTO_BUFFER_num(in->certs) >= 2) { if (!CBB_add_asn1(&session, &child, kCertChainTag)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(in->certs); i++) { const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs, i); if (!CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), CRYPTO_BUFFER_len(buffer))) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } } if (in->ticket_age_add_valid) { if (!CBB_add_asn1(&session, &child, kTicketAgeAddTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || !CBB_add_u32(&child2, in->ticket_age_add)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (!in->is_server) { if (!CBB_add_asn1(&session, &child, kIsServerTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_BOOLEAN) || !CBB_add_u8(&child2, 0x00)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (in->peer_signature_algorithm != 0 && (!CBB_add_asn1(&session, &child, kPeerSignatureAlgorithmTag) || !CBB_add_asn1_uint64(&child, in->peer_signature_algorithm))) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } if (in->ticket_max_early_data != 0 && (!CBB_add_asn1(&session, &child, kTicketMaxEarlyDataTag) || !CBB_add_asn1_uint64(&child, in->ticket_max_early_data))) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } if (in->timeout != in->auth_timeout && (!CBB_add_asn1(&session, &child, kAuthTimeoutTag) || !CBB_add_asn1_uint64(&child, in->auth_timeout))) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } if (in->early_alpn) { if (!CBB_add_asn1(&session, &child, kEarlyALPNTag) || !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || !CBB_add_bytes(&child2, (const uint8_t *)in->early_alpn, in->early_alpn_len)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } } if (!CBB_finish(&cbb, out_data, out_len)) { OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } return 1; err: CBB_cleanup(&cbb); return 0; }
static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { SSL *const ssl = hs->ssl; /* Send a ServerHello. */ CBB cbb, body, extensions; if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_SERVER_HELLO) || !CBB_add_u16(&body, ssl->version) || !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) || !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) || !CBB_add_u16(&body, ssl_cipher_get_value(ssl->s3->tmp.new_cipher)) || !CBB_add_u16_length_prefixed(&body, &extensions) || !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) || !ssl_ext_key_share_add_serverhello(hs, &extensions)) { goto err; } if (ssl->s3->short_header) { if (!CBB_add_u16(&extensions, TLSEXT_TYPE_short_header) || !CBB_add_u16(&extensions, 0 /* empty extension */)) { goto err; } } if (!ssl_add_message_cbb(ssl, &cbb)) { goto err; } /* Derive and enable the handshake traffic secrets. */ if (!tls13_derive_handshake_secrets(hs) || !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret, hs->hash_len) || !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret, hs->hash_len)) { goto err; } /* Send EncryptedExtensions. */ if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_ENCRYPTED_EXTENSIONS) || !ssl_add_serverhello_tlsext(hs, &body) || !ssl_add_message_cbb(ssl, &cbb)) { goto err; } /* Determine whether to request a client certificate. */ hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER); /* CertificateRequest may only be sent in non-resumption handshakes. */ if (ssl->s3->session_reused) { hs->cert_request = 0; } /* Send a CertificateRequest, if necessary. */ if (hs->cert_request) { CBB sigalgs_cbb; if (!ssl->method->init_message(ssl, &cbb, &body, SSL3_MT_CERTIFICATE_REQUEST) || !CBB_add_u8(&body, 0 /* no certificate_request_context. */)) { goto err; } const uint16_t *sigalgs; size_t num_sigalgs = tls12_get_verify_sigalgs(ssl, &sigalgs); if (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb)) { goto err; } for (size_t i = 0; i < num_sigalgs; i++) { if (!CBB_add_u16(&sigalgs_cbb, sigalgs[i])) { goto err; } } if (!ssl_add_client_CA_list(ssl, &body) || !CBB_add_u16(&body, 0 /* empty certificate_extensions. */) || !ssl_add_message_cbb(ssl, &cbb)) { goto err; } } /* Send the server Certificate message, if necessary. */ if (!ssl->s3->session_reused) { if (!ssl_has_certificate(ssl)) { OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET); goto err; } if (!tls13_add_certificate(hs)) { goto err; } hs->tls13_state = state_send_server_certificate_verify; return ssl_hs_ok; } hs->tls13_state = state_send_server_finished; return ssl_hs_ok; err: CBB_cleanup(&cbb); return ssl_hs_error; }