Discussion:
Encrypted RPC using Schannel's SPPI for SSL and AuthInfo binding
(too old to reply)
Durand Miller
2004-12-07 05:37:02 UTC
Permalink
Hi,


I'm developing on Windows 2000 Server (SP4) with the Microsoft Platform SDK
(2003)
and Visual C++ 6. I currently have an RPC (tcp) connection running between
two machines to do remote data retrieval and this connection now needs to be
encrypted.

I'm hoping to get an SSL tunnel between the two using the RPC calls
RpcSetBindingAuthInfo and RpcServerRegisterAuthInfo while specifying
RPC_C_AUTHN_GSS_SCHANNEL and setting up my SCHANNEL_CRED structure...

I'm having little luck and there is hardly any documentation about this
process that I can find. My steps have been the following:

Server side:
1) I've made a self-signed certificate using makecert.exe and I've loaded it
into the LocalMachine\Root certificate store.
2) In the RPC server setup, I'm opening up this store and locating the
certificate.
3) I'm setting up an SCHANNEL_CRED structure to point to this single
certificate.
4) I'm also setting up the structure to point to the LocalMachine\Root store
as the trusted certificates.
5) I'm then calling RpcServerRegisterAuthInfo with RPC_C_AUTHN_GSS_SCHANNEL
and passing this SCHANNEL_CRED as my data.
6) I'm then continuing on as normal....

Do I need a principal name for the Register call? If my certificate is
called "bob", I've tried "msstd:bob", "bob" and NULL?
Do I need to initialize the SCHANNEL_CRED structure in any way? And if so,
how?

Client side:
1) I've imported the same key that the server generated into the same
store - LocalMachine\Root
2) In the RPC server setup, I'm opening up this store and locating the
certificate.
3) I'm setting up an SCHANNEL_CRED structure to point to this single
certificate.
4) I'm specifying that SSL3/2/1, etc be used in the structure. (trying them
all)
5) I'm fully resolving my binding information
6) I'm then calling RpcSetBindingAuthInfo with RPC_C_AUTHN_GSS_SCHANNEL and
passing this SCHANNEL_CRED as my data.
7) I'm then continuing on as normal....and attempting to connect.

None of these calls return an error code. Everything returns 0 on both sides
of the connection.

However, when I run the actual RPC client, I get an error output of 5
(ACCESS DENIED) as soon as it attempts to connect.

Does this mean the handshake is failing and my credentials are incorrect?


Regards,

Durand.
Greg Kapoustin [MSFT]
2004-12-08 17:25:23 UTC
Permalink
Post by Durand Miller
None of these calls return an error code. Everything returns 0 on both sides
of the connection.
However, when I run the actual RPC client, I get an error output of 5
Are you saying that in some configuration the calls succeed, but in another
they fail?

The rough process to initializing RPC client and server for secure RPC over
SChannel is:

On the client:

- Create a binding handle in the usual manner.
- Call CertOpenStore(), CertFindCertificateInStore() to load PCCERT_CONTEXT
you will use to authenticate the client.
- Initialize the SCHANNEL_CRED you will use for the client.
- Call RpcBindingSetAuthInfoEx() for your binding handle passing
RPC_C_AUTHN_GSS_SCHANNEL, and the SCHANNEL_CRED you created as the
AuthIdentity parameter.
- Make the call.
- Don't forget to cleanup by calling CertFreeCertificateContext() and
CertCloseStore().

On the server:

- Begin to initialize the server in the usual manner, but do not listen.
- Call CertOpenStore(), CertFindCertificateInStore() to load PCCERT_CONTEXT
you will use to authenticate the server.
- Initialize the SCHANNEL_CRED you will use for the server.
- Call RpcServerRegisterAuthInfo() passing RPC_C_AUTHN_GSS_SCHANNEL, and the
SCHANNEL_CRED you created as the Arg parameter.
- You may need to cleanup by calling CertFreeCertificateContext() and
CertCloseStore() if you unload your service from a running process.

If you are getting ACCESS_DENIED and can repro on Windows XP or later, you
can obtain RPC Extended Error Information as described in the MSDN to see
where the error is coming from.

