Beispiel #1
0
        public unsafe X509Certificate2 GenerateCertificateAuthority(PrivateKey privateKey, X500DistinguishedName dn, HashAlgorithm signatureAlgorithm, 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())
                        {
                            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));
                    }
                }
            }
        }