diff --git a/lib/base/tlsutility.cpp b/lib/base/tlsutility.cpp index 72635f450..bf9954b53 100644 --- a/lib/base/tlsutility.cpp +++ b/lib/base/tlsutility.cpp @@ -4,6 +4,7 @@ #include "base/convert.hpp" #include "base/logger.hpp" #include "base/context.hpp" +#include "base/convert.hpp" #include "base/utility.hpp" #include "base/application.hpp" #include "base/exception.hpp" @@ -806,6 +807,14 @@ bool VerifyCertificate(const std::shared_ptr& caCertificate, const std::sh X509_STORE_CTX_free(csc); X509_STORE_free(store); + if (rc == 0) { + int err = X509_STORE_CTX_get_error(csc); + + BOOST_THROW_EXCEPTION(openssl_error() + << boost::errinfo_api_function("X509_verify_cert") + << errinfo_openssl_error(err)); + } + return rc == 1; } @@ -826,6 +835,53 @@ bool IsCa(const std::shared_ptr& cacert) #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ } +int GetCertificateVersion(const std::shared_ptr& cert) +{ + return X509_get_version(cert.get()) + 1; +} + +String GetSignatureAlgorithm(const std::shared_ptr& cert) +{ + int alg; + int sign_alg; + X509_PUBKEY *key; + X509_ALGOR *algor; + + key = X509_get_X509_PUBKEY(cert.get()); + + X509_PUBKEY_get0_param(nullptr, nullptr, 0, &algor, key); //TODO: Error handling + + alg = OBJ_obj2nid (algor->algorithm); + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + sign_alg = OBJ_obj2nid((cert.get())->sig_alg->algorithm); +#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */ + sign_alg = X509_get_signature_nid(cert.get()); +#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */ + + return Convert::ToString((sign_alg == NID_undef) ? "Unknown" : OBJ_nid2ln(sign_alg)); +} + +Array::Ptr GetSubjectAltNames(const std::shared_ptr& cert) +{ + GENERAL_NAMES* subjectAltNames = (GENERAL_NAMES*)X509_get_ext_d2i(cert.get(), NID_subject_alt_name, nullptr, nullptr); + + Array::Ptr sans = new Array(); + + for (int i = 0; i < sk_GENERAL_NAME_num(subjectAltNames); i++) { + GENERAL_NAME* gen = sk_GENERAL_NAME_value(subjectAltNames, i); + if (gen->type == GEN_URI || gen->type == GEN_DNS || gen->type == GEN_EMAIL) { + ASN1_IA5STRING *asn1_str = gen->d.uniformResourceIdentifier; + String san = Convert::ToString(ASN1_STRING_data(asn1_str)); + sans->Add(san); + } + } + + GENERAL_NAMES_free(subjectAltNames); + + return sans; +} + std::string to_string(const errinfo_openssl_error& e) { std::ostringstream tmp; diff --git a/lib/base/tlsutility.hpp b/lib/base/tlsutility.hpp index 715bfd426..a101f9b79 100644 --- a/lib/base/tlsutility.hpp +++ b/lib/base/tlsutility.hpp @@ -6,12 +6,15 @@ #include "base/i2-base.hpp" #include "base/object.hpp" #include "base/shared.hpp" +#include "base/array.hpp" #include "base/string.hpp" #include #include #include #include #include +#include +#include #include #include #include @@ -48,6 +51,9 @@ String RandomString(int length); bool VerifyCertificate(const std::shared_ptr& caCertificate, const std::shared_ptr& certificate); bool IsCa(const std::shared_ptr& cacert); +int GetCertificateVersion(const std::shared_ptr& cert); +String GetSignatureAlgorithm(const std::shared_ptr& cert); +Array::Ptr GetSubjectAltNames(const std::shared_ptr& cert); class openssl_error : virtual public std::exception, virtual public boost::exception { };