-
Notifications
You must be signed in to change notification settings - Fork 1.3k
CSHARP-6005: CSFLE/QE support for HTTP Proxies #2077
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| /* Copyright 2019-present MongoDB Inc. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| using System; | ||
| using System.IO; | ||
| using System.Net; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
| using MongoDB.Driver.Core.Connections; | ||
| using MongoDB.Driver.Core.Misc; | ||
|
|
||
| namespace MongoDB.Driver.Encryption; | ||
|
|
||
| internal sealed class KmsConnectorStreamFactory : IStreamFactory | ||
| { | ||
| private readonly IKmsConnector _kmsConnector; | ||
|
|
||
| public KmsConnectorStreamFactory(IKmsConnector kmsConnector) | ||
| { | ||
| _kmsConnector = Ensure.IsNotNull(kmsConnector, nameof(kmsConnector)); | ||
| } | ||
|
|
||
| public Stream CreateStream(EndPoint endPoint, CancellationToken cancellationToken) | ||
| { | ||
| var (host, port) = GetHostAndPort(endPoint); | ||
| var stream = _kmsConnector.Connect(host, port, cancellationToken); | ||
| return EnsureConnectResult(stream, nameof(IKmsConnector.Connect)); | ||
| } | ||
|
|
||
| public async Task<Stream> CreateStreamAsync(EndPoint endPoint, CancellationToken cancellationToken) | ||
| { | ||
| var (host, port) = GetHostAndPort(endPoint); | ||
| var stream = await _kmsConnector.ConnectAsync(host, port, cancellationToken).ConfigureAwait(false); | ||
| return EnsureConnectResult(stream, nameof(IKmsConnector.ConnectAsync)); | ||
| } | ||
|
|
||
| private static Stream EnsureConnectResult(Stream stream, string methodName) | ||
| { | ||
| return stream ?? throw new InvalidOperationException($"{nameof(IKmsConnector)}.{methodName} returned null."); | ||
| } | ||
|
|
||
| private static (string Host, int Port) GetHostAndPort(EndPoint endPoint) | ||
| { | ||
| var dnsEndPoint = (DnsEndPoint)endPoint; | ||
| return (dnsEndPoint.Host, dnsEndPoint.Port); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| /* Copyright 2019-present MongoDB Inc. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
|
|
||
| using System.IO; | ||
| using System.Threading; | ||
| using System.Threading.Tasks; | ||
|
|
||
| namespace MongoDB.Driver.Encryption; | ||
|
|
||
| /// <summary> | ||
| /// Opens the transport connection used to reach a KMS host. When supplied via | ||
| /// <c>ClientEncryptionOptions</c> or <see cref="AutoEncryptionOptions"/>, the driver | ||
| /// invokes this instead of opening a direct TCP connection to the KMS host, then wraps the | ||
| /// returned stream in TLS using the KMS provider's configured TLS options. | ||
| /// The primary use case is routing KMS traffic through an HTTP proxy via HTTPS CONNECT. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// Both <see cref="Connect"/> and <see cref="ConnectAsync"/> must be implemented, even if the | ||
| /// application only uses one of the driver's sync or async encryption APIs: the driver calls | ||
| /// whichever method matches the API used for the operation in progress. An implementation that | ||
| /// only supports one direction can have the other throw. | ||
| /// </remarks> | ||
| public interface IKmsConnector | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need this new abstraction?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Discussed offline but I added some reasoning in the PR description. |
||
| { | ||
| /// <summary> | ||
| /// Opens a connection to the specified KMS host. | ||
| /// </summary> | ||
| /// <param name="host">The KMS hostname (for example, <c>kms.us-east-1.amazonaws.com</c>).</param> | ||
| /// <param name="port">The KMS port.</param> | ||
| /// <param name="cancellationToken">The cancellation token.</param> | ||
| /// <returns>A stream connected to the KMS host. The driver wraps this stream in TLS. Must not be null.</returns> | ||
| Stream Connect(string host, int port, CancellationToken cancellationToken); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we use Endpoint instead of host and port?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Discussed offline as well but for visibility: |
||
|
|
||
| /// <summary> | ||
| /// Opens a connection to the specified KMS host. | ||
| /// </summary> | ||
| /// <param name="host">The KMS hostname (for example, <c>kms.us-east-1.amazonaws.com</c>).</param> | ||
| /// <param name="port">The KMS port.</param> | ||
| /// <param name="cancellationToken">The cancellation token.</param> | ||
| /// <returns>A stream connected to the KMS host. The driver wraps this stream in TLS. Must not be null.</returns> | ||
| Task<Stream> ConnectAsync(string host, int port, CancellationToken cancellationToken); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adelinowona I guess we'll address this during backporting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yep