* [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
#include <openssl/objects.h>
#include <openssl/evp.h>
#include <openssl/x509.h>
+#include <openssl/dh.h>
+#include <openssl/bn.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 (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;
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 ((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,
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;