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.

114 lines
3.4 KiB

  1. //+-------------------------------------------------------------------------
  2. // File: licexample.cpp
  3. //
  4. // Contents: An example calling the minasn1 and mincrypt APIs to parse
  5. // the certificates in a PKCS #7 Signed Data, find a certificate
  6. // having the license extension and validate this certificate
  7. // up to a baked in and trusted root. Returns a pointer
  8. // to the license data within the verified certificate.
  9. //--------------------------------------------------------------------------
  10. #include <windows.h>
  11. #include "minasn1.h"
  12. #include "mincrypt.h"
  13. #define MAX_LICENSE_CERT_CNT 20
  14. #define MAX_LICENSE_EXT_CNT 20
  15. // #define szOID_ESL_LICENSE_EXT "1.3.6.1.4.1.311.41.3"
  16. const BYTE rgbOID_ESL_LICENSE_EXT[] =
  17. {0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x29, 0x03};
  18. const CRYPT_DER_BLOB ESL_LICENSE_EXTEncodedOIDBlob = {
  19. sizeof(rgbOID_ESL_LICENSE_EXT),
  20. (BYTE *) rgbOID_ESL_LICENSE_EXT
  21. };
  22. // Returns ERROR_SUCCESS if able to find and successfully verify the
  23. // certificate containing the license data. Returns pointer to the
  24. // license data bytes in the encoded data.
  25. LONG
  26. GetAndVerifyLicenseDataFromPKCS7SignedData(
  27. IN const BYTE *pbEncoded,
  28. IN DWORD cbEncoded,
  29. OUT const BYTE **ppbLicenseData,
  30. OUT DWORD *pcbLicenseData
  31. )
  32. {
  33. LONG lErr;
  34. const BYTE *pbLicenseData;
  35. DWORD cbLicenseData;
  36. DWORD cCert;
  37. CRYPT_DER_BLOB rgrgCertBlob[MAX_LICENSE_CERT_CNT][MINASN1_CERT_BLOB_CNT];
  38. PCRYPT_DER_BLOB rgLicenseCertBlob;
  39. DWORD iCert;
  40. // Parse the PKCS #7 to get the bag of certs.
  41. cCert = MAX_LICENSE_CERT_CNT;
  42. if (0 >= MinAsn1ExtractParsedCertificatesFromSignedData(
  43. pbEncoded,
  44. cbEncoded,
  45. &cCert,
  46. rgrgCertBlob
  47. ))
  48. goto ParseError;
  49. // Loop through the certs. Parse the cert's extensions. Attempt to
  50. // find the license extension.
  51. rgLicenseCertBlob = NULL;
  52. for (iCert = 0; iCert < cCert; iCert++) {
  53. DWORD cExt;
  54. CRYPT_DER_BLOB rgrgExtBlob[MAX_LICENSE_EXT_CNT][MINASN1_EXT_BLOB_CNT];
  55. PCRYPT_DER_BLOB rgLicenseExtBlob;
  56. cExt = MAX_LICENSE_EXT_CNT;
  57. if (0 >= MinAsn1ParseExtensions(
  58. &rgrgCertBlob[iCert][MINASN1_CERT_EXTS_IDX],
  59. &cExt,
  60. rgrgExtBlob
  61. ))
  62. continue;
  63. rgLicenseExtBlob = MinAsn1FindExtension(
  64. (PCRYPT_DER_BLOB) &ESL_LICENSE_EXTEncodedOIDBlob,
  65. cExt,
  66. rgrgExtBlob
  67. );
  68. if (NULL != rgLicenseExtBlob) {
  69. pbLicenseData = rgLicenseExtBlob[MINASN1_EXT_VALUE_IDX].pbData;
  70. cbLicenseData = rgLicenseExtBlob[MINASN1_EXT_VALUE_IDX].cbData;
  71. rgLicenseCertBlob = rgrgCertBlob[iCert];
  72. break;
  73. }
  74. }
  75. if (NULL == rgLicenseCertBlob)
  76. goto NoLicenseCert;
  77. // Verify the License certificate chain to a baked in trusted root.
  78. lErr = MinCryptVerifyCertificate(
  79. rgLicenseCertBlob,
  80. cCert,
  81. rgrgCertBlob
  82. );
  83. CommonReturn:
  84. *ppbLicenseData = pbLicenseData;
  85. *pcbLicenseData = cbLicenseData;
  86. return lErr;
  87. ErrorReturn:
  88. pbLicenseData = NULL;
  89. cbLicenseData = 0;
  90. goto CommonReturn;
  91. ParseError:
  92. lErr = CRYPT_E_BAD_MSG;
  93. goto ErrorReturn;
  94. NoLicenseCert:
  95. lErr = ERROR_NOT_FOUND;
  96. goto ErrorReturn;
  97. }