* [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
* 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.
*
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
+#ifndef OPENSSL_NO_KRB5
#include <openssl/krb5_asn.h>
+#endif
#include <openssl/md5.h>
-#include "cryptlib.h"
static SSL_METHOD *ssl3_get_server_method(int ver);
static int ssl3_get_client_hello(SSL *s);
if (init)
{
- memcpy((char *)&SSLv3_server_data,(char *)sslv3_base_method(),
- sizeof(SSL_METHOD));
- SSLv3_server_data.ssl_accept=ssl3_accept;
- SSLv3_server_data.get_ssl_method=ssl3_get_server_method;
- init=0;
+ CRYPTO_w_lock(CRYPTO_LOCK_SSL_METHOD);
+
+ if (init)
+ {
+ memcpy((char *)&SSLv3_server_data,(char *)sslv3_base_method(),
+ sizeof(SSL_METHOD));
+ SSLv3_server_data.ssl_accept=ssl3_accept;
+ SSLv3_server_data.get_ssl_method=ssl3_get_server_method;
+ init=0;
+ }
+
+ CRYPTO_w_unlock(CRYPTO_LOCK_SSL_METHOD);
}
return(&SSLv3_server_data);
}
if (ret == 2)
s->state = SSL3_ST_SR_CLNT_HELLO_C;
else {
- /* could be sent for a DH cert, even if we
- * have not asked for it :-) */
- ret=ssl3_get_client_certificate(s);
- if (ret <= 0) goto end;
+ if (s->s3->tmp.cert_request)
+ {
+ ret=ssl3_get_client_certificate(s);
+ if (ret <= 0) goto end;
+ }
s->init_num=0;
s->state=SSL3_ST_SR_KEY_EXCH_A;
}
}
/* TLS does not mind if there is extra stuff */
+#if 0 /* SSL 3.0 does not mind either, so we should disable this test
+ * (was enabled in 0.9.6d through 0.9.6j and 0.9.7 through 0.9.7b,
+ * in earlier SSLeay/OpenSSL releases this test existed but was buggy) */
if (s->version == SSL3_VERSION)
{
if (p < (d+n))
goto f_err;
}
}
+#endif
/* Given s->session->ciphers and SSL_get_ciphers, we must
* pick a cipher */
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;
kn=0;
}
- if (!BUF_MEM_grow(buf,n+4+kn))
+ if (!BUF_MEM_grow_clean(buf,n+4+kn))
{
SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,ERR_LIB_BUF);
goto err;
{
name=sk_X509_NAME_value(sk,i);
j=i2d_X509_NAME(name,NULL);
- if (!BUF_MEM_grow(buf,4+n+j+2))
+ if (!BUF_MEM_grow_clean(buf,4+n+j+2))
{
SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST,ERR_R_BUF_LIB);
goto err;
s->init_num += 4;
#endif
+ s->state = SSL3_ST_SW_CERT_REQ_B;
}
/* SSL3_ST_SW_CERT_REQ_B */
return(-1);
}
+
+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_get_client_key_exchange(SSL *s)
{
int i,al,ok;
if (i != SSL_MAX_MASTER_KEY_LENGTH)
{
al=SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT);
+ /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_RSA_DECRYPT); */
}
if ((al == -1) && !((p[0] == (s->client_version>>8)) && (p[1] == (s->client_version & 0xff))))
(p[0] == (s->version>>8)) && (p[1] == (s->version & 0xff))))
{
al=SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER);
- goto f_err;
+ /* SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_BAD_PROTOCOL_VERSION_NUMBER); */
+
+ /* The Klima-Pokorny-Rosa extension of Bleichenbacher's attack
+ * (http://eprint.iacr.org/2003/052/) exploits the version
+ * number check as a "bad version oracle" -- an alert would
+ * reveal that the plaintext corresponding to some ciphertext
+ * made up by the adversary is properly formatted except
+ * that the version number is wrong. To avoid such attacks,
+ * we should treat this just like any other decryption error. */
}
}
if (al != -1)
{
-#if 0
- goto f_err;
-#else
/* Some decryption failure -- use random value instead as countermeasure
* against Bleichenbacher's attack on PKCS #1 v1.5 RSA padding
- * (see RFC 2246, section 7.4.7.1).
- * But note that due to length and protocol version checking, the
- * attack is impractical anyway (see section 5 in D. Bleichenbacher:
- * "Chosen Ciphertext Attacks Against Protocols Based on the RSA
- * Encryption Standard PKCS #1", CRYPTO '98, LNCS 1462, pp. 1-12).
- */
+ * (see RFC 2246, section 7.4.7.1). */
ERR_clear_error();
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 */
-#endif
}
s->session->master_key_length=
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key,
p,i);
- memset(p,0,i);
+ OPENSSL_cleanse(p,i);
}
else
#endif
s->session->master_key_length=
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key,p,i);
- memset(p,0,i);
+ OPENSSL_cleanse(p,i);
}
else
#endif
if (enc == NULL)
goto err;
- memset(iv, 0, EVP_MAX_IV_LENGTH); /* per RFC 1510 */
+ memset(iv, 0, sizeof iv); /* per RFC 1510 */
if (!EVP_DecryptInit_ex(&ciph_ctx,enc,NULL,kssl_ctx->key,iv))
{
if ((l & SSL_kECDH) || (l & SSL_kECDHE))
{
int ret = 1;
+ int field_size = 0;
/* initialize structures for server's ECDH key pair */
if ((srvr_ecdh = EC_KEY_new()) == NULL)
}
/* Compute the shared pre-master secret */
- i = ECDH_compute_key(p, clnt_ecpoint, srvr_ecdh);
+ field_size = EC_GROUP_get_degree(srvr_ecdh->group);
+ if (field_size <= 0)
+ {
+ SSLerr(SSL_F_SSL3_GET_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)
+ i = ECDH_compute_key(p, KDF1_SHA1_len, clnt_ecpoint, srvr_ecdh, KDF1_SHA1);
+ else
+ i = ECDH_compute_key(p, (field_size+7)/8, clnt_ecpoint, srvr_ecdh, NULL);
if (i <= 0)
{
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
s->session->master_key_length = s->method->ssl3_enc-> \
generate_master_secret(s, s->session->master_key, p, i);
- memset(p, 0, i);
+ OPENSSL_cleanse(p, i);
return (ret);
}
else
#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH)
err:
#endif
-#ifndef NO_OPENSSL_ECDH
+#ifndef OPENSSL_NO_ECDH
EVP_PKEY_free(clnt_pub_pkey);
EC_POINT_free(clnt_ecpoint);
if (srvr_ecdh != NULL)
SSL3_ST_SR_CERT_VRFY_A,
SSL3_ST_SR_CERT_VRFY_B,
-1,
- 512, /* 512? */
+ 514, /* 514? */
&ok);
if (!ok) return((int)n);
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,
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)
{
/* This is the complement of curve_id2nid in s3_clnt.c. */
static int nid2curve_id(int nid)
{
- /* 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]) */
switch (nid) {
case NID_sect163k1: /* sect163k1 (1) */
return 1;