Blob Blame History Raw
# HG changeset patch
# User Jack Magne <jmagne@redhat.com>
# Date 1504307754 25200
#      Fri Sep 01 16:15:54 2017 -0700
# Node ID eec15518fd61f1d988c25b4de589555796f9e65f
# Parent  17d1d7b740ca5777fbcf8ee817a2f26b9c93593a
unwrapping of HMAC-SHA1 secret keys using AES wrapping and unwrapping
cfu on behalf of jmagne

diff -r 17d1d7b740ca -r eec15518fd61 org/mozilla/jss/pkcs11/PK11KeyWrapper.java
--- a/org/mozilla/jss/pkcs11/PK11KeyWrapper.java	Mon May 01 10:39:50 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11KeyWrapper.java	Fri Sep 01 16:15:54 2017 -0700
@@ -588,6 +588,8 @@
             return EncryptionAlgorithm.RC4;
         } else if( type == SymmetricKey.AES ) {
             return EncryptionAlgorithm.AES_128_ECB;
+        } else if( type == SymmetricKey.SHA1_HMAC) {
+            return HMACAlgorithm.SHA1;
         } else  {
             Assert._assert( type == SymmetricKey.RC2 );
             return EncryptionAlgorithm.RC2_CBC;
diff -r 17d1d7b740ca -r eec15518fd61 org/mozilla/jss/pkcs11/PK11MessageDigest.c
--- a/org/mozilla/jss/pkcs11/PK11MessageDigest.c	Mon May 01 10:39:50 2017 -0700
+++ b/org/mozilla/jss/pkcs11/PK11MessageDigest.c	Fri Sep 01 16:15:54 2017 -0700
@@ -67,19 +67,19 @@
     }
 
     /* copy the key, setting the CKA_SIGN attribute */
-    /*
+    
     newKey = PK11_CopySymKeyForSigning(origKey, mech);
+
+    /* For some key on the hsm, this call could fail, but the key may work anyway */
+
     if( newKey == NULL ) {
-        JSS_throwMsg(env, DIGEST_EXCEPTION,
-                        "Unable to set CKA_SIGN attribute on symmetric key");
-        goto finish;
+        newKey = origKey;
     }
-    */
 
     param.data = NULL;
     param.len = 0;
 
-    context = PK11_CreateContextBySymKey(mech, CKA_SIGN, origKey, &param);
+    context = PK11_CreateContextBySymKey(mech, CKA_SIGN, newKey, &param);
     if( context == NULL ) {
         JSS_throwMsg(env, DIGEST_EXCEPTION,
             "Unable to initialize digest context");
@@ -88,7 +88,7 @@
 
     contextObj = JSS_PK11_wrapCipherContextProxy(env, &context);
 finish:
-    if(newKey) {
+    if(newKey && (newKey != origKey)) {
         /* SymKeys are ref counted, and the context will free it's ref
          * when it is destroyed */
         PK11_FreeSymKey(newKey);
diff -r 17d1d7b740ca -r eec15518fd61 org/mozilla/jss/tests/HmacTest.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/org/mozilla/jss/tests/HmacTest.java	Fri Sep 01 16:15:54 2017 -0700
@@ -0,0 +1,119 @@
+
+package org.mozilla.jss.tests;
+
+
+import java.security.Key;
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+
+import org.mozilla.jss.CryptoManager;
+import org.mozilla.jss.crypto.CryptoToken;
+import org.mozilla.jss.crypto.SymmetricKey;
+
+
+public class HmacTest {
+
+  private static final String INTERNAL_KEY_STORAGE_TOKEN =
+    new CryptoManager.InitializationValues("").getInternalKeyStorageTokenDescription().trim();
+
+  private static final String NSS_DATABASE_DIR = "sql:data";
+  private static final String PROVIDER = "Mozilla-JSS";
+
+
+  public static void main(String[] args)
+   {
+
+    String algorithm = "hmac-sha1";
+
+    try {
+       configureCrypto(args);
+
+       Mac mac = Mac.getInstance(algorithm, PROVIDER);
+
+       byte[] keyData = new byte[16];
+       Key key = importHmacSha1Key(keyData);
+
+       mac.init(key);
+
+       doHMAC(mac,"Dogtag rules!");
+
+       System.out.println("Done");
+
+       System.exit(0);
+    } catch (Exception e) {
+        System.exit(1);
+    }
+  }
+
+  private static void configureCrypto(String[] args)
+    throws Exception {
+
+    CryptoManager.InitializationValues initializationValues =
+      new CryptoManager.InitializationValues(args[0]);
+
+    CryptoManager.initialize(initializationValues);
+
+    CryptoManager cryptoManager = CryptoManager.getInstance();
+
+    CryptoToken cryptoToken =
+      cryptoManager.getTokenByName(INTERNAL_KEY_STORAGE_TOKEN);
+
+    cryptoManager.setThreadToken(cryptoToken);
+  }
+
+  private static Key importHmacSha1Key(byte[] key)
+    throws Exception {
+
+    final String WRAPPING_ALGORITHM = "AES/CBC/PKCS5Padding";
+
+    Key wrappingKey = getWrappingKey();
+
+    byte[] iv = new byte[16];
+    IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
+
+    Cipher wrappingCipher = Cipher.getInstance(WRAPPING_ALGORITHM, PROVIDER);
+    wrappingCipher.init(Cipher.ENCRYPT_MODE, wrappingKey, ivParameterSpec);
+
+    byte[] wrappedKeyData = wrappingCipher.doFinal(key);
+
+    Cipher unwrappingCipher = Cipher.getInstance(WRAPPING_ALGORITHM, PROVIDER);
+    unwrappingCipher.init(Cipher.UNWRAP_MODE, wrappingKey, ivParameterSpec);
+
+    return (SecretKey) unwrappingCipher.unwrap(wrappedKeyData,
+                                               SymmetricKey.SHA1_HMAC.toString(),
+                                               Cipher.SECRET_KEY);
+  }
+
+  private static synchronized Key getWrappingKey()
+    throws Exception {
+
+    final String keyGenAlgorithm = "AES";
+    final int wrappingKeyLength = 256;
+
+    KeyGenerator keyGen = KeyGenerator.getInstance(keyGenAlgorithm, PROVIDER);
+    keyGen.init(wrappingKeyLength);
+    return keyGen.generateKey();
+  }
+
+  public static void doHMAC(Mac mozillaHmac, String clearText)
+            throws Exception {
+        byte[] mozillaHmacOut;
+
+        //Get the Mozilla HMAC
+        mozillaHmacOut = mozillaHmac.doFinal(clearText.getBytes());
+
+        if (mozillaHmacOut.length == mozillaHmac.getMacLength()) {
+            System.out.println(PROVIDER + " supports " +
+                    mozillaHmac.getAlgorithm() + "  and the output size is " + mozillaHmac.getMacLength());
+        } else {
+            throw new Exception("ERROR: hmac output size is " +
+                    mozillaHmacOut.length + ", should be " +
+                    mozillaHmac.getMacLength());
+        }
+    }
+
+
+}
diff -r 17d1d7b740ca -r eec15518fd61 org/mozilla/jss/tests/all.pl
--- a/org/mozilla/jss/tests/all.pl	Mon May 01 10:39:50 2017 -0700
+++ b/org/mozilla/jss/tests/all.pl	Fri Sep 01 16:15:54 2017 -0700
@@ -492,6 +492,10 @@
 $command = "$java -cp $jss_classpath org.mozilla.jss.tests.HMACTest $testdir $pwfile";
 run_test($testname, $command);
 
+$testname = "HMAC Unwrap";
+$command = "$java -cp $jss_classpath org.mozilla.jss.tests.HmacTest $testdir $pwfile";
+run_test($testname, $command);
+
 $testname = "KeyWrapping ";
 $command = "$java -cp $jss_classpath org.mozilla.jss.tests.JCAKeyWrap $testdir $pwfile";
 run_test($testname, $command);