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