scep 0.0.1 → 0.0.2

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.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +5 -1
  4. data/.yardopts +3 -0
  5. data/README.md +19 -1
  6. data/lib/scep.rb +2 -4
  7. data/lib/scep/asn1.rb +38 -0
  8. data/lib/scep/endpoint.rb +2 -0
  9. data/lib/scep/jscep_cli.rb +26 -0
  10. data/lib/scep/keypair.rb +4 -0
  11. data/lib/scep/pki_operation/base.rb +25 -0
  12. data/lib/scep/pki_operation/request.rb +122 -1
  13. data/lib/scep/version.rb +1 -1
  14. data/scep.gemspec +4 -1
  15. data/spec/console +2 -0
  16. data/spec/fixtures/ejbca/ca.crt +20 -0
  17. data/spec/fixtures/ejbca/ca.key +27 -0
  18. data/spec/fixtures/ejbca/ca/README +14 -0
  19. data/spec/fixtures/ejbca/ca/management_ca/data.xml +511 -0
  20. data/spec/fixtures/ejbca/ca/management_ca/keystore.p12.b64 +75 -0
  21. data/spec/fixtures/ejbca/ca/management_ca/xkmskeystore.p12.b64 +75 -0
  22. data/spec/fixtures/ejbca/management_ca.crt +20 -0
  23. data/spec/fixtures/ejbca/management_ca.full.crt +22 -0
  24. data/spec/fixtures/ejbca/management_ca.key +27 -0
  25. data/spec/fixtures/ejbca/management_ca.new.key +27 -0
  26. data/spec/fixtures/ejbca/sample-request.csr +8 -0
  27. data/spec/fixtures/ejbca/sample-request.key +9 -0
  28. data/spec/fixtures/ejbca/sample-scep-request.pkcs7 +0 -0
  29. data/spec/fixtures/ejbca/subca.crt +20 -0
  30. data/spec/fixtures/ejbca/subca.key +27 -0
  31. data/spec/fixtures/ejbca/subca.p12.base64 +75 -0
  32. data/spec/fixtures/ejbca/superadmin.key +27 -0
  33. data/spec/fixtures/foo.b64 +30 -0
  34. data/spec/integration/ejbca_spec.rb +79 -0
  35. data/spec/integration/jscep_cli_spec.rb +21 -0
  36. data/spec/lib/scep/pki_operation/base_spec.rb +32 -0
  37. data/spec/lib/scep/pki_operation/request_spec.rb +64 -8
  38. data/spec/spec_helper.rb +10 -2
  39. metadata +74 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ceb79fd8756349928c7653f5c59191e3cc8cbfe7
4
- data.tar.gz: 9f322dce3a3d7a45f7ae7c220d67b2908dc57380
3
+ metadata.gz: ad5f9fb037bd11d20202a13cccea4df7fae8bfc5
4
+ data.tar.gz: 3a65c1f2080b37093293cf42794127b9eeefac73
5
5
  SHA512:
6
- metadata.gz: 26c7b9378ffd100b39788cd61973e568b4413887bb6dac749ff68bb5d29419fb34028eade582235cd29970f9f27cdeeb39d73eb542ba011a0bddf4c5dc2f44fc
7
- data.tar.gz: c864e7169c4ab8403d706b294cd48bfc535d010807d5e793b7347bd5463659095ea702db69cef2be1c2956afab5400c4e435b4d3a5d0809c220a972018b87d43
6
+ metadata.gz: 0180abbc2c0b712c577c2cdd3542448666ebaf03db74bcceef19ebd3f7079592f66bf24945da2940faf33fd3db10f58252279043c080b4ffdc21d48fd2d60a80
7
+ data.tar.gz: 5cb798cd5f3267efd6d9ad78c33cbac8b30cb6ff0d03ea201787fcd12ea863dda74b36c1a84b3fb322b65b9e2b4a735f1ba8d03a81b48349fa8a06327e503dd0
data/.gitignore CHANGED
@@ -13,3 +13,4 @@
13
13
  *.a
14
14
  mkmf.log
15
15
  .idea
16
+ .DS_Store
@@ -1,6 +1,10 @@
1
1
  language: ruby
2
2
  cache: bundler
