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.

898 lines
27 KiB

  1. #include <windows.h>
  2. #include <wincrypt.h>
  3. #include <winscard.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. /*
  8. A list of the API calls made by enrollment:
  9. CryptAcquireContext
  10. CRYPT_VERIFYCONTEXT
  11. CryptGetProvParam
  12. PP_ENUMALGS_EX
  13. PP_ENUMALGS
  14. PP_KEYSPEC
  15. PP_NAME
  16. PP_UNIQUE_CONTAINER
  17. PP_PROVTYPE
  18. CryptReleaseContext
  19. CryptGetUserKey
  20. AT_KEYEXCHANGE
  21. CryptGenKey
  22. CryptDestroyKey
  23. CryptExportKey
  24. PUBLICKEYBLOB
  25. CryptCreateHash
  26. CALG_SHA
  27. CryptHashData
  28. CryptSignHash
  29. AT_KEYEXCHANGE
  30. CryptDestroyHash
  31. */
  32. #define TEST_CASE(X) { if (ERROR_SUCCESS != (dwSts = X)) { printf("%s", #X); goto Ret; } }
  33. #define CAPI_TEST_CASE(X) { if (! X) { dwSts = GetLastError(); printf("%s", #X); goto Ret; } }
  34. BYTE rgbTestCer [] = {
  35. 0x30, 0x82, 0x05, 0x8f, 0x30, 0x82, 0x04, 0xf8, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x0a, 0x1e,
  36. 0x39, 0xa7, 0x1c, 0x00, 0x01, 0x00, 0x0f, 0xc9, 0x64, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
  37. 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x4b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03,
  38. 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a,
  39. 0x13, 0x09, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x31, 0x0e, 0x30, 0x0c, 0x06,
  40. 0x03, 0x55, 0x04, 0x0b, 0x13, 0x05, 0x4e, 0x74, 0x64, 0x65, 0x76, 0x31, 0x18, 0x30, 0x16, 0x06,
  41. 0x03, 0x55, 0x04, 0x03, 0x13, 0x0f, 0x4e, 0x54, 0x44, 0x45, 0x56, 0x20, 0x49, 0x53, 0x53, 0x55,
  42. 0x45, 0x33, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x31, 0x31, 0x31, 0x31, 0x39, 0x32,
  43. 0x31, 0x32, 0x39, 0x31, 0x34, 0x5a, 0x17, 0x0d, 0x30, 0x32, 0x30, 0x39, 0x32, 0x30, 0x32, 0x31,
  44. 0x33, 0x33, 0x32, 0x38, 0x5a, 0x30, 0x7b, 0x31, 0x13, 0x30, 0x11, 0x06, 0x0a, 0x09, 0x92, 0x26,
  45. 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x03, 0x63, 0x6f, 0x6d, 0x31, 0x19, 0x30, 0x17,
  46. 0x06, 0x0a, 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x09, 0x6d, 0x69,
  47. 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x31, 0x15, 0x30, 0x13, 0x06, 0x0a, 0x09, 0x92, 0x26,
  48. 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, 0x16, 0x05, 0x6e, 0x74, 0x64, 0x65, 0x76, 0x31, 0x0c,
  49. 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x03, 0x49, 0x54, 0x47, 0x31, 0x0e, 0x30, 0x0c,
  50. 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x05, 0x55, 0x73, 0x65, 0x72, 0x73, 0x31, 0x14, 0x30, 0x12,
  51. 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0b, 0x44, 0x61, 0x6e, 0x20, 0x47, 0x72, 0x69, 0x66, 0x66,
  52. 0x69, 0x6e, 0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
  53. 0x01, 0x01, 0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0x89,
  54. 0x9f, 0x70, 0xb2, 0x5e, 0xfd, 0x99, 0x31, 0xb8, 0xcd, 0x17, 0xba, 0x2f, 0x7c, 0xb9, 0xed, 0xde,
  55. 0x56, 0xff, 0xb3, 0x37, 0x78, 0xd0, 0x51, 0xae, 0x14, 0x7c, 0xae, 0x91, 0x1f, 0xb0, 0x26, 0x87,
  56. 0xaf, 0x43, 0x3e, 0xde, 0x59, 0xbb, 0xc8, 0xcf, 0xbe, 0x25, 0x03, 0x0a, 0x1c, 0xd8, 0x18, 0x4d,
  57. 0x1a, 0xbd, 0xe3, 0xb0, 0x73, 0xc9, 0x2b, 0x29, 0x0b, 0x0a, 0x12, 0xdd, 0x55, 0x37, 0xcb, 0x2b,
  58. 0x8f, 0xf2, 0xe6, 0x2c, 0x2e, 0x7f, 0x8d, 0x71, 0x9a, 0x77, 0xf6, 0x4e, 0x4e, 0x3e, 0x94, 0x2e,
  59. 0xdb, 0x3c, 0xd4, 0xde, 0x32, 0x1f, 0xc7, 0xb9, 0x96, 0x72, 0xbb, 0x0d, 0x80, 0xc9, 0xc0, 0x3e,
  60. 0x84, 0xee, 0x33, 0x3c, 0x62, 0x46, 0x17, 0x7d, 0x27, 0x83, 0x15, 0xdd, 0x2f, 0x2f, 0x0a, 0xb3,
  61. 0xcf, 0x76, 0xf6, 0x9b, 0x0d, 0x70, 0x6d, 0x99, 0x5b, 0xca, 0xba, 0x07, 0x8a, 0x44, 0xd3, 0x02,
  62. 0x03, 0x01, 0x00, 0x01, 0xa3, 0x82, 0x03, 0x48, 0x30, 0x82, 0x03, 0x44, 0x30, 0x0b, 0x06, 0x03,
  63. 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xa0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e,
  64. 0x04, 0x16, 0x04, 0x14, 0x38, 0xef, 0x1a, 0xde, 0x6f, 0x3e, 0xa8, 0x73, 0x86, 0x74, 0xb8, 0x27,
  65. 0x4b, 0x9e, 0x8a, 0x98, 0xf7, 0x67, 0x70, 0x47, 0x30, 0x2b, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04,
  66. 0x01, 0x82, 0x37, 0x14, 0x02, 0x04, 0x1e, 0x1e, 0x1c, 0x00, 0x53, 0x00, 0x6d, 0x00, 0x61, 0x00,
  67. 0x72, 0x00, 0x74, 0x00, 0x63, 0x00, 0x61, 0x00, 0x72, 0x00, 0x64, 0x00, 0x4c, 0x00, 0x6f, 0x00,
  68. 0x67, 0x00, 0x6f, 0x00, 0x6e, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
  69. 0x80, 0x14, 0xc9, 0x44, 0x56, 0x4a, 0x90, 0x13, 0x7c, 0xa9, 0xf3, 0x33, 0x06, 0x6b, 0xde, 0xd0,
  70. 0x99, 0xbb, 0xe7, 0xc8, 0xce, 0xe9, 0x30, 0x82, 0x01, 0x26, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04,
  71. 0x82, 0x01, 0x1d, 0x30, 0x82, 0x01, 0x19, 0x30, 0x82, 0x01, 0x15, 0xa0, 0x82, 0x01, 0x11, 0xa0,
  72. 0x82, 0x01, 0x0d, 0x86, 0x81, 0xc4, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e,
  73. 0x3d, 0x4e, 0x54, 0x44, 0x45, 0x56, 0x25, 0x32, 0x30, 0x49, 0x53, 0x53, 0x55, 0x45, 0x33, 0x25,
  74. 0x32, 0x30, 0x43, 0x41, 0x2c, 0x43, 0x4e, 0x3d, 0x57, 0x48, 0x49, 0x43, 0x41, 0x33, 0x2c, 0x43,
  75. 0x4e, 0x3d, 0x43, 0x44, 0x50, 0x2c, 0x43, 0x4e, 0x3d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25,
  76. 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73,
  77. 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d,
  78. 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43,
  79. 0x3d, 0x6e, 0x74, 0x64, 0x65, 0x76, 0x2c, 0x44, 0x43, 0x3d, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73,
  80. 0x6f, 0x66, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d, 0x3f, 0x63, 0x65, 0x72, 0x74, 0x69,
  81. 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x52, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
  82. 0x4c, 0x69, 0x73, 0x74, 0x3f, 0x62, 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74,
  83. 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d, 0x63, 0x52, 0x4c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62,
  84. 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x86, 0x44, 0x68, 0x74, 0x74, 0x70,
  85. 0x3a, 0x2f, 0x2f, 0x77, 0x68, 0x69, 0x63, 0x61, 0x33, 0x2e, 0x6e, 0x74, 0x64, 0x65, 0x76, 0x2e,
  86. 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65,
  87. 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c, 0x2f, 0x4e, 0x54, 0x44, 0x45, 0x56, 0x25, 0x32,
  88. 0x30, 0x49, 0x53, 0x53, 0x55, 0x45, 0x33, 0x25, 0x32, 0x30, 0x43, 0x41, 0x2e, 0x63, 0x72, 0x6c,
  89. 0x30, 0x82, 0x01, 0x42, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 0x82,
  90. 0x01, 0x34, 0x30, 0x82, 0x01, 0x30, 0x30, 0x81, 0xbd, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
  91. 0x07, 0x30, 0x02, 0x86, 0x81, 0xb0, 0x6c, 0x64, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x2f, 0x43, 0x4e,
  92. 0x3d, 0x4e, 0x54, 0x44, 0x45, 0x56, 0x25, 0x32, 0x30, 0x49, 0x53, 0x53, 0x55, 0x45, 0x33, 0x25,
  93. 0x32, 0x30, 0x43, 0x41, 0x2c, 0x43, 0x4e, 0x3d, 0x41, 0x49, 0x41, 0x2c, 0x43, 0x4e, 0x3d, 0x50,
  94. 0x75, 0x62, 0x6c, 0x69, 0x63, 0x25, 0x32, 0x30, 0x4b, 0x65, 0x79, 0x25, 0x32, 0x30, 0x53, 0x65,
  95. 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,
  96. 0x65, 0x73, 0x2c, 0x43, 0x4e, 0x3d, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74,
  97. 0x69, 0x6f, 0x6e, 0x2c, 0x44, 0x43, 0x3d, 0x6e, 0x74, 0x64, 0x65, 0x76, 0x2c, 0x44, 0x43, 0x3d,
  98. 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2c, 0x44, 0x43, 0x3d, 0x63, 0x6f, 0x6d,
  99. 0x3f, 0x63, 0x41, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x3f, 0x62,
  100. 0x61, 0x73, 0x65, 0x3f, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x3d,
  101. 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x75, 0x74,
  102. 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x6e, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
  103. 0x30, 0x02, 0x86, 0x62, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x68, 0x69, 0x63, 0x61,
  104. 0x33, 0x2e, 0x6e, 0x74, 0x64, 0x65, 0x76, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66,
  105. 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x65, 0x72, 0x74, 0x45, 0x6e, 0x72, 0x6f, 0x6c, 0x6c,
  106. 0x2f, 0x57, 0x48, 0x49, 0x43, 0x41, 0x33, 0x2e, 0x6e, 0x74, 0x64, 0x65, 0x76, 0x2e, 0x6d, 0x69,
  107. 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x5f, 0x4e, 0x54, 0x44, 0x45,
  108. 0x56, 0x25, 0x32, 0x30, 0x49, 0x53, 0x53, 0x55, 0x45, 0x33, 0x25, 0x32, 0x30, 0x43, 0x41, 0x28,
  109. 0x31, 0x29, 0x2e, 0x63, 0x72, 0x74, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x18, 0x30,
  110. 0x16, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x02, 0x06, 0x08, 0x2b,
  111. 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x37, 0x06, 0x03, 0x55, 0x1d, 0x11, 0x04, 0x30,
  112. 0x30, 0x2e, 0xa0, 0x2c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x03,
  113. 0xa0, 0x1e, 0x0c, 0x1c, 0x64, 0x61, 0x6e, 0x67, 0x72, 0x69, 0x66, 0x66, 0x40, 0x6e, 0x74, 0x64,
  114. 0x65, 0x76, 0x2e, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, 0x6d,
  115. 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x03,
  116. 0x81, 0x81, 0x00, 0x92, 0xe6, 0x34, 0x6a, 0x1b, 0x71, 0xe6, 0x91, 0x4a, 0x92, 0x35, 0x00, 0x2d,
  117. 0xe3, 0x20, 0x50, 0x68, 0x01, 0x7d, 0x92, 0xe7, 0xc1, 0x5c, 0xfd, 0x13, 0xb5, 0x49, 0x31, 0xc5,
  118. 0xc5, 0x0d, 0x5f, 0xa5, 0xf3, 0xa6, 0xd1, 0xb4, 0x28, 0x7b, 0x70, 0xfd, 0x16, 0xd2, 0x60, 0x3a,
  119. 0xa9, 0xa5, 0x39, 0x08, 0xed, 0x36, 0x76, 0xa5, 0x44, 0xf3, 0x45, 0x8e, 0x56, 0x63, 0xd6, 0xfe,
  120. 0x0e, 0xbd, 0x41, 0xf0, 0xdf, 0x2c, 0xa7, 0xdf, 0x03, 0xda, 0xf0, 0x35, 0x2f, 0x51, 0xab, 0xa3,
  121. 0x0d, 0x94, 0xb2, 0x89, 0x12, 0xe0, 0x30, 0x6f, 0xee, 0x1f, 0x09, 0x21, 0xe4, 0x3e, 0x51, 0x4f,
  122. 0xf0, 0x4a, 0xb3, 0x30, 0x87, 0xef, 0x7a, 0x49, 0x2f, 0x0e, 0x30, 0x4d, 0xd0, 0xd5, 0x4b, 0xfc,
  123. 0x77, 0xac, 0x81, 0xb8, 0xf1, 0x36, 0xfa, 0x9e, 0xbb, 0x35, 0x5b, 0xf7, 0x4a, 0x5f, 0x81, 0x16,
  124. 0x98, 0x27, 0xd7
  125. };
  126. #define cbTestCer sizeof(rgbTestCer)
  127. //
  128. // Function: AllocH
  129. //
  130. LPVOID WINAPI AllocH(
  131. IN SIZE_T cBytes)
  132. {
  133. return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cBytes);
  134. }
  135. //
  136. // Function: FreeH
  137. //
  138. void WINAPI FreeH(
  139. IN LPVOID pMem)
  140. {
  141. HeapFree(GetProcessHeap(), 0, pMem);
  142. }
  143. //
  144. // Function: PrintBytes
  145. //
  146. #define CROW 8
  147. void PrintBytes(LPSTR pszHdr, BYTE *pb, DWORD cbSize)
  148. {
  149. ULONG cb, i;
  150. CHAR rgsz[1024];
  151. printf("\n %s, %d bytes ::\n", pszHdr, cbSize);
  152. while (cbSize > 0)
  153. {
  154. // Start every row with an extra space
  155. printf(" ");
  156. cb = min(CROW, cbSize);
  157. cbSize -= cb;
  158. for (i = 0; i < cb; i++)
  159. printf(" %02x", pb[i]);
  160. for (i = cb; i < CROW; i++)
  161. printf(" ");
  162. printf(" '");
  163. for (i = 0; i < cb; i++)
  164. {
  165. if (pb[i] >= 0x20 && pb[i] <= 0x7f)
  166. printf("%c", pb[i]);
  167. else
  168. printf(".");
  169. }
  170. printf("\n");
  171. pb += cb;
  172. }
  173. }
  174. DWORD TestLogon(void)
  175. {
  176. HCRYPTPROV hProv = 0;
  177. HCRYPTKEY hKey = 0;
  178. HCRYPTHASH hHash = 0;
  179. HCRYPTKEY hHelperEncryptKey = 0;
  180. DWORD dwSts = ERROR_SUCCESS;
  181. DWORD cbCertificate = 0;
  182. PBYTE pbCertificate = NULL;
  183. DWORD cbSignature = 0;
  184. PBYTE pbSignature = NULL;
  185. HCRYPTPROV hHelperProv = 0;
  186. HCRYPTKEY hPublicKey = 0;
  187. DWORD cbPublicKey = 0;
  188. PBYTE pbPublicKey = NULL;
  189. HCRYPTHASH hHelperHash = 0;
  190. DWORD cbEncrypted = 0;
  191. PBYTE pbEncrypted = NULL;
  192. DWORD cb = 0;
  193. DWORD cbEncryptedKey = 0;
  194. PBYTE pbEncryptedKey = NULL;
  195. HCRYPTKEY hDecryptKey = 0;
  196. CAPI_TEST_CASE(CryptAcquireContext(
  197. &hProv,
  198. L"\\\\.\\Gemplus GemPC430 0\\" /*NULL*/,
  199. MS_SCARD_PROV,
  200. PROV_RSA_FULL,
  201. CRYPT_SILENT | CRYPT_MACHINE_KEYSET));
  202. CAPI_TEST_CASE(CryptGetUserKey(
  203. hProv, AT_KEYEXCHANGE, &hKey));
  204. //
  205. // Get the user logon certificate
  206. //
  207. CAPI_TEST_CASE(CryptGetKeyParam(
  208. hKey, KP_CERTIFICATE, NULL, &cbCertificate, 0));
  209. pbCertificate = AllocH(cbCertificate);
  210. if (NULL == pbCertificate)
  211. {
  212. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  213. goto Ret;
  214. }
  215. CAPI_TEST_CASE(CryptGetKeyParam(
  216. hKey, KP_CERTIFICATE, pbCertificate, &cbCertificate, 0));
  217. PrintBytes("KP_CERTIFICATE", pbCertificate, cbCertificate);
  218. //
  219. // Hash the certificate
  220. //
  221. CAPI_TEST_CASE(CryptCreateHash(
  222. hProv, CALG_MD5, 0, 0, &hHash));
  223. CAPI_TEST_CASE(CryptHashData(
  224. hHash, pbCertificate, cbCertificate, 0));
  225. CAPI_TEST_CASE(CryptSetProvParam(
  226. hProv, PP_SIGNATURE_PIN, (PBYTE) "0000", 0));
  227. //
  228. // Sign the hash
  229. //
  230. CAPI_TEST_CASE(CryptSignHash(
  231. hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &cbSignature))
  232. pbSignature = AllocH(cbSignature);
  233. if (NULL == pbSignature)
  234. {
  235. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  236. goto Ret;
  237. }
  238. CAPI_TEST_CASE(CryptSignHash(
  239. hHash, AT_KEYEXCHANGE, NULL, 0, pbSignature, &cbSignature));
  240. //
  241. // Export the public key
  242. //
  243. CAPI_TEST_CASE(CryptExportKey(
  244. hKey, 0, PUBLICKEYBLOB, 0, NULL, &cbPublicKey));
  245. pbPublicKey = AllocH(cbPublicKey);
  246. if (NULL == pbPublicKey)
  247. {
  248. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  249. goto Ret;
  250. }
  251. CAPI_TEST_CASE(CryptExportKey(
  252. hKey, 0, PUBLICKEYBLOB, 0, pbPublicKey, &cbPublicKey));
  253. //
  254. // Import the public key into the helper CSP
  255. //
  256. CAPI_TEST_CASE(CryptAcquireContext(
  257. &hHelperProv, NULL, MS_STRONG_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT));
  258. CAPI_TEST_CASE(CryptImportKey(
  259. hHelperProv, pbPublicKey, cbPublicKey, 0, 0, &hPublicKey));
  260. //
  261. // Now hash the cert with the helper CSP
  262. //
  263. CAPI_TEST_CASE(CryptCreateHash(
  264. hHelperProv, CALG_MD5, 0, 0, &hHelperHash));
  265. CAPI_TEST_CASE(CryptHashData(
  266. hHelperHash, pbCertificate, cbCertificate, 0));
  267. //
  268. // Verify the signature on our cert hash
  269. //
  270. CAPI_TEST_CASE(CryptVerifySignature(
  271. hHelperHash, pbSignature, cbSignature, hPublicKey, NULL, 0));
  272. //
  273. // Derive a session key from the hash
  274. //
  275. CAPI_TEST_CASE(CryptDeriveKey(
  276. hHelperProv,
  277. CALG_3DES,
  278. hHelperHash,
  279. CRYPT_EXPORTABLE,
  280. &hHelperEncryptKey));
  281. //
  282. // Encrypt the cert with the session key
  283. //
  284. cbEncrypted = cbCertificate;
  285. CAPI_TEST_CASE(CryptEncrypt(
  286. hHelperEncryptKey, 0, TRUE, 0, NULL, &cbEncrypted, 0));
  287. pbEncrypted = AllocH(cbEncrypted);
  288. if (NULL == pbEncrypted)
  289. {
  290. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  291. goto Ret;
  292. }
  293. memcpy(
  294. pbEncrypted,
  295. pbCertificate,
  296. cbCertificate);
  297. cb = cbCertificate;
  298. CAPI_TEST_CASE(CryptEncrypt(
  299. hHelperEncryptKey, 0, TRUE, 0, pbEncrypted, &cb, cbEncrypted));
  300. //
  301. // Export the encryption key, encrypted with the public key
  302. //
  303. CAPI_TEST_CASE(CryptExportKey(
  304. hHelperEncryptKey, hPublicKey, SIMPLEBLOB, 0, NULL, &cbEncryptedKey));
  305. pbEncryptedKey = AllocH(cbEncryptedKey);
  306. if (NULL == pbEncryptedKey)
  307. {
  308. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  309. goto Ret;
  310. }
  311. CAPI_TEST_CASE(CryptExportKey(
  312. hHelperEncryptKey,
  313. hPublicKey,
  314. SIMPLEBLOB,
  315. 0,
  316. pbEncryptedKey,
  317. &cbEncryptedKey));
  318. //
  319. // Import the encrypted session key into the smartcard CSP, decrypting it
  320. // with the private key
  321. //
  322. CAPI_TEST_CASE(CryptImportKey(
  323. hProv, pbEncryptedKey, cbEncryptedKey, hKey, 0, &hDecryptKey));
  324. //
  325. // Decrypt the encrypted certificate using the session key
  326. //
  327. CAPI_TEST_CASE(CryptDecrypt(
  328. hDecryptKey, 0, TRUE, 0, pbEncrypted, &cbEncrypted));
  329. //
  330. // Compare the decrypted certificate with the original
  331. //
  332. if (cbCertificate != cbEncrypted ||
  333. 0 != memcmp(pbEncrypted, pbCertificate, cbCertificate))
  334. {
  335. printf("ERROR: Decrypted cert doesn't match\n");
  336. dwSts = -1;
  337. }
  338. Ret:
  339. if (pbEncrypted)
  340. FreeH(pbEncrypted);
  341. if (pbCertificate)
  342. FreeH(pbCertificate);
  343. if (pbEncryptedKey)
  344. FreeH(pbEncryptedKey);
  345. if (pbSignature)
  346. FreeH(pbSignature);
  347. if (pbPublicKey)
  348. FreeH(pbPublicKey);
  349. if (hDecryptKey)
  350. CryptDestroyKey(hDecryptKey);
  351. if (hKey)
  352. CryptDestroyKey(hKey);
  353. if (hPublicKey)
  354. CryptDestroyKey(hPublicKey);
  355. if (hHelperEncryptKey)
  356. CryptDestroyKey(hHelperEncryptKey);
  357. if (hHash)
  358. CryptDestroyHash(hHash);
  359. if (hHelperHash)
  360. CryptDestroyHash(hHelperHash);
  361. if (hProv)
  362. CryptReleaseContext(hProv, 0);
  363. if (hHelperProv)
  364. CryptReleaseContext(hHelperProv, 0);
  365. return dwSts;
  366. }
  367. DWORD CheckCertUsageForDefaultContainer(
  368. PBYTE pbEncodedCert,
  369. DWORD cbEncodedCert,
  370. BOOL *pfMakeDefault)
  371. {
  372. DWORD dwSts = 0;
  373. PCCERT_CONTEXT pCertCtx = NULL;
  374. PCERT_ENHKEY_USAGE pUsage = NULL;
  375. DWORD cbUsage = 0;
  376. *pfMakeDefault = FALSE;
  377. pCertCtx = CertCreateCertificateContext(
  378. X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
  379. pbEncodedCert,
  380. cbEncodedCert);
  381. if (NULL == pCertCtx)
  382. {
  383. dwSts = GetLastError();
  384. goto Ret;
  385. }
  386. if (! CertGetEnhancedKeyUsage(
  387. pCertCtx,
  388. 0,
  389. NULL,
  390. &cbUsage))
  391. {
  392. dwSts = GetLastError();
  393. goto Ret;
  394. }
  395. pUsage = (PCERT_ENHKEY_USAGE) AllocH(cbUsage);
  396. if (NULL == pUsage)
  397. {
  398. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  399. goto Ret;
  400. }
  401. if (! CertGetEnhancedKeyUsage(
  402. pCertCtx,
  403. 0,
  404. pUsage,
  405. &cbUsage))
  406. {
  407. dwSts = GetLastError();
  408. goto Ret;
  409. }
  410. while (pUsage->cUsageIdentifier)
  411. {
  412. pUsage->cUsageIdentifier -= 1;
  413. if (0 == strcmp(
  414. szOID_KP_SMARTCARD_LOGON,
  415. pUsage->rgpszUsageIdentifier[pUsage->cUsageIdentifier]) ||
  416. 0 == strcmp(
  417. szOID_ENROLLMENT_AGENT,
  418. pUsage->rgpszUsageIdentifier[pUsage->cUsageIdentifier]))
  419. {
  420. *pfMakeDefault = TRUE;
  421. }
  422. }
  423. Ret:
  424. if (pUsage)
  425. FreeH(pUsage);
  426. if (pCertCtx)
  427. CertFreeCertificateContext(pCertCtx);
  428. return dwSts;
  429. }
  430. DWORD TestEnrollment(void)
  431. {
  432. HCRYPTPROV hProv = 0;
  433. DWORD dwSts = 0;
  434. DWORD dwData = 0;
  435. DWORD cbData = 0;
  436. PROV_ENUMALGS_EX EnumalgsEx;
  437. DWORD dwFlags = 0;
  438. HCRYPTKEY hKey = 0;
  439. PBYTE pbData = NULL;
  440. LPSTR szContainer = NULL;
  441. LPSTR szName = NULL;
  442. HCRYPTHASH hHash = 0;
  443. BOOL fDefault = FALSE;
  444. memset(&EnumalgsEx, 0, sizeof(EnumalgsEx));
  445. CAPI_TEST_CASE(CryptAcquireContext(
  446. &hProv, NULL, MS_SCARD_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT));
  447. // Used only for enrollment station - filtering for smartcard CSP's
  448. cbData = sizeof(DWORD);
  449. CAPI_TEST_CASE(CryptGetProvParam(
  450. hProv, PP_IMPTYPE, (PBYTE) &dwData, &cbData, 0));
  451. printf(" ImpType: %d\n", dwData);
  452. cbData = sizeof(DWORD);
  453. CAPI_TEST_CASE(CryptGetProvParam(
  454. hProv, PP_KEYSPEC, (PBYTE) &dwData, &cbData, 0));
  455. printf(" Keyspec: %d\n", dwData);
  456. cbData = sizeof(DWORD);
  457. CAPI_TEST_CASE(CryptGetProvParam(
  458. hProv, PP_PROVTYPE, (PBYTE) &dwData, &cbData, 0));
  459. printf(" Provtype: %d\n", dwData);
  460. cbData = 0;
  461. CAPI_TEST_CASE(CryptGetProvParam(
  462. hProv, PP_NAME, NULL, &cbData, 0));
  463. szName = (LPSTR) AllocH(cbData);
  464. if (NULL == szName)
  465. {
  466. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  467. goto Ret;
  468. }
  469. CAPI_TEST_CASE(CryptGetProvParam(
  470. hProv, PP_NAME, (PBYTE) szName, &cbData, 0));
  471. printf(" Prov name: %s\n", szName);
  472. dwFlags = CRYPT_FIRST;
  473. cbData = sizeof(EnumalgsEx);
  474. while (CryptGetProvParam(
  475. hProv, PP_ENUMALGS_EX, (PBYTE) &EnumalgsEx, &cbData, dwFlags))
  476. {
  477. printf(" %s\n", EnumalgsEx.szName);
  478. dwFlags = 0;
  479. }
  480. if (ERROR_NO_MORE_ITEMS != (dwSts = GetLastError()))
  481. {
  482. if (ERROR_SUCCESS == dwSts)
  483. dwSts = -1;
  484. goto Ret;
  485. }
  486. dwSts = ERROR_SUCCESS;
  487. CAPI_TEST_CASE(CryptReleaseContext(hProv, 0));
  488. hProv = 0;
  489. CAPI_TEST_CASE(CryptAcquireContext(
  490. &hProv, NULL, MS_SCARD_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET));
  491. CAPI_TEST_CASE(CryptGetProvParam(
  492. hProv, PP_CONTAINER, NULL, &cbData, 0));
  493. szContainer = (LPSTR) AllocH(cbData);
  494. if (NULL == szContainer)
  495. {
  496. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  497. goto Ret;
  498. }
  499. CAPI_TEST_CASE(CryptGetProvParam(
  500. hProv, PP_CONTAINER, (PBYTE) szContainer, &cbData, 0));
  501. printf(" Container name: %s\n", szContainer);
  502. FreeH(szContainer);
  503. szContainer = NULL;
  504. CAPI_TEST_CASE(CryptGetProvParam(
  505. hProv, PP_UNIQUE_CONTAINER, NULL, &cbData, 0));
  506. szContainer = (LPSTR) AllocH(cbData);
  507. if (NULL == szContainer)
  508. {
  509. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  510. goto Ret;
  511. }
  512. CAPI_TEST_CASE(CryptGetProvParam(
  513. hProv, PP_UNIQUE_CONTAINER, (PBYTE) szContainer, &cbData, 0));
  514. printf(" Unique container: %s\n", szContainer);
  515. // Eliminate the SetProv step to force the CSP to show pin UI
  516. /*
  517. CAPI_TEST_CASE(CryptSetProvParam(
  518. hProv, PP_SIGNATURE_PIN, (PBYTE) "0000", 0));
  519. */
  520. CAPI_TEST_CASE(CryptGenKey(
  521. hProv, AT_KEYEXCHANGE, 0, &hKey));
  522. //
  523. // Test creating and signing a hash
  524. //
  525. CAPI_TEST_CASE(CryptCreateHash(
  526. hProv, CALG_SHA, 0, 0, &hHash));
  527. CAPI_TEST_CASE(CryptSignHash(
  528. hHash, AT_KEYEXCHANGE, NULL, 0, NULL, &cbData));
  529. pbData = AllocH(cbData);
  530. if (NULL == pbData)
  531. {
  532. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  533. goto Ret;
  534. }
  535. CAPI_TEST_CASE(CryptSignHash(
  536. hHash, AT_KEYEXCHANGE, NULL, 0, pbData, &cbData));
  537. PrintBytes("Signature blob", pbData, cbData);
  538. CAPI_TEST_CASE(CryptVerifySignature(
  539. hHash, pbData, cbData, hKey, NULL, 0));
  540. CAPI_TEST_CASE(CryptDestroyHash(hHash));
  541. hHash = 0;
  542. FreeH(pbData);
  543. pbData = NULL;
  544. //
  545. // Test writing a reading a user certificate
  546. //
  547. dwSts = CheckCertUsageForDefaultContainer(
  548. rgbTestCer,
  549. sizeof(rgbTestCer),
  550. &fDefault);
  551. if (ERROR_SUCCESS != dwSts)
  552. goto Ret;
  553. CAPI_TEST_CASE(CryptSetKeyParam(
  554. hKey, KP_CERTIFICATE, rgbTestCer, 0));
  555. CAPI_TEST_CASE(CryptGetKeyParam(
  556. hKey, KP_CERTIFICATE, NULL, &cbData, 0));
  557. pbData = AllocH(cbData);
  558. if (NULL == pbData)
  559. {
  560. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  561. goto Ret;
  562. }
  563. CAPI_TEST_CASE(CryptGetKeyParam(
  564. hKey, KP_CERTIFICATE, pbData, &cbData, 0));
  565. PrintBytes("KP_CERTIFICATE", pbData, cbData);
  566. FreeH(pbData);
  567. pbData = NULL;
  568. CAPI_TEST_CASE(CryptDestroyKey(hKey));
  569. hKey = 0;
  570. //
  571. // Test exporting a public key
  572. //
  573. CAPI_TEST_CASE(CryptGetUserKey(
  574. hProv, AT_KEYEXCHANGE, &hKey));
  575. CAPI_TEST_CASE(CryptExportKey(
  576. hKey, 0, PUBLICKEYBLOB, 0, NULL, &cbData));
  577. pbData = AllocH(cbData);
  578. if (NULL == pbData)
  579. {
  580. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  581. goto Ret;
  582. }
  583. CAPI_TEST_CASE(CryptExportKey(
  584. hKey, 0, PUBLICKEYBLOB, 0, pbData, &cbData));
  585. PrintBytes("PUBLICKEYBLOB", pbData, cbData);
  586. FreeH(pbData);
  587. pbData = NULL;
  588. CAPI_TEST_CASE(CryptDestroyKey(hKey));
  589. hKey = 0;
  590. Ret:
  591. if (hHash)
  592. CryptDestroyHash(hHash);
  593. if (hKey)
  594. CryptDestroyKey(hKey);
  595. if (hProv)
  596. CryptReleaseContext(hProv, 0);
  597. if (pbData)
  598. FreeH(pbData);
  599. if (szName)
  600. FreeH(szName);
  601. return dwSts;
  602. }
  603. DWORD TestCertPropagation(void)
  604. {
  605. DWORD dwSts = ERROR_SUCCESS;
  606. HCRYPTPROV hProv = 0;
  607. HCRYPTKEY hKey = 0;
  608. PBYTE pbCert = NULL;
  609. DWORD cbCert = 0;
  610. CAPI_TEST_CASE(CryptAcquireContext(
  611. &hProv,
  612. /*L"\\\\.\\GemPlus SCR 500\\My Big - long container"*/ NULL,
  613. MS_SCARD_PROV,
  614. PROV_RSA_FULL,
  615. 0));
  616. CAPI_TEST_CASE(CryptGetUserKey(
  617. hProv, AT_KEYEXCHANGE, &hKey));
  618. CAPI_TEST_CASE(CryptGetKeyParam(
  619. hKey, KP_CERTIFICATE, NULL, &cbCert, 0));
  620. pbCert = AllocH(cbCert);
  621. if (NULL == pbCert)
  622. {
  623. dwSts = ERROR_NOT_ENOUGH_MEMORY;
  624. goto Ret;
  625. }
  626. CAPI_TEST_CASE(CryptGetKeyParam(
  627. hKey, KP_CERTIFICATE, pbCert, &cbCert, 0));
  628. PrintBytes("User Cert", pbCert, cbCert);
  629. Ret:
  630. if (pbCert)
  631. FreeH(pbCert);
  632. return dwSts;
  633. }
  634. DWORD Cleanup(void)
  635. {
  636. DWORD dwSts = ERROR_SUCCESS;
  637. HCRYPTPROV hProv = 0;
  638. CHAR rgszContainer [MAX_PATH];
  639. DWORD cbContainer = sizeof(rgszContainer);
  640. CAPI_TEST_CASE(CryptAcquireContext(
  641. &hProv, NULL, MS_SCARD_PROV, PROV_RSA_FULL, 0));
  642. CAPI_TEST_CASE(CryptGetProvParam(
  643. hProv, PP_CONTAINER, (PBYTE) rgszContainer, &cbContainer, 0));
  644. CAPI_TEST_CASE(CryptReleaseContext(hProv, 0));
  645. printf("Deleting default container ...\n");
  646. CAPI_TEST_CASE(CryptAcquireContextA(
  647. &hProv, rgszContainer, MS_SCARD_PROV_A, PROV_RSA_FULL, CRYPT_DELETEKEYSET));
  648. Ret:
  649. return dwSts;
  650. }
  651. void DisplayHelp(void)
  652. {
  653. printf("Usage: scnarios [option]\n");
  654. printf(" -1 : Test simulated enrollment\n");
  655. printf(" -2 : Test simulated certificate propagation\n");
  656. printf(" -3 : Test simulated logon\n");
  657. printf(" -c : Cleanup (delete default container)\n");
  658. }
  659. int _cdecl main(int argc, char * argv[])
  660. {
  661. DWORD dwSts = ERROR_SUCCESS;
  662. BOOL fDisplayHelp = FALSE;
  663. while (--argc>0)
  664. {
  665. if (**++argv == '-')
  666. {
  667. switch(argv[0][1])
  668. {
  669. case '1':
  670. dwSts = TestEnrollment();
  671. if (ERROR_SUCCESS != dwSts)
  672. goto Ret;
  673. break;
  674. case '2':
  675. dwSts = TestCertPropagation();
  676. if (ERROR_SUCCESS != dwSts)
  677. goto Ret;
  678. break;
  679. case '3':
  680. dwSts = TestLogon();
  681. if (ERROR_SUCCESS != dwSts)
  682. goto Ret;
  683. break;
  684. case 'c':
  685. dwSts = Cleanup();
  686. if (ERROR_SUCCESS != dwSts)
  687. goto Ret;
  688. break;
  689. case '?':
  690. fDisplayHelp = TRUE;
  691. break;
  692. default:
  693. printf("Invalid args\n");
  694. fDisplayHelp = TRUE;
  695. goto Ret;
  696. }
  697. }
  698. }
  699. Ret:
  700. if (TRUE == fDisplayHelp)
  701. {
  702. DisplayHelp();
  703. }
  704. else
  705. {
  706. if (ERROR_SUCCESS != dwSts)
  707. printf(" failed, 0x%x\n", dwSts);
  708. else
  709. printf("Success.\n");
  710. }
  711. return 0;
  712. }