Skip to content

Commit

Permalink
Improve error when private key is missing in RSABCrypt
Browse files Browse the repository at this point in the history
CNG bcrypt gives an unhelpful error when a public key used in a way that requires the private key. RSABCrypt knows if the key is public or not so we can use this to throw a more helpful exception.
  • Loading branch information
vcsjones authored Apr 5, 2024
1 parent b76baa8 commit 068ba8e
Showing 1 changed file with 16 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ internal sealed class RSABCrypt : RSA

private SafeBCryptKeyHandle? _key;
private int _lastKeySize;
private bool _publicOnly;

internal RSABCrypt()
{
Expand Down Expand Up @@ -51,11 +52,11 @@ private SafeBCryptKeyHandle GetKey()

SafeBCryptKeyHandle newKey = Interop.BCrypt.BCryptGenerateKeyPair(s_algHandle, keySize);
Interop.BCrypt.BCryptFinalizeKeyPair(newKey);
SetKey(newKey);
SetKey(newKey, publicOnly: false);
return newKey;
}

private void SetKey(SafeBCryptKeyHandle newKey)
private void SetKey(SafeBCryptKeyHandle newKey, bool publicOnly)
{
Debug.Assert(!newKey.IsInvalid);

Expand All @@ -65,6 +66,7 @@ private void SetKey(SafeBCryptKeyHandle newKey)

SafeBCryptKeyHandle? oldKey = Interlocked.Exchange(ref _key, newKey);
ForceSetKeySize(keySize);
_publicOnly = publicOnly;
oldKey?.Dispose();
}

Expand Down Expand Up @@ -112,7 +114,7 @@ public override void ImportParameters(RSAParameters parameters)
CryptoPool.Return(keyBlob);
}

SetKey(newKey);
SetKey(newKey, publicOnly: parameters.D is null);
}

public override byte[] Encrypt(byte[] data, RSAEncryptionPadding padding)
Expand Down Expand Up @@ -190,6 +192,8 @@ public override bool TryDecrypt(
throw new CryptographicException(SR.Cryptography_RSA_DecryptWrongSize);
}

ThrowIfPublicOnly();

switch (padding.Mode)
{
case RSAEncryptionPaddingMode.Pkcs1:
Expand Down Expand Up @@ -261,6 +265,7 @@ public override bool TrySignHash(
string? hashAlgorithmName = hashAlgorithm.Name;
ArgumentException.ThrowIfNullOrEmpty(hashAlgorithmName, nameof(hashAlgorithm));
ArgumentNullException.ThrowIfNull(padding);
ThrowIfPublicOnly();

SafeBCryptKeyHandle key = GetKey();

Expand Down Expand Up @@ -426,5 +431,13 @@ private void ThrowIfDisposed()
{
ObjectDisposedException.ThrowIf(_lastKeySize < 0, this);
}

private void ThrowIfPublicOnly()
{
if (_publicOnly)
{
throw new CryptographicException(SR.Cryptography_CSP_NoPrivateKey);
}
}
}
}

0 comments on commit 068ba8e

Please sign in to comment.