def _sign_assertion(assertion): """Sign a SAML assertion. This method utilizes ``xmlsec1`` binary and signs SAML assertions in a separate process. ``xmlsec1`` cannot read input data from stdin so the prepared assertion needs to be serialized and stored in a temporary file. This file will be deleted immediately after ``xmlsec1`` returns. The signed assertion is redirected to a standard output and read using subprocess.PIPE redirection. A ``saml.Assertion`` class is created from the signed string again and returned. Parameters that are required in the CONF:: * xmlsec_binary * private key file path * public key file path :return: XML <Assertion> object """ xmlsec_binary = CONF.saml.xmlsec1_binary idp_private_key = CONF.saml.keyfile idp_public_key = CONF.saml.certfile # xmlsec1 --sign --privkey-pem privkey,cert --id-attr:ID <tag> <file> certificates = '%(idp_private_key)s,%(idp_public_key)s' % { 'idp_public_key': idp_public_key, 'idp_private_key': idp_private_key } command_list = [xmlsec_binary, '--sign', '--privkey-pem', certificates, '--id-attr:ID', 'Assertion'] try: # NOTE(gyee): need to make the namespace prefixes explicit so # they won't get reassigned when we wrap the assertion into # SAML2 response file_path = fileutils.write_to_tempfile(assertion.to_string( nspair={'saml': saml2.NAMESPACE, 'xmldsig': xmldsig.NAMESPACE})) command_list.append(file_path) process = subprocess.Popen(command_list, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) stdout, stderr = process.communicate() retcode = process.poll() if retcode: msg = _LE('Error when signing assertion, reason: %(reason)s') msg = msg % {'reason': stderr} LOG.error(msg) raise exception.SAMLSigningError(reason=stderr) finally: try: os.remove(file_path) except OSError: pass return saml2.create_class_from_xml_string(saml.Assertion, stdout)
def _sign_assertion(assertion): """Sign a SAML assertion. This method utilizes ``xmlsec1`` binary and signs SAML assertions in a separate process. ``xmlsec1`` cannot read input data from stdin so the prepared assertion needs to be serialized and stored in a temporary file. This file will be deleted immediately after ``xmlsec1`` returns. The signed assertion is redirected to a standard output and read using subprocess.PIPE redirection. A ``saml.Assertion`` class is created from the signed string again and returned. Parameters that are required in the CONF:: * xmlsec_binary * private key file path * public key file path :return: XML <Assertion> object """ xmlsec_binary = CONF.saml.xmlsec1_binary idp_private_key = CONF.saml.keyfile idp_public_key = CONF.saml.certfile # xmlsec1 --sign --privkey-pem privkey,cert --id-attr:ID <tag> <file> certificates = '%(idp_private_key)s,%(idp_public_key)s' % { 'idp_public_key': idp_public_key, 'idp_private_key': idp_private_key } command_list = [ xmlsec_binary, '--sign', '--privkey-pem', certificates, '--id-attr:ID', 'Assertion' ] try: # NOTE(gyee): need to make the namespace prefixes explicit so # they won't get reassigned when we wrap the assertion into # SAML2 response file_path = fileutils.write_to_tempfile( assertion.to_string(nspair={ 'saml': saml2.NAMESPACE, 'xmldsig': xmldsig.NAMESPACE })) command_list.append(file_path) stdout = subprocess.check_output(command_list) except Exception as e: msg = _LE('Error when signing assertion, reason: %(reason)s') msg = msg % {'reason': e} LOG.error(msg) raise exception.SAMLSigningError(reason=e) finally: try: os.remove(file_path) except OSError: pass return saml2.create_class_from_xml_string(saml.Assertion, stdout)
def _sign_assertion(assertion): """Sign a SAML assertion. This method utilizes ``xmlsec1`` binary and signs SAML assertions in a separate process. ``xmlsec1`` cannot read input data from stdin so the prepared assertion needs to be serialized and stored in a temporary file. This file will be deleted immediately after ``xmlsec1`` returns. The signed assertion is redirected to a standard output and read using subprocess.PIPE redirection. A ``saml.Assertion`` class is created from the signed string again and returned. Parameters that are required in the CONF:: * xmlsec_binary * private key file path * public key file path :return: XML <Assertion> object """ xmlsec_binary = CONF.saml.xmlsec1_binary idp_private_key = CONF.saml.keyfile idp_public_key = CONF.saml.certfile # xmlsec1 --sign --privkey-pem privkey,cert --id-attr:ID <tag> <file> certificates = '%(idp_private_key)s,%(idp_public_key)s' % { 'idp_public_key': idp_public_key, 'idp_private_key': idp_private_key } command_list = [xmlsec_binary, '--sign', '--privkey-pem', certificates, '--id-attr:ID', 'Assertion'] try: file_path = fileutils.write_to_tempfile(assertion.to_string()) command_list.append(file_path) stdout = subprocess.check_output(command_list) except Exception as e: msg = _LE('Error when signing assertion, reason: %(reason)s') msg = msg % {'reason': e} LOG.error(msg) raise exception.SAMLSigningError(reason=e) finally: try: os.remove(file_path) except OSError: pass return saml2.create_class_from_xml_string(saml.Assertion, stdout)