* if SSL_VERIFY_CLIENT_ONCE is set, don't request cert
* during re-negotiation:
*/
- && ((s->session->peer == NULL) ||
+ && (s->s3->tmp.finish_md_len == 0 ||
!(s->verify_mode & SSL_VERIFY_CLIENT_ONCE))
/*
* never request cert in anonymous ciphersuites (see
return WRITE_TRAN_CONTINUE;
case TLS_ST_SW_CERT:
+ st->hand_state = TLS_ST_SW_CERT_VRFY;
+ return WRITE_TRAN_CONTINUE;
+
+ case TLS_ST_SW_CERT_VRFY:
st->hand_state = TLS_ST_SW_FINISHED;
return WRITE_TRAN_CONTINUE;
*mt = SSL3_MT_CERTIFICATE;
break;
+ case TLS_ST_SW_CERT_VRFY:
+ *confunc = tls_construct_cert_verify;
+ *mt = SSL3_MT_CERTIFICATE_VERIFY;
+ break;
+
+
case TLS_ST_SW_KEY_EXCH:
*confunc = tls_construct_server_key_exchange;
*mt = SSL3_MT_SERVER_KEY_EXCHANGE;
unsigned long type;
const BIGNUM *r[4];
EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
+ EVP_PKEY_CTX *pctx = NULL;
size_t paramlen, paramoffset;
if (!WPACKET_get_total_written(pkt, ¶moffset)) {
*/
if (md) {
unsigned char *sigbytes1, *sigbytes2;
- unsigned int siglen;
+ size_t siglen;
+ int ispss = 0;
/* Get length of the parameters we have written above */
if (!WPACKET_get_length(pkt, ¶mlen)) {
}
/* send signature algorithm */
if (SSL_USE_SIGALGS(s)) {
- if (!tls12_get_sigandhash(pkt, pkey, md)) {
+ if (!tls12_get_sigandhash(s, pkt, pkey, md, &ispss)) {
/* Should never happen */
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
ERR_R_INTERNAL_ERROR);
* up front, and then properly allocate them in the WPACKET
* afterwards.
*/
- if (!WPACKET_sub_reserve_bytes_u16(pkt, EVP_PKEY_size(pkey),
- &sigbytes1)
- || EVP_SignInit_ex(md_ctx, md, NULL) <= 0
- || EVP_SignUpdate(md_ctx, &(s->s3->client_random[0]),
- SSL3_RANDOM_SIZE) <= 0
- || EVP_SignUpdate(md_ctx, &(s->s3->server_random[0]),
- SSL3_RANDOM_SIZE) <= 0
- || EVP_SignUpdate(md_ctx, s->init_buf->data + paramoffset,
- paramlen) <= 0
- || EVP_SignFinal(md_ctx, sigbytes1, &siglen, pkey) <= 0
+ siglen = EVP_PKEY_size(pkey);
+ if (!WPACKET_sub_reserve_bytes_u16(pkt, siglen, &sigbytes1)
+ || EVP_DigestSignInit(md_ctx, &pctx, md, NULL, pkey) <= 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+ if (ispss) {
+ if (EVP_PKEY_CTX_set_rsa_padding(pctx,
+ RSA_PKCS1_PSS_PADDING) <= 0
+ /* -1 here means set saltlen to the digest len */
+ || EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1) <= 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
+ ERR_R_EVP_LIB);
+ goto f_err;
+ }
+ }
+ if (EVP_DigestSignUpdate(md_ctx, &(s->s3->client_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestSignUpdate(md_ctx, &(s->s3->server_random[0]),
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestSignUpdate(md_ctx,
+ s->init_buf->data + paramoffset,
+ paramlen) <= 0
+ || EVP_DigestSignFinal(md_ctx, sigbytes1, &siglen) <= 0
|| !WPACKET_sub_allocate_bytes_u16(pkt, siglen, &sigbytes2)
|| sigbytes1 != sigbytes2) {
SSLerr(SSL_F_TLS_CONSTRUCT_SERVER_KEY_EXCHANGE,
}
if (SSL_USE_SIGALGS(s)) {
- const unsigned char *psigs;
+ const unsigned int *psigs;
size_t nl = tls12_get_psigalgs(s, &psigs);
+
if (!WPACKET_start_sub_packet_u16(pkt)
|| !tls12_copy_sigalgs(s, pkt, psigs, nl)
|| !WPACKET_close(pkt)) {
* certificate, while we do include it in statem_clnt.c
*/
sk = NULL;
+
+ /* Save the current hash state for when we receive the CertificateVerify */
+ if (SSL_IS_TLS13(s)
+ && !ssl_handshake_hash(s, s->cert_verify_hash,
+ sizeof(s->cert_verify_hash),
+ &s->cert_verify_hash_len)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR);
+ goto f_err;
+ }
+
ret = MSG_PROCESS_CONTINUE_READING;
goto done;
return NULL;
}
- if ((skp == NULL) || (*skp == NULL)) {
- sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */
- if (sk == NULL) {
- SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
- *al = SSL_AD_INTERNAL_ERROR;
- return NULL;
- }
- } else {
- sk = *skp;
- sk_SSL_CIPHER_zero(sk);
+ sk = sk_SSL_CIPHER_new_null();
+ if (sk == NULL) {
+ SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE);
+ *al = SSL_AD_INTERNAL_ERROR;
+ return NULL;
}
- if (!PACKET_memdup(cipher_suites, &s->s3->tmp.ciphers_raw,
- &s->s3->tmp.ciphers_rawlen)) {
+ if (sslv2format) {
+ size_t numciphers = PACKET_remaining(cipher_suites) / n;
+ PACKET sslv2ciphers = *cipher_suites;
+ unsigned int leadbyte;
+ unsigned char *raw;
+
+ /*
+ * We store the raw ciphers list in SSLv3+ format so we need to do some
+ * preprocessing to convert the list first. If there are any SSLv2 only
+ * ciphersuites with a non-zero leading byte then we are going to
+ * slightly over allocate because we won't store those. But that isn't a
+ * problem.
+ */
+ raw = s->s3->tmp.ciphers_raw = OPENSSL_malloc(numciphers * n);
+ if (raw == NULL) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ goto err;
+ }
+ for (s->s3->tmp.ciphers_rawlen = 0;
+ PACKET_remaining(&sslv2ciphers) > 0;
+ raw += TLS_CIPHER_LEN) {
+ if (!PACKET_get_1(&sslv2ciphers, &leadbyte)
+ || (leadbyte == 0
+ && !PACKET_copy_bytes(&sslv2ciphers, raw,
+ TLS_CIPHER_LEN))
+ || (leadbyte != 0
+ && !PACKET_forward(&sslv2ciphers, TLS_CIPHER_LEN))) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ OPENSSL_free(raw);
+ s->s3->tmp.ciphers_raw = NULL;
+ s->s3->tmp.ciphers_rawlen = 0;
+ goto err;
+ }
+ if (leadbyte == 0)
+ s->s3->tmp.ciphers_rawlen += TLS_CIPHER_LEN;
+ }
+ } else if (!PACKET_memdup(cipher_suites, &s->s3->tmp.ciphers_raw,
+ &s->s3->tmp.ciphers_rawlen)) {
*al = SSL_AD_INTERNAL_ERROR;
goto err;
}
goto err;
}
- if (skp != NULL)
- *skp = sk;
- return (sk);
+ *skp = sk;
+ return sk;
err:
- if ((skp == NULL) || (*skp == NULL))
- sk_SSL_CIPHER_free(sk);
+ sk_SSL_CIPHER_free(sk);
return NULL;
}