From 7c0885657ae1909945094c45415a6a56e391a954 Mon Sep 17 00:00:00 2001 From: Anders Rundgren Date: Mon, 15 Apr 2019 21:02:39 +0200 Subject: [PATCH] Lots of Android changes --- .../android/content/Context.java | 18 +- .../android/provider/Settings.java | 12 +- .../keystore/KeyGenParameterSpec.java | 35 +++- .../security/keystore/KeyProperties.java | 10 +- .../support/test/InstrumentationRegistry.java | 11 ++ .../sks/SKSReferenceImplementation.java | 14 +- .../ppmastertest/org/webpki/sks/SKSTest.java | 178 +++++++++++------- .../src/org/webpki/crypto/KeyAlgorithms.java | 2 +- .../src/org/webpki/sks/SecureKeyStore.java | 5 - library/test/org/webpki/sks/GenKey.java | 8 +- library/test/org/webpki/sks/PKCS12Import.java | 6 +- library/test/org/webpki/sks/ProvSess.java | 6 +- .../sks/SKSReferenceImplementation.java | 6 + library/test/org/webpki/sks/SKSTest.java | 172 ++++++++++------- .../se/SEReferenceImplementation.java | 17 +- 15 files changed, 327 insertions(+), 173 deletions(-) create mode 100644 library/androidrefsrc/android/support/test/InstrumentationRegistry.java diff --git a/library/androidrefsrc/android/content/Context.java b/library/androidrefsrc/android/content/Context.java index bde69939..9cc8ad31 100644 --- a/library/androidrefsrc/android/content/Context.java +++ b/library/androidrefsrc/android/content/Context.java @@ -1,7 +1,21 @@ package android.content; +import java.io.InputStream; +import java.io.OutputStream; + public class Context { - static int MODE_PRIVATE = 0; + public static int MODE_PRIVATE = 0; + + public String getContentResolver() { + return null; + } -} \ No newline at end of file + public InputStream openFileInput(String file) { + return null; + } + + public OutputStream openFileOutput(String file, int mode) { + return null; + } +} diff --git a/library/androidrefsrc/android/provider/Settings.java b/library/androidrefsrc/android/provider/Settings.java index 0c66eeff..bbbbd771 100644 --- a/library/androidrefsrc/android/provider/Settings.java +++ b/library/androidrefsrc/android/provider/Settings.java @@ -2,4 +2,14 @@ public class Settings { -} \ No newline at end of file + public static class Secure { + + public static String ANDROID_ID = "does't matter here"; + + public static String getString(String whatever, String yes) { + return null; + } + + } + +} diff --git a/library/androidrefsrc/android/security/keystore/KeyGenParameterSpec.java b/library/androidrefsrc/android/security/keystore/KeyGenParameterSpec.java index 9df30872..1d55e2fd 100644 --- a/library/androidrefsrc/android/security/keystore/KeyGenParameterSpec.java +++ b/library/androidrefsrc/android/security/keystore/KeyGenParameterSpec.java @@ -1,5 +1,38 @@ package android.security.keystore; +import java.math.BigInteger; +import java.security.spec.ECGenParameterSpec; +import java.security.spec.AlgorithmParameterSpec; +import java.util.Date; + +import javax.security.auth.x500.X500Principal; + public class KeyGenParameterSpec { -} \ No newline at end of file + public static class Builder { + public Builder(String a, int b) { + + } + + public Builder setAlgorithmParameterSpec(AlgorithmParameterSpec g) { + return this; + } + public Builder setDigests(int alg) { + return this; + } + public Builder setCertificateSerialNumber(BigInteger serial) { + return this; + } + public Builder setCertificateNotBefore(Date date) { + return this; + } + public Builder setCertificateSubject(X500Principal name) { + return this; + } + public AlgorithmParameterSpec build() { + return null; + } + + } + +} diff --git a/library/androidrefsrc/android/security/keystore/KeyProperties.java b/library/androidrefsrc/android/security/keystore/KeyProperties.java index 9820b53e..0f15d9bc 100644 --- a/library/androidrefsrc/android/security/keystore/KeyProperties.java +++ b/library/androidrefsrc/android/security/keystore/KeyProperties.java @@ -2,4 +2,12 @@ public class KeyProperties { -} \ No newline at end of file + public static String KEY_ALGORITHM_EC = "EC"; + public static String KEY_ALGORITHM_RSA = "RSA"; + + public static int PURPOSE_SIGN = 2; + public static int PURPOSE_VERIFY = 4; + + public static int DIGEST_SHA256 = 256; + +} diff --git a/library/androidrefsrc/android/support/test/InstrumentationRegistry.java b/library/androidrefsrc/android/support/test/InstrumentationRegistry.java new file mode 100644 index 00000000..08313668 --- /dev/null +++ b/library/androidrefsrc/android/support/test/InstrumentationRegistry.java @@ -0,0 +1,11 @@ +package android.support.test; + +import android.content.Context; + +public class InstrumentationRegistry { + + public static Context getTargetContext() { + return null; + } + +} diff --git a/library/ppmastertest/org/webpki/sks/SKSReferenceImplementation.java b/library/ppmastertest/org/webpki/sks/SKSReferenceImplementation.java index 632f42a3..6d7d0212 100644 --- a/library/ppmastertest/org/webpki/sks/SKSReferenceImplementation.java +++ b/library/ppmastertest/org/webpki/sks/SKSReferenceImplementation.java @@ -141,13 +141,25 @@ public class SKSReferenceImplementation implements SecureKeyStore, Serializable static final String SKS_UPDATE_URL = null; // Change here to test or disable static final boolean SKS_DEVICE_PIN_SUPPORT = false; // Change here to test or disable static final boolean SKS_BIOMETRIC_SUPPORT = false; // Change here to test or disable - static final boolean SKS_RSA_EXPONENT_SUPPORT = true; // Change here to test or disable + + /////////////////////////////////////////////////////////////////////////////////// + // Default RSA support + /////////////////////////////////////////////////////////////////////////////////// + static final boolean SKS_RSA_EXPONENT_SUPPORT = false; + static final short[] SKS_DEFAULT_RSA_SUPPORT = {2048}; + //#else static final String SKS_VENDOR_DESCRIPTION = "SKS Reference - Java Emulator Edition"; static final String SKS_UPDATE_URL = null; // Change here to test or disable static final boolean SKS_DEVICE_PIN_SUPPORT = true; // Change here to test or disable static final boolean SKS_BIOMETRIC_SUPPORT = true; // Change here to test or disable + + /////////////////////////////////////////////////////////////////////////////////// + // Default RSA support + /////////////////////////////////////////////////////////////////////////////////// static final boolean SKS_RSA_EXPONENT_SUPPORT = true; // Change here to test or disable + static final short[] SKS_DEFAULT_RSA_SUPPORT = {1024, 2048}; + //#endif static final int MAX_LENGTH_CRYPTO_DATA = 16384; static final int MAX_LENGTH_EXTENSION_DATA = 65536; diff --git a/library/ppmastertest/org/webpki/sks/SKSTest.java b/library/ppmastertest/org/webpki/sks/SKSTest.java index 94b39b15..e4155781 100644 --- a/library/ppmastertest/org/webpki/sks/SKSTest.java +++ b/library/ppmastertest/org/webpki/sks/SKSTest.java @@ -33,6 +33,7 @@ import java.security.spec.RSAKeyGenParameterSpec; import java.util.EnumSet; +import java.util.HashSet; import java.util.Set; import java.util.Vector; @@ -82,8 +83,10 @@ import org.webpki.sks.SKSException; import org.webpki.sks.SecureKeyStore; + //#if ANDROID import android.support.test.runner.AndroidJUnit4; +import android.support.test.InstrumentationRegistry; import org.junit.runner.RunWith; @@ -116,15 +119,22 @@ public class SKSTest { static Vector prov_sessions = new Vector(); static Device device; + + static HashSet supported_algorithms = new HashSet(); static boolean bc_loaded; + static KeyAlgorithms preferred_rsa_algorithm; + static byte[] serverCertificate = {1,2,3}; @BeforeClass public static void openFile() throws Exception { //#if ANDROID - // something + sks = SKSStore.createSKS("JUnit", InstrumentationRegistry.getTargetContext(), true); + device = new Device(sks); + DeviceInfo dev = device.device_info; + reference_implementation = true; //#else standalone_testing = new Boolean(System.getProperty("sks.standalone")); // Start deprecating Bouncycastle since Android will remove most of it anyway @@ -161,6 +171,19 @@ public static void openFile() throws Exception { if (!prov_sessions.isEmpty()) { System.out.println("There were " + prov_sessions.size() + " open sessions before test started"); } + for (String alg : dev.getSupportedAlgorithms()) { + supported_algorithms.add(alg); + } + for (KeyAlgorithms ka : KeyAlgorithms.values()) { + if (!ka.isRSAKey() || ka.hasParameters() || !ka.isMandatorySksAlgorithm()) continue; + if (supported_algorithms.contains(ka.getAlgorithmId(AlgorithmPreferences.SKS))) { + preferred_rsa_algorithm = ka; + break; + } + } + if (preferred_rsa_algorithm == null) { + throw new RuntimeException("No RSA!"); + } } @AfterClass @@ -549,7 +572,7 @@ void PINstress(ProvSess sess) throws Exception { null /* pukPolicy */); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -676,7 +699,7 @@ void badKeySpec(String key_algorithm, byte[] keyParameters, String expected_mess sess.setKeyParameters(keyParameters); try { sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, null /* pin_value */, null, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -786,7 +809,7 @@ void serverSeed(int length) throws Exception { false /* enablePinCaching */, AppUsage.AUTHENTICATION, "" /* friendlyName */, - new KeySpecifier(KeyAlgorithms.RSA1024), + new KeySpecifier(preferred_rsa_algorithm), null).setCertificate(cn()); sess.closeSession(); } @@ -802,7 +825,7 @@ void rsaEncryptionTest(AsymEncryptionAlgorithms encryption_algorithm) throws Exc null /* pukPolicy */); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.ENCRYPTION).setCertificate(cn()); @@ -874,13 +897,13 @@ void create3Keys(String s_pin, String a_pin, String e_pin) throws Exception { puk /* pukPolicy */); GenKey key1 = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, s_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.SIGNATURE).setCertificate(cn()); try { sess.createKey("Key.2", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, a_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -893,7 +916,7 @@ void create3Keys(String s_pin, String a_pin, String e_pin) throws Exception { } try { sess.createKey("Key.3", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, e_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.ENCRYPTION).setCertificate(cn()); @@ -905,12 +928,12 @@ void create3Keys(String s_pin, String a_pin, String e_pin) throws Exception { continue; } GenKey key4 = sess.createKey("Key.4", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, s_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.SIGNATURE).setCertificate(cn()); sess.createKey("Key.5", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, e_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.ENCRYPTION).setCertificate(cn()); @@ -1002,7 +1025,7 @@ public void test4() throws Exception { public void test5() throws Exception { ProvSess sess = new ProvSess(device); sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION); @@ -1014,7 +1037,7 @@ public void test5() throws Exception { sess = new ProvSess(device); try { sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, "1234" /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION); @@ -1594,7 +1617,7 @@ public void test31() throws Exception { puk_pol /* pukPolicy */); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.ENCRYPTION).setCertificate(cn()); @@ -1717,7 +1740,7 @@ public void test32() throws Exception { public void test33() throws Exception { ProvSess sess = new ProvSess(device); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -1735,7 +1758,7 @@ public void test34() throws Exception { ProvSess sess = new ProvSess(device); sess.overrideExportProtection(ExportProtection.NONE.getSksValue()); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -1757,7 +1780,7 @@ public void test35() throws Exception { sess.overrideExportProtection(ExportProtection.PIN.getSksValue()); try { sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -1780,7 +1803,7 @@ public void test36() throws Exception { null /* pukPolicy */); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -1815,7 +1838,7 @@ public void test37() throws Exception { try { sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -1842,7 +1865,7 @@ public void test38() throws Exception { (short) 3 /* retryLimit*/, puk_pol /* pukPolicy */); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -2128,7 +2151,7 @@ public void test45() throws Exception { null /* pukPolicy */); sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.AUTHENTICATION, @@ -2180,7 +2203,7 @@ public void test47() throws Exception { @Test public void test48() throws Exception { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(1024); + kpg.initialize(preferred_rsa_algorithm.getPublicKeySizeInBits()); KeyPair key_pair = kpg.generateKeyPair(); String good_pin = "1563"; for (AppUsage keyUsage : AppUsage.values()) { @@ -2198,7 +2221,7 @@ public void test48() throws Exception { good_pin /* pin_value */, pinPolicy, keyUsage).setCertificate(cn(), key_pair.getPublic()); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); assertTrue("IMPORTED must be set", key.getKeyProtectionInfo().getKeyBackup() == KeyProtectionInfo.KEYBACKUP_IMPORTED); Cipher cipher = Cipher.getInstance(AsymEncryptionAlgorithms.RSA_ES_PKCS_1_5.getJceName()); @@ -2495,13 +2518,13 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); GenKey key2 = sess.createKey("Key.2", KeyAlgorithms.NIST_P_256, null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificatePath(key.getCertificatePath()); - key2.setPrivateKey(key_pair.getPrivate()); + key2.setPrivateKey(key_pair); try { sess.closeSession(); fail("Not allowed"); @@ -2514,7 +2537,7 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); sess = new ProvSess(device); key2 = sess.createKey("Key.4", @@ -2522,7 +2545,7 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificatePath(key.getCertificatePath()); - key2.setPrivateKey(key_pair.getPrivate()); + key2.setPrivateKey(key_pair); try { sess.closeSession(); fail("Not allowed"); @@ -2535,7 +2558,7 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); ProvSess sess2 = new ProvSess(device); GenKey new_key = sess2.createKey("Key.4", @@ -2543,7 +2566,7 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificatePath(key.getCertificatePath()); - new_key.setPrivateKey(key_pair.getPrivate()); + new_key.setPrivateKey(key_pair); new_key.postUpdateKey(key); sess2.closeSession(); sess = new ProvSess(device, 0); @@ -2552,7 +2575,7 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); sess2 = new ProvSess(device); new_key = sess2.createKey("Key.4", @@ -2560,7 +2583,7 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificatePath(key.getCertificatePath()); - new_key.setPrivateKey(key_pair.getPrivate()); + new_key.setPrivateKey(key_pair); sess2.postDeleteKey(key); sess2.closeSession(); } @@ -2643,9 +2666,9 @@ public void test61() throws Exception { key.setSymmetricKey(symmetricKey); try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(1024); + kpg.initialize(preferred_rsa_algorithm.getPublicKeySizeInBits()); KeyPair key_pair = kpg.generateKeyPair(); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); fail("Duplicate import"); } catch (SKSException e) { @@ -2671,9 +2694,9 @@ public void test62() throws Exception { AppUsage.AUTHENTICATION).setCertificate(cn()); try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(1024); + kpg.initialize(preferred_rsa_algorithm.getPublicKeySizeInBits()); KeyPair key_pair = kpg.generateKeyPair(); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); fail("Mixing RSA and EC is not possible"); } catch (SKSException e) { @@ -2693,7 +2716,7 @@ public void test63() throws Exception { (short) 3 /* retryLimit */, null /* pukPolicy */); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(1024); + kpg.initialize(preferred_rsa_algorithm.getPublicKeySizeInBits()); KeyPair key_pair = kpg.generateKeyPair(); sess.createKey("Key.1", KeyAlgorithms.NIST_P_256, @@ -2710,28 +2733,33 @@ public void test63() throws Exception { @Test public void test64() throws Exception { - String good_pin = "1563"; - ProvSess sess = new ProvSess(device); - PINPol pinPolicy = sess.createPINPolicy("PIN", - PassphraseFormat.NUMERIC, - EnumSet.noneOf(PatternRestriction.class), - Grouping.SHARED, 4 /* minLength */, - 8 /* maxLength */, - (short) 3 /* retryLimit */, - null /* pukPolicy */); - KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(1024); - KeyPair key_pair = kpg.generateKeyPair(); - sess.createKey("Key.1", - KeyAlgorithms.RSA1024, - good_pin /* pin_value */, - pinPolicy, - AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); - try { - sess.closeSession(); - fail("Mismatch"); - } catch (SKSException e) { - checkException(e, "RSA mismatch between public and private keys for: Key.1"); + for (KeyAlgorithms ka : KeyAlgorithms.values()) { + if (!ka.isRSAKey()) continue; + if (ka.hasParameters()) continue; + if (!supported_algorithms.contains(ka.getAlgorithmId(AlgorithmPreferences.SKS))) continue; + String good_pin = "1563"; + ProvSess sess = new ProvSess(device); + PINPol pinPolicy = sess.createPINPolicy("PIN", + PassphraseFormat.NUMERIC, + EnumSet.noneOf(PatternRestriction.class), + Grouping.SHARED, 4 /* minLength */, + 8 /* maxLength */, + (short) 3 /* retryLimit */, + null /* pukPolicy */); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); + kpg.initialize(ka.getPublicKeySizeInBits()); + KeyPair key_pair = kpg.generateKeyPair(); + sess.createKey("Key.1", + ka, + good_pin /* pin_value */, + pinPolicy, + AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); + try { + sess.closeSession(); + fail("Mismatch"); + } catch (SKSException e) { + checkException(e, "RSA mismatch between public and private keys for: Key.1"); + } } } @@ -2780,43 +2808,47 @@ public void test67() throws Exception { new ProvSess(device); fail("Bad server key"); } catch (SKSException e) { - checkException(e, "Unsupported EC key algorithm for: \"" + SecureKeyStore.VAR_SERVER_EPHEMERAL_KEY + "\""); ProvSess.override_server_ephemeral_key_algorithm = null; + checkException(e, "Unsupported EC key algorithm for: \"" + SecureKeyStore.VAR_SERVER_EPHEMERAL_KEY + "\""); } } @Test public void test68() throws Exception { - badKeySpec(KeyAlgorithms.RSA1024.getAlgorithmId(AlgorithmPreferences.SKS), new byte[]{0, 0, 0, 3}, "Unexpected \"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\""); + badKeySpec(preferred_rsa_algorithm.getAlgorithmId(AlgorithmPreferences.SKS), new byte[]{0, 0, 0, 3}, "Unexpected \"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\""); badKeySpec(KeyAlgorithms.NIST_P_256.getAlgorithmId(AlgorithmPreferences.SKS), new byte[]{0, 0, 0, 3}, "Unexpected \"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\""); badKeySpec("http://badcrypto/snakeoil-1", null, "Unsupported \"" + SecureKeyStore.VAR_KEY_ALGORITHM + "\": http://badcrypto/snakeoil-1"); - boolean supports_var_exp = false; - for (String algorithm : device.device_info.getSupportedAlgorithms()) { - if (algorithm.equals(KeyAlgorithms.RSA1024_EXP.getAlgorithmId(AlgorithmPreferences.SKS))) { - supports_var_exp = true; + KeyAlgorithms rsa_var_exp = null; + for (KeyAlgorithms ka : KeyAlgorithms.values()) { + if (ka.isRSAKey() && ka.hasParameters() && + supported_algorithms.contains(ka.getAlgorithmId(AlgorithmPreferences.SKS)) && + ka.getPublicKeySizeInBits() == preferred_rsa_algorithm.getPublicKeySizeInBits()) { + rsa_var_exp = ka; break; } + } - if (supports_var_exp) { - badKeySpec(KeyAlgorithms.RSA1024_EXP.getAlgorithmId(AlgorithmPreferences.SKS), null, "Missing \"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\""); - badKeySpec(KeyAlgorithms.RSA1024_EXP.getAlgorithmId(AlgorithmPreferences.SKS), new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 3}, "\"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\" length error: 9"); - badKeySpec(KeyAlgorithms.RSA1024_EXP.getAlgorithmId(AlgorithmPreferences.SKS), new byte[0], "\"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\" length error: 0"); + if (rsa_var_exp != null) { + badKeySpec(rsa_var_exp.getAlgorithmId(AlgorithmPreferences.SKS), null, "Missing \"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\""); + badKeySpec(rsa_var_exp.getAlgorithmId(AlgorithmPreferences.SKS), new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 3}, "\"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\" length error: 9"); + badKeySpec(rsa_var_exp.getAlgorithmId(AlgorithmPreferences.SKS), new byte[0], "\"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\" length error: 0"); } ProvSess sess = new ProvSess(device); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(new RSAKeyGenParameterSpec(1024, BigInteger.valueOf(3))); + kpg.initialize(new RSAKeyGenParameterSpec(preferred_rsa_algorithm.getPublicKeySizeInBits(), + BigInteger.valueOf(3))); KeyPair key_pair = kpg.generateKeyPair(); try { GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, null /* pin_value */, null, AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); - assertTrue("RSA exp match", supports_var_exp); + assertFalse("RSA exp match", rsa_var_exp == null); } catch (SKSException e) { - assertFalse("RSA exp mismatch", supports_var_exp); + assertTrue("RSA exp mismatch", rsa_var_exp == null); checkException(e, "Unsupported RSA exponent value for: Key.1"); } } @@ -3141,7 +3173,7 @@ public void test82() throws Exception { } @Test - public void Test83() throws Exception { + public void test83() throws Exception { boolean dev_pin = device.sks.getDeviceInfo().getDevicePinSupport(); try { ProvSess sess = new ProvSess(device); diff --git a/library/src/org/webpki/crypto/KeyAlgorithms.java b/library/src/org/webpki/crypto/KeyAlgorithms.java index 320d8ebd..18e36c48 100644 --- a/library/src/org/webpki/crypto/KeyAlgorithms.java +++ b/library/src/org/webpki/crypto/KeyAlgorithms.java @@ -37,7 +37,7 @@ public enum KeyAlgorithms implements CryptoAlgorithms { 1024, AsymSignatureAlgorithms.RSA_SHA256, false, - true, + false, null, null), diff --git a/library/src/org/webpki/sks/SecureKeyStore.java b/library/src/org/webpki/sks/SecureKeyStore.java index c7020afd..f01bff9e 100644 --- a/library/src/org/webpki/sks/SecureKeyStore.java +++ b/library/src/org/webpki/sks/SecureKeyStore.java @@ -193,11 +193,6 @@ public interface SecureKeyStore { byte BIOMETRIC_PROTECTION_COMBINED = 0x02; byte BIOMETRIC_PROTECTION_EXCLUSIVE = 0x03; - /////////////////////////////////////////////////////////////////////////////////// - // Default RSA support - /////////////////////////////////////////////////////////////////////////////////// - short[] SKS_DEFAULT_RSA_SUPPORT = {1024, 2048}; - /////////////////////////////////////////////////////////////////////////////////// // Special algorithms /////////////////////////////////////////////////////////////////////////////////// diff --git a/library/test/org/webpki/sks/GenKey.java b/library/test/org/webpki/sks/GenKey.java index f1c83b84..34daf3a6 100644 --- a/library/test/org/webpki/sks/GenKey.java +++ b/library/test/org/webpki/sks/GenKey.java @@ -21,7 +21,7 @@ import java.math.BigInteger; import java.security.GeneralSecurityException; -import java.security.PrivateKey; +import java.security.KeyPair; import java.security.PublicKey; import java.security.cert.CertificateEncodingException; @@ -46,7 +46,9 @@ import org.webpki.sks.KeyProtectionInfo; import org.webpki.sks.SKSException; import org.webpki.sks.SecureKeyStore; + import org.webpki.sks.ProvSess.MacGenerator; + import org.webpki.util.ArrayUtil; public class GenKey { @@ -136,9 +138,9 @@ public void setSymmetricKey(byte[] symmetricKey) throws IOException, GeneralSecu prov_sess.sks.importSymmetricKey(keyHandle, encrypted_symmetric_key, prov_sess.mac4call(symk_mac.getResult(), SecureKeyStore.METHOD_IMPORT_SYMMETRIC_KEY)); } - public void setPrivateKey(PrivateKey privateKey) throws IOException, GeneralSecurityException { + public void setPrivateKey(KeyPair keyPair) throws IOException, GeneralSecurityException { MacGenerator privk_mac = getEECertMacBuilder(); - byte[] encrypted_private_key = prov_sess.server_sess_key.encrypt(privateKey.getEncoded()); + byte[] encrypted_private_key = prov_sess.server_sess_key.encrypt(keyPair.getPrivate().getEncoded()); privk_mac.addArray(encrypted_private_key); prov_sess.sks.importPrivateKey(keyHandle, encrypted_private_key, prov_sess.mac4call(privk_mac.getResult(), SecureKeyStore.METHOD_IMPORT_PRIVATE_KEY)); } diff --git a/library/test/org/webpki/sks/PKCS12Import.java b/library/test/org/webpki/sks/PKCS12Import.java index 2c8581ba..12ca8d6e 100644 --- a/library/test/org/webpki/sks/PKCS12Import.java +++ b/library/test/org/webpki/sks/PKCS12Import.java @@ -18,6 +18,7 @@ import java.io.IOException; +import java.security.KeyPair; import java.security.KeyStore; import java.security.PrivateKey; import java.security.PublicKey; @@ -89,7 +90,8 @@ public static void main(String[] argc) throws Exception { break; } } - boolean rsaFlag = cert_path.firstElement().getPublicKey() instanceof RSAPublicKey; + PublicKey publicKey = cert_path.firstElement().getPublicKey(); + boolean rsaFlag = publicKey instanceof RSAPublicKey; if (privateKey == null) { throw new IOException("No private key!"); } @@ -165,7 +167,7 @@ public static void main(String[] argc) throws Exception { new KeySpecifier(KeyAlgorithms.NIST_P_256), endorsed_algs); key.setCertificatePath(cert_path.toArray(new X509Certificate[0])); - key.setPrivateKey(privateKey); + key.setPrivateKey(new KeyPair(publicKey, privateKey)); sess.closeSession(); System.out.println("Imported Subject: " + cert_path.firstElement().getSubjectX500Principal().getName() + "\nID=#" + key.keyHandle + ", " + (rsaFlag ? "RSA" : "EC") + " Key with " + prot); diff --git a/library/test/org/webpki/sks/ProvSess.java b/library/test/org/webpki/sks/ProvSess.java index 8b314455..48361886 100644 --- a/library/test/org/webpki/sks/ProvSess.java +++ b/library/test/org/webpki/sks/ProvSess.java @@ -207,7 +207,7 @@ static private void addKMK(KeyPair keyPair) throws IOException, GeneralSecurityE byte[] session_key; - public ECPublicKey generateEphemeralKey(KeyAlgorithms ec_key_algorithm) throws IOException { + public ECPublicKey generateEphemeralKey(KeyAlgorithms ec_key_algorithm) { try { KeyPairGenerator generator = KeyPairGenerator.getInstance("EC"); ECGenParameterSpec eccgen = new ECGenParameterSpec(ec_key_algorithm.getJceName()); @@ -215,8 +215,8 @@ public ECPublicKey generateEphemeralKey(KeyAlgorithms ec_key_algorithm) throws I KeyPair kp = generator.generateKeyPair(); server_ec_private_key = (ECPrivateKey) kp.getPrivate(); return (ECPublicKey) kp.getPublic(); - } catch (GeneralSecurityException e) { - throw new IOException(e); + } catch (Exception e) { + throw new SKSException(e); } } diff --git a/library/test/org/webpki/sks/SKSReferenceImplementation.java b/library/test/org/webpki/sks/SKSReferenceImplementation.java index aec02365..2350ac22 100644 --- a/library/test/org/webpki/sks/SKSReferenceImplementation.java +++ b/library/test/org/webpki/sks/SKSReferenceImplementation.java @@ -114,7 +114,13 @@ public class SKSReferenceImplementation implements SecureKeyStore, Serializable static final String SKS_UPDATE_URL = null; // Change here to test or disable static final boolean SKS_DEVICE_PIN_SUPPORT = true; // Change here to test or disable static final boolean SKS_BIOMETRIC_SUPPORT = true; // Change here to test or disable + + /////////////////////////////////////////////////////////////////////////////////// + // Default RSA support + /////////////////////////////////////////////////////////////////////////////////// static final boolean SKS_RSA_EXPONENT_SUPPORT = true; // Change here to test or disable + static final short[] SKS_DEFAULT_RSA_SUPPORT = {1024, 2048}; + static final int MAX_LENGTH_CRYPTO_DATA = 16384; static final int MAX_LENGTH_EXTENSION_DATA = 65536; diff --git a/library/test/org/webpki/sks/SKSTest.java b/library/test/org/webpki/sks/SKSTest.java index f53185fb..bc6d2d64 100644 --- a/library/test/org/webpki/sks/SKSTest.java +++ b/library/test/org/webpki/sks/SKSTest.java @@ -33,6 +33,7 @@ import java.security.spec.RSAKeyGenParameterSpec; import java.util.EnumSet; +import java.util.HashSet; import java.util.Set; import java.util.Vector; @@ -80,6 +81,7 @@ import org.webpki.sks.SKSException; import org.webpki.sks.SecureKeyStore; + import org.webpki.sks.ws.TrustedGUIAuthorization; import org.webpki.sks.ws.WSSpecific; @@ -101,9 +103,13 @@ public class SKSTest { static Vector prov_sessions = new Vector(); static Device device; + + static HashSet supported_algorithms = new HashSet(); static boolean bc_loaded; + static KeyAlgorithms preferred_rsa_algorithm; + static byte[] serverCertificate = {1,2,3}; @BeforeClass @@ -142,6 +148,19 @@ public static void openFile() throws Exception { if (!prov_sessions.isEmpty()) { System.out.println("There were " + prov_sessions.size() + " open sessions before test started"); } + for (String alg : dev.getSupportedAlgorithms()) { + supported_algorithms.add(alg); + } + for (KeyAlgorithms ka : KeyAlgorithms.values()) { + if (!ka.isRSAKey() || ka.hasParameters() || !ka.isMandatorySksAlgorithm()) continue; + if (supported_algorithms.contains(ka.getAlgorithmId(AlgorithmPreferences.SKS))) { + preferred_rsa_algorithm = ka; + break; + } + } + if (preferred_rsa_algorithm == null) { + throw new RuntimeException("No RSA!"); + } } @AfterClass @@ -528,7 +547,7 @@ void PINstress(ProvSess sess) throws Exception { null /* pukPolicy */); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -655,7 +674,7 @@ void badKeySpec(String key_algorithm, byte[] keyParameters, String expected_mess sess.setKeyParameters(keyParameters); try { sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, null /* pin_value */, null, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -765,7 +784,7 @@ void serverSeed(int length) throws Exception { false /* enablePinCaching */, AppUsage.AUTHENTICATION, "" /* friendlyName */, - new KeySpecifier(KeyAlgorithms.RSA1024), + new KeySpecifier(preferred_rsa_algorithm), null).setCertificate(cn()); sess.closeSession(); } @@ -781,7 +800,7 @@ void rsaEncryptionTest(AsymEncryptionAlgorithms encryption_algorithm) throws Exc null /* pukPolicy */); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.ENCRYPTION).setCertificate(cn()); @@ -853,13 +872,13 @@ void create3Keys(String s_pin, String a_pin, String e_pin) throws Exception { puk /* pukPolicy */); GenKey key1 = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, s_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.SIGNATURE).setCertificate(cn()); try { sess.createKey("Key.2", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, a_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -872,7 +891,7 @@ void create3Keys(String s_pin, String a_pin, String e_pin) throws Exception { } try { sess.createKey("Key.3", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, e_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.ENCRYPTION).setCertificate(cn()); @@ -884,12 +903,12 @@ void create3Keys(String s_pin, String a_pin, String e_pin) throws Exception { continue; } GenKey key4 = sess.createKey("Key.4", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, s_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.SIGNATURE).setCertificate(cn()); sess.createKey("Key.5", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, e_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.ENCRYPTION).setCertificate(cn()); @@ -981,7 +1000,7 @@ public void test4() throws Exception { public void test5() throws Exception { ProvSess sess = new ProvSess(device); sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION); @@ -993,7 +1012,7 @@ public void test5() throws Exception { sess = new ProvSess(device); try { sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, "1234" /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION); @@ -1573,7 +1592,7 @@ public void test31() throws Exception { puk_pol /* pukPolicy */); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.ENCRYPTION).setCertificate(cn()); @@ -1696,7 +1715,7 @@ public void test32() throws Exception { public void test33() throws Exception { ProvSess sess = new ProvSess(device); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -1714,7 +1733,7 @@ public void test34() throws Exception { ProvSess sess = new ProvSess(device); sess.overrideExportProtection(ExportProtection.NONE.getSksValue()); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -1736,7 +1755,7 @@ public void test35() throws Exception { sess.overrideExportProtection(ExportProtection.PIN.getSksValue()); try { sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -1759,7 +1778,7 @@ public void test36() throws Exception { null /* pukPolicy */); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -1794,7 +1813,7 @@ public void test37() throws Exception { try { sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -1821,7 +1840,7 @@ public void test38() throws Exception { (short) 3 /* retryLimit*/, puk_pol /* pukPolicy */); GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn()); @@ -2107,7 +2126,7 @@ public void test45() throws Exception { null /* pukPolicy */); sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, good_pin /* pin_value */, pinPolicy /* pinPolicy */, AppUsage.AUTHENTICATION, @@ -2159,7 +2178,7 @@ public void test47() throws Exception { @Test public void test48() throws Exception { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(1024); + kpg.initialize(preferred_rsa_algorithm.getPublicKeySizeInBits()); KeyPair key_pair = kpg.generateKeyPair(); String good_pin = "1563"; for (AppUsage keyUsage : AppUsage.values()) { @@ -2177,7 +2196,7 @@ public void test48() throws Exception { good_pin /* pin_value */, pinPolicy, keyUsage).setCertificate(cn(), key_pair.getPublic()); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); assertTrue("IMPORTED must be set", key.getKeyProtectionInfo().getKeyBackup() == KeyProtectionInfo.KEYBACKUP_IMPORTED); Cipher cipher = Cipher.getInstance(AsymEncryptionAlgorithms.RSA_ES_PKCS_1_5.getJceName()); @@ -2474,13 +2493,13 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); GenKey key2 = sess.createKey("Key.2", KeyAlgorithms.NIST_P_256, null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificatePath(key.getCertificatePath()); - key2.setPrivateKey(key_pair.getPrivate()); + key2.setPrivateKey(key_pair); try { sess.closeSession(); fail("Not allowed"); @@ -2493,7 +2512,7 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); sess = new ProvSess(device); key2 = sess.createKey("Key.4", @@ -2501,7 +2520,7 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificatePath(key.getCertificatePath()); - key2.setPrivateKey(key_pair.getPrivate()); + key2.setPrivateKey(key_pair); try { sess.closeSession(); fail("Not allowed"); @@ -2514,7 +2533,7 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); ProvSess sess2 = new ProvSess(device); GenKey new_key = sess2.createKey("Key.4", @@ -2522,7 +2541,7 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificatePath(key.getCertificatePath()); - new_key.setPrivateKey(key_pair.getPrivate()); + new_key.setPrivateKey(key_pair); new_key.postUpdateKey(key); sess2.closeSession(); sess = new ProvSess(device, 0); @@ -2531,7 +2550,7 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); sess2 = new ProvSess(device); new_key = sess2.createKey("Key.4", @@ -2539,7 +2558,7 @@ public void test58() throws Exception { null /* pin_value */, null /* pinPolicy */, AppUsage.AUTHENTICATION).setCertificatePath(key.getCertificatePath()); - new_key.setPrivateKey(key_pair.getPrivate()); + new_key.setPrivateKey(key_pair); sess2.postDeleteKey(key); sess2.closeSession(); } @@ -2620,9 +2639,9 @@ public void test61() throws Exception { key.setSymmetricKey(symmetricKey); try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(1024); + kpg.initialize(preferred_rsa_algorithm.getPublicKeySizeInBits()); KeyPair key_pair = kpg.generateKeyPair(); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); fail("Duplicate import"); } catch (SKSException e) { @@ -2648,9 +2667,9 @@ public void test62() throws Exception { AppUsage.AUTHENTICATION).setCertificate(cn()); try { KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(1024); + kpg.initialize(preferred_rsa_algorithm.getPublicKeySizeInBits()); KeyPair key_pair = kpg.generateKeyPair(); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); fail("Mixing RSA and EC is not possible"); } catch (SKSException e) { @@ -2670,7 +2689,7 @@ public void test63() throws Exception { (short) 3 /* retryLimit */, null /* pukPolicy */); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(1024); + kpg.initialize(preferred_rsa_algorithm.getPublicKeySizeInBits()); KeyPair key_pair = kpg.generateKeyPair(); sess.createKey("Key.1", KeyAlgorithms.NIST_P_256, @@ -2687,28 +2706,33 @@ public void test63() throws Exception { @Test public void test64() throws Exception { - String good_pin = "1563"; - ProvSess sess = new ProvSess(device); - PINPol pinPolicy = sess.createPINPolicy("PIN", - PassphraseFormat.NUMERIC, - EnumSet.noneOf(PatternRestriction.class), - Grouping.SHARED, 4 /* minLength */, - 8 /* maxLength */, - (short) 3 /* retryLimit */, - null /* pukPolicy */); - KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(1024); - KeyPair key_pair = kpg.generateKeyPair(); - sess.createKey("Key.1", - KeyAlgorithms.RSA1024, - good_pin /* pin_value */, - pinPolicy, - AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); - try { - sess.closeSession(); - fail("Mismatch"); - } catch (SKSException e) { - checkException(e, "RSA mismatch between public and private keys for: Key.1"); + for (KeyAlgorithms ka : KeyAlgorithms.values()) { + if (!ka.isRSAKey()) continue; + if (ka.hasParameters()) continue; + if (!supported_algorithms.contains(ka.getAlgorithmId(AlgorithmPreferences.SKS))) continue; + String good_pin = "1563"; + ProvSess sess = new ProvSess(device); + PINPol pinPolicy = sess.createPINPolicy("PIN", + PassphraseFormat.NUMERIC, + EnumSet.noneOf(PatternRestriction.class), + Grouping.SHARED, 4 /* minLength */, + 8 /* maxLength */, + (short) 3 /* retryLimit */, + null /* pukPolicy */); + KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); + kpg.initialize(ka.getPublicKeySizeInBits()); + KeyPair key_pair = kpg.generateKeyPair(); + sess.createKey("Key.1", + ka, + good_pin /* pin_value */, + pinPolicy, + AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); + try { + sess.closeSession(); + fail("Mismatch"); + } catch (SKSException e) { + checkException(e, "RSA mismatch between public and private keys for: Key.1"); + } } } @@ -2757,43 +2781,47 @@ public void test67() throws Exception { new ProvSess(device); fail("Bad server key"); } catch (SKSException e) { - checkException(e, "Unsupported EC key algorithm for: \"" + SecureKeyStore.VAR_SERVER_EPHEMERAL_KEY + "\""); ProvSess.override_server_ephemeral_key_algorithm = null; + checkException(e, "Unsupported EC key algorithm for: \"" + SecureKeyStore.VAR_SERVER_EPHEMERAL_KEY + "\""); } } @Test public void test68() throws Exception { - badKeySpec(KeyAlgorithms.RSA1024.getAlgorithmId(AlgorithmPreferences.SKS), new byte[]{0, 0, 0, 3}, "Unexpected \"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\""); + badKeySpec(preferred_rsa_algorithm.getAlgorithmId(AlgorithmPreferences.SKS), new byte[]{0, 0, 0, 3}, "Unexpected \"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\""); badKeySpec(KeyAlgorithms.NIST_P_256.getAlgorithmId(AlgorithmPreferences.SKS), new byte[]{0, 0, 0, 3}, "Unexpected \"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\""); badKeySpec("http://badcrypto/snakeoil-1", null, "Unsupported \"" + SecureKeyStore.VAR_KEY_ALGORITHM + "\": http://badcrypto/snakeoil-1"); - boolean supports_var_exp = false; - for (String algorithm : device.device_info.getSupportedAlgorithms()) { - if (algorithm.equals(KeyAlgorithms.RSA1024_EXP.getAlgorithmId(AlgorithmPreferences.SKS))) { - supports_var_exp = true; + KeyAlgorithms rsa_var_exp = null; + for (KeyAlgorithms ka : KeyAlgorithms.values()) { + if (ka.isRSAKey() && ka.hasParameters() && + supported_algorithms.contains(ka.getAlgorithmId(AlgorithmPreferences.SKS)) && + ka.getPublicKeySizeInBits() == preferred_rsa_algorithm.getPublicKeySizeInBits()) { + rsa_var_exp = ka; break; } + } - if (supports_var_exp) { - badKeySpec(KeyAlgorithms.RSA1024_EXP.getAlgorithmId(AlgorithmPreferences.SKS), null, "Missing \"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\""); - badKeySpec(KeyAlgorithms.RSA1024_EXP.getAlgorithmId(AlgorithmPreferences.SKS), new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 3}, "\"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\" length error: 9"); - badKeySpec(KeyAlgorithms.RSA1024_EXP.getAlgorithmId(AlgorithmPreferences.SKS), new byte[0], "\"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\" length error: 0"); + if (rsa_var_exp != null) { + badKeySpec(rsa_var_exp.getAlgorithmId(AlgorithmPreferences.SKS), null, "Missing \"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\""); + badKeySpec(rsa_var_exp.getAlgorithmId(AlgorithmPreferences.SKS), new byte[]{0, 0, 0, 0, 0, 0, 0, 0, 3}, "\"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\" length error: 9"); + badKeySpec(rsa_var_exp.getAlgorithmId(AlgorithmPreferences.SKS), new byte[0], "\"" + SecureKeyStore.VAR_KEY_PARAMETERS + "\" length error: 0"); } ProvSess sess = new ProvSess(device); KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); - kpg.initialize(new RSAKeyGenParameterSpec(1024, BigInteger.valueOf(3))); + kpg.initialize(new RSAKeyGenParameterSpec(preferred_rsa_algorithm.getPublicKeySizeInBits(), + BigInteger.valueOf(3))); KeyPair key_pair = kpg.generateKeyPair(); try { GenKey key = sess.createKey("Key.1", - KeyAlgorithms.RSA1024, + preferred_rsa_algorithm, null /* pin_value */, null, AppUsage.AUTHENTICATION).setCertificate(cn(), key_pair.getPublic()); - key.setPrivateKey(key_pair.getPrivate()); + key.setPrivateKey(key_pair); sess.closeSession(); - assertTrue("RSA exp match", supports_var_exp); + assertFalse("RSA exp match", rsa_var_exp == null); } catch (SKSException e) { - assertFalse("RSA exp mismatch", supports_var_exp); + assertTrue("RSA exp mismatch", rsa_var_exp == null); checkException(e, "Unsupported RSA exponent value for: Key.1"); } } @@ -3118,7 +3146,7 @@ public void test82() throws Exception { } @Test - public void Test83() throws Exception { + public void test83() throws Exception { boolean dev_pin = device.sks.getDeviceInfo().getDevicePinSupport(); try { ProvSess sess = new ProvSess(device); diff --git a/library/test/org/webpki/sks/twolayer/se/SEReferenceImplementation.java b/library/test/org/webpki/sks/twolayer/se/SEReferenceImplementation.java index 698da08a..268a1de0 100644 --- a/library/test/org/webpki/sks/twolayer/se/SEReferenceImplementation.java +++ b/library/test/org/webpki/sks/twolayer/se/SEReferenceImplementation.java @@ -86,12 +86,13 @@ public class SEReferenceImplementation { ///////////////////////////////////////////////////////////////////////////////////////////// // SKS version and configuration data ///////////////////////////////////////////////////////////////////////////////////////////// - static final String SKS_VENDOR_NAME = "WebPKI.org"; - static final String SKS_VENDOR_DESCRIPTION = "SKS TEE/SE RI - SE Module"; - static final String SKS_UPDATE_URL = null; // Change here to test or disable - static final boolean SKS_RSA_EXPONENT_SUPPORT = true; // Change here to test or disable - static final int MAX_LENGTH_CRYPTO_DATA = 16384; - static final int MAX_LENGTH_EXTENSION_DATA = 65536; + static final String SKS_VENDOR_NAME = "WebPKI.org"; + static final String SKS_VENDOR_DESCRIPTION = "SKS TEE/SE RI - SE Module"; + static final String SKS_UPDATE_URL = null; // Change here to test or disable + static final boolean SKS_RSA_EXPONENT_SUPPORT = false; + static final short[] SKS_DEFAULT_RSA_SUPPORT = {2048}; + static final int MAX_LENGTH_CRYPTO_DATA = 16384; + static final int MAX_LENGTH_EXTENSION_DATA = 65536; static final char[] BASE64_URL = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', @@ -461,7 +462,7 @@ static Algorithm addAlgorithm(String uri, String jceName, int mask) { (byte)0xCD, (byte)0xC9, (byte)0x45, (byte)0xF3, (byte)0x21, (byte)0xC5, (byte)0xCF, (byte)0x41, (byte)0x17, (byte)0xF3, (byte)0x3A, (byte)0xB4}); - for (short rsa_size : SecureKeyStore.SKS_DEFAULT_RSA_SUPPORT) { + for (short rsa_size : SKS_DEFAULT_RSA_SUPPORT) { addAlgorithm("https://webpki.github.io/sks/algorithm#rsa" + rsa_size, null, ALG_RSA_KEY | ALG_KEY_GEN | rsa_size); if (SKS_RSA_EXPONENT_SUPPORT) { @@ -853,7 +854,7 @@ static void checkRSAKeyCompatibility(int rsaKey_size, BigInteger exponent, Strin abort("Unsupported RSA exponent value for: " + keyId); } boolean found = false; - for (short key_size : SecureKeyStore.SKS_DEFAULT_RSA_SUPPORT) { + for (short key_size : SKS_DEFAULT_RSA_SUPPORT) { if (key_size == rsaKey_size) { found = true; break;