X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_lib.c;h=accef0c0ce3d28179b596f2651ec98089b9cb90c;hp=8094e2fde8b050554cf6b11b9d30edfbece1f038;hb=0e1d6ecf37ea33ad963249cdb5efebeb04299033;hpb=48e5119a6b83fd5781174d3b524cb8d1dc411649 diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 8094e2fde8..accef0c0ce 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -590,6 +590,7 @@ int SSL_clear(SSL *s) OPENSSL_free(s->psksession_id); s->psksession_id = NULL; s->psksession_id_len = 0; + s->hello_retry_request = 0; s->error = 0; s->hit = 0; @@ -613,6 +614,9 @@ int SSL_clear(SSL *s) s->key_update = SSL_KEY_UPDATE_NONE; + EVP_MD_CTX_free(s->pha_dgst); + s->pha_dgst = NULL; + /* Reset DANE verification result state */ s->dane.mdpth = -1; s->dane.pdpth = -1; @@ -690,8 +694,7 @@ SSL *SSL_new(SSL_CTX *ctx) */ if (RAND_get_rand_method() == RAND_OpenSSL()) { s->drbg = - RAND_DRBG_new(RAND_DRBG_NID, RAND_DRBG_FLAG_CTR_USE_DF, - RAND_DRBG_get0_public()); + RAND_DRBG_new(RAND_DRBG_NID, 0, RAND_DRBG_get0_public()); if (s->drbg == NULL || RAND_DRBG_instantiate(s->drbg, (const unsigned char *) SSL_version_str, @@ -1185,6 +1188,8 @@ void SSL_free(SSL *s) OPENSSL_free(s->ext.alpn); OPENSSL_free(s->ext.tls13_cookie); OPENSSL_free(s->clienthello); + OPENSSL_free(s->pha_context); + EVP_MD_CTX_free(s->pha_dgst); sk_X509_NAME_pop_free(s->ca_names, X509_NAME_free); @@ -2448,10 +2453,12 @@ STACK_OF(SSL_CIPHER) *SSL_get1_supported_ciphers(SSL *s) { STACK_OF(SSL_CIPHER) *sk = NULL, *ciphers; int i; + ciphers = SSL_get_ciphers(s); if (!ciphers) return NULL; - ssl_set_client_disabled(s); + if (!ssl_set_client_disabled(s)) + return NULL; for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { const SSL_CIPHER *c = sk_SSL_CIPHER_value(ciphers, i); if (!ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_SUPPORTED, 0)) { @@ -2803,6 +2810,18 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, contextlen, use_context); } +int SSL_export_keying_material_early(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *context, + size_t contextlen) +{ + if (s->version != TLS1_3_VERSION) + return 0; + + return tls13_export_keying_material_early(s, out, olen, label, llen, + context, contextlen); +} + static unsigned long ssl_session_hash(const SSL_SESSION *a) { const unsigned char *session_id = a->session_id; @@ -2939,6 +2958,10 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) sizeof(ret->ext.tick_aes_key)) <= 0)) ret->options |= SSL_OP_NO_TICKET; + if (RAND_bytes(ret->ext.cookie_hmac_key, + sizeof(ret->ext.cookie_hmac_key)) <= 0) + goto err; + #ifndef OPENSSL_NO_SRP if (!SSL_CTX_SRP_CTX_init(ret)) goto err; @@ -2979,10 +3002,22 @@ 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 + * We cannot usefully set a default max_early_data here (which gets + * propagated in SSL_new(), for the following reason: setting the + * SSL field causes tls_construct_stoc_early_data() to tell the + * client that early data will be accepted when constructing a TLS 1.3 + * session ticket, and the client will accordingly send us early data + * when using that ticket (if the client has early data to send). + * However, in order for the early data to actually be consumed by + * the application, the application must also have calls to + * SSL_read_early_data(); otherwise we'll just skip past the early data + * and ignore it. So, since the application must add calls to + * SSL_read_early_data(), we also require them to add + * calls to SSL_CTX_set_max_early_data() in order to use early data, + * eliminating the bandwidth-wasting early data in the case described + * above. */ - ret->max_early_data = SSL3_RT_MAX_PLAIN_LENGTH; + ret->max_early_data = 0; return ret; err: @@ -3223,6 +3258,12 @@ void ssl_set_masks(SSL *s) && pvalid[SSL_PKEY_ED25519] & CERT_PKEY_EXPLICIT_SIGN && TLS1_get_version(s) == TLS1_2_VERSION) mask_a |= SSL_aECDSA; + + /* Allow Ed448 for TLS 1.2 if peer supports it */ + if (!(mask_a & SSL_aECDSA) && ssl_has_cert(s, SSL_PKEY_ED448) + && pvalid[SSL_PKEY_ED448] & CERT_PKEY_EXPLICIT_SIGN + && TLS1_get_version(s) == TLS1_2_VERSION) + mask_a |= SSL_aECDSA; #endif #ifndef OPENSSL_NO_EC @@ -5262,9 +5303,11 @@ int ssl_randbytes(SSL *s, unsigned char *rnd, size_t size) * serialization of SSL accesses for the needed concurrency protection * here. */ - return RAND_DRBG_generate(s->drbg, rnd, size, 0, NULL, 0); + return RAND_DRBG_bytes(s->drbg, rnd, size); } - return RAND_bytes(rnd, (int)size); + if (size > INT_MAX) + return 0; + return RAND_bytes(rnd, size); } __owur unsigned int ssl_get_max_send_fragment(const SSL *ssl) @@ -5291,3 +5334,75 @@ __owur unsigned int ssl_get_split_send_fragment(const SSL *ssl) /* return current SSL connection setting */ return ssl->split_send_fragment; } + +int SSL_stateless(SSL *s) +{ + int ret; + + /* Ensure there is no state left over from a previous invocation */ + if (!SSL_clear(s)) + return 0; + + ERR_clear_error(); + + s->s3->flags |= TLS1_FLAGS_STATELESS; + ret = SSL_accept(s); + s->s3->flags &= ~TLS1_FLAGS_STATELESS; + + if (ret > 0 && s->ext.cookieok) + return 1; + + return 0; +} + +void SSL_force_post_handshake_auth(SSL *ssl) +{ + ssl->pha_forced = 1; +} + +int SSL_verify_client_post_handshake(SSL *ssl) +{ + if (!SSL_IS_TLS13(ssl)) { + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_WRONG_SSL_VERSION); + return 0; + } + if (!ssl->server) { + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_NOT_SERVER); + return 0; + } + + if (!SSL_is_init_finished(ssl)) { + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_STILL_IN_INIT); + return 0; + } + + switch (ssl->post_handshake_auth) { + case SSL_PHA_NONE: + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_EXTENSION_NOT_RECEIVED); + return 0; + default: + case SSL_PHA_EXT_SENT: + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, ERR_R_INTERNAL_ERROR); + return 0; + case SSL_PHA_EXT_RECEIVED: + break; + case SSL_PHA_REQUEST_PENDING: + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_REQUEST_PENDING); + return 0; + case SSL_PHA_REQUESTED: + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_REQUEST_SENT); + return 0; + } + + ssl->post_handshake_auth = SSL_PHA_REQUEST_PENDING; + + /* checks verify_mode and algorithm_auth */ + if (!send_certificate_request(ssl)) { + ssl->post_handshake_auth = SSL_PHA_EXT_RECEIVED; /* restore on error */ + SSLerr(SSL_F_SSL_VERIFY_CLIENT_POST_HANDSHAKE, SSL_R_INVALID_CONFIG); + return 0; + } + + ossl_statem_set_in_init(ssl, 1); + return 1; +}