|
|
f2c538 |
From 3c4ca8a2010889fe292704ebcc8b922f77f2f7c2 Mon Sep 17 00:00:00 2001
|
|
|
f2c538 |
From: "Endi S. Dewata" <edewata@redhat.com>
|
|
|
f2c538 |
Date: Wed, 9 Dec 2015 00:30:50 +0100
|
|
|
f2c538 |
Subject: [PATCH] Added verifyCertificate() method.
|
|
|
f2c538 |
|
|
|
f2c538 |
A new CryptoManager.verifyCertificate() method has been added as
|
|
|
f2c538 |
an alternative to isCertValid(). If there is a certificate
|
|
|
f2c538 |
validation problem, the method will throw a CertificateValidation
|
|
|
f2c538 |
exception that contains the NSS error message and code. The
|
|
|
f2c538 |
exception will also provide a stack trace to help troubleshoot
|
|
|
f2c538 |
validation issues.
|
|
|
f2c538 |
|
|
|
f2c538 |
https://fedorahosted.org/pki/ticket/850
|
|
|
f2c538 |
---
|
|
|
f2c538 |
.../jss/org/mozilla/jss/CryptoManager.java | 54 ++++++++------
|
|
|
f2c538 |
mozilla/security/jss/org/mozilla/jss/PK11Finder.c | 83 +++++++++++++++++++---
|
|
|
f2c538 |
.../jss/org/mozilla/jss/util/jss_exceptions.h | 2 +
|
|
|
f2c538 |
3 files changed, 110 insertions(+), 29 deletions(-)
|
|
|
f2c538 |
|
|
|
f2c538 |
diff --git a/mozilla/security/jss/org/mozilla/jss/CryptoManager.java b/mozilla/security/jss/org/mozilla/jss/CryptoManager.java
|
|
|
f2c538 |
index 0a4f59064bfddb42d473022550c24f251719d02b..54ffd8130b0e1f1fca49dd8b130a621e449c7ce7 100644
|
|
|
f2c538 |
--- a/mozilla/security/jss/org/mozilla/jss/CryptoManager.java
|
|
|
f2c538 |
+++ b/mozilla/security/jss/org/mozilla/jss/CryptoManager.java
|
|
|
f2c538 |
@@ -1515,30 +1515,44 @@ public final class CryptoManager implements TokenSupplier
|
|
|
f2c538 |
CertificateUsage certificateUsage)
|
|
|
f2c538 |
throws ObjectNotFoundException, InvalidNicknameException
|
|
|
f2c538 |
{
|
|
|
f2c538 |
- if (nickname==null) {
|
|
|
f2c538 |
- throw new InvalidNicknameException("Nickname must be non-null");
|
|
|
f2c538 |
- }
|
|
|
f2c538 |
- // 0 certificate usage will get current usage
|
|
|
f2c538 |
- // should call isCertValid() call above that returns certificate usage
|
|
|
f2c538 |
- if ((certificateUsage == null) ||
|
|
|
f2c538 |
- (certificateUsage == CertificateUsage.CheckAllUsages)){
|
|
|
f2c538 |
- int currCertificateUsage = 0x0000;
|
|
|
f2c538 |
- currCertificateUsage = verifyCertificateNowCUNative(nickname,
|
|
|
f2c538 |
- checkSig);
|
|
|
f2c538 |
+ try {
|
|
|
f2c538 |
+ verifyCertificate(nickname, checkSig, certificateUsage);
|
|
|
f2c538 |
+ return true;
|
|
|
f2c538 |
+
|
|
|
f2c538 |
+ } catch (ObjectNotFoundException | InvalidNicknameException e) {
|
|
|
f2c538 |
+ throw e;
|
|
|
f2c538 |
|
|
|
f2c538 |
- if (currCertificateUsage == CertificateUsage.basicCertificateUsages){
|
|
|
f2c538 |
- // cert is good for nothing
|
|
|
f2c538 |
- return false;
|
|
|
f2c538 |
- } else
|
|
|
f2c538 |
- return true;
|
|
|
f2c538 |
- } else {
|
|
|
f2c538 |
- return verifyCertificateNowNative(nickname, checkSig,
|
|
|
f2c538 |
- certificateUsage.getUsage());
|
|
|
f2c538 |
+ } catch (CertificateException e) {
|
|
|
f2c538 |
+ return false;
|
|
|
f2c538 |
}
|
|
|
f2c538 |
}
|
|
|
f2c538 |
|
|
|
f2c538 |
- private native boolean verifyCertificateNowNative(String nickname,
|
|
|
f2c538 |
- boolean checkSig, int certificateUsage) throws ObjectNotFoundException;
|
|
|
f2c538 |
+ /**
|
|
|
f2c538 |
+ * Verify a certificate that exists in the given cert database,
|
|
|
f2c538 |
+ * check if it's valid and that we trust the issuer. Verify time
|
|
|
f2c538 |
+ * against now.
|
|
|
f2c538 |
+ * @param nickname nickname of the certificate to verify.
|
|
|
f2c538 |
+ * @param checkSig verify the signature of the certificate
|
|
|
f2c538 |
+ * @param certificateUsage see certificate usage defined to verify certificate
|
|
|
f2c538 |
+ *
|
|
|
f2c538 |
+ * @exception InvalidNicknameException If the nickname is null.
|
|
|
f2c538 |
+ * @exception ObjectNotFoundException If no certificate could be found
|
|
|
f2c538 |
+ * with the given nickname.
|
|
|
f2c538 |
+ * @exception CertificateException If certificate is invalid.
|
|
|
f2c538 |
+ */
|
|
|
f2c538 |
+ public void verifyCertificate(String nickname,
|
|
|
f2c538 |
+ boolean checkSig,
|
|
|
f2c538 |
+ CertificateUsage certificateUsage)
|
|
|
f2c538 |
+ throws ObjectNotFoundException, InvalidNicknameException, CertificateException {
|
|
|
f2c538 |
+ int usage = certificateUsage == null ? 0 : certificateUsage.getUsage();
|
|
|
f2c538 |
+ verifyCertificateNowNative(nickname, checkSig, usage);
|
|
|
f2c538 |
+ }
|
|
|
f2c538 |
+
|
|
|
f2c538 |
+ private native void verifyCertificateNowNative(
|
|
|
f2c538 |
+ String nickname,
|
|
|
f2c538 |
+ boolean checkSig,
|
|
|
f2c538 |
+ int certificateUsage)
|
|
|
f2c538 |
+ throws ObjectNotFoundException, InvalidNicknameException, CertificateException;
|
|
|
f2c538 |
|
|
|
f2c538 |
/**
|
|
|
f2c538 |
* note: this method calls obsolete function in NSS
|
|
|
f2c538 |
diff --git a/mozilla/security/jss/org/mozilla/jss/PK11Finder.c b/mozilla/security/jss/org/mozilla/jss/PK11Finder.c
|
|
|
f2c538 |
index 8c7f0b4c05b58527a41cac140dbb5dc30578570f..4986478ffc860e145cd31e41c2880fcc2b5e007e 100644
|
|
|
f2c538 |
--- a/mozilla/security/jss/org/mozilla/jss/PK11Finder.c
|
|
|
f2c538 |
+++ b/mozilla/security/jss/org/mozilla/jss/PK11Finder.c
|
|
|
f2c538 |
@@ -1667,21 +1667,86 @@ Java_org_mozilla_jss_CryptoManager_verifyCertificateNowCUNative(JNIEnv *env,
|
|
|
f2c538 |
/***********************************************************************
|
|
|
f2c538 |
* CryptoManager.verifyCertificateNowNative
|
|
|
f2c538 |
*
|
|
|
f2c538 |
- * Returns JNI_TRUE if success, JNI_FALSE otherwise
|
|
|
f2c538 |
+ * Verify a certificate that exists in the given cert database,
|
|
|
f2c538 |
+ * check if it's valid and that we trust the issuer. Verify time
|
|
|
f2c538 |
+ * against now.
|
|
|
f2c538 |
+ * @param nickname nickname of the certificate to verify.
|
|
|
f2c538 |
+ * @param checkSig verify the signature of the certificate
|
|
|
f2c538 |
+ * @param certificateUsage see certificate usage defined to verify certificate
|
|
|
f2c538 |
+ *
|
|
|
f2c538 |
+ * @exception InvalidNicknameException If the nickname is null.
|
|
|
f2c538 |
+ * @exception ObjectNotFoundException If no certificate could be found
|
|
|
f2c538 |
+ * with the given nickname.
|
|
|
f2c538 |
+ * @exception CertificateException If certificate is invalid.
|
|
|
f2c538 |
*/
|
|
|
f2c538 |
-JNIEXPORT jboolean JNICALL
|
|
|
f2c538 |
+JNIEXPORT void JNICALL
|
|
|
f2c538 |
Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative(JNIEnv *env,
|
|
|
f2c538 |
- jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage)
|
|
|
f2c538 |
+ jobject self, jstring nickString, jboolean checkSig, jint certificateUsage)
|
|
|
f2c538 |
{
|
|
|
f2c538 |
- SECStatus rv = SECFailure;
|
|
|
f2c538 |
SECCertificateUsage currUsage = 0x0000;
|
|
|
f2c538 |
+ SECStatus rv = SECFailure;
|
|
|
f2c538 |
+ CERTCertificate *cert = NULL;
|
|
|
f2c538 |
+ char *nickname = NULL;
|
|
|
f2c538 |
|
|
|
f2c538 |
- rv = verifyCertificateNow(env, self, nickString, checkSig, required_certificateUsage, &currUsage);
|
|
|
f2c538 |
+ if (nickString == NULL) {
|
|
|
f2c538 |
+ JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname");
|
|
|
f2c538 |
+ goto finish;
|
|
|
f2c538 |
+ }
|
|
|
f2c538 |
|
|
|
f2c538 |
- if( rv == SECSuccess) {
|
|
|
f2c538 |
- return JNI_TRUE;
|
|
|
f2c538 |
- } else {
|
|
|
f2c538 |
- return JNI_FALSE;
|
|
|
f2c538 |
+ nickname = (char *) (*env)->GetStringUTFChars(env, nickString, NULL);
|
|
|
f2c538 |
+
|
|
|
f2c538 |
+ if (nickname == NULL) {
|
|
|
f2c538 |
+ JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname");
|
|
|
f2c538 |
+ goto finish;
|
|
|
f2c538 |
+ }
|
|
|
f2c538 |
+
|
|
|
f2c538 |
+ cert = CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname);
|
|
|
f2c538 |
+
|
|
|
f2c538 |
+ if (cert == NULL) {
|
|
|
f2c538 |
+ char *msgBuf;
|
|
|
f2c538 |
+ msgBuf = PR_smprintf("Certificate not found: %s", nickname);
|
|
|
f2c538 |
+ JSS_throwMsg(env, OBJECT_NOT_FOUND_EXCEPTION, msgBuf);
|
|
|
f2c538 |
+ PR_Free(msgBuf);
|
|
|
f2c538 |
+ goto finish;
|
|
|
f2c538 |
+ }
|
|
|
f2c538 |
+
|
|
|
f2c538 |
+ /* 0 for certificateUsage in call to CERT_VerifyCertificateNow will
|
|
|
f2c538 |
+ * retrieve the current valid usage into currUsage
|
|
|
f2c538 |
+ */
|
|
|
f2c538 |
+ rv = CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), cert,
|
|
|
f2c538 |
+ checkSig, certificateUsage, NULL, &currUsage);
|
|
|
f2c538 |
+
|
|
|
f2c538 |
+ if (rv != SECSuccess) {
|
|
|
f2c538 |
+ JSS_throwMsgPrErr(env, CERTIFICATE_EXCEPTION, "Invalid certificate");
|
|
|
f2c538 |
+ goto finish;
|
|
|
f2c538 |
+ }
|
|
|
f2c538 |
+
|
|
|
f2c538 |
+ if ((certificateUsage == 0x0000) &&
|
|
|
f2c538 |
+ (currUsage ==
|
|
|
f2c538 |
+ ( certUsageUserCertImport |
|
|
|
f2c538 |
+ certUsageVerifyCA |
|
|
|
f2c538 |
+ certUsageProtectedObjectSigner |
|
|
|
f2c538 |
+ certUsageAnyCA ))) {
|
|
|
f2c538 |
+
|
|
|
f2c538 |
+ /* The certificate is good for nothing.
|
|
|
f2c538 |
+ * The following usages cannot be verified:
|
|
|
f2c538 |
+ * certUsageAnyCA
|
|
|
f2c538 |
+ * certUsageProtectedObjectSigner
|
|
|
f2c538 |
+ * certUsageUserCertImport
|
|
|
f2c538 |
+ * certUsageVerifyCA
|
|
|
f2c538 |
+ * (0x0b80)
|
|
|
f2c538 |
+ */
|
|
|
f2c538 |
+
|
|
|
f2c538 |
+ JSS_throwMsgPrErr(env, CERTIFICATE_EXCEPTION, "Unusable certificate");
|
|
|
f2c538 |
+ goto finish;
|
|
|
f2c538 |
+ }
|
|
|
f2c538 |
+
|
|
|
f2c538 |
+finish:
|
|
|
f2c538 |
+ if (nickname != NULL) {
|
|
|
f2c538 |
+ (*env)->ReleaseStringUTFChars(env, nickString, nickname);
|
|
|
f2c538 |
+ }
|
|
|
f2c538 |
+ if (cert != NULL) {
|
|
|
f2c538 |
+ CERT_DestroyCertificate(cert);
|
|
|
f2c538 |
}
|
|
|
f2c538 |
}
|
|
|
f2c538 |
|
|
|
f2c538 |
diff --git a/mozilla/security/jss/org/mozilla/jss/util/jss_exceptions.h b/mozilla/security/jss/org/mozilla/jss/util/jss_exceptions.h
|
|
|
f2c538 |
index 4884928306223ff0699a22e7da33e3d13a904d39..acd329a4ecd3592ebe1d72c7bdac435d84dcae99 100644
|
|
|
f2c538 |
--- a/mozilla/security/jss/org/mozilla/jss/util/jss_exceptions.h
|
|
|
f2c538 |
+++ b/mozilla/security/jss/org/mozilla/jss/util/jss_exceptions.h
|
|
|
f2c538 |
@@ -79,6 +79,8 @@ PR_BEGIN_EXTERN_C
|
|
|
f2c538 |
|
|
|
f2c538 |
#define INTERRUPTED_IO_EXCEPTION "java/io/InterruptedIOException"
|
|
|
f2c538 |
|
|
|
f2c538 |
+#define INVALID_NICKNAME_EXCEPTION "org/mozilla/jss/util/InvalidNicknameException"
|
|
|
f2c538 |
+
|
|
|
f2c538 |
#define INVALID_KEY_FORMAT_EXCEPTION "org/mozilla/jss/crypto/InvalidKeyFormatException"
|
|
|
f2c538 |
|
|
|
f2c538 |
#define INVALID_PARAMETER_EXCEPTION "java/security/InvalidParameterException"
|
|
|
f2c538 |
--
|
|
|
f2c538 |
2.5.0
|
|
|
f2c538 |
|