Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

407 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name:
  4. clicert.c
  5. Abstract:
  6. Contains code related to the tshare certificate validation and data
  7. encryption using server public key.
  8. Author:
  9. Madan Appiah (madana) 24-Jan-1998
  10. Environment:
  11. User Mode - Win32
  12. Revision History:
  13. --*/
  14. #include <seccom.h>
  15. BOOL
  16. UnpackServerCert(
  17. LPBYTE pbCert,
  18. DWORD dwCertLen,
  19. PHydra_Server_Cert pServerCert
  20. )
  21. /*++
  22. Routine Description:
  23. This function unpacks the blob of server certicate to server certificate
  24. structure.
  25. Arguments:
  26. pbCert - pointer to the server public key blob.
  27. dwCertLen - length of the above server public key.
  28. pServerCert - pointer to a server certificate structure.
  29. Return Value:
  30. TRUE - if successfully unpacked.
  31. FALSE - otherwise.
  32. --*/
  33. {
  34. LPBYTE pbScan;
  35. DWORD cbScan;
  36. //
  37. // return if the pointer are invalid.
  38. // return if the certificate is insufficient length.
  39. //
  40. if( (pbCert == NULL) ||
  41. (dwCertLen < (3 * sizeof(DWORD) + 4 * sizeof(WORD))) ||
  42. (pServerCert == NULL) ) {
  43. return( FALSE );
  44. }
  45. pbScan = pbCert;
  46. cbScan = dwCertLen;
  47. //
  48. // Assign dwVersion
  49. //
  50. pServerCert->dwVersion = *(DWORD UNALIGNED FAR *)pbScan;
  51. pbScan += sizeof(DWORD);
  52. cbScan -= sizeof(DWORD);
  53. //
  54. // Assign dwSigAlgID
  55. //
  56. pServerCert->dwSigAlgID = *(DWORD UNALIGNED FAR *)pbScan;
  57. pbScan += sizeof(DWORD);
  58. cbScan -= sizeof(DWORD);
  59. //
  60. // Assign dwSignID
  61. //
  62. pServerCert->dwKeyAlgID = *(DWORD UNALIGNED FAR *)pbScan;
  63. pbScan += sizeof(DWORD);
  64. cbScan -= sizeof(DWORD);
  65. //
  66. //Assign PublicKeyData
  67. //
  68. pServerCert->PublicKeyData.wBlobType = *(WORD UNALIGNED FAR *)pbScan;
  69. pbScan += sizeof(WORD);
  70. cbScan -= sizeof(WORD);
  71. if( pServerCert->PublicKeyData.wBlobType != BB_RSA_KEY_BLOB ) {
  72. return( FALSE );
  73. }
  74. pServerCert->PublicKeyData.wBlobLen = *(WORD UNALIGNED FAR *)pbScan;
  75. pbScan += sizeof(WORD);
  76. cbScan -= sizeof(WORD);
  77. if( pServerCert->PublicKeyData.wBlobLen > 0 ) {
  78. if(cbScan < pServerCert->PublicKeyData.wBlobLen) {
  79. return ( FALSE );
  80. }
  81. pServerCert->PublicKeyData.pBlob = pbScan;
  82. pbScan += pServerCert->PublicKeyData.wBlobLen;
  83. cbScan -= pServerCert->PublicKeyData.wBlobLen;
  84. }
  85. else {
  86. pServerCert->PublicKeyData.pBlob = NULL;
  87. }
  88. //
  89. // Assign SignatureBlob
  90. //
  91. if(cbScan < sizeof(WORD)) {
  92. return ( FALSE );
  93. }
  94. pServerCert->SignatureBlob.wBlobType = *(WORD UNALIGNED *)pbScan;
  95. pbScan += sizeof(WORD);
  96. cbScan -= sizeof(WORD);
  97. if( pServerCert->SignatureBlob.wBlobType != BB_RSA_SIGNATURE_BLOB ) {
  98. return( FALSE );
  99. }
  100. if(cbScan < sizeof(WORD)) {
  101. return ( FALSE );
  102. }
  103. pServerCert->SignatureBlob.wBlobLen = *(WORD UNALIGNED FAR *)pbScan;
  104. pbScan += sizeof(WORD);
  105. cbScan -= sizeof(WORD);
  106. if( pServerCert->SignatureBlob.wBlobLen > 0 ) {
  107. if(cbScan < pServerCert->SignatureBlob.wBlobLen) {
  108. return ( FALSE );
  109. }
  110. pServerCert->SignatureBlob.pBlob = pbScan;
  111. }
  112. else {
  113. pServerCert->SignatureBlob.pBlob = NULL;
  114. }
  115. return( TRUE );
  116. }
  117. BOOL
  118. ValidateServerCert(
  119. PHydra_Server_Cert pServerCert
  120. )
  121. /*++
  122. Routine Description:
  123. This function validate the server public key.
  124. Arguments:
  125. pSserverCert - pointer to a server certificate.
  126. Return Value:
  127. TRUE - if the server public key is valid.
  128. FALSE - otherwise.
  129. --*/
  130. {
  131. DWORD dwLen;
  132. LPBYTE pbSignature;
  133. MD5_CTX HashState;
  134. BYTE SignHash[0x48];
  135. LPBYTE pbScan;
  136. //
  137. // pack the certificate data into a byte blob excluding the signature info.
  138. //
  139. dwLen =
  140. 3 * sizeof(DWORD) +
  141. 2 * sizeof(WORD) +
  142. pServerCert->PublicKeyData.wBlobLen;
  143. //
  144. // allocated space for the binary blob.
  145. //
  146. pbSignature = malloc( (UINT)dwLen );
  147. if( pbSignature == NULL ) {
  148. return( FALSE );
  149. }
  150. pbScan = pbSignature;
  151. memcpy( pbScan, &pServerCert->dwVersion, sizeof(DWORD));
  152. pbScan += sizeof(DWORD);
  153. memcpy( pbScan, &pServerCert->dwSigAlgID, sizeof(DWORD));
  154. pbScan += sizeof(DWORD);
  155. memcpy( pbScan, &pServerCert->dwKeyAlgID, sizeof(DWORD));
  156. pbScan += sizeof(DWORD);
  157. memcpy( pbScan, &pServerCert->PublicKeyData.wBlobType, sizeof(WORD));
  158. pbScan += sizeof(WORD);
  159. memcpy( pbScan, &pServerCert->PublicKeyData.wBlobLen, sizeof(WORD));
  160. pbScan += sizeof(WORD);
  161. memcpy(
  162. pbScan,
  163. pServerCert->PublicKeyData.pBlob,
  164. pServerCert->PublicKeyData.wBlobLen);
  165. //
  166. // generate the hash on the data.
  167. //
  168. MD5Init( &HashState );
  169. MD5Update( &HashState, pbSignature, dwLen );
  170. MD5Final( &HashState );
  171. //
  172. // free the signature blob, we don't need it anymore.
  173. //
  174. free( pbSignature );
  175. //
  176. // initialize the pulic key.
  177. //
  178. g_pPublicKey = (LPBSAFE_PUB_KEY)g_abPublicKeyModulus;
  179. g_pPublicKey->magic = RSA1;
  180. g_pPublicKey->keylen = 0x48;
  181. g_pPublicKey->bitlen = 0x0200;
  182. g_pPublicKey->datalen = 0x3f;
  183. g_pPublicKey->pubexp = 0xc0887b5b;
  184. //
  185. // decrypt the signature.
  186. //
  187. memset(SignHash, 0x00, 0x48);
  188. BSafeEncPublic( g_pPublicKey, pServerCert->SignatureBlob.pBlob, SignHash);
  189. //
  190. // compare the hash value.
  191. //
  192. if( memcmp( SignHash, HashState.digest, 16 )) {
  193. return( FALSE );
  194. }
  195. //
  196. // successfully validated the signature.
  197. //
  198. return( TRUE );
  199. }
  200. BOOL
  201. EncryptClientRandom(
  202. LPBYTE pbSrvPublicKey,
  203. DWORD dwSrvPublicKey,
  204. LPBYTE pbRandomKey,
  205. DWORD dwRandomKeyLen,
  206. LPBYTE pbEncRandomKey,
  207. LPDWORD pdwEncRandomKey
  208. )
  209. /*++
  210. Routine Description:
  211. Encrypt the client random using server's public key.
  212. Arguments:
  213. pbSrvPublicKey - pointer to the server public key.
  214. dwSrvPublicKey - length of the server public key.
  215. pbRandomKey - pointer to a buffer where the client random key.
  216. dwRandomKeyLen - length of the random key passed in.
  217. pbEncRandomKey - pointer to a buffer where the encrypted client random is
  218. returned.
  219. pdwEncRandomKey - pointer to a place where the length of the above buffer is
  220. passed in and length of the buffer used/required is returned.
  221. In case the function fails for other reasons then insufficient buffer
  222. the value of *pdwEncRandomKey is 0.
  223. Return Value:
  224. TRUE - if the key is encrypted successfully.
  225. FALSE - otherwise.
  226. --*/
  227. {
  228. LPBSAFE_PUB_KEY pSrvPublicKey;
  229. BYTE abInputBuffer[512];
  230. ASSERT( pbSrvPublicKey != NULL );
  231. pSrvPublicKey = (LPBSAFE_PUB_KEY)pbSrvPublicKey;
  232. //
  233. // check to see buffer length pointer is valid.
  234. //
  235. if( pdwEncRandomKey == NULL ) {
  236. return( FALSE );
  237. }
  238. //
  239. // First we have to check that the keylen makes sense. If it is bigger
  240. // then the abInputBuffer we can't use it. So it does not make sense for
  241. // the caller to allocate it. Also if a bad server gives us a big number
  242. // in keylen we will just fail the call and not tell the caller to allocate
  243. // the buffer and call us back with a buffer we can't use anyway.
  244. //
  245. if ((NULL == pSrvPublicKey) ||
  246. (pSrvPublicKey->datalen >= pSrvPublicKey->keylen) ||
  247. (pSrvPublicKey->keylen > sizeof(abInputBuffer))) {
  248. *pdwEncRandomKey = 0;
  249. return( FALSE );
  250. }
  251. //
  252. // check to see a output buffer is specified and
  253. // the encrypt buffer length is sufficient.
  254. //
  255. if( (pbEncRandomKey == NULL) ||
  256. (*pdwEncRandomKey < pSrvPublicKey->keylen) ) {
  257. *pdwEncRandomKey = pSrvPublicKey->keylen;
  258. return( FALSE );
  259. }
  260. // Check if the pbRandomKey and dwRandomKeyLen are valid.
  261. // We did not do this in the beginning because we should
  262. // be able to query the needed buffer length by passing
  263. // in just the pSrvPublicKey pointer and the pdwEncRandomKey.
  264. if ((NULL == pbRandomKey) ||
  265. (dwRandomKeyLen > pSrvPublicKey->datalen)) {
  266. *pdwEncRandomKey = 0;
  267. return( FALSE );
  268. }
  269. //
  270. // init the input buffer.
  271. //
  272. memset( abInputBuffer, 0x0, (UINT)pSrvPublicKey->keylen );
  273. //
  274. // copy data to be encrypted in the input buffer.
  275. //
  276. memcpy( abInputBuffer, pbRandomKey, (UINT)dwRandomKeyLen );
  277. //
  278. // initialize the output buffer.
  279. //
  280. memset( pbEncRandomKey, 0x0, (UINT)pSrvPublicKey->keylen );
  281. //
  282. // encrypt data now.
  283. //
  284. if( !BSafeEncPublic(
  285. pSrvPublicKey,
  286. (LPBYTE)abInputBuffer,
  287. pbEncRandomKey ) ) {
  288. *pdwEncRandomKey = 0;
  289. return( FALSE );
  290. }
  291. //
  292. // successfully encrypted the client random,
  293. // return the encrypted data length.
  294. //
  295. *pdwEncRandomKey = pSrvPublicKey->keylen;
  296. return( TRUE );
  297. }