Explorar o código

Hue - Upgrade Python-RSA to safe version

- rsa-4.0 is the last supported in Python2.7
- Python3.8 has rsa-4.7 package

(cherry picked from commit 251f88b1e49e4f1a82b3788309a768a60f393158)
Prakash Ranade %!s(int64=3) %!d(string=hai) anos
pai
achega
4837badcf7
Modificáronse 49 ficheiros con 1491 adicións e 1981 borrados
  1. 0 25
      desktop/core/ext-py/rsa-3.4.2/PKG-INFO
  2. 0 441
      desktop/core/ext-py/rsa-3.4.2/rsa/_version133.py
  3. 0 513
      desktop/core/ext-py/rsa-3.4.2/rsa/_version200.py
  4. 0 135
      desktop/core/ext-py/rsa-3.4.2/rsa/bigfile.py
  5. 0 179
      desktop/core/ext-py/rsa-3.4.2/rsa/varblock.py
  6. 0 73
      desktop/core/ext-py/rsa-3.4.2/tests/test_bigfile.py
  7. 0 32
      desktop/core/ext-py/rsa-3.4.2/tests/test_compat.py
  8. 0 42
      desktop/core/ext-py/rsa-3.4.2/tests/test_key.py
  9. 0 44
      desktop/core/ext-py/rsa-3.4.2/tests/test_prime.py
  10. 0 88
      desktop/core/ext-py/rsa-3.4.2/tests/test_varblock.py
  11. 27 5
      desktop/core/ext-py/rsa-4.0/CHANGELOG.txt
  12. 0 0
      desktop/core/ext-py/rsa-4.0/LICENSE
  13. 0 0
      desktop/core/ext-py/rsa-4.0/MANIFEST.in
  14. 73 0
      desktop/core/ext-py/rsa-4.0/PKG-INFO
  15. 12 13
      desktop/core/ext-py/rsa-4.0/README.md
  16. 0 0
      desktop/core/ext-py/rsa-4.0/create_timing_table.py
  17. 7 7
      desktop/core/ext-py/rsa-4.0/rsa/__init__.py
  18. 41 27
      desktop/core/ext-py/rsa-4.0/rsa/_compat.py
  19. 0 0
      desktop/core/ext-py/rsa-4.0/rsa/asn1.py
  20. 5 100
      desktop/core/ext-py/rsa-4.0/rsa/cli.py
  21. 42 42
      desktop/core/ext-py/rsa-4.0/rsa/common.py
  22. 0 0
      desktop/core/ext-py/rsa-4.0/rsa/core.py
  23. 108 56
      desktop/core/ext-py/rsa-4.0/rsa/key.py
  24. 74 0
      desktop/core/ext-py/rsa-4.0/rsa/machine_size.py
  25. 2 1
      desktop/core/ext-py/rsa-4.0/rsa/parallel.py
  26. 13 12
      desktop/core/ext-py/rsa-4.0/rsa/pem.py
  27. 98 40
      desktop/core/ext-py/rsa-4.0/rsa/pkcs1.py
  28. 103 0
      desktop/core/ext-py/rsa-4.0/rsa/pkcs1_v2.py
  29. 36 13
      desktop/core/ext-py/rsa-4.0/rsa/prime.py
  30. 1 1
      desktop/core/ext-py/rsa-4.0/rsa/randnum.py
  31. 14 23
      desktop/core/ext-py/rsa-4.0/rsa/transform.py
  32. 0 0
      desktop/core/ext-py/rsa-4.0/rsa/util.py
  33. 10 11
      desktop/core/ext-py/rsa-4.0/setup.cfg
  34. 10 5
      desktop/core/ext-py/rsa-4.0/setup.py
  35. 0 0
      desktop/core/ext-py/rsa-4.0/tests/__init__.py
  36. 0 0
      desktop/core/ext-py/rsa-4.0/tests/private.pem
  37. 296 0
      desktop/core/ext-py/rsa-4.0/tests/test_cli.py
  38. 29 10
      desktop/core/ext-py/rsa-4.0/tests/test_common.py
  39. 80 0
      desktop/core/ext-py/rsa-4.0/tests/test_compat.py
  40. 0 0
      desktop/core/ext-py/rsa-4.0/tests/test_integers.py
  41. 79 0
      desktop/core/ext-py/rsa-4.0/tests/test_key.py
  42. 59 18
      desktop/core/ext-py/rsa-4.0/tests/test_load_save_keys.py
  43. 0 0
      desktop/core/ext-py/rsa-4.0/tests/test_parallel.py
  44. 31 3
      desktop/core/ext-py/rsa-4.0/tests/test_pem.py
  45. 36 9
      desktop/core/ext-py/rsa-4.0/tests/test_pkcs1.py
  46. 83 0
      desktop/core/ext-py/rsa-4.0/tests/test_pkcs1_v2.py
  47. 110 0
      desktop/core/ext-py/rsa-4.0/tests/test_prime.py
  48. 0 0
      desktop/core/ext-py/rsa-4.0/tests/test_strings.py
  49. 12 13
      desktop/core/ext-py/rsa-4.0/tests/test_transform.py

+ 0 - 25
desktop/core/ext-py/rsa-3.4.2/PKG-INFO

@@ -1,25 +0,0 @@
-Metadata-Version: 1.1
-Name: rsa
-Version: 3.4.2
-Summary: Pure-Python RSA implementation
-Home-page: https://stuvel.eu/rsa
-Author: Sybren A. Stuvel
-Author-email: sybren@stuvel.eu
-License: ASL 2
-Description: UNKNOWN
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Intended Audience :: Education
-Classifier: Intended Audience :: Information Technology
-Classifier: License :: OSI Approved :: Apache Software License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.6
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Programming Language :: Python :: 3.5
-Classifier: Topic :: Security :: Cryptography

+ 0 - 441
desktop/core/ext-py/rsa-3.4.2/rsa/_version133.py

@@ -1,441 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      https://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-"""Deprecated version of the RSA module
-
-.. deprecated:: 2.0
-
-    This submodule is deprecated and will be completely removed as of version 4.0.
-
-Module for calculating large primes, and RSA encryption, decryption,
-signing and verification. Includes generating public and private keys.
-
-WARNING: this code implements the mathematics of RSA. It is not suitable for
-real-world secure cryptography purposes. It has not been reviewed by a security
-expert. It does not include padding of data. There are many ways in which the
-output of this module, when used without any modification, can be sucessfully
-attacked.
-"""
-
-__author__ = "Sybren Stuvel, Marloes de Boer and Ivo Tamboer"
-__date__ = "2010-02-05"
-__version__ = '1.3.3'
-
-# NOTE: Python's modulo can return negative numbers. We compensate for
-# this behaviour using the abs() function
-
-try:
-    import cPickle as pickle
-except ImportError:
-    import pickle
-from pickle import dumps, loads
-import base64
-import math
-import os
-import random
-import sys
-import types
-import zlib
-
-from rsa._compat import byte
-
-# Display a warning that this insecure version is imported.
-import warnings
-warnings.warn('Insecure version of the RSA module is imported as %s, be careful'
-        % __name__)
-warnings.warn('This submodule is deprecated and will be completely removed as of version 4.0.',
-              DeprecationWarning)
-
-
-def gcd(p, q):
-    """Returns the greatest common divisor of p and q
-
-
-    >>> gcd(42, 6)
-    6
-    """
-    if p<q: return gcd(q, p)
-    if q == 0: return p
-    return gcd(q, abs(p%q))
-
-def bytes2int(bytes):
-    """Converts a list of bytes or a string to an integer
-    """
-
-    if not (type(bytes) is types.ListType or type(bytes) is types.StringType):
-        raise TypeError("You must pass a string or a list")
-
-    # Convert byte stream to integer
-    integer = 0
-    for byte in bytes:
-        integer *= 256
-        if type(byte) is types.StringType: byte = ord(byte)
-        integer += byte
-
-    return integer
-
-def int2bytes(number):
-    """Converts a number to a string of bytes
-    """
-
-    if not (type(number) is types.LongType or type(number) is types.IntType):
-        raise TypeError("You must pass a long or an int")
-
-    string = ""
-
-    while number > 0:
-        string = "%s%s" % (byte(number & 0xFF), string)
-        number /= 256
-    
-    return string
-
-def fast_exponentiation(a, p, n):
-    """Calculates r = a^p mod n
-    """
-    result = a % n
-    remainders = []
-    while p != 1:
-        remainders.append(p & 1)
-        p = p >> 1
-    while remainders:
-        rem = remainders.pop()
-        result = ((a ** rem) * result ** 2) % n
-    return result
-
-def read_random_int(nbits):
-    """Reads a random integer of approximately nbits bits rounded up
-    to whole bytes"""
-
-    nbytes = ceil(nbits/8.)
-    randomdata = os.urandom(nbytes)
-    return bytes2int(randomdata)
-
-def ceil(x):
-    """ceil(x) -> int(math.ceil(x))"""
-
-    return int(math.ceil(x))
-    
-def randint(minvalue, maxvalue):
-    """Returns a random integer x with minvalue <= x <= maxvalue"""
-
-    # Safety - get a lot of random data even if the range is fairly
-    # small
-    min_nbits = 32
-
-    # The range of the random numbers we need to generate
-    range = maxvalue - minvalue
-
-    # Which is this number of bytes
-    rangebytes = ceil(math.log(range, 2) / 8.)
-
-    # Convert to bits, but make sure it's always at least min_nbits*2
-    rangebits = max(rangebytes * 8, min_nbits * 2)
-    
-    # Take a random number of bits between min_nbits and rangebits
-    nbits = random.randint(min_nbits, rangebits)
-    
-    return (read_random_int(nbits) % range) + minvalue
-
-def fermat_little_theorem(p):
-    """Returns 1 if p may be prime, and something else if p definitely
-    is not prime"""
-
-    a = randint(1, p-1)
-    return fast_exponentiation(a, p-1, p)
-
-def jacobi(a, b):
-    """Calculates the value of the Jacobi symbol (a/b)
-    """
-
-    if a % b == 0:
-        return 0
-    result = 1
-    while a > 1:
-        if a & 1:
-            if ((a-1)*(b-1) >> 2) & 1:
-                result = -result
-            b, a = a, b % a
-        else:
-            if ((b ** 2 - 1) >> 3) & 1:
-                result = -result
-            a = a >> 1
-    return result
-
-def jacobi_witness(x, n):
-    """Returns False if n is an Euler pseudo-prime with base x, and
-    True otherwise.
-    """
-
-    j = jacobi(x, n) % n
-    f = fast_exponentiation(x, (n-1)/2, n)
-
-    if j == f: return False
-    return True
-
-def randomized_primality_testing(n, k):
-    """Calculates whether n is composite (which is always correct) or
-    prime (which is incorrect with error probability 2**-k)
-
-    Returns False if the number if composite, and True if it's
-    probably prime.
-    """
-
-    q = 0.5     # Property of the jacobi_witness function
-
-    # t = int(math.ceil(k / math.log(1/q, 2)))
-    t = ceil(k / math.log(1/q, 2))
-    for i in range(t+1):
-        x = randint(1, n-1)
-        if jacobi_witness(x, n): return False
-    
-    return True
-
-def is_prime(number):
-    """Returns True if the number is prime, and False otherwise.
-    """
-
-    """
-    if not fermat_little_theorem(number) == 1:
-        # Not prime, according to Fermat's little theorem
-        return False
-    """
-
-    if randomized_primality_testing(number, 5):
-        # Prime, according to Jacobi
-        return True
-    
-    # Not prime
-    return False
-
-    
-def getprime(nbits):
-    """Returns a prime number of max. 'math.ceil(nbits/8)*8' bits. In
-    other words: nbits is rounded up to whole bytes.
-    """
-
-    nbytes = int(math.ceil(nbits/8.))
-
-    while True:
-        integer = read_random_int(nbits)
-
-        # Make sure it's odd
-        integer |= 1
-
-        # Test for primeness
-        if is_prime(integer): break
-
-        # Retry if not prime
-
-    return integer
-
-def are_relatively_prime(a, b):
-    """Returns True if a and b are relatively prime, and False if they
-    are not.
-    """
-
-    d = gcd(a, b)
-    return (d == 1)
-
-def find_p_q(nbits):
-    """Returns a tuple of two different primes of nbits bits"""
-
-    p = getprime(nbits)
-    while True:
-        q = getprime(nbits)
-        if not q == p: break
-    
-    return (p, q)
-
-def extended_euclid_gcd(a, b):
-    """Returns a tuple (d, i, j) such that d = gcd(a, b) = ia + jb
-    """
-
-    if b == 0:
-        return (a, 1, 0)
-
-    q = abs(a % b)
-    r = long(a / b)
-    (d, k, l) = extended_euclid_gcd(b, q)
-
-    return (d, l, k - l*r)
-
-# Main function: calculate encryption and decryption keys
-def calculate_keys(p, q, nbits):
-    """Calculates an encryption and a decryption key for p and q, and
-    returns them as a tuple (e, d)"""
-
-    n = p * q
-    phi_n = (p-1) * (q-1)
-
-    while True:
-        # Make sure e has enough bits so we ensure "wrapping" through
-        # modulo n
-        e = getprime(max(8, nbits/2))
-        if are_relatively_prime(e, n) and are_relatively_prime(e, phi_n): break
-
-    (d, i, j) = extended_euclid_gcd(e, phi_n)
-
-    if not d == 1:
-        raise Exception("e (%d) and phi_n (%d) are not relatively prime" % (e, phi_n))
-
-    if not (e * i) % phi_n == 1:
-        raise Exception("e (%d) and i (%d) are not mult. inv. modulo phi_n (%d)" % (e, i, phi_n))
-
-    return (e, i)
-
-
-def gen_keys(nbits):
-    """Generate RSA keys of nbits bits. Returns (p, q, e, d).
-
-    Note: this can take a long time, depending on the key size.
-    """
-
-    while True:
-        (p, q) = find_p_q(nbits)
-        (e, d) = calculate_keys(p, q, nbits)
-
-        # For some reason, d is sometimes negative. We don't know how
-        # to fix it (yet), so we keep trying until everything is shiny
-        if d > 0: break
-
-    return (p, q, e, d)
-
-def gen_pubpriv_keys(nbits):
-    """Generates public and private keys, and returns them as (pub,
-    priv).
-
-    The public key consists of a dict {e: ..., , n: ....). The private
-    key consists of a dict {d: ...., p: ...., q: ....).
-    """
-    
-    (p, q, e, d) = gen_keys(nbits)
-
-    return ( {'e': e, 'n': p*q}, {'d': d, 'p': p, 'q': q} )
-
-def encrypt_int(message, ekey, n):
-    """Encrypts a message using encryption key 'ekey', working modulo
-    n"""
-
-    if type(message) is types.IntType:
-        return encrypt_int(long(message), ekey, n)
-
-    if not type(message) is types.LongType:
-        raise TypeError("You must pass a long or an int")
-
-    if message > 0 and \
-            math.floor(math.log(message, 2)) > math.floor(math.log(n, 2)):
-        raise OverflowError("The message is too long")
-
-    return fast_exponentiation(message, ekey, n)
-
-def decrypt_int(cyphertext, dkey, n):
-    """Decrypts a cypher text using the decryption key 'dkey', working
-    modulo n"""
-
-    return encrypt_int(cyphertext, dkey, n)
-
-def sign_int(message, dkey, n):
-    """Signs 'message' using key 'dkey', working modulo n"""
-
-    return decrypt_int(message, dkey, n)
-
-def verify_int(signed, ekey, n):
-    """verifies 'signed' using key 'ekey', working modulo n"""
-
-    return encrypt_int(signed, ekey, n)
-
-def picklechops(chops):
-    """Pickles and base64encodes it's argument chops"""
-
-    value = zlib.compress(dumps(chops))
-    encoded = base64.encodestring(value)
-    return encoded.strip()
-
-def unpicklechops(string):
-    """base64decodes and unpickes it's argument string into chops"""
-
-    return loads(zlib.decompress(base64.decodestring(string)))
-
-def chopstring(message, key, n, funcref):
-    """Splits 'message' into chops that are at most as long as n,
-    converts these into integers, and calls funcref(integer, key, n)
-    for each chop.
-
-    Used by 'encrypt' and 'sign'.
-    """
-
-    msglen = len(message)
-    mbits = msglen * 8
-    nbits = int(math.floor(math.log(n, 2)))
-    nbytes = nbits / 8
-    blocks = msglen / nbytes
-
-    if msglen % nbytes > 0:
-        blocks += 1
-
-    cypher = []
-    
-    for bindex in range(blocks):
-        offset = bindex * nbytes
-        block = message[offset:offset+nbytes]
-        value = bytes2int(block)
-        cypher.append(funcref(value, key, n))
-
-    return picklechops(cypher)
-
-def gluechops(chops, key, n, funcref):
-    """Glues chops back together into a string.  calls
-    funcref(integer, key, n) for each chop.
-
-    Used by 'decrypt' and 'verify'.
-    """
-    message = ""
-
-    chops = unpicklechops(chops)
-    
-    for cpart in chops:
-        mpart = funcref(cpart, key, n)
-        message += int2bytes(mpart)
-    
-    return message
-
-def encrypt(message, key):
-    """Encrypts a string 'message' with the public key 'key'"""
-    
-    return chopstring(message, key['e'], key['n'], encrypt_int)
-
-def sign(message, key):
-    """Signs a string 'message' with the private key 'key'"""
-    
-    return chopstring(message, key['d'], key['p']*key['q'], decrypt_int)
-
-def decrypt(cypher, key):
-    """Decrypts a cypher with the private key 'key'"""
-
-    return gluechops(cypher, key['d'], key['p']*key['q'], decrypt_int)
-
-def verify(cypher, key):
-    """Verifies a cypher with the public key 'key'"""
-
-    return gluechops(cypher, key['e'], key['n'], encrypt_int)
-
-# Do doctest if we're not imported
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()
-
-__all__ = ["gen_pubpriv_keys", "encrypt", "decrypt", "sign", "verify"]
-

+ 0 - 513
desktop/core/ext-py/rsa-3.4.2/rsa/_version200.py

