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