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.

375 lines
13 KiB

  1. #include "nt.h"
  2. #include "ntdef.h"
  3. #include "ntrtl.h"
  4. #include "nturtl.h"
  5. #include "sxs-rtl.h"
  6. #include "skiplist.h"
  7. #include "fasterxml.h"
  8. #include "namespacemanager.h"
  9. #include "xmlstructure.h"
  10. #include "manifestinspection.h"
  11. #include "analyzerxmldsig.h"
  12. //
  13. // This is all the stuff required to do XMLDSIG for us
  14. //
  15. DECLARE_ELEMENT(Signature);
  16. DECLARE_ELEMENT(Signature_SignatureValue);
  17. DECLARE_ELEMENT(Signature_SignedInfo);
  18. DECLARE_ELEMENT(Signature_KeyInfo);
  19. DECLARE_ELEMENT(Signature_KeyInfo_KeyName);
  20. DECLARE_ELEMENT(Signature_KeyInfo_KeyValue);
  21. DECLARE_ELEMENT(Signature_KeyInfo_KeyValue_DSAKeyValue);
  22. DECLARE_ELEMENT(Signature_KeyInfo_KeyValue_RSAKeyValue);
  23. //DECLARE_ELEMENT(Signature_Object);
  24. DECLARE_ELEMENT(Signature_SignedInfo_CanonicalizationMethod);
  25. DECLARE_ELEMENT(Signature_SignedInfo_SignatureMethod);
  26. DECLARE_ELEMENT(Signature_SignedInfo_Reference);
  27. DECLARE_ELEMENT(Signature_SignedInfo_Reference_Transforms);
  28. DECLARE_ELEMENT(Signature_SignedInfo_Reference_DigestMethod);
  29. DECLARE_ELEMENT(Signature_SignedInfo_Reference_DigestValue);
  30. const XML_SPECIAL_STRING sc_ss_xmldsignamespace = MAKE_SPECIAL_STRING("http://www.w3.org/2000/09/xmldsig#");
  31. XML_ELEMENT_DEFINITION rgs_Element_Signature =
  32. {
  33. XML_ELEMENT_FLAG_ALLOW_ANY_CHILDREN,
  34. eManifestState_Signature,
  35. NULL,
  36. &sc_ss_xmldsignamespace,
  37. MAKE_SPECIAL_STRING("Signature"),
  38. &Rtl_InspectManifest_Signature,
  39. rgs_Element_Signature_Children,
  40. 0,
  41. { 0 }
  42. };
  43. PCXML_ELEMENT_DEFINITION rgs_Element_Signature_Children[] = {
  44. ELEMENT_NAMED(Signature_SignatureValue),
  45. ELEMENT_NAMED(Signature_SignedInfo),
  46. ELEMENT_NAMED(Signature_KeyInfo),
  47. // ELEMENT_NAMED(Signature_Object),
  48. };
  49. /*
  50. Signature::
  51. <!ELEMENT SignatureValue (#PCDATA) >
  52. <!ATTLIST SignatureValue
  53. Id ID #IMPLIED>
  54. */
  55. enum {
  56. eAttribs_Signature_SignatureValue_Id = 0,
  57. eAttribs_Signature_SignatureValue_Count
  58. };
  59. ELEMENT_DEFINITION_NS(Signature, SignatureValue, sc_ss_xmldsignamespace, Rtl_InspectManifest_Signature, XML_ELEMENT_FLAG_ALLOW_ANY_CHILDREN | XML_ELEMENT_FLAG_ALLOW_ANY_ATTRIBUTES)
  60. ATTRIBUTE_DEFINITION_NONS_NODEFAULT_OPTIONAL(Id),
  61. ELEMENT_DEFINITION_DEFNS_END();
  62. ELEMENT_DEFINITION_CHILD_ELEMENTS(Signature, SignatureValue)
  63. ELEMENT_DEFINITION_CHILD_ELEMENTS_END();
  64. /*
  65. <!ELEMENT SignedInfo (CanonicalizationMethod, SignatureMethod, Reference+) >
  66. <!ATTLIST SignedInfo Id ID #IMPLIED>
  67. */
  68. enum {
  69. eAttribs_Signature_SignedInfo_Id = 0,
  70. eAttribs_Signature_SignedInfo_Count
  71. };
  72. ELEMENT_DEFINITION_NS(Signature, SignedInfo, sc_ss_xmldsignamespace, Rtl_InspectManifest_Signature, XML_ELEMENT_FLAG_ALLOW_ANY_CHILDREN)
  73. ATTRIBUTE_DEFINITION_NONS_NODEFAULT_OPTIONAL(Id),
  74. ELEMENT_DEFINITION_DEFNS_END();
  75. ELEMENT_DEFINITION_CHILD_ELEMENTS(Signature, SignedInfo)
  76. ELEMENT_NAMED(Signature_SignedInfo_CanonicalizationMethod),
  77. ELEMENT_NAMED(Signature_SignedInfo_SignatureMethod),
  78. ELEMENT_NAMED(Signature_SignedInfo_Reference),
  79. ELEMENT_DEFINITION_CHILD_ELEMENTS_END();
  80. /*
  81. Signature::SignedInfo
  82. <!ELEMENT CanonicalizationMethod (#PCDATA %Method.ANY;)* >
  83. <!ATTLIST CanonicalizationMethod
  84. Algorithm CDATA #REQUIRED >
  85. */
  86. enum {
  87. eAttribs_Signature_SignedInfo_CanonicalizationMethod_Algorithm = 0,
  88. eAttribs_Signature_SignedInfo_CanonicalizationMethod_Count
  89. };
  90. ELEMENT_DEFINITION_NS(Signature_SignedInfo, CanonicalizationMethod, sc_ss_xmldsignamespace, Rtl_InspectManifest_Signature, XML_ELEMENT_FLAG_NO_ELEMENTS)
  91. ATTRIBUTE_DEFINITION_NONS_NODEFAULT(Algorithm),
  92. ELEMENT_DEFINITION_DEFNS_END();
  93. ELEMENT_DEFINITION_CHILD_ELEMENTS(Signature_SignedInfo, CanonicalizationMethod)
  94. ELEMENT_DEFINITION_CHILD_ELEMENTS_END();
  95. /*
  96. Signature::SignedInfo
  97. <!ELEMENT SignatureMethod (#PCDATA|HMACOutputLength %Method.ANY;)* >
  98. <!ATTLIST SignatureMethod
  99. Algorithm CDATA #REQUIRED >
  100. */
  101. enum {
  102. eAttribs_Signature_SignedInfo_SignatureMethod_Algorithm = 0,
  103. eAttribs_Signature_SignedInfo_SignatureMethod_Count
  104. };
  105. ELEMENT_DEFINITION_NS(Signature_SignedInfo, SignatureMethod, sc_ss_xmldsignamespace, Rtl_InspectManifest_Signature, XML_ELEMENT_FLAG_ALLOW_ANY_CHILDREN)
  106. ATTRIBUTE_DEFINITION_NONS_NODEFAULT(Algorithm),
  107. ELEMENT_DEFINITION_DEFNS_END();
  108. ELEMENT_DEFINITION_CHILD_ELEMENTS(Signature_SignedInfo, SignatureMethod)
  109. ELEMENT_DEFINITION_CHILD_ELEMENTS_END();
  110. /*
  111. Signature::SignedInfo
  112. <!ELEMENT Reference (Transforms?, DigestMethod, DigestValue) >
  113. <!ATTLIST Reference
  114. Id ID #IMPLIED
  115. URI CDATA #IMPLIED
  116. Type CDATA #IMPLIED>
  117. */
  118. enum {
  119. eAttribs_Signature_SignedInfo_Reference_Id = 0,
  120. eAttribs_Signature_SignedInfo_Reference_Type,
  121. eAttribs_Signature_SignedInfo_Reference_URI,
  122. eAttribs_Signature_SignedInfo_Reference_Count
  123. };
  124. ELEMENT_DEFINITION_NS(Signature_SignedInfo, Reference, sc_ss_xmldsignamespace, Rtl_InspectManifest_Signature, 0)
  125. ATTRIBUTE_DEFINITION_NONS_NODEFAULT_OPTIONAL(Id),
  126. ATTRIBUTE_DEFINITION_NONS_NODEFAULT_OPTIONAL(Type),
  127. ATTRIBUTE_DEFINITION_NONS_NODEFAULT_OPTIONAL(URI),
  128. ELEMENT_DEFINITION_DEFNS_END();
  129. ELEMENT_DEFINITION_CHILD_ELEMENTS(Signature_SignedInfo, Reference)
  130. // ELEMENT_NAMED(Signature_SignedInfo_Reference_Transforms),
  131. ELEMENT_NAMED(Signature_SignedInfo_Reference_DigestMethod),
  132. ELEMENT_NAMED(Signature_SignedInfo_Reference_DigestValue),
  133. ELEMENT_DEFINITION_CHILD_ELEMENTS_END();
  134. /*
  135. Signature::SignedInfo::Reference
  136. <!ELEMENT DigestMethod (#PCDATA %Method.ANY;)* >
  137. <!ATTLIST DigestMethod
  138. Algorithm CDATA #REQUIRED >
  139. */
  140. enum {
  141. eAttribs_Signature_SignedInfo_Reference_DigestMethod_Algorithm = 0,
  142. eAttribs_Signature_SignedInfo_Reference_DigestMethod_Count
  143. };
  144. ELEMENT_DEFINITION_NS(Signature_SignedInfo_Reference, DigestMethod, sc_ss_xmldsignamespace, Rtl_InspectManifest_Signature, 0)
  145. ATTRIBUTE_DEFINITION_NONS_NODEFAULT(Algorithm)
  146. ELEMENT_DEFINITION_DEFNS_END();
  147. ELEMENT_DEFINITION_CHILD_ELEMENTS(Signature_SignedInfo_Reference, DigestMethod)
  148. ELEMENT_DEFINITION_CHILD_ELEMENTS_END();
  149. /*
  150. Signature::SignedInfo::Reference
  151. <!ELEMENT DigestValue (#PCDATA) >
  152. */
  153. enum {
  154. eAttribs_Signature_SignedInfo_Reference_DigestValue_Count = 0
  155. };
  156. ELEMENT_DEFINITION_NS(Signature_SignedInfo_Reference, DigestValue, sc_ss_xmldsignamespace, Rtl_InspectManifest_Signature, 0)
  157. ATTRIBUTE_DEFINITION_NONS_NODEFAULT(unused)
  158. ELEMENT_DEFINITION_DEFNS_END();
  159. ELEMENT_DEFINITION_CHILD_ELEMENTS(Signature_SignedInfo_Reference, DigestValue)
  160. ELEMENT_DEFINITION_CHILD_ELEMENTS_END();
  161. /*
  162. Signature::
  163. <!ELEMENT KeyInfo (#PCDATA|KeyName|KeyValue|RetrievalMethod|
  164. X509Data|PGPData|SPKIData|MgmtData %KeyInfo.ANY;)* >
  165. <!ATTLIST KeyInfo
  166. Id ID #IMPLIED >
  167. */
  168. enum {
  169. eAttribs_Signature_KeyInfo_Id = 0,
  170. eAttribs_Signature_KeyInfo_Count
  171. };
  172. ELEMENT_DEFINITION_NS(Signature, KeyInfo, sc_ss_xmldsignamespace, Rtl_InspectManifest_Signature, 0)
  173. ATTRIBUTE_DEFINITION_NONS_NODEFAULT_OPTIONAL(Id),
  174. ELEMENT_DEFINITION_DEFNS_END();
  175. // For now we only support keyname and keyvalue
  176. ELEMENT_DEFINITION_CHILD_ELEMENTS(Signature, KeyInfo)
  177. ELEMENT_NAMED(Signature_KeyInfo_KeyName),
  178. // ELEMENT_NAMED(Signature_KeyInfo_KeyValue),
  179. // ELEMENT_NAMED(Signature_KeyInfo_RetrievalMethod),
  180. // ELEMENT_NAMED(Signature_KeyInfo_X509Data),
  181. // ELEMENT_NAMED(Signature_KeyInfo_PGPData),
  182. // ELEMENT_NAMED(Signature_KeyInfo_SPKIData),
  183. // ELEMENT_NAMED(Signature_KeyInfo_MgmtData)
  184. ELEMENT_DEFINITION_CHILD_ELEMENTS_END();
  185. /*
  186. Signature::KeyInfo
  187. <!ELEMENT KeyName (#PCDATA) >
  188. */
  189. enum {
  190. eAttribs_Signature_KeyInfo_KeyName_Count = 0
  191. };
  192. ELEMENT_DEFINITION_NS(Signature_KeyInfo, KeyName, sc_ss_xmldsignamespace, Rtl_InspectManifest_Signature, XML_ELEMENT_FLAG_NO_ELEMENTS)
  193. ATTRIBUTE_DEFINITION_NONS_NODEFAULT(empty),
  194. ELEMENT_DEFINITION_DEFNS_END();
  195. ELEMENT_DEFINITION_CHILD_ELEMENTS(Signature_KeyInfo, KeyName)
  196. ELEMENT_DEFINITION_CHILD_ELEMENTS_END();
  197. static int q[] = {0};
  198. NTSTATUS
  199. Rtl_InspectManifest_Signature(
  200. PXML_LOGICAL_STATE pLogicalState,
  201. PRTL_MANIFEST_CONTENT_RAW pManifestContent,
  202. PXMLDOC_THING pDocThing,
  203. PRTL_GROWING_LIST pAttributes,
  204. MANIFEST_ELEMENT_CALLBACK_REASON Reason,
  205. const struct _XML_ELEMENT_DEFINITION *pElementDefinition
  206. )
  207. {
  208. PXML_DSIG_BLOCK pCurrentBlock = NULL;
  209. ULONG ulBlockIndex = 0;
  210. NTSTATUS status;
  211. //
  212. // Might not want signatures
  213. //
  214. if (!pManifestContent->pManifestSignatures)
  215. return STATUS_SUCCESS;
  216. ulBlockIndex = pManifestContent->ulDocumentSignatures;
  217. //
  218. // Top-level <Signature> tag encountered
  219. //
  220. if (pElementDefinition == ELEMENT_NAMED(Signature)) {
  221. status = RtlIndexIntoGrowingList(
  222. pManifestContent->pManifestSignatures,
  223. ulBlockIndex,
  224. (PVOID*)&pCurrentBlock,
  225. (Reason == eElementNotify_Open));
  226. if (!NT_SUCCESS(status))
  227. goto Exit;
  228. //
  229. // Opening the Signature tag requires that we reserve another slot in the signature
  230. // array now before doing anything else.
  231. //
  232. if (Reason == eElementNotify_Open) {
  233. RtlZeroMemory(pCurrentBlock, sizeof(*pCurrentBlock));
  234. //
  235. // Track this opening element as the entire contents of the <Signature> blob
  236. // that will get hashed later on. In the close, we'll adjust the size of the
  237. // element to account for the entire data run.
  238. //
  239. pCurrentBlock->DsigDocumentExtent = pDocThing->TotalExtent;
  240. }
  241. //
  242. // As we close this element, we bump up the number of signatures found in the
  243. // raw content and reset the "whole signature block" value
  244. //
  245. else if (Reason == eElementNotify_Close) {
  246. pManifestContent->ulDocumentSignatures++;
  247. //
  248. // We only care about end elements - the above is already sufficient for
  249. // empty elements.
  250. //
  251. if (pDocThing->ulThingType == XMLDOC_THING_END_ELEMENT) {
  252. ULONG_PTR ulpStartLocation = (ULONG_PTR)pCurrentBlock->DsigDocumentExtent.pvData;
  253. ULONG_PTR ulpThisEnding = ((ULONG_PTR)pDocThing->TotalExtent.pvData) + pDocThing->TotalExtent.cbData;
  254. pCurrentBlock->DsigDocumentExtent.cbData = ulpThisEnding - ulpStartLocation;
  255. }
  256. }
  257. }
  258. //
  259. // Always get the 'active' block, we'll need it for all the operations below,
  260. // but don't grow in case we're out of range.
  261. //
  262. else {
  263. status = RtlIndexIntoGrowingList(pManifestContent->pManifestSignatures, ulBlockIndex, (PVOID*)&pCurrentBlock, FALSE);
  264. if (!NT_SUCCESS(status))
  265. goto Exit;
  266. }
  267. //
  268. // Now do something useful with this block
  269. //
  270. ASSERT(pCurrentBlock != NULL);
  271. if (pCurrentBlock == NULL) {
  272. status = STATUS_INTERNAL_ERROR;
  273. goto Exit;
  274. }
  275. //
  276. // Signature values are only hyperspace, and only one of them at that.
  277. //
  278. if (pElementDefinition == ELEMENT_NAMED(Signature_SignatureValue)) {
  279. if (Reason == eElementNotify_Hyperspace) {
  280. if ((pCurrentBlock->ulFlags & XMLDSIG_FLAG_SIGNATURE_DATA_PRESENT) == 0) {
  281. pCurrentBlock->ulFlags |= XMLDSIG_FLAG_SIGNATURE_DATA_PRESENT;
  282. pCurrentBlock->SignatureData = pDocThing->Hyperspace;
  283. }
  284. else {
  285. // TODO: Log an error here about duplicate <SignatureData>'s being invalid
  286. status = STATUS_UNSUCCESSFUL;
  287. goto Exit;
  288. }
  289. }
  290. }
  291. //
  292. // Signature methods get tacked into the current block as well
  293. //
  294. else if (pElementDefinition == ELEMENT_NAMED(Signature_SignedInfo_SignatureMethod)) {
  295. PXMLDOC_ATTRIBUTE OrganizedAttributes[eAttribs_Signature_SignedInfo_SignatureMethod_Count];
  296. if (Reason == eElementNotify_Open) {
  297. status = RtlValidateAttributesAndOrganize(
  298. &pLogicalState->ParseState,
  299. &pDocThing->Element,
  300. pAttributes,
  301. pElementDefinition,
  302. OrganizedAttributes);
  303. if (OrganizedAttributes[eAttribs_Signature_SignedInfo_SignatureMethod_Algorithm]) {
  304. if ((pCurrentBlock->ulFlags & XMLDSIG_FLAG_SIGNATURE_METHOD_PRESENT) == 0) {
  305. pCurrentBlock->SignedInfoData.SignatureMethod = OrganizedAttributes[eAttribs_Signature_SignedInfo_SignatureMethod_Algorithm]->Value;
  306. pCurrentBlock->ulFlags |= XMLDSIG_FLAG_SIGNATURE_METHOD_PRESENT;
  307. }
  308. else {
  309. // TODO: Log a message here about duplicated SignatureMethod.Algorithm values
  310. status = STATUS_UNSUCCESSFUL;
  311. goto Exit;
  312. }
  313. }
  314. else {
  315. // TODO: Algorithm is required on this element
  316. status = STATUS_UNSUCCESSFUL;
  317. goto Exit;
  318. }
  319. }
  320. }
  321. status = STATUS_SUCCESS;
  322. Exit:
  323. return status;
  324. }