KeyPair.java

Go to the documentation of this file.
00001 /* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
00002 /*
00003 Copyright (c) 2002-2011 ymnk, JCraft,Inc. All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions are met:
00007 
00008   1. Redistributions of source code must retain the above copyright notice,
00009      this list of conditions and the following disclaimer.
00010 
00011   2. Redistributions in binary form must reproduce the above copyright 
00012      notice, this list of conditions and the following disclaimer in 
00013      the documentation and/or other materials provided with the distribution.
00014 
00015   3. The names of the authors may not be used to endorse or promote products
00016      derived from this software without specific prior written permission.
00017 
00018 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
00019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
00020 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
00021 INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
00022 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00023 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00025 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00026 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
00027 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00028 */
00029 
00030 package com.jcraft.jsch;
00031 
00032 import java.io.FileOutputStream;
00033 import java.io.FileInputStream;
00034 import java.io.File;
00035 
00051 public abstract class KeyPair{
00056   public static final int ERROR=0;
00060   public static final int DSA=1;
00064   public static final int RSA=2;
00069   public static final int UNKNOWN=3;
00070 
00071   static final int VENDOR_OPENSSH=0;
00072   static final int VENDOR_FSECURE=1;
00073   int vendor=VENDOR_OPENSSH;
00074 
00075   private static final byte[] cr=Util.str2byte("\n");
00076 
00084   public static KeyPair genKeyPair(JSch jsch, int type) throws JSchException{
00085     return genKeyPair(jsch, type, 1024);
00086   }
00087 
00096   public static KeyPair genKeyPair(JSch jsch, int type, int key_size) throws JSchException{
00097     KeyPair kpair=null;
00098     if(type==DSA){ kpair=new KeyPairDSA(jsch); }
00099     else if(type==RSA){ kpair=new KeyPairRSA(jsch); }
00100     if(kpair!=null){
00101       kpair.generate(key_size);
00102     }
00103     return kpair;
00104   }
00105 
00106   abstract void generate(int key_size) throws JSchException;
00107 
00108   abstract byte[] getBegin();
00109   abstract byte[] getEnd();
00110   abstract int getKeySize();
00111 
00112   public String getPublicKeyComment(){
00113     return publicKeyComment;
00114   }
00115   private String publicKeyComment = "";
00116 
00117   JSch jsch=null;
00118   private Cipher cipher;
00119   private HASH hash;
00120   private Random random;
00121 
00122   private byte[] passphrase;
00123 
00134   public KeyPair(JSch jsch){
00135     this.jsch=jsch;
00136   }
00137 
00138   static byte[][] header={Util.str2byte("Proc-Type: 4,ENCRYPTED"),
00139                           Util.str2byte("DEK-Info: DES-EDE3-CBC,")};
00140 
00141   abstract byte[] getPrivateKey();
00142 
00147   // TODO: describe the format.
00148   public void writePrivateKey(java.io.OutputStream out){
00149     byte[] plain=getPrivateKey();
00150     byte[][] _iv=new byte[1][];
00151     byte[] encoded=encrypt(plain, _iv);
00152     if(encoded!=plain)
00153       Util.bzero(plain);
00154     byte[] iv=_iv[0];
00155     byte[] prv=Util.toBase64(encoded, 0, encoded.length);
00156 
00157     try{
00158       out.write(getBegin()); out.write(cr);
00159       if(passphrase!=null){
00160     out.write(header[0]); out.write(cr);
00161     out.write(header[1]); 
00162     for(int i=0; i<iv.length; i++){
00163       out.write(b2a((byte)((iv[i]>>>4)&0x0f)));
00164       out.write(b2a((byte)(iv[i]&0x0f)));
00165     }
00166         out.write(cr);
00167     out.write(cr);
00168       }
00169       int i=0;
00170       while(i<prv.length){
00171     if(i+64<prv.length){
00172       out.write(prv, i, 64);
00173       out.write(cr);
00174       i+=64;
00175       continue;
00176     }
00177     out.write(prv, i, prv.length-i);
00178     out.write(cr);
00179     break;
00180       }
00181       out.write(getEnd()); out.write(cr);
00182       //out.close();
00183     }
00184     catch(Exception e){
00185     }
00186   }
00187 
00188   private static byte[] space=Util.str2byte(" ");
00189 
00190   abstract byte[] getKeyTypeName();
00191 
00196   public abstract int getKeyType();
00197 
00201   public byte[] getPublicKeyBlob(){ return publickeyblob; }
00202 
00209   public void writePublicKey(java.io.OutputStream out, String comment){
00210     byte[] pubblob=getPublicKeyBlob();
00211     byte[] pub=Util.toBase64(pubblob, 0, pubblob.length);
00212     try{
00213       out.write(getKeyTypeName()); out.write(space);
00214       out.write(pub, 0, pub.length); out.write(space);
00215       out.write(Util.str2byte(comment));
00216       out.write(cr);
00217     }
00218     catch(Exception e){
00219     }
00220   }
00221 
00228   public void writePublicKey(String name, String comment) throws java.io.FileNotFoundException, java.io.IOException{
00229     FileOutputStream fos=new FileOutputStream(name);
00230     writePublicKey(fos, comment);
00231     fos.close();
00232   }
00233 
00242   public void writeSECSHPublicKey(java.io.OutputStream out, String comment){
00243     byte[] pubblob=getPublicKeyBlob();
00244     byte[] pub=Util.toBase64(pubblob, 0, pubblob.length);
00245     try{
00246       out.write(Util.str2byte("---- BEGIN SSH2 PUBLIC KEY ----")); out.write(cr);
00247       out.write(Util.str2byte("Comment: \""+comment+"\"")); out.write(cr);
00248       int index=0;
00249       while(index<pub.length){
00250     int len=70;
00251     if((pub.length-index)<len)len=pub.length-index;
00252     out.write(pub, index, len); out.write(cr);
00253     index+=len;
00254       }
00255       out.write(Util.str2byte("---- END SSH2 PUBLIC KEY ----")); out.write(cr);
00256     }
00257     catch(Exception e){
00258     }
00259   }
00260 
00269   public void writeSECSHPublicKey(String name, String comment) throws java.io.FileNotFoundException, java.io.IOException{
00270     FileOutputStream fos=new FileOutputStream(name);
00271     writeSECSHPublicKey(fos, comment);
00272     fos.close();
00273   }
00274 
00275 
00280   public void writePrivateKey(String name) throws java.io.FileNotFoundException, java.io.IOException{
00281     FileOutputStream fos=new FileOutputStream(name);
00282     writePrivateKey(fos);
00283     fos.close();
00284   }
00285 
00286 
00292   public String getFingerPrint(){
00293     if(hash==null) hash=genHash();
00294     byte[] kblob=getPublicKeyBlob();
00295     if(kblob==null) return null;
00296     return getKeySize()+" "+Util.getFingerPrint(hash, kblob);
00297   }
00298 
00299   private byte[] encrypt(byte[] plain, byte[][] _iv){
00300     if(passphrase==null) return plain;
00301 
00302     if(cipher==null) cipher=genCipher();
00303     byte[] iv=_iv[0]=new byte[cipher.getIVSize()];
00304 
00305     if(random==null) random=genRandom();
00306     random.fill(iv, 0, iv.length);
00307 
00308     byte[] key=genKey(passphrase, iv);
00309     byte[] encoded=plain;
00310 
00311     // PKCS#5Padding
00312     {
00313       //int bsize=cipher.getBlockSize();
00314       int bsize=cipher.getIVSize();
00315       byte[] foo=new byte[(encoded.length/bsize+1)*bsize];
00316       System.arraycopy(encoded, 0, foo, 0, encoded.length);
00317       int padding=bsize-encoded.length%bsize;
00318       for(int i=foo.length-1; (foo.length-padding)<=i; i--){
00319         foo[i]=(byte)padding;
00320       }
00321       encoded=foo;
00322     }
00323 
00324     try{
00325       cipher.init(Cipher.ENCRYPT_MODE, key, iv);
00326       cipher.update(encoded, 0, encoded.length, encoded, 0);
00327     }
00328     catch(Exception e){
00329       //System.err.println(e);
00330     }
00331     Util.bzero(key);
00332     return encoded;
00333   }
00334 
00335   abstract boolean parse(byte[] data);
00336 
00337   private byte[] decrypt(byte[] data, byte[] passphrase, byte[] iv){
00338     /*
00339     if(iv==null){  // FSecure
00340       iv=new byte[8];
00341       for(int i=0; i<iv.length; i++)iv[i]=0;
00342     }
00343     */
00344     try{
00345       byte[] key=genKey(passphrase, iv);
00346       cipher.init(Cipher.DECRYPT_MODE, key, iv);
00347       Util.bzero(key);
00348       byte[] plain=new byte[data.length];
00349       cipher.update(data, 0, data.length, plain, 0);
00350       return plain;
00351     }
00352     catch(Exception e){
00353       //System.err.println(e);
00354     }
00355     return null;
00356   }
00357 
00358   int writeSEQUENCE(byte[] buf, int index, int len){
00359     buf[index++]=0x30;
00360     index=writeLength(buf, index, len);
00361     return index;
00362   }
00363   int writeINTEGER(byte[] buf, int index, byte[] data){
00364     buf[index++]=0x02;
00365     index=writeLength(buf, index, data.length);
00366     System.arraycopy(data, 0, buf, index, data.length);
00367     index+=data.length;
00368     return index;
00369   }
00370 
00371   int countLength(int len){
00372     int i=1;
00373     if(len<=0x7f) return i;
00374     while(len>0){
00375       len>>>=8;
00376       i++;
00377     }
00378     return i;
00379   }
00380 
00381   int writeLength(byte[] data, int index, int len){
00382     int i=countLength(len)-1;
00383     if(i==0){
00384       data[index++]=(byte)len;
00385       return index;
00386     }
00387     data[index++]=(byte)(0x80|i);
00388     int j=index+i;
00389     while(i>0){
00390       data[index+i-1]=(byte)(len&0xff);
00391       len>>>=8;
00392       i--;
00393     }
00394     return j;
00395   }
00396 
00397   private Random genRandom(){
00398     if(random==null){
00399       try{
00400     Class c=Class.forName(jsch.getConfig("random"));
00401         random=(Random)(c.newInstance());
00402       }
00403       catch(Exception e){ System.err.println("connect: random "+e); }
00404     }
00405     return random;
00406   }
00407 
00408   private HASH genHash(){
00409     try{
00410       Class c=Class.forName(jsch.getConfig("md5"));
00411       hash=(HASH)(c.newInstance());
00412       hash.init();
00413     }
00414     catch(Exception e){
00415     }
00416     return hash;
00417   }
00418   private Cipher genCipher(){
00419     try{
00420       Class c;
00421       c=Class.forName(jsch.getConfig("3des-cbc"));
00422       cipher=(Cipher)(c.newInstance());
00423     }
00424     catch(Exception e){
00425     }
00426     return cipher;
00427   }
00428 
00429   /*
00430     hash is MD5
00431     h(0) <- hash(passphrase, iv);
00432     h(n) <- hash(h(n-1), passphrase, iv);
00433     key <- (h(0),...,h(n))[0,..,key.length];
00434   */
00435   synchronized byte[] genKey(byte[] passphrase, byte[] iv){
00436     if(cipher==null) cipher=genCipher();
00437     if(hash==null) hash=genHash();
00438 
00439     byte[] key=new byte[cipher.getBlockSize()];
00440     int hsize=hash.getBlockSize();
00441     byte[] hn=new byte[key.length/hsize*hsize+
00442                (key.length%hsize==0?0:hsize)];
00443     try{
00444       byte[] tmp=null;
00445       if(vendor==VENDOR_OPENSSH){
00446     for(int index=0; index+hsize<=hn.length;){
00447       if(tmp!=null){ hash.update(tmp, 0, tmp.length); }
00448       hash.update(passphrase, 0, passphrase.length);
00449           hash.update(iv, 0, iv.length > 8 ? 8: iv.length);
00450       tmp=hash.digest();
00451       System.arraycopy(tmp, 0, hn, index, tmp.length);
00452       index+=tmp.length;
00453     }
00454     System.arraycopy(hn, 0, key, 0, key.length); 
00455       }
00456       else if(vendor==VENDOR_FSECURE){
00457     for(int index=0; index+hsize<=hn.length;){
00458       if(tmp!=null){ hash.update(tmp, 0, tmp.length); }
00459       hash.update(passphrase, 0, passphrase.length);
00460       tmp=hash.digest();
00461       System.arraycopy(tmp, 0, hn, index, tmp.length);
00462       index+=tmp.length;
00463     }
00464     System.arraycopy(hn, 0, key, 0, key.length); 
00465       }
00466     }
00467     catch(Exception e){
00468       System.err.println(e);
00469     }
00470     return key;
00471   } 
00472 
00473 
00479   public void setPassphrase(String passphrase){
00480     if(passphrase==null || passphrase.length()==0){
00481       setPassphrase((byte[])null);
00482     }
00483     else{
00484       setPassphrase(Util.str2byte(passphrase));
00485     }
00486   }
00492   public void setPassphrase(byte[] passphrase){
00493     if(passphrase!=null && passphrase.length==0) 
00494       passphrase=null;
00495     this.passphrase=passphrase;
00496   }
00497 
00498   private boolean encrypted=false;
00499   private byte[] data=null;
00500   private byte[] iv=null;
00501   private byte[] publickeyblob=null;
00502 
00508   public boolean isEncrypted(){ return encrypted; }
00509 
00515   public boolean decrypt(String _passphrase){
00516     if(_passphrase==null || _passphrase.length()==0){
00517       return !encrypted;
00518     }
00519     return decrypt(Util.str2byte(_passphrase));
00520   }
00526   public boolean decrypt(byte[] _passphrase){
00527     if(!encrypted){
00528       return true;
00529     }
00530     if(_passphrase==null){
00531       return !encrypted;
00532     }
00533     byte[] bar=new byte[_passphrase.length];
00534     System.arraycopy(_passphrase, 0, bar, 0, bar.length);
00535     _passphrase=bar;
00536     byte[] foo=decrypt(data, _passphrase, iv);
00537     Util.bzero(_passphrase);
00538     if(parse(foo)){
00539       encrypted=false;
00540     }
00541     return !encrypted;
00542   }
00543 
00552   public static KeyPair load(JSch jsch, String prvkey) throws JSchException{
00553     String pubkey=prvkey+".pub";
00554     if(!new File(pubkey).exists()){
00555       pubkey=null;
00556     }
00557     return load(jsch, prvkey, pubkey);
00558   }
00559 
00567   public static KeyPair load(JSch jsch, String prvkey, String pubkey) throws JSchException{
00568 
00569     byte[] iv=new byte[8];       // 8
00570     boolean encrypted=true;
00571     byte[] data=null;
00572 
00573     byte[] publickeyblob=null;
00574 
00575     int type=ERROR;
00576     int vendor=VENDOR_OPENSSH;
00577     String publicKeyComment = "";
00578     Cipher cipher=null;
00579 
00580     try{
00581       File file=new File(prvkey);
00582       FileInputStream fis=new FileInputStream(prvkey);
00583       byte[] buf=new byte[(int)(file.length())];
00584       int len=0;
00585       while(true){
00586         int i=fis.read(buf, len, buf.length-len);
00587         if(i<=0)
00588           break;
00589         len+=i;
00590       }
00591       fis.close();
00592 
00593       int i=0;
00594 
00595       while(i<len){
00596         if(buf[i] == '-' && i+4<len && 
00597            buf[i+1] == '-' && buf[i+2] == '-' && 
00598            buf[i+3] == '-' && buf[i+4] == '-'){
00599           break;
00600         }
00601         i++;
00602       }
00603 
00604       while(i<len){
00605         if(buf[i]=='B'&& i+3<len && buf[i+1]=='E'&& buf[i+2]=='G'&& buf[i+3]=='I'){
00606           i+=6;     
00607           if(buf[i]=='D'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=DSA; }
00608       else if(buf[i]=='R'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=RSA; }
00609       else if(buf[i]=='S'&& buf[i+1]=='S'&& buf[i+2]=='H'){ // FSecure
00610         type=UNKNOWN;
00611         vendor=VENDOR_FSECURE;
00612       }
00613       else{
00614         throw new JSchException("invalid privatekey: "+prvkey);
00615       }
00616           i+=3;
00617       continue;
00618     }
00619         if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' && 
00620            buf[i+4]=='2'&& buf[i+5]=='5'&& buf[i+6]=='6'&& buf[i+7]=='-'){
00621           i+=8;
00622           if(Session.checkCipher((String)jsch.getConfig("aes256-cbc"))){
00623             Class c=Class.forName((String)jsch.getConfig("aes256-cbc"));
00624             cipher=(Cipher)(c.newInstance());
00625             // key=new byte[cipher.getBlockSize()];
00626             iv=new byte[cipher.getIVSize()];
00627           }
00628           else{
00629             throw new JSchException("privatekey: aes256-cbc is not available "+prvkey);
00630           }
00631           continue;
00632         }
00633         if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' && 
00634            buf[i+4]=='1'&& buf[i+5]=='9'&& buf[i+6]=='2'&& buf[i+7]=='-'){
00635           i+=8;
00636           if(Session.checkCipher((String)jsch.getConfig("aes192-cbc"))){
00637             Class c=Class.forName((String)jsch.getConfig("aes192-cbc"));
00638             cipher=(Cipher)(c.newInstance());
00639             // key=new byte[cipher.getBlockSize()];
00640             iv=new byte[cipher.getIVSize()];
00641           }
00642           else{
00643             throw new JSchException("privatekey: aes192-cbc is not available "+prvkey);
00644           }
00645           continue;
00646         }
00647         if(buf[i]=='A'&& i+7<len && buf[i+1]=='E'&& buf[i+2]=='S'&& buf[i+3]=='-' && 
00648            buf[i+4]=='1'&& buf[i+5]=='2'&& buf[i+6]=='8'&& buf[i+7]=='-'){
00649           i+=8;
00650           if(Session.checkCipher((String)jsch.getConfig("aes128-cbc"))){
00651             Class c=Class.forName((String)jsch.getConfig("aes128-cbc"));
00652             cipher=(Cipher)(c.newInstance());
00653             // key=new byte[cipher.getBlockSize()];
00654             iv=new byte[cipher.getIVSize()];
00655           }
00656           else{
00657             throw new JSchException("privatekey: aes128-cbc is not available "+prvkey);
00658           }
00659           continue;
00660         }
00661         if(buf[i]=='C'&& i+3<len && buf[i+1]=='B'&& buf[i+2]=='C'&& buf[i+3]==','){
00662           i+=4;
00663       for(int ii=0; ii<iv.length; ii++){
00664             iv[ii]=(byte)(((a2b(buf[i++])<<4)&0xf0)+(a2b(buf[i++])&0xf));
00665       }
00666       continue;
00667     }
00668     if(buf[i]==0x0d && i+1<buf.length && buf[i+1]==0x0a){
00669       i++;
00670       continue;
00671     }
00672     if(buf[i]==0x0a && i+1<buf.length){
00673       if(buf[i+1]==0x0a){ i+=2; break; }
00674       if(buf[i+1]==0x0d &&
00675          i+2<buf.length && buf[i+2]==0x0a){
00676          i+=3; break;
00677       }
00678       boolean inheader=false;
00679       for(int j=i+1; j<buf.length; j++){
00680         if(buf[j]==0x0a) break;
00681         //if(buf[j]==0x0d) break;
00682         if(buf[j]==':'){inheader=true; break;}
00683       }
00684       if(!inheader){
00685         i++; 
00686         encrypted=false;    // no passphrase
00687         break;
00688       }
00689     }
00690     i++;
00691       }
00692 
00693       if(type==ERROR){
00694     throw new JSchException("invalid privatekey: "+prvkey);
00695       }
00696 
00697       int start=i;
00698       while(i<len){
00699         if(buf[i]==0x0a){
00700       boolean xd=(buf[i-1]==0x0d);
00701           System.arraycopy(buf, i+1, 
00702                buf, 
00703                i-(xd ? 1 : 0), 
00704                len-i-1-(xd ? 1 : 0)
00705                );
00706       if(xd)len--;
00707           len--;
00708           continue;
00709         }
00710         if(buf[i]=='-'){  break; }
00711         i++;
00712       }
00713       data=Util.fromBase64(buf, start, i-start);
00714 
00715       if(data.length>4 &&            // FSecure
00716      data[0]==(byte)0x3f &&
00717      data[1]==(byte)0x6f &&
00718      data[2]==(byte)0xf9 &&
00719      data[3]==(byte)0xeb){
00720 
00721     Buffer _buf=new Buffer(data);
00722     _buf.getInt();  // 0x3f6ff9be
00723     _buf.getInt();
00724     byte[]_type=_buf.getString();
00725     //System.err.println("type: "+new String(_type)); 
00726     String _cipher=Util.byte2str(_buf.getString());
00727     //System.err.println("cipher: "+_cipher); 
00728     if(_cipher.equals("3des-cbc")){
00729        _buf.getInt();
00730        byte[] foo=new byte[data.length-_buf.getOffSet()];
00731        _buf.getByte(foo);
00732        data=foo;
00733        encrypted=true;
00734        throw new JSchException("unknown privatekey format: "+prvkey);
00735     }
00736     else if(_cipher.equals("none")){
00737        _buf.getInt();
00738        _buf.getInt();
00739 
00740            encrypted=false;
00741 
00742        byte[] foo=new byte[data.length-_buf.getOffSet()];
00743        _buf.getByte(foo);
00744        data=foo;
00745     }
00746       }
00747 
00748       if(pubkey!=null){
00749     try{
00750       file=new File(pubkey);
00751       fis=new FileInputStream(pubkey);
00752       buf=new byte[(int)(file.length())];
00753           len=0;
00754           while(true){
00755             i=fis.read(buf, len, buf.length-len);
00756             if(i<=0)
00757               break;
00758             len+=i;
00759           }
00760       fis.close();
00761 
00762       if(buf.length>4 &&             // FSecure's public key
00763          buf[0]=='-' && buf[1]=='-' && buf[2]=='-' && buf[3]=='-'){
00764 
00765         boolean valid=true;
00766         i=0;
00767         do{i++;}while(buf.length>i && buf[i]!=0x0a);
00768         if(buf.length<=i) {valid=false;}
00769 
00770         while(valid){
00771           if(buf[i]==0x0a){
00772         boolean inheader=false;
00773         for(int j=i+1; j<buf.length; j++){
00774           if(buf[j]==0x0a) break;
00775           if(buf[j]==':'){inheader=true; break;}
00776         }
00777         if(!inheader){
00778           i++; 
00779           break;
00780         }
00781           }
00782           i++;
00783         }
00784         if(buf.length<=i){valid=false;}
00785 
00786         start=i;
00787         while(valid && i<len){
00788           if(buf[i]==0x0a){
00789         System.arraycopy(buf, i+1, buf, i, len-i-1);
00790         len--;
00791         continue;
00792           }
00793           if(buf[i]=='-'){  break; }
00794           i++;
00795         }
00796         if(valid){
00797           publickeyblob=Util.fromBase64(buf, start, i-start);
00798           if(type==UNKNOWN){
00799         if(publickeyblob[8]=='d'){ type=DSA; }
00800         else if(publickeyblob[8]=='r'){ type=RSA; }
00801           }
00802         }
00803       }
00804       else{
00805         if(buf[0]=='s'&& buf[1]=='s'&& buf[2]=='h' && buf[3]=='-'){
00806           i=0;
00807           while(i<len){ if(buf[i]==' ')break; i++;} i++;
00808           if(i<len){
00809         start=i;
00810         while(i<len){ if(buf[i]==' ')break; i++;}
00811         publickeyblob=Util.fromBase64(buf, start, i-start);
00812           }
00813               if(i++<len){
00814                 int s=i;
00815                 while(i<len){ if(buf[i]=='\n')break; i++;}
00816                 if(i<len){
00817                   publicKeyComment = new String(buf, s, i-s);
00818                 }
00819               } 
00820         }
00821       }
00822     }
00823     catch(Exception ee){
00824     }
00825       }
00826     }
00827     catch(Exception e){
00828       if(e instanceof JSchException) throw (JSchException)e;
00829       if(e instanceof Throwable)
00830         throw new JSchException(e.toString(), (Throwable)e);
00831       throw new JSchException(e.toString());
00832     }
00833 
00834     KeyPair kpair=null;
00835     if(type==DSA){ kpair=new KeyPairDSA(jsch); }
00836     else if(type==RSA){ kpair=new KeyPairRSA(jsch); }
00837 
00838     if(kpair!=null){
00839       kpair.encrypted=encrypted;
00840       kpair.publickeyblob=publickeyblob;
00841       kpair.vendor=vendor;
00842       kpair.publicKeyComment=publicKeyComment;
00843       kpair.cipher=cipher;
00844 
00845       if(encrypted){
00846     kpair.iv=iv;
00847     kpair.data=data;
00848       }
00849       else{
00850     if(kpair.parse(data)){
00851       return kpair;
00852     }
00853     else{
00854       throw new JSchException("invalid privatekey: "+prvkey);
00855     }
00856       }
00857     }
00858 
00859     return kpair;
00860   }
00861 
00862   static private byte a2b(byte c){
00863     if('0'<=c&&c<='9') return (byte)(c-'0');
00864     return (byte)(c-'a'+10);
00865   }
00866   static private byte b2a(byte c){
00867     if(0<=c&&c<=9) return (byte)(c+'0');
00868     return (byte)(c-10+'A');
00869   }
00870 
00875   public void dispose(){
00876     Util.bzero(passphrase);
00877   }
00878 
00886   public void finalize (){
00887     dispose();
00888   }
00889 }

Generated on 5 May 2015 for HPCVIEWER by  doxygen 1.6.1