org.jose4j.jca.ProviderContext Maven / Gradle / Ivy
/*
* Copyright 2012-2017 Brian Campbell
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jose4j.jca;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
/**
* Allows for the caller of various JOSE and JWT functionality to specify
* a particular Java Cryptography Architecture provider by name for various
* cryptographic operations as well as a {@code SecureRandom} source of randomness.
*
* Use {@link #getSuppliedKeyProviderContext()} to indicate the provider to be used for cryptographic operations
* directly involve the key supplied by the caller.
* Use {@link #getGeneralProviderContext()}
* to indicate the provider to be used for other operations that do not directly involve the key supplied by the caller.
* Signing and verification are operations that use the supplied key as do
* key encryption and key agreement methods used to transmit or arrive at the content encryption key. Content encryption, however,
* is done with that content encryption key rather than the supplied key. So, other than when using direct (alg=dir) encryption,
* set the cipher provider name on the general provider to control the provider used in content encryption.
* For example, to specify the provider for an RSA signature when producing a JWS, create a new {@code ProviderContext} and set the name of the provider using
* {@link org.jose4j.jca.ProviderContext.Context#setSignatureProvider(String)} on the {@link Context} obtained from calling
* {@link #getSuppliedKeyProviderContext()}. To specify the provider for an HMAC when producing a JWS, set the name of the provider using
* {@link org.jose4j.jca.ProviderContext.Context#setMacProvider(String)} on the {@code Context} obtained from calling {@code getSuppliedKeyProviderContext()}.
* To specify the provider for decrypting a key with RSA when consuming a JWE, use {@link org.jose4j.jca.ProviderContext.Context#setCipherProvider(String)}
* on the Context obtained from {@code getSuppliedKeyProviderContext()}. To specify the provider for decrypting the content of the message, on the other hand,
* set the cipher provider on the Context obtained from {@code getGeneralProviderContext()}.
*
* A ProviderContext can be set on a {@link org.jose4j.jws.JsonWebSignature} or {@link org.jose4j.jwe.JsonWebEncryption} as well as a
* {@link org.jose4j.jwt.consumer.JwtConsumer} via the {@link org.jose4j.jwt.consumer.JwtConsumerBuilder}.
*
*
* @see org.jose4j.jwx.JsonWebStructure#setProviderContext(ProviderContext)
* @see org.jose4j.jwt.consumer.JwtConsumerBuilder#setJwsProviderContext(ProviderContext)
* @see org.jose4j.jwt.consumer.JwtConsumerBuilder#setJweProviderContext(ProviderContext)
*/
public class ProviderContext
{
private SecureRandom secureRandom;
private Context suppliedKeyProviderContext = new Context();
private Context generalProviderContext = new Context();
/**
* The Java Cryptography Architecture provider context to be used for operations
* that directly involve the key supplied by the caller.
* @return the {@code Context} object on which various provider preferences can be set
*/
public Context getSuppliedKeyProviderContext()
{
return suppliedKeyProviderContext;
}
/**
* The Java Cryptography Architecture provider context to be used for operations
* that do not directly involve the key supplied by the caller.
* @return the {@code Context} object on which various provider preferences can be set
*/
public Context getGeneralProviderContext()
{
return generalProviderContext;
}
/**
* Gets the secure random generator.
*
* @return The specific secure random generator if set, otherwise
* {@code null} for a default system one.
*/
public SecureRandom getSecureRandom()
{
return secureRandom;
}
/**
* Sets the secure random generator.
*
* @param secureRandom the SecureRandom to use or {@code null} for a default system one.
*/
public void setSecureRandom(SecureRandom secureRandom)
{
this.secureRandom = secureRandom;
}
/**
* Allows for a provider to be named for various operations.
* Not all operations are relevant in any particular JOSE context.
*/
public class Context
{
private String generalProvider;
private String keyPairGeneratorProvider;
private String keyAgreementProvider;
private String cipherProvider;
private KeyDecipherMode keyDecipherModeOverride;
private String signatureProvider;
private SignatureAlgorithmOverride signatureAlgorithmOverride;
private String macProvider;
private String messageDigestProvider;
private String keyFactoryProvider;
/**
* Gets the general JCA provider to be used for all relevant operations when
* a more specific one isn't set.
* @return the general JCA provider name
*/
public String getGeneralProvider()
{
return generalProvider;
}
/**
* Sets the general JCA provider to be used for all relevant operations when
* a more specific one isn't set. {@code null} to use the system configured
* providers.
*
* @param generalProvider the provider name
*/
public void setGeneralProvider(String generalProvider)
{
this.generalProvider = generalProvider;
}
/**
* Gets the JCA provider to be used for relevant {@code KeyPairGenerator} operations.
* @return the name of the provider or {@code null} for the system configured providers.
*/
public String getKeyPairGeneratorProvider()
{
return select(keyPairGeneratorProvider);
}
/**
* Sets the JCA provider to be used for relevant {@code KeyPairGenerator} operations.
* {@code null} to use the system configured providers.
*
* @param keyPairGeneratorProvider the provider name
*/
public void setKeyPairGeneratorProvider(String keyPairGeneratorProvider)
{
this.keyPairGeneratorProvider = keyPairGeneratorProvider;
}
/**
* Gets the JCA provider to be used for relevant {@code KeyAgreement} operations.
* @return the name of the provider or {@code null} for the system configured providers.
*/
public String getKeyAgreementProvider()
{
return select(keyAgreementProvider);
}
/**
* Sets the JCA provider to be used for relevant {@code KeyAgreement} operations.
* {@code null} to use the system configured providers.
*
* @param keyAgreementProvider the provider name
*/
public void setKeyAgreementProvider(String keyAgreementProvider)
{
this.keyAgreementProvider = keyAgreementProvider;
}
/**
* Gets the JCA provider to be used for relevant {@code Cipher} operations.
* @return the name of the provider or {@code null} for the system configured providers.
*/
public String getCipherProvider()
{
return select(cipherProvider);
}
/**
* Sets the JCA provider to be used for relevant {@code Cipher} operations.
* {@code null} to use the system configured providers.
*
* @param cipherProvider the provider name
*/
public void setCipherProvider(String cipherProvider)
{
this.cipherProvider = cipherProvider;
}
/**
* Gets the cipher mode to use when deciphering/decrypting/unwrapping an encrypted content encryption key.
* @return the mode
* @since 0.9.1
*/
public KeyDecipherMode getKeyDecipherModeOverride()
{
return keyDecipherModeOverride;
}
/**
* Sets the cipher mode to use when deciphering/decrypting/unwrapping an encrypted content encryption key.
* Using decrypt mode with certain JCA providers might be necessary for access to the raw bytes
* of the decrypted key, which are needed when decrypting the JWE Ciphertext.
* @param keyDecipherModeOverride the mode
* @since 0.9.1
*/
public void setKeyDecipherModeOverride(KeyDecipherMode keyDecipherModeOverride)
{
this.keyDecipherModeOverride = keyDecipherModeOverride;
}
/**
* Gets the JCA provider to be used for relevant {@code Signature} operations.
* @return the name of the provider or {@code null} for the system configured providers.
*/
public String getSignatureProvider()
{
return select(signatureProvider);
}
/**
* Sets the JCA provider to be used for relevant {@code Signature} operations.
* {@code null} to use the system configured providers.
*
* @param signatureProvider the provider name
*/
public void setSignatureProvider(String signatureProvider)
{
this.signatureProvider = signatureProvider;
}
/**
* Gets the algorithm info (name and parameter spec) to be used as overrides for relevant {@code Signature} operations.
* Null means no override is done and the normal algorithm details are used.
* @return the SignatureAlgorithmOverride object or null
*/
public SignatureAlgorithmOverride getSignatureAlgorithmOverride()
{
return signatureAlgorithmOverride;
}
/**
* Sets the algorithm info (name and parameter spec) to be used as overrides for relevant {@code Signature} operations.
* The need for this should be quite rare but it could be useful in cases where different providers are using different
* names for the same algorithm - and there have been some naming inconsistencies with RSAPSS where RSASSA-PSS + AlgorithmParameterSpec
* was used when PSS support was added to the default JRE but providers that supported PSS earlier used something like SHA256withRSAandMGF1).
*
* @param signatureAlgorithmOverride with the algorithm info. Null indicates to use the defaults (and is the default in and of itself).
*/
public void setSignatureAlgorithmOverride(SignatureAlgorithmOverride signatureAlgorithmOverride)
{
this.signatureAlgorithmOverride = signatureAlgorithmOverride;
}
/**
* Gets the JCA provider to be used for relevant {@code Mac} operations.
* @return of the Mac provider or {@code null} for the system configured providers.
*/
public String getMacProvider()
{
return select(macProvider);
}
/**
* Sets the JCA provider to be used for relevant {@code Mac} operations.
* {@code null} to use the system configured providers.
*
* @param macProvider the provider name
*/
public void setMacProvider(String macProvider)
{
this.macProvider = macProvider;
}
/**
* Gets the JCA provider to be used for relevant {@code MessageDigest} operations.
* @return the name of the provider or {@code null} for the system configured providers.
*/
public String getMessageDigestProvider()
{
return select(messageDigestProvider);
}
/**
* Sets the JCA provider to be used for relevant {@code MessageDigest} operations.
* {@code null} to use the system configured providers.
*
* @param messageDigestProvider the provider name
*/
public void setMessageDigestProvider(String messageDigestProvider)
{
this.messageDigestProvider = messageDigestProvider;
}
/**
* Gets the JCA provider to be used for relevant {@code KeyFactory} operations.
* @return the name of the provider or {@code null} for the system configured providers.
*/
public String getKeyFactoryProvider()
{
return select(keyFactoryProvider);
}
/**
* Sets the JCA provider to be used for relevant {@code KeyFactory} operations.
* {@code null} to use the system configured providers.
*
* @param keyFactoryProvider the provider name
*/
public void setKeyFactoryProvider(String keyFactoryProvider)
{
this.keyFactoryProvider = keyFactoryProvider;
}
private String select(String specificValue)
{
return specificValue == null ? generalProvider : specificValue;
}
}
/**
* Signature Algorithm info used to override normal defaults.
*/
public static class SignatureAlgorithmOverride
{
private String algorithmName;
private AlgorithmParameterSpec AlgorithmParameterSpec;
/**
* Create a new SignatureAlgorithmOverride instance
* @param algorithmName the algorithm name (e.g. SHA256withRSAandMGF1)
* @param aps the AlgorithmParameterSpec
*/
public SignatureAlgorithmOverride(String algorithmName, AlgorithmParameterSpec aps)
{
this.algorithmName = algorithmName;
AlgorithmParameterSpec = aps;
}
/**
* Gets the name of the signature algorithm to use in place of the normal default one.
* @return the signature algorithm name.
*/
public String getAlgorithmName()
{
return algorithmName;
}
/**
* Gets the AlgorithmParameterSpec to use in place of the normal default one.
* @return the AlgorithmParameterSpec.
*/
public AlgorithmParameterSpec getAlgorithmParameterSpec()
{
return AlgorithmParameterSpec;
}
}
/**
* The cipher mode to use when deciphering/decrypting/unwrapping an encrypted content encryption key
* @since 0.9.1
*/
public enum KeyDecipherMode {UNWRAP, DECRYPT}
}