SecretKeysBasic.java revision 8729:0242fce0f717
1251876Speter/* 2251876Speter * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. 3251876Speter * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4251876Speter * 5251876Speter * This code is free software; you can redistribute it and/or modify it 6251876Speter * under the terms of the GNU General Public License version 2 only, as 7251876Speter * published by the Free Software Foundation. 8251876Speter * 9251876Speter * This code is distributed in the hope that it will be useful, but WITHOUT 10251876Speter * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11251876Speter * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12251876Speter * version 2 for more details (a copy is included in the LICENSE file that 13251876Speter * accompanied this code). 14251876Speter * 15251876Speter * You should have received a copy of the GNU General Public License version 16251876Speter * 2 along with this work; if not, write to the Free Software Foundation, 17251876Speter * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18251876Speter * 19251876Speter * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20251876Speter * or visit www.oracle.com if you need additional information or have any 21251876Speter * questions. 22251876Speter */ 23251876Speter 24251876Speterimport java.io.*; 25251876Speterimport java.util.*; 26251876Speterimport java.security.*; 27251876Speterimport javax.crypto.*; 28251876Speterimport javax.crypto.spec.*; 29251876Speterimport javax.xml.bind.DatatypeConverter; 30251876Speter 31251876Speterpublic class SecretKeysBasic extends PKCS11Test { 32251876Speter 33251876Speter private static final char SEP = File.separatorChar; 34251876Speter private static char[] tokenPwd; 35251876Speter private static final char[] nssPwd = 36251876Speter new char[]{'t', 'e', 's', 't', '1', '2'}; 37251876Speter private static final char[] solarisPwd = 38251876Speter new char[]{'p', 'i', 'n'}; 39251876Speter private static SecretKey sk1; 40251876Speter private static SecretKey sk2; 41251876Speter private static SecretKey softkey; 42251876Speter private static KeyStore ks; 43251876Speter private static final String KS_TYPE = "PKCS11"; 44251876Speter private static Provider provider; 45251876Speter 46251876Speter public static void main(String[] args) throws Exception { 47251876Speter main(new SecretKeysBasic()); 48251876Speter } 49251876Speter 50251876Speter public void main(Provider p) throws Exception { 51251876Speter this.provider = p; 52251876Speter 53251876Speter // create secret key 54251876Speter byte[] keyVal = new byte[16]; 55251876Speter (new SecureRandom()).nextBytes(keyVal); 56251876Speter // NSS will throw CKR_HOST_MEMORY if calling C_DecryptInit w/ 57251876Speter // (keyVal[0] == 0) 58251876Speter if (keyVal[0] == 0) { 59251876Speter keyVal[0] = 1; 60251876Speter } 61251876Speter softkey = new SecretKeySpec(keyVal, "AES"); 62251876Speter dumpKey("softkey", softkey); 63251876Speter 64251876Speter KeyGenerator kg = KeyGenerator.getInstance("DESede", provider); 65251876Speter sk1 = kg.generateKey(); 66251876Speter dumpKey("skey1", sk1); 67251876Speter sk2 = kg.generateKey(); 68251876Speter dumpKey("skey2", sk2); 69251876Speter 70251876Speter String token = System.getProperty("TOKEN"); 71251876Speter 72251876Speter if (token == null || token.length() == 0) { 73251876Speter System.out.println("Error: missing TOKEN system property"); 74251876Speter throw new Exception("token arg required"); 75251876Speter } 76251876Speter 77251876Speter if ("nss".equals(token)) { 78251876Speter tokenPwd = nssPwd; 79251876Speter } else if ("solaris".equals(token)) { 80251876Speter tokenPwd = solarisPwd; 81251876Speter } 82251876Speter 83251876Speter int testnum = 1; 84251876Speter doTest(); 85251876Speter } 86251876Speter 87251876Speter private static boolean checkSecretKeyEntry(String alias, 88251876Speter SecretKey expected, 89251876Speter boolean saveBeforeCheck) 90251876Speter throws Exception { 91251876Speter 92251876Speter // A bug in NSS 3.12 (Mozilla bug 471665) causes AES key lengths 93251876Speter // to be read incorrectly. Checking for improper 16 byte length 94251876Speter // in key string. 95251876Speter if (isNSS(provider) && expected.getAlgorithm().equals("AES") && 96251876Speter (getNSSVersion() >= 3.12 && getNSSVersion() <= 3.122)) { 97251876Speter System.out.println("NSS 3.12 bug returns incorrect AES key "+ 98251876Speter "length breaking key storage. Aborting..."); 99251876Speter return true; 100251876Speter } 101251876Speter 102251876Speter if (saveBeforeCheck) { 103251876Speter ks.setKeyEntry(alias, expected, null, null); 104251876Speter } 105251876Speter SecretKey result = (SecretKey) (ks.getKey(alias, null)); 106251876Speter String keyEncFormat = result.getFormat(); 107251876Speter if (keyEncFormat == null) { 108251876Speter // sensitive or un-extractable keys - verify by encrypt/decrypt 109251876Speter byte[] data = new byte[64]; 110251876Speter Cipher c = 111251876Speter Cipher.getInstance(result.getAlgorithm() + "/CBC/NoPadding", 112251876Speter provider); 113251876Speter c.init(Cipher.ENCRYPT_MODE, expected); 114251876Speter byte[] encOut = c.doFinal(data); 115251876Speter c.init(Cipher.DECRYPT_MODE, result, c.getParameters()); 116251876Speter byte[] decOut = c.doFinal(encOut); 117251876Speter if (!Arrays.equals(data, decOut)) { 118251876Speter return false; 119251876Speter } 120251876Speter } else if (keyEncFormat.toUpperCase().equals("RAW")) { 121251876Speter if (!Arrays.equals(result.getEncoded(), expected.getEncoded())) { 122251876Speter dumpKey("\texpected:", expected); 123251876Speter dumpKey("\treturns:", result); 124251876Speter return false; 125251876Speter } 126251876Speter } 127251876Speter return true; 128251876Speter } 129251876Speter 130251876Speter private static void dumpKey(String info, SecretKey key) { 131251876Speter System.out.println(info + "> " + key); 132251876Speter System.out.println("\tALGO=" + key.getAlgorithm()); 133251876Speter if (key.getFormat() != null) { 134251876Speter System.out.println("\t[" + key.getFormat() + "] VALUE=" + 135251876Speter DatatypeConverter.printHexBinary(key.getEncoded())); 136251876Speter } else { 137251876Speter System.out.println("\tVALUE=n/a"); 138251876Speter } 139251876Speter } 140251876Speter 141251876Speter private static void doTest() throws Exception { 142251876Speter if (ks == null) { 143251876Speter ks = KeyStore.getInstance(KS_TYPE, provider); 144251876Speter ks.load(null, tokenPwd); 145251876Speter } 146251876Speter 147251876Speter System.out.println("Number of entries: " + ks.size()); 148251876Speter if (ks.size() != 0) { 149251876Speter System.out.println("Deleting entries under aliases: "); 150251876Speter for (Enumeration<String> aliases = ks.aliases(); 151251876Speter aliases.hasMoreElements();) { 152251876Speter String alias = aliases.nextElement(); 153251876Speter System.out.println("\t" + alias); 154251876Speter ks.deleteEntry(alias); 155251876Speter } 156251876Speter } 157251876Speter 158251876Speter String alias = "testSKey"; 159251876Speter 160251876Speter boolean testResult = checkSecretKeyEntry(alias, softkey, true); 161251876Speter if (!testResult) { 162251876Speter System.out.println("FAILURE: setKey() w/ softSecretKey failed"); 163251876Speter } 164251876Speter 165251876Speter if (!checkSecretKeyEntry(alias, sk1, true)) { 166251876Speter testResult = false; 167251876Speter System.out.println("FAILURE: setKey() w/ skey1 failed"); 168251876Speter } 169251876Speter if (!checkSecretKeyEntry(alias, sk2, true)) { 170251876Speter testResult = false; 171251876Speter System.out.println("FAILURE: setKey() w/ skey2 failed"); 172251876Speter } 173251876Speter 174251876Speter ks.store(null); 175251876Speter System.out.println("Reloading keystore..."); 176251876Speter 177251876Speter ks.load(null, "whatever".toCharArray()); 178251876Speter if (ks.size() != 1) { 179251876Speter System.out.println("FAILURE: reload#1 ks.size() != 1"); 180251876Speter } 181251876Speter if (!checkSecretKeyEntry(alias, sk2, false)) { 182251876Speter testResult = false; 183251876Speter System.out.println("FAILURE: reload#1 ks entry check failed"); 184251876Speter } 185251876Speter 186251876Speter ks.deleteEntry(alias); 187251876Speter ks.store(null); 188251876Speter 189251876Speter System.out.println("Reloading keystore..."); 190251876Speter ks.load(null, "whatever".toCharArray()); 191251876Speter if (ks.size() != 0) { 192251876Speter testResult = false; 193251876Speter System.out.println("FAILURE: reload#2 ks.size() != 0"); 194251876Speter } 195251876Speter if (!testResult) { 196251876Speter throw new Exception("One or more test failed!"); 197251876Speter } 198251876Speter } 199251876Speter} 200251876Speter