diff options
author | tb <> | 2024-10-31 14:58:22 +0000 |
---|---|---|
committer | tb <> | 2024-10-31 14:58:22 +0000 |
commit | 0e3dba5b6baf332335bf0fdd135743ba36e8c5d9 (patch) | |
tree | ea716d9d9656a84b62cd034145985694da3ab19c | |
parent | 88f9511e2c9117d0faf1b852ec3ddb362c212115 (diff) | |
download | openbsd-0e3dba5b6baf332335bf0fdd135743ba36e8c5d9.tar.gz openbsd-0e3dba5b6baf332335bf0fdd135743ba36e8c5d9.tar.bz2 openbsd-0e3dba5b6baf332335bf0fdd135743ba36e8c5d9.zip |
Rewrite i2o_ECPublicKey()
Turn the function into single exit and use ec_point_to_octets() to avoid
the point2oct dance. Ensure that the buf_len size_t doesn't get truncated
by the int return.
While we could avoid an allocation in case out == NULL, we don't do so.
In case out != NULL and *out != NULL this API assumes *out has sufficient
room, copies the result into it and advances *out past it. This is just
asking for trouble (of course, i2d has the same misfeature). Don't use
this if you can help it.
Unfortunately, OpenSSH couldn't help it in at least one spot (that one's
on BoringSSL's allocator not returning an allocated pointer that you can
pass to free). We had to do it lest people run RedHat patches of dubious
quality. For: FIPS the monkey must be pleased at all cost.
ok jsing
-rw-r--r-- | src/lib/libcrypto/ec/ec_asn1.c | 51 |
1 files changed, 25 insertions, 26 deletions
diff --git a/src/lib/libcrypto/ec/ec_asn1.c b/src/lib/libcrypto/ec/ec_asn1.c index 7cc9a75c55..c44b06be82 100644 --- a/src/lib/libcrypto/ec/ec_asn1.c +++ b/src/lib/libcrypto/ec/ec_asn1.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ec_asn1.c,v 1.101 2024/10/30 17:54:54 tb Exp $ */ | 1 | /* $OpenBSD: ec_asn1.c,v 1.102 2024/10/31 14:58:22 tb Exp $ */ |
2 | /* | 2 | /* |
3 | * Written by Nils Larsch for the OpenSSL project. | 3 | * Written by Nils Larsch for the OpenSSL project. |
4 | */ | 4 | */ |
@@ -56,8 +56,10 @@ | |||
56 | * | 56 | * |
57 | */ | 57 | */ |
58 | 58 | ||
59 | #include <limits.h> | ||
59 | #include <stddef.h> | 60 | #include <stddef.h> |
60 | #include <stdlib.h> | 61 | #include <stdlib.h> |
62 | #include <string.h> | ||
61 | 63 | ||
62 | #include <openssl/opensslconf.h> | 64 | #include <openssl/opensslconf.h> |
63 | 65 | ||
@@ -1409,38 +1411,35 @@ LCRYPTO_ALIAS(o2i_ECPublicKey); | |||
1409 | int | 1411 | int |
1410 | i2o_ECPublicKey(const EC_KEY *ec_key, unsigned char **out) | 1412 | i2o_ECPublicKey(const EC_KEY *ec_key, unsigned char **out) |
1411 | { | 1413 | { |
1414 | unsigned char *buf = NULL; | ||
1412 | size_t buf_len = 0; | 1415 | size_t buf_len = 0; |
1413 | int new_buffer = 0; | 1416 | int ret = 0; |
1414 | 1417 | ||
1415 | if (ec_key == NULL) { | 1418 | if (ec_key == NULL) { |
1416 | ECerror(ERR_R_PASSED_NULL_PARAMETER); | 1419 | ECerror(ERR_R_PASSED_NULL_PARAMETER); |
1417 | return 0; | 1420 | goto err; |
1418 | } | 1421 | } |
1419 | buf_len = EC_POINT_point2oct(ec_key->group, ec_key->pub_key, | ||
1420 | ec_key->conv_form, NULL, 0, NULL); | ||
1421 | 1422 | ||
1422 | if (out == NULL || buf_len == 0) | 1423 | if (!ec_point_to_octets(ec_key->group, ec_key->pub_key, |
1423 | /* out == NULL => just return the length of the octet string */ | 1424 | ec_key->conv_form, &buf, &buf_len, NULL)) |
1424 | return buf_len; | 1425 | goto err; |
1426 | if (buf_len > INT_MAX) | ||
1427 | goto err; | ||
1425 | 1428 | ||
1426 | if (*out == NULL) { | 1429 | if (out != NULL && *out != NULL) { |
1427 | if ((*out = malloc(buf_len)) == NULL) { | 1430 | /* Muppet's answer to the Jackass show. */ |
1428 | ECerror(ERR_R_MALLOC_FAILURE); | 1431 | memcpy(*out, buf, buf_len); |
1429 | return 0; | ||
1430 | } | ||
1431 | new_buffer = 1; | ||
1432 | } | ||
1433 | if (!EC_POINT_point2oct(ec_key->group, ec_key->pub_key, ec_key->conv_form, | ||
1434 | *out, buf_len, NULL)) { | ||
1435 | ECerror(ERR_R_EC_LIB); | ||
1436 | if (new_buffer) { | ||
1437 | free(*out); | ||
1438 | *out = NULL; | ||
1439 | } | ||
1440 | return 0; | ||
1441 | } | ||
1442 | if (!new_buffer) | ||
1443 | *out += buf_len; | 1432 | *out += buf_len; |
1444 | return buf_len; | 1433 | } else if (out != NULL) { |
1434 | *out = buf; | ||
1435 | buf = NULL; | ||
1436 | } | ||
1437 | |||
1438 | ret = buf_len; | ||
1439 | |||
1440 | err: | ||
1441 | freezero(buf, buf_len); | ||
1442 | |||
1443 | return ret; | ||
1445 | } | 1444 | } |
1446 | LCRYPTO_ALIAS(i2o_ECPublicKey); | 1445 | LCRYPTO_ALIAS(i2o_ECPublicKey); |