Skip to content
This repository was archived by the owner on Aug 27, 2022. It is now read-only.
/ lanai Public archive

Commit c0b348f

Browse files
author
Jamil Nimeh
committedJun 23, 2020
8239950: Update PKCS9 Attributes to PKCS#9 v2.0 Encodings
Reviewed-by: weijun
1 parent d8219d0 commit c0b348f

File tree

3 files changed

+245
-13
lines changed

3 files changed

+245
-13
lines changed
 

‎src/java.base/share/classes/sun/security/pkcs/PKCS9Attribute.java

+16-7
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@
2828
import java.io.IOException;
2929
import java.io.OutputStream;
3030
import java.security.cert.CertificateException;
31-
import java.util.Locale;
3231
import java.util.Date;
33-
import java.util.HashMap;
3432
import sun.security.x509.CertificateExtensions;
3533
import sun.security.util.*;
3634

@@ -234,19 +232,27 @@ public class PKCS9Attribute implements DerEncoder {
234232
private static final Byte[][] PKCS9_VALUE_TAGS = {
235233
null,
236234
{DerValue.tag_IA5String}, // EMailAddress
237-
{DerValue.tag_IA5String, // UnstructuredName
238-
DerValue.tag_PrintableString},
235+
{DerValue.tag_IA5String,
236+
DerValue.tag_PrintableString,
237+
DerValue.tag_T61String,
238+
DerValue.tag_BMPString,
239+
DerValue.tag_UniversalString,
240+
DerValue.tag_UTF8String}, // UnstructuredName
239241
{DerValue.tag_ObjectId}, // ContentType
240242
{DerValue.tag_OctetString}, // MessageDigest
241-
{DerValue.tag_UtcTime}, // SigningTime
243+
{DerValue.tag_UtcTime,
244+
DerValue.tag_GeneralizedTime}, // SigningTime
242245
{DerValue.tag_Sequence}, // Countersignature
243246
{DerValue.tag_PrintableString,
244247
DerValue.tag_T61String,
245248
DerValue.tag_BMPString,
246249
DerValue.tag_UniversalString,
247250
DerValue.tag_UTF8String}, // ChallengePassword
248251
{DerValue.tag_PrintableString,
249-
DerValue.tag_T61String}, // UnstructuredAddress
252+
DerValue.tag_T61String,
253+
DerValue.tag_BMPString,
254+
DerValue.tag_UniversalString,
255+
DerValue.tag_UTF8String}, // UnstructuredAddress
250256
{DerValue.tag_SetOf}, // ExtendedCertificateAttributes
251257
{DerValue.tag_Sequence}, // issuerAndSerialNumber
252258
null,
@@ -437,7 +443,10 @@ public PKCS9Attribute(DerValue derVal) throws IOException {
437443
break;
438444

439445
case 5: // signing time
440-
value = (new DerInputStream(elems[0].toByteArray())).getUTCTime();
446+
byte elemTag = elems[0].getTag();
447+
DerInputStream dis = new DerInputStream(elems[0].toByteArray());
448+
value = (elemTag == DerValue.tag_GeneralizedTime) ?
449+
dis.getGeneralizedTime() : dis.getUTCTime();
441450
break;
442451

443452
case 6: // countersignature

‎src/java.base/share/classes/sun/security/util/DerValue.java

+26-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
2828
import java.io.*;
2929
import java.math.BigInteger;
3030
import java.nio.charset.Charset;
31+
import java.nio.charset.IllegalCharsetNameException;
32+
import java.nio.charset.UnsupportedCharsetException;
3133
import java.util.Date;
3234

3335
import static java.nio.charset.StandardCharsets.*;
@@ -360,8 +362,9 @@ private DerInputStream init(byte stringTag, String value) {
360362
case tag_UTF8String:
361363
charset = UTF_8;
362364
break;
363-
// TBD: Need encoder for UniversalString before it can
364-
// be handled.
365+
case tag_UniversalString:
366+
charset = Charset.forName("UTF_32BE");
367+
break;
365368
default:
366369
throw new IllegalArgumentException("Unsupported DER string type");
367370
}
@@ -598,10 +601,8 @@ else if (tag == tag_T61String)
598601
return getT61String();
599602
else if (tag == tag_IA5String)
600603
return getIA5String();
601-
/*
602-
else if (tag == tag_UniversalString)
604+
else if (tag == tag_UniversalString)
603605
return getUniversalString();
604-
*/
605606
else if (tag == tag_BMPString)
606607
return getBMPString();
607608
else if (tag == tag_GeneralString)
@@ -740,6 +741,25 @@ public String getGeneralString() throws IOException {
740741
return new String(getDataBytes(), US_ASCII);
741742
}
742743

744+
/**
745+
* Returns the ASN.1 UNIVERSAL (UTF-32) STRING value as a Java String.
746+
*
747+
* @return a string corresponding to the encoded UniversalString held in
748+
* this value or an empty string if UTF_32BE is not a supported character
749+
* set.
750+
*/
751+
public String getUniversalString() throws IOException {
752+
if (tag != tag_UniversalString)
753+
throw new IOException(
754+
"DerValue.getUniversalString, not UniversalString " + tag);
755+
try {
756+
Charset cset = Charset.forName("UTF_32BE");
757+
return new String(getDataBytes(), cset);
758+
} catch (IllegalCharsetNameException | UnsupportedCharsetException e) {
759+
return "";
760+
}
761+
}
762+
743763
/**
744764
* Returns a Date if the DerValue is UtcTime.
745765
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/*
2+
* Copyright (c) 2020, 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 8239950
27+
* @summary Update PKCS9 Attributes to PKCS#9 v2.0 Encodings
28+
* @library /test/lib
29+
* @modules java.base/sun.security.pkcs
30+
java.base/sun.security.util
31+
*/
32+
33+
import java.io.IOException;
34+
import java.util.*;
35+
import sun.security.pkcs.PKCS9Attribute;
36+
import sun.security.util.DerValue;
37+
import jdk.test.lib.Utils;
38+
39+
public class PKCS9AttrTypeTests {
40+
41+
static final Map<String, String> TEST_INPUT_GOOD =
42+
new LinkedHashMap<String, String>() {{
43+
44+
// Challenge Password
45+
put("challengePasssword as TeletexString",
46+
"301e06092a864886f70d010907311114" +
47+
"0f5468697349734150617373776f7264");
48+
put("challengePasssword as PrintableString",
49+
"301e06092a864886f70d010907311113" +
50+
"0f5468697349734150617373776f7264");
51+
put("challengePasssword as UniversalString",
52+
"304b06092a864886f70d010907313e1c" +
53+
"3c000000540000006800000069000000" +
54+
"73000000490000007300000041000000" +
55+
"50000000610000007300000073000000" +
56+
"770000006f0000007200000064");
57+
put("challengePasssword as UTF8String",
58+
"301e06092a864886f70d01090731110c" +
59+
"0f5468697349734150617373776f7264");
60+
put("challengePasssword as BMPString",
61+
"302d06092a864886f70d01090731201e" +
62+
"1e005400680069007300490073004100" +
63+
"500061007300730077006f00720064");
64+
65+
// Unstructured Name
66+
put("unstructuredName as IA5String",
67+
"301b06092a864886f70d010902310e16" +
68+
"0c5468697349734d794e616d65");
69+
put("unstructuredName as TeletexString",
70+
"301b06092a864886f70d010902310e14" +
71+
"0c5468697349734d794e616d65");
72+
put("unstructuredName as PrintableString",
73+
"301b06092a864886f70d010902310e13" +
74+
"0c5468697349734d794e616d65");
75+
put("unstructuredName as UniversalString",
76+
"303f06092a864886f70d01090231321c" +
77+
"30000000540000006800000069000000" +
78+
"7300000049000000730000004d000000" +
79+
"790000004e000000610000006d000000" +
80+
"65");
81+
put("unstructuredName as UTF8String",
82+
"301b06092a864886f70d010902310e0c" +
83+
"0c5468697349734d794e616d65");
84+
put("unstructuredName as BMPString",
85+
"302706092a864886f70d010902311a1e" +
86+
"18005400680069007300490073004d00" +
87+
"79004e0061006d0065");
88+
put("unstructuredName as Multi-Valued",
89+
"302d06092a864886f70d010902312013" +
90+
"10546869734973416c736f4d794e616d" +
91+
"65160c5468697349734d794e616d65");
92+
93+
// Unstructured Address
94+
put("unstructuredAddress as TeletexString",
95+
"301e06092a864886f70d010908311114" +
96+
"0f5468697349734d7941646472657373");
97+
put("unstructuredAddress as PrintableString",
98+
"301e06092a864886f70d010908311113" +
99+
"0f5468697349734d7941646472657373");
100+
put("unstructuredAddress as UniversalString",
101+
"304b06092a864886f70d010908313e1c" +
102+
"3c000000540000006800000069000000" +
103+
"7300000049000000730000004d000000" +
104+
"79000000410000006400000064000000" +
105+
"72000000650000007300000073");
106+
put("unstructuredAddress as UTF8String",
107+
"301e06092a864886f70d01090831110c" +
108+
"0f5468697349734d7941646472657373");
109+
put("unstructuredAddress as BMPString",
110+
"302d06092a864886f70d01090831201e" +
111+
"1e005400680069007300490073004d00" +
112+
"790041006400640072006500730073");
113+
put("unstructuredAddress as Multi-Valued",
114+
"303306092a864886f70d01090831260c" +
115+
"13546869734973416c736f4d79416464" +
116+
"72657373130f5468697349734d794164" +
117+
"6472657373");
118+
119+
// Signing Time
120+
put("signingTime as UTCTime",
121+
"301c06092a864886f70d010905310f17" +
122+
"0d3635303533313132303030305a");
123+
put("signingTime as GeneralizedTime",
124+
"301e06092a864886f70d010905311118" +
125+
"0f32303530303533313132303030305a");
126+
}};
127+
128+
static final Map<String, String> TEST_INPUT_BAD =
129+
new LinkedHashMap<String, String>() {{
130+
131+
// Challenge Password
132+
put("challengePasssword as IA5String",
133+
"301e06092a864886f70d010907311116" +
134+
"0f5468697349734150617373776f7264");
135+
put("challengePassword as Multi-Valued",
136+
"303306092a864886f70d01090731260c" +
137+
"13546869734973416c736f4150617373" +
138+
"776f7264130f54686973497341506173" +
139+
"73776f7264");
140+
141+
// Unstructured Name
142+
put("unstructuredName as UTCTime",
143+
"301c06092a864886f70d010902310f17" +
144+
"0d3635303533313132303030305a");
145+
146+
// Unstructured Address
147+
put("unstructuredAddress as IA5String",
148+
"301e06092a864886f70d010908311116" +
149+
"0f5468697349734d7941646472657373");
150+
151+
// Signing Time
152+
put("signingTime as Multi-Valued",
153+
"302b06092a864886f70d010905311e17" +
154+
"0d3230303432383035303030305a170d" +
155+
"3635303533313132303030305a"); // DKN
156+
}};
157+
158+
public static void main(String[] args) throws Exception {
159+
int failedTests = 0;
160+
161+
for (Map.Entry<String, String> entry : TEST_INPUT_GOOD.entrySet()) {
162+
try {
163+
System.out.print("Test - " + entry.getKey() + ": ");
164+
165+
// Decode each Base64 test vector into DER and place into
166+
// a DerValue object to be consumed by PKCS9Attribute.
167+
PKCS9Attribute p9Attr = new PKCS9Attribute(
168+
new DerValue(Utils.toByteArray(entry.getValue())));
169+
System.out.println("PASS");
170+
System.out.println("---------------");
171+
System.out.println(p9Attr);
172+
System.out.println("---------------");
173+
} catch (IOException ioe) {
174+
failedTests++;
175+
System.out.println("FAIL:");
176+
ioe.printStackTrace(System.out);
177+
System.out.println();
178+
}
179+
}
180+
181+
for (Map.Entry<String, String> entry : TEST_INPUT_BAD.entrySet()) {
182+
try {
183+
System.out.print("Test - " + entry.getKey() + ": ");
184+
185+
// Decode each Base64 test vector into DER and place into
186+
// a DerValue object to be consumed by PKCS9Attribute.
187+
PKCS9Attribute p9Attr = new PKCS9Attribute(
188+
new DerValue(
189+
Base64.getMimeDecoder().decode(entry.getValue())));
190+
failedTests++;
191+
System.out.println("FAIL: Expected IOException did not occur");
192+
} catch (IOException ioe) {
193+
System.out.println("PASS\n" + ioe);
194+
}
195+
196+
}
197+
198+
if (failedTests > 0) {
199+
throw new RuntimeException(
200+
"One or more test cases failed, see output");
201+
}
202+
}
203+
}

0 commit comments

Comments
 (0)
This repository has been archived.