001package com.nimbusds.jose.crypto.factories;
002
003
004import java.security.Key;
005import java.security.interfaces.ECPrivateKey;
006import java.security.interfaces.RSAPrivateKey;
007
008import javax.crypto.SecretKey;
009
010import net.jcip.annotations.ThreadSafe;
011
012import com.nimbusds.jose.*;
013import com.nimbusds.jose.crypto.*;
014import com.nimbusds.jose.proc.JWEDecrypterFactory;
015
016
017/**
018 * Default JSON Web Encryption (JWE) decrypter factory.
019 *
020 * <p>Supports all standard JWE algorithms implemented in the
021 * {@link com.nimbusds.jose.crypto} package.
022 *
023 * @author Vladimir Dzhuvinov
024 * @version 2015-06-29
025 */
026@ThreadSafe
027public class DefaultJWEDecrypterFactory implements JWEDecrypterFactory {
028
029
030        @Override
031        public JWEDecrypter createJWEDecrypter(final JWEHeader header, final Key key)
032                throws JOSEException {
033
034                if (RSADecrypter.SUPPORTED_ALGORITHMS.contains(header.getAlgorithm()) &&
035                        RSADecrypter.SUPPORTED_ENCRYPTION_METHODS.contains(header.getEncryptionMethod())) {
036
037                        if (!(key instanceof RSAPrivateKey)) {
038                                throw new KeyTypeException(RSAPrivateKey.class);
039                        }
040
041                        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)key;
042
043                        return new RSADecrypter(rsaPrivateKey);
044
045                } else if (ECDHDecrypter.SUPPORTED_ALGORITHMS.contains(header.getAlgorithm()) &&
046                        ECDHDecrypter.SUPPORTED_ENCRYPTION_METHODS.contains(header.getEncryptionMethod())) {
047
048                        if (!(key instanceof ECPrivateKey)) {
049                                throw new KeyTypeException(ECPrivateKey.class);
050                        }
051
052                        ECPrivateKey ecPrivateKey = (ECPrivateKey)key;
053                        return new ECDHDecrypter(ecPrivateKey);
054
055                } else if (DirectDecrypter.SUPPORTED_ALGORITHMS.contains(header.getAlgorithm()) &&
056                        DirectDecrypter.SUPPORTED_ENCRYPTION_METHODS.contains(header.getEncryptionMethod())) {
057
058                        if (!(key instanceof SecretKey)) {
059                                throw new KeyTypeException(SecretKey.class);
060                        }
061
062                        SecretKey aesKey = (SecretKey)key;
063                        DirectDecrypter directDecrypter =  new DirectDecrypter(aesKey);
064
065                        if (! directDecrypter.supportedEncryptionMethods().contains(header.getEncryptionMethod())) {
066                                throw new KeyLengthException(header.getEncryptionMethod().cekBitLength(), header.getEncryptionMethod());
067                        }
068
069                        return directDecrypter;
070
071                } else if (AESDecrypter.SUPPORTED_ALGORITHMS.contains(header.getAlgorithm()) &&
072                        AESDecrypter.SUPPORTED_ENCRYPTION_METHODS.contains(header.getEncryptionMethod())) {
073
074                        if (!(key instanceof SecretKey)) {
075                                throw new KeyTypeException(SecretKey.class);
076                        }
077
078                        SecretKey aesKey = (SecretKey)key;
079                        AESDecrypter aesDecrypter = new AESDecrypter(aesKey);
080
081                        if (! aesDecrypter.supportedJWEAlgorithms().contains(header.getAlgorithm())) {
082                                throw new KeyLengthException(header.getAlgorithm());
083                        }
084
085                        return aesDecrypter;
086
087                } else if (PasswordBasedDecrypter.SUPPORTED_ALGORITHMS.contains(header.getAlgorithm()) &&
088                        PasswordBasedDecrypter.SUPPORTED_ENCRYPTION_METHODS.contains(header.getEncryptionMethod())) {
089
090                        if (!(key instanceof SecretKey)) {
091                                throw new KeyTypeException(SecretKey.class);
092                        }
093
094                        byte[] password = key.getEncoded();
095                        return new PasswordBasedDecrypter(password);
096
097                } else {
098
099                        throw new JOSEException("Unsupported JWE algorithm or encryption method");
100                }
101        }
102}