@@ -1,513 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      https://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-"""Deprecated version of the RSA module
-
-.. deprecated:: 3.0
-
-    This submodule is deprecated and will be completely removed as of version 4.0.
-
-"""
-
-__author__ = "Sybren Stuvel, Marloes de Boer, Ivo Tamboer, and Barry Mead"
-__date__ = "2010-02-08"
-__version__ = '2.0'
-
-import math
-import os
-import random
-import sys
-import types
-from rsa._compat import byte
-
-# Display a warning that this insecure version is imported.
-import warnings
-warnings.warn('Insecure version of the RSA module is imported as %s' % __name__)
-warnings.warn('This submodule is deprecated and will be completely removed as of version 4.0.',
-              DeprecationWarning)
-
-
-def bit_size(number):
-    """Returns the number of bits required to hold a specific long number"""
-
-    return int(math.ceil(math.log(number,2)))
-
-def gcd(p, q):
-    """Returns the greatest common divisor of p and q
-    >>> gcd(48, 180)
-    12
-    """
-    # Iterateive Version is faster and uses much less stack space
-    while q != 0:
-        if p < q: (p,q) = (q,p)
-        (p,q) = (q, p % q)
-    return p
-    
-
-def bytes2int(bytes):
-    r"""Converts a list of bytes or a string to an integer
-    """
-
-    if not (type(bytes) is types.ListType or type(bytes) is types.StringType):
-        raise TypeError("You must pass a string or a list")
-
-    # Convert byte stream to integer
-    integer = 0
-    for byte in bytes:
-        integer *= 256
-        if type(byte) is types.StringType: byte = ord(byte)
-        integer += byte
-
-    return integer
-
-def int2bytes(number):
-    """
-    Converts a number to a string of bytes
-    """
-
-    if not (type(number) is types.LongType or type(number) is types.IntType):
-        raise TypeError("You must pass a long or an int")
-
-    string = ""
-
-    while number > 0:
-        string = "%s%s" % (byte(number & 0xFF), string)
-        number /= 256
-    
-    return string
-
-def to64(number):
-    """Converts a number in the range of 0 to 63 into base 64 digit
-    character in the range of '0'-'9', 'A'-'Z', 'a'-'z','-','_'.
-    """
-
-    if not (type(number) is types.LongType or type(number) is types.IntType):
-        raise TypeError("You must pass a long or an int")
-
-    if 0 <= number <= 9:            #00-09 translates to '0' - '9'
-        return byte(number + 48)
-
-    if 10 <= number <= 35:
-        return byte(number + 55)     #10-35 translates to 'A' - 'Z'
-
-    if 36 <= number <= 61:
-        return byte(number + 61)     #36-61 translates to 'a' - 'z'
-
-    if number == 62:                # 62   translates to '-' (minus)
-        return byte(45)
-
-    if number == 63:                # 63   translates to '_' (underscore)
-        return byte(95)
-
-    raise ValueError('Invalid Base64 value: %i' % number)
-
-
-def from64(number):
-    """Converts an ordinal character value in the range of
-    0-9,A-Z,a-z,-,_ to a number in the range of 0-63.
-    """
-
-    if not (type(number) is types.LongType or type(number) is types.IntType):
-        raise TypeError("You must pass a long or an int")
-
-    if 48 <= number <= 57:         #ord('0') - ord('9') translates to 0-9
-        return(number - 48)
-
-    if 65 <= number <= 90:         #ord('A') - ord('Z') translates to 10-35
-        return(number - 55)
-
-    if 97 <= number <= 122:        #ord('a') - ord('z') translates to 36-61
-        return(number - 61)
-
-    if number == 45:               #ord('-') translates to 62
-        return(62)
-
-    if number == 95:               #ord('_') translates to 63
-        return(63)
-
-    raise ValueError('Invalid Base64 value: %i' % number)
-
-
-def int2str64(number):
-    """Converts a number to a string of base64 encoded characters in
-    the range of '0'-'9','A'-'Z,'a'-'z','-','_'.
-    """
-
-    if not (type(number) is types.LongType or type(number) is types.IntType):
-        raise TypeError("You must pass a long or an int")
-
-    string = ""
-
-    while number > 0:
-        string = "%s%s" % (to64(number & 0x3F), string)
-        number /= 64
-
-    return string
-
-
-def str642int(string):
-    """Converts a base64 encoded string into an integer.
-    The chars of this string in in the range '0'-'9','A'-'Z','a'-'z','-','_'
-    """
-
-    if not (type(string) is types.ListType or type(string) is types.StringType):
-        raise TypeError("You must pass a string or a list")
-
-    integer = 0
-    for byte in string:
-        integer *= 64
-        if type(byte) is types.StringType: byte = ord(byte)
-        integer += from64(byte)
-
-    return integer
-
-def read_random_int(nbits):
-    """Reads a random integer of approximately nbits bits rounded up
-    to whole bytes"""
-
-    nbytes = int(math.ceil(nbits/8.))
-    randomdata = os.urandom(nbytes)
-    return bytes2int(randomdata)
-
-def randint(minvalue, maxvalue):
-    """Returns a random integer x with minvalue <= x <= maxvalue"""
-
-    # Safety - get a lot of random data even if the range is fairly
-    # small
-    min_nbits = 32
-
-    # The range of the random numbers we need to generate
-    range = (maxvalue - minvalue) + 1
-
-    # Which is this number of bytes
-    rangebytes = ((bit_size(range) + 7) / 8)
-
-    # Convert to bits, but make sure it's always at least min_nbits*2
-    rangebits = max(rangebytes * 8, min_nbits * 2)
-    
-    # Take a random number of bits between min_nbits and rangebits
-    nbits = random.randint(min_nbits, rangebits)
-    
-    return (read_random_int(nbits) % range) + minvalue
-
-def jacobi(a, b):
-    """Calculates the value of the Jacobi symbol (a/b)
-    where both a and b are positive integers, and b is odd
-    """
-
-    if a == 0: return 0
-    result = 1
-    while a > 1:
-        if a & 1:
-            if ((a-1)*(b-1) >> 2) & 1:
-                result = -result
-            a, b = b % a, a
-        else:
-            if (((b * b) - 1) >> 3) & 1:
-                result = -result
-            a >>= 1
-    if a == 0: return 0
-    return result
-
-def jacobi_witness(x, n):
-    """Returns False if n is an Euler pseudo-prime with base x, and
-    True otherwise.
-    """
-
-    j = jacobi(x, n) % n
-    f = pow(x, (n-1)/2, n)
-
-    if j == f: return False
-    return True
-
-def randomized_primality_testing(n, k):
-    """Calculates whether n is composite (which is always correct) or
-    prime (which is incorrect with error probability 2**-k)
-
-    Returns False if the number is composite, and True if it's
-    probably prime.
-    """
-
-    # 50% of Jacobi-witnesses can report compositness of non-prime numbers
-
-    for i in range(k):
-        x = randint(1, n-1)
-        if jacobi_witness(x, n): return False
-    
-    return True
-
-def is_prime(number):
-    """Returns True if the number is prime, and False otherwise.
-    """
-
-    if randomized_primality_testing(number, 6):
-        # Prime, according to Jacobi
-        return True
-    
-    # Not prime
-    return False
-
-    
-def getprime(nbits):
-    """Returns a prime number of max. 'math.ceil(nbits/8)*8' bits. In
-    other words: nbits is rounded up to whole bytes.
-    """
-
-    while True:
-        integer = read_random_int(nbits)
-
-        # Make sure it's odd
-        integer |= 1
-
-        # Test for primeness
-        if is_prime(integer): break
-
-        # Retry if not prime
-
-    return integer
-
-def are_relatively_prime(a, b):
-    """Returns True if a and b are relatively prime, and False if they
-    are not.
-
-    >>> are_relatively_prime(2, 3)
-    1
-    >>> are_relatively_prime(2, 4)
-    0
-    """
-
-    d = gcd(a, b)
-    return (d == 1)
-
-def find_p_q(nbits):
-    """Returns a tuple of two different primes of nbits bits"""
-    pbits = nbits + (nbits/16)  #Make sure that p and q aren't too close
-    qbits = nbits - (nbits/16)  #or the factoring programs can factor n
-    p = getprime(pbits)
-    while True:
-        q = getprime(qbits)
-        #Make sure p and q are different.
-        if not q == p: break
-    return (p, q)
-
-def extended_gcd(a, b):
-    """Returns a tuple (r, i, j) such that r = gcd(a, b) = ia + jb
-    """
-    # r = gcd(a,b) i = multiplicitive inverse of a mod b
-    #      or      j = multiplicitive inverse of b mod a
-    # Neg return values for i or j are made positive mod b or a respectively
-    # Iterateive Version is faster and uses much less stack space
-    x = 0
-    y = 1
-    lx = 1
-    ly = 0
-    oa = a                             #Remember original a/b to remove 
-    ob = b                             #negative values from return results
-    while b != 0:
-        q = long(a/b)
-        (a, b)  = (b, a % b)
-        (x, lx) = ((lx - (q * x)),x)
-        (y, ly) = ((ly - (q * y)),y)
-    if (lx < 0): lx += ob              #If neg wrap modulo orignal b
-    if (ly < 0): ly += oa              #If neg wrap modulo orignal a
-    return (a, lx, ly)                 #Return only positive values
-
-# Main function: calculate encryption and decryption keys
-def calculate_keys(p, q, nbits):
-    """Calculates an encryption and a decryption key for p and q, and
-    returns them as a tuple (e, d)"""
-
-    n = p * q
-    phi_n = (p-1) * (q-1)
-
-    while True:
-        # Make sure e has enough bits so we ensure "wrapping" through
-        # modulo n
-        e = max(65537,getprime(nbits/4))
-        if are_relatively_prime(e, n) and are_relatively_prime(e, phi_n): break
-
-    (d, i, j) = extended_gcd(e, phi_n)
-
-    if not d == 1:
-        raise Exception("e (%d) and phi_n (%d) are not relatively prime" % (e, phi_n))
-    if (i < 0):
-        raise Exception("New extended_gcd shouldn't return negative values")
-    if not (e * i) % phi_n == 1:
-        raise Exception("e (%d) and i (%d) are not mult. inv. modulo phi_n (%d)" % (e, i, phi_n))
-
-    return (e, i)
-
-
-def gen_keys(nbits):
-    """Generate RSA keys of nbits bits. Returns (p, q, e, d).
-
-    Note: this can take a long time, depending on the key size.
-    """
-
-    (p, q) = find_p_q(nbits)
-    (e, d) = calculate_keys(p, q, nbits)
-
-    return (p, q, e, d)
-
-def newkeys(nbits):
-    """Generates public and private keys, and returns them as (pub,
-    priv).
-
-    The public key consists of a dict {e: ..., , n: ....). The private
-    key consists of a dict {d: ...., p: ...., q: ....).
-    """
-    nbits = max(9,nbits)           # Don't let nbits go below 9 bits
-    (p, q, e, d) = gen_keys(nbits)
-
-    return ( {'e': e, 'n': p*q}, {'d': d, 'p': p, 'q': q} )
-
-def encrypt_int(message, ekey, n):
-    """Encrypts a message using encryption key 'ekey', working modulo n"""
-
-    if type(message) is types.IntType:
-        message = long(message)
-
-    if not type(message) is types.LongType:
-        raise TypeError("You must pass a long or int")
-
-    if message < 0 or message > n:
-        raise OverflowError("The message is too long")
-
-    #Note: Bit exponents start at zero (bit counts start at 1) this is correct
-    safebit = bit_size(n) - 2                   #compute safe bit (MSB - 1)
-    message += (1 << safebit)                   #add safebit to ensure folding
-
-    return pow(message, ekey, n)
-
-def decrypt_int(cyphertext, dkey, n):
-    """Decrypts a cypher text using the decryption key 'dkey', working
-    modulo n"""
-
-    message = pow(cyphertext, dkey, n)
-
-    safebit = bit_size(n) - 2                   #compute safe bit (MSB - 1)
-    message -= (1 << safebit)                   #remove safebit before decode
-
-    return message
-
-def encode64chops(chops):
-    """base64encodes chops and combines them into a ',' delimited string"""
-
-    chips = []                              #chips are character chops
-
-    for value in chops:
-        chips.append(int2str64(value))
-
-    #delimit chops with comma
-    encoded = ','.join(chips)
-
-    return encoded
-
-def decode64chops(string):
-    """base64decodes and makes a ',' delimited string into chops"""
-
-    chips = string.split(',')               #split chops at commas
-
-    chops = []
-
-    for string in chips:                    #make char chops (chips) into chops
-        chops.append(str642int(string))
-
-    return chops
-
-def chopstring(message, key, n, funcref):
-    """Chops the 'message' into integers that fit into n,
-    leaving room for a safebit to be added to ensure that all
-    messages fold during exponentiation.  The MSB of the number n
-    is not independant modulo n (setting it could cause overflow), so
-    use the next lower bit for the safebit.  Therefore reserve 2-bits
-    in the number n for non-data bits.  Calls specified encryption
-    function for each chop.
-
-    Used by 'encrypt' and 'sign'.
-    """
-
-    msglen = len(message)
-    mbits = msglen * 8
-    #Set aside 2-bits so setting of safebit won't overflow modulo n.
-    nbits = bit_size(n) - 2             # leave room for safebit
-    nbytes = nbits / 8
-    blocks = msglen / nbytes
-
-    if msglen % nbytes > 0:
-        blocks += 1
-
-    cypher = []
-    
-    for bindex in range(blocks):
-        offset = bindex * nbytes
-        block = message[offset:offset+nbytes]
-        value = bytes2int(block)
-        cypher.append(funcref(value, key, n))
-
-    return encode64chops(cypher)   #Encode encrypted ints to base64 strings
-
-def gluechops(string, key, n, funcref):
-    """Glues chops back together into a string.  calls
-    funcref(integer, key, n) for each chop.
-
-    Used by 'decrypt' and 'verify'.
-    """
-    message = ""
-
-    chops = decode64chops(string)  #Decode base64 strings into integer chops
-    
-    for cpart in chops:
-        mpart = funcref(cpart, key, n) #Decrypt each chop
-        message += int2bytes(mpart)    #Combine decrypted strings into a msg
-    
-    return message
-
-def encrypt(message, key):
-    """Encrypts a string 'message' with the public key 'key'"""
-    if 'n' not in key:
-        raise Exception("You must use the public key with encrypt")
-
-    return chopstring(message, key['e'], key['n'], encrypt_int)
-
-def sign(message, key):
-    """Signs a string 'message' with the private key 'key'"""
-    if 'p' not in key:
-        raise Exception("You must use the private key with sign")
-
-    return chopstring(message, key['d'], key['p']*key['q'], encrypt_int)
-
-def decrypt(cypher, key):
-    """Decrypts a string 'cypher' with the private key 'key'"""
-    if 'p' not in key:
-        raise Exception("You must use the private key with decrypt")
-
-    return gluechops(cypher, key['d'], key['p']*key['q'], decrypt_int)
-
-def verify(cypher, key):
-    """Verifies a string 'cypher' with the public key 'key'"""
-    if 'n' not in key:
-        raise Exception("You must use the public key with verify")
-
-    return gluechops(cypher, key['e'], key['n'], decrypt_int)
-
-# Do doctest if we're not imported
-if __name__ == "__main__":
-    import doctest
-    doctest.testmod()
-
-__all__ = ["newkeys", "encrypt", "decrypt", "sign", "verify"]
-

+ 0 - 135
desktop/core/ext-py/rsa-3.4.2/rsa/bigfile.py

@@ -1,135 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      https://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-"""Large file support
-
-.. deprecated:: 3.4
-
-    The VARBLOCK format is NOT recommended for general use, has been deprecated since
-    Python-RSA 3.4, and will be removed in a future release. It's vulnerable to a
-    number of attacks:
-
-    1. decrypt/encrypt_bigfile() does not implement `Authenticated encryption`_ nor
-       uses MACs to verify messages before decrypting public key encrypted messages.
-
-    2. decrypt/encrypt_bigfile() does not use hybrid encryption (it uses plain RSA)
-       and has no method for chaining, so block reordering is possible.
-
-    See `issue #19 on Github`_ for more information.
-
-.. _Authenticated encryption: https://en.wikipedia.org/wiki/Authenticated_encryption
-.. _issue #19 on Github: https://github.com/sybrenstuvel/python-rsa/issues/13
-
-
-This module contains functions to:
-
-    - break a file into smaller blocks, and encrypt them, and store the
-      encrypted blocks in another file.
-
-    - take such an encrypted files, decrypt its blocks, and reconstruct the
-      original file.
-
-The encrypted file format is as follows, where || denotes byte concatenation:
-
-    FILE := VERSION || BLOCK || BLOCK ...
-
-    BLOCK := LENGTH || DATA
-
-    LENGTH := varint-encoded length of the subsequent data. Varint comes from
-    Google Protobuf, and encodes an integer into a variable number of bytes.
-    Each byte uses the 7 lowest bits to encode the value. The highest bit set
-    to 1 indicates the next byte is also part of the varint. The last byte will
-    have this bit set to 0.
-
-This file format is called the VARBLOCK format, in line with the varint format
-used to denote the block sizes.
-
-"""
-
-import warnings
-
-from rsa import key, common, pkcs1, varblock
-from rsa._compat import byte
-
-
-def encrypt_bigfile(infile, outfile, pub_key):
-    """Encrypts a file, writing it to 'outfile' in VARBLOCK format.
-
-    .. deprecated:: 3.4
-        This function was deprecated in Python-RSA version 3.4 due to security issues
-        in the VARBLOCK format. See the documentation_ for more information.
-
-    .. _documentation: https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-files
-
-    :param infile: file-like object to read the cleartext from
-    :param outfile: file-like object to write the crypto in VARBLOCK format to
-    :param pub_key: :py:class:`rsa.PublicKey` to encrypt with
-
-    """
-
-    warnings.warn("The 'rsa.bigfile.encrypt_bigfile' function was deprecated in Python-RSA version "
-                  "3.4 due to security issues in the VARBLOCK format. See "
-                  "https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-files "
-                  "for more information.",
-                  DeprecationWarning, stacklevel=2)
-
-    if not isinstance(pub_key, key.PublicKey):
-        raise TypeError('Public key required, but got %r' % pub_key)
-
-    key_bytes = common.bit_size(pub_key.n) // 8
-    blocksize = key_bytes - 11  # keep space for PKCS#1 padding
-
-    # Write the version number to the VARBLOCK file
-    outfile.write(byte(varblock.VARBLOCK_VERSION))
-
-    # Encrypt and write each block
-    for block in varblock.yield_fixedblocks(infile, blocksize):
-        crypto = pkcs1.encrypt(block, pub_key)
-
-        varblock.write_varint(outfile, len(crypto))
-        outfile.write(crypto)
-
-
-def decrypt_bigfile(infile, outfile, priv_key):
-    """Decrypts an encrypted VARBLOCK file, writing it to 'outfile'
-
-    .. deprecated:: 3.4
-        This function was deprecated in Python-RSA version 3.4 due to security issues
-        in the VARBLOCK format. See the documentation_ for more information.
-
-    .. _documentation: https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-files
-
-    :param infile: file-like object to read the crypto in VARBLOCK format from
-    :param outfile: file-like object to write the cleartext to
-    :param priv_key: :py:class:`rsa.PrivateKey` to decrypt with
-
-    """
-
-    warnings.warn("The 'rsa.bigfile.decrypt_bigfile' function was deprecated in Python-RSA version "
-                  "3.4 due to security issues in the VARBLOCK format. See "
-                  "https://stuvel.eu/python-rsa-doc/usage.html#working-with-big-files "
-                  "for more information.",
-                  DeprecationWarning, stacklevel=2)
-
-    if not isinstance(priv_key, key.PrivateKey):
-        raise TypeError('Private key required, but got %r' % priv_key)
-
-    for block in varblock.yield_varblocks(infile):
-        cleartext = pkcs1.decrypt(block, priv_key)
-        outfile.write(cleartext)
-
-
-__all__ = ['encrypt_bigfile', 'decrypt_bigfile']

+ 0 - 179
desktop/core/ext-py/rsa-3.4.2/rsa/varblock.py

@@ -1,179 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      https://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-"""VARBLOCK file support
-
-.. deprecated:: 3.4
-
-    The VARBLOCK format is NOT recommended for general use, has been deprecated since
-    Python-RSA 3.4, and will be removed in a future release. It's vulnerable to a
-    number of attacks:
-
-    1. decrypt/encrypt_bigfile() does not implement `Authenticated encryption`_ nor
-       uses MACs to verify messages before decrypting public key encrypted messages.
-
-    2. decrypt/encrypt_bigfile() does not use hybrid encryption (it uses plain RSA)
-       and has no method for chaining, so block reordering is possible.
-
-    See `issue #19 on Github`_ for more information.
-
-.. _Authenticated encryption: https://en.wikipedia.org/wiki/Authenticated_encryption
-.. _issue #19 on Github: https://github.com/sybrenstuvel/python-rsa/issues/13
-
-
-The VARBLOCK file format is as follows, where || denotes byte concatenation:
-
-    FILE := VERSION || BLOCK || BLOCK ...
-
-    BLOCK := LENGTH || DATA
-
-    LENGTH := varint-encoded length of the subsequent data. Varint comes from
-    Google Protobuf, and encodes an integer into a variable number of bytes.
-    Each byte uses the 7 lowest bits to encode the value. The highest bit set
-    to 1 indicates the next byte is also part of the varint. The last byte will
-    have this bit set to 0.
-
-This file format is called the VARBLOCK format, in line with the varint format
-used to denote the block sizes.
-
-"""
-
-import warnings
-
-from rsa._compat import byte, b
-
-ZERO_BYTE = b('\x00')
-VARBLOCK_VERSION = 1
-
-warnings.warn("The 'rsa.varblock' module was deprecated in Python-RSA version "
-              "3.4 due to security issues in the VARBLOCK format. See "
-              "https://github.com/sybrenstuvel/python-rsa/issues/13 for more information.",
-              DeprecationWarning)
-
-
-def read_varint(infile):
-    """Reads a varint from the file.
-
-    When the first byte to be read indicates EOF, (0, 0) is returned. When an
-    EOF occurs when at least one byte has been read, an EOFError exception is
-    raised.
-
-    :param infile: the file-like object to read from. It should have a read()
-        method.
-    :returns: (varint, length), the read varint and the number of read bytes.
-    """
-
-    varint = 0
-    read_bytes = 0
-
-    while True:
-        char = infile.read(1)
-        if len(char) == 0:
-            if read_bytes == 0:
-                return 0, 0
-            raise EOFError('EOF while reading varint, value is %i so far' %
-                           varint)
-
-        byte = ord(char)
-        varint += (byte & 0x7F) << (7 * read_bytes)
-
-        read_bytes += 1
-
-        if not byte & 0x80:
-            return varint, read_bytes
-
-
-def write_varint(outfile, value):
-    """Writes a varint to a file.
-
-    :param outfile: the file-like object to write to. It should have a write()
-        method.
-    :returns: the number of written bytes.
-    """
-
-    # there is a big difference between 'write the value 0' (this case) and
-    # 'there is nothing left to write' (the false-case of the while loop)
-
-    if value == 0:
-        outfile.write(ZERO_BYTE)
-        return 1
-
-    written_bytes = 0
-    while value > 0:
-        to_write = value & 0x7f
-        value >>= 7
-
-        if value > 0:
-            to_write |= 0x80
-
-        outfile.write(byte(to_write))
-        written_bytes += 1
-
-    return written_bytes
-
-
-def yield_varblocks(infile):
-    """Generator, yields each block in the input file.
-
-    :param infile: file to read, is expected to have the VARBLOCK format as
-        described in the module's docstring.
-    @yields the contents of each block.
-    """
-
-    # Check the version number
-    first_char = infile.read(1)
-    if len(first_char) == 0:
-        raise EOFError('Unable to read VARBLOCK version number')
-
-    version = ord(first_char)
-    if version != VARBLOCK_VERSION:
-        raise ValueError('VARBLOCK version %i not supported' % version)
-
-    while True:
-        (block_size, read_bytes) = read_varint(infile)
-
-        # EOF at block boundary, that's fine.
-        if read_bytes == 0 and block_size == 0:
-            break
-
-        block = infile.read(block_size)
-
-        read_size = len(block)
-        if read_size != block_size:
-            raise EOFError('Block size is %i, but could read only %i bytes' %
-                           (block_size, read_size))
-
-        yield block
-
-
-def yield_fixedblocks(infile, blocksize):
-    """Generator, yields each block of ``blocksize`` bytes in the input file.
-
-    :param infile: file to read and separate in blocks.
-    :returns: a generator that yields the contents of each block
-    """
-
-    while True:
-        block = infile.read(blocksize)
-
-        read_bytes = len(block)
-        if read_bytes == 0:
-            break
-
-        yield block
-
-        if read_bytes < blocksize:
-            break

+ 0 - 73
desktop/core/ext-py/rsa-3.4.2/tests/test_bigfile.py

@@ -1,73 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      https://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-"""Tests block operations."""
-
-from rsa._compat import b
-
-try:
-    from StringIO import StringIO as BytesIO
-except ImportError:
-    from io import BytesIO
-import unittest
-
-import rsa
-from rsa import bigfile, varblock, pkcs1
-
-
-class BigfileTest(unittest.TestCase):
-    def test_encrypt_decrypt_bigfile(self):
-        # Expected block size + 11 bytes padding
-        pub_key, priv_key = rsa.newkeys((6 + 11) * 8)
-
-        # Encrypt the file
-        message = b('123456Sybren')
-        infile = BytesIO(message)
-        outfile = BytesIO()
-
-        bigfile.encrypt_bigfile(infile, outfile, pub_key)
-
-        # Test
-        crypto = outfile.getvalue()
-
-        cryptfile = BytesIO(crypto)
-        clearfile = BytesIO()
-
-        bigfile.decrypt_bigfile(cryptfile, clearfile, priv_key)
-        self.assertEquals(clearfile.getvalue(), message)
-
-        # We have 2x6 bytes in the message, so that should result in two
-        # bigfile.
-        cryptfile.seek(0)
-        varblocks = list(varblock.yield_varblocks(cryptfile))
-        self.assertEqual(2, len(varblocks))
-
-    def test_sign_verify_bigfile(self):
-        # Large enough to store MD5-sum and ASN.1 code for MD5
-        pub_key, priv_key = rsa.newkeys((34 + 11) * 8)
-
-        # Sign the file
-        msgfile = BytesIO(b('123456Sybren'))
-        signature = pkcs1.sign(msgfile, priv_key, 'MD5')
-
-        # Check the signature
-        msgfile.seek(0)
-        self.assertTrue(pkcs1.verify(msgfile, signature, pub_key))
-
-        # Alter the message, re-check
-        msgfile = BytesIO(b('123456sybren'))
-        self.assertRaises(pkcs1.VerificationError,
-                          pkcs1.verify, msgfile, signature, pub_key)

+ 0 - 32
desktop/core/ext-py/rsa-3.4.2/tests/test_compat.py

@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      https://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-import unittest
-import struct
-
-from rsa._compat import is_bytes, byte
-
-
-class TestByte(unittest.TestCase):
-    def test_byte(self):
-        for i in range(256):
-            byt = byte(i)
-            self.assertTrue(is_bytes(byt))
-            self.assertEqual(ord(byt), i)
-
-    def test_raises_StructError_on_overflow(self):
-        self.assertRaises(struct.error, byte, 256)
-        self.assertRaises(struct.error, byte, -1)

+ 0 - 42
desktop/core/ext-py/rsa-3.4.2/tests/test_key.py

@@ -1,42 +0,0 @@
-"""
-Some tests for the rsa/key.py file.
-"""
-
-import unittest
-
-import rsa.key
-import rsa.core
-
-
-class BlindingTest(unittest.TestCase):
-    def test_blinding(self):
-        """Test blinding and unblinding.
-
-        This is basically the doctest of the PrivateKey.blind method, but then
-        implemented as unittest to allow running on different Python versions.
-        """
-
-        pk = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
-
-        message = 12345
-        encrypted = rsa.core.encrypt_int(message, pk.e, pk.n)
-
-        blinded = pk.blind(encrypted, 4134431)  # blind before decrypting
-        decrypted = rsa.core.decrypt_int(blinded, pk.d, pk.n)
-        unblinded = pk.unblind(decrypted, 4134431)
-
-        self.assertEqual(unblinded, message)
-
-
-class KeyGenTest(unittest.TestCase):
-    def test_custom_exponent(self):
-        priv, pub = rsa.key.newkeys(16, exponent=3)
-
-        self.assertEqual(3, priv.e)
-        self.assertEqual(3, pub.e)
-
-    def test_default_exponent(self):
-        priv, pub = rsa.key.newkeys(16)
-
-        self.assertEqual(0x10001, priv.e)
-        self.assertEqual(0x10001, pub.e)

+ 0 - 44
desktop/core/ext-py/rsa-3.4.2/tests/test_prime.py

@@ -1,44 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-"""Tests prime functions."""
-
-import unittest
-
-import rsa.prime
-
-
-class PrimeTest(unittest.TestCase):
-    def test_is_prime(self):
-        """Test some common primes."""
-
-        # Test some trivial numbers
-        self.assertFalse(rsa.prime.is_prime(-1))
-        self.assertFalse(rsa.prime.is_prime(0))
-        self.assertFalse(rsa.prime.is_prime(1))
-        self.assertTrue(rsa.prime.is_prime(2))
-        self.assertFalse(rsa.prime.is_prime(42))
-        self.assertTrue(rsa.prime.is_prime(41))
-
-        # Test some slightly larger numbers
-        self.assertEqual(
-            [907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997],
-            [x for x in range(901, 1000) if rsa.prime.is_prime(x)]
-        )
-
-        # Test around the 50th millionth known prime.
-        self.assertTrue(rsa.prime.is_prime(982451653))
-        self.assertFalse(rsa.prime.is_prime(982451653 * 961748941))

+ 0 - 88
desktop/core/ext-py/rsa-3.4.2/tests/test_varblock.py

@@ -1,88 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
-#
-#  Licensed under the Apache License, Version 2.0 (the "License");
-#  you may not use this file except in compliance with the License.
-#  You may obtain a copy of the License at
-#
-#      https://www.apache.org/licenses/LICENSE-2.0
-#
-#  Unless required by applicable law or agreed to in writing, software
-#  distributed under the License is distributed on an "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#  See the License for the specific language governing permissions and
-#  limitations under the License.
-
-"""Tests varblock operations."""
-
-try:
-    from StringIO import StringIO as BytesIO
-except ImportError:
-    from io import BytesIO
-import unittest
-
-from rsa._compat import b
-from rsa import varblock
-
-
-class VarintTest(unittest.TestCase):
-    def test_read_varint(self):
-        encoded = b('\xac\x02crummy')
-        infile = BytesIO(encoded)
-
-        (decoded, read) = varblock.read_varint(infile)
-
-        # Test the returned values
-        self.assertEqual(300, decoded)
-        self.assertEqual(2, read)
-
-        # The rest of the file should be untouched
-        self.assertEqual(b('crummy'), infile.read())
-
-    def test_read_zero(self):
-        encoded = b('\x00crummy')
-        infile = BytesIO(encoded)
-
-        (decoded, read) = varblock.read_varint(infile)
-
-        # Test the returned values
-        self.assertEqual(0, decoded)
-        self.assertEqual(1, read)
-
-        # The rest of the file should be untouched
-        self.assertEqual(b('crummy'), infile.read())
-
-    def test_write_varint(self):
-        expected = b('\xac\x02')
-        outfile = BytesIO()
-
-        written = varblock.write_varint(outfile, 300)
-
-        # Test the returned values
-        self.assertEqual(expected, outfile.getvalue())
-        self.assertEqual(2, written)
-
-    def test_write_zero(self):
-        outfile = BytesIO()
-        written = varblock.write_varint(outfile, 0)
-
-        # Test the returned values
-        self.assertEqual(b('\x00'), outfile.getvalue())
-        self.assertEqual(1, written)
-
-
-class VarblockTest(unittest.TestCase):
-    def test_yield_varblock(self):
-        infile = BytesIO(b('\x01\x0512345\x06Sybren'))
-
-        varblocks = list(varblock.yield_varblocks(infile))
-        self.assertEqual([b('12345'), b('Sybren')], varblocks)
-
-
-class FixedblockTest(unittest.TestCase):
-    def test_yield_fixedblock(self):
-        infile = BytesIO(b('123456Sybren'))
-
-        fixedblocks = list(varblock.yield_fixedblocks(infile, 6))
-        self.assertEqual([b('123456'), b('Sybren')], fixedblocks)

+ 27 - 5
desktop/core/ext-py/rsa-3.4.2/CHANGELOG.txt → desktop/core/ext-py/rsa-4.0/CHANGELOG.txt

@@ -1,7 +1,30 @@
 Python-RSA changelog
 ========================================
 
-Version 3.4.2 - released 2016-03-26
+Version 4.0 - released 2018-09-16
+----------------------------------------
+
+- Removed deprecated modules:
+    - rsa.varblock
+    - rsa.bigfile
+    - rsa._version133
+    - rsa._version200
+- Removed CLI commands that use the VARBLOCK/bigfile format.
+- Ensured that PublicKey.save_pkcs1() and PrivateKey.save_pkcs1() always return bytes.
+- Dropped support for Python 2.6 and 3.3.
+- Dropped support for Psyco.
+- Miller-Rabin iterations determined by bitsize of key.
+  [#58](https://github.com/sybrenstuvel/python-rsa/pull/58)
+- Added function `rsa.find_signature_hash()` to return the name of the hashing
+  algorithm used to sign a message. `rsa.verify()` now also returns that name,
+  instead of always returning `True`.
+  [#78](https://github.com/sybrenstuvel/python-rsa/issues/13)
+- Add support for SHA-224 for PKCS1 signatures.
+  [#104](https://github.com/sybrenstuvel/python-rsa/pull/104)
+- Transitioned from `requirements.txt` to Pipenv for package management.
+
+
+Version 3.4.2 - released 2016-03-29
 ----------------------------------------
 
 - Fixed dates in CHANGELOG.txt
@@ -17,7 +40,7 @@ Version 3.4.1 - released 2016-03-26
 Version 3.4 - released 2016-03-17
 ----------------------------------------
 
-- Moved development to Github: https://github.com/sybrenstuvel/python-rsa
+- Moved development to GitHub: https://github.com/sybrenstuvel/python-rsa
 - Solved side-channel vulnerability by implementing blinding, fixes #19
 - Deprecated the VARBLOCK format and rsa.bigfile module due to security issues, see
     https://github.com/sybrenstuvel/python-rsa/issues/13
@@ -33,7 +56,7 @@ Version 3.4 - released 2016-03-17
 [1] https://travis-ci.org/sybrenstuvel/python-rsa
 [2] https://coveralls.io/github/sybrenstuvel/python-rsa
 [3] https://codeclimate.com/github/sybrenstuvel/python-rsa
-[4] http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pd
+[4] http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
 
 
 Version 3.3 - released 2016-01-13
@@ -121,7 +144,7 @@ Version 3.0 - released 2011-08-05
   the size of both ``p`` and ``q``. This is the common interpretation of
   RSA keysize. To get the old behaviour, double the keysize when generating a
   new key.
-  
+
 - Added a lot of doctests
 
 - Added random-padded encryption and decryption using PKCS#1 version 1.5
@@ -139,4 +162,3 @@ Version 2.0
 ----------------------------------------
 
 - Security improvements by Barry Mead.
-

+ 0 - 0
desktop/core/ext-py/rsa-3.4.2/LICENSE → desktop/core/ext-py/rsa-4.0/LICENSE


+ 0 - 0
desktop/core/ext-py/rsa-3.4.2/MANIFEST.in → desktop/core/ext-py/rsa-4.0/MANIFEST.in


+ 73 - 0
desktop/core/ext-py/rsa-4.0/PKG-INFO

@@ -0,0 +1,73 @@
+Metadata-Version: 2.1
+Name: rsa
+Version: 4.0
+Summary: Pure-Python RSA implementation
+Home-page: https://stuvel.eu/rsa
+Author: Sybren A. Stuvel
+Author-email: sybren@stuvel.eu
+Maintainer: Sybren A. Stuvel
+Maintainer-email: sybren@stuvel.eu
+License: ASL 2
+Description: Pure Python RSA implementation
+        ==============================
+        
+        [![PyPI](https://img.shields.io/pypi/v/rsa.svg)](https://pypi.org/project/rsa/)
+        [![Build Status](https://travis-ci.org/sybrenstuvel/python-rsa.svg?branch=master)](https://travis-ci.org/sybrenstuvel/python-rsa)
+        [![Coverage Status](https://coveralls.io/repos/github/sybrenstuvel/python-rsa/badge.svg?branch=master)](https://coveralls.io/github/sybrenstuvel/python-rsa?branch=master)
+        [![Code Climate](https://img.shields.io/codeclimate/github/sybrenstuvel/python-rsa.svg)](https://codeclimate.com/github/sybrenstuvel/python-rsa)
+        
+        [Python-RSA](https://stuvel.eu/rsa) is a pure-Python RSA implementation. It supports
+        encryption and decryption, signing and verifying signatures, and key
+        generation according to PKCS#1 version 1.5. It can be used as a Python
+        library as well as on the commandline. The code was mostly written by
+        Sybren A.  Stüvel.
+        
+        Documentation can be found at the [Python-RSA homepage](https://stuvel.eu/rsa).
+        
+        Download and install using:
+        
+            pip install rsa
+        
+        or download it from the [Python Package Index](https://pypi.org/project/rsa/).
+        
+        The source code is maintained at [GitHub](https://github.com/sybrenstuvel/python-rsa/) and is
+        licensed under the [Apache License, version 2.0](https://www.apache.org/licenses/LICENSE-2.0)
+        
+        
+        Major changes in 4.0
+        --------------------
+        
+        Version 3.4 was the last version in the 3.x range. Version 4.0 drops the following modules,
+        as they are insecure:
+        
+        - `rsa._version133`
+        - `rsa._version200`
+        - `rsa.bigfile`
+        - `rsa.varblock`
+        
+        Those modules were marked as deprecated in version 3.4.
+        
+        Furthermore, in 4.0 the I/O functions is streamlined to always work with bytes on all
+        supported versions of Python.
+        
+        Version 4.0 drops support for Python 2.6 and 3.3.
+        
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: Education
+Classifier: Intended Audience :: Information Technology
+Classifier: License :: OSI Approved :: Apache Software License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Security :: Cryptography
+Description-Content-Type: text/markdown

+ 12 - 13
desktop/core/ext-py/rsa-3.4.2/README.md → desktop/core/ext-py/rsa-4.0/README.md

@@ -1,13 +1,10 @@
 Pure Python RSA implementation
 ==============================
 
-[![PyPI](https://img.shields.io/pypi/v/rsa.svg)](https://pypi.python.org/pypi/rsa)
-[![Build Status](https://travis-ci.org/sybrenstuvel/python-rsa.svg?branch=master)]
-    (https://travis-ci.org/sybrenstuvel/python-rsa)
-[![Coverage Status](https://coveralls.io/repos/github/sybrenstuvel/python-rsa/badge.svg?branch=master)]
-    (https://coveralls.io/github/sybrenstuvel/python-rsa?branch=master)
-[![Code Climate](https://img.shields.io/codeclimate/github/sybrenstuvel/python-rsa.svg)]
-    (https://codeclimate.com/github/sybrenstuvel/python-rsa)
+[![PyPI](https://img.shields.io/pypi/v/rsa.svg)](https://pypi.org/project/rsa/)
+[![Build Status](https://travis-ci.org/sybrenstuvel/python-rsa.svg?branch=master)](https://travis-ci.org/sybrenstuvel/python-rsa)
+[![Coverage Status](https://coveralls.io/repos/github/sybrenstuvel/python-rsa/badge.svg?branch=master)](https://coveralls.io/github/sybrenstuvel/python-rsa?branch=master)
+[![Code Climate](https://img.shields.io/codeclimate/github/sybrenstuvel/python-rsa.svg)](https://codeclimate.com/github/sybrenstuvel/python-rsa)
 
 [Python-RSA](https://stuvel.eu/rsa) is a pure-Python RSA implementation. It supports
 encryption and decryption, signing and verifying signatures, and key
@@ -21,16 +18,16 @@ Download and install using:
 
     pip install rsa
 
-or download it from the [Python Package Index](https://pypi.python.org/pypi/rsa).
+or download it from the [Python Package Index](https://pypi.org/project/rsa/).
 
-The source code is maintained at [Github](https://github.com/sybrenstuvel/python-rsa/) and is
+The source code is maintained at [GitHub](https://github.com/sybrenstuvel/python-rsa/) and is
 licensed under the [Apache License, version 2.0](https://www.apache.org/licenses/LICENSE-2.0)
 
 
-Plans for the future
+Major changes in 4.0
 --------------------
 
-Version 3.4 is the last version in the 3.x range. Version 4.0 will drop the following modules,
+Version 3.4 was the last version in the 3.x range. Version 4.0 drops the following modules,
 as they are insecure:
 
 - `rsa._version133`
@@ -38,7 +35,9 @@ as they are insecure:
 - `rsa.bigfile`
 - `rsa.varblock`
 
-Those modules are marked as deprecated in version 3.4.
+Those modules were marked as deprecated in version 3.4.
 
-Furthermore, in 4.0 the I/O functions will be streamlined to always work with bytes on all
+Furthermore, in 4.0 the I/O functions is streamlined to always work with bytes on all
 supported versions of Python.
+
+Version 4.0 drops support for Python 2.6 and 3.3.

+ 0 - 0
desktop/core/ext-py/rsa-3.4.2/create_timing_table.py → desktop/core/ext-py/rsa-4.0/create_timing_table.py


+ 7 - 7
desktop/core/ext-py/rsa-3.4.2/rsa/__init__.py → desktop/core/ext-py/rsa-4.0/rsa/__init__.py

@@ -18,19 +18,18 @@
 Module for calculating large primes, and RSA encryption, decryption, signing
 and verification. Includes generating public and private keys.
 
-WARNING: this implementation does not use random padding, compression of the
-cleartext input to prevent repetitions, or other common security improvements.
-Use with care.
+WARNING: this implementation does not use compression of the cleartext input to
+prevent repetitions, or other common security improvements. Use with care.
 
 """
 
 from rsa.key import newkeys, PrivateKey, PublicKey
 from rsa.pkcs1 import encrypt, decrypt, sign, verify, DecryptionError, \
-    VerificationError
+    VerificationError, find_signature_hash,  sign_hash, compute_hash
 
 __author__ = "Sybren Stuvel, Barry Mead and Yesudeep Mangalapilly"
-__date__ = "2016-03-29"
-__version__ = '3.4.2'
+__date__ = "2018-09-16"
+__version__ = '4.0'
 
 # Do doctest if we're run directly
 if __name__ == "__main__":
@@ -39,4 +38,5 @@ if __name__ == "__main__":
     doctest.testmod()
 
 __all__ = ["newkeys", "encrypt", "decrypt", "sign", "verify", 'PublicKey',
-           'PrivateKey', 'DecryptionError', 'VerificationError']
+           'PrivateKey', 'DecryptionError', 'VerificationError',
+           'compute_hash', 'sign_hash']

+ 41 - 27
desktop/core/ext-py/rsa-3.4.2/rsa/_compat.py → desktop/core/ext-py/rsa-4.0/rsa/_compat.py

@@ -18,18 +18,17 @@
 
 from __future__ import absolute_import
 
+import itertools
 import sys
 from struct import pack
 
-try:
-    MAX_INT = sys.maxsize
-except AttributeError:
-    MAX_INT = sys.maxint
-
+MAX_INT = sys.maxsize
 MAX_INT64 = (1 << 63) - 1
 MAX_INT32 = (1 << 31) - 1
 MAX_INT16 = (1 << 15) - 1
 
