~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to contrib/NSch/NSch/KeyPair.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 2006-2010 ymnk, JCraft,Inc. All rights reserved.
 
3
 
 
4
Redistribution and use in source and binary forms, with or without
 
5
modification, are permitted provided that the following conditions are met:
 
6
 
 
7
  1. Redistributions of source code must retain the above copyright notice,
 
8
     this list of conditions and the following disclaimer.
 
9
 
 
10
  2. Redistributions in binary form must reproduce the above copyright 
 
11
     notice, this list of conditions and the following disclaimer in 
 
12
     the documentation and/or other materials provided with the distribution.
 
13
 
 
14
  3. The names of the authors may not be used to endorse or promote products
 
15
     derived from this software without specific prior written permission.
 
16
 
 
17
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 
18
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 
19
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
 
20
INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
 
21
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
22
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 
23
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 
24
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 
25
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 
26
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 
 
28
This code is based on jsch (http://www.jcraft.com/jsch).
 
29
All credit should go to the authors of jsch.
 
30
*/
 
31
 
 
32
using System;
 
33
using NSch;
 
34
using Sharpen;
 
35
 
 
36
namespace NSch
 
37
{
 
38
        public abstract class KeyPair
 
39
        {
 
40
                public const int ERROR = 0;
 
41
 
 
42
                public const int DSA = 1;
 
43
 
 
44
                public const int RSA = 2;
 
45
 
 
46
                public const int UNKNOWN = 3;
 
47
 
 
48
                internal const int VENDOR_OPENSSH = 0;
 
49
 
 
50
                internal const int VENDOR_FSECURE = 1;
 
51
 
 
52
                internal int vendor = VENDOR_OPENSSH;
 
53
 
 
54
                private static readonly byte[] cr = Util.Str2byte("\n");
 
55
 
 
56
                /// <exception cref="NSch.JSchException"></exception>
 
57
                public static NSch.KeyPair GenKeyPair(JSch jsch, int type)
 
58
                {
 
59
                        return GenKeyPair(jsch, type, 1024);
 
60
                }
 
61
 
 
62
                /// <exception cref="NSch.JSchException"></exception>
 
63
                public static NSch.KeyPair GenKeyPair(JSch jsch, int type, int key_size)
 
64
                {
 
65
                        NSch.KeyPair kpair = null;
 
66
                        if (type == DSA)
 
67
                        {
 
68
                                kpair = new KeyPairDSA(jsch);
 
69
                        }
 
70
                        else
 
71
                        {
 
72
                                if (type == RSA)
 
73
                                {
 
74
                                        kpair = new KeyPairRSA(jsch);
 
75
                                }
 
76
                        }
 
77
                        if (kpair != null)
 
78
                        {
 
79
                                kpair.Generate(key_size);
 
80
                        }
 
81
                        return kpair;
 
82
                }
 
83
 
 
84
                /// <exception cref="NSch.JSchException"></exception>
 
85
                internal abstract void Generate(int key_size);
 
86
 
 
87
                internal abstract byte[] GetBegin();
 
88
 
 
89
                internal abstract byte[] GetEnd();
 
90
 
 
91
                internal abstract int GetKeySize();
 
92
 
 
93
                internal JSch jsch = null;
 
94
 
 
95
                private NSch.Cipher cipher;
 
96
 
 
97
                private HASH hash;
 
98
 
 
99
                private Random random;
 
100
 
 
101
                private byte[] passphrase;
 
102
 
 
103
                public KeyPair(JSch jsch)
 
104
                {
 
105
                        this.jsch = jsch;
 
106
                }
 
107
 
 
108
                internal static byte[][] header = new byte[][] { Util.Str2byte("Proc-Type: 4,ENCRYPTED"
 
109
                        ), Util.Str2byte("DEK-Info: DES-EDE3-CBC,") };
 
110
 
 
111
                internal abstract byte[] GetPrivateKey();
 
112
 
 
113
                public virtual void WritePrivateKey(OutputStream @out)
 
114
                {
 
115
                        byte[] plain = GetPrivateKey();
 
116
                        byte[][] _iv = new byte[1][];
 
117
                        byte[] encoded = Encrypt(plain, _iv);
 
118
                        if (encoded != plain)
 
119
                        {
 
120
                                Util.Bzero(plain);
 
121
                        }
 
122
                        byte[] iv = _iv[0];
 
123
                        byte[] prv = Util.ToBase64(encoded, 0, encoded.Length);
 
124
                        try
 
125
                        {
 
126
                                @out.Write(GetBegin());
 
127
                                @out.Write(cr);
 
128
                                if (passphrase != null)
 
129
                                {
 
130
                                        @out.Write(header[0]);
 
131
                                        @out.Write(cr);
 
132
                                        @out.Write(header[1]);
 
133
                                        for (int i = 0; i < iv.Length; i++)
 
134
                                        {
 
135
                                                @out.Write(B2a(unchecked((byte)((iv[i] >> 4) & unchecked((int)(0x0f))))));
 
136
                                                @out.Write(B2a(unchecked((byte)(iv[i] & unchecked((int)(0x0f))))));
 
137
                                        }
 
138
                                        @out.Write(cr);
 
139
                                        @out.Write(cr);
 
140
                                }
 
141
                                int i_1 = 0;
 
142
                                while (i_1 < prv.Length)
 
143
                                {
 
144
                                        if (i_1 + 64 < prv.Length)
 
145
                                        {
 
146
                                                @out.Write(prv, i_1, 64);
 
147
                                                @out.Write(cr);
 
148
                                                i_1 += 64;
 
149
                                                continue;
 
150
                                        }
 
151
                                        @out.Write(prv, i_1, prv.Length - i_1);
 
152
                                        @out.Write(cr);
 
153
                                        break;
 
154
                                }
 
155
                                @out.Write(GetEnd());
 
156
                                @out.Write(cr);
 
157
                        }
 
158
                        catch (Exception)
 
159
                        {
 
160
                        }
 
161
                }
 
162
 
 
163
                private static byte[] space = Util.Str2byte(" ");
 
164
 
 
165
                //out.close();
 
166
                internal abstract byte[] GetKeyTypeName();
 
167
 
 
168
                public abstract int GetKeyType();
 
169
 
 
170
                public virtual byte[] GetPublicKeyBlob()
 
171
                {
 
172
                        return publickeyblob;
 
173
                }
 
174
 
 
175
                public virtual void WritePublicKey(OutputStream @out, string comment)
 
176
                {
 
177
                        byte[] pubblob = GetPublicKeyBlob();
 
178
                        byte[] pub = Util.ToBase64(pubblob, 0, pubblob.Length);
 
179
                        try
 
180
                        {
 
181
                                @out.Write(GetKeyTypeName());
 
182
                                @out.Write(space);
 
183
                                @out.Write(pub, 0, pub.Length);
 
184
                                @out.Write(space);
 
185
                                @out.Write(Util.Str2byte(comment));
 
186
                                @out.Write(cr);
 
187
                        }
 
188
                        catch (Exception)
 
189
                        {
 
190
                        }
 
191
                }
 
192
 
 
193
                /// <exception cref="System.IO.FileNotFoundException"></exception>
 
194
                /// <exception cref="System.IO.IOException"></exception>
 
195
                public virtual void WritePublicKey(string name, string comment)
 
196
                {
 
197
                        FileOutputStream fos = new FileOutputStream(name);
 
198
                        WritePublicKey(fos, comment);
 
199
                        fos.Close();
 
200
                }
 
201
 
 
202
                public virtual void WriteSECSHPublicKey(OutputStream @out, string comment)
 
203
                {
 
204
                        byte[] pubblob = GetPublicKeyBlob();
 
205
                        byte[] pub = Util.ToBase64(pubblob, 0, pubblob.Length);
 
206
                        try
 
207
                        {
 
208
                                @out.Write(Util.Str2byte("---- BEGIN SSH2 PUBLIC KEY ----"));
 
209
                                @out.Write(cr);
 
210
                                @out.Write(Util.Str2byte("Comment: \"" + comment + "\""));
 
211
                                @out.Write(cr);
 
212
                                int index = 0;
 
213
                                while (index < pub.Length)
 
214
                                {
 
215
                                        int len = 70;
 
216
                                        if ((pub.Length - index) < len)
 
217
                                        {
 
218
                                                len = pub.Length - index;
 
219
                                        }
 
220
                                        @out.Write(pub, index, len);
 
221
                                        @out.Write(cr);
 
222
                                        index += len;
 
223
                                }
 
224
                                @out.Write(Util.Str2byte("---- END SSH2 PUBLIC KEY ----"));
 
225
                                @out.Write(cr);
 
226
                        }
 
227
                        catch (Exception)
 
228
                        {
 
229
                        }
 
230
                }
 
231
 
 
232
                /// <exception cref="System.IO.FileNotFoundException"></exception>
 
233
                /// <exception cref="System.IO.IOException"></exception>
 
234
                public virtual void WriteSECSHPublicKey(string name, string comment)
 
235
                {
 
236
                        FileOutputStream fos = new FileOutputStream(name);
 
237
                        WriteSECSHPublicKey(fos, comment);
 
238
                        fos.Close();
 
239
                }
 
240
 
 
241
                /// <exception cref="System.IO.FileNotFoundException"></exception>
 
242
                /// <exception cref="System.IO.IOException"></exception>
 
243
                public virtual void WritePrivateKey(string name)
 
244
                {
 
245
                        FileOutputStream fos = new FileOutputStream(name);
 
246
                        WritePrivateKey(fos);
 
247
                        fos.Close();
 
248
                }
 
249
 
 
250
                public virtual string GetFingerPrint()
 
251
                {
 
252
                        if (hash == null)
 
253
                        {
 
254
                                hash = GenHash();
 
255
                        }
 
256
                        byte[] kblob = GetPublicKeyBlob();
 
257
                        if (kblob == null)
 
258
                        {
 
259
                                return null;
 
260
                        }
 
261
                        return GetKeySize() + " " + Util.GetFingerPrint(hash, kblob);
 
262
                }
 
263
 
 
264
                private byte[] Encrypt(byte[] plain, byte[][] _iv)
 
265
                {
 
266
                        if (passphrase == null)
 
267
                        {
 
268
                                return plain;
 
269
                        }
 
270
                        if (cipher == null)
 
271
                        {
 
272
                                cipher = GenCipher();
 
273
                        }
 
274
                        byte[] iv = _iv[0] = new byte[cipher.GetIVSize()];
 
275
                        if (random == null)
 
276
                        {
 
277
                                random = GenRandom();
 
278
                        }
 
279
                        random.Fill(iv, 0, iv.Length);
 
280
                        byte[] key = GenKey(passphrase, iv);
 
281
                        byte[] encoded = plain;
 
282
                        {
 
283
                                // PKCS#5Padding
 
284
                                //int bsize=cipher.getBlockSize();
 
285
                                int bsize = cipher.GetIVSize();
 
286
                                byte[] foo = new byte[(encoded.Length / bsize + 1) * bsize];
 
287
                                System.Array.Copy(encoded, 0, foo, 0, encoded.Length);
 
288
                                int padding = bsize - encoded.Length % bsize;
 
289
                                for (int i = foo.Length - 1; (foo.Length - padding) <= i; i--)
 
290
                                {
 
291
                                        foo[i] = unchecked((byte)padding);
 
292
                                }
 
293
                                encoded = foo;
 
294
                        }
 
295
                        try
 
296
                        {
 
297
                                cipher.Init(NSch.Cipher.ENCRYPT_MODE, key, iv);
 
298
                                cipher.Update(encoded, 0, encoded.Length, encoded, 0);
 
299
                        }
 
300
                        catch (Exception)
 
301
                        {
 
302
                        }
 
303
                        //System.err.println(e);
 
304
                        Util.Bzero(key);
 
305
                        return encoded;
 
306
                }
 
307
 
 
308
                internal abstract bool Parse(byte[] data);
 
309
 
 
310
                private byte[] Decrypt(byte[] data, byte[] passphrase, byte[] iv)
 
311
                {
 
312
                        try
 
313
                        {
 
314
                                byte[] key = GenKey(passphrase, iv);
 
315
                                cipher.Init(NSch.Cipher.DECRYPT_MODE, key, iv);
 
316
                                Util.Bzero(key);
 
317
                                byte[] plain = new byte[data.Length];
 
318
                                cipher.Update(data, 0, data.Length, plain, 0);
 
319
                                return plain;
 
320
                        }
 
321
                        catch (Exception)
 
322
                        {
 
323
                        }
 
324
                        //System.err.println(e);
 
325
                        return null;
 
326
                }
 
327
 
 
328
                internal virtual int WriteSEQUENCE(byte[] buf, int index, int len)
 
329
                {
 
330
                        buf[index++] = unchecked((int)(0x30));
 
331
                        index = WriteLength(buf, index, len);
 
332
                        return index;
 
333
                }
 
334
 
 
335
                internal virtual int WriteINTEGER(byte[] buf, int index, byte[] data)
 
336
                {
 
337
                        buf[index++] = unchecked((int)(0x02));
 
338
                        index = WriteLength(buf, index, data.Length);
 
339
                        System.Array.Copy(data, 0, buf, index, data.Length);
 
340
                        index += data.Length;
 
341
                        return index;
 
342
                }
 
343
 
 
344
                internal virtual int CountLength(int len)
 
345
                {
 
346
                        int i = 1;
 
347
                        if (len <= unchecked((int)(0x7f)))
 
348
                        {
 
349
                                return i;
 
350
                        }
 
351
                        while (len > 0)
 
352
                        {
 
353
                                len = (int)(((uint)len) >> 8);
 
354
                                i++;
 
355
                        }
 
356
                        return i;
 
357
                }
 
358
 
 
359
                internal virtual int WriteLength(byte[] data, int index, int len)
 
360
                {
 
361
                        int i = CountLength(len) - 1;
 
362
                        if (i == 0)
 
363
                        {
 
364
                                data[index++] = unchecked((byte)len);
 
365
                                return index;
 
366
                        }
 
367
                        data[index++] = unchecked((byte)(unchecked((int)(0x80)) | i));
 
368
                        int j = index + i;
 
369
                        while (i > 0)
 
370
                        {
 
371
                                data[index + i - 1] = unchecked((byte)(len & unchecked((int)(0xff))));
 
372
                                len = (int)(((uint)len) >> 8);
 
373
                                i--;
 
374
                        }
 
375
                        return j;
 
376
                }
 
377
 
 
378
                private Random GenRandom()
 
379
                {
 
380
                        if (random == null)
 
381
                        {
 
382
                                try
 
383
                                {
 
384
                                        Type c = Sharpen.Runtime.GetType(JSch.GetConfig("random"));
 
385
                                        random = (Random)(System.Activator.CreateInstance(c));
 
386
                                }
 
387
                                catch (Exception e)
 
388
                                {
 
389
                                        System.Console.Error.WriteLine("connect: random " + e);
 
390
                                }
 
391
                        }
 
392
                        return random;
 
393
                }
 
394
 
 
395
                private HASH GenHash()
 
396
                {
 
397
                        try
 
398
                        {
 
399
                                Type c = Sharpen.Runtime.GetType(JSch.GetConfig("md5"));
 
400
                                hash = (HASH)(System.Activator.CreateInstance(c));
 
401
                                hash.Init();
 
402
                        }
 
403
                        catch (Exception)
 
404
                        {
 
405
                        }
 
406
                        return hash;
 
407
                }
 
408
 
 
409
                private NSch.Cipher GenCipher()
 
410
                {
 
411
                        try
 
412
                        {
 
413
                                Type c;
 
414
                                c = Sharpen.Runtime.GetType(JSch.GetConfig("3des-cbc"));
 
415
                                cipher = (NSch.Cipher)(System.Activator.CreateInstance(c));
 
416
                        }
 
417
                        catch (Exception)
 
418
                        {
 
419
                        }
 
420
                        return cipher;
 
421
                }
 
422
 
 
423
                internal virtual byte[] GenKey(byte[] passphrase, byte[] iv)
 
424
                {
 
425
                        lock (this)
 
426
                        {
 
427
                                if (cipher == null)
 
428
                                {
 
429
                                        cipher = GenCipher();
 
430
                                }
 
431
                                if (hash == null)
 
432
                                {
 
433
                                        hash = GenHash();
 
434
                                }
 
435
                                byte[] key = new byte[cipher.GetBlockSize()];
 
436
                                int hsize = hash.GetBlockSize();
 
437
                                byte[] hn = new byte[key.Length / hsize * hsize + (key.Length % hsize == 0 ? 0 : 
 
438
                                        hsize)];
 
439
                                try
 
440
                                {
 
441
                                        byte[] tmp = null;
 
442
                                        if (vendor == VENDOR_OPENSSH)
 
443
                                        {
 
444
                                                for (int index = 0; index + hsize <= hn.Length; )
 
445
                                                {
 
446
                                                        if (tmp != null)
 
447
                                                        {
 
448
                                                                hash.Update(tmp, 0, tmp.Length);
 
449
                                                        }
 
450
                                                        hash.Update(passphrase, 0, passphrase.Length);
 
451
                                                        hash.Update(iv, 0, iv.Length);
 
452
                                                        tmp = hash.Digest();
 
453
                                                        System.Array.Copy(tmp, 0, hn, index, tmp.Length);
 
454
                                                        index += tmp.Length;
 
455
                                                }
 
456
                                                System.Array.Copy(hn, 0, key, 0, key.Length);
 
457
                                        }
 
458
                                        else
 
459
                                        {
 
460
                                                if (vendor == VENDOR_FSECURE)
 
461
                                                {
 
462
                                                        for (int index = 0; index + hsize <= hn.Length; )
 
463
                                                        {
 
464
                                                                if (tmp != null)
 
465
                                                                {
 
466
                                                                        hash.Update(tmp, 0, tmp.Length);
 
467
                                                                }
 
468
                                                                hash.Update(passphrase, 0, passphrase.Length);
 
469
                                                                tmp = hash.Digest();
 
470
                                                                System.Array.Copy(tmp, 0, hn, index, tmp.Length);
 
471
                                                                index += tmp.Length;
 
472
                                                        }
 
473
                                                        System.Array.Copy(hn, 0, key, 0, key.Length);
 
474
                                                }
 
475
                                        }
 
476
                                }
 
477
                                catch (Exception e)
 
478
                                {
 
479
                                        System.Console.Error.WriteLine(e);
 
480
                                }
 
481
                                return key;
 
482
                        }
 
483
                }
 
484
 
 
485
                public virtual void SetPassphrase(string passphrase)
 
486
                {
 
487
                        if (passphrase == null || passphrase.Length == 0)
 
488
                        {
 
489
                                SetPassphrase((byte[])null);
 
490
                        }
 
491
                        else
 
492
                        {
 
493
                                SetPassphrase(Util.Str2byte(passphrase));
 
494
                        }
 
495
                }
 
496
 
 
497
                public virtual void SetPassphrase(byte[] passphrase)
 
498
                {
 
499
                        if (passphrase != null && passphrase.Length == 0)
 
500
                        {
 
501
                                passphrase = null;
 
502
                        }
 
503
                        this.passphrase = passphrase;
 
504
                }
 
505
 
 
506
                private bool encrypted = false;
 
507
 
 
508
                private byte[] data = null;
 
509
 
 
510
                private byte[] iv = null;
 
511
 
 
512
                private byte[] publickeyblob = null;
 
513
 
 
514
                public virtual bool IsEncrypted()
 
515
                {
 
516
                        return encrypted;
 
517
                }
 
518
 
 
519
                public virtual bool Decrypt(string _passphrase)
 
520
                {
 
521
                        if (_passphrase == null || _passphrase.Length == 0)
 
522
                        {
 
523
                                return !encrypted;
 
524
                        }
 
525
                        return Decrypt(Util.Str2byte(_passphrase));
 
526
                }
 
527
 
 
528
                public virtual bool Decrypt(byte[] _passphrase)
 
529
                {
 
530
                        if (!encrypted)
 
531
                        {
 
532
                                return true;
 
533
                        }
 
534
                        if (_passphrase == null)
 
535
                        {
 
536
                                return !encrypted;
 
537
                        }
 
538
                        byte[] bar = new byte[_passphrase.Length];
 
539
                        System.Array.Copy(_passphrase, 0, bar, 0, bar.Length);
 
540
                        _passphrase = bar;
 
541
                        byte[] foo = Decrypt(data, _passphrase, iv);
 
542
                        Util.Bzero(_passphrase);
 
543
                        if (Parse(foo))
 
544
                        {
 
545
                                encrypted = false;
 
546
                        }
 
547
                        return !encrypted;
 
548
                }
 
549
 
 
550
                /// <exception cref="NSch.JSchException"></exception>
 
551
                public static NSch.KeyPair Load(JSch jsch, string prvkey)
 
552
                {
 
553
                        string pubkey = prvkey + ".pub";
 
554
                        if (!new FilePath(pubkey).Exists())
 
555
                        {
 
556
                                pubkey = null;
 
557
                        }
 
558
                        return Load(jsch, prvkey, pubkey);
 
559
                }
 
560
 
 
561
                /// <exception cref="NSch.JSchException"></exception>
 
562
                public static NSch.KeyPair Load(JSch jsch, string prvkey, string pubkey)
 
563
                {
 
564
                        byte[] iv = new byte[8];
 
565
                        // 8
 
566
                        bool encrypted = true;
 
567
                        byte[] data = null;
 
568
                        byte[] publickeyblob = null;
 
569
                        int type = ERROR;
 
570
                        int vendor = VENDOR_OPENSSH;
 
571
                        try
 
572
                        {
 
573
                                FilePath file = new FilePath(prvkey);
 
574
                                FileInputStream fis = new FileInputStream(prvkey);
 
575
                                byte[] buf = new byte[(int)(file.Length())];
 
576
                                int len = 0;
 
577
                                while (true)
 
578
                                {
 
579
                                        int i = fis.Read(buf, len, buf.Length - len);
 
580
                                        if (i <= 0)
 
581
                                        {
 
582
                                                break;
 
583
                                        }
 
584
                                        len += i;
 
585
                                }
 
586
                                fis.Close();
 
587
                                int i_1 = 0;
 
588
                                while (i_1 < len)
 
589
                                {
 
590
                                        if (buf[i_1] == 'B' && buf[i_1 + 1] == 'E' && buf[i_1 + 2] == 'G' && buf[i_1 + 3]
 
591
                                                 == 'I')
 
592
                                        {
 
593
                                                i_1 += 6;
 
594
                                                if (buf[i_1] == 'D' && buf[i_1 + 1] == 'S' && buf[i_1 + 2] == 'A')
 
595
                                                {
 
596
                                                        type = DSA;
 
597
                                                }
 
598
                                                else
 
599
                                                {
 
600
                                                        if (buf[i_1] == 'R' && buf[i_1 + 1] == 'S' && buf[i_1 + 2] == 'A')
 
601
                                                        {
 
602
                                                                type = RSA;
 
603
                                                        }
 
604
                                                        else
 
605
                                                        {
 
606
                                                                if (buf[i_1] == 'S' && buf[i_1 + 1] == 'S' && buf[i_1 + 2] == 'H')
 
607
                                                                {
 
608
                                                                        // FSecure
 
609
                                                                        type = UNKNOWN;
 
610
                                                                        vendor = VENDOR_FSECURE;
 
611
                                                                }
 
612
                                                                else
 
613
                                                                {
 
614
                                                                        //System.err.println("invalid format: "+identity);
 
615
                                                                        throw new JSchException("invalid privatekey: " + prvkey);
 
616
                                                                }
 
617
                                                        }
 
618
                                                }
 
619
                                                i_1 += 3;
 
620
                                                continue;
 
621
                                        }
 
622
                                        if (buf[i_1] == 'C' && buf[i_1 + 1] == 'B' && buf[i_1 + 2] == 'C' && buf[i_1 + 3]
 
623
                                                 == ',')
 
624
                                        {
 
625
                                                i_1 += 4;
 
626
                                                for (int ii = 0; ii < iv.Length; ii++)
 
627
                                                {
 
628
                                                        iv[ii] = unchecked((byte)(((A2b(buf[i_1++]) << 4) & unchecked((int)(0xf0))) + (A2b
 
629
                                                                (buf[i_1++]) & unchecked((int)(0xf)))));
 
630
                                                }
 
631
                                                continue;
 
632
                                        }
 
633
                                        if (buf[i_1] == unchecked((int)(0x0d)) && i_1 + 1 < buf.Length && buf[i_1 + 1] ==
 
634
                                                 unchecked((int)(0x0a)))
 
635
                                        {
 
636
                                                i_1++;
 
637
                                                continue;
 
638
                                        }
 
639
                                        if (buf[i_1] == unchecked((int)(0x0a)) && i_1 + 1 < buf.Length)
 
640
                                        {
 
641
                                                if (buf[i_1 + 1] == unchecked((int)(0x0a)))
 
642
                                                {
 
643
                                                        i_1 += 2;
 
644
                                                        break;
 
645
                                                }
 
646
                                                if (buf[i_1 + 1] == unchecked((int)(0x0d)) && i_1 + 2 < buf.Length && buf[i_1 + 2
 
647
                                                        ] == unchecked((int)(0x0a)))
 
648
                                                {
 
649
                                                        i_1 += 3;
 
650
                                                        break;
 
651
                                                }
 
652
                                                bool inheader = false;
 
653
                                                for (int j = i_1 + 1; j < buf.Length; j++)
 
654
                                                {
 
655
                                                        if (buf[j] == unchecked((int)(0x0a)))
 
656
                                                        {
 
657
                                                                break;
 
658
                                                        }
 
659
                                                        //if(buf[j]==0x0d) break;
 
660
                                                        if (buf[j] == ':')
 
661
                                                        {
 
662
                                                                inheader = true;
 
663
                                                                break;
 
664
                                                        }
 
665
                                                }
 
666
                                                if (!inheader)
 
667
                                                {
 
668
                                                        i_1++;
 
669
                                                        encrypted = false;
 
670
                                                        // no passphrase
 
671
                                                        break;
 
672
                                                }
 
673
                                        }
 
674
                                        i_1++;
 
675
                                }
 
676
                                if (type == ERROR)
 
677
                                {
 
678
                                        throw new JSchException("invalid privatekey: " + prvkey);
 
679
                                }
 
680
                                int start = i_1;
 
681
                                while (i_1 < len)
 
682
                                {
 
683
                                        if (buf[i_1] == unchecked((int)(0x0a)))
 
684
                                        {
 
685
                                                bool xd = (buf[i_1 - 1] == unchecked((int)(0x0d)));
 
686
                                                System.Array.Copy(buf, i_1 + 1, buf, i_1 - (xd ? 1 : 0), len - i_1 - 1 - (xd ? 1 : 
 
687
                                                        0));
 
688
                                                if (xd)
 
689
                                                {
 
690
                                                        len--;
 
691
                                                }
 
692
                                                len--;
 
693
                                                continue;
 
694
                                        }
 
695
                                        if (buf[i_1] == '-')
 
696
                                        {
 
697
                                                break;
 
698
                                        }
 
699
                                        i_1++;
 
700
                                }
 
701
                                data = Util.FromBase64(buf, start, i_1 - start);
 
702
                                if (data.Length > 4 && data[0] == unchecked((byte)unchecked((int)(0x3f))) && data
 
703
                                        [1] == unchecked((byte)unchecked((int)(0x6f))) && data[2] == unchecked((byte)unchecked(
 
704
                                        (int)(0xf9))) && data[3] == unchecked((byte)unchecked((int)(0xeb))))
 
705
                                {
 
706
                                        // FSecure
 
707
                                        Buffer _buf = new Buffer(data);
 
708
                                        _buf.GetInt();
 
709
                                        // 0x3f6ff9be
 
710
                                        _buf.GetInt();
 
711
                                        byte[] _type = _buf.GetString();
 
712
                                        //System.err.println("type: "+new String(_type)); 
 
713
                                        byte[] _cipher = _buf.GetString();
 
714
                                        string cipher = Util.Byte2str(_cipher);
 
715
                                        //System.err.println("cipher: "+cipher); 
 
716
                                        if (cipher.Equals("3des-cbc"))
 
717
                                        {
 
718
                                                _buf.GetInt();
 
719
                                                byte[] foo = new byte[data.Length - _buf.GetOffSet()];
 
720
                                                _buf.GetByte(foo);
 
721
                                                data = foo;
 
722
                                                encrypted = true;
 
723
                                                throw new JSchException("unknown privatekey format: " + prvkey);
 
724
                                        }
 
725
                                        else
 
726
                                        {
 
727
                                                if (cipher.Equals("none"))
 
728
                                                {
 
729
                                                        _buf.GetInt();
 
730
                                                        _buf.GetInt();
 
731
                                                        encrypted = false;
 
732
                                                        byte[] foo = new byte[data.Length - _buf.GetOffSet()];
 
733
                                                        _buf.GetByte(foo);
 
734
                                                        data = foo;
 
735
                                                }
 
736
                                        }
 
737
                                }
 
738
                                if (pubkey != null)
 
739
                                {
 
740
                                        try
 
741
                                        {
 
742
                                                file = new FilePath(pubkey);
 
743
                                                fis = new FileInputStream(pubkey);
 
744
                                                buf = new byte[(int)(file.Length())];
 
745
                                                len = 0;
 
746
                                                while (true)
 
747
                                                {
 
748
                                                        i_1 = fis.Read(buf, len, buf.Length - len);
 
749
                                                        if (i_1 <= 0)
 
750
                                                        {
 
751
                                                                break;
 
752
                                                        }
 
753
                                                        len += i_1;
 
754
                                                }
 
755
                                                fis.Close();
 
756
                                                if (buf.Length > 4 && buf[0] == '-' && buf[1] == '-' && buf[2] == '-' && buf[3] ==
 
757
                                                         '-')
 
758
                                                {
 
759
                                                        // FSecure's public key
 
760
                                                        bool valid = true;
 
761
                                                        i_1 = 0;
 
762
                                                        do
 
763
                                                        {
 
764
                                                                i_1++;
 
765
                                                        }
 
766
                                                        while (buf.Length > i_1 && buf[i_1] != unchecked((int)(0x0a)));
 
767
                                                        if (buf.Length <= i_1)
 
768
                                                        {
 
769
                                                                valid = false;
 
770
                                                        }
 
771
                                                        while (valid)
 
772
                                                        {
 
773
                                                                if (buf[i_1] == unchecked((int)(0x0a)))
 
774
                                                                {
 
775
                                                                        bool inheader = false;
 
776
                                                                        for (int j = i_1 + 1; j < buf.Length; j++)
 
777
                                                                        {
 
778
                                                                                if (buf[j] == unchecked((int)(0x0a)))
 
779
                                                                                {
 
780
                                                                                        break;
 
781
                                                                                }
 
782
                                                                                if (buf[j] == ':')
 
783
                                                                                {
 
784
                                                                                        inheader = true;
 
785
                                                                                        break;
 
786
                                                                                }
 
787
                                                                        }
 
788
                                                                        if (!inheader)
 
789
                                                                        {
 
790
                                                                                i_1++;
 
791
                                                                                break;
 
792
                                                                        }
 
793
                                                                }
 
794
                                                                i_1++;
 
795
                                                        }
 
796
                                                        if (buf.Length <= i_1)
 
797
                                                        {
 
798
                                                                valid = false;
 
799
                                                        }
 
800
                                                        start = i_1;
 
801
                                                        while (valid && i_1 < len)
 
802
                                                        {
 
803
                                                                if (buf[i_1] == unchecked((int)(0x0a)))
 
804
                                                                {
 
805
                                                                        System.Array.Copy(buf, i_1 + 1, buf, i_1, len - i_1 - 1);
 
806
                                                                        len--;
 
807
                                                                        continue;
 
808
                                                                }
 
809
                                                                if (buf[i_1] == '-')
 
810
                                                                {
 
811
                                                                        break;
 
812
                                                                }
 
813
                                                                i_1++;
 
814
                                                        }
 
815
                                                        if (valid)
 
816
                                                        {
 
817
                                                                publickeyblob = Util.FromBase64(buf, start, i_1 - start);
 
818
                                                                if (type == UNKNOWN)
 
819
                                                                {
 
820
                                                                        if (publickeyblob[8] == 'd')
 
821
                                                                        {
 
822
                                                                                type = DSA;
 
823
                                                                        }
 
824
                                                                        else
 
825
                                                                        {
 
826
                                                                                if (publickeyblob[8] == 'r')
 
827
                                                                                {
 
828
                                                                                        type = RSA;
 
829
                                                                                }
 
830
                                                                        }
 
831
                                                                }
 
832
                                                        }
 
833
                                                }
 
834
                                                else
 
835
                                                {
 
836
                                                        if (buf[0] == 's' && buf[1] == 's' && buf[2] == 'h' && buf[3] == '-')
 
837
                                                        {
 
838
                                                                i_1 = 0;
 
839
                                                                while (i_1 < len)
 
840
                                                                {
 
841
                                                                        if (buf[i_1] == ' ')
 
842
                                                                        {
 
843
                                                                                break;
 
844
                                                                        }
 
845
                                                                        i_1++;
 
846
                                                                }
 
847
                                                                i_1++;
 
848
                                                                if (i_1 < len)
 
849
                                                                {
 
850
                                                                        start = i_1;
 
851
                                                                        while (i_1 < len)
 
852
                                                                        {
 
853
                                                                                if (buf[i_1] == ' ')
 
854
                                                                                {
 
855
                                                                                        break;
 
856
                                                                                }
 
857
                                                                                i_1++;
 
858
                                                                        }
 
859
                                                                        publickeyblob = Util.FromBase64(buf, start, i_1 - start);
 
860
                                                                }
 
861
                                                        }
 
862
                                                }
 
863
                                        }
 
864
                                        catch (Exception)
 
865
                                        {
 
866
                                        }
 
867
                                }
 
868
                        }
 
869
                        catch (Exception e)
 
870
                        {
 
871
                                if (e is JSchException)
 
872
                                {
 
873
                                        throw (JSchException)e;
 
874
                                }
 
875
                                if (e is Exception)
 
876
                                {
 
877
                                        throw new JSchException(e.ToString(), (Exception)e);
 
878
                                }
 
879
                                throw new JSchException(e.ToString());
 
880
                        }
 
881
                        NSch.KeyPair kpair = null;
 
882
                        if (type == DSA)
 
883
                        {
 
884
                                kpair = new KeyPairDSA(jsch);
 
885
                        }
 
886
                        else
 
887
                        {
 
888
                                if (type == RSA)
 
889
                                {
 
890
                                        kpair = new KeyPairRSA(jsch);
 
891
                                }
 
892
                        }
 
893
                        if (kpair != null)
 
894
                        {
 
895
                                kpair.encrypted = encrypted;
 
896
                                kpair.publickeyblob = publickeyblob;
 
897
                                kpair.vendor = vendor;
 
898
                                if (encrypted)
 
899
                                {
 
900
                                        kpair.iv = iv;
 
901
                                        kpair.data = data;
 
902
                                }
 
903
                                else
 
904
                                {
 
905
                                        if (kpair.Parse(data))
 
906
                                        {
 
907
                                                return kpair;
 
908
                                        }
 
909
                                        else
 
910
                                        {
 
911
                                                throw new JSchException("invalid privatekey: " + prvkey);
 
912
                                        }
 
913
                                }
 
914
                        }
 
915
                        return kpair;
 
916
                }
 
917
 
 
918
                private static byte A2b(byte c)
 
919
                {
 
920
                        if ('0' <= c && ((sbyte)c) <= '9')
 
921
                        {
 
922
                                return unchecked((byte)(c - '0'));
 
923
                        }
 
924
                        return unchecked((byte)(c - 'a' + 10));
 
925
                }
 
926
 
 
927
                private static byte B2a(byte c)
 
928
                {
 
929
                        if (0 <= c && ((sbyte)c) <= 9)
 
930
                        {
 
931
                                return unchecked((byte)(c + '0'));
 
932
                        }
 
933
                        return unchecked((byte)(c - 10 + 'A'));
 
934
                }
 
935
 
 
936
                public virtual void Dispose()
 
937
                {
 
938
                        Util.Bzero(passphrase);
 
939
                }
 
940
 
 
941
                ~KeyPair()
 
942
                {
 
943
                        Dispose();
 
944
                }
 
945
        }
 
946
}