X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_clnt.c;h=8feb24a1424500ff5cc5bf668e17061aae17087c;hp=aff0d9e61b079717715f0c5bcfc95d7329478fde;hb=60a938c6bca4c0890ed2d320e29fb43c970094d5;hpb=4579924b7e55fccc7013e6de196f2e2ab175ce39 diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index aff0d9e61b..8feb24a142 100644 --- a/ssl/s3_clnt.c +++ b/ssl/s3_clnt.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2003 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 @@ -130,7 +130,7 @@ #include #include #include -#include "cryptlib.h" +#include static SSL_METHOD *ssl3_get_client_method(int ver); static int ssl3_client_hello(SSL *s); @@ -183,7 +183,7 @@ SSL_METHOD *SSLv3_client_method(void) int ssl3_connect(SSL *s) { - BUF_MEM *buf; + BUF_MEM *buf=NULL; unsigned long Time=time(NULL),l; long num1; void (*cb)(const SSL *ssl,int type,int val)=NULL; @@ -244,6 +244,7 @@ int ssl3_connect(SSL *s) goto end; } s->init_buf=buf; + buf=NULL; } if (!ssl3_setup_buffers(s)) { ret= -1; goto end; } @@ -529,6 +530,8 @@ int ssl3_connect(SSL *s) } end: s->in_handshake--; + if (buf != NULL) + BUF_MEM_free(buf); if (cb != NULL) cb(s,SSL_CB_CONNECT_EXIT,ret); return(ret); @@ -579,7 +582,7 @@ static int ssl3_client_hello(SSL *s) *(p++)=i; if (i != 0) { - if (i > sizeof s->session->session_id) + if (i > (int)sizeof(s->session->session_id)) { SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); goto err; @@ -778,11 +781,12 @@ static int ssl3_get_server_certificate(SSL *s) int al,i,ok,ret= -1; unsigned long n,nc,llen,l; X509 *x=NULL; - unsigned char *p,*d,*q; + const unsigned char *q,*p; + unsigned char *d; STACK_OF(X509) *sk=NULL; SESS_CERT *sc; EVP_PKEY *pkey=NULL; - int need_cert = 1; /* VRS: 0=> will allow null cert if auth == KRB5 */ + int need_cert = 1; /* VRS: 0=> will allow null cert if auth == KRB5 */ n=ssl3_get_message(s, SSL3_ST_CR_CERT_A, @@ -805,7 +809,7 @@ static int ssl3_get_server_certificate(SSL *s) SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_BAD_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) { @@ -857,10 +861,10 @@ static int ssl3_get_server_certificate(SSL *s) i=ssl_verify_cert_chain(s,sk); if ((s->verify_mode != SSL_VERIFY_NONE) && (!i) #ifndef OPENSSL_NO_KRB5 - && (s->s3->tmp.new_cipher->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK)) - != (SSL_aKRB5|SSL_kKRB5) + && (s->s3->tmp.new_cipher->algorithms & (SSL_MKEY_MASK|SSL_AUTH_MASK)) + != (SSL_aKRB5|SSL_kKRB5) #endif /* OPENSSL_NO_KRB5 */ - ) + ) { al=ssl_verify_alarm_type(s->verify_result); SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,SSL_R_CERTIFICATE_VERIFY_FAILED); @@ -883,16 +887,16 @@ static int ssl3_get_server_certificate(SSL *s) pkey=X509_get_pubkey(x); - /* VRS: allow null cert if auth == KRB5 */ - need_cert = ((s->s3->tmp.new_cipher->algorithms - & (SSL_MKEY_MASK|SSL_AUTH_MASK)) - == (SSL_aKRB5|SSL_kKRB5))? 0: 1; + /* VRS: allow null cert if auth == KRB5 */ + need_cert = ((s->s3->tmp.new_cipher->algorithms + & (SSL_MKEY_MASK|SSL_AUTH_MASK)) + == (SSL_aKRB5|SSL_kKRB5))? 0: 1; #ifdef KSSL_DEBUG printf("pkey,x = %p, %p\n", pkey,x); printf("ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x,pkey)); printf("cipher, alg, nc = %s, %lx, %d\n", s->s3->tmp.new_cipher->name, - s->s3->tmp.new_cipher->algorithms, need_cert); + s->s3->tmp.new_cipher->algorithms, need_cert); #endif /* KSSL_DEBUG */ if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))) @@ -914,31 +918,31 @@ static int ssl3_get_server_certificate(SSL *s) goto f_err; } - if (need_cert) - { - sc->peer_cert_type=i; - CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509); - /* Why would the following ever happen? - * We just created sc a couple of lines ago. */ - if (sc->peer_pkeys[i].x509 != NULL) - X509_free(sc->peer_pkeys[i].x509); - sc->peer_pkeys[i].x509=x; - sc->peer_key= &(sc->peer_pkeys[i]); - - if (s->session->peer != NULL) - X509_free(s->session->peer); - CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509); - s->session->peer=x; - } - else - { - sc->peer_cert_type=i; - sc->peer_key= NULL; - - if (s->session->peer != NULL) - X509_free(s->session->peer); - s->session->peer=NULL; - } + if (need_cert) + { + sc->peer_cert_type=i; + CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509); + /* Why would the following ever happen? + * We just created sc a couple of lines ago. */ + if (sc->peer_pkeys[i].x509 != NULL) + X509_free(sc->peer_pkeys[i].x509); + sc->peer_pkeys[i].x509=x; + sc->peer_key= &(sc->peer_pkeys[i]); + + if (s->session->peer != NULL) + X509_free(s->session->peer); + CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509); + s->session->peer=x; + } + else + { + sc->peer_cert_type=i; + sc->peer_key= NULL; + + if (s->session->peer != NULL) + X509_free(s->session->peer); + s->session->peer=NULL; + } s->session->verify_result = s->verify_result; x=NULL; @@ -1406,7 +1410,8 @@ static int ssl3_get_certificate_request(SSL *s) unsigned long n,nc,l; unsigned int llen,ctype_num,i; X509_NAME *xn=NULL; - unsigned char *p,*d,*q; + const unsigned char *p,*q; + unsigned char *d; STACK_OF(X509_NAME) *ca_sk=NULL; n=ssl3_get_message(s, @@ -1445,7 +1450,7 @@ static int ssl3_get_certificate_request(SSL *s) } } - d=p=(unsigned char *)s->init_msg; + p=d=(unsigned char *)s->init_msg; if ((ca_sk=sk_X509_NAME_new(ca_dn_cmp)) == NULL) { @@ -1571,6 +1576,19 @@ static int ssl3_get_server_done(SSL *s) return(ret); } + +static const int KDF1_SHA1_len = 20; +static void *KDF1_SHA1(void *in, size_t inlen, void *out, size_t outlen) + { +#ifndef OPENSSL_NO_SHA + if (outlen != SHA_DIGEST_LENGTH) + return NULL; + return SHA1(in, inlen, out); +#else + return NULL; +#endif + } + static int ssl3_send_client_key_exchange(SSL *s) { unsigned char *p,*d; @@ -1581,7 +1599,7 @@ static int ssl3_send_client_key_exchange(SSL *s) EVP_PKEY *pkey=NULL; #endif #ifndef OPENSSL_NO_KRB5 - KSSL_ERR kssl_err; + KSSL_ERR kssl_err; #endif /* OPENSSL_NO_KRB5 */ #ifndef OPENSSL_NO_ECDH EC_KEY *clnt_ecdh = NULL; @@ -1599,8 +1617,8 @@ static int ssl3_send_client_key_exchange(SSL *s) l=s->s3->tmp.new_cipher->algorithms; - /* Fool emacs indentation */ - if (0) {} + /* Fool emacs indentation */ + if (0) {} #ifndef OPENSSL_NO_RSA else if (l & SSL_kRSA) { @@ -1662,12 +1680,12 @@ static int ssl3_send_client_key_exchange(SSL *s) #endif #ifndef OPENSSL_NO_KRB5 else if (l & SSL_kKRB5) - { - krb5_error_code krb5rc; - KSSL_CTX *kssl_ctx = s->kssl_ctx; - /* krb5_data krb5_ap_req; */ - krb5_data *enc_ticket; - krb5_data authenticator, *authp = NULL; + { + krb5_error_code krb5rc; + KSSL_CTX *kssl_ctx = s->kssl_ctx; + /* krb5_data krb5_ap_req; */ + krb5_data *enc_ticket; + krb5_data authenticator, *authp = NULL; EVP_CIPHER_CTX ciph_ctx; EVP_CIPHER *enc = NULL; unsigned char iv[EVP_MAX_IV_LENGTH]; @@ -1679,8 +1697,8 @@ static int ssl3_send_client_key_exchange(SSL *s) EVP_CIPHER_CTX_init(&ciph_ctx); #ifdef KSSL_DEBUG - printf("ssl3_send_client_key_exchange(%lx & %lx)\n", - l, SSL_kKRB5); + printf("ssl3_send_client_key_exchange(%lx & %lx)\n", + l, SSL_kKRB5); #endif /* KSSL_DEBUG */ authp = NULL; @@ -1688,37 +1706,37 @@ static int ssl3_send_client_key_exchange(SSL *s) if (KRB5SENDAUTH) authp = &authenticator; #endif /* KRB5SENDAUTH */ - krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp, + krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp, &kssl_err); enc = kssl_map_enc(kssl_ctx->enctype); - if (enc == NULL) - goto err; + if (enc == NULL) + goto err; #ifdef KSSL_DEBUG - { - printf("kssl_cget_tkt rtn %d\n", krb5rc); - if (krb5rc && kssl_err.text) + { + printf("kssl_cget_tkt rtn %d\n", krb5rc); + if (krb5rc && kssl_err.text) printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text); - } + } #endif /* KSSL_DEBUG */ - if (krb5rc) - { - ssl3_send_alert(s,SSL3_AL_FATAL, + if (krb5rc) + { + ssl3_send_alert(s,SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, kssl_err.reason); - goto err; - } + goto err; + } /* 20010406 VRS - Earlier versions used KRB5 AP_REQ ** in place of RFC 2712 KerberosWrapper, as in: ** - ** Send ticket (copy to *p, set n = length) - ** n = krb5_ap_req.length; - ** memcpy(p, krb5_ap_req.data, krb5_ap_req.length); - ** if (krb5_ap_req.data) - ** kssl_krb5_free_data_contents(NULL,&krb5_ap_req); - ** + ** Send ticket (copy to *p, set n = length) + ** n = krb5_ap_req.length; + ** memcpy(p, krb5_ap_req.data, krb5_ap_req.length); + ** if (krb5_ap_req.data) + ** kssl_krb5_free_data_contents(NULL,&krb5_ap_req); + ** ** Now using real RFC 2712 KerberosWrapper ** (Thanks to Simon Wilkinson ) ** Note: 2712 "opaque" types are here replaced @@ -1783,14 +1801,14 @@ static int ssl3_send_client_key_exchange(SSL *s) p+=outl; n+=outl + 2; - s->session->master_key_length= - s->method->ssl3_enc->generate_master_secret(s, + s->session->master_key_length= + s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, tmp_buf, sizeof tmp_buf); OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); OPENSSL_cleanse(epms, outl); - } + } #endif #ifndef OPENSSL_NO_DH else if (l & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) @@ -1854,6 +1872,7 @@ static int ssl3_send_client_key_exchange(SSL *s) { EC_GROUP *srvr_group = NULL; int ecdh_clnt_cert = 0; + int field_size = 0; /* Did we send out the client's * ECDH share for use in premaster @@ -1925,7 +1944,7 @@ static int ssl3_send_client_key_exchange(SSL *s) clnt_ecdh->group = srvr_group; if (ecdh_clnt_cert) { - /* Reuse key info from our certificate + /* Reuse key info from our certificate * We only need our private key to perform * the ECDH computation. */ @@ -1942,25 +1961,39 @@ static int ssl3_send_client_key_exchange(SSL *s) } } - /* use the 'p' output buffer for the ECDH key, but - * make sure to clear it out afterwards + /* use the 'p' output buffer for the ECDH key, but + * make sure to clear it out afterwards */ - n=ECDH_compute_key(p, srvr_ecpoint, clnt_ecdh); + field_size = EC_GROUP_get_degree(clnt_ecdh->group); + if (field_size <= 0) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + /* If field size is not more than 24 octets, then use SHA-1 hash of result; + * otherwise, use result (see section 4.8 of draft-ietf-tls-ecc-03.txt; + * this is new with this version of the Internet Draft). + */ + if (field_size <= 24 * 8) + n=ECDH_compute_key(p, KDF1_SHA1_len, srvr_ecpoint, clnt_ecdh, KDF1_SHA1); + else + n=ECDH_compute_key(p, (field_size+7)/8, srvr_ecpoint, clnt_ecdh, NULL); if (n <= 0) - { - SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); - goto err; + goto err; } - /* generate master key from the result */ - s->session->master_key_length = s->method->ssl3_enc \ + /* generate master key from the result */ + s->session->master_key_length = s->method->ssl3_enc \ -> generate_master_secret(s, s->session->master_key, p, n); - memset(p, 0, n); /* clean up */ + memset(p, 0, n); /* clean up */ if (ecdh_clnt_cert) { @@ -1996,7 +2029,7 @@ static int ssl3_send_client_key_exchange(SSL *s) encodedPoint, encoded_pt_len, bn_ctx); *p = n; /* length of encoded point */ - /* Encoded point will be copied here */ + /* Encoded point will be copied here */ p += 1; /* copy the point */ memcpy((unsigned char *)p, encodedPoint, n); @@ -2009,7 +2042,7 @@ static int ssl3_send_client_key_exchange(SSL *s) if (encodedPoint != NULL) OPENSSL_free(encodedPoint); if (clnt_ecdh != NULL) { - /* group is shared */ + /* group is shared */ clnt_ecdh->group = NULL; EC_KEY_free(clnt_ecdh); } @@ -2046,7 +2079,7 @@ err: clnt_ecdh->group = NULL; EC_KEY_free(clnt_ecdh); } - EVP_PKEY_free(srvr_pub_pkey); + EVP_PKEY_free(srvr_pub_pkey); #endif return(-1); } @@ -2130,6 +2163,7 @@ static int ssl3_send_client_verify(SSL *s) *(d++)=SSL3_MT_CERTIFICATE_VERIFY; l2n3(n,d); + s->state=SSL3_ST_CW_CERT_VRFY_B; s->init_num=(int)n+4; s->init_off=0; } @@ -2322,7 +2356,7 @@ static int ssl3_check_cert_and_algorithm(SSL *s) if (algs & SSL_kRSA) { if (rsa == NULL - || RSA_size(rsa) > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) + || RSA_size(rsa)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_RSA_KEY); goto f_err; @@ -2334,7 +2368,7 @@ static int ssl3_check_cert_and_algorithm(SSL *s) if (algs & (SSL_kEDH|SSL_kDHr|SSL_kDHd)) { if (dh == NULL - || DH_size(dh) > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) + || DH_size(dh)*8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM,SSL_R_MISSING_EXPORT_TMP_DH_KEY); goto f_err; @@ -2359,7 +2393,8 @@ err: /* This is the complement of nid2curve_id in s3_srvr.c. */ static int curve_id2nid(int curve_id) { - /* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) */ + /* ECC curves from draft-ietf-tls-ecc-01.txt (Mar 15, 2001) + * (no changes in draft-ietf-tls-ecc-03.txt [June 2003]) */ static int nid_list[26] = { 0,