diff options
author | job <> | 2023-04-25 21:51:44 +0000 |
---|---|---|
committer | job <> | 2023-04-25 21:51:44 +0000 |
commit | b21c79476f497aaeb7b5ebb90221f72ae63a98a8 (patch) | |
tree | 42e030bfcee71cc82e67c2b2315f64615b2a59af /src | |
parent | 2f530dfc75f9e3b3e36457e1a84e334001f1818a (diff) | |
download | openbsd-b21c79476f497aaeb7b5ebb90221f72ae63a98a8.tar.gz openbsd-b21c79476f497aaeb7b5ebb90221f72ae63a98a8.tar.bz2 openbsd-b21c79476f497aaeb7b5ebb90221f72ae63a98a8.zip |
Add regress test for invalidation of DER cache in select X509 setter functions
Diffstat (limited to 'src')
-rw-r--r-- | src/regress/lib/libcrypto/x509/Makefile | 7 | ||||
-rw-r--r-- | src/regress/lib/libcrypto/x509/dercache.c | 195 |
2 files changed, 200 insertions, 2 deletions
diff --git a/src/regress/lib/libcrypto/x509/Makefile b/src/regress/lib/libcrypto/x509/Makefile index 8b659b7f09..6e4c35f550 100644 --- a/src/regress/lib/libcrypto/x509/Makefile +++ b/src/regress/lib/libcrypto/x509/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | # $OpenBSD: Makefile,v 1.16 2023/03/02 21:15:14 tb Exp $ | 1 | # $OpenBSD: Makefile,v 1.17 2023/04/25 21:51:44 job Exp $ |
2 | 2 | ||
3 | PROGS = constraints verify x509attribute x509name x509req_ext callback | 3 | PROGS = constraints verify x509attribute x509name x509req_ext callback |
4 | PROGS += expirecallback callbackfailures | 4 | PROGS += expirecallback callbackfailures dercache |
5 | LDADD = -lcrypto | 5 | LDADD = -lcrypto |
6 | DPADD = ${LIBCRYPTO} | 6 | DPADD = ${LIBCRYPTO} |
7 | 7 | ||
@@ -24,6 +24,9 @@ CLEANFILES += x509name.result callback.out | |||
24 | . endif | 24 | . endif |
25 | .endif | 25 | .endif |
26 | 26 | ||
27 | run-regress-dercache: dercache | ||
28 | ./dercache | ||
29 | |||
27 | run-regress-verify: verify | 30 | run-regress-verify: verify |
28 | perl ${.CURDIR}/make-dir-roots.pl ${.CURDIR}/../certs . | 31 | perl ${.CURDIR}/make-dir-roots.pl ${.CURDIR}/../certs . |
29 | ./verify ${.CURDIR}/../certs | 32 | ./verify ${.CURDIR}/../certs |
diff --git a/src/regress/lib/libcrypto/x509/dercache.c b/src/regress/lib/libcrypto/x509/dercache.c new file mode 100644 index 0000000000..d84cb0831f --- /dev/null +++ b/src/regress/lib/libcrypto/x509/dercache.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* $OpenBSD: dercache.c,v 1.1 2023/04/25 21:51:44 job Exp $ */ | ||
2 | /* | ||
3 | * Copyright (c) 2023 Job Snijders <job@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 | /* | ||
19 | * This program tests whether the presence of "->enc.modified = 1;" | ||
20 | * in select X509 setter functions properly triggers invalidation of cached | ||
21 | * DER. | ||
22 | */ | ||
23 | |||
24 | #include <err.h> | ||
25 | #include <stdio.h> | ||
26 | #include <string.h> | ||
27 | |||
28 | #include <openssl/evp.h> | ||
29 | #include <openssl/rsa.h> | ||
30 | #include <openssl/x509.h> | ||
31 | |||
32 | #define SETUP() \ | ||
33 | derp = der; \ | ||
34 | if ((a = d2i_X509(NULL, &derp, dersz)) == NULL) \ | ||
35 | errx(1, "d2i_X509"); \ | ||
36 | if ((der2sz = i2d_X509(a, &der2)) <= 0) \ | ||
37 | errx(1, "i2d_X509"); \ | ||
38 | der2p = der2; | ||
39 | |||
40 | #define CLEANUP() \ | ||
41 | X509_free(a); \ | ||
42 | a = NULL; \ | ||
43 | free(der2); \ | ||
44 | der2 = NULL; | ||
45 | |||
46 | #define CLEANUPSETUP() \ | ||
47 | CLEANUP() \ | ||
48 | SETUP() | ||
49 | |||
50 | #define SETX509NAME(fname, value, cert) \ | ||
51 | if ((xn = X509_NAME_new()) == NULL) \ | ||
52 | err(1, NULL); \ | ||
53 | if (!X509_NAME_add_entry_by_txt(xn, "C", MBSTRING_ASC, \ | ||
54 | (const unsigned char*) value, -1, -1, 0)) \ | ||
55 | errx(1, "X509_NAME_add_entry_by_txt"); \ | ||
56 | if (!fname(cert, xn)) \ | ||
57 | errx(1, "fname"); \ | ||
58 | X509_NAME_free(xn); \ | ||
59 | xn = NULL; | ||
60 | |||
61 | #define SETASN1TIME(fname, value, cert) \ | ||
62 | if ((at = ASN1_TIME_new()) == NULL) \ | ||
63 | err(1, NULL); \ | ||
64 | if ((at = X509_gmtime_adj(NULL, value)) == NULL) \ | ||
65 | errx(1, "X509_gmtime_adj"); \ | ||
66 | if (!fname(cert, at)) \ | ||
67 | errx(1, "fname"); \ | ||
68 | ASN1_TIME_free(at); \ | ||
69 | at = NULL; | ||
70 | |||
71 | #define SETINTEGER(fname, value, cert) \ | ||
72 | if ((ai = ASN1_INTEGER_new()) == NULL) \ | ||
73 | err(1, NULL); \ | ||
74 | if (!ASN1_INTEGER_set(ai, value)) \ | ||
75 | errx(1, "ASN1_INTEGER_set"); \ | ||
76 | if (!fname(cert, ai)) \ | ||
77 | errx(1, "fname"); \ | ||
78 | ASN1_INTEGER_free(ai); \ | ||
79 | ai = NULL; | ||
80 | |||
81 | |||
82 | static int | ||
83 | x509_compare(char *f, X509 *a, const unsigned char *der, long dersz) | ||
84 | { | ||
85 | unsigned char *der_test = NULL; | ||
86 | long der_testsz; | ||
87 | int rc = 0; | ||
88 | |||
89 | if ((der_testsz = i2d_X509(a, &der_test)) <= 0) | ||
90 | errx(1, "i2d_X509"); | ||
91 | |||
92 | if (dersz == der_testsz) { | ||
93 | if (memcmp(der, der_test, dersz) == 0) { | ||
94 | warnx("%s() didn't invalidate DER cache", f); | ||
95 | rc = 1; | ||
96 | } else | ||
97 | warnx("%s() OK", f); | ||
98 | } else | ||
99 | warnx("%s() OK", f); | ||
100 | |||
101 | free(der_test); | ||
102 | return rc; | ||
103 | } | ||
104 | |||
105 | int | ||
106 | main(void) | ||
107 | { | ||
108 | ASN1_INTEGER *ai = NULL; | ||
109 | ASN1_TIME *at = NULL; | ||
110 | EVP_PKEY *pkey = NULL; | ||
111 | EVP_PKEY_CTX *pkey_ctx = NULL; | ||
112 | X509_NAME *xn = NULL; | ||
113 | X509 *a, *x; | ||
114 | const unsigned char *derp, *der2p; | ||
115 | unsigned char *der = NULL, *der2 = NULL; | ||
116 | long dersz, der2sz; | ||
117 | int ret = 0; | ||
118 | |||
119 | if ((x = X509_new()) == NULL) | ||
120 | err(1, NULL); | ||
121 | |||
122 | if ((pkey_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL)) == NULL) | ||
123 | errx(1, "EVP_PKEY_CTX_new_id"); | ||
124 | if (EVP_PKEY_keygen_init(pkey_ctx) != 1) | ||
125 | errx(1, "EVP_PKEY_keygen_init"); | ||
126 | if (EVP_PKEY_CTX_set_rsa_keygen_bits(pkey_ctx, 2048) <= 0) | ||
127 | errx(1, "EVP_PKEY_CTX_set_rsa_keygen_bits"); | ||
128 | if (EVP_PKEY_keygen(pkey_ctx, &pkey) <= 0) | ||
129 | errx(1, "EVP_PKEY_keygen"); | ||
130 | if (X509_set_pubkey(x, pkey) != 1) | ||
131 | errx(1, "X509_set_pubkey"); | ||
132 | |||
133 | SETINTEGER(X509_set_serialNumber, 1, x) | ||
134 | SETASN1TIME(X509_set_notBefore, 0, x) | ||
135 | SETASN1TIME(X509_set_notAfter, 60, x) | ||
136 | SETX509NAME(X509_set_issuer_name, "NL", x) | ||
137 | SETX509NAME(X509_set_subject_name, "BE", x) | ||
138 | |||
139 | // one time creation of the original DER | ||
140 | if (!X509_sign(x, pkey, EVP_sha256())) | ||
141 | errx(1, "X509_sign"); | ||
142 | if ((dersz = i2d_X509(x, &der)) <= 0) | ||
143 | errx(1, "i2d_X509"); | ||
144 | |||
145 | SETUP() | ||
146 | |||
147 | // test X509_set_version | ||
148 | if (!X509_set_version(a, 2)) | ||
149 | errx(1, "X509_set_version"); | ||
150 | ret += x509_compare("X509_set_version", a, der2p, der2sz); | ||
151 | |||
152 | CLEANUPSETUP() | ||
153 | |||
154 | // test X509_set_serialNumber | ||
155 | SETINTEGER(X509_set_serialNumber, 2, a) | ||
156 | ret += x509_compare("X509_set_serialNumber", a, der2p, der2sz); | ||
157 | |||
158 | CLEANUPSETUP() | ||
159 | |||
160 | // test X509_set_issuer_name | ||
161 | SETX509NAME(X509_set_issuer_name, "DE", a) | ||
162 | ret += x509_compare("X509_set_issuer_name", a, der2p, der2sz); | ||
163 | |||
164 | CLEANUPSETUP() | ||
165 | |||
166 | // test X509_set_subject_name | ||
167 | SETX509NAME(X509_set_subject_name, "FR", a) | ||
168 | ret += x509_compare("X509_set_subject_name", a, der2p, der2sz); | ||
169 | |||
170 | CLEANUPSETUP() | ||
171 | |||
172 | // test X509_set_notBefore | ||
173 | SETASN1TIME(X509_set_notBefore, 120, a) | ||
174 | ret += x509_compare("X509_set_notBefore", a, der2p, der2sz); | ||
175 | |||
176 | CLEANUPSETUP() | ||
177 | |||
178 | // test X509_set_notAfter | ||
179 | SETASN1TIME(X509_set_notAfter, 180, a) | ||
180 | ret += x509_compare("X509_set_notAfter", a, der2p, der2sz); | ||
181 | |||
182 | CLEANUPSETUP() | ||
183 | |||
184 | // test X509_set_pubkey | ||
185 | if (EVP_PKEY_keygen(pkey_ctx, &pkey) <= 0) | ||
186 | errx(1, "EVP_PKEY_keygen"); | ||
187 | if (X509_set_pubkey(a, pkey) != 1) | ||
188 | errx(1, "X509_set_pubkey"); | ||
189 | ret += x509_compare("X509_set_pubkey", a, der2p, der2sz); | ||
190 | |||
191 | CLEANUP() | ||
192 | |||
193 | if (ret) | ||
194 | return 1; | ||
195 | } | ||