]> git.ipfire.org Git - thirdparty/openssl.git/blame - test/verify_extra_test.c
In OpenSSL builds, declare STACK for datatypes ...
[thirdparty/openssl.git] / test / verify_extra_test.c
CommitLineData
593e9c63 1/*
33388b44 2 * Copyright 2015-2020 The OpenSSL Project Authors. All Rights Reserved.
593e9c63 3 *
909f1a2e 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
440e5d80
RS
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
593e9c63
MC
8 */
9
10#include <stdio.h>
ccf45361 11#include <string.h>
593e9c63
MC
12#include <openssl/crypto.h>
13#include <openssl/bio.h>
14#include <openssl/x509.h>
15#include <openssl/pem.h>
16#include <openssl/err.h>
4afc6060 17#include "testutil.h"
593e9c63 18
852c2ed2
RS
19DEFINE_STACK_OF(X509)
20
ad887416
P
21static const char *roots_f;
22static const char *untrusted_f;
23static const char *bad_f;
bc42bd62 24static const char *req_f;
ad887416 25
593e9c63
MC
26static STACK_OF(X509) *load_certs_from_file(const char *filename)
27{
28 STACK_OF(X509) *certs;
29 BIO *bio;
30 X509 *x;
31
32 bio = BIO_new_file(filename, "r");
33
34 if (bio == NULL) {
35 return NULL;
36 }
37
38 certs = sk_X509_new_null();
39 if (certs == NULL) {
40 BIO_free(bio);
41 return NULL;
42 }
43
44 ERR_set_mark();
45 do {
46 x = PEM_read_bio_X509(bio, NULL, 0, NULL);
47 if (x != NULL && !sk_X509_push(certs, x)) {
48 sk_X509_pop_free(certs, X509_free);
49 BIO_free(bio);
50 return NULL;
51 } else if (x == NULL) {
52 /*
53 * We probably just ran out of certs, so ignore any errors
54 * generated
55 */
56 ERR_pop_to_mark();
57 }
58 } while (x != NULL);
59
60 BIO_free(bio);
61
62 return certs;
63}
64
65/*
66 * Test for CVE-2015-1793 (Alternate Chains Certificate Forgery)
67 *
68 * Chain is as follows:
69 *
70 * rootCA (self-signed)
71 * |
72 * interCA
73 * |
74 * subinterCA subinterCA (self-signed)
75 * | |
76 * leaf ------------------
77 * |
78 * bad
79 *
80 * rootCA, interCA, subinterCA, subinterCA (ss) all have CA=TRUE
81 * leaf and bad have CA=FALSE
82 *
83 * subinterCA and subinterCA (ss) have the same subject name and keys
84 *
85 * interCA (but not rootCA) and subinterCA (ss) are in the trusted store
86 * (roots.pem)
87 * leaf and subinterCA are in the untrusted list (untrusted.pem)
88 * bad is the certificate being verified (bad.pem)
89 *
90 * Versions vulnerable to CVE-2015-1793 will fail to detect that leaf has
91 * CA=FALSE, and will therefore incorrectly verify bad
92 *
93 */
ad887416 94static int test_alt_chains_cert_forgery(void)
593e9c63
MC
95{
96 int ret = 0;
97 int i;
98 X509 *x = NULL;
99 STACK_OF(X509) *untrusted = NULL;
100 BIO *bio = NULL;
101 X509_STORE_CTX *sctx = NULL;
102 X509_STORE *store = NULL;
103 X509_LOOKUP *lookup = NULL;
104
105 store = X509_STORE_new();
106 if (store == NULL)
107 goto err;
108
109 lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file());
110 if (lookup == NULL)
111 goto err;
28b86f31 112 if (!X509_LOOKUP_load_file(lookup, roots_f, X509_FILETYPE_PEM))
593e9c63
MC
113 goto err;
114
e9daa815 115 untrusted = load_certs_from_file(untrusted_f);
593e9c63 116
e9daa815 117 if ((bio = BIO_new_file(bad_f, "r")) == NULL)
593e9c63
MC
118 goto err;
119
28b86f31 120 if ((x = PEM_read_bio_X509(bio, NULL, 0, NULL)) == NULL)
593e9c63
MC
121 goto err;
122
123 sctx = X509_STORE_CTX_new();
124 if (sctx == NULL)
125 goto err;
126
127 if (!X509_STORE_CTX_init(sctx, store, x, untrusted))
128 goto err;
129
130 i = X509_verify_cert(sctx);
131
e8aa8b6c 132 if (i == 0 && X509_STORE_CTX_get_error(sctx) == X509_V_ERR_INVALID_CA) {
593e9c63
MC
133 /* This is the result we were expecting: Test passed */
134 ret = 1;
135 }
136 err:
137 X509_STORE_CTX_free(sctx);
138 X509_free(x);
139 BIO_free(bio);
140 sk_X509_pop_free(untrusted, X509_free);
141 X509_STORE_free(store);
593e9c63
MC
142 return ret;
143}
144
7f6dfa19
MC
145static int test_store_ctx(void)
146{
147 X509_STORE_CTX *sctx = NULL;
148 X509 *x = NULL;
149 BIO *bio = NULL;
150 int testresult = 0, ret;
151
152 bio = BIO_new_file(bad_f, "r");
153 if (bio == NULL)
154 goto err;
155
156 x = PEM_read_bio_X509(bio, NULL, 0, NULL);
157 if (x == NULL)
158 goto err;
159
160 sctx = X509_STORE_CTX_new();
161 if (sctx == NULL)
162 goto err;
163
164 if (!X509_STORE_CTX_init(sctx, NULL, x, NULL))
165 goto err;
166
167 /* Verifying a cert where we have no trusted certs should fail */
168 ret = X509_verify_cert(sctx);
169
170 if (ret == 0) {
171 /* This is the result we were expecting: Test passed */
172 testresult = 1;
173 }
174
175 err:
176 X509_STORE_CTX_free(sctx);
177 X509_free(x);
178 BIO_free(bio);
179 return testresult;
180}
181
a43ce58f
SL
182OPT_TEST_DECLARE_USAGE("roots.pem untrusted.pem bad.pem\n")
183
fda127be 184static int test_distinguishing_id(void)
ccf45361 185{
ccf45361
PY
186 X509 *x = NULL;
187 BIO *bio = NULL;
188 int ret = 0;
189 ASN1_OCTET_STRING *v = NULL, *v2 = NULL;
fda127be 190 char *distid = "this is an ID";
ccf45361
PY
191
192 bio = BIO_new_file(bad_f, "r");
193 if (bio == NULL)
194 goto err;
195
196 x = PEM_read_bio_X509(bio, NULL, 0, NULL);
197 if (x == NULL)
198 goto err;
199
200 v = ASN1_OCTET_STRING_new();
201 if (v == NULL)
202 goto err;
203
fda127be
RL
204 if (!ASN1_OCTET_STRING_set(v, (unsigned char *)distid,
205 (int)strlen(distid))) {
ccf45361
PY
206 ASN1_OCTET_STRING_free(v);
207 goto err;
208 }
209
fda127be 210 X509_set0_distinguishing_id(x, v);
ccf45361 211
fda127be 212 v2 = X509_get0_distinguishing_id(x);
ccf45361
PY
213 if (!TEST_ptr(v2)
214 || !TEST_int_eq(ASN1_OCTET_STRING_cmp(v, v2), 0))
215 goto err;
216
217 ret = 1;
218 err:
219 X509_free(x);
220 BIO_free(bio);
221 return ret;
222}
bc42bd62 223
fda127be 224static int test_req_distinguishing_id(void)
bc42bd62 225{
bc42bd62
PY
226 X509_REQ *x = NULL;
227 BIO *bio = NULL;
228 int ret = 0;
229 ASN1_OCTET_STRING *v = NULL, *v2 = NULL;
fda127be 230 char *distid = "this is an ID";
bc42bd62
PY
231
232 bio = BIO_new_file(req_f, "r");
233 if (bio == NULL)
234 goto err;
235
236 x = PEM_read_bio_X509_REQ(bio, NULL, 0, NULL);
237 if (x == NULL)
238 goto err;
239
240 v = ASN1_OCTET_STRING_new();
241 if (v == NULL)
242 goto err;
243
fda127be
RL
244 if (!ASN1_OCTET_STRING_set(v, (unsigned char *)distid,
245 (int)strlen(distid))) {
bc42bd62
PY
246 ASN1_OCTET_STRING_free(v);
247 goto err;
248 }
249
fda127be 250 X509_REQ_set0_distinguishing_id(x, v);
bc42bd62 251
fda127be 252 v2 = X509_REQ_get0_distinguishing_id(x);
bc42bd62
PY
253 if (!TEST_ptr(v2)
254 || !TEST_int_eq(ASN1_OCTET_STRING_cmp(v, v2), 0))
255 goto err;
256
257 ret = 1;
258 err:
259 X509_REQ_free(x);
260 BIO_free(bio);
261 return ret;
262}
ccf45361 263
ad887416 264int setup_tests(void)
593e9c63 265{
8d242823
MC
266 if (!test_skip_common_options()) {
267 TEST_error("Error parsing test options\n");
268 return 0;
269 }
270
ad887416
P
271 if (!TEST_ptr(roots_f = test_get_argument(0))
272 || !TEST_ptr(untrusted_f = test_get_argument(1))
bc42bd62
PY
273 || !TEST_ptr(bad_f = test_get_argument(2))
274 || !TEST_ptr(req_f = test_get_argument(3)))
ad887416 275 return 0;
593e9c63 276
ad887416 277 ADD_TEST(test_alt_chains_cert_forgery);
7f6dfa19 278 ADD_TEST(test_store_ctx);
fda127be
RL
279 ADD_TEST(test_distinguishing_id);
280 ADD_TEST(test_req_distinguishing_id);
ad887416 281 return 1;
593e9c63 282}