~ubuntu-branches/ubuntu/trusty/jsch/trusty-proposed

« back to all changes in this revision

Viewing changes to src/com/jcraft/jsch/IdentityFile.java

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2008-03-21 11:41:01 UTC
  • mfrom: (3.1.2 hardy)
  • Revision ID: james.westby@ubuntu.com-20080321114101-2g9w5l8ynwf6pbsq
Tags: 0.1.37-3
Add OSGi manifest patch. Thanks to Roberto Jimenoca. Closes: #471209.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
2
2
/*
3
 
Copyright (c) 2002,2003,2004,2005,2006 ymnk, JCraft,Inc. All rights reserved.
 
3
Copyright (c) 2002-2008 ymnk, JCraft,Inc. All rights reserved.
4
4
 
5
5
Redistribution and use in source and binary forms, with or without
6
6
modification, are permitted provided that the following conditions are met:
72
72
 
73
73
  private boolean encrypted=true;
74
74
 
75
 
  IdentityFile(String identity, JSch jsch) throws JSchException{
76
 
    this.identity=identity;
 
75
  static IdentityFile newInstance(String prvfile, String pubfile, JSch jsch) throws JSchException{
 
76
    byte[] prvkey=null;
 
77
    byte[] pubkey=null;
 
78
 
 
79
    File file=null;
 
80
    FileInputStream fis=null;
 
81
    try{
 
82
      file=new File(prvfile);
 
83
      fis=new FileInputStream(prvfile);
 
84
      prvkey=new byte[(int)(file.length())];
 
85
      int len=0;
 
86
      while(true){
 
87
        int i=fis.read(prvkey, len, prvkey.length-len);
 
88
        if(i<=0)
 
89
          break;
 
90
        len+=i;
 
91
      }
 
92
      fis.close();
 
93
    }
 
94
    catch(Exception e){
 
95
      try{ if(fis!=null) fis.close();}
 
96
      catch(Exception ee){}
 
97
      if(e instanceof Throwable)
 
98
        throw new JSchException(e.toString(), (Throwable)e);
 
99
      throw new JSchException(e.toString());
 
100
    }
 
101
 
 
102
    String _pubfile=pubfile;
 
103
    if(pubfile==null){
 
104
      _pubfile=prvfile+".pub";
 
105
    }
 
106
 
 
107
    try{
 
108
      file=new File(_pubfile);
 
109
      fis = new FileInputStream(_pubfile);
 
110
      pubkey=new byte[(int)(file.length())];
 
111
      int len=0;
 
112
      while(true){
 
113
        int i=fis.read(pubkey, len, pubkey.length-len);
 
114
        if(i<=0)
 
115
          break;
 
116
        len+=i;
 
117
      }
 
118
      fis.close();
 
119
    }
 
120
    catch(Exception e){
 
121
      try{ if(fis!=null) fis.close();}
 
122
      catch(Exception ee){}
 
123
      if(pubfile!=null){  
 
124
        // The pubfile is explicitry given, but not accessible.
 
125
        if(e instanceof Throwable)
 
126
          throw new JSchException(e.toString(), (Throwable)e);
 
127
        throw new JSchException(e.toString());
 
128
      }
 
129
    }
 
130
    return newInstance(prvfile, prvkey, pubkey, jsch);
 
131
  }
 
132
 
 
133
  static IdentityFile newInstance(String name, byte[] prvkey, byte[] pubkey, JSch jsch) throws JSchException{
 
134
    try{
 
135
      return new IdentityFile(name, prvkey, pubkey, jsch);
 
136
    }
 
137
    finally{
 
138
      Util.bzero(prvkey);
 
139
    }
 
140
  }
 
141
 
 
142
  private IdentityFile(String name, byte[] prvkey, byte[] pubkey, JSch jsch) throws JSchException{
 
143
    this.identity=name;
77
144
    this.jsch=jsch;
78
145
    try{
79
146
      Class c;
84
151
      c=Class.forName((String)jsch.getConfig("md5"));
85
152
      hash=(HASH)(c.newInstance());
86
153
      hash.init();
87
 
      File file=new File(identity);
88
 
      FileInputStream fis = new FileInputStream(identity);
89
 
      byte[] buf=new byte[(int)(file.length())];
90
 
      int len=fis.read(buf, 0, buf.length);
91
 
      fis.close();
 
154
 
 
155
      byte[] buf=prvkey;
 
156
      int len=buf.length;
92
157
 
93
158
      int i=0;
94
159
      while(i<len){
101
166
            keytype=FSECURE;
102
167
          }
103
168
          else{
104
 
            //System.out.println("invalid format: "+identity);
105
 
            throw new JSchException("invaid privatekey: "+identity);
 
169
            //System.err.println("invalid format: "+identity);
 
170
            throw new JSchException("invalid privatekey: "+identity);
106
171
          }
107
172
          i+=3;
108
173
          continue;
142
207
      }
143
208
 
144
209
      if(type==ERROR){
145
 
        throw new JSchException("invaid privatekey: "+identity);
 
210
        throw new JSchException("invalid privatekey: "+identity);
146
211
      }
147
212
 
148
213
      int start=i;
173
238
        _buf.getInt();  // 0x3f6ff9be
174
239
        _buf.getInt();
175
240
        byte[]_type=_buf.getString();
176
 
        //System.out.println("type: "+new String(_type)); 
 
241
        //System.err.println("type: "+new String(_type)); 
177
242
        byte[] _cipher=_buf.getString();
178
243
        String cipher=new String(_cipher);
179
 
        //System.out.println("cipher: "+cipher); 
 
244
        //System.err.println("cipher: "+cipher); 
180
245
        if(cipher.equals("3des-cbc")){
181
246
           _buf.getInt();
182
247
           byte[] foo=new byte[encoded_data.length-_buf.getOffSet()];
198
263
 
199
264
      }
200
265
 
201
 
      try{
202
 
        file=new File(identity+".pub");
203
 
        fis=new FileInputStream(identity+".pub");
204
 
        buf=new byte[(int)(file.length())];
205
 
        len=fis.read(buf, 0, buf.length);
206
 
        fis.close();
207
 
      }
208
 
      catch(Exception ee){
209
 
        return;
210
 
      }
 
266
      if(pubkey==null){
 
267
        return;
 
268
      }
 
269
      
 
270
      buf=pubkey;
 
271
      len=buf.length;
211
272
 
212
273
      if(buf.length>4 &&             // FSecure's public key
213
274
         buf[0]=='-' && buf[1]=='-' && buf[2]=='-' && buf[3]=='-'){
214
 
 
215
275
        i=0;
216
 
        do{i++;}while(buf.length>i && buf[i]!=0x0a);
217
 
        if(buf.length<=i) return;
218
 
 
219
 
        while(true){
 
276
        do{i++;}while(len>i && buf[i]!=0x0a);
 
277
        if(len<=i) return;
 
278
        while(i<len){
220
279
          if(buf[i]==0x0a){
221
280
            boolean inheader=false;
222
 
            for(int j=i+1; j<buf.length; j++){
 
281
            for(int j=i+1; j<len; j++){
223
282
              if(buf[j]==0x0a) break;
224
283
              if(buf[j]==':'){inheader=true; break;}
225
284
            }
230
289
          }
231
290
          i++;
232
291
        }
233
 
        if(buf.length<=i) return;
 
292
        if(len<=i) return;
234
293
 
235
294
        start=i;
236
295
        while(i<len){
244
303
        }
245
304
        publickeyblob=Util.fromBase64(buf, start, i-start);
246
305
 
247
 
        if(type==UNKNOWN){
 
306
        if(type==UNKNOWN && publickeyblob.length>8){
248
307
          if(publickeyblob[8]=='d'){
249
308
            type=DSS;
250
309
          }
259
318
        while(i<len){ if(buf[i]==' ')break; i++;} i++;
260
319
        if(i>=len) return;
261
320
        start=i;
262
 
        while(i<len){ if(buf[i]==' ')break; i++;}
 
321
        while(i<len){ if(buf[i]==' ' || buf[i]=='\n')break; i++;}
263
322
        publickeyblob=Util.fromBase64(buf, start, i-start);
 
323
        if(publickeyblob.length<4+7){  // It must start with "ssh-XXX".
 
324
          if(JSch.getLogger().isEnabled(Logger.WARN)){
 
325
            JSch.getLogger().log(Logger.WARN, 
 
326
                                 "failed to parse the public key");
 
327
          }
 
328
          publickeyblob=null;
 
329
        }
264
330
      }
265
 
 
266
331
    }
267
332
    catch(Exception e){
268
 
      System.out.println("Identity: "+e);
 
333
      //System.err.println("IdentityFile: "+e);
269
334
      if(e instanceof JSchException) throw (JSchException)e;
 
335
      if(e instanceof Throwable)
 
336
        throw new JSchException(e.toString(), (Throwable)e);
270
337
      throw new JSchException(e.toString());
271
338
    }
272
 
 
273
339
  }
274
340
 
275
341
  public String getAlgName(){
277
343
    return "ssh-dss"; 
278
344
  }
279
345
 
280
 
  public boolean setPassphrase(String _passphrase) throws JSchException{
 
346
  public boolean setPassphrase(byte[] _passphrase) throws JSchException{
281
347
    /*
282
348
      hash is MD5
283
349
      h(0) <- hash(passphrase, iv);
287
353
    try{
288
354
      if(encrypted){
289
355
        if(_passphrase==null) return false;
290
 
        byte[] passphrase=_passphrase.getBytes();
 
356
        byte[] passphrase=_passphrase;
291
357
        int hsize=hash.getBlockSize();
292
358
        byte[] hn=new byte[key.length/hsize*hsize+
293
359
                           (key.length%hsize==0?0:hsize)];
313
379
          }
314
380
          System.arraycopy(hn, 0, key, 0, key.length); 
315
381
        }
316
 
        if(passphrase!=null){
317
 
          for(int i=0; i<passphrase.length; i++){
318
 
            passphrase[i]=0;
319
 
          }
320
 
          passphrase=null;
321
 
        }
 
382
        Util.bzero(passphrase);
322
383
      }
323
384
      if(decrypt()){
324
385
        encrypted=false;
329
390
    }
330
391
    catch(Exception e){
331
392
      if(e instanceof JSchException) throw (JSchException)e;
 
393
      if(e instanceof Throwable)
 
394
        throw new JSchException(e.toString(), (Throwable)e);
332
395
      throw new JSchException(e.toString());
333
396
    }
334
397
  }
378
441
      rsa.init();
379
442
      rsa.setPrvKey(d_array, n_array);
380
443
 
381
 
      /*
382
 
      byte[] goo=new byte[4];
383
 
      goo[0]=(byte)(session.getSessionId().length>>>24);
384
 
      goo[1]=(byte)(session.getSessionId().length>>>16);
385
 
      goo[2]=(byte)(session.getSessionId().length>>>8);
386
 
      goo[3]=(byte)(session.getSessionId().length);
387
 
      rsa.update(goo);
388
 
      rsa.update(session.getSessionId());
389
 
      */
390
444
      rsa.update(data);
391
445
      byte[] sig = rsa.sign();
392
446
      Buffer buf=new Buffer("ssh-rsa".length()+4+
404
458
/*
405
459
    byte[] foo;
406
460
    int i;
407
 
    System.out.print("P ");
 
461
    System.err.print("P ");
408
462
    foo=P_array;
409
463
    for(i=0;  i<foo.length; i++){
410
 
      System.out.print(Integer.toHexString(foo[i]&0xff)+":");
 
464
      System.err.print(Integer.toHexString(foo[i]&0xff)+":");
411
465
    }
412
 
    System.out.println("");
413
 
    System.out.print("Q ");
 
466
    System.err.println("");
 
467
    System.err.print("Q ");
414
468
    foo=Q_array;
415
469
    for(i=0;  i<foo.length; i++){
416
 
      System.out.print(Integer.toHexString(foo[i]&0xff)+":");
 
470
      System.err.print(Integer.toHexString(foo[i]&0xff)+":");
417
471
    }
418
 
    System.out.println("");
419
 
    System.out.print("G ");
 
472
    System.err.println("");
 
473
    System.err.print("G ");
420
474
    foo=G_array;
421
475
    for(i=0;  i<foo.length; i++){
422
 
      System.out.print(Integer.toHexString(foo[i]&0xff)+":");
 
476
      System.err.print(Integer.toHexString(foo[i]&0xff)+":");
423
477
    }
424
 
    System.out.println("");
 
478
    System.err.println("");
425
479
*/
426
480
 
427
481
    try{      
430
484
      dsa.init();
431
485
      dsa.setPrvKey(prv_array, P_array, Q_array, G_array);
432
486
 
433
 
      /*
434
 
      byte[] goo=new byte[4];
435
 
      goo[0]=(byte)(session.getSessionId().length>>>24);
436
 
      goo[1]=(byte)(session.getSessionId().length>>>16);
437
 
      goo[2]=(byte)(session.getSessionId().length>>>8);
438
 
      goo[3]=(byte)(session.getSessionId().length);
439
 
      dsa.update(goo);
440
 
      dsa.update(session.getSessionId());
441
 
      */
442
 
 
443
487
      dsa.update(data);
444
488
      byte[] sig = dsa.sign();
445
489
      Buffer buf=new Buffer("ssh-dss".length()+4+
449
493
      return buf.buffer;
450
494
    }
451
495
    catch(Exception e){
452
 
      //System.out.println("e "+e);
 
496
      //System.err.println("e "+e);
453
497
    }
454
498
    return null;
455
499
  }
524
568
      }
525
569
      index+=length;
526
570
 
527
 
//System.out.println("int: len="+length);
528
 
//System.out.print(Integer.toHexString(plain[index-1]&0xff)+":");
529
 
//System.out.println("");
 
571
//System.err.println("int: len="+length);
 
572
//System.err.print(Integer.toHexString(plain[index-1]&0xff)+":");
 
573
//System.err.println("");
530
574
 
531
575
      index++;
532
576
      length=plain[index++]&0xff;
538
582
      System.arraycopy(plain, index, n_array, 0, length);
539
583
      index+=length;
540
584
/*
541
 
System.out.println("int: N len="+length);
 
585
System.err.println("int: N len="+length);
542
586
for(int i=0; i<n_array.length; i++){
543
 
System.out.print(Integer.toHexString(n_array[i]&0xff)+":");
 
587
System.err.print(Integer.toHexString(n_array[i]&0xff)+":");
544
588
}
545
 
System.out.println("");
 
589
System.err.println("");
546
590
*/
547
591
      index++;
548
592
      length=plain[index++]&0xff;
554
598
      System.arraycopy(plain, index, e_array, 0, length);
555
599
      index+=length;
556
600
/*
557
 
System.out.println("int: E len="+length);
 
601
System.err.println("int: E len="+length);
558
602
for(int i=0; i<e_array.length; i++){
559
 
System.out.print(Integer.toHexString(e_array[i]&0xff)+":");
 
603
System.err.print(Integer.toHexString(e_array[i]&0xff)+":");
560
604
}
561
 
System.out.println("");
 
605
System.err.println("");
562
606
*/
563
607
      index++;
564
608
      length=plain[index++]&0xff;
570
614
      System.arraycopy(plain, index, d_array, 0, length);
571
615
      index+=length;
572
616
/*
573
 
System.out.println("int: D len="+length);
 
617
System.err.println("int: D len="+length);
574
618
for(int i=0; i<d_array.length; i++){
575
 
System.out.print(Integer.toHexString(d_array[i]&0xff)+":");
 
619
System.err.print(Integer.toHexString(d_array[i]&0xff)+":");
576
620
}
577
 
System.out.println("");
 
621
System.err.println("");
578
622
*/
579
623
 
580
624
      index++;
587
631
      System.arraycopy(plain, index, p_array, 0, length);
588
632
      index+=length;
589
633
/*
590
 
System.out.println("int: P len="+length);
 
634
System.err.println("int: P len="+length);
591
635
for(int i=0; i<p_array.length; i++){
592
 
System.out.print(Integer.toHexString(p_array[i]&0xff)+":");
 
636
System.err.print(Integer.toHexString(p_array[i]&0xff)+":");
593
637
}
594
 
System.out.println("");
 
638
System.err.println("");
595
639
*/
596
640
      index++;
597
641
      length=plain[index++]&0xff;
603
647
      System.arraycopy(plain, index, q_array, 0, length);
604
648
      index+=length;
605
649
/*
606
 
System.out.println("int: q len="+length);
 
650
System.err.println("int: q len="+length);
607
651
for(int i=0; i<q_array.length; i++){
608
 
System.out.print(Integer.toHexString(q_array[i]&0xff)+":");
 
652
System.err.print(Integer.toHexString(q_array[i]&0xff)+":");
609
653
}
610
 
System.out.println("");
 
654
System.err.println("");
611
655
*/
612
656
      index++;
613
657
      length=plain[index++]&0xff;
619
663
      System.arraycopy(plain, index, dmp1_array, 0, length);
620
664
      index+=length;
621
665
/*
622
 
System.out.println("int: dmp1 len="+length);
 
666
System.err.println("int: dmp1 len="+length);
623
667
for(int i=0; i<dmp1_array.length; i++){
624
 
System.out.print(Integer.toHexString(dmp1_array[i]&0xff)+":");
 
668
System.err.print(Integer.toHexString(dmp1_array[i]&0xff)+":");
625
669
}
626
 
System.out.println("");
 
670
System.err.println("");
627
671
*/
628
672
      index++;
629
673
      length=plain[index++]&0xff;
635
679
      System.arraycopy(plain, index, dmq1_array, 0, length);
636
680
      index+=length;
637
681
/*
638
 
System.out.println("int: dmq1 len="+length);
 
682
System.err.println("int: dmq1 len="+length);
639
683
for(int i=0; i<dmq1_array.length; i++){
640
 
System.out.print(Integer.toHexString(dmq1_array[i]&0xff)+":");
 
684
System.err.print(Integer.toHexString(dmq1_array[i]&0xff)+":");
641
685
}
642
 
System.out.println("");
 
686
System.err.println("");
643
687
*/
644
688
      index++;
645
689
      length=plain[index++]&0xff;
651
695
      System.arraycopy(plain, index, iqmp_array, 0, length);
652
696
      index+=length;
653
697
/*
654
 
System.out.println("int: iqmp len="+length);
 
698
System.err.println("int: iqmp len="+length);
655
699
for(int i=0; i<iqmp_array.length; i++){
656
 
System.out.print(Integer.toHexString(iqmp_array[i]&0xff)+":");
 
700
System.err.print(Integer.toHexString(iqmp_array[i]&0xff)+":");
657
701
}
658
 
System.out.println("");
 
702
System.err.println("");
659
703
*/
660
704
    }
661
705
    catch(Exception e){
662
 
      //System.out.println(e);
 
706
      //System.err.println(e);
663
707
      return false;
664
708
    }
665
709
    return true;
675
719
          cipher.update(encoded_data, 0, encoded_data.length, plain, 0);
676
720
/*
677
721
for(int i=0; i<plain.length; i++){
678
 
System.out.print(Integer.toHexString(plain[i]&0xff)+":");
 
722
System.err.print(Integer.toHexString(plain[i]&0xff)+":");
679
723
}
680
 
System.out.println("");
 
724
System.err.println("");
681
725
*/
682
726
        }
683
727
        else if(keytype==FSECURE){
778
822
      index+=length;
779
823
    }
780
824
    catch(Exception e){
781
 
      //System.out.println(e);
 
825
      //System.err.println(e);
782
826
      //e.printStackTrace();
783
827
      return false;
784
828
    }
788
832
  public boolean isEncrypted(){
789
833
    return encrypted;
790
834
  }
791
 
  public String getName(){return identity;}
792
 
 
793
 
  private int writeSEQUENCE(byte[] buf, int index, int len){
794
 
    buf[index++]=0x30;
795
 
    index=writeLength(buf, index, len);
796
 
    return index;
797
 
  }
798
 
  private int writeINTEGER(byte[] buf, int index, byte[] data){
799
 
    buf[index++]=0x02;
800
 
    index=writeLength(buf, index, data.length);
801
 
    System.arraycopy(data, 0, buf, index, data.length);
802
 
    index+=data.length;
803
 
    return index;
804
 
  }
805
 
 
806
 
  private int countLength(int len){
807
 
    int i=1;
808
 
    if(len<=0x7f) return i;
809
 
    while(len>0){
810
 
      len>>>=8;
811
 
      i++;
812
 
    }
813
 
    return i;
814
 
  }
815
 
 
816
 
  private int writeLength(byte[] data, int index, int len){
817
 
    int i=countLength(len)-1;
818
 
    if(i==0){
819
 
      data[index++]=(byte)len;
820
 
      return index;
821
 
    }
822
 
    data[index++]=(byte)(0x80|i);
823
 
    int j=index+i;
824
 
    while(i>0){
825
 
      data[index+i-1]=(byte)(len&0xff);
826
 
      len>>>=8;
827
 
      i--;
828
 
    }
829
 
    return j;
 
835
 
 
836
  public String getName(){
 
837
    return identity;
830
838
  }
831
839
 
832
840
  private byte a2b(byte c){
834
842
    if('a'<=c&&c<='z') return (byte)(c-'a'+10);
835
843
    return (byte)(c-'A'+10);
836
844
  }
837
 
  private byte b2a(byte c){
838
 
    if(0<=c&&c<=9) return (byte)(c+'0');
839
 
    return (byte)(c-10+'A');
 
845
 
 
846
  public boolean equals(Object o){
 
847
    if(!(o instanceof IdentityFile)) return super.equals(o);
 
848
    IdentityFile foo=(IdentityFile)o;
 
849
    return getName().equals(foo.getName());
 
850
  }
 
851
 
 
852
  public void clear(){
 
853
    Util.bzero(encoded_data);
 
854
    Util.bzero(prv_array);
 
855
    Util.bzero(d_array);
 
856
    Util.bzero(key);
 
857
    Util.bzero(iv);
 
858
  }
 
859
 
 
860
  public void finalize (){
 
861
    clear();
840
862
  }
841
863
}