1 /*
   2  * Copyright (c) 2005, 2016, 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 6345251
  27  * @summary Basic known-answer-test for TlsPrf
  28  * @author Andreas Sterbenz
  29  * @library ..
  30  * @modules java.base/sun.security.internal.spec
  31  *          jdk.crypto.token
  32  * @run main/othervm TestPRF
  33  * @run main/othervm TestPRF sm policy
  34  */
  35 
  36 import java.io.BufferedReader;
  37 import java.nio.file.Files;
  38 import java.nio.file.Paths;
  39 import java.security.Provider;
  40 import java.util.Arrays;
  41 import javax.crypto.KeyGenerator;
  42 import javax.crypto.SecretKey;
  43 import javax.crypto.spec.SecretKeySpec;
  44 import sun.security.internal.spec.TlsPrfParameterSpec;
  45 
  46 public class TestPRF extends PKCS11Test {
  47 
  48     private static final int PREFIX_LENGTH = "prf-output: ".length();
  49 
  50     public static void main(String[] args) throws Exception {
  51         main(new TestPRF(), args);
  52     }
  53 
  54     @Override
  55     public void main(Provider provider) throws Exception {
  56         if (provider.getService("KeyGenerator", "SunTlsPrf") == null) {
  57             System.out.println("Provider does not support algorithm, skipping");
  58             return;
  59         }
  60 
  61         try (BufferedReader reader = Files.newBufferedReader(
  62                 Paths.get(BASE, "prfdata.txt"))) {
  63 
  64             int n = 0;
  65             int lineNumber = 0;
  66 
  67             byte[] secret = null;
  68             String label = null;
  69             byte[] seed = null;
  70             int length = 0;
  71             byte[] output = null;
  72 
  73             while (true) {
  74                 String line = reader.readLine();
  75                 lineNumber++;
  76                 if (line == null) {
  77                     break;
  78                 }
  79                 if (line.startsWith("prf-") == false) {
  80                     continue;
  81                 }
  82 
  83                 String data = line.substring(PREFIX_LENGTH);
  84                 if (line.startsWith("prf-secret:")) {
  85                     secret = parse(data);
  86                 } else if (line.startsWith("prf-label:")) {
  87                     label = data;
  88                 } else if (line.startsWith("prf-seed:")) {
  89                     seed = parse(data);
  90                 } else if (line.startsWith("prf-length:")) {
  91                     length = Integer.parseInt(data);
  92                 } else if (line.startsWith("prf-output:")) {
  93                     output = parse(data);
  94 
  95                     System.out.print(".");
  96                     n++;
  97 
  98                     KeyGenerator kg =
  99                         KeyGenerator.getInstance("SunTlsPrf", provider);
 100                     SecretKey inKey;
 101                     if (secret == null) {
 102                         inKey = null;
 103                     } else {
 104                         inKey = new SecretKeySpec(secret, "Generic");
 105                     }
 106                     TlsPrfParameterSpec spec =
 107                         new TlsPrfParameterSpec(inKey, label, seed, length,
 108                             null, -1, -1);
 109                     SecretKey key;
 110                     try {
 111                         kg.init(spec);
 112                         key = kg.generateKey();
 113                     } catch (Exception e) {
 114                         if (secret == null) {
 115                             // This fails on Solaris, but since we never call this
 116                             // API for this case in JSSE, ignore the failure.
 117                             // (SunJSSE uses the CKM_TLS_KEY_AND_MAC_DERIVE
 118                             // mechanism)
 119                             System.out.print("X");
 120                             continue;
 121                         }
 122                         System.out.println();
 123                         throw new Exception("Error on line: " + lineNumber, e);
 124                     }
 125                     byte[] enc = key.getEncoded();
 126                     if (Arrays.equals(output, enc) == false) {
 127                         System.out.println();
 128                         System.out.println("expected: " + toString(output));
 129                         System.out.println("actual:   " + toString(enc));
 130                         throw new Exception("mismatch line: " + lineNumber);
 131                     }
 132                 } else {
 133                     throw new Exception("Unknown line: " + line);
 134                 }
 135             }
 136             if (n == 0) {
 137                 throw new Exception("no tests");
 138             }
 139             System.out.println();
 140             System.out.println("OK: " + n + " tests");
 141         }
 142     }
 143 
 144 }