예제 #1
0
        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);
        }
예제 #2
0
        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)));
        }
예제 #4
0
        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);
        }
예제 #5
0
        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));
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }