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-2004 Andreas Steffen, Zuercher Hochschule Winterthur
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
17 * RCSID $Id: x509.c,v 1.35 2006/02/28 19:12:19 as Exp $
26 #include <sys/types.h>
29 #include <freeswan/ipsec_policy.h>
31 #include "constants.h"
49 /* chained lists of X.509 end certificates */
51 static x509cert_t
*x509certs
= NULL
;
53 /* ASN.1 definition of a basicConstraints extension */
55 static const asn1Object_t basicConstraintsObjects
[] = {
56 { 0, "basicConstraints", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
57 { 1, "CA", ASN1_BOOLEAN
, ASN1_DEF
|
59 { 1, "pathLenConstraint", ASN1_INTEGER
, ASN1_OPT
|
61 { 1, "end opt", ASN1_EOC
, ASN1_END
} /* 3 */
64 #define BASIC_CONSTRAINTS_CA 1
65 #define BASIC_CONSTRAINTS_ROOF 4
67 /* ASN.1 definition of time */
69 static const asn1Object_t timeObjects
[] = {
70 { 0, "utcTime", ASN1_UTCTIME
, ASN1_OPT
|
72 { 0, "end opt", ASN1_EOC
, ASN1_END
}, /* 1 */
73 { 0, "generalizeTime", ASN1_GENERALIZEDTIME
, ASN1_OPT
|
75 { 0, "end opt", ASN1_EOC
, ASN1_END
} /* 3 */
79 #define TIME_GENERALIZED 2
82 /* ASN.1 definition of a keyIdentifier */
84 static const asn1Object_t keyIdentifierObjects
[] = {
85 { 0, "keyIdentifier", ASN1_OCTET_STRING
, ASN1_BODY
} /* 0 */
88 /* ASN.1 definition of a authorityKeyIdentifier extension */
90 static const asn1Object_t authorityKeyIdentifierObjects
[] = {
91 { 0, "authorityKeyIdentifier", ASN1_SEQUENCE
, ASN1_NONE
}, /* 0 */
92 { 1, "keyIdentifier", ASN1_CONTEXT_S_0
, ASN1_OPT
|
94 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 2 */
95 { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1
, ASN1_OPT
|
97 { 1, "end opt", ASN1_EOC
, ASN1_END
}, /* 4 */
98 { 1, "authorityCertSerialNumber", ASN1_CONTEXT_S_2
, ASN1_OPT
|
100 { 1, "end opt", ASN1_EOC
, ASN1_END
} /* 6 */
103 #define AUTH_KEY_ID_KEY_ID 1
104 #define AUTH_KEY_ID_CERT_ISSUER 3
105 #define AUTH_KEY_ID_CERT_SERIAL 5
106 #define AUTH_KEY_ID_ROOF 7
108 /* ASN.1 definition of a authorityInfoAccess extension */
110 static const asn1Object_t authorityInfoAccessObjects
[] = {
111 { 0, "authorityInfoAccess", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
112 { 1, "accessDescription", ASN1_SEQUENCE
, ASN1_NONE
}, /* 1 */
113 { 2, "accessMethod", ASN1_OID
, ASN1_BODY
}, /* 2 */
114 { 2, "accessLocation", ASN1_EOC
, ASN1_RAW
}, /* 3 */
115 { 0, "end loop", ASN1_EOC
, ASN1_END
} /* 4 */
118 #define AUTH_INFO_ACCESS_METHOD 2
119 #define AUTH_INFO_ACCESS_LOCATION 3
120 #define AUTH_INFO_ACCESS_ROOF 5
122 /* ASN.1 definition of a extendedKeyUsage extension */
124 static const asn1Object_t extendedKeyUsageObjects
[] = {
125 { 0, "extendedKeyUsage", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
126 { 1, "keyPurposeID", ASN1_OID
, ASN1_BODY
}, /* 1 */
127 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 2 */
130 #define EXT_KEY_USAGE_PURPOSE_ID 1
131 #define EXT_KEY_USAGE_ROOF 3
133 /* ASN.1 definition of generalNames */
135 static const asn1Object_t generalNamesObjects
[] = {
136 { 0, "generalNames", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
137 { 1, "generalName", ASN1_EOC
, ASN1_RAW
}, /* 1 */
138 { 0, "end loop", ASN1_EOC
, ASN1_END
} /* 2 */
141 #define GENERAL_NAMES_GN 1
142 #define GENERAL_NAMES_ROOF 3
144 /* ASN.1 definition of generalName */
146 static const asn1Object_t generalNameObjects
[] = {
147 { 0, "otherName", ASN1_CONTEXT_C_0
, ASN1_OPT
|
149 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 1 */
150 { 0, "rfc822Name", ASN1_CONTEXT_S_1
, ASN1_OPT
|
152 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 3 */
153 { 0, "dnsName", ASN1_CONTEXT_S_2
, ASN1_OPT
|
155 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 5 */
156 { 0, "x400Address", ASN1_CONTEXT_S_3
, ASN1_OPT
|
158 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 7 */
159 { 0, "directoryName", ASN1_CONTEXT_C_4
, ASN1_OPT
|
161 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 9 */
162 { 0, "ediPartyName", ASN1_CONTEXT_C_5
, ASN1_OPT
|
163 ASN1_BODY
}, /* 10 */
164 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 11 */
165 { 0, "uniformResourceIdentifier", ASN1_CONTEXT_S_6
, ASN1_OPT
|
166 ASN1_BODY
}, /* 12 */
167 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 13 */
168 { 0, "ipAddress", ASN1_CONTEXT_S_7
, ASN1_OPT
|
169 ASN1_BODY
}, /* 14 */
170 { 0, "end choice", ASN1_EOC
, ASN1_END
}, /* 15 */
171 { 0, "registeredID", ASN1_CONTEXT_S_8
, ASN1_OPT
|
172 ASN1_BODY
}, /* 16 */
173 { 0, "end choice", ASN1_EOC
, ASN1_END
} /* 17 */
176 #define GN_OBJ_OTHER_NAME 0
177 #define GN_OBJ_RFC822_NAME 2
178 #define GN_OBJ_DNS_NAME 4
179 #define GN_OBJ_X400_ADDRESS 6
180 #define GN_OBJ_DIRECTORY_NAME 8
181 #define GN_OBJ_EDI_PARTY_NAME 10
182 #define GN_OBJ_URI 12
183 #define GN_OBJ_IP_ADDRESS 14
184 #define GN_OBJ_REGISTERED_ID 16
185 #define GN_OBJ_ROOF 18
187 /* ASN.1 definition of otherName */
189 static const asn1Object_t otherNameObjects
[] = {
190 {0, "type-id", ASN1_OID
, ASN1_BODY
}, /* 0 */
191 {0, "value", ASN1_CONTEXT_C_0
, ASN1_BODY
} /* 1 */
194 #define ON_OBJ_ID_TYPE 0
195 #define ON_OBJ_VALUE 1
196 #define ON_OBJ_ROOF 2
198 /* ASN.1 definition of crlDistributionPoints */
200 static const asn1Object_t crlDistributionPointsObjects
[] = {
201 { 0, "crlDistributionPoints", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 0 */
202 { 1, "DistributionPoint", ASN1_SEQUENCE
, ASN1_NONE
}, /* 1 */
203 { 2, "distributionPoint", ASN1_CONTEXT_C_0
, ASN1_OPT
|
205 { 3, "fullName", ASN1_CONTEXT_C_0
, ASN1_OPT
|
207 { 3, "end choice", ASN1_EOC
, ASN1_END
}, /* 4 */
208 { 3, "nameRelativeToCRLIssuer", ASN1_CONTEXT_C_1
, ASN1_OPT
|
210 { 3, "end choice", ASN1_EOC
, ASN1_END
}, /* 6 */
211 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 7 */
212 { 2, "reasons", ASN1_CONTEXT_C_1
, ASN1_OPT
|
214 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 9 */
215 { 2, "crlIssuer", ASN1_CONTEXT_C_2
, ASN1_OPT
|
216 ASN1_BODY
}, /* 10 */
217 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 11 */
218 { 0, "end loop", ASN1_EOC
, ASN1_END
}, /* 12 */
221 #define CRL_DIST_POINTS_FULLNAME 3
222 #define CRL_DIST_POINTS_ROOF 13
224 /* ASN.1 definition of an X.509v3 certificate */
226 static const asn1Object_t certObjects
[] = {
227 { 0, "certificate", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 0 */
228 { 1, "tbsCertificate", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 1 */
229 { 2, "DEFAULT v1", ASN1_CONTEXT_C_0
, ASN1_DEF
}, /* 2 */
230 { 3, "version", ASN1_INTEGER
, ASN1_BODY
}, /* 3 */
231 { 2, "serialNumber", ASN1_INTEGER
, ASN1_BODY
}, /* 4 */
232 { 2, "signature", ASN1_EOC
, ASN1_RAW
}, /* 5 */
233 { 2, "issuer", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 6 */
234 { 2, "validity", ASN1_SEQUENCE
, ASN1_NONE
}, /* 7 */
235 { 3, "notBefore", ASN1_EOC
, ASN1_RAW
}, /* 8 */
236 { 3, "notAfter", ASN1_EOC
, ASN1_RAW
}, /* 9 */
237 { 2, "subject", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 10 */
238 { 2, "subjectPublicKeyInfo", ASN1_SEQUENCE
, ASN1_NONE
}, /* 11 */
239 { 3, "algorithm", ASN1_EOC
, ASN1_RAW
}, /* 12 */
240 { 3, "subjectPublicKey", ASN1_BIT_STRING
, ASN1_NONE
}, /* 13 */
241 { 4, "RSAPublicKey", ASN1_SEQUENCE
, ASN1_OBJ
}, /* 14 */
242 { 5, "modulus", ASN1_INTEGER
, ASN1_BODY
}, /* 15 */
243 { 5, "publicExponent", ASN1_INTEGER
, ASN1_BODY
}, /* 16 */
244 { 2, "issuerUniqueID", ASN1_CONTEXT_C_1
, ASN1_OPT
}, /* 17 */
245 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 18 */
246 { 2, "subjectUniqueID", ASN1_CONTEXT_C_2
, ASN1_OPT
}, /* 19 */
247 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 20 */
248 { 2, "optional extensions", ASN1_CONTEXT_C_3
, ASN1_OPT
}, /* 21 */
249 { 3, "extensions", ASN1_SEQUENCE
, ASN1_LOOP
}, /* 22 */
250 { 4, "extension", ASN1_SEQUENCE
, ASN1_NONE
}, /* 23 */
251 { 5, "extnID", ASN1_OID
, ASN1_BODY
}, /* 24 */
252 { 5, "critical", ASN1_BOOLEAN
, ASN1_DEF
|
253 ASN1_BODY
}, /* 25 */
254 { 5, "extnValue", ASN1_OCTET_STRING
, ASN1_BODY
}, /* 26 */
255 { 3, "end loop", ASN1_EOC
, ASN1_END
}, /* 27 */
256 { 2, "end opt", ASN1_EOC
, ASN1_END
}, /* 28 */
257 { 1, "signatureAlgorithm", ASN1_EOC
, ASN1_RAW
}, /* 29 */
258 { 1, "signatureValue", ASN1_BIT_STRING
, ASN1_BODY
} /* 30 */
261 #define X509_OBJ_CERTIFICATE 0
262 #define X509_OBJ_TBS_CERTIFICATE 1
263 #define X509_OBJ_VERSION 3
264 #define X509_OBJ_SERIAL_NUMBER 4
265 #define X509_OBJ_SIG_ALG 5
266 #define X509_OBJ_ISSUER 6
267 #define X509_OBJ_NOT_BEFORE 8
268 #define X509_OBJ_NOT_AFTER 9
269 #define X509_OBJ_SUBJECT 10
270 #define X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM 12
271 #define X509_OBJ_SUBJECT_PUBLIC_KEY 13
272 #define X509_OBJ_RSA_PUBLIC_KEY 14
273 #define X509_OBJ_MODULUS 15
274 #define X509_OBJ_PUBLIC_EXPONENT 16
275 #define X509_OBJ_EXTN_ID 24
276 #define X509_OBJ_CRITICAL 25
277 #define X509_OBJ_EXTN_VALUE 26
278 #define X509_OBJ_ALGORITHM 29
279 #define X509_OBJ_SIGNATURE 30
280 #define X509_OBJ_ROOF 31
283 const x509cert_t empty_x509cert
= {
285 UNDEFINED_TIME
, /* installed */
287 FALSE
, /* smartcard */
288 AUTH_NONE
, /* authority_flags */
289 { NULL
, 0 } , /* certificate */
290 { NULL
, 0 } , /* tbsCertificate */
292 { NULL
, 0 } , /* serialNumber */
293 OID_UNKNOWN
, /* sigAlg */
294 { NULL
, 0 } , /* issuer */
298 { NULL
, 0 } , /* subject */
299 /* subjectPublicKeyInfo */
300 OID_UNKNOWN
, /* subjectPublicKeyAlgorithm */
301 { NULL
, 0 } , /* subjectPublicKey */
302 { NULL
, 0 } , /* modulus */
303 { NULL
, 0 } , /* publicExponent */
305 /* subjectUniqueID */
312 FALSE
, /* isOcspSigner */
313 { NULL
, 0 } , /* subjectKeyID */
314 { NULL
, 0 } , /* authKeyID */
315 { NULL
, 0 } , /* authKeySerialNumber */
316 { NULL
, 0 } , /* accessLocation */
317 NULL
, /* subjectAltName */
318 NULL
, /* crlDistributionPoints */
319 OID_UNKNOWN
, /* algorithm */
320 { NULL
, 0 } /* signature */
323 /* coding of X.501 distinguished name */
331 /* X.501 acronyms for well known object identifiers (OIDs) */
333 static u_char oid_ND
[] = {0x02, 0x82, 0x06, 0x01,
335 static u_char oid_UID
[] = {0x09, 0x92, 0x26, 0x89, 0x93,
336 0xF2, 0x2C, 0x64, 0x01, 0x01};
337 static u_char oid_DC
[] = {0x09, 0x92, 0x26, 0x89, 0x93,
338 0xF2, 0x2C, 0x64, 0x01, 0x19};
339 static u_char oid_CN
[] = {0x55, 0x04, 0x03};
340 static u_char oid_S
[] = {0x55, 0x04, 0x04};
341 static u_char oid_SN
[] = {0x55, 0x04, 0x05};
342 static u_char oid_C
[] = {0x55, 0x04, 0x06};
343 static u_char oid_L
[] = {0x55, 0x04, 0x07};
344 static u_char oid_ST
[] = {0x55, 0x04, 0x08};
345 static u_char oid_O
[] = {0x55, 0x04, 0x0A};
346 static u_char oid_OU
[] = {0x55, 0x04, 0x0B};
347 static u_char oid_T
[] = {0x55, 0x04, 0x0C};
348 static u_char oid_D
[] = {0x55, 0x04, 0x0D};
349 static u_char oid_N
[] = {0x55, 0x04, 0x29};
350 static u_char oid_G
[] = {0x55, 0x04, 0x2A};
351 static u_char oid_I
[] = {0x55, 0x04, 0x2B};
352 static u_char oid_ID
[] = {0x55, 0x04, 0x2D};
353 static u_char oid_E
[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
354 0x0D, 0x01, 0x09, 0x01};
355 static u_char oid_UN
[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
356 0x0D, 0x01, 0x09, 0x02};
357 static u_char oid_TCGID
[] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x89,
358 0x31, 0x01, 0x01, 0x02, 0x02, 0x4B};
360 static const x501rdn_t x501rdns
[] = {
361 {"ND" , {oid_ND
, 7}, ASN1_PRINTABLESTRING
},
362 {"UID" , {oid_UID
, 10}, ASN1_PRINTABLESTRING
},
363 {"DC" , {oid_DC
, 10}, ASN1_PRINTABLESTRING
},
364 {"CN" , {oid_CN
, 3}, ASN1_PRINTABLESTRING
},
365 {"S" , {oid_S
, 3}, ASN1_PRINTABLESTRING
},
366 {"SN" , {oid_SN
, 3}, ASN1_PRINTABLESTRING
},
367 {"serialNumber" , {oid_SN
, 3}, ASN1_PRINTABLESTRING
},
368 {"C" , {oid_C
, 3}, ASN1_PRINTABLESTRING
},
369 {"L" , {oid_L
, 3}, ASN1_PRINTABLESTRING
},
370 {"ST" , {oid_ST
, 3}, ASN1_PRINTABLESTRING
},
371 {"O" , {oid_O
, 3}, ASN1_PRINTABLESTRING
},
372 {"OU" , {oid_OU
, 3}, ASN1_PRINTABLESTRING
},
373 {"T" , {oid_T
, 3}, ASN1_PRINTABLESTRING
},
374 {"D" , {oid_D
, 3}, ASN1_PRINTABLESTRING
},
375 {"N" , {oid_N
, 3}, ASN1_PRINTABLESTRING
},
376 {"G" , {oid_G
, 3}, ASN1_PRINTABLESTRING
},
377 {"I" , {oid_I
, 3}, ASN1_PRINTABLESTRING
},
378 {"ID" , {oid_ID
, 3}, ASN1_PRINTABLESTRING
},
379 {"E" , {oid_E
, 9}, ASN1_IA5STRING
},
380 {"Email" , {oid_E
, 9}, ASN1_IA5STRING
},
381 {"emailAddress" , {oid_E
, 9}, ASN1_IA5STRING
},
382 {"UN" , {oid_UN
, 9}, ASN1_IA5STRING
},
383 {"unstructuredName", {oid_UN
, 9}, ASN1_IA5STRING
},
384 {"TCGID" , {oid_TCGID
, 12}, ASN1_PRINTABLESTRING
}
387 #define X501_RDN_ROOF 24
389 static u_char ASN1_subjectAltName_oid_str
[] = {
390 0x06, 0x03, 0x55, 0x1D, 0x11
393 static const chunk_t ASN1_subjectAltName_oid
= strchunk(ASN1_subjectAltName_oid_str
);
396 update_chunk(chunk_t
*ch
, int n
)
398 n
= (n
> -1 && n
< (int)ch
->len
)? n
: (int)ch
->len
-1;
399 ch
->ptr
+= n
; ch
->len
-= n
;
404 * Pointer is set to the first RDN in a DN
407 init_rdn(chunk_t dn
, chunk_t
*rdn
, chunk_t
*attribute
, bool *next
)
410 *attribute
= empty_chunk
;
412 /* a DN is a SEQUENCE OF RDNs */
414 if (*dn
.ptr
!= ASN1_SEQUENCE
)
416 return "DN is not a SEQUENCE";
419 rdn
->len
= asn1_length(&dn
);
421 if (rdn
->len
== ASN1_INVALID_LENGTH
)
422 return "Invalid RDN length";
426 /* are there any RDNs ? */
427 *next
= rdn
->len
> 0;
433 * Fetches the next RDN in a DN
436 get_next_rdn(chunk_t
*rdn
, chunk_t
* attribute
, chunk_t
*oid
, chunk_t
*value
437 , asn1_t
*type
, bool *next
)
441 /* initialize return values */
443 *value
= empty_chunk
;
445 /* if all attributes have been parsed, get next rdn */
446 if (attribute
->len
<= 0)
448 /* an RDN is a SET OF attributeTypeAndValue */
449 if (*rdn
->ptr
!= ASN1_SET
)
450 return "RDN is not a SET";
452 attribute
->len
= asn1_length(rdn
);
454 if (attribute
->len
== ASN1_INVALID_LENGTH
)
455 return "Invalid attribute length";
457 attribute
->ptr
= rdn
->ptr
;
459 /* advance to start of next RDN */
460 rdn
->ptr
+= attribute
->len
;
461 rdn
->len
-= attribute
->len
;
464 /* an attributeTypeAndValue is a SEQUENCE */
465 if (*attribute
->ptr
!= ASN1_SEQUENCE
)
466 return "attributeTypeAndValue is not a SEQUENCE";
468 /* extract the attribute body */
469 body
.len
= asn1_length(attribute
);
471 if (body
.len
== ASN1_INVALID_LENGTH
)
472 return "Invalid attribute body length";
474 body
.ptr
= attribute
->ptr
;
476 /* advance to start of next attribute */
477 attribute
->ptr
+= body
.len
;
478 attribute
->len
-= body
.len
;
480 /* attribute type is an OID */
481 if (*body
.ptr
!= ASN1_OID
)
482 return "attributeType is not an OID";
485 oid
->len
= asn1_length(&body
);
487 if (oid
->len
== ASN1_INVALID_LENGTH
)
488 return "Invalid attribute OID length";
492 /* advance to the attribute value */
493 body
.ptr
+= oid
->len
;
494 body
.len
-= oid
->len
;
496 /* extract string type */
499 /* extract string value */
500 value
->len
= asn1_length(&body
);
502 if (value
->len
== ASN1_INVALID_LENGTH
)
503 return "Invalid attribute string length";
505 value
->ptr
= body
.ptr
;
507 /* are there any RDNs left? */
508 *next
= rdn
->len
> 0 || attribute
->len
> 0;
514 * Parses an ASN.1 distinguished name int its OID/value pairs
517 dn_parse(chunk_t dn
, chunk_t
*str
)
519 chunk_t rdn
, oid
, attribute
, value
;
525 err_t ugh
= init_rdn(dn
, &rdn
, &attribute
, &next
);
527 if (ugh
!= NULL
) /* a parsing error has occured */
532 ugh
= get_next_rdn(&rdn
, &attribute
, &oid
, &value
, &type
, &next
);
534 if (ugh
!= NULL
) /* a parsing error has occured */
537 if (first
) /* first OID/value pair */
539 else /* separate OID/value pair by a comma */
540 update_chunk(str
, snprintf(str
->ptr
,str
->len
,", "));
543 oid_code
= known_oid(oid
);
544 if (oid_code
== OID_UNKNOWN
) /* OID not found in list */
547 update_chunk(str
, snprintf(str
->ptr
,str
->len
,"%s",
548 oid_names
[oid_code
].name
));
551 update_chunk(str
, snprintf(str
->ptr
,str
->len
,"=%.*s",
552 (int)value
.len
,value
.ptr
));
558 * Count the number of wildcard RDNs in a distinguished name
561 dn_count_wildcards(chunk_t dn
)
563 chunk_t rdn
, attribute
, oid
, value
;
568 err_t ugh
= init_rdn(dn
, &rdn
, &attribute
, &next
);
570 if (ugh
!= NULL
) /* a parsing error has occured */
575 ugh
= get_next_rdn(&rdn
, &attribute
, &oid
, &value
, &type
, &next
);
577 if (ugh
!= NULL
) /* a parsing error has occured */
579 if (value
.len
== 1 && *value
.ptr
== '*')
580 wildcards
++; /* we have found a wildcard RDN */
586 * Prints a binary string in hexadecimal form
589 hex_str(chunk_t bin
, chunk_t
*str
)
592 update_chunk(str
, snprintf(str
->ptr
,str
->len
,"0x"));
593 for (i
=0; i
< bin
.len
; i
++)
594 update_chunk(str
, snprintf(str
->ptr
,str
->len
,"%02X",*bin
.ptr
++));
598 /* Converts a binary DER-encoded ASN.1 distinguished name
599 * into LDAP-style human-readable ASCII format
602 dntoa(char *dst
, size_t dstlen
, chunk_t dn
)
609 ugh
= dn_parse(dn
, &str
);
611 if (ugh
!= NULL
) /* error, print DN as hex string */
614 DBG_log("error in DN parsing: %s", ugh
)
620 return (int)(dstlen
- str
.len
);
624 * Same as dntoa but prints a special string for a null dn
627 dntoa_or_null(char *dst
, size_t dstlen
, chunk_t dn
, const char* null_dn
)
630 return snprintf(dst
, dstlen
, "%s", null_dn
);
632 return dntoa(dst
, dstlen
, dn
);
635 /* Converts an LDAP-style human-readable ASCII-encoded
636 * ASN.1 distinguished name into binary DER-encoded format
639 atodn(char *src
, chunk_t
*dn
)
641 /* finite state machine for atodn */
651 u_char oid_len_buf
[3];
652 u_char name_len_buf
[3];
653 u_char rdn_seq_len_buf
[3];
654 u_char rdn_set_len_buf
[3];
655 u_char dn_seq_len_buf
[3];
657 chunk_t asn1_oid_len
= { oid_len_buf
, 0 };
658 chunk_t asn1_name_len
= { name_len_buf
, 0 };
659 chunk_t asn1_rdn_seq_len
= { rdn_seq_len_buf
, 0 };
660 chunk_t asn1_rdn_set_len
= { rdn_set_len_buf
, 0 };
661 chunk_t asn1_dn_seq_len
= { dn_seq_len_buf
, 0 };
662 chunk_t oid
= empty_chunk
;
663 chunk_t name
= empty_chunk
;
673 u_char
*dn_ptr
= dn
->ptr
+ 4;
675 state_t state
= SEARCH_OID
;
682 if (*src
!= ' ' && *src
!= '/' && *src
!= ',')
690 if (*src
!= ' ' && *src
!= '=')
694 for (pos
= 0; pos
< X501_RDN_ROOF
; pos
++)
696 if (strlen(x501rdns
[pos
].name
) == oid
.len
&&
697 strncasecmp(x501rdns
[pos
].name
, oid
.ptr
, oid
.len
) == 0)
698 break; /* found a valid OID */
700 if (pos
== X501_RDN_ROOF
)
702 ugh
= "unknown OID in distinguished name";
706 code_asn1_length(x501rdns
[pos
].oid
.len
, &asn1_oid_len
);
708 /* reset oid and change state */
714 if (*src
!= ' ' && *src
!= '=')
723 if (*src
!= ',' && *src
!= '/' && *src
!= '\0')
733 name
.len
-= whitespace
;
734 code_asn1_length(name
.len
, &asn1_name_len
);
736 /* compute the length of the relative distinguished name sequence */
737 rdn_seq_len
= 1 + asn1_oid_len
.len
+ x501rdns
[pos
].oid
.len
+
738 1 + asn1_name_len
.len
+ name
.len
;
739 code_asn1_length(rdn_seq_len
, &asn1_rdn_seq_len
);
741 /* compute the length of the relative distinguished name set */
742 rdn_set_len
= 1 + asn1_rdn_seq_len
.len
+ rdn_seq_len
;
743 code_asn1_length(rdn_set_len
, &asn1_rdn_set_len
);
745 /* encode the relative distinguished name */
746 *dn_ptr
++ = ASN1_SET
;
747 chunkcpy(dn_ptr
, asn1_rdn_set_len
);
748 *dn_ptr
++ = ASN1_SEQUENCE
;
749 chunkcpy(dn_ptr
, asn1_rdn_seq_len
);
750 *dn_ptr
++ = ASN1_OID
;
751 chunkcpy(dn_ptr
, asn1_oid_len
);
752 chunkcpy(dn_ptr
, x501rdns
[pos
].oid
);
753 /* encode the ASN.1 character string type of the name */
754 *dn_ptr
++ = (x501rdns
[pos
].type
== ASN1_PRINTABLESTRING
755 && !is_printablestring(name
))? ASN1_T61STRING
: x501rdns
[pos
].type
;
756 chunkcpy(dn_ptr
, asn1_name_len
);
757 chunkcpy(dn_ptr
, name
);
759 /* accumulate the length of the distinguished name sequence */
760 dn_seq_len
+= 1 + asn1_rdn_set_len
.len
+ rdn_set_len
;
762 /* reset name and change state */
770 } while (*src
++ != '\0');
772 /* complete the distinguished name sequence*/
773 code_asn1_length(dn_seq_len
, &asn1_dn_seq_len
);
774 dn
->ptr
+= 3 - asn1_dn_seq_len
.len
;
775 dn
->len
= 1 + asn1_dn_seq_len
.len
+ dn_seq_len
;
777 *dn_ptr
++ = ASN1_SEQUENCE
;
778 chunkcpy(dn_ptr
, asn1_dn_seq_len
);
782 /* compare two distinguished names by
783 * comparing the individual RDNs
786 same_dn(chunk_t a
, chunk_t b
)
788 chunk_t rdn_a
, rdn_b
, attribute_a
, attribute_b
;
789 chunk_t oid_a
, oid_b
, value_a
, value_b
;
790 asn1_t type_a
, type_b
;
793 /* same lengths for the DNs */
797 /* try a binary comparison first */
798 if (memcmp(a
.ptr
, b
.ptr
, b
.len
) == 0)
801 /* initialize DN parsing */
802 if (init_rdn(a
, &rdn_a
, &attribute_a
, &next_a
) != NULL
803 || init_rdn(b
, &rdn_b
, &attribute_b
, &next_b
) != NULL
)
806 /* fetch next RDN pair */
807 while (next_a
&& next_b
)
809 /* parse next RDNs and check for errors */
810 if (get_next_rdn(&rdn_a
, &attribute_a
, &oid_a
, &value_a
, &type_a
, &next_a
) != NULL
811 || get_next_rdn(&rdn_b
, &attribute_b
, &oid_b
, &value_b
, &type_b
, &next_b
) != NULL
)
816 /* OIDs must agree */
817 if (oid_a
.len
!= oid_b
.len
|| memcmp(oid_a
.ptr
, oid_b
.ptr
, oid_b
.len
) != 0)
820 /* same lengths for values */
821 if (value_a
.len
!= value_b
.len
)
824 /* printableStrings and email RDNs require uppercase comparison */
825 if (type_a
== type_b
&& (type_a
== ASN1_PRINTABLESTRING
||
826 (type_a
== ASN1_IA5STRING
&& known_oid(oid_a
) == OID_PKCS9_EMAIL
)))
828 if (strncasecmp(value_a
.ptr
, value_b
.ptr
, value_b
.len
) != 0)
833 if (strncmp(value_a
.ptr
, value_b
.ptr
, value_b
.len
) != 0)
837 /* both DNs must have same number of RDNs */
838 if (next_a
|| next_b
)
841 /* the two DNs are equal! */
846 /* compare two distinguished names by comparing the individual RDNs.
847 * A single'*' character designates a wildcard RDN in DN b.
850 match_dn(chunk_t a
, chunk_t b
, int *wildcards
)
852 chunk_t rdn_a
, rdn_b
, attribute_a
, attribute_b
;
853 chunk_t oid_a
, oid_b
, value_a
, value_b
;
854 asn1_t type_a
, type_b
;
857 /* initialize wildcard counter */
860 /* initialize DN parsing */
861 if (init_rdn(a
, &rdn_a
, &attribute_a
, &next_a
) != NULL
862 || init_rdn(b
, &rdn_b
, &attribute_b
, &next_b
) != NULL
)
865 /* fetch next RDN pair */
866 while (next_a
&& next_b
)
868 /* parse next RDNs and check for errors */
869 if (get_next_rdn(&rdn_a
, &attribute_a
, &oid_a
, &value_a
, &type_a
, &next_a
) != NULL
870 || get_next_rdn(&rdn_b
, &attribute_b
, &oid_b
, &value_b
, &type_b
, &next_b
) != NULL
)
875 /* OIDs must agree */
876 if (oid_a
.len
!= oid_b
.len
|| memcmp(oid_a
.ptr
, oid_b
.ptr
, oid_b
.len
) != 0)
879 /* does rdn_b contain a wildcard? */
880 if (value_b
.len
== 1 && *value_b
.ptr
== '*')
886 /* same lengths for values */
887 if (value_a
.len
!= value_b
.len
)
890 /* printableStrings and email RDNs require uppercase comparison */
891 if (type_a
== type_b
&& (type_a
== ASN1_PRINTABLESTRING
||
892 (type_a
== ASN1_IA5STRING
&& known_oid(oid_a
) == OID_PKCS9_EMAIL
)))
894 if (strncasecmp(value_a
.ptr
, value_b
.ptr
, value_b
.len
) != 0)
899 if (strncmp(value_a
.ptr
, value_b
.ptr
, value_b
.len
) != 0)
903 /* both DNs must have same number of RDNs */
904 if (next_a
|| next_b
)
907 /* the two DNs match! */
912 * compare two X.509 certificates by comparing their signatures
915 same_x509cert(const x509cert_t
*a
, const x509cert_t
*b
)
917 return same_chunk(a
->signature
, b
->signature
);
920 /* for each link pointing to the certificate
921 " increase the count by one
924 share_x509cert(x509cert_t
*cert
)
931 * add a X.509 user/host certificate to the chained list
934 add_x509cert(x509cert_t
*cert
)
936 x509cert_t
*c
= x509certs
;
940 if (same_x509cert(c
, cert
)) /* already in chain, free cert */
948 /* insert new cert at the root of the chain */
949 lock_certs_and_keys("add_x509cert");
950 cert
->next
= x509certs
;
952 DBG(DBG_CONTROL
| DBG_PARSING
,
953 DBG_log(" x509 cert inserted")
955 unlock_certs_and_keys("add_x509cert");
960 * choose either subject DN or a subjectAltName as connection end ID
963 select_x509cert_id(x509cert_t
*cert
, struct id
*end_id
)
965 bool copy_subject_dn
= TRUE
; /* ID is subject DN */
967 if (end_id
->kind
!= ID_NONE
) /* check for matching subjectAltName */
969 generalName_t
*gn
= cert
->subjectAltName
;
973 struct id id
= empty_id
;
976 if (same_id(&id
, end_id
))
978 copy_subject_dn
= FALSE
; /* take subjectAltName instead */
987 if (end_id
->kind
!= ID_NONE
&& end_id
->kind
!= ID_DER_ASN1_DN
)
991 idtoa(end_id
, buf
, BUF_LEN
);
992 plog(" no subjectAltName matches ID '%s', replaced by subject DN", buf
);
994 end_id
->kind
= ID_DER_ASN1_DN
;
995 end_id
->name
.len
= cert
->subject
.len
;
996 end_id
->name
.ptr
= temporary_cyclic_buffer();
997 memcpy(end_id
->name
.ptr
, cert
->subject
.ptr
, cert
->subject
.len
);
1002 * check for equality between two key identifiers
1005 same_keyid(chunk_t a
, chunk_t b
)
1007 if (a
.ptr
== NULL
|| b
.ptr
== NULL
)
1010 return same_chunk(a
, b
);
1014 * check for equality between two serial numbers
1017 same_serial(chunk_t a
, chunk_t b
)
1019 /* do not compare serial numbers if one of them is not defined */
1020 if (a
.ptr
== NULL
|| b
.ptr
== NULL
)
1023 return same_chunk(a
, b
);
1027 * get a X.509 certificate with a given issuer found at a certain position
1030 get_x509cert(chunk_t issuer
, chunk_t serial
, chunk_t keyid
, x509cert_t
*chain
)
1032 x509cert_t
*cert
= (chain
!= NULL
)? chain
->next
: x509certs
;
1034 while (cert
!= NULL
)
1036 if ((keyid
.ptr
!= NULL
) ? same_keyid(keyid
, cert
->authKeyID
)
1037 : (same_dn(issuer
, cert
->issuer
)
1038 && same_serial(serial
, cert
->authKeySerialNumber
)))
1048 * encode a linked list of subjectAltNames
1051 build_subjectAltNames(generalName_t
*subjectAltNames
)
1056 generalName_t
*gn
= subjectAltNames
;
1058 /* compute the total size of the ASN.1 attributes object */
1061 len
+= gn
->name
.len
;
1065 pos
= build_asn1_object(&names
, ASN1_SEQUENCE
, len
);
1067 gn
= subjectAltNames
;
1070 chunkcpy(pos
, gn
->name
);
1074 return asn1_wrap(ASN1_SEQUENCE
, "cm"
1075 , ASN1_subjectAltName_oid
1076 , asn1_wrap(ASN1_OCTET_STRING
, "m", names
));
1080 * build a to-be-signed X.509 certificate body
1083 build_tbs_x509cert(x509cert_t
*cert
, const RSA_public_key_t
*rsa
)
1085 /* version is always X.509v3 */
1086 chunk_t version
= asn1_simple_object(ASN1_CONTEXT_C_0
, ASN1_INTEGER_2
);
1088 chunk_t extensions
= empty_chunk
;
1090 if (cert
->subjectAltName
!= NULL
)
1092 extensions
= asn1_wrap(ASN1_CONTEXT_C_3
, "m"
1093 , asn1_wrap(ASN1_SEQUENCE
, "m"
1094 , build_subjectAltNames(cert
->subjectAltName
)));
1097 return asn1_wrap(ASN1_SEQUENCE
, "mmccmcmm"
1099 , asn1_simple_object(ASN1_INTEGER
, cert
->serialNumber
)
1100 , asn1_algorithmIdentifier(cert
->sigAlg
)
1102 , asn1_wrap(ASN1_SEQUENCE
, "mm"
1103 , timetoasn1(&cert
->notBefore
, ASN1_UTCTIME
)
1104 , timetoasn1(&cert
->notAfter
, ASN1_UTCTIME
)
1107 , pkcs1_build_publicKeyInfo(rsa
)
1113 * build a DER-encoded X.509 certificate
1116 build_x509cert(x509cert_t
*cert
, const RSA_public_key_t
*cert_key
1117 , const RSA_private_key_t
*signer_key
)
1119 chunk_t tbs_cert
= build_tbs_x509cert(cert
, cert_key
);
1121 chunk_t signature
= pkcs1_build_signature(tbs_cert
, cert
->sigAlg
1122 , signer_key
, TRUE
);
1124 cert
->certificate
= asn1_wrap(ASN1_SEQUENCE
, "mcm"
1126 , asn1_algorithmIdentifier(cert
->sigAlg
)
1131 * free the dynamic memory used to store generalNames
1134 free_generalNames(generalName_t
* gn
, bool free_name
)
1138 generalName_t
*gn_top
= gn
;
1141 pfree(gn
->name
.ptr
);
1149 * free a X.509 certificate
1152 free_x509cert(x509cert_t
*cert
)
1156 free_generalNames(cert
->subjectAltName
, FALSE
);
1157 free_generalNames(cert
->crlDistributionPoints
, FALSE
);
1158 pfreeany(cert
->certificate
.ptr
);
1164 /* release of a certificate decreases the count by one
1165 " the certificate is freed when the counter reaches zero
1168 release_x509cert(x509cert_t
*cert
)
1170 if (cert
!= NULL
&& --cert
->count
== 0)
1172 x509cert_t
**pp
= &x509certs
;
1176 free_x509cert(cert
);
1182 * stores a chained list of end certs and CA certs
1185 store_x509certs(x509cert_t
**firstcert
, bool strict
)
1187 x509cert_t
*cacerts
= NULL
;
1188 x509cert_t
**pp
= firstcert
;
1190 /* first extract CA certs, discarding root CA certs */
1194 x509cert_t
*cert
= *pp
;
1200 /* we don't accept self-signed CA certs */
1201 if (same_dn(cert
->issuer
, cert
->subject
))
1203 plog("self-signed cacert rejected");
1204 free_x509cert(cert
);
1208 /* insertion into temporary chain of candidate CA certs */
1209 cert
->next
= cacerts
;
1217 /* now verify the candidate CA certs */
1219 while (cacerts
!= NULL
)
1221 x509cert_t
*cert
= cacerts
;
1223 cacerts
= cacerts
->next
;
1225 if (trust_authcert_candidate(cert
, cacerts
))
1227 add_authcert(cert
, AUTH_CA
);
1231 plog("intermediate cacert rejected");
1232 free_x509cert(cert
);
1236 /* now verify the end certificates */
1243 x509cert_t
*cert
= *pp
;
1245 if (verify_x509cert(cert
, strict
, &valid_until
))
1247 DBG(DBG_CONTROL
| DBG_PARSING
,
1248 DBG_log("public key validated")
1250 add_x509_public_key(cert
, valid_until
, DAL_SIGNED
);
1254 plog("X.509 certificate rejected");
1257 free_x509cert(cert
);
1262 * decrypts an RSA signature using the issuer's certificate
1265 decrypt_sig(chunk_t sig
, int alg
, const x509cert_t
*issuer_cert
,
1272 case OID_RSA_ENCRYPTION
:
1273 case OID_MD2_WITH_RSA
:
1274 case OID_MD5_WITH_RSA
:
1275 case OID_SHA1_WITH_RSA
:
1276 case OID_SHA1_WITH_RSA_OIW
:
1277 case OID_SHA256_WITH_RSA
:
1278 case OID_SHA384_WITH_RSA
:
1279 case OID_SHA512_WITH_RSA
:
1282 RSA_public_key_t rsa
;
1284 init_RSA_public_key(&rsa
, issuer_cert
->publicExponent
1285 , issuer_cert
->modulus
);
1287 /* decrypt the signature s = s^e mod n */
1288 n_to_mpz(s
, sig
.ptr
, sig
.len
);
1289 mpz_powm(s
, s
, &rsa
.e
, &rsa
.n
);
1291 /* convert back to bytes */
1292 decrypted
= mpz_to_n(s
, rsa
.k
);
1294 DBG_dump_chunk(" decrypted signature: ", decrypted
)
1297 /* copy the least significant bits of decrypted signature
1298 * into the digest string
1300 memcpy(digest
->ptr
, decrypted
.ptr
+ decrypted
.len
- digest
->len
,
1304 free_RSA_public_content(&rsa
);
1305 pfree(decrypted
.ptr
);
1316 * Check if a signature over binary blob is genuine
1319 check_signature(chunk_t tbs
, chunk_t sig
, int digest_alg
, int enc_alg
1320 , const x509cert_t
*issuer_cert
)
1322 u_char digest_buf
[MAX_DIGEST_LEN
];
1323 u_char decrypted_buf
[MAX_DIGEST_LEN
];
1324 chunk_t digest
= {digest_buf
, MAX_DIGEST_LEN
};
1325 chunk_t decrypted
= {decrypted_buf
, MAX_DIGEST_LEN
};
1328 if (digest_alg
!= OID_UNKNOWN
)
1329 DBG_log("signature digest algorithm: '%s'",oid_names
[digest_alg
].name
);
1331 DBG_log("unknown signature digest algorithm");
1334 if (!compute_digest(tbs
, digest_alg
, &digest
))
1336 plog(" digest algorithm not supported");
1341 DBG_dump_chunk(" digest:", digest
)
1344 decrypted
.len
= digest
.len
; /* we want the same digest length */
1347 if (enc_alg
!= OID_UNKNOWN
)
1348 DBG_log("signature encryption algorithm: '%s'",oid_names
[enc_alg
].name
);
1350 DBG_log("unknown signature encryption algorithm");
1353 if (!decrypt_sig(sig
, enc_alg
, issuer_cert
, &decrypted
))
1355 plog(" decryption algorithm not supported");
1359 /* check if digests are equal */
1360 return !memcmp(decrypted
.ptr
, digest
.ptr
, digest
.len
);
1364 * extracts the basicConstraints extension
1367 parse_basicConstraints(chunk_t blob
, int level0
)
1375 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1377 while (objectID
< BASIC_CONSTRAINTS_ROOF
) {
1379 if (!extract_object(basicConstraintsObjects
, &objectID
,
1380 &object
,&level
, &ctx
))
1383 if (objectID
== BASIC_CONSTRAINTS_CA
)
1385 isCA
= object
.len
&& *object
.ptr
;
1387 DBG_log(" %s",(isCA
)?"TRUE":"FALSE");
1396 * Converts a X.500 generalName into an ID
1399 gntoid(struct id
*id
, const generalName_t
*gn
)
1403 case GN_DNS_NAME
: /* ID type: ID_FQDN */
1405 id
->name
= gn
->name
;
1407 case GN_IP_ADDRESS
: /* ID type: ID_IPV4_ADDR */
1409 const struct af_info
*afi
= &af_inet4_info
;
1412 id
->kind
= afi
->id_addr
;
1413 ugh
= initaddr(gn
->name
.ptr
, gn
->name
.len
, afi
->af
, &id
->ip_addr
);
1416 case GN_RFC822_NAME
: /* ID type: ID_USER_FQDN */
1417 id
->kind
= ID_USER_FQDN
;
1418 id
->name
= gn
->name
;
1422 id
->name
= empty_chunk
;
1426 /* compute the subjectKeyIdentifier according to section 4.2.1.2 of RFC 3280
1427 * as the 160 bit SHA-1 hash of the public key
1430 compute_subjectKeyID(x509cert_t
*cert
, chunk_t subjectKeyID
)
1436 , cert
->subjectPublicKey
.ptr
1437 , cert
->subjectPublicKey
.len
);
1438 SHA1Final(subjectKeyID
.ptr
, &context
);
1439 subjectKeyID
.len
= SHA1_DIGEST_SIZE
;
1443 * extracts an otherName
1446 parse_otherName(chunk_t blob
, int level0
)
1452 int oid
= OID_UNKNOWN
;
1454 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1456 while (objectID
< ON_OBJ_ROOF
)
1458 if (!extract_object(otherNameObjects
, &objectID
, &object
, &level
, &ctx
))
1463 case ON_OBJ_ID_TYPE
:
1464 oid
= known_oid(object
);
1467 if (oid
== OID_XMPP_ADDR
)
1469 if (!parse_asn1_simple_object(&object
, ASN1_UTF8STRING
1470 , level
+ 1, "xmppAddr"))
1486 * extracts a generalName
1488 static generalName_t
*
1489 parse_generalName(chunk_t blob
, int level0
)
1491 u_char buf
[BUF_LEN
];
1497 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1499 while (objectID
< GN_OBJ_ROOF
)
1501 bool valid_gn
= FALSE
;
1503 if (!extract_object(generalNameObjects
, &objectID
, &object
, &level
, &ctx
))
1507 case GN_OBJ_RFC822_NAME
:
1508 case GN_OBJ_DNS_NAME
:
1511 DBG_log(" '%.*s'", (int)object
.len
, object
.ptr
);
1515 case GN_OBJ_DIRECTORY_NAME
:
1517 dntoa(buf
, BUF_LEN
, object
);
1518 DBG_log(" '%s'", buf
)
1522 case GN_OBJ_IP_ADDRESS
:
1524 DBG_log(" '%d.%d.%d.%d'", *object
.ptr
, *(object
.ptr
+1),
1525 *(object
.ptr
+2), *(object
.ptr
+3));
1529 case GN_OBJ_OTHER_NAME
:
1530 if (!parse_otherName(object
, level
+ 1))
1533 case GN_OBJ_X400_ADDRESS
:
1534 case GN_OBJ_EDI_PARTY_NAME
:
1535 case GN_OBJ_REGISTERED_ID
:
1543 generalName_t
*gn
= alloc_thing(generalName_t
, "generalName");
1544 gn
->kind
= (objectID
- GN_OBJ_OTHER_NAME
) / 2;
1556 * extracts one or several GNs and puts them into a chained list
1558 static generalName_t
*
1559 parse_generalNames(chunk_t blob
, int level0
, bool implicit
)
1566 generalName_t
*top_gn
= NULL
;
1568 asn1_init(&ctx
, blob
, level0
, implicit
, DBG_RAW
);
1570 while (objectID
< GENERAL_NAMES_ROOF
)
1572 if (!extract_object(generalNamesObjects
, &objectID
, &object
, &level
, &ctx
))
1575 if (objectID
== GENERAL_NAMES_GN
)
1577 generalName_t
*gn
= parse_generalName(object
, level
+1);
1590 * returns a directoryName
1592 chunk_t
get_directoryName(chunk_t blob
, int level
, bool implicit
)
1594 chunk_t name
= empty_chunk
;
1595 generalName_t
* gn
= parse_generalNames(blob
, level
, implicit
);
1597 if (gn
!= NULL
&& gn
->kind
== GN_DIRECTORY_NAME
)
1600 free_generalNames(gn
, FALSE
);
1606 * extracts and converts a UTCTIME or GENERALIZEDTIME object
1609 parse_time(chunk_t blob
, int level0
)
1616 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1618 while (objectID
< TIME_ROOF
)
1620 if (!extract_object(timeObjects
, &objectID
, &object
, &level
, &ctx
))
1621 return UNDEFINED_TIME
;
1623 if (objectID
== TIME_UTC
|| objectID
== TIME_GENERALIZED
)
1625 return asn1totime(&object
, (objectID
== TIME_UTC
)
1626 ? ASN1_UTCTIME
: ASN1_GENERALIZEDTIME
);
1630 return UNDEFINED_TIME
;
1634 * extracts a keyIdentifier
1637 parse_keyIdentifier(chunk_t blob
, int level0
, bool implicit
)
1644 asn1_init(&ctx
, blob
, level0
, implicit
, DBG_RAW
);
1646 extract_object(keyIdentifierObjects
, &objectID
, &object
, &level
, &ctx
);
1651 * extracts an authoritykeyIdentifier
1654 parse_authorityKeyIdentifier(chunk_t blob
, int level0
1655 , chunk_t
*authKeyID
, chunk_t
*authKeySerialNumber
)
1662 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1664 while (objectID
< AUTH_KEY_ID_ROOF
)
1666 if (!extract_object(authorityKeyIdentifierObjects
, &objectID
, &object
, &level
, &ctx
))
1670 case AUTH_KEY_ID_KEY_ID
:
1671 *authKeyID
= parse_keyIdentifier(object
, level
+1, TRUE
);
1673 case AUTH_KEY_ID_CERT_ISSUER
:
1675 generalName_t
* gn
= parse_generalNames(object
, level
+1, TRUE
);
1677 free_generalNames(gn
, FALSE
);
1680 case AUTH_KEY_ID_CERT_SERIAL
:
1681 *authKeySerialNumber
= object
;
1691 * extracts an authorityInfoAcess location
1694 parse_authorityInfoAccess(chunk_t blob
, int level0
, chunk_t
*accessLocation
)
1701 u_int accessMethod
= OID_UNKNOWN
;
1703 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1705 while (objectID
< AUTH_INFO_ACCESS_ROOF
)
1707 if (!extract_object(authorityInfoAccessObjects
, &objectID
, &object
, &level
, &ctx
))
1711 case AUTH_INFO_ACCESS_METHOD
:
1712 accessMethod
= known_oid(object
);
1714 case AUTH_INFO_ACCESS_LOCATION
:
1716 switch (accessMethod
)
1719 if (*object
.ptr
== ASN1_CONTEXT_S_6
)
1721 if (asn1_length(&object
) == ASN1_INVALID_LENGTH
)
1725 DBG_log(" '%.*s'",(int)object
.len
, object
.ptr
)
1728 /* only HTTP(S) URIs accepted */
1729 if (strncasecmp(object
.ptr
, "http", 4) == 0)
1731 *accessLocation
= object
;
1735 plog("warning: ignoring OCSP InfoAccessLocation with unkown protocol");
1738 /* unkown accessMethod, ignoring */
1752 * extracts extendedKeyUsage OIDs
1755 parse_extendedKeyUsage(chunk_t blob
, int level0
)
1762 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1764 while (objectID
< EXT_KEY_USAGE_ROOF
)
1766 if (!extract_object(extendedKeyUsageObjects
, &objectID
1767 , &object
, &level
, &ctx
))
1770 if (objectID
== EXT_KEY_USAGE_PURPOSE_ID
1771 && known_oid(object
) == OID_OCSP_SIGNING
)
1778 /* extracts one or several crlDistributionPoints and puts them into
1781 static generalName_t
*
1782 parse_crlDistributionPoints(chunk_t blob
, int level0
)
1789 generalName_t
*top_gn
= NULL
; /* top of the chained list */
1790 generalName_t
**tail_gn
= &top_gn
; /* tail of the chained list */
1792 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1794 while (objectID
< CRL_DIST_POINTS_ROOF
)
1796 if (!extract_object(crlDistributionPointsObjects
, &objectID
,
1797 &object
, &level
, &ctx
))
1800 if (objectID
== CRL_DIST_POINTS_FULLNAME
)
1802 generalName_t
*gn
= parse_generalNames(object
, level
+1, TRUE
);
1803 /* append extracted generalNames to existing chained list */
1805 /* find new tail of the chained list */
1808 tail_gn
= &gn
->next
; gn
= gn
->next
;
1818 * Parses an X.509v3 certificate
1821 parse_x509cert(chunk_t blob
, u_int level0
, x509cert_t
*cert
)
1823 u_char buf
[BUF_LEN
];
1828 u_int extn_oid
= OID_UNKNOWN
;
1831 asn1_init(&ctx
, blob
, level0
, FALSE
, DBG_RAW
);
1833 while (objectID
< X509_OBJ_ROOF
)
1835 if (!extract_object(certObjects
, &objectID
, &object
, &level
, &ctx
))
1838 /* those objects which will parsed further need the next higher level */
1842 case X509_OBJ_CERTIFICATE
:
1843 cert
->certificate
= object
;
1845 case X509_OBJ_TBS_CERTIFICATE
:
1846 cert
->tbsCertificate
= object
;
1848 case X509_OBJ_VERSION
:
1849 cert
->version
= (object
.len
) ? (1+(u_int
)*object
.ptr
) : 1;
1851 DBG_log(" v%d", cert
->version
);
1854 case X509_OBJ_SERIAL_NUMBER
:
1855 cert
->serialNumber
= object
;
1857 case X509_OBJ_SIG_ALG
:
1858 cert
->sigAlg
= parse_algorithmIdentifier(object
, level
, NULL
);
1860 case X509_OBJ_ISSUER
:
1861 cert
->issuer
= object
;
1863 dntoa(buf
, BUF_LEN
, object
);
1864 DBG_log(" '%s'",buf
)
1867 case X509_OBJ_NOT_BEFORE
:
1868 cert
->notBefore
= parse_time(object
, level
);
1870 case X509_OBJ_NOT_AFTER
:
1871 cert
->notAfter
= parse_time(object
, level
);
1873 case X509_OBJ_SUBJECT
:
1874 cert
->subject
= object
;
1876 dntoa(buf
, BUF_LEN
, object
);
1877 DBG_log(" '%s'",buf
)
1880 case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM
:
1881 if (parse_algorithmIdentifier(object
, level
, NULL
) == OID_RSA_ENCRYPTION
)
1882 cert
->subjectPublicKeyAlgorithm
= PUBKEY_ALG_RSA
;
1885 plog(" unsupported public key algorithm");
1889 case X509_OBJ_SUBJECT_PUBLIC_KEY
:
1890 if (ctx
.blobs
[4].len
> 0 && *ctx
.blobs
[4].ptr
== 0x00)
1892 /* skip initial bit string octet defining 0 unused bits */
1893 ctx
.blobs
[4].ptr
++; ctx
.blobs
[4].len
--;
1897 plog(" invalid RSA public key format");
1901 case X509_OBJ_RSA_PUBLIC_KEY
:
1902 cert
->subjectPublicKey
= object
;
1904 case X509_OBJ_MODULUS
:
1905 if (object
.len
< RSA_MIN_OCTETS
+ 1)
1907 plog(" " RSA_MIN_OCTETS_UGH
);
1910 if (object
.len
> RSA_MAX_OCTETS
+ (size_t)(*object
.ptr
== 0x00))
1912 plog(" " RSA_MAX_OCTETS_UGH
);
1915 cert
->modulus
= object
;
1917 case X509_OBJ_PUBLIC_EXPONENT
:
1918 cert
->publicExponent
= object
;
1920 case X509_OBJ_EXTN_ID
:
1921 extn_oid
= known_oid(object
);
1923 case X509_OBJ_CRITICAL
:
1924 critical
= object
.len
&& *object
.ptr
;
1926 DBG_log(" %s",(critical
)?"TRUE":"FALSE");
1929 case X509_OBJ_EXTN_VALUE
:
1932 case OID_SUBJECT_KEY_ID
:
1933 cert
->subjectKeyID
=
1934 parse_keyIdentifier(object
, level
, FALSE
);
1936 case OID_SUBJECT_ALT_NAME
:
1937 cert
->subjectAltName
=
1938 parse_generalNames(object
, level
, FALSE
);
1940 case OID_BASIC_CONSTRAINTS
:
1942 parse_basicConstraints(object
, level
);
1944 case OID_CRL_DISTRIBUTION_POINTS
:
1945 cert
->crlDistributionPoints
=
1946 parse_crlDistributionPoints(object
, level
);
1948 case OID_AUTHORITY_KEY_ID
:
1949 parse_authorityKeyIdentifier(object
, level
1950 , &cert
->authKeyID
, &cert
->authKeySerialNumber
);
1952 case OID_AUTHORITY_INFO_ACCESS
:
1953 parse_authorityInfoAccess(object
, level
, &cert
->accessLocation
);
1955 case OID_EXTENDED_KEY_USAGE
:
1956 cert
->isOcspSigner
= parse_extendedKeyUsage(object
, level
);
1958 case OID_NS_REVOCATION_URL
:
1959 case OID_NS_CA_REVOCATION_URL
:
1960 case OID_NS_CA_POLICY_URL
:
1961 case OID_NS_COMMENT
:
1962 if (!parse_asn1_simple_object(&object
, ASN1_IA5STRING
1963 , level
, oid_names
[extn_oid
].name
))
1973 case X509_OBJ_ALGORITHM
:
1974 cert
->algorithm
= parse_algorithmIdentifier(object
, level
, NULL
);
1976 case X509_OBJ_SIGNATURE
:
1977 cert
->signature
= object
;
1984 time(&cert
->installed
);
1988 /* verify the validity of a certificate by
1989 * checking the notBefore and notAfter dates
1992 check_validity(const x509cert_t
*cert
, time_t *until
)
1994 time_t current_time
;
1996 time(¤t_time
);
1997 DBG(DBG_CONTROL
| DBG_PARSING
,
1998 DBG_log(" not before : %s", timetoa(&cert
->notBefore
, TRUE
));
1999 DBG_log(" current time: %s", timetoa(¤t_time
, TRUE
));
2000 DBG_log(" not after : %s", timetoa(&cert
->notAfter
, TRUE
));
2003 if (cert
->notAfter
< *until
) *until
= cert
->notAfter
;
2005 if (current_time
< cert
->notBefore
)
2006 return "certificate is not valid yet";
2007 if (current_time
> cert
->notAfter
)
2008 return "certificate has expired";
2014 * verifies a X.509 certificate
2017 verify_x509cert(const x509cert_t
*cert
, bool strict
, time_t *until
)
2021 *until
= cert
->notAfter
;
2023 for (pathlen
= 0; pathlen
< MAX_CA_PATH_LEN
; pathlen
++)
2025 x509cert_t
*issuer_cert
;
2026 u_char buf
[BUF_LEN
];
2030 dntoa(buf
, BUF_LEN
, cert
->subject
);
2031 DBG_log("subject: '%s'",buf
);
2032 dntoa(buf
, BUF_LEN
, cert
->issuer
);
2033 DBG_log("issuer: '%s'",buf
);
2034 if (cert
->authKeyID
.ptr
!= NULL
)
2036 datatot(cert
->authKeyID
.ptr
, cert
->authKeyID
.len
, ':'
2038 DBG_log("authkey: %s", buf
);
2042 ugh
= check_validity(cert
, until
);
2051 DBG_log("certificate is valid")
2054 lock_authcert_list("verify_x509cert");
2055 issuer_cert
= get_authcert(cert
->issuer
, cert
->authKeySerialNumber
2056 , cert
->authKeyID
, AUTH_CA
);
2058 if (issuer_cert
== NULL
)
2060 plog("issuer cacert not found");
2061 unlock_authcert_list("verify_x509cert");
2065 DBG_log("issuer cacert found")
2068 if (!check_signature(cert
->tbsCertificate
, cert
->signature
2069 , cert
->algorithm
, cert
->algorithm
, issuer_cert
))
2071 plog("certificate signature is invalid");
2072 unlock_authcert_list("verify_x509cert");
2076 DBG_log("certificate signature is valid")
2078 unlock_authcert_list("verify_x509cert");
2080 /* check if cert is a self-signed root ca */
2081 if (pathlen
> 0 && same_dn(cert
->issuer
, cert
->subject
))
2084 DBG_log("reached self-signed root ca")
2090 time_t nextUpdate
= *until
;
2091 time_t revocationDate
= UNDEFINED_TIME
;
2092 crl_reason_t revocationReason
= REASON_UNSPECIFIED
;
2094 /* first check certificate revocation using ocsp */
2095 cert_status_t status
= verify_by_ocsp(cert
, &nextUpdate
2096 , &revocationDate
, &revocationReason
);
2098 /* if ocsp service is not available then fall back to crl */
2099 if ((status
== CERT_UNDEFINED
)
2100 || (status
== CERT_UNKNOWN
&& strict
))
2102 status
= verify_by_crl(cert
, &nextUpdate
, &revocationDate
2103 , &revocationReason
);
2109 /* if status information is stale */
2110 if (strict
&& nextUpdate
< time(NULL
))
2113 DBG_log("certificate is good but status is stale")
2115 remove_x509_public_key(cert
);
2119 DBG_log("certificate is good")
2122 /* with strict crl policy the public key must have the same
2123 * lifetime as the validity of the ocsp status or crl lifetime
2125 if (strict
&& nextUpdate
< *until
)
2126 *until
= nextUpdate
;
2129 plog("certificate was revoked on %s, reason: %s"
2130 , timetoa(&revocationDate
, TRUE
)
2131 , enum_name(&crl_reason_names
, revocationReason
));
2132 remove_x509_public_key(cert
);
2135 case CERT_UNDEFINED
:
2137 plog("certificate status unknown");
2140 remove_x509_public_key(cert
);
2147 /* go up one step in the trust chain */
2150 plog("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN
);
2155 * list all X.509 certs in a chained list
2158 list_x509cert_chain(const char *caption
, x509cert_t
* cert
, u_char auth_flags
2164 /* determine the current time */
2167 while (cert
!= NULL
)
2169 if (auth_flags
== AUTH_NONE
|| (auth_flags
& cert
->authority_flags
))
2172 char keyid
[KEYID_BUF
];
2173 u_char buf
[BUF_LEN
];
2176 c
.type
= CERT_X509_SIGNATURE
;
2181 whack_log(RC_COMMENT
, " ");
2182 whack_log(RC_COMMENT
, "List of X.509 %s Certificates:", caption
);
2183 whack_log(RC_COMMENT
, " ");
2187 whack_log(RC_COMMENT
, "%s, count: %d", timetoa(&cert
->installed
, utc
),
2189 dntoa(buf
, BUF_LEN
, cert
->subject
);
2190 whack_log(RC_COMMENT
, " subject: '%s'", buf
);
2191 dntoa(buf
, BUF_LEN
, cert
->issuer
);
2192 whack_log(RC_COMMENT
, " issuer: '%s'", buf
);
2193 datatot(cert
->serialNumber
.ptr
, cert
->serialNumber
.len
, ':'
2195 whack_log(RC_COMMENT
, " serial: %s", buf
);
2196 form_keyid(cert
->publicExponent
, cert
->modulus
, keyid
, &keysize
);
2197 whack_log(RC_COMMENT
, " pubkey: %4d RSA Key %s%s"
2199 , cert
->smartcard
? ", on smartcard" :
2200 (has_private_key(c
)? ", has private key" : ""));
2201 whack_log(RC_COMMENT
, " validity: not before %s %s",
2202 timetoa(&cert
->notBefore
, utc
),
2203 (cert
->notBefore
< now
)?"ok":"fatal (not valid yet)");
2204 whack_log(RC_COMMENT
, " not after %s %s",
2205 timetoa(&cert
->notAfter
, utc
),
2206 check_expiry(cert
->notAfter
, CA_CERT_WARNING_INTERVAL
, TRUE
));
2207 if (cert
->subjectKeyID
.ptr
!= NULL
)
2209 datatot(cert
->subjectKeyID
.ptr
, cert
->subjectKeyID
.len
, ':'
2211 whack_log(RC_COMMENT
, " subjkey: %s", buf
);
2213 if (cert
->authKeyID
.ptr
!= NULL
)
2215 datatot(cert
->authKeyID
.ptr
, cert
->authKeyID
.len
, ':'
2217 whack_log(RC_COMMENT
, " authkey: %s", buf
);
2219 if (cert
->authKeySerialNumber
.ptr
!= NULL
)
2221 datatot(cert
->authKeySerialNumber
.ptr
, cert
->authKeySerialNumber
.len
2222 , ':', buf
, BUF_LEN
);
2223 whack_log(RC_COMMENT
, " aserial: %s", buf
);
2231 * list all X.509 end certificates in a chained list
2234 list_x509_end_certs(bool utc
)
2236 list_x509cert_chain("End", x509certs
, AUTH_NONE
, utc
);