summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorschwarze <>2020-06-04 21:21:03 +0000
committerschwarze <>2020-06-04 21:21:03 +0000
commitd0cf9aeca512581235a63d9ed8e8a3c69039b9df (patch)
tree2920ef908eabfe843f01bfd04a3aaf4eff0a1cec /src
parent53beb8fe96aa9ab3ce5c57b525e3a1fbb817382e (diff)
downloadopenbsd-d0cf9aeca512581235a63d9ed8e8a3c69039b9df.tar.gz
openbsd-d0cf9aeca512581235a63d9ed8e8a3c69039b9df.tar.bz2
openbsd-d0cf9aeca512581235a63d9ed8e8a3c69039b9df.zip
When X509_ATTRIBUTE_create() receives an invalid NID (e.g., -1), return
failure rather than silently constructing a broken X509_ATTRIBUTE object that might cause NULL pointer accesses later on. This matters because X509_ATTRIBUTE_create() is used by documented API functions like PKCS7_add_attribute(3) and the NID comes straight from the user. This fixes a bug found while working on documentation. OK tb@ and "thanks" bluhm@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/asn1/x_attrib.c7
-rw-r--r--src/lib/libcrypto/man/PKCS7_add_attribute.316
-rw-r--r--src/regress/lib/libcrypto/x509/Makefile13
-rw-r--r--src/regress/lib/libcrypto/x509/x509attribute.c107
4 files changed, 124 insertions, 19 deletions
diff --git a/src/lib/libcrypto/asn1/x_attrib.c b/src/lib/libcrypto/asn1/x_attrib.c
index bb74a1b6c7..04816eab77 100644
--- a/src/lib/libcrypto/asn1/x_attrib.c
+++ b/src/lib/libcrypto/asn1/x_attrib.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x_attrib.c,v 1.13 2015/02/14 14:56:45 jsing Exp $ */ 1/* $OpenBSD: x_attrib.c,v 1.14 2020/06/04 21:21:03 schwarze 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 *
@@ -174,10 +174,13 @@ X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
174{ 174{
175 X509_ATTRIBUTE *ret = NULL; 175 X509_ATTRIBUTE *ret = NULL;
176 ASN1_TYPE *val = NULL; 176 ASN1_TYPE *val = NULL;
177 ASN1_OBJECT *oid;
177 178
179 if ((oid = OBJ_nid2obj(nid)) == NULL)
180 return (NULL);
178 if ((ret = X509_ATTRIBUTE_new()) == NULL) 181 if ((ret = X509_ATTRIBUTE_new()) == NULL)
179 return (NULL); 182 return (NULL);
180 ret->object = OBJ_nid2obj(nid); 183 ret->object = oid;
181 ret->single = 0; 184 ret->single = 0;
182 if ((ret->value.set = sk_ASN1_TYPE_new_null()) == NULL) 185 if ((ret->value.set = sk_ASN1_TYPE_new_null()) == NULL)
183 goto err; 186 goto err;
diff --git a/src/lib/libcrypto/man/PKCS7_add_attribute.3 b/src/lib/libcrypto/man/PKCS7_add_attribute.3
index 09c36a4d5d..081703f0f3 100644
--- a/src/lib/libcrypto/man/PKCS7_add_attribute.3
+++ b/src/lib/libcrypto/man/PKCS7_add_attribute.3
@@ -1,4 +1,4 @@
1.\" $OpenBSD: PKCS7_add_attribute.3,v 1.1 2020/06/04 10:24:27 schwarze Exp $ 1.\" $OpenBSD: PKCS7_add_attribute.3,v 1.2 2020/06/04 21:21:03 schwarze Exp $
2.\" 2.\"
3.\" Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org> 3.\" Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
4.\" 4.\"
@@ -123,7 +123,9 @@ exist.
123and 123and
124.Fn PKCS7_add_signed_attribute 124.Fn PKCS7_add_signed_attribute
125return 1 on success or 0 on failure. 125return 1 on success or 0 on failure.
126The most common reason for failure is lack of memory. 126The most common reasons for failure are an invalid
127.Fa nid
128argument or lack of memory.
127.Pp 129.Pp
128.Fn PKCS7_get_attribute 130.Fn PKCS7_get_attribute
129and 131and
@@ -153,16 +155,6 @@ These functions first appeared in OpenSSL 0.9.1
153and have been available since 155and have been available since
154.Ox 2.6 . 156.Ox 2.6 .
155.Sh BUGS 157.Sh BUGS
156Adding an attribute with an invalid
157.Fa nid
158ought to fail, but it actually succeeds
159setting the type of the new attribute to
160.Dv NULL .
161Subsequent attempts to retrieve attributes
162may cause the program to crash due to
163.Dv NULL
164pointer access.
165.Pp
166A function to remove individual attributes from these lists 158A function to remove individual attributes from these lists
167does not appear to exist. 159does not appear to exist.
168A program desiring to do that might have to manually iterate the fields 160A program desiring to do that might have to manually iterate the fields
diff --git a/src/regress/lib/libcrypto/x509/Makefile b/src/regress/lib/libcrypto/x509/Makefile
index 106a9f2bf2..19edf9398b 100644
--- a/src/regress/lib/libcrypto/x509/Makefile
+++ b/src/regress/lib/libcrypto/x509/Makefile
@@ -1,16 +1,19 @@
1# $OpenBSD: Makefile,v 1.1 2018/04/07 13:54:46 schwarze Exp $ 1# $OpenBSD: Makefile,v 1.2 2020/06/04 21:21:03 schwarze Exp $
2 2
3PROG= x509name 3PROGS = x509attribute x509name
4LDADD= -lcrypto 4LDADD= -lcrypto
5DPADD= ${LIBCRYPTO} 5DPADD= ${LIBCRYPTO}
6WARNINGS= Yes 6WARNINGS= Yes
7CFLAGS+= -Wall -Werror 7CFLAGS+= -Wall -Werror
8 8
9REGRESS_TARGETS=regress-x509name 9REGRESS_TARGETS=regress-x509attribute regress-x509name
10CLEANFILES+= x509name.result 10CLEANFILES+= x509name.result
11 11
12regress-x509name: ${PROG} 12regress-x509attribute: x509attribute
13 ./${PROG} > x509name.result 13 ./x509attribute
14
15regress-x509name: x509name
16 ./x509name > x509name.result
14 diff -u ${.CURDIR}/x509name.expected x509name.result 17 diff -u ${.CURDIR}/x509name.expected x509name.result
15 18
16.include <bsd.regress.mk> 19.include <bsd.regress.mk>
diff --git a/src/regress/lib/libcrypto/x509/x509attribute.c b/src/regress/lib/libcrypto/x509/x509attribute.c
new file mode 100644
index 0000000000..3dd6d2912c
--- /dev/null
+++ b/src/regress/lib/libcrypto/x509/x509attribute.c
@@ -0,0 +1,107 @@
1/* $OpenBSD: x509attribute.c,v 1.1 2020/06/04 21:21:03 schwarze Exp $ */
2/*
3 * Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <errno.h>
19#include <stdio.h>
20#include <string.h>
21
22#include <openssl/err.h>
23#include <openssl/x509.h>
24
25void fail_head(const char *);
26void fail_tail(void);
27void fail_str(const char *, const char *);
28void fail_int(const char *, int);
29
30static const char *testname;
31static int errcount;
32
33void
34fail_head(const char *stepname)
35{
36 fprintf(stderr, "failure#%d testname=%s stepname=%s ",
37 ++errcount, testname, stepname);
38}
39
40void
41fail_tail(void)
42{
43 unsigned long errnum;
44
45 if ((errnum = ERR_get_error()))
46 fprintf(stderr, "OpenSSL says: %s\n",
47 ERR_error_string(errnum, NULL));
48 if (errno)
49 fprintf(stderr, "libc says: %s\n", strerror(errno));
50}
51
52void
53fail_str(const char *stepname, const char *result)
54{
55 fail_head(stepname);
56 fprintf(stderr, "wrong result=%s\n", result);
57 fail_tail();
58}
59
60void
61fail_int(const char *stepname, int result)
62{
63 fail_head(stepname);
64 fprintf(stderr, "wrong result=%d\n", result);
65 fail_tail();
66}
67
68int
69main(void)
70{
71 X509_ATTRIBUTE *attrib;
72 ASN1_TYPE *any;
73 ASN1_OBJECT *coid;
74 int num;
75
76 testname = "preparation";
77 if ((coid = OBJ_nid2obj(NID_pkcs7_data)) == NULL) {
78 fail_str("OBJ_nid2obj", "NULL");
79 return 1;
80 }
81
82 testname = "valid_args";
83 if ((attrib = X509_ATTRIBUTE_create(NID_pkcs9_contentType,
84 V_ASN1_OBJECT, coid)) == NULL)
85 fail_str("X509_ATTRIBUTE_create", "NULL");
86 else if (attrib->object == NULL)
87 fail_str("attrib->object", "NULL");
88 else if (attrib->single)
89 fail_int("attrib->single", attrib->single);
90 else if ((num = sk_ASN1_TYPE_num(attrib->value.set)) != 1)
91 fail_int("num", num);
92 else if ((any = sk_ASN1_TYPE_value(attrib->value.set, 0)) == NULL)
93 fail_str("any", "NULL");
94 else if (any->type != V_ASN1_OBJECT)
95 fail_int("any->type", any->type);
96 else if (any->value.object != coid)
97 fail_str("value", "wrong pointer");
98 X509_ATTRIBUTE_free(attrib);
99
100 testname = "bad_nid";
101 if ((attrib = X509_ATTRIBUTE_create(-1,
102 V_ASN1_OBJECT, coid)) != NULL)
103 fail_str("X509_ATTRIBUTE_create", "not NULL");
104 X509_ATTRIBUTE_free(attrib);
105
106 return errcount != 0;
107}