X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fstatem%2Fextensions.c;h=a5dda45a96e7ed76a3cda707a1383c0e2a6b97a8;hp=68d8cea0bdd58f4e8fcbd061c966f1b36c7c4476;hb=5626f634c31cfde48ccbbee243be29e0eb77171e;hpb=108d45df737f5b0a4842de02c3f8ff1b9b07306f diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index 68d8cea0bd..a5dda45a96 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -28,7 +28,6 @@ static int init_status_request(SSL *s, unsigned int context); static int init_npn(SSL *s, unsigned int context); #endif static int init_alpn(SSL *s, unsigned int context); -static int final_alpn(SSL *s, unsigned int context, int sent, int *al); static int init_sig_algs(SSL *s, unsigned int context); static int init_certificate_authorities(SSL *s, unsigned int context); static EXT_RETURN tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, @@ -91,7 +90,7 @@ typedef struct extensions_definition_st { /* * Definitions of all built-in extensions. NOTE: Changes in the number or order - * of these extensions should be mirrored with equivalent changes to the + * of these extensions should be mirrored with equivalent changes to the * indexes ( TLSEXT_IDX_* ) defined in ssl_locl.h. * Each extension has an initialiser, a client and * server side parser and a finaliser. The initialiser is called (if the @@ -207,7 +206,7 @@ static const EXTENSION_DEFINITION ext_defs[] = { SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_2_SERVER_HELLO | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS, init_alpn, tls_parse_ctos_alpn, tls_parse_stoc_alpn, - tls_construct_stoc_alpn, tls_construct_ctos_alpn, final_alpn + tls_construct_stoc_alpn, tls_construct_ctos_alpn, NULL }, #ifndef OPENSSL_NO_SRTP { @@ -462,6 +461,7 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, return 0; } + i = 0; while (PACKET_remaining(&extensions) > 0) { unsigned int type, idx; PACKET extension; @@ -518,6 +518,12 @@ int tls_collect_extensions(SSL *s, PACKET *packet, unsigned int context, thisex->data = extension; thisex->present = 1; thisex->type = type; + thisex->received_order = i++; + if (s->ext.debug_cb) + s->ext.debug_cb(s, !s->server, thisex->type, + PACKET_data(&thisex->data), + PACKET_remaining(&thisex->data), + s->ext.debug_arg); } } @@ -569,12 +575,6 @@ int tls_parse_extension(SSL *s, TLSEXT_INDEX idx, int context, if (!currext->present) return 1; - if (s->ext.debug_cb) - s->ext.debug_cb(s, !s->server, currext->type, - PACKET_data(&currext->data), - PACKET_remaining(&currext->data), - s->ext.debug_arg); - /* Skip if we've already parsed this extension */ if (currext->parsed) return 1; @@ -719,7 +719,7 @@ int tls_construct_extensions(SSL *s, WPACKET *pkt, unsigned int context, /* Add custom extensions first */ if ((context & SSL_EXT_CLIENT_HELLO) != 0) { - /* On the server side with initiase during ClientHello parsing */ + /* On the server side with initialise during ClientHello parsing */ custom_ext_init(&s->cert->custext); } if (!custom_ext_add(s, context, pkt, x, chainidx, max_version, &tmpal)) { @@ -936,44 +936,6 @@ static int init_alpn(SSL *s, unsigned int context) return 1; } -static int final_alpn(SSL *s, unsigned int context, int sent, int *al) -{ - const unsigned char *selected = NULL; - unsigned char selected_len = 0; - - if (!s->server) - return 1; - - if (s->ctx->ext.alpn_select_cb != NULL && s->s3->alpn_proposed != NULL) { - int r = s->ctx->ext.alpn_select_cb(s, &selected, &selected_len, - s->s3->alpn_proposed, - (unsigned int)s->s3->alpn_proposed_len, - s->ctx->ext.alpn_select_cb_arg); - - if (r == SSL_TLSEXT_ERR_OK) { - OPENSSL_free(s->s3->alpn_selected); - s->s3->alpn_selected = OPENSSL_memdup(selected, selected_len); - if (s->s3->alpn_selected == NULL) { - *al = SSL_AD_INTERNAL_ERROR; - return 0; - } - s->s3->alpn_selected_len = selected_len; -#ifndef OPENSSL_NO_NEXTPROTONEG - /* ALPN takes precedence over NPN. */ - s->s3->npn_seen = 0; -#endif - } else if (r == SSL_TLSEXT_ERR_NOACK) { - /* Behave as if no callback was present. */ - return 1; - } else { - *al = SSL_AD_NO_APPLICATION_PROTOCOL; - return 0; - } - } - - return 1; -} - static int init_sig_algs(SSL *s, unsigned int context) { /* Clear any signature algorithms extension received */ @@ -1116,7 +1078,7 @@ static int final_key_share(SSL *s, unsigned int context, int sent, int *al) && (!s->hit || (s->ext.psk_kex_mode & TLSEXT_KEX_MODE_FLAG_KE) == 0)) { /* Nothing left we can do - just fail */ - *al = SSL_AD_HANDSHAKE_FAILURE; + *al = SSL_AD_MISSING_EXTENSION; SSLerr(SSL_F_FINAL_KEY_SHARE, SSL_R_NO_SUITABLE_KEY_SHARE); return 0; } @@ -1225,21 +1187,60 @@ static int init_psk_kex_modes(SSL *s, unsigned int context) int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, size_t binderoffset, const unsigned char *binderin, - unsigned char *binderout, - SSL_SESSION *sess, int sign) + unsigned char *binderout, SSL_SESSION *sess, int sign, + int external) { EVP_PKEY *mackey = NULL; EVP_MD_CTX *mctx = NULL; unsigned char hash[EVP_MAX_MD_SIZE], binderkey[EVP_MAX_MD_SIZE]; unsigned char finishedkey[EVP_MAX_MD_SIZE], tmpbinder[EVP_MAX_MD_SIZE]; + unsigned char tmppsk[EVP_MAX_MD_SIZE]; + unsigned char *early_secret, *psk; const char resumption_label[] = "res binder"; - size_t bindersize, hashsize = EVP_MD_size(md); + const char external_label[] = "ext binder"; + const char nonce_label[] = "resumption"; + const char *label; + size_t bindersize, labelsize, hashsize = EVP_MD_size(md); int ret = -1; - /* Generate the early_secret */ - if (!tls13_generate_secret(s, md, NULL, sess->master_key, - sess->master_key_length, - (unsigned char *)&s->early_secret)) { + if (external) { + label = external_label; + labelsize = sizeof(external_label) - 1; + } else { + label = resumption_label; + labelsize = sizeof(resumption_label) - 1; + } + + if (sess->master_key_length != hashsize) { + SSLerr(SSL_F_TLS_PSK_DO_BINDER, SSL_R_BAD_PSK); + goto err; + } + + if (external) { + psk = sess->master_key; + } else { + psk = tmppsk; + if (!tls13_hkdf_expand(s, md, sess->master_key, + (const unsigned char *)nonce_label, + sizeof(nonce_label) - 1, sess->ext.tick_nonce, + sess->ext.tick_nonce_len, psk, hashsize)) { + SSLerr(SSL_F_TLS_PSK_DO_BINDER, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + /* + * Generate the early_secret. On the server side we've selected a PSK to + * resume with (internal or external) so we always do this. On the client + * side we do this for a non-external (i.e. resumption) PSK so that it + * is in place for sending early data. For client side external PSK we + * generate it but store it away for later use. + */ + if (s->server || !external) + early_secret = (unsigned char *)s->early_secret; + else + early_secret = (unsigned char *)sess->early_secret; + if (!tls13_generate_secret(s, md, NULL, psk, hashsize, early_secret)) { SSLerr(SSL_F_TLS_PSK_DO_BINDER, ERR_R_INTERNAL_ERROR); goto err; } @@ -1257,10 +1258,8 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart, } /* Generate the binder key */ - if (!tls13_hkdf_expand(s, md, s->early_secret, - (unsigned char *)resumption_label, - sizeof(resumption_label) - 1, hash, binderkey, - hashsize)) { + if (!tls13_hkdf_expand(s, md, early_secret, (unsigned char *)label, + labelsize, hash, hashsize, binderkey, hashsize)) { SSLerr(SSL_F_TLS_PSK_DO_BINDER, ERR_R_INTERNAL_ERROR); goto err; }