-
Notifications
You must be signed in to change notification settings - Fork 2
/
README
324 lines (242 loc) · 11.2 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
NAME
XML::Sig - XML::Sig - A toolkit to help sign and verify XML Digital
Signatures
VERSION
version 0.65
SYNOPSIS
my $xml = '<foo ID="abc">123</foo>';
my $signer = XML::Sig->new({
key => 'path/to/private.key',
});
# create a signature
my $signed = $signer->sign($xml);
print "Signed XML: $signed\n";
# verify a signature
$signer->verify($signed)
or die "Signature Invalid.";
print "Signature valid.\n";
DESCRIPTION
This perl module provides two primary capabilities: given an XML string,
create and insert digital signatures, or if one is already present in
the string verify it -- all in accordance with the W3C standard
governing XML signatures.
NAME
XML::Sig - A toolkit to help sign and verify XML Digital Signatures.
PREREQUISITES
* Digest::SHA
* XML::LibXML
* MIME::Base64
* Crypt::OpenSSL::X509
* Crypt::OpenSSL::Bignum
* Crypt::OpenSSL::RSA
* Crypt::OpenSSL::DSA
* Crypt::PK::ECC
USAGE
SUPPORTED ALGORITHMS & TRANSFORMS
This module supports the following signature methods:
* DSA
* RSA
* RSA encoded as x509
* ECDSA
* ECDSA encoded as x509
* HMAC
This module supports the following canonicalization methods and
transforms:
* Enveloped Signature
* REC-xml-c14n-20010315#
* REC-xml-c14n-20010315#WithComments
* REC-xml-c14n11-20080502
* REC-xml-c14n11-20080502#WithComments
* xml-exc-c14n#
* xml-exc-c14n#WithComments
OPTIONS
Each of the following options are also accessors on the main XML::Sig
object. TODO Not strictly correct rewrite
key The path to a file containing the contents of a private key. This
option is used only when generating signatures.
cert
The path to a file containing a PEM-formatted X509 certificate. This
option is used only when generating signatures with the "x509"
option. This certificate will be embedded in the signed document,
and should match the private key used for the signature.
cert_text
A string containing a PEM-formatted X509 certificate. This option is
used only when generating signatures with the "x509" option. This
certificate will be embedded in the signed document, and should
match the private key used for the signature.
x509
Takes a true (1) or false (0) value and indicates how you want the
signature to be encoded. When true, the X509 certificate supplied
will be encoded in the signature. Otherwise the native encoding
format for RSA, DSA and ECDSA will be used.
sig_hash
Passing sig_hash to new allows you to specify the SignatureMethod
hashing algorithm used when signing the SignedInfo. RSA and ECDSA
supports the hashes specified sha1, sha224, sha256, sha384 and
sha512
DSA supports only sha1 and sha256 (but you really should not sign
anything with DSA anyway). This is over-ridden by the key's
signature size which is related to the key size. 1024-bit keys
require sha1, 2048-bit and 3072-bit keys require sha256.
digest_hash
Passing digest_hash to new allows you to specify the DigestMethod
hashing algorithm used when calculating the hash of the XML being
signed. Supported hashes can be specified sha1, sha224, sha256,
sha384, sha512, ripemd160
hmac_key
Base64 encoded hmac_key
key_name
The name of the key that should be referenced. In the case of xmlsec
the --keys-file (ex. t/xmlsec-keys.xml) holds keys with a KeyName
that is referenced by this name.
no_xml_declaration
Some applications such as Net::SAML2 expect to sign a fragment of
the full XML document so is this is true (1) it will not include the
XML Declaration at the beginning of the signed XML. False (0) or
undefined returns an XML document starting with the XML Declaration.
The following options act similar to "xmlsec --id-attr:ID
<node-namespace-uri>:<name>"
ns A HashRef to namespaces you want to define to select the correct
attribute ID on
id_attr
The xpath string you want to sign your XML message on.
METHODS
new(...)
Constructor; see OPTIONS above.
sign($xml)
When given a string of XML, it will return the same string with a
signature generated from the key provided when the XML::Sig object was
initialized.
This method will sign all elements in your XML with an ID (case
sensitive) attribute. Each element with an ID attribute will be the
basis for a seperate signature. It will correspond to the URI attribute
in the Reference element that will be contained by the signature. If no
ID attribute can be found on an element, the signature will not be
created.
The elements are signed in reverse order currently assuming (possibly
incorrectly) that the lower element in the tree may need to be signed
inclusive of its Signature because it is a child of the higher element.
Arguments: $xml: string XML string
Returns: string Signed XML
verify($xml)
Returns true or false based upon whether the signature is valid or not.
When using XML::Sig exclusively to verify a signature, no key needs to
be specified during initialization given that the public key should be
transmitted with the signature.
XML::Sig checks all signature in the provided xml and will fail should
any signature pointing to an existing ID in the XML fail to verify.
Should there be a Signature included that does not point to an existing
node in the XML it is ignored and other Signaures are checked. If there
are no other Signatures it will return false.
Arguments: $xml: string XML string
Returns: string Signed XML
signer_cert()
Following a successful verify with an X509 certificate, returns the
signer's certificate as embedded in the XML document for verification
against a CA certificate. The certificate is returned as a
Crypt::OpenSSL::X509 object.
Arguments: none
Returns: Crypt::OpenSSL::X509: Certificate used to sign the XML
ABOUT DIGITAL SIGNATURES
Just as one might want to send an email message that is
cryptographically signed in order to give the recipient the means to
independently verify who sent the email, one might also want to sign an
XML document. This is especially true in the scenario where an XML
document is received in an otherwise unauthenticated context, e.g. SAML.
However XML provides a challenge that email does not. In XML, two
documents can be byte-wise inequivalent, and semanticaly equivalent at
the same time. For example:
<?xml version="1.0"?>
<foo>
<bar />
</foo>
And:
<?xml version="1.0"?>
<foo>
<bar></bar>
</foo>
Each of these document express the same thing, or in other words they
"mean" the same thing. However if you were to strictly sign the raw text
of these documents, they would each produce different signatures.
XML Signatures on the other hand will produce the same signature for
each of the documents above. Therefore an XML document can be written
and rewritten by different parties and still be able to have someone at
the end of the line verify a signature the document may contain.
There is a specially subscribed methodology for how this process should
be executed and involves transforming the XML into its canonical form so
a signature can be reliably inserted or extracted for verification. This
module implements that process.
EXAMPLE SIGNATURE
Below is a sample XML signature to give you some sense of what they look
like. First let's look at the original XML document, prior to being
signed:
<?xml version="1.0"?>
<foo ID="abc">
<bar>123</bar>
</foo>
Now, let's insert a signature:
<?xml version="1.0"?>
<foo ID="abc">
<bar>123</bar>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo xmlns="http://www.w3.org/2000/09/xmldsig#" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#abc">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>9kpmrvv3peVJpNSTRycrV+jeHVY=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
HXUBnMgPJf//j4ihaWnaylNwAR5AzDFY83HljFIlLmTqX1w1C72ZTuRObvYve8TNEbVsQlTQkj4R
hiY0pgIMQUb75GLYFtc+f0YmBZf5rCWY3NWzo432D3ogAvpEzYXEQPmicWe2QozQhybaz9/wrYki
XiXY+57fqCkf7aT8Bb6G+fn7Aj8gnZFLkmKxwCdyGsIZOIZdQ8MWpeQrifxBR0d8W1Zm6ix21WNv
ONt575h7VxLKw8BDhNPS0p8CS3hOnSk29stpiDMCHFPxAwrbKVL1kGDLaLZn1q8nNRmH8oFxG15l
UmS3JXDZAss8gZhU7g9T4XllCqjrAvzPLOFdeQ==
</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>
1b+m37u3Xyawh2ArV8txLei251p03CXbkVuWaJu9C8eHy1pu87bcthi+T5WdlCPKD7KGtkKn9vq
i4BJBZcG/Y10e8KWVlXDLg9gibN5hb0Agae3i1cCJTqqnQ0Ka8w1XABtbxTimS1B0aO1zYW6d+U
Yl0xIeAOPsGMfWeu1NgLChZQton1/NrJsKwzMaQy1VI8m4gUleit9Z8mbz9bNMshdgYEZ9oC4bH
n/SnA4FvQl1fjWyTpzL/aWF/bEzS6Qd8IBk7yhcWRJAGdXTWtwiX4mXb4h/2sdrSNvyOsd/shCf
OSMsf0TX+OdlbH079AsxOwoUjlzjuKdCiFPdU6yAJw==
</Modulus>
<Exponent>Iw==</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
</foo>
SEE ALSO
<http://www.w3.org/TR/xmldsig-core/>
VERSION CONTROL
<https://github.com/perl-net-saml2/perl-XML-Sig>
AUTHORS and CREDITS
Author: Byrne Reese <byrne@majordojo.com>
Thanks to Manni Heumann who wrote Google::SAML::Response from which this
module borrows heavily in order to create digital signatures.
Net::SAML2 embedded version amended by Chris Andrews <chris@nodnol.org>.
Maintainer: Timothy Legge <timlegge@cpan.org>
AUTHORS
* Byrne Reese <byrne@cpan.org>
* Timothy Legge <timlegge@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2023 by Byrne Reese, Chris Andrews and
Others; in detail:
Copyright 2009 Byrne, Michael Hendricks
2010 Chris Andrews
2011 Chris Andrews, Oskari Okko Ojala
2012 Chris Andrews, Peter Marschall
2015 Mike Wisener
2016 Jeff Fearn
2017 Mike Wisener, xmikew
2019-2021 Timothy Legge
2022-2023 Timothy Legge, Wesley Schwengle
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.