163762 make OCSP responder configurable at runtime

This commit is contained in:
glen.beasley%sun.com 2002-08-27 21:46:13 +00:00
Родитель 2315bdca14
Коммит 81f5e0bbda
2 изменённых файлов: 312 добавлений и 221 удалений

Просмотреть файл

@ -1,27 +1,27 @@
/*
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
*
* The Original Code is the Netscape Security Services for Java.
*
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* "GPL"), in which case the provisions of the GPL are applicable
* instead of those above. If you wish to allow use of your
* version of this file only under the terms of the GPL and not to
* allow others to use your version of this file under the MPL,
* indicate your decision by deleting the provisions above and
@ -110,94 +110,118 @@ handleSigChild(JNIEnv *env) {
}
#endif
int ConfigureOCSP(
JNIEnv *env,
jboolean ocspCheckingEnabled,
int ConfigureOCSP(
JNIEnv *env,
jboolean ocspCheckingEnabled,
jstring ocspResponderURL,
jstring ocspResponderCertNickname )
{
char *ocspResponderURL_string=NULL;
char *ocspResponderCertNickname_string=NULL;
SECStatus status;
int result = SECSuccess;
char *ocspResponderURL_string=NULL;
char *ocspResponderCertNickname_string=NULL;
SECStatus status;
int result = SECSuccess;
CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
/* if caller specified default responder, get the
* strings associated with these args
*/
/* if caller specified default responder, get the
* strings associated with these args
*/
if (ocspResponderURL) {
ocspResponderURL_string =
(char*) (*env)->GetStringUTFChars(env, ocspResponderURL, NULL);
if (ocspResponderURL_string == NULL) {
JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION,
"OCSP invalid URL");
result = SECFailure;
goto loser;
}
if (ocspResponderURL) {
ocspResponderURL_string =
(char*) (*env)->GetStringUTFChars(env, ocspResponderURL, NULL);
if (ocspResponderURL_string == NULL) {
JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION,
"OCSP invalid URL");
result = SECFailure;
goto loser;
}
}
if (ocspResponderCertNickname) {
ocspResponderCertNickname_string =
(char*) (*env)->GetStringUTFChars(env, ocspResponderCertNickname, NULL);
if (ocspResponderCertNickname_string == NULL) {
JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION,
"OCSP invalid nickname");
result = SECFailure;
goto loser;
}
}
/* first disable OCSP - we'll enable it later */
CERT_DisableOCSPChecking(certdb);
/* if they set the default responder, then set it up
* and enable it
*/
if (ocspResponderURL) {
/* if ocspResponderURL is set they must specify the
ocspResponderCertNickname */
if (ocspResponderCertNickname == NULL ) {
JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION,
"if OCSP responderURL is set, the Responder Cert nickname must be set");
result = SECFailure;
goto loser;
} else {
CERTCertificate *cert;
/* if the nickname is set */
cert = CERT_FindCertByNickname(certdb, ocspResponderCertNickname_string);
if (cert == NULL) {
/*
* look for the cert on an external token.
*/
cert = PK11_FindCertFromNickname(ocspResponderCertNickname_string, NULL);
}
if (cert == NULL) {
JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION,
"Unable to find the OCSP Responder Certificate nickname.");
result = SECFailure;
goto loser;
}
}
status =
CERT_SetOCSPDefaultResponder( certdb,
ocspResponderURL_string,
ocspResponderCertNickname_string
);
if (status == SECFailure) {
/* deal with error */
JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION,
"OCSP Could not set responder");
result = SECFailure;
goto loser;
}
CERT_EnableOCSPDefaultResponder(certdb);
}
else {
/* if no defaultresponder is set, disable it */
CERT_DisableOCSPDefaultResponder(certdb);
}
if (ocspResponderCertNickname) {
ocspResponderCertNickname_string =
(char*) (*env)->GetStringUTFChars(env, ocspResponderCertNickname, NULL);
if (ocspResponderCertNickname_string == NULL) {
JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION,
"OCSP invalid nickname");
result = SECFailure;
goto loser;
}
}
/* enable OCSP checking if requested */
/* first disable OCSP - we'll enable it later */
CERT_DisableOCSPChecking(certdb);
/* if they set the default responder, then set it up
* and enable it
*/
if (ocspResponderURL) {
status =
CERT_SetOCSPDefaultResponder( certdb,
ocspResponderURL_string,
ocspResponderCertNickname_string
);
if (status == SECFailure) {
/* deal with error */
JSS_throwMsg(env, GENERAL_SECURITY_EXCEPTION,
"OCSP Could not set responder");
result = SECFailure;
goto loser;
}
CERT_EnableOCSPDefaultResponder(certdb);
}
else {
/* if no defaultresponder is set, disable it */
CERT_DisableOCSPDefaultResponder(certdb);
}
/* enable OCSP checking if requested */
if (ocspCheckingEnabled) {
CERT_EnableOCSPChecking(certdb);
}
if (ocspCheckingEnabled) {
CERT_EnableOCSPChecking(certdb);
}
loser:
if (ocspResponderURL_string) {
(*env)->ReleaseStringUTFChars(env,
ocspResponderURL, ocspResponderURL_string);
}
if (ocspResponderURL_string) {
(*env)->ReleaseStringUTFChars(env,
ocspResponderURL, ocspResponderURL_string);
}
if (ocspResponderCertNickname_string) {
(*env)->ReleaseStringUTFChars(env,
ocspResponderCertNickname, ocspResponderCertNickname_string);
}
if (ocspResponderCertNickname_string) {
(*env)->ReleaseStringUTFChars(env,
ocspResponderCertNickname, ocspResponderCertNickname_string);
}
return result;
return result;
}
@ -230,9 +254,9 @@ Java_org_mozilla_jss_CryptoManager_initializeAllNative
jstring keySlotString,
jstring fipsString,
jstring fipsKeyString,
jboolean ocspCheckingEnabled,
jstring ocspResponderURL,
jstring ocspResponderCertNickname )
jboolean ocspCheckingEnabled,
jstring ocspResponderURL,
jstring ocspResponderCertNickname )
{
Java_org_mozilla_jss_CryptoManager_initializeAllNative2(
env,
@ -250,12 +274,12 @@ Java_org_mozilla_jss_CryptoManager_initializeAllNative
keySlotString,
fipsString,
fipsKeyString,
ocspCheckingEnabled,
ocspResponderURL,
ocspResponderCertNickname,
ocspCheckingEnabled,
ocspResponderURL,
ocspResponderCertNickname,
JNI_FALSE /*initializeJavaOnly*/ );
}
JNIEXPORT void JNICALL
Java_org_mozilla_jss_CryptoManager_initializeAllNative2
@ -273,9 +297,9 @@ Java_org_mozilla_jss_CryptoManager_initializeAllNative2
jstring keySlotString,
jstring fipsString,
jstring fipsKeyString,
jboolean ocspCheckingEnabled,
jstring ocspResponderURL,
jstring ocspResponderCertNickname,
jboolean ocspCheckingEnabled,
jstring ocspResponderURL,
jstring ocspResponderCertNickname,
jboolean initializeJavaOnly )
{
SECStatus rv = SECFailure;
@ -321,7 +345,7 @@ Java_org_mozilla_jss_CryptoManager_initializeAllNative2
/*
* Save the JavaVM pointer so we can retrieve the JNI environment
* later. This only works if there is only one Java VM.
*/
*/
if( (*env)->GetJavaVM(env, &JSS_javaVM) != 0 ) {
JSS_trace(env, JSS_TRACE_ERROR,
"Unable to to access Java virtual machine");
@ -412,24 +436,24 @@ Java_org_mozilla_jss_CryptoManager_initializeAllNative2
goto finish;
}
/*
* Set default password callback. This is the only place this
* should ever be called if you are using Ninja.
/*
* Set default password callback. This is the only place this
* should ever be called if you are using Ninja.
*/
PK11_SetPasswordFunc(getPWFromCallback);
PK11_SetPasswordFunc(getPWFromCallback);
/*
* Setup NSS to call the specified OCSP responder
*/
rv = ConfigureOCSP(
env,
ocspCheckingEnabled,
/*
* Setup NSS to call the specified OCSP responder
*/
rv = ConfigureOCSP(
env,
ocspCheckingEnabled,
ocspResponderURL,
ocspResponderCertNickname );
if (rv != SECSuccess) {
goto finish;
}
if (rv != SECSuccess) {
goto finish;
}
/*
* Set up policy. We're always domestic now. Thanks to the US Government!
@ -472,7 +496,7 @@ finish:
}
/**********************************************************************
*
*
* JSS_setPasswordCallback
*
* Sets the global PasswordCallback object, which will be used to
@ -498,7 +522,7 @@ JSS_setPasswordCallback(JNIEnv *env, jobject callback)
}
/**********************************************************************
*
*
* CryptoManager.setNativePasswordCallback
*
* Sets the global PasswordCallback object, which will be used to
@ -535,24 +559,24 @@ Java_org_mozilla_jss_CryptoManager_setNativePasswordCallback
static char*
getPWFromCallback(PK11SlotInfo *slot, PRBool retry, void *arg)
{
jobject pwcbInfo;
jobject pwcbInfo;
jobject pwObject;
jbyteArray pwArray=NULL;
char* pwchars;
char* returnchars=NULL;
jclass callbackClass;
jbyteArray pwArray=NULL;
char* pwchars;
char* returnchars=NULL;
jclass callbackClass;
jclass passwordClass;
jmethodID getPWMethod;
jmethodID getPWMethod;
jmethodID getByteCopyMethod;
jmethodID clearMethod;
jthrowable exception;
jthrowable exception;
jobject callback;
JNIEnv *env;
JNIEnv *env;
PR_ASSERT(slot!=NULL);
if(slot==NULL) {
return NULL;
}
PR_ASSERT(slot!=NULL);
if(slot==NULL) {
return NULL;
}
/* Get the callback from the arg, or use the default */
PR_ASSERT(sizeof(void*) == sizeof(jobject));
@ -570,64 +594,64 @@ getPWFromCallback(PK11SlotInfo *slot, PRBool retry, void *arg)
PR_ASSERT(PR_FALSE);
goto finish;
}
PR_ASSERT(env != NULL);
PR_ASSERT(env != NULL);
/*****************************************
* Construct the JSS_PasswordCallbackInfo
*****************************************/
pwcbInfo = makePWCBInfo(env, slot);
if(pwcbInfo==NULL) {
goto finish;
}
/*****************************************
* Construct the JSS_PasswordCallbackInfo
*****************************************/
pwcbInfo = makePWCBInfo(env, slot);
if(pwcbInfo==NULL) {
goto finish;
}
/*****************************************
* Get the callback class and methods
*****************************************/
callbackClass = (*env)->GetObjectClass(env, callback);
/*****************************************
* Get the callback class and methods
*****************************************/
callbackClass = (*env)->GetObjectClass(env, callback);
if(callbackClass == NULL) {
JSS_trace(env, JSS_TRACE_ERROR, "Failed to find password "
"callback class");
PR_ASSERT(PR_FALSE);
PR_ASSERT(PR_FALSE);
}
if(retry) {
getPWMethod = (*env)->GetMethodID(
env,
callbackClass,
PW_CALLBACK_GET_PW_AGAIN_NAME,
PW_CALLBACK_GET_PW_AGAIN_SIG);
} else {
getPWMethod = (*env)->GetMethodID(
env,
callbackClass,
PW_CALLBACK_GET_PW_FIRST_NAME,
PW_CALLBACK_GET_PW_FIRST_SIG);
}
if(getPWMethod == NULL) {
if(retry) {
getPWMethod = (*env)->GetMethodID(
env,
callbackClass,
PW_CALLBACK_GET_PW_AGAIN_NAME,
PW_CALLBACK_GET_PW_AGAIN_SIG);
} else {
getPWMethod = (*env)->GetMethodID(
env,
callbackClass,
PW_CALLBACK_GET_PW_FIRST_NAME,
PW_CALLBACK_GET_PW_FIRST_SIG);
}
if(getPWMethod == NULL) {
JSS_trace(env, JSS_TRACE_ERROR,
"Failed to find password callback accessor method");
ASSERT_OUTOFMEM(env);
goto finish;
}
ASSERT_OUTOFMEM(env);
goto finish;
}
/*****************************************
* Get the password from the callback
*****************************************/
pwObject = (*env)->CallObjectMethod(
env,
callback,
getPWMethod,
pwcbInfo);
/*****************************************
* Get the password from the callback
*****************************************/
pwObject = (*env)->CallObjectMethod(
env,
callback,
getPWMethod,
pwcbInfo);
if( (*env)->ExceptionOccurred(env) != NULL) {
goto finish;
}
if( pwObject == NULL ) {
JSS_throw(env, GIVE_UP_EXCEPTION);
goto finish;
}
if( pwObject == NULL ) {
JSS_throw(env, GIVE_UP_EXCEPTION);
goto finish;
}
/*****************************************
* Get Password class and methods
*****************************************/
/*****************************************
* Get Password class and methods
*****************************************/
passwordClass = (*env)->GetObjectClass(env, pwObject);
if(passwordClass == NULL) {
JSS_trace(env, JSS_TRACE_ERROR, "Failed to find Password class");
@ -657,32 +681,32 @@ getPWFromCallback(PK11SlotInfo *slot, PRBool retry, void *arg)
pwArray = (*env)->CallObjectMethod( env, pwObject, getByteCopyMethod);
(*env)->CallVoidMethod(env, pwObject, clearMethod);
exception = (*env)->ExceptionOccurred(env);
if(exception == NULL) {
PR_ASSERT(pwArray != NULL);
exception = (*env)->ExceptionOccurred(env);
if(exception == NULL) {
PR_ASSERT(pwArray != NULL);
/*************************************************************
* Copy the characters out of the byte array,
* then erase it
*************************************************************/
pwchars = (char*) (*env)->GetByteArrayElements(env, pwArray, NULL);
PR_ASSERT(pwchars!=NULL);
/*************************************************************
* Copy the characters out of the byte array,
* then erase it
*************************************************************/
pwchars = (char*) (*env)->GetByteArrayElements(env, pwArray, NULL);
PR_ASSERT(pwchars!=NULL);
returnchars = PL_strdup(pwchars);
JSS_wipeCharArray(pwchars);
(*env)->ReleaseByteArrayElements(env, pwArray, (jbyte*)pwchars, 0);
} else {
returnchars = NULL;
}
returnchars = PL_strdup(pwchars);
JSS_wipeCharArray(pwchars);
(*env)->ReleaseByteArrayElements(env, pwArray, (jbyte*)pwchars, 0);
} else {
returnchars = NULL;
}
finish:
if( (exception=(*env)->ExceptionOccurred(env)) != NULL) {
if( (exception=(*env)->ExceptionOccurred(env)) != NULL) {
#ifdef DEBUG
jclass giveupClass;
jmethodID printStackTrace;
jclass excepClass;
#endif
(*env)->ExceptionClear(env);
(*env)->ExceptionClear(env);
#ifdef DEBUG
giveupClass = (*env)->FindClass(env, GIVE_UP_EXCEPTION);
PR_ASSERT(giveupClass != NULL);
@ -693,10 +717,10 @@ finish:
(*env)->CallVoidMethod(env, exception, printStackTrace);
PR_ASSERT( PR_FALSE );
}
PR_ASSERT(returnchars==NULL);
PR_ASSERT(returnchars==NULL);
#endif
}
return returnchars;
}
return returnchars;
}
/**********************************************************************
@ -709,54 +733,54 @@ finish:
static jobject
makePWCBInfo(JNIEnv *env, PK11SlotInfo *slot)
{
jclass infoClass;
jmethodID constructor;
jstring name;
jobject pwcbInfo=NULL;
jclass infoClass;
jmethodID constructor;
jstring name;
jobject pwcbInfo=NULL;
PR_ASSERT(env!=NULL && slot!=NULL);
PR_ASSERT(env!=NULL && slot!=NULL);
/*****************************************
/*****************************************
* Turn the token name into a Java String
*****************************************/
name = (*env)->NewStringUTF(env, PK11_GetTokenName(slot));
if(name == NULL) {
ASSERT_OUTOFMEM(env);
goto finish;
}
*****************************************/
name = (*env)->NewStringUTF(env, PK11_GetTokenName(slot));
if(name == NULL) {
ASSERT_OUTOFMEM(env);
goto finish;
}
/*****************************************
* Look up the class and constructor
*****************************************/
infoClass = (*env)->FindClass(env, TOKEN_CBINFO_CLASS_NAME);
if(infoClass == NULL) {
/*****************************************
* Look up the class and constructor
*****************************************/
infoClass = (*env)->FindClass(env, TOKEN_CBINFO_CLASS_NAME);
if(infoClass == NULL) {
JSS_trace(env, JSS_TRACE_ERROR, "Unable to find TokenCallbackInfo "
"class");
ASSERT_OUTOFMEM(env);
goto finish;
}
constructor = (*env)->GetMethodID( env,
infoClass,
TOKEN_CBINFO_CONSTRUCTOR_NAME,
TOKEN_CBINFO_CONSTRUCTOR_SIG);
if(constructor == NULL) {
ASSERT_OUTOFMEM(env);
goto finish;
}
constructor = (*env)->GetMethodID( env,
infoClass,
TOKEN_CBINFO_CONSTRUCTOR_NAME,
TOKEN_CBINFO_CONSTRUCTOR_SIG);
if(constructor == NULL) {
JSS_trace(env, JSS_TRACE_ERROR, "Unable to find "
"TokenCallbackInfo constructor");
ASSERT_OUTOFMEM(env);
goto finish;
}
ASSERT_OUTOFMEM(env);
goto finish;
}
/*****************************************
* Create the CallbackInfo object
*****************************************/
pwcbInfo = (*env)->NewObject(env, infoClass, constructor, name);
/*****************************************
* Create the CallbackInfo object
*****************************************/
pwcbInfo = (*env)->NewObject(env, infoClass, constructor, name);
if(pwcbInfo == NULL) {
JSS_trace(env, JSS_TRACE_ERROR, "Unable to create TokenCallbackInfo");
ASSERT_OUTOFMEM(env);
}
finish:
return pwcbInfo;
return pwcbInfo;
}
/**********************************************************************
@ -897,3 +921,28 @@ Java_org_mozilla_jss_DatabaseCloser_closeDatabases
{
NSS_Shutdown();
}
/**********************************************************************
* configureOCSPNative
*
* Allows configuration of the OCSP responder during runtime.
*/
JNIEXPORT void JNICALL
Java_org_mozilla_jss_CryptoManager_configureOCSPNative(
JNIEnv *env, jobject this,
jboolean ocspCheckingEnabled,
jstring ocspResponderURL,
jstring ocspResponderCertNickname )
{
SECStatus rv = SECFailure;
rv = ConfigureOCSP(env,ocspCheckingEnabled,
ocspResponderURL, ocspResponderCertNickname);
if (rv != SECSuccess) {
JSS_throwMsgPrErr(env,
GENERAL_SECURITY_EXCEPTION,
"Failed to configure OCSP");
}
}

