diff options
Diffstat (limited to 'src/lib/libssl/ssl_sigalgs.c')
-rw-r--r-- | src/lib/libssl/ssl_sigalgs.c | 84 |
1 files changed, 79 insertions, 5 deletions
diff --git a/src/lib/libssl/ssl_sigalgs.c b/src/lib/libssl/ssl_sigalgs.c index 3a7f6d6687..50f4802fdb 100644 --- a/src/lib/libssl/ssl_sigalgs.c +++ b/src/lib/libssl/ssl_sigalgs.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssl_sigalgs.c,v 1.17 2019/03/19 16:56:04 jsing Exp $ */ | 1 | /* $OpenBSD: ssl_sigalgs.c,v 1.18 2019/03/25 17:21:18 jsing Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2018-2019 Bob Beck <beck@openbsd.org> | 3 | * Copyright (c) 2018-2019 Bob Beck <beck@openbsd.org> |
4 | * | 4 | * |
@@ -246,7 +246,8 @@ ssl_sigalgs_build(CBB *cbb, uint16_t *values, size_t len) | |||
246 | } | 246 | } |
247 | 247 | ||
248 | int | 248 | int |
249 | ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey) | 249 | ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey, |
250 | int check_curve) | ||
250 | { | 251 | { |
251 | if (sigalg == NULL || pkey == NULL) | 252 | if (sigalg == NULL || pkey == NULL) |
252 | return 0; | 253 | return 0; |
@@ -266,12 +267,85 @@ ssl_sigalg_pkey_ok(const struct ssl_sigalg *sigalg, EVP_PKEY *pkey) | |||
266 | if (pkey->type == EVP_PKEY_EC) { | 267 | if (pkey->type == EVP_PKEY_EC) { |
267 | if (sigalg->curve_nid == 0) | 268 | if (sigalg->curve_nid == 0) |
268 | return 0; | 269 | return 0; |
269 | /* Curve must match for EC keys */ | 270 | /* Curve must match for EC keys. */ |
270 | if (EC_GROUP_get_curve_name(EC_KEY_get0_group | 271 | if (check_curve && EC_GROUP_get_curve_name(EC_KEY_get0_group |
271 | (EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->curve_nid) { | 272 | (EVP_PKEY_get0_EC_KEY(pkey))) != sigalg->curve_nid) { |
272 | return 1; /* XXX www.videolan.org curve mismatch */ | 273 | return 0; |
273 | } | 274 | } |
274 | } | 275 | } |
275 | 276 | ||
276 | return 1; | 277 | return 1; |
277 | } | 278 | } |
279 | |||
280 | const struct ssl_sigalg * | ||
281 | ssl_sigalg_select(SSL *s, EVP_PKEY *pkey) | ||
282 | { | ||
283 | uint16_t *tls_sigalgs = tls12_sigalgs; | ||
284 | size_t tls_sigalgs_len = tls12_sigalgs_len; | ||
285 | int check_curve = 0; | ||
286 | CBS cbs; | ||
287 | |||
288 | if (TLS1_get_version(s) >= TLS1_3_VERSION) { | ||
289 | tls_sigalgs = tls13_sigalgs; | ||
290 | tls_sigalgs_len = tls13_sigalgs_len; | ||
291 | check_curve = 1; | ||
292 | } | ||
293 | |||
294 | /* Pre TLS 1.2 defaults */ | ||
295 | if (!SSL_USE_SIGALGS(s)) { | ||
296 | switch (pkey->type) { | ||
297 | case EVP_PKEY_RSA: | ||
298 | return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_MD5_SHA1); | ||
299 | case EVP_PKEY_EC: | ||
300 | return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1); | ||
301 | #ifndef OPENSSL_NO_GOST | ||
302 | case EVP_PKEY_GOSTR01: | ||
303 | return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94); | ||
304 | #endif | ||
305 | } | ||
306 | SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE); | ||
307 | return (NULL); | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * RFC 5246 allows a TLS 1.2 client to send no sigalgs, in | ||
312 | * which case the server must use the the default. | ||
313 | */ | ||
314 | if (TLS1_get_version(s) < TLS1_3_VERSION && | ||
315 | S3I(s)->hs.sigalgs == NULL) { | ||
316 | switch (pkey->type) { | ||
317 | case EVP_PKEY_RSA: | ||
318 | return ssl_sigalg_lookup(SIGALG_RSA_PKCS1_SHA1); | ||
319 | case EVP_PKEY_EC: | ||
320 | return ssl_sigalg_lookup(SIGALG_ECDSA_SHA1); | ||
321 | #ifndef OPENSSL_NO_GOST | ||
322 | case EVP_PKEY_GOSTR01: | ||
323 | return ssl_sigalg_lookup(SIGALG_GOSTR01_GOST94); | ||
324 | #endif | ||
325 | } | ||
326 | SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE); | ||
327 | return (NULL); | ||
328 | } | ||
329 | |||
330 | /* | ||
331 | * If we get here, we have client or server sent sigalgs, use one. | ||
332 | */ | ||
333 | CBS_init(&cbs, S3I(s)->hs.sigalgs, S3I(s)->hs.sigalgs_len); | ||
334 | while (CBS_len(&cbs) > 0) { | ||
335 | uint16_t sig_alg; | ||
336 | const struct ssl_sigalg *sigalg; | ||
337 | |||
338 | if (!CBS_get_u16(&cbs, &sig_alg)) | ||
339 | return 0; | ||
340 | |||
341 | if ((sigalg = ssl_sigalg(sig_alg, tls_sigalgs, | ||
342 | tls_sigalgs_len)) == NULL) | ||
343 | continue; | ||
344 | |||
345 | if (ssl_sigalg_pkey_ok(sigalg, pkey, check_curve)) | ||
346 | return sigalg; | ||
347 | } | ||
348 | |||
349 | SSLerror(s, SSL_R_UNKNOWN_PKEY_TYPE); | ||
350 | return NULL; | ||
351 | } | ||