Skip to content

Instantly share code, notes, and snippets.

@fearthecowboy
Created January 5, 2016 23:05
Show Gist options
  • Save fearthecowboy/780b57516d76e0c94546 to your computer and use it in GitHub Desktop.
Save fearthecowboy/780b57516d76e0c94546 to your computer and use it in GitHub Desktop.
uses GenerateSelfSignedCertificate to generate an SSL cert
public unsafe X509Certificate2 GenerateSelfSignedCertificate(PrivateKey privateKey, X500DistinguishedName dn, HashAlgorithm signatureAlgorithm, string[] dnsNames, IPAddress[] ipAddresses = null, DateTime? notBefore = null, DateTime? notAfter = null)
{
fixed (byte* dnPtr = dn.RawData)
{
var blob = new NATIVE_CRYPTOAPI_BLOB
{
cbData = (uint)dn.RawData.Length,
pbData = dnPtr
};
var signatureAlgorithmIdentifier = new CRYPT_ALGORITHM_IDENTIFIER
{
pszObjId = HashAlgorithmToSignatureAlgorithm(privateKey, signatureAlgorithm)
};
using (var extensions = new MarshalX509ExtensionCollection())
{
using (extensions.Freeze())
{
var usage = X509KeyUsageFlags.DigitalSignature;
if (privateKey.AlgorithmGroup == AlgorithmGroup.RSA)
{
//Key encipherment is not valid for DSA/ECDSA
usage |= X509KeyUsageFlags.KeyEncipherment;
}
extensions.Add(new X509BasicConstraintsExtension(false, false, 0, true));
extensions.Add(new X509KeyUsageExtension(usage, true));
extensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid(OIDs.EKU_SERVER) }, false));
extensions.Add(new X509SubjectAlternativeNameExtension(DnsAltNamesFromArray(dnsNames, ipAddresses ?? new IPAddress[0]), false));
// extensions.Add(new X509BasicConstraintsExtension(true, true, 1, true));
// extensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.CrlSign | X509KeyUsageFlags.KeyCertSign, true));
// extensions.Add(new X509EnhancedKeyUsageExtension(new OidCollection { new Oid(OIDs.EKU_SERVER) }, false));
using (var publicKey = privateKey.ToPublicKey())
{
using (var sha1 = new SHA1CryptoServiceProvider())
{
var pubKeyHash = sha1.ComputeHash(publicKey.Key);
extensions.Add(new X509SubjectKeyIdentifierExtension(pubKeyHash, false));
extensions.Add(new X509AuthorityKeyIdentifierExtension(pubKeyHash, null));
}
}
}
var certExtensions = extensions.Extensions;
var keyProvInfo = new CRYPT_KEY_PROV_INFO
{
cProvParam = 0,
dwKeySpec = privateKey.KeySpec,
dwProvType = privateKey.Handle.IsNCryptKey ? ProviderType.CNG : ProviderType.PROV_RSA_AES,
pwszProvName = privateKey.ProviderName,
dwFlags = 0,
pwszContainerName = privateKey.Name
};
var beginning = new SYSTEMTIME(notBefore ?? DateTime.UtcNow.AddHours(-1));
var expiration = new SYSTEMTIME(notAfter ?? DateTime.UtcNow.AddHours(-1).AddYears(30));
var certContext = Crypt32.CertCreateSelfSignCertificate(privateKey.Handle, ref blob, SelfSignFlags.NONE, ref keyProvInfo, ref signatureAlgorithmIdentifier, beginning, expiration, ref certExtensions);
if (certContext == IntPtr.Zero)
{
throw new Win32Exception(Marshal.GetLastWin32Error());
}
return new X509Certificate2(certContext);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment