Remove unused module.
Roland believes this module can be removed - leftovers from some earlier refactoring.
This commit is contained in:
@@ -1,271 +0,0 @@
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
|
||||
from subprocess import Popen
|
||||
from subprocess import PIPE
|
||||
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
from saml2.sigver import make_temp
|
||||
from saml2.sigver import parse_xmlsec_output
|
||||
from saml2.sigver import XmlsecError
|
||||
from saml2 import saml
|
||||
|
||||
__author__ = 'rohe0002'
|
||||
|
||||
import xmlenc as enc
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
#<EncryptedData
|
||||
# xmlns="http://www.w3.org/2001/04/xmlenc#"
|
||||
# Type="http://www.w3.org/2001/04/xmlenc#Element">
|
||||
# <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#tripledes-cbc"/>
|
||||
# <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
# <EncryptedKey xmlns="http://www.w3.org/2001/04/xmlenc#">
|
||||
# <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
|
||||
# <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
|
||||
# <KeyName/>
|
||||
# </KeyInfo>
|
||||
# <CipherData>
|
||||
# <CipherValue/>
|
||||
# </CipherData>
|
||||
# </EncryptedKey>
|
||||
# </KeyInfo>
|
||||
# <CipherData>
|
||||
# <CipherValue/>
|
||||
# </CipherData>
|
||||
#</EncryptedData>
|
||||
|
||||
class DecryptionError(Exception):
|
||||
pass
|
||||
|
||||
ID_ATTR = "ID"
|
||||
#NODE_NAME = "urn:oasis:names:tc:SAML:2.0:assertion:Assertion"
|
||||
ENC_DATA = "urn:oasis:names:tc:SAML:2.0:assertion:EncryptedData"
|
||||
ENC_KEY_CLASS = "EncryptedKey"
|
||||
|
||||
RSA_15 = "http://www.w3.org/2001/04/xmlenc#rsa-1_5"
|
||||
RSA_OAEP = "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"
|
||||
AES128_CBC="http://www.w3.org/2001/04/xmlenc#aes128-cbc"
|
||||
TRIPLE_DES = "http://www.w3.org/2001/04/xmlenc#tripledes-cbc"
|
||||
|
||||
LOG_LINE = 60*"="+"\n%s\n"+60*"-"+"\n%s"+60*"="
|
||||
LOG_LINE_2 = 60*"="+"\n%s\n%s\n"+60*"-"+"\n%s"+60*"="
|
||||
|
||||
# registered xmlsec transforms
|
||||
TRANSFORMS = ["base64","enveloped-signature","c14n","c14n-with-comments",
|
||||
"c14n11","c14n11-with-comments","exc-c14n",
|
||||
"exc-c14n-with-comments","xpath","xpath2","xpointer","xslt",
|
||||
"aes128-cbc","aes192-cbc","aes256-cbc","kw-aes128","kw-aes192",
|
||||
"kw-aes256","tripledes-cbc","kw-tripledes","dsa-sha1","hmac-md5",
|
||||
"hmac-ripemd160","hmac-sha1","hmac-sha224","hmac-sha256",
|
||||
"hmac-sha384","hmac-sha512","md5","ripemd160","rsa-md5",
|
||||
"rsa-ripemd160","rsa-sha1","rsa-sha224","rsa-sha256","rsa-sha384",
|
||||
"rsa-sha512","rsa-1_5","rsa-oaep-mgf1p","sha1","sha224","sha256",
|
||||
"sha384","sha512"]
|
||||
|
||||
ALGORITHM = {
|
||||
"tripledes-cbc": TRIPLE_DES,
|
||||
"aes128-cbc": AES128_CBC,
|
||||
"rsa-1_5": RSA_15,
|
||||
"rsa-oaep-mgf1p": RSA_OAEP
|
||||
}
|
||||
|
||||
def template(ident=None, session_key="tripledes-cbc"):
|
||||
"""
|
||||
If an assertion is to be signed the signature part has to be preset
|
||||
with which algorithms to be used, this function returns such a
|
||||
preset part.
|
||||
|
||||
:param ident: The identifier of the assertion, so you know which assertion
|
||||
was signed
|
||||
:return: A preset signature part
|
||||
"""
|
||||
|
||||
cipher_data = enc.CipherData(cipher_value=enc.CipherValue())
|
||||
encryption_method = enc.EncryptionMethod(algorithm=ALGORITHM[session_key])
|
||||
#key_info = ds.KeyInfo(key_name=ds.KeyName())
|
||||
encrypted_data = enc.EncryptedData(
|
||||
type = "http://www.w3.org/2001/04/xmlenc#Element",
|
||||
encryption_method=encryption_method,
|
||||
#key_info=key_info,
|
||||
cipher_data=cipher_data)
|
||||
|
||||
if ident:
|
||||
encrypted_data.id = "%s" % ident
|
||||
|
||||
return encrypted_data
|
||||
|
||||
# xmlsec decrypt --privkey-pem userkey.pem doc-encrypted.xml
|
||||
|
||||
def decrypt_message(enctext, xmlsec_binary, key_file=None,
|
||||
key_file_type="privkey-pem", cafile=None,
|
||||
epath=None, id_attr="",
|
||||
node_name="", node_id=None, debug=False):
|
||||
""" Decrypts an encrypted part of a XML document.
|
||||
|
||||
:param enctext: XML document containing an encrypted part
|
||||
:param xmlsec_binary: The xmlsec1 binaries to be used
|
||||
:param key_file: The key used to decrypt the message
|
||||
:param key_file_type: The key file type
|
||||
:param node_name: The SAML class of the root node in the message
|
||||
:param node_id: The identifier of the root node if any
|
||||
:param id_attr: Should normally be one of "id", "Id" or "ID"
|
||||
:param debug: To debug or not
|
||||
:return: The decrypted document if all was OK otherwise will raise an
|
||||
exception.
|
||||
"""
|
||||
|
||||
if not id_attr:
|
||||
id_attr = ID_ATTR
|
||||
|
||||
_, fil = make_temp(enctext, decode=False)
|
||||
|
||||
com_list = [xmlsec_binary, "--decrypt",
|
||||
"--%s" % key_file_type, key_file]
|
||||
|
||||
if key_file_type in ["privkey-pem", "privkey-der", "pkcs8-pem",
|
||||
"pkcs8-der"]:
|
||||
if isinstance(cafile, basestring):
|
||||
com_list.append(cafile)
|
||||
else:
|
||||
com_list.extend(cafile)
|
||||
|
||||
if id_attr:
|
||||
com_list.extend(["--id-attr:%s" % id_attr, node_name])
|
||||
|
||||
elif epath:
|
||||
xpath = create_xpath(epath)
|
||||
com_list.extend(['--node-xpath', xpath])
|
||||
|
||||
# if debug:
|
||||
# com_list.append("--store-signatures")
|
||||
|
||||
if node_id:
|
||||
com_list.extend(["--node-id", node_id])
|
||||
|
||||
com_list.append(fil)
|
||||
|
||||
if debug:
|
||||
try:
|
||||
print " ".join(com_list)
|
||||
except TypeError:
|
||||
print "key_file_type", key_file_type
|
||||
print "key_file", key_file
|
||||
print "node_name", node_name
|
||||
print "fil", fil
|
||||
raise
|
||||
print "%s: %s" % (key_file, os.access(key_file, os.F_OK))
|
||||
print "%s: %s" % (fil, os.access(fil, os.F_OK))
|
||||
|
||||
pof = Popen(com_list, stderr=PIPE, stdout=PIPE)
|
||||
p_out = pof.stdout.read()
|
||||
try:
|
||||
p_err = pof.stderr.read()
|
||||
if debug:
|
||||
print p_err
|
||||
verified = parse_xmlsec_output(p_err)
|
||||
except XmlsecError, exc:
|
||||
logger(LOG_LINE % (p_out, exc))
|
||||
raise DecryptionError("%s" % (exc,))
|
||||
|
||||
return verified
|
||||
|
||||
# Whole document
|
||||
#xmlsec1 encrypt --pubkey-pem ServerKeys/pubkey.pem --session-key des-192
|
||||
# --xml-data ClientRequest.xml
|
||||
# --output ClientEncrypted.xml EncryptionTemplate.xml
|
||||
|
||||
# single value
|
||||
#/opt/local/bin/xmlsec1 encrypt --pubkey-cert-pem pubkey.pem
|
||||
# --session-key des-192 --xml-data pre_saml2_response.xml
|
||||
# --node-xpath '/*[local-name()="Response"]/*[local-name()="Assertion"]/*[local-name()="Subject"]/*[local-name()="EncryptedID"]/text()'
|
||||
# encryption_template.xml > enc.out
|
||||
|
||||
def create_xpath(path):
|
||||
"""
|
||||
:param path: list of element names
|
||||
"""
|
||||
|
||||
return "/*".join(['[local-name()="%s"]' % e for e in path]) + "/text()"
|
||||
|
||||
def encrypt_using_xmlsec(xmlsec, data, template, epath=None, key=None,
|
||||
key_file=None, key_file_type="pubkey-pem",
|
||||
session_key=None):
|
||||
"""encrypting a value using xmlsec.
|
||||
|
||||
:param xmlsec: Path to the xmlsec1 binary
|
||||
:param data: A XML document from which the value should be picked.
|
||||
:param template: The encyption part template
|
||||
:param epath: Which value to encrypt, if not the whole document
|
||||
should be encrypted.
|
||||
:param key: The key to be used for the encrypting, either this or
|
||||
:param key_file: The file where the key can be found
|
||||
:param key_file_type: pubkey-pem, pubkey-der, pubkey-cert-pem,
|
||||
pubkey-cert-der, privkey-der, privkey-pem, ...
|
||||
:param session_key: Key algorithm
|
||||
:return: The signed statement
|
||||
"""
|
||||
|
||||
if not key_file and key:
|
||||
_, key_file = make_temp("%s" % key, ".pem")
|
||||
|
||||
ntf = NamedTemporaryFile()
|
||||
xpath = create_xpath(epath)
|
||||
|
||||
com_list = [xmlsec, "encrypt",
|
||||
"--output", ntf.name,
|
||||
"--xml-data", data,
|
||||
'--node-xpath', xpath,
|
||||
key_file_type, key_file
|
||||
]
|
||||
|
||||
if session_key:
|
||||
com_list.extend(["--session-key", session_key])
|
||||
|
||||
_, fil = make_temp("%s" % template, decode=False)
|
||||
com_list.append(fil)
|
||||
|
||||
pof = Popen(com_list, stderr=PIPE, stdout=PIPE)
|
||||
p_out = pof.stdout.read()
|
||||
p_err = pof.stderr.read()
|
||||
|
||||
# this doesn't work if --store-signatures are used
|
||||
if p_out == "":
|
||||
ntf.seek(0)
|
||||
encrypted_statement = ntf.read()
|
||||
if not encrypted_statement:
|
||||
logger.error(p_err)
|
||||
raise Exception("Encryption failed")
|
||||
else:
|
||||
return encrypted_statement
|
||||
else:
|
||||
logger.error(LOG_LINE % (p_out, p_err))
|
||||
raise Exception("Encryption failed")
|
||||
|
||||
def encrypt_id(response, xmlsec, key_file, key_file_type, identifier,
|
||||
session_key, node_id=""):
|
||||
"""
|
||||
:param response: The response as a Response class instance
|
||||
:param xmlsec: Where the xmlsec1 binaries reside
|
||||
:param key_file: Which key file to use
|
||||
:param key_file_type: The type of key file
|
||||
:param identifier: The subject identifier
|
||||
:param session_key: The type of key used to encrypt
|
||||
:return: statement with the subject identifier encrypted
|
||||
"""
|
||||
if not response.assertion[0].subject.encrypted_id:
|
||||
response.assertion[0].subject.encrypted_id = saml.EncryptedID(
|
||||
identifier)
|
||||
|
||||
statement = encrypt_using_xmlsec(xmlsec, "%s" % response,
|
||||
template=template(ident=node_id,
|
||||
session_key=session_key),
|
||||
epath=["Response","Assertion","Subject","NameID"],
|
||||
key_file=key_file,
|
||||
key_file_type=key_file_type,
|
||||
session_key=session_key)
|
||||
|
||||
return statement
|
Reference in New Issue
Block a user