public static function curlContactCert($url, $key, $cert, $keypw = false, $postData = null) { if (is_null($key) || is_null($cert) || $key === "" || $cert === "") { throw new ConfusaGenException("Empty key or certificate received " . "when using curlContactCert(). " . "Aborting curl-transfer to url: {$url}"); } if (is_null($postData) || !is_array($postData) || count($postData) == 0) { return false; } /* Do basic URL filtering */ $curlurl = Input::sanitizeURL($url); if (is_null($curlurl) || $curlurl === "" || filter_var($curlurl, FILTER_VALIDATE_URL) === false) { Logger::log_event(LOG_NOTICE, "invalid URL (" . $curlurl . "), aborting curl-fetch."); return false; } Logger::log_event(LOG_DEBUG, "Contacting {$curlurl} using cert AuthN"); /* key should be encrypted, if not, do not use it (not safe!) */ $start = "-----BEGIN ENCRYPTED PRIVATE KEY-----"; if (substr($key, 0, strlen($start)) !== $start) { Logger::log_event(LOG_NOTICE, "Trying to use curlContactCert with unecrypted private key, aborting."); return false; } $rkey = openssl_pkey_get_private($key, $keypw); if ($rkey === false) { Logger::log_event(LOG_NOTICE, "Could not parse private key for CurlContactCert, aborting"); return false; } if (!openssl_x509_check_private_key($cert, $rkey)) { Logger::log_event(LOG_NOTICE, "Provided key and certificate is not a pair, cannot continue."); /* throw exception? */ return false; } $rcert = new Certificate($cert); if (!$rcert->isValid()) { $logline = "Certificate (" . $rcert->getHash() . ") has expired, cannot use this. Aborting curl."; Logger::log_event(LOG_NOTICE, $logline); return false; } if (!file_exists("/tmp/" . $rcert->getHash() . ".key") || !file_exists("/tmp/" . $rcert->getHash() . ".crt")) { if (file_put_contents("/tmp/" . $rcert->getHash() . ".key", $key) === false) { Logger::log_event(LOG_NOTICE, "Could not write key to file"); } if (file_put_contents("/tmp/" . $rcert->getHash() . ".crt", $cert) === false) { Logger::log_event(LOG_NOTICE, "Could not write cert to file"); } } $options = array(CURLOPT_URL => $curlurl, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_SSLKEY => "/tmp/" . $rcert->getHash() . ".key", CURLOPT_SSLCERT => "/tmp/" . $rcert->getHash() . ".crt", CURLOPT_SSLKEYPASSWD => $keypw, CURLOPT_HEADER => false, CURLOPT_FOLLOWLOCATION => true, CURLOPT_RETURNTRANSFER => 1, CURLOPT_CONNECTTIMEOUT => 15); $channel = curl_init(); curl_setopt_array($channel, $options); $data = curl_exec($channel); $status = curl_errno($channel); curl_close($channel); if ($status !== 0) { throw new ConfusaGenException("Could not connect properly to remote " . "endpoint {$curlurl} using cert-based authN! " . "Maybe the Confusa instance is misconfigured? " . "Please contact an administrator!"); } return $data; }