View Javadoc
1   /*
2    * The contents of this file are subject to the terms of the Common Development and
3    * Distribution License (the License). You may not use this file except in compliance with the
4    * License.
5    *
6    * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
7    * specific language governing permission and limitations under the License.
8    *
9    * When distributing Covered Software, include this CDDL Header Notice in each file and include
10   * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
11   * Header, with the fields enclosed by brackets [] replaced by your own identifying
12   * information: "Portions copyright [year] [name of copyright owner]".
13   *
14   * Copyright 2016 ForgeRock AS.
15   */
16  
17  package org.forgerock.json.jose.jwe.handlers.encryption;
18  
19  import java.security.Key;
20  import java.security.NoSuchAlgorithmException;
21  import java.security.SecureRandom;
22  
23  import org.forgerock.json.jose.exceptions.JweEncryptionException;
24  import org.forgerock.json.jose.jwe.EncryptionMethod;
25  import org.forgerock.json.jose.jwe.JweEncryption;
26  import org.forgerock.util.Reject;
27  
28  /**
29   * Handles the underlying {@link EncryptionMethod}.
30   */
31  abstract class ContentEncryptionHandler {
32      private static final String INITIALISATION_VECTOR_ALGORITHM = "SHA1PRNG";
33  
34      /**
35       * Returns an appropriate content encryption handler for the given encryption method.
36       *
37       * @param method the encryption method.
38       * @return an appropriate handler for the given encryption method.
39       */
40      static ContentEncryptionHandler getInstance(EncryptionMethod method) {
41          Reject.ifNull(method, "EncryptionMethod cannot be null");
42          switch (method) {
43          case A128CBC_HS256:
44          case A192CBC_HS384:
45          case A256CBC_HS512:
46              return new AESCBCHMACSHA2ContentEncryptionHandler(method);
47          case A128GCM:
48          case A192GCM:
49          case A256GCM:
50              return new AESGCMContentEncryptionHandler(method);
51          default:
52              throw new UnsupportedOperationException("Unsupported encryption method: " + method);
53          }
54      }
55  
56      abstract JweEncryption encrypt(Key key, byte[] iv, byte[] plainText, byte[] additionalData);
57  
58      abstract byte[] decrypt(Key key, byte[] iv, JweEncryption cipherText, byte[] additionalData);
59  
60      abstract Key generateEncryptionKey();
61  
62      byte[] generateInitialisationVector() {
63          try {
64              final int ivByteLength = getIVByteLength();
65              SecureRandom randomGen = SecureRandom.getInstance(INITIALISATION_VECTOR_ALGORITHM);
66  
67              byte[] bytes = new byte[ivByteLength];
68              randomGen.nextBytes(bytes);
69              return bytes;
70          } catch (NoSuchAlgorithmException e) {
71              throw new JweEncryptionException("Unsupported Algorithm, " + INITIALISATION_VECTOR_ALGORITHM, e);
72          }
73      }
74  
75      int getIVByteLength() {
76          return 128 / 8;
77      }
78  }