1/* 2 * Copyright (c) 1999, 2013, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.sun.crypto.provider; 27 28import java.security.Key; 29import java.security.PublicKey; 30import java.security.PrivateKey; 31import java.security.KeyFactory; 32import java.security.InvalidKeyException; 33import java.security.NoSuchAlgorithmException; 34import java.security.spec.PKCS8EncodedKeySpec; 35import java.security.spec.X509EncodedKeySpec; 36import java.security.spec.InvalidKeySpecException; 37 38import javax.crypto.SecretKey; 39import javax.crypto.Cipher; 40import javax.crypto.spec.SecretKeySpec; 41 42/** 43 * This class is a helper class which construct key objects 44 * from encoded keys. 45 * 46 * @author Sharon Liu 47 * 48 */ 49 50final 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 */ 60 private static final PublicKey constructPublicKey(byte[] encodedKey, 61 String encodedKeyAlgorithm) 62 throws InvalidKeyException, NoSuchAlgorithmException 63 { 64 PublicKey key = null; 65 66 try { 67 KeyFactory keyFactory = 68 KeyFactory.getInstance(encodedKeyAlgorithm, 69 SunJCE.getInstance()); 70 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey); 71 key = keyFactory.generatePublic(keySpec); 72 } catch (NoSuchAlgorithmException nsae) { 73 // Try to see whether there is another 74 // provider which supports this algorithm 75 try { 76 KeyFactory keyFactory = 77 KeyFactory.getInstance(encodedKeyAlgorithm); 78 X509EncodedKeySpec keySpec = 79 new X509EncodedKeySpec(encodedKey); 80 key = keyFactory.generatePublic(keySpec); 81 } catch (NoSuchAlgorithmException nsae2) { 82 throw new NoSuchAlgorithmException("No installed providers " + 83 "can create keys for the " + 84 encodedKeyAlgorithm + 85 "algorithm"); 86 } catch (InvalidKeySpecException ikse2) { 87 InvalidKeyException ike = 88 new InvalidKeyException("Cannot construct public key"); 89 ike.initCause(ikse2); 90 throw ike; 91 } 92 } catch (InvalidKeySpecException ikse) { 93 InvalidKeyException ike = 94 new InvalidKeyException("Cannot construct public key"); 95 ike.initCause(ikse); 96 throw ike; 97 } 98 99 return key; 100 } 101 102 /** 103 * Construct a private key from its encoding. 104 * 105 * @param encodedKey the encoding of a private key. 106 * 107 * @param encodedKeyAlgorithm the algorithm the wrapped key is for. 108 * 109 * @return a private key constructed from the encodedKey. 110 */ 111 private static final PrivateKey constructPrivateKey(byte[] encodedKey, 112 String encodedKeyAlgorithm) 113 throws InvalidKeyException, NoSuchAlgorithmException 114 { 115 PrivateKey key = null; 116 117 try { 118 KeyFactory keyFactory = 119 KeyFactory.getInstance(encodedKeyAlgorithm, 120 SunJCE.getInstance()); 121 PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey); 122 return keyFactory.generatePrivate(keySpec); 123 } catch (NoSuchAlgorithmException nsae) { 124 // Try to see whether there is another 125 // provider which supports this algorithm 126 try { 127 KeyFactory keyFactory = 128 KeyFactory.getInstance(encodedKeyAlgorithm); 129 PKCS8EncodedKeySpec keySpec = 130 new PKCS8EncodedKeySpec(encodedKey); 131 key = keyFactory.generatePrivate(keySpec); 132 } catch (NoSuchAlgorithmException nsae2) { 133 throw new NoSuchAlgorithmException("No installed providers " + 134 "can create keys for the " + 135 encodedKeyAlgorithm + 136 "algorithm"); 137 } catch (InvalidKeySpecException ikse2) { 138 InvalidKeyException ike = 139 new InvalidKeyException("Cannot construct private key"); 140 ike.initCause(ikse2); 141 throw ike; 142 } 143 } catch (InvalidKeySpecException ikse) { 144 InvalidKeyException ike = 145 new InvalidKeyException("Cannot construct private key"); 146 ike.initCause(ikse); 147 throw ike; 148 } 149 150 return key; 151 } 152 153 /** 154 * Construct a secret key from its encoding. 155 * 156 * @param encodedKey the encoding of a secret key. 157 * 158 * @param encodedKeyAlgorithm the algorithm the secret key is for. 159 * 160 * @return a secret key constructed from the encodedKey. 161 */ 162 private static final SecretKey constructSecretKey(byte[] encodedKey, 163 String encodedKeyAlgorithm) 164 { 165 return (new SecretKeySpec(encodedKey, encodedKeyAlgorithm)); 166 } 167 168 static final Key constructKey(byte[] encoding, String keyAlgorithm, 169 int keyType) 170 throws InvalidKeyException, NoSuchAlgorithmException { 171 Key result = null; 172 switch (keyType) { 173 case Cipher.SECRET_KEY: 174 result = ConstructKeys.constructSecretKey(encoding, 175 keyAlgorithm); 176 break; 177 case Cipher.PRIVATE_KEY: 178 result = ConstructKeys.constructPrivateKey(encoding, 179 keyAlgorithm); 180 break; 181 case Cipher.PUBLIC_KEY: 182 result = ConstructKeys.constructPublicKey(encoding, 183 keyAlgorithm); 184 break; 185 } 186 return result; 187 } 188} 189