aboutsummaryrefslogtreecommitdiffstats
path: root/src/pluto/ocsp.c
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2009-04-20 20:53:38 +0000
committerAndreas Steffen <andreas.steffen@strongswan.org>2009-04-20 20:53:38 +0000
commit08b2d288a1281d672533428fb1d8170dff9e5e08 (patch)
tree040f1eaa97f5f3c243b67b59a47d7e8742779e42 /src/pluto/ocsp.c
parent09f706ec3e69e1899ba3efb9eaf248f35d5c6aaa (diff)
downloadstrongswan-08b2d288a1281d672533428fb1d8170dff9e5e08.tar.bz2
strongswan-08b2d288a1281d672533428fb1d8170dff9e5e08.tar.xz
scepclient and pluto use asn1 from libstrongswan
Diffstat (limited to 'src/pluto/ocsp.c')
-rw-r--r--src/pluto/ocsp.c582
1 files changed, 286 insertions, 296 deletions
diff --git a/src/pluto/ocsp.c b/src/pluto/ocsp.c
index ef270cd6c..2516391c2 100644
--- a/src/pluto/ocsp.c
+++ b/src/pluto/ocsp.c
@@ -26,6 +26,10 @@
#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"
@@ -33,10 +37,8 @@
#include "crl.h"
#include "ca.h"
#include "rnd.h"
-#include "asn1.h"
#include "certs.h"
#include "smartcard.h"
-#include <asn1/oid.h>
#include "whack.h"
#include "pkcs1.h"
#include "keys.h"
@@ -160,131 +162,137 @@ static smartcard_t *ocsp_requestor_sc = NULL;
static const struct RSA_private_key *ocsp_requestor_pri = NULL;
-/* asn.1 definitions for parsing */
-
+/**
+ * ASN.1 definition of ocspResponse
+ */
static const asn1Object_t ocspResponseObjects[] = {
- { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
- { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
- { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
- { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
- { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
+ { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
+ { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
+ { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
+ { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
+ { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
+#define OCSP_RESPONSE_STATUS 1
+#define OCSP_RESPONSE_TYPE 4
+#define OCSP_RESPONSE 5
-#define OCSP_RESPONSE_STATUS 1
-#define OCSP_RESPONSE_TYPE 4
-#define OCSP_RESPONSE 5
-#define OCSP_RESPONSE_ROOF 7
-
+/**
+ * ASN.1 definition of basicResponse
+ */
static const asn1Object_t basicResponseObjects[] = {
- { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
- ASN1_DEF }, /* 2 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
- { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
- { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
- { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
- { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
- { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
- { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
- ASN1_DEF }, /* 16 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
- { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
- { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
- { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
- { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
- { 3, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 24 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 26 */
+ { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
+ { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
+ { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
+ ASN1_DEF }, /* 2 */
+ { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
+ { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
+ { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
+ { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
+ { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
+ { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
+ { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
+ { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
+ { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
+ { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
+ { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
+ { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
+ { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
+ ASN1_DEF }, /* 16 */
+ { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
+ { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
+ { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
+ { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
+ { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
+ { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
+ { 3, "certificate", ASN1_SEQUENCE, ASN1_RAW }, /* 24 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
-
-#define BASIC_RESPONSE_TBS_DATA 1
-#define BASIC_RESPONSE_VERSION 3
-#define BASIC_RESPONSE_ID_BY_NAME 5
-#define BASIC_RESPONSE_ID_BY_KEY 8
-#define BASIC_RESPONSE_PRODUCED_AT 10
-#define BASIC_RESPONSE_RESPONSES 11
-#define BASIC_RESPONSE_EXT_ID 15
-#define BASIC_RESPONSE_CRITICAL 16
-#define BASIC_RESPONSE_EXT_VALUE 17
-#define BASIC_RESPONSE_ALGORITHM 20
-#define BASIC_RESPONSE_SIGNATURE 21
-#define BASIC_RESPONSE_CERTIFICATE 24
-#define BASIC_RESPONSE_ROOF 27
-
+#define BASIC_RESPONSE_TBS_DATA 1
+#define BASIC_RESPONSE_VERSION 3
+#define BASIC_RESPONSE_ID_BY_NAME 5
+#define BASIC_RESPONSE_ID_BY_KEY 8
+#define BASIC_RESPONSE_PRODUCED_AT 10
+#define BASIC_RESPONSE_RESPONSES 11
+#define BASIC_RESPONSE_EXT_ID 15
+#define BASIC_RESPONSE_CRITICAL 16
+#define BASIC_RESPONSE_EXT_VALUE 17
+#define BASIC_RESPONSE_ALGORITHM 20
+#define BASIC_RESPONSE_SIGNATURE 21
+#define BASIC_RESPONSE_CERTIFICATE 24
+
+/**
+ * ASN.1 definition of responses
+ */
static const asn1Object_t responsesObjects[] = {
- { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
+ { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
+ { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
+#define RESPONSES_SINGLE_RESPONSE 1
-#define RESPONSES_SINGLE_RESPONSE 1
-#define RESPONSES_ROOF 3
-
+/**
+ * ASN.1 definition of singleResponse
+ */
static const asn1Object_t singleResponseObjects[] = {
- { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
- { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
- { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
- { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
- { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
- { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
- { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
- { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
- { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
- { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
- { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
- { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
- { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
- { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
- { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
- { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
- { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
- { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
- ASN1_DEF }, /* 24 */
- { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 27 */
+ { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
+ { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
+ { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
+ { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
+ { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
+ { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
+ { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
+ { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
+ { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
+ { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
+ { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
+ { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
+ { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
+ { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
+ { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
+ { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
+ { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
+ { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
+ { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
+ { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
+ ASN1_DEF }, /* 24 */
+ { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
+ { 1, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
};
+#define SINGLE_RESPONSE_ALGORITHM 2
+#define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
+#define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
+#define SINGLE_RESPONSE_SERIAL_NUMBER 5
+#define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
+#define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
+#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
+#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
+#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
+#define SINGLE_RESPONSE_THIS_UPDATE 16
+#define SINGLE_RESPONSE_NEXT_UPDATE 18
+#define SINGLE_RESPONSE_EXT_ID 23
+#define SINGLE_RESPONSE_CRITICAL 24
+#define SINGLE_RESPONSE_EXT_VALUE 25
-#define SINGLE_RESPONSE_ALGORITHM 2
-#define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
-#define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
-#define SINGLE_RESPONSE_SERIAL_NUMBER 5
-#define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
-#define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
-#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
-#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
-#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
-#define SINGLE_RESPONSE_THIS_UPDATE 16
-#define SINGLE_RESPONSE_NEXT_UPDATE 18
-#define SINGLE_RESPONSE_EXT_ID 23
-#define SINGLE_RESPONSE_CRITICAL 24
-#define SINGLE_RESPONSE_EXT_VALUE 25
-#define SINGLE_RESPONSE_ROOF 28
-
-/* build an ocsp location from certificate information
+/*
+ * Build an ocsp location from certificate information
* without unsharing its contents
*/
-static bool
-build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
+static bool build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
{
static u_char digest[SHA1_DIGEST_SIZE]; /* temporary storage */
@@ -330,11 +338,10 @@ build_ocsp_location(const x509cert_t *cert, ocsp_location_t *location)
return TRUE;
}
-/*
- * compare two ocsp locations for equality
+/**
+ * Compare two ocsp locations for equality
*/
-static bool
-same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b)
+static bool same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b)
{
return ((a->authKeyID.ptr != NULL)
? same_keyid(a->authKeyID, b->authKeyID)
@@ -343,11 +350,10 @@ same_ocsp_location(const ocsp_location_t *a, const ocsp_location_t *b)
&& chunk_equals(a->uri, b->uri);
}
-/*
- * find an existing ocsp location in a chained list
+/**
+ * Find an existing ocsp location in a chained list
*/
-ocsp_location_t*
-get_ocsp_location(const ocsp_location_t * loc, ocsp_location_t *chain)
+ocsp_location_t* get_ocsp_location(const ocsp_location_t * loc, ocsp_location_t *chain)
{
while (chain != NULL)
@@ -359,12 +365,14 @@ get_ocsp_location(const ocsp_location_t * loc, ocsp_location_t *chain)
return NULL;
}
-/* retrieves the status of a cert from the ocsp cache
+/**
+ * Retrieves the status of a cert from the ocsp cache
* returns CERT_UNDEFINED if no status is found
*/
-static cert_status_t
-get_ocsp_status(const ocsp_location_t *loc, chunk_t serialNumber
- ,time_t *nextUpdate, time_t *revocationTime, crl_reason_t *revocationReason)
+static cert_status_t get_ocsp_status(const ocsp_location_t *loc,
+ chunk_t serialNumber,
+ time_t *nextUpdate, time_t *revocationTime,
+ crl_reason_t *revocationReason)
{
ocsp_certinfo_t *certinfo, **certinfop;
int cmp = -1;
@@ -399,12 +407,12 @@ get_ocsp_status(const ocsp_location_t *loc, chunk_t serialNumber
return CERT_UNDEFINED;
}
-/*
- * verify the ocsp status of a certificate
+/**
+ * Verify the ocsp status of a certificate
*/
-cert_status_t
-verify_by_ocsp(const x509cert_t *cert, time_t *until
-, time_t *revocationDate, crl_reason_t *revocationReason)
+cert_status_t verify_by_ocsp(const x509cert_t *cert, time_t *until,
+ time_t *revocationDate,
+ crl_reason_t *revocationReason)
{
cert_status_t status;
ocsp_location_t location;
@@ -434,11 +442,10 @@ verify_by_ocsp(const x509cert_t *cert, time_t *until
return status;
}
-/*
- * check if an ocsp status is about to expire
+/**
+ * Check if an ocsp status is about to expire
*/
-void
-check_ocsp(void)
+void check_ocsp(void)
{
ocsp_location_t *location;
@@ -485,21 +492,19 @@ check_ocsp(void)
unlock_ocsp_cache("check_ocsp");
}
-/*
+/**
* frees the allocated memory of a certinfo struct
*/
-static void
-free_certinfo(ocsp_certinfo_t *certinfo)
+static void free_certinfo(ocsp_certinfo_t *certinfo)
{
free(certinfo->serialNumber.ptr);
free(certinfo);
}
-/*
+/**
* frees all certinfos in a chained list
*/
-static void
-free_certinfos(ocsp_certinfo_t *chain)
+static void free_certinfos(ocsp_certinfo_t *chain)
{
ocsp_certinfo_t *certinfo;
@@ -511,11 +516,10 @@ free_certinfos(ocsp_certinfo_t *chain)
}
}
-/*
- * frees the memory allocated to an ocsp location including all certinfos
+/**
+ * Frees the memory allocated to an ocsp location including all certinfos
*/
-static void
-free_ocsp_location(ocsp_location_t* location)
+static void free_ocsp_location(ocsp_location_t* location)
{
free(location->issuer.ptr);
free(location->authNameID.ptr);
@@ -527,10 +531,9 @@ free_ocsp_location(ocsp_location_t* location)
}
/*
- * free a chained list of ocsp locations
+ * Free a chained list of ocsp locations
*/
-void
-free_ocsp_locations(ocsp_location_t **chain)
+void free_ocsp_locations(ocsp_location_t **chain)
{
while (*chain != NULL)
{
@@ -540,33 +543,30 @@ free_ocsp_locations(ocsp_location_t **chain)
}
}
-/*
- * free the ocsp cache
+/**
+ * Free the ocsp cache
*/
-void
-free_ocsp_cache(void)
+void free_ocsp_cache(void)
{
lock_ocsp_cache("free_ocsp_cache");
free_ocsp_locations(&ocsp_cache);
unlock_ocsp_cache("free_ocsp_cache");
}
-/*
- * frees the ocsp cache and global variables
+/**
+ * Frees the ocsp cache and global variables
*/
-void
-free_ocsp(void)
+void free_ocsp(void)
{
free(ocsp_default_uri.ptr);
free_ocsp_cache();
}
-/*
- * list a chained list of ocsp_locations
+/**
+ * List a chained list of ocsp_locations
*/
-void
-list_ocsp_locations(ocsp_location_t *location, bool requests, bool utc
-, bool strict)
+void list_ocsp_locations(ocsp_location_t *location, bool requests,
+ bool utc, bool strict)
{
bool first = TRUE;
@@ -644,19 +644,17 @@ list_ocsp_locations(ocsp_location_t *location, bool requests, bool utc
}
}
-/*
- * list the ocsp cache
+/**
+ * List the ocsp cache
*/
-void
-list_ocsp_cache(bool utc, bool strict)
+void list_ocsp_cache(bool utc, bool strict)
{
lock_ocsp_cache("list_ocsp_cache");
list_ocsp_locations(ocsp_cache, FALSE, utc, strict);
unlock_ocsp_cache("list_ocsp_cache");
}
-static bool
-get_ocsp_requestor_cert(ocsp_location_t *location)
+static bool get_ocsp_requestor_cert(ocsp_location_t *location)
{
x509cert_t *cert = NULL;
@@ -718,9 +716,8 @@ get_ocsp_requestor_cert(ocsp_location_t *location)
return FALSE;
}
-static chunk_t
-generate_signature(chunk_t digest, smartcard_t *sc
- , const RSA_private_key_t *pri)
+static chunk_t generate_signature(chunk_t digest, smartcard_t *sc,
+ const RSA_private_key_t *pri)
{
chunk_t sigdata;
u_char *pos;
@@ -750,7 +747,7 @@ generate_signature(chunk_t digest, smartcard_t *sc
, (int)sc->slot, sc->id)
)
- pos = build_asn1_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
+ pos = asn1_build_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
*pos++ = 0x00;
scx_sign_hash(sc, digest.ptr, digest.len, pos, siglen);
if (!pkcs11_keep_state)
@@ -760,20 +757,18 @@ generate_signature(chunk_t digest, smartcard_t *sc
{
/* RSA signature is done in software */
siglen = pri->pub.k;
- pos = build_asn1_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
+ pos = asn1_build_object(&sigdata, ASN1_BIT_STRING, 1 + siglen);
*pos++ = 0x00;
sign_hash(pri, digest.ptr, digest.len, pos, siglen);
}
return sigdata;
}
-/*
- * build signature into ocsp request
- * gets built only if a request cert with
- * a corresponding private key is found
+/**
+ * build signature into ocsp request gets built only if a request cert
+ * with a corresponding private key is found
*/
-static chunk_t
-build_signature(chunk_t tbsRequest)
+static chunk_t build_signature(chunk_t tbsRequest)
{
chunk_t sigdata, certs;
chunk_t digest_info;
@@ -788,7 +783,7 @@ build_signature(chunk_t tbsRequest)
* an ASN.1 structure for encryption
*/
digest_info = asn1_wrap(ASN1_SEQUENCE, "cm"
- , ASN1_sha1_id
+ , asn1_algorithmIdentifier(OID_SHA1)
, asn1_simple_object(ASN1_OCTET_STRING, digest_raw));
/* generate the RSA signature */
@@ -811,21 +806,21 @@ build_signature(chunk_t tbsRequest)
/* build signature comprising algorithm, signature and cert */
return asn1_wrap(ASN1_CONTEXT_C_0, "m"
, asn1_wrap(ASN1_SEQUENCE, "cmm"
- , ASN1_sha1WithRSA_id
+ , asn1_algorithmIdentifier(OID_SHA1_WITH_RSA)
, sigdata
, certs
)
);
}
-/* build request (into requestList)
+/**
+ * Build request (into requestList)
* no singleRequestExtensions used
*/
-static chunk_t
-build_request(ocsp_location_t *location, ocsp_certinfo_t *certinfo)
+static chunk_t build_request(ocsp_location_t *location, ocsp_certinfo_t *certinfo)
{
chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm"
- , ASN1_sha1_id
+ , asn1_algorithmIdentifier(OID_SHA1)
, asn1_simple_object(ASN1_OCTET_STRING, location->authNameID)
, asn1_simple_object(ASN1_OCTET_STRING, location->authKeyID)
, asn1_simple_object(ASN1_INTEGER, certinfo->serialNumber));
@@ -833,11 +828,10 @@ build_request(ocsp_location_t *location, ocsp_certinfo_t *certinfo)
return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
}
-/*
+/**
* build requestList (into TBSRequest)
*/
-static chunk_t
-build_request_list(ocsp_location_t *location)
+static chunk_t build_request_list(ocsp_location_t *location)
{
chunk_t requestList;
request_list_t *reqs = NULL;
@@ -862,8 +856,7 @@ build_request_list(ocsp_location_t *location)
certinfo = certinfo->next;
}
- pos = build_asn1_object(&requestList, ASN1_SEQUENCE
- , datalen);
+ pos = asn1_build_object(&requestList, ASN1_SEQUENCE, datalen);
/* copy all in chained list, free list afterwards */
while (reqs != NULL)
@@ -878,22 +871,20 @@ build_request_list(ocsp_location_t *location)
return requestList;
}
-/*
- * build requestorName (into TBSRequest)
+/**
+ * Build requestorName (into TBSRequest)
*/
-static chunk_t
-build_requestor_name(void)
+static chunk_t build_requestor_name(void)
{
return asn1_wrap(ASN1_CONTEXT_C_1, "m"
, asn1_simple_object(ASN1_CONTEXT_C_4
, ocsp_requestor_cert->subject));
}
-/*
+/**
* build nonce extension (into requestExtensions)
*/
-static chunk_t
-build_nonce_extension(ocsp_location_t *location)
+static chunk_t build_nonce_extension(ocsp_location_t *location)
{
/* generate a random nonce */
location->nonce.ptr = malloc(NONCE_LENGTH),
@@ -905,11 +896,10 @@ build_nonce_extension(ocsp_location_t *location)
, asn1_simple_object(ASN1_OCTET_STRING, location->nonce));
}
-/*
- * build requestExtensions (into TBSRequest)
+/**
+ * Build requestExtensions (into TBSRequest)
*/
-static chunk_t
-build_request_ext(ocsp_location_t *location)
+static chunk_t build_request_ext(ocsp_location_t *location)
{
return asn1_wrap(ASN1_CONTEXT_C_2, "m"
, asn1_wrap(ASN1_SEQUENCE, "mm"
@@ -922,11 +912,10 @@ build_request_ext(ocsp_location_t *location)
);
}
-/*
- * build TBSRequest (into OCSPRequest)
+/**
+ * Build TBSRequest (into OCSPRequest)
*/
-static chunk_t
-build_tbs_request(ocsp_location_t *location, bool has_requestor_cert)
+static chunk_t build_tbs_request(ocsp_location_t *location, bool has_requestor_cert)
{
/* version is skipped since the default is ok */
return asn1_wrap(ASN1_SEQUENCE, "mmm"
@@ -937,11 +926,11 @@ build_tbs_request(ocsp_location_t *location, bool has_requestor_cert)
, build_request_ext(location));
}
-/* assembles an ocsp request to given location
+/**
+ * Assembles an ocsp request to given location
* and sets nonce field in location to the sent nonce
*/
-chunk_t
-build_ocsp_request(ocsp_location_t *location)
+chunk_t build_ocsp_request(ocsp_location_t *location)
{
bool has_requestor_cert;
chunk_t tbsRequest, signature;
@@ -977,11 +966,10 @@ build_ocsp_request(ocsp_location_t *location)
, signature);
}
-/*
- * check if the OCSP response has a valid signature
+/**
+ * Check if the OCSP response has a valid signature
*/
-static bool
-valid_ocsp_response(response_t *res)
+static bool valid_ocsp_response(response_t *res)
{
int pathlen;
x509cert_t *authcert;
@@ -1086,27 +1074,25 @@ valid_ocsp_response(response_t *res)
return FALSE;
}
-/*
- * parse a basic OCSP response
+/**
+ * Parse a basic OCSP response
*/
-static bool
-parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
+static bool parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
{
- asn1_ctx_t ctx;
- bool critical;
+ asn1_parser_t *parser;
chunk_t object;
- u_int level, version;
+ u_int version;
u_char buf[BUF_LEN];
- int objectID = 0;
+ int objectID;
int extn_oid = OID_UNKNOWN;
+ bool success = FALSE;
+ bool critical;
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+ parser = asn1_parser_create(basicResponseObjects, blob);
+ parser->set_top_level(parser, level0);
- while (objectID < BASIC_RESPONSE_ROOF)
+ while (parser->iterate(parser, &objectID, &object))
{
- if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
switch (objectID)
{
case BASIC_RESPONSE_TBS_DATA:
@@ -1117,7 +1103,7 @@ parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
if (version != OCSP_BASIC_RESPONSE_VERSION)
{
plog("wrong ocsp basic response version (version= %i)", version);
- return FALSE;
+ goto end;
}
break;
case BASIC_RESPONSE_ID_BY_NAME:
@@ -1131,7 +1117,7 @@ parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
res->responder_id_key = object;
break;
case BASIC_RESPONSE_PRODUCED_AT:
- res->produced_at = asn1totime(&object, ASN1_GENERALIZEDTIME);
+ res->produced_at = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
break;
case BASIC_RESPONSE_RESPONSES:
res->responses = object;
@@ -1150,7 +1136,8 @@ parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
res->nonce = object;
break;
case BASIC_RESPONSE_ALGORITHM:
- res->algorithm = parse_algorithmIdentifier(object, level+1, NULL);
+ res->algorithm = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, NULL);
break;
case BASIC_RESPONSE_SIGNATURE:
res->signature = object;
@@ -1162,7 +1149,7 @@ parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
*cert = empty_x509cert;
- if (parse_x509cert(blob, level+1, cert)
+ if (parse_x509cert(blob, parser->get_level(parser)+1, cert)
&& cert->isOcspSigner
&& trust_authcert_candidate(cert, NULL))
{
@@ -1178,32 +1165,32 @@ parse_basic_ocsp_response(chunk_t blob, int level0, response_t *res)
}
break;
}
- objectID++;
}
- return TRUE;
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
+
}
-/*
- * parse an ocsp response and return the result as a response_t struct
+/**
+ * Parse an ocsp response and return the result as a response_t struct
*/
-static response_status
-parse_ocsp_response(chunk_t blob, response_t * res)
+static response_status parse_ocsp_response(chunk_t blob, response_t * res)
{
- asn1_ctx_t ctx;
+ asn1_parser_t *parser;
chunk_t object;
- u_int level;
- int objectID = 0;
+ int objectID;
int ocspResponseType = OID_UNKNOWN;
+ bool success = FALSE;
response_status rStatus = STATUS_INTERNALERROR;
- asn1_init(&ctx, blob, 0, FALSE, DBG_RAW);
+ parser = asn1_parser_create(ocspResponseObjects, blob);
- while (objectID < OCSP_RESPONSE_ROOF)
+ while (parser->iterate(parser, &objectID, &object))
{
- if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx))
- return STATUS_INTERNALERROR;
-
switch (objectID) {
case OCSP_RESPONSE_STATUS:
rStatus = (response_status) *object.ptr;
@@ -1219,9 +1206,9 @@ parse_ocsp_response(chunk_t blob, response_t * res)
case STATUS_UNAUTHORIZED:
plog("ocsp response: server said '%s'"
, response_status_names[rStatus]);
- return rStatus;
+ goto end;
default:
- return STATUS_INTERNALERROR;
+ goto end;
}
break;
case OCSP_RESPONSE_TYPE:
@@ -1231,47 +1218,50 @@ parse_ocsp_response(chunk_t blob, response_t * res)
{
switch (ocspResponseType) {
case OID_BASIC:
- if (!parse_basic_ocsp_response(object, level+1, res))
- return STATUS_INTERNALERROR;
+ success = parse_basic_ocsp_response(object,
+ parser->get_level(parser)+1, res);
break;
default:
DBG(DBG_CONTROL,
DBG_log("ocsp response is not of type BASIC");
DBG_dump_chunk("ocsp response OID: ", object);
)
- return STATUS_INTERNALERROR;
+ goto end;
}
}
break;
}
- objectID++;
}
+ success &= parser->success(parser);
+
+end:
+ parser->destroy(parser);
return rStatus;
}
-/*
- * parse a basic OCSP response
+/**
+ * Parse a basic OCSP response
*/
-static bool
-parse_ocsp_single_response(chunk_t blob, int level0, single_response_t *sres)
+static bool parse_ocsp_single_response(chunk_t blob, int level0,
+ single_response_t *sres)
{
- u_int level, extn_oid;
- asn1_ctx_t ctx;
- bool critical;
+ asn1_parser_t *parser;
chunk_t object;
- int objectID = 0;
+ u_int extn_oid;
+ int objectID;
+ bool critical;
+ bool success = FALSE;
- asn1_init(&ctx, blob, level0, FALSE, DBG_RAW);
+ parser = asn1_parser_create(singleResponseObjects, blob);
+ parser->set_top_level(parser, level0);
- while (objectID < SINGLE_RESPONSE_ROOF)
+ while (parser->iterate(parser, &objectID, &object))
{
- if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
switch (objectID)
{
case SINGLE_RESPONSE_ALGORITHM:
- sres->hash_algorithm = parse_algorithmIdentifier(object, level+1, NULL);
+ sres->hash_algorithm = asn1_parse_algorithmIdentifier(object,
+ parser->get_level(parser)+1, NULL);
break;
case SINGLE_RESPONSE_ISSUER_NAME_HASH:
sres->issuer_name_hash = object;
@@ -1289,7 +1279,7 @@ parse_ocsp_single_response(chunk_t blob, int level0, single_response_t *sres)
sres->status = CERT_REVOKED;
break;
case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
- sres->revocationTime = asn1totime(&object, ASN1_GENERALIZEDTIME);
+ sres->revocationTime = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
break;
case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
sres->revocationReason = (object.len == 1)
@@ -1299,10 +1289,10 @@ parse_ocsp_single_response(chunk_t blob, int level0, single_response_t *sres)
sres->status = CERT_UNKNOWN;
break;
case SINGLE_RESPONSE_THIS_UPDATE:
- sres->thisUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
+ sres->thisUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
break;
case SINGLE_RESPONSE_NEXT_UPDATE:
- sres->nextUpdate = asn1totime(&object, ASN1_GENERALIZEDTIME);
+ sres->nextUpdate = asn1_to_time(&object, ASN1_GENERALIZEDTIME);
break;
case SINGLE_RESPONSE_EXT_ID:
extn_oid = asn1_known_oid(object);
@@ -1315,16 +1305,17 @@ parse_ocsp_single_response(chunk_t blob, int level0, single_response_t *sres)
case SINGLE_RESPONSE_EXT_VALUE:
break;
}
- objectID++;
}
- return TRUE;
+ success = parser->success(parser);
+ parser->destroy(parser);
+ return success;
}
-/*
- * add an ocsp location to a chained list
+/**
+ * Add an ocsp location to a chained list
*/
-ocsp_location_t*
-add_ocsp_location(const ocsp_location_t *loc, ocsp_location_t **chain)
+ocsp_location_t* add_ocsp_location(const ocsp_location_t *loc,
+ ocsp_location_t **chain)
{
ocsp_location_t *location = malloc_thing(ocsp_location_t);
@@ -1347,12 +1338,11 @@ add_ocsp_location(const ocsp_location_t *loc, ocsp_location_t **chain)
return location;
}
-/*
+/**
* add a certinfo struct to a chained list
*/
-void
-add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info, ocsp_location_t **chain
- , bool request)
+void add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info,
+ ocsp_location_t **chain, bool request)
{
ocsp_location_t *location;
ocsp_certinfo_t *certinfo, **certinfop;
@@ -1362,7 +1352,9 @@ add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info, ocsp_location_t **chai
location = get_ocsp_location(loc, *chain);
if (location == NULL)
+ {
location = add_ocsp_location(loc, chain);
+ }
/* traverse list of certinfos in increasing order */
certinfop = &location->certinfo;
@@ -1404,8 +1396,9 @@ add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info, ocsp_location_t **chai
certinfo->status = CERT_UNDEFINED;
if (cmp != 0)
+ {
certinfo->thisUpdate = now;
-
+ }
certinfo->nextUpdate = UNDEFINED_TIME;
}
else
@@ -1424,11 +1417,11 @@ add_certinfo(ocsp_location_t *loc, ocsp_certinfo_t *info, ocsp_location_t **chai
}
}
-/*
- * process received ocsp single response and add it to ocsp cache
+/**
+ * Process received ocsp single response and add it to ocsp cache
*/
-static void
-process_single_response(ocsp_location_t *location, single_response_t *sres)
+static void process_single_response(ocsp_location_t *location,
+ single_response_t *sres)
{
ocsp_certinfo_t *certinfo, **certinfop;
int cmp = -1;
@@ -1481,14 +1474,12 @@ process_single_response(ocsp_location_t *location, single_response_t *sres)
/* free certinfo unlinked from ocsp fetch request list */
free_certinfo(certinfo);
-
}
-/*
- * parse and verify ocsp response and update the ocsp cache
+/**
+ * Parse and verify ocsp response and update the ocsp cache
*/
-void
-parse_ocsp(ocsp_location_t *location, chunk_t blob)
+void parse_ocsp(ocsp_location_t *location, chunk_t blob)
{
response_t res = empty_response;
@@ -1523,28 +1514,27 @@ parse_ocsp(ocsp_location_t *location, chunk_t blob)
/* now parse the single responses one at a time */
{
- u_int level;
- asn1_ctx_t ctx;
+ asn1_parser_t *parser;
chunk_t object;
- int objectID = 0;
+ int objectID;
- asn1_init(&ctx, res.responses, 0, FALSE, DBG_RAW);
+ parser = asn1_parser_create(responsesObjects, res.responses);
- while (objectID < RESPONSES_ROOF)
+ while (parser->iterate(parser, &objectID, &object))
{
- if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
- return;
-
if (objectID == RESPONSES_SINGLE_RESPONSE)
{
single_response_t sres = empty_single_response;
- if (parse_ocsp_single_response(object, level+1, &sres))
+ if (!parse_ocsp_single_response(object,
+ parser->get_level(parser)+1, &sres))
{
- process_single_response(location, &sres);
+ goto end;
}
+ process_single_response(location, &sres);
}
- objectID++;
}
+end:
+ parser->destroy(parser);
}
}