Skip to content

Commit 9f52b02

Browse files
blackspherefollowerqdot
authored andcommitted
Adding more information to the Bad Data crypto exception.
1 parent 82ed3a9 commit 9f52b02

1 file changed

Lines changed: 22 additions & 145 deletions

File tree

Buttplug.Components.WebsocketServer/CertUtils.cs

Lines changed: 22 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -22,86 +22,6 @@ namespace Buttplug.Components.WebsocketServer
2222
internal static class CertUtils
2323
{
2424
// Note: Much of this code comes from https://stackoverflow.com/a/22247129
25-
private static X509Certificate2 GenerateSelfSignedCertificate(string subject, X509Certificate2 issuer, AsymmetricCipherKeyPair issuerKeyPair)
26-
{
27-
const int keyStrength = 2048;
28-
29-
// Generating Random Numbers
30-
var randomGenerator = new CryptoApiRandomGenerator();
31-
var random = new SecureRandom(randomGenerator);
32-
33-
// The Certificate Generator
34-
var certificateGenerator = new X509V3CertificateGenerator();
35-
36-
// Serial Number
37-
certificateGenerator.SetSerialNumber(BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random));
38-
39-
// Issuer
40-
certificateGenerator.SetIssuerDN(new X509Name(issuer.Subject));
41-
certificateGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(issuerKeyPair.Public)));
42-
43-
// Subject DN
44-
certificateGenerator.SetSubjectDN(new X509Name("CN=" + subject));
45-
46-
// Subject Alternative Name
47-
var subjectAlternativeNames = new List<Asn1Encodable>()
48-
{
49-
new GeneralName(GeneralName.DnsName, Environment.MachineName),
50-
new GeneralName(GeneralName.DnsName, "localhost"),
51-
new GeneralName(GeneralName.IPAddress, "127.0.0.1"),
52-
};
53-
54-
if (subject != "localhost" && subject != Environment.MachineName)
55-
{
56-
subjectAlternativeNames.Add(new GeneralName(GeneralName.DnsName, subject));
57-
}
58-
59-
certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName.Id, false, new DerSequence(subjectAlternativeNames.ToArray()));
60-
61-
// Valid For
62-
var notBefore = DateTime.UtcNow.Date;
63-
var notAfter = notBefore.AddYears(2);
64-
certificateGenerator.SetNotBefore(notBefore);
65-
certificateGenerator.SetNotAfter(notAfter);
66-
67-
// Subject Public Key
68-
var keyPairGenerator = new RsaKeyPairGenerator();
69-
var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
70-
keyPairGenerator.Init(keyGenerationParameters);
71-
var subjectKeyPair = keyPairGenerator.GenerateKeyPair();
72-
certificateGenerator.SetPublicKey(subjectKeyPair.Public);
73-
certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(subjectKeyPair.Public)));
74-
75-
// Add basic constraint
76-
certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(false));
77-
78-
certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false, new ExtendedKeyUsage(new[] { KeyPurposeID.IdKPServerAuth }));
79-
80-
// Signature Algorithm
81-
const string signatureAlgorithm = "SHA256WithRSA";
82-
var signatureFactory = new Asn1SignatureFactory(signatureAlgorithm, issuerKeyPair.Private);
83-
84-
// selfsign certificate
85-
var certificate = certificateGenerator.Generate(signatureFactory);
86-
87-
// correcponding private key
88-
var info = PrivateKeyInfoFactory.CreatePrivateKeyInfo(subjectKeyPair.Private);
89-
90-
// merge into X509Certificate2
91-
var x509 = new X509Certificate2(certificate.GetEncoded());
92-
var seq = (Asn1Sequence)Asn1Object.FromByteArray(info.ParsePrivateKey().GetDerEncoded());
93-
if (seq.Count != 9)
94-
{
95-
// throw new PemException("malformed sequence in RSA private key");
96-
}
97-
98-
var rsa = RsaPrivateKeyStructure.GetInstance(seq);
99-
var rsaparams = new RsaPrivateCrtKeyParameters(
100-
rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);
101-
x509.PrivateKey = ToDotNetKey(rsaparams); // x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
102-
return x509;
103-
}
104-
10525
private static X509Certificate2 GenerateSelfSignedCertificate(string subject)
10626
{
10727
const int keyStrength = 2048;
@@ -154,7 +74,7 @@ private static X509Certificate2 GenerateSelfSignedCertificate(string subject)
15474
// Add basic constraint
15575
certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(false));
15676

157-
certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false, new ExtendedKeyUsage(new[] { KeyPurposeID.IdKPServerAuth }));
77+
certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth));
15878

