1 /*
   2  * Copyright (c) 2012, 2015, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 import java.io.File;
  27 import java.io.IOException;
  28 import java.security.GeneralSecurityException;
  29 import java.security.Key;
  30 import java.security.KeyStore;
  31 import java.security.KeyStoreException;
  32 import java.security.NoSuchAlgorithmException;
  33 import java.security.PKCS12Attribute;
  34 import java.security.PrivateKey;
  35 import java.security.UnrecoverableEntryException;
  36 import java.security.cert.Certificate;
  37 import java.util.Arrays;
  38 import java.util.Set;
  39 import static java.lang.System.out;
  40 import java.util.HashSet;
  41 
  42 /**
  43  * @test
  44  * @bug 8048830
  45  * @summary Test store metadata attributes to PKCS12 keystore.
  46  * @library /lib/testlibrary ../
  47  * @run main MetadataStoreLoadTest
  48  */
  49 public class MetadataStoreLoadTest {
  50     private static final char[] PASSWORD = "passwd".toCharArray();
  51     private static final char[] KEY_PASSWORD = "keypasswd".toCharArray();
  52     private static final String ALIAS = "testkey_metadata";
  53     private static final String KEYSTORE = "ks.pkcs12";
  54     private static final String KESTORE_NEW = "ks-attr.pkcs12";
  55     private static final int MAX_HUGE_SIZE = 2000000;
  56     private static final String WORKING_DIRECTORY = System.getProperty(
  57             "test.classes", "." + File.separator);
  58     private static final String KEYSTORE_PATH = WORKING_DIRECTORY
  59             + File.separator + KEYSTORE;
  60     private static KeyStore.Entry.Attribute[] ATTR_SET;
  61 
  62     private void runTest() throws GeneralSecurityException,
  63             UnrecoverableEntryException, NoSuchAlgorithmException,
  64             KeyStoreException, IOException {
  65         storeAttrs();
  66         checkAttrs();
  67     }
  68 
  69     private void storeAttrs() throws UnrecoverableEntryException,
  70             GeneralSecurityException, NoSuchAlgorithmException,
  71             KeyStoreException, IOException {
  72         KeyStore ksIn = Utils.loadKeyStore(KEYSTORE_PATH,
  73                 Utils.KeyStoreType.pkcs12, PASSWORD);
  74         KeyStore ksAttr = KeyStore
  75                 .getInstance(Utils.KeyStoreType.pkcs12.name());
  76         ksAttr.load(null);
  77         Key key = ksIn.getKey(ALIAS, PASSWORD);
  78         Certificate cert = ksIn.getCertificate(ALIAS);
  79         Set<KeyStore.Entry.Attribute> attrs =
  80                 new HashSet<>(Arrays.asList(ATTR_SET));
  81         KeyStore.Entry e = new KeyStore.PrivateKeyEntry((PrivateKey) key,
  82                 new Certificate[]{cert}, attrs);
  83         ksAttr.setEntry(ALIAS, e, new KeyStore.PasswordProtection(
  84                 KEY_PASSWORD));
  85 
  86         out.println("Attributes before store:");
  87         e.getAttributes().stream().forEach((attr) -> {
  88             out.println(attr.getName() + ", '" + attr.getValue() + "'");
  89         });
  90         Utils.saveKeyStore(ksAttr, WORKING_DIRECTORY + File.separator
  91                 + KESTORE_NEW, PASSWORD);
  92     }
  93 
  94     private void checkAttrs() throws UnrecoverableEntryException,
  95             GeneralSecurityException, NoSuchAlgorithmException,
  96             KeyStoreException, IOException {
  97         KeyStore ks = Utils.loadKeyStore(WORKING_DIRECTORY
  98                 + File.separator
  99                 + KESTORE_NEW, Utils.KeyStoreType.pkcs12, PASSWORD);
 100         KeyStore.Entry keyStoreEntry = ks.getEntry(ALIAS,
 101                 new KeyStore.PasswordProtection(KEY_PASSWORD));
 102         out.println("Attributes after store:");
 103         //print attribute values
 104         keyStoreEntry.getAttributes().stream().forEach((attr) -> {
 105             out.println(attr.getName() + ", '" + attr.getValue() + "'");
 106         });
 107         Arrays.stream(ATTR_SET).forEach((attr) -> {
 108             if (!keyStoreEntry.getAttributes().contains(attr)) {
 109                 throw new RuntimeException("Entry doesn't contain attribute: ("
 110                         + attr.getName() + ", '" + attr.getValue() + "')");
 111             }
 112         });
 113     }
 114 
 115     public static void main(String[] args) throws Exception {
 116         MetadataStoreLoadTest test = new MetadataStoreLoadTest();
 117         test.setUp();
 118         test.runTest();
 119         out.println("Test Passed");
 120     }
 121 
 122     private void setUp() {
 123         Utils.createKeyStore(Utils.KeyStoreType.pkcs12, KEYSTORE_PATH, ALIAS);
 124         final String allCharsString = "`1234567890-=qwertyuiop[]asdfghjkl;'\\zx"
 125                 + "cvbnm,./!@#$%^&*()_+QWERTYUIOP{}ASDFGHJKL:|>ZXCVBNM<>?\"";
 126         StringBuilder sbPrintable = new StringBuilder();
 127         while (sbPrintable.length() < MAX_HUGE_SIZE) {
 128             sbPrintable.append(allCharsString);
 129         }
 130         final String hugePrintable = sbPrintable.toString();
 131         final String binaryString = "00:11:22:33:44:55:66:77:88:99:AA:BB:DD:"
 132                 + "EE:FF:";
 133         StringBuilder sbBinary = new StringBuilder();
 134         sbBinary.append(binaryString);
 135         while (sbBinary.length() < MAX_HUGE_SIZE) {
 136             sbBinary.append(":").append(binaryString);
 137         }
 138         sbBinary.insert(0, "[").append("]");
 139         final String hugeBinary = sbBinary.toString();
 140         ATTR_SET = new PKCS12Attribute[5];
 141         ATTR_SET[0] = new PKCS12Attribute("1.2.840.113549.1.9.1",
 142                 "Test email addres attr <test@oracle.com>");
 143         ATTR_SET[1] = new PKCS12Attribute("1.2.110.1", "not registered attr");
 144         ATTR_SET[2] = new PKCS12Attribute("1.2.110.2", hugePrintable);
 145         ATTR_SET[3] = new PKCS12Attribute("1.2.110.3", hugeBinary);
 146         ATTR_SET[4] = new PKCS12Attribute("1.2.110.2", " ");
 147     }
 148 }