moxml 0.1.25 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/release.yml +9 -0
  3. data/.github/workflows/windows.yml +62 -0
  4. data/Gemfile +3 -1
  5. data/README.adoc +133 -6
  6. data/docs/signature/algorithms.md +108 -0
  7. data/docs/signature/architecture.md +148 -0
  8. data/docs/signature/c14n.md +110 -0
  9. data/docs/signature/examples.md +109 -0
  10. data/docs/signature/flows.md +132 -0
  11. data/docs/signature/quick-reference.md +115 -0
  12. data/docs/signature/security.md +143 -0
  13. data/examples/signature/auto_key_extraction.rb +24 -0
  14. data/examples/signature/enveloped_rsa.rb +45 -0
  15. data/examples/signature/hmac.rb +33 -0
  16. data/lib/compat/opal/moxml_boot.rb +5 -0
  17. data/lib/moxml/adapter/base.rb +53 -49
  18. data/lib/moxml/adapter/customized_leptris/declaration.rb +32 -0
  19. data/lib/moxml/adapter/customized_leptris/doctype.rb +31 -0
  20. data/lib/moxml/adapter/customized_leptris/entity_reference.rb +12 -0
  21. data/lib/moxml/adapter/customized_leptris/text_segment.rb +26 -0
  22. data/lib/moxml/adapter/customized_leptris.rb +16 -0
  23. data/lib/moxml/adapter/customized_libxml/cdata.rb +3 -12
  24. data/lib/moxml/adapter/customized_libxml/comment.rb +2 -9
  25. data/lib/moxml/adapter/customized_libxml/declaration.rb +1 -10
  26. data/lib/moxml/adapter/customized_libxml/node.rb +8 -0
  27. data/lib/moxml/adapter/customized_libxml/processing_instruction.rb +2 -10
  28. data/lib/moxml/adapter/customized_libxml/text.rb +2 -9
  29. data/lib/moxml/adapter/customized_oga/entity_decoder.rb +37 -0
  30. data/lib/moxml/adapter/customized_oga/raw_value_override.rb +52 -0
  31. data/lib/moxml/adapter/customized_oga/xml_generator.rb +4 -34
  32. data/lib/moxml/adapter/customized_oga.rb +2 -0
  33. data/lib/moxml/adapter/customized_ox/entity_reference.rb +1 -17
  34. data/lib/moxml/adapter/customized_rexml/entity_reference.rb +1 -11
  35. data/lib/moxml/adapter/headed_ox.rb +9 -128
  36. data/lib/moxml/adapter/leptris.rb +965 -0
  37. data/lib/moxml/adapter/libxml.rb +131 -99
  38. data/lib/moxml/adapter/nokogiri.rb +29 -8
  39. data/lib/moxml/adapter/oga.rb +91 -54
  40. data/lib/moxml/adapter/ox.rb +93 -137
  41. data/lib/moxml/adapter/rexml.rb +61 -50
  42. data/lib/moxml/adapter.rb +2 -1
  43. data/lib/moxml/attribute.rb +8 -4
  44. data/lib/moxml/attribute_resolver.rb +189 -0
  45. data/lib/moxml/c14n/attribute_handler.rb +71 -0
  46. data/lib/moxml/c14n/character_encoder.rb +29 -0
  47. data/lib/moxml/c14n/data_model.rb +145 -0
  48. data/lib/moxml/c14n/exclusive.rb +188 -0
  49. data/lib/moxml/c14n/inclusive_10.rb +42 -0
  50. data/lib/moxml/c14n/inclusive_11.rb +21 -0
  51. data/lib/moxml/c14n/namespace_context.rb +68 -0
  52. data/lib/moxml/c14n/namespace_handler.rb +71 -0
  53. data/lib/moxml/c14n/node.rb +42 -0
  54. data/lib/moxml/c14n/nodes/attribute_node.rb +50 -0
  55. data/lib/moxml/c14n/nodes/comment_node.rb +29 -0
  56. data/lib/moxml/c14n/nodes/element_node.rb +62 -0
  57. data/lib/moxml/c14n/nodes/namespace_node.rb +41 -0
  58. data/lib/moxml/c14n/nodes/processing_instruction_node.rb +30 -0
  59. data/lib/moxml/c14n/nodes/root_node.rb +22 -0
  60. data/lib/moxml/c14n/nodes/text_node.rb +29 -0
  61. data/lib/moxml/c14n/nodes.rb +17 -0
  62. data/lib/moxml/c14n/processor.rb +118 -0
  63. data/lib/moxml/c14n/writer.rb +121 -0
  64. data/lib/moxml/c14n/xml_base_handler.rb +140 -0
  65. data/lib/moxml/c14n.rb +96 -0
  66. data/lib/moxml/config.rb +29 -3
  67. data/lib/moxml/context.rb +12 -0
  68. data/lib/moxml/element.rb +29 -12
  69. data/lib/moxml/entity/reference.rb +28 -0
  70. data/lib/moxml/entity.rb +125 -0
  71. data/lib/moxml/node.rb +90 -1
  72. data/lib/moxml/sax/namespace_splitter.rb +5 -2
  73. data/lib/moxml/signature/algorithms/base64_transform.rb +40 -0
  74. data/lib/moxml/signature/algorithms/canonicalization_base.rb +87 -0
  75. data/lib/moxml/signature/algorithms/digest_base.rb +51 -0
  76. data/lib/moxml/signature/algorithms/dsa_sha.rb +107 -0
  77. data/lib/moxml/signature/algorithms/ecdsa_sha.rb +125 -0
  78. data/lib/moxml/signature/algorithms/enveloped_signature_transform.rb +79 -0
  79. data/lib/moxml/signature/algorithms/exc_c14n_10.rb +23 -0
  80. data/lib/moxml/signature/algorithms/hmac_sha.rb +117 -0
  81. data/lib/moxml/signature/algorithms/inclusive_c14n_10.rb +21 -0
  82. data/lib/moxml/signature/algorithms/inclusive_c14n_11.rb +23 -0
  83. data/lib/moxml/signature/algorithms/rsa_pkcs1_sha.rb +56 -0
  84. data/lib/moxml/signature/algorithms/sha1.rb +13 -0
  85. data/lib/moxml/signature/algorithms/sha224.rb +13 -0
  86. data/lib/moxml/signature/algorithms/sha256.rb +13 -0
  87. data/lib/moxml/signature/algorithms/sha384.rb +13 -0
  88. data/lib/moxml/signature/algorithms/sha512.rb +13 -0
  89. data/lib/moxml/signature/algorithms/signature_method_base.rb +58 -0
  90. data/lib/moxml/signature/algorithms/transform_base.rb +40 -0
  91. data/lib/moxml/signature/algorithms.rb +113 -0
  92. data/lib/moxml/signature/errors.rb +99 -0
  93. data/lib/moxml/signature/key_extractor.rb +172 -0
  94. data/lib/moxml/signature/model/algorithm_method.rb +18 -0
  95. data/lib/moxml/signature/model/digest_method.rb +15 -0
  96. data/lib/moxml/signature/model/key/dsa_key_value.rb +28 -0
  97. data/lib/moxml/signature/model/key/ec_key_value.rb +22 -0
  98. data/lib/moxml/signature/model/key/rsa_key_value.rb +19 -0
  99. data/lib/moxml/signature/model/key/x509_data.rb +32 -0
  100. data/lib/moxml/signature/model/key/x509_digest.rb +19 -0
  101. data/lib/moxml/signature/model/key/x509_issuer_serial.rb +19 -0
  102. data/lib/moxml/signature/model/key_info.rb +21 -0
  103. data/lib/moxml/signature/model/key_value.rb +20 -0
  104. data/lib/moxml/signature/model/object_element.rb +18 -0
  105. data/lib/moxml/signature/model/reference.rb +22 -0
  106. data/lib/moxml/signature/model/signature.rb +21 -0
  107. data/lib/moxml/signature/model/signature_value.rb +16 -0
  108. data/lib/moxml/signature/model/signed_info.rb +20 -0
  109. data/lib/moxml/signature/model/transform.rb +16 -0
  110. data/lib/moxml/signature/model/transforms.rb +36 -0
  111. data/lib/moxml/signature/model.rb +35 -0
  112. data/lib/moxml/signature/parser.rb +270 -0
  113. data/lib/moxml/signature/reference_resolver.rb +79 -0
  114. data/lib/moxml/signature/reference_result.rb +22 -0
  115. data/lib/moxml/signature/serializer.rb +163 -0
  116. data/lib/moxml/signature/signer.rb +73 -0
  117. data/lib/moxml/signature/single_verification_result.rb +31 -0
  118. data/lib/moxml/signature/transform_pipeline.rb +106 -0
  119. data/lib/moxml/signature/verification_result.rb +27 -0
  120. data/lib/moxml/signature/verifier.rb +129 -0
  121. data/lib/moxml/signature.rb +94 -0
  122. data/lib/moxml/version.rb +1 -1
  123. data/lib/moxml/xml_emitter.rb +71 -0
  124. data/lib/moxml/xpath/compiler.rb +60 -7
  125. data/lib/moxml/xpath/parser.rb +22 -15
  126. data/lib/moxml.rb +5 -0
  127. data/reference-docs/w3c-xmldsig-bestpractices.md +216 -0
  128. data/reference-docs/w3c-xmldsig-core.md +400 -0
  129. data/spec/examples/readme_examples_spec.rb +0 -4
  130. data/spec/examples/xpath_examples_spec.rb +0 -11
  131. data/spec/fixtures/xmldsig/keys/rsa_private.pem +28 -0
  132. data/spec/fixtures/xmldsig/keys/rsa_public.pem +9 -0
  133. data/spec/fixtures/xmldsig/keys/rsa_ref.pem +15 -0
  134. data/spec/fixtures/xmldsig/keys/rsa_ref.pub +6 -0
  135. data/spec/fixtures/xmldsig/sign2-doc.xml +6 -0
  136. data/spec/fixtures/xmldsig/sign2-result.xml +25 -0
  137. data/spec/fixtures/xmldsig/sign3-result.xml +39 -0
  138. data/spec/integration/all_adapters_spec.rb +17 -0
  139. data/spec/integration/sax_parity_spec.rb +58 -0
  140. data/spec/integration/shared_examples/edge_cases.rb +0 -10
  141. data/spec/integration/shared_examples/integration_workflows.rb +0 -10
  142. data/spec/integration/shared_examples/node_wrappers/attribute_behavior.rb +98 -0
  143. data/spec/integration/shared_examples/node_wrappers/namespace_behavior.rb +26 -0
  144. data/spec/integration/shared_examples/node_wrappers/node_behavior.rb +0 -8
  145. data/spec/moxml/adapter/leptris_spec.rb +75 -0
  146. data/spec/moxml/adapter/ox_spec.rb +20 -6
  147. data/spec/moxml/adapter/platform_spec.rb +15 -2
  148. data/spec/moxml/adapter/shared_examples/adapter_contract.rb +180 -0
  149. data/spec/moxml/attribute_resolver_spec.rb +108 -0
  150. data/spec/moxml/c14n/api_spec.rb +117 -0
  151. data/spec/moxml/c14n/c14n_spec.rb +88 -0
  152. data/spec/moxml/c14n/comments_pis_spec.rb +65 -0
  153. data/spec/moxml/c14n/inclusive10_spec.rb +60 -0
  154. data/spec/moxml/c14n/namespace_edge_cases_spec.rb +88 -0
  155. data/spec/moxml/c14n/xml_attributes_spec.rb +54 -0
  156. data/spec/moxml/doctype_spec.rb +1 -1
  157. data/spec/moxml/entity_spec.rb +76 -0
  158. data/spec/moxml/node_spec.rb +104 -0
  159. data/spec/moxml/sax_entity_parity_spec.rb +358 -0
  160. data/spec/moxml/signature/algorithms/base64_transform_spec.rb +26 -0
  161. data/spec/moxml/signature/algorithms/digest_base_spec.rb +72 -0
  162. data/spec/moxml/signature/algorithms/dsa_sha_spec.rb +46 -0
  163. data/spec/moxml/signature/algorithms/ecdsa_sha_spec.rb +72 -0
  164. data/spec/moxml/signature/algorithms/enveloped_signature_transform_spec.rb +40 -0
  165. data/spec/moxml/signature/algorithms/hmac_sha_spec.rb +71 -0
  166. data/spec/moxml/signature/algorithms/rsa_pkcs1_sha_spec.rb +55 -0
  167. data/spec/moxml/signature/algorithms_spec.rb +76 -0
  168. data/spec/moxml/signature/cross_verify_spec.rb +64 -0
  169. data/spec/moxml/signature/edge_cases_spec.rb +284 -0
  170. data/spec/moxml/signature/fixtures_spec.rb +80 -0
  171. data/spec/moxml/signature/key_extractor_spec.rb +96 -0
  172. data/spec/moxml/signature/model_spec.rb +54 -0
  173. data/spec/moxml/signature/round_trip_spec.rb +113 -0
  174. data/spec/moxml/xml_emitter_spec.rb +64 -0
  175. data/spec/moxml/xpath/axes_spec.rb +72 -0
  176. data/spec/moxml/xpath/parser_spec.rb +6 -0
  177. data/spec/moxml/xpath_capabilities_spec.rb +5 -3
  178. data/spec/performance/benchmark_spec.rb +13 -6
  179. data/spec/performance/thread_safety_spec.rb +0 -4
  180. data/spec/spec_helper.rb +5 -1
  181. metadata +130 -2