Greg
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Post by Durand Miller
Hi,
I'm developing on Windows 2000 Server (SP4) with the Microsoft Platform
SDK (2003)
and Visual C++ 6. I currently have an RPC (tcp) connection running between
two machines to do remote data retrieval and this connection now needs to be
encrypted.
I'm hoping to get an SSL tunnel between the two using the RPC calls
RpcSetBindingAuthInfo and RpcServerRegisterAuthInfo while specifying
RPC_C_AUTHN_GSS_SCHANNEL and setting up my SCHANNEL_CRED structure...
I'm having little luck and there is hardly any documentation about this
1) I've made a self-signed certificate using makecert.exe and I've loaded
it into the LocalMachine\Root certificate store.
2) In the RPC server setup, I'm opening up this store and locating the
certificate.
3) I'm setting up an SCHANNEL_CRED structure to point to this single
certificate.
4) I'm also setting up the structure to point to the LocalMachine\Root
store as the trusted certificates.
5) I'm then calling RpcServerRegisterAuthInfo with
RPC_C_AUTHN_GSS_SCHANNEL and passing this SCHANNEL_CRED as my data.
6) I'm then continuing on as normal....
Do I need a principal name for the Register call? If my certificate is
called "bob", I've tried "msstd:bob", "bob" and NULL?
Do I need to initialize the SCHANNEL_CRED structure in any way? And if so,
how?
1) I've imported the same key that the server generated into the same
store - LocalMachine\Root
2) In the RPC server setup, I'm opening up this store and locating the
certificate.
3) I'm setting up an SCHANNEL_CRED structure to point to this single
certificate.
4) I'm specifying that SSL3/2/1, etc be used in the structure. (trying
them all)
5) I'm fully resolving my binding information
6) I'm then calling RpcSetBindingAuthInfo with RPC_C_AUTHN_GSS_SCHANNEL
and passing this SCHANNEL_CRED as my data.
7) I'm then continuing on as normal....and attempting to connect.
None of these calls return an error code. Everything returns 0 on both sides
of the connection.
However, when I run the actual RPC client, I get an error output of 5
(ACCESS DENIED) as soon as it attempts to connect.
Does this mean the handshake is failing and my credentials are incorrect?
Regards,
Durand.
Durand Miller
2004-12-08 20:48:00 UTC
Permalink
Post by Greg Kapoustin [MSFT]
Are you saying that in some configuration the calls succeed, but in another
they fail?
Sorry, I mean that the calls during the RPC initialization all return 0
(OK). RpcBindingSetAuthInfoEx returns 0, etc. This happens on both the
server and client side.

It's only after the RPC initialization is complete, the server is listening
and the client attempts to run the remote procedure that an error is printed
to the console with an error code of -5 (access denied). Note that this
error message is printed to the console/cmd line. No error message gets
returned to my app .. just printed out.