15979
// Signature Algorithm
16080
const string signatureAlgorithm = "SHA256WithRSA";
@@ -177,7 +97,15 @@ private static X509Certificate2 GenerateSelfSignedCertificate(string subject)
17797
var rsa = RsaPrivateKeyStructure.GetInstance(seq);
17898
var rsaparams = new RsaPrivateCrtKeyParameters(
17999
rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1, rsa.Exponent2, rsa.Coefficient);
180-
x509.PrivateKey = ToDotNetKey(rsaparams); // x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
100+
try
101+
{
102+
x509.PrivateKey = ToDotNetKey(rsaparams); // x509.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
103+
}
104+
catch (CryptographicException e)
105+
{
106+
throw new Exception($"Exception on cert generation!\nSubject {subject}\nHostname {Environment.MachineName}\nSequenceCount {seq.Count} (should be 9?)", e);
107+
}
108+
181109
return x509;
182110
}
183111

@@ -205,61 +133,6 @@ private static AsymmetricAlgorithm ToDotNetKey(RsaPrivateCrtKeyParameters privat
205133
return rsaProvider;
206134
}
207135

208-
// ReSharper disable once RedundantAssignment
209-
private static X509Certificate2 GenerateCACertificate(string subjectName, ref AsymmetricCipherKeyPair caKeyPair)
210-
{
211-
const int keyStrength = 2048;
212-
213-
// Generating Random Numbers
214-
var randomGenerator = new CryptoApiRandomGenerator();
215-
var random = new SecureRandom(randomGenerator);
216-
217-
// The Certificate Generator
218-
var certificateGenerator = new X509V3CertificateGenerator();
219-
220-
// Subject Public Key
221-
var keyGenerationParameters = new KeyGenerationParameters(random, keyStrength);
222-
var keyPairGenerator = new RsaKeyPairGenerator();
223-
keyPairGenerator.Init(keyGenerationParameters);
224-
caKeyPair = keyPairGenerator.GenerateKeyPair();
225-
226-
// Serial Number
227-
var serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(long.MaxValue), random);
228-
certificateGenerator.SetSerialNumber(serialNumber);
229-
230-
// Signature Algorithm
231-
const string signatureAlgorithm = "SHA256WithRSA";
232-
233-
// Set the public key
234-
certificateGenerator.SetPublicKey(caKeyPair.Public);
235-
certificateGenerator.AddExtension(X509Extensions.SubjectKeyIdentifier.Id, false, new SubjectKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(caKeyPair.Public)));
236-
237-
// Issuer and Subject Name
238-
var subjectDN = new X509Name(subjectName);
239-
certificateGenerator.SetSubjectDN(subjectDN);
240-
241-
// Issuer
242-
certificateGenerator.SetIssuerDN(subjectDN);
243-
certificateGenerator.AddExtension(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifier(SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(caKeyPair.Public)));
244-
245-
// Valid For
246-
var notBefore = DateTime.UtcNow.Date;
247-
var notAfter = notBefore.AddYears(2);
248-
certificateGenerator.SetNotBefore(notBefore);
249-
certificateGenerator.SetNotAfter(notAfter);
250-
251-
// Make this a CA
252-
certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(true));
253-
254-
// selfsign certificate
255-
var signatureFactory = new Asn1SignatureFactory(signatureAlgorithm, caKeyPair.Private);
256-
var certificate = certificateGenerator.Generate(signatureFactory);
257-
var x509 = new X509Certificate2(certificate.GetEncoded());
258-
return x509;
259-
260-
// return issuerKeyPair.Private;
261-
}
262-
263136
public static X509Certificate2 GetCert(string app, string hostname = "localhost")
264137
{
265138
var appPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), app);
@@ -276,17 +149,21 @@ public static X509Certificate2 GetCert(string app, string hostname = "localhost"
276149
}
277150
}
278151

279-
if (!File.Exists(certPfx))
152+
if (File.Exists(certPfx))
280153
{
281-
var clientCert = GenerateSelfSignedCertificate(hostname);
282-
var p12cert = clientCert.Export(X509ContentType.Pfx);
283-
Directory.CreateDirectory(appPath);
284-
var w = File.OpenWrite(certPfx);
285-
w.Write(p12cert, 0, p12cert.Length);
286-
w.Close();
154+
return new X509Certificate2(File.ReadAllBytes(certPfx), (string)null,
155+
X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
287156
}
288157

289-
return new X509Certificate2(File.ReadAllBytes(certPfx), (string)null, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
158+
var clientCert = GenerateSelfSignedCertificate(hostname);
159+
var p12Cert = clientCert.Export(X509ContentType.Pfx);
160+
Directory.CreateDirectory(appPath);
161+
var w = File.OpenWrite(certPfx);
162+
w.Write(p12Cert, 0, p12Cert.Length);
163+
w.Close();
164+
165+
return new X509Certificate2(File.ReadAllBytes(certPfx), (string)null,
166+
X509KeyStorageFlags.Exportable | X509KeyStorageFlags.PersistKeySet);
290167
}
291168
}
292169
}

0 commit comments

Comments
 (0)