nokogiri-xmlsec-instructure 0.11.0 → 0.12.0
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.
- checksums.yaml +4 -4
- data/ext/nokogiri_ext_xmlsec/common.h +13 -0
- data/ext/nokogiri_ext_xmlsec/init.c +71 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_decrypt_with_key.c +89 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_encrypt_with_key.c +227 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_helpers_set_attribute_id.c +93 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_init.c +30 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_sign.c +271 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_verify_with.c +261 -0
- data/ext/nokogiri_ext_xmlsec/options.c +209 -0
- data/ext/nokogiri_ext_xmlsec/options.h +38 -0
- data/ext/nokogiri_ext_xmlsec/shutdown.c +12 -0
- data/ext/nokogiri_ext_xmlsec/util.c +140 -0
- data/ext/nokogiri_ext_xmlsec/util.h +42 -0
- data/ext/nokogiri_ext_xmlsec/xmlsecrb.h +49 -0
- data/lib/xmlsec/version.rb +1 -1
- metadata +17 -4
- data/lib/nokogiri_ext_xmlsec.bundle +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b9e1360203a6f2ce84bc88abe8d731d657a88a02642d5cc26827f3dac53c6da
|
4
|
+
data.tar.gz: 1d5fa5d3e4570b50716268d2cd65a7159a0170466babb829042169c71c1e20b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97d2d274344a10a9be1fe7c7c354882ff1d1d1a56ba38cd28c4ba8f2e1f6e64c4aa4f8ac143361fda0187b1ef69ee2ac8cdec0688164c67a83567aab7a1286be
|
7
|
+
data.tar.gz: 477f5c98388d76e02cbdaf913ff21328c3ed397fd5797c363d7dfc5d9641f25657eea0bf0b027ac599d0620976c8e72f12de5c19aa3a0fcb77bc01bf69ff3de9
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#include "xmlsecrb.h"
|
2
|
+
#include "util.h"
|
3
|
+
|
4
|
+
#include <xmlsec/dl.h>
|
5
|
+
#include <xmlsec/errors.h>
|
6
|
+
|
7
|
+
#ifndef XMLSEC_NO_XSLT
|
8
|
+
#include <libxslt/xslt.h>
|
9
|
+
#include <libxslt/security.h>
|
10
|
+
#endif /* XMLSEC_NO_XSLT */
|
11
|
+
|
12
|
+
EXTENSION_EXPORT
|
13
|
+
void Init_nokogiri_ext_xmlsec() {
|
14
|
+
#ifndef XMLSEC_NO_XSLT
|
15
|
+
xsltSecurityPrefsPtr xsltSecPrefs = NULL;
|
16
|
+
#endif /* XMLSEC_NO_XSLT */
|
17
|
+
|
18
|
+
/* xmlsec proper */
|
19
|
+
// libxml
|
20
|
+
xmlInitParser();
|
21
|
+
LIBXML_TEST_VERSION
|
22
|
+
xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
|
23
|
+
// xslt
|
24
|
+
|
25
|
+
#ifndef XMLSEC_NO_XSLT
|
26
|
+
xmlIndentTreeOutput = 1;
|
27
|
+
|
28
|
+
/* Disable all XSLT options that give filesystem and network access. */
|
29
|
+
xsltSecPrefs = xsltNewSecurityPrefs();
|
30
|
+
xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_READ_FILE, xsltSecurityForbid);
|
31
|
+
xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_WRITE_FILE, xsltSecurityForbid);
|
32
|
+
xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_CREATE_DIRECTORY, xsltSecurityForbid);
|
33
|
+
xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_READ_NETWORK, xsltSecurityForbid);
|
34
|
+
xsltSetSecurityPrefs(xsltSecPrefs, XSLT_SECPREF_WRITE_NETWORK, xsltSecurityForbid);
|
35
|
+
xsltSetDefaultSecurityPrefs(xsltSecPrefs);
|
36
|
+
#endif /* XMLSEC_NO_XSLT */
|
37
|
+
|
38
|
+
// xmlsec
|
39
|
+
|
40
|
+
if (xmlSecInit() < 0) {
|
41
|
+
rb_raise(rb_eRuntimeError, "xmlsec initialization failed");
|
42
|
+
return;
|
43
|
+
}
|
44
|
+
if (xmlSecCheckVersion() != 1) {
|
45
|
+
rb_raise(rb_eRuntimeError, "xmlsec version is not compatible");
|
46
|
+
return;
|
47
|
+
}
|
48
|
+
// load crypto
|
49
|
+
#ifdef XMLSEC_CRYPTO_DYNAMIC_LOADING
|
50
|
+
if(xmlSecCryptoDLLoadLibrary(NULL) < 0) {
|
51
|
+
rb_raise(rb_eRuntimeError,
|
52
|
+
"Error: unable to load default xmlsec-crypto library. Make sure"
|
53
|
+
"that you have it installed and check shared libraries path\n"
|
54
|
+
"(LD_LIBRARY_PATH) envornment variable.\n");
|
55
|
+
return;
|
56
|
+
}
|
57
|
+
#endif /* XMLSEC_CRYPTO_DYNAMIC_LOADING */
|
58
|
+
// init crypto
|
59
|
+
if (xmlSecCryptoAppInit(NULL) < 0) {
|
60
|
+
rb_raise(rb_eRuntimeError, "unable to initialize crypto engine");
|
61
|
+
return;
|
62
|
+
}
|
63
|
+
// init xmlsec-crypto library
|
64
|
+
if (xmlSecCryptoInit() < 0) {
|
65
|
+
rb_raise(rb_eRuntimeError, "xmlsec-crypto initialization failed");
|
66
|
+
}
|
67
|
+
|
68
|
+
/* ruby classes & objects */
|
69
|
+
Init_Nokogiri_ext();
|
70
|
+
}
|
71
|
+
|
@@ -0,0 +1,89 @@
|
|
1
|
+
#include "xmlsecrb.h"
|
2
|
+
#include "util.h"
|
3
|
+
|
4
|
+
VALUE decrypt_with_key(VALUE self, VALUE rb_key_name, VALUE rb_key) {
|
5
|
+
VALUE rb_exception_result = Qnil;
|
6
|
+
const char* exception_message = NULL;
|
7
|
+
|
8
|
+
xmlNodePtr node = NULL;
|
9
|
+
xmlSecEncCtxPtr encCtx = NULL;
|
10
|
+
xmlSecKeysMngrPtr keyManager = NULL;
|
11
|
+
char *key = NULL;
|
12
|
+
char *keyName = NULL;
|
13
|
+
unsigned int keyLength = 0;
|
14
|
+
|
15
|
+
resetXmlSecError();
|
16
|
+
|
17
|
+
Check_Type(rb_key, T_STRING);
|
18
|
+
Check_Type(rb_key_name, T_STRING);
|
19
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
20
|
+
key = RSTRING_PTR(rb_key);
|
21
|
+
keyLength = RSTRING_LEN(rb_key);
|
22
|
+
keyName = StringValueCStr(rb_key_name);
|
23
|
+
|
24
|
+
keyManager = createKeyManagerWithSingleKey(key, keyLength, keyName,
|
25
|
+
&rb_exception_result,
|
26
|
+
&exception_message);
|
27
|
+
if (keyManager == NULL) {
|
28
|
+
// Propagate the exception.
|
29
|
+
goto done;
|
30
|
+
}
|
31
|
+
|
32
|
+
// create encryption context
|
33
|
+
encCtx = xmlSecEncCtxCreate(keyManager);
|
34
|
+
if(encCtx == NULL) {
|
35
|
+
rb_exception_result = rb_eDecryptionError;
|
36
|
+
exception_message = "failed to create encryption context";
|
37
|
+
goto done;
|
38
|
+
}
|
39
|
+
// don't let xmlsec free the node we're looking at out from under us
|
40
|
+
encCtx->flags |= XMLSEC_ENC_RETURN_REPLACED_NODE;
|
41
|
+
|
42
|
+
#ifdef XMLSEC_KEYINFO_FLAGS_LAX_KEY_SEARCH
|
43
|
+
// Enable lax key search, since xmlsec 1.3.0
|
44
|
+
encCtx->keyInfoReadCtx.flags |= XMLSEC_KEYINFO_FLAGS_LAX_KEY_SEARCH;
|
45
|
+
#endif
|
46
|
+
|
47
|
+
// decrypt the data
|
48
|
+
if((xmlSecEncCtxDecrypt(encCtx, node) < 0) || (encCtx->result == NULL)) {
|
49
|
+
rb_exception_result = rb_eDecryptionError;
|
50
|
+
exception_message = "decryption failed";
|
51
|
+
goto done;
|
52
|
+
}
|
53
|
+
|
54
|
+
if(encCtx->resultReplaced == 0) {
|
55
|
+
rb_exception_result = rb_eDecryptionError;
|
56
|
+
exception_message = "Not implemented: don't know how to handle decrypted, non-XML data yet";
|
57
|
+
goto done;
|
58
|
+
}
|
59
|
+
|
60
|
+
done:
|
61
|
+
// cleanup
|
62
|
+
if(encCtx != NULL) {
|
63
|
+
// the replaced node is orphaned, but not freed; let Nokogiri
|
64
|
+
// own it now
|
65
|
+
if(encCtx->replacedNodeList != NULL) {
|
66
|
+
noko_xml_document_pin_node(encCtx->replacedNodeList);
|
67
|
+
// no really, please don't free it
|
68
|
+
encCtx->replacedNodeList = NULL;
|
69
|
+
}
|
70
|
+
xmlSecEncCtxDestroy(encCtx);
|
71
|
+
}
|
72
|
+
|
73
|
+
if (keyManager != NULL) {
|
74
|
+
xmlSecKeysMngrDestroy(keyManager);
|
75
|
+
}
|
76
|
+
|
77
|
+
xmlSecErrorsSetCallback(xmlSecErrorsDefaultCallback);
|
78
|
+
|
79
|
+
if(rb_exception_result != Qnil) {
|
80
|
+
if (hasXmlSecLastError()) {
|
81
|
+
rb_raise(rb_exception_result, "%s, XmlSec error: %s", exception_message,
|
82
|
+
getXmlSecLastError());
|
83
|
+
} else {
|
84
|
+
rb_raise(rb_exception_result, "%s", exception_message);
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
return Qnil;
|
89
|
+
}
|
@@ -0,0 +1,227 @@
|
|
1
|
+
#include "xmlsecrb.h"
|
2
|
+
#include "options.h"
|
3
|
+
#include "util.h"
|
4
|
+
|
5
|
+
// Encrypes the XML Document document using XMLEnc.
|
6
|
+
//
|
7
|
+
// Expects 3 positional arguments:
|
8
|
+
// rb_rsa_key_name - String with name of the rsa key. May be the empty.
|
9
|
+
// rb_rsa_key - A PEM encoded rsa key for signing.
|
10
|
+
// rb_opts - An ruby hash that configures the encryption options.
|
11
|
+
// See XmlEncOptions struct for possible values.
|
12
|
+
VALUE encrypt_with_key(VALUE self, VALUE rb_rsa_key_name, VALUE rb_rsa_key,
|
13
|
+
VALUE rb_opts) {
|
14
|
+
VALUE rb_exception_result = Qnil;
|
15
|
+
VALUE rb_cert = Qnil;
|
16
|
+
const char* exception_message = NULL;
|
17
|
+
|
18
|
+
xmlDocPtr doc = NULL;
|
19
|
+
xmlNodePtr node = NULL;
|
20
|
+
xmlNodePtr encDataNode = NULL;
|
21
|
+
xmlNodePtr encKeyNode = NULL;
|
22
|
+
xmlNodePtr keyInfoNode = NULL;
|
23
|
+
xmlSecEncCtxPtr encCtx = NULL;
|
24
|
+
xmlSecKeysMngrPtr keyManager = NULL;
|
25
|
+
char *keyName = NULL;
|
26
|
+
char *key = NULL;
|
27
|
+
char *certificate = NULL;
|
28
|
+
unsigned int keyLength = 0;
|
29
|
+
unsigned int certificateLength = 0;
|
30
|
+
|
31
|
+
resetXmlSecError();
|
32
|
+
|
33
|
+
Check_Type(rb_rsa_key, T_STRING);
|
34
|
+
Check_Type(rb_opts, T_HASH);
|
35
|
+
|
36
|
+
key = RSTRING_PTR(rb_rsa_key);
|
37
|
+
keyLength = RSTRING_LEN(rb_rsa_key);
|
38
|
+
if (rb_rsa_key_name != Qnil) {
|
39
|
+
Check_Type(rb_rsa_key_name, T_STRING);
|
40
|
+
keyName = StringValueCStr(rb_rsa_key_name);
|
41
|
+
}
|
42
|
+
|
43
|
+
rb_cert = rb_hash_aref(rb_opts, ID2SYM(rb_intern("cert")));
|
44
|
+
if (!NIL_P(rb_cert)) {
|
45
|
+
Check_Type(rb_cert, T_STRING);
|
46
|
+
certificate = RSTRING_PTR(rb_cert);
|
47
|
+
certificateLength = RSTRING_LEN(rb_cert);
|
48
|
+
}
|
49
|
+
|
50
|
+
XmlEncOptions options;
|
51
|
+
if (!GetXmlEncOptions(rb_opts, &options, &rb_exception_result,
|
52
|
+
&exception_message)) {
|
53
|
+
goto done;
|
54
|
+
}
|
55
|
+
|
56
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
57
|
+
doc = node->doc;
|
58
|
+
|
59
|
+
// create encryption template to encrypt XML file and replace
|
60
|
+
// its content with encryption result
|
61
|
+
encDataNode = xmlSecTmplEncDataCreate(doc, options.block_encryption, NULL,
|
62
|
+
xmlSecTypeEncElement, NULL, NULL);
|
63
|
+
if(encDataNode == NULL) {
|
64
|
+
rb_exception_result = rb_eEncryptionError;
|
65
|
+
exception_message = "failed to create encryption template";
|
66
|
+
goto done;
|
67
|
+
}
|
68
|
+
|
69
|
+
// we want to put encrypted data in the <enc:CipherValue/> node
|
70
|
+
if(xmlSecTmplEncDataEnsureCipherValue(encDataNode) == NULL) {
|
71
|
+
rb_exception_result = rb_eEncryptionError;
|
72
|
+
exception_message = "failed to add CipherValue node";
|
73
|
+
goto done;
|
74
|
+
}
|
75
|
+
|
76
|
+
// add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to put key name in the
|
77
|
+
// signed document
|
78
|
+
keyInfoNode = xmlSecTmplEncDataEnsureKeyInfo(encDataNode, NULL);
|
79
|
+
if(keyInfoNode == NULL) {
|
80
|
+
rb_exception_result = rb_eEncryptionError;
|
81
|
+
exception_message = "failed to add key info";
|
82
|
+
goto done;
|
83
|
+
}
|
84
|
+
|
85
|
+
if(certificate) {
|
86
|
+
// add <dsig:X509Data/>
|
87
|
+
if(xmlSecTmplKeyInfoAddX509Data(keyInfoNode) == NULL) {
|
88
|
+
rb_exception_result = rb_eSigningError;
|
89
|
+
exception_message = "failed to add X509Data node";
|
90
|
+
goto done;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
if(keyName != NULL) {
|
95
|
+
if(xmlSecTmplKeyInfoAddKeyName(keyInfoNode, NULL) == NULL) {
|
96
|
+
rb_exception_result = rb_eEncryptionError;
|
97
|
+
exception_message = "failed to add key name";
|
98
|
+
goto done;
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
if ((keyManager = createKeyManagerWithSingleKey(
|
103
|
+
key, keyLength, keyName,
|
104
|
+
&rb_exception_result,
|
105
|
+
&exception_message)) == NULL) {
|
106
|
+
// Propagate the exception.
|
107
|
+
goto done;
|
108
|
+
}
|
109
|
+
|
110
|
+
// create encryption context, we don't need keys manager in this example
|
111
|
+
encCtx = xmlSecEncCtxCreate(keyManager);
|
112
|
+
if(encCtx == NULL) {
|
113
|
+
rb_exception_result = rb_eEncryptionError;
|
114
|
+
exception_message = "failed to create encryption context";
|
115
|
+
goto done;
|
116
|
+
}
|
117
|
+
|
118
|
+
#ifdef XMLSEC_KEYINFO_FLAGS_LAX_KEY_SEARCH
|
119
|
+
// Enable lax key search, since xmlsec 1.3.0
|
120
|
+
encCtx->keyInfoWriteCtx.flags |= XMLSEC_KEYINFO_FLAGS_LAX_KEY_SEARCH;
|
121
|
+
#endif
|
122
|
+
|
123
|
+
// Generate the symmetric key.
|
124
|
+
encCtx->encKey = xmlSecKeyGenerateByName(BAD_CAST options.key_type, options.key_bits,
|
125
|
+
xmlSecKeyDataTypeSession);
|
126
|
+
|
127
|
+
if(encCtx->encKey == NULL) {
|
128
|
+
rb_exception_result = rb_eDecryptionError;
|
129
|
+
exception_message = "failed to generate session key";
|
130
|
+
goto done;
|
131
|
+
}
|
132
|
+
|
133
|
+
if(certificate) {
|
134
|
+
// load certificate and add to the key
|
135
|
+
if(xmlSecCryptoAppKeyCertLoadMemory(encCtx->encKey,
|
136
|
+
(xmlSecByte *)certificate,
|
137
|
+
certificateLength,
|
138
|
+
xmlSecKeyDataFormatPem) < 0) {
|
139
|
+
rb_exception_result = rb_eSigningError;
|
140
|
+
exception_message = "failed to load certificate";
|
141
|
+
goto done;
|
142
|
+
}
|
143
|
+
}
|
144
|
+
|
145
|
+
// We don't want xmlsec to free the node we're looking at out from under us,
|
146
|
+
// since it's still referenced from a Ruby object.
|
147
|
+
encCtx->flags |= XMLSEC_ENC_RETURN_REPLACED_NODE;
|
148
|
+
|
149
|
+
// Set key name.
|
150
|
+
if(keyName) {
|
151
|
+
if(xmlSecKeySetName(encCtx->encKey, (xmlSecByte *)keyName) < 0) {
|
152
|
+
rb_exception_result = rb_eEncryptionError;
|
153
|
+
exception_message = "failed to set key name";
|
154
|
+
goto done;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
// Add <enc:EncryptedKey/> node to the <dsig:KeyInfo/> tag to include
|
159
|
+
// the session key.
|
160
|
+
encKeyNode = xmlSecTmplKeyInfoAddEncryptedKey(keyInfoNode,
|
161
|
+
options.key_transport, // encMethodId encryptionMethod
|
162
|
+
NULL, // xmlChar *idAttribute
|
163
|
+
NULL, // xmlChar *typeAttribute
|
164
|
+
NULL // xmlChar *recipient
|
165
|
+
);
|
166
|
+
if (encKeyNode == NULL) {
|
167
|
+
rb_exception_result = rb_eEncryptionError;
|
168
|
+
exception_message = "failed to add encrypted key node";
|
169
|
+
goto done;
|
170
|
+
}
|
171
|
+
if (xmlSecTmplEncDataEnsureCipherValue(encKeyNode) == NULL) {
|
172
|
+
rb_exception_result = rb_eEncryptionError;
|
173
|
+
exception_message = "failed to add encrypted cipher value";
|
174
|
+
goto done;
|
175
|
+
}
|
176
|
+
|
177
|
+
// encrypt the data
|
178
|
+
if(xmlSecEncCtxXmlEncrypt(encCtx, encDataNode, node) < 0) {
|
179
|
+
rb_exception_result = rb_eEncryptionError;
|
180
|
+
exception_message = "encryption failed";
|
181
|
+
goto done;
|
182
|
+
}
|
183
|
+
|
184
|
+
// the template is inserted in the doc, so don't free it
|
185
|
+
encDataNode = NULL;
|
186
|
+
encKeyNode = NULL;
|
187
|
+
|
188
|
+
done:
|
189
|
+
|
190
|
+
/* cleanup */
|
191
|
+
if(encCtx != NULL) {
|
192
|
+
// the replaced node is orphaned, but not freed; let Nokogiri
|
193
|
+
// own it now
|
194
|
+
if (encCtx->replacedNodeList != NULL) {
|
195
|
+
noko_xml_document_pin_node(encCtx->replacedNodeList);
|
196
|
+
// no really, please don't free it
|
197
|
+
encCtx->replacedNodeList = NULL;
|
198
|
+
}
|
199
|
+
|
200
|
+
xmlSecEncCtxDestroy(encCtx);
|
201
|
+
}
|
202
|
+
|
203
|
+
if (encKeyNode != NULL) {
|
204
|
+
xmlFreeNode(encKeyNode);
|
205
|
+
}
|
206
|
+
|
207
|
+
if(encDataNode != NULL) {
|
208
|
+
xmlFreeNode(encDataNode);
|
209
|
+
}
|
210
|
+
|
211
|
+
if (keyManager != NULL) {
|
212
|
+
xmlSecKeysMngrDestroy(keyManager);
|
213
|
+
}
|
214
|
+
|
215
|
+
xmlSecErrorsSetCallback(xmlSecErrorsDefaultCallback);
|
216
|
+
|
217
|
+
if(rb_exception_result != Qnil) {
|
218
|
+
if (hasXmlSecLastError()) {
|
219
|
+
rb_raise(rb_exception_result, "%s, XmlSec error: %s", exception_message,
|
220
|
+
getXmlSecLastError());
|
221
|
+
} else {
|
222
|
+
rb_raise(rb_exception_result, "%s", exception_message);
|
223
|
+
}
|
224
|
+
}
|
225
|
+
|
226
|
+
return Qnil;
|
227
|
+
}
|
@@ -0,0 +1,93 @@
|
|
1
|
+
#include "xmlsecrb.h"
|
2
|
+
#include "util.h"
|
3
|
+
|
4
|
+
VALUE set_id_attribute(VALUE self, VALUE rb_attr_name) {
|
5
|
+
VALUE rb_exception_result = Qnil;
|
6
|
+
const char* exception_message = NULL;
|
7
|
+
|
8
|
+
xmlNodePtr node = NULL;
|
9
|
+
xmlAttrPtr attr = NULL;
|
10
|
+
xmlAttrPtr tmp = NULL;
|
11
|
+
xmlChar *name = NULL;
|
12
|
+
char *idName = NULL;
|
13
|
+
char *exception_attribute_arg = NULL;
|
14
|
+
|
15
|
+
resetXmlSecError();
|
16
|
+
|
17
|
+
Noko_Node_Get_Struct(self, xmlNode, node);
|
18
|
+
Check_Type(rb_attr_name, T_STRING);
|
19
|
+
idName = StringValueCStr(rb_attr_name);
|
20
|
+
|
21
|
+
// find pointer to id attribute
|
22
|
+
attr = xmlHasProp(node, (const xmlChar* )idName);
|
23
|
+
if((attr == NULL) || (attr->children == NULL)) {
|
24
|
+
rb_exception_result = rb_eRuntimeError;
|
25
|
+
exception_message = "Can't find attribute to add register as id";
|
26
|
+
goto done;
|
27
|
+
}
|
28
|
+
|
29
|
+
// get the attribute (id) value
|
30
|
+
name = xmlNodeListGetString(node->doc, attr->children, 1);
|
31
|
+
if(name == NULL) {
|
32
|
+
rb_exception_result = rb_eRuntimeError;
|
33
|
+
exception_message = "has no value";
|
34
|
+
exception_attribute_arg = idName;
|
35
|
+
goto done;
|
36
|
+
}
|
37
|
+
|
38
|
+
// check that we don't have that id already registered
|
39
|
+
tmp = xmlGetID(node->doc, name);
|
40
|
+
if(tmp != NULL) {
|
41
|
+
rb_exception_result = rb_eRuntimeError;
|
42
|
+
exception_message = "is already an ID";
|
43
|
+
exception_attribute_arg = idName;
|
44
|
+
goto done;
|
45
|
+
}
|
46
|
+
|
47
|
+
// finally register id
|
48
|
+
xmlAddID(NULL, node->doc, name, attr);
|
49
|
+
|
50
|
+
done:
|
51
|
+
// and do not forget to cleanup
|
52
|
+
if (name) {
|
53
|
+
xmlFree(name);
|
54
|
+
}
|
55
|
+
|
56
|
+
xmlSecErrorsSetCallback(xmlSecErrorsDefaultCallback);
|
57
|
+
|
58
|
+
if(rb_exception_result != Qnil) {
|
59
|
+
if (exception_attribute_arg) {
|
60
|
+
if (hasXmlSecLastError()) {
|
61
|
+
rb_raise(rb_exception_result, "Attribute %s %s, XmlSec error: %s",
|
62
|
+
exception_attribute_arg, exception_message, getXmlSecLastError());
|
63
|
+
} else {
|
64
|
+
rb_raise(rb_exception_result, "Attribute %s %s",
|
65
|
+
exception_attribute_arg, exception_message);
|
66
|
+
}
|
67
|
+
} else {
|
68
|
+
if (hasXmlSecLastError()) {
|
69
|
+
rb_raise(rb_exception_result, "%s, XmlSec error: %s", exception_message,
|
70
|
+
getXmlSecLastError());
|
71
|
+
} else {
|
72
|
+
rb_raise(rb_exception_result, "%s", exception_message);
|
73
|
+
}
|
74
|
+
}
|
75
|
+
}
|
76
|
+
|
77
|
+
return Qtrue;
|
78
|
+
}
|
79
|
+
|
80
|
+
VALUE get_id(VALUE self, VALUE rb_id)
|
81
|
+
{
|
82
|
+
xmlAttrPtr prop;
|
83
|
+
xmlDocPtr doc;
|
84
|
+
|
85
|
+
Check_Type(rb_id, T_STRING);
|
86
|
+
Noko_Node_Get_Struct(self, xmlDoc, doc);
|
87
|
+
prop = xmlGetID(doc, (const xmlChar *)StringValueCStr(rb_id));
|
88
|
+
if (prop) {
|
89
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
|
90
|
+
} else {
|
91
|
+
return Qnil;
|
92
|
+
}
|
93
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#include "xmlsecrb.h"
|
2
|
+
|
3
|
+
VALUE rb_cNokogiri_XML_Document = Qnil;
|
4
|
+
VALUE rb_cNokogiri_XML_Node = Qnil;
|
5
|
+
VALUE rb_eSigningError = Qnil;
|
6
|
+
VALUE rb_eVerificationError = Qnil;
|
7
|
+
VALUE rb_eKeystoreError = Qnil;
|
8
|
+
VALUE rb_eEncryptionError = Qnil;
|
9
|
+
VALUE rb_eDecryptionError = Qnil;
|
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_Node, "sign!", sign, 1);
|
19
|
+
rb_define_method(rb_cNokogiri_XML_Node, "verify_with", verify_with, 1);
|
20
|
+
rb_define_method(rb_cNokogiri_XML_Node, "encrypt_with_key", encrypt_with_key, 3);
|
21
|
+
rb_define_method(rb_cNokogiri_XML_Node, "decrypt_with_key", decrypt_with_key, 2);
|
22
|
+
rb_define_method(rb_cNokogiri_XML_Document, "get_id", get_id, 1);
|
23
|
+
rb_define_method(rb_cNokogiri_XML_Node, "set_id_attribute", set_id_attribute, 1);
|
24
|
+
|
25
|
+
rb_eSigningError = rb_define_class_under(XMLSec, "SigningError", rb_eRuntimeError);
|
26
|
+
rb_eVerificationError = rb_define_class_under(XMLSec, "VerificationError", rb_eRuntimeError);
|
27
|
+
rb_eKeystoreError = rb_define_class_under(XMLSec, "KeystoreError", rb_eRuntimeError);
|
28
|
+
rb_eEncryptionError = rb_define_class_under(XMLSec, "EncryptionError", rb_eRuntimeError);
|
29
|
+
rb_eDecryptionError = rb_define_class_under(XMLSec, "DecryptionError", rb_eRuntimeError);
|
30
|
+
}
|