scep 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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-----