1 /*
2  * Copyright (c) 2018, 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 import java.security.*;
24 import java.security.interfaces.RSAPrivateKey;
25 import java.security.interfaces.RSAPublicKey;
26 import java.security.spec.*;
27 import java.util.Arrays;
28 import java.util.stream.IntStream;
29 import static javax.crypto.Cipher.PRIVATE_KEY;
30 import static javax.crypto.Cipher.PUBLIC_KEY;
31 
32 /**
33  * @test
34  * @bug 8146293 8242556
35  * @summary Test RSASSA-PSS AlgorithmParameters impl of SunRsaSign provider.
36  * @run main PSSParametersTest
37  */
38 public class PSSParametersTest {
39     /**
40      * JDK default RSA Provider.
41      */
42     private static final String PROVIDER = "SunRsaSign";
43 
44     private static final String PSS_ALGO = "RSASSA-PSS";
45     private static final String PSS_OID = "1.2.840.113549.1.1.10";
46 
main(String[] args)47     public static void main(String[] args) throws Exception {
48         System.out.println("Testing against DEFAULT parameters");
49         test(PSSParameterSpec.DEFAULT);
50         System.out.println("Testing against custom parameters");
51         test(new PSSParameterSpec("SHA-512/224", "MGF1",
52                 MGF1ParameterSpec.SHA384, 100, 1));
53         System.out.println("Test Passed");
54     }
55 
56     // test the given spec by first initializing w/ it, generate the DER
57     // bytes, then initialize w/ the DER bytes, retrieve the spec.
58     // compare both spec for equality and throw exception if the check failed.
test(PSSParameterSpec spec)59     private static void test(PSSParameterSpec spec) throws Exception {
60         String ALGORITHMS[] = { PSS_ALGO, PSS_OID };
61         for (String alg : ALGORITHMS) {
62             AlgorithmParameters params = AlgorithmParameters.getInstance
63                     (alg, PROVIDER);
64             params.init(spec);
65             byte[] encoded = params.getEncoded();
66             AlgorithmParameters params2 = AlgorithmParameters.getInstance
67                     (alg, PROVIDER);
68             params2.init(encoded);
69             PSSParameterSpec spec2 = params2.getParameterSpec
70                 (PSSParameterSpec.class);
71             if (!isEqual(spec, spec2)) {
72                 throw new RuntimeException("Spec check Failed for " +  alg);
73             }
74         }
75     }
76 
isEqual(PSSParameterSpec spec, PSSParameterSpec spec2)77     private static boolean isEqual(PSSParameterSpec spec,
78             PSSParameterSpec spec2) throws Exception {
79         if (spec == spec2) return true;
80         if (spec == null || spec2 == null) return false;
81 
82         if (!spec.getDigestAlgorithm().equals(spec2.getDigestAlgorithm())) {
83             System.out.println("Different digest algorithms: " +
84                 spec.getDigestAlgorithm() + " vs " + spec2.getDigestAlgorithm());
85             return false;
86         }
87         if (!spec.getMGFAlgorithm().equals(spec2.getMGFAlgorithm())) {
88             System.out.println("Different MGF algorithms: " +
89                 spec.getMGFAlgorithm() + " vs " + spec2.getMGFAlgorithm());
90             return false;
91         }
92         if (spec.getSaltLength() != spec2.getSaltLength()) {
93             System.out.println("Different Salt Length: " +
94                 spec.getSaltLength() + " vs " + spec2.getSaltLength());
95             return false;
96         }
97         if (spec.getTrailerField() != spec2.getTrailerField()) {
98             System.out.println("Different TrailerField: " +
99                 spec.getTrailerField() + " vs " + spec2.getTrailerField());
100             return false;
101         }
102         // continue checking MGF Parameters
103         AlgorithmParameterSpec mgfParams = spec.getMGFParameters();
104         AlgorithmParameterSpec mgfParams2 = spec2.getMGFParameters();
105         if (mgfParams == mgfParams2) return true;
106         if (mgfParams == null || mgfParams2 == null) {
107             System.out.println("Different MGF Parameters: " +
108                 mgfParams + " vs " + mgfParams2);
109             return false;
110         }
111         if (mgfParams instanceof MGF1ParameterSpec) {
112             if (mgfParams2 instanceof MGF1ParameterSpec) {
113                 boolean result =
114                     ((MGF1ParameterSpec)mgfParams).getDigestAlgorithm().equals
115                          (((MGF1ParameterSpec)mgfParams2).getDigestAlgorithm());
116                 if (!result) {
117                     System.out.println("Different MGF1 digest algorithms: " +
118                         ((MGF1ParameterSpec)mgfParams).getDigestAlgorithm() +
119                         " vs " +
120                         ((MGF1ParameterSpec)mgfParams2).getDigestAlgorithm());
121                 }
122                 return result;
123             } else {
124                 System.out.println("Different MGF Parameters types: " +
125                     mgfParams.getClass() + " vs " + mgfParams2.getClass());
126                 return false;
127             }
128         }
129         throw new RuntimeException("Unrecognized MGFParameters: " + mgfParams);
130     }
131 }
132