mscode_parser.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* Parse a Microsoft Individual Code Signing blob
  3. *
  4. * Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.
  5. * Written by David Howells ([email protected])
  6. */
  7. #define pr_fmt(fmt) "MSCODE: "fmt
  8. #include <linux/kernel.h>
  9. #include <linux/slab.h>
  10. #include <linux/err.h>
  11. #include <linux/oid_registry.h>
  12. #include <crypto/pkcs7.h>
  13. #include "verify_pefile.h"
  14. #include "mscode.asn1.h"
  15. /*
  16. * Parse a Microsoft Individual Code Signing blob
  17. */
  18. int mscode_parse(void *_ctx, const void *content_data, size_t data_len,
  19. size_t asn1hdrlen)
  20. {
  21. struct pefile_context *ctx = _ctx;
  22. content_data -= asn1hdrlen;
  23. data_len += asn1hdrlen;
  24. pr_devel("Data: %zu [%*ph]\n", data_len, (unsigned)(data_len),
  25. content_data);
  26. return asn1_ber_decoder(&mscode_decoder, ctx, content_data, data_len);
  27. }
  28. /*
  29. * Check the content type OID
  30. */
  31. int mscode_note_content_type(void *context, size_t hdrlen,
  32. unsigned char tag,
  33. const void *value, size_t vlen)
  34. {
  35. enum OID oid;
  36. oid = look_up_OID(value, vlen);
  37. if (oid == OID__NR) {
  38. char buffer[50];
  39. sprint_oid(value, vlen, buffer, sizeof(buffer));
  40. pr_err("Unknown OID: %s\n", buffer);
  41. return -EBADMSG;
  42. }
  43. /*
  44. * pesign utility had a bug where it was putting
  45. * OID_msIndividualSPKeyPurpose instead of OID_msPeImageDataObjId
  46. * So allow both OIDs.
  47. */
  48. if (oid != OID_msPeImageDataObjId &&
  49. oid != OID_msIndividualSPKeyPurpose) {
  50. pr_err("Unexpected content type OID %u\n", oid);
  51. return -EBADMSG;
  52. }
  53. return 0;
  54. }
  55. /*
  56. * Note the digest algorithm OID
  57. */
  58. int mscode_note_digest_algo(void *context, size_t hdrlen,
  59. unsigned char tag,
  60. const void *value, size_t vlen)
  61. {
  62. struct pefile_context *ctx = context;
  63. char buffer[50];
  64. enum OID oid;
  65. oid = look_up_OID(value, vlen);
  66. switch (oid) {
  67. case OID_md4:
  68. ctx->digest_algo = "md4";
  69. break;
  70. case OID_md5:
  71. ctx->digest_algo = "md5";
  72. break;
  73. case OID_sha1:
  74. ctx->digest_algo = "sha1";
  75. break;
  76. case OID_sha256:
  77. ctx->digest_algo = "sha256";
  78. break;
  79. case OID_sha384:
  80. ctx->digest_algo = "sha384";
  81. break;
  82. case OID_sha512:
  83. ctx->digest_algo = "sha512";
  84. break;
  85. case OID_sha224:
  86. ctx->digest_algo = "sha224";
  87. break;
  88. case OID__NR:
  89. sprint_oid(value, vlen, buffer, sizeof(buffer));
  90. pr_err("Unknown OID: %s\n", buffer);
  91. return -EBADMSG;
  92. default:
  93. pr_err("Unsupported content type: %u\n", oid);
  94. return -ENOPKG;
  95. }
  96. return 0;
  97. }
  98. /*
  99. * Note the digest we're guaranteeing with this certificate
  100. */
  101. int mscode_note_digest(void *context, size_t hdrlen,
  102. unsigned char tag,
  103. const void *value, size_t vlen)
  104. {
  105. struct pefile_context *ctx = context;
  106. ctx->digest = kmemdup(value, vlen, GFP_KERNEL);
  107. if (!ctx->digest)
  108. return -ENOMEM;
  109. ctx->digest_len = vlen;
  110. return 0;
  111. }