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 
 24 /**
 25  * @test
 26  * @bug 8146293 8242556 8172366
 27  * @summary Test RSASSA-PSS Key related support such as KeyPairGenerator
 28  * and KeyFactory of the SunRsaSign provider
 29  */
 30 
 31 import java.io.*;
 32 import java.util.*;
 33 import java.math.BigInteger;
 34 
 35 import java.security.*;
 36 import java.security.interfaces.*;
 37 import java.security.spec.*;
 38 
 39 public class TestPSSKeySupport {
 40 
 41     private static final String ALGO = "RSASSA-PSS";
 42 
 43     /**
 44      * Test that key1 (reference key) and key2 (key to be tested) are
 45      * equivalent
 46      */
 47     private static void testKey(Key key1, Key key2) throws Exception {
 48         if (key2.getAlgorithm().equals(ALGO) == false) {
 49             throw new Exception("Algorithm not " + ALGO);
 50         }
 51         if (key1 instanceof PublicKey) {
 52             if (key2.getFormat().equals("X.509") == false) {
 53                 throw new Exception("Format not X.509");
 54             }
 55         } else if (key1 instanceof PrivateKey) {
 56             if (key2.getFormat().equals("PKCS#8") == false) {
 57                 throw new Exception("Format not PKCS#8");
 58             }
 59         }
 60         if (key1.equals(key2) == false) {
 61             throw new Exception("Keys not equal");
 62         }
 63         if (Arrays.equals(key1.getEncoded(), key2.getEncoded()) == false) {
 64             throw new Exception("Encodings not equal");
 65         }
 66     }
 67 
 68     private static void testPublic(KeyFactory kf, PublicKey key) throws Exception {
 69         System.out.println("Testing public key...");
 70         PublicKey key2 = (PublicKey)kf.translateKey(key);
 71         KeySpec rsaSpec = kf.getKeySpec(key, RSAPublicKeySpec.class);
 72         PublicKey key3 = kf.generatePublic(rsaSpec);
 73         KeySpec x509Spec = kf.getKeySpec(key, X509EncodedKeySpec.class);
 74         PublicKey key4 = kf.generatePublic(x509Spec);
 75         KeySpec x509Spec2 = new X509EncodedKeySpec(key.getEncoded());
 76         PublicKey key5 = kf.generatePublic(x509Spec2);
 77         testKey(key, key);
 78         testKey(key, key2);
 79         testKey(key, key3);
 80         testKey(key, key4);
 81         testKey(key, key5);
 82     }
 83 
 84     private static void testPrivate(KeyFactory kf, PrivateKey key) throws Exception {
 85         System.out.println("Testing private key...");
 86         PrivateKey key2 = (PrivateKey)kf.translateKey(key);
 87         KeySpec rsaSpec = kf.getKeySpec(key, RSAPrivateCrtKeySpec.class);
 88         PrivateKey key3 = kf.generatePrivate(rsaSpec);
 89         KeySpec pkcs8Spec = kf.getKeySpec(key, PKCS8EncodedKeySpec.class);
 90         PrivateKey key4 = kf.generatePrivate(pkcs8Spec);
 91         KeySpec pkcs8Spec2 = new PKCS8EncodedKeySpec(key.getEncoded());
 92         PrivateKey key5 = kf.generatePrivate(pkcs8Spec2);
 93         testKey(key, key);
 94         testKey(key, key2);
 95         testKey(key, key3);
 96         testKey(key, key4);
 97         testKey(key, key5);
 98 
 99         KeySpec rsaSpec2 = kf.getKeySpec(key, RSAPrivateKeySpec.class);
100         PrivateKey key6 = kf.generatePrivate(rsaSpec2);
101         RSAPrivateKey rsaKey = (RSAPrivateKey)key;
102         KeySpec rsaSpec3 = new RSAPrivateKeySpec(rsaKey.getModulus(),
103             rsaKey.getPrivateExponent(), rsaKey.getParams());
104         PrivateKey key7 = kf.generatePrivate(rsaSpec3);
105         testKey(key6, key6);
106         testKey(key6, key7);
107     }
108 
109     private static void test(KeyFactory kf, Key key) throws Exception {
110         if (key.getAlgorithm().equals(ALGO) == false) {
111             throw new Exception("Error: key algo should be " + ALGO);
112         }
113         if (key instanceof PublicKey) {
114             testPublic(kf, (PublicKey)key);
115         } else if (key instanceof PrivateKey) {
116             testPrivate(kf, (PrivateKey)key);
117         }
118     }
119 
120     private static void checkKeyPair(KeyPair kp) throws Exception {
121         PublicKey pubKey = kp.getPublic();
122         if (!(pubKey instanceof RSAPublicKey)) {
123             throw new Exception("Error: public key should be RSAPublicKey");
124         }
125         PrivateKey privKey = kp.getPrivate();
126         if (!(privKey instanceof RSAPrivateKey)) {
127             throw new Exception("Error: private key should be RSAPrivateKey");
128         }
129     }
130 
131     public static void main(String[] args) throws Exception {
132         KeyPairGenerator kpg =
133             KeyPairGenerator.getInstance(ALGO, "SunRsaSign");
134 
135         // Algorithm-Independent Initialization
136         kpg.initialize(2048);
137         KeyPair kp = kpg.generateKeyPair();
138         checkKeyPair(kp);
139         BigInteger pubExp = ((RSAPublicKey)kp.getPublic()).getPublicExponent();
140 
141         // Algorithm-specific Initialization
142         PSSParameterSpec params = new PSSParameterSpec("SHA-256", "MGF1",
143             MGF1ParameterSpec.SHA256, 32, 1);
144         kpg.initialize(new RSAKeyGenParameterSpec(2048, pubExp, params));
145         KeyPair kp2 = kpg.generateKeyPair();
146         checkKeyPair(kp2);
147 
148         params = new PSSParameterSpec("SHA3-256", "MGF1",
149             new MGF1ParameterSpec("SHA3-256"), 32, 1);
150         kpg.initialize(new RSAKeyGenParameterSpec(2048, pubExp, params));
151         KeyPair kp3 = kpg.generateKeyPair();
152         checkKeyPair(kp3);
153 
154         KeyFactory kf = KeyFactory.getInstance(ALGO, "SunRsaSign");
155         test(kf, kp.getPublic());
156         test(kf, kp.getPrivate());
157         test(kf, kp2.getPublic());
158         test(kf, kp2.getPrivate());
159         test(kf, kp3.getPublic());
160         test(kf, kp3.getPrivate());
161     }
162 }