diff --git a/README.md b/README.md index 3b91aa4..2f81d16 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,6 @@ Vault.NET is an .NET API client for the interacting with [Vault](https://www.vau ```csharp using Vault; - var vaultClient = new VaultClient(); vaultClient.Token = "XXXXXX"; ``` @@ -24,10 +23,8 @@ var data = new Dictionary {"zip", "zap"} }; await vaultClient.Secret.Write("secret/foo", data); - var secret = await vaultClient.Secret.Read>("secret/foo"); Console.WriteLine(secret.Data["zip"]); - // zap ``` @@ -35,7 +32,6 @@ Console.WriteLine(secret.Data["zip"]); ```csharp using Vault.Models.Secret.Pki; - var testRole = new RolesRequest { AllowAnyDomain = true, @@ -43,14 +39,12 @@ var testRole = new RolesRequest MaxTtl = "1h" }; await vaultClient.Secret.Write("pki/roles/test", testRole); - var certRequest = new IssueRequest { CommonName = "Test Cert" }; var cert = await vaultClient.Secret.Write("pki/issue/test", certRequest); Console.WriteLine(secret.Data.Certificate); - // -----BEGIN CERTIFICATE----- // MII... ``` @@ -59,9 +53,7 @@ Console.WriteLine(secret.Data.Certificate); ```csharp using Vault.Models.Auth.UserPass; - await vaultClient.Sys.EnableAuth("userpass", "userpass", "Userpass Mount"); - var usersRequest = new UsersRequest { Password = "password", @@ -70,16 +62,13 @@ var usersRequest = new UsersRequest MaxTtl = "2h" }; await vaultClient.Auth.Write("userpass/users/username", usersRequest); - var loginRequest = new LoginRequest { Password = "password" }; var loginResponse = await vaultClient.Auth.Write("userpass/login/username", loginRequest); - // Set client token to authenticated token vaultClient.Token = loginResponse.Auth.ClientToken; - // Proceed with authenticated requests ``` diff --git a/src/Vault/Vault.csproj b/src/Vault/Vault.csproj index fbd91ef..e083b6b 100644 --- a/src/Vault/Vault.csproj +++ b/src/Vault/Vault.csproj @@ -28,6 +28,7 @@ + diff --git a/src/Vault/VaultHttpClient.cs b/src/Vault/VaultHttpClient.cs index 8fb7c98..665740c 100644 --- a/src/Vault/VaultHttpClient.cs +++ b/src/Vault/VaultHttpClient.cs @@ -1,7 +1,10 @@ using System; +using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -11,7 +14,49 @@ namespace Vault { public class VaultHttpClient : IVaultHttpClient { - private static readonly HttpClient HttpClient = new HttpClient(); + private static HttpClient HttpClientInitialization() + { + HttpClient httpClient = null; + + #if NET45 + if (!string.IsNullOrEmpty(Vault.VaultOptions.Default.CertPath)) + { + WebRequestHandler requestHandler = new WebRequestHandler(); + requestHandler.ClientCertificateOptions = ClientCertificateOption.Manual; + requestHandler.ClientCertificates.Add(new X509Certificate2(Vault.VaultOptions.Default.CertPath)); + httpClient = new HttpClient(requestHandler); + } + else + httpClient = new HttpClient(); + #else + if (!string.IsNullOrEmpty(Vault.VaultOptions.Default.CertPath)) + { + var handler = new HttpClientHandler(); + handler.ServerCertificateCustomValidationCallback = (request, cert, chain, errors) => + { + const SslPolicyErrors unforgivableErrors = + SslPolicyErrors.RemoteCertificateNotAvailable | + SslPolicyErrors.RemoteCertificateNameMismatch; + + if ((errors & unforgivableErrors) != 0) + { + return false; + } + + X509Certificate2 remoteRoot = chain.ChainElements[chain.ChainElements.Count - 1].Certificate; + return new X509Certificate2(Vault.VaultOptions.Default.CertPath).RawData.SequenceEqual(remoteRoot.RawData); + }; + httpClient = new HttpClient(handler); + } + else + { + httpClient = new HttpClient(); + } + #endif + return httpClient; + } + + private static readonly HttpClient HttpClient = HttpClientInitialization(); public VaultHttpClient() { diff --git a/src/Vault/VaultOptions.cs b/src/Vault/VaultOptions.cs index a710217..74ce690 100644 --- a/src/Vault/VaultOptions.cs +++ b/src/Vault/VaultOptions.cs @@ -8,6 +8,7 @@ public class VaultOptions : IOptions public string Address { get; set; } = "https://localhost:8200"; public string Token { get; set; } + public string CertPath { get; set; } VaultOptions IOptions.Value => this; }