Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions IDE/Android/app/src/main/cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ list(REMOVE_ITEM TLS_SOURCES ${wolfssl_DIR}/src/ssl_misc.c)
list(REMOVE_ITEM TLS_SOURCES ${wolfssl_DIR}/src/ssl_p7p12.c)
list(REMOVE_ITEM TLS_SOURCES ${wolfssl_DIR}/src/ssl_sess.c)
list(REMOVE_ITEM TLS_SOURCES ${wolfssl_DIR}/src/ssl_sk.c)
list(REMOVE_ITEM TLS_SOURCES ${wolfssl_DIR}/src/ssl_tsp.c)
list(REMOVE_ITEM TLS_SOURCES ${wolfssl_DIR}/src/x509.c)
list(REMOVE_ITEM TLS_SOURCES ${wolfssl_DIR}/src/x509_str.c)

Expand All @@ -282,6 +283,7 @@ if ("${WOLFSSL_PKG_TYPE}" MATCHES "normal")
list(REMOVE_ITEM CRYPTO_SOURCES ${wolfssl_DIR}/wolfcrypt/src/evp_pk.c)
list(REMOVE_ITEM CRYPTO_SOURCES ${wolfssl_DIR}/wolfcrypt/src/misc.c)
list(REMOVE_ITEM CRYPTO_SOURCES ${wolfssl_DIR}/wolfcrypt/src/asn_orig.c)
list(REMOVE_ITEM CRYPTO_SOURCES ${wolfssl_DIR}/wolfcrypt/src/asn_tsp.c)

elseif("${WOLFSSL_PKG_TYPE}" MATCHES "fipsready")
# FIPS Ready needs to explicitly order files for in-core integrity check to work properly.
Expand Down
1 change: 1 addition & 0 deletions README_JCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ 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.wks.maxEntrySize | 10485760 | Integer | Max encoded entry size in bytes when loading WKS (10 MB default) |
| wolfjce.keystore.kekCacheEnabled | false | true | Enable KEK caching in WKS KeyStore for performance |
| wolfjce.keystore.kekCacheTtlSec | 300 | Integer | KEK cache TTL in seconds (1 second minimum) |
| wolfjce.mapJKStoWKS | UNSET | true | Register fake JKS KeyStore service mapped to WKS |
Expand Down
1 change: 1 addition & 0 deletions docs/design/WolfSSLKeyStore.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ please reference the appropriate Security Policy or contact fips@wolfssl.com.
| --- | --- | --- | --- |
| `wolfjce.wks.iterationCount` | 210,000 | 10,000 | PBKDF2 iteration count |
| `wolfjce.wks.maxCertChainLength` | 100 | N/A | Max cert chain length |
| `wolfjce.wks.maxEntrySize` | 10485760 | N/A | Max encoded entry size in bytes |
| `wolfjce.keystore.kekCacheEnabled` | false | N/A | Enable KEK caching |
| `wolfjce.keystore.kekCacheTtlSec` | 300 | 1 | Cache TTL in seconds |

