Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make KeyType compatible with Android Keystore #586

Merged
merged 5 commits into from
May 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/main/java/com/hierynomus/sshj/common/KeyAlgorithm.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (C)2009 - SSHJ Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hierynomus.sshj.common;

public class KeyAlgorithm {

public static final String RSA = "RSA";
public static final String DSA = "DSA";

/** Elliptic curve signature key algorithm for use with BouncyCastle **/
public static final String ECDSA = "ECDSA";

/** General elliptic curve algorithm identifier for use with BouncyCastle **/
public static final String EC_BC = "EC";

/** General elliptic curve algorithm identifier for use with the Android Keystore **/
public static final String EC_KEYSTORE = "EC";
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.hierynomus.sshj.userauth.keyprovider;

import com.hierynomus.sshj.common.KeyAlgorithm;
import com.hierynomus.sshj.common.KeyDecryptionFailedException;
import com.hierynomus.sshj.transport.cipher.BlockCiphers;
import net.i2p.crypto.eddsa.EdDSAPrivateKey;
Expand Down Expand Up @@ -216,7 +217,7 @@ private KeyPair readUnencrypted(final PlainBuffer keyBuffer, final PublicKey pub
keyBuffer.readMPInt(); // iqmp (q^-1 mod p)
keyBuffer.readMPInt(); // p (Prime 1)
keyBuffer.readMPInt(); // q (Prime 2)
kp = new KeyPair(publicKey, SecurityUtils.getKeyFactory("RSA").generatePrivate(new RSAPrivateKeySpec(n, d)));
kp = new KeyPair(publicKey, SecurityUtils.getKeyFactory(KeyAlgorithm.RSA).generatePrivate(new RSAPrivateKeySpec(n, d)));
break;
case ECDSA256:
kp = new KeyPair(publicKey, createECDSAPrivateKey(kt, keyBuffer, "P-256"));
Expand Down Expand Up @@ -248,7 +249,7 @@ private PrivateKey createECDSAPrivateKey(KeyType kt, PlainBuffer buffer, String
X9ECParameters ecParams = NISTNamedCurves.getByName(name);
ECNamedCurveSpec ecCurveSpec = new ECNamedCurveSpec(name, ecParams.getCurve(), ecParams.getG(), ecParams.getN());
ECPrivateKeySpec pks = new ECPrivateKeySpec(s, ecCurveSpec);
return SecurityUtils.getKeyFactory("ECDSA").generatePrivate(pks);
return SecurityUtils.getKeyFactory(KeyAlgorithm.ECDSA).generatePrivate(pks);

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package net.schmizz.sshj.common;

import com.hierynomus.sshj.common.KeyAlgorithm;
import com.hierynomus.sshj.secg.SecgUtils;
import org.bouncycastle.asn1.nist.NISTNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
Expand Down Expand Up @@ -87,7 +88,7 @@ static PublicKey readPubKeyFromBuffer(Buffer<?> buf, String variation) throws Ge
ECPoint p = new ECPoint(bigX, bigY);
ECPublicKeySpec publicKeySpec = new ECPublicKeySpec(p, ecCurveSpec);

KeyFactory keyFactory = KeyFactory.getInstance("ECDSA");
KeyFactory keyFactory = KeyFactory.getInstance(KeyAlgorithm.ECDSA);
return keyFactory.generatePublic(publicKeySpec);
} catch (Exception ex) {
throw new GeneralSecurityException(ex);
Expand All @@ -103,7 +104,7 @@ static void writePubKeyContentsIntoBuffer(PublicKey pk, Buffer<?> buf) {
}

static boolean isECKeyWithFieldSize(Key key, int fieldSize) {
return "ECDSA".equals(key.getAlgorithm())
return (KeyAlgorithm.ECDSA.equals(key.getAlgorithm()) || KeyAlgorithm.EC_KEYSTORE.equals(key.getAlgorithm()))
&& fieldSizeFromKey((ECKey) key) == fieldSize;
}

Expand Down
11 changes: 5 additions & 6 deletions src/main/java/net/schmizz/sshj/common/KeyType.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package net.schmizz.sshj.common;

import com.hierynomus.sshj.common.KeyAlgorithm;
import com.hierynomus.sshj.signature.Ed25519PublicKey;
import com.hierynomus.sshj.userauth.certificate.Certificate;
import net.i2p.crypto.eddsa.EdDSAPublicKey;
Expand All @@ -30,9 +31,7 @@
import java.security.Key;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.RSAPublicKeySpec;
Expand All @@ -53,7 +52,7 @@ public PublicKey readPubKeyFromBuffer(Buffer<?> buf)
} catch (Buffer.BufferException be) {
throw new GeneralSecurityException(be);
}
final KeyFactory keyFactory = SecurityUtils.getKeyFactory("RSA");
final KeyFactory keyFactory = SecurityUtils.getKeyFactory(KeyAlgorithm.RSA);
return keyFactory.generatePublic(new RSAPublicKeySpec(n, e));
}

Expand All @@ -66,7 +65,7 @@ protected void writePubKeyContentsIntoBuffer(PublicKey pk, Buffer<?> buf) {

@Override
protected boolean isMyType(Key key) {
return (key instanceof RSAPublicKey || key instanceof RSAPrivateKey);
return KeyAlgorithm.RSA.equals(key.getAlgorithm());
}
},

Expand All @@ -84,7 +83,7 @@ public PublicKey readPubKeyFromBuffer(Buffer<?> buf)
} catch (Buffer.BufferException be) {
throw new GeneralSecurityException(be);
}
final KeyFactory keyFactory = SecurityUtils.getKeyFactory("DSA");
final KeyFactory keyFactory = SecurityUtils.getKeyFactory(KeyAlgorithm.DSA);
return keyFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g));
}

Expand All @@ -99,7 +98,7 @@ protected void writePubKeyContentsIntoBuffer(PublicKey pk, Buffer<?> buf) {

@Override
protected boolean isMyType(Key key) {
return (key instanceof DSAPublicKey || key instanceof DSAPrivateKey);
return KeyAlgorithm.DSA.equals(key.getAlgorithm());
}

},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package net.schmizz.sshj.transport.kex;

import com.hierynomus.sshj.common.KeyAlgorithm;
import net.schmizz.sshj.common.Factory;
import net.schmizz.sshj.transport.random.Random;
import org.bouncycastle.asn1.x9.X9ECParameters;
Expand All @@ -31,7 +32,7 @@ public class Curve25519DH extends DHBase {
private byte[] secretKey;

public Curve25519DH() {
super("ECDSA", "ECDH");
super(KeyAlgorithm.ECDSA, "ECDH");
}

@Override
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/net/schmizz/sshj/transport/kex/ECDH.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package net.schmizz.sshj.transport.kex;

import com.hierynomus.sshj.common.KeyAlgorithm;
import net.schmizz.sshj.common.Factory;
import net.schmizz.sshj.common.SecurityUtils;
import net.schmizz.sshj.transport.random.Random;
Expand Down Expand Up @@ -54,7 +55,7 @@ public void init(AlgorithmParameterSpec params, Factory<Random> randomFactory) t

@Override
public void computeK(byte[] f) throws GeneralSecurityException {
KeyFactory keyFactory = SecurityUtils.getKeyFactory("EC");
KeyFactory keyFactory = SecurityUtils.getKeyFactory(KeyAlgorithm.EC_BC);
ECPublicKeySpec keySpec = new ECPublicKeySpec(getDecoded(f, ecParameterSpec.getCurve()), ecParameterSpec);
PublicKey yourPubKey = keyFactory.generatePublic(keySpec);
agreement.doPhase(yourPubKey, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package net.schmizz.sshj.transport.verification;

import com.hierynomus.sshj.common.KeyAlgorithm;
import com.hierynomus.sshj.transport.verification.KnownHostMatchers;
import net.schmizz.sshj.common.*;
import org.slf4j.Logger;
Expand Down Expand Up @@ -239,7 +240,7 @@ public KnownHostEntry parseEntry(String line)
final BigInteger e = new BigInteger(split[i++]);
final BigInteger n = new BigInteger(split[i++]);
try {
final KeyFactory keyFactory = SecurityUtils.getKeyFactory("RSA");
final KeyFactory keyFactory = SecurityUtils.getKeyFactory(KeyAlgorithm.RSA);
key = keyFactory.generatePublic(new RSAPublicKeySpec(n, e));
} catch (Exception ex) {
log.error("Error reading entry `{}`, could not create key", line, ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package net.schmizz.sshj.userauth.keyprovider;

import com.hierynomus.sshj.common.KeyAlgorithm;
import com.hierynomus.sshj.transport.cipher.BlockCiphers;
import net.schmizz.sshj.common.Base64;
import net.schmizz.sshj.common.ByteArrayUtils;
Expand Down Expand Up @@ -140,7 +141,7 @@ protected KeyPair readKeyPair()
ASN1Data asn = new ASN1Data(data = decrypt(Base64.decode(sb.toString()), cipher, iv));
switch (type) {
case RSA: {
KeyFactory factory = KeyFactory.getInstance("RSA");
KeyFactory factory = KeyFactory.getInstance(KeyAlgorithm.RSA);
asn.readNext();
BigInteger modulus = asn.readNext();
BigInteger pubExp = asn.readNext();
Expand All @@ -150,7 +151,7 @@ protected KeyPair readKeyPair()
return new KeyPair(pubKey, prvKey);
}
case DSA: {
KeyFactory factory = KeyFactory.getInstance("DSA");
KeyFactory factory = KeyFactory.getInstance(KeyAlgorithm.DSA);
asn.readNext();
BigInteger p = asn.readNext();
BigInteger q = asn.readNext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package net.schmizz.sshj.userauth.keyprovider;

import com.hierynomus.sshj.common.KeyAlgorithm;
import net.schmizz.sshj.common.Base64;
import net.schmizz.sshj.common.KeyType;
import net.schmizz.sshj.userauth.password.PasswordUtils;
Expand Down Expand Up @@ -114,7 +115,7 @@ protected KeyPair readKeyPair() throws IOException {

final KeyFactory factory;
try {
factory = KeyFactory.getInstance("RSA");
factory = KeyFactory.getInstance(KeyAlgorithm.RSA);
} catch (NoSuchAlgorithmException s) {
throw new IOException(s.getMessage(), s);
}
Expand All @@ -141,7 +142,7 @@ protected KeyPair readKeyPair() throws IOException {

final KeyFactory factory;
try {
factory = KeyFactory.getInstance("DSA");
factory = KeyFactory.getInstance(KeyAlgorithm.DSA);
} catch (NoSuchAlgorithmException s) {
throw new IOException(s.getMessage(), s);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
*/
package net.schmizz.sshj.signature

import com.hierynomus.sshj.common.KeyAlgorithm
import spock.lang.Unroll;

import java.math.BigInteger;
Expand All @@ -47,7 +48,7 @@ import spock.lang.Specification

class SignatureDSASpec extends Specification {

def keyFactory = KeyFactory.getInstance("DSA")
def keyFactory = KeyFactory.getInstance(KeyAlgorithm.DSA)

private PublicKey createPublicKey(final byte[] y, final byte[] p, final byte[] q, final byte[] g) throws Exception {
final BigInteger publicKey = new BigInteger(y);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.security.spec.DSAPublicKeySpec;
import java.util.Arrays;

import com.hierynomus.sshj.common.KeyAlgorithm;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
Expand All @@ -35,7 +36,7 @@ public class SignatureDSATest {

@Before
public void setUp() throws NoSuchAlgorithmException {
keyFactory = KeyFactory.getInstance("DSA");
keyFactory = KeyFactory.getInstance(KeyAlgorithm.DSA);
}

@Test
Expand Down
9 changes: 5 additions & 4 deletions src/test/java/net/schmizz/sshj/util/KeyUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
*/
package net.schmizz.sshj.util;

import com.hierynomus.sshj.common.KeyAlgorithm;
import net.schmizz.sshj.common.SecurityUtils;

import java.math.BigInteger;
Expand All @@ -46,7 +47,7 @@ public class KeyUtil {
/** Creates a DSA private key. */
public static PrivateKey newDSAPrivateKey(String x, String p, String q, String g)
throws GeneralSecurityException {
return SecurityUtils.getKeyFactory("DSA").generatePrivate(new DSAPrivateKeySpec(new BigInteger(x, 16),
return SecurityUtils.getKeyFactory(KeyAlgorithm.DSA).generatePrivate(new DSAPrivateKeySpec(new BigInteger(x, 16),
new BigInteger(p, 16),
new BigInteger(q, 16),
new BigInteger(g, 16))
Expand All @@ -56,7 +57,7 @@ public static PrivateKey newDSAPrivateKey(String x, String p, String q, String g
/** Creates a DSA public key. */
public static PublicKey newDSAPublicKey(String y, String p, String q, String g)
throws GeneralSecurityException {
return SecurityUtils.getKeyFactory("DSA").generatePublic(new DSAPublicKeySpec(new BigInteger(y, 16),
return SecurityUtils.getKeyFactory(KeyAlgorithm.DSA).generatePublic(new DSAPublicKeySpec(new BigInteger(y, 16),
new BigInteger(p, 16),
new BigInteger(q, 16),
new BigInteger(g, 16))
Expand All @@ -66,15 +67,15 @@ public static PublicKey newDSAPublicKey(String y, String p, String q, String g)
/** Creates an RSA private key. */
public static PrivateKey newRSAPrivateKey(String modulus, String exponent)
throws GeneralSecurityException {
return SecurityUtils.getKeyFactory("RSA").generatePrivate(new RSAPrivateKeySpec(new BigInteger(modulus, 16),
return SecurityUtils.getKeyFactory(KeyAlgorithm.RSA).generatePrivate(new RSAPrivateKeySpec(new BigInteger(modulus, 16),
new BigInteger(exponent, 16))
);
}

/** Creates an RSA public key. */
public static PublicKey newRSAPublicKey(String modulus, String exponent)
throws GeneralSecurityException {
return SecurityUtils.getKeyFactory("RSA").generatePublic(new RSAPublicKeySpec(new BigInteger(modulus, 16),
return SecurityUtils.getKeyFactory(KeyAlgorithm.RSA).generatePublic(new RSAPublicKeySpec(new BigInteger(modulus, 16),
new BigInteger(exponent, 16)));
}

Expand Down