mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-08 16:18:05 +03:00
Comprehensive support for publickey auth with certificates (#702)
* Add key types for ECDSA and ED25519 with certificates to implement publickey auth with that keys. * Read public key certificates in OpenSSHKeyV1KeyFile. * Fix ClassCastException in ECDSAVariationsAdapter.isECKeyWithFieldSize. * Introduce an integration test for publickey auth with certificates. * Refactor: merge copy-paste from OpenSshKey*File.java into an util class. * Add the license to KeyWithCertificateSpec.groovy * Add the license to OpenSSHKeyFileUtil.java
This commit is contained in:
@@ -137,9 +137,13 @@ public class DefaultConfig
|
||||
|
||||
protected void initKeyAlgorithms() {
|
||||
setKeyAlgorithms(Arrays.<Factory.Named<KeyAlgorithm>>asList(
|
||||
KeyAlgorithms.EdDSA25519CertV01(),
|
||||
KeyAlgorithms.EdDSA25519(),
|
||||
KeyAlgorithms.ECDSASHANistp521CertV01(),
|
||||
KeyAlgorithms.ECDSASHANistp521(),
|
||||
KeyAlgorithms.ECDSASHANistp384CertV01(),
|
||||
KeyAlgorithms.ECDSASHANistp384(),
|
||||
KeyAlgorithms.ECDSASHANistp256CertV01(),
|
||||
KeyAlgorithms.ECDSASHANistp256(),
|
||||
KeyAlgorithms.RSASHA512(),
|
||||
KeyAlgorithms.RSASHA256(),
|
||||
|
||||
@@ -105,6 +105,7 @@ class ECDSAVariationsAdapter {
|
||||
|
||||
static boolean isECKeyWithFieldSize(Key key, int fieldSize) {
|
||||
return (KeyAlgorithm.ECDSA.equals(key.getAlgorithm()) || KeyAlgorithm.EC_KEYSTORE.equals(key.getAlgorithm()))
|
||||
&& key instanceof ECKey
|
||||
&& fieldSizeFromKey((ECKey) key) == fieldSize;
|
||||
}
|
||||
|
||||
|
||||
@@ -251,6 +251,98 @@ public enum KeyType {
|
||||
}
|
||||
},
|
||||
|
||||
ED25519_CERT("ssh-ed25519-cert-v01@openssh.com") {
|
||||
@Override
|
||||
public PublicKey readPubKeyFromBuffer(Buffer<?> buf)
|
||||
throws GeneralSecurityException {
|
||||
return CertUtils.readPubKey(buf, ED25519);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writePubKeyContentsIntoBuffer(PublicKey pk, Buffer<?> buf) {
|
||||
CertUtils.writePubKeyContentsIntoBuffer(pk, ED25519, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isMyType(Key key) {
|
||||
return CertUtils.isCertificateOfType(key, ED25519);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyType getParent() {
|
||||
return KeyType.ED25519;
|
||||
}
|
||||
},
|
||||
|
||||
ECDSA256_CERT("ecdsa-sha2-nistp256-cert-v01@openssh.com") {
|
||||
@Override
|
||||
public PublicKey readPubKeyFromBuffer(Buffer<?> buf)
|
||||
throws GeneralSecurityException {
|
||||
return CertUtils.readPubKey(buf, ECDSA256);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writePubKeyContentsIntoBuffer(PublicKey pk, Buffer<?> buf) {
|
||||
CertUtils.writePubKeyContentsIntoBuffer(pk, ECDSA256, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isMyType(Key key) {
|
||||
return CertUtils.isCertificateOfType(key, ECDSA256);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyType getParent() {
|
||||
return KeyType.ECDSA256;
|
||||
}
|
||||
},
|
||||
|
||||
ECDSA384_CERT("ecdsa-sha2-nistp384-cert-v01@openssh.com") {
|
||||
@Override
|
||||
public PublicKey readPubKeyFromBuffer(Buffer<?> buf)
|
||||
throws GeneralSecurityException {
|
||||
return CertUtils.readPubKey(buf, ECDSA384);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writePubKeyContentsIntoBuffer(PublicKey pk, Buffer<?> buf) {
|
||||
CertUtils.writePubKeyContentsIntoBuffer(pk, ECDSA384, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isMyType(Key key) {
|
||||
return CertUtils.isCertificateOfType(key, ECDSA384);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyType getParent() {
|
||||
return KeyType.ECDSA384;
|
||||
}
|
||||
},
|
||||
|
||||
ECDSA521_CERT("ecdsa-sha2-nistp521-cert-v01@openssh.com") {
|
||||
@Override
|
||||
public PublicKey readPubKeyFromBuffer(Buffer<?> buf)
|
||||
throws GeneralSecurityException {
|
||||
return CertUtils.readPubKey(buf, ECDSA521);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writePubKeyContentsIntoBuffer(PublicKey pk, Buffer<?> buf) {
|
||||
CertUtils.writePubKeyContentsIntoBuffer(pk, ECDSA521, buf);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isMyType(Key key) {
|
||||
return CertUtils.isCertificateOfType(key, ECDSA521);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyType getParent() {
|
||||
return KeyType.ECDSA521;
|
||||
}
|
||||
},
|
||||
|
||||
/** Unrecognized */
|
||||
UNKNOWN("unknown") {
|
||||
@Override
|
||||
|
||||
@@ -15,9 +15,7 @@
|
||||
*/
|
||||
package net.schmizz.sshj.userauth.keyprovider;
|
||||
|
||||
import net.schmizz.sshj.common.Base64;
|
||||
import net.schmizz.sshj.common.Buffer;
|
||||
import net.schmizz.sshj.common.KeyType;
|
||||
import com.hierynomus.sshj.userauth.keyprovider.OpenSSHKeyFileUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.PublicKey;
|
||||
@@ -58,11 +56,8 @@ public class OpenSSHKeyFile
|
||||
@Override
|
||||
public void init(File location) {
|
||||
// try cert key location first
|
||||
File pubKey = new File(location + "-cert.pub");
|
||||
if (!pubKey.exists()) {
|
||||
pubKey = new File(location + ".pub");
|
||||
}
|
||||
if (pubKey.exists())
|
||||
File pubKey = OpenSSHKeyFileUtil.getPublicKeyFile(location);
|
||||
if (pubKey != null)
|
||||
try {
|
||||
initPubKey(new FileReader(pubKey));
|
||||
} catch (IOException e) {
|
||||
@@ -91,25 +86,8 @@ public class OpenSSHKeyFile
|
||||
* @param publicKey Public key accessible through a {@code Reader}
|
||||
*/
|
||||
private void initPubKey(Reader publicKey) throws IOException {
|
||||
final BufferedReader br = new BufferedReader(publicKey);
|
||||
try {
|
||||
String keydata;
|
||||
while ((keydata = br.readLine()) != null) {
|
||||
keydata = keydata.trim();
|
||||
if (!keydata.isEmpty()) {
|
||||
String[] parts = keydata.trim().split("\\s+");
|
||||
if (parts.length >= 2) {
|
||||
type = KeyType.fromString(parts[0]);
|
||||
pubKey = new Buffer.PlainBuffer(Base64.decode(parts[1])).readPublicKey();
|
||||
} else {
|
||||
throw new IOException("Got line with only one column");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw new IOException("Public key file is blank");
|
||||
} finally {
|
||||
br.close();
|
||||
}
|
||||
OpenSSHKeyFileUtil.ParsedPubKey parsed = OpenSSHKeyFileUtil.initPubKey(publicKey);
|
||||
type = parsed.getType();
|
||||
pubKey = parsed.getPubKey();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user