1 /* Support of X.509 certificates and CRLs
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-2002 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.16 2005-06-08 05:06:38 matthewn Exp $
26 #include <sys/types.h>
30 #include "constants.h"
36 #include "preshared.h"
42 /* path definitions for cacerts and crls */
44 #include <config/autoconf.h>
46 #ifdef CONFIG_USER_FLATFSD_FLATFSD
47 #define __IPSEC__PREFIX__ "/etc/config"
49 #define __IPSEC__PREFIX__ "/etc"
52 #define X509_CERT_PATH __IPSEC__PREFIX__ "/"
53 #define PGP_CERT_PATH __IPSEC__PREFIX__ "/pgpcert.pgp"
54 #define CA_CERT_PATH __IPSEC__PREFIX__
55 #define CRL_PATH __IPSEC__PREFIX__
57 /* chained lists of host/user and ca certificates and crls */
59 static x509cert_t *x509certs = NULL;
60 static x509cert_t *x509cacerts = NULL;
61 static x509crl_t *x509crls = NULL;
63 /* contains my X.509 or OpenPGP certificate
64 " not used for X.509 certs anymore, backward compatibility only
67 static cert_t my_default_cert;
69 /* ASN.1 definition of a basicConstraints extension */
71 static const asn1Object_t basicConstraintsObjects[] = {
72 { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
73 { 1, "CA", ASN1_BOOLEAN, ASN1_DEF |
75 { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT |
77 { 1, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
80 #define BASIC_CONSTRAINTS_CA 1
81 #define BASIC_CONSTRAINTS_ROOF 4
83 /* ASN.1 definition of generalNames */
85 static const asn1Object_t generalNamesObjects[] = {
86 { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
87 { 1, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT |
89 { 1, "end choice", ASN1_EOC, ASN1_END }, /* 2 */
90 { 1, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT |
92 { 1, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
93 { 1, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT |
95 { 1, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
96 { 1, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT |
98 { 1, "end choice", ASN1_EOC, ASN1_END }, /* 8 */
99 { 1, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT |
101 { 1, "end choice", ASN1_EOC, ASN1_END }, /* 10 */
102 { 1, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT |
103 ASN1_BODY }, /* 11 */
104 { 1, "end choice", ASN1_EOC, ASN1_END }, /* 12 */
105 { 1, "uniformResourceIdentifier", ASN1_CONTEXT_S_6, ASN1_OPT |
106 ASN1_BODY }, /* 13 */
107 { 1, "end choice", ASN1_EOC, ASN1_END }, /* 14 */
108 { 1, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT |
109 ASN1_BODY }, /* 15 */
110 { 1, "end choice", ASN1_EOC, ASN1_END }, /* 16 */
111 { 1, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT |
112 ASN1_BODY }, /* 17 */
113 { 1, "end choice", ASN1_EOC, ASN1_END }, /* 18 */
114 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 19 */
117 #define GN_OBJ_OTHER_NAME 1
118 #define GN_OBJ_RFC822_NAME 3
119 #define GN_OBJ_DNS_NAME 5
120 #define GN_OBJ_X400_ADDRESS 7
121 #define GN_OBJ_DIRECTORY_NAME 9
122 #define GN_OBJ_EDI_PARTY_NAME 11
123 #define GN_OBJ_URI 13
124 #define GN_OBJ_IP_ADDRESS 15
125 #define GN_OBJ_REGISTERED_ID 17
126 #define GN_OBJ_ROOF 20
128 /* ASN.1 definition of crlDistributionPoints */
130 static const asn1Object_t crlDistributionPointsObjects[] = {
131 { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
132 { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
133 { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT |
135 { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT |
137 { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
138 { 3, "nameRelativeToCRLIssuer", ASN1_CONTEXT_C_1, ASN1_OPT |
140 { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
141 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
142 { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT |
144 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
145 { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT |
146 ASN1_BODY }, /* 10 */
147 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
148 { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
151 #define CRL_DIST_POINTS_FULLNAME 3
152 #define CRL_DIST_POINTS_ROOF 13
154 /* ASN.1 definition of an X.509v3 certificate */
156 static const asn1Object_t certObjects[] = {
157 { 0, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
158 { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
159 { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
160 { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
161 { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
162 { 2, "signature", ASN1_SEQUENCE, ASN1_NONE }, /* 5 */
163 { 3, "sigAlg", ASN1_OID, ASN1_BODY }, /* 6 */
164 { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 7 */
165 { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 8 */
166 { 3, "notBefore", ASN1_UTCTIME, ASN1_BODY }, /* 9 */
167 { 3, "notAfter", ASN1_UTCTIME, ASN1_BODY }, /* 10 */
168 { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
169 { 2, "subjectPublicKeyInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 12 */
170 { 3, "algorithm", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
171 { 4, "algorithm", ASN1_OID, ASN1_BODY }, /* 14 */
172 { 3, "subjectPublicKey", ASN1_BIT_STRING, ASN1_NONE }, /* 15 */
173 { 4, "RSAPublicKey", ASN1_SEQUENCE, ASN1_NONE }, /* 16 */
174 { 5, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 17 */
175 { 5, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 18 */
176 { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 19 */
177 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
178 { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 21 */
179 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 22 */
180 { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 23 */
181 { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 24 */
182 { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 25 */
183 { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 26 */
184 { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
185 ASN1_BODY }, /* 27 */
186 { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 28 */
187 { 3, "end loop", ASN1_EOC, ASN1_END }, /* 29 */
188 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 30 */
189 { 1, "signatureAlgorithm", ASN1_SEQUENCE, ASN1_NONE }, /* 31 */
190 { 2, "algorithm", ASN1_OID, ASN1_BODY }, /* 32 */
191 { 1, "signature", ASN1_BIT_STRING, ASN1_BODY } /* 33 */
194 #define X509_OBJ_CERTIFICATE 0
195 #define X509_OBJ_TBS_CERTIFICATE 1
196 #define X509_OBJ_VERSION 3
197 #define X509_OBJ_SERIAL_NUMBER 4
198 #define X509_OBJ_SIG_ALG 6
199 #define X509_OBJ_ISSUER 7
200 #define X509_OBJ_NOT_BEFORE 9
201 #define X509_OBJ_NOT_AFTER 10
202 #define X509_OBJ_SUBJECT 11
203 #define X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM 14
204 #define X509_OBJ_SUBJECT_PUBLIC_KEY 15
205 #define X509_OBJ_MODULUS 17
206 #define X509_OBJ_PUBLIC_EXPONENT 18
207 #define X509_OBJ_EXTN_ID 26
208 #define X509_OBJ_CRITICAL 27
209 #define X509_OBJ_EXTN_VALUE 28
210 #define X509_OBJ_ALGORITHM 32
211 #define X509_OBJ_SIGNATURE 33
212 #define X509_OBJ_ROOF 34
215 /* ASN.1 definition of an X.509 certificate list */
217 static const asn1Object_t crlObjects[] = {
218 { 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
219 { 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
220 { 2, "version", ASN1_INTEGER, ASN1_OPT |
222 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
223 { 2, "signature", ASN1_SEQUENCE, ASN1_NONE }, /* 4 */
224 { 3, "sigAlg", ASN1_OID, ASN1_BODY }, /* 5 */
225 { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
226 { 2, "thisUpdate", ASN1_UTCTIME, ASN1_BODY }, /* 7 */
227 { 2, "nextUpdate", ASN1_UTCTIME, ASN1_OPT |
229 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
230 { 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT |
231 ASN1_LOOP }, /* 10 */
232 { 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
233 { 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 12 */
234 { 4, "revocationDate", ASN1_UTCTIME, ASN1_BODY }, /* 13 */
235 { 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT |
236 ASN1_LOOP }, /* 14 */
237 { 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 15 */
238 { 6, "extnID", ASN1_OID, ASN1_BODY }, /* 16 */
239 { 6, "critical", ASN1_BOOLEAN, ASN1_DEF |
240 ASN1_BODY }, /* 17 */
241 { 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 18 */
242 { 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 19 */
243 { 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 20 */
244 { 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */
245 { 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 22 */
246 { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 23 */
247 { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 24 */
248 { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
249 ASN1_BODY }, /* 25 */
250 { 3, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
251 { 2, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
252 { 1, "signatureAlgorithm", ASN1_SEQUENCE, ASN1_NONE }, /* 28 */
253 { 2, "algorithm", ASN1_OID, ASN1_BODY }, /* 29 */
254 { 1, "signature", ASN1_BIT_STRING, ASN1_BODY } /* 30 */
257 #define CRL_OBJ_CERTIFICATE_LIST 0
258 #define CRL_OBJ_TBS_CERT_LIST 1
259 #define CRL_OBJ_VERSION 2
260 #define CRL_OBJ_SIG_ALG 5
261 #define CRL_OBJ_ISSUER 6
262 #define CRL_OBJ_THIS_UPDATE 7
263 #define CRL_OBJ_NEXT_UPDATE 8
264 #define CRL_OBJ_USER_CERTIFICATE 12
265 #define CRL_OBJ_REVOCATION_DATE 13
266 #define CRL_OBJ_CRITICAL 17
267 #define CRL_OBJ_ALGORITHM 29
268 #define CRL_OBJ_SIGNATURE 30
269 #define CRL_OBJ_ROOF 31
272 const x509cert_t empty_x509cert = {
276 { NULL, 0 }, /* certificate */
277 { NULL, 0 }, /* tbsCertificate */
279 { NULL, 0 }, /* serialNumber */
281 { NULL, 0 }, /* sigAlg */
282 { NULL, 0 }, /* issuer */
286 { NULL, 0 }, /* subject */
287 /* subjectPublicKeyInfo */
288 0 , /* subjectPublicKeyAlgorithm */
289 /* subjectPublicKey */
290 { NULL, 0 }, /* modulus */
291 { NULL, 0 }, /* publicExponent */
292 { NULL, 0 }, /* issuerUniqueID */
293 { NULL, 0 }, /* subjectUniqueID */
300 NULL , /* subjectAltName */
301 NULL , /* crlDistributionPoints */
302 /* signatureAlgorithm */
303 { NULL, 0 }, /* algorithm */
304 { NULL, 0 } /* signature */
307 const x509crl_t empty_x509crl = {
310 { NULL, 0 }, /* certificateList */
311 { NULL, 0 }, /* tbsCertList */
313 { NULL, 0 }, /* sigAlg */
314 { NULL, 0 }, /* issuer */
317 NULL , /* revokedCertificates */
319 /* signatureAlgorithm*/
320 { NULL, 0 }, /* algorithm*/
321 { NULL, 0 } /* signature*/
325 /* coding of X.501 distinguished name */
334 /* X.501 acronyms for well known object identifiers (OIDs) */
336 static const u_char oid_CN[] = {0x55, 0x04, 0x03};
337 static const u_char oid_S[] = {0x55, 0x04, 0x04};
338 static const u_char oid_SN[] = {0x55, 0x04, 0x05};
339 static const u_char oid_C[] = {0x55, 0x04, 0x06};
340 static const u_char oid_L[] = {0x55, 0x04, 0x07};
341 static const u_char oid_ST[] = {0x55, 0x04, 0x08};
342 static const u_char oid_O[] = {0x55, 0x04, 0x0A};
343 static const u_char oid_OU[] = {0x55, 0x04, 0x0B};
344 static const u_char oid_T[] = {0x55, 0x04, 0x0C};
345 static const u_char oid_D[] = {0x55, 0x04, 0x0D};
346 static const u_char oid_N[] = {0x55, 0x04, 0x29};
347 static const u_char oid_G[] = {0x55, 0x04, 0x2A};
348 static const u_char oid_I[] = {0x55, 0x04, 0x2B};
349 static const u_char oid_E[] = {0x2A, 0x86, 0x48, 0x86, 0xF7,
350 0x0D, 0x01, 0x09, 0x01};
351 static const u_char oid_TCGID[] = {0x2B, 0x06, 0x01, 0x04, 0x01, 0x89,
352 0x31, 0x01, 0x01, 0x02, 0x02, 0x4B};
354 static const x501rdn_t x501rdns[] = {
355 {"CN" , {oid_CN, 3}, ASN1_PRINTABLESTRING},
356 {"S" , {oid_S, 3}, ASN1_PRINTABLESTRING},
357 {"SN" , {oid_SN, 3}, ASN1_PRINTABLESTRING},
358 {"C" , {oid_C, 3}, ASN1_PRINTABLESTRING},
359 {"L" , {oid_L, 3}, ASN1_PRINTABLESTRING},
360 {"ST" , {oid_ST, 3}, ASN1_PRINTABLESTRING},
361 {"O" , {oid_O, 3}, ASN1_PRINTABLESTRING},
362 {"OU" , {oid_OU, 3}, ASN1_PRINTABLESTRING},
363 {"T" , {oid_T, 3}, ASN1_PRINTABLESTRING},
364 {"D" , {oid_D, 3}, ASN1_PRINTABLESTRING},
365 {"N" , {oid_N, 3}, ASN1_PRINTABLESTRING},
366 {"G" , {oid_G, 3}, ASN1_PRINTABLESTRING},
367 {"I" , {oid_I, 3}, ASN1_PRINTABLESTRING},
368 {"E" , {oid_E, 9}, ASN1_IA5STRING},
369 {"Email" , {oid_E, 9}, ASN1_IA5STRING},
370 {"emailAddress" , {oid_E, 9}, ASN1_IA5STRING},
371 {"TCGID" , {oid_TCGID, 12}, ASN1_PRINTABLESTRING}
374 #define X501_RDN_ROOF 16
376 /* Maximum length of ASN.1 distinquished name */
381 code_asn1_length(u_int length, chunk_t *code)
385 code->ptr[0] = length;
388 else if (length < 256)
391 code->ptr[1] = length;
397 code->ptr[1] = length >> 8;
398 code->ptr[2] = length & 0xff;
405 update_chunk(chunk_t *ch, int n)
407 n = (n > -1 && n < ch->len)? n : ch->len-1;
408 ch->ptr += n; ch->len -= n;
413 * Pointer is set to the first RDN in a DN
416 init_rdn(chunk_t dn, chunk_t *rdn)
420 /* a DN is a SEQUENCE OF RDNs */
422 if (*dn.ptr != ASN1_SEQUENCE)
424 return "DN is not a SEQUENCE";
427 rdn->len = asn1_length(&dn);
434 * Fetches the next RDN in a DN
437 get_next_rdn(chunk_t *rdn, chunk_t *oid, chunk_t *value, asn1_t *type)
441 /* initialize return values */
443 *value = empty_chunk;
445 /* an RDN is a SET OF attributeTypeAndValue */
446 if (*rdn->ptr != ASN1_SET)
447 return "RDN is not a SET";
449 attribute.len = asn1_length(rdn);
450 attribute.ptr = rdn->ptr;
452 /* advance to start of next RDN */
453 rdn->ptr += attribute.len;
454 rdn->len -= attribute.len;
456 /* an attributeTypeAndValue is a SEQUENCE */
457 if (*attribute.ptr != ASN1_SEQUENCE)
458 return "attributeTypeAndValue is not a SEQUENCE";
460 /* extract the attribute body */
461 attribute.len = asn1_length(&attribute);
463 /* attribute type is an OID */
464 if (*attribute.ptr != ASN1_OID)
465 return "attributeType is not an OID";
468 oid->len = asn1_length(&attribute);
469 oid->ptr = attribute.ptr;
471 /* advance to the attribute value */
472 attribute.ptr += oid->len;
473 attribute.len -= oid->len;
475 /* extract string type */
476 *type = *attribute.ptr;
478 /* extract string value */
479 value->len = asn1_length(&attribute);
480 value->ptr = attribute.ptr;
486 * Parses an ASN.1 distinguished name int its OID/value pairs
489 dn_parse(chunk_t dn, chunk_t *str)
491 chunk_t rdn, oid, value;
496 err_t ugh = init_rdn(dn, &rdn);
498 if (ugh != NULL) /* a parsing error has occured */
503 ugh = get_next_rdn(&rdn, &oid, &value, &type);
505 if (ugh != NULL) /* a parsing error has occured */
508 if (first) /* first OID/value pair */
510 else /* separate OID/value pair by a comma */
511 update_chunk(str, snprintf(str->ptr,str->len,", "));
514 oid_code = known_oid(oid);
515 if (oid_code == -1) /* OID not found in list */
518 update_chunk(str, snprintf(str->ptr,str->len,"%s",
519 oid_names[oid_code].name));
522 update_chunk(str, snprintf(str->ptr,str->len,"=%.*s",
523 (int)value.len,value.ptr));
529 * Prints a binary string in hexadecimal form
532 hex_str(chunk_t bin, chunk_t *str)
535 update_chunk(str, snprintf(str->ptr,str->len,"0x"));
536 for (i=0; i < bin.len; i++)
537 update_chunk(str, snprintf(str->ptr,str->len,"%02X",*bin.ptr++));
541 /* Converts a binary DER-encoded ASN.1 distinguished name
542 * into LDAP-style human-readable ASCII format
545 dntoa(char *dst, size_t dstlen, chunk_t dn)
552 ugh = dn_parse(dn, &str);
554 if (ugh != NULL) /* error, print DN as hex string */
557 DBG_log("error in DN parsing: %s", ugh)
563 return (int)(dstlen - str.len);
566 /* Converts an LDAP-style human-readable ASCII-encoded
567 * ASN.1 distinguished name into binary DER-encoded format
570 atodn(char *src, chunk_t *dn)
572 /* finite state machine for atodn */
582 u_char oid_len_buf[3];
583 u_char name_len_buf[3];
584 u_char rdn_seq_len_buf[3];
585 u_char rdn_set_len_buf[3];
586 u_char dn_seq_len_buf[3];
588 chunk_t asn1_oid_len = { oid_len_buf, 0 };
589 chunk_t asn1_name_len = { name_len_buf, 0 };
590 chunk_t asn1_rdn_seq_len = { rdn_seq_len_buf, 0 };
591 chunk_t asn1_rdn_set_len = { rdn_set_len_buf, 0 };
592 chunk_t asn1_dn_seq_len = { dn_seq_len_buf, 0 };
593 chunk_t oid = empty_chunk;
594 chunk_t name = empty_chunk;
604 u_char *dn_ptr = dn->ptr + 4;
606 state_t state = SEARCH_OID;
613 if (*src != ' ' && *src != '/' && *src != ',')
621 if (*src != ' ' && *src != '=')
625 for (pos = 0; pos < X501_RDN_ROOF; pos++)
627 if (strlen(x501rdns[pos].name) == oid.len &&
628 strncasecmp(x501rdns[pos].name, oid.ptr, oid.len) == 0)
629 break; /* found a valid OID */
631 if (pos == X501_RDN_ROOF)
633 ugh = "unknown OID in ID_DER_ASN1_DN";
637 code_asn1_length(x501rdns[pos].oid.len, &asn1_oid_len);
639 /* reset oid and change state */
645 if (*src != ' ' && *src != '=')
654 if (*src != ',' && *src != '/' && *src != '\0')
664 name.len -= whitespace;
665 code_asn1_length(name.len, &asn1_name_len);
667 /* compute the length of the relative distinguished name sequence */
668 rdn_seq_len = 1 + asn1_oid_len.len + x501rdns[pos].oid.len +
669 1 + asn1_name_len.len + name.len;
670 code_asn1_length(rdn_seq_len, &asn1_rdn_seq_len);
672 /* compute the length of the relative distinguished name set */
673 rdn_set_len = 1 + asn1_rdn_seq_len.len + rdn_seq_len;
674 code_asn1_length(rdn_set_len, &asn1_rdn_set_len);
676 /* encode the relative distinguished name */
677 *dn_ptr++ = ASN1_SET;
678 chunkcpy(dn_ptr, asn1_rdn_set_len);
679 *dn_ptr++ = ASN1_SEQUENCE;
680 chunkcpy(dn_ptr, asn1_rdn_seq_len);
681 *dn_ptr++ = ASN1_OID;
682 chunkcpy(dn_ptr, asn1_oid_len);
683 chunkcpy(dn_ptr, x501rdns[pos].oid);
684 /* encode the ASN.1 character string type of the name */
685 *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING
686 && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type;
687 chunkcpy(dn_ptr, asn1_name_len);
688 chunkcpy(dn_ptr, name);
690 /* accumulate the length of the distinguished name sequence */
691 dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len;
693 /* reset name and change state */
701 } while (*src++ != '\0');
703 /* complete the distinguished name sequence*/
704 code_asn1_length(dn_seq_len, &asn1_dn_seq_len);
705 dn->ptr += 3 - asn1_dn_seq_len.len;
706 dn->len = 1 + asn1_dn_seq_len.len + dn_seq_len;
708 *dn_ptr++ = ASN1_SEQUENCE;
709 chunkcpy(dn_ptr, asn1_dn_seq_len);
713 /* compare two distinguished names by
714 * comparing the individual RDNs
717 same_dn(chunk_t a, chunk_t b)
719 chunk_t rdn_a, rdn_b;
720 chunk_t oid_a, oid_b;
721 chunk_t value_a, value_b;
722 asn1_t type_a, type_b;
724 /* same lengths for the DNs */
728 /* initialize DN parsing */
729 if (init_rdn(a, &rdn_a) != NULL || init_rdn(b, &rdn_b) != NULL)
732 /* fetch next RDN pair */
733 while (rdn_a.len > 0 && rdn_b.len > 0)
735 /* parse next RDNs and check for errors */
736 if (get_next_rdn(&rdn_a, &oid_a, &value_a, &type_a) != NULL ||
737 get_next_rdn(&rdn_b, &oid_b, &value_b, &type_b) != NULL)
742 /* OIDs must agree */
743 if (oid_a.len != oid_b.len || memcmp(oid_a.ptr, oid_b.ptr, oid_b.len) != 0)
746 /* same lengths for values */
747 if (value_a.len != value_b.len)
750 /* printableStrings and email RDNs require uppercase comparison */
751 if (type_a == type_b && (type_a == ASN1_PRINTABLESTRING ||
752 (type_a == ASN1_IA5STRING && known_oid(oid_a) == OID_PKCS9_EMAIL)))
754 if (strncasecmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
759 if (strncmp(value_a.ptr, value_b.ptr, value_b.len) != 0)
763 /* both DNs must have same number of RDNs */
764 if (rdn_a.len != 0 || rdn_b.len != 0)
767 /* the two DNs are equal! */
772 * compare two certificates by comparing their signatures
775 same_cert(x509cert_t *a, x509cert_t *b)
777 return a->signature.len == b->signature.len &&
778 memcmp(a->signature.ptr, b->signature.ptr, b->signature.len) == 0;
781 /* for each link pointing to the certificate
782 " increase the count by one
785 share_x509cert(x509cert_t *cert)
792 * add a X.509 user/host certificate to the chained list
795 add_x509cert(x509cert_t *cert)
797 x509cert_t *c = x509certs;
801 if (same_cert(c, cert)) /* already in chain, free cert */
809 /* insert new cert at the root of the chain */
810 cert->next = x509certs;
816 * get the X.509 CA certificate with a given subject
819 get_x509cacert(chunk_t subject)
821 x509cert_t *cert = x509cacerts;
822 x509cert_t *prev_cert = NULL;
826 if (same_dn(cert->subject, subject))
828 if (cert != x509cacerts)
830 /* bring the certificate up front */
831 prev_cert->next = cert->next;
832 cert->next = x509cacerts;
844 * get the X.509 CRL with a given issuer
847 get_x509crl(chunk_t issuer)
849 x509crl_t *crl = x509crls;
850 x509crl_t *prev_crl = NULL;
854 if (same_dn(crl->issuer, issuer))
858 /* bring the CRL up front */
859 prev_crl->next = crl->next;
860 crl->next = x509crls;
871 /* Send my certificate either defined and loaded via
872 * /etc/ipsec.conf or by default loaded from /etc/x509cert.der
873 * (deprecated for X.509 certificates)
876 get_mycert(cert_t *mycert, x509cert_t *cert)
878 *mycert = my_default_cert;
882 mycert->type = CERT_X509_SIGNATURE;
883 mycert->cert = cert->certificate;
885 return mycert->type != CERT_NONE;
889 * free the dynamic memory used to store generalNames
892 free_generalNames(generalName_t* gn)
896 generalName_t *gn_top = gn;
903 * free a X.509 certificate
906 free_x509cert(x509cert_t *cert)
910 free_generalNames(cert->subjectAltName);
911 free_generalNames(cert->crlDistributionPoints);
912 if (cert->certificate.ptr != NULL)
913 pfree(cert->certificate.ptr);
919 /* release of a certificate decreases the count by one
920 " the certificate is freed when the counter reaches zero
923 release_x509cert(x509cert_t *cert)
925 if (cert != NULL && --cert->count == 0)
927 x509cert_t **pp = &x509certs;
936 * free the first CA certificate in the chain
939 free_first_cacert(void)
941 x509cert_t *first = x509cacerts;
942 x509cacerts = first->next;
943 free_x509cert(first);
947 * free all CA certificates
952 while (x509cacerts != NULL)
957 * free the dynamic memory used to store revoked certificates
960 free_revoked_certs(revokedCert_t* revokedCerts)
962 while (revokedCerts != NULL)
964 revokedCert_t * revokedCert = revokedCerts;
965 revokedCerts = revokedCert->next;
971 * free the dynamic memory used to store CRLs
976 x509crl_t * crl = x509crls;
977 x509crls = crl->next;
978 free_revoked_certs(crl->revokedCertificates);
979 pfree(crl->certificateList.ptr);
986 while (x509crls != NULL)
991 * free the dynamic memory used to store my X.509 or OpenPGP certificate
996 freeanychunk(my_default_cert.cert);
1000 * Filter eliminating the directory entries '.' and '..'
1003 file_select(const struct dirent *entry)
1005 return strcmp(entry->d_name, "." ) &&
1006 strcmp(entry->d_name, "..");
1010 * stores a chained list of user/host and CA certs
1013 store_x509certs(x509cert_t **firstcert)
1015 x509cert_t **pp = firstcert;
1017 /* first store CA certs */
1021 x509cert_t *cert = *pp;
1025 /* we don't accept self-signed CA certs */
1026 if (same_dn(cert->issuer, cert->subject))
1028 log("self-signed cacert rejected");
1030 free_x509cert(cert);
1034 if (get_x509cacert(cert->subject))
1036 free_first_cacert();
1038 DBG_log("existing cacert deleted")
1041 share_x509cert(cert); /* set count to one */
1043 /* insert into chained cacert list*/
1045 cert->next = x509cacerts;
1048 DBG_log("cacert inserted")
1056 /* now verify user/host certificates */
1062 x509cert_t *cert = *pp;
1064 if (verify_x509cert(cert))
1067 DBG_log("Public key validated")
1069 add_x509_public_key(cert, DAL_SIGNED);
1073 log("X.509 certificate rejected");
1076 free_x509cert(cert);
1081 * Loads a X.509 certificate
1084 load_x509cert(const char* filename, const char* label)
1086 chunk_t blob = empty_chunk;
1087 if (load_asn1_file(filename, "", label, &blob))
1089 x509cert_t *cert = alloc_thing(x509cert_t, "x509cert");
1090 *cert = empty_x509cert;
1091 if (parse_x509cert(blob, 0, cert)) {
1092 log(" X.509 loaded: %s", filename);
1096 log(" error in X.509 certificate: %s", filename);
1097 free_x509cert(cert);
1104 * Loads a host certificate
1107 load_host_cert(const char* filename)
1111 if (*filename == '/') /* absolute pathname */
1112 strncpy(path, filename, BUF_LEN);
1113 else /* relative pathname */
1114 snprintf(path, BUF_LEN, "%s/%s", HOST_CERT_PATH, filename);
1116 return load_x509cert(path, "host cert");
1120 * Loads CA certificates
1125 struct dirent **filelist;
1126 u_char buf[BUF_LEN];
1130 /* change directory to specified path */
1131 save_dir = getcwd(buf, BUF_LEN);
1132 if (chdir(CA_CERT_PATH))
1134 log("Could not change to directory '%s'", CA_CERT_PATH);
1138 log("Changing to directory '%s'",CA_CERT_PATH);
1139 n = scandir(CA_CERT_PATH, &filelist, file_select, alphasort);
1142 log(" Warning: empty directory");
1147 x509cert_t *cacert = load_x509cert(filelist[n]->d_name, "cacert");
1150 if (get_x509cacert(cacert->subject))
1152 free_first_cacert();
1154 DBG_log(" existing cacert deleted")
1157 share_x509cert(cacert); /* set count to one */
1158 cacert->next = x509cacerts;
1159 x509cacerts = cacert;
1166 /* restore directory path */
1176 struct dirent **filelist;
1177 u_char buf[BUF_LEN];
1181 /* change directory to specified path */
1182 save_dir = getcwd(buf, BUF_LEN);
1183 if (chdir(CRL_PATH))
1185 log("Could not change to directory '%s'", CRL_PATH);
1189 // log("Changing to directory '%s'", CRL_PATH);
1190 n = scandir(CRL_PATH, &filelist, file_select, alphasort);
1193 log(" Warning: empty directory");
1198 chunk_t blob = empty_chunk;
1199 if (load_asn1_file(filelist[n]->d_name, "", "crl", &blob))
1201 x509crl_t *crl = alloc_thing(x509crl_t, "x509crl");
1202 *crl = empty_x509crl;
1203 if (parse_x509crl(blob, 0, crl))
1205 if (get_x509crl(crl->issuer))
1209 DBG_log(" existing CRL deleted")
1212 log(" X.509 CRL loaded: %s",filelist[n]->d_name);
1213 crl->next = x509crls;
1218 log(" error in X.509 CRL: %s",filelist[n]->d_name);
1219 free_revoked_certs(crl->revokedCertificates);
1230 /* restore directory path */
1234 /* Loads the X.509 or OpenPGP certificate sent by FreeS/WAN to
1235 * its peers during ISAKMP Phase 1
1240 x509cert_t *myX509cert = NULL;
1242 /* deleting old certificate, if present */
1243 pfreeany(my_default_cert.cert.ptr);
1245 /* initializing certificate */
1246 my_default_cert.type = CERT_NONE;
1247 my_default_cert.cert = empty_chunk;
1249 /* loading a default X.509 certificate, if available */
1250 myX509cert = load_x509cert(X509_CERT_PATH, "my default X.509 cert");
1252 if (myX509cert != NULL)
1254 my_default_cert.type = CERT_X509_SIGNATURE;
1255 my_default_cert.cert = myX509cert->certificate;
1256 myX509cert->certificate = empty_chunk;
1257 free_x509cert(myX509cert);
1261 /* loading an OpenPGP certificate, if available */
1265 fd = fopen(PGP_CERT_PATH, "r");
1268 my_default_cert.type = CERT_PGP;
1269 fseek(fd, 0, SEEK_END );
1270 my_default_cert.cert.len = ftell(fd);
1272 my_default_cert.cert.ptr = alloc_bytes(my_default_cert.cert.len, "cert");
1273 i = fread(my_default_cert.cert.ptr, 1, my_default_cert.cert.len, fd);
1275 log("Loaded my OpenPGP certificate file '%s' (%d bytes)",
1280 // log("OpenPGP certificate file '%s' not found", PGP_CERT_PATH);
1286 * extracts the basicConstraints extension
1289 parse_basicConstraints(chunk_t blob, int level0)
1296 asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
1298 while (objectID < BASIC_CONSTRAINTS_ROOF) {
1300 if (!extract_object(basicConstraintsObjects, &objectID,
1304 if (objectID == BASIC_CONSTRAINTS_CA)
1306 isCA = object.len && *object.ptr;
1308 DBG_log(" %s",(isCA)?"TRUE":"FALSE");
1317 * Converts a X.500 generalName into an ID
1320 gntoid(struct id *id, const generalName_t *gn)
1324 case GN_DNS_NAME: /* ID type: ID_FQDN */
1326 id->name = gn->name;
1328 case GN_IP_ADDRESS: /* ID type: ID_IPV4_ADDR */
1330 const struct af_info *afi = &af_inet4_info;
1333 id->kind = afi->id_addr;
1334 ugh = initaddr(gn->name.ptr, gn->name.len, afi->af, &id->ip_addr);
1337 case GN_RFC822_NAME: /* ID type: ID_USER_FQDN */
1338 id->kind = ID_USER_FQDN;
1339 id->name = gn->name;
1343 id->name = empty_chunk;
1349 * extracts one or several GNs and puts them into a chained list
1351 static generalName_t*
1352 parse_generalNames(chunk_t blob, int level0, bool implicit)
1354 u_char buf[BUF_LEN];
1359 generalName_t *top_gn = NULL;
1361 asn1_init(&ctx, blob, level0, implicit, DBG_RAW);
1363 while (objectID < GN_OBJ_ROOF) {
1364 bool valid_gn = FALSE;
1366 if (!extract_object(generalNamesObjects, &objectID, &object, &ctx))
1370 case GN_OBJ_RFC822_NAME:
1371 case GN_OBJ_DNS_NAME:
1374 DBG_log(" '%.*s'", (int)object.len, object.ptr);
1378 case GN_OBJ_DIRECTORY_NAME:
1379 dntoa(buf, BUF_LEN, object);
1381 DBG_log(" '%s'", buf);
1385 case GN_OBJ_IP_ADDRESS:
1387 DBG_log(" '%d.%d.%d.%d'", *object.ptr, *(object.ptr+1),
1388 *(object.ptr+2), *(object.ptr+3));
1392 case GN_OBJ_OTHER_NAME:
1393 case GN_OBJ_X400_ADDRESS:
1394 case GN_OBJ_EDI_PARTY_NAME:
1395 case GN_OBJ_REGISTERED_ID:
1403 generalName_t *gn = alloc_thing(generalName_t, "generalName");
1404 gn->kind = (objectID - GN_OBJ_OTHER_NAME) / 2;
1414 /* extracts one or several crlDistributionPoints and puts them into
1417 static generalName_t*
1418 parse_crlDistributionPoints(chunk_t blob, int level0)
1424 generalName_t *top_gn = NULL; /* top of the chained list */
1425 generalName_t **tail_gn = &top_gn; /* tail of the chained list */
1427 asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
1429 while (objectID < CRL_DIST_POINTS_ROOF) {
1431 if (!extract_object(crlDistributionPointsObjects, &objectID,
1435 if (objectID == CRL_DIST_POINTS_FULLNAME)
1437 u_int level = crlDistributionPointsObjects[objectID].level + level0;
1438 generalName_t *gn = parse_generalNames(object, level, TRUE);
1439 /* append extracted generalNames to existing chained list */
1441 /* find new tail of the chained list */
1444 tail_gn = &gn->next; gn = gn->next;
1454 * Parses an X.509v3 certificate
1457 parse_x509cert(chunk_t blob, u_int level0, x509cert_t *cert)
1459 u_char buf[BUF_LEN];
1466 asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
1468 while (objectID < X509_OBJ_ROOF) {
1470 if (!extract_object(certObjects, &objectID, &object, &ctx))
1474 case X509_OBJ_CERTIFICATE:
1475 cert->certificate = object;
1477 case X509_OBJ_TBS_CERTIFICATE:
1478 cert->tbsCertificate = object;
1480 case X509_OBJ_VERSION:
1481 cert->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
1483 DBG_log(" v%d", cert->version);
1486 case X509_OBJ_SERIAL_NUMBER:
1487 cert->serialNumber = object;
1489 case X509_OBJ_SIG_ALG:
1490 cert->sigAlg = object;
1492 case X509_OBJ_ISSUER:
1493 cert->issuer = object;
1494 dntoa(buf, BUF_LEN, object);
1496 DBG_log(" '%s'",buf);
1499 case X509_OBJ_NOT_BEFORE:
1500 cert->notBefore = asn1totime(&object, ASN1_UTCTIME);
1502 case X509_OBJ_NOT_AFTER:
1503 cert->notAfter = asn1totime(&object, ASN1_UTCTIME);
1505 case X509_OBJ_SUBJECT:
1506 cert->subject = object;
1507 dntoa(buf, BUF_LEN, object);
1509 DBG_log(" '%s'",buf);
1512 case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM:
1513 if ( known_oid(object) == OID_RSA_ENCRYPTION )
1514 cert->subjectPublicKeyAlgorithm = PUBKEY_ALG_RSA;
1516 case X509_OBJ_SUBJECT_PUBLIC_KEY:
1517 if (cert->subjectPublicKeyAlgorithm == PUBKEY_ALG_RSA)
1519 ctx.blobs[4].ptr++; ctx.blobs[4].len--;
1522 objectID = X509_OBJ_MODULUS;
1524 case X509_OBJ_MODULUS:
1525 cert->modulus = object;
1527 case X509_OBJ_PUBLIC_EXPONENT:
1528 cert->publicExponent = object;
1530 case X509_OBJ_EXTN_ID:
1533 case X509_OBJ_CRITICAL:
1534 critical = object.len && *object.ptr;
1536 DBG_log(" %s",(critical)?"TRUE":"FALSE");
1539 case X509_OBJ_EXTN_VALUE:
1541 u_int extn_oid = known_oid(extnID);
1542 u_int level = level0 + certObjects[objectID].level + 1;
1544 if (extn_oid == OID_BASIC_CONSTRAINTS)
1546 parse_basicConstraints(object, level);
1547 else if (extn_oid == OID_SUBJECT_ALT_NAME)
1548 cert->subjectAltName =
1549 parse_generalNames(object, level, FALSE);
1550 else if (extn_oid == OID_CRL_DISTRIBUTION_POINTS)
1551 cert->crlDistributionPoints =
1552 parse_crlDistributionPoints(object, level);
1555 case X509_OBJ_ALGORITHM:
1556 cert->algorithm = object;
1558 case X509_OBJ_SIGNATURE:
1559 cert->signature = object;
1566 time(&cert->installed);
1572 * Parses an X.509 CRL
1575 parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
1577 u_char buf[BUF_LEN];
1580 chunk_t userCertificate;
1584 asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
1586 while (objectID < CRL_OBJ_ROOF) {
1588 if (!extract_object(crlObjects, &objectID, &object, &ctx))
1592 case CRL_OBJ_CERTIFICATE_LIST:
1593 crl->certificateList = object;
1595 case CRL_OBJ_TBS_CERT_LIST:
1596 crl->tbsCertList = object;
1598 case CRL_OBJ_VERSION:
1599 crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
1601 DBG_log(" v%d", crl->version);
1604 case CRL_OBJ_SIG_ALG:
1605 crl->sigAlg = object;
1607 case CRL_OBJ_ISSUER:
1608 crl->issuer = object;
1609 dntoa(buf, BUF_LEN, object);
1611 DBG_log(" '%s'",buf);
1614 case CRL_OBJ_THIS_UPDATE:
1615 crl->thisUpdate = asn1totime(&object, ASN1_UTCTIME);
1617 case CRL_OBJ_NEXT_UPDATE:
1618 crl->nextUpdate = asn1totime(&object, ASN1_UTCTIME);
1620 case CRL_OBJ_USER_CERTIFICATE:
1621 userCertificate = object;
1623 case CRL_OBJ_REVOCATION_DATE:
1625 /* put all the serial numbers and the revocation date in a chained list
1626 with revocedCertificates pointing to the first revoked certificate */
1628 revokedCert_t *revokedCert = alloc_thing(revokedCert_t, "revokedCert");
1629 revokedCert->userCertificate = userCertificate;
1630 revokedCert->revocationDate = asn1totime(&object, ASN1_UTCTIME);
1631 revokedCert->next = crl->revokedCertificates;
1632 crl->revokedCertificates = revokedCert;
1635 case CRL_OBJ_CRITICAL:
1636 critical = object.len && *object.ptr;
1638 DBG_log(" %s",(critical)?"TRUE":"FALSE");
1641 case CRL_OBJ_ALGORITHM:
1642 crl->algorithm = object;
1644 case CRL_OBJ_SIGNATURE:
1645 crl->signature = object;
1652 time(&crl->installed);
1656 /* verify the validity of a certificate by
1657 * checking the notBefore and notAfter dates
1660 check_validity(const x509cert_t *cert)
1662 time_t current_time;
1664 time(¤t_time);
1668 // FIXME - This is probabaly not the best place to put this
1669 // however it makes debugging certificate problems much easier
1670 struct id id = empty_id;
1671 char buf[IDTOA_BUF];
1673 id.kind = ID_DER_ASN1_DN;
1674 id.name.len = (&cert->subject)->len;
1675 id.name.ptr = temporary_cyclic_buffer();
1676 memcpy(id.name.ptr, cert->subject.ptr, cert->subject.len);
1677 idtoa(&id, buf, IDTOA_BUF);
1679 log(" Certificate DN: %s", buf);
1680 log(" valid from: %s", timetoa(&cert->notBefore, TRUE));
1681 log(" to: %s", timetoa(&cert->notAfter, TRUE));
1686 DBG_log(" not before : %s", timetoa(&cert->notBefore, TRUE));
1687 DBG_log(" current time: %s", timetoa(¤t_time, TRUE));
1688 DBG_log(" not after : %s", timetoa(&cert->notAfter, TRUE));
1691 return (current_time >= cert->notBefore) &&
1692 (current_time <= cert->notAfter);
1697 * compute a digest over a binary blob
1700 compute_digest(chunk_t tbs, int alg, chunk_t *digest)
1705 case OID_MD2_WITH_RSA:
1709 MD2Update(&context, tbs.ptr, tbs.len);
1710 MD2Final(digest->ptr, &context);
1711 digest->len = MD2_DIGEST_SIZE;
1715 case OID_MD5_WITH_RSA:
1719 MD5Update(&context, tbs.ptr, tbs.len);
1720 MD5Final(digest->ptr, &context);
1721 digest->len = MD5_DIGEST_SIZE;
1725 case OID_SHA1_WITH_RSA:
1729 SHA1Update(&context, tbs.ptr, tbs.len);
1730 SHA1Final(digest->ptr, &context);
1731 digest->len = SHA1_DIGEST_SIZE;
1741 * decrypts an RSA signature using the issuer's certificate
1744 decrypt_sig(chunk_t sig, int alg, const x509cert_t *issuer_cert,
1750 case OID_RSA_ENCRYPTION:
1751 case OID_MD2_WITH_RSA:
1752 case OID_MD5_WITH_RSA:
1753 case OID_SHA1_WITH_RSA:
1754 case OID_SHA256_WITH_RSA:
1755 case OID_SHA384_WITH_RSA:
1756 case OID_SHA512_WITH_RSA:
1762 n_to_mpz(s, sig.ptr, sig.len);
1763 n_to_mpz(e, issuer_cert->publicExponent.ptr,
1764 issuer_cert->publicExponent.len);
1765 n_to_mpz(n, issuer_cert->modulus.ptr,
1766 issuer_cert->modulus.len);
1768 /* decrypt the signature s = s^e mod n */
1769 mpz_powm(s, s, e, n);
1770 /* convert back to bytes */
1771 decrypted = mpz_to_n(s, issuer_cert->modulus.len);
1773 DBG_dump_chunk(" decrypted signature: ", decrypted)
1776 /* copy the least significant bits of decrypted signature
1777 * into the digest string
1779 memcpy(digest->ptr, decrypted.ptr + decrypted.len - digest->len,
1783 pfree(decrypted.ptr);
1796 * Check if a signature over binary blob is genuine
1799 check_signature(chunk_t tbs, chunk_t sig, chunk_t algorithm,
1800 const x509cert_t *issuer_cert)
1802 u_char digest_buf[MAX_DIGEST_LEN];
1803 u_char decrypted_buf[MAX_DIGEST_LEN];
1804 chunk_t digest = {digest_buf, MAX_DIGEST_LEN};
1805 chunk_t decrypted = {decrypted_buf, MAX_DIGEST_LEN};
1807 int alg = known_oid(algorithm);
1812 DBG_log("Signature Algorithm: '%s'",oid_names[alg].name);
1817 u_char buf[BUF_LEN];
1818 chunk_t hex_oid = {buf, BUF_LEN};
1820 hex_str(hex_oid, &algorithm);
1821 DBG_log("Signature Algorithm: '%s'", hex_oid.ptr);
1825 if (!compute_digest(tbs, alg, &digest))
1827 log(" digest algorithm not supported");
1832 DBG_dump_chunk(" digest:", digest)
1835 decrypted.len = digest.len; /* we want the same digest length */
1837 if (!decrypt_sig(sig, alg, issuer_cert, &decrypted))
1839 log(" decryption algorithm not supported");
1843 /* check if digests are equal */
1844 return !memcmp(decrypted.ptr, digest.ptr, digest.len);
1847 /* Checks if the current certificate is revoked. It goes through the
1848 * list of revoked certificates of the corresponding crl. If the
1849 * certificate is not found in the list, then the certificate is valid
1850 * and FALSE is returned.
1853 check_crl(const x509crl_t *crl, chunk_t serial)
1855 revokedCert_t *revokedCert = crl->revokedCertificates;
1856 time_t current_time;
1858 time(¤t_time);
1860 DBG_log("Next CRL update:");
1861 DBG_log(" this update : %s", timetoa(&crl->thisUpdate, TRUE));
1862 DBG_log(" current time: %s", timetoa(¤t_time, TRUE));
1863 DBG_log(" next update : %s", timetoa(&crl->nextUpdate, TRUE));
1865 if (current_time > crl->nextUpdate)
1866 log("Next CRL update was expected on %s",
1867 timetoa(&crl->nextUpdate, TRUE));
1870 DBG_dump_chunk("Serial number:", serial)
1873 while(revokedCert != NULL)
1875 /* compare serial numbers */
1876 if (revokedCert->userCertificate.len == serial.len &&
1877 memcmp(revokedCert->userCertificate.ptr, serial.ptr, serial.len) == 0)
1879 log("Revocation date: %s",
1880 timetoa(&revokedCert->revocationDate, TRUE));
1883 revokedCert = revokedCert->next;
1890 * verifies a X.509 certificate
1893 verify_x509cert(const x509cert_t *cert){
1897 if (same_dn(cert->issuer, cert->subject))
1899 log("end certificate with identical subject and issuer not accepted");
1903 for (pathlen = 0; pathlen < MAX_CA_PATH_LEN; pathlen++)
1905 u_char buf[BUF_LEN];
1906 x509cert_t *issuer_cert;
1910 dntoa(buf, BUF_LEN, cert->subject);
1911 DBG_log("Subject: '%s'",buf);
1913 if (!check_validity(cert))
1915 log("Certificate is invalid");
1919 DBG_log(" certificate is valid")
1923 dntoa(buf, BUF_LEN, cert->issuer);
1924 DBG_log("Issuer: '%s'",buf);
1927 issuer_cert = get_x509cacert(cert->issuer);
1929 if (issuer_cert == NULL)
1931 log("Issuer CA certificate not found");
1935 DBG_log(" issuer CA certificate found")
1938 if (!check_signature(cert->tbsCertificate, cert->signature,
1939 cert->algorithm, issuer_cert))
1941 log("Certificate signature is invalid");
1945 DBG_log(" certificate signature is valid")
1948 crl = get_x509crl(cert->issuer);
1952 log("Issuer CRL not found");
1957 DBG_log(" issuer CRL found")
1959 if (check_signature(crl->tbsCertList, crl->signature,
1960 crl->algorithm, issuer_cert))
1963 DBG_log(" CRL signature is valid")
1966 if (check_crl(crl, cert->serialNumber))
1968 log("Certificate has been revoked");
1969 remove_x509_public_key(cert);
1973 DBG_log(" certificate not revoked")
1978 log("CRL signature is invalid");
1981 /* check if cert is a self-signed root ca */
1982 if (pathlen > 0 && same_dn(cert->issuer, cert->subject))
1985 DBG_log("reached self-signed root ca")
1989 /* otherwise go up one step in the trust chain */
1993 log("maximum ca path length of %d levels exceeded", MAX_CA_PATH_LEN);
1998 * list all certs in a chained list
2001 list_cert_chain(const char * caption, x509cert_t* cert, bool utc)
2005 /* determine the current time */
2008 whack_log(RC_COMMENT, " ");
2009 whack_log(RC_COMMENT, "List of %s:", caption);
2010 whack_log(RC_COMMENT, " ");
2012 while (cert != NULL)
2014 u_char buf[BUF_LEN];
2016 whack_log(RC_COMMENT, "%s, count: %d", timetoa(&cert->installed, utc), cert->count);
2017 dntoa(buf, BUF_LEN, cert->subject);
2018 whack_log(RC_COMMENT, " subject: '%s'", buf);
2019 dntoa(buf, BUF_LEN, cert->issuer);
2020 whack_log(RC_COMMENT, " issuer: '%s'", buf);
2021 whack_log(RC_COMMENT, " validity: not before %s %s",
2022 timetoa(&cert->notBefore, utc),
2023 (cert->notBefore < now)?"ok":"fatal (not valid yet)");
2024 whack_log(RC_COMMENT, " not after %s %s",
2025 timetoa(&cert->notAfter, utc),
2026 check_expiry(cert->notAfter, CA_CERT_WARNING_INTERVAL, TRUE));
2032 * list all user/host certs in a chained list
2035 list_certs(bool utc)
2037 list_cert_chain("User/Host Certificates", x509certs, utc);
2041 * list all user/host certs in a chained list
2044 list_cacerts(bool utc)
2046 list_cert_chain("CA Certificates", x509cacerts, utc);
2050 * list all crls in the chained list
2055 const bool strict = FALSE; /*expiry of CRL is non-fatal */
2057 x509crl_t* crl = x509crls;
2059 whack_log(RC_COMMENT, " ");
2060 whack_log(RC_COMMENT, "List of CRLs:");
2061 whack_log(RC_COMMENT, " ");
2065 u_char buf[BUF_LEN];
2067 revokedCert_t *revokedCert = crl->revokedCertificates;
2069 /* count number of revoked certificates in CRL */
2070 while (revokedCert != NULL)
2073 revokedCert = revokedCert->next;
2076 whack_log(RC_COMMENT, "%s, revoked certs: %d",
2077 timetoa(&crl->installed, utc), revoked);
2078 dntoa(buf, BUF_LEN, crl->issuer);
2079 whack_log(RC_COMMENT, " issuer: '%s'", buf);
2080 whack_log(RC_COMMENT, " updates: this %s",
2081 timetoa(&crl->thisUpdate, utc));
2082 whack_log(RC_COMMENT, " next %s %s",
2083 timetoa(&crl->nextUpdate, utc),
2084 check_expiry(crl->nextUpdate, CRL_WARNING_INTERVAL, strict));