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.
Files changed (48) hide show
  1. data/README.rdoc +0 -0
  2. data/ext/xmlsig/BioWrap.h +98 -0
  3. data/ext/xmlsig/DSig.cpp +109 -0
  4. data/ext/xmlsig/DSig.h +81 -0
  5. data/ext/xmlsig/DSigCtx.h +72 -0
  6. data/ext/xmlsig/Exceptions.cpp +151 -0
  7. data/ext/xmlsig/Exceptions.h +214 -0
  8. data/ext/xmlsig/Key.cpp +582 -0
  9. data/ext/xmlsig/Key.h +338 -0
  10. data/ext/xmlsig/KeyInfoCtx.h +67 -0
  11. data/ext/xmlsig/KeyStore.cpp +180 -0
  12. data/ext/xmlsig/KeyStore.h +157 -0
  13. data/ext/xmlsig/KeysMngrWrap.h +62 -0
  14. data/ext/xmlsig/NodeSet.h +60 -0
  15. data/ext/xmlsig/Signer.cpp +691 -0
  16. data/ext/xmlsig/Signer.h +373 -0
  17. data/ext/xmlsig/TrustVerifier.cpp +145 -0
  18. data/ext/xmlsig/TrustVerifier.h +174 -0
  19. data/ext/xmlsig/Verifier.cpp +677 -0
  20. data/ext/xmlsig/Verifier.h +313 -0
  21. data/ext/xmlsig/X509Certificate.cpp +362 -0
  22. data/ext/xmlsig/X509Certificate.h +146 -0
  23. data/ext/xmlsig/XPath.cpp +173 -0
  24. data/ext/xmlsig/XPath.h +156 -0
  25. data/ext/xmlsig/XPathCtx.h +68 -0
  26. data/ext/xmlsig/XmlCharBuf.h +60 -0
  27. data/ext/xmlsig/XmlDoc.cpp +278 -0
  28. data/ext/xmlsig/XmlDoc.h +157 -0
  29. data/ext/xmlsig/XmlElement.cpp +151 -0
  30. data/ext/xmlsig/XmlElement.h +134 -0
  31. data/ext/xmlsig/countptr.h +260 -0
  32. data/ext/xmlsig/extconf.rb +58 -0
  33. data/ext/xmlsig/runtests.rb +23 -0
  34. data/ext/xmlsig/swig/countptr.i +27 -0
  35. data/ext/xmlsig/swig/exceptions.i +79 -0
  36. data/ext/xmlsig/swig/ruby.i +17 -0
  37. data/ext/xmlsig/swig/xmlsig.i +405 -0
  38. data/ext/xmlsig/t/tc_cert.rb +34 -0
  39. data/ext/xmlsig/t/tc_interface.rb +158 -0
  40. data/ext/xmlsig/t/tc_signer.rb +501 -0
  41. data/ext/xmlsig/t/tc_tsik.rb +490 -0
  42. data/ext/xmlsig/t/tc_verifier.rb +151 -0
  43. data/ext/xmlsig/t/tsik_interop/sign.rb +48 -0
  44. data/ext/xmlsig/t/tsik_interop/verify.rb +31 -0
  45. data/ext/xmlsig/t/tsik_interop/verify_own.rb +46 -0
  46. data/ext/xmlsig/xmlsig.cpp +13363 -0
  47. data/lib/xmlsig.rb +1 -0
  48. metadata +113 -0
