[openssl-commits] [openssl] master update
Matt Caswell
matt at openssl.org
Mon Jul 18 22:07:28 UTC 2016
The branch master has been updated
via 05ec6a25f80ac8edfb7d7cb764d2dd68156a6965 (commit)
via a7a752285a4fdb716fa5e184b84fe1474de6dbcf (commit)
via 840a2bf8eccc5efa77f84e8470b33ac0c64bb020 (commit)
via e00e0b3d84719e80ed5a8fd48c1162537c2fa12c (commit)
via 67ad5aabe6b6d60ac27f6a4b10e7b1ba65113829 (commit)
via a8c1c7040aabdb78f9bec21ba16be8f262de1444 (commit)
via 13c0ec4ad441cee62c5671caa9fe1168cb7f951b (commit)
via 0bce0b02d8a24890e5ceee54c95504e66eb19856 (commit)
via d4450e4bb95de561de54c6319596bf5637062337 (commit)
from c76a4aead2660f417608eead5cdff81f04021220 (commit)
- Log -----------------------------------------------------------------
commit 05ec6a25f80ac8edfb7d7cb764d2dd68156a6965
Author: Matt Caswell <matt at openssl.org>
Date: Fri Jul 8 12:27:30 2016 +0100
Fix up error codes after splitting up tls_construct_key_exchange()
Reviewed-by: Richard Levitte <levitte at openssl.org>
commit a7a752285a4fdb716fa5e184b84fe1474de6dbcf
Author: Matt Caswell <matt at openssl.org>
Date: Fri Jul 8 11:09:02 2016 +0100
Some tidy ups after the CKE construction refactor
Reviewed-by: Richard Levitte <levitte at openssl.org>
commit 840a2bf8eccc5efa77f84e8470b33ac0c64bb020
Author: Matt Caswell <matt at openssl.org>
Date: Fri Jul 8 10:43:59 2016 +0100
Split out SRP CKE construction into a separate function
Continuing previous commit to break up the
tls_construct_client_key_exchange() function. This splits out the SRP
code.
Reviewed-by: Richard Levitte <levitte at openssl.org>
commit e00e0b3d84719e80ed5a8fd48c1162537c2fa12c
Author: Matt Caswell <matt at openssl.org>
Date: Fri Jul 8 10:07:55 2016 +0100
Split out GOST CKE construction into a separate function
Continuing previous commit to break up the
tls_construct_client_key_exchange() function. This splits out the GOST
code.
Reviewed-by: Richard Levitte <levitte at openssl.org>
commit 67ad5aabe6b6d60ac27f6a4b10e7b1ba65113829
Author: Matt Caswell <matt at openssl.org>
Date: Fri Jul 8 09:51:02 2016 +0100
Split out DHE CKE construction into a separate function
Continuing previous commit to break up the
tls_construct_client_key_exchange() function. This splits out the ECDHE
code.
Reviewed-by: Richard Levitte <levitte at openssl.org>
commit a8c1c7040aabdb78f9bec21ba16be8f262de1444
Author: Matt Caswell <matt at openssl.org>
Date: Fri Jul 8 09:42:07 2016 +0100
Split out DHE CKE construction into a separate function
Continuing previous commit to break up the
tls_construct_client_key_exchange() function. This splits out the DHE
code.
Reviewed-by: Richard Levitte <levitte at openssl.org>
commit 13c0ec4ad441cee62c5671caa9fe1168cb7f951b
Author: Matt Caswell <matt at openssl.org>
Date: Thu Jul 7 14:42:27 2016 +0100
Split out CKE construction PSK pre-amble and RSA into a separate function
The tls_construct_client_key_exchange() function is too long. This splits
out the construction of the PSK pre-amble into a separate function as well
as the RSA construction.
Reviewed-by: Richard Levitte <levitte at openssl.org>
commit 0bce0b02d8a24890e5ceee54c95504e66eb19856
Author: Matt Caswell <matt at openssl.org>
Date: Thu Jul 7 12:47:07 2016 +0100
Narrow the scope of local variables in tls_construct_client_key_exchange()
This is in preparation for splitting up this over long function.
Reviewed-by: Richard Levitte <levitte at openssl.org>
commit d4450e4bb95de561de54c6319596bf5637062337
Author: Matt Caswell <matt at openssl.org>
Date: Thu Jul 7 15:51:17 2016 +0100
Fix bug with s2n et al macros
The parameters should have parens around them when used.
Reviewed-by: Richard Levitte <levitte at openssl.org>
-----------------------------------------------------------------------
Summary of changes:
include/openssl/ssl.h | 6 +
ssl/ssl_err.c | 7 +
ssl/ssl_locl.h | 24 +-
ssl/statem/statem_clnt.c | 767 +++++++++++++++++++++++++----------------------
4 files changed, 437 insertions(+), 367 deletions(-)
diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h
index 1e50e7e..8dcd525 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -2203,6 +2203,12 @@ void ERR_load_SSL_strings(void);
# define SSL_F_TLS1_SET_SERVER_SIGALGS 335
# define SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK 354
# define SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST 372
+# define SSL_F_TLS_CONSTRUCT_CKE_DHE 404
+# define SSL_F_TLS_CONSTRUCT_CKE_ECDHE 405
+# define SSL_F_TLS_CONSTRUCT_CKE_GOST 406
+# define SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE 407
+# define SSL_F_TLS_CONSTRUCT_CKE_RSA 409
+# define SSL_F_TLS_CONSTRUCT_CKE_SRP 410
# define SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE 355
# define SSL_F_TLS_CONSTRUCT_CLIENT_HELLO 356
# define SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE 357
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c
index b69e91c..5192168 100644
--- a/ssl/ssl_err.c
+++ b/ssl/ssl_err.c
@@ -231,6 +231,13 @@ static ERR_STRING_DATA SSL_str_functs[] = {
"tls_client_key_exchange_post_work"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST),
"tls_construct_certificate_request"},
+ {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_DHE), "tls_construct_cke_dhe"},
+ {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_ECDHE), "tls_construct_cke_ecdhe"},
+ {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_GOST), "tls_construct_cke_gost"},
+ {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE),
+ "tls_construct_cke_psk_preamble"},
+ {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_RSA), "tls_construct_cke_rsa"},
+ {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CKE_SRP), "tls_construct_cke_srp"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_CERTIFICATE),
"tls_construct_client_certificate"},
{ERR_FUNC(SSL_F_TLS_CONSTRUCT_CLIENT_HELLO),
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 8287077..1cc63aa 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -141,18 +141,18 @@
} \
}
-# define n2s(c,s) ((s=(((unsigned int)(c[0]))<< 8)| \
- (((unsigned int)(c[1])) )),c+=2)
-# define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), \
- c[1]=(unsigned char)(((s) )&0xff)),c+=2)
-
-# define n2l3(c,l) ((l =(((unsigned long)(c[0]))<<16)| \
- (((unsigned long)(c[1]))<< 8)| \
- (((unsigned long)(c[2])) )),c+=3)
-
-# define l2n3(l,c) ((c[0]=(unsigned char)(((l)>>16)&0xff), \
- c[1]=(unsigned char)(((l)>> 8)&0xff), \
- c[2]=(unsigned char)(((l) )&0xff)),c+=3)
+# define n2s(c,s) ((s=(((unsigned int)((c)[0]))<< 8)| \
+ (((unsigned int)((c)[1])) )),(c)+=2)
+# define s2n(s,c) (((c)[0]=(unsigned char)(((s)>> 8)&0xff), \
+ (c)[1]=(unsigned char)(((s) )&0xff)),(c)+=2)
+
+# define n2l3(c,l) ((l =(((unsigned long)((c)[0]))<<16)| \
+ (((unsigned long)((c)[1]))<< 8)| \
+ (((unsigned long)((c)[2])) )),(c)+=3)
+
+# define l2n3(l,c) (((c)[0]=(unsigned char)(((l)>>16)&0xff), \
+ (c)[1]=(unsigned char)(((l)>> 8)&0xff), \
+ (c)[2]=(unsigned char)(((l) )&0xff)),(c)+=3)
#define DTLS_VERSION_GT(v1, v2) ((v1) < (v2))
#define DTLS_VERSION_GE(v1, v2) ((v1) <= (v2))
diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c
index bcbb0fd..60aecdb 100644
--- a/ssl/statem/statem_clnt.c
+++ b/ssl/statem/statem_clnt.c
@@ -2012,426 +2012,483 @@ MSG_PROCESS_RETURN tls_process_server_done(SSL *s, PACKET *pkt)
return MSG_PROCESS_FINISHED_READING;
}
-int tls_construct_client_key_exchange(SSL *s)
+static int tls_construct_cke_psk_preamble(SSL *s, unsigned char **p,
+ size_t *pskhdrlen, int *al)
{
- unsigned char *p;
- int n;
#ifndef OPENSSL_NO_PSK
- size_t pskhdrlen = 0;
+ int ret = 0;
+ /*
+ * The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes to return a
+ * \0-terminated identity. The last byte is for us for simulating
+ * strnlen.
+ */
+ char identity[PSK_MAX_IDENTITY_LEN + 1];
+ size_t identitylen = 0;
+ unsigned char psk[PSK_MAX_PSK_LEN];
+ unsigned char *tmppsk = NULL;
+ char *tmpidentity = NULL;
+ size_t psklen = 0;
+
+ if (s->psk_client_callback == NULL) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, SSL_R_PSK_NO_CLIENT_CB);
+ *al = SSL_AD_INTERNAL_ERROR;
+ goto err;
+ }
+
+ memset(identity, 0, sizeof(identity));
+
+ psklen = s->psk_client_callback(s, s->session->psk_identity_hint,
+ identity, sizeof(identity) - 1,
+ psk, sizeof(psk));
+
+ if (psklen > PSK_MAX_PSK_LEN) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
+ *al = SSL_AD_HANDSHAKE_FAILURE;
+ goto err;
+ } else if (psklen == 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE,
+ SSL_R_PSK_IDENTITY_NOT_FOUND);
+ *al = SSL_AD_HANDSHAKE_FAILURE;
+ goto err;
+ }
+
+ identitylen = strlen(identity);
+ if (identitylen > PSK_MAX_IDENTITY_LEN) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
+ *al = SSL_AD_HANDSHAKE_FAILURE;
+ goto err;
+ }
+
+ tmppsk = OPENSSL_memdup(psk, psklen);
+ tmpidentity = OPENSSL_strdup(identity);
+ if (tmppsk == NULL || tmpidentity == NULL) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_MALLOC_FAILURE);
+ *al = SSL_AD_INTERNAL_ERROR;
+ goto err;
+ }
+
+ OPENSSL_free(s->s3->tmp.psk);
+ s->s3->tmp.psk = tmppsk;
+ s->s3->tmp.psklen = psklen;
+ tmppsk = NULL;
+ OPENSSL_free(s->session->psk_identity);
+ s->session->psk_identity = tmpidentity;
+ tmpidentity = NULL;
+ s2n(identitylen, *p);
+ memcpy(*p, identity, identitylen);
+ *pskhdrlen = 2 + identitylen;
+ *p += identitylen;
+
+ ret = 1;
+
+ err:
+ OPENSSL_cleanse(psk, psklen);
+ OPENSSL_cleanse(identity, sizeof(identity));
+ OPENSSL_clear_free(tmppsk, psklen);
+ OPENSSL_clear_free(tmpidentity, identitylen);
+
+ return ret;
+#else
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
#endif
- unsigned long alg_k;
+}
+
+static int tls_construct_cke_rsa(SSL *s, unsigned char **p, int *len, int *al)
+{
#ifndef OPENSSL_NO_RSA
unsigned char *q;
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *pctx = NULL;
-#endif
-#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
- EVP_PKEY *ckey = NULL, *skey = NULL;
-#endif
-#ifndef OPENSSL_NO_EC
- unsigned char *encodedPoint = NULL;
- int encoded_pt_len = 0;
-#endif
+ size_t enclen;
unsigned char *pms = NULL;
size_t pmslen = 0;
- alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- p = ssl_handshake_start(s);
-
-
-#ifndef OPENSSL_NO_PSK
- if (alg_k & SSL_PSK) {
- int psk_err = 1;
+ if (s->session->peer == NULL) {
/*
- * The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes to return a
- * \0-terminated identity. The last byte is for us for simulating
- * strnlen.
+ * We should always have a server certificate with SSL_kRSA.
*/
- char identity[PSK_MAX_IDENTITY_LEN + 1];
- size_t identitylen;
- unsigned char psk[PSK_MAX_PSK_LEN];
- size_t psklen;
-
- if (s->psk_client_callback == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- SSL_R_PSK_NO_CLIENT_CB);
- goto err;
- }
-
- memset(identity, 0, sizeof(identity));
-
- psklen = s->psk_client_callback(s, s->session->psk_identity_hint,
- identity, sizeof(identity) - 1,
- psk, sizeof(psk));
-
- if (psklen > PSK_MAX_PSK_LEN) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto psk_err;
- } else if (psklen == 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- SSL_R_PSK_IDENTITY_NOT_FOUND);
- goto psk_err;
- }
- OPENSSL_free(s->s3->tmp.psk);
- s->s3->tmp.psk = OPENSSL_memdup(psk, psklen);
- OPENSSL_cleanse(psk, psklen);
-
- if (s->s3->tmp.psk == NULL) {
- OPENSSL_cleanse(identity, sizeof(identity));
- goto memerr;
- }
-
- s->s3->tmp.psklen = psklen;
- identitylen = strlen(identity);
- if (identitylen > PSK_MAX_IDENTITY_LEN) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto psk_err;
- }
- OPENSSL_free(s->session->psk_identity);
- s->session->psk_identity = OPENSSL_strdup(identity);
- if (s->session->psk_identity == NULL) {
- OPENSSL_cleanse(identity, sizeof(identity));
- goto memerr;
- }
-
- s2n(identitylen, p);
- memcpy(p, identity, identitylen);
- pskhdrlen = 2 + identitylen;
- p += identitylen;
- psk_err = 0;
-psk_err:
- OPENSSL_cleanse(identity, sizeof(identity));
- if (psk_err != 0) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
- goto err;
- }
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_RSA, ERR_R_INTERNAL_ERROR);
+ return 0;
}
- if (alg_k & SSL_kPSK) {
- n = 0;
- } else
-#endif
- /* Fool emacs indentation */
- if (0) {
+ pkey = X509_get0_pubkey(s->session->peer);
+ if (EVP_PKEY_get0_RSA(pkey) == NULL) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_RSA, ERR_R_INTERNAL_ERROR);
+ return 0;
}
-#ifndef OPENSSL_NO_RSA
- else if (alg_k & (SSL_kRSA | SSL_kRSAPSK)) {
- size_t enclen;
- pmslen = SSL_MAX_MASTER_KEY_LENGTH;
- pms = OPENSSL_malloc(pmslen);
- if (pms == NULL)
- goto memerr;
-
- if (s->session->peer == NULL) {
- /*
- * We should always have a server certificate with SSL_kRSA.
- */
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
- pkey = X509_get0_pubkey(s->session->peer);
- if (EVP_PKEY_get0_RSA(pkey) == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
+ pmslen = SSL_MAX_MASTER_KEY_LENGTH;
+ pms = OPENSSL_malloc(pmslen);
+ if (pms == NULL) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_RSA, ERR_R_MALLOC_FAILURE);
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
- pms[0] = s->client_version >> 8;
- pms[1] = s->client_version & 0xff;
- if (RAND_bytes(pms + 2, pmslen - 2) <= 0)
- goto err;
+ pms[0] = s->client_version >> 8;
+ pms[1] = s->client_version & 0xff;
+ if (RAND_bytes(pms + 2, pmslen - 2) <= 0) {
+ goto err;
+ }
- q = p;
- /* Fix buf for TLS and beyond */
- if (s->version > SSL3_VERSION)
- p += 2;
- pctx = EVP_PKEY_CTX_new(pkey, NULL);
- if (pctx == NULL || EVP_PKEY_encrypt_init(pctx) <= 0
- || EVP_PKEY_encrypt(pctx, NULL, &enclen, pms, pmslen) <= 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_EVP_LIB);
- goto err;
- }
- if (EVP_PKEY_encrypt(pctx, p, &enclen, pms, pmslen) <= 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- SSL_R_BAD_RSA_ENCRYPT);
- goto err;
- }
- n = enclen;
- EVP_PKEY_CTX_free(pctx);
- pctx = NULL;
+ q = *p;
+ /* Fix buf for TLS and beyond */
+ if (s->version > SSL3_VERSION)
+ *p += 2;
+ pctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (pctx == NULL || EVP_PKEY_encrypt_init(pctx) <= 0
+ || EVP_PKEY_encrypt(pctx, NULL, &enclen, pms, pmslen) <= 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_RSA, ERR_R_EVP_LIB);
+ goto err;
+ }
+ if (EVP_PKEY_encrypt(pctx, *p, &enclen, pms, pmslen) <= 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_RSA, SSL_R_BAD_RSA_ENCRYPT);
+ goto err;
+ }
+ *len = enclen;
+ EVP_PKEY_CTX_free(pctx);
+ pctx = NULL;
# ifdef PKCS1_CHECK
- if (s->options & SSL_OP_PKCS1_CHECK_1)
- p[1]++;
- if (s->options & SSL_OP_PKCS1_CHECK_2)
- tmp_buf[0] = 0x70;
+ if (s->options & SSL_OP_PKCS1_CHECK_1)
+ (*p)[1]++;
+ if (s->options & SSL_OP_PKCS1_CHECK_2)
+ tmp_buf[0] = 0x70;
# endif
- /* Fix buf for TLS and beyond */
- if (s->version > SSL3_VERSION) {
- s2n(n, q);
- n += 2;
- }
+ /* Fix buf for TLS and beyond */
+ if (s->version > SSL3_VERSION) {
+ s2n(*len, q);
+ *len += 2;
}
+
+ s->s3->tmp.pms = pms;
+ s->s3->tmp.pmslen = pmslen;
+
+ return 1;
+ err:
+ OPENSSL_clear_free(pms, pmslen);
+ EVP_PKEY_CTX_free(pctx);
+
+ return 0;
+#else
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_RSA, ERR_R_INTERNAL_ERROR);
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
#endif
-#ifndef OPENSSL_NO_DH
- else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
- DH *dh_clnt = NULL;
- const BIGNUM *pub_key;
- skey = s->s3->peer_tmp;
- if (skey == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
- ckey = ssl_generate_pkey(skey, NID_undef);
- dh_clnt = EVP_PKEY_get0_DH(ckey);
+}
- if (dh_clnt == NULL || ssl_derive(s, ckey, skey) == 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
+static int tls_construct_cke_dhe(SSL *s, unsigned char **p, int *len, int *al)
+{
+#ifndef OPENSSL_NO_DH
+ DH *dh_clnt = NULL;
+ const BIGNUM *pub_key;
+ EVP_PKEY *ckey = NULL, *skey = NULL;
+ skey = s->s3->peer_tmp;
+ if (skey == NULL) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_DHE, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+ ckey = ssl_generate_pkey(skey, NID_undef);
+ dh_clnt = EVP_PKEY_get0_DH(ckey);
- /* send off the data */
- DH_get0_key(dh_clnt, &pub_key, NULL);
- n = BN_num_bytes(pub_key);
- s2n(n, p);
- BN_bn2bin(pub_key, p);
- n += 2;
+ if (dh_clnt == NULL || ssl_derive(s, ckey, skey) == 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_DHE, ERR_R_INTERNAL_ERROR);
EVP_PKEY_free(ckey);
- ckey = NULL;
+ return 0;
}
+
+ /* send off the data */
+ DH_get0_key(dh_clnt, &pub_key, NULL);
+ *len = BN_num_bytes(pub_key);
+ s2n(*len, *p);
+ BN_bn2bin(pub_key, *p);
+ *len += 2;
+ EVP_PKEY_free(ckey);
+
+ return 1;
+#else
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_DHE, ERR_R_INTERNAL_ERROR);
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
#endif
+}
+static int tls_construct_cke_ecdhe(SSL *s, unsigned char **p, int *len, int *al)
+{
#ifndef OPENSSL_NO_EC
- else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {
+ unsigned char *encodedPoint = NULL;
+ int encoded_pt_len = 0;
+ EVP_PKEY *ckey = NULL, *skey = NULL;
- skey = s->s3->peer_tmp;
- if ((skey == NULL) || EVP_PKEY_get0_EC_KEY(skey) == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
+ skey = s->s3->peer_tmp;
+ if ((skey == NULL) || EVP_PKEY_get0_EC_KEY(skey) == NULL) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_ECDHE, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
- ckey = ssl_generate_pkey(skey, NID_undef);
+ ckey = ssl_generate_pkey(skey, NID_undef);
- if (ssl_derive(s, ckey, skey) == 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_EVP_LIB);
- goto err;
- }
+ if (ssl_derive(s, ckey, skey) == 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_ECDHE, ERR_R_EVP_LIB);
+ goto err;
+ }
- /* Generate encoding of client key */
- encoded_pt_len = EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(ckey),
- POINT_CONVERSION_UNCOMPRESSED,
- &encodedPoint, NULL);
+ /* Generate encoding of client key */
+ encoded_pt_len = EC_KEY_key2buf(EVP_PKEY_get0_EC_KEY(ckey),
+ POINT_CONVERSION_UNCOMPRESSED,
+ &encodedPoint, NULL);
- if (encoded_pt_len == 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
- goto err;
- }
+ if (encoded_pt_len == 0) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_ECDHE, ERR_R_EC_LIB);
+ goto err;
+ }
- EVP_PKEY_free(ckey);
- ckey = NULL;
+ EVP_PKEY_free(ckey);
+ ckey = NULL;
- n = encoded_pt_len;
+ *len = encoded_pt_len;
- *p = n; /* length of encoded point */
- /* Encoded point will be copied here */
- p += 1;
- /* copy the point */
- memcpy(p, encodedPoint, n);
- /* increment n to account for length field */
- n += 1;
+ /* length of encoded point */
+ **p = *len;
+ *p += 1;
+ /* copy the point */
+ memcpy(*p, encodedPoint, *len);
+ /* increment len to account for length field */
+ *len += 1;
- /* Free allocated memory */
- OPENSSL_free(encodedPoint);
- }
-#endif /* !OPENSSL_NO_EC */
+ OPENSSL_free(encodedPoint);
+
+ return 1;
+ err:
+ EVP_PKEY_free(ckey);
+ return 0;
+#else
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_ECDHE, ERR_R_INTERNAL_ERROR);
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+#endif
+}
+
+static int tls_construct_cke_gost(SSL *s, unsigned char **p, int *len, int *al)
+{
#ifndef OPENSSL_NO_GOST
- else if (alg_k & SSL_kGOST) {
- /* GOST key exchange message creation */
- EVP_PKEY_CTX *pkey_ctx;
- X509 *peer_cert;
- size_t msglen;
- unsigned int md_len;
- unsigned char shared_ukm[32], tmp[256];
- EVP_MD_CTX *ukm_hash;
- int dgst_nid = NID_id_GostR3411_94;
- if ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aGOST12) != 0)
- dgst_nid = NID_id_GostR3411_2012_256;
-
-
- pmslen = 32;
- pms = OPENSSL_malloc(pmslen);
- if (pms == NULL)
- goto memerr;
+ /* GOST key exchange message creation */
+ EVP_PKEY_CTX *pkey_ctx = NULL;
+ X509 *peer_cert;
+ size_t msglen;
+ unsigned int md_len;
+ unsigned char shared_ukm[32], tmp[256];
+ EVP_MD_CTX *ukm_hash = NULL;
+ int dgst_nid = NID_id_GostR3411_94;
+ unsigned char *pms = NULL;
+ size_t pmslen = 0;
- /*
- * Get server sertificate PKEY and create ctx from it
- */
- peer_cert = s->session->peer;
- if (!peer_cert) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER);
- goto err;
- }
+ if ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aGOST12) != 0)
+ dgst_nid = NID_id_GostR3411_2012_256;
- pkey_ctx = EVP_PKEY_CTX_new(X509_get0_pubkey(peer_cert), NULL);
- if (pkey_ctx == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_MALLOC_FAILURE);
- goto err;
- }
- /*
- * If we have send a certificate, and certificate key
- * parameters match those of server certificate, use
- * certificate key for key exchange
- */
+ /*
+ * Get server sertificate PKEY and create ctx from it
+ */
+ peer_cert = s->session->peer;
+ if (!peer_cert) {
+ *al = SSL_AD_HANDSHAKE_FAILURE;
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST,
+ SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER);
+ return 0;
+ }
- /* Otherwise, generate ephemeral key pair */
+ pkey_ctx = EVP_PKEY_CTX_new(X509_get0_pubkey(peer_cert), NULL);
+ if (pkey_ctx == NULL) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ /*
+ * If we have send a certificate, and certificate key
+ * parameters match those of server certificate, use
+ * certificate key for key exchange
+ */
- if (pkey_ctx == NULL
- || EVP_PKEY_encrypt_init(pkey_ctx) <= 0
- /* Generate session key */
- || RAND_bytes(pms, pmslen) <= 0) {
- EVP_PKEY_CTX_free(pkey_ctx);
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto err;
- };
- /*
- * If we have client certificate, use its secret as peer key
- */
- if (s->s3->tmp.cert_req && s->cert->key->privatekey) {
- if (EVP_PKEY_derive_set_peer
- (pkey_ctx, s->cert->key->privatekey) <= 0) {
- /*
- * If there was an error - just ignore it. Ephemeral key
- * * would be used
- */
- ERR_clear_error();
- }
- }
- /*
- * Compute shared IV and store it in algorithm-specific context
- * data
- */
- ukm_hash = EVP_MD_CTX_new();
- if (EVP_DigestInit(ukm_hash,
- EVP_get_digestbynid(dgst_nid)) <= 0
- || EVP_DigestUpdate(ukm_hash, s->s3->client_random,
- SSL3_RANDOM_SIZE) <= 0
- || EVP_DigestUpdate(ukm_hash, s->s3->server_random,
- SSL3_RANDOM_SIZE) <= 0
- || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) {
- EVP_MD_CTX_free(ukm_hash);
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
- EVP_MD_CTX_free(ukm_hash);
- if (EVP_PKEY_CTX_ctrl
- (pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8,
- shared_ukm) < 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- SSL_R_LIBRARY_BUG);
- goto err;
- }
- /* Make GOST keytransport blob message */
- /*
- * Encapsulate it into sequence
- */
- *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
- msglen = 255;
- if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, pms, pmslen) <= 0) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- SSL_R_LIBRARY_BUG);
- goto err;
- }
- if (msglen >= 0x80) {
- *(p++) = 0x81;
- *(p++) = msglen & 0xff;
- n = msglen + 3;
- } else {
- *(p++) = msglen & 0xff;
- n = msglen + 2;
- }
- memcpy(p, tmp, msglen);
- /* Check if pubkey from client certificate was used */
- if (EVP_PKEY_CTX_ctrl
- (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) {
- /* Set flag "skip certificate verify" */
- s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY;
+ /* Otherwise, generate ephemeral key pair */
+ pmslen = 32;
+ pms = OPENSSL_malloc(pmslen);
+ if (pms == NULL) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ if (EVP_PKEY_encrypt_init(pkey_ctx) <= 0
+ /* Generate session key */
+ || RAND_bytes(pms, pmslen) <= 0) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, ERR_R_INTERNAL_ERROR);
+ goto err;
+ };
+ /*
+ * If we have client certificate, use its secret as peer key
+ */
+ if (s->s3->tmp.cert_req && s->cert->key->privatekey) {
+ if (EVP_PKEY_derive_set_peer
+ (pkey_ctx, s->cert->key->privatekey) <= 0) {
+ /*
+ * If there was an error - just ignore it. Ephemeral key
+ * * would be used
+ */
+ ERR_clear_error();
}
- EVP_PKEY_CTX_free(pkey_ctx);
+ }
+ /*
+ * Compute shared IV and store it in algorithm-specific context
+ * data
+ */
+ ukm_hash = EVP_MD_CTX_new();
+ if (ukm_hash == NULL
+ || EVP_DigestInit(ukm_hash, EVP_get_digestbynid(dgst_nid)) <= 0
+ || EVP_DigestUpdate(ukm_hash, s->s3->client_random,
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestUpdate(ukm_hash, s->s3->server_random,
+ SSL3_RANDOM_SIZE) <= 0
+ || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ EVP_MD_CTX_free(ukm_hash);
+ ukm_hash = NULL;
+ if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT,
+ EVP_PKEY_CTRL_SET_IV, 8, shared_ukm) < 0) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, SSL_R_LIBRARY_BUG);
+ goto err;
+ }
+ /* Make GOST keytransport blob message */
+ /*
+ * Encapsulate it into sequence
+ */
+ *((*p)++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED;
+ msglen = 255;
+ if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, pms, pmslen) <= 0) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, SSL_R_LIBRARY_BUG);
+ goto err;
+ }
+ if (msglen >= 0x80) {
+ *((*p)++) = 0x81;
+ *((*p)++) = msglen & 0xff;
+ *len = msglen + 3;
+ } else {
+ *((*p)++) = msglen & 0xff;
+ *len = msglen + 2;
+ }
+ memcpy(*p, tmp, msglen);
+ /* Check if pubkey from client certificate was used */
+ if (EVP_PKEY_CTX_ctrl(pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2,
+ NULL) > 0) {
+ /* Set flag "skip certificate verify" */
+ s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY;
+ }
+ EVP_PKEY_CTX_free(pkey_ctx);
+ s->s3->tmp.pms = pms;
+ s->s3->tmp.pmslen = pmslen;
+
+ return 1;
+ err:
+ EVP_PKEY_CTX_free(pkey_ctx);
+ OPENSSL_clear_free(pms, pmslen);
+ EVP_MD_CTX_free(ukm_hash);
+ return 0;
+#else
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_GOST, ERR_R_INTERNAL_ERROR);
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+#endif
+}
+static int tls_construct_cke_srp(SSL *s, unsigned char **p, int *len, int *al)
+{
+#ifndef OPENSSL_NO_SRT
+ if (s->srp_ctx.A != NULL) {
+ /* send off the data */
+ *len = BN_num_bytes(s->srp_ctx.A);
+ s2n(*len, *p);
+ BN_bn2bin(s->srp_ctx.A, *p);
+ *len += 2;
+ } else {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_SRP, ERR_R_INTERNAL_ERROR);
+ return 0;
}
+ OPENSSL_free(s->session->srp_username);
+ s->session->srp_username = OPENSSL_strdup(s->srp_ctx.login);
+ if (s->session->srp_username == NULL) {
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_SRP, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ return 1;
+#else
+ SSLerr(SSL_F_TLS_CONSTRUCT_CKE_SRP, ERR_R_INTERNAL_ERROR);
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
#endif
-#ifndef OPENSSL_NO_SRP
- else if (alg_k & SSL_kSRP) {
- if (s->srp_ctx.A != NULL) {
- /* send off the data */
- n = BN_num_bytes(s->srp_ctx.A);
- s2n(n, p);
- BN_bn2bin(s->srp_ctx.A, p);
- n += 2;
- } else {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
+}
+
+int tls_construct_client_key_exchange(SSL *s)
+{
+ unsigned char *p;
+ int len;
+ size_t pskhdrlen = 0;
+ unsigned long alg_k;
+ int al = -1;
+
+ alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
+
+ p = ssl_handshake_start(s);
+
+ if ((alg_k & SSL_PSK)
+ && !tls_construct_cke_psk_preamble(s, &p, &pskhdrlen, &al))
+ goto err;
+
+ if (alg_k & SSL_kPSK) {
+ len = 0;
+ } else if (alg_k & (SSL_kRSA | SSL_kRSAPSK)) {
+ if (!tls_construct_cke_rsa(s, &p, &len, &al))
goto err;
- }
- OPENSSL_free(s->session->srp_username);
- s->session->srp_username = OPENSSL_strdup(s->srp_ctx.login);
- if (s->session->srp_username == NULL) {
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE,
- ERR_R_MALLOC_FAILURE);
+ } else if (alg_k & (SSL_kDHE | SSL_kDHEPSK)) {
+ if (!tls_construct_cke_dhe(s, &p, &len, &al))
goto err;
- }
- }
-#endif
- else {
+ } else if (alg_k & (SSL_kECDHE | SSL_kECDHEPSK)) {
+ if (!tls_construct_cke_ecdhe(s, &p, &len, &al))
+ goto err;
+ } else if (alg_k & SSL_kGOST) {
+ if (!tls_construct_cke_gost(s, &p, &len, &al))
+ goto err;
+ } else if (alg_k & SSL_kSRP) {
+ if (!tls_construct_cke_srp(s, &p, &len, &al))
+ goto err;
+ } else {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
goto err;
}
-#ifndef OPENSSL_NO_PSK
- n += pskhdrlen;
-#endif
+ len += pskhdrlen;
- if (!ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, n)) {
+ if (!ssl_set_handshake_header(s, SSL3_MT_CLIENT_KEY_EXCHANGE, len)) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR);
goto err;
}
- if (pms != NULL) {
- s->s3->tmp.pms = pms;
- s->s3->tmp.pmslen = pmslen;
- }
-
return 1;
- memerr:
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- SSLerr(SSL_F_TLS_CONSTRUCT_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
err:
- OPENSSL_clear_free(pms, pmslen);
+ if (al != -1)
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ OPENSSL_clear_free(s->s3->tmp.pms, s->s3->tmp.pmslen);
s->s3->tmp.pms = NULL;
-#ifndef OPENSSL_NO_RSA
- EVP_PKEY_CTX_free(pctx);
-#endif
-#ifndef OPENSSL_NO_EC
- OPENSSL_free(encodedPoint);
-#endif
-#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DH)
- EVP_PKEY_free(ckey);
-#endif
#ifndef OPENSSL_NO_PSK
OPENSSL_clear_free(s->s3->tmp.psk, s->s3->tmp.psklen);
s->s3->tmp.psk = NULL;
More information about the openssl-commits
mailing list