summaryrefslogtreecommitdiff
path: root/src/regress/lib
diff options
context:
space:
mode:
authortb <>2026-01-04 09:51:42 +0000
committertb <>2026-01-04 09:51:42 +0000
commitf65bd896414ed2e25bad00527fa4f1c5fabdad09 (patch)
tree5ab684b0386050cab74af4580e7fb381694ec8e2 /src/regress/lib
parente25ccd667e01e3a9e37f06e7cc79fb7ac0f6e3f4 (diff)
downloadopenbsd-f65bd896414ed2e25bad00527fa4f1c5fabdad09.tar.gz
openbsd-f65bd896414ed2e25bad00527fa4f1c5fabdad09.tar.bz2
openbsd-f65bd896414ed2e25bad00527fa4f1c5fabdad09.zip
i2c_ASN1_BIT_STRING() vs ASN1_STRING_FLAG_BITS_LEFT
A nasty quirk in the bit string handling is that the serialization produced by i2d_ASN1_BIT_STRING() depends on whether the the magic ASN1_STRING_FLAG_BITS_LEFT is set. If ASN1_STRING_FLAG_BITS_LEFT is set, the number of unused bits is carried in a->flags & 0x07 and the remainder of the bit string is in a->data. This is terrible and undocumented but handled correctly. If ASN1_STRING_FLAG_BITS_LEFT is not set, all trailing zero bits are (intended to be) chopped off with all sorts of hilarious side effects. I broke this quite thoroughly when I incorrectly ported an overflow check from BoringSSL in: https://github.com/openbsd/src/commit/f81cc285d2aed8b36615119a306533696f3eb66c The result is that we currently return ret = a->length + 1 for both NULL and non-NULL pp. The calls to asn1_ex_i2c() in asn1_i2d_ex_primitive() thus report consistent lengths back, making it succeed. asn1_i2d_ex_primitive() therefore skips a->length + 1 bytes, while i2c_ASN1_BIT_STRING() only overwrites len + 1 bytes, which are possibly fewer. So a caller passing in an output buffer containing garbage (malloc) will get some of that garbage back in the encoding. Further, i2c_ASN1_BIT_STRING() also advances that pointer by the possibly reduced len + 1, but that fortunately doesn't matter since that's an effect local to asn1_ex_i2c(), the only caller of i2c_ASN1_BIT_STRING(). The last bit is that the current behavior may set bogus unused bits coming from the scanning backward madness. I added such an example in the parent commit. The fix is simple: use len after the truncation effect was established, not the original a->length, turning this commit into what my backport should have been. This fixes the two currently failing regress tests, so remove expected failure marker again. ok jsing kenjiro
Diffstat (limited to 'src/regress/lib')
-rw-r--r--src/regress/lib/libcrypto/asn1/Makefile4
1 files changed, 1 insertions, 3 deletions
diff --git a/src/regress/lib/libcrypto/asn1/Makefile b/src/regress/lib/libcrypto/asn1/Makefile
index 1bb9da8585..23a01ab600 100644
--- a/src/regress/lib/libcrypto/asn1/Makefile
+++ b/src/regress/lib/libcrypto/asn1/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.29 2026/01/04 09:42:32 tb Exp $ 1# $OpenBSD: Makefile,v 1.30 2026/01/04 09:51:42 tb Exp $
2 2
3PROGS = \ 3PROGS = \
4 asn1api \ 4 asn1api \
@@ -22,8 +22,6 @@ CFLAGS+= -Wall -Wundef -Werror
22CFLAGS+= -I${.CURDIR}/../../../../lib/libcrypto/asn1 22CFLAGS+= -I${.CURDIR}/../../../../lib/libcrypto/asn1
23CFLAGS+= -I${.CURDIR}/../../../../lib/libcrypto/bytestring 23CFLAGS+= -I${.CURDIR}/../../../../lib/libcrypto/bytestring
24 24
25REGRESS_EXPECTED_FAILURES += run-regress-asn1basic
26
27LDADD_asn1basic = ${CRYPTO_INT} 25LDADD_asn1basic = ${CRYPTO_INT}
28LDADD_asn1object = ${CRYPTO_INT} 26LDADD_asn1object = ${CRYPTO_INT}
29LDADD_asn1time = ${CRYPTO_INT} 27LDADD_asn1time = ${CRYPTO_INT}