Created
January 5, 2016 23:05
-
-
Save fearthecowboy/780b57516d76e0c94546 to your computer and use it in GitHub Desktop.
uses GenerateSelfSignedCertificate to generate an SSL cert
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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