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,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
+ }