Commit 766b3616 authored by Honfika's avatar Honfika

BC Cert Maker simplified and fixed

parent 5d8a30b3
......@@ -63,7 +63,7 @@ namespace Titanium.Web.Proxy.Examples.Wpf
public MainWindow()
{
proxyServer = new ProxyServer();
proxyServer.CertificateEngine = CertificateEngine.DefaultWindows;
//proxyServer.CertificateEngine = CertificateEngine.BouncyCastle;
proxyServer.TrustRootCertificate = true;
proxyServer.CertificateManager.TrustRootCertificateAsAdministrator();
proxyServer.ForwardToUpstreamGateway = true;
......
......@@ -88,6 +88,7 @@ namespace Titanium.Web.Proxy.Network.Certificate
var subjectAlternativeNamesExtension = new DerSequence(subjectAlternativeNames);
certificateGenerator.AddExtension(X509Extensions.SubjectAlternativeName.Id, false, subjectAlternativeNamesExtension);
}
// Subject Public Key
var keyGenerationParameters = new KeyGenerationParameters(secureRandom, keyStrength);
var keyPairGenerator = new RsaKeyPairGenerator();
......@@ -98,6 +99,10 @@ namespace Titanium.Web.Proxy.Network.Certificate
// Set certificate intended purposes to only Server Authentication
certificateGenerator.AddExtension(X509Extensions.ExtendedKeyUsage.Id, false, new ExtendedKeyUsage(KeyPurposeID.IdKPServerAuth));
if (issuerPrivateKey == null)
{
certificateGenerator.AddExtension(X509Extensions.BasicConstraints.Id, true, new BasicConstraints(true));
}
var signatureFactory = new Asn1SignatureFactory(signatureAlgorithm, issuerPrivateKey ?? subjectKeyPair.Private, secureRandom);
......@@ -118,35 +123,14 @@ namespace Titanium.Web.Proxy.Network.Certificate
var rsaparams = new RsaPrivateCrtKeyParameters(rsa.Modulus, rsa.PublicExponent, rsa.PrivateExponent, rsa.Prime1, rsa.Prime2, rsa.Exponent1,
rsa.Exponent2, rsa.Coefficient);
#if NET45
// Set private key onto certificate instance
var x509Certificate = new X509Certificate2(certificate.GetEncoded());
x509Certificate.PrivateKey = DotNetUtilities.ToRSA(rsaparams);
x509Certificate.FriendlyName = subjectName;
#else
var x509Certificate = WithPrivateKey(certificate, rsaparams);
x509Certificate.FriendlyName = subjectName;
#endif
return x509Certificate;
}
private static X509Certificate2 WithPrivateKey(Org.BouncyCastle.X509.X509Certificate certificate, AsymmetricKeyParameter privateKey)
{
const string password = "password";
var store = new Pkcs12Store();
var entry = new X509CertificateEntry(certificate);
store.SetCertificateEntry(certificate.SubjectDN.ToString(), entry);
store.SetKeyEntry(certificate.SubjectDN.ToString(), new AsymmetricKeyEntry(privateKey), new[] { entry });
using (var ms = new MemoryStream())
{
store.Save(ms, password.ToCharArray(), new SecureRandom(new CryptoApiRandomGenerator()));
return new X509Certificate2(ms.ToArray(), password, X509KeyStorageFlags.Exportable);
}
}
/// <summary>
/// Makes the certificate internal.
/// </summary>
......@@ -173,39 +157,11 @@ namespace Titanium.Web.Proxy.Network.Certificate
}
else
{
#if NET45
var kp = DotNetUtilities.GetKeyPair(signingCertificate.PrivateKey);
#else
var rsa = signingCertificate.GetRSAPrivateKey();
var kp = GetRsaKeyPair(rsa.ExportParameters(true));
#endif
return GenerateCertificate(hostName, subjectName, signingCertificate.Subject, validFrom, validTo, issuerPrivateKey: kp.Private);
}
}
static AsymmetricCipherKeyPair GetRsaKeyPair(RSAParameters rp)
{
BigInteger modulus = new BigInteger(1, rp.Modulus);
BigInteger pubExp = new BigInteger(1, rp.Exponent);
RsaKeyParameters pubKey = new RsaKeyParameters(
false,
modulus,
pubExp);
RsaPrivateCrtKeyParameters privKey = new RsaPrivateCrtKeyParameters(
modulus,
pubExp,
new BigInteger(1, rp.D),
new BigInteger(1, rp.P),
new BigInteger(1, rp.Q),
new BigInteger(1, rp.DP),
new BigInteger(1, rp.DQ),
new BigInteger(1, rp.InverseQ));
return new AsymmetricCipherKeyPair(pubKey, privKey);
}
/// <summary>
/// Makes the certificate internal.
/// </summary>
......@@ -244,41 +200,5 @@ namespace Titanium.Web.Proxy.Network.Certificate
return MakeCertificateInternal(isRoot, subject, $"CN={subject}", DateTime.UtcNow.AddDays(-certificateGraceDays), DateTime.UtcNow.AddDays(certificateValidDays), isRoot ? null : signingCert);
}
class CryptoApiRandomGenerator : IRandomGenerator
{
readonly RandomNumberGenerator rndProv;
public CryptoApiRandomGenerator()
{
rndProv = RandomNumberGenerator.Create();
}
public void AddSeedMaterial(byte[] seed) { }
public void AddSeedMaterial(long seed) { }
public void NextBytes(byte[] bytes)
{
rndProv.GetBytes(bytes);
}
public void NextBytes(byte[] bytes, int start, int len)
{
if (start < 0)
throw new ArgumentException("Start offset cannot be negative", "start");
if (bytes.Length < (start + len))
throw new ArgumentException("Byte array too small for requested offset and length");
if (bytes.Length == len && start == 0)
{
NextBytes(bytes);
}
else
{
byte[] tmpBuf = new byte[len];
NextBytes(tmpBuf);
Array.Copy(tmpBuf, 0, bytes, start, len);
}
}
}
}
}
......@@ -12,7 +12,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Portable.BouncyCastle" Version="1.8.1.2" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.1.3" />
<PackageReference Include="StreamExtended" Version="1.0.81" />
</ItemGroup>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment