001/*
002 * nimbus-jose-jwt
003 *
004 * Copyright 2012-2016, Connect2id Ltd and contributors.
005 *
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
007 * this file except in compliance with the License. You may obtain a copy of the
008 * License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software distributed
013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations under the License.
016 */
017
018package com.nimbusds.jose.crypto.impl;
019
020
021import java.util.Collections;
022import java.util.LinkedHashSet;
023import java.util.Set;
024import javax.crypto.SecretKey;
025
026import com.nimbusds.jose.EncryptionMethod;
027import com.nimbusds.jose.JWEAlgorithm;
028import com.nimbusds.jose.KeyLengthException;
029import com.nimbusds.jose.util.ByteUtils;
030
031
032/**
033 * The base abstract class for direct encrypters and decrypters of
034 * {@link com.nimbusds.jose.JWEObject JWE objects} with a shared symmetric key.
035 *
036 * <p>Supports the following key management algorithms:
037 *
038 * <ul>
039 *     <li>{@link com.nimbusds.jose.JWEAlgorithm#DIR}
040 * </ul>
041 *
042 * <p>Supports the following content encryption algorithms:
043 *
044 * <ul>
045 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256}
046 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A192CBC_HS384}
047 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512}
048 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A128GCM}
049 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A192GCM}
050 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A256GCM}
051 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A128CBC_HS256_DEPRECATED}
052 *     <li>{@link com.nimbusds.jose.EncryptionMethod#A256CBC_HS512_DEPRECATED}
053 *     <li>{@link com.nimbusds.jose.EncryptionMethod#XC20P}
054 * </ul>
055 * 
056 * @author Vladimir Dzhuvinov
057 * @version 2015-06-29
058 */
059public abstract class DirectCryptoProvider extends BaseJWEProvider {
060
061
062        /**
063         * The supported JWE algorithms by the direct crypto provider class.
064         */
065        public static final Set<JWEAlgorithm> SUPPORTED_ALGORITHMS;
066
067
068        /**
069         * The supported encryption methods by the direct crypto provider
070         * class.
071         */
072        public static final Set<EncryptionMethod> SUPPORTED_ENCRYPTION_METHODS = ContentCryptoProvider.SUPPORTED_ENCRYPTION_METHODS;
073
074
075        static {
076                Set<JWEAlgorithm> algs = new LinkedHashSet<>();
077                algs.add(JWEAlgorithm.DIR);
078                SUPPORTED_ALGORITHMS = Collections.unmodifiableSet(algs);
079        }
080
081
082        /**
083         * Returns the compatible encryption methods for the specified Content
084         * Encryption Key (CEK) length.
085         *
086         * @param cekLength The CEK length in bits.
087         *
088         * @return The compatible encryption methods.
089         *
090         * @throws KeyLengthException If the CEK length is not compatible.
091         */
092        private static Set<EncryptionMethod> getCompatibleEncryptionMethods(final int cekLength)
093                throws KeyLengthException {
094
095                Set<EncryptionMethod> encs = ContentCryptoProvider.COMPATIBLE_ENCRYPTION_METHODS.get(cekLength);
096
097                if (encs == null) {
098                        throw new KeyLengthException("The Content Encryption Key length must be 128 bits (16 bytes), 192 bits (24 bytes), 256 bits (32 bytes), 384 bits (48 bytes) or 512 bites (64 bytes)");
099                }
100
101                return encs;
102        }
103
104
105        /**
106         * The Content Encryption Key (CEK).
107         */
108        private final SecretKey cek;
109
110
111        /**
112         * Creates a new direct encryption / decryption provider.
113         *
114         * @param cek The Content Encryption Key (CEK). Must be 128 bits (16
115         *            bytes), 192 bits (24 bytes), 256 bits (32 bytes), 384
116         *            bits (48 bytes) or 512 bits (64 bytes) long. Must not be
117         *            {@code null}.
118         *
119         * @throws KeyLengthException If the CEK length is not compatible.
120         */
121        protected DirectCryptoProvider(final SecretKey cek)
122                throws KeyLengthException {
123
124                super(SUPPORTED_ALGORITHMS, getCompatibleEncryptionMethods(ByteUtils.bitLength(cek.getEncoded())));
125
126                this.cek = cek;
127        }
128
129
130        /**
131         * Gets the Content Encryption Key (CEK).
132         *
133         * @return The key.
134         */
135        public SecretKey getKey() {
136
137                return cek;
138        }
139}