xref: /openbsd/regress/lib/libssl/asn1/asn1test.c (revision d89ec533)
1 /*	$OpenBSD: asn1test.c,v 1.9 2021/10/23 08:13:52 jsing Exp $	*/
2 /*
3  * Copyright (c) 2014, 2016 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 <stdlib.h>
20 
21 #include <openssl/bio.h>
22 #include <openssl/err.h>
23 #include <openssl/ssl.h>
24 #include <openssl/tls1.h>
25 
26 #include "ssl_locl.h"
27 
28 int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
29 SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
30     long length);
31 
32 X509 *peer_cert;
33 
34 unsigned char *peer_cert_pem =
35     "-----BEGIN CERTIFICATE-----\n"
36     "MIIBcTCCARugAwIBAgIJAPYhaZJAvUuUMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV\n"
37     "BAoMCVRlc3QgUGVlcjAeFw0xNjEyMjYxNDQ3NDdaFw0yNjEyMjQxNDQ3NDdaMBQx\n"
38     "EjAQBgNVBAoMCVRlc3QgUGVlcjBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCyhAdJ\n"
39     "wojHv/uKONh8MbmR2U2+VF1HQusnLfSfHPqkJfvDzLWJ41TG7QcXkx2rIJVtAFrO\n"
40     "U9yNdFYJLA/hsrbjAgMBAAGjUDBOMB0GA1UdDgQWBBS3bZOw7fvaortdsdE2TPMq\n"
41     "IRXFRzAfBgNVHSMEGDAWgBS3bZOw7fvaortdsdE2TPMqIRXFRzAMBgNVHRMEBTAD\n"
42     "AQH/MA0GCSqGSIb3DQEBBQUAA0EAHsxNS+rNUZbopeDMhVIviOfUmelDjJrT56Rc\n"
43     "VJoFN3Gc1cV8nQAHm9aJs71uksC+MN04Pzh0WqmYX9XXrnYPcg==\n"
44     "-----END CERTIFICATE-----\n";
45 
46 struct ssl_asn1_test {
47 	SSL_SESSION session;
48 	int peer_cert;
49 	const unsigned char asn1[1024];
50 	int asn1_len;
51 };
52 
53 unsigned char tlsext_tick[] = {
54 	0x43, 0x56, 0x45, 0x2d, 0x32, 0x30, 0x31, 0x34,
55 	0x2d, 0x30, 0x31, 0x36, 0x30, 0x3a, 0x20, 0x37,
56 	0x74, 0x68, 0x20, 0x41, 0x70, 0x72, 0x69, 0x6c,
57 	0x20, 0x32, 0x30, 0x31, 0x34, 0x0a, 0x43, 0x56,
58 	0x45, 0x2d, 0x32, 0x30, 0x31, 0x30, 0x2d, 0x35,
59 	0x32, 0x39, 0x38, 0x3a, 0x20, 0x38, 0x74, 0x68,
60 	0x20, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x20, 0x32,
61 	0x30, 0x31, 0x34, 0x0a, 0x43, 0x56, 0x45, 0x2d,
62 	0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, 0x31, 0x39,
63 	0x38, 0x3a, 0x20, 0x32, 0x31, 0x73, 0x74, 0x20,
64 	0x41, 0x70, 0x72, 0x69, 0x6c, 0x20, 0x32, 0x30,
65 	0x31, 0x34, 0x0a, 0x43, 0x56, 0x45, 0x2d, 0x32,
66 	0x30, 0x31, 0x34, 0x2d, 0x33, 0x34, 0x37, 0x30,
67 	0x3a, 0x20, 0x33, 0x30, 0x74, 0x68, 0x20, 0x4d,
68 	0x61, 0x79, 0x20, 0x32, 0x30, 0x31, 0x34, 0x0a,
69 	0x43, 0x56, 0x45, 0x2d, 0x32, 0x30, 0x31, 0x34,
70 	0x2d, 0x30, 0x31, 0x39, 0x35, 0x3a, 0x20, 0x35,
71 	0x74, 0x68, 0x20, 0x4a, 0x75, 0x6e, 0x65, 0x20,
72 	0x32, 0x30, 0x31, 0x34, 0x0a, 0x43, 0x56, 0x45,
73 	0x2d, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, 0x32,
74 	0x32, 0x31, 0x3a, 0x20, 0x35, 0x74, 0x68, 0x20,
75 	0x4a, 0x75, 0x6e, 0x65, 0x20, 0x32, 0x30, 0x31,
76 	0x34, 0x0a, 0x43, 0x56, 0x45, 0x2d, 0x32, 0x30,
77 	0x31, 0x34, 0x2d, 0x30, 0x32, 0x32, 0x34, 0x3a,
78 	0x20, 0x35, 0x74, 0x68, 0x20, 0x4a, 0x75, 0x6e,
79 	0x65, 0x20, 0x32, 0x30, 0x31, 0x34, 0x0a,
80 };
81 
82 struct ssl_asn1_test ssl_asn1_tests[] = {
83 	{
84 		.session = {
85 			.cipher_id = 0x03000000L | 1,
86 			.ssl_version = TLS1_2_VERSION,
87 		},
88 		.asn1 = {
89 			0x30, 0x13, 0x02, 0x01, 0x01, 0x02, 0x02, 0x03,
90 			0x03, 0x04, 0x02, 0x00, 0x01, 0x04, 0x00, 0x04,
91 			0x00, 0xa4, 0x02, 0x04, 0x00,
92 		},
93 		.asn1_len = 21,
94 	},
95 	{
96 		.session = {
97 			.cipher_id = 0x03000000L | 1,
98 			.ssl_version = TLS1_2_VERSION,
99 			.master_key_length = 26,
100 			.session_id = "0123456789",
101 			.session_id_length = 10,
102 			.sid_ctx = "abcdefghijklmnopqrstuvwxyz",
103 			.sid_ctx_length = 26,
104 		},
105 		.asn1 = {
106 			0x30, 0x51, 0x02, 0x01, 0x01, 0x02, 0x02, 0x03,
107 			0x03, 0x04, 0x02, 0x00, 0x01, 0x04, 0x0a, 0x30,
108 			0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
109 			0x39, 0x04, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x00,
110 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 			0x00, 0x00, 0x00, 0x00, 0x00, 0xa4, 0x1c, 0x04,
113 			0x1a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
114 			0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
115 			0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
116 			0x78, 0x79, 0x7a,
117 		},
118 		.asn1_len = 83,
119 	},
120 	{
121 		.session = {
122 			.cipher_id = 0x03000000L | 1,
123 			.ssl_version = TLS1_2_VERSION,
124 			.master_key_length = 26,
125 			.session_id = "0123456789",
126 			.session_id_length = 10,
127 			.sid_ctx = "abcdefghijklmnopqrstuvwxyz",
128 			.sid_ctx_length = 26,
129 			.time = 1405266069,
130 			.timeout = 5,
131 			.verify_result = 42,
132 			.tlsext_hostname = "libressl.openbsd.org",
133 			.tlsext_tick_lifetime_hint = 0x7abbccdd,
134 			.tlsext_tick = tlsext_tick,
135 			.tlsext_ticklen = sizeof(tlsext_tick),
136 		},
137 		.peer_cert = 1,
138 		.asn1 = {
139 			0x30, 0x82, 0x02, 0xd1, 0x02, 0x01, 0x01, 0x02,
140 			0x02, 0x03, 0x03, 0x04, 0x02, 0x00, 0x01, 0x04,
141 			0x0a, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36,
142 			0x37, 0x38, 0x39, 0x04, 0x1a, 0x00, 0x00, 0x00,
143 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 			0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1,
146 			0x06, 0x02, 0x04, 0x53, 0xc2, 0xa8, 0x95, 0xa2,
147 			0x03, 0x02, 0x01, 0x05, 0xa3, 0x82, 0x01, 0x75,
148 			0x30, 0x82, 0x01, 0x71, 0x30, 0x82, 0x01, 0x1b,
149 			0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x09, 0x00,
150 			0xf6, 0x21, 0x69, 0x92, 0x40, 0xbd, 0x4b, 0x94,
151 			0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
152 			0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30,
153 			0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
154 			0x04, 0x0a, 0x0c, 0x09, 0x54, 0x65, 0x73, 0x74,
155 			0x20, 0x50, 0x65, 0x65, 0x72, 0x30, 0x1e, 0x17,
156 			0x0d, 0x31, 0x36, 0x31, 0x32, 0x32, 0x36, 0x31,
157 			0x34, 0x34, 0x37, 0x34, 0x37, 0x5a, 0x17, 0x0d,
158 			0x32, 0x36, 0x31, 0x32, 0x32, 0x34, 0x31, 0x34,
159 			0x34, 0x37, 0x34, 0x37, 0x5a, 0x30, 0x14, 0x31,
160 			0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a,
161 			0x0c, 0x09, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50,
162 			0x65, 0x65, 0x72, 0x30, 0x5c, 0x30, 0x0d, 0x06,
163 			0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
164 			0x01, 0x01, 0x05, 0x00, 0x03, 0x4b, 0x00, 0x30,
165 			0x48, 0x02, 0x41, 0x00, 0xb2, 0x84, 0x07, 0x49,
166 			0xc2, 0x88, 0xc7, 0xbf, 0xfb, 0x8a, 0x38, 0xd8,
167 			0x7c, 0x31, 0xb9, 0x91, 0xd9, 0x4d, 0xbe, 0x54,
168 			0x5d, 0x47, 0x42, 0xeb, 0x27, 0x2d, 0xf4, 0x9f,
169 			0x1c, 0xfa, 0xa4, 0x25, 0xfb, 0xc3, 0xcc, 0xb5,
170 			0x89, 0xe3, 0x54, 0xc6, 0xed, 0x07, 0x17, 0x93,
171 			0x1d, 0xab, 0x20, 0x95, 0x6d, 0x00, 0x5a, 0xce,
172 			0x53, 0xdc, 0x8d, 0x74, 0x56, 0x09, 0x2c, 0x0f,
173 			0xe1, 0xb2, 0xb6, 0xe3, 0x02, 0x03, 0x01, 0x00,
174 			0x01, 0xa3, 0x50, 0x30, 0x4e, 0x30, 0x1d, 0x06,
175 			0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14,
176 			0xb7, 0x6d, 0x93, 0xb0, 0xed, 0xfb, 0xda, 0xa2,
177 			0xbb, 0x5d, 0xb1, 0xd1, 0x36, 0x4c, 0xf3, 0x2a,
178 			0x21, 0x15, 0xc5, 0x47, 0x30, 0x1f, 0x06, 0x03,
179 			0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80,
180 			0x14, 0xb7, 0x6d, 0x93, 0xb0, 0xed, 0xfb, 0xda,
181 			0xa2, 0xbb, 0x5d, 0xb1, 0xd1, 0x36, 0x4c, 0xf3,
182 			0x2a, 0x21, 0x15, 0xc5, 0x47, 0x30, 0x0c, 0x06,
183 			0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03,
184 			0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a,
185 			0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
186 			0x05, 0x00, 0x03, 0x41, 0x00, 0x1e, 0xcc, 0x4d,
187 			0x4b, 0xea, 0xcd, 0x51, 0x96, 0xe8, 0xa5, 0xe0,
188 			0xcc, 0x85, 0x52, 0x2f, 0x88, 0xe7, 0xd4, 0x99,
189 			0xe9, 0x43, 0x8c, 0x9a, 0xd3, 0xe7, 0xa4, 0x5c,
190 			0x54, 0x9a, 0x05, 0x37, 0x71, 0x9c, 0xd5, 0xc5,
191 			0x7c, 0x9d, 0x00, 0x07, 0x9b, 0xd6, 0x89, 0xb3,
192 			0xbd, 0x6e, 0x92, 0xc0, 0xbe, 0x30, 0xdd, 0x38,
193 			0x3f, 0x38, 0x74, 0x5a, 0xa9, 0x98, 0x5f, 0xd5,
194 			0xd7, 0xae, 0x76, 0x0f, 0x72, 0xa4, 0x1c, 0x04,
195 			0x1a, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
196 			0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
197 			0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
198 			0x78, 0x79, 0x7a, 0xa5, 0x03, 0x02, 0x01, 0x2a,
199 			0xa6, 0x16, 0x04, 0x14, 0x6c, 0x69, 0x62, 0x72,
200 			0x65, 0x73, 0x73, 0x6c, 0x2e, 0x6f, 0x70, 0x65,
201 			0x6e, 0x62, 0x73, 0x64, 0x2e, 0x6f, 0x72, 0x67,
202 			0xa9, 0x06, 0x02, 0x04, 0x7a, 0xbb, 0xcc, 0xdd,
203 			0xaa, 0x81, 0xd2, 0x04, 0x81, 0xcf, 0x43, 0x56,
204 			0x45, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30,
205 			0x31, 0x36, 0x30, 0x3a, 0x20, 0x37, 0x74, 0x68,
206 			0x20, 0x41, 0x70, 0x72, 0x69, 0x6c, 0x20, 0x32,
207 			0x30, 0x31, 0x34, 0x0a, 0x43, 0x56, 0x45, 0x2d,
208 			0x32, 0x30, 0x31, 0x30, 0x2d, 0x35, 0x32, 0x39,
209 			0x38, 0x3a, 0x20, 0x38, 0x74, 0x68, 0x20, 0x41,
210 			0x70, 0x72, 0x69, 0x6c, 0x20, 0x32, 0x30, 0x31,
211 			0x34, 0x0a, 0x43, 0x56, 0x45, 0x2d, 0x32, 0x30,
212 			0x31, 0x34, 0x2d, 0x30, 0x31, 0x39, 0x38, 0x3a,
213 			0x20, 0x32, 0x31, 0x73, 0x74, 0x20, 0x41, 0x70,
214 			0x72, 0x69, 0x6c, 0x20, 0x32, 0x30, 0x31, 0x34,
215 			0x0a, 0x43, 0x56, 0x45, 0x2d, 0x32, 0x30, 0x31,
216 			0x34, 0x2d, 0x33, 0x34, 0x37, 0x30, 0x3a, 0x20,
217 			0x33, 0x30, 0x74, 0x68, 0x20, 0x4d, 0x61, 0x79,
218 			0x20, 0x32, 0x30, 0x31, 0x34, 0x0a, 0x43, 0x56,
219 			0x45, 0x2d, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30,
220 			0x31, 0x39, 0x35, 0x3a, 0x20, 0x35, 0x74, 0x68,
221 			0x20, 0x4a, 0x75, 0x6e, 0x65, 0x20, 0x32, 0x30,
222 			0x31, 0x34, 0x0a, 0x43, 0x56, 0x45, 0x2d, 0x32,
223 			0x30, 0x31, 0x34, 0x2d, 0x30, 0x32, 0x32, 0x31,
224 			0x3a, 0x20, 0x35, 0x74, 0x68, 0x20, 0x4a, 0x75,
225 			0x6e, 0x65, 0x20, 0x32, 0x30, 0x31, 0x34, 0x0a,
226 			0x43, 0x56, 0x45, 0x2d, 0x32, 0x30, 0x31, 0x34,
227 			0x2d, 0x30, 0x32, 0x32, 0x34, 0x3a, 0x20, 0x35,
228 			0x74, 0x68, 0x20, 0x4a, 0x75, 0x6e, 0x65, 0x20,
229 			0x32, 0x30, 0x31, 0x34, 0x0a,
230 		},
231 		.asn1_len = 725,
232 	},
233 	{
234 		.session = {
235 			.cipher_id = 0x03000000L | 1,
236 			.ssl_version = TLS1_2_VERSION,
237 			.timeout = -1,
238 		},
239 		.asn1 = {
240 			0x0,
241 		},
242 		.asn1_len = -1,
243 	},
244 	{
245 		.session = {
246 			.cipher_id = 0x03000000L | 1,
247 			.ssl_version = TLS1_2_VERSION,
248 			.time = -1,
249 		},
250 		.asn1 = {
251 			0x0,
252 		},
253 		.asn1_len = -1,
254 	},
255 };
256 
257 #define N_SSL_ASN1_TESTS \
258     (sizeof(ssl_asn1_tests) / sizeof(*ssl_asn1_tests))
259 
260 static int
261 session_strcmp(const unsigned char *o1, const unsigned char *o2, size_t len)
262 {
263 	if (o1 == NULL && o2 == NULL)
264 		return (0);
265 	if (o1 == NULL || o2 == NULL)
266 		return (1);
267 	return memcmp(o1, o2, len);
268 }
269 
270 static int
271 session_cmp(SSL_SESSION *s1, SSL_SESSION *s2)
272 {
273 	/* Compare the ASN.1 encoded values from two sessions. */
274 	if (s1->ssl_version != s2->ssl_version) {
275 		fprintf(stderr, "ssl_version differs: %i != %i\n",
276 		    s1->ssl_version, s2->ssl_version);
277 		return (1);
278 	}
279 	if (s1->cipher_id != s2->cipher_id) {
280 		fprintf(stderr, "cipher_id differs: %li != %li\n",
281 		    s1->cipher_id, s2->cipher_id);
282 		return (1);
283 	}
284 
285 	if (s1->master_key_length != s2->master_key_length) {
286 		fprintf(stderr, "master_key_length differs: %i != %i\n",
287 		    s1->master_key_length, s2->master_key_length);
288 		return (1);
289 	}
290 	if (session_strcmp(s1->master_key, s2->master_key,
291 	    s1->master_key_length) != 0) {
292 		fprintf(stderr, "master_key differs\n");
293 		return (1);
294 	}
295 
296 	if (s1->session_id_length != s2->session_id_length) {
297 		fprintf(stderr, "session_id_length differs: %i != %i\n",
298 		    s1->session_id_length, s2->session_id_length);
299 		return (1);
300 	}
301 	if (session_strcmp(s1->session_id, s2->session_id,
302 	    s1->session_id_length) != 0) {
303 		fprintf(stderr, "session_id differs\n");
304 		return (1);
305 	}
306 
307 	if (s1->sid_ctx_length != s2->sid_ctx_length) {
308 		fprintf(stderr, "sid_ctx_length differs: %i != %i\n",
309 		    s1->sid_ctx_length, s2->sid_ctx_length);
310 		return (1);
311 	}
312 	if (session_strcmp(s1->sid_ctx, s2->sid_ctx,
313 	    s1->sid_ctx_length) != 0) {
314 		fprintf(stderr, "sid_ctx differs\n");
315 		return (1);
316 	}
317 
318 	/* d2i_SSL_SESSION uses the current time if decoding a zero value. */
319 	if ((s1->time != s2->time) && s1->time != 0 && s2->time != 0) {
320 		fprintf(stderr, "time differs: %lli != %lli\n",
321 		    (long long)s1->time, (long long)s2->time);
322 		return (1);
323 	}
324 	/* d2i_SSL_SESSION uses a timeout of 3 if decoding a zero value. */
325 	if ((s1->timeout != s2->timeout) &&
326 	    s1->timeout != 3 && s2->timeout != 3) {
327 		fprintf(stderr, "timeout differs: %li != %li\n",
328 		    s1->timeout, s2->timeout);
329 		return (1);
330 	}
331 
332 	/* Ensure that a certificate is or is not present in both. */
333 	if ((s1->peer != NULL || s2->peer != NULL) &&
334 	    (s1->peer == NULL || s2->peer == NULL ||
335 	     X509_cmp(s1->peer, s2->peer) != 0)) {
336 		fprintf(stderr, "peer differs\n");
337 		return (1);
338 	}
339 
340 	if (s1->verify_result != s2->verify_result) {
341 		fprintf(stderr, "verify_result differs: %li != %li\n",
342 		    s1->verify_result, s2->verify_result);
343 		return (1);
344 	}
345 
346 	if (session_strcmp(s1->tlsext_hostname, s2->tlsext_hostname,
347 	    (s1->tlsext_hostname ? strlen(s1->tlsext_hostname) : 0)) != 0) {
348 		fprintf(stderr, "sid_ctx differs\n");
349 		return (1);
350 	}
351 	if (s1->tlsext_tick_lifetime_hint != s2->tlsext_tick_lifetime_hint) {
352 		fprintf(stderr, "tlsext_tick_lifetime_hint differs: "
353 		    "%u != %u\n", s1->tlsext_tick_lifetime_hint,
354 		    s2->tlsext_tick_lifetime_hint);
355 		return (1);
356 	}
357 	if (s1->tlsext_ticklen != s2->tlsext_ticklen) {
358 		fprintf(stderr, "tlsext_ticklen differs: %zu != %zu\n",
359 		    s1->tlsext_ticklen, s2->tlsext_ticklen);
360 		return (1);
361 	}
362 	if (session_strcmp(s1->tlsext_tick, s2->tlsext_tick,
363 	    s1->tlsext_ticklen) != 0) {
364 		fprintf(stderr, "tlsext_tick differs\n");
365 		return (1);
366 	}
367 
368 	return (0);
369 }
370 
371 static int
372 do_ssl_asn1_test(int test_no, struct ssl_asn1_test *sat)
373 {
374 	SSL_SESSION *sp = NULL;
375 	unsigned char *ap, *asn1 = NULL;
376 	const unsigned char *pp;
377 	int i, len, rv = 1;
378 
379 	if (sat->peer_cert)
380 		sat->session.peer = peer_cert;
381 
382 	len = i2d_SSL_SESSION(&sat->session, NULL);
383 	if (len != sat->asn1_len) {
384 		fprintf(stderr, "FAIL: test %i returned ASN1 length %i, "
385 		    "want %i\n", test_no, len, sat->asn1_len);
386 		goto failed;
387 	}
388 
389 	/* See if the test is expected to fail... */
390 	if (sat->asn1_len == -1)
391 		return (0);
392 
393 	if ((asn1 = malloc(len)) == NULL)
394 		errx(1, "failed to allocate memory");
395 
396 	ap = asn1;
397 	len = i2d_SSL_SESSION(&sat->session, &ap);
398 
399 	/* Check the length again since the code path is different. */
400 	if (len != sat->asn1_len) {
401 		fprintf(stderr, "FAIL: test %i returned ASN1 length %i, "
402 		    "want %i\n", test_no, len, sat->asn1_len);
403 		goto failed;
404 	}
405 	/* ap should now point at the end of the buffer. */
406 	if (ap - asn1 != len) {
407 		fprintf(stderr, "FAIL: test %i pointer increment does not "
408 		    "match length (%i != %i)\n", test_no, (int)(ap - asn1), len);
409 		goto failed;
410 	}
411 
412 	if (memcmp(asn1, &sat->asn1, len) != 0) {
413 		fprintf(stderr, "FAIL: test %i - encoding differs:\n", test_no);
414 		fprintf(stderr, "encoding:\n");
415 		for (i = 1; i <= len; i++) {
416 			fprintf(stderr, " 0x%02hhx,", asn1[i - 1]);
417 			if (i % 8 == 0)
418 				fprintf(stderr, "\n");
419 		}
420 		fprintf(stderr, "\n");
421 		fprintf(stderr, "test data:\n");
422 		for (i = 1; i <= sat->asn1_len; i++) {
423 			fprintf(stderr, " 0x%02hhx,", sat->asn1[i - 1]);
424 			if (i % 8 == 0)
425 				fprintf(stderr, "\n");
426 		}
427 		fprintf(stderr, "\n");
428 		goto failed;
429 	}
430 
431 	pp = sat->asn1;
432 
433 	if ((sp = d2i_SSL_SESSION(NULL, &pp, sat->asn1_len)) == NULL) {
434 		fprintf(stderr, "FAIL: test %i - decoding failed\n", test_no);
435 		goto failed;
436 	}
437 
438 	if (session_cmp(sp, &sat->session) != 0) {
439 		fprintf(stderr, "FAIL: test %i - decoding differs\n", test_no);
440 		goto failed;
441 	}
442 
443 	rv = 0;
444 
445  failed:
446 	ERR_print_errors_fp(stderr);
447 	SSL_SESSION_free(sp);
448 	free(asn1);
449 
450 	return (rv);
451 }
452 
453 int
454 main(int argc, char **argv)
455 {
456 	BIO *bio = NULL;
457 	int failed = 0;
458 	size_t i;
459 
460 	SSL_library_init();
461 	SSL_load_error_strings();
462 
463 	bio = BIO_new_mem_buf(peer_cert_pem, -1);
464 	if (bio == NULL)
465 		errx(1, "failed to create bio");
466 
467 	peer_cert = PEM_read_bio_X509(bio, NULL, NULL, NULL);
468 	if (peer_cert == NULL)
469 		errx(1, "failed to read peer cert");
470 
471 	for (i = 0; i < N_SSL_ASN1_TESTS; i++)
472 		failed += do_ssl_asn1_test(i, &ssl_asn1_tests[i]);
473 
474 	X509_free(peer_cert);
475 	BIO_free(bio);
476 
477 	return (failed);
478 }
479