/// <summary>
        /// Renews a <see cref="X509Certificate2"/>. This keeps all but the serial number, effective date, and expiration date./>
        /// </summary>
        /// <param name="certificate">Certificate being renewed</param>
        /// <param name="effectiveDate">New effective date</param>
        /// <param name="expirationDate">New expiration date</param>
        /// <param name="caCertificate">Signing certificate</param>
        /// <returns>New <seealso cref="X509Certificate2"/> renewed from <paramref name="certificate"/></returns>
        public static X509Certificate2 Renew(X509Certificate2 certificate, DateTime effectiveDate, DateTime expirationDate,
                                             X509Certificate2 caCertificate)
        {
            AsymmetricKeyParameter signingKey = caCertificate == null ? null : Certificate.TransformRSAPrivateKey((RSACryptoServiceProvider)caCertificate.PrivateKey);
            var privateKeyParameter           = TransformRSAPrivateKey((RSACryptoServiceProvider)certificate.PrivateKey);
            var bcCert                      = DotNetUtilities.FromX509Certificate(certificate);
            var publicKeyParameter          = bcCert.GetPublicKey();
            AsymmetricCipherKeyPair keyPair = new AsymmetricCipherKeyPair(publicKeyParameter, privateKeyParameter);

            X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
            BigInteger serialNumber            = CreateSerialNumber();

            certGen.SetSerialNumber(serialNumber);
            certGen.SetIssuerDN(bcCert.IssuerDN);

            // Converted time to Universal Time so that the time set when calling Generate is the same as the time specified
            certGen.SetNotBefore(effectiveDate.ToUniversalTime());
            certGen.SetNotAfter(expirationDate.ToUniversalTime());

            certGen.SetSubjectDN(bcCert.SubjectDN);
            certGen.SetPublicKey(keyPair.Public);
            certGen.SetSignatureAlgorithm(SIGNATURE_ALGORITHM);

            // Copy all extensions
            foreach (var ext in certificate.Extensions)
            {
                certGen.CopyAndAddExtension(ext.Oid.Value, ext.Critical, bcCert);
            }

            Org.BouncyCastle.X509.X509Certificate bcNewCert = certGen.Generate(signingKey ?? keyPair.Private);

            X509Certificate2 dotNetCert = new X509Certificate2(bcNewCert.GetEncoded())
            {
                // Restore private key
                PrivateKey = certificate.PrivateKey
            };

            return(dotNetCert);
        }