Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Needs to handle SEC_I_INCOMPLETE_CREDENTIALS from InitializeSecurityContext #32

Open
sdroege opened this issue Jun 28, 2017 · 2 comments

Comments

@sdroege
Copy link

sdroege commented Jun 28, 2017

match status {

The server might request credentials (i.e. a client-side certificate for authentication), but does not necessarily actually require it (SEC_E_INCOMPLETE_CREDENTIALS at a later time, note the I vs. E). When getting SEC_I_INCOMPLETE_CREDENTIALS, InitializeSecurityContext() just has to be called again like the first time (without any input) and will produce new output then.

Alternatively one can create a new credentials handle with any client certificates before doing the above.

@heinzelotto
Copy link

Since we pass ISC_REQ_USE_SUPPLIED_CREDS #24 InitializeSecurityContext() will never return the informational status code SEC_I_INCOMPLETE_CREDENTIALS.

The documentation is wrong on this one. It says:

When the server requests client authentication, the client must send the server one of its certificates. By default, Schannel will, with no notification to the client, attempt to locate a client certificate and send it to the server. To disable this feature, clients specify ISC_REQ_USE_SUPPLIED_CREDS when calling the InitializeSecurityContext (Schannel) function. When this flag is specified, Schannel will return SEC_I_INCOMPLETE_CREDENTIALS to the client when the server requests authentication and the client has not previously supplied a certificate.

After experimenting, I discovered the following for the case that no client cert was explicitly specified and the server sends a CertificateRequest:

  • If SCH_CRED_NO_DEFAULT_CREDS is set in AcquireCredentialsHandle(), then any available client certs from the store are ignored, they will not automatically be used. If the flag is not set, then an available client certificate will automatically be selected from the store when the server requests client auth.
  • If ISC_REQ_USE_SUPPLIED_CREDS is set in InitializeSecurityContext(), no informational status code will be returned. When a client cert is available (explicitly specified or automatically retrieved from the store) it will be sent, if not then no certificate will be sent (and the server can decide to terminate the connection). If the flag is not set, then upon a CertificateRequest by the server but no available client cert, InitializeSecurityContext() will return SEC_I_INCOMPLETE_CREDENTIALS, giving us the chance to maybe prompt the user for a certificate, set it in the credential and continue by calling ISC again.

@obsgolem
Copy link

obsgolem commented Aug 29, 2022

I think I will need this feature for implementing sfackler/rust-native-tls#232. My thought for that is to provide the ability to specify a client certificate beforehand, as well as a callback for if you don't do that. The callback should take a list of valid CAs (retrieved through QueryContextAttributes) and return a certificate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants