Skip to content

Commit c5b940d

Browse files
author
Rafał Maciąg
committed
adding local cache for certificates.
1 parent 4526ac0 commit c5b940d

File tree

3 files changed

+51
-10
lines changed

3 files changed

+51
-10
lines changed

src/MicroPlumberd.Encryption/CertManager.cs

+11-10
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,16 @@ public class CertificateNotFoundException : Exception
1818
public string Recipient { get; init; }
1919
}
2020

21-
class CertManagerInitializer(ICertManager cm) : BackgroundService
21+
class CertManagerInitializer(ICertManager cm, IPlumber plumber) : BackgroundService
2222
{
2323
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
2424
{
2525
await cm.Init();
26+
await plumber.Subscribe("$et-PublicCertificateSnapShotted", FromRelativeStreamPosition.Start)
27+
.WithSnapshotHandler<PubCertEventHandler>();
2628
}
2729
}
30+
2831
class CertManager(IPlumber plumber, IConfiguration configuration) : ICertManager
2932
{
3033
private ConcurrentDictionary<string, X509Certificate2> _private = new();
@@ -34,19 +37,16 @@ public X509Certificate2 Get(string recipient)
3437
return _public.GetOrAdd(recipient, r =>
3538
{
3639
var certDir = configuration.GetValue<string>("CertsPath") ?? "./certs";
37-
var file = Path.Combine(certDir, r + ".pfx");
40+
3841
if (!Directory.Exists(certDir))
3942
Directory.CreateDirectory(certDir);
43+
var file = Path.Combine(certDir, $"{r}.cer");
4044
if (File.Exists(file))
4145
return new X509Certificate2(file);
42-
else
43-
{
44-
var result = plumber.GetState<PublicCertificate>(recipient).Result;
45-
if (result == null)
46-
throw new CertificateNotFoundException() { Recipient = recipient };
47-
48-
return new X509Certificate2(result.Value.Data);
49-
}
46+
file = Path.Combine(certDir, $"{r}.pfx");
47+
if (File.Exists(file))
48+
return new X509Certificate2(file);
49+
throw new CertificateNotFoundException() { Recipient = recipient};
5050
});
5151
}
5252

@@ -78,6 +78,7 @@ public async Task Init()
7878
PublicCertificate pc = new PublicCertificate() { Data = pubCer };
7979
await plumber.AppendState(pc, r);
8080
}
81+
8182
}
8283
public X509Certificate2 GetPrivate(string recipient)
8384
{

src/MicroPlumberd.Encryption/ContainerExtensions.cs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public static IServiceCollection AddEncryption(this IServiceCollection services)
1010
services.AddHostedService<CertManagerInitializer>();
1111
services.TryAddSingleton<IEncryptor, Encryptor>();
1212
services.TryAddSingleton<ICertManager, CertManager>();
13+
services.AddSingleton<PubCertEventHandler>();
1314
return services;
1415
}
1516
public static IPlumberConfig EnableEncryption(this IPlumberConfig services)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using Microsoft.Extensions.Configuration;
2+
using Microsoft.Extensions.Logging;
3+
4+
namespace MicroPlumberd.Encryption;
5+
6+
7+
class PubCertEventHandler(IConfiguration configuration, ILogger<PubCertEventHandler> log) : IEventHandler, ITypeRegister
8+
{
9+
Task IEventHandler.Handle(Metadata m, object ev) => Given(m, ev);
10+
public async Task Given(Metadata m, object ev)
11+
{
12+
switch (ev)
13+
{
14+
case PublicCertificate e: await Given(m, e); break;
15+
default:
16+
throw new ArgumentException("Unknown event type", ev.GetType().Name);
17+
}
18+
}
19+
static IEnumerable<Type> ITypeRegister.Types => [typeof(PublicCertificate)];
20+
21+
public async Task Given(Metadata m, PublicCertificate cert)
22+
{
23+
var certDir = configuration.GetValue<string>("CertsPath") ?? "./certs";
24+
var recipient = m.SourceStreamId.Substring(m.SourceStreamId.IndexOf('-')+1);
25+
var file = Path.Combine(certDir, $"{recipient}.cer");
26+
if (!Directory.Exists(certDir))
27+
Directory.CreateDirectory(certDir);
28+
try
29+
{
30+
if(!File.Exists(file))
31+
log.LogInformation("Persisting new public certificate: " + recipient);
32+
await File.WriteAllBytesAsync(file, cert.Data);
33+
}
34+
catch (Exception ex)
35+
{
36+
log.LogWarning(ex,"Could not save public certificate.");
37+
}
38+
}
39+
}

0 commit comments

Comments
 (0)