nokogiri-xmlsec-instructure 0.9.4 → 0.10.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +8 -0
- data/ext/nokogiri_ext_xmlsec/init.c +0 -5
- data/ext/nokogiri_ext_xmlsec/nokogiri_decrypt_with_key.c +8 -1
- data/ext/nokogiri_ext_xmlsec/nokogiri_encrypt_with_key.c +53 -12
- data/ext/nokogiri_ext_xmlsec/nokogiri_helpers_set_attribute_id.c +8 -6
- data/ext/nokogiri_ext_xmlsec/nokogiri_init.c +1 -1
- data/ext/nokogiri_ext_xmlsec/nokogiri_sign.c +2 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_verify_with.c +2 -0
- data/ext/nokogiri_ext_xmlsec/util.c +1 -0
- data/ext/nokogiri_ext_xmlsec/xmlsecrb.h +1 -0
- data/lib/xmlsec.rb +7 -6
- data/lib/xmlsec/version.rb +1 -1
- data/nokogiri-xmlsec-instructure.gemspec +4 -3
- data/spec/lib/nokogiri/xml/document/encryption_and_decryption_spec.rb +21 -0
- metadata +24 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 72eea7707ea8c4d24e0cb82afc804752be0313d810554ca54f4ea9e4a3f857e9
|
4
|
+
data.tar.gz: 4641d782e76a25aa3f251ff160f04d66198a1c2c3a4020f625dc29f7bbe5e365
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f116055729f4a0bddbee6432c99e9f505aad12a45452121d4fb14414de8eaf613009db60d28d55a7e7c8b7c5678e67e7d3a297741186f4e9eabcf4d08b88385c
|
7
|
+
data.tar.gz: d73b7b9d8ff63621b3162b4d83dfcf8ffd52b253d589fc863ef44d47847801e23ad8a386b4459a933431c5eaef0e377051089e8c4af06cde05522e3d390f4ae3
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -10,6 +10,14 @@ to `Nokogiri::XML::Document`.
|
|
10
10
|
|
11
11
|
## Installation
|
12
12
|
|
13
|
+
Install this before attempting to install; or else it may fail (tested on CentOS 7) while trying to find -lltdl from the xmlsec1-openssl lib. I'm guessing it's a dependency. Someone else may know more.
|
14
|
+
|
15
|
+
# CentOS/RHEL
|
16
|
+
yum install libtool-ltdl-devel
|
17
|
+
|
18
|
+
# Debian/Ubuntu
|
19
|
+
apt install -y libxmlsec1-dev
|
20
|
+
|
13
21
|
Add this line to your application's Gemfile:
|
14
22
|
|
15
23
|
gem 'nokogiri-xmlsec'
|
@@ -20,7 +20,6 @@ void Init_nokogiri_ext_xmlsec() {
|
|
20
20
|
xmlInitParser();
|
21
21
|
LIBXML_TEST_VERSION
|
22
22
|
xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
|
23
|
-
xmlSubstituteEntitiesDefault(1);
|
24
23
|
// xslt
|
25
24
|
|
26
25
|
#ifndef XMLSEC_NO_XSLT
|
@@ -66,10 +65,6 @@ void Init_nokogiri_ext_xmlsec() {
|
|
66
65
|
rb_raise(rb_eRuntimeError, "xmlsec-crypto initialization failed");
|
67
66
|
}
|
68
67
|
|
69
|
-
// Set Error callback catcher last because various modules also call this.
|
70
|
-
// This way we always win.
|
71
|
-
xmlSecErrorsSetCallback(storeErrorCallback);
|
72
|
-
|
73
68
|
/* ruby classes & objects */
|
74
69
|
Init_Nokogiri_ext();
|
75
70
|
}
|
@@ -1,6 +1,11 @@
|
|
1
1
|
#include "xmlsecrb.h"
|
2
2
|
#include "util.h"
|
3
3
|
|
4
|
+
// technically we should include nokogiri.h, but we don't know
|
5
|
+
// how to find it. we _know_ this function will exist at runtime
|
6
|
+
// though, so just declare it here
|
7
|
+
void noko_xml_document_pin_node(xmlNodePtr);
|
8
|
+
|
4
9
|
VALUE decrypt_with_key(VALUE self, VALUE rb_key_name, VALUE rb_key) {
|
5
10
|
VALUE rb_exception_result = Qnil;
|
6
11
|
const char* exception_message = NULL;
|
@@ -58,7 +63,7 @@ done:
|
|
58
63
|
// the replaced node is orphaned, but not freed; let Nokogiri
|
59
64
|
// own it now
|
60
65
|
if(encCtx->replacedNodeList != NULL) {
|
61
|
-
|
66
|
+
noko_xml_document_pin_node(encCtx->replacedNodeList);
|
62
67
|
// no really, please don't free it
|
63
68
|
encCtx->replacedNodeList = NULL;
|
64
69
|
}
|
@@ -69,6 +74,8 @@ done:
|
|
69
74
|
xmlSecKeysMngrDestroy(keyManager);
|
70
75
|
}
|
71
76
|
|
77
|
+
xmlSecErrorsSetCallback(xmlSecErrorsDefaultCallback);
|
78
|
+
|
72
79
|
if(rb_exception_result != Qnil) {
|
73
80
|
if (hasXmlSecLastError()) {
|
74
81
|
rb_raise(rb_exception_result, "%s, XmlSec error: %s", exception_message,
|
@@ -12,9 +12,11 @@
|
|
12
12
|
VALUE encrypt_with_key(VALUE self, VALUE rb_rsa_key_name, VALUE rb_rsa_key,
|
13
13
|
VALUE rb_opts) {
|
14
14
|
VALUE rb_exception_result = Qnil;
|
15
|
+
VALUE rb_cert = Qnil;
|
15
16
|
const char* exception_message = NULL;
|
16
17
|
|
17
18
|
xmlDocPtr doc = NULL;
|
19
|
+
xmlNodePtr node = NULL;
|
18
20
|
xmlNodePtr encDataNode = NULL;
|
19
21
|
xmlNodePtr encKeyNode = NULL;
|
20
22
|
xmlNodePtr keyInfoNode = NULL;
|
@@ -22,17 +24,28 @@ VALUE encrypt_with_key(VALUE self, VALUE rb_rsa_key_name, VALUE rb_rsa_key,
|
|
22
24
|
xmlSecKeysMngrPtr keyManager = NULL;
|
23
25
|
char *keyName = NULL;
|
24
26
|
char *key = NULL;
|
27
|
+
char *certificate = NULL;
|
25
28
|
unsigned int keyLength = 0;
|
29
|
+
unsigned int certificateLength = 0;
|
26
30
|
|
27
31
|
resetXmlSecError();
|
28
32
|
|
29
33
|
Check_Type(rb_rsa_key, T_STRING);
|
30
|
-
Check_Type(rb_rsa_key_name, T_STRING);
|
31
34
|
Check_Type(rb_opts, T_HASH);
|
32
35
|
|
33
36
|
key = RSTRING_PTR(rb_rsa_key);
|
34
37
|
keyLength = RSTRING_LEN(rb_rsa_key);
|
35
|
-
|
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
|
+
}
|
36
49
|
|
37
50
|
XmlEncOptions options;
|
38
51
|
if (!GetXmlEncOptions(rb_opts, &options, &rb_exception_result,
|
@@ -40,7 +53,8 @@ VALUE encrypt_with_key(VALUE self, VALUE rb_rsa_key_name, VALUE rb_rsa_key,
|
|
40
53
|
goto done;
|
41
54
|
}
|
42
55
|
|
43
|
-
Data_Get_Struct(self,
|
56
|
+
Data_Get_Struct(self, xmlNode, node);
|
57
|
+
doc = node->doc;
|
44
58
|
|
45
59
|
// create encryption template to encrypt XML file and replace
|
46
60
|
// its content with encryption result
|
@@ -68,10 +82,21 @@ VALUE encrypt_with_key(VALUE self, VALUE rb_rsa_key_name, VALUE rb_rsa_key,
|
|
68
82
|
goto done;
|
69
83
|
}
|
70
84
|
|
71
|
-
if(
|
72
|
-
|
73
|
-
|
74
|
-
|
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
|
+
}
|
75
100
|
}
|
76
101
|
|
77
102
|
if ((keyManager = createKeyManagerWithSingleKey(
|
@@ -100,11 +125,25 @@ VALUE encrypt_with_key(VALUE self, VALUE rb_rsa_key_name, VALUE rb_rsa_key,
|
|
100
125
|
goto done;
|
101
126
|
}
|
102
127
|
|
128
|
+
if(certificate) {
|
129
|
+
// load certificate and add to the key
|
130
|
+
if(xmlSecCryptoAppKeyCertLoadMemory(encCtx->encKey,
|
131
|
+
(xmlSecByte *)certificate,
|
132
|
+
certificateLength,
|
133
|
+
xmlSecKeyDataFormatPem) < 0) {
|
134
|
+
rb_exception_result = rb_eSigningError;
|
135
|
+
exception_message = "failed to load certificate";
|
136
|
+
goto done;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
103
140
|
// Set key name.
|
104
|
-
if(
|
105
|
-
|
106
|
-
|
107
|
-
|
141
|
+
if(keyName) {
|
142
|
+
if(xmlSecKeySetName(encCtx->encKey, (xmlSecByte *)keyName) < 0) {
|
143
|
+
rb_exception_result = rb_eEncryptionError;
|
144
|
+
exception_message = "failed to set key name";
|
145
|
+
goto done;
|
146
|
+
}
|
108
147
|
}
|
109
148
|
|
110
149
|
// Add <enc:EncryptedKey/> node to the <dsig:KeyInfo/> tag to include
|
@@ -127,7 +166,7 @@ VALUE encrypt_with_key(VALUE self, VALUE rb_rsa_key_name, VALUE rb_rsa_key,
|
|
127
166
|
}
|
128
167
|
|
129
168
|
// encrypt the data
|
130
|
-
if(xmlSecEncCtxXmlEncrypt(encCtx, encDataNode,
|
169
|
+
if(xmlSecEncCtxXmlEncrypt(encCtx, encDataNode, node) < 0) {
|
131
170
|
rb_exception_result = rb_eEncryptionError;
|
132
171
|
exception_message = "encryption failed";
|
133
172
|
goto done;
|
@@ -156,6 +195,8 @@ done:
|
|
156
195
|
xmlSecKeysMngrDestroy(keyManager);
|
157
196
|
}
|
158
197
|
|
198
|
+
xmlSecErrorsSetCallback(xmlSecErrorsDefaultCallback);
|
199
|
+
|
159
200
|
if(rb_exception_result != Qnil) {
|
160
201
|
if (hasXmlSecLastError()) {
|
161
202
|
rb_raise(rb_exception_result, "%s, XmlSec error: %s", exception_message,
|
@@ -2,7 +2,7 @@
|
|
2
2
|
#include "util.h"
|
3
3
|
|
4
4
|
// declaration from Nokogiri proper
|
5
|
-
VALUE
|
5
|
+
VALUE noko_xml_node_wrap(VALUE klass, xmlNodePtr node) ;
|
6
6
|
|
7
7
|
VALUE set_id_attribute(VALUE self, VALUE rb_attr_name) {
|
8
8
|
VALUE rb_exception_result = Qnil;
|
@@ -14,7 +14,7 @@ VALUE set_id_attribute(VALUE self, VALUE rb_attr_name) {
|
|
14
14
|
xmlChar *name = NULL;
|
15
15
|
char *idName = NULL;
|
16
16
|
char *exception_attribute_arg = NULL;
|
17
|
-
|
17
|
+
|
18
18
|
resetXmlSecError();
|
19
19
|
|
20
20
|
Data_Get_Struct(self, xmlNode, node);
|
@@ -28,7 +28,7 @@ VALUE set_id_attribute(VALUE self, VALUE rb_attr_name) {
|
|
28
28
|
exception_message = "Can't find attribute to add register as id";
|
29
29
|
goto done;
|
30
30
|
}
|
31
|
-
|
31
|
+
|
32
32
|
// get the attribute (id) value
|
33
33
|
name = xmlNodeListGetString(node->doc, attr->children, 1);
|
34
34
|
if(name == NULL) {
|
@@ -37,7 +37,7 @@ VALUE set_id_attribute(VALUE self, VALUE rb_attr_name) {
|
|
37
37
|
exception_attribute_arg = idName;
|
38
38
|
goto done;
|
39
39
|
}
|
40
|
-
|
40
|
+
|
41
41
|
// check that we don't have that id already registered
|
42
42
|
tmp = xmlGetID(node->doc, name);
|
43
43
|
if(tmp != NULL) {
|
@@ -46,7 +46,7 @@ VALUE set_id_attribute(VALUE self, VALUE rb_attr_name) {
|
|
46
46
|
exception_attribute_arg = idName;
|
47
47
|
goto done;
|
48
48
|
}
|
49
|
-
|
49
|
+
|
50
50
|
// finally register id
|
51
51
|
xmlAddID(NULL, node->doc, name, attr);
|
52
52
|
|
@@ -56,6 +56,8 @@ done:
|
|
56
56
|
xmlFree(name);
|
57
57
|
}
|
58
58
|
|
59
|
+
xmlSecErrorsSetCallback(xmlSecErrorsDefaultCallback);
|
60
|
+
|
59
61
|
if(rb_exception_result != Qnil) {
|
60
62
|
if (exception_attribute_arg) {
|
61
63
|
if (hasXmlSecLastError()) {
|
@@ -87,7 +89,7 @@ VALUE get_id(VALUE self, VALUE rb_id)
|
|
87
89
|
Data_Get_Struct(self, xmlDoc, doc);
|
88
90
|
prop = xmlGetID(doc, (const xmlChar *)StringValueCStr(rb_id));
|
89
91
|
if (prop) {
|
90
|
-
return
|
92
|
+
return noko_xml_node_wrap(Qnil, (xmlNodePtr)prop);
|
91
93
|
} else {
|
92
94
|
return Qnil;
|
93
95
|
}
|
@@ -17,7 +17,7 @@ void Init_Nokogiri_ext() {
|
|
17
17
|
|
18
18
|
rb_define_method(rb_cNokogiri_XML_Node, "sign!", sign, 1);
|
19
19
|
rb_define_method(rb_cNokogiri_XML_Node, "verify_with", verify_with, 1);
|
20
|
-
rb_define_method(
|
20
|
+
rb_define_method(rb_cNokogiri_XML_Node, "encrypt_with_key", encrypt_with_key, 3);
|
21
21
|
rb_define_method(rb_cNokogiri_XML_Node, "decrypt_with_key", decrypt_with_key, 2);
|
22
22
|
rb_define_method(rb_cNokogiri_XML_Document, "get_id", get_id, 1);
|
23
23
|
rb_define_method(rb_cNokogiri_XML_Node, "set_id_attribute", set_id_attribute, 1);
|
@@ -232,6 +232,8 @@ done:
|
|
232
232
|
xmlSecDSigCtxDestroy(dsigCtx);
|
233
233
|
}
|
234
234
|
|
235
|
+
xmlSecErrorsSetCallback(xmlSecErrorsDefaultCallback);
|
236
|
+
|
235
237
|
if(rb_exception_result != Qnil) {
|
236
238
|
// remove the signature node before raising an exception, so that
|
237
239
|
// the document is untouched
|
@@ -246,6 +246,8 @@ done:
|
|
246
246
|
xmlSecKeysMngrDestroy(keyManager);
|
247
247
|
}
|
248
248
|
|
249
|
+
xmlSecErrorsSetCallback(xmlSecErrorsDefaultCallback);
|
250
|
+
|
249
251
|
if(!NIL_P(rb_exception_result)) {
|
250
252
|
if (hasXmlSecLastError()) {
|
251
253
|
rb_raise(rb_exception_result, "%s, XmlSec error: %s", exception_message,
|
data/lib/xmlsec.rb
CHANGED
@@ -61,12 +61,8 @@ class Nokogiri::XML::Document
|
|
61
61
|
# # encrypt with a public key and optional key name
|
62
62
|
# doc.encrypt! key: 'public-key', name: 'name'
|
63
63
|
#
|
64
|
-
def encrypt! opts
|
65
|
-
|
66
|
-
encrypt_with_key opts[:name].to_s, opts[:key], opts.select { |key, _| key != :key && key != :name }
|
67
|
-
else
|
68
|
-
raise "public :key is required for encryption"
|
69
|
-
end
|
64
|
+
def encrypt!(key:, name: nil, **opts)
|
65
|
+
root.encrypt_with(key: key, name: name, **opts)
|
70
66
|
self
|
71
67
|
end
|
72
68
|
|
@@ -89,6 +85,11 @@ class Nokogiri::XML::Document
|
|
89
85
|
end
|
90
86
|
|
91
87
|
class Nokogiri::XML::Node
|
88
|
+
def encrypt_with(key:, name: nil, **opts)
|
89
|
+
raise ArgumentError("public :key is required for encryption") unless key
|
90
|
+
encrypt_with_key(name, key, opts)
|
91
|
+
end
|
92
|
+
|
92
93
|
def decrypt_with(opts)
|
93
94
|
raise 'inadequate options specified for decryption' unless opts[:key]
|
94
95
|
|
data/lib/xmlsec/version.rb
CHANGED
@@ -28,9 +28,10 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.require_paths = ["lib"]
|
29
29
|
spec.extensions = %w{ext/nokogiri_ext_xmlsec/extconf.rb}
|
30
30
|
|
31
|
-
spec.add_dependency 'nokogiri'
|
32
|
-
|
33
|
-
spec.add_development_dependency "bundler", "~> 1
|
31
|
+
spec.add_dependency 'nokogiri', '>= 1.11.2'
|
32
|
+
|
33
|
+
spec.add_development_dependency "bundler", "~> 2.1"
|
34
|
+
spec.add_development_dependency "byebug"
|
34
35
|
spec.add_development_dependency "rake"
|
35
36
|
spec.add_development_dependency "rake-compiler"
|
36
37
|
spec.add_development_dependency "rspec"
|
@@ -31,4 +31,25 @@ describe "encryption and decryption:" do
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
it "encrypts a single element" do
|
35
|
+
doc = subject
|
36
|
+
original = doc.to_s
|
37
|
+
node = doc.at_xpath('env:Envelope/env:Data', 'env' => 'urn:envelope')
|
38
|
+
node.encrypt_with(key: fixture('rsa.pub'), block_encryption: 'aes128-cbc', key_transport: 'rsa-1_5')
|
39
|
+
expect(doc.root.name).to eq 'Envelope'
|
40
|
+
expect(doc.root.element_children.first.name).to eq 'EncryptedData'
|
41
|
+
encrypted_data = doc.root.element_children.first
|
42
|
+
encrypted_data.decrypt_with(key: fixture('rsa.pem'))
|
43
|
+
expect(doc.to_s).to eq original
|
44
|
+
end
|
45
|
+
|
46
|
+
it "inserts a certificate" do
|
47
|
+
doc = subject
|
48
|
+
doc.encrypt!(key: fixture('cert/server.key.decrypted'),
|
49
|
+
cert: fixture('cert/server.crt'),
|
50
|
+
block_encryption: 'aes128-cbc',
|
51
|
+
key_transport: 'rsa-1_5')
|
52
|
+
expect(doc.to_s).to match(/X509Data/)
|
53
|
+
expect(doc.to_s).not_to match(/X509Data></)
|
54
|
+
end
|
34
55
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nokogiri-xmlsec-instructure
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Albert J. Wong
|
8
8
|
- Cody Cutrer
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-04-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -17,28 +17,42 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version:
|
20
|
+
version: 1.11.2
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version:
|
27
|
+
version: 1.11.2
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: bundler
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '1
|
34
|
+
version: '2.1'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '1
|
41
|
+
version: '2.1'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: byebug
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
42
56
|
- !ruby/object:Gem::Dependency
|
43
57
|
name: rake
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -172,7 +186,7 @@ homepage: https://github.com/instructure/nokogiri-xmlsec-instructure
|
|
172
186
|
licenses:
|
173
187
|
- MIT
|
174
188
|
metadata: {}
|
175
|
-
post_install_message:
|
189
|
+
post_install_message:
|
176
190
|
rdoc_options: []
|
177
191
|
require_paths:
|
178
192
|
- lib
|
@@ -187,9 +201,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
201
|
- !ruby/object:Gem::Version
|
188
202
|
version: '0'
|
189
203
|
requirements: []
|
190
|
-
|
191
|
-
|
192
|
-
signing_key:
|
204
|
+
rubygems_version: 3.2.15
|
205
|
+
signing_key:
|
193
206
|
specification_version: 4
|
194
207
|
summary: Wrapper around http://www.aleksey.com/xmlsec to support XML encryption, decryption,
|
195
208
|
signing and signature validation in Ruby
|