Skip to content

Dispose all resources used in CmsSignature #115666

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,31 +71,34 @@ internal override bool VerifySignature(
return false;
}

DSAParameters dsaParameters = dsa.ExportParameters(false);
int bufSize = 2 * dsaParameters.Q!.Length;
using (dsa)
{
DSAParameters dsaParameters = dsa.ExportParameters(false);
int bufSize = 2 * dsaParameters.Q!.Length;

#if NET || NETSTANDARD2_1
byte[] rented = CryptoPool.Rent(bufSize);
Span<byte> ieee = new Span<byte>(rented, 0, bufSize);
byte[] rented = CryptoPool.Rent(bufSize);
Span<byte> ieee = new Span<byte>(rented, 0, bufSize);

try
{
try
{
#else
byte[] ieee = new byte[bufSize];
byte[] ieee = new byte[bufSize];
#endif
if (!DsaDerToIeee(signature, ieee))
{
return false;
}
if (!DsaDerToIeee(signature, ieee))
{
return false;
}

return dsa.VerifySignature(valueHash, ieee);
return dsa.VerifySignature(valueHash, ieee);
#if NET || NETSTANDARD2_1
}
finally
{
CryptoPool.Return(rented, bufSize);
}
}
finally
{
CryptoPool.Return(rented, bufSize);
}
#endif
}
}

protected override bool Sign(
Expand All @@ -115,71 +118,75 @@ protected override bool Sign(
Debug.Assert(Helpers.IsDSASupported);
signatureParameters = null;

// If there's no private key, fall back to the public key for a "no private key" exception.
DSA? dsa = key as DSA ??
PkcsPal.Instance.GetPrivateKeyForSigning<DSA>(certificate, silent) ??
certificate.GetDSAPublicKey();

if (dsa == null)
using (GetSigningKey(key, certificate, silent, DSACertificateExtensions.GetDSAPublicKey, out DSA? dsa))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: Using DSACertificateExtensions.GetDSAPublicKey is more succinct, but the main reason for changing to this is because I was getting errors due to dotnet/roslyn-analyzers#4282.

{
signatureAlgorithm = null;
signatureValue = null;
return false;
}
if (dsa == null)
{
signatureAlgorithm = null;
signatureValue = null;
return false;
}

string? oidValue =
hashAlgorithmOid switch
string? oidValue =
hashAlgorithmOid switch
{
Oids.Sha1 => Oids.DsaWithSha1,
Oids.Sha256 => Oids.DsaWithSha256,
Oids.Sha384 => Oids.DsaWithSha384,
Oids.Sha512 => Oids.DsaWithSha512,
_ => null
};

if (oidValue == null)
{
Oids.Sha1 => Oids.DsaWithSha1,
Oids.Sha256 => Oids.DsaWithSha256,
Oids.Sha384 => Oids.DsaWithSha384,
Oids.Sha512 => Oids.DsaWithSha512,
_ => null
};

if (oidValue == null)
{
signatureAlgorithm = null;
signatureValue = null;
return false;
}
signatureAlgorithm = null;
signatureValue = null;
return false;
}

signatureAlgorithm = oidValue;
signatureAlgorithm = oidValue;

#if NET || NETSTANDARD2_1
// The Q size cannot be bigger than the KeySize.
byte[] rented = CryptoPool.Rent(dsa.KeySize / 8);
int bytesWritten = 0;
// The Q size cannot be bigger than the KeySize.
byte[] rented = CryptoPool.Rent(dsa.KeySize / 8);
int bytesWritten = 0;

try
{
if (dsa.TryCreateSignature(dataHash, rented, out bytesWritten))
try
{
var signature = new ReadOnlySpan<byte>(rented, 0, bytesWritten);

if (key != null && !certificate.GetDSAPublicKey()!.VerifySignature(dataHash, signature))
if (dsa.TryCreateSignature(dataHash, rented, out bytesWritten))
{
// key did not match certificate
signatureValue = null;
return false;
var signature = new ReadOnlySpan<byte>(rented, 0, bytesWritten);

if (key != null)
{
using (DSA certKey = certificate.GetDSAPublicKey()!)
{
if (!certKey.VerifySignature(dataHash, signature))
{
// key did not match certificate
signatureValue = null;
return false;
}
}
}

signatureValue = DsaIeeeToDer(signature);
return true;
}

signatureValue = DsaIeeeToDer(signature);
return true;
}
}
finally
{
CryptoPool.Return(rented, bytesWritten);
}
finally
{
CryptoPool.Return(rented, bytesWritten);
}

signatureValue = null;
return false;
signatureValue = null;
return false;
#else
byte[] signature = dsa.CreateSignature(dataHash);
signatureValue = DsaIeeeToDer(new ReadOnlySpan<byte>(signature));
return true;
byte[] signature = dsa.CreateSignature(dataHash);
signatureValue = DsaIeeeToDer(new ReadOnlySpan<byte>(signature));
return true;
#endif
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,36 +71,39 @@ internal override bool VerifySignature(
return false;
}

int bufSize;
checked
using (key)
{
// fieldSize = ceil(KeySizeBits / 8);
int fieldSize = (key.KeySize + 7) / 8;
bufSize = 2 * fieldSize;
}
int bufSize;
checked
{
// fieldSize = ceil(KeySizeBits / 8);
int fieldSize = (key.KeySize + 7) / 8;
bufSize = 2 * fieldSize;
}

#if NET || NETSTANDARD2_1
byte[] rented = CryptoPool.Rent(bufSize);
Span<byte> ieee = new Span<byte>(rented, 0, bufSize);
byte[] rented = CryptoPool.Rent(bufSize);
Span<byte> ieee = new Span<byte>(rented, 0, bufSize);

try
{
try
{
#else
byte[] ieee = new byte[bufSize];
byte[] ieee = new byte[bufSize];
#endif
if (!DsaDerToIeee(signature, ieee))
{
return false;
}
if (!DsaDerToIeee(signature, ieee))
{
return false;
}

return key.VerifyHash(valueHash, ieee);
return key.VerifyHash(valueHash, ieee);
#if NET || NETSTANDARD2_1
}
finally
{
CryptoPool.Return(rented, bufSize);
}
}
finally
{
CryptoPool.Return(rented, bufSize);
}
#endif
}
}

