static int test_EVP_DigestVerifyInitFromAlgorithm(void) { int ret = 0; CBS cert, cert_body, tbs_cert, algorithm, signature; uint8_t padding; X509_ALGOR *algor = NULL; const uint8_t *derp; EVP_PKEY *pkey = NULL; EVP_MD_CTX md_ctx; EVP_MD_CTX_init(&md_ctx); CBS_init(&cert, kExamplePSSCert, sizeof(kExamplePSSCert)); if (!CBS_get_asn1(&cert, &cert_body, CBS_ASN1_SEQUENCE) || CBS_len(&cert) != 0 || !CBS_get_any_asn1_element(&cert_body, &tbs_cert, NULL, NULL) || !CBS_get_asn1_element(&cert_body, &algorithm, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&cert_body, &signature, CBS_ASN1_BITSTRING) || CBS_len(&cert_body) != 0) { fprintf(stderr, "Failed to parse certificate\n"); goto out; } /* Signatures are BIT STRINGs, but they have are multiple of 8 bytes, so the leading phase byte is just a zero. */ if (!CBS_get_u8(&signature, &padding) || padding != 0) { fprintf(stderr, "Invalid signature padding\n"); goto out; } derp = CBS_data(&algorithm); if (!d2i_X509_ALGOR(&algor, &derp, CBS_len(&algorithm)) || derp != CBS_data(&algorithm) + CBS_len(&algorithm)) { fprintf(stderr, "Failed to parse algorithm\n"); } pkey = load_example_rsa_key(); if (pkey == NULL || !EVP_DigestVerifyInitFromAlgorithm(&md_ctx, algor, pkey) || !EVP_DigestVerifyUpdate(&md_ctx, CBS_data(&tbs_cert), CBS_len(&tbs_cert)) || !EVP_DigestVerifyFinal(&md_ctx, CBS_data(&signature), CBS_len(&signature))) { goto out; } ret = 1; out: if (!ret) { BIO_print_errors_fp(stderr); } EVP_MD_CTX_cleanup(&md_ctx); if (pkey) { EVP_PKEY_free(pkey); } return ret; }
static int test_get_u(void) { static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; uint8_t u8; uint16_t u16; uint32_t u32; CBS data; CBS_init(&data, kData, sizeof(kData)); return CBS_get_u8(&data, &u8) && u8 == 1 && CBS_get_u16(&data, &u16) && u16 == 0x203 && CBS_get_u24(&data, &u32) && u32 == 0x40506 && CBS_get_u32(&data, &u32) && u32 == 0x708090a && !CBS_get_u8(&data, &u8); }
static int tls13_receive_key_update(SSL *ssl) { CBS cbs; uint8_t key_update_request; CBS_init(&cbs, ssl->init_msg, ssl->init_num); if (!CBS_get_u8(&cbs, &key_update_request) || CBS_len(&cbs) != 0 || (key_update_request != SSL_KEY_UPDATE_NOT_REQUESTED && key_update_request != SSL_KEY_UPDATE_REQUESTED)) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); return 0; } /* TODO(svaldez): Send KeyUpdate if |key_update_request| is * |SSL_KEY_UPDATE_REQUESTED|. */ return tls13_rotate_traffic_key(ssl, evp_aead_open); }
static int test_get_prefixed(void) { static const uint8_t kData[] = {1, 2, 0, 2, 3, 4, 0, 0, 3, 3, 2, 1}; uint8_t u8; uint16_t u16; uint32_t u32; CBS data, prefixed; CBS_init(&data, kData, sizeof(kData)); return CBS_get_u8_length_prefixed(&data, &prefixed) && CBS_len(&prefixed) == 1 && CBS_get_u8(&prefixed, &u8) && u8 == 2 && CBS_get_u16_length_prefixed(&data, &prefixed) && CBS_len(&prefixed) == 2 && CBS_get_u16(&prefixed, &u16) && u16 == 0x304 && CBS_get_u24_length_prefixed(&data, &prefixed) && CBS_len(&prefixed) == 3 && CBS_get_u24(&prefixed, &u32) && u32 == 0x30201; }
EVP_PKEY *EVP_parse_public_key(CBS *cbs) { // Parse the SubjectPublicKeyInfo. CBS spki, algorithm, key; int type; uint8_t padding; if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || !parse_key_type(&algorithm, &type) || !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) || CBS_len(&spki) != 0 || // Every key type defined encodes the key as a byte string with the same // conversion to BIT STRING. !CBS_get_u8(&key, &padding) || padding != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); return NULL; } // Set up an |EVP_PKEY| of the appropriate type. EVP_PKEY *ret = EVP_PKEY_new(); if (ret == NULL || !EVP_PKEY_set_type(ret, type)) { goto err; } // Call into the type-specific SPKI decoding function. if (ret->ameth->pub_decode == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); goto err; } if (!ret->ameth->pub_decode(ret, &algorithm, &key)) { goto err; } return ret; err: EVP_PKEY_free(ret); return NULL; }
int tls1_process_sigalgs(SSL *s, CBS *cbs) { const EVP_MD *md; CERT *c = s->cert; int idx; /* Extension ignored for inappropriate versions */ if (!SSL_USE_SIGALGS(s)) return 1; /* Should never happen */ if (c == NULL) return 0; c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL; c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL; c->pkeys[SSL_PKEY_ECC].digest = NULL; c->pkeys[SSL_PKEY_GOST01].digest = NULL; while (CBS_len(cbs) > 0) { uint8_t hash_alg, sig_alg; if (!CBS_get_u8(cbs, &hash_alg) || !CBS_get_u8(cbs, &sig_alg)) return 0; switch (sig_alg) { case TLSEXT_signature_rsa: idx = SSL_PKEY_RSA_SIGN; break; case TLSEXT_signature_ecdsa: idx = SSL_PKEY_ECC; break; case TLSEXT_signature_gostr01: case TLSEXT_signature_gostr12_256: case TLSEXT_signature_gostr12_512: idx = SSL_PKEY_GOST01; break; default: continue; } if (c->pkeys[idx].digest == NULL) { md = tls12_get_hash(hash_alg); if (md) { c->pkeys[idx].digest = md; if (idx == SSL_PKEY_RSA_SIGN) c->pkeys[SSL_PKEY_RSA_ENC].digest = md; } } } /* * Set any remaining keys to default values. NOTE: if alg is not * supported it stays as NULL. */ if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) { c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); } if (!c->pkeys[SSL_PKEY_ECC].digest) c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); #ifndef OPENSSL_NO_GOST if (!c->pkeys[SSL_PKEY_GOST01].digest) c->pkeys[SSL_PKEY_GOST01].digest = EVP_gostr341194(); #endif return 1; }
int tls13_process_certificate(SSL_HANDSHAKE *hs, int allow_anonymous) { SSL *const ssl = hs->ssl; CBS cbs, context, certificate_list; CBS_init(&cbs, ssl->init_msg, ssl->init_num); if (!CBS_get_u8_length_prefixed(&cbs, &context) || CBS_len(&context) != 0) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); return 0; } const int retain_sha256 = ssl->server && ssl->retain_only_sha256_of_client_certs; int ret = 0; EVP_PKEY *pkey = NULL; STACK_OF(CRYPTO_BUFFER) *certs = sk_CRYPTO_BUFFER_new_null(); if (certs == NULL) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } if (!CBS_get_u24_length_prefixed(&cbs, &certificate_list)) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto err; } while (CBS_len(&certificate_list) > 0) { CBS certificate, extensions; if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) || !CBS_get_u16_length_prefixed(&certificate_list, &extensions) || CBS_len(&certificate) == 0) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH); goto err; } if (sk_CRYPTO_BUFFER_num(certs) == 0) { pkey = ssl_cert_parse_pubkey(&certificate); if (pkey == NULL) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); goto err; } /* TLS 1.3 always uses certificate keys for signing thus the correct * keyUsage is enforced. */ if (!ssl_cert_check_digital_signature_key_usage(&certificate)) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); goto err; } if (retain_sha256) { /* Retain the hash of the leaf certificate if requested. */ SHA256(CBS_data(&certificate), CBS_len(&certificate), ssl->s3->new_session->peer_sha256); } } CRYPTO_BUFFER *buf = CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool); if (buf == NULL || !sk_CRYPTO_BUFFER_push(certs, buf)) { CRYPTO_BUFFER_free(buf); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); goto err; } /* Parse out the extensions. */ int have_status_request = 0, have_sct = 0; CBS status_request, sct; const SSL_EXTENSION_TYPE ext_types[] = { {TLSEXT_TYPE_status_request, &have_status_request, &status_request}, {TLSEXT_TYPE_certificate_timestamp, &have_sct, &sct}, }; uint8_t alert; if (!ssl_parse_extensions(&extensions, &alert, ext_types, OPENSSL_ARRAY_SIZE(ext_types), 0 /* reject unknown */)) { ssl3_send_alert(ssl, SSL3_AL_FATAL, alert); goto err; } /* All Certificate extensions are parsed, but only the leaf extensions are * stored. */ if (have_status_request) { if (ssl->server || !ssl->ocsp_stapling_enabled) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); goto err; } uint8_t status_type; CBS ocsp_response; if (!CBS_get_u8(&status_request, &status_type) || status_type != TLSEXT_STATUSTYPE_ocsp || !CBS_get_u24_length_prefixed(&status_request, &ocsp_response) || CBS_len(&ocsp_response) == 0 || CBS_len(&status_request) != 0) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); goto err; } if (sk_CRYPTO_BUFFER_num(certs) == 1 && !CBS_stow(&ocsp_response, &ssl->s3->new_session->ocsp_response, &ssl->s3->new_session->ocsp_response_length)) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); goto err; } } if (have_sct) { if (ssl->server || !ssl->signed_cert_timestamps_enabled) { OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); goto err; } if (!ssl_is_sct_list_valid(&sct)) { OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); goto err; } if (sk_CRYPTO_BUFFER_num(certs) == 1 && !CBS_stow(&sct, &ssl->s3->new_session->tlsext_signed_cert_timestamp_list, &ssl->s3->new_session ->tlsext_signed_cert_timestamp_list_length)) { ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); goto err; } } } if (CBS_len(&cbs) != 0) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); goto err; } EVP_PKEY_free(hs->peer_pubkey); hs->peer_pubkey = pkey; pkey = NULL; sk_CRYPTO_BUFFER_pop_free(ssl->s3->new_session->certs, CRYPTO_BUFFER_free); ssl->s3->new_session->certs = certs; certs = NULL; if (!ssl_session_x509_cache_objects(ssl->s3->new_session)) { OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); goto err; } if (sk_CRYPTO_BUFFER_num(ssl->s3->new_session->certs) == 0) { if (!allow_anonymous) { OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED); goto err; } /* OpenSSL returns X509_V_OK when no certificates are requested. This is * classed by them as a bug, but it's assumed by at least NGINX. */ ssl->s3->new_session->verify_result = X509_V_OK; /* No certificate, so nothing more to do. */ ret = 1; goto err; } ssl->s3->new_session->peer_sha256_valid = retain_sha256; if (!ssl_verify_cert_chain(ssl, &ssl->s3->new_session->verify_result, ssl->s3->new_session->x509_chain)) { goto err; } ret = 1; err: sk_CRYPTO_BUFFER_pop_free(certs, CRYPTO_BUFFER_free); EVP_PKEY_free(pkey); return ret; }
/* Obtain handshake message of message type 'mt' (any if mt == -1), * maximum acceptable body length 'max'. * The first four bytes (msg_type and length) are read in state 'st1', * the body is read in state 'stn'. */ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) { uint8_t *p; uint32_t l; long n; int i, al; CBS cbs; uint8_t message_type; if (s->s3->tmp.reuse_message) { s->s3->tmp.reuse_message = 0; if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { al = SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } *ok = 1; s->state = stn; s->init_msg = s->init_buf->data + 4; s->init_num = (int)s->s3->tmp.message_size; return s->init_num; } p = (uint8_t *)s->init_buf->data; if (s->state == st1) /* s->init_num < 4 */ { int skip_message; do { while (s->init_num < 4) { i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], 4 - s->init_num, 0); if (i <= 0) { s->rwstate = SSL_READING; *ok = 0; return i; } s->init_num += i; } skip_message = 0; if (!s->server && p[0] == SSL3_MT_HELLO_REQUEST) { /* * The server may always send 'Hello Request' * messages -- we are doing a handshake anyway * now, so ignore them if their format is * correct. Does not count for 'Finished' MAC. */ if (p[1] == 0 && p[2] == 0 && p[3] == 0) { s->init_num = 0; skip_message = 1; if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, p, 4, s, s->msg_callback_arg); } } } while (skip_message); /* s->init_num == 4 */ if ((mt >= 0) && (*p != mt)) { al = SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); goto f_err; } /* XXX remove call to n2l3 */ CBS_init(&cbs, p, 4); if (!CBS_get_u8(&cbs, &message_type) || !CBS_get_u24(&cbs, &l)) { SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB); goto err; } s->s3->tmp.message_type = message_type; if (l > (unsigned long)max) { al = SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); goto f_err; } if (l && !BUF_MEM_grow_clean(s->init_buf, l + 4)) { SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB); goto err; } s->s3->tmp.message_size = l; s->state = stn; s->init_msg = s->init_buf->data + 4; s->init_num = 0; } /* next state (stn) */ p = s->init_msg; n = s->s3->tmp.message_size - s->init_num; while (n > 0) { i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], n, 0); if (i <= 0) { s->rwstate = SSL_READING; *ok = 0; return i; } s->init_num += i; n -= i; } /* If receiving Finished, record MAC of prior handshake messages for * Finished verification. */ if (*s->init_buf->data == SSL3_MT_FINISHED) ssl3_take_mac(s); /* Feed this message into MAC computation. */ tls1_finish_mac(s, (uint8_t *)s->init_buf->data, s->init_num + 4); if (s->msg_callback) s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, (size_t)s->init_num + 4, s, s->msg_callback_arg); *ok = 1; return s->init_num; f_err: ssl3_send_alert(s, SSL3_AL_FATAL, al); err: *ok = 0; return (-1); }