I've already ensured that the permissions of private key directory (All
Users\Application Data\Microsoft\Crypto\RSA\MachineKeys) are correct. They
were incorrect and Schannel was reporting errors ("unable to access private
key") to the eventvwr on the server side. This situation also generates a
cmd line error message of -5. Once I corrected the permissions, schannel no
longer complained but my -5 errors messages remained.

I believe it now means that the SSL handshake is failing. I'm using the
same self-signed key (public & private set) on both sides which I created
using makecert and I have installed it into the "Local Machine\Root". I
understand that there used to be a bug in schannel (2000SP2 and less?) which
only allowed keys in the CA certificate store. My machine was fully patched
with all fixes. I did move the certificate between Root, CA and My in order
to test any potential problems still there.

No luck.

Can you elaborate on how to initialize the SCHANNEL_CRED you will use for
the server and the client?

I'll get another basic example up and running to test on an XP machine.
When I solve this, I'd like to put up sample code on my website. I've found
very little documentation and no examples on how to do this.



Durand Miller
Post by Greg Kapoustin [MSFT]
Post by Durand Miller
None of these calls return an error code. Everything returns 0 on both sides
of the connection.
However, when I run the actual RPC client, I get an error output of 5
Are you saying that in some configuration the calls succeed, but in
another they fail?
The rough process to initializing RPC client and server for secure RPC
- Create a binding handle in the usual manner.
- Call CertOpenStore(), CertFindCertificateInStore() to load
PCCERT_CONTEXT
you will use to authenticate the client.
- Initialize the SCHANNEL_CRED you will use for the client.
- Call RpcBindingSetAuthInfoEx() for your binding handle passing
RPC_C_AUTHN_GSS_SCHANNEL, and the SCHANNEL_CRED you created as the
AuthIdentity parameter.
- Make the call.
- Don't forget to cleanup by calling CertFreeCertificateContext() and
CertCloseStore().
- Begin to initialize the server in the usual manner, but do not listen.
- Call CertOpenStore(), CertFindCertificateInStore() to load
PCCERT_CONTEXT
you will use to authenticate the server.
- Initialize the SCHANNEL_CRED you will use for the server.
- Call RpcServerRegisterAuthInfo() passing RPC_C_AUTHN_GSS_SCHANNEL, and the
SCHANNEL_CRED you created as the Arg parameter.
- You may need to cleanup by calling CertFreeCertificateContext() and
CertCloseStore() if you unload your service from a running process.
If you are getting ACCESS_DENIED and can repro on Windows XP or later, you
can obtain RPC Extended Error Information as described in the MSDN to see
where the error is coming from.
Greg
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Post by Durand Miller
Hi,
I'm developing on Windows 2000 Server (SP4) with the Microsoft Platform
SDK (2003)
and Visual C++ 6. I currently have an RPC (tcp) connection running between
two machines to do remote data retrieval and this connection now needs to be
encrypted.
I'm hoping to get an SSL tunnel between the two using the RPC calls
RpcSetBindingAuthInfo and RpcServerRegisterAuthInfo while specifying
RPC_C_AUTHN_GSS_SCHANNEL and setting up my SCHANNEL_CRED structure...
I'm having little luck and there is hardly any documentation about this
1) I've made a self-signed certificate using makecert.exe and I've loaded
it into the LocalMachine\Root certificate store.
2) In the RPC server setup, I'm opening up this store and locating the
certificate.
3) I'm setting up an SCHANNEL_CRED structure to point to this single
certificate.
4) I'm also setting up the structure to point to the LocalMachine\Root
store as the trusted certificates.
5) I'm then calling RpcServerRegisterAuthInfo with
RPC_C_AUTHN_GSS_SCHANNEL and passing this SCHANNEL_CRED as my data.
6) I'm then continuing on as normal....
Do I need a principal name for the Register call? If my certificate is
called "bob", I've tried "msstd:bob", "bob" and NULL?
Do I need to initialize the SCHANNEL_CRED structure in any way? And if so,
how?
1) I've imported the same key that the server generated into the same
store - LocalMachine\Root
2) In the RPC server setup, I'm opening up this store and locating the
certificate.
3) I'm setting up an SCHANNEL_CRED structure to point to this single
certificate.
4) I'm specifying that SSL3/2/1, etc be used in the structure. (trying
them all)
5) I'm fully resolving my binding information
6) I'm then calling RpcSetBindingAuthInfo with RPC_C_AUTHN_GSS_SCHANNEL
and passing this SCHANNEL_CRED as my data.
7) I'm then continuing on as normal....and attempting to connect.
None of these calls return an error code. Everything returns 0 on both sides
of the connection.
However, when I run the actual RPC client, I get an error output of 5
(ACCESS DENIED) as soon as it attempts to connect.
Does this mean the handshake is failing and my credentials are incorrect?
Regards,
Durand.
Greg Kapoustin [MSFT]
2004-12-16 21:20:35 UTC
Permalink
RPC will not print error message -5 on the console. Error will be signaled
by RPC via an exception. You should be able to investigate where exactly
the exception occurs by debugging the process and catching the exception.

Your best bet for quickly isolating the cause of this error is to repro on
XP or later and to obtain the RPC Extended Error Information as described in
the MSDN.
Post by Durand Miller
Can you elaborate on how to initialize the SCHANNEL_CRED you will use for
the server and the client?
On the client/server:

SCHANNEL_CRED Credentials;
PCCERT_CONTEXT Context;
memset(Credentials, 0, sizeof(SCHANNEL_CRED));
Credentials->dwVersion = SCHANNEL_CRED_VERSION;
Credentials->cCreds = 1;
Credentials->paCred = &Context;

You should be able to find additional details on these structures in the
MSDN.

Greg
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Post by Durand Miller
Post by Greg Kapoustin [MSFT]
Are you saying that in some configuration the calls succeed, but in another
they fail?
Sorry, I mean that the calls during the RPC initialization all return 0
(OK). RpcBindingSetAuthInfoEx returns 0, etc. This happens on both the
server and client side.
It's only after the RPC initialization is complete, the server is
listening and the client attempts to run the remote procedure that an
error is printed to the console with an error code of -5 (access denied).
Note that this error message is printed to the console/cmd line. No error
message gets returned to my app .. just printed out.
I've already ensured that the permissions of private key directory (All
Users\Application Data\Microsoft\Crypto\RSA\MachineKeys) are correct.
They were incorrect and Schannel was reporting errors ("unable to access
private key") to the eventvwr on the server side. This situation also
generates a cmd line error message of -5. Once I corrected the
permissions, schannel no longer complained but my -5 errors messages
remained.
I believe it now means that the SSL handshake is failing. I'm using the
same self-signed key (public & private set) on both sides which I created
using makecert and I have installed it into the "Local Machine\Root". I
understand that there used to be a bug in schannel (2000SP2 and less?)
which only allowed keys in the CA certificate store. My machine was fully
patched with all fixes. I did move the certificate between Root, CA and
My in order to test any potential problems still there.
No luck.
Can you elaborate on how to initialize the SCHANNEL_CRED you will use for
the server and the client?
I'll get another basic example up and running to test on an XP machine.
When I solve this, I'd like to put up sample code on my website. I've
found very little documentation and no examples on how to do this.
Durand Miller
Post by Greg Kapoustin [MSFT]
Post by Durand Miller
None of these calls return an error code. Everything returns 0 on both sides
of the connection.
However, when I run the actual RPC client, I get an error output of 5
Are you saying that in some configuration the calls succeed, but in
another they fail?
The rough process to initializing RPC client and server for secure RPC
- Create a binding handle in the usual manner.
- Call CertOpenStore(), CertFindCertificateInStore() to load
PCCERT_CONTEXT
you will use to authenticate the client.
- Initialize the SCHANNEL_CRED you will use for the client.
- Call RpcBindingSetAuthInfoEx() for your binding handle passing
RPC_C_AUTHN_GSS_SCHANNEL, and the SCHANNEL_CRED you created as the
AuthIdentity parameter.
- Make the call.
- Don't forget to cleanup by calling CertFreeCertificateContext() and
CertCloseStore().
- Begin to initialize the server in the usual manner, but do not listen.
- Call CertOpenStore(), CertFindCertificateInStore() to load
PCCERT_CONTEXT
you will use to authenticate the server.
- Initialize the SCHANNEL_CRED you will use for the server.
- Call RpcServerRegisterAuthInfo() passing RPC_C_AUTHN_GSS_SCHANNEL, and the
SCHANNEL_CRED you created as the Arg parameter.
- You may need to cleanup by calling CertFreeCertificateContext() and
CertCloseStore() if you unload your service from a running process.
If you are getting ACCESS_DENIED and can repro on Windows XP or later,
you can obtain RPC Extended Error Information as described in the MSDN to
see where the error is coming from.
Greg
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Post by Durand Miller
Hi,
I'm developing on Windows 2000 Server (SP4) with the Microsoft Platform
SDK (2003)
and Visual C++ 6. I currently have an RPC (tcp) connection running between
two machines to do remote data retrieval and this connection now needs to be
encrypted.
I'm hoping to get an SSL tunnel between the two using the RPC calls
RpcSetBindingAuthInfo and RpcServerRegisterAuthInfo while specifying
RPC_C_AUTHN_GSS_SCHANNEL and setting up my SCHANNEL_CRED structure...
I'm having little luck and there is hardly any documentation about this
1) I've made a self-signed certificate using makecert.exe and I've
loaded it into the LocalMachine\Root certificate store.
2) In the RPC server setup, I'm opening up this store and locating the
certificate.
3) I'm setting up an SCHANNEL_CRED structure to point to this single
certificate.
4) I'm also setting up the structure to point to the LocalMachine\Root
store as the trusted certificates.
5) I'm then calling RpcServerRegisterAuthInfo with
RPC_C_AUTHN_GSS_SCHANNEL and passing this SCHANNEL_CRED as my data.
6) I'm then continuing on as normal....
Do I need a principal name for the Register call? If my certificate is
called "bob", I've tried "msstd:bob", "bob" and NULL?
Do I need to initialize the SCHANNEL_CRED structure in any way? And if so,
how?
1) I've imported the same key that the server generated into the same
store - LocalMachine\Root
2) In the RPC server setup, I'm opening up this store and locating the
certificate.
3) I'm setting up an SCHANNEL_CRED structure to point to this single
certificate.
4) I'm specifying that SSL3/2/1, etc be used in the structure. (trying
them all)
5) I'm fully resolving my binding information
6) I'm then calling RpcSetBindingAuthInfo with RPC_C_AUTHN_GSS_SCHANNEL
and passing this SCHANNEL_CRED as my data.
7) I'm then continuing on as normal....and attempting to connect.
None of these calls return an error code. Everything returns 0 on both sides
of the connection.
However, when I run the actual RPC client, I get an error output of 5
(ACCESS DENIED) as soon as it attempts to connect.
Does this mean the handshake is failing and my credentials are incorrect?
Regards,
Durand.
jvizente
2005-01-02 15:58:10 UTC
Permalink
Hi all,

