xmlsig 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ }