Auto SSL Certificate Registration

Share your advanced PureBasic knowledge/code with the community.
tatanas
Enthusiast
Enthusiast
Posts: 198
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Auto SSL Certificate Registration

Post by tatanas »

Hi !

Here is a small code I wanted to share with you.
This code get the SSL certificate of a server and add it to the certificate store of Windows.

Then you can reload it (get certificate context) and use it with httpsendrequest function (not in the code above).

Code: Select all

; https://www.codeproject.com/Articles/24003/One-Click-SSL-Certificate-Registration-using-WinHT

; SSL Certificate Registration

Prototype.i ProtoWinHttpOpen(pwszUserAgent.i, dwAccessType.i, *pwszProxyName, *pwszProxyBypass, dwFlags.i)
Prototype.i ProtoWinHttpConnect(hSession, pswzServerName.i, nServerPort.i, dwReserved.i)
Prototype.i ProtoWinHttpOpenRequest(hConnect, pwszVerb.p-unicode, pwszObjectName.p-unicode, *pwszVersion, *pwszReferrer, *ppwszAcceptTypes, dwFlags.i)
Prototype.i ProtoWinHttpSetOption(hInternet, dwOption.i, *lpBuffer, dwBufferLength.i)
Prototype.i ProtoWinHttpSendRequest(hRequest, pwszHeaders.i, dwHeadersLength.i, *lpOptional, dwOptionalLength.i, dwTotalLength.i, dwContext.i)
Prototype.i ProtoWinHttpQueryOption(hInternet, dwOption.i, *lpBuffer, dwBufferLength.i)

If OpenLibrary(0, "Winhttp.dll")
	WinHttpOpen_.ProtoWinHttpOpen 					= GetFunction(0, "WinHttpOpen")
	WinHttpConnect_.ProtoWinHttpConnect 			= GetFunction(0, "WinHttpConnect")
	WinHttpOpenRequest_.ProtoWinHttpOpenRequest 	= GetFunction(0, "WinHttpOpenRequest")
	WinHttpSetOption_.ProtoWinHttpSetOption 		= GetFunction(0, "WinHttpSetOption")
	WinHttpSendRequest_.ProtoWinHttpSendRequest 	= GetFunction(0, "WinHttpSendRequest")
	WinHttpQueryOption_.ProtoWinHttpQueryOption 	= GetFunction(0, "WinHttpQueryOption")
Else
	Debug "Dll loading error"
	End
EndIf


#INTERNET_DEFAULT_HTTPS_PORT 			= 443

#WINHTTP_NO_PROXY_NAME 					= 0
#WINHTTP_NO_PROXY_BYPASS 				= 0
#WINHTTP_NO_REFERER 						= 0
#WINHTTP_DEFAULT_ACCEPT_TYPES 		= 0
#WINHTTP_ACCESS_TYPE_DEFAULT_PROXY 	= 0
#WINHTTP_FLAG_SECURE 					= $00800000

#SECURITY_FLAG_IGNORE_UNKNOWN_CA 		 = $00000100
#SECURITY_FLAG_IGNORE_CERT_CN_INVALID 	 = $00001000
#SECURITY_FLAG_IGNORE_CERT_DATE_INVALID = $00002000

#WINHTTP_OPTION_SECURITY_FLAGS 		= 31
#WINHTTP_NO_ADDITIONAL_HEADERS 		= #Null
#WINHTTP_NO_REQUEST_DATA		 		= #Null
#WINHTTP_OPTION_SERVER_CERT_CONTEXT = 78

#CERT_STORE_PROV_SYSTEM					= 10
#CERT_STORE_OPEN_EXISTING_FLAG		= $00004000
#CERT_SYSTEM_STORE_LOCAL_MACHINE_ID = 2
#CERT_SYSTEM_STORE_LOCATION_SHIFT	= 16
#CERT_SYSTEM_STORE_LOCAL_MACHINE		= #CERT_SYSTEM_STORE_LOCAL_MACHINE_ID << #CERT_SYSTEM_STORE_LOCATION_SHIFT
#CERT_STORE_ADD_REPLACE_EXISTING		= 3


; define your access
AgentName$ = "PBrocks" 	; whatever
ServerName$ = "" 	; ip address or domain name of the https server to connect to
; check CertOpenStore_ function to change the location where the certificate will be stored (https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/nf-wincrypt-certopenstore)
; Default : import the certificate in root store of local machine

; open a session handle
hSession = WinHttpOpen_(@AgentName$, #WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, #WINHTTP_NO_PROXY_NAME, #WINHTTP_NO_PROXY_BYPASS, 0)
If Not hSession
	Debug "WinHttpOpen_ error"
	End
EndIf

; connect To a web server
hConnect = WinHttpConnect_(hSession, @ServerName$, #INTERNET_DEFAULT_HTTPS_PORT, 0)
If Not hConnect
	Debug "WinHttpConnect_ error"
	End
EndIf

; open a request handle
hRequest = WinHttpOpenRequest_(hConnect, "GET", "", #Null, #WINHTTP_NO_REFERER, #WINHTTP_DEFAULT_ACCEPT_TYPES, #WINHTTP_FLAG_SECURE)
If Not hRequest
	Debug "WinHttpOpenRequest_ error"
	End
EndIf

; important - set security To ignore 'bad' certs
dwFlags.l = #SECURITY_FLAG_IGNORE_CERT_CN_INVALID | #SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | #SECURITY_FLAG_IGNORE_UNKNOWN_CA
If Not WinHttpSetOption_(hRequest, #WINHTTP_OPTION_SECURITY_FLAGS, @dwFlags, SizeOf(dwFlags))
	Debug "WinHttpSetOption_ error"
	End
EndIf

; send the request
If Not WinHttpSendRequest_(hRequest, #WINHTTP_NO_ADDITIONAL_HEADERS, 0, #WINHTTP_NO_REQUEST_DATA, 0, 0, 0)
	Debug "WinHttpSendRequest_ error : " + GetLastError_()
	End
EndIf

; get a handle on the certificate
pCert.i
dwLen = SizeOf(pCert)
If Not WinHttpQueryOption_(hRequest, #WINHTTP_OPTION_SERVER_CERT_CONTEXT, @pCert, @dwLen)
	Debug "WinHttpQueryOption_ error : " + GetLastError_()
	End
EndIf

; open a certificate store
hCertStore = CertOpenStore_(#CERT_STORE_PROV_SYSTEM, 0, 0, #CERT_STORE_OPEN_EXISTING_FLAG | #CERT_SYSTEM_STORE_LOCAL_MACHINE, @"Root")
If Not hCertStore
	Debug "CertOpenStore_ error"
	End
EndIf

; add the certificate
If Not CertAddCertificateContextToStore_(hCertStore, pCert, #CERT_STORE_ADD_REPLACE_EXISTING, #Null)
	Debug "CertAddCertificateContextToStore_ error"
	End
EndIf

; release the certificate
CertFreeCertificateContext_(pCert)

; close the store
CertCloseStore_(hCertStore, 0)

CloseLibrary(0)
Windows 10 Pro x64
PureBasic 6.04 x64
Cyllceaux
Enthusiast
Enthusiast
Posts: 458
Joined: Mon Jun 23, 2014 1:18 pm
Contact:

Re: Auto SSL Certificate Registration

Post by Cyllceaux »

+1

I used an external lib for that... but this is much better :)
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Auto SSL Certificate Registration

Post by Kwai chang caine »

Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
Post Reply