diff --git a/security/jss/lib/jss.def b/security/jss/lib/jss.def index b4634ae0531b..24fa9a792e05 100644 --- a/security/jss/lib/jss.def +++ b/security/jss/lib/jss.def @@ -258,6 +258,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_setCipherPreferenceDefault; Java_org_mozilla_jss_ssl_SSLSocket_getCipherPreference; Java_org_mozilla_jss_CryptoManager_configureOCSPNative; Java_org_mozilla_jss_pkcs11_PK11SymKey_getLength; +Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getCertObject; ;+ local: ;+ *; ;+}; diff --git a/security/jss/org/mozilla/jss/provider/java/security/JSSKeyStoreSpi.c b/security/jss/org/mozilla/jss/provider/java/security/JSSKeyStoreSpi.c index b5a3f8df2ee5..5e96cd2a24de 100644 --- a/security/jss/org/mozilla/jss/provider/java/security/JSSKeyStoreSpi.c +++ b/security/jss/org/mozilla/jss/provider/java/security/JSSKeyStoreSpi.c @@ -503,14 +503,13 @@ engineGetCertificateTraversalCallback return travStat; } - -JNIEXPORT jbyteArray JNICALL -Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getDERCert - (JNIEnv *env, jobject this, jstring alias) +static CERTCertificate* +lookupCertByNickname(JNIEnv *env, jobject this, jstring alias) { PK11SlotInfo *slot; EngineGetCertificateCBInfo cbinfo = {NULL,NULL}; jbyteArray derCertBA = NULL; + PRStatus status = PR_FAILURE; if( alias == NULL ) goto finish; @@ -522,26 +521,67 @@ Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getDERCert cbinfo.targetNickname = (*env)->GetStringUTFChars(env, alias, NULL); if(cbinfo.targetNickname == NULL ) goto finish; - if( traverseTokenObjects( env, - slot, - engineGetCertificateTraversalCallback, - CERT, - (void*) &cbinfo) - != PR_SUCCESS ) - { - goto finish; - } - - if( cbinfo.cert != NULL ) { - derCertBA = JSS_SECItemToByteArray(env, &cbinfo.cert->derCert); - } + status = traverseTokenObjects( env, + slot, + engineGetCertificateTraversalCallback, + CERT, + (void*) &cbinfo); finish: if( cbinfo.targetNickname != NULL ) { (*env)->ReleaseStringUTFChars(env, alias, cbinfo.targetNickname); } - if( cbinfo.cert != NULL) { + if( status != PR_SUCCESS && cbinfo.cert != NULL) { CERT_DestroyCertificate(cbinfo.cert); + cbinfo.cert = NULL; + } + return cbinfo.cert; +} + +JNIEXPORT jobject JNICALL +Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getCertObject + (JNIEnv *env, jobject this, jstring alias) +{ + CERTCertificate *cert = NULL; + jobject certObj = NULL; + + cert = lookupCertByNickname(env, this, alias); + if( cert == NULL ) { + goto finish; + } + + certObj = JSS_PK11_wrapCert(env, &cert); + +finish: + if( cert != NULL ) { + CERT_DestroyCertificate(cert); + } + if( certObj == NULL ) { + PR_ASSERT( (*env)->ExceptionOccurred(env) ); + } + return certObj; +} + +JNIEXPORT jbyteArray JNICALL +Java_org_mozilla_jss_provider_java_security_JSSKeyStoreSpi_getDERCert + (JNIEnv *env, jobject this, jstring alias) +{ + CERTCertificate * cert = NULL; + jbyteArray derCertBA = NULL; + + cert = lookupCertByNickname(env, this, alias); + if( cert == NULL ) { + goto finish; + } + + derCertBA = JSS_SECItemToByteArray(env, &cert->derCert); + +finish: + if( cert != NULL) { + CERT_DestroyCertificate(cert); + } + if( derCertBA == NULL ) { + PR_ASSERT( (*env)->ExceptionOccurred(env) ); } return derCertBA; } diff --git a/security/jss/org/mozilla/jss/provider/java/security/JSSKeyStoreSpi.java b/security/jss/org/mozilla/jss/provider/java/security/JSSKeyStoreSpi.java index 403a40551256..4e30cfa24eb2 100644 --- a/security/jss/org/mozilla/jss/provider/java/security/JSSKeyStoreSpi.java +++ b/security/jss/org/mozilla/jss/provider/java/security/JSSKeyStoreSpi.java @@ -54,6 +54,10 @@ import org.mozilla.jss.pkcs11.TokenProxy; import org.mozilla.jss.crypto.CryptoToken; import org.mozilla.jss.crypto.TokenSupplierManager; import org.mozilla.jss.crypto.SecretKeyFacade; +import org.mozilla.jss.crypto.X509Certificate; +import org.mozilla.jss.crypto.TokenException; +import org.mozilla.jss.crypto.TokenRuntimeException; +import org.mozilla.jss.CryptoManager; /** * The JSS implementation of the JCA KeyStore SPI. @@ -169,6 +173,7 @@ public class JSSKeyStoreSpi extends java.security.KeyStoreSpi { } private native byte[] getDERCert(String alias); + private native X509Certificate getCertObject(String alias); public String engineGetCertificateAlias(Certificate cert) { try { @@ -181,14 +186,28 @@ public class JSSKeyStoreSpi extends java.security.KeyStoreSpi { private native String getCertNickname(byte[] derCert); public Certificate[] engineGetCertificateChain(String alias) { - Certificate cert = engineGetCertificate(alias); - if( cert == null ) { + try { + X509Certificate leaf = getCertObject(alias); + if( leaf == null ) { return null; - } else { - Certificate[] certs = new Certificate[1]; - certs[0] = cert; - return certs; } + CryptoManager cm = CryptoManager.getInstance(); + X509Certificate[] jssChain = cm.buildCertificateChain(leaf); + + Certificate[] chain = new Certificate[jssChain.length]; + for( int i=0; i < chain.length; ++i) { + chain[i] = certFactory.generateCertificate( + new ByteArrayInputStream(jssChain[i].getEncoded()) ); + } + return chain; + } catch(TokenException te ) { + throw new TokenRuntimeException(te.toString()); + } catch(CryptoManager.NotInitializedException e) { + throw new RuntimeException("CryptoManager not initialized"); + } catch(CertificateException ce) { + ce.printStackTrace(); + return null; + } } /*