nokogiri-xmlsec-me-harder 0.9.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 +7 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/Guardfile +13 -0
- data/LICENSE.txt +22 -0
- data/README.md +123 -0
- data/Rakefile +30 -0
- data/ext/nokogiri_ext_xmlsec/common.h +13 -0
- data/ext/nokogiri_ext_xmlsec/extconf.rb +27 -0
- data/ext/nokogiri_ext_xmlsec/init.c +76 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_decrypt_with_key.c +82 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_encrypt_with_key.c +169 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_helpers_set_attribute_id.c +76 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_init.c +32 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_sign_certificate.c +186 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_sign_rsa.c +167 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_verify_signature_certificates.c +138 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_verify_signature_named_keys.c +133 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_verify_signature_rsa.c +76 -0
- data/ext/nokogiri_ext_xmlsec/options.c +166 -0
- data/ext/nokogiri_ext_xmlsec/options.h +36 -0
- data/ext/nokogiri_ext_xmlsec/shutdown.c +12 -0
- data/ext/nokogiri_ext_xmlsec/util.c +139 -0
- data/ext/nokogiri_ext_xmlsec/util.h +42 -0
- data/ext/nokogiri_ext_xmlsec/xmlsecrb.h +44 -0
- data/lib/nokogiri-xmlsec.rb +1 -0
- data/lib/xmlsec.rb +104 -0
- data/lib/xmlsec/version.rb +3 -0
- data/nokogiri-xmlsec-me-harder.gemspec +39 -0
- data/spec/fixtures/cert/server.crt +14 -0
- data/spec/fixtures/cert/server.csr +11 -0
- data/spec/fixtures/cert/server.key.decrypted +15 -0
- data/spec/fixtures/cert/server.key.encrypted +18 -0
- data/spec/fixtures/hate.xml +7 -0
- data/spec/fixtures/pwned.xml +1 -0
- data/spec/fixtures/rsa.pem +15 -0
- data/spec/fixtures/rsa.pub +6 -0
- data/spec/fixtures/sign2-doc.xml +6 -0
- data/spec/fixtures/sign2-result.xml +25 -0
- data/spec/fixtures/sign3-result.xml +38 -0
- data/spec/lib/nokogiri/xml/document/encryption_and_decryption_spec.rb +34 -0
- data/spec/lib/nokogiri/xml/document/signing_and_verifying_spec.rb +123 -0
- data/spec/lib/nokogiri/xml/document/unsafe_xml_spec.rb +61 -0
- data/spec/spec_helper.rb +10 -0
- metadata +213 -0
@@ -0,0 +1,76 @@
|
|
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
|
+
Data_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
|
+
if(rb_exception_result != Qnil) {
|
57
|
+
if (exception_attribute_arg) {
|
58
|
+
if (hasXmlSecLastError()) {
|
59
|
+
rb_raise(rb_exception_result, "Attribute %s %s, XmlSec error: %s",
|
60
|
+
exception_attribute_arg, exception_message, getXmlSecLastError());
|
61
|
+
} else {
|
62
|
+
rb_raise(rb_exception_result, "Attribute %s %s",
|
63
|
+
exception_attribute_arg, exception_message);
|
64
|
+
}
|
65
|
+
} else {
|
66
|
+
if (hasXmlSecLastError()) {
|
67
|
+
rb_raise(rb_exception_result, "%s, XmlSec error: %s", exception_message,
|
68
|
+
getXmlSecLastError());
|
69
|
+
} else {
|
70
|
+
rb_raise(rb_exception_result, "%s", exception_message);
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
return Qtrue;
|
76
|
+
}
|
@@ -0,0 +1,32 @@
|
|
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_Document, "sign_with_key", sign_with_key, 1);
|
19
|
+
rb_define_method(rb_cNokogiri_XML_Document, "sign_with_certificate", sign_with_certificate, 1);
|
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, 3);
|
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,186 @@
|
|
1
|
+
#include "xmlsecrb.h"
|
2
|
+
|
3
|
+
#include "options.h"
|
4
|
+
#include "util.h"
|
5
|
+
|
6
|
+
// Appends an xmlsig <dsig:Signature> node to document stored in |self|
|
7
|
+
// with a signature based on the given key and cert.
|
8
|
+
//
|
9
|
+
// Expects a ruby hash for the signing arguments.
|
10
|
+
// Hash parameters:
|
11
|
+
// :key - A PEM encoded rsa key for signing.
|
12
|
+
// :cert - The public cert to include with the signature.
|
13
|
+
// :signature_alg - Algorithm identified by the URL fragment. Supported algorithms
|
14
|
+
// taken from http://www.w3.org/TR/xmldsig-core
|
15
|
+
// :digest_alg - Algorithm identified by the URL fragment. Supported algorithms
|
16
|
+
// taken from http://www.w3.org/TR/xmldsig-core
|
17
|
+
// :name - [optional] String with name of the rsa key.
|
18
|
+
// :uri - [optional] The URI attribute for the <Reference> node in the
|
19
|
+
// signature.
|
20
|
+
VALUE sign_with_certificate(VALUE self, VALUE rb_opts) {
|
21
|
+
VALUE rb_exception_result = Qnil;
|
22
|
+
const char* exception_message = NULL;
|
23
|
+
|
24
|
+
xmlDocPtr doc = NULL;
|
25
|
+
xmlNodePtr signNode = NULL;
|
26
|
+
xmlNodePtr refNode = NULL;
|
27
|
+
xmlNodePtr keyInfoNode = NULL;
|
28
|
+
xmlSecDSigCtxPtr dsigCtx = NULL;
|
29
|
+
char *keyName = "";
|
30
|
+
char *certificate = NULL;
|
31
|
+
char *rsaKey = NULL;
|
32
|
+
char *refUri = NULL;
|
33
|
+
unsigned int rsaKeyLength = 0;
|
34
|
+
unsigned int certificateLength = 0;
|
35
|
+
|
36
|
+
resetXmlSecError();
|
37
|
+
|
38
|
+
VALUE rb_rsa_key = rb_hash_aref(rb_opts, ID2SYM(rb_intern("key")));
|
39
|
+
VALUE rb_cert = rb_hash_aref(rb_opts, ID2SYM(rb_intern("cert")));
|
40
|
+
VALUE rb_signature_alg = rb_hash_aref(rb_opts, ID2SYM(rb_intern("signature_alg")));
|
41
|
+
VALUE rb_digest_alg = rb_hash_aref(rb_opts, ID2SYM(rb_intern("digest_alg")));
|
42
|
+
VALUE rb_uri = rb_hash_aref(rb_opts, ID2SYM(rb_intern("uri")));
|
43
|
+
VALUE rb_key_name = rb_hash_aref(rb_opts, ID2SYM(rb_intern("name")));
|
44
|
+
|
45
|
+
Check_Type(rb_rsa_key, T_STRING);
|
46
|
+
Check_Type(rb_cert, T_STRING);
|
47
|
+
Check_Type(rb_signature_alg, T_STRING);
|
48
|
+
Check_Type(rb_digest_alg, T_STRING);
|
49
|
+
|
50
|
+
rsaKey = RSTRING_PTR(rb_rsa_key);
|
51
|
+
rsaKeyLength = RSTRING_LEN(rb_rsa_key);
|
52
|
+
certificate = RSTRING_PTR(rb_cert);
|
53
|
+
certificateLength = RSTRING_LEN(rb_cert);
|
54
|
+
|
55
|
+
if (!NIL_P(rb_key_name)) {
|
56
|
+
Check_Type(rb_key_name, T_STRING);
|
57
|
+
keyName = StringValueCStr(rb_key_name);
|
58
|
+
}
|
59
|
+
if (!NIL_P(rb_uri)) {
|
60
|
+
Check_Type(rb_uri, T_STRING);
|
61
|
+
refUri = StringValueCStr(rb_uri);
|
62
|
+
}
|
63
|
+
|
64
|
+
Data_Get_Struct(self, xmlDoc, doc);
|
65
|
+
xmlSecTransformId signature_algorithm = GetSignatureMethod(rb_signature_alg,
|
66
|
+
&rb_exception_result, &exception_message);
|
67
|
+
if (signature_algorithm == xmlSecTransformIdUnknown) {
|
68
|
+
// Propagate exception.
|
69
|
+
goto done;
|
70
|
+
}
|
71
|
+
|
72
|
+
// create signature template for enveloped signature.
|
73
|
+
signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId,
|
74
|
+
signature_algorithm, NULL);
|
75
|
+
if (signNode == NULL) {
|
76
|
+
rb_exception_result = rb_eSigningError;
|
77
|
+
exception_message = "failed to create signature template";
|
78
|
+
goto done;
|
79
|
+
}
|
80
|
+
|
81
|
+
// add <dsig:Signature/> node to the doc
|
82
|
+
xmlAddChild(xmlDocGetRootElement(doc), signNode);
|
83
|
+
|
84
|
+
// add reference
|
85
|
+
xmlSecTransformId digest_algorithm = GetDigestMethod(rb_digest_alg,
|
86
|
+
&rb_exception_result, &exception_message);
|
87
|
+
if (digest_algorithm == xmlSecTransformIdUnknown) {
|
88
|
+
// Propagate exception.
|
89
|
+
goto done;
|
90
|
+
}
|
91
|
+
refNode = xmlSecTmplSignatureAddReference(signNode, digest_algorithm,
|
92
|
+
NULL, (const xmlChar *)refUri, NULL);
|
93
|
+
if(refNode == NULL) {
|
94
|
+
rb_exception_result = rb_eSigningError;
|
95
|
+
exception_message = "failed to add reference to signature template";
|
96
|
+
goto done;
|
97
|
+
}
|
98
|
+
|
99
|
+
// add enveloped transform
|
100
|
+
if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL) {
|
101
|
+
rb_exception_result = rb_eSigningError;
|
102
|
+
exception_message = "failed to add enveloped transform to reference";
|
103
|
+
goto done;
|
104
|
+
}
|
105
|
+
|
106
|
+
if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformExclC14NId) == NULL) {
|
107
|
+
rb_exception_result = rb_eSigningError;
|
108
|
+
exception_message = "failed to add canonicalization transform to reference";
|
109
|
+
goto done;
|
110
|
+
}
|
111
|
+
|
112
|
+
// add <dsig:KeyInfo/> and <dsig:X509Data/>
|
113
|
+
keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL);
|
114
|
+
if(keyInfoNode == NULL) {
|
115
|
+
rb_exception_result = rb_eSigningError;
|
116
|
+
exception_message = "failed to add key info";
|
117
|
+
goto done;
|
118
|
+
}
|
119
|
+
|
120
|
+
if(xmlSecTmplKeyInfoAddX509Data(keyInfoNode) == NULL) {
|
121
|
+
rb_exception_result = rb_eSigningError;
|
122
|
+
exception_message = "failed to add X509Data node";
|
123
|
+
goto done;
|
124
|
+
}
|
125
|
+
|
126
|
+
// create signature context, we don't need keys manager in this example
|
127
|
+
dsigCtx = createDSigContext(NULL);
|
128
|
+
if(dsigCtx == NULL) {
|
129
|
+
rb_exception_result = rb_eSigningError;
|
130
|
+
exception_message = "failed to create signature context";
|
131
|
+
goto done;
|
132
|
+
}
|
133
|
+
|
134
|
+
// load private key, assuming that there is not password
|
135
|
+
dsigCtx->signKey = xmlSecCryptoAppKeyLoadMemory((xmlSecByte *)rsaKey,
|
136
|
+
rsaKeyLength,
|
137
|
+
xmlSecKeyDataFormatPem,
|
138
|
+
NULL, // password
|
139
|
+
NULL,
|
140
|
+
NULL);
|
141
|
+
if(dsigCtx->signKey == NULL) {
|
142
|
+
rb_exception_result = rb_eSigningError;
|
143
|
+
exception_message = "failed to load private key";
|
144
|
+
goto done;
|
145
|
+
}
|
146
|
+
|
147
|
+
// load certificate and add to the key
|
148
|
+
if(xmlSecCryptoAppKeyCertLoadMemory(dsigCtx->signKey,
|
149
|
+
(xmlSecByte *)certificate,
|
150
|
+
certificateLength,
|
151
|
+
xmlSecKeyDataFormatPem) < 0) {
|
152
|
+
rb_exception_result = rb_eSigningError;
|
153
|
+
exception_message = "failed to load certificate";
|
154
|
+
goto done;
|
155
|
+
}
|
156
|
+
|
157
|
+
// set key name
|
158
|
+
if(xmlSecKeySetName(dsigCtx->signKey, (xmlSecByte *)keyName) < 0) {
|
159
|
+
rb_exception_result = rb_eSigningError;
|
160
|
+
exception_message = "failed to set key name";
|
161
|
+
goto done;
|
162
|
+
}
|
163
|
+
|
164
|
+
// sign the template
|
165
|
+
if(xmlSecDSigCtxSign(dsigCtx, signNode) < 0) {
|
166
|
+
rb_exception_result = rb_eSigningError;
|
167
|
+
exception_message = "signature failed";
|
168
|
+
goto done;
|
169
|
+
}
|
170
|
+
|
171
|
+
done:
|
172
|
+
if(dsigCtx != NULL) {
|
173
|
+
xmlSecDSigCtxDestroy(dsigCtx);
|
174
|
+
}
|
175
|
+
|
176
|
+
if(rb_exception_result != Qnil) {
|
177
|
+
if (hasXmlSecLastError()) {
|
178
|
+
rb_raise(rb_exception_result, "%s, XmlSec error: %s", exception_message,
|
179
|
+
getXmlSecLastError());
|
180
|
+
} else {
|
181
|
+
rb_raise(rb_exception_result, "%s", exception_message);
|
182
|
+
}
|
183
|
+
}
|
184
|
+
|
185
|
+
return Qnil;
|
186
|
+
}
|
@@ -0,0 +1,167 @@
|
|
1
|
+
#include "xmlsecrb.h"
|
2
|
+
|
3
|
+
#include "options.h"
|
4
|
+
#include "util.h"
|
5
|
+
|
6
|
+
// Appends an xmlsig <dsig:Signature> node to document stored in |self|
|
7
|
+
// with a signature based on the given bare rsa key and keyname.
|
8
|
+
//
|
9
|
+
// Expects a ruby hash for the signing arguments.
|
10
|
+
// Hash parameters:
|
11
|
+
// :key_name - String with name of the rsa key. May be the empty string.
|
12
|
+
// :rsa_key - A PEM encoded rsa key for signing.
|
13
|
+
// :signature_alg - Algorithm identified by the URL fragment. Supported algorithms
|
14
|
+
// taken from http://www.w3.org/TR/xmldsig-core
|
15
|
+
// :digest_alg - Algorithm identified by the URL fragment. Supported algorithms
|
16
|
+
// taken from http://www.w3.org/TR/xmldsig-core
|
17
|
+
// :ref_uri - [optional] The URI attribute for the <Reference> node in the
|
18
|
+
// signature.
|
19
|
+
VALUE sign_with_key(VALUE self, VALUE rb_opts) {
|
20
|
+
VALUE rb_exception_result = Qnil;
|
21
|
+
const char* exception_message = NULL;
|
22
|
+
|
23
|
+
xmlDocPtr doc = NULL;
|
24
|
+
xmlNodePtr signNode = NULL;
|
25
|
+
xmlNodePtr refNode = NULL;
|
26
|
+
xmlNodePtr keyInfoNode = NULL;
|
27
|
+
xmlSecDSigCtxPtr dsigCtx = NULL;
|
28
|
+
char *keyName = NULL;
|
29
|
+
char *rsaKey = NULL;
|
30
|
+
char *refUri = NULL;
|
31
|
+
unsigned int rsaKeyLength = 0;
|
32
|
+
|
33
|
+
resetXmlSecError();
|
34
|
+
|
35
|
+
VALUE rb_key_name = rb_hash_aref(rb_opts, ID2SYM(rb_intern("name")));
|
36
|
+
VALUE rb_rsa_key = rb_hash_aref(rb_opts, ID2SYM(rb_intern("key")));
|
37
|
+
VALUE rb_signature_alg = rb_hash_aref(rb_opts, ID2SYM(rb_intern("signature_alg")));
|
38
|
+
VALUE rb_digest_alg = rb_hash_aref(rb_opts, ID2SYM(rb_intern("digest_alg")));
|
39
|
+
VALUE rb_uri = rb_hash_aref(rb_opts, ID2SYM(rb_intern("uri")));
|
40
|
+
|
41
|
+
Check_Type(rb_rsa_key, T_STRING);
|
42
|
+
Check_Type(rb_key_name, T_STRING);
|
43
|
+
Check_Type(rb_signature_alg, T_STRING);
|
44
|
+
Check_Type(rb_digest_alg, T_STRING);
|
45
|
+
|
46
|
+
rsaKey = RSTRING_PTR(rb_rsa_key);
|
47
|
+
rsaKeyLength = RSTRING_LEN(rb_rsa_key);
|
48
|
+
keyName = StringValueCStr(rb_key_name);
|
49
|
+
|
50
|
+
if (!NIL_P(rb_uri)) {
|
51
|
+
Check_Type(rb_uri, T_STRING);
|
52
|
+
refUri = StringValueCStr(rb_uri);
|
53
|
+
}
|
54
|
+
|
55
|
+
Data_Get_Struct(self, xmlDoc, doc);
|
56
|
+
xmlSecTransformId signature_algorithm = GetSignatureMethod(rb_signature_alg,
|
57
|
+
&rb_exception_result, &exception_message);
|
58
|
+
if (signature_algorithm == xmlSecTransformIdUnknown) {
|
59
|
+
// Propagate exception.
|
60
|
+
goto done;
|
61
|
+
}
|
62
|
+
|
63
|
+
// create signature template for enveloped signature
|
64
|
+
signNode = xmlSecTmplSignatureCreate(doc, xmlSecTransformExclC14NId,
|
65
|
+
signature_algorithm, NULL);
|
66
|
+
if (signNode == NULL) {
|
67
|
+
rb_exception_result = rb_eSigningError;
|
68
|
+
exception_message = "failed to create signature template";
|
69
|
+
goto done;
|
70
|
+
}
|
71
|
+
|
72
|
+
// add <dsig:Signature/> node to the doc
|
73
|
+
xmlAddChild(xmlDocGetRootElement(doc), signNode);
|
74
|
+
|
75
|
+
// add reference
|
76
|
+
xmlSecTransformId digest_algorithm = GetDigestMethod(rb_digest_alg,
|
77
|
+
&rb_exception_result, &exception_message);
|
78
|
+
if (digest_algorithm == xmlSecTransformIdUnknown) {
|
79
|
+
// Propagate exception.
|
80
|
+
goto done;
|
81
|
+
}
|
82
|
+
refNode = xmlSecTmplSignatureAddReference(signNode, digest_algorithm,
|
83
|
+
NULL, (const xmlChar *)refUri, NULL);
|
84
|
+
if(refNode == NULL) {
|
85
|
+
rb_exception_result = rb_eSigningError;
|
86
|
+
exception_message = "failed to add reference to signature template";
|
87
|
+
goto done;
|
88
|
+
}
|
89
|
+
|
90
|
+
// add enveloped transform
|
91
|
+
if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformEnvelopedId) == NULL) {
|
92
|
+
rb_exception_result = rb_eSigningError;
|
93
|
+
exception_message = "failed to add enveloped transform to reference";
|
94
|
+
goto done;
|
95
|
+
}
|
96
|
+
|
97
|
+
if(xmlSecTmplReferenceAddTransform(refNode, xmlSecTransformExclC14NId) == NULL) {
|
98
|
+
rb_exception_result = rb_eSigningError;
|
99
|
+
exception_message = "failed to add canonicalization transform to reference";
|
100
|
+
goto done;
|
101
|
+
}
|
102
|
+
|
103
|
+
// add <dsig:KeyInfo/> and <dsig:KeyName/> nodes to put key name in the signed
|
104
|
+
// document
|
105
|
+
keyInfoNode = xmlSecTmplSignatureEnsureKeyInfo(signNode, NULL);
|
106
|
+
if(keyInfoNode == NULL) {
|
107
|
+
rb_exception_result = rb_eSigningError;
|
108
|
+
exception_message = "failed to add key info";
|
109
|
+
goto done;
|
110
|
+
}
|
111
|
+
if(xmlSecTmplKeyInfoAddKeyName(keyInfoNode, NULL) == NULL) {
|
112
|
+
rb_exception_result = rb_eSigningError;
|
113
|
+
exception_message = "failed to add key name";
|
114
|
+
goto done;
|
115
|
+
}
|
116
|
+
|
117
|
+
// create signature context, we don't need keys manager in this example
|
118
|
+
dsigCtx = createDSigContext(NULL);
|
119
|
+
if(dsigCtx == NULL) {
|
120
|
+
rb_exception_result = rb_eSigningError;
|
121
|
+
exception_message = "failed to create signature context";
|
122
|
+
goto done;
|
123
|
+
}
|
124
|
+
|
125
|
+
// load private key, assuming that there is no password
|
126
|
+
dsigCtx->signKey = xmlSecCryptoAppKeyLoadMemory((xmlSecByte *)rsaKey,
|
127
|
+
rsaKeyLength,
|
128
|
+
xmlSecKeyDataFormatPem,
|
129
|
+
NULL, // password
|
130
|
+
NULL,
|
131
|
+
NULL);
|
132
|
+
if(dsigCtx->signKey == NULL) {
|
133
|
+
rb_exception_result = rb_eSigningError;
|
134
|
+
exception_message = "failed to load private pem key";
|
135
|
+
goto done;
|
136
|
+
}
|
137
|
+
|
138
|
+
// set key name
|
139
|
+
if(xmlSecKeySetName(dsigCtx->signKey, (xmlSecByte *)keyName) < 0) {
|
140
|
+
rb_exception_result = rb_eSigningError;
|
141
|
+
exception_message = "failed to set key name";
|
142
|
+
goto done;
|
143
|
+
}
|
144
|
+
|
145
|
+
// sign the template
|
146
|
+
if(xmlSecDSigCtxSign(dsigCtx, signNode) < 0) {
|
147
|
+
rb_exception_result = rb_eSigningError;
|
148
|
+
exception_message = "signature failed";
|
149
|
+
goto done;
|
150
|
+
}
|
151
|
+
|
152
|
+
done:
|
153
|
+
if(dsigCtx != NULL) {
|
154
|
+
xmlSecDSigCtxDestroy(dsigCtx);
|
155
|
+
}
|
156
|
+
|
157
|
+
if(rb_exception_result != Qnil) {
|
158
|
+
if (hasXmlSecLastError()) {
|
159
|
+
rb_raise(rb_exception_result, "%s, XmlSec error: %s", exception_message,
|
160
|
+
getXmlSecLastError());
|
161
|
+
} else {
|
162
|
+
rb_raise(rb_exception_result, "%s", exception_message);
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
return Qnil;
|
167
|
+
}
|