+PY2 = sys.version_info[0] == 2
+
 # Determine the word size of the processor.
 if MAX_INT == MAX_INT64:
     # 64-bit processor.
@@ -41,32 +40,26 @@ else:
     # Else we just assume 64-bit processor keeping up with modern times.
     MACHINE_WORD_SIZE = 64
 
-try:
-    # < Python3
-    unicode_type = unicode
-except NameError:
-    # Python3.
-    unicode_type = str
-
-# Fake byte literals.
-if str is unicode_type:
-    def byte_literal(s):
-        return s.encode('latin1')
+if PY2:
+    integer_types = (int, long)
+    range = xrange
+    zip = itertools.izip
 else:
-    def byte_literal(s):
-        return s
+    integer_types = (int, )
+    range = range
+    zip = zip
 
-# ``long`` is no more. Do type detection using this instead.
-try:
-    integer_types = (int, long)
-except NameError:
-    integer_types = (int,)
 
-b = byte_literal
+def write_to_stdout(data):
+    """Writes bytes to stdout
 
-# To avoid calling b() multiple times in tight loops.
-ZERO_BYTE = b('\x00')
-EMPTY_BYTE = b('')
+    :type data: bytes
+    """
+    if PY2:
+        sys.stdout.write(data)
+    else:
+        # On Py3 we must use the buffer interface to write bytes.
+        sys.stdout.buffer.write(data)
 
 
 def is_bytes(obj):
@@ -109,6 +102,27 @@ def byte(num):
     return pack("B", num)
 
 
+def xor_bytes(b1, b2):
+    """
+    Returns the bitwise XOR result between two bytes objects, b1 ^ b2.
+
+    Bitwise XOR operation is commutative, so order of parameters doesn't
+    generate different results. If parameters have different length, extra
+    length of the largest one is ignored.
+
+    :param b1:
+        First bytes object.
+    :param b2:
+        Second bytes object.
+    :returns:
+        Bytes object, result of XOR operation.
+    """
+    if PY2:
+        return ''.join(byte(ord(x) ^ ord(y)) for x, y in zip(b1, b2))
+
+    return bytes(x ^ y for x, y in zip(b1, b2))
+
+
 def get_word_alignment(num, force_arch=64,
                        _machine_word_size=MACHINE_WORD_SIZE):
     """

+ 0 - 0
desktop/core/ext-py/rsa-3.4.2/rsa/asn1.py → desktop/core/ext-py/rsa-4.0/rsa/asn1.py


+ 5 - 100
desktop/core/ext-py/rsa-3.4.2/rsa/cli.py → desktop/core/ext-py/rsa-4.0/rsa/cli.py

@@ -26,7 +26,6 @@ import sys
 from optparse import OptionParser
 
 import rsa
-import rsa.bigfile
 import rsa.pkcs1
 
 HASH_METHODS = sorted(rsa.pkcs1.HASH_METHODS.keys())
@@ -84,7 +83,7 @@ def keygen():
             outfile.write(data)
     else:
         print('Writing private key to stdout', file=sys.stderr)
-        sys.stdout.write(data)
+        rsa._compat.write_to_stdout(data)
 
 
 class CryptoOperation(object):
@@ -113,7 +112,7 @@ class CryptoOperation(object):
         self.output_help = self.output_help % self.__class__.__dict__
 
     @abc.abstractmethod
-    def perform_operation(self, indata, key, cli_args=None):
+    def perform_operation(self, indata, key, cli_args):
         """Performs the program's operation.
 
         Implement in a subclass.
@@ -190,7 +189,7 @@ class CryptoOperation(object):
                 outfile.write(outdata)
         else:
             print('Writing output to stdout', file=sys.stderr)
-            sys.stdout.write(outdata)
+            rsa._compat.write_to_stdout(outdata)
 
 
 class EncryptOperation(CryptoOperation):
@@ -198,8 +197,7 @@ class EncryptOperation(CryptoOperation):
 
     keyname = 'public'
     description = ('Encrypts a file. The file must be shorter than the key '
-                   'length in order to be encrypted. For larger files, use the '
-                   'pyrsa-encrypt-bigfile command.')
+                   'length in order to be encrypted.')
     operation = 'encrypt'
     operation_past = 'encrypted'
     operation_progressive = 'encrypting'
@@ -215,8 +213,7 @@ class DecryptOperation(CryptoOperation):
 
     keyname = 'private'
     description = ('Decrypts a file. The original file must be shorter than '
-                   'the key length in order to have been encrypted. For larger '
-                   'files, use the pyrsa-decrypt-bigfile command.')
+                   'the key length in order to have been encrypted.')
     operation = 'decrypt'
     operation_past = 'decrypted'
     operation_progressive = 'decrypting'
@@ -285,99 +282,7 @@ class VerifyOperation(CryptoOperation):
         print('Verification OK', file=sys.stderr)
 
 
-class BigfileOperation(CryptoOperation):
-    """CryptoOperation that doesn't read the entire file into memory."""
-
-    def __init__(self):
-        CryptoOperation.__init__(self)
-
-        self.file_objects = []
-
-    def __del__(self):
-        """Closes any open file handles."""
-
-        for fobj in self.file_objects:
-            fobj.close()
-
-    def __call__(self):
-        """Runs the program."""
-
-        (cli, cli_args) = self.parse_cli()
-
-        key = self.read_key(cli_args[0], cli.keyform)
-
-        # Get the file handles
-        infile = self.get_infile(cli.input)
-        outfile = self.get_outfile(cli.output)
-
-        # Call the operation
-        print(self.operation_progressive.title(), file=sys.stderr)
-        self.perform_operation(infile, outfile, key, cli_args)
-
-    def get_infile(self, inname):
-        """Returns the input file object"""
-
-        if inname:
-            print('Reading input from %s' % inname, file=sys.stderr)
-            fobj = open(inname, 'rb')
-            self.file_objects.append(fobj)
-        else:
-            print('Reading input from stdin', file=sys.stderr)
-            fobj = sys.stdin
-
-        return fobj
-
-    def get_outfile(self, outname):
-        """Returns the output file object"""
-
-        if outname:
-            print('Will write output to %s' % outname, file=sys.stderr)
-            fobj = open(outname, 'wb')
-            self.file_objects.append(fobj)
-        else:
-            print('Will write output to stdout', file=sys.stderr)
-            fobj = sys.stdout
-
-        return fobj
-
-
-class EncryptBigfileOperation(BigfileOperation):
-    """Encrypts a file to VARBLOCK format."""
-
-    keyname = 'public'
-    description = ('Encrypts a file to an encrypted VARBLOCK file. The file '
-                   'can be larger than the key length, but the output file is only '
-                   'compatible with Python-RSA.')
-    operation = 'encrypt'
-    operation_past = 'encrypted'
-    operation_progressive = 'encrypting'
-
-    def perform_operation(self, infile, outfile, pub_key, cli_args=None):
-        """Encrypts files to VARBLOCK."""
-
-        return rsa.bigfile.encrypt_bigfile(infile, outfile, pub_key)
-
-
-class DecryptBigfileOperation(BigfileOperation):
-    """Decrypts a file in VARBLOCK format."""
-
-    keyname = 'private'
-    description = ('Decrypts an encrypted VARBLOCK file that was encrypted '
-                   'with pyrsa-encrypt-bigfile')
-    operation = 'decrypt'
-    operation_past = 'decrypted'
-    operation_progressive = 'decrypting'
-    key_class = rsa.PrivateKey
-
-    def perform_operation(self, infile, outfile, priv_key, cli_args=None):
-        """Decrypts a VARBLOCK file."""
-
-        return rsa.bigfile.decrypt_bigfile(infile, outfile, priv_key)
-
-
 encrypt = EncryptOperation()
 decrypt = DecryptOperation()
 sign = SignOperation()
 verify = VerifyOperation()
-encrypt_bigfile = EncryptBigfileOperation()
-decrypt_bigfile = DecryptBigfileOperation()

+ 42 - 42
desktop/core/ext-py/rsa-3.4.2/rsa/common.py → desktop/core/ext-py/rsa-4.0/rsa/common.py

@@ -14,17 +14,25 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
+from rsa._compat import zip
+
 """Common functionality shared by several modules."""
 
 
+class NotRelativePrimeError(ValueError):
+    def __init__(self, a, b, d, msg=None):
+        super(NotRelativePrimeError, self).__init__(
+            msg or "%d and %d are not relatively prime, divider=%i" % (a, b, d))
+        self.a = a
+        self.b = b
+        self.d = d
+
+
 def bit_size(num):
     """
     Number of bits needed to represent a integer excluding any prefix
     0 bits.
 
-    As per definition from https://wiki.python.org/moin/BitManipulation and
-    to match the behavior of the Python 3 API.
-
     Usage::
 
         >>> bit_size(1023)
@@ -41,41 +49,11 @@ def bit_size(num):
     :returns:
         Returns the number of bits in the integer.
     """
-    if num == 0:
-        return 0
-    if num < 0:
-        num = -num
-
-    # Make sure this is an int and not a float.
-    num & 1
-
-    hex_num = "%x" % num
-    return ((len(hex_num) - 1) * 4) + {
-        '0': 0, '1': 1, '2': 2, '3': 2,
-        '4': 3, '5': 3, '6': 3, '7': 3,
-        '8': 4, '9': 4, 'a': 4, 'b': 4,
-        'c': 4, 'd': 4, 'e': 4, 'f': 4,
-    }[hex_num[0]]
-
-
-def _bit_size(number):
-    """
-    Returns the number of bits required to hold a specific long number.
-    """
-    if number < 0:
-        raise ValueError('Only nonnegative numbers possible: %s' % number)
-
-    if number == 0:
-        return 0
 
-    # This works, even with very large numbers. When using math.log(number, 2),
-    # you'll get rounding errors and it'll fail.
-    bits = 0
-    while number:
-        bits += 1
-        number >>= 1
-
-    return bits
+    try:
+        return num.bit_length()
+    except AttributeError:
+        raise TypeError('bit_size(num) only supports integers, not %r' % type(num))
 
 
 def byte_size(number):
@@ -98,11 +76,33 @@ def byte_size(number):
     :returns:
         The number of bytes required to hold a specific long number.
     """
-    quanta, mod = divmod(bit_size(number), 8)
-    if mod or number == 0:
+    if number == 0:
+        return 1
+    return ceil_div(bit_size(number), 8)
+
+
+def ceil_div(num, div):
+    """
+    Returns the ceiling function of a division between `num` and `div`.
+
+    Usage::
+
+        >>> ceil_div(100, 7)
+        15
+        >>> ceil_div(100, 10)
+        10
+        >>> ceil_div(1, 4)
+        1
+
+    :param num: Division's numerator, a number
+    :param div: Division's divisor, a number
+
+    :return: Rounded up result of the division between the parameters.
+    """
+    quanta, mod = divmod(num, div)
+    if mod:
         quanta += 1
     return quanta
-    # return int(math.ceil(bit_size(number) / 8.0))
 
 
 def extended_gcd(a, b):
@@ -131,7 +131,7 @@ def extended_gcd(a, b):
 
 
 def inverse(x, n):
-    """Returns x^-1 (mod n)
+    """Returns the inverse of x % n under multiplication, a.k.a x^-1 (mod n)
 
     >>> inverse(7, 4)
     3
@@ -142,7 +142,7 @@ def inverse(x, n):
     (divider, inv, _) = extended_gcd(x, n)
 
     if divider != 1:
-        raise ValueError("x (%d) and n (%d) are not relatively prime" % (x, n))
+        raise NotRelativePrimeError(x, n, divider)
 
     return inv
 

+ 0 - 0
desktop/core/ext-py/rsa-3.4.2/rsa/core.py → desktop/core/ext-py/rsa-4.0/rsa/core.py


+ 108 - 56
desktop/core/ext-py/rsa-3.4.2/rsa/key.py → desktop/core/ext-py/rsa-4.0/rsa/key.py

@@ -34,14 +34,16 @@ of pyasn1.
 """
 
 import logging
-from rsa._compat import b
+import warnings
 
+from rsa._compat import range
 import rsa.prime
 import rsa.pem
 import rsa.common
 import rsa.randnum
 import rsa.core
 
+
 log = logging.getLogger(__name__)
 DEFAULT_EXPONENT = 65537
 
@@ -55,15 +57,56 @@ class AbstractKey(object):
         self.n = n
         self.e = e
 
+    @classmethod
+    def _load_pkcs1_pem(cls, keyfile):
+        """Loads a key in PKCS#1 PEM format, implement in a subclass.
+
+        :param keyfile: contents of a PEM-encoded file that contains
+            the public key.
+        :type keyfile: bytes
+
+        :return: the loaded key
+        :rtype: AbstractKey
+        """
+
+    @classmethod
+    def _load_pkcs1_der(cls, keyfile):
+        """Loads a key in PKCS#1 PEM format, implement in a subclass.
+
+        :param keyfile: contents of a DER-encoded file that contains
+            the public key.
+        :type keyfile: bytes
+
+        :return: the loaded key
+        :rtype: AbstractKey
+        """
+
+    def _save_pkcs1_pem(self):
+        """Saves the key in PKCS#1 PEM format, implement in a subclass.
+
+        :returns: the PEM-encoded key.
+        :rtype: bytes
+        """
+
+    def _save_pkcs1_der(self):
+        """Saves the key in PKCS#1 DER format, implement in a subclass.
+
+        :returns: the DER-encoded key.
+        :rtype: bytes
+        """
+
     @classmethod
     def load_pkcs1(cls, keyfile, format='PEM'):
         """Loads a key in PKCS#1 DER or PEM format.
 
         :param keyfile: contents of a DER- or PEM-encoded file that contains
-            the public key.
+            the key.
+        :type keyfile: bytes
         :param format: the format of the file to load; 'PEM' or 'DER'
+        :type format: str
 
-        :return: a PublicKey object
+        :return: the loaded key
+        :rtype: AbstractKey
         """
 
         methods = {
@@ -87,10 +130,12 @@ class AbstractKey(object):
                                                                         formats))
 
     def save_pkcs1(self, format='PEM'):
-        """Saves the public key in PKCS#1 DER or PEM format.
+        """Saves the key in PKCS#1 DER or PEM format.
 
         :param format: the format to save; 'PEM' or 'DER'
-        :returns: the DER- or PEM-encoded public key.
+        :type format: str
+        :returns: the DER- or PEM-encoded key.
+        :rtype: bytes
         """
 
         methods = {
@@ -139,7 +184,7 @@ class PublicKey(AbstractKey):
     This key is also known as the 'encryption key'. It contains the 'n' and 'e'
     values.
 
-    Supports attributes as well as dictionary-like access. Attribute accesss is
+    Supports attributes as well as dictionary-like access. Attribute access is
     faster, though.
 
     >>> PublicKey(5, 3)
@@ -185,6 +230,9 @@ class PublicKey(AbstractKey):
     def __ne__(self, other):
         return not (self == other)
 
+    def __hash__(self):
+        return hash((self.n, self.e))
+
     @classmethod
     def _load_pkcs1_der(cls, keyfile):
         """Loads a key in PKCS#1 DER format.
@@ -215,7 +263,8 @@ class PublicKey(AbstractKey):
     def _save_pkcs1_der(self):
         """Saves the public key in PKCS#1 DER format.
 
-        @returns: the DER-encoded public key.
+        :returns: the DER-encoded public key.
+        :rtype: bytes
         """
 
         from pyasn1.codec.der import encoder
@@ -247,6 +296,7 @@ class PublicKey(AbstractKey):
         """Saves a PKCS#1 PEM-encoded public key file.
 
         :return: contents of a PEM-encoded file that contains the public key.
+        :rtype: bytes
         """
 
         der = self._save_pkcs1_der()
@@ -264,6 +314,7 @@ class PublicKey(AbstractKey):
 
         :param keyfile: contents of a PEM-encoded file that contains the public
             key, from OpenSSL.
+        :type keyfile: bytes
         :return: a PublicKey object
         """
 
@@ -277,6 +328,7 @@ class PublicKey(AbstractKey):
         :param keyfile: contents of a DER-encoded file that contains the public
             key, from OpenSSL.
         :return: a PublicKey object
+        :rtype: bytes
 
         """
 
@@ -298,57 +350,36 @@ class PrivateKey(AbstractKey):
     This key is also known as the 'decryption key'. It contains the 'n', 'e',
     'd', 'p', 'q' and other values.
 
-    Supports attributes as well as dictionary-like access. Attribute accesss is
+    Supports attributes as well as dictionary-like access. Attribute access is
     faster, though.
 
     >>> PrivateKey(3247, 65537, 833, 191, 17)
     PrivateKey(3247, 65537, 833, 191, 17)
 
-    exp1, exp2 and coef can be given, but if None or omitted they will be calculated:
+    exp1, exp2 and coef will be calculated:
 
-    >>> pk = PrivateKey(3727264081, 65537, 3349121513, 65063, 57287, exp2=4)
+    >>> pk = PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
     >>> pk.exp1
     55063
-    >>> pk.exp2  # this is of course not a correct value, but it is the one we passed.
-    4
-    >>> pk.coef
-    50797
-
-    If you give exp1, exp2 or coef, they will be used as-is:
-
-    >>> pk = PrivateKey(1, 2, 3, 4, 5, 6, 7, 8)
-    >>> pk.exp1
-    6
     >>> pk.exp2
-    7
+    10095
     >>> pk.coef
-    8
+    50797
 
     """
 
     __slots__ = ('n', 'e', 'd', 'p', 'q', 'exp1', 'exp2', 'coef')
 
-    def __init__(self, n, e, d, p, q, exp1=None, exp2=None, coef=None):
+    def __init__(self, n, e, d, p, q):
         AbstractKey.__init__(self, n, e)
         self.d = d
         self.p = p
         self.q = q
 
-        # Calculate the other values if they aren't supplied
-        if exp1 is None:
-            self.exp1 = int(d % (p - 1))
-        else:
-            self.exp1 = exp1
-
-        if exp2 is None:
-            self.exp2 = int(d % (q - 1))
-        else:
-            self.exp2 = exp2
-
-        if coef is None:
-            self.coef = rsa.common.inverse(q, p)
-        else:
-            self.coef = coef
+        # Calculate exponents and coefficient.
+        self.exp1 = int(d % (p - 1))
+        self.exp2 = int(d % (q - 1))
+        self.coef = rsa.common.inverse(q, p)
 
     def __getitem__(self, key):
         return getattr(self, key)
@@ -383,6 +414,9 @@ class PrivateKey(AbstractKey):
     def __ne__(self, other):
         return not (self == other)
 
+    def __hash__(self):
+        return hash((self.n, self.e, self.d, self.p, self.q, self.exp1, self.exp2, self.coef))
+
     def blinded_decrypt(self, encrypted):
         """Decrypts the message using blinding to prevent side-channel attacks.
 
@@ -420,6 +454,7 @@ class PrivateKey(AbstractKey):
 
         :param keyfile: contents of a DER-encoded file that contains the private
             key.
+        :type keyfile: bytes
         :return: a PrivateKey object
 
         First let's construct a DER encoded key:
@@ -456,13 +491,26 @@ class PrivateKey(AbstractKey):
         if priv[0] != 0:
             raise ValueError('Unable to read this file, version %s != 0' % priv[0])
 
-        as_ints = tuple(int(x) for x in priv[1:9])
-        return cls(*as_ints)
+        as_ints = map(int, priv[1:6])
+        key = cls(*as_ints)
+
+        exp1, exp2, coef = map(int, priv[6:9])
+
+        if (key.exp1, key.exp2, key.coef) != (exp1, exp2, coef):
+            warnings.warn(
+                'You have provided a malformed keyfile. Either the exponents '
+                'or the coefficient are incorrect. Using the correct values '
+                'instead.',
+                UserWarning,
+            )
+
+        return key
 
     def _save_pkcs1_der(self):
         """Saves the private key in PKCS#1 DER format.
 
-        @returns: the DER-encoded private key.
+        :returns: the DER-encoded private key.
+        :rtype: bytes
         """
 
         from pyasn1.type import univ, namedtype
@@ -470,15 +518,15 @@ class PrivateKey(AbstractKey):
 
         class AsnPrivKey(univ.Sequence):
             componentType = namedtype.NamedTypes(
-                    namedtype.NamedType('version', univ.Integer()),
-                    namedtype.NamedType('modulus', univ.Integer()),
-                    namedtype.NamedType('publicExponent', univ.Integer()),
-                    namedtype.NamedType('privateExponent', univ.Integer()),
-                    namedtype.NamedType('prime1', univ.Integer()),
-                    namedtype.NamedType('prime2', univ.Integer()),
-                    namedtype.NamedType('exponent1', univ.Integer()),
-                    namedtype.NamedType('exponent2', univ.Integer()),
-                    namedtype.NamedType('coefficient', univ.Integer()),
+                namedtype.NamedType('version', univ.Integer()),
+                namedtype.NamedType('modulus', univ.Integer()),
+                namedtype.NamedType('publicExponent', univ.Integer()),
+                namedtype.NamedType('privateExponent', univ.Integer()),
+                namedtype.NamedType('prime1', univ.Integer()),
+                namedtype.NamedType('prime2', univ.Integer()),
+                namedtype.NamedType('exponent1', univ.Integer()),
+                namedtype.NamedType('exponent2', univ.Integer()),
+                namedtype.NamedType('coefficient', univ.Integer()),
             )
 
         # Create the ASN object
@@ -504,20 +552,22 @@ class PrivateKey(AbstractKey):
 
         :param keyfile: contents of a PEM-encoded file that contains the private
             key.
+        :type keyfile: bytes
         :return: a PrivateKey object
         """
 
-        der = rsa.pem.load_pem(keyfile, b('RSA PRIVATE KEY'))
+        der = rsa.pem.load_pem(keyfile, b'RSA PRIVATE KEY')
         return cls._load_pkcs1_der(der)
 
     def _save_pkcs1_pem(self):
         """Saves a PKCS#1 PEM-encoded private key file.
 
         :return: contents of a PEM-encoded file that contains the private key.
+        :rtype: bytes
         """
 
         der = self._save_pkcs1_der()
-        return rsa.pem.save_pem(der, b('RSA PRIVATE KEY'))
+        return rsa.pem.save_pem(der, b'RSA PRIVATE KEY')
 
 
 def find_p_q(nbits, getprime_func=rsa.prime.getprime, accurate=True):
@@ -615,9 +665,11 @@ def calculate_keys_custom_exponent(p, q, exponent):
 
     try:
         d = rsa.common.inverse(exponent, phi_n)
-    except ValueError:
-        raise ValueError("e (%d) and phi_n (%d) are not relatively prime" %
-                         (exponent, phi_n))
+    except rsa.common.NotRelativePrimeError as ex:
+        raise rsa.common.NotRelativePrimeError(
+            exponent, phi_n, ex.d,
+            msg="e (%d) and phi_n (%d) are not relatively prime (divider=%i)" %
+                (exponent, phi_n, ex.d))
 
     if (exponent * d) % phi_n != 1:
         raise ValueError("e (%d) and d (%d) are not mult. inv. modulo "
@@ -731,7 +783,7 @@ if __name__ == '__main__':
             if failures:
                 break
 
-            if (count and count % 10 == 0) or count == 1:
+            if (count % 10 == 0 and count) or count == 1:
                 print('%i times' % count)
     except KeyboardInterrupt:
         print('Aborted')

+ 74 - 0
desktop/core/ext-py/rsa-4.0/rsa/machine_size.py

@@ -0,0 +1,74 @@
+# -*- coding: utf-8 -*-
+#
+#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+"""Detection of 32-bit and 64-bit machines and byte alignment."""
+
+import sys
+
+MAX_INT = sys.maxsize
+MAX_INT64 = (1 << 63) - 1
+MAX_INT32 = (1 << 31) - 1
+MAX_INT16 = (1 << 15) - 1
+
+# Determine the word size of the processor.
+if MAX_INT == MAX_INT64:
+    # 64-bit processor.
+    MACHINE_WORD_SIZE = 64
+elif MAX_INT == MAX_INT32:
+    # 32-bit processor.
+    MACHINE_WORD_SIZE = 32
+else:
+    # Else we just assume 64-bit processor keeping up with modern times.
+    MACHINE_WORD_SIZE = 64
+
+
+def get_word_alignment(num, force_arch=64,
+                       _machine_word_size=MACHINE_WORD_SIZE):
+    """
+    Returns alignment details for the given number based on the platform
+    Python is running on.
+
+    :param num:
+        Unsigned integral number.
+    :param force_arch:
+        If you don't want to use 64-bit unsigned chunks, set this to
+        anything other than 64. 32-bit chunks will be preferred then.
+        Default 64 will be used when on a 64-bit machine.
+    :param _machine_word_size:
+        (Internal) The machine word size used for alignment.
+    :returns:
+        4-tuple::
+
+            (word_bits, word_bytes,
+             max_uint, packing_format_type)
+    """
+    max_uint64 = 0xffffffffffffffff
+    max_uint32 = 0xffffffff
+    max_uint16 = 0xffff
+    max_uint8 = 0xff
+
+    if force_arch == 64 and _machine_word_size >= 64 and num > max_uint32:
+        # 64-bit unsigned integer.
+        return 64, 8, max_uint64, "Q"
+    elif num > max_uint16:
+        # 32-bit unsigned integer
+        return 32, 4, max_uint32, "L"
+    elif num > max_uint8:
+        # 16-bit unsigned integer.
+        return 16, 2, max_uint16, "H"
+    else:
+        # 8-bit unsigned integer.
+        return 8, 1, max_uint8, "B"

+ 2 - 1
desktop/core/ext-py/rsa-3.4.2/rsa/parallel.py → desktop/core/ext-py/rsa-4.0/rsa/parallel.py

@@ -28,6 +28,7 @@ from __future__ import print_function
 
 import multiprocessing as mp
 
+from rsa._compat import range
 import rsa.prime
 import rsa.randnum
 
@@ -94,7 +95,7 @@ if __name__ == '__main__':
         if failures:
             break
 
-        if count and count % 10 == 0:
+        if count % 10 == 0 and count:
             print('%i times' % count)
 
     print('Doctests done')

+ 13 - 12
desktop/core/ext-py/rsa-3.4.2/rsa/pem.py → desktop/core/ext-py/rsa-4.0/rsa/pem.py

@@ -17,19 +17,20 @@
 """Functions that load and write PEM-encoded files."""
 
 import base64
-from rsa._compat import b, is_bytes
+
+from rsa._compat import is_bytes, range
 
 
 def _markers(pem_marker):
     """
-    Returns the start and end PEM markers
+    Returns the start and end PEM markers, as bytes.
     """
 
-    if is_bytes(pem_marker):
-        pem_marker = pem_marker.decode('utf-8')
+    if not is_bytes(pem_marker):
+        pem_marker = pem_marker.encode('ascii')
 
-    return (b('-----BEGIN %s-----' % pem_marker),
-            b('-----END %s-----' % pem_marker))
+    return (b'-----BEGIN ' + pem_marker + b'-----',
+            b'-----END ' + pem_marker + b'-----')
 
 
 def load_pem(contents, pem_marker):
@@ -81,7 +82,7 @@ def load_pem(contents, pem_marker):
             break
 
         # Load fields
-        if b(':') in line:
+        if b':' in line:
             continue
 
         pem_lines.append(line)
@@ -94,7 +95,7 @@ def load_pem(contents, pem_marker):
         raise ValueError('No PEM end marker "%s" found' % pem_end)
 
     # Base64-decode the contents
-    pem = b('').join(pem_lines)
+    pem = b''.join(pem_lines)
     return base64.standard_b64decode(pem)
 
 
@@ -106,13 +107,13 @@ def save_pem(contents, pem_marker):
         when your file has '-----BEGIN RSA PRIVATE KEY-----' and
         '-----END RSA PRIVATE KEY-----' markers.
 
-    :return: the base64-encoded content between the start and end markers.
+    :return: the base64-encoded content between the start and end markers, as bytes.
 
     """
 
     (pem_start, pem_end) = _markers(pem_marker)
 
-    b64 = base64.standard_b64encode(contents).replace(b('\n'), b(''))
+    b64 = base64.standard_b64encode(contents).replace(b'\n', b'')
     pem_lines = [pem_start]
 
     for block_start in range(0, len(b64), 64):
@@ -120,6 +121,6 @@ def save_pem(contents, pem_marker):
         pem_lines.append(block)
 
     pem_lines.append(pem_end)
-    pem_lines.append(b(''))
+    pem_lines.append(b'')
 
-    return b('\n').join(pem_lines)
+    return b'\n'.join(pem_lines)

+ 98 - 40
desktop/core/ext-py/rsa-3.4.2/rsa/pkcs1.py → desktop/core/ext-py/rsa-4.0/rsa/pkcs1.py

@@ -31,21 +31,23 @@ to your users.
 import hashlib
 import os
 
-from rsa._compat import b
+from rsa._compat import range
 from rsa import common, transform, core
 
 # ASN.1 codes that describe the hash algorithm used.
 HASH_ASN1 = {
-    'MD5': b('\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10'),
-    'SHA-1': b('\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14'),
-    'SHA-256': b('\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20'),
-    'SHA-384': b('\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30'),
-    'SHA-512': b('\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40'),
+    'MD5': b'\x30\x20\x30\x0c\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05\x05\x00\x04\x10',
+    'SHA-1': b'\x30\x21\x30\x09\x06\x05\x2b\x0e\x03\x02\x1a\x05\x00\x04\x14',
+    'SHA-224': b'\x30\x2d\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04\x05\x00\x04\x1c',
+    'SHA-256': b'\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01\x05\x00\x04\x20',
+    'SHA-384': b'\x30\x41\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02\x05\x00\x04\x30',
+    'SHA-512': b'\x30\x51\x30\x0d\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03\x05\x00\x04\x40',
 }
 
 HASH_METHODS = {
     'MD5': hashlib.md5,
     'SHA-1': hashlib.sha1,
+    'SHA-224': hashlib.sha224,
     'SHA-256': hashlib.sha256,
     'SHA-384': hashlib.sha384,
     'SHA-512': hashlib.sha512,
@@ -87,7 +89,7 @@ def _pad_for_encryption(message, target_length):
                             ' space for %i' % (msglength, max_msglength))
 
     # Get random padding
-    padding = b('')
+    padding = b''
     padding_length = target_length - msglength - 3
 
     # We remove 0-bytes, so we'll end up with less padding than we've asked for,
@@ -99,15 +101,15 @@ def _pad_for_encryption(message, target_length):
         # after removing the 0-bytes. This increases the chance of getting
         # enough bytes, especially when needed_bytes is small
         new_padding = os.urandom(needed_bytes + 5)
-        new_padding = new_padding.replace(b('\x00'), b(''))
+        new_padding = new_padding.replace(b'\x00', b'')
         padding = padding + new_padding[:needed_bytes]
 
     assert len(padding) == padding_length
 
-    return b('').join([b('\x00\x02'),
-                       padding,
-                       b('\x00'),
-                       message])
+    return b''.join([b'\x00\x02',
+                     padding,
+                     b'\x00',
+                     message])
 
 
 def _pad_for_signing(message, target_length):
@@ -138,10 +140,10 @@ def _pad_for_signing(message, target_length):
 
     padding_length = target_length - msglength - 3
 
-    return b('').join([b('\x00\x01'),
-                       padding_length * b('\xff'),
-                       b('\x00'),
-                       message])
+    return b''.join([b'\x00\x01',
+                     padding_length * b'\xff',
+                     b'\x00',
+                     message])
 
 
 def encrypt(message, pub_key):
@@ -233,30 +235,29 @@ def decrypt(crypto, priv_key):
     cleartext = transform.int2bytes(decrypted, blocksize)
 
     # If we can't find the cleartext marker, decryption failed.
-    if cleartext[0:2] != b('\x00\x02'):
+    if cleartext[0:2] != b'\x00\x02':
         raise DecryptionError('Decryption failed')
 
     # Find the 00 separator between the padding and the message
     try:
-        sep_idx = cleartext.index(b('\x00'), 2)
+        sep_idx = cleartext.index(b'\x00', 2)
     except ValueError:
         raise DecryptionError('Decryption failed')
 
     return cleartext[sep_idx + 1:]
 
 
-def sign(message, priv_key, hash):
-    """Signs the message with the private key.
+def sign_hash(hash_value, priv_key, hash_method):
+    """Signs a precomputed hash with the private key.
 
     Hashes the message, then signs the hash with the given key. This is known
     as a "detached signature", because the message itself isn't altered.
 
-    :param message: the message to sign. Can be an 8-bit string or a file-like
-        object. If ``message`` has a ``read()`` method, it is assumed to be a
-        file-like object.
+    :param hash_value: A precomputed hash to sign (ignores message). Should be set to
+        None if needing to hash and sign message.
     :param priv_key: the :py:class:`rsa.PrivateKey` to sign with
-    :param hash: the hash method used on the message. Use 'MD5', 'SHA-1',
-        'SHA-256', 'SHA-384' or 'SHA-512'.
+    :param hash_method: the hash method used on the message. Use 'MD5', 'SHA-1',
+        'SHA-224', SHA-256', 'SHA-384' or 'SHA-512'.
     :return: a message signature block.
     :raise OverflowError: if the private key is too small to contain the
         requested hash.
@@ -264,15 +265,12 @@ def sign(message, priv_key, hash):
     """
 
     # Get the ASN1 code for this hash method
-    if hash not in HASH_ASN1:
-        raise ValueError('Invalid hash method: %s' % hash)
-    asn1code = HASH_ASN1[hash]
-
-    # Calculate the hash
-    hash = _hash(message, hash)
+    if hash_method not in HASH_ASN1:
+        raise ValueError('Invalid hash method: %s' % hash_method)
+    asn1code = HASH_ASN1[hash_method]
 
     # Encrypt the hash with the private key
-    cleartext = asn1code + hash
+    cleartext = asn1code + hash_value
     keylength = common.byte_size(priv_key.n)
     padded = _pad_for_signing(cleartext, keylength)
 
@@ -283,6 +281,28 @@ def sign(message, priv_key, hash):
     return block
 
 
+def sign(message, priv_key, hash_method):
+    """Signs the message with the private key.
+
+    Hashes the message, then signs the hash with the given key. This is known
+    as a "detached signature", because the message itself isn't altered.
+
+    :param message: the message to sign. Can be an 8-bit string or a file-like
+        object. If ``message`` has a ``read()`` method, it is assumed to be a
+        file-like object.
+    :param priv_key: the :py:class:`rsa.PrivateKey` to sign with
+    :param hash_method: the hash method used on the message. Use 'MD5', 'SHA-1',
+        'SHA-224', SHA-256', 'SHA-384' or 'SHA-512'.
+    :return: a message signature block.
+    :raise OverflowError: if the private key is too small to contain the
+        requested hash.
+
+    """
+
+    msg_hash = compute_hash(message, hash_method)
+    return sign_hash(msg_hash, priv_key, hash_method)
+
+
 def verify(message, signature, pub_key):
     """Verifies that the signature matches the message.
 
@@ -294,6 +314,7 @@ def verify(message, signature, pub_key):
     :param signature: the signature block, as created with :py:func:`rsa.sign`.
     :param pub_key: the :py:class:`rsa.PublicKey` of the person signing the message.
     :raise VerificationError: when the signature doesn't match the message.
+    :returns: the name of the used hash.
 
     """
 
@@ -304,7 +325,7 @@ def verify(message, signature, pub_key):
 
     # Get the hash method
     method_name = _find_method_hash(clearsig)
-    message_hash = _hash(message, method_name)
+    message_hash = compute_hash(message, method_name)
 
     # Reconstruct the expected padded hash
     cleartext = HASH_ASN1[method_name] + message_hash
@@ -314,10 +335,50 @@ def verify(message, signature, pub_key):
     if expected != clearsig:
         raise VerificationError('Verification failed')
 
-    return True
+    return method_name
+
 
+def find_signature_hash(signature, pub_key):
+    """Returns the hash name detected from the signature.
 
