3

I have three client certificates installed in Windows 7 and need to use a specific one to authenticate a ServerXMLHTTP60 call using VBA.

Calling ServerXMLHTTP60.SetOption with the friendly name of the certificate returns with no error. But the subsequent .send fails with "A certificate is required to complete client authentication".

Code example:

    Public Sub TestCert()
    Dim myHTTP as New ServerXMLHTTP60
    Dim myURL as String

        ' Open the connection to the secure server
         myHTTP.Open "GET", "https://server/finalpath", False

        ' Attempt to set the correct client certificate
        ' I have also tried just the friendly name as well as 
        ' LOCAL_MACHINE\My\cert friendly name'
        myHTTP.SetOption 3, "CURRENT_USER\My\cert friendly name"

        ' Send request fails with "A certificate is required ..."
        myHTTP.Send
    End Sub

The specified certificate is working fine via IE or Firefox with this site. I must be using an incorrect pathname for the certificate. Is there a way to determine the correct client certificate pathname to ensure success?

Bryan P
  • 51
  • 1
  • 5
  • I ran across this same issue and ended up using [WinHTTP](https://msdn.microsoft.com/en-us/library/windows/desktop/aa384106(v=vs.85).aspx) instead with the [SetAutoLogonPolicy](https://msdn.microsoft.com/en-us/library/windows/desktop/aa384050(v=vs.85).aspx) option, which provides the default client certificate in the same way that IE would. WinHTTP is also a good choice because it supports [WPAD](https://en.wikipedia.org/wiki/Web_Proxy_Autodiscovery_Protocol) in the case where the network you are on uses proxies. – Blackhawk Aug 11 '15 at 13:05
  • @Blackhawk, thank you, but now there is a new problem. The WinHTTP.Send works without error now, but it does not appear to be sending a certificate at all. The WinHTTP.ResponseText contains the exact same authentication failed error document returned as if I tried sending the request without any certificate or autologonpolicy at all. – Bryan P Aug 11 '15 at 17:38
  • Can you visit the site with IE? – Blackhawk Aug 11 '15 at 17:39
  • I can. No problems, and the automatic certificate prompting occurs without a hitch. – Bryan P Aug 11 '15 at 17:59
  • Well then I guess it's back to trying to find an appropriate cert for the job. [Here is an example](http://stackoverflow.com/a/1264398/2832561) of setting the client cert with WinHTTP for an HTTPS site. – Blackhawk Aug 11 '15 at 18:11
  • Did you try `request.SetAutoLogonPolicy AutoLogonPolicy_Always` before you did `request.send`? – Blackhawk Aug 11 '15 at 19:15
  • I appreciate the help. Still no success. Have you had any success attaching a certificate using the base WinHTTP or WININET functions? I have not been to successfully use the .InternetSetOption() function where you have to provide a certificate context -- that function always returns an error about not having enough space in the buffer. I realize that using VBA is probably the main issue here, but this is all occurring inside a MS Access back-end functionality. – Bryan P Aug 12 '15 at 11:19
  • Moving problem to --> [link](http://stackoverflow.com/questions/31966601/using-vba-to-attach-a-client-certificate-to-a-wininet-httpsendrequest) – Bryan P Aug 12 '15 at 13:27
  • Did it ultimately work for you? My experience is you need to use the certificate "Subject" or any of the "Subject Alternative Name" values, not the "friendly name" when providing a client certificate, at least with ASP/VBScript using ServerXMLHTTP or WinHTTP. – KBr Jun 12 '17 at 23:33
  • I'm getting Run-time error '-2147012852 (80072f0c) A certificate is required to complete client authentication. Does this mean it does not pass my certificate during handshake? – bherto39 Jul 09 '20 at 07:45

1 Answers1

-1

This drove me mad for a couple of days but... Assuming you install your client to default store under current user and your certificate has subject cn=mycert then this seems to work. Running office16, windows 10, winhttp5.1

Dim apiConnection As New WinHttp.WinHttpRequest

' Set the authentication settings
apiConnection.SetClientCertificate "mycert"

apiConnection.Open "Get", "https://localhost:8443", False
apiConnection.Send
cloudpta
  • 134
  • 1
  • 6