@@ -0,0 +1,216 @@
1
+ # XML Signature Best Practices
2
+
3
+ W3C Working Group Note 11 April 2013
4
+
5
+ - This version: http://www.w3.org/TR/2013/NOTE-xmldsig-bestpractices-20130411/
6
+ - Latest published version: http://www.w3.org/TR/xmldsig-bestpractices/
7
+ - Latest editor's draft: http://www.w3.org/2008/xmlsec/Drafts/best-practices/Overview.html
8
+ - Previous version: http://www.w3.org/TR/2013/NOTE-xmldsig-bestpractices-20130124/
9
+ - Editors: Frederick Hirsch (Nokia), Pratik Datta (Oracle)
10
+
11
+ Copyright © 2013 W3C® (MIT, ERCIM, Keio, Beihang), All Rights Reserved.
12
+
13
+ ## Abstract
14
+
15
+ This document collects best practices for implementers and users of the XML
16
+ Signature specification [XMLDSIG-CORE1]. Most of these best practices are
17
+ related to improving security and mitigating attacks, yet others are for best
18
+ practices in the practical use of XML Signature, such as signing XML that
19
+ doesn't use namespaces, for example.
20
+
21
+ ## 1. Overview
22
+
23
+ The XML Signature specification [XMLDSIG-CORE1] offers powerful and flexible
24
+ mechanisms to support a variety of use cases. This flexibility has the downside
25
+ of increasing the number of possible attacks. One countermeasure to the
26
+ increased number of threats is to follow best practices, including a
27
+ simplification of use of XML Signature where possible.
28
+
29
+ ## 2. Best Practices for Implementers
30
+
31
+ ### 2.1 Reduce the opportunities for denial of service attacks
32
+
33
+ XML Signature may be used in application server systems, where multiple incoming
34
+ messages are being processed simultaneously. In this situation incoming messages
35
+ should be assumed to be possibly hostile with the concern that a single poison
36
+ message could bring down an entire set of web applications and services.
37
+
38
+ **Best Practice 1**: Mitigate denial of service attacks by executing potentially
39
+ dangerous operations only after successfully authenticating the signature.
40
+
41
+ Validate the `ds:Reference` elements for a signature only after establishing
42
+ trust, for example by verifying the key and validating `ds:SignedInfo` first.
43
+
44
+ Recommended order of operations:
45
+
46
+ 1. **Step 1** — fetch the verification key and establish trust in that key.
47
+ 2. **Step 2** — validate `ds:SignedInfo` with that key.
48
+ 3. **Step 3** — validate the references.
49
+
50
+ **Best Practice 2**: Establish trust in the verification/validation key (validate
51
+ X.509 certificates, certificate chains and revocation status).
52
+
53
+ #### 2.1.1 XSLT transform that causes denial of service
54
+
55
+ A nested-loop XSLT can require O(N^4) operations on a document with N elements.
56
+
57
+ **Best Practice 3**: Consider avoiding XSLT Transforms.
58
+
59
+ #### 2.1.2 XSLT transform that executes arbitrary code
60
+
61
+ XSLT user-defined extensions can execute arbitrary code (e.g., shell commands).
62
+
63
+ **Best Practice 4**: When XSLT is required disallow the use of user-defined
64
+ extensions.
65
+
66
+ #### 2.1.3 XPath Filtering transform that causes denial of service
67
+
68
+ A document with N namespaces and N elements produces N×N namespace nodes; an
69
+ XPath Filter evaluates the expression once per node, giving O(N^4) cost.
70
+
71
+ **Best Practice 5**: Try to avoid or limit XPath transforms.
72
+
73
+ #### 2.1.4 XPath selection DoS in streaming mode
74
+
75
+ Wildcard axes (descendant, following, etc.) cause search-context explosion in
76
+ streaming verifiers.
77
+
78
+ **Best Practice 6**: Avoid using "descendant", "descendant-or-self",
79
+ "following-sibling", and "following" axes when using streaming XPaths.
80
+
81
+ #### 2.1.5 Retrieval method that causes an infinite loop
82
+
83
+ `ds:RetrievalMethod` may form cyclic references.
84
+
85
+ **Best Practice 7**: Try to avoid or limit `ds:RetrievalMethod` support with
86
+ `ds:KeyInfo`.
87
+
88
+ #### 2.1.6 Problematic external references
89
+
90
+ External URI references can read sensitive files or trigger side effects on
91
+ other sites.
92
+
93
+ **Best Practice 8**: Control external references (mitigate query parameters,
94
+ unknown URI schemes, inappropriate content).
95
+
96
+ #### 2.1.7 Denial of service caused by too many transforms
97
+
98
+ A reference may carry thousands of C14N transforms.
99
+
100
+ **Best Practice 9**: Limit the number of `ds:Reference` transforms allowed.
101
+
102
+ ### 2.2 Provide a mechanism to determine what was signed
103
+
104
+ **Best Practice 10**: Offer interfaces for the application to learn what was
105
+ signed (return pre-digested data and pre-C14N data).
106
+
107
+ ### 2.3 Be aware of certificate encoding issues
108
+
109
+ **Best Practice 11**: Do not re-encode certificates; use DER when possible with
110
+ the `X509Certificate` element. Re-encoding can break the signature on the
111
+ certificate.
112
+
113
+ ## 3. Best Practices for Applications
114
+
115
+ ### 3.1 Check what is signed
116
+
117
+ **Best Practice 12**: Enable verifier to automate "see what is signed"
118
+ functionality.
119
+
120
+ **Best Practice 13**: When applying XML Signatures using XPath it is recommended
121
+ to always actively verify that the signature protects the intended elements and
122
+ not more or less.
123
+
124
+ **Best Practice 14**: When checking a reference URI, don't just check the name of
125
+ the element (wrapping attack mitigation — also check position).
126
+
127
+ ### 3.2 Prevent replay attacks
128
+
129
+ **Best Practice 15**: Unless impractical, sign all parts of the document.
130
+
131
+ **Best Practice 16**: Use a nonce in combination with signing time.
132
+
133
+ **Best Practice 17**: Do not rely on application logic to prevent replay attacks
134
+ since applications may change.
135
+
136
+ **Best Practice 18**: Nonce and signing time must be signature protected.
137
+
138
+ ### 3.3 Enable Long-Lived Signatures
139
+
140
+ **Best Practice 19**: Use Timestamp tokens issued by Timestamp authorities for
141
+ long lived signatures.
142
+
143
+ **Best Practice 20**: Long lived signatures should include a `xsd:dateTime` field
144
+ to indicate the time of signing.
145
+
146
+ ### 3.4 Signing XML without namespace information ("legacy XML")
147
+
148
+ **Best Practice 21**: When creating an enveloping signature over XML without
149
+ namespace information, take steps to avoid having that content inherit the XML
150
+ Signature namespace (insert an empty default namespace declaration, or define a
151
+ namespace prefix for the Signature namespace).
152
+
153
+ ### 3.5 Prefer the XPath Filter 2 Transform
154
+
155
+ **Best Practice 22**: Prefer the XPath Filter 2 Transform to the XPath Filter
156
+ Transform if possible.
157
+
158
+ ## 4. Best Practices for Signers and Verifiers
159
+
160
+ ### 4.1 Do not transmit external unparsed entity references
161
+
162
+ **Best Practice 23**: Do not transmit unparsed external entity references in
163
+ signed material. Expand all entity references before creating the cleartext.
164
+
165
+ ### 4.2 Be aware of schema processing
166
+
167
+ **Best Practice 24**: Do not rely on a validating processor on the consumer's end
168
+ to normalize XML documents.
169
+
170
+ **Best Practice 25**: Avoid destructive validation before signature validation.
171
+
172
+ ### 4.3 HMAC truncation
173
+
174
+ **Best Practice 26**: When using an HMAC, set the HMAC Output Length to one half
175
+ the number of bits in the hash size.
176
+
177
+ ### 4.4 Distinct keys for sign and encrypt
178
+
179
+ **Best Practice 27**: When encrypting and signing use distinct keys.
180
+
181
+ ## 5. Best Practices Summary
182
+
183
+ 1. Mitigate DoS by authenticating before dangerous operations.
184
+ 2. Establish trust in the verification key.
185
+ 3. Avoid XSLT transforms.
186
+ 4. Disallow XSLT user-defined extensions.
187
+ 5. Avoid/limit XPath transforms.
188
+ 6. Avoid wildcard axes in streaming XPaths.
189
+ 7. Avoid/limit `ds:RetrievalMethod`.
190
+ 8. Control external references.
191
+ 9. Limit number of transforms per Reference.
192
+ 10. Offer interfaces to learn what was signed.
193
+ 11. Don't re-encode certificates; prefer DER.
194
+ 12. Enable verifier to "see what is signed".
195
+ 13. With XPath, verify the signature actually protects intended elements.
196
+ 14. When checking reference URI, check both name and position.
197
+ 15. Sign all parts of the document unless impractical.
198
+ 16. Use nonce + signing time.
199
+ 17. Don't rely solely on application logic for replay prevention.
200
+ 18. Nonce and signing time must be signature protected.
201
+ 19. Use TSA-issued timestamp tokens for long-lived signatures.
202
+ 20. Include `xsd:dateTime` for signing time in long-lived signatures.
203
+ 21. Avoid namespace inheritance in enveloping signatures over legacy XML.
204
+ 22. Prefer XPath Filter 2 over XPath Filter.
205
+ 23. Don't transmit unparsed external entity references.
206
+ 24. Don't rely on validating parser on consumer's end.
207
+ 25. Avoid destructive validation before signature validation.
208
+ 26. Truncate HMAC to half hash size.
209
+ 27. Use distinct keys for signing and encryption.
210
+
211
+ ## References
212
+
213
+ - [XMLDSIG-CORE1] — XML Signature Syntax and Processing Version 1.1
214
+ - [XADES] — XML Advanced Electronic Signatures (ETSI TS 101 903)
215
+ - [RFC3161] — Internet X.509 PKI Time-Stamp Protocol (TSP)
216
+ - [MCINTOSH-WRAP] — XML signature element wrapping attacks and countermeasures
@@ -0,0 +1,400 @@
1
+ # XML Signature Syntax and Processing Version 1.1 (W3C Recommendation, 11 April 2013)
2
+
3
+ Curated implementation-focused extract. Source: https://www.w3.org/TR/xmldsig-core/
4
+
5
+ Editors: Donald Eastlake, Joseph Reagle, David Solo, Frederick Hirsch, Magnus Nyström, Thomas Roessler, Kelvin Yiu.
6
+
7
+ ## Abstract
8
+
9
+ XML Signatures provide integrity, message authentication, and/or signer
10
+ authentication services for data of any type, whether located within the XML
11
+ that includes the signature or elsewhere.
12
+
13
+ ## Namespaces
14
+
15
+ | URI | prefix |
16
+ | --- | --- |
17
+ | `http://www.w3.org/2000/09/xmldsig#` | `ds:` / `dsig:` |
18
+ | `http://www.w3.org/2009/xmldsig11#` | `dsig11:` |
19
+
20
+ Algorithm identifiers in the `http://www.w3.org/2001/04/xmldsig-more#` namespace
21
+ are defined by RFC 6931.
22
+
23
+ ## Signature Structure
24
+
25
+ ```
26
+ <Signature ID?>
27
+ <SignedInfo>
28
+ <CanonicalizationMethod />
29
+ <SignatureMethod />
30
+ (<Reference URI? >
31
+ (<Transforms>)?
32
+ <DigestMethod>
33
+ <DigestValue>
34
+ </Reference>)+
35
+ </SignedInfo>
36
+ <SignatureValue>
37
+ (<KeyInfo>)?
38
+ (<Object ID?>)*
39
+ </Signature>
40
+ ```
41
+
42
+ ## Processing Rules
43
+
44
+ ### 3.1 Signature Generation
45
+
46
+ #### 3.1.1 Reference Generation
47
+
48
+ For each data object being signed:
49
+
50
+ 1. Apply the `Transforms`, as determined by the application, to the data object.
51
+ 2. Calculate the digest value over the resulting data object.
52
+ 3. Create a `Reference` element, including the (optional) identification of the
53
+ data object, any (optional) transform elements, the digest algorithm and the
54
+ `DigestValue`.
55
+
56
+ #### 3.1.2 Signature Generation
57
+
58
+ 1. Create `SignedInfo` element with `SignatureMethod`, `CanonicalizationMethod`
59
+ and `Reference`(s).
60
+ 2. Canonicalize and then calculate the `SignatureValue` over `SignedInfo` based
61
+ on algorithms specified in `SignedInfo`.
62
+ 3. Construct the `Signature` element that includes `SignedInfo`, `Object`(s),
63
+ `KeyInfo` (if required), and `SignatureValue`.
64
+
65
+ ### 3.2 Core Validation
66
+
67
+ The required steps of core validation include:
68
+
69
+ 1. **Reference validation** — verification of the digest contained in each
70
+ `Reference` in `SignedInfo`.
71
+ 2. **Signature validation** — cryptographic signature validation of the signature
72
+ calculated over `SignedInfo`.
73
+
74
+ Comparison of each value is over the numeric (integer) or decoded octet sequence
75
+ of the value.
76
+
77
+ #### 3.2.1 Reference Validation
78
+
79
+ 1. Canonicalize the `SignedInfo` element based on the `CanonicalizationMethod`.
80
+ 2. For each `Reference` in `SignedInfo`:
81
+ 1. Obtain the data object (dereference `URI`, execute `Transforms`, or fetch
82
+ from local cache).
83
+ 2. Digest using the `DigestMethod`.
84
+ 3. Compare against `DigestValue`; mismatch ⇒ validation fails.
85
+
86
+ #### 3.2.2 Signature Validation
87
+
88
+ 1. Obtain the keying information from `KeyInfo` or external source.
89
+ 2. Obtain the canonical form of `SignedInfo` using `CanonicalizationMethod` and
90
+ confirm the `SignatureValue` over `SignedInfo`.
91
+
92
+ ## Schema
93
+
94
+ ### `ds:CryptoBinary`
95
+
96
+ Integer-to-octet conversion equivalent to IEEE 1363 I2OSP with minimal length,
97
+ then base64-encoded.
98
+
99
+ ### 4.2 `Signature`
100
+
101
+ ```xml
102
+ <element name="Signature" type="ds:SignatureType"/>
103
+ <complexType name="SignatureType">
104
+ <sequence>
105
+ <element ref="ds:SignedInfo"/>
106
+ <element ref="ds:SignatureValue"/>
107
+ <element ref="ds:KeyInfo" minOccurs="0"/>
108
+ <element ref="ds:Object" minOccurs="0" maxOccurs="unbounded"/>
109
+ </sequence>
110
+ <attribute name="Id" type="ID" use="optional"/>
111
+ </complexType>
112
+ ```
113
+
114
+ ### 4.3 `SignatureValue`
115
+
116
+ ```xml
117
+ <complexType name="SignatureValueType">
118
+ <simpleContent>
119
+ <extension base="base64Binary">
120
+ <attribute name="Id" type="ID" use="optional"/>
121
+ </extension>
122
+ </simpleContent>
123
+ </complexType>
124
+ ```
125
+
126
+ ### 4.4 `SignedInfo`
127
+
128
+ ```xml
129
+ <complexType name="SignedInfoType">
130
+ <sequence>
131
+ <element ref="ds:CanonicalizationMethod"/>
132
+ <element ref="ds:SignatureMethod"/>
133
+ <element ref="ds:Reference" maxOccurs="unbounded"/>
134
+ </sequence>
135
+ <attribute name="Id" type="ID" use="optional"/>
136
+ </complexType>
137
+ ```
138
+
139
+ ### 4.4.1 `CanonicalizationMethod`
140
+
141
+ ```xml
142
+ <complexType name="CanonicalizationMethodType" mixed="true">
143
+ <sequence>
144
+ <any namespace="##any" minOccurs="0" maxOccurs="unbounded"/>
145
+ </sequence>
146
+ <attribute name="Algorithm" type="anyURI" use="required"/>
147
+ </complexType>
148
+ ```
149
+
150
+ ### 4.4.2 `SignatureMethod`
151
+
152
+ ```xml
153
+ <complexType name="SignatureMethodType" mixed="true">
154
+ <sequence>
155
+ <element name="HMACOutputLength" minOccurs="0" type="ds:HMACOutputLengthType"/>
156
+ <any namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
157
+ </sequence>
158
+ <attribute name="Algorithm" type="anyURI" use="required"/>
159
+ </complexType>
160
+ ```
161
+
162
+ Signatures MUST be deemed invalid if the HMAC truncation length is below the
163
+ larger of (a) half the underlying hash output length, and (b) 80 bits.
164
+
165
+ ### 4.4.3 `Reference`
166
+
167
+ ```xml
168
+ <complexType name="ReferenceType">
169
+ <sequence>
170
+ <element ref="ds:Transforms" minOccurs="0"/>
171
+ <element ref="ds:DigestMethod"/>
172
+ <element ref="ds:DigestValue"/>
173
+ </sequence>
174
+ <attribute name="Id" type="ID" use="optional"/>
175
+ <attribute name="URI" type="anyURI" use="optional"/>
176
+ <attribute name="Type" type="anyURI" use="optional"/>
177
+ </complexType>
178
+ ```
179
+
180
+ #### 4.4.3.2 Reference Processing Model
181
+
182
+ Result of URI dereferencing or transforms is either octet stream or XPath node-set.
183
+
184
+ Defaults:
185
+ - octet stream + node-set transform expected ⇒ parse octets as XML.
186
+ - node-set + octet transform expected ⇒ canonicalize via C14N.
187
+
188
+ A **same-document reference** is a URI-Reference that consists of `#` followed by
189
+ a fragment, or an empty URI.
190
+
191
+ - `URI=""` ⇒ node-set (minus comments) of the entire document.
192
+ - `URI="#id"` ⇒ node-set of the element with that ID + descendants + in-scope
193
+ namespaces/attributes, no comments.
194
+ - `#xpointer(/)` retains comments at root.
195
+ - `#xpointer(id('ID'))` retains comments for the element.
196
+
197
+ ### 4.4.3.4 `Transforms`
198
+
199
+ ```xml
200
+ <complexType name="TransformsType">
201
+ <sequence>
202
+ <element ref="ds:Transform" maxOccurs="unbounded"/>
203
+ </sequence>
204
+ </complexType>
205
+
206
+ <complexType name="TransformType" mixed="true">
207
+ <choice minOccurs="0" maxOccurs="unbounded">
208
+ <any namespace="##other" processContents="lax"/>
209
+ <element name="XPath" type="string"/>
210
+ </choice>
211
+ <attribute name="Algorithm" type="anyURI" use="required"/>
212
+ </complexType>
213
+ ```
214
+
215
+ ### 4.5 `KeyInfo`
216
+
217
+ ```xml
218
+ <complexType name="KeyInfoType" mixed="true">
219
+ <choice maxOccurs="unbounded">
220
+ <element ref="ds:KeyName"/>
221
+ <element ref="ds:KeyValue"/>
222
+ <element ref="ds:RetrievalMethod"/>
223
+ <element ref="ds:X509Data"/>
224
+ <element ref="ds:PGPData"/>
225
+ <element ref="ds:SPKIData"/>
226
+ <element ref="ds:MgmtData"/>
227
+ <any processContents="lax" namespace="##other"/>
228
+ </choice>
229
+ <attribute name="Id" type="ID" use="optional"/>
230
+ </complexType>
231
+ ```
232
+
233
+ `KeyValue` contains one of `DSAKeyValue`, `RSAKeyValue`, or (1.1) `ECKeyValue`.
234
+
235
+ X509Data child elements: `X509IssuerSerial` (deprecated), `X509SKI`,
236
+ `X509SubjectName`, `X509Certificate`, `X509CRL`, `dsig11:X509Digest`.
237
+
238
+ ### 4.6 `Object`
239
+
240
+ Optional element for including data objects. Has `Id`, `MimeType`, `Encoding`
241
+ attributes.
242
+
243
+ ## Additional Syntax
244
+
245
+ ### 5.1 `Manifest`
246
+
247
+ A list of `Reference`s where digest checking is application-defined (not core).
248
+
249
+ ### 5.2 `SignatureProperties`
250
+
251
+ For signature-time, hardware serial, etc. `SignatureProperty` has required
252
+ `Target` attribute referencing the `Signature` element.
253
+
254
+ ### 5.3 PIs and 5.4 Comments
255
+
256
+ Unless `CanonicalizationMethod` strips comments or PIs, they are signed.
257
+
258
+ ## Algorithms
259
+
260
+ ### Mandatory & Recommended URIs
261
+
262
+ **Digest**:
263
+ - Required: SHA1 `http://www.w3.org/2000/09/xmldsig#sha1` (discouraged); SHA256
264
+ `http://www.w3.org/2001/04/xmlenc#sha256`
265
+ - Optional: SHA224 `…xmldsig-more#sha224`; SHA384 `…xmldsig-more#sha384`; SHA512
266
+ `…xmlenc#sha512`
267
+
268
+ **MAC**:
269
+ - Required: HMAC-SHA1 `…xmldsig#hmac-sha1` (discouraged); HMAC-SHA256
270
+ `…xmldsig-more#hmac-sha256`
271
+ - Recommended: HMAC-SHA384, HMAC-SHA512
272
+
273
+ **Signature**:
274
+ - Required: RSA-SHA256 `…xmldsig-more#rsa-sha256`; ECDSA-SHA256
275
+ `…xmldsig-more#ecdsa-sha256`; DSA-SHA1 (verification only) `…xmldsig#dsa-sha1`
276
+ - Recommended: RSA-SHA1 (verification; discouraged for generation)
277
+ - Optional: RSA-{SHA224,SHA384,SHA512}; ECDSA-{SHA1,SHA224,SHA384,SHA512};
278
+ DSA-SHA256 `…xmldsig11#dsa-sha256`
279
+
280
+ **Canonicalization**:
281
+ - Required:
282
+ - Canonical XML 1.0 (omit comments): `http://www.w3.org/TR/2001/REC-xml-c14n-20010315`
283
+ - Canonical XML 1.1 (omit comments): `http://www.w3.org/2006/12/xml-c14n11`
284
+ - Exclusive XML Canonicalization 1.0 (omit comments): `http://www.w3.org/2001/10/xml-exc-c14n#`
285
+ - Recommended variants append `#WithComments`
286
+
287
+ **Transform**:
288
+ - Required: base64 `…xmldsig#base64`; Enveloped Signature
289
+ `…xmldsig#enveloped-signature`
290
+ - Recommended: XPath `…REC-xpath-19991116`; XPath Filter 2.0
291
+ `…2002/06/xmldsig-filter2`
292
+ - Optional: XSLT `…REC-xslt-19991116`
293
+
294
+ ### Digest Algorithms
295
+
296
+ - SHA-1: 160-bit / 20 octets, base64-encoded.
297
+ - SHA-256: 256-bit / 32 octets.
298
+ - SHA-384: 384-bit / 48 octets.
299
+ - SHA-512: 512-bit / 64 octets.
300
+
301
+ ### HMAC
302
+
303
+ Identifier family: `…xmldsig#hmac-sha1`, `…xmldsig-more#hmac-{sha224,sha256,sha384,sha512}`.
304
+ Truncation length (`HMACOutputLength`) MUST be a multiple of 8 bits. If below
305
+ half the hash output length, signature MUST be deemed invalid.
306
+
307
+ ### DSA
308
+
309
+ Identifier: `…xmldsig#dsa-sha1` (1024/160), `…xmldsig11#dsa-sha256` (2048/256 or
310
+ 3072/256).
311
+
312
+ Output (r, s): base64-encoded concatenation of two octet streams using I2OSP with
313
+ length parameter 20 (for SHA-1) or `N` (for SHA-256 with N=|q|).
314
+
315
+ ### RSA (PKCS#1 v1.5)
316
+
317
+ Identifiers: `…xmldsig#rsa-sha1`, `…xmldsig-more#rsa-{sha224,sha256,sha384,sha512}`.
318
+ RSASSA-PKCS1-v1_5 per RFC 3447 §8.2.1.
319
+
320
+ ### ECDSA
321
+
322
+ Identifiers: `…xmldsig-more#ecdsa-{sha1,sha224,sha256,sha384,sha512}`.
323
+ Output (r, s): base64-encoded concatenation of I2OSP of r and s, each of length
324
+ equal to the base point order in bytes (32 for P-256, 66 for P-521).
325
+
326
+ Required curve: P-256 (FIPS 186-3 §D.2.3). Recommended: P-384, P-521.
327
+
328
+ ### Canonicalization
329
+
330
+ All algorithms take octet-stream or node-set, produce octet-stream output.
331
+ Output is UTF-8 (no BOM), NFC. See [XML-C14N], [XML-C14N11], [XML-EXC-C14N].
332
+
333
+ ### Transforms
334
+
335
+ - **base64** (octet→octet, node-set→octet): decodes base64. For node-set input,
336
+ logically applies `self::text()`, sorts by document order, concatenates.
337
+ - **XPath Filtering** (octet|node-set → node-set): evaluates XPath per node,
338
+ includes nodes where boolean result is true. Includes `here()` function.
339
+ - **Enveloped Signature**: removes the containing `Signature` element from
340
+ digest calculation. Equivalent to specific XPath.
341
+ - **XSLT**: octet-stream → octet-stream via XSL stylesheet (sole child).
342
+
343
+ ## XML Canonicalization Considerations
344
+
345
+ Signatures only work if verification uses the same bits as signing. XML surface
346
+ forms vary, so canonicalization standardizes before signing/verification.
347
+
348
+ Categories of change to canonicalize:
349
+ 1. XML 1.0 syntax (line endings, attribute defaults, entity refs, attribute
350
+ normalization).
351
+ 2. DOM/SAX information loss (attribute order, insignificant whitespace, namespace
352
+ declaration locations).
353
+ 3. Charset conversion.
354
+ 4. Namespace inheritance/context.
355
+
356
+ All canonicalization algorithms identified use UTF-8 (no BOM) and do not perform
357
+ character normalization. Applications SHOULD produce content in NFC.
358
+
359
+ ### Namespace Context and Portable Signatures
360
+
361
+ Inclusive canonicalization "attracts" ancestor namespace context, breaking
362
+ signatures when subdocuments are moved. Exclusive canonicalization "repels"
363
+ ancestor context, preserving portability.
364
+
365
+ ## Security Considerations
366
+
367
+ ### 8.1 Transforms
368
+
369
+ - Only what is signed is secure.
370
+ - Only what is "seen" should be signed.
371
+ - "See" what is signed (operate over canonicalized form).
372
+
373
+ ### 8.2 Security Models
374
+
375
+ Public-key signatures vs keyed-hash MACs have different trust models. Public
376
+ keys verify; only private-key holders can sign. MAC keys are shared; any
377
+ verifier can forge.
378
+
379
+ ### 8.3 Algorithms, Key Lengths, Certificates
380
+
381
+ Conforming implementations MUST support RSA signature generation and
382
+ verification with public keys at least 2048 bits. 3072-bit recommended for
383
+ signatures verified beyond 2030.
384
+
385
+ ### 8.4 Error Messages
386
+
387
+ Generic error responses; avoid leaking specifics about algorithm processing.
388
+
389
+ ## References
390
+
391
+ - [XML-C14N] Canonical XML 1.0
392
+ - [XML-C14N11] Canonical XML 1.1
393
+ - [XML-EXC-C14N] Exclusive XML Canonicalization 1.0
394
+ - [PKCS1] RFC 3447 (RSA Cryptography Specifications v2.1)
395
+ - [FIPS-186-3] Digital Signature Standard
396
+ - [FIPS-180-3] Secure Hash Standard
397
+ - [HMAC] RFC 2104
398
+ - [RFC6931] Additional XML Security URIs
399
+ - [XPATH] XML Path Language 1.0
400
+ - [XMLDSIG-BESTPRACTICES] XML Signature Best Practices
@@ -110,10 +110,6 @@ RSpec.shared_examples "README Examples" do
110
110
  describe "Error handling example" do
111
111
  it "handles errors as shown in README" do
112
112
  context = Moxml.new
113
- if context.config.adapter_name == :ox
114
- pending "Ox doesn't have a native XPath"
115
- end
116
-
117
113
  expect do
118
114
  context.parse("<invalid>")
119
115
  end.to raise_error(Moxml::ParseError)
@@ -24,20 +24,12 @@ RSpec.shared_examples "XPath Examples" do
24
24
  end
25
25
 
26
26
  it "finds nodes with namespaces" do
27
- if context.config.adapter_name == :ox
28
- pending "Ox doesn't have a native XPath"
29
- end
30
-
31
27
  titles = doc.xpath("//dc:title",
32
28
  "dc" => "http://purl.org/dc/elements/1.1/")
33
29
  expect(titles.map(&:text)).to eq(%w[First Second])
34
30
  end
35
31
 
36
32
  it "finds nodes by attributes" do
37
- if %i[ox headed_ox].include?(context.config.adapter_name)
38
- pending "Ox doesn't have native XPath, HeadedOx parser doesn't support .// syntax yet"
39
- end
40
-
41
33
  book = doc.at_xpath('//book[@id="2"]')
42
34
  expect(book).not_to be_nil
43
35
  title = book.at_xpath(".//dc:title",
@@ -46,9 +38,6 @@ RSpec.shared_examples "XPath Examples" do
46
38
  end
47
39
 
48
40
  it "finds nested attributes efficiently" do
49
- if %i[ox headed_ox].include?(context.config.adapter_name)
50
- pending "Ox doesn't have native XPath, HeadedOx parser doesn't support .// syntax yet"
51
- end
52
41
  # More efficient - specific path
53
42
  titles1 = doc.xpath("//book/dc:title")
54
43
 
@@ -0,0 +1,28 @@
1
+ -----BEGIN PRIVATE KEY-----
2
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8F3ut738mezjz
3
+ Wg6J11OJCe28lyJXHcb6PbMJVm9NUC3MeMr27PI9s7ildxEodm9bOkXTIGD1ev4Y
4
+ 4p69cjMeyn1vFoxUyE+IN9+0pSVs/ABf19/349MFMTC1mpWlBvRtOKyCkLObQ0hn
5
+ i+lMd4mQ+Ht+6+ZQNpNGIE0HcUUTH/r13AkmYLGYjlf2BwiqLP5MaxsdARormXwJ
6
+ wsJD92us5MHN2P4Pew+J+TyCMdM94h7TCR4vmhZrX7EQcbIfsIEYpfRs3IeORW90
7
+ CoXt7AgLmC+myMt8N/VF6OTKzXrShjGGeF88sikG0GSsIVWy7+tReqe4rfx/iavd
8
+ da0LhPJVAgMBAAECggEAMSugaPmFj11CJ5fg2hcA3v/J9vW5g/WkWTG89pFyek8e
9
+ Eeh4ArIxp4Cuog7s3NuNQ9eJfmZmAnZ7K60+mz7Z71A3F03ZNKbC59TXdeWAUavV
10
+ Ozj3c1nLBf30gl0dhq05Q74/lshWM54UtQEF5bgQLeZPfoATzt9dg8UY7ful95f/
11
+ StU1jJB16r7l8Oy1KyJE094ZL+dYSAaJaG/kb/hq857UJxU/9mmnqq0AsAseXrHm
12
+ 9T4AR5vJjhh71+3BHsQNxP6oO2ErV+Bd4MddMRYZbyo7jVIN6t6nti+uB+reKAi0
13
+ FdcKNL+zldxPyKzt/dXh43M1Y60aFJ9jre/x+aqW9wKBgQDmGrguBixFJiBYdJXw
14
+ NXyIDKDYPRlP3+B28piybne3JVvnyZQ+v5KmDCAtE4i/hIkX9/pdyXAoAfsEI8dc
15
+ sarcFPynMjl+BpBxRKiMgIJvAsRh83HfrkewUTk9uhD3hqW4RlKZZIRlsPuEhIcG
16
+ 2oWJzwuDlRsZyrlqLef94O59FwKBgQDRQmJgZm0faJfIFkmy17iCSmpLCHsef3iJ
17
+ gKr2yQBxOJMwConPauZEQ+YdTjk2XPo81TNpjWyBKZD+1RPPpJ5sFzUAfAqCfsxY
18
+ EZWCzuZKntiegwOsdRrp5FdAFrFCmttW0p5AnTH23PMKxT+7fMDmuwq1X3pS712X
19
+ hGujrnXncwKBgDKKrefWDUVHAZXMTd7MMMVFWNMGYJftycT2tlmC8CK3Pv+jhD9g
20
+ HtsAENU11DSU7PPp0QFmrI7tGHCpVzHiCHB8353t5zjqQjHO7eKmm3+8sNv++AU0
21
+ p6Rvws3vH6ju11mpgJ0WugoIHMbXwTzdJLXHV3UYfDJnF+DdonZeQKQTAoGAIo7K
22
+ /k6MAN7eCg4cN6vGbcXqTd/lrUCx4EtecIj7SLdmH03uOlHWGzn3W6maay7pqHgx
23
+ GGJho+cAagU4U1dFTmZ6u0zA05IrHvQwc7zFbVdUQME0LxvbyPqLqirVNUGrrWf0
24
+ +Ii9Qp50iLfQcZ8FoFUNTKyq391l4Gre99YM5J8CgYEA2EsA5AVf3Q4hkY5ImWN9
25
+ hWgcvKaa1Fw8n59iGExgoh1Zr4p9SWxaNxa/iY3q0wdiQBMihEgFdc3JMBiS3RSe
26
+ KZCpPAFeNW9RnXIQwnW06oyaiZkymLq96cYT5ToSLEoFl9/Z+ulMAYrfRJGszyR+
27
+ hJAW5QUsrp1RKksKftYOAlA=
28
+ -----END PRIVATE KEY-----
@@ -0,0 +1,9 @@
1
+ -----BEGIN PUBLIC KEY-----
2
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvBd7re9/Jns481oOiddT
3
+ iQntvJciVx3G+j2zCVZvTVAtzHjK9uzyPbO4pXcRKHZvWzpF0yBg9Xr+GOKevXIz
4
+ Hsp9bxaMVMhPiDfftKUlbPwAX9ff9+PTBTEwtZqVpQb0bTisgpCzm0NIZ4vpTHeJ
5
+ kPh7fuvmUDaTRiBNB3FFEx/69dwJJmCxmI5X9gcIqiz+TGsbHQEaK5l8CcLCQ/dr
6
+ rOTBzdj+D3sPifk8gjHTPeIe0wkeL5oWa1+xEHGyH7CBGKX0bNyHjkVvdAqF7ewI
7
+ C5gvpsjLfDf1Rejkys160oYxhnhfPLIpBtBkrCFVsu/rUXqnuK38f4mr3XWtC4Ty
8
+ VQIDAQAB
9
+ -----END PUBLIC KEY-----