From f8fffe5e29f55856b93b5e21f1a672bb1a0fec40 Mon Sep 17 00:00:00 2001 From: hsm Date: Sun, 29 May 2016 04:17:53 +0100 Subject: Add support for auth with open-keychain --- .../java/com/trilead/ssh2/crypto/PEMDecoder.java | 59 ++++++++++++++++++++++ .../java/com/trilead/ssh2/crypto/PEMStructure.java | 3 +- 2 files changed, 61 insertions(+), 1 deletion(-) (limited to 'sshlib/src/main/java/com/trilead/ssh2/crypto') diff --git a/sshlib/src/main/java/com/trilead/ssh2/crypto/PEMDecoder.java b/sshlib/src/main/java/com/trilead/ssh2/crypto/PEMDecoder.java index 5c0c2fd..09b875e 100644 --- a/sshlib/src/main/java/com/trilead/ssh2/crypto/PEMDecoder.java +++ b/sshlib/src/main/java/com/trilead/ssh2/crypto/PEMDecoder.java @@ -30,6 +30,7 @@ import com.trilead.ssh2.crypto.cipher.CBCMode; import com.trilead.ssh2.crypto.cipher.DES; import com.trilead.ssh2.crypto.cipher.DESede; import com.trilead.ssh2.signature.ECDSASHA2Verify; +import com.trilead.ssh2.signature.TokenRSAPrivateKey; /** * PEM Support. @@ -42,6 +43,7 @@ public class PEMDecoder public static final int PEM_RSA_PRIVATE_KEY = 1; public static final int PEM_DSA_PRIVATE_KEY = 2; public static final int PEM_EC_PRIVATE_KEY = 3; + public static final int PEM_RSA_TOKEN_PRIVATE_KEY = 4; private static final int hexToInt(char c) { @@ -186,6 +188,12 @@ public class PEMDecoder ps.pemType = PEM_EC_PRIVATE_KEY; break; } + + if (line.startsWith("-----BEGIN RSA PUBLIC KEY-----")) { + endLine = "-----END RSA PUBLIC KEY-----"; + ps.pemType = PEM_RSA_TOKEN_PRIVATE_KEY; + break; + } } while (true) @@ -224,6 +232,12 @@ public class PEMDecoder ps.dekInfo = values; continue; } + + if ("Private-Key-ID:".equals(name)) + { + ps.private_key_id = values; + continue; + } /* Ignore line */ } @@ -468,9 +482,54 @@ public class PEMDecoder return generateKeyPair("EC", privSpec, pubSpec); } + if (ps.pemType == PEM_RSA_TOKEN_PRIVATE_KEY) + { + + if (ps.private_key_id == null) { + throw new IOException("No Private-Key-ID: line in stream."); + } + if (ps.private_key_id.length != 1) { + throw new IOException("No Private-Key-ID: line in stream."); + } + + SimpleDERReader dr = new SimpleDERReader(ps.data); + + byte[] seq = dr.readSequenceAsByteArray(); + + if (dr.available() != 0) + throw new IOException("Padding in RSA PUBLIC KEY DER stream."); + + dr.resetInput(seq); + + BigInteger n = dr.readInt(); + BigInteger e = dr.readInt(); + + RSAPublicKeySpec pubSpec = new RSAPublicKeySpec(n, e); + + return generateTokenKeyPair("RSA", new TokenRSAPrivateKey(ps.private_key_id[0]), pubSpec); + } + throw new IOException("PEM problem: it is of unknown type"); } + + private static KeyPair generateTokenKeyPair(String algorithm, PrivateKey priv_key, KeySpec pubSpec) + throws IOException { + try { + final KeyFactory kf = KeyFactory.getInstance(algorithm); + final PublicKey pubKey = kf.generatePublic(pubSpec); + final PrivateKey privKey = priv_key; + return new KeyPair(pubKey, privKey); + } catch (NoSuchAlgorithmException ex) { + IOException ioex = new IOException(); + ioex.initCause(ex); + throw ioex; + } catch (InvalidKeySpecException ex) { + IOException ioex = new IOException("invalid keyspec"); + ioex.initCause(ex); + throw ioex; + } + } /** * Generate a {@code KeyPair} given an {@code algorithm} and {@code KeySpec}. */ diff --git a/sshlib/src/main/java/com/trilead/ssh2/crypto/PEMStructure.java b/sshlib/src/main/java/com/trilead/ssh2/crypto/PEMStructure.java index 83fb799..0aeb2eb 100644 --- a/sshlib/src/main/java/com/trilead/ssh2/crypto/PEMStructure.java +++ b/sshlib/src/main/java/com/trilead/ssh2/crypto/PEMStructure.java @@ -12,6 +12,7 @@ public class PEMStructure { public int pemType; String dekInfo[]; + String private_key_id[]; String procType[]; public byte[] data; -} \ No newline at end of file +} -- cgit v1.2.3