Permalink
Browse files

moved to pyXMLSecurity

  • Loading branch information...
1 parent 4a32d14 commit 912170bd71b0381cfb5b3470a99e75f6f3052a2e @leifj committed Aug 27, 2012
Showing with 30 additions and 5,012 deletions.
  1. +26 −0 LICENSE.txt
  2. +2 −2 setup.py
  3. +1 −1 src/pyff/mdrepo.py
  4. +1 −1 src/pyff/pipes/builtins.py
  5. +0 −231 src/pyff/xmlsec/__init__.py
  6. +0 −54 src/pyff/xmlsec/int_to_bytes.py
  7. +0 −238 src/pyff/xmlsec/rsa_x509_pem/Crypto/PublicKey/DSA.py
  8. +0 −132 src/pyff/xmlsec/rsa_x509_pem/Crypto/PublicKey/ElGamal.py
  9. +0 −259 src/pyff/xmlsec/rsa_x509_pem/Crypto/PublicKey/RSA.py
  10. +0 −17 src/pyff/xmlsec/rsa_x509_pem/Crypto/PublicKey/__init__.py
  11. +0 −201 src/pyff/xmlsec/rsa_x509_pem/Crypto/PublicKey/number.py
  12. +0 −172 src/pyff/xmlsec/rsa_x509_pem/Crypto/PublicKey/pubkey.py
  13. +0 −170 src/pyff/xmlsec/rsa_x509_pem/Crypto/PublicKey/qNEW.py
  14. +0 −25 src/pyff/xmlsec/rsa_x509_pem/Crypto/__init__.py
  15. +0 −52 src/pyff/xmlsec/rsa_x509_pem/README
  16. +0 −73 src/pyff/xmlsec/rsa_x509_pem/__init__.py
  17. +0 −26 src/pyff/xmlsec/rsa_x509_pem/keys/README.txt
  18. +0 −22 src/pyff/xmlsec/rsa_x509_pem/keys/cacert_pass_helloworld.pem
  19. +0 −18 src/pyff/xmlsec/rsa_x509_pem/keys/cakey_pass_helloworld.pem
  20. +0 −27 src/pyff/xmlsec/rsa_x509_pem/keys/id_rsa
  21. +0 −1 src/pyff/xmlsec/rsa_x509_pem/keys/id_rsa.pub
  22. +0 −15 src/pyff/xmlsec/rsa_x509_pem/keys/privkey_1_rsa_1024.pem
  23. +0 −27 src/pyff/xmlsec/rsa_x509_pem/keys/privkey_1_rsa_2048.pem
  24. +0 −9 src/pyff/xmlsec/rsa_x509_pem/keys/privkey_1_rsa_512.pem
  25. +0 −20 src/pyff/xmlsec/rsa_x509_pem/keys/rsa_cert_1_1024.pem
  26. +0 −25 src/pyff/xmlsec/rsa_x509_pem/keys/rsa_cert_1_2048.pem
  27. +0 −17 src/pyff/xmlsec/rsa_x509_pem/keys/rsa_cert_1_512.pem
  28. +0 −1 src/pyff/xmlsec/rsa_x509_pem/pyasn1/__init__.py
  29. 0 src/pyff/xmlsec/rsa_x509_pem/pyasn1/codec/__init__.py
  30. 0 src/pyff/xmlsec/rsa_x509_pem/pyasn1/codec/ber/__init__.py
  31. +0 −525 src/pyff/xmlsec/rsa_x509_pem/pyasn1/codec/ber/decoder.py
  32. +0 −256 src/pyff/xmlsec/rsa_x509_pem/pyasn1/codec/ber/encoder.py
  33. +0 −8 src/pyff/xmlsec/rsa_x509_pem/pyasn1/codec/ber/eoo.py
  34. 0 src/pyff/xmlsec/rsa_x509_pem/pyasn1/codec/cer/__init__.py
  35. +0 −28 src/pyff/xmlsec/rsa_x509_pem/pyasn1/codec/cer/decoder.py
  36. +0 −85 src/pyff/xmlsec/rsa_x509_pem/pyasn1/codec/cer/encoder.py
  37. 0 src/pyff/xmlsec/rsa_x509_pem/pyasn1/codec/der/__init__.py
  38. +0 −5 src/pyff/xmlsec/rsa_x509_pem/pyasn1/codec/der/decoder.py
  39. +0 −25 src/pyff/xmlsec/rsa_x509_pem/pyasn1/codec/der/encoder.py
  40. +0 −3 src/pyff/xmlsec/rsa_x509_pem/pyasn1/error.py
  41. 0 src/pyff/xmlsec/rsa_x509_pem/pyasn1/type/__init__.py
  42. +0 −218 src/pyff/xmlsec/rsa_x509_pem/pyasn1/type/base.py
  43. +0 −57 src/pyff/xmlsec/rsa_x509_pem/pyasn1/type/char.py
  44. +0 −188 src/pyff/xmlsec/rsa_x509_pem/pyasn1/type/constraint.py
  45. +0 −3 src/pyff/xmlsec/rsa_x509_pem/pyasn1/type/error.py
  46. +0 −132 src/pyff/xmlsec/rsa_x509_pem/pyasn1/type/namedtype.py
  47. +0 −42 src/pyff/xmlsec/rsa_x509_pem/pyasn1/type/namedval.py
  48. +0 −117 src/pyff/xmlsec/rsa_x509_pem/pyasn1/type/tag.py
  49. +0 −643 src/pyff/xmlsec/rsa_x509_pem/pyasn1/type/univ.py
  50. +0 −12 src/pyff/xmlsec/rsa_x509_pem/pyasn1/type/useful.py
  51. +0 −147 src/pyff/xmlsec/rsa_x509_pem/rsa_pem.py
  52. +0 −34 src/pyff/xmlsec/rsa_x509_pem/sequence_parser.py
  53. +0 −343 src/pyff/xmlsec/rsa_x509_pem/test.py
  54. +0 −305 src/pyff/xmlsec/rsa_x509_pem/x509_pem.py
