5.3.3.1.3 Validating a Proprietary Certificate

Verification of the Proprietary Certificate signature is carried out by decrypting the signature with the Terminal Services public signing key and then verifying that this result is the same as the MD5 hash of the first six fields of the certificate.

 m = s^e mod n

Where

 m = decrypted signature
 s = signature
 e = public exponent
 n = modulus

The structure of the Proprietary Certificate is detailed in section 2.2.1.4.3.1.1. A 128-bit MD5 hash over the first six fields (which are all little-endian integers of varying lengths) appears as follows.

 PublicKeyBlob = wBlobType + wBlobLen + PublicKeyBytes
 hash = MD5(dwVersion + dwSigAlgID + dwKeyAlgID + PublicKeyBlob)

Next, the actual signature bytes are decrypted with the Terminal Services public key using RSA by treating the signature bytes as an unsigned little-endian integer. If performed correctly, the decryption operation will produce a 63-byte integer value. When represented in little-endian format, this integer value conforms to the following specification.

  • The 17th byte is 0x00.

  • The 18th through 62nd bytes are each 0xFF.

  • The 63rd byte is 0x01.

The following is an example of a successfully decrypted signature.

 0xf5 0xcc 0x18 0xee 0x45 0xe9 0x4d 0xa6
 0x79 0x02 0xca 0x76 0x51 0x33 0xe1 0x7f
 0x00 0xff 0xff 0xff 0xff 0xff 0xff 0xff 
 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 
 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff
 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 
 0xff 0xff 0xff 0xff 0xff 0xff 0x01

The first 16 bytes of the decrypted signature are then compared to the hash that was generated over the Proprietary Certificate, and if they match, the signature has been successfully verified.

Example Java source code that shows how to use a private 64-byte asymmetric key to sign an array of 63 bytes by using RSA is presented in section 4.9. The code also shows how to use the associated public key to verify the signature.