1 /* Support of X.509 certificates
2 * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
3 * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
4 * Copyright (C) 2002 Mario Strasser
5 * Copyright (C) 2000-2009 Andreas Steffen - Hochschule fuer Technik Rapperswil
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 #include <sys/types.h>
28 #include <asn1/asn1.h>
29 #include <asn1/asn1_parser.h>
31 #include <crypto/hashers/hasher.h>
33 #include "constants.h"
47 * Chained lists of X.509 end certificates
49 static x509cert_t
*x509certs
= NULL
;
52 * ASN.1 definition of a authorityKeyIdentifier extension
54 static const asn1Object_t authKeyIdentifierObjects
[] = {
55 { 0, "authorityKeyIdentifier", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
56 { 1, "keyIdentifier", ASN1_CONTEXT_S_0
, ASN1_OPT
|ASN1_BODY
}, /* 1 */
57 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 2 */
58 { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1
, ASN1_OPT
|ASN1_OBJ
}, /* 3 */
59 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 4 */
60 { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2
, ASN1_OPT
|ASN1_BODY
}, /* 5 */
61 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 6 */
62 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
64 #define AUTH_KEY_ID_KEY_ID 1
65 #define AUTH_KEY_ID_CERT_ISSUER 3
66 #define AUTH_KEY_ID_CERT_SERIAL 5
69 * ASN.1 definition of generalNames
71 static const asn1Object_t generalNamesObjects
[] = {
72 { 0, "generalNames", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
73 { 1, "generalName", ASN1_EOC
, ASN1_RAW
}, /* 1 */
74 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 2 */
75 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
77 #define GENERAL_NAMES_GN 1
80 * ASN.1 definition of generalName
82 static const asn1Object_t generalNameObjects
[] = {
83 { 0, "otherName", ASN1_CONTEXT_C_0
, ASN1_OPT
|ASN1_BODY
}, /* 0 */
84 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 1 */
85 { 0, "rfc822Name", ASN1_CONTEXT_S_1
, ASN1_OPT
|ASN1_BODY
}, /* 2 */
86 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 3 */
87 { 0, "dnsName", ASN1_CONTEXT_S_2
, ASN1_OPT
|ASN1_BODY
}, /* 4 */
88 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 5 */
89 { 0, "x400Address", ASN1_CONTEXT_S_3
, ASN1_OPT
|ASN1_BODY
}, /* 6 */
90 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 7 */
91 { 0, "directoryName", ASN1_CONTEXT_C_4
, ASN1_OPT
|ASN1_BODY
}, /* 8 */
92 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 9 */
93 { 0, "ediPartyName", ASN1_CONTEXT_C_5
, ASN1_OPT
|ASN1_BODY
}, /* 10 */
94 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 11 */
95 { 0, "URI", ASN1_CONTEXT_S_6
, ASN1_OPT
|ASN1_BODY
}, /* 12 */
96 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 13 */
97 { 0, "ipAddress", ASN1_CONTEXT_S_7
, ASN1_OPT
|ASN1_BODY
}, /* 14 */
98 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 15 */
99 { 0, "registeredID", ASN1_CONTEXT_S_8
, ASN1_OPT
|ASN1_BODY
}, /* 16 */
100 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 17 */
101 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
103 #define GN_OBJ_OTHER_NAME 0
104 #define GN_OBJ_RFC822_NAME 2
105 #define GN_OBJ_DNS_NAME 4
106 #define GN_OBJ_X400_ADDRESS 6
107 #define GN_OBJ_DIRECTORY_NAME 8
108 #define GN_OBJ_EDI_PARTY_NAME 10
109 #define GN_OBJ_URI 12
110 #define GN_OBJ_IP_ADDRESS 14
111 #define GN_OBJ_REGISTERED_ID 16
114 * ASN.1 definition of otherName
116 static const asn1Object_t otherNameObjects
[] = {
117 {0, "type-id", ASN1_OID
, ASN1_BODY
}, /* 0 */
118 {0, "value", ASN1_CONTEXT_C_0
, ASN1_BODY
}, /* 1 */
119 {0, "exit", ASN1_EOC
, ASN1_EXIT
}
121 #define ON_OBJ_ID_TYPE 0
122 #define ON_OBJ_VALUE 1
124 const x509cert_t empty_x509cert
= {
127 UNDEFINED_TIME
, /* installed */
129 FALSE
, /* smartcard */
130 AUTH_NONE
, /* authority_flags */
133 /* coding of X.501 distinguished name */
141 /* X.501 acronyms for well known object identifiers (OIDs) */
143 static u_char oid_ND
[] = {0x02, 0x82, 0x06, 0x01,
145 static u_char oid_UID
[] = {0x09, 0x92, 0x26, 0x89, 0x93,
146 0xF2, 0x2C, 0x64, 0x01, 0x01};
147 static u_char oid_DC
[] = {0x09, 0x92, 0x26, 0x89, 0x93,
148 0xF2, 0x2C, 0x64, 0x01, 0x19};
149 static u_char oid_CN
[] = {0x55, 0x04, 0x03};
150 static u_char oid_S
[] = {0x55, 0x04, 0x04};
151 static u_char oid_SN
[] = {0x55, 0x04, 0x05};
152 static u_char oid_C
[] = {0x55, 0x04, 0x06};
153 static u_char oid_L
[] = {0x55, 0x04, 0x07};
154 static u_char oid_ST
[] = {0x55, 0x04, 0x08};
155 static u_char oid_O
[] = {0x55, 0x04, 0x0A};
156 static u_char oid_OU
[] = {0x55, 0x04, 0x0B};
157 static u_char oid_T
[] = {0x55, 0x04, 0x0C};
158 static u_char oid_D
[] = {0x55, 0x04, 0x0D};
159 static u_char oid_N
[] = {0x55, 0x04, 0x29};
160 static u_char oid_G
[] = {0x55, 0x04, 0x2A};
161 static u_char oid_I
[] = {0x55, 0x04, 0x2B};
162 static u_char oid_ID
[] = {0x55, 0x04, 0x2D};
163 static u_char oid_EN
[] = {0x60, 0x86, 0x48, 0x01, 0x86,
164 0xF8, 0x42, 0x03, 0x01, 0x03};
165 static u_char oid_E
[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
166 0x0D, 0x01, 0x09, 0x01};
167 static u_char oid_UN
[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
168 0x0D, 0x01, 0x09, 0x02};
169 static u_char oid_TCGID
[] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x89,
170 0x31, 0x01, 0x01, 0x02, 0x02, 0x4B};
172 static const x501rdn_t x501rdns
[] = {
173 {"ND" , {oid_ND
, 7}, ASN1_PRINTABLESTRING
},
174 {"UID" , {oid_UID
, 10}, ASN1_PRINTABLESTRING
},
175 {"DC" , {oid_DC
, 10}, ASN1_PRINTABLESTRING
},
176 {"CN" , {oid_CN
, 3}, ASN1_PRINTABLESTRING
},
177 {"S" , {oid_S
, 3}, ASN1_PRINTABLESTRING
},
178 {"SN" , {oid_SN
, 3}, ASN1_PRINTABLESTRING
},
179 {"serialNumber" , {oid_SN
, 3}, ASN1_PRINTABLESTRING
},
180 {"C" , {oid_C
, 3}, ASN1_PRINTABLESTRING
},
181 {"L" , {oid_L
, 3}, ASN1_PRINTABLESTRING
},
182 {"ST" , {oid_ST
, 3}, ASN1_PRINTABLESTRING
},
183 {"O" , {oid_O
, 3}, ASN1_PRINTABLESTRING
},
184 {"OU" , {oid_OU
, 3}, ASN1_PRINTABLESTRING
},
185 {"T" , {oid_T
, 3}, ASN1_PRINTABLESTRING
},
186 {"D" , {oid_D
, 3}, ASN1_PRINTABLESTRING
},
187 {"N" , {oid_N
, 3}, ASN1_PRINTABLESTRING
},
188 {"G" , {oid_G
, 3}, ASN1_PRINTABLESTRING
},
189 {"I" , {oid_I
, 3}, ASN1_PRINTABLESTRING
},
190 {"ID" , {oid_ID
, 3}, ASN1_PRINTABLESTRING
},
191 {"EN" , {oid_EN
, 10}, ASN1_PRINTABLESTRING
},
192 {"employeeNumber" , {oid_EN
, 10}, ASN1_PRINTABLESTRING
},
193 {"E" , {oid_E
, 9}, ASN1_IA5STRING
},
194 {"Email" , {oid_E
, 9}, ASN1_IA5STRING
},
195 {"emailAddress" , {oid_E
, 9}, ASN1_IA5STRING
},
196 {"UN" , {oid_UN
, 9}, ASN1_IA5STRING
},
197 {"unstructuredName", {oid_UN
, 9}, ASN1_IA5STRING
},
198 {"TCGID" , {oid_TCGID
, 12}, ASN1_PRINTABLESTRING
}
201 #define X501_RDN_ROOF 26
203 static void update_chunk(chunk_t
*ch
, int n
)
205 n
= (n
> -1 && n
< (int)ch
->len
)? n
: (int)ch
->len
-1;
206 ch
->ptr
+= n
; ch
->len
-= n
;
210 * Pointer is set to the first RDN in a DN
212 static err_t
init_rdn(chunk_t dn
, chunk_t
*rdn
, chunk_t
*attribute
, bool *next
)
215 *attribute
= chunk_empty
;
217 /* a DN is a SEQUENCE OF RDNs */
219 if (*dn
.ptr
!= ASN1_SEQUENCE
)
221 return "DN is not a SEQUENCE";
224 rdn
->len
= asn1_length(&dn
);
226 if (rdn
->len
== ASN1_INVALID_LENGTH
)
228 return "Invalid RDN length";
232 /* are there any RDNs ? */
233 *next
= rdn
->len
> 0;
239 * Fetches the next RDN in a DN
241 static err_t
get_next_rdn(chunk_t
*rdn
, chunk_t
* attribute
, chunk_t
*oid
,
242 chunk_t
*value
, asn1_t
*type
, bool *next
)
246 /* initialize return values */
248 *value
= chunk_empty
;
250 /* if all attributes have been parsed, get next rdn */
251 if (attribute
->len
<= 0)
253 /* an RDN is a SET OF attributeTypeAndValue */
254 if (*rdn
->ptr
!= ASN1_SET
)
256 return "RDN is not a SET";
258 attribute
->len
= asn1_length(rdn
);
260 if (attribute
->len
== ASN1_INVALID_LENGTH
)
262 return "Invalid attribute length";
264 attribute
->ptr
= rdn
->ptr
;
266 /* advance to start of next RDN */
267 rdn
->ptr
+= attribute
->len
;
268 rdn
->len
-= attribute
->len
;
271 /* an attributeTypeAndValue is a SEQUENCE */
272 if (*attribute
->ptr
!= ASN1_SEQUENCE
)
274 return "attributeTypeAndValue is not a SEQUENCE";
277 /* extract the attribute body */
278 body
.len
= asn1_length(attribute
);
280 if (body
.len
== ASN1_INVALID_LENGTH
)
282 return "Invalid attribute body length";
284 body
.ptr
= attribute
->ptr
;
286 /* advance to start of next attribute */
287 attribute
->ptr
+= body
.len
;
288 attribute
->len
-= body
.len
;
290 /* attribute type is an OID */
291 if (*body
.ptr
!= ASN1_OID
)
293 return "attributeType is not an OID";
297 oid
->len
= asn1_length(&body
);
299 if (oid
->len
== ASN1_INVALID_LENGTH
)
301 return "Invalid attribute OID length";
305 /* advance to the attribute value */
306 body
.ptr
+= oid
->len
;
307 body
.len
-= oid
->len
;
309 /* extract string type */
312 /* extract string value */
313 value
->len
= asn1_length(&body
);
315 if (value
->len
== ASN1_INVALID_LENGTH
)
317 return "Invalid attribute string length";
319 value
->ptr
= body
.ptr
;
321 /* are there any RDNs left? */
322 *next
= rdn
->len
> 0 || attribute
->len
> 0;
328 * Parses an ASN.1 distinguished name int its OID/value pairs
330 static err_t
dn_parse(chunk_t dn
, chunk_t
*str
)
332 chunk_t rdn
, oid
, attribute
, value
;
338 err_t ugh
= init_rdn(dn
, &rdn
, &attribute
, &next
);
340 if (ugh
!= NULL
) /* a parsing error has occured */
347 ugh
= get_next_rdn(&rdn
, &attribute
, &oid
, &value
, &type
, &next
);
349 if (ugh
!= NULL
) /* a parsing error has occured */
354 if (first
) /* first OID/value pair */
358 else /* separate OID/value pair by a comma */
360 update_chunk(str
, snprintf(str
->ptr
,str
->len
,", "));
364 oid_code
= asn1_known_oid(oid
);
365 if (oid_code
== OID_UNKNOWN
) /* OID not found in list */
371 update_chunk(str
, snprintf(str
->ptr
,str
->len
,"%s",
372 oid_names
[oid_code
].name
));
376 update_chunk(str
, snprintf(str
->ptr
,str
->len
,"=%.*s",
377 (int)value
.len
,value
.ptr
));
383 * Count the number of wildcard RDNs in a distinguished name
385 int dn_count_wildcards(chunk_t dn
)
387 chunk_t rdn
, attribute
, oid
, value
;
392 err_t ugh
= init_rdn(dn
, &rdn
, &attribute
, &next
);
394 if (ugh
!= NULL
) /* a parsing error has occured */
401 ugh
= get_next_rdn(&rdn
, &attribute
, &oid
, &value
, &type
, &next
);
403 if (ugh
!= NULL
) /* a parsing error has occured */
407 if (value
.len
== 1 && *value
.ptr
== '*')
409 wildcards
++; /* we have found a wildcard RDN */
416 * Prints a binary string in hexadecimal form
418 void hex_str(chunk_t bin
, chunk_t
*str
)
421 update_chunk(str
, snprintf(str
->ptr
,str
->len
,"0x"));
422 for (i
=0; i
< bin
.len
; i
++)
423 update_chunk(str
, snprintf(str
->ptr
,str
->len
,"%02X",*bin
.ptr
++));
427 /** Converts a binary DER-encoded ASN.1 distinguished name
428 * into LDAP-style human-readable ASCII format
430 int dntoa(char *dst
, size_t dstlen
, chunk_t dn
)
437 ugh
= dn_parse(dn
, &str
);
439 if (ugh
!= NULL
) /* error, print DN as hex string */
442 DBG_log("error in DN parsing: %s", ugh
)
448 return (int)(dstlen
- str
.len
);
452 * Same as dntoa but prints a special string for a null dn
454 int dntoa_or_null(char *dst
, size_t dstlen
, chunk_t dn
, const char* null_dn
)
458 return snprintf(dst
, dstlen
, "%s", null_dn
);
462 return dntoa(dst
, dstlen
, dn
);
468 * Codes ASN.1 lengths up to a size of 16'777'215 bytes
470 static void code_asn1_length(size_t length
, chunk_t
*code
)
474 code
->ptr
[0] = length
;
477 else if (length
< 256)
480 code
->ptr
[1] = (u_char
) length
;
483 else if (length
< 65536)
486 code
->ptr
[1] = length
>> 8;
487 code
->ptr
[2] = length
& 0x00ff;
493 code
->ptr
[1] = length
>> 16;
494 code
->ptr
[2] = (length
>> 8) & 0x00ff;
495 code
->ptr
[3] = length
& 0x0000ff;
501 * Converts an LDAP-style human-readable ASCII-encoded
502 * ASN.1 distinguished name into binary DER-encoded format
504 err_t
atodn(char *src
, chunk_t
*dn
)
506 /* finite state machine for atodn */
516 u_char oid_len_buf
[3];
517 u_char name_len_buf
[3];
518 u_char rdn_seq_len_buf
[3];
519 u_char rdn_set_len_buf
[3];
520 u_char dn_seq_len_buf
[3];
522 chunk_t asn1_oid_len
= { oid_len_buf
, 0 };
523 chunk_t asn1_name_len
= { name_len_buf
, 0 };
524 chunk_t asn1_rdn_seq_len
= { rdn_seq_len_buf
, 0 };
525 chunk_t asn1_rdn_set_len
= { rdn_set_len_buf
, 0 };
526 chunk_t asn1_dn_seq_len
= { dn_seq_len_buf
, 0 };
527 chunk_t oid
= chunk_empty
;
528 chunk_t name
= chunk_empty
;
538 u_char
*dn_ptr
= dn
->ptr
+ 4;
540 state_t state
= SEARCH_OID
;
547 if (*src
!= ' ' && *src
!= '/' && *src
!= ',')
555 if (*src
!= ' ' && *src
!= '=')
561 for (pos
= 0; pos
< X501_RDN_ROOF
; pos
++)
563 if (strlen(x501rdns
[pos
].name
) == oid
.len
&&
564 strncasecmp(x501rdns
[pos
].name
, oid
.ptr
, oid
.len
) == 0)
566 break; /* found a valid OID */
569 if (pos
== X501_RDN_ROOF
)
571 ugh
= "unknown OID in distinguished name";
575 code_asn1_length(x501rdns
[pos
].oid
.len
, &asn1_oid_len
);
577 /* reset oid and change state */
583 if (*src
!= ' ' && *src
!= '=')
592 if (*src
!= ',' && *src
!= '/' && *src
!= '\0')
606 name
.len
-= whitespace
;
607 code_asn1_length(name
.len
, &asn1_name_len
);
609 /* compute the length of the relative distinguished name sequence */
610 rdn_seq_len
= 1 + asn1_oid_len
.len
+ x501rdns
[pos
].oid
.len
+
611 1 + asn1_name_len
.len
+ name
.len
;
612 code_asn1_length(rdn_seq_len
, &asn1_rdn_seq_len
);
614 /* compute the length of the relative distinguished name set */
615 rdn_set_len
= 1 + asn1_rdn_seq_len
.len
+ rdn_seq_len
;
616 code_asn1_length(rdn_set_len
, &asn1_rdn_set_len
);
618 /* encode the relative distinguished name */
619 *dn_ptr
++ = ASN1_SET
;
620 chunkcpy(dn_ptr
, asn1_rdn_set_len
);
621 *dn_ptr
++ = ASN1_SEQUENCE
;
622 chunkcpy(dn_ptr
, asn1_rdn_seq_len
);
623 *dn_ptr
++ = ASN1_OID
;
624 chunkcpy(dn_ptr
, asn1_oid_len
);
625 chunkcpy(dn_ptr
, x501rdns
[pos
].oid
);
626 /* encode the ASN.1 character string type of the name */
627 *dn_ptr
++ = (x501rdns
[pos
].type
== ASN1_PRINTABLESTRING
628 && !asn1_is_printablestring(name
))? ASN1_T61STRING
: x501rdns
[pos
].type
;
629 chunkcpy(dn_ptr
, asn1_name_len
);
630 chunkcpy(dn_ptr
, name
);
632 /* accumulate the length of the distinguished name sequence */
633 dn_seq_len
+= 1 + asn1_rdn_set_len
.len
+ rdn_set_len
;
635 /* reset name and change state */
643 } while (*src
++ != '\0');
645 /* complete the distinguished name sequence*/
646 code_asn1_length(dn_seq_len
, &asn1_dn_seq_len
);
647 dn
->ptr
+= 3 - asn1_dn_seq_len
.len
;
648 dn
->len
= 1 + asn1_dn_seq_len
.len
+ dn_seq_len
;
650 *dn_ptr
++ = ASN1_SEQUENCE
;
651 chunkcpy(dn_ptr
, asn1_dn_seq_len
);
656 * compare two distinguished names by comparing the individual RDNs
658 bool same_dn(chunk_t a
, chunk_t b
)
660 chunk_t rdn_a
, rdn_b
, attribute_a
, attribute_b
;
661 chunk_t oid_a
, oid_b
, value_a
, value_b
;
662 asn1_t type_a
, type_b
;
665 /* same lengths for the DNs */
671 /* try a binary comparison first */
672 if (memeq(a
.ptr
, b
.ptr
, b
.len
))
677 /* initialize DN parsing */
678 if (init_rdn(a
, &rdn_a
, &attribute_a
, &next_a
) != NULL
679 || init_rdn(b
, &rdn_b
, &attribute_b
, &next_b
) != NULL
)
684 /* fetch next RDN pair */
685 while (next_a
&& next_b
)
687 /* parse next RDNs and check for errors */
688 if (get_next_rdn(&rdn_a
, &attribute_a
, &oid_a
, &value_a
, &type_a
, &next_a
) != NULL
689 || get_next_rdn(&rdn_b
, &attribute_b
, &oid_b
, &value_b
, &type_b
, &next_b
) != NULL
)
694 /* OIDs must agree */
695 if (oid_a
.len
!= oid_b
.len
|| memcmp(oid_a
.ptr
, oid_b
.ptr
, oid_b
.len
) != 0)
700 /* same lengths for values */
701 if (value_a
.len
!= value_b
.len
)
706 /* printableStrings and email RDNs require uppercase comparison */
707 if (type_a
== type_b
&& (type_a
== ASN1_PRINTABLESTRING
||
708 (type_a
== ASN1_IA5STRING
&& asn1_known_oid(oid_a
) == OID_EMAIL_ADDRESS
)))
710 if (strncasecmp(value_a
.ptr
, value_b
.ptr
, value_b
.len
) != 0)
717 if (strncmp(value_a
.ptr
, value_b
.ptr
, value_b
.len
) != 0)
723 /* both DNs must have same number of RDNs */
724 if (next_a
|| next_b
)
729 /* the two DNs are equal! */
735 * Compare two distinguished names by comparing the individual RDNs.
736 * A single'*' character designates a wildcard RDN in DN b.
738 bool match_dn(chunk_t a
, chunk_t b
, int *wildcards
)
740 chunk_t rdn_a
, rdn_b
, attribute_a
, attribute_b
;
741 chunk_t oid_a
, oid_b
, value_a
, value_b
;
742 asn1_t type_a
, type_b
;
745 /* initialize wildcard counter */
748 /* initialize DN parsing */
749 if (init_rdn(a
, &rdn_a
, &attribute_a
, &next_a
) != NULL
750 || init_rdn(b
, &rdn_b
, &attribute_b
, &next_b
) != NULL
)
755 /* fetch next RDN pair */
756 while (next_a
&& next_b
)
758 /* parse next RDNs and check for errors */
759 if (get_next_rdn(&rdn_a
, &attribute_a
, &oid_a
, &value_a
, &type_a
, &next_a
) != NULL
760 || get_next_rdn(&rdn_b
, &attribute_b
, &oid_b
, &value_b
, &type_b
, &next_b
) != NULL
)
765 /* OIDs must agree */
766 if (oid_a
.len
!= oid_b
.len
|| memcmp(oid_a
.ptr
, oid_b
.ptr
, oid_b
.len
) != 0)
771 /* does rdn_b contain a wildcard? */
772 if (value_b
.len
== 1 && *value_b
.ptr
== '*')
778 /* same lengths for values */
779 if (value_a
.len
!= value_b
.len
)
784 /* printableStrings and email RDNs require uppercase comparison */
785 if (type_a
== type_b
&& (type_a
== ASN1_PRINTABLESTRING
||
786 (type_a
== ASN1_IA5STRING
&& asn1_known_oid(oid_a
) == OID_EMAIL_ADDRESS
)))
788 if (strncasecmp(value_a
.ptr
, value_b
.ptr
, value_b
.len
) != 0)
795 if (strncmp(value_a
.ptr
, value_b
.ptr
, value_b
.len
) != 0)
802 /* both DNs must have same number of RDNs */
803 if (next_a
|| next_b
)
808 /* the two DNs match! */
813 * For each link pointing to the certificate increase the count by one
815 void share_x509cert(x509cert_t
*cert
)
824 * Add a X.509 user/host certificate to the chained list
826 x509cert_t
* add_x509cert(x509cert_t
*cert
)
828 certificate_t
*certificate
= cert
->cert
;
829 x509cert_t
*c
= x509certs
;
833 if (certificate
->equals(certificate
, c
->cert
)) /* already in chain, free cert */
841 /* insert new cert at the root of the chain */
842 lock_certs_and_keys("add_x509cert");
843 cert
->next
= x509certs
;
845 DBG(DBG_CONTROL
| DBG_PARSING
,
846 DBG_log(" x509 cert inserted")
848 unlock_certs_and_keys("add_x509cert");
853 * Choose either subject DN or a subjectAltName as connection end ID
855 void select_x509cert_id(x509cert_t
*cert
, struct id
*end_id
)
857 certificate_t
*certificate
= cert
->cert
;
858 x509_t
*x509
= (x509_t
*)certificate
;
859 identification_t
*subjectAltName
;
861 bool copy_subject_dn
= TRUE
; /* ID is subject DN */
863 if (end_id
->kind
!= ID_ANY
) /* check for matching subjectAltName */
865 enumerator_t
*enumerator
;
867 enumerator
= x509
->create_subjectAltName_enumerator(x509
);
868 while (enumerator
->enumerate(enumerator
, &subjectAltName
))
870 struct id id
= empty_id
;
872 id_from_identification(&id
, subjectAltName
);
873 if (same_id(&id
, end_id
))
875 copy_subject_dn
= FALSE
; /* take subjectAltName instead */
879 enumerator
->destroy(enumerator
);
884 identification_t
*subject
= certificate
->get_subject(certificate
);
885 chunk_t subject_dn
= subject
->get_encoding(subject
);
887 if (end_id
->kind
!= ID_ANY
&& end_id
->kind
!= ID_DER_ASN1_DN
)
891 idtoa(end_id
, buf
, BUF_LEN
);
892 plog(" no subjectAltName matches ID '%s', replaced by subject DN", buf
);
894 end_id
->kind
= ID_DER_ASN1_DN
;
895 end_id
->name
.len
= subject_dn
.len
;
896 end_id
->name
.ptr
= temporary_cyclic_buffer();
897 memcpy(end_id
->name
.ptr
, subject_dn
.ptr
, subject_dn
.len
);
902 * Check for equality between two key identifiers
904 bool same_keyid(chunk_t a
, chunk_t b
)
906 if (a
.ptr
== NULL
|| b
.ptr
== NULL
)
910 return chunk_equals(a
, b
);
914 * Get a X.509 certificate with a given issuer found at a certain position
916 x509cert_t
* get_x509cert(chunk_t issuer
, chunk_t keyid
, x509cert_t
*chain
)
918 x509cert_t
*cert
= (chain
!= NULL
)? chain
->next
: x509certs
;
922 certificate_t
*certificate
= cert
->cert
;
923 x509_t
*x509
= (x509_t
*)certificate
;
924 identification_t
*cert_issuer
= certificate
->get_issuer(certificate
);
925 chunk_t cert_issuer_dn
= cert_issuer
->get_encoding(cert_issuer
);
926 chunk_t authKeyID
= x509
->get_authKeyIdentifier(x509
);
928 if ((keyid
.ptr
!= NULL
) ?
same_keyid(keyid
, authKeyID
)
929 : same_dn(issuer
, cert_issuer_dn
))
939 * Free the dynamic memory used to store generalNames
941 void free_generalNames(generalName_t
* gn
, bool free_name
)
945 generalName_t
*gn_top
= gn
;
956 * Free a X.509 certificate
958 void free_x509cert(x509cert_t
*cert
)
962 certificate_t
*certificate
= cert
->cert
;
966 certificate
->destroy(certificate
);
974 * Release of a certificate decreases the count by one
975 * the certificate is freed when the counter reaches zero
977 void release_x509cert(x509cert_t
*cert
)
979 if (cert
!= NULL
&& --cert
->count
== 0)
981 x509cert_t
**pp
= &x509certs
;
992 * Stores a chained list of end certs and CA certs
994 void store_x509certs(x509cert_t
**firstcert
, bool strict
)
996 x509cert_t
*cacerts
= NULL
;
997 x509cert_t
**pp
= firstcert
;
999 /* first extract CA certs, discarding root CA certs */
1003 x509cert_t
*cert
= *pp
;
1004 certificate_t
*certificate
= cert
->cert
;
1005 x509_t
*x509
= (x509_t
*)certificate
;
1006 x509_flag_t flags
= x509
->get_flags(x509
);
1008 if (flags
& X509_CA
)
1012 /* we don't accept self-signed CA certs */
1013 if (flags
& X509_SELF_SIGNED
)
1015 plog("self-signed cacert rejected");
1016 free_x509cert(cert
);
1020 /* insertion into temporary chain of candidate CA certs */
1021 cert
->next
= cacerts
;
1031 /* now verify the candidate CA certs */
1033 while (cacerts
!= NULL
)
1035 x509cert_t
*cert
= cacerts
;
1037 cacerts
= cacerts
->next
;
1039 if (trust_authcert_candidate(cert
, cacerts
))
1041 add_authcert(cert
, AUTH_CA
);
1045 plog("intermediate cacert rejected");
1046 free_x509cert(cert
);
1050 /* now verify the end certificates */
1057 x509cert_t
*cert
= *pp
;
1059 if (verify_x509cert(cert
, strict
, &valid_until
))
1061 DBG(DBG_CONTROL
| DBG_PARSING
,
1062 DBG_log("public key validated")
1064 add_x509_public_key(cert
, valid_until
, DAL_SIGNED
);
1068 plog("X.509 certificate rejected");
1071 free_x509cert(cert
);
1076 * Check if a signature over binary blob is genuine
1078 bool x509_check_signature(chunk_t tbs
, chunk_t sig
, int algorithm
,
1079 certificate_t
*issuer_cert
)
1083 signature_scheme_t scheme
;
1085 scheme
= signature_scheme_from_oid(algorithm
);
1086 if (scheme
== SIGN_UNKNOWN
)
1091 key
= issuer_cert
->get_public_key(issuer_cert
);
1096 success
= key
->verify(key
, scheme
, tbs
, sig
);
1103 * Build an ASN.1 encoded PKCS#1 signature over a binary blob
1105 chunk_t
x509_build_signature(chunk_t tbs
, int algorithm
, private_key_t
*key
,
1109 signature_scheme_t scheme
= signature_scheme_from_oid(algorithm
);
1111 if (scheme
== SIGN_UNKNOWN
|| !key
->sign(key
, scheme
, tbs
, &signature
))
1115 return (bit_string
) ?
asn1_bitstring("m", signature
)
1116 : asn1_wrap(ASN1_OCTET_STRING
, "m", signature
);
1120 * Extracts an otherName
1122 static bool parse_otherName(chunk_t blob
, int level0
)
1124 asn1_parser_t
*parser
;
1127 int oid
= OID_UNKNOWN
;
1128 bool success
= FALSE
;
1130 parser
= asn1_parser_create(otherNameObjects
, blob
);
1131 parser
->set_top_level(parser
, level0
);
1133 while (parser
->iterate(parser
, &objectID
, &object
))
1137 case ON_OBJ_ID_TYPE
:
1138 oid
= asn1_known_oid(object
);
1141 if (oid
== OID_XMPP_ADDR
)
1143 if (!asn1_parse_simple_object(&object
, ASN1_UTF8STRING
,
1144 parser
->get_level(parser
) + 1, "xmppAddr"))
1154 success
= parser
->success(parser
);
1157 parser
->destroy(parser
);
1163 * Extracts a generalName
1165 static generalName_t
* parse_generalName(chunk_t blob
, int level0
)
1167 u_char buf
[BUF_LEN
];
1168 asn1_parser_t
*parser
;
1170 generalName_t
*gn
= NULL
;
1173 parser
= asn1_parser_create(generalNameObjects
, blob
);
1174 parser
->set_top_level(parser
, level0
);
1176 while (parser
->iterate(parser
, &objectID
, &object
))
1178 bool valid_gn
= FALSE
;
1181 case GN_OBJ_RFC822_NAME
:
1182 case GN_OBJ_DNS_NAME
:
1185 DBG_log(" '%.*s'", (int)object
.len
, object
.ptr
);
1189 case GN_OBJ_DIRECTORY_NAME
:
1191 dntoa(buf
, BUF_LEN
, object
);
1192 DBG_log(" '%s'", buf
)
1196 case GN_OBJ_IP_ADDRESS
:
1198 DBG_log(" '%d.%d.%d.%d'", *object
.ptr
, *(object
.ptr
+1),
1199 *(object
.ptr
+2), *(object
.ptr
+3));
1203 case GN_OBJ_OTHER_NAME
:
1204 if (!parse_otherName(object
, parser
->get_level(parser
)+1))
1209 case GN_OBJ_X400_ADDRESS
:
1210 case GN_OBJ_EDI_PARTY_NAME
:
1211 case GN_OBJ_REGISTERED_ID
:
1219 gn
= malloc_thing(generalName_t
);
1220 gn
->kind
= (objectID
- GN_OBJ_OTHER_NAME
) / 2;
1228 parser
->destroy(parser
);
1233 * Extracts one or several GNs and puts them into a chained list
1235 static generalName_t
* parse_generalNames(chunk_t blob
, int level0
, bool implicit
)
1237 asn1_parser_t
*parser
;
1240 generalName_t
*top_gn
= NULL
;
1242 parser
= asn1_parser_create(generalNamesObjects
, blob
);
1243 parser
->set_top_level(parser
, level0
);
1244 parser
->set_flags(parser
, implicit
, FALSE
);
1246 while (parser
->iterate(parser
, &objectID
, &object
))
1248 if (objectID
== GENERAL_NAMES_GN
)
1250 generalName_t
*gn
= parse_generalName(object
,
1251 parser
->get_level(parser
)+1);
1259 parser
->destroy(parser
);
1265 * Returns a directoryName
1267 chunk_t
get_directoryName(chunk_t blob
, int level
, bool implicit
)
1269 chunk_t name
= chunk_empty
;
1270 generalName_t
* gn
= parse_generalNames(blob
, level
, implicit
);
1272 if (gn
!= NULL
&& gn
->kind
== GN_DIRECTORY_NAME
)
1276 free_generalNames(gn
, FALSE
);
1281 * Extracts an authoritykeyIdentifier
1283 void parse_authorityKeyIdentifier(chunk_t blob
, int level0
,
1285 chunk_t
*authKeySerialNumber
)
1287 asn1_parser_t
*parser
;
1291 parser
= asn1_parser_create(authKeyIdentifierObjects
, blob
);
1292 parser
->set_top_level(parser
, level0
);
1294 while (parser
->iterate(parser
, &objectID
, &object
))
1298 case AUTH_KEY_ID_KEY_ID
:
1299 *authKeyID
= object
;
1301 case AUTH_KEY_ID_CERT_ISSUER
:
1303 generalName_t
* gn
= parse_generalNames(object
,
1304 parser
->get_level(parser
) + 1, TRUE
);
1306 free_generalNames(gn
, FALSE
);
1309 case AUTH_KEY_ID_CERT_SERIAL
:
1310 *authKeySerialNumber
= object
;
1316 parser
->destroy(parser
);
1320 * Verify the validity of a certificate by
1321 * checking the notBefore and notAfter dates
1323 err_t
check_validity(const x509cert_t
*cert
, time_t *until
)
1325 time_t current_time
, notBefore
, notAfter
;
1326 certificate_t
*certificate
= cert
->cert
;
1328 time(¤t_time
);
1329 certificate
->get_validity(certificate
, ¤t_time
, ¬Before
, ¬After
);
1330 DBG(DBG_CONTROL
| DBG_PARSING
,
1331 DBG_log(" not before : %T", ¬Before
, TRUE
);
1332 DBG_log(" current time: %T", ¤t_time
, TRUE
);
1333 DBG_log(" not after : %T", ¬After
, TRUE
);
1336 if (*until
== 0 || notAfter
< *until
)
1340 if (current_time
< notBefore
)
1342 return "certificate is not valid yet";
1344 if (current_time
> notAfter
)
1346 return "certificate has expired";
1355 * Verifies a X.509 certificate
1357 bool verify_x509cert(const x509cert_t
*cert
, bool strict
, time_t *until
)
1363 for (pathlen
= 0; pathlen
< MAX_CA_PATH_LEN
; pathlen
++)
1365 certificate_t
*certificate
= cert
->cert
;
1366 identification_t
*subject
= certificate
->get_subject(certificate
);
1367 identification_t
*issuer
= certificate
->get_issuer(certificate
);
1368 x509_t
*x509
= (x509_t
*)certificate
;
1369 chunk_t authKeyID
= x509
->get_authKeyIdentifier(x509
);
1370 x509cert_t
*issuer_cert
;
1374 DBG_log("subject: '%Y'", subject
);
1375 DBG_log("issuer: '%Y'", issuer
);
1376 if (authKeyID
.ptr
!= NULL
)
1378 DBG_log("authkey: %#B", &authKeyID
);
1382 ugh
= check_validity(cert
, until
);
1391 DBG_log("certificate is valid")
1394 lock_authcert_list("verify_x509cert");
1395 issuer_cert
= get_authcert(issuer
->get_encoding(issuer
),
1396 authKeyID
, AUTH_CA
);
1397 if (issuer_cert
== NULL
)
1399 plog("issuer cacert not found");
1400 unlock_authcert_list("verify_x509cert");
1404 DBG_log("issuer cacert found")
1407 if (!certificate
->issued_by(certificate
, issuer_cert
->cert
))
1409 plog("certificate signature is invalid");
1410 unlock_authcert_list("verify_x509cert");
1414 DBG_log("certificate signature is valid")
1416 unlock_authcert_list("verify_x509cert");
1418 /* check if cert is a self-signed root ca */
1419 if (pathlen
> 0 && (x509
->get_flags(x509
) & X509_SELF_SIGNED
))
1422 DBG_log("reached self-signed root ca")
1428 time_t nextUpdate
= *until
;
1429 time_t revocationDate
= UNDEFINED_TIME
;
1430 crl_reason_t revocationReason
= CRL_REASON_UNSPECIFIED
;
1432 /* first check certificate revocation using ocsp */
1433 cert_status_t status
= verify_by_ocsp(cert
, &nextUpdate
1434 , &revocationDate
, &revocationReason
);
1436 /* if ocsp service is not available then fall back to crl */
1437 if ((status
== CERT_UNDEFINED
)
1438 || (status
== CERT_UNKNOWN
&& strict
))
1440 status
= verify_by_crl(cert
, &nextUpdate
, &revocationDate
1441 , &revocationReason
);
1447 /* if status information is stale */
1448 if (strict
&& nextUpdate
< time(NULL
))
1451 DBG_log("certificate is good but status is stale")
1453 remove_x509_public_key(cert
);
1457 DBG_log("certificate is good")
1460 /* with strict crl policy the public key must have the same
1461 * lifetime as the validity of the ocsp status or crl lifetime
1463 if (strict
&& nextUpdate
< *until
)
1465 *until
= nextUpdate
;
1469 plog("certificate was revoked on %T, reason: %N"
1470 , &revocationDate
, TRUE
1471 , crl_reason_names
, revocationReason
);
1472 remove_x509_public_key(cert
);
1475 case CERT_UNDEFINED
:
1477 plog("certificate status unknown");
1480 remove_x509_public_key(cert
);
1487 /* go up one step in the trust chain */
1490 plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN
);
1495 * List all X.509 certs in a chained list
1497 void list_x509cert_chain(const char *caption
, x509cert_t
* cert
,
1498 u_char auth_flags
, bool utc
)
1503 /* determine the current time */
1506 while (cert
!= NULL
)
1508 if (auth_flags
== AUTH_NONE
|| (auth_flags
& cert
->authority_flags
))
1510 time_t notBefore
, notAfter
;
1512 chunk_t serial
, keyid
, subjkey
, authkey
;
1514 certificate_t
*certificate
= cert
->cert
;
1515 x509_t
*x509
= (x509_t
*)certificate
;
1517 c
.type
= CERT_X509_SIGNATURE
;
1522 whack_log(RC_COMMENT
, " ");
1523 whack_log(RC_COMMENT
, "List of X.509 %s Certificates:", caption
);
1524 whack_log(RC_COMMENT
, " ");
1528 whack_log(RC_COMMENT
, "%T, count: %d", &cert
->installed
, utc
,
1530 whack_log(RC_COMMENT
, " subject: '%Y'",
1531 certificate
->get_subject(certificate
));
1532 whack_log(RC_COMMENT
, " issuer: '%Y'",
1533 certificate
->get_issuer(certificate
));
1534 serial
= x509
->get_serial(x509
);
1535 whack_log(RC_COMMENT
, " serial: %#B", &serial
);
1538 certificate
->get_validity(certificate
, &now
, ¬Before
, ¬After
);
1539 whack_log(RC_COMMENT
, " validity: not before %T %s",
1541 (notBefore
< now
)?
"ok":"fatal (not valid yet)");
1542 whack_log(RC_COMMENT
, " not after %T %s",
1544 check_expiry(notAfter
, CA_CERT_WARNING_INTERVAL
, TRUE
));
1546 key
= certificate
->get_public_key(certificate
);
1549 whack_log(RC_COMMENT
, " pubkey: %N %4d bits%s",
1550 key_type_names
, key
->get_type(key
),
1551 key
->get_keysize(key
) * BITS_PER_BYTE
,
1552 cert
->smartcard ?
", on smartcard" :
1553 (has_private_key(c
)?
", has private key" : ""));
1555 if (key
->get_fingerprint(key
, KEY_ID_PUBKEY_INFO_SHA1
, &keyid
))
1557 whack_log(RC_COMMENT
, " keyid: %#B", &keyid
);
1559 if (key
->get_fingerprint(key
, KEY_ID_PUBKEY_SHA1
, &subjkey
))
1561 whack_log(RC_COMMENT
, " subjkey: %#B", &subjkey
);
1566 /* list optional authorityKeyIdentifier */
1567 authkey
= x509
->get_authKeyIdentifier(x509
);
1570 whack_log(RC_COMMENT
, " authkey: %#B", &authkey
);
1578 * List all X.509 end certificates in a chained list
1580 void list_x509_end_certs(bool utc
)
1582 list_x509cert_chain("End", x509certs
, AUTH_NONE
, utc
);