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)); } }
/// <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)); }