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