From 1b2bc7b1e34e075dd1eb72d458a1c4859454ffa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= <sebastien.blin@savoirfairelinux.com> Date: Mon, 3 Jan 2022 16:10:01 -0500 Subject: [PATCH] crypto: add parameter to change Certificate's validity period This allow to create certificate with a different validity than 10 years and be able to change the expiration of a certificate --- include/opendht/crypto.h | 10 ++++++++-- src/crypto.cpp | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/include/opendht/crypto.h b/include/opendht/crypto.h index c734b704..70b68f52 100644 --- a/include/opendht/crypto.h +++ b/include/opendht/crypto.h @@ -541,8 +541,8 @@ struct OPENDHT_PUBLIC Certificate { void addRevocationList(RevocationList&&); void addRevocationList(std::shared_ptr<RevocationList>); - static Certificate generate(const PrivateKey& key, const std::string& name = "dhtnode", const Identity& ca = {}, bool is_ca = false); - static Certificate generate(const CertificateRequest& request, const Identity& ca); + static Certificate generate(const PrivateKey& key, const std::string& name = "dhtnode", const Identity& ca = {}, bool is_ca = false, int64_t validity = 0); + static Certificate generate(const CertificateRequest& request, const Identity& ca, int64_t validity = 0); gnutls_x509_crt_t getCopy() const { if (not cert) @@ -592,6 +592,12 @@ struct OPENDHT_PUBLIC Certificate { */ std::pair<std::string, Blob> generateOcspRequest(gnutls_x509_crt_t& issuer); + /** + * Change certificate's expiration + */ + void setValidity(const Identity& ca, int64_t validity); + void setValidity(const PrivateKey& key, int64_t validity); + gnutls_x509_crt_t cert {nullptr}; std::shared_ptr<Certificate> issuer {}; std::shared_ptr<OcspResponse> ocspResponse; diff --git a/src/crypto.cpp b/src/crypto.cpp index e5c7f83d..4dad2584 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -1163,14 +1163,14 @@ setRandomSerial(gnutls_x509_crt_t cert) } Certificate -Certificate::generate(const PrivateKey& key, const std::string& name, const Identity& ca, bool is_ca) +Certificate::generate(const PrivateKey& key, const std::string& name, const Identity& ca, bool is_ca, int64_t validity) { gnutls_x509_crt_t cert; if (not key.x509_key or gnutls_x509_crt_init(&cert) != GNUTLS_E_SUCCESS) return {}; Certificate ret {cert}; - setValidityPeriod(cert, 10 * 365 * 24 * 60 * 60); + setValidityPeriod(cert, validity <= 0 ? 10 * 365 * 24 * 60 * 60 : validity); if (int err = gnutls_x509_crt_set_key(cert, key.x509_key)) { throw CryptoException(std::string("Error when setting certificate key ") + gnutls_strerror(err)); } @@ -1216,7 +1216,7 @@ Certificate::generate(const PrivateKey& key, const std::string& name, const Iden } Certificate -Certificate::generate(const CertificateRequest& request, const Identity& ca) +Certificate::generate(const CertificateRequest& request, const Identity& ca, int64_t validity) { gnutls_x509_crt_t cert; if (auto err = gnutls_x509_crt_init(&cert)) @@ -1229,7 +1229,7 @@ Certificate::generate(const CertificateRequest& request, const Identity& ca) throw CryptoException(std::string("Can't set certificate version: ") + gnutls_strerror(err)); } - setValidityPeriod(cert, 10 * 365 * 24 * 60 * 60); + setValidityPeriod(cert, validity <= 0 ? 10 * 365 * 24 * 60 * 60 : validity); setRandomSerial(cert); if (auto err = gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, ca.second->getPreferredDigest(), 0)) { @@ -1240,6 +1240,32 @@ Certificate::generate(const CertificateRequest& request, const Identity& ca) return ret.getPacked(); } +void +Certificate::setValidity(const Identity& ca, int64_t validity) +{ + setValidityPeriod(cert, validity); + setRandomSerial(cert); + if (ca.first && ca.second) { + if (not ca.second->isCA()) { + throw CryptoException("Signing certificate must be CA"); + } + if (int err = gnutls_x509_crt_privkey_sign(cert, ca.second->cert, ca.first->key, ca.second->getPreferredDigest(), 0)) { + throw CryptoException(std::string("Error when signing certificate ") + gnutls_strerror(err)); + } + } +} + +void +Certificate::setValidity(const PrivateKey& key, int64_t validity) +{ + setValidityPeriod(cert, validity); + setRandomSerial(cert); + const auto& pk = key.getPublicKey(); + if (int err = gnutls_x509_crt_privkey_sign(cert, cert, key.key, pk.getPreferredDigest(), 0)) { + throw CryptoException(std::string("Error when signing certificate ") + gnutls_strerror(err)); + } +} + std::vector<std::shared_ptr<RevocationList>> Certificate::getRevocationLists() const { -- GitLab