Annotation of embedaddon/strongswan/src/libstrongswan/tests/suites/test_certnames.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2014 Martin Willi
3: * Copyright (C) 2014 revosec AG
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include "test_suite.h"
17:
18: #include <asn1/asn1.h>
19: #include <credentials/sets/mem_cred.h>
20: #include <credentials/certificates/x509.h>
21:
22: /**
23: * RSA private key, so we don't have to generate one
24: */
25: static char keydata[] = {
26: 0x30,0x82,0x02,0x5e,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xb1,0x9b,0xd4,0x51,0x24,
27: 0xfc,0x56,0x1d,0x3d,0xfb,0xa2,0xea,0x37,0x02,0x70,0x72,0x87,0x84,0x2f,0x3b,0x2d,
28: 0x6e,0x22,0xef,0x3f,0x37,0x04,0xb2,0x6f,0xb7,0xe7,0xd8,0x58,0x05,0xde,0x34,0xbf,
29: 0x99,0xe6,0x40,0x7a,0x56,0xa7,0x73,0xf5,0x98,0xcb,0xb0,0x37,0x90,0x5e,0xd1,0x3f,
30: 0xf4,0x73,0x50,0x7f,0x53,0x8e,0xf1,0x04,0x25,0xb4,0x77,0x22,0x4e,0x8a,0x9d,0x27,
31: 0x8f,0x6f,0xaf,0x59,0xbd,0xb0,0x0f,0xf0,0xaa,0x11,0x94,0x66,0x16,0x10,0x58,0xad,
32: 0x77,0xa1,0xac,0x58,0xb4,0xd0,0x0d,0xbc,0x11,0xe0,0xc0,0xe9,0x29,0xdc,0x42,0x63,
33: 0x01,0x23,0x4f,0x28,0x41,0x6d,0x34,0x9e,0x0c,0x4a,0xc8,0x62,0x83,0xb5,0x71,0x71,
34: 0x0b,0x51,0xc0,0x4c,0x37,0xd4,0x68,0x19,0x52,0x9a,0x8b,0x02,0x03,0x01,0x00,0x01,
35: 0x02,0x81,0x81,0x00,0x82,0xca,0x33,0x16,0xb2,0x3a,0xd4,0x1b,0x62,0x9a,0x9c,0xc5,
36: 0x07,0x4f,0x57,0x89,0x2f,0x7c,0x4a,0xdf,0xb4,0x3b,0xc7,0xa4,0x11,0x14,0x2d,0xf4,
37: 0x4c,0xca,0xcc,0x03,0x88,0x06,0x82,0x34,0xab,0xe7,0xe4,0x24,0x15,0x33,0x1c,0xcb,
38: 0x0a,0xcf,0xc3,0x27,0x78,0x33,0x6b,0x6f,0x82,0x3e,0x3c,0x70,0xc9,0xe2,0xb9,0x7f,
39: 0x88,0xc3,0x4f,0x59,0xb5,0x8e,0xa3,0x81,0xd9,0x88,0x1f,0xc0,0x38,0xbc,0xc8,0x93,
40: 0x40,0x0f,0x43,0xd8,0x72,0x12,0xb4,0xcc,0x6d,0x76,0x0a,0x6f,0x01,0x05,0xa8,0x88,
41: 0xf4,0x57,0x44,0xd2,0x05,0xc4,0x77,0xf5,0xfb,0x1b,0xf3,0xb2,0x0d,0x90,0xb8,0xb4,
42: 0x63,0x62,0x70,0x2c,0xe4,0x28,0xd8,0x20,0x10,0x85,0x4a,0x5e,0x63,0xa9,0xb0,0xdd,
43: 0xba,0xd0,0x32,0x49,0x02,0x41,0x00,0xdb,0x77,0xf1,0xdd,0x1a,0x12,0xc5,0xfb,0x2b,
44: 0x5b,0xb2,0xcd,0xb6,0xd0,0x4c,0xc4,0xe5,0x93,0xd6,0xf8,0x88,0xfc,0x18,0x40,0x21,
45: 0x9c,0xf7,0x2d,0x60,0x6f,0x91,0xf5,0x73,0x3c,0xf7,0x7f,0x67,0x1d,0x5b,0xb5,0xee,
46: 0x29,0xc1,0xd4,0xc6,0xdb,0x44,0x4c,0x40,0x05,0x63,0xaa,0x71,0x95,0x18,0x14,0xa7,
47: 0x23,0x9f,0x7a,0xee,0x7f,0xb5,0xc7,0x02,0x41,0x00,0xcf,0x2c,0x24,0x50,0x65,0xf4,
48: 0x94,0x7b,0xe9,0xf3,0x13,0x77,0xea,0x27,0x3c,0x6f,0x03,0x84,0xa7,0x7d,0xa2,0x54,
49: 0x40,0x97,0x82,0x0e,0xd9,0x09,0x9f,0x4a,0xa6,0x75,0xe5,0x66,0xe4,0x9c,0x59,0xd9,
50: 0x3a,0xe6,0xf7,0xd8,0x8b,0x68,0xb0,0x21,0x52,0x31,0xb3,0x4a,0xa0,0x2c,0x41,0xd7,
51: 0x1f,0x7b,0xe2,0x0f,0x15,0xc9,0x6e,0xc0,0xe5,0x1d,0x02,0x41,0x00,0x9c,0x1a,0x61,
52: 0x9f,0x89,0xc7,0x26,0xa9,0x33,0xba,0xe2,0xa0,0x6d,0xd3,0x15,0x77,0xcb,0x6f,0xef,
53: 0xad,0x12,0x0a,0x75,0xd9,0x4f,0xcf,0x4d,0x05,0x2a,0x9d,0xd1,0x2c,0xcb,0xcd,0xe6,
54: 0xa0,0xe9,0x20,0x39,0xb6,0x5a,0xf3,0xba,0x99,0xf4,0xe3,0xcb,0x5d,0x8d,0x00,0x08,
55: 0x57,0x18,0xb9,0x1a,0xca,0xbd,0xe3,0x99,0xb1,0x1f,0xe9,0x18,0xcb,0x02,0x40,0x65,
56: 0x35,0x1b,0x48,0x6b,0x86,0x60,0x43,0x68,0xb6,0xe6,0xfb,0xdd,0xd7,0xed,0x1e,0x0e,
57: 0x89,0xef,0x88,0xe0,0x94,0x68,0x39,0x9b,0xbf,0xc5,0x27,0x7e,0x39,0xe9,0xb8,0x0e,
58: 0xa9,0x85,0x65,0x1c,0x3f,0x93,0x16,0xe2,0x5d,0x57,0x3d,0x7d,0x4d,0xc9,0xe9,0x9d,
59: 0xbd,0x07,0x22,0x97,0xc7,0x90,0x09,0xe5,0x15,0x99,0x7f,0x1e,0x2b,0xfd,0xc1,0x02,
60: 0x41,0x00,0x92,0x78,0xfe,0x04,0xa0,0x53,0xed,0x36,0x97,0xbd,0x16,0xce,0x91,0x9b,
61: 0xbe,0x1f,0x8e,0x40,0x00,0x99,0x0c,0x49,0x15,0xca,0x59,0xd3,0xe3,0xd4,0xeb,0x71,
62: 0xcf,0xda,0xd7,0xc8,0x99,0x74,0xfc,0x6b,0xe8,0xfd,0xe5,0xe0,0x49,0x61,0xcb,0xda,
63: 0xe3,0xe7,0x8b,0x72,0xb5,0x69,0x73,0x2b,0x8b,0x54,0xcb,0xd9,0x48,0x6d,0x61,0x02,
64: 0x49,0xe8,
65: };
66:
67: /**
68: * Issue a certificate with permitted/excluded name constraints
69: */
70: static certificate_t* create_cert(certificate_t *ca, char *subject, char *san,
71: x509_flag_t flags, identification_t *permitted,
72: identification_t *excluded)
73: {
74: private_key_t *privkey;
75: public_key_t *pubkey;
76: certificate_t *cert;
77: identification_t *id;
78: linked_list_t *plist, *elist, *sans;
79:
80: privkey = lib->creds->create(lib->creds, CRED_PRIVATE_KEY, KEY_RSA,
81: BUILD_BLOB_ASN1_DER, chunk_from_thing(keydata),
82: BUILD_END);
83: ck_assert(privkey);
84: pubkey = privkey->get_public_key(privkey);
85: ck_assert(pubkey);
86: plist = linked_list_create();
87: if (permitted)
88: {
89: plist->insert_last(plist, permitted);
90: }
91: elist = linked_list_create();
92: if (excluded)
93: {
94: elist->insert_last(elist, excluded);
95: }
96: sans = linked_list_create();
97: if (san)
98: {
99: id = identification_create_from_string(san);
100: sans->insert_last(sans, id);
101: }
102: id = identification_create_from_string(subject);
103: cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
104: BUILD_SIGNING_KEY, privkey,
105: BUILD_PUBLIC_KEY, pubkey,
106: BUILD_SUBJECT, id,
107: BUILD_X509_FLAG, flags,
108: BUILD_SIGNING_CERT, ca,
109: BUILD_SUBJECT_ALTNAMES, sans,
110: BUILD_PERMITTED_NAME_CONSTRAINTS, plist,
111: BUILD_EXCLUDED_NAME_CONSTRAINTS, elist,
112: BUILD_END);
113: ck_assert(cert);
114: id->destroy(id);
115: sans->destroy_offset(sans, offsetof(identification_t, destroy));
116: plist->destroy_offset(plist, offsetof(identification_t, destroy));
117: elist->destroy_offset(elist, offsetof(identification_t, destroy));
118: privkey->destroy(privkey);
119: pubkey->destroy(pubkey);
120:
121: return cert;
122: }
123:
124: /**
125: * Check if a certificate with given subject has a valid trustchain
126: */
127: static bool check_trust(identification_t *subject)
128: {
129: enumerator_t *certs;
130: certificate_t *cert;
131: bool trusted;
132:
133: certs = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY,
134: subject, FALSE);
135: trusted = certs->enumerate(certs, &cert, NULL);
136: certs->destroy(certs);
137:
138: return trusted;
139: }
140:
141: static mem_cred_t *creds;
142:
143: START_SETUP(setup)
144: {
145: creds = mem_cred_create();
146: lib->credmgr->add_set(lib->credmgr, &creds->set);
147: }
148: END_SETUP
149:
150: START_TEARDOWN(teardown)
151: {
152: lib->credmgr->remove_set(lib->credmgr, &creds->set);
153: creds->destroy(creds);
154: lib->credmgr->flush_cache(lib->credmgr, CERT_ANY);
155: }
156: END_TEARDOWN
157:
158: static struct {
159: char *constraint;
160: char *subject;
161: bool good;
162: } permitted_dn[] = {
163: { "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", TRUE },
164: { "C=CH, O=strongSwan", "C=CH, O=strong", FALSE },
165: { "C=CH, O=strongSwan", "C=CH, O=strong, CN=tester", FALSE },
166: { "C=CH, O=strongSwan", "C=CH, O=another, CN=tester", FALSE },
167: { "C=CH, O=strongSwan", "C=CH, CN=tester, O=strongSwan", FALSE },
168: };
169:
170: START_TEST(test_permitted_dn)
171: {
172: certificate_t *ca, *im, *sj;
173: identification_t *id;
174:
175: id = identification_create_from_string(permitted_dn[_i].constraint);
176: ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, id, NULL);
177: id = identification_create_from_string(permitted_dn[_i].constraint);
178: im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, id, NULL);
179: sj = create_cert(im, permitted_dn[_i].subject, NULL, 0, NULL, NULL);
180:
181: creds->add_cert(creds, TRUE, ca);
182: creds->add_cert(creds, FALSE, im);
183: creds->add_cert(creds, FALSE, sj);
184:
185: ck_assert(check_trust(sj->get_subject(sj)) == permitted_dn[_i].good);
186: }
187: END_TEST
188:
189: static struct {
190: id_type_t ctype;
191: char *cdata;
192: char *subject;
193: bool good;
194: } permitted_san[] = {
195: { ID_FQDN, ".strongswan.org", "test.strongswan.org", TRUE },
196: { ID_FQDN, "strongswan.org", "test.strongswan.org", TRUE },
197: { ID_FQDN, "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", TRUE },
198: { ID_FQDN, "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", FALSE },
199: { ID_FQDN, "strongswan.org", "strongswan.org.com", FALSE },
200: { ID_FQDN, ".strongswan.org", "strongswan.org", FALSE },
201: { ID_FQDN, "strongswan.org", "nostrongswan.org", FALSE },
202: { ID_FQDN, "strongswan.org", "swan.org", FALSE },
203: { ID_FQDN, "strongswan.org", "swan.org", FALSE },
204: { ID_RFC822_ADDR, "tester@strongswan.org", "tester@strongswan.org", TRUE },
205: { ID_RFC822_ADDR, "tester@strongswan.org", "atester@strongswan.org", FALSE },
206: { ID_RFC822_ADDR, "strongswan.org", "tester@strongswan.org", TRUE },
207: { ID_RFC822_ADDR, "strongswan.org", "tester@test.strongswan.org", FALSE },
208: { ID_RFC822_ADDR, ".strongswan.org", "tester@test.strongswan.org", TRUE },
209: { ID_RFC822_ADDR, ".strongswan.org", "tester@strongswan.org", FALSE },
210: };
211:
212: START_TEST(test_permitted_san)
213: {
214: certificate_t *ca, *sj;
215: identification_t *id;
216:
217: id = identification_create_from_encoding(permitted_san[_i].ctype,
218: chunk_from_str(permitted_san[_i].cdata));
219: ca = create_cert(NULL, "CN=CA", NULL, X509_CA, id, NULL);
220: sj = create_cert(ca, "CN=SJ", permitted_san[_i].subject, 0, NULL, NULL);
221:
222: creds->add_cert(creds, TRUE, ca);
223: creds->add_cert(creds, FALSE, sj);
224:
225: ck_assert(check_trust(sj->get_subject(sj)) == permitted_san[_i].good);
226: }
227: END_TEST
228:
229: static struct {
230: char *constraint;
231: char *subject;
232: bool good;
233: } excluded_dn[] = {
234: { "C=CH, O=another", "C=CH, O=strongSwan, CN=tester", TRUE },
235: { "C=CH, O=another", "C=CH, O=anot", TRUE },
236: { "C=CH, O=another", "C=CH, O=anot, CN=tester", TRUE },
237: { "C=CH, O=another", "C=CH, O=another, CN=tester", FALSE },
238: { "C=CH, O=another", "C=CH, CN=tester, O=another", TRUE },
239: };
240:
241: START_TEST(test_excluded_dn)
242: {
243: certificate_t *ca, *im, *sj;
244: identification_t *id;
245:
246: id = identification_create_from_string(excluded_dn[_i].constraint);
247: ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, NULL, id);
248: id = identification_create_from_string(excluded_dn[_i].constraint);
249: im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, NULL, id);
250: sj = create_cert(im, excluded_dn[_i].subject, NULL, 0, NULL, NULL);
251:
252: creds->add_cert(creds, TRUE, ca);
253: creds->add_cert(creds, FALSE, im);
254: creds->add_cert(creds, FALSE, sj);
255:
256: ck_assert(check_trust(sj->get_subject(sj)) == excluded_dn[_i].good);
257: }
258: END_TEST
259:
260: static struct {
261: id_type_t ctype;
262: char *cdata;
263: char *subject;
264: bool good;
265: } excluded_san[] = {
266: { ID_FQDN, ".strongswan.org", "test.strongswan.org", FALSE },
267: { ID_FQDN, "strongswan.org", "test.strongswan.org", FALSE },
268: { ID_FQDN, "a.b.c.strongswan.org", "d.a.b.c.strongswan.org", FALSE },
269: { ID_FQDN, "a.b.c.strongswan.org", "a.b.c.d.strongswan.org", TRUE },
270: { ID_FQDN, "strongswan.org", "strongswan.org.com", TRUE },
271: { ID_FQDN, ".strongswan.org", "strongswan.org", TRUE },
272: { ID_FQDN, "strongswan.org", "nostrongswan.org", TRUE },
273: { ID_FQDN, "strongswan.org", "swan.org", TRUE },
274: { ID_FQDN, "strongswan.org", "swan.org", TRUE },
275: { ID_RFC822_ADDR, "tester@strongswan.org", "tester@strongswan.org", FALSE },
276: { ID_RFC822_ADDR, "tester@strongswan.org", "atester@strongswan.org", TRUE },
277: { ID_RFC822_ADDR, "strongswan.org", "tester@strongswan.org", FALSE },
278: { ID_RFC822_ADDR, "strongswan.org", "tester@test.strongswan.org", TRUE },
279: { ID_RFC822_ADDR, ".strongswan.org", "tester@test.strongswan.org", FALSE },
280: { ID_RFC822_ADDR, ".strongswan.org", "tester@strongswan.org", TRUE },
281: };
282:
283: START_TEST(test_excluded_san)
284: {
285: certificate_t *ca, *sj;
286: identification_t *id;
287:
288: id = identification_create_from_encoding(excluded_san[_i].ctype,
289: chunk_from_str(excluded_san[_i].cdata));
290: ca = create_cert(NULL, "CN=CA", NULL, X509_CA, NULL, id);
291: sj = create_cert(ca, "CN=SJ", excluded_san[_i].subject, 0, NULL, NULL);
292:
293: creds->add_cert(creds, TRUE, ca);
294: creds->add_cert(creds, FALSE, sj);
295:
296: ck_assert(check_trust(sj->get_subject(sj)) == excluded_san[_i].good);
297: }
298: END_TEST
299:
300: static struct {
301: char *caconst;
302: char *imconst;
303: char *subject;
304: bool good;
305: } permitted_dninh[] = {
306: { "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", TRUE },
307: { "C=CH", "C=DE, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE },
308: { "C=CH, O=strongSwan", "C=CH", "C=CH", FALSE },
309: };
310:
311: START_TEST(test_permitted_dninh)
312: {
313: certificate_t *ca, *im, *sj;
314: identification_t *id;
315:
316: id = identification_create_from_string(permitted_dninh[_i].caconst);
317: ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, id, NULL);
318: id = identification_create_from_string(permitted_dninh[_i].imconst);
319: im = create_cert(ca, "C=CH, O=strongSwan, CN=IM", NULL, X509_CA, id, NULL);
320: sj = create_cert(im, permitted_dninh[_i].subject, NULL, 0, NULL, NULL);
321:
322: creds->add_cert(creds, TRUE, ca);
323: creds->add_cert(creds, FALSE, im);
324: creds->add_cert(creds, FALSE, sj);
325:
326: ck_assert(check_trust(sj->get_subject(sj)) == permitted_dninh[_i].good);
327: }
328: END_TEST
329:
330: static struct {
331: char *caconst;
332: char *imconst;
333: char *subject;
334: bool good;
335: } excluded_dninh[] = {
336: { "C=CH, O=strongSwan", "C=CH", "C=DE", TRUE },
337: { "C=CH, O=strongSwan", "C=DE", "C=CH", FALSE },
338: { "C=CH", "C=CH, O=strongSwan", "C=CH, O=strongSwan, CN=tester", FALSE },
339: };
340:
341: START_TEST(test_excluded_dninh)
342: {
343: certificate_t *ca, *im, *sj;
344: identification_t *id;
345:
346: id = identification_create_from_string(excluded_dninh[_i].caconst);
347: ca = create_cert(NULL, "C=CH, O=strongSwan, CN=CA", NULL, X509_CA, NULL, id);
348: id = identification_create_from_string(excluded_dninh[_i].imconst);
349: im = create_cert(ca, "C=DE, CN=IM", NULL, X509_CA, NULL, id);
350: sj = create_cert(im, excluded_dninh[_i].subject, NULL, 0, NULL, NULL);
351:
352: creds->add_cert(creds, TRUE, ca);
353: creds->add_cert(creds, FALSE, im);
354: creds->add_cert(creds, FALSE, sj);
355:
356: ck_assert(check_trust(sj->get_subject(sj)) == excluded_dninh[_i].good);
357: }
358: END_TEST
359:
360: Suite *certnames_suite_create()
361: {
362: Suite *s;
363: TCase *tc;
364:
365: s = suite_create("certnames");
366:
367: tc = tcase_create("permitted DN name constraints");
368: tcase_add_checked_fixture(tc, setup, teardown);
369: tcase_add_loop_test(tc, test_permitted_dn, 0, countof(permitted_dn));
370: suite_add_tcase(s, tc);
371:
372: tc = tcase_create("permitted subjectAltName constraints");
373: tcase_add_checked_fixture(tc, setup, teardown);
374: tcase_add_loop_test(tc, test_permitted_san, 0, countof(permitted_san));
375: suite_add_tcase(s, tc);
376:
377: tc = tcase_create("excluded DN constraints");
378: tcase_add_checked_fixture(tc, setup, teardown);
379: tcase_add_loop_test(tc, test_excluded_dn, 0, countof(excluded_dn));
380: suite_add_tcase(s, tc);
381:
382: tc = tcase_create("excluded subjectAltName constraints");
383: tcase_add_checked_fixture(tc, setup, teardown);
384: tcase_add_loop_test(tc, test_excluded_san, 0, countof(excluded_san));
385: suite_add_tcase(s, tc);
386:
387: tc = tcase_create("permitted DN name constraint inherit");
388: tcase_add_checked_fixture(tc, setup, teardown);
389: tcase_add_loop_test(tc, test_permitted_dninh, 0, countof(permitted_dninh));
390: suite_add_tcase(s, tc);
391:
392: tc = tcase_create("excluded DN name constraint inherit");
393: tcase_add_checked_fixture(tc, setup, teardown);
394: tcase_add_loop_test(tc, test_excluded_dninh, 0, countof(excluded_dninh));
395: suite_add_tcase(s, tc);
396:
397: return s;
398: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>