xml-kit 0.1.11 → 0.1.12
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/.gitlab-ci.yml +5 -5
- data/.rubocop.yml +94 -0
- data/.rubocop_todo.yml +22 -0
- data/.travis.yml +3 -2
- data/Gemfile +4 -2
- data/Rakefile +10 -3
- data/bin/cibuild +21 -0
- data/bin/console +4 -3
- data/bin/lint +11 -0
- data/bin/setup +0 -2
- data/bin/test +17 -0
- data/lib/xml-kit.rb +3 -0
- data/lib/xml/kit.rb +30 -30
- data/lib/xml/kit/certificate.rb +14 -7
- data/lib/xml/kit/crypto.rb +3 -1
- data/lib/xml/kit/crypto/oaep_cipher.rb +4 -2
- data/lib/xml/kit/crypto/rsa_cipher.rb +4 -2
- data/lib/xml/kit/crypto/symmetric_cipher.rb +10 -8
- data/lib/xml/kit/crypto/unknown_cipher.rb +4 -3
- data/lib/xml/kit/decryption.rb +12 -10
- data/lib/xml/kit/decryption_error.rb +3 -1
- data/lib/xml/kit/document.rb +6 -12
- data/lib/xml/kit/encryption.rb +4 -2
- data/lib/xml/kit/fingerprint.rb +4 -2
- data/lib/xml/kit/id.rb +2 -0
- data/lib/xml/kit/key_pair.rb +2 -0
- data/lib/xml/kit/namespaces.rb +14 -12
- data/lib/xml/kit/self_signed_certificate.rb +4 -2
- data/lib/xml/kit/signature.rb +12 -10
- data/lib/xml/kit/signatures.rb +3 -1
- data/lib/xml/kit/templatable.rb +11 -1
- data/lib/xml/kit/template.rb +4 -2
- data/lib/xml/kit/templates/certificate.builder +3 -1
- data/lib/xml/kit/templates/encryption.builder +2 -0
- data/lib/xml/kit/templates/signature.builder +5 -3
- data/lib/xml/kit/version.rb +3 -1
- data/xml-kit.gemspec +29 -24
- metadata +53 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a3ce34db33309cbe5b6afe5bd7ed352bfca890ba176151136ab9c8223b27090
|
4
|
+
data.tar.gz: f4c89d59e1329584df15437a7b39210a7bff471c0a59edfb1cd07b4bde1a7a53
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3866cc2e2bbc1fe2349a1d3cd8c7a2977029d46f0afa67f7f8113439a2031ad38dc409fdf22ba0a8e2093dcc07f625c0bd9dcb3e018eaaeaad159c82d5540732
|
7
|
+
data.tar.gz: 594bae158f8ac34f12629b4feb9e38c7a890ec515c6211663d94b9adb2ee532cedd6dd79a0b1084628730da6b89465353582551281b6074835e0a5d62136151c
|
data/.gitlab-ci.yml
CHANGED
@@ -5,11 +5,11 @@ before_script:
|
|
5
5
|
- echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
|
6
6
|
- locale-gen
|
7
7
|
- export LC_ALL=en_US.UTF-8
|
8
|
-
- ruby -v
|
9
|
-
- which ruby
|
10
|
-
- gem install bundler --no-ri --no-rdoc
|
11
|
-
- bundle install --jobs $(nproc) "${FLAGS[@]}"
|
12
8
|
|
13
9
|
rspec:
|
14
10
|
script:
|
15
|
-
-
|
11
|
+
- bin/cibuild
|
12
|
+
|
13
|
+
lint:
|
14
|
+
script:
|
15
|
+
- bin/lint
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
inherit_from: .rubocop_todo.yml
|
2
|
+
|
3
|
+
require:
|
4
|
+
- rubocop/cop/internal_affairs
|
5
|
+
- rubocop-rspec
|
6
|
+
|
7
|
+
AllCops:
|
8
|
+
Exclude:
|
9
|
+
- 'coverage/**/*'
|
10
|
+
- 'pkg/**/*'
|
11
|
+
- 'spec/fixtures/**/*'
|
12
|
+
- 'tmp/**/*'
|
13
|
+
- 'vendor/**/*'
|
14
|
+
TargetRubyVersion: 2.2
|
15
|
+
|
16
|
+
Layout/ClassStructure:
|
17
|
+
Enabled: true
|
18
|
+
Categories:
|
19
|
+
module_inclusion:
|
20
|
+
- include
|
21
|
+
- prepend
|
22
|
+
- extend
|
23
|
+
ExpectedOrder:
|
24
|
+
- module_inclusion
|
25
|
+
- constants
|
26
|
+
- public_class_methods
|
27
|
+
- initializer
|
28
|
+
- instance_methods
|
29
|
+
- protected_methods
|
30
|
+
- private_methods
|
31
|
+
|
32
|
+
Layout/EndOfLine:
|
33
|
+
EnforcedStyle: lf
|
34
|
+
|
35
|
+
Layout/IndentArray:
|
36
|
+
EnforcedStyle: consistent
|
37
|
+
|
38
|
+
Layout/IndentHeredoc:
|
39
|
+
EnforcedStyle: active_support
|
40
|
+
|
41
|
+
Lint/AmbiguousBlockAssociation:
|
42
|
+
Exclude:
|
43
|
+
- 'spec/**/*.rb'
|
44
|
+
|
45
|
+
Lint/InterpolationCheck:
|
46
|
+
Exclude:
|
47
|
+
- 'spec/**/*.rb'
|
48
|
+
|
49
|
+
Metrics/BlockLength:
|
50
|
+
Exclude:
|
51
|
+
- '**/**/*.builder'
|
52
|
+
- '**/*.rake'
|
53
|
+
- '*.gemspec'
|
54
|
+
- 'Rakefile'
|
55
|
+
- 'spec/**/*.rb'
|
56
|
+
|
57
|
+
Metrics/ModuleLength:
|
58
|
+
Exclude:
|
59
|
+
- 'spec/**/*.rb'
|
60
|
+
|
61
|
+
Metrics/LineLength:
|
62
|
+
Exclude:
|
63
|
+
- 'spec/**/*.rb'
|
64
|
+
|
65
|
+
Naming/FileName:
|
66
|
+
Exclude:
|
67
|
+
- 'lib/xml-kit.rb'
|
68
|
+
|
69
|
+
Style/Documentation:
|
70
|
+
Enabled: false
|
71
|
+
|
72
|
+
Style/EachWithObject:
|
73
|
+
Enabled: false
|
74
|
+
|
75
|
+
Style/StringLiterals:
|
76
|
+
EnforcedStyle: 'single_quotes'
|
77
|
+
|
78
|
+
Style/TrailingCommaInLiteral:
|
79
|
+
Enabled: false
|
80
|
+
|
81
|
+
RSpec/ExampleLength:
|
82
|
+
Max: 80
|
83
|
+
|
84
|
+
RSpec/MultipleExpectations:
|
85
|
+
Enabled: false
|
86
|
+
|
87
|
+
RSpec/NamedSubject:
|
88
|
+
Enabled: false
|
89
|
+
|
90
|
+
RSpec/NestedGroups:
|
91
|
+
Max: 7
|
92
|
+
|
93
|
+
RSpec/SubjectStub:
|
94
|
+
Enabled: false
|
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2018-03-03 11:50:08 -0700 using RuboCop version 0.52.1.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 2
|
10
|
+
Metrics/AbcSize:
|
11
|
+
Max: 18
|
12
|
+
|
13
|
+
# Offense count: 1
|
14
|
+
Style/DoubleNegation:
|
15
|
+
Exclude:
|
16
|
+
- 'lib/xml/kit/certificate.rb'
|
17
|
+
|
18
|
+
# Offense count: 29
|
19
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, IgnoredPatterns.
|
20
|
+
# URISchemes: http, https
|
21
|
+
Metrics/LineLength:
|
22
|
+
Max: 141
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
source 'https://rubygems.org'
|
4
|
+
|
5
|
+
git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
|
4
6
|
|
5
7
|
# Specify your gem's dependencies in xml-kit.gemspec
|
6
8
|
gemspec
|
data/Rakefile
CHANGED
@@ -1,6 +1,13 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/audit/task'
|
4
|
+
require 'bundler/gem_tasks'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
require 'rubocop/rake_task'
|
3
7
|
|
4
8
|
RSpec::Core::RakeTask.new(:spec)
|
9
|
+
RuboCop::RakeTask.new(:rubocop)
|
10
|
+
Bundler::Audit::Task.new
|
5
11
|
|
6
|
-
task :
|
12
|
+
task default: :spec
|
13
|
+
task lint: [:rubocop, 'bundle:audit']
|
data/bin/cibuild
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# script/cibuild: Setup environment for CI to run tests. This is primarily
|
4
|
+
# designed to run on the continuous integration server.
|
5
|
+
|
6
|
+
set -e
|
7
|
+
|
8
|
+
cd "$(dirname "$0")/.."
|
9
|
+
|
10
|
+
echo [$(date "+%H:%M:%S")] "==> Started at…"
|
11
|
+
|
12
|
+
# GC customizations
|
13
|
+
export RUBY_GC_MALLOC_LIMIT=79000000
|
14
|
+
export RUBY_GC_HEAP_INIT_SLOTS=800000
|
15
|
+
export RUBY_HEAP_FREE_MIN=100000
|
16
|
+
export RUBY_HEAP_SLOTS_INCREMENT=400000
|
17
|
+
export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
|
18
|
+
|
19
|
+
ruby -v
|
20
|
+
gem install bundler --no-ri --no-rdoc --conservative
|
21
|
+
bin/test
|
data/bin/console
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
-
require
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'xml/kit'
|
5
6
|
|
6
7
|
# You can add fixtures and/or initialization code here to make experimenting
|
7
8
|
# with your gem easier. You can also use a different console, if you like.
|
@@ -10,5 +11,5 @@ require "xml/kit"
|
|
10
11
|
# require "pry"
|
11
12
|
# Pry.start
|
12
13
|
|
13
|
-
require
|
14
|
+
require 'irb'
|
14
15
|
IRB.start(__FILE__)
|
data/bin/lint
ADDED
data/bin/setup
CHANGED
data/bin/test
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/bin/sh
|
2
|
+
|
3
|
+
# script/test: Run test suite for application. Optionally pass in a path to an
|
4
|
+
# individual test file to run a single test.
|
5
|
+
|
6
|
+
|
7
|
+
set -e
|
8
|
+
|
9
|
+
cd "$(dirname "$0")/.."
|
10
|
+
|
11
|
+
[ -z "$DEBUG" ] || set -x
|
12
|
+
|
13
|
+
echo [$(date "+%H:%M:%S")] "==> Running setup…"
|
14
|
+
bin/setup
|
15
|
+
|
16
|
+
echo [$(date "+%H:%M:%S")] "==> Running tests…"
|
17
|
+
bundle exec rake spec
|
data/lib/xml-kit.rb
ADDED
data/lib/xml/kit.rb
CHANGED
@@ -1,32 +1,34 @@
|
|
1
|
-
|
2
|
-
require "active_support/core_ext/numeric/time"
|
3
|
-
require "active_support/deprecation"
|
4
|
-
require "base64"
|
5
|
-
require "builder"
|
6
|
-
require "logger"
|
7
|
-
require "nokogiri"
|
8
|
-
require "openssl"
|
9
|
-
require "pathname"
|
10
|
-
require "tilt"
|
11
|
-
require "xmldsig"
|
1
|
+
# frozen_string_literal: true
|
12
2
|
|
13
|
-
require
|
3
|
+
require 'active_model'
|
4
|
+
require 'active_support/core_ext/numeric/time'
|
5
|
+
require 'active_support/deprecation'
|
6
|
+
require 'base64'
|
7
|
+
require 'builder'
|
8
|
+
require 'logger'
|
9
|
+
require 'nokogiri'
|
10
|
+
require 'openssl'
|
11
|
+
require 'pathname'
|
12
|
+
require 'tilt'
|
13
|
+
require 'xmldsig'
|
14
14
|
|
15
|
-
require
|
16
|
-
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
20
|
-
require
|
21
|
-
require
|
22
|
-
require
|
23
|
-
require
|
24
|
-
require
|
25
|
-
require
|
26
|
-
require
|
27
|
-
require
|
28
|
-
require
|
29
|
-
require
|
15
|
+
require 'xml/kit/namespaces'
|
16
|
+
|
17
|
+
require 'xml/kit/certificate'
|
18
|
+
require 'xml/kit/crypto'
|
19
|
+
require 'xml/kit/decryption'
|
20
|
+
require 'xml/kit/decryption_error'
|
21
|
+
require 'xml/kit/document'
|
22
|
+
require 'xml/kit/encryption'
|
23
|
+
require 'xml/kit/fingerprint'
|
24
|
+
require 'xml/kit/id'
|
25
|
+
require 'xml/kit/key_pair'
|
26
|
+
require 'xml/kit/self_signed_certificate'
|
27
|
+
require 'xml/kit/signature'
|
28
|
+
require 'xml/kit/signatures'
|
29
|
+
require 'xml/kit/templatable'
|
30
|
+
require 'xml/kit/template'
|
31
|
+
require 'xml/kit/version'
|
30
32
|
|
31
33
|
module Xml
|
32
34
|
module Kit
|
@@ -35,9 +37,7 @@ module Xml
|
|
35
37
|
@logger ||= Logger.new(STDOUT)
|
36
38
|
end
|
37
39
|
|
38
|
-
|
39
|
-
@logger = logger
|
40
|
-
end
|
40
|
+
attr_writer :logger
|
41
41
|
|
42
42
|
def deprecate(message)
|
43
43
|
@deprecation ||= ActiveSupport::Deprecation.new('1.0.0', 'xml-kit')
|
data/lib/xml/kit/certificate.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
# {include:file:spec/xml/certificate_spec.rb}
|
4
6
|
class Certificate
|
5
7
|
BASE64_FORMAT = %r(\A([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?\Z)
|
6
|
-
BEGIN_CERT
|
7
|
-
END_CERT
|
8
|
+
BEGIN_CERT = /-----BEGIN CERTIFICATE-----/
|
9
|
+
END_CERT = /-----END CERTIFICATE-----/
|
8
10
|
# The use can be `:signing` or `:encryption`. Use `nil` for both.
|
9
11
|
attr_reader :use
|
10
12
|
|
@@ -59,7 +61,7 @@ module Xml
|
|
59
61
|
end
|
60
62
|
|
61
63
|
def ==(other)
|
62
|
-
|
64
|
+
fingerprint == other.fingerprint
|
63
65
|
end
|
64
66
|
|
65
67
|
def eql?(other)
|
@@ -106,6 +108,11 @@ module Xml
|
|
106
108
|
x509.not_before
|
107
109
|
end
|
108
110
|
|
111
|
+
def to_xml(pretty: false, xml: ::Builder::XmlMarkup.new)
|
112
|
+
xml = ::Xml::Kit::Template.new(self).to_xml(xml: xml)
|
113
|
+
pretty ? Nokogiri::XML(xml).to_xml(indent: 2) : xml
|
114
|
+
end
|
115
|
+
|
109
116
|
class << self
|
110
117
|
def to_x509(value)
|
111
118
|
return value if value.is_a?(OpenSSL::X509::Certificate)
|
@@ -122,10 +129,10 @@ module Xml
|
|
122
129
|
end
|
123
130
|
|
124
131
|
def strip(value)
|
125
|
-
value
|
126
|
-
gsub(BEGIN_CERT, '')
|
127
|
-
gsub(END_CERT, '')
|
128
|
-
gsub(/[\r\n]|\\r|\\n|\s/,
|
132
|
+
value
|
133
|
+
.gsub(BEGIN_CERT, '')
|
134
|
+
.gsub(END_CERT, '')
|
135
|
+
.gsub(/[\r\n]|\\r|\\n|\s/, '')
|
129
136
|
end
|
130
137
|
end
|
131
138
|
end
|
data/lib/xml/kit/crypto.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'xml/kit/crypto/oaep_cipher'
|
2
4
|
require 'xml/kit/crypto/rsa_cipher'
|
3
5
|
require 'xml/kit/crypto/symmetric_cipher'
|
@@ -6,7 +8,7 @@ require 'xml/kit/crypto/unknown_cipher'
|
|
6
8
|
module Xml
|
7
9
|
module Kit
|
8
10
|
module Crypto
|
9
|
-
CIPHERS = [
|
11
|
+
CIPHERS = [SymmetricCipher, RsaCipher, OaepCipher, UnknownCipher].freeze
|
10
12
|
|
11
13
|
# @!visibility private
|
12
14
|
def self.cipher_for(algorithm, key)
|
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
module Crypto
|
4
6
|
class OaepCipher
|
5
7
|
ALGORITHMS = {
|
6
8
|
'http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' => true,
|
7
|
-
}
|
8
|
-
def initialize(
|
9
|
+
}.freeze
|
10
|
+
def initialize(_algorithm, key)
|
9
11
|
@key = key
|
10
12
|
end
|
11
13
|
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
module Crypto
|
4
6
|
class RsaCipher
|
5
|
-
ALGORITHM = "#{::Xml::Kit::Namespaces::XMLENC}rsa-1_5"
|
7
|
+
ALGORITHM = "#{::Xml::Kit::Namespaces::XMLENC}rsa-1_5".freeze
|
6
8
|
|
7
|
-
def initialize(
|
9
|
+
def initialize(_algorithm, key)
|
8
10
|
@key = key
|
9
11
|
end
|
10
12
|
|
@@ -1,14 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
module Crypto
|
4
6
|
class SymmetricCipher
|
5
|
-
DEFAULT_ALGORITHM="#{::Xml::Kit::Namespaces::XMLENC}aes256-cbc"
|
7
|
+
DEFAULT_ALGORITHM = "#{::Xml::Kit::Namespaces::XMLENC}aes256-cbc".freeze
|
6
8
|
ALGORITHMS = {
|
7
|
-
"#{::Xml::Kit::Namespaces::XMLENC}tripledes-cbc" =>
|
8
|
-
"#{::Xml::Kit::Namespaces::XMLENC}aes128-cbc" =>
|
9
|
-
"#{::Xml::Kit::Namespaces::XMLENC}aes192-cbc" =>
|
10
|
-
"#{::Xml::Kit::Namespaces::XMLENC}aes256-cbc" =>
|
11
|
-
}
|
9
|
+
"#{::Xml::Kit::Namespaces::XMLENC}tripledes-cbc" => 'DES-EDE3-CBC',
|
10
|
+
"#{::Xml::Kit::Namespaces::XMLENC}aes128-cbc" => 'AES-128-CBC',
|
11
|
+
"#{::Xml::Kit::Namespaces::XMLENC}aes192-cbc" => 'AES-192-CBC',
|
12
|
+
"#{::Xml::Kit::Namespaces::XMLENC}aes256-cbc" => 'AES-256-CBC',
|
13
|
+
}.freeze
|
12
14
|
|
13
15
|
attr_reader :key
|
14
16
|
|
@@ -29,9 +31,9 @@ module Xml
|
|
29
31
|
|
30
32
|
def decrypt(cipher_text)
|
31
33
|
cipher.decrypt
|
32
|
-
iv = cipher_text[0..cipher.iv_len-1]
|
34
|
+
iv = cipher_text[0..cipher.iv_len - 1]
|
33
35
|
data = cipher_text[cipher.iv_len..-1]
|
34
|
-
#cipher.padding = 0
|
36
|
+
# cipher.padding = 0
|
35
37
|
cipher.key = @key
|
36
38
|
cipher.iv = iv
|
37
39
|
cipher.update(data) + cipher.final
|
@@ -1,11 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
module Crypto
|
4
6
|
class UnknownCipher
|
5
|
-
def initialize(algorithm, key)
|
6
|
-
end
|
7
|
+
def initialize(algorithm, key); end
|
7
8
|
|
8
|
-
def self.matches?(
|
9
|
+
def self.matches?(_algorithm)
|
9
10
|
true
|
10
11
|
end
|
11
12
|
|
data/lib/xml/kit/decryption.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
# {include:file:spec/saml/xml_decryption_spec.rb}
|
@@ -13,7 +15,7 @@ module Xml
|
|
13
15
|
#
|
14
16
|
# @param data [Hash] the XML document converted to a [Hash] using Hash.from_xml.
|
15
17
|
def decrypt(data)
|
16
|
-
::Xml::Kit.deprecate(
|
18
|
+
::Xml::Kit.deprecate('decrypt is deprecated. Use decrypt_xml or decrypt_hash instead.')
|
17
19
|
decrypt_hash(data)
|
18
20
|
end
|
19
21
|
|
@@ -30,34 +32,34 @@ module Xml
|
|
30
32
|
def decrypt_hash(hash)
|
31
33
|
encrypted_data = hash['EncryptedData']
|
32
34
|
symmetric_key = symmetric_key_from(encrypted_data)
|
33
|
-
|
34
|
-
|
35
|
+
cipher_value = encrypted_data['CipherData']['CipherValue']
|
36
|
+
cipher_text = Base64.decode64(cipher_value)
|
37
|
+
algorithm = encrypted_data['EncryptionMethod']['Algorithm']
|
38
|
+
to_plaintext(cipher_text, symmetric_key, algorithm)
|
35
39
|
end
|
36
40
|
|
37
41
|
# Decrypts an EncryptedData Nokogiri::XML::Element.
|
38
42
|
#
|
39
43
|
# @param node [Nokogiri::XML::Element.] the XML node to decrypt.
|
40
44
|
def decrypt_node(node)
|
41
|
-
return node unless !node.nil? &&
|
45
|
+
return node unless !node.nil? && node.name == 'EncryptedData'
|
42
46
|
|
43
47
|
node.parent.replace(decrypt_xml(node.to_s))[0]
|
44
48
|
end
|
45
49
|
|
46
50
|
private
|
47
51
|
|
48
|
-
def symmetric_key_from(encrypted_data)
|
49
|
-
|
50
|
-
cipher_text = Base64.decode64(encrypted_key['CipherData']['CipherValue'])
|
51
|
-
attempts = private_keys.count
|
52
|
+
def symmetric_key_from(encrypted_data, attempts = private_keys.count)
|
53
|
+
cipher_text = Base64.decode64(encrypted_data['KeyInfo']['EncryptedKey']['CipherData']['CipherValue'])
|
52
54
|
private_keys.each do |private_key|
|
53
55
|
begin
|
54
56
|
attempts -= 1
|
55
|
-
return to_plaintext(cipher_text, private_key,
|
57
|
+
return to_plaintext(cipher_text, private_key, encrypted_data['KeyInfo']['EncryptedKey']['EncryptionMethod']['Algorithm'])
|
56
58
|
rescue OpenSSL::PKey::RSAError
|
57
59
|
raise if attempts.zero?
|
58
60
|
end
|
59
61
|
end
|
60
|
-
raise DecryptionError
|
62
|
+
raise DecryptionError, private_keys
|
61
63
|
end
|
62
64
|
|
63
65
|
def to_plaintext(cipher_text, symmetric_key, algorithm)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
class DecryptionError < StandardError
|
@@ -5,7 +7,7 @@ module Xml
|
|
5
7
|
|
6
8
|
def initialize(private_keys)
|
7
9
|
@private_keys = private_keys
|
8
|
-
super(
|
10
|
+
super('Cannot decrypt document with the provided private keys')
|
9
11
|
end
|
10
12
|
end
|
11
13
|
end
|
data/lib/xml/kit/document.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
# {include:file:spec/saml/xml_spec.rb}
|
@@ -41,7 +43,7 @@ module Xml
|
|
41
43
|
|
42
44
|
def validate_signatures
|
43
45
|
invalid_signatures.flat_map(&:errors).uniq.each do |error|
|
44
|
-
errors.add(error,
|
46
|
+
errors.add(error, 'is invalid')
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
@@ -58,22 +60,14 @@ module Xml
|
|
58
60
|
return if find_by('//ds:Signature').nil?
|
59
61
|
|
60
62
|
x509_certificates.each do |certificate|
|
61
|
-
|
62
|
-
if inactive
|
63
|
-
error_message = "Not valid before #{certificate.not_before}"
|
64
|
-
errors.add(:certificate, error_message)
|
65
|
-
end
|
63
|
+
errors.add(:certificate, "Not valid before #{certificate.not_before}") if now < certificate.not_before
|
66
64
|
|
67
|
-
|
68
|
-
if expired
|
69
|
-
error_message = "Not valid after #{certificate.not_after}"
|
70
|
-
errors.add(:certificate, error_message)
|
71
|
-
end
|
65
|
+
errors.add(:certificate, "Not valid after #{certificate.not_after}") if now > certificate.not_after
|
72
66
|
end
|
73
67
|
end
|
74
68
|
|
75
69
|
def x509_certificates
|
76
|
-
find_all(
|
70
|
+
find_all('//ds:KeyInfo/ds:X509Data/ds:X509Certificate').map do |item|
|
77
71
|
Certificate.to_x509(item.text)
|
78
72
|
end
|
79
73
|
end
|
data/lib/xml/kit/encryption.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
class Encryption
|
@@ -13,10 +15,10 @@ module Xml
|
|
13
15
|
asymmetric_algorithm: ::Xml::Kit::Crypto::RsaCipher::ALGORITHM
|
14
16
|
)
|
15
17
|
@symmetric_algorithm = symmetric_algorithm
|
16
|
-
@symmetric_cipher_value = Base64.encode64(symmetric_cipher.encrypt(raw_xml)).
|
18
|
+
@symmetric_cipher_value = Base64.encode64(symmetric_cipher.encrypt(raw_xml)).delete("\n")
|
17
19
|
|
18
20
|
@asymmetric_algorithm = asymmetric_algorithm
|
19
|
-
@asymmetric_cipher_value = Base64.encode64(public_key.public_encrypt(symmetric_cipher.key)).
|
21
|
+
@asymmetric_cipher_value = Base64.encode64(public_key.public_encrypt(symmetric_cipher.key)).delete("\n")
|
20
22
|
end
|
21
23
|
|
22
24
|
def to_xml(xml: ::Builder::XmlMarkup.new)
|
data/lib/xml/kit/fingerprint.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
# This generates a fingerprint for an X509 Certificate.
|
@@ -25,7 +27,7 @@ module Xml
|
|
25
27
|
end
|
26
28
|
|
27
29
|
def ==(other)
|
28
|
-
|
30
|
+
to_s == other.to_s
|
29
31
|
end
|
30
32
|
|
31
33
|
def eql?(other)
|
@@ -43,7 +45,7 @@ module Xml
|
|
43
45
|
private
|
44
46
|
|
45
47
|
def pretty_fingerprint(fingerprint)
|
46
|
-
fingerprint.upcase.scan(/../).join(
|
48
|
+
fingerprint.upcase.scan(/../).join(':')
|
47
49
|
end
|
48
50
|
end
|
49
51
|
end
|
data/lib/xml/kit/id.rb
CHANGED
data/lib/xml/kit/key_pair.rb
CHANGED
data/lib/xml/kit/namespaces.rb
CHANGED
@@ -1,18 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
module Namespaces
|
4
|
-
CANONICALIZATION =
|
5
|
-
ENVELOPED_SIG =
|
6
|
-
RSA_SHA1 =
|
7
|
-
RSA_SHA256 =
|
8
|
-
RSA_SHA384 =
|
9
|
-
RSA_SHA512 =
|
10
|
-
SHA1 =
|
11
|
-
SHA256 = 'http://www.w3.org/2001/04/xmlenc#sha256'
|
12
|
-
SHA384 =
|
13
|
-
SHA512 = 'http://www.w3.org/2001/04/xmlenc#sha512'
|
14
|
-
XMLDSIG =
|
15
|
-
XMLENC =
|
6
|
+
CANONICALIZATION = 'http://www.w3.org/2001/10/xml-exc-c14n#'.freeze
|
7
|
+
ENVELOPED_SIG = 'http://www.w3.org/2000/09/xmldsig#enveloped-signature'.freeze
|
8
|
+
RSA_SHA1 = 'http://www.w3.org/2000/09/xmldsig#rsa-sha1'.freeze
|
9
|
+
RSA_SHA256 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'.freeze
|
10
|
+
RSA_SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384'.freeze
|
11
|
+
RSA_SHA512 = 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512'.freeze
|
12
|
+
SHA1 = 'http://www.w3.org/2000/09/xmldsig#sha1'.freeze
|
13
|
+
SHA256 = 'http://www.w3.org/2001/04/xmlenc#sha256'.freeze
|
14
|
+
SHA384 = 'http://www.w3.org/2001/04/xmldsig-more#sha384'.freeze
|
15
|
+
SHA512 = 'http://www.w3.org/2001/04/xmlenc#sha512'.freeze
|
16
|
+
XMLDSIG = 'http://www.w3.org/2000/09/xmldsig#'.freeze
|
17
|
+
XMLENC = 'http://www.w3.org/2001/04/xmlenc#'.freeze
|
16
18
|
end
|
17
19
|
end
|
18
20
|
end
|
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
class SelfSignedCertificate
|
4
|
-
SUBJECT=
|
6
|
+
SUBJECT = '/C=CA/ST=AB/L=Calgary/O=XmlKit/OU=XmlKit/CN=XmlKit'.freeze
|
5
7
|
|
6
8
|
def create(algorithm: 'AES-256-CBC', passphrase: nil, key_pair: OpenSSL::PKey::RSA.new(2048))
|
7
9
|
certificate = certificate_for(key_pair.public_key)
|
8
10
|
certificate.sign(key_pair, OpenSSL::Digest::SHA256.new)
|
9
|
-
[
|
11
|
+
[certificate.to_pem, export(key_pair, algorithm, passphrase)]
|
10
12
|
end
|
11
13
|
|
12
14
|
private
|
data/lib/xml/kit/signature.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
class Signature
|
4
6
|
SIGNATURE_METHODS = {
|
5
|
-
SHA1:
|
6
|
-
SHA224:
|
7
|
-
SHA256:
|
8
|
-
SHA384:
|
9
|
-
SHA512:
|
7
|
+
SHA1: 'http://www.w3.org/2000/09/xmldsig#rsa-sha1',
|
8
|
+
SHA224: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha224',
|
9
|
+
SHA256: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
|
10
|
+
SHA384: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha384',
|
11
|
+
SHA512: 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha512',
|
10
12
|
}.freeze
|
11
13
|
DIGEST_METHODS = {
|
12
|
-
SHA1:
|
13
|
-
SHA224:
|
14
|
-
SHA256:
|
15
|
-
SHA384:
|
16
|
-
SHA512:
|
14
|
+
SHA1: 'http://www.w3.org/2000/09/xmldsig#SHA1',
|
15
|
+
SHA224: 'http://www.w3.org/2001/04/xmldsig-more#sha224',
|
16
|
+
SHA256: 'http://www.w3.org/2001/04/xmlenc#sha256',
|
17
|
+
SHA384: 'http://www.w3.org/2001/04/xmldsig-more#sha384',
|
18
|
+
SHA512: 'http://www.w3.org/2001/04/xmlenc#sha512',
|
17
19
|
}.freeze
|
18
20
|
|
19
21
|
attr_reader :certificate
|
data/lib/xml/kit/signatures.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
# @!visibility private
|
@@ -41,7 +43,7 @@ module Xml
|
|
41
43
|
signatures = new(
|
42
44
|
key_pair: key_pair,
|
43
45
|
signature_method: signature_method,
|
44
|
-
digest_method: digest_method
|
46
|
+
digest_method: digest_method
|
45
47
|
)
|
46
48
|
yield xml, XmlSignatureTemplate.new(xml, signatures)
|
47
49
|
signatures.complete(xml.target!)
|
data/lib/xml/kit/templatable.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
module Templatable
|
@@ -51,6 +53,14 @@ module Xml
|
|
51
53
|
signatures.sign_with(key_pair)
|
52
54
|
end
|
53
55
|
|
56
|
+
# Allows you to specify which public key to use for generating an XML encrypted element.
|
57
|
+
#
|
58
|
+
# @param certificate [Xml::Kit::Certificate] the certificate containing the public key to use for encryption.
|
59
|
+
def encrypt_with(certificate)
|
60
|
+
self.encrypt = true
|
61
|
+
self.encryption_certificate = certificate
|
62
|
+
end
|
63
|
+
|
54
64
|
private
|
55
65
|
|
56
66
|
def sign?
|
@@ -62,7 +72,7 @@ module Xml
|
|
62
72
|
@signatures ||= ::Xml::Kit::Signatures.new(
|
63
73
|
key_pair: signing_key_pair,
|
64
74
|
digest_method: digest_method,
|
65
|
-
signature_method: signature_method
|
75
|
+
signature_method: signature_method
|
66
76
|
)
|
67
77
|
end
|
68
78
|
|
data/lib/xml/kit/template.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Xml
|
2
4
|
module Kit
|
3
5
|
class Template
|
4
|
-
TEMPLATES_DIR=Pathname.new(File.join(__dir__,
|
6
|
+
TEMPLATES_DIR = Pathname.new(File.join(__dir__, 'templates/'))
|
5
7
|
|
6
8
|
attr_reader :target
|
7
9
|
|
@@ -24,7 +26,7 @@ module Xml
|
|
24
26
|
end
|
25
27
|
|
26
28
|
def template_name
|
27
|
-
"#{target.class.name.split(
|
29
|
+
"#{target.class.name.split('::').last.underscore}.builder"
|
28
30
|
end
|
29
31
|
|
30
32
|
def template
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
xml.Signature 'xmlns' => ::Xml::Kit::Namespaces::XMLDSIG do
|
2
4
|
xml.SignedInfo do
|
3
5
|
xml.CanonicalizationMethod Algorithm: ::Xml::Kit::Namespaces::CANONICALIZATION
|
4
6
|
xml.SignatureMethod Algorithm: signature_method
|
@@ -8,10 +10,10 @@ xml.Signature "xmlns" => ::Xml::Kit::Namespaces::XMLDSIG do
|
|
8
10
|
xml.Transform Algorithm: ::Xml::Kit::Namespaces::CANONICALIZATION
|
9
11
|
end
|
10
12
|
xml.DigestMethod Algorithm: digest_method
|
11
|
-
xml.DigestValue
|
13
|
+
xml.DigestValue ''
|
12
14
|
end
|
13
15
|
end
|
14
|
-
xml.SignatureValue
|
16
|
+
xml.SignatureValue ''
|
15
17
|
xml.KeyInfo do
|
16
18
|
xml.X509Data do
|
17
19
|
xml.X509Certificate certificate.stripped
|
data/lib/xml/kit/version.rb
CHANGED
data/xml-kit.gemspec
CHANGED
@@ -1,36 +1,41 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
6
|
+
require 'xml/kit/version'
|
5
7
|
|
6
8
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
9
|
+
spec.name = 'xml-kit'
|
8
10
|
spec.version = Xml::Kit::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
+
spec.authors = ['mo khan']
|
12
|
+
spec.email = ['mo@mokhan.ca']
|
11
13
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
14
|
+
spec.summary = 'A simple toolkit for working with XML.'
|
15
|
+
spec.description = 'A simple toolkit for working with XML.'
|
16
|
+
spec.homepage = 'https://github.com/saml-kit/xml-kit'
|
17
|
+
spec.license = 'MIT'
|
16
18
|
spec.required_ruby_version = '>= 2.2.0'
|
17
19
|
|
18
|
-
spec.files
|
20
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
19
21
|
f.match(%r{^(test|spec|features)/})
|
20
22
|
end
|
21
|
-
spec.metadata[
|
22
|
-
spec.bindir =
|
23
|
+
spec.metadata['yard.run'] = 'yri'
|
24
|
+
spec.bindir = 'exe'
|
23
25
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
-
spec.require_paths = [
|
26
|
+
spec.require_paths = ['lib']
|
25
27
|
|
26
|
-
spec.add_dependency
|
27
|
-
spec.add_dependency
|
28
|
-
spec.add_dependency
|
29
|
-
spec.add_dependency
|
30
|
-
spec.add_dependency
|
31
|
-
spec.add_development_dependency
|
32
|
-
spec.add_development_dependency
|
33
|
-
spec.add_development_dependency
|
34
|
-
spec.add_development_dependency
|
35
|
-
spec.add_development_dependency
|
28
|
+
spec.add_dependency 'activemodel', '>= 4.2.0'
|
29
|
+
spec.add_dependency 'builder', '~> 3.2'
|
30
|
+
spec.add_dependency 'nokogiri', '>= 1.8.2'
|
31
|
+
spec.add_dependency 'tilt', '>= 1.4.1'
|
32
|
+
spec.add_dependency 'xmldsig', '~> 0.6'
|
33
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
34
|
+
spec.add_development_dependency 'bundler-audit', '~> 0.6'
|
35
|
+
spec.add_development_dependency 'ffaker', '~> 2.7'
|
36
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
37
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
38
|
+
spec.add_development_dependency 'rubocop', '~> 0.52'
|
39
|
+
spec.add_development_dependency 'rubocop-rspec', '~> 1.22'
|
40
|
+
spec.add_development_dependency 'simplecov', '~> 0.15.1'
|
36
41
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xml-kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mo khan
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-03-
|
11
|
+
date: 2018-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 1.8.
|
47
|
+
version: 1.8.2
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 1.8.
|
54
|
+
version: 1.8.2
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: tilt
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '1.16'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: bundler-audit
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.6'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.6'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: ffaker
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,6 +150,34 @@ dependencies:
|
|
136
150
|
- - "~>"
|
137
151
|
- !ruby/object:Gem::Version
|
138
152
|
version: '3.0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rubocop
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0.52'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0.52'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rubocop-rspec
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '1.22'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '1.22'
|
139
181
|
- !ruby/object:Gem::Dependency
|
140
182
|
name: simplecov
|
141
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -160,13 +202,19 @@ files:
|
|
160
202
|
- ".gitignore"
|
161
203
|
- ".gitlab-ci.yml"
|
162
204
|
- ".rspec"
|
205
|
+
- ".rubocop.yml"
|
206
|
+
- ".rubocop_todo.yml"
|
163
207
|
- ".travis.yml"
|
164
208
|
- Gemfile
|
165
209
|
- LICENSE.txt
|
166
210
|
- README.md
|
167
211
|
- Rakefile
|
212
|
+
- bin/cibuild
|
168
213
|
- bin/console
|
214
|
+
- bin/lint
|
169
215
|
- bin/setup
|
216
|
+
- bin/test
|
217
|
+
- lib/xml-kit.rb
|
170
218
|
- lib/xml/kit.rb
|
171
219
|
- lib/xml/kit/certificate.rb
|
172
220
|
- lib/xml/kit/crypto.rb
|
@@ -214,7 +262,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
214
262
|
version: '0'
|
215
263
|
requirements: []
|
216
264
|
rubyforge_project:
|
217
|
-
rubygems_version: 2.7.
|
265
|
+
rubygems_version: 2.7.6
|
218
266
|
signing_key:
|
219
267
|
specification_version: 4
|
220
268
|
summary: A simple toolkit for working with XML.
|