TestKeyMaterial.java revision 3002:9d6a9f65d2bf
1/* 2 * Copyright (c) 2005, 2010, 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 24/** 25 * @test 26 * @bug 6316539 27 * @summary Known-answer-test for TlsKeyMaterial generator 28 * @author Andreas Sterbenz 29 * @library .. 30 */ 31 32import java.io.*; 33import java.util.*; 34 35import java.security.Security; 36import java.security.Provider; 37 38import javax.crypto.KeyGenerator; 39import javax.crypto.SecretKey; 40 41import javax.crypto.spec.*; 42 43import sun.security.internal.spec.*; 44 45public class TestKeyMaterial extends PKCS11Test { 46 47 private static int PREFIX_LENGTH = "km-master: ".length(); 48 49 public static void main(String[] args) throws Exception { 50 main(new TestKeyMaterial()); 51 } 52 53 public void main(Provider provider) throws Exception { 54 if (provider.getService("KeyGenerator", "SunTlsKeyMaterial") == null) { 55 System.out.println("Provider does not support algorithm, skipping"); 56 return; 57 } 58 59 InputStream in = new FileInputStream(new File(BASE, "keymatdata.txt")); 60 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 61 62 int n = 0; 63 int lineNumber = 0; 64 65 byte[] master = null; 66 int major = 0; 67 int minor = 0; 68 byte[] clientRandom = null; 69 byte[] serverRandom = null; 70 String cipherAlgorithm = null; 71 int keyLength = 0; 72 int expandedKeyLength = 0; 73 int ivLength = 0; 74 int macLength = 0; 75 byte[] clientCipherBytes = null; 76 byte[] serverCipherBytes = null; 77 byte[] clientIv = null; 78 byte[] serverIv = null; 79 byte[] clientMacBytes = null; 80 byte[] serverMacBytes = null; 81 82 while (true) { 83 String line = reader.readLine(); 84 lineNumber++; 85 if (line == null) { 86 break; 87 } 88 if (line.startsWith("km-") == false) { 89 continue; 90 } 91 String data = line.substring(PREFIX_LENGTH); 92 if (line.startsWith("km-master:")) { 93 master = parse(data); 94 } else if (line.startsWith("km-major:")) { 95 major = Integer.parseInt(data); 96 } else if (line.startsWith("km-minor:")) { 97 minor = Integer.parseInt(data); 98 } else if (line.startsWith("km-crandom:")) { 99 clientRandom = parse(data); 100 } else if (line.startsWith("km-srandom:")) { 101 serverRandom = parse(data); 102 } else if (line.startsWith("km-cipalg:")) { 103 cipherAlgorithm = data; 104 } else if (line.startsWith("km-keylen:")) { 105 keyLength = Integer.parseInt(data); 106 } else if (line.startsWith("km-explen:")) { 107 expandedKeyLength = Integer.parseInt(data); 108 } else if (line.startsWith("km-ivlen:")) { 109 ivLength = Integer.parseInt(data); 110 } else if (line.startsWith("km-maclen:")) { 111 macLength = Integer.parseInt(data); 112 } else if (line.startsWith("km-ccipkey:")) { 113 clientCipherBytes = parse(data); 114 } else if (line.startsWith("km-scipkey:")) { 115 serverCipherBytes = parse(data); 116 } else if (line.startsWith("km-civ:")) { 117 clientIv = parse(data); 118 } else if (line.startsWith("km-siv:")) { 119 serverIv = parse(data); 120 } else if (line.startsWith("km-cmackey:")) { 121 clientMacBytes = parse(data); 122 } else if (line.startsWith("km-smackey:")) { 123 serverMacBytes = parse(data); 124 125 System.out.print("."); 126 n++; 127 128 KeyGenerator kg = 129 KeyGenerator.getInstance("SunTlsKeyMaterial", provider); 130 SecretKey masterKey = 131 new SecretKeySpec(master, "TlsMasterSecret"); 132 TlsKeyMaterialParameterSpec spec = 133 new TlsKeyMaterialParameterSpec(masterKey, major, minor, 134 clientRandom, serverRandom, cipherAlgorithm, 135 keyLength, expandedKeyLength, ivLength, macLength, 136 null, -1, -1); 137 138 kg.init(spec); 139 TlsKeyMaterialSpec result = 140 (TlsKeyMaterialSpec)kg.generateKey(); 141 match(lineNumber, clientCipherBytes, 142 result.getClientCipherKey(), cipherAlgorithm); 143 match(lineNumber, serverCipherBytes, 144 result.getServerCipherKey(), cipherAlgorithm); 145 match(lineNumber, clientIv, result.getClientIv(), ""); 146 match(lineNumber, serverIv, result.getServerIv(), ""); 147 match(lineNumber, clientMacBytes, result.getClientMacKey(), ""); 148 match(lineNumber, serverMacBytes, result.getServerMacKey(), ""); 149 150 } else { 151 throw new Exception("Unknown line: " + line); 152 } 153 } 154 if (n == 0) { 155 throw new Exception("no tests"); 156 } 157 in.close(); 158 System.out.println(); 159 System.out.println("OK: " + n + " tests"); 160 } 161 162 private static void stripParity(byte[] b) { 163 for (int i = 0; i < b.length; i++) { 164 b[i] &= 0xfe; 165 } 166 } 167 168 private static void match(int lineNumber, byte[] out, Object res, 169 String cipherAlgorithm) throws Exception { 170 if ((out == null) || (res == null)) { 171 if (out != res) { 172 throw new Exception("null mismatch line " + lineNumber); 173 } else { 174 return; 175 } 176 } 177 byte[] b; 178 if (res instanceof SecretKey) { 179 b = ((SecretKey)res).getEncoded(); 180 if (cipherAlgorithm.equalsIgnoreCase("DES") || 181 cipherAlgorithm.equalsIgnoreCase("DESede")) { 182 // strip DES parity bits before comparision 183 stripParity(out); 184 stripParity(b); 185 } 186 } else if (res instanceof IvParameterSpec) { 187 b = ((IvParameterSpec)res).getIV(); 188 } else { 189 throw new Exception(res.getClass().getName()); 190 } 191 if (Arrays.equals(out, b) == false) { 192 System.out.println(); 193 System.out.println("out: " + toString(out)); 194 System.out.println("b: " + toString(b)); 195 throw new Exception("mismatch line " + lineNumber); 196 } 197 } 198 199} 200