xref: /openbsd/regress/lib/libcrypto/asn1/asn1x509.c (revision 73471bf0)
1 /* $OpenBSD: asn1x509.c,v 1.1 2021/11/30 07:34:29 jsing Exp $ */
2 /*
3  * Copyright (c) 2017 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 <err.h>
19 #include <string.h>
20 
21 #include <openssl/asn1.h>
22 #include <openssl/bio.h>
23 #include <openssl/bn.h>
24 #include <openssl/dsa.h>
25 #include <openssl/ec.h>
26 #include <openssl/err.h>
27 #include <openssl/pem.h>
28 #include <openssl/rsa.h>
29 #include <openssl/x509.h>
30 
31 const char *dsa_test_key = \
32     "-----BEGIN DSA PRIVATE KEY-----\n" \
33     "MIH5AgEAAkEAt+CNNryEe8t2SkjuP0azjOKjSMXsw3GzjLS5c+vFLQKs0zIuPp8F\n" \
34     "I/z5t8vcNt/D8EyzQZWxgCfoasHqDOJvRwIVAKrJMyIMt9iJtaS31cyIJmIDVlZX\n" \
35     "AkEAs1/Uy+x0+1C1n7V3eJxuBdO/LUalbrZM5PfcwDshf9kcQNLsRu5zTZkU0OX/\n" \
36     "8xANz+ue2o6LON2sTAtuEfSM1QJBAIDRt0rQGGrFCRJ4O39Iqlf27yIO6Gq1ppbE\n" \
37     "Wvsvz4YSIZsG02vlBlzVIhULftNnkpN59MFtIjx8RsbEQ4YTnSICFDXPf/UIRvdH\n" \
38     "20NV++tnUZYUAXM+\n" \
39     "-----END DSA PRIVATE KEY-----\n";
40 
41 unsigned char dsa_test_asn1_pubkey[] = {
42 	0x30, 0x81, 0xf2, 0x30, 0x81, 0xa9, 0x06, 0x07,
43 	0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01, 0x30,
44 	0x81, 0x9d, 0x02, 0x41, 0x00, 0xb7, 0xe0, 0x8d,
45 	0x36, 0xbc, 0x84, 0x7b, 0xcb, 0x76, 0x4a, 0x48,
46 	0xee, 0x3f, 0x46, 0xb3, 0x8c, 0xe2, 0xa3, 0x48,
47 	0xc5, 0xec, 0xc3, 0x71, 0xb3, 0x8c, 0xb4, 0xb9,
48 	0x73, 0xeb, 0xc5, 0x2d, 0x02, 0xac, 0xd3, 0x32,
49 	0x2e, 0x3e, 0x9f, 0x05, 0x23, 0xfc, 0xf9, 0xb7,
50 	0xcb, 0xdc, 0x36, 0xdf, 0xc3, 0xf0, 0x4c, 0xb3,
51 	0x41, 0x95, 0xb1, 0x80, 0x27, 0xe8, 0x6a, 0xc1,
52 	0xea, 0x0c, 0xe2, 0x6f, 0x47, 0x02, 0x15, 0x00,
53 	0xaa, 0xc9, 0x33, 0x22, 0x0c, 0xb7, 0xd8, 0x89,
54 	0xb5, 0xa4, 0xb7, 0xd5, 0xcc, 0x88, 0x26, 0x62,
55 	0x03, 0x56, 0x56, 0x57, 0x02, 0x41, 0x00, 0xb3,
56 	0x5f, 0xd4, 0xcb, 0xec, 0x74, 0xfb, 0x50, 0xb5,
57 	0x9f, 0xb5, 0x77, 0x78, 0x9c, 0x6e, 0x05, 0xd3,
58 	0xbf, 0x2d, 0x46, 0xa5, 0x6e, 0xb6, 0x4c, 0xe4,
59 	0xf7, 0xdc, 0xc0, 0x3b, 0x21, 0x7f, 0xd9, 0x1c,
60 	0x40, 0xd2, 0xec, 0x46, 0xee, 0x73, 0x4d, 0x99,
61 	0x14, 0xd0, 0xe5, 0xff, 0xf3, 0x10, 0x0d, 0xcf,
62 	0xeb, 0x9e, 0xda, 0x8e, 0x8b, 0x38, 0xdd, 0xac,
63 	0x4c, 0x0b, 0x6e, 0x11, 0xf4, 0x8c, 0xd5, 0x03,
64 	0x44, 0x00, 0x02, 0x41, 0x00, 0x80, 0xd1, 0xb7,
65 	0x4a, 0xd0, 0x18, 0x6a, 0xc5, 0x09, 0x12, 0x78,
66 	0x3b, 0x7f, 0x48, 0xaa, 0x57, 0xf6, 0xef, 0x22,
67 	0x0e, 0xe8, 0x6a, 0xb5, 0xa6, 0x96, 0xc4, 0x5a,
68 	0xfb, 0x2f, 0xcf, 0x86, 0x12, 0x21, 0x9b, 0x06,
69 	0xd3, 0x6b, 0xe5, 0x06, 0x5c, 0xd5, 0x22, 0x15,
70 	0x0b, 0x7e, 0xd3, 0x67, 0x92, 0x93, 0x79, 0xf4,
71 	0xc1, 0x6d, 0x22, 0x3c, 0x7c, 0x46, 0xc6, 0xc4,
72 	0x43, 0x86, 0x13, 0x9d, 0x22,
73 };
74 
75 const char *ec_test_key = \
76     "-----BEGIN EC PRIVATE KEY-----\n" \
77     "MHcCAQEEIEDkF84aPdBNu4vbPE+QV3EP9ULp4Enr1N0lz4vzuc2boAoGCCqGSM49\n" \
78     "AwEHoUQDQgAEUQGHBjYwbfHvI3QqdDy8ftNU5UvQqh6TH6upIrtz4CVccxnWO2+s\n" \
79     "qSMOu1z5KnGIOVf2kLQ2S2iMahyFMezr8g==\n" \
80     "-----END EC PRIVATE KEY-----\n";
81 
82 unsigned char ec_test_asn1_pubkey[] = {
83 	0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86,
84 	0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a,
85 	0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
86 	0x42, 0x00, 0x04, 0x51, 0x01, 0x87, 0x06, 0x36,
87 	0x30, 0x6d, 0xf1, 0xef, 0x23, 0x74, 0x2a, 0x74,
88 	0x3c, 0xbc, 0x7e, 0xd3, 0x54, 0xe5, 0x4b, 0xd0,
89 	0xaa, 0x1e, 0x93, 0x1f, 0xab, 0xa9, 0x22, 0xbb,
90 	0x73, 0xe0, 0x25, 0x5c, 0x73, 0x19, 0xd6, 0x3b,
91 	0x6f, 0xac, 0xa9, 0x23, 0x0e, 0xbb, 0x5c, 0xf9,
92 	0x2a, 0x71, 0x88, 0x39, 0x57, 0xf6, 0x90, 0xb4,
93 	0x36, 0x4b, 0x68, 0x8c, 0x6a, 0x1c, 0x85, 0x31,
94 	0xec, 0xeb, 0xf2,
95 };
96 
97 const char *rsa_test_key = \
98     "-----BEGIN PRIVATE KEY-----\n" \
99     "MIIBVgIBADANBgkqhkiG9w0BAQEFAASCAUAwggE8AgEAAkEA4Fs6ljFFQw/ElDf5\n" \
100     "LTghVw972PVpQuKPQvwb1cWbV3+7W5sXOcoM/RvwzO7WeppkeltVCBoKaQd+9e2Z\n" \
101     "BHtYhwIDAQABAkEAhWv7dWIrrGvuHa8D0i51NU8R+b5IMOyHAfDnpMN1VByWcBdb\n" \
102     "G7ZJsEYlO1Tbx1zFQOVyrDUY2hn0YttPjWys0QIhAP9+FRhHCYye/EY14zSa+lxb\n" \
103     "ljOPjWgddMdJBcPOVNUNAiEA4M1QUtIcTnTnfvcxvEBIhbmSR8fRvZYAeT5EoTKM\n" \
104     "puMCIQD9898X8JRHWEg9qZabVWiBoO+ddJUD5jOLWsQGKvMbiQIgBOQyxTqRJxvg\n" \
105     "FaEnUeNMMKyzBCDS7X8gD4NNVvyUluUCIQC/lnO9xYi6S4BFMwHFEUY0jLr5vgsR\n" \
106     "+esRU9dLkMqt+w==\n" \
107     "-----END PRIVATE KEY-----\n";
108 
109 unsigned char rsa_test_asn1_pubkey[] = {
110 	0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
111 	0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
112 	0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41,
113 	0x00, 0xe0, 0x5b, 0x3a, 0x96, 0x31, 0x45, 0x43,
114 	0x0f, 0xc4, 0x94, 0x37, 0xf9, 0x2d, 0x38, 0x21,
115 	0x57, 0x0f, 0x7b, 0xd8, 0xf5, 0x69, 0x42, 0xe2,
116 	0x8f, 0x42, 0xfc, 0x1b, 0xd5, 0xc5, 0x9b, 0x57,
117 	0x7f, 0xbb, 0x5b, 0x9b, 0x17, 0x39, 0xca, 0x0c,
118 	0xfd, 0x1b, 0xf0, 0xcc, 0xee, 0xd6, 0x7a, 0x9a,
119 	0x64, 0x7a, 0x5b, 0x55, 0x08, 0x1a, 0x0a, 0x69,
120 	0x07, 0x7e, 0xf5, 0xed, 0x99, 0x04, 0x7b, 0x58,
121 	0x87, 0x02, 0x03, 0x01, 0x00, 0x01,
122 };
123 
124 static void
125 hexdump(const unsigned char *buf, size_t len)
126 {
127 	size_t i;
128 
129 	for (i = 1; i <= len; i++)
130 		fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
131 
132 	fprintf(stderr, "\n");
133 }
134 
135 static int
136 compare_data(const char *label, const unsigned char *d1, size_t d1_len,
137     const unsigned char *d2, size_t d2_len)
138 {
139 	if (d1_len != d2_len) {
140 		fprintf(stderr, "FAIL: got %s with length %zu, want %zu\n",
141 		    label, d1_len, d2_len);
142 		return -1;
143 	}
144 	if (memcmp(d1, d2, d1_len) != 0) {
145 		fprintf(stderr, "FAIL: %s differs\n", label);
146 		fprintf(stderr, "got:\n");
147 		hexdump(d1, d1_len);
148 		fprintf(stderr, "want:\n");
149 		hexdump(d2, d2_len);
150 		return -1;
151 	}
152 	return 0;
153 }
154 
155 static int
156 dsa_pubkey_test(void)
157 {
158 	EVP_PKEY *pkey_a = NULL, *pkey_b = NULL;
159 	unsigned char *out = NULL, *data = NULL;
160 	DSA *dsa_a = NULL, *dsa_b = NULL;
161 	const unsigned char *p;
162 	BIO *bio_mem = NULL;
163 	int failure = 1;
164 	int len;
165 
166 	if ((bio_mem = BIO_new_mem_buf((void *)dsa_test_key, -1)) == NULL)
167 		errx(1, "failed to create BIO");
168 
169 	if ((dsa_a = PEM_read_bio_DSAPrivateKey(bio_mem, NULL, NULL, NULL)) == NULL) {
170 		ERR_print_errors_fp(stderr);
171 		errx(1, "failed to decode DSA key from PEM");
172 	}
173 
174 	/*
175 	 * Test i2d_PUBKEY/d2i_PUBKEY.
176 	 */
177 	if ((pkey_a = EVP_PKEY_new()) == NULL)
178 		errx(1, "failed to create EVP_PKEY");
179 	if (!EVP_PKEY_set1_DSA(pkey_a, dsa_a))
180 		errx(1, "failed to set DSA on EVP_PKEY");
181 
182 	if ((len = i2d_PUBKEY(pkey_a, &out)) < 0) {
183 		fprintf(stderr, "FAIL: i2d_PUBKEY failed\n");
184 		goto done;
185 	}
186 	if (compare_data("DSA PUBKEY", out, len, dsa_test_asn1_pubkey,
187 	    sizeof(dsa_test_asn1_pubkey)) == -1)
188 		goto done;
189 
190 	p = out;
191 	if ((pkey_b = d2i_PUBKEY(NULL, &p, len)) == NULL) {
192 		fprintf(stderr, "FAIL: d2i_PUBKEY failed\n");
193 		goto done;
194 	}
195 
196 	if (BN_cmp(pkey_a->pkey.dsa->pub_key, pkey_b->pkey.dsa->pub_key) != 0) {
197 		fprintf(stderr, "FAIL: DSA public keys mismatch\n");
198 		goto done;
199 	}
200 
201 	free(out);
202 	out = NULL;
203 
204 	/*
205 	 * Test i2d_DSA_PUBKEY/d2i_DSA_PUBKEY.
206 	 */
207 
208 	if ((len = i2d_DSA_PUBKEY(dsa_a, &out)) < 0) {
209 		fprintf(stderr, "FAIL: i2d_DSA_PUBKEY failed\n");
210 		goto done;
211 	}
212 	if (compare_data("DSA_PUBKEY", out, len, dsa_test_asn1_pubkey,
213 	    sizeof(dsa_test_asn1_pubkey)) == -1)
214 		goto done;
215 
216 	p = out;
217 	if ((dsa_b = d2i_DSA_PUBKEY(NULL, &p, len)) == NULL) {
218 		fprintf(stderr, "FAIL: d2i_DSA_PUBKEY failed\n");
219 		goto done;
220 	}
221 
222 	if (BN_cmp(dsa_a->pub_key, dsa_b->pub_key) != 0) {
223 		fprintf(stderr, "FAIL: DSA public keys mismatch\n");
224 		goto done;
225 	}
226 
227 	p = out;
228 	if ((dsa_a = d2i_DSA_PUBKEY(&dsa_a, &p, len)) == NULL) {
229 		fprintf(stderr, "FAIL: d2i_DSA_PUBKEY failed\n");
230 		goto done;
231 	}
232 
233 	if (BN_cmp(dsa_a->pub_key, dsa_b->pub_key) != 0) {
234 		fprintf(stderr, "FAIL: DSA public keys mismatch\n");
235 		goto done;
236 	}
237 
238 	/*
239 	 * Test i2d_DSA_PUBKEY_bio/d2i_DSA_PUBKEY_bio.
240 	 */
241 	BIO_free_all(bio_mem);
242 	if ((bio_mem = BIO_new(BIO_s_mem())) == NULL)
243                 errx(1, "BIO_new failed for BIO_s_mem");
244 
245 	if ((len = i2d_DSA_PUBKEY_bio(bio_mem, dsa_a)) < 0) {
246 		fprintf(stderr, "FAIL: i2d_DSA_PUBKEY_bio failed\n");
247 		goto done;
248 	}
249 
250 	len = BIO_get_mem_data(bio_mem, &data);
251 	if (compare_data("DSA_PUBKEY", data, len, dsa_test_asn1_pubkey,
252 	    sizeof(dsa_test_asn1_pubkey)) == -1)
253 		goto done;
254 
255 	DSA_free(dsa_b);
256 	if ((dsa_b = d2i_DSA_PUBKEY_bio(bio_mem, NULL)) == NULL) {
257 		fprintf(stderr, "FAIL: d2i_DSA_PUBKEY_bio failed\n");
258 		goto done;
259 	}
260 
261 	if (BN_cmp(dsa_a->pub_key, dsa_b->pub_key) != 0) {
262 		fprintf(stderr, "FAIL: DSA public keys mismatch\n");
263 		goto done;
264 	}
265 
266 	failure = 0;
267 
268  done:
269 	BIO_free_all(bio_mem);
270 	DSA_free(dsa_a);
271 	DSA_free(dsa_b);
272 	EVP_PKEY_free(pkey_a);
273 	EVP_PKEY_free(pkey_b);
274 	free(out);
275 
276 	return (failure);
277 }
278 
279 static int
280 ec_pubkey_test(void)
281 {
282 	EVP_PKEY *pkey_a = NULL, *pkey_b = NULL;
283 	unsigned char *out = NULL, *data = NULL;
284 	EC_KEY *ec_a = NULL, *ec_b = NULL;
285 	const unsigned char *p;
286 	BIO *bio_mem = NULL;
287 	int failure = 1;
288 	int len;
289 
290 	if ((bio_mem = BIO_new_mem_buf((void *)ec_test_key, -1)) == NULL)
291 		errx(1, "failed to create BIO");
292 
293 	if ((ec_a = PEM_read_bio_ECPrivateKey(bio_mem, NULL, NULL, NULL)) == NULL) {
294 		ERR_print_errors_fp(stderr);
295 		errx(1, "failed to decode EC key from PEM");
296 	}
297 
298 	/*
299 	 * Test i2d_PUBKEY/d2i_PUBKEY.
300 	 */
301 	if ((pkey_a = EVP_PKEY_new()) == NULL)
302 		errx(1, "failed to create EVP_PKEY");
303 	if (!EVP_PKEY_set1_EC_KEY(pkey_a, ec_a))
304 		errx(1, "failed to set EC_KEY on EVP_PKEY");
305 
306 	if ((len = i2d_PUBKEY(pkey_a, &out)) < 0) {
307 		fprintf(stderr, "FAIL: i2d_PUBKEY failed\n");
308 		goto done;
309 	}
310 	if (compare_data("EC_KEY PUBKEY", out, len, ec_test_asn1_pubkey,
311 	    sizeof(ec_test_asn1_pubkey)) == -1)
312 		goto done;
313 
314 	p = out;
315 	if ((pkey_b = d2i_PUBKEY(NULL, &p, len)) == NULL) {
316 		fprintf(stderr, "FAIL: d2i_PUBKEY failed\n");
317 		goto done;
318 	}
319 
320 	if (EC_GROUP_cmp(EC_KEY_get0_group(pkey_a->pkey.ec),
321 	    EC_KEY_get0_group(pkey_b->pkey.ec), NULL) != 0) {
322 		fprintf(stderr, "FAIL: EC_KEY groups keys mismatch\n");
323 		goto done;
324 	}
325         if (EC_POINT_cmp(EC_KEY_get0_group(pkey_a->pkey.ec),
326 	    EC_KEY_get0_public_key(pkey_a->pkey.ec),
327 	    EC_KEY_get0_public_key(pkey_b->pkey.ec), NULL) != 0) {
328 		fprintf(stderr, "FAIL: EC_KEY public keys mismatch\n");
329 		goto done;
330 	}
331 
332 	free(out);
333 	out = NULL;
334 
335 	/*
336 	 * Test i2d_EC_PUBKEY/d2i_EC_PUBKEY.
337 	 */
338 
339 	if ((len = i2d_EC_PUBKEY(ec_a, &out)) < 0) {
340 		fprintf(stderr, "FAIL: i2d_EC_PUBKEY failed\n");
341 		goto done;
342 	}
343 	if (compare_data("EC_PUBKEY", out, len, ec_test_asn1_pubkey,
344 	    sizeof(ec_test_asn1_pubkey)) == -1)
345 		goto done;
346 
347 	p = out;
348 	if ((ec_b = d2i_EC_PUBKEY(NULL, &p, len)) == NULL) {
349 		fprintf(stderr, "FAIL: d2i_EC_PUBKEY failed\n");
350 		goto done;
351 	}
352 
353 	if (EC_GROUP_cmp(EC_KEY_get0_group(ec_a), EC_KEY_get0_group(ec_b),
354 	    NULL) != 0) {
355 		fprintf(stderr, "FAIL: EC_KEY groups keys mismatch\n");
356 		goto done;
357 	}
358         if (EC_POINT_cmp(EC_KEY_get0_group(ec_a), EC_KEY_get0_public_key(ec_a),
359 	    EC_KEY_get0_public_key(ec_b), NULL) != 0) {
360 		fprintf(stderr, "FAIL: EC_KEY public keys mismatch\n");
361 		goto done;
362 	}
363 
364 	p = out;
365 	if ((ec_a = d2i_EC_PUBKEY(&ec_a, &p, len)) == NULL) {
366 		fprintf(stderr, "FAIL: d2i_EC_PUBKEY failed\n");
367 		goto done;
368 	}
369 
370 	if (EC_GROUP_cmp(EC_KEY_get0_group(ec_a), EC_KEY_get0_group(ec_b),
371 	    NULL) != 0) {
372 		fprintf(stderr, "FAIL: EC_KEY groups keys mismatch\n");
373 		goto done;
374 	}
375         if (EC_POINT_cmp(EC_KEY_get0_group(ec_a), EC_KEY_get0_public_key(ec_a),
376 	    EC_KEY_get0_public_key(ec_b), NULL) != 0) {
377 		fprintf(stderr, "FAIL: EC_KEY public keys mismatch\n");
378 		goto done;
379 	}
380 
381 	/*
382 	 * Test i2d_EC_PUBKEY_bio/d2i_EC_PUBKEY_bio.
383 	 */
384 	BIO_free_all(bio_mem);
385 	if ((bio_mem = BIO_new(BIO_s_mem())) == NULL)
386                 errx(1, "BIO_new failed for BIO_s_mem");
387 
388 	if ((len = i2d_EC_PUBKEY_bio(bio_mem, ec_a)) < 0) {
389 		fprintf(stderr, "FAIL: i2d_EC_PUBKEY_bio failed\n");
390 		goto done;
391 	}
392 
393 	len = BIO_get_mem_data(bio_mem, &data);
394 	if (compare_data("EC_PUBKEY", data, len, ec_test_asn1_pubkey,
395 	    sizeof(ec_test_asn1_pubkey)) == -1)
396 		goto done;
397 
398 	EC_KEY_free(ec_b);
399 	if ((ec_b = d2i_EC_PUBKEY_bio(bio_mem, NULL)) == NULL) {
400 		fprintf(stderr, "FAIL: d2i_EC_PUBKEY_bio failed\n");
401 		goto done;
402 	}
403 
404 	if (EC_GROUP_cmp(EC_KEY_get0_group(ec_a), EC_KEY_get0_group(ec_b),
405 	    NULL) != 0) {
406 		fprintf(stderr, "FAIL: EC_KEY groups keys mismatch\n");
407 		goto done;
408 	}
409         if (EC_POINT_cmp(EC_KEY_get0_group(ec_a), EC_KEY_get0_public_key(ec_a),
410 	    EC_KEY_get0_public_key(ec_b), NULL) != 0) {
411 		fprintf(stderr, "FAIL: EC_KEY public keys mismatch\n");
412 		goto done;
413 	}
414 
415 	failure = 0;
416 
417  done:
418 	BIO_free_all(bio_mem);
419 	EC_KEY_free(ec_a);
420 	EC_KEY_free(ec_b);
421 	EVP_PKEY_free(pkey_a);
422 	EVP_PKEY_free(pkey_b);
423 	free(out);
424 
425 	return (failure);
426 }
427 
428 static int
429 rsa_pubkey_test(void)
430 {
431 	EVP_PKEY *pkey_a = NULL, *pkey_b = NULL;
432 	RSA *rsa_a = NULL, *rsa_b = NULL;
433 	unsigned char *out = NULL, *data = NULL;
434 	const unsigned char *p;
435 	BIO *bio_mem = NULL;
436 	int failure = 1;
437 	int len;
438 
439 	if ((bio_mem = BIO_new_mem_buf((void *)rsa_test_key, -1)) == NULL)
440 		errx(1, "failed to create BIO");
441 
442 	if ((rsa_a = PEM_read_bio_RSAPrivateKey(bio_mem, NULL, NULL, NULL)) == NULL) {
443 		ERR_print_errors_fp(stderr);
444 		errx(1, "failed to decode RSA key from PEM");
445 	}
446 
447 	/*
448 	 * Test i2d_PUBKEY/d2i_PUBKEY.
449 	 */
450 	if ((pkey_a = EVP_PKEY_new()) == NULL)
451 		errx(1, "failed to create EVP_PKEY");
452 	if (!EVP_PKEY_set1_RSA(pkey_a, rsa_a))
453 		errx(1, "failed to set RSA on EVP_PKEY");
454 
455 	if ((len = i2d_PUBKEY(pkey_a, &out)) < 0) {
456 		fprintf(stderr, "FAIL: i2d_PUBKEY failed\n");
457 		goto done;
458 	}
459 	if (compare_data("RSA PUBKEY", out, len, rsa_test_asn1_pubkey,
460 	    sizeof(rsa_test_asn1_pubkey)) == -1)
461 		goto done;
462 
463 	p = out;
464 	if ((pkey_b = d2i_PUBKEY(NULL, &p, len)) == NULL) {
465 		fprintf(stderr, "FAIL: d2i_PUBKEY failed\n");
466 		goto done;
467 	}
468 
469 	if (BN_cmp(pkey_a->pkey.rsa->n, pkey_b->pkey.rsa->n) != 0 ||
470 	    BN_cmp(pkey_a->pkey.rsa->e, pkey_b->pkey.rsa->e) != 0) {
471 		fprintf(stderr, "FAIL: RSA public keys mismatch\n");
472 		goto done;
473 	}
474 
475 	free(out);
476 	out = NULL;
477 
478 	/*
479 	 * Test i2d_RSA_PUBKEY/d2i_RSA_PUBKEY.
480 	 */
481 
482 	if ((len = i2d_RSA_PUBKEY(rsa_a, &out)) < 0) {
483 		fprintf(stderr, "FAIL: i2d_RSA_PUBKEY failed\n");
484 		goto done;
485 	}
486 	if (compare_data("RSA_PUBKEY", out, len, rsa_test_asn1_pubkey,
487 	    sizeof(rsa_test_asn1_pubkey)) == -1)
488 		goto done;
489 
490 	p = out;
491 	if ((rsa_b = d2i_RSA_PUBKEY(NULL, &p, len)) == NULL) {
492 		fprintf(stderr, "FAIL: d2i_RSA_PUBKEY failed\n");
493 		goto done;
494 	}
495 
496 	if (BN_cmp(rsa_a->n, rsa_b->n) != 0 ||
497 	    BN_cmp(rsa_a->e, rsa_b->e) != 0) {
498 		fprintf(stderr, "FAIL: RSA public keys mismatch\n");
499 		goto done;
500 	}
501 
502 	p = out;
503 	if ((rsa_a = d2i_RSA_PUBKEY(&rsa_a, &p, len)) == NULL) {
504 		fprintf(stderr, "FAIL: d2i_RSA_PUBKEY failed\n");
505 		goto done;
506 	}
507 
508 	if (BN_cmp(rsa_a->n, rsa_b->n) != 0 ||
509 	    BN_cmp(rsa_a->e, rsa_b->e) != 0) {
510 		fprintf(stderr, "FAIL: RSA public keys mismatch\n");
511 		goto done;
512 	}
513 
514 	/*
515 	 * Test i2d_RSA_PUBKEY_bio/d2i_RSA_PUBKEY_bio.
516 	 */
517 	BIO_free_all(bio_mem);
518 	if ((bio_mem = BIO_new(BIO_s_mem())) == NULL)
519                 errx(1, "BIO_new failed for BIO_s_mem");
520 
521 	if ((len = i2d_RSA_PUBKEY_bio(bio_mem, rsa_a)) < 0) {
522 		fprintf(stderr, "FAIL: i2d_RSA_PUBKEY_bio failed\n");
523 		goto done;
524 	}
525 
526 	len = BIO_get_mem_data(bio_mem, &data);
527 	if (compare_data("RSA_PUBKEY", data, len, rsa_test_asn1_pubkey,
528 	    sizeof(rsa_test_asn1_pubkey)) == -1)
529 		goto done;
530 
531 	RSA_free(rsa_b);
532 	if ((rsa_b = d2i_RSA_PUBKEY_bio(bio_mem, NULL)) == NULL) {
533 		fprintf(stderr, "FAIL: d2i_RSA_PUBKEY_bio failed\n");
534 		goto done;
535 	}
536 
537 	if (BN_cmp(rsa_a->n, rsa_b->n) != 0 ||
538 	    BN_cmp(rsa_a->e, rsa_b->e) != 0) {
539 		fprintf(stderr, "FAIL: RSA public keys mismatch\n");
540 		goto done;
541 	}
542 
543 	failure = 0;
544 
545  done:
546 	BIO_free_all(bio_mem);
547 	RSA_free(rsa_a);
548 	RSA_free(rsa_b);
549 	EVP_PKEY_free(pkey_a);
550 	EVP_PKEY_free(pkey_b);
551 	free(out);
552 
553 	return (failure);
554 }
555 
556 int
557 main(int argc, char **argv)
558 {
559 	int failed = 0;
560 
561 	ERR_load_crypto_strings();
562 
563 	failed |= dsa_pubkey_test();
564 	failed |= ec_pubkey_test();
565 	failed |= rsa_pubkey_test();
566 
567 	return (failed);
568 }
569