X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Ft1_lib.c;h=f85a0b8c0821aad020c70dd5f0fed99609c1a776;hp=c747b3092f849742ac6c94c4f058105e961c7a56;hb=56e8dc542bd693b2dccea8828b3d8e5fc6932d0c;hpb=d64b6c980c8101e2d96c982c0b211ac3f94a3aaa diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index c747b3092f..f85a0b8c08 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -113,6 +113,9 @@ #include #include #include +#ifdef OPENSSL_NO_EC2M +#include +#endif #include #include #include "ssl_locl.h" @@ -260,31 +263,43 @@ static const unsigned char ecformats_default[] = static const unsigned char eccurves_default[] = { +#ifndef OPENSSL_NO_EC2M 0,14, /* sect571r1 (14) */ 0,13, /* sect571k1 (13) */ +#endif 0,25, /* secp521r1 (25) */ 0,28, /* brainpool512r1 (28) */ +#ifndef OPENSSL_NO_EC2M 0,11, /* sect409k1 (11) */ 0,12, /* sect409r1 (12) */ +#endif 0,27, /* brainpoolP384r1 (27) */ 0,24, /* secp384r1 (24) */ +#ifndef OPENSSL_NO_EC2M 0,9, /* sect283k1 (9) */ 0,10, /* sect283r1 (10) */ +#endif 0,26, /* brainpoolP256r1 (26) */ 0,22, /* secp256k1 (22) */ 0,23, /* secp256r1 (23) */ +#ifndef OPENSSL_NO_EC2M 0,8, /* sect239k1 (8) */ 0,6, /* sect233k1 (6) */ 0,7, /* sect233r1 (7) */ +#endif 0,20, /* secp224k1 (20) */ 0,21, /* secp224r1 (21) */ +#ifndef OPENSSL_NO_EC2M 0,4, /* sect193r1 (4) */ 0,5, /* sect193r2 (5) */ +#endif 0,18, /* secp192k1 (18) */ 0,19, /* secp192r1 (19) */ +#ifndef OPENSSL_NO_EC2M 0,1, /* sect163k1 (1) */ 0,2, /* sect163r1 (2) */ 0,3, /* sect163r2 (3) */ +#endif 0,15, /* secp160k1 (15) */ 0,16, /* secp160r1 (16) */ 0,17, /* secp160r2 (17) */ @@ -300,37 +315,49 @@ static const unsigned char suiteb_curves[] = /* Brainpool not allowed in FIPS mode */ static const unsigned char fips_curves_default[] = { - 0,14, /* sect571r1 (14) */ - 0,13, /* sect571k1 (13) */ - 0,25, /* secp521r1 (25) */ - 0,11, /* sect409k1 (11) */ +#ifndef OPENSSL_NO_EC2M + 0,14, /* sect571r1 (14) */ + 0,13, /* sect571k1 (13) */ +#endif + 0,25, /* secp521r1 (25) */ +#ifndef OPENSSL_NO_EC2M + 0,11, /* sect409k1 (11) */ 0,12, /* sect409r1 (12) */ +#endif 0,24, /* secp384r1 (24) */ +#ifndef OPENSSL_NO_EC2M 0,9, /* sect283k1 (9) */ - 0,10, /* sect283r1 (10) */ - 0,22, /* secp256k1 (22) */ - 0,23, /* secp256r1 (23) */ - 0,8, /* sect239k1 (8) */ + 0,10, /* sect283r1 (10) */ +#endif + 0,22, /* secp256k1 (22) */ + 0,23, /* secp256r1 (23) */ +#ifndef OPENSSL_NO_EC2M + 0,8, /* sect239k1 (8) */ 0,6, /* sect233k1 (6) */ - 0,7, /* sect233r1 (7) */ + 0,7, /* sect233r1 (7) */ +#endif 0,20, /* secp224k1 (20) */ 0,21, /* secp224r1 (21) */ - 0,4, /* sect193r1 (4) */ - 0,5, /* sect193r2 (5) */ +#ifndef OPENSSL_NO_EC2M + 0,4, /* sect193r1 (4) */ + 0,5, /* sect193r2 (5) */ +#endif 0,18, /* secp192k1 (18) */ - 0,19, /* secp192r1 (19) */ + 0,19, /* secp192r1 (19) */ +#ifndef OPENSSL_NO_EC2M 0,1, /* sect163k1 (1) */ 0,2, /* sect163r1 (2) */ 0,3, /* sect163r2 (3) */ +#endif 0,15, /* secp160k1 (15) */ - 0,16, /* secp160r1 (16) */ - 0,17, /* secp160r2 (17) */ + 0,16, /* secp160r1 (16) */ + 0,17, /* secp160r2 (17) */ }; #endif int tls1_ec_curve_id2nid(int curve_id) { - /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */ + /* ECC curves from RFC 4492 and RFC 7027 */ if ((curve_id < 1) || ((unsigned int)curve_id > sizeof(nid_list)/sizeof(nid_list[0]))) return 0; @@ -339,7 +366,7 @@ int tls1_ec_curve_id2nid(int curve_id) int tls1_ec_nid2curve_id(int nid) { - /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */ + /* ECC curves from RFC 4492 and RFC 7027 */ switch (nid) { case NID_sect163k1: /* sect163k1 (1) */ @@ -555,6 +582,10 @@ int tls1_set_curves(unsigned char **pext, size_t *pextlen, * while curve ids < 32 */ unsigned long dup_list = 0; +#ifdef OPENSSL_NO_EC2M + EC_GROUP *curve; +#endif + clist = OPENSSL_malloc(ncurves * 2); if (!clist) return 0; @@ -570,6 +601,19 @@ int tls1_set_curves(unsigned char **pext, size_t *pextlen, OPENSSL_free(clist); return 0; } +#endif +#ifdef OPENSSL_NO_EC2M + curve = EC_GROUP_new_by_curve_name(curves[i]); + if(!curve || + EC_METHOD_get_field_type(EC_GROUP_method_of(curve)) + == NID_X9_62_characteristic_two_field) + { + if(curve) EC_GROUP_free(curve); + OPENSSL_free(clist); + return 0; + } + else + EC_GROUP_free(curve); #endif idmask = 1L << id; if (!id || (dup_list & idmask)) @@ -1306,12 +1350,6 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, unsigned c s2n(TLSEXT_TYPE_elliptic_curves,ret); s2n(plistlen + 2, ret); - - /* NB: draft-ietf-tls-ecc-12.txt uses a one-byte prefix for - * elliptic_curve_list, but the examples use two bytes. - * http://www1.ietf.org/mail-archive/web/tls/current/msg00538.html - * resolves this to two bytes. - */ s2n(plistlen, ret); memcpy(ret, plist, plistlen); ret+=plistlen; @@ -1908,7 +1946,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char unsigned short len; unsigned char *data = *p; int renegotiate_seen = 0; - size_t i; s->servername_done = 0; s->tlsext_status_type = -1; @@ -1938,18 +1975,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char OPENSSL_free(s->cert->peer_sigalgs); s->cert->peer_sigalgs = NULL; } - /* Clear any shared sigtnature algorithms */ - if (s->cert->shared_sigalgs) - { - OPENSSL_free(s->cert->shared_sigalgs); - s->cert->shared_sigalgs = NULL; - } - /* Clear certificate digests and validity flags */ - for (i = 0; i < SSL_PKEY_NUM; i++) - { - s->cert->pkeys[i].digest = NULL; - s->cert->pkeys[i].valid_flags = 0; - } if (data >= (d+n-2)) goto ri_check; @@ -2236,21 +2261,11 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *al = SSL_AD_DECODE_ERROR; return 0; } - if (!tls1_process_sigalgs(s, data, dsize)) + if (!tls1_save_sigalgs(s, data, dsize)) { *al = SSL_AD_DECODE_ERROR; return 0; } - /* If sigalgs received and no shared algorithms fatal - * error. - */ - if (s->cert->peer_sigalgs && !s->cert->shared_sigalgs) - { - SSLerr(SSL_F_SSL_SCAN_CLIENTHELLO_TLSEXT, - SSL_R_NO_SHARED_SIGATURE_ALGORITHMS); - *al = SSL_AD_ILLEGAL_PARAMETER; - return 0; - } } else if (type == TLSEXT_TYPE_status_request) { @@ -2424,17 +2439,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char al)) return 0; } - /* 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) - { - if (custom_ext_parse(s, 1, type, data, size, al) <= 0) - return 0; - } data+=size; } @@ -2453,9 +2457,41 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); return 0; } - /* If no signature algorithms extension set default values */ - if (!s->cert->peer_sigalgs) - ssl_cert_set_default_md(s->cert); + + return 1; + } + +/* + * Parse any custom extensions found. "data" is the start of the extension data + * and "limit" is the end of the record. TODO: add strict syntax checking. + */ + +static int ssl_scan_clienthello_custom_tlsext(SSL *s, const unsigned char *data, const unsigned char *limit, int *al) + { + unsigned short type, size, len; + /* If resumed session or no custom extensions nothing to do */ + if (s->hit || s->cert->srv_ext.meths_count == 0) + return 1; + + if (data >= limit - 2) + return 1; + n2s(data, len); + + if (data > limit - len) + return 1; + + while (data <= limit - 4) + { + n2s(data, type); + n2s(data, size); + + if (data+size > limit) + return 1; + if (custom_ext_parse(s, 1 /* server */, type, data, size, al) <= 0) + return 0; + + data+=size; + } return 1; } @@ -2463,7 +2499,13 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n) { int al = -1; - custom_ext_init(&s->cert->srv_ext); + unsigned char *ptmp = *p; + /* + * Internally supported extensions are parsed first so SNI can be handled + * before custom extensions. An application processing SNI will typically + * switch the parent context using SSL_set_SSL_CTX and custom extensions + * need to be handled by the new SSL_CTX structure. + */ if (ssl_scan_clienthello_tlsext(s, p, d, n, &al) <= 0) { ssl3_send_alert(s,SSL3_AL_FATAL,al); @@ -2475,6 +2517,14 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT,SSL_R_CLIENTHELLO_TLSEXT); return 0; } + + custom_ext_init(&s->cert->srv_ext); + if (ssl_scan_clienthello_custom_tlsext(s, ptmp, d + n, &al) <= 0) + { + ssl3_send_alert(s,SSL3_AL_FATAL,al); + return 0; + } + return 1; } @@ -2958,6 +3008,50 @@ static int ssl_check_clienthello_tlsext_early(SSL *s) } } +int tls1_set_server_sigalgs(SSL *s) + { + int al; + size_t i; + /* Clear any shared sigtnature algorithms */ + if (s->cert->shared_sigalgs) + { + OPENSSL_free(s->cert->shared_sigalgs); + s->cert->shared_sigalgs = NULL; + } + /* Clear certificate digests and validity flags */ + for (i = 0; i < SSL_PKEY_NUM; i++) + { + s->cert->pkeys[i].digest = NULL; + s->cert->pkeys[i].valid_flags = 0; + } + + /* If sigalgs received process it. */ + if (s->cert->peer_sigalgs) + { + if (!tls1_process_sigalgs(s)) + { + SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, + ERR_R_MALLOC_FAILURE); + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + /* Fatal error is no shared signature algorithms */ + if (!s->cert->shared_sigalgs) + { + SSLerr(SSL_F_TLS1_SET_SERVER_SIGALGS, + SSL_R_NO_SHARED_SIGATURE_ALGORITHMS); + al = SSL_AD_ILLEGAL_PARAMETER; + goto err; + } + } + else + ssl_cert_set_default_md(s->cert); + return 1; + err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return 0; + } + int ssl_check_clienthello_tlsext_late(SSL *s) { int ret = SSL_TLSEXT_ERR_OK; @@ -3344,7 +3438,10 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, int eticklen, HMAC_Final(&hctx, tick_hmac, NULL); HMAC_CTX_cleanup(&hctx); if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) + { + EVP_CIPHER_CTX_cleanup(&ctx); return 2; + } /* Attempt to decrypt session data */ /* Move p after IV to start of encrypted ticket, update length */ p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); @@ -3636,13 +3733,9 @@ static int tls1_set_shared_sigalgs(SSL *s) /* Set preferred digest for each key type */ -int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) +int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize) { - int idx; - size_t i; - const EVP_MD *md; CERT *c = s->cert; - TLS_SIGALGS *sigptr; /* Extension ignored for inappropriate versions */ if (!SSL_USE_SIGALGS(s)) return 1; @@ -3657,8 +3750,18 @@ int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) return 0; c->peer_sigalgslen = dsize; memcpy(c->peer_sigalgs, data, dsize); + return 1; + } - tls1_set_shared_sigalgs(s); +int tls1_process_sigalgs(SSL *s) + { + int idx; + size_t i; + const EVP_MD *md; + CERT *c = s->cert; + TLS_SIGALGS *sigptr; + if (!tls1_set_shared_sigalgs(s)) + return 0; #ifdef OPENSSL_SSL_DEBUG_BROKEN_PROTOCOL if (s->cert->cert_flags & SSL_CERT_FLAG_BROKEN_PROTOCOL)