JCE: initial implementation of WolfCryptUtil.convertKeyStoreToWKS()
parent
783c9275de
commit
0834dbdafc
|
@ -234,8 +234,7 @@ SecretKey objects.
|
||||||
#### Converting Other KeyStore Formats to WKS
|
#### Converting Other KeyStore Formats to WKS
|
||||||
|
|
||||||
The Java `keytool` application can be used to convert between KeyStore formats.
|
The Java `keytool` application can be used to convert between KeyStore formats.
|
||||||
This can be easily used for example to convert a JKS KeyStore into a WKS
|
This can be easily used to convert a JKS KeyStore into a WKS format KeyStore.
|
||||||
format KeyStore.
|
|
||||||
|
|
||||||
The following example command would convert a KeyStore in JKS format named
|
The following example command would convert a KeyStore in JKS format named
|
||||||
`server.jks` to a KeyStore in WKS format named `server.wks`:
|
`server.jks` to a KeyStore in WKS format named `server.wks`:
|
||||||
|
@ -248,6 +247,50 @@ keytool -importkeystore -srckeystore server.jks -destkeystore server.wks \
|
||||||
--providerpath /path/to/wolfcrypt-jni.jar
|
--providerpath /path/to/wolfcrypt-jni.jar
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Additionally, wolfJCE provides a utility method `WolfCryptUtil.convertKeyStoreToWKS()`
|
||||||
|
that can be used programmatically to convert KeyStore formats. This method
|
||||||
|
supports converting from JKS, PKCS12, and WKS formats to WKS format. When
|
||||||
|
converting from WKS to WKS, the method efficiently returns the same input
|
||||||
|
stream without performing any conversion.
|
||||||
|
|
||||||
|
The method automatically detects the input KeyStore format and handles the
|
||||||
|
conversion appropriately. It supports the following features:
|
||||||
|
|
||||||
|
- Automatic format detection (WKS, JKS, PKCS12)
|
||||||
|
- Preservation of all certificates and keys from the source KeyStore
|
||||||
|
- Support for both key entries (with certificate chains) and certificate-only entries
|
||||||
|
- Efficient handling of WKS input (returns same stream)
|
||||||
|
- Proper stream handling with mark/reset support for large KeyStores
|
||||||
|
|
||||||
|
**FIPS NOTE:** This utility method will call Sun provider code for JKS
|
||||||
|
and PKCS12. This means that if using wolfCrypt FIPS, these calls will make
|
||||||
|
calls into non-FIPS compliant cryptography for the conversion. Please take
|
||||||
|
this into consideration when being used in a FIPS compliant environment.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
|
||||||
|
```java
|
||||||
|
import com.wolfssl.provider.jce.WolfCryptUtil;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
|
||||||
|
/* Load your source KeyStore (JKS, PKCS12, or WKS) */
|
||||||
|
InputStream sourceStream = ...;
|
||||||
|
char[] password = "your_password".toCharArray();
|
||||||
|
|
||||||
|
/* Convert to WKS format, fail on insert errors */
|
||||||
|
InputStream wksStream = WolfCryptUtil.convertKeyStoreToWKS(sourceStream, password, true);
|
||||||
|
|
||||||
|
/* Load the converted WKS KeyStore */
|
||||||
|
KeyStore wksStore = KeyStore.getInstance("WKS", "wolfJCE");
|
||||||
|
wksStore.load(wksStream, password);
|
||||||
|
```
|
||||||
|
|
||||||
|
The method respects the Security properties `wolfjce.mapJKStoWKS` and
|
||||||
|
`wolfjce.mapPKCS12toWKS` when performing conversions. If these properties are
|
||||||
|
set to "true", the method will use reflection to find the Sun provider
|
||||||
|
implementations for JKS and PKCS12 to use for conversion.
|
||||||
|
|
||||||
To list entries inside a WKS keystore using the `keytool`, a command
|
To list entries inside a WKS keystore using the `keytool`, a command
|
||||||
similar to the following can be used (with the `-list` option):
|
similar to the following can be used (with the `-list` option):
|
||||||
|
|
||||||
|
@ -388,7 +431,7 @@ ant build system, please see the main README.md included in this package.
|
||||||
wolfSSL (company) has it's own set of code signing certificates from Oracle
|
wolfSSL (company) has it's own set of code signing certificates from Oracle
|
||||||
that allow wolfJCE to be authenticated in the Oracle JDK. With each release
|
that allow wolfJCE to be authenticated in the Oracle JDK. With each release
|
||||||
of wolfJCE, wolfSSL ships a couple pre-signed versions of the
|
of wolfJCE, wolfSSL ships a couple pre-signed versions of the
|
||||||
‘wolfcrypt-jni.jar”, located at:
|
'wolfcrypt-jni.jar", located at:
|
||||||
|
|
||||||
wolfcrypt-jni-X.X.X/lib/signed/debug/wolfcrypt-jni.jar
|
wolfcrypt-jni-X.X.X/lib/signed/debug/wolfcrypt-jni.jar
|
||||||
wolfcrypt-jni-X.X.X/lib/signed/release/wolfcrypt-jni.jar
|
wolfcrypt-jni-X.X.X/lib/signed/release/wolfcrypt-jni.jar
|
||||||
|
|
|
@ -82,6 +82,7 @@ infer --fail-on-issue run -- javac \
|
||||||
src/main/java/com/wolfssl/provider/jce/WolfCryptRandom.java \
|
src/main/java/com/wolfssl/provider/jce/WolfCryptRandom.java \
|
||||||
src/main/java/com/wolfssl/provider/jce/WolfCryptSecretKeyFactory.java \
|
src/main/java/com/wolfssl/provider/jce/WolfCryptSecretKeyFactory.java \
|
||||||
src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java \
|
src/main/java/com/wolfssl/provider/jce/WolfCryptSignature.java \
|
||||||
|
src/main/java/com/wolfssl/provider/jce/WolfCryptUtil.java \
|
||||||
src/main/java/com/wolfssl/provider/jce/WolfSSLKeyStore.java
|
src/main/java/com/wolfssl/provider/jce/WolfSSLKeyStore.java
|
||||||
|
|
||||||
RETVAL=$?
|
RETVAL=$?
|
||||||
|
|
|
@ -0,0 +1,390 @@
|
||||||
|
/* WolfCryptUtil.java
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2025 wolfSSL Inc.
|
||||||
|
*
|
||||||
|
* This file is part of wolfSSL.
|
||||||
|
*
|
||||||
|
* wolfSSL is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* wolfSSL is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.wolfssl.provider.jce;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.security.Key;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import java.security.KeyStoreException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.NoSuchProviderException;
|
||||||
|
import java.security.Provider;
|
||||||
|
import java.security.Security;
|
||||||
|
import java.security.UnrecoverableKeyException;
|
||||||
|
import java.security.cert.Certificate;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class containing helper functions for wolfCrypt JCE provider.
|
||||||
|
*/
|
||||||
|
public class WolfCryptUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum size of the keystore buffer to mark. We try to set this
|
||||||
|
* high enough to handle any large keystore. Although there is no
|
||||||
|
* upper limit on the size of a keystore, looking at the JDK 23 cacerts
|
||||||
|
* KeyStore file, that is 190kB. We leave ample room for growth here
|
||||||
|
* with 512kB.
|
||||||
|
*/
|
||||||
|
private static final int MAX_KEYSTORE_SIZE = 512 * 1024;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chunk size for reading the keystore. We use 4kB as a happy medium
|
||||||
|
* between memory usage and performance.
|
||||||
|
*/
|
||||||
|
private static final int KEYSTORE_CHUNK_SIZE = 4 * 1024;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal method for logging output.
|
||||||
|
*
|
||||||
|
* @param msg message to be logged
|
||||||
|
*/
|
||||||
|
private static synchronized void log(String msg) {
|
||||||
|
WolfCryptDebug.log(WolfCryptUtil.class, WolfCryptDebug.INFO,
|
||||||
|
() -> msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a Java KeyStore (JKS or PKCS12) to a WolfSSLKeyStore (WKS)
|
||||||
|
* format.
|
||||||
|
*
|
||||||
|
* This method detects the type of the input KeyStore (WKS, JKS, or PKCS12)
|
||||||
|
* and converts it to WKS format if needed. All certificates and keys from
|
||||||
|
* the source KeyStore are transferred to the destination KeyStore. If the
|
||||||
|
* input KeyStore is already of type WKS, the method will return the same
|
||||||
|
* InputStream.
|
||||||
|
*
|
||||||
|
* @param stream Input stream containing a WKS, JKS, or PKCS12 KeyStore
|
||||||
|
* @param oldPassword Password used to decrypt KeyStore entries.
|
||||||
|
* @param newPassword Password used to encrypt KeyStore entries. When used
|
||||||
|
* with wolfCrypt FIPS, this password needs to meet FIPS minimum
|
||||||
|
* HMAC key size requirements and must be at least 14 characters.
|
||||||
|
* @param failOnInsertErrors If true, throw an exception if an error occurs
|
||||||
|
* during the insertion of a certificate or key into the newly
|
||||||
|
* created WKS KeyStore. If false, log the error and continue
|
||||||
|
* inserting the remaining entries. When used with wolfCrypt FIPS,
|
||||||
|
* entries can fail to insert into WKS KeyStore due to FIPS
|
||||||
|
* restrictions on the algorithms used.
|
||||||
|
* @return InputStream containing the newly created WKS KeyStore
|
||||||
|
* @throws IOException If an I/O error occurs
|
||||||
|
* @throws NoSuchProviderException If required security providers are not
|
||||||
|
* available or if reflection operations fail when accessing the
|
||||||
|
* original KeyStore implementations
|
||||||
|
*/
|
||||||
|
public static InputStream convertKeyStoreToWKS(InputStream stream,
|
||||||
|
char[] oldPassword, char[] newPassword, boolean failOnInsertErrors)
|
||||||
|
throws IOException, NoSuchProviderException {
|
||||||
|
|
||||||
|
boolean mapJksToWks = false;
|
||||||
|
boolean mapPkcs12ToWks = false;
|
||||||
|
boolean wksFound = false;
|
||||||
|
boolean jksFound = false;
|
||||||
|
KeyStore sourceStore = null;
|
||||||
|
|
||||||
|
log("converting KeyStore InputStream to WKS format");
|
||||||
|
|
||||||
|
if (stream == null) {
|
||||||
|
throw new IllegalArgumentException("Input stream cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (oldPassword == null) {
|
||||||
|
throw new IllegalArgumentException("Old password cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newPassword == null) {
|
||||||
|
throw new IllegalArgumentException("New password cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure wolfJCE provider is available and registered */
|
||||||
|
Provider wolfJCE = Security.getProvider("wolfJCE");
|
||||||
|
if (wolfJCE == null) {
|
||||||
|
Security.addProvider(new WolfCryptProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
/* Check if wolfJCE has mapped JKS or PKCS12 to WKS */
|
||||||
|
String mapJksToWksStr =
|
||||||
|
Security.getProperty("wolfjce.mapJKStoWKS");
|
||||||
|
if (mapJksToWksStr != null && !mapJksToWksStr.isEmpty() &&
|
||||||
|
mapJksToWksStr.equalsIgnoreCase("true")) {
|
||||||
|
mapJksToWks = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
String mapPkcs12ToWksStr =
|
||||||
|
Security.getProperty("wolfjce.mapPKCS12toWKS");
|
||||||
|
if (mapPkcs12ToWksStr != null && !mapPkcs12ToWksStr.isEmpty() &&
|
||||||
|
mapPkcs12ToWksStr.equalsIgnoreCase("true")) {
|
||||||
|
mapPkcs12ToWks = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
log("JKS to WKS mapping enabled: " + mapJksToWks);
|
||||||
|
log("PKCS12 to WKS mapping enabled: " + mapPkcs12ToWks);
|
||||||
|
|
||||||
|
/* Since we will be doing KeyStore type detection by trying to
|
||||||
|
* read the KeyStore, we want to make sure we have the ability
|
||||||
|
* to mark() the stream. If we don't have the ability, we copy
|
||||||
|
* the stream into a ByteArrayOutputStream and then into a
|
||||||
|
* ByteArrayInputStream which is markable. */
|
||||||
|
if (!stream.markSupported()) {
|
||||||
|
try {
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
int numRead;
|
||||||
|
byte[] data = new byte[KEYSTORE_CHUNK_SIZE];
|
||||||
|
while ((numRead = stream.read(data, 0, data.length)) != -1) {
|
||||||
|
buffer.write(data, 0, numRead);
|
||||||
|
}
|
||||||
|
buffer.flush();
|
||||||
|
stream = new ByteArrayInputStream(buffer.toByteArray());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IOException("Failed to read stream contents", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mark the current position in the stream */
|
||||||
|
stream.mark(MAX_KEYSTORE_SIZE);
|
||||||
|
|
||||||
|
/* Try WKS */
|
||||||
|
try {
|
||||||
|
sourceStore = KeyStore.getInstance("WKS", "wolfJCE");
|
||||||
|
sourceStore.load(stream, oldPassword);
|
||||||
|
wksFound = true;
|
||||||
|
|
||||||
|
log("Input KeyStore is already in WKS format");
|
||||||
|
} catch (KeyStoreException | NoSuchAlgorithmException |
|
||||||
|
CertificateException | IOException e) {
|
||||||
|
/* Not a WKS KeyStore, continue with other formats */
|
||||||
|
} finally {
|
||||||
|
stream.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try JKS */
|
||||||
|
if (!wksFound) {
|
||||||
|
try {
|
||||||
|
if (mapJksToWks) {
|
||||||
|
/* If JKS is mapped to WKS, use reflection to get the
|
||||||
|
* Sun provider's JKS implementation */
|
||||||
|
try {
|
||||||
|
sourceStore = getJksKeyStoreFromSunProvider();
|
||||||
|
} catch (ReflectiveOperationException |
|
||||||
|
KeyStoreException ex) {
|
||||||
|
throw new NoSuchProviderException(
|
||||||
|
"Failed to get JKS implementation via " +
|
||||||
|
"reflection from Sun provider: " +
|
||||||
|
ex.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sourceStore = KeyStore.getInstance("JKS");
|
||||||
|
}
|
||||||
|
sourceStore.load(stream, oldPassword);
|
||||||
|
jksFound = true;
|
||||||
|
|
||||||
|
log("Input KeyStore is in JKS format");
|
||||||
|
} catch (IOException | NoSuchAlgorithmException |
|
||||||
|
CertificateException e) {
|
||||||
|
/* Not a JKS KeyStore, continue with other formats */
|
||||||
|
} finally {
|
||||||
|
stream.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try PKCS12 */
|
||||||
|
if (!wksFound && !jksFound) {
|
||||||
|
try {
|
||||||
|
if (mapPkcs12ToWks) {
|
||||||
|
/* If PKCS12 is mapped to WKS, use reflection to get
|
||||||
|
* the Sun provider's PKCS12 implementation */
|
||||||
|
try {
|
||||||
|
sourceStore = getPkcs12KeyStoreFromSunProvider();
|
||||||
|
} catch (ReflectiveOperationException |
|
||||||
|
KeyStoreException ex) {
|
||||||
|
throw new NoSuchProviderException(
|
||||||
|
"Failed to get PKCS12 implementation via " +
|
||||||
|
"reflection from Sun provider: " +
|
||||||
|
ex.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sourceStore = KeyStore.getInstance("PKCS12");
|
||||||
|
}
|
||||||
|
sourceStore.load(stream, oldPassword);
|
||||||
|
|
||||||
|
log("Input KeyStore is in PKCS12 format");
|
||||||
|
} catch (KeyStoreException | NoSuchAlgorithmException |
|
||||||
|
CertificateException ex) {
|
||||||
|
throw new IOException(
|
||||||
|
"Input KeyStore is neither WKS, JKS nor " +
|
||||||
|
"PKCS12 KeyStore format", ex);
|
||||||
|
} finally {
|
||||||
|
stream.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create destination WKS KeyStore */
|
||||||
|
KeyStore destStore = KeyStore.getInstance("WKS", "wolfJCE");
|
||||||
|
destStore.load(null, newPassword);
|
||||||
|
log("Creating destination WKS KeyStore to populate");
|
||||||
|
|
||||||
|
/* Copy all entries from source to destination */
|
||||||
|
Enumeration<String> aliases = sourceStore.aliases();
|
||||||
|
while (aliases.hasMoreElements()) {
|
||||||
|
String alias = aliases.nextElement();
|
||||||
|
|
||||||
|
if (sourceStore.isKeyEntry(alias)) {
|
||||||
|
/* Handle key entries (may include a certificate chain) */
|
||||||
|
try {
|
||||||
|
Key key = sourceStore.getKey(alias, oldPassword);
|
||||||
|
Certificate[] chain =
|
||||||
|
sourceStore.getCertificateChain(alias);
|
||||||
|
destStore.setKeyEntry(alias, key, newPassword, chain);
|
||||||
|
} catch (UnrecoverableKeyException | KeyStoreException e) {
|
||||||
|
if (failOnInsertErrors) {
|
||||||
|
throw new IOException("Failed to copy key entry: " +
|
||||||
|
alias, e);
|
||||||
|
} else {
|
||||||
|
log("Failed to copy key entry: " + alias +
|
||||||
|
", continuing with next entry");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (sourceStore.isCertificateEntry(alias)) {
|
||||||
|
/* Handle certificate-only entries */
|
||||||
|
try {
|
||||||
|
Certificate cert = sourceStore.getCertificate(alias);
|
||||||
|
destStore.setCertificateEntry(alias, cert);
|
||||||
|
} catch (KeyStoreException e) {
|
||||||
|
if (failOnInsertErrors) {
|
||||||
|
throw new IOException(
|
||||||
|
"Failed to copy certificate entry: " +
|
||||||
|
alias, e);
|
||||||
|
} else {
|
||||||
|
log("Failed to copy certificate entry: " + alias +
|
||||||
|
", continuing with next entry");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log("Copied all entries from source to destination KeyStore");
|
||||||
|
|
||||||
|
/* Write the WKS KeyStore to a byte array and return as
|
||||||
|
* InputStream */
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
destStore.store(baos, newPassword);
|
||||||
|
|
||||||
|
return new ByteArrayInputStream(baos.toByteArray());
|
||||||
|
|
||||||
|
} catch (KeyStoreException | NoSuchAlgorithmException |
|
||||||
|
CertificateException e) {
|
||||||
|
throw new IOException("Error during KeyStore conversion", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Sun provider JKS KeyStore implementation using reflection.
|
||||||
|
* This is used when wolfJCE has registered itself as the JKS provider
|
||||||
|
* using the Security property "wolfjce.mapJKStoWKS".
|
||||||
|
*
|
||||||
|
* @return A KeyStore instance from the Sun provider for JKS format
|
||||||
|
* @throws ReflectiveOperationException If reflection fails
|
||||||
|
* @throws KeyStoreException If the KeyStore cannot be created
|
||||||
|
*/
|
||||||
|
private static KeyStore getJksKeyStoreFromSunProvider()
|
||||||
|
throws ReflectiveOperationException, KeyStoreException {
|
||||||
|
/* Try to find the Sun provider */
|
||||||
|
Provider sunProvider = Security.getProvider("SUN");
|
||||||
|
if (sunProvider == null) {
|
||||||
|
throw new KeyStoreException("SUN provider not available");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
/* Try to get the KeyStore from the explicit provider first */
|
||||||
|
return KeyStore.getInstance("JKS", sunProvider);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
/* Fallback to using reflection if the first approach fails */
|
||||||
|
/* Load the JKS KeyStore class directly from the Sun provider */
|
||||||
|
Class<?> jksKeyStoreClass =
|
||||||
|
Class.forName("sun.security.provider.JavaKeyStore$JKS");
|
||||||
|
Constructor<?> constructor =
|
||||||
|
jksKeyStoreClass.getDeclaredConstructor();
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
KeyStore ks = (KeyStore) constructor.newInstance();
|
||||||
|
|
||||||
|
/* Initialize the KeyStore */
|
||||||
|
Method engineInitMethod =
|
||||||
|
jksKeyStoreClass.getDeclaredMethod("engineInit");
|
||||||
|
engineInitMethod.setAccessible(true);
|
||||||
|
engineInitMethod.invoke(ks);
|
||||||
|
|
||||||
|
return ks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Sun provider PKCS12 KeyStore implementation using reflection.
|
||||||
|
* This is used when wolfJCE has registered itself as the PKCS12 provider
|
||||||
|
* using the Security property "wolfjce.mapPKCS12toWKS".
|
||||||
|
*
|
||||||
|
* @return A KeyStore instance from the Sun provider for PKCS12 format
|
||||||
|
* @throws ReflectiveOperationException If reflection fails
|
||||||
|
* @throws KeyStoreException If the KeyStore cannot be created
|
||||||
|
*/
|
||||||
|
private static KeyStore getPkcs12KeyStoreFromSunProvider()
|
||||||
|
throws ReflectiveOperationException, KeyStoreException {
|
||||||
|
/* Try to find the SunJSSE provider */
|
||||||
|
Provider sunJsseProvider = Security.getProvider("SunJSSE");
|
||||||
|
if (sunJsseProvider == null) {
|
||||||
|
/* Try Sun provider as fallback */
|
||||||
|
sunJsseProvider = Security.getProvider("SUN");
|
||||||
|
if (sunJsseProvider == null) {
|
||||||
|
throw new KeyStoreException(
|
||||||
|
"Neither SunJSSE nor SUN provider available");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
/* Try to get the KeyStore through the provider first */
|
||||||
|
return KeyStore.getInstance("PKCS12", sunJsseProvider);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
/* Fallback to using reflection if the first approach fails */
|
||||||
|
/* Load the PKCS12 KeyStore class */
|
||||||
|
Class<?> pkcs12KeyStoreClass =
|
||||||
|
Class.forName("sun.security.pkcs12.PKCS12KeyStore");
|
||||||
|
Constructor<?> constructor =
|
||||||
|
pkcs12KeyStoreClass.getDeclaredConstructor();
|
||||||
|
constructor.setAccessible(true);
|
||||||
|
KeyStore ks = (KeyStore) constructor.newInstance();
|
||||||
|
|
||||||
|
/* Initialize the KeyStore */
|
||||||
|
Method engineInitMethod =
|
||||||
|
pkcs12KeyStoreClass.getDeclaredMethod("engineInit");
|
||||||
|
engineInitMethod.setAccessible(true);
|
||||||
|
engineInitMethod.invoke(ks);
|
||||||
|
|
||||||
|
return ks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,468 @@
|
||||||
|
/* WolfCryptUtilsTest.java
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006-2025 wolfSSL Inc.
|
||||||
|
*
|
||||||
|
* This file is part of wolfSSL.
|
||||||
|
*
|
||||||
|
* wolfSSL is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* wolfSSL is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.wolfssl.provider.jce.test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import org.junit.Rule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.rules.TestRule;
|
||||||
|
import org.junit.rules.TestWatcher;
|
||||||
|
import org.junit.runner.Description;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.File;
|
||||||
|
import java.security.Security;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.security.Provider;
|
||||||
|
import java.security.KeyStore;
|
||||||
|
import com.wolfssl.provider.jce.WolfCryptProvider;
|
||||||
|
import com.wolfssl.provider.jce.WolfCryptUtil;
|
||||||
|
import com.wolfssl.wolfcrypt.Fips;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test suite for WolfCryptUtils.convertKeyStoreToWKS method.
|
||||||
|
*
|
||||||
|
* Tests converting JKS KeyStore to WKS format and error handling.
|
||||||
|
*/
|
||||||
|
public class WolfCryptUtilTest {
|
||||||
|
|
||||||
|
/* Common test password for test KeyStores */
|
||||||
|
private static final char[] PASSWORD = "wolfsslpassword".toCharArray();
|
||||||
|
private static final String WKS_PROVIDER = "wolfJCE";
|
||||||
|
private static final String TEST_ALIAS = "server";
|
||||||
|
private static final String TEST_JKS_PATH = "examples/certs/server.jks";
|
||||||
|
private static final String TEST_P12_PATH = "examples/certs/client.p12";
|
||||||
|
private static final String TEST_WKS_PATH = "examples/certs/server.wks";
|
||||||
|
private static final char[] CACERTS_PASSWORD = "changeit".toCharArray();
|
||||||
|
|
||||||
|
/* Original security property values */
|
||||||
|
private static String origMapJksToWks = null;
|
||||||
|
private static String origMapPkcs12ToWks = null;
|
||||||
|
|
||||||
|
@Rule(order = Integer.MIN_VALUE)
|
||||||
|
public TestRule testWatcher = new TestWatcher() {
|
||||||
|
protected void starting(Description desc) {
|
||||||
|
System.out.println("\t" + desc.getMethodName());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpClass() {
|
||||||
|
|
||||||
|
System.out.println("JCE WolfCryptUtils Class");
|
||||||
|
|
||||||
|
/* Register wolfJCE provider if not already done */
|
||||||
|
Provider wolfJCE = Security.getProvider(WKS_PROVIDER);
|
||||||
|
if (wolfJCE == null) {
|
||||||
|
Security.insertProviderAt(new WolfCryptProvider(), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Store original security property values */
|
||||||
|
origMapJksToWks = Security.getProperty("wolfjce.mapJKStoWKS");
|
||||||
|
origMapPkcs12ToWks = Security.getProperty("wolfjce.mapPKCS12toWKS");
|
||||||
|
|
||||||
|
/* Make sure we set them to known values at the start */
|
||||||
|
Security.setProperty("wolfjce.mapJKStoWKS", "false");
|
||||||
|
Security.setProperty("wolfjce.mapPKCS12toWKS", "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDownClass() {
|
||||||
|
/* Restore original security property values */
|
||||||
|
if (origMapJksToWks != null) {
|
||||||
|
Security.setProperty("wolfjce.mapJKStoWKS", origMapJksToWks);
|
||||||
|
} else {
|
||||||
|
Security.setProperty("wolfjce.mapJKStoWKS", "false");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (origMapPkcs12ToWks != null) {
|
||||||
|
Security.setProperty("wolfjce.mapPKCS12toWKS", origMapPkcs12ToWks);
|
||||||
|
} else {
|
||||||
|
Security.setProperty("wolfjce.mapPKCS12toWKS", "false");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to load a KeyStore file into a ByteArrayInputStream
|
||||||
|
* @param path Path to the KeyStore file
|
||||||
|
* @return ByteArrayInputStream containing the KeyStore data
|
||||||
|
* @throws Exception if file cannot be read
|
||||||
|
*/
|
||||||
|
private static synchronized ByteArrayInputStream loadKeyStoreFile(
|
||||||
|
String path) throws Exception {
|
||||||
|
|
||||||
|
FileInputStream fis = new FileInputStream(path);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = fis.read(buffer)) != -1) {
|
||||||
|
baos.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
fis.close();
|
||||||
|
|
||||||
|
return new ByteArrayInputStream(baos.toByteArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper method to find the Java cacerts file
|
||||||
|
* @return Path to cacerts file if found, null otherwise
|
||||||
|
*/
|
||||||
|
private static String findCacertsFile() {
|
||||||
|
String javaHome = System.getProperty("java.home");
|
||||||
|
if (javaHome == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Common locations for cacerts file */
|
||||||
|
String[] possiblePaths = {
|
||||||
|
/* Standard locations */
|
||||||
|
javaHome + "/lib/security/cacerts",
|
||||||
|
javaHome + "/jre/lib/security/cacerts",
|
||||||
|
/* Android locations */
|
||||||
|
javaHome + "/etc/security/cacerts",
|
||||||
|
/* Windows specific */
|
||||||
|
javaHome + "\\lib\\security\\cacerts",
|
||||||
|
javaHome + "\\jre\\lib\\security\\cacerts"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (String path : possiblePaths) {
|
||||||
|
File file = new File(path);
|
||||||
|
if (file.exists() && file.isFile()) {
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with null input stream (should throw an exception)
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testNullInputStream() {
|
||||||
|
try {
|
||||||
|
WolfCryptUtil.convertKeyStoreToWKS(null, PASSWORD, PASSWORD, true);
|
||||||
|
fail("Should have thrown an exception for null input stream");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
/* Expected exception */
|
||||||
|
assertTrue("Exception message should indicate null input stream",
|
||||||
|
e.getMessage().contains("null"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail("Unexpected exception type: " + e.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test with null password (should throw an exception)
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testNullPassword() {
|
||||||
|
/* Create a dummy keystore for testing */
|
||||||
|
try {
|
||||||
|
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||||
|
ks.load(null, PASSWORD);
|
||||||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
ks.store(baos, PASSWORD);
|
||||||
|
ByteArrayInputStream bais =
|
||||||
|
new ByteArrayInputStream(baos.toByteArray());
|
||||||
|
|
||||||
|
WolfCryptUtil.convertKeyStoreToWKS(bais, PASSWORD, null, true);
|
||||||
|
fail("Should have thrown an exception for null password");
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
/* Expected exception */
|
||||||
|
assertTrue("Exception message should indicate null password",
|
||||||
|
e.getMessage().contains("null"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
fail("Unexpected exception type: " + e.getClass().getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test converting JKS to WKS with mapJKStoWKS=false
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testConvertJksToWksWithoutMapping() throws Exception {
|
||||||
|
/* Store original property value */
|
||||||
|
String origValue = Security.getProperty("wolfjce.mapJKStoWKS");
|
||||||
|
|
||||||
|
try {
|
||||||
|
Security.setProperty("wolfjce.mapJKStoWKS", "false");
|
||||||
|
|
||||||
|
/* Load test JKS KeyStore */
|
||||||
|
ByteArrayInputStream jksStream = loadKeyStoreFile(TEST_JKS_PATH);
|
||||||
|
|
||||||
|
/* Convert to WKS */
|
||||||
|
ByteArrayInputStream wksStream =
|
||||||
|
(ByteArrayInputStream)WolfCryptUtil.convertKeyStoreToWKS(
|
||||||
|
jksStream, PASSWORD, PASSWORD, true);
|
||||||
|
|
||||||
|
/* Load the converted WKS KeyStore */
|
||||||
|
KeyStore wksStore = KeyStore.getInstance("WKS", "wolfJCE");
|
||||||
|
wksStore.load(wksStream, PASSWORD);
|
||||||
|
|
||||||
|
/* Verify the key and certificate were properly converted */
|
||||||
|
assertTrue("Key entry should exist",
|
||||||
|
wksStore.isKeyEntry(TEST_ALIAS));
|
||||||
|
assertNotNull("Private key should exist",
|
||||||
|
wksStore.getKey(TEST_ALIAS, PASSWORD));
|
||||||
|
assertNotNull("Certificate chain should exist",
|
||||||
|
wksStore.getCertificateChain(TEST_ALIAS));
|
||||||
|
assertEquals("Certificate chain should have length 2",
|
||||||
|
2, wksStore.getCertificateChain(TEST_ALIAS).length);
|
||||||
|
} finally {
|
||||||
|
/* Restore original property value */
|
||||||
|
if (origValue != null) {
|
||||||
|
Security.setProperty("wolfjce.mapJKStoWKS", origValue);
|
||||||
|
} else {
|
||||||
|
Security.setProperty("wolfjce.mapJKStoWKS", "false");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test converting JKS to WKS with mapJKStoWKS=true
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testConvertJksToWksWithMapping() throws Exception {
|
||||||
|
/* Store original property value */
|
||||||
|
String origValue = Security.getProperty("wolfjce.mapJKStoWKS");
|
||||||
|
|
||||||
|
try {
|
||||||
|
Security.setProperty("wolfjce.mapJKStoWKS", "true");
|
||||||
|
|
||||||
|
/* Load test JKS KeyStore */
|
||||||
|
ByteArrayInputStream jksStream = loadKeyStoreFile(TEST_JKS_PATH);
|
||||||
|
|
||||||
|
/* Convert to WKS */
|
||||||
|
ByteArrayInputStream wksStream =
|
||||||
|
(ByteArrayInputStream)WolfCryptUtil.convertKeyStoreToWKS(
|
||||||
|
jksStream, PASSWORD, PASSWORD, true);
|
||||||
|
|
||||||
|
/* Load the converted WKS KeyStore */
|
||||||
|
KeyStore wksStore = KeyStore.getInstance("WKS", "wolfJCE");
|
||||||
|
wksStore.load(wksStream, PASSWORD);
|
||||||
|
|
||||||
|
/* Verify the key and certificate were properly converted */
|
||||||
|
assertTrue("Key entry should exist",
|
||||||
|
wksStore.isKeyEntry(TEST_ALIAS));
|
||||||
|
assertNotNull("Private key should exist",
|
||||||
|
wksStore.getKey(TEST_ALIAS, PASSWORD));
|
||||||
|
assertNotNull("Certificate chain should exist",
|
||||||
|
wksStore.getCertificateChain(TEST_ALIAS));
|
||||||
|
assertEquals("Certificate chain should have length 2",
|
||||||
|
2, wksStore.getCertificateChain(TEST_ALIAS).length);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
/* Restore original property value */
|
||||||
|
if (origValue != null) {
|
||||||
|
Security.setProperty("wolfjce.mapJKStoWKS", origValue);
|
||||||
|
} else {
|
||||||
|
Security.setProperty("wolfjce.mapJKStoWKS", "false");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test converting PKCS12 to WKS with mapPKCS12toWKS=false
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testConvertP12ToWksWithoutMapping() throws Exception {
|
||||||
|
/* Store original property value */
|
||||||
|
String origValue = Security.getProperty("wolfjce.mapPKCS12toWKS");
|
||||||
|
|
||||||
|
try {
|
||||||
|
Security.setProperty("wolfjce.mapPKCS12toWKS", "false");
|
||||||
|
|
||||||
|
/* Load test PKCS12 KeyStore */
|
||||||
|
ByteArrayInputStream p12Stream = loadKeyStoreFile(TEST_P12_PATH);
|
||||||
|
|
||||||
|
/* Convert to WKS */
|
||||||
|
ByteArrayInputStream wksStream =
|
||||||
|
(ByteArrayInputStream)WolfCryptUtil.convertKeyStoreToWKS(
|
||||||
|
p12Stream, PASSWORD, PASSWORD, true);
|
||||||
|
|
||||||
|
/* Load the converted WKS KeyStore */
|
||||||
|
KeyStore wksStore = KeyStore.getInstance("WKS", "wolfJCE");
|
||||||
|
wksStore.load(wksStream, PASSWORD);
|
||||||
|
|
||||||
|
/* Verify both entries were properly converted */
|
||||||
|
assertTrue("RSA key entry should exist",
|
||||||
|
wksStore.isKeyEntry("client"));
|
||||||
|
assertTrue("ECC key entry should exist",
|
||||||
|
wksStore.isKeyEntry("client-ecc"));
|
||||||
|
|
||||||
|
/* Verify RSA key and certificate */
|
||||||
|
assertNotNull("RSA private key should exist",
|
||||||
|
wksStore.getKey("client", PASSWORD));
|
||||||
|
assertNotNull("RSA certificate chain should exist",
|
||||||
|
wksStore.getCertificateChain("client"));
|
||||||
|
assertEquals("RSA certificate chain should have length 1",
|
||||||
|
1, wksStore.getCertificateChain("client").length);
|
||||||
|
|
||||||
|
/* Verify ECC key and certificate */
|
||||||
|
assertNotNull("ECC private key should exist",
|
||||||
|
wksStore.getKey("client-ecc", PASSWORD));
|
||||||
|
assertNotNull("ECC certificate chain should exist",
|
||||||
|
wksStore.getCertificateChain("client-ecc"));
|
||||||
|
assertEquals("ECC certificate chain should have length 1",
|
||||||
|
1, wksStore.getCertificateChain("client-ecc").length);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
/* Restore original property value */
|
||||||
|
if (origValue != null) {
|
||||||
|
Security.setProperty("wolfjce.mapPKCS12toWKS", origValue);
|
||||||
|
} else {
|
||||||
|
Security.setProperty("wolfjce.mapPKCS12toWKS", "false");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test converting PKCS12 to WKS with mapPKCS12toWKS=true
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testConvertP12ToWksWithMapping() throws Exception {
|
||||||
|
/* Store original property value */
|
||||||
|
String origValue = Security.getProperty("wolfjce.mapPKCS12toWKS");
|
||||||
|
|
||||||
|
try {
|
||||||
|
Security.setProperty("wolfjce.mapPKCS12toWKS", "true");
|
||||||
|
|
||||||
|
/* Load test PKCS12 KeyStore */
|
||||||
|
ByteArrayInputStream p12Stream = loadKeyStoreFile(TEST_P12_PATH);
|
||||||
|
|
||||||
|
/* Convert to WKS */
|
||||||
|
ByteArrayInputStream wksStream =
|
||||||
|
(ByteArrayInputStream)WolfCryptUtil.convertKeyStoreToWKS(
|
||||||
|
p12Stream, PASSWORD, PASSWORD, true);
|
||||||
|
|
||||||
|
/* Load the converted WKS KeyStore */
|
||||||
|
KeyStore wksStore = KeyStore.getInstance("WKS", "wolfJCE");
|
||||||
|
wksStore.load(wksStream, PASSWORD);
|
||||||
|
|
||||||
|
/* Verify both entries were properly converted */
|
||||||
|
assertTrue("RSA key entry should exist",
|
||||||
|
wksStore.isKeyEntry("client"));
|
||||||
|
assertTrue("ECC key entry should exist",
|
||||||
|
wksStore.isKeyEntry("client-ecc"));
|
||||||
|
|
||||||
|
/* Verify RSA key and certificate */
|
||||||
|
assertNotNull("RSA private key should exist",
|
||||||
|
wksStore.getKey("client", PASSWORD));
|
||||||
|
assertNotNull("RSA certificate chain should exist",
|
||||||
|
wksStore.getCertificateChain("client"));
|
||||||
|
assertEquals("RSA certificate chain should have length 1",
|
||||||
|
1, wksStore.getCertificateChain("client").length);
|
||||||
|
|
||||||
|
/* Verify ECC key and certificate */
|
||||||
|
assertNotNull("ECC private key should exist",
|
||||||
|
wksStore.getKey("client-ecc", PASSWORD));
|
||||||
|
assertNotNull("ECC certificate chain should exist",
|
||||||
|
wksStore.getCertificateChain("client-ecc"));
|
||||||
|
assertEquals("ECC certificate chain should have length 1",
|
||||||
|
1, wksStore.getCertificateChain("client-ecc").length);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
/* Restore original property value */
|
||||||
|
if (origValue != null) {
|
||||||
|
Security.setProperty("wolfjce.mapPKCS12toWKS", origValue);
|
||||||
|
} else {
|
||||||
|
Security.setProperty("wolfjce.mapPKCS12toWKS", "false");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test converting WKS to WKS (should return same InputStream)
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testConvertWksToWks() throws Exception {
|
||||||
|
/* Load test WKS KeyStore */
|
||||||
|
ByteArrayInputStream wksStream = loadKeyStoreFile(TEST_WKS_PATH);
|
||||||
|
|
||||||
|
/* Convert WKS to WKS */
|
||||||
|
ByteArrayInputStream wksStreamB =
|
||||||
|
(ByteArrayInputStream)WolfCryptUtil.convertKeyStoreToWKS(
|
||||||
|
wksStream, PASSWORD, PASSWORD, true);
|
||||||
|
|
||||||
|
/* Verify the KeyStore can still be loaded */
|
||||||
|
KeyStore wksStore = KeyStore.getInstance("WKS", "wolfJCE");
|
||||||
|
wksStore.load(wksStreamB, PASSWORD);
|
||||||
|
|
||||||
|
/* Verify the key and certificate were preserved */
|
||||||
|
assertTrue("Key entry should exist", wksStore.isKeyEntry(TEST_ALIAS));
|
||||||
|
assertNotNull("Private key should exist",
|
||||||
|
wksStore.getKey(TEST_ALIAS, PASSWORD));
|
||||||
|
assertNotNull("Certificate chain should exist",
|
||||||
|
wksStore.getCertificateChain(TEST_ALIAS));
|
||||||
|
assertEquals("Certificate chain should have length 2",
|
||||||
|
2, wksStore.getCertificateChain(TEST_ALIAS).length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test converting Java cacerts to WKS format
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testConvertCacertsToWks() throws Exception {
|
||||||
|
|
||||||
|
boolean failOnInsertErrors = true;
|
||||||
|
char[] password = CACERTS_PASSWORD;
|
||||||
|
|
||||||
|
/* Find cacerts file */
|
||||||
|
String cacertsPath = findCacertsFile();
|
||||||
|
if (cacertsPath == null) {
|
||||||
|
System.out.println(
|
||||||
|
"Skipping testConvertCacertsToWks: cacerts file not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If using FIPS mode, set failOnInsertErrors to false */
|
||||||
|
if (Fips.enabled) {
|
||||||
|
failOnInsertErrors = false;
|
||||||
|
password = (new String(CACERTS_PASSWORD) +
|
||||||
|
new String(CACERTS_PASSWORD)).toCharArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Load cacerts KeyStore */
|
||||||
|
ByteArrayInputStream cacertsStream = loadKeyStoreFile(cacertsPath);
|
||||||
|
|
||||||
|
/* Convert to WKS */
|
||||||
|
ByteArrayInputStream wksStream =
|
||||||
|
(ByteArrayInputStream)WolfCryptUtil.convertKeyStoreToWKS(
|
||||||
|
cacertsStream, CACERTS_PASSWORD, password, failOnInsertErrors);
|
||||||
|
|
||||||
|
/* Load the converted WKS KeyStore */
|
||||||
|
KeyStore wksStore = KeyStore.getInstance("WKS", "wolfJCE");
|
||||||
|
wksStore.load(wksStream, password);
|
||||||
|
|
||||||
|
/* Verify the KeyStore was converted and contains entries */
|
||||||
|
assertTrue("WKS KeyStore should contain entries",
|
||||||
|
wksStore.size() > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -43,7 +43,8 @@ import org.junit.runners.Suite.SuiteClasses;
|
||||||
WolfCryptKeyGeneratorTest.class,
|
WolfCryptKeyGeneratorTest.class,
|
||||||
WolfCryptKeyPairGeneratorTest.class,
|
WolfCryptKeyPairGeneratorTest.class,
|
||||||
WolfCryptPKIXCertPathValidatorTest.class,
|
WolfCryptPKIXCertPathValidatorTest.class,
|
||||||
WolfSSLKeyStoreTest.class
|
WolfSSLKeyStoreTest.class,
|
||||||
|
WolfCryptUtilTest.class
|
||||||
})
|
})
|
||||||
|
|
||||||
public class WolfJCETestSuite { }
|
public class WolfJCETestSuite { }
|
||||||
|
|
|
@ -1430,7 +1430,6 @@ public class WolfSSLKeyStoreTest {
|
||||||
assertEquals(1, store.size());
|
assertEquals(1, store.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
//CHRIS
|
|
||||||
@Test
|
@Test
|
||||||
public void testLoadWKSasJKSFromFile()
|
public void testLoadWKSasJKSFromFile()
|
||||||
throws KeyStoreException, IOException, FileNotFoundException,
|
throws KeyStoreException, IOException, FileNotFoundException,
|
||||||
|
|
Loading…
Reference in New Issue