Expand Down
2 changes: 2 additions & 0 deletions jni/include/com_wolfssl_provider_jce_WolfSSLKeyStore.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -1072,7 +1072,7 @@ public CertPathValidatorResult engineValidate(

/* If we are in FIPS mode, verify wolfJCE is the Signature provider
* to help maintain FIPS compliance */
if (Fips.enabled && pkixParams.getSigProvider() != "wolfJCE") {
if (Fips.enabled && !"wolfJCE".equals(pkixParams.getSigProvider())) {
if (pkixParams.getSigProvider() == null) {
/* Preferred Signature provider not set, set to wolfJCE */
pkixParams.setSigProvider("wolfJCE");
Expand Down
80 changes: 73 additions & 7 deletions src/main/java/com/wolfssl/provider/jce/WolfSSLKeyStore.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.Date;
import java.util.Enumeration;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.io.InputStream;
import java.io.OutputStream;
Expand Down Expand Up @@ -224,6 +225,11 @@ public class WolfSSLKeyStore extends KeyStoreSpi {
private static final int WKS_DEFAULT_MAX_CHAIN_COUNT = 100;
private static final int WKS_MAX_CHAIN_COUNT;

/* Max encoded entry size in bytes, configurable via
* 'wolfjce.wks.maxEntrySize' Security property */
private static final int WKS_DEFAULT_MAX_ENTRY_SIZE = 10 * 1024 * 1024;
private static final int WKS_MAX_ENTRY_SIZE;

/* WKS magic number, used when storing KeyStore to OutputStream */
private static final int WKS_MAGIC_NUMBER = 7;

Expand Down Expand Up @@ -341,8 +347,10 @@ void wipe() {
static {
int iCount = WKS_PBKDF2_DEFAULT_ITERATIONS;
int cLength = WKS_DEFAULT_MAX_CHAIN_COUNT;
int eLength = WKS_DEFAULT_MAX_ENTRY_SIZE;
String iterations = null;
String chainCount = null;
String entrySize = null;

/* Set PBKDF2 iteration count, using default or one set by
* user in 'wolfjce.wks.iterationCount' Security property in
Expand Down Expand Up @@ -389,6 +397,27 @@ void wipe() {

log("setting max cert chain length: " + cLength);
WKS_MAX_CHAIN_COUNT = cLength;

/* Set max encoded entry size limit, using default or one set with
* `wolfjce.wks.maxEntrySize` Security property */
entrySize = Security.getProperty("wolfjce.wks.maxEntrySize");
if (entrySize != null && !entrySize.isEmpty()) {
try {
eLength = Integer.parseInt(entrySize);
if (eLength <= 0) {
log("wolfjce.wks.maxEntrySize (" + eLength +
") lower than 0, using default");
eLength = WKS_DEFAULT_MAX_ENTRY_SIZE;
}
} catch (NumberFormatException e) {
/* Error parsing property, fall back to default */
log("error parsing wolfjce.wks.maxEntrySize property, " +
"using default instead");
}
}

log("setting max entry size: " + eLength);
WKS_MAX_ENTRY_SIZE = eLength;
}

/**
Expand Down Expand Up @@ -2320,6 +2349,12 @@ public synchronized void engineLoad(InputStream stream, char[] password)
WKSSecretKey sKeyEntry = null;
WKSCertificate certEntry = null;

/* Parse entries into a local map first. They are only committed
* into the shared this.entries map after the HMAC integrity check
* passes, so a failed or tampered load never exposes unverified
* entries to engineGetKey()/engineGetCertificate() callers. */
Map<String, Object> loadedEntries = new LinkedHashMap<String, Object>();

log("loading KeyStore from InputStream");

/* Clear any cached KEK entries from previous keystore */
Expand Down Expand Up @@ -2381,8 +2416,15 @@ public synchronized void engineLoad(InputStream stream, char[] password)

/* encoded entry length */
encodedLen = dis.readInt();
if (encodedLen < 0) {
throw new IOException("Invalid encoded length, negative");
if (encodedLen <= 0) {
throw new IOException("Invalid encoded entry length: " +
encodedLen);
}

if (encodedLen > WKS_MAX_ENTRY_SIZE) {
throw new IOException("Encoded entry length (" +
encodedLen + ") is larger than max allowed: " +
WKS_MAX_ENTRY_SIZE);
}

/* encoded entry */
Expand All @@ -2397,19 +2439,19 @@ public synchronized void engineLoad(InputStream stream, char[] password)
case WKS_ENTRY_ID_PRIVATE_KEY:
log("loading PrivateKey: " + alias);
keyEntry = new WKSPrivateKey(encodedEntry);
entries.put(alias, keyEntry);
loadedEntries.put(alias, keyEntry);
break;

case WKS_ENTRY_ID_SECRET_KEY:
log("loading SecretKey: " + alias);
sKeyEntry = new WKSSecretKey(encodedEntry);
entries.put(alias, sKeyEntry);
loadedEntries.put(alias, sKeyEntry);
break;

case WKS_ENTRY_ID_CERTIFICATE:
log("loading Certificate: " + alias);
certEntry = new WKSCertificate(encodedEntry);
entries.put(alias, certEntry);
loadedEntries.put(alias, certEntry);
break;

default:
Expand Down Expand Up @@ -2444,8 +2486,10 @@ public synchronized void engineLoad(InputStream stream, char[] password)

/* HMAC len and HMAC */
hmacLen = dis.readInt();
if (hmacLen < 0) {
throw new IOException("Invalid HMAC length, negative");
if (hmacLen != WKS_HMAC_KEY_LENGTH) {
throw new IOException(
"HMAC length (" + hmacLen + ") is different than " +
"expected (" + WKS_HMAC_KEY_LENGTH + ")");
}
hmac = new byte[hmacLen];
hmacLen = dis.read(hmac);
Expand Down Expand Up @@ -2474,6 +2518,11 @@ public synchronized void engineLoad(InputStream stream, char[] password)
"no password provided");
}

/* Commit parsed entries into the shared map, replacing any
* previous contents */
this.entries.clear();
this.entries.putAll(loadedEntries);

} finally {
if (dis != null) {
dis.close();
Expand Down Expand Up @@ -2773,6 +2822,10 @@ protected WKSPrivateKey(byte[] encoded)
throw new IOException(
"Bad encrypted key length, negative");
}
if (tmp > WKS_MAX_ENTRY_SIZE) {
throw new IOException("Encrypted key length (" + tmp +
") is larger than max allowed: " + WKS_MAX_ENTRY_SIZE);
}
this.encryptedKey = new byte[tmp];
dis.readFully(this.encryptedKey);

Expand Down Expand Up @@ -2800,6 +2853,11 @@ protected WKSPrivateKey(byte[] encoded)
throw new IOException(
"Bad encoding length, negative");
}
if (tmp > WKS_MAX_ENTRY_SIZE) {
throw new IOException("Cert encoding length (" + tmp +
") is larger than max allowed: " +
WKS_MAX_ENTRY_SIZE);
}
tmpArr = new byte[tmp];

/* encoded cert */
Expand Down Expand Up @@ -3116,6 +3174,10 @@ protected WKSCertificate(byte[] encoded)
if (tmp < 0) {
throw new IOException("Bad encoding length, negative");
}
if (tmp > WKS_MAX_ENTRY_SIZE) {
throw new IOException("Cert encoding length (" + tmp +
") is larger than max allowed: " + WKS_MAX_ENTRY_SIZE);
}
tmpArr = new byte[tmp];

/* encoded cert */
Expand Down Expand Up @@ -3391,6 +3453,10 @@ protected WKSSecretKey(byte[] encoded)
throw new IOException(
"Bad encrypted key length, negative");
}
if (tmp > WKS_MAX_ENTRY_SIZE) {
throw new IOException("Encrypted key length (" + tmp +
") is larger than max allowed: " + WKS_MAX_ENTRY_SIZE);
}
this.encryptedKey = new byte[tmp];
dis.readFully(this.encryptedKey);

Expand Down
Loading
Loading