/// <summary> /// SSH2 private key signature /// </summary> private void SSH2Sign(byte[] blob, byte[] data, uint flags) { if ((flags & SSH_AGENT_OLD_SIGNATURE) != 0) { SendFailure(); return; } SSH2UserAuthKey key = SSH2FindKey(blob); if (key == null) { SendFailure(); return; } SSH2PayloadImageBuilder image = new SSH2PayloadImageBuilder(); image.WriteString(key.Algorithm.GetAlgorithmName()); image.WriteAsString(key.Sign(data)); byte[] signatureBlob = image.GetBytes(); Send( new OpenSSHAgentForwardingMessage(OpenSSHAgentForwardingMessageType.SSH2_AGENT_SIGN_RESPONSE) .WriteAsString(signatureBlob) ); }
/// <summary> /// Constructor /// </summary> /// <param name="hostName">host name</param> /// <param name="portNumber">port number</param> /// <param name="hostKey">host key</param> public SSH2HostKeyInformationProvider(string hostName, int portNumber, PublicKey hostKey) { HostName = hostName; PortNumber = portNumber; _hostKey = hostKey; _knownHostsString = new Lazy<string>( () => { // Poderosa known_hosts format return new StringBuilder() .Append(_hostKey.Algorithm.GetAlgorithmName()) .Append(' ') .Append(Encoding.ASCII.GetString(Base64.Encode(_encodedHostKey.Value))) .ToString(); }, false ); _encodedHostKey = new Lazy<byte[]>( () => { SSH2PayloadImageBuilder image = new SSH2PayloadImageBuilder(0x10000); image.WriteString(_hostKey.Algorithm.GetAlgorithmName()); if (_hostKey is RSAPublicKey) { RSAPublicKey rsa = (RSAPublicKey)_hostKey; image.WriteBigInteger(rsa.Exponent); image.WriteBigInteger(rsa.Modulus); } else if (_hostKey is DSAPublicKey) { DSAPublicKey dsa = (DSAPublicKey)_hostKey; image.WriteBigInteger(dsa.P); image.WriteBigInteger(dsa.Q); image.WriteBigInteger(dsa.G); image.WriteBigInteger(dsa.Y); } else if (_hostKey is ECDSAPublicKey) { ECDSAPublicKey ec = (ECDSAPublicKey)_hostKey; image.WriteString(ec.CurveName); image.WriteAsString(ec.ToOctetString()); } else if (_hostKey is EDDSAPublicKey) { EDDSAPublicKey ed = (EDDSAPublicKey)_hostKey; image.WriteAsString(ed.Bytes); } else { throw new SSHException("Host key algorithm is unsupported"); } return image.GetBytes(); }, false ); }
public byte[] GetPublicKeyBlob() { SSH2PayloadImageBuilder imageBuilder = new SSH2PayloadImageBuilder() .WriteString(SSH2Util.PublicKeyAlgorithmName(_keypair.Algorithm)); _keypair.PublicKey.WriteTo(new SSH2KeyWriter(imageBuilder)); return imageBuilder.GetBytes(); }
private AuthenticationResult UserAuth() { const string sn = "ssh-connection"; if (_param.AuthenticationType == AuthenticationType.KeyboardInteractive) { Transmit( new SSH2Packet(SSH2PacketType.SSH_MSG_USERAUTH_REQUEST) .WriteUTF8String(_param.UserName) .WriteString(sn) .WriteString("keyboard-interactive") .WriteString("") //lang .WriteString("") //submethod ); TraceTransmissionEvent(SSH2PacketType.SSH_MSG_USERAUTH_REQUEST, "starting keyboard-interactive authentication"); _authenticationResult = ProcessAuthenticationResponse(); } else { if (_param.AuthenticationType == AuthenticationType.Password) { //Password authentication Transmit( new SSH2Packet(SSH2PacketType.SSH_MSG_USERAUTH_REQUEST) .WriteUTF8String(_param.UserName) .WriteString(sn) .WriteString("password") .WriteBool(false) .WriteUTF8String(_param.Password) ); TraceTransmissionEvent(SSH2PacketType.SSH_MSG_USERAUTH_REQUEST, "starting password authentication"); } else { //public key authentication SSH2UserAuthKey kp = SSH2UserAuthKey.FromSECSHStyleFile(_param.IdentityFile, _param.Password); string algorithmName = SSH2Util.PublicKeyAlgorithmName(kp.Algorithm); // construct a packet except signature SSH2Packet packet = new SSH2Packet(SSH2PacketType.SSH_MSG_USERAUTH_REQUEST) .WriteUTF8String(_param.UserName) .WriteString(sn) .WriteString("publickey") .WriteBool(true) .WriteString(algorithmName) .WriteAsString(kp.GetPublicKeyBlob()); // take payload image for the signature byte[] payloadImage = packet.GetPayloadBytes(); // construct the signature source SSH2PayloadImageBuilder workPayload = new SSH2PayloadImageBuilder() .WriteAsString(_sessionID) .Write(payloadImage); // take a signature blob byte[] signatureBlob = kp.Sign(workPayload.GetBytes()); // encode signature (RFC4253) workPayload.Clear(); byte[] signature = workPayload .WriteString(algorithmName) .WriteAsString(signatureBlob) .GetBytes(); // append signature to the packet packet.WriteAsString(signature); Transmit(packet); TraceTransmissionEvent(SSH2PacketType.SSH_MSG_USERAUTH_REQUEST, "starting public key authentication"); } _authenticationResult = ProcessAuthenticationResponse(); if (_authenticationResult == AuthenticationResult.Failure) throw new SSHException(Strings.GetString("AuthenticationFailed")); } return _authenticationResult; }