-def _hash(message, method_name):
+    If you also want to verify the message, use :py:func:`rsa.verify()` instead.
+    It also returns the name of the used hash.
+
+    :param signature: the signature block, as created with :py:func:`rsa.sign`.
+    :param pub_key: the :py:class:`rsa.PublicKey` of the person signing the message.
+    :returns: the name of the used hash.
+    """
+
+    keylength = common.byte_size(pub_key.n)
+    encrypted = transform.bytes2int(signature)
+    decrypted = core.decrypt_int(encrypted, pub_key.e, pub_key.n)
+    clearsig = transform.int2bytes(decrypted, keylength)
+
+    return _find_method_hash(clearsig)
+
+
+def yield_fixedblocks(infile, blocksize):
+    """Generator, yields each block of ``blocksize`` bytes in the input file.
+
+    :param infile: file to read and separate in blocks.
+    :param blocksize: block size in bytes.
+    :returns: a generator that yields the contents of each block
+    """
+
+    while True:
+        block = infile.read(blocksize)
+
+        read_bytes = len(block)
+        if read_bytes == 0:
+            break
+
+        yield block
+
+        if read_bytes < blocksize:
+            break
+
+
+def compute_hash(message, method_name):
     """Returns the message digest.
 
     :param message: the signed message. Can be an 8-bit string or a file-like
@@ -335,11 +396,8 @@ def _hash(message, method_name):
     hasher = method()
 
     if hasattr(message, 'read') and hasattr(message.read, '__call__'):
-        # Late import to prevent DeprecationWarnings.
-        from . import varblock
-
         # read as 1K blocks
-        for block in varblock.yield_fixedblocks(message, 1024):
+        for block in yield_fixedblocks(message, 1024):
             hasher.update(block)
     else:
         # hash the message object itself.
@@ -375,7 +433,7 @@ if __name__ == '__main__':
         if failures:
             break
 
-        if count and count % 100 == 0:
+        if count % 100 == 0 and count:
             print('%i times' % count)
 
     print('Doctests done')

+ 103 - 0
desktop/core/ext-py/rsa-4.0/rsa/pkcs1_v2.py

@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+#
+#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+"""Functions for PKCS#1 version 2 encryption and signing
+
+This module implements certain functionality from PKCS#1 version 2. Main
+documentation is RFC 2437: https://tools.ietf.org/html/rfc2437
+"""
+
+from rsa._compat import range
+from rsa import (
+    common,
+    pkcs1,
+    transform,
+)
+
+
+def mgf1(seed, length, hasher='SHA-1'):
+    """
+    MGF1 is a Mask Generation Function based on a hash function.
+
+    A mask generation function takes an octet string of variable length and a
+    desired output length as input, and outputs an octet string of the desired
+    length. The plaintext-awareness of RSAES-OAEP relies on the random nature of
+    the output of the mask generation function, which in turn relies on the
+    random nature of the underlying hash.
+
+    :param bytes seed: seed from which mask is generated, an octet string
+    :param int length: intended length in octets of the mask, at most 2^32(hLen)
+    :param str hasher: hash function (hLen denotes the length in octets of the hash
+        function output)
+
+    :return: mask, an octet string of length `length`
+    :rtype: bytes
+
+    :raise OverflowError: when `length` is too large for the specified `hasher`
+    :raise ValueError: when specified `hasher` is invalid
+    """
+
+    try:
+        hash_length = pkcs1.HASH_METHODS[hasher]().digest_size
+    except KeyError:
+        raise ValueError(
+            'Invalid `hasher` specified. Please select one of: {hash_list}'.format(
+                hash_list=', '.join(sorted(pkcs1.HASH_METHODS.keys()))
+            )
+        )
+
+    # If l > 2^32(hLen), output "mask too long" and stop.
+    if length > (2**32 * hash_length):
+        raise OverflowError(
+            "Desired length should be at most 2**32 times the hasher's output "
+            "length ({hash_length} for {hasher} function)".format(
+                hash_length=hash_length,
+                hasher=hasher,
+            )
+        )
+
+    # Looping `counter` from 0 to ceil(l / hLen)-1, build `output` based on the
+    # hashes formed by (`seed` + C), being `C` an octet string of length 4
+    # generated by converting `counter` with the primitive I2OSP
+    output = b''.join(
+        pkcs1.compute_hash(
+            seed + transform.int2bytes(counter, fill_size=4),
+            method_name=hasher,
+        )
+        for counter in range(common.ceil_div(length, hash_length) + 1)
+    )
+
+    # Output the leading `length` octets of `output` as the octet string mask.
+    return output[:length]
+
+
+__all__ = [
+    'mgf1',
+]
+
+if __name__ == '__main__':
+    print('Running doctests 1000x or until failure')
+    import doctest
+
+    for count in range(1000):
+        (failures, tests) = doctest.testmod()
+        if failures:
+            break
+
+        if count % 100 == 0 and count:
+            print('%i times' % count)
+
+    print('Doctests done')

+ 36 - 13
desktop/core/ext-py/rsa-3.4.2/rsa/prime.py → desktop/core/ext-py/rsa-4.0/rsa/prime.py

@@ -20,6 +20,8 @@ Implementation based on the book Algorithm Design by Michael T. Goodrich and
 Roberto Tamassia, 2002.
 """
 
+from rsa._compat import range
+import rsa.common
 import rsa.randnum
 
 __all__ = ['getprime', 'are_relatively_prime']
@@ -37,6 +39,32 @@ def gcd(p, q):
     return p
 
 
+def get_primality_testing_rounds(number):
+    """Returns minimum number of rounds for Miller-Rabing primality testing,
+    based on number bitsize.
+
+    According to NIST FIPS 186-4, Appendix C, Table C.3, minimum number of
+    rounds of M-R testing, using an error probability of 2 ** (-100), for
+    different p, q bitsizes are:
+      * p, q bitsize: 512; rounds: 7
+      * p, q bitsize: 1024; rounds: 4
+      * p, q bitsize: 1536; rounds: 3
+    See: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
+    """
+
+    # Calculate number bitsize.
+    bitsize = rsa.common.bit_size(number)
+    # Set number of rounds.
+    if bitsize >= 1536:
+        return 3
+    if bitsize >= 1024:
+        return 4
+    if bitsize >= 512:
+        return 7
+    # For smaller bitsizes, set arbitrary number of rounds.
+    return 10
+
+
 def miller_rabin_primality_testing(n, k):
     """Calculates whether n is composite (which is always correct) or prime
     (which theoretically is incorrect with error probability 4**-k), by
@@ -69,7 +97,7 @@ def miller_rabin_primality_testing(n, k):
     # Test k witnesses.
     for _ in range(k):
         # Generate random integer a, where 2 <= a <= (n - 2)
-        a = rsa.randnum.randint(n - 4) + 2
+        a = rsa.randnum.randint(n - 3) + 1
 
         x = pow(a, d, n)
         if x == 1 or x == n - 1:
@@ -99,26 +127,21 @@ def is_prime(number):
     False
     >>> is_prime(41)
     True
-    >>> [x for x in range(901, 1000) if is_prime(x)]
-    [907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
     """
 
     # Check for small numbers.
     if number < 10:
-        return number in [2, 3, 5, 7]
+        return number in {2, 3, 5, 7}
 
     # Check for even numbers.
     if not (number & 1):
         return False
 
-    # According to NIST FIPS 186-4, Appendix C, Table C.3, minimum number of
-    # rounds of M-R testing, using an error probability of 2 ** (-100), for
-    # different p, q bitsizes are:
-    #   * p, q bitsize: 512; rounds: 7
-    #   * p, q bitsize: 1024; rounds: 4
-    #   * p, q bitsize: 1536; rounds: 3
-    # See: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
-    return miller_rabin_primality_testing(number, 7)
+    # Calculate minimum number of rounds.
+    k = get_primality_testing_rounds(number)
+
+    # Run primality testing with (minimum + 1) rounds.
+    return miller_rabin_primality_testing(number, k + 1)
 
 
 def getprime(nbits):
@@ -172,7 +195,7 @@ if __name__ == '__main__':
         if failures:
             break
 
-        if count and count % 100 == 0:
+        if count % 100 == 0 and count:
             print('%i times' % count)
 
     print('Doctests done')

+ 1 - 1
desktop/core/ext-py/rsa-3.4.2/rsa/randnum.py → desktop/core/ext-py/rsa-4.0/rsa/randnum.py

@@ -88,7 +88,7 @@ def randint(maxvalue):
         if value <= maxvalue:
             break
 
-        if tries and tries % 10 == 0:
+        if tries % 10 == 0 and tries:
             # After a lot of tries to get the right number of bits but still
             # smaller than maxvalue, decrease the number of bits by 1. That'll
             # dramatically increase the chances to get a large enough number.

+ 14 - 23
desktop/core/ext-py/rsa-3.4.2/rsa/transform.py → desktop/core/ext-py/rsa-4.0/rsa/transform.py

@@ -21,20 +21,11 @@ From bytes to a number, number to bytes, etc.
 
 from __future__ import absolute_import
 
-try:
-    # We'll use psyco if available on 32-bit architectures to speed up code.
-    # Using psyco (if available) cuts down the execution time on Python 2.5
-    # at least by half.
-    import psyco
-
-    psyco.full()
-except ImportError:
-    pass
-
 import binascii
 from struct import pack
-from rsa import common
-from rsa._compat import is_integer, b, byte, get_word_alignment, ZERO_BYTE, EMPTY_BYTE
+
+from rsa._compat import byte, is_integer
+from rsa import common, machine_size
 
 
 def bytes2int(raw_bytes):
@@ -92,7 +83,7 @@ def _int2bytes(number, block_size=None):
     # Do some bounds checking
     if number == 0:
         needed_bytes = 1
-        raw_bytes = [ZERO_BYTE]
+        raw_bytes = [b'\x00']
     else:
         needed_bytes = common.byte_size(number)
         raw_bytes = []
@@ -110,14 +101,14 @@ def _int2bytes(number, block_size=None):
 
     # Pad with zeroes to fill the block
     if block_size and block_size > 0:
-        padding = (block_size - needed_bytes) * ZERO_BYTE
+        padding = (block_size - needed_bytes) * b'\x00'
     else:
-        padding = EMPTY_BYTE
+        padding = b''
 
-    return padding + EMPTY_BYTE.join(raw_bytes)
+    return padding + b''.join(raw_bytes)
 
 
-def bytes_leading(raw_bytes, needle=ZERO_BYTE):
+def bytes_leading(raw_bytes, needle=b'\x00'):
     """
     Finds the number of prefixed byte occurrences in the haystack.
 
@@ -126,7 +117,7 @@ def bytes_leading(raw_bytes, needle=ZERO_BYTE):
     :param raw_bytes:
         Raw bytes.
     :param needle:
-        The byte to count. Default \000.
+        The byte to count. Default \x00.
     :returns:
         The number of leading needle bytes.
     """
@@ -186,11 +177,11 @@ def int2bytes(number, fill_size=None, chunk_size=None, overflow=False):
     # Ensure these are integers.
     number & 1
 
-    raw_bytes = b('')
+    raw_bytes = b''
 
     # Pack the integer one machine word at a time into bytes.
     num = number
-    word_bits, _, max_uint, pack_type = get_word_alignment(num)
+    word_bits, _, max_uint, pack_type = machine_size.get_word_alignment(num)
     pack_format = ">%s" % pack_type
     while num > 0:
         raw_bytes = pack(pack_format, num & max_uint) + raw_bytes
@@ -198,7 +189,7 @@ def int2bytes(number, fill_size=None, chunk_size=None, overflow=False):
     # Obtain the index of the first non-zero byte.
     zero_leading = bytes_leading(raw_bytes)
     if number == 0:
-        raw_bytes = ZERO_BYTE
+        raw_bytes = b'\x00'
     # De-padding.
     raw_bytes = raw_bytes[zero_leading:]
 
@@ -209,12 +200,12 @@ def int2bytes(number, fill_size=None, chunk_size=None, overflow=False):
                     "Need %d bytes for number, but fill size is %d" %
                     (length, fill_size)
             )
-        raw_bytes = raw_bytes.rjust(fill_size, ZERO_BYTE)
+        raw_bytes = raw_bytes.rjust(fill_size, b'\x00')
     elif chunk_size and chunk_size > 0:
         remainder = length % chunk_size
         if remainder:
             padding_size = chunk_size - remainder
-            raw_bytes = raw_bytes.rjust(length + padding_size, ZERO_BYTE)
+            raw_bytes = raw_bytes.rjust(length + padding_size, b'\x00')
     return raw_bytes
 
 

+ 0 - 0
desktop/core/ext-py/rsa-3.4.2/rsa/util.py → desktop/core/ext-py/rsa-4.0/rsa/util.py


+ 10 - 11
desktop/core/ext-py/rsa-3.4.2/setup.cfg → desktop/core/ext-py/rsa-4.0/setup.cfg

@@ -1,11 +1,10 @@
-[nosetests]
-verbosity = 2
-
-[bdist_wheel]
-universal = 1
-
-[egg_info]
-tag_date = 0
-tag_svn_revision = 0
-tag_build = 
-
+[bdist_wheel]
+universal = 1
+
+[metadata]
+license_file = LICENSE
+
+[egg_info]
+tag_build = 
+tag_date = 0
+

+ 10 - 5
desktop/core/ext-py/rsa-3.4.2/setup.py → desktop/core/ext-py/rsa-4.0/setup.py

@@ -16,10 +16,15 @@
 
 from setuptools import setup
 
+with open('README.md') as f:
+    long_description = f.read()
+
 if __name__ == '__main__':
     setup(name='rsa',
-          version='3.4.2',
+          version='4.0',
           description='Pure-Python RSA implementation',
+          long_description=long_description,
+          long_description_content_type='text/markdown',
           author='Sybren A. Stuvel',
           author_email='sybren@stuvel.eu',
           maintainer='Sybren A. Stuvel',
@@ -36,12 +41,14 @@ if __name__ == '__main__':
               'Operating System :: OS Independent',
               'Programming Language :: Python',
               'Programming Language :: Python :: 2',
-              'Programming Language :: Python :: 2.6',
               'Programming Language :: Python :: 2.7',
               'Programming Language :: Python :: 3',
-              'Programming Language :: Python :: 3.3',
               'Programming Language :: Python :: 3.4',
               'Programming Language :: Python :: 3.5',
+              'Programming Language :: Python :: 3.6',
+              'Programming Language :: Python :: 3.7',
+              'Programming Language :: Python :: Implementation :: CPython',
+              'Programming Language :: Python :: Implementation :: PyPy',
               'Topic :: Security :: Cryptography',
           ],
           install_requires=[
@@ -54,8 +61,6 @@ if __name__ == '__main__':
               'pyrsa-decrypt = rsa.cli:decrypt',
               'pyrsa-sign = rsa.cli:sign',
               'pyrsa-verify = rsa.cli:verify',
-              'pyrsa-encrypt-bigfile = rsa.cli:encrypt_bigfile',
-              'pyrsa-decrypt-bigfile = rsa.cli:decrypt_bigfile',
           ]},
 
           )

+ 0 - 0
desktop/core/ext-py/rsa-3.4.2/tests/__init__.py → desktop/core/ext-py/rsa-4.0/tests/__init__.py


+ 0 - 0
desktop/core/ext-py/rsa-3.4.2/tests/private.pem → desktop/core/ext-py/rsa-4.0/tests/private.pem


+ 296 - 0
desktop/core/ext-py/rsa-4.0/tests/test_cli.py

