testing cleanup, removed unused classes/interfaces

This commit is contained in:
Les Hazlewood 2021-10-12 11:13:21 -07:00
parent 36b450258b
commit e6db3da6b0
38 changed files with 187 additions and 234 deletions

View File

@ -15,7 +15,7 @@
*/
package io.jsonwebtoken;
import io.jsonwebtoken.security.CryptoException;
import io.jsonwebtoken.security.SecurityException;
/**
* Exception indicating that either calculating a signature or verifying an existing signature of a JWT failed.
@ -24,7 +24,7 @@ import io.jsonwebtoken.security.CryptoException;
* @deprecated in favor of {@link io.jsonwebtoken.security.SignatureException}; this class will be removed before 1.0
*/
@Deprecated
public class SignatureException extends CryptoException {
public class SignatureException extends SecurityException {
public SignatureException(String message) {
super(message);

View File

@ -20,5 +20,5 @@ import java.security.Key;
/**
* @since JJWT_RELEASE_VERSION
*/
public interface CryptoRequest<T, K extends Key> extends SecurityRequest, PayloadSupplier<T>, KeySupplier<K> {
public interface CryptoRequest<T, K extends Key> extends SecurityRequest, KeySupplier<K>, PayloadSupplier<T> {
}

View File

@ -18,5 +18,5 @@ package io.jsonwebtoken.security;
/**
* @since JJWT_RELEASE_VERSION
*/
public interface SymmetricAeadDecryptionRequest extends SymmetricAeadRequest, InitializationVectorSupplier, DigestSupplier {
public interface DecryptSymmetricAeadRequest extends SymmetricAeadRequest, InitializationVectorSupplier, DigestSupplier {
}

View File

@ -15,16 +15,10 @@
*/
package io.jsonwebtoken.security;
import java.security.Key;
/**
* @since JJWT_RELEASE_VERSION
*/
public class CryptoException extends SecurityException {
public CryptoException(String message) {
super(message);
}
public CryptoException(String message, Throwable cause) {
super(message, cause);
}
public interface DecryptionKeyRequest<K extends Key> extends KeyRequest<K>, PayloadSupplier<byte[]> {
}

View File

@ -33,7 +33,7 @@ import java.security.Key;
*/
public interface KeyAlgorithm<E extends Key, D extends Key> extends Identifiable {
KeyResult getEncryptionKey(KeyRequest<SecretKey, E> request) throws SecurityException;
KeyResult getEncryptionKey(KeyRequest<E> request) throws SecurityException;
SecretKey getDecryptionKey(KeyRequest<byte[], D> request) throws SecurityException;
SecretKey getDecryptionKey(DecryptionKeyRequest<D> request) throws SecurityException;
}

View File

@ -22,7 +22,7 @@ import java.security.Key;
/**
* @since JJWT_RELEASE_VERSION
*/
public interface KeyRequest<T, K extends Key> extends CryptoRequest<T, K> {
public interface KeyRequest<K extends Key> extends SecurityRequest, KeySupplier<K> {
SymmetricAeadAlgorithm getEncryptionAlgorithm();

View File

@ -24,5 +24,5 @@ public interface SymmetricAeadAlgorithm extends Identifiable, SecretKeyGenerator
AeadResult encrypt(SymmetricAeadRequest request) throws SecurityException;
PayloadSupplier<byte[]> decrypt(SymmetricAeadDecryptionRequest request) throws SecurityException;
PayloadSupplier<byte[]> decrypt(DecryptSymmetricAeadRequest request) throws SecurityException;
}

View File

@ -37,7 +37,7 @@ public class DefaultJweBuilder extends DefaultJwtBuilder<JweBuilder> implements
private Function<SymmetricAeadRequest, AeadResult> encFunction;
private KeyAlgorithm<Key, ?> alg;
private Function<KeyRequest<SecretKey, Key>, KeyResult> algFunction;
private Function<KeyRequest<Key>, KeyResult> algFunction;
private Key key;
@ -98,9 +98,9 @@ public class DefaultJweBuilder extends DefaultJwtBuilder<JweBuilder> implements
Assert.hasText(alg.getId(), "KeyAlgorithm id cannot be null or empty.");
String cekMsg = "Unable to obtain content encryption key from key management algorithm '" + alg.getId() + "'.";
this.algFunction = wrap(cekMsg, new Function<KeyRequest<SecretKey, Key>, KeyResult>() {
this.algFunction = wrap(cekMsg, new Function<KeyRequest<Key>, KeyResult>() {
@Override
public KeyResult apply(KeyRequest<SecretKey, Key> request) {
public KeyResult apply(KeyRequest<Key> request) {
return keyAlg.getEncryptionKey(request);
}
});
@ -145,7 +145,7 @@ public class DefaultJweBuilder extends DefaultJwtBuilder<JweBuilder> implements
jweHeader.setCompressionAlgorithm(compressionCodec.getAlgorithmName());
}
KeyRequest<SecretKey, Key> keyRequest = new DefaultKeyRequest<>(this.provider, this.secureRandom, null, this.key, jweHeader, enc);
KeyRequest<Key> keyRequest = new DefaultKeyRequest<>(this.provider, this.secureRandom, this.key, jweHeader, enc);
KeyResult keyResult = algFunction.apply(keyRequest);
Assert.state(keyResult != null, "KeyAlgorithm must return a KeyResult.");

View File

@ -40,12 +40,13 @@ import io.jsonwebtoken.PrematureJwtException;
import io.jsonwebtoken.SigningKeyResolver;
import io.jsonwebtoken.UnsupportedJwtException;
import io.jsonwebtoken.impl.compression.DefaultCompressionCodecResolver;
import io.jsonwebtoken.impl.lang.Bytes;
import io.jsonwebtoken.impl.lang.ConstantFunction;
import io.jsonwebtoken.impl.lang.Function;
import io.jsonwebtoken.impl.lang.LegacyServices;
import io.jsonwebtoken.impl.security.ConstantKeyLocator;
import io.jsonwebtoken.impl.security.DefaultAeadResult;
import io.jsonwebtoken.impl.security.DefaultKeyRequest;
import io.jsonwebtoken.impl.security.DefaultDecryptionKeyRequest;
import io.jsonwebtoken.impl.security.DefaultVerifySignatureRequest;
import io.jsonwebtoken.impl.security.EncryptionAlgorithmsBridge;
import io.jsonwebtoken.impl.security.KeyAlgorithmsBridge;
@ -60,16 +61,16 @@ import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.lang.Collections;
import io.jsonwebtoken.lang.DateFormats;
import io.jsonwebtoken.lang.Strings;
import io.jsonwebtoken.security.DecryptSymmetricAeadRequest;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.InvalidKeyException;
import io.jsonwebtoken.security.KeyAlgorithm;
import io.jsonwebtoken.security.KeyRequest;
import io.jsonwebtoken.security.Keys;
import io.jsonwebtoken.security.PayloadSupplier;
import io.jsonwebtoken.security.SignatureAlgorithm;
import io.jsonwebtoken.security.SignatureAlgorithms;
import io.jsonwebtoken.security.SignatureException;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import io.jsonwebtoken.security.SymmetricAeadDecryptionRequest;
import io.jsonwebtoken.security.VerifySignatureRequest;
import io.jsonwebtoken.security.WeakKeyException;
@ -112,7 +113,7 @@ public class DefaultJwtParser implements JwtParser {
}
private static <H extends Header<H>, R extends Identifiable> Function<H, R> locFn(String id, String msg, Function<String, R> reg, Collection<R> extras) {
Function<H,R> backup = backup(id, msg, extras);
Function<H, R> backup = backup(id, msg, extras);
return new IdLocator<>(id, msg, reg, backup);
}
@ -172,10 +173,11 @@ public class DefaultJwtParser implements JwtParser {
this.compressionCodecLocator = new CompressionCodecLocator<>(new DefaultCompressionCodecResolver());
}
@SuppressWarnings("deprecation") //SigningKeyResolver will be removed for 1.0
@SuppressWarnings("deprecation")
//SigningKeyResolver will be removed for 1.0
DefaultJwtParser(Provider provider,
SigningKeyResolver signingKeyResolver,
Function<?,Key> keyLocator,
Function<?, Key> keyLocator,
Clock clock,
long allowedClockSkewMillis,
Claims expectedClaims,
@ -399,7 +401,7 @@ public class DefaultJwtParser implements JwtParser {
TokenizedJwe tokenizedJwe = (TokenizedJwe) tokenized;
JweHeader jweHeader = (JweHeader) header;
byte[] cekBytes = new byte[0]; //ignored unless using an encrypted key algorithm
byte[] cekBytes = Bytes.EMPTY; //ignored unless using an encrypted key algorithm
String base64Url = tokenizedJwe.getEncryptedKey();
if (Strings.hasText(base64Url)) {
cekBytes = base64UrlDecode(base64Url, "JWE encrypted key");
@ -418,8 +420,8 @@ public class DefaultJwtParser implements JwtParser {
throw new MalformedJwtException(msg);
}
// This is intentional - the AAD (Additional Authenticated Data) scheme for compact JWEs is to use
// the ASCII bytes of the raw base64url text as the AAD, and *not* the base64url-decoded bytes per
// The AAD (Additional Authenticated Data) scheme for compact JWEs is to use the ASCII bytes of the
// raw base64url text as the AAD, and NOT the base64url-decoded bytes per
// https://datatracker.ietf.org/doc/html/rfc7516#section-5.1, Step 14.
final byte[] aad = base64UrlHeader.getBytes(StandardCharsets.US_ASCII);
@ -438,27 +440,33 @@ public class DefaultJwtParser implements JwtParser {
}
final SymmetricAeadAlgorithm encAlg = this.encryptionAlgorithmLocator.apply(jweHeader);
if (encAlg == null) {
String msg = "Unrecognized JWE encryption algorithm identifier: " + enc;
String msg = "Unrecognized JWE encryption algorithm '" + enc + "'.";
throw new UnsupportedJwtException(msg);
}
@SuppressWarnings("rawtypes") final KeyAlgorithm keyAlg = this.keyAlgorithmLocator.apply(jweHeader);
if (keyAlg == null) {
String msg = "Unrecognized JWE key management algorithm: " + alg;
String msg = "Unrecognized JWE key algorithm '" + alg + "'.";
throw new UnsupportedJwtException(msg);
}
final Key key = ((Function<JweHeader,Key>)this.keyLocator).apply(jweHeader);
final Key key = ((Function<JweHeader, Key>) this.keyLocator).apply(jweHeader);
if (key == null) {
String msg = "No key available for the '" + keyAlg.getId() + "' key management algorithm. Unable to " +
"perform '" + encAlg + "' decryption.";
String msg = "No key found for use with JWE key algorithm '" + keyAlg.getId() +
"'. Unable to decrypt JWE payload.";
throw new UnsupportedJwtException(msg);
}
KeyRequest<byte[], ?> request = new DefaultKeyRequest<>(this.provider, null, cekBytes, key, jweHeader, encAlg);
DecryptionKeyRequest<Key> request =
new DefaultDecryptionKeyRequest<>(this.provider, null, key, jweHeader, encAlg, cekBytes);
final SecretKey cek = keyAlg.getDecryptionKey(request);
if (cek == null) {
String msg = "The '" + keyAlg.getId() + "' JWE key algorithm did not return a decryption key. " +
"Unable to perform '" + encAlg.getId() + "' decryption.";
throw new IllegalStateException(msg);
}
SymmetricAeadDecryptionRequest decryptRequest =
DecryptSymmetricAeadRequest decryptRequest =
new DefaultAeadResult(this.provider, null, bytes, cek, aad, tag, iv);
PayloadSupplier<byte[]> result = encAlg.decrypt(decryptRequest);
bytes = result.getPayload();
@ -475,13 +483,13 @@ public class DefaultJwtParser implements JwtParser {
Jwt<?, ?> jwt;
Object body = claims != null ? claims : payload;
if (header instanceof JweHeader) {
jwt = new DefaultJwe<>((JweHeader)header, body, iv, tag);
jwt = new DefaultJwe<>((JweHeader) header, body, iv, tag);
} else { // JWS
if (!Strings.hasText(tokenized.getDigest()) && SignatureAlgorithms.NONE.getId().equalsIgnoreCase(alg)) {
//noinspection rawtypes
jwt = new DefaultJwt(header, body);
} else {
jwt = new DefaultJws<>((JwsHeader)header, body, tokenized.getDigest());
jwt = new DefaultJws<>((JwsHeader) header, body, tokenized.getDigest());
}
}
@ -492,7 +500,7 @@ public class DefaultJwtParser implements JwtParser {
final JwsHeader jwsHeader = jws.getHeader();
SignatureAlgorithm<?,Key> algorithm = (SignatureAlgorithm<?,Key>)signatureAlgorithmLocator.apply(jwsHeader);
SignatureAlgorithm<?, Key> algorithm = (SignatureAlgorithm<?, Key>) signatureAlgorithmLocator.apply(jwsHeader);
if (algorithm == null) {
String msg = "Unrecognized JWS algorithm identifier: " + alg;
throw new UnsupportedJwtException(msg);

View File

@ -1,7 +1,5 @@
package io.jsonwebtoken.impl;
import io.jsonwebtoken.lang.Assert;
/**
* @since JJWT_RELEASE_VERSION
*/
@ -103,7 +101,7 @@ public class DispatchingParser {
if (secretKey == null) {
String msg = "SecretKeyResolver did not return a secret key for headers " + headers +
". This is required for message decryption.";
throw new CryptoException(msg);
throw new SecurityException(msg);
}
byte[] aad = base64UrlEncodedHeader.getBytes(StandardCharsets.US_ASCII);

View File

@ -60,6 +60,7 @@ abstract class AbstractAsymmetricJwkBuilder<K extends Key, J extends AsymmetricJ
@Override
public T setPublicKeyUse(String use) {
Assert.hasText(use, "publicKeyUse cannot be null or empty.");
return put(AbstractAsymmetricJwk.PUBLIC_KEY_USE, use);
}
@ -70,12 +71,14 @@ abstract class AbstractAsymmetricJwkBuilder<K extends Key, J extends AsymmetricJ
@Override
public T setX509CertificateChain(List<X509Certificate> chain) {
Assert.notEmpty(chain, "X509Certificate chain cannot be null or empty.");
this.jwkContext.setX509CertificateChain(chain);
return tthis();
}
@Override
public T setX509Url(URI url) {
Assert.notNull(url, "X509Url cannot be null.");
this.jwkContext.setX509Url(url);
return tthis();
}

View File

@ -1,27 +0,0 @@
package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.security.SecurityRequest;
import java.security.Provider;
import java.security.SecureRandom;
abstract class AbstractSecurityRequest implements SecurityRequest {
private final Provider provider;
private final SecureRandom secureRandom;
public AbstractSecurityRequest(Provider provider, SecureRandom secureRandom) {
this.provider = provider;
this.secureRandom = secureRandom;
}
@Override
public Provider getProvider() {
return this.provider;
}
@Override
public SecureRandom getSecureRandom() {
return this.secureRandom;
}
}

View File

@ -6,6 +6,7 @@ import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.impl.lang.ValueGetter;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.KeyAlgorithm;
import io.jsonwebtoken.security.KeyRequest;
import io.jsonwebtoken.security.KeyResult;
@ -29,7 +30,7 @@ public class AesGcmKeyAlgorithm extends AesAlgorithm implements KeyAlgorithm<Sec
}
@Override
public KeyResult getEncryptionKey(final KeyRequest<SecretKey, SecretKey> request) throws SecurityException {
public KeyResult getEncryptionKey(final KeyRequest<SecretKey> request) throws SecurityException {
Assert.notNull(request, "request cannot be null.");
final SecretKey kek = assertKey(request);
@ -63,7 +64,7 @@ public class AesGcmKeyAlgorithm extends AesAlgorithm implements KeyAlgorithm<Sec
}
@Override
public SecretKey getDecryptionKey(KeyRequest<byte[], SecretKey> request) throws SecurityException {
public SecretKey getDecryptionKey(DecryptionKeyRequest<SecretKey> request) throws SecurityException {
Assert.notNull(request, "request cannot be null.");
final SecretKey kek = assertKey(request);
final byte[] cekBytes = Assert.notEmpty(request.getPayload(), "Decryption request payload (ciphertext) cannot be null or empty.");

View File

@ -2,6 +2,7 @@ package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.KeyAlgorithm;
import io.jsonwebtoken.security.KeyRequest;
import io.jsonwebtoken.security.KeyResult;
@ -24,7 +25,7 @@ public class AesWrapKeyAlgorithm extends AesAlgorithm implements KeyAlgorithm<Se
}
@Override
public KeyResult getEncryptionKey(KeyRequest<SecretKey, SecretKey> request) throws SecurityException {
public KeyResult getEncryptionKey(KeyRequest<SecretKey> request) throws SecurityException {
Assert.notNull(request, "request cannot be null.");
final SecretKey kek = assertKey(request);
SymmetricAeadAlgorithm enc = Assert.notNull(request.getEncryptionAlgorithm(), "Request encryptionAlgorithm cannot be null.");
@ -43,7 +44,7 @@ public class AesWrapKeyAlgorithm extends AesAlgorithm implements KeyAlgorithm<Se
}
@Override
public SecretKey getDecryptionKey(KeyRequest<byte[], SecretKey> request) throws SecurityException {
public SecretKey getDecryptionKey(DecryptionKeyRequest<SecretKey> request) throws SecurityException {
Assert.notNull(request, "request cannot be null.");
final SecretKey kek = assertKey(request);
final byte[] cekBytes = Assert.notEmpty(request.getPayload(), "Request encrypted key (request.getPayload()) cannot be null or empty.");

View File

@ -3,7 +3,7 @@ package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.lang.Arrays;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.CryptoException;
import io.jsonwebtoken.security.SecurityException;
import io.jsonwebtoken.security.UnsupportedKeyException;
import javax.crypto.SecretKey;
@ -53,11 +53,11 @@ final class ConcatKDF extends CryptoAlgorithm {
* @return the derived key
* @throws UnsupportedKeyException if unable to obtain {@code sharedSecretKey}'s
* {@link Key#getEncoded() encoded byte array}.
* @throws CryptoException if unable to perform the necessary {@link MessageDigest} computations to
* @throws SecurityException if unable to perform the necessary {@link MessageDigest} computations to
* generate the derived key.
*/
public SecretKey deriveKey(SecretKey sharedSecretKey, final long derivedKeyBitLength, final byte[] OtherInfo)
throws UnsupportedKeyException, CryptoException {
throws UnsupportedKeyException, SecurityException {
// OtherInfo argument assertions:
final int otherInfoByteLength = Arrays.length(OtherInfo);

View File

@ -2,13 +2,13 @@ package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.AeadResult;
import io.jsonwebtoken.security.SymmetricAeadDecryptionRequest;
import io.jsonwebtoken.security.DecryptSymmetricAeadRequest;
import javax.crypto.SecretKey;
import java.security.Provider;
import java.security.SecureRandom;
public class DefaultAeadResult extends DefaultSymmetricAeadRequest implements AeadResult, SymmetricAeadDecryptionRequest {
public class DefaultAeadResult extends DefaultSymmetricAeadRequest implements AeadResult, DecryptSymmetricAeadRequest {
private final byte[] TAG;

View File

@ -0,0 +1,24 @@
package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.JweHeader;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import java.security.Key;
import java.security.Provider;
import java.security.SecureRandom;
public class DefaultDecryptionKeyRequest<K extends Key> extends DefaultKeyRequest<K> implements DecryptionKeyRequest<K> {
private final byte[] payload;
public DefaultDecryptionKeyRequest(Provider provider, SecureRandom secureRandom, K key, JweHeader header, SymmetricAeadAlgorithm encryptionAlgorithm, byte[] payload) {
super(provider, secureRandom, key, header, encryptionAlgorithm);
this.payload = payload;
}
@Override
public byte[] getPayload() {
return this.payload;
}
}

View File

@ -1,13 +0,0 @@
package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.security.Jwk;
import java.security.Key;
public class DefaultJwkFactory<K extends Key, J extends Jwk<K>> implements JwkFactory<K,J> {
@Override
public J createJwk(JwkContext<K> ctx) {
return null;
}
}

View File

@ -9,25 +9,17 @@ import java.security.Key;
import java.security.Provider;
import java.security.SecureRandom;
public class DefaultKeyRequest<T, K extends Key> extends DefaultCryptoRequest<T, K> implements KeyRequest<T, K> {
public class DefaultKeyRequest<K extends Key> extends DefaultKeyedRequest<K> implements KeyRequest<K> {
private final JweHeader header;
private final SymmetricAeadAlgorithm encryptionAlgorithm;
public DefaultKeyRequest(Provider provider, SecureRandom secureRandom, T payload, K key, JweHeader header, SymmetricAeadAlgorithm encryptionAlgorithm) {
super(provider, secureRandom, payload, key);
public DefaultKeyRequest(Provider provider, SecureRandom secureRandom, K key, JweHeader header, SymmetricAeadAlgorithm encryptionAlgorithm) {
super(provider, secureRandom, key);
this.header = Assert.notNull(header, "JweHeader cannot be null.");
this.encryptionAlgorithm = Assert.notNull(encryptionAlgorithm, "SymmetricAeadAlgorithm argument cannot be null.");
}
@Override
protected T assertValidPayload(T payload) throws IllegalArgumentException {
if (payload != null) {
return super.assertValidPayload(payload);
}
return null;
}
@Override
public JweHeader getHeader() {
return this.header;

View File

@ -2,17 +2,16 @@ package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.KeySupplier;
import io.jsonwebtoken.security.SecurityRequest;
import java.security.Key;
import java.security.Provider;
import java.security.SecureRandom;
public class KeyedRequest<K extends Key> extends DefaultSecurityRequest implements SecurityRequest, KeySupplier<K> {
public class DefaultKeyedRequest<K extends Key> extends DefaultSecurityRequest implements KeySupplier<K> {
private final K key;
public KeyedRequest(Provider provider, SecureRandom secureRandom, K key) {
public DefaultKeyedRequest(Provider provider, SecureRandom secureRandom, K key) {
super(provider, secureRandom);
this.key = Assert.notNull(key, "Key cannot be null.");
}

View File

@ -2,6 +2,7 @@ package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.KeyRequest;
import io.jsonwebtoken.security.KeyResult;
import io.jsonwebtoken.security.RsaKeyAlgorithm;
@ -31,7 +32,7 @@ public class DefaultRsaKeyAlgorithm<E extends RSAKey & PublicKey, D extends RSAK
}
@Override
public KeyResult getEncryptionKey(final KeyRequest<SecretKey, E> request) throws SecurityException {
public KeyResult getEncryptionKey(final KeyRequest<E> request) throws SecurityException {
Assert.notNull(request, "Request cannot be null.");
final E kek = Assert.notNull(request.getKey(), "Request key encryption key cannot be null.");
SymmetricAeadAlgorithm enc = Assert.notNull(request.getEncryptionAlgorithm(), "Request encryptionAlgorithm cannot be null.");
@ -53,7 +54,7 @@ public class DefaultRsaKeyAlgorithm<E extends RSAKey & PublicKey, D extends RSAK
}
@Override
public SecretKey getDecryptionKey(KeyRequest<byte[], D> request) throws SecurityException {
public SecretKey getDecryptionKey(DecryptionKeyRequest<D> request) throws SecurityException {
Assert.notNull(request, "request cannot be null.");
final D kek = Assert.notNull(request.getKey(), "Request key decryption key cannot be null.");
final byte[] cekBytes = Assert.notEmpty(request.getPayload(), "Request encrypted key (request.getPayload()) cannot be null or empty.");

View File

@ -1,6 +1,7 @@
package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.KeyAlgorithm;
import io.jsonwebtoken.security.KeyRequest;
import io.jsonwebtoken.security.KeyResult;
@ -21,14 +22,14 @@ public class DirectKeyAlgorithm implements KeyAlgorithm<SecretKey, SecretKey> {
}
@Override
public KeyResult getEncryptionKey(KeyRequest<SecretKey, SecretKey> request) throws SecurityException {
public KeyResult getEncryptionKey(KeyRequest<SecretKey> request) throws SecurityException {
Assert.notNull(request, "request cannot be null.");
SecretKey key = Assert.notNull(request.getKey(), "request.getKey() cannot be null.");
return new DefaultKeyResult(key);
}
@Override
public SecretKey getDecryptionKey(KeyRequest<byte[], SecretKey> request) throws SecurityException {
public SecretKey getDecryptionKey(DecryptionKeyRequest<SecretKey> request) throws SecurityException {
Assert.notNull(request, "request cannot be null.");
return Assert.notNull(request.getKey(), "request.getKey() cannot be null.");
}

View File

@ -42,8 +42,8 @@ class EcPrivateJwkFactory extends AbstractEcJwkFactory<ECPrivateKey, EcPrivateJw
// [JWA spec](https://tools.ietf.org/html/rfc7518#section-6.2.2)
// requires public values to be present in private JWKs, so add them:
JwkContext<ECPublicKey> pubCtx = new DefaultJwkContext<>(DefaultEcPrivateJwk.PRIVATE_NAMES, ecPublicKey);
EcPublicJwk pubJwk = EcPublicJwkFactory.DEFAULT_INSTANCE.createJwkFromKey(pubCtx);
JwkContext<ECPublicKey> pubCtx = new DefaultJwkContext<>(DefaultEcPrivateJwk.PRIVATE_NAMES, ctx, ecPublicKey);
EcPublicJwk pubJwk = EcPublicJwkFactory.DEFAULT_INSTANCE.createJwk(pubCtx);
ctx.putAll(pubJwk); // add public values to private key context
int fieldSize = key.getParams().getCurve().getField().getFieldSize();

View File

@ -6,11 +6,9 @@ import io.jsonwebtoken.lang.Arrays;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.lang.RuntimeEnvironment;
import io.jsonwebtoken.security.AeadResult;
import io.jsonwebtoken.security.CryptoException;
import io.jsonwebtoken.security.KeyException;
import io.jsonwebtoken.security.DecryptSymmetricAeadRequest;
import io.jsonwebtoken.security.PayloadSupplier;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import io.jsonwebtoken.security.SymmetricAeadDecryptionRequest;
import io.jsonwebtoken.security.SymmetricAeadRequest;
import javax.crypto.Cipher;
@ -35,7 +33,7 @@ public class GcmAesAeadAlgorithm extends AesAlgorithm implements SymmetricAeadAl
}
@Override
public AeadResult encrypt(final SymmetricAeadRequest req) throws CryptoException, KeyException {
public AeadResult encrypt(final SymmetricAeadRequest req) throws SecurityException {
Assert.notNull(req, "Request cannot be null.");
final SecretKey key = assertKey(req);
@ -67,7 +65,7 @@ public class GcmAesAeadAlgorithm extends AesAlgorithm implements SymmetricAeadAl
}
@Override
public PayloadSupplier<byte[]> decrypt(final SymmetricAeadDecryptionRequest req) throws CryptoException, KeyException {
public PayloadSupplier<byte[]> decrypt(final DecryptSymmetricAeadRequest req) throws SecurityException {
Assert.notNull(req, "Request cannot be null.");
final SecretKey key = assertKey(req);

View File

@ -4,11 +4,11 @@ import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.AeadResult;
import io.jsonwebtoken.security.CryptoRequest;
import io.jsonwebtoken.security.DecryptSymmetricAeadRequest;
import io.jsonwebtoken.security.PayloadSupplier;
import io.jsonwebtoken.security.SignatureException;
import io.jsonwebtoken.security.SignatureRequest;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import io.jsonwebtoken.security.SymmetricAeadDecryptionRequest;
import io.jsonwebtoken.security.SymmetricAeadRequest;
import javax.crypto.Cipher;
@ -124,7 +124,7 @@ public class HmacAesAeadAlgorithm extends AesAlgorithm implements SymmetricAeadA
}
@Override
public PayloadSupplier<byte[]> decrypt(final SymmetricAeadDecryptionRequest req) {
public PayloadSupplier<byte[]> decrypt(final DecryptSymmetricAeadRequest req) {
Assert.notNull(req, "Request cannot be null.");

View File

@ -3,7 +3,6 @@ package io.jsonwebtoken.impl.security;
import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.lang.Classes;
import io.jsonwebtoken.security.CryptoException;
import io.jsonwebtoken.security.SecurityException;
import io.jsonwebtoken.security.SignatureException;
@ -33,7 +32,7 @@ public class JcaTemplate {
this.secureRandom = Assert.notNull(secureRandom, "SecureRandom cannot be null.");
}
public <T, R> R execute(Class<T> clazz, CheckedFunction<T, R> fn) throws CryptoException {
public <T, R> R execute(Class<T> clazz, CheckedFunction<T, R> fn) throws SecurityException {
return execute(new JcaInstanceSupplier<>(clazz, this.jcaName, this.provider), fn);
}
@ -57,14 +56,14 @@ public class JcaTemplate {
});
}
private <T, R> R execute(JcaInstanceSupplier<T> supplier, CheckedFunction<T, R> callback) throws CryptoException {
private <T, R> R execute(JcaInstanceSupplier<T> supplier, CheckedFunction<T, R> callback) throws SecurityException {
try {
T instance = supplier.getInstance();
return callback.apply(instance);
} catch (SecurityException se) {
throw se; //propagate
} catch (Exception e) {
throw new CryptoException(supplier.getName() + " callback execution failed: " + e.getMessage(), e);
throw new SecurityException(supplier.getName() + " callback execution failed: " + e.getMessage(), e);
}
}
@ -113,13 +112,13 @@ public class JcaTemplate {
}
protected Exception wrap(String msg, Exception cause) {
if (cause instanceof CryptoException) {
if (cause instanceof SecurityException) {
return cause;
}
if (Signature.class.isAssignableFrom(clazz) || Mac.class.isAssignableFrom(clazz)) {
return new SignatureException(msg, cause);
}
return new CryptoException(msg, cause);
return new SecurityException(msg, cause);
}
protected T doGetInstance() {

View File

@ -7,6 +7,7 @@ import io.jsonwebtoken.impl.IdRegistry;
import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.impl.lang.Registry;
import io.jsonwebtoken.lang.Collections;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.EncryptionAlgorithms;
import io.jsonwebtoken.security.KeyAlgorithm;
import io.jsonwebtoken.security.KeyRequest;
@ -99,7 +100,7 @@ public final class KeyAlgorithmsBridge {
// hashing and not ancillary steps needed to setup the hashing/derivation
return new KeyAlgorithm<PbeKey, SecretKey>() {
@Override
public KeyResult getEncryptionKey(KeyRequest<SecretKey, PbeKey> request) throws SecurityException {
public KeyResult getEncryptionKey(KeyRequest<PbeKey> request) throws SecurityException {
int iterations = request.getKey().getWorkFactor();
char[] password = request.getKey().getPassword();
try {
@ -111,7 +112,7 @@ public final class KeyAlgorithmsBridge {
}
@Override
public SecretKey getDecryptionKey(KeyRequest<byte[], SecretKey> request) throws SecurityException {
public SecretKey getDecryptionKey(DecryptionKeyRequest<SecretKey> request) throws SecurityException {
throw new UnsupportedOperationException("Not intended to be called.");
}
@ -128,7 +129,7 @@ public final class KeyAlgorithmsBridge {
private static char[] randomChars(int length) {
char[] chars = new char[length];
for(int i = 0; i < length; i++) {
for (int i = 0; i < length; i++) {
chars[i] = randomChar();
}
return chars;
@ -161,8 +162,7 @@ public final class KeyAlgorithmsBridge {
char[] password = randomChars(PASSWORD_LENGTH);
PbeKey pbeKey = Keys.forPbe().setPassword(password).setWorkFactor(workFactor).build();
KeyRequest<SecretKey, PbeKey> request =
new DefaultKeyRequest<>(null, null, null, pbeKey, HEADER, ENC_ALG);
KeyRequest<PbeKey> request = new DefaultKeyRequest<>(null, null, pbeKey, HEADER, ENC_ALG);
long start = System.currentTimeMillis();
alg.getEncryptionKey(request); // <-- Computation occurs here. Don't need the result, just need to exec

View File

@ -6,12 +6,12 @@ import io.jsonwebtoken.impl.lang.CheckedFunction;
import io.jsonwebtoken.impl.lang.ValueGetter;
import io.jsonwebtoken.io.Encoders;
import io.jsonwebtoken.lang.Assert;
import io.jsonwebtoken.security.DecryptionKeyRequest;
import io.jsonwebtoken.security.KeyAlgorithm;
import io.jsonwebtoken.security.KeyRequest;
import io.jsonwebtoken.security.KeyResult;
import io.jsonwebtoken.security.PbeKey;
import io.jsonwebtoken.security.SecurityException;
import io.jsonwebtoken.security.SymmetricAeadAlgorithm;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
@ -94,7 +94,7 @@ public class Pbes2HsAkwAlgorithm extends CryptoAlgorithm implements KeyAlgorithm
}
}
private SecretKey deriveKey(final KeyRequest<?, ?> request, final char[] password, final byte[] salt, final int iterations) {
private SecretKey deriveKey(final KeyRequest<?> request, final char[] password, final byte[] salt, final int iterations) {
try {
return execute(request, SecretKeyFactory.class, new CheckedFunction<SecretKeyFactory, SecretKey>() {
@Override
@ -109,7 +109,7 @@ public class Pbes2HsAkwAlgorithm extends CryptoAlgorithm implements KeyAlgorithm
}
}
protected byte[] generateInputSalt(KeyRequest<?, ?> request) {
protected byte[] generateInputSalt(KeyRequest<?> request) {
byte[] inputSalt = new byte[this.HASH_BYTE_LENGTH];
ensureSecureRandom(request).nextBytes(inputSalt);
return inputSalt;
@ -121,11 +121,9 @@ public class Pbes2HsAkwAlgorithm extends CryptoAlgorithm implements KeyAlgorithm
}
@Override
public KeyResult getEncryptionKey(KeyRequest<SecretKey, PbeKey> request) throws SecurityException {
public KeyResult getEncryptionKey(KeyRequest<PbeKey> request) throws SecurityException {
Assert.notNull(request, "request cannot be null.");
SymmetricAeadAlgorithm enc = Assert.notNull(request.getEncryptionAlgorithm(), "Request encryptionAlgorithm cannot be null.");
final SecretKey cek = Assert.notNull(enc.generateKey(), "Request encryption algorithm cannot generate a null key.");
final PbeKey pbeKey = Assert.notNull(request.getKey(), "request.getKey() cannot be null.");
final int iterations = assertIterations(pbeKey.getWorkFactor());
@ -135,9 +133,9 @@ public class Pbes2HsAkwAlgorithm extends CryptoAlgorithm implements KeyAlgorithm
char[] password = pbeKey.getPassword(); // will be safely cleaned/zeroed in deriveKey next:
final SecretKey derivedKek = deriveKey(request, password, rfcSalt, iterations);
// now encrypt (wrap) the CEK with the PBE-derived key:
DefaultKeyRequest<SecretKey, SecretKey> wrapReq = new DefaultKeyRequest<>(request.getProvider(),
request.getSecureRandom(), cek, derivedKek, request.getHeader(), request.getEncryptionAlgorithm());
// now get a new CEK that is encrypted ('wrapped') with the PBE-derived key:
DefaultKeyRequest<SecretKey> wrapReq = new DefaultKeyRequest<>(request.getProvider(),
request.getSecureRandom(), derivedKek, request.getHeader(), request.getEncryptionAlgorithm());
KeyResult result = wrapAlg.getEncryptionKey(wrapReq);
request.getHeader().put(SALT_HEADER_NAME, p2s);
@ -174,7 +172,7 @@ public class Pbes2HsAkwAlgorithm extends CryptoAlgorithm implements KeyAlgorithm
}
@Override
public SecretKey getDecryptionKey(KeyRequest<byte[], SecretKey> request) throws SecurityException {
public SecretKey getDecryptionKey(DecryptionKeyRequest<SecretKey> request) throws SecurityException {
JweHeader header = Assert.notNull(request.getHeader(), "Request JweHeader cannot be null.");
final SecretKey key = Assert.notNull(request.getKey(), "Request Key cannot be null.");
@ -187,8 +185,8 @@ public class Pbes2HsAkwAlgorithm extends CryptoAlgorithm implements KeyAlgorithm
final SecretKey derivedKek = deriveKey(request, password, rfcSalt, iterations);
KeyRequest<byte[], SecretKey> unwrapReq = new DefaultKeyRequest<>(request.getProvider(),
request.getSecureRandom(), request.getPayload(), derivedKek, header, request.getEncryptionAlgorithm());
DecryptionKeyRequest<SecretKey> unwrapReq = new DefaultDecryptionKeyRequest<>(request.getProvider(),
request.getSecureRandom(), derivedKek, header, request.getEncryptionAlgorithm(), request.getPayload());
return wrapAlg.getDecryptionKey(unwrapReq);
}

View File

@ -95,7 +95,7 @@ class RsaPrivateJwkFactory extends AbstractFamilyJwkFactory<RSAPrivateKey, RsaPr
// The [JWA Spec](https://datatracker.ietf.org/doc/html/rfc7518#section-6.3.1)
// requires public values to be present in private JWKs, so add them:
JwkContext<RSAPublicKey> pubCtx = new DefaultJwkContext<>(DefaultRsaPrivateJwk.PRIVATE_NAMES, rsaPublicKey);
JwkContext<RSAPublicKey> pubCtx = new DefaultJwkContext<>(DefaultRsaPrivateJwk.PRIVATE_NAMES, ctx, rsaPublicKey);
RsaPublicJwk pubJwk = RsaPublicJwkFactory.DEFAULT_INSTANCE.createJwk(pubCtx);
ctx.putAll(pubJwk); // add public values to private key context

View File

@ -1,6 +1,5 @@
package io.jsonwebtoken.impl.lang
import io.jsonwebtoken.security.CryptoException
import io.jsonwebtoken.security.SecurityException
import org.junit.Test
@ -11,7 +10,7 @@ class PropagatingExceptionFunctionTest {
@Test
void testAssignableException() {
def ex = new CryptoException("test")
def ex = new SecurityException("test")
def fn = new PropagatingExceptionFunction<>(SecurityException.class, "foo", new Function<Object,Object>() {
@Override

View File

@ -3,11 +3,6 @@ package io.jsonwebtoken.impl.security
import io.jsonwebtoken.security.*
import org.junit.Test
import javax.crypto.SecretKey
import javax.crypto.spec.SecretKeySpec
import java.nio.charset.StandardCharsets
import java.security.Key
import java.security.Provider
import java.security.SecureRandom
import static org.junit.Assert.*
@ -36,7 +31,7 @@ class AesAlgorithmTest {
try {
alg.encrypt(req)
} catch (CryptoException expected) {
} catch (SecurityException expected) {
assertTrue expected.getCause() instanceof IllegalArgumentException
assertTrue expected.getCause().getMessage().equals('broken')
}
@ -47,16 +42,14 @@ class AesAlgorithmTest {
def alg = new TestAesAlgorithm('foo', 'foo', 192)
key = EncryptionAlgorithms.A128GCM.generateKey() //weaker than required
def key = EncryptionAlgorithms.A128GCM.generateKey() //weaker than required
def request = new DefaultCryptoRequest(null, null, new byte[1], key)
try {
alg.assertKey(request)
fail()
} catch (CryptoException expected) {
} catch (SecurityException expected) {
}
}
@ -86,7 +79,7 @@ class AesAlgorithmTest {
}
@Override
PayloadSupplier<byte[]> decrypt(SymmetricAeadDecryptionRequest symmetricAeadDecryptionRequest) {
PayloadSupplier<byte[]> decrypt(DecryptSymmetricAeadRequest symmetricAeadDecryptionRequest) {
return null
}
}

View File

@ -77,14 +77,14 @@ class AesGcmKeyAlgorithmTest {
}
}
def ereq = new DefaultKeyRequest(null, null, cek, kek, header, enc)
def ereq = new DefaultKeyRequest(null, null, kek, header, enc)
def result = alg.getEncryptionKey(ereq)
byte[] encryptedKeyBytes = result.getPayload()
assertFalse "encryptedKey must be populated", Arrays.length(encryptedKeyBytes) == 0
def dcek = alg.getDecryptionKey(new DefaultKeyRequest<byte[], SecretKey>(null, null, encryptedKeyBytes, kek, header, enc))
def dcek = alg.getDecryptionKey(new DefaultDecryptionKeyRequest(null, null, kek, header, enc, encryptedKeyBytes))
//Assert the decrypted key matches the original cek
assertEquals cek.algorithm, dcek.algorithm
@ -111,7 +111,7 @@ class AesGcmKeyAlgorithmTest {
return cek
}
}
def ereq = new DefaultKeyRequest(null, null, cek, kek, header, enc)
def ereq = new DefaultKeyRequest(null, null, kek, header, enc)
def result = alg.getEncryptionKey(ereq)
header.put(headerName, value) //null value will remove it
@ -119,7 +119,7 @@ class AesGcmKeyAlgorithmTest {
byte[] encryptedKeyBytes = result.getPayload()
try {
alg.getDecryptionKey(new DefaultKeyRequest<byte[], SecretKey>(null, null, encryptedKeyBytes, kek, header, enc))
alg.getDecryptionKey(new DefaultDecryptionKeyRequest(null, null, kek, header, enc, encryptedKeyBytes))
fail()
} catch (MalformedJwtException iae) {
assertEquals exmsg, iae.getMessage()

View File

@ -15,14 +15,14 @@ class ConstantKeyLocatorTest {
@Test
void testSignatureVerificationKey() {
def key = new SecretKeySpec(new byte[1], 'AES') //dummy key for testing
assertSame key, new ConstantKeyLocator(key, null).resolveKey(new DefaultJwsHeader())
assertSame key, new ConstantKeyLocator(key, null).locate(new DefaultJwsHeader())
}
@Test
void testSignatureVerificationKeyMissing() {
def resolver = new ConstantKeyLocator(null, null)
def locator = new ConstantKeyLocator(null, null)
try {
resolver.resolveKey(new DefaultJwsHeader())
locator.locate(new DefaultJwsHeader())
} catch (UnsupportedJwtException uje) {
String msg = 'Signed JWTs are not supported: the JwtParser has not been configured with a signature ' +
'verification key or a KeyResolver. Consider configuring the JwtParserBuilder with one of these ' +
@ -34,14 +34,14 @@ class ConstantKeyLocatorTest {
@Test
void testDecryptionKey() {
def key = new SecretKeySpec(new byte[1], 'AES') //dummy key for testing
assertSame key, new ConstantKeyLocator(null, key).resolveKey(new DefaultJweHeader())
assertSame key, new ConstantKeyLocator(null, key).locate(new DefaultJweHeader())
}
@Test
void testDecryptionKeyMissing() {
def resolver = new ConstantKeyLocator(null, null)
def locator = new ConstantKeyLocator(null, null)
try {
resolver.resolveKey(new DefaultJweHeader())
locator.locate(new DefaultJweHeader())
} catch (UnsupportedJwtException uje) {
String msg = 'Encrypted JWTs are not supported: the JwtParser has not been configured with a decryption ' +
'key or a KeyResolver. Consider configuring the JwtParserBuilder with one of these ' +

View File

@ -2,8 +2,8 @@ package io.jsonwebtoken.impl.security
import io.jsonwebtoken.JwtException
import io.jsonwebtoken.io.Decoders
import io.jsonwebtoken.security.CryptoException
import io.jsonwebtoken.security.InvalidKeyException
import io.jsonwebtoken.security.SecurityException
import io.jsonwebtoken.security.SignatureAlgorithms
import io.jsonwebtoken.security.WeakKeyException
import org.junit.Test
@ -28,7 +28,7 @@ class DefaultEllipticCurveSignatureAlgorithmTest {
}
}
@Test(expected = CryptoException)
@Test(expected = SecurityException)
void testGenerateKeyPairInvalidCurveName() {
def alg = new DefaultEllipticCurveSignatureAlgorithm('ES256', 'SHA256withECDSA', 'notreal', 256, 256)
alg.generateKeyPair()

View File

@ -1,7 +1,7 @@
package io.jsonwebtoken.impl.security
import io.jsonwebtoken.impl.lang.CheckedFunction
import io.jsonwebtoken.security.CryptoException
import io.jsonwebtoken.security.SecurityException
import io.jsonwebtoken.security.SignatureException
import org.junit.Test
@ -42,7 +42,7 @@ class JcaTemplateTest {
try {
supplier.getInstance()
} catch (CryptoException ce) { //should be wrapped as crypto exception
} catch (SecurityException ce) { //should be wrapped as SecurityException
String msg = ce.getMessage()
//we check for starts-with/ends-with logic here instead of equals because the JCE provider String value
//contains the JCE version number, and that can differ across JDK versions. Since we use different JDK
@ -54,7 +54,7 @@ class JcaTemplateTest {
@Test
void testGetInstanceDoesNotWrapCryptoExceptions() {
def ex = new CryptoException("foo")
def ex = new SecurityException("foo")
def supplier = new JcaTemplate.JcaInstanceSupplier<Cipher>(Cipher.class, 'AES', null) {
@Override
protected Cipher doGetInstance() {
@ -64,7 +64,7 @@ class JcaTemplateTest {
try {
supplier.getInstance()
} catch (CryptoException ce) {
} catch (SecurityException ce) {
assertSame ex, ce
}
}
@ -104,7 +104,7 @@ class JcaTemplateTest {
throw ex
}
})
} catch (CryptoException e) {
} catch (SecurityException e) {
assertEquals 'Cipher callback execution failed: testing', e.getMessage()
assertSame ex, e.getCause()
}

View File

@ -3,19 +3,16 @@ package io.jsonwebtoken.impl.security
import io.jsonwebtoken.io.Decoders
import io.jsonwebtoken.io.Encoders
import io.jsonwebtoken.security.EllipticCurveSignatureAlgorithm
import io.jsonwebtoken.security.Jwks
import io.jsonwebtoken.security.SignatureAlgorithms
import io.jsonwebtoken.security.*
import org.junit.Test
import javax.crypto.SecretKey
import java.security.KeyPair
import java.security.MessageDigest
import java.security.PrivateKey
import java.security.PublicKey
import java.security.cert.X509Certificate
import java.security.interfaces.ECPrivateKey
import java.security.interfaces.ECPublicKey
import java.security.interfaces.RSAPrivateKey
import java.security.interfaces.RSAPublicKey
import java.security.interfaces.ECKey
import static org.junit.Assert.*
@ -30,16 +27,16 @@ class JwksTest {
return Encoders.BASE64URL.encode(random);
}
static void testProperty(String name, String id, def val) {
static void testProperty(String name, String id, def val, def expectedFieldValue=val) {
String cap = "${name.capitalize()}"
def key = name == 'use' ? EC_PAIR.public : SKEY
def key = name == 'publicKeyUse' || name == 'x509CertificateChain' ? EC_PAIR.public : SKEY
//test non-null value:
def builder = Jwks.builder().setKey(key)
builder."set${cap}"(val)
def jwk = builder.build()
assertEquals val, jwk."get${cap}"()
assertEquals val, jwk."${id}"
assertEquals expectedFieldValue, jwk."${id}"
//test null value:
builder = Jwks.builder().setKey(key)
@ -112,73 +109,59 @@ class JwksTest {
}
@Test
void testUse() {
testProperty('use', 'use', srandom())
void testPublicKeyUse() {
testProperty('publicKeyUse', 'use', srandom())
}
@Test
void testX509CertChain() {
//get a test cert:
X509Certificate cert = CertUtils.readTestCertificate(SignatureAlgorithms.RS256)
testProperty('x509CertificateChain', 'x5c', cert)
def sval = JwkX509StringConverter.INSTANCE.applyTo(cert)
testProperty('x509CertificateChain', 'x5c', [cert], [sval])
}
@Test
void testAPI() {
def pair = SignatureAlgorithms.ES256.generateKeyPair();
ECPublicKey ecPub = pair.getPublic() as ECPublicKey
ECPrivateKey ecPriv = pair.getPrivate() as ECPrivateKey
pair = SignatureAlgorithms.RS256.generateKeyPair()
RSAPublicKey rsaPub = pair.getPublic() as RSAPublicKey
RSAPrivateKey rsaPriv = pair.getPrivate() as RSAPrivateKey
SecretKey secretKey = SignatureAlgorithms.HS256.generateKey()
def ecPubJwk = Jwks.builder().setKey(ecPub).setPublicKeyUse("sig").build()
assertEquals ecPub, ecPubJwk.toKey()
def rsaPrivJwk = Jwks.builder().setKey(rsaPub).setPublicKeyUse("foo").setPrivateKey(rsaPriv).build();
def ecPrivJwk = Jwks.builder().setKey(ecPriv).build()
def pubJwk = ecPrivJwk.toPublicJwk()
assertEquals ecPubJwk, pubJwk
assertEquals ecPub, ecPrivJwk.toPublicKey()
def rsaPubJwk = Jwks.builder().setKey(rsaPub).build()
rsaPrivJwk = Jwks.builder().setKey(rsaPriv).setPublicKey(rsaPub).build()
assertEquals rsaPubJwk, rsaPrivJwk.toPublicJwk()
}
@Test
void testSecretKeyConversionHappyPath() {
def algs = [SignatureAlgorithms.HS256, SignatureAlgorithms.HS384, SignatureAlgorithms.HS512]
for (def alg : algs) {
SecretKey key = alg.generateKey();
def jwk = Jwks.builder().setKey(key).build()
def result = Jwks.builder().putAll(jwk).build()
assertArrayEquals key.encoded, result.toKey().encoded
void testSecretJwks() {
Collection<SecretKeySignatureAlgorithm> algs = SignatureAlgorithms.values().findAll({it instanceof SecretKeySignatureAlgorithm}) as Collection<SecretKeySignatureAlgorithm>
for(def alg : algs) {
SecretKey secretKey = alg.generateKey()
def jwk = Jwks.builder().setKey(secretKey).setId('id').build()
assertEquals 'oct', jwk.getType()
assertTrue jwk.containsKey('k')
assertEquals 'id', jwk.getId()
assertEquals secretKey, jwk.toKey()
}
}
@Test
void testEcConversionHappyPath() {
void testAsymmetricJwks() {
List<EllipticCurveSignatureAlgorithm> algs = [SignatureAlgorithms.ES256, SignatureAlgorithms.ES384, SignatureAlgorithms.ES512]
Collection<AsymmetricKeySignatureAlgorithm> algs = SignatureAlgorithms.values().findAll({it instanceof AsymmetricKeySignatureAlgorithm}) as Collection<AsymmetricKeySignatureAlgorithm>
for (EllipticCurveSignatureAlgorithm alg : algs) {
for(def alg : algs) {
def pair = alg.generateKeyPair()
ECPublicKey pubKey = (ECPublicKey) pair.getPublic();
ECPrivateKey privKey = (ECPrivateKey) pair.getPrivate();
PublicKey pub = pair.getPublic()
PrivateKey priv = pair.getPrivate()
def jwk = Jwks.builder().setKey(pubKey).build()
def result = Jwks.builder().putAll(jwk).build()
assertEquals pubKey, result.toKey()
// test individual keys
PublicJwk pubJwk = Jwks.builder().setKey(pub).setPublicKeyUse("sig").build()
assertEquals pub, pubJwk.toKey()
PrivateJwk privJwk = Jwks.builder().setKey(priv).setPublicKeyUse("sig").build()
assertEquals priv, privJwk.toKey()
PublicJwk privPubJwk = privJwk.toPublicJwk()
assertEquals pubJwk, privPubJwk
assertEquals pub, pubJwk.toKey()
jwk = Jwks.builder().setKey(privKey).build()
result = Jwks.builder().putAll(jwk).build()
assertEquals privKey, result.toKey()
// test pair
privJwk = pub instanceof ECKey ?
Jwks.builder().setKeyPairEc(pair).setPublicKeyUse("sig").build() :
Jwks.builder().setKeyPairRsa(pair).setPublicKeyUse("sig").build()
assertEquals priv, privJwk.toKey()
privPubJwk = privJwk.toPublicJwk()
assertEquals pubJwk, privPubJwk
assertEquals pub, pubJwk.toKey()
}
}
}

View File

@ -1,7 +1,8 @@
package io.jsonwebtoken.impl.security
import io.jsonwebtoken.security.CryptoException
import io.jsonwebtoken.security.InvalidKeyException
import io.jsonwebtoken.security.SecurityException
import io.jsonwebtoken.security.WeakKeyException
import org.junit.Test
@ -15,7 +16,7 @@ class MacSignatureAlgorithmTest {
return new MacSignatureAlgorithm('HS256', 'HmacSHA256', 256)
}
@Test(expected = CryptoException)
@Test(expected = SecurityException)
void testKeyGeneratorNoSuchAlgorithm() {
MacSignatureAlgorithm alg = new MacSignatureAlgorithm('HS256', 'foo', 256);
alg.generateKey()

View File

@ -280,7 +280,7 @@ class RFC7517AppendixCTest {
}
def keyAlg = new Pbes2HsAkwAlgorithm(128) {
@Override
protected byte[] generateInputSalt(KeyRequest<SecretKey, SecretKey> request) {
protected byte[] generateInputSalt(KeyRequest<SecretKey> request) {
return RFC_P2S;
}
}