1 /*
2  * Copyright (c) 2005, 2018, 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 8136355
27  * @summary Known-answer-test for TlsMasterSecret generator
28  * @author Andreas Sterbenz
29  * @library /test/lib ..
30  * @modules java.base/sun.security.internal.interfaces
31  *          java.base/sun.security.internal.spec
32  *          jdk.crypto.cryptoki
33  * @run main/othervm TestMasterSecret
34  * @run main/othervm TestMasterSecret sm TestMasterSecret.policy
35  */
36 
37 import java.io.BufferedReader;
38 import java.nio.file.Files;
39 import java.nio.file.Paths;
40 import java.security.Provider;
41 import java.security.InvalidAlgorithmParameterException;
42 import java.util.Arrays;
43 import javax.crypto.KeyGenerator;
44 import javax.crypto.SecretKey;
45 import javax.crypto.spec.SecretKeySpec;
46 import sun.security.internal.interfaces.TlsMasterSecret;
47 import sun.security.internal.spec.TlsMasterSecretParameterSpec;
48 
49 public class TestMasterSecret extends PKCS11Test {
50 
51     private static final int PREFIX_LENGTH = "m-premaster:  ".length();
52 
main(String[] args)53     public static void main(String[] args) throws Exception {
54         main(new TestMasterSecret(), args);
55     }
56 
57     @Override
main(Provider provider)58     public void main(Provider provider) throws Exception {
59         if (provider.getService("KeyGenerator", "SunTlsMasterSecret") == null) {
60             System.out.println("Not supported by provider, skipping");
61             return;
62         }
63 
64         try (BufferedReader reader = Files.newBufferedReader(
65                 Paths.get(BASE, "masterdata.txt"))) {
66 
67             int n = 0;
68             int lineNumber = 0;
69 
70             String algorithm = null;
71             byte[] premaster = null;
72             byte[] clientRandom = null;
73             byte[] serverRandom = null;
74             int protoMajor = 0;
75             int protoMinor = 0;
76             int preMajor = 0;
77             int preMinor = 0;
78             byte[] master = null;
79 
80             while (true) {
81                 String line = reader.readLine();
82                 lineNumber++;
83                 if (line == null) {
84                     break;
85                 }
86                 if (line.startsWith("m-") == false) {
87                     continue;
88                 }
89                 String data = line.substring(PREFIX_LENGTH);
90                 if (line.startsWith("m-algorithm:")) {
91                     algorithm = data;
92                 } else if (line.startsWith("m-premaster:")) {
93                     premaster = parse(data);
94                 } else if (line.startsWith("m-crandom:")) {
95                     clientRandom = parse(data);
96                 } else if (line.startsWith("m-srandom:")) {
97                     serverRandom = parse(data);
98                 } else if (line.startsWith("m-protomajor:")) {
99                     protoMajor = Integer.parseInt(data);
100                 } else if (line.startsWith("m-protominor:")) {
101                     protoMinor = Integer.parseInt(data);
102                 } else if (line.startsWith("m-premajor:")) {
103                     preMajor = Integer.parseInt(data);
104                 } else if (line.startsWith("m-preminor:")) {
105                     preMinor = Integer.parseInt(data);
106                 } else if (line.startsWith("m-master:")) {
107                     master = parse(data);
108 
109                     System.out.print(".");
110                     n++;
111 
112                     KeyGenerator kg =
113                         KeyGenerator.getInstance("SunTlsMasterSecret", provider);
114                     SecretKey premasterKey =
115                         new SecretKeySpec(premaster, algorithm);
116                     TlsMasterSecretParameterSpec spec =
117                         new TlsMasterSecretParameterSpec(premasterKey,
118                             protoMajor, protoMinor, clientRandom, serverRandom,
119                             null, -1, -1);
120 
121                     try {
122                         kg.init(spec);
123                         TlsMasterSecret key = (TlsMasterSecret)kg.generateKey();
124                         byte[] enc = key.getEncoded();
125                         if (Arrays.equals(master, enc) == false) {
126                             throw new Exception("mismatch line: " + lineNumber);
127                         }
128                         if ((preMajor != key.getMajorVersion()) ||
129                                 (preMinor != key.getMinorVersion())) {
130                            throw new Exception("version mismatch line: " + lineNumber);
131                         }
132                     } catch (InvalidAlgorithmParameterException iape) {
133                         // SSLv3 support is removed in S12
134                         if (preMajor == 3 && preMinor == 0) {
135                             System.out.println("Skip testing SSLv3");
136                             continue;
137                         }
138                     }
139                 } else {
140                     throw new Exception("Unknown line: " + line);
141                 }
142             }
143             if (n == 0) {
144                 throw new Exception("no tests");
145             }
146             System.out.println();
147             System.out.println("OK: " + n + " tests");
148         }
149     }
150 
151 }
152