1   /* $RCSfile: DESede3KeySpec.java,v $
2    * $Revision: 1.8 $
3    * $Date: 2002/11/23 11:09:57 $
4    * $Author: uwe_guenther $
5    * $State: Exp $
6    *
7    * Created on August 11, 2001 11:18 AM
8    *
9    * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
10   *
11   * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
12   * ServiceProvider is a library, written in JavaTM, that should be 
13   * used in HBCI banking applications (clients and may be servers),
14   * to do cryptographic operations.
15   *
16   * The jhbci library is free software; you can redistribute it and/or
17   * modify it under the terms of the GNU Lesser General Public
18   * License as published by the Free Software Foundation; either
19   * version 2.1 of the License, or (at your option) any later version.
20   *
21   * The jhbci library is distributed in the hope that it will be useful,
22   * but WITHOUT ANY WARRANTY; without even the implied warranty of
23   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24   * Lesser General Public License for more details.
25   *
26   * You should have received a copy of the GNU Lesser General Public
27   * License along with this library; if not, write to the Free Software
28   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29   *
30   */
31  
32  package de.cscc.crypto.provider.spec;
33  
34  import java.security.InvalidKeyException;
35  
36  /** 
37   * 3 Key Triple DES secret keys specification (168 bit or 192 bit with parity)
38   * class.
39   *
40   * <p>This class is immutable.
41   *
42   * @author  <a href=mailto:uwe@cscc.de>Uwe G&uuml;nther</a>
43   * @version $Revision: 1.8 $
44   */
45  public class DESede3KeySpec implements DESKeySpec, Cloneable {
46  
47      /** Key length in bytes. */        
48      private static final int DES_EDE_3KEY_LEN = 24;
49  
50      /** Internal data representation of key1. */    
51      private DES1KeySpec key1;
52      
53      /** Internal data representation of key2. */        
54      private DES1KeySpec key2;
55  
56      /** Internal data representation of key3. */        
57      private DES1KeySpec key3;    
58      
59      /** 
60       * Creates a new DESede3KeySpec from a 24 bytes long byte array.
61       * We use the first 24 bytes in key as the key material for the DES key.
62       *
63       * The first (leftmost) DES key (key[0] to key[7]) is key1,
64       * the second (middle) DES key (key[8] to key[15]) is key2 and
65       * the third (rightmost) DES key (key[16] to key[13]) is key3.
66       *
67       * @param key the buffer with the three DES keys.
68       * @throws InvalidKeyException if the given key material is shorter
69       *                              than 24 bytes or the key is weak or semi weak.
70       */
71      public DESede3KeySpec(byte[] key) throws InvalidKeyException {
72          this(key, 0);
73      }
74      
75      /** 
76       * Creates a new DESede3KeySpec from a 24 bytes long byte array. 
77       *
78       * @param key the buffer with the DES keys.
79       * @param offset the offset in key, where the key starts.
80       * @throws InvalidKeyException if the given key material is shorter
81       *                              than 24 bytes or the key is weak or semi weak.
82       */
83      public DESede3KeySpec(byte[] key, int offset) throws InvalidKeyException {   
84          this.key1 = new DES1KeySpec(key, offset+0);
85          this.key2 = new DES1KeySpec(key, offset+8);
86          this.key3 = new DES1KeySpec(key, offset+16);        
87      }
88  
89      /** 
90       * Creates a new DESede3KeySpec from an existing one.
91       *
92       * @param key DesKeySpec object with a key.
93       */
94      public DESede3KeySpec(DESede3KeySpec key) { 
95          this.key1 = new DES1KeySpec(key.key1);
96          this.key2 = new DES1KeySpec(key.key2);
97          this.key3 = new DES1KeySpec(key.key3);
98      } 
99  
100     /** 
101      * Creates and returns a deep copy of this object.
102      *
103      * @return a clone of this instance.
104      * @see java.lang.Cloneable
105      * @exception CloneNotSupportedException if the object's class does not
106      *             support the <code>Cloneable</code> interface. Subclasses
107      *             that override the <code>clone</code> method can also
108      *             throw this exception to indicate that an instance cannot
109      *             be cloned.
110      */        
111     public Object clone() throws CloneNotSupportedException {
112        DESede3KeySpec result = (DESede3KeySpec) super.clone();
113        result.key1 = (DES1KeySpec) this.key1.clone();
114        result.key2 = (DES1KeySpec) this.key2.clone();
115        result.key3 = (DES1KeySpec) this.key3.clone();
116        return result;
117     }
118         
119     /** 
120      * Indicates whether some other object is "equal to" this one.
121      *
122      * @param   obj   the reference object with which to compare.
123      * @return  <code>true</code> if this object is the same as the obj
124      *         argument; <code>false</code> otherwise.
125      * @see     #hashCode()
126      * @see     java.util.Hashtable
127      */        
128     public boolean equals(Object obj) {
129         //Only for performance.
130         if (this == obj) {
131             return true;
132         } 
133         
134         //If obj == null then instanceof returns false, see JLS 15.20.2
135         if (!(obj instanceof DESede3KeySpec)) {
136             return false;
137         }
138         
139         DESede3KeySpec other = (DESede3KeySpec)obj;
140         return this.key1.equals(other.key1) &&
141                this.key2.equals(other.key2) &&
142                this.key3.equals(other.key3)  ;
143     }
144     
145     /**
146      * Returns a hash code value for the object. This method is
147      * supported for the benefit of hashtables such as those provided by
148      * <code>java.util.Hashtable</code>.
149      *
150      * @return  a hash code value for this object.
151      * @see     #equals(java.lang.Object)
152      * @see     java.util.Hashtable
153      */    
154     public int hashCode() {
155         int result = 17;
156         result = 37*result + this.key1.hashCode();
157         result = 37*result + this.key2.hashCode();
158         result = 37*result + this.key3.hashCode();
159         return result;
160     }    
161 
162     /** 
163      * Returns a string representation of the object. 
164      * The Format may catch (change in further releases.
165      *
166      * @return  a string representation of the object.
167      */     
168     public String toString() {    
169         return "key1: [" + this.key1 + "] " +
170                "key2: [" + this.key2 + "] " +
171                "key3: [" + this.key3 + "]";
172     }
173 
174     /** 
175      * Get the DES Key as byte[24].
176      *
177      * @return the DES Key as byte[24]. 
178      */    
179     public byte[] getKey() {
180         byte[] returnValue = new byte[24];
181         System.arraycopy(this.key1.getKey(), 0, returnValue, 0, 8);
182         System.arraycopy(this.key2.getKey(), 0, returnValue, 8, 8);
183         System.arraycopy(this.key3.getKey(), 0, returnValue, 16, 8);
184         return returnValue;
185     }
186 }
187