def extract_tag_text(xml, tagname): open_tag = compat.to_bytes("<%s" % tagname) close_tag = compat.to_bytes("</%s>" % tagname) xml = OneLogin_Saml2_XML.to_string(xml) start = xml.find(open_tag) assert start != -1 end = xml.find(close_tag, start) + len(close_tag) assert end != -1 return compat.to_string(xml[start:end])
def validate_binary_sign(signed_query, signature, cert=None, algorithm=OneLogin_Saml2_Constants.RSA_SHA1, debug=False): """ Validates signed binary data (Used to validate GET Signature). :param signed_query: The element we should validate :type: string :param signature: The signature that will be validate :type: string :param cert: The public cert :type: string :param algorithm: Signature algorithm :type: string :param debug: Activate the xmlsec debug :type: bool """ try: xmlsec.enable_debug_trace(debug) dsig_ctx = xmlsec.SignatureContext() dsig_ctx.key = xmlsec.Key.from_memory(cert, xmlsec.KeyFormat.CERT_PEM, None) 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( algorithm, xmlsec.Transform.RSA_SHA1) dsig_ctx.verify_binary(compat.to_bytes(signed_query), sign_algorithm_transform, compat.to_bytes(signature)) return True except xmlsec.Error as e: if debug: print(e) return False
def sign_binary(msg, key, algorithm=xmlsec.Transform.RSA_SHA1, debug=False): """ Sign binary message :param msg: The element we should validate :type: bytes :param key: The private key :type: string :param debug: Activate the xmlsec debug :type: bool :return signed message :rtype str """ if isinstance(msg, str): msg = msg.encode('utf8') xmlsec.enable_debug_trace(debug) dsig_ctx = xmlsec.SignatureContext() dsig_ctx.key = xmlsec.Key.from_memory(key, xmlsec.KeyFormat.PEM, None) return dsig_ctx.sign_binary(compat.to_bytes(msg), algorithm)
def generate_unique_id(): """ Generates an unique string (used for example as ID for assertions). :return: A unique string :rtype: string """ return 'ONELOGIN_%s' % sha1(compat.to_bytes(uuid4().hex)).hexdigest()
def deflate_and_base64_encode(value): """ Deflates and then base64 encodes a string :param value: The string to deflate and encode :type value: string :returns: The deflated and encoded string :rtype: string """ return OneLogin_Saml2_Utils.b64encode( zlib.compress(compat.to_bytes(value))[2:-4])
def calculate_x509_fingerprint(x509_cert, alg='sha1'): """ Calculates the fingerprint of a formatted x509cert. :param x509_cert: x509 cert formatted :type: string :param alg: The algorithm to build the fingerprint :type: string :returns: fingerprint :rtype: string """ assert isinstance(x509_cert, compat.str_type) lines = x509_cert.split('\n') data = '' inData = False for line in lines: # Remove '\r' from end of line if present. line = line.rstrip() if not inData: if line == '-----BEGIN CERTIFICATE-----': inData = True elif line == '-----BEGIN PUBLIC KEY-----' or line == '-----BEGIN RSA PRIVATE KEY-----': # This isn't an X509 certificate. return None else: if line == '-----END CERTIFICATE-----': break # Append the current line to the certificate data. data += line if not data: return None decoded_data = base64.b64decode(compat.to_bytes(data)) if alg == 'sha512': fingerprint = sha512(decoded_data) elif alg == 'sha384': fingerprint = sha384(decoded_data) elif alg == 'sha256': fingerprint = sha256(decoded_data) else: fingerprint = sha1(decoded_data) return fingerprint.hexdigest().lower()
def b64encode(data): """base64 encode""" return compat.to_string(base64.b64encode(compat.to_bytes(data)))