protected override bool Sign(
Expand All @@ -111,92 +114,96 @@ protected override bool Sign(
#endif
string? hashAlgorithmOid,
X509Certificate2 certificate,
object? certKey,
object? privateKey,
bool silent,
[NotNullWhen(true)] out string? signatureAlgorithm,
[NotNullWhen(true)] out byte[]? signatureValue,
out byte[]? signatureParameters)
{
signatureParameters = null;
// If there's no private key, fall back to the public key for a "no private key" exception.
ECDsa? key = certKey as ECDsa ??
PkcsPal.Instance.GetPrivateKeyForSigning<ECDsa>(certificate, silent) ??
certificate.GetECDsaPublicKey();

if (key == null)
using (GetSigningKey(privateKey, certificate, silent, ECDsaCertificateExtensions.GetECDsaPublicKey, out ECDsa? key))
{
signatureAlgorithm = null;
signatureValue = null;
return false;
}

string? oidValue =
hashAlgorithmOid switch
if (key == null)
{
Oids.Sha1 => Oids.ECDsaWithSha1,
Oids.Sha256 => Oids.ECDsaWithSha256,
Oids.Sha384 => Oids.ECDsaWithSha384,
Oids.Sha512 => Oids.ECDsaWithSha512,
signatureAlgorithm = null;
signatureValue = null;
return false;
}

string? oidValue =
hashAlgorithmOid switch
{
Oids.Sha1 => Oids.ECDsaWithSha1,
Oids.Sha256 => Oids.ECDsaWithSha256,
Oids.Sha384 => Oids.ECDsaWithSha384,
Oids.Sha512 => Oids.ECDsaWithSha512,
#if NET8_0_OR_GREATER
Oids.Sha3_256 => Oids.ECDsaWithSha3_256,
Oids.Sha3_384 => Oids.ECDsaWithSha3_384,
Oids.Sha3_512 => Oids.ECDsaWithSha3_512,
Oids.Sha3_256 => Oids.ECDsaWithSha3_256,
Oids.Sha3_384 => Oids.ECDsaWithSha3_384,
Oids.Sha3_512 => Oids.ECDsaWithSha3_512,
#endif
_ => null,
};
_ => null,
};

if (oidValue == null)
{
signatureAlgorithm = null;
signatureValue = null;
return false;
}
if (oidValue == null)
{
signatureAlgorithm = null;
signatureValue = null;
return false;
}

signatureAlgorithm = oidValue;
signatureAlgorithm = oidValue;

#if NET || NETSTANDARD2_1
int bufSize;
checked
{
// fieldSize = ceil(KeySizeBits / 8);
int fieldSize = (key.KeySize + 7) / 8;
bufSize = 2 * fieldSize;
}
int bufSize;
checked
{
// fieldSize = ceil(KeySizeBits / 8);
int fieldSize = (key.KeySize + 7) / 8;
bufSize = 2 * fieldSize;
}

byte[] rented = CryptoPool.Rent(bufSize);
int bytesWritten = 0;
byte[] rented = CryptoPool.Rent(bufSize);
int bytesWritten = 0;

try
{
if (key.TrySignHash(dataHash, rented, out bytesWritten))
try
{
var signedHash = new ReadOnlySpan<byte>(rented, 0, bytesWritten);

if (key != null && !certificate.GetECDsaPublicKey()!.VerifyHash(dataHash, signedHash))
if (key.TrySignHash(dataHash, rented, out bytesWritten))
{
// key did not match certificate
signatureValue = null;
return false;
var signedHash = new ReadOnlySpan<byte>(rented, 0, bytesWritten);

if (key != null)
{
using (ECDsa certKey = certificate.GetECDsaPublicKey()!)
{
if (!certKey.VerifyHash(dataHash, signedHash))
{
// key did not match certificate
signatureValue = null;
return false;
}
}
}

signatureValue = DsaIeeeToDer(signedHash);
return true;
}

signatureValue = DsaIeeeToDer(signedHash);
return true;
}
}
finally
{
CryptoPool.Return(rented, bytesWritten);
}
finally
{
CryptoPool.Return(rented, bytesWritten);
}
#endif

signatureValue = DsaIeeeToDer(key.SignHash(
signatureValue = DsaIeeeToDer(key.SignHash(
#if NET || NETSTANDARD2_1
dataHash.ToArray()
dataHash.ToArray()
#else
dataHash
dataHash
#endif
));
return true;
));
return true;
}
}
}
}
Expand Down
Loading
Loading