kex exception handling cleanups

This commit is contained in:
Shikhar Bhushan
2010-03-21 17:24:46 +01:00
parent 49e3d4ec27
commit 63b321e8d1
7 changed files with 71 additions and 117 deletions

View File

@@ -47,6 +47,7 @@ import net.schmizz.sshj.transport.verification.HostKeyVerifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.util.Arrays;
import java.util.LinkedList;
@@ -228,8 +229,12 @@ final class KeyExchanger
log.debug("Negotiated algorithms: {}", negotiatedAlgs);
kex = Factory.Named.Util.create(transport.getConfig().getKeyExchangeFactories(), negotiatedAlgs
.getKeyExchangeAlgorithm());
kex.init(transport, transport.getServerID().getBytes(), transport.getClientID().getBytes(), buf
.getCompactData(), clientProposal.getPacket().getCompactData());
try {
kex.init(transport, transport.getServerID().getBytes(), transport.getClientID().getBytes(), buf
.getCompactData(), clientProposal.getPacket().getCompactData());
} catch (GeneralSecurityException e) {
throw new TransportException(DisconnectReason.KEY_EXCHANGE_FAILED, e);
}
}
/**
@@ -347,10 +352,14 @@ final class KeyExchanger
case FOLLOWUP:
ensureKexOngoing();
log.info("Received kex followup data");
if (kex.next(msg, buf)) {
verifyHost(kex.getHostKey());
sendNewKeys();
expected = Expected.NEWKEYS;
try {
if (kex.next(msg, buf)) {
verifyHost(kex.getHostKey());
sendNewKeys();
expected = Expected.NEWKEYS;
}
} catch (GeneralSecurityException e) {
throw new TransportException(DisconnectReason.KEY_EXCHANGE_FAILED, e);
}
break;

View File

@@ -51,6 +51,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
/**
@@ -81,6 +82,10 @@ public abstract class AbstractDHG
return ByteArrayUtils.copyOf(H);
}
public byte[] getK() {
return ByteArrayUtils.copyOf(K);
}
public Digest getHash() {
return sha;
}
@@ -89,12 +94,8 @@ public abstract class AbstractDHG
return hostKey;
}
public byte[] getK() {
return ByteArrayUtils.copyOf(K);
}
public void init(Transport trans, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
throws TransportException {
throws GeneralSecurityException, TransportException {
this.trans = trans;
this.V_S = ByteArrayUtils.copyOf(V_S);
this.V_C = ByteArrayUtils.copyOf(V_C);
@@ -109,7 +110,7 @@ public abstract class AbstractDHG
}
public boolean next(Message msg, SSHPacket packet)
throws TransportException {
throws GeneralSecurityException, TransportException {
if (msg != Message.KEXDH_31)
throw new TransportException(DisconnectReason.KEY_EXCHANGE_FAILED, "Unexpected packet: " + msg);
@@ -139,7 +140,8 @@ public abstract class AbstractDHG
signature.init(hostKey, null);
signature.update(H, 0, H.length);
if (!signature.verify(sig))
throw new TransportException(DisconnectReason.KEY_EXCHANGE_FAILED, "KeyExchange signature verification failed");
throw new TransportException(DisconnectReason.KEY_EXCHANGE_FAILED,
"KeyExchange signature verification failed");
return true;
}

View File

@@ -56,17 +56,16 @@ public class DH {
private BigInteger e; // my public key
private BigInteger f; // your public key
private BigInteger K; // shared secret key
private final KeyPairGenerator myKpairGen;
private final KeyAgreement myKeyAgree;
private final KeyPairGenerator generator;
private final KeyAgreement agreement;
public DH() {
try {
myKpairGen = SecurityUtils.getKeyPairGenerator("DH");
myKeyAgree = SecurityUtils.getKeyAgreement("DH");
generator = SecurityUtils.getKeyPairGenerator("DH");
agreement = SecurityUtils.getKeyAgreement("DH");
} catch (GeneralSecurityException e) {
throw new SSHRuntimeException(e);
}
}
public void setF(BigInteger f) {
@@ -81,33 +80,25 @@ public class DH {
this.p = p;
}
public byte[] getE() {
public byte[] getE()
throws GeneralSecurityException {
if (e == null) {
DHParameterSpec dhSkipParamSpec = new DHParameterSpec(p, g);
KeyPair myKpair;
try {
myKpairGen.initialize(dhSkipParamSpec);
myKpair = myKpairGen.generateKeyPair();
myKeyAgree.init(myKpair.getPrivate());
} catch (GeneralSecurityException e) {
throw new SSHRuntimeException(e);
}
e = ((javax.crypto.interfaces.DHPublicKey) myKpair.getPublic()).getY();
generator.initialize(new DHParameterSpec(p, g));
final KeyPair kp = generator.generateKeyPair();
agreement.init(kp.getPrivate());
e = ((javax.crypto.interfaces.DHPublicKey) kp.getPublic()).getY();
}
return e.toByteArray();
}
public byte[] getK() {
public byte[] getK()
throws GeneralSecurityException {
if (K == null) {
try {
KeyFactory myKeyFac = SecurityUtils.getKeyFactory("DH");
DHPublicKeySpec keySpec = new DHPublicKeySpec(f, p, g);
PublicKey yourPubKey = myKeyFac.generatePublic(keySpec);
myKeyAgree.doPhase(yourPubKey, true);
} catch (GeneralSecurityException e) {
throw new SSHRuntimeException(e);
}
K = new BigInteger(myKeyAgree.generateSecret());
final KeyFactory keyFactory = SecurityUtils.getKeyFactory("DH");
final DHPublicKeySpec keySpec = new DHPublicKeySpec(f, p, g);
final PublicKey yourPubKey = keyFactory.generatePublic(keySpec);
agreement.doPhase(yourPubKey, true);
K = new BigInteger(agreement.generateSecret());
}
return K.toByteArray();
}

View File

@@ -59,8 +59,8 @@ public class DHG1
@Override
protected void initDH(DH dh) {
dh.setG(DHGroupData.getG());
dh.setP(DHGroupData.getP1());
dh.setG(DHGroupData.G);
dh.setP(DHGroupData.P1);
}
}

View File

@@ -60,8 +60,8 @@ public class DHG14
@Override
protected void initDH(DH dh) {
dh.setG(DHGroupData.getG());
dh.setP(DHGroupData.getP14());
dh.setG(DHGroupData.G);
dh.setP(DHGroupData.P14);
}
}

View File

@@ -40,74 +40,23 @@ import java.math.BigInteger;
/** Simple class holding the data for DH group key exchanges. */
public final class DHGroupData {
private static final BigInteger G = new BigInteger(new byte[]{2});
public static final BigInteger G =
new BigInteger("2");
private static final BigInteger P1 = new BigInteger(new byte[]{
(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2,
(byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C,
(byte) 0xD1, (byte) 0x29, (byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC,
(byte) 0x74, (byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B,
(byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34, (byte) 0x04,
(byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A, (byte) 0x43,
(byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D, (byte) 0xF2, (byte) 0x5F, (byte) 0x14,
(byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2,
(byte) 0x45, (byte) 0xE4, (byte) 0x85, (byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E,
(byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED,
(byte) 0x6B, (byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7,
(byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89, (byte) 0x9F,
(byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C, (byte) 0x4B, (byte) 0x1F,
(byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51, (byte) 0xEC, (byte) 0xE6, (byte) 0x53,
(byte) 0x81, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF
});
public static final BigInteger P1 =
new BigInteger("1797693134862315907708391567937874531978602960487560117064444236841971802161585193" +
"6894783379586492554150218056548598050364644054819923910005079287700335581663922955" +
"3136239076508735759914822574862575007425302077447712589550957937778424442426617334" +
"727629299387668709205606050270810842907692932019128194467627007");
private static final BigInteger P14 = new BigInteger(new byte[]{
(byte) 0x00, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF, (byte) 0xC9, (byte) 0x0F, (byte) 0xDA, (byte) 0xA2, (byte) 0x21, (byte) 0x68, (byte) 0xC2,
(byte) 0x34, (byte) 0xC4, (byte) 0xC6, (byte) 0x62, (byte) 0x8B, (byte) 0x80, (byte) 0xDC, (byte) 0x1C,
(byte) 0xD1, (byte) 0x29, (byte) 0x02, (byte) 0x4E, (byte) 0x08, (byte) 0x8A, (byte) 0x67, (byte) 0xCC,
(byte) 0x74, (byte) 0x02, (byte) 0x0B, (byte) 0xBE, (byte) 0xA6, (byte) 0x3B, (byte) 0x13, (byte) 0x9B,
(byte) 0x22, (byte) 0x51, (byte) 0x4A, (byte) 0x08, (byte) 0x79, (byte) 0x8E, (byte) 0x34, (byte) 0x04,
(byte) 0xDD, (byte) 0xEF, (byte) 0x95, (byte) 0x19, (byte) 0xB3, (byte) 0xCD, (byte) 0x3A, (byte) 0x43,
(byte) 0x1B, (byte) 0x30, (byte) 0x2B, (byte) 0x0A, (byte) 0x6D, (byte) 0xF2, (byte) 0x5F, (byte) 0x14,
(byte) 0x37, (byte) 0x4F, (byte) 0xE1, (byte) 0x35, (byte) 0x6D, (byte) 0x6D, (byte) 0x51, (byte) 0xC2,
(byte) 0x45, (byte) 0xE4, (byte) 0x85, (byte) 0xB5, (byte) 0x76, (byte) 0x62, (byte) 0x5E, (byte) 0x7E,
(byte) 0xC6, (byte) 0xF4, (byte) 0x4C, (byte) 0x42, (byte) 0xE9, (byte) 0xA6, (byte) 0x37, (byte) 0xED,
(byte) 0x6B, (byte) 0x0B, (byte) 0xFF, (byte) 0x5C, (byte) 0xB6, (byte) 0xF4, (byte) 0x06, (byte) 0xB7,
(byte) 0xED, (byte) 0xEE, (byte) 0x38, (byte) 0x6B, (byte) 0xFB, (byte) 0x5A, (byte) 0x89, (byte) 0x9F,
(byte) 0xA5, (byte) 0xAE, (byte) 0x9F, (byte) 0x24, (byte) 0x11, (byte) 0x7C, (byte) 0x4B, (byte) 0x1F,
(byte) 0xE6, (byte) 0x49, (byte) 0x28, (byte) 0x66, (byte) 0x51, (byte) 0xEC, (byte) 0xE4, (byte) 0x5B,
(byte) 0x3D, (byte) 0xC2, (byte) 0x00, (byte) 0x7C, (byte) 0xB8, (byte) 0xA1, (byte) 0x63, (byte) 0xBF,
(byte) 0x05, (byte) 0x98, (byte) 0xDA, (byte) 0x48, (byte) 0x36, (byte) 0x1C, (byte) 0x55, (byte) 0xD3,
(byte) 0x9A, (byte) 0x69, (byte) 0x16, (byte) 0x3F, (byte) 0xA8, (byte) 0xFD, (byte) 0x24, (byte) 0xCF,
(byte) 0x5F, (byte) 0x83, (byte) 0x65, (byte) 0x5D, (byte) 0x23, (byte) 0xDC, (byte) 0xA3, (byte) 0xAD,
(byte) 0x96, (byte) 0x1C, (byte) 0x62, (byte) 0xF3, (byte) 0x56, (byte) 0x20, (byte) 0x85, (byte) 0x52,
(byte) 0xBB, (byte) 0x9E, (byte) 0xD5, (byte) 0x29, (byte) 0x07, (byte) 0x70, (byte) 0x96, (byte) 0x96,
(byte) 0x6D, (byte) 0x67, (byte) 0x0C, (byte) 0x35, (byte) 0x4E, (byte) 0x4A, (byte) 0xBC, (byte) 0x98,
(byte) 0x04, (byte) 0xF1, (byte) 0x74, (byte) 0x6C, (byte) 0x08, (byte) 0xCA, (byte) 0x18, (byte) 0x21,
(byte) 0x7C, (byte) 0x32, (byte) 0x90, (byte) 0x5E, (byte) 0x46, (byte) 0x2E, (byte) 0x36, (byte) 0xCE,
(byte) 0x3B, (byte) 0xE3, (byte) 0x9E, (byte) 0x77, (byte) 0x2C, (byte) 0x18, (byte) 0x0E, (byte) 0x86,
(byte) 0x03, (byte) 0x9B, (byte) 0x27, (byte) 0x83, (byte) 0xA2, (byte) 0xEC, (byte) 0x07, (byte) 0xA2,
(byte) 0x8F, (byte) 0xB5, (byte) 0xC5, (byte) 0x5D, (byte) 0xF0, (byte) 0x6F, (byte) 0x4C, (byte) 0x52,
(byte) 0xC9, (byte) 0xDE, (byte) 0x2B, (byte) 0xCB, (byte) 0xF6, (byte) 0x95, (byte) 0x58, (byte) 0x17,
(byte) 0x18, (byte) 0x39, (byte) 0x95, (byte) 0x49, (byte) 0x7C, (byte) 0xEA, (byte) 0x95, (byte) 0x6A,
(byte) 0xE5, (byte) 0x15, (byte) 0xD2, (byte) 0x26, (byte) 0x18, (byte) 0x98, (byte) 0xFA, (byte) 0x05,
(byte) 0x10, (byte) 0x15, (byte) 0x72, (byte) 0x8E, (byte) 0x5A, (byte) 0x8A, (byte) 0xAC, (byte) 0xAA,
(byte) 0x68, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF,
(byte) 0xFF
});
public static BigInteger getG() {
return G;
}
public static BigInteger getP1() {
return P1;
}
public static BigInteger getP14() {
return P14;
}
public static final BigInteger P14 =
new BigInteger("3231700607131100730033891392642382824881794124114023911284200975140074170663435422" +
"2619689417363569347117901737909704191754605873209195028853758986185622153212175412" +
"5149017745202702357960782362488842461894775876411059286460994117232454266225221932" +
"3054091903768052423551912567971587011700105805587765103886184728025797605490356973" +
"2561526167081339361799541336476559160368317896729073178384589680639671900977202194" +
"1686472258710314113364293195361934716365332097170774482279885885653692086452966360" +
"7725026895550592836275112117409697299806841055435958486658329164213621823107899099" +
"9448652468262416972035911852507045361090559");
}

View File

@@ -41,6 +41,7 @@ import net.schmizz.sshj.transport.Transport;
import net.schmizz.sshj.transport.TransportException;
import net.schmizz.sshj.transport.digest.Digest;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
/** Key exchange algorithm. */
@@ -55,14 +56,18 @@ public interface KeyExchange {
* @param I_S the server key init packet
* @param I_C the client key init packet
*
* @throws TransportException if there is an error sending a packet
* @throws GeneralSecurityException
* @throws TransportException if there is an error sending a packet
*/
void init(Transport trans, byte[] V_S, byte[] V_C, byte[] I_S, byte[] I_C)
throws TransportException;
throws GeneralSecurityException, TransportException;
/** @return the computed H parameter */
byte[] getH();
/** @return the computed K parameter */
byte[] getK();
/**
* The message digest used by this key exchange algorithm.
*
@@ -73,9 +78,6 @@ public interface KeyExchange {
/** @return the host key determined from server's response packets */
PublicKey getHostKey();
/** @return the computed K parameter */
byte[] getK();
/**
* Process the next packet
*
@@ -84,9 +86,10 @@ public interface KeyExchange {
*
* @return a boolean indicating if the processing is complete or if more packets are to be received
*
* @throws TransportException if there is an error sending a packet
* @throws GeneralSecurityException
* @throws TransportException if there is an error sending a packet
*/
boolean next(Message msg, SSHPacket buffer)
throws TransportException;
throws GeneralSecurityException, TransportException;
}