Skip to content

CSHARP-3936: Support KMIP in client side field level encryption. #675

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 12 commits into from
Nov 18, 2021

Conversation

DmitryLukyanov
Copy link
Contributor

No description provided.

.gitignore Outdated
@@ -47,7 +47,7 @@ Help
src/packages

# Nupkg artifacts
*.nupkg
#*.nupkg
Copy link
Contributor Author

Choose a reason for hiding this comment

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

will be reverted

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

NuGet.config Outdated
<packageSources>
<add key="LocalPackages" value="libs" />
</packageSources>
<activePackageSource>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

will be reverted

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -303,6 +303,7 @@ functions:
CLIENT_PEM=${DRIVERS_TOOLS}/.evergreen/x509gen/client.pem \
REQUIRE_API_VERSION=${REQUIRE_API_VERSION} \
FRAMEWORK=${FRAMEWORK} \
ALLOW_NOSSL=true \
Copy link
Contributor Author

Choose a reason for hiding this comment

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

for kmip we need to pass client certificate regardless ssl options

@@ -922,44 +964,6 @@ tasks:
vars:
FRAMEWORK: netstandard21

- name: test-kms-tls-expired-certificate-netstandard21
Copy link
Contributor Author

Choose a reason for hiding this comment

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

new tests cover this logic

# PYTHON The python path

# Don't write anything to output
if [ -z "$Venv" ]; then
Copy link
Contributor Author

Choose a reason for hiding this comment

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

a new script that provides python path

if (testCase.Name.Contains("kmip"))
{
// kmip requires configuring kms mock server
RequireEnvironment.Check().EnvironmentVariable("KMS_MOCK_SERVERS_ENABLED");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

skip because kmip tests require kms mock servers

@@ -40,6 +46,7 @@

namespace MongoDB.Driver.Tests.Specifications.client_side_encryption.prose_tests
{
[Trait("Category", "FLE")]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

some of tests here still fail from time to time, investigating

AssertException(exception);
}

void AssertException(Exception exception)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

asserts exception based on OS, TF, Certificate configuration, KMS provider


return false;
});
clientEncryptionOptions._tlsOptions(tlsOptions); // avoid validation on serverCertificateValidationCallback
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I use reflection, because settings serverCertificateValidationCallback is disabled via public API

@@ -1023,52 +1288,61 @@ public void ViewAreProhibitedTest([Values(false, true)] bool async)
[SkippableTheory]
[ParameterAttributeData]
public void UnsupportedPlatformsTests(
[Values("local", "aws", "azure", "gcp")] string kmsProvider,
[Values("gcp")] string kmsProvider, // the rest kms providers are supported on all supported TFs
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this test is not longer complicated because most of the cases were gone for now

@DmitryLukyanov DmitryLukyanov requested a review from jyemin November 9, 2021 20:54
@@ -690,13 +693,15 @@ void ValidKmsEndpointConfigurator(string kt, Dictionary<string, object> ko)
case "gcp":
ko.Add("endpoint", "oauth2.googleapis.com:443");
break;
case "kmip":
//ko.Add("endpoint", "localhost:5698");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

missed this, will fix in the next commit

@JamesKovacs JamesKovacs requested review from JamesKovacs and removed request for jyemin November 9, 2021 23:29
@DmitryLukyanov
Copy link
Contributor Author

Ready for review, the only pending question is related to failing tests with unexpected exception:

Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host.

like here. It looks like it's related to mock server behavior, I asked Kevin maybe he faced with this, so will reach our him tommorow

@@ -567,6 +564,10 @@ EncryptionAlgorithm ParseAlgorithm(string algorithm)
// gcp
[InlineData("gcp", "cloudkms.googleapis.com:443", null, "parse error")]
[InlineData("gcp", "example.com:443", "Invalid KMS response", null)]
// kmip
[InlineData("kmip", null, null, "$HostNotFound$")]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. I don't use enum itself, because it breaks a bit Test Explorer on .net framework, due some serialization issue
  2. I use a code instead a message, because the message is platform dependent in some cases

Copy link
Contributor

@JamesKovacs JamesKovacs left a comment

Choose a reason for hiding this comment

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

See comments inline to discuss. Main point of discussion is around testing strategy. A few auxiliary questions about API and impl.


SSL=${SSL:-nossl}
OCSP_TLS_SHOULD_SUCCEED=${OCSP_TLS_SHOULD_SUCCEED:-nil}
OCSP_ALGORITHM=${OCSP_ALGORITHM:-nil}
ALLOW_NOSSL=${ALLOW_NOSSL:-nil}
Copy link
Contributor

Choose a reason for hiding this comment

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

ALLOW_NOSSL is making my brain hurt trying to figure out if SSL is allowed or not. What about calling this option REQUIRE_CERTS or something similar?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this option allows skipping the validation where we add the certificate to trusted storage only if ${SSL}="ssl", so this describes exactly what happens. I don't mind to change it, but REQUIRE_CERTS is not what this variable have control about. What about: IGNORE_SSL_CHECK?

Copy link
Contributor

Choose a reason for hiding this comment

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

Given that there is no harm in adding certs even if they're unused, why don't we simplify the script to always add the certs and remove the need for this option?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this file is used in other logic like in OCSP and other, I would not want to change anything there

@@ -267,5 +283,28 @@ private async Task SendKmsRequestAsync(KmsRequest request, CancellationToken can
}
}
}

