Skip to content
This repository was archived by the owner on Nov 29, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 19 additions & 88 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,98 +1,29 @@
# Vault.NET [![Build status](https://ci.appveyor.com/api/projects/status/784hg5j70vcnumeb/branch/master?svg=true)](https://ci.appveyor.com/project/chatham/vault-net/branch/master)
# Vault.NET Local Certificate
Copy link
Contributor

Choose a reason for hiding this comment

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

Please provide the description of the change in the description of the pull request. This is the main README for the repository.


* Vault API: v0.9.1
* .NET Standard 1.3 (.NET: >= 4.6, .NET Core: >= 1.0.0)
* .NET 4.5
* Nuget: Vault [![NuGet](https://img.shields.io/nuget/v/Vault.svg)](https://www.nuget.org/packages/Vault/)
Required Packages/Assembly:

Vault.NET is an .NET API client for the interacting with [Vault](https://www.vaultproject.io/). This is a port of the go api client and provides generic methods for interacting with the paths in Vault.
- Microsoft.AspNet.WebApi.Client
- System.Net.Http.Formatting.dll

## Example
I have defined a new property "CertPah" that is populated before the definition of the httpcliet.

```csharp
using Vault;
In case it is empty, the behavior remains unchanged.

var vaultClient = new VaultClient();
vaultClient.Token = "XXXXXX";
```
If it is different from empty, then the certificate is taken locally and contributes to Vault API calls.

### Generic Secret

```csharp
var data = new Dictionary<string, string>
{
{"zip", "zap"}
};
await vaultClient.Secret.Write("secret/foo", data);

var secret = await vaultClient.Secret.Read<Dictionary<string, string>>("secret/foo");
Console.WriteLine(secret.Data["zip"]);

// zap
```

### PKI

```csharp
using Vault.Models.Secret.Pki;

var testRole = new RolesRequest
{
AllowAnyDomain = true,
EnforceHostnames = false,
MaxTtl = "1h"
};
await vaultClient.Secret.Write("pki/roles/test", testRole);

var certRequest = new IssueRequest
```csharp
public static async Task<Dictionary<string, string>> VaultAsync(string secretPath)
{
CommonName = "Test Cert"
};
var cert = await vaultClient.Secret.Write<IssueRequest, IssueResponse>("pki/issue/test", certRequest);
Console.WriteLine(secret.Data.Certificate);

// -----BEGIN CERTIFICATE-----
// MII...
```

### Username/Password Authentication

```csharp
using Vault.Models.Auth.UserPass;

await vaultClient.Sys.EnableAuth("userpass", "userpass", "Userpass Mount");

var usersRequest = new UsersRequest
{
Password = "password",
Policies = new List<string> { "default" },
Ttl = "1h",
MaxTtl = "2h"
};
await vaultClient.Auth.Write("userpass/users/username", usersRequest);

var loginRequest = new LoginRequest
{
Password = "password"
};
var loginResponse = await vaultClient.Auth.Write<LoginRequest, NoData>("userpass/login/username", loginRequest);

// Set client token to authenticated token
vaultClient.Token = loginResponse.Auth.ClientToken;

// Proceed with authenticated requests
```

## Models

Many request/response objects are provided in this package to support different backends. This is in no way an exhaustive list of all the objects. Since the models are the things that are going to most likely change between versions of vault, it may make sense to make your own to service your needs. These may get split into a seperate Nuget package in the future.

## Testing

Since most of the operation of this library are just building requests and passing them to the vault API and the vault team provides an easy to use local development server, each test runs against its own vault server. This means that tests require the vault binary available to spin up the vault server instance. The test suite will first look for the environment variable `VAULT_BIN` and if not found will fall back to use the `vault` binary in the `$PATH`.
VaultOptions.Default.CertPath = new DirectoryInfo(
Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\" + "AppData\\cert.crt"))
).ToString();

Downloads for vault can be found [here](https://www.vaultproject.io/downloads.html).
var vaultClient = new VaultClient();
vaultClient.Address = new System.Uri("https://vault.personal.domain.com:8200");
vaultClient.Token = "token";

## Versioning
var secret = await vaultClient.Secret.Read<Dictionary<string, string>>(secretPath);

This library will follow the version of vault that it was developed against. Since most core operations of vault maintain backwards compatibility, this library can be used against many older and newer versions of vault. If features are added or bugs are fixed, a new point release will be created (ex. 0.6.4 -> 0.6.4.1). If there is some functionality that breaks on a newer version of vault, please submit a pull request.
return secret.Data;
}
```
7 changes: 7 additions & 0 deletions src/Vault/Vault.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@
<ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
<Reference Include="System.Web" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Formatting" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFramework)' == 'net45'">
Copy link
Contributor

Choose a reason for hiding this comment

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

We are moving away from support specific .NET runtimes to ensure compatibility. Please target .NET Standard 1.1. There is another pull request already that removes .NET 4.5 specific support.

<PackageReference Include="Microsoft.AspNet.WebApi.Client">
<Version>5.2.4</Version>
</PackageReference>
</ItemGroup>

</Project>
37 changes: 36 additions & 1 deletion src/Vault/VaultHttpClient.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -11,7 +14,39 @@ namespace Vault
{
public class VaultHttpClient : IVaultHttpClient
{
private static readonly HttpClient HttpClient = new HttpClient();
public static HttpClient HttpClientinitialization()
{
HttpClient httpClient = null;

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();
}
return httpClient;
}

private static readonly HttpClient HttpClient = HttpClientinitialization();

public VaultHttpClient()
{
Expand Down
1 change: 1 addition & 0 deletions src/Vault/VaultOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class VaultOptions : IOptions<VaultOptions>

public string Address { get; set; } = "https://localhost:8200";
public string Token { get; set; }
public string CertPath { get; set; }

VaultOptions IOptions<VaultOptions>.Value => this;
}
Expand Down
1 change: 1 addition & 0 deletions test/Vault.Tests/Vault.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.5.0" />
<PackageReference Include="NSubstitute" Version="3.1.0" />
<PackageReference Include="xunit" Version="2.3.1" />
Expand Down