Rewrite i2o_ECPublicKey with CBB_finish_i2d.
Less code, and internally handles overflows. (Although this one cannot
overflow.)
Bug: 516
Change-Id: I3c2718075689d2815a43534a578a323c52787223
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/55452
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/ec_extra/ec_asn1.c b/crypto/ec_extra/ec_asn1.c
index 43132a6..ee75165 100644
--- a/crypto/ec_extra/ec_asn1.c
+++ b/crypto/ec_extra/ec_asn1.c
@@ -518,42 +518,18 @@
}
int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) {
- size_t buf_len = 0;
- int new_buffer = 0;
-
if (key == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
-
- buf_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL,
- 0, NULL);
-
- if (outp == NULL || buf_len == 0) {
- // out == NULL => just return the length of the octet string
- return buf_len;
+ CBB cbb;
+ if (!CBB_init(&cbb, 0) || //
+ !EC_POINT_point2cbb(&cbb, key->group, key->pub_key, key->conv_form,
+ NULL)) {
+ CBB_cleanup(&cbb);
+ return -1;
}
-
- if (*outp == NULL) {
- *outp = OPENSSL_malloc(buf_len);
- if (*outp == NULL) {
- OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- new_buffer = 1;
- }
- if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp,
- buf_len, NULL)) {
- OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
- if (new_buffer) {
- OPENSSL_free(*outp);
- *outp = NULL;
- }
- return 0;
- }
-
- if (!new_buffer) {
- *outp += buf_len;
- }
- return buf_len;
+ int ret = CBB_finish_i2d(&cbb, outp);
+ // Historically, this function used the wrong return value on error.
+ return ret > 0 ? ret : 0;
}
diff --git a/include/openssl/ec_key.h b/include/openssl/ec_key.h
index ee9c9f0..00986cf 100644
--- a/include/openssl/ec_key.h
+++ b/include/openssl/ec_key.h
@@ -361,7 +361,7 @@
long len);
// i2o_ECPublicKey marshals an EC point from |key|, as described in
-// |i2d_SAMPLE|.
+// |i2d_SAMPLE|, except it returns zero on error instead of a negative value.
//
// Use |EC_POINT_point2cbb| instead.
OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp);