Skip to content
This repository has been archived by the owner on Jun 30, 2022. It is now read-only.

Commit

Permalink
Bug 1308026 - JSS certificate validation does not pass up exact error…
Browse files Browse the repository at this point in the history
… from NSS, r=edewata

A new CryptoManager.verifyCertificate() method has been added as
an alternative to isCertValid(). If the specified certificate is
invalid, the new method will throw a CertificateException containing
the actual NSS error code and a description instead of just a boolean
value returned by the old method. The exception itself will also
help locate the error for troubleshooting.
Patch contributed by Endi S. Edewata <[email protected]>
  • Loading branch information
edewata committed Mar 8, 2017
1 parent 6b52d3a commit 20cad63
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 38 deletions.
1 change: 1 addition & 0 deletions lib/jss.def
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ Java_org_mozilla_jss_pkcs11_PK11KeyPairGenerator_generateDSAKeyPairWithOpFlags;
Java_org_mozilla_jss_CryptoManager_OCSPCacheSettingsNative;
Java_org_mozilla_jss_CryptoManager_setOCSPTimeoutNative;
Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative;
Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2;
Java_org_mozilla_jss_CryptoManager_verifyCertificateNowCUNative;
Java_org_mozilla_jss_asn1_ASN1Util_getTagDescriptionByOid;
Java_org_mozilla_jss_ssl_SocketBase_setSSLVersionRange;
Expand Down
64 changes: 64 additions & 0 deletions org/mozilla/jss/CryptoManager.c
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,70 @@ Java_org_mozilla_jss_CryptoManager_initializeAllNative
jboolean PK11Reload,
jboolean noPK11Finalize,
jboolean cooperate)
{
Java_org_mozilla_jss_CryptoManager_initializeAllNative2(
env,
clazz,
configDir,
certPrefix,
keyPrefix,
secmodName,
readOnly,
manuString,
libraryString,
tokString,
keyTokString,
slotString,
keySlotString,
fipsString,
fipsKeyString,
ocspCheckingEnabled,
ocspResponderURL,
ocspResponderCertNickname,
JNI_FALSE, /*initializeJavaOnly*/
PKIXVerify,
noCertDB,
noModDB,
forceOpen,
noRootInit,
optimizeSpace,
PK11ThreadSafe,
PK11Reload,
noPK11Finalize,
cooperate);
}


JNIEXPORT void JNICALL
Java_org_mozilla_jss_CryptoManager_initializeAllNative2
(JNIEnv *env, jclass clazz,
jstring configDir,
jstring certPrefix,
jstring keyPrefix,
jstring secmodName,
jboolean readOnly,
jstring manuString,
jstring libraryString,
jstring tokString,
jstring keyTokString,
jstring slotString,
jstring keySlotString,
jstring fipsString,
jstring fipsKeyString,
jboolean ocspCheckingEnabled,
jstring ocspResponderURL,
jstring ocspResponderCertNickname,
jboolean initializeJavaOnly,
jboolean PKIXVerify,
jboolean noCertDB,
jboolean noModDB,
jboolean forceOpen,
jboolean noRootInit,
jboolean optimizeSpace,
jboolean PK11ThreadSafe,
jboolean PK11Reload,
jboolean noPK11Finalize,
jboolean cooperate)
{
SECStatus rv = SECFailure;
char *szConfigDir = NULL;
Expand Down
32 changes: 30 additions & 2 deletions org/mozilla/jss/CryptoManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -953,7 +953,7 @@ public static synchronized void initialize( InitializationValues values )
"Must set ocspResponderCertNickname");
}
}
initializeAllNative(values.configDir,
initializeAllNative2(values.configDir,
values.certPrefix,
values.keyPrefix,
values.secmodName,
Expand Down Expand Up @@ -1018,7 +1018,7 @@ public static synchronized void initialize( InitializationValues values )
}

private static native void
initializeAllNative(String configDir,
initializeAllNative2(String configDir,
String certPrefix,
String keyPrefix,
String secmodName,
Expand Down Expand Up @@ -1573,6 +1573,7 @@ private native int verifyCertificateNowCUNative(String nickname,
* @exception InvalidNicknameException If the nickname is null
* @exception ObjectNotFoundException If no certificate could be found
* with the given nickname.
* @deprecated Use verifyCertificate() instead
*/
public boolean isCertValid(String nickname, boolean checkSig,
CertificateUsage certificateUsage)
Expand Down Expand Up @@ -1600,9 +1601,36 @@ public boolean isCertValid(String nickname, boolean checkSig,
}
}

/**
* Verify a certificate that exists in the given cert database,
* check if it's valid and that we trust the issuer. Verify time
* against now.
* @param nickname nickname of the certificate to verify.
* @param checkSig verify the signature of the certificate
* @param certificateUsage see certificate usage defined to verify certificate
*
* @exception InvalidNicknameException If the nickname is null.
* @exception ObjectNotFoundException If no certificate could be found
* with the given nickname.
* @exception CertificateException If certificate is invalid.
*/
public void verifyCertificate(String nickname,
boolean checkSig,
CertificateUsage certificateUsage)
throws ObjectNotFoundException, InvalidNicknameException, CertificateException {
int usage = certificateUsage == null ? 0 : certificateUsage.getUsage();
verifyCertificateNowNative2(nickname, checkSig, usage);
}

private native boolean verifyCertificateNowNative(String nickname,
boolean checkSig, int certificateUsage) throws ObjectNotFoundException;

private native void verifyCertificateNowNative2(
String nickname,
boolean checkSig,
int certificateUsage)
throws ObjectNotFoundException, InvalidNicknameException, CertificateException;

/**
* note: this method calls obsolete function in NSS
*
Expand Down
99 changes: 99 additions & 0 deletions org/mozilla/jss/PK11Finder.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@
SECStatus
CERT_ImportCAChainTrusted(SECItem *certs, int numcerts, SECCertUsage certUsage);

/*
* This is a private function, used only by JSS in this file.
*/
JNIEXPORT void JNICALL
Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2(JNIEnv *env,
jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage);

/*****************************************************************
*
* CryptoManager. f i n d C e r t B y N i c k n a m e N a t i v e
Expand Down Expand Up @@ -1596,6 +1603,98 @@ Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative(JNIEnv *env,
}
}

/***********************************************************************
* CryptoManager.verifyCertificateNowNative2
*
* Verify a certificate that exists in the given cert database,
* check if it's valid and that we trust the issuer. Verify time
* against now.
* @param nickname nickname of the certificate to verify.
* @param checkSig verify the signature of the certificate
* @param certificateUsage see certificate usage defined to verify certificate
*
* @exception InvalidNicknameException If the nickname is null.
* @exception ObjectNotFoundException If no certificate could be found
* with the given nickname.
* @exception CertificateException If certificate is invalid.
*/
JNIEXPORT void JNICALL
Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative2(JNIEnv *env,
jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage)
{
jint certificateUsage;
SECCertificateUsage currUsage = 0x0000; /* unexposed for now */
SECStatus rv = SECFailure;
CERTCertificate *cert = NULL;
char *nickname = NULL;

if (nickString == NULL) {
JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname");
goto finish;
}

nickname = (char *) (*env)->GetStringUTFChars(env, nickString, NULL);
if (nickname == NULL) {
JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname");
goto finish;
}

certificateUsage = required_certificateUsage;
if (cert == NULL) {
JSS_throw(env, OBJECT_NOT_FOUND_EXCEPTION);
goto finish;
}

cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname);

if (cert == NULL) {
char *msgBuf;
msgBuf = PR_smprintf("Certificate not found: %s", nickname);
JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, msgBuf);
PR_Free(msgBuf);
goto finish;
}

/* 0 for certificateUsage in call to CERT_VerifyCertificateNow will
* retrieve the current valid usage into currUsage
*/
rv = CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), cert,
checkSig, certificateUsage, NULL, &currUsage);

if (rv != SECSuccess) {
JSS_throwMsgPrErr(env, CERTIFICATE_EXCEPTION, "Invalid certificate");
goto finish;
}

if ((certificateUsage == 0x0000) &&
(currUsage ==
( certUsageUserCertImport |
certUsageVerifyCA |
certUsageProtectedObjectSigner |
certUsageAnyCA ))) {

/* The certificate is good for nothing.
* The following usages cannot be verified:
* certUsageAnyCA
* certUsageProtectedObjectSigner
* certUsageUserCertImport
* certUsageVerifyCA
* (0x0b80)
*/

JSS_throwMsgPrErr(env, CERTIFICATE_EXCEPTION, "Unusable certificate");
goto finish;
}

finish:
if (nickname != NULL) {
(*env)->ReleaseStringUTFChars(env, nickString, nickname);
}
if (cert != NULL) {
CERT_DestroyCertificate(cert);
}
}


/***********************************************************************
* CryptoManager.verifyCertNowNative
Expand Down
39 changes: 3 additions & 36 deletions org/mozilla/jss/asn1/config.mk
Original file line number Diff line number Diff line change
@@ -1,39 +1,6 @@
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# 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 the Initial Developer are Copyright (C) 1998-2000
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
TARGETS=$(LIBRARY)
SHARED_LIBRARY=
IMPORT_LIBRARY=
Expand Down
2 changes: 2 additions & 0 deletions org/mozilla/jss/util/jss_exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ PR_BEGIN_EXTERN_C

#define INTERRUPTED_IO_EXCEPTION "java/io/InterruptedIOException"

#define INVALID_NICKNAME_EXCEPTION "org/mozilla/jss/util/InvalidNicknameException"

#define INVALID_KEY_FORMAT_EXCEPTION "org/mozilla/jss/crypto/InvalidKeyFormatException"

#define INVALID_PARAMETER_EXCEPTION "java/security/InvalidParameterException"
Expand Down

0 comments on commit 20cad63

Please sign in to comment.