mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 23:30:55 +03:00
Compare commits
2 Commits
e390394e3b
...
issue-588
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fedf8c410c | ||
|
|
8b0d1ca03c |
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.hierynomus.sshj
|
package com.hierynomus.sshj
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.key.ECDSAKeyAlgorithm
|
||||||
|
import com.hierynomus.sshj.key.EdDSAKeyAlgorithm
|
||||||
import com.hierynomus.sshj.signature.SignatureEdDSA
|
import com.hierynomus.sshj.signature.SignatureEdDSA
|
||||||
import net.schmizz.sshj.DefaultConfig
|
import net.schmizz.sshj.DefaultConfig
|
||||||
import net.schmizz.sshj.SSHClient
|
import net.schmizz.sshj.SSHClient
|
||||||
@@ -29,7 +31,7 @@ class IntegrationSpec extends IntegrationBaseSpec {
|
|||||||
def "should accept correct key for #signatureName"() {
|
def "should accept correct key for #signatureName"() {
|
||||||
given:
|
given:
|
||||||
def config = new DefaultConfig()
|
def config = new DefaultConfig()
|
||||||
config.setSignatureFactories(signatureFactory)
|
config.setKeyAlgorithms(Collections.singletonList(signatureFactory))
|
||||||
SSHClient sshClient = new SSHClient(config)
|
SSHClient sshClient = new SSHClient(config)
|
||||||
sshClient.addHostKeyVerifier(fingerprint) // test-containers/ssh_host_ecdsa_key's fingerprint
|
sshClient.addHostKeyVerifier(fingerprint) // test-containers/ssh_host_ecdsa_key's fingerprint
|
||||||
|
|
||||||
@@ -40,7 +42,7 @@ class IntegrationSpec extends IntegrationBaseSpec {
|
|||||||
sshClient.isConnected()
|
sshClient.isConnected()
|
||||||
|
|
||||||
where:
|
where:
|
||||||
signatureFactory << [new SignatureECDSA.Factory256(), new SignatureEdDSA.Factory()]
|
signatureFactory << [new ECDSAKeyAlgorithm.Factory256(), new EdDSAKeyAlgorithm.Factory()]
|
||||||
fingerprint << ["d3:6a:a9:52:05:ab:b5:48:dd:73:60:18:0c:3a:f0:a3", "dc:68:38:ce:fc:6f:2c:d6:6d:6b:34:eb:5c:f0:41:6a"]
|
fingerprint << ["d3:6a:a9:52:05:ab:b5:48:dd:73:60:18:0c:3a:f0:a3", "dc:68:38:ce:fc:6f:2c:d6:6d:6b:34:eb:5c:f0:41:6a"]
|
||||||
signatureName = signatureFactory.getName()
|
signatureName = signatureFactory.getName()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* 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.signature
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.IntegrationBaseSpec
|
||||||
|
import com.hierynomus.sshj.key.RSAKeyAlgorithm
|
||||||
|
import net.schmizz.sshj.DefaultConfig
|
||||||
|
import net.schmizz.sshj.signature.SignatureRSA
|
||||||
|
import spock.lang.Unroll
|
||||||
|
|
||||||
|
class SignatureSpec extends IntegrationBaseSpec {
|
||||||
|
|
||||||
|
@Unroll
|
||||||
|
def "should correctly connect with #sig Signature"() {
|
||||||
|
given:
|
||||||
|
def cfg = new DefaultConfig()
|
||||||
|
cfg.setKeyAlgorithms(Collections.singletonList(sigFactory))
|
||||||
|
def client = getConnectedClient(cfg)
|
||||||
|
|
||||||
|
when:
|
||||||
|
client.authPublickey(USERNAME, KEYFILE)
|
||||||
|
|
||||||
|
then:
|
||||||
|
client.authenticated
|
||||||
|
|
||||||
|
where:
|
||||||
|
sigFactory << [new RSAKeyAlgorithm.FactorySSHRSA(), new RSAKeyAlgorithm.FactoryRSASHA256(), new RSAKeyAlgorithm.FactoryRSASHA512()]
|
||||||
|
sig = sigFactory.name
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,9 +17,6 @@ package com.hierynomus.sshj.transport.mac
|
|||||||
|
|
||||||
import com.hierynomus.sshj.IntegrationBaseSpec
|
import com.hierynomus.sshj.IntegrationBaseSpec
|
||||||
import net.schmizz.sshj.DefaultConfig
|
import net.schmizz.sshj.DefaultConfig
|
||||||
import net.schmizz.sshj.transport.mac.HMACRIPEMD160
|
|
||||||
import net.schmizz.sshj.transport.mac.HMACSHA2256
|
|
||||||
import spock.lang.AutoCleanup
|
|
||||||
import spock.lang.Unroll
|
import spock.lang.Unroll
|
||||||
|
|
||||||
class MacSpec extends IntegrationBaseSpec {
|
class MacSpec extends IntegrationBaseSpec {
|
||||||
|
|||||||
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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.key;
|
||||||
|
|
||||||
|
import net.schmizz.sshj.common.Buffer;
|
||||||
|
import net.schmizz.sshj.common.Factory;
|
||||||
|
import net.schmizz.sshj.common.KeyType;
|
||||||
|
import net.schmizz.sshj.signature.Signature;
|
||||||
|
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
|
||||||
|
public abstract class AbstractKeyAlgorithm implements KeyAlgorithm {
|
||||||
|
private final String keyAlgorithm;
|
||||||
|
private final Factory.Named<Signature> signature;
|
||||||
|
private final KeyType keyFormat;
|
||||||
|
|
||||||
|
public AbstractKeyAlgorithm(String keyAlgorithm, Factory.Named<Signature> signature, KeyType keyFormat) {
|
||||||
|
this.keyAlgorithm = keyAlgorithm;
|
||||||
|
this.signature = signature;
|
||||||
|
this.keyFormat = keyFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void putPubKeyIntoBuffer(PublicKey pk, Buffer<?> buf) {
|
||||||
|
keyFormat.putPubKeyIntoBuffer(pk, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PublicKey readPubKeyFromBuffer(Buffer<?> buf) throws GeneralSecurityException {
|
||||||
|
return keyFormat.readPubKeyFromBuffer(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getKeyAlgorithm() {
|
||||||
|
return keyAlgorithm;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyType getKeyFormat() {
|
||||||
|
return keyFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Signature newSignature() {
|
||||||
|
return this.signature.create();
|
||||||
|
}
|
||||||
|
}
|
||||||
65
src/main/java/com/hierynomus/sshj/key/DSAKeyAlgorithm.java
Normal file
65
src/main/java/com/hierynomus/sshj/key/DSAKeyAlgorithm.java
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* 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.key;
|
||||||
|
|
||||||
|
import net.schmizz.sshj.common.Factory;
|
||||||
|
import net.schmizz.sshj.common.KeyType;
|
||||||
|
import net.schmizz.sshj.signature.Signature;
|
||||||
|
import net.schmizz.sshj.signature.SignatureDSA;
|
||||||
|
|
||||||
|
public class DSAKeyAlgorithm extends AbstractKeyAlgorithm {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named factory for the SSH-DSA key algorithm.
|
||||||
|
*/
|
||||||
|
public static class FactorySSHDSA
|
||||||
|
implements net.schmizz.sshj.common.Factory.Named<KeyAlgorithm> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyAlgorithm create() {
|
||||||
|
return new DSAKeyAlgorithm(KeyType.DSA.toString(), new SignatureDSA.Factory(), KeyType.DSA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return KeyType.DSA.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named factory for the SSH-DSS-CERT key algorithm
|
||||||
|
*/
|
||||||
|
public static class FactorySSHDSSCert
|
||||||
|
implements net.schmizz.sshj.common.Factory.Named<KeyAlgorithm> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyAlgorithm create() {
|
||||||
|
return new DSAKeyAlgorithm(KeyType.DSA_CERT.toString(), new SignatureDSA.Factory(), KeyType.DSA_CERT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return KeyType.DSA_CERT.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public DSAKeyAlgorithm(String keyAlgorithm, Factory.Named<Signature> signature, KeyType keyFormat) {
|
||||||
|
super(keyAlgorithm, signature, KeyType.DSA);
|
||||||
|
}
|
||||||
|
}
|
||||||
72
src/main/java/com/hierynomus/sshj/key/ECDSAKeyAlgorithm.java
Normal file
72
src/main/java/com/hierynomus/sshj/key/ECDSAKeyAlgorithm.java
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* 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.key;
|
||||||
|
|
||||||
|
import net.schmizz.sshj.common.Factory;
|
||||||
|
import net.schmizz.sshj.common.KeyType;
|
||||||
|
import net.schmizz.sshj.signature.Signature;
|
||||||
|
import net.schmizz.sshj.signature.SignatureECDSA;
|
||||||
|
|
||||||
|
public class ECDSAKeyAlgorithm extends AbstractKeyAlgorithm {
|
||||||
|
/** A named factory for ECDSA-256 signature */
|
||||||
|
public static class Factory256 implements net.schmizz.sshj.common.Factory.Named<KeyAlgorithm> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyAlgorithm create() {
|
||||||
|
return new ECDSAKeyAlgorithm(KeyType.ECDSA256.toString(), new SignatureECDSA.Factory256(), KeyType.ECDSA256);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return KeyType.ECDSA256.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A named factory for ECDSA-384 signature */
|
||||||
|
public static class Factory384 implements net.schmizz.sshj.common.Factory.Named<KeyAlgorithm> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyAlgorithm create() {
|
||||||
|
return new ECDSAKeyAlgorithm(KeyType.ECDSA384.toString(), new SignatureECDSA.Factory384(), KeyType.ECDSA384);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return KeyType.ECDSA384.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A named factory for ECDSA-521 signature */
|
||||||
|
public static class Factory521 implements net.schmizz.sshj.common.Factory.Named<KeyAlgorithm> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyAlgorithm create() {
|
||||||
|
return new ECDSAKeyAlgorithm(KeyType.ECDSA521.toString(), new SignatureECDSA.Factory384(), KeyType.ECDSA521);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return KeyType.ECDSA521.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ECDSAKeyAlgorithm(String keyAlgorithm, Factory.Named<Signature> signature, KeyType keyFormat) {
|
||||||
|
super(keyAlgorithm, signature, keyFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
39
src/main/java/com/hierynomus/sshj/key/EdDSAKeyAlgorithm.java
Normal file
39
src/main/java/com/hierynomus/sshj/key/EdDSAKeyAlgorithm.java
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.key;
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.signature.SignatureEdDSA;
|
||||||
|
import net.schmizz.sshj.common.KeyType;
|
||||||
|
import net.schmizz.sshj.signature.Signature;
|
||||||
|
|
||||||
|
public class EdDSAKeyAlgorithm extends AbstractKeyAlgorithm {
|
||||||
|
public static class Factory implements net.schmizz.sshj.common.Factory.Named<KeyAlgorithm> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return KeyType.ED25519.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyAlgorithm create() {
|
||||||
|
return new EdDSAKeyAlgorithm(KeyType.ED25519.toString(), new SignatureEdDSA.Factory(), KeyType.ED25519);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public EdDSAKeyAlgorithm(String keyAlgorithm, Factory.Named<Signature> signature, KeyType keyFormat) {
|
||||||
|
super(keyAlgorithm, signature, keyFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/main/java/com/hierynomus/sshj/key/KeyAlgorithm.java
Normal file
45
src/main/java/com/hierynomus/sshj/key/KeyAlgorithm.java
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* 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.key;
|
||||||
|
|
||||||
|
import net.schmizz.sshj.common.Buffer;
|
||||||
|
import net.schmizz.sshj.common.KeyType;
|
||||||
|
import net.schmizz.sshj.signature.Signature;
|
||||||
|
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.security.PublicKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In [RFC4252], the concept "public key algorithm" is used to establish
|
||||||
|
* a relationship between one algorithm name, and:
|
||||||
|
* <p>
|
||||||
|
* A. procedures used to generate and validate a private/public
|
||||||
|
* keypair;
|
||||||
|
* B. a format used to encode a public key; and
|
||||||
|
* C. procedures used to calculate, encode, and verify a signature.
|
||||||
|
*/
|
||||||
|
public interface KeyAlgorithm {
|
||||||
|
|
||||||
|
PublicKey readPubKeyFromBuffer(Buffer<?> buf) throws GeneralSecurityException;
|
||||||
|
|
||||||
|
void putPubKeyIntoBuffer(PublicKey pk, Buffer<?> buf);
|
||||||
|
|
||||||
|
String getKeyAlgorithm();
|
||||||
|
|
||||||
|
KeyType getKeyFormat();
|
||||||
|
|
||||||
|
Signature newSignature();
|
||||||
|
}
|
||||||
96
src/main/java/com/hierynomus/sshj/key/RSAKeyAlgorithm.java
Normal file
96
src/main/java/com/hierynomus/sshj/key/RSAKeyAlgorithm.java
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* 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.key;
|
||||||
|
|
||||||
|
import net.schmizz.sshj.common.Factory;
|
||||||
|
import net.schmizz.sshj.common.KeyType;
|
||||||
|
import net.schmizz.sshj.signature.Signature;
|
||||||
|
import net.schmizz.sshj.signature.SignatureRSA;
|
||||||
|
|
||||||
|
public class RSAKeyAlgorithm extends AbstractKeyAlgorithm {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named factory for the SSH-RSA (SHA1) public key algorithm
|
||||||
|
*/
|
||||||
|
public static class FactorySSHRSA
|
||||||
|
implements net.schmizz.sshj.common.Factory.Named<KeyAlgorithm> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyAlgorithm create() {
|
||||||
|
return new RSAKeyAlgorithm("ssh-rsa", new SignatureRSA.FactorySSHRSA(), KeyType.RSA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "ssh-rsa";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named factory for the ssh-rsa-cert-v01@openssh.com (SHA1) public key algorithm
|
||||||
|
*/
|
||||||
|
public static class FactorySSHRSACert
|
||||||
|
implements net.schmizz.sshj.common.Factory.Named<KeyAlgorithm> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyAlgorithm create() {
|
||||||
|
return new RSAKeyAlgorithm("ssh-rsa-cert-v01@openssh.com", new SignatureRSA.FactoryCERT(), KeyType.RSA_CERT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "ssh-rsa-cert-v01@openssh.com";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named factory for the RSA-SHA2-256 public key algorithm
|
||||||
|
*/
|
||||||
|
public static class FactoryRSASHA256
|
||||||
|
implements net.schmizz.sshj.common.Factory.Named<KeyAlgorithm> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyAlgorithm create() {
|
||||||
|
return new RSAKeyAlgorithm("rsa-sha2-256", new SignatureRSA.FactoryRSASHA256(), KeyType.RSA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "rsa-sha2-256";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A named factory for the RSA-SHA2-512 public key algorithm
|
||||||
|
*/
|
||||||
|
public static class FactoryRSASHA512
|
||||||
|
implements net.schmizz.sshj.common.Factory.Named<KeyAlgorithm> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyAlgorithm create() {
|
||||||
|
return new RSAKeyAlgorithm("rsa-sha2-512", new SignatureRSA.FactoryRSASHA512(), KeyType.RSA);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "rsa-sha2-512";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public RSAKeyAlgorithm(String keyAlgorithm, Factory.Named<Signature> signature, KeyType keyFormat) {
|
||||||
|
super(keyAlgorithm, signature, keyFormat);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,7 +40,7 @@ public class SignatureEdDSA extends AbstractSignature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SignatureEdDSA() {
|
SignatureEdDSA() {
|
||||||
super(getEngine());
|
super(getEngine(), KeyType.ED25519.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static EdDSAEngine getEngine() {
|
private static EdDSAEngine getEngine() {
|
||||||
|
|||||||
@@ -15,6 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj;
|
package net.schmizz.sshj;
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.key.DSAKeyAlgorithm;
|
||||||
|
import com.hierynomus.sshj.key.EdDSAKeyAlgorithm;
|
||||||
|
import com.hierynomus.sshj.key.RSAKeyAlgorithm;
|
||||||
import com.hierynomus.sshj.signature.SignatureEdDSA;
|
import com.hierynomus.sshj.signature.SignatureEdDSA;
|
||||||
|
|
||||||
import net.schmizz.sshj.common.SecurityUtils;
|
import net.schmizz.sshj.common.SecurityUtils;
|
||||||
@@ -23,6 +26,8 @@ import net.schmizz.sshj.signature.SignatureRSA;
|
|||||||
import net.schmizz.sshj.transport.random.JCERandom;
|
import net.schmizz.sshj.transport.random.JCERandom;
|
||||||
import net.schmizz.sshj.transport.random.SingletonRandomFactory;
|
import net.schmizz.sshj.transport.random.SingletonRandomFactory;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers SpongyCastle as JCE provider.
|
* Registers SpongyCastle as JCE provider.
|
||||||
*/
|
*/
|
||||||
@@ -33,11 +38,14 @@ public class AndroidConfig
|
|||||||
SecurityUtils.registerSecurityProvider("org.spongycastle.jce.provider.BouncyCastleProvider");
|
SecurityUtils.registerSecurityProvider("org.spongycastle.jce.provider.BouncyCastleProvider");
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't add ECDSA
|
|
||||||
protected void initSignatureFactories() {
|
@Override
|
||||||
setSignatureFactories(new SignatureRSA.Factory(), new SignatureDSA.Factory(),
|
protected void initKeyAlgorithms() {
|
||||||
// but add EdDSA
|
setKeyAlgorithms(Arrays.asList(
|
||||||
new SignatureEdDSA.Factory());
|
new EdDSAKeyAlgorithm.Factory(),
|
||||||
|
new RSAKeyAlgorithm.FactorySSHRSA(),
|
||||||
|
new DSAKeyAlgorithm.FactorySSHDSA()
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj;
|
package net.schmizz.sshj;
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.key.KeyAlgorithm;
|
||||||
import net.schmizz.keepalive.KeepAliveProvider;
|
import net.schmizz.keepalive.KeepAliveProvider;
|
||||||
import net.schmizz.sshj.common.Factory;
|
import net.schmizz.sshj.common.Factory;
|
||||||
import net.schmizz.sshj.common.LoggerFactory;
|
import net.schmizz.sshj.common.LoggerFactory;
|
||||||
@@ -77,11 +78,11 @@ public interface Config {
|
|||||||
Factory<Random> getRandomFactory();
|
Factory<Random> getRandomFactory();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the list of named factories for {@link Signature}
|
* Retrieve the list of named factories for {@link com.hierynomus.sshj.key.KeyAlgorithm}
|
||||||
*
|
*
|
||||||
* @return a list of named {@link Signature} factories
|
* @return a list of named {@link com.hierynomus.sshj.key.KeyAlgorithm} factories
|
||||||
*/
|
*/
|
||||||
List<Factory.Named<Signature>> getSignatureFactories();
|
List<Factory.Named<KeyAlgorithm>> getKeyAlgorithms();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the software version information for identification during SSH connection initialization. For example,
|
* Returns the software version information for identification during SSH connection initialization. For example,
|
||||||
@@ -132,11 +133,11 @@ public interface Config {
|
|||||||
void setRandomFactory(Factory<Random> randomFactory);
|
void setRandomFactory(Factory<Random> randomFactory);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the named factories for {@link Signature}.
|
* Set the named factories for {@link KeyAlgorithm}.
|
||||||
*
|
*
|
||||||
* @param signatureFactories a list of named factories
|
* @param keyAlgorithms a list of named factories
|
||||||
*/
|
*/
|
||||||
void setSignatureFactories(List<Factory.Named<Signature>> signatureFactories);
|
void setKeyAlgorithms(List<Factory.Named<KeyAlgorithm>> keyAlgorithms);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the software version information for identification during SSH connection initialization. For example, {@code
|
* Set the software version information for identification during SSH connection initialization. For example, {@code
|
||||||
|
|||||||
@@ -15,10 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj;
|
package net.schmizz.sshj;
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.key.KeyAlgorithm;
|
||||||
import net.schmizz.keepalive.KeepAliveProvider;
|
import net.schmizz.keepalive.KeepAliveProvider;
|
||||||
import net.schmizz.sshj.common.Factory;
|
import net.schmizz.sshj.common.Factory;
|
||||||
import net.schmizz.sshj.common.LoggerFactory;
|
import net.schmizz.sshj.common.LoggerFactory;
|
||||||
import net.schmizz.sshj.signature.Signature;
|
|
||||||
import net.schmizz.sshj.transport.cipher.Cipher;
|
import net.schmizz.sshj.transport.cipher.Cipher;
|
||||||
import net.schmizz.sshj.transport.compression.Compression;
|
import net.schmizz.sshj.transport.compression.Compression;
|
||||||
import net.schmizz.sshj.transport.kex.KeyExchange;
|
import net.schmizz.sshj.transport.kex.KeyExchange;
|
||||||
@@ -42,7 +42,7 @@ public class ConfigImpl
|
|||||||
private List<Factory.Named<Cipher>> cipherFactories;
|
private List<Factory.Named<Cipher>> cipherFactories;
|
||||||
private List<Factory.Named<Compression>> compressionFactories;
|
private List<Factory.Named<Compression>> compressionFactories;
|
||||||
private List<Factory.Named<MAC>> macFactories;
|
private List<Factory.Named<MAC>> macFactories;
|
||||||
private List<Factory.Named<Signature>> signatureFactories;
|
private List<Factory.Named<KeyAlgorithm>> keyAlgorithms;
|
||||||
private List<Factory.Named<FileKeyProvider>> fileKeyProviderFactories;
|
private List<Factory.Named<FileKeyProvider>> fileKeyProviderFactories;
|
||||||
|
|
||||||
private boolean waitForServerIdentBeforeSendingClientIdent = false;
|
private boolean waitForServerIdentBeforeSendingClientIdent = false;
|
||||||
@@ -78,11 +78,6 @@ public class ConfigImpl
|
|||||||
return randomFactory;
|
return randomFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<Factory.Named<Signature>> getSignatureFactories() {
|
|
||||||
return signatureFactories;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getVersion() {
|
public String getVersion() {
|
||||||
return version;
|
return version;
|
||||||
@@ -138,15 +133,6 @@ public class ConfigImpl
|
|||||||
this.randomFactory = randomFactory;
|
this.randomFactory = randomFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSignatureFactories(Factory.Named<Signature>... signatureFactories) {
|
|
||||||
setSignatureFactories(Arrays.asList(signatureFactories));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSignatureFactories(List<Factory.Named<Signature>> signatureFactories) {
|
|
||||||
this.signatureFactories = signatureFactories;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setVersion(String version) {
|
public void setVersion(String version) {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
@@ -172,6 +158,16 @@ public class ConfigImpl
|
|||||||
this.waitForServerIdentBeforeSendingClientIdent = waitForServerIdentBeforeSendingClientIdent;
|
this.waitForServerIdentBeforeSendingClientIdent = waitForServerIdentBeforeSendingClientIdent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Factory.Named<KeyAlgorithm>> getKeyAlgorithms() {
|
||||||
|
return keyAlgorithms;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setKeyAlgorithms(List<Factory.Named<KeyAlgorithm>> keyAlgorithms) {
|
||||||
|
this.keyAlgorithms = keyAlgorithms;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LoggerFactory getLoggerFactory() {
|
public LoggerFactory getLoggerFactory() {
|
||||||
return loggerFactory;
|
return loggerFactory;
|
||||||
|
|||||||
@@ -15,7 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj;
|
package net.schmizz.sshj;
|
||||||
|
|
||||||
import com.hierynomus.sshj.signature.SignatureEdDSA;
|
import com.hierynomus.sshj.key.DSAKeyAlgorithm;
|
||||||
|
import com.hierynomus.sshj.key.ECDSAKeyAlgorithm;
|
||||||
|
import com.hierynomus.sshj.key.EdDSAKeyAlgorithm;
|
||||||
|
import com.hierynomus.sshj.key.RSAKeyAlgorithm;
|
||||||
import com.hierynomus.sshj.transport.cipher.BlockCiphers;
|
import com.hierynomus.sshj.transport.cipher.BlockCiphers;
|
||||||
import com.hierynomus.sshj.transport.cipher.StreamCiphers;
|
import com.hierynomus.sshj.transport.cipher.StreamCiphers;
|
||||||
import com.hierynomus.sshj.transport.kex.DHGroups;
|
import com.hierynomus.sshj.transport.kex.DHGroups;
|
||||||
@@ -26,10 +29,7 @@ import net.schmizz.keepalive.KeepAliveProvider;
|
|||||||
import net.schmizz.sshj.common.Factory;
|
import net.schmizz.sshj.common.Factory;
|
||||||
import net.schmizz.sshj.common.LoggerFactory;
|
import net.schmizz.sshj.common.LoggerFactory;
|
||||||
import net.schmizz.sshj.common.SecurityUtils;
|
import net.schmizz.sshj.common.SecurityUtils;
|
||||||
import net.schmizz.sshj.signature.SignatureDSA;
|
import net.schmizz.sshj.transport.cipher.Cipher;
|
||||||
import net.schmizz.sshj.signature.SignatureECDSA;
|
|
||||||
import net.schmizz.sshj.signature.SignatureRSA;
|
|
||||||
import net.schmizz.sshj.transport.cipher.*;
|
|
||||||
import net.schmizz.sshj.transport.compression.NoneCompression;
|
import net.schmizz.sshj.transport.compression.NoneCompression;
|
||||||
import net.schmizz.sshj.transport.kex.Curve25519SHA256;
|
import net.schmizz.sshj.transport.kex.Curve25519SHA256;
|
||||||
import net.schmizz.sshj.transport.kex.DHGexSHA1;
|
import net.schmizz.sshj.transport.kex.DHGexSHA1;
|
||||||
@@ -56,7 +56,7 @@ import java.util.*;
|
|||||||
* <li>{@link net.schmizz.sshj.ConfigImpl#setMACFactories MAC}: {@link net.schmizz.sshj.transport.mac.HMACSHA1}, {@link net.schmizz.sshj.transport.mac.HMACSHA196}, {@link net.schmizz.sshj.transport.mac.HMACMD5}, {@link
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setMACFactories MAC}: {@link net.schmizz.sshj.transport.mac.HMACSHA1}, {@link net.schmizz.sshj.transport.mac.HMACSHA196}, {@link net.schmizz.sshj.transport.mac.HMACMD5}, {@link
|
||||||
* net.schmizz.sshj.transport.mac.HMACMD596}</li>
|
* net.schmizz.sshj.transport.mac.HMACMD596}</li>
|
||||||
* <li>{@link net.schmizz.sshj.ConfigImpl#setCompressionFactories Compression}: {@link net.schmizz.sshj.transport.compression.NoneCompression}</li>
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setCompressionFactories Compression}: {@link net.schmizz.sshj.transport.compression.NoneCompression}</li>
|
||||||
* <li>{@link net.schmizz.sshj.ConfigImpl#setSignatureFactories Signature}: {@link net.schmizz.sshj.signature.SignatureRSA}, {@link net.schmizz.sshj.signature.SignatureDSA}</li>
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setKeyAlgorithms KeyAlgorithm}: {@link net.schmizz.sshj.signature.SignatureRSA}, {@link net.schmizz.sshj.signature.SignatureDSA}</li>
|
||||||
* <li>{@link net.schmizz.sshj.ConfigImpl#setRandomFactory PRNG}: {@link net.schmizz.sshj.transport.random.BouncyCastleRandom}* or {@link net.schmizz.sshj.transport.random.JCERandom}</li>
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setRandomFactory PRNG}: {@link net.schmizz.sshj.transport.random.BouncyCastleRandom}* or {@link net.schmizz.sshj.transport.random.JCERandom}</li>
|
||||||
* <li>{@link net.schmizz.sshj.ConfigImpl#setFileKeyProviderFactories Key file support}: {@link net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile}*, {@link
|
* <li>{@link net.schmizz.sshj.ConfigImpl#setFileKeyProviderFactories Key file support}: {@link net.schmizz.sshj.userauth.keyprovider.PKCS8KeyFile}*, {@link
|
||||||
* net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile}*</li>
|
* net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile}*</li>
|
||||||
@@ -76,12 +76,12 @@ public class DefaultConfig
|
|||||||
setVersion(readVersionFromProperties());
|
setVersion(readVersionFromProperties());
|
||||||
final boolean bouncyCastleRegistered = SecurityUtils.isBouncyCastleRegistered();
|
final boolean bouncyCastleRegistered = SecurityUtils.isBouncyCastleRegistered();
|
||||||
initKeyExchangeFactories(bouncyCastleRegistered);
|
initKeyExchangeFactories(bouncyCastleRegistered);
|
||||||
|
initKeyAlgorithms();
|
||||||
initRandomFactory(bouncyCastleRegistered);
|
initRandomFactory(bouncyCastleRegistered);
|
||||||
initFileKeyProviderFactories(bouncyCastleRegistered);
|
initFileKeyProviderFactories(bouncyCastleRegistered);
|
||||||
initCipherFactories();
|
initCipherFactories();
|
||||||
initCompressionFactories();
|
initCompressionFactories();
|
||||||
initMACFactories();
|
initMACFactories();
|
||||||
initSignatureFactories();
|
|
||||||
setKeepAliveProvider(KeepAliveProvider.HEARTBEAT);
|
setKeepAliveProvider(KeepAliveProvider.HEARTBEAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,6 +133,20 @@ public class DefaultConfig
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void initKeyAlgorithms() {
|
||||||
|
setKeyAlgorithms(Arrays.asList(
|
||||||
|
new EdDSAKeyAlgorithm.Factory(),
|
||||||
|
new ECDSAKeyAlgorithm.Factory521(),
|
||||||
|
new ECDSAKeyAlgorithm.Factory384(),
|
||||||
|
new ECDSAKeyAlgorithm.Factory256(),
|
||||||
|
new RSAKeyAlgorithm.FactoryRSASHA512(),
|
||||||
|
new RSAKeyAlgorithm.FactoryRSASHA256(),
|
||||||
|
new RSAKeyAlgorithm.FactorySSHRSACert(),
|
||||||
|
new DSAKeyAlgorithm.FactorySSHDSSCert(),
|
||||||
|
new RSAKeyAlgorithm.FactorySSHRSA(),
|
||||||
|
new DSAKeyAlgorithm.FactorySSHDSA()));
|
||||||
|
}
|
||||||
|
|
||||||
protected void initRandomFactory(boolean bouncyCastleRegistered) {
|
protected void initRandomFactory(boolean bouncyCastleRegistered) {
|
||||||
setRandomFactory(new SingletonRandomFactory(bouncyCastleRegistered
|
setRandomFactory(new SingletonRandomFactory(bouncyCastleRegistered
|
||||||
? new BouncyCastleRandom.Factory() : new JCERandom.Factory()));
|
? new BouncyCastleRandom.Factory() : new JCERandom.Factory()));
|
||||||
@@ -207,18 +221,6 @@ public class DefaultConfig
|
|||||||
log.debug("Available cipher factories: {}", avail);
|
log.debug("Available cipher factories: {}", avail);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initSignatureFactories() {
|
|
||||||
setSignatureFactories(
|
|
||||||
new SignatureEdDSA.Factory(),
|
|
||||||
new SignatureECDSA.Factory256(),
|
|
||||||
new SignatureECDSA.Factory384(),
|
|
||||||
new SignatureECDSA.Factory521(),
|
|
||||||
new SignatureRSA.Factory(),
|
|
||||||
new SignatureRSA.FactoryCERT(),
|
|
||||||
new SignatureDSA.Factory()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void initMACFactories() {
|
protected void initMACFactories() {
|
||||||
setMACFactories(
|
setMACFactories(
|
||||||
Macs.HMACSHA1(),
|
Macs.HMACSHA1(),
|
||||||
|
|||||||
@@ -29,18 +29,26 @@ public abstract class AbstractSignature
|
|||||||
|
|
||||||
@SuppressWarnings("PMD.UnnecessaryFullyQualifiedName")
|
@SuppressWarnings("PMD.UnnecessaryFullyQualifiedName")
|
||||||
protected final java.security.Signature signature;
|
protected final java.security.Signature signature;
|
||||||
|
private final String signatureName;
|
||||||
|
|
||||||
protected AbstractSignature(String algorithm) {
|
protected AbstractSignature(String algorithm, String signatureName) {
|
||||||
try {
|
try {
|
||||||
this.signature = SecurityUtils.getSignature(algorithm);
|
this.signature = SecurityUtils.getSignature(algorithm);
|
||||||
|
this.signatureName = signatureName;
|
||||||
} catch (GeneralSecurityException e) {
|
} catch (GeneralSecurityException e) {
|
||||||
throw new SSHRuntimeException(e);
|
throw new SSHRuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected AbstractSignature(@SuppressWarnings("PMD.UnnecessaryFullyQualifiedName")
|
protected AbstractSignature(@SuppressWarnings("PMD.UnnecessaryFullyQualifiedName")
|
||||||
java.security.Signature signatureEngine) {
|
java.security.Signature signatureEngine, String signatureName) {
|
||||||
this.signature = signatureEngine;
|
this.signature = signatureEngine;
|
||||||
|
this.signatureName = signatureName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSignatureName() {
|
||||||
|
return signatureName;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import java.security.PublicKey;
|
|||||||
/** Signature interface for SSH used to sign or verify data. Usually wraps a {@code javax.crypto.Signature} object. */
|
/** Signature interface for SSH used to sign or verify data. Usually wraps a {@code javax.crypto.Signature} object. */
|
||||||
public interface Signature {
|
public interface Signature {
|
||||||
|
|
||||||
|
String getSignatureName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize this signature with the given public key for signature verification.
|
* Initialize this signature with the given public key for signature verification.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ public class SignatureDSA
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SignatureDSA() {
|
public SignatureDSA() {
|
||||||
super("SHA1withDSA");
|
super("SHA1withDSA", KeyType.DSA.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -72,8 +72,8 @@ public class SignatureDSA
|
|||||||
|
|
||||||
// result must be 40 bytes, but length of r and s may not be 20 bytes
|
// result must be 40 bytes, but length of r and s may not be 20 bytes
|
||||||
|
|
||||||
int r_copylen = (r.length < 20) ? r.length : 20;
|
int r_copylen = Math.min(r.length, 20);
|
||||||
int s_copylen = (s.length < 20) ? s.length : 20;
|
int s_copylen = Math.min(s.length, 20);
|
||||||
|
|
||||||
System.arraycopy(r, r.length - r_copylen, result, 20 - r_copylen, r_copylen);
|
System.arraycopy(r, r.length - r_copylen, result, 20 - r_copylen, r_copylen);
|
||||||
System.arraycopy(s, s.length - s_copylen, result, 40 - s_copylen, s_copylen);
|
System.arraycopy(s, s.length - s_copylen, result, 40 - s_copylen, s_copylen);
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public class SignatureECDSA extends AbstractSignature {
|
|||||||
private String keyTypeName;
|
private String keyTypeName;
|
||||||
|
|
||||||
public SignatureECDSA(String algorithm, String keyTypeName) {
|
public SignatureECDSA(String algorithm, String keyTypeName) {
|
||||||
super(algorithm);
|
super(algorithm, keyTypeName);
|
||||||
this.keyTypeName = keyTypeName;
|
this.keyTypeName = keyTypeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,26 +22,53 @@ import net.schmizz.sshj.common.SSHRuntimeException;
|
|||||||
import java.security.InvalidKeyException;
|
import java.security.InvalidKeyException;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/** RSA {@link Signature} */
|
/** RSA {@link Signature} */
|
||||||
public class SignatureRSA
|
public class SignatureRSA
|
||||||
extends AbstractSignature {
|
extends AbstractSignature {
|
||||||
|
|
||||||
/** A named factory for RSA {@link Signature} */
|
/** A named factory for RSA {@link Signature} */
|
||||||
public static class Factory
|
public static class FactorySSHRSA
|
||||||
implements net.schmizz.sshj.common.Factory.Named<Signature> {
|
implements net.schmizz.sshj.common.Factory.Named<Signature> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Signature create() {
|
public Signature create() {
|
||||||
return new SignatureRSA(KeyType.RSA.toString());
|
return new SignatureRSA("SHA1withRSA", KeyType.RSA, KeyType.RSA.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return KeyType.RSA.toString();
|
return KeyType.RSA.toString();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A named factory for RSA {@link Signature} */
|
||||||
|
public static class FactoryRSASHA256
|
||||||
|
implements net.schmizz.sshj.common.Factory.Named<Signature> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Signature create() {
|
||||||
|
return new SignatureRSA("SHA256withRSA", KeyType.RSA, "rsa-sha2-256");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "rsa-sha2-256";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/** A named factory for RSA {@link Signature} */
|
||||||
|
public static class FactoryRSASHA512
|
||||||
|
implements net.schmizz.sshj.common.Factory.Named<Signature> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Signature create() {
|
||||||
|
return new SignatureRSA("SHA512withRSA", KeyType.RSA, "rsa-sha2-512");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "rsa-sha2-512";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A named factory for RSA {@link Signature} */
|
/** A named factory for RSA {@link Signature} */
|
||||||
@@ -50,7 +77,7 @@ public class SignatureRSA
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Signature create() {
|
public Signature create() {
|
||||||
return new SignatureRSA(KeyType.RSA_CERT.toString());
|
return new SignatureRSA("SHA1withRSA", KeyType.RSA_CERT, KeyType.RSA.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -60,19 +87,19 @@ public class SignatureRSA
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String keyTypeName;
|
private KeyType keyType;
|
||||||
|
|
||||||
|
|
||||||
public SignatureRSA(String keyTypeName) {
|
public SignatureRSA(String algorithm, KeyType keyType, String name) {
|
||||||
super("SHA1withRSA");
|
super(algorithm, name);
|
||||||
this.keyTypeName = keyTypeName;
|
this.keyType = keyType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void initVerify(PublicKey publicKey) {
|
public void initVerify(PublicKey publicKey) {
|
||||||
try {
|
try {
|
||||||
if (this.keyTypeName.equals(KeyType.RSA_CERT.toString()) && publicKey instanceof Certificate) {
|
if (this.keyType.equals(KeyType.RSA_CERT) && publicKey instanceof Certificate) {
|
||||||
signature.initVerify(((Certificate<PublicKey>) publicKey).getKey());
|
signature.initVerify(((Certificate<PublicKey>) publicKey).getKey());
|
||||||
} else {
|
} else {
|
||||||
signature.initVerify(publicKey);
|
signature.initVerify(publicKey);
|
||||||
@@ -89,7 +116,7 @@ public class SignatureRSA
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean verify(byte[] sig) {
|
public boolean verify(byte[] sig) {
|
||||||
sig = extractSig(sig, KeyType.RSA.toString());
|
sig = extractSig(sig, getSignatureName());
|
||||||
try {
|
try {
|
||||||
return signature.verify(sig);
|
return signature.verify(sig);
|
||||||
} catch (SignatureException e) {
|
} catch (SignatureException e) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj.transport;
|
package net.schmizz.sshj.transport;
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.key.KeyAlgorithm;
|
||||||
import net.schmizz.concurrent.ErrorDeliveryUtil;
|
import net.schmizz.concurrent.ErrorDeliveryUtil;
|
||||||
import net.schmizz.concurrent.Event;
|
import net.schmizz.concurrent.Event;
|
||||||
import net.schmizz.sshj.common.*;
|
import net.schmizz.sshj.common.*;
|
||||||
@@ -30,9 +31,7 @@ import org.slf4j.Logger;
|
|||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.util.Arrays;
|
import java.util.*;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
@@ -232,6 +231,13 @@ final class KeyExchanger
|
|||||||
}
|
}
|
||||||
kex = Factory.Named.Util.create(transport.getConfig().getKeyExchangeFactories(),
|
kex = Factory.Named.Util.create(transport.getConfig().getKeyExchangeFactories(),
|
||||||
negotiatedAlgs.getKeyExchangeAlgorithm());
|
negotiatedAlgs.getKeyExchangeAlgorithm());
|
||||||
|
|
||||||
|
List<KeyAlgorithm> keyAlgorithms = new ArrayList<KeyAlgorithm>();
|
||||||
|
for (String signatureAlgorithm : negotiatedAlgs.getSignatureAlgorithms()) {
|
||||||
|
keyAlgorithms.add(Factory.Named.Util.create(transport.getConfig().getKeyAlgorithms(), signatureAlgorithm));
|
||||||
|
}
|
||||||
|
transport.setKeyAlgorithms(keyAlgorithms);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
kex.init(transport,
|
kex.init(transport,
|
||||||
transport.getServerID(), transport.getClientID(),
|
transport.getServerID(), transport.getClientID(),
|
||||||
|
|||||||
@@ -15,10 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj.transport;
|
package net.schmizz.sshj.transport;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public final class NegotiatedAlgorithms {
|
public final class NegotiatedAlgorithms {
|
||||||
|
|
||||||
private final String kex;
|
private final String kex;
|
||||||
private final String sig;
|
private final List<String> availableSigs;
|
||||||
private final String c2sCipher;
|
private final String c2sCipher;
|
||||||
private final String s2cCipher;
|
private final String s2cCipher;
|
||||||
private final String c2sMAC;
|
private final String c2sMAC;
|
||||||
@@ -26,10 +28,10 @@ public final class NegotiatedAlgorithms {
|
|||||||
private final String c2sComp;
|
private final String c2sComp;
|
||||||
private final String s2cComp;
|
private final String s2cComp;
|
||||||
|
|
||||||
NegotiatedAlgorithms(String kex, String sig, String c2sCipher, String s2cCipher, String c2sMAC, String s2cMAC,
|
NegotiatedAlgorithms(String kex, List<String> availableSigs, String c2sCipher, String s2cCipher, String c2sMAC, String s2cMAC,
|
||||||
String c2sComp, String s2cComp) {
|
String c2sComp, String s2cComp) {
|
||||||
this.kex = kex;
|
this.kex = kex;
|
||||||
this.sig = sig;
|
this.availableSigs = availableSigs;
|
||||||
this.c2sCipher = c2sCipher;
|
this.c2sCipher = c2sCipher;
|
||||||
this.s2cCipher = s2cCipher;
|
this.s2cCipher = s2cCipher;
|
||||||
this.c2sMAC = c2sMAC;
|
this.c2sMAC = c2sMAC;
|
||||||
@@ -42,8 +44,8 @@ public final class NegotiatedAlgorithms {
|
|||||||
return kex;
|
return kex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getSignatureAlgorithm() {
|
public List<String> getSignatureAlgorithms() {
|
||||||
return sig;
|
return availableSigs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClient2ServerCipherAlgorithm() {
|
public String getClient2ServerCipherAlgorithm() {
|
||||||
@@ -74,7 +76,7 @@ public final class NegotiatedAlgorithms {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return ("[ " +
|
return ("[ " +
|
||||||
"kex=" + kex + "; " +
|
"kex=" + kex + "; " +
|
||||||
"sig=" + sig + "; " +
|
"availableSigs=" + availableSigs + "; " +
|
||||||
"c2sCipher=" + c2sCipher + "; " +
|
"c2sCipher=" + c2sCipher + "; " +
|
||||||
"s2cCipher=" + s2cCipher + "; " +
|
"s2cCipher=" + s2cCipher + "; " +
|
||||||
"c2sMAC=" + c2sMAC + "; " +
|
"c2sMAC=" + c2sMAC + "; " +
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import net.schmizz.sshj.common.Factory;
|
|||||||
import net.schmizz.sshj.common.Message;
|
import net.schmizz.sshj.common.Message;
|
||||||
import net.schmizz.sshj.common.SSHPacket;
|
import net.schmizz.sshj.common.SSHPacket;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -38,7 +39,7 @@ class Proposal {
|
|||||||
|
|
||||||
public Proposal(Config config) {
|
public Proposal(Config config) {
|
||||||
kex = Factory.Named.Util.getNames(config.getKeyExchangeFactories());
|
kex = Factory.Named.Util.getNames(config.getKeyExchangeFactories());
|
||||||
sig = Factory.Named.Util.getNames(config.getSignatureFactories());
|
sig = Factory.Named.Util.getNames(config.getKeyAlgorithms());
|
||||||
c2sCipher = s2cCipher = Factory.Named.Util.getNames(config.getCipherFactories());
|
c2sCipher = s2cCipher = Factory.Named.Util.getNames(config.getCipherFactories());
|
||||||
c2sMAC = s2cMAC = Factory.Named.Util.getNames(config.getMACFactories());
|
c2sMAC = s2cMAC = Factory.Named.Util.getNames(config.getMACFactories());
|
||||||
c2sComp = s2cComp = Factory.Named.Util.getNames(config.getCompressionFactories());
|
c2sComp = s2cComp = Factory.Named.Util.getNames(config.getCompressionFactories());
|
||||||
@@ -126,7 +127,7 @@ class Proposal {
|
|||||||
throws TransportException {
|
throws TransportException {
|
||||||
return new NegotiatedAlgorithms(
|
return new NegotiatedAlgorithms(
|
||||||
firstMatch(this.getKeyExchangeAlgorithms(), other.getKeyExchangeAlgorithms()),
|
firstMatch(this.getKeyExchangeAlgorithms(), other.getKeyExchangeAlgorithms()),
|
||||||
firstMatch(this.getSignatureAlgorithms(), other.getSignatureAlgorithms()),
|
allMatch(this.getSignatureAlgorithms(), other.getSignatureAlgorithms()),
|
||||||
firstMatch(this.getClient2ServerCipherAlgorithms(), other.getClient2ServerCipherAlgorithms()),
|
firstMatch(this.getClient2ServerCipherAlgorithms(), other.getClient2ServerCipherAlgorithms()),
|
||||||
firstMatch(this.getServer2ClientCipherAlgorithms(), other.getServer2ClientCipherAlgorithms()),
|
firstMatch(this.getServer2ClientCipherAlgorithms(), other.getServer2ClientCipherAlgorithms()),
|
||||||
firstMatch(this.getClient2ServerMACAlgorithms(), other.getClient2ServerMACAlgorithms()),
|
firstMatch(this.getClient2ServerMACAlgorithms(), other.getClient2ServerMACAlgorithms()),
|
||||||
@@ -138,19 +139,36 @@ class Proposal {
|
|||||||
|
|
||||||
private static String firstMatch(List<String> a, List<String> b)
|
private static String firstMatch(List<String> a, List<String> b)
|
||||||
throws TransportException {
|
throws TransportException {
|
||||||
for (String aa : a)
|
for (String aa : a) {
|
||||||
for (String bb : b)
|
if (b.contains(aa)) {
|
||||||
if (aa.equals(bb))
|
|
||||||
return aa;
|
return aa;
|
||||||
|
}
|
||||||
|
}
|
||||||
throw new TransportException("Unable to reach a settlement: " + a + " and " + b);
|
throw new TransportException("Unable to reach a settlement: " + a + " and " + b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<String> allMatch(List<String> a, List<String> b) throws TransportException {
|
||||||
|
List<String> res = new ArrayList<String>();
|
||||||
|
for (String aa : a) {
|
||||||
|
if (b.contains(aa)) {
|
||||||
|
res.add(aa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res.isEmpty()) {
|
||||||
|
throw new TransportException("Unable to reach a settlement: " + a + " and " + b);
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
private static String toCommaString(List<String> sl) {
|
private static String toCommaString(List<String> sl) {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (String s : sl) {
|
for (String s : sl) {
|
||||||
if (i++ != 0)
|
if (i++ != 0) {
|
||||||
sb.append(",");
|
sb.append(",");
|
||||||
|
}
|
||||||
sb.append(s);
|
sb.append(s);
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
|
|||||||
@@ -15,9 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj.transport;
|
package net.schmizz.sshj.transport;
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.key.KeyAlgorithm;
|
||||||
import net.schmizz.sshj.Config;
|
import net.schmizz.sshj.Config;
|
||||||
import net.schmizz.sshj.Service;
|
import net.schmizz.sshj.Service;
|
||||||
import net.schmizz.sshj.common.DisconnectReason;
|
import net.schmizz.sshj.common.DisconnectReason;
|
||||||
|
import net.schmizz.sshj.common.KeyType;
|
||||||
import net.schmizz.sshj.common.SSHPacket;
|
import net.schmizz.sshj.common.SSHPacket;
|
||||||
import net.schmizz.sshj.common.SSHPacketHandler;
|
import net.schmizz.sshj.common.SSHPacketHandler;
|
||||||
import net.schmizz.sshj.transport.verification.AlgorithmsVerifier;
|
import net.schmizz.sshj.transport.verification.AlgorithmsVerifier;
|
||||||
@@ -235,4 +237,6 @@ public interface Transport
|
|||||||
* @param e The exception that occurred.
|
* @param e The exception that occurred.
|
||||||
*/
|
*/
|
||||||
void die(Exception e);
|
void die(Exception e);
|
||||||
|
|
||||||
|
KeyAlgorithm getKeyAlgorithm(KeyType keyType) throws TransportException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj.transport;
|
package net.schmizz.sshj.transport;
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.key.KeyAlgorithm;
|
||||||
import com.hierynomus.sshj.transport.IdentificationStringParser;
|
import com.hierynomus.sshj.transport.IdentificationStringParser;
|
||||||
import net.schmizz.concurrent.ErrorDeliveryUtil;
|
import net.schmizz.concurrent.ErrorDeliveryUtil;
|
||||||
import net.schmizz.concurrent.Event;
|
import net.schmizz.concurrent.Event;
|
||||||
@@ -30,6 +31,7 @@ import org.slf4j.Logger;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
@@ -39,6 +41,7 @@ import java.util.concurrent.locks.ReentrantLock;
|
|||||||
public final class TransportImpl
|
public final class TransportImpl
|
||||||
implements Transport, DisconnectListener {
|
implements Transport, DisconnectListener {
|
||||||
|
|
||||||
|
|
||||||
private static final class NullService
|
private static final class NullService
|
||||||
extends AbstractService {
|
extends AbstractService {
|
||||||
|
|
||||||
@@ -86,6 +89,8 @@ public final class TransportImpl
|
|||||||
|
|
||||||
private final Decoder decoder;
|
private final Decoder decoder;
|
||||||
|
|
||||||
|
private List<KeyAlgorithm> keyAlgorithms;
|
||||||
|
|
||||||
private final Event<TransportException> serviceAccept;
|
private final Event<TransportException> serviceAccept;
|
||||||
|
|
||||||
private final Event<TransportException> close;
|
private final Event<TransportException> close;
|
||||||
@@ -649,4 +654,18 @@ public final class TransportImpl
|
|||||||
return connInfo;
|
return connInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public KeyAlgorithm getKeyAlgorithm(KeyType keyType) throws TransportException {
|
||||||
|
for (KeyAlgorithm ka : keyAlgorithms) {
|
||||||
|
if (ka.getKeyFormat().equals(keyType)) {
|
||||||
|
return ka;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new TransportException("Cannot find an available KeyAlgorithm for type " + keyType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setKeyAlgorithms(List<KeyAlgorithm> keyAlgorithms) {
|
||||||
|
this.keyAlgorithms = keyAlgorithms;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,8 +78,8 @@ public abstract class AbstractDHG extends AbstractDH
|
|||||||
digest.update(buf.array(), buf.rpos(), buf.available());
|
digest.update(buf.array(), buf.rpos(), buf.available());
|
||||||
H = digest.digest();
|
H = digest.digest();
|
||||||
|
|
||||||
Signature signature = Factory.Named.Util.create(trans.getConfig().getSignatureFactories(),
|
|
||||||
KeyType.fromKey(hostKey).toString());
|
Signature signature = trans.getKeyAlgorithm(KeyType.fromKey(hostKey)).newSignature();
|
||||||
signature.initVerify(hostKey);
|
signature.initVerify(hostKey);
|
||||||
signature.update(H, 0, H.length);
|
signature.update(H, 0, H.length);
|
||||||
if (!signature.verify(sig))
|
if (!signature.verify(sig))
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj.transport.kex;
|
package net.schmizz.sshj.transport.kex;
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.key.KeyAlgorithm;
|
||||||
import net.schmizz.sshj.common.*;
|
import net.schmizz.sshj.common.*;
|
||||||
import net.schmizz.sshj.signature.Signature;
|
import net.schmizz.sshj.signature.Signature;
|
||||||
import net.schmizz.sshj.transport.Transport;
|
import net.schmizz.sshj.transport.Transport;
|
||||||
@@ -30,9 +31,9 @@ import java.security.GeneralSecurityException;
|
|||||||
public abstract class AbstractDHGex extends AbstractDH {
|
public abstract class AbstractDHGex extends AbstractDH {
|
||||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
private int minBits = 1024;
|
private final int minBits = 1024;
|
||||||
private int maxBits = 8192;
|
private final int maxBits = 8192;
|
||||||
private int preferredBits = 2048;
|
private final int preferredBits = 2048;
|
||||||
|
|
||||||
public AbstractDHGex(Digest digest) {
|
public AbstractDHGex(Digest digest) {
|
||||||
super(new DH(), digest);
|
super(new DH(), digest);
|
||||||
@@ -84,8 +85,8 @@ public abstract class AbstractDHGex extends AbstractDH {
|
|||||||
.putMPInt(k);
|
.putMPInt(k);
|
||||||
digest.update(buf.array(), buf.rpos(), buf.available());
|
digest.update(buf.array(), buf.rpos(), buf.available());
|
||||||
H = digest.digest();
|
H = digest.digest();
|
||||||
Signature signature = Factory.Named.Util.create(trans.getConfig().getSignatureFactories(),
|
KeyAlgorithm keyAlgorithm = trans.getKeyAlgorithm(KeyType.fromKey(hostKey));
|
||||||
KeyType.fromKey(hostKey).toString());
|
Signature signature = keyAlgorithm.newSignature();
|
||||||
signature.initVerify(hostKey);
|
signature.initVerify(hostKey);
|
||||||
signature.update(H, 0, H.length);
|
signature.update(H, 0, H.length);
|
||||||
if (!signature.verify(sig))
|
if (!signature.verify(sig))
|
||||||
|
|||||||
@@ -15,11 +15,12 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj.userauth.method;
|
package net.schmizz.sshj.userauth.method;
|
||||||
|
|
||||||
|
import com.hierynomus.sshj.key.KeyAlgorithm;
|
||||||
import net.schmizz.sshj.common.Buffer;
|
import net.schmizz.sshj.common.Buffer;
|
||||||
import net.schmizz.sshj.common.Factory;
|
|
||||||
import net.schmizz.sshj.common.KeyType;
|
import net.schmizz.sshj.common.KeyType;
|
||||||
import net.schmizz.sshj.common.SSHPacket;
|
import net.schmizz.sshj.common.SSHPacket;
|
||||||
import net.schmizz.sshj.signature.Signature;
|
import net.schmizz.sshj.signature.Signature;
|
||||||
|
import net.schmizz.sshj.transport.TransportException;
|
||||||
import net.schmizz.sshj.userauth.UserAuthException;
|
import net.schmizz.sshj.userauth.UserAuthException;
|
||||||
import net.schmizz.sshj.userauth.keyprovider.KeyProvider;
|
import net.schmizz.sshj.userauth.keyprovider.KeyProvider;
|
||||||
|
|
||||||
@@ -47,9 +48,15 @@ public abstract class KeyedAuthMethod
|
|||||||
}
|
}
|
||||||
|
|
||||||
// public key as 2 strings: [ key type | key blob ]
|
// public key as 2 strings: [ key type | key blob ]
|
||||||
reqBuf.putString(KeyType.fromKey(key).toString())
|
KeyType keyType = KeyType.fromKey(key);
|
||||||
|
try {
|
||||||
|
KeyAlgorithm ka = params.getTransport().getKeyAlgorithm(keyType);
|
||||||
|
reqBuf.putString(ka.getKeyAlgorithm())
|
||||||
.putString(new Buffer.PlainBuffer().putPublicKey(key).getCompactData());
|
.putString(new Buffer.PlainBuffer().putPublicKey(key).getCompactData());
|
||||||
return reqBuf;
|
return reqBuf;
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw new UserAuthException("No KeyAlgorithm configured for key " + keyType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SSHPacket putSig(SSHPacket reqBuf)
|
protected SSHPacket putSig(SSHPacket reqBuf)
|
||||||
@@ -61,17 +68,20 @@ public abstract class KeyedAuthMethod
|
|||||||
throw new UserAuthException("Problem getting private key from " + kProv, ioe);
|
throw new UserAuthException("Problem getting private key from " + kProv, ioe);
|
||||||
}
|
}
|
||||||
|
|
||||||
final String kt = KeyType.fromKey(key).toString();
|
final KeyType kt = KeyType.fromKey(key);
|
||||||
Signature signature = Factory.Named.Util.create(params.getTransport().getConfig().getSignatureFactories(), kt);
|
Signature signature;
|
||||||
if (signature == null)
|
try {
|
||||||
throw new UserAuthException("Could not create signature instance for " + kt + " key");
|
signature = params.getTransport().getKeyAlgorithm(kt).newSignature();
|
||||||
|
} catch (TransportException e) {
|
||||||
|
throw new UserAuthException("No KeyAlgorithm configured for key " + kt);
|
||||||
|
}
|
||||||
|
|
||||||
signature.initSign(key);
|
signature.initSign(key);
|
||||||
signature.update(new Buffer.PlainBuffer()
|
signature.update(new Buffer.PlainBuffer()
|
||||||
.putString(params.getTransport().getSessionID())
|
.putString(params.getTransport().getSessionID())
|
||||||
.putBuffer(reqBuf) // & rest of the data for sig
|
.putBuffer(reqBuf) // & rest of the data for sig
|
||||||
.getCompactData());
|
.getCompactData());
|
||||||
reqBuf.putSignature(kt, signature.encode(signature.sign()));
|
reqBuf.putSignature(signature.getSignatureName(), signature.encode(signature.sign()));
|
||||||
return reqBuf;
|
return reqBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user