- fixed log-to-syslog behavior
[strongswan.git] / Source / lib / crypto / x509.c
1 /**
2 * @file x509.c
3 *
4 * @brief Implementation of x509_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2006 Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include <gmp.h>
24 #include <sys/stat.h>
25 #include <unistd.h>
26 #include <string.h>
27
28 #include "x509.h"
29
30 #include <daemon.h>
31 #include <asn1/asn1.h>
32 #include <asn1/oid.h>
33 #include <utils/logger_manager.h>
34
35 typedef const char *err_t; /* error message, or NULL for success */
36
37 #define chunkcpy(dst, chunk) { memcpy(dst, chunk.ptr, chunk.len); dst += chunk.len;}
38
39 #define BUF_LEN 512
40 #define RSA_MIN_OCTETS (512 / 8)
41 #define RSA_MIN_OCTETS_UGH "RSA modulus too small for security: less than 512 bits"
42 #define RSA_MAX_OCTETS (8192 / 8)
43 #define RSA_MAX_OCTETS_UGH "RSA modulus too large: more than 8192 bits"
44
45 logger_t *logger;
46
47 typedef enum generalNames_t generalNames_t;
48
49 /**
50 * Different kinds of generalNames
51 */
52 enum generalNames_t {
53 GN_OTHER_NAME = 0,
54 GN_RFC822_NAME = 1,
55 GN_DNS_NAME = 2,
56 GN_X400_ADDRESS = 3,
57 GN_DIRECTORY_NAME = 4,
58 GN_EDI_PARTY_NAME = 5,
59 GN_URI = 6,
60 GN_IP_ADDRESS = 7,
61 GN_REGISTERED_ID = 8,
62 };
63
64 typedef struct generalName_t generalName_t;
65
66 /**
67 * A generalName, chainable in a list
68 */
69 struct generalName_t {
70 generalName_t *next;
71 generalNames_t kind;
72 chunk_t name;
73 };
74
75 typedef struct private_x509_t private_x509_t;
76
77 /**
78 * Private data of a x509_t object.
79 */
80 struct private_x509_t {
81 /**
82 * Public interface for this certificate.
83 */
84 x509_t public;
85
86 time_t installed;
87 u_char authority_flags;
88 chunk_t x509;
89 chunk_t tbsCertificate;
90 u_int version;
91 chunk_t serialNumber;
92 /* signature */
93 int sigAlg;
94 chunk_t issuer;
95 /* validity */
96 time_t notBefore;
97 time_t notAfter;
98 chunk_t subject;
99 /* subjectPublicKeyInfo */
100 auth_method_t subjectPublicKeyAlgorithm;
101 chunk_t subjectPublicKey;
102 rsa_public_key_t *public_key;
103 /* issuerUniqueID */
104 /* subjectUniqueID */
105 /* v3 extensions */
106 /* extension */
107 /* extension */
108 /* extnID */
109 /* critical */
110 /* extnValue */
111 bool isCA;
112 bool isOcspSigner; /* ocsp */
113 chunk_t subjectKeyID;
114 chunk_t authKeyID;
115 chunk_t authKeySerialNumber;
116 chunk_t accessLocation; /* ocsp */
117 generalName_t *subjectAltName;
118 generalName_t *crlDistributionPoints;
119 /* signatureAlgorithm */
120 int algorithm;
121 chunk_t signature;
122 };
123
124 /**
125 * ASN.1 definition of a basicConstraints extension
126 */
127 static const asn1Object_t basicConstraintsObjects[] = {
128 { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
129 { 1, "CA", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 1 */
130 { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */
131 { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */
132 };
133 #define BASIC_CONSTRAINTS_CA 1
134 #define BASIC_CONSTRAINTS_ROOF 4
135
136 /**
137 * ASN.1 definition of time
138 */
139 static const asn1Object_t timeObjects[] = {
140 { 0, "utcTime", ASN1_UTCTIME, ASN1_OPT|ASN1_BODY }, /* 0 */
141 { 0, "end opt", ASN1_EOC, ASN1_END }, /* 1 */
142 { 0, "generalizeTime",ASN1_GENERALIZEDTIME, ASN1_OPT|ASN1_BODY }, /* 2 */
143 { 0, "end opt", ASN1_EOC, ASN1_END } /* 3 */
144 };
145 #define TIME_UTC 0
146 #define TIME_GENERALIZED 2
147 #define TIME_ROOF 4
148
149 /**
150 * ASN.1 definition of a keyIdentifier
151 */
152 static const asn1Object_t keyIdentifierObjects[] = {
153 { 0, "keyIdentifier", ASN1_OCTET_STRING, ASN1_BODY } /* 0 */
154 };
155
156 /**
157 * ASN.1 definition of a authorityKeyIdentifier extension
158 */
159 static const asn1Object_t authorityKeyIdentifierObjects[] = {
160 { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
161 { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_OBJ }, /* 1 */
162 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
163 { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */
164 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
165 { 1, "authorityCertSerialNumber",ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */
166 { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
167 };
168 #define AUTH_KEY_ID_KEY_ID 1
169 #define AUTH_KEY_ID_CERT_ISSUER 3
170 #define AUTH_KEY_ID_CERT_SERIAL 5
171 #define AUTH_KEY_ID_ROOF 7
172
173 /**
174 * ASN.1 definition of a authorityInfoAccess extension
175 */
176 static const asn1Object_t authorityInfoAccessObjects[] = {
177 { 0, "authorityInfoAccess", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
178 { 1, "accessDescription", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
179 { 2, "accessMethod", ASN1_OID, ASN1_BODY }, /* 2 */
180 { 2, "accessLocation", ASN1_EOC, ASN1_RAW }, /* 3 */
181 { 0, "end loop", ASN1_EOC, ASN1_END } /* 4 */
182 };
183 #define AUTH_INFO_ACCESS_METHOD 2
184 #define AUTH_INFO_ACCESS_LOCATION 3
185 #define AUTH_INFO_ACCESS_ROOF 5
186
187 /**
188 * ASN.1 definition of a extendedKeyUsage extension
189 */
190 static const asn1Object_t extendedKeyUsageObjects[] = {
191 { 0, "extendedKeyUsage", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
192 { 1, "keyPurposeID", ASN1_OID, ASN1_BODY }, /* 1 */
193 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
194 };
195
196 #define EXT_KEY_USAGE_PURPOSE_ID 1
197 #define EXT_KEY_USAGE_ROOF 3
198
199 /**
200 * ASN.1 definition of generalNames
201 */
202 static const asn1Object_t generalNamesObjects[] = {
203 { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
204 { 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */
205 { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
206 };
207 #define GENERAL_NAMES_GN 1
208 #define GENERAL_NAMES_ROOF 3
209
210 /**
211 * ASN.1 definition of generalName
212 */
213 static const asn1Object_t generalNameObjects[] = {
214 { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */
215 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
216 { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */
217 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
218 { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */
219 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
220 { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */
221 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
222 { 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT|ASN1_BODY }, /* 8 */
223 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
224 { 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT|ASN1_BODY }, /* 10 */
225 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
226 { 0, "URI", ASN1_CONTEXT_S_6, ASN1_OPT|ASN1_BODY }, /* 12 */
227 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */
228 { 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT|ASN1_BODY }, /* 14 */
229 { 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */
230 { 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT|ASN1_BODY }, /* 16 */
231 { 0, "end choice", ASN1_EOC, ASN1_END } /* 17 */
232 };
233 #define GN_OBJ_OTHER_NAME 0
234 #define GN_OBJ_RFC822_NAME 2
235 #define GN_OBJ_DNS_NAME 4
236 #define GN_OBJ_X400_ADDRESS 6
237 #define GN_OBJ_DIRECTORY_NAME 8
238 #define GN_OBJ_EDI_PARTY_NAME 10
239 #define GN_OBJ_URI 12
240 #define GN_OBJ_IP_ADDRESS 14
241 #define GN_OBJ_REGISTERED_ID 16
242 #define GN_OBJ_ROOF 18
243
244 /**
245 * ASN.1 definition of otherName
246 */
247 static const asn1Object_t otherNameObjects[] = {
248 {0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */
249 {0, "value", ASN1_CONTEXT_C_0, ASN1_BODY } /* 1 */
250 };
251 #define ON_OBJ_ID_TYPE 0
252 #define ON_OBJ_VALUE 1
253 #define ON_OBJ_ROOF 2
254
255 /**
256 * SN.1 definition of crlDistributionPoints
257 */
258 static const asn1Object_t crlDistributionPointsObjects[] = {
259 { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
260 { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
261 { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 2 */
262 { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */
263 { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
264 { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */
265 { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
266 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
267 { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */
268 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
269 { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_BODY }, /* 10 */
270 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
271 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
272 };
273 #define CRL_DIST_POINTS_FULLNAME 3
274 #define CRL_DIST_POINTS_ROOF 13
275
276 /**
277 * ASN.1 definition of an X.509v3 x509
278 */
279 static const asn1Object_t certObjects[] = {
280 { 0, "x509", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
281 { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
282 { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
283 { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
284 { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
285 { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */
286 { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
287 { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */
288 { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */
289 { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */
290 { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
291 { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
292 { 3, "algorithm", ASN1_EOC, ASN1_RAW }, /* 12 */
293 { 3, "subjectPublicKey", ASN1_BIT_STRING, ASN1_NONE }, /* 13 */
294 { 4, "RSAPublicKey", ASN1_SEQUENCE, ASN1_RAW }, /* 14 */
295 { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 15 */
296 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 16 */
297 { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 17 */
298 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 18 */
299 { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 19 */
300 { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
301 { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
302 { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
303 { 5, "critical", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 23 */
304 { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
305 { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
306 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
307 { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
308 { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 28 */
309 };
310 #define X509_OBJ_CERTIFICATE 0
311 #define X509_OBJ_TBS_CERTIFICATE 1
312 #define X509_OBJ_VERSION 3
313 #define X509_OBJ_SERIAL_NUMBER 4
314 #define X509_OBJ_SIG_ALG 5
315 #define X509_OBJ_ISSUER 6
316 #define X509_OBJ_NOT_BEFORE 8
317 #define X509_OBJ_NOT_AFTER 9
318 #define X509_OBJ_SUBJECT 10
319 #define X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM 12
320 #define X509_OBJ_SUBJECT_PUBLIC_KEY 13
321 #define X509_OBJ_RSA_PUBLIC_KEY 14
322 #define X509_OBJ_EXTN_ID 22
323 #define X509_OBJ_CRITICAL 23
324 #define X509_OBJ_EXTN_VALUE 24
325 #define X509_OBJ_ALGORITHM 27
326 #define X509_OBJ_SIGNATURE 28
327 #define X509_OBJ_ROOF 29
328
329
330
331 /**
332 * X.501 acronyms for well known object identifiers (OIDs)
333 */
334 static u_char oid_ND[] = {
335 0x02, 0x82, 0x06, 0x01,
336 0x0A, 0x07, 0x14
337 };
338 static u_char oid_UID[] = {
339 0x09, 0x92, 0x26, 0x89, 0x93,
340 0xF2, 0x2C, 0x64, 0x01, 0x01
341 };
342 static u_char oid_DC[] = {
343 0x09, 0x92, 0x26, 0x89, 0x93,
344 0xF2, 0x2C, 0x64, 0x01, 0x19
345 };
346 static u_char oid_CN[] = {
347 0x55, 0x04, 0x03
348 };
349 static u_char oid_S[] = {
350 0x55, 0x04, 0x04
351 };
352 static u_char oid_SN[] = {
353 0x55, 0x04, 0x05
354 };
355 static u_char oid_C[] = {
356 0x55, 0x04, 0x06
357 };
358 static u_char oid_L[] = {
359 0x55, 0x04, 0x07
360 };
361 static u_char oid_ST[] = {
362 0x55, 0x04, 0x08
363 };
364 static u_char oid_O[] = {
365 0x55, 0x04, 0x0A
366 };
367 static u_char oid_OU[] = {
368 0x55, 0x04, 0x0B
369 };
370 static u_char oid_T[] = {
371 0x55, 0x04, 0x0C
372 };
373 static u_char oid_D[] = {
374 0x55, 0x04, 0x0D
375 };
376 static u_char oid_N[] = {
377 0x55, 0x04, 0x29
378 };
379 static u_char oid_G[] = {
380 0x55, 0x04, 0x2A
381 };
382 static u_char oid_I[] = {
383 0x55, 0x04, 0x2B
384 };
385 static u_char oid_ID[] = {
386 0x55, 0x04, 0x2D
387 };
388 static u_char oid_E[] = {
389 0x2A, 0x86, 0x48, 0x86, 0xF7,
390 0x0D, 0x01, 0x09, 0x01
391 };
392 static u_char oid_UN[] = {
393 0x2A, 0x86, 0x48, 0x86, 0xF7,
394 0x0D, 0x01, 0x09, 0x02
395 };
396 static u_char oid_TCGID[] = {
397 0x2B, 0x06, 0x01, 0x04, 0x01, 0x89,
398 0x31, 0x01, 0x01, 0x02, 0x02, 0x4B
399 };
400
401 /**
402 * coding of X.501 distinguished name
403 */
404 typedef struct {
405 const u_char *name;
406 chunk_t oid;
407 u_char type;
408 } x501rdn_t;
409
410 static const x501rdn_t x501rdns[] = {
411 {"ND", {oid_ND, 7}, ASN1_PRINTABLESTRING},
412 {"UID", {oid_UID, 10}, ASN1_PRINTABLESTRING},
413 {"DC", {oid_DC, 10}, ASN1_PRINTABLESTRING},
414 {"CN", {oid_CN, 3}, ASN1_PRINTABLESTRING},
415 {"S", {oid_S, 3}, ASN1_PRINTABLESTRING},
416 {"SN", {oid_SN, 3}, ASN1_PRINTABLESTRING},
417 {"serialNumber", {oid_SN, 3}, ASN1_PRINTABLESTRING},
418 {"C", {oid_C, 3}, ASN1_PRINTABLESTRING},
419 {"L", {oid_L, 3}, ASN1_PRINTABLESTRING},
420 {"ST", {oid_ST, 3}, ASN1_PRINTABLESTRING},
421 {"O", {oid_O, 3}, ASN1_PRINTABLESTRING},
422 {"OU", {oid_OU, 3}, ASN1_PRINTABLESTRING},
423 {"T", {oid_T, 3}, ASN1_PRINTABLESTRING},
424 {"D", {oid_D, 3}, ASN1_PRINTABLESTRING},
425 {"N", {oid_N, 3}, ASN1_PRINTABLESTRING},
426 {"G", {oid_G, 3}, ASN1_PRINTABLESTRING},
427 {"I", {oid_I, 3}, ASN1_PRINTABLESTRING},
428 {"ID", {oid_ID, 3}, ASN1_PRINTABLESTRING},
429 {"E", {oid_E, 9}, ASN1_IA5STRING},
430 {"Email", {oid_E, 9}, ASN1_IA5STRING},
431 {"emailAddress", {oid_E, 9}, ASN1_IA5STRING},
432 {"UN", {oid_UN, 9}, ASN1_IA5STRING},
433 {"unstructuredName",{oid_UN, 9}, ASN1_IA5STRING},
434 {"TCGID", {oid_TCGID, 12}, ASN1_PRINTABLESTRING}
435 };
436
437 #define X501_RDN_ROOF 24
438
439 static u_char ASN1_subjectAltName_oid_str[] = {
440 0x06, 0x03, 0x55, 0x1D, 0x11
441 };
442
443 static const chunk_t ASN1_subjectAltName_oid = chunk_from_buf(ASN1_subjectAltName_oid_str);
444
445
446 static void update_chunk(chunk_t *ch, int n)
447 {
448 n = (n > -1 && n < (int)ch->len)? n : (int)ch->len-1;
449 ch->ptr += n; ch->len -= n;
450 }
451
452 /**
453 * Prints a binary string in hexadecimal form
454 */
455 void hex_str(chunk_t bin, chunk_t *str)
456 {
457 u_int i;
458 update_chunk(str, snprintf(str->ptr,str->len,"0x"));
459 for (i=0; i < bin.len; i++)
460 {
461 update_chunk(str, snprintf(str->ptr,str->len,"%02X",*bin.ptr++));
462 }
463 }
464
465 /**
466 * Pointer is set to the first RDN in a DN
467 */
468 static err_t init_rdn(chunk_t dn, chunk_t *rdn, chunk_t *attribute, bool *next)
469 {
470 *rdn = CHUNK_INITIALIZER;
471 *attribute = CHUNK_INITIALIZER;
472
473 /* a DN is a SEQUENCE OF RDNs */
474 if (*dn.ptr != ASN1_SEQUENCE)
475 {
476 return "DN is not a SEQUENCE";
477 }
478
479 rdn->len = asn1_length(&dn);
480
481 if (rdn->len == ASN1_INVALID_LENGTH)
482 return "Invalid RDN length";
483
484 rdn->ptr = dn.ptr;
485
486 /* are there any RDNs ? */
487 *next = rdn->len > 0;
488
489 return NULL;
490 }
491
492 /**
493 * Fetches the next RDN in a DN
494 */
495 static err_t get_next_rdn(chunk_t *rdn, chunk_t * attribute, chunk_t *oid, chunk_t *value, asn1_t *type, bool *next)
496 {
497 chunk_t body;
498
499 /* initialize return values */
500 *oid = CHUNK_INITIALIZER;
501 *value = CHUNK_INITIALIZER;
502
503 /* if all attributes have been parsed, get next rdn */
504 if (attribute->len <= 0)
505 {
506 /* an RDN is a SET OF attributeTypeAndValue */
507 if (*rdn->ptr != ASN1_SET)
508 {
509 return "RDN is not a SET";
510 }
511 attribute->len = asn1_length(rdn);
512 if (attribute->len == ASN1_INVALID_LENGTH)
513 {
514 return "Invalid attribute length";
515 }
516 attribute->ptr = rdn->ptr;
517 /* advance to start of next RDN */
518 rdn->ptr += attribute->len;
519 rdn->len -= attribute->len;
520 }
521
522 /* an attributeTypeAndValue is a SEQUENCE */
523 if (*attribute->ptr != ASN1_SEQUENCE)
524 {
525 return "attributeTypeAndValue is not a SEQUENCE";
526 }
527
528 /* extract the attribute body */
529 body.len = asn1_length(attribute);
530
531 if (body.len == ASN1_INVALID_LENGTH)
532 {
533 return "Invalid attribute body length";
534 }
535
536 body.ptr = attribute->ptr;
537
538 /* advance to start of next attribute */
539 attribute->ptr += body.len;
540 attribute->len -= body.len;
541
542 /* attribute type is an OID */
543 if (*body.ptr != ASN1_OID)
544 {
545 return "attributeType is not an OID";
546 }
547 /* extract OID */
548 oid->len = asn1_length(&body);
549
550 if (oid->len == ASN1_INVALID_LENGTH)
551 {
552 return "Invalid attribute OID length";
553 }
554 oid->ptr = body.ptr;
555
556 /* advance to the attribute value */
557 body.ptr += oid->len;
558 body.len -= oid->len;
559
560 /* extract string type */
561 *type = *body.ptr;
562
563 /* extract string value */
564 value->len = asn1_length(&body);
565
566 if (value->len == ASN1_INVALID_LENGTH)
567 {
568 return "Invalid attribute string length";
569 }
570 value->ptr = body.ptr;
571
572 /* are there any RDNs left? */
573 *next = rdn->len > 0 || attribute->len > 0;
574 return NULL;
575 }
576
577 /**
578 * Parses an ASN.1 distinguished name int its OID/value pairs
579 */
580 static err_t dn_parse(chunk_t dn, chunk_t *str)
581 {
582 chunk_t rdn, oid, attribute, value;
583 asn1_t type;
584 int oid_code;
585 bool next;
586 bool first = TRUE;
587
588 err_t ugh = init_rdn(dn, &rdn, &attribute, &next);
589
590 if (ugh != NULL)
591 {/* a parsing error has occured */
592 return ugh;
593 }
594
595 while (next)
596 {
597 ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
598
599 if (ugh != NULL)
600 { /* a parsing error has occured */
601 return ugh;
602 }
603
604 if (first)
605 { /* first OID/value pair */
606 first = FALSE;
607 }
608 else
609 { /* separate OID/value pair by a comma */
610 update_chunk(str, snprintf(str->ptr,str->len,", "));
611 }
612
613 /* print OID */
614 oid_code = known_oid(oid);
615 if (oid_code == OID_UNKNOWN)
616 { /* OID not found in list */
617 hex_str(oid, str);
618 }
619 else
620 {
621 update_chunk(str, snprintf(str->ptr,str->len,"%s", oid_names[oid_code].name));
622 }
623 /* print value */
624 update_chunk(str, snprintf(str->ptr,str->len,"=%.*s", (int)value.len,value.ptr));
625 }
626 return NULL;
627 }
628
629 /**
630 * Count the number of wildcard RDNs in a distinguished name
631 */
632 int dn_count_wildcards(chunk_t dn)
633 {
634 chunk_t rdn, attribute, oid, value;
635 asn1_t type;
636 bool next;
637 int wildcards = 0;
638
639 err_t ugh = init_rdn(dn, &rdn, &attribute, &next);
640
641 if (ugh != NULL)
642 { /* a parsing error has occured */
643 return -1;
644 }
645
646 while (next)
647 {
648 ugh = get_next_rdn(&rdn, &attribute, &oid, &value, &type, &next);
649 if (ugh != NULL)
650 {/* a parsing error has occured */
651 return -1;
652 }
653 if (value.len == 1 && *value.ptr == '*')
654 {
655 wildcards++; /* we have found a wildcard RDN */
656 }
657 }
658 return wildcards;
659 }
660
661
662 /**
663 * Converts a binary DER-encoded ASN.1 distinguished name
664 * into LDAP-style human-readable ASCII format
665 */
666 int dntoa(char *dst, size_t dstlen, chunk_t dn)
667 {
668 err_t ugh = NULL;
669 chunk_t str;
670
671 str.ptr = dst;
672 str.len = dstlen;
673 ugh = dn_parse(dn, &str);
674
675 if (ugh != NULL) /* error, print DN as hex string */
676 {
677 logger->log(logger, ERROR|LEVEL1, "error in DN parsing: %s", ugh);
678 str.ptr = dst;
679 str.len = dstlen;
680 hex_str(dn, &str);
681 }
682 return (int)(dstlen - str.len);
683 }
684
685 /**
686 * Same as dntoa but prints a special string for a null dn
687 */
688 int dntoa_or_null(char *dst, size_t dstlen, chunk_t dn, const char* null_dn)
689 {
690 if (dn.ptr == NULL)
691 {
692 return snprintf(dst, dstlen, "%s", null_dn);
693 }
694 else
695 {
696 return dntoa(dst, dstlen, dn);
697 }
698 }
699
700 /**
701 * Converts an LDAP-style human-readable ASCII-encoded
702 * ASN.1 distinguished name into binary DER-encoded format
703 */
704 err_t atodn(char *src, chunk_t *dn)
705 {
706 /* finite state machine for atodn */
707 typedef enum {
708 SEARCH_OID = 0,
709 READ_OID = 1,
710 SEARCH_NAME = 2,
711 READ_NAME = 3,
712 UNKNOWN_OID = 4
713 } state_t;
714
715 u_char oid_len_buf[3];
716 u_char name_len_buf[3];
717 u_char rdn_seq_len_buf[3];
718 u_char rdn_set_len_buf[3];
719 u_char dn_seq_len_buf[3];
720
721 chunk_t asn1_oid_len = { oid_len_buf, 0 };
722 chunk_t asn1_name_len = { name_len_buf, 0 };
723 chunk_t asn1_rdn_seq_len = { rdn_seq_len_buf, 0 };
724 chunk_t asn1_rdn_set_len = { rdn_set_len_buf, 0 };
725 chunk_t asn1_dn_seq_len = { dn_seq_len_buf, 0 };
726 chunk_t oid = CHUNK_INITIALIZER;
727 chunk_t name = CHUNK_INITIALIZER;
728
729 int whitespace = 0;
730 int rdn_seq_len = 0;
731 int rdn_set_len = 0;
732 int dn_seq_len = 0;
733 int pos = 0;
734
735 err_t ugh = NULL;
736
737 u_char *dn_ptr = dn->ptr + 4;
738
739 state_t state = SEARCH_OID;
740
741 do
742 {
743 switch (state)
744 {
745 case SEARCH_OID:
746 if (*src != ' ' && *src != '/' && *src != ',')
747 {
748 oid.ptr = src;
749 oid.len = 1;
750 state = READ_OID;
751 }
752 break;
753 case READ_OID:
754 if (*src != ' ' && *src != '=')
755 oid.len++;
756 else
757 {
758 for (pos = 0; pos < X501_RDN_ROOF; pos++)
759 {
760 if (strlen(x501rdns[pos].name) == oid.len &&
761 strncasecmp(x501rdns[pos].name, oid.ptr, oid.len) == 0)
762 {
763 break; /* found a valid OID */
764 }
765 }
766 if (pos == X501_RDN_ROOF)
767 {
768 ugh = "unknown OID in distinguished name";
769 state = UNKNOWN_OID;
770 break;
771 }
772 code_asn1_length(x501rdns[pos].oid.len, &asn1_oid_len);
773
774 /* reset oid and change state */
775 oid = CHUNK_INITIALIZER;
776 state = SEARCH_NAME;
777 }
778 break;
779 case SEARCH_NAME:
780 if (*src != ' ' && *src != '=')
781 {
782 name.ptr = src;
783 name.len = 1;
784 whitespace = 0;
785 state = READ_NAME;
786 }
787 break;
788 case READ_NAME:
789 if (*src != ',' && *src != '/' && *src != '\0')
790 {
791 name.len++;
792 if (*src == ' ')
793 whitespace++;
794 else
795 whitespace = 0;
796 }
797 else
798 {
799 name.len -= whitespace;
800 code_asn1_length(name.len, &asn1_name_len);
801
802 /* compute the length of the relative distinguished name sequence */
803 rdn_seq_len = 1 + asn1_oid_len.len + x501rdns[pos].oid.len +
804 1 + asn1_name_len.len + name.len;
805 code_asn1_length(rdn_seq_len, &asn1_rdn_seq_len);
806
807 /* compute the length of the relative distinguished name set */
808 rdn_set_len = 1 + asn1_rdn_seq_len.len + rdn_seq_len;
809 code_asn1_length(rdn_set_len, &asn1_rdn_set_len);
810
811 /* encode the relative distinguished name */
812 *dn_ptr++ = ASN1_SET;
813 chunkcpy(dn_ptr, asn1_rdn_set_len);
814 *dn_ptr++ = ASN1_SEQUENCE;
815 chunkcpy(dn_ptr, asn1_rdn_seq_len);
816 *dn_ptr++ = ASN1_OID;
817 chunkcpy(dn_ptr, asn1_oid_len);
818 chunkcpy(dn_ptr, x501rdns[pos].oid);
819 /* encode the ASN.1 character string type of the name */
820 *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
821 && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
822 chunkcpy(dn_ptr, asn1_name_len);
823 chunkcpy(dn_ptr, name);
824
825 /* accumulate the length of the distinguished name sequence */
826 dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
827
828 /* reset name and change state */
829 name = CHUNK_INITIALIZER;
830 state = SEARCH_OID;
831 }
832 break;
833 case UNKNOWN_OID:
834 break;
835 }
836 } while (*src++ != '\0');
837
838 /* complete the distinguished name sequence */
839 code_asn1_length(dn_seq_len, &asn1_dn_seq_len);
840 dn->ptr += 3 - asn1_dn_seq_len.len;
841 dn->len = 1 + asn1_dn_seq_len.len + dn_seq_len;
842 dn_ptr = dn->ptr;
843 *dn_ptr++ = ASN1_SEQUENCE;
844 chunkcpy(dn_ptr, asn1_dn_seq_len);
845 return ugh;
846 }
847
848 /**
849 * compare two distinguished names by
850 * comparing the individual RDNs
851 */
852 bool same_dn(chunk_t a, chunk_t b)
853 {
854 chunk_t rdn_a, rdn_b, attribute_a, attribute_b;
855 chunk_t oid_a, oid_b, value_a, value_b;
856 asn1_t type_a, type_b;
857 bool next_a, next_b;
858
859 /* same lengths for the DNs */
860 if (a.len != b.len)
861 {
862 return FALSE;
863 }
864 /* try a binary comparison first */
865 if (memcmp(a.ptr, b.ptr, b.len) == 0)
866 {
867 return TRUE;
868 }
869
870 /* initialize DN parsing */
871 if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != NULL ||
872 init_rdn(b, &rdn_b, &attribute_b, &next_b) != NULL)
873 {
874 return FALSE;
875 }
876
877 /* fetch next RDN pair */
878 while (next_a && next_b)
879 {
880 /* parse next RDNs and check for errors */
881 if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != NULL
882 || get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != NULL)
883 {
884 return FALSE;
885 }
886 /* OIDs must agree */
887 if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
888 {
889 return FALSE;
890 }
891 /* same lengths for values */
892 if (value_a.len != value_b.len)
893 {
894 return FALSE;
895 }
896 /* printableStrings and email RDNs require uppercase comparison */
897 if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
898 (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
899 {
900 if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
901 {
902 return FALSE;
903 }
904 }
905 else
906 {
907 if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
908 {
909 return FALSE;
910 }
911 }
912 }
913 /* both DNs must have same number of RDNs */
914 if (next_a || next_b)
915 return FALSE;
916
917 /* the two DNs are equal! */
918 return TRUE;
919 }
920
921
922 /**
923 * compare two distinguished names by comparing the individual RDNs.
924 * A single'*' character designates a wildcard RDN in DN b.
925 */
926 bool match_dn(chunk_t a, chunk_t b, int *wildcards)
927 {
928 chunk_t rdn_a, rdn_b, attribute_a, attribute_b;
929 chunk_t oid_a, oid_b, value_a, value_b;
930 asn1_t type_a, type_b;
931 bool next_a, next_b;
932
933 /* initialize wildcard counter */
934 *wildcards = 0;
935
936 /* initialize DN parsing */
937 if (init_rdn(a, &rdn_a, &attribute_a, &next_a) != NULL ||
938 init_rdn(b, &rdn_b, &attribute_b, &next_b) != NULL)
939 {
940 return FALSE;
941 }
942 /* fetch next RDN pair */
943 while (next_a && next_b)
944 {
945 /* parse next RDNs and check for errors */
946 if (get_next_rdn(&rdn_a, &attribute_a, &oid_a, &value_a, &type_a, &next_a) != NULL ||
947 get_next_rdn(&rdn_b, &attribute_b, &oid_b, &value_b, &type_b, &next_b) != NULL)
948 {
949 return FALSE;
950 }
951 /* OIDs must agree */
952 if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
953 {
954 return FALSE;
955 }
956 /* does rdn_b contain a wildcard? */
957 if (value_b.len == 1 && *value_b.ptr == '*')
958 {
959 (*wildcards)++;
960 continue;
961 }
962 /* same lengths for values */
963 if (value_a.len != value_b.len)
964 {
965 return FALSE;
966 }
967 /* printableStrings and email RDNs require uppercase comparison */
968 if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
969 (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
970 {
971 if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
972 {
973 return FALSE;
974 }
975 }
976 else
977 {
978 if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
979 {
980 return FALSE;
981 }
982 }
983 }
984 /* both DNs must have same number of RDNs */
985 if (next_a || next_b)
986 {
987 return FALSE;
988 }
989 /* the two DNs match! */
990 return TRUE;
991 }
992
993 /**
994 * compare two X.509 x509s by comparing their signatures
995 */
996 static bool equals(private_x509_t *this, private_x509_t *other)
997 {
998 return chunk_equals(this->signature, other->signature);
999 }
1000
1001 /**
1002 * encode a linked list of subjectAltNames
1003 */
1004 chunk_t build_subjectAltNames(generalName_t *subjectAltNames)
1005 {
1006 u_char *pos;
1007 chunk_t names;
1008 size_t len = 0;
1009 generalName_t *gn = subjectAltNames;
1010
1011 /* compute the total size of the ASN.1 attributes object */
1012 while (gn != NULL)
1013 {
1014 len += gn->name.len;
1015 gn = gn->next;
1016 }
1017
1018 pos = build_asn1_object(&names, ASN1_SEQUENCE, len);
1019
1020 gn = subjectAltNames;
1021 while (gn != NULL)
1022 {
1023 chunkcpy(pos, gn->name);
1024 gn = gn->next;
1025 }
1026
1027 return asn1_wrap(ASN1_SEQUENCE, "cm",
1028 ASN1_subjectAltName_oid,
1029 asn1_wrap(ASN1_OCTET_STRING, "m", names)
1030 );
1031 }
1032
1033 /**
1034 * free the dynamic memory used to store generalNames
1035 */
1036 void free_generalNames(generalName_t* gn, bool free_name)
1037 {
1038 while (gn != NULL)
1039 {
1040 generalName_t *gn_top = gn;
1041 if (free_name)
1042 {
1043 free(gn->name.ptr);
1044 }
1045 gn = gn->next;
1046 free(gn_top);
1047 }
1048 }
1049
1050 /**
1051 * extracts the basicConstraints extension
1052 */
1053 static bool parse_basicConstraints(chunk_t blob, int level0)
1054 {
1055 asn1_ctx_t ctx;
1056 chunk_t object;
1057 u_int level;
1058 int objectID = 0;
1059 bool isCA = FALSE;
1060
1061 asn1_init(&ctx, blob, level0, FALSE);
1062
1063 while (objectID < BASIC_CONSTRAINTS_ROOF) {
1064
1065 if (!extract_object(basicConstraintsObjects, &objectID, &object,&level, &ctx))
1066 {
1067 break;
1068 }
1069 if (objectID == BASIC_CONSTRAINTS_CA)
1070 {
1071 isCA = object.len && *object.ptr;
1072 logger->log(logger, RAW|LEVEL1, " %s", isCA ? "TRUE" : "FALSE");
1073 }
1074 objectID++;
1075 }
1076 return isCA;
1077 }
1078
1079 /**
1080 * extracts an otherName
1081 */
1082 static bool parse_otherName(chunk_t blob, int level0)
1083 {
1084 asn1_ctx_t ctx;
1085 chunk_t object;
1086 int objectID = 0;
1087 u_int level;
1088 int oid = OID_UNKNOWN;
1089
1090 asn1_init(&ctx, blob, level0, FALSE);
1091
1092 while (objectID < ON_OBJ_ROOF)
1093 {
1094 if (!extract_object(otherNameObjects, &objectID, &object, &level, &ctx))
1095 return FALSE;
1096
1097 switch (objectID)
1098 {
1099 case ON_OBJ_ID_TYPE:
1100 oid = known_oid(object);
1101 break;
1102 case ON_OBJ_VALUE:
1103 if (oid == OID_XMPP_ADDR)
1104 {
1105 if (!parse_asn1_simple_object(&object, ASN1_UTF8STRING, level + 1, "xmppAddr"))
1106 {
1107 return FALSE;
1108 }
1109 }
1110 break;
1111 default:
1112 break;
1113 }
1114 objectID++;
1115 }
1116 return TRUE;
1117 }
1118
1119
1120 /**
1121 * extracts a generalName
1122 */
1123 static generalName_t* parse_generalName(chunk_t blob, int level0)
1124 {
1125 asn1_ctx_t ctx;
1126 chunk_t object;
1127 int objectID = 0;
1128 u_int level;
1129
1130 asn1_init(&ctx, blob, level0, FALSE);
1131
1132 while (objectID < GN_OBJ_ROOF)
1133 {
1134 bool valid_gn = FALSE;
1135
1136 if (!extract_object(generalNameObjects, &objectID, &object, &level, &ctx))
1137 return NULL;
1138
1139 switch (objectID) {
1140 case GN_OBJ_RFC822_NAME:
1141 case GN_OBJ_DNS_NAME:
1142 case GN_OBJ_URI:
1143 logger->log(logger, RAW|LEVEL1, " '%.*s'", (int)object.len, object.ptr);
1144 valid_gn = TRUE;
1145 break;
1146 case GN_OBJ_DIRECTORY_NAME:
1147 valid_gn = TRUE;
1148 break;
1149 case GN_OBJ_IP_ADDRESS:
1150 logger->log(logger, RAW|LEVEL1, " '%d.%d.%d.%d'",
1151 *object.ptr, *(object.ptr+1),
1152 *(object.ptr+2), *(object.ptr+3));
1153 valid_gn = TRUE;
1154 break;
1155 case GN_OBJ_OTHER_NAME:
1156 if (!parse_otherName(object, level + 1))
1157 return NULL;
1158 break;
1159 case GN_OBJ_X400_ADDRESS:
1160 case GN_OBJ_EDI_PARTY_NAME:
1161 case GN_OBJ_REGISTERED_ID:
1162 break;
1163 default:
1164 break;
1165 }
1166
1167 if (valid_gn)
1168 {
1169 generalName_t *gn = malloc_thing(generalName_t);
1170 gn->kind = (objectID - GN_OBJ_OTHER_NAME) / 2;
1171 gn->name = object;
1172 gn->next = NULL;
1173 return gn;
1174 }
1175 objectID++;
1176 }
1177 return NULL;
1178 }
1179
1180 /**
1181 * extracts one or several GNs and puts them into a chained list
1182 */
1183 static generalName_t* parse_generalNames(chunk_t blob, int level0, bool implicit)
1184 {
1185 asn1_ctx_t ctx;
1186 chunk_t object;
1187 u_int level;
1188 int objectID = 0;
1189
1190 generalName_t *top_gn = NULL;
1191
1192 asn1_init(&ctx, blob, level0, implicit);
1193
1194 while (objectID < GENERAL_NAMES_ROOF)
1195 {
1196 if (!extract_object(generalNamesObjects, &objectID, &object, &level, &ctx))
1197 return NULL;
1198
1199 if (objectID == GENERAL_NAMES_GN)
1200 {
1201 generalName_t *gn = parse_generalName(object, level+1);
1202 if (gn != NULL)
1203 {
1204 gn->next = top_gn;
1205 top_gn = gn;
1206 }
1207 }
1208 objectID++;
1209 }
1210 return top_gn;
1211 }
1212
1213 /**
1214 * returns a directoryName
1215 */
1216 chunk_t get_directoryName(chunk_t blob, int level, bool implicit)
1217 {
1218 chunk_t name = CHUNK_INITIALIZER;
1219 generalName_t * gn = parse_generalNames(blob, level, implicit);
1220
1221 if (gn != NULL && gn->kind == GN_DIRECTORY_NAME)
1222 {
1223 name= gn->name;
1224 }
1225
1226 free_generalNames(gn, FALSE);
1227
1228 return name;
1229 }
1230
1231 /**
1232 * extracts and converts a UTCTIME or GENERALIZEDTIME object
1233 */
1234 time_t parse_time(chunk_t blob, int level0)
1235 {
1236 asn1_ctx_t ctx;
1237 chunk_t object;
1238 u_int level;
1239 int objectID = 0;
1240
1241 asn1_init(&ctx, blob, level0, FALSE);
1242
1243 while (objectID < TIME_ROOF)
1244 {
1245 if (!extract_object(timeObjects, &objectID, &object, &level, &ctx))
1246 return 0;
1247
1248 if (objectID == TIME_UTC || objectID == TIME_GENERALIZED)
1249 {
1250 return asn1totime(&object, (objectID == TIME_UTC)
1251 ? ASN1_UTCTIME : ASN1_GENERALIZEDTIME);
1252 }
1253 objectID++;
1254 }
1255 return 0;
1256 }
1257
1258 /**
1259 * extracts a keyIdentifier
1260 */
1261 static chunk_t parse_keyIdentifier(chunk_t blob, int level0, bool implicit)
1262 {
1263 asn1_ctx_t ctx;
1264 chunk_t object;
1265 u_int level;
1266 int objectID = 0;
1267
1268 asn1_init(&ctx, blob, level0, implicit);
1269
1270 extract_object(keyIdentifierObjects, &objectID, &object, &level, &ctx);
1271 return object;
1272 }
1273
1274 /**
1275 * extracts an authoritykeyIdentifier
1276 */
1277 void parse_authorityKeyIdentifier(chunk_t blob, int level0 , chunk_t *authKeyID, chunk_t *authKeySerialNumber)
1278 {
1279 asn1_ctx_t ctx;
1280 chunk_t object;
1281 u_int level;
1282 int objectID = 0;
1283
1284 asn1_init(&ctx, blob, level0, FALSE);
1285 while (objectID < AUTH_KEY_ID_ROOF)
1286 {
1287 if (!extract_object(authorityKeyIdentifierObjects, &objectID, &object, &level, &ctx))
1288 {
1289 return;
1290 }
1291 switch (objectID)
1292 {
1293 case AUTH_KEY_ID_KEY_ID:
1294 *authKeyID = parse_keyIdentifier(object, level+1, TRUE);
1295 break;
1296 case AUTH_KEY_ID_CERT_ISSUER:
1297 {
1298 generalName_t *gn = parse_generalNames(object, level+1, TRUE);
1299 free_generalNames(gn, FALSE);
1300 break;
1301 }
1302 case AUTH_KEY_ID_CERT_SERIAL:
1303 *authKeySerialNumber = object;
1304 break;
1305 default:
1306 break;
1307 }
1308 objectID++;
1309 }
1310 }
1311
1312 /**
1313 * extracts an authorityInfoAcess location
1314 */
1315 static void parse_authorityInfoAccess(chunk_t blob, int level0, chunk_t *accessLocation)
1316 {
1317 asn1_ctx_t ctx;
1318 chunk_t object;
1319 u_int level;
1320 int objectID = 0;
1321
1322 u_int accessMethod = OID_UNKNOWN;
1323
1324 asn1_init(&ctx, blob, level0, FALSE);
1325 while (objectID < AUTH_INFO_ACCESS_ROOF)
1326 {
1327 if (!extract_object(authorityInfoAccessObjects, &objectID, &object, &level, &ctx))
1328 {
1329 return;
1330 }
1331 switch (objectID)
1332 {
1333 case AUTH_INFO_ACCESS_METHOD:
1334 accessMethod = known_oid(object);
1335 break;
1336 case AUTH_INFO_ACCESS_LOCATION:
1337 {
1338 switch (accessMethod)
1339 {
1340 case OID_OCSP:
1341 if (*object.ptr == ASN1_CONTEXT_S_6)
1342 {
1343 if (asn1_length(&object) == ASN1_INVALID_LENGTH)
1344 {
1345 return;
1346 }
1347 logger->log(logger, RAW|LEVEL1, " '%.*s'",(int)object.len, object.ptr);
1348 /* only HTTP(S) URIs accepted */
1349 if (strncasecmp(object.ptr, "http", 4) == 0)
1350 {
1351 *accessLocation = object;
1352 return;
1353 }
1354 }
1355 logger->log(logger, ERROR|LEVEL2, "ignoring OCSP InfoAccessLocation with unkown protocol");
1356 break;
1357 default:
1358 /* unkown accessMethod, ignoring */
1359 break;
1360 }
1361 break;
1362 }
1363 default:
1364 break;
1365 }
1366 objectID++;
1367 }
1368 }
1369
1370 /**
1371 * extracts extendedKeyUsage OIDs
1372 */
1373 static bool parse_extendedKeyUsage(chunk_t blob, int level0)
1374 {
1375 asn1_ctx_t ctx;
1376 chunk_t object;
1377 u_int level;
1378 int objectID = 0;
1379
1380 asn1_init(&ctx, blob, level0, FALSE);
1381 while (objectID < EXT_KEY_USAGE_ROOF)
1382 {
1383 if (!extract_object(extendedKeyUsageObjects, &objectID, &object, &level, &ctx))
1384 {
1385 return FALSE;
1386 }
1387 if (objectID == EXT_KEY_USAGE_PURPOSE_ID &&
1388 known_oid(object) == OID_OCSP_SIGNING)
1389 {
1390 return TRUE;
1391 }
1392 objectID++;
1393 }
1394 return FALSE;
1395 }
1396
1397 /**
1398 * extracts one or several crlDistributionPoints and puts them into
1399 * a chained list
1400 */
1401 static generalName_t* parse_crlDistributionPoints(chunk_t blob, int level0)
1402 {
1403 asn1_ctx_t ctx;
1404 chunk_t object;
1405 u_int level;
1406 int objectID = 0;
1407
1408 generalName_t *top_gn = NULL; /* top of the chained list */
1409 generalName_t **tail_gn = &top_gn; /* tail of the chained list */
1410
1411 asn1_init(&ctx, blob, level0, FALSE);
1412 while (objectID < CRL_DIST_POINTS_ROOF)
1413 {
1414 if (!extract_object(crlDistributionPointsObjects, &objectID, &object, &level, &ctx))
1415 {
1416 return NULL;
1417 }
1418 if (objectID == CRL_DIST_POINTS_FULLNAME)
1419 {
1420 generalName_t *gn = parse_generalNames(object, level+1, TRUE);
1421 /* append extracted generalNames to existing chained list */
1422 *tail_gn = gn;
1423 /* find new tail of the chained list */
1424 while (gn != NULL)
1425 {
1426 tail_gn = &gn->next; gn = gn->next;
1427 }
1428 }
1429 objectID++;
1430 }
1431 return top_gn;
1432 }
1433
1434
1435 /**
1436 * Parses an X.509v3 x509
1437 */
1438 bool parse_x509cert(chunk_t blob, u_int level0, private_x509_t *cert)
1439 {
1440 u_char buf[BUF_LEN];
1441 asn1_ctx_t ctx;
1442 bool critical;
1443 chunk_t object;
1444 u_int level;
1445 u_int extn_oid = OID_UNKNOWN;
1446 int objectID = 0;
1447
1448 asn1_init(&ctx, blob, level0, FALSE);
1449 while (objectID < X509_OBJ_ROOF)
1450 {
1451 if (!extract_object(certObjects, &objectID, &object, &level, &ctx))
1452 {
1453 return FALSE;
1454 }
1455 /* those objects which will parsed further need the next higher level */
1456 level++;
1457 switch (objectID) {
1458 case X509_OBJ_CERTIFICATE:
1459 cert->x509 = object;
1460 break;
1461 case X509_OBJ_TBS_CERTIFICATE:
1462 cert->tbsCertificate = object;
1463 break;
1464 case X509_OBJ_VERSION:
1465 cert->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
1466 logger->log(logger, RAW|LEVEL1, " v%d", cert->version);
1467 break;
1468 case X509_OBJ_SERIAL_NUMBER:
1469 cert->serialNumber = object;
1470 break;
1471 case X509_OBJ_SIG_ALG:
1472 cert->sigAlg = parse_algorithmIdentifier(object, level, NULL);
1473 break;
1474 case X509_OBJ_ISSUER:
1475 cert->issuer = object;
1476 dntoa(buf, BUF_LEN, object);
1477 logger->log(logger, RAW|LEVEL1, " '%s'", buf);
1478 break;
1479 case X509_OBJ_NOT_BEFORE:
1480 cert->notBefore = parse_time(object, level);
1481 break;
1482 case X509_OBJ_NOT_AFTER:
1483 cert->notAfter = parse_time(object, level);
1484 break;
1485 case X509_OBJ_SUBJECT:
1486 cert->subject = object;
1487 dntoa(buf, BUF_LEN, object);
1488 logger->log(logger, RAW|LEVEL1, " '%s'", buf);
1489 break;
1490 case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM:
1491 if (parse_algorithmIdentifier(object, level, NULL) == OID_RSA_ENCRYPTION)
1492 {
1493 cert->subjectPublicKeyAlgorithm = RSA_DIGITAL_SIGNATURE;
1494 }
1495 else
1496 {
1497 logger->log(logger, ERROR|LEVEL1, " unsupported public key algorithm");
1498 return FALSE;
1499 }
1500 break;
1501 case X509_OBJ_SUBJECT_PUBLIC_KEY:
1502 if (ctx.blobs[4].len > 0 && *ctx.blobs[4].ptr == 0x00)
1503 {
1504 /* skip initial bit string octet defining 0 unused bits */
1505 ctx.blobs[4].ptr++; ctx.blobs[4].len--;
1506 }
1507 else
1508 {
1509 logger->log(logger, ERROR|LEVEL1, " invalid RSA public key format");
1510 return FALSE;
1511 }
1512 break;
1513 case X509_OBJ_RSA_PUBLIC_KEY:
1514 cert->subjectPublicKey = object;
1515 break;
1516 case X509_OBJ_EXTN_ID:
1517 extn_oid = known_oid(object);
1518 break;
1519 case X509_OBJ_CRITICAL:
1520 critical = object.len && *object.ptr;
1521 logger->log(logger, ERROR|LEVEL1, " %s", critical ? "TRUE" : "FALSE");
1522 break;
1523 case X509_OBJ_EXTN_VALUE:
1524 {
1525 switch (extn_oid) {
1526 case OID_SUBJECT_KEY_ID:
1527 cert->subjectKeyID = parse_keyIdentifier(object, level, FALSE);
1528 break;
1529 case OID_SUBJECT_ALT_NAME:
1530 cert->subjectAltName = parse_generalNames(object, level, FALSE);
1531 break;
1532 case OID_BASIC_CONSTRAINTS:
1533 cert->isCA = parse_basicConstraints(object, level);
1534 break;
1535 case OID_CRL_DISTRIBUTION_POINTS:
1536 cert->crlDistributionPoints = parse_crlDistributionPoints(object, level);
1537 break;
1538 case OID_AUTHORITY_KEY_ID:
1539 parse_authorityKeyIdentifier(object, level , &cert->authKeyID, &cert->authKeySerialNumber);
1540 break;
1541 case OID_AUTHORITY_INFO_ACCESS:
1542 parse_authorityInfoAccess(object, level, &cert->accessLocation);
1543 break;
1544 case OID_EXTENDED_KEY_USAGE:
1545 cert->isOcspSigner = parse_extendedKeyUsage(object, level);
1546 break;
1547 case OID_NS_REVOCATION_URL:
1548 case OID_NS_CA_REVOCATION_URL:
1549 case OID_NS_CA_POLICY_URL:
1550 case OID_NS_COMMENT:
1551 if (!parse_asn1_simple_object(&object, ASN1_IA5STRING , level, oid_names[extn_oid].name))
1552 {
1553 return FALSE;
1554 }
1555 break;
1556 default:
1557 break;
1558 }
1559 break;
1560 }
1561 case X509_OBJ_ALGORITHM:
1562 cert->algorithm = parse_algorithmIdentifier(object, level, NULL);
1563 break;
1564 case X509_OBJ_SIGNATURE:
1565 cert->signature = object;
1566 break;
1567 default:
1568 break;
1569 }
1570 objectID++;
1571 }
1572 time(&cert->installed);
1573 return TRUE;
1574 }
1575
1576 /**
1577 * verify the validity of a x509 by
1578 * checking the notBefore and notAfter dates
1579 */
1580 err_t check_validity(const private_x509_t *cert, time_t *until)
1581 {
1582 time_t current_time;
1583
1584 time(&current_time);
1585
1586 if (cert->notAfter < *until)
1587 {
1588 *until = cert->notAfter;
1589 }
1590 if (current_time < cert->notBefore)
1591 {
1592 return "x509 is not valid yet";
1593 }
1594 if (current_time > cert->notAfter)
1595 {
1596 return "x509 has expired";
1597 }
1598 else
1599 {
1600 return NULL;
1601 }
1602 }
1603
1604 static rsa_public_key_t *get_public_key(private_x509_t *this)
1605 {
1606 return this->public_key->clone(this->public_key);;
1607 }
1608
1609 /**
1610 * destroy
1611 */
1612 static void destroy(private_x509_t *this)
1613 {
1614 free_generalNames(this->subjectAltName, FALSE);
1615 free_generalNames(this->crlDistributionPoints, FALSE);
1616 if (this->public_key)
1617 {
1618 this->public_key->destroy(this->public_key);
1619 }
1620 free(this);
1621 }
1622
1623 /*
1624 * Described in header.
1625 */
1626 x509_t *x509_create_from_chunk(chunk_t chunk)
1627 {
1628 private_x509_t *this = malloc_thing(private_x509_t);
1629
1630 /* public functions */
1631 this->public.equals = (bool (*) (x509_t*,x509_t*))equals;
1632 this->public.destroy = (void (*) (x509_t*))destroy;
1633 this->public.get_public_key = (rsa_public_key_t* (*) (x509_t*))get_public_key;
1634
1635 /* initialize */
1636 this->subjectPublicKey = CHUNK_INITIALIZER;
1637 this->public_key = NULL;
1638 this->subjectAltName = NULL;
1639 this->crlDistributionPoints = NULL;
1640
1641 logger = logger_manager->get_logger(logger_manager, ASN1);
1642
1643 if (!parse_x509cert(chunk, 0, this))
1644 {
1645 destroy(this);
1646 return NULL;
1647 }
1648
1649 this->public_key = rsa_public_key_create_from_chunk(this->subjectPublicKey);
1650 if (this->public_key == NULL)
1651 {
1652 destroy(this);
1653 return NULL;
1654 }
1655
1656 return &this->public;
1657 }
1658
1659 /*
1660 * Described in header.
1661 */
1662 x509_t *x509_create_from_file(char *filename)
1663 {
1664 struct stat stb;
1665 FILE *file;
1666 char *buffer;
1667 chunk_t chunk;
1668
1669 if (stat(filename, &stb) == -1)
1670 {
1671 return NULL;
1672 }
1673
1674 buffer = alloca(stb.st_size);
1675
1676 file = fopen(filename, "r");
1677 if (file == NULL)
1678 {
1679 return NULL;
1680 }
1681
1682 if (fread(buffer, stb.st_size, 1, file) == -1)
1683 {
1684 fclose(file);
1685 return NULL;
1686 }
1687 fclose(file);
1688
1689 chunk.ptr = buffer;
1690 chunk.len = stb.st_size;
1691
1692 return x509_create_from_chunk(chunk);
1693 }