summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/dsa/dsa_lib.c
diff options
context:
space:
mode:
authortb <>2022-08-31 13:01:01 +0000
committertb <>2022-08-31 13:01:01 +0000
commitd1472daedc6c1d5786dbc4b552ac0f1ad19c65d2 (patch)
tree8991ebe0360b3e90f90f196c1565ac3ed01531ab /src/lib/libcrypto/dsa/dsa_lib.c
parent15eca26842e04912050d30a972fcce04e046da8a (diff)
downloadopenbsd-d1472daedc6c1d5786dbc4b552ac0f1ad19c65d2.tar.gz
openbsd-d1472daedc6c1d5786dbc4b552ac0f1ad19c65d2.tar.bz2
openbsd-d1472daedc6c1d5786dbc4b552ac0f1ad19c65d2.zip
Rework DSA_size() and ECDSA_size()
DSA_size() and ECDSA_size() have a very special hack. They fudge up an ASN1_INTEGER with a size which is typically > 100 bytes, backed by a buffer of size 4. This was "fine", however, since they set buf[0] = 0xff, where the craziness that was i2c_ASN1_INTEGER() only looks at the first octet (one may then ask why a buffer of size 4 was necessary...). This changed with the rewrite of i2c_ASN1_INTEGER(), which doesn't respect this particular hack and rightly assumes that it is fed an actual ASN1_INTEGER... Instead, create an appropriate signature and use i2d to determine its size. Fixes an out-of-bounds read flagged by ASAN and oss-fuzz. ok jsing
Diffstat (limited to '')
-rw-r--r--src/lib/libcrypto/dsa/dsa_lib.c28
1 files changed, 10 insertions, 18 deletions
diff --git a/src/lib/libcrypto/dsa/dsa_lib.c b/src/lib/libcrypto/dsa/dsa_lib.c
index 949722b734..da95705947 100644
--- a/src/lib/libcrypto/dsa/dsa_lib.c
+++ b/src/lib/libcrypto/dsa/dsa_lib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: dsa_lib.c,v 1.35 2022/06/27 12:28:46 tb Exp $ */ 1/* $OpenBSD: dsa_lib.c,v 1.36 2022/08/31 13:01:01 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -220,23 +220,15 @@ DSA_up_ref(DSA *r)
220int 220int
221DSA_size(const DSA *r) 221DSA_size(const DSA *r)
222{ 222{
223 int ret, i; 223 DSA_SIG signature;
224 ASN1_INTEGER bs; 224 int ret = 0;
225 unsigned char buf[4]; /* 4 bytes looks really small. 225
226 However, i2d_ASN1_INTEGER() will not look 226 signature.r = r->q;
227 beyond the first byte, as long as the second 227 signature.s = r->q;
228 parameter is NULL. */ 228
229 229 if ((ret = i2d_DSA_SIG(&signature, NULL)) < 0)
230 i = BN_num_bits(r->q); 230 ret = 0;
231 bs.length = (i + 7) / 8; 231
232 bs.data = buf;
233 bs.type = V_ASN1_INTEGER;
234 /* If the top bit is set the asn1 encoding is 1 larger. */
235 buf[0] = 0xff;
236
237 i = i2d_ASN1_INTEGER(&bs, NULL);
238 i += i; /* r and s */
239 ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
240 return ret; 232 return ret;
241} 233}
242 234