summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/libcrypto/pem/pem_info.c38
-rw-r--r--src/regress/lib/libcrypto/Makefile3
-rw-r--r--src/regress/lib/libcrypto/pem/Makefile8
-rw-r--r--src/regress/lib/libcrypto/pem/x509_info.c184
4 files changed, 211 insertions, 22 deletions
diff --git a/src/lib/libcrypto/pem/pem_info.c b/src/lib/libcrypto/pem/pem_info.c
index f02aaa8bb4..9561b5f4df 100644
--- a/src/lib/libcrypto/pem/pem_info.c
+++ b/src/lib/libcrypto/pem/pem_info.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: pem_info.c,v 1.22 2017/01/29 17:49:23 beck Exp $ */ 1/* $OpenBSD: pem_info.c,v 1.23 2020/07/23 17:15:35 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 *
@@ -101,29 +101,28 @@ PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb,
101 void *pp; 101 void *pp;
102 unsigned char *data = NULL; 102 unsigned char *data = NULL;
103 const unsigned char *p; 103 const unsigned char *p;
104 long len, error = 0; 104 long len;
105 int ok = 0; 105 int ok = 0;
106 STACK_OF(X509_INFO) *ret = NULL; 106 int num_in, ptype, raw;
107 unsigned int i, raw, ptype; 107 STACK_OF(X509_INFO) *ret = sk;
108 d2i_of_void *d2i = 0; 108 d2i_of_void *d2i = NULL;
109 109
110 if (sk == NULL) { 110 if (ret == NULL) {
111 if ((ret = sk_X509_INFO_new_null()) == NULL) { 111 if ((ret = sk_X509_INFO_new_null()) == NULL) {
112 PEMerror(ERR_R_MALLOC_FAILURE); 112 PEMerror(ERR_R_MALLOC_FAILURE);
113 return 0; 113 return NULL;
114 } 114 }
115 } else 115 }
116 ret = sk; 116 num_in = sk_X509_INFO_num(ret);
117 117
118 if ((xi = X509_INFO_new()) == NULL) 118 if ((xi = X509_INFO_new()) == NULL)
119 goto err; 119 goto err;
120 for (;;) { 120 for (;;) {
121 raw = 0; 121 raw = 0;
122 ptype = 0; 122 ptype = 0;
123 i = PEM_read_bio(bp, &name, &header, &data, &len); 123 if (!PEM_read_bio(bp, &name, &header, &data, &len)) {
124 if (i == 0) { 124 if (ERR_GET_REASON(ERR_peek_last_error()) ==
125 error = ERR_GET_REASON(ERR_peek_last_error()); 125 PEM_R_NO_START_LINE) {
126 if (error == PEM_R_NO_START_LINE) {
127 ERR_clear_error(); 126 ERR_clear_error();
128 break; 127 break;
129 } 128 }
@@ -286,22 +285,19 @@ start:
286 ok = 1; 285 ok = 1;
287 286
288err: 287err:
289 if (xi != NULL)
290 X509_INFO_free(xi);
291 if (!ok) { 288 if (!ok) {
292 for (i = 0; ((int)i) < sk_X509_INFO_num(ret); i++) { 289 while (sk_X509_INFO_num(ret) > num_in)
293 xi = sk_X509_INFO_value(ret, i); 290 X509_INFO_free(sk_X509_INFO_pop(ret));
294 X509_INFO_free(xi);
295 }
296 if (ret != sk) 291 if (ret != sk)
297 sk_X509_INFO_free(ret); 292 sk_X509_INFO_free(ret);
298 ret = NULL; 293 ret = NULL;
299 } 294 }
300 295 X509_INFO_free(xi);
301 free(name); 296 free(name);
302 free(header); 297 free(header);
303 free(data); 298 free(data);
304 return (ret); 299
300 return ret;
305} 301}
306 302
307 303
diff --git a/src/regress/lib/libcrypto/Makefile b/src/regress/lib/libcrypto/Makefile
index a5b4cc3855..8d6d40d62e 100644
--- a/src/regress/lib/libcrypto/Makefile
+++ b/src/regress/lib/libcrypto/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.38 2020/07/14 18:33:34 jsing Exp $ 1# $OpenBSD: Makefile,v 1.39 2020/07/23 17:15:35 schwarze Exp $
2 2
3SUBDIR += aead 3SUBDIR += aead
4SUBDIR += aeswrap 4SUBDIR += aeswrap
@@ -33,6 +33,7 @@ SUBDIR += init
33SUBDIR += md4 33SUBDIR += md4
34SUBDIR += md5 34SUBDIR += md5
35SUBDIR += pbkdf2 35SUBDIR += pbkdf2
36SUBDIR += pem
36SUBDIR += pkcs7 37SUBDIR += pkcs7
37SUBDIR += poly1305 38SUBDIR += poly1305
38SUBDIR += rand 39SUBDIR += rand
diff --git a/src/regress/lib/libcrypto/pem/Makefile b/src/regress/lib/libcrypto/pem/Makefile
new file mode 100644
index 0000000000..34561e217f
--- /dev/null
+++ b/src/regress/lib/libcrypto/pem/Makefile
@@ -0,0 +1,8 @@
1# $OpenBSD: Makefile,v 1.1 2020/07/23 17:15:35 schwarze Exp $
2
3PROG = x509_info
4LDADD = -lcrypto
5WARNINGS = Yes
6CFLAGS += -Werror
7
8.include <bsd.regress.mk>
diff --git a/src/regress/lib/libcrypto/pem/x509_info.c b/src/regress/lib/libcrypto/pem/x509_info.c
new file mode 100644
index 0000000000..e6b5388a71
--- /dev/null
+++ b/src/regress/lib/libcrypto/pem/x509_info.c
@@ -0,0 +1,184 @@
1/* $OpenBSD: x509_info.c,v 1.1 2020/07/23 17:15:35 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 <err.h>
19#include <string.h>
20
21#include <openssl/bio.h>
22#include <openssl/err.h>
23#include <openssl/pem.h>
24#include <openssl/x509.h>
25
26static const char *const bogus_pem = "\
27-----BEGIN BOGUS----- \n\
28-----END BOGUS----- \n\
29";
30
31static const char *const cert_pem = "\
32-----BEGIN CERTIFICATE----- \n\
33MIIDpTCCAo2gAwIBAgIJAPYm3GvOr5eTMA0GCSqGSIb3DQEBBQUAMHAxCzAJBgNV \n\
34BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMSIwIAYDVQQLDBlGT1IgVEVT \n\
35VElORyBQVVJQT1NFUyBPTkxZMSUwIwYDVQQDDBxPcGVuU1NMIFRlc3QgSW50ZXJt \n\
36ZWRpYXRlIENBMB4XDTE0MDUyNDE0NDUxMVoXDTI0MDQwMTE0NDUxMVowZDELMAkG \n\
37A1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxIjAgBgNVBAsMGUZPUiBU \n\
38RVNUSU5HIFBVUlBPU0VTIE9OTFkxGTAXBgNVBAMMEFRlc3QgQ2xpZW50IENlcnQw \n\
39ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0ranbHRLcLVqN+0BzcZpY \n\
40+yOLqxzDWT1LD9eW1stC4NzXX9/DCtSIVyN7YIHdGLrIPr64IDdXXaMRzgZ2rOKs \n\
41lmHCAiFpO/ja99gGCJRxH0xwQatqAULfJVHeUhs7OEGOZc2nWifjqKvGfNTilP7D \n\
42nwi69ipQFq9oS19FmhwVHk2wg7KZGHI1qDyG04UrfCZMRitvS9+UVhPpIPjuiBi2 \n\
43x3/FZIpL5gXJvvFK6xHY63oq2asyzBATntBgnP4qJFWWcvRx24wF1PnZabxuVoL2 \n\
44bPnQ/KvONDrw3IdqkKhYNTul7jEcu3OlcZIMw+7DiaKJLAzKb/bBF5gm/pwW6As9 \n\
45AgMBAAGjTjBMMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXgMCwGCWCGSAGG \n\
46+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTANBgkqhkiG9w0B \n\
47AQUFAAOCAQEAJzA4KTjkjXGSC4He63yX9Br0DneGBzjAwc1H6f72uqnCs8m7jgkE \n\
48PQJFdTzQUKh97QPUuayZ2gl8XHagg+iWGy60Kw37gQ0+lumCN2sllvifhHU9R03H \n\
49bWtS4kue+yQjMbrzf3zWygMDgwvFOUAIgBpH9qGc+CdNu97INTYd0Mvz51vLlxRn \n\
50sC5aBYCWaZFnw3lWYxf9eVFRy9U+DkYFqX0LpmbDtcKP7AZGE6ZwSzaim+Cnoz1u \n\
51Cgn+QmpFXgJKMFIZ82iSZISn+JkCCGxctZX1lMvai4Wi8Y0HxW9FTFZ6KBNwwE4B \n\
52zjbN/ehBkgLlW/DWfi44DvwUHmuU6QP3cw== \n\
53-----END CERTIFICATE----- \n\
54";
55
56int
57main(void)
58{
59 BIO *bp;
60 STACK_OF(X509_INFO) *skin, *skout;
61 X509_INFO *info0, *info1;
62 const char *errdata;
63 unsigned long errcode;
64 int errcount, errflags, num;
65
66 errcount = 0;
67 if ((skin = sk_X509_INFO_new_null()) == NULL)
68 err(1, "sk_X509_INFO_new_null");
69
70 /* Test with empty input. */
71
72 if ((bp = BIO_new_mem_buf("", 0)) == NULL)
73 err(1, "BIO_new_mem_buf(empty)");
74 if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) == NULL)
75 err(1, "empty input: %s",
76 ERR_error_string(ERR_get_error(), NULL));
77 if (skout != skin)
78 errx(1, "empty input did not return the same stack");
79 skout = NULL;
80 if ((num = sk_X509_INFO_num(skin)) != 0)
81 errx(1, "empty input created %d X509_INFO objects", num);
82 BIO_free(bp);
83
84 /* Test with bogus input. */
85
86 if ((bp = BIO_new_mem_buf(bogus_pem, strlen(bogus_pem))) == NULL)
87 err(1, "BIO_new_mem_buf(bogus_pem)");
88 if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) != NULL)
89 errx(1, "success with bogus input on first try");
90 if ((num = sk_X509_INFO_num(skin)) != 0)
91 errx(1, "bogus input created %d X509_INFO objects", num);
92 if (BIO_reset(bp) != 1)
93 errx(1, "BIO_reset");
94
95 /* Populate stack and test again with bogus input. */
96
97 if ((info0 = X509_INFO_new()) == NULL)
98 err(1, "X509_INFO_new");
99 info0->references = 2; /* X509_INFO_up_ref(3) doesn't exist. */
100 if (sk_X509_INFO_push(skin, info0) != 1)
101 err(1, "sk_X509_INFO_push");
102 if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) != NULL)
103 errx(1, "success with bogus input on second try");
104 if ((num = sk_X509_INFO_num(skin)) != 1)
105 errx(1, "bogus input changed stack size from 1 to %d", num);
106 if (sk_X509_INFO_value(skin, 0) != info0)
107 errx(1, "bogus input changed stack content");
108 if (info0->references != 2) {
109 warnx("bogus input changed ref count from 2 to %d",
110 info0->references);
111 info0->references = 2;
112 errcount++;
113 }
114 BIO_free(bp);
115
116 /* Use a real certificate object. */
117
118 if ((bp = BIO_new_mem_buf(cert_pem, strlen(cert_pem))) == NULL)
119 err(1, "BIO_new_mem_buf(cert_pem)");
120 if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) == NULL) {
121 errdata = NULL;
122 errflags = 0;
123 while ((errcode = ERR_get_error_line_data(NULL, NULL,
124 &errdata, &errflags)) != 0)
125 if (errdata != NULL && (errflags & ERR_TXT_STRING))
126 warnx("%s --- %s",
127 ERR_error_string(errcode, NULL),
128 errdata);
129 else
130 warnx("%s", ERR_error_string(errcode, NULL));
131 err(1, "real input: parsing failed");
132 }
133 if (skout != skin)
134 errx(1, "real input did not return the same stack");
135 skout = NULL;
136 if ((num = sk_X509_INFO_num(skin)) != 2)
137 errx(1, "real input changed stack size from 1 to %d", num);
138 if (sk_X509_INFO_value(skin, 0) != info0)
139 errx(1, "real input changed stack content");
140 if (info0->references != 2)
141 errx(1, "real input changed ref count from 2 to %d",
142 info0->references);
143 info1 = sk_X509_INFO_pop(skin);
144 if (info1->x509 == NULL)
145 errx(1, "real input did not create a certificate");
146 X509_INFO_free(info1);
147 info1 = NULL;
148 BIO_free(bp);
149
150 /* Two real certificates followed by bogus input. */
151
152 if ((bp = BIO_new(BIO_s_mem())) == NULL)
153 err(1, "BIO_new");
154 if (BIO_puts(bp, cert_pem) != strlen(cert_pem))
155 err(1, "BIO_puts(cert_pem) first copy");
156 if (BIO_puts(bp, cert_pem) != strlen(cert_pem))
157 err(1, "BIO_puts(cert_pem) second copy");
158 if (BIO_puts(bp, bogus_pem) != strlen(bogus_pem))
159 err(1, "BIO_puts(bogus_pem)");
160 if ((skout = PEM_X509_INFO_read_bio(bp, skin, NULL, NULL)) != NULL)
161 errx(1, "success with real + bogus input");
162 if ((num = sk_X509_INFO_num(skin)) != 1) {
163 warnx("real + bogus input changed stack size from 1 to %d",
164 num);
165 while (sk_X509_INFO_num(skin) > 1)
166 sk_X509_INFO_pop(skin);
167 errcount++;
168 }
169 if (sk_X509_INFO_value(skin, 0) != info0)
170 errx(1, "real + bogus input changed stack content");
171 if (info0->references != 2) {
172 warnx("real + bogus input changed ref count from 2 to %d",
173 info0->references);
174 errcount++;
175 }
176 BIO_free(bp);
177 info0->references = 1;
178 X509_INFO_free(info0);
179 sk_X509_INFO_free(skin);
180
181 if (errcount > 0)
182 errx(1, "%d errors detected", errcount);
183 return 0;
184}