X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fs3_clnt.c;h=8feb24a1424500ff5cc5bf668e17061aae17087c;hp=ca15881eaf2713e20e887a9fe05b9789fe6be4a3;hb=60a938c6bca4c0890ed2d320e29fb43c970094d5;hpb=a90ae02454ed755a56a00943ea49195c6b565655 diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c index ca15881eaf..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 @@ -117,19 +117,6 @@ * The Contribution is licensed pursuant to the OpenSSL open source * license provided above. * - * In addition, Sun covenants to all licensees who provide a reciprocal - * covenant with respect to their own patents if any, not to sue under - * current and future patent claims necessarily infringed by the making, - * using, practicing, selling, offering for sale and/or otherwise - * disposing of the Contribution as delivered hereunder - * (or portions thereof), provided that such covenant shall not apply: - * 1) for code that a licensee deletes from the Contribution; - * 2) separates from the Contribution; or - * 3) for infringements caused by: - * i) the modification of the Contribution or - * ii) the combination of the Contribution with other software or - * devices where such combination causes the infringement. - * * ECC cipher suite support in OpenSSL originally written by * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. * @@ -143,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); @@ -178,18 +165,25 @@ SSL_METHOD *SSLv3_client_method(void) if (init) { - memcpy((char *)&SSLv3_client_data,(char *)sslv3_base_method(), - sizeof(SSL_METHOD)); - SSLv3_client_data.ssl_connect=ssl3_connect; - SSLv3_client_data.get_ssl_method=ssl3_get_client_method; - init=0; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD); + + if (init) + { + memcpy((char *)&SSLv3_client_data,(char *)sslv3_base_method(), + sizeof(SSL_METHOD)); + SSLv3_client_data.ssl_connect=ssl3_connect; + SSLv3_client_data.get_ssl_method=ssl3_get_client_method; + init=0; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD); } return(&SSLv3_client_data); } 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; @@ -250,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; } @@ -535,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); @@ -585,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; @@ -671,30 +668,20 @@ static int ssl3_get_server_hello(SSL *s) /* get the session-id */ j= *(p++); - if(j > sizeof s->session->session_id) - { - al=SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, - SSL_R_SSL3_SESSION_ID_TOO_LONG); - goto f_err; - } - - if ((j != 0) && (j != SSL3_SESSION_ID_SIZE)) + if ((j > sizeof s->session->session_id) || (j > SSL3_SESSION_ID_SIZE)) { - /* SSLref returns 16 :-( */ - if (j < SSL2_SSL_SESSION_ID_LENGTH) - { - al=SSL_AD_ILLEGAL_PARAMETER; - SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SSL3_SESSION_ID_TOO_SHORT); - goto f_err; - } + al=SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SSL3_SESSION_ID_TOO_LONG); + goto f_err; } + if (j != 0 && j == s->session->session_id_length && memcmp(p,s->session->session_id,j) == 0) { if(s->sid_ctx_length != s->session->sid_ctx_length || memcmp(s->session->sid_ctx,s->sid_ctx,s->sid_ctx_length)) { + /* actually a client application bug */ al=SSL_AD_ILLEGAL_PARAMETER; SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); goto f_err; @@ -738,7 +725,12 @@ static int ssl3_get_server_hello(SSL *s) goto f_err; } - if (s->hit && (s->session->cipher != c)) + /* Depending on the session caching (internal/external), the cipher + and/or cipher_id values may not be set. Make sure that + cipher_id is set and use it for comparison. */ + if (s->session->cipher) + s->session->cipher_id = s->session->cipher->id; + if (s->hit && (s->session->cipher_id != c->id)) { if (!(s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)) @@ -789,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, @@ -816,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) { @@ -868,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); @@ -894,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))) @@ -925,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; @@ -1417,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, @@ -1456,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) { @@ -1582,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; @@ -1592,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; @@ -1610,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) { @@ -1636,16 +1643,16 @@ static int ssl3_send_client_key_exchange(SSL *s) tmp_buf[0]=s->client_version>>8; tmp_buf[1]=s->client_version&0xff; - if (RAND_bytes(&(tmp_buf[2]),SSL_MAX_MASTER_KEY_LENGTH-2) <= 0) + if (RAND_bytes(&(tmp_buf[2]),sizeof tmp_buf-2) <= 0) goto err; - s->session->master_key_length=SSL_MAX_MASTER_KEY_LENGTH; + s->session->master_key_length=sizeof tmp_buf; q=p; /* Fix buf for TLS and beyond */ if (s->version > SSL3_VERSION) p+=2; - n=RSA_public_encrypt(SSL_MAX_MASTER_KEY_LENGTH, + n=RSA_public_encrypt(sizeof tmp_buf, tmp_buf,p,rsa,RSA_PKCS1_PADDING); #ifdef PKCS1_CHECK if (s->options & SSL_OP_PKCS1_CHECK_1) p[1]++; @@ -1667,18 +1674,18 @@ static int ssl3_send_client_key_exchange(SSL *s) s->session->master_key_length= s->method->ssl3_enc->generate_master_secret(s, s->session->master_key, - tmp_buf,SSL_MAX_MASTER_KEY_LENGTH); - memset(tmp_buf,0,SSL_MAX_MASTER_KEY_LENGTH); + tmp_buf,sizeof tmp_buf); + OPENSSL_cleanse(tmp_buf,sizeof tmp_buf); } #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]; @@ -1690,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; @@ -1699,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 @@ -1764,7 +1771,7 @@ static int ssl3_send_client_key_exchange(SSL *s) n+=2; } - if (RAND_bytes(tmp_buf,SSL_MAX_MASTER_KEY_LENGTH) <= 0) + if (RAND_bytes(tmp_buf,sizeof tmp_buf) <= 0) goto err; /* 20010420 VRS. Tried it this way; failed. @@ -1774,11 +1781,11 @@ static int ssl3_send_client_key_exchange(SSL *s) ** EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv); */ - memset(iv, 0, EVP_MAX_IV_LENGTH); /* per RFC 1510 */ + memset(iv, 0, sizeof iv); /* per RFC 1510 */ EVP_EncryptInit_ex(&ciph_ctx,enc, NULL, kssl_ctx->key,iv); EVP_EncryptUpdate(&ciph_ctx,epms,&outl,tmp_buf, - SSL_MAX_MASTER_KEY_LENGTH); + sizeof tmp_buf); EVP_EncryptFinal_ex(&ciph_ctx,&(epms[outl]),&padl); outl += padl; if (outl > sizeof epms) @@ -1794,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, SSL_MAX_MASTER_KEY_LENGTH); + tmp_buf, sizeof tmp_buf); - memset(tmp_buf, 0, SSL_MAX_MASTER_KEY_LENGTH); - memset(epms, 0, outl); - } + 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)) @@ -1865,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 @@ -1936,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. */ @@ -1953,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) { @@ -2007,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); @@ -2020,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); } @@ -2057,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); } @@ -2141,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; } @@ -2333,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; @@ -2345,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; @@ -2370,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,