1/* 2 * Copyright (c) 1997, 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 javax.crypto.SecretKey; 29import javax.crypto.SecretKeyFactorySpi; 30import javax.crypto.spec.DESedeKeySpec; 31import java.security.InvalidKeyException; 32import java.security.spec.KeySpec; 33import java.security.spec.InvalidKeySpecException; 34import javax.crypto.spec.SecretKeySpec; 35 36/** 37 * This class implements the DES-EDE key factory of the Sun provider. 38 * 39 * @author Jan Luehe 40 * 41 */ 42 43public final class DESedeKeyFactory extends SecretKeyFactorySpi { 44 45 /** 46 * Empty constructor 47 */ 48 public DESedeKeyFactory() { 49 } 50 51 /** 52 * Generates a <code>SecretKey</code> object from the provided key 53 * specification (key material). 54 * 55 * @param keySpec the specification (key material) of the secret key 56 * 57 * @return the secret key 58 * 59 * @exception InvalidKeySpecException if the given key specification 60 * is inappropriate for this key factory to produce a public key. 61 */ 62 protected SecretKey engineGenerateSecret(KeySpec keySpec) 63 throws InvalidKeySpecException { 64 65 try { 66 if (keySpec instanceof DESedeKeySpec) { 67 return new DESedeKey(((DESedeKeySpec)keySpec).getKey()); 68 } 69 if (keySpec instanceof SecretKeySpec) { 70 return new DESedeKey(((SecretKeySpec)keySpec).getEncoded()); 71 72 } 73 throw new InvalidKeySpecException 74 ("Inappropriate key specification"); 75 } catch (InvalidKeyException e) { 76 throw new InvalidKeySpecException(e.getMessage()); 77 } 78 } 79 80 /** 81 * Returns a specification (key material) of the given key 82 * in the requested format. 83 * 84 * @param key the key 85 * 86 * @param keySpec the requested format in which the key material shall be 87 * returned 88 * 89 * @return the underlying key specification (key material) in the 90 * requested format 91 * 92 * @exception InvalidKeySpecException if the requested key specification is 93 * inappropriate for the given key, or the given key cannot be processed 94 * (e.g., the given key has an unrecognized algorithm or format). 95 */ 96 protected KeySpec engineGetKeySpec(SecretKey key, Class<?> keySpec) 97 throws InvalidKeySpecException { 98 99 try { 100 if ((key instanceof SecretKey) 101 && (key.getAlgorithm().equalsIgnoreCase("DESede")) 102 && (key.getFormat().equalsIgnoreCase("RAW"))) { 103 104 // Check if requested key spec is amongst the valid ones 105 if (DESedeKeySpec.class.isAssignableFrom(keySpec)) { 106 return new DESedeKeySpec(key.getEncoded()); 107 108 } else { 109 throw new InvalidKeySpecException 110 ("Inappropriate key specification"); 111 } 112 113 } else { 114 throw new InvalidKeySpecException 115 ("Inappropriate key format/algorithm"); 116 } 117 } catch (InvalidKeyException e) { 118 throw new InvalidKeySpecException("Secret key has wrong size"); 119 } 120 } 121 122 /** 123 * Translates a <code>SecretKey</code> object, whose provider may be 124 * unknown or potentially untrusted, into a corresponding 125 * <code>SecretKey</code> object of this key factory. 126 * 127 * @param key the key whose provider is unknown or untrusted 128 * 129 * @return the translated key 130 * 131 * @exception InvalidKeyException if the given key cannot be processed by 132 * this key factory. 133 */ 134 protected SecretKey engineTranslateKey(SecretKey key) 135 throws InvalidKeyException { 136 137 try { 138 139 if ((key != null) 140 && (key.getAlgorithm().equalsIgnoreCase("DESede")) 141 && (key.getFormat().equalsIgnoreCase("RAW"))) { 142 // Check if key originates from this factory 143 if (key instanceof com.sun.crypto.provider.DESedeKey) { 144 return key; 145 } 146 // Convert key to spec 147 DESedeKeySpec desEdeKeySpec 148 = (DESedeKeySpec)engineGetKeySpec(key, 149 DESedeKeySpec.class); 150 // Create key from spec, and return it 151 return engineGenerateSecret(desEdeKeySpec); 152 153 } else { 154 throw new InvalidKeyException 155 ("Inappropriate key format/algorithm"); 156 } 157 158 } catch (InvalidKeySpecException e) { 159 throw new InvalidKeyException("Cannot translate key"); 160 } 161 } 162} 163