1 /*
   2  * Copyright (c) 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 import jdk.test.lib.SecurityTools;
  25 import sun.security.util.ObjectIdentifier;
  26 
  27 import java.nio.file.Files;
  28 import java.nio.file.Path;
  29 import java.nio.file.Paths;
  30 import java.util.ArrayList;
  31 import java.util.List;
  32 
  33 import static jdk.testlibrary.security.DerUtils.*;
  34 import static sun.security.pkcs.ContentInfo.DATA_OID;
  35 import static sun.security.pkcs.ContentInfo.ENCRYPTED_DATA_OID;
  36 import static sun.security.x509.AlgorithmId.*;
  37 
  38 /*
  39  * @test
  40  * @bug 8076190
  41  * @library /lib/testlibrary /lib
  42  * @modules java.base/sun.security.pkcs
  43  *          java.base/sun.security.x509
  44  *          java.base/sun.security.util
  45  * @summary Checks the preferences order of pkcs12 params
  46  */
  47 public class ParamsPreferences {
  48 
  49     public static final void main(String[] args) throws Exception {
  50         int c = 0;
  51 
  52         // with storepass
  53         test(c++, "-", "-",
  54                 pbeWithSHA1AndRC2_40_oid, 50000,
  55                 pbeWithSHA1AndDESede_oid, 50000,
  56                 SHA_oid, 100000);
  57 
  58         // password-less with system property
  59         test(c++, "keystore.pkcs12.certProtectionAlgorithm", "NONE",
  60                 "keystore.pkcs12.macAlgorithm", "NONE",
  61                 "-", "-",
  62                 null, 0,
  63                 pbeWithSHA1AndDESede_oid, 50000,
  64                 null, 0);
  65 
  66         // password-less with security property
  67         test(c++, "-",
  68                 "keystore.pkcs12.certProtectionAlgorithm", "NONE",
  69                 "keystore.pkcs12.macAlgorithm", "NONE",
  70                 "-",
  71                 null, 0,
  72                 pbeWithSHA1AndDESede_oid, 50000,
  73                 null, 0);
  74 
  75         // back to with storepass by overriding security property with system property
  76         test(c++, "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede",
  77                 "keystore.pkcs12.macAlgorithm", "HmacPBESHA256",
  78                 "-",
  79                 "keystore.pkcs12.certProtectionAlgorithm", "NONE",
  80                 "keystore.pkcs12.macAlgorithm", "NONE",
  81                 "-",
  82                 pbeWithSHA1AndDESede_oid, 50000,
  83                 pbeWithSHA1AndDESede_oid, 50000,
  84                 SHA256_oid, 100000);
  85 
  86         // back to with storepass by using "" to force hardcoded default
  87         test(c++, "keystore.pkcs12.certProtectionAlgorithm", "",
  88                 "keystore.pkcs12.keyProtectionAlgorithm", "",
  89                 "keystore.pkcs12.macAlgorithm", "",
  90                 "-",
  91                 "keystore.pkcs12.certProtectionAlgorithm", "NONE",
  92                 "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
  93                 "keystore.pkcs12.macAlgorithm", "NONE",
  94                 "-",
  95                 pbeWithSHA1AndRC2_40_oid, 50000,
  96                 pbeWithSHA1AndDESede_oid, 50000,
  97                 SHA_oid, 100000);
  98 
  99         // change everything with system property
 100         test(c++, "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede",
 101                 "keystore.pkcs12.certPbeIterationCount", 3000,
 102                 "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
 103                 "keystore.pkcs12.keyPbeIterationCount", 4000,
 104                 "keystore.pkcs12.macAlgorithm", "HmacPBESHA256",
 105                 "keystore.pkcs12.macIterationCount", 2000,
 106                 "-", "-",
 107                 pbeWithSHA1AndDESede_oid, 3000,
 108                 pbeWithSHA1AndRC2_40_oid, 4000,
 109                 SHA256_oid, 2000);
 110 
 111         // change everything with security property
 112         test(c++, "-",
 113                 "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede",
 114                 "keystore.pkcs12.certPbeIterationCount", 3000,
 115                 "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
 116                 "keystore.pkcs12.keyPbeIterationCount", 4000,
 117                 "keystore.pkcs12.macAlgorithm", "HmacPBESHA256",
 118                 "keystore.pkcs12.macIterationCount", 2000,
 119                 "-",
 120                 pbeWithSHA1AndDESede_oid, 3000,
 121                 pbeWithSHA1AndRC2_40_oid, 4000,
 122                 SHA256_oid, 2000);
 123 
 124         // override security property with system property
 125         test(c++, "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndDESede",
 126                 "keystore.pkcs12.certPbeIterationCount", 13000,
 127                 "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
 128                 "keystore.pkcs12.keyPbeIterationCount", 14000,
 129                 "keystore.pkcs12.macAlgorithm", "HmacPBESHA256",
 130                 "keystore.pkcs12.macIterationCount", 12000,
 131                 "-",
 132                 "keystore.pkcs12.certProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
 133                 "keystore.pkcs12.certPbeIterationCount", 3000,
 134                 "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndDESede",
 135                 "keystore.pkcs12.keyPbeIterationCount", 4000,
 136                 "keystore.pkcs12.macAlgorithm", "HmacPBESHA1",
 137                 "keystore.pkcs12.macIterationCount", 2000,
 138                 "-",
 139                 pbeWithSHA1AndDESede_oid, 13000,
 140                 pbeWithSHA1AndRC2_40_oid, 14000,
 141                 SHA256_oid, 12000);
 142 
 143         // check keyProtectionAlgorithm old behavior. Preferences of
 144         // 4 different settings.
 145 
 146         test(c++, "-",
 147                 "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128",
 148                 "-",
 149                 pbeWithSHA1AndRC2_40_oid, 50000,
 150                 pbeWithSHA1AndRC2_128_oid, 50000,
 151                 SHA_oid, 100000);
 152         test(c++, "-",
 153                 "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128",
 154                 "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
 155                 "-",
 156                 pbeWithSHA1AndRC2_40_oid, 50000,
 157                 pbeWithSHA1AndRC2_40_oid, 50000,
 158                 SHA_oid, 100000);
 159         test(c++,
 160                 "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_128",
 161                 "-",
 162                 "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128",
 163                 "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
 164                 "-",
 165                 pbeWithSHA1AndRC2_40_oid, 50000,
 166                 pbeWithSHA1AndRC4_128_oid, 50000,
 167                 SHA_oid, 100000);
 168         test(c++,
 169                 "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_128",
 170                 "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC4_40",
 171                 "-",
 172                 "keystore.PKCS12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_128",
 173                 "keystore.pkcs12.keyProtectionAlgorithm", "PBEWithSHA1AndRC2_40",
 174                 "-",
 175                 pbeWithSHA1AndRC2_40_oid, 50000,
 176                 pbeWithSHA1AndRC4_40_oid, 50000,
 177                 SHA_oid, 100000);
 178     }
 179 
 180     /**
 181      * Run once.
 182      *
 183      * @param args an array containing system properties and values, "-",
 184      *             security properties and values, "-", expected certPbeAlg,
 185      *             certPbeIC, keyPbeAlg, keyPbeIc, macAlg, macIC.
 186      */
 187     static void test(int n, Object... args) throws Exception {
 188         boolean isSysProp = true;
 189         String cmd = "-keystore ks" + n + " -storetype PKCS12 -genkeypair -keyalg EC "
 190                 + "-alias a -dname CN=A -storepass changeit "
 191                 + "-J-Djava.security.properties=" + n + ".conf";
 192         List<String> jsConf = new ArrayList<>();
 193         for (int i = 0; i < args.length; i++) {
 194             if (isSysProp) {
 195                 if (args[i].equals("-")) {
 196                     isSysProp = false;
 197                 } else {
 198                     cmd += " -J-D" + args[i] + "=" + args[++i];
 199                 }
 200             } else {
 201                 if (args[i] == "-") {
 202                     Files.write(Paths.get(n + ".conf"), jsConf);
 203                     System.out.println("--------- test starts ----------");
 204                     System.out.println(jsConf);
 205                     SecurityTools.keytool(cmd).shouldHaveExitValue(0);
 206 
 207                     byte[] data = Files.readAllBytes(Paths.get("ks" + n));
 208 
 209                     // cert pbe alg + ic
 210                     if (args[i+1] == null) {
 211                         checkAlg(data, "110c10", DATA_OID);
 212                     } else {
 213                         checkAlg(data, "110c10", ENCRYPTED_DATA_OID);
 214                         checkAlg(data, "110c110110", (ObjectIdentifier)args[i+1]);
 215                         checkInt(data, "110c1101111", (int)args[i+2]);
 216                     }
 217 
 218                     // key pbe alg + ic
 219                     checkAlg(data, "110c010c01000", (ObjectIdentifier)args[i+3]);
 220                     checkInt(data, "110c010c010011", (int)args[i+4]);
 221 
 222                     // mac alg + ic
 223                     if (args[i+5] == null) {
 224                         shouldNotExist(data, "2");
 225                     } else {
 226                         checkAlg(data, "2000", (ObjectIdentifier)args[i+5]);
 227                         checkInt(data, "22", (int)args[i+6]);
 228                     }
 229                 } else {
 230                     jsConf.add(args[i] + "=" + args[++i]);
 231                 }
 232             }
 233         }
 234     }
 235 }