crypto: unify API across GnuTLS versions

Throw an exception if GnuTLS is too old
instead of not providing the API.

Also consistently throw in case of hash error,
and return 0 for an empty hash, for both
PublicKey and Certificate.
This commit is contained in:
Adrien Beraud committed 2017-04-20 17:07:21 +02:00
1 parent 02147b0b16
commit f41c8fef99
3 files changed
+29 -18

No files matched your search

-4
View File
@@ -83,9 +83,7 @@ struct OPENDHT_PUBLIC PublicKey
PublicKey& operator=(PublicKey&& o) noexcept;
InfoHash getId() const;
#if GNUTLS_VERSION_NUMBER >= 0x030401
PkId getLongId() const;
#endif
bool checkSignature(const Blob& data, const Blob& signature) const;
Blob encrypt(const Blob&) const;
@@ -364,9 +362,7 @@ struct OPENDHT_PUBLIC Certificate {
/** Same as getPublicKey().getId() */
InfoHash getId() const;
#if GNUTLS_VERSION_NUMBER >= 0x030401
PkId getLongId() const;
#endif
/** Read certificate Common Name (CN) */
std::string getName() const;
+1 -2
View File
@@ -51,11 +51,10 @@ public:
InfoHash getId() const {
return key_ ? key_->getPublicKey().getId() : InfoHash();
}
#if GNUTLS_VERSION_NUMBER >= 0x030401
PkId getLongId() const {
return key_ ? key_->getPublicKey().getLongId() : PkId();
}
#endif
ValueType secureType(ValueType&& type);
ValueType secureType(const ValueType& type) {
+28 -12
View File
@@ -525,24 +525,34 @@ PublicKey::encrypt(const Blob& data) const
InfoHash
PublicKey::getId() const
{
if (not pk)
return {};
InfoHash id;
size_t sz = id.size();
if (gnutls_pubkey_get_key_id(pk, 0, id.data(), &sz) != GNUTLS_E_SUCCESS || sz != id.size())
return {};
if (auto err = gnutls_pubkey_get_key_id(pk, 0, id.data(), &sz))
throw CryptoException(std::string("Can't get public key ID: ") + gnutls_strerror(err));
if (sz != id.size())
throw CryptoException("Can't get public key ID: wrong output length.");
return id;
}
#if GNUTLS_VERSION_NUMBER >= 0x030401
PkId
PublicKey::getLongId() const
{
if (not pk)
return {};
#if GNUTLS_VERSION_NUMBER < 0x030401
throw CryptoException("Can't get 256 bits public key ID: GnuTLS 3.4.1 or higher required.");
#else
PkId h;
size_t sz = h.size();
if (gnutls_pubkey_get_key_id(pk, GNUTLS_KEYID_USE_SHA256, h.data(), &sz) != GNUTLS_E_SUCCESS || sz != h.size())
return {};
if (auto err = gnutls_pubkey_get_key_id(pk, GNUTLS_KEYID_USE_SHA256, h.data(), &sz))
throw CryptoException(std::string("Can't get 256 bits public key ID: ") + gnutls_strerror(err));
if (sz != h.size())
throw CryptoException("Can't get 256 bits public key ID: wrong output length.");
return h;
}
#endif
}
Certificate::Certificate(const Blob& certData) : cert(nullptr)
{
@@ -643,24 +653,30 @@ Certificate::getId() const
return {};
InfoHash id;
size_t sz = id.size();
if (gnutls_x509_crt_get_key_id(cert, 0, id.data(), &sz) != GNUTLS_E_SUCCESS || sz != id.size())
throw CryptoException("Can't get certificate public key ID.");
if (auto err = gnutls_x509_crt_get_key_id(cert, 0, id.data(), &sz))
throw CryptoException(std::string("Can't get certificate public key ID: ") + gnutls_strerror(err));
if (sz != id.size())
throw CryptoException("Can't get certificate public key ID: wrong output length.");
return id;
}
#if GNUTLS_VERSION_NUMBER >= 0x030401
PkId
Certificate::getLongId() const
{
if (not cert)
return {};
#if GNUTLS_VERSION_NUMBER < 0x030401
throw CryptoException("Can't get certificate 256 bits public key ID: GnuTLS 3.4.1 or higher required.");
#else
PkId id;
size_t sz = id.size();
if (gnutls_x509_crt_get_key_id(cert, GNUTLS_KEYID_USE_SHA256, id.data(), &sz) != GNUTLS_E_SUCCESS || sz != id.size())
throw CryptoException("Can't get certificate public key ID.");
if (auto err = gnutls_x509_crt_get_key_id(cert, GNUTLS_KEYID_USE_SHA256, id.data(), &sz))
throw CryptoException(std::string("Can't get certificate 256 bits public key ID: ") + gnutls_strerror(err));
if (sz != id.size())
throw CryptoException("Can't get certificate 256 bits public key ID: wrong output length.");
return id;
}
#endif
}
static std::string
getDN(gnutls_x509_crt_t cert, const char* oid, bool issuer = false)