X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_lib.c;h=581941ecb3099bd6fe4488a8d31b5159682cab48;hp=c92875f2d9dfe8ad6bf356752fbd6a1c9c172b96;hb=b8c49611bc26c8f9a980b814496a3069cd524b79;hpb=4020c0b33b25f829ca68976970d44227d115eb9e diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index c92875f2d9..581941ecb3 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -105,6 +105,8 @@ static const struct { }, }; +static int ssl_write_early_finish(SSL *s); + static int dane_ctx_enable(struct dane_ctx_st *dctx) { const EVP_MD **mdevp; @@ -471,6 +473,8 @@ int SSL_clear(SSL *s) clear_ciphers(s); s->first_packet = 0; + s->key_update = SSL_KEY_UPDATE_NONE; + /* Reset DANE verification result state */ s->dane.mdpth = -1; s->dane.pdpth = -1; @@ -549,6 +553,7 @@ SSL *SSL_new(SSL_CTX *ctx) s->mode = ctx->mode; s->max_cert_list = ctx->max_cert_list; s->references = 1; + s->max_early_data = ctx->max_early_data; /* * Earlier library versions used to copy the pointer to the CERT, not @@ -639,6 +644,8 @@ SSL *SSL_new(SSL_CTX *ctx) s->method = ctx->method; + s->key_update = SSL_KEY_UPDATE_NONE; + if (!s->method->ssl_new(s)) goto err; @@ -1010,6 +1017,8 @@ void SSL_free(SSL *s) #endif OPENSSL_free(s->ext.ocsp.resp); OPENSSL_free(s->ext.alpn); + OPENSSL_free(s->ext.tls13_cookie); + OPENSSL_free(s->clienthello); sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free); @@ -1314,7 +1323,7 @@ int SSL_has_pending(const SSL *s) * data. That data may not result in any application data, or we may fail * to parse the records for some reason. */ - if (SSL_pending(s)) + if (RECORD_LAYER_processed_read_pending(&s->rlayer)) return 1; return RECORD_LAYER_read_pending(&s->rlayer); @@ -1527,6 +1536,47 @@ static int ssl_io_intern(void *vargs) return -1; } +int ssl_read_internal(SSL *s, void *buf, size_t num, size_t *readbytes) +{ + if (s->handshake_func == NULL) { + SSLerr(SSL_F_SSL_READ_INTERNAL, SSL_R_UNINITIALIZED); + return -1; + } + + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + return 0; + } + + if (s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY + || s->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY) { + SSLerr(SSL_F_SSL_READ_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + /* + * If we are a client and haven't received the ServerHello etc then we + * better do that + */ + ossl_statem_check_finish_init(s, 0); + + if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { + struct ssl_async_args args; + int ret; + + args.s = s; + args.buf = buf; + args.num = num; + args.type = READFUNC; + args.f.func_read = s->method->ssl_read; + + ret = ssl_start_async_job(s, &args, ssl_io_intern); + *readbytes = s->asyncrw; + return ret; + } else { + return s->method->ssl_read(s, buf, num, readbytes); + } +} + int SSL_read(SSL *s, void *buf, int num) { int ret; @@ -1537,7 +1587,7 @@ int SSL_read(SSL *s, void *buf, int num) return -1; } - ret = SSL_read_ex(s, buf, (size_t)num, &readbytes); + ret = ssl_read_internal(s, buf, (size_t)num, &readbytes); /* * The cast is safe here because ret should be <= INT_MAX because num is @@ -1550,17 +1600,96 @@ int SSL_read(SSL *s, void *buf, int num) } int SSL_read_ex(SSL *s, void *buf, size_t num, size_t *readbytes) +{ + int ret = ssl_read_internal(s, buf, num, readbytes); + + if (ret < 0) + ret = 0; + return ret; +} + +int SSL_read_early_data(SSL *s, void *buf, size_t num, size_t *readbytes) +{ + int ret; + + if (!s->server) { + SSLerr(SSL_F_SSL_READ_EARLY_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return SSL_READ_EARLY_DATA_ERROR; + } + + switch (s->early_data_state) { + case SSL_EARLY_DATA_NONE: + if (!SSL_in_before(s)) { + SSLerr(SSL_F_SSL_READ_EARLY_DATA, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return SSL_READ_EARLY_DATA_ERROR; + } + /* fall through */ + + case SSL_EARLY_DATA_ACCEPT_RETRY: + s->early_data_state = SSL_EARLY_DATA_ACCEPTING; + ret = SSL_accept(s); + if (ret <= 0) { + /* NBIO or error */ + s->early_data_state = SSL_EARLY_DATA_ACCEPT_RETRY; + return SSL_READ_EARLY_DATA_ERROR; + } + /* fall through */ + + case SSL_EARLY_DATA_READ_RETRY: + if (s->ext.early_data == SSL_EARLY_DATA_ACCEPTED) { + s->early_data_state = SSL_EARLY_DATA_READING; + ret = SSL_read_ex(s, buf, num, readbytes); + /* + * Record layer will call ssl_end_of_early_data_seen() if we see + * that alert - which updates the early_data_state to + * SSL_EARLY_DATA_FINISHED_READING + */ + if (ret > 0 || (ret <= 0 && s->early_data_state + != SSL_EARLY_DATA_FINISHED_READING)) { + s->early_data_state = SSL_EARLY_DATA_READ_RETRY; + return ret > 0 ? SSL_READ_EARLY_DATA_SUCCESS + : SSL_READ_EARLY_DATA_ERROR; + } + } else { + s->early_data_state = SSL_EARLY_DATA_FINISHED_READING; + } + *readbytes = 0; + return SSL_READ_EARLY_DATA_FINISH; + + default: + SSLerr(SSL_F_SSL_READ_EARLY_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return SSL_READ_EARLY_DATA_ERROR; + } +} + +int ssl_end_of_early_data_seen(SSL *s) +{ + if (s->early_data_state == SSL_EARLY_DATA_READING + || s->early_data_state == SSL_EARLY_DATA_READ_RETRY) { + s->early_data_state = SSL_EARLY_DATA_FINISHED_READING; + ossl_statem_finish_early_data(s); + return 1; + } + + return 0; +} + +int SSL_get_early_data_status(const SSL *s) +{ + return s->ext.early_data; +} + +static int ssl_peek_internal(SSL *s, void *buf, size_t num, size_t *readbytes) { if (s->handshake_func == NULL) { - SSLerr(SSL_F_SSL_READ_EX, SSL_R_UNINITIALIZED); + SSLerr(SSL_F_SSL_PEEK_INTERNAL, SSL_R_UNINITIALIZED); return -1; } if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - s->rwstate = SSL_NOTHING; - return (0); + return 0; } - if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { struct ssl_async_args args; int ret; @@ -1569,13 +1698,13 @@ int SSL_read_ex(SSL *s, void *buf, size_t num, size_t *readbytes) args.buf = buf; args.num = num; args.type = READFUNC; - args.f.func_read = s->method->ssl_read; + args.f.func_read = s->method->ssl_peek; ret = ssl_start_async_job(s, &args, ssl_io_intern); *readbytes = s->asyncrw; return ret; } else { - return s->method->ssl_read(s, buf, num, readbytes); + return s->method->ssl_peek(s, buf, num, readbytes); } } @@ -1589,7 +1718,7 @@ int SSL_peek(SSL *s, void *buf, int num) return -1; } - ret = SSL_peek_ex(s, buf, (size_t)num, &readbytes); + ret = ssl_peek_internal(s, buf, (size_t)num, &readbytes); /* * The cast is safe here because ret should be <= INT_MAX because num is @@ -1601,31 +1730,60 @@ int SSL_peek(SSL *s, void *buf, int num) return ret; } + int SSL_peek_ex(SSL *s, void *buf, size_t num, size_t *readbytes) +{ + int ret = ssl_peek_internal(s, buf, num, readbytes); + + if (ret < 0) + ret = 0; + return ret; +} + +int ssl_write_internal(SSL *s, const void *buf, size_t num, size_t *written) { if (s->handshake_func == NULL) { - SSLerr(SSL_F_SSL_PEEK_EX, SSL_R_UNINITIALIZED); + SSLerr(SSL_F_SSL_WRITE_INTERNAL, SSL_R_UNINITIALIZED); return -1; } - if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { - return (0); + if (s->shutdown & SSL_SENT_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + SSLerr(SSL_F_SSL_WRITE_INTERNAL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) { + /* + * We're still writing early data. We need to stop that so we can write + * normal data + */ + if (!ssl_write_early_finish(s)) + return 0; + } else if (s->early_data_state == SSL_EARLY_DATA_CONNECT_RETRY + || s->early_data_state == SSL_EARLY_DATA_ACCEPT_RETRY + || s->early_data_state == SSL_EARLY_DATA_READ_RETRY) { + SSLerr(SSL_F_SSL_WRITE_INTERNAL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; } + /* If we are a client and haven't sent the Finished we better do that */ + ossl_statem_check_finish_init(s, 1); + if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { - struct ssl_async_args args; int ret; + struct ssl_async_args args; args.s = s; - args.buf = buf; + args.buf = (void *)buf; args.num = num; - args.type = READFUNC; - args.f.func_read = s->method->ssl_peek; + args.type = WRITEFUNC; + args.f.func_write = s->method->ssl_write; ret = ssl_start_async_job(s, &args, ssl_io_intern); - *readbytes = s->asyncrw; + *written = s->asyncrw; return ret; } else { - return s->method->ssl_peek(s, buf, num, readbytes); + return s->method->ssl_write(s, buf, num, written); } } @@ -1639,7 +1797,7 @@ int SSL_write(SSL *s, const void *buf, int num) return -1; } - ret = SSL_write_ex(s, buf, (size_t)num, &written); + ret = ssl_write_internal(s, buf, (size_t)num, &written); /* * The cast is safe here because ret should be <= INT_MAX because num is @@ -1653,33 +1811,82 @@ int SSL_write(SSL *s, const void *buf, int num) int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written) { - if (s->handshake_func == NULL) { - SSLerr(SSL_F_SSL_WRITE_EX, SSL_R_UNINITIALIZED); - return -1; - } + int ret = ssl_write_internal(s, buf, num, written); - if (s->shutdown & SSL_SENT_SHUTDOWN) { - s->rwstate = SSL_NOTHING; - SSLerr(SSL_F_SSL_WRITE_EX, SSL_R_PROTOCOL_IS_SHUTDOWN); - return (-1); - } + if (ret < 0) + ret = 0; + return ret; +} - if ((s->mode & SSL_MODE_ASYNC) && ASYNC_get_current_job() == NULL) { - int ret; - struct ssl_async_args args; +int SSL_write_early_data(SSL *s, const void *buf, size_t num, size_t *written) +{ + int ret; - args.s = s; - args.buf = (void *)buf; - args.num = num; - args.type = WRITEFUNC; - args.f.func_write = s->method->ssl_write; + switch (s->early_data_state) { + case SSL_EARLY_DATA_NONE: + if (s->server + || !SSL_in_before(s) + || s->session == NULL + || s->session->ext.max_early_data == 0) { + SSLerr(SSL_F_SSL_WRITE_EARLY_DATA, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + /* fall through */ + + case SSL_EARLY_DATA_CONNECT_RETRY: + s->early_data_state = SSL_EARLY_DATA_CONNECTING; + ret = SSL_connect(s); + if (ret <= 0) { + /* NBIO or error */ + s->early_data_state = SSL_EARLY_DATA_CONNECT_RETRY; + return 0; + } + /* fall through */ - ret = ssl_start_async_job(s, &args, ssl_io_intern); - *written = s->asyncrw; + case SSL_EARLY_DATA_WRITE_RETRY: + s->early_data_state = SSL_EARLY_DATA_WRITING; + ret = SSL_write_ex(s, buf, num, written); + s->early_data_state = SSL_EARLY_DATA_WRITE_RETRY; return ret; - } else { - return s->method->ssl_write(s, buf, num, written); + + case SSL_EARLY_DATA_READ_RETRY: + /* We are a server writing to an unauthenticated client */ + s->early_data_state = SSL_EARLY_DATA_UNAUTH_WRITING; + ret = SSL_write_ex(s, buf, num, written); + s->early_data_state = SSL_EARLY_DATA_READ_RETRY; + return ret; + + default: + SSLerr(SSL_F_SSL_WRITE_EARLY_DATA, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } +} + +static int ssl_write_early_finish(SSL *s) +{ + int ret; + + if (s->early_data_state != SSL_EARLY_DATA_WRITE_RETRY) { + SSLerr(SSL_F_SSL_WRITE_EARLY_FINISH, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; } + + s->early_data_state = SSL_EARLY_DATA_WRITING; + ret = ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_END_OF_EARLY_DATA); + if (ret <= 0) { + s->early_data_state = SSL_EARLY_DATA_WRITE_RETRY; + return 0; + } + s->early_data_state = SSL_EARLY_DATA_FINISHED_WRITING; + /* + * We set the enc_write_ctx back to NULL because we may end up writing + * in cleartext again if we get a HelloRetryRequest from the server. + */ + EVP_CIPHER_CTX_free(s->enc_write_ctx); + s->enc_write_ctx = NULL; + ossl_statem_set_in_init(s, 1); + return 1; } int SSL_shutdown(SSL *s) @@ -1714,14 +1921,45 @@ int SSL_shutdown(SSL *s) } } -int SSL_renegotiate(SSL *s) +int SSL_key_update(SSL *s, int updatetype) { /* - * TODO(TLS1.3): Return an error for now. Perhaps we should do a KeyUpdate - * instead when we support that? + * TODO(TLS1.3): How will applications know whether TLSv1.3 has been + * negotiated, and that it is appropriate to call SSL_key_update() instead + * of SSL_renegotiate(). */ - if (SSL_IS_TLS13(s)) + if (!SSL_IS_TLS13(s)) { + SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_WRONG_SSL_VERSION); + return 0; + } + + if (updatetype != SSL_KEY_UPDATE_NOT_REQUESTED + && updatetype != SSL_KEY_UPDATE_REQUESTED) { + SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_INVALID_KEY_UPDATE_TYPE); + return 0; + } + + if (!SSL_is_init_finished(s)) { + SSLerr(SSL_F_SSL_KEY_UPDATE, SSL_R_STILL_IN_INIT); + return 0; + } + + ossl_statem_set_in_init(s, 1); + s->key_update = updatetype; + return 1; +} + +int SSL_get_key_update_type(SSL *s) +{ + return s->key_update; +} + +int SSL_renegotiate(SSL *s) +{ + if (SSL_IS_TLS13(s)) { + SSLerr(SSL_F_SSL_RENEGOTIATE, SSL_R_WRONG_SSL_VERSION); return 0; + } if (s->renegotiate == 0) s->renegotiate = 1; @@ -1733,10 +1971,6 @@ int SSL_renegotiate(SSL *s) int SSL_renegotiate_abbreviated(SSL *s) { - /* - * TODO(TLS1.3): Return an error for now. Perhaps we should do a KeyUpdate - * instead when we support that? - */ if (SSL_IS_TLS13(s)) return 0; @@ -2444,11 +2678,6 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) if (!OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL)) return NULL; - if (FIPS_mode() && (meth->version < TLS1_VERSION)) { - SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_AT_LEAST_TLS_1_0_NEEDED_IN_FIPS_MODE); - return NULL; - } - if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); goto err; @@ -2567,6 +2796,12 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) ret->ext.status_type = TLSEXT_STATUSTYPE_nothing; + /* + * Default max early data is a fully loaded single record. Could be split + * across multiple records in practice + */ + ret->max_early_data = SSL3_RT_MAX_PLAIN_LENGTH; + return ret; err: SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE); @@ -2737,8 +2972,8 @@ void ssl_set_masks(SSL *s) #endif rsa_enc = pvalid[SSL_PKEY_RSA] & CERT_PKEY_VALID; - rsa_sign = pvalid[SSL_PKEY_RSA] & CERT_PKEY_SIGN; - dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_SIGN; + rsa_sign = pvalid[SSL_PKEY_RSA] & CERT_PKEY_VALID; + dsa_sign = pvalid[SSL_PKEY_DSA_SIGN] & CERT_PKEY_VALID; #ifndef OPENSSL_NO_EC have_ecc_cert = pvalid[SSL_PKEY_ECC] & CERT_PKEY_VALID; #endif @@ -2833,97 +3068,17 @@ int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) #endif -static int ssl_get_server_cert_index(const SSL *s) -{ - int idx; - - if (SSL_IS_TLS13(s)) { - if (s->s3->tmp.sigalg == NULL) { - SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX, ERR_R_INTERNAL_ERROR); - return -1; - } - return s->s3->tmp.cert_idx; - } - - idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher); - if (idx == SSL_PKEY_GOST_EC) { - if (s->cert->pkeys[SSL_PKEY_GOST12_512].x509) - idx = SSL_PKEY_GOST12_512; - else if (s->cert->pkeys[SSL_PKEY_GOST12_256].x509) - idx = SSL_PKEY_GOST12_256; - else if (s->cert->pkeys[SSL_PKEY_GOST01].x509) - idx = SSL_PKEY_GOST01; - else - idx = -1; - } - if (idx == -1) - SSLerr(SSL_F_SSL_GET_SERVER_CERT_INDEX, ERR_R_INTERNAL_ERROR); - return idx; -} - -CERT_PKEY *ssl_get_server_send_pkey(SSL *s) -{ - CERT *c; - int i; - - c = s->cert; - if (!s->s3 || !s->s3->tmp.new_cipher) - return NULL; - ssl_set_masks(s); - - i = ssl_get_server_cert_index(s); - - /* This may or may not be an error. */ - if (i < 0) - return NULL; - - /* May be NULL. */ - return &c->pkeys[i]; -} - -EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, - const EVP_MD **pmd) -{ - unsigned long alg_a; - CERT *c; - int idx = -1; - - alg_a = cipher->algorithm_auth; - c = s->cert; - - if (alg_a & SSL_aDSS && c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL) - idx = SSL_PKEY_DSA_SIGN; - else if (alg_a & SSL_aRSA && c->pkeys[SSL_PKEY_RSA].privatekey != NULL) - idx = SSL_PKEY_RSA; - else if (alg_a & SSL_aECDSA && - c->pkeys[SSL_PKEY_ECC].privatekey != NULL) - idx = SSL_PKEY_ECC; - if (idx == -1) { - SSLerr(SSL_F_SSL_GET_SIGN_PKEY, ERR_R_INTERNAL_ERROR); - return (NULL); - } - if (pmd) - *pmd = s->s3->tmp.md[idx]; - return c->pkeys[idx].privatekey; -} - int ssl_get_server_cert_serverinfo(SSL *s, const unsigned char **serverinfo, size_t *serverinfo_length) { - CERT *c = NULL; - int i = 0; + CERT_PKEY *cpk = s->s3->tmp.cert; *serverinfo_length = 0; - c = s->cert; - i = ssl_get_server_cert_index(s); - - if (i == -1) - return 0; - if (c->pkeys[i].serverinfo == NULL) + if (cpk == NULL || cpk->serverinfo == NULL) return 0; - *serverinfo = c->pkeys[i].serverinfo; - *serverinfo_length = c->pkeys[i].serverinfo_length; + *serverinfo = cpk->serverinfo; + *serverinfo_length = cpk->serverinfo_length; return 1; } @@ -3061,15 +3216,14 @@ int SSL_get_error(const SSL *s, int i) return (SSL_ERROR_SYSCALL); } } - if (SSL_want_x509_lookup(s)) { + if (SSL_want_x509_lookup(s)) return (SSL_ERROR_WANT_X509_LOOKUP); - } - if (SSL_want_async(s)) { + if (SSL_want_async(s)) return SSL_ERROR_WANT_ASYNC; - } - if (SSL_want_async_job(s)) { + if (SSL_want_async_job(s)) return SSL_ERROR_WANT_ASYNC_JOB; - } + if (SSL_want_early(s)) + return SSL_ERROR_WANT_EARLY; if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) && (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) @@ -3098,6 +3252,15 @@ int SSL_do_handshake(SSL *s) return -1; } + if (s->early_data_state == SSL_EARLY_DATA_WRITE_RETRY) { + int edfin; + + edfin = ssl_write_early_finish(s); + if (edfin <= 0) + return edfin; + } + ossl_statem_check_finish_init(s, -1); + s->method->ssl_renegotiate_check(s, 0); if (SSL_in_init(s) || SSL_in_before(s)) { @@ -3633,11 +3796,6 @@ void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) return (CRYPTO_get_ex_data(&s->ex_data, idx)); } -int ssl_ok(SSL *s) -{ - return (1); -} - X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) { return (ctx->cert_store); @@ -4354,7 +4512,84 @@ const CTLOG_STORE *SSL_CTX_get0_ctlog_store(const SSL_CTX *ctx) return ctx->ctlog_store; } -#endif +#endif /* OPENSSL_NO_CT */ + +void SSL_CTX_set_early_cb(SSL_CTX *c, SSL_early_cb_fn cb, void *arg) +{ + c->early_cb = cb; + c->early_cb_arg = arg; +} + +int SSL_early_isv2(SSL *s) +{ + if (s->clienthello == NULL) + return 0; + return s->clienthello->isv2; +} + +unsigned int SSL_early_get0_legacy_version(SSL *s) +{ + if (s->clienthello == NULL) + return 0; + return s->clienthello->legacy_version; +} + +size_t SSL_early_get0_random(SSL *s, const unsigned char **out) +{ + if (s->clienthello == NULL) + return 0; + if (out != NULL) + *out = s->clienthello->random; + return SSL3_RANDOM_SIZE; +} + +size_t SSL_early_get0_session_id(SSL *s, const unsigned char **out) +{ + if (s->clienthello == NULL) + return 0; + if (out != NULL) + *out = s->clienthello->session_id; + return s->clienthello->session_id_len; +} + +size_t SSL_early_get0_ciphers(SSL *s, const unsigned char **out) +{ + if (s->clienthello == NULL) + return 0; + if (out != NULL) + *out = PACKET_data(&s->clienthello->ciphersuites); + return PACKET_remaining(&s->clienthello->ciphersuites); +} + +size_t SSL_early_get0_compression_methods(SSL *s, const unsigned char **out) +{ + if (s->clienthello == NULL) + return 0; + if (out != NULL) + *out = s->clienthello->compressions; + return s->clienthello->compressions_len; +} + +int SSL_early_get0_ext(SSL *s, unsigned int type, const unsigned char **out, + size_t *outlen) +{ + size_t i; + RAW_EXTENSION *r; + + if (s->clienthello == NULL) + return 0; + for (i = 0; i < s->clienthello->pre_proc_exts_len; ++i) { + r = s->clienthello->pre_proc_exts + i; + if (r->present && r->type == type) { + if (out != NULL) + *out = PACKET_data(&r->data); + if (outlen != NULL) + *outlen = PACKET_remaining(&r->data); + return 1; + } + } + return 0; +} void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, SSL_CTX_keylog_cb_func cb) { @@ -4451,3 +4686,187 @@ int ssl_log_secret(SSL *ssl, secret_len); } +#define SSLV2_CIPHER_LEN 3 + +int ssl_cache_cipherlist(SSL *s, PACKET *cipher_suites, int sslv2format, + int *al) +{ + int n; + + n = sslv2format ? SSLV2_CIPHER_LEN : TLS_CIPHER_LEN; + + if (PACKET_remaining(cipher_suites) == 0) { + SSLerr(SSL_F_SSL_CACHE_CIPHERLIST, SSL_R_NO_CIPHERS_SPECIFIED); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + if (PACKET_remaining(cipher_suites) % n != 0) { + SSLerr(SSL_F_SSL_CACHE_CIPHERLIST, + SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + OPENSSL_free(s->s3->tmp.ciphers_raw); + s->s3->tmp.ciphers_raw = NULL; + s->s3->tmp.ciphers_rawlen = 0; + + if (sslv2format) { + size_t numciphers = PACKET_remaining(cipher_suites) / n; + PACKET sslv2ciphers = *cipher_suites; + unsigned int leadbyte; + unsigned char *raw; + + /* + * We store the raw ciphers list in SSLv3+ format so we need to do some + * preprocessing to convert the list first. If there are any SSLv2 only + * ciphersuites with a non-zero leading byte then we are going to + * slightly over allocate because we won't store those. But that isn't a + * problem. + */ + raw = OPENSSL_malloc(numciphers * TLS_CIPHER_LEN); + s->s3->tmp.ciphers_raw = raw; + if (raw == NULL) { + *al = SSL_AD_INTERNAL_ERROR; + goto err; + } + for (s->s3->tmp.ciphers_rawlen = 0; + PACKET_remaining(&sslv2ciphers) > 0; + raw += TLS_CIPHER_LEN) { + if (!PACKET_get_1(&sslv2ciphers, &leadbyte) + || (leadbyte == 0 + && !PACKET_copy_bytes(&sslv2ciphers, raw, + TLS_CIPHER_LEN)) + || (leadbyte != 0 + && !PACKET_forward(&sslv2ciphers, TLS_CIPHER_LEN))) { + *al = SSL_AD_INTERNAL_ERROR; + OPENSSL_free(s->s3->tmp.ciphers_raw); + s->s3->tmp.ciphers_raw = NULL; + s->s3->tmp.ciphers_rawlen = 0; + goto err; + } + if (leadbyte == 0) + s->s3->tmp.ciphers_rawlen += TLS_CIPHER_LEN; + } + } else if (!PACKET_memdup(cipher_suites, &s->s3->tmp.ciphers_raw, + &s->s3->tmp.ciphers_rawlen)) { + *al = SSL_AD_INTERNAL_ERROR; + goto err; + } + return 1; + err: + return 0; +} + +int SSL_bytes_to_cipher_list(SSL *s, const unsigned char *bytes, size_t len, + int isv2format, STACK_OF(SSL_CIPHER) **sk, + STACK_OF(SSL_CIPHER) **scsvs) +{ + int alert; + PACKET pkt; + + if (!PACKET_buf_init(&pkt, bytes, len)) + return 0; + return bytes_to_cipher_list(s, &pkt, sk, scsvs, isv2format, &alert); +} + +int bytes_to_cipher_list(SSL *s, PACKET *cipher_suites, + STACK_OF(SSL_CIPHER) **skp, + STACK_OF(SSL_CIPHER) **scsvs_out, + int sslv2format, int *al) +{ + const SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *sk = NULL; + STACK_OF(SSL_CIPHER) *scsvs = NULL; + int n; + /* 3 = SSLV2_CIPHER_LEN > TLS_CIPHER_LEN = 2. */ + unsigned char cipher[SSLV2_CIPHER_LEN]; + + n = sslv2format ? SSLV2_CIPHER_LEN : TLS_CIPHER_LEN; + + if (PACKET_remaining(cipher_suites) == 0) { + SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, SSL_R_NO_CIPHERS_SPECIFIED); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + if (PACKET_remaining(cipher_suites) % n != 0) { + SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, + SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + sk = sk_SSL_CIPHER_new_null(); + scsvs = sk_SSL_CIPHER_new_null(); + if (sk == NULL || scsvs == NULL) { + SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + *al = SSL_AD_INTERNAL_ERROR; + goto err; + } + + while (PACKET_copy_bytes(cipher_suites, cipher, n)) { + /* + * SSLv3 ciphers wrapped in an SSLv2-compatible ClientHello have the + * first byte set to zero, while true SSLv2 ciphers have a non-zero + * first byte. We don't support any true SSLv2 ciphers, so skip them. + */ + if (sslv2format && cipher[0] != '\0') + continue; + + /* For SSLv2-compat, ignore leading 0-byte. */ + c = ssl_get_cipher_by_char(s, sslv2format ? &cipher[1] : cipher, 1); + if (c != NULL) { + if ((c->valid && !sk_SSL_CIPHER_push(sk, c)) || + (!c->valid && !sk_SSL_CIPHER_push(scsvs, c))) { + SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + *al = SSL_AD_INTERNAL_ERROR; + goto err; + } + } + } + if (PACKET_remaining(cipher_suites) > 0) { + *al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_BYTES_TO_CIPHER_LIST, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (skp != NULL) + *skp = sk; + else + sk_SSL_CIPHER_free(sk); + if (scsvs_out != NULL) + *scsvs_out = scsvs; + else + sk_SSL_CIPHER_free(scsvs); + return 1; + err: + sk_SSL_CIPHER_free(sk); + sk_SSL_CIPHER_free(scsvs); + return 0; +} + +int SSL_CTX_set_max_early_data(SSL_CTX *ctx, uint32_t max_early_data) +{ + ctx->max_early_data = max_early_data; + + return 1; +} + +uint32_t SSL_CTX_get_max_early_data(const SSL_CTX *ctx) +{ + return ctx->max_early_data; +} + +int SSL_set_max_early_data(SSL *s, uint32_t max_early_data) +{ + s->max_early_data = max_early_data; + + return 1; +} + +uint32_t SSL_get_max_early_data(const SSL_CTX *s) +{ + return s->max_early_data; +}