Home All Groups Group Topic Archive Search About

How to send certificate for client authentication?

Author
9 Aug 2005 12:07 AM
David Carr
Hi all,

I have a VC++ v7 Windows C++ application (i.e. not C#) which is accessing a
webservice via https.  The directory is configured through IIS to require a
client certificate.  This web reference was added and the SOAP code
auto-generated.

While I have had no problem creating a C# application that adds an
X509Certificate to the service's X509CertificateCollection, I cannot figure
out the functional equivalent to achieve this in a C++ application.

Understandably, the C++ application fails in call SendRequest(), as IIS
refuses this request.  This occurs for all of the web service's methods.

Ideally I am looking for an example of how to attach a certificate, prior to
calling the request.  All other ideas (e.g. is this simply the wrong
approach?) would also be most welcome.

Best regards,
David

Author
9 Aug 2005 4:30 AM
Joe Kaplan (MVP - ADSI)
Are you using VC++ writing .NET code or unmanaged code with a different
stack like WinInet or WinHTTP?  It isn't clear from your posting.

Both WinInet and WinHTTP have different methods of specifying client
certificates (via InternetSetOption and WinHTTPSetOption respectively).

If this is managed code, the syntax should be about the same.

Joe K.

Show quoteHide quote
"David Carr" <David_Carr@NoSpamCanada.Com> wrote in message
news:eAtMHbHnFHA.2484@TK2MSFTNGP15.phx.gbl...
> Hi all,
>
> I have a VC++ v7 Windows C++ application (i.e. not C#) which is accessing
> a
> webservice via https.  The directory is configured through IIS to require
> a
> client certificate.  This web reference was added and the SOAP code
> auto-generated.
>
> While I have had no problem creating a C# application that adds an
> X509Certificate to the service's X509CertificateCollection, I cannot
> figure
> out the functional equivalent to achieve this in a C++ application.
>
> Understandably, the C++ application fails in call SendRequest(), as IIS
> refuses this request.  This occurs for all of the web service's methods.
>
> Ideally I am looking for an example of how to attach a certificate, prior
> to
> calling the request.  All other ideas (e.g. is this simply the wrong
> approach?) would also be most welcome.
>
> Best regards,
> David
>
>
Author
10 Aug 2005 1:55 AM
David Carr
Hi Joe - thx for the reply.

The client is unmanaged C++.  I added the web reference and the IDE added
all the code (e.g. in the Solution Explorer, MyService.h is a new file in
the group 'Generated Files').  In the TClient and CSoapRootHandler derived
class (e.g. CService1T), the call to the given method fails in the call to
SendRequest().  The code segment follows.

As a novice to .NET, it is not clear to me what the C++ functional
equivalent to the simplicity of C#, where I simply call Add() to the
X509CertificateCollection.  So my question is what the equivalent is, and
where to make this change (e.g. in the auto-generated code?).

I hope this helps clarify my problem.

template <typename TClient>
inline HRESULT CService1T<TClient>::HelloWorld(BSTR* HelloWorldResult)
{
    if ( HelloWorldResult == NULL )
        return E_POINTER;

// ME: CODE REMOVED...

    __atlsoap_hr = GenerateResponse(GetWriteStream());
    if (FAILED(__atlsoap_hr))
    {
        SetClientError(SOAPCLIENT_GENERATE_ERROR);
        goto __skip_cleanup;
    }
// ME: ALWAYS FAILS HERE
    __atlsoap_hr = SendRequest(_T("SOAPAction:
\"http://tempuri.org/HelloWorld\"\r\n"));
    if (FAILED(__atlsoap_hr))
    {
        goto __skip_cleanup;
    }

// ME: CODE REMOVED...

*HelloWorldResult = __params.HelloWorldResult;
goto __skip_cleanup;
__cleanup:
Cleanup();
__skip_cleanup:
ResetClientState(true);
memset(&__params, 0x00, sizeof(__params));
return __atlsoap_hr;
}



Show quoteHide quote
"Joe Kaplan (MVP - ADSI)" <joseph.e.kap***@removethis.accenture.com> wrote
in message news:uPQZXsJnFHA.3120@TK2MSFTNGP09.phx.gbl...
> Are you using VC++ writing .NET code or unmanaged code with a different
> stack like WinInet or WinHTTP?  It isn't clear from your posting.
>
> Both WinInet and WinHTTP have different methods of specifying client
> certificates (via InternetSetOption and WinHTTPSetOption respectively).
>
> If this is managed code, the syntax should be about the same.
>
> Joe K.
>
> "David Carr" <David_Carr@NoSpamCanada.Com> wrote in message
> news:eAtMHbHnFHA.2484@TK2MSFTNGP15.phx.gbl...
> > Hi all,
> >
> > I have a VC++ v7 Windows C++ application (i.e. not C#) which is
accessing
> > a
> > webservice via https.  The directory is configured through IIS to
require
> > a
> > client certificate.  This web reference was added and the SOAP code
> > auto-generated.
> >
> > While I have had no problem creating a C# application that adds an
> > X509Certificate to the service's X509CertificateCollection, I cannot
> > figure
> > out the functional equivalent to achieve this in a C++ application.
> >
> > Understandably, the C++ application fails in call SendRequest(), as IIS
> > refuses this request.  This occurs for all of the web service's methods.
> >
> > Ideally I am looking for an example of how to attach a certificate,
prior
> > to
> > calling the request.  All other ideas (e.g. is this simply the wrong
> > approach?) would also be most welcome.
> >
> > Best regards,
> > David
> >
> >
>
>
Author
10 Aug 2005 2:18 AM
Joe Kaplan (MVP - ADSI)
I'm not an ATL guy at all (you are poisting in a .NET group after all), but
having looked at this last night, I got the impression that the ATL SOAP
stuff uses WinInet under the hood and that some of those classes provide a
member that will give you the WinInet handle.  Once you have that, you can
call the appropriate WinInet InternetSetOption function to specify the
client certificate you want (which takes a crypto API cert_context or
something).

Hopefully that gives you enough to go on to figure it out.  Otherwise,
someone else will have to help (perhaps an unmanaged C++ group?).

Best of luck,

Joe K.

Show quoteHide quote
"David Carr" <David_Carr@NoSpamCanada.Com> wrote in message
news:ulA777UnFHA.2920@TK2MSFTNGP14.phx.gbl...
> Hi Joe - thx for the reply.
>
> The client is unmanaged C++.  I added the web reference and the IDE added
> all the code (e.g. in the Solution Explorer, MyService.h is a new file in
> the group 'Generated Files').  In the TClient and CSoapRootHandler derived
> class (e.g. CService1T), the call to the given method fails in the call to
> SendRequest().  The code segment follows.
>
> As a novice to .NET, it is not clear to me what the C++ functional
> equivalent to the simplicity of C#, where I simply call Add() to the
> X509CertificateCollection.  So my question is what the equivalent is, and
> where to make this change (e.g. in the auto-generated code?).
>
> I hope this helps clarify my problem.
>
> template <typename TClient>
> inline HRESULT CService1T<TClient>::HelloWorld(BSTR* HelloWorldResult)
> {
>    if ( HelloWorldResult == NULL )
>        return E_POINTER;
>
> // ME: CODE REMOVED...
>
>    __atlsoap_hr = GenerateResponse(GetWriteStream());
>    if (FAILED(__atlsoap_hr))
>    {
>        SetClientError(SOAPCLIENT_GENERATE_ERROR);
>        goto __skip_cleanup;
>    }
> // ME: ALWAYS FAILS HERE
>    __atlsoap_hr = SendRequest(_T("SOAPAction:
> \"http://tempuri.org/HelloWorld\"\r\n"));
>    if (FAILED(__atlsoap_hr))
>    {
>        goto __skip_cleanup;
>    }
>
> // ME: CODE REMOVED...
>
> *HelloWorldResult = __params.HelloWorldResult;
> goto __skip_cleanup;
> __cleanup:
> Cleanup();
> __skip_cleanup:
> ResetClientState(true);
> memset(&__params, 0x00, sizeof(__params));
> return __atlsoap_hr;
> }
>
>
>
> "Joe Kaplan (MVP - ADSI)" <joseph.e.kap***@removethis.accenture.com> wrote
> in message news:uPQZXsJnFHA.3120@TK2MSFTNGP09.phx.gbl...
>> Are you using VC++ writing .NET code or unmanaged code with a different
>> stack like WinInet or WinHTTP?  It isn't clear from your posting.
>>
>> Both WinInet and WinHTTP have different methods of specifying client
>> certificates (via InternetSetOption and WinHTTPSetOption respectively).
>>
>> If this is managed code, the syntax should be about the same.
>>
>> Joe K.
>>
>> "David Carr" <David_Carr@NoSpamCanada.Com> wrote in message
>> news:eAtMHbHnFHA.2484@TK2MSFTNGP15.phx.gbl...
>> > Hi all,
>> >
>> > I have a VC++ v7 Windows C++ application (i.e. not C#) which is
> accessing
>> > a
>> > webservice via https.  The directory is configured through IIS to
> require
>> > a
>> > client certificate.  This web reference was added and the SOAP code
>> > auto-generated.
>> >
>> > While I have had no problem creating a C# application that adds an
>> > X509Certificate to the service's X509CertificateCollection, I cannot
>> > figure
>> > out the functional equivalent to achieve this in a C++ application.
>> >
>> > Understandably, the C++ application fails in call SendRequest(), as IIS
>> > refuses this request.  This occurs for all of the web service's
>> > methods.
>> >
>> > Ideally I am looking for an example of how to attach a certificate,
> prior
>> > to
>> > calling the request.  All other ideas (e.g. is this simply the wrong
>> > approach?) would also be most welcome.
>> >
>> > Best regards,
>> > David
>> >
>> >
>>
>>
>
>
Author
12 Aug 2005 3:21 AM
David Carr
Joe - Yes, thanks, this did provide enough of a lead to get me further.
Just some info below so that this posting has utility for others in the
future.

When the web service was added, the SOAP proxy class CService1T was
generated by sproxy.exe.  A code snippet follows.

template <typename TClient = CSoapSocketClientT<> >
class CService1T : public TClient, public CSoapRootHandler
{
    protected:
....
}

Previously I was using this code in my VC++ dialog app simply like:
    CService1T oServ;
however this would not give me any of the functionality found in WinINet.
To have access, this was simply a case of constructing the service object
as:
    CService1T<CSoapWininetClient> oServ;

Once I had done this, I was then able to access InternetErrorDlg() in order
to display a list of certificates to select from, and InternetQueryOption()
to obtain the IIS server certificate.

Hope this helps,
David


Show quoteHide quote
"Joe Kaplan (MVP - ADSI)" <joseph.e.kap***@removethis.accenture.com> wrote
in message news:ew9raHVnFHA.3960@TK2MSFTNGP12.phx.gbl...
> I'm not an ATL guy at all (you are poisting in a .NET group after all),
but
> having looked at this last night, I got the impression that the ATL SOAP
> stuff uses WinInet under the hood and that some of those classes provide a
> member that will give you the WinInet handle.  Once you have that, you can
> call the appropriate WinInet InternetSetOption function to specify the
> client certificate you want (which takes a crypto API cert_context or
> something).
>
> Hopefully that gives you enough to go on to figure it out.  Otherwise,
> someone else will have to help (perhaps an unmanaged C++ group?).
>
> Best of luck,
>
> Joe K.
>
> "David Carr" <David_Carr@NoSpamCanada.Com> wrote in message
> news:ulA777UnFHA.2920@TK2MSFTNGP14.phx.gbl...
> > Hi Joe - thx for the reply.
> >
> > The client is unmanaged C++.  I added the web reference and the IDE
added
> > all the code (e.g. in the Solution Explorer, MyService.h is a new file
in
> > the group 'Generated Files').  In the TClient and CSoapRootHandler
derived
> > class (e.g. CService1T), the call to the given method fails in the call
to
> > SendRequest().  The code segment follows.
> >
> > As a novice to .NET, it is not clear to me what the C++ functional
> > equivalent to the simplicity of C#, where I simply call Add() to the
> > X509CertificateCollection.  So my question is what the equivalent is,
and
> > where to make this change (e.g. in the auto-generated code?).
> >
> > I hope this helps clarify my problem.
> >
> > template <typename TClient>
> > inline HRESULT CService1T<TClient>::HelloWorld(BSTR* HelloWorldResult)
> > {
> >    if ( HelloWorldResult == NULL )
> >        return E_POINTER;
> >
> > // ME: CODE REMOVED...
> >
> >    __atlsoap_hr = GenerateResponse(GetWriteStream());
> >    if (FAILED(__atlsoap_hr))
> >    {
> >        SetClientError(SOAPCLIENT_GENERATE_ERROR);
> >        goto __skip_cleanup;
> >    }
> > // ME: ALWAYS FAILS HERE
> >    __atlsoap_hr = SendRequest(_T("SOAPAction:
> > \"http://tempuri.org/HelloWorld\"\r\n"));
> >    if (FAILED(__atlsoap_hr))
> >    {
> >        goto __skip_cleanup;
> >    }
> >
> > // ME: CODE REMOVED...
> >
> > *HelloWorldResult = __params.HelloWorldResult;
> > goto __skip_cleanup;
> > __cleanup:
> > Cleanup();
> > __skip_cleanup:
> > ResetClientState(true);
> > memset(&__params, 0x00, sizeof(__params));
> > return __atlsoap_hr;
> > }
> >
> >
> >
> > "Joe Kaplan (MVP - ADSI)" <joseph.e.kap***@removethis.accenture.com>
wrote
> > in message news:uPQZXsJnFHA.3120@TK2MSFTNGP09.phx.gbl...
> >> Are you using VC++ writing .NET code or unmanaged code with a different
> >> stack like WinInet or WinHTTP?  It isn't clear from your posting.
> >>
> >> Both WinInet and WinHTTP have different methods of specifying client
> >> certificates (via InternetSetOption and WinHTTPSetOption respectively).
> >>
> >> If this is managed code, the syntax should be about the same.
> >>
> >> Joe K.
> >>
> >> "David Carr" <David_Carr@NoSpamCanada.Com> wrote in message
> >> news:eAtMHbHnFHA.2484@TK2MSFTNGP15.phx.gbl...
> >> > Hi all,
> >> >
> >> > I have a VC++ v7 Windows C++ application (i.e. not C#) which is
> > accessing
> >> > a
> >> > webservice via https.  The directory is configured through IIS to
> > require
> >> > a
> >> > client certificate.  This web reference was added and the SOAP code
> >> > auto-generated.
> >> >
> >> > While I have had no problem creating a C# application that adds an
> >> > X509Certificate to the service's X509CertificateCollection, I cannot
> >> > figure
> >> > out the functional equivalent to achieve this in a C++ application.
> >> >
> >> > Understandably, the C++ application fails in call SendRequest(), as
IIS
> >> > refuses this request.  This occurs for all of the web service's
> >> > methods.
> >> >
> >> > Ideally I am looking for an example of how to attach a certificate,
> > prior
> >> > to
> >> > calling the request.  All other ideas (e.g. is this simply the wrong
> >> > approach?) would also be most welcome.
> >> >
> >> > Best regards,
> >> > David
> >> >
> >> >
> >>
> >>
> >
> >
>
>