nokogiri-xmlsec-instructure 0.9.6 → 0.9.7
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 +4 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_decrypt_with_key.c +5 -0
- data/ext/nokogiri_ext_xmlsec/nokogiri_encrypt_with_key.c +51 -12
- data/ext/nokogiri_ext_xmlsec/nokogiri_init.c +1 -1
- data/lib/xmlsec.rb +7 -6
- data/lib/xmlsec/version.rb +1 -1
- data/nokogiri-xmlsec-instructure.gemspec +2 -1
- data/spec/lib/nokogiri/xml/document/encryption_and_decryption_spec.rb +21 -0
- metadata +22 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e62d20498ea2a3a7afe3038145ef752a3cb1472b15cb64651aecf7ae531cc561
|
4
|
+
data.tar.gz: ea744d07e2f148fd72880b4eb6a4e520aac09f5b62cdaa3573b3cbe5323aaf16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8fb1eb16f65c9e88872a29d186a3b949d71526e871efc444eb397362c3412567a4d736b87dda3bf02bbc7a1db7983bbcb736f809e595a9f9599a2d148ebdcea
|
7
|
+
data.tar.gz: ee60f516c6e91205000743a14ca6c9b958bd172ac8f2be80d27bd649b2843e35991e0f1a4d0ce318a650edce969d95e0216144e56d04bf53b3cc1c403bba2642
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -10,6 +10,10 @@ 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
|
+
yum install libtool-ltdl-devel
|
16
|
+
|
13
17
|
Add this line to your application's Gemfile:
|
14
18
|
|
15
19
|
gem 'nokogiri-xmlsec'
|
@@ -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 nokogiri_root_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;
|
@@ -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;
|
@@ -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);
|
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
@@ -30,7 +30,8 @@ Gem::Specification.new do |spec|
|
|
30
30
|
|
31
31
|
spec.add_dependency 'nokogiri'
|
32
32
|
|
33
|
-
spec.add_development_dependency "bundler", "~> 1
|
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.9.
|
4
|
+
version: 0.9.7
|
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: 2020-09-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: nokogiri
|
@@ -31,14 +31,28 @@ dependencies:
|
|
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.1.2
|
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
|