public static DsaKey CreatePrivate( ReadOnlySpan <byte> password, ReadOnlySpan <byte> source, out int publicKeySize) { var dsaParameters = ReadOpenPgpPublicKey(source, out publicKeySize); byte[] xArray = new byte[source.Length - publicKeySize]; try { S2kBasedEncryption.DecryptSecretKey(password, source.Slice(publicKeySize), xArray, out int bytesWritten); dsaParameters.X = MPInteger.ReadInteger(xArray, out int xConsumed).ToArray(); // Make sure Q, X have the same length (DSA implementation on Windows requires it) int qxLength = Math.Max(dsaParameters.X.Length, dsaParameters.Q !.Length); ResizeArrayIfNeeded(ref dsaParameters.Q, qxLength); ResizeArrayIfNeeded(ref dsaParameters.X, qxLength); return(new DsaKey(DSA.Create(dsaParameters))); } finally { CryptographicOperations.ZeroMemory(xArray); CryptographicOperations.ZeroMemory(dsaParameters.X); } }
public static ECDiffieHellmanKey CreatePrivate( ReadOnlySpan <byte> fingerprint, ReadOnlySpan <byte> password, ReadOnlySpan <byte> source, out int publicKeySize) { var ecParameters = ReadOpenPgpECParameters(source, out publicKeySize); // TODO: Validation byte kdfSize = source[publicKeySize]; var kdfParameters = source.Slice(publicKeySize + 1, kdfSize).ToArray(); byte[] paramsArray = new byte[source.Length - publicKeySize]; try { S2kBasedEncryption.DecryptSecretKey(password, source.Slice(publicKeySize + kdfSize + 1), paramsArray, out int bytesWritten); Debug.Assert(bytesWritten != 0); ecParameters.D = MPInteger.ReadInteger(paramsArray, out int dConsumed).ToArray(); return(new ECDiffieHellmanKey(CreateECDiffieHellman(ecParameters), kdfParameters, fingerprint.ToArray())); } finally { CryptographicOperations.ZeroMemory(paramsArray); CryptographicOperations.ZeroMemory(ecParameters.D); } }
public new static EdDsaKey CreatePrivate( ReadOnlySpan <byte> password, ReadOnlySpan <byte> source, out int publicKeySize) { var ecParameters = ReadOpenPgpECParameters(source, out publicKeySize); byte[] paramsArray = new byte[source.Length - publicKeySize]; try { S2kBasedEncryption.DecryptSecretKey(password, source.Slice(publicKeySize), paramsArray, out int bytesWritten); Debug.Assert(bytesWritten != 0); ecParameters.D = MPInteger.ReadInteger(paramsArray, out int dConsumed).ToArray(); return(new EdDsaKey(CreateEdDsa(ecParameters))); } finally { CryptographicOperations.ZeroMemory(paramsArray); CryptographicOperations.ZeroMemory(ecParameters.D); } }
public static ElGamalKey CreatePrivate( ReadOnlySpan <byte> password, ReadOnlySpan <byte> source, out int bytesRead) { var elgamalParameters = ReadOpenPgpPublicKey(source, out bytesRead); byte[] xArray = new byte[source.Length - bytesRead]; try { S2kBasedEncryption.DecryptSecretKey(password, source.Slice(bytesRead), xArray, out int bytesWritten); elgamalParameters.X = MPInteger.ReadInteger(xArray, out int xConsumed).ToArray(); bytesRead = source.Length; return(new ElGamalKey(ElGamal.Create(elgamalParameters))); } finally { CryptographicOperations.ZeroMemory(xArray); CryptographicOperations.ZeroMemory(elgamalParameters.X); } }
public static RsaKey CreatePrivate( ReadOnlySpan <byte> password, ReadOnlySpan <byte> source, out int publicKeyBytes, int version = 4) { var rsaParameters = ReadOpenPgpPublicKey(source, out publicKeyBytes); byte[] paramsArray = new byte[source.Length - publicKeyBytes]; try { S2kBasedEncryption.DecryptSecretKey(password, source.Slice(publicKeyBytes), paramsArray, out int bytesWritten, version); Debug.Assert(bytesWritten != 0); int halfModulusLength = (rsaParameters.Modulus !.Length + 1) / 2; rsaParameters.D = new byte[rsaParameters.Modulus.Length]; rsaParameters.P = new byte[halfModulusLength]; rsaParameters.Q = new byte[halfModulusLength]; rsaParameters.DP = new byte[halfModulusLength]; rsaParameters.DQ = new byte[halfModulusLength]; rsaParameters.InverseQ = new byte[halfModulusLength]; var privateSource = new ReadOnlySpan <byte>(paramsArray); var d = MPInteger.ReadInteger(privateSource, out int dConsumed); privateSource = privateSource.Slice(dConsumed); var p = MPInteger.ReadInteger(privateSource, out int pConsumed); privateSource = privateSource.Slice(pConsumed); var q = MPInteger.ReadInteger(privateSource, out int qConsumed); //source = source.Slice(qConsumed); // Technically InverseQ follows but it's often incorrect // FIXME: These BigIntegers cannot be cleared from memory var D = new BigInteger(d, isBigEndian: true, isUnsigned: true); var P = new BigInteger(p, isBigEndian: true, isUnsigned: true); var Q = new BigInteger(q, isBigEndian: true, isUnsigned: true); var DP = BigInteger.Remainder(D, P - BigInteger.One); var DQ = BigInteger.Remainder(D, Q - BigInteger.One); // Lot of the public keys in the test suite have this wrong (switched P/Q) var InverseQ = BigInteger.ModPow(Q, P - BigInteger.One - BigInteger.One, P); d.CopyTo(rsaParameters.D.AsSpan(rsaParameters.D.Length - d.Length)); p.CopyTo(rsaParameters.P.AsSpan(rsaParameters.P.Length - p.Length)); q.CopyTo(rsaParameters.Q.AsSpan(rsaParameters.Q.Length - q.Length)); DP.TryWriteBytes(rsaParameters.DP.AsSpan(rsaParameters.DP.Length - DP.GetByteCount(isUnsigned: true)), out var _, isBigEndian: true, isUnsigned: true); DQ.TryWriteBytes(rsaParameters.DQ.AsSpan(rsaParameters.DQ.Length - DQ.GetByteCount(isUnsigned: true)), out var _, isBigEndian: true, isUnsigned: true); InverseQ.TryWriteBytes(rsaParameters.InverseQ.AsSpan(rsaParameters.InverseQ.Length - InverseQ.GetByteCount(isUnsigned: true)), out var _, isBigEndian: true, isUnsigned: true); return(new RsaKey(RSA.Create(rsaParameters))); } finally { CryptographicOperations.ZeroMemory(paramsArray); CryptographicOperations.ZeroMemory(rsaParameters.D); CryptographicOperations.ZeroMemory(rsaParameters.P); CryptographicOperations.ZeroMemory(rsaParameters.Q); CryptographicOperations.ZeroMemory(rsaParameters.DP); CryptographicOperations.ZeroMemory(rsaParameters.DQ); CryptographicOperations.ZeroMemory(rsaParameters.InverseQ); } }