8049237: Need new tests for X509V3 certificates
authorrhalade
Tue, 01 Sep 2015 16:27:28 -0700
changeset 32422 02ffe1771ea3
parent 32421 4a91a1bcd84f
child 32423 2342600f2ada
8049237: Need new tests for X509V3 certificates Reviewed-by: mullan, xuelei
jdk/test/sun/security/x509/X509CertImpl/V3Certificate.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/x509/X509CertImpl/V3Certificate.java	Tue Sep 01 16:27:28 2015 -0700
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import static java.lang.System.out;
+import java.security.InvalidKeyException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+import sun.misc.BASE64Encoder;
+import sun.security.util.BitArray;
+import sun.security.util.ObjectIdentifier;
+import sun.security.x509.*;
+
+/**
+ * @test
+ * @bug 8049237
+ * @modules java.base/sun.security.x509
+ *          java.base/sun.security.util
+ *          java.base/sun.misc
+ * @summary This test generates V3 certificate with all the supported
+ * extensions. Writes back the generated certificate in to a file and checks for
+ * equality with the original certificate.
+ */
+public class V3Certificate {
+
+    public static final String V3_FILE = "certV3";
+    public static final String V3_B64_FILE = "certV3.b64";
+
+    public static void main(String[] args) throws IOException,
+            NoSuchAlgorithmException, InvalidKeyException, CertificateException,
+            NoSuchProviderException, SignatureException {
+
+        boolean success = true;
+
+        success &= test("RSA", "SHA256withRSA", 2048);
+        success &= test("DSA", "SHA256withDSA", 2048);
+        success &= test("EC", "SHA256withECDSA", 384);
+
+        if (!success) {
+            throw new RuntimeException("At least one test case failed");
+        }
+    }
+
+    public static boolean test(String algorithm, String sigAlg, int keyLength)
+            throws IOException,
+            NoSuchAlgorithmException,
+            InvalidKeyException,
+            CertificateException,
+            NoSuchProviderException,
+            SignatureException {
+
+        byte[] issuerId = {1, 2, 3, 4, 5};
+        byte[] subjectId = {6, 7, 8, 9, 10};
+        boolean testResult = true;
+
+        // Subject and Issuer
+        X500Name subject = new X500Name("test", "Oracle", "Santa Clara",
+                "US");
+        X500Name issuer = subject;
+
+        // Generate keys and sign
+        KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm);
+        keyGen.initialize(keyLength);
+        KeyPair pair = keyGen.generateKeyPair();
+        PublicKey publicKey = pair.getPublic();
+        PrivateKey privateKey = pair.getPrivate();
+        MessageDigest md = MessageDigest.getInstance("SHA");
+        byte[] keyId = md.digest(publicKey.getEncoded());
+
+        Signature signature = Signature.getInstance(sigAlg);
+        signature.initSign(privateKey);
+
+        // Validity interval
+        Date firstDate = new Date();
+        Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("PST"));
+        cal.set(2014, 03, 10, 12, 30, 30);
+        Date lastDate = cal.getTime();
+        CertificateValidity interval = new CertificateValidity(firstDate,
+                lastDate);
+
+        // Certificate Info
+        X509CertInfo cert = new X509CertInfo();
+
+        cert.set(X509CertInfo.VERSION,
+                new CertificateVersion(CertificateVersion.V3));
+        cert.set(X509CertInfo.SERIAL_NUMBER,
+                new CertificateSerialNumber((int) (firstDate.getTime() / 1000)));
+        cert.set(X509CertInfo.ALGORITHM_ID,
+                new CertificateAlgorithmId(AlgorithmId.get(sigAlg)));
+        cert.set(X509CertInfo.SUBJECT, subject);
+        cert.set(X509CertInfo.KEY, new CertificateX509Key(publicKey));
+        cert.set(X509CertInfo.VALIDITY, interval);
+        cert.set(X509CertInfo.ISSUER, issuer);
+
+        cert.set(X509CertInfo.ISSUER_ID,
+                new UniqueIdentity(
+                        new BitArray(issuerId.length * 8 - 2, issuerId)));
+        cert.set(X509CertInfo.SUBJECT_ID, new UniqueIdentity(subjectId));
+
+        // Create Extensions
+        CertificateExtensions exts = new CertificateExtensions();
+
+        GeneralNameInterface mailInf = new RFC822Name("test@Oracle.com");
+        GeneralName mail = new GeneralName(mailInf);
+        GeneralNameInterface dnsInf = new DNSName("Oracle.com");
+        GeneralName dns = new GeneralName(dnsInf);
+        GeneralNameInterface uriInf = new URIName("http://www.Oracle.com");
+        GeneralName uri = new GeneralName(uriInf);
+
+        // localhost
+        byte[] address = new byte[]{127, 0, 0, 1};
+
+        GeneralNameInterface ipInf = new IPAddressName(address);
+        GeneralName ip = new GeneralName(ipInf);
+        int[] oidData = new int[]{1, 2, 3, 4};
+
+        GeneralNameInterface oidInf = new OIDName(new ObjectIdentifier(oidData));
+        GeneralName oid = new GeneralName(oidInf);
+
+        SubjectAlternativeNameExtension subjectName
+                = new SubjectAlternativeNameExtension();
+        IssuerAlternativeNameExtension issuerName
+                = new IssuerAlternativeNameExtension();
+
+        GeneralNames subjectNames
+                = (GeneralNames) subjectName.
+                get(SubjectAlternativeNameExtension.SUBJECT_NAME);
+
+        GeneralNames issuerNames
+                = (GeneralNames) issuerName.
+                get(IssuerAlternativeNameExtension.ISSUER_NAME);
+
+        subjectNames.add(mail);
+        subjectNames.add(dns);
+        subjectNames.add(uri);
+
+        issuerNames.add(ip);
+        issuerNames.add(oid);
+
+        cal.set(2000, 11, 15, 12, 30, 30);
+        lastDate = cal.getTime();
+        PrivateKeyUsageExtension pkusage
+                = new PrivateKeyUsageExtension(firstDate, lastDate);
+
+        KeyUsageExtension usage = new KeyUsageExtension();
+        usage.set(KeyUsageExtension.CRL_SIGN, true);
+        usage.set(KeyUsageExtension.DIGITAL_SIGNATURE, true);
+        usage.set(KeyUsageExtension.NON_REPUDIATION, true);
+
+        KeyIdentifier kid = new KeyIdentifier(keyId);
+        SerialNumber sn = new SerialNumber(42);
+        AuthorityKeyIdentifierExtension aki
+                = new AuthorityKeyIdentifierExtension(kid, subjectNames, sn);
+
+        SubjectKeyIdentifierExtension ski
+                = new SubjectKeyIdentifierExtension(keyId);
+
+        BasicConstraintsExtension cons
+                = new BasicConstraintsExtension(true, 10);
+
+        PolicyConstraintsExtension pce = new PolicyConstraintsExtension(2, 4);
+
+        exts.set(SubjectAlternativeNameExtension.NAME, subjectName);
+        exts.set(IssuerAlternativeNameExtension.NAME, issuerName);
+        exts.set(PrivateKeyUsageExtension.NAME, pkusage);
+        exts.set(KeyUsageExtension.NAME, usage);
+        exts.set(AuthorityKeyIdentifierExtension.NAME, aki);
+        exts.set(SubjectKeyIdentifierExtension.NAME, ski);
+        exts.set(BasicConstraintsExtension.NAME, cons);
+        exts.set(PolicyConstraintsExtension.NAME, pce);
+        cert.set(X509CertInfo.EXTENSIONS, exts);
+
+        // Generate and sign X509CertImpl
+        X509CertImpl crt = new X509CertImpl(cert);
+        crt.sign(privateKey, sigAlg);
+        crt.verify(publicKey);
+
+        try (FileOutputStream fos = new FileOutputStream(new File(V3_FILE));
+                FileOutputStream fos_b64
+                = new FileOutputStream(new File(V3_B64_FILE));
+                PrintWriter pw = new PrintWriter(fos_b64)) {
+            crt.encode((OutputStream) fos);
+            fos.flush();
+
+            // Certificate boundaries/
+            pw.println("-----BEGIN CERTIFICATE-----");
+            pw.flush();
+            new BASE64Encoder().encodeBuffer(crt.getEncoded(), fos_b64);
+            fos_b64.flush();
+            pw.println("-----END CERTIFICATE-----");
+        }
+
+        out.println("*** Certificate ***");
+        out.println(crt);
+        out.println("*** End Certificate ***");
+
+        X509Certificate x2 = generateCertificate(V3_FILE);
+        if (!x2.equals(crt)) {
+            out.println("*** Certificate mismatch ***");
+            testResult = false;
+        }
+
+        X509Certificate x3 = generateCertificate(V3_B64_FILE);
+        if (!x3.equals(crt)) {
+            out.println("*** Certificate mismatch ***");
+            testResult = false;
+        }
+
+        return testResult;
+    }
+
+    static X509Certificate generateCertificate(String certFile) {
+        try (InputStream inStrm = new FileInputStream(certFile)) {
+            CertificateFactory cf = CertificateFactory.getInstance("X509");
+            X509Certificate x2
+                    = (X509Certificate) cf.generateCertificate(inStrm);
+            return x2;
+        } catch (CertificateException | IOException e) {
+            throw new RuntimeException("Exception while "
+                    + "genrating certificate for " + certFile, e);
+        }
+    }
+}