Skip to content
Open
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
10 changes: 4 additions & 6 deletions jni/jni_wolfssl_x509_store_ctx.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,11 @@
#include <wolfcrypt_jni_debug.h>

/* Check if CertPathBuilder feature is available.
* CertPathBuilder requires wolfSSL >= 5.8.0 for proper X509_STORE chain
* building support. Older versions have issues with reference counting
* and chain building. */
* CertPathBuilder requires wolfSSL >= 5.9.2. Older versions have issues
* with reference counting and chain building. */
static int isCertPathBuilderAvailable(void)
{
#if defined(OPENSSL_EXTRA) && \
(LIBWOLFSSL_VERSION_HEX >= 0x05008000)
#if defined(OPENSSL_EXTRA) && (LIBWOLFSSL_VERSION_HEX >= 0x05009002)
return 1;
#else
return 0;
Expand Down Expand Up @@ -137,7 +135,7 @@ JNIEXPORT jlong JNICALL Java_com_wolfssl_wolfcrypt_WolfSSLX509StoreCtx_wolfSSL_1
(void)jcl;

if (!isCertPathBuilderAvailable()) {
LogStr("CertPathBuilder requires wolfSSL >= 5.8.0\n");
LogStr("CertPathBuilder requires wolfSSL >= 5.9.2\n");
return 0;
}

Expand Down
41 changes: 31 additions & 10 deletions src/main/java/com/wolfssl/provider/jce/WolfCryptCipher.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,18 @@ enum RsaKeyType {
private AlgorithmParameterSpec storedSpec = null;
private byte[] iv = null;

/* Default AEAD (AES-GCM/CCM) tag length in bytes (128 bits) */
private static final int AEAD_DEFAULT_TAG_LEN_SZ = 16;

/* AES-GCM/CCM tag length (bytes), default to 128 bits */
private int gcmTagLen = 16;
private int gcmTagLen = AEAD_DEFAULT_TAG_LEN_SZ;

/* Native AES-CCM nonce length bounds (bytes) */
private static final int CCM_NONCE_MIN_SZ = 7;
private static final int CCM_NONCE_MAX_SZ = 13;

/* Nonce length generated for parameterless AES-CCM init (bytes). */
private static final int CCM_NONCE_GEN_SZ = 12;

/* AAD data for AES-GCM/CCM, accumulated via engineUpdateAAD() */
private ByteArrayOutputStream aadStream = null;
Expand Down Expand Up @@ -716,8 +726,9 @@ protected int engineGetOutputSize(int inputLen)
switch (this.cipherType) {
case WC_AES:
if (paddingType == PaddingType.WC_NONE) {
if (cipherMode == CipherMode.WC_GCM) {
/* In AES-GCM mode we append the authentication tag
if (cipherMode == CipherMode.WC_GCM ||
cipherMode == CipherMode.WC_CCM) {
/* In AES-GCM or AES-CCM mode we append the auth tag
* to the end of ciphertext, When decrypting, output
* size will have it taken off. */
if (this.direction == OpMode.WC_ENCRYPT) {
Expand Down Expand Up @@ -939,7 +950,15 @@ private void wolfCryptSetIV(AlgorithmParameterSpec spec,

/* store IV, or generate random IV if not available */
if (spec == null) {
this.iv = new byte[this.blockSize];
/* No parameters given, reset AEAD tag length to the default so
* shorter tag length from a previous init() is not reused */
this.gcmTagLen = AEAD_DEFAULT_TAG_LEN_SZ;

if (cipherMode == CipherMode.WC_CCM) {
this.iv = new byte[CCM_NONCE_GEN_SZ];
} else {
this.iv = new byte[this.blockSize];
}

if (random != null) {
random.nextBytes(this.iv);
Expand Down Expand Up @@ -990,10 +1009,11 @@ else if (cipherMode == CipherMode.WC_CCM) {
"AES-CCM nonce is null or 0 length");
}

/* CCM nonce length validation (7-15 bytes typical) */
if (ccmSpec.getIV().length < 7 || ccmSpec.getIV().length > 15) {
if (ccmSpec.getIV().length < CCM_NONCE_MIN_SZ ||
ccmSpec.getIV().length > CCM_NONCE_MAX_SZ) {
throw new InvalidAlgorithmParameterException(
"CCM nonce length must be 7-15 bytes, got: " +
"CCM nonce length must be " + CCM_NONCE_MIN_SZ + "-" +
CCM_NONCE_MAX_SZ + " bytes, got: " +
ccmSpec.getIV().length);
}

Expand Down Expand Up @@ -1908,9 +1928,10 @@ else if (cipherMode == CipherMode.WC_OFB) {
/* Create appropriate ParameterSpec with the current IV to avoid
* generating a new random IV during reset */
AlgorithmParameterSpec currentIvSpec;
if (cipherMode == CipherMode.WC_GCM) {
/* For GCM mode, create GCMParameterSpec with current
* IV and tag length */
if (cipherMode == CipherMode.WC_GCM ||
cipherMode == CipherMode.WC_CCM) {
/* AES-GCM and AES-CCM both expect a GCMParameterSpec
* carrying the current IV and tag length */
currentIvSpec = new GCMParameterSpec(
this.gcmTagLen * 8, this.iv.clone());
} else {
Expand Down
63 changes: 57 additions & 6 deletions src/main/java/com/wolfssl/provider/jce/WolfCryptDhParameters.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,22 @@ protected void engineInit(byte[] params) throws IOException {

int idx = 0;
int seqLen = 0;
int seqEnd = 0;
int pLen = 0;
int gLen = 0;
int lLen = 0;
byte[] pBytes = null;
byte[] gBytes = null;
byte[] lBytes = null;
BigInteger lValue = null;

/* Parse DER-encoded DH parameters. Doing basic DER parsing here
* since wolfCrypt does not have DER parsing support for this
* encoded parameters format.
* encoded parameters format. The SEQUENCE must span the entire
* input, any trailing data is rejected.
*
* Format: SEQUENCE { prime INTEGER, generator INTEGER } */
* Format: SEQUENCE { prime INTEGER, generator INTEGER,
* privateValueLength INTEGER OPTIONAL } */
try {
/* Check SEQUENCE tag */
if (params[idx++] != 0x30) {
Expand All @@ -90,7 +96,13 @@ protected void engineInit(byte[] params) throws IOException {
throw new IOException(
"Invalid DH parameters: bad SEQUENCE length: " + seqLen);
}
int seqEnd = idx + seqLen;
seqEnd = idx + seqLen;

/* SEQUENCE must span the entire input, reject any trailing data */
if (seqEnd != params.length) {
throw new IOException(
"Invalid DH parameters: trailing data after SEQUENCE");
}

/* Decode prime (p) INTEGER */
if (idx >= seqEnd || params[idx++] != 0x02) {
Expand Down Expand Up @@ -124,8 +136,40 @@ protected void engineInit(byte[] params) throws IOException {
idx += gLen;
this.g = new BigInteger(1, gBytes);

/* Private value length not encoded in standard DH params */
this.l = 0;
/* Decode optional private-value length (l) INTEGER, if present. */
if (idx < seqEnd) {
if (params[idx++] != 0x02) {
throw new IOException(
"Invalid DH parameters: expected INTEGER tag for l");
}
lLen = WolfCryptASN1Util.getDERLength(params, idx);
idx += WolfCryptASN1Util.getDERLengthSize(params, idx);
if (lLen <= 0 || lLen > (seqEnd - idx)) {
throw new IOException(
"Invalid DH parameters: bad length for l: " + lLen);
}
lBytes = new byte[lLen];
System.arraycopy(params, idx, lBytes, 0, lLen);
idx += lLen;
lValue = new BigInteger(1, lBytes);
this.l = lValue.intValue();
/* Reject a value that does not fit in a Java int */
if (!BigInteger.valueOf(this.l).equals(lValue)) {
throw new IOException(
"Invalid DH parameters: private value length too big");
}
}
else {
/* Private value length is optional and absent */
this.l = 0;
}

/* Reject any trailing data inside the SEQUENCE */
if (idx != seqEnd) {
throw new IOException(
"Invalid DH parameters: unexpected trailing data " +
"in SEQUENCE");
}

} catch (ArrayIndexOutOfBoundsException | IllegalArgumentException e) {
throw new IOException("Invalid DH parameters encoding: " +
Expand Down Expand Up @@ -194,7 +238,8 @@ protected byte[] engineGetEncoded(String format) throws IOException {
byte[] pBytes = this.p.toByteArray();
byte[] gBytes = this.g.toByteArray();

/* Encode as ASN.1 SEQUENCE { prime, generator } */
/* Encode as ASN.1 SEQUENCE { prime, generator,
* privateValueLength OPTIONAL } */
ByteArrayOutputStream seq = new ByteArrayOutputStream();

/* Encode p as INTEGER */
Expand All @@ -207,6 +252,12 @@ protected byte[] engineGetEncoded(String format) throws IOException {
seq.write(WolfCryptASN1Util.encodeDERLength(gBytes.length));
seq.write(gBytes);

/* Encode optional private-value length (l) as the third INTEGER */
if (this.l > 0) {
seq.write(WolfCryptASN1Util.encodeDERInteger(
BigInteger.valueOf(this.l)));
}

byte[] seqBytes = seq.toByteArray();

/* Wrap in SEQUENCE */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,7 @@ private void registerServices() {
put("CertPathValidator.PKIX",
"com.wolfssl.provider.jce.WolfCryptPKIXCertPathValidator");

/* CertPathBuilder requires wolfSSL 5.8.0 or later */
/* CertPathBuilder requires wolfSSL 5.9.2 or later */
if (WolfSSLX509StoreCtx.isSupported()) {
put("CertPathBuilder.PKIX",
"com.wolfssl.provider.jce.WolfCryptPKIXCertPathBuilder");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -655,9 +655,12 @@ private SecretKey translatePBEKey(PBEKey key)

if (key != null) {

if (!isAlgorithmSupported(key.getAlgorithm())) {
throw new InvalidKeyException(
"SecretKey algorithm not supported: " + key.getAlgorithm());
/* Require the source key algorithm to match this factory. */
String keyAlgo = key.getAlgorithm();
if (keyAlgo == null || !keyAlgo.equalsIgnoreCase(this.typeString)) {
throw new InvalidKeyException("PBEKey algorithm " + keyAlgo +
" does not match this SecretKeyFactory algorithm " +
this.typeString);
}

try {
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/com/wolfssl/wolfcrypt/WolfSSLX509StoreCtx.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ private static native byte[][] wolfSSL_X509_verify_cert_and_get_chain(
/**
* Check if CertPathBuilder functionality is supported.
*
* CertPathBuilder requires wolfSSL version 5.8.0 or later for proper
* X509_STORE chain building support.
* CertPathBuilder requires wolfSSL version 5.9.2 or later. Earlier
* versions have X509_STORE chain building issues.
*
* @return true if CertPathBuilder is supported, false otherwise
*/
Expand Down Expand Up @@ -119,19 +119,19 @@ public static boolean isStoreCheckTimeSupported() {
/**
* Create new WolfSSLX509StoreCtx object.
*
* Requires wolfSSL version 5.8.0 or later for proper X509_STORE
* Requires wolfSSL version 5.9.2 or later for proper X509_STORE
* chain building support.
*
* @throws WolfCryptException if unable to create native X509_STORE,
* or if wolfSSL version is too old (requires 5.8.0+)
* or if wolfSSL version is too old (requires 5.9.2+)
*/
public WolfSSLX509StoreCtx() throws WolfCryptException {

storePtr = wolfSSL_X509_STORE_new();
if (storePtr == 0) {
throw new WolfCryptException(
"Failed to create native WOLFSSL_X509_STORE. " +
"CertPathBuilder requires wolfSSL 5.8.0 or later.");
"CertPathBuilder requires wolfSSL 5.9.2 or later.");
}
this.active = true;
}
Expand Down
Loading
Loading