[Python-modules-commits] [asn1crypto] 01/09: import asn1crypto_0.22.0.orig.tar.gz

Tristan Seligmann mithrandi at moszumanska.debian.org
Tue Jun 20 19:04:10 UTC 2017


This is an automated email from the git hooks/post-receive script.

mithrandi pushed a commit to annotated tag debian/0.22.0-1
in repository asn1crypto.

commit 8b49055eba0caa52daaba2d4b31a602e77fc1e03
Author: Tristan Seligmann <mithrandi at mithrandi.net>
Date:   Tue Jun 20 19:44:55 2017 +0200

    import asn1crypto_0.22.0.orig.tar.gz
---
 PKG-INFO                                 |   23 +
 asn1crypto.egg-info/PKG-INFO             |   23 +
 asn1crypto.egg-info/SOURCES.txt          |   32 +
 asn1crypto.egg-info/dependency_links.txt |    1 +
 asn1crypto.egg-info/top_level.txt        |    1 +
 asn1crypto/__init__.py                   |    9 +
 asn1crypto/_elliptic_curve.py            |  314 ++
 asn1crypto/_errors.py                    |   45 +
 asn1crypto/_ffi.py                       |   45 +
 asn1crypto/_inet.py                      |  170 +
 asn1crypto/_int.py                       |  159 +
 asn1crypto/_iri.py                       |  288 ++
 asn1crypto/_ordereddict.py               |  135 +
 asn1crypto/_perf/__init__.py             |    0
 asn1crypto/_perf/_big_num_ctypes.py      |   65 +
 asn1crypto/_teletex_codec.py             |  331 ++
 asn1crypto/_types.py                     |   46 +
 asn1crypto/algos.py                      | 1122 +++++++
 asn1crypto/cms.py                        |  915 ++++++
 asn1crypto/core.py                       | 5099 ++++++++++++++++++++++++++++++
 asn1crypto/crl.py                        |  536 ++++
 asn1crypto/csr.py                        |   96 +
 asn1crypto/keys.py                       | 1245 ++++++++
 asn1crypto/ocsp.py                       |  649 ++++
 asn1crypto/parser.py                     |  289 ++
 asn1crypto/pdf.py                        |   84 +
 asn1crypto/pem.py                        |  222 ++
 asn1crypto/pkcs12.py                     |  193 ++
 asn1crypto/tsp.py                        |  310 ++
 asn1crypto/util.py                       |  712 +++++
 asn1crypto/version.py                    |    6 +
 asn1crypto/x509.py                       | 2681 ++++++++++++++++
 setup.cfg                                |    5 +
 setup.py                                 |   81 +
 34 files changed, 15932 insertions(+)

diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..b1aeb1a
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,23 @@
+Metadata-Version: 1.1
+Name: asn1crypto
+Version: 0.22.0
+Summary: Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP
+Home-page: https://github.com/wbond/asn1crypto
+Author: wbond
+Author-email: will at wbond.net
+License: MIT
+Description: Docs for this project are maintained at https://github.com/wbond/asn1crypto#readme.
+Keywords: asn1 crypto pki x509 certificate rsa dsa ec dh
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Security :: Cryptography
diff --git a/asn1crypto.egg-info/PKG-INFO b/asn1crypto.egg-info/PKG-INFO
new file mode 100644
index 0000000..b1aeb1a
--- /dev/null
+++ b/asn1crypto.egg-info/PKG-INFO
@@ -0,0 +1,23 @@
+Metadata-Version: 1.1
+Name: asn1crypto
+Version: 0.22.0
+Summary: Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP
+Home-page: https://github.com/wbond/asn1crypto
+Author: wbond
+Author-email: will at wbond.net
+License: MIT
+Description: Docs for this project are maintained at https://github.com/wbond/asn1crypto#readme.
+Keywords: asn1 crypto pki x509 certificate rsa dsa ec dh
+Platform: UNKNOWN
+Classifier: Development Status :: 4 - Beta
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Security :: Cryptography
diff --git a/asn1crypto.egg-info/SOURCES.txt b/asn1crypto.egg-info/SOURCES.txt
new file mode 100644
index 0000000..bc551e1
--- /dev/null
+++ b/asn1crypto.egg-info/SOURCES.txt
@@ -0,0 +1,32 @@
+setup.py
+asn1crypto/__init__.py
+asn1crypto/_elliptic_curve.py
+asn1crypto/_errors.py
+asn1crypto/_ffi.py
+asn1crypto/_inet.py
+asn1crypto/_int.py
+asn1crypto/_iri.py
+asn1crypto/_ordereddict.py
+asn1crypto/_teletex_codec.py
+asn1crypto/_types.py
+asn1crypto/algos.py
+asn1crypto/cms.py
+asn1crypto/core.py
+asn1crypto/crl.py
+asn1crypto/csr.py
+asn1crypto/keys.py
+asn1crypto/ocsp.py
+asn1crypto/parser.py
+asn1crypto/pdf.py
+asn1crypto/pem.py
+asn1crypto/pkcs12.py
+asn1crypto/tsp.py
+asn1crypto/util.py
+asn1crypto/version.py
+asn1crypto/x509.py
+asn1crypto.egg-info/PKG-INFO
+asn1crypto.egg-info/SOURCES.txt
+asn1crypto.egg-info/dependency_links.txt
+asn1crypto.egg-info/top_level.txt
+asn1crypto/_perf/__init__.py
+asn1crypto/_perf/_big_num_ctypes.py
\ No newline at end of file
diff --git a/asn1crypto.egg-info/dependency_links.txt b/asn1crypto.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/asn1crypto.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/asn1crypto.egg-info/top_level.txt b/asn1crypto.egg-info/top_level.txt
new file mode 100644
index 0000000..35a704e
--- /dev/null
+++ b/asn1crypto.egg-info/top_level.txt
@@ -0,0 +1 @@
+asn1crypto
diff --git a/asn1crypto/__init__.py b/asn1crypto/__init__.py
new file mode 100644
index 0000000..afdeb43
--- /dev/null
+++ b/asn1crypto/__init__.py
@@ -0,0 +1,9 @@
+# coding: utf-8
+from __future__ import unicode_literals, division, absolute_import, print_function
+
+from .version import __version__, __version_info__
+
+__all__ = [
+    '__version__',
+    '__version_info__',
+]
diff --git a/asn1crypto/_elliptic_curve.py b/asn1crypto/_elliptic_curve.py
new file mode 100644
index 0000000..0ecab2d
--- /dev/null
+++ b/asn1crypto/_elliptic_curve.py
@@ -0,0 +1,314 @@
+# coding: utf-8
+
+"""
+Classes and objects to represent prime-field elliptic curves and points on them.
+Exports the following items:
+
+ - PrimeCurve()
+ - PrimePoint()
+ - SECP192R1_CURVE
+ - SECP192R1_BASE_POINT
+ - SECP224R1_CURVE
+ - SECP224R1_BASE_POINT
+ - SECP256R1_CURVE
+ - SECP256R1_BASE_POINT
+ - SECP384R1_CURVE
+ - SECP384R1_BASE_POINT
+ - SECP521R1_CURVE
+ - SECP521R1_BASE_POINT
+
+The curve constants are all PrimeCurve() objects and the base point constants
+are all PrimePoint() objects.
+
+Some of the following source code is derived from
+http://webpages.charter.net/curryfans/peter/downloads.html, but has been heavily
+modified to fit into this projects lint settings. The original project license
+is listed below:
+
+Copyright (c) 2014 Peter Pearson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+"""
+
+from __future__ import unicode_literals, division, absolute_import, print_function
+
+from ._int import inverse_mod
+
+
+class PrimeCurve():
+    """
+    Elliptic curve over a prime field. Characteristic two field curves are not
+    supported.
+    """
+
+    def __init__(self, p, a, b):
+        """
+        The curve of points satisfying y^2 = x^3 + a*x + b (mod p)
+
+        :param p:
+            The prime number as an integer
+
+        :param a:
+            The component a as an integer
+
+        :param b:
+            The component b as an integer
+        """
+
+        self.p = p
+        self.a = a
+        self.b = b
+
+    def contains(self, point):
+        """
+        :param point:
+            A Point object
+
+        :return:
+            Boolean if the point is on this curve
+        """
+
+        y2 = point.y * point.y
+        x3 = point.x * point.x * point.x
+        return (y2 - (x3 + self.a * point.x + self.b)) % self.p == 0
+
+
+class PrimePoint():
+    """
+    A point on a prime-field elliptic curve
+    """
+
+    def __init__(self, curve, x, y, order=None):
+        """
+        :param curve:
+            A PrimeCurve object
+
+        :param x:
+            The x coordinate of the point as an integer
+
+        :param y:
+            The y coordinate of the point as an integer
+
+        :param order:
+            The order of the point, as an integer - optional
+        """
+
+        self.curve = curve
+        self.x = x
+        self.y = y
+        self.order = order
+
+        # self.curve is allowed to be None only for INFINITY:
+        if self.curve:
+            if not self.curve.contains(self):
+                raise ValueError('Invalid EC point')
+
+        if self.order:
+            if self * self.order != INFINITY:
+                raise ValueError('Invalid EC point')
+
+    def __cmp__(self, other):
+        """
+        :param other:
+            A PrimePoint object
+
+        :return:
+            0 if identical, 1 otherwise
+        """
+        if self.curve == other.curve and self.x == other.x and self.y == other.y:
+            return 0
+        else:
+            return 1
+
+    def __add__(self, other):
+        """
+        :param other:
+            A PrimePoint object
+
+        :return:
+            A PrimePoint object
+        """
+
+        # X9.62 B.3:
+
+        if other == INFINITY:
+            return self
+        if self == INFINITY:
+            return other
+        assert self.curve == other.curve
+        if self.x == other.x:
+            if (self.y + other.y) % self.curve.p == 0:
+                return INFINITY
+            else:
+                return self.double()
+
+        p = self.curve.p
+
+        l = ((other.y - self.y) * inverse_mod(other.x - self.x, p)) % p
+
+        x3 = (l * l - self.x - other.x) % p
+        y3 = (l * (self.x - x3) - self.y) % p
+
+        return PrimePoint(self.curve, x3, y3)
+
+    def __mul__(self, other):
+        """
+        :param other:
+            An integer to multiple the Point by
+
+        :return:
+            A PrimePoint object
+        """
+
+        def leftmost_bit(x):
+            assert x > 0
+            result = 1
+            while result <= x:
+                result = 2 * result
+            return result // 2
+
+        e = other
+        if self.order:
+            e = e % self.order
+        if e == 0:
+            return INFINITY
+        if self == INFINITY:
+            return INFINITY
+        assert e > 0
+
+        # From X9.62 D.3.2:
+
+        e3 = 3 * e
+        negative_self = PrimePoint(self.curve, self.x, -self.y, self.order)
+        i = leftmost_bit(e3) // 2
+        result = self
+        # print "Multiplying %s by %d (e3 = %d):" % ( self, other, e3 )
+        while i > 1:
+            result = result.double()
+            if (e3 & i) != 0 and (e & i) == 0:
+                result = result + self
+            if (e3 & i) == 0 and (e & i) != 0:
+                result = result + negative_self
+            # print ". . . i = %d, result = %s" % ( i, result )
+            i = i // 2
+
+        return result
+
+    def __rmul__(self, other):
+        """
+        :param other:
+            An integer to multiple the Point by
+
+        :return:
+            A PrimePoint object
+        """
+
+        return self * other
+
+    def double(self):
+        """
+        :return:
+            A PrimePoint object that is twice this point
+        """
+
+        # X9.62 B.3:
+
+        p = self.curve.p
+        a = self.curve.a
+
+        l = ((3 * self.x * self.x + a) * inverse_mod(2 * self.y, p)) % p
+
+        x3 = (l * l - 2 * self.x) % p
+        y3 = (l * (self.x - x3) - self.y) % p
+
+        return PrimePoint(self.curve, x3, y3)
+
+
+# This one point is the Point At Infinity for all purposes:
+INFINITY = PrimePoint(None, None, None)
+
+
+# NIST Curve P-192:
+SECP192R1_CURVE = PrimeCurve(
+    6277101735386680763835789423207666416083908700390324961279,
+    -3,
+    0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1
+)
+SECP192R1_BASE_POINT = PrimePoint(
+    SECP192R1_CURVE,
+    0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012,
+    0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811,
+    6277101735386680763835789423176059013767194773182842284081
+)
+
+
+# NIST Curve P-224:
+SECP224R1_CURVE = PrimeCurve(
+    26959946667150639794667015087019630673557916260026308143510066298881,
+    -3,
+    0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4
+)
+SECP224R1_BASE_POINT = PrimePoint(
+    SECP224R1_CURVE,
+    0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21,
+    0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34,
+    26959946667150639794667015087019625940457807714424391721682722368061
+)
+
+
+# NIST Curve P-256:
+SECP256R1_CURVE = PrimeCurve(
+    115792089210356248762697446949407573530086143415290314195533631308867097853951,
+    -3,
+    0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b
+)
+SECP256R1_BASE_POINT = PrimePoint(
+    SECP256R1_CURVE,
+    0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296,
+    0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5,
+    115792089210356248762697446949407573529996955224135760342422259061068512044369
+)
+
+
+# NIST Curve P-384:
+SECP384R1_CURVE = PrimeCurve(
+    39402006196394479212279040100143613805079739270465446667948293404245721771496870329047266088258938001861606973112319,  # noqa
+    -3,
+    0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef
+)
+SECP384R1_BASE_POINT = PrimePoint(
+    SECP384R1_CURVE,
+    0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7,
+    0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f,
+    39402006196394479212279040100143613805079739270465446667946905279627659399113263569398956308152294913554433653942643
+)
+
+
+# NIST Curve P-521:
+SECP521R1_CURVE = PrimeCurve(
+    6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151,  # noqa
+    -3,
+    0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00  # noqa
+)
+SECP521R1_BASE_POINT = PrimePoint(
+    SECP521R1_CURVE,
+    0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66,  # noqa
+    0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650,  # noqa
+    6864797660130609714981900799081393217269435300143305409394463459185543183397655394245057746333217197532963996371363321113864768612440380340372808892707005449  # noqa
+)
diff --git a/asn1crypto/_errors.py b/asn1crypto/_errors.py
new file mode 100644
index 0000000..cc785a5
--- /dev/null
+++ b/asn1crypto/_errors.py
@@ -0,0 +1,45 @@
+# coding: utf-8
+
+"""
+Helper for formatting exception messages. Exports the following items:
+
+ - unwrap()
+"""
+
+from __future__ import unicode_literals, division, absolute_import, print_function
+
+import re
+import textwrap
+
+
+def unwrap(string, *params):
+    """
+    Takes a multi-line string and does the following:
+
+     - dedents
+     - converts newlines with text before and after into a single line
+     - strips leading and trailing whitespace
+
+    :param string:
+        The string to format
+
+    :param *params:
+        Params to interpolate into the string
+
+    :return:
+        The formatted string
+    """
+
+    output = textwrap.dedent(string)
+
+    # Unwrap lines, taking into account bulleted lists, ordered lists and
+    # underlines consisting of = signs
+    if output.find('\n') != -1:
+        output = re.sub('(?<=\\S)\n(?=[^ \n\t\\d\\*\\-=])', ' ', output)
+
+    if params:
+        output = output % params
+
+    output = output.strip()
+
+    return output
diff --git a/asn1crypto/_ffi.py b/asn1crypto/_ffi.py
new file mode 100644
index 0000000..2a4f5bf
--- /dev/null
+++ b/asn1crypto/_ffi.py
@@ -0,0 +1,45 @@
+# coding: utf-8
+
+"""
+FFI helper compatibility functions. Exports the following items:
+
+ - LibraryNotFoundError
+ - FFIEngineError
+ - bytes_from_buffer()
+ - buffer_from_bytes()
+ - null()
+"""
+
+from __future__ import unicode_literals, division, absolute_import, print_function
+
+from ctypes import create_string_buffer
+
+
+def buffer_from_bytes(initializer):
+    return create_string_buffer(initializer)
+
+
+def bytes_from_buffer(buffer, maxlen=None):
+    return buffer.raw
+
+
+def null():
+    return None
+
+
+class LibraryNotFoundError(Exception):
+
+    """
+    An exception when trying to find a shared library
+    """
+
+    pass
+
+
+class FFIEngineError(Exception):
+
+    """
+    An exception when trying to instantiate ctypes or cffi
+    """
+
+    pass
diff --git a/asn1crypto/_inet.py b/asn1crypto/_inet.py
new file mode 100644
index 0000000..0d78aa4
--- /dev/null
+++ b/asn1crypto/_inet.py
@@ -0,0 +1,170 @@
+# coding: utf-8
+from __future__ import unicode_literals, division, absolute_import, print_function
+
+import socket
+import struct
+
+from ._errors import unwrap
+from ._types import byte_cls, bytes_to_list, str_cls, type_name
+
+
+def inet_ntop(address_family, packed_ip):
+    """
+    Windows compatiblity shim for socket.inet_ntop().
+
+    :param address_family:
+        socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6
+
+    :param packed_ip:
+        A byte string of the network form of an IP address
+
+    :return:
+        A unicode string of the IP address
+    """
+
+    if address_family not in set([socket.AF_INET, socket.AF_INET6]):
+        raise ValueError(unwrap(
+            '''
+            address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s),
+            not %s
+            ''',
+            repr(socket.AF_INET),
+            repr(socket.AF_INET6),
+            repr(address_family)
+        ))
+
+    if not isinstance(packed_ip, byte_cls):
+        raise TypeError(unwrap(
+            '''
+            packed_ip must be a byte string, not %s
+            ''',
+            type_name(packed_ip)
+        ))
+
+    required_len = 4 if address_family == socket.AF_INET else 16
+    if len(packed_ip) != required_len:
+        raise ValueError(unwrap(
+            '''
+            packed_ip must be %d bytes long - is %d
+            ''',
+            required_len,
+            len(packed_ip)
+        ))
+
+    if address_family == socket.AF_INET:
+        return '%d.%d.%d.%d' % tuple(bytes_to_list(packed_ip))
+
+    octets = struct.unpack(b'!HHHHHHHH', packed_ip)
+
+    runs_of_zero = {}
+    longest_run = 0
+    zero_index = None
+    for i, octet in enumerate(octets + (-1,)):
+        if octet != 0:
+            if zero_index is not None:
+                length = i - zero_index
+                if length not in runs_of_zero:
+                    runs_of_zero[length] = zero_index
+                longest_run = max(longest_run, length)
+                zero_index = None
+        elif zero_index is None:
+            zero_index = i
+
+    hexed = [hex(o)[2:] for o in octets]
+
+    if longest_run < 2:
+        return ':'.join(hexed)
+
+    zero_start = runs_of_zero[longest_run]
+    zero_end = zero_start + longest_run
+
+    return ':'.join(hexed[:zero_start]) + '::' + ':'.join(hexed[zero_end:])
+
+
+def inet_pton(address_family, ip_string):
+    """
+    Windows compatiblity shim for socket.inet_ntop().
+
+    :param address_family:
+        socket.AF_INET for IPv4 or socket.AF_INET6 for IPv6
+
+    :param ip_string:
+        A unicode string of an IP address
+
+    :return:
+        A byte string of the network form of the IP address
+    """
+
+    if address_family not in set([socket.AF_INET, socket.AF_INET6]):
+        raise ValueError(unwrap(
+            '''
+            address_family must be socket.AF_INET (%s) or socket.AF_INET6 (%s),
+            not %s
+            ''',
+            repr(socket.AF_INET),
+            repr(socket.AF_INET6),
+            repr(address_family)
+        ))
+
+    if not isinstance(ip_string, str_cls):
+        raise TypeError(unwrap(
+            '''
+            ip_string must be a unicode string, not %s
+            ''',
+            type_name(ip_string)
+        ))
+
+    if address_family == socket.AF_INET:
+        octets = ip_string.split('.')
+        error = len(octets) != 4
+        if not error:
+            ints = []
+            for o in octets:
+                o = int(o)
+                if o > 255 or o < 0:
+                    error = True
+                    break
+                ints.append(o)
+
+        if error:
+            raise ValueError(unwrap(
+                '''
+                ip_string must be a dotted string with four integers in the
+                range of 0 to 255, got %s
+                ''',
+                repr(ip_string)
+            ))
+
+        return struct.pack(b'!BBBB', *ints)
+
+    error = False
+    omitted = ip_string.count('::')
+    if omitted > 1:
+        error = True
+    elif omitted == 0:
+        octets = ip_string.split(':')
+        error = len(octets) != 8
+    else:
+        begin, end = ip_string.split('::')
+        begin_octets = begin.split(':')
+        end_octets = end.split(':')
+        missing = 8 - len(begin_octets) - len(end_octets)
+        octets = begin_octets + (['0'] * missing) + end_octets
+
+    if not error:
+        ints = []
+        for o in octets:
+            o = int(o, 16)
+            if o > 65535 or o < 0:
+                error = True
+                break
+            ints.append(o)
+
+        return struct.pack(b'!HHHHHHHH', *ints)
+
+    raise ValueError(unwrap(
+        '''
+        ip_string must be a valid ipv6 string, got %s
+        ''',
+        repr(ip_string)
+    ))
diff --git a/asn1crypto/_int.py b/asn1crypto/_int.py
new file mode 100644
index 0000000..d0c2319
--- /dev/null
+++ b/asn1crypto/_int.py
@@ -0,0 +1,159 @@
+# coding: utf-8
+
+"""
+Function for calculating the modular inverse. Exports the following items:
+
+ - inverse_mod()
+
+Source code is derived from
+http://webpages.charter.net/curryfans/peter/downloads.html, but has been heavily
+modified to fit into this projects lint settings. The original project license
+is listed below:
+
+Copyright (c) 2014 Peter Pearson
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+"""
+
+from __future__ import unicode_literals, division, absolute_import, print_function
+
+import math
+import platform
+
+from .util import int_to_bytes, int_from_bytes
+
+# First try to use ctypes with OpenSSL for better performance
+try:
+    from ._ffi import (
+        buffer_from_bytes,
+        bytes_from_buffer,
+        FFIEngineError,
+        LibraryNotFoundError,
+        null,
+    )
+
+    # Some versions of PyPy have segfault issues, so we just punt on PyPy
+    if platform.python_implementation() == 'PyPy':
+        raise EnvironmentError()
+
+    try:
+        from ._perf._big_num_ctypes import libcrypto
+
+        def inverse_mod(a, p):
+            """
+            Compute the modular inverse of a (mod p)
+
+            :param a:
+                An integer
+
+            :param p:
+                An integer
+
+            :return:
+                An integer
+            """
+
+            ctx = libcrypto.BN_CTX_new()
+
+            a_bytes = int_to_bytes(abs(a))
+            p_bytes = int_to_bytes(abs(p))
+
+            a_buf = buffer_from_bytes(a_bytes)
+            a_bn = libcrypto.BN_bin2bn(a_buf, len(a_bytes), null())
+            if a < 0:
+                libcrypto.BN_set_negative(a_bn, 1)
+
+            p_buf = buffer_from_bytes(p_bytes)
+            p_bn = libcrypto.BN_bin2bn(p_buf, len(p_bytes), null())
+            if p < 0:
+                libcrypto.BN_set_negative(p_bn, 1)
+
+            r_bn = libcrypto.BN_mod_inverse(null(), a_bn, p_bn, ctx)
+            r_len_bits = libcrypto.BN_num_bits(r_bn)
+            r_len = int(math.ceil(r_len_bits / 8))
+            r_buf = buffer_from_bytes(r_len)
+            libcrypto.BN_bn2bin(r_bn, r_buf)
+            r_bytes = bytes_from_buffer(r_buf, r_len)
+            result = int_from_bytes(r_bytes)
+
+            libcrypto.BN_free(a_bn)
+            libcrypto.BN_free(p_bn)
+            libcrypto.BN_free(r_bn)
+            libcrypto.BN_CTX_free(ctx)
+
+            return result
+    except (LibraryNotFoundError, FFIEngineError):
+        raise EnvironmentError()
+
+# If there was an issue using ctypes or OpenSSL, we fall back to pure python
+except (EnvironmentError, ImportError):
+
+    def inverse_mod(a, p):
+        """
+        Compute the modular inverse of a (mod p)
+
+        :param a:
+            An integer
+
+        :param p:
+            An integer
+
+        :return:
+            An integer
+        """
+
+        if a < 0 or p <= a:
+            a = a % p
+
+        # From Ferguson and Schneier, roughly:
+
+        c, d = a, p
+        uc, vc, ud, vd = 1, 0, 0, 1
+        while c != 0:
+            q, c, d = divmod(d, c) + (c,)
+            uc, vc, ud, vd = ud - q * uc, vd - q * vc, uc, vc
+
+        # At this point, d is the GCD, and ud*a+vd*p = d.
+        # If d == 1, this means that ud is a inverse.
+
+        assert d == 1
+        if ud > 0:
+            return ud
+        else:
+            return ud + p
+
+
+def fill_width(bytes_, width):
+    """
+    Ensure a byte string representing a positive integer is a specific width
+    (in bytes)
+
+    :param bytes_:
+        The integer byte string
+
+    :param width:
+        The desired width as an integer
+
+    :return:
+        A byte string of the width specified
+    """
+
+    while len(bytes_) < width:
+        bytes_ = b'\x00' + bytes_
+    return bytes_
diff --git a/asn1crypto/_iri.py b/asn1crypto/_iri.py
new file mode 100644
index 0000000..57ddd40
--- /dev/null
+++ b/asn1crypto/_iri.py
@@ -0,0 +1,288 @@
+# coding: utf-8
+
+"""
+Functions to convert unicode IRIs into ASCII byte string URIs and back. Exports
+the following items:
+
+ - iri_to_uri()
+ - uri_to_iri()
+"""
+
+from __future__ import unicode_literals, division, absolute_import, print_function
+
+from encodings import idna  # noqa
+import codecs
+import re
+import sys
+
+from ._errors import unwrap
+from ._types import byte_cls, str_cls, type_name, bytes_to_list, int_types
+
+if sys.version_info < (3,):
+    from urlparse import urlsplit, urlunsplit
+    from urllib import (
+        quote as urlquote,
+        unquote as unquote_to_bytes,
+    )
+
+else:
+    from urllib.parse import (
+        quote as urlquote,
+        unquote_to_bytes,
+        urlsplit,
+        urlunsplit,
+    )
+
+
+def iri_to_uri(value):
+    """
+    Normalizes and encodes a unicode IRI into an ASCII byte string URI
+
+    :param value:
+        A unicode string of an IRI
+
+    :return:
+        A byte string of the ASCII-encoded URI
+    """
+
+    if not isinstance(value, str_cls):
+        raise TypeError(unwrap(
+            '''
+            value must be a unicode string, not %s
+            ''',
+            type_name(value)
+        ))
+
+    scheme = None
+    # Python 2.6 doesn't split properly is the URL doesn't start with http:// or https://
+    if sys.version_info < (2, 7) and not value.startswith('http://') and not value.startswith('https://'):
+        real_prefix = None
+        prefix_match = re.match('^[^:]*://', value)
+        if prefix_match:
+            real_prefix = prefix_match.group(0)
+            value = 'http://' + value[len(real_prefix):]
... 15176 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/asn1crypto.git



More information about the Python-modules-commits mailing list