View
@@ -0,0 +1,26 @@
+Copyright 2012 NORDUnet A/S. All rights reserved.
+Copyright 2011 Andrew D Yates. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this list of
+ conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list
+ of conditions and the following disclaimer in the documentation and/or other materials
+ provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY NORDUNET A/S ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NORDUNET A/S OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+The views and conclusions contained in the software and documentation are those of the
+authors and should not be interpreted as representing official policies, either expressed
+or implied, of NORDUnet A/S.
View
@@ -11,10 +11,10 @@
install_requires = [
'lxml',
- 'dm.xmlsec.binding',
'pyyaml',
'eventlet',
- 'pyOpenSSL'
+ 'pyOpenSSL',
+ 'pyXMLSecurity'
# List your project dependencies here.
# For more details, see:
# http://packages.python.org/distribute/setuptools.html#declaring-dependencies
View
@@ -7,7 +7,7 @@
from copy import deepcopy
import logging
from pyff.utils import schema
-import pyff.xmlsec as xmlsec
+import xmlsec
from pyff.constants import NS
import traceback
@@ -16,7 +16,7 @@
from eventlet.green import urllib2
from StringIO import StringIO
from lxml import etree
-import pyff.xmlsec as xmlsec
+import xmlsec
import base64
from datetime import datetime
View
@@ -1,231 +0,0 @@
-
-__author__ = 'leifj'
-
-import os
-import rsa_x509_pem
-import lxml.etree as etree
-import logging
-from pyff.constants import NS
-import base64
-import hashlib
-import copy
-import int_to_bytes as itb
-
-# SHA1 digest with ASN.1 BER SHA1 algorithm designator prefix [RSA-SHA1]
-PREFIX = '\x30\x21\x30\x09\x06\x05\x2B\x0E\x03\x02\x1A\x05\x00\x04\x14'
-
-TRANSFORM_ENVELOPED_SIGNATURE = "http://www.w3.org/2000/09/xmldsig#enveloped-signature"
-TRANSFORM_C14_EXC = "http://www.w3.org/2001/10/xml-exc-c14n"
-TRANSFORM_C14_EXC_WITH_COMMENTS = "http://www.w3.org/2001/10/xml-exc-c14n#WithComments"
-
-# This code was inspired by https://github.com/andrewdyates/xmldsig
-# and includes https://github.com/andrewdyates/rsa_x509_pem with
-# permission from the author.
-
-class XMLSigException(Exception):
- pass
-
-def _find_matching_cert(t,fp):
- for cd in t.findall(".//{%s}X509Certificate" % NS['ds']):
- fp = fp.lower().replace(":","")
- cert_pem = cd.text
- cert_der = base64.b64decode(cert_pem)
- m = hashlib.sha1()
- m.update(cert_der)
- fingerprint = m.hexdigest().lower()
- if fingerprint == fp:
- return cert_pem
- return None
-
-def number_of_bits(num):
- assert num>=0
- nbits = 1
- max = 2
- while max<=num:
- nbits += 1
- max += max
- return nbits
-
-def sign(t,key,cert):
- pass
-
-b64d = lambda s: s.decode('base64')
-
-def b64e(s):
- if type(s) in (int, long):
- s = itb.int_to_bytes(s)
- return s.encode('base64').replace('\n', '')
-
-def _signed_value(data, key_size):
- """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`
- """
-
- asn_digest = PREFIX + data
-
- # 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'
- padded_digest = pad + asn_digest
-
- return padded_digest
-
-def _digest(str,hash_alg):
- h = getattr(hashlib,hash_alg)()
- h.update(str)
- digest = b64e(h.digest())
- return digest
-
-def _process_references(t,sig=None):
- if sig is None:
- sig = t.find(".//{%s}Signature" % NS['ds'])
- for ref in sig.findall(".//{%s}Reference" % NS['ds']):
- object = None
- uri = ref.get('URI',None)
- if uri is not None or uri == '#' or uri == '':
- ct = copy.deepcopy(t)
- object = ct.getroot()
- else:
- raise ValueError("unknown reference %s" % uri)
-
- for tr in ref.findall(".//{%s}Transform" % NS['ds']):
- object = _transform(tr.get('Algorithm',None),object)
-
- dm = ref.find(".//{%s}DigestMethod" % NS['ds'])
- if dm is None:
- raise ValueError("Unable to find DigestMethod")
- hash_alg = (dm.get('Algorithm').split("#"))[1]
- logging.debug("using hash algorithm %s" % hash_alg)
- digest = _digest(object,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
-
-def _cert(sig,keyspec):
- data = None
- if os.path.isfile(keyspec):
- with open(keyspec) as c:
- data = c.read()
- elif ':' in keyspec:
- cd = _find_matching_cert(sig,keyspec)
- if cd is not None:
- data = "-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----" % cd
- else:
- data = keyspec
-
- if data is None:
- raise ValueError("Unable to find anything useful to verify with")
-
- return data
-
-import re, htmlentitydefs
-
-TRANSFORM_ENVELOPED_SIGNATURE = 'http://www.w3.org/2000/09/xmldsig#enveloped-signature'
-TRANSFORM_C14N_EXCLUSIVE_WITH_COMMENTS = 'http://www.w3.org/2001/10/xml-exc-c14n#WithComments'
-TRANSFORM_C14N_EXCLUSIVE = 'http://www.w3.org/2001/10/xml-exc-c14n'
-TRANSFORM_C14N_INCLUSIVE = 'http://www.w3.org/TR/2001/REC-xml-c14n-20010315'
-
-##
-# Removes HTML or XML character references and entities from a text string.
-#
-# @param text The HTML (or XML) source text.
-# @return The plain text, as a Unicode string, if necessary.
-
-def _unescape(text):
- def fixup(m):
- text = m.group(0)
- if text[:2] == "&#":
- # character reference
- try:
- if text[:3] == "&#x":
- return unichr(int(text[3:-1], 16))
- else:
- return unichr(int(text[2:-1]))
- except ValueError:
- pass
- else:
- # named entity
- try:
- text = unichr(htmlentitydefs.name2codepoint[text[1:-1]])
- except KeyError:
- pass
- return text # leave as is
- return re.sub("&#?\w+;", fixup, text)
-
-def _enveloped_signature(t):
- sig = t.find('.//{http://www.w3.org/2000/09/xmldsig#}Signature')
- p = sig.getprevious()
- if sig.tail is not None:
- if p is not None:
- p.tail += sig.tail
- else:
- sig.getparent().text += sig.tail
- sig.getparent().remove(sig)
- return t
-
-def _c14n(t,exclusive,with_comments):
- cxml = etree.tostring(t,method="c14n",exclusive=exclusive,with_comments=with_comments)
- u = _unescape(cxml.decode("utf8",errors='replace')).encode("utf8").strip()
- assert u[0] == '<',XMLSigException("C14N buffer doesn't start with '<'")
- assert u[-1] == '>',XMLSigException("C14N buffer doesn't end with '>'")
- return u
-
-def _transform(uri,t,**kwargs):
- if uri == TRANSFORM_ENVELOPED_SIGNATURE:
- return _enveloped_signature(t)
-
- if uri == TRANSFORM_C14N_EXCLUSIVE_WITH_COMMENTS:
- return _c14n(t,exclusive=True,with_comments=True)
-
- if uri == TRANSFORM_C14N_EXCLUSIVE:
- return _c14n(t,exclusive=True,with_comments=False)
-
- if uri == TRANSFORM_C14N_INCLUSIVE:
- return _c14n(t,exclusive=False,with_comments=False)
-
- raise ValueError("unknown or unimplemented transform %s" % uri)
-
-def verify(t,keyspec):
- with open("/tmp/foo-signed.xml","w") as fd:
- fd.write(etree.tostring(t))
-
- for sig in t.findall(".//{%s}Signature" % NS['ds']):
- sv = sig.findtext(".//{%s}SignatureValue" % NS['ds'])
- assert sv is not None,XMLSigException("No SignatureValue")
-
- data = _cert(sig,keyspec)
- cert = rsa_x509_pem.parse(data)
- key = rsa_x509_pem.get_key(cert)
- key_f_public = rsa_x509_pem.f_public(key)
-
- expected = key_f_public(b64d(sv))
-
- _process_references(t,sig)
-
- si = sig.find(".//{%s}SignedInfo" % NS['ds'])
- cm = si.find(".//{%s}CanonicalizationMethod" % NS['ds'])
- assert cm is not None and cm.get('Algorithm',None) is not None,XMLSigException("No CanonicalizationMethod")
- sic = _transform(cm.get('Algorithm'),si)
- digest = _digest(sic,"sha1")
- logging.debug("SignedInfo digest: %s" % digest)
- b_digest = b64d(digest)
-
- sz = int(key.size())+1
- logging.debug("key size: %d" % sz)
- actual = _signed_value(b_digest, sz)
-
- assert expected == actual,XMLSigException("Signature validation failed")
-
- return True
@@ -1,54 +0,0 @@
-#!/usr/bin/python2.5
-# -*- coding: utf-8 -*-
-# Copyright © 2011 Andrew D. Yates
-# All Rights Reserved
-"""Bytes to Integer Functions.
-
-`int` types may be cast as `long`
-"""
-__authors__ = ['"Andrew D. Yates" <andrewyates.name@gmail.com>']
-
-def bytes_to_int(s):
- """Return converted bytestring to integer.
-
- Args:
- s: str of bytes
- Returns:
- int: numeric interpretation of binary string `s`
- """
- # int type casts may return a long type
- return int(s.encode('hex'), 16)
-
-
-def int_to_bytes(num):
- """Return converted integer to bytestring.
-
- Note: string encoding is faster than divmod(num, 256) in Python.
-
- Args:
- num: integer, non-negative
- Returns:
- str: bytestring of binary data to represent `num`
- Raises:
- ValueError: `num` is not a non-negative integer
- """
- if not is_natural(num, include_zero=True):
- raise ValueError("%s is not a non-negative integer.")
- hexed = "%x" % num
- # align hexadecimal string to byte boundaries
- if len(hexed) % 2 == 1:
- hexed = '0%s' % hexed
- return hexed.decode('hex')
-
-
-def is_natural(value, include_zero=False):
- """Return if value is a natural integer in Python.
-
- Returns:
- bool: is value a natural number?
- """
- return all((
- isinstance(value, (int, long)),
- value >= 0,
- not (value == 0 and not include_zero),
- ))
Oops, something went wrong.

0 comments on commit 912170b

Please sign in to comment.