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 * </ul>
054 * 
055 * @author Vladimir Dzhuvinov
056 * @version 2015-06-29
057 */
058public abstract class DirectCryptoProvider extends BaseJWEProvider {
059
060
061        /**
062         * The supported JWE algorithms by the direct crypto provider class.
063         */
064        public static final Set<JWEAlgorithm> SUPPORTED_ALGORITHMS;
065
066
067        /**
068         * The supported encryption methods by the direct crypto provider
069         * class.
070         */
071        public static final Set<EncryptionMethod> SUPPORTED_ENCRYPTION_METHODS = ContentCryptoProvider.SUPPORTED_ENCRYPTION_METHODS;
072
073
074        static {
075                Set<JWEAlgorithm> algs = new LinkedHashSet<>();
076                algs.add(JWEAlgorithm.DIR);
077                SUPPORTED_ALGORITHMS = Collections.unmodifiableSet(algs);
078        }
079
080
081        /**
082         * Returns the compatible encryption methods for the specified Content
083         * Encryption Key (CEK) length.
084         *
085         * @param cekLength The CEK length in bits.
086         *
087         * @return The compatible encryption methods.
088         *
089         * @throws KeyLengthException If the CEK length is not compatible.
090         */
091        private static Set<EncryptionMethod> getCompatibleEncryptionMethods(final int cekLength)
092                throws KeyLengthException {
093
094                Set<EncryptionMethod> encs = ContentCryptoProvider.COMPATIBLE_ENCRYPTION_METHODS.get(cekLength);
095
096                if (encs == null) {
097                        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)");
098                }
099
100                return encs;
101        }
102
103
104        /**
105         * The Content Encryption Key (CEK).
106         */
107        private final SecretKey cek;
108
109
110        /**
111         * Creates a new direct encryption / decryption provider.
112         *
113         * @param cek The Content Encryption Key (CEK). Must be 128 bits (16
114         *            bytes), 192 bits (24 bytes), 256 bits (32 bytes), 384
115         *            bits (48 bytes) or 512 bits (64 bytes) long. Must not be
116         *            {@code null}.
117         *
118         * @throws KeyLengthException If the CEK length is not compatible.
119         */
120        protected DirectCryptoProvider(final SecretKey cek)
121                throws KeyLengthException {
122
123                super(SUPPORTED_ALGORITHMS, getCompatibleEncryptionMethods(ByteUtils.bitLength(cek.getEncoded())));
124
125                this.cek = cek;
126        }
127
128
129        /**
130         * Gets the Content Encryption Key (CEK).
131         *
132         * @return The key.
133         */
134        public SecretKey getKey() {
135
136                return cek;
137        }
138}