KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sslexplorer > security > pki > dsa > SshDssPublicKey


1 /*
2  * SSL-Explorer
3  *
4  * Copyright (C) 2003-2006 3SP LTD. All Rights Reserved
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2 of
9  * the License, or (at your option) any later version.
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this program; if not, write to the Free Software
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */

19             
20 package com.sslexplorer.security.pki.dsa;
21
22 import java.io.ByteArrayOutputStream JavaDoc;
23 import java.io.IOException JavaDoc;
24 import java.math.BigInteger JavaDoc;
25 import java.security.KeyFactory JavaDoc;
26 import java.security.NoSuchAlgorithmException JavaDoc;
27 import java.security.PublicKey JavaDoc;
28 import java.security.Signature JavaDoc;
29 import java.security.SignatureException JavaDoc;
30 import java.security.interfaces.DSAPublicKey JavaDoc;
31 import java.security.spec.DSAPublicKeySpec JavaDoc;
32
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35
36 import com.maverick.util.ByteArrayReader;
37 import com.maverick.util.ByteArrayWriter;
38 import com.sslexplorer.security.pki.InvalidKeyException;
39 import com.sslexplorer.security.pki.InvalidSignatureException;
40 import com.sslexplorer.security.pki.SimpleASNWriter;
41 import com.sslexplorer.security.pki.SshPublicKey;
42
43 /**
44  *
45  *
46  * @author $author$
47  */

48 public class SshDssPublicKey extends SshPublicKey {
49     private static Log log = LogFactory.getLog(SshDssPublicKey.class);
50     private DSAPublicKey JavaDoc pubkey;
51
52     /**
53      * Creates a new SshDssPublicKey object.
54      *
55      * @param key
56      */

57     public SshDssPublicKey(DSAPublicKey JavaDoc key) {
58         this.pubkey = key;
59     }
60
61     /**
62      * Creates a new SshDssPublicKey object.
63      *
64      * @param key
65      *
66      * @throws InvalidKeyException
67      */

68     public SshDssPublicKey(byte[] key) throws InvalidKeyException {
69         try {
70             DSAPublicKeySpec JavaDoc dsaKey;
71
72             // Extract the key information
73
ByteArrayReader bar = new ByteArrayReader(key);
74             String JavaDoc header = bar.readString();
75
76             if (!header.equals(getAlgorithmName())) {
77                 throw new InvalidKeyException();
78             }
79
80             BigInteger JavaDoc p = bar.readBigInteger();
81             BigInteger JavaDoc q = bar.readBigInteger();
82             BigInteger JavaDoc g = bar.readBigInteger();
83             BigInteger JavaDoc y = bar.readBigInteger();
84             dsaKey = new DSAPublicKeySpec JavaDoc(y, p, q, g);
85
86             KeyFactory JavaDoc kf = KeyFactory.getInstance("DSA");
87             
88             pubkey = (DSAPublicKey JavaDoc) kf.generatePublic(dsaKey);
89         } catch (Exception JavaDoc e) {
90             throw new InvalidKeyException();
91         }
92     }
93     
94     public PublicKey JavaDoc getPublicKey() {
95         return pubkey;
96     }
97
98     /**
99      *
100      *
101      * @return
102      */

103     public String JavaDoc getAlgorithmName() {
104         return "ssh-dss";
105     }
106
107     /**
108      *
109      *
110      * @return
111      */

112     public int getBitLength() {
113         return pubkey.getY().bitLength();
114     }
115
116     /**
117      *
118      *
119      * @return
120      */

121     public byte[] getEncoded() {
122         try {
123             ByteArrayWriter baw = new ByteArrayWriter();
124             baw.writeString(getAlgorithmName());
125             baw.writeBigInteger(pubkey.getParams().getP());
126             baw.writeBigInteger(pubkey.getParams().getQ());
127             baw.writeBigInteger(pubkey.getParams().getG());
128             baw.writeBigInteger(pubkey.getY());
129
130             return baw.toByteArray();
131         } catch (IOException JavaDoc ioe) {
132             return null;
133         }
134     }
135
136     /**
137      *
138      *
139      * @param signature
140      * @param data
141      *
142      * @return
143      *
144      * @throws InvalidSshKeySignatureException
145      */

146     public boolean verifySignature(byte[] signature, byte[] data)
147         throws InvalidSignatureException {
148         try {
149             // Check for differing version of the transport protocol
150
if (signature.length != 40) {
151                 ByteArrayReader bar = new ByteArrayReader(signature);
152                 byte[] sig = bar.readBinaryString();
153
154                 //if (log.isDebugEnabled()) {log.debug("Signature blob is " + new String(sig));}
155
String JavaDoc header = new String JavaDoc(sig);
156                 if (log.isDebugEnabled())
157                     log.debug("Header is " + header);
158
159                 if (!header.equals("ssh-dss")) {
160                     throw new InvalidSignatureException();
161                 }
162
163                 signature = bar.readBinaryString();
164
165                 //if (log.isDebugEnabled()) {log.debug("Read signature from blob: " + new String(signature));}
166
}
167
168             // Using a SimpleASNWriter
169
ByteArrayOutputStream JavaDoc r = new ByteArrayOutputStream JavaDoc();
170             ByteArrayOutputStream JavaDoc s = new ByteArrayOutputStream JavaDoc();
171             SimpleASNWriter asn = new SimpleASNWriter();
172             asn.writeByte(0x02);
173
174             if (((signature[0] & 0x80) == 0x80) && (signature[0] != 0x00)) {
175                 r.write(0);
176                 r.write(signature, 0, 20);
177             } else {
178                 r.write(signature, 0, 20);
179             }
180
181             asn.writeData(r.toByteArray());
182             asn.writeByte(0x02);
183
184             if (((signature[20] & 0x80) == 0x80) && (signature[20] != 0x00)) {
185                 s.write(0);
186                 s.write(signature, 20, 20);
187             } else {
188                 s.write(signature, 20, 20);
189             }
190
191             asn.writeData(s.toByteArray());
192
193             SimpleASNWriter asnEncoded = new SimpleASNWriter();
194             asnEncoded.writeByte(0x30);
195             asnEncoded.writeData(asn.toByteArray());
196
197             byte[] encoded = asnEncoded.toByteArray();
198
199             if (log.isDebugEnabled()) {
200                 log.debug("Verifying host key signature");
201                 log.debug("Signature length is " +
202                     String.valueOf(signature.length));
203
204                 String JavaDoc hex = "";
205
206                 for (int i = 0; i < signature.length; i++) {
207                     hex += (Integer.toHexString(signature[i] & 0xFF) + " ");
208                 }
209
210                 log.debug("SSH: " + hex);
211                 hex = "";
212
213                 for (int i = 0; i < encoded.length; i++) {
214                     hex += (Integer.toHexString(encoded[i] & 0xFF) + " ");
215                 }
216
217                 log.debug("Encoded: " + hex);
218             }
219
220             // The previous way
221

222             /*byte[] encoded;
223                          // Determine the encoded length of the big integers
224                          int rlen = (((signature[0] & 0x80) == 0x80) ? 0x15 : 0x14);
225                          log.debug("rlen=" + String.valueOf(rlen));
226                          int slen = (((signature[20] & 0x80) == 0x80) ? 0x15 : 0x14);
227                          log.debug("slen=" + String.valueOf(slen));
228                  byte[] asn1r = { 0x30, (byte) (rlen + slen + 4), 0x02, (byte) rlen };
229                          byte[] asn1s = { 0x02, (byte) slen };
230                          // Create the encoded byte array
231                  encoded = new byte[asn1r.length + rlen + asn1s.length + slen];
232                          // Copy the data and encode it into the array
233                          System.arraycopy(asn1r, 0, encoded, 0, asn1r.length);
234                          // Copy the integer inserting a zero byte if signed
235                          int roffset = (((signature[0] & 0x80) == 0x80) ? 1 : 0);
236                  System.arraycopy(signature, 0, encoded, asn1r.length + roffset, 20);
237                  System.arraycopy(asn1s, 0, encoded, asn1r.length + roffset + 20,
238                 asn1s.length);
239                          int soffset = (((signature[20] & 0x80) == 0x80) ? 1 : 0);
240                          System.arraycopy(signature, 20, encoded,
241                 asn1r.length + roffset + 20 + asn1s.length + soffset, 20);
242              */

243             Signature JavaDoc sig = Signature.getInstance("SHA1withDSA");
244             sig.initVerify(pubkey);
245             sig.update(data);
246
247             return sig.verify(encoded);
248         } catch (NoSuchAlgorithmException JavaDoc nsae) {
249             throw new InvalidSignatureException();
250         } catch (java.security.InvalidKeyException JavaDoc ike) {
251             throw new InvalidSignatureException();
252         } catch (IOException JavaDoc ioe) {
253             throw new InvalidSignatureException();
254         } catch (SignatureException JavaDoc se) {
255             throw new InvalidSignatureException();
256         }
257     }
258 }
259
Popular Tags