def __init__(self, settings, response): """ Constructs the response object. :param settings: The setting info :type settings: OneLogin_Saml2_Setting object :param response: The base64 encoded, XML string containing the samlp:Response :type response: string """ self.__settings = settings self.__error = None self.response = OneLogin_Saml2_Utils.b64decode(response) self.document = OneLogin_Saml2_XML.to_etree(self.response) self.decrypted_document = None self.encrypted = None self.valid_scd_not_on_or_after = None # Quick check for the presence of EncryptedAssertion encrypted_assertion_nodes = self.__query( '/samlp:Response/saml:EncryptedAssertion') if encrypted_assertion_nodes: decrypted_document = deepcopy(self.document) self.encrypted = True self.decrypted_document = self.__decrypt_assertion( decrypted_document)
def __validate_signature(self, data, saml_type, raise_exceptions=False): """ Validate Signature :param data: The Request data :type data: dict :param cert: The certificate to check signature :type cert: str :param saml_type: The target URL the user should be redirected to :type saml_type: string SAMLRequest | SAMLResponse :param raise_exceptions: Whether to return false on failure or raise an exception :type raise_exceptions: Boolean """ try: signature = data.get('Signature', None) if signature is None: if self.__settings.is_strict( ) and self.__settings.get_security_data().get( 'wantMessagesSigned', False): raise OneLogin_Saml2_ValidationError( 'The %s is not signed. Rejected.' % saml_type, OneLogin_Saml2_ValidationError.NO_SIGNED_MESSAGE) return True idp_data = self.get_settings().get_idp_data() 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): error_msg = 'In order to validate the sign on the %s, the x509cert of the IdP is required' % saml_type self.__errors.append(error_msg) raise OneLogin_Saml2_Error(error_msg, OneLogin_Saml2_Error.CERT_NOT_FOUND) sign_alg = data.get('SigAlg', OneLogin_Saml2_Constants.RSA_SHA1) if isinstance(sign_alg, bytes): sign_alg = sign_alg.decode('utf8') lowercase_urlencoding = False if 'lowercase_urlencoding' in self.__request_data.keys(): lowercase_urlencoding = self.__request_data[ 'lowercase_urlencoding'] signed_query = self.__build_sign_query( data[saml_type], data.get('RelayState', None), sign_alg, saml_type, lowercase_urlencoding) if exists_multix509sign: for cert in idp_data['x509certMulti']['signing']: if OneLogin_Saml2_Utils.validate_binary_sign( signed_query, OneLogin_Saml2_Utils.b64decode(signature), cert, sign_alg): return True raise OneLogin_Saml2_ValidationError( 'Signature validation failed. %s rejected' % saml_type, OneLogin_Saml2_ValidationError.INVALID_SIGNATURE) else: cert = idp_data['x509cert'] if not OneLogin_Saml2_Utils.validate_binary_sign( signed_query, OneLogin_Saml2_Utils.b64decode(signature), cert, sign_alg, self.__settings.is_debug_active()): raise OneLogin_Saml2_ValidationError( 'Signature validation failed. %s rejected' % saml_type, OneLogin_Saml2_ValidationError.INVALID_SIGNATURE) return True except Exception as e: self.__error_reason = str(e) if raise_exceptions: raise e return False