public void CrlInternalBuilderTest() { var dname = new X500DistinguishedName("CN=Test"); var hash = HashAlgorithmName.SHA256; var crlBuilder = CrlBuilder.Create(dname, hash) .SetNextUpdate(DateTime.Today.AddDays(30)); byte[] serial = new byte[] { 4, 5, 6, 7 }; var revokedarray = new RevokedCertificate(serial); crlBuilder.RevokedCertificates.Add(revokedarray); string serstring = "45678910"; var revokedstring = new RevokedCertificate(serstring); crlBuilder.RevokedCertificates.Add(revokedstring); crlBuilder.CrlExtensions.Add(X509Extensions.BuildCRLNumber(123)); var crlEncoded = crlBuilder.Encode(); Assert.NotNull(crlEncoded); var x509Crl = new X509CRL(); x509Crl.DecodeCrl(crlEncoded); Assert.NotNull(x509Crl); Assert.NotNull(x509Crl.CrlExtensions); Assert.NotNull(x509Crl.RevokedCertificates); Assert.AreEqual(dname.RawData, x509Crl.IssuerName.RawData); //Assert.AreEqual(crlBuilder.ThisUpdate, x509Crl.ThisUpdate); //Assert.AreEqual(crlBuilder.NextUpdate, x509Crl.NextUpdate); Assert.AreEqual(2, x509Crl.RevokedCertificates.Count); Assert.AreEqual(serial, x509Crl.RevokedCertificates[0].UserCertificate); Assert.AreEqual(serstring, x509Crl.RevokedCertificates[1].SerialNumber); Assert.AreEqual(1, x509Crl.CrlExtensions.Count); Assert.AreEqual(hash, x509Crl.HashAlgorithmName); }
public void CrlBuilderTest(KeyHashPair keyHashPair) { var crlBuilder = CrlBuilder.Create(m_issuerCert.SubjectName, keyHashPair.HashAlgorithmName) .SetThisUpdate(DateTime.UtcNow.Date) .SetNextUpdate(DateTime.UtcNow.Date.AddDays(30)); // little endian byte array as serial number? byte[] serial = new byte[] { 4, 5, 6, 7 }; var revokedarray = new RevokedCertificate(serial); crlBuilder.RevokedCertificates.Add(revokedarray); string serstring = "123456789101"; var revokedstring = new RevokedCertificate(serstring); crlBuilder.RevokedCertificates.Add(revokedstring); crlBuilder.CrlExtensions.Add(X509Extensions.BuildCRLNumber(1111)); crlBuilder.CrlExtensions.Add(X509Extensions.BuildAuthorityKeyIdentifier(m_issuerCert)); var i509Crl = crlBuilder.CreateForRSA(m_issuerCert); X509CRL x509Crl = new X509CRL(i509Crl.RawData); Assert.NotNull(x509Crl); Assert.NotNull(x509Crl.CrlExtensions); Assert.NotNull(x509Crl.RevokedCertificates); Assert.AreEqual(m_issuerCert.SubjectName.RawData, x509Crl.IssuerName.RawData); Assert.AreEqual(crlBuilder.ThisUpdate, x509Crl.ThisUpdate); Assert.AreEqual(crlBuilder.NextUpdate, x509Crl.NextUpdate); Assert.AreEqual(2, x509Crl.RevokedCertificates.Count); Assert.AreEqual(serial, x509Crl.RevokedCertificates[0].UserCertificate); Assert.AreEqual(serstring, x509Crl.RevokedCertificates[1].SerialNumber); Assert.AreEqual(2, x509Crl.CrlExtensions.Count); Assert.True(x509Crl.VerifySignature(new X509Certificate2(m_issuerCert.RawData), true)); }
/// <summary> /// Revoke the certificates. /// </summary> /// <remarks> /// Merge all existing revoked certificates from CRL list. /// Add serialnumbers of new revoked certificates. /// The CRL number is increased by one and the new CRL is returned. /// </remarks> public static X509CRL RevokeCertificate( X509Certificate2 issuerCertificate, X509CRLCollection issuerCrls, X509Certificate2Collection revokedCertificates, DateTime thisUpdate, DateTime nextUpdate ) { if (!issuerCertificate.HasPrivateKey) { throw new ServiceResultException(StatusCodes.BadCertificateInvalid, "Issuer certificate has no private key, cannot revoke certificate."); } BigInteger crlSerialNumber = 0; var crlRevokedList = new Dictionary <string, RevokedCertificate>(); // merge all existing revocation list if (issuerCrls != null) { foreach (X509CRL issuerCrl in issuerCrls) { var extension = X509Extensions.FindExtension <X509CrlNumberExtension>(issuerCrl.CrlExtensions); if (extension != null && extension.CrlNumber > crlSerialNumber) { crlSerialNumber = extension.CrlNumber; } foreach (var revokedCertificate in issuerCrl.RevokedCertificates) { if (!crlRevokedList.ContainsKey(revokedCertificate.SerialNumber)) { crlRevokedList[revokedCertificate.SerialNumber] = revokedCertificate; } } } } // add existing serial numbers if (revokedCertificates != null) { foreach (var cert in revokedCertificates) { if (!crlRevokedList.ContainsKey(cert.SerialNumber)) { var entry = new RevokedCertificate(cert.SerialNumber, CRLReason.PrivilegeWithdrawn); crlRevokedList[cert.SerialNumber] = entry; } } } CrlBuilder crlBuilder = CrlBuilder.Create(issuerCertificate.SubjectName) .AddRevokedCertificates(crlRevokedList.Values.ToList()) .SetThisUpdate(thisUpdate) .SetNextUpdate(nextUpdate) .AddCRLExtension(X509Extensions.BuildAuthorityKeyIdentifier(issuerCertificate)) .AddCRLExtension(X509Extensions.BuildCRLNumber(crlSerialNumber + 1)); return(new X509CRL(crlBuilder.CreateForRSA(issuerCertificate))); }
public void CreateCRL() { // little endian byte array as serial number? byte[] serial = new byte[] { 1, 2, 3 }; var revokedarray = new RevokedCertificate(serial); var crlBuilder = CrlBuilder.Create(m_issuerCert.SubjectName, HashAlgorithmName.SHA256) .SetThisUpdate(DateTime.UtcNow.Date) .SetNextUpdate(DateTime.UtcNow.Date.AddDays(30)); crlBuilder.RevokedCertificates.Add(revokedarray); crlBuilder.CrlExtensions.Add(X509Extensions.BuildCRLNumber(1)); crlBuilder.CrlExtensions.Add(X509Extensions.BuildAuthorityKeyIdentifier(m_issuerCert)); _ = crlBuilder.CreateForRSA(m_issuerCert); }
public void CrlBuilderTestWithSignatureGenerator(KeyHashPair keyHashPair) { var crlBuilder = CrlBuilder.Create(m_issuerCert.SubjectName, keyHashPair.HashAlgorithmName) .SetThisUpdate(DateTime.UtcNow.Date) .SetNextUpdate(DateTime.UtcNow.Date.AddDays(30)); // little endian byte array as serial number? byte[] serial = new byte[] { 4, 5, 6, 7 }; var revokedarray = new RevokedCertificate(serial); crlBuilder.RevokedCertificates.Add(revokedarray); string serstring = "709876543210"; var revokedstring = new RevokedCertificate(serstring); crlBuilder.RevokedCertificates.Add(revokedstring); crlBuilder.CrlExtensions.Add(X509Extensions.BuildCRLNumber(1111)); crlBuilder.CrlExtensions.Add(X509Extensions.BuildAuthorityKeyIdentifier(m_issuerCert)); IX509CRL ix509Crl; using (RSA rsa = m_issuerCert.GetRSAPrivateKey()) { X509SignatureGenerator generator = X509SignatureGenerator.CreateForRSA(rsa, RSASignaturePadding.Pkcs1); ix509Crl = crlBuilder.CreateSignature(generator); } X509CRL x509Crl = new X509CRL(ix509Crl); Assert.NotNull(x509Crl); Assert.NotNull(x509Crl.CrlExtensions); Assert.NotNull(x509Crl.RevokedCertificates); Assert.AreEqual(m_issuerCert.SubjectName.RawData, x509Crl.IssuerName.RawData); Assert.AreEqual(crlBuilder.ThisUpdate, x509Crl.ThisUpdate); Assert.AreEqual(crlBuilder.NextUpdate, x509Crl.NextUpdate); Assert.AreEqual(2, x509Crl.RevokedCertificates.Count); Assert.AreEqual(serial, x509Crl.RevokedCertificates[0].UserCertificate); Assert.AreEqual(serstring, x509Crl.RevokedCertificates[1].SerialNumber); Assert.AreEqual(2, x509Crl.CrlExtensions.Count); using (var issuerPubKey = new X509Certificate2(m_issuerCert.RawData)) { Assert.True(x509Crl.VerifySignature(issuerPubKey, true)); } }
public void GlobalSetup() { m_issuerCert = CertificateBuilder.Create("CN=Root CA") .SetCAConstraint() .CreateForRSA(); m_certificate = CertificateBuilder.Create("CN=TestCert") .SetNotBefore(DateTime.Today.AddDays(-1)) .AddExtension( new X509SubjectAltNameExtension("urn:opcfoundation.org:mypc", new string[] { "mypc", "mypc.opcfoundation.org", "192.168.1.100" })) .CreateForRSA(); var crlBuilder = CrlBuilder.Create(m_issuerCert.SubjectName, HashAlgorithmName.SHA256) .SetThisUpdate(DateTime.UtcNow.Date) .SetNextUpdate(DateTime.UtcNow.Date.AddDays(30)); var revokedarray = new RevokedCertificate(m_certificate.SerialNumber); crlBuilder.RevokedCertificates.Add(revokedarray); crlBuilder.CrlExtensions.Add(X509Extensions.BuildCRLNumber(1)); crlBuilder.CrlExtensions.Add(X509Extensions.BuildAuthorityKeyIdentifier(m_issuerCert)); m_issuerCrl = crlBuilder.CreateForRSA(m_issuerCert); m_x509Crl = new X509CRL(m_issuerCrl.RawData); var random = new Random(); m_rsaPrivateKey = m_certificate.GetRSAPrivateKey(); m_rsaPublicKey = m_certificate.GetRSAPublicKey(); // blob size for RSA padding OaepSHA256 int blobSize = m_rsaPublicKey.KeySize / 8 - 66; m_randomByteArray = new byte[blobSize]; random.NextBytes(m_randomByteArray); m_encryptedByteArray = m_rsaPublicKey.Encrypt(m_randomByteArray, RSAEncryptionPadding.OaepSHA256); m_signature = m_rsaPrivateKey.SignData(m_randomByteArray, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); }
private int InternalRun() { bool isRoot = string.IsNullOrEmpty(Options.IssuerName); var builder = new CertificateBuilder(Options.KeyStrength, Options.SignatureAlgorithm, Logger); X509Certificate bcCertificate; // Key pair of the issuing certificate. AsymmetricCipherKeyPair issuingKeyPair = null; // Key pair for the generated certificate. AsymmetricCipherKeyPair generatedKeyPair = null; X509Certificate2 storeCertificate = null; // Root self signed certificate. if (isRoot) { // Builder path for Root CA bcCertificate = builder .AddSKID() .AddSerialNumber() .AddValidityTime() .AddExtendedKeyUsages() .AddSubjectCommonName(Options.CommonName) .AddIssuerCommonName(Options.CommonName) // Self Signed .MakeCA() .GenerateRootWithPrivateKey(out issuingKeyPair); } else { storeCertificate = LoadCACertificate(Options.IssuerName); builder = new CertificateBuilder(Options.KeyStrength, Options.SignatureAlgorithm, Logger); if (!ValidateIssuer(storeCertificate)) { throw new CertificateException( "Provided certificate is not a valid CA and therefore cannot issue other certificates."); } issuingKeyPair = DotNetUtilities.GetKeyPair(storeCertificate.PrivateKey); string[] dpUrls = Options.DistributionPoints.Count() > 0 ? Options.DistributionPoints.ToArray(): MenuInterupts.GetCrlDistributionPoints(); bcCertificate = builder .AddSKID() .AddSerialNumber() .AddValidityTime() .AddExtendedKeyUsages() .AddSubjectCommonName(Options.CommonName) .AddIssuerCommonName(Options.IssuerName) // Generate from CA. .AddAKID(issuingKeyPair.Public) .AddCRLDistributionPoints(dpUrls) .MakeCA() .Generate(issuingKeyPair.Private, out generatedKeyPair); } var convertedCertificate = GetWindowsCertFromGenerated(bcCertificate, Options.CommonName, isRoot ? issuingKeyPair.Private : generatedKeyPair.Private, builder.SecureRandom); if (Options.Debug) { DisplayCertificateDebugInfo(convertedCertificate); } if (!string.IsNullOrEmpty(Options.ExportLocation)) { // Export the certificate to the var exportPath = Path.Combine($"{Options.ExportLocation}", $"{Helper.StringToCNString(Options.CommonName)}.pfx"); File.WriteAllBytes(exportPath, convertedCertificate.Export(X509ContentType.Pkcs12)); } else { // Add CA certificate to Root store var machineStore = new X509Store(isRoot ? StoreName.Root : StoreName.CertificateAuthority, StoreLocation.LocalMachine); machineStore.Open(OpenFlags.ReadWrite); machineStore.Add(convertedCertificate); machineStore.Close(); } // Get our crl choice for this certificate authority. bool generateCrl = Options.GenerateCRL ? Options.GenerateCRL : MenuInterupts.GetCrlChoice(); if (generateCrl) { var crlKeyPair = isRoot ? issuingKeyPair : generatedKeyPair; var crlBuilder = new CrlBuilder(); var crl = crlBuilder .AddIssuerName(Options.CommonName) .AddUpdatePeriod() .AddAKID(crlKeyPair.Public) .Generate(crlKeyPair.Private); var crlPostFix = Configuration["certificateSettings:crlPostFix"]; var exportPath = Path.Join(Configuration["certificateSettings:crlExportPath"], $"{Options.CommonName}{crlPostFix}.crl"); File.WriteAllBytes(exportPath, crl.GetEncoded()); Logger.Info($"CRL Generated at {exportPath}"); } return(SUCCESS); }