2525
2626package com .sun .crypto .provider ;
2727
28+ import jdk .internal .access .SharedSecrets ;
29+
2830import java .security .Key ;
2931import java .security .PublicKey ;
3032import java .security .PrivateKey ;
4850 */
4951
5052final class ConstructKeys {
51- /**
52- * Construct a public key from its encoding.
53- *
54- * @param encodedKey the encoding of a public key.
55- *
56- * @param encodedKeyAlgorithm the algorithm the encodedKey is for.
57- *
58- * @return a public key constructed from the encodedKey.
59- */
53+
6054 private static final PublicKey constructPublicKey (byte [] encodedKey ,
61- String encodedKeyAlgorithm )
55+ int ofs , int len , String encodedKeyAlgorithm )
6256 throws InvalidKeyException , NoSuchAlgorithmException {
6357 PublicKey key = null ;
58+ byte [] keyBytes = (ofs == 0 && encodedKey .length == len )
59+ ? encodedKey : Arrays .copyOfRange (encodedKey , ofs , ofs + len );
60+ X509EncodedKeySpec keySpec = new X509EncodedKeySpec (keyBytes );
6461 try {
6562 KeyFactory keyFactory =
6663 KeyFactory .getInstance (encodedKeyAlgorithm ,
6764 SunJCE .getInstance ());
68- X509EncodedKeySpec keySpec = new X509EncodedKeySpec (encodedKey );
6965 key = keyFactory .generatePublic (keySpec );
7066 } catch (NoSuchAlgorithmException nsae ) {
7167 // Try to see whether there is another
7268 // provider which supports this algorithm
7369 try {
7470 KeyFactory keyFactory =
7571 KeyFactory .getInstance (encodedKeyAlgorithm );
76- X509EncodedKeySpec keySpec =
77- new X509EncodedKeySpec (encodedKey );
7872 key = keyFactory .generatePublic (keySpec );
7973 } catch (NoSuchAlgorithmException nsae2 ) {
8074 throw new NoSuchAlgorithmException ("No installed providers " +
@@ -97,34 +91,24 @@ private static final PublicKey constructPublicKey(byte[] encodedKey,
9791 return key ;
9892 }
9993
100- /**
101- * Construct a private key from its encoding.
102- *
103- * @param encodedKey the encoding of a private key.
104- *
105- * @param encodedKeyAlgorithm the algorithm the wrapped key is for.
106- *
107- * @return a private key constructed from the encodedKey.
108- */
10994 private static final PrivateKey constructPrivateKey (byte [] encodedKey ,
110- String encodedKeyAlgorithm )
95+ int ofs , int len , String encodedKeyAlgorithm )
11196 throws InvalidKeyException , NoSuchAlgorithmException {
11297 PrivateKey key = null ;
113-
98+ byte [] keyBytes = (ofs == 0 && encodedKey .length == len )
99+ ? encodedKey : Arrays .copyOfRange (encodedKey , ofs , ofs + len );
100+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec (keyBytes );
114101 try {
115102 KeyFactory keyFactory =
116103 KeyFactory .getInstance (encodedKeyAlgorithm ,
117104 SunJCE .getInstance ());
118- PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec (encodedKey );
119105 return keyFactory .generatePrivate (keySpec );
120106 } catch (NoSuchAlgorithmException nsae ) {
121107 // Try to see whether there is another
122108 // provider which supports this algorithm
123109 try {
124110 KeyFactory keyFactory =
125111 KeyFactory .getInstance (encodedKeyAlgorithm );
126- PKCS8EncodedKeySpec keySpec =
127- new PKCS8EncodedKeySpec (encodedKey );
128112 key = keyFactory .generatePrivate (keySpec );
129113 } catch (NoSuchAlgorithmException nsae2 ) {
130114 throw new NoSuchAlgorithmException ("No installed providers " +
@@ -142,20 +126,16 @@ private static final PrivateKey constructPrivateKey(byte[] encodedKey,
142126 new InvalidKeyException ("Cannot construct private key" );
143127 ike .initCause (ikse );
144128 throw ike ;
129+ } finally {
130+ SharedSecrets .getJavaSecuritySpecAccess ().clearEncodedKeySpec (keySpec );
131+ if (keyBytes != encodedKey ) {
132+ Arrays .fill (keyBytes , (byte )0 );
133+ }
145134 }
146135
147136 return key ;
148137 }
149138
150- /**
151- * Construct a secret key from its encoding.
152- *
153- * @param encodedKey the encoding of a secret key.
154- *
155- * @param encodedKeyAlgorithm the algorithm the secret key is for.
156- *
157- * @return a secret key constructed from the encodedKey.
158- */
159139 private static final SecretKey constructSecretKey (byte [] encodedKey ,
160140 int ofs , int len , String encodedKeyAlgorithm ) {
161141 return (new SecretKeySpec (encodedKey , ofs , len , encodedKeyAlgorithm ));
@@ -170,35 +150,14 @@ static final Key constructKey(byte[] encoding, String keyAlgorithm,
170150 static final Key constructKey (byte [] encoding , int ofs , int len ,
171151 String keyAlgorithm , int keyType )
172152 throws InvalidKeyException , NoSuchAlgorithmException {
173- switch (keyType ) {
174- case Cipher .SECRET_KEY :
175- try {
176- return ConstructKeys .constructSecretKey (encoding , ofs , len ,
177- keyAlgorithm );
178- } finally {
179- Arrays .fill (encoding , ofs , len , (byte )0 );
180- }
181- case Cipher .PRIVATE_KEY :
182- byte [] encoding2 = encoding ;
183- try {
184- if (ofs != 0 || len != encoding .length ) {
185- encoding2 = Arrays .copyOfRange (encoding , ofs , ofs + len );
186- }
187- return ConstructKeys .constructPrivateKey (encoding2 ,
188- keyAlgorithm );
189- } finally {
190- Arrays .fill (encoding , ofs , len , (byte )0 );
191- if (encoding2 != encoding ) {
192- Arrays .fill (encoding2 , (byte )0 );
193- }
194- }
195- case Cipher .PUBLIC_KEY :
196- if (ofs != 0 || len != encoding .length ) {
197- encoding = Arrays .copyOfRange (encoding , ofs , ofs + len );
198- }
199- return ConstructKeys .constructPublicKey (encoding , keyAlgorithm );
200- default :
201- throw new NoSuchAlgorithmException ("Unsupported key type" );
202- }
153+ return switch (keyType ) {
154+ case Cipher .SECRET_KEY -> ConstructKeys .constructSecretKey (
155+ encoding , ofs , len , keyAlgorithm );
156+ case Cipher .PRIVATE_KEY -> ConstructKeys .constructPrivateKey (
157+ encoding , ofs , len , keyAlgorithm );
158+ case Cipher .PUBLIC_KEY -> ConstructKeys .constructPublicKey (
159+ encoding , ofs , len , keyAlgorithm );
160+ default -> throw new NoSuchAlgorithmException ("Unsupported key type" );
161+ };
203162 }
204163}
0 commit comments