Sign in to follow this  
Followers 0
Galapo

libcurl.au3 "certificate verify failed"

3 posts in this topic

With the _DllCallBack function comes the handy libcurl.au3 to handle dll calls to the cURL libcurl.dll.

Running the function on sites with an invalid certificate produces an error: "error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed".

Using curl.exe from the commandline and specifying to turn off certificate validation allows for successful downloading, eg 'curl.exe -k https://o.aolcdn.com -o output.txt'.

The documentation says that the same is possible also with libcurl.dll, ie with a call like curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, FALSE). My question is, how might we go about this with with the AutoIt function and is it possible?

#include "DllCallBack.au3"

; From libcurl headers
Global Const $CURLOPT_URL = 0x2712
Global Const $CURLOPT_WRITEDATA = 0x2711
Global Const $CURLOPT_WRITEFUNCTION = 0x4E2B
Global Const $CURLOPT_PROGRESSFUNCTION = 0x4E58
Global Const $CURLOPT_NOPROGRESS = 0x2B
Global Const $CURLOPT_ERRORBUFFER = 0x271A
Global Const $CURLOPT_TRANSFERTEXT = 0x35
Global Const $CURL_ERROR_SIZE = 0x100

; Load and initialize curl
$hDll_LibCurl = DllOpen("libcurl.dll")
$hCurlHandle = DllCall($hDll_LibCurl, "ptr:cdecl", "curl_easy_init")
$hCurlHandle = $hCurlHandle[0]

; Register Callback function's
; typedef int (*curl_progress_callback)(void *clientp,double dltotal,double dlnow,double ultotal,double ulnow);
$pProgress = _DllCallBack ("_Progress", "ptr;double;double;double;double",$_DllCallBack_Cdecl)
; size_t function( void *ptr, size_t size, size_t nmemb, void *stream);
$pWriteFunc = _DllCallBack ("_WriteFunc", "ptr;uint;uint;ptr",$_DllCallBack_Cdecl)

; Create a buffer for error messages and Url
$CURL_ERROR = DllStructCreate("char[" & $CURL_ERROR_SIZE + 1 & "]")
$URL = DllStructCreate("char[256]")
DllStructSetData($URL, 1, "https://o.aolcdn.com")

; Setup Task
;DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_TRANSFERTEXT, "int", 1)
DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_URL, "ptr", DllStructGetPtr($URL))
DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_NOPROGRESS, "int", 0)
DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_PROGRESSFUNCTION, "ptr", $pProgress)
DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_WRITEFUNCTION, "ptr", $pWriteFunc)
DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_ERRORBUFFER, "ptr", DllStructGetPtr($CURL_ERROR))

; Perform task
Global $g_nTimer = TimerInit(), $g_hFileOut = FileOpen("libcurl_dummy",2+16)
ProgressOn("Downloading", "")
$nPerform = DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_perform", "ptr", $hCurlHandle)
$nPerform = $nPerform[0]
If $nPerform <> 0 Then
    ; libcurl reported an error
    ConsoleWrite("! " & DllStructGetData($CURL_ERROR, 1) & @CRLF)
EndIf

; The progress function which gets called
Func _Progress($clientp, $dltotal, $dlnow, $ultotal, $ulnow)
    If TimerDiff($g_nTimer) > 250 Then
        ProgressSet($dlnow / $dltotal * 100, StringFormat("%.2fKb (%.1f%%)", $dlnow / 1024, $dlnow / $dltotal * 100))
        $g_nTimer = TimerInit()
    EndIf
    Return 0 ; Continue
EndFunc   ;==>_Progress

; This Callback function recieves the data downloaded
Func _WriteFunc ($ptr,$nSize,$nMemb,$pStream)
   Local $vData = DllStructCreate ("byte[" & $nSize*$nMemb & "]",$ptr)
   FileWrite($g_hFileOut,DllStructGetData($vData,1))
   Return $nSize*$nMemb
EndFunc

; Cleanup
ProgressOff()
FileClose($g_hFileOut)
DllCall($hDll_LibCurl, "none:cdecl", "curl_easy_cleanup", "ptr", $hCurlHandle)
$URL = 0
$CURL_ERROR = 0
_DllCallBack_Free ($pProgress)
_DllCallBack_Free ($pWriteFunc)

Thanks,

Galapo.

Share this post


Link to post
Share on other sites



All you should need to know is the value for CURLOPT_SSL_VERIFYPEER. I did a quick search and I think 64 is the proper value. So something like this should work.

Global Const $CURLOPT_SSL_VERIFYPEER = 0x40

DllCall($hDll_LibCurl, "uint:cdecl", "curl_easy_setopt", "ptr", $hCurlHandle, "uint", $CURLOPT_SSL_VERIFYPEER, "int", 0)

Share this post


Link to post
Share on other sites

Hi zorphnog,

Thanks indeed for that! I just tested and the function is now working for the server I was having troubles with.

So the idea is to convert the value to hex for use within the AutoIt function. Finally I get the idea of how these dll calls work.

Thanks again,

Galapo.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0