New features
- Add support for PKCS#8 private key files
- Add additional async overloads on SftpClient
- Add support for OpenSSH certificates
- Add support for
chacha20-poly1305@openssh.com
cipher algorithm - Increase support for
aes*-gcm@openssh.com
andzlib@openssh.com
on lower targets
This release takes a dependency on BouncyCastle in an effort to eliminate primitive crypto code from the library. It also takes a dependency on System.Formats.Asn1 on lower targets.
Breaking changes
- A number of legacy algorithms were dropped in #1442
- The implementation of DSA was changed from using handwritten code to using System.Cryptography in #1458. See the PR description for behaviour changes this could cause.
Renci.SshNet.Common.BigInteger
was deleted and its uses replaced withSystem.Numerics.BigInteger
in #1469Renci.SshNet.Common.DerData
andRenci.SshNet.Common.ObjectIdentifier
were deleted in #1490 and uses replaced with System.Formats.Asn1- See the full API diff at the end
What's Changed
- Make ZlibOpenSsh public by @Rob-Hague in #1433
- Docs updates by @Rob-Hague in #1432
- Ref System.Memory for net462 and netstandard2.0 by @scott-xu in #1417
- Remove some #ifdefs with System.Memory by @Rob-Hague in #1434
- Allow empty softwareversion string (#822) by @doerig in #1441
- .NET 9: don't treat NuGet audit Warnings as Errors and fix warning by @mus65 in #1443
- Stabilise some more tests by @Rob-Hague in #1438
- Replace internal BouncyCastle with NuGet package by @mus65 in #1370
- Drop legacy algorithms part 1 by @Rob-Hague in #1442
- Clean up Abstractions / use HashData by @mus65 in #1451
- [Curve25519] Use BouncyCastle instead of Chaos.NaCl by @scott-xu in #1447
- [Ed25519] Use BouncyCastle instead of Chaos.NaCl by @scott-xu in #1448
- Remove Chaos.Nacl by @scott-xu in #1455
- [Zlib] Falls back to use BouncyCastle if BCL doesn't support by @scott-xu in #1453
- Add support for AEAD ChaCha20Poly1305 Cipher by @scott-xu in #1416
- Integrate with Nerdbank.GitVersioning by @scott-xu in #1299
- Use BCL ECDiffieHellman for KeyExchange instead of BouncyCastle (.NET 8.0 onward only) by @scott-xu in #1371
- Enable all net48 integration tests and stabilise tests by @scott-xu in #1456
- Revert mono/.NET Framework integration tests by @Rob-Hague in #1462
- Add another allowed SocketError value in tests by @Rob-Hague in #1457
- Use System.Security.Cryptography for DSA by @Rob-Hague in #1458
- Use ExceptionDispatchInfo to retain call stack in AsyncResult.EndInvoke() by @scott-xu in #1470
- Port shared tests folder by @Rob-Hague in #1467
- [AesGcm] Falls back to use BouncyCastle if BCL doesn't support by @scott-xu in #1450
- another .NET 9 SDK Build fix by @mus65 in #1475
- [ECDsa] Falls back to use BouncyCastle if BCL (Mono) doesn't support by @scott-xu in #1461
- Use System.Numerics.BigInteger by @Rob-Hague in #1469
- Remove unnecessary finalizers by @Rob-Hague in #1209
- fix "client not connected" after SFTP reconnect by @mus65 in #1484
- [Private Key] Support more ciphers for OpenSSH private key decryption by @scott-xu in #1487
- Migrate to NuGet Central Package Management by @mus65 in #1488
- Ref System.Formats.Asn1 nuget package by @scott-xu in #1490
- Update dependencies by @mus65 in #1492
- Miscellaneous cleanup/throw helpers by @Rob-Hague in #1491
- Update SonarAnalyzer.CSharp by @mus65 in #1494
- Add support for OpenSSL PKCS#8 private key format by @scott-xu in #1496
- Add interface to SshClient by @eugencowie in #1499
- Added ExistsAsync and GetAsync to SftpClient by @snargledorf in #1501
- fix ConnectAsync not respecting the connection timeout by @mus65 in #1502
- Added ChangeDirectoryAsync to SftpClient by @snargledorf in #1504
- Added CreateDirectoryAsync to SftpClient by @snargledorf in #1505
- Added support for deleting directories asynchronously by @snargledorf in #1503
- Fix sftp async methods not observing error conditions by @Rob-Hague in #1510
- Add support for OpenSSH certificates by @Rob-Hague in #1498
- Swallow ObjectDisposed on SFTP wait handle when receiving late response by @Rob-Hague in #1531
- Bump test dependencies by @Rob-Hague in #1532
New Contributors
- @doerig made their first contribution in #1441
- @eugencowie made their first contribution in #1499
- @snargledorf made their first contribution in #1501
Full Changelog: 2024.1.0...2024.2.0
API diff
namespace Renci.SshNet
{
public interface IBaseClient : System.IDisposable
{
+ event System.EventHandler<Renci.SshNet.Common.SshIdentificationEventArgs>? ServerIdentificationReceived;
}
public interface ISftpClient : Renci.SshNet.IBaseClient, System.IDisposable
{
+ System.Threading.Tasks.Task ChangeDirectoryAsync(string path, System.Threading.CancellationToken cancellationToken = default);
+ System.Threading.Tasks.Task CreateDirectoryAsync(string path, System.Threading.CancellationToken cancellationToken = default);
+ System.Threading.Tasks.Task DeleteAsync(string path, System.Threading.CancellationToken cancellationToken = default);
+ System.Threading.Tasks.Task DeleteDirectoryAsync(string path, System.Threading.CancellationToken cancellationToken = default);
}
+ public interface ISshClient : Renci.SshNet.IBaseClient, System.IDisposable
+ {
+ System.Collections.Generic.IEnumerable<Renci.SshNet.ForwardedPort> ForwardedPorts { get; }
+ void AddForwardedPort(Renci.SshNet.ForwardedPort port);
+ Renci.SshNet.SshCommand CreateCommand(string commandText);
+ Renci.SshNet.SshCommand CreateCommand(string commandText, System.Text.Encoding encoding);
+ Renci.SshNet.Shell CreateShell(System.IO.Stream input, System.IO.Stream output, System.IO.Stream extendedOutput);
+ Renci.SshNet.Shell CreateShell(System.Text.Encoding encoding, string input, System.IO.Stream output, System.IO.Stream extendedOutput);
+ Renci.SshNet.Shell CreateShell(System.IO.Stream input, System.IO.Stream output, System.IO.Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, System.Collections.Generic.IDictionary<Renci.SshNet.Common.TerminalModes, uint> terminalModes);
+ Renci.SshNet.Shell CreateShell(System.IO.Stream input, System.IO.Stream output, System.IO.Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, System.Collections.Generic.IDictionary<Renci.SshNet.Common.TerminalModes, uint>? terminalModes, int bufferSize);
+ Renci.SshNet.Shell CreateShell(System.Text.Encoding encoding, string input, System.IO.Stream output, System.IO.Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, System.Collections.Generic.IDictionary<Renci.SshNet.Common.TerminalModes, uint> terminalModes);
+ Renci.SshNet.Shell CreateShell(System.Text.Encoding encoding, string input, System.IO.Stream output, System.IO.Stream extendedOutput, string terminalName, uint columns, uint rows, uint width, uint height, System.Collections.Generic.IDictionary<Renci.SshNet.Common.TerminalModes, uint>? terminalModes, int bufferSize);
+ Renci.SshNet.Shell CreateShellNoTerminal(System.IO.Stream input, System.IO.Stream output, System.IO.Stream extendedOutput, int bufferSize = -1);
+ Renci.SshNet.ShellStream CreateShellStream(string terminalName, uint columns, uint rows, uint width, uint height, int bufferSize);
+ Renci.SshNet.ShellStream CreateShellStream(string terminalName, uint columns, uint rows, uint width, uint height, int bufferSize, System.Collections.Generic.IDictionary<Renci.SshNet.Common.TerminalModes, uint>? terminalModeValues);
+ Renci.SshNet.ShellStream CreateShellStreamNoTerminal(int bufferSize = -1);
+ void RemoveForwardedPort(Renci.SshNet.ForwardedPort port);
+ Renci.SshNet.SshCommand RunCommand(string commandText);
+ }
public class PrivateKeyConnectionInfo : Renci.SshNet.ConnectionInfo, System.IDisposable
{
- public PrivateKeyConnectionInfo(string host, string username, params Renci.SshNet.PrivateKeyFile[] keyFiles) { }
+ public PrivateKeyConnectionInfo(string host, string username, params Renci.SshNet.IPrivateKeySource[] keyFiles) { }
}
public class PrivateKeyFile : Renci.SshNet.IPrivateKeySource, System.IDisposable
{
- public PrivateKeyFile(System.IO.Stream privateKey, string passPhrase) { }
+ public PrivateKeyFile(System.IO.Stream privateKey, string? passPhrase) { }
- public PrivateKeyFile(string fileName, string passPhrase) { }
+ public PrivateKeyFile(string fileName, string? passPhrase) { }
+ public PrivateKeyFile(System.IO.Stream privateKey, string? passPhrase, System.IO.Stream? certificate) { }
+ public PrivateKeyFile(string fileName, string? passPhrase, string? certificateFileName) { }
+ public Renci.SshNet.Security.Certificate? Certificate { get; }
}
public class SftpClient : Renci.SshNet.BaseClient, Renci.SshNet.IBaseClient, Renci.SshNet.ISftpClient, System.IDisposable
{
+ public System.Threading.Tasks.Task ChangeDirectoryAsync(string path, System.Threading.CancellationToken cancellationToken = default) { }
+ public System.Threading.Tasks.Task CreateDirectoryAsync(string path, System.Threading.CancellationToken cancellationToken = default) { }
+ public System.Threading.Tasks.Task DeleteAsync(string path, System.Threading.CancellationToken cancellationToken = default) { }
+ public System.Threading.Tasks.Task DeleteDirectoryAsync(string path, System.Threading.CancellationToken cancellationToken = default) { }
+ public System.Threading.Tasks.Task<bool> ExistsAsync(string path, System.Threading.CancellationToken cancellationToken = default) { }
+ public System.Threading.Tasks.Task<Renci.SshNet.Sftp.ISftpFile> GetAsync(string path, System.Threading.CancellationToken cancellationToken) { }
}
- public class SshClient : Renci.SshNet.BaseClient
+ public class SshClient : Renci.SshNet.BaseClient, Renci.SshNet.IBaseClient, Renci.SshNet.ISshClient, System.IDisposable
{
}
}
namespace Renci.SshNet.Common
{
- public struct BigInteger : System.IComparable, System.IComparable<Renci.SshNet.Common.BigInteger>, System.IEquatable<Renci.SshNet.Common.BigInteger>, System.IFormattable
- {
- }
- public class DerData
- {
- public DerData() { }
- public DerData(byte[] data, bool construct = false) { }
- public bool IsEndOfData { get; }
- public byte[] Encode() { }
- public Renci.SshNet.Common.BigInteger ReadBigInteger() { }
- public byte[] ReadBitString() { }
- public byte ReadByte() { }
- public byte[] ReadBytes(int length) { }
- public int ReadInteger() { }
- public int ReadLength() { }
- public byte[] ReadObject() { }
- public byte[] ReadOctetString() { }
- public void Write(Renci.SshNet.Common.BigInteger data) { }
- public void Write(Renci.SshNet.Common.DerData data) { }
- public void Write(Renci.SshNet.Common.ObjectIdentifier identifier) { }
- public void Write(bool data) { }
- public void Write(byte[] data) { }
- public void Write(uint data) { }
- public void WriteBitstring(byte[] data) { }
- public void WriteBytes(System.Collections.Generic.IEnumerable<byte> data) { }
- public void WriteNull() { }
- public void WriteObjectIdentifier(byte[] bytes) { }
- }
public class HostKeyEventArgs : System.EventArgs
{
+ public Renci.SshNet.Security.Certificate? Certificate { get; }
}
- public struct ObjectIdentifier
- {
- public ObjectIdentifier(params ulong[] identifiers) { }
- public ulong[] Identifiers { get; }
- }
public abstract class SshData
{
- protected void Write(Renci.SshNet.Common.BigInteger data) { }
+ protected void Write(System.Numerics.BigInteger data) { }
}
public class SshDataStream : System.IO.MemoryStream
{
- public Renci.SshNet.Common.BigInteger ReadBigInt() { }
+ public System.Numerics.BigInteger ReadBigInt() { }
- public void Write(Renci.SshNet.Common.BigInteger data) { }
+ public void Write(System.Numerics.BigInteger data) { }
}
}
namespace Renci.SshNet.Compression
{
+ public class Zlib : Renci.SshNet.Compression.Compressor
+ {
+ public Zlib() { }
+ protected Zlib(bool delayedCompression) { }
+ public override string Name { get; }
+ protected override byte[] CompressCore(byte[] data, int offset, int length) { }
+ protected override byte[] DecompressCore(byte[] data, int offset, int length) { }
+ protected override void Dispose(bool disposing) { }
+ }
+ public class ZlibOpenSsh : Renci.SshNet.Compression.Zlib
+ {
+ public ZlibOpenSsh() { }
+ public override string Name { get; }
+ }
}
namespace Renci.SshNet.Messages.Transport
{
public class KeyExchangeDhGroupExchangeGroup : Renci.SshNet.Messages.Message
{
- public Renci.SshNet.Common.BigInteger SafePrime { get; }
- public Renci.SshNet.Common.BigInteger SubGroup { get; }
+ public System.Numerics.BigInteger SafePrime { get; }
+ public System.Numerics.BigInteger SubGroup { get; }
}
}
namespace Renci.SshNet.Security
{
+ public class Certificate
+ {
+ public Certificate(byte[] data) { }
+ public byte[] CertificateAuthorityKey { get; }
+ public string CertificateAuthorityKeyFingerPrint { get; }
+ public System.Collections.Generic.IDictionary<string, string> CriticalOptions { get; }
+ public System.Collections.Generic.IDictionary<string, string> Extensions { get; }
+ public Renci.SshNet.Security.Key Key { get; }
+ public string KeyId { get; }
+ public string Name { get; }
+ public byte[] Nonce { get; }
+ public ulong Serial { get; }
+ public byte[] Signature { get; }
+ public Renci.SshNet.Security.Certificate.CertificateType Type { get; }
+ public System.DateTimeOffset ValidAfter { get; }
+ public ulong ValidAfterUnixSeconds { get; }
+ public System.DateTimeOffset ValidBefore { get; }
+ public ulong ValidBeforeUnixSeconds { get; }
+ public System.Collections.Generic.IList<string> ValidPrincipals { get; }
+ public enum CertificateType : uint
+ {
+ User = 1u,
+ Host = 2u,
+ }
+ }
- public class CertificateHostAlgorithm : Renci.SshNet.Security.HostAlgorithm
+ public class CertificateHostAlgorithm : Renci.SshNet.Security.KeyHostAlgorithm
{
- public CertificateHostAlgorithm(string name) { }
+ public CertificateHostAlgorithm(string name, Renci.SshNet.Security.Certificate certificate, System.Collections.Generic.IReadOnlyDictionary<string, System.Func<byte[], Renci.SshNet.Security.KeyHostAlgorithm>> keyAlgorithms) { }
+ public CertificateHostAlgorithm(string name, Renci.SshNet.Security.Key privateKey, Renci.SshNet.Security.Certificate certificate) { }
+ public CertificateHostAlgorithm(string name, Renci.SshNet.Security.Certificate certificate, Renci.SshNet.Security.Cryptography.DigitalSignature digitalSignature, System.Collections.Generic.IReadOnlyDictionary<string, System.Func<byte[], Renci.SshNet.Security.KeyHostAlgorithm>> keyAlgorithms) { }
+ public CertificateHostAlgorithm(string name, Renci.SshNet.Security.Key privateKey, Renci.SshNet.Security.Certificate certificate, Renci.SshNet.Security.Cryptography.DigitalSignature digitalSignature) { }
+ public Renci.SshNet.Security.Certificate Certificate { get; }
}
public class DsaKey : Renci.SshNet.Security.Key, System.IDisposable
{
- public DsaKey(Renci.SshNet.Common.BigInteger p, Renci.SshNet.Common.BigInteger q, Renci.SshNet.Common.BigInteger g, Renci.SshNet.Common.BigInteger y, Renci.SshNet.Common.BigInteger x) { }
+ public DsaKey(System.Numerics.BigInteger p, System.Numerics.BigInteger q, System.Numerics.BigInteger g, System.Numerics.BigInteger y, System.Numerics.BigInteger x) { }
- public Renci.SshNet.Common.BigInteger G { get; }
+ public System.Numerics.BigInteger G { get; }
- public Renci.SshNet.Common.BigInteger P { get; }
- public override Renci.SshNet.Common.BigInteger[] Public { get; }
- public Renci.SshNet.Common.BigInteger Q { get; }
- public Renci.SshNet.Common.BigInteger X { get; }
- public Renci.SshNet.Common.BigInteger Y { get; }
+ public System.Numerics.BigInteger P { get; }
+ public override System.Numerics.BigInteger[] Public { get; }
+ public System.Numerics.BigInteger Q { get; }
+ public System.Numerics.BigInteger X { get; }
+ public System.Numerics.BigInteger Y { get; }
}
public class ED25519Key : Renci.SshNet.Security.Key, System.IDisposable
{
- public override Renci.SshNet.Common.BigInteger[] Public { get; }
+ public override System.Numerics.BigInteger[] Public { get; }
}
public class EcdsaKey : Renci.SshNet.Security.Key, System.IDisposable
{
- public byte[] PrivateKey { get; }
- public override Renci.SshNet.Common.BigInteger[] Public { get; }
+ public byte[]? PrivateKey { get; }
+ public override System.Numerics.BigInteger[] Public { get; }
}
public abstract class Key
{
- public abstract Renci.SshNet.Common.BigInteger[] Public { get; }
+ public abstract System.Numerics.BigInteger[] Public { get; }
}
public class RsaKey : Renci.SshNet.Security.Key, System.IDisposable
{
- public RsaKey(Renci.SshNet.Common.BigInteger modulus, Renci.SshNet.Common.BigInteger exponent, Renci.SshNet.Common.BigInteger d, Renci.SshNet.Common.BigInteger p, Renci.SshNet.Common.BigInteger q, Renci.SshNet.Common.BigInteger inverseQ) { }
- public Renci.SshNet.Common.BigInteger D { get; }
- public Renci.SshNet.Common.BigInteger DP { get; }
- public Renci.SshNet.Common.BigInteger DQ { get; }
+ public RsaKey(System.Numerics.BigInteger modulus, System.Numerics.BigInteger exponent, System.Numerics.BigInteger d, System.Numerics.BigInteger p, System.Numerics.BigInteger q, System.Numerics.BigInteger inverseQ) { }
+ public System.Numerics.BigInteger D { get; }
+ public System.Numerics.BigInteger DP { get; }
+ public System.Numerics.BigInteger DQ { get; }
- public Renci.SshNet.Common.BigInteger Exponent { get; }
- public Renci.SshNet.Common.BigInteger InverseQ { get; }
+ public System.Numerics.BigInteger Exponent { get; }
+ public System.Numerics.BigInteger InverseQ { get; }
- public Renci.SshNet.Common.BigInteger Modulus { get; }
- public Renci.SshNet.Common.BigInteger P { get; }
- public override Renci.SshNet.Common.BigInteger[] Public { get; }
- public Renci.SshNet.Common.BigInteger Q { get; }
+ public System.Numerics.BigInteger Modulus { get; }
+ public System.Numerics.BigInteger P { get; }
+ public override System.Numerics.BigInteger[] Public { get; }
+ public System.Numerics.BigInteger Q { get; }
}
public sealed class SshKeyData : Renci.SshNet.Common.SshData
{
- public SshKeyData(string name, Renci.SshNet.Common.BigInteger[] keys) { }
+ public SshKeyData(string name, System.Numerics.BigInteger[] keys) { }
- public Renci.SshNet.Common.BigInteger[] Keys { get; }
+ public System.Numerics.BigInteger[] Keys { get; }
}
}
namespace Renci.SshNet.Security.Cryptography
{
public abstract class Cipher
{
- public byte[] Decrypt(byte[] input) { }
+ public virtual byte[] Decrypt(byte[] input) { }
}
- public class HMACMD5 : System.Security.Cryptography.HMACMD5
- {
- public HMACMD5(byte[] key) { }
- public HMACMD5(byte[] key, int hashSize) { }
- public override int HashSize { get; }
- protected override byte[] HashFinal() { }
- }
- public class HMACSHA1 : System.Security.Cryptography.HMACSHA1
- {
- public HMACSHA1(byte[] key) { }
- public HMACSHA1(byte[] key, int hashSize) { }
- public override int HashSize { get; }
- protected override byte[] HashFinal() { }
- }
- public class HMACSHA256 : System.Security.Cryptography.HMACSHA256
- {
- public HMACSHA256(byte[] key) { }
- public HMACSHA256(byte[] key, int hashSize) { }
- public override int HashSize { get; }
- protected override byte[] HashFinal() { }
- }
- public class HMACSHA384 : System.Security.Cryptography.HMACSHA384
- {
- public HMACSHA384(byte[] key) { }
- public HMACSHA384(byte[] key, int hashSize) { }
- public override int HashSize { get; }
- protected override byte[] HashFinal() { }
- }
- public class HMACSHA512 : System.Security.Cryptography.HMACSHA512
- {
- public HMACSHA512(byte[] key) { }
- public HMACSHA512(byte[] key, int hashSize) { }
- public override int HashSize { get; }
- protected override byte[] HashFinal() { }
- }
- public abstract class StreamCipher : Renci.SshNet.Security.Cryptography.SymmetricCipher
- {
- protected StreamCipher(byte[] key) { }
- }
}
namespace Renci.SshNet.Security.Cryptography.Ciphers
{
- public sealed class Arc4Cipher : Renci.SshNet.Security.Cryptography.StreamCipher
- {
- public Arc4Cipher(byte[] key, bool dischargeFirstBytes) { }
- public override byte MinimumSize { get; }
- public override byte[] Decrypt(byte[] input, int offset, int length) { }
- public override byte[] Encrypt(byte[] input, int offset, int length) { }
- }
- public sealed class BlowfishCipher : Renci.SshNet.Security.Cryptography.BlockCipher
- {
- public BlowfishCipher(byte[] key, Renci.SshNet.Security.Cryptography.Ciphers.CipherMode mode, Renci.SshNet.Security.Cryptography.Ciphers.CipherPadding padding) { }
- public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { }
- public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { }
- }
- public sealed class CastCipher : Renci.SshNet.Security.Cryptography.BlockCipher
- {
- public CastCipher(byte[] key, Renci.SshNet.Security.Cryptography.Ciphers.CipherMode mode, Renci.SshNet.Security.Cryptography.Ciphers.CipherPadding padding) { }
- public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { }
- public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { }
- }
- public sealed class SerpentCipher : Renci.SshNet.Security.Cryptography.BlockCipher
- {
- public SerpentCipher(byte[] key, Renci.SshNet.Security.Cryptography.Ciphers.CipherMode mode, Renci.SshNet.Security.Cryptography.Ciphers.CipherPadding padding) { }
- public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { }
- public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { }
- }
- public sealed class TwofishCipher : Renci.SshNet.Security.Cryptography.BlockCipher
- {
- public TwofishCipher(byte[] key, Renci.SshNet.Security.Cryptography.Ciphers.CipherMode mode, Renci.SshNet.Security.Cryptography.Ciphers.CipherPadding padding) { }
- public override int DecryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { }
- public override int EncryptBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset) { }
- }
}
namespace Renci.SshNet.Security.Cryptography.Ciphers.Paddings
{
- public class PKCS5Padding : Renci.SshNet.Security.Cryptography.Ciphers.CipherPadding
- public PKCS5Padding() { }
- public override byte[] Pad(byte[] input, int offset, int length, int paddinglength) { }
- public override byte[] Pad(int blockSize, byte[] input, int offset, int length) { }
- }
}
namespace Renci.SshNet.Sftp
{
public interface ISftpFile
{
+ System.Threading.Tasks.Task DeleteAsync(System.Threading.CancellationToken cancellationToken = default);
}
public sealed class SftpFile : Renci.SshNet.Sftp.ISftpFile
{
+ public System.Threading.Tasks.Task DeleteAsync(System.Threading.CancellationToken cancellationToken = default) { }
}
}