summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2023-03-06 08:08:31 +0000
committertb <>2023-03-06 08:08:31 +0000
commitec79b8a0caa19718e16811a1ca55f0c980ef6d2f (patch)
treeeed7711b1cc0c71d0017dc611ab43527b1c7ef41
parent6bac610727a591217d2872d33752ba81334680ae (diff)
downloadopenbsd-ec79b8a0caa19718e16811a1ca55f0c980ef6d2f.tar.gz
openbsd-ec79b8a0caa19718e16811a1ca55f0c980ef6d2f.tar.bz2
openbsd-ec79b8a0caa19718e16811a1ca55f0c980ef6d2f.zip
ASN.1 enc: check ASN1_item_ex_i2d() consistency
The i2d API design is: call a function first with a pointer to NULL, get the length, allocate a buffer, call the function passing the buffer in. Both calls should be checked since ther are still internal allocations. At the heart of ASN.1 encoding, this idiom is used and the second call is assumed to succeed after the length was determined. This is far from guaranteed. Check that the second call returns the same length and error otherwise. ok jsing
-rw-r--r--src/lib/libcrypto/asn1/tasn_enc.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/src/lib/libcrypto/asn1/tasn_enc.c b/src/lib/libcrypto/asn1/tasn_enc.c
index 55e65895f8..1b9cfa1a0e 100644
--- a/src/lib/libcrypto/asn1/tasn_enc.c
+++ b/src/lib/libcrypto/asn1/tasn_enc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tasn_enc.c,v 1.27 2022/11/26 16:08:50 tb Exp $ */ 1/* $OpenBSD: tasn_enc.c,v 1.28 2023/03/06 08:08:31 tb Exp $ */
2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL 2/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3 * project 2000. 3 * project 2000.
4 */ 4 */
@@ -108,7 +108,7 @@ asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it,
108{ 108{
109 if (out && !*out) { 109 if (out && !*out) {
110 unsigned char *p, *buf; 110 unsigned char *p, *buf;
111 int len; 111 int len, len2;
112 len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags); 112 len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags);
113 if (len <= 0) 113 if (len <= 0)
114 return len; 114 return len;
@@ -116,7 +116,12 @@ asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it,
116 if (!buf) 116 if (!buf)
117 return -1; 117 return -1;
118 p = buf; 118 p = buf;
119 ASN1_item_ex_i2d(&val, &p, it, -1, flags); 119 len2 = ASN1_item_ex_i2d(&val, &p, it, -1, flags);
120 if (len2 != len) {
121 freezero(buf, len);
122 ASN1error(ASN1_R_LENGTH_ERROR);
123 return -1;
124 }
120 *out = buf; 125 *out = buf;
121 return len; 126 return len;
122 } 127 }