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,582 @@
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 <xmlsec/openssl/app.h>
20
+ #include <xmlsec/keysdata.h>
21
+ #include <xmlsec/keys.h>
22
+ #include <xmlsec/openssl/crypto.h>
23
+ #include <xmlsec/openssl/x509.h>
24
+ #include <xmlsec/xmltree.h>
25
+ #include "Key.h"
26
+ #include "XmlDoc.h"
27
+ #include "KeyInfoCtx.h"
28
+ #include "Exceptions.h"
29
+ using namespace std;
30
+
31
+
32
+ KeyPtrWrap::KeyPtrWrap (const KeyPtrWrap& key)
33
+ : key(0)
34
+ {
35
+ operator=(key);
36
+ }
37
+
38
+
39
+ KeyPtrWrap::~KeyPtrWrap ()
40
+ {
41
+ freeKey();
42
+ }
43
+
44
+
45
+ void KeyPtrWrap::freeKey ()
46
+ {
47
+ if (key)
48
+ {
49
+ xmlSecKeyDestroy(key);
50
+ key = 0;
51
+ }
52
+ }
53
+
54
+
55
+ const KeyPtrWrap& KeyPtrWrap::operator= (const KeyPtrWrap& newkey)
56
+ {
57
+ if (this != &newkey)
58
+ {
59
+ freeKey();
60
+ key = newkey.copy();
61
+ }
62
+ return *this;
63
+ }
64
+
65
+
66
+ const KeyPtrWrap& KeyPtrWrap::operator= (xmlSecKeyPtr newkey)
67
+ {
68
+ if (key != newkey)
69
+ {
70
+ freeKey();
71
+ key = newkey;
72
+ }
73
+ return *this;
74
+ }
75
+
76
+
77
+ bool KeyPtrWrap::isValid () const
78
+ {
79
+ return xmlSecKeyIsValid(key);
80
+ }
81
+
82
+
83
+ xmlSecKeyPtr KeyPtrWrap::copy () const
84
+ {
85
+ if (!isValid())
86
+ {
87
+ return 0;
88
+ }
89
+ return xmlSecKeyDuplicate(key);
90
+ }
91
+
92
+
93
+ KeyPtrWrap& KeyPtrWrap::create ()
94
+ {
95
+ freeKey();
96
+ key = xmlSecKeyCreate();
97
+ return *this;
98
+ }
99
+
100
+
101
+ Key::Key ()
102
+ {}
103
+
104
+
105
+ Key::Key (xmlSecKeyPtr newKey)
106
+ {
107
+ if (newKey != NULL)
108
+ {
109
+ key = KeyPtrWrap(newKey).copy();
110
+ if (key == NULL)
111
+ {
112
+ THROW_NORET(MemoryError, "Couldn't copy key");
113
+ }
114
+ }
115
+ }
116
+
117
+
118
+ Key::Key (X509CertificatePtr cert)
119
+ {
120
+ if (cert)
121
+ {
122
+ KeyPtr keyPtr = cert->getKey();
123
+ if (keyPtr)
124
+ {
125
+ this->operator=(*keyPtr);
126
+ }
127
+ }
128
+ }
129
+
130
+
131
+ Key::Key (vector<X509CertificatePtr> certs)
132
+ {
133
+ if (certs.size())
134
+ {
135
+ KeyPtr keyPtr = certs[0]->getKey();
136
+ if (keyPtr)
137
+ {
138
+ this->operator=(*keyPtr);
139
+ for (vector<X509CertificatePtr>::iterator certIter = certs.begin() + 1;
140
+ certIter != certs.end(); certIter++)
141
+ {
142
+ addCert(*certIter);
143
+ }
144
+ }
145
+ }
146
+ }
147
+
148
+
149
+ Key::Key (const Key& newkey)
150
+ {
151
+ this->operator=(newkey);
152
+ }
153
+
154
+
155
+ Key::~Key ()
156
+ {}
157
+
158
+
159
+ const Key& Key::operator= (const Key& newkey)
160
+ {
161
+ if (this != &newkey)
162
+ {
163
+ key = newkey.dupKey();
164
+ }
165
+ return *this;
166
+ }
167
+
168
+
169
+ int Key::create ()
170
+ {
171
+ key.create();
172
+ if (key == NULL)
173
+ {
174
+ THROW(MemoryError, "Couldn't create key", -1);
175
+ }
176
+ return 0;
177
+ }
178
+
179
+
180
+ int Key::isValid () const
181
+ {
182
+ return key.isValid();
183
+ }
184
+
185
+
186
+ xmlSecKeyPtr Key::getKey () const
187
+ {
188
+ return key.getKey();
189
+ }
190
+
191
+
192
+ xmlSecKeyPtr Key::dupKey () const
193
+ {
194
+ if (!isValid())
195
+ {
196
+ THROW(KeyError, "Invalid key", 0);
197
+ }
198
+ xmlSecKeyPtr newKey = key.copy();
199
+ if (newKey == NULL)
200
+ {
201
+ THROW(MemoryError, "Couldn't create key", 0);
202
+ }
203
+ return newKey;
204
+ }
205
+
206
+
207
+ int Key::setName (string name)
208
+ {
209
+ if (!isValid())
210
+ {
211
+ THROW(KeyError, "Invalid key", -1);
212
+ }
213
+ if (xmlSecKeySetName(key, BAD_CAST name.c_str()) < 0)
214
+ {
215
+ THROW(LibError, "Failed to set key name", -1);
216
+ }
217
+ return 0;
218
+ }
219
+
220
+
221
+ string Key::getName ()
222
+ {
223
+ string name;
224
+ if (key)
225
+ {
226
+ const xmlChar* nameStr = xmlSecKeyGetName(key);
227
+ if (nameStr)
228
+ {
229
+ name = string((const char*)nameStr);
230
+ }
231
+ }
232
+ return name;
233
+ }
234
+
235
+
236
+ void Key::dump ()
237
+ {
238
+ if (key == NULL)
239
+ {
240
+ return;
241
+ }
242
+ // xmlSecKeyDebugDump(key,stdout);
243
+ fprintf(stderr, "Key value:\n");
244
+ xmlSecKeyDataDebugDump(key->value, stderr);
245
+ for (xmlSecSize i = 0; i < xmlSecPtrListGetSize(key->dataList); i++)
246
+ {
247
+ fprintf(stderr, "Key data list (%i):\n", (int)i);
248
+ xmlSecKeyDataPtr keyData =
249
+ (xmlSecKeyDataPtr)xmlSecPtrListGetItem(key->dataList, i);
250
+ if (keyData)
251
+ {
252
+ xmlSecKeyDataDebugDump(keyData, stderr);
253
+ }
254
+ }
255
+ }
256
+
257
+ // This callback is needed for a bug in xmlsec 1.2.9, in which the password is
258
+ // unused in favour of a null passphrase callback
259
+ int openSSLDummyPasswordCallback (char *buf, int bufsize, int verify, void *userdata)
260
+ {
261
+ char* password = (char*)userdata;
262
+
263
+ if ((password == NULL) || (strlen(password) + 1 > (unsigned)bufsize))
264
+ {
265
+ return(-1);
266
+ }
267
+
268
+ strcpy(buf, password);
269
+ return (strlen(buf));
270
+ }
271
+
272
+
273
+ int Key::loadFromFile (string fileName, string keyDataFormatString, string password)
274
+ {
275
+ const char *password_cstr = NULL;
276
+ if (password.length())
277
+ {
278
+ password_cstr = password.c_str();
279
+ }
280
+ key = xmlSecOpenSSLAppKeyLoad(
281
+ fileName.c_str(),
282
+ findKeyDataFormat(keyDataFormatString),
283
+ password_cstr,
284
+ password_cstr == NULL ? NULL : (void*)&openSSLDummyPasswordCallback,
285
+ password_cstr == NULL ? NULL : (void*)password_cstr);
286
+ if (key == NULL)
287
+ {
288
+ THROW(IOError, "Failure loading key file", -1);
289
+ }
290
+ return 0;
291
+ }
292
+
293
+
294
+ int Key::loadFromKeyInfoFile (string fileName)
295
+ {
296
+ XmlDoc xmlDoc;
297
+ if (xmlDoc.loadFromFile(fileName) < 0)
298
+ {
299
+ return -1;
300
+ }
301
+ return loadFromKeyInfo(xmlDoc);
302
+ }
303
+
304
+
305
+ int Key::loadHMACFromString (string hMACString)
306
+ {
307
+ create();
308
+ xmlSecKeyDataPtr keyData = xmlSecKeyDataCreate(xmlSecOpenSSLKeyDataHmacId);
309
+ if (!xmlSecKeyDataIsValid(keyData))
310
+ {
311
+ THROW(MemoryError, "Unable to create keyData", -1);
312
+ }
313
+
314
+ xmlSecBufferPtr buffer = xmlSecKeyDataBinaryValueGetBuffer(keyData);
315
+ if (!buffer)
316
+ {
317
+ THROW(MemoryError, "Unable to get buffer", -1);
318
+ }
319
+
320
+ if (xmlSecBufferSetData(buffer, (const unsigned char*)hMACString.c_str(), hMACString.length()) < 0)
321
+ {
322
+ THROW(LibError, "Unable to set buffer data", -1);
323
+ }
324
+
325
+ if (xmlSecKeySetValue(key, keyData) < 0)
326
+ {
327
+ THROW(KeyError, "Unable to set key value", -1);
328
+ }
329
+ return 0;
330
+ }
331
+
332
+
333
+ int Key::addCertFromFile (string fileName, string format)
334
+ {
335
+ if (!isValid())
336
+ {
337
+ THROW(KeyError, "Invalid key", -1);
338
+ }
339
+ if (xmlSecOpenSSLAppKeyCertLoad(key, fileName.c_str(),
340
+ findKeyDataFormat(format.c_str())) < 0)
341
+ {
342
+ THROW(IOError, "Failure loading certificate file", -1);
343
+ }
344
+ return 0;
345
+ }
346
+
347
+
348
+ int Key::addCert (KeyPtr certKey)
349
+ {
350
+ return addCert(certKey->getCertificateChain());
351
+ }
352
+
353
+
354
+ int Key::addCert (X509CertificatePtr x509)
355
+ {
356
+ if (!isValid())
357
+ {
358
+ THROW(KeyError, "Invalid key", -1);
359
+ }
360
+ if (!x509)
361
+ {
362
+ THROW(ValueError, "Bad x509 parameter", -1);
363
+ }
364
+ xmlSecKeyDataPtr certData = xmlSecKeyEnsureData(key,
365
+ xmlSecOpenSSLKeyDataX509Id);
366
+ if (certData == NULL)
367
+ {
368
+ THROW(MemoryError, "Couldn't create cert data", -1);
369
+ }
370
+ if (xmlSecOpenSSLKeyDataX509AdoptCert(certData, x509->getDup()) < 0)
371
+ {
372
+ THROW(LibError, "Unable to adopt cert data", -1);
373
+ }
374
+ return 0;
375
+ }
376
+
377
+
378
+ int Key::addCert (vector<X509CertificatePtr> certs)
379
+ {
380
+ int certsAdded = 0;
381
+ for (vector<X509CertificatePtr>::iterator certIter = certs.begin();
382
+ certIter != certs.end(); certIter++)
383
+ {
384
+ int ret = addCert(*certIter);
385
+ if (ret < 0)
386
+ {
387
+ return ret;
388
+ }
389
+ certsAdded++;
390
+ }
391
+ return certsAdded;
392
+ }
393
+
394
+
395
+ X509CertificatePtr Key::getCertificate ()
396
+ {
397
+ vector<X509CertificatePtr> certChain = getCertificateChain();
398
+ if (certChain.size())
399
+ {
400
+ return certChain[0];
401
+ }
402
+ return 0;
403
+ }
404
+
405
+
406
+ vector<X509CertificatePtr> Key::getCertificateChain ()
407
+ {
408
+ vector<X509CertificatePtr> certChain;
409
+ if (!isValid())
410
+ {
411
+ THROW(KeyError, "Invalid key", certChain);
412
+ }
413
+ if (!(xmlSecKeyDataIsValid(key->value) )) // &&
414
+ // xmlSecKeyDataCheckId(key->value, xmlSecKeyDataStore)))
415
+ {
416
+ THROW(KeyError, "Invalid key value", certChain);
417
+ }
418
+ if (!xmlSecPtrListIsValid(key->dataList))
419
+ {
420
+ return certChain;
421
+ }
422
+ for (xmlSecSize i = 0; i < xmlSecPtrListGetSize(key->dataList); i++)
423
+ {
424
+ xmlSecKeyDataPtr keyData =
425
+ (xmlSecKeyDataPtr)xmlSecPtrListGetItem(key->dataList, i);
426
+ if (keyData && xmlSecKeyDataCheckId(keyData, xmlSecOpenSSLKeyDataX509Id))
427
+ {
428
+ xmlSecSize size = xmlSecOpenSSLKeyDataX509GetCertsSize(keyData);
429
+ for (xmlSecSize j = 0; j < size; j++)
430
+ {
431
+ X509* cert = xmlSecOpenSSLKeyDataX509GetCert(keyData, j);
432
+ if (cert)
433
+ {
434
+ X509CertificatePtr x509 = new X509Certificate(cert);
435
+ certChain.push_back(x509);
436
+ }
437
+ }
438
+ }
439
+ }
440
+ return certChain;
441
+ }
442
+
443
+
444
+ struct _DsigKeyDataFormatMap
445
+ {
446
+ string formatString;
447
+ xmlSecKeyDataFormat keyDataFormat;
448
+ }
449
+ dsigKeyDataFormatMap[] = {
450
+ {"binary", xmlSecKeyDataFormatBinary},
451
+ {"pem", xmlSecKeyDataFormatPem},
452
+ {"der", xmlSecKeyDataFormatDer},
453
+ {"pkcs8_pem", xmlSecKeyDataFormatPkcs8Pem},
454
+ {"pkcs8_der", xmlSecKeyDataFormatPkcs8Der},
455
+ {"pkcs12", xmlSecKeyDataFormatPkcs12},
456
+ {"cert_pem", xmlSecKeyDataFormatCertPem},
457
+ {"cert_der", xmlSecKeyDataFormatCertDer},
458
+ {"unknown", xmlSecKeyDataFormatUnknown} // sentinel
459
+ };
460
+
461
+ xmlSecKeyDataFormat Key::findKeyDataFormat (string formatString)
462
+ {
463
+ xmlSecKeyDataFormat keyDataFormat = xmlSecKeyDataFormatUnknown;
464
+ int i = 0;
465
+ while (1)
466
+ {
467
+ if (dsigKeyDataFormatMap[i].formatString == formatString)
468
+ {
469
+ keyDataFormat = dsigKeyDataFormatMap[i].keyDataFormat;
470
+ break;
471
+ }
472
+ if (dsigKeyDataFormatMap[i].keyDataFormat == xmlSecKeyDataFormatUnknown)
473
+ break;
474
+ i++;
475
+ }
476
+ return keyDataFormat;
477
+ }
478
+
479
+
480
+ int Key::loadFromKeyInfo (xmlDocPtr xmlDoc, xmlSecKeysMngrPtr keysMngr)
481
+ {
482
+ assert(xmlDoc);
483
+ // find keyinfo node
484
+ xmlNodePtr node = xmlSecFindNode(xmlDocGetRootElement(xmlDoc),
485
+ xmlSecNodeKeyInfo, xmlSecDSigNs);
486
+ if (node == NULL)
487
+ {
488
+ THROW(XMLError, "Can't find key info node", -1);
489
+ }
490
+ return loadFromKeyInfo(node);
491
+ }
492
+
493
+
494
+ int Key::loadFromKeyInfo (xmlNodePtr xmlNode, xmlSecKeysMngrPtr keysMngr)
495
+ {
496
+ assert(xmlNode);
497
+ if (!xmlSecCheckNodeName(xmlNode, xmlSecNodeKeyInfo, xmlSecDSigNs))
498
+ {
499
+ THROW(XMLError, "Invalid key info node", -1);
500
+ }
501
+
502
+ KeyInfoCtx keyInfoCtx (keysMngr);
503
+ if (!keyInfoCtx)
504
+ {
505
+ return -1;
506
+ }
507
+ keyInfoCtx->mode = xmlSecKeyInfoModeRead;
508
+ KeyPtrWrap newKey = xmlSecKeysMngrGetKey(xmlNode, keyInfoCtx);
509
+ if (newKey == NULL)
510
+ {
511
+ THROW(LibError, "Couldn't load key info", -1);
512
+ }
513
+ else
514
+ {
515
+ key = newKey.copy();
516
+ if (key == NULL)
517
+ {
518
+ THROW(MemoryError, "Couldn't copy key", -1);
519
+ }
520
+ }
521
+ return 0;
522
+ }
523
+
524
+ bool Key::hasSameValues(const Key& otherKey) const
525
+ {
526
+ // if both are invalid then the keys are the same
527
+ if (!isValid() && !otherKey.isValid())
528
+ return true;
529
+
530
+ if (!isValid() || !otherKey.isValid())
531
+ return false;
532
+
533
+ const xmlSecKeyPtr thisSecKeyPtr = getKey();
534
+ const xmlSecKeyPtr otherSecKeyPtr = otherKey.getKey();
535
+
536
+ // if the same pointers then the keys are the same
537
+ if (thisSecKeyPtr == otherSecKeyPtr)
538
+ return true;
539
+
540
+ bool bRet = false;
541
+ if ((thisSecKeyPtr->value->id == otherSecKeyPtr->value->id)
542
+ && (thisSecKeyPtr->notValidBefore == otherSecKeyPtr->notValidBefore)
543
+ && (thisSecKeyPtr->notValidAfter == otherSecKeyPtr->notValidAfter)
544
+ && (thisSecKeyPtr->usage == otherSecKeyPtr->usage))
545
+ {
546
+ if ((xmlSecKeyDataGetType(thisSecKeyPtr->value) == xmlSecKeyDataGetType(otherSecKeyPtr->value))
547
+ && (xmlSecKeyDataGetSize(thisSecKeyPtr->value) == xmlSecKeyDataGetSize(otherSecKeyPtr->value)))
548
+ {
549
+ xmlSecByte *thisBuffer = NULL;
550
+ xmlSecSize thisSize = 0;
551
+ KeyInfoCtx thisCtx;
552
+ bRet = true; // assume suceess - if the following fails there is nothing more we can do
553
+ if (xmlSecKeyDataBinWrite(thisSecKeyPtr->value->id, thisSecKeyPtr, &thisBuffer, &thisSize, thisCtx) == 0)
554
+ {
555
+ xmlSecByte *otherBuffer = NULL;
556
+ xmlSecSize otherSize = 0;
557
+ KeyInfoCtx otherCtx;
558
+
559
+ // if this succeeds then the other will succeed since they have the same Id so
560
+ bRet = false; // assume failure
561
+ if (xmlSecKeyDataBinWrite(otherSecKeyPtr->value->id, otherSecKeyPtr, &otherBuffer, &otherSize, otherCtx) == 0)
562
+ {
563
+ if ((thisSize == otherSize) && (memcmp(thisBuffer, otherBuffer, thisSize) == 0))
564
+ {
565
+ bRet = true;
566
+ }
567
+ }
568
+ if (otherBuffer)
569
+ {
570
+ memset(otherBuffer, 0, otherSize);
571
+ xmlFree(otherBuffer);
572
+ }
573
+ }
574
+ if (thisBuffer)
575
+ {
576
+ memset(thisBuffer, 0, thisSize);
577
+ xmlFree(thisBuffer);
578
+ }
579
+ }
580
+ }
581
+ return bRet;
582
+ }