X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;ds=sidebyside;f=ssl%2Fs3_srvr.c;h=389f708b3ede168cd52322827790d67a575d735b;hb=a4c4a7d5cafaf7e0933d024d189f72b2e350b628;hp=ebf432421f3b0d1500832a7f88a4c49ead945d5f;hpb=b2284ed34af2ceeffb450d1e5180c9377c49a6f0;p=oweals%2Fopenssl.git diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index ebf432421f..389f708b3e 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -152,7 +152,6 @@ #define NETSCAPE_HANG_BUG #include -#include #include "ssl_locl.h" #include "kssl_lcl.h" #include @@ -181,7 +180,7 @@ static const SSL_METHOD *ssl3_get_server_method(int ver) } #ifndef OPENSSL_NO_SRP -static int ssl_check_srp_ext_ClientHello(SSL *s,int *al) +static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) { int ret = SSL_ERROR_NONE; @@ -403,9 +402,30 @@ int ssl3_accept(SSL *s) s->state=SSL3_ST_SW_CHANGE_A; #endif else - s->state=SSL3_ST_SW_CERT_A; - s->init_num=0; +#ifndef OPENSSL_NO_TLSEXT + s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_A; +#else + s->state = SSL3_ST_SW_CERT_A; +#endif + s->init_num = 0; + break; + +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_SW_SUPPLEMENTAL_DATA_A: + case SSL3_ST_SW_SUPPLEMENTAL_DATA_B: + /* We promised to send an audit proof in the hello. */ + if (s->s3->tlsext_authz_promised_to_client) + { + ret = tls1_send_server_supplemental_data(s); + if (ret <= 0) goto end; + } + else + skip = 1; + + s->state = SSL3_ST_SW_CERT_A; + s->init_num = 0; break; +#endif case SSL3_ST_SW_CERT_A: case SSL3_ST_SW_CERT_B: @@ -916,13 +936,14 @@ int ssl3_check_client_hello(SSL *s) int ssl3_get_client_hello(SSL *s) { - int i,j,ok,al,ret= -1; + int i,j,ok,al=SSL_AD_INTERNAL_ERROR,ret= -1; unsigned int cookie_len; long n; unsigned long id; - unsigned char *p,*d,*q; + unsigned char *p,*d; SSL_CIPHER *c; #ifndef OPENSSL_NO_COMP + unsigned char *q; SSL_COMP *comp=NULL; #endif STACK_OF(SSL_CIPHER) *ciphers=NULL; @@ -1158,7 +1179,9 @@ int ssl3_get_client_hello(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_LENGTH_MISMATCH); goto f_err; } +#ifndef OPENSSL_NO_COMP q=p; +#endif for (j=0; joptions & SSL_OP_NO_COMPRESSION) { - al=SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION); goto f_err; } @@ -1267,7 +1288,6 @@ int ssl3_get_client_hello(SSL *s) } if (s->s3->tmp.new_compression == NULL) { - al=SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INVALID_COMPRESSION_ALGORITHM); goto f_err; } @@ -1316,7 +1336,6 @@ int ssl3_get_client_hello(SSL *s) */ if (s->session->compress_meth != 0) { - al=SSL_AD_INTERNAL_ERROR; SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_INCONSISTENT_COMPRESSION); goto f_err; } @@ -1342,6 +1361,14 @@ int ssl3_get_client_hello(SSL *s) goto f_err; } ciphers=NULL; + /* Let cert callback update server certificates if required */ + if (s->cert->cert_cb + && s->cert->cert_cb(s, s->cert->cert_cb_arg) <= 0) + { + al=SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_CERT_CB_ERROR); + goto f_err; + } c=ssl3_choose_cipher(s,s->session->ciphers, SSL_get_ciphers(s)); @@ -1408,6 +1435,16 @@ int ssl3_get_client_hello(SSL *s) * s->tmp.new_cipher - the new cipher to use. */ + /* Handles TLS extensions that we couldn't check earlier */ + if (s->version >= SSL3_VERSION) + { + if (ssl_check_clienthello_tlsext_late(s) <= 0) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + } + if (ret < 0) ret=1; if (0) { @@ -1680,8 +1717,8 @@ int ssl3_send_server_key_exchange(SSL *s) ecdhp=cert->ecdh_tmp; if (s->cert->ecdh_tmp_auto) { - /* Get NID of first shared curve */ - int nid = tls1_shared_curve(s, 0); + /* Get NID of appropriate shared curve */ + int nid = tls1_shared_curve(s, -2); if (nid != NID_undef) ecdhp = EC_KEY_new_by_curve_name(nid); } @@ -2050,9 +2087,11 @@ int ssl3_send_certificate_request(SSL *s) if (TLS1_get_version(s) >= TLS1_2_VERSION) { - nl = tls12_get_req_sig_algs(s, p + 2); + const unsigned char *psigs; + nl = tls12_get_psigalgs(s, &psigs); s2n(nl, p); - p += nl + 2; + memcpy(p, psigs, nl); + p += nl; n += nl + 2; } @@ -2980,7 +3019,7 @@ int ssl3_get_cert_verify(SSL *s) if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY) { s->s3->tmp.reuse_message=1; - if ((peer != NULL) && (type | EVP_PKT_SIGN)) + if ((peer != NULL) && (type & EVP_PKT_SIGN)) { al=SSL_AD_UNEXPECTED_MESSAGE; SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE); @@ -3025,26 +3064,15 @@ int ssl3_get_cert_verify(SSL *s) { if (TLS1_get_version(s) >= TLS1_2_VERSION) { - int sigalg = tls12_get_sigid(pkey); - /* Should never happen */ - if (sigalg == -1) + int rv = tls12_check_peer_sigalg(&md, s, p, pkey); + if (rv == -1) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,ERR_R_INTERNAL_ERROR); - al=SSL_AD_INTERNAL_ERROR; + al = SSL_AD_INTERNAL_ERROR; goto f_err; } - /* Check key type is consistent with signature */ - if (sigalg != (int)p[1]) + else if (rv == 0) { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_WRONG_SIGNATURE_TYPE); - al=SSL_AD_DECODE_ERROR; - goto f_err; - } - md = tls12_get_hash(p[0]); - if (md == NULL) - { - SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_UNKNOWN_DIGEST); - al=SSL_AD_DECODE_ERROR; + al = SSL_AD_DECODE_ERROR; goto f_err; } #ifdef SSL_DEBUG @@ -3323,7 +3351,7 @@ int ssl3_get_client_certificate(SSL *s) if (i <= 0) { al=ssl_verify_alarm_type(s->verify_result); - SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_NO_CERTIFICATE_RETURNED); + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED); goto f_err; } } @@ -3566,7 +3594,7 @@ int ssl3_send_cert_status(SSL *s) return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } -# ifndef OPENSSL_NO_NPN +# ifndef OPENSSL_NO_NEXTPROTONEG /* ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. It * sets the next_proto member in s if found */ int ssl3_get_next_proto(SSL *s) @@ -3633,4 +3661,99 @@ int ssl3_get_next_proto(SSL *s) return 1; } # endif + +int tls1_send_server_supplemental_data(SSL *s) + { + size_t length = 0; + const unsigned char *authz, *orig_authz; + unsigned char *p; + size_t authz_length, i; + + if (s->state != SSL3_ST_SW_SUPPLEMENTAL_DATA_A) + return ssl3_do_write(s, SSL3_RT_HANDSHAKE); + + orig_authz = authz = ssl_get_authz_data(s, &authz_length); + if (authz == NULL) + { + /* This should never occur. */ + return 0; + } + + /* First we walk over the authz data to see how long the handshake + * message will be. */ + for (i = 0; i < authz_length; i++) + { + unsigned short len; + unsigned char type; + + type = *(authz++); + n2s(authz, len); + /* n2s increments authz by 2*/ + i += 2; + + if (memchr(s->s3->tlsext_authz_client_types, + type, + s->s3->tlsext_authz_client_types_len) != NULL) + length += 1 /* authz type */ + 2 /* length */ + len; + + authz += len; + i += len; + } + + length += 1 /* handshake type */ + + 3 /* handshake length */ + + 3 /* supplemental data length */ + + 2 /* supplemental entry type */ + + 2 /* supplemental entry length */; + + if (!BUF_MEM_grow_clean(s->init_buf, length)) + { + SSLerr(SSL_F_TLS1_SEND_SERVER_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB); + return 0; + } + + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL3_MT_SUPPLEMENTAL_DATA; + /* Handshake length */ + l2n3(length - 4, p); + /* Length of supplemental data */ + l2n3(length - 7, p); + /* Supplemental data type */ + s2n(TLSEXT_SUPPLEMENTALDATATYPE_authz_data, p); + /* Its length */ + s2n(length - 11, p); + + authz = orig_authz; + + /* Walk over the authz again and append the selected elements. */ + for (i = 0; i < authz_length; i++) + { + unsigned short len; + unsigned char type; + + type = *(authz++); + n2s(authz, len); + /* n2s increments authz by 2 */ + i += 2; + + if (memchr(s->s3->tlsext_authz_client_types, + type, + s->s3->tlsext_authz_client_types_len) != NULL) + { + *(p++) = type; + s2n(len, p); + memcpy(p, authz, len); + p += len; + } + + authz += len; + i += len; + } + + s->state = SSL3_ST_SW_SUPPLEMENTAL_DATA_B; + s->init_num = length; + s->init_off = 0; + + return ssl3_do_write(s, SSL3_RT_HANDSHAKE); + } #endif