summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2018-06-10 13:50:40 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2018-06-10 13:50:40 +0000
commit75c3dfd7cb9d5c62cb09764e0dcbc745f1548161 (patch)
tree65c6bddf9d64db4999e038a35ad948d3a5c3728f
parentb6e0d0b03279ca885ad6e2759078f12698a0778e (diff)
Now that all of the server-side client key exchange processing functions
have been converted to CBS, pull it up a level. ok inoguchi@ tb@
-rw-r--r--lib/libssl/ssl_srvr.c93
1 files changed, 40 insertions, 53 deletions
diff --git a/lib/libssl/ssl_srvr.c b/lib/libssl/ssl_srvr.c
index 3bd33199894..ff5b020d7a0 100644
--- a/lib/libssl/ssl_srvr.c
+++ b/lib/libssl/ssl_srvr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ssl_srvr.c,v 1.34 2018/06/03 15:33:37 jsing Exp $ */
+/* $OpenBSD: ssl_srvr.c,v 1.35 2018/06/10 13:50:39 jsing Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -1724,22 +1724,18 @@ ssl3_send_certificate_request(SSL *s)
}
static int
-ssl3_get_client_kex_rsa(SSL *s, unsigned char *p, long n)
+ssl3_get_client_kex_rsa(SSL *s, CBS *cbs)
{
unsigned char fakekey[SSL_MAX_MASTER_KEY_LENGTH];
unsigned char *pms = NULL;
+ unsigned char *p;
size_t pms_len = 0;
EVP_PKEY *pkey = NULL;
RSA *rsa = NULL;
- CBS cbs, enc_pms;
+ CBS enc_pms;
int decrypt_len;
int al = -1;
- if (n < 0)
- goto err;
-
- CBS_init(&cbs, p, n);
-
arc4random_buf(fakekey, sizeof(fakekey));
fakekey[0] = s->client_version >> 8;
fakekey[1] = s->client_version & 0xff;
@@ -1760,9 +1756,9 @@ ssl3_get_client_kex_rsa(SSL *s, unsigned char *p, long n)
goto err;
p = pms;
- if (!CBS_get_u16_length_prefixed(&cbs, &enc_pms))
+ if (!CBS_get_u16_length_prefixed(cbs, &enc_pms))
goto truncated;
- if (CBS_len(&cbs) != 0 || CBS_len(&enc_pms) != RSA_size(rsa)) {
+ if (CBS_len(cbs) != 0 || CBS_len(&enc_pms) != RSA_size(rsa)) {
SSLerror(s, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
goto err;
}
@@ -1827,23 +1823,17 @@ ssl3_get_client_kex_rsa(SSL *s, unsigned char *p, long n)
}
static int
-ssl3_get_client_kex_dhe(SSL *s, unsigned char *p, long n)
+ssl3_get_client_kex_dhe(SSL *s, CBS *cbs)
{
int key_size = 0, key_len, al;
unsigned char *key = NULL;
BIGNUM *bn = NULL;
- CBS cbs, dh_Yc;
+ CBS dh_Yc;
DH *dh;
- if (n < 0)
- goto err;
-
- CBS_init(&cbs, p, n);
-
- if (!CBS_get_u16_length_prefixed(&cbs, &dh_Yc))
+ if (!CBS_get_u16_length_prefixed(cbs, &dh_Yc))
goto truncated;
-
- if (CBS_len(&cbs) != 0)
+ if (CBS_len(cbs) != 0)
goto truncated;
if (S3I(s)->tmp.dh == NULL) {
@@ -1895,25 +1885,20 @@ ssl3_get_client_kex_dhe(SSL *s, unsigned char *p, long n)
}
static int
-ssl3_get_client_kex_ecdhe_ecp(SSL *s, unsigned char *p, long n)
+ssl3_get_client_kex_ecdhe_ecp(SSL *s, CBS *cbs)
{
unsigned char *key = NULL;
int key_size = 0, key_len;
EC_POINT *point = NULL;
BN_CTX *bn_ctx = NULL;
const EC_GROUP *group;
- CBS cbs, public;
EC_KEY *ecdh;
+ CBS public;
int ret = -1;
- if (n < 0)
- goto err;
-
- CBS_init(&cbs, p, n);
-
- if (!CBS_get_u8_length_prefixed(&cbs, &public))
+ if (!CBS_get_u8_length_prefixed(cbs, &public))
goto err;
- if (CBS_len(&cbs) != 0)
+ if (CBS_len(cbs) != 0)
goto err;
/*
@@ -1977,17 +1962,15 @@ ssl3_get_client_kex_ecdhe_ecp(SSL *s, unsigned char *p, long n)
}
static int
-ssl3_get_client_kex_ecdhe_ecx(SSL *s, unsigned char *p, long n)
+ssl3_get_client_kex_ecdhe_ecx(SSL *s, CBS *cbs)
{
uint8_t *shared_key = NULL;
- CBS cbs, ecpoint;
+ CBS ecpoint;
int ret = -1;
- if (n < 0)
+ if (!CBS_get_u8_length_prefixed(cbs, &ecpoint))
goto err;
-
- CBS_init(&cbs, p, n);
- if (!CBS_get_u8_length_prefixed(&cbs, &ecpoint))
+ if (CBS_len(cbs) != 0)
goto err;
if (CBS_len(&ecpoint) != X25519_KEY_LENGTH)
goto err;
@@ -2013,31 +1996,26 @@ ssl3_get_client_kex_ecdhe_ecx(SSL *s, unsigned char *p, long n)
}
static int
-ssl3_get_client_kex_ecdhe(SSL *s, unsigned char *p, long n)
+ssl3_get_client_kex_ecdhe(SSL *s, CBS *cbs)
{
if (S3I(s)->tmp.x25519 != NULL)
- return ssl3_get_client_kex_ecdhe_ecx(s, p, n);
+ return ssl3_get_client_kex_ecdhe_ecx(s, cbs);
- return ssl3_get_client_kex_ecdhe_ecp(s, p, n);
+ return ssl3_get_client_kex_ecdhe_ecp(s, cbs);
}
static int
-ssl3_get_client_kex_gost(SSL *s, unsigned char *p, long n)
+ssl3_get_client_kex_gost(SSL *s, CBS *cbs)
{
EVP_PKEY_CTX *pkey_ctx;
EVP_PKEY *client_pub_pkey = NULL, *pk = NULL;
unsigned char premaster_secret[32];
unsigned long alg_a;
size_t outlen = 32;
- CBS cbs, gostblob;
+ CBS gostblob;
int al;
int ret = 0;
- if (n < 0)
- goto err;
-
- CBS_init(&cbs, p, n);
-
/* Get our certificate private key*/
alg_a = S3I(s)->hs.new_cipher->algorithm_auth;
if (alg_a & SSL_aGOST01)
@@ -2062,9 +2040,9 @@ ssl3_get_client_kex_gost(SSL *s, unsigned char *p, long n)
}
/* Decrypt session key */
- if (!CBS_get_asn1(&cbs, &gostblob, CBS_ASN1_SEQUENCE))
+ if (!CBS_get_asn1(cbs, &gostblob, CBS_ASN1_SEQUENCE))
goto truncated;
- if (CBS_len(&cbs) != 0)
+ if (CBS_len(cbs) != 0)
goto truncated;
if (EVP_PKEY_decrypt(pkey_ctx, premaster_secret, &outlen,
CBS_data(&gostblob), CBS_len(&gostblob)) <= 0) {
@@ -2103,8 +2081,8 @@ int
ssl3_get_client_key_exchange(SSL *s)
{
unsigned long alg_k;
- unsigned char *p;
int al, ok;
+ CBS cbs;
long n;
/* 2048 maxlen is a guess. How long a key does that permit? */
@@ -2113,21 +2091,24 @@ ssl3_get_client_key_exchange(SSL *s)
if (!ok)
return ((int)n);
- p = (unsigned char *)s->internal->init_msg;
+ if (n < 0)
+ goto err;
+
+ CBS_init(&cbs, s->internal->init_msg, n);
alg_k = S3I(s)->hs.new_cipher->algorithm_mkey;
if (alg_k & SSL_kRSA) {
- if (ssl3_get_client_kex_rsa(s, p, n) != 1)
+ if (ssl3_get_client_kex_rsa(s, &cbs) != 1)
goto err;
} else if (alg_k & SSL_kDHE) {
- if (ssl3_get_client_kex_dhe(s, p, n) != 1)
+ if (ssl3_get_client_kex_dhe(s, &cbs) != 1)
goto err;
} else if (alg_k & SSL_kECDHE) {
- if (ssl3_get_client_kex_ecdhe(s, p, n) != 1)
+ if (ssl3_get_client_kex_ecdhe(s, &cbs) != 1)
goto err;
} else if (alg_k & SSL_kGOST) {
- if (ssl3_get_client_kex_gost(s, p, n) != 1)
+ if (ssl3_get_client_kex_gost(s, &cbs) != 1)
goto err;
} else {
al = SSL_AD_HANDSHAKE_FAILURE;
@@ -2135,6 +2116,12 @@ ssl3_get_client_key_exchange(SSL *s)
goto f_err;
}
+ if (CBS_len(&cbs) != 0) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
+ goto f_err;
+ }
+
return (1);
f_err: