JCE: add Security property support for wolfjce.mapJKStoWKS and wolfjce.mapPKCS12toWKS
parent
b302945e5b
commit
fc85641fab
|
@ -80,7 +80,7 @@ public class MainActivity extends AppCompatActivity {
|
|||
public void testFindProvider(TextView tv)
|
||||
throws NoSuchProviderException, NoSuchAlgorithmException {
|
||||
|
||||
Security.addProvider(new WolfCryptProvider());
|
||||
Security.insertProviderAt(new WolfCryptProvider(), 1);
|
||||
|
||||
Provider p = Security.getProvider("wolfJCE");
|
||||
if (p == null) {
|
||||
|
|
|
@ -36,6 +36,40 @@ file for JCE provider customization:
|
|||
| --- | --- | --- | --- |
|
||||
| wolfjce.wks.iterationCount | 210,000 | Numeric | PBKDF2 iteration count (10,000 minimum) |
|
||||
| wolfjce.wks.maxCertChainLength | 100 | Integer | Max cert chain length |
|
||||
| wolfjce.mapJKStoWKS | UNSET | true | Register fake JKS KeyStore service mapped to WKS |
|
||||
| wolfjce.mapPKCS12toWKS | UNSET | true | Register fake PKCS12 KeyStore service mapped to WKS |
|
||||
|
||||
**wolfjce.mapJKStoWKS** - this Security property should be used with caution.
|
||||
When enabled, this will register a "JKS" KeyStore type in wolfJCE, which means
|
||||
calling applications using `KeyStore.getInstance("JKS")` will get a KeyStore
|
||||
implementation from wolfJCE. BUT, this KeyStore type will actually be a
|
||||
WolfSSLKeyStore (WKS) type internally. Loading actual JKS files will fail.
|
||||
This can be helpful when FIPS compliance is required, but existing code gets
|
||||
a JKS KeyStore instance - and this assumes the caller has the flexibility to
|
||||
actually load a real WKS KeyStore file into this KeyStore object. If this
|
||||
property is being set at runtime programatically, the wolfJCE provider services
|
||||
will need to be refreshed / reloaded, by doing:
|
||||
|
||||
```
|
||||
WolfCryptProvider prov = (WolfCryptProvider)Security.getProvider("wolfJCE");
|
||||
prov.refreshServices();
|
||||
```
|
||||
|
||||
**wolfjce.mapPKCS12toWKS** - this Security property should be used with caution.
|
||||
When enabled, this will register a "PKCS12" KeyStore type in wolfJCE, which
|
||||
means calling applications using `KeyStore.getInstance("PKCS12")` will get a
|
||||
KeyStore implementation from wolfJCE. BUT, this KeyStore type will actually be a
|
||||
WolfSSLKeyStore (WKS) type internally. Loading actual PKCS12 files will fail.
|
||||
This can be helpful when FIPS compliance is required, but existing code gets
|
||||
a PKCS12 KeyStore instance - and this assumes the caller has the flexibility to
|
||||
actually load a real WKS KeyStore file into this KeyStore object. If this
|
||||
property is being set at runtime programatically, the wolfJCE provider services
|
||||
will need to be refreshed / reloaded, by doing:
|
||||
|
||||
```
|
||||
WolfCryptProvider prov = (WolfCryptProvider)Security.getProvider("wolfJCE");
|
||||
prov.refreshServices();
|
||||
```
|
||||
|
||||
#### System Property Support
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
package com.wolfssl.provider.jce;
|
||||
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import com.wolfssl.wolfcrypt.FeatureDetect;
|
||||
import com.wolfssl.wolfcrypt.Fips;
|
||||
|
||||
|
@ -37,6 +38,27 @@ public final class WolfCryptProvider extends Provider {
|
|||
*/
|
||||
public WolfCryptProvider() {
|
||||
super("wolfJCE", 1.7, "wolfCrypt JCE Provider");
|
||||
registerServices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh the services provided by this JCE provider.
|
||||
*
|
||||
* This is required when one of the Security properties has been changed
|
||||
* that affect the services offered by this provider. For example:
|
||||
* wolfjce.mapJKStoWKS
|
||||
* wolfjce.mapPKCS12toWKS
|
||||
*/
|
||||
public void refreshServices() {
|
||||
registerServices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register services provided by wolfJCE, called by class constructor.
|
||||
*/
|
||||
private void registerServices() {
|
||||
String mapJksToWks = null;
|
||||
String mapPkcs12ToWks = null;
|
||||
|
||||
/* MessageDigest */
|
||||
if (FeatureDetect.Md5Enabled()) {
|
||||
|
@ -222,6 +244,32 @@ public final class WolfCryptProvider extends Provider {
|
|||
put("KeyStore.WKS",
|
||||
"com.wolfssl.provider.jce.WolfSSLKeyStore");
|
||||
|
||||
/* Fake mapping of JKS to WKS type. Use with caution! This is
|
||||
* usually used when FIPS compliance is needed but code cannot be
|
||||
* changed that creates a JKS KeyStore object type. Any files loaded
|
||||
* into this fake JKS KeyStore MUST be of actual type WKS or failures
|
||||
* will happen. Remove service first here in case of refresh. */
|
||||
remove("KeyStore.JKS");
|
||||
mapJksToWks = Security.getProperty("wolfjce.mapJKStoWKS");
|
||||
if (mapJksToWks != null && !mapJksToWks.isEmpty() &&
|
||||
mapJksToWks.equalsIgnoreCase("true")) {
|
||||
put("KeyStore.JKS",
|
||||
"com.wolfssl.provider.jce.WolfSSLKeyStore");
|
||||
}
|
||||
|
||||
/* Fake mapping of PKCS12 to WKS type. Use with caution! This is
|
||||
* usually used when FIPS compliance is needed but code cannot be
|
||||
* changed that creates a JKS KeyStore object type. Any files loaded
|
||||
* into this fake JKS KeyStore MUST be of actual type WKS or failures
|
||||
* will happen. Remove service first here in case of refresh. */
|
||||
remove("KeyStore.PKCS12");
|
||||
mapPkcs12ToWks = Security.getProperty("wolfjce.mapPKCS12toWKS");
|
||||
if (mapPkcs12ToWks != null && !mapPkcs12ToWks.isEmpty() &&
|
||||
mapPkcs12ToWks.equalsIgnoreCase("true")) {
|
||||
put("KeyStore.PKCS12",
|
||||
"com.wolfssl.provider.jce.WolfSSLKeyStore");
|
||||
}
|
||||
|
||||
/* If using a FIPS version of wolfCrypt, allow private key to be
|
||||
* exported for use. Only applicable to FIPS 140-3 */
|
||||
if (Fips.enabled) {
|
||||
|
|
|
@ -140,7 +140,7 @@ public class WolfCryptKeyAgreementTest {
|
|||
System.out.println("JCE WolfCryptKeyAgreementTest Class");
|
||||
|
||||
/* install wolfJCE provider at runtime */
|
||||
Security.addProvider(new WolfCryptProvider());
|
||||
Security.insertProviderAt(new WolfCryptProvider(), 1);
|
||||
|
||||
Provider p = Security.getProvider("wolfJCE");
|
||||
assertNotNull(p);
|
||||
|
|
|
@ -92,7 +92,7 @@ public class WolfCryptMacTest {
|
|||
System.out.println("JCE WolfCryptMac Class");
|
||||
|
||||
/* install wolfJCE provider at runtime */
|
||||
Security.addProvider(new WolfCryptProvider());
|
||||
Security.insertProviderAt(new WolfCryptProvider(), 1);
|
||||
|
||||
Provider p = Security.getProvider("wolfJCE");
|
||||
assertNotNull(p);
|
||||
|
|
|
@ -64,7 +64,7 @@ public class WolfCryptMessageDigestMd5Test {
|
|||
System.out.println("JCE WolfCryptMessageDigestMd5Test");
|
||||
|
||||
/* install wolfJCE provider at runtime */
|
||||
Security.addProvider(new WolfCryptProvider());
|
||||
Security.insertProviderAt(new WolfCryptProvider(), 1);
|
||||
|
||||
Provider p = Security.getProvider("wolfJCE");
|
||||
assertNotNull(p);
|
||||
|
|
|
@ -64,7 +64,7 @@ public class WolfCryptMessageDigestSha256Test {
|
|||
System.out.println("JCE WolfCryptMessageDigestSha256 Class");
|
||||
|
||||
/* install wolfJCE provider at runtime */
|
||||
Security.addProvider(new WolfCryptProvider());
|
||||
Security.insertProviderAt(new WolfCryptProvider(), 1);
|
||||
|
||||
Provider p = Security.getProvider("wolfJCE");
|
||||
assertNotNull(p);
|
||||
|
|
|
@ -64,7 +64,7 @@ public class WolfCryptMessageDigestSha384Test {
|
|||
System.out.println("JCE WolfCryptMessageDigestSha384 Class");
|
||||
|
||||
/* install wolfJCE provider at runtime */
|
||||
Security.addProvider(new WolfCryptProvider());
|
||||
Security.insertProviderAt(new WolfCryptProvider(), 1);
|
||||
|
||||
Provider p = Security.getProvider("wolfJCE");
|
||||
assertNotNull(p);
|
||||
|
|
|
@ -64,7 +64,7 @@ public class WolfCryptMessageDigestSha512Test {
|
|||
System.out.println("JCE WolfCryptMessageDigestSha512 Class");
|
||||
|
||||
/* install wolfJCE provider at runtime */
|
||||
Security.addProvider(new WolfCryptProvider());
|
||||
Security.insertProviderAt(new WolfCryptProvider(), 1);
|
||||
|
||||
Provider p = Security.getProvider("wolfJCE");
|
||||
assertNotNull(p);
|
||||
|
|
|
@ -65,7 +65,7 @@ public class WolfCryptMessageDigestShaTest {
|
|||
System.out.println("JCE WolfCryptMessageDigestSha Class");
|
||||
|
||||
/* install wolfJCE provider at runtime */
|
||||
Security.addProvider(new WolfCryptProvider());
|
||||
Security.insertProviderAt(new WolfCryptProvider(), 1);
|
||||
|
||||
Provider p = Security.getProvider("wolfJCE");
|
||||
assertNotNull(p);
|
||||
|
|
|
@ -95,7 +95,7 @@ public class WolfCryptSecretKeyFactoryTest {
|
|||
/* Install wolfJCE provider at runtime. Not registering as top priority
|
||||
* provider so we can still likely get SunJCE or platform provider
|
||||
* when not specifying wolfJCE explicitly. */
|
||||
Security.addProvider(new WolfCryptProvider());
|
||||
Security.insertProviderAt(new WolfCryptProvider(), 1);
|
||||
|
||||
Provider p = Security.getProvider(provider);
|
||||
assertNotNull(p);
|
||||
|
|
|
@ -93,7 +93,7 @@ public class WolfCryptSignatureTest {
|
|||
System.out.println("JCE WolfCryptSignature Class");
|
||||
|
||||
/* install wolfJCE provider at runtime */
|
||||
Security.addProvider(new WolfCryptProvider());
|
||||
Security.insertProviderAt(new WolfCryptProvider(), 1);
|
||||
|
||||
Provider p = Security.getProvider("wolfJCE");
|
||||
assertNotNull(p);
|
||||
|
|
|
@ -136,6 +136,12 @@ public class WolfSSLKeyStoreTest {
|
|||
private static Certificate[] eccServerChain = null; /* ECC chain */
|
||||
private static Certificate[] invalidChain = null;
|
||||
|
||||
/* Example .jks KeyStore file paths */
|
||||
private static String clientJKS = null; /* client.jks */
|
||||
|
||||
/* Examnple .p12 KeyStore file paths */
|
||||
private static String clientP12 = null; /* client.p12 */
|
||||
|
||||
/* Example .wks KeyStore file paths */
|
||||
private static String clientWKS = null; /* client.wks */
|
||||
private static String clientRsa1024WKS = null; /* client-rsa-1024.wks */
|
||||
|
@ -381,6 +387,14 @@ public class WolfSSLKeyStoreTest {
|
|||
intEccInt2CertDer =
|
||||
certPre.concat("examples/certs/intermediate/ca-int2-ecc-cert.der");
|
||||
|
||||
/* Set paths to example JKS KeyStore files */
|
||||
clientJKS =
|
||||
certPre.concat("examples/certs/client.jks");
|
||||
|
||||
/* Set paths to example PKCS12 KeyStore files */
|
||||
clientP12 =
|
||||
certPre.concat("examples/certs/client.p12");
|
||||
|
||||
/* Set paths to example WKS KeyStore files */
|
||||
clientWKS =
|
||||
certPre.concat("examples/certs/client.wks");
|
||||
|
@ -1426,6 +1440,139 @@ public class WolfSSLKeyStoreTest {
|
|||
assertEquals(1, store.size());
|
||||
}
|
||||
|
||||
//CHRIS
|
||||
@Test
|
||||
public void testLoadWKSasJKSFromFile()
|
||||
throws KeyStoreException, IOException, FileNotFoundException,
|
||||
NoSuchProviderException, NoSuchAlgorithmException,
|
||||
CertificateException, InvalidKeySpecException,
|
||||
UnrecoverableKeyException {
|
||||
|
||||
WolfCryptProvider prov = null;
|
||||
KeyStore store = null;
|
||||
|
||||
/* Use client.wks (clientWKS) to test. Any WKS KeyStore could be used,
|
||||
* this was just picked since was first used/tested in test above. */
|
||||
|
||||
/* If Security property "wolfjce.mapJKStoWKS=true" has been set,
|
||||
* WolfSSLKeyStore should be able to load a WKS file when using a
|
||||
* "JKS" KeyStore type. */
|
||||
String origProperty = Security.getProperty("wolfjce.mapJKStoWKS");
|
||||
|
||||
/* The wolfJCE service list needs to be refreshed after changing
|
||||
* Security properties that will adjust the services we register */
|
||||
Security.setProperty("wolfjce.mapJKStoWKS", "true");
|
||||
prov = (WolfCryptProvider)Security.getProvider("wolfJCE");
|
||||
prov.refreshServices();
|
||||
|
||||
/* Load WKS as JKS, should work w/o exception */
|
||||
store = KeyStore.getInstance("JKS");
|
||||
assertNotNull(store);
|
||||
assertNotNull(store.getProvider());
|
||||
assertTrue(store.getProvider().contains("wolfJCE"));
|
||||
store.load(new FileInputStream(clientWKS), storePass.toCharArray());
|
||||
assertEquals(2, store.size());
|
||||
|
||||
/* Load JKS as JKS when this is set should fail, since using WKS
|
||||
* implementation underneath fake JKS mapping */
|
||||
try {
|
||||
store.load(new FileInputStream(clientJKS), storePass.toCharArray());
|
||||
fail("Loaded JKS as JKS, but shouldn't with fake mapping set");
|
||||
} catch (IOException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Set mapping to false, loading a WKS as JKS should throw exception */
|
||||
Security.setProperty("wolfjce.mapJKStoWKS", "false");
|
||||
prov = (WolfCryptProvider)Security.getProvider("wolfJCE");
|
||||
prov.refreshServices();
|
||||
store = KeyStore.getInstance("JKS");
|
||||
assertTrue(!store.getProvider().contains("wolfJCE"));
|
||||
try {
|
||||
store.load(new FileInputStream(clientWKS), storePass.toCharArray());
|
||||
fail("Loaded WKS as JKS, but shouldn't have been able to");
|
||||
} catch (IOException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Loading JKS as JKS should work when mapping not set */
|
||||
store.load(new FileInputStream(clientJKS), storePass.toCharArray());
|
||||
|
||||
/* Restore Security property */
|
||||
if (origProperty == null) {
|
||||
Security.setProperty("wolfjce.mapJKStoWKS", "");
|
||||
}
|
||||
else {
|
||||
Security.setProperty("wolfjce.mapJKStoWKS", origProperty);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadWKSasPKCS12FromFile()
|
||||
throws KeyStoreException, IOException, FileNotFoundException,
|
||||
NoSuchProviderException, NoSuchAlgorithmException,
|
||||
CertificateException, InvalidKeySpecException,
|
||||
UnrecoverableKeyException {
|
||||
|
||||
WolfCryptProvider prov = null;
|
||||
KeyStore store = null;
|
||||
|
||||
/* Use client.wks (clientWKS) to test. Any WKS KeyStore could be used,
|
||||
* this was just picked since was first used/tested in test above. */
|
||||
|
||||
/* If Security property "wolfjce.mapPKCS12toWKS=true" has been set,
|
||||
* WolfSSLKeyStore should be able to load a WKS file when using a
|
||||
* "PKCS12" KeyStore type. */
|
||||
String origProperty = Security.getProperty("wolfjce.mapPKCS12toWKS");
|
||||
|
||||
/* The wolfJCE service list needs to be refreshed after changing
|
||||
* Security properties that will adjust the services we register */
|
||||
Security.setProperty("wolfjce.mapPKCS12toWKS", "true");
|
||||
prov = (WolfCryptProvider)Security.getProvider("wolfJCE");
|
||||
prov.refreshServices();
|
||||
|
||||
/* Load WKS as PKCS12, should work w/o exception */
|
||||
store = KeyStore.getInstance("PKCS12");
|
||||
assertNotNull(store);
|
||||
assertNotNull(store.getProvider());
|
||||
assertTrue(store.getProvider().contains("wolfJCE"));
|
||||
store.load(new FileInputStream(clientWKS), storePass.toCharArray());
|
||||
assertEquals(2, store.size());
|
||||
|
||||
/* Load PKCS12 as PKCS12 when this is set should fail, since using WKS
|
||||
* implementation underneath fake PKCS12 mapping */
|
||||
try {
|
||||
store.load(new FileInputStream(clientP12), storePass.toCharArray());
|
||||
fail("Loaded PKCS12 as PKCS12, but shouldn't with fake mapping set");
|
||||
} catch (IOException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Set mapping to false, loading WKS as PKCS12 should throw exception */
|
||||
Security.setProperty("wolfjce.mapPKCS12toWKS", "false");
|
||||
prov = (WolfCryptProvider)Security.getProvider("wolfJCE");
|
||||
prov.refreshServices();
|
||||
store = KeyStore.getInstance("PKCS12");
|
||||
assertTrue(!store.getProvider().contains("wolfJCE"));
|
||||
try {
|
||||
store.load(new FileInputStream(clientWKS), storePass.toCharArray());
|
||||
fail("Loaded WKS as PKCS12, but shouldn't have been able to");
|
||||
} catch (IOException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* Loading PKCS12 as PKCS12 should work when mapping not set */
|
||||
store.load(new FileInputStream(clientP12), storePass.toCharArray());
|
||||
|
||||
/* Restore Security property */
|
||||
if (origProperty == null) {
|
||||
Security.setProperty("wolfjce.mapPKCS12toWKS", "");
|
||||
}
|
||||
else {
|
||||
Security.setProperty("wolfjce.mapPKCS12toWKS", origProperty);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadSystemCAKeyStore()
|
||||
throws KeyStoreException, IOException, FileNotFoundException,
|
||||
|
|
Loading…
Reference in New Issue