summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornelson%bolyard.com <devnull@localhost>2009-03-21 01:40:36 +0000
committernelson%bolyard.com <devnull@localhost>2009-03-21 01:40:36 +0000
commitff57936293dc3b0c3c243e0a0ed8cc95e4af16f5 (patch)
tree0b85b04c955878ff13e4e7bebf8d5b230e8e76d9
parentcf3739d3301cd51658ca24332a315161ef5d1278 (diff)
downloadnss-hg-ff57936293dc3b0c3c243e0a0ed8cc95e4af16f5.tar.gz
Bug 483168: Embed a list of default OCSP Responder URLs for certain CAs
r= Honza Bombas, Julien Pierre
-rw-r--r--security/nss/lib/certdb/certt.h6
-rw-r--r--security/nss/lib/certhigh/ocsp.c43
-rw-r--r--security/nss/lib/certhigh/ocsp.h18
-rw-r--r--security/nss/lib/nss/nss.def1
4 files changed, 66 insertions, 2 deletions
diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h
index 7fd8781e2..a0b533576 100644
--- a/security/nss/lib/certdb/certt.h
+++ b/security/nss/lib/certdb/certt.h
@@ -1253,6 +1253,12 @@ typedef enum CertStrictnessLevels {
#define CERT_ENABLE_LDAP_FETCH 1
#define CERT_ENABLE_HTTP_FETCH 2
+/* This functin pointer type may be used for any function that takes
+ * a CERTCertificate * and returns an allocated string, which must be
+ * freed by a call to PORT_Free.
+ */
+typedef char * (*CERT_StringFromCertFcn)(CERTCertificate *cert);
+
/* XXX Lisa thinks the template declarations belong in cert.h, not here? */
#include "secasn1t.h" /* way down here because I expect template stuff to
diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c
index 28b84dc7d..d47aa8312 100644
--- a/security/nss/lib/certhigh/ocsp.c
+++ b/security/nss/lib/certhigh/ocsp.c
@@ -120,6 +120,7 @@ static struct OCSPGlobalStruct {
PRUint32 timeoutSeconds;
OCSPCacheData cache;
SEC_OcspFailureMode ocspFailureMode;
+ CERT_StringFromCertFcn alternateOCSPAIAFcn;
} OCSP_Global = { NULL,
NULL,
DEFAULT_OCSP_CACHE_SIZE,
@@ -127,9 +128,12 @@ static struct OCSPGlobalStruct {
DEFAULT_MAXIMUM_SECONDS_TO_NEXT_OCSP_FETCH_ATTEMPT,
DEFAULT_OSCP_TIMEOUT_SECONDS,
{NULL, 0, NULL, NULL},
- ocspMode_FailureIsVerificationFailure
+ ocspMode_FailureIsVerificationFailure,
+ NULL
};
+
+
/* Forward declarations */
static SECItem *
ocsp_GetEncodedOCSPResponseFromRequest(PRArenaPool *arena,
@@ -288,6 +292,27 @@ SEC_RegisterDefaultHttpClient(const SEC_HttpClientFcn *fcnTable)
return SECSuccess;
}
+SECStatus
+CERT_RegisterAlternateOCSPAIAInfoCallBack(
+ CERT_StringFromCertFcn newCallback,
+ CERT_StringFromCertFcn * oldCallback)
+{
+ CERT_StringFromCertFcn old;
+
+ if (!OCSP_Global.monitor) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return SECFailure;
+ }
+
+ PR_EnterMonitor(OCSP_Global.monitor);
+ old = OCSP_Global.alternateOCSPAIAFcn;
+ OCSP_Global.alternateOCSPAIAFcn = newCallback;
+ PR_ExitMonitor(OCSP_Global.monitor);
+ if (oldCallback)
+ *oldCallback = old;
+ return SECSuccess;
+}
+
static PLHashNumber PR_CALLBACK
ocsp_CacheKeyHashFunction(const void *key)
{
@@ -4489,6 +4514,7 @@ ocsp_GetResponderLocation(CERTCertDBHandle *handle, CERTCertificate *cert,
PRBool canUseDefault, PRBool *isDefault)
{
ocspCheckingContext *ocspcx = NULL;
+ char *ocspUrl = NULL;
if (canUseDefault) {
ocspcx = ocsp_GetCheckingContext(handle);
@@ -4510,7 +4536,20 @@ ocsp_GetResponderLocation(CERTCertDBHandle *handle, CERTCertificate *cert,
* extension that has a value for OCSP, and get the url from that.
*/
*isDefault = PR_FALSE;
- return CERT_GetOCSPAuthorityInfoAccessLocation(cert);
+ ocspUrl = CERT_GetOCSPAuthorityInfoAccessLocation(cert);
+ if (!ocspUrl) {
+ CERT_StringFromCertFcn altFcn;
+
+ PR_EnterMonitor(OCSP_Global.monitor);
+ altFcn = OCSP_Global.alternateOCSPAIAFcn;
+ PR_ExitMonitor(OCSP_Global.monitor);
+ if (altFcn) {
+ ocspUrl = (*altFcn)(cert);
+ if (ocspUrl)
+ *isDefault = PR_TRUE;
+ }
+ }
+ return ocspUrl;
}
/*
diff --git a/security/nss/lib/certhigh/ocsp.h b/security/nss/lib/certhigh/ocsp.h
index 8095f9c1a..08f0dab83 100644
--- a/security/nss/lib/certhigh/ocsp.h
+++ b/security/nss/lib/certhigh/ocsp.h
@@ -457,6 +457,24 @@ extern char *
CERT_GetOCSPAuthorityInfoAccessLocation(CERTCertificate *cert);
/*
+ * FUNCTION: CERT_RegisterAlternateOCSPAIAInfoCallBack
+ * This function serves two purposes.
+ * 1) It registers the address of a callback function that will be
+ * called for certs that have no OCSP AIA extension, to see if the
+ * callback wishes to supply an alternative URL for such an OCSP inquiry.
+ * 2) It outputs the previously registered function's address to the
+ * address supplied by the caller, unless that is NULL.
+ * The registered callback function returns NULL, or an allocated string
+ * that may be subsequently freed by calling PORT_Free().
+ * RETURN:
+ * SECSuccess or SECFailure (if the library is not yet intialized)
+ */
+extern SECStatus
+CERT_RegisterAlternateOCSPAIAInfoCallBack(
+ CERT_StringFromCertFcn newCallback,
+ CERT_StringFromCertFcn * oldCallback);
+
+/*
* FUNCTION: CERT_ParseURL
* Parse the URI of a OCSP responder into hostname, port, and path.
* INPUTS:
diff --git a/security/nss/lib/nss/nss.def b/security/nss/lib/nss/nss.def
index af44d0726..84d495e28 100644
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -967,6 +967,7 @@ PK11_FindCertFromDERCertItem;
;+NSS_3.12.3 { # NSS 3.12.3 release
;+ global:
CERT_CompareCerts;
+CERT_RegisterAlternateOCSPAIAInfoCallBack;
PK11_GetSymKeyHandle;
;+ local:
;+ *;