ruby-saml 1.16.0 → 1.18.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 +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/test.yml +49 -3
- data/CHANGELOG.md +31 -8
- data/README.md +96 -69
- data/UPGRADING.md +9 -0
- data/lib/onelogin/ruby-saml/authrequest.rb +7 -8
- data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +6 -8
- data/lib/onelogin/ruby-saml/logoutrequest.rb +6 -6
- data/lib/onelogin/ruby-saml/logoutresponse.rb +2 -1
- data/lib/onelogin/ruby-saml/metadata.rb +21 -25
- data/lib/onelogin/ruby-saml/response.rb +116 -52
- data/lib/onelogin/ruby-saml/saml_message.rb +21 -11
- data/lib/onelogin/ruby-saml/settings.rb +132 -31
- data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +7 -6
- data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +7 -7
- data/lib/onelogin/ruby-saml/utils.rb +86 -22
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/lib/xml_security.rb +116 -36
- data/ruby-saml.gemspec +6 -0
- metadata +4 -3
@@ -55,13 +55,14 @@ module OneLogin
|
|
55
55
|
attr_accessor :compress_response
|
56
56
|
attr_accessor :double_quote_xml_attribute_values
|
57
57
|
attr_accessor :message_max_bytesize
|
58
|
+
attr_accessor :check_malformed_doc
|
58
59
|
attr_accessor :passive
|
59
60
|
attr_reader :protocol_binding
|
60
61
|
attr_accessor :attributes_index
|
61
62
|
attr_accessor :force_authn
|
62
63
|
attr_accessor :certificate
|
63
|
-
attr_accessor :certificate_new
|
64
64
|
attr_accessor :private_key
|
65
|
+
attr_accessor :sp_cert_multi
|
65
66
|
attr_accessor :authn_context
|
66
67
|
attr_accessor :authn_context_comparison
|
67
68
|
attr_accessor :authn_context_decl_ref
|
@@ -70,6 +71,7 @@ module OneLogin
|
|
70
71
|
attr_accessor :security
|
71
72
|
attr_accessor :soft
|
72
73
|
# Deprecated
|
74
|
+
attr_accessor :certificate_new
|
73
75
|
attr_accessor :assertion_consumer_logout_service_url
|
74
76
|
attr_reader :assertion_consumer_logout_service_binding
|
75
77
|
attr_accessor :issuer
|
@@ -180,10 +182,7 @@ module OneLogin
|
|
180
182
|
# @return [OpenSSL::X509::Certificate|nil] Build the IdP certificate from the settings (previously format it)
|
181
183
|
#
|
182
184
|
def get_idp_cert
|
183
|
-
|
184
|
-
|
185
|
-
formatted_cert = OneLogin::RubySaml::Utils.format_cert(idp_cert)
|
186
|
-
OpenSSL::X509::Certificate.new(formatted_cert)
|
185
|
+
OneLogin::RubySaml::Utils.build_cert_object(idp_cert)
|
187
186
|
end
|
188
187
|
|
189
188
|
# @return [Hash with 2 arrays of OpenSSL::X509::Certificate] Build multiple IdP certificates from the settings.
|
@@ -191,7 +190,7 @@ module OneLogin
|
|
191
190
|
def get_idp_cert_multi
|
192
191
|
return nil if idp_cert_multi.nil? || idp_cert_multi.empty?
|
193
192
|
|
194
|
-
raise ArgumentError.new("Invalid value for idp_cert_multi")
|
193
|
+
raise ArgumentError.new("Invalid value for idp_cert_multi") unless idp_cert_multi.is_a?(Hash)
|
195
194
|
|
196
195
|
certs = {:signing => [], :encryption => [] }
|
197
196
|
|
@@ -200,49 +199,70 @@ module OneLogin
|
|
200
199
|
next if !certs_for_type || certs_for_type.empty?
|
201
200
|
|
202
201
|
certs_for_type.each do |idp_cert|
|
203
|
-
|
204
|
-
certs[type].push(OpenSSL::X509::Certificate.new(formatted_cert))
|
202
|
+
certs[type].push(OneLogin::RubySaml::Utils.build_cert_object(idp_cert))
|
205
203
|
end
|
206
204
|
end
|
207
205
|
|
208
206
|
certs
|
209
207
|
end
|
210
208
|
|
211
|
-
# @return [OpenSSL::X509::Certificate
|
212
|
-
#
|
213
|
-
|
214
|
-
|
209
|
+
# @return [Hash<Symbol, Array<Array<OpenSSL::X509::Certificate, OpenSSL::PKey::RSA>>>]
|
210
|
+
# Build the SP certificates and private keys from the settings. If
|
211
|
+
# check_sp_cert_expiration is true, only returns certificates and private keys
|
212
|
+
# that are not expired.
|
213
|
+
def get_sp_certs
|
214
|
+
certs = get_all_sp_certs
|
215
|
+
return certs unless security[:check_sp_cert_expiration]
|
215
216
|
|
216
|
-
|
217
|
-
|
217
|
+
active_certs = { signing: [], encryption: [] }
|
218
|
+
certs.each do |use, pairs|
|
219
|
+
next if pairs.empty?
|
218
220
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
221
|
+
pairs = pairs.select { |cert, _| !cert || OneLogin::RubySaml::Utils.is_cert_active(cert) }
|
222
|
+
raise OneLogin::RubySaml::ValidationError.new("The SP certificate expired.") if pairs.empty?
|
223
|
+
|
224
|
+
active_certs[use] = pairs.freeze
|
223
225
|
end
|
226
|
+
active_certs.freeze
|
227
|
+
end
|
224
228
|
|
225
|
-
|
229
|
+
# @return [Array<OpenSSL::X509::Certificate, OpenSSL::PKey::RSA>]
|
230
|
+
# The SP signing certificate and private key.
|
231
|
+
def get_sp_signing_pair
|
232
|
+
get_sp_certs[:signing].first
|
226
233
|
end
|
227
234
|
|
228
|
-
# @return [OpenSSL::X509::Certificate
|
229
|
-
#
|
230
|
-
def
|
231
|
-
|
235
|
+
# @return [OpenSSL::X509::Certificate] The SP signing certificate.
|
236
|
+
# @deprecated Use get_sp_signing_pair or get_sp_certs instead.
|
237
|
+
def get_sp_cert
|
238
|
+
node = get_sp_signing_pair
|
239
|
+
node[0] if node
|
240
|
+
end
|
232
241
|
|
233
|
-
|
234
|
-
|
242
|
+
# @return [OpenSSL::PKey::RSA] The SP signing key.
|
243
|
+
def get_sp_signing_key
|
244
|
+
node = get_sp_signing_pair
|
245
|
+
node[1] if node
|
235
246
|
end
|
236
247
|
|
237
|
-
# @
|
238
|
-
|
239
|
-
def get_sp_key
|
240
|
-
return nil if private_key.nil? || private_key.empty?
|
248
|
+
# @deprecated Use get_sp_signing_key or get_sp_certs instead.
|
249
|
+
alias_method :get_sp_key, :get_sp_signing_key
|
241
250
|
|
242
|
-
|
243
|
-
|
251
|
+
# @return [Array<OpenSSL::PKey::RSA>] The SP decryption keys.
|
252
|
+
def get_sp_decryption_keys
|
253
|
+
ary = get_sp_certs[:encryption].map { |pair| pair[1] }
|
254
|
+
ary.compact!
|
255
|
+
ary.uniq!(&:to_pem)
|
256
|
+
ary.freeze
|
244
257
|
end
|
245
258
|
|
259
|
+
# @return [OpenSSL::X509::Certificate|nil] Build the New SP certificate from the settings.
|
260
|
+
#
|
261
|
+
# @deprecated Use get_sp_certs instead
|
262
|
+
def get_sp_cert_new
|
263
|
+
node = get_sp_certs[:signing].last
|
264
|
+
node[0] if node
|
265
|
+
end
|
246
266
|
|
247
267
|
def idp_binding_from_embed_sign
|
248
268
|
security[:embed_sign] ? Utils::BINDINGS[:post] : Utils::BINDINGS[:redirect]
|
@@ -262,7 +282,9 @@ module OneLogin
|
|
262
282
|
:compress_response => true,
|
263
283
|
:message_max_bytesize => 250000,
|
264
284
|
:soft => true,
|
285
|
+
:check_malformed_doc => true,
|
265
286
|
:double_quote_xml_attribute_values => false,
|
287
|
+
|
266
288
|
:security => {
|
267
289
|
:authn_requests_signed => false,
|
268
290
|
:logout_requests_signed => false,
|
@@ -280,6 +302,85 @@ module OneLogin
|
|
280
302
|
:lowercase_url_encoding => false
|
281
303
|
}.freeze
|
282
304
|
}.freeze
|
305
|
+
|
306
|
+
private
|
307
|
+
|
308
|
+
# @return [Hash<Symbol, Array<Array<OpenSSL::X509::Certificate, OpenSSL::PKey::RSA>>>]
|
309
|
+
# Build the SP certificates and private keys from the settings. Returns all
|
310
|
+
# certificates and private keys, even if they are expired.
|
311
|
+
def get_all_sp_certs
|
312
|
+
validate_sp_certs_params!
|
313
|
+
get_sp_certs_multi || get_sp_certs_single
|
314
|
+
end
|
315
|
+
|
316
|
+
# Validate certificate, certificate_new, private_key, and sp_cert_multi params.
|
317
|
+
def validate_sp_certs_params!
|
318
|
+
multi = sp_cert_multi && !sp_cert_multi.empty?
|
319
|
+
cert = certificate && !certificate.empty?
|
320
|
+
cert_new = certificate_new && !certificate_new.empty?
|
321
|
+
pk = private_key && !private_key.empty?
|
322
|
+
if multi && (cert || cert_new || pk)
|
323
|
+
raise ArgumentError.new("Cannot specify both sp_cert_multi and certificate, certificate_new, private_key parameters")
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
# Get certs from certificate, certificate_new, and private_key parameters.
|
328
|
+
def get_sp_certs_single
|
329
|
+
certs = { :signing => [], :encryption => [] }
|
330
|
+
|
331
|
+
sp_key = OneLogin::RubySaml::Utils.build_private_key_object(private_key)
|
332
|
+
cert = OneLogin::RubySaml::Utils.build_cert_object(certificate)
|
333
|
+
if cert || sp_key
|
334
|
+
ary = [cert, sp_key].freeze
|
335
|
+
certs[:signing] << ary
|
336
|
+
certs[:encryption] << ary
|
337
|
+
end
|
338
|
+
|
339
|
+
cert_new = OneLogin::RubySaml::Utils.build_cert_object(certificate_new)
|
340
|
+
if cert_new
|
341
|
+
ary = [cert_new, sp_key].freeze
|
342
|
+
certs[:signing] << ary
|
343
|
+
certs[:encryption] << ary
|
344
|
+
end
|
345
|
+
|
346
|
+
certs
|
347
|
+
end
|
348
|
+
|
349
|
+
# Get certs from get_sp_cert_multi parameter.
|
350
|
+
def get_sp_certs_multi
|
351
|
+
return if sp_cert_multi.nil? || sp_cert_multi.empty?
|
352
|
+
|
353
|
+
raise ArgumentError.new("sp_cert_multi must be a Hash") unless sp_cert_multi.is_a?(Hash)
|
354
|
+
|
355
|
+
certs = { :signing => [], :encryption => [] }.freeze
|
356
|
+
|
357
|
+
[:signing, :encryption].each do |type|
|
358
|
+
certs_for_type = sp_cert_multi[type] || sp_cert_multi[type.to_s]
|
359
|
+
next if !certs_for_type || certs_for_type.empty?
|
360
|
+
|
361
|
+
unless certs_for_type.is_a?(Array) && certs_for_type.all? { |cert| cert.is_a?(Hash) }
|
362
|
+
raise ArgumentError.new("sp_cert_multi :#{type} node must be an Array of Hashes")
|
363
|
+
end
|
364
|
+
|
365
|
+
certs_for_type.each do |pair|
|
366
|
+
cert = pair[:certificate] || pair['certificate'] || pair[:cert] || pair['cert']
|
367
|
+
key = pair[:private_key] || pair['private_key'] || pair[:key] || pair['key']
|
368
|
+
|
369
|
+
unless cert && key
|
370
|
+
raise ArgumentError.new("sp_cert_multi :#{type} node Hashes must specify keys :certificate and :private_key")
|
371
|
+
end
|
372
|
+
|
373
|
+
certs[type] << [
|
374
|
+
OneLogin::RubySaml::Utils.build_cert_object(cert),
|
375
|
+
OneLogin::RubySaml::Utils.build_private_key_object(key)
|
376
|
+
].freeze
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
certs.each { |_, ary| ary.freeze }
|
381
|
+
certs
|
382
|
+
end
|
283
383
|
end
|
284
384
|
end
|
285
385
|
end
|
386
|
+
|
@@ -91,16 +91,16 @@ module OneLogin
|
|
91
91
|
end
|
92
92
|
|
93
93
|
# Decrypts an EncryptedID element
|
94
|
-
# @param
|
94
|
+
# @param encrypted_id_node [REXML::Element] The EncryptedID element
|
95
95
|
# @return [REXML::Document] The decrypted EncrypedtID element
|
96
96
|
#
|
97
|
-
def decrypt_nameid(
|
97
|
+
def decrypt_nameid(encrypted_id_node)
|
98
98
|
|
99
|
-
if settings.nil? ||
|
100
|
-
raise ValidationError.new('An ' +
|
99
|
+
if settings.nil? || settings.get_sp_decryption_keys.empty?
|
100
|
+
raise ValidationError.new('An ' + encrypted_id_node.name + ' found and no SP private key found on the settings to decrypt it')
|
101
101
|
end
|
102
102
|
|
103
|
-
elem_plaintext = OneLogin::RubySaml::Utils.
|
103
|
+
elem_plaintext = OneLogin::RubySaml::Utils.decrypt_multi(encrypted_id_node, settings.get_sp_decryption_keys)
|
104
104
|
# If we get some problematic noise in the plaintext after decrypting.
|
105
105
|
# This quick regexp parse will grab only the Element and discard the noise.
|
106
106
|
elem_plaintext = elem_plaintext.match(/(.*<\/(\w+:)?NameID>)/m)[0]
|
@@ -238,7 +238,8 @@ module OneLogin
|
|
238
238
|
# @raise [ValidationError] if soft == false and validation fails
|
239
239
|
#
|
240
240
|
def validate_structure
|
241
|
-
|
241
|
+
check_malformed_doc = check_malformed_doc?(settings)
|
242
|
+
unless valid_saml?(document, soft, check_malformed_doc)
|
242
243
|
return append_error("Invalid SAML Logout Request. Not match the saml-schema-protocol-2.0.xsd")
|
243
244
|
end
|
244
245
|
|
@@ -70,7 +70,7 @@ module OneLogin
|
|
70
70
|
response_doc = create_logout_response_xml_doc(settings, request_id, logout_message, logout_status_code)
|
71
71
|
response_doc.context[:attribute_quote] = :quote if settings.double_quote_xml_attribute_values
|
72
72
|
|
73
|
-
response = ""
|
73
|
+
response = "".dup
|
74
74
|
response_doc.write(response)
|
75
75
|
|
76
76
|
Logging.debug "Created SLO Logout Response: #{response}"
|
@@ -78,9 +78,10 @@ module OneLogin
|
|
78
78
|
response = deflate(response) if settings.compress_response
|
79
79
|
base64_response = encode(response)
|
80
80
|
response_params = {"SAMLResponse" => base64_response}
|
81
|
+
sp_signing_key = settings.get_sp_signing_key
|
81
82
|
|
82
|
-
if settings.idp_slo_service_binding == Utils::BINDINGS[:redirect] && settings.security[:logout_responses_signed] &&
|
83
|
-
params['SigAlg']
|
83
|
+
if settings.idp_slo_service_binding == Utils::BINDINGS[:redirect] && settings.security[:logout_responses_signed] && sp_signing_key
|
84
|
+
params['SigAlg'] = settings.security[:signature_method]
|
84
85
|
url_string = OneLogin::RubySaml::Utils.build_query(
|
85
86
|
:type => 'SAMLResponse',
|
86
87
|
:data => base64_response,
|
@@ -88,7 +89,7 @@ module OneLogin
|
|
88
89
|
:sig_alg => params['SigAlg']
|
89
90
|
)
|
90
91
|
sign_algorithm = XMLSecurity::BaseDocument.new.algorithm(settings.security[:signature_method])
|
91
|
-
signature =
|
92
|
+
signature = sp_signing_key.sign(sign_algorithm.new, url_string)
|
92
93
|
params['Signature'] = encode(signature)
|
93
94
|
end
|
94
95
|
|
@@ -150,9 +151,8 @@ module OneLogin
|
|
150
151
|
|
151
152
|
def sign_document(document, settings)
|
152
153
|
# embed signature
|
153
|
-
|
154
|
-
|
155
|
-
cert = settings.get_sp_cert
|
154
|
+
cert, private_key = settings.get_sp_signing_pair
|
155
|
+
if settings.idp_slo_service_binding == Utils::BINDINGS[:post] && private_key && cert
|
156
156
|
document.sign_document(private_key, cert, settings.security[:signature_method], settings.security[:digest_method])
|
157
157
|
end
|
158
158
|
|
@@ -32,18 +32,28 @@ module OneLogin
|
|
32
32
|
(\d+)W # 8: Weeks
|
33
33
|
)
|
34
34
|
$)x.freeze
|
35
|
+
|
35
36
|
UUID_PREFIX = '_'
|
37
|
+
@@prefix = '_'
|
36
38
|
|
37
|
-
# Checks if the x509 cert provided is expired
|
38
|
-
#
|
39
|
-
# @param cert [Certificate] The x509 certificate
|
39
|
+
# Checks if the x509 cert provided is expired.
|
40
40
|
#
|
41
|
+
# @param cert [OpenSSL::X509::Certificate|String] The x509 certificate.
|
42
|
+
# @return [true|false] Whether the certificate is expired.
|
41
43
|
def self.is_cert_expired(cert)
|
42
|
-
if cert.is_a?(String)
|
43
|
-
|
44
|
-
|
44
|
+
cert = OpenSSL::X509::Certificate.new(cert) if cert.is_a?(String)
|
45
|
+
|
46
|
+
cert.not_after < Time.now
|
47
|
+
end
|
45
48
|
|
46
|
-
|
49
|
+
# Checks if the x509 cert provided has both started and has not expired.
|
50
|
+
#
|
51
|
+
# @param cert [OpenSSL::X509::Certificate|String] The x509 certificate.
|
52
|
+
# @return [true|false] Whether the certificate is currently active.
|
53
|
+
def self.is_cert_active(cert)
|
54
|
+
cert = OpenSSL::X509::Certificate.new(cert) if cert.is_a?(String)
|
55
|
+
now = Time.now
|
56
|
+
cert.not_before <= now && cert.not_after >= now
|
47
57
|
end
|
48
58
|
|
49
59
|
# Interprets a ISO8601 duration value relative to a given timestamp.
|
@@ -61,20 +71,26 @@ module OneLogin
|
|
61
71
|
matches = duration.match(DURATION_FORMAT)
|
62
72
|
|
63
73
|
if matches.nil?
|
64
|
-
raise
|
74
|
+
raise StandardError.new("Invalid ISO 8601 duration")
|
65
75
|
end
|
66
76
|
|
67
77
|
sign = matches[1] == '-' ? -1 : 1
|
68
78
|
|
69
79
|
durYears, durMonths, durDays, durHours, durMinutes, durSeconds, durWeeks =
|
70
|
-
matches[2..8].map
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
80
|
+
matches[2..8].map do |match|
|
81
|
+
if match
|
82
|
+
match = match.tr(',', '.').gsub(/\.0*\z/, '')
|
83
|
+
sign * (match.include?('.') ? match.to_f : match.to_i)
|
84
|
+
else
|
85
|
+
0
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
datetime = Time.at(timestamp).utc.to_datetime
|
90
|
+
datetime = datetime.next_year(durYears)
|
91
|
+
datetime = datetime.next_month(durMonths)
|
92
|
+
datetime = datetime.next_day((7*durWeeks) + durDays)
|
93
|
+
datetime.to_time.utc.to_i + (durHours * 3600) + (durMinutes * 60) + durSeconds
|
78
94
|
end
|
79
95
|
|
80
96
|
# Return a properly formatted x509 certificate
|
@@ -128,6 +144,28 @@ module OneLogin
|
|
128
144
|
"-----BEGIN #{key_label}-----\n#{key}\n-----END #{key_label}-----"
|
129
145
|
end
|
130
146
|
|
147
|
+
# Given a certificate string, return an OpenSSL::X509::Certificate object.
|
148
|
+
#
|
149
|
+
# @param cert [String] The original certificate
|
150
|
+
# @return [OpenSSL::X509::Certificate] The certificate object
|
151
|
+
#
|
152
|
+
def self.build_cert_object(cert)
|
153
|
+
return nil if cert.nil? || cert.empty?
|
154
|
+
|
155
|
+
OpenSSL::X509::Certificate.new(format_cert(cert))
|
156
|
+
end
|
157
|
+
|
158
|
+
# Given a private key string, return an OpenSSL::PKey::RSA object.
|
159
|
+
#
|
160
|
+
# @param cert [String] The original private key
|
161
|
+
# @return [OpenSSL::PKey::RSA] The private key object
|
162
|
+
#
|
163
|
+
def self.build_private_key_object(private_key)
|
164
|
+
return nil if private_key.nil? || private_key.empty?
|
165
|
+
|
166
|
+
OpenSSL::PKey::RSA.new(format_private_key(private_key))
|
167
|
+
end
|
168
|
+
|
131
169
|
# Build the Query String signature that will be used in the HTTP-Redirect binding
|
132
170
|
# to generate the Signature
|
133
171
|
# @param params [Hash] Parameters to build the Query String
|
@@ -199,7 +237,7 @@ module OneLogin
|
|
199
237
|
|
200
238
|
# Validate the Signature parameter sent on the HTTP-Redirect binding
|
201
239
|
# @param params [Hash] Parameters to be used in the validation process
|
202
|
-
# @option params [OpenSSL::X509::Certificate] cert The
|
240
|
+
# @option params [OpenSSL::X509::Certificate] cert The IDP public certificate
|
203
241
|
# @option params [String] sig_alg The SigAlg parameter
|
204
242
|
# @option params [String] signature The Signature parameter (base64 encoded)
|
205
243
|
# @option params [String] query_string The full GET Query String to be compared
|
@@ -216,6 +254,8 @@ module OneLogin
|
|
216
254
|
# @param status_message [Strig] StatusMessage value
|
217
255
|
# @return [String] The status error message
|
218
256
|
def self.status_error_msg(error_msg, raw_status_code = nil, status_message = nil)
|
257
|
+
error_msg = error_msg.dup
|
258
|
+
|
219
259
|
unless raw_status_code.nil?
|
220
260
|
if raw_status_code.include? "|"
|
221
261
|
status_codes = raw_status_code.split(' | ')
|
@@ -236,9 +276,29 @@ module OneLogin
|
|
236
276
|
error_msg
|
237
277
|
end
|
238
278
|
|
279
|
+
# Obtains the decrypted string from an Encrypted node element in XML,
|
280
|
+
# given multiple private keys to try.
|
281
|
+
# @param encrypted_node [REXML::Element] The Encrypted element
|
282
|
+
# @param private_keys [Array<OpenSSL::PKey::RSA>] The Service provider private key
|
283
|
+
# @return [String] The decrypted data
|
284
|
+
def self.decrypt_multi(encrypted_node, private_keys)
|
285
|
+
raise ArgumentError.new('private_keys must be specified') if !private_keys || private_keys.empty?
|
286
|
+
|
287
|
+
error = nil
|
288
|
+
private_keys.each do |key|
|
289
|
+
begin
|
290
|
+
return decrypt_data(encrypted_node, key)
|
291
|
+
rescue OpenSSL::PKey::PKeyError => e
|
292
|
+
error ||= e
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
raise(error) if error
|
297
|
+
end
|
298
|
+
|
239
299
|
# Obtains the decrypted string from an Encrypted node element in XML
|
240
|
-
# @param encrypted_node [REXML::Element]
|
241
|
-
# @param private_key
|
300
|
+
# @param encrypted_node [REXML::Element] The Encrypted element
|
301
|
+
# @param private_key [OpenSSL::PKey::RSA] The Service provider private key
|
242
302
|
# @return [String] The decrypted data
|
243
303
|
def self.decrypt_data(encrypted_node, private_key)
|
244
304
|
encrypt_data = REXML::XPath.first(
|
@@ -302,7 +362,7 @@ module OneLogin
|
|
302
362
|
|
303
363
|
# Obtains the deciphered text
|
304
364
|
# @param cipher_text [String] The ciphered text
|
305
|
-
# @param symmetric_key [String] The
|
365
|
+
# @param symmetric_key [String] The symmetric key used to encrypt the text
|
306
366
|
# @param algorithm [String] The encrypted algorithm
|
307
367
|
# @return [String] The deciphered text
|
308
368
|
def self.retrieve_plaintext(cipher_text, symmetric_key, algorithm)
|
@@ -344,11 +404,15 @@ module OneLogin
|
|
344
404
|
end
|
345
405
|
|
346
406
|
def self.set_prefix(value)
|
347
|
-
|
407
|
+
@@prefix = value
|
408
|
+
end
|
409
|
+
|
410
|
+
def self.prefix
|
411
|
+
@@prefix
|
348
412
|
end
|
349
413
|
|
350
414
|
def self.uuid
|
351
|
-
"#{
|
415
|
+
"#{prefix}" + (RUBY_VERSION < '1.9' ? "#{@@uuid_generator.generate}" : "#{SecureRandom.uuid}")
|
352
416
|
end
|
353
417
|
|
354
418
|
# Given two strings, attempt to match them as URIs using Rails' parse method. If they can be parsed,
|