X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=ssl%2Fs3_srvr.c;h=cd10334b90cd3ba3666706696ec2556233fc9111;hb=1385ddbb14286dba10e0cca41546986ffc8ea645;hp=ca39d6b1c8e97374f0749ef8a58fb870095e05a0;hpb=14f3d7c5ccd38875d5f3ee2007baec5a7240adc0;p=openssl.git diff --git a/ssl/s3_srvr.c b/ssl/s3_srvr.c index ca39d6b1c8..cd10334b90 100644 --- a/ssl/s3_srvr.c +++ b/ssl/s3_srvr.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -133,21 +133,16 @@ #include #include #include +#ifndef OPENSSL_NO_DH +#include +#endif +#include +#ifndef OPENSSL_NO_KRB5 #include +#endif #include -#include "cryptlib.h" static SSL_METHOD *ssl3_get_server_method(int ver); -static int ssl3_get_client_hello(SSL *s); -static int ssl3_check_client_hello(SSL *s); -static int ssl3_send_server_hello(SSL *s); -static int ssl3_send_server_key_exchange(SSL *s); -static int ssl3_send_certificate_request(SSL *s); -static int ssl3_send_server_done(SSL *s); -static int ssl3_get_client_key_exchange(SSL *s); -static int ssl3_get_client_certificate(SSL *s); -static int ssl3_get_cert_verify(SSL *s); -static int ssl3_send_hello_request(SSL *s); #ifndef OPENSSL_NO_ECDH static int nid2curve_id(int nid); @@ -626,7 +621,7 @@ end: return(ret); } -static int ssl3_send_hello_request(SSL *s) +int ssl3_send_hello_request(SSL *s) { unsigned char *p; @@ -648,14 +643,14 @@ static int ssl3_send_hello_request(SSL *s) return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } -static int ssl3_check_client_hello(SSL *s) +int ssl3_check_client_hello(SSL *s) { int ok; long n; /* this function is called when we really expect a Certificate message, * so permit appropriate message length */ - n=ssl3_get_message(s, + n=s->method->ssl_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, -1, @@ -681,9 +676,10 @@ static int ssl3_check_client_hello(SSL *s) return 1; } -static int ssl3_get_client_hello(SSL *s) +int ssl3_get_client_hello(SSL *s) { int i,j,ok,al,ret= -1; + unsigned int cookie_len; long n; unsigned long id; unsigned char *p,*d,*q; @@ -702,7 +698,7 @@ static int ssl3_get_client_hello(SSL *s) s->first_packet=1; s->state=SSL3_ST_SR_CLNT_HELLO_B; } - n=ssl3_get_message(s, + n=s->method->ssl_get_message(s, SSL3_ST_SR_CLNT_HELLO_B, SSL3_ST_SR_CLNT_HELLO_C, SSL3_MT_CLIENT_HELLO, @@ -767,6 +763,68 @@ static int ssl3_get_client_hello(SSL *s) } p+=j; + + if (SSL_version(s) == DTLS1_VERSION) + { + /* cookie stuff */ + cookie_len = *(p++); + + if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && + s->d1->send_cookie == 0) + { + /* HelloVerifyMessage has already been sent */ + if ( cookie_len != s->d1->cookie_len) + { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); + goto f_err; + } + } + + /* + * The ClientHello may contain a cookie even if the + * HelloVerify message has not been sent--make sure that it + * does not cause an overflow. + */ + if ( cookie_len > sizeof(s->d1->rcvd_cookie)) + { + /* too much data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); + goto f_err; + } + + /* verify the cookie if appropriate option is set. */ + if ( (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && + cookie_len > 0) + { + memcpy(s->d1->rcvd_cookie, p, cookie_len); + + if ( s->ctx->app_verify_cookie_cb != NULL) + { + if ( s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie, + cookie_len) == 0) + { + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_COOKIE_MISMATCH); + goto f_err; + } + /* else cookie verification succeeded */ + } + else if ( memcmp(s->d1->rcvd_cookie, s->d1->cookie, + s->d1->cookie_len) != 0) /* default verification */ + { + al=SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_COOKIE_MISMATCH); + goto f_err; + } + } + + p += cookie_len; + } + n2s(p,i); if ((i == 0) && (j != 0)) { @@ -816,8 +874,7 @@ static int ssl3_get_client_hello(SSL *s) if ((s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) && (sk_SSL_CIPHER_num(ciphers) == 1)) { /* Very bad for multi-threading.... */ - s->session->cipher=sk_SSL_CIPHER_value(ciphers, - 0); + s->session->cipher=sk_SSL_CIPHER_value(ciphers, 0); } else { @@ -980,7 +1037,7 @@ err: return(ret); } -static int ssl3_send_server_hello(SSL *s) +int ssl3_send_server_hello(SSL *s) { unsigned char *buf; unsigned char *p,*d; @@ -993,7 +1050,8 @@ static int ssl3_send_server_hello(SSL *s) p=s->s3->server_random; Time=time(NULL); /* Time */ l2n(Time,p); - RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-sizeof(Time)); + if (RAND_pseudo_bytes(p,SSL3_RANDOM_SIZE-4) <= 0) + return -1; /* Do the message type and length last */ d=p= &(buf[4]); @@ -1016,7 +1074,7 @@ static int ssl3_send_server_hello(SSL *s) s->session->session_id_length=0; sl=s->session->session_id_length; - if (sl > sizeof s->session->session_id) + if (sl > (int)sizeof(s->session->session_id)) { SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); return -1; @@ -1051,7 +1109,7 @@ static int ssl3_send_server_hello(SSL *s) return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } -static int ssl3_send_server_done(SSL *s) +int ssl3_send_server_done(SSL *s) { unsigned char *p; @@ -1075,7 +1133,7 @@ static int ssl3_send_server_done(SSL *s) return(ssl3_do_write(s,SSL3_RT_HANDSHAKE)); } -static int ssl3_send_server_key_exchange(SSL *s) +int ssl3_send_server_key_exchange(SSL *s) { #ifndef OPENSSL_NO_RSA unsigned char *q; @@ -1205,6 +1263,8 @@ static int ssl3_send_server_key_exchange(SSL *s) #ifndef OPENSSL_NO_ECDH if (type & SSL_kECDHE) { + const EC_GROUP *group; + ecdhp=cert->ecdh_tmp; if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL)) { @@ -1234,14 +1294,14 @@ static int ssl3_send_server_key_exchange(SSL *s) } if (!EC_KEY_up_ref(ecdhp)) { - SSLerr(SSL_F_SSL3_CTRL,ERR_R_ECDH_LIB); + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); goto err; } ecdh = ecdhp; s->s3->tmp.ecdh=ecdh; - if ((ecdh->pub_key == NULL) || - (ecdh->priv_key == NULL) || + if ((EC_KEY_get0_public_key(ecdh) == NULL) || + (EC_KEY_get0_private_key(ecdh) == NULL) || (s->options & SSL_OP_SINGLE_ECDH_USE)) { if(!EC_KEY_generate_key(ecdh)) @@ -1251,16 +1311,16 @@ static int ssl3_send_server_key_exchange(SSL *s) } } - if ((ecdh->group == NULL) || - (ecdh->pub_key == NULL) || - (ecdh->priv_key == NULL)) + if (((group = EC_KEY_get0_group(ecdh)) == NULL) || + (EC_KEY_get0_public_key(ecdh) == NULL) || + (EC_KEY_get0_private_key(ecdh) == NULL)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_R_ECDH_LIB); goto err; } if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - (EC_GROUP_get_degree(ecdh->group) > 163)) + (EC_GROUP_get_degree(group) > 163)) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); goto err; @@ -1271,7 +1331,7 @@ static int ssl3_send_server_key_exchange(SSL *s) * supported named curves, curve_id is non-zero. */ if ((curve_id = - nid2curve_id(EC_GROUP_get_nid(ecdh->group))) + nid2curve_id(EC_GROUP_get_curve_name(group))) == 0) { SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); @@ -1282,8 +1342,8 @@ static int ssl3_send_server_key_exchange(SSL *s) * First check the size of encoding and * allocate memory accordingly. */ - encodedlen = EC_POINT_point2oct(ecdh->group, - ecdh->pub_key, + encodedlen = EC_POINT_point2oct(group, + EC_KEY_get0_public_key(ecdh), POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); @@ -1297,8 +1357,8 @@ static int ssl3_send_server_key_exchange(SSL *s) } - encodedlen = EC_POINT_point2oct(ecdh->group, - ecdh->pub_key, + encodedlen = EC_POINT_point2oct(group, + EC_KEY_get0_public_key(ecdh), POINT_CONVERSION_UNCOMPRESSED, encodedPoint, encodedlen, bn_ctx); @@ -1494,7 +1554,7 @@ err: return(-1); } -static int ssl3_send_certificate_request(SSL *s) +int ssl3_send_certificate_request(SSL *s) { unsigned char *p,*d; int i,j,nl,off,n; @@ -1574,6 +1634,7 @@ static int ssl3_send_certificate_request(SSL *s) s->init_num += 4; #endif + s->state = SSL3_ST_SW_CERT_REQ_B; } /* SSL3_ST_SW_CERT_REQ_B */ @@ -1583,19 +1644,23 @@ err: } +#ifndef OPENSSL_NO_ECDH static const int KDF1_SHA1_len = 20; -static void *KDF1_SHA1(void *in, size_t inlen, void *out, size_t outlen) +static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen) { #ifndef OPENSSL_NO_SHA - if (outlen != SHA_DIGEST_LENGTH) + if (*outlen < SHA_DIGEST_LENGTH) return NULL; + else + *outlen = SHA_DIGEST_LENGTH; return SHA1(in, inlen, out); #else return NULL; -#endif +#endif /* OPENSSL_NO_SHA */ } +#endif /* OPENSSL_NO_ECDH */ -static int ssl3_get_client_key_exchange(SSL *s) +int ssl3_get_client_key_exchange(SSL *s) { int i,al,ok; long n; @@ -1620,7 +1685,7 @@ static int ssl3_get_client_key_exchange(SSL *s) BN_CTX *bn_ctx = NULL; #endif - n=ssl3_get_message(s, + n=s->method->ssl_get_message(s, SSL3_ST_SR_KEY_EXCH_A, SSL3_ST_SR_KEY_EXCH_B, SSL3_MT_CLIENT_KEY_EXCHANGE, @@ -1726,7 +1791,8 @@ static int ssl3_get_client_key_exchange(SSL *s) i = SSL_MAX_MASTER_KEY_LENGTH; p[0] = s->client_version >> 8; p[1] = s->client_version & 0xff; - RAND_pseudo_bytes(p+2, i-2); /* should be RAND_bytes, but we cannot work around a failure */ + if (RAND_pseudo_bytes(p+2, i-2) <= 0) /* should be RAND_bytes, but we cannot work around a failure */ + goto err; } s->session->master_key_length= @@ -1823,11 +1889,27 @@ static int ssl3_get_client_key_exchange(SSL *s) n2s(p,i); enc_ticket.length = i; + + if (n < enc_ticket.length + 6) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + enc_ticket.data = (char *)p; p+=enc_ticket.length; n2s(p,i); authenticator.length = i; + + if (n < enc_ticket.length + authenticator.length + 6) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + authenticator.data = (char *)p; p+=authenticator.length; @@ -1846,8 +1928,8 @@ static int ssl3_get_client_key_exchange(SSL *s) goto err; } - if (n != enc_ticket.length + authenticator.length + - enc_pms.length + 6) + if (n != (long)(enc_ticket.length + authenticator.length + + enc_pms.length + 6)) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG); @@ -1863,7 +1945,7 @@ static int ssl3_get_client_key_exchange(SSL *s) if (kssl_err.text) printf("kssl_err text= %s\n", kssl_err.text); #endif /* KSSL_DEBUG */ - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); goto err; } @@ -1880,14 +1962,14 @@ static int ssl3_get_client_key_exchange(SSL *s) if (kssl_err.text) printf("kssl_err text= %s\n", kssl_err.text); #endif /* KSSL_DEBUG */ - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); goto err; } if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0) { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, krb5rc); + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc); goto err; } @@ -1964,6 +2046,9 @@ static int ssl3_get_client_key_exchange(SSL *s) { int ret = 1; int field_size = 0; + const EC_KEY *tkey; + const EC_GROUP *group; + const BIGNUM *priv_key; /* initialize structures for server's ECDH key pair */ if ((srvr_ecdh = EC_KEY_new()) == NULL) @@ -1977,23 +2062,29 @@ static int ssl3_get_client_key_exchange(SSL *s) if (l & SSL_kECDH) { /* use the certificate */ - srvr_ecdh->group = s->cert->key->privatekey-> \ - pkey.eckey->group; - srvr_ecdh->priv_key = s->cert->key->privatekey-> \ - pkey.eckey->priv_key; + tkey = s->cert->key->privatekey->pkey.ec; } else { /* use the ephermeral values we saved when * generating the ServerKeyExchange msg. */ - srvr_ecdh->group = s->s3->tmp.ecdh->group; - srvr_ecdh->priv_key = s->s3->tmp.ecdh->priv_key; + tkey = s->s3->tmp.ecdh; + } + + group = EC_KEY_get0_group(tkey); + priv_key = EC_KEY_get0_private_key(tkey); + + if (!EC_KEY_set_group(srvr_ecdh, group) || + !EC_KEY_set_private_key(srvr_ecdh, priv_key)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_EC_LIB); + goto err; } /* Let's get client's public key */ - if ((clnt_ecpoint = EC_POINT_new(srvr_ecdh->group)) - == NULL) + if ((clnt_ecpoint = EC_POINT_new(group)) == NULL) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); @@ -2032,7 +2123,7 @@ static int ssl3_get_client_key_exchange(SSL *s) } EC_POINT_copy(clnt_ecpoint, - clnt_pub_pkey->pkey.eckey->pub_key); + EC_KEY_get0_public_key(clnt_pub_pkey->pkey.ec)); ret = 2; /* Skip certificate verify processing */ } else @@ -2050,7 +2141,7 @@ static int ssl3_get_client_key_exchange(SSL *s) /* Get encoded point length */ i = *p; p += 1; - if (EC_POINT_oct2point(srvr_ecdh->group, + if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, @@ -2064,7 +2155,7 @@ static int ssl3_get_client_key_exchange(SSL *s) } /* Compute the shared pre-master secret */ - field_size = EC_GROUP_get_degree(srvr_ecdh->group); + field_size = EC_GROUP_get_degree(group); if (field_size <= 0) { SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, @@ -2089,11 +2180,7 @@ static int ssl3_get_client_key_exchange(SSL *s) EVP_PKEY_free(clnt_pub_pkey); EC_POINT_free(clnt_ecpoint); if (srvr_ecdh != NULL) - { - srvr_ecdh->priv_key = NULL; - srvr_ecdh->group = NULL; EC_KEY_free(srvr_ecdh); - } BN_CTX_free(bn_ctx); /* Compute the master secret */ @@ -2122,17 +2209,13 @@ err: EVP_PKEY_free(clnt_pub_pkey); EC_POINT_free(clnt_ecpoint); if (srvr_ecdh != NULL) - { - srvr_ecdh->priv_key = NULL; - srvr_ecdh->group = NULL; EC_KEY_free(srvr_ecdh); - } BN_CTX_free(bn_ctx); #endif return(-1); } -static int ssl3_get_cert_verify(SSL *s) +int ssl3_get_cert_verify(SSL *s) { EVP_PKEY *pkey=NULL; unsigned char *p; @@ -2141,7 +2224,7 @@ static int ssl3_get_cert_verify(SSL *s) int type=0,i,j; X509 *peer; - n=ssl3_get_message(s, + n=s->method->ssl_get_message(s, SSL3_ST_SR_CERT_VRFY_A, SSL3_ST_SR_CERT_VRFY_B, -1, @@ -2257,7 +2340,7 @@ static int ssl3_get_cert_verify(SSL *s) { j=ECDSA_verify(pkey->save_type, &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), - SHA_DIGEST_LENGTH,p,i,pkey->pkey.eckey); + SHA_DIGEST_LENGTH,p,i,pkey->pkey.ec); if (j <= 0) { /* bad signature */ @@ -2287,15 +2370,16 @@ end: return(ret); } -static int ssl3_get_client_certificate(SSL *s) +int ssl3_get_client_certificate(SSL *s) { int i,ok,al,ret= -1; X509 *x=NULL; unsigned long l,nc,llen,n; - unsigned char *p,*d,*q; + const unsigned char *p,*q; + unsigned char *d; STACK_OF(X509) *sk=NULL; - n=ssl3_get_message(s, + n=s->method->ssl_get_message(s, SSL3_ST_SR_CERT_A, SSL3_ST_SR_CERT_B, -1, @@ -2330,7 +2414,7 @@ static int ssl3_get_client_certificate(SSL *s) SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,SSL_R_WRONG_MESSAGE_TYPE); goto f_err; } - d=p=(unsigned char *)s->init_msg; + p=d=(unsigned char *)s->init_msg; if ((sk=sk_X509_new_null()) == NULL) {