diff options
| author | jsing <> | 2019-03-25 17:21:18 +0000 |
|---|---|---|
| committer | jsing <> | 2019-03-25 17:21:18 +0000 |
| commit | c46928243f6c8aa22e46219e22df33de006a501f (patch) | |
| tree | eb5e58a5d9b8198b8475b96156e908c92c86e532 /src/lib/libssl/ssl_sigalgs.c | |
| parent | efbbd2468336b87fa8f4dc802ec09d5638f8f0cb (diff) | |
| download | openbsd-c46928243f6c8aa22e46219e22df33de006a501f.tar.gz openbsd-c46928243f6c8aa22e46219e22df33de006a501f.tar.bz2 openbsd-c46928243f6c8aa22e46219e22df33de006a501f.zip | |
Defer sigalgs selection until the certificate is known.
Previously the signature algorithm was selected when the TLS extension was
parsed (or the client received a certificate request), however the actual
certificate to be used is not known at this stage. This leads to various
problems, including the selection of a signature algorithm that cannot be
used with the certificate key size (as found by jeremy@ via ruby regress).
Instead, store the signature algorithms list and only select a signature
algorithm when we're ready to do signature generation.
Joint work with beck@.
Diffstat (limited to '')
| -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 | } | ||