@@ -0,0 +1,296 @@
+"""
+Unit tests for CLI entry points.
+"""
+
+from __future__ import print_function
+
+import unittest
+import sys
+import functools
+from contextlib import contextmanager
+
+import os
+from io import StringIO, BytesIO
+
+import rsa
+import rsa.cli
+import rsa.util
+from rsa._compat import PY2
+
+
+def make_buffer():
+    if PY2:
+        return BytesIO()
+    buf = StringIO()
+    buf.buffer = BytesIO()
+    return buf
+
+
+def get_bytes_out(out):
+    if PY2:
+        # Python 2.x writes 'str' to stdout
+        return out.getvalue()
+    # Python 3.x writes 'bytes' to stdout.buffer
+    return out.buffer.getvalue()
+
+
+@contextmanager
+def captured_output():
+    """Captures output to stdout and stderr"""
+
+    new_out, new_err = make_buffer(), make_buffer()
+    old_out, old_err = sys.stdout, sys.stderr
+    try:
+        sys.stdout, sys.stderr = new_out, new_err
+        yield new_out, new_err
+    finally:
+        sys.stdout, sys.stderr = old_out, old_err
+
+
+@contextmanager
+def cli_args(*new_argv):
+    """Updates sys.argv[1:] for a single test."""
+
+    old_args = sys.argv[:]
+    sys.argv[1:] = [str(arg) for arg in new_argv]
+
+    try:
+        yield
+    finally:
+        sys.argv[1:] = old_args
+
+
+def remove_if_exists(fname):
+    """Removes a file if it exists."""
+
+    if os.path.exists(fname):
+        os.unlink(fname)
+
+
+def cleanup_files(*filenames):
+    """Makes sure the files don't exist when the test runs, and deletes them afterward."""
+
+    def remove():
+        for fname in filenames:
+            remove_if_exists(fname)
+
+    def decorator(func):
+        @functools.wraps(func)
+        def wrapper(*args, **kwargs):
+            remove()
+            try:
+                return func(*args, **kwargs)
+            finally:
+                remove()
+
+        return wrapper
+
+    return decorator
+
+
+class AbstractCliTest(unittest.TestCase):
+    @classmethod
+    def setUpClass(cls):
+        # Ensure there is a key to use
+        cls.pub_key, cls.priv_key = rsa.newkeys(512)
+        cls.pub_fname = '%s.pub' % cls.__name__
+        cls.priv_fname = '%s.key' % cls.__name__
+
+        with open(cls.pub_fname, 'wb') as outfile:
+            outfile.write(cls.pub_key.save_pkcs1())
+
+        with open(cls.priv_fname, 'wb') as outfile:
+            outfile.write(cls.priv_key.save_pkcs1())
+
+    @classmethod
+    def tearDownClass(cls):
+        if hasattr(cls, 'pub_fname'):
+            remove_if_exists(cls.pub_fname)
+        if hasattr(cls, 'priv_fname'):
+            remove_if_exists(cls.priv_fname)
+
+    def assertExits(self, status_code, func, *args, **kwargs):
+        try:
+            func(*args, **kwargs)
+        except SystemExit as ex:
+            if status_code == ex.code:
+                return
+            self.fail('SystemExit() raised by %r, but exited with code %r, expected %r' % (
+                func, ex.code, status_code))
+        else:
+            self.fail('SystemExit() not raised by %r' % func)
+
+
+class KeygenTest(AbstractCliTest):
+    def test_keygen_no_args(self):
+        with cli_args():
+            self.assertExits(1, rsa.cli.keygen)
+
+    def test_keygen_priv_stdout(self):
+        with captured_output() as (out, err):
+            with cli_args(128):
+                rsa.cli.keygen()
+
+        lines = get_bytes_out(out).splitlines()
+        self.assertEqual(b'-----BEGIN RSA PRIVATE KEY-----', lines[0])
+        self.assertEqual(b'-----END RSA PRIVATE KEY-----', lines[-1])
+
+        # The key size should be shown on stderr
+        self.assertTrue('128-bit key' in err.getvalue())
+
+    @cleanup_files('test_cli_privkey_out.pem')
+    def test_keygen_priv_out_pem(self):
+        with captured_output() as (out, err):
+            with cli_args('--out=test_cli_privkey_out.pem', '--form=PEM', 128):
+                rsa.cli.keygen()
+
+        # The key size should be shown on stderr
+        self.assertTrue('128-bit key' in err.getvalue())
+
+        # The output file should be shown on stderr
+        self.assertTrue('test_cli_privkey_out.pem' in err.getvalue())
+
+        # If we can load the file as PEM, it's good enough.
+        with open('test_cli_privkey_out.pem', 'rb') as pemfile:
+            rsa.PrivateKey.load_pkcs1(pemfile.read())
+
+    @cleanup_files('test_cli_privkey_out.der')
+    def test_keygen_priv_out_der(self):
+        with captured_output() as (out, err):
+            with cli_args('--out=test_cli_privkey_out.der', '--form=DER', 128):
+                rsa.cli.keygen()
+
+        # The key size should be shown on stderr
+        self.assertTrue('128-bit key' in err.getvalue())
+
+        # The output file should be shown on stderr
+        self.assertTrue('test_cli_privkey_out.der' in err.getvalue())
+
+        # If we can load the file as der, it's good enough.
+        with open('test_cli_privkey_out.der', 'rb') as derfile:
+            rsa.PrivateKey.load_pkcs1(derfile.read(), format='DER')
+
+    @cleanup_files('test_cli_privkey_out.pem', 'test_cli_pubkey_out.pem')
+    def test_keygen_pub_out_pem(self):
+        with captured_output() as (out, err):
+            with cli_args('--out=test_cli_privkey_out.pem',
+                          '--pubout=test_cli_pubkey_out.pem',
+                          '--form=PEM', 256):
+                rsa.cli.keygen()
+
+        # The key size should be shown on stderr
+        self.assertTrue('256-bit key' in err.getvalue())
+
+        # The output files should be shown on stderr
+        self.assertTrue('test_cli_privkey_out.pem' in err.getvalue())
+        self.assertTrue('test_cli_pubkey_out.pem' in err.getvalue())
+
+        # If we can load the file as PEM, it's good enough.
+        with open('test_cli_pubkey_out.pem', 'rb') as pemfile:
+            rsa.PublicKey.load_pkcs1(pemfile.read())
+
+
+class EncryptDecryptTest(AbstractCliTest):
+    def test_empty_decrypt(self):
+        with cli_args():
+            self.assertExits(1, rsa.cli.decrypt)
+
+    def test_empty_encrypt(self):
+        with cli_args():
+            self.assertExits(1, rsa.cli.encrypt)
+
+    @cleanup_files('encrypted.txt', 'cleartext.txt')
+    def test_encrypt_decrypt(self):
+        with open('cleartext.txt', 'wb') as outfile:
+            outfile.write(b'Hello cleartext RSA users!')
+
+        with cli_args('-i', 'cleartext.txt', '--out=encrypted.txt', self.pub_fname):
+            with captured_output():
+                rsa.cli.encrypt()
+
+        with cli_args('-i', 'encrypted.txt', self.priv_fname):
+            with captured_output() as (out, err):
+                rsa.cli.decrypt()
+
+        # We should have the original cleartext on stdout now.
+        output = get_bytes_out(out)
+        self.assertEqual(b'Hello cleartext RSA users!', output)
+
+    @cleanup_files('encrypted.txt', 'cleartext.txt')
+    def test_encrypt_decrypt_unhappy(self):
+        with open('cleartext.txt', 'wb') as outfile:
+            outfile.write(b'Hello cleartext RSA users!')
+
+        with cli_args('-i', 'cleartext.txt', '--out=encrypted.txt', self.pub_fname):
+            with captured_output():
+                rsa.cli.encrypt()
+
+        # Change a few bytes in the encrypted stream.
+        with open('encrypted.txt', 'r+b') as encfile:
+            encfile.seek(40)
+            encfile.write(b'hahaha')
+
+        with cli_args('-i', 'encrypted.txt', self.priv_fname):
+            with captured_output() as (out, err):
+                self.assertRaises(rsa.DecryptionError, rsa.cli.decrypt)
+
+
+class SignVerifyTest(AbstractCliTest):
+    def test_empty_verify(self):
+        with cli_args():
+            self.assertExits(1, rsa.cli.verify)
+
+    def test_empty_sign(self):
+        with cli_args():
+            self.assertExits(1, rsa.cli.sign)
+
+    @cleanup_files('signature.txt', 'cleartext.txt')
+    def test_sign_verify(self):
+        with open('cleartext.txt', 'wb') as outfile:
+            outfile.write(b'Hello RSA users!')
+
+        with cli_args('-i', 'cleartext.txt', '--out=signature.txt', self.priv_fname, 'SHA-256'):
+            with captured_output():
+                rsa.cli.sign()
+
+        with cli_args('-i', 'cleartext.txt', self.pub_fname, 'signature.txt'):
+            with captured_output() as (out, err):
+                rsa.cli.verify()
+
+        self.assertFalse(b'Verification OK' in get_bytes_out(out))
+
+    @cleanup_files('signature.txt', 'cleartext.txt')
+    def test_sign_verify_unhappy(self):
+        with open('cleartext.txt', 'wb') as outfile:
+            outfile.write(b'Hello RSA users!')
+
+        with cli_args('-i', 'cleartext.txt', '--out=signature.txt', self.priv_fname, 'SHA-256'):
+            with captured_output():
+                rsa.cli.sign()
+
+        # Change a few bytes in the cleartext file.
+        with open('cleartext.txt', 'r+b') as encfile:
+            encfile.seek(6)
+            encfile.write(b'DSA')
+
+        with cli_args('-i', 'cleartext.txt', self.pub_fname, 'signature.txt'):
+            with captured_output() as (out, err):
+                self.assertExits('Verification failed.', rsa.cli.verify)
+
+
+class PrivatePublicTest(AbstractCliTest):
+    """Test CLI command to convert a private to a public key."""
+
+    @cleanup_files('test_private_to_public.pem')
+    def test_private_to_public(self):
+
+        with cli_args('-i', self.priv_fname, '-o', 'test_private_to_public.pem'):
+            with captured_output():
+                rsa.util.private_to_public()
+
+        # Check that the key is indeed valid.
+        with open('test_private_to_public.pem', 'rb') as pemfile:
+            key = rsa.PublicKey.load_pkcs1(pemfile.read())
+
+        self.assertEqual(self.priv_key.n, key.n)
+        self.assertEqual(self.priv_key.e, key.e)

+ 29 - 10
desktop/core/ext-py/rsa-3.4.2/tests/test_common.py → desktop/core/ext-py/rsa-4.0/tests/test_common.py

@@ -17,14 +17,14 @@
 
 import unittest
 import struct
-from rsa._compat import byte, b
-from rsa.common import byte_size, bit_size, _bit_size
+from rsa._compat import byte
+from rsa.common import byte_size, bit_size, inverse
 
 
 class TestByte(unittest.TestCase):
     def test_values(self):
-        self.assertEqual(byte(0), b('\x00'))
-        self.assertEqual(byte(255), b('\xff'))
+        self.assertEqual(byte(0), b'\x00')
+        self.assertEqual(byte(255), b'\xff')
 
     def test_struct_error_when_out_of_bounds(self):
         self.assertRaises(struct.error, byte, 256)
@@ -69,9 +69,28 @@ class TestBitSize(unittest.TestCase):
         self.assertEqual(bit_size((1 << 1024) + 1), 1025)
         self.assertEqual(bit_size((1 << 1024) - 1), 1024)
 
-        self.assertEqual(_bit_size(1023), 10)
-        self.assertEqual(_bit_size(1024), 11)
-        self.assertEqual(_bit_size(1025), 11)
-        self.assertEqual(_bit_size(1 << 1024), 1025)
-        self.assertEqual(_bit_size((1 << 1024) + 1), 1025)
-        self.assertEqual(_bit_size((1 << 1024) - 1), 1024)
+    def test_negative_values(self):
+        self.assertEqual(bit_size(-1023), 10)
+        self.assertEqual(bit_size(-1024), 11)
+        self.assertEqual(bit_size(-1025), 11)
+        self.assertEqual(bit_size(-1 << 1024), 1025)
+        self.assertEqual(bit_size(-((1 << 1024) + 1)), 1025)
+        self.assertEqual(bit_size(-((1 << 1024) - 1)), 1024)
+
+    def test_bad_type(self):
+        self.assertRaises(TypeError, bit_size, [])
+        self.assertRaises(TypeError, bit_size, ())
+        self.assertRaises(TypeError, bit_size, dict())
+        self.assertRaises(TypeError, bit_size, "")
+        self.assertRaises(TypeError, bit_size, None)
+        self.assertRaises(TypeError, bit_size, 0.0)
+
+
+class TestInverse(unittest.TestCase):
+    def test_normal(self):
+        self.assertEqual(3, inverse(7, 4))
+        self.assertEqual(9, inverse(5, 11))
+
+    def test_not_relprime(self):
+        self.assertRaises(ValueError, inverse, 4, 8)
+        self.assertRaises(ValueError, inverse, 25, 5)

+ 80 - 0
desktop/core/ext-py/rsa-4.0/tests/test_compat.py

@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+#
+#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+import unittest
+import struct
+
+from rsa._compat import byte, is_bytes, range, xor_bytes
+
+
+class TestByte(unittest.TestCase):
+    """Tests for single bytes."""
+
+    def test_byte(self):
+        for i in range(256):
+            byt = byte(i)
+            self.assertTrue(is_bytes(byt))
+            self.assertEqual(ord(byt), i)
+
+    def test_raises_StructError_on_overflow(self):
+        self.assertRaises(struct.error, byte, 256)
+        self.assertRaises(struct.error, byte, -1)
+
+    def test_byte_literal(self):
+        self.assertIsInstance(b'abc', bytes)
+
+
+class TestBytes(unittest.TestCase):
+    """Tests for bytes objects."""
+
+    def setUp(self):
+        self.b1 = b'\xff\xff\xff\xff'
+        self.b2 = b'\x00\x00\x00\x00'
+        self.b3 = b'\xf0\xf0\xf0\xf0'
+        self.b4 = b'\x4d\x23\xca\xe2'
+        self.b5 = b'\x9b\x61\x3b\xdc'
+        self.b6 = b'\xff\xff'
+
+        self.byte_strings = (self.b1, self.b2, self.b3, self.b4, self.b5, self.b6)
+
+    def test_xor_bytes(self):
+        self.assertEqual(xor_bytes(self.b1, self.b2), b'\xff\xff\xff\xff')
+        self.assertEqual(xor_bytes(self.b1, self.b3), b'\x0f\x0f\x0f\x0f')
+        self.assertEqual(xor_bytes(self.b1, self.b4), b'\xb2\xdc\x35\x1d')
+        self.assertEqual(xor_bytes(self.b1, self.b5), b'\x64\x9e\xc4\x23')
+        self.assertEqual(xor_bytes(self.b2, self.b3), b'\xf0\xf0\xf0\xf0')
+        self.assertEqual(xor_bytes(self.b2, self.b4), b'\x4d\x23\xca\xe2')
+        self.assertEqual(xor_bytes(self.b2, self.b5), b'\x9b\x61\x3b\xdc')
+        self.assertEqual(xor_bytes(self.b3, self.b4), b'\xbd\xd3\x3a\x12')
+        self.assertEqual(xor_bytes(self.b3, self.b5), b'\x6b\x91\xcb\x2c')
+        self.assertEqual(xor_bytes(self.b4, self.b5), b'\xd6\x42\xf1\x3e')
+
+    def test_xor_bytes_length(self):
+        self.assertEqual(xor_bytes(self.b1, self.b6), b'\x00\x00')
+        self.assertEqual(xor_bytes(self.b2, self.b6), b'\xff\xff')
+        self.assertEqual(xor_bytes(self.b3, self.b6), b'\x0f\x0f')
+        self.assertEqual(xor_bytes(self.b4, self.b6), b'\xb2\xdc')
+        self.assertEqual(xor_bytes(self.b5, self.b6), b'\x64\x9e')
+        self.assertEqual(xor_bytes(self.b6, b''), b'')
+
+    def test_xor_bytes_commutative(self):
+        for first in self.byte_strings:
+            for second in self.byte_strings:
+                min_length = min(len(first), len(second))
+                result = xor_bytes(first, second)
+
+                self.assertEqual(result, xor_bytes(second, first))
+                self.assertEqual(len(result), min_length)

+ 0 - 0
desktop/core/ext-py/rsa-3.4.2/tests/test_integers.py → desktop/core/ext-py/rsa-4.0/tests/test_integers.py


+ 79 - 0
desktop/core/ext-py/rsa-4.0/tests/test_key.py

@@ -0,0 +1,79 @@
+"""
+Some tests for the rsa/key.py file.
+"""
+
+import unittest
+
+import rsa.key
+import rsa.core
+
+
+class BlindingTest(unittest.TestCase):
+    def test_blinding(self):
+        """Test blinding and unblinding.
+
+        This is basically the doctest of the PrivateKey.blind method, but then
+        implemented as unittest to allow running on different Python versions.
+        """
+
+        pk = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
+
+        message = 12345
+        encrypted = rsa.core.encrypt_int(message, pk.e, pk.n)
+
+        blinded = pk.blind(encrypted, 4134431)  # blind before decrypting
+        decrypted = rsa.core.decrypt_int(blinded, pk.d, pk.n)
+        unblinded = pk.unblind(decrypted, 4134431)
+
+        self.assertEqual(unblinded, message)
+
+
+class KeyGenTest(unittest.TestCase):
+    def test_custom_exponent(self):
+        priv, pub = rsa.key.newkeys(16, exponent=3)
+
+        self.assertEqual(3, priv.e)
+        self.assertEqual(3, pub.e)
+
+    def test_default_exponent(self):
+        priv, pub = rsa.key.newkeys(16)
+
+        self.assertEqual(0x10001, priv.e)
+        self.assertEqual(0x10001, pub.e)
+
+    def test_exponents_coefficient_calculation(self):
+        pk = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
+
+        self.assertEqual(pk.exp1, 55063)
+        self.assertEqual(pk.exp2, 10095)
+        self.assertEqual(pk.coef, 50797)
+
+    def test_custom_getprime_func(self):
+        # List of primes to test with, in order [p, q, p, q, ....]
+        # By starting with two of the same primes, we test that this is
+        # properly rejected.
+        primes = [64123, 64123, 64123, 50957, 39317, 33107]
+
+        def getprime(_):
+            return primes.pop(0)
+
+        # This exponent will cause two other primes to be generated.
+        exponent = 136407
+
+        (p, q, e, d) = rsa.key.gen_keys(64,
+                                        accurate=False,
+                                        getprime_func=getprime,
+                                        exponent=exponent)
+        self.assertEqual(39317, p)
+        self.assertEqual(33107, q)
+
+
+class HashTest(unittest.TestCase):
+    """Test hashing of keys"""
+
+    def test_hash_possible(self):
+        priv, pub = rsa.key.newkeys(16)
+
+        # This raises a TypeError when hashing isn't possible.
+        hash(priv)
+        hash(pub)

+ 59 - 18
desktop/core/ext-py/rsa-3.4.2/tests/test_load_save_keys.py → desktop/core/ext-py/rsa-4.0/tests/test_load_save_keys.py

@@ -14,62 +14,63 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.
 
-'''Unittest for saving and loading keys.'''
+"""Unittest for saving and loading keys."""
 
 import base64
-import unittest
+import mock
 import os.path
 import pickle
+import unittest
+import warnings
 
-from rsa._compat import b
-
+from rsa._compat import range
 import rsa.key
 
-B64PRIV_DER = b('MC4CAQACBQDeKYlRAgMBAAECBQDHn4npAgMA/icCAwDfxwIDANcXAgInbwIDAMZt')
+B64PRIV_DER = b'MC4CAQACBQDeKYlRAgMBAAECBQDHn4npAgMA/icCAwDfxwIDANcXAgInbwIDAMZt'
 PRIVATE_DER = base64.standard_b64decode(B64PRIV_DER)
 
-B64PUB_DER = b('MAwCBQDeKYlRAgMBAAE=')
+B64PUB_DER = b'MAwCBQDeKYlRAgMBAAE='
 PUBLIC_DER = base64.standard_b64decode(B64PUB_DER)
 
