xmlsig 0.0.1
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.
- data/README.rdoc +0 -0
- data/ext/xmlsig/BioWrap.h +98 -0
- data/ext/xmlsig/DSig.cpp +109 -0
- data/ext/xmlsig/DSig.h +81 -0
- data/ext/xmlsig/DSigCtx.h +72 -0
- data/ext/xmlsig/Exceptions.cpp +151 -0
- data/ext/xmlsig/Exceptions.h +214 -0
- data/ext/xmlsig/Key.cpp +582 -0
- data/ext/xmlsig/Key.h +338 -0
- data/ext/xmlsig/KeyInfoCtx.h +67 -0
- data/ext/xmlsig/KeyStore.cpp +180 -0
- data/ext/xmlsig/KeyStore.h +157 -0
- data/ext/xmlsig/KeysMngrWrap.h +62 -0
- data/ext/xmlsig/NodeSet.h +60 -0
- data/ext/xmlsig/Signer.cpp +691 -0
- data/ext/xmlsig/Signer.h +373 -0
- data/ext/xmlsig/TrustVerifier.cpp +145 -0
- data/ext/xmlsig/TrustVerifier.h +174 -0
- data/ext/xmlsig/Verifier.cpp +677 -0
- data/ext/xmlsig/Verifier.h +313 -0
- data/ext/xmlsig/X509Certificate.cpp +362 -0
- data/ext/xmlsig/X509Certificate.h +146 -0
- data/ext/xmlsig/XPath.cpp +173 -0
- data/ext/xmlsig/XPath.h +156 -0
- data/ext/xmlsig/XPathCtx.h +68 -0
- data/ext/xmlsig/XmlCharBuf.h +60 -0
- data/ext/xmlsig/XmlDoc.cpp +278 -0
- data/ext/xmlsig/XmlDoc.h +157 -0
- data/ext/xmlsig/XmlElement.cpp +151 -0
- data/ext/xmlsig/XmlElement.h +134 -0
- data/ext/xmlsig/countptr.h +260 -0
- data/ext/xmlsig/extconf.rb +58 -0
- data/ext/xmlsig/runtests.rb +23 -0
- data/ext/xmlsig/swig/countptr.i +27 -0
- data/ext/xmlsig/swig/exceptions.i +79 -0
- data/ext/xmlsig/swig/ruby.i +17 -0
- data/ext/xmlsig/swig/xmlsig.i +405 -0
- data/ext/xmlsig/t/tc_cert.rb +34 -0
- data/ext/xmlsig/t/tc_interface.rb +158 -0
- data/ext/xmlsig/t/tc_signer.rb +501 -0
- data/ext/xmlsig/t/tc_tsik.rb +490 -0
- data/ext/xmlsig/t/tc_verifier.rb +151 -0
- data/ext/xmlsig/t/tsik_interop/sign.rb +48 -0
- data/ext/xmlsig/t/tsik_interop/verify.rb +31 -0
- data/ext/xmlsig/t/tsik_interop/verify_own.rb +46 -0
- data/ext/xmlsig/xmlsig.cpp +13363 -0
- data/lib/xmlsig.rb +1 -0
- metadata +113 -0
data/ext/xmlsig/Signer.h
ADDED
@@ -0,0 +1,373 @@
|
|
1
|
+
/*
|
2
|
+
* (C) Copyright 2006 VeriSign, Inc.
|
3
|
+
* Developed by Sxip Identity
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
*
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
* See the License for the specific language governing permissions and
|
15
|
+
* limitations under the License.
|
16
|
+
*/
|
17
|
+
#ifndef _SIGNER_H
|
18
|
+
#define _SIGNER_H
|
19
|
+
|
20
|
+
#include <string>
|
21
|
+
#include <vector>
|
22
|
+
#include <xmlsec/transforms.h>
|
23
|
+
#include "XmlDoc.h"
|
24
|
+
#include "Key.h"
|
25
|
+
#include "XPath.h"
|
26
|
+
#include "KeyStore.h"
|
27
|
+
#include "X509Certificate.h"
|
28
|
+
using namespace std;
|
29
|
+
|
30
|
+
/**
|
31
|
+
* Signer signs XML documents according to the W3C XML-Signature specification (http://www.w3.org/2000/09/xmldsig#).
|
32
|
+
*
|
33
|
+
* There are three modes of operation specified:
|
34
|
+
*
|
35
|
+
* - Enveloping signature, in which the signature is over content
|
36
|
+
* found within an Object element of the signature itself.
|
37
|
+
* - Enveloped signature, in which the original document contains the
|
38
|
+
* signature as an element.
|
39
|
+
* - Detached signature. Similar to Enveloped signature, but the
|
40
|
+
* Signature element is detached from the signed element.
|
41
|
+
*
|
42
|
+
* This implementation supports all three modes of signing. Its usage:
|
43
|
+
*
|
44
|
+
* -# Construct the Signer. You must provide the Signer with
|
45
|
+
* -# the XML document that you want to sign, and
|
46
|
+
* -# the signing key.
|
47
|
+
* Optionally, you can supply the verification key and attach it in the Signature.
|
48
|
+
* -# If desired, add references.
|
49
|
+
* -# Sign the document. Explicitly choose which way to sign, or
|
50
|
+
* accept default, depending on references added. You may supply
|
51
|
+
* a location in the resulting Document where the Signature will
|
52
|
+
* be placed. An enveloping signature will be created if you
|
53
|
+
* provide no location for the signature.
|
54
|
+
*
|
55
|
+
* You can choose whether to sign the document in place, or to
|
56
|
+
* return a new, signed, document, leaving the original intact with
|
57
|
+
* the sign() and signInPlace() APIs.
|
58
|
+
*
|
59
|
+
* Note: An XML document may have several associated signatures, but
|
60
|
+
* this API only supports a single signature. If you need to sign
|
61
|
+
* multiple times, create a new Signer on the result from sign( and
|
62
|
+
* then iterate.
|
63
|
+
*
|
64
|
+
* Example usage (C++):
|
65
|
+
* @code
|
66
|
+
* Signer signer(doc, privateKey, publicKey);
|
67
|
+
*
|
68
|
+
* XPath loc1("id('someID')");
|
69
|
+
* signer.addReference(loc1);
|
70
|
+
*
|
71
|
+
* XPath loc2("/some/element");
|
72
|
+
* signer.addReference(loc2);
|
73
|
+
*
|
74
|
+
* XPath output("/");
|
75
|
+
* XmlDocPtr d = signer.sign(output);
|
76
|
+
* @endcode
|
77
|
+
*
|
78
|
+
* In the example above, we sign a document and implicitly tell it to
|
79
|
+
* add the public verification key to its output. We supply two
|
80
|
+
* locations, loc1 and loc2, to be signed (these locations will be two
|
81
|
+
* references in the resulting signature) and a location, output, where
|
82
|
+
* we want the resulting signature to be placed. Since we supply an
|
83
|
+
* output location, an enveloped signature will be created. If we had
|
84
|
+
* instead signed like this:
|
85
|
+
* @code
|
86
|
+
* Document d = signer.sign();
|
87
|
+
* @endcode
|
88
|
+
*
|
89
|
+
* then we would have forced an enveloping signature.
|
90
|
+
*
|
91
|
+
* Note that this API only allows XPath expressions that evaluate to a
|
92
|
+
* single node. Nor are relative XPath expressions (e.g., "../element")
|
93
|
+
* allowed since the Signature reference's context changes at the time of
|
94
|
+
* signing.
|
95
|
+
*/
|
96
|
+
class Signer
|
97
|
+
{
|
98
|
+
public:
|
99
|
+
/**
|
100
|
+
* Creates a signer with a signing key. No verification key is
|
101
|
+
* added to the signature. The recipient of the signed document
|
102
|
+
* must obtain this key from a source other than the signed
|
103
|
+
* document.
|
104
|
+
* @param doc An XML document
|
105
|
+
* @param key key used to sign the document
|
106
|
+
*/
|
107
|
+
Signer (XmlDocClassPtr doc, KeyPtr key);
|
108
|
+
/**
|
109
|
+
* Creates a Signer with a signing key and a verifying key as part
|
110
|
+
* of the Signature element.
|
111
|
+
* @param doc An XML document
|
112
|
+
* @param key key used to sign the document
|
113
|
+
* @param verifyKey A public or verifying key that will be appended to the signature
|
114
|
+
*/
|
115
|
+
Signer (XmlDocClassPtr doc, KeyPtr key, KeyPtr verifyKey);
|
116
|
+
/**
|
117
|
+
* Creates a Signer with a private key and a certificate that
|
118
|
+
* contains a public key. No verification key is added to the
|
119
|
+
* signature. The recipient of the signed document is assumed to
|
120
|
+
* have knowledge of this key. The certificate passed is appended
|
121
|
+
* to the KeyInfo element.
|
122
|
+
* @param doc An XML document
|
123
|
+
* @param key key used to sign the document
|
124
|
+
* @param cert A certificate containing a public key to include in the signature
|
125
|
+
*/
|
126
|
+
Signer (XmlDocClassPtr doc, KeyPtr key, X509CertificatePtr cert);
|
127
|
+
/**
|
128
|
+
* Creates a Signer with a private key and a certificate
|
129
|
+
* chain. The chain's first element (at index 0) is used for
|
130
|
+
* signing, the rest of the certificates will be appended into the
|
131
|
+
* X509Data element.
|
132
|
+
*
|
133
|
+
* Only the first certificate in the chain will have its Issuer
|
134
|
+
* Serial information, Subject name and SKI copied; the rest of
|
135
|
+
* the certificates will have only the X509Certificate.
|
136
|
+
*
|
137
|
+
* No verification key is added to the signature.
|
138
|
+
*
|
139
|
+
* @param doc An XML document
|
140
|
+
* @param key key used to sign the document
|
141
|
+
* @param cert a X.509 certificate chain that will be output into the resulting document.
|
142
|
+
*/
|
143
|
+
Signer (XmlDocClassPtr doc, KeyPtr key, vector<X509CertificatePtr> cert);
|
144
|
+
/**
|
145
|
+
* Destroy the Signer object.
|
146
|
+
*/
|
147
|
+
~Signer ();
|
148
|
+
|
149
|
+
/**
|
150
|
+
* Signs the document and returns a new document containing a
|
151
|
+
* Signature element enveloping the signed data.
|
152
|
+
* @return a new XmlDoc on success, NULL on failure
|
153
|
+
*/
|
154
|
+
XmlDocClassPtr sign ();
|
155
|
+
/**
|
156
|
+
* Signs the document and inserts the Signature element according
|
157
|
+
* to the XPath expression (appending the resulting
|
158
|
+
* signature). The returned document contains the original
|
159
|
+
* document with a Signature element either enveloped or detached,
|
160
|
+
* depending on whether the references contain the signature.
|
161
|
+
* @param xPath The XPath expression pointing to a single node
|
162
|
+
* that the resulting Signature will be appended to. Note that
|
163
|
+
* it is an error if the xpath expression evaluates to a
|
164
|
+
* NodeList (i.e., must be a single Node)
|
165
|
+
* @return a new XmlDoc on success, NULL on failure
|
166
|
+
*/
|
167
|
+
XmlDocClassPtr sign (XPathPtr xPath);
|
168
|
+
/**
|
169
|
+
* Signs the document and inserts the Signature element according
|
170
|
+
* to the XPath expression (appending the resulting
|
171
|
+
* signature). The returned document contains the original
|
172
|
+
* document with a Signature element either enveloped or detached,
|
173
|
+
* depending on whether the references contain the signature.
|
174
|
+
* @param xPath An XPath expression
|
175
|
+
* @param insertBefore if true, the signature will be inserted before
|
176
|
+
* the resulting node of the xpath expression; if false, the signature
|
177
|
+
* will be appended as a child to the resulting node of the Xpath
|
178
|
+
* expression.
|
179
|
+
* @return a new XmlDoc on success, NULL on failure
|
180
|
+
*/
|
181
|
+
XmlDocClassPtr sign (XPathPtr xPath, bool insertBefore);
|
182
|
+
/**
|
183
|
+
* Signs the document and returns it. The returned document
|
184
|
+
* contains a Signature element enveloping the signed data
|
185
|
+
* (replacing previous contents of document).
|
186
|
+
* @return 0 if success, -1 if something went wrong
|
187
|
+
*/
|
188
|
+
int signInPlace ();
|
189
|
+
/**
|
190
|
+
* Signs the document and inserts the Signature element according
|
191
|
+
* to the XPath expression. The original document will be
|
192
|
+
* returned, amended with a Signature element enveloped or
|
193
|
+
* detached, depending on whether the references contain the
|
194
|
+
* signature.
|
195
|
+
* @param xPath The XPath expression pointing to a single node
|
196
|
+
* that the resulting Signature will be appended to. Note that
|
197
|
+
* it is an error if the xpath expression evaluates to a
|
198
|
+
* NodeList (i.e., must be a single Node)
|
199
|
+
* @return 0 if success, -1 if something went wrong
|
200
|
+
*/
|
201
|
+
int signInPlace (XPathPtr xPath);
|
202
|
+
/**
|
203
|
+
* Signs the document and inserts the Signature element according
|
204
|
+
* to the XPath expression (appending the resulting
|
205
|
+
* signature). The original document containsis returned. It will
|
206
|
+
* contain a Signature element either enveloped or detached,
|
207
|
+
* depending on whether the references contain the signature.
|
208
|
+
* @param xPath The XPath expression pointing to a single node
|
209
|
+
* that the resulting Signature will be appended to. Note that
|
210
|
+
* it is an error if the xpath expression evaluates to a
|
211
|
+
* NodeList (i.e., must be a single Node)
|
212
|
+
* @param insertBefore if true, the signature will be inserted
|
213
|
+
* before the resulting node of the xpath expression; if
|
214
|
+
* false, the signature will be appended as a child to the
|
215
|
+
* resulting node of the Xpath expression.
|
216
|
+
* @return 0 if success, -1 if something went wrong
|
217
|
+
*/
|
218
|
+
int signInPlace (XPathPtr xPath, bool insertBefore);
|
219
|
+
/**
|
220
|
+
* This signer will use the exclusive signature as defined by
|
221
|
+
* http://www.w3.org/2001/10/xml-exc-c14n#.
|
222
|
+
* The exclusive c14n algorithm will be used for canonicalization
|
223
|
+
* of the signature, as well as for all added transformations
|
224
|
+
* The inclusive canonicalization algorithm is the default.
|
225
|
+
* @param prefixes string containing space delimited list of ns
|
226
|
+
* prefixes - the inclusive prefix list as defined by the
|
227
|
+
* specification. Any namespace prefix in the list that are
|
228
|
+
* not visibly used in the context will be silently ignored.
|
229
|
+
* @return 0 if success, -1 if something went wrong
|
230
|
+
*/
|
231
|
+
int useExclusiveCanonicalizer (string prefixes);
|
232
|
+
/**
|
233
|
+
* Adds a reference to an existing set of Elements in the
|
234
|
+
* document. These elements will be part of the data to be
|
235
|
+
* signed. Validation of the XPath expression occurs at signing
|
236
|
+
* time.
|
237
|
+
* @param xPath An XPath expression
|
238
|
+
*/
|
239
|
+
void addReference (XPathPtr xPath);
|
240
|
+
/**
|
241
|
+
* Specify that you want to attach a public key to the signature when
|
242
|
+
* sign() or signInPlace() is called. In the case of a DSA or RSA private
|
243
|
+
* key, this will cause the public key to be extracted from the private key
|
244
|
+
* and attached. This can only be done for asymmetric keys. Setting a true value
|
245
|
+
* here will not cause a symmetric key to be attached (e.g. HMAC).
|
246
|
+
*
|
247
|
+
* Default is to not attach the public key.
|
248
|
+
*
|
249
|
+
* @param value - 1 = attach a public key, 0 - don't attach.
|
250
|
+
*/
|
251
|
+
void attachPublicKey (int value);
|
252
|
+
/**
|
253
|
+
* Use key from a KeyStore to sign the signature.
|
254
|
+
* @param keyStore A key store
|
255
|
+
* @return 0 on success, -1 on error
|
256
|
+
*/
|
257
|
+
int setKeyStore (KeyStorePtr keyStore);
|
258
|
+
/**
|
259
|
+
* Add a certificate to the signature from a file.
|
260
|
+
* @param fileName File containing an X509 Certificate
|
261
|
+
* @param format Key data format string (see Key::loadFromFile() for format list)
|
262
|
+
* @return 0 if success, -1 if something went wrong
|
263
|
+
*/
|
264
|
+
int addCertFromFile (string fileName, string format);
|
265
|
+
/**
|
266
|
+
* Add a certificate to the signature.
|
267
|
+
* @param cert An X509 certificate object
|
268
|
+
* @return 0 if success, -1 if something went wrong
|
269
|
+
*/
|
270
|
+
int addCert (X509CertificatePtr cert);
|
271
|
+
|
272
|
+
/// @cond NO_INTERFACE
|
273
|
+
protected:
|
274
|
+
/**
|
275
|
+
* The XML Document.
|
276
|
+
*/
|
277
|
+
XmlDocClassPtr mXmlDoc;
|
278
|
+
/**
|
279
|
+
* The private key.
|
280
|
+
*/
|
281
|
+
KeyPtr mKey;
|
282
|
+
/**
|
283
|
+
* The verifiying key
|
284
|
+
*/
|
285
|
+
KeyPtr mVerifyKey;
|
286
|
+
/**
|
287
|
+
* XPath references
|
288
|
+
*/
|
289
|
+
vector<XPath> xPathRefs;
|
290
|
+
/**
|
291
|
+
* Flag for exclusive c14n
|
292
|
+
*/
|
293
|
+
int c14n_excl;
|
294
|
+
/**
|
295
|
+
* Inclusive ns prefixes for exclusive c14n
|
296
|
+
*/
|
297
|
+
string c14n_excl_incprefixes;
|
298
|
+
/**
|
299
|
+
* Should we add a keyInfo node?
|
300
|
+
*/
|
301
|
+
int mAddKeyInfo;
|
302
|
+
/**
|
303
|
+
* Should we add a keyValue node?
|
304
|
+
*/
|
305
|
+
int mAddKeyValue;
|
306
|
+
/**
|
307
|
+
* KeyStore
|
308
|
+
*/
|
309
|
+
KeyStorePtr keyStore;
|
310
|
+
|
311
|
+
/**
|
312
|
+
* Return c14n method based on exclusive flag
|
313
|
+
* @return c14n method id
|
314
|
+
*/
|
315
|
+
xmlSecTransformId c14nMethod () const;
|
316
|
+
/**
|
317
|
+
* Apply c14n method to reference element as transform
|
318
|
+
* @param refNode reference element in signature template
|
319
|
+
* @return result transform element, or null if error
|
320
|
+
*/
|
321
|
+
xmlNodePtr c14nMethodTransform (xmlNodePtr refNode);
|
322
|
+
/**
|
323
|
+
* Check if reference element is enveloped in associated XPath expression
|
324
|
+
* @param refNode
|
325
|
+
* @param xPath
|
326
|
+
* @return 1 if enveloped, 0 if not, negative on error
|
327
|
+
*/
|
328
|
+
int isEnveloped (xmlNodePtr refNode, XPath& xPath);
|
329
|
+
/**
|
330
|
+
* Return true if a certificate has been attached to the
|
331
|
+
* signing key.
|
332
|
+
* @return 1 if a certificate exists, 0 if not, negative on error
|
333
|
+
*/
|
334
|
+
int certAdded ();
|
335
|
+
/**
|
336
|
+
* Validate the set of XPath references on the current document
|
337
|
+
* @return true if all XPath expressions are valid
|
338
|
+
*/
|
339
|
+
int validateXPathRefs ();
|
340
|
+
/**
|
341
|
+
* Evaluate the XPath expression and return the element referred to
|
342
|
+
* The expression must refer to a single node.
|
343
|
+
* @param xPath An XPath expression
|
344
|
+
* @return a node pointer, null on error
|
345
|
+
*/
|
346
|
+
xmlNodePtr locateSignature (XPathPtr xPath);
|
347
|
+
/**
|
348
|
+
* Check for a pre-existing signature element on the given node
|
349
|
+
*/
|
350
|
+
xmlNodePtr checkForSignatureElement (xmlNodePtr node, int insertBefore);
|
351
|
+
/**
|
352
|
+
* Create a new signature template
|
353
|
+
* @param doc A raw xml document pointer
|
354
|
+
* @param node the node following which the signature node should be created;
|
355
|
+
* if null, assume an enveloping signature
|
356
|
+
* @param insertBefore if true, the signature will be inserted before
|
357
|
+
* the resulting node of the xpath expression; if false, the signature
|
358
|
+
* will be appended as a child to the resulting node of the Xpath
|
359
|
+
* expression.
|
360
|
+
* @return the signature node pointer, null on failure
|
361
|
+
*/
|
362
|
+
xmlNodePtr createTemplate (xmlDocPtr doc, xmlNodePtr node = 0,
|
363
|
+
bool insertBefore = false);
|
364
|
+
/**
|
365
|
+
* Signs the document at the specified signature node.
|
366
|
+
* @param sigNode signature node
|
367
|
+
* @return 0 if success, -1 if something went wrong
|
368
|
+
*/
|
369
|
+
int signNode (xmlNodePtr sigNode);
|
370
|
+
/// @endcond
|
371
|
+
};
|
372
|
+
|
373
|
+
#endif // _SIGNER_H
|
@@ -0,0 +1,145 @@
|
|
1
|
+
/*
|
2
|
+
* (C) Copyright 2006 VeriSign, Inc.
|
3
|
+
* Developed by Sxip Identity
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
*
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
* See the License for the specific language governing permissions and
|
15
|
+
* limitations under the License.
|
16
|
+
*/
|
17
|
+
#include <iostream>
|
18
|
+
#include <string>
|
19
|
+
#include <vector>
|
20
|
+
#include <libxml/tree.h>
|
21
|
+
#include <libxml/parser.h>
|
22
|
+
#include <stdio.h>
|
23
|
+
#include <errno.h>
|
24
|
+
#include <assert.h>
|
25
|
+
#include <xmlsec/xmltree.h>
|
26
|
+
#include <xmlsec/openssl/x509.h>
|
27
|
+
#include "TrustVerifier.h"
|
28
|
+
#include "XmlCharBuf.h"
|
29
|
+
#include "KeyInfoCtx.h"
|
30
|
+
#include "Exceptions.h"
|
31
|
+
using namespace std;
|
32
|
+
|
33
|
+
|
34
|
+
int TrustVerifier::verifyTrust ()
|
35
|
+
{
|
36
|
+
THROW(TrustVerificationError, "Unable to trust key absence.", 0);
|
37
|
+
}
|
38
|
+
|
39
|
+
|
40
|
+
int TrustVerifier::verifyTrust (KeyPtr)
|
41
|
+
{
|
42
|
+
return 0;
|
43
|
+
}
|
44
|
+
|
45
|
+
|
46
|
+
int TrustVerifier::verifyTrust (vector<X509CertificatePtr>)
|
47
|
+
{
|
48
|
+
return 0;
|
49
|
+
}
|
50
|
+
|
51
|
+
|
52
|
+
SimpleTrustVerifier::SimpleTrustVerifier (vector<KeyPtr> keys)
|
53
|
+
: keys (keys)
|
54
|
+
{}
|
55
|
+
|
56
|
+
|
57
|
+
SimpleTrustVerifier::~SimpleTrustVerifier ()
|
58
|
+
{}
|
59
|
+
|
60
|
+
|
61
|
+
int SimpleTrustVerifier::verifyTrust (KeyPtr key)
|
62
|
+
{
|
63
|
+
for (vector<KeyPtr>::iterator keyIter = keys.begin();
|
64
|
+
keyIter != keys.end(); keyIter++)
|
65
|
+
{
|
66
|
+
if (*key == **keyIter)
|
67
|
+
{
|
68
|
+
return 1;
|
69
|
+
}
|
70
|
+
}
|
71
|
+
THROW(TrustVerificationError,
|
72
|
+
"Key to check is not in the collection of trusted keys", 0);
|
73
|
+
}
|
74
|
+
|
75
|
+
|
76
|
+
int SimpleTrustVerifier::verifyTrust (vector<X509CertificatePtr> chain)
|
77
|
+
{
|
78
|
+
if (chain.size() < 1)
|
79
|
+
{
|
80
|
+
THROW(KeyError, "No certificates in chain", -1);
|
81
|
+
}
|
82
|
+
return verifyTrust(chain[0]->getKey());
|
83
|
+
}
|
84
|
+
|
85
|
+
|
86
|
+
X509TrustVerifier::X509TrustVerifier (vector<X509CertificatePtr> certCollection)
|
87
|
+
: certs(certCollection)
|
88
|
+
{
|
89
|
+
for (vector<X509CertificatePtr>::iterator certIter = certs.begin();
|
90
|
+
certIter != certs.end(); certIter++)
|
91
|
+
{
|
92
|
+
keyStore.addTrustedCert(*certIter);
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
|
97
|
+
X509TrustVerifier::~X509TrustVerifier ()
|
98
|
+
{}
|
99
|
+
|
100
|
+
|
101
|
+
int X509TrustVerifier::verifyTrust (KeyPtr key)
|
102
|
+
{
|
103
|
+
for (vector<X509CertificatePtr>::iterator certIter = certs.begin();
|
104
|
+
certIter != certs.end(); certIter++)
|
105
|
+
{
|
106
|
+
KeyPtr certKey((*certIter)->getKey());
|
107
|
+
if (key->hasSameValues(*certKey))
|
108
|
+
{
|
109
|
+
return 1;
|
110
|
+
}
|
111
|
+
}
|
112
|
+
THROW(TrustVerificationError,
|
113
|
+
"Key to check is not in the collection of trusted certificates", 0);
|
114
|
+
}
|
115
|
+
|
116
|
+
|
117
|
+
int X509TrustVerifier::verifyTrust (vector<X509CertificatePtr> chain)
|
118
|
+
{
|
119
|
+
KeyInfoCtx keyInfoCtx (keyStore);
|
120
|
+
xmlSecKeyDataStorePtr store = xmlSecKeysMngrGetDataStore(keyStore,
|
121
|
+
xmlSecOpenSSLX509StoreId);
|
122
|
+
if ((store == NULL) || !xmlSecKeyDataStoreIsValid(store))
|
123
|
+
{
|
124
|
+
THROW(LibError, "Failed to retrieve keystore data", -1);
|
125
|
+
}
|
126
|
+
STACK_OF(X509)* crl = sk_X509_new_null();
|
127
|
+
STACK_OF(X509)* stack = sk_X509_new_null();
|
128
|
+
if (!stack)
|
129
|
+
{
|
130
|
+
THROW(LibError, "Failed to allocate certificate stack", -1);
|
131
|
+
}
|
132
|
+
for (vector<X509CertificatePtr>::iterator certIter = chain.begin();
|
133
|
+
certIter != chain.end(); certIter++)
|
134
|
+
{
|
135
|
+
sk_X509_push(stack, (*certIter)->getDup());
|
136
|
+
}
|
137
|
+
X509* verifiedCert = xmlSecOpenSSLX509StoreVerify(store, stack, crl, keyInfoCtx);
|
138
|
+
sk_X509_free(stack);
|
139
|
+
if (!verifiedCert)
|
140
|
+
{
|
141
|
+
THROW(TrustVerificationError,
|
142
|
+
"Certificate chain does not connect to a trusted authority", 0);
|
143
|
+
}
|
144
|
+
return 1;
|
145
|
+
}
|
@@ -0,0 +1,174 @@
|
|
1
|
+
/*
|
2
|
+
* (C) Copyright 2006 VeriSign, Inc.
|
3
|
+
* Developed by Sxip Identity
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
*
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
* See the License for the specific language governing permissions and
|
15
|
+
* limitations under the License.
|
16
|
+
*/
|
17
|
+
#ifndef _TRUSTVERIFIER_H
|
18
|
+
#define _TRUSTVERIFIER_H
|
19
|
+
|
20
|
+
#include <string>
|
21
|
+
#include <vector>
|
22
|
+
#include "Key.h"
|
23
|
+
#include "X509Certificate.h"
|
24
|
+
#include "KeyStore.h"
|
25
|
+
using namespace std;
|
26
|
+
|
27
|
+
/**
|
28
|
+
* Checks whether a given public key or certificate chain is
|
29
|
+
* trusted. Using this interface allows the trust policy to be
|
30
|
+
* decoupled from the various entities that need to verify trust.
|
31
|
+
*
|
32
|
+
* To comply with this interface's contract, users should call the
|
33
|
+
* method that gives the most information. Depending on the
|
34
|
+
* information available, choose a method based on the following list
|
35
|
+
* in decreasing order of preferred usage.
|
36
|
+
*
|
37
|
+
* -# Call verifyTrust(vector<X509CertificatePtr>) if one or more certificates
|
38
|
+
* are available.
|
39
|
+
* -# Call verifyTrust(KeyPtr,std::string) if a public key and an XML
|
40
|
+
* Signature key name are both available.
|
41
|
+
* -# Call verifyTrust(KeyPtr) if only a public key is available.
|
42
|
+
* -# Call verifyTrust() if no trust material is available.
|
43
|
+
*/
|
44
|
+
class TrustVerifier
|
45
|
+
{
|
46
|
+
public:
|
47
|
+
TrustVerifier ()
|
48
|
+
{}
|
49
|
+
virtual ~TrustVerifier ()
|
50
|
+
{}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* Verifies that the absence of a key or certificate (e.g., an
|
54
|
+
* unsigned message) can be trusted. Returns silently if the
|
55
|
+
* message is trusted, or throws an exception if not.
|
56
|
+
*
|
57
|
+
* TrustVerifier does not consider the absence of a key or
|
58
|
+
* certificate to be trusted and will always throw an exception
|
59
|
+
* when this method is called.
|
60
|
+
*
|
61
|
+
* @return <0 on error
|
62
|
+
* @throws TrustVerificationError if unable to trust the absence of a key
|
63
|
+
*/
|
64
|
+
virtual int verifyTrust ();
|
65
|
+
/**
|
66
|
+
* Verifies that a public key is trusted. Returns silently if the
|
67
|
+
* key is trusted, or throws an exception indicating the reason it
|
68
|
+
* is not.
|
69
|
+
* @param key the public key to check
|
70
|
+
* @return <0 on error, 0 on failure to verify, 1 on verification passed
|
71
|
+
* @throws TrustVerificationError if unable to trust the public key
|
72
|
+
*/
|
73
|
+
virtual int verifyTrust (KeyPtr key);
|
74
|
+
/**
|
75
|
+
* Verifies that a certificate chain is trusted. The chain must be
|
76
|
+
* presented in order from leaf entity toward root CA, such that
|
77
|
+
* for all i, 0 <= i < (chain.length - 1) implies
|
78
|
+
* chain[i].verify(chain[i+1].getPublicKey()) will
|
79
|
+
* succeed. Returns silently if the chain is trusted, or throws an
|
80
|
+
* exception indicating the reason if not.
|
81
|
+
* @param chain certificate chain
|
82
|
+
* @return <0 on error, 0 on failure to verify, 1 on verification passed
|
83
|
+
* @throws TrustVerificationError f the given chain cannot be
|
84
|
+
* trusted, or if an error occurs while trying to determine trust
|
85
|
+
*/
|
86
|
+
virtual int verifyTrust (vector<X509CertificatePtr> chain);
|
87
|
+
};
|
88
|
+
|
89
|
+
|
90
|
+
/**
|
91
|
+
* A simple TrustVerifier implementation based on a collection of
|
92
|
+
* trusted public keys.
|
93
|
+
*
|
94
|
+
* A key is trusted if it is in the trusted collection; a certificate
|
95
|
+
* chain is trusted if the public key of the leaf certificate is in
|
96
|
+
* the trusted collection.
|
97
|
+
*
|
98
|
+
* When verifyTrust() is called, an exception is always thrown by this
|
99
|
+
* class.
|
100
|
+
*/
|
101
|
+
class SimpleTrustVerifier : public TrustVerifier
|
102
|
+
{
|
103
|
+
public:
|
104
|
+
/**
|
105
|
+
* Create the SimpleTrustVerifier with a set of trusted keys.
|
106
|
+
* @param keys a set of trusted public keys
|
107
|
+
*/
|
108
|
+
SimpleTrustVerifier (vector<KeyPtr> keys);
|
109
|
+
/**
|
110
|
+
* Destroy the SimpleTrustVerifier.
|
111
|
+
*/
|
112
|
+
~SimpleTrustVerifier ();
|
113
|
+
|
114
|
+
/// @copydoc TrustVerifier::verifyTrust()
|
115
|
+
int verifyTrust ()
|
116
|
+
{
|
117
|
+
return TrustVerifier::verifyTrust();
|
118
|
+
}
|
119
|
+
/// @copydoc TrustVerifier::verifyTrust(KeyPtr)
|
120
|
+
int verifyTrust (KeyPtr key);
|
121
|
+
/// @copydoc TrustVerifier::verifyTrust(vector<X509CertificatePtr>)
|
122
|
+
int verifyTrust (vector<X509CertificatePtr> chain);
|
123
|
+
|
124
|
+
/// @cond NO_INTERFACE
|
125
|
+
protected:
|
126
|
+
vector<KeyPtr> keys;
|
127
|
+
/// @endcond
|
128
|
+
};
|
129
|
+
|
130
|
+
|
131
|
+
/**
|
132
|
+
* A trust verifier based on a collection of trusted certificates. A
|
133
|
+
* KeyStore may be passed to the X509TrustVerifier constructor to use
|
134
|
+
* the trusted certificates stored in the KeyStore.
|
135
|
+
*
|
136
|
+
* A key is trusted if it is the public key of one of the trusted
|
137
|
+
* certificates; a certificate chain is trusted if it can be traced
|
138
|
+
* back to a trusted certificate.
|
139
|
+
*
|
140
|
+
* When verifyTrust() is called, an exception is always thrown by this
|
141
|
+
* class.
|
142
|
+
*/
|
143
|
+
class X509TrustVerifier : public TrustVerifier
|
144
|
+
{
|
145
|
+
public:
|
146
|
+
/**
|
147
|
+
* Create the X509TrustVerifier object with a collection of
|
148
|
+
* trusted certificates.
|
149
|
+
* @param certs A list of trusted certificates
|
150
|
+
*/
|
151
|
+
X509TrustVerifier (vector<X509CertificatePtr> certs);
|
152
|
+
/**
|
153
|
+
* Destroy the X509TrustVerifier.
|
154
|
+
*/
|
155
|
+
~X509TrustVerifier ();
|
156
|
+
|
157
|
+
/// @copydoc TrustVerifier::verifyTrust()
|
158
|
+
int verifyTrust ()
|
159
|
+
{
|
160
|
+
return TrustVerifier::verifyTrust();
|
161
|
+
}
|
162
|
+
/// @copydoc TrustVerifier::verifyTrust(KeyPtr)
|
163
|
+
int verifyTrust (KeyPtr key);
|
164
|
+
/// @copydoc TrustVerifier::verifyTrust(vector<X509CertificatePtr>)
|
165
|
+
int verifyTrust (vector<X509CertificatePtr> chain);
|
166
|
+
|
167
|
+
/// @cond NO_INTERFACE
|
168
|
+
protected:
|
169
|
+
vector<X509CertificatePtr> certs;
|
170
|
+
KeyStore keyStore;
|
171
|
+
/// @endcond
|
172
|
+
};
|
173
|
+
|
174
|
+
#endif // _TRUSTVERIFIER_H
|