From f2c53857d362752dc4ac7dcdee31505011dd5f82 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 03 2016 06:01:10 +0000 Subject: import jss-4.2.6-42.el7 --- diff --git a/SOURCES/jss-Fixed-build-failures.patch b/SOURCES/jss-Fixed-build-failures.patch new file mode 100644 index 0000000..af11010 --- /dev/null +++ b/SOURCES/jss-Fixed-build-failures.patch @@ -0,0 +1,349 @@ +From 22092d1bde94dc8a1f6e8198fa2fcc597c36c32f Mon Sep 17 00:00:00 2001 +From: "Endi S. Dewata" +Date: Wed, 9 Dec 2015 00:30:50 +0100 +Subject: [PATCH] Fixed build failures. + +The Javadoc on various classes have been modified to fix build +failures on F23 and Rawhide due to stringent requirements on +those platforms. + +The Debug_debug.jnot has been renamed to Debug.java to fix build +failure in Eclipse. + +https://bugzilla.redhat.com/show_bug.cgi?id=1289799 +--- + .classpath | 7 +++++++ + .project | 17 +++++++++++++++++ + mozilla/security/jss/build_java.pl | 2 +- + mozilla/security/jss/org/mozilla/jss/CryptoManager.java | 14 +++++++------- + .../security/jss/org/mozilla/jss/asn1/ASN1Header.java | 2 +- + .../security/jss/org/mozilla/jss/pkcs11/PK11Token.java | 2 +- + .../security/jss/org/mozilla/jss/pkcs12/CertBag.java | 1 + + .../security/jss/org/mozilla/jss/pkcs7/ContentInfo.java | 1 - + .../security/jss/org/mozilla/jss/pkcs7/SignerInfo.java | 17 ++++++++++------- + .../jss/org/mozilla/jss/pkix/cms/ContentInfo.java | 1 - + .../jss/org/mozilla/jss/pkix/cms/SignerInfo.java | 17 ++++++++++------- + .../jss/org/mozilla/jss/pkix/crmf/CertReqMsg.java | 2 +- + .../jss/org/mozilla/jss/ssl/SSLServerSocket.java | 3 --- + .../mozilla/jss/util/{Debug_debug.jnot => Debug.java} | 0 + 14 files changed, 56 insertions(+), 30 deletions(-) + create mode 100644 .classpath + create mode 100644 .project + rename mozilla/security/jss/org/mozilla/jss/util/{Debug_debug.jnot => Debug.java} (100%) + +diff --git a/.classpath b/.classpath +new file mode 100644 +index 0000000000000000000000000000000000000000..df092d3f7d8df936b753bea75c11bf4003e1a77f +--- /dev/null ++++ b/.classpath +@@ -0,0 +1,7 @@ ++ ++ ++ ++ ++ ++ ++ +diff --git a/.project b/.project +new file mode 100644 +index 0000000000000000000000000000000000000000..c0b616e95c7512076c9976374bda14e11d7cdd8c +--- /dev/null ++++ b/.project +@@ -0,0 +1,17 @@ ++ ++ ++ jss-4.2 ++ ++ ++ ++ ++ ++ org.eclipse.jdt.core.javabuilder ++ ++ ++ ++ ++ ++ org.eclipse.jdt.core.javanature ++ ++ +diff --git a/mozilla/security/jss/build_java.pl b/mozilla/security/jss/build_java.pl +index c34473e0eec883323b6b100e671018a9edafe442..379a5e05dbc0599c95d2228bd14f659d3e493d0b 100644 +--- a/mozilla/security/jss/build_java.pl ++++ b/mozilla/security/jss/build_java.pl +@@ -137,7 +137,7 @@ sub setup_vars { + $class_jar = "$dist_dir/$cmdline_vars{XPCLASS_DBG_JAR}"; + $class_release_dir .= "/$cmdline_vars{SOURCE_RELEASE_CLASSES_DBG_DIR}"; + $javac_opt_flag = "-g"; +- $debug_source_file = "org/mozilla/jss/util/Debug_debug.jnot"; ++ $debug_source_file = "org/mozilla/jss/util/Debug.java"; + } + $jni_header_dir = "$dist_dir/private/jss/_jni"; + +diff --git a/mozilla/security/jss/org/mozilla/jss/CryptoManager.java b/mozilla/security/jss/org/mozilla/jss/CryptoManager.java +index 08aad8fe3c3a62ae8e233fc1035723690adf4581..6ef0256a3b777db48461f19da0fa64ec7857ed6b 100644 +--- a/mozilla/security/jss/org/mozilla/jss/CryptoManager.java ++++ b/mozilla/security/jss/org/mozilla/jss/CryptoManager.java +@@ -600,7 +600,7 @@ public final class CryptoManager implements TokenSupplier + * loaded cryptographic modules for the token. + * + * @param name The name of the token. +- * @exception org.mozilla.jss.crypto.NoSuchTokenException If no token ++ * @exception NoSuchTokenException If no token + * is found with the given name. + */ + public synchronized CryptoToken getTokenByName(String name) +@@ -855,9 +855,9 @@ public final class CryptoManager implements TokenSupplier + * initialize(). + * + * @param configDir The directory containing the security databases. +- * @exception org.mozilla.jss.util.KeyDatabaseException Unable to open ++ * @exception KeyDatabaseException Unable to open + * the key database, or it was currupted. +- * @exception org.mozilla.jss.util.CertDatabaseException Unable ++ * @exception CertDatabaseException Unable + * to open the certificate database, or it was currupted. + **/ + public static synchronized void initialize( String configDir ) +@@ -878,9 +878,9 @@ public final class CryptoManager implements TokenSupplier + * initialize(). + * + * @param values The options with which to initialize CryptoManager. +- * @exception org.mozilla.jss.util.KeyDatabaseException Unable to open ++ * @exception KeyDatabaseException Unable to open + * the key database, or it was currupted. +- * @exception org.mozilla.jss.util.CertDatabaseException Unable ++ * @exception CertDatabaseException Unable + * to open the certificate database, or it was currupted. + **/ + public static synchronized void initialize( InitializationValues values ) +@@ -1021,7 +1021,7 @@ public final class CryptoManager implements TokenSupplier + * @return The leaf certificate from the chain. + * @exception CertificateEncodingException If the package encoding + * was not recognized. +- * @exception CertificateNicknameConflictException If the leaf certificate ++ * @exception NicknameConflictException If the leaf certificate + * is a user certificate, and another certificate already has the + * given nickname. + * @exception UserCertConflictException If the leaf certificate +@@ -1059,7 +1059,7 @@ public final class CryptoManager implements TokenSupplier + * @return The leaf certificate from the chain. + * @exception CertificateEncodingException If the package encoding + * was not recognized. +- * @exception CertificateNicknameConflictException If the leaf certificate ++ * @exception NicknameConflictException If the leaf certificate + * another certificate already has the given nickname. + * @exception UserCertConflictException If the leaf certificate + * has already been imported. +diff --git a/mozilla/security/jss/org/mozilla/jss/asn1/ASN1Header.java b/mozilla/security/jss/org/mozilla/jss/asn1/ASN1Header.java +index bfa37c9f5eba1c5df9bb275cad16c1bf57c9c65d..d15be4922b52d16a25e3212b2b25809cd7ddf3b6 100644 +--- a/mozilla/security/jss/org/mozilla/jss/asn1/ASN1Header.java ++++ b/mozilla/security/jss/org/mozilla/jss/asn1/ASN1Header.java +@@ -259,7 +259,7 @@ public class ASN1Header { + /** + * This constructor is to be called when we are constructing an ASN1Value + * rather than decoding it. +- * @param contentLength Must be >=0. Although indefinite length ++ * @param contentLength Must be >=0. Although indefinite length + * decoding is supported, indefinite length encoding + * is not. + */ +diff --git a/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Token.java b/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Token.java +index e521b6108b90daeb7035413bba50a41e9b20ec49..98e93f0e858b09402364b4dc89c36a63e7ef0f7b 100644 +--- a/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Token.java ++++ b/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Token.java +@@ -236,7 +236,7 @@ public final class PK11Token implements CryptoToken { + * + * @param ssopwcb The security officer's current password callback. + * @param userpwcb The user's new password callback. +- * @exception IncorrectPinException If the security officer PIN is ++ * @exception IncorrectPasswordException If the security officer PIN is + * incorrect. + * @exception TokenException If the PIN was already initialized, + * or there was an unspecified error in the token. +diff --git a/mozilla/security/jss/org/mozilla/jss/pkcs12/CertBag.java b/mozilla/security/jss/org/mozilla/jss/pkcs12/CertBag.java +index a1b08d2e9ee9dfcb4ee809e101f3074611664384..61ad979d65d5ecc6659281218c58e8ec9a48211c 100644 +--- a/mozilla/security/jss/org/mozilla/jss/pkcs12/CertBag.java ++++ b/mozilla/security/jss/org/mozilla/jss/pkcs12/CertBag.java +@@ -91,6 +91,7 @@ public class CertBag implements ASN1Value { + *
  • If the type is SDSI_CERT_TYPE, returns + * an IA5String. + *
  • For all other types, returns an ANY. ++ * + * + * @exception InvalidBERException If the cert is not encoded correctly. + */ +diff --git a/mozilla/security/jss/org/mozilla/jss/pkcs7/ContentInfo.java b/mozilla/security/jss/org/mozilla/jss/pkcs7/ContentInfo.java +index 4db7a42c75cc21d71841e20dcb9a4c1494ff08c2..4578e9bcd8abdb4e7b6717b07aee932dd887d675 100644 +--- a/mozilla/security/jss/org/mozilla/jss/pkcs7/ContentInfo.java ++++ b/mozilla/security/jss/org/mozilla/jss/pkcs7/ContentInfo.java +@@ -169,7 +169,6 @@ public class ContentInfo implements ASN1Value { + * an OCTET_STRING will be returned. + *

    If the contentType is not one of the six standard types, + * the returned object will be an ANY. +- * + */ + public ASN1Value getInterpretedContent() throws InvalidBERException { + if(contentType.equals(DATA)) { +diff --git a/mozilla/security/jss/org/mozilla/jss/pkcs7/SignerInfo.java b/mozilla/security/jss/org/mozilla/jss/pkcs7/SignerInfo.java +index 300e993cffd9dcadaf996609abeebf8627eafde8..c49107c80543ec94fbb3117a1a9a1088f851a6b3 100644 +--- a/mozilla/security/jss/org/mozilla/jss/pkcs7/SignerInfo.java ++++ b/mozilla/security/jss/org/mozilla/jss/pkcs7/SignerInfo.java +@@ -129,7 +129,7 @@ public class SignerInfo implements ASN1Value { + /** + * Retrieves the DigestAlgorithm used in this SignerInfo. + * +- * @exception NoSuchAlgorithm If the algorithm is not recognized by JSS. ++ * @exception NoSuchAlgorithmException If the algorithm is not recognized by JSS. + */ + public DigestAlgorithm getDigestAlgorithm() + throws NoSuchAlgorithmException +@@ -402,10 +402,12 @@ public class SignerInfo implements ASN1Value { + /** + * Verifies that this SignerInfo contains a valid signature of the + * given message digest. If any authenticated attributes are present, +- * they are also validated. The verification algorithm is as follows:

      +- *

      Note that this does not verify the validity of the +- * the certificate itself, only the signature. ++ * they are also validated. The verification algorithm is as follows: + * ++ * Note that this does not verify the validity of the ++ * the certificate itself, only the signature. ++ * ++ *

        + *
      • If no authenticated attributes are present, the content type is + * verified to be data. Then it is verified that the message + * digest passed +@@ -413,24 +415,25 @@ public class SignerInfo implements ASN1Value { + * digest in the SignerInfo. + * + *
      • If authenticated attributes are present, +- * two particular attributes must be present:
          ++ * two particular attributes must be present: ++ *
            + *
          • PKCS #9 Content-Type, the type of content that is being signed. + * This must match the contentType parameter. + *
          • PKCS #9 Message-Digest, the digest of the content that is being + * signed. This must match the messageDigest parameter. + *
          ++ * + * After these two attributes are verified to be both present and correct, + * the encryptedDigest field of the SignerInfo is verified to be the + * signature of the contents octets of the DER encoding of the + * authenticatedAttributes field. +- * + *
        + * + * @param messageDigest The hash of the content that is signed by this + * SignerInfo. + * @param contentType The type of the content that is signed by this + * SignerInfo. +- * @exception NoSuchObjectException If no certificate matching the ++ * @exception ObjectNotFoundException If no certificate matching the + * the issuer name and serial number can be found. + */ + public void verify(byte[] messageDigest, OBJECT_IDENTIFIER contentType) +diff --git a/mozilla/security/jss/org/mozilla/jss/pkix/cms/ContentInfo.java b/mozilla/security/jss/org/mozilla/jss/pkix/cms/ContentInfo.java +index 91ae770c94b3a8817c13e4cb86609c432ef682b8..9f61e605b416dffc38525ccec4dcce9f380c7dcc 100644 +--- a/mozilla/security/jss/org/mozilla/jss/pkix/cms/ContentInfo.java ++++ b/mozilla/security/jss/org/mozilla/jss/pkix/cms/ContentInfo.java +@@ -168,7 +168,6 @@ public class ContentInfo implements ASN1Value { + * an OCTET_STRING will be returned. + *

        If the contentType is not one of the six standard types, + * the returned object will be an ANY. +- *

      + */ + public ASN1Value getInterpretedContent() throws InvalidBERException { + if(contentType.equals(DATA)) { +diff --git a/mozilla/security/jss/org/mozilla/jss/pkix/cms/SignerInfo.java b/mozilla/security/jss/org/mozilla/jss/pkix/cms/SignerInfo.java +index ff34a554e4d5f43b6ce18acfac01899858d62117..e7feb934dc0a78fbc40a6ff7d8db87f0af9177fe 100644 +--- a/mozilla/security/jss/org/mozilla/jss/pkix/cms/SignerInfo.java ++++ b/mozilla/security/jss/org/mozilla/jss/pkix/cms/SignerInfo.java +@@ -130,7 +130,7 @@ public class SignerInfo implements ASN1Value { + /** + * Retrieves the DigestAlgorithm used in this SignerInfo. + * +- * @exception NoSuchAlgorithm If the algorithm is not recognized by JSS. ++ * @exception NoSuchAlgorithmException If the algorithm is not recognized by JSS. + */ + public DigestAlgorithm getDigestAlgorithm() + throws NoSuchAlgorithmException +@@ -403,10 +403,12 @@ public class SignerInfo implements ASN1Value { + /** + * Verifies that this SignerInfo contains a valid signature of the + * given message digest. If any signed attributes are present, +- * they are also validated. The verification algorithm is as follows:
        +- *

        Note that this does not verify the validity of the +- * the certificate itself, only the signature. ++ * they are also validated. The verification algorithm is as follows: + * ++ * Note that this does not verify the validity of the ++ * the certificate itself, only the signature. ++ * ++ *

          + *
        • If no signed attributes are present, the content type is + * verified to be data. Then it is verified that the message + * digest passed +@@ -414,24 +416,25 @@ public class SignerInfo implements ASN1Value { + * digest in the SignerInfo. + * + *
        • If signed attributes are present, +- * two particular attributes must be present:
            ++ * two particular attributes must be present: ++ *
              + *
            • PKCS #9 Content-Type, the type of content that is being signed. + * This must match the contentType parameter. + *
            • PKCS #9 Message-Digest, the digest of the content that is being + * signed. This must match the messageDigest parameter. + *
            ++ * + * After these two attributes are verified to be both present and correct, + * the encryptedDigest field of the SignerInfo is verified to be the + * signature of the contents octets of the DER encoding of the + * signedAttributes field. +- * + *
          + * + * @param messageDigest The hash of the content that is signed by this + * SignerInfo. + * @param contentType The type of the content that is signed by this + * SignerInfo. +- * @exception NoSuchObjectException If no certificate matching the ++ * @exception ObjectNotFoundException If no certificate matching the + * the issuer name and serial number can be found. + */ + public void verify(byte[] messageDigest, OBJECT_IDENTIFIER contentType) +diff --git a/mozilla/security/jss/org/mozilla/jss/pkix/crmf/CertReqMsg.java b/mozilla/security/jss/org/mozilla/jss/pkix/crmf/CertReqMsg.java +index 53d162b69673caeed3e998dc9c2e221b95dfc6db..c6637039c87043f36dd1a1e449a819edbcc816e3 100644 +--- a/mozilla/security/jss/org/mozilla/jss/pkix/crmf/CertReqMsg.java ++++ b/mozilla/security/jss/org/mozilla/jss/pkix/crmf/CertReqMsg.java +@@ -112,7 +112,7 @@ public class CertReqMsg implements ASN1Value { + + /** + * Constructs a CertReqmsg from a CertRequest and, optionally, +- * a pop>/i> and a regInfo. ++ * a pop and a regInfo. + * @param pop May be NULL. + * @param regInfo May be NULL. + */ +diff --git a/mozilla/security/jss/org/mozilla/jss/ssl/SSLServerSocket.java b/mozilla/security/jss/org/mozilla/jss/ssl/SSLServerSocket.java +index 2043a598cf3e8d023287c0f7142045c1e4f68e4d..58d14496e5ad92aa91a966e119e14f470da4fd4a 100644 +--- a/mozilla/security/jss/org/mozilla/jss/ssl/SSLServerSocket.java ++++ b/mozilla/security/jss/org/mozilla/jss/ssl/SSLServerSocket.java +@@ -174,9 +174,6 @@ public class SSLServerSocket extends java.net.ServerSocket { + * @return java.net.Socket Local socket for client communication + * + * @throws IOException If an input or output exception occurred +- * @throws SocketTimeoutException If the socket timesout trying to connect +- * @throws InterruptedIOException If an input or output is interrupted +- * @throws SSLSocketException JSS subclass of java.net.SocketException + */ + public Socket accept() throws IOException { + synchronized (acceptLock) { +diff --git a/mozilla/security/jss/org/mozilla/jss/util/Debug_debug.jnot b/mozilla/security/jss/org/mozilla/jss/util/Debug.java +similarity index 100% +rename from mozilla/security/jss/org/mozilla/jss/util/Debug_debug.jnot +rename to mozilla/security/jss/org/mozilla/jss/util/Debug.java +-- +2.4.3 + diff --git a/SOURCES/jss-VerifyCertificate-enhancement.patch b/SOURCES/jss-VerifyCertificate-enhancement.patch new file mode 100644 index 0000000..6582b41 --- /dev/null +++ b/SOURCES/jss-VerifyCertificate-enhancement.patch @@ -0,0 +1,204 @@ +From 3c4ca8a2010889fe292704ebcc8b922f77f2f7c2 Mon Sep 17 00:00:00 2001 +From: "Endi S. Dewata" +Date: Wed, 9 Dec 2015 00:30:50 +0100 +Subject: [PATCH] Added verifyCertificate() method. + +A new CryptoManager.verifyCertificate() method has been added as +an alternative to isCertValid(). If there is a certificate +validation problem, the method will throw a CertificateValidation +exception that contains the NSS error message and code. The +exception will also provide a stack trace to help troubleshoot +validation issues. + +https://fedorahosted.org/pki/ticket/850 +--- + .../jss/org/mozilla/jss/CryptoManager.java | 54 ++++++++------ + mozilla/security/jss/org/mozilla/jss/PK11Finder.c | 83 +++++++++++++++++++--- + .../jss/org/mozilla/jss/util/jss_exceptions.h | 2 + + 3 files changed, 110 insertions(+), 29 deletions(-) + +diff --git a/mozilla/security/jss/org/mozilla/jss/CryptoManager.java b/mozilla/security/jss/org/mozilla/jss/CryptoManager.java +index 0a4f59064bfddb42d473022550c24f251719d02b..54ffd8130b0e1f1fca49dd8b130a621e449c7ce7 100644 +--- a/mozilla/security/jss/org/mozilla/jss/CryptoManager.java ++++ b/mozilla/security/jss/org/mozilla/jss/CryptoManager.java +@@ -1515,30 +1515,44 @@ public final class CryptoManager implements TokenSupplier + CertificateUsage certificateUsage) + throws ObjectNotFoundException, InvalidNicknameException + { +- if (nickname==null) { +- throw new InvalidNicknameException("Nickname must be non-null"); +- } +- // 0 certificate usage will get current usage +- // should call isCertValid() call above that returns certificate usage +- if ((certificateUsage == null) || +- (certificateUsage == CertificateUsage.CheckAllUsages)){ +- int currCertificateUsage = 0x0000; +- currCertificateUsage = verifyCertificateNowCUNative(nickname, +- checkSig); ++ try { ++ verifyCertificate(nickname, checkSig, certificateUsage); ++ return true; ++ ++ } catch (ObjectNotFoundException | InvalidNicknameException e) { ++ throw e; + +- if (currCertificateUsage == CertificateUsage.basicCertificateUsages){ +- // cert is good for nothing +- return false; +- } else +- return true; +- } else { +- return verifyCertificateNowNative(nickname, checkSig, +- certificateUsage.getUsage()); ++ } catch (CertificateException e) { ++ return false; + } + } + +- private native boolean verifyCertificateNowNative(String nickname, +- boolean checkSig, int certificateUsage) throws ObjectNotFoundException; ++ /** ++ * 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(); ++ verifyCertificateNowNative(nickname, checkSig, usage); ++ } ++ ++ private native void verifyCertificateNowNative( ++ String nickname, ++ boolean checkSig, ++ int certificateUsage) ++ throws ObjectNotFoundException, InvalidNicknameException, CertificateException; + + /** + * note: this method calls obsolete function in NSS +diff --git a/mozilla/security/jss/org/mozilla/jss/PK11Finder.c b/mozilla/security/jss/org/mozilla/jss/PK11Finder.c +index 8c7f0b4c05b58527a41cac140dbb5dc30578570f..4986478ffc860e145cd31e41c2880fcc2b5e007e 100644 +--- a/mozilla/security/jss/org/mozilla/jss/PK11Finder.c ++++ b/mozilla/security/jss/org/mozilla/jss/PK11Finder.c +@@ -1667,21 +1667,86 @@ Java_org_mozilla_jss_CryptoManager_verifyCertificateNowCUNative(JNIEnv *env, + /*********************************************************************** + * CryptoManager.verifyCertificateNowNative + * +- * Returns JNI_TRUE if success, JNI_FALSE otherwise ++ * 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 jboolean JNICALL ++JNIEXPORT void JNICALL + Java_org_mozilla_jss_CryptoManager_verifyCertificateNowNative(JNIEnv *env, +- jobject self, jstring nickString, jboolean checkSig, jint required_certificateUsage) ++ jobject self, jstring nickString, jboolean checkSig, jint certificateUsage) + { +- SECStatus rv = SECFailure; + SECCertificateUsage currUsage = 0x0000; ++ SECStatus rv = SECFailure; ++ CERTCertificate *cert = NULL; ++ char *nickname = NULL; + +- rv = verifyCertificateNow(env, self, nickString, checkSig, required_certificateUsage, &currUsage); ++ if (nickString == NULL) { ++ JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname"); ++ goto finish; ++ } + +- if( rv == SECSuccess) { +- return JNI_TRUE; +- } else { +- return JNI_FALSE; ++ nickname = (char *) (*env)->GetStringUTFChars(env, nickString, NULL); ++ ++ if (nickname == NULL) { ++ JSS_throwMsg(env, INVALID_NICKNAME_EXCEPTION, "Missing certificate nickname"); ++ 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); + } + } + +diff --git a/mozilla/security/jss/org/mozilla/jss/util/jss_exceptions.h b/mozilla/security/jss/org/mozilla/jss/util/jss_exceptions.h +index 4884928306223ff0699a22e7da33e3d13a904d39..acd329a4ecd3592ebe1d72c7bdac435d84dcae99 100644 +--- a/mozilla/security/jss/org/mozilla/jss/util/jss_exceptions.h ++++ b/mozilla/security/jss/org/mozilla/jss/util/jss_exceptions.h +@@ -79,6 +79,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" +-- +2.5.0 + diff --git a/SOURCES/jss-crmf-envelopedData.patch b/SOURCES/jss-crmf-envelopedData.patch new file mode 100644 index 0000000..13c21d7 --- /dev/null +++ b/SOURCES/jss-crmf-envelopedData.patch @@ -0,0 +1,33 @@ +diff -up jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkix/crmf/EncryptedKey.java.roysjosh jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkix/crmf/EncryptedKey.java +--- jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkix/crmf/EncryptedKey.java.roysjosh 2016-06-24 14:51:48.929122053 -0700 ++++ jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkix/crmf/EncryptedKey.java 2016-06-24 14:52:29.487027005 -0700 +@@ -127,7 +127,8 @@ public class EncryptedKey implements ASN + } else { + Assert._assert(type == ENVELOPED_DATA); + Assert._assert(envelopedData != null); +- envelopedData.encode(implicitTag, ostream); ++ EXPLICIT explicit = new EXPLICIT( new Tag(0), envelopedData ); ++ explicit.encode(tag, ostream); + } + } + +@@ -147,7 +148,9 @@ public class EncryptedKey implements ASN + choicet = new CHOICE.Template(); + + choicet.addElement( EncryptedValue.getTemplate() ); +- choicet.addElement( new Tag(0), ANY.getTemplate() ); ++ choicet.addElement( new EXPLICIT.Template( ++ new Tag(0), ++ ANY.getTemplate() )); + } + + public boolean tagMatch(Tag tag) { +@@ -164,7 +167,7 @@ public class EncryptedKey implements ASN + return new EncryptedKey( (EncryptedValue) choice.getValue() ); + } else { + Assert._assert( choice.getTag().equals(new Tag(0)) ); +- return new EncryptedKey( (ANY) choice.getValue() ); ++ return new EncryptedKey( (ANY) ((EXPLICIT) choice.getValue()).getContent() ); + } + + } catch(InvalidBERException e) { diff --git a/SOURCES/jss-lunasaUnwrap.patch b/SOURCES/jss-lunasaUnwrap.patch new file mode 100644 index 0000000..5021bd6 --- /dev/null +++ b/SOURCES/jss-lunasaUnwrap.patch @@ -0,0 +1,12 @@ +diff -up jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c.cfu jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c +--- jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c.cfu 2016-04-28 16:50:06.000000000 -0700 ++++ jss-4.2.6/mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c 2016-04-28 16:50:00.000000000 -0700 +@@ -434,7 +434,7 @@ Java_org_mozilla_jss_pkcs11_PK11KeyWrapp + isSensitive = PR_FALSE; + isExtractable = PR_FALSE; + } else if ( isLunasa) { +- isSensitive = PR_FALSE; ++ isSensitive = PR_TRUE; + isExtractable = PR_TRUE; + } + diff --git a/SOURCES/jss-symkey-enhancements.patch b/SOURCES/jss-symkey-enhancements.patch new file mode 100644 index 0000000..248ba76 --- /dev/null +++ b/SOURCES/jss-symkey-enhancements.patch @@ -0,0 +1,1855 @@ +diff -up ./mozilla/security/jss/build_java.pl.jmagne ./mozilla/security/jss/build_java.pl +--- ./mozilla/security/jss/build_java.pl.jmagne 2016-04-14 13:56:16.946920239 -0700 ++++ ./mozilla/security/jss/build_java.pl 2016-04-14 14:53:08.501298062 -0700 +@@ -31,7 +31,8 @@ org.mozilla.jss.pkcs11.PK11MessageDigest + org.mozilla.jss.pkcs11.PK11PrivKey + org.mozilla.jss.pkcs11.PK11PubKey + org.mozilla.jss.pkcs11.PK11SymKey +-org.mozilla.jss.pkcs11.PK11KeyPairGenerator ++org.mozilla.jss.pkcs11.PK11KeyPairGenerator ++org.mozilla.jss.pkcs11.PK11SymmetricKeyDeriver + org.mozilla.jss.pkcs11.PK11KeyGenerator + org.mozilla.jss.pkcs11.PK11Token + org.mozilla.jss.pkcs11.PrivateKeyProxy +diff -up ./mozilla/security/jss/lib/jss.def.jmagne ./mozilla/security/jss/lib/jss.def +--- ./mozilla/security/jss/lib/jss.def.jmagne 2016-04-14 16:00:06.229534228 -0700 ++++ ./mozilla/security/jss/lib/jss.def 2016-04-14 16:00:32.229356314 -0700 +@@ -158,6 +158,7 @@ Java_org_mozilla_jss_pkcs11_PK11Store_de + Java_org_mozilla_jss_pkcs11_PK11Store_importPrivateKey; + Java_org_mozilla_jss_pkcs11_PK11Store_putCertsInVector; + Java_org_mozilla_jss_pkcs11_PK11Store_putKeysInVector; ++Java_org_mozilla_jss_pkcs11_PK11Store_putSymKeysInVector; + Java_org_mozilla_jss_pkcs11_SigContextProxy_releaseNativeResources; + Java_org_mozilla_jss_pkcs11_PK11RSAPublicKey_getModulusByteArray; + Java_org_mozilla_jss_pkcs11_PK11RSAPublicKey_getPublicExponentByteArray; +@@ -336,6 +337,8 @@ Java_org_mozilla_jss_CryptoManager_verif + Java_org_mozilla_jss_asn1_ASN1Util_getTagDescriptionByOid; + Java_org_mozilla_jss_ssl_SocketBase_setSSLVersionRange; + Java_org_mozilla_jss_ssl_SSLSocket_setSSLVersionRangeDefault; ++Java_org_mozilla_jss_pkcs11_PK11SymmetricKeyDeriver_nativeDeriveSymKey; ++Java_org_mozilla_jss_pkcs11_PK11SymKey_setNickNameNative; + ;+ local: + ;+ *; + ;+}; +diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.c.jmagne ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.c +--- ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.c.jmagne 2016-04-14 16:02:38.108494940 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.c 2016-04-14 16:02:47.243432431 -0700 +@@ -114,6 +114,11 @@ JSS_AlgInfo JSS_AlgTable[NUM_ALGS] = { + /* 51 */ {SEC_OID_PKCS5_PBKDF2, SEC_OID_TAG}, + /* 52 */ {SEC_OID_PKCS5_PBES2, SEC_OID_TAG}, + /* 53 */ {SEC_OID_PKCS5_PBMAC1, SEC_OID_TAG}, ++/* 54 */ {SEC_OID_HMAC_SHA1,SEC_OID_TAG}, ++/* 55 */ {SEC_OID_HMAC_SHA224,SEC_OID_TAG}, ++/* 56 */ {SEC_OID_HMAC_SHA256,SEC_OID_TAG}, ++/* 57 */ {SEC_OID_HMAC_SHA384,SEC_OID_TAG}, ++/* 58 */ {SEC_OID_HMAC_SHA512,SEC_OID_TAG} + /* REMEMBER TO UPDATE NUM_ALGS!!! */ + }; + +diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.h.jmagne ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.h +--- ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.h.jmagne 2016-04-14 11:30:41.871517926 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.h 2016-04-14 11:30:54.933436860 -0700 +@@ -56,7 +56,7 @@ typedef struct JSS_AlgInfoStr { + JSS_AlgType type; + } JSS_AlgInfo; + +-#define NUM_ALGS 54 ++#define NUM_ALGS 59 + + extern JSS_AlgInfo JSS_AlgTable[]; + extern CK_ULONG JSS_symkeyUsage[]; +diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.java.jmagne ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.java +--- ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.java.jmagne 2016-04-14 16:06:13.388021812 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/crypto/Algorithm.java 2016-04-14 16:06:27.537924813 -0700 +@@ -237,5 +237,9 @@ public class Algorithm { + protected static final short SEC_OID_PKCS5_PBKDF2=51; + protected static final short SEC_OID_PKCS5_PBES2=52; + protected static final short SEC_OID_PKCS5_PBMAC1=53; +- ++ protected static final short SEC_OID_HMAC_SHA1=54; ++ protected static final short SEC_OID_HMAC_SHA224=55; ++ protected static final short SEC_OID_HMAC_SHA256=56; ++ protected static final short SEC_OID_HMAC_SHA384=57; ++ protected static final short SEC_OID_HMAC_SHA512=58; + } +diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/CryptoStore.java.jmagne ./mozilla/security/jss/org/mozilla/jss/crypto/CryptoStore.java +--- ./mozilla/security/jss/org/mozilla/jss/crypto/CryptoStore.java.jmagne 2016-04-14 17:03:33.504298176 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/crypto/CryptoStore.java 2016-04-14 17:03:42.198238112 -0700 +@@ -75,6 +75,18 @@ public interface CryptoStore { + getPrivateKeys() throws TokenException; + + /** ++ * Returns all symmetric keys stored on this token. ++ * ++ * @return An array of all symmetric keys stored on this token. ++ * @exception TokenException If an error occurs on the token while ++ * gathering the keys. ++ */ ++ public SymmetricKey[] ++ getSymmetricKeys() throws TokenException; ++ ++ ++ ++ /** + * Deletes the given PrivateKey from the CryptoToken. + * This is a very dangerous call: it deletes the key from the underlying + * token. After calling this, the PrivateKey passed in must no longer +diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/CryptoToken.java.jmagne ./mozilla/security/jss/org/mozilla/jss/crypto/CryptoToken.java +--- ./mozilla/security/jss/org/mozilla/jss/crypto/CryptoToken.java.jmagne 2016-04-14 16:07:39.458429756 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/crypto/CryptoToken.java 2016-04-14 16:07:52.266341595 -0700 +@@ -92,6 +92,9 @@ public interface CryptoToken { + getCipherContext(EncryptionAlgorithm algorithm) + throws java.security.NoSuchAlgorithmException, TokenException; + ++ public abstract SymmetricKeyDeriver getSymmetricKeyDeriver() ++ throws TokenException; ++ + public abstract KeyWrapper + getKeyWrapper(KeyWrapAlgorithm algorithm) + throws java.security.NoSuchAlgorithmException, TokenException; +diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/HMACAlgorithm.java.jmagne ./mozilla/security/jss/org/mozilla/jss/crypto/HMACAlgorithm.java +--- ./mozilla/security/jss/org/mozilla/jss/crypto/HMACAlgorithm.java.jmagne 2016-04-14 16:09:02.858855679 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/crypto/HMACAlgorithm.java 2016-04-14 16:09:18.048751121 -0700 +@@ -85,4 +85,21 @@ public class HMACAlgorithm extends Diges + public static final HMACAlgorithm SHA1 = new HMACAlgorithm + (CKM_SHA_1_HMAC, "SHA-1-HMAC", + OBJECT_IDENTIFIER.ALGORITHM.subBranch(26), 20); ++ ++ public static final HMACAlgorithm SHA224 = new HMACAlgorithm ++ (SEC_OID_HMAC_SHA224, "SHA-224-HMAC", ++ OBJECT_IDENTIFIER.RSADSI.subBranch(8), 28); ++ ++ public static final HMACAlgorithm SHA256 = new HMACAlgorithm ++ (SEC_OID_HMAC_SHA256, "SHA-256-HMAC", ++ OBJECT_IDENTIFIER.RSADSI.subBranch(9), 32); ++ ++ public static final HMACAlgorithm SHA384 = new HMACAlgorithm ++ (SEC_OID_HMAC_SHA384, "SHA-384-HMAC", ++ OBJECT_IDENTIFIER.RSADSI.subBranch(10), 48); ++ ++ public static final HMACAlgorithm SHA512 = new HMACAlgorithm ++ (SEC_OID_HMAC_SHA512, "SHA-512-HMAC", ++ OBJECT_IDENTIFIER.RSADSI.subBranch(11), 64); ++ + } +diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/KeyWrapper.java.jmagne ./mozilla/security/jss/org/mozilla/jss/crypto/KeyWrapper.java +--- ./mozilla/security/jss/org/mozilla/jss/crypto/KeyWrapper.java.jmagne 2016-04-14 16:10:43.930159965 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/crypto/KeyWrapper.java 2016-04-14 16:10:55.377081172 -0700 +@@ -133,4 +133,21 @@ public interface KeyWrapper { + throws TokenException, IllegalStateException, + InvalidAlgorithmParameterException; + ++ public SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, ++ SymmetricKey.Usage usage, int keyLength) ++ throws TokenException, IllegalStateException, ++ InvalidAlgorithmParameterException; ++ ++ /** ++ * Unwraps a key and allows it to be used for all operations. ++ * @param keyLength The expected length of the key in bytes. This is ++ * only used for variable-length keys (RC4) and non-padding ++ * algorithms. Otherwise, it can be set to anything(like 0). ++ */ ++ public SymmetricKey unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, ++ int keyLength) ++ throws TokenException, IllegalStateException, ++ InvalidAlgorithmParameterException; ++ ++ + } +diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/SymmetricKeyDeriver.java.jmagne ./mozilla/security/jss/org/mozilla/jss/crypto/SymmetricKeyDeriver.java +--- ./mozilla/security/jss/org/mozilla/jss/crypto/SymmetricKeyDeriver.java.jmagne 2016-04-14 16:36:36.080464052 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/crypto/SymmetricKeyDeriver.java 2016-04-14 16:36:49.784369514 -0700 +@@ -0,0 +1,79 @@ ++/* ***** 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 ***** */ ++ ++package org.mozilla.jss.crypto; ++ ++import java.security.spec.AlgorithmParameterSpec; ++import java.security.InvalidAlgorithmParameterException; ++import java.security.PublicKey; ++import java.security.InvalidKeyException; ++ ++public interface SymmetricKeyDeriver { ++ ++ /* Use with the encrypt type mechanisms ++ Example: initDerive( ++ symKey, (PKCS11Constants.CKM_DES3_ECB_ENCRYPT_DATA) 4354L, derivationData, null, ++ PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE, 16); ++ */ ++ ++ public abstract void initDerive(SymmetricKey baseKey, ++ long deriveMech, byte[] param, byte[] iv, long targetMech, long operation, long keySize) ++ throws InvalidKeyException; ++ ++ ++ ++ /* Use with key extraction and key concatanation mechanisms ++ ++ Example: ++ param: byte array that has the bit position of where to extract ++ initDerive( ++ derivedKey, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null, ++ PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,8); ++ ++ ++ initDerive( ++ baseSymKey,secondarySymKey, PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY,null,null, ++ PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,0); ++ ++ */ ++ ++ public abstract void initDerive(SymmetricKey baseKey, ++ SymmetricKey secondaryKey, long deriveMech, byte[] param, byte[] iv, long targetMech, long operation, long keySize) ++ throws InvalidKeyException; ++ ++ public abstract SymmetricKey derive() ++ throws TokenException; ++} +diff -up ./mozilla/security/jss/org/mozilla/jss/crypto/SymmetricKey.java.jmagne ./mozilla/security/jss/org/mozilla/jss/crypto/SymmetricKey.java +--- ./mozilla/security/jss/org/mozilla/jss/crypto/SymmetricKey.java.jmagne 2016-04-14 16:11:50.865699222 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/crypto/SymmetricKey.java 2016-04-14 16:12:02.768617289 -0700 +@@ -71,6 +71,10 @@ public interface SymmetricKey { + + String getFormat(); + ++ String getNickName(); ++ ++ void setNickName(String nickName); ++ + public final static class Type { + // all names converted to lowercase for case insensitivity + private static Hashtable nameMap = new Hashtable(); +diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/manifest.mn.jmagne ./mozilla/security/jss/org/mozilla/jss/pkcs11/manifest.mn +--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/manifest.mn.jmagne 2016-04-14 16:15:59.271989344 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/manifest.mn 2016-04-14 16:16:10.670910881 -0700 +@@ -64,6 +64,7 @@ CSRCS = \ + PK11Store.c \ + PK11SymKey.c \ + PK11Token.c \ ++ PK11SymmetricKeyDeriver.c \ + $(NULL) + + +diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c.jmagne ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c +--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c.jmagne 2016-04-14 16:17:29.760366477 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.c 2016-04-14 16:17:58.742166983 -0700 +@@ -519,7 +519,7 @@ JNIEXPORT jobject JNICALL + Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymWithSym + (JNIEnv *env, jclass clazz, jobject tokenObj, jobject unwrapperObj, + jbyteArray wrappedBA, jobject wrapAlgObj, jobject typeAlgObj, +- jint keyLen, jbyteArray ivBA, jint usageEnum) ++ jint keyLen, jbyteArray ivBA, jint usageEnum,jboolean temporary) + { + PK11SymKey *symKey=NULL, *wrappingKey=NULL; + CK_MECHANISM_TYPE wrappingMech, keyTypeMech; +@@ -527,6 +527,7 @@ Java_org_mozilla_jss_pkcs11_PK11KeyWrapp + jobject keyObj = NULL; + CK_ULONG operation; + CK_FLAGS flags; ++ PRBool isPermanent = PR_FALSE; + + /* get key type */ + keyTypeMech = JSS_getPK11MechFromAlg(env, typeAlgObj); +@@ -579,8 +580,21 @@ Java_org_mozilla_jss_pkcs11_PK11KeyWrapp + flags = 0; + } + +- symKey = PK11_UnwrapSymKeyWithFlags(wrappingKey, wrappingMech, param, +- wrappedKey, keyTypeMech, operation, keyLen, flags); ++ if( temporary ) { ++ isPermanent = PR_FALSE; ++ } else { ++ isPermanent = PR_TRUE; ++ } ++ ++ if( isPermanent == PR_FALSE) { ++ symKey = PK11_UnwrapSymKeyWithFlags(wrappingKey, wrappingMech, param, ++ wrappedKey, keyTypeMech, operation, keyLen, flags); ++ ++ } else { ++ symKey = PK11_UnwrapSymKeyWithFlagsPerm(wrappingKey, wrappingMech, param, ++ wrappedKey, keyTypeMech, operation, keyLen, flags,isPermanent); ++ } ++ + if( symKey == NULL ) { + JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to unwrap key"); + goto finish; +@@ -702,7 +716,7 @@ finish: + JNIEXPORT jobject JNICALL + Java_org_mozilla_jss_pkcs11_PK11KeyWrapper_nativeUnwrapSymPlaintext + (JNIEnv *env, jclass clazz, jobject tokenObj, jbyteArray wrappedBA, +- jobject typeAlgObj, jint usageEnum) ++ jobject typeAlgObj, jint usageEnum,jboolean temporary) + { + PK11SymKey *symKey=NULL; + CK_MECHANISM_TYPE keyTypeMech; +@@ -711,6 +725,8 @@ Java_org_mozilla_jss_pkcs11_PK11KeyWrapp + PK11SlotInfo *slot = NULL; + CK_ULONG operation; + CK_FLAGS flags; ++ PRBool isPerm = PR_FALSE; ++ + + /* get key type */ + keyTypeMech = JSS_getPK11MechFromAlg(env, typeAlgObj); +@@ -740,9 +756,15 @@ Java_org_mozilla_jss_pkcs11_PK11KeyWrapp + flags = 0; + } + ++ if( temporary ) { ++ isPerm = PR_FALSE; ++ } else { ++ isPerm = PR_TRUE; ++ } ++ + /* pull in the key */ + symKey = PK11_ImportSymKeyWithFlags(slot, keyTypeMech, PK11_OriginUnwrap, +- operation, wrappedKey, flags, PR_FALSE /*isPerm*/, NULL); ++ operation, wrappedKey, flags, isPerm, NULL); + if( symKey == NULL ) { + JSS_throwMsg(env, TOKEN_EXCEPTION, "Failed to unwrap key"); + goto finish; +diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.java.jmagne ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.java +--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.java.jmagne 2016-04-14 16:19:26.998559480 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11KeyWrapper.java 2016-04-14 16:19:40.941463506 -0700 +@@ -498,8 +498,25 @@ final class PK11KeyWrapper implements Ke + return unwrapSymmetric(wrapped, type, -1, keyLen); + } + ++ public SymmetricKey ++ unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, ++ SymmetricKey.Usage usage, int keyLen) ++ throws TokenException, IllegalStateException, ++ InvalidAlgorithmParameterException ++ { ++ return unwrapSymmetricPerm(wrapped, type, usage.getVal(), keyLen); ++ } ++ ++ public SymmetricKey ++ unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, int keyLen) ++ throws TokenException, IllegalStateException, ++ InvalidAlgorithmParameterException ++ { ++ return unwrapSymmetricPerm(wrapped, type, -1, keyLen); ++ } ++ + private SymmetricKey +- unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type, ++ unwrapSymmetricPerm(byte[] wrapped, SymmetricKey.Type type, + int usageEnum, int keyLen) + throws TokenException, IllegalStateException, + InvalidAlgorithmParameterException +@@ -508,6 +525,10 @@ final class PK11KeyWrapper implements Ke + throw new IllegalStateException(); + } + ++ /* Since we want permanent,make the temporary arg false */ ++ boolean temporary = false; ++ ++ + if( (! algorithm.isPadded()) && (type == SymmetricKey.RC4) ) { + if( keyLen <= 0 ) { + throw new InvalidAlgorithmParameterException( +@@ -521,12 +542,53 @@ final class PK11KeyWrapper implements Ke + + if( algorithm == KeyWrapAlgorithm.PLAINTEXT ) { + return nativeUnwrapSymPlaintext(token, wrapped, algFromType(type), +- usageEnum ); ++ usageEnum,temporary ); + } else { + if( symKey != null ) { + Assert._assert(pubKey==null && privKey==null); + return nativeUnwrapSymWithSym(token, symKey, wrapped, algorithm, +- algFromType(type), keyLen, IV, usageEnum); ++ algFromType(type), keyLen, IV, usageEnum,temporary); ++ } else { ++ Assert._assert(privKey!=null && pubKey==null && symKey==null); ++ throw new TokenException("We do not support permnament unwrapping with private key."); ++ } ++ } ++ } ++ ++ ++ private SymmetricKey ++ unwrapSymmetric(byte[] wrapped, SymmetricKey.Type type, ++ int usageEnum, int keyLen) ++ throws TokenException, IllegalStateException, ++ InvalidAlgorithmParameterException ++ { ++ if( state != UNWRAP ) { ++ throw new IllegalStateException(); ++ } ++ ++ if( (! algorithm.isPadded()) && (type == SymmetricKey.RC4) ) { ++ if( keyLen <= 0 ) { ++ throw new InvalidAlgorithmParameterException( ++ "RC4 keys wrapped in unpadded algorithms need key length"+ ++ " specified when unwrapping"); ++ } ++ } else { ++ // Don't use the key length ++ //keyLen = 0; ++ } ++ ++ /* Since we DONT want permanent,make the temporary arg true */ ++ boolean temporary = true; ++ ++ ++ if( algorithm == KeyWrapAlgorithm.PLAINTEXT ) { ++ return nativeUnwrapSymPlaintext(token, wrapped, algFromType(type), ++ usageEnum, temporary ); ++ } else { ++ if( symKey != null ) { ++ Assert._assert(pubKey==null && privKey==null); ++ return nativeUnwrapSymWithSym(token, symKey, wrapped, algorithm, ++ algFromType(type), keyLen, IV, usageEnum,temporary); + } else { + Assert._assert(privKey!=null && pubKey==null && symKey==null); + return nativeUnwrapSymWithPriv(token, privKey, wrapped, +@@ -586,7 +648,7 @@ final class PK11KeyWrapper implements Ke + private static native SymmetricKey + nativeUnwrapSymWithSym(PK11Token token, SymmetricKey unwrappingKey, + byte[] wrappedKey, KeyWrapAlgorithm alg, Algorithm type, int keyLen, +- byte[] IV, int usageEnum) ++ byte[] IV, int usageEnum,boolean temporary) + throws TokenException; + + /** +@@ -600,7 +662,7 @@ final class PK11KeyWrapper implements Ke + + private static native SymmetricKey + nativeUnwrapSymPlaintext(PK11Token token, byte[] wrappedKey, +- Algorithm type, int usageEnum); ++ Algorithm type, int usageEnum,boolean temporary); + + private void reset() { + state = UNINITIALIZED; +diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11MessageDigest.c.jmagne ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11MessageDigest.c +--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11MessageDigest.c.jmagne 2016-05-06 18:10:04.531912407 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11MessageDigest.c 2016-05-06 17:36:19.913933639 -0700 +@@ -99,17 +99,19 @@ Java_org_mozilla_jss_pkcs11_PK11MessageD + } + + /* copy the key, setting the CKA_SIGN attribute */ +- newKey = PK11_CopySymKeyForSigning(origKey, mech); ++/* newKey = PK11_CopySymKeyForSigning(origKey, mech); + if( newKey == NULL ) { + JSS_throwMsg(env, DIGEST_EXCEPTION, + "Unable to set CKA_SIGN attribute on symmetric key"); + goto finish; + } + ++*/ ++ + param.data = NULL; + param.len = 0; + +- context = PK11_CreateContextBySymKey(mech, CKA_SIGN, newKey, ¶m); ++ context = PK11_CreateContextBySymKey(mech, CKA_SIGN, origKey, ¶m); + if( context == NULL ) { + JSS_throwMsg(env, DIGEST_EXCEPTION, + "Unable to initialize digest context"); +diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Store.c.jmagne ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Store.c +--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Store.c.jmagne 2016-04-14 16:22:16.174394977 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Store.c 2016-04-14 16:22:26.605323176 -0700 +@@ -44,13 +44,101 @@ + #include + #include + #include +- + #include + #include + #include "pk11util.h" + #include + #include + ++typedef struct ++{ ++ enum ++ { ++ PW_NONE = 0, ++ PW_FROMFILE = 1, ++ PW_PLAINTEXT = 2, ++ PW_EXTERNAL = 3 ++ } source; ++ char *data; ++} secuPWData; ++ ++/********************************************************************** ++ * PK11Store.putSymKeysInVector ++ */ ++JNIEXPORT void JNICALL ++Java_org_mozilla_jss_pkcs11_PK11Store_putSymKeysInVector ++ (JNIEnv *env, jobject this, jobject keyVector) ++{ ++ PK11SlotInfo *slot; ++ jobject object = NULL; ++ jclass vectorClass; ++ jmethodID addElement; ++ ++ PK11SymKey *firstSymKey= NULL; ++ PK11SymKey *sk = NULL; ++ PK11SymKey *nextSymKey = NULL; ++ secuPWData pwdata; ++ ++ PK11SymKey *freeSymKey = NULL; ++ PK11SymKey *nextFreeSymKey = NULL; ++ ++ pwdata.source = PW_NONE; ++ pwdata.data = (char *) NULL; ++ ++ PR_ASSERT(env!=NULL && this!=NULL && keyVector!=NULL); ++ ++ if( JSS_PK11_getStoreSlotPtr(env, this, &slot) != PR_SUCCESS) { ++ ASSERT_OUTOFMEM(env); ++ goto finish; ++ } ++ PR_ASSERT(slot!=NULL); ++ ++ vectorClass = (*env)->GetObjectClass(env, keyVector); ++ if(vectorClass == NULL) { ++ ASSERT_OUTOFMEM(env); ++ goto finish; ++ } ++ ++ addElement = (*env)->GetMethodID(env, ++ vectorClass, ++ VECTOR_ADD_ELEMENT_NAME, ++ VECTOR_ADD_ELEMENT_SIG); ++ if(addElement == NULL) { ++ ASSERT_OUTOFMEM(env); ++ goto finish; ++ } ++ ++ PK11_Authenticate(slot, PR_TRUE /*load certs*/, NULL /*wincx*/); ++ ++ /* Obtain the symmetric key list. */ ++ firstSymKey = PK11_ListFixedKeysInSlot( slot , NULL, ( void *) &pwdata ); ++ sk = firstSymKey; ++ ++ while(( sk != NULL )) ++ { ++ if( sk ) { ++ ++ nextSymKey = sk; ++ object = JSS_PK11_wrapSymKey(env, &sk); ++ ++ if(object == NULL) { ++ PR_ASSERT( (*env)->ExceptionOccurred(env) ); ++ goto finish; ++ } ++ ++ /*************************************************** ++ * Insert the key into the vector ++ ***************************************************/ ++ (*env)->CallVoidMethod(env, keyVector, addElement, object); ++ } ++ ++ sk = PK11_GetNextSymKey( nextSymKey ); ++ } ++ ++finish: ++ ++ return; ++} + + /********************************************************************** + * PK11Store.putKeysInVector +diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Store.java.jmagne ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Store.java +--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Store.java.jmagne 2016-04-14 16:23:26.997907471 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Store.java 2016-04-14 16:23:34.435856272 -0700 +@@ -66,8 +66,23 @@ public final class PK11Store implements + keys.copyInto( (Object[]) array ); + return array; + } ++ ++ public synchronized SymmetricKey[] ++ getSymmetricKeys() throws TokenException { ++ ++ Vector keys = new Vector(); ++ putSymKeysInVector(keys); ++ SymmetricKey[] array = new SymmetricKey[keys.size()]; ++ keys.copyInto( (Object[]) array); ++ return array; ++ } ++ ++ ++ + protected native void putKeysInVector(Vector keys) throws TokenException; + ++ protected native void putSymKeysInVector(Vector symKeys) throws TokenException; ++ + + public native void deletePrivateKey(PrivateKey key) + throws NoSuchItemOnTokenException, TokenException; +diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymKey.c.jmagne ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymKey.c +--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymKey.c.jmagne 2016-04-14 16:24:44.565372557 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymKey.c 2016-05-17 11:37:48.532485104 -0700 +@@ -33,7 +33,6 @@ + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ +- + #include "_jni/org_mozilla_jss_pkcs11_SymKeyProxy.h" + + #include +@@ -62,6 +61,8 @@ JSS_PK11_wrapSymKey(JNIEnv *env, PK11Sym + jmethodID constructor; + jbyteArray ptrArray; + jobject Key=NULL; ++ char *nickname = NULL; ++ jstring jnickname = NULL; + + PR_ASSERT(env!=NULL && symKey!=NULL && *symKey!=NULL); + +@@ -72,10 +73,17 @@ JSS_PK11_wrapSymKey(JNIEnv *env, PK11Sym + goto finish; + } + ++ nickname = PK11_GetSymKeyNickname( *symKey ); ++ ++ if (nickname) { ++ jnickname = (*env)->NewStringUTF(env, nickname); ++ } ++ ++ + /* find the constructor */ + constructor = (*env)->GetMethodID(env, keyClass, + PLAIN_CONSTRUCTOR, +- PK11SYMKEY_CONSTRUCTOR_SIG); ++ PK11SYMKEY_CONSTRUCTOR_1_SIG); + if(constructor == NULL) { + ASSERT_OUTOFMEM(env); + goto finish; +@@ -87,12 +95,16 @@ JSS_PK11_wrapSymKey(JNIEnv *env, PK11Sym + goto finish; + } + /* call the constructor */ +- Key = (*env)->NewObject(env, keyClass, constructor, ptrArray); ++ Key = (*env)->NewObject(env, keyClass, constructor, ptrArray,jnickname); + + finish: + if(Key == NULL) { + PK11_FreeSymKey(*symKey); + } ++ if(nickname != NULL) { ++ PORT_Free(nickname); ++ nickname = NULL; ++ } + *symKey = NULL; + return Key; + } +@@ -181,6 +193,49 @@ finish: + + /*********************************************************************** + * ++ * PK11SymKey.setNickNameNative ++ */ ++JNIEXPORT void JNICALL ++Java_org_mozilla_jss_pkcs11_PK11SymKey_setNickNameNative ++ (JNIEnv *env, jobject this,jstring nickname) ++{ ++ PK11SymKey *key=NULL; ++ const char *keyname = NULL; ++ SECStatus status; ++ ++ /* If no nickname provided, we are done */ ++ if( nickname == NULL ) { ++ JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, ++ "Nickname is NULL, will not be set"); ++ goto finish; ++ } ++ ++ /* get the key pointer */ ++ if( JSS_PK11_getSymKeyPtr(env, this, &key) != PR_SUCCESS) { ++ goto finish; ++ } ++ ++ /* convert the Java String into a native "C" string */ ++ keyname = (*env)->GetStringUTFChars( env, nickname, 0 ); ++ ++ /* name the key */ ++ status = PK11_SetSymKeyNickname( key, keyname ); ++ if( status != SECSuccess ) { ++ JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, ++ "Failed to name symmetric key"); ++ } ++finish: ++ ++ if( keyname != NULL ) { ++ /* free the native "C" string */ ++ (*env)->ReleaseStringUTFChars(env, nickname, keyname); ++ } ++ ++ return; ++} ++ ++/*********************************************************************** ++ * + * PK11SymKey.getKeyData + */ + JNIEXPORT jbyteArray JNICALL +@@ -279,6 +334,10 @@ Java_org_mozilla_jss_pkcs11_PK11SymKey_g + case CKK_AES: + typeFieldName = AES_KEYTYPE_FIELD; + break; ++ case CKK_DES2: ++ printf("hello des2! \n"); ++ typeFieldName = DES3_KEYTYPE_FIELD; ++ break; + default: + PR_ASSERT(PR_FALSE); + typeFieldName = DES_KEYTYPE_FIELD; +diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymKey.java.jmagne ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymKey.java +--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymKey.java.jmagne 2016-04-14 16:58:33.385371633 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymKey.java 2016-05-17 11:41:36.323841045 -0700 +@@ -44,9 +44,17 @@ public final class PK11SymKey implements + protected PK11SymKey(byte[] pointer) { + Assert._assert(pointer!=null); + keyProxy = new SymKeyProxy(pointer); ++ nickName = null; ++ } ++ ++ protected PK11SymKey(byte[] pointer,String nickName) { ++ Assert._assert(pointer!=null); ++ keyProxy = new SymKeyProxy(pointer); ++ this.nickName = nickName; + } + + private SymKeyProxy keyProxy; ++ private String nickName; + + public SymmetricKey.Type getType() { + KeyType kt = getKeyType(); +@@ -108,6 +116,20 @@ public final class PK11SymKey implements + public String getFormat() { + return "RAW"; + } ++ ++ public String getNickName() { ++ return nickName; ++ } ++ ++ public void setNickName(String nickName) { ++ this.nickName = nickName; ++ ++ if( nickName != null) { ++ setNickNameNative(nickName); ++ } ++ } ++ ++ public native void setNickNameNative(String nickName); + } + + class SymKeyProxy extends KeyProxy { +diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymmetricKeyDeriver.c.jmagne ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymmetricKeyDeriver.c +--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymmetricKeyDeriver.c.jmagne 2016-04-14 16:26:18.611723763 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymmetricKeyDeriver.c 2016-05-17 14:13:35.456574082 -0700 +@@ -0,0 +1,364 @@ ++/* ***** 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 ***** */ ++#include "_jni/org_mozilla_jss_pkcs11_PK11SymmetricKeyDeriver.h" ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "java_ids.h" ++ ++#include "pk11util.h" ++#include ++ ++/*********************************************************************** ++ * Expose the NSS functionality at low level, one should know what to do ++ * at the Java level. ++ */ ++ ++JNIEXPORT jobject JNICALL Java_org_mozilla_jss_pkcs11_PK11SymmetricKeyDeriver_nativeDeriveSymKey ++ (JNIEnv * env, jobject this,jobject tokenObj, ++ jobject baseKeyObj, jobject secondaryKeyObj, ++ jlong deriveMechanism, jbyteArray param, jbyteArray iv, jlong targetMechanism, jlong operation, jlong keySize) ++{ ++ jobject keyObj = NULL; ++ PK11SlotInfo *slot=NULL; ++ PK11SlotInfo *bestSlot = NULL; ++ PK11SlotInfo *slotForKey = NULL; ++ PK11SlotInfo *slotForSecondaryKey = NULL; ++ PK11SlotInfo *finalSlot = NULL; ++ PK11SlotInfo *finalSecondarySlot = NULL; ++ PK11SlotInfo *finalBaseKeySlot = NULL; ++ ++ PK11SymKey *baseKey = NULL; ++ PK11SymKey *bestBaseKey = NULL; ++ PK11SymKey *finalBaseKey = NULL; ++ PK11SymKey *newKey = NULL; ++ ++ PK11SymKey *secondaryKey = NULL; ++ PK11SymKey *bestSecondaryKey = NULL; ++ PK11SymKey *finalSecondaryKey = NULL; ++ PK11SymKey *derivedKey = NULL; ++ jbyte *paramValue = NULL; ++ int paramLength = 0; ++ jbyte *ivValue = NULL; ++ int ivLength = 0; ++ ++ ++ CK_OBJECT_HANDLE keyhandle = 0; ++ ++ CK_AES_CBC_ENCRYPT_DATA_PARAMS aes; ++ CK_DES_CBC_ENCRYPT_DATA_PARAMS des; ++ CK_KEY_DERIVATION_STRING_DATA string; ++ ++ SECItem paramsItem = { siBuffer, NULL, 0 }; ++ ++ PR_ASSERT(env!=NULL && this!=NULL); ++ ++ if( baseKeyObj == 0) { ++ PR_fprintf(PR_STDOUT,"baseKeyObj can not be null!\n"); ++ goto loser; ++ } ++ ++ if( param != NULL) { ++ paramValue = (*env)->GetByteArrayElements(env,param, NULL); ++ paramLength = (*env)->GetArrayLength(env,param); ++ } ++ ++ if( iv != NULL) { ++ ivValue = (*env)->GetByteArrayElements(env,iv, NULL); ++ ivLength = (*env)->GetArrayLength(env,iv); ++ } ++ ++ /* Set up the params data for the PK11_Derive family */ ++ ++ switch ( deriveMechanism ) { ++ case CKM_DES_ECB_ENCRYPT_DATA: ++ case CKM_DES3_ECB_ENCRYPT_DATA: ++ case CKM_AES_ECB_ENCRYPT_DATA: ++ case CKM_CAMELLIA_ECB_ENCRYPT_DATA: ++ case CKM_SEED_ECB_ENCRYPT_DATA: ++ /* Use CK_KEY_DERIVATION_STRING_DATA */ ++ ++ string.pData = (unsigned char *) paramValue; ++ string.ulLen = paramLength; ++ paramsItem.data = (void *) &string; ++ paramsItem.len = sizeof(string); ++ ++ break; ++ case CKM_DES_CBC_ENCRYPT_DATA: ++ case CKM_DES3_CBC_ENCRYPT_DATA: ++ /* Use CK_DES_CBC_ENCRYPT_DATA_PARAMS */ ++ ++ if( ivValue == NULL) { ++ PR_fprintf(PR_STDOUT, "Need iv param for CKM_DES_CBC_ENCRYPT_DATA or CKM_DES3_CBC_ENCRYPT_DATA. \n"); ++ goto loser; ++ } ++ ++ if( ivLength != 8) { ++ PR_fprintf(PR_STDOUT, "Need iv param for CKM_DES_CBC_ENCRYPT_DATA structure to be 8 bytes!. \n"); ++ goto loser; ++ } ++ ++ des.pData = (unsigned char *) paramValue; ++ des.length = paramLength; ++ PORT_Memcpy(des.iv,ivValue,ivLength); ++ paramsItem.data = (void *) &des; ++ paramsItem.len = sizeof(des); ++ ++ break; ++ ++ case CKM_AES_CBC_ENCRYPT_DATA: ++ case CKM_CAMELLIA_CBC_ENCRYPT_DATA: ++ case CKM_SEED_CBC_ENCRYPT_DATA: ++ /* Use CK_AES_CBC_ENCRYPT_DATA_PARAMS */ ++ ++ if ( ivValue == NULL ) { ++ PR_fprintf(PR_STDOUT, "Need iv param for CBC encrypt derive for AES, or CAMELLIA or SEED. \n"); ++ goto loser; ++ } ++ ++ if( ivLength != 16) { ++ PR_fprintf(PR_STDOUT, "Need iv param for CK_AES_CBC_ENCRYPT_DATA_PARAMS structure to be 16 bytes!. \n"); ++ goto loser; ++ } ++ ++ aes.pData = (unsigned char *) paramValue; ++ aes.length = paramLength; ++ PORT_Memcpy(aes.iv,ivValue,ivLength); ++ paramsItem.data = (void *) &aes; ++ paramsItem.len = sizeof(aes); ++ break; ++ default: ++ paramsItem.data = (unsigned char *) paramValue; ++ paramsItem.len = paramLength; ++ break; ++ } ++ ++ /* Get slot */ ++ if( JSS_PK11_getTokenSlotPtr(env, tokenObj, &slot) != PR_SUCCESS) { ++ goto loser; ++ } ++ ++ /* Get base key */ ++ ++ if( JSS_PK11_getSymKeyPtr(env, baseKeyObj, &baseKey) != PR_SUCCESS) { ++ PR_fprintf(PR_STDOUT, "PK11SymmetricKeyDeriver.nativeDeriveSymKey: Unable to extract symmetric base key!"); ++ goto loser; ++ } ++ ++ /* Ask NSS what the best slot for the given mechanism */ ++ ++ bestSlot = PK11_GetBestSlot(deriveMechanism, NULL); ++ ++ if( bestSlot == NULL) { ++ PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: Can't find suitable slot for sym key derivation! \n"); ++ goto loser; ++ } ++ ++ slotForKey = PK11_GetSlotFromKey(baseKey); ++ ++ int keyOnRequestedSlot = 0; ++ int baseKeyMoved= 0; ++ ++ if(slotForKey != slot) { ++ keyOnRequestedSlot = 0; ++ } else { ++ keyOnRequestedSlot = 1; ++ finalBaseKeySlot = slot; ++ } ++ ++ if ( PK11_DoesMechanism( slot, deriveMechanism)) { ++ if ( keyOnRequestedSlot ) { ++ finalBaseKey = baseKey; ++ } else { ++ bestBaseKey = PK11_MoveSymKey( slot, CKA_ENCRYPT, 0, PR_FALSE, baseKey ); ++ if(bestBaseKey == NULL) { ++ PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: Can't move Base Key to requested slot!\n"); ++ goto loser; ++ } ++ baseKeyMoved = 1; ++ finalBaseKey = bestBaseKey; ++ finalBaseKeySlot = slot; ++ } ++ ++ } else { ++ bestBaseKey = PK11_MoveSymKey( bestSlot, CKA_ENCRYPT, 0, PR_FALSE, baseKey ); ++ if(bestBaseKey == NULL) { ++ PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: Can't move Base Key to best slot!\n"); ++ goto loser; ++ } ++ baseKeyMoved = 1; ++ finalBaseKey = bestBaseKey; ++ finalBaseKeySlot = bestSlot; ++ } ++ ++ /* Assume we want to do a concatenation family here */ ++ ++ if( secondaryKeyObj != NULL) { ++ if( JSS_PK11_getSymKeyPtr(env, secondaryKeyObj, &secondaryKey) != PR_SUCCESS) { ++ PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: Can't find secondary sym key!\n"); ++ goto loser; ++ } ++ ++ /* Make sure the secondary key is in the proper slot to do concatenation */ ++ ++ slotForSecondaryKey = PK11_GetSlotFromKey( secondaryKey ); ++ ++ if( finalBaseKeySlot != slotForSecondaryKey ) { ++ ++ finalSecondaryKey = PK11_MoveSymKey (finalBaseKeySlot, CKA_ENCRYPT, 0, PR_FALSE, secondaryKey); ++ ++ if( finalSecondaryKey == NULL) { ++ PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey, Problem moving secondary key to proper slot.\n"); ++ goto loser; ++ } ++ } else { ++ finalSecondaryKey = secondaryKey; ++ } ++ ++ if( paramValue == NULL) { ++ keyhandle = PK11_GetSymKeyHandle(finalSecondaryKey); ++ ++ if( keyhandle == 0) { ++ PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey, can't get handle for secondary sym key.\n"); ++ goto loser; ++ } ++ ++ paramsItem.data=(unsigned char *) &keyhandle; ++ paramsItem.len=sizeof(keyhandle); ++ ++ } else { ++ PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: incorrect input parameter provided!\n"); ++ goto loser; ++ } ++ } ++ ++ derivedKey = PK11_Derive(finalBaseKey, deriveMechanism, ¶msItem, targetMechanism, ++ operation, keySize); ++ if(derivedKey == NULL) { ++ PR_fprintf(PR_STDOUT, ++ "ERROR: Can't derive symmetric key, error: %d \n",PR_GetError()); ++ goto loser; ++ } ++ ++ if ( (finalSlot = PK11_GetSlotFromKey(derivedKey )) != slot) { ++ newKey = PK11_MoveSymKey ( slot, CKA_ENCRYPT, 0, PR_FALSE, derivedKey); ++ ++ if ( newKey == NULL ) { ++ PR_fprintf(PR_STDOUT,"PK11SymmetricKeyDeriver.nativeDeriveSymKey: error moving key to original slot, return anyway. \n"); ++ newKey = derivedKey; ++ derivedKey = NULL; ++ } ++ ++ } else { ++ newKey = derivedKey; ++ derivedKey = NULL; ++ } ++ ++ keyObj = JSS_PK11_wrapSymKey(env, &newKey); ++ ++loser: ++ ++ if ( bestBaseKey != NULL ) { ++ PK11_FreeSymKey ( bestBaseKey ); ++ bestBaseKey = NULL; ++ } ++ ++ if ( bestSecondaryKey != NULL ) { ++ PK11_FreeSymKey ( bestSecondaryKey ); ++ bestSecondaryKey = NULL; ++ } ++ ++ if ( derivedKey != NULL) { ++ PK11_FreeSymKey ( derivedKey ); ++ derivedKey = NULL; ++ } ++ ++ if (bestSlot != NULL ) { ++ PK11_FreeSlot(bestSlot); ++ bestSlot = NULL; ++ } ++ ++ if ( slotForKey != NULL ) { ++ PK11_FreeSlot( slotForKey ); ++ slotForKey = NULL; ++ } ++ ++ if ( finalSlot != NULL ) { ++ PK11_FreeSlot( finalSlot ); ++ finalSlot = NULL; ++ } ++ ++ if ( finalSecondarySlot != NULL ) { ++ PK11_FreeSlot( finalSecondarySlot ); ++ finalSecondarySlot = NULL; ++ } ++ ++ if ( slotForSecondaryKey != NULL ) { ++ PK11_FreeSlot( slotForSecondaryKey ); ++ slotForSecondaryKey = NULL; ++ } ++ ++ if(paramValue) { ++ (*env)->ReleaseByteArrayElements(env, param, (jbyte*)paramValue, ++ JNI_ABORT); ++ } ++ if(ivValue) { ++ (*env)->ReleaseByteArrayElements(env, iv, (jbyte*)ivValue, ++ JNI_ABORT); ++ } ++ ++ if( keyObj == NULL) { ++ JSS_throwMsgPrErr(env, TOKEN_EXCEPTION, "Unable to derive symmetric key! " ++ "failure!"); ++ } ++ ++ return keyObj; ++} +diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymmetricKeyDeriver.java.jmagne ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymmetricKeyDeriver.java +--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymmetricKeyDeriver.java.jmagne 2016-04-14 16:28:29.179823017 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11SymmetricKeyDeriver.java 2016-04-14 16:28:36.186774680 -0700 +@@ -0,0 +1,158 @@ ++/* ***** 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 ***** */ ++ ++package org.mozilla.jss.pkcs11; ++ ++import org.mozilla.jss.crypto.*; ++import org.mozilla.jss.util.Assert; ++import sun.security.pkcs11.wrapper.*; ++import java.security.InvalidKeyException; ++ ++ ++/*This operation is pkcs11 based only */ ++ ++public class PK11SymmetricKeyDeriver implements SymmetricKeyDeriver { ++ ++ private PK11Token token = null; ++ private SymmetricKey baseKey = null; ++ private SymmetricKey secondaryKey = null; ++ private long deriveMechanism = 0; ++ private long targetMechanism = 0; ++ private long operation = 0; ++ private long keySize = 0; ++ private byte[] param = null; ++ private byte[] iv = null; ++ ++ public PK11SymmetricKeyDeriver(PK11Token token) ++ { ++ this.token = token; ++ } ++ ++ /* Use with the encrypt type mechanisms ++ ++ Example: initDerive( ++ symKey, (PKCS11Constants.CKM_DES3_ECB_ENCRYPT_DATA) 4354L, derivationData, null, ++ PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE, 16); ++ ++ ++ */ ++ public void initDerive(SymmetricKey baseKey, long deriveMech, byte[] param, byte[] iv, ++ long targetMech, long operation, long keySize) throws InvalidKeyException ++ { ++ reset(); ++ ++ if(baseKey == null) { ++ throw new InvalidKeyException("Key is null"); ++ } ++ ++ this.baseKey = baseKey; ++ this.deriveMechanism = deriveMech; ++ this.targetMechanism = targetMech; ++ this.operation = operation; ++ ++ if ( param != null) { ++ this.param = new byte[param.length]; ++ System.arraycopy(param,0,this.param,0,param.length); ++ } ++ ++ if ( iv != null) { ++ this.iv = new byte[iv.length]; ++ System.arraycopy(iv,0,this.iv,0,iv.length); ++ } ++ ++ this.keySize = keySize; ++ ++ } ++ ++ /* Use with key extraction and key concatanation mechanisms ++ ++ Example Extraction: ++ param: byte array that has the bit position of where to extract ++ initDerive( ++ derivedKey, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null, ++ PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,8); ++ ++ Example Concat: ++ ++ initDerive( ++ baseSymKey,secondarySymKey, PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY,null,null, ++ PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,0); ++ ++ */ ++ ++ public void initDerive(SymmetricKey baseKey, SymmetricKey secondaryKey, long deriveMech, ++ byte[] param, byte[] iv, long targetMech, long operation, long keySize) throws InvalidKeyException ++ { ++ reset(); ++ ++ if ( baseKey == null || secondaryKey == null) { ++ throw new InvalidKeyException("Key is null"); ++ } ++ ++ initDerive(baseKey, deriveMech, param,iv,targetMech,operation,keySize); ++ this.secondaryKey = secondaryKey; ++ ++ } ++ ++ ++ public SymmetricKey derive() ++ throws TokenException ++ { ++ SymmetricKey result = deriveSymKey(this.baseKey,this.secondaryKey,this.deriveMechanism, this.param, this.iv, this.targetMechanism, this.operation,this.keySize); ++ return result; ++ } ++ ++ private SymmetricKey ++ deriveSymKey(SymmetricKey baseKey, SymmetricKey secondaryKey, long deriveMechanism, byte[] param, byte[] iv, long targetMechanism, long operation, long keySize) ++ throws TokenException, IllegalStateException ++ { ++ return nativeDeriveSymKey(token, baseKey, secondaryKey,deriveMechanism, param, iv, targetMechanism, operation, keySize); ++ } ++ ++ public native SymmetricKey nativeDeriveSymKey(PK11Token token, SymmetricKey baseKey, SymmetricKey secondaryKey, long deriveMechanism, byte[] param, byte[] iv, ++ long targetMechanism, long operation, long keySize); ++ ++ private void reset() { ++ baseKey = null; ++ secondaryKey = null; ++ deriveMechanism = 0; ++ targetMechanism = 0; ++ operation = 0; ++ keySize = 0; ++ param = null; ++ iv = null; ++ } ++} +diff -up ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Token.java.jmagne ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Token.java +--- ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Token.java.jmagne 2016-04-14 16:30:46.098878459 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/pkcs11/PK11Token.java 2016-04-14 17:27:30.918367372 -0700 +@@ -131,6 +131,11 @@ public final class PK11Token implements + return PK11KeyGenerator.clone(key, this); + } + ++ public PK11SymmetricKeyDeriver getSymmetricKeyDeriver() ++ { ++ return new PK11SymmetricKeyDeriver(this); ++ } ++ + public KeyWrapper + getKeyWrapper(KeyWrapAlgorithm algorithm) + throws NoSuchAlgorithmException, TokenException +diff -up ./mozilla/security/jss/org/mozilla/jss/tests/SymKeyDeriving.java.jmagne ./mozilla/security/jss/org/mozilla/jss/tests/SymKeyDeriving.java +--- ./mozilla/security/jss/org/mozilla/jss/tests/SymKeyDeriving.java.jmagne 2016-04-14 16:32:58.529964860 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/tests/SymKeyDeriving.java 2016-05-17 11:43:51.858862556 -0700 +@@ -0,0 +1,516 @@ ++/* ***** 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 ***** */ ++ ++package org.mozilla.jss.tests; ++ ++import org.mozilla.jss.crypto.*; ++import org.mozilla.jss.CryptoManager; ++import org.mozilla.jss.util.Assert; ++import org.mozilla.jss.pkcs11.*; ++import sun.security.pkcs11.wrapper.PKCS11Constants; ++import java.nio.ByteBuffer; ++import java.util.Arrays; ++import java.util.Vector; ++import java.util.Enumeration; ++ ++/** ++ * Sym Key deriving tests.. ++ * ++ */ ++ ++public class SymKeyDeriving { ++ ++ private static final byte[] iv8 = new byte [] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8 }; ++ private static final byte[] iv16 = new byte [] { 0x1, 0x2, 0x3, 0x4, ++ 0x5, 0x6, 0x7, 0x8, ++ 0x9,0xa, 0xb, 0xc,0xd,0xe, 0xf,0x10 }; ++ ++ private static final byte[] derivationData1 = new byte[] { 0x11, 0x11, 0x13, ++ 0x14, 0x15, 0x16, 0x17, 0x18 }; ++ ++ private static final byte[] derivationData2 = new byte [] { 0x9, 0xa, 0xb, 0xc, 0xd, ++ 0xe, 0xf, 0x10 }; ++ ++ private static final byte[] derivationData16 = new byte[] { 0x1, 0x2, 0x3, 0x4, 0x5, 0x6,0x7, 0x8, ++ 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10 }; ++ ++ ++ public static void main(String args[]) { ++ ++ SymmetricKey macKeyDev = null; ++ try { ++ ++ CryptoManager.InitializationValues vals = ++ new CryptoManager.InitializationValues("./" ++ ); ++ CryptoManager.initialize(vals); ++ CryptoManager cm = CryptoManager.getInstance(); ++ CryptoToken token = cm.getInternalCryptoToken(); ++ CryptoToken keyToken = cm.getInternalKeyStorageToken(); ++ System.out.println("interal token name: " + keyToken.getName()); ++ KeyGenerator keyKg = keyToken.getKeyGenerator(KeyGenAlgorithm.DES3); ++ SymmetricKey baseKey = keyKg.generate(); ++ ++ ++ KeyGenerator keyKgDes = keyToken.getKeyGenerator(KeyGenAlgorithm.DES); ++ SymmetricKey baseKeyDes = keyKgDes.generate(); ++ System.out.println("strength: " + baseKeyDes.getStrength()); ++ ++ ++ KeyGenerator keyKgAES = keyToken.getKeyGenerator(KeyGenAlgorithm.AES); ++ keyKgAES.initialize(128); ++ SymmetricKey baseKeyAES = keyKgAES.generate(); ++ ++ ++ ++ System.out.println("baseKey bytes: "); ++ byte[] baseBytes = baseKey.getEncoded(); ++ displayByteArray(baseBytes,true); ++ ++ ++ /*****************************************************************************************************/ ++ ++ System.out.println("\n Mechanism CKM_EXTRACT_KEY_FROM_KEY test 16 bytes. \n"); ++ ++ ++ SymmetricKeyDeriver deriver = token.getSymmetricKeyDeriver(); ++ System.out.println("deriver: " + deriver); ++ System.out.println("CKM_EXTRACT_KEY_FROM_KEY : " + PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY); ++ ++ long bitPosition = 0; ++ ++ byte[] param = longToBytes(bitPosition); ++ ++ deriver.initDerive( ++ baseKey, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null, ++ PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,(long) 16); ++ ++ ++ SymmetricKey extracted16 = deriver.derive(); ++ ++ System.out.println("Derived key: " + extracted16); ++ ++ if(extracted16 == null) { ++ System.out.println("Failed to derive 16 byte key with mechanism: CKM_EXTRACT_KEY_FROM_KEY \n"); ++ } ++ ++ System.out.println("derivedKey 16 bytes: "); ++ byte[] derivedBytes = extracted16.getEncoded(); ++ displayByteArray(derivedBytes,true); ++ ++ ++ /*****************************************************************************************************/ ++ ++ System.out.println("\n Mechanism CKM_EXTRACT_KEY_FROM_KEY test 8 bytes. \n"); ++ ++ ++ SymmetricKeyDeriver extract8 = token.getSymmetricKeyDeriver(); ++ extract8.initDerive( ++ extracted16, PKCS11Constants.CKM_EXTRACT_KEY_FROM_KEY,param,null, ++ PKCS11Constants.CKA_ENCRYPT, PKCS11Constants.CKA_DERIVE,(long) 8); ++ ++ ++ SymmetricKey extracted8 = extract8.derive(); ++ System.out.println("Derived key: " + extracted8); ++ ++ if(extracted8 == null) { ++ System.out.println("Failed to derive key extracted 8 bytes with mechanism: CKM_EXTRACT_KEY_FROM_KEY \n"); ++ } ++ ++ byte[] extracted8Bytes = extracted8.getEncoded(); ++ System.out.println("derived extracted 8 bytes of key: "); ++ displayByteArray(extracted8Bytes,true); ++ ++ ++ /*****************************************************************************************************/ ++ ++ ++ System.out.println("\n Mechanism CKM_CONCATENATE_BASE_AND_KEY test 16 + 8 = 24 byte key. \n"); ++ ++ SymmetricKeyDeriver concat = keyToken.getSymmetricKeyDeriver(); ++ concat.initDerive( ++ extracted16,extracted8, PKCS11Constants.CKM_CONCATENATE_BASE_AND_KEY,null,null, ++ PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,(long) 0); ++ ++ SymmetricKey concated24 = concat.derive(); ++ ++ if( concated24 == null) { ++ System.out.println("Failed to derive key concated 8 bytes to 16 bytes key: CKM_CONCATENATE_BASE_AND_KEY \n"); ++ } ++ ++ byte[] concated24Bytes = concated24.getEncoded(); ++ System.out.println("derived concated 16 + 8 = 24 byte key: "); ++ displayByteArray(concated24Bytes,true); ++ ++ /*****************************************************************************************************/ ++ ++ // Now lets try more complex derivation ++ ++ // tmp2 = PK11_Derive( master , CKM_DES_ECB_ENCRYPT_DATA , ¶m , CKM_CONCATENATE_BASE_AND_KEY , CKA_DERIVE , 0); ++ ++ System.out.println("\n Mechanism CKM_DES_ECB_ENCRYPT_DATA test. \n"); ++ ++ SymmetricKeyDeriver encrypt = token.getSymmetricKeyDeriver(); ++ ++ encrypt.initDerive( ++ baseKeyDes, /* PKCS11Constants.CKM_DES_ECB_ENCRYPT_DATA */ 4352L,derivationData1 ,null, ++ PKCS11Constants.CKM_DES_ECB, PKCS11Constants.CKA_DERIVE,(long) 8); ++ ++ SymmetricKey encrypted8 = encrypt.derive(); ++ ++ if( encrypted8 == null) { ++ System.out.println("Failed to derive 8 bytes from encrypted derivation data."); ++ } ++ ++ byte[] encrypted8Bytes = encrypted8.getEncoded(); ++ System.out.println("derived encrypted 8 bytes: " + encrypted8Bytes.length); ++ displayByteArray(encrypted8Bytes,true); ++ ++ Cipher cipher = null; ++ cipher = keyToken.getCipherContext(EncryptionAlgorithm.DES_ECB); ++ ++ cipher.initEncrypt(baseKeyDes); ++ ++ byte[] ciphertext = cipher.doFinal(derivationData1); ++ displayByteArray(ciphertext,true); ++ ++ if ( ciphertext.length != encrypted8Bytes.length ) { ++ System.out.println("FAILED: encrypted data length not equal to derived key length."); ++ } else { ++ for ( int i = 0; i < ciphertext.length ; i ++) { ++ ciphertext[i]&=0xfe; ++ encrypted8Bytes[i]&=0xfe; ++ } ++ if ( Arrays.equals(ciphertext, encrypted8Bytes)) { ++ System.out.println("PASSED: derived key the same as encrypted data."); ++ } else { ++ ++ System.out.println("FAILED: derived key not the same as encrypted data."); ++ } ++ } ++ ++ ++ /*****************************************************************************************************/ ++ ++ // Try ecnrypted des3 derivation ++ ++ System.out.println("\n Mechanism CKM_DES3_ECB_ENCRYPT_DATA test. \n"); ++ ++ SymmetricKeyDeriver encryptDes3 = token.getSymmetricKeyDeriver(); ++ ++ encryptDes3.initDerive( ++ baseKey, /* PKCS11Constants.CKM_DES3_ECB_ENCRYPT_DATA */ 4354L ,derivationData16 ,null, ++ PKCS11Constants.CKM_DES3_ECB, PKCS11Constants.CKA_DERIVE,(long) 16); ++ ++ ++ SymmetricKey encrypted16 = encryptDes3.derive(); ++ ++ if ( encrypted16 == null) { ++ System.out.println("Failed to derive 16 bytes from encrypted derivation data."); ++ } ++ ++ byte[] encrypted16Bytes = encrypted16.getEncoded(); ++ ++ System.out.println("derived encrypted 16 bytes: " + encrypted16Bytes.length); ++ displayByteArray(encrypted16Bytes,true); ++ ++ ++ cipher = keyToken.getCipherContext(EncryptionAlgorithm.DES3_ECB); ++ cipher.initEncrypt(baseKey); ++ ciphertext = cipher.doFinal(derivationData16); ++ displayByteArray(ciphertext,true); ++ ++ if ( ciphertext.length != encrypted16Bytes.length ) { ++ System.out.println("FAILED: encrypted data length not equal to derived key length."); ++ } else { ++ for ( int i = 0; i < ciphertext.length ; i ++) { ++ ciphertext[i]&=0xfe; ++ encrypted16Bytes[i]&=0xfe; ++ } ++ if ( Arrays.equals(ciphertext, encrypted16Bytes)) { ++ System.out.println("PASSED: derived key the same as encrypted data."); ++ } else { ++ System.out.println("FAILED: derived key not the same as encrypted data."); ++ } ++ } ++ ++ ++ /*****************************************************************************************************/ ++ ++ System.out.println("\n Mechanism CKM_DES_CBC_ENCRYPT_DATA test. \n"); ++ ++ SymmetricKeyDeriver encryptDesCBC = token.getSymmetricKeyDeriver(); ++ ++ encryptDesCBC.initDerive( ++ baseKeyDes, /* PKCS11Constants.CKM_DES_CBC_ENCRYPT_DATA */ 4353L ,derivationData1 ,iv8, ++ PKCS11Constants.CKM_DES_CBC, PKCS11Constants.CKA_DERIVE,(long) 8); ++ ++ ++ SymmetricKey encryptedDesCBC = encryptDesCBC.derive(); ++ ++ if ( encryptedDesCBC == null) { ++ System.out.println("Failed to derive 8 bytes from encrypted derivation data."); ++ } ++ ++ byte[] encryptedDesCBCBytes = encryptedDesCBC.getEncoded(); ++ ++ System.out.println("derived encrypted 8 bytes: " + encryptedDesCBCBytes.length); ++ displayByteArray(encryptedDesCBCBytes,true); ++ ++ ++ cipher = keyToken.getCipherContext(EncryptionAlgorithm.DES_CBC); ++ cipher.initEncrypt(baseKeyDes,new IVParameterSpec(iv8)); ++ ciphertext = cipher.doFinal(derivationData1); ++ displayByteArray(ciphertext,true); ++ ++ if ( ciphertext.length != encryptedDesCBCBytes.length ) { ++ System.out.println("FAILED: encrypted data length not equal to derived key length."); ++ } else { ++ for ( int i = 0; i < ciphertext.length ; i ++) { ++ ciphertext[i]&=0xfe; ++ encryptedDesCBCBytes[i]&=0xfe; ++ } ++ if ( Arrays.equals(ciphertext, encryptedDesCBCBytes)) { ++ System.out.println("PASSED: derived key the same as encrypted data."); ++ } else { ++ ++ System.out.println("FAILED: derived key not the same as encrypted data."); ++ } ++ } ++ ++ /*****************************************************************************************************/ ++ ++ System.out.println("\n Mechanism CKM_DES3_CBC_ENCRYPT_DATA test. \n"); ++ ++ SymmetricKeyDeriver encryptDes3CBC = token.getSymmetricKeyDeriver(); ++ ++ encryptDes3CBC.initDerive( ++ baseKey, /* PKCS11Constants.CKM_DES3_CBC_ENCRYPT_DATA */ 4355L ,derivationData16 ,iv8, ++ PKCS11Constants.CKM_DES3_CBC, PKCS11Constants.CKA_DERIVE,(long) 16); ++ ++ ++ SymmetricKey encryptedDes3CBC = encryptDes3CBC.derive(); ++ ++ if ( encryptedDes3CBC == null) { ++ System.out.println("Failed to derive 16 bytes from encrypted derivation data."); ++ } ++ ++ byte[] encryptedDes3CBCBytes = encryptedDes3CBC.getEncoded(); ++ ++ System.out.println("derived encrypted 16 bytes: " + encryptedDes3CBCBytes.length); ++ displayByteArray(encryptedDes3CBCBytes,true); ++ ++ ++ cipher = keyToken.getCipherContext(EncryptionAlgorithm.DES3_CBC); ++ cipher.initEncrypt(baseKey,new IVParameterSpec(iv8)); ++ ciphertext = cipher.doFinal(derivationData16); ++ displayByteArray(ciphertext,true); ++ ++ if ( ciphertext.length != encryptedDes3CBCBytes.length ) { ++ System.out.println("FAILED: encrypted data length not equal to derived key length."); ++ } else { ++ for ( int i = 0; i < ciphertext.length ; i ++) { ++ ciphertext[i]&=0xfe; ++ encryptedDes3CBCBytes[i]&=0xfe; ++ } ++ if ( Arrays.equals(ciphertext, encryptedDes3CBCBytes)) { ++ System.out.println("PASSED: derived key the same as encrypted data."); ++ } else { ++ ++ System.out.println("FAILED: derived key not the same as encrypted data."); ++ } ++ } ++ ++ /*****************************************************************************************************/ ++ ++ System.out.println("\n Mechanism CKM_AES_ECB_ENCRYPT_DATA test. \n"); ++ ++ SymmetricKeyDeriver encryptAESECB = token.getSymmetricKeyDeriver(); ++ ++ //System.in.read(); ++ encryptAESECB.initDerive( ++ baseKeyAES, /* PKCS11Constants.CKM_AES_ECB_ENCRYPT_DATA */ 4356L ,derivationData16 ,null, ++ PKCS11Constants.CKM_AES_ECB, PKCS11Constants.CKA_DERIVE,(long) 16); ++ ++ ++ SymmetricKey encryptedAESECB = encryptAESECB.derive(); ++ ++ if ( encryptedAESECB == null) { ++ System.out.println("Failed to derive 16 bytes from encrypted derivation data."); ++ } ++ ++ byte[] encryptedAESECBBytes = encryptedAESECB.getEncoded(); ++ ++ System.out.println("derived encrypted 16 bytes: " + encryptedAESECBBytes.length); ++ displayByteArray(encryptedAESECBBytes,true); ++ ++ ++ cipher = keyToken.getCipherContext(EncryptionAlgorithm.AES_128_ECB); ++ cipher.initEncrypt(baseKeyAES); ++ ciphertext = cipher.doFinal(derivationData16); ++ displayByteArray(ciphertext,true); ++ ++ if ( ciphertext.length != encryptedAESECBBytes.length ) { ++ System.out.println("FAILED: encrypted data length not equal to derived key length."); ++ } else { ++ for ( int i = 0; i < ciphertext.length ; i ++) { ++ ciphertext[i]&=0xfe; ++ encryptedAESECBBytes[i]&=0xfe; ++ } ++ if ( Arrays.equals(ciphertext, encryptedAESECBBytes)) { ++ System.out.println("PASSED: derived key the same as encrypted data."); ++ } else { ++ ++ System.out.println("FAILED: derived key not the same as encrypted data."); ++ } ++ } ++ ++ ++ /*****************************************************************************************************/ ++ ++ System.out.println("\n Mechanism CKM_AES_CBC_ENCRYPT_DATA test. \n"); ++ ++ SymmetricKeyDeriver encryptAESCBC= token.getSymmetricKeyDeriver(); ++ ++ //System.in.read(); ++ encryptAESCBC.initDerive( ++ baseKeyAES, /* PKCS11Constants.CKM_AES_CBC_ENCRYPT_DATA */ 4357L ,derivationData16 ,iv16, ++ PKCS11Constants.CKM_AES_CBC, PKCS11Constants.CKA_DERIVE,(long) 16); ++ ++ ++ SymmetricKey encryptedAESCBC = encryptAESCBC.derive(); ++ ++ if ( encryptedAESCBC == null) { ++ System.out.println("Failed to derive 16 bytes from encrypted derivation data."); ++ } ++ ++ byte[] encryptedAESCBCBytes = encryptedAESCBC.getEncoded(); ++ ++ System.out.println("derived encrypted 16 bytes: " + encryptedAESCBCBytes.length); ++ displayByteArray(encryptedAESCBCBytes,true); ++ ++ ++ cipher = keyToken.getCipherContext(EncryptionAlgorithm.AES_128_CBC); ++ cipher.initEncrypt(baseKeyAES,new IVParameterSpec(iv16)); ++ ciphertext = cipher.doFinal(derivationData16); ++ displayByteArray(ciphertext,true); ++ ++ if ( ciphertext.length != encryptedAESCBCBytes.length ) { ++ System.out.println("FAILED: encrypted data length not equal to derived key length."); ++ } else { ++ for ( int i = 0; i < ciphertext.length ; i ++) { ++ ciphertext[i]&=0xfe; ++ encryptedAESCBCBytes[i]&=0xfe; ++ } ++ if ( Arrays.equals(ciphertext, encryptedAESCBCBytes)) { ++ System.out.println("PASSED: derived key the same as encrypted data."); ++ } else { ++ ++ System.out.println("FAILED: derived key not the same as encrypted data."); ++ } ++ } ++ ++ // get vector of symkeys ++ ++ Enumeration ect = null; ++ ect = (Enumeration) cm.getAllTokens(); ++ CryptoToken ct = null; //ct = cm.getTokenByName("ePass Token"); ++ while (ect.hasMoreElements()) ++ { ++ ct = ect.nextElement(); ++ System.out.println("CryptoToken.name= " + ct.getName()); ++ } ++ ++ SymmetricKey[] keys = keyToken.getCryptoStore().getSymmetricKeys(); ++ ++ SymmetricKey macKey = getSymKeyByName(keys, "defKeySet-macKey"); ++ ++ System.out.println("macKey: " + macKey); ++ ++ } catch(Exception e) { ++ e.printStackTrace(); ++ } ++ } ++ ++ public static void ++ displayByteArray(byte[] ba, boolean has_check_sum) { ++ char mask = 0xff; ++ ++ if ( has_check_sum == true ) ++ mask = 0xfe; ++ ++ for(int i=0; i < ba.length; i++) { ++ ++ System.out.print( Integer.toHexString(ba[i]&mask) + " " ); ++ if( (i % 26) == 25 ) { ++ System.out.println(""); ++ } ++ } ++ System.out.println(""); ++ } ++ ++ public static byte[] longToBytes(long x) { ++ ByteBuffer buffer = ByteBuffer.allocate(8); ++ buffer.putLong(x); ++ return buffer.array(); ++ } ++ ++ public static byte[] concatByteArrays(byte[] a, byte[] b) { ++ byte[] result = new byte[a.length + b.length]; ++ System.arraycopy(a, 0, result, 0, a.length); ++ System.arraycopy(b, 0, result, a.length, b.length); ++ return result; ++ } ++ ++ public static SymmetricKey getSymKeyByName( SymmetricKey[] keys, String name) { ++ if ( keys == null || name == null ) { ++ return null; ++ } ++ ++ int len = keys.length; ++ for(int i = 0 ; i < len ; i++ ) { ++ SymmetricKey cur = keys[i]; ++ if ( cur != null ) { ++ if( name.equals(cur.getNickName())) { ++ System.out.println("Found key: " + name + "\n"); ++ return cur; ++ } ++ } ++ } ++ ++ return null; ++ } ++} +diff -up ./mozilla/security/jss/org/mozilla/jss/util/java_ids.h.jmagne ./mozilla/security/jss/org/mozilla/jss/util/java_ids.h +--- ./mozilla/security/jss/org/mozilla/jss/util/java_ids.h.jmagne 2016-04-14 16:34:36.729287416 -0700 ++++ ./mozilla/security/jss/org/mozilla/jss/util/java_ids.h 2016-04-14 16:34:45.608226163 -0700 +@@ -243,6 +243,7 @@ PR_BEGIN_EXTERN_C + */ + #define PK11SYMKEY_CLASS_NAME "org/mozilla/jss/pkcs11/PK11SymKey" + #define PK11SYMKEY_CONSTRUCTOR_SIG "([B)V" ++#define PK11SYMKEY_CONSTRUCTOR_1_SIG "([BLjava/lang/String;)V" + + /* + * PK11Token diff --git a/SPECS/jss.spec b/SPECS/jss.spec index 3fa15a9..cc130dc 100644 --- a/SPECS/jss.spec +++ b/SPECS/jss.spec @@ -1,6 +1,6 @@ Name: jss Version: 4.2.6 -Release: 37%{?dist} +Release: 42%{?dist} Summary: Java Security Services (JSS) Group: System Environment/Libraries @@ -16,11 +16,11 @@ Source2: http://pki.fedoraproject.org/pki/sources/%{name}/%{name}-%{versi Source3: http://pki.fedoraproject.org/pki/sources/%{name}/%{name}-%{version}-%{release}/lgpl.txt BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -BuildRequires: nss-devel >= 3.12.3.99 -BuildRequires: nspr-devel >= 4.6.99 +BuildRequires: nss-devel >= 3.21.0 +BuildRequires: nspr-devel >= 4.11.0 BuildRequires: java-devel Requires: java -Requires: nss >= 3.12.3.99 +Requires: nss >= 3.21.0 Patch1: jss-key_pair_usage_with_op_flags.patch Patch2: jss-javadocs-param.patch @@ -50,6 +50,11 @@ Patch25: jss-RC4-strengh-verify.patch Patch26: jss-support-TLS1_1-TLS1_2.patch Patch27: jss-WindowsCompileFix.patch Patch28: jss-WindowsLoadLibrary.patch +Patch29: jss-Fixed-build-failures.patch +Patch30: jss-VerifyCertificate-enhancement.patch +Patch31: jss-lunasaUnwrap.patch +Patch32: jss-symkey-enhancements.patch +Patch33: jss-crmf-envelopedData.patch %description Java Security Services (JSS) is a java native interface which provides a bridge @@ -94,6 +99,11 @@ This package contains the API documentation for JSS. %patch26 -p1 %patch27 -p1 %patch28 -p1 +%patch29 -p1 +%patch30 -p1 +%patch31 -p1 +%patch32 -p1 +%patch33 -p1 %build [ -z "$JAVA_HOME" ] && export JAVA_HOME=%{_jvmdir}/java @@ -198,6 +208,23 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Tue Aug 9 2016 Christina Fu - 4.2.6-42 +- Sync up patches from both Fedora and RHEL; adding one patch + (cfu, edewata, mharmsen) from RHEL: +- Bugzilla Bug #1289799 - JSS build failure on F23 and Rawhide (edewata) + +* Fri Jun 24 2016 Christina Fu - 4.2.6-41 +- Bugzilla 1221295 jss fails to decode EncryptedKey >> EnvelopedData + (cfu for roysjosh@gmail.com) + +* Thu May 19 2016 Christina Fu - 4.2.6-40 +- Bugzilla 1074208 - pass up exact JSS certificate validation errors from NSS + (edewata) +- Bugzilla 1331596 - Key archival fails when KRA is configured with lunasa. + (cfu) +- PKI ticket 801 - Merge pki-symkey into jss (phase 1) + (jmagne) + * Wed Jul 8 2015 Christina Fu - 4.2.6-37 - Bugzilla Bug #1238450 - UnsatisfiedLinkError on Windows