@@ -478,7 +478,7 @@ std::shared_ptr<X509> GetX509Certificate(const String& pemfile)
478
478
return std::shared_ptr<X509>(cert, X509_free);
479
479
}
480
480
481
- int MakeX509CSR (const String& cn, const String& keyfile, const String& csrfile, const String& certfile, int validFor, bool ca)
481
+ int MakeX509CSR (const String& cn, const String& keyfile, const String& csrfile, const String& certfile, long validFor, bool ca)
482
482
{
483
483
char errbuf[256 ];
484
484
@@ -640,7 +640,7 @@ int MakeX509CSR(const String& cn, const String& keyfile, const String& csrfile,
640
640
return 1 ;
641
641
}
642
642
643
- std::shared_ptr<X509> CreateCert (EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, int validFor, bool ca)
643
+ std::shared_ptr<X509> CreateCert (EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME *issuer, EVP_PKEY *cakey, long validFor, bool ca)
644
644
{
645
645
X509 *cert = X509_new ();
646
646
X509_set_version (cert, 2 );
@@ -649,7 +649,7 @@ std::shared_ptr<X509> CreateCert(EVP_PKEY *pubkey, X509_NAME *subject, X509_NAME
649
649
notBefore = validFor - validFor / 4 ; // Add 25% of the validity period to the past
650
650
}
651
651
X509_gmtime_adj (X509_get_notBefore (cert), notBefore);
652
- X509_gmtime_adj (X509_get_notAfter (cert), validFor);
652
+ X509_gmtime_adj (X509_get_notAfter (cert), NormalizeCertValidFor ( validFor) );
653
653
X509_set_pubkey (cert, pubkey);
654
654
655
655
X509_set_subject_name (cert, subject);
@@ -732,7 +732,7 @@ String GetIcingaCADir()
732
732
return Configuration::DataDir + " /ca" ;
733
733
}
734
734
735
- std::shared_ptr<X509> CreateCertIcingaCA (EVP_PKEY *pubkey, X509_NAME *subject, int validFor, bool ca)
735
+ std::shared_ptr<X509> CreateCertIcingaCA (EVP_PKEY *pubkey, X509_NAME *subject, long validFor, bool ca)
736
736
{
737
737
char errbuf[256 ];
738
738
@@ -779,7 +779,7 @@ std::shared_ptr<X509> CreateCertIcingaCA(EVP_PKEY *pubkey, X509_NAME *subject, i
779
779
* @param validFor The validity period in seconds. Defaults to LEAF_VALID_FOR.
780
780
* @returns The new X509 certificate or an empty shared_ptr on error.
781
781
*/
782
- std::shared_ptr<X509> CreateCertIcingaCA (const std::shared_ptr<X509>& cert, int validFor)
782
+ std::shared_ptr<X509> CreateCertIcingaCA (const std::shared_ptr<X509>& cert, long validFor)
783
783
{
784
784
std::shared_ptr<EVP_PKEY> pkey = std::shared_ptr<EVP_PKEY>(X509_get_pubkey (cert.get ()), EVP_PKEY_free);
785
785
return CreateCertIcingaCA (pkey.get (), X509_get_subject_name (cert.get ()), validFor);
@@ -812,6 +812,30 @@ bool IsCaUptodate(X509* cert)
812
812
return !CertExpiresWithin (cert, LEAF_VALID_FOR);
813
813
}
814
814
815
+ /* *
816
+ * Normalizes the specified certificate validity period in seconds to avoid
817
+ * issues with 32-bit time_t wrap-around in 2038.
818
+ *
819
+ * On 64-bit systems this function simply returns the specified value. On 32-bit systems it ensures that
820
+ * the current time plus the specified value never overflows the maximum value of time_t. Otherwise, the
821
+ * returned value is adjusted so that the sum is exactly the maximum value of time_t.
822
+ *
823
+ * @param seconds The desired validity period in seconds.
824
+ * @returns The normalized validity period in seconds.
825
+ */
826
+ long NormalizeCertValidFor (long seconds)
827
+ {
828
+ if constexpr (sizeof (time_t ) > sizeof (int32_t )) {
829
+ return seconds;
830
+ }
831
+
832
+ constexpr time_t maxTimeT = static_cast <time_t >(std::numeric_limits<int32_t >::max ());
833
+ if (auto rem = maxTimeT - time (nullptr ); rem < seconds) {
834
+ return rem;
835
+ }
836
+ return seconds;
837
+ }
838
+
815
839
String CertificateToString (X509* cert)
816
840
{
817
841
BIO *mem = BIO_new (BIO_s_mem ());
0 commit comments