Important:
This is retired content. This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
A version of this page is also available for
4/8/2010

Client certificates contain information that identifies the user, as well as information about the organization that issued the certificate. For example, a standard X.509 certificate contains at least the following:

  • Version

  • Serial number

  • Signature algorithm ID

  • Issuer name

  • Validity period

  • Subject (user) name

  • Subject public key information

  • Signature on the fields just listed

Note:
SSL client certificates are only supported in Windows CE .NET 4.1 and later.

Virtual Root Configuration

It is possible to require or allow a client to provide a certificate during SSL negotiations. Whether to require (or allow) a client certificate is set on a per-virtual-root basis. The Web Server will request the Web client to send a client certificate, if it has one, if either of the following flags are set as the Pparameter of the requested virtual root. For more information, see Virtual Path Registry Settings.

The following code example shows how to set the flags to require or allow SSL client certificates.

Copy Code
HSE_URL_FLAGS_REQUIRE_CERT (0x00000040) Requires SSL client
certificates.
HSE_URL_FLAGS_NEGO_CERT (0x00000020)  Allows SSL client
certificates.

If the client does not provide a certificate to the Web Server and HSE_URL_FLAGS_REQUIRE_CERTwas set, the request will terminate and an error will be returned to the client. If the HSE_URL_FLAGS_NEGO_CERTbut not the HSE_URL_FLAGS_REQUIRE_CERTwas set, then the request will continue.

There are two primary ways to use client certificates on the server. One is to write an ISAPI extension that uses information in the client certificate to determine information such as what operations on the extension the user is allowed to perform. In this case, the ISAPI extension maps the user name and permissions allowed for itself. The other way is to use the Web Server to map client certificates before processing the request further.

Mapping Client Certificate Information to a Web Server User

If the following flag is set in the Pvalue of the virtual root the Web Server will attempt to match the information in the certificate to a user name upon successfully receiving the SSL client certificate.

Copy Code
HSE_URL_FLAGS_MAP_CERT   0x00000080  // Map SSL cert to user
account

With IIS, the HSE_URL_FLAGS_MAP_CERTflag will map the certificate information to an NT user account. Since Windows Embedded CE does not have user accounts, this flag will instead map to a Web Server pseudo-user. This user is then checked against the UserListregistry setting for the virtual root that is being accessed, as described in Web Server Access Rights. For information about UserList, see Virtual Path Registry Settings.

Client certificates are mapped to users based on the IssuerCNand/or the certificate's serial number. Web Server pseudo users are enumerated in the registry and specified under the Web site's SSL\Userskey. The name of each registry key under the SSL\Userskey specifies the pseudo user's name. The values IssuerCNand SerialNumberunder each user name registry entry specify the IssuerCNand SerialNumberof the certificate that must be provided in order to map the user. IssuerCNis a REG_SZ. SerialNumberis a binary entry.

Example of Mapping Client Certificate Information to a Web Server User

The following example shows how to setup a Web Server registry to require SSL client certificates for a restricted virtual root, create a list of users, and map the certificates to the user name. In this scenario, we want to limit access to the virtual root /Accountsto the users Alice, Bob, and Carol.

First we setup the Web Server to use SSL. The certificate name CE Server Certificatemust already be installed in the Web Server's certificate store. This is the server certificate that the Web Server sends on all SSL negotiations, not to be confused with the client certificate. It is also assumed that the issuer of the client certificates will have already been setup as a trusted authority in the Windows Embedded CE trusted or privileged security store.

Copy Code
[HKEY_LOCAL_MACHINE\HTTPD\SSL]
	"IsEnabled"=dword:1
	"CertificateSubject"= "CE Server Certificate"

Next we setup the virtual root /Accounts. A=1signifies that a user must be authenticated to gain access to resources under this virtual root. P= HSE_URL_FLAGS_EXECUTE | HSE_URL_FLAGS_REQUIRE_CERT | HSE_URL_FLAGS_MAP_CERT | HSE_URL_FLAGS_SSL128. This allows the virtual root resources to be executed — that is, to run the ISAPI extension), requires the client to send SSL certificates, maps the certificate to a user account, and requires 128 bit encryption. The UserListspecifies the users who will be allowed to access this page.

Copy Code
[HKEY_LOCAL_MACHINE\HTTPD\VROOTS\/Accounting/]
	; ISAPI extension that we're placing restricitons on.
	@="\windows\accounting.dll" 
	"A"=dword:1
	"P"=dword: 0x000001C4
	"UserList"="alice;bob;carol"

Now we list our three users and the SSL client certificates that will map to them. Alice and Bob were issued their certificate from CompanyIssuer, which is the certificate server for their company. Since we do not want to allow access to anyone that has a certificate issued from CompanyIssuer, we further restrict access based on the serial number of the certificate. In Carol's case, AccountingIssueris more restrictive about to whom certificates will be issued in the first place. So as not to need to enter a different serial number for each user that has a certificate from AccountingIssuer, we do not include the serial number in this case.

Copy Code
[HKEY_LOCAL_MACHINE\HTTPD\SSL\USERS\Alice\MAP-1]
	"IssuerCN"="CompanyIssuer"
	"SerialNumber"=hex: 01,02,03,04,00,00,00,00,00,05
[HKEY_LOCAL_MACHINE\HTTPD\SSL\USERS\Bob\MAP-1]
	"IssuerCN"="CompanyIssuer"
	"SerialNumber"=hex: 01,02,03,04,00,00,00,00,00,06
[HKEY_LOCAL_MACHINE\HTTPD\SSL\USERS\Carol\MAP-1]
	"IssuerCN"="AccountingIssuer"

That is all that is needed for the registry.

When a request comes in over SSL to the virtual root /Accounting, the Web Server will request a client certificate and fail if one is not provided (due to HSE_URL_FLAGS_REQUIRE_CERTbeing set.)

If the certificate is provided, the Web Server will run through each of the users and try to match the provided IssuerCNand SerialNumber.

Before accessing accounting.dll, the Web Server will verify that the user mapped by the client cert is specified is present in the UserList. If this is not the case, the Web Server will return an error, but will not try to perform Basic or NTLM authentication on this virtual root, even if Basic and/or NTLM are supported by the Web Server. If a client certificate is requested for a given virtual root, no other form of authentication will be supported other than mapping that client certificate to the user name as described above.

Allowing Certificates that Would Otherwise Be Rejected

Before retrieving any information from the client certificate, the Web Server will first verify that the certificate is valid. To be valid the certificate must have a valid date, be issued from a trusted authority, among other requirements. The Web Server makes a call to CertGetCertificateChainto make this determination. If there is an error, CertGetCertificateChainwill specify an error of the form CERT_TRUST_xxx( CERT_TRUSTflags are defined in Wincrypt.h). If the value specified is anything other than CERT_TRUST_NO_ERROR, by default the Web Server will terminate the request and return an error to the client.

It is possible to override the Web Server's default rejection of invalid certificates. To enable this, in the base SSL registry key for the Web site set the registry value CertTrustOverrideto be a DWORDof the CERT_TRUST_error flags that you are willing to have the Web Server ignore. The Web Server will ignore these (and only these) error codes.

For instance, to have the default Web site accept a certificate authority that CertGetCertificateChainbrings up errors on, set ( CERT_TRUST_IS_PARTIAL_CHAIN | CERT_TRUST_IS_UNTRUSTED_ROOT) in CertTrustOverride, as follows.

Copy Code
[HKEY_LOCAL_MACHINE\COMM\HTTPD\SSL]
	CertTrustOverride=dword: 0x00010020
Security Note:
It is highly recommended that CertTrustOverridenot be modified from the default value, due to security concerns. This functionality is provided as a last ditch resort for scenarios where proper certificates cannot be issued.

Notice About Posting Large Amounts of Data When Using Client Certificates

Due to the way the SSL protocol works, along with the security policy of the Web Server, there may be some difficulty posting extremely large amounts of data to the Web Server if SSL client certificates are being used in the same request.

The way the Web Server typically handles large POST requests (even when doing SSL with no client certificates) is to read the first PostReadSizesize of bytes into a buffer and stop reading. It is the responsibility of the ISAPI extension to continue to receive more data at this point by making repeated calls to ReadClient. The Web Server does this to make sure that it never tries to allocate a buffer that is too large and to guard against malicious users sending enormous amounts of data to the device to exhausts its resources.

When a request comes into a virtual root using a client certificate, the Web Server is unaware that it will need a client certificate until after the initial SSL handshake because it will not know what virtual root is being requested until after the handshake is complete. When it sees it needs a client certificate, the Web Server will request one in the middle of the request. It is possible that the Web client will send its client certificate after it has sent greater than PostReadSizeamount of bytes. If the Web Server has not received the SSL client cert before reading PostReadSizebytes, it will terminate the request.

To work around this, either increase the size of PostReadSizeto be the maximum size of the buffer you are willing to accept. As an alternative, you can create a connection to the virtual root that requires client certificates that does not POST data and that does a keep-alive. On this connection the client certificate can be obtained by the Web Server without having to deal with this issue. On the next request (as long as keep-alives are used), there will be no need for the client to resend its certificate and the previous scenario will not be an issue.

See Also