-PRIVATE_PEM = b('''
+PRIVATE_PEM = b'''\
 -----BEGIN CONFUSING STUFF-----
 Cruft before the key
 
 -----BEGIN RSA PRIVATE KEY-----
 Comment: something blah
 
-%s
+''' + B64PRIV_DER + b'''
 -----END RSA PRIVATE KEY-----
 
 Stuff after the key
 -----END CONFUSING STUFF-----
-''' % B64PRIV_DER.decode("utf-8"))
+'''
 
-CLEAN_PRIVATE_PEM = b('''\
+CLEAN_PRIVATE_PEM = b'''\
 -----BEGIN RSA PRIVATE KEY-----
-%s
+''' + B64PRIV_DER + b'''
 -----END RSA PRIVATE KEY-----
-''' % B64PRIV_DER.decode("utf-8"))
+'''
 
-PUBLIC_PEM = b('''
+PUBLIC_PEM = b'''\
 -----BEGIN CONFUSING STUFF-----
 Cruft before the key
 
 -----BEGIN RSA PUBLIC KEY-----
 Comment: something blah
 
-%s
+''' + B64PUB_DER + b'''
 -----END RSA PUBLIC KEY-----
 
 Stuff after the key
 -----END CONFUSING STUFF-----
-''' % B64PUB_DER.decode("utf-8"))
+'''
 
-CLEAN_PUBLIC_PEM = b('''\
+CLEAN_PUBLIC_PEM = b'''\
 -----BEGIN RSA PUBLIC KEY-----
-%s
+''' + B64PUB_DER + b'''
 -----END RSA PUBLIC KEY-----
-''' % B64PUB_DER.decode("utf-8"))
+'''
 
 
 class DerTest(unittest.TestCase):
@@ -82,6 +83,39 @@ class DerTest(unittest.TestCase):
         expected = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
 
         self.assertEqual(expected, key)
+        self.assertEqual(key.exp1, 55063)
+        self.assertEqual(key.exp2, 10095)
+        self.assertEqual(key.coef, 50797)
+
+    @mock.patch('pyasn1.codec.der.decoder.decode')
+    def test_load_malformed_private_key(self, der_decode):
+        """Test loading malformed private DER keys."""
+
+        # Decode returns an invalid exp2 value.
+        der_decode.return_value = (
+            [0, 3727264081, 65537, 3349121513, 65063, 57287, 55063, 0, 50797],
+            0,
+        )
+
+        with warnings.catch_warnings(record=True) as w:
+            # Always print warnings
+            warnings.simplefilter('always')
+
+            # Load 3 keys
+            for _ in range(3):
+                key = rsa.key.PrivateKey.load_pkcs1(PRIVATE_DER, 'DER')
+
+            # Check that 3 warnings were generated.
+            self.assertEqual(3, len(w))
+
+            for warning in w:
+                self.assertTrue(issubclass(warning.category, UserWarning))
+                self.assertIn('malformed', str(warning.message))
+
+        # Check that we are creating the key with correct values
+        self.assertEqual(key.exp1, 55063)
+        self.assertEqual(key.exp2, 10095)
+        self.assertEqual(key.coef, 50797)
 
     def test_save_private_key(self):
         """Test saving private DER keys."""
@@ -89,6 +123,7 @@ class DerTest(unittest.TestCase):
         key = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
         der = key.save_pkcs1('DER')
 
+        self.assertIsInstance(der, bytes)
         self.assertEqual(PRIVATE_DER, der)
 
     def test_load_public_key(self):
@@ -105,6 +140,7 @@ class DerTest(unittest.TestCase):
         key = rsa.key.PublicKey(3727264081, 65537)
         der = key.save_pkcs1('DER')
 
+        self.assertIsInstance(der, bytes)
         self.assertEqual(PUBLIC_DER, der)
 
 
@@ -118,6 +154,9 @@ class PemTest(unittest.TestCase):
         expected = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
 
         self.assertEqual(expected, key)
+        self.assertEqual(key.exp1, 55063)
+        self.assertEqual(key.exp2, 10095)
+        self.assertEqual(key.coef, 50797)
 
     def test_save_private_key(self):
         """Test saving private PEM files."""
@@ -125,6 +164,7 @@ class PemTest(unittest.TestCase):
         key = rsa.key.PrivateKey(3727264081, 65537, 3349121513, 65063, 57287)
         pem = key.save_pkcs1('PEM')
 
+        self.assertIsInstance(pem, bytes)
         self.assertEqual(CLEAN_PRIVATE_PEM, pem)
 
     def test_load_public_key(self):
@@ -141,6 +181,7 @@ class PemTest(unittest.TestCase):
         key = rsa.key.PublicKey(3727264081, 65537)
         pem = key.save_pkcs1('PEM')
 
+        self.assertIsInstance(pem, bytes)
         self.assertEqual(CLEAN_PUBLIC_PEM, pem)
 
     def test_load_from_disk(self):

+ 0 - 0
desktop/core/ext-py/rsa-3.4.2/tests/test_parallel.py → desktop/core/ext-py/rsa-4.0/tests/test_parallel.py


+ 31 - 3
desktop/core/ext-py/rsa-3.4.2/tests/test_pem.py → desktop/core/ext-py/rsa-4.0/tests/test_pem.py

@@ -17,7 +17,7 @@
 
 import unittest
 
-from rsa._compat import b
+from rsa._compat import is_bytes
 from rsa.pem import _markers
 import rsa.key
 
@@ -49,8 +49,8 @@ prime2 = 88103681619592083641803383393198542599284510949756076218404908654323473
 class TestMarkers(unittest.TestCase):
     def test_values(self):
         self.assertEqual(_markers('RSA PRIVATE KEY'),
-                         (b('-----BEGIN RSA PRIVATE KEY-----'),
-                          b('-----END RSA PRIVATE KEY-----')))
+                         (b'-----BEGIN RSA PRIVATE KEY-----',
+                          b'-----END RSA PRIVATE KEY-----'))
 
 
 class TestBytesAndStrings(unittest.TestCase):
@@ -72,3 +72,31 @@ class TestBytesAndStrings(unittest.TestCase):
         key = rsa.key.PrivateKey.load_pkcs1(private_key_pem.encode('ascii'))
         self.assertEqual(prime1, key.p)
         self.assertEqual(prime2, key.q)
+
+
+class TestByteOutput(unittest.TestCase):
+    """Tests that PEM and DER are returned as bytes."""
+
+    def test_bytes_public(self):
+        key = rsa.key.PublicKey.load_pkcs1_openssl_pem(public_key_pem)
+        self.assertTrue(is_bytes(key.save_pkcs1(format='DER')))
+        self.assertTrue(is_bytes(key.save_pkcs1(format='PEM')))
+
+    def test_bytes_private(self):
+        key = rsa.key.PrivateKey.load_pkcs1(private_key_pem)
+        self.assertTrue(is_bytes(key.save_pkcs1(format='DER')))
+        self.assertTrue(is_bytes(key.save_pkcs1(format='PEM')))
+
+
+class TestByteInput(unittest.TestCase):
+    """Tests that PEM and DER can be loaded from bytes."""
+
+    def test_bytes_public(self):
+        key = rsa.key.PublicKey.load_pkcs1_openssl_pem(public_key_pem.encode('ascii'))
+        self.assertTrue(is_bytes(key.save_pkcs1(format='DER')))
+        self.assertTrue(is_bytes(key.save_pkcs1(format='PEM')))
+
+    def test_bytes_private(self):
+        key = rsa.key.PrivateKey.load_pkcs1(private_key_pem.encode('ascii'))
+        self.assertTrue(is_bytes(key.save_pkcs1(format='DER')))
+        self.assertTrue(is_bytes(key.save_pkcs1(format='PEM')))

+ 36 - 9
desktop/core/ext-py/rsa-3.4.2/tests/test_pkcs1.py → desktop/core/ext-py/rsa-4.0/tests/test_pkcs1.py

@@ -21,7 +21,7 @@ import unittest
 
 import rsa
 from rsa import pkcs1
-from rsa._compat import byte, b, is_bytes
+from rsa._compat import byte, is_bytes
 
 
 class BinaryTest(unittest.TestCase):
@@ -48,7 +48,8 @@ class BinaryTest(unittest.TestCase):
         a = encrypted[5]
         if is_bytes(a):
             a = ord(a)
-        encrypted = encrypted[:5] + byte(a + 1) + encrypted[6:]
+        altered_a = (a + 1) % 256
+        encrypted = encrypted[:5] + byte(altered_a) + encrypted[6:]
 
         self.assertRaises(pkcs1.DecryptionError, pkcs1.decrypt, encrypted,
                           self.priv)
@@ -72,27 +73,32 @@ class SignatureTest(unittest.TestCase):
     def test_sign_verify(self):
         """Test happy flow of sign and verify"""
 
-        message = b('je moeder')
-        print("\tMessage:   %r" % message)
+        message = b'je moeder'
+        signature = pkcs1.sign(message, self.priv, 'SHA-256')
+
+        self.assertEqual('SHA-256', pkcs1.verify(message, signature, self.pub))
+
+    def test_find_signature_hash(self):
+        """Test happy flow of sign and find_signature_hash"""
 
+        message = b'je moeder'
         signature = pkcs1.sign(message, self.priv, 'SHA-256')
-        print("\tSignature: %r" % signature)
 
-        self.assertTrue(pkcs1.verify(message, signature, self.pub))
+        self.assertEqual('SHA-256', pkcs1.find_signature_hash(signature, self.pub))
 
     def test_alter_message(self):
         """Altering the message should let the verification fail."""
 
-        signature = pkcs1.sign(b('je moeder'), self.priv, 'SHA-256')
+        signature = pkcs1.sign(b'je moeder', self.priv, 'SHA-256')
         self.assertRaises(pkcs1.VerificationError, pkcs1.verify,
-                          b('mijn moeder'), signature, self.pub)
+                          b'mijn moeder', signature, self.pub)
 
     def test_sign_different_key(self):
         """Signing with another key should let the verification fail."""
 
         (otherpub, _) = rsa.newkeys(512)
 
-        message = b('je moeder')
+        message = b'je moeder'
         signature = pkcs1.sign(message, self.priv, 'SHA-256')
         self.assertRaises(pkcs1.VerificationError, pkcs1.verify,
                           message, signature, otherpub)
@@ -105,3 +111,24 @@ class SignatureTest(unittest.TestCase):
         signature2 = pkcs1.sign(message, self.priv, 'SHA-1')
 
         self.assertEqual(signature1, signature2)
+
+    def test_split_hash_sign(self):
+        """Hashing and then signing should match with directly signing the message. """
+
+        message = b'je moeder'
+        msg_hash = pkcs1.compute_hash(message, 'SHA-256')
+        signature1 = pkcs1.sign_hash(msg_hash, self.priv, 'SHA-256')
+
+        # Calculate the signature using the unified method
+        signature2 = pkcs1.sign(message, self.priv, 'SHA-256')
+
+        self.assertEqual(signature1, signature2)
+
+    def test_hash_sign_verify(self):
+        """Test happy flow of hash, sign, and verify"""
+
+        message = b'je moeder'
+        msg_hash = pkcs1.compute_hash(message, 'SHA-224')
+        signature = pkcs1.sign_hash(msg_hash, self.priv, 'SHA-224')
+
+        self.assertTrue(pkcs1.verify(message, signature, self.pub))

+ 83 - 0
desktop/core/ext-py/rsa-4.0/tests/test_pkcs1_v2.py

@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+#
+#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+"""Tests PKCS #1 version 2 functionality.
+
+Most of the mocked values come from the test vectors found at:
+http://www.itomorrowmag.com/emc-plus/rsa-labs/standards-initiatives/pkcs-rsa-cryptography-standard.htm
+"""
+
+import unittest
+
+from rsa import pkcs1_v2
+
+
+class MGFTest(unittest.TestCase):
+    def test_oaep_int_db_mask(self):
+        seed = (
+            b'\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2'
+            b'\xf0\x6c\xb5\x8f'
+        )
+        db = (
+            b'\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90'
+            b'\xaf\xd8\x07\x09\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+            b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+            b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+            b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
+            b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xd4\x36\xe9\x95\x69'
+            b'\xfd\x32\xa7\xc8\xa0\x5b\xbc\x90\xd3\x2c\x49'
+        )
+        masked_db = (
+            b'\xdc\xd8\x7d\x5c\x68\xf1\xee\xa8\xf5\x52\x67\xc3\x1b\x2e\x8b\xb4'
+            b'\x25\x1f\x84\xd7\xe0\xb2\xc0\x46\x26\xf5\xaf\xf9\x3e\xdc\xfb\x25'
+            b'\xc9\xc2\xb3\xff\x8a\xe1\x0e\x83\x9a\x2d\xdb\x4c\xdc\xfe\x4f\xf4'
+            b'\x77\x28\xb4\xa1\xb7\xc1\x36\x2b\xaa\xd2\x9a\xb4\x8d\x28\x69\xd5'
+            b'\x02\x41\x21\x43\x58\x11\x59\x1b\xe3\x92\xf9\x82\xfb\x3e\x87\xd0'
+            b'\x95\xae\xb4\x04\x48\xdb\x97\x2f\x3a\xc1\x4f\x7b\xc2\x75\x19\x52'
+            b'\x81\xce\x32\xd2\xf1\xb7\x6d\x4d\x35\x3e\x2d'
+        )
+
+        # dbMask = MGF(seed, length(DB))
+        db_mask = pkcs1_v2.mgf1(seed, length=len(db))
+        expected_db_mask = (
+            b'\x06\xe1\xde\xb2\x36\x9a\xa5\xa5\xc7\x07\xd8\x2c\x8e\x4e\x93\x24'
+            b'\x8a\xc7\x83\xde\xe0\xb2\xc0\x46\x26\xf5\xaf\xf9\x3e\xdc\xfb\x25'
+            b'\xc9\xc2\xb3\xff\x8a\xe1\x0e\x83\x9a\x2d\xdb\x4c\xdc\xfe\x4f\xf4'
+            b'\x77\x28\xb4\xa1\xb7\xc1\x36\x2b\xaa\xd2\x9a\xb4\x8d\x28\x69\xd5'
+            b'\x02\x41\x21\x43\x58\x11\x59\x1b\xe3\x92\xf9\x82\xfb\x3e\x87\xd0'
+            b'\x95\xae\xb4\x04\x48\xdb\x97\x2f\x3a\xc1\x4e\xaf\xf4\x9c\x8c\x3b'
+            b'\x7c\xfc\x95\x1a\x51\xec\xd1\xdd\xe6\x12\x64'
+        )
+
+        self.assertEqual(db_mask, expected_db_mask)
+
+        # seedMask = MGF(maskedDB, length(seed))
+        seed_mask = pkcs1_v2.mgf1(masked_db, length=len(seed))
+        expected_seed_mask = (
+            b'\x41\x87\x0b\x5a\xb0\x29\xe6\x57\xd9\x57\x50\xb5\x4c\x28\x3c\x08'
+            b'\x72\x5d\xbe\xa9'
+        )
+
+        self.assertEqual(seed_mask, expected_seed_mask)
+
+    def test_invalid_hasher(self):
+        """Tests an invalid hasher generates an exception"""
+        with self.assertRaises(ValueError):
+            pkcs1_v2.mgf1(b'\x06\xe1\xde\xb2', length=8, hasher='SHA2')
+
+    def test_invalid_length(self):
+        with self.assertRaises(OverflowError):
+            pkcs1_v2.mgf1(b'\x06\xe1\xde\xb2', length=2**50)

+ 110 - 0
desktop/core/ext-py/rsa-4.0/tests/test_prime.py

@@ -0,0 +1,110 @@
+# -*- coding: utf-8 -*-
+#
+#  Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu>
+#
+#  Licensed under the Apache License, Version 2.0 (the "License");
+#  you may not use this file except in compliance with the License.
+#  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing, software
+#  distributed under the License is distributed on an "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#  See the License for the specific language governing permissions and
+#  limitations under the License.
+
+"""Tests prime functions."""
+
+import unittest
+
+from rsa._compat import range
+import rsa.prime
+import rsa.randnum
+
+
+class PrimeTest(unittest.TestCase):
+    def test_is_prime(self):
+        """Test some common primes."""
+
+        # Test some trivial numbers
+        self.assertFalse(rsa.prime.is_prime(-1))
+        self.assertFalse(rsa.prime.is_prime(0))
+        self.assertFalse(rsa.prime.is_prime(1))
+        self.assertTrue(rsa.prime.is_prime(2))
+        self.assertFalse(rsa.prime.is_prime(42))
+        self.assertTrue(rsa.prime.is_prime(41))
+
+        # Test some slightly larger numbers
+        self.assertEqual(
+            [907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997],
+            [x for x in range(901, 1000) if rsa.prime.is_prime(x)]
+        )
+
+        # Test around the 50th millionth known prime.
+        self.assertTrue(rsa.prime.is_prime(982451653))
+        self.assertFalse(rsa.prime.is_prime(982451653 * 961748941))
+
+    def test_miller_rabin_primality_testing(self):
+        """Uses monkeypatching to ensure certain random numbers.
+
+        This allows us to predict/control the code path.
+        """
+
+        randints = []
+
+        def fake_randint(maxvalue):
+            return randints.pop(0)
+
+        orig_randint = rsa.randnum.randint
+        rsa.randnum.randint = fake_randint
+        try:
+            # 'n is composite'
+            randints.append(2630484832)  # causes the 'n is composite' case with n=3784949785
+            self.assertEqual(False, rsa.prime.miller_rabin_primality_testing(2787998641, 7))
+            self.assertEqual([], randints)
+
+            # 'Exit inner loop and continue with next witness'
+            randints.extend([
+                2119139098,  # causes 'Exit inner loop and continue with next witness'
+                # the next witnesses for the above case:
+                3051067716, 3603501763, 3230895847, 3687808133, 3760099987, 4026931495, 3022471882,
+            ])
+            self.assertEqual(True, rsa.prime.miller_rabin_primality_testing(2211417913,
+                                                                            len(randints)))
+            self.assertEqual([], randints)
+        finally:
+            rsa.randnum.randint = orig_randint
+
+    def test_mersenne_primes(self):
+        """Tests first known Mersenne primes.
+
+        Mersenne primes are prime numbers that can be written in the form
+        `Mn = 2**n - 1` for some integer `n`. For the list of known Mersenne
+        primes, see:
+        https://en.wikipedia.org/wiki/Mersenne_prime#List_of_known_Mersenne_primes
+        """
+
+        # List of known Mersenne exponents.
+        known_mersenne_exponents = [
+            2, 3, 5, 7, 13, 17, 19, 31, 61, 89, 107, 127, 521, 607, 1279,
+            2203, 2281, 4423,
+        ]
+
+        # Test Mersenne primes.
+        for exp in known_mersenne_exponents:
+            self.assertTrue(rsa.prime.is_prime(2**exp - 1))
+
+    def test_get_primality_testing_rounds(self):
+        """Test round calculation for primality testing."""
+
+        self.assertEqual(rsa.prime.get_primality_testing_rounds(1 << 63),  10)
+        self.assertEqual(rsa.prime.get_primality_testing_rounds(1 << 127), 10)
+        self.assertEqual(rsa.prime.get_primality_testing_rounds(1 << 255), 10)
+        self.assertEqual(rsa.prime.get_primality_testing_rounds(1 << 511),  7)
+        self.assertEqual(rsa.prime.get_primality_testing_rounds(1 << 767),  7)
+        self.assertEqual(rsa.prime.get_primality_testing_rounds(1 << 1023), 4)
+        self.assertEqual(rsa.prime.get_primality_testing_rounds(1 << 1279), 4)
+        self.assertEqual(rsa.prime.get_primality_testing_rounds(1 << 1535), 3)
+        self.assertEqual(rsa.prime.get_primality_testing_rounds(1 << 2047), 3)
+        self.assertEqual(rsa.prime.get_primality_testing_rounds(1 << 4095), 3)

+ 0 - 0
desktop/core/ext-py/rsa-3.4.2/tests/test_strings.py → desktop/core/ext-py/rsa-4.0/tests/test_strings.py


+ 12 - 13
desktop/core/ext-py/rsa-3.4.2/tests/test_transform.py → desktop/core/ext-py/rsa-4.0/tests/test_transform.py

@@ -15,37 +15,36 @@
 #  limitations under the License.
 
 import unittest
-from rsa._compat import b
 from rsa.transform import int2bytes, bytes2int, _int2bytes
 
 
 class Test_int2bytes(unittest.TestCase):
     def test_accuracy(self):
-        self.assertEqual(int2bytes(123456789), b('\x07[\xcd\x15'))
-        self.assertEqual(_int2bytes(123456789), b('\x07[\xcd\x15'))
+        self.assertEqual(int2bytes(123456789), b'\x07[\xcd\x15')
+        self.assertEqual(_int2bytes(123456789), b'\x07[\xcd\x15')
 
     def test_codec_identity(self):
         self.assertEqual(bytes2int(int2bytes(123456789, 128)), 123456789)
         self.assertEqual(bytes2int(_int2bytes(123456789, 128)), 123456789)
 
     def test_chunk_size(self):
-        self.assertEqual(int2bytes(123456789, 6), b('\x00\x00\x07[\xcd\x15'))
+        self.assertEqual(int2bytes(123456789, 6), b'\x00\x00\x07[\xcd\x15')
         self.assertEqual(int2bytes(123456789, 7),
-                         b('\x00\x00\x00\x07[\xcd\x15'))
+                         b'\x00\x00\x00\x07[\xcd\x15')
 
         self.assertEqual(_int2bytes(123456789, 6),
-                         b('\x00\x00\x07[\xcd\x15'))
+                         b'\x00\x00\x07[\xcd\x15')
         self.assertEqual(_int2bytes(123456789, 7),
-                         b('\x00\x00\x00\x07[\xcd\x15'))
+                         b'\x00\x00\x00\x07[\xcd\x15')
 
     def test_zero(self):
-        self.assertEqual(int2bytes(0, 4), b('\x00') * 4)
-        self.assertEqual(int2bytes(0, 7), b('\x00') * 7)
-        self.assertEqual(int2bytes(0), b('\x00'))
+        self.assertEqual(int2bytes(0, 4), b'\x00' * 4)
+        self.assertEqual(int2bytes(0, 7), b'\x00' * 7)
+        self.assertEqual(int2bytes(0), b'\x00')
 
-        self.assertEqual(_int2bytes(0, 4), b('\x00') * 4)
-        self.assertEqual(_int2bytes(0, 7), b('\x00') * 7)
-        self.assertEqual(_int2bytes(0), b('\x00'))
+        self.assertEqual(_int2bytes(0, 4), b'\x00' * 4)
+        self.assertEqual(_int2bytes(0, 7), b'\x00' * 7)
+        self.assertEqual(_int2bytes(0), b'\x00')
 
     def test_correctness_against_base_implementation(self):
         # Slow test.