using System; using Renci.SshNet.Common; using Renci.SshNet.Security.Cryptography; namespace Renci.SshNet.Security { /// /// Contains RSA private and public key /// public class RsaKey : Key, IDisposable { private bool _isDisposed; /// /// Gets the Key String. /// public override string ToString() { return "ssh-rsa"; } /// /// Gets the modulus. /// public BigInteger Modulus { get { return _privateKey[0]; } } /// /// Gets the exponent. /// public BigInteger Exponent { get { return _privateKey[1]; } } /// /// Gets the D. /// public BigInteger D { get { if (_privateKey.Length > 2) { return _privateKey[2]; } return BigInteger.Zero; } } /// /// Gets the P. /// public BigInteger P { get { if (_privateKey.Length > 3) { return _privateKey[3]; } return BigInteger.Zero; } } /// /// Gets the Q. /// public BigInteger Q { get { if (_privateKey.Length > 4) { return _privateKey[4]; } return BigInteger.Zero; } } /// /// Gets the DP. /// public BigInteger DP { get { if (_privateKey.Length > 5) { return _privateKey[5]; } return BigInteger.Zero; } } /// /// Gets the DQ. /// public BigInteger DQ { get { if (_privateKey.Length > 6) { return _privateKey[6]; } return BigInteger.Zero; } } /// /// Gets the inverse Q. /// public BigInteger InverseQ { get { if (_privateKey.Length > 7) { return _privateKey[7]; } return BigInteger.Zero; } } /// /// Gets the length of the key. /// /// /// The length of the key. /// public override int KeyLength { get { return Modulus.BitLength; } } private RsaDigitalSignature _digitalSignature; /// /// Gets the digital signature. /// protected override DigitalSignature DigitalSignature { get { _digitalSignature ??= new RsaDigitalSignature(this); return _digitalSignature; } } /// /// Gets or sets the public. /// /// /// The public. /// public override BigInteger[] Public { get { return new[] { Exponent, Modulus }; } set { if (value.Length != 2) { throw new InvalidOperationException("Invalid private key."); } _privateKey = new[] { value[1], value[0] }; } } /// /// Initializes a new instance of the class. /// public RsaKey() { } /// /// Initializes a new instance of the class. /// /// DER encoded private key data. public RsaKey(byte[] data) : base(data) { if (_privateKey.Length != 8) { throw new InvalidOperationException("Invalid private key."); } } /// /// Initializes a new instance of the class. /// /// The modulus. /// The exponent. /// The d. /// The p. /// The q. /// The inverse Q. public RsaKey(BigInteger modulus, BigInteger exponent, BigInteger d, BigInteger p, BigInteger q, BigInteger inverseQ) { _privateKey = new BigInteger[8] { modulus, exponent, d, p, q, PrimeExponent(d, p), PrimeExponent(d, q), inverseQ }; } private static BigInteger PrimeExponent(BigInteger privateExponent, BigInteger prime) { var pe = prime - new BigInteger(1); return privateExponent % pe; } /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } /// /// Releases unmanaged and - optionally - managed resources /// /// true to release both managed and unmanaged resources; false to release only unmanaged resources. protected virtual void Dispose(bool disposing) { if (_isDisposed) { return; } if (disposing) { var digitalSignature = _digitalSignature; if (digitalSignature != null) { digitalSignature.Dispose(); _digitalSignature = null; } _isDisposed = true; } } /// /// Releases unmanaged resources and performs other cleanup operations before the /// is reclaimed by garbage collection. /// ~RsaKey() { Dispose(disposing: false); } } }