identification: Optionally match RDNs in any order and accept missing RDNs
[strongswan.git] / src / libstrongswan / utils / identification.c
1 /*
2 * Copyright (C) 2016 Andreas Steffen
3 * Copyright (C) 2009-2019 Tobias Brunner
4 * Copyright (C) 2005-2009 Martin Willi
5 * Copyright (C) 2005 Jan Hutter
6 * HSR Hochschule fuer Technik Rapperswil
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 #include <string.h>
20 #include <stdio.h>
21 #include <errno.h>
22
23 #include "identification.h"
24
25 #include <utils/utils.h>
26 #include <asn1/oid.h>
27 #include <asn1/asn1.h>
28 #include <crypto/hashers/hasher.h>
29 #include <collections/array.h>
30
31 ENUM_BEGIN(id_match_names, ID_MATCH_NONE, ID_MATCH_MAX_WILDCARDS,
32 "MATCH_NONE",
33 "MATCH_ANY",
34 "MATCH_MAX_WILDCARDS");
35 ENUM_NEXT(id_match_names, ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_MAX_WILDCARDS,
36 "MATCH_PERFECT");
37 ENUM_END(id_match_names, ID_MATCH_PERFECT);
38
39 ENUM_BEGIN(id_type_names, ID_ANY, ID_KEY_ID,
40 "ID_ANY",
41 "ID_IPV4_ADDR",
42 "ID_FQDN",
43 "ID_RFC822_ADDR",
44 "ID_IPV4_ADDR_SUBNET",
45 "ID_IPV6_ADDR",
46 "ID_IPV6_ADDR_SUBNET",
47 "ID_IPV4_ADDR_RANGE",
48 "ID_IPV6_ADDR_RANGE",
49 "ID_DER_ASN1_DN",
50 "ID_DER_ASN1_GN",
51 "ID_KEY_ID");
52 ENUM_NEXT(id_type_names, ID_DER_ASN1_GN_URI, ID_DER_ASN1_GN_URI, ID_KEY_ID,
53 "ID_DER_ASN1_GN_URI");
54 ENUM_END(id_type_names, ID_DER_ASN1_GN_URI);
55
56 /**
57 * coding of X.501 distinguished name
58 */
59 typedef struct {
60 const u_char *name;
61 int oid;
62 u_char type;
63 } x501rdn_t;
64
65 static const x501rdn_t x501rdns[] = {
66 {"ND", OID_NAME_DISTINGUISHER, ASN1_PRINTABLESTRING},
67 {"UID", OID_PILOT_USERID, ASN1_PRINTABLESTRING},
68 {"DC", OID_PILOT_DOMAIN_COMPONENT, ASN1_PRINTABLESTRING},
69 {"CN", OID_COMMON_NAME, ASN1_PRINTABLESTRING},
70 {"S", OID_SURNAME, ASN1_PRINTABLESTRING},
71 {"SN", OID_SERIAL_NUMBER, ASN1_PRINTABLESTRING},
72 {"serialNumber", OID_SERIAL_NUMBER, ASN1_PRINTABLESTRING},
73 {"C", OID_COUNTRY, ASN1_PRINTABLESTRING},
74 {"L", OID_LOCALITY, ASN1_PRINTABLESTRING},
75 {"ST", OID_STATE_OR_PROVINCE, ASN1_PRINTABLESTRING},
76 {"STREET", OID_STREET_ADDRESS, ASN1_PRINTABLESTRING},
77 {"O", OID_ORGANIZATION, ASN1_PRINTABLESTRING},
78 {"OU", OID_ORGANIZATION_UNIT, ASN1_PRINTABLESTRING},
79 {"T", OID_TITLE, ASN1_PRINTABLESTRING},
80 {"D", OID_DESCRIPTION, ASN1_PRINTABLESTRING},
81 {"postalAddress", OID_POSTAL_ADDRESS, ASN1_PRINTABLESTRING},
82 {"postalCode", OID_POSTAL_CODE, ASN1_PRINTABLESTRING},
83 {"N", OID_NAME, ASN1_PRINTABLESTRING},
84 {"G", OID_GIVEN_NAME, ASN1_PRINTABLESTRING},
85 {"I", OID_INITIALS, ASN1_PRINTABLESTRING},
86 {"dnQualifier", OID_DN_QUALIFIER, ASN1_PRINTABLESTRING},
87 {"dmdName", OID_DMD_NAME, ASN1_PRINTABLESTRING},
88 {"pseudonym", OID_PSEUDONYM, ASN1_PRINTABLESTRING},
89 {"ID", OID_UNIQUE_IDENTIFIER, ASN1_PRINTABLESTRING},
90 {"EN", OID_EMPLOYEE_NUMBER, ASN1_PRINTABLESTRING},
91 {"employeeNumber", OID_EMPLOYEE_NUMBER, ASN1_PRINTABLESTRING},
92 {"E", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
93 {"Email", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
94 {"emailAddress", OID_EMAIL_ADDRESS, ASN1_IA5STRING},
95 {"UN", OID_UNSTRUCTURED_NAME, ASN1_IA5STRING},
96 {"unstructuredName", OID_UNSTRUCTURED_NAME, ASN1_IA5STRING},
97 {"UA", OID_UNSTRUCTURED_ADDRESS, ASN1_PRINTABLESTRING},
98 {"unstructuredAddress", OID_UNSTRUCTURED_ADDRESS, ASN1_PRINTABLESTRING},
99 {"TCGID", OID_TCGID, ASN1_PRINTABLESTRING}
100 };
101
102 /**
103 * maximum number of RDNs in atodn()
104 */
105 #define RDN_MAX 20
106
107
108 typedef struct private_identification_t private_identification_t;
109
110 /**
111 * Private data of an identification_t object.
112 */
113 struct private_identification_t {
114 /**
115 * Public interface.
116 */
117 identification_t public;
118
119 /**
120 * Encoded representation of this ID.
121 */
122 chunk_t encoded;
123
124 /**
125 * Type of this ID.
126 */
127 id_type_t type;
128 };
129
130 /**
131 * Enumerator over RDNs
132 */
133 typedef struct {
134 /* implements enumerator interface */
135 enumerator_t public;
136 /* next set to parse, if any */
137 chunk_t sets;
138 /* next sequence in set, if any */
139 chunk_t seqs;
140 } rdn_enumerator_t;
141
142 METHOD(enumerator_t, rdn_enumerate, bool,
143 rdn_enumerator_t *this, va_list args)
144 {
145 chunk_t rdn, *oid, *data;
146 u_char *type;
147
148 VA_ARGS_VGET(args, oid, type, data);
149
150 /* a DN contains one or more SET, each containing one or more SEQUENCES,
151 * each containing a OID/value RDN */
152 if (!this->seqs.len)
153 {
154 /* no SEQUENCEs in current SET, parse next SET */
155 if (asn1_unwrap(&this->sets, &this->seqs) != ASN1_SET)
156 {
157 return FALSE;
158 }
159 }
160 if (asn1_unwrap(&this->seqs, &rdn) == ASN1_SEQUENCE &&
161 asn1_unwrap(&rdn, oid) == ASN1_OID)
162 {
163 int t = asn1_unwrap(&rdn, data);
164
165 if (t != ASN1_INVALID)
166 {
167 *type = t;
168 return TRUE;
169 }
170 }
171 return FALSE;
172 }
173
174 /**
175 * Create an enumerator over all RDNs (oid, string type, data) of a DN
176 */
177 static enumerator_t* create_rdn_enumerator(chunk_t dn)
178 {
179 rdn_enumerator_t *e;
180
181 INIT(e,
182 .public = {
183 .enumerate = enumerator_enumerate_default,
184 .venumerate = _rdn_enumerate,
185 .destroy = (void*)free,
186 },
187 );
188
189 /* a DN is a SEQUENCE, get the first SET of it */
190 if (asn1_unwrap(&dn, &e->sets) == ASN1_SEQUENCE)
191 {
192 e->seqs = chunk_empty;
193 return &e->public;
194 }
195 free(e);
196 return enumerator_create_empty();
197 }
198
199 /**
200 * Part enumerator over RDNs
201 */
202 typedef struct {
203 /* implements enumerator interface */
204 enumerator_t public;
205 /* inner RDN enumerator */
206 enumerator_t *inner;
207 } rdn_part_enumerator_t;
208
209 METHOD(enumerator_t, rdn_part_enumerate, bool,
210 rdn_part_enumerator_t *this, va_list args)
211 {
212 int i, known_oid, strtype;
213 chunk_t oid, inner_data, *data;
214 id_part_t *type;
215 static const struct {
216 int oid;
217 id_part_t type;
218 } oid2part[] = {
219 {OID_COMMON_NAME, ID_PART_RDN_CN},
220 {OID_SURNAME, ID_PART_RDN_S},
221 {OID_SERIAL_NUMBER, ID_PART_RDN_SN},
222 {OID_COUNTRY, ID_PART_RDN_C},
223 {OID_LOCALITY, ID_PART_RDN_L},
224 {OID_STATE_OR_PROVINCE, ID_PART_RDN_ST},
225 {OID_ORGANIZATION, ID_PART_RDN_O},
226 {OID_ORGANIZATION_UNIT, ID_PART_RDN_OU},
227 {OID_TITLE, ID_PART_RDN_T},
228 {OID_DESCRIPTION, ID_PART_RDN_D},
229 {OID_NAME, ID_PART_RDN_N},
230 {OID_GIVEN_NAME, ID_PART_RDN_G},
231 {OID_INITIALS, ID_PART_RDN_I},
232 {OID_DN_QUALIFIER, ID_PART_RDN_DNQ},
233 {OID_DMD_NAME, ID_PART_RDN_DMDN},
234 {OID_PSEUDONYM, ID_PART_RDN_PN},
235 {OID_UNIQUE_IDENTIFIER, ID_PART_RDN_ID},
236 {OID_EMAIL_ADDRESS, ID_PART_RDN_E},
237 {OID_EMPLOYEE_NUMBER, ID_PART_RDN_EN},
238 };
239
240 VA_ARGS_VGET(args, type, data);
241
242 while (this->inner->enumerate(this->inner, &oid, &strtype, &inner_data))
243 {
244 known_oid = asn1_known_oid(oid);
245 for (i = 0; i < countof(oid2part); i++)
246 {
247 if (oid2part[i].oid == known_oid)
248 {
249 *type = oid2part[i].type;
250 *data = inner_data;
251 return TRUE;
252 }
253 }
254 }
255 return FALSE;
256 }
257
258 METHOD(enumerator_t, rdn_part_enumerator_destroy, void,
259 rdn_part_enumerator_t *this)
260 {
261 this->inner->destroy(this->inner);
262 free(this);
263 }
264
265 METHOD(identification_t, create_part_enumerator, enumerator_t*,
266 private_identification_t *this)
267 {
268 switch (this->type)
269 {
270 case ID_DER_ASN1_DN:
271 {
272 rdn_part_enumerator_t *e;
273
274 INIT(e,
275 .inner = create_rdn_enumerator(this->encoded),
276 .public = {
277 .enumerate = enumerator_enumerate_default,
278 .venumerate = _rdn_part_enumerate,
279 .destroy = _rdn_part_enumerator_destroy,
280 },
281 );
282 return &e->public;
283 }
284 case ID_RFC822_ADDR:
285 /* TODO */
286 case ID_FQDN:
287 /* TODO */
288 default:
289 return enumerator_create_empty();
290 }
291 }
292
293 /**
294 * Print a separator between two RDNs
295 */
296 static inline bool print_separator(char **buf, size_t *len)
297 {
298 int written;
299
300 written = snprintf(*buf, *len, ", ");
301 if (written < 0 || written >= *len)
302 {
303 return FALSE;
304 }
305 *buf += written;
306 *len -= written;
307 return TRUE;
308 }
309
310 /**
311 * Print a DN with all its RDN in a buffer to present it to the user
312 */
313 static void dntoa(chunk_t dn, char *buf, size_t len)
314 {
315 enumerator_t *e;
316 chunk_t oid_data, data, printable;
317 u_char type;
318 int oid, written;
319 bool finished = FALSE, empty = TRUE;
320
321 e = create_rdn_enumerator(dn);
322 while (e->enumerate(e, &oid_data, &type, &data))
323 {
324 empty = FALSE;
325
326 /* previous RDN was empty but it wasn't the last one */
327 if (finished && !print_separator(&buf, &len))
328 {
329 break;
330 }
331 finished = FALSE;
332
333 oid = asn1_known_oid(oid_data);
334 if (oid == OID_UNKNOWN)
335 {
336 written = snprintf(buf, len, "%#B=", &oid_data);
337 }
338 else
339 {
340 written = snprintf(buf, len,"%s=", oid_names[oid].name);
341 }
342 if (written < 0 || written >= len)
343 {
344 break;
345 }
346 buf += written;
347 len -= written;
348
349 written = 0;
350 chunk_printable(data, &printable, '?');
351 if (printable.ptr)
352 {
353 written = snprintf(buf, len, "%.*s", (int)printable.len,
354 printable.ptr);
355 }
356 chunk_free(&printable);
357 if (written < 0 || written >= len)
358 {
359 break;
360 }
361 buf += written;
362 len -= written;
363
364 if (!data.ptr)
365 { /* we can't calculate if we're finished, assume we are */
366 finished = TRUE;
367 }
368 else if (data.ptr + data.len == dn.ptr + dn.len)
369 {
370 finished = TRUE;
371 break;
372 }
373 else if (!print_separator(&buf, &len))
374 {
375 break;
376 }
377 }
378 if (empty)
379 {
380 snprintf(buf, len, "");
381 }
382 else if (!finished)
383 {
384 snprintf(buf, len, "(invalid ID_DER_ASN1_DN)");
385 }
386 e->destroy(e);
387 }
388
389 /**
390 * Converts an LDAP-style human-readable ASCII-encoded
391 * ASN.1 distinguished name into binary DER-encoded format
392 */
393 static status_t atodn(char *src, chunk_t *dn)
394 {
395 /* finite state machine for atodn */
396 typedef enum {
397 SEARCH_OID = 0,
398 READ_OID = 1,
399 SEARCH_NAME = 2,
400 READ_NAME = 3,
401 UNKNOWN_OID = 4
402 } state_t;
403
404 chunk_t oid = chunk_empty;
405 chunk_t name = chunk_empty;
406 chunk_t rdns[RDN_MAX];
407 int rdn_count = 0;
408 int dn_len = 0;
409 int whitespace = 0;
410 int i = 0;
411 asn1_t rdn_type;
412 state_t state = SEARCH_OID;
413 status_t status = SUCCESS;
414 char sep = '\0';
415
416 do
417 {
418 switch (state)
419 {
420 case SEARCH_OID:
421 if (!sep && *src == '/')
422 { /* use / as separator if the string starts with a slash */
423 sep = '/';
424 break;
425 }
426 if (*src != ' ' && *src != '\0')
427 {
428 if (!sep)
429 { /* use , as separator by default */
430 sep = ',';
431 }
432 oid.ptr = src;
433 oid.len = 1;
434 state = READ_OID;
435 }
436 break;
437 case READ_OID:
438 if (*src != ' ' && *src != '=')
439 {
440 oid.len++;
441 }
442 else
443 {
444 bool found = FALSE;
445
446 for (i = 0; i < countof(x501rdns); i++)
447 {
448 if (strlen(x501rdns[i].name) == oid.len &&
449 strncasecmp(x501rdns[i].name, oid.ptr, oid.len) == 0)
450 {
451 found = TRUE;
452 break;
453 }
454 }
455 if (!found)
456 {
457 status = NOT_SUPPORTED;
458 state = UNKNOWN_OID;
459 break;
460 }
461 /* reset oid and change state */
462 oid = chunk_empty;
463 state = SEARCH_NAME;
464 }
465 break;
466 case SEARCH_NAME:
467 if (*src == ' ' || *src == '=')
468 {
469 break;
470 }
471 else if (*src != sep && *src != '\0')
472 {
473 name.ptr = src;
474 name.len = 1;
475 whitespace = 0;
476 state = READ_NAME;
477 break;
478 }
479 name = chunk_empty;
480 whitespace = 0;
481 state = READ_NAME;
482 /* fall-through */
483 case READ_NAME:
484 if (*src != sep && *src != '\0')
485 {
486 name.len++;
487 if (*src == ' ')
488 whitespace++;
489 else
490 whitespace = 0;
491 }
492 else
493 {
494 name.len -= whitespace;
495 rdn_type = (x501rdns[i].type == ASN1_PRINTABLESTRING
496 && !asn1_is_printablestring(name))
497 ? ASN1_UTF8STRING : x501rdns[i].type;
498
499 if (rdn_count < RDN_MAX)
500 {
501 chunk_t rdn_oid;
502
503 rdn_oid = asn1_build_known_oid(x501rdns[i].oid);
504 if (rdn_oid.len)
505 {
506 rdns[rdn_count] =
507 asn1_wrap(ASN1_SET, "m",
508 asn1_wrap(ASN1_SEQUENCE, "mm",
509 rdn_oid,
510 asn1_wrap(rdn_type, "c", name)
511 )
512 );
513 dn_len += rdns[rdn_count++].len;
514 }
515 else
516 {
517 status = INVALID_ARG;
518 }
519 }
520 else
521 {
522 status = OUT_OF_RES;
523 }
524 /* reset name and change state */
525 name = chunk_empty;
526 state = SEARCH_OID;
527 }
528 break;
529 case UNKNOWN_OID:
530 break;
531 }
532 } while (*src++ != '\0');
533
534 if (state == READ_OID)
535 { /* unterminated OID */
536 status = INVALID_ARG;
537 }
538
539 /* build the distinguished name sequence */
540 {
541 int i;
542 u_char *pos = asn1_build_object(dn, ASN1_SEQUENCE, dn_len);
543
544 for (i = 0; i < rdn_count; i++)
545 {
546 memcpy(pos, rdns[i].ptr, rdns[i].len);
547 pos += rdns[i].len;
548 free(rdns[i].ptr);
549 }
550 }
551 if (status != SUCCESS)
552 {
553 free(dn->ptr);
554 *dn = chunk_empty;
555 }
556 return status;
557 }
558
559 METHOD(identification_t, get_encoding, chunk_t,
560 private_identification_t *this)
561 {
562 return this->encoded;
563 }
564
565 METHOD(identification_t, get_type, id_type_t,
566 private_identification_t *this)
567 {
568 return this->type;
569 }
570
571 /**
572 * Check if this is a wildcard value
573 */
574 static inline bool is_wildcard(chunk_t data)
575 {
576 return data.len == 1 && data.ptr[0] == '*';
577 }
578
579 METHOD(identification_t, contains_wildcards_dn, bool,
580 private_identification_t *this)
581 {
582 enumerator_t *enumerator;
583 bool contains = FALSE;
584 id_part_t type;
585 chunk_t data;
586
587 enumerator = create_part_enumerator(this);
588 while (enumerator->enumerate(enumerator, &type, &data))
589 {
590 if (is_wildcard(data))
591 {
592 contains = TRUE;
593 break;
594 }
595 }
596 enumerator->destroy(enumerator);
597 return contains;
598 }
599
600 METHOD(identification_t, contains_wildcards_memchr, bool,
601 private_identification_t *this)
602 {
603 return memchr(this->encoded.ptr, '*', this->encoded.len) != NULL;
604 }
605
606 METHOD(identification_t, hash_binary, u_int,
607 private_identification_t *this, u_int inc)
608 {
609 u_int hash;
610
611 hash = chunk_hash_inc(chunk_from_thing(this->type), inc);
612 if (this->type != ID_ANY)
613 {
614 hash = chunk_hash_inc(this->encoded, hash);
615 }
616 return hash;
617 }
618
619 METHOD(identification_t, equals_binary, bool,
620 private_identification_t *this, identification_t *other)
621 {
622 if (this->type == other->get_type(other))
623 {
624 if (this->type == ID_ANY)
625 {
626 return TRUE;
627 }
628 return chunk_equals(this->encoded, other->get_encoding(other));
629 }
630 return FALSE;
631 }
632
633 /**
634 * Compare two RDNs for equality, comparing some string types case insensitive
635 */
636 static bool rdn_equals(chunk_t oid, u_char a_type, chunk_t a, u_char b_type,
637 chunk_t b)
638 {
639 if (a_type == b_type &&
640 (a_type == ASN1_PRINTABLESTRING ||
641 (a_type == ASN1_IA5STRING &&
642 asn1_known_oid(oid) == OID_EMAIL_ADDRESS)))
643 { /* ignore case for printableStrings and email RDNs */
644 return strncaseeq(a.ptr, b.ptr, a.len);
645 }
646 else
647 { /* respect case and length for everything else */
648 return memeq(a.ptr, b.ptr, a.len);
649 }
650 }
651
652 /**
653 * RDNs when matching DNs
654 */
655 typedef struct {
656 chunk_t oid;
657 u_char type;
658 chunk_t data;
659 bool matched;
660 } rdn_t;
661
662 /**
663 * Match DNs (o_dn may contain wildcards and RDNs in a different order, if
664 * allow_unmatched is TRUE, t_dn may contain unmatched RDNs)
665 */
666 static bool match_dn(chunk_t t_dn, chunk_t o_dn, int *wc, bool allow_unmatched)
667 {
668 enumerator_t *enumerator;
669 array_t *rdns;
670 rdn_t *rdn, *found;
671 chunk_t oid, data;
672 u_char type;
673 bool finished = FALSE;
674 int i, regular = 0;
675
676 *wc = 0;
677
678 /* try a binary compare */
679 if (chunk_equals(t_dn, o_dn))
680 {
681 return TRUE;
682 }
683
684 rdns = array_create(0, 8);
685
686 enumerator = create_rdn_enumerator(o_dn);
687 while (TRUE)
688 {
689 if (!enumerator->enumerate(enumerator, &oid, &type, &data))
690 {
691 break;
692 }
693 INIT(rdn,
694 .oid = oid,
695 .type = type,
696 .data = data,
697 );
698 if (is_wildcard(data))
699 {
700 /* insert wildcards at the end, to perform exact matches first */
701 array_insert(rdns, ARRAY_TAIL, rdn);
702 }
703 else
704 {
705 array_insert(rdns, regular++, rdn);
706 }
707 /* the enumerator returns FALSE on parse error, we are finished
708 * if we have reached the end of the DN only */
709 if ((data.ptr + data.len == o_dn.ptr + o_dn.len))
710 {
711 finished = TRUE;
712 }
713 }
714 enumerator->destroy(enumerator);
715
716 if (!finished)
717 { /* invalid DN */
718 array_destroy_function(rdns, (void*)free, NULL);
719 return FALSE;
720 }
721 finished = FALSE;
722
723 enumerator = create_rdn_enumerator(t_dn);
724 while (TRUE)
725 {
726 if (!enumerator->enumerate(enumerator, &oid, &type, &data))
727 {
728 break;
729 }
730 for (i = 0, found = NULL; i < array_count(rdns); i++)
731 {
732 array_get(rdns, i, &rdn);
733 if (!rdn->matched && chunk_equals(rdn->oid, oid))
734 {
735 if (is_wildcard(rdn->data))
736 {
737 (*wc)++;
738 }
739 else if (data.len != rdn->data.len ||
740 !rdn_equals(oid, type, data, rdn->type, rdn->data))
741 {
742 continue;
743 }
744 rdn->matched = TRUE;
745 found = rdn;
746 break;
747 }
748 }
749 if (!found)
750 {
751 /* treat unmatched RDNs like wildcards if allowed */
752 if (!allow_unmatched)
753 {
754 break;
755 }
756 (*wc)++;
757 }
758 /* the enumerator returns FALSE on parse error, we are finished
759 * if we have reached the end of the DN only */
760 if ((data.ptr + data.len == t_dn.ptr + t_dn.len))
761 {
762 finished = TRUE;
763 }
764 }
765 enumerator->destroy(enumerator);
766
767 if (finished)
768 {
769 for (i = 0; i < array_count(rdns); i++)
770 {
771 array_get(rdns, i, &rdn);
772 if (!rdn->matched)
773 {
774 finished = FALSE;
775 }
776 }
777 }
778 array_destroy_function(rdns, (void*)free, NULL);
779 return finished;
780 }
781
782 /**
783 * Reordered RDNs are fine, but match all
784 */
785 static bool match_dn_reordered(chunk_t t_dn, chunk_t o_dn, int *wc)
786 {
787 return match_dn(t_dn, o_dn, wc, FALSE);
788 }
789
790 /**
791 * t_dn may contain more RDNs than o_dn
792 */
793 static bool match_dn_relaxed(chunk_t t_dn, chunk_t o_dn, int *wc)
794 {
795 return match_dn(t_dn, o_dn, wc, TRUE);
796 }
797
798 /**
799 * Compare two DNs, for equality if wc == NULL, with wildcard matching otherwise
800 */
801 static bool compare_dn(chunk_t t_dn, chunk_t o_dn, int *wc)
802 {
803 enumerator_t *t, *o;
804 chunk_t t_oid, o_oid, t_data, o_data;
805 u_char t_type, o_type;
806 bool t_next, o_next, finished = FALSE;
807
808 if (wc)
809 {
810 *wc = 0;
811 }
812 else if (t_dn.len != o_dn.len)
813 {
814 return FALSE;
815 }
816
817 if (chunk_equals(t_dn, o_dn))
818 {
819 return TRUE;
820 }
821
822 t = create_rdn_enumerator(t_dn);
823 o = create_rdn_enumerator(o_dn);
824 while (TRUE)
825 {
826 t_next = t->enumerate(t, &t_oid, &t_type, &t_data);
827 o_next = o->enumerate(o, &o_oid, &o_type, &o_data);
828
829 if (!o_next && !t_next)
830 {
831 break;
832 }
833 finished = FALSE;
834 if (o_next != t_next)
835 {
836 break;
837 }
838 if (!chunk_equals(t_oid, o_oid))
839 {
840 break;
841 }
842 if (wc && is_wildcard(o_data))
843 {
844 (*wc)++;
845 }
846 else
847 {
848 if (t_data.len != o_data.len)
849 {
850 break;
851 }
852 if (!rdn_equals(t_oid, t_type, t_data, o_type, o_data))
853 {
854 break;
855 }
856 }
857 /* the enumerator returns FALSE on parse error, we are finished
858 * if we have reached the end of the DN only */
859 if ((t_data.ptr + t_data.len == t_dn.ptr + t_dn.len) &&
860 (o_data.ptr + o_data.len == o_dn.ptr + o_dn.len))
861 {
862 finished = TRUE;
863 }
864 }
865 t->destroy(t);
866 o->destroy(o);
867 return finished;
868 }
869
870 METHOD(identification_t, equals_dn, bool,
871 private_identification_t *this, identification_t *other)
872 {
873 return compare_dn(this->encoded, other->get_encoding(other), NULL);
874 }
875
876 METHOD(identification_t, hash_dn, u_int,
877 private_identification_t *this, u_int inc)
878 {
879 enumerator_t *rdns;
880 chunk_t oid, data;
881 u_char type;
882 u_int hash;
883
884 hash = chunk_hash_inc(chunk_from_thing(this->type), inc);
885 rdns = create_rdn_enumerator(this->encoded);
886 while (rdns->enumerate(rdns, &oid, &type, &data))
887 {
888 hash = chunk_hash_inc(data, chunk_hash_inc(oid, hash));
889 }
890 rdns->destroy(rdns);
891 return hash;
892 }
893
894 METHOD(identification_t, equals_strcasecmp, bool,
895 private_identification_t *this, identification_t *other)
896 {
897 chunk_t encoded = other->get_encoding(other);
898
899 /* we do some extra sanity checks to check for invalid IDs with a
900 * terminating null in it. */
901 if (this->type == other->get_type(other) &&
902 this->encoded.len == encoded.len &&
903 memchr(this->encoded.ptr, 0, this->encoded.len) == NULL &&
904 memchr(encoded.ptr, 0, encoded.len) == NULL &&
905 strncasecmp(this->encoded.ptr, encoded.ptr, this->encoded.len) == 0)
906 {
907 return TRUE;
908 }
909 return FALSE;
910 }
911
912 METHOD(identification_t, matches_binary, id_match_t,
913 private_identification_t *this, identification_t *other)
914 {
915 if (other->get_type(other) == ID_ANY)
916 {
917 return ID_MATCH_ANY;
918 }
919 if (this->type == other->get_type(other) &&
920 chunk_equals(this->encoded, other->get_encoding(other)))
921 {
922 return ID_MATCH_PERFECT;
923 }
924 return ID_MATCH_NONE;
925 }
926
927 METHOD(identification_t, matches_string, id_match_t,
928 private_identification_t *this, identification_t *other)
929 {
930 chunk_t encoded = other->get_encoding(other);
931 u_int len = encoded.len;
932
933 if (other->get_type(other) == ID_ANY)
934 {
935 return ID_MATCH_ANY;
936 }
937 if (this->type != other->get_type(other))
938 {
939 return ID_MATCH_NONE;
940 }
941 /* try a equals check first */
942 if (equals_strcasecmp(this, other))
943 {
944 return ID_MATCH_PERFECT;
945 }
946 if (len == 0 || this->encoded.len < len)
947 {
948 return ID_MATCH_NONE;
949 }
950
951 /* check for single wildcard at the head of the string */
952 if (*encoded.ptr == '*')
953 {
954 /* single asterisk matches any string */
955 if (len-- == 1)
956 { /* not better than ID_ANY */
957 return ID_MATCH_ANY;
958 }
959 if (strncasecmp(this->encoded.ptr + this->encoded.len - len,
960 encoded.ptr + 1, len) == 0)
961 {
962 return ID_MATCH_ONE_WILDCARD;
963 }
964 }
965 return ID_MATCH_NONE;
966 }
967
968 METHOD(identification_t, matches_any, id_match_t,
969 private_identification_t *this, identification_t *other)
970 {
971 if (other->get_type(other) == ID_ANY)
972 {
973 return ID_MATCH_ANY;
974 }
975 return ID_MATCH_NONE;
976 }
977
978 /**
979 * Match DNs given the matching function
980 */
981 static id_match_t matches_dn_internal(private_identification_t *this,
982 identification_t *other,
983 bool (*match)(chunk_t,chunk_t,int*))
984 {
985 int wc;
986
987 if (other->get_type(other) == ID_ANY)
988 {
989 return ID_MATCH_ANY;
990 }
991
992 if (this->type == other->get_type(other))
993 {
994 if (match(this->encoded, other->get_encoding(other), &wc))
995 {
996 wc = min(wc, ID_MATCH_ONE_WILDCARD - ID_MATCH_MAX_WILDCARDS);
997 return ID_MATCH_PERFECT - wc;
998 }
999 }
1000 return ID_MATCH_NONE;
1001 }
1002
1003 METHOD(identification_t, matches_dn, id_match_t,
1004 private_identification_t *this, identification_t *other)
1005 {
1006 return matches_dn_internal(this, other, compare_dn);
1007 }
1008
1009 METHOD(identification_t, matches_dn_reordered, id_match_t,
1010 private_identification_t *this, identification_t *other)
1011 {
1012 return matches_dn_internal(this, other, match_dn_reordered);
1013 }
1014
1015 METHOD(identification_t, matches_dn_relaxed, id_match_t,
1016 private_identification_t *this, identification_t *other)
1017 {
1018 return matches_dn_internal(this, other, match_dn_relaxed);
1019 }
1020
1021 /**
1022 * Transform netmask to CIDR bits
1023 */
1024 static int netmask_to_cidr(char *netmask, size_t address_size)
1025 {
1026 uint8_t byte;
1027 int i, netbits = 0;
1028
1029 for (i = 0; i < address_size; i++)
1030 {
1031 byte = netmask[i];
1032
1033 if (byte == 0x00)
1034 {
1035 break;
1036 }
1037 if (byte == 0xff)
1038 {
1039 netbits += 8;
1040 }
1041 else
1042 {
1043 while (byte & 0x80)
1044 {
1045 netbits++;
1046 byte <<= 1;
1047 }
1048 }
1049 }
1050 return netbits;
1051 }
1052
1053 METHOD(identification_t, matches_range, id_match_t,
1054 private_identification_t *this, identification_t *other)
1055 {
1056 chunk_t other_encoding;
1057 uint8_t *address, *from, *to, *network, *netmask;
1058 size_t address_size = 0;
1059 int netbits, range_sign, i;
1060
1061 if (other->get_type(other) == ID_ANY)
1062 {
1063 return ID_MATCH_ANY;
1064 }
1065 if (this->type == other->get_type(other) &&
1066 chunk_equals(this->encoded, other->get_encoding(other)))
1067 {
1068 return ID_MATCH_PERFECT;
1069 }
1070 if ((this->type == ID_IPV4_ADDR &&
1071 other->get_type(other) == ID_IPV4_ADDR_SUBNET))
1072 {
1073 address_size = sizeof(struct in_addr);
1074 }
1075 else if ((this->type == ID_IPV6_ADDR &&
1076 other->get_type(other) == ID_IPV6_ADDR_SUBNET))
1077 {
1078 address_size = sizeof(struct in6_addr);
1079 }
1080 if (address_size)
1081 {
1082 other_encoding = other->get_encoding(other);
1083 if (this->encoded.len != address_size ||
1084 other_encoding.len != 2 * address_size)
1085 {
1086 return ID_MATCH_NONE;
1087 }
1088 address = this->encoded.ptr;
1089 network = other_encoding.ptr;
1090 netmask = other_encoding.ptr + address_size;
1091 netbits = netmask_to_cidr(netmask, address_size);
1092
1093 if (netbits == 0)
1094 {
1095 return ID_MATCH_MAX_WILDCARDS;
1096 }
1097 if (netbits == 8 * address_size)
1098 {
1099 return memeq(address, network, address_size) ?
1100 ID_MATCH_PERFECT : ID_MATCH_NONE;
1101 }
1102 for (i = 0; i < (netbits + 7)/8; i++)
1103 {
1104 if ((address[i] ^ network[i]) & netmask[i])
1105 {
1106 return ID_MATCH_NONE;
1107 }
1108 }
1109 return ID_MATCH_ONE_WILDCARD;
1110 }
1111 if ((this->type == ID_IPV4_ADDR &&
1112 other->get_type(other) == ID_IPV4_ADDR_RANGE))
1113 {
1114 address_size = sizeof(struct in_addr);
1115 }
1116 else if ((this->type == ID_IPV6_ADDR &&
1117 other->get_type(other) == ID_IPV6_ADDR_RANGE))
1118 {
1119 address_size = sizeof(struct in6_addr);
1120 }
1121 if (address_size)
1122 {
1123 other_encoding = other->get_encoding(other);
1124 if (this->encoded.len != address_size ||
1125 other_encoding.len != 2 * address_size)
1126 {
1127 return ID_MATCH_NONE;
1128 }
1129 address = this->encoded.ptr;
1130 from = other_encoding.ptr;
1131 to = other_encoding.ptr + address_size;
1132
1133 range_sign = memcmp(to, from, address_size);
1134 if (range_sign < 0)
1135 { /* to is smaller than from */
1136 return ID_MATCH_NONE;
1137 }
1138
1139 /* check lower bound */
1140 for (i = 0; i < address_size; i++)
1141 {
1142 if (address[i] != from[i])
1143 {
1144 if (address[i] < from[i])
1145 {
1146 return ID_MATCH_NONE;
1147 }
1148 break;
1149 }
1150 }
1151
1152 /* check upper bound */
1153 for (i = 0; i < address_size; i++)
1154 {
1155 if (address[i] != to[i])
1156 {
1157 if (address[i] > to[i])
1158 {
1159 return ID_MATCH_NONE;
1160 }
1161 break;
1162 }
1163 }
1164 return range_sign ? ID_MATCH_ONE_WILDCARD : ID_MATCH_PERFECT;
1165 }
1166 return ID_MATCH_NONE;
1167 }
1168
1169 /**
1170 * Described in header.
1171 */
1172 int identification_printf_hook(printf_hook_data_t *data,
1173 printf_hook_spec_t *spec, const void *const *args)
1174 {
1175 private_identification_t *this = *((private_identification_t**)(args[0]));
1176 chunk_t proper;
1177 char buf[BUF_LEN], *pos;
1178 size_t len, address_size;
1179 int written;
1180
1181 if (this == NULL)
1182 {
1183 return print_in_hook(data, "%*s", spec->width, "(null)");
1184 }
1185
1186 switch (this->type)
1187 {
1188 case ID_ANY:
1189 snprintf(buf, BUF_LEN, "%%any");
1190 break;
1191 case ID_IPV4_ADDR:
1192 if (this->encoded.len < sizeof(struct in_addr) ||
1193 inet_ntop(AF_INET, this->encoded.ptr, buf, BUF_LEN) == NULL)
1194 {
1195 snprintf(buf, BUF_LEN, "(invalid ID_IPV4_ADDR)");
1196 }
1197 break;
1198 case ID_IPV4_ADDR_SUBNET:
1199 address_size = sizeof(struct in_addr);
1200 if (this->encoded.len < 2 * address_size ||
1201 inet_ntop(AF_INET, this->encoded.ptr, buf, BUF_LEN) == NULL)
1202 {
1203 snprintf(buf, BUF_LEN, "(invalid ID_IPV4_ADDR_SUBNET)");
1204 break;
1205 }
1206 written = strlen(buf);
1207 snprintf(buf + written, BUF_LEN - written, "/%d",
1208 netmask_to_cidr(this->encoded.ptr + address_size,
1209 address_size));
1210 break;
1211 case ID_IPV4_ADDR_RANGE:
1212 address_size = sizeof(struct in_addr);
1213 if (this->encoded.len < 2 * address_size ||
1214 inet_ntop(AF_INET, this->encoded.ptr, buf, BUF_LEN) == NULL)
1215 {
1216 snprintf(buf, BUF_LEN, "(invalid ID_IPV4_ADDR_RANGE)");
1217 break;
1218 }
1219 written = strlen(buf);
1220 pos = buf + written;
1221 len = BUF_LEN - written;
1222 written = snprintf(pos, len, "-");
1223 if (written < 0 || written >= len ||
1224 inet_ntop(AF_INET, this->encoded.ptr + address_size,
1225 pos + written, len - written) == NULL)
1226 {
1227 snprintf(buf, BUF_LEN, "(invalid ID_IPV4_ADDR_RANGE)");
1228 }
1229 break;
1230 case ID_IPV6_ADDR:
1231 if (this->encoded.len < sizeof(struct in6_addr) ||
1232 inet_ntop(AF_INET6, this->encoded.ptr, buf, BUF_LEN) == NULL)
1233 {
1234 snprintf(buf, BUF_LEN, "(invalid ID_IPV6_ADDR)");
1235 }
1236 break;
1237 case ID_IPV6_ADDR_SUBNET:
1238 address_size = sizeof(struct in6_addr);
1239 if (this->encoded.len < 2 * address_size ||
1240 inet_ntop(AF_INET6, this->encoded.ptr, buf, BUF_LEN) == NULL)
1241 {
1242 snprintf(buf, BUF_LEN, "(invalid ID_IPV6_ADDR_SUBNET)");
1243 }
1244 else
1245 {
1246 written = strlen(buf);
1247 snprintf(buf + written, BUF_LEN - written, "/%d",
1248 netmask_to_cidr(this->encoded.ptr + address_size,
1249 address_size));
1250 }
1251 break;
1252 case ID_IPV6_ADDR_RANGE:
1253 address_size = sizeof(struct in6_addr);
1254 if (this->encoded.len < 2 * address_size ||
1255 inet_ntop(AF_INET6, this->encoded.ptr, buf, BUF_LEN) == NULL)
1256 {
1257 snprintf(buf, BUF_LEN, "(invalid ID_IPV6_ADDR_RANGE)");
1258 break;
1259 }
1260 written = strlen(buf);
1261 pos = buf + written;
1262 len = BUF_LEN - written;
1263 written = snprintf(pos, len, "-");
1264 if (written < 0 || written >= len ||
1265 inet_ntop(AF_INET6, this->encoded.ptr + address_size,
1266 pos + written, len - written) == NULL)
1267 {
1268 snprintf(buf, BUF_LEN, "(invalid ID_IPV6_ADDR_RANGE)");
1269 }
1270 break;
1271 case ID_FQDN:
1272 case ID_RFC822_ADDR:
1273 case ID_DER_ASN1_GN_URI:
1274 chunk_printable(this->encoded, &proper, '?');
1275 snprintf(buf, BUF_LEN, "%.*s", (int)proper.len, proper.ptr);
1276 chunk_free(&proper);
1277 break;
1278 case ID_DER_ASN1_DN:
1279 dntoa(this->encoded, buf, BUF_LEN);
1280 break;
1281 case ID_DER_ASN1_GN:
1282 snprintf(buf, BUF_LEN, "(ASN.1 general name)");
1283 break;
1284 case ID_KEY_ID:
1285 if (chunk_printable(this->encoded, NULL, '?') &&
1286 this->encoded.len != HASH_SIZE_SHA1)
1287 { /* fully printable, use ascii version */
1288 snprintf(buf, BUF_LEN, "%.*s", (int)this->encoded.len,
1289 this->encoded.ptr);
1290 }
1291 else
1292 { /* not printable, hex dump */
1293 snprintf(buf, BUF_LEN, "%#B", &this->encoded);
1294 }
1295 break;
1296 default:
1297 snprintf(buf, BUF_LEN, "(unknown ID type: %d)", this->type);
1298 break;
1299 }
1300 if (spec->minus)
1301 {
1302 return print_in_hook(data, "%-*s", spec->width, buf);
1303 }
1304 return print_in_hook(data, "%*s", spec->width, buf);
1305 }
1306
1307 METHOD(identification_t, clone_, identification_t*,
1308 private_identification_t *this)
1309 {
1310 private_identification_t *clone = malloc_thing(private_identification_t);
1311
1312 memcpy(clone, this, sizeof(private_identification_t));
1313 if (this->encoded.len)
1314 {
1315 clone->encoded = chunk_clone(this->encoded);
1316 }
1317 return &clone->public;
1318 }
1319
1320 METHOD(identification_t, destroy, void,
1321 private_identification_t *this)
1322 {
1323 chunk_free(&this->encoded);
1324 free(this);
1325 }
1326
1327 /**
1328 * Generic constructor used for the other constructors.
1329 */
1330 static private_identification_t *identification_create(id_type_t type)
1331 {
1332 private_identification_t *this;
1333 char *rdn_matching;
1334
1335 INIT(this,
1336 .public = {
1337 .get_encoding = _get_encoding,
1338 .get_type = _get_type,
1339 .create_part_enumerator = _create_part_enumerator,
1340 .clone = _clone_,
1341 .destroy = _destroy,
1342 },
1343 .type = type,
1344 );
1345
1346 switch (type)
1347 {
1348 case ID_ANY:
1349 this->public.hash = _hash_binary;
1350 this->public.equals = _equals_binary;
1351 this->public.matches = _matches_any;
1352 this->public.contains_wildcards = return_true;
1353 break;
1354 case ID_FQDN:
1355 case ID_RFC822_ADDR:
1356 this->public.hash = _hash_binary;
1357 this->public.equals = _equals_strcasecmp;
1358 this->public.matches = _matches_string;
1359 this->public.contains_wildcards = _contains_wildcards_memchr;
1360 break;
1361 case ID_DER_ASN1_DN:
1362 this->public.hash = _hash_dn;
1363 this->public.equals = _equals_dn;
1364 this->public.matches = _matches_dn;
1365 this->public.contains_wildcards = _contains_wildcards_dn;
1366 /* check for more relaxed matching config */
1367 rdn_matching = lib->settings->get_str(lib->settings,
1368 "%s.rdn_matching", NULL, lib->ns);
1369 if (streq("reordered", rdn_matching))
1370 {
1371 this->public.matches = _matches_dn_reordered;
1372 }
1373 else if (streq("relaxed", rdn_matching))
1374 {
1375 this->public.matches = _matches_dn_relaxed;
1376 }
1377 break;
1378 case ID_IPV4_ADDR:
1379 case ID_IPV6_ADDR:
1380 this->public.hash = _hash_binary;
1381 this->public.equals = _equals_binary;
1382 this->public.matches = _matches_range;
1383 this->public.contains_wildcards = return_false;
1384 break;
1385 default:
1386 this->public.hash = _hash_binary;
1387 this->public.equals = _equals_binary;
1388 this->public.matches = _matches_binary;
1389 this->public.contains_wildcards = return_false;
1390 break;
1391 }
1392 return this;
1393 }
1394
1395 /**
1396 * Create an identity for a specific type, determined by prefix
1397 */
1398 static private_identification_t* create_from_string_with_prefix_type(char *str)
1399 {
1400 struct {
1401 const char *str;
1402 id_type_t type;
1403 } prefixes[] = {
1404 { "ipv4:", ID_IPV4_ADDR },
1405 { "ipv6:", ID_IPV6_ADDR },
1406 { "ipv4net:", ID_IPV4_ADDR_SUBNET },
1407 { "ipv6net:", ID_IPV6_ADDR_SUBNET },
1408 { "ipv4range:", ID_IPV4_ADDR_RANGE },
1409 { "ipv6range:", ID_IPV6_ADDR_RANGE },
1410 { "rfc822:", ID_RFC822_ADDR },
1411 { "email:", ID_RFC822_ADDR },
1412 { "userfqdn:", ID_USER_FQDN },
1413 { "fqdn:", ID_FQDN },
1414 { "dns:", ID_FQDN },
1415 { "asn1dn:", ID_DER_ASN1_DN },
1416 { "asn1gn:", ID_DER_ASN1_GN },
1417 { "xmppaddr:", ID_DER_ASN1_GN },
1418 { "keyid:", ID_KEY_ID },
1419 };
1420 private_identification_t *this;
1421 int i;
1422
1423 for (i = 0; i < countof(prefixes); i++)
1424 {
1425 if (strcasepfx(str, prefixes[i].str))
1426 {
1427 this = identification_create(prefixes[i].type);
1428 str += strlen(prefixes[i].str);
1429
1430 if (*str == '#')
1431 {
1432 this->encoded = chunk_from_hex(chunk_from_str(str + 1), NULL);
1433 }
1434 else
1435 {
1436 this->encoded = chunk_clone(chunk_from_str(str));
1437 }
1438
1439 if (prefixes[i].type == ID_DER_ASN1_GN &&
1440 strcasepfx(prefixes[i].str, "xmppaddr:"))
1441 {
1442 this->encoded = asn1_wrap(ASN1_CONTEXT_C_0, "mm",
1443 asn1_build_known_oid(OID_XMPP_ADDR),
1444 asn1_wrap(ASN1_CONTEXT_C_0, "m",
1445 asn1_wrap(ASN1_UTF8STRING, "m",
1446 this->encoded)));
1447 }
1448
1449 return this;
1450 }
1451 }
1452 return NULL;
1453 }
1454
1455 /**
1456 * Create an identity for a specific type, determined by a numerical prefix
1457 *
1458 * The prefix is of the form "{x}:", where x denotes the numerical identity
1459 * type.
1460 */
1461 static private_identification_t* create_from_string_with_num_type(char *str)
1462 {
1463 private_identification_t *this;
1464 u_long type;
1465
1466 if (*str++ != '{')
1467 {
1468 return NULL;
1469 }
1470 errno = 0;
1471 type = strtoul(str, &str, 0);
1472 if (errno || *str++ != '}' || *str++ != ':')
1473 {
1474 return NULL;
1475 }
1476 this = identification_create(type);
1477 if (*str == '#')
1478 {
1479 this->encoded = chunk_from_hex(chunk_from_str(str + 1), NULL);
1480 }
1481 else
1482 {
1483 this->encoded = chunk_clone(chunk_from_str(str));
1484 }
1485 return this;
1486 }
1487
1488 /**
1489 * Convert to an IPv4/IPv6 host address, subnet or address range
1490 */
1491 static private_identification_t* create_ip_address_from_string(char *string,
1492 bool is_ipv4)
1493 {
1494 private_identification_t *this;
1495 uint8_t encoding[32];
1496 uint8_t *str, *pos, *address, *to_address, *netmask;
1497 size_t address_size;
1498 int bits, bytes, i;
1499 bool has_subnet = FALSE, has_range = FALSE;
1500
1501 address = encoding;
1502 address_size = is_ipv4 ? sizeof(struct in_addr) : sizeof(struct in6_addr);
1503
1504 str = strdup(string);
1505 pos = strchr(str, '/');
1506 if (pos)
1507 { /* separate IP address from optional netmask */
1508
1509 *pos = '\0';
1510 has_subnet = TRUE;
1511 }
1512 else
1513 {
1514 pos = strchr(str, '-');
1515 if (pos)
1516 { /* separate lower address from upper address of IP range */
1517 *pos = '\0';
1518 has_range = TRUE;
1519 }
1520 }
1521
1522 if (inet_pton(is_ipv4 ? AF_INET : AF_INET6, str, address) != 1)
1523 {
1524 free(str);
1525 return NULL;
1526 }
1527
1528 if (has_subnet)
1529 { /* is IP subnet */
1530 bits = atoi(pos + 1);
1531 if (bits > 8 * address_size)
1532 {
1533 free(str);
1534 return NULL;
1535 }
1536 bytes = bits / 8;
1537 bits -= 8 * bytes;
1538 netmask = encoding + address_size;
1539
1540 for (i = 0; i < address_size; i++)
1541 {
1542 if (bytes)
1543 {
1544 *netmask = 0xff;
1545 bytes--;
1546 }
1547 else if (bits)
1548 {
1549 *netmask = 0xff << (8 - bits);
1550 bits = 0;
1551 }
1552 else
1553 {
1554 *netmask = 0x00;
1555 }
1556 *address++ &= *netmask++;
1557 }
1558 this = identification_create(is_ipv4 ? ID_IPV4_ADDR_SUBNET :
1559 ID_IPV6_ADDR_SUBNET);
1560 this->encoded = chunk_clone(chunk_create(encoding, 2 * address_size));
1561 }
1562 else if (has_range)
1563 { /* is IP range */
1564 to_address = encoding + address_size;
1565
1566 if (inet_pton(is_ipv4 ? AF_INET : AF_INET6, pos + 1, to_address) != 1)
1567 {
1568 free(str);
1569 return NULL;
1570 }
1571 for (i = 0; i < address_size; i++)
1572 {
1573 if (address[i] != to_address[i])
1574 {
1575 if (address[i] > to_address[i])
1576 {
1577 free(str);
1578 return NULL;
1579 }
1580 break;
1581 }
1582 }
1583 this = identification_create(is_ipv4 ? ID_IPV4_ADDR_RANGE :
1584 ID_IPV6_ADDR_RANGE);
1585 this->encoded = chunk_clone(chunk_create(encoding, 2 * address_size));
1586 }
1587 else
1588 { /* is IP host address */
1589 this = identification_create(is_ipv4 ? ID_IPV4_ADDR : ID_IPV6_ADDR);
1590 this->encoded = chunk_clone(chunk_create(encoding, address_size));
1591 }
1592 free(str);
1593
1594 return this;
1595 }
1596
1597 /*
1598 * Described in header.
1599 */
1600 identification_t *identification_create_from_string(char *string)
1601 {
1602 private_identification_t *this;
1603 chunk_t encoded;
1604
1605 if (string == NULL)
1606 {
1607 string = "%any";
1608 }
1609 this = create_from_string_with_prefix_type(string);
1610 if (this)
1611 {
1612 return &this->public;
1613 }
1614 this = create_from_string_with_num_type(string);
1615 if (this)
1616 {
1617 return &this->public;
1618 }
1619 if (strchr(string, '=') != NULL)
1620 {
1621 /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN.
1622 * convert from LDAP style or openssl x509 -subject style to ASN.1 DN
1623 */
1624 if (atodn(string, &encoded) == SUCCESS)
1625 {
1626 this = identification_create(ID_DER_ASN1_DN);
1627 this->encoded = encoded;
1628 }
1629 else
1630 {
1631 this = identification_create(ID_KEY_ID);
1632 this->encoded = chunk_from_str(strdup(string));
1633 }
1634 return &this->public;
1635 }
1636 else if (strchr(string, '@') == NULL)
1637 {
1638 if (streq(string, "")
1639 || streq(string, "%any")
1640 || streq(string, "%any6")
1641 || streq(string, "0.0.0.0")
1642 || streq(string, "*")
1643 || streq(string, "::")
1644 || streq(string, "0::0"))
1645 {
1646 /* any ID will be accepted */
1647 this = identification_create(ID_ANY);
1648 return &this->public;
1649 }
1650 else
1651 {
1652 if (strchr(string, ':') == NULL)
1653 {
1654 /* IPv4 address or subnet */
1655 this = create_ip_address_from_string(string, TRUE);
1656 if (!this)
1657 { /* not IPv4, mostly FQDN */
1658 this = identification_create(ID_FQDN);
1659 this->encoded = chunk_from_str(strdup(string));
1660 }
1661 return &this->public;
1662 }
1663 else
1664 {
1665 /* IPv6 address or subnet */
1666 this = create_ip_address_from_string(string, FALSE);
1667 if (!this)
1668 { /* not IPv4/6 fallback to KEY_ID */
1669 this = identification_create(ID_KEY_ID);
1670 this->encoded = chunk_from_str(strdup(string));
1671 }
1672 return &this->public;
1673 }
1674 }
1675 }
1676 else
1677 {
1678 if (*string == '@')
1679 {
1680 string++;
1681 if (*string == '#')
1682 {
1683 this = identification_create(ID_KEY_ID);
1684 this->encoded = chunk_from_hex(chunk_from_str(string + 1), NULL);
1685 return &this->public;
1686 }
1687 else if (*string == '@')
1688 {
1689 this = identification_create(ID_USER_FQDN);
1690 this->encoded = chunk_clone(chunk_from_str(string + 1));
1691 return &this->public;
1692 }
1693 else
1694 {
1695 this = identification_create(ID_FQDN);
1696 this->encoded = chunk_clone(chunk_from_str(string));
1697 return &this->public;
1698 }
1699 }
1700 else
1701 {
1702 this = identification_create(ID_RFC822_ADDR);
1703 this->encoded = chunk_from_str(strdup(string));
1704 return &this->public;
1705 }
1706 }
1707 }
1708
1709 /*
1710 * Described in header.
1711 */
1712 identification_t * identification_create_from_data(chunk_t data)
1713 {
1714 char buf[data.len + 1];
1715
1716 if (is_asn1(data))
1717 {
1718 return identification_create_from_encoding(ID_DER_ASN1_DN, data);
1719 }
1720 else
1721 {
1722 /* use string constructor */
1723 snprintf(buf, sizeof(buf), "%.*s", (int)data.len, data.ptr);
1724 return identification_create_from_string(buf);
1725 }
1726 }
1727
1728 /*
1729 * Described in header.
1730 */
1731 identification_t *identification_create_from_encoding(id_type_t type,
1732 chunk_t encoded)
1733 {
1734 private_identification_t *this = identification_create(type);
1735
1736 /* apply encoded chunk */
1737 if (type != ID_ANY)
1738 {
1739 this->encoded = chunk_clone(encoded);
1740 }
1741 return &(this->public);
1742 }
1743
1744 /*
1745 * Described in header.
1746 */
1747 identification_t *identification_create_from_sockaddr(sockaddr_t *sockaddr)
1748 {
1749 switch (sockaddr->sa_family)
1750 {
1751 case AF_INET:
1752 {
1753 struct in_addr *addr = &(((struct sockaddr_in*)sockaddr)->sin_addr);
1754
1755 return identification_create_from_encoding(ID_IPV4_ADDR,
1756 chunk_create((u_char*)addr, sizeof(struct in_addr)));
1757 }
1758 case AF_INET6:
1759 {
1760 struct in6_addr *addr = &(((struct sockaddr_in6*)sockaddr)->sin6_addr);
1761
1762 return identification_create_from_encoding(ID_IPV6_ADDR,
1763 chunk_create((u_char*)addr, sizeof(struct in6_addr)));
1764 }
1765 default:
1766 {
1767 private_identification_t *this = identification_create(ID_ANY);
1768
1769 return &(this->public);
1770 }
1771 }
1772 }