def _c14n(t, exclusive, with_comments, inclusive_prefix_list=None, schema=None): """ Perform XML canonicalization (c14n) on an lxml.etree. :param t: XML as lxml.etree :param exclusive: boolean :param with_comments: boolean, keep comments or not :param inclusive_prefix_list: List of namespaces to include (?) :returns: XML as string (utf8) """ xml_str = etree.tostring(t) doc = parse_xml(xml_str, remove_whitespace=config.c14n_strip_ws, remove_comments=not with_comments, schema=schema) buf = etree.tostring(doc, method='c14n', exclusive=exclusive, with_comments=with_comments, inclusive_ns_prefixes=inclusive_prefix_list) u = unescape_xml_entities(buf.decode("utf8", 'replace')).encode("utf8").strip() if u[0] != '<': raise XMLSigException("C14N buffer doesn't start with '<'") if u[-1] != '>': raise XMLSigException("C14N buffer doesn't end with '>'") return u
def __init__(self, filename, private): super(XMLSecCryptoFile, self).__init__(source='file', do_padding=False, private=private, do_digest=False) with io.open(filename, "rb") as file: if private: self.key = serialization.load_pem_private_key( file.read(), password=None, backend=default_backend()) if not isinstance(self.key, rsa.RSAPrivateKey): raise XMLSigException( "We don't support non-RSA private keys at the moment.") # XXX Do not leak private key -- is there any situation # where we might need this pem? self.cert_pem = None # self.cert_pem = self.key.private_bytes( # encoding=serialization.Encoding.PEM, # format=serialization.PrivateFormat.PKCS8, # encryption_algorithm=serialization.NoEncryption()) self.keysize = self.key.key_size else: self.key = load_pem_x509_certificate(file.read(), backend=default_backend()) if not isinstance(self.key.public_key(), rsa.RSAPublicKey): raise XMLSigException( "We don't support non-RSA public keys at the moment.") self.cert_pem = self.key.public_bytes( encoding=serialization.Encoding.PEM) self.keysize = self.key.public_key().key_size self._from_file = filename # for debugging
def _verify(t, keyspec, sig_path=".//{%s}Signature" % NS['ds']): """ Verify the signature(s) in an XML document. Throws an XMLSigException on any non-matching signatures. :param t: XML as lxml.etree :param keyspec: X.509 cert filename, string with fingerprint or X.509 cert as string :returns: True if signature(s) validated, False if there were no signatures """ if config.debug_write_to_files: with open("/tmp/foo-sig.xml", "w") as fd: fd.write(etree.tostring(root_elt(t))) # Load and parse certificate, unless keyspec is a fingerprint. cert = _load_keyspec(keyspec) validated = [] for sig in t.findall(sig_path): sv = sig.findtext(".//{%s}SignatureValue" % NS['ds']) if sv is None: raise XMLSigException("No SignatureValue") this_f_public = None this_keysize = None if cert is None: # keyspec is fingerprint - look for matching certificate in XML this_cert = _load_keyspec(keyspec, signature_element=sig) if this_cert is None: raise XMLSigException( "Could not find certificate to validate signature") this_f_public = this_cert['f_public'] this_keysize = this_cert['keysize'] else: # Non-fingerprint keyspec, use pre-parsed values this_cert = cert this_f_public = cert['f_public'] this_keysize = cert['keysize'] logging.debug("key size: %d bits" % this_cert['keysize']) if this_cert is None: raise XMLSigException( "Could not find certificate to validate signature") si = sig.find(".//{%s}SignedInfo" % NS['ds']) cm_alg = _cm_alg(si) digest_alg = _sig_digest(si) validated_objects = _process_references(t, sig, sig_path) b_digest = _create_signature_digest(si, cm_alg, digest_alg) actual = _signed_value(b_digest, this_keysize, True, digest_alg) expected = this_f_public(b64d(sv)) if expected != actual: raise XMLSigException("Signature validation failed") validated.extend(validated_objects) return validated
def sign(t, key_spec, cert_spec=None, reference_uri=''): """ Sign an XML document. This means to 'complete' all Signature elements in the XML. :param t: XML as lxml.etree :param key_spec: private key reference, see _load_keyspec() for syntax. :param cert_spec: None or public key reference (to add cert to document), see _load_keyspec() for syntax. :param reference_uri: Envelope signature reference URI :returns: XML as lxml.etree (for convenience, 't' is modified in-place) """ do_padding = False # only in the case of our fallback keytype do we need to do pkcs1 padding here private = _load_keyspec(key_spec, private=True) if private is None: raise XMLSigException("Unable to load private key from '%s'" % key_spec) if private['source'] == 'file': do_padding = True # need to do p1 padding in this case if cert_spec is None and private['source'] == 'pkcs11': cert_spec = private['data'] logging.debug("Using P11 cert_spec :\n%s" % cert_spec) public = _load_keyspec(cert_spec) if public is None: raise XMLSigException("Unable to load public key from '%s'" \ % (cert_spec)) if public['keysize'] != private['keysize']: raise XMLSigException("Public and private key sizes do not match (%s, %s)" \ % (public['keysize'], private['keysize'])) logging.debug("Using %s bit key" % (private['keysize'])) if t.find(".//{%s}Signature" % NS['ds']) is None: add_enveloped_signature(t, reference_uri=reference_uri) if _DEBUG_WRITE_TO_FILES: with open("/tmp/sig-ref.xml", "w") as fd: fd.write(etree.tostring(_root(t))) for sig in t.findall(".//{%s}Signature" % NS['ds']): hash_alg = _process_references(t, sig) si = sig.find(".//{%s}SignedInfo" % NS['ds']) b_digest = _create_signature_digest(si, hash_alg) # RSA sign hash digest and insert it into the XML tbs = _signed_value(b_digest, private['keysize'], do_padding, hash_alg) signed = private['f_private'](tbs) signature = b64e(signed) logging.debug("SignatureValue: %s" % signature) si.addnext(DS.SignatureValue(signature)) if public is not None: # Insert cert_data as b64-encoded X.509 certificate into XML document sv_elt = si.getnext() sv_elt.addnext(DS.KeyInfo(DS.X509Data(DS.X509Certificate(pem2b64(public['data']))))) return t
def _ref_digest(ref): dm = ref.find(".//{%s}DigestMethod" % NS['ds']) if dm is None: raise XMLSigException( "Unable to find DigestMethod for Reference@URI {!s}".format( ref.get('URI'))) alg_uri = _alg(dm) hash_alg = (alg_uri.split("#"))[1] if not hash_alg: raise XMLSigException( "Unable to determine digest algorithm from {!s}".format(alg_uri)) return hash_alg
def _ref_digest(ref): dm = ref.find(".//{%s}DigestMethod" % NS['ds']) if dm is None: raise XMLSigException( "Unable to find DigestMethod for Reference@URI {!s}".format( ref.get('URI'))) alg_uri = _alg(dm) if alg_uri is None: raise XMLSigException("No suitable DigestMethod") hash_alg = constants.sign_alg_xmldsig_digest_to_internal(alg_uri.lower()) return hash_alg
def parse_uri(pk11_uri): o = urlparse(pk11_uri) if o.scheme != 'pkcs11': raise XMLSigException("Bad URI scheme in pkcs11 URI %s" % pk11_uri) logging.debug("parsed pkcs11 uri: %s" % repr(o)) slot = 0 library = None keyname = None query = {} if not '/' in o.path: raise XMLSigException( "Missing keyname part in pkcs11 URI (pkcs11://[library[:slot]/]keyname[?pin=<pin>])" ) (module_path, sep, keyqs) = o.path.rpartition('/') qs = o.query if qs: keyname = keyqs elif '?' in keyqs: (keyname, sep, qss) = keyqs.rpartition('?') qs = qss else: keyname = keyqs if qs: for av in qs.split('&'): if not '=' in av: raise XMLSigException("Bad query string in pkcs11 URI %s" % pk11_uri) (a, sep, v) = av.partition('=') assert a assert v query[a] = v if ':' in module_path: (library, sep, slot_str) = module_path.rpartition(":") slot = int(slot_str) else: library = module_path if library is None or len(library) == 0: library = os.environ.get('PYKCS11LIB', None) if library is None or len(library) == 0: raise XMLSigException("No PKCS11 module in pkcs11 URI %s" % pk11_uri) logging.debug("returning %s %s %s %s" % (library, slot, keyname, query)) return library, slot, keyname, query
def _verify(t, keyspec, sig_path=".//{%s}Signature" % NS['ds'], drop_signature=False): """ Verify the signature(s) in an XML document. Throws an XMLSigException on any non-matching signatures. :param t: XML as lxml.etree :param keyspec: X.509 cert filename, string with fingerprint or X.509 cert as string :returns: True if signature(s) validated, False if there were no signatures """ if config.debug_write_to_files: with open("/tmp/foo-sig.xml", "w") as fd: fd.write(etree.tostring(root_elt(t))) validated = [] for sig in t.findall(sig_path): try: sv = sig.findtext(".//{%s}SignatureValue" % NS['ds']) if not sv: raise XMLSigException("No SignatureValue") logging.debug("SignatureValue: {!s}".format(sv)) this_cert = xmlsec.crypto.from_keyspec(keyspec, signature_element=sig) logging.debug("key size: {!s} bits".format(this_cert.keysize)) si = sig.find(".//{%s}SignedInfo" % NS['ds']) logging.debug("Found signedinfo {!s}".format(etree.tostring(si))) cm_alg = _cm_alg(si) sig_digest_alg = _sig_digest(si) refmap = _process_references(t, sig, sig_path=sig_path, drop_signature=drop_signature) for ref, obj in refmap.items(): b_digest = _create_signature_digest(si, cm_alg, sig_digest_alg) actual = _signed_value(b_digest, this_cert.keysize, True, sig_digest_alg) if not this_cert.verify(b64d(sv), actual): raise XMLSigException( "Failed to validate {!s} using ref digest {!s} and cm {!s}" .format(etree.tostring(sig), ref_digest_alg, cm_alg)) validated.append(obj) except XMLSigException, ex: logging.error(ex)
def _signed_value(data, key_size, do_pad, hash_alg): # TODO Do proper asn1 CMS """Return unencrypted rsa-sha1 signature value `padded_digest` from `data`. The resulting signed value will be in the form: (01 | FF* | 00 | prefix | digest) [RSA-SHA1] where "digest" is of the generated c14n xml for <SignedInfo>. Args: data: str of bytes to sign key_size: int of key length in bits; => len(`data`) + 3 Returns: str: rsa-sha1 signature value of `data` """ prefix = ASN1_BER_ALG_DESIGNATOR_PREFIX.get(hash_alg) if not prefix: raise XMLSigException("Unknown hash algorithm %s" % hash_alg) asn_digest = prefix + data if do_pad: # Pad to "one octet shorter than the RSA modulus" [RSA-SHA1] # WARNING: key size is in bits, not bytes! padded_size = key_size / 8 - 1 pad_size = padded_size - len(asn_digest) - 2 pad = '\x01' + '\xFF' * pad_size + '\x00' return pad + asn_digest else: return asn_digest
def _sig_alg(si): sm = si.find(".//{%s}SignatureMethod" % NS['ds']) sig_uri = _alg(sm) if sm is None or sig_uri is None: raise XMLSigException("No SignatureMethod") return constants.sign_alg_xmldsig_sig_to_internal(sig_uri.lower())
def __init__(self, signature_element, keyspec): source = None data = None #print "XMLSecCryptoFromXML using %s and keyspec=%s" % (signature_element, keyspec) fp = keyspec if ':' not in keyspec: fp, _ = _cert_fingerprint(keyspec) cd = _find_cert_by_fingerprint(signature_element, fp) if cd is not None: data = cd source = 'signature_element' elif '-----BEGIN' in keyspec: data = keyspec source = 'keyspec' if data is None: raise ValueError("Unable to find cert matching fingerprint: %s" % fp) super(XMLSecCryptoFromXML, self).__init__(source=source, do_padding=False, private=False, do_digest=False) self.key = load_pem_x509_certificate(data, backend=default_backend()) if not isinstance(self.key.public_key(), rsa.RSAPublicKey): raise XMLSigException( "We don't support non-RSA public keys at the moment.") # XXX now we could implement encrypted-PEM-support self.cert_pem = self.key.public_bytes( encoding=serialization.Encoding.PEM) self.keysize = self.key.public_key().key_size self._from_keyspec = keyspec # for debugging
def sign(self, data, hash_alg, pad_alg="PKCS1v15"): if self.is_private: hasher = getattr(hashes, hash_alg) padder = getattr(padding, pad_alg) return self.key.sign(data, padder(), hasher()) else: raise XMLSigException('Signing is only possible with a private key.')
def _transform(uri, t, tr=None, schema=None, sig_path=".//{%s}Signature" % NS['ds']): if uri == constants.TRANSFORM_ENVELOPED_SIGNATURE: return _enveloped_signature(t, sig_path) if uri == constants.TRANSFORM_C14N_EXCLUSIVE_WITH_COMMENTS: return _c14n(t, exclusive=True, with_comments=True, inclusive_prefix_list=_find_nslist(tr), schema=schema) if uri == constants.TRANSFORM_C14N_EXCLUSIVE: return _c14n(t, exclusive=True, with_comments=False, inclusive_prefix_list=_find_nslist(tr), schema=schema) if uri == constants.TRANSFORM_C14N_INCLUSIVE: return _c14n(t, exclusive=False, with_comments=False, schema=schema) raise XMLSigException("unknown or unimplemented transform %s" % uri)
def _signed_value(data, key_size, do_pad, hash_alg): # TODO Do proper asn1 CMS """Return unencrypted rsa-sha1 signature value `padded_digest` from `data`. The resulting signed value will be in the form: (01 | FF* | 00 | prefix | digest) [RSA-SHA1] where "digest" is of the generated c14n xml for <SignedInfo>. :param data: str of bytes to sign :param key_size: key length (if known) in bits; => len(`data`) + 3 :param do_pad: Do PKCS1 (?) padding of the data - requires integer key_size :param hash_alg: Hash algorithm as string (e.g. 'sha1') :returns: rsa-sha signature value of `data` :type data: string :type key_size: None | int :type do_pad: bool :type hash_alg: string :rtype: string """ prefix = constants.ASN1_BER_ALG_DESIGNATOR_PREFIX.get(hash_alg) if not prefix: raise XMLSigException("Unknown hash algorithm %s" % hash_alg) asn_digest = prefix + data if do_pad: # Pad to "one octet shorter than the RSA modulus" [RSA-SHA1] # WARNING: key size is in bits, not bytes! padded_size = key_size / 8 - 1 pad_size = padded_size - len(asn_digest) - 2 pad = '\x01' + '\xFF' * pad_size + '\x00' return pad + asn_digest else: return asn_digest
def _process_references(t, sig=None): """ :returns: hash algorithm as string """ if sig is None: sig = t.find(".//{%s}Signature" % NS['ds']) hash_alg = None for ref in sig.findall(".//{%s}Reference" % NS['ds']): obj = None uri = ref.get('URI', None) if uri is None or uri == '#' or uri == '': ct = _remove_child_comments(_root(copy.deepcopy(t))) obj = _root(ct) elif uri.startswith('#'): ct = copy.deepcopy(t) obj = _remove_child_comments(_get_by_id(ct, uri[1:])) else: raise XMLSigException("Unknown reference %s" % uri) if obj is None: raise XMLSigException("Unable to dereference Reference URI='%s'" % uri) for tr in ref.findall(".//{%s}Transform" % NS['ds']): logging.debug("transform: %s" % _alg(tr)) obj = _transform(_alg(tr), obj, tr) if _DEBUG_WRITE_TO_FILES: with open("/tmp/foo-obj.xml", "w") as fd: fd.write(obj) dm = ref.find(".//{%s}DigestMethod" % NS['ds']) if dm is None: raise XMLSigException("Unable to find DigestMethod") this_hash_alg = (_alg(dm).split("#"))[1] logging.debug("using hash algorithm %s" % this_hash_alg) hash_alg = hash_alg or this_hash_alg if this_hash_alg != hash_alg: raise XMLSigException("Unable to handle more than one hash algorithm (%s != %s)" % (this_hash_alg, hash_alg)) digest = _digest(obj, this_hash_alg) logging.debug("digest for %s: %s" % (uri, digest)) dv = ref.find(".//{%s}DigestValue" % NS['ds']) logging.debug(etree.tostring(dv)) dv.text = digest return hash_alg
def sign(self, data, hash_alg, pad_alg="PKCS1v15"): if self.is_private: if not isinstance(data, six.binary_type): data = unicode_to_bytes(data) hasher = getattr(hashes, hash_alg) padder = getattr(padding, pad_alg) return self.key.sign(data, padder(), hasher()) else: raise XMLSigException('Signing is only possible with a private key.')
def from_keyspec(keyspec, private=False, signature_element=None): """ Load a key referenced by a keyspec (see below). To 'load' a key means different things based on what can be loaded through a given specification. For example, if keyspec is a a PKCS#11 reference to a private key then naturally the key itself is not available. Possible keyspecs, in evaluation order : - a callable. Return a partial dict with 'f_private' set to the keyspec. - a filename. Load a PEM X.509 certificate from the file. - a PKCS#11-URI (see xmlsec.pk11.parse_uri()). Return a dict with 'f_private' set to a function calling the 'sign' function for the key, and the rest based on the (public) key returned by xmlsec.pk11.signer(). - an http:// URL REST URL used for signing (see pyeleven). - a fingerprint. If signature_element is provided, the key is located using the fingerprint (provided as string). - X.509 string. An X.509 certificate as string. If the keyspec is prefixed by 'xmlsec+', that prefix will be removed. This is a workaround for pysaml2 that handles keyspecs starting with 'http' differently. Resulting dictionary (used except for 'callable') : {'keyspec': keyspec, 'source': 'pkcs11' or 'file' or 'fingerprint' or 'keyspec', 'data': X.509 certificate as string if source != 'pkcs11', 'key': Parsed key from certificate if source != 'pkcs11', 'keysize': Keysize in bits if source != 'pkcs11', 'f_public': rsa_x509_pem.f_public(key) if private == False, 'f_private': rsa_x509_pem.f_private(key) if private == True, } :param keyspec: Keyspec as string or callable. See above. :param private: True of False, is keyspec a private key or not? :param signature_element: :returns: dict, see above. """ if keyspec.startswith('xmlsec+'): # workaround for pysaml2 which handles http keyspecs differently keyspec = keyspec[7:] thread_local = threading.local() cache = getattr(thread_local, 'keycache', {}) if keyspec in cache: return cache[keyspec] key = _load_keyspec(keyspec, private, signature_element) if key is None: raise XMLSigException( 'Unable to load private key from {!s}'.format(keyspec)) cache[keyspec] = key thread_local.cache = cache return key
def delete_elt(elt): if elt.getparent() is None: raise XMLSigException("Cannot delete root") if elt.tail is not None: #logging.debug("tail: '%s'" % elt.tail) p = elt.getprevious() if p is not None: #logging.debug("adding tail to previous") if p.tail is None: p.tail = '' p.tail += elt.tail else: #logging.debug("adding tail to parent") up = elt.getparent() if up is None: raise XMLSigException("Signature has no parent") if up.text is None: up.text = '' up.text += elt.tail elt.getparent().remove(elt)
def _c14n(t, exclusive, with_comments, inclusive_prefix_list=None): """ Perform XML canonicalization (c14n) on an lxml.etree. NOTE: The c14n done here is missing whitespace removal. The whitespace has to be removed at parse time. One way to do that is to use xmlsec.parse_xml(). :param t: XML as lxml.etree :param exclusive: boolean :param with_comments: boolean, keep comments or not :param inclusive_prefix_list: List of namespaces to include (?) :returns: XML as string (utf8) """ cxml = etree.tostring(t, method="c14n", exclusive=exclusive, with_comments=with_comments, inclusive_ns_prefixes=inclusive_prefix_list) u = _unescape(cxml.decode("utf8", 'replace')).encode("utf8").strip() if u[0] != '<': raise XMLSigException("C14N buffer doesn't start with '<'") if u[-1] != '>': raise XMLSigException("C14N buffer doesn't end with '>'") return u
def _create_signature_digest(si, hash_alg): """ :param hash_alg: string such as 'sha1' """ cm = si.find(".//{%s}CanonicalizationMethod" % NS['ds']) cm_alg = _alg(cm) if cm is None or cm_alg is None: raise XMLSigException("No CanonicalizationMethod") sic = _transform(cm_alg, si) logging.debug("SignedInfo C14N: %s" % sic) digest = _digest(sic, hash_alg) logging.debug("SignedInfo digest: %s" % digest) return b64d(digest)
def verify(self, signature, msg, hash_alg, pad_alg="PKCS1v15"): if not self.is_private: try: hasher = getattr(hashes, hash_alg) padder = getattr(padding, pad_alg) self.key.public_key().verify(signature, msg, padder(), hasher()) except InvalidSignature: return False return True else: raise XMLSigException( 'Verifying is only possible with a certificate.')
def verify(self, signature, msg, hash_alg, pad_alg="PKCS1v15"): if not self.is_private: if not isinstance(msg, six.binary_type): msg = unicode_to_bytes(msg) try: hasher = getattr(hashes, hash_alg) padder = getattr(padding, pad_alg) self.key.public_key().verify(signature, msg, padder(), hasher()) except InvalidSignature: return False return True else: raise XMLSigException( 'Verifying is only possible with a certificate.')
def sign(self, data, hash_alg=None): try: import requests import json url = '{!s}/rawsign'.format(self._keyspec) r = requests.post(url, json=dict(mech='RSAPKCS1', data=data.encode("base64"))) if r.status_code != requests.codes.ok: r.raise_for_status() msg = r.json() if not 'signed' in msg: raise ValueError("Missing signed data in response message") return msg['signed'].decode('base64') except Exception, ex: from traceback import print_exc print_exc(ex) raise XMLSigException(ex)
def __init__(self, keyspec): super(XMLSecCryptoP11, self).__init__(source='pkcs11', do_padding=False, private=True) from xmlsec import pk11 self._private_callable, data = pk11.signer(keyspec) logging.debug("Using pkcs11 signing key: {!s}".format(self._private_callable)) if data is not None: self.key = load_pem_x509_certificate(data, backend=default_backend()) if not isinstance(self.key.public_key(), rsa.RSAPublicKey): raise XMLSigException("We don't support non-RSA public keys at the moment.") self.cert_pem = self.key.public_bytes(encoding=serialization.Encoding.PEM) self.keysize = self.key.public_key().key_size self._from_keyspec = keyspec # for debugging
def signer(pk11_uri, mech=PyKCS11.MechanismRSAPKCS1): library, slot, keyname, query = parse_uri(pk11_uri) pin = None pin_spec = query.get('pin', "env:PYKCS11PIN") if pin_spec.startswith("env:"): pin = os.environ.get(pin_spec[4:], None) else: pin = pin_spec session = _session(str(library), slot, str(pin)) key, cert = _find_key(session, keyname) if key is None: raise XMLSigException("No such key: %s" % pk11_uri) if cert is not None: logging.info("Found matching cert in token") return lambda data: _sign_and_close(session, key, data, mech), cert
def _cert2dict(cert): """ Build cert_dict similar to old rsa_x509_pem backend. Shouldn't be used by new code. @param cert A cryptography.x509.Certificate object """ key = cert.public_key() if not isinstance(key, rsa.RSAPublicKey): raise XMLSigException( "We don't support non-RSA public keys at the moment.") cdict = dict() cdict['type'] = "X509 CERTIFICATE" cdict['pem'] = cert.public_bytes(encoding=serialization.Encoding.PEM) cdict['body'] = b64encode( cert.public_bytes(encoding=serialization.Encoding.DER)) n = key.public_numbers() cdict['modulus'] = n.n cdict['publicExponent'] = n.e cdict['subject'] = cert.subject cdict['cert'] = RSAobjShim(cert) return cdict
def sign(self, data, hash_alg=None): try: import requests import json url = '{!s}/rawsign'.format(self._keyspec) if not isinstance(data, six.binary_type): data = data.encode("utf-8") data = base64.b64encode(data) r = requests.post(url, json=dict(mech='RSAPKCS1', data=data)) if r.status_code != requests.codes.ok: r.raise_for_status() msg = r.json() if 'signed' not in msg: raise ValueError("Missing signed data in response message") signed_msg = msg['signed'] if not isinstance(signed_msg, six.binary_type): signed_msg = signed_msg.encode("utf-8") return base64.b64decode(signed_msg) except Exception as ex: from traceback import format_exc log.debug(format_exc()) raise XMLSigException(ex)
def _transform(uri, t, tr=None, schema=None, sig_path=".//{%s}Signature" % NS['ds']): if uri == constants.TRANSFORM_ENVELOPED_SIGNATURE: return _enveloped_signature(t, sig_path) if uri == constants.TRANSFORM_C14N_EXCLUSIVE_WITH_COMMENTS: nslist = None if tr is not None: elt = tr.find(".//{%s}InclusiveNamespaces" % 'http://www.w3.org/2001/10/xml-exc-c14n#') if elt is not None: nslist = elt.get('PrefixList', '').split() return _c14n(t, exclusive=True, with_comments=True, inclusive_prefix_list=nslist, schema=schema) if uri == constants.TRANSFORM_C14N_EXCLUSIVE: nslist = None if tr is not None: elt = tr.find(".//{%s}InclusiveNamespaces" % 'http://www.w3.org/2001/10/xml-exc-c14n#') if elt is not None: nslist = elt.get('PrefixList', '').split() return _c14n(t, exclusive=True, with_comments=False, inclusive_prefix_list=nslist, schema=schema) if uri == constants.TRANSFORM_C14N_INCLUSIVE: return _c14n(t, exclusive=False, with_comments=False, schema=schema) raise XMLSigException("unknown or unimplemented transform %s" % uri)
def _try_a_to_b(dic, item): try: return dic[item] except KeyError: raise XMLSigException("Algorithm '%s' not supported." % item)
__author__ = 'leifj' from xmlsec.exceptions import XMLSigException from six.moves.urllib_parse import urlparse import os import logging from xmlsec.utils import b642pem _modules = {} try: import PyKCS11 from PyKCS11.LowLevel import CKA_ID, CKA_LABEL, CKA_CLASS, CKO_PRIVATE_KEY, CKO_CERTIFICATE, CKK_RSA, CKA_KEY_TYPE, CKA_VALUE except ImportError: raise XMLSigException("pykcs11 is required for PKCS#11 keys - cf README.rst") all_attributes = list(PyKCS11.CKA.keys()) # remove the CKR_ATTRIBUTE_SENSITIVE attributes since we can't get all_attributes.remove(PyKCS11.LowLevel.CKA_PRIVATE_EXPONENT) all_attributes.remove(PyKCS11.LowLevel.CKA_PRIME_1) all_attributes.remove(PyKCS11.LowLevel.CKA_PRIME_2) all_attributes.remove(PyKCS11.LowLevel.CKA_EXPONENT_1) all_attributes.remove(PyKCS11.LowLevel.CKA_EXPONENT_2) all_attributes.remove(PyKCS11.LowLevel.CKA_COEFFICIENT) all_attributes = [e for e in all_attributes if isinstance(e, int)] def parse_uri(pk11_uri): o = urlparse(pk11_uri)