im having a similar problem to this (I posted other message where i
explain it). Im not sure but if you are working on a xp sp2 machine or
you are trying to access a endpoint on a xp sp2, the problem could be
that. With the sp2 there is lot of changes in rpc. I think my problems
comes with that...

I have the same problem as you only when i set explicit credentials with
RpcBindingSetAuthInfo. I dont know if this could be useful but i did
some captures with ethereal and i notice a field of the bind packet is
different when i use explicit and implicit credentials. When i use
implicit the fields "calling workstation domain" and "calling
workstation name" have good values, pointing to string representing my
domain and name. But when i set explicit credentials both are NULL. With
RpcBindingSetAuthInfo is not possible to set that fields and i dont know
how to set them.

Have you tried to use implicit credentials instead explicit for seeing
if it works?
Post by Greg Kapoustin [MSFT]
RPC will not print error message -5 on the console. Error will be signaled
by RPC via an exception. You should be able to investigate where exactly
the exception occurs by debugging the process and catching the exception.
Your best bet for quickly isolating the cause of this error is to repro on
XP or later and to obtain the RPC Extended Error Information as described in
the MSDN.
Post by Durand Miller
Can you elaborate on how to initialize the SCHANNEL_CRED you will use for
the server and the client?
SCHANNEL_CRED Credentials;
PCCERT_CONTEXT Context;
memset(Credentials, 0, sizeof(SCHANNEL_CRED));
Credentials->dwVersion = SCHANNEL_CRED_VERSION;
Credentials->cCreds = 1;
Credentials->paCred = &Context;
You should be able to find additional details on these structures in the
MSDN.
Greg
Greg Kapoustin [MSFT]
2005-01-03 19:31:20 UTC
Permalink
This particular thread dealt with SSL questions. There should not have been
substantive changes in xpsp2 affecting secure RPC over SSL.

It sounds like your problem is encountered while using NTLM.

Greg
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Post by jvizente
Hi all,
im having a similar problem to this (I posted other message where i
explain it). Im not sure but if you are working on a xp sp2 machine or you
are trying to access a endpoint on a xp sp2, the problem could be that.
With the sp2 there is lot of changes in rpc. I think my problems comes
with that...
I have the same problem as you only when i set explicit credentials with
RpcBindingSetAuthInfo. I dont know if this could be useful but i did some
captures with ethereal and i notice a field of the bind packet is
different when i use explicit and implicit credentials. When i use
implicit the fields "calling workstation domain" and "calling workstation
name" have good values, pointing to string representing my domain and
name. But when i set explicit credentials both are NULL. With
RpcBindingSetAuthInfo is not possible to set that fields and i dont know
how to set them.
Have you tried to use implicit credentials instead explicit for seeing if
it works?
Post by Greg Kapoustin [MSFT]
RPC will not print error message -5 on the console. Error will be signaled
by RPC via an exception. You should be able to investigate where exactly
the exception occurs by debugging the process and catching the exception.
Your best bet for quickly isolating the cause of this error is to repro on
XP or later and to obtain the RPC Extended Error Information as described in
the MSDN.
Post by Durand Miller
Can you elaborate on how to initialize the SCHANNEL_CRED you will use for
the server and the client?
SCHANNEL_CRED Credentials;
PCCERT_CONTEXT Context;
memset(Credentials, 0, sizeof(SCHANNEL_CRED));
Credentials->dwVersion = SCHANNEL_CRED_VERSION;
Credentials->cCreds = 1;
Credentials->paCred = &Context;
You should be able to find additional details on these structures in the
MSDN.
Greg
Loading...