-
Notifications
You must be signed in to change notification settings - Fork 151
/
Copy pathTlsVariationsExample.cs
196 lines (181 loc) · 8.24 KB
/
TlsVariationsExample.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
using System;
using System.Net.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using NATS.Client;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities.Collections;
namespace NATSExamples
{
/// <summary>
/// This example shows various ways to handle TLS, including manual verification and
/// OCSP revocation checking.
///
/// Revocation checking requires: opts.CheckCertificateRevocation = true
/// Manual Verification requires: opts.TLSRemoteCertificationValidationCallback = ...
///
/// If you provide a manual callback, you can do whatever you like, including checking
/// the certificate and chain.
///
/// X509 Certificate 2
/// https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509certificate2?view=net-6.0
/// X509 Extension Class:
/// https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.x509certificates.x509extension?view=net-6.0
///
/// BouncyCastle is an industry standard crypto library https://www.bouncycastle.org/index.html
/// It might provide functionality that will help handling the certificate and chain.
///
/// </summary>
internal static class TlsVariationsExample
{
static readonly string Url = "tls://localhost:4222";
public static void Main(string[] args)
{
var opts = RevocationCheckingOptions();
// var opts = ManualVerificationOptions();
try
{
using (IConnection c = new ConnectionFactory().CreateConnection(opts))
{
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
}
}
private static Options RevocationCheckingOptions()
{
Options opts = ConnectionFactory.GetDefaultOptions();
opts.Url = Url;
opts.Secure = true;
X509Certificate2 cert = new X509Certificate2("client.pfx", "password");
opts.AddCertificate(cert);
opts.CheckCertificateRevocation = true;
return opts;
}
private static Options ManualVerificationOptions()
{
Options opts = ConnectionFactory.GetDefaultOptions();
opts.Url = Url;
opts.Secure = true;
opts.TLSRemoteCertificationValidationCallback = ManualServerCertVerification;
return opts;
}
private static bool ManualServerCertVerification(object sender,
X509Certificate certificate, X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
Console.WriteLine();
if (certificate is X509Certificate2 cert2)
{
Console.WriteLine("X509Certificate2");
try
{
byte[] rawdata = cert2.RawData;
Console.WriteLine(" Content Type: " + X509Certificate2.GetCertContentType(rawdata));
Console.WriteLine(" Friendly Name: " + cert2.FriendlyName);
Console.WriteLine(" Certificate Verified?: " + cert2.Verify());
Console.WriteLine(" Simple Name: " + cert2.GetNameInfo(X509NameType.SimpleName,true));
Console.WriteLine(" Signature Algorithm: " + cert2.SignatureAlgorithm.FriendlyName);
// Console.WriteLine(" Public Key: " + cert2.PublicKey.Key.ToXmlString(false));
Console.WriteLine(" Certificate Archived?: " + cert2.Archived);
Console.WriteLine(" Length of Raw Data: " + cert2.RawData.Length);
}
catch (CryptographicException)
{
Console.WriteLine("Information could not be written out for this certificate.");
}
Console.WriteLine();
Console.WriteLine("X509Certificate2 Extensions");
foreach (X509Extension ext in cert2.Extensions)
{
Console.WriteLine(" " + ext.GetType().Name
+ "\n Oid: " + ext.Oid.FriendlyName
+ "\n Critical: " + ext.Critical
+ "\n Raw Len: " + ext.RawData.Length);
if (ext is X509BasicConstraintsExtension bcExt)
{
Console.WriteLine(" CA: " + bcExt.CertificateAuthority);
Console.WriteLine(" HPLC: " + bcExt.HasPathLengthConstraint);
Console.WriteLine(" PLC: " + bcExt.PathLengthConstraint);
}
else if (ext is X509KeyUsageExtension kuExt)
{
Console.WriteLine(" Usages: " + kuExt.KeyUsages);
}
else if (ext is X509EnhancedKeyUsageExtension ekuExt)
{
if (ekuExt.EnhancedKeyUsages.Count > 0)
{
Console.WriteLine(" Enhanced Key Usages");
foreach (Oid oid in ekuExt.EnhancedKeyUsages)
{
Console.WriteLine(" " + oid.FriendlyName);
}
}
}
else if (ext is X509SubjectKeyIdentifierExtension skiExt)
{
Console.WriteLine(" Subject Key Identifier: " + skiExt.SubjectKeyIdentifier);
}
}
Console.WriteLine();
}
Console.WriteLine("sslPolicyErrors");
Console.WriteLine(" " + sslPolicyErrors);
Console.WriteLine();
if (chain != null)
{
Console.WriteLine("X509Chain Statuses");
foreach (X509ChainStatus cs in chain.ChainStatus)
{
Console.WriteLine(" " + cs.Status + " | " + cs.StatusInformation);
}
Console.WriteLine();
}
// ------------------------------------------------------------------------------------------
// BouncyCastle
// ------------------------------------------------------------------------------------------
Org.BouncyCastle.X509.X509Certificate bcX509 = DotNetUtilities.FromX509Certificate(certificate);
Console.WriteLine("BouncyCastle X509Certificate");
Console.WriteLine(" " + bcX509.CertificateStructure);
Console.WriteLine(" " + bcX509.IsValidNow);
Console.WriteLine(" " + bcX509.NotBefore);
Console.WriteLine(" " + bcX509.NotAfter);
Console.WriteLine(" " + bcX509.SigAlgName);
Console.WriteLine(" " + bcX509.SigAlgOid);
if (bcX509.GetExtendedKeyUsage().Count > 0)
{
Console.WriteLine(" Extended Key Usage");
foreach (var eku in bcX509.GetExtendedKeyUsage())
{
Console.WriteLine(" " + eku);
}
}
void InspectExtension(ISet extSet, string label)
{
if (extSet.Count > 0)
{
Console.WriteLine(" " + label);
foreach (string oid in extSet)
{
try
{
Asn1OctetString asn = bcX509.GetExtensionValue(new DerObjectIdentifier(oid));
Console.WriteLine(" Oid: " + oid + " | Asn: " + asn);
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}
InspectExtension(bcX509.GetNonCriticalExtensionOids(), "Non Critical Extensions");
InspectExtension(bcX509.GetCriticalExtensionOids(), "Critical Extensions");
return true; // true if the cert is okay, false if it not
}
}
}