in AwsEncryptionSDK/runtimes/net/TestVectorsNative/TestVectors/TestVectors.cs [137:273]
public void CanDecryptTestVector(
string vectorId,
DecryptVector vector,
Dictionary<string, Key> keyMap,
byte[] expectedPlaintext,
string expectedError,
MemoryStream ciphertextStream,
NetV4_0_0_RetryPolicy _netV400RetryPolicy
) {
if (expectedPlaintext != null && expectedError != null)
{
throw new ArgumentException(
$"Test vector {vectorId} has both plaintext and error in its expected result, this is not possible"
);
}
Exception exceptionHolder = null;
bool exceptionHasBeenCaught = false;
try
{
AwsEncryptionSdkConfig config = new AwsEncryptionSdkConfig
{
CommitmentPolicy = ESDKCommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT,
NetV4_0_0_RetryPolicy = _netV400RetryPolicy
};
ESDK encryptionSdk = new ESDK(config);
ICryptographicMaterialsManager cmm = MaterialProviderFactory.CreateDecryptCmm(vector, keyMap, vectorId);
DecryptInput decryptInput = new DecryptInput
{
Ciphertext = ciphertextStream,
MaterialsManager = cmm,
};
if (vector.CMM is "RequiredEncryptionContext")
{
decryptInput = new DecryptInput
{
Ciphertext = ciphertextStream,
MaterialsManager = cmm,
EncryptionContext = vector.EncryptionContext
};
}
AWS.Cryptography.EncryptionSDK.DecryptOutput decryptOutput = encryptionSdk.Decrypt(decryptInput);
if (expectedError != null)
{
throw new TestVectorShouldHaveFailedException(
$"Test vector {vectorId} succeeded when it shouldn't have"
);
}
byte[] result = decryptOutput.Plaintext.ToArray();
Assert.Equal(expectedPlaintext, result);
}
// Ensure Test Failure is not caught
catch (TestVectorShouldHaveFailedException)
{
throw;
}
catch (Exception e) when (
e is AWS.Cryptography.Primitives.CollectionOfErrors
or AWS.Cryptography.KeyStore.CollectionOfErrors
or AWS.Cryptography.MaterialProviders.CollectionOfErrors
or AWS.Cryptography.EncryptionSDK.CollectionOfErrors
)
{
exceptionHasBeenCaught = true;
exceptionHolder = e;
// Use Reflection to get the common list field
Type collectionType = e.GetType();
FieldInfo listFieldInfo = collectionType.GetField("list");
List<Exception> list = (List<Exception>)listFieldInfo?.GetValue(e);
List<string> debugList = new List<string>();
if (vector.MasterKeys != null) debugList.AddRange(vector.MasterKeys.Select(keyInfo => $"Key: {keyInfo.Key}, Type: {keyInfo.Type}"));
testLogging.WriteLine($"CollectionOfErrors Logging. List:\n{string.Join("\n\t", list!)}");
testLogging.WriteLine($"CollectionOfErrors Logging. master-keys:\n{string.Join("\n\t", debugList)}");
}
catch (Exception e) when (
e is AWS.Cryptography.Primitives.OpaqueError
or AWS.Cryptography.KeyStore.OpaqueError
or AWS.Cryptography.MaterialProviders.OpaqueError
or AWS.Cryptography.EncryptionSDK.OpaqueError
)
{
exceptionHasBeenCaught = true;
// Use Reflection to get the common Obj field
Type opaqueType = e.GetType();
FieldInfo objFieldInfo = opaqueType.GetField("obj");
object obj = objFieldInfo?.GetValue(e);
switch (obj)
{
case null when e.Message.Equals(OPAQUE_ERROR_NULL_OBJ_MSG):
testLogging.WriteLine($"OpaqueError Logging: Obj was null. Error Type is {opaqueType}");
exceptionHolder = e;
break;
case Exception nestedException:
testLogging.WriteLine($"OpaqueError Logging: Obj is an Exception. " +
$"Error Type is {opaqueType}.\n" +
$"Nested Exception is {nestedException.GetType()}.\n" +
$"Nested Exceptions message is: \n\t{nestedException.Message}\n"
// + $"Nested Exceptions StackTrace is: \n\t{nestedException.StackTrace}"
);
exceptionHolder = nestedException;
break;
default:
testLogging.WriteLine($"OpaqueError Logging: Obj is an arbitrary object. " +
$"Error Type is {opaqueType}. " +
$"Type of Obj is {obj!.GetType()}.");
exceptionHolder = e;
break;
}
}
catch (Exception e)
{
exceptionHasBeenCaught = true;
exceptionHolder = e;
testLogging.WriteLine($"Unexpected Exception: {e}");
testLogging.WriteLine($"Unexpected Exception: Error Type is {e.GetType()}. " +
$"Exception's message is: {e.Message}");
}
finally
{
if (expectedPlaintext == null && exceptionHasBeenCaught)
{
testLogging.WriteLine("Decrypt Failed, possibly correctly?");
}
if (expectedPlaintext != null && exceptionHasBeenCaught)
{
testLogging.WriteLine("Decrypt Failed, and should not have!");
}
}
if (exceptionHolder != null && expectedPlaintext != null)
{
// Should succeed but did not, throw exception
throw exceptionHolder;
}
}