@@ -0,0 +1,313 @@
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 _VERIFIER_H
18
+ #define _VERIFIER_H
19
+ #include <vector>
20
+ #include "Key.h"
21
+ #include "XmlDoc.h"
22
+ #include "XPath.h"
23
+ #include "KeyStore.h"
24
+ #include "X509Certificate.h"
25
+ #include "XmlElement.h"
26
+ #include "Exceptions.h"
27
+ #include "NodeSet.h"
28
+ using namespace std;
29
+
30
+
31
+ /**
32
+ * Verifier verifies XML signatures according to the W3C XML-Signature specification (http://www.w3.org/2000/09/xmldsig#).
33
+ *
34
+ * A DOM document may contain several signatures. This class can
35
+ * verify all signatures in a document, one at a time, with either the
36
+ * verification key supplied in the document, or with a user-supplied
37
+ * key.
38
+ *
39
+ * Usage:
40
+ *
41
+ * -# Construct the Verifier. You must provide the Verifier with
42
+ * -# the XML document that contains the signature
43
+ * -# (optional) the location of the signature within the XML
44
+ * document. To provide the location of the signature within an
45
+ * XML document, you must use an XPath expression. For more on
46
+ * constructing XPaths, see http://www.w3.org/TR/xpath. If no
47
+ * location is specified, Verifier will attempt to verify the
48
+ * first Signature element it finds in the document.
49
+ * -# Supply the verification key. This key may be taken from the
50
+ * document (if available) by default, or a specific key may be
51
+ * supplied by the user.
52
+ * -# Verify the signature. Note that the Verifier will locate and
53
+ * verify the signature specified in Step 1.
54
+ *
55
+ * Note: An XML document may contain several signatures, but this API
56
+ * only supports verification of one signature per Verifier. If you
57
+ * need to verify multiple signatures, create a new Verifier for each
58
+ * signature.
59
+ *
60
+ * Example use (C++):
61
+ *
62
+ * @code
63
+ * XPath signatureLocation("//ds:Signature");
64
+ * signatureLocation.addNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
65
+ * Verifier verifier(doc, signatureLocation);
66
+ * bool isVerified = verifier.verify();
67
+ * @endcode
68
+ *
69
+ * In the above example, we try to verify the signature by
70
+ * \e signatureLocation using the key found within the signature at
71
+ * \e signatureLocation. If \e signatureLocation does not contain a single
72
+ * signature, an exception is thrown. To set the key used to verify
73
+ * the signature:
74
+ *
75
+ * @code
76
+ * XPath signatureLocation("//ds:Signature");
77
+ * signatureLocation.addNamespace("ds", "http://www.w3.org/2000/09/xmldsig#");
78
+ * Verifier verifier(doc, signatureLocation);
79
+ * Key verifyingKey = some_public_key;
80
+ * bool isVerified = verifier.verify(verifyingKey);
81
+ * @endcode
82
+ *
83
+ * If exceptions are enabled, error codes will not be returned.
84
+ */
85
+ class Verifier
86
+ {
87
+ public:
88
+ /**
89
+ * Creates a Verifier that points to the first Signature in the document.
90
+ * @param doc An XML document
91
+ * @throws MemoryError
92
+ */
93
+ Verifier (XmlDocClassPtr doc);
94
+ /**
95
+ * Creates a Verifier that points to a single Signature within the document.
96
+ * @param doc An XML document
97
+ * @param xpath An XPath expression that points to a single signature
98
+ * @throws MemoryError
99
+ */
100
+ Verifier (XmlDocClassPtr doc, XPathPtr xpath);
101
+ /**
102
+ * Destroy the Verifier object.
103
+ */
104
+ ~Verifier ();
105
+
106
+ /**
107
+ * Use trusted certificates from a KeyStore to verify the signature.
108
+ * @param keyStore A key store
109
+ * @return 0 on success, -1 on error
110
+ * @throws ValueError If the keyStore is invalid
111
+ */
112
+ int setKeyStore (KeyStorePtr keyStore);
113
+ /**
114
+ * Verifies the signature using the public key embedded in the document.
115
+ * @return 1 if signature valid, 0 if not valid, -1 on error
116
+ * @throws DocError The document to verify is invalid in some way
117
+ * @throws KeyError No verifying key is available
118
+ * @throws XMLError A signature couldn't be found in the document
119
+ */
120
+ int verify ();
121
+ /**
122
+ * Verifies the signature at the previously given signature
123
+ * location using the supplied key. Note that all keying
124
+ * information in the signature being verified is ignored, and the
125
+ * supplied key will be used.
126
+ * @param key A public key
127
+ * @return 1 if signature valid, 0 if not valid, -1 on error
128
+ * @throws DocError The document to verify is invalid in some way
129
+ * @throws KeyError The verifying key is invalid
130
+ * @throws XMLError A signature couldn't be found in the document
131
+ */
132
+ int verify (KeyPtr key);
133
+ /**
134
+ * Returns the verification key in the document. The verifying key
135
+ * will be retrieved from the Signature element pointed to by the
136
+ * XPath supplied in the constructor. If no XPath was specified,
137
+ * uses the first Signature element found in the document.
138
+ * @return Pointer to the key, or null if none is found, or for cases
139
+ * where both a key and a certificate are part of the signature's
140
+ * keying information, null is returned, if the key is not equal
141
+ * to the certificate's key.
142
+ * @throws DocError The document to verify is invalid in some way
143
+ * @throws XMLError A signature couldn't be found in the document
144
+ * @throws LibError An error occurred in one of the base libraries
145
+ */
146
+ KeyPtr getVerifyingKey ();
147
+ /**
148
+ * Returns whether the element at the given XPath is contained by
149
+ * one of the Signature references, i.e., whether it is signed.
150
+ * @param xpath An XPath expression pointing to the signature
151
+ * @return 1 if element is referenced, 0 if not, -1 on error
152
+ */
153
+ int isReferenced (XPathPtr xpath);
154
+ /**
155
+ * Returns all elements referenced by the Signature.
156
+ * @return a (possibly empty) list of elements
157
+ */
158
+ vector<XmlElementPtr> getReferencedElements ();
159
+
160
+ /**
161
+ * Returns the certificate in the document. If there are multiple
162
+ * certificates available, only the first (in document order) will
163
+ * be returned.
164
+ * @return Pointer to the certificate found at the XPath
165
+ * expression; null if no certificate can be found, or if both
166
+ * a key and a certificate is part of the signature's keying
167
+ * information, and the key is not equal to the certificate's
168
+ * key.
169
+ * @throws DocError The document to verify is invalid in some way
170
+ * @throws XMLError A signature couldn't be found in the document
171
+ * @throws LibError An error occurred in one of the base libraries
172
+ * @throws XPathError if xpath results in no usable certificate
173
+ * (as defined by http://www.w3.org/2000/09/xmldsig:KeyInfo/X509Data)
174
+ */
175
+ X509CertificatePtr getCertificate ();
176
+ /**
177
+ * Retrieve the certificate chain from the signature element.
178
+ * @return the certificate chain found at the xpath expression;
179
+ * null if no certificate chain can be found, or if both a key
180
+ * and at least one certificate is part of the signature's
181
+ * keying information, and the key is not equal to the leaf
182
+ * certificate's key. If there is a single certificate found,
183
+ * a vector of size 1 will be returned.
184
+ * @throws XPathError if xpath results in no usable certificate
185
+ * (as defined by http://www.w3.org/2000/09/xmldsig:KeyInfo/X509Data)
186
+ */
187
+ vector<X509CertificatePtr> getCertificateChain ();
188
+ /**
189
+ * Set whether or not to check certificate chain on verify.
190
+ * (default is to do so.)
191
+ * @param skip 1 to NOT check certificate chain on verify, 0 to do so
192
+ */
193
+ void skipCertCheck (int skip = 1) { skipCertCheckFlag = (skip != 0); }
194
+
195
+ /// @cond NO_INTERFACE
196
+
197
+ protected:
198
+ /**
199
+ * The XML document to verify.
200
+ */
201
+ XmlDocClassPtr mXmlDoc;
202
+ /**
203
+ * The (possibly null) XPath expression pointing to a signature.
204
+ */
205
+ XPathPtr xPath;
206
+ /**
207
+ * The KeyStore.
208
+ */
209
+ KeyStorePtr mKeyStore;
210
+ /**
211
+ * Default keystore created internally.
212
+ */
213
+ KeyStorePtr mDefaultKeyStore;
214
+ /**
215
+ * Don't check certificate chain on verification.
216
+ */
217
+ bool skipCertCheckFlag;
218
+
219
+ /**
220
+ * Get internal representation of keystore.
221
+ */
222
+ xmlSecKeysMngrPtr getKeysMngr ();
223
+ /**
224
+ * Set node to the first one returned by the xpath expression.
225
+ */
226
+ int findSignatureXPath (xmlDocPtr doc, xmlNodePtr* node);
227
+ /**
228
+ * Find the signature node.
229
+ */
230
+ int findStartNode (xmlDocPtr doc, xmlNodePtr* node);
231
+ /**
232
+ * Verify a signature specified by the node.
233
+ */
234
+ int verifyNode (xmlDocPtr doc, xmlNodePtr node, KeyPtr key);
235
+ /**
236
+ * Verify a signature specified by the node (internal method called by verify(*)
237
+ */
238
+ int doVerify (KeyPtr verifyingKey);
239
+ /**
240
+ * Initialiser.
241
+ */
242
+ void verifierInit ();
243
+ /**
244
+ * Check if element referred to by XPath expression is contained
245
+ * in the nodeset.
246
+ */
247
+ int isContained (xmlSecNodeSetPtr nodeSet, XPathPtr xPathElem);
248
+ /**
249
+ * Get a nodeset for the initial transform context.
250
+ */
251
+ xmlSecNodeSetPtr nodeSetFromTransformCtx (xmlSecTransformCtxPtr ctx,
252
+ xmlDocPtr doc);
253
+ /**
254
+ * Get certificates from X509Data element.
255
+ * @param node Signature data node under which X509Data node exists
256
+ * @return list of X509 certificates
257
+ */
258
+ vector<X509CertificatePtr> getX509Data (xmlNodePtr node);
259
+ /**
260
+ * Get the X509 certificate from the X509Certificate node.
261
+ * @param node X509Certificate element
262
+ * @return certificate pointer, null on error
263
+ */
264
+ X509CertificatePtr getX509CertificateNode (xmlNodePtr node);
265
+ /**
266
+ * Callback type for Verifier::refNodes().
267
+ * @param nset node set for referenced nodes
268
+ * @param verifier verifier object we're operating on
269
+ * @param data user data pointer
270
+ * @return nonzero to abort (negative is an error)
271
+ */
272
+ typedef int (*refNodesCallback) (xmlSecNodeSetPtr nset, Verifier* verifier, void* data);
273
+ /**
274
+ * Callback for Verifier::isReferenced(), passed to Verifier::refNodes().
275
+ * @param nset node set for referenced nodes
276
+ * @param verifier verifier object we're operating on
277
+ * @param data pointer to XPathPtr object
278
+ * @return nonzero if XPath expression is contained (negative is an error)
279
+ */
280
+ static int isReferencedCallback (xmlSecNodeSetPtr nset, Verifier* verifier, void* data);
281
+ /**
282
+ * Callback for xmlSecNodeSetWalk, running through elements and adding copies
283
+ * of them to the vector in the user data pointer.
284
+ * @param cur the current node
285
+ * @param data pointer to vector<XmlElementPtr>
286
+ * @return 0, keep running through referenced nodesets or -1 on error
287
+ */
288
+ static int getElementsCallback (xmlSecNodeSetPtr, xmlNodePtr cur, xmlNodePtr, void *data);
289
+ /**
290
+ * Callback for Verifier::getReferencedElements(), passed to Verifier::refNodes().
291
+ * @param nset node set for referenced nodes
292
+ * @param verifier verifier object we're operating on
293
+ * @param data pointer to vector<XmlElementPtr>
294
+ * @return 0, keep running through referenced nodesets or -1 on error
295
+ * @throw LibError if the node set walk call fails
296
+ */
297
+ static int getReferencedElementsCallback (xmlSecNodeSetPtr nset, Verifier* verifier, void* data);
298
+ /**
299
+ * Get the set of nodes referenced by the signature, executing the callback
300
+ * for each node set.
301
+ * @param callbackFn function to call for each reference node set
302
+ * @data data pointer to pass to callback
303
+ * @return set of nodes, null on error
304
+ * @throws DocError if no document
305
+ * @throws XMLError if the signature can't be found
306
+ * @throws LibError on various xmlsec errors
307
+ */
308
+ int refNodes (refNodesCallback callbackFn, void* data);
309
+
310
+ /// @endcond
311
+ };
312
+
313
+ #endif
@@ -0,0 +1,362 @@
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 "X509Certificate.h"
18
+ #include <libxml/tree.h>
19
+ #include <openssl/x509.h>
20
+ #include <openssl/x509v3.h>
21
+ #include <xmlsec/openssl/x509.h>
22
+ #include <xmlsec/openssl/app.h>
23
+ #include <xmlsec/openssl/evp.h>
24
+ #include <xmlsec/xmlsec.h>
25
+ #include <xmlsec/errors.h>
26
+ #include <iostream>
27
+ #include "BioWrap.h"
28
+
29
+ X509Certificate::X509Certificate ()
30
+ : ptr(0)
31
+ {}
32
+
33
+
34
+ X509Certificate::X509Certificate (X509* x509ptr)
35
+ : ptr(0)
36
+ {
37
+ if (x509ptr)
38
+ {
39
+ ptr = X509_dup(x509ptr);
40
+ if (ptr == NULL)
41
+ {
42
+ THROW_NORET(MemoryError, "Unable to copy certificate data");
43
+ }
44
+ }
45
+ }
46
+
47
+
48
+ X509Certificate::X509Certificate (const X509Certificate& cert)
49
+ : ptr(0)
50
+ {
51
+ operator=(cert);
52
+ }
53
+
54
+
55
+ const X509Certificate& X509Certificate::operator= (const X509Certificate& cert)
56
+ {
57
+ if (&cert != this)
58
+ {
59
+ ptr = cert.getDup();
60
+ }
61
+ return *this;
62
+ }
63
+
64
+
65
+ X509Certificate::~X509Certificate ()
66
+ {
67
+ if (ptr)
68
+ {
69
+ X509_free(ptr);
70
+ }
71
+ }
72
+
73
+
74
+ X509* X509Certificate::getDup () const
75
+ {
76
+ X509* dupCert = X509_dup(ptr);
77
+ if (dupCert == NULL)
78
+ {
79
+ THROW(MemoryError, "Unable to copy certificate data", 0);
80
+ }
81
+ return dupCert;
82
+ }
83
+
84
+
85
+ KeyPtr X509Certificate::getKey () const
86
+ {
87
+ KeyPtr keyPtr;
88
+ if (!ptr)
89
+ {
90
+ return 0;
91
+ }
92
+ xmlSecKeyDataPtr keyDataPtr = xmlSecOpenSSLX509CertGetKey(ptr);
93
+ if (!keyDataPtr)
94
+ {
95
+ return 0;
96
+ }
97
+ keyPtr = KeyPtr(new Key);
98
+ keyPtr->create();
99
+ if (xmlSecKeySetValue(*keyPtr, keyDataPtr) < 0)
100
+ {
101
+ THROW(LibError, "Couldn't set key value", 0);
102
+ }
103
+
104
+ xmlSecKeyDataPtr certData = xmlSecKeyEnsureData(*keyPtr,
105
+ xmlSecOpenSSLKeyDataX509Id);
106
+ if (certData == NULL)
107
+ {
108
+ THROW(LibError, "Couldn't create cert data", 0);
109
+ }
110
+ if (xmlSecOpenSSLKeyDataX509AdoptCert(certData, getDup()) < 0)
111
+ {
112
+ THROW(LibError, "Unable to adopt cert data", 0);
113
+ }
114
+ return keyPtr;
115
+ }
116
+
117
+ int X509Certificate::loadFromFile (string fileName, string format)
118
+ {
119
+ Key key;
120
+ if (ptr)
121
+ {
122
+ X509_free(ptr);
123
+ }
124
+ int ret = key.loadFromFile(fileName, format, "");
125
+ if (ret < 0)
126
+ {
127
+ THROW(IOError, "Unable to load X509 certificate key", ret);
128
+ }
129
+ X509CertificatePtr cert = key.getCertificate();
130
+ if (cert)
131
+ {
132
+ operator=(*cert);
133
+ }
134
+ else
135
+ {
136
+ return -1;
137
+ }
138
+ return 0;
139
+ }
140
+
141
+ string X509Certificate::getSubjectDN()
142
+ {
143
+ string name;
144
+ if (!ptr) {
145
+ THROW(LibError, "Certificate not loaded", name);
146
+ }
147
+ const xmlChar* buf = nameToString(X509_get_subject_name(ptr));
148
+ if (buf) {
149
+ name = string((const char*)buf);
150
+ }
151
+ return name;
152
+ }
153
+
154
+ string X509Certificate::getIssuerDN()
155
+ {
156
+ string name;
157
+ if (!ptr) {
158
+ THROW(LibError, "Certificate not loaded", name);
159
+ }
160
+ const xmlChar* buf = nameToString(X509_get_issuer_name(ptr));
161
+ if (buf) {
162
+ name = string((const char*)buf);
163
+ }
164
+ return name;
165
+ }
166
+
167
+ int X509Certificate::getVersion()
168
+ {
169
+ if (!ptr) {
170
+ THROW(LibError, "Certificate not loaded", -1);
171
+ }
172
+ return X509_get_version(ptr)+1;
173
+ }
174
+
175
+ int X509Certificate::isValid()
176
+ {
177
+ if (!ptr) {
178
+ THROW(LibError, "Certificate not loaded", -1);
179
+ }
180
+ int i = X509_cmp_time(X509_get_notBefore(ptr), NULL);
181
+ if (i == 0) {
182
+ THROW(LibError, "Invalid data in certificate notBefore field", 0);
183
+ }
184
+ if (i > 0) {
185
+ return 0;
186
+ }
187
+ i = X509_cmp_time(X509_get_notAfter(ptr), NULL);
188
+ if (i == 0) {
189
+ THROW(LibError, "Invalid data in certificate notAfter field", 0);
190
+ }
191
+ if (i < 0) {
192
+ return 0;
193
+ }
194
+ return 1;
195
+ }
196
+
197
+ // yanked from xmlsec/src/openssl/x509.c
198
+ xmlChar*
199
+ X509Certificate::nameToString(X509_NAME* nm) {
200
+ xmlChar *res = NULL;
201
+ BIO *mem = NULL;
202
+ long size;
203
+
204
+ xmlSecAssert2(nm != NULL, NULL);
205
+
206
+ mem = BIO_new(BIO_s_mem());
207
+ if(mem == NULL) {
208
+ xmlSecError(XMLSEC_ERRORS_HERE,
209
+ NULL,
210
+ "BIO_new",
211
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
212
+ "BIO_s_mem");
213
+ return(NULL);
214
+ }
215
+
216
+ if (X509_NAME_print_ex(mem, nm, 0, XN_FLAG_RFC2253) <=0) {
217
+ xmlSecError(XMLSEC_ERRORS_HERE,
218
+ NULL,
219
+ "X509_NAME_print_ex",
220
+ XMLSEC_ERRORS_R_CRYPTO_FAILED,
221
+ XMLSEC_ERRORS_NO_MESSAGE);
222
+ BIO_free_all(mem);
223
+ return(NULL);
224
+ }
225
+
226
+ BIO_flush(mem); /* should call flush ? */
227
+
228
+ size = BIO_pending(mem);
229
+ res = (xmlChar*) xmlMalloc(size + 1);
230
+ if(res == NULL) {
231
+ xmlSecError(XMLSEC_ERRORS_HERE,
232
+ NULL,
233
+ "xmlMalloc",
234
+ XMLSEC_ERRORS_R_MALLOC_FAILED,
235
+ XMLSEC_ERRORS_NO_MESSAGE);
236
+ BIO_free_all(mem);
237
+ return(NULL);
238
+ }
239
+
240
+ size = BIO_read(mem, res, size);
241
+ res[size] = '\0';
242
+
243
+ BIO_free_all(mem);
244
+ return(res);
245
+ }
246
+
247
+
248
+ int X509Certificate::verify (KeyPtr key)
249
+ {
250
+ if (!key || !key->isValid())
251
+ {
252
+ THROW(KeyError, "Invalid key", -1);
253
+ }
254
+ xmlSecKeyPtr secKey = key->getKey();
255
+ if (!secKey || !secKey->value)
256
+ {
257
+ THROW(KeyError, "Invalid key", -1);
258
+ }
259
+ EVP_PKEY* evp_pkey = xmlSecOpenSSLEvpKeyDataGetEvp(secKey->value);
260
+ if (!evp_pkey)
261
+ {
262
+ THROW(KeyError, "Key is not a public key", -1);
263
+ }
264
+ int ret = X509_verify(ptr, evp_pkey);
265
+ if (ret < 0)
266
+ {
267
+ THROW(LibError, "X509 verify failed", -1);
268
+ }
269
+ return ret;
270
+ }
271
+
272
+ #ifdef WIN32
273
+ #define strncasecmp _strnicmp
274
+ #endif
275
+
276
+ int X509Certificate::getBasicConstraints () {
277
+ if (!ptr) {
278
+ THROW(LibError, "Certificate not loaded", -1);
279
+ }
280
+ X509_EXTENSION *ext = NULL;
281
+ int pathlen = -1;
282
+ X509V3_EXT_METHOD *method = NULL;
283
+ STACK_OF(CONF_VALUE) *vals = NULL;
284
+ void *ext_str = NULL;
285
+
286
+ int index = X509_get_ext_by_NID(ptr, NID_basic_constraints, -1);
287
+ if((index >= 0) && (ext = X509_get_ext(ptr, index))) {
288
+ #if OPENSSL_VERSION_NUMBER >= 0x0090800fL
289
+ const unsigned char **ext_value_data;
290
+ ext_value_data = (const_cast<const unsigned char **> (&ext->value->data));
291
+ #else
292
+ unsigned char **ext_value_data = &ext->value->data;
293
+ #endif
294
+ if (!ext_value_data) {
295
+ goto end;
296
+ }
297
+ method = X509V3_EXT_get(ext);
298
+ if (!method || !method->i2v) {
299
+ goto end;
300
+ }
301
+ ext_str = ASN1_item_d2i(NULL, ext_value_data, ext->value->length, ASN1_ITEM_ptr(method->it));
302
+ if (!ext_str) {
303
+ goto end;
304
+ }
305
+ vals = method->i2v(method, ext_str, NULL);
306
+ if (!vals) {
307
+ goto end;
308
+ }
309
+ int isCA = 0;
310
+ for(int i = 0; i < sk_CONF_VALUE_num(vals); i++) {
311
+ CONF_VALUE *val = sk_CONF_VALUE_value(vals, i);
312
+ if (!val) {
313
+ goto end;
314
+ }
315
+ if ((strncasecmp(val->name,"CA", 2)==0) && (strncasecmp(val->value, "TRUE", 4)==0))
316
+ isCA=1;
317
+ if ((strncasecmp(val->name,"pathlen", 2)==0))
318
+ pathlen=atoi(val->value);
319
+ }
320
+ if (isCA) {
321
+ if (pathlen == -1) {
322
+ pathlen = 0x7fffffff;
323
+ }
324
+ }
325
+ }
326
+ end:
327
+ if (ext_str) ASN1_item_free((ASN1_VALUE*)ext_str, ASN1_ITEM_ptr(method->it));
328
+ if (vals) sk_CONF_VALUE_pop_free(vals, X509V3_conf_free);
329
+ return pathlen;
330
+ }
331
+
332
+
333
+ int X509Certificate::isEqualTo (X509Certificate& other)
334
+ {
335
+ BioWrap bioSelf, bioOther;
336
+
337
+ i2d_X509_bio(bioSelf, ptr);
338
+ BIO_flush(bioSelf);
339
+
340
+ i2d_X509_bio(bioOther, other.ptr);
341
+ BIO_flush(bioOther);
342
+
343
+ xmlSecByte *memSelf=0, *memOther=0;
344
+ long sizeSelf=0, sizeOther=0;
345
+ sizeSelf = BIO_get_mem_data(bioSelf, &memSelf);
346
+ sizeOther = BIO_get_mem_data(bioOther, &memOther);
347
+
348
+ if (sizeSelf != sizeOther)
349
+ {
350
+ return 0;
351
+ }
352
+
353
+ while (sizeSelf)
354
+ {
355
+ if (*memSelf++ != *memOther++)
356
+ {
357
+ return 0;
358
+ }
359
+ sizeSelf--;
360
+ }
361
+ return 1;
362
+ }