internal void WritePrivatePartInSECSHStyleFile(Stream dest, string comment, string passphrase) { //step1 key body SSH2DataWriter wr = new SSH2DataWriter(); wr.Write(0); //this field is filled later if (_keypair.Algorithm == PublicKeyAlgorithm.RSA) { RSAKeyPair rsa = (RSAKeyPair)_keypair; RSAPublicKey pub = (RSAPublicKey)_keypair.PublicKey; wr.WriteBigIntWithBits(pub.Exponent); wr.WriteBigIntWithBits(rsa.D); wr.WriteBigIntWithBits(pub.Modulus); wr.WriteBigIntWithBits(rsa.U); wr.WriteBigIntWithBits(rsa.P); wr.WriteBigIntWithBits(rsa.Q); } else { DSAKeyPair dsa = (DSAKeyPair)_keypair; DSAPublicKey pub = (DSAPublicKey)_keypair.PublicKey; wr.Write(0); wr.WriteBigIntWithBits(pub.P); wr.WriteBigIntWithBits(pub.G); wr.WriteBigIntWithBits(pub.Q); wr.WriteBigIntWithBits(pub.Y); wr.WriteBigIntWithBits(dsa.X); } int padding_len = 0; if (passphrase != null) { padding_len = 8 - (int)wr.Length % 8; wr.Write(new byte[padding_len]); } byte[] encrypted_body = wr.ToByteArray(); SSHUtil.WriteIntToByteArray(encrypted_body, 0, encrypted_body.Length - padding_len - 4); //encrypt if necessary if (passphrase != null) { Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH2, CipherAlgorithm.TripleDES, PassphraseToKey(passphrase, 24)); Debug.Assert(encrypted_body.Length % 8 == 0); byte[] tmp = new Byte[encrypted_body.Length]; c.Encrypt(encrypted_body, 0, encrypted_body.Length, tmp, 0); encrypted_body = tmp; } //step2 make binary key data wr = new SSH2DataWriter(); wr.Write(SSH_COM_MAGIC_VAL); wr.Write(0); //for total size wr.Write(_keypair.Algorithm == PublicKeyAlgorithm.RSA? "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}" : "dl-modp{sign{dsa-nist-sha1},dh{plain}}"); wr.Write(passphrase == null? "none" : "3des-cbc"); wr.WriteAsString(encrypted_body); byte[] rawdata = wr.ToByteArray(); SSHUtil.WriteIntToByteArray(rawdata, 4, rawdata.Length); //fix total length //step3 write final data StreamWriter sw = new StreamWriter(dest, Encoding.UTF8); sw.WriteLine("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"); if (comment != null) { WriteKeyFileBlock(sw, "Comment: " + comment, true); } byte[] tmpdata = Base64.Encode(rawdata); WriteKeyFileBlock(sw, Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length), false); sw.WriteLine("---- END SSH2 ENCRYPTED PRIVATE KEY ----"); sw.Dispose(); }
internal void WritePrivatePartInSECSHStyleFile(Stream dest, string comment, string passphrase) { //step1 key body SSH2DataWriter wr = new SSH2DataWriter(); wr.Write(0); //this field is filled later if(_keypair.Algorithm==PublicKeyAlgorithm.RSA) { RSAKeyPair rsa = (RSAKeyPair)_keypair; RSAPublicKey pub = (RSAPublicKey)_keypair.PublicKey; wr.WriteBigIntWithBits(pub.Exponent); wr.WriteBigIntWithBits(rsa.D); wr.WriteBigIntWithBits(pub.Modulus); wr.WriteBigIntWithBits(rsa.U); wr.WriteBigIntWithBits(rsa.P); wr.WriteBigIntWithBits(rsa.Q); } else { DSAKeyPair dsa = (DSAKeyPair)_keypair; DSAPublicKey pub = (DSAPublicKey)_keypair.PublicKey; wr.Write(0); wr.WriteBigIntWithBits(pub.P); wr.WriteBigIntWithBits(pub.G); wr.WriteBigIntWithBits(pub.Q); wr.WriteBigIntWithBits(pub.Y); wr.WriteBigIntWithBits(dsa.X); } int padding_len = 0; if(passphrase!=null) { padding_len = 8 - (int)wr.Length % 8; wr.Write(new byte[padding_len]); } byte[] encrypted_body = wr.ToByteArray(); SSHUtil.WriteIntToByteArray(encrypted_body, 0, encrypted_body.Length - padding_len - 4); //encrypt if necessary if(passphrase!=null) { Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH2, CipherAlgorithm.TripleDES, PassphraseToKey(passphrase,24)); Debug.Assert(encrypted_body.Length % 8 ==0); byte[] tmp = new Byte[encrypted_body.Length]; c.Encrypt(encrypted_body, 0, encrypted_body.Length, tmp, 0); encrypted_body = tmp; } //step2 make binary key data wr = new SSH2DataWriter(); wr.Write(SSH_COM_MAGIC_VAL); wr.Write(0); //for total size wr.Write(_keypair.Algorithm==PublicKeyAlgorithm.RSA? "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}" : "dl-modp{sign{dsa-nist-sha1},dh{plain}}"); wr.Write(passphrase==null? "none" : "3des-cbc"); wr.WriteAsString(encrypted_body); byte[] rawdata = wr.ToByteArray(); SSHUtil.WriteIntToByteArray(rawdata, 4, rawdata.Length); //fix total length //step3 write final data StreamWriter sw = new StreamWriter(dest, Encoding.UTF8); sw.WriteLine("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"); if(comment!=null) WriteKeyFileBlock(sw, "Comment: " + comment, true); byte[] tmpdata = Base64.Encode(rawdata); WriteKeyFileBlock(sw, Encoding.UTF8.GetString(tmpdata,0,tmpdata.Length), false); sw.WriteLine("---- END SSH2 ENCRYPTED PRIVATE KEY ----"); sw.Dispose(); }
private bool ProcessKEXDHREPLY(SSH2Packet packet) { //Round2 receives response SSH2DataReader re = new SSH2DataReader(packet.Data); PacketType h = re.ReadPacketType(); if(h!=PacketType.SSH_MSG_KEXDH_REPLY) throw new Exception(String.Format("KeyExchange response is not KEXDH_REPLY but {0}", h)); byte[] key_and_cert = re.ReadString(); BigInteger f = re.ReadMPInt(); byte[] signature = re.ReadString(); Debug.Assert(re.Rest==0); //Round3 calc hash H SSH2DataWriter wr = new SSH2DataWriter(); _k = f.modPow(_x, DH_PRIME); wr = new SSH2DataWriter(); wr.Write(_cInfo._clientVersionString); wr.Write(_cInfo._serverVersionString); wr.WriteAsString(_clientKEXINITPayload); wr.WriteAsString(_serverKEXINITPayload); wr.WriteAsString(key_and_cert); wr.Write(_e); wr.Write(f); wr.Write(_k); _hash = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha1).HashData(wr.ToByteArray().AsBuffer()).ToArray(); if(!VerifyHostKey(key_and_cert, signature, _hash)) return false; //Debug.WriteLine("hash="+DebugUtil.DumpByteArray(hash)); if(_sessionID==null) _sessionID = _hash; return true; }
private AuthenticationResult UserAuth() { string sn = "ssh-connection"; SSH2DataWriter wr = new SSH2DataWriter(); wr.WritePacketType(PacketType.SSH_MSG_USERAUTH_REQUEST); wr.Write(_param.UserName); if(_param.AuthenticationType==AuthenticationType.Password) { //Password authentication wr.Write(sn); wr.Write("password"); wr.Write(false); wr.Write(_param.Password); } else if(_param.AuthenticationType==AuthenticationType.KeyboardInteractive) { wr.Write(sn); wr.Write("keyboard-interactive"); wr.Write(""); //lang wr.Write(""); //submethod } else { //public key authentication //SSH2UserAuthKey kp = SSH2UserAuthKey.FromSECSHStyleFile(_param.IdentityFile, _param.Password); SSH2UserAuthKey kp = SSH2UserAuthKey.FromPrivateKeyFile(_param.IdentityFile, _param.Password); SSH2DataWriter signsource = new SSH2DataWriter(); signsource.WriteAsString(_sessionID); signsource.WritePacketType(PacketType.SSH_MSG_USERAUTH_REQUEST); signsource.Write(_param.UserName); signsource.Write(sn); signsource.Write("publickey"); signsource.Write(true); signsource.Write(SSH2Util.PublicKeyAlgorithmName(kp.Algorithm)); signsource.WriteAsString(kp.GetPublicKeyBlob()); SSH2DataWriter signpack = new SSH2DataWriter(); signpack.Write(SSH2Util.PublicKeyAlgorithmName(kp.Algorithm)); signpack.WriteAsString(kp.Sign(signsource.ToByteArray())); wr.Write(sn); wr.Write("publickey"); wr.Write(true); wr.Write(SSH2Util.PublicKeyAlgorithmName(kp.Algorithm)); wr.WriteAsString(kp.GetPublicKeyBlob()); wr.WriteAsString(signpack.ToByteArray()); } TransmitPacket(wr.ToByteArray()); _authenticationResult = ProcessAuthenticationResponse(); //if (_authenticationResult == GranadosRT.Routrek.SSHC.AuthenticationResult.Failure) // throw new Exception(Strings.GetString("AuthenticationFailed")); return _authenticationResult; }
private void OpenShell(ISSHChannelEventReceiver receiver, PacketType pt, SSH2DataReader reader) { if(_negotiationStatus==3) { if(pt!=PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION) { if(pt!=PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE) receiver.OnChannelError(null, "opening channel failed; packet type="+pt); else { int errcode = reader.ReadInt32(); byte[] tmpdata = reader.ReadString(); string msg = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); receiver.OnChannelError(null, msg); } Close(); } else { _remoteID = reader.ReadInt32(); _serverMaxPacketSize = reader.ReadInt32(); //open pty SSH2DataWriter wr = new SSH2DataWriter(); wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_REQUEST); wr.Write(_remoteID); wr.Write("pty-req"); wr.Write(true); wr.Write(_connection.Param().TerminalName); wr.Write(_connection.Param().TerminalWidth); wr.Write(_connection.Param().TerminalHeight); wr.Write(_connection.Param().TerminalPixelWidth); wr.Write(_connection.Param().TerminalPixelHeight); wr.WriteAsString(new byte[0]); TransmitPacket(wr.ToByteArray()); _negotiationStatus = 2; } } else if(_negotiationStatus==2) { if(pt!=PacketType.SSH_MSG_CHANNEL_SUCCESS) { receiver.OnChannelError(null, "opening pty failed"); Close(); } else { //open shell SSH2DataWriter wr = new SSH2DataWriter(); wr.Write((byte)PacketType.SSH_MSG_CHANNEL_REQUEST); wr.Write(_remoteID); wr.Write("shell"); wr.Write(true); TransmitPacket(wr.ToByteArray()); _negotiationStatus = 1; } } else if(_negotiationStatus==1) { if(pt!=PacketType.SSH_MSG_CHANNEL_SUCCESS) { receiver.OnChannelError(null, "Opening shell failed: packet type="+pt.ToString()); Close(); } else { receiver.OnChannelReady(); _negotiationStatus = 0; //goal! } } else Debug.Assert(false); }
public void Transmit(byte[] data, int offset, int length) { SSH2DataWriter wr = new SSH2DataWriter(); wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_DATA); wr.Write(_remoteID); wr.WriteAsString(data, offset, length); TransmitPacket(wr.ToByteArray()); }
public void Transmit(byte[] data) { //!!it is better idea that we wait a WINDOW_ADJUST if the left size is lack SSH2DataWriter wr = new SSH2DataWriter(); wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_DATA); wr.Write(_remoteID); wr.WriteAsString(data); TransmitPacket(wr.ToByteArray()); }