summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
authortb <>2024-10-31 14:58:22 +0000
committertb <>2024-10-31 14:58:22 +0000
commit0e3dba5b6baf332335bf0fdd135743ba36e8c5d9 (patch)
treeea716d9d9656a84b62cd034145985694da3ab19c /src/lib
parent88f9511e2c9117d0faf1b852ec3ddb362c212115 (diff)
downloadopenbsd-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
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/libcrypto/ec/ec_asn1.c51
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);
1409int 1411int
1410i2o_ECPublicKey(const EC_KEY *ec_key, unsigned char **out) 1412i2o_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}
1446LCRYPTO_ALIAS(i2o_ECPublicKey); 1445LCRYPTO_ALIAS(i2o_ECPublicKey);