// nested type
private class NetworkStreamFactory : IStreamFactory
Copy link
Contributor

Choose a reason for hiding this comment

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

Examining TcpStreamFactory, we handle differences between .NET Framework and .NET Core. NetworkStreamFactory is implemented identically to the .NET Framework CreateStream code. Are we sure we don't need the extra logic in TcpStreamFactory for proper operation on .NET Core?

@@ -23,6 +23,7 @@

namespace MongoDB.Driver.Core.TestHelpers.Logging
{
[DebuggerStepThrough]
Copy link
Contributor

Choose a reason for hiding this comment

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

We should make this change in the context of CSHARP-3904, not this PR.

Copy link
Contributor

@JamesKovacs JamesKovacs left a comment

Choose a reason for hiding this comment

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

Some outstanding comments that need to be addressed. Please let me know if you have any questions or would like to discuss.

@@ -216,7 +216,7 @@ public override string ToString()
}
if (_tlsOptions != null)
{
sb.AppendFormat("TlsOptions: {0}", _tlsOptions.Select(t => new BsonDocument(t.Key, "<hidden>")).ToJson(jsonWriterSettings));
sb.AppendFormat("TlsOptions: {0}, ", _tlsOptions.ToJson(jsonWriterSettings));
Copy link
Contributor

Choose a reason for hiding this comment

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

I think hiding the tlsOptions - which could contain sensitive data - other than the key name is the correct thing to do even if it makes debugging more difficult. Why did you remove the <hidden> replacement code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I described it here: #675 (comment) so, to simplify logic, but I see that it gives some problem with serialization IntPtr like:

MongoDB.Bson.BsonSerializationException : No serializer found for type System.IntPtr.

EG: https://evergreen.mongodb.com/build/dot_net_driver_kms_tls_mocked_tests_windows__version~5.0_os~windows_64_topology~standalone_ssl~nossl_patch_60ad0c84b164c0648eabe7dea72aa6d94f8289aa_618d6e7de3c33142e63b40c5_21_11_11_19_27_33
I will probably revert it

Copy link
Contributor

Choose a reason for hiding this comment

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

SslStreamSettings has 5 properties:
CheckCertificateRevocation - might be useful but currently only true is allowed for KMIP/KMS
ClientCertificates - we don't want to expose these
ClientCertificateSelectionCallback - delegate; only useful thing to show would be whether it is set or not
EnabledSslProtocols - might be useful to show these but we could potentially leak security information about whether support for older (and less secure) protocols is enabled
ServerCertificateValidationCallback - delegate; only useful thing to show would be whether it is set or not

Of the 5 properties, they either have known values for KMIP/KMS or would leak security information. So I think <hidden> is a better choice rather than risking leaking sensitive information.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

reverted

Copy link
Contributor

@JamesKovacs JamesKovacs left a comment

Choose a reason for hiding this comment

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

LGTM

FRAMEWORK=${FRAMEWORK} \
TARGET="TestCsfleWithMockedKms" \
evergreen/run-tests.sh
evergreen/cleanup-test-resources.sh
Copy link
Contributor

Choose a reason for hiding this comment

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

cleanup-test-resources.sh requires the OS environment variable but you're not setting it. When you set environment variables like this ENV=VALUE cmd, the environment variable only applies to cmd and not to any following commands.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@@ -267,5 +283,28 @@ private async Task SendKmsRequestAsync(KmsRequest request, CancellationToken can
}
}
}

// nested type
private class NetworkStreamFactory : IStreamFactory
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's leave it as it is here and revisit later if necessary.

@@ -23,6 +23,7 @@

namespace MongoDB.Driver.Core.TestHelpers.Logging
{
[DebuggerStepThrough]
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm good with implementing CSHARP-3904 immediately. I just don't want to have [DebuggerStepThrough] changes mixed into the KMIP changes.

@DmitryLukyanov
Copy link
Contributor Author

DmitryLukyanov commented Nov 18, 2021

@DmitryLukyanov DmitryLukyanov force-pushed the csharp3936 branch 2 times, most recently from 4929f15 to 58ccd79 Compare November 18, 2021 23:21
Copy link
Contributor

@JamesKovacs JamesKovacs left a comment

Choose a reason for hiding this comment

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

LGTM

@DmitryLukyanov DmitryLukyanov merged commit 5cdfe04 into mongodb:master Nov 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants