ret = -1;
goto end;
}
+
+ if (!ssl_security(s, SSL_SECOP_VERSION, 0,
+ s->version, NULL))
+ {
+ SSLerr(SSL_F_SSL3_CONNECT, SSL_R_VERSION_TOO_LOW);
+ return -1;
+ }
/* s->version=SSL3_VERSION; */
s->type=SSL_ST_CONNECT;
}
s->init_num=0;
break;
-#ifndef OPENSSL_NO_TLSEXT
- case SSL3_ST_CR_SUPPLEMENTAL_DATA_A:
- case SSL3_ST_CR_SUPPLEMENTAL_DATA_B:
- ret = tls1_get_server_supplemental_data(s);
- if (ret <= 0) goto end;
- s->state=SSL3_ST_CR_CERT_A;
- s->init_num = 0;
- break;
-#endif
case SSL3_ST_CR_CERT_A:
case SSL3_ST_CR_CERT_B:
#ifndef OPENSSL_NO_TLSEXT
ret=ssl3_check_finished(s);
if (ret <= 0) goto end;
- if (ret == 3)
- {
- s->state=SSL3_ST_CR_SUPPLEMENTAL_DATA_A;
- s->init_num=0;
- break;
- }
if (ret == 2)
{
s->hit = 1;
}
}
#endif
-#ifndef OPENSSL_NO_TLSEXT
- s->state=SSL3_ST_CW_SUPPLEMENTAL_DATA_A;
-#else
if (s->s3->tmp.cert_req)
s->state=SSL3_ST_CW_CERT_A;
else
s->state=SSL3_ST_CW_KEY_EXCH_A;
-#endif
s->init_num=0;
break;
break;
#endif
-#ifndef OPENSSL_NO_TLSEXT
- case SSL3_ST_CW_SUPPLEMENTAL_DATA_A:
- case SSL3_ST_CW_SUPPLEMENTAL_DATA_B:
- ret = tls1_send_client_supplemental_data(s, &skip);
- if (ret <= 0) goto end;
- if (s->s3->tmp.cert_req)
- s->state=SSL3_ST_CW_CERT_A;
- else
- s->state=SSL3_ST_CW_KEY_EXCH_A;
- s->init_num=0;
- break;
-#endif
-
case SSL3_ST_CW_FINISHED_A:
case SSL3_ST_CW_FINISHED_B:
ret=ssl3_send_finished(s,
s->method->ssl3_enc->client_finished_label,
s->method->ssl3_enc->client_finished_label_len);
if (ret <= 0) goto end;
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->state=SSL3_ST_CW_FLUSH;
/* clear flags */
case SSL3_ST_CR_FINISHED_A:
case SSL3_ST_CR_FINISHED_B:
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
SSL3_ST_CR_FINISHED_B);
if (ret <= 0) goto end;
*(p++)=1;
#else
- if ((s->options & SSL_OP_NO_COMPRESSION)
- || !s->ctx->comp_methods)
+ if (!ssl_allow_compression(s) || !s->ctx->comp_methods)
j=0;
else
j=sk_SSL_COMP_num(s->ctx->comp_methods);
{
s->session->cipher = pref_cipher ?
pref_cipher : ssl_get_cipher_by_char(s, p+j);
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
}
}
#endif /* OPENSSL_NO_TLSEXT */
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
goto f_err;
}
+ s->s3->flags |= SSL3_FLAGS_CCS_OK;
s->hit=1;
}
else /* a miss or crap from the other end */
/* If it is a disabled cipher we didn't send it in client hello,
* so return an error.
*/
- if (ssl_cipher_disabled(s, c))
+ if (ssl_cipher_disabled(s, c, SSL_SECOP_CIPHER_CHECK))
{
al=SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_WRONG_CIPHER_RETURNED);
}
if (j == 0)
comp=NULL;
- else if (s->options & SSL_OP_NO_COMPRESSION)
+ else if (!ssl_allow_compression(s))
{
al=SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_COMPRESSION_DISABLED);
goto f_err;
}
ERR_clear_error(); /* but we keep s->verify_result */
+ if (i > 1)
+ {
+ SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, i);
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ goto f_err;
+ }
sc=ssl_sess_cert_new();
if (sc == NULL) goto err;
p+=i;
n-=param_len;
+ if (!srp_verify_server_param(s, &al))
+ {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_BAD_SRP_PARAMETERS);
+ goto f_err;
+ }
+
/* We must check if there is a certificate */
#ifndef OPENSSL_NO_RSA
if (alg_a & SSL_aRSA)
p+=i;
n-=param_len;
+ if (!ssl_security(s, SSL_SECOP_TMP_DH,
+ DH_security_bits(dh), 0, dh))
+ {
+ al=SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,SSL_R_DH_KEY_TOO_SMALL);
+ goto f_err;
+ }
+
#ifndef OPENSSL_NO_RSA
if (alg_a & SSL_aRSA)
pkey=X509_get_pubkey(s->session->sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509);
RSA *rsa;
unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
+ if (s->session->sess_cert == NULL)
+ {
+ /* We should always have a server certificate with SSL_kRSA. */
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
if (s->session->sess_cert->peer_rsa_tmp != NULL)
rsa=s->session->sess_cert->peer_rsa_tmp;
else
int ecdh_clnt_cert = 0;
int field_size = 0;
+ if (s->session->sess_cert == NULL)
+ {
+ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
+ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
+ goto err;
+ }
+
/* Did we send out the client's
* ECDH share for use in premaster
* computation as part of client certificate?
int ok;
long n;
- /* Read the message to see if it is supplemental data,
- * regardless if there is a session ticket this function is
- * called when we really expect a Certificate message, so
- * permit appropriate message length */
+ /* If we have no ticket it cannot be a resumed session. */
+ if (!s->session->tlsext_tick)
+ return 1;
+ /* 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_CR_CERT_A,
SSL3_ST_CR_CERT_B,
if (!ok) return((int)n);
s->s3->tmp.reuse_message = 1;
- if (s->s3->tmp.message_type == SSL3_MT_SUPPLEMENTAL_DATA)
- return 3;
- /* If we have no ticket it cannot be a resumed session. */
- if (!s->session->tlsext_tick)
- return 1;
if ((s->s3->tmp.message_type == SSL3_MT_FINISHED)
|| (s->s3->tmp.message_type == SSL3_MT_NEWSESSION_TICKET))
return 2;
i = s->ctx->client_cert_cb(s,px509,ppkey);
return i;
}
-
-#ifndef OPENSSL_NO_TLSEXT
-int tls1_send_client_supplemental_data(SSL *s, int *skip)
- {
- int al = 0;
- if (s->ctx->cli_supp_data_records_count)
- {
- unsigned char *p = NULL;
- unsigned char *size_loc = NULL;
- cli_supp_data_record *record = NULL;
- size_t length = 0;
- size_t i = 0;
-
- for (i = 0; i < s->ctx->cli_supp_data_records_count; i++)
- {
- const unsigned char *out = NULL;
- unsigned short outlen = 0;
- int cb_retval = 0;
- record = &s->ctx->cli_supp_data_records[i];
-
- /* NULL callback or -1 omits supp data entry*/
- if (!record->fn2)
- continue;
- cb_retval = record->fn2(s, record->supp_data_type,
- &out, &outlen, &al,
- record->arg);
- if (cb_retval == -1)
- continue; /* skip this supp data entry */
- if (cb_retval == 0)
- {
- SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
- goto f_err;
- }
- if (outlen == 0 || TLSEXT_MAXLEN_supplemental_data < outlen + 4 + length)
- {
- SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
- return 0;
- }
- /* if first entry, write handshake message type */
- if (length == 0)
- {
- if (!BUF_MEM_grow_clean(s->init_buf, 4))
- {
- SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
- return 0;
- }
- p = (unsigned char *)s->init_buf->data;
- *(p++) = SSL3_MT_SUPPLEMENTAL_DATA;
- /* update message length when all
- * callbacks complete */
- size_loc = p;
- /* skip over handshake length field (3
- * bytes) and supp_data length field
- * (3 bytes) */
- p += 3 + 3;
- length += 1 +3 +3;
- }
- if (!BUF_MEM_grow(s->init_buf, outlen + 4))
- {
- SSLerr(SSL_F_TLS1_SEND_CLIENT_SUPPLEMENTAL_DATA,ERR_R_BUF_LIB);
- return 0;
- }
- s2n(record->supp_data_type, p);
- s2n(outlen, p);
- memcpy(p, out, outlen);
- length += (outlen + 4);
- p += outlen;
- }
- if (length > 0)
- {
- /* write handshake length */
- l2n3(length - 4, size_loc);
- /* supp_data length */
- l2n3(length - 7, size_loc);
- s->state = SSL3_ST_CW_SUPPLEMENTAL_DATA_B;
- s->init_num = length;
- s->init_off = 0;
- return ssl3_do_write(s, SSL3_RT_HANDSHAKE);
- }
- }
-
- /* no supp data message sent */
- *skip = 1;
- s->init_num = 0;
- s->init_off = 0;
- return 1;
-
- f_err:
- ssl3_send_alert(s,SSL3_AL_FATAL,al);
- return 0;
- }
-
-int tls1_get_server_supplemental_data(SSL *s)
- {
- int al = 0;
- int ok;
- long n;
- const unsigned char *p, *d;
- unsigned short supp_data_entry_type = 0;
- unsigned short supp_data_entry_len = 0;
- unsigned long supp_data_len = 0;
- size_t i;
- int cb_retval = 0;
-
- n=s->method->ssl_get_message(s,
- SSL3_ST_CR_SUPPLEMENTAL_DATA_A,
- SSL3_ST_CR_SUPPLEMENTAL_DATA_B,
- SSL3_MT_SUPPLEMENTAL_DATA,
- /* use default limit */
- TLSEXT_MAXLEN_supplemental_data,
- &ok);
-
- if (!ok) return((int)n);
-
- p = (unsigned char *)s->init_msg;
- d = p;
- /* The message cannot be empty */
- if (n < 3)
- {
- al = SSL_AD_DECODE_ERROR;
- SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA,SSL_R_LENGTH_MISMATCH);
- goto f_err;
- }
- n2l3(p, supp_data_len);
- while (p < d+supp_data_len)
- {
- n2s(p, supp_data_entry_type);
- n2s(p, supp_data_entry_len);
- /* if there is a callback for this supp data type, send it */
- for (i=0; i < s->ctx->cli_supp_data_records_count; i++)
- {
- if (s->ctx->cli_supp_data_records[i].supp_data_type == supp_data_entry_type &&
- s->ctx->cli_supp_data_records[i].fn1)
- {
- cb_retval = s->ctx->cli_supp_data_records[i].fn1(s, supp_data_entry_type, p,
- supp_data_entry_len, &al,
- s->ctx->cli_supp_data_records[i].arg);
- if (cb_retval == 0)
- {
- SSLerr(SSL_F_TLS1_GET_SERVER_SUPPLEMENTAL_DATA, ERR_R_SSL_LIB);
- goto f_err;
- }
- }
- }
- p += supp_data_entry_len;
- }
- return 1;
-f_err:
- ssl3_send_alert(s,SSL3_AL_FATAL,al);
- return -1;
- }
-#endif