private static int GetIntegerSize(SSH2DataReader binr) { byte bt = 0; byte lowbyte = 0x00; byte highbyte = 0x00; int count = 0; bt = binr.ReadByte(); if (bt != 0x02) //expect integer { return(0); } bt = binr.ReadByte(); if (bt == 0x81) { count = binr.ReadByte(); // data size in next byte } else if (bt == 0x82) { highbyte = binr.ReadByte(); // data size in next 2 bytes lowbyte = binr.ReadByte(); byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; count = BitConverter.ToInt32(modint, 0); } else { count = bt; // we already have the data size } while (binr.ReadByte() == 0x00) { //remove high order zeros in data count -= 1; } binr.Seek(-1); //last ReadByte wasn't a removed zero, so back up a byte return(count); }
public static bool IsPrivateKeyEncrypted(string filename) { bool returnVal = false; var fileToLaunch = StorageFile.GetFileFromPathAsync(filename); fileToLaunch.AsTask().Wait(); var streamToLaunch = fileToLaunch.AsTask().Result.OpenStreamForReadAsync(); streamToLaunch.Wait(); using (Stream s = streamToLaunch.Result) { using (StreamReader r = new StreamReader(streamToLaunch.Result, Encoding.UTF8)) { string l = r.ReadLine(); if (l == PKCS8_RSA_HEADER) { while (l != "-----END RSA PRIVATE KEY-----") { if (l.IndexOf("Proc-Type: 4,ENCRYPTED") != -1) { returnVal = true; break; } l = r.ReadLine(); if (l == null) { break; } } } else if (l == PKCS8_DSA_HEADER) { while (l != "-----END DSA PRIVATE KEY-----") { if (l.IndexOf("Proc-Type: 4,ENCRYPTED") != -1) { returnVal = true; break; } l = r.ReadLine(); if (l == null) { break; } } } else if (l == SSH_COM_HEADER) { l = r.ReadLine(); StringBuilder buf = new StringBuilder(); while (l != "---- END SSH2 ENCRYPTED PRIVATE KEY ----") { if (l.IndexOf(':') == -1) { buf.Append(l); } else { while (l.EndsWith("\\")) { l = r.ReadLine(); } } l = r.ReadLine(); if (l == null) { break; } } byte[] keydata = Base64.Decode(Encoding.UTF8.GetBytes(buf.ToString())); SSH2DataReader re = new SSH2DataReader(keydata); int magic = re.ReadInt32(); if (magic != SSH_COM_MAGIC_VAL) { return(false); // Magic number doesn't match so just say false because it will error-out anyway } int privateKeyLen = re.ReadInt32(); byte[] tmpstr = re.ReadString(); string type = Encoding.UTF8.GetString(tmpstr, 0, tmpstr.Length); tmpstr = re.ReadString(); string ciphername = Encoding.UTF8.GetString(tmpstr, 0, tmpstr.Length); int bufLen = re.ReadInt32(); if (ciphername != "none") { returnVal = true; } } r.Dispose(); s.Dispose(); } } return(returnVal); }
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 void ProcessKEXINIT(SSH2Packet packet) { _serverKEXINITPayload = packet.Data; SSH2DataReader re = new SSH2DataReader(_serverKEXINITPayload); byte[] head = re.Read(17); //Type and cookie if(head[0]!=(byte)PacketType.SSH_MSG_KEXINIT) throw new Exception(String.Format("Server response is not SSH_MSG_KEXINIT but {0}", head[0])); Encoding enc = Encoding.UTF8; byte[] tmpdata; tmpdata = re.ReadString(); string kex = enc.GetString(tmpdata,0,tmpdata.Length); _cInfo._supportedKEXAlgorithms = kex; CheckAlgorithmSupport("keyexchange", kex, "diffie-hellman-group1-sha1"); tmpdata = re.ReadString(); string host_key = enc.GetString(tmpdata, 0, tmpdata.Length); _cInfo._supportedHostKeyAlgorithms = host_key; _cInfo._algorithmForHostKeyVerification = DecideHostKeyAlgorithm(host_key); tmpdata = re.ReadString(); string enc_cs = enc.GetString(tmpdata, 0, tmpdata.Length); _cInfo._supportedCipherAlgorithms = enc_cs; _cInfo._algorithmForTransmittion = DecideCipherAlgorithm(enc_cs); tmpdata = re.ReadString(); string enc_sc = enc.GetString(tmpdata, 0, tmpdata.Length); _cInfo._algorithmForReception = DecideCipherAlgorithm(enc_sc); tmpdata = re.ReadString(); string mac_cs = enc.GetString(tmpdata, 0, tmpdata.Length); CheckAlgorithmSupport("mac", mac_cs, "hmac-sha1"); tmpdata = re.ReadString(); string mac_sc = enc.GetString(tmpdata, 0, tmpdata.Length); CheckAlgorithmSupport("mac", mac_sc, "hmac-sha1"); tmpdata = re.ReadString(); string comp_cs = enc.GetString(tmpdata, 0, tmpdata.Length); CheckAlgorithmSupport("compression", comp_cs, "none"); tmpdata = re.ReadString(); string comp_sc = enc.GetString(tmpdata, 0, tmpdata.Length); CheckAlgorithmSupport("compression", comp_sc, "none"); tmpdata = re.ReadString(); string lang_cs = enc.GetString(tmpdata, 0, tmpdata.Length); tmpdata = re.ReadString(); string lang_sc = enc.GetString(tmpdata, 0, tmpdata.Length); bool flag = re.ReadBool(); int reserved = re.ReadInt32(); Debug.Assert(re.Rest==0); if(flag) throw new Exception(resLoader.GetString("AlgNegotiationFailed")); }
private static int GetIntegerSize(SSH2DataReader binr) { byte bt = 0; byte lowbyte = 0x00; byte highbyte = 0x00; int count = 0; bt = binr.ReadByte(); if (bt != 0x02) //expect integer return 0; bt = binr.ReadByte(); if (bt == 0x81) count = binr.ReadByte(); // data size in next byte else if (bt == 0x82) { highbyte = binr.ReadByte(); // data size in next 2 bytes lowbyte = binr.ReadByte(); byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; count = BitConverter.ToInt32(modint, 0); } else { count = bt; // we already have the data size } while (binr.ReadByte() == 0x00) { //remove high order zeros in data count -= 1; } binr.Seek(-1); //last ReadByte wasn't a removed zero, so back up a byte return count; }
private void VerifyHostKeyByDSS(SSH2DataReader pubkey, byte[] sigbody, byte[] hash) { BigInteger p = pubkey.ReadMPInt(); BigInteger q = pubkey.ReadMPInt(); BigInteger g = pubkey.ReadMPInt(); BigInteger y = pubkey.ReadMPInt(); Debug.Assert(pubkey.Rest==0); //Debug.WriteLine(p.ToHexString()); //Debug.WriteLine(q.ToHexString()); //Debug.WriteLine(g.ToHexString()); //Debug.WriteLine(y.ToHexString()); DSAPublicKey pk = new DSAPublicKey(p,g,q,y); pk.Verify(sigbody, HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha1).HashData(hash.AsBuffer()).ToArray()); _cInfo._hostkey = pk; }
private AuthenticationResult ProcessAuthenticationResponse() { do { SSH2DataReader response = new SSH2DataReader(ReceivePacket().Data); PacketType h = response.ReadPacketType(); if(h==PacketType.SSH_MSG_USERAUTH_FAILURE) { byte[] tmpdata = response.ReadString(); string msg = Encoding.UTF8.GetString(tmpdata,0,tmpdata.Length); _eventReceiver.OnDebugMessage(true, tmpdata); bool partialSuccess = response.ReadBool(); return GranadosRT.Routrek.SSHC.AuthenticationResult.Failure; } else if(h==PacketType.SSH_MSG_USERAUTH_BANNER) { //Debug.WriteLine("USERAUTH_BANNER"); byte[] tmpdata = response.ReadString(); _eventReceiver.OnDebugMessage(true, tmpdata); } else if(h==PacketType.SSH_MSG_USERAUTH_SUCCESS) { _packetBuilder.Handler = new CallbackSSH2PacketHandler(this); return GranadosRT.Routrek.SSHC.AuthenticationResult.Success; //successfully exit } else if (h == PacketType.SSH_MSG_USERAUTH_INFO_REQUEST) { byte[] tmpdata = response.ReadString(); string name = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); tmpdata = response.ReadString(); string inst = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); tmpdata = response.ReadString(); string lang = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); int num = response.ReadInt32(); string[] prompts = new string[num]; for (int i = 0; i < num; i++) { tmpdata = response.ReadString(); prompts[i] = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); bool echo = response.ReadBool(); } if (prompts.Length == 0) { //TODO 0 length response SSH2DataWriter re = new SSH2DataWriter(); re.WritePacketType(PacketType.SSH_MSG_USERAUTH_INFO_RESPONSE); re.Write(0); byte[] ba = re.ToByteArray(); TransmitPacket(ba); return ProcessAuthenticationResponse(); } else { _eventReceiver.OnAuthenticationPrompt(prompts); return GranadosRT.Routrek.SSHC.AuthenticationResult.Prompt; } } else { //throw new Exception(resLoader.GetString("ProtocolError") + resLoader.GetString("UnexpectedPacket") + h); } } while(true); }
/* * Format style note * ---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- * Comment: ******* * <base64-encoded body> * ---- END SSH2 ENCRYPTED PRIVATE KEY ---- * * body = MAGIC_VAL || body-length || type(string) || encryption-algorithm-name(string) || encrypted-body(string) * encrypted-body = array of BigInteger(algorithm-specific) */ internal static SSH2UserAuthKey FromRSAOpenSSHStyleStream(StreamReader r, string passphrase) { string l = r.ReadLine(); StringBuilder buf = new StringBuilder(); while (l != "-----END RSA PRIVATE KEY-----") { if (l.IndexOf(':') == -1) buf.Append(l); else { while (l.EndsWith("\\")) l = r.ReadLine(); } l = r.ReadLine(); if (l == null) throw new Exception(resLoader.GetString("BrokenKeyFile")); } //r.Close(); byte[] keydata = CryptographicBuffer.DecodeFromBase64String(buf.ToString()).ToArray(); if (passphrase != "") { r.BaseStream.Seek(0, SeekOrigin.Begin); r.ReadLine();//Get rid of header if (!r.ReadLine().StartsWith("Proc-Type: 4,ENCRYPTED")) throw new Exception(resLoader.GetString("KeyFormatUnsupported")); String saltline = r.ReadLine(); if (!saltline.StartsWith("DEK-Info: DES-EDE3-CBC,")) throw new Exception(resLoader.GetString("KeyFormatUnsupported")); String saltstr = saltline.Substring(saltline.IndexOf(",") + 1).Trim(); byte[] salt = new byte[saltstr.Length / 2]; for (int i = 0; i < salt.Length; i++) salt[i] = Convert.ToByte(saltstr.Substring(i * 2, 2), 16); byte[] deskey = GetOpenSSL3deskey(salt, passphrase, 1, 2); if (deskey == null) return null; byte[] rsakey = DecryptKey(keydata, deskey, salt); keydata = rsakey; } r.Dispose(); SSH2DataReader re = new SSH2DataReader(keydata); int magic = re.ReadInt16(); if (magic != OPEN_SSH_MAGIC_VAL) throw new Exception(resLoader.GetString("BrokenKeyFile")); int length = re.ReadInt16(); //Version re.ReadByte(); // tag: 2 re.ReadByte(); // stored length: 1 int version = (int)re.ReadByte(); // 0 //Modulus length = GetIntegerSize(re); // tag: 2 BigInteger n = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger e = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger d = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger p = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger q = new BigInteger(re.Read(length)); //u ?? is not stored? calculated in special constructor /* length = GetIntegerSize(re); // tag: 2 BigInteger u = re.ReadASNBigInt(); */ return new SSH2UserAuthKey(new RSAKeyPair(n, e, d, p, q)); }
private void ReceivePortForwardingResponse(ISSHChannelEventReceiver receiver, PacketType pt, SSH2DataReader reader) { if(_negotiationStatus==1) { 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(); _negotiationStatus = 0; receiver.OnChannelReady(); } } else Debug.Assert(false); }
//synchronous reception internal SSH2Packet ReceivePacket() { while(true) { SSH2Packet p = null; SynchronizedSSH2PacketHandler handler = (SynchronizedSSH2PacketHandler)_packetBuilder.Handler; try { if (!handler.HasPacket) { handler.Wait(); if (handler.State == ReceiverState.Error) throw new Exception(handler.ErrorMessage); else if (handler.State == ReceiverState.Closed) throw new Exception(resLoader.GetString("SocketClosed")); } p = handler.PopPacket(); } catch (Exception e) { _eventReceiver.OnError(e, e.Message); return p; } SSH2DataReader r = new SSH2DataReader(p.Data); PacketType pt = r.ReadPacketType(); if(pt==PacketType.SSH_MSG_IGNORE) { if(_eventReceiver!=null) _eventReceiver.OnIgnoreMessage(r.ReadString()); } else if(pt==PacketType.SSH_MSG_DEBUG) { bool f = r.ReadBool(); if(_eventReceiver!=null) _eventReceiver.OnDebugMessage(f, r.ReadString()); } else return p; } }
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); }
internal void ProcessPacket(ISSHChannelEventReceiver receiver, PacketType pt, int data_length, SSH2DataReader re) { //NOTE: the offset of 're' is next to 'receipiant channel' field _leftWindowSize -= data_length; if (_negotiationStatus < 1) { while (_leftWindowSize <= _windowSize) { SSH2DataWriter adj = new SSH2DataWriter(); adj.WritePacketType(PacketType.SSH_MSG_CHANNEL_WINDOW_ADJUST); adj.Write(_remoteID); adj.Write(_windowSize); TransmitPacket(adj.ToByteArray()); _leftWindowSize += _windowSize; Debug.WriteLine("Window size is adjusted to " + _leftWindowSize); } } if(pt==PacketType.SSH_MSG_CHANNEL_WINDOW_ADJUST) { int w = re.ReadInt32(); //Debug.WriteLine(String.Format("Window Adjust +={0}",w)); } else if(_negotiationStatus!=0) { //when the negotiation is not completed if(_type==ChannelType.Shell) OpenShell(receiver, pt, re); else if(_type==ChannelType.ForwardedLocalToRemote) ReceivePortForwardingResponse(receiver, pt, re); else if(_type==ChannelType.Session) EstablishSession(receiver, pt, re); } else { switch(pt) { case PacketType.SSH_MSG_CHANNEL_DATA: { int len = re.ReadInt32(); //await receiver.OnData(re.Image, re.Offset, len); receiver.OnData(re.Image, re.Offset, len); } break; case PacketType.SSH_MSG_CHANNEL_EXTENDED_DATA: { int t = re.ReadInt32(); byte[] data = re.ReadString(); receiver.OnExtendedData(t, data); } break; case PacketType.SSH_MSG_CHANNEL_REQUEST: { byte[] tmpdata = re.ReadString(); string request = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); bool reply = re.ReadBool(); if(request=="exit-status") { int status = re.ReadInt32(); } } break; case PacketType.SSH_MSG_CHANNEL_EOF: receiver.OnChannelEOF(); break; case PacketType.SSH_MSG_CHANNEL_CLOSE: _connection.UnregisterChannelEventReceiver(_localID); receiver.OnChannelClosed(); break; case PacketType.SSH_MSG_CHANNEL_FAILURE: case PacketType.SSH_MSG_CHANNEL_SUCCESS: receiver.OnMiscPacket((byte)pt, re.Image, re.Offset, re.Rest); break; default: receiver.OnMiscPacket((byte)pt, re.Image, re.Offset, re.Rest); Debug.WriteLine(resLoader.GetString("UnexpectedPacket")+pt); break; } } }
private void VerifyHostKeyByRSA(SSH2DataReader pubkey, byte[] sigbody, byte[] hash) { BigInteger exp = pubkey.ReadMPInt(); BigInteger mod = pubkey.ReadMPInt(); Debug.Assert(pubkey.Rest==0); //Debug.WriteLine(exp.ToHexString()); //Debug.WriteLine(mod.ToHexString()); RSAPublicKey pk = new RSAPublicKey(exp, mod); pk.VerifyWithSHA1(sigbody, HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha1).HashData(hash.AsBuffer()).ToArray()); _cInfo._hostkey = pk; }
/* * Format style note * ---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- * Comment: ******* * <base64-encoded body> * ---- END SSH2 ENCRYPTED PRIVATE KEY ---- * * body = MAGIC_VAL || body-length || type(string) || encryption-algorithm-name(string) || encrypted-body(string) * encrypted-body = array of BigInteger(algorithm-specific) */ internal static SSH2UserAuthKey FromRSAOpenSSHStyleStream(StreamReader r, string passphrase) { string l = r.ReadLine(); StringBuilder buf = new StringBuilder(); while (l != "-----END RSA PRIVATE KEY-----") { if (l.IndexOf(':') == -1) { buf.Append(l); } else { while (l.EndsWith("\\")) { l = r.ReadLine(); } } l = r.ReadLine(); if (l == null) { throw new Exception(resLoader.GetString("BrokenKeyFile")); } } //r.Close(); byte[] keydata = CryptographicBuffer.DecodeFromBase64String(buf.ToString()).ToArray(); if (passphrase != "") { r.BaseStream.Seek(0, SeekOrigin.Begin); r.ReadLine();//Get rid of header if (!r.ReadLine().StartsWith("Proc-Type: 4,ENCRYPTED")) { throw new Exception(resLoader.GetString("KeyFormatUnsupported")); } String saltline = r.ReadLine(); if (!saltline.StartsWith("DEK-Info: DES-EDE3-CBC,")) { throw new Exception(resLoader.GetString("KeyFormatUnsupported")); } String saltstr = saltline.Substring(saltline.IndexOf(",") + 1).Trim(); byte[] salt = new byte[saltstr.Length / 2]; for (int i = 0; i < salt.Length; i++) { salt[i] = Convert.ToByte(saltstr.Substring(i * 2, 2), 16); } byte[] deskey = GetOpenSSL3deskey(salt, passphrase, 1, 2); if (deskey == null) { return(null); } byte[] rsakey = DecryptKey(keydata, deskey, salt); keydata = rsakey; } r.Dispose(); SSH2DataReader re = new SSH2DataReader(keydata); int magic = re.ReadInt16(); if (magic != OPEN_SSH_MAGIC_VAL) { throw new Exception(resLoader.GetString("BrokenKeyFile")); } int length = re.ReadInt16(); //Version re.ReadByte(); // tag: 2 re.ReadByte(); // stored length: 1 int version = (int)re.ReadByte(); // 0 //Modulus length = GetIntegerSize(re); // tag: 2 BigInteger n = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger e = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger d = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger p = new BigInteger(re.Read(length)); length = GetIntegerSize(re); // tag: 2 BigInteger q = new BigInteger(re.Read(length)); //u ?? is not stored? calculated in special constructor /* * length = GetIntegerSize(re); // tag: 2 * BigInteger u = re.ReadASNBigInt(); */ return(new SSH2UserAuthKey(new RSAKeyPair(n, e, d, p, q))); }
private bool ProcessPacket(SSH2Packet packet) { //Debug.WriteLine("ProcessPacket pt="+pt); SSH2DataReader r = new SSH2DataReader(packet.Data); PacketType pt = r.ReadPacketType(); if(pt==PacketType.SSH_MSG_DISCONNECT) { int errorcode = r.ReadInt32(); byte[] tmpdata = r.ReadString(); string description = Encoding.UTF8.GetString(tmpdata, 0 ,tmpdata.Length); _eventReceiver.OnConnectionClosed(); return false; } else if(_waitingForPortForwardingResponse) { if(pt!=PacketType.SSH_MSG_REQUEST_SUCCESS) _eventReceiver.OnUnknownMessage((byte)pt, r.Image); _waitingForPortForwardingResponse = false; return true; } else if(pt==PacketType.SSH_MSG_CHANNEL_OPEN) { ProcessPortforwardingRequest(_eventReceiver, r); return true; } else if(pt>=PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION && pt<=PacketType.SSH_MSG_CHANNEL_FAILURE) { int local_channel = r.ReadInt32(); ChannelEntry e = FindChannelEntry(local_channel); if(e!=null) //throw new Exception("Unknown channel "+local_channel); ((SSH2Channel)e._channel).ProcessPacket(e._receiver, pt, 5+r.Rest, r); else Debug.WriteLine("unexpected channel pt="+pt+" local_channel="+local_channel.ToString()); return true; } else if(pt==PacketType.SSH_MSG_IGNORE) { _eventReceiver.OnIgnoreMessage(r.ReadString()); return true; } else if(_asyncKeyExchanger!=null) { _asyncKeyExchanger.AsyncProcessPacket(packet); return true; } else if(pt==PacketType.SSH_MSG_KEXINIT) { //Debug.WriteLine("Host sent KEXINIT"); _asyncKeyExchanger = new KeyExchanger(this, _sessionID); _asyncKeyExchanger.AsyncProcessPacket(packet); return true; } else { _eventReceiver.OnUnknownMessage((byte)pt, r.Image); return false; } }
/* * Format style note * ---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- * Comment: ******* * <base64-encoded body> * ---- END SSH2 ENCRYPTED PRIVATE KEY ---- * * body = MAGIC_VAL || body-length || type(string) || encryption-algorithm-name(string) || encrypted-body(string) * encrypted-body = array of BigInteger(algorithm-specific) */ internal static SSH2UserAuthKey FromSECSHStyleStream(StreamReader r, string passphrase) { string l = r.ReadLine(); StringBuilder buf = new StringBuilder(); while (l != "---- END SSH2 ENCRYPTED PRIVATE KEY ----") { if (l.IndexOf(':') == -1) { buf.Append(l); } else { while (l.EndsWith("\\")) { l = r.ReadLine(); } } l = r.ReadLine(); if (l == null) { throw new Exception(resLoader.GetString("BrokenKeyFile")); } } //r.Close(); r.Dispose(); byte[] keydata = Base64.Decode(Encoding.UTF8.GetBytes(buf.ToString())); SSH2DataReader re = new SSH2DataReader(keydata); int magic = re.ReadInt32(); if (magic != SSH_COM_MAGIC_VAL) { throw new Exception(resLoader.GetString("BrokenKeyFile")); } int privateKeyLen = re.ReadInt32(); byte[] tmpstr = re.ReadString(); string type = Encoding.UTF8.GetString(tmpstr, 0, tmpstr.Length); tmpstr = re.ReadString(); string ciphername = Encoding.UTF8.GetString(tmpstr, 0, tmpstr.Length); int bufLen = re.ReadInt32(); if (ciphername != "none") { CipherAlgorithm algo = CipherFactory.SSH2NameToAlgorithm(ciphername); byte[] key = PassphraseToKey(passphrase, CipherFactory.GetKeySize(algo)); Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH2, algo, key); byte[] tmp = new Byte[re.Image.Length - re.Offset]; c.Decrypt(re.Image, re.Offset, re.Image.Length - re.Offset, tmp, 0); re = new SSH2DataReader(tmp); } int parmLen = re.ReadInt32(); if (parmLen < 0 || parmLen > re.Rest) { throw new Exception(resLoader.GetString("WrongPassphrase")); } if (type.IndexOf("if-modn") != -1) { //mindterm mistaken this order of BigIntegers BigInteger e = re.ReadBigIntWithBits(); BigInteger d = re.ReadBigIntWithBits(); BigInteger n = re.ReadBigIntWithBits(); BigInteger u = re.ReadBigIntWithBits(); BigInteger p = re.ReadBigIntWithBits(); BigInteger q = re.ReadBigIntWithBits(); return(new SSH2UserAuthKey(new RSAKeyPair(e, d, n, u, p, q))); } else if (type.IndexOf("dl-modp") != -1) { if (re.ReadInt32() != 0) { throw new Exception(resLoader.GetString("BrokenKeyFile")); } BigInteger p = re.ReadBigIntWithBits(); BigInteger g = re.ReadBigIntWithBits(); BigInteger q = re.ReadBigIntWithBits(); BigInteger y = re.ReadBigIntWithBits(); BigInteger x = re.ReadBigIntWithBits(); return(new SSH2UserAuthKey(new DSAKeyPair(p, g, q, y, x))); } else { throw new Exception(resLoader.GetString("KeyFormatUnknown")); } }
private void ProcessPortforwardingRequest(ISSHConnectionEventReceiver receiver, SSH2DataReader reader) { byte[] tmpdata = reader.ReadString(); string method = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); int remote_channel = reader.ReadInt32(); int window_size = reader.ReadInt32(); //skip initial window size int servermaxpacketsize = reader.ReadInt32(); tmpdata = reader.ReadString(); string host = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); int port = reader.ReadInt32(); tmpdata = reader.ReadString(); string originator_ip = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); int originator_port = reader.ReadInt32(); PortForwardingCheckResult r = receiver.CheckPortForwardingRequest(host,port,originator_ip,originator_port); SSH2DataWriter wr = new SSH2DataWriter(); if(r.allowed) { //send OPEN_CONFIRMATION SSH2Channel channel = new SSH2Channel(this, ChannelType.ForwardedRemoteToLocal, RegisterChannelEventReceiver(null, r.channel)._localID, remote_channel, servermaxpacketsize); wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION); wr.Write(remote_channel); wr.Write(channel.LocalChannelID()); wr.Write(_param.WindowSize); //initial window size wr.Write(_param.MaxPacketSize); //max packet size receiver.EstablishPortforwarding(r.channel, channel); } else { wr.WritePacketType(PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE); wr.Write(remote_channel); wr.Write(r.reason_code); wr.Write(r.reason_message); wr.Write(""); //lang tag } TransmitPacket(wr.ToByteArray()); }
/* * Format style note * ---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ---- * Comment: ******* * <base64-encoded body> * ---- END SSH2 ENCRYPTED PRIVATE KEY ---- * * body = MAGIC_VAL || body-length || type(string) || encryption-algorithm-name(string) || encrypted-body(string) * encrypted-body = array of BigInteger(algorithm-specific) */ internal static SSH2UserAuthKey FromSECSHStyleStream(StreamReader r, string passphrase) { string l = r.ReadLine(); StringBuilder buf = new StringBuilder(); while(l!="---- END SSH2 ENCRYPTED PRIVATE KEY ----") { if(l.IndexOf(':')==-1) buf.Append(l); else { while(l.EndsWith("\\")) l = r.ReadLine(); } l = r.ReadLine(); if (l == null) throw new Exception(resLoader.GetString("BrokenKeyFile")); } //r.Close(); r.Dispose(); byte[] keydata = Base64.Decode(Encoding.UTF8.GetBytes(buf.ToString())); SSH2DataReader re = new SSH2DataReader(keydata); int magic = re.ReadInt32(); if (magic != SSH_COM_MAGIC_VAL) throw new Exception(resLoader.GetString("BrokenKeyFile")); int privateKeyLen = re.ReadInt32(); byte[] tmpstr = re.ReadString(); string type = Encoding.UTF8.GetString(tmpstr, 0, tmpstr.Length); tmpstr = re.ReadString(); string ciphername = Encoding.UTF8.GetString(tmpstr, 0, tmpstr.Length); int bufLen = re.ReadInt32(); if(ciphername!="none") { CipherAlgorithm algo = CipherFactory.SSH2NameToAlgorithm(ciphername); byte[] key = PassphraseToKey(passphrase, CipherFactory.GetKeySize(algo)); Cipher c = CipherFactory.CreateCipher(SSHProtocol.SSH2, algo, key); byte[] tmp = new Byte[re.Image.Length-re.Offset]; c.Decrypt(re.Image, re.Offset, re.Image.Length-re.Offset, tmp, 0); re = new SSH2DataReader(tmp); } int parmLen = re.ReadInt32(); if(parmLen<0 || parmLen>re.Rest) throw new Exception(resLoader.GetString("WrongPassphrase")); if(type.IndexOf("if-modn")!=-1) { //mindterm mistaken this order of BigIntegers BigInteger e = re.ReadBigIntWithBits(); BigInteger d = re.ReadBigIntWithBits(); BigInteger n = re.ReadBigIntWithBits(); BigInteger u = re.ReadBigIntWithBits(); BigInteger p = re.ReadBigIntWithBits(); BigInteger q = re.ReadBigIntWithBits(); return new SSH2UserAuthKey(new RSAKeyPair(e, d, n, u, p, q)); } else if(type.IndexOf("dl-modp")!=-1) { if (re.ReadInt32() != 0) throw new Exception(resLoader.GetString("BrokenKeyFile")); BigInteger p = re.ReadBigIntWithBits(); BigInteger g = re.ReadBigIntWithBits(); BigInteger q = re.ReadBigIntWithBits(); BigInteger y = re.ReadBigIntWithBits(); BigInteger x = re.ReadBigIntWithBits(); return new SSH2UserAuthKey(new DSAKeyPair(p, g, q, y, x)); } else throw new Exception(resLoader.GetString("KeyFormatUnknown")); }
private void ServiceRequest(string servicename) { SSH2DataWriter wr = new SSH2DataWriter(); wr.WritePacketType(PacketType.SSH_MSG_SERVICE_REQUEST); wr.Write(servicename); TransmitPacket(wr.ToByteArray()); byte[] response = ReceivePacket().Data; SSH2DataReader re = new SSH2DataReader(response); PacketType t = re.ReadPacketType(); if(t!=PacketType.SSH_MSG_SERVICE_ACCEPT) { throw new Exception("service establishment failed "+t); } byte[] tmpdata = re.ReadString(); string s = Encoding.UTF8.GetString(tmpdata,0,tmpdata.Length); if(servicename!=s) throw new Exception(resLoader.GetString("ProtocolError")); }
public static bool IsPrivateKeyEncrypted(string filename) { bool returnVal = false; var fileToLaunch = StorageFile.GetFileFromPathAsync(filename); fileToLaunch.AsTask().Wait(); var streamToLaunch = fileToLaunch.AsTask().Result.OpenStreamForReadAsync(); streamToLaunch.Wait(); using (Stream s = streamToLaunch.Result) { using (StreamReader r = new StreamReader(streamToLaunch.Result, Encoding.UTF8)) { string l = r.ReadLine(); if (l == PKCS8_RSA_HEADER) { while (l != "-----END RSA PRIVATE KEY-----") { if (l.IndexOf("Proc-Type: 4,ENCRYPTED") != -1) { returnVal = true; break; } l = r.ReadLine(); if (l == null) break; } } else if (l == PKCS8_DSA_HEADER) { while (l != "-----END DSA PRIVATE KEY-----") { if (l.IndexOf("Proc-Type: 4,ENCRYPTED") != -1) { returnVal = true; break; } l = r.ReadLine(); if (l == null) break; } } else if (l == SSH_COM_HEADER) { l = r.ReadLine(); StringBuilder buf = new StringBuilder(); while(l!="---- END SSH2 ENCRYPTED PRIVATE KEY ----") { if(l.IndexOf(':')==-1) buf.Append(l); else { while(l.EndsWith("\\")) l = r.ReadLine(); } l = r.ReadLine(); if(l==null) break; } byte[] keydata = Base64.Decode(Encoding.UTF8.GetBytes(buf.ToString())); SSH2DataReader re = new SSH2DataReader(keydata); int magic = re.ReadInt32(); if (magic != SSH_COM_MAGIC_VAL) return false; // Magic number doesn't match so just say false because it will error-out anyway int privateKeyLen = re.ReadInt32(); byte[] tmpstr = re.ReadString(); string type = Encoding.UTF8.GetString(tmpstr, 0, tmpstr.Length); tmpstr = re.ReadString(); string ciphername = Encoding.UTF8.GetString(tmpstr, 0, tmpstr.Length); int bufLen = re.ReadInt32(); if (ciphername != "none") { returnVal = true; } } r.Dispose(); s.Dispose(); } } return returnVal; }
private bool VerifyHostKey(byte[] K_S, byte[] signature, byte[] hash) { SSH2DataReader re1 = new SSH2DataReader(K_S); byte[] tmpdata = re1.ReadString(); string algorithm = Encoding.UTF8.GetString(tmpdata,0,tmpdata.Length); if(algorithm!=SSH2Util.PublicKeyAlgorithmName(_cInfo._algorithmForHostKeyVerification)) throw new Exception("Protocol Error: Host Key Algorithm Mismatch"); SSH2DataReader re2 = new SSH2DataReader(signature); tmpdata = re2.ReadString(); algorithm = Encoding.UTF8.GetString(tmpdata, 0, tmpdata.Length); if(algorithm!=SSH2Util.PublicKeyAlgorithmName(_cInfo._algorithmForHostKeyVerification)) throw new Exception("Protocol Error: Host Key Algorithm Mismatch"); byte[] sigbody = re2.ReadString(); Debug.Assert(re2.Rest==0); if(_cInfo._algorithmForHostKeyVerification==PublicKeyAlgorithm.RSA) VerifyHostKeyByRSA(re1, sigbody, hash); else if(_cInfo._algorithmForHostKeyVerification==PublicKeyAlgorithm.DSA) VerifyHostKeyByDSS(re1, sigbody, hash); else throw new Exception("Bad host key algorithm "+_cInfo._algorithmForHostKeyVerification); //ask the client whether he accepts the host key if(!_startedByHost && _param.KeyCheck!=null && !_param.KeyCheck(_cInfo)) return false; else return true; }