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