summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjsing <>2022-01-30 18:38:41 +0000
committerjsing <>2022-01-30 18:38:41 +0000
commit90bd8d8a0aaecfe43c384a58aedb9f0ddc7b187d (patch)
tree9dc550ccf6fd38e8963c6c7b1d3efc7e8efdea7b
parent1bfc624a0460beb64b4c1dfe3c01302d295b4591 (diff)
downloadopenbsd-90bd8d8a0aaecfe43c384a58aedb9f0ddc7b187d.tar.gz
openbsd-90bd8d8a0aaecfe43c384a58aedb9f0ddc7b187d.tar.bz2
openbsd-90bd8d8a0aaecfe43c384a58aedb9f0ddc7b187d.zip
Add initial regress for tls_signer.
-rw-r--r--src/regress/lib/libtls/Makefile3
-rw-r--r--src/regress/lib/libtls/signer/Makefile17
-rw-r--r--src/regress/lib/libtls/signer/signertest.c286
3 files changed, 305 insertions, 1 deletions
diff --git a/src/regress/lib/libtls/Makefile b/src/regress/lib/libtls/Makefile
index 7c4d152223..8b74915df9 100644
--- a/src/regress/lib/libtls/Makefile
+++ b/src/regress/lib/libtls/Makefile
@@ -1,8 +1,9 @@
1# $OpenBSD: Makefile,v 1.6 2018/11/09 19:24:50 tb Exp $ 1# $OpenBSD: Makefile,v 1.7 2022/01/30 18:38:41 jsing Exp $
2 2
3SUBDIR += config 3SUBDIR += config
4SUBDIR += keypair 4SUBDIR += keypair
5SUBDIR += gotls 5SUBDIR += gotls
6SUBDIR += signer
6SUBDIR += tls 7SUBDIR += tls
7SUBDIR += verify 8SUBDIR += verify
8 9
diff --git a/src/regress/lib/libtls/signer/Makefile b/src/regress/lib/libtls/signer/Makefile
new file mode 100644
index 0000000000..b26141728c
--- /dev/null
+++ b/src/regress/lib/libtls/signer/Makefile
@@ -0,0 +1,17 @@
1# $OpenBSD: Makefile,v 1.1 2022/01/30 18:38:41 jsing Exp $
2
3PROG= signertest
4LDADD= -lcrypto -lssl -ltls
5DPADD= ${LIBCRYPTO} ${LIBSSL} ${LIBTLS}
6
7WARNINGS= Yes
8CFLAGS+= -DLIBRESSL_INTERNAL -Wall -Wundef -Werror
9
10REGRESS_TARGETS= \
11 regress-signertest
12
13regress-signertest: ${PROG}
14 ./signertest \
15 ${.CURDIR}/../../libssl/certs
16
17.include <bsd.regress.mk>
diff --git a/src/regress/lib/libtls/signer/signertest.c b/src/regress/lib/libtls/signer/signertest.c
new file mode 100644
index 0000000000..ce8a0db8f5
--- /dev/null
+++ b/src/regress/lib/libtls/signer/signertest.c
@@ -0,0 +1,286 @@
1/* $OpenBSD: signertest.c,v 1.1 2022/01/30 18:38:41 jsing Exp $ */
2/*
3 * Copyright (c) 2018, 2022 Joel Sing <jsing@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 <sys/stat.h>
19
20#include <err.h>
21#include <fcntl.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <string.h>
25#include <unistd.h>
26
27#include <openssl/bio.h>
28#include <openssl/err.h>
29#include <openssl/pem.h>
30#include <openssl/x509.h>
31
32#include <tls.h>
33
34const char *cert_path;
35
36static void
37hexdump(const unsigned char *buf, size_t len)
38{
39 size_t i;
40
41 for (i = 1; i <= len; i++)
42 fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
43
44 fprintf(stderr, "\n");
45}
46
47static void
48load_file(const char *filename, const uint8_t **data, size_t *data_len)
49{
50 char *filepath;
51 struct stat sb;
52 uint8_t *buf;
53 size_t len;
54 ssize_t n;
55 int fd;
56
57 if (asprintf(&filepath, "%s/%s", cert_path, filename) == -1)
58 err(1, "asprintf");
59 if ((fd = open(filepath, O_RDONLY)) == -1)
60 err(1, "failed to open '%s'", filepath);
61 if ((fstat(fd, &sb)) == -1)
62 err(1, "failed to stat '%s'", filepath);
63 if (sb.st_size < 0)
64 err(1, "file size invalid for '%s'", filepath);
65 len = (size_t)sb.st_size;
66 if ((buf = malloc(len)) == NULL)
67 err(1, "out of memory");
68 n = read(fd, buf, len);
69 if (n < 0 || (size_t)n != len)
70 err(1, "failed to read '%s'", filepath);
71 close(fd);
72
73 *data = buf;
74 *data_len = len;
75
76 free(filepath);
77}
78
79static int
80compare_mem(char *label, const uint8_t *data1, size_t data1_len,
81 const uint8_t *data2, size_t data2_len)
82{
83 if (data1_len != data2_len) {
84 fprintf(stderr, "FAIL: %s length mismatch (%zu != %zu)\n",
85 label, data1_len, data2_len);
86 fprintf(stderr, "Got:\n");
87 hexdump(data1, data1_len);
88 fprintf(stderr, "Want:\n");
89 hexdump(data2, data2_len);
90 return -1;
91 }
92 if (data1 == data2) {
93 fprintf(stderr, "FAIL: %s comparing same memory (%p == %p)\n",
94 label, data1, data2);
95 return -1;
96 }
97 if (memcmp(data1, data2, data1_len) != 0) {
98 fprintf(stderr, "FAIL: %s data mismatch\n", label);
99 fprintf(stderr, "Got:\n");
100 hexdump(data1, data1_len);
101 fprintf(stderr, "Want:\n");
102 hexdump(data2, data2_len);
103 return -1;
104 }
105 return 0;
106}
107
108const char *server_ecdsa_pubkey_hash = \
109 "SHA256:cef2616ece9a57a76d072013b0faad2232511487c67c45bf00fbcecc070e2f5b";
110const char *server_rsa_pubkey_hash = \
111 "SHA256:f03c535d374614e7356c0a4e6fd37fe94297b60ed86212adcba40e8e0b07bc9f";
112const char *server_unknown_pubkey_hash = \
113 "SHA256:f03c535d374614e7356c0a4e6fd37fe94297b60ed86212adcba40e8e0b07bc9e";
114
115const uint8_t test_digest[] = {
116 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
117 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
118 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
119 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
120};
121
122const uint8_t test_rsa_signature[] = {
123 0x77, 0xfb, 0xdd, 0x41, 0x45, 0x40, 0x25, 0xd6,
124 0x01, 0xe0, 0x59, 0x04, 0x65, 0xae, 0xa1, 0x59,
125 0xae, 0xa2, 0x44, 0x08, 0xf7, 0x02, 0x3d, 0xe4,
126 0xc6, 0x0d, 0x4d, 0x9a, 0x3a, 0xce, 0x34, 0xbe,
127 0x2e, 0xc0, 0xfc, 0xbd, 0x5b, 0x21, 0xe4, 0xbb,
128 0xce, 0x02, 0xfd, 0xc3, 0xfc, 0x3d, 0x25, 0xe7,
129 0xd1, 0x9a, 0x13, 0x60, 0xcb, 0x07, 0xda, 0x23,
130 0xf7, 0xa3, 0xf0, 0xaf, 0x16, 0x1b, 0x28, 0x54,
131 0x0a, 0x3c, 0xc1, 0x31, 0x08, 0x0f, 0x2f, 0xce,
132 0x6d, 0x09, 0x45, 0x48, 0xee, 0x37, 0xa8, 0xc3,
133 0x91, 0xcb, 0xde, 0xad, 0xc6, 0xcf, 0x18, 0x19,
134 0xeb, 0xad, 0x08, 0x66, 0x2f, 0xce, 0x1d, 0x07,
135 0xe3, 0x03, 0x84, 0x00, 0xca, 0x0f, 0x1d, 0x0f,
136 0x0e, 0x6e, 0x54, 0xc1, 0x39, 0x3f, 0x2a, 0x78,
137 0xc8, 0xa3, 0x6d, 0x52, 0xb9, 0x26, 0x8e, 0x7e,
138 0x7a, 0x18, 0x3c, 0x8a, 0x50, 0xa3, 0xad, 0xab,
139 0xd0, 0x03, 0xc5, 0x3e, 0xa5, 0x46, 0x87, 0xb0,
140 0x03, 0xde, 0xd9, 0xe5, 0x4d, 0x73, 0x95, 0xcf,
141 0xe1, 0x59, 0x8e, 0x2e, 0x50, 0x69, 0xe6, 0x20,
142 0xaf, 0x21, 0x4f, 0xe6, 0xc4, 0x86, 0x11, 0x36,
143 0x79, 0x68, 0x83, 0xde, 0x0e, 0x81, 0xde, 0x2e,
144 0xd0, 0x19, 0x3f, 0x4b, 0xad, 0x3e, 0xbf, 0xdd,
145 0x14, 0x4d, 0x66, 0xf3, 0x7f, 0x7d, 0xca, 0xed,
146 0x99, 0x62, 0xdc, 0x7c, 0xb2, 0x8b, 0x57, 0xcb,
147 0xdf, 0xed, 0x16, 0x13, 0x86, 0xd8, 0xd8, 0xb4,
148 0x44, 0x6e, 0xd5, 0x54, 0xbc, 0xdf, 0xe7, 0x34,
149 0x10, 0xa4, 0x17, 0x5f, 0xb7, 0xe1, 0x33, 0x2c,
150 0xc1, 0x70, 0x5b, 0x87, 0x0d, 0x39, 0xee, 0xe8,
151 0xec, 0x18, 0x92, 0xe8, 0x95, 0xa8, 0x93, 0x26,
152 0xdf, 0x26, 0x93, 0x96, 0xfd, 0xad, 0x81, 0xb6,
153 0xeb, 0x72, 0x9c, 0xd4, 0xcc, 0xf6, 0x9f, 0xb0,
154 0xbb, 0xbd, 0xbd, 0x44, 0x1c, 0x99, 0x07, 0x6d,
155};
156
157static int
158do_signer_tests(void)
159{
160 char *server_rsa_filepath = NULL;
161 const uint8_t *server_ecdsa = NULL;
162 size_t server_ecdsa_len;
163 struct tls_signer *signer = NULL;
164 uint8_t *signature = NULL;
165 size_t signature_len;
166 EC_KEY *ec_key = NULL;
167 X509 *x509 = NULL;
168 BIO *bio = NULL;
169 int failed = 1;
170
171 load_file("server1-ecdsa.pem", &server_ecdsa, &server_ecdsa_len);
172
173 if (asprintf(&server_rsa_filepath, "%s/%s", cert_path,
174 "server1-rsa.pem") == -1) {
175 fprintf(stderr, "FAIL: failed to build rsa file path\n");
176 goto failure;
177 }
178
179 /* Load the ECDSA public key - we'll need it later. */
180 if ((bio = BIO_new_mem_buf(server_ecdsa, server_ecdsa_len)) == NULL) {
181 fprintf(stderr, "FAIL: failed to create bio\n");
182 goto failure;
183 }
184 if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) {
185 fprintf(stderr, "FAIL: failed to load certificate\n");
186 goto failure;
187 }
188 if ((ec_key = EVP_PKEY_get1_EC_KEY(X509_get0_pubkey(x509))) == NULL) {
189 fprintf(stderr, "FAIL: failed to get EC public key\n");
190 goto failure;
191 }
192
193 /* Create signer and add key pairs (one ECDSA, one RSA). */
194 if ((signer = tls_signer_new()) == NULL) {
195 fprintf(stderr, "FAIL: failed to create tls signer\n");
196 goto failure;
197 }
198 if (tls_signer_add_keypair_mem(signer, server_ecdsa, server_ecdsa_len,
199 server_ecdsa, server_ecdsa_len) == -1) {
200 fprintf(stderr, "FAIL: failed to add ECDSA keypair to tls "
201 "signer: %s\n", tls_signer_error(signer));
202 goto failure;
203 }
204 if (tls_signer_add_keypair_file(signer, server_rsa_filepath,
205 server_rsa_filepath) == -1) {
206 fprintf(stderr, "FAIL: failed to add RSA keypair to tls "
207 "signer: %s\n", tls_signer_error(signer));
208 goto failure;
209 }
210
211 /* Sign with RSA. */
212 if (tls_signer_sign(signer, server_rsa_pubkey_hash, test_digest,
213 sizeof(test_digest), &signature, &signature_len,
214 RSA_PKCS1_PADDING) == -1) {
215 fprintf(stderr, "FAIL: failed to sign with RSA key: %s\n",
216 tls_signer_error(signer));
217 goto failure;
218 }
219 if (compare_mem("rsa signature", signature, signature_len,
220 test_rsa_signature, sizeof(test_rsa_signature)) == -1)
221 goto failure;
222
223 free(signature);
224 signature = NULL;
225
226 /*
227 * Sign with ECDSA - ECDSA signatures are non-deterministic so we cannot
228 * check against a known value, rather we can only verify the signature.
229 */
230 if (tls_signer_sign(signer, server_ecdsa_pubkey_hash, test_digest,
231 sizeof(test_digest), &signature, &signature_len, 0) == -1) {
232 fprintf(stderr, "FAIL: failed to sign with ECDSA key: %s\n",
233 tls_signer_error(signer));
234 goto failure;
235 }
236 if (ECDSA_verify(0, test_digest, sizeof(test_digest), signature,
237 signature_len, ec_key) != 1) {
238 fprintf(stderr, "FAIL: failed to verify ECDSA signature\n");
239 goto failure;
240 }
241
242 free(signature);
243 signature = NULL;
244
245 /* Attempt to sign with an unknown cert pubkey hash. */
246 if (tls_signer_sign(signer, server_unknown_pubkey_hash, test_digest,
247 sizeof(test_digest), &signature, &signature_len, 0) != -1) {
248 fprintf(stderr, "FAIL: signing succeeded with unknown key\n");
249 goto failure;
250 }
251 if (strcmp(tls_signer_error(signer), "key not found") != 0) {
252 fprintf(stderr, "FAIL: got tls signer error '%s', want "
253 "'key not found'\n", tls_signer_error(signer));
254 goto failure;
255 }
256
257 failed = 0;
258
259 failure:
260 BIO_free(bio);
261 EC_KEY_free(ec_key);
262 X509_free(x509);
263 tls_signer_free(signer);
264 free((uint8_t *)server_ecdsa);
265 free(server_rsa_filepath);
266 free(signature);
267
268 return failed;
269}
270
271int
272main(int argc, char **argv)
273{
274 int failure = 0;
275
276 if (argc != 2) {
277 fprintf(stderr, "usage: %s certpath\n", argv[0]);
278 return (1);
279 }
280
281 cert_path = argv[1];
282
283 failure |= do_signer_tests();
284
285 return (failure);
286}