Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/src/main/java/io/jsonwebtoken/Jwts.java
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ public static JwtBuilder builder() {
/**
* Returns a new {@link JwtParserBuilder} instance that can be configured to create an immutable/thread-safe {@link JwtParser}.
*
* @return a new {@link JwtParser} instance that can be configured create an immutable/thread-safe {@link JwtParser}.
* @return a new {@link JwtParserBuilder} instance that can be configured create an immutable/thread-safe {@link JwtParser}.
*/
public static JwtParserBuilder parser() {
return JWT_PARSER_BUILDER_SUPPLIER.get();
Expand Down
43 changes: 43 additions & 0 deletions api/src/main/java/io/jsonwebtoken/security/AeadRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import javax.crypto.SecretKey;
import java.io.InputStream;
import java.io.OutputStream;

/**
* A request to an {@link AeadAlgorithm} to perform authenticated encryption with a supplied symmetric
Expand All @@ -27,4 +28,46 @@
* @since 0.12.0
*/
public interface AeadRequest extends SecureRequest<InputStream, SecretKey>, AssociatedDataSupplier {

/**
* Named parameters (setters) used to configure an {@link AeadRequest AeadRequest} instance.
*
* @param <M> the instance type returned for method chaining.
* @since JJWT_RELEASE_VERSION
*/
interface Params<M extends Params<M>> extends SecureRequest.Params<InputStream, SecretKey, M> {

/**
* Sets any &quot;associated data&quot; that must be integrity protected (but not encrypted) when performing
* <a href="https://en.wikipedia.org/wiki/Authenticated_encryption">AEAD encryption or decryption</a>.
*
* @param aad the {@code InputStream} containing any associated data that must be integrity protected or
* verified during AEAD encryption or decryption.
* @return the instance for method chaining.
* @see AeadAlgorithm#encrypt(AeadRequest, AeadResult)
* @see AeadAlgorithm#decrypt(DecryptAeadRequest, OutputStream)
*/
M associatedData(InputStream aad);
}

/**
* A builder for creating new immutable {@link AeadRequest} instances used for AEAD encryption via
* {@link AeadAlgorithm#encrypt(AeadRequest, AeadResult)}.
*
* @since JJWT_RELEASE_VERSION
*/
interface Builder extends Params<Builder>, io.jsonwebtoken.lang.Builder<AeadRequest> {
}

/**
* Returns a new {@link AeadRequest.Builder} for creating immutable {@link AeadRequest}s used for AEAD encryption
* via {@link AeadAlgorithm#encrypt(AeadRequest, AeadResult)}.
*
* @return a new {@link AeadRequest.Builder} for creating immutable {@link AeadRequest}s used for AEAD encryption
* via {@link AeadAlgorithm#encrypt(AeadRequest, AeadResult)}.
* @since JJWT_RELEASE_VERSION
*/
static AeadRequest.Builder builder() {
return Suppliers.AEAD_REQUEST_BUILDER.get();
}
}
15 changes: 14 additions & 1 deletion api/src/main/java/io/jsonwebtoken/security/AeadResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
*
* @since 0.12.0
*/
public interface AeadResult {
public interface AeadResult extends DigestSupplier, IvSupplier {

/**
* Returns the {@code OutputStream} the AeadAlgorithm will use to write the resulting ciphertext during
Expand All @@ -50,4 +50,17 @@ public interface AeadResult {
* @return the AeadResult for method chaining.
*/
AeadResult setIv(byte[] iv);

/**
* Returns a new {@link AeadResult} with the specified {@link OutputStream} that will be used to write the
* resulting ciphertext during encryption or plaintext during decryption.
*
* @return a new {@link AeadResult} with the specified {@link OutputStream} that will be used to write the
* resulting ciphertext during encryption or plaintext during decryption.
* @since JJWT_RELEASE_VERSION
*/
static AeadResult with(OutputStream out) {
return Suppliers.AEAD_RESULT_FACTORY.apply(out);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,59 @@
package io.jsonwebtoken.security;

import javax.crypto.SecretKey;
import java.io.OutputStream;

/**
* A request to an {@link AeadAlgorithm} to decrypt ciphertext and perform integrity-protection with a supplied
* A request to an {@link AeadAlgorithm} to decrypt ciphertext with integrity verification with a supplied
* decryption {@link SecretKey}. Extends both {@link IvSupplier} and {@link DigestSupplier} to
* ensure the respective required IV and AAD tag returned from an {@link AeadResult} are available for decryption.
*
* @since 0.12.0
*/
public interface DecryptAeadRequest extends AeadRequest, IvSupplier, DigestSupplier {

/**
* Named parameters (setters) used to configure an {@link AeadRequest AeadRequest} instance.
*
* @since JJWT_RELEASE_VERSION
*/
interface Params<M extends Params<M>> extends AeadRequest.Params<M> {

/**
* Sets the required initialization vector used during AEAD decryption.
*
* @param iv the required initialization vector used during AEAD decryption.
*/
M iv(byte[] iv);

/**
* Sets the required AEAD Authentication Tag used to verify message authenticity during AEAD decryption.
*
* @param digest the required AEAD Authentication Tag used to verify message authenticity during AEAD decryption.
* @return the instance for method chaining.
*/
M digest(byte[] digest);
}

/**
* A builder for creating new immutable {@link DecryptAeadRequest}s used for AEAD decryption via
* {@link AeadAlgorithm#decrypt(DecryptAeadRequest, OutputStream)}.
*
* @since JJWT_RELEASE_VERSION
*/
interface Builder extends io.jsonwebtoken.lang.Builder<DecryptAeadRequest>, Params<Builder> {
}

/**
* Returns a new {@link DecryptAeadRequest.Builder} for creating immutable {@link DecryptAeadRequest}s used for
* AEAD decryption via {@link AeadAlgorithm#decrypt(DecryptAeadRequest, OutputStream)}.
*
* @return a new {@link DecryptAeadRequest.Builder} for creating immutable {@link DecryptAeadRequest}s used for
* AEAD decryption via {@link AeadAlgorithm#decrypt(DecryptAeadRequest, OutputStream)}.
* @since JJWT_RELEASE_VERSION
*/
static DecryptAeadRequest.Builder builder() {
return Suppliers.DECRYPT_AEAD_REQUEST_BUILDER.get();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,44 @@
* {@code JWE Encrypted Key} (such as an initialization vector, authentication tag, ephemeral key, etc) is expected
* to be available in the JWE protected header, accessible via {@link #getHeader()}.</p>
*
* @param <K> the type of {@link Key} used during the request to obtain the resulting decryption key.
* @param <K> the type of key used by the {@link KeyAlgorithm} to obtain the JWE Content Encryption Key (CEK).
* @see KeyAlgorithm#getDecryptionKey(DecryptionKeyRequest)
* @since 0.12.0
*/
public interface DecryptionKeyRequest<K extends Key> extends SecureRequest<byte[], K>, KeyRequest<byte[]> {

/**
* Named parameters (setters) used to configure a {@link DecryptionKeyRequest DecryptionKeyRequest}
* instance.
*
* @param <K> the type of key used by the {@link KeyAlgorithm} to obtain the JWE Content Encryption Key (CEK).
* @param <M> the instance type returned for method chaining.
* @since JJWT_RELEASE_VERSION
*/
interface Params<K extends Key, M extends Params<K, M>> extends KeyRequest.Params<byte[], M>,
SecureRequest.Params<byte[], K, M> {
}

/**
* A builder for creating new immutable {@link DecryptionKeyRequest} instances used to get a JWE
* decryption key via {@link KeyAlgorithm#getDecryptionKey(DecryptionKeyRequest)}.
*
* @param <K> the type of key used by the {@link KeyAlgorithm} to obtain the JWE Content Encryption Key (CEK).
* @since JJWT_RELEASE_VERSION
*/
interface Builder<K extends Key> extends Params<K, Builder<K>>, io.jsonwebtoken.lang.Builder<DecryptionKeyRequest<K>> {
}

/**
* Returns a new {@link DecryptionKeyRequest.Builder} for creating immutable {@link DecryptionKeyRequest}s used to
* get a JWE decryption key via {@link KeyAlgorithm#getDecryptionKey(DecryptionKeyRequest)}.
*
* @return a new {@link DecryptionKeyRequest.Builder} for creating immutable {@link DecryptionKeyRequest}s used to
* get a JWE decryption key via {@link KeyAlgorithm#getDecryptionKey(DecryptionKeyRequest)}.
* @since JJWT_RELEASE_VERSION
*/
@SuppressWarnings("unchecked")
static <K extends Key> DecryptionKeyRequest.Builder<K> builder() {
return (DecryptionKeyRequest.Builder<K>) Suppliers.DECRYPTION_KEY_REQUEST_BUILDER.get();
}
}
24 changes: 24 additions & 0 deletions api/src/main/java/io/jsonwebtoken/security/HashAlgorithm.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import io.jsonwebtoken.Identifiable;

import java.io.InputStream;
import java.util.function.Consumer;

/**
* A {@link DigestAlgorithm} that computes and verifies digests without the use of a cryptographic key, such as for
Expand All @@ -42,4 +43,27 @@
* @since 0.12.0
*/
public interface HashAlgorithm extends DigestAlgorithm<Request<InputStream>, VerifyDigestRequest> {

default byte[] digest(Consumer<Request.Params<InputStream, ?>> c) {
Request.Builder<InputStream> b = Request.builder();
c.accept(b);
Request<InputStream> r = b.build();
return digest(r);
}

default byte[] digest(InputStream is) {
return digest(c -> c.payload(is));
}

default boolean verify(Consumer<VerifyDigestRequest.Params<?>> c) {
VerifyDigestRequest.Builder b = VerifyDigestRequest.builder();
c.accept(b);
VerifyDigestRequest r = b.build();
return verify(r);
}

default boolean verify(InputStream is, byte[] digest) {
return verify(c -> c.payload(is).digest(digest));
}

}
70 changes: 70 additions & 0 deletions api/src/main/java/io/jsonwebtoken/security/KeyRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

import io.jsonwebtoken.JweHeader;

import java.security.Key;

/**
* A request to a {@link KeyAlgorithm} to obtain the key necessary for AEAD encryption or decryption. The exact
* {@link AeadAlgorithm} that will be used is accessible via {@link #getEncryptionAlgorithm()}.
Expand Down Expand Up @@ -74,4 +76,72 @@ public interface KeyRequest<T> extends Request<T> {
* reading or writing any {@link KeyAlgorithm}-specific information.
*/
JweHeader getHeader();

/**
* Named parameters (setters) used to configure a {@link KeyRequest KeyRequest} instance.
*
* @param <T> the type of request payload. For an encryption key request, this will be the
* key used to obtain the encryption key. For a decryption key request, this will be the encrypted CEK
* (Content Encryption Key) ciphertext byte array.
* @param <M> the instance type returned for method chaining.
* @since JJWT_RELEASE_VERSION
*/
interface Params<T, M extends Params<T, M>> extends Request.Params<T, M> {

/**
* Sets the {@link JweHeader} that will be used to construct the final JWE header, available for
* reading or writing any {@link KeyAlgorithm}-specific information.
*
* <p>For an encryption key request, any <em>public</em> information specific to the called {@code KeyAlgorithm}
* implementation that is required to be transmitted in the JWE (such as an initialization vector,
* authentication tag or ephemeral key, etc) is expected to be added to this header. Although the header is
* checked for authenticity and integrity, it itself is <em>not</em> encrypted, so
* {@link KeyAlgorithm}s should never place any secret or private information in the header.</p>
*
* <p>For a decryption request, any public information necessary by the called {@link KeyAlgorithm}
* (such as an initialization vector, authentication tag, ephemeral key, etc) is expected to be available in
* this header.</p>
*
* @param header the {@link JweHeader} that will be used to construct the final JWE header, available for
* reading or writing any {@link KeyAlgorithm}-specific information.
* @return the instance for method chaining.
*/
M header(JweHeader header);

/**
* Sets the {@link AeadAlgorithm} that will be called for encryption or decryption after processing the
* {@code KeyRequest}. {@link KeyAlgorithm} implementations that generate an ephemeral {@code SecretKey} to use
* as what the <a href="https://www.rfc-editor.org/rfc/rfc7516.html#section-2">JWE specification calls</a> a
* &quot;Content Encryption Key (CEK)&quot; should call the {@code AeadAlgorithm}'s
* {@link AeadAlgorithm#key() key()} builder to create a key suitable for that exact {@code AeadAlgorithm}.
*
* @param alg the {@link AeadAlgorithm} that will be called for encryption or decryption after processing the
* {@code KeyRequest}.
* @return the instance for method chaining.
*/
M encryptionAlgorithm(AeadAlgorithm alg);
}

/**
* A builder for creating {@link KeyRequest}s used to get a JWE encryption key via
* {@link KeyAlgorithm#getEncryptionKey(KeyRequest)}.
*
* @param <K> the type of {@link java.security.Key Key} used to obtain the encryption key.
* @since JJWT_RELEASE_VERSION
*/
interface Builder<K extends Key> extends Params<K, Builder<K>>, io.jsonwebtoken.lang.Builder<KeyRequest<K>> {
}

/**
* Returns a new {@link KeyRequest.Builder} for creating immutable {@link KeyRequest}s used to get a JWE
* encryption key via {@link KeyAlgorithm#getEncryptionKey(KeyRequest)}.
*
* @return a new {@link KeyRequest.Builder} for creating immutable {@link KeyRequest}s used to get a JWE
* encryption key via {@link KeyAlgorithm#getEncryptionKey(KeyRequest)}.
* @since JJWT_RELEASE_VERSION
*/
@SuppressWarnings("unchecked")
static <K extends Key> KeyRequest.Builder<K> builder() {
return (KeyRequest.Builder<K>) Suppliers.KEY_REQUEST_BUILDER.get();
}
}
58 changes: 58 additions & 0 deletions api/src/main/java/io/jsonwebtoken/security/Request.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,62 @@ public interface Request<T> extends Message<T> {
* {@code null} if a default {@link SecureRandom} should be used.
*/
SecureRandom getSecureRandom();

/**
* Named parameters (setters) used to configure a {@link Request Request} instance.
*
* @param <T> the type of payload in the request.
* @param <M> the instance type returned for method chaining.
* @since JJWT_RELEASE_VERSION
*/
interface Params<T, M extends Params<T, M>> {

/**
* Sets the JCA provider that should be used for cryptographic operations during the request. A {@code null}
* value indicates that the JCA subsystem preferred provider should be used by default.
*
* @param provider the JCA provider that should be used for cryptographic operations during the request, or
* {@code null} to use the JCA subsystem preferred provider.
* @return the instance for method chaining.
*/
M provider(Provider provider);

/**
* Sets the {@code SecureRandom} to use when performing cryptographic operations during the request. A
* {@code null} value ensures a default {@link SecureRandom} should be used.
*
* @param random the {@code SecureRandom} to use when performing cryptographic operations during the request,
* or {@code null} if a default {@link SecureRandom} should be used.
* @return the instance for method chaining.
*/
M random(SecureRandom random);

/**
* Sets the request payload.
*
* @param payload the request payload.
* @return the instance for method chaining.
*/
M payload(T payload);
}

/**
* A builder for creating new immutable {@link Request} instances.
*
* @param <T> the type of payload in the request.
* @since JJWT_RELEASE_VERSION
*/
interface Builder<T> extends io.jsonwebtoken.lang.Builder<Request<T>>, Params<T, Builder<T>> {
}

/**
* Returns a new {@link Request.Builder} for creating immutable {@link Request}s.
*
* @return a new {@link Request.Builder} for creating immutable {@link Request}s.
* @since JJWT_RELEASE_VERSION
*/
@SuppressWarnings("unchecked")
static <T> Builder<T> builder() {
return (Builder<T>) Suppliers.REQUEST_BUILDER.get();
}
}
Loading