summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTheo Buehler <tb@cvs.openbsd.org>2024-05-29 16:14:39 +0000
committerTheo Buehler <tb@cvs.openbsd.org>2024-05-29 16:14:39 +0000
commite00fe24646c14b3a9d6b7d6b55e228e0b8cc9cc9 (patch)
tree0ee31535200a6d984f2665a121448365eb4f7197
parent781ee797d4e37872fb3e4c1f8a43f22b22bcc6e3 (diff)
Fix i2d_ASN1_OBJECT()
When called with a pointer to NULL as an output buffer, one would expect an i2d API to allocate the buffer and return it. The implementation here is special and the allocation dance was forgotten, resulting in a SIGSEGV. Add said dance. ok jsing
-rw-r--r--lib/libcrypto/asn1/a_object.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/lib/libcrypto/asn1/a_object.c b/lib/libcrypto/asn1/a_object.c
index aae1b8bbd78..ed9e9287c4d 100644
--- a/lib/libcrypto/asn1/a_object.c
+++ b/lib/libcrypto/asn1/a_object.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: a_object.c,v 1.53 2024/05/29 16:10:41 tb Exp $ */
+/* $OpenBSD: a_object.c,v 1.54 2024/05/29 16:14:38 tb Exp $ */
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
@@ -615,7 +615,7 @@ c2i_ASN1_OBJECT(ASN1_OBJECT **out_aobj, const unsigned char **pp, long len)
int
i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
{
- unsigned char *p;
+ unsigned char *buf, *p;
int objsize;
if (a == NULL || a->data == NULL)
@@ -626,11 +626,20 @@ i2d_ASN1_OBJECT(const ASN1_OBJECT *a, unsigned char **pp)
if (pp == NULL)
return objsize;
- p = *pp;
+ if ((buf = *pp) == NULL)
+ buf = calloc(1, objsize);
+ if (buf == NULL)
+ return -1;
+
+ p = buf;
ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
memcpy(p, a->data, a->length);
p += a->length;
+ /* If buf was allocated, return it, otherwise return the advanced p. */
+ if (*pp == NULL)
+ p = buf;
+
*pp = p;
return objsize;