Skip to content

Commit

Permalink
all certs to be loaded from env variables
Browse files Browse the repository at this point in the history
  • Loading branch information
dkackman committed Nov 18, 2023
1 parent 859a9ef commit 529c6dc
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 9 deletions.
12 changes: 12 additions & 0 deletions src/chia-dotnet.tests/ConnectionSigningTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,17 @@ public async Task InvalidCertPathThrowsFileNotFound()
_ = await Assert.ThrowsAsync<FileNotFoundException>(
async () => await rpc.Connect());
}

[Fact]
public void CanLoadCertFromFile()
{
var endpoint = new EndpointInfo()
{
CertPath = @"C:\Users\don\.chia\mainnet\config\ssl\data_layer\private_data_layer.crt",
KeyPath = @"C:\Users\don\.chia\mainnet\config\ssl\data_layer\private_data_layer.key"
};
var certs = endpoint.GetCert();
Assert.NotNull(certs);
}
}
}
26 changes: 22 additions & 4 deletions src/chia-dotnet/CertLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal static class CertLoader
/// <param name="certPath">The full path the public cert (.crt)</param>
/// <param name="keyPath">The full path to the RSA encoded private key (.key)</param>
/// <returns>An ephemeral certificate that can be used for WebSocket authentication</returns>
public static X509Certificate2Collection GetCerts(string certPath, string keyPath)
public static X509Certificate2Collection GetCertFromFiles(string certPath, string keyPath)
{
if (!File.Exists(certPath))
{
Expand All @@ -29,9 +29,27 @@ public static X509Certificate2Collection GetCerts(string certPath, string keyPat
throw new FileNotFoundException($"key file {keyPath} not found");
}

using X509Certificate2 cert = new(certPath);
using StreamReader streamReader = new(keyPath);
using var rsa = DeserializePrivateKey(streamReader.ReadToEnd());
using StreamReader certStreamReader = new(certPath);
using StreamReader keyStreamReader = new(keyPath);

return DeserializeCert(certStreamReader.ReadToEnd(), keyStreamReader.ReadToEnd());
}


public static X509Certificate2Collection DeserializeCert(string certBlob, string keyBlob)
{
if (string.IsNullOrEmpty(certBlob))
{
throw new ArgumentNullException(nameof(certBlob));
}

if (string.IsNullOrEmpty(keyBlob))
{
throw new ArgumentNullException(nameof(keyBlob));
}

using X509Certificate2 cert = new(Encoding.UTF8.GetBytes(certBlob));
using var rsa = DeserializePrivateKey(keyBlob);
using var certWithKey = cert.CopyWithPrivateKey(rsa);

var keyBytes = certWithKey.Export(X509ContentType.Pkcs12);
Expand Down
23 changes: 23 additions & 0 deletions src/chia-dotnet/EndpointInfo.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.Security.Cryptography.X509Certificates;

namespace chia.dotnet
{
/// <summary>
/// Information about how to connect and authenticate with the RPC endpoint
/// </summary>
/// <remarks>Using the <see cref="CertPath"/>/<see cref="KeyPath"/> vs <see cref="Cert"/>/<see cref="Key"/> are independent of each other</remarks>
public record EndpointInfo
{
/// <summary>
Expand All @@ -21,5 +23,26 @@ public record EndpointInfo
/// The full file system path to the base64 encoded RSA private key to authenticate with the endpoint (.key)
/// </summary>
public string KeyPath { get; init; } = string.Empty;

/// <summary>
/// The loaded cert as base 64 encoded blob
/// </summary>
public string Cert { get; init; } = string.Empty;

/// <summary>
/// The loaded key as base 64 encoded blob
/// </summary>

public string Key { get; init; } = string.Empty;


internal X509Certificate2Collection GetCert()
{
// if the cert blobs are empty get certs from the file paths
// otherwise use the blobs
return string.IsNullOrEmpty(Cert) && string.IsNullOrEmpty(Key)
? CertLoader.GetCertFromFiles(CertPath, KeyPath)
: CertLoader.DeserializeCert(Cert, Key);
}
}
}
2 changes: 1 addition & 1 deletion src/chia-dotnet/HttpRpcClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public HttpRpcClient(EndpointInfo endpoint)
Endpoint = endpoint ?? throw new ArgumentNullException(nameof(endpoint));

var handler = new SocketsHttpHandler();
handler.SslOptions.ClientCertificates = CertLoader.GetCerts(Endpoint.CertPath, Endpoint.KeyPath);
handler.SslOptions.ClientCertificates = endpoint.GetCert();
handler.SslOptions.RemoteCertificateValidationCallback += ValidateServerCertificate;

_httpClient = new(handler, true)
Expand Down
2 changes: 1 addition & 1 deletion src/chia-dotnet/WebSocketRpcClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public async Task Connect(CancellationToken cancellationToken = default)
throw new InvalidOperationException("RpcClient connection is already open");
}

_webSocket.Options.ClientCertificates = CertLoader.GetCerts(Endpoint.CertPath, Endpoint.KeyPath);
_webSocket.Options.ClientCertificates = Endpoint.GetCert();

await _webSocket.ConnectAsync(Endpoint.Uri, cancellationToken).ConfigureAwait(false);
_ = Task.Factory.StartNew(ReceiveLoop, _receiveCancellationTokenSource.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default).ConfigureAwait(false);
Expand Down
6 changes: 3 additions & 3 deletions src/chia-dotnet/chia-dotnet.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Version>2.1.8</Version>
<Version>2.1.9</Version>
<Authors>dkackman</Authors>
<Company>dkackman</Company>
<Description>A .net client library for chia™ RPC interfaces that runs on linux and windows.</Description>
Expand All @@ -21,8 +21,8 @@
<PackageReleaseNotes>Add default data_layer xonfig to GetEndpoint</PackageReleaseNotes>
<PackageIcon>chia-leaf-logo-384x384.png</PackageIcon>
<PackageIconUrl />
<AssemblyVersion>2.1.7.0</AssemblyVersion>
<FileVersion>2.1.7.0</FileVersion>
<AssemblyVersion>2.1.9.0</AssemblyVersion>
<FileVersion>2.1.9.0</FileVersion>
<Nullable>enable</Nullable>
<Title>chia.dotnet</Title>
<PackageReadmeFile>README.md</PackageReadmeFile>
Expand Down

0 comments on commit 529c6dc

Please sign in to comment.