summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authorjsing <>2016-11-05 08:26:37 +0000
committerjsing <>2016-11-05 08:26:37 +0000
commit9fa2112db3b5977fa473ce68fa02199114a3b870 (patch)
treef18e5a0a899b59b54269ba0efb72acd8d5566f6f /src/lib
parent8e601af590fe4daecd1a7d96cddb851fc0118296 (diff)
downloadopenbsd-9fa2112db3b5977fa473ce68fa02199114a3b870.tar.gz
openbsd-9fa2112db3b5977fa473ce68fa02199114a3b870.tar.bz2
openbsd-9fa2112db3b5977fa473ce68fa02199114a3b870.zip
Convert ssl3_get_server_kex_ecdhe() to CBS, simplifying tls1_check_curve()
in the process. This also fixes a long standing bug where tls1_ec_curve_id2nid() is called with only one byte of the curve ID. ok beck@ miod@
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libssl/s3_clnt.c75
-rw-r--r--src/lib/libssl/ssl_locl.h8
-rw-r--r--src/lib/libssl/t1_lib.c20
3 files changed, 41 insertions, 62 deletions
diff --git a/src/lib/libssl/s3_clnt.c b/src/lib/libssl/s3_clnt.c
index dd5121366d..ff015568e4 100644
--- a/src/lib/libssl/s3_clnt.c
+++ b/src/lib/libssl/s3_clnt.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: s3_clnt.c,v 1.143 2016/11/04 19:11:43 jsing Exp $ */ 1/* $OpenBSD: s3_clnt.c,v 1.144 2016/11/05 08:26:36 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -1175,64 +1175,63 @@ ssl3_get_server_kex_dhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn)
1175static int 1175static int
1176ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn) 1176ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn)
1177{ 1177{
1178 CBS cbs, ecpoint;
1179 uint8_t curve_type;
1180 uint16_t curve_id;
1178 EC_POINT *srvr_ecpoint = NULL; 1181 EC_POINT *srvr_ecpoint = NULL;
1179 EC_KEY *ecdh = NULL; 1182 EC_KEY *ecdh = NULL;
1180 BN_CTX *bn_ctx = NULL; 1183 BN_CTX *bn_ctx = NULL;
1181 const EC_GROUP *group; 1184 const EC_GROUP *group;
1182 EC_GROUP *ngroup; 1185 EC_GROUP *ngroup;
1183 SESS_CERT *sc; 1186 SESS_CERT *sc;
1184 unsigned char *p; 1187 int curve_nid;
1185 int al, param_len; 1188 long alg_a;
1186 long alg_a, n; 1189 int al;
1187 int curve_nid = 0;
1188 int encoded_pt_len = 0;
1189 1190
1190 alg_a = s->s3->tmp.new_cipher->algorithm_auth; 1191 alg_a = s->s3->tmp.new_cipher->algorithm_auth;
1191 n = *nn;
1192 p = *pp;
1193 sc = s->session->sess_cert; 1192 sc = s->session->sess_cert;
1194 1193
1195 if ((ecdh = EC_KEY_new()) == NULL) { 1194 if (*nn < 0)
1196 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
1197 goto err; 1195 goto err;
1198 }
1199 1196
1200 /* 1197 CBS_init(&cbs, *pp, *nn);
1201 * Extract elliptic curve parameters and the server's ephemeral ECDH
1202 * public key. Keep accumulating lengths of various components in
1203 * param_len and make sure it never exceeds n.
1204 */
1205 1198
1206 /* 1199 /*
1207 * XXX: For now we only support named (not generic) curves 1200 * Extract EC parameters and the server's ephemeral ECDH public key.
1208 * and the ECParameters in this case is just three bytes.
1209 */ 1201 */
1210 param_len = 3; 1202
1211 if (param_len > n) { 1203 if ((ecdh = EC_KEY_new()) == NULL) {
1204 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
1205 goto err;
1206 }
1207
1208 /* Only named curves are supported. */
1209 if (!CBS_get_u8(&cbs, &curve_type) ||
1210 curve_type != NAMED_CURVE_TYPE ||
1211 !CBS_get_u16(&cbs, &curve_id)) {
1212 al = SSL_AD_DECODE_ERROR; 1212 al = SSL_AD_DECODE_ERROR;
1213 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); 1213 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
1214 goto f_err; 1214 goto f_err;
1215 } 1215 }
1216 1216
1217 /* 1217 /*
1218 * Check curve is one of our preferences, if not server has 1218 * Check that the curve is one of our preferences - if it is not,
1219 * sent an invalid curve. 1219 * the server has sent us an invalid curve.
1220 */ 1220 */
1221 if (tls1_check_curve(s, p, param_len) != 1) { 1221 if (tls1_check_curve(s, curve_id) != 1) {
1222 al = SSL_AD_DECODE_ERROR; 1222 al = SSL_AD_DECODE_ERROR;
1223 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_CURVE); 1223 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_CURVE);
1224 goto f_err; 1224 goto f_err;
1225 } 1225 }
1226 1226
1227 if ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0) { 1227 if ((curve_nid = tls1_ec_curve_id2nid(curve_id)) == 0) {
1228 al = SSL_AD_INTERNAL_ERROR; 1228 al = SSL_AD_INTERNAL_ERROR;
1229 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, 1229 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE,
1230 SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); 1230 SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
1231 goto f_err; 1231 goto f_err;
1232 } 1232 }
1233 1233
1234 ngroup = EC_GROUP_new_by_curve_name(curve_nid); 1234 if ((ngroup = EC_GROUP_new_by_curve_name(curve_nid)) == NULL) {
1235 if (ngroup == NULL) {
1236 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); 1235 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB);
1237 goto err; 1236 goto err;
1238 } 1237 }
@@ -1244,31 +1243,23 @@ ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn)
1244 1243
1245 group = EC_KEY_get0_group(ecdh); 1244 group = EC_KEY_get0_group(ecdh);
1246 1245
1247 p += 3;
1248
1249 /* Next, get the encoded ECPoint */ 1246 /* Next, get the encoded ECPoint */
1250 if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) || 1247 if ((srvr_ecpoint = EC_POINT_new(group)) == NULL ||
1251 ((bn_ctx = BN_CTX_new()) == NULL)) { 1248 (bn_ctx = BN_CTX_new()) == NULL) {
1252 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); 1249 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE);
1253 goto err; 1250 goto err;
1254 } 1251 }
1255 1252
1256 if (param_len + 1 > n) 1253 if (!CBS_get_u8_length_prefixed(&cbs, &ecpoint))
1257 goto truncated; 1254 goto truncated;
1258 encoded_pt_len = *p; 1255
1259 /* length of encoded point */ 1256 if (EC_POINT_oct2point(group, srvr_ecpoint, CBS_data(&ecpoint),
1260 p += 1; 1257 CBS_len(&ecpoint), bn_ctx) == 0) {
1261 param_len += (1 + encoded_pt_len);
1262 if ((param_len > n) || (EC_POINT_oct2point(group, srvr_ecpoint,
1263 p, encoded_pt_len, bn_ctx) == 0)) {
1264 al = SSL_AD_DECODE_ERROR; 1258 al = SSL_AD_DECODE_ERROR;
1265 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT); 1259 SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT);
1266 goto f_err; 1260 goto f_err;
1267 } 1261 }
1268 1262
1269 n -= param_len;
1270 p += encoded_pt_len;
1271
1272 /* 1263 /*
1273 * The ECC/TLS specification does not mention the use of DSA to sign 1264 * The ECC/TLS specification does not mention the use of DSA to sign
1274 * ECParameters in the server key exchange message. We do support RSA 1265 * ECParameters in the server key exchange message. We do support RSA
@@ -1288,8 +1279,8 @@ ssl3_get_server_kex_ecdhe(SSL *s, EVP_PKEY **pkey, unsigned char **pp, long *nn)
1288 BN_CTX_free(bn_ctx); 1279 BN_CTX_free(bn_ctx);
1289 EC_POINT_free(srvr_ecpoint); 1280 EC_POINT_free(srvr_ecpoint);
1290 1281
1291 *nn = n; 1282 *nn = CBS_len(&cbs);
1292 *pp = p; 1283 *pp = (unsigned char *)CBS_data(&cbs);
1293 1284
1294 return (1); 1285 return (1);
1295 1286
diff --git a/src/lib/libssl/ssl_locl.h b/src/lib/libssl/ssl_locl.h
index 1b3838a33f..4386f0f7e5 100644
--- a/src/lib/libssl/ssl_locl.h
+++ b/src/lib/libssl/ssl_locl.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssl_locl.h,v 1.134 2016/11/04 19:11:43 jsing Exp $ */ 1/* $OpenBSD: ssl_locl.h,v 1.135 2016/11/05 08:26:36 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -772,9 +772,9 @@ int ssl_ok(SSL *s);
772 772
773int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s); 773int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s);
774 774
775int tls1_ec_curve_id2nid(uint16_t curve_id); 775int tls1_ec_curve_id2nid(const uint16_t curve_id);
776uint16_t tls1_ec_nid2curve_id(int nid); 776uint16_t tls1_ec_nid2curve_id(const int nid);
777int tls1_check_curve(SSL *s, const unsigned char *p, size_t len); 777int tls1_check_curve(SSL *s, const uint16_t curve_id);
778int tls1_get_shared_curve(SSL *s); 778int tls1_get_shared_curve(SSL *s);
779 779
780unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p, 780unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *p,
diff --git a/src/lib/libssl/t1_lib.c b/src/lib/libssl/t1_lib.c
index e7dbe9cd99..090259cf1f 100644
--- a/src/lib/libssl/t1_lib.c
+++ b/src/lib/libssl/t1_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: t1_lib.c,v 1.93 2016/10/19 16:38:40 jsing Exp $ */ 1/* $OpenBSD: t1_lib.c,v 1.94 2016/11/05 08:26:37 jsing Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -282,7 +282,7 @@ static const uint16_t eccurves_default[] = {
282}; 282};
283 283
284int 284int
285tls1_ec_curve_id2nid(uint16_t curve_id) 285tls1_ec_curve_id2nid(const uint16_t curve_id)
286{ 286{
287 /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */ 287 /* ECC curves from draft-ietf-tls-ecc-12.txt (Oct. 17, 2005) */
288 if ((curve_id < 1) || 288 if ((curve_id < 1) ||
@@ -405,27 +405,15 @@ tls1_get_curvelist(SSL *s, int client_curves, const uint16_t **pcurves,
405 405
406/* Check that a curve is one of our preferences. */ 406/* Check that a curve is one of our preferences. */
407int 407int
408tls1_check_curve(SSL *s, const unsigned char *p, size_t len) 408tls1_check_curve(SSL *s, const uint16_t curve_id)
409{ 409{
410 CBS cbs;
411 const uint16_t *curves; 410 const uint16_t *curves;
412 size_t curveslen, i; 411 size_t curveslen, i;
413 uint8_t type;
414 uint16_t cid;
415
416 CBS_init(&cbs, p, len);
417
418 /* Only named curves are supported. */
419 if (CBS_len(&cbs) != 3 ||
420 !CBS_get_u8(&cbs, &type) ||
421 type != NAMED_CURVE_TYPE ||
422 !CBS_get_u16(&cbs, &cid))
423 return (0);
424 412
425 tls1_get_curvelist(s, 0, &curves, &curveslen); 413 tls1_get_curvelist(s, 0, &curves, &curveslen);
426 414
427 for (i = 0; i < curveslen; i++) { 415 for (i = 0; i < curveslen; i++) {
428 if (curves[i] == cid) 416 if (curves[i] == curve_id)
429 return (1); 417 return (1);
430 } 418 }
431 return (0); 419 return (0);