45
45
46
46
/**
47
47
* <h2>Sample PuTTY file format</h2>
48
+ *
48
49
* <pre>
49
50
* PuTTY-User-Key-File-2: ssh-rsa
50
51
* Encryption: none
70
71
*/
71
72
public class PuTTYKeyFile extends BaseFileKeyProvider {
72
73
73
- public static class Factory
74
- implements net .schmizz .sshj .common .Factory .Named <FileKeyProvider > {
74
+ public static class Factory implements net .schmizz .sshj .common .Factory .Named <FileKeyProvider > {
75
75
76
76
@ Override
77
77
public FileKeyProvider create () {
@@ -88,33 +88,35 @@ public String getName() {
88
88
private byte [] publicKey ;
89
89
90
90
/**
91
- * Key type. Either "ssh-rsa" for RSA key, or "ssh-dss" for DSA key.
91
+ * Key type
92
92
*/
93
93
@ Override
94
94
public KeyType getType () throws IOException {
95
- return KeyType .fromString (headers .get ("PuTTY-User-Key-File-2" ));
95
+ for (String h : headers .keySet ()) {
96
+ if (h .startsWith ("PuTTY-User-Key-File-" )) {
97
+ return KeyType .fromString (headers .get (h ));
98
+ }
99
+ }
100
+ return KeyType .UNKNOWN ;
96
101
}
97
102
98
103
public boolean isEncrypted () {
99
104
// Currently the only supported encryption types are "aes256-cbc" and "none".
100
105
return "aes256-cbc" .equals (headers .get ("Encryption" ));
101
106
}
102
107
103
- private Map <String , String > payload
104
- = new HashMap <String , String >();
108
+ private Map <String , String > payload = new HashMap <String , String >();
105
109
106
110
/**
107
111
* For each line that looks like "Xyz: vvv", it will be stored in this map.
108
112
*/
109
- private final Map <String , String > headers
110
- = new HashMap <String , String >();
111
-
113
+ private final Map <String , String > headers = new HashMap <String , String >();
112
114
113
115
protected KeyPair readKeyPair () throws IOException {
114
116
this .parseKeyPair ();
115
117
final Buffer .PlainBuffer publicKeyReader = new Buffer .PlainBuffer (publicKey );
116
118
final Buffer .PlainBuffer privateKeyReader = new Buffer .PlainBuffer (privateKey );
117
- publicKeyReader .readBytes (); // The first part of the payload is a human-readable key format name.
119
+ publicKeyReader .readBytes (); // The first part of the payload is a human-readable key format name.
118
120
if (KeyType .RSA .equals (this .getType ())) {
119
121
// public key exponent
120
122
BigInteger e = publicKeyReader .readMPInt ();
@@ -131,10 +133,8 @@ protected KeyPair readKeyPair() throws IOException {
131
133
throw new IOException (s .getMessage (), s );
132
134
}
133
135
try {
134
- return new KeyPair (
135
- factory .generatePublic (new RSAPublicKeySpec (n , e )),
136
- factory .generatePrivate (new RSAPrivateKeySpec (n , d ))
137
- );
136
+ return new KeyPair (factory .generatePublic (new RSAPublicKeySpec (n , e )),
137
+ factory .generatePrivate (new RSAPrivateKeySpec (n , d )));
138
138
} catch (InvalidKeySpecException i ) {
139
139
throw new IOException (i .getMessage (), i );
140
140
}
@@ -155,10 +155,8 @@ protected KeyPair readKeyPair() throws IOException {
155
155
throw new IOException (s .getMessage (), s );
156
156
}
157
157
try {
158
- return new KeyPair (
159
- factory .generatePublic (new DSAPublicKeySpec (y , p , q , g )),
160
- factory .generatePrivate (new DSAPrivateKeySpec (x , p , q , g ))
161
- );
158
+ return new KeyPair (factory .generatePublic (new DSAPublicKeySpec (y , p , q , g )),
159
+ factory .generatePrivate (new DSAPrivateKeySpec (x , p , q , g )));
162
160
} catch (InvalidKeySpecException e ) {
163
161
throw new IOException (e .getMessage (), e );
164
162
}
@@ -187,8 +185,8 @@ protected KeyPair readKeyPair() throws IOException {
187
185
if (ecdsaCurve != null ) {
188
186
BigInteger s = new BigInteger (1 , privateKeyReader .readBytes ());
189
187
X9ECParameters ecParams = NISTNamedCurves .getByName (ecdsaCurve );
190
- ECNamedCurveSpec ecCurveSpec =
191
- new ECNamedCurveSpec ( ecdsaCurve , ecParams . getCurve (), ecParams . getG (), ecParams .getN ());
188
+ ECNamedCurveSpec ecCurveSpec = new ECNamedCurveSpec ( ecdsaCurve , ecParams . getCurve (), ecParams . getG (),
189
+ ecParams .getN ());
192
190
ECPrivateKeySpec pks = new ECPrivateKeySpec (s , ecCurveSpec );
193
191
try {
194
192
PrivateKey privateKey = SecurityUtils .getKeyFactory (KeyAlgorithm .ECDSA ).generatePrivate (pks );
@@ -247,7 +245,8 @@ protected void parseKeyPair() throws IOException {
247
245
}
248
246
249
247
/**
250
- * Converts a passphrase into a key, by following the convention that PuTTY uses.
248
+ * Converts a passphrase into a key, by following the convention that PuTTY
249
+ * uses.
251
250
* <p/>
252
251
* <p/>
253
252
* This is used to decrypt the private key when it's encrypted.
@@ -256,15 +255,16 @@ private byte[] toKey(final String passphrase) throws IOException {
256
255
try {
257
256
MessageDigest digest = MessageDigest .getInstance ("SHA-1" );
258
257
259
- // The encryption key is derived from the passphrase by means of a succession of SHA-1 hashes.
258
+ // The encryption key is derived from the passphrase by means of a succession of
259
+ // SHA-1 hashes.
260
260
261
261
// Sequence number 0
262
- digest .update (new byte []{ 0 , 0 , 0 , 0 });
262
+ digest .update (new byte [] { 0 , 0 , 0 , 0 });
263
263
digest .update (passphrase .getBytes ());
264
264
byte [] key1 = digest .digest ();
265
265
266
266
// Sequence number 1
267
- digest .update (new byte []{ 0 , 0 , 0 , 1 });
267
+ digest .update (new byte [] { 0 , 0 , 0 , 1 });
268
268
digest .update (passphrase .getBytes ());
269
269
byte [] key2 = digest .digest ();
270
270
0 commit comments