Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
:param data: The Request data
:type data: dict
:param saml_type: The target URL the user should be redirected to
:type saml_type: string SAMLRequest | SAMLResponse
:param sign_algorithm: Signature algorithm method
:type sign_algorithm: string
"""
assert saml_type in ('SAMLRequest', 'SAMLResponse')
key = self.get_settings().get_sp_key()
if not key:
raise OneLogin_Saml2_Error(
"Trying to sign the %s but can't load the SP private key." % saml_type,
OneLogin_Saml2_Error.SP_CERTS_NOT_FOUND
)
msg = self.__build_sign_query(data[saml_type],
data.get('RelayState', None),
sign_algorithm,
saml_type)
sign_algorithm_transform_map = {
OneLogin_Saml2_Constants.DSA_SHA1: xmlsec.Transform.DSA_SHA1,
OneLogin_Saml2_Constants.RSA_SHA1: xmlsec.Transform.RSA_SHA1,
OneLogin_Saml2_Constants.RSA_SHA256: xmlsec.Transform.RSA_SHA256,
OneLogin_Saml2_Constants.RSA_SHA384: xmlsec.Transform.RSA_SHA384,
OneLogin_Saml2_Constants.RSA_SHA512: xmlsec.Transform.RSA_SHA512
}
sign_algorithm_transform = sign_algorithm_transform_map.get(sign_algorithm, xmlsec.Transform.RSA_SHA1)
:param relay_state: The target URL the user should be redirected to
:type relay_state: string
:param saml_type: The target URL the user should be redirected to
:type saml_type: string SAMLRequest | SAMLResponse
:param sign_algorithm: Signature algorithm method
:type sign_algorithm: string
"""
assert saml_type in ['SAMLRequest', 'SAMLResponse']
# Load the key into the xmlsec context
key = self.__settings.get_sp_key()
if not key:
raise OneLogin_Saml2_Error(
"Trying to sign the %s but can't load the SP private key" % saml_type,
OneLogin_Saml2_Error.PRIVATE_KEY_NOT_FOUND
)
dsig_ctx = xmlsec.DSigCtx()
dsig_ctx.signKey = xmlsec.Key.loadMemory(key, xmlsec.KeyDataFormatPem, None)
msg = '%s=%s' % (saml_type, quote_plus(saml_data))
if relay_state is not None:
msg += '&RelayState=%s' % quote_plus(relay_state)
msg += '&SigAlg=%s' % quote_plus(sign_algorithm)
# Sign the metadata with our private key.
sign_algorithm_transform_map = {
OneLogin_Saml2_Constants.DSA_SHA1: xmlsec.TransformDsaSha1,
OneLogin_Saml2_Constants.RSA_SHA1: xmlsec.TransformRsaSha1,
x509_cert_value_formatted = OneLogin_Saml2_Utils.format_cert(x509_cert_value)
x509_fingerprint_value = OneLogin_Saml2_Utils.calculate_x509_fingerprint(x509_cert_value_formatted, fingerprintalg)
if fingerprint == x509_fingerprint_value:
cert = x509_cert_value_formatted
# Check if Reference URI is empty
# reference_elem = OneLogin_Saml2_Utils.query(signature_node, '//ds:Reference')
# if len(reference_elem) > 0:
# if reference_elem[0].get('URI') == '':
# reference_elem[0].set('URI', '#%s' % signature_node.getparent().get('ID'))
if cert is None or cert == '':
raise OneLogin_Saml2_Error(
'Could not validate node signature: No certificate provided.',
OneLogin_Saml2_Error.CERT_NOT_FOUND
)
file_cert = OneLogin_Saml2_Utils.write_temp_file(cert)
if validatecert:
mngr = xmlsec.KeysMngr()
mngr.loadCert(file_cert.name, xmlsec.KeyDataFormatCertPem, xmlsec.KeyDataTypeTrusted)
dsig_ctx = xmlsec.DSigCtx(mngr)
else:
dsig_ctx = xmlsec.DSigCtx()
dsig_ctx.signKey = xmlsec.Key.load(file_cert.name, xmlsec.KeyDataFormatCertPem, None)
file_cert.close()
dsig_ctx.setEnabledKeyData([xmlsec.KeyDataX509])
x509_certificate_node = x509_certificate_nodes[0]
x509_cert_value = OneLogin_Saml2_Utils.element_text(x509_certificate_node)
x509_cert_value_formatted = OneLogin_Saml2_Utils.format_cert(x509_cert_value)
x509_fingerprint_value = OneLogin_Saml2_Utils.calculate_x509_fingerprint(x509_cert_value_formatted, fingerprintalg)
if fingerprint == x509_fingerprint_value:
cert = x509_cert_value_formatted
# Check if Reference URI is empty
# reference_elem = OneLogin_Saml2_Utils.query(signature_node, '//ds:Reference')
# if len(reference_elem) > 0:
# if reference_elem[0].get('URI') == '':
# reference_elem[0].set('URI', '#%s' % signature_node.getparent().get('ID'))
if cert is None or cert == '':
raise OneLogin_Saml2_Error(
'Could not validate node signature: No certificate provided.',
OneLogin_Saml2_Error.CERT_NOT_FOUND
)
file_cert = OneLogin_Saml2_Utils.write_temp_file(cert)
if validatecert:
mngr = xmlsec.KeysMngr()
mngr.loadCert(file_cert.name, xmlsec.KeyDataFormatCertPem, xmlsec.KeyDataTypeTrusted)
dsig_ctx = xmlsec.DSigCtx(mngr)
else:
dsig_ctx = xmlsec.DSigCtx()
dsig_ctx.signKey = xmlsec.Key.load(file_cert.name, xmlsec.KeyDataFormatCertPem, None)
file_cert.close()
:type session_index: string
:param nq: IDP Name Qualifier
:type: string
:param name_id_format: The NameID Format that will be set in the LogoutRequest.
:type: string
:param spnq: SP Name Qualifier
:type: string
:returns: Redirection url
"""
slo_url = self.get_slo_url()
if slo_url is None:
raise OneLogin_Saml2_Error(
'The IdP does not support Single Log Out',
OneLogin_Saml2_Error.SAML_SINGLE_LOGOUT_NOT_SUPPORTED
)
if name_id is None and self.__nameid is not None:
name_id = self.__nameid
if name_id_format is None and self.__nameid_format is not None:
name_id_format = self.__nameid_format
logout_request = OneLogin_Saml2_Logout_Request(
self.__settings,
name_id=name_id,
session_index=session_index,
nq=nq,
name_id_format=name_id_format,
spnq=spnq
sign_alg = get_data['SigAlg']
signed_query = 'SAMLResponse=%s' % OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'SAMLResponse', lowercase_urlencoding=lowercase_urlencoding)
if 'RelayState' in get_data:
signed_query = '%s&RelayState=%s' % (signed_query, OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'RelayState', lowercase_urlencoding=lowercase_urlencoding))
signed_query = '%s&SigAlg=%s' % (signed_query, OneLogin_Saml2_Utils.get_encoded_parameter(get_data, 'SigAlg', OneLogin_Saml2_Constants.RSA_SHA1, lowercase_urlencoding=lowercase_urlencoding))
exists_x509cert = 'x509cert' in idp_data and idp_data['x509cert']
exists_multix509sign = 'x509certMulti' in idp_data and \
'signing' in idp_data['x509certMulti'] and \
idp_data['x509certMulti']['signing']
if not (exists_x509cert or exists_multix509sign):
raise OneLogin_Saml2_Error(
'In order to validate the sign on the Logout Response, the x509cert of the IdP is required',
OneLogin_Saml2_Error.CERT_NOT_FOUND
)
if exists_multix509sign:
for cert in idp_data['x509certMulti']['signing']:
if OneLogin_Saml2_Utils.validate_binary_sign(signed_query, b64decode(get_data['Signature']), cert, sign_alg):
return True
raise OneLogin_Saml2_ValidationError(
'Signature validation failed. Logout Response rejected',
OneLogin_Saml2_ValidationError.INVALID_SIGNATURE
)
else:
cert = idp_data['x509cert']
if not OneLogin_Saml2_Utils.validate_binary_sign(signed_query, b64decode(get_data['Signature']), cert, sign_alg):
raise OneLogin_Saml2_ValidationError(
'Signature validation failed. Logout Response rejected',
OneLogin_Saml2_ValidationError.INVALID_SIGNATURE
"""
Builds the Signature
:param data: The Request data
:type data: dict
:param saml_type: The target URL the user should be redirected to
:type saml_type: string SAMLRequest | SAMLResponse
:param sign_algorithm: Signature algorithm method
:type sign_algorithm: string
"""
assert saml_type in ('SAMLRequest', 'SAMLResponse')
key = self.get_settings().get_sp_key()
if not key:
raise OneLogin_Saml2_Error(
"Trying to sign the %s but can't load the SP private key." % saml_type,
OneLogin_Saml2_Error.SP_CERTS_NOT_FOUND
)
msg = self.__build_sign_query(data[saml_type],
data.get('RelayState', None),
sign_algorithm,
saml_type)
sign_algorithm_transform_map = {
OneLogin_Saml2_Constants.DSA_SHA1: xmlsec.Transform.DSA_SHA1,
OneLogin_Saml2_Constants.RSA_SHA1: xmlsec.Transform.RSA_SHA1,
OneLogin_Saml2_Constants.RSA_SHA256: xmlsec.Transform.RSA_SHA256,
OneLogin_Saml2_Constants.RSA_SHA384: xmlsec.Transform.RSA_SHA384,
OneLogin_Saml2_Constants.RSA_SHA512: xmlsec.Transform.RSA_SHA512
}
self.__idp = {}
self.__security = {}
self.__contacts = {}
self.__organization = {}
self.__errors = []
self.__load_paths(base_path=custom_base_path)
self.__update_paths(settings)
if settings is None:
try:
valid = self.__load_settings_from_file()
except Exception as e:
raise e
if not valid:
raise OneLogin_Saml2_Error(
'Invalid dict settings at the file: %s',
OneLogin_Saml2_Error.SETTINGS_INVALID,
','.join(self.__errors)
)
elif isinstance(settings, dict):
if not self.__load_settings_from_dict(settings):
raise OneLogin_Saml2_Error(
'Invalid dict settings: %s',
OneLogin_Saml2_Error.SETTINGS_INVALID,
','.join(self.__errors)
)
else:
raise Exception('Unsupported settings object')
self.format_idp_cert()
self.format_sp_cert()
:return: Name ID Data (Value, Format, NameQualifier, SPNameQualifier)
:rtype: dict
"""
if isinstance(request, etree._Element):
elem = request
else:
if isinstance(request, Document):
request = request.toxml()
elem = fromstring(request, forbid_dtd=True)
name_id = None
encrypted_entries = OneLogin_Saml2_Utils.query(elem, '/samlp:LogoutRequest/saml:EncryptedID')
if len(encrypted_entries) == 1:
if key is None:
raise OneLogin_Saml2_Error(
'Private Key is required in order to decrypt the NameID, check settings',
OneLogin_Saml2_Error.PRIVATE_KEY_NOT_FOUND
)
encrypted_data_nodes = OneLogin_Saml2_Utils.query(elem, '/samlp:LogoutRequest/saml:EncryptedID/xenc:EncryptedData')
if len(encrypted_data_nodes) == 1:
encrypted_data = encrypted_data_nodes[0]
name_id = OneLogin_Saml2_Utils.decrypt_element(encrypted_data, key)
else:
entries = OneLogin_Saml2_Utils.query(elem, '/samlp:LogoutRequest/saml:NameID')
if len(entries) == 1:
name_id = entries[0]
if name_id is None:
raise OneLogin_Saml2_ValidationError(
'NameID not found in the Logout Request',
self.__update_paths(settings)
if settings is None:
try:
valid = self.__load_settings_from_file()
except Exception as e:
raise e
if not valid:
raise OneLogin_Saml2_Error(
'Invalid dict settings at the file: %s',
OneLogin_Saml2_Error.SETTINGS_INVALID,
','.join(self.__errors)
)
elif isinstance(settings, dict):
if not self.__load_settings_from_dict(settings):
raise OneLogin_Saml2_Error(
'Invalid dict settings: %s',
OneLogin_Saml2_Error.SETTINGS_INVALID,
','.join(self.__errors)
)
else:
raise Exception('Unsupported settings object')
self.format_idp_cert()
self.format_sp_cert()
self.format_sp_key()