|
|
|
@ -61,21 +61,31 @@ bool CCurlHttpClient::authenticate(const std::string &user, const std::string &p
|
|
|
|
|
|
|
|
|
|
const char *CAFilename = "ssl_ca_cert.pem"; // this is the certificate "Thawte Server CA"
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
|
|
|
|
|
{
|
|
|
|
|
// look for certificate in search paths
|
|
|
|
|
string path = CPath::lookup(CAFilename);
|
|
|
|
|
nldebug("Cert path '%s'", path.c_str());
|
|
|
|
|
|
|
|
|
|
if (path.empty())
|
|
|
|
|
{
|
|
|
|
|
nlwarning("Unable to find %s", CAFilename);
|
|
|
|
|
return CURLE_SSL_CACERT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CIFile file;
|
|
|
|
|
|
|
|
|
|
if (!file.open(CAFilename))
|
|
|
|
|
// open certificate
|
|
|
|
|
if (!file.open(path))
|
|
|
|
|
{
|
|
|
|
|
nlwarning("Unable to open %s", CAFilename);
|
|
|
|
|
nlwarning("Unable to open %s", path.c_str());
|
|
|
|
|
return CURLE_SSL_CACERT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CURLcode res = CURLE_OK;
|
|
|
|
|
|
|
|
|
|
// load certificate content into memory
|
|
|
|
|
std::vector<uint8> buffer(file.getFileSize());
|
|
|
|
|
file.serialBuffer(&buffer[0], file.getFileSize());
|
|
|
|
|
|
|
|
|
@ -84,25 +94,33 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
|
|
|
|
|
|
|
|
|
|
if (bio)
|
|
|
|
|
{
|
|
|
|
|
// get a pointer to the X509 certificate store (which may be empty!)
|
|
|
|
|
X509_STORE *store = SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
|
|
|
|
|
|
|
|
|
|
// use it to read the PEM formatted certificate from memory into an X509
|
|
|
|
|
// structure that SSL can use
|
|
|
|
|
X509 *cert = NULL;
|
|
|
|
|
PEM_read_bio_X509(bio, &cert, 0, NULL);
|
|
|
|
|
STACK_OF(X509_INFO) *info = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL);
|
|
|
|
|
|
|
|
|
|
if (cert)
|
|
|
|
|
if (info)
|
|
|
|
|
{
|
|
|
|
|
// get a pointer to the X509 certificate store (which may be empty!)
|
|
|
|
|
X509_STORE *store = SSL_CTX_get_cert_store((SSL_CTX *)sslctx);
|
|
|
|
|
|
|
|
|
|
// add our certificate to this store
|
|
|
|
|
if (X509_STORE_add_cert(store, cert) == 0)
|
|
|
|
|
// iterate over all entries from the PEM file, add them to the x509_store one by one
|
|
|
|
|
for (sint i = 0; i < sk_X509_INFO_num(info); ++i)
|
|
|
|
|
{
|
|
|
|
|
nlwarning("Error adding certificate");
|
|
|
|
|
res = CURLE_SSL_CACERT;
|
|
|
|
|
X509_INFO *itmp = sk_X509_INFO_value(info, i);
|
|
|
|
|
|
|
|
|
|
if (itmp->x509)
|
|
|
|
|
{
|
|
|
|
|
// add our certificate to this store
|
|
|
|
|
if (X509_STORE_add_cert(store, itmp->x509) == 0)
|
|
|
|
|
{
|
|
|
|
|
nlwarning("Error adding certificate");
|
|
|
|
|
res = CURLE_SSL_CACERT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// decrease reference counts
|
|
|
|
|
X509_free(cert);
|
|
|
|
|
// cleanup
|
|
|
|
|
sk_X509_INFO_pop_free(info, X509_INFO_free);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -113,9 +131,14 @@ static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
|
|
|
|
|
// decrease reference counts
|
|
|
|
|
BIO_free(bio);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
nlwarning("Unable to allocate BIO buffer for certificates");
|
|
|
|
|
res = CURLE_SSL_CACERT;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// all set to go
|
|
|
|
|
return CURLE_OK ;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
@ -125,7 +148,10 @@ bool CCurlHttpClient::verifyServer(bool verify)
|
|
|
|
|
curl_easy_setopt(_Curl, CURLOPT_SSL_VERIFYPEER, verify ? 1 : 0);
|
|
|
|
|
curl_easy_setopt(_Curl, CURLOPT_SSLCERTTYPE, "PEM");
|
|
|
|
|
// would allow to provide the CA in memory instead of using CURLOPT_CAINFO, but needs to include and link OpenSSL
|
|
|
|
|
curl_easy_setopt(_Curl, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);
|
|
|
|
|
if (curl_easy_setopt(_Curl, CURLOPT_SSL_CTX_FUNCTION, *sslctx_function) == CURLE_NOT_BUILT_IN)
|
|
|
|
|
{
|
|
|
|
|
nlwarning("Unable to support CURLOPT_SSL_CTX_FUNCTION, curl not compiled with OpenSSL ?");
|
|
|
|
|
}
|
|
|
|
|
// don't use that anymore, because CA can't be loaded from BNP and doesn't support UTF-8 under Windows
|
|
|
|
|
// curl_easy_setopt(_Curl, CURLOPT_CAINFO, path.c_str());
|
|
|
|
|
curl_easy_setopt(_Curl, CURLOPT_CAPATH, NULL);
|
|
|
|
@ -181,7 +207,7 @@ bool CCurlHttpClient::sendRequest(const std::string& methodWB, const std::string
|
|
|
|
|
curl_easy_getinfo(_Curl, CURLINFO_RESPONSE_CODE, &r);
|
|
|
|
|
if (verbose)
|
|
|
|
|
{
|
|
|
|
|
nldebug("%u", r);
|
|
|
|
|
nldebug("%u", (uint)r);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|