aboutsummaryrefslogtreecommitdiffstats
path: root/sshlib/src/main/java/com/trilead/ssh2/crypto/PEMDecoder.java
diff options
context:
space:
mode:
Diffstat (limited to 'sshlib/src/main/java/com/trilead/ssh2/crypto/PEMDecoder.java')
-rw-r--r--sshlib/src/main/java/com/trilead/ssh2/crypto/PEMDecoder.java59
1 files changed, 59 insertions, 0 deletions
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}.
*/