view app/src/main/java/ch/ethz/ssh2/signature/RSASHA1Verify.java @ 462:0f53523562bb
update TODO
author |
Carl Byington <carl@five-ten-sg.com> |
date |
Sun, 28 Apr 2019 17:46:13 -0700 (2019-04-29) |
parents |
d29cce60f393 |
children |
|
line source
package ch.ethz.ssh2.signature;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import java.security.SignatureException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.security.spec.RSAPublicKeySpec;
import ch.ethz.ssh2.log.Logger;
import ch.ethz.ssh2.packets.TypesReader;
import ch.ethz.ssh2.packets.TypesWriter;
/**
* RSASHA1Verify.
*
* @author Christian Plattner, plattner@trilead.com
* @version $Id: RSASHA1Verify.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
*/
public class RSASHA1Verify {
private static final Logger log = Logger.getLogger(RSASHA1Verify.class);
public static RSAPublicKey decodeSSHRSAPublicKey(byte[] key) throws IOException {
TypesReader tr = new TypesReader(key);
String key_format = tr.readString();
if (key_format.equals("ssh-rsa") == false)
throw new IllegalArgumentException("This is not a ssh-rsa public key");
BigInteger e = tr.readMPINT();
BigInteger n = tr.readMPINT();
if (tr.remain() != 0)
throw new IOException("Padding in RSA public key!");
KeySpec keySpec = new RSAPublicKeySpec(n, e);
try {
KeyFactory kf = KeyFactory.getInstance("RSA");
return (RSAPublicKey) kf.generatePublic(keySpec);
}
catch (NoSuchAlgorithmException nsae) {
IOException ioe = new IOException("No RSA KeyFactory available");
ioe.initCause(nsae);
throw ioe;
}
catch (InvalidKeySpecException ikse) {
IOException ioe = new IOException("No RSA KeyFactory available");
ioe.initCause(ikse);
throw ioe;
}
}
public static byte[] encodeSSHRSAPublicKey(RSAPublicKey pk) throws IOException {
TypesWriter tw = new TypesWriter();
tw.writeString("ssh-rsa");
tw.writeMPInt(pk.getPublicExponent());
tw.writeMPInt(pk.getModulus());
return tw.getBytes();
}
public static byte[] decodeSSHRSASignature(byte[] sig) throws IOException {
TypesReader tr = new TypesReader(sig);
String sig_format = tr.readString();
if (sig_format.equals("ssh-rsa") == false)
throw new IOException("Peer sent wrong signature format");
/* S is NOT an MPINT. "The value for 'rsa_signature_blob' is encoded as a string
* containing s (which is an integer, without lengths or padding, unsigned and in
* network byte order)." See also below.
*/
byte[] s = tr.readByteString();
if (s.length == 0)
throw new IOException("Error in RSA signature, S is empty.");
if (log.isEnabled()) {
log.info("Decoding ssh-rsa signature string (length: " + s.length + ")");
}
if (tr.remain() != 0)
throw new IOException("Padding in RSA signature!");
if (s[0] == 0 && s[1] == 0 && s[2] == 0) {
int i = 0;
int j = ((s[i++] << 24) & 0xff000000) | ((s[i++] << 16) & 0x00ff0000)
| ((s[i++] << 8) & 0x0000ff00) | ((s[i++]) & 0x000000ff);
i += j;
j = ((s[i++] << 24) & 0xff000000) | ((s[i++] << 16) & 0x00ff0000)
| ((s[i++] << 8) & 0x0000ff00) | ((s[i++]) & 0x000000ff);
byte[] tmp = new byte[j];
System.arraycopy(s, i, tmp, 0, j);
sig = tmp;
}
return s;
}
public static byte[] encodeSSHRSASignature(byte[] s) throws IOException {
TypesWriter tw = new TypesWriter();
tw.writeString("ssh-rsa");
/* S is NOT an MPINT. "The value for 'rsa_signature_blob' is encoded as a string
* containing s (which is an integer, without lengths or padding, unsigned and in
* network byte order)."
*/
/* Remove first zero sign byte, if present */
if ((s.length > 1) && (s[0] == 0x00))
tw.writeString(s, 1, s.length - 1);
else
tw.writeString(s, 0, s.length);
return tw.getBytes();
}
public static byte[] generateSignature(byte[] message, RSAPrivateKey pk) throws IOException {
try {
Signature s = Signature.getInstance("SHA1withRSA");
s.initSign(pk);
s.update(message);
return s.sign();
}
catch (NoSuchAlgorithmException e) {
IOException ex = new IOException();
ex.initCause(e);
throw ex;
}
catch (InvalidKeyException e) {
IOException ex = new IOException();
ex.initCause(e);
throw ex;
}
catch (SignatureException e) {
IOException ex = new IOException();
ex.initCause(e);
throw ex;
}
}
public static boolean verifySignature(byte[] message, byte[] ds, RSAPublicKey dpk) throws IOException {
try {
Signature s = Signature.getInstance("SHA1withRSA");
s.initVerify(dpk);
s.update(message);
return s.verify(ds);
}
catch (NoSuchAlgorithmException e) {
IOException ex = new IOException();
ex.initCause(e);
throw ex;
}
catch (InvalidKeyException e) {
IOException ex = new IOException();
ex.initCause(e);
throw ex;
}
catch (SignatureException e) {
IOException ex = new IOException();
ex.initCause(e);
throw ex;
}
}
}