}
s->init_num=0;
- s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE;
s->s3->flags &= ~TLS1_FLAGS_SKIP_CERT_VERIFY;
s->s3->flags &= ~SSL3_FLAGS_CCS_OK;
/* Should have been reset by ssl3_get_finished, too. */
case SSL3_ST_SW_KEY_EXCH_B:
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- /* clear this, it may get reset by
- * send_server_key_exchange */
- if ((s->options & SSL_OP_EPHEMERAL_RSA)
-#ifndef OPENSSL_NO_KRB5
- && !(alg_k & SSL_kKRB5)
-#endif /* OPENSSL_NO_KRB5 */
- )
- /* option SSL_OP_EPHEMERAL_RSA sends temporary RSA key
- * even when forbidden by protocol specs
- * (handshake may fail as clients are not required to
- * be able to handle this) */
- s->s3->tmp.use_rsa_tmp=1;
- else
- s->s3->tmp.use_rsa_tmp=0;
+ /*
+ * clear this, it may get reset by
+ * send_server_key_exchange
+ */
+ s->s3->tmp.use_rsa_tmp=0;
/* only send if a DH key exchange, fortezza or
* server certificate contains the server's
* public key for key exchange.
*/
- if (s->s3->tmp.use_rsa_tmp
+ if (0
/* PSK: send ServerKeyExchange if PSK identity
* hint if provided */
#ifndef OPENSSL_NO_PSK
case SSL3_ST_SR_CERT_A:
case SSL3_ST_SR_CERT_B:
- /* Check for second client hello (MS SGC) */
- ret = ssl3_check_client_hello(s);
- if (ret <= 0)
- goto end;
- if (ret == 2)
- s->state = SSL3_ST_SR_CLNT_HELLO_C;
- else {
- 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;
- }
+ 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;
break;
case SSL3_ST_SR_KEY_EXCH_A:
return ssl_do_write(s);
}
-int ssl3_check_client_hello(SSL *s)
- {
- int ok;
- long n;
-
- /* this function is called when we really expect a Certificate message,
- * so permit appropriate message length */
- n=s->method->ssl_get_message(s,
- SSL3_ST_SR_CERT_A,
- SSL3_ST_SR_CERT_B,
- -1,
- s->max_cert_list,
- &ok);
- if (!ok) return((int)n);
- s->s3->tmp.reuse_message = 1;
- if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO)
- {
- /* We only allow the client to restart the handshake once per
- * negotiation. */
- if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE)
- {
- SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, SSL_R_MULTIPLE_SGC_RESTARTS);
- return -1;
- }
- /* Throw away what we have done so far in the current handshake,
- * which will now be aborted. (A full SSL_clear would be too much.) */
-#ifndef OPENSSL_NO_DH
- if (s->s3->tmp.dh != NULL)
- {
- DH_free(s->s3->tmp.dh);
- s->s3->tmp.dh = NULL;
- }
-#endif
-#ifndef OPENSSL_NO_ECDH
- if (s->s3->tmp.ecdh != NULL)
- {
- EC_KEY_free(s->s3->tmp.ecdh);
- s->s3->tmp.ecdh = NULL;
- }
-#endif
- s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE;
- return 2;
- }
- return 1;
-}
-
int ssl3_get_client_hello(SSL *s)
{
int i,j,ok,al=SSL_AD_INTERNAL_ERROR,ret= -1;
}
/* else cookie verification succeeded */
}
+ /* default verification */
else if ( memcmp(s->d1->rcvd_cookie, s->d1->cookie,
- s->d1->cookie_len) != 0) /* default verification */
+ s->d1->cookie_len) != 0)
{
al=SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,
id=s->session->cipher->id;
#ifdef CIPHER_DEBUG
- printf("client sent %d ciphers\n",sk_num(ciphers));
+ fprintf(stderr,"client sent %d ciphers\n",sk_SSL_CIPHER_num(ciphers));
#endif
for (i=0; i<sk_SSL_CIPHER_num(ciphers); i++)
{
c=sk_SSL_CIPHER_value(ciphers,i);
#ifdef CIPHER_DEBUG
- printf("client [%2d of %2d]:%s\n",
- i,sk_num(ciphers),SSL_CIPHER_get_name(c));
+ fprintf(stderr,"client [%2d of %2d]:%s\n",
+ i,sk_SSL_CIPHER_num(ciphers),
+ SSL_CIPHER_get_name(c));
#endif
if (c->id == id)
{
else if (s->hit)
comp = NULL;
else if (ssl_allow_compression(s) && s->ctx->comp_methods)
- { /* See if we have a match */
+ {
+ /* See if we have a match */
int m,nn,o,v,done=0;
nn=sk_SSL_COMP_num(s->ctx->comp_methods);
goto f_err;
}
- /* we now have the following setup.
+ /*-
+ * we now have the following setup.
* client_random
* cipher_list - our prefered list of ciphers
* ciphers - the clients prefered list of ciphers
memcpy(p,s->s3->server_random,SSL3_RANDOM_SIZE);
p+=SSL3_RANDOM_SIZE;
- /* There are several cases for the session ID to send
+ /*-
+ * There are several cases for the session ID to send
* back in the server hello:
* - For session reuse from the session cache,
* we send back the old session ID.
SSL3_ST_SR_KEY_EXCH_A,
SSL3_ST_SR_KEY_EXCH_B,
SSL3_MT_CLIENT_KEY_EXCHANGE,
- 2048, /* ??? */
+ 2048,
&ok);
if (!ok) return((int)n);
unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH];
int decrypt_len;
unsigned char decrypt_good, version_good;
+ size_t j;
/* FIX THIS UP EAY EAY EAY EAY */
if (s->s3->tmp.use_rsa_tmp)
{
if (!(s->options & SSL_OP_TLS_D5_BUG))
{
+ al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
- goto err;
+ goto f_err;
}
else
p-=2;
n=i;
}
+ /*
+ * Reject overly short RSA ciphertext because we want to be sure
+ * that the buffer size makes it safe to iterate over the entire
+ * size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The
+ * actual expected size is larger due to RSA padding, but the
+ * bound is sufficient to be safe.
+ */
+ if (n < SSL_MAX_MASTER_KEY_LENGTH)
+ {
+ al = SSL_AD_DECRYPT_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
+ goto f_err;
+ }
+
/* We must not leak whether a decryption failure occurs because
* of Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see
* RFC 2246, section 7.4.7.1). The code follows that advice of
* to remain non-zero (0xff). */
decrypt_good &= version_good;
- /* Now copy rand_premaster_secret over p using
- * decrypt_good_mask. */
- for (i = 0; i < (int) sizeof(rand_premaster_secret); i++)
+ /*
+ * Now copy rand_premaster_secret over from p using
+ * decrypt_good_mask. If decryption failed, then p does not
+ * contain valid plaintext, however, a check above guarantees
+ * it is still sufficiently large to read from.
+ */
+ for (j = 0; j < sizeof(rand_premaster_secret); j++)
{
- p[i] = constant_time_select_8(decrypt_good, p[i],
- rand_premaster_secret[i]);
+ p[j] = constant_time_select_8(decrypt_good, p[j],
+ rand_premaster_secret[j]);
}
s->session->master_key_length=
s->method->ssl3_enc->generate_master_secret(s,
s->session->master_key,
- p,i);
- OPENSSL_cleanse(p,i);
+ p,sizeof(rand_premaster_secret));
+ OPENSSL_cleanse(p,sizeof(rand_premaster_secret));
}
else
#endif
&kssl_err)) != 0)
{
#ifdef KSSL_DEBUG
- printf("kssl_sget_tkt rtn %d [%d]\n",
+ fprintf(stderr,"kssl_sget_tkt rtn %d [%d]\n",
krb5rc, kssl_err.reason);
if (kssl_err.text)
- printf("kssl_err text= %s\n", kssl_err.text);
+ fprintf(stderr,"kssl_err text= %s\n", kssl_err.text);
#endif /* KSSL_DEBUG */
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
kssl_err.reason);
&authtime, &kssl_err)) != 0)
{
#ifdef KSSL_DEBUG
- printf("kssl_check_authent rtn %d [%d]\n",
+ fprintf(stderr,"kssl_check_authent rtn %d [%d]\n",
krb5rc, kssl_err.reason);
if (kssl_err.text)
- printf("kssl_err text= %s\n", kssl_err.text);
+ fprintf(stderr,"kssl_err text= %s\n", kssl_err.text);
#endif /* KSSL_DEBUG */
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
kssl_err.reason);
}
- /* Was doing kssl_ctx_free() here,
- ** but it caused problems for apache.
- ** kssl_ctx = kssl_ctx_free(kssl_ctx);
- ** if (s->kssl_ctx) s->kssl_ctx = NULL;
- */
+ /*- Was doing kssl_ctx_free() here,
+ * but it caused problems for apache.
+ * kssl_ctx = kssl_ctx_free(kssl_ctx);
+ * if (s->kssl_ctx) s->kssl_ctx = NULL;
+ */
}
else
#endif /* OPENSSL_NO_KRB5 */
if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_VERIFY)
{
s->s3->tmp.reuse_message=1;
- if ((peer != NULL) && (type & EVP_PKT_SIGN))
+ if (peer != NULL)
{
al=SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_GET_CERT_VERIFY,SSL_R_MISSING_VERIFY_MESSAGE);
i2d_SSL_SESSION(sess, &p);
SSL_SESSION_free(sess);
- /* Grow buffer if need be: the length calculation is as
+ /*-
+ * Grow buffer if need be: the length calculation is as
* follows handshake_header_length +
* 4 (ticket lifetime hint) + 2 (ticket length) +
* 16 (key name) + max_iv_len (iv length) +
if (s->state == SSL3_ST_SW_CERT_STATUS_A)
{
unsigned char *p;
- /* Grow buffer if need be: the length calculation is as
+ /*-
+ * Grow buffer if need be: the length calculation is as
* follows 1 (message type) + 3 (message length) +
* 1 (ocsp response type) + 3 (ocsp response length)
* + (ocsp response)
return -1;
}
+ /* See the payload format below */
n=s->method->ssl_get_message(s,
SSL3_ST_SR_NEXT_PROTO_A,
SSL3_ST_SR_NEXT_PROTO_B,
SSL3_MT_NEXT_PROTO,
- 514, /* See the payload format below */
+ 514,
&ok);
if (!ok)
p=(unsigned char *)s->init_msg;
- /* The payload looks like:
+ /*-
+ * The payload looks like:
* uint8 proto_len;
* uint8 proto[proto_len];
* uint8 padding_len;