Просмотреть файл

@ -52,7 +52,7 @@ import org.mozilla.jss.provider.java.security.JSSMessageDigestSpi;
* Initialization is done with static methods, and must be done before
* an instance can be created. All other operations are done with instance
* methods.
* @version $Revision: 1.11 $ $Date: 2002-08-14 23:00:45 $
* @version $Revision: 1.12 $ $Date: 2002-08-27 21:46:13 $
*/
public final class CryptoManager implements TokenSupplier
{
@ -62,19 +62,28 @@ public final class CryptoManager implements TokenSupplier
public final static class CertUsage {
private int usage;
private String name;
static private ArrayList list = new ArrayList();
private CertUsage() {};
private CertUsage(int usage, String name) {
this.usage = usage;
this.name = name;
this.list.add(this);
}
int getUsage() {
public int getUsage() {
return usage;
}
static public Iterator getCertUsages() {
return list.iterator();
}
public String toString() {
return name;
}
// certUsage, these must be kept in sync with nss/lib/certdb/certt.h
public static final CertUsage SSLClient = new CertUsage(0, "SSLClient");
public static final CertUsage SSLServer = new CertUsage(1, "SSLServer");
@ -731,6 +740,7 @@ public final class CryptoManager implements TokenSupplier
*/
public synchronized native boolean FIPSEnabled();
///////////////////////////////////////////////////////////////////////
// Password Callback management
///////////////////////////////////////////////////////////////////////
@ -1421,4 +1431,36 @@ public final class CryptoManager implements TokenSupplier
boolean checkSig, int cUsage)
throws TokenException, CertificateEncodingException;
///////////////////////////////////////////////////////////////////////
// OCSP management
///////////////////////////////////////////////////////////////////////
/**
* Enables OCSP, note when you Initialize JSS for the first time, for
* backwards compatibility, the initialize will enable OCSP if you
* previously set values.ocspCheckingEnabled and
* values.ocspResponderURL/values.ocspResponderCertNickname
* configureOCSP will allow changing of the the OCSPResponder at runtime.
* * @param ocspChecking true or false to enable/disable OCSP
* * @param ocspResponderURL - url of the OCSP responder
* * @param ocspResponderCertNickname - the nickname of the OCSP
* signer certificate or the CA certificate found in the cert DB
*/
public void configureOCSP(
boolean ocspCheckingEnabled,
String ocspResponderURL,
String ocspResponderCertNickname )
throws GeneralSecurityException
{
configureOCSPNative(ocspCheckingEnabled,
ocspResponderURL,
ocspResponderCertNickname );
}
private native void configureOCSPNative( boolean ocspCheckingEnabled,
String ocspResponderURL,
String ocspResponderCertNickname )
throws GeneralSecurityException;
}