X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=ssl%2Fs3_clnt.c;h=d4f7cec712acbf2ae53639e757203d37234318c6;hb=e5cd536894a96fa6640c60a7690a9fb7f6459520;hp=477b6816453c4c1395776741036a0ec57b465add;hpb=8d6ad9e39d3e104427c133ac45ce05f30da9f9a3;p=oweals%2Fopenssl.git diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index 477b681645..d4f7cec712 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,20 +130,11 @@ #include #include #include -#include "cryptlib.h" +#include +#include static SSL_METHOD *ssl3_get_client_method(int ver); -static int ssl3_client_hello(SSL *s); -static int ssl3_get_server_hello(SSL *s); -static int ssl3_get_certificate_request(SSL *s); static int ca_dn_cmp(const X509_NAME * const *a,const X509_NAME * const *b); -static int ssl3_get_server_done(SSL *s); -static int ssl3_send_client_verify(SSL *s); -static int ssl3_send_client_certificate(SSL *s); -static int ssl3_send_client_key_exchange(SSL *s); -static int ssl3_get_key_exchange(SSL *s); -static int ssl3_get_server_certificate(SSL *s); -static int ssl3_check_cert_and_algorithm(SSL *s); #ifndef OPENSSL_NO_ECDH static int curve_id2nid(int curve_id); @@ -538,7 +529,7 @@ end: } -static int ssl3_client_hello(SSL *s) +int ssl3_client_hello(SSL *s) { unsigned char *buf; unsigned char *p,*d; @@ -561,7 +552,8 @@ static int ssl3_client_hello(SSL *s) p=s->s3->client_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) + goto err; /* Do the message type and length last */ d=p= &(buf[4]); @@ -582,7 +574,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; @@ -592,7 +584,7 @@ static int ssl3_client_hello(SSL *s) } /* Ciphers supported */ - i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2])); + i=ssl_cipher_list_to_bytes(s,SSL_get_ciphers(s),&(p[2]),0); if (i == 0) { SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_NO_CIPHERS_AVAILABLE); @@ -631,7 +623,7 @@ err: return(-1); } -static int ssl3_get_server_hello(SSL *s) +int ssl3_get_server_hello(SSL *s) { STACK_OF(SSL_CIPHER) *sk; SSL_CIPHER *c; @@ -641,14 +633,40 @@ static int ssl3_get_server_hello(SSL *s) long n; SSL_COMP *comp; - n=ssl3_get_message(s, + n=s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_HELLO_A, SSL3_ST_CR_SRVR_HELLO_B, - SSL3_MT_SERVER_HELLO, + -1, 300, /* ?? */ &ok); if (!ok) return((int)n); + + if ( SSL_version(s) == DTLS1_VERSION) + { + if ( s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST) + { + if ( s->d1->send_cookie == 0) + { + s->s3->tmp.reuse_message = 1; + return 1; + } + else /* already sent a cookie */ + { + al=SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_MESSAGE_TYPE); + goto f_err; + } + } + } + + if ( s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO) + { + al=SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_BAD_MESSAGE_TYPE); + goto f_err; + } + d=p=(unsigned char *)s->init_msg; if ((p[0] != (s->version>>8)) || (p[1] != (s->version&0xff))) @@ -776,18 +794,19 @@ err: return(-1); } -static int ssl3_get_server_certificate(SSL *s) +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, + n=s->method->ssl_get_message(s, SSL3_ST_CR_CERT_A, SSL3_ST_CR_CERT_B, -1, @@ -808,7 +827,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) { @@ -860,10 +879,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); @@ -886,16 +905,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))) @@ -917,31 +936,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; @@ -959,7 +978,7 @@ err: return(ret); } -static int ssl3_get_key_exchange(SSL *s) +int ssl3_get_key_exchange(SSL *s) { #ifndef OPENSSL_NO_RSA unsigned char *q,md_buf[EVP_MAX_MD_SIZE*2]; @@ -985,7 +1004,7 @@ static int ssl3_get_key_exchange(SSL *s) /* use same message size as in ssl3_get_certificate_request() * as ServerKeyExchange message may be skipped */ - n=ssl3_get_message(s, + n=s->method->ssl_get_message(s, SSL3_ST_CR_KEY_EXCH_A, SSL3_ST_CR_KEY_EXCH_B, -1, @@ -1170,6 +1189,9 @@ static int ssl3_get_key_exchange(SSL *s) #ifndef OPENSSL_NO_ECDH else if (alg & SSL_kECDHE) { + EC_GROUP *ngroup; + const EC_GROUP *group; + if ((ecdh=EC_KEY_new()) == NULL) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); @@ -1195,14 +1217,23 @@ static int ssl3_get_key_exchange(SSL *s) goto f_err; } - if (!(ecdh->group=EC_GROUP_new_by_nid(curve_nid))) + ngroup = EC_GROUP_new_by_curve_name(curve_nid); + if (ngroup == NULL) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_EC_LIB); goto err; } + if (EC_KEY_set_group(ecdh, ngroup) == 0) + { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_EC_LIB); + goto err; + } + EC_GROUP_free(ngroup); + + group = EC_KEY_get0_group(ecdh); if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && - (EC_GROUP_get_degree(ecdh->group) > 163)) + (EC_GROUP_get_degree(group) > 163)) { al=SSL_AD_EXPORT_RESTRICTION; SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); @@ -1212,7 +1243,7 @@ static int ssl3_get_key_exchange(SSL *s) p+=2; /* Next, get the encoded ECPoint */ - if (((srvr_ecpoint = EC_POINT_new(ecdh->group)) == NULL) || + if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) || ((bn_ctx = BN_CTX_new()) == NULL)) { SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); @@ -1223,7 +1254,7 @@ static int ssl3_get_key_exchange(SSL *s) p+=1; param_len += (1 + encoded_pt_len); if ((param_len > n) || - (EC_POINT_oct2point(ecdh->group, srvr_ecpoint, + (EC_POINT_oct2point(group, srvr_ecpoint, p, encoded_pt_len, bn_ctx) == 0)) { al=SSL_AD_DECODE_ERROR; @@ -1248,10 +1279,11 @@ static int ssl3_get_key_exchange(SSL *s) pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); #endif /* else anonymous ECDH, so no certificate or pkey. */ - ecdh->pub_key = srvr_ecpoint; + EC_KEY_set_public_key(ecdh, srvr_ecpoint); s->session->sess_cert->peer_ecdh_tmp=ecdh; ecdh=NULL; BN_CTX_free(bn_ctx); + EC_POINT_free(srvr_ecpoint); srvr_ecpoint = NULL; } else if (alg & SSL_kECDH) @@ -1403,16 +1435,17 @@ err: return(-1); } -static int ssl3_get_certificate_request(SSL *s) +int ssl3_get_certificate_request(SSL *s) { int ok,ret=0; 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, + n=s->method->ssl_get_message(s, SSL3_ST_CR_CERT_REQ_A, SSL3_ST_CR_CERT_REQ_B, -1, @@ -1448,7 +1481,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) { @@ -1550,12 +1583,12 @@ static int ca_dn_cmp(const X509_NAME * const *a, const X509_NAME * const *b) return(X509_NAME_cmp(*a,*b)); } -static int ssl3_get_server_done(SSL *s) +int ssl3_get_server_done(SSL *s) { int ok,ret=0; long n; - n=ssl3_get_message(s, + n=s->method->ssl_get_message(s, SSL3_ST_CR_SRVR_DONE_A, SSL3_ST_CR_SRVR_DONE_B, SSL3_MT_SERVER_DONE, @@ -1574,7 +1607,22 @@ static int ssl3_get_server_done(SSL *s) return(ret); } -static int ssl3_send_client_key_exchange(SSL *s) + +static const int KDF1_SHA1_len = 20; +static void *KDF1_SHA1(const void *in, size_t inlen, void *out, size_t *outlen) + { +#ifndef OPENSSL_NO_SHA + if (*outlen < SHA_DIGEST_LENGTH) + return NULL; + else + *outlen = SHA_DIGEST_LENGTH; + return SHA1(in, inlen, out); +#else + return NULL; +#endif + } + +int ssl3_send_client_key_exchange(SSL *s) { unsigned char *p,*d; int n; @@ -1584,11 +1632,11 @@ 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; - EC_POINT *srvr_ecpoint = NULL; + const EC_POINT *srvr_ecpoint = NULL; EVP_PKEY *srvr_pub_pkey = NULL; unsigned char *encodedPoint = NULL; int encoded_pt_len = 0; @@ -1602,8 +1650,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) { @@ -1665,12 +1713,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]; @@ -1682,8 +1730,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; @@ -1691,37 +1739,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 @@ -1786,14 +1834,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)) @@ -1855,8 +1903,10 @@ static int ssl3_send_client_key_exchange(SSL *s) #ifndef OPENSSL_NO_ECDH else if ((l & SSL_kECDH) || (l & SSL_kECDHE)) { - EC_GROUP *srvr_group = NULL; + const EC_GROUP *srvr_group = NULL; + EC_KEY *tkey; int ecdh_clnt_cert = 0; + int field_size = 0; /* Did we send out the client's * ECDH share for use in premaster @@ -1888,10 +1938,7 @@ static int ssl3_send_client_key_exchange(SSL *s) if (s->session->sess_cert->peer_ecdh_tmp != NULL) { - srvr_group = s->session->sess_cert-> \ - peer_ecdh_tmp->group; - srvr_ecpoint = s->session->sess_cert-> \ - peer_ecdh_tmp->pub_key; + tkey = s->session->sess_cert->peer_ecdh_tmp; } else { @@ -1900,18 +1947,19 @@ static int ssl3_send_client_key_exchange(SSL *s) sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); if ((srvr_pub_pkey == NULL) || (srvr_pub_pkey->type != EVP_PKEY_EC) || - (srvr_pub_pkey->pkey.eckey == NULL)) + (srvr_pub_pkey->pkey.ec == NULL)) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); goto err; } - srvr_group = srvr_pub_pkey->pkey.eckey->group; - srvr_ecpoint = - srvr_pub_pkey->pkey.eckey->pub_key; + tkey = srvr_pub_pkey->pkey.ec; } + srvr_group = EC_KEY_get0_group(tkey); + srvr_ecpoint = EC_KEY_get0_public_key(tkey); + if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) { SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, @@ -1925,15 +1973,30 @@ static int ssl3_send_client_key_exchange(SSL *s) goto err; } - clnt_ecdh->group = srvr_group; + if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB); + goto err; + } 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. */ - clnt_ecdh->priv_key = BN_dup(s->cert->key-> \ - privatekey->pkey.eckey->priv_key); + const BIGNUM *priv_key; + tkey = s->cert->key->privatekey->pkey.ec; + priv_key = EC_KEY_get0_private_key(tkey); + if (priv_key == NULL) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) + { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_EC_LIB); + goto err; + } } else { @@ -1945,25 +2008,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(srvr_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) { @@ -1976,8 +2053,8 @@ static int ssl3_send_client_key_exchange(SSL *s) * allocate memory accordingly. */ encoded_pt_len = - EC_POINT_point2oct(clnt_ecdh->group, - clnt_ecdh->pub_key, + EC_POINT_point2oct(srvr_group, + EC_KEY_get0_public_key(clnt_ecdh), POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL); @@ -1993,13 +2070,13 @@ static int ssl3_send_client_key_exchange(SSL *s) } /* Encode the public key */ - n = EC_POINT_point2oct(clnt_ecdh->group, - clnt_ecdh->pub_key, + n = EC_POINT_point2oct(srvr_group, + EC_KEY_get0_public_key(clnt_ecdh), POINT_CONVERSION_UNCOMPRESSED, 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); @@ -2011,11 +2088,7 @@ static int ssl3_send_client_key_exchange(SSL *s) BN_CTX_free(bn_ctx); if (encodedPoint != NULL) OPENSSL_free(encodedPoint); if (clnt_ecdh != NULL) - { - /* group is shared */ - clnt_ecdh->group = NULL; EC_KEY_free(clnt_ecdh); - } EVP_PKEY_free(srvr_pub_pkey); } #endif /* !OPENSSL_NO_ECDH */ @@ -2044,17 +2117,13 @@ err: BN_CTX_free(bn_ctx); if (encodedPoint != NULL) OPENSSL_free(encodedPoint); if (clnt_ecdh != NULL) - { - /* group is shared */ - clnt_ecdh->group = NULL; EC_KEY_free(clnt_ecdh); - } - EVP_PKEY_free(srvr_pub_pkey); + EVP_PKEY_free(srvr_pub_pkey); #endif return(-1); } -static int ssl3_send_client_verify(SSL *s) +int ssl3_send_client_verify(SSL *s) { unsigned char *p,*d; unsigned char data[MD5_DIGEST_LENGTH+SHA_DIGEST_LENGTH]; @@ -2115,7 +2184,7 @@ static int ssl3_send_client_verify(SSL *s) if (!ECDSA_sign(pkey->save_type, &(data[MD5_DIGEST_LENGTH]), SHA_DIGEST_LENGTH,&(p[2]), - (unsigned int *)&j,pkey->pkey.eckey)) + (unsigned int *)&j,pkey->pkey.ec)) { SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_ECDSA_LIB); @@ -2133,6 +2202,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; } @@ -2141,7 +2211,7 @@ err: return(-1); } -static int ssl3_send_client_certificate(SSL *s) +int ssl3_send_client_certificate(SSL *s) { X509 *x509=NULL; EVP_PKEY *pkey=NULL; @@ -2220,7 +2290,7 @@ static int ssl3_send_client_certificate(SSL *s) #define has_bits(i,m) (((i)&(m)) == (m)) -static int ssl3_check_cert_and_algorithm(SSL *s) +int ssl3_check_cert_and_algorithm(SSL *s) { int i,idx; long algs; @@ -2325,7 +2395,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; @@ -2337,7 +2407,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; @@ -2362,7 +2432,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,