Skip to content

Commit 7e13275

Browse files
authored
feat: support for x509 Certificate Serialization.
Support for x509 Certificate Serialization.
2 parents 5573ccb + 301cc85 commit 7e13275

File tree

2 files changed

+87
-1
lines changed

2 files changed

+87
-1
lines changed

src/Aguacongas.AspNetCore.Authentication/AuthenticationSchemeOptionsSerializer.cs

+51-1
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,55 @@
66
using System;
77
using System.Linq;
88
using System.Reflection;
9+
using System.Security.Cryptography.X509Certificates;
910

1011
namespace Aguacongas.AspNetCore.Authentication
1112
{
13+
/// <summary>
14+
/// Converter For x509 Data
15+
/// </summary>
16+
public class X509Certificate2JsonConverter : JsonConverter
17+
{
18+
/// <summary>
19+
/// Is the object fed to this a match for our converter type.
20+
/// </summary>
21+
/// <param name="objectType"></param>
22+
/// <returns></returns>
23+
public override bool CanConvert(Type objectType)
24+
{
25+
return objectType == typeof(X509Certificate2);
26+
}
27+
28+
/// <summary>
29+
/// Read method.
30+
/// </summary>
31+
/// <param name="reader"></param>
32+
/// <param name="objectType"></param>
33+
/// <param name="existingValue"></param>
34+
/// <param name="serializer"></param>
35+
/// <returns></returns>
36+
public override object ReadJson(JsonReader reader,
37+
Type objectType, object existingValue, JsonSerializer serializer)
38+
{
39+
var deserializedRaw = serializer.Deserialize<byte[]>(reader);
40+
var deserialized = new X509Certificate2(deserializedRaw);
41+
return deserialized;
42+
}
43+
44+
/// <summary>
45+
/// Write method.
46+
/// </summary>
47+
/// <param name="writer"></param>
48+
/// <param name="value"></param>
49+
/// <param name="serializer"></param>
50+
public override void WriteJson(JsonWriter writer,
51+
object value, JsonSerializer serializer)
52+
{
53+
byte[] certData = ((X509Certificate2)value).Export(X509ContentType.Pfx);
54+
serializer.Serialize(writer, certData);
55+
}
56+
}
57+
1258
/// <summary>
1359
/// Manage <see cref="AuthenticationSchemeOptions"/> serialization.
1460
/// </summary>
@@ -27,7 +73,11 @@ public class AuthenticationSchemeOptionsSerializer : IAuthenticationSchemeOption
2773
ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
2874
Formatting = Formatting.None,
2975
DefaultValueHandling = DefaultValueHandling.Include,
30-
ContractResolver = new ContractResolver()
76+
ContractResolver = new ContractResolver(),
77+
Converters =
78+
{
79+
new X509Certificate2JsonConverter()
80+
}
3181
};
3282

3383
/// <summary>

test/Aguacongas.AspNetCore.Authentication.Test/AuthenticationSchemeOptionsSerializerTest.cs

+36
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22
// Copyright (c) 2021 @Olivier Lefebvre
33
using Microsoft.AspNetCore.Authentication.OAuth;
44
using Microsoft.AspNetCore.Authentication.WsFederation;
5+
using Newtonsoft.Json;
6+
using System;
7+
using System.Security.Cryptography;
8+
using System.Security.Cryptography.X509Certificates;
9+
using System.Text.Json.Serialization;
510
using Xunit;
611

712
namespace Aguacongas.AspNetCore.Authentication.Test
@@ -54,5 +59,36 @@ public void SeserializeOptions_should_seserialize_default_value()
5459

5560
Assert.False(deserialized.RequireHttpsMetadata);
5661
}
62+
63+
[Fact]
64+
public void SerializationOptions_should_serialize_x509_certificate()
65+
{
66+
var holder = new CertificateHolder();
67+
holder.Certificate = CertificateHolder.CreateCertificate();
68+
var str = JsonConvert.SerializeObject(holder);
69+
var holderRestored = JsonConvert.DeserializeObject<CertificateHolder>(str);
70+
var holderStr = holder.Certificate.ToString();
71+
var holderRestoredStr = holderRestored.Certificate.ToString();
72+
Assert.Equal(holderStr, holderRestoredStr);
73+
holder.Dispose();
74+
holderRestored.Dispose();
75+
}
76+
}
77+
78+
public class CertificateHolder : IDisposable
79+
{
80+
[Newtonsoft.Json.JsonConverter(typeof(X509Certificate2JsonConverter))]
81+
public X509Certificate2 Certificate { get; set; }
82+
83+
public void Dispose() => Certificate?.Dispose();
84+
85+
public static X509Certificate2 CreateCertificate()
86+
{
87+
var ecdsa = ECDsa.Create();
88+
var req = new CertificateRequest("cn=foobar", ecdsa, HashAlgorithmName.SHA256);
89+
var c = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(5));
90+
return c;
91+
}
5792
}
93+
5894
}

0 commit comments

Comments
 (0)