TestKeyMaterial.java revision 13549:88a7d9ea4ae2
1228944Sadrian/* 2228944Sadrian * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. 3228944Sadrian * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4228944Sadrian * 5228944Sadrian * This code is free software; you can redistribute it and/or modify it 6228944Sadrian * under the terms of the GNU General Public License version 2 only, as 7229126Sadrian * published by the Free Software Foundation. 8228944Sadrian * 9228944Sadrian * This code is distributed in the hope that it will be useful, but WITHOUT 10228944Sadrian * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11228944Sadrian * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12228944Sadrian * version 2 for more details (a copy is included in the LICENSE file that 13228944Sadrian * accompanied this code). 14228944Sadrian * 15228944Sadrian * You should have received a copy of the GNU General Public License version 16266331Sian * 2 along with this work; if not, write to the Free Software Foundation, 17228944Sadrian * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18228944Sadrian * 19266331Sian * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20228944Sadrian * or visit www.oracle.com if you need additional information or have any 21250385Sadrian * questions. 22266331Sian */ 23250385Sadrian 24250385Sadrian/** 25250385Sadrian * @test 26250385Sadrian * @bug 6316539 27228944Sadrian * @summary Known-answer-test for TlsKeyMaterial generator 28266331Sian * @author Andreas Sterbenz 29 * @library .. 30 * @modules java.base/sun.security.internal.spec 31 * @run main/othervm TestKeyMaterial 32 * @run main/othervm TestKeyMaterial sm policy 33 */ 34 35import java.io.BufferedReader; 36import java.nio.file.Files; 37import java.nio.file.Paths; 38import java.security.Provider; 39import java.util.Arrays; 40import javax.crypto.KeyGenerator; 41import javax.crypto.SecretKey; 42import javax.crypto.spec.IvParameterSpec; 43import javax.crypto.spec.SecretKeySpec; 44import sun.security.internal.spec.TlsKeyMaterialParameterSpec; 45import sun.security.internal.spec.TlsKeyMaterialSpec; 46 47public class TestKeyMaterial extends PKCS11Test { 48 49 private static final int PREFIX_LENGTH = "km-master: ".length(); 50 51 public static void main(String[] args) throws Exception { 52 main(new TestKeyMaterial(), args); 53 } 54 55 @Override 56 public void main(Provider provider) throws Exception { 57 if (provider.getService("KeyGenerator", "SunTlsKeyMaterial") == null) { 58 System.out.println("Provider does not support algorithm, skipping"); 59 return; 60 } 61 62 try (BufferedReader reader = Files.newBufferedReader( 63 Paths.get(BASE, "keymatdata.txt"))) { 64 65 int n = 0; 66 int lineNumber = 0; 67 68 byte[] master = null; 69 int major = 0; 70 int minor = 0; 71 byte[] clientRandom = null; 72 byte[] serverRandom = null; 73 String cipherAlgorithm = null; 74 int keyLength = 0; 75 int expandedKeyLength = 0; 76 int ivLength = 0; 77 int macLength = 0; 78 byte[] clientCipherBytes = null; 79 byte[] serverCipherBytes = null; 80 byte[] clientIv = null; 81 byte[] serverIv = null; 82 byte[] clientMacBytes = null; 83 byte[] serverMacBytes = null; 84 85 while (true) { 86 String line = reader.readLine(); 87 lineNumber++; 88 if (line == null) { 89 break; 90 } 91 if (line.startsWith("km-") == false) { 92 continue; 93 } 94 String data = line.substring(PREFIX_LENGTH); 95 if (line.startsWith("km-master:")) { 96 master = parse(data); 97 } else if (line.startsWith("km-major:")) { 98 major = Integer.parseInt(data); 99 } else if (line.startsWith("km-minor:")) { 100 minor = Integer.parseInt(data); 101 } else if (line.startsWith("km-crandom:")) { 102 clientRandom = parse(data); 103 } else if (line.startsWith("km-srandom:")) { 104 serverRandom = parse(data); 105 } else if (line.startsWith("km-cipalg:")) { 106 cipherAlgorithm = data; 107 } else if (line.startsWith("km-keylen:")) { 108 keyLength = Integer.parseInt(data); 109 } else if (line.startsWith("km-explen:")) { 110 expandedKeyLength = Integer.parseInt(data); 111 } else if (line.startsWith("km-ivlen:")) { 112 ivLength = Integer.parseInt(data); 113 } else if (line.startsWith("km-maclen:")) { 114 macLength = Integer.parseInt(data); 115 } else if (line.startsWith("km-ccipkey:")) { 116 clientCipherBytes = parse(data); 117 } else if (line.startsWith("km-scipkey:")) { 118 serverCipherBytes = parse(data); 119 } else if (line.startsWith("km-civ:")) { 120 clientIv = parse(data); 121 } else if (line.startsWith("km-siv:")) { 122 serverIv = parse(data); 123 } else if (line.startsWith("km-cmackey:")) { 124 clientMacBytes = parse(data); 125 } else if (line.startsWith("km-smackey:")) { 126 serverMacBytes = parse(data); 127 128 System.out.print("."); 129 n++; 130 131 KeyGenerator kg = 132 KeyGenerator.getInstance("SunTlsKeyMaterial", provider); 133 SecretKey masterKey = 134 new SecretKeySpec(master, "TlsMasterSecret"); 135 TlsKeyMaterialParameterSpec spec = 136 new TlsKeyMaterialParameterSpec(masterKey, major, minor, 137 clientRandom, serverRandom, cipherAlgorithm, 138 keyLength, expandedKeyLength, ivLength, macLength, 139 null, -1, -1); 140 141 kg.init(spec); 142 TlsKeyMaterialSpec result = 143 (TlsKeyMaterialSpec)kg.generateKey(); 144 match(lineNumber, clientCipherBytes, 145 result.getClientCipherKey(), cipherAlgorithm); 146 match(lineNumber, serverCipherBytes, 147 result.getServerCipherKey(), cipherAlgorithm); 148 match(lineNumber, clientIv, result.getClientIv(), ""); 149 match(lineNumber, serverIv, result.getServerIv(), ""); 150 match(lineNumber, clientMacBytes, result.getClientMacKey(), ""); 151 match(lineNumber, serverMacBytes, result.getServerMacKey(), ""); 152 153 } else { 154 throw new Exception("Unknown line: " + line); 155 } 156 } 157 if (n == 0) { 158 throw new Exception("no tests"); 159 } 160 System.out.println(); 161 System.out.println("OK: " + n + " tests"); 162 } 163 } 164 165 private static void stripParity(byte[] b) { 166 for (int i = 0; i < b.length; i++) { 167 b[i] &= 0xfe; 168 } 169 } 170 171 private static void match(int lineNumber, byte[] out, Object res, 172 String cipherAlgorithm) throws Exception { 173 if ((out == null) || (res == null)) { 174 if (out != res) { 175 throw new Exception("null mismatch line " + lineNumber); 176 } else { 177 return; 178 } 179 } 180 byte[] b; 181 if (res instanceof SecretKey) { 182 b = ((SecretKey)res).getEncoded(); 183 if (cipherAlgorithm.equalsIgnoreCase("DES") || 184 cipherAlgorithm.equalsIgnoreCase("DESede")) { 185 // strip DES parity bits before comparision 186 stripParity(out); 187 stripParity(b); 188 } 189 } else if (res instanceof IvParameterSpec) { 190 b = ((IvParameterSpec)res).getIV(); 191 } else { 192 throw new Exception(res.getClass().getName()); 193 } 194 if (Arrays.equals(out, b) == false) { 195 System.out.println(); 196 System.out.println("out: " + toString(out)); 197 System.out.println("b: " + toString(b)); 198 throw new Exception("mismatch line " + lineNumber); 199 } 200 } 201 202} 203