xmlenc 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZTg0OGJjOWQ5MzI1MDU2ZTZlYjk0ODU5NzE1ZjYyMDJhMzZmZmYwNQ==
5
+ data.tar.gz: !binary |-
6
+ OTk5OGFmZWM2NTNmMmUzNGQxNDE4NjgyZTlkMWUwNWQ4MWMzZGYxNw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NmY0ZGQyMTZjNzk2N2E5NzQ1M2I5MTUyNzBhZDhiYWQwYjE3ZGM4ZDhlZTBj
10
+ ODY5MjJhNzVmZGFjZTE1Yzk2YjZjZGM1ZTlkZmZlNzY1ZWJhMjY2NWM4NjI0
11
+ OWYzNTBkMTE4ZDNlOTU2MThlNzAwNzk2MmEyNWY4ZWEzNDFjMDM=
12
+ data.tar.gz: !binary |-
13
+ ZjNlZTYxMTQ1ZGM4YjdjODcyNTdkNTkxMDhiZTJkYjA5YmMxOWJkZGVmNzFh
14
+ MjkwODNkNTBhMjY2NTg5MGI1OGVhMzBlZmJjZWEwYTQxODI0ZjYwOWVmYWI2
15
+ YWVjZjk2MDFiMjZhNmNlMTc1MDY3MTViMWU5MGYxOTkwOWYyOWQ=
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .idea
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in xmlenc.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Benoist
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,29 @@
1
+ # Xmlenc
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'xmlenc'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install xmlenc
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ require 'xmlenc/version'
2
+ require 'openssl'
3
+ require 'base64'
4
+ require 'nokogiri'
5
+
6
+ module Xmlenc
7
+ NAMESPACES = {
8
+ xenc: 'http://www.w3.org/2001/04/xmlenc#',
9
+ ds: 'http://www.w3.org/2000/09/xmldsig#'
10
+ }
11
+
12
+ class UnsupportedError < StandardError
13
+ end
14
+
15
+ module Algorithms
16
+ autoload :Rsa15, 'xmlenc/algorithms/rsa_15'
17
+ autoload :RsaOaepMgf1p, 'xmlenc/algorithms/rsa_oaep_mgf1p'
18
+ autoload :DES3CBC, 'xmlenc/algorithms/des3_cbc'
19
+ autoload :AESCBC, 'xmlenc/algorithms/aes_cbc'
20
+ end
21
+
22
+ autoload :EncryptedDocument, 'xmlenc/encrypted_document'
23
+ autoload :EncryptedData, 'xmlenc/encrypted_data'
24
+ autoload :EncryptedKey, 'xmlenc/encrypted_key'
25
+ end
@@ -0,0 +1,38 @@
1
+ module Xmlenc
2
+ module Algorithms
3
+ class AESCBC
4
+ class << self
5
+ def [](size)
6
+ new(size)
7
+ end
8
+ end
9
+
10
+ def initialize(size)
11
+ @size = size
12
+ end
13
+
14
+ def setup(key)
15
+ @key = key
16
+ self
17
+ end
18
+
19
+ def decrypt(cipher_value, options = {})
20
+ cipher.decrypt
21
+ cipher.key = @key
22
+ cipher.iv = cipher_value[0...iv_len]
23
+ result = cipher.update(cipher_value[iv_len..-1])
24
+ result << cipher.final
25
+ end
26
+
27
+ private
28
+
29
+ def iv_len
30
+ cipher.iv_len
31
+ end
32
+
33
+ def cipher
34
+ @cipher ||= OpenSSL::Cipher::Cipher.new("aes-#{@size}-cbc")
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,31 @@
1
+ module Xmlenc
2
+ module Algorithms
3
+ class DES3CBC
4
+ def self.setup(key)
5
+ new(key)
6
+ end
7
+
8
+ def initialize(key)
9
+ @key = key
10
+ end
11
+
12
+ def decrypt(cipher_value, options = {})
13
+ cipher.decrypt
14
+ cipher.key = @key
15
+ cipher.iv = cipher_value[0...iv_len]
16
+ result = cipher.update(cipher_value[iv_len..-1])
17
+ result << cipher.final
18
+ end
19
+
20
+ private
21
+
22
+ def iv_len
23
+ cipher.iv_len
24
+ end
25
+
26
+ def cipher
27
+ @cipher ||= OpenSSL::Cipher::Cipher.new('des-ede3-cbc')
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,13 @@
1
+ module Xmlenc
2
+ module Algorithms
3
+ class Rsa15
4
+ def initialize(key)
5
+ @key = key
6
+ end
7
+
8
+ def decrypt(cipher_value, options = {})
9
+ @key.private_decrypt(cipher_value)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ module Xmlenc
2
+ module Algorithms
3
+ class RsaOaepMgf1p
4
+ DIGEST_METHODS = %w(http://www.w3.org/2000/09/xmldsig#sha1)
5
+
6
+ def initialize(key)
7
+ @key = key
8
+ end
9
+
10
+ def decrypt(cipher_value, options = {})
11
+ verify_algorithm(options[:node])
12
+ @key.private_decrypt(cipher_value, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
13
+ end
14
+
15
+ private
16
+
17
+ def verify_algorithm(node)
18
+ digest_method = node.at_xpath('./ds:DigestMethod', NAMESPACES)['Algorithm']
19
+ unless DIGEST_METHODS.include? digest_method
20
+ raise UnsupportedError.new("RSA OEAP MGF1P unsupported digest method #{digest_method}")
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,44 @@
1
+ module Xmlenc
2
+ class EncryptedData
3
+ ALGORITHMS = {
4
+ 'http://www.w3.org/2001/04/xmlenc#tripledes-cbc' => Algorithms::DES3CBC,
5
+ 'http://www.w3.org/2001/04/xmlenc#aes128-cbc' => Algorithms::AESCBC[128],
6
+ 'http://www.w3.org/2001/04/xmlenc#aes256-cbc' => Algorithms::AESCBC[256]
7
+ }
8
+
9
+ attr_accessor :node
10
+
11
+ def initialize(node)
12
+ @node = node
13
+ end
14
+
15
+ def document
16
+ @node.document
17
+ end
18
+
19
+ def encryption_method
20
+ at_xpath('./xenc:EncryptionMethod')
21
+ end
22
+
23
+ def cipher_value
24
+ at_xpath('./xenc:CipherData/xenc:CipherValue').content.gsub(/[\n\s]/, '')
25
+ end
26
+
27
+ def decrypt(key)
28
+ decryptor = algorithm.setup(key)
29
+ decryptor.decrypt(Base64.decode64(cipher_value), node: encryption_method)
30
+ end
31
+
32
+ private
33
+
34
+ def at_xpath(xpath)
35
+ @node.at_xpath(xpath, NAMESPACES)
36
+ end
37
+
38
+ def algorithm
39
+ algorithm = encryption_method['Algorithm']
40
+ ALGORITHMS[algorithm] ||
41
+ raise(UnsupportedError.new("Unsupported encryption method #{algorithm}"))
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,28 @@
1
+ module Xmlenc
2
+ class EncryptedDocument
3
+ attr_accessor :xml
4
+
5
+ def initialize(xml)
6
+ @xml = xml
7
+ end
8
+
9
+ def document
10
+ @document = Nokogiri::XML::Document.parse(xml)
11
+ end
12
+
13
+ def encrypted_keys
14
+ document.xpath('//xenc:EncryptedKey', NAMESPACES).collect { |n| EncryptedKey.new(n) }
15
+ end
16
+
17
+ def decrypt(key)
18
+ encrypted_keys.each do |encrypted_key|
19
+ encrypted_data = encrypted_key.encrypted_data
20
+
21
+ data_key = encrypted_key.decrypt(key)
22
+ decrypted_data = encrypted_data.decrypt(data_key)
23
+ encrypted_data.node.replace(decrypted_data)
24
+ end
25
+ @document.to_xml
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,53 @@
1
+ module Xmlenc
2
+ class EncryptedKey
3
+ ALGORITHMS = {
4
+ 'http://www.w3.org/2001/04/xmlenc#rsa-1_5' => Algorithms::Rsa15,
5
+ 'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' => Algorithms::RsaOaepMgf1p
6
+ }
7
+
8
+ def initialize(node)
9
+ @node = node
10
+ end
11
+
12
+ def document
13
+ @node.document
14
+ end
15
+
16
+ def encryption_method
17
+ at_xpath('./xenc:EncryptionMethod')
18
+ end
19
+
20
+ def encrypted_data
21
+ EncryptedData.new(referenced_node)
22
+ end
23
+
24
+ def cipher_value
25
+ at_xpath('./xenc:CipherData/xenc:CipherValue').content.gsub(/[\n\s]/, '')
26
+ end
27
+
28
+ def decrypt(key)
29
+ decryptor = algorithm.new(key)
30
+ decryptor.decrypt(Base64.decode64(cipher_value), node: encryption_method)
31
+ end
32
+
33
+ private
34
+
35
+ def referenced_node
36
+ document.at_xpath("//xenc:EncryptedData[@Id='#{reference_uri}']", NAMESPACES)
37
+ end
38
+
39
+ def reference_uri
40
+ at_xpath('./xenc:ReferenceList/xenc:DataReference')['URI'][1..-1]
41
+ end
42
+
43
+ def at_xpath(xpath)
44
+ @node.at_xpath(xpath, NAMESPACES)
45
+ end
46
+
47
+ def algorithm
48
+ algorithm = encryption_method['Algorithm']
49
+ ALGORITHMS[algorithm] ||
50
+ raise(UnsupportedError.new("Unsupported encryption method #{algorithm}"))
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,3 @@
1
+ module Xmlenc
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,61 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <PaymentInfo xmlns="http://example.org/paymentv2">
3
+ <Name>John Smith</Name>
4
+ <EncryptedData Id="ED" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns="http://www.w3.org/2001/04/xmlenc#">
5
+ <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
6
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
7
+ <EncryptedKey Id="EK" xmlns="http://www.w3.org/2001/04/xmlenc#">
8
+ <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
9
+ <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
10
+ <ds:KeyName>my-rsa-key</ds:KeyName>
11
+ <ds:X509Data>
12
+ <ds:X509Certificate>
13
+ MIIDzTCCArWgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBljELMAkGA1UEBhMCVVMx
14
+ CzAJBgNVBAgTAk5ZMRIwEAYDVQQHEwlNYW5oYXR0YW4xFTATBgNVBAoTDExhdmEg
15
+ U3VwcmVtZTEUMBIGA1UECxMLSGVhZCBPZmZpY2UxFDASBgNVBAMTC1JTQSBUZXN0
16
+ IENBMSMwIQYJKoZIhvcNAQkBFhR0ZWNoQGxhdmFzdXByZW1lLm9yZzAeFw0wMjAx
17
+ MzExNjI5NDNaFw00MzAyMjUxNjI5NDNaMIGWMQswCQYDVQQGEwJVUzELMAkGA1UE
18
+ CBMCTlkxEjAQBgNVBAcTCU1hbmhhdHRhbjEVMBMGA1UEChMMTGF2YSBTdXByZW1l
19
+ MRQwEgYDVQQLEwtIZWFkIE9mZmljZTEUMBIGA1UEAxMLUlNBIFRlc3QgQ0ExIzAh
20
+ BgkqhkiG9w0BCQEWFHRlY2hAbGF2YXN1cHJlbWUub3JnMIIBIjANBgkqhkiG9w0B
21
+ AQEFAAOCAQ8AMIIBCgKCAQEAgj3TOyUtgg99oEfsm8h9JTZBxUkzYkXVUOHxIwnk
22
+ Fwp4y9ZnrGja/j+kpRyKvYP5CkNdq0e58/r7GLXj45iqd03XjsFNTdjy4OIOgf7J
23
+ xMG7z+hEB1LT2swTs10GILFWPByRl3/BEsnekLZdoqNoJrvnttVkxgu3x80Ji3/A
24
+ ZD8Ub/kBGOSPyu6pn3OdnMTc5q4r1qUe985lQzCZvCMw6AoGeCyJodNu2MbveNeH
25
+ +YPjRgLCQfzvOFRq+9qMtE8XfUJZdNhPZhgdsOGf8uJauTcIHbAyw7BhxPy6RikW
26
+ W5yiWUmBya+7t4y1TQJzham/0y0zU3TAA7b/rDrU7xmNPwIDAQABoyQwIjAPBgNV
27
+ HRMBAf8EBTADAQH/MA8GA1UdDwEB/wQFAwMHBgAwDQYJKoZIhvcNAQEEBQADggEB
28
+ ADELWZjFLPjSjGeOaeUwH/mEOP+l/nTtxe07IWAQL4kvb4wsiUsM1EkPptcBQsym
29
+ OYgFhf3Elqma84bbOyp85y/iQnjpqWWJ73TFXSWZamSIhYb4Gk+dQuwFI+zD3B2y
30
+ WwqghaAHDzxtzROLUBjo+97Y6ng6V5zjmtdGOFwNXwWhf3Y+MjnErtBIKYao8NJO
31
+ p6di80w82+s6Ot+CLVvVobLhxS/y8yWplATRiQnI5ij/WTLML+tiU5aes0c9abaf
32
+ O7i9j1iTuZsDT3f96ia0RSLsXSGij737QKc3ZM8lSxBWfepWYO+G+IRgr1q9IUDa
33
+ kKO/vB9Ay64Rt88XbLnnGns=
34
+ </ds:X509Certificate>
35
+ </ds:X509Data>
36
+ </ds:KeyInfo>
37
+ <CipherData>
38
+ <CipherValue>
39
+ cCxxYh3xGBTqlXbhmKxWzNMlHeE28E7vPrMyM5V4T+t1Iy2csj1BoQ7cqBjEhqEy
40
+ Eot4WNRYsY7P44mWBKurj2mdWQWgoxHvtITP9AR3JTMxUo3TF5ltW76DLDsEvWlE
41
+ uZKam0PYj6lYPKd4npUULeZyR/rDRrth/wFIBD8vbQlUsBHapNT9MbQfSKZemOuT
42
+ UJL9PNgsosySpKrX564oQw398XsxfTFxi4hqbdqzA/CLL418X01hUjIHdyv6XnA2
43
+ 98Bmfv9WMPpX05udR4raDv5X8NWxjH00hAhasM3qumxoyCT6mAGfqvE23I+OXtrN
44
+ lUvE9mMjANw4zweCHsOcfw==
45
+ </CipherValue>
46
+ </CipherData>
47
+ <ReferenceList>
48
+ <DataReference URI="#ED"/>
49
+ </ReferenceList>
50
+ </EncryptedKey>
51
+ </ds:KeyInfo>
52
+ <CipherData>
53
+ <CipherValue>
54
+ u2vogkwlvFqeknJ0lYTBZkWS/eX8LR1fDPFMfyK1/UY0EyZfHvbONfDHcC/HLv/f
55
+ aAOOO2Y0GqsknP0LYT1OznkiJrzx134cmJCgbyrYXd3Mp21Pq3rs66JJ34Qt3/+I
56
+ EyJBUSMT8TdT3fBD44BtOqH2op/hy2g3hQPFZul4GiHBEnNJL/4nU1yad3bMvtAB
57
+ mzhx80lJvPGLcruj5V77WMvkvZfoeEqMq4qPWK02ZURsJsq0iZcJDi39NB7OCiON
58
+ </CipherValue>
59
+ </CipherData>
60
+ </EncryptedData>
61
+ </PaymentInfo>
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEogIBAAKCAQEAgj3TOyUtgg99oEfsm8h9JTZBxUkzYkXVUOHxIwnkFwp4y9Zn
3
+ rGja/j+kpRyKvYP5CkNdq0e58/r7GLXj45iqd03XjsFNTdjy4OIOgf7JxMG7z+hE
4
+ B1LT2swTs10GILFWPByRl3/BEsnekLZdoqNoJrvnttVkxgu3x80Ji3/AZD8Ub/kB
5
+ GOSPyu6pn3OdnMTc5q4r1qUe985lQzCZvCMw6AoGeCyJodNu2MbveNeH+YPjRgLC
6
+ QfzvOFRq+9qMtE8XfUJZdNhPZhgdsOGf8uJauTcIHbAyw7BhxPy6RikWW5yiWUmB
7
+ ya+7t4y1TQJzham/0y0zU3TAA7b/rDrU7xmNPwIDAQABAoIBAFK+PIiC4hqTBNjj
8
+ WOrPwNH3WmmgS8jPXOp54NzF1+bbfErj+BGMvDRy8oMDUxF72qgujD/Y3canWQcl
9
+ 55Yc04/gIGZNYHNotUUx2M21tTIPcuZvRWjxsi57ILj/DHmQsJyX+dcqDtuE7KU7
10
+ dtlwvyZ8koWRpOg9YZDKLpo1m2ET0RjyNEm9fvt6m3ZwSawA9Yu0xSVvVIukNIl7
11
+ eimQzBYeGQwGwhMgMoybQWjwIOpnbvcRfT/iAh9n/AyXcjtOMGwWhifjel+U1XMM
12
+ hrcL3mA5xb+gGQpZ7TToTfmOEJeVCh9BRKpgniH4JVClhiTOeN4VTLZYg/BGmGTj
13
+ rEZKX4ECgYEAigDXtsEns9+QVsQKYolI/GE0Edkd1OkyGw11N3YIMNNzOotcDKoU
14
+ 0/Jt1hI7NaWRgi9/LyphmEM/dBaNnrNW6GPIETSjUQ9FuK2LywkNUiM2D+UFsLlq
15
+ EJ4S50/7kdXOC3t9rm9tiIPyqwJKNxRmyAAKfiRbYiEtqqR5zdGXcBECgYEA8ZoG
16
+ xTcXI7pqmkWcI87siHhth1jFCGv3EMwAeIy4tk4HBkxjZoBy/hU2mxviYPhuFEPj
17
+ JTKEbiQRebVLwaTJxs543deGQ1shdVHT1005wyGyhuIVXYC56Xhu+8B2y32650/X
18
+ wRTSUXxP/eQ+Qb2MeDPZ0XgpHhU74Za4F812eE8CgYABNwqvKDoyQjiiGu3Aelbz
19
+ KePseE3j7v2q8U5j450k2Oe9zzZLQkAWsZ638McmrMOAMuzavHPJhGYNnpk2mXud
20
+ Zit/w0fg0dKaUqTVb8n3PCogr7KCIM/HP60I7lJXsVs0DK1JmN+NASRkzwtaOsrA
21
+ 3gc5nxZS4dnmE7ai0kKUEQKBgEfA/xHDctPhoZd/5QedhRJi8eSosJv3tMEAVYN4
22
+ B8PdGKj+NudSbtSXaEhY17sFDWxnXSbHAh3UCHylI4K3dlXdLHh2ciG/BwjY7Jmd
23
+ DfKuJ1939fB3Mr/sTMnoN1/oT4IzbFij3nLlALze9L6BlR5+B8r2bP/KPqaZJMOs
24
+ +epxAoGAdV6yhdRcUrSBg6e8Q2f1or7LeYzi6xWjf1RRjqPOgf6VB/xiMmF6RnZK
25
+ uRUzK9ieRnAhtDFJTS1nPbfVLPSsASzxAaGQGdZ3AsHD4jp03jCyKtBaPKdDzeVr
26
+ rrIYPcyZ4OBeoFWUvzlDEtEcqJc3ONwpNWal7nhKEbb/AjqFmpg=
27
+ -----END RSA PRIVATE KEY-----