money-nokogiri-xmlsec 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/Guardfile +13 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +121 -0
  8. data/Rakefile +30 -0
  9. data/ext/nokogiri_ext_xmlsec/extconf.rb +20 -0
  10. data/ext/nokogiri_ext_xmlsec/init.c +46 -0
  11. data/ext/nokogiri_ext_xmlsec/nokogiri_decrypt_with_key.c +124 -0
  12. data/ext/nokogiri_ext_xmlsec/nokogiri_encrypt_with_key.c +177 -0
  13. data/ext/nokogiri_ext_xmlsec/nokogiri_helpers_set_attribute_id.c +43 -0
  14. data/ext/nokogiri_ext_xmlsec/nokogiri_init.c +32 -0
  15. data/ext/nokogiri_ext_xmlsec/nokogiri_sign_certificate.c +143 -0
  16. data/ext/nokogiri_ext_xmlsec/nokogiri_sign_rsa.c +95 -0
  17. data/ext/nokogiri_ext_xmlsec/nokogiri_verify_signature_certificates.c +96 -0
  18. data/ext/nokogiri_ext_xmlsec/nokogiri_verify_signature_named_keys.c +106 -0
  19. data/ext/nokogiri_ext_xmlsec/nokogiri_verify_signature_rsa.c +56 -0
  20. data/ext/nokogiri_ext_xmlsec/shutdown.c +12 -0
  21. data/ext/nokogiri_ext_xmlsec/xmlsecrb.h +39 -0
  22. data/lib/money-nokogiri-xmlsec.rb +1 -0
  23. data/lib/xmlsec.rb +110 -0
  24. data/lib/xmlsec/version.rb +3 -0
  25. data/money-nokogiri-xmlsec.gemspec +36 -0
  26. data/spec/fixtures/cert/server.crt +14 -0
  27. data/spec/fixtures/cert/server.csr +11 -0
  28. data/spec/fixtures/cert/server.key.decrypted +15 -0
  29. data/spec/fixtures/cert/server.key.encrypted +18 -0
  30. data/spec/fixtures/rsa.pem +15 -0
  31. data/spec/fixtures/rsa.pub +6 -0
  32. data/spec/fixtures/sign2-doc.xml +6 -0
  33. data/spec/fixtures/sign2-result.xml +24 -0
  34. data/spec/fixtures/sign3-result.xml +37 -0
  35. data/spec/lib/nokogiri/xml/document/encryption_and_decryption_spec.rb +28 -0
  36. data/spec/lib/nokogiri/xml/document/signing_and_verifying_spec.rb +70 -0
  37. data/spec/spec_helper.rb +10 -0
  38. metadata +197 -0
