mirror of
https://github.com/jwtk/jjwt.git
synced 2025-02-16 17:54:58 +00:00
testing cleanup, removed unused classes/interfaces
This commit is contained in:
parent
36b450258b
commit
e6db3da6b0
@ -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);
|
||||
|
@ -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> {
|
||||
}
|
||||
|
@ -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 {
|
||||
}
|
@ -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[]> {
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.");
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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.");
|
||||
|
@ -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.");
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
@ -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.");
|
||||
}
|
@ -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.");
|
||||
|
@ -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.");
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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.");
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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 ' +
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user