xmlenc 0.0.1 → 0.1.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 +8 -8
- data/README.md +27 -2
- data/lib/xmlenc.rb +19 -1
- data/lib/xmlenc/algorithms/aes_cbc.rb +20 -4
- data/lib/xmlenc/algorithms/des3_cbc.rb +14 -4
- data/lib/xmlenc/algorithms/rsa_15.rb +5 -1
- data/lib/xmlenc/algorithms/rsa_oaep_mgf1p.rb +6 -1
- data/lib/xmlenc/builder/base.rb +49 -0
- data/lib/xmlenc/builder/cipher_data.rb +14 -0
- data/lib/xmlenc/builder/complex_types/encrypted_type.rb +20 -0
- data/lib/xmlenc/builder/encrypted_data.rb +13 -0
- data/lib/xmlenc/builder/encrypted_key.rb +10 -0
- data/lib/xmlenc/builder/encryption_method.rb +16 -0
- data/lib/xmlenc/builder/key_info.rb +16 -0
- data/lib/xmlenc/encrypted_data.rb +23 -1
- data/lib/xmlenc/encrypted_document.rb +2 -4
- data/lib/xmlenc/encrypted_key.rb +11 -1
- data/lib/xmlenc/version.rb +1 -1
- data/spec/fixtures/template.xml +45 -0
- data/spec/lib/xmlenc/algorithms/aes_cbc_spec.rb +22 -0
- data/spec/lib/xmlenc/algorithms/des3_cbc_spec.rb +22 -0
- data/spec/lib/xmlenc/algorithms/rsa_15_spec.rb +26 -0
- data/spec/lib/xmlenc/algorithms/rsa_oaep_mgf1p_spec.rb +26 -0
- data/spec/lib/xmlenc/builder/base_spec.rb +27 -0
- data/spec/lib/xmlenc/builder/cipher_data_spec.rb +28 -0
- data/spec/lib/xmlenc/builder/complex_types/encrypted_type_spec.rb +67 -0
- data/spec/lib/xmlenc/builder/encrypted_data_spec.rb +73 -0
- data/spec/lib/xmlenc/builder/encrypted_key_spec.rb +65 -0
- data/spec/lib/xmlenc/builder/encryption_method_spec.rb +29 -0
- data/spec/lib/xmlenc/builder/key_info_spec.rb +38 -0
- data/spec/lib/xmlenc/encrypted_data_spec.rb +19 -0
- data/spec/lib/xmlenc/encrypted_key_spec.rb +21 -0
- data/spec/spec_helper.rb +1 -0
- data/xmlenc.gemspec +4 -1
- metadata +76 -5
- data/spec/lib/xmlenc/.keep +0 -0
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZWJjYTNjOTdkM2Y5ZTQ2YThhYWZiNjgzNWU1Zjk1Mjc4MGZhZjIwOA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YjljZjYyZmQwNmJlY2VmYTVlYmNkZDE4Y2I3YjU5NjEwOTNiNTZjYw==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NWI3YzYxMDI0ODQ2OGNlMTM0YzgxZGY3NTIyZjQyYzIzNDY0NGJlZTQzNzlh
|
10
|
+
NjEyNWFjZTAwMmE0YmZjMWYzZDYxNDc5MTY5OTUxMjM5NDY5OTZlZmQ5MTJl
|
11
|
+
YTVmMzRjZTBmYzg4MzU2ODMzM2MyMmVkMDhkOTY0OWNhODNhMTk=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
NjJiYmUyY2U5OTIxNTdiYTcyM2NiNTQ1ODM3YWE2NTI1ODJkYTNhNTgxMTYx
|
14
|
+
MWY1NGJiZDBiN2I0MjRjZmUyYjI1ZjgxMWM3YzliZWEzZTM3ODgyZmJjNmVm
|
15
|
+
YmM1M2U2ODNmYmNhNDMzNDFkNzk0OTUyM2YyYzViM2Y1Y2JhNzg=
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Xmlenc
|
2
2
|
|
3
|
-
|
3
|
+
This gem is a (partial) implementation of the XMLEncryption specification (http://www.w3.org/TR/xmlenc-core/)
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -18,7 +18,32 @@ Or install it yourself as:
|
|
18
18
|
|
19
19
|
## Usage
|
20
20
|
|
21
|
-
|
21
|
+
### Decrypt a document
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
key_pem = File.read('path/to/key.pem')
|
25
|
+
xml = File.read('path/to/file.xml')
|
26
|
+
|
27
|
+
private_key = OpenSSL::PKey::RSA.new(key_pem)
|
28
|
+
decrypted_document = Xmlenc::EncryptedDocument.decrypt(private_key)
|
29
|
+
```
|
30
|
+
|
31
|
+
### Supported algorithms
|
32
|
+
|
33
|
+
Data algorithms
|
34
|
+
* http://www.w3.org/2001/04/xmlenc#tripledes-cbc
|
35
|
+
* http://www.w3.org/2001/04/xmlenc#aes128-cbc
|
36
|
+
* http://www.w3.org/2001/04/xmlenc#aes256-cbc
|
37
|
+
|
38
|
+
Key algorithms
|
39
|
+
|
40
|
+
* http://www.w3.org/2001/04/xmlenc#rsa-1_5
|
41
|
+
* http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p (Without OAEPParams and only SHA1 digest methods)
|
42
|
+
|
43
|
+
|
44
|
+
## Roadmap
|
45
|
+
1. add encryption (in progress)
|
46
|
+
2. support more algorithms
|
22
47
|
|
23
48
|
## Contributing
|
24
49
|
|
data/lib/xmlenc.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'active_support/all'
|
2
|
+
require 'active_model'
|
1
3
|
require 'xmlenc/version'
|
2
4
|
require 'openssl'
|
3
5
|
require 'base64'
|
@@ -12,8 +14,24 @@ module Xmlenc
|
|
12
14
|
class UnsupportedError < StandardError
|
13
15
|
end
|
14
16
|
|
17
|
+
class UnparseableMessage < StandardError
|
18
|
+
end
|
19
|
+
|
20
|
+
module Builder
|
21
|
+
autoload :Base, 'xmlenc/builder/base'
|
22
|
+
autoload :EncryptedData, 'xmlenc/builder/encrypted_data'
|
23
|
+
autoload :EncryptionMethod, 'xmlenc/builder/encryption_method'
|
24
|
+
autoload :EncryptedKey, 'xmlenc/builder/encrypted_key'
|
25
|
+
autoload :KeyInfo, 'xmlenc/builder/key_info'
|
26
|
+
autoload :CipherData, 'xmlenc/builder/cipher_data'
|
27
|
+
|
28
|
+
module ComplexTypes
|
29
|
+
autoload :EncryptedType, 'xmlenc/builder/complex_types/encrypted_type'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
15
33
|
module Algorithms
|
16
|
-
autoload :
|
34
|
+
autoload :RSA15, 'xmlenc/algorithms/rsa_15'
|
17
35
|
autoload :RsaOaepMgf1p, 'xmlenc/algorithms/rsa_oaep_mgf1p'
|
18
36
|
autoload :DES3CBC, 'xmlenc/algorithms/des3_cbc'
|
19
37
|
autoload :AESCBC, 'xmlenc/algorithms/aes_cbc'
|
@@ -11,8 +11,10 @@ module Xmlenc
|
|
11
11
|
@size = size
|
12
12
|
end
|
13
13
|
|
14
|
-
def setup(key)
|
15
|
-
@
|
14
|
+
def setup(key = nil)
|
15
|
+
@cipher= nil
|
16
|
+
@iv = nil
|
17
|
+
@key = key || cipher.random_key
|
16
18
|
self
|
17
19
|
end
|
18
20
|
|
@@ -20,12 +22,26 @@ module Xmlenc
|
|
20
22
|
cipher.decrypt
|
21
23
|
cipher.key = @key
|
22
24
|
cipher.iv = cipher_value[0...iv_len]
|
23
|
-
|
24
|
-
|
25
|
+
cipher.update(cipher_value[iv_len..-1]) << cipher.final
|
26
|
+
end
|
27
|
+
|
28
|
+
def encrypt(data, options = {})
|
29
|
+
cipher.encrypt
|
30
|
+
cipher.key = @key
|
31
|
+
cipher.iv = iv
|
32
|
+
iv << cipher.update(data) << cipher.final
|
33
|
+
end
|
34
|
+
|
35
|
+
def key
|
36
|
+
@key
|
25
37
|
end
|
26
38
|
|
27
39
|
private
|
28
40
|
|
41
|
+
def iv
|
42
|
+
@iv ||= cipher.random_iv
|
43
|
+
end
|
44
|
+
|
29
45
|
def iv_len
|
30
46
|
cipher.iv_len
|
31
47
|
end
|
@@ -5,16 +5,26 @@ module Xmlenc
|
|
5
5
|
new(key)
|
6
6
|
end
|
7
7
|
|
8
|
-
def initialize(key)
|
9
|
-
@key = key
|
8
|
+
def initialize(key = nil)
|
9
|
+
@key = key || cipher.random_key
|
10
10
|
end
|
11
11
|
|
12
12
|
def decrypt(cipher_value, options = {})
|
13
13
|
cipher.decrypt
|
14
14
|
cipher.key = @key
|
15
15
|
cipher.iv = cipher_value[0...iv_len]
|
16
|
-
|
17
|
-
|
16
|
+
cipher.update(cipher_value[iv_len..-1]) << cipher.final
|
17
|
+
end
|
18
|
+
|
19
|
+
def encrypt(data, options = {})
|
20
|
+
cipher.encrypt
|
21
|
+
cipher.key = @key
|
22
|
+
cipher.iv = iv
|
23
|
+
iv << cipher.update(data) << cipher.final
|
24
|
+
end
|
25
|
+
|
26
|
+
def key
|
27
|
+
@key
|
18
28
|
end
|
19
29
|
|
20
30
|
private
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Xmlenc
|
2
2
|
module Algorithms
|
3
|
-
class
|
3
|
+
class RSA15
|
4
4
|
def initialize(key)
|
5
5
|
@key = key
|
6
6
|
end
|
@@ -8,6 +8,10 @@ module Xmlenc
|
|
8
8
|
def decrypt(cipher_value, options = {})
|
9
9
|
@key.private_decrypt(cipher_value)
|
10
10
|
end
|
11
|
+
|
12
|
+
def encrypt(data, option = {})
|
13
|
+
@key.public_encrypt(data)
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
13
17
|
end
|
@@ -8,10 +8,15 @@ module Xmlenc
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def decrypt(cipher_value, options = {})
|
11
|
-
verify_algorithm(options[:node])
|
11
|
+
verify_algorithm(options[:node]) if options[:node]
|
12
12
|
@key.private_decrypt(cipher_value, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
|
13
13
|
end
|
14
14
|
|
15
|
+
def encrypt(data, options = {})
|
16
|
+
verify_algorithm(options[:node]) if options[:node]
|
17
|
+
@key.public_encrypt(data, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
|
18
|
+
end
|
19
|
+
|
15
20
|
private
|
16
21
|
|
17
22
|
def verify_algorithm(node)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "happymapper"
|
2
|
+
|
3
|
+
module Xmlenc
|
4
|
+
module Builder
|
5
|
+
module Base
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
include ::HappyMapper
|
10
|
+
include ::ActiveModel::Validations
|
11
|
+
|
12
|
+
extend HappyMapperClassMethods
|
13
|
+
include HappyMapperInstanceMethods
|
14
|
+
end
|
15
|
+
|
16
|
+
module HappyMapperInstanceMethods
|
17
|
+
def initialize(attributes = {})
|
18
|
+
attributes.each do |key, value|
|
19
|
+
send("#{key}=", value) if respond_to?("#{key}=") && value.present?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def from_xml=(bool)
|
24
|
+
@from_xml = bool
|
25
|
+
end
|
26
|
+
|
27
|
+
def from_xml?
|
28
|
+
@from_xml
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module HappyMapperClassMethods
|
33
|
+
def parse(xml, options = {})
|
34
|
+
object = super
|
35
|
+
if object.is_a?(Array)
|
36
|
+
object.map { |x| x.from_xml = true }
|
37
|
+
elsif object
|
38
|
+
object.from_xml = true
|
39
|
+
end
|
40
|
+
object
|
41
|
+
rescue Nokogiri::XML::SyntaxError => e
|
42
|
+
raise Xmlenc::UnparseableMessage.new(e.message)
|
43
|
+
rescue NoMethodError => e
|
44
|
+
raise Xmlenc::UnparseableMessage.new(e.message)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Xmlenc
|
2
|
+
module Builder
|
3
|
+
class CipherData
|
4
|
+
include Xmlenc::Builder::Base
|
5
|
+
|
6
|
+
tag "CipherData"
|
7
|
+
|
8
|
+
register_namespace "xenc", Xmlenc::NAMESPACES[:xenc]
|
9
|
+
namespace "xenc"
|
10
|
+
|
11
|
+
element :cipher_value, String, namespace: "xenc", tag: "CipherValue"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Xmlenc
|
2
|
+
module Builder
|
3
|
+
module ComplexTypes
|
4
|
+
module EncryptedType
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
include Xmlenc::Builder::Base
|
7
|
+
|
8
|
+
included do
|
9
|
+
register_namespace "xenc", Xmlenc::NAMESPACES[:xenc]
|
10
|
+
|
11
|
+
has_one :encryption_method, Xmlenc::Builder::EncryptionMethod, xpath: "./"
|
12
|
+
has_one :key_info, Xmlenc::Builder::KeyInfo, xpath: "./"
|
13
|
+
has_one :cipher_data, Xmlenc::Builder::CipherData, xpath: "./"
|
14
|
+
|
15
|
+
validates :cipher_data, presence: true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Xmlenc
|
2
|
+
module Builder
|
3
|
+
class EncryptionMethod
|
4
|
+
include Xmlenc::Builder::Base
|
5
|
+
|
6
|
+
tag "EncryptionMethod"
|
7
|
+
|
8
|
+
register_namespace "xenc", Xmlenc::NAMESPACES[:xenc]
|
9
|
+
namespace "xenc"
|
10
|
+
|
11
|
+
attribute :algorithm, String, tag: "Algorithm"
|
12
|
+
|
13
|
+
validates :algorithm, presence: true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Xmlenc
|
2
|
+
module Builder
|
3
|
+
class KeyInfo
|
4
|
+
include Xmlenc::Builder::Base
|
5
|
+
|
6
|
+
tag "KeyInfo"
|
7
|
+
|
8
|
+
register_namespace "ds", Xmlenc::NAMESPACES[:ds]
|
9
|
+
namespace "ds"
|
10
|
+
|
11
|
+
element :key_name, String, namespace: "ds", tag: "KeyName"
|
12
|
+
|
13
|
+
has_one :encrypted_key, Xmlenc::Builder::EncryptedKey, xpath: "./"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -6,6 +6,11 @@ module Xmlenc
|
|
6
6
|
'http://www.w3.org/2001/04/xmlenc#aes256-cbc' => Algorithms::AESCBC[256]
|
7
7
|
}
|
8
8
|
|
9
|
+
TYPES = {
|
10
|
+
'http://www.w3.org/2001/04/xmlenc#Element' => :element,
|
11
|
+
'http://www.w3.org/2001/04/xmlenc#Content' => :content,
|
12
|
+
}
|
13
|
+
|
9
14
|
attr_accessor :node
|
10
15
|
|
11
16
|
def initialize(node)
|
@@ -24,9 +29,26 @@ module Xmlenc
|
|
24
29
|
at_xpath('./xenc:CipherData/xenc:CipherValue').content.gsub(/[\n\s]/, '')
|
25
30
|
end
|
26
31
|
|
32
|
+
def cipher_value=(value)
|
33
|
+
at_xpath('./xenc:CipherData/xenc:CipherValue').content = value
|
34
|
+
end
|
35
|
+
|
27
36
|
def decrypt(key)
|
28
37
|
decryptor = algorithm.setup(key)
|
29
|
-
decryptor.decrypt(Base64.decode64(cipher_value), node: encryption_method)
|
38
|
+
decrypted = decryptor.decrypt(Base64.decode64(cipher_value), node: encryption_method)
|
39
|
+
@node.replace(decrypted) unless @node == document.root
|
40
|
+
decrypted
|
41
|
+
end
|
42
|
+
|
43
|
+
def encrypt(data)
|
44
|
+
encryptor = algorithm.setup
|
45
|
+
encrypted = encryptor.encrypt(data, node: encryption_method)
|
46
|
+
self.cipher_value = Base64.encode64(encrypted)
|
47
|
+
encryptor.key
|
48
|
+
end
|
49
|
+
|
50
|
+
def type
|
51
|
+
TYPES[@node['Type']]
|
30
52
|
end
|
31
53
|
|
32
54
|
private
|
@@ -7,7 +7,7 @@ module Xmlenc
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def document
|
10
|
-
@document
|
10
|
+
@document ||= Nokogiri::XML::Document.parse(xml)
|
11
11
|
end
|
12
12
|
|
13
13
|
def encrypted_keys
|
@@ -17,10 +17,8 @@ module Xmlenc
|
|
17
17
|
def decrypt(key)
|
18
18
|
encrypted_keys.each do |encrypted_key|
|
19
19
|
encrypted_data = encrypted_key.encrypted_data
|
20
|
-
|
21
20
|
data_key = encrypted_key.decrypt(key)
|
22
|
-
|
23
|
-
encrypted_data.node.replace(decrypted_data)
|
21
|
+
encrypted_data.decrypt(data_key)
|
24
22
|
end
|
25
23
|
@document.to_xml
|
26
24
|
end
|
data/lib/xmlenc/encrypted_key.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Xmlenc
|
2
2
|
class EncryptedKey
|
3
3
|
ALGORITHMS = {
|
4
|
-
'http://www.w3.org/2001/04/xmlenc#rsa-1_5' => Algorithms::
|
4
|
+
'http://www.w3.org/2001/04/xmlenc#rsa-1_5' => Algorithms::RSA15,
|
5
5
|
'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' => Algorithms::RsaOaepMgf1p
|
6
6
|
}
|
7
7
|
|
@@ -25,11 +25,21 @@ module Xmlenc
|
|
25
25
|
at_xpath('./xenc:CipherData/xenc:CipherValue').content.gsub(/[\n\s]/, '')
|
26
26
|
end
|
27
27
|
|
28
|
+
def cipher_value=(value)
|
29
|
+
at_xpath('./xenc:CipherData/xenc:CipherValue').content = value
|
30
|
+
end
|
31
|
+
|
28
32
|
def decrypt(key)
|
29
33
|
decryptor = algorithm.new(key)
|
30
34
|
decryptor.decrypt(Base64.decode64(cipher_value), node: encryption_method)
|
31
35
|
end
|
32
36
|
|
37
|
+
def encrypt(key, data)
|
38
|
+
encryptor = algorithm.new(key)
|
39
|
+
encrypted = encryptor.encrypt(data, node: encryption_method)
|
40
|
+
self.cipher_value = Base64.encode64(encrypted)
|
41
|
+
end
|
42
|
+
|
33
43
|
private
|
34
44
|
|
35
45
|
def referenced_node
|
data/lib/xmlenc/version.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
<EncryptedData Id="ED" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#">
|
2
|
+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
|
3
|
+
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
4
|
+
<EncryptedKey Id="EK" xmlns="http://www.w3.org/2001/04/xmlenc#">
|
5
|
+
<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
|
6
|
+
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
7
|
+
<ds:KeyName>my-rsa-key</ds:KeyName>
|
8
|
+
<ds:X509Data>
|
9
|
+
<ds:X509Certificate>
|
10
|
+
MIIDzTCCArWgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBljELMAkGA1UEBhMCVVMx
|
11
|
+
CzAJBgNVBAgTAk5ZMRIwEAYDVQQHEwlNYW5oYXR0YW4xFTATBgNVBAoTDExhdmEg
|
12
|
+
U3VwcmVtZTEUMBIGA1UECxMLSGVhZCBPZmZpY2UxFDASBgNVBAMTC1JTQSBUZXN0
|
13
|
+
IENBMSMwIQYJKoZIhvcNAQkBFhR0ZWNoQGxhdmFzdXByZW1lLm9yZzAeFw0wMjAx
|
14
|
+
MzExNjI5NDNaFw00MzAyMjUxNjI5NDNaMIGWMQswCQYDVQQGEwJVUzELMAkGA1UE
|
15
|
+
CBMCTlkxEjAQBgNVBAcTCU1hbmhhdHRhbjEVMBMGA1UEChMMTGF2YSBTdXByZW1l
|
16
|
+
MRQwEgYDVQQLEwtIZWFkIE9mZmljZTEUMBIGA1UEAxMLUlNBIFRlc3QgQ0ExIzAh
|
17
|
+
BgkqhkiG9w0BCQEWFHRlY2hAbGF2YXN1cHJlbWUub3JnMIIBIjANBgkqhkiG9w0B
|
18
|
+
AQEFAAOCAQ8AMIIBCgKCAQEAgj3TOyUtgg99oEfsm8h9JTZBxUkzYkXVUOHxIwnk
|
19
|
+
Fwp4y9ZnrGja/j+kpRyKvYP5CkNdq0e58/r7GLXj45iqd03XjsFNTdjy4OIOgf7J
|
20
|
+
xMG7z+hEB1LT2swTs10GILFWPByRl3/BEsnekLZdoqNoJrvnttVkxgu3x80Ji3/A
|
21
|
+
ZD8Ub/kBGOSPyu6pn3OdnMTc5q4r1qUe985lQzCZvCMw6AoGeCyJodNu2MbveNeH
|
22
|
+
+YPjRgLCQfzvOFRq+9qMtE8XfUJZdNhPZhgdsOGf8uJauTcIHbAyw7BhxPy6RikW
|
23
|
+
W5yiWUmBya+7t4y1TQJzham/0y0zU3TAA7b/rDrU7xmNPwIDAQABoyQwIjAPBgNV
|
24
|
+
HRMBAf8EBTADAQH/MA8GA1UdDwEB/wQFAwMHBgAwDQYJKoZIhvcNAQEEBQADggEB
|
25
|
+
ADELWZjFLPjSjGeOaeUwH/mEOP+l/nTtxe07IWAQL4kvb4wsiUsM1EkPptcBQsym
|
26
|
+
OYgFhf3Elqma84bbOyp85y/iQnjpqWWJ73TFXSWZamSIhYb4Gk+dQuwFI+zD3B2y
|
27
|
+
WwqghaAHDzxtzROLUBjo+97Y6ng6V5zjmtdGOFwNXwWhf3Y+MjnErtBIKYao8NJO
|
28
|
+
p6di80w82+s6Ot+CLVvVobLhxS/y8yWplATRiQnI5ij/WTLML+tiU5aes0c9abaf
|
29
|
+
O7i9j1iTuZsDT3f96ia0RSLsXSGij737QKc3ZM8lSxBWfepWYO+G+IRgr1q9IUDa
|
30
|
+
kKO/vB9Ay64Rt88XbLnnGns=
|
31
|
+
</ds:X509Certificate>
|
32
|
+
</ds:X509Data>
|
33
|
+
</ds:KeyInfo>
|
34
|
+
<CipherData>
|
35
|
+
<CipherValue/>
|
36
|
+
</CipherData>
|
37
|
+
<ReferenceList>
|
38
|
+
<DataReference URI="ED"/>
|
39
|
+
</ReferenceList>
|
40
|
+
</EncryptedKey>
|
41
|
+
</ds:KeyInfo>
|
42
|
+
<CipherData>
|
43
|
+
<CipherValue/>
|
44
|
+
</CipherData>
|
45
|
+
</EncryptedData>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Xmlenc::Algorithms::AESCBC do
|
4
|
+
let(:key) { %w(1e8c108fc0521dcad99ff2daad45af64).pack('H*') }
|
5
|
+
let(:iv) { %w(6232242cfaa495554dd5f684b17d6de4).pack('H*') }
|
6
|
+
let(:cipher_value) { Base64.decode64 "YjIkLPqklVVN1faEsX1t5EXXxdlW3B0rKoZsT5DtaS+pChdcceQV605clJ8Y\nEhOjEhM0oCGf855bQVWp7J3TJqUFlxahREEWCfEvsIUzy/wNMHV6Z/mTFkQU\nWnrO3C3DSC6rTglijkPp592Sh1Cb6HTD60Nc/Myn3QLnwlSj+30x3uTUiAVE\nL+xduAnppCR1vhRsB3yw32TjRfZt1b+UURRzCts5oLrVAu9SSrmgJI+vUX9g\nsRgvwkmsi4AAq38a\n" }
|
7
|
+
let(:data) { "<CreditCard Currency=\"USD\" Limit=\"5,000\">\r\n <Number>4019 2445 0277 5567</Number>\r\n <Issuer>Bank of the Internet</Issuer>\r\n <Expiration Time=\"04/02\"/>\r\n </CreditCard>" }
|
8
|
+
subject { described_class.new(128).setup(key) }
|
9
|
+
|
10
|
+
describe 'encrypt' do
|
11
|
+
it 'encrypts the data' do
|
12
|
+
subject.stub(:iv).and_return(iv)
|
13
|
+
expect(subject.encrypt(data)).to be == cipher_value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'decrypt' do
|
18
|
+
it 'decrypts the cipher_value' do
|
19
|
+
expect(subject.decrypt(cipher_value)).to be == data
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Xmlenc::Algorithms::DES3CBC do
|
4
|
+
let(:key) { %w(3219e991eccd9186bf75a83ef8982fd0df4558fd1a837aa2).pack('H*') }
|
5
|
+
let(:iv) { %w(918eac719c69c915).pack('H*') }
|
6
|
+
let(:cipher_value) { Base64.decode64 "kY6scZxpyRXQbaDZp+LbuvSFYgmI3pQrfsrCVt3/9sZzpeUTPXJEatQ5KPOX\nYpJCGid01h/T8PIezic0Ooz/jU+r3kYMKesMYiXin4CXTZYcGhd0TjmOd4kg\n1vlhE8ktWLC7JDzFLPAqXbOug3ghmWunFiUETbGJaF5V4AHIoZrYP+RS3DTL\ngJcATuDeWyOdueqnLefXiCDNqgSTsK4OyNlX0fpUJgKbL+Mhf5vsqxyIqDsS\n/p6cRA==\n" }
|
7
|
+
let(:data) { "<CreditCard Currency=\"USD\" Limit=\"5,000\">\r\n <Number>4019 2445 0277 5567</Number>\r\n <Issuer>Bank of the Internet</Issuer>\r\n <Expiration Time=\"04/02\"/>\r\n </CreditCard>" }
|
8
|
+
subject { described_class.setup(key) }
|
9
|
+
|
10
|
+
describe 'encrypt' do
|
11
|
+
it 'encrypts the data' do
|
12
|
+
subject.stub(:iv).and_return(iv)
|
13
|
+
expect(subject.encrypt(data)).to be == cipher_value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'decrypt' do
|
18
|
+
it 'decrypts the cipher_value' do
|
19
|
+
expect(subject.decrypt(cipher_value)).to be == data
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Xmlenc::Algorithms::RSA15 do
|
4
|
+
let(:private_key) { OpenSSL::PKey::RSA.new(File.read('spec/fixtures/key.pem')) }
|
5
|
+
let(:public_key) { private_key.public_key }
|
6
|
+
let(:cipher_value) { Base64.decode64 "cCxxYh3xGBTqlXbhmKxWzNMlHeE28E7vPrMyM5V4T+t1Iy2csj1BoQ7cqBjE\nhqEyEot4WNRYsY7P44mWBKurj2mdWQWgoxHvtITP9AR3JTMxUo3TF5ltW76D\nLDsEvWlEuZKam0PYj6lYPKd4npUULeZyR/rDRrth/wFIBD8vbQlUsBHapNT9\nMbQfSKZemOuTUJL9PNgsosySpKrX564oQw398XsxfTFxi4hqbdqzA/CLL418\nX01hUjIHdyv6XnA298Bmfv9WMPpX05udR4raDv5X8NWxjH00hAhasM3qumxo\nyCT6mAGfqvE23I+OXtrNlUvE9mMjANw4zweCHsOcfw==\n" }
|
7
|
+
let(:key) { %w(ba1407b67c847b0a85a33c93286c401d).pack("H*") }
|
8
|
+
|
9
|
+
|
10
|
+
describe 'decrypt' do
|
11
|
+
subject { described_class.new(private_key) }
|
12
|
+
|
13
|
+
it 'decrypts the cipher value' do
|
14
|
+
expect(subject.decrypt(cipher_value)).to be == key
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'encrypt' do
|
19
|
+
subject { described_class.new(public_key) }
|
20
|
+
|
21
|
+
it 'encrypts the key' do
|
22
|
+
encrypted = subject.encrypt(key)
|
23
|
+
expect(private_key.private_decrypt(encrypted)).to be == key
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Xmlenc::Algorithms::RsaOaepMgf1p do
|
4
|
+
let(:private_key) { OpenSSL::PKey::RSA.new(File.read('spec/fixtures/key.pem')) }
|
5
|
+
let(:public_key) { private_key.public_key }
|
6
|
+
let(:cipher_value) { Base64.decode64 "W6N0IhRF2AdgfzzkZSp/u1kH5KmH8L4W8k4mdNMboLsYgnBUV3lsRvoFrVTX\nluMVDtXY1ju7aAEUJP9eMRU676kvRR5nSVuAbWCAejgkHMtGShJHU1s/JMzb\nu3iaxsuyPosT7/iafinNIXumvqLM/WQl9KbsmcWoAmJISbK1+WJ2kahrXNav\n4+7vMJq90BOPl8bXIzeKIsps7OGwEvrFaJ5RzVjZXi9SDXXD1vd6tJBcCfcZ\n347Mat1tZkR3cYrCMhDdte3gYGUQLzUlMYucvWz1slzTX3rYea/vhgA+OLOp\ndZxwM4igx1d8j5jjmo8FR1rxwd0G4NHA1bZ6TOy/IA==\n" }
|
7
|
+
let(:key) { %w(1e8c108fc0521dcad99ff2daad45af64).pack("H*") }
|
8
|
+
|
9
|
+
|
10
|
+
describe 'decrypt' do
|
11
|
+
subject { described_class.new(private_key) }
|
12
|
+
|
13
|
+
it 'decrypts the cipher value' do
|
14
|
+
expect(subject.decrypt(cipher_value)).to be == key
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'encrypt' do
|
19
|
+
subject { described_class.new(public_key) }
|
20
|
+
|
21
|
+
it 'encrypts the key' do
|
22
|
+
encrypted = subject.encrypt(key)
|
23
|
+
expect(private_key.private_decrypt(encrypted, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)).to be == key
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class BaseDummy
|
4
|
+
include Xmlenc::Builder::Base
|
5
|
+
|
6
|
+
tag "tag"
|
7
|
+
end
|
8
|
+
|
9
|
+
describe BaseDummy do
|
10
|
+
describe "parse override" do
|
11
|
+
it "sets the from_xml flag" do
|
12
|
+
BaseDummy.parse("<tag></tag>", single: true).from_xml?.should be_true
|
13
|
+
end
|
14
|
+
|
15
|
+
it "raises an error if the message cannot be parsed" do
|
16
|
+
expect {
|
17
|
+
BaseDummy.parse("invalid")
|
18
|
+
}.to raise_error(Xmlenc::UnparseableMessage)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "raises an error if the message is nil" do
|
22
|
+
expect {
|
23
|
+
BaseDummy.parse(nil)
|
24
|
+
}.to raise_error(Xmlenc::UnparseableMessage)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Xmlenc::Builder::CipherData do
|
4
|
+
|
5
|
+
let(:xml) { File.read File.join("spec", "fixtures", "encrypted_document.xml") }
|
6
|
+
subject { described_class.parse(xml) }
|
7
|
+
|
8
|
+
describe "#parse" do
|
9
|
+
it "should create two CipherData elements" do
|
10
|
+
subject.each do |element|
|
11
|
+
expect(element).to be_a Xmlenc::Builder::CipherData
|
12
|
+
end
|
13
|
+
|
14
|
+
expect(subject.size).to eq 2
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "cipher value" do
|
18
|
+
it "should parse the cipher value of the first cipher data element" do
|
19
|
+
expect(subject.first.cipher_value.gsub(/[\n\s]/, "")).to eq "cCxxYh3xGBTqlXbhmKxWzNMlHeE28E7vPrMyM5V4T+t1Iy2csj1BoQ7cqBjEhqEyEot4WNRYsY7P44mWBKurj2mdWQWgoxHvtITP9AR3JTMxUo3TF5ltW76DLDsEvWlEuZKam0PYj6lYPKd4npUULeZyR/rDRrth/wFIBD8vbQlUsBHapNT9MbQfSKZemOuTUJL9PNgsosySpKrX564oQw398XsxfTFxi4hqbdqzA/CLL418X01hUjIHdyv6XnA298Bmfv9WMPpX05udR4raDv5X8NWxjH00hAhasM3qumxoyCT6mAGfqvE23I+OXtrNlUvE9mMjANw4zweCHsOcfw=="
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should parse the cipher value of the last cipher data element" do
|
23
|
+
expect(subject.last.cipher_value.gsub(/[\n\s]/, "")).to eq "u2vogkwlvFqeknJ0lYTBZkWS/eX8LR1fDPFMfyK1/UY0EyZfHvbONfDHcC/HLv/faAOOO2Y0GqsknP0LYT1OznkiJrzx134cmJCgbyrYXd3Mp21Pq3rs66JJ34Qt3/+IEyJBUSMT8TdT3fBD44BtOqH2op/hy2g3hQPFZul4GiHBEnNJL/4nU1yad3bMvtABmzhx80lJvPGLcruj5V77WMvkvZfoeEqMq4qPWK02ZURsJsq0iZcJDi39NB7OCiON"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class EncryptedTypeDummy
|
4
|
+
include Xmlenc::Builder::ComplexTypes::EncryptedType
|
5
|
+
|
6
|
+
tag "EncryptedData"
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Xmlenc::Builder::ComplexTypes::EncryptedType do
|
10
|
+
|
11
|
+
let(:xml) { File.read File.join("spec", "fixtures", "encrypted_document.xml") }
|
12
|
+
subject { EncryptedTypeDummy.new.parse(xml, single: true) }
|
13
|
+
|
14
|
+
describe "required fields" do
|
15
|
+
it "should have the cipher data field" do
|
16
|
+
expect(subject).to respond_to :cipher_data
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should check the presence of cipher data" do
|
20
|
+
subject.cipher_data = nil
|
21
|
+
expect(subject).to have(1).error_on :cipher_data
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "optional fields" do
|
26
|
+
[:encryption_method, :key_info].each do |field|
|
27
|
+
it "should have the #{field} field" do
|
28
|
+
expect(subject).to respond_to field
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should allow #{field} to be blank" do
|
32
|
+
subject.send("#{field}=", nil)
|
33
|
+
expect(subject).to be_valid
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#parse" do
|
39
|
+
describe "encryption method" do
|
40
|
+
it "should create an EncryptionMethod element" do
|
41
|
+
expect(subject.encryption_method).to be_a Xmlenc::Builder::EncryptionMethod
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should parse the algorithm" do
|
45
|
+
expect(subject.encryption_method.algorithm).to eq "http://www.w3.org/2001/04/xmlenc#aes128-cbc"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "key info" do
|
50
|
+
it "should create a KeyInfo element" do
|
51
|
+
expect(subject.key_info).to be_a Xmlenc::Builder::KeyInfo
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "cipher data" do
|
56
|
+
it "should create a CipherData element" do
|
57
|
+
expect(subject.cipher_data).to be_a Xmlenc::Builder::CipherData
|
58
|
+
end
|
59
|
+
|
60
|
+
let(:cipher_value) { subject.cipher_data.cipher_value.gsub(/[\n\s]/, "") }
|
61
|
+
|
62
|
+
it "should parse the cipher value" do
|
63
|
+
expect(cipher_value).to eq "u2vogkwlvFqeknJ0lYTBZkWS/eX8LR1fDPFMfyK1/UY0EyZfHvbONfDHcC/HLv/faAOOO2Y0GqsknP0LYT1OznkiJrzx134cmJCgbyrYXd3Mp21Pq3rs66JJ34Qt3/+IEyJBUSMT8TdT3fBD44BtOqH2op/hy2g3hQPFZul4GiHBEnNJL/4nU1yad3bMvtABmzhx80lJvPGLcruj5V77WMvkvZfoeEqMq4qPWK02ZURsJsq0iZcJDi39NB7OCiON"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Xmlenc::Builder::EncryptedData do
|
4
|
+
|
5
|
+
let(:xml) { File.read File.join("spec", "fixtures", "encrypted_document.xml") }
|
6
|
+
subject { described_class.parse(xml, single: true) }
|
7
|
+
|
8
|
+
describe "required fields" do
|
9
|
+
it "should have the cipher data field" do
|
10
|
+
expect(subject).to respond_to :cipher_data
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should check the presence of cipher data" do
|
14
|
+
subject.cipher_data = nil
|
15
|
+
expect(subject).to have(1).error_on :cipher_data
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "optional fields" do
|
20
|
+
[:encryption_method, :key_info].each do |field|
|
21
|
+
it "should have the #{field} field" do
|
22
|
+
expect(subject).to respond_to field
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should allow #{field} to be blank" do
|
26
|
+
subject.send("#{field}=", nil)
|
27
|
+
expect(subject).to be_valid
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#parse" do
|
33
|
+
it "should create an EncryptedData element" do
|
34
|
+
expect(subject).to be_a Xmlenc::Builder::EncryptedData
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should parse the id" do
|
38
|
+
expect(subject.id).to eq "ED"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should parse the type" do
|
42
|
+
expect(subject.type).to eq "http://www.w3.org/2001/04/xmlenc#Element"
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "encryption method" do
|
46
|
+
it "should create an EncryptionMethod element" do
|
47
|
+
expect(subject.encryption_method).to be_a Xmlenc::Builder::EncryptionMethod
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should parse the algorithm" do
|
51
|
+
expect(subject.encryption_method.algorithm).to eq "http://www.w3.org/2001/04/xmlenc#aes128-cbc"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "key info" do
|
56
|
+
it "should create a KeyInfo element" do
|
57
|
+
expect(subject.key_info).to be_a Xmlenc::Builder::KeyInfo
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "cipher data" do
|
62
|
+
it "should create a CipherData element" do
|
63
|
+
expect(subject.cipher_data).to be_a Xmlenc::Builder::CipherData
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:cipher_value) { subject.cipher_data.cipher_value.gsub(/[\n\s]/, "") }
|
67
|
+
|
68
|
+
it "should parse the cipher value" do
|
69
|
+
expect(cipher_value).to eq "u2vogkwlvFqeknJ0lYTBZkWS/eX8LR1fDPFMfyK1/UY0EyZfHvbONfDHcC/HLv/faAOOO2Y0GqsknP0LYT1OznkiJrzx134cmJCgbyrYXd3Mp21Pq3rs66JJ34Qt3/+IEyJBUSMT8TdT3fBD44BtOqH2op/hy2g3hQPFZul4GiHBEnNJL/4nU1yad3bMvtABmzhx80lJvPGLcruj5V77WMvkvZfoeEqMq4qPWK02ZURsJsq0iZcJDi39NB7OCiON"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Xmlenc::Builder::EncryptedKey do
|
4
|
+
|
5
|
+
let(:xml) { File.read File.join("spec", "fixtures", "encrypted_document.xml") }
|
6
|
+
subject { described_class.parse(xml, single: true) }
|
7
|
+
|
8
|
+
describe "required fields" do
|
9
|
+
it "should have the cipher data field" do
|
10
|
+
expect(subject).to respond_to :cipher_data
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should check the presence of cipher data" do
|
14
|
+
subject.cipher_data = nil
|
15
|
+
expect(subject).to have(1).error_on :cipher_data
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "optional fields" do
|
20
|
+
[:encryption_method, :key_info].each do |field|
|
21
|
+
it "should have the #{field} field" do
|
22
|
+
expect(subject).to respond_to field
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should allow #{field} to be blank" do
|
26
|
+
subject.send("#{field}=", nil)
|
27
|
+
expect(subject).to be_valid
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#parse" do
|
33
|
+
it "should create an EncryptedKey" do
|
34
|
+
expect(subject).to be_a Xmlenc::Builder::EncryptedKey
|
35
|
+
end
|
36
|
+
|
37
|
+
describe "encryption method" do
|
38
|
+
it "should create an EncryptionMethod element" do
|
39
|
+
expect(subject.encryption_method).to be_a Xmlenc::Builder::EncryptionMethod
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should parse the algorithm" do
|
43
|
+
expect(subject.encryption_method.algorithm).to eq "http://www.w3.org/2001/04/xmlenc#rsa-1_5"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "key info" do
|
48
|
+
it "should create a KeyInfo element" do
|
49
|
+
expect(subject.key_info).to be_a Xmlenc::Builder::KeyInfo
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "cipher data" do
|
54
|
+
it "should create a CipherData element" do
|
55
|
+
expect(subject.cipher_data).to be_a Xmlenc::Builder::CipherData
|
56
|
+
end
|
57
|
+
|
58
|
+
let(:cipher_value) { subject.cipher_data.cipher_value.gsub(/[\n\s]/, "") }
|
59
|
+
|
60
|
+
it "should parse the cipher value" do
|
61
|
+
expect(cipher_value).to eq "cCxxYh3xGBTqlXbhmKxWzNMlHeE28E7vPrMyM5V4T+t1Iy2csj1BoQ7cqBjEhqEyEot4WNRYsY7P44mWBKurj2mdWQWgoxHvtITP9AR3JTMxUo3TF5ltW76DLDsEvWlEuZKam0PYj6lYPKd4npUULeZyR/rDRrth/wFIBD8vbQlUsBHapNT9MbQfSKZemOuTUJL9PNgsosySpKrX564oQw398XsxfTFxi4hqbdqzA/CLL418X01hUjIHdyv6XnA298Bmfv9WMPpX05udR4raDv5X8NWxjH00hAhasM3qumxoyCT6mAGfqvE23I+OXtrNlUvE9mMjANw4zweCHsOcfw=="
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Xmlenc::Builder::EncryptionMethod do
|
4
|
+
|
5
|
+
let(:xml) { File.read File.join("spec", "fixtures", "encrypted_document.xml") }
|
6
|
+
subject { described_class.parse(xml, single: true) }
|
7
|
+
|
8
|
+
describe "required fields" do
|
9
|
+
it "should have the algorithm field" do
|
10
|
+
expect(subject).to respond_to :algorithm
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should check the presence of algorithm" do
|
14
|
+
subject.algorithm = nil
|
15
|
+
expect(subject).to have(1).error_on :algorithm
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#parse" do
|
20
|
+
it "should create an EncryptionMethod" do
|
21
|
+
expect(subject).to be_a Xmlenc::Builder::EncryptionMethod
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should parse the algorithm" do
|
25
|
+
expect(subject.algorithm).to eq "http://www.w3.org/2001/04/xmlenc#aes128-cbc"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Xmlenc::Builder::KeyInfo do
|
4
|
+
|
5
|
+
let(:xml) { File.read File.join("spec", "fixtures", "encrypted_document.xml") }
|
6
|
+
subject { described_class.parse(xml) }
|
7
|
+
|
8
|
+
describe "#parse" do
|
9
|
+
it "should create two KeyInfo elements" do
|
10
|
+
subject.each do |element|
|
11
|
+
expect(element).to be_a Xmlenc::Builder::KeyInfo
|
12
|
+
end
|
13
|
+
|
14
|
+
expect(subject.size).to eq 2
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "key name" do
|
18
|
+
it "doesn't have a key name in the first key info element" do
|
19
|
+
expect(subject.first.key_name).to be_nil
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should parse the key name in the second key info element" do
|
23
|
+
expect(subject.last.key_name).to eq "my-rsa-key"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "encrypted key" do
|
28
|
+
it "should parse the encrypted key in the first key info element" do
|
29
|
+
expect(subject.first.encrypted_key).to be_a Xmlenc::Builder::EncryptedKey
|
30
|
+
end
|
31
|
+
|
32
|
+
it "doesn't have an encrypted key in the second key info element" do
|
33
|
+
expect(subject.last.encrypted_key).to be_nil
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Xmlenc::EncryptedData do
|
4
|
+
let(:plain_xml) { File.read('spec/fixtures/phaos/payment.xml') }
|
4
5
|
let(:encrypted_xml) { File.read('spec/fixtures/encrypted_document.xml') }
|
5
6
|
let(:doc) { Nokogiri::XML::Document.parse(encrypted_xml) }
|
6
7
|
let(:encrypted_data_node) { doc.at_xpath('//xenc:EncryptedData', Xmlenc::NAMESPACES) }
|
@@ -77,4 +78,22 @@ describe Xmlenc::EncryptedData do
|
|
77
78
|
end
|
78
79
|
end
|
79
80
|
end
|
81
|
+
|
82
|
+
describe 'encrypt' do
|
83
|
+
let(:template_node) { Nokogiri::XML::Document.parse(File.read('spec/fixtures/template.xml')).root }
|
84
|
+
let(:encrypted_data_template) { described_class.new(template_node) }
|
85
|
+
let(:data) { subject.decrypt(key) }
|
86
|
+
|
87
|
+
it 'stores the encrypted value in the cipher value' do
|
88
|
+
key = encrypted_data_template.encrypt(data)
|
89
|
+
|
90
|
+
expect(encrypted_data_template.cipher_value.length).to be > 0
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'allows decryption with the key' do
|
94
|
+
key = encrypted_data_template.encrypt(data)
|
95
|
+
|
96
|
+
expect(encrypted_data_template.decrypt(key)).to be == data
|
97
|
+
end
|
98
|
+
end
|
80
99
|
end
|
@@ -95,4 +95,25 @@ describe Xmlenc::EncryptedKey do
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
+
describe 'encrypt' do
|
99
|
+
let(:template_doc) { Nokogiri::XML::Document.parse(File.read('spec/fixtures/template.xml')) }
|
100
|
+
let(:encrypted_key_template) { described_class.new(template_doc.at_xpath('//xenc:EncryptedKey', Xmlenc::NAMESPACES)) }
|
101
|
+
let(:public_key) { private_key.public_key }
|
102
|
+
let(:data) { 'random key' }
|
103
|
+
|
104
|
+
it 'stores the encrypted value in the cipher value' do
|
105
|
+
encrypted_key_template.encrypt(public_key, data)
|
106
|
+
|
107
|
+
expect(encrypted_key_template.cipher_value.length).to be > 0
|
108
|
+
|
109
|
+
puts encrypted_key_template.document.to_xml
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'allows decryption with the key' do
|
113
|
+
encrypted_key_template.encrypt(public_key, data)
|
114
|
+
|
115
|
+
expect(encrypted_key_template.decrypt(private_key)).to be == data
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
98
119
|
end
|
data/spec/spec_helper.rb
CHANGED
data/xmlenc.gemspec
CHANGED
@@ -18,8 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ["lib"]
|
20
20
|
|
21
|
+
spec.add_dependency "activesupport", ">= 3.0.0"
|
22
|
+
spec.add_dependency "activemodel", ">= 3.0.0"
|
21
23
|
spec.add_dependency "nokogiri", "~> 1.6"
|
24
|
+
spec.add_development_dependency "nokogiri-happymapper", '~> 0.5.7'
|
22
25
|
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
-
spec.add_development_dependency "rspec", "~> 2.14"
|
26
|
+
spec.add_development_dependency "rspec-rails", "~> 2.14"
|
24
27
|
spec.add_development_dependency "rake"
|
25
28
|
end
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xmlenc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benoist
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-10-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ! '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ! '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activemodel
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 3.0.0
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 3.0.0
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: nokogiri
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,6 +52,20 @@ dependencies:
|
|
24
52
|
- - ~>
|
25
53
|
- !ruby/object:Gem::Version
|
26
54
|
version: '1.6'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: nokogiri-happymapper
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.5.7
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.5.7
|
27
69
|
- !ruby/object:Gem::Dependency
|
28
70
|
name: bundler
|
29
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,7 +81,7 @@ dependencies:
|
|
39
81
|
- !ruby/object:Gem::Version
|
40
82
|
version: '1.3'
|
41
83
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: rspec
|
84
|
+
name: rspec-rails
|
43
85
|
requirement: !ruby/object:Gem::Requirement
|
44
86
|
requirements:
|
45
87
|
- - ~>
|
@@ -84,6 +126,13 @@ files:
|
|
84
126
|
- lib/xmlenc/algorithms/des3_cbc.rb
|
85
127
|
- lib/xmlenc/algorithms/rsa_15.rb
|
86
128
|
- lib/xmlenc/algorithms/rsa_oaep_mgf1p.rb
|
129
|
+
- lib/xmlenc/builder/base.rb
|
130
|
+
- lib/xmlenc/builder/cipher_data.rb
|
131
|
+
- lib/xmlenc/builder/complex_types/encrypted_type.rb
|
132
|
+
- lib/xmlenc/builder/encrypted_data.rb
|
133
|
+
- lib/xmlenc/builder/encrypted_key.rb
|
134
|
+
- lib/xmlenc/builder/encryption_method.rb
|
135
|
+
- lib/xmlenc/builder/key_info.rb
|
87
136
|
- lib/xmlenc/encrypted_data.rb
|
88
137
|
- lib/xmlenc/encrypted_document.rb
|
89
138
|
- lib/xmlenc/encrypted_key.rb
|
@@ -98,7 +147,18 @@ files:
|
|
98
147
|
- spec/fixtures/phaos/key.txt
|
99
148
|
- spec/fixtures/phaos/payment.xml
|
100
149
|
- spec/fixtures/phaos/rsa-priv-key.pem
|
101
|
-
- spec/
|
150
|
+
- spec/fixtures/template.xml
|
151
|
+
- spec/lib/xmlenc/algorithms/aes_cbc_spec.rb
|
152
|
+
- spec/lib/xmlenc/algorithms/des3_cbc_spec.rb
|
153
|
+
- spec/lib/xmlenc/algorithms/rsa_15_spec.rb
|
154
|
+
- spec/lib/xmlenc/algorithms/rsa_oaep_mgf1p_spec.rb
|
155
|
+
- spec/lib/xmlenc/builder/base_spec.rb
|
156
|
+
- spec/lib/xmlenc/builder/cipher_data_spec.rb
|
157
|
+
- spec/lib/xmlenc/builder/complex_types/encrypted_type_spec.rb
|
158
|
+
- spec/lib/xmlenc/builder/encrypted_data_spec.rb
|
159
|
+
- spec/lib/xmlenc/builder/encrypted_key_spec.rb
|
160
|
+
- spec/lib/xmlenc/builder/encryption_method_spec.rb
|
161
|
+
- spec/lib/xmlenc/builder/key_info_spec.rb
|
102
162
|
- spec/lib/xmlenc/encrypted_data_spec.rb
|
103
163
|
- spec/lib/xmlenc/encrypted_document_spec.rb
|
104
164
|
- spec/lib/xmlenc/encrypted_key_spec.rb
|
@@ -140,7 +200,18 @@ test_files:
|
|
140
200
|
- spec/fixtures/phaos/key.txt
|
141
201
|
- spec/fixtures/phaos/payment.xml
|
142
202
|
- spec/fixtures/phaos/rsa-priv-key.pem
|
143
|
-
- spec/
|
203
|
+
- spec/fixtures/template.xml
|
204
|
+
- spec/lib/xmlenc/algorithms/aes_cbc_spec.rb
|
205
|
+
- spec/lib/xmlenc/algorithms/des3_cbc_spec.rb
|
206
|
+
- spec/lib/xmlenc/algorithms/rsa_15_spec.rb
|
207
|
+
- spec/lib/xmlenc/algorithms/rsa_oaep_mgf1p_spec.rb
|
208
|
+
- spec/lib/xmlenc/builder/base_spec.rb
|
209
|
+
- spec/lib/xmlenc/builder/cipher_data_spec.rb
|
210
|
+
- spec/lib/xmlenc/builder/complex_types/encrypted_type_spec.rb
|
211
|
+
- spec/lib/xmlenc/builder/encrypted_data_spec.rb
|
212
|
+
- spec/lib/xmlenc/builder/encrypted_key_spec.rb
|
213
|
+
- spec/lib/xmlenc/builder/encryption_method_spec.rb
|
214
|
+
- spec/lib/xmlenc/builder/key_info_spec.rb
|
144
215
|
- spec/lib/xmlenc/encrypted_data_spec.rb
|
145
216
|
- spec/lib/xmlenc/encrypted_document_spec.rb
|
146
217
|
- spec/lib/xmlenc/encrypted_key_spec.rb
|
data/spec/lib/xmlenc/.keep
DELETED
File without changes
|