1 19 20 package com.sslexplorer.security.pki.dsa; 21 22 import java.io.ByteArrayOutputStream ; 23 import java.io.IOException ; 24 import java.math.BigInteger ; 25 import java.security.KeyFactory ; 26 import java.security.NoSuchAlgorithmException ; 27 import java.security.PublicKey ; 28 import java.security.Signature ; 29 import java.security.SignatureException ; 30 import java.security.interfaces.DSAPublicKey ; 31 import java.security.spec.DSAPublicKeySpec ; 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 48 public class SshDssPublicKey extends SshPublicKey { 49 private static Log log = LogFactory.getLog(SshDssPublicKey.class); 50 private DSAPublicKey pubkey; 51 52 57 public SshDssPublicKey(DSAPublicKey key) { 58 this.pubkey = key; 59 } 60 61 68 public SshDssPublicKey(byte[] key) throws InvalidKeyException { 69 try { 70 DSAPublicKeySpec dsaKey; 71 72 ByteArrayReader bar = new ByteArrayReader(key); 74 String header = bar.readString(); 75 76 if (!header.equals(getAlgorithmName())) { 77 throw new InvalidKeyException(); 78 } 79 80 BigInteger p = bar.readBigInteger(); 81 BigInteger q = bar.readBigInteger(); 82 BigInteger g = bar.readBigInteger(); 83 BigInteger y = bar.readBigInteger(); 84 dsaKey = new DSAPublicKeySpec (y, p, q, g); 85 86 KeyFactory kf = KeyFactory.getInstance("DSA"); 87 88 pubkey = (DSAPublicKey ) kf.generatePublic(dsaKey); 89 } catch (Exception e) { 90 throw new InvalidKeyException(); 91 } 92 } 93 94 public PublicKey getPublicKey() { 95 return pubkey; 96 } 97 98 103 public String getAlgorithmName() { 104 return "ssh-dss"; 105 } 106 107 112 public int getBitLength() { 113 return pubkey.getY().bitLength(); 114 } 115 116 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 ioe) { 132 return null; 133 } 134 } 135 136 146 public boolean verifySignature(byte[] signature, byte[] data) 147 throws InvalidSignatureException { 148 try { 149 if (signature.length != 40) { 151 ByteArrayReader bar = new ByteArrayReader(signature); 152 byte[] sig = bar.readBinaryString(); 153 154 String header = new String (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 } 167 168 ByteArrayOutputStream r = new ByteArrayOutputStream (); 170 ByteArrayOutputStream s = new ByteArrayOutputStream (); 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 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 222 243 Signature sig = Signature.getInstance("SHA1withDSA"); 244 sig.initVerify(pubkey); 245 sig.update(data); 246 247 return sig.verify(encoded); 248 } catch (NoSuchAlgorithmException nsae) { 249 throw new InvalidSignatureException(); 250 } catch (java.security.InvalidKeyException ike) { 251 throw new InvalidSignatureException(); 252 } catch (IOException ioe) { 253 throw new InvalidSignatureException(); 254 } catch (SignatureException se) { 255 throw new InvalidSignatureException(); 256 } 257 } 258 } 259 | Popular Tags |