26 * @bug 6316539 |
26 * @bug 6316539 |
27 * @summary Known-answer-test for TlsKeyMaterial generator |
27 * @summary Known-answer-test for TlsKeyMaterial generator |
28 * @author Andreas Sterbenz |
28 * @author Andreas Sterbenz |
29 * @library .. |
29 * @library .. |
30 * @modules java.base/sun.security.internal.spec |
30 * @modules java.base/sun.security.internal.spec |
|
31 * @run main/othervm TestKeyMaterial |
|
32 * @run main/othervm TestKeyMaterial sm policy |
31 */ |
33 */ |
32 |
34 |
33 import java.io.*; |
35 import java.io.BufferedReader; |
34 import java.util.*; |
36 import java.nio.file.Files; |
35 |
37 import java.nio.file.Paths; |
36 import java.security.Security; |
|
37 import java.security.Provider; |
38 import java.security.Provider; |
38 |
39 import java.util.Arrays; |
39 import javax.crypto.KeyGenerator; |
40 import javax.crypto.KeyGenerator; |
40 import javax.crypto.SecretKey; |
41 import javax.crypto.SecretKey; |
41 |
42 import javax.crypto.spec.IvParameterSpec; |
42 import javax.crypto.spec.*; |
43 import javax.crypto.spec.SecretKeySpec; |
43 |
44 import sun.security.internal.spec.TlsKeyMaterialParameterSpec; |
44 import sun.security.internal.spec.*; |
45 import sun.security.internal.spec.TlsKeyMaterialSpec; |
45 |
46 |
46 public class TestKeyMaterial extends PKCS11Test { |
47 public class TestKeyMaterial extends PKCS11Test { |
47 |
48 |
48 private static int PREFIX_LENGTH = "km-master: ".length(); |
49 private static final int PREFIX_LENGTH = "km-master: ".length(); |
49 |
50 |
50 public static void main(String[] args) throws Exception { |
51 public static void main(String[] args) throws Exception { |
51 main(new TestKeyMaterial()); |
52 main(new TestKeyMaterial(), args); |
52 } |
53 } |
53 |
54 |
|
55 @Override |
54 public void main(Provider provider) throws Exception { |
56 public void main(Provider provider) throws Exception { |
55 if (provider.getService("KeyGenerator", "SunTlsKeyMaterial") == null) { |
57 if (provider.getService("KeyGenerator", "SunTlsKeyMaterial") == null) { |
56 System.out.println("Provider does not support algorithm, skipping"); |
58 System.out.println("Provider does not support algorithm, skipping"); |
57 return; |
59 return; |
58 } |
60 } |
59 |
61 |
60 InputStream in = new FileInputStream(new File(BASE, "keymatdata.txt")); |
62 try (BufferedReader reader = Files.newBufferedReader( |
61 BufferedReader reader = new BufferedReader(new InputStreamReader(in)); |
63 Paths.get(BASE, "keymatdata.txt"))) { |
62 |
64 |
63 int n = 0; |
65 int n = 0; |
64 int lineNumber = 0; |
66 int lineNumber = 0; |
65 |
67 |
66 byte[] master = null; |
68 byte[] master = null; |
67 int major = 0; |
69 int major = 0; |
68 int minor = 0; |
70 int minor = 0; |
69 byte[] clientRandom = null; |
71 byte[] clientRandom = null; |
70 byte[] serverRandom = null; |
72 byte[] serverRandom = null; |
71 String cipherAlgorithm = null; |
73 String cipherAlgorithm = null; |
72 int keyLength = 0; |
74 int keyLength = 0; |
73 int expandedKeyLength = 0; |
75 int expandedKeyLength = 0; |
74 int ivLength = 0; |
76 int ivLength = 0; |
75 int macLength = 0; |
77 int macLength = 0; |
76 byte[] clientCipherBytes = null; |
78 byte[] clientCipherBytes = null; |
77 byte[] serverCipherBytes = null; |
79 byte[] serverCipherBytes = null; |
78 byte[] clientIv = null; |
80 byte[] clientIv = null; |
79 byte[] serverIv = null; |
81 byte[] serverIv = null; |
80 byte[] clientMacBytes = null; |
82 byte[] clientMacBytes = null; |
81 byte[] serverMacBytes = null; |
83 byte[] serverMacBytes = null; |
82 |
84 |
83 while (true) { |
85 while (true) { |
84 String line = reader.readLine(); |
86 String line = reader.readLine(); |
85 lineNumber++; |
87 lineNumber++; |
86 if (line == null) { |
88 if (line == null) { |
87 break; |
89 break; |
88 } |
90 } |
89 if (line.startsWith("km-") == false) { |
91 if (line.startsWith("km-") == false) { |
90 continue; |
92 continue; |
91 } |
93 } |
92 String data = line.substring(PREFIX_LENGTH); |
94 String data = line.substring(PREFIX_LENGTH); |
93 if (line.startsWith("km-master:")) { |
95 if (line.startsWith("km-master:")) { |
94 master = parse(data); |
96 master = parse(data); |
95 } else if (line.startsWith("km-major:")) { |
97 } else if (line.startsWith("km-major:")) { |
96 major = Integer.parseInt(data); |
98 major = Integer.parseInt(data); |
97 } else if (line.startsWith("km-minor:")) { |
99 } else if (line.startsWith("km-minor:")) { |
98 minor = Integer.parseInt(data); |
100 minor = Integer.parseInt(data); |
99 } else if (line.startsWith("km-crandom:")) { |
101 } else if (line.startsWith("km-crandom:")) { |
100 clientRandom = parse(data); |
102 clientRandom = parse(data); |
101 } else if (line.startsWith("km-srandom:")) { |
103 } else if (line.startsWith("km-srandom:")) { |
102 serverRandom = parse(data); |
104 serverRandom = parse(data); |
103 } else if (line.startsWith("km-cipalg:")) { |
105 } else if (line.startsWith("km-cipalg:")) { |
104 cipherAlgorithm = data; |
106 cipherAlgorithm = data; |
105 } else if (line.startsWith("km-keylen:")) { |
107 } else if (line.startsWith("km-keylen:")) { |
106 keyLength = Integer.parseInt(data); |
108 keyLength = Integer.parseInt(data); |
107 } else if (line.startsWith("km-explen:")) { |
109 } else if (line.startsWith("km-explen:")) { |
108 expandedKeyLength = Integer.parseInt(data); |
110 expandedKeyLength = Integer.parseInt(data); |
109 } else if (line.startsWith("km-ivlen:")) { |
111 } else if (line.startsWith("km-ivlen:")) { |
110 ivLength = Integer.parseInt(data); |
112 ivLength = Integer.parseInt(data); |
111 } else if (line.startsWith("km-maclen:")) { |
113 } else if (line.startsWith("km-maclen:")) { |
112 macLength = Integer.parseInt(data); |
114 macLength = Integer.parseInt(data); |
113 } else if (line.startsWith("km-ccipkey:")) { |
115 } else if (line.startsWith("km-ccipkey:")) { |
114 clientCipherBytes = parse(data); |
116 clientCipherBytes = parse(data); |
115 } else if (line.startsWith("km-scipkey:")) { |
117 } else if (line.startsWith("km-scipkey:")) { |
116 serverCipherBytes = parse(data); |
118 serverCipherBytes = parse(data); |
117 } else if (line.startsWith("km-civ:")) { |
119 } else if (line.startsWith("km-civ:")) { |
118 clientIv = parse(data); |
120 clientIv = parse(data); |
119 } else if (line.startsWith("km-siv:")) { |
121 } else if (line.startsWith("km-siv:")) { |
120 serverIv = parse(data); |
122 serverIv = parse(data); |
121 } else if (line.startsWith("km-cmackey:")) { |
123 } else if (line.startsWith("km-cmackey:")) { |
122 clientMacBytes = parse(data); |
124 clientMacBytes = parse(data); |
123 } else if (line.startsWith("km-smackey:")) { |
125 } else if (line.startsWith("km-smackey:")) { |
124 serverMacBytes = parse(data); |
126 serverMacBytes = parse(data); |
125 |
127 |
126 System.out.print("."); |
128 System.out.print("."); |
127 n++; |
129 n++; |
128 |
130 |
129 KeyGenerator kg = |
131 KeyGenerator kg = |
130 KeyGenerator.getInstance("SunTlsKeyMaterial", provider); |
132 KeyGenerator.getInstance("SunTlsKeyMaterial", provider); |
131 SecretKey masterKey = |
133 SecretKey masterKey = |
132 new SecretKeySpec(master, "TlsMasterSecret"); |
134 new SecretKeySpec(master, "TlsMasterSecret"); |
133 TlsKeyMaterialParameterSpec spec = |
135 TlsKeyMaterialParameterSpec spec = |
134 new TlsKeyMaterialParameterSpec(masterKey, major, minor, |
136 new TlsKeyMaterialParameterSpec(masterKey, major, minor, |
135 clientRandom, serverRandom, cipherAlgorithm, |
137 clientRandom, serverRandom, cipherAlgorithm, |
136 keyLength, expandedKeyLength, ivLength, macLength, |
138 keyLength, expandedKeyLength, ivLength, macLength, |
137 null, -1, -1); |
139 null, -1, -1); |
138 |
140 |
139 kg.init(spec); |
141 kg.init(spec); |
140 TlsKeyMaterialSpec result = |
142 TlsKeyMaterialSpec result = |
141 (TlsKeyMaterialSpec)kg.generateKey(); |
143 (TlsKeyMaterialSpec)kg.generateKey(); |
142 match(lineNumber, clientCipherBytes, |
144 match(lineNumber, clientCipherBytes, |
143 result.getClientCipherKey(), cipherAlgorithm); |
145 result.getClientCipherKey(), cipherAlgorithm); |
144 match(lineNumber, serverCipherBytes, |
146 match(lineNumber, serverCipherBytes, |
145 result.getServerCipherKey(), cipherAlgorithm); |
147 result.getServerCipherKey(), cipherAlgorithm); |
146 match(lineNumber, clientIv, result.getClientIv(), ""); |
148 match(lineNumber, clientIv, result.getClientIv(), ""); |
147 match(lineNumber, serverIv, result.getServerIv(), ""); |
149 match(lineNumber, serverIv, result.getServerIv(), ""); |
148 match(lineNumber, clientMacBytes, result.getClientMacKey(), ""); |
150 match(lineNumber, clientMacBytes, result.getClientMacKey(), ""); |
149 match(lineNumber, serverMacBytes, result.getServerMacKey(), ""); |
151 match(lineNumber, serverMacBytes, result.getServerMacKey(), ""); |
150 |
152 |
151 } else { |
153 } else { |
152 throw new Exception("Unknown line: " + line); |
154 throw new Exception("Unknown line: " + line); |
153 } |
155 } |
154 } |
156 } |
155 if (n == 0) { |
157 if (n == 0) { |
156 throw new Exception("no tests"); |
158 throw new Exception("no tests"); |
157 } |
159 } |
158 in.close(); |
160 System.out.println(); |
159 System.out.println(); |
161 System.out.println("OK: " + n + " tests"); |
160 System.out.println("OK: " + n + " tests"); |
162 } |
161 } |
163 } |
162 |
164 |
163 private static void stripParity(byte[] b) { |
165 private static void stripParity(byte[] b) { |
164 for (int i = 0; i < b.length; i++) { |
166 for (int i = 0; i < b.length; i++) { |
165 b[i] &= 0xfe; |
167 b[i] &= 0xfe; |