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 { /// /// 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 { if (_digitalSignature == null) { _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]; _privateKey[0] = modulus; _privateKey[1] = exponent; _privateKey[2] = d; _privateKey[3] = p; _privateKey[4] = q; _privateKey[5] = PrimeExponent(d, p); _privateKey[6] = PrimeExponent(d, q); _privateKey[7] = inverseQ; } private static BigInteger PrimeExponent(BigInteger privateExponent, BigInteger prime) { BigInteger pe = prime - new BigInteger(1); return privateExponent % pe; } #region IDisposable Members private bool _isDisposed; /// /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. /// public void Dispose() { Dispose(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(false); } #endregion } }