3
+ addons:
4
+ code_climate:
5
+ repo_token: 3feb9a3ab131bce3ab5393ca281d31ad367d7b87feaaa02dd60ec5e7f3c57d6d
3
6
  rvm:
4
7
  - 1.8.7
8
+ - 1.9.3
5
9
  - 2.2.1
6
- script: bundle exec rspec
10
+ script: bundle exec rspec spec/lib
@@ -0,0 +1,3 @@
1
+ --markup markdown
2
+ --protected
3
+ --private
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  SCEP Gem
2
2
  ========
3
+ [![Build Status](https://travis-ci.org/onelogin/scep-gem.svg?branch=master)](https://travis-ci.org/onelogin/scep-gem) [![Code Climate](https://codeclimate.com/github/onelogin/scep-gem/badges/gpa.svg)](https://codeclimate.com/github/onelogin/scep-gem) [![Test Coverage](https://codeclimate.com/github/onelogin/scep-gem/badges/coverage.svg)](https://codeclimate.com/github/onelogin/scep-gem/coverage)
4
+
3
5
  Libraries that allow you to be a SCEP server, be a SCEP proxy, etc.
4
6
 
5
7
  If you believe you have discovered a security vulnerability in this gem, please email security@onelogin.com with a description. You can also use the form based submission located here: https://www.onelogin.com/security. We follow responsible disclosure guidelines, and will work with you to quickly find a resolution.
@@ -23,7 +25,7 @@ When we want to forward a CSR to a RA. We may or may not be an RA ourselves.
23
25
  First,collect some certificates:
24
26
 
25
27
  ```ruby
26
- their_ra_cert = OpenSSL::X509::Certificate.new File.read(their-ra.crt')
28
+ their_ra_cert = OpenSSL::X509::Certificate.new File.read('their-ra.crt')
27
29
  our_keypair = SCEP::Keypair.read 'our.crt', 'our.key'
28
30
  csr = OpenSSL::X509::Request.new File.read('some.csr')
29
31
  ```
@@ -142,3 +144,19 @@ post '/scep?operation=PKIOperation' do
142
144
  render results.p7enc_response.to_der
143
145
  end
144
146
  ```
147
+
148
+ ### EJBCA Support
149
+ EJBCA supports the SCEP specification rigorously. This requires tampering with the ASN1 format of PKCS#7. To
150
+ solve this, use the following code for SCEP requests:
151
+
152
+ ```ruby
153
+ request = SCEP::PKIOperation::Request.new(@keypair)
154
+ request.tamper_scep_message_type = true
155
+ # send request
156
+ ```
157
+
158
+ EJBCA should accept this message. However, this MAY break verifications for other SCEP endpoints. Until this issue
159
+ is fixed, it is suggested you avoid using this unless you absolutely have to.
160
+
161
+ ## License
162
+ This gem is released under the [MIT License](http://opensource.org/licenses/MIT)
@@ -1,5 +1,6 @@
1
1
  require 'logger'
2
2
  require 'openssl'
3
+ require 'openssl-extensions/all'
3
4
 
4
5
  require 'scep/version'
5
6
 
@@ -8,10 +9,7 @@ module SCEP
8
9
  autoload :PKIOperation, 'scep/pki_operation'
9
10
  autoload :PKCS7CertOnly, 'scep/pkcs7_cert_only'
10
11
  autoload :Keypair, 'scep/keypair'
11
-
12
- # Allows backwards-compatibility between ruby 1.8.7 and newer versions
13
- # @return [OpenSSL::PKCS7]
14
- PKCS7 = defined?(OpenSSL::PKCS7::PKCS7) ? OpenSSL::PKCS7::PKCS7 : OpenSSL::PKCS7
12
+ autoload :ASN1, 'scep/asn1'
15
13
 
16
14
  class << self
17
15
 
@@ -0,0 +1,38 @@
1
+ # Add OpenSSL ASN1 objects here as needed
2
+
3
+ OpenSSL::ASN1::ObjectId.register('2.16.840.1.113733.1.9.2', 'messageType', 'scep-messageType')
4
+
5
+
6
+ module SCEP
7
+
8
+ # Re-usable ASN1 compnents for some of the finer points of SCEP
9
+ module ASN1
10
+
11
+ MESSAGE_TYPE_PKCS_REQ = 19
12
+
13
+ # Pre-made ASN1 value that identifies what type of message this is
14
+ def self.message_type(type = MESSAGE_TYPE_PKCS_REQ)
15
+ OpenSSL::ASN1::Sequence.new([
16
+ OpenSSL::ASN1::ObjectId.new('scep-messageType'),
17
+ OpenSSL::ASN1::Set.new([
18
+ OpenSSL::ASN1::PrintableString.new(type.to_s)
19
+ ])
20
+ ])
21
+ end
22
+
23
+ def self.pkcs7_signature_hash(hash, algorithm_name)
24
+ OpenSSL::ASN1::Sequence.new([
25
+ OpenSSL::ASN1::Sequence.new([
26
+ OpenSSL::ASN1::ObjectId.new(algorithm_name),
27
+ OpenSSL::ASN1::Null.new(nil)
28
+ ]),
29
+ OpenSSL::ASN1::OctetString.new(hash)
30
+ ])
31
+ end
32
+
33
+ def self.calculate_and_generate_pkcs7_signature_hash(data, algorithm)
34
+ hash = OpenSSL::Digest.digest(algorithm, data)
35
+ pkcs7_signature_hash(hash, algorithm)
36
+ end
37
+ end
38
+ end
@@ -114,6 +114,8 @@ module SCEP
114
114
  end
115
115
 
116
116
  if response.code != 200
117
+ logger.debug "Response body:"
118
+ logger.debug response.body
117
119
  raise ProtocolError, "SCEP request returned non-200 code of #{response.code}"
118
120
  end
119
121
 
@@ -0,0 +1,26 @@
1
+ module SCEP
2
+ class JSCEPCli
3
+ include SCEP::Loggable
4
+ autoload :Request, 'scep/jscep_cli/request'
5
+
6
+ BUNDLED_JSCEP_CLI_JAR_PATH = File.join(File.dirname(__FILE__), '..', '..', 'bin', 'jscepcli-1.0.jar')
7
+
8
+ attr_accessor :jarfile
9
+
10
+ attr_accessor :java_executable
11
+
12
+ def initialize(java_executable = 'java', jarfile = BUNDLED_JSCEP_CLI_JAR_PATH)
13
+ @jarfile = jarfile
14
+ @java_executable = java_executable
15
+ end
16
+
17
+ # @param request [SCEP::JSCEPCli::Request] the request to forward
18
+ def forward(request)
19
+ logger.info "Making JSCEP CLI request to #{request.url}"
20
+ cmd = "#{java_executable} -jar #{jarfile} #{request.to_cli_arguments}"
21
+ logger.debug "Executing command: #{cmd}"
22
+ system cmd
23
+ end
24
+
25
+ end
26
+ end
@@ -22,6 +22,10 @@ module SCEP
22
22
  raise ArgumentError, '`certificate` must be an OpenSSL::X509::Certificate' unless
23
23
  certificate.is_a?(OpenSSL::X509::Certificate)
24
24
 
25
+ unless certificate.check_private_key(private_key)
26
+ raise ArgumentError, '`private_key` does not match `certificate`'
27
+ end
28
+
25
29
  @certificate = certificate
26
30
  @private_key = private_key
27
31
  end
@@ -7,6 +7,8 @@ module SCEP
7
7
  # * {#ra_private_key RA Private Key}
8
8
  #
9
9
  class Base
10
+ include SCEP::Loggable
11
+
10
12
  DEFAULT_CIPHER_ALGORITHM = 'aes-256-cbc'
11
13
 
12
14
  # Our keypair
@@ -71,6 +73,7 @@ module SCEP
71
73
 
72
74
  # Decrypt
73
75
  @p7enc = OpenSSL::PKCS7.new(@p7sign.data)
76
+ check_if_recipient_matches_ra_certificate_name(@p7enc)
74
77
  @p7enc.decrypt(ra_keypair.private_key, ra_keypair.certificate, OpenSSL::PKCS7::BINARY)
75
78
  end
76
79
 
@@ -105,6 +108,28 @@ module SCEP
105
108
 
106
109
  protected
107
110
 
111
+ def check_if_recipient_matches_ra_certificate_name(p7enc)
112
+ if p7enc.recipients.nil? || p7enc.recipients.empty?
113
+ logger.warn 'SCEP request does not have any recipient info - ' \
114
+ 'cannot determine if SCEP request is intended for us'
115
+ return false
116
+ end
117
+
118
+ matched = false
119
+ names = p7enc.recipients.map(&:issuer).each do |name|
120
+ if name.cmp(ra_keypair.certificate.subject) == 0
121
+ matched = true
122
+ break
123
+ end
124
+ end
125
+
126
+ unless matched
127
+ logger.warn 'SCEP request does not appear to be addressed to us! ' \
128
+ "RA Cert: #{ra_keypair.certificate.subject.to_s}, Recipients: [#{names.map(&:to_s).join(', ')}]"
129
+ end
130
+ matched
131
+ end
132
+
108
133
  # Same as `Array.wrap`
109
134
  # @see http://apidock.com/rails/Array/wrap/class
110
135
  def wrap_array(object)
@@ -4,6 +4,9 @@ module SCEP
4
4
 
5
5
  # Handles decoding or creation of a scep CSR request.
6
6
  #
7
+ # ## EJBCA Support
8
+ # This requires tampering of the SCEP request. Please see {#tamper_scep_message_type}
9
+ #
7
10
  # @example Get Certificates Ready
8
11
  # ra_cert = SCEP::DEFAULT_RA_CERTIFICATE
9
12
  # ra_key = SCEP::DEFAULT_RA_PRIVATE_KEY
@@ -37,6 +40,64 @@ module SCEP
37
40
  # @return [OpenSSL::X509::Request]
38
41
  attr_accessor :csr
39
42
 
43
+ # Whether we should tamper with the SCEP message type. This is **required** to work with some SCEP
44
+ # implementations, but this may cause verification to fail. Only affects encryption.
45
+ # @example Without Tampering
46
+ # request = SCEP::PKIOperation::Request.new(keypair)
47
+ # encrypted = request.encrypt(another_keypair)
48
+ #
49
+ # # Here, `encrypted` will not be accepted by EJBCA, but ruby will parse it just fine
50
+ # p7sign = OpenSSL::PKCS7.new(encrypted)
51
+ # verified = p7sign.verify([keypair.certificate], nil, nil)
52
+ # p verified # => true
53
+ #
54
+ # @example With Tampering
55
+ # request = SCEP::PKIOperation::Request.new(keypair)
56
+ # request.tamper_scep_message_type = true
57
+ # encrypted = request.encrypt(another_keypair)
58
+ #
59
+ # # Here, `encrypted` will be accepted by EJBCA, but rejected by ruby
60
+ # p7sign = OpenSSL::PKCS7.new(encrypted)
61
+ # verified = p7sign.verify([keypair.certificate], nil, nil)
62
+ # p verified # => false
63
+ #
64
+ # @todo Need to figure out how to re-calculate the SCEP extended attributes signature, which will make
65
+ # this obsolete!
66
+ # @return [Boolean] whether to tamper with the SCEP message type
67
+ attr_accessor :tamper_scep_message_type
68
+ alias_method :tamper_scep_message_type?, :tamper_scep_message_type
69
+
70
+ def initialize(ra_keypair)
71
+ super
72
+ @tamper_scep_message_type = false
73
+ end
74
+
75
+ # @return [Boolean] TRUE if the request has a challenge password, FALSE otherwise
76
+ def challenge_password?
77
+ csr && csr.challenge_password?
78
+ end
79
+
80
+ # Get the challenge password from the request, if any
81
+ # @return [String,nil] a STRING representation of the challenge password, NIL if there is
82
+ # no challenge password
83
+ def challenge_password
84
+ return nil unless challenge_password?
85
+ csr_challenge_password.value.value.first.value
86
+ end
87
+
88
+ # @todo: add code to set the challenge password
89
+ # def challenge_password=(password)
90
+ # return false if csr.blank?
91
+ # attribute = csr_challenge_password
92
+ # if attribute.blank?
93
+ # attribute = generate_challenge_password(password)
94
+ # csr.add_attribute(attribute)
95
+ # else
96
+ # binding.pry
97
+ # attribute.value.value.first.value = password
98
+ # end
99
+ # end
100
+
40
101
  # Decrypts a signed and encrypted csr. Sets {#csr} to the decrypted value
41
102
  # @param [String] signed_and_encrypted_csr the raw and encrypted
42
103
  # @param [Boolean] verify if TRUE, verifies against {#x509_store}. If FALSE, skips verification
@@ -54,7 +115,12 @@ module SCEP
54
115
  def encrypt(target_encryption_certs)
55
116
  raise ArgumentError, '#csr must be an OpenSSL::X509::Request' unless
56
117
  csr.is_a?(OpenSSL::X509::Request)
57
- sign_and_encrypt_raw(csr.to_der, target_encryption_certs)
118
+ p7enc = sign_and_encrypt_raw(csr.to_der, target_encryption_certs)
119
+ if tamper_scep_message_type?
120
+ logger.info 'Tampering SCEP message type - request may be rejected by RA'
121
+ p7enc = add_scep_message_type(p7enc)
122
+ end
123
+ p7enc
58
124
  end
59
125
 
60
126
  # Decrypts a signed and encrypted payload and then re-encrypts it. {#csr} will contain the CSR object
@@ -65,6 +131,61 @@ module SCEP
65
131
  decrypt(signed_and_encrypted_csr, verify)
66
132
  encrypt(target_encryption_certs)
67
133
  end
134
+
135
+ protected
136
+
137
+ # Gets the challenge password from the CSR
138
+ def csr_challenge_password
139
+ csr.send(:read_attributes_by_oid, 'challengePassword')
140
+ end
141
+
142
+ # Adds a required message type to the PKCS7 request. I can't believe I'm doing this...
143
+ #
144
+ # Take a look at https://tools.ietf.org/html/draft-nourse-scep-11. Here, we're adding the
145
+ # signerInfo/messageType of "PKCSReq" inside of the "Signed PKCSReq."
146
+ #
147
+ # @param [OpenSSL::PKCS7] pkcs7 a pkcs7 message
148
+ # @return [OpenSSL::PKCS7] a new pkcs7 message with the proper scep message type
149
+ # @note Don't tamper with the signer info once you've used this method!
150
+ def add_scep_message_type(pkcs7)
151
+ asn1 = OpenSSL::ASN1.decode(pkcs7.to_der)
152
+ pkcs_cert_resp_signed = asn1.value[1].value[0]
153
+ signer_info = pkcs_cert_resp_signed.value[4].value[0]
154
+ authenticated_attributes = signer_info.value[3]
155
+ authenticated_attributes.value << SCEP::ASN1.message_type(SCEP::ASN1::MESSAGE_TYPE_PKCS_REQ)
156
+ # todo: broken?? --
157
+ # recalculate_authenticated_attributes_digest(signer_info)
158
+ return OpenSSL::PKCS7.new(asn1.to_der)
159
+ end
160
+
161
+ # todo: this currently does not work! Kept here for future purposes
162
+ def recalculate_authenticated_attributes_digest(signer_info)
163
+ digest_algorithm = signer_info.value[2].value[0].sn # => "SHA256"
164
+
165
+ # This is where this is not working - we need to hash the "authenticatedAttributes",
166
+ # but this does not appear to be hashing the correct thing!
167
+ authenticated_attributes = signer_info.value[3]
168
+
169
+ new_digest = SCEP::ASN1.calculate_and_generate_pkcs7_signature_hash(
170
+ authenticated_attributes.to_der,
171
+ digest_algorithm)
172
+
173
+ encrypted_digest = ra_keypair.private_key.private_encrypt(new_digest.to_der)
174
+ signer_info.value.last.value = encrypted_digest
175
+ end
176
+
177
+ # Takes a password and generates an attribute
178
+ # @param password [String] what the challenge password should be
179
+ # @return [OpenSSL::X509::Attribute]
180
+ # @todo: This does not currently work!
181
+ # def self.generate_challenge_password(password)
182
+ # attribute = OpenSSL::X509::Attribute.new('challengePassword')
183
+ # attribute.value = OpenSSL::ASN1::Set.new([
184
+ # OpenSSL::ASN1::PrintableString.new(password.to_s)
185
+ # ])
186
+ # attribute
187
+ # end
188
+
68
189
  end
69
190
  end
70
191
  end
@@ -1,3 +1,3 @@
1
1
  module SCEP
2
- VERSION = '0.0.1'
2
+ VERSION = '0.0.2'
3
3
  end
@@ -11,17 +11,20 @@ Gem::Specification.new do |spec|
11
11
  spec.summary = %q{SCEP libraries}
12
12
  spec.description = %q{Makes development of SCEP services easier}
13
13
  spec.homepage = 'https://github.com/onelogin/scep-gem'
14
- spec.license = 'Proprietary'
14
+ spec.license = 'MIT'
15
15
 
16
16
  spec.files = `git ls-files -z`.split("\x0")
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
+ spec.add_dependency 'openssl-extensions'
22
+
21
23
  if RUBY_VERSION < '1.9'
22
24
  spec.add_dependency 'httparty', '<= 0.11'
23
25
  else
24
26
  spec.add_dependency 'httparty'
27
+ spec.add_development_dependency 'codeclimate-test-reporter'
25
28
  end
26
29
 
27
30
  spec.add_development_dependency 'bundler', '~> 1.7'
@@ -1,7 +1,9 @@
1
1
  #!/usr/bin/env ruby
2
+ require 'rubygems'
2
3
  require 'bundler'
3
4
  Bundler.require :default
4
5
  require 'scep'
5
6
  require 'pry'
7
+ require './spec/spec_helper'
6
8
 
7
9
  pry
@@ -0,0 +1,20 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDUTCCAjmgAwIBAgIIDUmm3traB2EwDQYJKoZIhvcNAQELBQAwOzEVMBMGA1UE
3
+ AwwMTWFuYWdlbWVudENBMRUwEwYDVQQKDAxFSkJDQSBTYW1wbGUxCzAJBgNVBAYT
4
+ AlNFMB4XDTE0MTAyMDIxMjYyMFoXDTE2MTAxOTIxMjYyMFowFTETMBEGA1UEAwwK
5
+ U3VwZXJBZG1pbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIW5crVk
6
+ NX759XMuPJKda3DbhP3/3uPHBwN05GHN1qw4/BvUoZthDW53/0Myskv1MY0lAUHs
7
+ UCLdLUQBEzsX/wLfRNDAfmcnNbRvzm5LccZrrWrEgvvQD0lGeQazX75V5QM+fkUh
8
+ rty9W7QVFEM5pQ773JD0uuo+JcO0TEqfIMg4YguZlF+FmUOc/j7Himm89Fo4HFtA
9
+ ROBhZf2L+vroktl7/RK4AoFPdtTCszhQJnBy1x1WyWkmV9tt7lNS5XJrRCOdZ5aM
10
+ JNN0A+/ySjGd3ASu2l0H8dIMkcjmHSgSPs8DQpq3xg75wIqDp3PZX4T+KBpBVl4Q
11
+ lb2m8josfw5rdGUCAwEAAaN/MH0wHQYDVR0OBBYEFHBewXga2nNj/pGhkjNDC4sN
12
+ AlerMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUPW27M+6uIGgi3cf1zgBipX/F
13
+ I8swDgYDVR0PAQH/BAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
14
+ BDANBgkqhkiG9w0BAQsFAAOCAQEAeb/8j8/rAMRO6I7XM3rX3wq5ZBBQIWi9Sy6/
15
+ fJhQo+T7MXpgnN5bx5BS9ebeC3kvPDhfSF+bCr+MT/mvnkh4/aybuJweZtP4GZiU
16
+ 0GC2gIu6syccdF0TTMawjbX7s7Q3i/7ysKH6D2V1fSJC9Td6cIdKSNytDPdZlCLZ
17
+ xbPQQYC0tj7AQ8Nj+kx3VI3bWEoD8C2AyecoKfANvRU7oiWGUT/j5UvnzU6dpVbE
18
+ DwcZMHnmDGWAh1WpVOGjSrzg1nEiYvPwDfdPBYfF9HLkCOXMvZEOTdDuEHdSvYSq
19
+ MXoCf9aY0dc8wbZbYUP5bdWR/1qb81rQfPoaZ5/4MSdh3GXyvg==
20
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEpQIBAAKCAQEAhblytWQ1fvn1cy48kp1rcNuE/f/e48cHA3TkYc3WrDj8G9Sh
3
+ m2ENbnf/QzKyS/UxjSUBQexQIt0tRAETOxf/At9E0MB+Zyc1tG/ObktxxmutasSC
4
+ +9APSUZ5BrNfvlXlAz5+RSGu3L1btBUUQzmlDvvckPS66j4lw7RMSp8gyDhiC5mU
5
+ X4WZQ5z+PseKabz0WjgcW0BE4GFl/Yv6+uiS2Xv9ErgCgU921MKzOFAmcHLXHVbJ
6
+ aSZX223uU1LlcmtEI51nlowk03QD7/JKMZ3cBK7aXQfx0gyRyOYdKBI+zwNCmrfG
7
+ DvnAioOnc9lfhP4oGkFWXhCVvabyOix/Dmt0ZQIDAQABAoIBACRp6ViHnyGigzoI
8
+ Hyp1f2pN/JsF7/XqnnhMflw7pvdi1RPnBNLAzN2GA5aS2YZhkEq1BvCinve/brIT
9
+ 8N6onCJ2FdEaedExFii6QWY7WRIFBEYMmPZlI6R6cj5m3e2Aikol3FCK6Yjmb3BM
10
+ RSZBLjc0Uk2Ots9OeQ4frJ6tUkny23W3GO8H7X4jqRtRiPgm+CkSMB7YbnL0P/8u
11
+ 4dv5+qzVi73nXL4pN+L0O/3N52pnxoFEbqzLvzvALKQNz6ISxOCGHbHRnjcoiRCA
12
+ aoaq+MWBa3JJcYEM1inntIBwyILaf5Vf2LhyyVBoHpDtKx7PdH2BHLSX4FsAH1kP
13
+ HzqKfokCgYEAyMNZQBkE2nyj7hh1auIWTtTZJl2qr3o+9+ZaxWIJ0GdkP5ndpRSJ
14
+ N3IaJcDcCbX1trTNlwVvaDSFRRTY7WERdXp994xqbHFTSIrXkKUEopZmB8Q5atHo
15
+ Kf6De6GCwic3mEkkvNdjeyJTQRmOt2R5CgioNfgUV0GibXjuZt9/rM8CgYEAqoRD
16
+ N7LLgOu8n9COtkzAYH4UJjQWU0cNpRjmqHWOIa86TZ44WAJkjsvrgFN6WV/edVgc
17
+ opP+X6LJNhuyotTskjidjio3hiozUeMlhrH1wd+FUOThLcSTu8ixx9MWM3kEPEtx
18
+ YaKbfv/LbRRvfnDfRWrjB1s34HR+eW8gFKjFYIsCgYEAu1FpiODPInyBB7pSc/OX
19
+ FN6L7bwfcbMB5ZNMxjX/KjAN3TnXEBvlG5KeyvLzWywnot13pZ0woW2/mwEklfen
20
+ rpEnzz14Xs4uAtVo5FDTzk+9yylO2VgY4nXSgBvmQPkOakx0tq3Q6CbSvz71Zi+c
21
+ r7v8Fr7tW6ylvLbE2b9XBQkCgYEAgoLDM/FsY1uLPsMRSCTMpc46O9doMwtSPUgm
22
+ 209Gny+QL3Jna61BLC6WLN036wo+qY/sMt+VNbvRx9FBU/Ims/ATX4mef9jy+L0j
23
+ rsms8VvUnUrhsvcfn/4HXIuLFZCNllykBnfADl9YYz/d6mgX6/jYlXvS88AWQXm1
24
+ kzpt/+sCgYEAtcZXruPcTc+IYvTIhn7hEL+/Osw+ZFRlSOTAnkGtgWl+fbI/EI7H
25
+ NtgvbZWFS+x5HeMFFlv7W/jTZW67HDlg4d+q7A4EoiS3rWJwAeYS2MKUn6B2vPEd
26
+ SolJW17YVSB0l4iAHUf6Ew32/rr/VeX48gKvS+CiuQNB7Tp5SnnKuBw=
27
+ -----END RSA PRIVATE KEY-----