diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/SshAuthenticationService.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/SshAuthenticationService.java index 2b3574aec..57dab705e 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/SshAuthenticationService.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/remote/SshAuthenticationService.java @@ -195,16 +195,18 @@ public class SshAuthenticationService extends Service { byte[] sshSignature; try { switch (authSubKeyAlgorithm) { - case PublicKeyAlgorithmTags.ECDSA: - sshSignature = SshSignatureConverter.getSshSignatureEcDsa(rawSignature, authSubKeyCurveOid); + case PublicKeyAlgorithmTags.EDDSA: + sshSignature = SshSignatureConverter.getSshSignatureEdDsa(rawSignature); break; case PublicKeyAlgorithmTags.RSA_SIGN: case PublicKeyAlgorithmTags.RSA_GENERAL: sshSignature = SshSignatureConverter.getSshSignatureRsa(rawSignature, hashAlgorithmTag); break; + case PublicKeyAlgorithmTags.ECDSA: + sshSignature = SshSignatureConverter.getSshSignatureEcDsa(rawSignature, authSubKeyCurveOid); + break; case PublicKeyAlgorithmTags.DSA: - case PublicKeyAlgorithmTags.EDDSA: - sshSignature = SshSignatureConverter.getSshSignature(rawSignature, authSubKeyAlgorithm); + sshSignature = SshSignatureConverter.getSshSignatureDsa(rawSignature); break; default: throw new NoSuchAlgorithmException("Unknown algorithm"); diff --git a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ssh/signature/SshSignatureConverter.java b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ssh/signature/SshSignatureConverter.java index b840f9e00..2605223d0 100644 --- a/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ssh/signature/SshSignatureConverter.java +++ b/OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ssh/signature/SshSignatureConverter.java @@ -21,7 +21,6 @@ import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.bcpg.HashAlgorithmTags; -import org.bouncycastle.bcpg.PublicKeyAlgorithmTags; import org.bouncycastle.util.BigIntegers; import org.sufficientlysecure.keychain.ssh.key.SshEncodedData; import org.sufficientlysecure.keychain.ssh.utils.SshUtils; @@ -33,15 +32,17 @@ import java.security.NoSuchAlgorithmException; public class SshSignatureConverter { private static String getRsaSignatureFormatId(int hashAlgorithm) throws NoSuchAlgorithmException { - // https://tools.ietf.org/html/rfc8332 switch (hashAlgorithm) { case HashAlgorithmTags.SHA512: + // https://tools.ietf.org/html/rfc8332 return "rsa-sha2-512"; case HashAlgorithmTags.SHA256: + // https://tools.ietf.org/html/rfc8332 return "rsa-sha2-256"; case HashAlgorithmTags.SHA1: + // https://tools.ietf.org/html/rfc4253 return "ssh-rsa"; default: @@ -49,32 +50,6 @@ public class SshSignatureConverter { } } - private static String getSignatureFormatId(int algorithm) throws NoSuchAlgorithmException { - switch (algorithm) { - case PublicKeyAlgorithmTags.EDDSA: - return "ssh-ed25519"; - - case PublicKeyAlgorithmTags.DSA: - return "ssh-dss"; - - default: - throw new NoSuchAlgorithmException("Unknown algorithm"); - } - } - - private static byte[] getSignatureBlob(byte[] rawSignature, int algorithm) throws NoSuchAlgorithmException { - switch (algorithm) { - case PublicKeyAlgorithmTags.EDDSA: - return rawSignature; - - case PublicKeyAlgorithmTags.DSA: - return getDsaSignatureBlob(rawSignature); - - default: - throw new NoSuchAlgorithmException("Unknown algorithm"); - } - } - private static byte[] getEcDsaSignatureBlob(byte[] rawSignature) { BigInteger r = getR(rawSignature); BigInteger s = getS(rawSignature); @@ -130,10 +105,20 @@ public class SshSignatureConverter { } } - public static byte[] getSshSignature(byte[] rawSignature, int algorithm) throws NoSuchAlgorithmException { + public static byte[] getSshSignatureEdDsa(byte[] rawSignature) { SshEncodedData signature = new SshEncodedData(); - signature.putString(getSignatureFormatId(algorithm)); - signature.putString(getSignatureBlob(rawSignature, algorithm)); + // https://tools.ietf.org/html/draft-ietf-curdle-ssh-ed25519-ed448-00 + signature.putString("ssh-ed25519"); + signature.putString(rawSignature); + + return signature.getBytes(); + } + + public static byte[] getSshSignatureDsa(byte[] rawSignature) { + SshEncodedData signature = new SshEncodedData(); + // https://tools.ietf.org/html/rfc4253 + signature.putString("ssh-dss"); + signature.putString(getDsaSignatureBlob(rawSignature)); return signature.getBytes(); } @@ -148,6 +133,7 @@ public class SshSignatureConverter { public static byte[] getSshSignatureEcDsa(byte[] rawSignature, String curveOid) throws NoSuchAlgorithmException { SshEncodedData signature = new SshEncodedData(); + // https://tools.ietf.org/html/rfc5656 signature.putString("ecdsa-sha2-" + SshUtils.getCurveName(curveOid)); signature.putString(getEcDsaSignatureBlob(rawSignature)); diff --git a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/ssh/signature/SshSignatureConverterTest.java b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/ssh/signature/SshSignatureConverterTest.java index c4d3c722f..97a5f3036 100644 --- a/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/ssh/signature/SshSignatureConverterTest.java +++ b/OpenKeychain/src/test/java/org/sufficientlysecure/keychain/ssh/signature/SshSignatureConverterTest.java @@ -242,14 +242,14 @@ public class SshSignatureConverterTest { @Test public void testEdDsa() throws Exception { - byte[] out = SshSignatureConverter.getSshSignature(RAW_EDDSA_SIGNATURE, PublicKeyAlgorithmTags.EDDSA); + byte[] out = SshSignatureConverter.getSshSignatureEdDsa(RAW_EDDSA_SIGNATURE); Assert.assertArrayEquals(SSH_EDDSA_SIGNATURE, out); } @Test public void testDsa() throws Exception { - byte[] out = SshSignatureConverter.getSshSignature(RAW_DSA_SIGNATURE, PublicKeyAlgorithmTags.DSA); + byte[] out = SshSignatureConverter.getSshSignatureDsa(RAW_DSA_SIGNATURE); Assert.assertArrayEquals(SSH_DSA_SIGNATURE, out); }