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 SSHException("service establishment failed "+t); } string s = Encoding.ASCII.GetString(re.ReadString()); if(servicename!=s) throw new SSHException("protocol error"); }
private bool ProcessPacket(SSH2Packet packet) { SSH2DataReader r = new SSH2DataReader(packet.Data); PacketType pt = r.ReadPacketType(); //Debug.WriteLine("ProcessPacket pt="+pt); if(pt==PacketType.SSH_MSG_DISCONNECT) { int errorcode = r.ReadInt32(); //string description = Encoding.ASCII.GetString(r.ReadString()); _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 SSHException("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; } }
private void ProcessPortforwardingRequest(ISSHConnectionEventReceiver receiver, SSH2DataReader reader) { string method = Encoding.ASCII.GetString(reader.ReadString()); int remote_channel = reader.ReadInt32(); int window_size = reader.ReadInt32(); //skip initial window size int servermaxpacketsize = reader.ReadInt32(); string host = Encoding.ASCII.GetString(reader.ReadString()); int port = reader.ReadInt32(); string originator_ip = Encoding.ASCII.GetString(reader.ReadString()); 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()); }
//synchronous reception internal SSH2Packet ReceivePacket() { while(true) { SSH2Packet p = null; SynchronizedSSH2PacketHandler handler = (SynchronizedSSH2PacketHandler)_packetBuilder.Handler; if(!handler.HasPacket) { handler.Wait(); if(handler.State==ReceiverState.Error) throw new SSHException(handler.ErrorMessage); else if(handler.State==ReceiverState.Closed) throw new SSHException("socket closed"); } p = handler.PopPacket(); 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 AuthenticationResult ProcessAuthenticationResponse() { do { SSH2DataReader response = new SSH2DataReader(ReceivePacket().Data); PacketType h = response.ReadPacketType(); if(h==PacketType.SSH_MSG_USERAUTH_FAILURE) { string msg = Encoding.ASCII.GetString(response.ReadString()); return AuthenticationResult.Failure; } else if(h==PacketType.SSH_MSG_USERAUTH_BANNER) { Debug.WriteLine("USERAUTH_BANNER"); } else if(h==PacketType.SSH_MSG_USERAUTH_SUCCESS) { _packetBuilder.Handler = new CallbackSSH2PacketHandler(this); return AuthenticationResult.Success; //successfully exit } else if(h==PacketType.SSH_MSG_USERAUTH_INFO_REQUEST) { string name = Encoding.ASCII.GetString(response.ReadString()); string inst = Encoding.ASCII.GetString(response.ReadString()); string lang = Encoding.ASCII.GetString(response.ReadString()); int num = response.ReadInt32(); string[] prompts = new string[num]; for(int i=0; i<num; i++) { prompts[i] = Encoding.ASCII.GetString(response.ReadString()); bool echo = response.ReadBool(); } _eventReceiver.OnAuthenticationPrompt(prompts); return AuthenticationResult.Prompt; } else throw new SSHException("protocol error: unexpected packet type "+h); } while(true); }
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(); string msg = Encoding.ASCII.GetString(reader.ReadString()); 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); }
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(); string msg = Encoding.ASCII.GetString(reader.ReadString()); receiver.OnChannelError(null, msg); } Close(); } else { _remoteID = reader.ReadInt32(); _serverMaxPacketSize = reader.ReadInt32(); _negotiationStatus = 0; receiver.OnChannelReady(); } } else Debug.Assert(false); }
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, new SHA1CryptoServiceProvider().ComputeHash(hash)); _cInfo._hostkey = pk; }
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; 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(); 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: { string request = Encoding.ASCII.GetString(re.ReadString()); bool reply = re.ReadBool(); if(request=="exit-status") { int status = re.ReadInt32(); } else if(reply) { //we reject unknown requests including keep-alive check SSH2DataWriter wr = new SSH2DataWriter(); wr.Write((byte)PacketType.SSH_MSG_CHANNEL_FAILURE); wr.Write(_remoteID); TransmitPacket(wr.ToByteArray()); } } 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("Unknown Packet "+pt); break; } } }
private bool VerifyHostKey(byte[] K_S, byte[] signature, byte[] hash) { SSH2DataReader re1 = new SSH2DataReader(K_S); string algorithm = Encoding.ASCII.GetString(re1.ReadString()); if(algorithm!=SSH2Util.PublicKeyAlgorithmName(_cInfo._algorithmForHostKeyVerification)) throw new SSHException("Protocol Error: Host Key Algorithm Mismatch"); SSH2DataReader re2 = new SSH2DataReader(signature); algorithm = Encoding.ASCII.GetString(re2.ReadString()); if(algorithm!=SSH2Util.PublicKeyAlgorithmName(_cInfo._algorithmForHostKeyVerification)) throw new SSHException("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 SSHException("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; }
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, new SHA1CryptoServiceProvider().ComputeHash(hash)); _cInfo._hostkey = pk; }
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 SSHException(String.Format("Server response is not SSH_MSG_KEXINIT but {0}", head[0])); Encoding enc = Encoding.ASCII; string kex = enc.GetString(re.ReadString()); _cInfo._supportedKEXAlgorithms = kex; CheckAlgorithmSupport("keyexchange", kex, "diffie-hellman-group1-sha1"); string host_key = enc.GetString(re.ReadString()); _cInfo._supportedHostKeyAlgorithms = host_key; _cInfo._algorithmForHostKeyVerification = DecideHostKeyAlgorithm(host_key); string enc_cs = enc.GetString(re.ReadString()); _cInfo._supportedCipherAlgorithms = enc_cs; _cInfo._algorithmForTransmittion = DecideCipherAlgorithm(enc_cs); string enc_sc = enc.GetString(re.ReadString()); _cInfo._algorithmForReception = DecideCipherAlgorithm(enc_sc); string mac_cs = enc.GetString(re.ReadString()); CheckAlgorithmSupport("mac", mac_cs, "hmac-sha1"); string mac_sc = enc.GetString(re.ReadString()); CheckAlgorithmSupport("mac", mac_sc, "hmac-sha1"); string comp_cs = enc.GetString(re.ReadString()); CheckAlgorithmSupport("compression", comp_cs, "none"); string comp_sc = enc.GetString(re.ReadString()); CheckAlgorithmSupport("compression", comp_sc, "none"); string lang_cs = enc.GetString(re.ReadString()); string lang_sc = enc.GetString(re.ReadString()); bool flag = re.ReadBool(); int reserved = re.ReadInt32(); Debug.Assert(re.Rest==0); if(flag) throw new SSHException("Algorithm negotiation failed"); }
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 SSHException(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 = new SHA1CryptoServiceProvider().ComputeHash(wr.ToByteArray()); if(!VerifyHostKey(key_and_cert, signature, _hash)) return false; //Debug.WriteLine("hash="+DebugUtil.DumpByteArray(hash)); if(_sessionID==null) _sessionID = _hash; return 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) */ public static SSH2UserAuthKey FromSECSHStyleStream(Stream strm, string passphrase) { StreamReader r = new StreamReader(strm, Encoding.ASCII); string l = r.ReadLine(); if (l == null || l != "---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----") { throw new SSHException("Wrong key format"); } 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 SSHException("Key is broken"); } } r.Close(); byte[] keydata = Base64.Decode(Encoding.ASCII.GetBytes(buf.ToString())); //Debug.WriteLine(DebugUtil.DumpByteArray(keydata)); /* * FileStream fs = new FileStream("C:\\IOPort\\keydata1.bin", FileMode.Create); * fs.Write(keydata, 0, keydata.Length); * fs.Close(); */ SSH2DataReader re = new SSH2DataReader(keydata); int magic = re.ReadInt32(); if (magic != MAGIC_VAL) { throw new SSHException("key file is broken"); } int privateKeyLen = re.ReadInt32(); string type = Encoding.ASCII.GetString(re.ReadString()); string ciphername = Encoding.ASCII.GetString(re.ReadString()); 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 SSHException(Strings.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 SSHException("DSS Private Key File is broken"); } 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 SSHException("unknown authentication method " + type); } }
/* * 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) */ public static SSH2UserAuthKey FromSECSHStyleStream(Stream strm, string passphrase) { StreamReader r = new StreamReader(strm, Encoding.ASCII); string l = r.ReadLine(); if(l==null || l!="---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----") throw new SSHException("Wrong key format"); 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 SSHException("Key is broken"); } r.Close(); byte[] keydata = Base64.Decode(Encoding.ASCII.GetBytes(buf.ToString())); //Debug.WriteLine(DebugUtil.DumpByteArray(keydata)); /* FileStream fs = new FileStream("C:\\IOPort\\keydata1.bin", FileMode.Create); fs.Write(keydata, 0, keydata.Length); fs.Close(); */ SSH2DataReader re = new SSH2DataReader(keydata); int magic = re.ReadInt32(); if(magic!=MAGIC_VAL) throw new SSHException("key file is broken"); int privateKeyLen = re.ReadInt32(); string type = Encoding.ASCII.GetString(re.ReadString()); string ciphername = Encoding.ASCII.GetString(re.ReadString()); 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 SSHException(Strings.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 SSHException("DSS Private Key File is broken"); 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 SSHException("unknown authentication method "+type); }
public static SSH2UserAuthKey FromByteArray(byte[] keydata, string passphrase) { SSH2DataReader re = new SSH2DataReader(keydata); int magic = re.ReadInt32(); if (magic != MAGIC_VAL) { throw new SSHException("key file is broken"); } int privateKeyLen = re.ReadInt32(); string type = Encoding.ASCII.GetString(re.ReadString()); string ciphername = Encoding.ASCII.GetString(re.ReadString()); 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 SSHException(Strings.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 SSHException("DSS Private Key File is broken"); } 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 SSHException("unknown authentication method " + type); } }