@@ -0,0 +1,43 @@
1
+ #include "xmlsecrb.h"
2
+
3
+ VALUE set_id_attribute(VALUE self, VALUE rb_attr_name) {
4
+ xmlNodePtr node;
5
+ xmlAttrPtr attr;
6
+ xmlAttrPtr tmp;
7
+ xmlChar *name;
8
+ const xmlChar *idName;
9
+
10
+ Data_Get_Struct(self, xmlNode, node);
11
+ Check_Type(rb_attr_name, T_STRING);
12
+ idName = (const xmlChar *)RSTRING_PTR(rb_attr_name);
13
+
14
+ // find pointer to id attribute
15
+ attr = xmlHasProp(node, idName);
16
+ if((attr == NULL) || (attr->children == NULL)) {
17
+ rb_raise(rb_eRuntimeError, "Can't find attribute to add register as id");
18
+ return Qfalse;
19
+ }
20
+
21
+ // get the attribute (id) value
22
+ name = xmlNodeListGetString(node->doc, attr->children, 1);
23
+ if(name == NULL) {
24
+ rb_raise(rb_eRuntimeError, "Attribute %s has no value", idName);
25
+ return Qfalse;
26
+ }
27
+
28
+ // check that we don't have that id already registered
29
+ tmp = xmlGetID(node->doc, name);
30
+ if(tmp != NULL) {
31
+ // rb_raise(rb_eRuntimeError, "Attribute %s is already an ID", idName);
32
+ xmlFree(name);
33
+ return Qfalse;
34
+ }
35
+
36
+ // finally register id
37
+ xmlAddID(NULL, node->doc, name, attr);
38
+
39
+ // and do not forget to cleanup
40
+ xmlFree(name);
41
+
42
+ return Qtrue;
43
+ }
@@ -0,0 +1,32 @@
1
+ #include "xmlsecrb.h"
2
+
3
+ VALUE rb_cNokogiri_XML_Document = T_NIL;
4
+ VALUE rb_cNokogiri_XML_Node = T_NIL;
5
+ VALUE rb_eSigningError = T_NIL;
6
+ VALUE rb_eVerificationError = T_NIL;
7
+ VALUE rb_eKeystoreError = T_NIL;
8
+ VALUE rb_eEncryptionError = T_NIL;
9
+ VALUE rb_eDecryptionError = T_NIL;
10
+
11
+ void Init_Nokogiri_ext() {
12
+ VALUE XMLSec = rb_define_module("XMLSec");
13
+ VALUE Nokogiri = rb_define_module("Nokogiri");
14
+ VALUE Nokogiri_XML = rb_define_module_under(Nokogiri, "XML");
15
+ rb_cNokogiri_XML_Document = rb_const_get(Nokogiri_XML, rb_intern("Document"));
16
+ rb_cNokogiri_XML_Node = rb_const_get(Nokogiri_XML, rb_intern("Node"));
17
+
18
+ rb_define_method(rb_cNokogiri_XML_Document, "sign_with_key", sign_with_key, 2);
19
+ rb_define_method(rb_cNokogiri_XML_Document, "sign_with_certificate", sign_with_certificate, 5);
20
+ rb_define_method(rb_cNokogiri_XML_Document, "verify_with_rsa_key", verify_signature_with_rsa_key, 1);
21
+ rb_define_method(rb_cNokogiri_XML_Document, "verify_with_named_keys", verify_signature_with_named_keys, 1);
22
+ rb_define_method(rb_cNokogiri_XML_Document, "verify_with_certificates", verify_signature_with_certificates, 1);
23
+ rb_define_method(rb_cNokogiri_XML_Document, "encrypt_with_key", encrypt_with_key, 2);
24
+ rb_define_method(rb_cNokogiri_XML_Document, "decrypt_with_key", decrypt_with_key, 2);
25
+ rb_define_method(rb_cNokogiri_XML_Node, "set_id_attribute", set_id_attribute, 1);
26
+
27
+ rb_eSigningError = rb_define_class_under(XMLSec, "SigningError", rb_eRuntimeError);
28
+ rb_eVerificationError = rb_define_class_under(XMLSec, "VerificationError", rb_eRuntimeError);
29
+ rb_eKeystoreError = rb_define_class_under(XMLSec, "KeystoreError", rb_eRuntimeError);
30
+ rb_eEncryptionError = rb_define_class_under(XMLSec, "EncryptionError", rb_eRuntimeError);
31
+ rb_eDecryptionError = rb_define_class_under(XMLSec, "DecryptionError", rb_eRuntimeError);
32
+ }
@@ -0,0 +1,143 @@
1
+ #include "xmlsecrb.h"
2
+
3
+ VALUE sign_with_certificate(VALUE self, VALUE rb_key_name, VALUE rb_rsa_key, VALUE rb_cert, VALUE rb_cert_issuer_name, VALUE rb_cert_serial_number) {
4
+ xmlDocPtr doc;
5
+ xmlNodePtr signNode = NULL;
6
+ xmlNodePtr refNode = NULL;
7
+ xmlNodePtr keyInfoNode = NULL;
8
+ xmlNodePtr x509DataNode = NULL;
9
+ xmlNodePtr issuerSerialNode = NULL;
10
+ xmlSecDSigCtxPtr dsigCtx = NULL;
11
+ char *keyName;
12
+ char *certificate;
13
+ char *issuerName;
14
+ char *serialNumber;
15
+ char *rsaKey;
16
+ unsigned int rsaKeyLength, certificateLength;
17
+
18
+ Data_Get_Struct(self, xmlDoc, doc);
19
+ rsaKey = RSTRING_PTR(rb_rsa_key);
20
+ rsaKeyLength = RSTRING_LEN(rb_rsa_key);
21
+ keyName = RSTRING_PTR(rb_key_name);
22
+ certificate = RSTRING_PTR(rb_cert);
23
+ issuerName = RSTRING_PTR(rb_cert_issuer_name);
24
+ serialNumber = RSTRING_PTR(rb_cert_serial_number);
25
+ certificateLength = RSTRING_LEN(rb_cert);
26
+
27
+ // create signature template for RSA-SHA1 enveloped signature
28
+ signNode = xmlSecTmplSignatureCreateNsPref(doc, xmlSecTransformInclC14NId,
29
+ xmlSecTransformRsaSha1Id, NULL, "ds");
30
+ if (signNode == NULL) {
31
+ rb_raise(rb_eSigningError, "failed to create signature template");
32
+ goto done;
33
+ }
34
+
35
+ // add <dsig:Signature/> node to the doc
36
+ xmlAddChild(xmlDocGetRootElement(doc), signNode);
37
+
38
+ // add reference
39
+ refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id,
40
+ NULL, "", NULL);
41
+ if(refNode == NULL) {
42
+ rb_raise(rb_eSigningError, "failed to add reference to signature template");
43
+ goto done;
44
+ }
45
+
46
+ // add enveloped transform
47
+ if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL) {
48
+ rb_raise(rb_eSigningError, "failed to add enveloped transform to reference");
49
+ goto done;
50
+ }
51
+
52
+ // add c14n transform
53
+ if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformInclC14NId) == NULL) {
54
+ rb_raise(rb_eSigningError, "failed to add c14n transform to reference");
55
+ goto done;
56
+ }
57
+
58
+ // add <dsig:KeyInfo/> and <dsig:X509Data/>
59
+ keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL);
60
+ if(keyInfoNode == NULL) {
61
+ rb_raise(rb_eSigningError, "failed to add key info");
62
+ goto done;
63
+ }
64
+
65
+ // add <X509Data/>
66
+ x509DataNode = xmlSecTmplKeyInfoAddX509Data(keyInfoNode);
67
+ if(x509DataNode == NULL) {
68
+ rb_raise(rb_eSigningError, "failed to add X509Data node");
69
+ goto done;
70
+ }
71
+
72
+ // add <X509Certificate/>
73
+ if(xmlSecTmplX509DataAddCertificate(x509DataNode) == NULL) {
74
+ rb_raise(rb_eSigningError, "failed to add X509Certificate node");
75
+ goto done;
76
+ }
77
+
78
+ // add <X509IssuerSerial/>
79
+ issuerSerialNode = xmlSecTmplX509DataAddIssuerSerial(x509DataNode);
80
+ if(issuerSerialNode == NULL) {
81
+ rb_raise(rb_eSigningError, "failed to add X509IssuerSerial node");
82
+ goto done;
83
+ }
84
+
85
+ // add <X509IssuerName/>
86
+ if(xmlSecTmplX509IssuerSerialAddIssuerName(issuerSerialNode, (xmlSecByte *)issuerName) == NULL) {
87
+ rb_raise(rb_eSigningError, "failed to add X509IssuerName node");
88
+ goto done;
89
+ }
90
+
91
+ // add <X509SerialNumber/>
92
+ if(xmlSecTmplX509IssuerSerialAddSerialNumber(issuerSerialNode, (xmlSecByte *)serialNumber) == NULL) {
93
+ rb_raise(rb_eSigningError, "failed to add X509SerialNumber node");
94
+ goto done;
95
+ }
96
+
97
+ // create signature context, we don't need keys manager in this example
98
+ dsigCtx = xmlSecDSigCtxCreate(NULL);
99
+ if(dsigCtx == NULL) {
100
+ rb_raise(rb_eSigningError, "failed to create signature context");
101
+ goto done;
102
+ }
103
+
104
+ // load private key, assuming that there is not password
105
+ dsigCtx->signKey = xmlSecCryptoAppKeyLoadMemory((xmlSecByte *)rsaKey,
106
+ rsaKeyLength,
107
+ xmlSecKeyDataFormatPem,
108
+ NULL, // password
109
+ NULL,
110
+ NULL);
111
+ if(dsigCtx->signKey == NULL) {
112
+ rb_raise(rb_eSigningError, "failed to load private key");
113
+ goto done;
114
+ }
115
+
116
+ // load certificate and add to the key
117
+ if(xmlSecCryptoAppKeyCertLoadMemory(dsigCtx->signKey,
118
+ (xmlSecByte *)certificate,
119
+ certificateLength,
120
+ xmlSecKeyDataFormatPem) < 0) {
121
+ rb_raise(rb_eSigningError, "failed to load certificate");
122
+ goto done;
123
+ }
124
+
125
+ // set key name
126
+ if(xmlSecKeySetName(dsigCtx->signKey, (xmlSecByte *)keyName) < 0) {
127
+ rb_raise(rb_eSigningError, "failed to set key name");
128
+ goto done;
129
+ }
130
+
131
+ // sign the template
132
+ if(xmlSecDSigCtxSign(dsigCtx, signNode) < 0) {
133
+ rb_raise(rb_eSigningError, "signature failed");
134
+ goto done;
135
+ }
136
+
137
+ done:
138
+ if(dsigCtx != NULL) {
139
+ xmlSecDSigCtxDestroy(dsigCtx);
140
+ }
141
+
142
+ return T_NIL;
143
+ }
@@ -0,0 +1,95 @@
1
+ #include "xmlsecrb.h"
2
+
3
+ // TODO the signature context probably should be a ruby instance variable
4
+ // and separate object, instead of being allocated/freed in each method.
5
+
6
+ VALUE sign_with_key(VALUE self, VALUE rb_key_name, VALUE rb_rsa_key) {
7
+ xmlDocPtr doc;
8
+ xmlNodePtr signNode = NULL;
9
+ xmlNodePtr refNode = NULL;
10
+ xmlNodePtr keyInfoNode = NULL;
11
+ xmlSecDSigCtxPtr dsigCtx = NULL;
12
+ char *keyName;
13
+ char *rsaKey;
14
+ unsigned int rsaKeyLength;
15
+
16
+ Data_Get_Struct(self, xmlDoc, doc);
17
+ rsaKey = RSTRING_PTR(rb_rsa_key);
18
+ rsaKeyLength = RSTRING_LEN(rb_rsa_key);
19
+ keyName = RSTRING_PTR(rb_key_name);
20
+
21
+ // create signature template for RSA-SHA1 enveloped signature
22
+ signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId,
23
+ xmlSecTransformRsaSha1Id, NULL);
24
+ if (signNode == NULL) {
25
+ rb_raise(rb_eSigningError, "failed to create signature template");
26
+ goto done;
27
+ }
28
+
29
+ // add <dsig:Signature/> node to the doc
30
+ xmlAddChild(xmlDocGetRootElement(doc), signNode);
31
+
32
+ // add reference
33
+ refNode = xmlSecTmplSignatureAddReference(signNode, xmlSecTransformSha1Id,
34
+ NULL, NULL, NULL);
35
+ if(refNode == NULL) {
36
+ rb_raise(rb_eSigningError, "failed to add reference to signature template");
37
+ goto done;
38
+ }
39
+
40
+ // add enveloped transform
41
+ if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL) {
42
+ rb_raise(rb_eSigningError, "failed to add enveloped transform to reference");
43
+ goto done;
44
+ }
45
+
46
+ // add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to put key name in the signed
47
+ // document
48
+ keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL);
49
+ if(keyInfoNode == NULL) {
50
+ rb_raise(rb_eSigningError, "failed to add key info");
51
+ goto done;
52
+ }
53
+ if(xmlSecTmplKeyInfoAddKeyName(keyInfoNode, NULL) == NULL) {
54
+ rb_raise(rb_eSigningError, "failed to add key name");
55
+ goto done;
56
+ }
57
+
58
+ // create signature context, we don't need keys manager in this example
59
+ dsigCtx = xmlSecDSigCtxCreate(NULL);
60
+ if(dsigCtx == NULL) {
61
+ rb_raise(rb_eSigningError, "failed to create signature context");
62
+ goto done;
63
+ }
64
+
65
+ // load private key, assuming that there is no password
66
+ dsigCtx->signKey = xmlSecCryptoAppKeyLoadMemory((xmlSecByte *)rsaKey,
67
+ rsaKeyLength,
68
+ xmlSecKeyDataFormatPem,
69
+ NULL, // password
70
+ NULL,
71
+ NULL);
72
+ if(dsigCtx->signKey == NULL) {
73
+ rb_raise(rb_eSigningError, "failed to load private pem key");
74
+ goto done;
75
+ }
76
+
77
+ // set key name
78
+ if(xmlSecKeySetName(dsigCtx->signKey, (xmlSecByte *)keyName) < 0) {
79
+ rb_raise(rb_eSigningError, "failed to set key name");
80
+ goto done;
81
+ }
82
+
83
+ // sign the template
84
+ if(xmlSecDSigCtxSign(dsigCtx, signNode) < 0) {
85
+ rb_raise(rb_eSigningError, "signature failed");
86
+ goto done;
87
+ }
88
+
89
+ done:
90
+ if(dsigCtx != NULL) {
91
+ xmlSecDSigCtxDestroy(dsigCtx);
92
+ }
93
+
94
+ return T_NIL;
95
+ }
@@ -0,0 +1,96 @@
1
+ #include "xmlsecrb.h"
2
+
3
+ static xmlSecKeysMngrPtr getKeyManager(VALUE rb_certs) {
4
+ int i, numCerts = RARRAY_LEN(rb_certs);
5
+ xmlSecKeysMngrPtr keyManager = xmlSecKeysMngrCreate();
6
+ VALUE rb_cert;
7
+ char *cert;
8
+ unsigned int certLength;
9
+ int numSuccessful = 0;
10
+
11
+ if (keyManager == NULL) return NULL;
12
+
13
+ if (xmlSecCryptoAppDefaultKeysMngrInit(keyManager) < 0) {
14
+ rb_raise(rb_eKeystoreError, "could not initialize key manager");
15
+ xmlSecKeysMngrDestroy(keyManager);
16
+ return NULL;
17
+ }
18
+
19
+ for (i = 0; i < numCerts; i++) {
20
+ rb_cert = RARRAY_PTR(rb_certs)[i];
21
+ Check_Type(rb_cert, T_STRING);
22
+ cert = RSTRING_PTR(rb_cert);
23
+ certLength = RSTRING_LEN(rb_cert);
24
+
25
+ if(xmlSecCryptoAppKeysMngrCertLoadMemory(keyManager,
26
+ (xmlSecByte *)cert,
27
+ certLength,
28
+ xmlSecKeyDataFormatPem,
29
+ xmlSecKeyDataTypeTrusted) < 0) {
30
+ rb_warn("failed to load certificate at index %d", i);
31
+ } else {
32
+ numSuccessful++;
33
+ }
34
+ }
35
+
36
+ // note, numCerts could be zero, meaning that we should use system SSL certs
37
+ if (numSuccessful == 0 && numCerts != 0) {
38
+ rb_raise(rb_eKeystoreError, "Could not load any of the specified certificates for signature verification");
39
+ xmlSecKeysMngrDestroy(keyManager);
40
+ return NULL;
41
+ }
42
+
43
+ return keyManager;
44
+ }
45
+
46
+ VALUE verify_signature_with_certificates(VALUE self, VALUE rb_certs) {
47
+ xmlDocPtr doc;
48
+ xmlNodePtr node = NULL;
49
+ xmlSecDSigCtxPtr dsigCtx = NULL;
50
+ xmlSecKeysMngrPtr keyManager = NULL;
51
+ VALUE result = Qfalse;
52
+
53
+ Check_Type(rb_certs, T_ARRAY);
54
+ Data_Get_Struct(self, xmlDoc, doc);
55
+
56
+ // find start node
57
+ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
58
+ if(node == NULL) {
59
+ rb_raise(rb_eVerificationError, "start node not found");
60
+ goto done;
61
+ }
62
+
63
+ keyManager = getKeyManager(rb_certs);
64
+ if (keyManager == NULL) {
65
+ rb_raise(rb_eKeystoreError, "failed to create key manager");
66
+ goto done;
67
+ }
68
+
69
+ // create signature context, we don't need keys manager in this example
70
+ dsigCtx = xmlSecDSigCtxCreate(keyManager);
71
+ if(dsigCtx == NULL) {
72
+ rb_raise(rb_eVerificationError, "failed to create signature context");
73
+ goto done;
74
+ }
75
+
76
+ // verify signature
77
+ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
78
+ rb_raise(rb_eVerificationError, "error occurred during signature verification");
79
+ goto done;
80
+ }
81
+
82
+ if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
83
+ result = Qtrue;
84
+ }
85
+
86
+ done:
87
+ if(dsigCtx != NULL) {
88
+ xmlSecDSigCtxDestroy(dsigCtx);
89
+ }
90
+
91
+ if (keyManager != NULL) {
92
+ xmlSecKeysMngrDestroy(keyManager);
93
+ }
94
+
95
+ return result;
96
+ }
@@ -0,0 +1,106 @@
1
+ #include "xmlsecrb.h"
2
+
3
+ static int addRubyKeyToManager(VALUE rb_key, VALUE rb_value, VALUE rb_manager) {
4
+ xmlSecKeysMngrPtr keyManager = (xmlSecKeysMngrPtr)rb_manager;
5
+ char *keyName, *keyData;
6
+ unsigned int keyDataLength;
7
+ xmlSecKeyPtr key;
8
+
9
+ Check_Type(rb_key, T_STRING);
10
+ Check_Type(rb_value, T_STRING);
11
+ keyName = RSTRING_PTR(rb_key);
12
+ keyData = RSTRING_PTR(rb_value);
13
+ keyDataLength = RSTRING_LEN(rb_value);
14
+
15
+ // load key
16
+ key = xmlSecCryptoAppKeyLoadMemory((xmlSecByte *)keyData,
17
+ keyDataLength,
18
+ xmlSecKeyDataFormatPem,
19
+ NULL, // password
20
+ NULL, NULL);
21
+ if (key == NULL) {
22
+ rb_warn("failed to load '%s' public or private pem key", keyName);
23
+ return ST_CONTINUE;
24
+ }
25
+
26
+ // set key name
27
+ if (xmlSecKeySetName(key, BAD_CAST keyName) < 0) {
28
+ rb_warn("failed to set key name for key '%s'", keyName);
29
+ return ST_CONTINUE;
30
+ }
31
+
32
+ // add key to key manager; from now on the manager is responsible for
33
+ // destroying the key
34
+ if (xmlSecCryptoAppDefaultKeysMngrAdoptKey(keyManager, key) < 0) {
35
+ rb_warn("failed to add key '%s' to key manager", keyName);
36
+ return ST_CONTINUE;
37
+ }
38
+
39
+ return ST_CONTINUE;
40
+ }
41
+
42
+ static xmlSecKeysMngrPtr getKeyManager(VALUE rb_hash) {
43
+ xmlSecKeysMngrPtr keyManager = xmlSecKeysMngrCreate();
44
+ if (keyManager == NULL) return NULL;
45
+ if (xmlSecCryptoAppDefaultKeysMngrInit(keyManager) < 0) {
46
+ rb_raise(rb_eKeystoreError, "could not initialize key manager");
47
+ xmlSecKeysMngrDestroy(keyManager);
48
+ return NULL;
49
+ }
50
+
51
+ rb_hash_foreach(rb_hash, addRubyKeyToManager, (VALUE)keyManager);
52
+
53
+ return keyManager;
54
+ }
55
+
56
+ VALUE verify_signature_with_named_keys(VALUE self, VALUE rb_hash) {
57
+ xmlDocPtr doc;
58
+ xmlNodePtr node = NULL;
59
+ xmlSecDSigCtxPtr dsigCtx = NULL;
60
+ xmlSecKeysMngrPtr keyManager = NULL;
61
+ VALUE result = Qfalse;
62
+
63
+ Check_Type(rb_hash, T_HASH);
64
+ Data_Get_Struct(self, xmlDoc, doc);
65
+
66
+ // find start node
67
+ node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
68
+ if(node == NULL) {
69
+ rb_raise(rb_eVerificationError, "start node not found");
70
+ goto done;
71
+ }
72
+
73
+ keyManager = getKeyManager(rb_hash);
74
+ if (keyManager == NULL) {
75
+ rb_raise(rb_eKeystoreError, "failed to create key manager");
76
+ goto done;
77
+ }
78
+
79
+ // create signature context, we don't need keys manager in this example
80
+ dsigCtx = xmlSecDSigCtxCreate(keyManager);
81
+ if(dsigCtx == NULL) {
82
+ rb_raise(rb_eVerificationError, "failed to create signature context");
83
+ goto done;
84
+ }
85
+
86
+ // verify signature
87
+ if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
88
+ rb_raise(rb_eVerificationError, "signature could not be verified");
89
+ goto done;
90
+ }
91
+
92
+ if(dsigCtx->status == xmlSecDSigStatusSucceeded) {
93
+ result = Qtrue;
94
+ }
95
+
96
+ done:
97
+ if(dsigCtx != NULL) {
98
+ xmlSecDSigCtxDestroy(dsigCtx);
99
+ }
100
+
101
+ if (keyManager != NULL) {
102
+ xmlSecKeysMngrDestroy(keyManager);
103
+ }
104
+
105
+ return result;
106
+ }