1/* 2 * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24import java.security.AlgorithmParameters; 25import java.util.Arrays; 26import javax.crypto.SecretKey; 27import javax.crypto.Cipher; 28import javax.crypto.KeyGenerator; 29import javax.crypto.SealedObject; 30 31/* 32 * @test 33 * @bug 8048596 34 * @summary Check if the seal/unseal feature works properly in AEAD/GCM mode. 35 */ 36public class SealedObjectTest { 37 38 private static final String AES = "AES"; 39 private static final String TRANSFORMATION = "AES/GCM/NoPadding"; 40 private static final String PROVIDER = "SunJCE"; 41 private static final int KEY_LENGTH = 128; 42 43 public static void main(String[] args) throws Exception { 44 doTest(); 45 } 46 47 /* 48 * Run the test: 49 * - init a cipher with AES/GCM/NoPadding transformation 50 * - seal an object 51 * - check if we can't seal it again with the same key/IV 52 * - unseal the object using different methods of SealedObject class 53 * - check if the original and sealed objects are equal 54 */ 55 static void doTest() throws Exception { 56 // init a secret Key 57 KeyGenerator kg = KeyGenerator.getInstance(AES, PROVIDER); 58 kg.init(KEY_LENGTH); 59 SecretKey key = kg.generateKey(); 60 61 // initialization 62 Cipher cipher = Cipher.getInstance(TRANSFORMATION, PROVIDER); 63 cipher.init(Cipher.ENCRYPT_MODE, key); 64 AlgorithmParameters params = cipher.getParameters(); 65 66 // seal an object 67 SealedObject so = new SealedObject(key, cipher); 68 try { 69 // check if we can't seal it again with the same key/IV 70 so = new SealedObject(key, cipher); 71 throw new RuntimeException( 72 "FAILED: expected IllegalStateException hasn't " 73 + "been thrown"); 74 } catch (IllegalStateException ise) { 75 System.out.println("Expected exception when seal it again with" 76 + " the same key/IV: " + ise); 77 } 78 79 // unseal the object using getObject(Cipher) and compare 80 cipher.init(Cipher.DECRYPT_MODE, key, params); 81 SecretKey unsealedKey = (SecretKey) so.getObject(cipher); 82 assertKeysSame(unsealedKey, key, "SealedObject.getObject(Cipher)"); 83 84 // unseal the object using getObject(Key) and compare 85 unsealedKey = (SecretKey) so.getObject(key); 86 assertKeysSame(unsealedKey, key, "SealedObject.getObject(Key)"); 87 88 // unseal the object using getObject(Key, String) and compare 89 unsealedKey = (SecretKey) so.getObject(key, PROVIDER); 90 91 assertKeysSame(unsealedKey, key, 92 "SealedObject.getObject(Key, String)"); 93 } 94 95 /** 96 * Compare two SecretKey objects. 97 * 98 * @param key1 first key 99 * @param key2 second key 100 * @param meth method that was used for unsealing the SecretKey object 101 * @return true if key1 and key2 are the same, false otherwise. 102 */ 103 static void assertKeysSame(SecretKey key1, SecretKey key2, String meth) { 104 if (!Arrays.equals(key1.getEncoded(), key2.getEncoded())) { 105 throw new RuntimeException( 106 "FAILED: original and unsealed objects aren't the same for " 107 + meth); 108 } 109 } 110} 111