1/*
2 * Copyright (c) 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.
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 8048357
27 * @summary test DER encoding of PKCS10 attributes
28 * @modules java.base/sun.security.pkcs
29 *          java.base/sun.security.pkcs10
30 *          java.base/sun.security.util
31 *          java.base/sun.security.x509
32 * @compile -XDignore.symbol.file PKCS10AttrEncoding.java
33 * @run main PKCS10AttrEncoding
34 */
35import java.security.KeyPair;
36import java.security.KeyPairGenerator;
37import java.security.PrivateKey;
38import java.security.Signature;
39import java.util.Enumeration;
40import java.util.GregorianCalendar;
41import java.util.HashMap;
42import sun.security.pkcs.PKCS9Attribute;
43import sun.security.pkcs10.PKCS10;
44import sun.security.pkcs10.PKCS10Attribute;
45import sun.security.pkcs10.PKCS10Attributes;
46import sun.security.util.ObjectIdentifier;
47import sun.security.x509.X500Name;
48import sun.security.x509.X509Key;
49
50public class PKCS10AttrEncoding {
51
52    static final ObjectIdentifier[] ids = {
53        PKCS9Attribute.CONTENT_TYPE_OID, // ContentType
54        PKCS9Attribute.SIGNING_TIME_OID, // SigningTime
55        PKCS9Attribute.CHALLENGE_PASSWORD_OID // ChallengePassword
56    };
57    static int failedCount = 0;
58    static HashMap<ObjectIdentifier, Object> constructedMap = new HashMap<>();
59
60    public static void main(String[] args) throws Exception {
61
62        // initializations
63        int len = ids.length;
64        Object[] values = {
65            new ObjectIdentifier("1.2.3.4"),
66            new GregorianCalendar(1970, 1, 25, 8, 56, 7).getTime(),
67            "challenging"
68        };
69        for (int j = 0; j < len; j++) {
70            constructedMap.put(ids[j], values[j]);
71        }
72
73        X500Name subject = new X500Name("cn=Test");
74        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
75        String sigAlg = "DSA";
76
77        keyGen.initialize(512);
78
79        KeyPair pair = keyGen.generateKeyPair();
80        X509Key publicKey = (X509Key) pair.getPublic();
81        PrivateKey privateKey = pair.getPrivate();
82
83        Signature signature = Signature.getInstance(sigAlg);
84        signature.initSign(privateKey);
85
86        // Create the PKCS10 request
87        PKCS10Attribute[] attrs = new PKCS10Attribute[len];
88        for (int j = 0; j < len; j++) {
89            attrs[j] = new PKCS10Attribute(ids[j], values[j]);
90        }
91        PKCS10 req = new PKCS10(publicKey, new PKCS10Attributes(attrs));
92        System.out.println("List of attributes in constructed PKCS10 "
93                + "request: ");
94        checkAttributes(req.getAttributes().getElements());
95
96        // Encode the PKCS10 request and generate another PKCS10 request from
97        // the encoded byte array
98        req.encodeAndSign(subject, signature);
99        PKCS10 resp = new PKCS10(req.getEncoded());
100        System.out.println("List of attributes in DER encoded PKCS10 Request:");
101        checkAttributes(resp.getAttributes().getElements());
102
103        if (failedCount > 0) {
104            throw new RuntimeException("Attributes Compared : Failed");
105        }
106        System.out.println("Attributes Compared : Pass");
107    }
108
109    static void checkAttributes(Enumeration attrs) {
110        int numOfAttrs = 0;
111        while (attrs.hasMoreElements()) {
112            numOfAttrs ++;
113            PKCS10Attribute attr = (PKCS10Attribute) attrs.nextElement();
114
115            if (constructedMap.containsKey(attr.getAttributeId())) {
116                if (constructedMap.get(attr.getAttributeId()).
117                        equals(attr.getAttributeValue())) {
118                    System.out.print("AttributeId: " + attr.getAttributeId());
119                    System.out.println(" AttributeValue: "
120                            + attr.getAttributeValue());
121                } else {
122                    failedCount++;
123                    System.out.print("< AttributeId: " + attr.getAttributeId());
124                    System.out.println("  AttributeValue: " + constructedMap.
125                            get(attr.getAttributeId()));
126                    System.out.print("< AttributeId: " + attr.getAttributeId());
127                    System.out.println("  AttributeValue: "
128                            + attr.getAttributeValue());
129                }
130            } else {
131                failedCount++;
132                System.out.println("No " + attr.getAttributeId()
133                        + " in DER encoded PKCS10 Request");
134            }
135        }
136        if(numOfAttrs != constructedMap.size()){
137            failedCount++;
138            System.out.println("Incorrect number of attributes.");
139
140        }
141        System.out.println();
142    }
143
144}
145