Correctly determine KeyType for ECDSA public key (Fixes #356)

This commit is contained in:
Jeroen van Erp
2017-09-05 15:23:47 +02:00
parent 0918bc626f
commit c6c9a3f6a8
4 changed files with 67 additions and 13 deletions

View File

@@ -17,8 +17,10 @@ package net.schmizz.sshj.common;
import java.math.BigInteger; import java.math.BigInteger;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.interfaces.ECKey;
import java.security.interfaces.ECPublicKey; import java.security.interfaces.ECPublicKey;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@@ -34,7 +36,7 @@ import org.slf4j.LoggerFactory;
import com.hierynomus.sshj.secg.SecgUtils; import com.hierynomus.sshj.secg.SecgUtils;
public class ECDSAVariationsAdapter { class ECDSAVariationsAdapter {
private final static String BASE_ALGORITHM_NAME = "ecdsa-sha2-nistp"; private final static String BASE_ALGORITHM_NAME = "ecdsa-sha2-nistp";
@@ -53,7 +55,7 @@ public class ECDSAVariationsAdapter {
SUPPORTED_CURVES.put("521", "nistp521"); SUPPORTED_CURVES.put("521", "nistp521");
} }
public static PublicKey readPubKeyFromBuffer(Buffer<?> buf, String variation) throws GeneralSecurityException { static PublicKey readPubKeyFromBuffer(Buffer<?> buf, String variation) throws GeneralSecurityException {
String algorithm = BASE_ALGORITHM_NAME + variation; String algorithm = BASE_ALGORITHM_NAME + variation;
if (!SecurityUtils.isBouncyCastleRegistered()) { if (!SecurityUtils.isBouncyCastleRegistered()) {
throw new GeneralSecurityException("BouncyCastle is required to read a key of type " + algorithm); throw new GeneralSecurityException("BouncyCastle is required to read a key of type " + algorithm);
@@ -92,7 +94,7 @@ public class ECDSAVariationsAdapter {
} }
} }
public static void writePubKeyContentsIntoBuffer(PublicKey pk, Buffer<?> buf) { static void writePubKeyContentsIntoBuffer(PublicKey pk, Buffer<?> buf) {
final ECPublicKey ecdsa = (ECPublicKey) pk; final ECPublicKey ecdsa = (ECPublicKey) pk;
byte[] encoded = SecgUtils.getEncoded(ecdsa.getW(), ecdsa.getParams().getCurve()); byte[] encoded = SecgUtils.getEncoded(ecdsa.getW(), ecdsa.getParams().getCurve());
@@ -100,8 +102,12 @@ public class ECDSAVariationsAdapter {
.putBytes(encoded); .putBytes(encoded);
} }
public static int fieldSizeFromKey(ECPublicKey ecPublicKey) { static boolean isECKeyWithFieldSize(Key key, int fieldSize) {
return ecPublicKey.getParams().getCurve().getField().getFieldSize(); return "ECDSA".equals(key.getAlgorithm())
&& fieldSizeFromKey((ECKey) key) == fieldSize;
} }
private static int fieldSizeFromKey(ECKey ecPublicKey) {
return ecPublicKey.getParams().getCurve().getField().getFieldSize();
}
} }

View File

@@ -20,11 +20,7 @@ import java.security.GeneralSecurityException;
import java.security.Key; import java.security.Key;
import java.security.KeyFactory; import java.security.KeyFactory;
import java.security.PublicKey; import java.security.PublicKey;
import java.security.interfaces.DSAPrivateKey; import java.security.interfaces.*;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.DSAPublicKeySpec; import java.security.spec.DSAPublicKeySpec;
import java.security.spec.RSAPublicKeySpec; import java.security.spec.RSAPublicKeySpec;
import java.util.ArrayList; import java.util.ArrayList;
@@ -130,7 +126,7 @@ public enum KeyType {
@Override @Override
protected boolean isMyType(Key key) { protected boolean isMyType(Key key) {
return ("ECDSA".equals(key.getAlgorithm()) && ECDSAVariationsAdapter.fieldSizeFromKey((ECPublicKey) key) == 256); return ECDSAVariationsAdapter.isECKeyWithFieldSize(key, 256);
} }
}, },
@@ -151,7 +147,7 @@ public enum KeyType {
@Override @Override
protected boolean isMyType(Key key) { protected boolean isMyType(Key key) {
return ("ECDSA".equals(key.getAlgorithm()) && ECDSAVariationsAdapter.fieldSizeFromKey((ECPublicKey) key) == 384); return ECDSAVariationsAdapter.isECKeyWithFieldSize(key, 384);
} }
}, },
@@ -172,7 +168,7 @@ public enum KeyType {
@Override @Override
protected boolean isMyType(Key key) { protected boolean isMyType(Key key) {
return ("ECDSA".equals(key.getAlgorithm()) && ECDSAVariationsAdapter.fieldSizeFromKey((ECPublicKey) key) == 521); return ECDSAVariationsAdapter.isECKeyWithFieldSize(key, 521);
} }
}, },

View File

@@ -0,0 +1,30 @@
package com.hierynomus.sshj.common
import net.schmizz.sshj.common.KeyType
import net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile
import spock.lang.Specification
import spock.lang.Unroll
class KeyTypeSpec extends Specification {
@Unroll
def "should determine correct keytype for #type key"() {
given:
OpenSSHKeyFile kf = new OpenSSHKeyFile()
kf.init(privKey, pubKey)
expect:
KeyType.fromKey(kf.getPublic()) == type
KeyType.fromKey(kf.getPrivate()) == type
where:
privKey << ["""-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIGhcvG8anyHew/xZJfozh5XIc1kmZZs6o2f0l3KFs4jgoAoGCCqGSM49
AwEHoUQDQgAEDUA1JYVD7URSoOGdwPxjea+ETD6IABMD9CWfk3NVTNkdu/Ksn7uX
cLTQhx4N16z1IgW2bRbSbsmM++UKXmeWyg==
-----END EC PRIVATE KEY-----"""]
pubKey << ["""ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBA1ANSWFQ+1EUqDhncD8Y3mvhEw+iAATA/Qln5NzVUzZHbvyrJ+7l3C00IceDdes9SIFtm0W0m7JjPvlCl5nlso= SSH Key"""]
type << [KeyType.ECDSA256]
}
}

View File

@@ -0,0 +1,22 @@
package net.schmizz.sshj.userauth.password
import spock.lang.Specification
class ConsolePasswordFinderSpec extends Specification {
def "should read password from console"() {
given:
def console = Mock(Console) {
readPassword(*_) >> "password".toCharArray()
}
def cpf = new ConsolePasswordFinder(console)
def resource = new AccountResource("test", "localhost")
when:
def password = cpf.reqPassword(resource)
then:
password == "password".toCharArray()
}
}