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 basicConstraints extension
54 static const asn1Object_t basicConstraintsObjects
[] = {
55 { 0, "basicConstraints", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
56 { 1, "CA", ASN1_BOOLEAN
, ASN1_DEF
|ASN1_BODY
}, /* 1 */
57 { 1, "pathLenConstraint", ASN1_INTEGER
, ASN1_OPT
|ASN1_BODY
}, /* 2 */
58 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 3 */
59 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
61 #define BASIC_CONSTRAINTS_CA 1
64 * ASN.1 definition of a authorityKeyIdentifier extension
66 static const asn1Object_t authKeyIdentifierObjects
[] = {
67 { 0, "authorityKeyIdentifier", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
68 { 1, "keyIdentifier", ASN1_CONTEXT_S_0
, ASN1_OPT
|ASN1_BODY
}, /* 1 */
69 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 2 */
70 { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1
, ASN1_OPT
|ASN1_OBJ
}, /* 3 */
71 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 4 */
72 { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2
, ASN1_OPT
|ASN1_BODY
}, /* 5 */
73 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 6 */
74 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
76 #define AUTH_KEY_ID_KEY_ID 1
77 #define AUTH_KEY_ID_CERT_ISSUER 3
78 #define AUTH_KEY_ID_CERT_SERIAL 5
81 * ASN.1 definition of a authorityInfoAccess extension
83 static const asn1Object_t authInfoAccessObjects
[] = {
84 { 0, "authorityInfoAccess", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
85 { 1, "accessDescription", ASN1_SEQUENCE
, ASN1_NONE
}, /* 1 */
86 { 2, "accessMethod", ASN1_OID
, ASN1_BODY
}, /* 2 */
87 { 2, "accessLocation", ASN1_EOC
, ASN1_RAW
}, /* 3 */
88 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 4 */
89 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
91 #define AUTH_INFO_ACCESS_METHOD 2
92 #define AUTH_INFO_ACCESS_LOCATION 3
95 * ASN.1 definition of a extendedKeyUsage extension
97 static const asn1Object_t extendedKeyUsageObjects
[] = {
98 { 0, "extendedKeyUsage", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
99 { 1, "keyPurposeID", ASN1_OID
, ASN1_BODY
}, /* 1 */
100 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 2 */
101 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
103 #define EXT_KEY_USAGE_PURPOSE_ID 1
106 * ASN.1 definition of generalNames
108 static const asn1Object_t generalNamesObjects
[] = {
109 { 0, "generalNames", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
110 { 1, "generalName", ASN1_EOC
, ASN1_RAW
}, /* 1 */
111 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 2 */
112 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
114 #define GENERAL_NAMES_GN 1
117 * ASN.1 definition of generalName
119 static const asn1Object_t generalNameObjects
[] = {
120 { 0, "otherName", ASN1_CONTEXT_C_0
, ASN1_OPT
|ASN1_BODY
}, /* 0 */
121 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 1 */
122 { 0, "rfc822Name", ASN1_CONTEXT_S_1
, ASN1_OPT
|ASN1_BODY
}, /* 2 */
123 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 3 */
124 { 0, "dnsName", ASN1_CONTEXT_S_2
, ASN1_OPT
|ASN1_BODY
}, /* 4 */
125 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 5 */
126 { 0, "x400Address", ASN1_CONTEXT_S_3
, ASN1_OPT
|ASN1_BODY
}, /* 6 */
127 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 7 */
128 { 0, "directoryName", ASN1_CONTEXT_C_4
, ASN1_OPT
|ASN1_BODY
}, /* 8 */
129 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 9 */
130 { 0, "ediPartyName", ASN1_CONTEXT_C_5
, ASN1_OPT
|ASN1_BODY
}, /* 10 */
131 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 11 */
132 { 0, "URI", ASN1_CONTEXT_S_6
, ASN1_OPT
|ASN1_BODY
}, /* 12 */
133 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 13 */
134 { 0, "ipAddress", ASN1_CONTEXT_S_7
, ASN1_OPT
|ASN1_BODY
}, /* 14 */
135 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 15 */
136 { 0, "registeredID", ASN1_CONTEXT_S_8
, ASN1_OPT
|ASN1_BODY
}, /* 16 */
137 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 17 */
138 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
140 #define GN_OBJ_OTHER_NAME 0
141 #define GN_OBJ_RFC822_NAME 2
142 #define GN_OBJ_DNS_NAME 4
143 #define GN_OBJ_X400_ADDRESS 6
144 #define GN_OBJ_DIRECTORY_NAME 8
145 #define GN_OBJ_EDI_PARTY_NAME 10
146 #define GN_OBJ_URI 12
147 #define GN_OBJ_IP_ADDRESS 14
148 #define GN_OBJ_REGISTERED_ID 16
151 * ASN.1 definition of otherName
153 static const asn1Object_t otherNameObjects
[] = {
154 {0, "type-id", ASN1_OID
, ASN1_BODY
}, /* 0 */
155 {0, "value", ASN1_CONTEXT_C_0
, ASN1_BODY
}, /* 1 */
156 {0, "exit", ASN1_EOC
, ASN1_EXIT
}
158 #define ON_OBJ_ID_TYPE 0
159 #define ON_OBJ_VALUE 1
162 * ASN.1 definition of crlDistributionPoints
164 static const asn1Object_t crlDistributionPointsObjects
[] = {
165 { 0, "crlDistributionPoints", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
166 { 1, "DistributionPoint", ASN1_SEQUENCE
, ASN1_NONE
}, /* 1 */
167 { 2, "distributionPoint", ASN1_CONTEXT_C_0
, ASN1_OPT
|ASN1_LOOP
}, /* 2 */
168 { 3, "fullName", ASN1_CONTEXT_C_0
, ASN1_OPT
|ASN1_OBJ
}, /* 3 */
169 { 3, "end choice", ASN1_EOC
, ASN1_END
}, /* 4 */
170 { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1
, ASN1_OPT
|ASN1_BODY
}, /* 5 */
171 { 3, "end choice", ASN1_EOC
, ASN1_END
}, /* 6 */
172 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 7 */
173 { 2, "reasons", ASN1_CONTEXT_C_1
, ASN1_OPT
|ASN1_BODY
}, /* 8 */
174 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 9 */
175 { 2, "crlIssuer", ASN1_CONTEXT_C_2
, ASN1_OPT
|ASN1_BODY
}, /* 10 */
176 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 11 */
177 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 12 */
178 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
180 #define CRL_DIST_POINTS_FULLNAME 3
183 * ASN.1 definition of an X.509v3 x509_cert
185 static const asn1Object_t certObjects
[] = {
186 { 0, "x509", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 0 */
187 { 1, "tbsCertificate", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 1 */
188 { 2, "DEFAULT v1", ASN1_CONTEXT_C_0
, ASN1_DEF
}, /* 2 */
189 { 3, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
190 { 2, "serialNumber", ASN1_INTEGER
, ASN1_BODY
}, /* 4 */
191 { 2, "signature", ASN1_EOC
, ASN1_RAW
}, /* 5 */
192 { 2, "issuer", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 6 */
193 { 2, "validity", ASN1_SEQUENCE
, ASN1_NONE
}, /* 7 */
194 { 3, "notBefore", ASN1_EOC
, ASN1_RAW
}, /* 8 */
195 { 3, "notAfter", ASN1_EOC
, ASN1_RAW
}, /* 9 */
196 { 2, "subject", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 10 */
197 { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE
, ASN1_RAW
}, /* 11 */
198 { 2, "issuerUniqueID", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 12 */
199 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 13 */
200 { 2, "subjectUniqueID", ASN1_CONTEXT_C_2
, ASN1_OPT
}, /* 14 */
201 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 15 */
202 { 2, "optional extensions", ASN1_CONTEXT_C_3
, ASN1_OPT
}, /* 16 */
203 { 3, "extensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 17 */
204 { 4, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 18 */
205 { 5, "extnID", ASN1_OID
, ASN1_BODY
}, /* 19 */
206 { 5, "critical", ASN1_BOOLEAN
, ASN1_DEF
|ASN1_BODY
}, /* 20 */
207 { 5, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 21 */
208 { 3, "end loop", ASN1_EOC
, ASN1_END
}, /* 22 */
209 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 23 */
210 { 1, "signatureAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 24 */
211 { 1, "signatureValue", ASN1_BIT_STRING
, ASN1_BODY
}, /* 25 */
212 { 0, "exit", ASN1_EOC
, ASN1_EXIT
}
214 #define X509_OBJ_CERTIFICATE 0
215 #define X509_OBJ_TBS_CERTIFICATE 1
216 #define X509_OBJ_VERSION 3
217 #define X509_OBJ_SERIAL_NUMBER 4
218 #define X509_OBJ_SIG_ALG 5
219 #define X509_OBJ_ISSUER 6
220 #define X509_OBJ_NOT_BEFORE 8
221 #define X509_OBJ_NOT_AFTER 9
222 #define X509_OBJ_SUBJECT 10
223 #define X509_OBJ_SUBJECT_PUBLIC_KEY_INFO 11
224 #define X509_OBJ_EXTN_ID 19
225 #define X509_OBJ_CRITICAL 20
226 #define X509_OBJ_EXTN_VALUE 21
227 #define X509_OBJ_ALGORITHM 24
228 #define X509_OBJ_SIGNATURE 25
230 const x509cert_t empty_x509cert
= {
232 UNDEFINED_TIME
, /* installed */
234 FALSE
, /* smartcard */
235 AUTH_NONE
, /* authority_flags */
236 { NULL
, 0 } , /* certificate */
237 { NULL
, 0 } , /* tbsCertificate */
239 { NULL
, 0 } , /* serialNumber */
240 OID_UNKNOWN
, /* sigAlg */
241 { NULL
, 0 } , /* issuer */
245 { NULL
, 0 } , /* subject */
246 NULL
, /* public_key */
248 /* subjectUniqueID */
255 FALSE
, /* isOcspSigner */
256 { NULL
, 0 } , /* subjectKeyID */
257 { NULL
, 0 } , /* authKeyID */
258 { NULL
, 0 } , /* authKeySerialNumber */
259 { NULL
, 0 } , /* accessLocation */
260 NULL
, /* subjectAltName */
261 NULL
, /* crlDistributionPoints */
262 OID_UNKNOWN
, /* algorithm */
263 { NULL
, 0 } /* signature */
266 /* coding of X.501 distinguished name */
274 /* X.501 acronyms for well known object identifiers (OIDs) */
276 static u_char oid_ND
[] = {0x02, 0x82, 0x06, 0x01,
278 static u_char oid_UID
[] = {0x09, 0x92, 0x26, 0x89, 0x93,
279 0xF2, 0x2C, 0x64, 0x01, 0x01};
280 static u_char oid_DC
[] = {0x09, 0x92, 0x26, 0x89, 0x93,
281 0xF2, 0x2C, 0x64, 0x01, 0x19};
282 static u_char oid_CN
[] = {0x55, 0x04, 0x03};
283 static u_char oid_S
[] = {0x55, 0x04, 0x04};
284 static u_char oid_SN
[] = {0x55, 0x04, 0x05};
285 static u_char oid_C
[] = {0x55, 0x04, 0x06};
286 static u_char oid_L
[] = {0x55, 0x04, 0x07};
287 static u_char oid_ST
[] = {0x55, 0x04, 0x08};
288 static u_char oid_O
[] = {0x55, 0x04, 0x0A};
289 static u_char oid_OU
[] = {0x55, 0x04, 0x0B};
290 static u_char oid_T
[] = {0x55, 0x04, 0x0C};
291 static u_char oid_D
[] = {0x55, 0x04, 0x0D};
292 static u_char oid_N
[] = {0x55, 0x04, 0x29};
293 static u_char oid_G
[] = {0x55, 0x04, 0x2A};
294 static u_char oid_I
[] = {0x55, 0x04, 0x2B};
295 static u_char oid_ID
[] = {0x55, 0x04, 0x2D};
296 static u_char oid_EN
[] = {0x60, 0x86, 0x48, 0x01, 0x86,
297 0xF8, 0x42, 0x03, 0x01, 0x03};
298 static u_char oid_E
[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
299 0x0D, 0x01, 0x09, 0x01};
300 static u_char oid_UN
[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
301 0x0D, 0x01, 0x09, 0x02};
302 static u_char oid_TCGID
[] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x89,
303 0x31, 0x01, 0x01, 0x02, 0x02, 0x4B};
305 static const x501rdn_t x501rdns
[] = {
306 {"ND" , {oid_ND
, 7}, ASN1_PRINTABLESTRING
},
307 {"UID" , {oid_UID
, 10}, ASN1_PRINTABLESTRING
},
308 {"DC" , {oid_DC
, 10}, ASN1_PRINTABLESTRING
},
309 {"CN" , {oid_CN
, 3}, ASN1_PRINTABLESTRING
},
310 {"S" , {oid_S
, 3}, ASN1_PRINTABLESTRING
},
311 {"SN" , {oid_SN
, 3}, ASN1_PRINTABLESTRING
},
312 {"serialNumber" , {oid_SN
, 3}, ASN1_PRINTABLESTRING
},
313 {"C" , {oid_C
, 3}, ASN1_PRINTABLESTRING
},
314 {"L" , {oid_L
, 3}, ASN1_PRINTABLESTRING
},
315 {"ST" , {oid_ST
, 3}, ASN1_PRINTABLESTRING
},
316 {"O" , {oid_O
, 3}, ASN1_PRINTABLESTRING
},
317 {"OU" , {oid_OU
, 3}, ASN1_PRINTABLESTRING
},
318 {"T" , {oid_T
, 3}, ASN1_PRINTABLESTRING
},
319 {"D" , {oid_D
, 3}, ASN1_PRINTABLESTRING
},
320 {"N" , {oid_N
, 3}, ASN1_PRINTABLESTRING
},
321 {"G" , {oid_G
, 3}, ASN1_PRINTABLESTRING
},
322 {"I" , {oid_I
, 3}, ASN1_PRINTABLESTRING
},
323 {"ID" , {oid_ID
, 3}, ASN1_PRINTABLESTRING
},
324 {"EN" , {oid_EN
, 10}, ASN1_PRINTABLESTRING
},
325 {"employeeNumber" , {oid_EN
, 10}, ASN1_PRINTABLESTRING
},
326 {"E" , {oid_E
, 9}, ASN1_IA5STRING
},
327 {"Email" , {oid_E
, 9}, ASN1_IA5STRING
},
328 {"emailAddress" , {oid_E
, 9}, ASN1_IA5STRING
},
329 {"UN" , {oid_UN
, 9}, ASN1_IA5STRING
},
330 {"unstructuredName", {oid_UN
, 9}, ASN1_IA5STRING
},
331 {"TCGID" , {oid_TCGID
, 12}, ASN1_PRINTABLESTRING
}
334 #define X501_RDN_ROOF 26
336 static u_char ASN1_subjectAltName_oid_str
[] = {
337 0x06, 0x03, 0x55, 0x1D, 0x11
340 static const chunk_t ASN1_subjectAltName_oid
= chunk_from_buf(ASN1_subjectAltName_oid_str
);
342 static void update_chunk(chunk_t
*ch
, int n
)
344 n
= (n
> -1 && n
< (int)ch
->len
)? n
: (int)ch
->len
-1;
345 ch
->ptr
+= n
; ch
->len
-= n
;
350 * Pointer is set to the first RDN in a DN
352 static err_t
init_rdn(chunk_t dn
, chunk_t
*rdn
, chunk_t
*attribute
, bool *next
)
355 *attribute
= chunk_empty
;
357 /* a DN is a SEQUENCE OF RDNs */
359 if (*dn
.ptr
!= ASN1_SEQUENCE
)
361 return "DN is not a SEQUENCE";
364 rdn
->len
= asn1_length(&dn
);
366 if (rdn
->len
== ASN1_INVALID_LENGTH
)
368 return "Invalid RDN length";
372 /* are there any RDNs ? */
373 *next
= rdn
->len
> 0;
379 * Fetches the next RDN in a DN
381 static err_t
get_next_rdn(chunk_t
*rdn
, chunk_t
* attribute
, chunk_t
*oid
,
382 chunk_t
*value
, asn1_t
*type
, bool *next
)
386 /* initialize return values */
388 *value
= chunk_empty
;
390 /* if all attributes have been parsed, get next rdn */
391 if (attribute
->len
<= 0)
393 /* an RDN is a SET OF attributeTypeAndValue */
394 if (*rdn
->ptr
!= ASN1_SET
)
396 return "RDN is not a SET";
398 attribute
->len
= asn1_length(rdn
);
400 if (attribute
->len
== ASN1_INVALID_LENGTH
)
402 return "Invalid attribute length";
404 attribute
->ptr
= rdn
->ptr
;
406 /* advance to start of next RDN */
407 rdn
->ptr
+= attribute
->len
;
408 rdn
->len
-= attribute
->len
;
411 /* an attributeTypeAndValue is a SEQUENCE */
412 if (*attribute
->ptr
!= ASN1_SEQUENCE
)
414 return "attributeTypeAndValue is not a SEQUENCE";
417 /* extract the attribute body */
418 body
.len
= asn1_length(attribute
);
420 if (body
.len
== ASN1_INVALID_LENGTH
)
422 return "Invalid attribute body length";
424 body
.ptr
= attribute
->ptr
;
426 /* advance to start of next attribute */
427 attribute
->ptr
+= body
.len
;
428 attribute
->len
-= body
.len
;
430 /* attribute type is an OID */
431 if (*body
.ptr
!= ASN1_OID
)
433 return "attributeType is not an OID";
437 oid
->len
= asn1_length(&body
);
439 if (oid
->len
== ASN1_INVALID_LENGTH
)
441 return "Invalid attribute OID length";
445 /* advance to the attribute value */
446 body
.ptr
+= oid
->len
;
447 body
.len
-= oid
->len
;
449 /* extract string type */
452 /* extract string value */
453 value
->len
= asn1_length(&body
);
455 if (value
->len
== ASN1_INVALID_LENGTH
)
457 return "Invalid attribute string length";
459 value
->ptr
= body
.ptr
;
461 /* are there any RDNs left? */
462 *next
= rdn
->len
> 0 || attribute
->len
> 0;
468 * Parses an ASN.1 distinguished name int its OID/value pairs
470 static err_t
dn_parse(chunk_t dn
, chunk_t
*str
)
472 chunk_t rdn
, oid
, attribute
, value
;
478 err_t ugh
= init_rdn(dn
, &rdn
, &attribute
, &next
);
480 if (ugh
!= NULL
) /* a parsing error has occured */
487 ugh
= get_next_rdn(&rdn
, &attribute
, &oid
, &value
, &type
, &next
);
489 if (ugh
!= NULL
) /* a parsing error has occured */
494 if (first
) /* first OID/value pair */
498 else /* separate OID/value pair by a comma */
500 update_chunk(str
, snprintf(str
->ptr
,str
->len
,", "));
504 oid_code
= asn1_known_oid(oid
);
505 if (oid_code
== OID_UNKNOWN
) /* OID not found in list */
511 update_chunk(str
, snprintf(str
->ptr
,str
->len
,"%s",
512 oid_names
[oid_code
].name
));
516 update_chunk(str
, snprintf(str
->ptr
,str
->len
,"=%.*s",
517 (int)value
.len
,value
.ptr
));
523 * Count the number of wildcard RDNs in a distinguished name
525 int dn_count_wildcards(chunk_t dn
)
527 chunk_t rdn
, attribute
, oid
, value
;
532 err_t ugh
= init_rdn(dn
, &rdn
, &attribute
, &next
);
534 if (ugh
!= NULL
) /* a parsing error has occured */
541 ugh
= get_next_rdn(&rdn
, &attribute
, &oid
, &value
, &type
, &next
);
543 if (ugh
!= NULL
) /* a parsing error has occured */
547 if (value
.len
== 1 && *value
.ptr
== '*')
549 wildcards
++; /* we have found a wildcard RDN */
556 * Prints a binary string in hexadecimal form
558 void hex_str(chunk_t bin
, chunk_t
*str
)
561 update_chunk(str
, snprintf(str
->ptr
,str
->len
,"0x"));
562 for (i
=0; i
< bin
.len
; i
++)
563 update_chunk(str
, snprintf(str
->ptr
,str
->len
,"%02X",*bin
.ptr
++));
567 /** Converts a binary DER-encoded ASN.1 distinguished name
568 * into LDAP-style human-readable ASCII format
570 int dntoa(char *dst
, size_t dstlen
, chunk_t dn
)
577 ugh
= dn_parse(dn
, &str
);
579 if (ugh
!= NULL
) /* error, print DN as hex string */
582 DBG_log("error in DN parsing: %s", ugh
)
588 return (int)(dstlen
- str
.len
);
592 * Same as dntoa but prints a special string for a null dn
594 int dntoa_or_null(char *dst
, size_t dstlen
, chunk_t dn
, const char* null_dn
)
598 return snprintf(dst
, dstlen
, "%s", null_dn
);
602 return dntoa(dst
, dstlen
, dn
);
608 * Codes ASN.1 lengths up to a size of 16'777'215 bytes
610 static void code_asn1_length(size_t length
, chunk_t
*code
)
614 code
->ptr
[0] = length
;
617 else if (length
< 256)
620 code
->ptr
[1] = (u_char
) length
;
623 else if (length
< 65536)
626 code
->ptr
[1] = length
>> 8;
627 code
->ptr
[2] = length
& 0x00ff;
633 code
->ptr
[1] = length
>> 16;
634 code
->ptr
[2] = (length
>> 8) & 0x00ff;
635 code
->ptr
[3] = length
& 0x0000ff;
641 * Converts an LDAP-style human-readable ASCII-encoded
642 * ASN.1 distinguished name into binary DER-encoded format
644 err_t
atodn(char *src
, chunk_t
*dn
)
646 /* finite state machine for atodn */
656 u_char oid_len_buf
[3];
657 u_char name_len_buf
[3];
658 u_char rdn_seq_len_buf
[3];
659 u_char rdn_set_len_buf
[3];
660 u_char dn_seq_len_buf
[3];
662 chunk_t asn1_oid_len
= { oid_len_buf
, 0 };
663 chunk_t asn1_name_len
= { name_len_buf
, 0 };
664 chunk_t asn1_rdn_seq_len
= { rdn_seq_len_buf
, 0 };
665 chunk_t asn1_rdn_set_len
= { rdn_set_len_buf
, 0 };
666 chunk_t asn1_dn_seq_len
= { dn_seq_len_buf
, 0 };
667 chunk_t oid
= chunk_empty
;
668 chunk_t name
= chunk_empty
;
678 u_char
*dn_ptr
= dn
->ptr
+ 4;
680 state_t state
= SEARCH_OID
;
687 if (*src
!= ' ' && *src
!= '/' && *src
!= ',')
695 if (*src
!= ' ' && *src
!= '=')
701 for (pos
= 0; pos
< X501_RDN_ROOF
; pos
++)
703 if (strlen(x501rdns
[pos
].name
) == oid
.len
&&
704 strncasecmp(x501rdns
[pos
].name
, oid
.ptr
, oid
.len
) == 0)
706 break; /* found a valid OID */
709 if (pos
== X501_RDN_ROOF
)
711 ugh
= "unknown OID in distinguished name";
715 code_asn1_length(x501rdns
[pos
].oid
.len
, &asn1_oid_len
);
717 /* reset oid and change state */
723 if (*src
!= ' ' && *src
!= '=')
732 if (*src
!= ',' && *src
!= '/' && *src
!= '\0')
746 name
.len
-= whitespace
;
747 code_asn1_length(name
.len
, &asn1_name_len
);
749 /* compute the length of the relative distinguished name sequence */
750 rdn_seq_len
= 1 + asn1_oid_len
.len
+ x501rdns
[pos
].oid
.len
+
751 1 + asn1_name_len
.len
+ name
.len
;
752 code_asn1_length(rdn_seq_len
, &asn1_rdn_seq_len
);
754 /* compute the length of the relative distinguished name set */
755 rdn_set_len
= 1 + asn1_rdn_seq_len
.len
+ rdn_seq_len
;
756 code_asn1_length(rdn_set_len
, &asn1_rdn_set_len
);
758 /* encode the relative distinguished name */
759 *dn_ptr
++ = ASN1_SET
;
760 chunkcpy(dn_ptr
, asn1_rdn_set_len
);
761 *dn_ptr
++ = ASN1_SEQUENCE
;
762 chunkcpy(dn_ptr
, asn1_rdn_seq_len
);
763 *dn_ptr
++ = ASN1_OID
;
764 chunkcpy(dn_ptr
, asn1_oid_len
);
765 chunkcpy(dn_ptr
, x501rdns
[pos
].oid
);
766 /* encode the ASN.1 character string type of the name */
767 *dn_ptr
++ = (x501rdns
[pos
].type
== ASN1_PRINTABLESTRING
768 && !asn1_is_printablestring(name
))? ASN1_T61STRING
: x501rdns
[pos
].type
;
769 chunkcpy(dn_ptr
, asn1_name_len
);
770 chunkcpy(dn_ptr
, name
);
772 /* accumulate the length of the distinguished name sequence */
773 dn_seq_len
+= 1 + asn1_rdn_set_len
.len
+ rdn_set_len
;
775 /* reset name and change state */
783 } while (*src
++ != '\0');
785 /* complete the distinguished name sequence*/
786 code_asn1_length(dn_seq_len
, &asn1_dn_seq_len
);
787 dn
->ptr
+= 3 - asn1_dn_seq_len
.len
;
788 dn
->len
= 1 + asn1_dn_seq_len
.len
+ dn_seq_len
;
790 *dn_ptr
++ = ASN1_SEQUENCE
;
791 chunkcpy(dn_ptr
, asn1_dn_seq_len
);
796 * compare two distinguished names by comparing the individual RDNs
798 bool same_dn(chunk_t a
, chunk_t b
)
800 chunk_t rdn_a
, rdn_b
, attribute_a
, attribute_b
;
801 chunk_t oid_a
, oid_b
, value_a
, value_b
;
802 asn1_t type_a
, type_b
;
805 /* same lengths for the DNs */
811 /* try a binary comparison first */
812 if (memeq(a
.ptr
, b
.ptr
, b
.len
))
817 /* initialize DN parsing */
818 if (init_rdn(a
, &rdn_a
, &attribute_a
, &next_a
) != NULL
819 || init_rdn(b
, &rdn_b
, &attribute_b
, &next_b
) != NULL
)
824 /* fetch next RDN pair */
825 while (next_a
&& next_b
)
827 /* parse next RDNs and check for errors */
828 if (get_next_rdn(&rdn_a
, &attribute_a
, &oid_a
, &value_a
, &type_a
, &next_a
) != NULL
829 || get_next_rdn(&rdn_b
, &attribute_b
, &oid_b
, &value_b
, &type_b
, &next_b
) != NULL
)
834 /* OIDs must agree */
835 if (oid_a
.len
!= oid_b
.len
|| memcmp(oid_a
.ptr
, oid_b
.ptr
, oid_b
.len
) != 0)
840 /* same lengths for values */
841 if (value_a
.len
!= value_b
.len
)
846 /* printableStrings and email RDNs require uppercase comparison */
847 if (type_a
== type_b
&& (type_a
== ASN1_PRINTABLESTRING
||
848 (type_a
== ASN1_IA5STRING
&& asn1_known_oid(oid_a
) == OID_EMAIL_ADDRESS
)))
850 if (strncasecmp(value_a
.ptr
, value_b
.ptr
, value_b
.len
) != 0)
857 if (strncmp(value_a
.ptr
, value_b
.ptr
, value_b
.len
) != 0)
863 /* both DNs must have same number of RDNs */
864 if (next_a
|| next_b
)
869 /* the two DNs are equal! */
875 * Compare two distinguished names by comparing the individual RDNs.
876 * A single'*' character designates a wildcard RDN in DN b.
878 bool match_dn(chunk_t a
, chunk_t b
, int *wildcards
)
880 chunk_t rdn_a
, rdn_b
, attribute_a
, attribute_b
;
881 chunk_t oid_a
, oid_b
, value_a
, value_b
;
882 asn1_t type_a
, type_b
;
885 /* initialize wildcard counter */
888 /* initialize DN parsing */
889 if (init_rdn(a
, &rdn_a
, &attribute_a
, &next_a
) != NULL
890 || init_rdn(b
, &rdn_b
, &attribute_b
, &next_b
) != NULL
)
895 /* fetch next RDN pair */
896 while (next_a
&& next_b
)
898 /* parse next RDNs and check for errors */
899 if (get_next_rdn(&rdn_a
, &attribute_a
, &oid_a
, &value_a
, &type_a
, &next_a
) != NULL
900 || get_next_rdn(&rdn_b
, &attribute_b
, &oid_b
, &value_b
, &type_b
, &next_b
) != NULL
)
905 /* OIDs must agree */
906 if (oid_a
.len
!= oid_b
.len
|| memcmp(oid_a
.ptr
, oid_b
.ptr
, oid_b
.len
) != 0)
911 /* does rdn_b contain a wildcard? */
912 if (value_b
.len
== 1 && *value_b
.ptr
== '*')
918 /* same lengths for values */
919 if (value_a
.len
!= value_b
.len
)
924 /* printableStrings and email RDNs require uppercase comparison */
925 if (type_a
== type_b
&& (type_a
== ASN1_PRINTABLESTRING
||
926 (type_a
== ASN1_IA5STRING
&& asn1_known_oid(oid_a
) == OID_EMAIL_ADDRESS
)))
928 if (strncasecmp(value_a
.ptr
, value_b
.ptr
, value_b
.len
) != 0)
935 if (strncmp(value_a
.ptr
, value_b
.ptr
, value_b
.len
) != 0)
942 /* both DNs must have same number of RDNs */
943 if (next_a
|| next_b
)
948 /* the two DNs match! */
953 * Compare two X.509 certificates by comparing their signatures
955 bool same_x509cert(const x509cert_t
*a
, const x509cert_t
*b
)
957 return chunk_equals(a
->signature
, b
->signature
);
961 * For each link pointing to the certificate increase the count by one
963 void share_x509cert(x509cert_t
*cert
)
972 * Add a X.509 user/host certificate to the chained list
974 x509cert_t
* add_x509cert(x509cert_t
*cert
)
976 x509cert_t
*c
= x509certs
;
980 if (same_x509cert(c
, cert
)) /* already in chain, free cert */
988 /* insert new cert at the root of the chain */
989 lock_certs_and_keys("add_x509cert");
990 cert
->next
= x509certs
;
992 DBG(DBG_CONTROL
| DBG_PARSING
,
993 DBG_log(" x509 cert inserted")
995 unlock_certs_and_keys("add_x509cert");
1000 * Choose either subject DN or a subjectAltName as connection end ID
1002 void select_x509cert_id(x509cert_t
*cert
, struct id
*end_id
)
1004 bool copy_subject_dn
= TRUE
; /* ID is subject DN */
1006 if (end_id
->kind
!= ID_ANY
) /* check for matching subjectAltName */
1008 generalName_t
*gn
= cert
->subjectAltName
;
1012 struct id id
= empty_id
;
1015 if (same_id(&id
, end_id
))
1017 copy_subject_dn
= FALSE
; /* take subjectAltName instead */
1024 if (copy_subject_dn
)
1026 if (end_id
->kind
!= ID_ANY
&& end_id
->kind
!= ID_DER_ASN1_DN
)
1030 idtoa(end_id
, buf
, BUF_LEN
);
1031 plog(" no subjectAltName matches ID '%s', replaced by subject DN", buf
);
1033 end_id
->kind
= ID_DER_ASN1_DN
;
1034 end_id
->name
.len
= cert
->subject
.len
;
1035 end_id
->name
.ptr
= temporary_cyclic_buffer();
1036 memcpy(end_id
->name
.ptr
, cert
->subject
.ptr
, cert
->subject
.len
);
1041 * Check for equality between two key identifiers
1043 bool same_keyid(chunk_t a
, chunk_t b
)
1045 if (a
.ptr
== NULL
|| b
.ptr
== NULL
)
1049 return chunk_equals(a
, b
);
1053 * Check for equality between two serial numbers
1055 bool same_serial(chunk_t a
, chunk_t b
)
1057 /* do not compare serial numbers if one of them is not defined */
1058 if (a
.ptr
== NULL
|| b
.ptr
== NULL
)
1062 return chunk_equals(a
, b
);
1066 * Get a X.509 certificate with a given issuer found at a certain position
1068 x509cert_t
* get_x509cert(chunk_t issuer
, chunk_t serial
, chunk_t keyid
,
1071 x509cert_t
*cert
= (chain
!= NULL
)? chain
->next
: x509certs
;
1073 while (cert
!= NULL
)
1075 if ((keyid
.ptr
!= NULL
) ?
same_keyid(keyid
, cert
->authKeyID
)
1076 : (same_dn(issuer
, cert
->issuer
)
1077 && same_serial(serial
, cert
->authKeySerialNumber
)))
1087 * Encode a linked list of subjectAltNames
1089 chunk_t
build_subjectAltNames(generalName_t
*subjectAltNames
)
1094 generalName_t
*gn
= subjectAltNames
;
1096 /* compute the total size of the ASN.1 attributes object */
1099 len
+= gn
->name
.len
;
1103 pos
= asn1_build_object(&names
, ASN1_SEQUENCE
, len
);
1105 gn
= subjectAltNames
;
1108 chunkcpy(pos
, gn
->name
);
1112 return asn1_wrap(ASN1_SEQUENCE
, "cm"
1113 , ASN1_subjectAltName_oid
1114 , asn1_wrap(ASN1_OCTET_STRING
, "m", names
));
1118 * Build a to-be-signed X.509 certificate body
1120 static chunk_t
build_tbs_x509cert(x509cert_t
*cert
, public_key_t
*rsa
)
1122 /* version is always X.509v3 */
1123 chunk_t version
= asn1_simple_object(ASN1_CONTEXT_C_0
, ASN1_INTEGER_2
);
1124 chunk_t key
= chunk_empty
;
1125 chunk_t extensions
= chunk_empty
;
1127 rsa
->get_encoding(rsa
, KEY_PUB_ASN1_DER
, &key
);
1129 chunk_t keyInfo
= asn1_wrap(ASN1_SEQUENCE
, "cm",
1130 asn1_algorithmIdentifier(OID_RSA_ENCRYPTION
),
1131 asn1_bitstring("m", key
));
1133 if (cert
->subjectAltName
!= NULL
)
1135 extensions
= asn1_wrap(ASN1_CONTEXT_C_3
, "m"
1136 , asn1_wrap(ASN1_SEQUENCE
, "m"
1137 , build_subjectAltNames(cert
->subjectAltName
)));
1140 return asn1_wrap(ASN1_SEQUENCE
, "mmccmcmm"
1142 , asn1_integer("c", cert
->serialNumber
)
1143 , asn1_algorithmIdentifier(cert
->sigAlg
)
1145 , asn1_wrap(ASN1_SEQUENCE
, "mm"
1146 , asn1_from_time(&cert
->notBefore
, ASN1_UTCTIME
)
1147 , asn1_from_time(&cert
->notAfter
, ASN1_UTCTIME
)
1156 * Build a DER-encoded X.509 certificate
1158 void build_x509cert(x509cert_t
*cert
, public_key_t
*cert_key
,
1159 private_key_t
*signer_key
)
1161 chunk_t tbs_cert
= build_tbs_x509cert(cert
, cert_key
);
1163 chunk_t signature
= x509_build_signature(tbs_cert
, cert
->sigAlg
1164 , signer_key
, TRUE
);
1166 cert
->certificate
= asn1_wrap(ASN1_SEQUENCE
, "mcm"
1168 , asn1_algorithmIdentifier(cert
->sigAlg
)
1173 * Free the dynamic memory used to store generalNames
1175 void free_generalNames(generalName_t
* gn
, bool free_name
)
1179 generalName_t
*gn_top
= gn
;
1190 * Free a X.509 certificate
1192 void free_x509cert(x509cert_t
*cert
)
1196 DESTROY_IF(cert
->public_key
);
1197 free_generalNames(cert
->subjectAltName
, FALSE
);
1198 free_generalNames(cert
->crlDistributionPoints
, FALSE
);
1199 free(cert
->certificate
.ptr
);
1206 * Release of a certificate decreases the count by one
1207 * the certificate is freed when the counter reaches zero
1209 void release_x509cert(x509cert_t
*cert
)
1211 if (cert
!= NULL
&& --cert
->count
== 0)
1213 x509cert_t
**pp
= &x509certs
;
1219 free_x509cert(cert
);
1224 * Stores a chained list of end certs and CA certs
1226 void store_x509certs(x509cert_t
**firstcert
, bool strict
)
1228 x509cert_t
*cacerts
= NULL
;
1229 x509cert_t
**pp
= firstcert
;
1231 /* first extract CA certs, discarding root CA certs */
1235 x509cert_t
*cert
= *pp
;
1241 /* we don't accept self-signed CA certs */
1242 if (same_dn(cert
->issuer
, cert
->subject
))
1244 plog("self-signed cacert rejected");
1245 free_x509cert(cert
);
1249 /* insertion into temporary chain of candidate CA certs */
1250 cert
->next
= cacerts
;
1260 /* now verify the candidate CA certs */
1262 while (cacerts
!= NULL
)
1264 x509cert_t
*cert
= cacerts
;
1266 cacerts
= cacerts
->next
;
1268 if (trust_authcert_candidate(cert
, cacerts
))
1270 add_authcert(cert
, AUTH_CA
);
1274 plog("intermediate cacert rejected");
1275 free_x509cert(cert
);
1279 /* now verify the end certificates */
1286 x509cert_t
*cert
= *pp
;
1288 if (verify_x509cert(cert
, strict
, &valid_until
))
1290 DBG(DBG_CONTROL
| DBG_PARSING
,
1291 DBG_log("public key validated")
1293 add_x509_public_key(cert
, valid_until
, DAL_SIGNED
);
1297 plog("X.509 certificate rejected");
1300 free_x509cert(cert
);
1305 * Check if a signature over binary blob is genuine
1307 bool x509_check_signature(chunk_t tbs
, chunk_t sig
, int algorithm
,
1308 const x509cert_t
*issuer_cert
)
1310 public_key_t
*key
= issuer_cert
->public_key
;
1311 signature_scheme_t scheme
= signature_scheme_from_oid(algorithm
);
1313 if (scheme
== SIGN_UNKNOWN
)
1317 return key
->verify(key
, scheme
, tbs
, sig
);
1321 * Build an ASN.1 encoded PKCS#1 signature over a binary blob
1323 chunk_t
x509_build_signature(chunk_t tbs
, int algorithm
, private_key_t
*key
,
1327 signature_scheme_t scheme
= signature_scheme_from_oid(algorithm
);
1329 if (scheme
== SIGN_UNKNOWN
|| !key
->sign(key
, scheme
, tbs
, &signature
))
1333 return (bit_string
) ?
asn1_bitstring("m", signature
)
1334 : asn1_wrap(ASN1_OCTET_STRING
, "m", signature
);
1338 * Extracts the basicConstraints extension
1340 static bool parse_basicConstraints(chunk_t blob
, int level0
)
1342 asn1_parser_t
*parser
;
1347 parser
= asn1_parser_create(basicConstraintsObjects
, blob
);
1348 parser
->set_top_level(parser
, level0
);
1350 while (parser
->iterate(parser
, &objectID
, &object
))
1352 if (objectID
== BASIC_CONSTRAINTS_CA
)
1354 isCA
= object
.len
&& *object
.ptr
;
1356 DBG_log(" %s",(isCA
)?
"TRUE":"FALSE");
1360 parser
->destroy(parser
);
1366 * Converts a X.500 generalName into an ID
1368 void gntoid(struct id
*id
, const generalName_t
*gn
)
1372 case GN_DNS_NAME
: /* ID type: ID_FQDN */
1374 id
->name
= gn
->name
;
1376 case GN_IP_ADDRESS
: /* ID type: ID_IPV4_ADDR */
1378 const struct af_info
*afi
= &af_inet4_info
;
1381 id
->kind
= afi
->id_addr
;
1382 ugh
= initaddr(gn
->name
.ptr
, gn
->name
.len
, afi
->af
, &id
->ip_addr
);
1385 case GN_RFC822_NAME
: /* ID type: ID_USER_FQDN */
1386 id
->kind
= ID_USER_FQDN
;
1387 id
->name
= gn
->name
;
1391 id
->name
= chunk_empty
;
1396 * Compute the subjectKeyIdentifier according to section 4.2.1.2 of RFC 3280
1397 * as the 160 bit SHA-1 hash of the public key
1399 bool compute_subjectKeyID(x509cert_t
*cert
, chunk_t subjectKeyID
)
1401 chunk_t fingerprint
;
1403 if (!cert
->public_key
->get_fingerprint(cert
->public_key
, KEY_ID_PUBKEY_SHA1
,
1406 plog(" unable to compute subjectKeyID");
1409 memcpy(subjectKeyID
.ptr
, fingerprint
.ptr
, subjectKeyID
.len
);
1414 * Extracts an otherName
1416 static bool parse_otherName(chunk_t blob
, int level0
)
1418 asn1_parser_t
*parser
;
1421 int oid
= OID_UNKNOWN
;
1422 bool success
= FALSE
;
1424 parser
= asn1_parser_create(otherNameObjects
, blob
);
1425 parser
->set_top_level(parser
, level0
);
1427 while (parser
->iterate(parser
, &objectID
, &object
))
1431 case ON_OBJ_ID_TYPE
:
1432 oid
= asn1_known_oid(object
);
1435 if (oid
== OID_XMPP_ADDR
)
1437 if (!asn1_parse_simple_object(&object
, ASN1_UTF8STRING
,
1438 parser
->get_level(parser
) + 1, "xmppAddr"))
1448 success
= parser
->success(parser
);
1451 parser
->destroy(parser
);
1457 * Extracts a generalName
1459 static generalName_t
* parse_generalName(chunk_t blob
, int level0
)
1461 u_char buf
[BUF_LEN
];
1462 asn1_parser_t
*parser
;
1464 generalName_t
*gn
= NULL
;
1467 parser
= asn1_parser_create(generalNameObjects
, blob
);
1468 parser
->set_top_level(parser
, level0
);
1470 while (parser
->iterate(parser
, &objectID
, &object
))
1472 bool valid_gn
= FALSE
;
1475 case GN_OBJ_RFC822_NAME
:
1476 case GN_OBJ_DNS_NAME
:
1479 DBG_log(" '%.*s'", (int)object
.len
, object
.ptr
);
1483 case GN_OBJ_DIRECTORY_NAME
:
1485 dntoa(buf
, BUF_LEN
, object
);
1486 DBG_log(" '%s'", buf
)
1490 case GN_OBJ_IP_ADDRESS
:
1492 DBG_log(" '%d.%d.%d.%d'", *object
.ptr
, *(object
.ptr
+1),
1493 *(object
.ptr
+2), *(object
.ptr
+3));
1497 case GN_OBJ_OTHER_NAME
:
1498 if (!parse_otherName(object
, parser
->get_level(parser
)+1))
1503 case GN_OBJ_X400_ADDRESS
:
1504 case GN_OBJ_EDI_PARTY_NAME
:
1505 case GN_OBJ_REGISTERED_ID
:
1513 gn
= malloc_thing(generalName_t
);
1514 gn
->kind
= (objectID
- GN_OBJ_OTHER_NAME
) / 2;
1522 parser
->destroy(parser
);
1527 * Extracts one or several GNs and puts them into a chained list
1529 static generalName_t
* parse_generalNames(chunk_t blob
, int level0
, bool implicit
)
1531 asn1_parser_t
*parser
;
1534 generalName_t
*top_gn
= NULL
;
1536 parser
= asn1_parser_create(generalNamesObjects
, blob
);
1537 parser
->set_top_level(parser
, level0
);
1538 parser
->set_flags(parser
, implicit
, FALSE
);
1540 while (parser
->iterate(parser
, &objectID
, &object
))
1542 if (objectID
== GENERAL_NAMES_GN
)
1544 generalName_t
*gn
= parse_generalName(object
,
1545 parser
->get_level(parser
)+1);
1553 parser
->destroy(parser
);
1559 * Returns a directoryName
1561 chunk_t
get_directoryName(chunk_t blob
, int level
, bool implicit
)
1563 chunk_t name
= chunk_empty
;
1564 generalName_t
* gn
= parse_generalNames(blob
, level
, implicit
);
1566 if (gn
!= NULL
&& gn
->kind
== GN_DIRECTORY_NAME
)
1570 free_generalNames(gn
, FALSE
);
1575 * Extracts an authoritykeyIdentifier
1577 void parse_authorityKeyIdentifier(chunk_t blob
, int level0
,
1579 chunk_t
*authKeySerialNumber
)
1581 asn1_parser_t
*parser
;
1585 parser
= asn1_parser_create(authKeyIdentifierObjects
, blob
);
1586 parser
->set_top_level(parser
, level0
);
1588 while (parser
->iterate(parser
, &objectID
, &object
))
1592 case AUTH_KEY_ID_KEY_ID
:
1593 *authKeyID
= object
;
1595 case AUTH_KEY_ID_CERT_ISSUER
:
1597 generalName_t
* gn
= parse_generalNames(object
,
1598 parser
->get_level(parser
) + 1, TRUE
);
1600 free_generalNames(gn
, FALSE
);
1603 case AUTH_KEY_ID_CERT_SERIAL
:
1604 *authKeySerialNumber
= object
;
1610 parser
->destroy(parser
);
1614 * Extracts an authorityInfoAcess location
1616 static void parse_authorityInfoAccess(chunk_t blob
, int level0
,
1617 chunk_t
*accessLocation
)
1619 asn1_parser_t
*parser
;
1622 int accessMethod
= OID_UNKNOWN
;
1624 parser
= asn1_parser_create(authInfoAccessObjects
, blob
);
1625 parser
->set_top_level(parser
, level0
);
1627 while (parser
->iterate(parser
, &objectID
, &object
))
1631 case AUTH_INFO_ACCESS_METHOD
:
1632 accessMethod
= asn1_known_oid(object
);
1634 case AUTH_INFO_ACCESS_LOCATION
:
1636 switch (accessMethod
)
1639 if (*object
.ptr
== ASN1_CONTEXT_S_6
)
1641 if (asn1_length(&object
) == ASN1_INVALID_LENGTH
)
1646 DBG_log(" '%.*s'",(int)object
.len
, object
.ptr
)
1649 /* only HTTP(S) URIs accepted */
1650 if (strncasecmp(object
.ptr
, "http", 4) == 0)
1652 *accessLocation
= object
;
1656 plog("warning: ignoring OCSP InfoAccessLocation with unkown protocol");
1659 /* unkown accessMethod, ignoring */
1670 parser
->destroy(parser
);
1674 * Extracts extendedKeyUsage OIDs
1676 static bool parse_extendedKeyUsage(chunk_t blob
, int level0
)
1678 asn1_parser_t
*parser
;
1681 bool ocsp_signing
= FALSE
;
1683 parser
= asn1_parser_create(extendedKeyUsageObjects
, blob
);
1684 parser
->set_top_level(parser
, level0
);
1686 while (parser
->iterate(parser
, &objectID
, &object
))
1688 if (objectID
== EXT_KEY_USAGE_PURPOSE_ID
1689 && asn1_known_oid(object
) == OID_OCSP_SIGNING
)
1691 ocsp_signing
= TRUE
;
1694 parser
->destroy(parser
);
1696 return ocsp_signing
;
1700 * Extracts one or several crlDistributionPoints
1701 * and puts them into a chained list
1703 static generalName_t
* parse_crlDistributionPoints(chunk_t blob
, int level0
)
1705 asn1_parser_t
*parser
;
1709 generalName_t
*top_gn
= NULL
; /* top of the chained list */
1710 generalName_t
**tail_gn
= &top_gn
; /* tail of the chained list */
1712 parser
= asn1_parser_create(crlDistributionPointsObjects
, blob
);
1713 parser
->set_top_level(parser
, level0
);
1715 while (parser
->iterate(parser
, &objectID
, &object
))
1717 if (objectID
== CRL_DIST_POINTS_FULLNAME
)
1721 gn
= parse_generalNames(object
, parser
->get_level(parser
)+1, TRUE
);
1722 /* append extracted generalNames to existing chained list */
1724 /* find new tail of the chained list */
1727 tail_gn
= &gn
->next
; gn
= gn
->next
;
1731 parser
->destroy(parser
);
1737 * Parses an X.509v3 certificate
1739 bool parse_x509cert(chunk_t blob
, u_int level0
, x509cert_t
*cert
)
1741 u_char buf
[BUF_LEN
];
1742 asn1_parser_t
*parser
;
1745 int extn_oid
= OID_UNKNOWN
;
1747 bool success
= FALSE
;
1749 parser
= asn1_parser_create(certObjects
, blob
);
1750 parser
->set_top_level(parser
, level0
);
1752 while (parser
->iterate(parser
, &objectID
, &object
))
1754 u_int level
= parser
->get_level(parser
) + 1;
1757 case X509_OBJ_CERTIFICATE
:
1758 cert
->certificate
= object
;
1760 case X509_OBJ_TBS_CERTIFICATE
:
1761 cert
->tbsCertificate
= object
;
1763 case X509_OBJ_VERSION
:
1764 cert
->version
= (object
.len
) ?
(1+(u_int
)*object
.ptr
) : 1;
1766 DBG_log(" v%d", cert
->version
);
1769 case X509_OBJ_SERIAL_NUMBER
:
1770 cert
->serialNumber
= object
;
1772 case X509_OBJ_SIG_ALG
:
1773 cert
->sigAlg
= asn1_parse_algorithmIdentifier(object
, level
, NULL
);
1775 case X509_OBJ_ISSUER
:
1776 cert
->issuer
= object
;
1778 dntoa(buf
, BUF_LEN
, object
);
1779 DBG_log(" '%s'",buf
)
1782 case X509_OBJ_NOT_BEFORE
:
1783 cert
->notBefore
= asn1_parse_time(object
, level
);
1785 case X509_OBJ_NOT_AFTER
:
1786 cert
->notAfter
= asn1_parse_time(object
, level
);
1788 case X509_OBJ_SUBJECT
:
1789 cert
->subject
= object
;
1791 dntoa(buf
, BUF_LEN
, object
);
1792 DBG_log(" '%s'",buf
)
1795 case X509_OBJ_SUBJECT_PUBLIC_KEY_INFO
:
1796 cert
->public_key
= lib
->creds
->create(lib
->creds
, CRED_PUBLIC_KEY
,
1797 KEY_ANY
, BUILD_BLOB_ASN1_DER
, object
, BUILD_END
);
1798 if (cert
->public_key
== NULL
)
1803 case X509_OBJ_EXTN_ID
:
1804 extn_oid
= asn1_known_oid(object
);
1806 case X509_OBJ_CRITICAL
:
1807 critical
= object
.len
&& *object
.ptr
;
1809 DBG_log(" %s",(critical
)?
"TRUE":"FALSE");
1812 case X509_OBJ_EXTN_VALUE
:
1815 case OID_SUBJECT_KEY_ID
:
1816 if (!asn1_parse_simple_object(&object
, ASN1_OCTET_STRING
,
1817 level
, "keyIdentifier"))
1821 cert
->subjectKeyID
= object
;
1823 case OID_SUBJECT_ALT_NAME
:
1824 cert
->subjectAltName
=
1825 parse_generalNames(object
, level
, FALSE
);
1827 case OID_BASIC_CONSTRAINTS
:
1829 parse_basicConstraints(object
, level
);
1831 case OID_CRL_DISTRIBUTION_POINTS
:
1832 cert
->crlDistributionPoints
=
1833 parse_crlDistributionPoints(object
, level
);
1835 case OID_AUTHORITY_KEY_ID
:
1836 parse_authorityKeyIdentifier(object
, level
1837 , &cert
->authKeyID
, &cert
->authKeySerialNumber
);
1839 case OID_AUTHORITY_INFO_ACCESS
:
1840 parse_authorityInfoAccess(object
, level
, &cert
->accessLocation
);
1842 case OID_EXTENDED_KEY_USAGE
:
1843 cert
->isOcspSigner
= parse_extendedKeyUsage(object
, level
);
1845 case OID_NS_REVOCATION_URL
:
1846 case OID_NS_CA_REVOCATION_URL
:
1847 case OID_NS_CA_POLICY_URL
:
1848 case OID_NS_COMMENT
:
1849 if (!asn1_parse_simple_object(&object
, ASN1_IA5STRING
1850 , level
, oid_names
[extn_oid
].name
))
1860 case X509_OBJ_ALGORITHM
:
1861 cert
->algorithm
= asn1_parse_algorithmIdentifier(object
, level
, NULL
);
1863 case X509_OBJ_SIGNATURE
:
1864 cert
->signature
= object
;
1870 success
= parser
->success(parser
);
1871 time(&cert
->installed
);
1874 parser
->destroy(parser
);
1879 * Verify the validity of a certificate by
1880 * checking the notBefore and notAfter dates
1882 err_t
check_validity(const x509cert_t
*cert
, time_t *until
)
1884 time_t current_time
;
1886 time(¤t_time
);
1887 DBG(DBG_CONTROL
| DBG_PARSING
,
1888 DBG_log(" not before : %T", &cert
->notBefore
, TRUE
);
1889 DBG_log(" current time: %T", ¤t_time
, TRUE
);
1890 DBG_log(" not after : %T", &cert
->notAfter
, TRUE
);
1893 if (cert
->notAfter
< *until
)
1895 *until
= cert
->notAfter
;
1897 if (current_time
< cert
->notBefore
)
1899 return "certificate is not valid yet";
1901 if (current_time
> cert
->notAfter
)
1903 return "certificate has expired";
1912 * Verifies a X.509 certificate
1914 bool verify_x509cert(const x509cert_t
*cert
, bool strict
, time_t *until
)
1918 *until
= cert
->notAfter
;
1920 for (pathlen
= 0; pathlen
< MAX_CA_PATH_LEN
; pathlen
++)
1922 x509cert_t
*issuer_cert
;
1923 u_char buf
[BUF_LEN
];
1927 dntoa(buf
, BUF_LEN
, cert
->subject
);
1928 DBG_log("subject: '%s'",buf
);
1929 dntoa(buf
, BUF_LEN
, cert
->issuer
);
1930 DBG_log("issuer: '%s'",buf
);
1931 if (cert
->authKeyID
.ptr
!= NULL
)
1933 datatot(cert
->authKeyID
.ptr
, cert
->authKeyID
.len
, ':'
1935 DBG_log("authkey: %s", buf
);
1939 ugh
= check_validity(cert
, until
);
1948 DBG_log("certificate is valid")
1951 lock_authcert_list("verify_x509cert");
1952 issuer_cert
= get_authcert(cert
->issuer
, cert
->authKeySerialNumber
1953 , cert
->authKeyID
, AUTH_CA
);
1955 if (issuer_cert
== NULL
)
1957 plog("issuer cacert not found");
1958 unlock_authcert_list("verify_x509cert");
1962 DBG_log("issuer cacert found")
1965 if (!x509_check_signature(cert
->tbsCertificate
, cert
->signature
,
1966 cert
->algorithm
, issuer_cert
))
1968 plog("certificate signature is invalid");
1969 unlock_authcert_list("verify_x509cert");
1973 DBG_log("certificate signature is valid")
1975 unlock_authcert_list("verify_x509cert");
1977 /* check if cert is a self-signed root ca */
1978 if (pathlen
> 0 && same_dn(cert
->issuer
, cert
->subject
))
1981 DBG_log("reached self-signed root ca")
1987 time_t nextUpdate
= *until
;
1988 time_t revocationDate
= UNDEFINED_TIME
;
1989 crl_reason_t revocationReason
= REASON_UNSPECIFIED
;
1991 /* first check certificate revocation using ocsp */
1992 cert_status_t status
= verify_by_ocsp(cert
, &nextUpdate
1993 , &revocationDate
, &revocationReason
);
1995 /* if ocsp service is not available then fall back to crl */
1996 if ((status
== CERT_UNDEFINED
)
1997 || (status
== CERT_UNKNOWN
&& strict
))
1999 status
= verify_by_crl(cert
, &nextUpdate
, &revocationDate
2000 , &revocationReason
);
2006 /* if status information is stale */
2007 if (strict
&& nextUpdate
< time(NULL
))
2010 DBG_log("certificate is good but status is stale")
2012 remove_x509_public_key(cert
);
2016 DBG_log("certificate is good")
2019 /* with strict crl policy the public key must have the same
2020 * lifetime as the validity of the ocsp status or crl lifetime
2022 if (strict
&& nextUpdate
< *until
)
2024 *until
= nextUpdate
;
2028 plog("certificate was revoked on %T, reason: %N"
2029 , &revocationDate
, TRUE
2030 , crl_reason_names
, revocationReason
);
2031 remove_x509_public_key(cert
);
2034 case CERT_UNDEFINED
:
2036 plog("certificate status unknown");
2039 remove_x509_public_key(cert
);
2046 /* go up one step in the trust chain */
2049 plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN
);
2054 * List all X.509 certs in a chained list
2056 void list_x509cert_chain(const char *caption
, x509cert_t
* cert
,
2057 u_char auth_flags
, bool utc
)
2062 /* determine the current time */
2065 while (cert
!= NULL
)
2067 if (auth_flags
== AUTH_NONE
|| (auth_flags
& cert
->authority_flags
))
2069 u_char buf
[BUF_LEN
];
2070 public_key_t
*key
= cert
->public_key
;
2074 c
.type
= CERT_X509_SIGNATURE
;
2079 whack_log(RC_COMMENT
, " ");
2080 whack_log(RC_COMMENT
, "List of X.509 %s Certificates:", caption
);
2081 whack_log(RC_COMMENT
, " ");
2085 whack_log(RC_COMMENT
, "%T, count: %d", &cert
->installed
, utc
,
2087 dntoa(buf
, BUF_LEN
, cert
->subject
);
2088 whack_log(RC_COMMENT
, " subject: '%s'", buf
);
2089 dntoa(buf
, BUF_LEN
, cert
->issuer
);
2090 whack_log(RC_COMMENT
, " issuer: '%s'", buf
);
2091 datatot(cert
->serialNumber
.ptr
, cert
->serialNumber
.len
, ':',
2093 whack_log(RC_COMMENT
, " serial: %s", buf
);
2094 whack_log(RC_COMMENT
, " validity: not before %T %s",
2095 &cert
->notBefore
, utc
,
2096 (cert
->notBefore
< now
)?
"ok":"fatal (not valid yet)");
2097 whack_log(RC_COMMENT
, " not after %T %s",
2098 &cert
->notAfter
, utc
,
2099 check_expiry(cert
->notAfter
, CA_CERT_WARNING_INTERVAL
, TRUE
));
2100 whack_log(RC_COMMENT
, " pubkey: %N %4d bits%s",
2101 key_type_names
, key
->get_type(key
),
2102 key
->get_keysize(key
) * BITS_PER_BYTE
,
2103 cert
->smartcard ?
", on smartcard" :
2104 (has_private_key(c
)?
", has private key" : ""));
2105 if (key
->get_fingerprint(key
, KEY_ID_PUBKEY_INFO_SHA1
, &keyid
))
2107 whack_log(RC_COMMENT
, " keyid: %#B", &keyid
);
2109 if (cert
->subjectKeyID
.ptr
!= NULL
)
2111 datatot(cert
->subjectKeyID
.ptr
, cert
->subjectKeyID
.len
, ':',
2113 whack_log(RC_COMMENT
, " subjkey: %s", buf
);
2115 if (cert
->authKeyID
.ptr
!= NULL
)
2117 datatot(cert
->authKeyID
.ptr
, cert
->authKeyID
.len
, ':',
2119 whack_log(RC_COMMENT
, " authkey: %s", buf
);
2121 if (cert
->authKeySerialNumber
.ptr
!= NULL
)
2123 datatot(cert
->authKeySerialNumber
.ptr
,
2124 cert
->authKeySerialNumber
.len
, ':', buf
, BUF_LEN
);
2125 whack_log(RC_COMMENT
, " aserial: %s", buf
);
2133 * List all X.509 end certificates in a chained list
2135 void list_x509_end_certs(bool utc
)
2137 list_x509cert_chain("End", x509certs
, AUTH_NONE
, utc
);