Merge pull request #258 from cconlon/fenrirAug14
Fixes for error mapping, DH init, OCSP reason code, and documentationpull/252/merge
commit
646b2b7419
|
|
@ -1845,6 +1845,10 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPSS_1CheckPadding(
|
|||
}
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
throwWolfCryptExceptionFromError(env, ret);
|
||||
}
|
||||
|
||||
if (ret == 0) {
|
||||
XMEMSET(pssData, 0, pssDataSz);
|
||||
|
||||
|
|
@ -1858,6 +1862,11 @@ Java_com_wolfssl_wolfcrypt_Rsa_wc_1RsaPSS_1CheckPadding(
|
|||
ret = wc_RsaPSS_CheckPadding_ex(digest, digestSz, pssData,
|
||||
pssDataSz, (enum wc_HashType)hashType, saltLen, 0);
|
||||
}
|
||||
|
||||
/* Throw OutOfMemoryError on memory error, other codes map to false */
|
||||
if (ret == MEMORY_E) {
|
||||
throwWolfCryptExceptionFromError(env, ret);
|
||||
}
|
||||
}
|
||||
if (ret == 0) {
|
||||
result = JNI_TRUE;
|
||||
|
|
|
|||
|
|
@ -44,9 +44,9 @@ JNIEXPORT jint JNICALL Java_com_wolfssl_wolfcrypt_WolfObject_init
|
|||
* com.wolfssl.wolfcrypt.Fips.runAllCast_fips() method. runAllCast_fips()
|
||||
* includes a synchronized check that only runs the CASTs once as long
|
||||
* as they were successful. Fips.runAllCast_fips() is called at both
|
||||
* the JNI-only level (WolfObject.init()), and the JCE level
|
||||
* (WolfCryptProvider constructor). Both of these runAllCast_fips()
|
||||
* at JNI/JCE levels are called before this wolfCrypt_Init() below. */
|
||||
* the JNI-only level (WolfObject static initializer), and the JCE level
|
||||
* (WolfCryptProvider constructor). Both of these calls happen after
|
||||
* this wolfCrypt_Init() below has returned. */
|
||||
|
||||
return (jint)wolfCrypt_Init();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -470,37 +470,35 @@ public class WolfCryptKeyAgreement extends KeyAgreementSpi {
|
|||
"AlgorithmParameterSpec is not of type DHParameterSpec");
|
||||
}
|
||||
|
||||
/* reject spec that conflicts with the key's own parameters */
|
||||
if (dhKey.getParams() != null &&
|
||||
(!dhKey.getParams().getP().equals(
|
||||
((DHParameterSpec)params).getP()) ||
|
||||
!dhKey.getParams().getG().equals(
|
||||
((DHParameterSpec)params).getG()))) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"DHParameterSpec does not match key parameters");
|
||||
}
|
||||
|
||||
paramP = ((DHParameterSpec)params).getP().toByteArray();
|
||||
paramG = ((DHParameterSpec)params).getG().toByteArray();
|
||||
|
||||
if (paramP != null && paramG != null) {
|
||||
|
||||
this.dh.setParams(paramP, paramG);
|
||||
|
||||
primeLen = paramP.length;
|
||||
|
||||
/* prime may have leading zero */
|
||||
if (paramP[0] == 0x00) {
|
||||
primeLen--;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
} else {
|
||||
if (paramP == null || paramG == null) {
|
||||
throw new InvalidParameterException(
|
||||
"AlgorithmParameterSpec does not include required " +
|
||||
"DH parameters (P,G)");
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* try to import params from key */
|
||||
paramP = dhKey.getParams().getP().toByteArray();
|
||||
paramG = dhKey.getParams().getG().toByteArray();
|
||||
|
||||
/* try to import params from key */
|
||||
paramP = dhKey.getParams().getP().toByteArray();
|
||||
paramG = dhKey.getParams().getG().toByteArray();
|
||||
|
||||
if (paramP == null || paramG == null) {
|
||||
throw new InvalidKeyException(
|
||||
"Key must include DH parameters when not called " +
|
||||
"with explicit AlgorithmParameterSpec");
|
||||
if (paramP == null || paramG == null) {
|
||||
throw new InvalidKeyException(
|
||||
"Key must include DH parameters when not called " +
|
||||
"with explicit AlgorithmParameterSpec");
|
||||
}
|
||||
}
|
||||
|
||||
this.dh.setParams(paramP, paramG);
|
||||
|
|
|
|||
|
|
@ -76,11 +76,10 @@ import com.wolfssl.wolfcrypt.WolfCryptException;
|
|||
* 1. Certificate policies, and the related setters/getters. As such,
|
||||
* validation will not return PolicyNode in CertPathBuilderResult
|
||||
*
|
||||
* Revocation checking is supported via:
|
||||
* - CRL: If PKIXParameters.isRevocationEnabled() is true and appropriate
|
||||
* CRLs have been loaded into CertStore Set
|
||||
* - OCSP: via getRevocationChecker() which returns a
|
||||
* WolfCryptPKIXRevocationChecker supporting OCSP and options
|
||||
* 2. CRL and OCSP revocation checking during path building, configured
|
||||
* CertPathCheckers are not executed by engineBuild(). To check
|
||||
* revocation, validate the returned CertPath with CertPathValidator
|
||||
* and PKIXParameters configured for revocation.
|
||||
*/
|
||||
public class WolfCryptPKIXCertPathBuilder extends CertPathBuilderSpi {
|
||||
|
||||
|
|
@ -1205,14 +1204,13 @@ public class WolfCryptPKIXCertPathBuilder extends CertPathBuilderSpi {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a CertPathChecker that this implementation uses to check
|
||||
* the revocation status of certificates.
|
||||
* Returns a WolfCryptPKIXRevocationChecker supporting OCSP and CRL
|
||||
* checking.
|
||||
*
|
||||
* This implementation returns a WolfCryptPKIXRevocationChecker that
|
||||
* supports both OCSP and CRL checking.
|
||||
* Path building does not execute this checker. To check revocation, add
|
||||
* it to PKIXParameters and validate the built path with CertPathValidator.
|
||||
*
|
||||
* @return a CertPathChecker object that this implementation uses to
|
||||
* check the revocation status of certificates.
|
||||
* @return a WolfCryptPKIXRevocationChecker for use with CertPathValidator
|
||||
*/
|
||||
@Override
|
||||
public CertPathChecker engineGetRevocationChecker() {
|
||||
|
|
|
|||
|
|
@ -1020,11 +1020,13 @@ public class WolfCryptPKIXCertPathValidator extends CertPathValidatorSpi {
|
|||
* a. CertPath.getType() is "X.509"
|
||||
* b. CertPath.getEncoding() contains "PkiPath"
|
||||
* 3. If wolfCrypt FIPS, verify params.getSigProvider() is wolfJCE
|
||||
* 4. Sanitize Certificate objects in CertPath chain
|
||||
* 4. Load TrustAnchors into WolfSSLCertManager, done before checker
|
||||
* initialization since OCSP needs anchors to verify responses
|
||||
* 5. Initialize any registered CertPathCheckers
|
||||
* 6. Sanitize Certificate objects in CertPath chain
|
||||
* a. Check target certificate constraints meet target cert
|
||||
* b. Check cert policies are not used (not supported)
|
||||
* 5. Call any registered CertPathCheckers
|
||||
* 6. Load TrustAnchors into WolfSSLCertManager
|
||||
* c. Call registered CertPathCheckers on each certificate
|
||||
* 7. Enable CRL if requested, load CRLs from getCertStores()
|
||||
* 8. Verify X.509 certificate chain
|
||||
* 9. Find top-most TrustAnchor for return object
|
||||
|
|
|
|||
|
|
@ -330,16 +330,7 @@ public class WolfCryptPKIXRevocationChecker extends PKIXRevocationChecker {
|
|||
"Failed to encode certificate", e);
|
||||
|
||||
} catch (WolfCryptException e) {
|
||||
/* A definitive OCSP "revoked" status must always be a hard fail,
|
||||
* with BasicReason.REVOKED. Other codes SOFT_FAIL may suppress. */
|
||||
if (e.getCode() == WolfCryptError.OCSP_CERT_REVOKED.getCode()) {
|
||||
throw new CertPathValidatorException(
|
||||
"Certificate revoked (OCSP): " + e.getMessage(), e,
|
||||
null, -1, BasicReason.REVOKED);
|
||||
}
|
||||
throw new CertPathValidatorException(
|
||||
"OCSP check failed: " + e.getMessage(), e,
|
||||
null, -1, BasicReason.UNDETERMINED_REVOCATION_STATUS);
|
||||
throw mapOcspException("OCSP check failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -503,12 +494,34 @@ public class WolfCryptPKIXRevocationChecker extends PKIXRevocationChecker {
|
|||
"Failed to encode certificate", e);
|
||||
|
||||
} catch (WolfCryptException e) {
|
||||
throw new CertPathValidatorException(
|
||||
"OCSP response check failed: " + e.getMessage(), e,
|
||||
null, -1, BasicReason.UNDETERMINED_REVOCATION_STATUS);
|
||||
throw mapOcspException("OCSP response check failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a native OCSP exception to CertPathValidatorException. An OCSP
|
||||
* "revoked" status must always be a hard fail with BasicReason.REVOKED.
|
||||
* Other codes map to UNDETERMINED_REVOCATION_STATUS, which SOFT_FAIL may
|
||||
* suppress.
|
||||
*
|
||||
* @param msgPrefix message prefix for non-revoked failures
|
||||
* @param e native exception from OCSP check
|
||||
*
|
||||
* @return CertPathValidatorException for caller to throw
|
||||
*/
|
||||
private CertPathValidatorException mapOcspException(String msgPrefix,
|
||||
WolfCryptException e) {
|
||||
|
||||
if (e.getCode() == WolfCryptError.OCSP_CERT_REVOKED.getCode()) {
|
||||
return new CertPathValidatorException(
|
||||
"Certificate revoked (OCSP): " + e.getMessage(), e,
|
||||
null, -1, BasicReason.REVOKED);
|
||||
}
|
||||
return new CertPathValidatorException(
|
||||
msgPrefix + ": " + e.getMessage(), e,
|
||||
null, -1, BasicReason.UNDETERMINED_REVOCATION_STATUS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle exception based on SOFT_FAIL option.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1249,7 +1249,6 @@ public class WolfCryptSignature extends SignatureSpi {
|
|||
/* Validate spec type and MGF1 inner digest */
|
||||
AlgorithmParameterSpec mgfParams = pss.getMGFParameters();
|
||||
if (mgfParams != null) {
|
||||
/* Different spec type silently falls back to the default digest */
|
||||
if (!(mgfParams instanceof MGF1ParameterSpec)) {
|
||||
throw new InvalidAlgorithmParameterException(
|
||||
"MGF1 parameters must be of type MGF1ParameterSpec, got " +
|
||||
|
|
|
|||
|
|
@ -2544,8 +2544,8 @@ public class WolfSSLKeyStore extends KeyStoreSpi {
|
|||
* Load the KeyStore from the provided InputStream.
|
||||
*
|
||||
* @param stream InputStream from which to load KeyStore
|
||||
* @param password password used to check KeyStore integrity, must not
|
||||
* be null
|
||||
* @param password password used to check KeyStore integrity, may be
|
||||
* null or empty to skip the whole KeyStore HMAC integrity check
|
||||
*
|
||||
* @throws IOException on I/O problem or issue with the
|
||||
* KeyStore data format
|
||||
|
|
|
|||
|
|
@ -217,10 +217,10 @@ public class AesCcm extends NativeStruct {
|
|||
* @param authIn additional data to be authenticated but not encrypted,
|
||||
* can be null if no additional data desired or available.
|
||||
*
|
||||
* @return encrypted cipertext buffer
|
||||
* @return encrypted ciphertext buffer
|
||||
*
|
||||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if key has already been set, if object
|
||||
* @throws IllegalStateException if key has not been set, if object
|
||||
* fails to initialize, or if releaseNativeStruct() has been
|
||||
* called and object has been released.
|
||||
*/
|
||||
|
|
@ -251,7 +251,7 @@ public class AesCcm extends NativeStruct {
|
|||
* @return decrypted plaintext buffer
|
||||
*
|
||||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if key has already been set, if object
|
||||
* @throws IllegalStateException if key has not been set, if object
|
||||
* fails to initialize, or if releaseNativeStruct() has been
|
||||
* called and object has been released.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -336,13 +336,21 @@ public class AesCmac extends NativeStruct {
|
|||
*
|
||||
* @return true if verification succeeds, false otherwise
|
||||
*
|
||||
* @throws WolfCryptException if native operation fails
|
||||
* @throws WolfCryptException if the native operation fails for any
|
||||
* reason other than MAC comparison mismatch
|
||||
*/
|
||||
public static synchronized boolean verify(byte[] mac, byte[] data,
|
||||
byte[] key) throws WolfCryptException {
|
||||
|
||||
int ret = wc_AesCmacVerify(mac, mac.length, data, data.length,
|
||||
key, key.length);
|
||||
key, key.length);
|
||||
|
||||
/* Native returns MAC_CMP_FAILED_E for a MAC mismatch, wolfSSL
|
||||
* versions before 5.9.2 return 1 */
|
||||
if ((ret != 0) && (ret != 1) &&
|
||||
(ret != WolfCryptError.MAC_CMP_FAILED_E.getCode())) {
|
||||
throw new WolfCryptException(ret);
|
||||
}
|
||||
|
||||
return (ret == 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -218,10 +218,10 @@ public class AesGcm extends NativeStruct {
|
|||
* @param authIn additional data to be authenticated but not encrypted,
|
||||
* can be null if no additional data desired or available.
|
||||
*
|
||||
* @return encrypted cipertext buffer
|
||||
* @return encrypted ciphertext buffer
|
||||
*
|
||||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if key has already been set, if object
|
||||
* @throws IllegalStateException if key has not been set, if object
|
||||
* fails to initialize, or if releaseNativeStruct() has been
|
||||
* called and object has been released.
|
||||
*/
|
||||
|
|
@ -252,7 +252,7 @@ public class AesGcm extends NativeStruct {
|
|||
* @return decrypted plaintext buffer
|
||||
*
|
||||
* @throws WolfCryptException if native operation fails
|
||||
* @throws IllegalStateException if key has already been set, if object
|
||||
* @throws IllegalStateException if key has not been set, if object
|
||||
* fails to initialize, or if releaseNativeStruct() has been
|
||||
* called and object has been released.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -952,9 +952,12 @@ public class Rsa extends NativeStruct {
|
|||
* @param mgf mask generation function (WC_MGF1SHA256 for MGF1 with SHA-256)
|
||||
* @param saltLen salt length in bytes, or special value
|
||||
*
|
||||
* @return true if padding is valid, false otherwise
|
||||
* @return true if padding is valid, false otherwise, including for
|
||||
* hashType, mgf, or saltLen values rejected during decode
|
||||
*
|
||||
* @throws WolfCryptException if native operation fails
|
||||
* @throws WolfCryptException on invalid arguments detected before
|
||||
* signature decode
|
||||
* @throws OutOfMemoryError on memory allocation failure
|
||||
* @throws IllegalStateException if object fails to initialize, or if
|
||||
* releaseNativeStruct() has been called and object has been
|
||||
* released.
|
||||
|
|
|
|||
|
|
@ -405,6 +405,50 @@ public class WolfCryptKeyAgreementTest {
|
|||
assertArrayEquals(secretA, secretB);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDHKeyAgreementWithExplicitParams()
|
||||
throws NoSuchProviderException, NoSuchAlgorithmException,
|
||||
InvalidKeyException, InvalidAlgorithmParameterException {
|
||||
|
||||
/* skip test if DH is not compiled in native wolfSSL */
|
||||
if (!FeatureDetect.DhEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
byte[][] pg = Dh.getNamedDhParams(Dh.WC_FFDHE_2048);
|
||||
BigInteger p = new BigInteger(1, pg[0]);
|
||||
BigInteger g = new BigInteger(1, pg[1]);
|
||||
DHParameterSpec dhParams = new DHParameterSpec(p, g);
|
||||
|
||||
KeyPairGenerator keyGen =
|
||||
KeyPairGenerator.getInstance("DH", "wolfJCE");
|
||||
keyGen.initialize(dhParams);
|
||||
KeyPair aPair = keyGen.generateKeyPair();
|
||||
KeyPair bPair = keyGen.generateKeyPair();
|
||||
|
||||
/* init() with explicit DHParameterSpec must import private key */
|
||||
KeyAgreement aKeyAgree = KeyAgreement.getInstance("DH", "wolfJCE");
|
||||
KeyAgreement bKeyAgree = KeyAgreement.getInstance("DH", "wolfJCE");
|
||||
aKeyAgree.init(aPair.getPrivate(), dhParams);
|
||||
bKeyAgree.init(bPair.getPrivate(), dhParams);
|
||||
aKeyAgree.doPhase(bPair.getPublic(), true);
|
||||
bKeyAgree.doPhase(aPair.getPublic(), true);
|
||||
|
||||
byte secretA[] = aKeyAgree.generateSecret();
|
||||
byte secretB[] = bKeyAgree.generateSecret();
|
||||
assertTrue(secretA.length > 0);
|
||||
assertArrayEquals(secretA, secretB);
|
||||
|
||||
/* spec that conflicts with key params must be rejected */
|
||||
try {
|
||||
aKeyAgree.init(aPair.getPrivate(),
|
||||
new DHParameterSpec(p, g.add(BigInteger.ONE)));
|
||||
fail("init() should reject mismatched DHParameterSpec");
|
||||
} catch (InvalidAlgorithmParameterException e) {
|
||||
/* expected */
|
||||
}
|
||||
}
|
||||
|
||||
/* Minimal DHPublicKey holding a caller-chosen Y, for feeding malicious
|
||||
* peer public key values into engineDoPhase() during testing. */
|
||||
private static DHPublicKey makeDHPublicKey(final BigInteger y,
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ import com.wolfssl.wolfcrypt.WolfSSLCertManager;
|
|||
import com.wolfssl.wolfcrypt.WolfCryptException;
|
||||
import com.wolfssl.wolfcrypt.WolfCryptError;
|
||||
import com.wolfssl.wolfcrypt.test.TimedTestWatcher;
|
||||
import com.wolfssl.wolfcrypt.test.Util;
|
||||
import com.wolfssl.provider.jce.WolfCryptProvider;
|
||||
import com.wolfssl.provider.jce.WolfCryptPKIXRevocationChecker;
|
||||
|
||||
|
|
@ -873,6 +874,89 @@ public class WolfCryptPKIXRevocationCheckerTest {
|
|||
cm.free();
|
||||
}
|
||||
|
||||
/* DER encoded OCSP response for server-cert.der, status successful, signed
|
||||
* by ca-cert.pem, generated with openssl ocsp. Contains no nextUpdate so
|
||||
* it never expires. Only needs to pass native response status parsing,
|
||||
* response verification itself is mocked below. */
|
||||
private static final String OCSP_RESPONSE_HEX =
|
||||
"308202330a0100a082022c3082022806092b0601050507300101048202193082" +
|
||||
"02153081fea18197308194310b30090603550406130255533110300e06035504" +
|
||||
"080c074d6f6e74616e613110300e06035504070c07426f7a656d616e3111300f" +
|
||||
"060355040a0c08536177746f6f746831133011060355040b0c0a436f6e73756c" +
|
||||
"74696e673118301606035504030c0f7777772e776f6c6673736c2e636f6d311f" +
|
||||
"301d06092a864886f70d0109011610696e666f40776f6c6673736c2e636f6d18" +
|
||||
"0f32303236303831343232353035335a3051304f303a300906052b0e03021a05" +
|
||||
"000414ff66218a6ec5866184259abad65539fb25512cdd0414278e671174c326" +
|
||||
"1d3fed3363b3a4d81d30e5e8d50201018000180f323032363038313432323530" +
|
||||
"35335a300d06092a864886f70d01010b0500038201010076d97a9999d345fc6f" +
|
||||
"071b127d806865c588e0bea677757ec370396aea7020ef0db922251f8ba6bb45" +
|
||||
"8abd4aeb310d9ff024b733a483ed8c8b7cfd116e003b5db9ab5d69f640973c93" +
|
||||
"856562fef0d4eeef3115877c3867bcfbe5910b47fad0e5c9dfa1d487bc6048be" +
|
||||
"7a0900a7505d9a2a59210921c359a95ebc94f12d2b8def4489a26a39253be4a7" +
|
||||
"6084f4f42dfc46d800536ebbff8bc85111408e221b6d5e8462588994d4ca338b" +
|
||||
"62d22bf0496dc53677f91892a6036040216851124f3abdb781d6c96a0358b0ad" +
|
||||
"a97563122e9c1d8fd99d2cd38b78373f0ad4c841dc11727fdbeac44efd9a75da" +
|
||||
"060e70d1c02774b5de05d3bd9a9fced3c73d65d3cc750d";
|
||||
|
||||
/* CertManager that simulates a definitive OCSP "revoked" status for a
|
||||
* pre-loaded response by throwing WolfCryptException(OCSP_CERT_REVOKED)
|
||||
* from CertManagerCheckOCSPResponse, like native wolfSSL does for a
|
||||
* revoked certificate. */
|
||||
private static class RevokedOcspResponseCertManager
|
||||
extends WolfSSLCertManager {
|
||||
|
||||
@Override
|
||||
public synchronized void CertManagerCheckOCSPResponse(
|
||||
byte[] response, int responseSz, byte[] cert, int certSz) {
|
||||
throw new WolfCryptException(
|
||||
WolfCryptError.OCSP_CERT_REVOKED.getCode());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreloadedOcspRevokedUsesRevokedReason() throws Exception {
|
||||
|
||||
if (!WolfCrypt.OcspEnabled()) {
|
||||
/* Skip test if OCSP not compiled in */
|
||||
return;
|
||||
}
|
||||
|
||||
CertPathValidator cpv = CertPathValidator.getInstance("PKIX", provider);
|
||||
WolfCryptPKIXRevocationChecker checker =
|
||||
(WolfCryptPKIXRevocationChecker)cpv.getRevocationChecker();
|
||||
|
||||
FileInputStream fis = new FileInputStream(caCertDer);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
X509Certificate caCert = (X509Certificate)cf.generateCertificate(fis);
|
||||
fis.close();
|
||||
|
||||
fis = new FileInputStream(serverCertDer);
|
||||
X509Certificate serverCert =
|
||||
(X509Certificate)cf.generateCertificate(fis);
|
||||
fis.close();
|
||||
|
||||
/* Preload OCSP response so check() takes the stapled path */
|
||||
Map<X509Certificate, byte[]> responses =
|
||||
new HashMap<X509Certificate, byte[]>();
|
||||
responses.put(serverCert, Util.h2b(OCSP_RESPONSE_HEX));
|
||||
checker.setOcspResponses(responses);
|
||||
|
||||
WolfSSLCertManager cm = new RevokedOcspResponseCertManager();
|
||||
cm.CertManagerLoadCA(caCert);
|
||||
checker.setCertManager(cm);
|
||||
checker.init(false);
|
||||
|
||||
try {
|
||||
checker.check(serverCert, null);
|
||||
fail("A revoked pre-loaded OCSP status must fail validation");
|
||||
} catch (CertPathValidatorException e) {
|
||||
assertEquals("Revoked cert must fail with BasicReason.REVOKED",
|
||||
BasicReason.REVOKED, e.getReason());
|
||||
}
|
||||
|
||||
cm.free();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRevocationCheckerCheckWithCertChain() throws Exception {
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|||
import com.wolfssl.wolfcrypt.Aes;
|
||||
import com.wolfssl.wolfcrypt.Fips;
|
||||
import com.wolfssl.wolfcrypt.AesCmac;
|
||||
import com.wolfssl.wolfcrypt.FeatureDetect;
|
||||
import com.wolfssl.wolfcrypt.NativeStruct;
|
||||
import com.wolfssl.wolfcrypt.WolfCryptError;
|
||||
import com.wolfssl.wolfcrypt.WolfCryptException;
|
||||
|
|
@ -220,6 +221,33 @@ public class AesCmacTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aesCmacVerifyInvalidArgsShouldThrow() {
|
||||
if (!FeatureDetect.AesCmacEnabled()) {
|
||||
/* skip test if AES-CMAC is not compiled in native wolfCrypt */
|
||||
return;
|
||||
}
|
||||
|
||||
byte[] mac = new byte[16];
|
||||
byte[] data = new byte[16];
|
||||
|
||||
/* zero length key is an operational error, not a MAC mismatch */
|
||||
try {
|
||||
AesCmac.verify(mac, data, new byte[0]);
|
||||
fail("verify() should have thrown for zero length key");
|
||||
} catch (WolfCryptException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
/* invalid key length is an operational error, not a MAC mismatch */
|
||||
try {
|
||||
AesCmac.verify(mac, data, new byte[5]);
|
||||
fail("verify() should have thrown for invalid key length");
|
||||
} catch (WolfCryptException e) {
|
||||
/* expected */
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void aesCmacAlgorithmInfoShouldWork() {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1509,6 +1509,37 @@ public class RsaTest {
|
|||
WolfCrypt.WC_HASH_TYPE_SHA256, Rsa.WC_MGF1SHA256, 32);
|
||||
assertTrue("RSA-PSS check padding failed", verified);
|
||||
|
||||
/* Corrupted signatures must report false, not throw. PSS decode
|
||||
* of garbage fails with position dependent error codes, exercise
|
||||
* first, middle and last bytes */
|
||||
int[] flipPos = new int[] { 0, signature.length / 2,
|
||||
signature.length - 1 };
|
||||
for (int pos : flipPos) {
|
||||
byte[] badSig = signature.clone();
|
||||
badSig[pos] ^= (byte)0x80;
|
||||
verified = key.rsaPssCheckPadding(badSig, digest,
|
||||
WolfCrypt.WC_HASH_TYPE_SHA256, Rsa.WC_MGF1SHA256, 32);
|
||||
assertFalse("corrupted signature passed padding check, " +
|
||||
"flipped byte " + pos, verified);
|
||||
}
|
||||
|
||||
/* Mismatched digest must report false, not throw */
|
||||
byte[] wrongDigest = digest.clone();
|
||||
wrongDigest[0] ^= 1;
|
||||
verified = key.rsaPssCheckPadding(signature, wrongDigest,
|
||||
WolfCrypt.WC_HASH_TYPE_SHA256, Rsa.WC_MGF1SHA256, 32);
|
||||
assertFalse("padding check passed with wrong digest", verified);
|
||||
|
||||
/* Operational errors must throw, not report false */
|
||||
try {
|
||||
key.rsaPssCheckPadding(signature, new byte[0],
|
||||
WolfCrypt.WC_HASH_TYPE_SHA256, Rsa.WC_MGF1SHA256, 32);
|
||||
fail("rsaPssCheckPadding should have thrown for empty " +
|
||||
"digest");
|
||||
} catch (WolfCryptException e) {
|
||||
/* expected */
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
fail("RSA-PSS check padding test failed: " + e.getMessage());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue