private void updateKeys(KeyExchange kex) 
		{
			byte[] K=kex.getK();
			byte[] H=kex.getH();
			HASH hash=kex.getHash();

			String[] guess=kex._guess;

			if(session_id==null)
			{
				session_id=new byte[H.Length];
				Tamir.SharpSsh.java.System.arraycopy(H, 0, session_id, 0, H.Length);
			}

			/*
			  Initial IV client to server:     HASH (K || H || "A" || session_id)
			  Initial IV server to client:     HASH (K || H || "B" || session_id)
			  Encryption key client to server: HASH (K || H || "C" || session_id)
			  Encryption key server to client: HASH (K || H || "D" || session_id)
			  Integrity key client to server:  HASH (K || H || "E" || session_id)
			  Integrity key server to client:  HASH (K || H || "F" || session_id)
			*/

			buf.reset();
			buf.putMPInt(K);
			buf.putByte(H);
			buf.putByte((byte)0x41);
			buf.putByte(session_id);
			hash.update(buf.buffer, 0, buf.index);
			IVc2s=hash.digest();

			int j=buf.index-session_id.Length-1;

			buf.buffer[j]++;
			hash.update(buf.buffer, 0, buf.index);
			IVs2c=hash.digest();

			buf.buffer[j]++;
			hash.update(buf.buffer, 0, buf.index);
			Ec2s=hash.digest();

			buf.buffer[j]++;
			hash.update(buf.buffer, 0, buf.index);
			Es2c=hash.digest();

			buf.buffer[j]++;
			hash.update(buf.buffer, 0, buf.index);
			MACc2s=hash.digest();

			buf.buffer[j]++;
			hash.update(buf.buffer, 0, buf.index);
			MACs2c=hash.digest();

			try
			{
				Class c;

				c=Class.forName(getConfig(guess[KeyExchange.PROPOSAL_ENC_ALGS_STOC]));
				s2ccipher=(Cipher)(c.newInstance());
				while(s2ccipher.getBlockSize()>Es2c.Length)
				{
					buf.reset();
					buf.putMPInt(K);
					buf.putByte(H);
					buf.putByte(Es2c);
					hash.update(buf.buffer, 0, buf.index);
					byte[] foo=hash.digest();
					byte[] bar=new byte[Es2c.Length+foo.Length];
					Tamir.SharpSsh.java.System.arraycopy(Es2c, 0, bar, 0, Es2c.Length);
					Tamir.SharpSsh.java.System.arraycopy(foo, 0, bar, Es2c.Length, foo.Length);
					Es2c=bar;
				}
				s2ccipher.init(Cipher.DECRYPT_MODE, Es2c, IVs2c);
				cipher_size=s2ccipher.getIVSize();
				c=Class.forName(getConfig(guess[KeyExchange.PROPOSAL_MAC_ALGS_STOC]));
				s2cmac=(MAC)(c.newInstance());
				s2cmac.init(MACs2c);
				mac_buf=new byte[s2cmac.getBlockSize()];

				c=Class.forName(getConfig(guess[KeyExchange.PROPOSAL_ENC_ALGS_CTOS]));
				c2scipher=(Cipher)(c.newInstance());
				while(c2scipher.getBlockSize()>Ec2s.Length)
				{
					buf.reset();
					buf.putMPInt(K);
					buf.putByte(H);
					buf.putByte(Ec2s);
					hash.update(buf.buffer, 0, buf.index);
					byte[] foo=hash.digest();
					byte[] bar=new byte[Ec2s.Length+foo.Length];
					Tamir.SharpSsh.java.System.arraycopy(Ec2s, 0, bar, 0, Ec2s.Length);
					Tamir.SharpSsh.java.System.arraycopy(foo, 0, bar, Ec2s.Length, foo.Length);
					Ec2s=bar;
				}
				c2scipher.init(Cipher.ENCRYPT_MODE, Ec2s, IVc2s);

				c=Class.forName(getConfig(guess[KeyExchange.PROPOSAL_MAC_ALGS_CTOS]));
				c2smac=(MAC)(c.newInstance());
				c2smac.init(MACc2s);

				if(!guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS].equals("none"))
				{
					String foo=getConfig(guess[KeyExchange.PROPOSAL_COMP_ALGS_CTOS]);
					if(foo!=null)
					{
						try
						{
							c=Class.forName(foo);
							deflater=(Compression)(c.newInstance());
							int level=6;
							try{ level=Integer.parseInt(getConfig("compression_level"));}
							catch(Exception ee){ }
							deflater.init(Compression.DEFLATER, level);
						}
						catch(Exception ee)
						{
							System.Console.Error.WriteLine(foo+" isn't accessible.");
						}
					}
				}
				else
				{
					if(deflater!=null)
					{
						deflater=null;
					}
				}
				if(!guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC].equals("none"))
				{
					String foo=getConfig(guess[KeyExchange.PROPOSAL_COMP_ALGS_STOC]);
					if(foo!=null)
					{
						try
						{
							c=Class.forName(foo);
							inflater=(Compression)(c.newInstance());
							inflater.init(Compression.INFLATER, 0);
						}
						catch(Exception ee)
						{
							System.Console.Error.WriteLine(foo+" isn't accessible.");
						}
					}
				}
				else
				{
					if(inflater!=null)
					{
						inflater=null;
					}
				}
			}
			catch(Exception e){ System.Console.Error.WriteLine("updatekeys: "+e); }
		}
Beispiel #2
0
		internal IdentityFile(String identity, JSch jsch) 
		{
			this.identity=identity;
			this.jsch=jsch;
			try
			{
				Type c=Type.GetType(jsch.getConfig("3des-cbc"));
				cipher=(Cipher)Activator.CreateInstance(c);
				key=new byte[cipher.getBlockSize()];   // 24
				iv=new byte[cipher.getIVSize()];       // 8
				c=Type.GetType(jsch.getConfig("md5"));
				hash=(HASH)(Activator.CreateInstance(c));
				hash.init();
				FileInfo file=new FileInfo(identity);
				FileStream fis = File.OpenRead(identity);
				byte[] buf=new byte[(int)(file.Length)];
				int len=fis.Read(buf, 0, buf.Length);
				fis.Close();

				int i=0;
				while(i<len)
				{
					if(buf[i]=='B'&& buf[i+1]=='E'&& buf[i+2]=='G'&& buf[i+3]=='I')
					{
						i+=6;	    
						if(buf[i]=='D'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=DSS; }
						else if(buf[i]=='R'&& buf[i+1]=='S'&& buf[i+2]=='A'){ type=RSA; }
						else if(buf[i]=='S'&& buf[i+1]=='S'&& buf[i+2]=='H')
						{ // FSecure
							type=UNKNOWN;
							keytype=FSECURE;
						}
						else
						{
							//System.out.println("invalid format: "+identity);
							throw new JSchException("invaid privatekey: "+identity);
						}
						i+=3;
						continue;
					}
					if(buf[i]=='C'&& buf[i+1]=='B'&& buf[i+2]=='C'&& buf[i+3]==',')
					{
						i+=4;
						for(int ii=0; ii<iv.Length; ii++)
						{
							iv[ii]=(byte)(((a2b(buf[i++])<<4)&0xf0)+
								(a2b(buf[i++])&0xf));
						}
						continue;
					}
					if(buf[i]==0x0d &&
						i+1<buf.Length && buf[i+1]==0x0a)
					{
						i++;
						continue;
					}
					if(buf[i]==0x0a && i+1<buf.Length)
					{
						if(buf[i+1]==0x0a){ i+=2; break; }
						if(buf[i+1]==0x0d &&
							i+2<buf.Length && buf[i+2]==0x0a)
						{
							i+=3; break;
						}
						bool inheader=false;
						for(int j=i+1; j<buf.Length; j++)
						{
							if(buf[j]==0x0a) break;
							//if(buf[j]==0x0d) break;
							if(buf[j]==':'){inheader=true; break;}
						}
						if(!inheader)
						{
							i++; 
							encrypted=false;    // no passphrase
							break;
						}
					}
					i++;
				}

				if(type==ERROR)
				{
					throw new JSchException("invaid privatekey: "+identity);
				}

				int start=i;
				while(i<len)
				{
					if(buf[i]==0x0a)
					{
						bool xd=(buf[i-1]==0x0d);
						Array.Copy(buf, i+1, 
							buf, 
							i-(xd ? 1 : 0), 
							len-i-1-(xd ? 1 : 0)
							);
						if(xd)len--;
						len--;
						continue;
					}
					if(buf[i]=='-'){  break; }
					i++;
				}
				encoded_data=Util.fromBase64(buf, start, i-start);

				if(encoded_data.Length>4 &&            // FSecure
					encoded_data[0]==(byte)0x3f &&
					encoded_data[1]==(byte)0x6f &&
					encoded_data[2]==(byte)0xf9 &&
					encoded_data[3]==(byte)0xeb)
				{

					Buffer _buf=new Buffer(encoded_data);
					_buf.ReadInt();  // 0x3f6ff9be
					_buf.ReadInt();
					byte[]_type=_buf.ReadString();
					//System.out.println("type: "+Encoding.UTF8.GetString(_type)); 
					byte[] _cipher=_buf.ReadString();
					String s_cipher=System.Text.Encoding.Default.GetString(_cipher);
					//System.out.println("cipher: "+cipher); 
					if(s_cipher.Equals("3des-cbc"))
					{
						_buf.ReadInt();
						byte[] foo=new byte[encoded_data.Length-_buf.Offset];
						_buf.ReadByte(foo);
						encoded_data=foo;
						encrypted=true;
						throw new JSchException("unknown privatekey format: "+identity);
					}
					else if(s_cipher.Equals("none"))
					{
						_buf.ReadInt();
						//_buf.getInt();

						encrypted=false;

						byte[] foo=new byte[encoded_data.Length-_buf.Offset];
						_buf.ReadByte(foo);
						encoded_data=foo;
					}

				}

				try
				{
					file=new FileInfo(identity+".pub");
					fis=File.OpenRead(identity+".pub");
					buf=new byte[(int)(file.Length)];
					len=fis.Read(buf, 0, buf.Length);
					fis.Close();
				}
				catch
				{
					return;
				}

				if(buf.Length>4 &&             // FSecure's public key
					buf[0]=='-' && buf[1]=='-' && buf[2]=='-' && buf[3]=='-')
				{

					i=0;
					do{i++;}while(buf.Length>i && buf[i]!=0x0a);
					if(buf.Length<=i) return;

					while(true)
					{
						if(buf[i]==0x0a)
						{
							bool inheader=false;
							for(int j=i+1; j<buf.Length; j++)
							{
								if(buf[j]==0x0a) break;
								if(buf[j]==':'){inheader=true; break;}
							}
							if(!inheader)
							{
								i++; 
								break;
							}
						}
						i++;
					}
					if(buf.Length<=i) return;

					start=i;
					while(i<len)
					{
						if(buf[i]==0x0a)
						{
							Array.Copy(buf, i+1, buf, i, len-i-1);
							len--;
							continue;
						}
						if(buf[i]=='-'){  break; }
						i++;
					}
					publickeyblob=Util.fromBase64(buf, start, i-start);

					if(type==UNKNOWN)
					{
						if(publickeyblob[8]=='d')
						{
							type=DSS;
						}
						else if(publickeyblob[8]=='r')
						{
							type=RSA;
						}
					}
				}
				else
				{
					if(buf[0]!='s'|| buf[1]!='s'|| buf[2]!='h'|| buf[3]!='-') return;
					i=0;
					while(i<len){ if(buf[i]==' ')break; i++;} i++;
					if(i>=len) return;
					start=i;
					while(i<len){ if(buf[i]==' ')break; i++;}
					publickeyblob=Util.fromBase64(buf, start, i-start);
				}

			}
			catch(Exception e)
			{
				Console.WriteLine("Identity: "+e);
				if(e is JSchException) throw (JSchException)e;
				throw new JSchException(e.ToString());
			}

		}
Beispiel #3
0
		private Cipher genCipher()
		{
			try
			{
				Type t;
				t=Type.GetType(jsch.getConfig("3des-cbc"));
				cipher=(Cipher)(Activator.CreateInstance(t));
			}
			catch//(Exception e)
			{
			}
			return cipher;
		}
Beispiel #4
0
		internal byte[] genKey(byte[] passphrase, byte[] iv)
		{
			if(cipher==null) cipher=genCipher();
			if(hash==null) hash=genHash();

			byte[] key=new byte[cipher.getBlockSize()];
			int hsize=hash.getBlockSize();
			byte[] hn=new byte[key.Length/hsize*hsize+
				(key.Length%hsize==0?0:hsize)];
			try
			{
				byte[] tmp=null;
				if(vendor==VENDOR_OPENSSH)
				{
					for(int index=0; index+hsize<=hn.Length;)
					{
						if(tmp!=null){ hash.update(tmp, 0, tmp.Length); }
						hash.update(passphrase, 0, passphrase.Length);
						hash.update(iv, 0, iv.Length);
						tmp=hash.digest();
						Array.Copy(tmp, 0, hn, index, tmp.Length);
						index+=tmp.Length;
					}
					Array.Copy(hn, 0, key, 0, key.Length); 
				}
				else if(vendor==VENDOR_FSECURE)
				{
					for(int index=0; index+hsize<=hn.Length;)
					{
						if(tmp!=null){ hash.update(tmp, 0, tmp.Length); }
						hash.update(passphrase, 0, passphrase.Length);
						tmp=hash.digest();
						Array.Copy(tmp, 0, hn, index, tmp.Length);
						index+=tmp.Length;
					}
					Array.Copy(hn, 0, key, 0, key.Length); 
				}
			}
			catch(Exception e)
			{
				Console.WriteLine(e);
			}
			return key;
		} 
Beispiel #5
0
		private byte[] encrypt(byte[] plain, byte[][] _iv)
		{
			if(passphrase==null) return plain;

			if(cipher==null) cipher=genCipher();
			byte[] iv=_iv[0]=new byte[cipher.getIVSize()];

			if(random==null) random=genRandom();
			random.fill(iv, 0, iv.Length);

			byte[] key=genKey(passphrase, iv);
			byte[] encoded=plain;
			int bsize=cipher.getBlockSize();
			if(encoded.Length%bsize!=0)
			{
				byte[] foo=new byte[(encoded.Length/bsize+1)*bsize];
				Array.Copy(encoded, 0, foo, 0, encoded.Length);
				encoded=foo;
			}

			try
			{
				cipher.init(Cipher.ENCRYPT_MODE, key, iv);
				cipher.update(encoded, 0, encoded.Length, encoded, 0);
			}
			catch(Exception e)
			{
				Console.WriteLine(e);
			}
			return encoded;
		}