public static async Task RsaCertificateCreateIntermediateCaTestAsync()
        {
            using (var mock = Setup()) {
                IKeyStore           keys    = mock.Create <KeyDatabase>();
                IDigestSigner       signer  = mock.Create <KeyDatabase>();
                ICertificateFactory factory = mock.Create <CertificateFactory>();

                Key       publicKey;
                KeyHandle issuerKey;
                Key       issuerPublicKey;
                using (var rsa1 = RSA.Create()) {
                    issuerKey = await keys.ImportKeyAsync("rsa1", rsa1.ToKey());

                    issuerPublicKey = rsa1.ToKey().GetPublicKey();
                }
                using (var rsa2 = RSA.Create()) {
                    await keys.ImportKeyAsync("rsa2", rsa2.ToKey());

                    publicKey = rsa2.ToKey().GetPublicKey();
                }

                var now   = DateTime.UtcNow;
                var intca = await factory.CreateCertificateAsync(signer, issuerKey,
                                                                 X500DistinguishedNameEx.Create("CN=leaf"), publicKey,
                                                                 now, now + TimeSpan.FromMinutes(1), SignatureType.PS256, true, sn => {
                    return(new List <X509Extension>());
                });
            }
        }
 /// <summary>
 /// Create signature generator.
 /// </summary>
 /// <param name="signKey">The signing key</param>
 /// <param name="signer">Digest signer to use</param>
 /// <param name="signature"></param>
 public X509SignatureGeneratorAdapter(IDigestSigner signer, KeyHandle signKey,
                                      SignatureType signature)
 {
     _signKey   = signKey ?? throw new ArgumentNullException(nameof(signKey));
     _signer    = signer ?? throw new ArgumentNullException(nameof(signer));
     _signature = signature;
 }
        public static async Task RsaCertificateCreateSelfSignedTestAsync()
        {
            using (var mock = Setup()) {
                IKeyStore           keys    = mock.Create <KeyDatabase>();
                IDigestSigner       signer  = mock.Create <KeyDatabase>();
                ICertificateFactory factory = mock.Create <CertificateFactory>();

                KeyHandle issuerKey;
                Key       issuerPublicKey;
                using (var rsa1 = RSA.Create()) {
                    issuerKey = await keys.ImportKeyAsync("rsa1", rsa1.ToKey(),
                                                          new KeyStoreProperties { Exportable = true });

                    issuerPublicKey = rsa1.ToKey().GetPublicKey();
                }

                var now  = DateTime.UtcNow;
                var cert = await factory.CreateCertificateAsync(signer, issuerKey,
                                                                X500DistinguishedNameEx.Create("CN=leaf"), issuerPublicKey,
                                                                now, now + TimeSpan.FromMinutes(1), SignatureType.RS256, false, sn => {
                    return(new List <X509Extension>());
                });

                var privateKey = await keys.ExportKeyAsync(issuerKey);

                using (cert) {
                    var certificate = cert.ToCertificate();
                    Assert.True(certificate.IsSelfSigned());
                    Assert.Equal(certificate.GetIssuerSerialNumberAsString(), certificate.GetSerialNumberAsString());
                }
            }
        }
        /// <summary>
        /// Create signed certificate from request
        /// </summary>
        /// <param name="request"></param>
        /// <param name="signer"></param>
        /// <param name="issuer"></param>
        /// <param name="signingKey"></param>
        /// <param name="signatureType"></param>
        /// <param name="notBefore"></param>
        /// <param name="notAfter"></param>
        /// <param name="serialNumber"></param>
        /// <returns></returns>
        public static X509Certificate2 Create(this CertificateRequest request, IDigestSigner signer,
                                              X500DistinguishedName issuer, KeyHandle signingKey, SignatureType signatureType,
                                              DateTime notBefore, DateTime notAfter, byte[] serialNumber)
        {
            var signatureGenerator = signer.CreateX509SignatureGenerator(
                signingKey, signatureType);
            var signedCert = request.Create(issuer, signatureGenerator, notBefore,
                                            notAfter, serialNumber);

            return(signedCert);
        }
 /// <summary>
 /// Create signature generator
 /// </summary>
 /// <param name="signer"></param>
 /// <param name="key"></param>
 /// <param name="signature"></param>
 /// <returns></returns>
 public static X509SignatureGenerator CreateX509SignatureGenerator(
     this IDigestSigner signer, KeyHandle key, SignatureType signature)
 {
     return(new X509SignatureGeneratorAdapter(signer, key, signature));
 }
        /// <inheritdoc/>
        public Task <X509Certificate2> CreateCertificateAsync(IDigestSigner signer,
                                                              Certificate issuer, X500DistinguishedName subjectName, Key pubKey,
                                                              DateTime notBefore, DateTime notAfter, SignatureType signatureType,
                                                              bool canIssue, Func <byte[], IEnumerable <X509Extension> > extensions,
                                                              CancellationToken ct)
        {
            try {
                if (issuer == null)
                {
                    throw new ArgumentNullException(nameof(issuer));
                }
                if (issuer.RawData == null)
                {
                    throw new ArgumentNullException(nameof(issuer.RawData));
                }
                if (issuer.IssuerPolicies == null)
                {
                    throw new ArgumentNullException(nameof(issuer.IssuerPolicies));
                }
                if (pubKey == null)
                {
                    throw new ArgumentNullException(nameof(pubKey));
                }

                // new serial number
                var serialNumber = new SerialNumber();

                // Create certificate request
                var request = pubKey.CreateCertificateRequest(subjectName, signatureType);

                // Basic constraints
                request.CertificateExtensions.Add(
                    new X509BasicConstraintsExtension(canIssue, !canIssue, 0, true));
                // Subject Key Identifier
                request.CertificateExtensions.Add(new X509SubjectKeyIdentifierExtension(
                                                      request.PublicKey, X509SubjectKeyIdentifierHashAlgorithm.Sha1, false));
                // Authority Key Identifier
                using (var issuerCert = issuer.ToX509Certificate2()) {
                    request.CertificateExtensions.Add(new X509AuthorityKeyIdentifierExtension(
                                                          issuerCert));
                }

                var keyUsages = X509KeyUsageFlags.None;
                if (extensions != null)
                {
                    foreach (var extension in extensions(serialNumber.Value))
                    {
                        if (extension == null ||
                            extension is X509BasicConstraintsExtension ||
                            extension is X509CrlDistributionPointsExtension ||
                            extension is X509SubjectKeyIdentifierExtension ||
                            extension is X509AuthorityKeyIdentifierExtension)
                        {
                            continue;
                        }
                        if (extension is X509CrlDistributionPointsExtension &&
                            canIssue &&
                            _config.AuthorityCrlRootUrl != null)
                        {
                            continue;
                        }
                        if (extension is X509KeyUsageExtension kux)
                        {
                            keyUsages = kux.KeyUsages;
                            continue;
                        }
                        request.CertificateExtensions.Add(extension);
                    }
                }
                if (canIssue)
                {
                    request.CertificateExtensions.Add(new X509KeyUsageExtension(
                                                          X509KeyUsageFlags.DigitalSignature |
                                                          X509KeyUsageFlags.KeyCertSign |
                                                          X509KeyUsageFlags.CrlSign | keyUsages, true));
                    if (_config?.AuthorityCrlRootUrl != null)
                    {
                        // add crl distribution point, if available
                        request.CertificateExtensions.Add(new X509CrlDistributionPointsExtension(
                                                              PatchUrl(_config.AuthorityCrlRootUrl, serialNumber.ToString())));
                    }
                }
                else
                {
                    // Key Usage
                    request.CertificateExtensions.Add(new X509KeyUsageExtension(
                                                          X509KeyUsageFlags.DigitalSignature |
                                                          X509KeyUsageFlags.DataEncipherment |
                                                          X509KeyUsageFlags.NonRepudiation |
                                                          X509KeyUsageFlags.KeyEncipherment | keyUsages, true));
                }

                if (_config?.AuthorityInfoRootUrl != null)
                {
                    // add information access point, if available for issuer authority
                    request.CertificateExtensions.Add(new X509AuthorityInformationAccessExtension(
                                                          PatchUrl(_config.AuthorityInfoRootUrl, issuer.GetSerialNumberAsString())));
                }

                // Adjust validity to issued certificate
                if (notAfter > issuer.NotAfterUtc)
                {
                    notAfter = issuer.NotAfterUtc;
                }
                if (notBefore < issuer.NotBeforeUtc)
                {
                    notBefore = issuer.NotBeforeUtc;
                }

                var signedCert = request.Create(signer, issuer, notBefore, notAfter, serialNumber.Value);
                return(Task.FromResult(signedCert));
            }
            catch (Exception ex) {
                return(Task.FromException <X509Certificate2>(ex));
            }
        }
        /// <inheritdoc/>
        Task <X509Certificate2> ICertificateFactory.CreateCertificateAsync(IDigestSigner signer,
                                                                           KeyHandle signingKey, X500DistinguishedName subject, Key pubKey,
                                                                           DateTime notBefore, DateTime notAfter, SignatureType signatureType,
                                                                           bool canIssue, Func <byte[], IEnumerable <X509Extension> > extensions, CancellationToken ct)
        {
            try {
                if (signingKey == null)
                {
                    throw new ArgumentNullException(nameof(signingKey));
                }
                if (pubKey == null)
                {
                    throw new ArgumentNullException(nameof(pubKey));
                }

                // new serial number
                var serialNumber = new SerialNumber();
                // Create certificate request
                var request = pubKey.CreateCertificateRequest(subject, signatureType);

                // Basic constraints
                request.CertificateExtensions.Add(new X509BasicConstraintsExtension(
                                                      canIssue, !canIssue, 0, true));
                // Subject Key Identifier
                var ski = new X509SubjectKeyIdentifierExtension(request.PublicKey,
                                                                X509SubjectKeyIdentifierHashAlgorithm.Sha1, false);
                request.CertificateExtensions.Add(ski);
                // Authority key kdentifier
                request.CertificateExtensions.Add(new X509AuthorityKeyIdentifierExtension(
                                                      subject.Name, serialNumber, ski.SubjectKeyIdentifier));

                var keyUsages = X509KeyUsageFlags.None;
                if (extensions != null)
                {
                    foreach (var extension in extensions(serialNumber.Value))
                    {
                        if (extension == null ||
                            extension is X509BasicConstraintsExtension ||
                            extension is X509SubjectKeyIdentifierExtension ||
                            extension is X509AuthorityKeyIdentifierExtension)
                        {
                            continue;
                        }
                        if (extension is X509CrlDistributionPointsExtension &&
                            canIssue &&
                            _config?.AuthorityCrlRootUrl != null)
                        {
                            continue;
                        }
                        if (extension is X509KeyUsageExtension kux)
                        {
                            keyUsages = kux.KeyUsages;
                            continue;
                        }
                        request.CertificateExtensions.Add(extension);
                    }
                }
                if (canIssue)
                {
                    request.CertificateExtensions.Add(new X509KeyUsageExtension(
                                                          X509KeyUsageFlags.DigitalSignature |
                                                          X509KeyUsageFlags.KeyCertSign |
                                                          X509KeyUsageFlags.CrlSign | keyUsages, true));

                    if (_config?.AuthorityCrlRootUrl != null)
                    {
                        // add crl distribution point, if available
                        request.CertificateExtensions.Add(new X509CrlDistributionPointsExtension(
                                                              PatchUrl(_config.AuthorityCrlRootUrl, serialNumber.ToString())));
                    }
                }
                else
                {
                    // Key Usage
                    request.CertificateExtensions.Add(new X509KeyUsageExtension(
                                                          X509KeyUsageFlags.DigitalSignature |
                                                          X509KeyUsageFlags.DataEncipherment |
                                                          X509KeyUsageFlags.NonRepudiation |
                                                          X509KeyUsageFlags.KeyEncipherment | keyUsages, true));
                }

                var signedCert = request.Create(signer, subject, signingKey, signatureType,
                                                notBefore, notAfter, serialNumber.Value);
                return(Task.FromResult(signedCert));
            }
            catch (Exception ex) {
                return(Task.FromException <X509Certificate2>(ex));
            }
        }
Beispiel #8
0
 /// <summary>
 /// Create factory
 /// </summary>
 /// <param name="signer"></param>
 public CrlFactory(IDigestSigner signer)
 {
     _signer = signer ?? throw new ArgumentNullException(nameof(signer));
 }
 /// <summary>
 /// Create signed certificate from request
 /// </summary>
 /// <param name="request"></param>
 /// <param name="signer"></param>
 /// <param name="issuer"></param>
 /// <param name="notBefore"></param>
 /// <param name="notAfter"></param>
 /// <param name="serialNumber"></param>
 /// <returns></returns>
 public static X509Certificate2 Create(this CertificateRequest request, IDigestSigner signer,
                                       Certificate issuer, DateTime notBefore, DateTime notAfter, byte[] serialNumber)
 {
     return(Create(request, signer, issuer.Subject, issuer.KeyHandle,
                   issuer.IssuerPolicies.SignatureType.Value, notBefore, notAfter, serialNumber));
 }