grid-proxy 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a79fba06f694fdac9174c53344d410b62f46477d
4
+ data.tar.gz: 43c42f5fa1de15331325ce880a25f620e214196e
5
+ SHA512:
6
+ metadata.gz: 1131f2721731e9f49f7b488fe4722c9500af75411a978ee0e31b2a2efb3d496de450aab809dd5a24239adb725a3051fcda0748c4e50d6325ec904894a35044a8
7
+ data.tar.gz: bbbd7089be9ae6a7cd428011a8f4c0b8b0316f9b22bc45e03aab2371b38dc2b9dc81340cb90307cbb0792da799662d75f0da988dd478977643aaa3641186c311
data/.gitignore ADDED
@@ -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,16 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in grid-proxy.gemspec
4
+ gemspec
5
+
6
+ group :development, :test do
7
+ gem 'pry'
8
+
9
+ gem 'guard'
10
+ gem 'guard-rspec', '~>3.0.2'
11
+
12
+ gem 'rspec'
13
+ gem 'rspec-mocks'
14
+
15
+ gem 'libnotify'
16
+ end
data/Guardfile ADDED
@@ -0,0 +1,5 @@
1
+ guard :rspec do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch('spec/spec_helper.rb') { "spec" }
5
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Marek Kasztelnik
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.
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # Grid::Proxy
2
+
3
+ Simple utility for validating grid proxy.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'grid-proxy'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install grid-proxy
18
+
19
+ ## Usage
20
+
21
+ ```ruby
22
+ require 'grid-proxy'
23
+
24
+ # Username prefix is used to find correct user name.
25
+ # For example in PlGrid infrastructure all users have 'plg' prefix
26
+ # and this value is the default.
27
+ proxy = GP::Proxy(proxy_payload, username_prefix)
28
+
29
+ # throws GP::ProxyValidationError with message describing failure,
30
+ # when proxy is not valid. `path_to_crl_file` is optional
31
+ proxy.verify!(ca_crt_payload, path_to_crl_file)
32
+
33
+ # `true` if proxy is valid, false otherwise.
34
+ proxy.valid?(ca_crt_payload, path_to_crl_file)
35
+
36
+ # Get proxy elements
37
+ proxy.proxycert
38
+ proxy.proxykey
39
+ proxy.usercert
40
+
41
+ # Get user name basing on given prefix
42
+ proxy.username
43
+ ```
44
+
45
+ ## Contributing
46
+
47
+ 1. Fork it
48
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
49
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
50
+ 4. Push to the branch (`git push origin my-new-feature`)
51
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'grid-proxy/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "grid-proxy"
8
+ spec.version = GP::VERSION
9
+ spec.authors = ["Marek Kasztelnik"]
10
+ spec.email = ["mkasztelnik@gmail.com"]
11
+ spec.description = %q{Grid proxy utils}
12
+ spec.summary = %q{Grid proxy utils}
13
+ spec.homepage = "https://github.com/dice-cyfronet/grid-proxy"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
data/lib/grid-proxy.rb ADDED
@@ -0,0 +1,3 @@
1
+ require "grid-proxy/version"
2
+ require "grid-proxy/proxy"
3
+ require "grid-proxy/exceptions"
@@ -0,0 +1,3 @@
1
+ module GP
2
+ class ProxyValidationError < StandardError; end
3
+ end
@@ -0,0 +1,101 @@
1
+ module GP
2
+ class Proxy
3
+ CERT_START = '-----BEGIN CERTIFICATE-----'
4
+
5
+ attr_reader :proxy_payload
6
+
7
+ def initialize(proxy_payload, username_prefix = 'plg')
8
+ @proxy_payload = proxy_payload
9
+ @username_prefix = username_prefix
10
+ end
11
+
12
+ def proxycert
13
+ @proxycert ||= cert_for_element(1)
14
+ end
15
+
16
+ def proxykey
17
+ begin
18
+ @proxykey ||= OpenSSL::PKey.read(proxy_element(1))
19
+ rescue
20
+ nil
21
+ end
22
+ end
23
+
24
+ def usercert
25
+ @usercert ||= cert_for_element(2)
26
+ end
27
+
28
+ def verify!(ca_cert_payload, crl_payload = nil)
29
+ now = Time.now
30
+ raise GP::ProxyValidationError.new('Proxy is not valid yet') if now < proxycert.not_before
31
+ raise GP::ProxyValidationError.new('Proxy expired') if now > proxycert.not_after
32
+ raise GP::ProxyValidationError.new('Usercert not signed with trusted certificate') unless ca_cert_payload && usercert.verify(cert(ca_cert_payload).public_key)
33
+ raise GP::ProxyValidationError.new('Proxy not signed with user certificate') unless proxycert.verify(usercert.public_key)
34
+
35
+ proxycert_issuer = proxycert.issuer.to_s
36
+ proxycert_subject = proxycert.subject.to_s
37
+
38
+ raise GP::ProxyValidationError.new('Proxy and user cert mismatch') unless proxycert_issuer == usercert.subject.to_s
39
+ raise GP::ProxyValidationError.new("Proxy subject must begin with the issuer") unless proxycert_subject.to_s.index(proxycert_issuer) == 0
40
+ raise GP::ProxyValidationError.new("Couldn't find '/CN=' in DN, not a proxy") unless proxycert_subject.to_s[proxycert_issuer.size, proxycert_subject.to_s.size].to_s.include?('/CN=')
41
+
42
+ raise GP::ProxyValidationError.new("Private proxy key missing") unless proxykey
43
+ raise GP::ProxyValidationError.new("Private proxy key and cert mismatch") unless proxycert.check_private_key(proxykey)
44
+
45
+ raise GP::ProxyValidationError.new("User cert was revoked") if crl_payload != nil and revoked? crl_payload
46
+
47
+ if now < usercert.not_before || now > usercert.not_after
48
+ raise GP::ProxyValidationError.
49
+ new('Proxy signed by outdated certificate')
50
+ end
51
+ end
52
+
53
+ def valid?(ca_cert_payload, crl_payload = nil)
54
+ begin
55
+ verify! ca_cert_payload, crl_payload
56
+ true
57
+ rescue GP::ProxyValidationError
58
+ false
59
+ end
60
+ end
61
+
62
+ def revoked?(crl_payload)
63
+ # crl should to be verified with ca cert
64
+ # crl(crl_payload).verify()
65
+
66
+ #check for usercert serial in list of all revoked certs
67
+ revoked_cert = crl(crl_payload).revoked().detect do |revoked|
68
+ revoked.serial == usercert.serial
69
+ end
70
+
71
+ return revoked_cert != nil ? true : false
72
+
73
+ end
74
+
75
+ def username
76
+ username_entry = usercert.subject.to_a.detect do |el|
77
+ el[0] == 'CN' && el[1].start_with?(@username_prefix)
78
+ end
79
+
80
+ username_entry ? username_entry[1] : nil
81
+ end
82
+
83
+ private
84
+
85
+ def cert_for_element(element_nr)
86
+ cert(proxy_element(element_nr))
87
+ end
88
+
89
+ def proxy_element(element_nr)
90
+ "#{CERT_START}#{@proxy_payload.split(CERT_START)[element_nr]}"
91
+ end
92
+
93
+ def cert(payload)
94
+ OpenSSL::X509::Certificate.new payload
95
+ end
96
+
97
+ def crl(payload)
98
+ OpenSSL::X509::CRL.new payload
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,3 @@
1
+ module GP
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,64 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDSjCCAjKgAwIBAgIEccygMzANBgkqhkiG9w0BAQUFADB6MQswCQYDVQQGEwJQ
3
+ TDEQMA4GA1UEChMHUEwtR3JpZDETMBEGA1UEChMKVXp5dGtvd25pazERMA8GA1UE
4
+ ChMIQ1lGUk9ORVQxGTAXBgNVBAMTEE1hcmVrIEthc3p0ZWxuaWsxFjAUBgNVBAMT
5
+ DXBsZ2thc3p0ZWxuaWswHhcNMTMxMjA0MDY0ODI5WhcNMTMxMjA0MTg1MzI5WjCB
6
+ jzELMAkGA1UEBhMCUEwxEDAOBgNVBAoTB1BMLUdyaWQxEzARBgNVBAoTClV6eXRr
7
+ b3duaWsxETAPBgNVBAoTCENZRlJPTkVUMRkwFwYDVQQDExBNYXJlayBLYXN6dGVs
8
+ bmlrMRYwFAYDVQQDEw1wbGdrYXN6dGVsbmlrMRMwEQYDVQQDEwoxOTA5MjM1NzYz
9
+ MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiSbXqodFP+mI9SU2DrI3n3lI7
10
+ j3mMo88c55lqKOzwk93NibvVk79shbz/rzbAFh9Phm/QE58wR460FAFPnbuCvVhu
11
+ N7KcN6p5JDancapWIwAsjsljfMMTsYAQ8xhL0Rxl0UcGeeaUHNsZvXGZX+eWuk+F
12
+ YtzCKlYo5i3sz1swCwIDAQABo0YwRDATBgNVHSUEDDAKBggrBgEFBQcDAjAOBgNV
13
+ HQ8BAf8EBAMCBLAwHQYIKwYBBQUHAQ4BAf8EDjAMMAoGCCsGAQUFBxUBMA0GCSqG
14
+ SIb3DQEBBQUAA4IBAQAiCx3X+5sNXMf9IFe6+D9LLjVzWor3FUaU8mGnSV0oATkH
15
+ evzSSEBggWlnWFDNaxBM1kSugbupFjG7QRl4X8ecCYSeewqC4jyox1SI3EKaPXt9
16
+ +x8BwxFDhoszQjh2BUSSlDskr/W4rlqVUc9o45W4Ur8R7dfmegb4LE/UQ7pUqLUC
17
+ RoXibDV8pPaWTtiv/6NuMfGQA6UtNxncDWp5irY22r8NZKpmBJjGeB3RE46CCyiZ
18
+ +SlHDM+3DTKSRLOmt03R7PE+HAx+m/h4mnKFpabGECGwmgo69c93BpJz7+b4pZ5B
19
+ 7QL0mKdh5Srebiqwxy9pKJt6el53w9C7/7FW+Bvs
20
+ -----END CERTIFICATE-----
21
+ -----BEGIN RSA PRIVATE KEY-----
22
+ MIICXQIBAAKBgQC9GAYDB9Ym65pkR0CxQl8NOjXSBxtuesc5UDXIILpD60BSZ00k
23
+ n70u37KadNmvPUtzT7+DMDZmFkAWxtHSmT7Id33nAz25ge5wkc7HPhmn4g5G4udc
24
+ gMjXG0eWg7+/Oe8nxVh8YgX/VobOhApPvpxsYkuvBwxTyok66uqTzAyD0QIDAQAB
25
+ AoGAdzNKruRkwjopJGeqR1OgmbUFMnXafAWXyvBeRt8irCgDby7BeYHc/0xyyV05
26
+ 0HciNfmir29YC3ihQ/pnUIvb/+oO0cWtd4th3ZLGEJo1YFxsNSERvQnjFrm0q/BM
27
+ bNtThlGB6k8KNrp8PIaQDPep0TnlUxEUsr2g5t2d0sYSpzUCQQD1aiAXmBosb1Ql
28
+ XZ2bH+ORkJDm3GNMKYGxg3BgP9eOYaMKD29Pa5xd5xGWvzDV2wFjs+Z7TBsXtK7E
29
+ kyg5rwazAkEAxUAA0YOx1O1Pw7+FwOfEtlW1W2JwEJahPGktz2wE5RLNo/p/eXnJ
30
+ qb3UHz2aSQPKVk1kuoY0L3bx3rExrwvtawJAQvdJeIa1pahfQq7v4bNq6n6TO5up
31
+ sM+mpyShlnH1RNHZplYd3oMTsP/racIT9lcDYwxk+QIEZoyUH+mz0UG0RwJBAKZv
32
+ qgEfkXcsQujV+0NZjVeZHG0es5abszMpQLlL2Rl9cz1RCizzAaGThqBRt5SyeRG3
33
+ Pi5RPUlroQ0aEOU2OD8CQQCA6crpDU0RXqrpBjrTUgi3Nvl6KFj8YPVGd3QOYM3m
34
+ fSh4/xPzp1gsJd1lWN22AuUhJgWggTbXVI98Ueybiu4G
35
+ -----END RSA PRIVATE KEY-----
36
+ -----BEGIN CERTIFICATE-----
37
+ MIIE+zCCAuOgAwIBAgIIebhrdbR7A/IwDQYJKoZIhvcNAQEFBQAwMzELMAkGA1UE
38
+ BhMCUEwxEDAOBgNVBAoTB1BMLUdyaWQxEjAQBgNVBAMTCVNpbXBsZSBDQTAeFw0x
39
+ MjEyMTIxMzQ2MDhaFw0xMzEyMTIxMzQ2MDhaMHoxCzAJBgNVBAYTAlBMMRAwDgYD
40
+ VQQKEwdQTC1HcmlkMRMwEQYDVQQKEwpVenl0a293bmlrMREwDwYDVQQKEwhDWUZS
41
+ T05FVDEZMBcGA1UEAxMQTWFyZWsgS2FzenRlbG5pazEWMBQGA1UEAxMNcGxna2Fz
42
+ enRlbG5pazCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMCzblkq3S7N
43
+ jb1i0feRHMWfJBUxhBpqf8wJrH6Ez9lwgeltEDd/dc7pRpuD9PuORyQrEB2xC+Eu
44
+ iK528UA4ravcCWVOnNlX7o/Ab1BsyevkwtFFzrODfYPpErXM/b+m1uRSRoeZG5/U
45
+ LcPAD0tnsXWoiU+XoGi3DYGAb7xGRm0sQYfHxCJQ/2QmkQKGY3K1leWSVTlvZtxd
46
+ bryNQSgJU+0XZnsuTcJcst6vlyERe02KjCBZ6qYeBMSJ55JHATupc0zF5HIX4Keq
47
+ drvoSueI1QI808Jzqd+saKDOXtHGhDjOslNBw61j0Vb3NXIX9LYTn2I/vBoz2k4P
48
+ JhVYKs0ICn0CAwEAAaOByzCByDAdBgNVHQ4EFgQUb/DPnzblDbrcnpMkcKAq4x4Q
49
+ DUgwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSpE1FZa0RLf5yh9znM2AH8VFVA
50
+ LTAaBgNVHSAEEzARMA8GDSsGAQQBgpYtAQEBAQIwNwYDVR0fBDAwLjAsoCqgKIYm
51
+ aHR0cDovL3BsZ3JpZC1zY2Eud2Nzcy53cm9jLnBsL2NybC5kZXIwDgYDVR0PAQH/
52
+ BAQDAgSwMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4ICAQDD
53
+ 0vkRC4BswLwX7IA/W0KsAMEI8W9R7+iw7grMxZY9rsLn3BmRxWpJ27bhhIRr986p
54
+ fR+ydWPHPEslXu4CqOtSp6EJf4IU+4ZM8622W2YjsGHpYDjk3WvSiq2TuSGzFJMd
55
+ SuAqdmVKsX8gudo8TdxUAuf4BdliQiSVJFIN/8HnPolOa4N5yPBudr9/PqQ5yRbJ
56
+ Ijlgsp4It4FRT4ats73u0cmVRMNIKSKJ3PSsDKtP3NUy0hrDdDKlWD8DqkYnE2p2
57
+ KALqmMQ3xiKlH1+VWwBrMDn+Py86hEYJ1+ZaRsyUSrhEKTEi9KZmFCDlPnvtHVJ3
58
+ emI7QguphAXoHcMQmuk35mIcZBWisp/fgJMEH0DgHrxDufpFeI90xDmtI9Nr+Uy0
59
+ n7lfmr52YfYUybRuVbZpGt9W8B6KEXHi9wwbEemh1uX2q/STTnC24ICL2vf7h+yn
60
+ +5U2YKmsk02JVy21ADkcDhUGZ7V2wn19MKJOGzL0DxmcomeIp0GEhn6uL01fyDcl
61
+ cJOHH6aXQJRz+v/QHwRnc2kDJi0HzukeHgzGk26IxOB/zkWp/amjJrDwTwVkQu0S
62
+ Jl2p4TIy7eeQsGgN1xiAxFCc7zNRyeZ8gXFQRg+OI49sVUBk1m4HAZJvqJIgxkie
63
+ g8nOThxmD2nRRAYwwEx4pQZdAiid0c/fzt3L0cLAXg==
64
+ -----END CERTIFICATE-----
@@ -0,0 +1,96 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDRDCCAiygAwIBAgIEZv7HyDANBgkqhkiG9w0BAQUFADB3MQswCQYDVQQGEwJQ
3
+ TDEQMA4GA1UEChMHUEwtR3JpZDETMBEGA1UEChMKVXp5dGtvd25pazERMA8GA1UE
4
+ ChMIQ1lGUk9ORVQxGDAWBgNVBAMTD0RhbmllbCBIYXJlemxhazEUMBIGA1UEAxML
5
+ cGxnaGFyZXpsYWswHhcNMTMxMDIxMDkwNDQ0WhcNMTMxMDIxMjEwOTQ0WjCBjDEL
6
+ MAkGA1UEBhMCUEwxEDAOBgNVBAoTB1BMLUdyaWQxEzARBgNVBAoTClV6eXRrb3du
7
+ aWsxETAPBgNVBAoTCENZRlJPTkVUMRgwFgYDVQQDEw9EYW5pZWwgSGFyZXpsYWsx
8
+ FDASBgNVBAMTC3BsZ2hhcmV6bGFrMRMwEQYDVQQDEwoxNzI3OTczMzIwMIGfMA0G
9
+ CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnlWzI9AGKQsoXnNXtB8eRgYRdh617FdQd
10
+ Zhg2r8eCEMu4/o1qUbjFFydNVmjgolpj0Zux6CWOnuvnSAqEJdBk5I+FMCpGGGUk
11
+ VqpobL8pWSEypniWEgVFPgVY7/Ayr4LjLXXvGwq/mbH6fjCJHsvKDRkKbOlfNDmf
12
+ 7qQANZVcCQIDAQABo0YwRDATBgNVHSUEDDAKBggrBgEFBQcDAjAOBgNVHQ8BAf8E
13
+ BAMCBLAwHQYIKwYBBQUHAQ4BAf8EDjAMMAoGCCsGAQUFBxUBMA0GCSqGSIb3DQEB
14
+ BQUAA4IBAQCTtTXA5BHQ4jJ+Nivz/3ZxH74UrBpfj8WJFuMiLGBhwRaKItOs4WZE
15
+ xc8Qp/rvanA5pB44ox34PwlKpdqkQrfvOwwnY+N/YnseUHNTR2W6Svs64c2ghEXS
16
+ EzqsPAV2y7VvyCva//8rdR7jJRIphJAqMzhhV26CtbB6qlEK02WN8BQR8kf1Zf21
17
+ b0koEjF10HpjnCKNNLR6N5h57H31+c3ODvXR7z/1xo5qgNWPyYG9tx47Cjns8nYA
18
+ CD1UGpKASm5hjdA4skXDyuqW5wnQbxvkKTBCj+xPhoBnYWZRjE968Wd31v55c1EE
19
+ OuuNI2fjovwzMHwbNPf0kv4/SWbxWP2k
20
+ -----END CERTIFICATE-----
21
+ -----BEGIN RSA PRIVATE KEY-----
22
+ MIICXAIBAAKBgQCnlWzI9AGKQsoXnNXtB8eRgYRdh617FdQdZhg2r8eCEMu4/o1q
23
+ UbjFFydNVmjgolpj0Zux6CWOnuvnSAqEJdBk5I+FMCpGGGUkVqpobL8pWSEypniW
24
+ EgVFPgVY7/Ayr4LjLXXvGwq/mbH6fjCJHsvKDRkKbOlfNDmf7qQANZVcCQIDAQAB
25
+ AoGAagwkywWd8+BQAqE8vsIth+Zt3MH/BeTKVdBFglW56pS2Vlq/IoiUZCRCuq3z
26
+ sDMNAB2kaPB+08G9hp4QCY/kTu4uYtOBSRsuNDVELN9S2zL6wRHzPGnUYSCnKpP0
27
+ hRzhHF+PG5oDtkhe3/mUbHE6aWiccJiJIeXdPCaOl8H3AAECQQDP60d8gMbUT0uh
28
+ W5u+DU0D3+1+7tdYzQqX409nZvVRCDmxH5fzsuhvH54MxkwAUFgwSTMXjH3f0/Qn
29
+ XcMXNc+BAkEAzlZPEqYo9387ples27vFYigPWP4zFlm94I0HlpD8eLZbp4aRXnVe
30
+ mQ7zmchsfdjo9Hq/TYATNmC4ZaC34XFQiQJATFGYk+LRGO1iXYA60rAfLOTtUEJr
31
+ WXUqBkaxxsrMEUprotBt/k4Vc3SvlxDSpOrY9CBqWKKBMb+jRy/rhIGEAQJBAMdm
32
+ tUfKd/CmbpjUReKb1aaEHEDed7RzyYGGCP1C5Bor8Os2qqlkN6Umw9erztzXkFkj
33
+ fliBGxAD7G+aH9moTjECQFBqZBl1vFbfXlYsbJvyzI6BsL+pHdzF6s2AwJMdwbQ7
34
+ w5ty/0htdxg7+3TNUXc5z7vIhz+ugEoccseNzn174fA=
35
+ -----END RSA PRIVATE KEY-----
36
+ -----BEGIN CERTIFICATE-----
37
+ MIIE+DCCAuCgAwIBAgIIGYYg85BsUXIwDQYJKoZIhvcNAQEFBQAwMzELMAkGA1UE
38
+ BhMCUEwxEDAOBgNVBAoTB1BMLUdyaWQxEjAQBgNVBAMTCVNpbXBsZSBDQTAeFw0x
39
+ MzA3MTAwNjM4NDNaFw0xNDA3MTAwNjM4NDNaMHcxCzAJBgNVBAYTAlBMMRAwDgYD
40
+ VQQKEwdQTC1HcmlkMRMwEQYDVQQKEwpVenl0a293bmlrMREwDwYDVQQKEwhDWUZS
41
+ T05FVDEYMBYGA1UEAxMPRGFuaWVsIEhhcmV6bGFrMRQwEgYDVQQDEwtwbGdoYXJl
42
+ emxhazCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALapGpwRnWScy+HS
43
+ NjtLSaL7Ye6vZnnemiQL8NxxL4yFg2A1vLXuxWpbM8BZdhOV2qSs3YCg3s7fAbTf
44
+ D0jEk+V2NODTRk8ajKnK2/o+fGWzwhkgOoAZIY7lzB/QBS3h5Viu3otmfo+UWXDG
45
+ ZFwJIxIluki0KUXcBZkbPoPaIZ5RqBWI9ZP8ihtfNT5zojiKE2Nmccp0QApsJDEX
46
+ bFb490cgwviXhEuoHumAdfiPVNTW3591YzPgVvzrzc2r/dBR3cS08tJfFTLl3oz9
47
+ Yq7luoTai4xehAIxAl4mt1/3gWrSmqlT91g4kKvQna6d1bkGpQ1bjoeik3NCenhP
48
+ 2rtp/ucCAwEAAaOByzCByDAdBgNVHQ4EFgQUMMsCoqqMZ93X0zaJwoH4eTTxIUsw
49
+ DAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSpE1FZa0RLf5yh9znM2AH8VFVALTAa
50
+ BgNVHSAEEzARMA8GDSsGAQQBgpYtAQEBAQIwNwYDVR0fBDAwLjAsoCqgKIYmaHR0
51
+ cDovL3BsZ3JpZC1zY2Eud2Nzcy53cm9jLnBsL2NybC5kZXIwDgYDVR0PAQH/BAQD
52
+ AgSwMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4ICAQAkhIBh
53
+ 2o6TzODMDseBcH/xKlTt1/+r8s3rCGf0mZ8/T2/DNaPUMgK0xvnPe2UqTJJPLDm4
54
+ 2R1d4ILUGfq6zfDiVAxXDIOOJEe0svud68GDTIIICrMqzY3m+NtAgRifd3KQWBBs
55
+ TV6gsvwncG805xUE9e7pYyKzHgOF6B693ByuSbacqukd3gLRyl3ECGxzZg8RjAnX
56
+ KC0QRC+5igtcbh3REqgxkq9AHMF2eHKYIW4cPoUe1EVR5cNv52LNr9AWF+VV8jWV
57
+ 6QyhmN9mjMsiYOrJ1VXZdpd4Kv0CTZKcNUektdqh8eg5kwLhdKzfHi/Ta9UdbWDY
58
+ B8IxTDlKieM/LAYSbXpBE8Iocn81FcocqujgFGC4hdRASr6RPkc89TZ5Qb5+Gla4
59
+ eRiO3c7sC+Q8upFqdbdu3RVjVgM/da3f83IETq4nkjC4sDov1zah5+I/oxYL4u0u
60
+ p3a/Hyl0s2FPngxmUVh7snBZpf4om/56mleCCcvmWD+/vc6tWWV53y6LiQ9dL8g5
61
+ 3P2Jj1O2OgnSC+8bHxBrmJ7cCY2a/2mAv8SvM3yF4Yqctw3FXZMuEmZVjbMJTHRA
62
+ 411MlFWsFDoZQxznq7/Hmm4SLpk7GkYuO06CUCl/Atk8LzEax/yIdjF/tfJbvuFL
63
+ B4DZGgNwe4EA4B+74pVehZHcsBusXcJdctVy7w==
64
+ -----END CERTIFICATE-----
65
+ -----BEGIN CERTIFICATE-----
66
+ MIIFhjCCA26gAwIBAgIIV39Xlts+63QwDQYJKoZIhvcNAQEFBQAwMzELMAkGA1UE
67
+ BhMCUEwxEDAOBgNVBAoTB1BMLUdyaWQxEjAQBgNVBAMTCVNpbXBsZSBDQTAeFw0x
68
+ MDA0MDIxNDA0MjFaFw0zMDA0MDIxNDA0MjFaMDMxCzAJBgNVBAYTAlBMMRAwDgYD
69
+ VQQKEwdQTC1HcmlkMRIwEAYDVQQDEwlTaW1wbGUgQ0EwggIiMA0GCSqGSIb3DQEB
70
+ AQUAA4ICDwAwggIKAoICAQDE0NE7HS6BfXAkwXJbxdKQ/7/urjWyw49IpxXno4SN
71
+ WDa7mFfqDu5pJeY5mw/mAfpirOjshrHouqf34vLRe8en6HTCYADXN23vVICM73QH
72
+ PmvSOJoPNQPQImsVYTOSlwyQA8DgRmOUoQ94wZw+yqwwCTJOQJ9ncuLAYJ9myvYG
73
+ VqPTN6lznFz6o/YUIPECsZ6JtJIc0ubXtt55thVkhzgce8GNusB0jREQ+KMkQlKx
74
+ 0xBQLkPJ+GW0cVyJIVW8EC3YHZJnWpmU5CdJn6MTBc76HwTN7IEGELJ3hoPd2lYw
75
+ rLol8AWK1kxNCnOXioDrJNialwA1kTb5pE+PTswBnH3z0UEoxISTjbJzwc418TBt
76
+ 9MKOLSqPMXAjIvTkM1ZFj/fCxUgm/aT/4+19m9tDnnQIO6br4An8qMAsmZRmIWQ/
77
+ s2FDVYvhxInJkjtfccFOCYKUMEePl3OCTUgz1K2Aonrg3Iu4dHVWwLZbyersOe32
78
+ NBxEH/q2Xy8XYg+cxwokjlyQwrIohkxwIquwFWr/CXLhtGKIBoHnn/+Tt4Vz5eQb
79
+ 2/Z+Xc1hpXPCYXKyYKKu9d+gBrb2mJ9al/SRzJ+DVRfphcuN6bNsIakb+B8cUwP2
80
+ vkh6JNJl7/BmmP9fvZ0adfaI/EQLjo4Angm3dxskzKMNX/PWY0SRInAKxE5MIiEz
81
+ vwIDAQABo4GdMIGaMB0GA1UdDgQWBBSpE1FZa0RLf5yh9znM2AH8VFVALTAPBgNV
82
+ HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKkTUVlrREt/nKH3OczYAfxUVUAtMDcG
83
+ A1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly9wbGdyaWQtc2NhLndjc3Mud3JvYy5wbC9j
84
+ cmwuZGVyMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAgEAi13PWttc
85
+ ReDFS9LOX91dhySRQcixT07AJWtys5VDwwy1DjPMwPF+Avanq9JZ5EII3yAvtZ0G
86
+ ikSE5OrYB4PC5mnJFwBGDIU/S2RBgwxEJUTAttRXrubyYPk3KBbJoCCQ2JdSY52P
87
+ Krde43ykQswHpKls9V3bhwpRZIoJt0e76qBNOuiRf4CUupj5BhRto072qDlWWBfY
88
+ BWg6YANwYXJc/+OvwUemEJGmYLT50zQBce7eIE4KcT44NqN5KG5tLMLH4tHfuVPe
89
+ n1eabXUu6W//RtlgxgNKjGKrPF7nz36HPLxcOqzEHcD7h2MEWo9vICbipWPmrfyW
90
+ 5OQ8UrCbXRmRnLodzhJrfXzA69PiZqCYERnu0RsvXLNWFRlQsbNfB5Ju3PJo9jtb
91
+ Mi6chpDMOgeogtPJNBw+XtgPha/MMPumOfl2uo1UIoeA1hF1uTGyLG2lDSA1kx+B
92
+ XJIJmDdsy/CBItl7zBM5oI9J+UeZp+H3jbRsmBXX6hmcNq3154nMpKV7n/ZfUbFG
93
+ Dk6eeapZA7/uqmXGcUAzcs5cPYW2FT02dcf2neU43bP5Z4+H7TpOU+LLVhs6Wdvr
94
+ rXaHEPmM8y+Zc9przAguYFseftKKtXwG5s8WC/brfRr5SUrnlYSQnd4LnO4VbDBo
95
+ rdb1YMm3y1JWoXT/Ckvtl9xnumA2r8pyg7g=
96
+ -----END CERTIFICATE-----
@@ -0,0 +1,62 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIC6TCCAdGgAwIBAgIBADANBgkqhkiG9w0BAQUFADB6MQswCQYDVQQGEwJQTDEQ
3
+ MA4GA1UEChMHUEwtR3JpZDETMBEGA1UEChMKVXp5dGtvd25pazERMA8GA1UEChMI
4
+ Q1lGUk9ORVQxGTAXBgNVBAMTEE1hcmVrIEthc3p0ZWxuaWsxFjAUBgNVBAMTDXBs
5
+ Z2thc3p0ZWxuaWswHhcNMTMxMjA0MDY0ODI5WhcNMTMxMjA0MTg1MzI5WjB6MQsw
6
+ CQYDVQQGEwJQTDEQMA4GA1UECgwHUEwtR3JpZDETMBEGA1UECgwKVXp5dGtvd25p
7
+ azERMA8GA1UECgwIQ1lGUk9ORVQxGTAXBgNVBAMMEE1hcmVrIEthc3p0ZWxuaWsx
8
+ FjAUBgNVBAMMDXBsZ2thc3p0ZWxuaWswgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
9
+ AoGBANEMEopg60rELXV9qz87XbzTxj4lt5HOulQfTNvP1hO3p/GHdZ3UN0TRKGTW
10
+ fUp7zgzbPEeTOFAYbiraQab2heBS9m6M1Sxodt+nRArsm16uu6DIG1r2aNoUolhJ
11
+ Tx9D5WNgmOXZQjrJL905GF3hd2xe/Z7z6e9NcL9QNjvVZwBHAgMBAAEwDQYJKoZI
12
+ hvcNAQEFBQADggEBAF3RnFI4//Y0lke8QW/niB5v7LOzLeO/M6rTrsfEyCFYAPZE
13
+ wXfZo3HLgUQfOVYgpBNJ7USWr171RDbSvnwR1mziynhCpNQ4oc/5Q5cFF1qn+3wV
14
+ bEwZFhij4TYoFUPFtiqT3j3tMuO3HGl2MbF18VKTnzc1YOQnfohXmtISI2lpoQzL
15
+ j+R2RATMPKw3CwnanzsLe/8x8XUfZV0XtuOwb5h+08q+StfAurqgyugwquTSOHn+
16
+ M8ZG5LYOihiMo6XEWbNzri8Z+/KKvNUY3BnAL4llg49zhk6XsJEy0Htx8e6cqtAg
17
+ x4MY+vuO8U+MCNMwUcbtydafwD3bK+lYia4vtXU=
18
+ -----END CERTIFICATE-----
19
+ -----BEGIN RSA PRIVATE KEY-----
20
+ MIICXAIBAAKBgQDRDBKKYOtKxC11fas/O12808Y+JbeRzrpUH0zbz9YTt6fxh3Wd
21
+ 1DdE0Shk1n1Ke84M2zxHkzhQGG4q2kGm9oXgUvZujNUsaHbfp0QK7JterrugyBta
22
+ 9mjaFKJYSU8fQ+VjYJjl2UI6yS/dORhd4XdsXv2e8+nvTXC/UDY71WcARwIDAQAB
23
+ AoGAUg9JH+TXuCu2JI7GMDYfn8YJ5c9sdeIOpoL66rZ1NJw9YsRn2SK651qrXpoL
24
+ 6LcctVNCIF6cFmTgqhWu+9l9x1DK/LF6pH7EFz15Hvk7OPJdYGzkEVvj3YxwnVj6
25
+ VD1wTAaXjeBlwB8bQlJvHysl8TtKjqqJd4hzLEESh8QbENECQQD7Vs+DtyP0XMyN
26
+ nUtZ21TWXFy0bbNwG9AKVnSdYGzXw0jaAWvNoKEycI3R00pNvHytg2fFDxlENzgU
27
+ +gNpB02jAkEA1Ox88FNzSyhTDMBRaXOSsh3/z2jPjEyWSXGqYK+dgfXd4Bhq3FPq
28
+ x9oQb7a9snKrDwn9BLNzARkAVTgxHOqlDQJAJv29rapguo0W8rU/Nk5vZ93mR9to
29
+ 5fB6os/swWlvGT3jdGaaCclsmH2bkrybn1mpYeWr2IdSHSIP4jkzBD0szwJBAIIG
30
+ TKGiBFUQMe8mflDMH/gfc7jgA2Zk2p3NCMN0WtYjI7QWlSMpJ8WVd9YQnTUc6zMK
31
+ 4XT+dKtl7hscbnl/HP0CQECEQoUMY80NpwxaLp2nGQ22hVIXE5rurc8iRrPuQyeH
32
+ Oe2POF/BDdy1yNSkdbm8zOo0eCt1zRdnh2bT24yEtOk=
33
+ -----END RSA PRIVATE KEY-----
34
+ -----BEGIN CERTIFICATE-----
35
+ MIIE+zCCAuOgAwIBAgIIebhrdbR7A/IwDQYJKoZIhvcNAQEFBQAwMzELMAkGA1UE
36
+ BhMCUEwxEDAOBgNVBAoTB1BMLUdyaWQxEjAQBgNVBAMTCVNpbXBsZSBDQTAeFw0x
37
+ MjEyMTIxMzQ2MDhaFw0xMzEyMTIxMzQ2MDhaMHoxCzAJBgNVBAYTAlBMMRAwDgYD
38
+ VQQKEwdQTC1HcmlkMRMwEQYDVQQKEwpVenl0a293bmlrMREwDwYDVQQKEwhDWUZS
39
+ T05FVDEZMBcGA1UEAxMQTWFyZWsgS2FzenRlbG5pazEWMBQGA1UEAxMNcGxna2Fz
40
+ enRlbG5pazCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMCzblkq3S7N
41
+ jb1i0feRHMWfJBUxhBpqf8wJrH6Ez9lwgeltEDd/dc7pRpuD9PuORyQrEB2xC+Eu
42
+ iK528UA4ravcCWVOnNlX7o/Ab1BsyevkwtFFzrODfYPpErXM/b+m1uRSRoeZG5/U
43
+ LcPAD0tnsXWoiU+XoGi3DYGAb7xGRm0sQYfHxCJQ/2QmkQKGY3K1leWSVTlvZtxd
44
+ bryNQSgJU+0XZnsuTcJcst6vlyERe02KjCBZ6qYeBMSJ55JHATupc0zF5HIX4Keq
45
+ drvoSueI1QI808Jzqd+saKDOXtHGhDjOslNBw61j0Vb3NXIX9LYTn2I/vBoz2k4P
46
+ JhVYKs0ICn0CAwEAAaOByzCByDAdBgNVHQ4EFgQUb/DPnzblDbrcnpMkcKAq4x4Q
47
+ DUgwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAWgBSpE1FZa0RLf5yh9znM2AH8VFVA
48
+ LTAaBgNVHSAEEzARMA8GDSsGAQQBgpYtAQEBAQIwNwYDVR0fBDAwLjAsoCqgKIYm
49
+ aHR0cDovL3BsZ3JpZC1zY2Eud2Nzcy53cm9jLnBsL2NybC5kZXIwDgYDVR0PAQH/
50
+ BAQDAgSwMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4ICAQDD
51
+ 0vkRC4BswLwX7IA/W0KsAMEI8W9R7+iw7grMxZY9rsLn3BmRxWpJ27bhhIRr986p
52
+ fR+ydWPHPEslXu4CqOtSp6EJf4IU+4ZM8622W2YjsGHpYDjk3WvSiq2TuSGzFJMd
53
+ SuAqdmVKsX8gudo8TdxUAuf4BdliQiSVJFIN/8HnPolOa4N5yPBudr9/PqQ5yRbJ
54
+ Ijlgsp4It4FRT4ats73u0cmVRMNIKSKJ3PSsDKtP3NUy0hrDdDKlWD8DqkYnE2p2
55
+ KALqmMQ3xiKlH1+VWwBrMDn+Py86hEYJ1+ZaRsyUSrhEKTEi9KZmFCDlPnvtHVJ3
56
+ emI7QguphAXoHcMQmuk35mIcZBWisp/fgJMEH0DgHrxDufpFeI90xDmtI9Nr+Uy0
57
+ n7lfmr52YfYUybRuVbZpGt9W8B6KEXHi9wwbEemh1uX2q/STTnC24ICL2vf7h+yn
58
+ +5U2YKmsk02JVy21ADkcDhUGZ7V2wn19MKJOGzL0DxmcomeIp0GEhn6uL01fyDcl
59
+ cJOHH6aXQJRz+v/QHwRnc2kDJi0HzukeHgzGk26IxOB/zkWp/amjJrDwTwVkQu0S
60
+ Jl2p4TIy7eeQsGgN1xiAxFCc7zNRyeZ8gXFQRg+OI49sVUBk1m4HAZJvqJIgxkie
61
+ g8nOThxmD2nRRAYwwEx4pQZdAiid0c/fzt3L0cLAXg==
62
+ -----END CERTIFICATE-----