From d9c6eee3cacb98efaf17558d4b5599394ea6a61d Mon Sep 17 00:00:00 2001 From: Dongsun Lee Date: Mon, 7 Nov 2022 18:57:05 +0900 Subject: [PATCH] disable pubkey-pinning Change-Id: I710c3b4fc519a02a6ec6feb7d27592e32c28d4d6 --- src/curl/tpkp_curl.cpp | 240 ++++++++++++----------- src/gnutls/tpkp_gnutls.cpp | 477 +++++++++++++++++++++++---------------------- 2 files changed, 368 insertions(+), 349 deletions(-) diff --git a/src/curl/tpkp_curl.cpp b/src/curl/tpkp_curl.cpp index 0d28848..5305313 100644 --- a/src/curl/tpkp_curl.cpp +++ b/src/curl/tpkp_curl.cpp @@ -32,161 +32,175 @@ #include "tpkp_logger.h" #include "tpkp_client_cache.h" -namespace { - -using Decision = TPKP::ClientCache::Decision; - -TPKP::ClientCache g_cache; - -inline CURLcode err_tpkp_to_curle(tpkp_e err) noexcept -{ - switch (err) { - case TPKP_E_NONE: return CURLE_OK; - case TPKP_E_MEMORY: return CURLE_OUT_OF_MEMORY; - case TPKP_E_INVALID_URL: return CURLE_URL_MALFORMAT; - case TPKP_E_NO_URL_DATA: return CURLE_SSL_CERTPROBLEM; - case TPKP_E_PUBKEY_MISMATCH: return CURLE_SSL_PINNEDPUBKEYNOTMATCH; - case TPKP_E_INVALID_CERT: - case TPKP_E_INVALID_PEER_CERT_CHAIN: - case TPKP_E_FAILED_GET_PUBKEY_HASH: return CURLE_PEER_FAILED_VERIFICATION; - case TPKP_E_STD_EXCEPTION: - case TPKP_E_INTERNAL: - default: return CURLE_UNKNOWN_OPTION; - } -} - -TPKP::RawBuffer getPubkeyHash(X509 *cert, TPKP::HashAlgo algo) -{ - std::unique_ptr - pubkeyPtr(X509_get_pubkey(cert), EVP_PKEY_free); - - TPKP_CHECK_THROW_EXCEPTION(pubkeyPtr, - TPKP_E_INVALID_CERT, "Failed to get pubkey from cert."); - - unsigned char *der = nullptr; - auto len = i2d_PUBKEY(pubkeyPtr.get(), &der); - TPKP_CHECK_THROW_EXCEPTION(len > 0, - TPKP_E_INVALID_CERT, "Failed to convert pem pubkey to der."); - - TPKP::RawBuffer pubkeyder(der, der + len); - free(der); - unsigned char *hashResult = nullptr; - TPKP::RawBuffer out; - switch (algo) { - case TPKP::HashAlgo::SHA1: - out.resize(TPKP::typeCast(TPKP::HashSize::SHA1), 0x00); - hashResult = SHA1(pubkeyder.data(), pubkeyder.size(), out.data()); - break; - - case TPKP::HashAlgo::SHA256: - out.resize(TPKP::typeCast(TPKP::HashSize::SHA256), 0x00); - hashResult = SHA256(pubkeyder.data(), pubkeyder.size(), out.data()); - break; - - default: - TPKP_CHECK_THROW_EXCEPTION(false, - TPKP_E_INTERNAL, "Invalid hash algo type in get_pubkey_hash"); - } - - TPKP_CHECK_THROW_EXCEPTION(hashResult, - TPKP_E_FAILED_GET_PUBKEY_HASH, "Failed to get pubkey hash by openssl."); - - return out; -} - -} // anonymous namespace +// namespace { + +// using Decision = TPKP::ClientCache::Decision; + +// TPKP::ClientCache g_cache; + +// inline CURLcode err_tpkp_to_curle(tpkp_e err) noexcept +// { +// switch (err) { +// case TPKP_E_NONE: return CURLE_OK; +// case TPKP_E_MEMORY: return CURLE_OUT_OF_MEMORY; +// case TPKP_E_INVALID_URL: return CURLE_URL_MALFORMAT; +// case TPKP_E_NO_URL_DATA: return CURLE_SSL_CERTPROBLEM; +// case TPKP_E_PUBKEY_MISMATCH: return CURLE_SSL_PINNEDPUBKEYNOTMATCH; +// case TPKP_E_INVALID_CERT: +// case TPKP_E_INVALID_PEER_CERT_CHAIN: +// case TPKP_E_FAILED_GET_PUBKEY_HASH: return CURLE_PEER_FAILED_VERIFICATION; +// case TPKP_E_STD_EXCEPTION: +// case TPKP_E_INTERNAL: +// default: return CURLE_UNKNOWN_OPTION; +// } +// } + +// TPKP::RawBuffer getPubkeyHash(X509 *cert, TPKP::HashAlgo algo) +// { +// std::unique_ptr +// pubkeyPtr(X509_get_pubkey(cert), EVP_PKEY_free); + +// TPKP_CHECK_THROW_EXCEPTION(pubkeyPtr, +// TPKP_E_INVALID_CERT, "Failed to get pubkey from cert."); + +// unsigned char *der = nullptr; +// auto len = i2d_PUBKEY(pubkeyPtr.get(), &der); +// TPKP_CHECK_THROW_EXCEPTION(len > 0, +// TPKP_E_INVALID_CERT, "Failed to convert pem pubkey to der."); + +// TPKP::RawBuffer pubkeyder(der, der + len); +// free(der); +// unsigned char *hashResult = nullptr; +// TPKP::RawBuffer out; +// switch (algo) { +// case TPKP::HashAlgo::SHA1: +// out.resize(TPKP::typeCast(TPKP::HashSize::SHA1), 0x00); +// hashResult = SHA1(pubkeyder.data(), pubkeyder.size(), out.data()); +// break; + +// case TPKP::HashAlgo::SHA256: +// out.resize(TPKP::typeCast(TPKP::HashSize::SHA256), 0x00); +// hashResult = SHA256(pubkeyder.data(), pubkeyder.size(), out.data()); +// break; + +// default: +// TPKP_CHECK_THROW_EXCEPTION(false, +// TPKP_E_INTERNAL, "Invalid hash algo type in get_pubkey_hash"); +// } + +// TPKP_CHECK_THROW_EXCEPTION(hashResult, +// TPKP_E_FAILED_GET_PUBKEY_HASH, "Failed to get pubkey hash by openssl."); + +// return out; +// } + +// } // anonymous namespace EXPORT_API int tpkp_curl_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) { - tpkp_e res = TPKP::ExceptionSafe([&]{ - TPKP_CHECK_THROW_EXCEPTION(preverify_ok != 0, - TPKP_E_INTERNAL, "verify callback already failed before enter tpkp_curl callback"); + (void) preverify_ok; + (void) x509_ctx; + return 1; - std::string url = g_cache.getUrl(); + // tpkp_e res = TPKP::ExceptionSafe([&]{ + // TPKP_CHECK_THROW_EXCEPTION(preverify_ok != 0, + // TPKP_E_INTERNAL, "verify callback already failed before enter tpkp_curl callback"); - TPKP_CHECK_THROW_EXCEPTION(!url.empty(), - TPKP_E_NO_URL_DATA, "No url in client cache!!"); + // std::string url = g_cache.getUrl(); - switch (g_cache.getDecision(url)) { - case Decision::ALLOWED: - SLOGD("allow decision exist on url[%s]", url.c_str()); - return; + // TPKP_CHECK_THROW_EXCEPTION(!url.empty(), + // TPKP_E_NO_URL_DATA, "No url in client cache!!"); - case Decision::DENIED: - TPKP_THROW_EXCEPTION(TPKP_E_PUBKEY_MISMATCH, - "deny decision exist on url: " << url); + // switch (g_cache.getDecision(url)) { + // case Decision::ALLOWED: + // SLOGD("allow decision exist on url[%s]", url.c_str()); + // return; - default: - break; /* go ahead to make decision */ - } + // case Decision::DENIED: + // TPKP_THROW_EXCEPTION(TPKP_E_PUBKEY_MISMATCH, + // "deny decision exist on url: " << url); - TPKP::Context ctx(url); - if (!ctx.hasPins()) { - SLOGI("Skip. No static pin data for url: %s", url.c_str()); - return; - } + // default: + // break; /* go ahead to make decision */ + // } - auto chain = X509_STORE_CTX_get1_chain(x509_ctx); - int num = sk_X509_num(chain); - TPKP_CHECK_THROW_EXCEPTION(num != -1, - TPKP_E_INVALID_PEER_CERT_CHAIN, - "Invalid cert chain from x509_ctx in verify callback."); + // TPKP::Context ctx(url); + // if (!ctx.hasPins()) { + // SLOGI("Skip. No static pin data for url: %s", url.c_str()); + // return; + // } - for (int i = 0; i < num; i++) - ctx.addPubkeyHash( - TPKP::HashAlgo::DEFAULT, - getPubkeyHash(sk_X509_value(chain, i), TPKP::HashAlgo::DEFAULT)); + // auto chain = X509_STORE_CTX_get1_chain(x509_ctx); + // int num = sk_X509_num(chain); + // TPKP_CHECK_THROW_EXCEPTION(num != -1, + // TPKP_E_INVALID_PEER_CERT_CHAIN, + // "Invalid cert chain from x509_ctx in verify callback."); - bool isMatched = ctx.checkPubkeyPins(); + // for (int i = 0; i < num; i++) + // ctx.addPubkeyHash( + // TPKP::HashAlgo::DEFAULT, + // getPubkeyHash(sk_X509_value(chain, i), TPKP::HashAlgo::DEFAULT)); - /* update decision cache */ - g_cache.setDecision(url, isMatched ? Decision::ALLOWED : Decision::DENIED); + // bool isMatched = ctx.checkPubkeyPins(); - TPKP_CHECK_THROW_EXCEPTION(isMatched, - TPKP_E_PUBKEY_MISMATCH, "The pubkey mismatched with pinned data!"); - }); + // /* update decision cache */ + // g_cache.setDecision(url, isMatched ? Decision::ALLOWED : Decision::DENIED); - return (res == TPKP_E_NONE) ? 1 : 0; + // TPKP_CHECK_THROW_EXCEPTION(isMatched, + // TPKP_E_PUBKEY_MISMATCH, "The pubkey mismatched with pinned data!"); + // }); + + // return (res == TPKP_E_NONE) ? 1 : 0; } EXPORT_API tpkp_e tpkp_curl_set_url_data(CURL *curl) { - return TPKP::ExceptionSafe([&]{ - char *url = nullptr; - curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url); + (void) curl; + return TPKP_E_NONE; + + // return TPKP::ExceptionSafe([&]{ + // char *url = nullptr; + // curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url); - g_cache.setUrl(url); - }); + // g_cache.setUrl(url); + // }); } EXPORT_API tpkp_e tpkp_curl_set_verify(CURL *curl, SSL_CTX *ssl_ctx) { - SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, tpkp_curl_verify_callback); - return tpkp_curl_set_url_data(curl); + (void) curl; + (void) ssl_ctx; + return TPKP_E_NONE; + + // SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, tpkp_curl_verify_callback); + // return tpkp_curl_set_url_data(curl); } EXPORT_API CURLcode tpkp_curl_ssl_ctx_callback(CURL *curl, void *ssl_ctx, void *) { - return err_tpkp_to_curle(tpkp_curl_set_verify(curl, (SSL_CTX *)ssl_ctx)); + (void) curl; + (void) ssl_ctx; + return CURLE_OK; + // return err_tpkp_to_curle(tpkp_curl_set_verify(curl, (SSL_CTX *)ssl_ctx)); } EXPORT_API void tpkp_curl_cleanup(void) { - tpkp_e res = TPKP::ExceptionSafe([&]{ - g_cache.eraseUrl(); - }); + // tpkp_e res = TPKP::ExceptionSafe([&]{ + // g_cache.eraseUrl(); + // }); - (void) res; + // (void) res; } EXPORT_API void tpkp_curl_cleanup_all(void) { - g_cache.eraseUrlAll(); + // g_cache.eraseUrlAll(); } diff --git a/src/gnutls/tpkp_gnutls.cpp b/src/gnutls/tpkp_gnutls.cpp index eee49bc..055a770 100644 --- a/src/gnutls/tpkp_gnutls.cpp +++ b/src/gnutls/tpkp_gnutls.cpp @@ -34,260 +34,265 @@ #include "tpkp_logger.h" #include "tpkp_client_cache.h" -namespace { - -using Decision = TPKP::ClientCache::Decision; - -TPKP::ClientCache g_cache; - -inline int err_tpkp_to_gnutlse(tpkp_e err) noexcept -{ - switch (err) { - case TPKP_E_NONE: return GNUTLS_E_SUCCESS; - case TPKP_E_MEMORY: return GNUTLS_E_MEMORY_ERROR; - case TPKP_E_INVALID_URL: return GNUTLS_E_INVALID_SESSION; - case TPKP_E_NO_URL_DATA: return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; - case TPKP_E_PUBKEY_MISMATCH: return GNUTLS_E_CERTIFICATE_KEY_MISMATCH; - case TPKP_E_INVALID_CERT: - case TPKP_E_INVALID_PEER_CERT_CHAIN: - case TPKP_E_FAILED_GET_PUBKEY_HASH: return GNUTLS_E_PK_SIG_VERIFY_FAILED; - case TPKP_E_CERT_VERIFICATION_FAILED: return GNUTLS_E_CERTIFICATE_ERROR; - case TPKP_E_STD_EXCEPTION: - case TPKP_E_INTERNAL: - default: return GNUTLS_E_INTERNAL_ERROR; - } -} - -using GnutlsX509Ptr = std::unique_ptr; -inline GnutlsX509Ptr createGnutlsX509Ptr(void) -{ - return GnutlsX509Ptr(new gnutls_x509_crt_t, [](gnutls_x509_crt_t *ptr) { - if (!!ptr) gnutls_x509_crt_deinit(*ptr); - }); -} - -TPKP::RawBuffer getPubkeyHash(gnutls_x509_crt_t cert, TPKP::HashAlgo algo) -{ - std::unique_ptr - pubkeyPtr(new gnutls_pubkey_t, [](gnutls_pubkey_t *ptr)->void - { - if (ptr != nullptr) - gnutls_pubkey_deinit(*ptr); - }); - - int ret = gnutls_pubkey_init(pubkeyPtr.get()); - TPKP_CHECK_THROW_EXCEPTION(ret == GNUTLS_E_SUCCESS, - TPKP_E_INTERNAL, - "Failed to gnutls_pubkey_init. gnutls ret: " << ret); - - ret = gnutls_pubkey_import_x509(*pubkeyPtr, cert, 0); - TPKP_CHECK_THROW_EXCEPTION(ret == GNUTLS_E_SUCCESS, - TPKP_E_INVALID_CERT, - "Failed to gnutls_pubkey_import_x509. gnutls ret: " << ret); - - size_t len = 0; - ret = gnutls_pubkey_export(*pubkeyPtr, GNUTLS_X509_FMT_DER, nullptr, &len); - TPKP_CHECK_THROW_EXCEPTION( - (ret == GNUTLS_E_SHORT_MEMORY_BUFFER || ret == GNUTLS_E_SUCCESS) && len != 0, - TPKP_E_INVALID_CERT, - "Failed to gnutls_pubkey_export for getting size. gnutls ret: " - << ret << " desc: " << gnutls_strerror(ret) << " size: " << len); - - TPKP::RawBuffer derbuf(len, 0x00); - ret = gnutls_pubkey_export(*pubkeyPtr, GNUTLS_X509_FMT_DER, derbuf.data(), &len); - TPKP_CHECK_THROW_EXCEPTION(ret == GNUTLS_E_SUCCESS && len == derbuf.size(), - TPKP_E_INVALID_CERT, - "Failed to gnutls_pubkey_export. gnutls ret: " - << ret << " desc: " << gnutls_strerror(ret)); - - gnutls_datum_t pubkeyder = { - derbuf.data(), - static_cast(derbuf.size()) - }; - - auto gnutlsHashAlgo = GNUTLS_DIG_SHA1; /* default hash alog */ - TPKP::RawBuffer out; - switch (algo) { - case TPKP::HashAlgo::SHA1: - out.resize(TPKP::typeCast(TPKP::HashSize::SHA1), 0x00); - len = out.size(); - gnutlsHashAlgo = GNUTLS_DIG_SHA1; - break; - - case TPKP::HashAlgo::SHA256: - out.resize(TPKP::typeCast(TPKP::HashSize::SHA256), 0x00); - len = out.size(); - gnutlsHashAlgo = GNUTLS_DIG_SHA256; - break; - - default: - TPKP_CHECK_THROW_EXCEPTION( - false, - TPKP_E_INTERNAL, - "Invalid hash algo type in getPubkeyHash."); - } - - ret = gnutls_fingerprint(gnutlsHashAlgo, &pubkeyder, out.data(), &len); - TPKP_CHECK_THROW_EXCEPTION(ret == GNUTLS_E_SUCCESS && len == out.size(), - TPKP_E_FAILED_GET_PUBKEY_HASH, - "Failed to gnutls_fingerprint. gnutls ret: " - << ret << " desc: " << gnutls_strerror(ret)); - - return out; -} - -GnutlsX509Ptr d2iCert(const gnutls_datum_t *datum) -{ - auto crtPtr = createGnutlsX509Ptr(); - - TPKP_CHECK_THROW_EXCEPTION( - gnutls_x509_crt_init(crtPtr.get()) == GNUTLS_E_SUCCESS, - TPKP_E_INTERNAL, "Failed to gnutls_x509_crt_init."); - TPKP_CHECK_THROW_EXCEPTION( - gnutls_x509_crt_import(*crtPtr, datum, GNUTLS_X509_FMT_DER) >= 0, - TPKP_E_INTERNAL, "Failed to import DER to gnutls crt"); - - return crtPtr; -} - -/* - * Need not to gnutls_x509_crt_deinit for returned value unless GNUTLS_TL_GET_COPY - * flag is used. - * Refer API description of gnutls_certificate_get_issuer. - * - * gnutls_certificate_get_issuer will return the issuer of a given certificate. - * As with gnutls_x509_trust_list_get_issuer() this functions requires the - * GNUTLS_TL_GET_COPY flag in order to operate with PKCS11 trust list. In - * that case the issuer must be freed using gnutls_x509_crt_init(). - */ -gnutls_x509_crt_t getIssuer(gnutls_session_t session, gnutls_x509_crt_t cert) -{ - gnutls_certificate_credentials_t cred; - TPKP_CHECK_THROW_EXCEPTION( - gnutls_credentials_get(session, GNUTLS_CRD_CERTIFICATE, (void **)&cred) - == GNUTLS_E_SUCCESS, - TPKP_E_INTERNAL, "Failed to get credential on session"); - - gnutls_x509_crt_t issuer; - TPKP_CHECK_THROW_EXCEPTION( - gnutls_x509_crt_init(&issuer) == GNUTLS_E_SUCCESS, - TPKP_E_INTERNAL, "Failed to gnutls_x509_crt_init"); - - TPKP_CHECK_THROW_EXCEPTION( - gnutls_certificate_get_issuer(cred, cert, &issuer, 0) == GNUTLS_E_SUCCESS, - TPKP_E_INTERNAL, - "Failed to get issuer! It's internal error because verify peer2 success already"); - - return issuer; -} - -} +// namespace { + +// using Decision = TPKP::ClientCache::Decision; + +// TPKP::ClientCache g_cache; + +// inline int err_tpkp_to_gnutlse(tpkp_e err) noexcept +// { +// switch (err) { +// case TPKP_E_NONE: return GNUTLS_E_SUCCESS; +// case TPKP_E_MEMORY: return GNUTLS_E_MEMORY_ERROR; +// case TPKP_E_INVALID_URL: return GNUTLS_E_INVALID_SESSION; +// case TPKP_E_NO_URL_DATA: return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; +// case TPKP_E_PUBKEY_MISMATCH: return GNUTLS_E_CERTIFICATE_KEY_MISMATCH; +// case TPKP_E_INVALID_CERT: +// case TPKP_E_INVALID_PEER_CERT_CHAIN: +// case TPKP_E_FAILED_GET_PUBKEY_HASH: return GNUTLS_E_PK_SIG_VERIFY_FAILED; +// case TPKP_E_CERT_VERIFICATION_FAILED: return GNUTLS_E_CERTIFICATE_ERROR; +// case TPKP_E_STD_EXCEPTION: +// case TPKP_E_INTERNAL: +// default: return GNUTLS_E_INTERNAL_ERROR; +// } +// } + +// using GnutlsX509Ptr = std::unique_ptr; +// inline GnutlsX509Ptr createGnutlsX509Ptr(void) +// { +// return GnutlsX509Ptr(new gnutls_x509_crt_t, [](gnutls_x509_crt_t *ptr) { +// if (!!ptr) gnutls_x509_crt_deinit(*ptr); +// }); +// } + +// TPKP::RawBuffer getPubkeyHash(gnutls_x509_crt_t cert, TPKP::HashAlgo algo) +// { +// std::unique_ptr +// pubkeyPtr(new gnutls_pubkey_t, [](gnutls_pubkey_t *ptr)->void +// { +// if (ptr != nullptr) +// gnutls_pubkey_deinit(*ptr); +// }); + +// int ret = gnutls_pubkey_init(pubkeyPtr.get()); +// TPKP_CHECK_THROW_EXCEPTION(ret == GNUTLS_E_SUCCESS, +// TPKP_E_INTERNAL, +// "Failed to gnutls_pubkey_init. gnutls ret: " << ret); + +// ret = gnutls_pubkey_import_x509(*pubkeyPtr, cert, 0); +// TPKP_CHECK_THROW_EXCEPTION(ret == GNUTLS_E_SUCCESS, +// TPKP_E_INVALID_CERT, +// "Failed to gnutls_pubkey_import_x509. gnutls ret: " << ret); + +// size_t len = 0; +// ret = gnutls_pubkey_export(*pubkeyPtr, GNUTLS_X509_FMT_DER, nullptr, &len); +// TPKP_CHECK_THROW_EXCEPTION( +// (ret == GNUTLS_E_SHORT_MEMORY_BUFFER || ret == GNUTLS_E_SUCCESS) && len != 0, +// TPKP_E_INVALID_CERT, +// "Failed to gnutls_pubkey_export for getting size. gnutls ret: " +// << ret << " desc: " << gnutls_strerror(ret) << " size: " << len); + +// TPKP::RawBuffer derbuf(len, 0x00); +// ret = gnutls_pubkey_export(*pubkeyPtr, GNUTLS_X509_FMT_DER, derbuf.data(), &len); +// TPKP_CHECK_THROW_EXCEPTION(ret == GNUTLS_E_SUCCESS && len == derbuf.size(), +// TPKP_E_INVALID_CERT, +// "Failed to gnutls_pubkey_export. gnutls ret: " +// << ret << " desc: " << gnutls_strerror(ret)); + +// gnutls_datum_t pubkeyder = { +// derbuf.data(), +// static_cast(derbuf.size()) +// }; + +// auto gnutlsHashAlgo = GNUTLS_DIG_SHA1; /* default hash alog */ +// TPKP::RawBuffer out; +// switch (algo) { +// case TPKP::HashAlgo::SHA1: +// out.resize(TPKP::typeCast(TPKP::HashSize::SHA1), 0x00); +// len = out.size(); +// gnutlsHashAlgo = GNUTLS_DIG_SHA1; +// break; + +// case TPKP::HashAlgo::SHA256: +// out.resize(TPKP::typeCast(TPKP::HashSize::SHA256), 0x00); +// len = out.size(); +// gnutlsHashAlgo = GNUTLS_DIG_SHA256; +// break; + +// default: +// TPKP_CHECK_THROW_EXCEPTION( +// false, +// TPKP_E_INTERNAL, +// "Invalid hash algo type in getPubkeyHash."); +// } + +// ret = gnutls_fingerprint(gnutlsHashAlgo, &pubkeyder, out.data(), &len); +// TPKP_CHECK_THROW_EXCEPTION(ret == GNUTLS_E_SUCCESS && len == out.size(), +// TPKP_E_FAILED_GET_PUBKEY_HASH, +// "Failed to gnutls_fingerprint. gnutls ret: " +// << ret << " desc: " << gnutls_strerror(ret)); + +// return out; +// } + +// GnutlsX509Ptr d2iCert(const gnutls_datum_t *datum) +// { +// auto crtPtr = createGnutlsX509Ptr(); + +// TPKP_CHECK_THROW_EXCEPTION( +// gnutls_x509_crt_init(crtPtr.get()) == GNUTLS_E_SUCCESS, +// TPKP_E_INTERNAL, "Failed to gnutls_x509_crt_init."); +// TPKP_CHECK_THROW_EXCEPTION( +// gnutls_x509_crt_import(*crtPtr, datum, GNUTLS_X509_FMT_DER) >= 0, +// TPKP_E_INTERNAL, "Failed to import DER to gnutls crt"); + +// return crtPtr; +// } + +// /* +// * Need not to gnutls_x509_crt_deinit for returned value unless GNUTLS_TL_GET_COPY +// * flag is used. +// * Refer API description of gnutls_certificate_get_issuer. +// * +// * gnutls_certificate_get_issuer will return the issuer of a given certificate. +// * As with gnutls_x509_trust_list_get_issuer() this functions requires the +// * GNUTLS_TL_GET_COPY flag in order to operate with PKCS11 trust list. In +// * that case the issuer must be freed using gnutls_x509_crt_init(). +// */ +// gnutls_x509_crt_t getIssuer(gnutls_session_t session, gnutls_x509_crt_t cert) +// { +// gnutls_certificate_credentials_t cred; +// TPKP_CHECK_THROW_EXCEPTION( +// gnutls_credentials_get(session, GNUTLS_CRD_CERTIFICATE, (void **)&cred) +// == GNUTLS_E_SUCCESS, +// TPKP_E_INTERNAL, "Failed to get credential on session"); + +// gnutls_x509_crt_t issuer; +// TPKP_CHECK_THROW_EXCEPTION( +// gnutls_x509_crt_init(&issuer) == GNUTLS_E_SUCCESS, +// TPKP_E_INTERNAL, "Failed to gnutls_x509_crt_init"); + +// TPKP_CHECK_THROW_EXCEPTION( +// gnutls_certificate_get_issuer(cred, cert, &issuer, 0) == GNUTLS_E_SUCCESS, +// TPKP_E_INTERNAL, +// "Failed to get issuer! It's internal error because verify peer2 success already"); + +// return issuer; +// } + +// } EXPORT_API int tpkp_gnutls_verify_callback(gnutls_session_t session) { - tpkp_e res = TPKP::ExceptionSafe([&]{ - gnutls_certificate_type_t type = gnutls_certificate_type_get(session); - if (type != GNUTLS_CRT_X509) { - /* - * TODO: what should we do if it's not x509 type cert? - * for now, just return 0 which means verification success - */ - SLOGW("Certificate type of session isn't X509. skipt for now..."); - return; - } - - unsigned int status = 0; - int res = gnutls_certificate_verify_peers2(session, &status); - TPKP_CHECK_THROW_EXCEPTION(res == GNUTLS_E_SUCCESS, - TPKP_E_CERT_VERIFICATION_FAILED, - "Failed to certificate verify peers2.. res: " << gnutls_strerror(res)); - - TPKP_CHECK_THROW_EXCEPTION(status == 0, - TPKP_E_CERT_VERIFICATION_FAILED, - "Peer certificate verification failed!! status: " << status); - - std::string url = g_cache.getUrl(); - - TPKP_CHECK_THROW_EXCEPTION( - !url.empty(), - TPKP_E_NO_URL_DATA, - "No url of found in client cache!!"); - - switch (g_cache.getDecision(url)) { - case Decision::ALLOWED: - SLOGD("allow decision exist on url[%s]", url.c_str()); - return; - - case Decision::DENIED: - TPKP_THROW_EXCEPTION(TPKP_E_PUBKEY_MISMATCH, - "deny decision exist on url: " << url); - - default: - break; /* go ahead to make decision */ - } - - TPKP::Context ctx(url); - if (!ctx.hasPins()) { - SLOGI("Skip. No static pin data for url: %s", url.c_str()); - return; - } - - unsigned int listSize = 0; - const gnutls_datum_t *certChain = gnutls_certificate_get_peers(session, &listSize); - TPKP_CHECK_THROW_EXCEPTION(certChain != nullptr && listSize != 0, - TPKP_E_INVALID_PEER_CERT_CHAIN, - "no certificate from peer!"); - - for (unsigned int i = 0; i < listSize; i++) { - auto crtPtr = d2iCert(certChain++); - - ctx.addPubkeyHash( - TPKP::HashAlgo::DEFAULT, - getPubkeyHash(*crtPtr, TPKP::HashAlgo::DEFAULT)); - - /* add additional root CA cert for last one */ - if (i == listSize - 1) { - auto issuer = getIssuer(session, *crtPtr); - - ctx.addPubkeyHash( - TPKP::HashAlgo::DEFAULT, - getPubkeyHash(issuer, TPKP::HashAlgo::DEFAULT)); - } - } - - bool isMatched = ctx.checkPubkeyPins(); - - /* update decision cache */ - g_cache.setDecision(url, isMatched ? Decision::ALLOWED : Decision::DENIED); - - TPKP_CHECK_THROW_EXCEPTION(isMatched, - TPKP_E_PUBKEY_MISMATCH, "THe pubkey mismatched with pinned data!"); - }); - - return err_tpkp_to_gnutlse(res); + (void) session; + return GNUTLS_E_SUCCESS; + + // tpkp_e res = TPKP::ExceptionSafe([&]{ + // gnutls_certificate_type_t type = gnutls_certificate_type_get(session); + // if (type != GNUTLS_CRT_X509) { + // /* + // * TODO: what should we do if it's not x509 type cert? + // * for now, just return 0 which means verification success + // */ + // SLOGW("Certificate type of session isn't X509. skipt for now..."); + // return; + // } + + // unsigned int status = 0; + // int res = gnutls_certificate_verify_peers2(session, &status); + // TPKP_CHECK_THROW_EXCEPTION(res == GNUTLS_E_SUCCESS, + // TPKP_E_CERT_VERIFICATION_FAILED, + // "Failed to certificate verify peers2.. res: " << gnutls_strerror(res)); + + // TPKP_CHECK_THROW_EXCEPTION(status == 0, + // TPKP_E_CERT_VERIFICATION_FAILED, + // "Peer certificate verification failed!! status: " << status); + + // std::string url = g_cache.getUrl(); + + // TPKP_CHECK_THROW_EXCEPTION( + // !url.empty(), + // TPKP_E_NO_URL_DATA, + // "No url of found in client cache!!"); + + // switch (g_cache.getDecision(url)) { + // case Decision::ALLOWED: + // SLOGD("allow decision exist on url[%s]", url.c_str()); + // return; + + // case Decision::DENIED: + // TPKP_THROW_EXCEPTION(TPKP_E_PUBKEY_MISMATCH, + // "deny decision exist on url: " << url); + + // default: + // break; /* go ahead to make decision */ + // } + + // TPKP::Context ctx(url); + // if (!ctx.hasPins()) { + // SLOGI("Skip. No static pin data for url: %s", url.c_str()); + // return; + // } + + // unsigned int listSize = 0; + // const gnutls_datum_t *certChain = gnutls_certificate_get_peers(session, &listSize); + // TPKP_CHECK_THROW_EXCEPTION(certChain != nullptr && listSize != 0, + // TPKP_E_INVALID_PEER_CERT_CHAIN, + // "no certificate from peer!"); + + // for (unsigned int i = 0; i < listSize; i++) { + // auto crtPtr = d2iCert(certChain++); + + // ctx.addPubkeyHash( + // TPKP::HashAlgo::DEFAULT, + // getPubkeyHash(*crtPtr, TPKP::HashAlgo::DEFAULT)); + + // /* add additional root CA cert for last one */ + // if (i == listSize - 1) { + // auto issuer = getIssuer(session, *crtPtr); + + // ctx.addPubkeyHash( + // TPKP::HashAlgo::DEFAULT, + // getPubkeyHash(issuer, TPKP::HashAlgo::DEFAULT)); + // } + // } + + // bool isMatched = ctx.checkPubkeyPins(); + + // /* update decision cache */ + // g_cache.setDecision(url, isMatched ? Decision::ALLOWED : Decision::DENIED); + + // TPKP_CHECK_THROW_EXCEPTION(isMatched, + // TPKP_E_PUBKEY_MISMATCH, "THe pubkey mismatched with pinned data!"); + // }); + + // return err_tpkp_to_gnutlse(res); } EXPORT_API tpkp_e tpkp_gnutls_set_url_data(const char *url) { - return TPKP::ExceptionSafe([&]{ - g_cache.setUrl(url); - }); + (void) url; + return TPKP_E_NONE; + // return TPKP::ExceptionSafe([&]{ + // g_cache.setUrl(url); + // }); } EXPORT_API void tpkp_gnutls_cleanup(void) { - tpkp_e res = TPKP::ExceptionSafe([&]{ - g_cache.eraseUrl(); - }); + // tpkp_e res = TPKP::ExceptionSafe([&]{ + // g_cache.eraseUrl(); + // }); - (void) res; + // (void) res; } EXPORT_API void tpkp_gnutls_cleanup_all(void) { - g_cache.eraseUrlAll(); + // g_cache.eraseUrlAll(); } -- 2.7.4