/// <summary>The public key contained in the object.</summary> /// <returns>A lightweight public key.</returns> /// <exception cref="PgpException">If the key algorithm is not recognised.</exception> private IAsymmetricPublicKey GetKey() { if (key != null) { return(key); } switch (keyPacket.Algorithm) { case PgpPublicKeyAlgorithm.RsaEncrypt: case PgpPublicKeyAlgorithm.RsaGeneral: case PgpPublicKeyAlgorithm.RsaSign: return(key = RsaKey.CreatePublic(keyPacket.KeyBytes, out var _)); case PgpPublicKeyAlgorithm.Dsa: return(key = DsaKey.CreatePublic(keyPacket.KeyBytes, out var _)); case PgpPublicKeyAlgorithm.ElGamalEncrypt: case PgpPublicKeyAlgorithm.ElGamalGeneral: return(key = ElGamalKey.CreatePublic(keyPacket.KeyBytes, out var _)); case PgpPublicKeyAlgorithm.ECDsa: return(key = ECDsaKey.CreatePublic(keyPacket.KeyBytes, out var _)); case PgpPublicKeyAlgorithm.ECDH: return(key = ECDiffieHellmanKey.CreatePublic(fingerprint, keyPacket.KeyBytes, out var _)); case PgpPublicKeyAlgorithm.EdDsa: return(key = EdDsaKey.CreatePublic(keyPacket.KeyBytes, out var _)); default: throw new PgpException("unknown public key algorithm encountered"); } }
public PgpKeyPair( AsymmetricAlgorithm asymmetricAlgorithm, DateTime creationTime, bool isMasterKey = true) { IAsymmetricPrivateKey privateKey; IAsymmetricPublicKey publicKey; byte[]? ecdhFingerprint = null; if (asymmetricAlgorithm is RSA rsa) { privateKey = new RsaKey(rsa); } else if (asymmetricAlgorithm is DSA dsa) { privateKey = new DsaKey(dsa); } else if (asymmetricAlgorithm is ElGamal elGamal) { privateKey = new ElGamalKey(elGamal); } else if (asymmetricAlgorithm is ECDiffieHellman ecdh) { privateKey = new ECDiffieHellmanKey(ecdh, new byte[] { 0, (byte)PgpHashAlgorithm.Sha256, (byte)PgpSymmetricKeyAlgorithm.Aes128 }, ecdhFingerprint = new byte[20]); } else if (asymmetricAlgorithm is Ed25519 eddsa) { privateKey = new EdDsaKey(eddsa); } else if (asymmetricAlgorithm is ECDsa ecdsa) { privateKey = new ECDsaKey(ecdsa); } else { throw new NotSupportedException(); } publicKey = (IAsymmetricPublicKey)privateKey; var keyBytes = publicKey.ExportPublicKey(); var keyPacket = isMasterKey ? new PublicKeyPacket(publicKey.Algorithm, creationTime, keyBytes) : new PublicSubkeyPacket(publicKey.Algorithm, creationTime, keyBytes); this.PublicKey = new PgpPublicKey(keyPacket) { key = publicKey }; if (ecdhFingerprint != null) { this.PublicKey.Fingerprint.Slice(0, 20).CopyTo(ecdhFingerprint); } this.PrivateKey = new PgpPrivateKey(this.PublicKey.KeyId, privateKey); }
/// <summary>Extract a <c>PgpPrivateKey</c> from this secret key's encrypted contents.</summary> /// <remarks> /// Allows the caller to handle the encoding of the passphrase to bytes. /// </remarks> public PgpPrivateKey?ExtractPrivateKey(ReadOnlySpan <byte> rawPassPhrase) { if (IsPrivateKeyEmpty) { return(null); } if (keyPacket.Version < 4) { Debug.Assert(keyPacket.Algorithm == PgpPublicKeyAlgorithm.RsaGeneral || keyPacket.Algorithm == PgpPublicKeyAlgorithm.RsaEncrypt || keyPacket.Algorithm == PgpPublicKeyAlgorithm.RsaSign); var rsa = RsaKey.CreatePrivate(rawPassPhrase, keyPacket.KeyBytes, out var _, version: 3); return(new PgpPrivateKey(KeyId, rsa)); } else if (keyPacket.Version >= 4) { switch (keyPacket.Algorithm) { case PgpPublicKeyAlgorithm.RsaGeneral: case PgpPublicKeyAlgorithm.RsaSign: case PgpPublicKeyAlgorithm.RsaEncrypt: var rsa = RsaKey.CreatePrivate(rawPassPhrase, keyPacket.KeyBytes, out var _); return(new PgpPrivateKey(KeyId, rsa)); case PgpPublicKeyAlgorithm.Dsa: var dsa = DsaKey.CreatePrivate(rawPassPhrase, keyPacket.KeyBytes, out var _); return(new PgpPrivateKey(KeyId, dsa)); case PgpPublicKeyAlgorithm.ECDH: var ecdh = ECDiffieHellmanKey.CreatePrivate(Fingerprint, rawPassPhrase, keyPacket.KeyBytes, out var _); return(new PgpPrivateKey(KeyId, ecdh)); case PgpPublicKeyAlgorithm.ECDsa: var ecdsa = ECDsaKey.CreatePrivate(rawPassPhrase, keyPacket.KeyBytes, out var _); return(new PgpPrivateKey(KeyId, ecdsa)); case PgpPublicKeyAlgorithm.EdDsa: var eddsa = EdDsaKey.CreatePrivate(rawPassPhrase, keyPacket.KeyBytes, out var _); return(new PgpPrivateKey(KeyId, eddsa)); case PgpPublicKeyAlgorithm.ElGamalEncrypt: case PgpPublicKeyAlgorithm.ElGamalGeneral: var elgamal = ElGamalKey.CreatePrivate(rawPassPhrase, keyPacket.KeyBytes, out var _); return(new PgpPrivateKey(KeyId, elgamal)); } } throw new PgpException("unknown public key version encountered"); }