aboutsummaryrefslogtreecommitdiffstats
path: root/src/pluto/crl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pluto/crl.c')
-rw-r--r--src/pluto/crl.c201
1 files changed, 99 insertions, 102 deletions
diff --git a/src/pluto/crl.c b/src/pluto/crl.c
index d186abac8..f419af0eb 100644
--- a/src/pluto/crl.c
+++ b/src/pluto/crl.c
@@ -1,5 +1,7 @@
/* Support of X.509 certificate revocation lists (CRLs)
- * Copyright (C) 2000-2004 Andreas Steffen, Zuercher Hochschule Winterthur
+ * Copyright (C) 2000-2009 Andreas Steffen
+ *
+ * HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
@@ -25,11 +27,13 @@
#include <freeswan.h>
#include <ipsec_policy.h>
+#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
+#include <asn1/oid.h>
+
#include "constants.h"
#include "defs.h"
#include "log.h"
-#include "asn1.h"
-#include <asn1/oid.h>
#include "x509.h"
#include "crl.h"
#include "ca.h"
@@ -43,64 +47,64 @@
static x509crl_t *x509crls = NULL;
-/* ASN.1 definition of an X.509 certificate list */
-
+/**
+ * ASN.1 definition of an X.509 certificate revocation list
+ */
static const asn1Object_t crlObjects[] = {
- { 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "version", ASN1_INTEGER, ASN1_OPT |
+ { 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
+ { 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "version", ASN1_INTEGER, ASN1_OPT |
ASN1_BODY }, /* 2 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 4 */
- { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 2, "thisUpdate", ASN1_EOC, ASN1_RAW }, /* 6 */
- { 2, "nextUpdate", ASN1_EOC, ASN1_RAW }, /* 7 */
- { 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT |
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
+ { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 4 */
+ { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
+ { 2, "thisUpdate", ASN1_EOC, ASN1_RAW }, /* 6 */
+ { 2, "nextUpdate", ASN1_EOC, ASN1_RAW }, /* 7 */
+ { 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT |
ASN1_LOOP }, /* 8 */
- { 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 9 */
- { 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 10 */
- { 4, "revocationDate", ASN1_EOC, ASN1_RAW }, /* 11 */
- { 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 12 */
- { 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
- { 6, "extnID", ASN1_OID, ASN1_BODY }, /* 14 */
- { 6, "critical", ASN1_BOOLEAN, ASN1_DEF |
+ { 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 9 */
+ { 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 10 */
+ { 4, "revocationDate", ASN1_EOC, ASN1_RAW }, /* 11 */
+ { 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT |
+ ASN1_LOOP }, /* 12 */
+ { 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
+ { 6, "extnID", ASN1_OID, ASN1_BODY }, /* 14 */
+ { 6, "critical", ASN1_BOOLEAN, ASN1_DEF |
ASN1_BODY }, /* 15 */
- { 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
- { 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 17 */
- { 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 19 */
- { 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
+ { 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
+ { 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 17 */
+ { 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 18 */
+ { 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 19 */
+ { 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
+ { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
+ { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
+ { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
ASN1_BODY }, /* 23 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
- { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 28 */
- };
-
-#define CRL_OBJ_CERTIFICATE_LIST 0
-#define CRL_OBJ_TBS_CERT_LIST 1
-#define CRL_OBJ_VERSION 2
-#define CRL_OBJ_SIG_ALG 4
-#define CRL_OBJ_ISSUER 5
-#define CRL_OBJ_THIS_UPDATE 6
-#define CRL_OBJ_NEXT_UPDATE 7
-#define CRL_OBJ_USER_CERTIFICATE 10
-#define CRL_OBJ_REVOCATION_DATE 11
-#define CRL_OBJ_CRL_ENTRY_EXTN_ID 14
-#define CRL_OBJ_CRL_ENTRY_CRITICAL 15
-#define CRL_OBJ_CRL_ENTRY_EXTN_VALUE 16
-#define CRL_OBJ_EXTN_ID 22
-#define CRL_OBJ_CRITICAL 23
-#define CRL_OBJ_EXTN_VALUE 24
-#define CRL_OBJ_ALGORITHM 27
-#define CRL_OBJ_SIGNATURE 28
-#define CRL_OBJ_ROOF 29
+ { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
+ { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
+ { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY }, /* 28 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define CRL_OBJ_CERTIFICATE_LIST 0
+#define CRL_OBJ_TBS_CERT_LIST 1
+#define CRL_OBJ_VERSION 2
+#define CRL_OBJ_SIG_ALG 4
+#define CRL_OBJ_ISSUER 5
+#define CRL_OBJ_THIS_UPDATE 6
+#define CRL_OBJ_NEXT_UPDATE 7
+#define CRL_OBJ_USER_CERTIFICATE 10
+#define CRL_OBJ_REVOCATION_DATE 11
+#define CRL_OBJ_CRL_ENTRY_EXTN_ID 14
+#define CRL_OBJ_CRL_ENTRY_CRITICAL 15
+#define CRL_OBJ_CRL_ENTRY_EXTN_VALUE 16
+#define CRL_OBJ_EXTN_ID 22
+#define CRL_OBJ_CRITICAL 23
+#define CRL_OBJ_EXTN_VALUE 24
+#define CRL_OBJ_ALGORITHM 27
+#define CRL_OBJ_SIGNATURE 28
const x509crl_t empty_x509crl = {
NULL , /* *next */
@@ -126,11 +130,10 @@ const x509crl_t empty_x509crl = {
{ NULL, 0 } /* signature */
};
-/*
- * get the X.509 CRL with a given issuer
+/**
+ * Get the X.509 CRL with a given issuer
*/
-static x509crl_t*
-get_x509crl(chunk_t issuer, chunk_t serial, chunk_t keyid)
+static x509crl_t* get_x509crl(chunk_t issuer, chunk_t serial, chunk_t keyid)
{
x509crl_t *crl = x509crls;
x509crl_t *prev_crl = NULL;
@@ -156,11 +159,10 @@ get_x509crl(chunk_t issuer, chunk_t serial, chunk_t keyid)
return NULL;
}
-/*
- * free the dynamic memory used to store revoked certificates
+/**
+ * Free the dynamic memory used to store revoked certificates
*/
-static void
-free_revoked_certs(revokedCert_t* revokedCerts)
+static void free_revoked_certs(revokedCert_t* revokedCerts)
{
while (revokedCerts != NULL)
{
@@ -170,11 +172,10 @@ free_revoked_certs(revokedCert_t* revokedCerts)
}
}
-/*
- * free the dynamic memory used to store CRLs
+/**
+ * Free the dynamic memory used to store CRLs
*/
-void
-free_crl(x509crl_t *crl)
+void free_crl(x509crl_t *crl)
{
free_revoked_certs(crl->revokedCertificates);
free_generalNames(crl->distributionPoints, TRUE);
@@ -182,8 +183,7 @@ free_crl(x509crl_t *crl)
free(crl);
}
-static void
-free_first_crl(void)
+static void free_first_crl(void)
{
x509crl_t *crl = x509crls;
@@ -191,8 +191,7 @@ free_first_crl(void)
free_crl(crl);
}
-void
-free_crls(void)
+void free_crls(void)
{
lock_crl_list("free_crls");
@@ -202,11 +201,10 @@ free_crls(void)
unlock_crl_list("free_crls");
}
-/*
+/**
* Insert X.509 CRL into chained list
*/
-bool
-insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl)
+bool insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl)
{
x509crl_t *crl = malloc_thing(x509crl_t);
@@ -322,11 +320,10 @@ insert_crl(chunk_t blob, chunk_t crl_uri, bool cache_crl)
}
}
-/*
+/**
* Loads CRLs
*/
-void
-load_crls(void)
+void load_crls(void)
{
struct dirent **filelist;
u_char buf[BUF_LEN];
@@ -376,11 +373,10 @@ load_crls(void)
ignore_result(chdir(save_dir));
}
-/*
+/**
* Parses a CRL revocation reason code
*/
-static crl_reason_t
-parse_crl_reasonCode(chunk_t object)
+static crl_reason_t parse_crl_reasonCode(chunk_t object)
{
crl_reason_t reason = REASON_UNSPECIFIED;
@@ -399,27 +395,22 @@ parse_crl_reasonCode(chunk_t object)
/*
* Parses an X.509 CRL
*/
-bool
-parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
+bool parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
{
u_char buf[BUF_LEN];
- asn1_ctx_t ctx;
- bool critical;
+ asn1_parser_t *parser;
chunk_t extnID;
chunk_t userCertificate = chunk_empty;
chunk_t object;
- u_int level;
- int objectID = 0;
+ int objectID;
+ bool success = FALSE;
+ bool critical;
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+ parser = asn1_parser_create(crlObjects, blob);
- while (objectID < CRL_OBJ_ROOF)
+ while (parser->iterate(parser, &objectID, &object))
{
- if (!extract_object(crlObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- /* those objects which will parsed further need the next higher level */
- level++;
+ u_int level = parser->get_level(parser)+1;
switch (objectID) {
case CRL_OBJ_CERTIFICATE_LIST:
@@ -435,7 +426,7 @@ parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
)
break;
case CRL_OBJ_SIG_ALG:
- crl->sigAlg = parse_algorithmIdentifier(object, level, NULL);
+ crl->sigAlg = asn1_parse_algorithmIdentifier(object, level, NULL);
break;
case CRL_OBJ_ISSUER:
crl->issuer = object;
@@ -445,10 +436,10 @@ parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
)
break;
case CRL_OBJ_THIS_UPDATE:
- crl->thisUpdate = parse_time(object, level);
+ crl->thisUpdate = asn1_parse_time(object, level);
break;
case CRL_OBJ_NEXT_UPDATE:
- crl->nextUpdate = parse_time(object, level);
+ crl->nextUpdate = asn1_parse_time(object, level);
break;
case CRL_OBJ_USER_CERTIFICATE:
userCertificate = object;
@@ -460,7 +451,7 @@ parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
revokedCert_t *revokedCert = malloc_thing(revokedCert_t);
revokedCert->userCertificate = userCertificate;
- revokedCert->revocationDate = parse_time(object, level);
+ revokedCert->revocationDate = asn1_parse_time(object, level);
revokedCert->revocationReason = REASON_UNSPECIFIED;
revokedCert->next = crl->revokedCertificates;
crl->revokedCertificates = revokedCert;
@@ -494,14 +485,17 @@ parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
}
else if (extn_oid == OID_CRL_NUMBER)
{
- if (!parse_asn1_simple_object(&object, ASN1_INTEGER, level, "crlNumber"))
- return FALSE;
+ if (!asn1_parse_simple_object(&object, ASN1_INTEGER,
+ level, "crlNumber"))
+ {
+ goto end;
+ }
crl->crlNumber = object;
}
}
break;
case CRL_OBJ_ALGORITHM:
- crl->algorithm = parse_algorithmIdentifier(object, level, NULL);
+ crl->algorithm = asn1_parse_algorithmIdentifier(object, level, NULL);
break;
case CRL_OBJ_SIGNATURE:
crl->signature = object;
@@ -509,10 +503,13 @@ parse_x509crl(chunk_t blob, u_int level0, x509crl_t *crl)
default:
break;
}
- objectID++;
}
+ success = parser->success(parser);
time(&crl->installed);
- return TRUE;
+
+end:
+ parser->destroy(parser);
+ return success;
}
/* Checks if the current certificate is revoked. It goes through the