X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=8bed38d6d4718290bb7b0ec83a115ef9bfb0ba89;hp=e0f3425c5af9b5423d105875ce05164164eca620;hb=9cd50f738ff55eae2a64f872492d3a7ce115f18d;hpb=5087afa108add621b4dd3dca0d921bf7774373d6 diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index e0f3425c5a..8bed38d6d4 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -140,6 +140,49 @@ SSL3_ENC_METHOD TLSv1_enc_data={ TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE, tls1_alert_code, tls1_export_keying_material, + 0, + SSL3_HM_HEADER_LENGTH, + ssl3_set_handshake_header, + ssl3_handshake_write + }; + +SSL3_ENC_METHOD TLSv1_1_enc_data={ + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + tls1_export_keying_material, + SSL_ENC_FLAG_EXPLICIT_IV, + SSL3_HM_HEADER_LENGTH, + ssl3_set_handshake_header, + ssl3_handshake_write + }; + +SSL3_ENC_METHOD TLSv1_2_enc_data={ + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + tls1_export_keying_material, + SSL_ENC_FLAG_EXPLICIT_IV|SSL_ENC_FLAG_SIGALGS|SSL_ENC_FLAG_SHA256_PRF + |SSL_ENC_FLAG_TLS1_2_CIPHERS, + SSL3_HM_HEADER_LENGTH, + ssl3_set_handshake_header, + ssl3_handshake_write }; long tls1_default_timeout(void) @@ -966,8 +1009,8 @@ void ssl_set_client_disabled(SSL *s) int have_rsa = 0, have_dsa = 0, have_ecdsa = 0; c->mask_a = 0; c->mask_k = 0; - /* If less than TLS 1.2 don't allow TLS 1.2 only ciphers */ - if (TLS1_get_version(s) < TLS1_2_VERSION) + /* Don't allow TLS 1.2 only ciphers if we don't suppport them */ + if (!SSL_CLIENT_USE_TLS1_2_CIPHERS(s)) c->mask_ssl = SSL_TLSV1_2; else c->mask_ssl = 0; @@ -1053,7 +1096,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha #ifndef OPENSSL_NO_EC /* See if we support any ECC ciphersuites */ int using_ecc = 0; - if (s->version != DTLS1_VERSION && s->version >= TLS1_VERSION) + if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) { int i; unsigned long alg_k, alg_a; @@ -1255,7 +1298,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha } skip_ext: - if (TLS1_get_client_version(s) >= TLS1_2_VERSION) + if (SSL_USE_SIGALGS(s)) { size_t salglen; const unsigned char *salg; @@ -1270,8 +1313,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha } #ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->client_opaque_prf_input != NULL && - s->version != DTLS1_VERSION) + if (s->s3->client_opaque_prf_input != NULL) { size_t col = s->s3->client_opaque_prf_input_len; @@ -1288,8 +1330,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha } #endif - if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp && - s->version != DTLS1_VERSION) + if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { int i; long extlen, idlen, itmp; @@ -1389,11 +1430,11 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha /* 1 byte for the list (we only support audit proofs) */ if (s->ctx->tlsext_authz_server_audit_proof_cb != NULL) { - size_t lenmax; const unsigned short ext_len = 2; const unsigned char list_len = 1; - if ((lenmax = limit - ret - 6) < 0) return NULL; + if (limit < ret + 6) + return NULL; s2n(TLSEXT_TYPE_server_authz, ret); /* Extension length: 2 bytes */ @@ -1402,6 +1443,40 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, unsigned cha *(ret++) = TLSEXT_AUTHZDATAFORMAT_audit_proof; } + /* Add custom TLS Extensions to ClientHello */ + if (s->ctx->custom_cli_ext_records_count) + { + size_t i; + custom_cli_ext_record* record; + + for (i = 0; i < s->ctx->custom_cli_ext_records_count; i++) + { + const unsigned char* out = NULL; + unsigned short outlen = 0; + + record = &s->ctx->custom_cli_ext_records[i]; + /* NULL callback sends empty extension */ + /* -1 from callback omits extension */ + if (record->fn1) + { + int cb_retval = 0; + cb_retval = record->fn1(s, record->ext_type, + &out, &outlen, + record->arg); + if (cb_retval == 0) + return NULL; /* error */ + if (cb_retval == -1) + continue; /* skip this extension */ + } + if (limit < ret + 4 + outlen) + return NULL; + s2n(record->ext_type, ret); + s2n(outlen, ret); + memcpy(ret, out, outlen); + ret += outlen; + } + } + if ((extdatalen = ret-p-2) == 0) return p; @@ -1461,7 +1536,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha } #ifndef OPENSSL_NO_EC - if (using_ecc && s->version != DTLS1_VERSION) + if (using_ecc) { const unsigned char *plist; size_t plistlen; @@ -1504,8 +1579,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha } #ifdef TLSEXT_TYPE_opaque_prf_input - if (s->s3->server_opaque_prf_input != NULL && - s->version != DTLS1_VERSION) + if (s->s3->server_opaque_prf_input != NULL) { size_t sol = s->s3->server_opaque_prf_input_len; @@ -1669,6 +1743,47 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *p, unsigned cha } } + /* If custom types were sent in ClientHello, add ServerHello responses */ + if (s->s3->tlsext_custom_types_count) + { + size_t i; + + for (i = 0; i < s->s3->tlsext_custom_types_count; i++) + { + size_t j; + custom_srv_ext_record *record; + + for (j = 0; j < s->ctx->custom_srv_ext_records_count; j++) + { + record = &s->ctx->custom_srv_ext_records[j]; + if (s->s3->tlsext_custom_types[i] == record->ext_type) + { + const unsigned char *out = NULL; + unsigned short outlen = 0; + int cb_retval = 0; + + /* NULL callback or -1 omits extension */ + if (!record->fn2) + break; + cb_retval = record->fn2(s, record->ext_type, + &out, &outlen, + record->arg); + if (cb_retval == 0) + return NULL; /* error */ + if (cb_retval == -1) + break; /* skip this extension */ + if (limit < ret + 4 + outlen) + return NULL; + s2n(record->ext_type, ret); + s2n(outlen, ret); + memcpy(ret, out, outlen); + ret += outlen; + break; + } + } + } + } + if ((extdatalen = ret-p-2)== 0) return p; @@ -1867,8 +1982,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char #endif #ifndef OPENSSL_NO_EC - else if (type == TLSEXT_TYPE_ec_point_formats && - s->version != DTLS1_VERSION) + else if (type == TLSEXT_TYPE_ec_point_formats) { unsigned char *sdata = data; int ecpointformatlist_length = *(sdata++); @@ -1903,8 +2017,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char fprintf(stderr,"\n"); #endif } - else if (type == TLSEXT_TYPE_elliptic_curves && - s->version != DTLS1_VERSION) + else if (type == TLSEXT_TYPE_elliptic_curves) { unsigned char *sdata = data; int ellipticcurvelist_length = (*(sdata++) << 8); @@ -1942,8 +2055,7 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char } #endif /* OPENSSL_NO_EC */ #ifdef TLSEXT_TYPE_opaque_prf_input - else if (type == TLSEXT_TYPE_opaque_prf_input && - s->version != DTLS1_VERSION) + else if (type == TLSEXT_TYPE_opaque_prf_input) { unsigned char *sdata = data; @@ -2018,8 +2130,8 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char return 0; } } - else if (type == TLSEXT_TYPE_status_request && - s->version != DTLS1_VERSION && s->ctx->tlsext_status_cb) + else if (type == TLSEXT_TYPE_status_request + && s->ctx->tlsext_status_cb) { if (size < 5) @@ -2237,6 +2349,54 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char } } + /* If this ClientHello extension was unhandled and this is + * a nonresumed connection, check whether the extension is a + * custom TLS Extension (has a custom_srv_ext_record), and if + * so call the callback and record the extension number so that + * an appropriate ServerHello may be later returned. + */ + else if (!s->hit && s->ctx->custom_srv_ext_records_count) + { + custom_srv_ext_record *record; + + for (i=0; i < s->ctx->custom_srv_ext_records_count; i++) + { + record = &s->ctx->custom_srv_ext_records[i]; + if (type == record->ext_type) + { + /* Error on duplicate TLS Extensions */ + size_t j; + + for (j = 0; j < s->s3->tlsext_custom_types_count; j++) + { + if (s->s3->tlsext_custom_types[j] == type) + { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + } + + /* Callback */ + if (record->fn1 && !record->fn1(s, type, data, size, al, record->arg)) + return 0; + + /* Add the (non-duplicated) entry */ + s->s3->tlsext_custom_types_count++; + s->s3->tlsext_custom_types = OPENSSL_realloc( + s->s3->tlsext_custom_types, + s->s3->tlsext_custom_types_count*2); + if (s->s3->tlsext_custom_types == NULL) + { + s->s3->tlsext_custom_types = 0; + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->s3->tlsext_custom_types[ + s->s3->tlsext_custom_types_count-1] = type; + } + } + } + data+=size; } @@ -2349,8 +2509,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char } #ifndef OPENSSL_NO_EC - else if (type == TLSEXT_TYPE_ec_point_formats && - s->version != DTLS1_VERSION) + else if (type == TLSEXT_TYPE_ec_point_formats) { unsigned char *sdata = data; int ecpointformatlist_length = *(sdata++); @@ -2396,8 +2555,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char s->tlsext_ticket_expected = 1; } #ifdef TLSEXT_TYPE_opaque_prf_input - else if (type == TLSEXT_TYPE_opaque_prf_input && - s->version != DTLS1_VERSION) + else if (type == TLSEXT_TYPE_opaque_prf_input) { unsigned char *sdata = data; @@ -2427,8 +2585,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char } } #endif - else if (type == TLSEXT_TYPE_status_request && - s->version != DTLS1_VERSION) + else if (type == TLSEXT_TYPE_status_request) { /* MUST be empty and only sent if we've requested * a status request message. @@ -2449,7 +2606,7 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char unsigned char selected_len; /* We must have requested it. */ - if ((s->ctx->next_proto_select_cb == NULL)) + if (s->ctx->next_proto_select_cb == NULL) { *al = TLS1_AD_UNSUPPORTED_EXTENSION; return 0; @@ -2544,6 +2701,26 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char s->s3->tlsext_authz_server_promised = 1; } + + /* If this extension type was not otherwise handled, but + * matches a custom_cli_ext_record, then send it to the c + * callback */ + else if (s->ctx->custom_cli_ext_records_count) + { + size_t i; + custom_cli_ext_record* record; + + for (i = 0; i < s->ctx->custom_cli_ext_records_count; i++) + { + record = &s->ctx->custom_cli_ext_records[i]; + if (record->ext_type == type) + { + if (record->fn2 && !record->fn2(s, type, data, size, al, record->arg)) + return 0; + break; + } + } + } data += size; } @@ -2989,7 +3166,7 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, if (p >= limit) return -1; /* Skip past DTLS cookie */ - if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) + if (SSL_IS_DTLS(s)) { i = *(p++); p+= i; @@ -3125,7 +3302,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, HMAC_Update(&hctx, etick, eticklen); HMAC_Final(&hctx, tick_hmac, NULL); HMAC_CTX_cleanup(&hctx); - if (memcmp(tick_hmac, etick + eticklen, mlen)) + if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) return 2; /* Attempt to decrypt session data */ /* Move p after IV to start of encrypted ticket, update length */ @@ -3416,8 +3593,8 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) const EVP_MD *md; CERT *c = s->cert; TLS_SIGALGS *sigptr; - /* Extension ignored for TLS versions below 1.2 */ - if (TLS1_get_version(s) < TLS1_2_VERSION) + /* Extension ignored for inappropriate versions */ + if (!SSL_USE_SIGALGS(s)) return 1; /* Should never happen */ if (!c)