26
26
/*
27
27
* @test
28
28
* @bug 8298420
29
+ * @library /test/lib
29
30
* @modules java.base/sun.security.pkcs
30
31
* java.base/sun.security.util
31
32
* @summary Testing basic PEM API decoding
37
38
import java .lang .Class ;
38
39
import java .nio .charset .StandardCharsets ;
39
40
import java .security .*;
41
+ import java .security .cert .CertificateEncodingException ;
40
42
import java .security .cert .X509CRL ;
41
43
import java .security .cert .X509Certificate ;
42
44
import java .security .interfaces .*;
43
- import java .security .spec .PKCS8EncodedKeySpec ;
44
- import java .security .spec .X509EncodedKeySpec ;
45
+ import java .security .spec .*;
45
46
import java .util .*;
46
47
import java .util .Arrays ;
47
48
49
+ import jdk .test .lib .Asserts ;
50
+ import sun .security .pkcs .PKCS8Key ;
48
51
import sun .security .util .Pem ;
49
52
50
53
public class PEMDecoderTest {
51
54
52
55
static HexFormat hex = HexFormat .of ();
53
56
54
- public static void main (String [] args ) throws IOException {
57
+ public static void main (String [] args ) throws Exception {
55
58
System .out .println ("Decoder test:" );
56
- PEMData .entryList .forEach (PEMDecoderTest ::test );
59
+ PEMData .entryList .forEach (entry -> test (entry , false ));
60
+ System .out .println ("Decoder test withFactory:" );
61
+ PEMData .entryList .forEach (entry -> test (entry , true ));
57
62
System .out .println ("Decoder test returning DEREncodable class:" );
58
63
PEMData .entryList .forEach (entry -> test (entry , DEREncodable .class ));
59
64
System .out .println ("Decoder test with encrypted PEM:" );
@@ -95,7 +100,11 @@ public static void main(String[] args) throws IOException {
95
100
96
101
System .out .println ("Check a Signature/Verify op is successful:" );
97
102
PEMData .privList .forEach (PEMDecoderTest ::testSignature );
98
- PEMData .oasList .forEach (PEMDecoderTest ::testSignature );
103
+ PEMData .oasList .stream ().filter (e -> !e .name ().endsWith ("xdh" ))
104
+ .forEach (PEMDecoderTest ::testSignature );
105
+
106
+ System .out .println ("Checking if decode() returns a PKCS8Key and can generate a pub" );
107
+ PEMData .oasList .forEach (PEMDecoderTest ::testPKCS8Key );
99
108
100
109
System .out .println ("Checking if ecCSR:" );
101
110
test (PEMData .ecCSR );
@@ -182,6 +191,10 @@ public static void main(String[] args) throws IOException {
182
191
} catch (Exception e ) {
183
192
throw new AssertionError ("error getting key" , e );
184
193
}
194
+ testCertTypeConverter (PEMData .ecCert );
195
+
196
+ System .out .println ("Decoder test testCoefZero:" );
197
+ testCoefZero (PEMData .rsaCrtCoefZeroPriv );
185
198
}
186
199
187
200
static void testInputStream () throws IOException {
@@ -231,6 +244,24 @@ static void testInputStream() throws IOException {
231
244
throw new AssertionError ("Failed" );
232
245
}
233
246
247
+ // test that X509 CERTIFICATE is converted to CERTIFICATE in PEM
248
+ static void testCertTypeConverter (PEMData .Entry entry ) throws CertificateEncodingException {
249
+ String certPem = entry .pem ().replace ("CERTIFICATE" , "X509 CERTIFICATE" );
250
+ Asserts .assertEqualsByteArray (entry .der (),
251
+ PEMDecoder .of ().decode (certPem , X509Certificate .class ).getEncoded ());
252
+
253
+ certPem = entry .pem ().replace ("CERTIFICATE" , "X.509 CERTIFICATE" );
254
+ Asserts .assertEqualsByteArray (entry .der (),
255
+ PEMDecoder .of ().decode (certPem , X509Certificate .class ).getEncoded ());
256
+ }
257
+
258
+ // test that when the crtCoeff is zero, the key is decoded but only the modulus and private
259
+ // exponent are used resulting in a different der
260
+ static void testCoefZero (PEMData .Entry entry ) {
261
+ RSAPrivateKey decoded = PEMDecoder .of ().decode (entry .pem (), RSAPrivateKey .class );
262
+ Asserts .assertNotEqualsByteArray (decoded .getEncoded (), entry .der ());
263
+ }
264
+
234
265
static void testPEMRecord (PEMData .Entry entry ) {
235
266
PEMRecord r = PEMDecoder .of ().decode (entry .pem (), PEMRecord .class );
236
267
String expected = entry .pem ().split ("-----" )[2 ].replace (System .lineSeparator (), "" );
@@ -333,13 +364,26 @@ static DEREncodable testEncrypted(PEMData.Entry entry) {
333
364
334
365
// Change the Entry to use the given class as the expected class returned
335
366
static DEREncodable test (PEMData .Entry entry , Class c ) {
336
- return test (entry .newClass (c ));
367
+ return test (entry .newClass (c ), false );
337
368
}
338
369
339
370
// Run test with a given Entry
340
371
static DEREncodable test (PEMData .Entry entry ) {
372
+ return test (entry , false );
373
+ }
374
+
375
+ // Run test with a given Entry
376
+ static DEREncodable test (PEMData .Entry entry , boolean withFactory ) {
377
+ System .out .printf ("Testing %s %s%n" , entry .name (), entry .provider ());
341
378
try {
342
- DEREncodable r = test (entry .pem (), entry .clazz (), PEMDecoder .of ());
379
+ PEMDecoder pemDecoder ;
380
+ if (withFactory ) {
381
+ Provider provider = Security .getProvider (entry .provider ());
382
+ pemDecoder = PEMDecoder .of ().withFactory (provider );
383
+ } else {
384
+ pemDecoder = PEMDecoder .of ();
385
+ }
386
+ DEREncodable r = test (entry .pem (), entry .clazz (), pemDecoder );
343
387
System .out .println ("PASS (" + entry .name () + ")" );
344
388
return r ;
345
389
} catch (Exception | AssertionError e ) {
@@ -412,6 +456,19 @@ static void testTwoKeys() throws IOException {
412
456
}
413
457
}
414
458
459
+ private static void testPKCS8Key (PEMData .Entry entry ) {
460
+ try {
461
+ PKCS8Key key = PEMDecoder .of ().decode (entry .pem (), PKCS8Key .class );
462
+ PKCS8EncodedKeySpec spec =
463
+ new PKCS8EncodedKeySpec (key .getEncoded ());
464
+
465
+ KeyFactory kf = KeyFactory .getInstance (key .getAlgorithm ());
466
+ kf .generatePublic (spec );
467
+ } catch (Exception ex ) {
468
+ throw new RuntimeException (ex );
469
+ }
470
+ }
471
+
415
472
static void testClass (PEMData .Entry entry , Class clazz ) throws IOException {
416
473
var pk = PEMDecoder .of ().decode (entry .pem (), clazz );
417
474
}
@@ -472,9 +529,15 @@ static void testSignature(PEMData.Entry entry) {
472
529
"should not be null" );
473
530
}
474
531
532
+ AlgorithmParameterSpec spec = null ;
475
533
String algorithm = switch (privateKey .getAlgorithm ()) {
476
534
case "EC" -> "SHA256withECDSA" ;
477
535
case "EdDSA" -> "EdDSA" ;
536
+ case "RSASSA-PSS" -> {
537
+ spec = new PSSParameterSpec (
538
+ "SHA-256" , "MGF1" , MGF1ParameterSpec .SHA256 , 32 , 1 );
539
+ yield "RSASSA-PSS" ;
540
+ }
478
541
case null -> {
479
542
System .out .println ("Algorithm is null " +
480
543
entry .name ());
@@ -487,6 +550,9 @@ static void testSignature(PEMData.Entry entry) {
487
550
try {
488
551
if (d instanceof PrivateKey ) {
489
552
s = Signature .getInstance (algorithm );
553
+ if (spec != null ) {
554
+ s .setParameter (spec );
555
+ }
490
556
s .initSign (privateKey );
491
557
s .update (data );
492
558
s .sign ();
0 commit comments