예제 #1
0
    def testStrict1(self):
        number = DerInteger()

        number.decode(b'\x02\x02\x00\x01')
        number.decode(b'\x02\x02\x00\x7F')
        self.assertRaises(ValueError, number.decode, b'\x02\x02\x00\x01', strict=True)
        self.assertRaises(ValueError, number.decode, b'\x02\x02\x00\x7F', strict=True)
예제 #2
0
 def testDecode2(self):
     # Multi-byte integer
     der = DerInteger()
     # Value 0x180L
     der.decode(b('\x02\x02\x01\x80'))
     self.assertEquals(der.value,0x180L)
     # One very long integer
     der.decode(
     b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\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')+
     b('\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')+
     b('\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')+
     b('\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')+
     b('\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')+
     b('\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')+
     b('\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')+
     b('\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')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
     self.assertEquals(der.value,2L**2048)
 def testEncode2(self):
     # Multi-byte integers
     # Value 128
     der = DerInteger(128)
     self.assertEquals(der.encode(), b('\x02\x02\x00\x80'))
     # Value 0x180
     der = DerInteger(0x180L)
     self.assertEquals(der.encode(), b('\x02\x02\x01\x80'))
     # One very long integer
     der = DerInteger(2L**2048)
     self.assertEquals(
         der.encode(),
         b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00') +
         b('\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') +
         b('\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') +
         b('\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') +
         b('\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') +
         b('\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') +
         b('\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') +
         b('\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') +
         b('\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') +
         b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +
         b('\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
예제 #4
0
    def testStrict1(self):
        number = DerInteger()

        number.decode(b'\x02\x02\x00\x01')
        number.decode(b'\x02\x02\x00\x7F')
        self.assertRaises(ValueError, number.decode, b'\x02\x02\x00\x01', strict=True)
        self.assertRaises(ValueError, number.decode, b'\x02\x02\x00\x7F', strict=True)
예제 #5
0
 def testDecode3(self):
     # Negative integer
     der = DerInteger()
     # Value -1
     der.decode(b('\x02\x01\xFF'))
     self.assertEquals(der.value, -1)
     # Value -32768
     der.decode(b('\x02\x02\x80\x00'))
     self.assertEquals(der.value, -32768)
예제 #6
0
 def testEncode3(self):
     # Negative integers
     # Value -1
     der = DerInteger(-1)
     self.assertEquals(der.encode(), b('\x02\x01\xFF'))
     # Value -128
     der = DerInteger(-128)
     self.assertEquals(der.encode(), b('\x02\x01\x80'))
     # Value
     der = DerInteger(-87873)
     self.assertEquals(der.encode(), b('\x02\x03\xFE\xA8\xBF'))
예제 #7
0
 def testEncode1(self):
     # Single-byte integers
     # Value 0
     der = DerInteger(0)
     self.assertEquals(der.encode(), b('\x02\x01\x00'))
     # Value 1
     der = DerInteger(1)
     self.assertEquals(der.encode(), b('\x02\x01\x01'))
     # Value 127
     der = DerInteger(127)
     self.assertEquals(der.encode(), b('\x02\x01\x7F'))
예제 #8
0
 def testDecode1(self):
     # Single-byte integer
     der = DerInteger()
     # Value 0
     der.decode(b('\x02\x01\x00'))
     self.assertEquals(der.value, 0)
     # Value 1
     der.decode(b('\x02\x01\x01'))
     self.assertEquals(der.value, 1)
     # Value 127
     der.decode(b('\x02\x01\x7F'))
     self.assertEquals(der.value, 127)
예제 #9
0
def _import_pkcs8(encoded, passphrase, params):
    if params:
        raise ValueError("PKCS#8 already includes parameters")
    k = PKCS8.unwrap(encoded, passphrase)
    if k[0] != oid:
        raise ValueError("No PKCS#8 encoded DSA key")
    x = DerInteger().decode(k[1]).value
    p, q, g = list(DerSequence().decode(k[2]))
    tup = (pow(g, x, p), g, p, q, x)
    return construct(tup)
예제 #10
0
 def testDecode5(self):
     # We still accept BER integer format
     der = DerInteger()
     # Redundant leading zeroes
     der.decode(b('\x02\x02\x00\x01'))
     self.assertEquals(der.value, 1)
     # Redundant leading 0xFF
     der.decode(b('\x02\x02\xFF\xFF'))
     self.assertEquals(der.value, -1)
     # Empty payload
     der.decode(b('\x02\x00'))
     self.assertEquals(der.value, 0)
예제 #11
0
def _import_subjectPublicKeyInfo(encoded, passphrase, params):

    algoid, encoded_key, emb_params =  _expand_subject_public_key_info(encoded)
    if algoid != oid:
        raise ValueError("No DSA subjectPublicKeyInfo")
    if params and emb_params:
        raise ValueError("Too many DSA parameters")

    y = DerInteger().decode(encoded_key).value
    p, q, g = list(DerSequence().decode(params or emb_params))
    tup = (y, g, p, q)
    return construct(tup)
예제 #12
0
 def testDecode2(self):
     # Multi-byte integer
     der = DerInteger()
     # Value 0x180L
     der.decode(b('\x02\x02\x01\x80'))
     self.assertEquals(der.value, 0x180)
     # One very long integer
     der.decode(
         b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00') +
         b('\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') +
         b('\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') +
         b('\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') +
         b('\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') +
         b('\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') +
         b('\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') +
         b('\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') +
         b('\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') +
         b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') +
         b('\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
     self.assertEquals(der.value, 2**2048)
예제 #13
0
 def testEncode2(self):
     # Multi-byte integers
     # Value 128
     der = DerInteger(128)
     self.assertEquals(der.encode(), b('\x02\x02\x00\x80'))
     # Value 0x180
     der = DerInteger(0x180L)
     self.assertEquals(der.encode(), b('\x02\x02\x01\x80'))
     # One very long integer
     der = DerInteger(2L**2048)
     self.assertEquals(der.encode(),
     b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\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')+
     b('\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')+
     b('\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')+
     b('\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')+
     b('\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')+
     b('\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')+
     b('\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')+
     b('\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')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+
     b('\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
예제 #14
0
 def testDecode5(self):
     # We still accept BER integer format
     der = DerInteger()
     # Redundant leading zeroes
     der.decode(b('\x02\x02\x00\x01'))
     self.assertEquals(der.value, 1)
     # Redundant leading 0xFF
     der.decode(b('\x02\x02\xFF\xFF'))
     self.assertEquals(der.value, -1)
     # Empty payload
     der.decode(b('\x02\x00'))
     self.assertEquals(der.value, 0)
예제 #15
0
 def testDecode1(self):
     # Single-byte integer
     der = DerInteger()
     # Value 0
     der.decode(b('\x02\x01\x00'))
     self.assertEquals(der.value, 0)
     # Value 1
     der.decode(b('\x02\x01\x01'))
     self.assertEquals(der.value, 1)
     # Value 127
     der.decode(b('\x02\x01\x7F'))
     self.assertEquals(der.value, 127)
예제 #16
0
 def testDecode3(self):
     # Negative integer
     der = DerInteger()
     # Value -1
     der.decode(b('\x02\x01\xFF'))
     self.assertEquals(der.value, -1)
     # Value -32768
     der.decode(b('\x02\x02\x80\x00'))
     self.assertEquals(der.value, -32768)
예제 #17
0
 def testEncode3(self):
     # Negative integers
     # Value -1
     der = DerInteger(-1)
     self.assertEquals(der.encode(), b('\x02\x01\xFF'))
     # Value -128
     der = DerInteger(-128)
     self.assertEquals(der.encode(), b('\x02\x01\x80'))
     # Value
     der = DerInteger(-87873)
     self.assertEquals(der.encode(), b('\x02\x03\xFE\xA8\xBF'))
예제 #18
0
 def testEncode1(self):
     # Single-byte integers
     # Value 0
     der = DerInteger(0)
     self.assertEquals(der.encode(), b('\x02\x01\x00'))
     # Value 1
     der = DerInteger(1)
     self.assertEquals(der.encode(), b('\x02\x01\x01'))
     # Value 127
     der = DerInteger(127)
     self.assertEquals(der.encode(), b('\x02\x01\x7F'))
예제 #19
0
def _extract_subject_public_key_info(x509_certificate):
    """Extract subjectPublicKeyInfo from a DER X.509 certificate."""

    certificate = DerSequence().decode(x509_certificate, nr_elements=3)
    tbs_certificate = DerSequence().decode(certificate[0],
                                           nr_elements=list(range(6, 11)))

    index = 5
    try:
        tbs_certificate[0] + 1
        # Version not present
        version = 1
    except TypeError:
        version = DerInteger(explicit=0).decode(tbs_certificate[0]).value
        if version not in (2, 3):
            raise ValueError("Incorrect X.509 certificate version")
        index = 6

    return tbs_certificate[index]
예제 #20
0
 def testDecode6(self):
     # Explicit encoding
     number = DerInteger(explicit=3)
     number.decode(b('\xa3\x03\x02\x01\x34'))
     self.assertEquals(number.value, 0x34)
예제 #21
0
 def testDecode6(self):
     # Explicit encoding
     number = DerInteger(explicit=3)
     number.decode(b('\xa3\x03\x02\x01\x34'))
     self.assertEquals(number.value, 0x34)
예제 #22
0
    def exportKey(self, format='PEM', pkcs8=None, passphrase=None,
                  protection=None, randfunc=None):
        """Export this DSA key.

        Args:
          format (string):
            The encoding for the output:

            - *'PEM'* (default). ASCII as per `RFC1421`_/ `RFC1423`_.
            - *'DER'*. Binary ASN.1 encoding.
            - *'OpenSSH'*. ASCII one-liner as per `RFC4253`_.
              Only suitable for public keys, not for private keys.

          passphrase (string):
            *Private keys only*. The pass phrase to protect the output.

          pkcs8 (boolean):
            *Private keys only*. If ``True`` (default), the key is encoded
            with `PKCS#8`_. If ``False``, it is encoded in the custom
            OpenSSL/OpenSSH container.

          protection (string):
            *Only in combination with a pass phrase*.
            The encryption scheme to use to protect the output.

            If :data:`pkcs8` takes value ``True``, this is the PKCS#8
            algorithm to use for deriving the secret and encrypting
            the private DSA key.
            For a complete list of algorithms, see :mod:`Cryptodome.IO.PKCS8`.
            The default is *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*.

            If :data:`pkcs8` is ``False``, the obsolete PEM encryption scheme is
            used. It is based on MD5 for key derivation, and Triple DES for
            encryption. Parameter :data:`protection` is then ignored.

            The combination ``format='DER'`` and ``pkcs8=False`` is not allowed
            if a passphrase is present.

          randfunc (callable):
            A function that returns random bytes.
            By default it is :func:`Cryptodome.Random.get_random_bytes`.

        Returns:
          byte string : the encoded key

        Raises:
          ValueError : when the format is unknown or when you try to encrypt a private
            key with *DER* format and OpenSSL/OpenSSH.

        .. warning::
            If you don't provide a pass phrase, the private key will be
            exported in the clear!

        .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt
        .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt
        .. _RFC4253:    http://www.ietf.org/rfc/rfc4253.txt
        .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt
        """

        if passphrase is not None:
            passphrase = tobytes(passphrase)

        if randfunc is None:
            randfunc = Random.get_random_bytes

        if format == 'OpenSSH':
            tup1 = [self._key[x].to_bytes() for x in 'p', 'q', 'g', 'y']

            def func(x):
                if (bord(x[0]) & 0x80):
                    return bchr(0) + x
                else:
                    return x

            tup2 = map(func, tup1)
            keyparts = [b('ssh-dss')] + tup2
            keystring = b('').join(
                            [struct.pack(">I", len(kp)) + kp for kp in keyparts]
                            )
            return b('ssh-dss ') + binascii.b2a_base64(keystring)[:-1]

        # DER format is always used, even in case of PEM, which simply
        # encodes it into BASE64.
        params = DerSequence([self.p, self.q, self.g])
        if self.has_private():
            if pkcs8 is None:
                pkcs8 = True
            if pkcs8:
                if not protection:
                    protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC'
                private_key = DerInteger(self.x).encode()
                binary_key = PKCS8.wrap(
                                private_key, oid, passphrase,
                                protection, key_params=params,
                                randfunc=randfunc
                                )
                if passphrase:
                    key_type = 'ENCRYPTED PRIVATE'
                else:
                    key_type = 'PRIVATE'
                passphrase = None
            else:
                if format != 'PEM' and passphrase:
                    raise ValueError("DSA private key cannot be encrypted")
                ints = [0, self.p, self.q, self.g, self.y, self.x]
                binary_key = DerSequence(ints).encode()
                key_type = "DSA PRIVATE"
        else:
            if pkcs8:
                raise ValueError("PKCS#8 is only meaningful for private keys")

            binary_key = _create_subject_public_key_info(oid,
                                DerInteger(self.y), params)
            key_type = "PUBLIC"

        if format == 'DER':
            return binary_key
        if format == 'PEM':
            pem_str = PEM.encode(
                                binary_key, key_type + " KEY",
                                passphrase, randfunc
                            )
            return tobytes(pem_str)
        raise ValueError("Unknown key format '%s'. Cannot export the DSA key." % format)
예제 #23
0
 def testInit1(self):
     der = DerSetOf([DerInteger(1), DerInteger(2)])
     self.assertEquals(der.encode(), b('1\x06\x02\x01\x01\x02\x01\x02'))
예제 #24
0
 def testInit2(self):
     der = DerBitString(DerInteger(1))
     self.assertEquals(der.encode(), b('\x03\x04\x00\x02\x01\x01'))
예제 #25
0
 def testInit1(self):
     der = DerSequence([1, DerInteger(2), b('0\x00')])
     self.assertEquals(der.encode(),
                       b('0\x08\x02\x01\x01\x02\x01\x020\x00'))
예제 #26
0
 def testErrDecode1(self):
     # Wide length field
     der = DerInteger()
     self.assertRaises(ValueError, der.decode, b('\x02\x81\x01\x01'))
예제 #27
0
 def testDecode7(self):
     # Verify decode returns the DerInteger
     der = DerInteger()
     self.assertEquals(der, der.decode(b('\x02\x01\x7F')))
예제 #28
0
 def testInit1(self):
     der = DerInteger(1)
     self.assertEquals(der.encode(), b('\x02\x01\x01'))
예제 #29
0
 def testDecode7(self):
     # Verify decode returns the DerInteger
     der = DerInteger()
     self.assertEquals(der, der.decode(b('\x02\x01\x7F')))
예제 #30
0
 def testInit1(self):
     der = DerInteger(1)
     self.assertEquals(der.encode(), b('\x02\x01\x01'))
예제 #31
0
 def testEncode4(self):
     # Explicit encoding
     number = DerInteger(0x34, explicit=3)
     self.assertEquals(number.encode(), b('\xa3\x03\x02\x01\x34'))
예제 #32
0
    def encrypt(data, passphrase, protection, prot_params=None, randfunc=None):
        """Encrypt a piece of data using a passphrase and *PBES2*.

        :Parameters:
          data : byte string
            The piece of data to encrypt.
          passphrase : byte string
            The passphrase to use for encrypting the data.
          protection : string
            The identifier of the encryption algorithm to use.
            The default value is '``PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC``'.
          prot_params : dictionary
            Parameters of the protection algorithm.

            +------------------+-----------------------------------------------+
            | Key              | Description                                   |
            +==================+===============================================+
            | iteration_count  | The KDF algorithm is repeated several times to|
            |                  | slow down brute force attacks on passwords    |
            |                  | (called *N* or CPU/memory cost in scrypt).    |
            |                  |                                               |
            |                  | The default value for PBKDF2 is 1 000.        |
            |                  | The default value for scrypt is 16 384.       |
            +------------------+-----------------------------------------------+
            | salt_size        | Salt is used to thwart dictionary and rainbow |
            |                  | attacks on passwords. The default value is 8  |
            |                  | bytes.                                        |
            +------------------+-----------------------------------------------+
            | block_size       | *(scrypt only)* Memory-cost (r). The default  |
            |                  | value is 8.                                   |
            +------------------+-----------------------------------------------+
            | parallelization  | *(scrypt only)* CPU-cost (p). The default     |
            |                  | value is 1.                                   |
            +------------------+-----------------------------------------------+


          randfunc : callable
            Random number generation function; it should accept
            a single integer N and return a string of random data,
            N bytes long. If not specified, a new RNG will be
            instantiated from ``Cryptodome.Random``.

        :Returns:
          The encrypted data, as a binary string.
        """

        if prot_params is None:
            prot_params = {}

        if randfunc is None:
            randfunc = Random.new().read

        if protection == 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC':
            key_size = 24
            module = DES3
            cipher_mode = DES3.MODE_CBC
            enc_oid = _OID_DES_EDE3_CBC
        elif protection in ('PBKDF2WithHMAC-SHA1AndAES128-CBC',
                            'scryptAndAES128-CBC'):
            key_size = 16
            module = AES
            cipher_mode = AES.MODE_CBC
            enc_oid = _OID_AES128_CBC
        elif protection in ('PBKDF2WithHMAC-SHA1AndAES192-CBC',
                            'scryptAndAES192-CBC'):
            key_size = 24
            module = AES
            cipher_mode = AES.MODE_CBC
            enc_oid = _OID_AES192_CBC
        elif protection in ('PBKDF2WithHMAC-SHA1AndAES256-CBC',
                            'scryptAndAES256-CBC'):
            key_size = 32
            module = AES
            cipher_mode = AES.MODE_CBC
            enc_oid = _OID_AES256_CBC
        else:
            raise ValueError("Unknown PBES2 mode")

        # Get random data
        iv = randfunc(module.block_size)
        salt = randfunc(prot_params.get("salt_size", 8))

        # Derive key from password
        if protection.startswith('PBKDF2'):
            count = prot_params.get("iteration_count", 1000)
            key = PBKDF2(passphrase, salt, key_size, count)
            kdf_info = DerSequence([
                DerObjectId(_OID_PBKDF2),  # PBKDF2
                DerSequence([DerOctetString(salt),
                             DerInteger(count)])
            ])
        else:
            # It must be scrypt
            count = prot_params.get("iteration_count", 16384)
            scrypt_r = prot_params.get('block_size', 8)
            scrypt_p = prot_params.get('parallelization', 1)
            key = scrypt(passphrase, salt, key_size, count, scrypt_r, scrypt_p)
            kdf_info = DerSequence([
                DerObjectId(_OID_SCRYPT),  # scrypt
                DerSequence([
                    DerOctetString(salt),
                    DerInteger(count),
                    DerInteger(scrypt_r),
                    DerInteger(scrypt_p)
                ])
            ])

        # Create cipher and use it
        cipher = module.new(key, cipher_mode, iv)
        encrypted_data = cipher.encrypt(pad(data, cipher.block_size))
        enc_info = DerSequence([DerObjectId(enc_oid), DerOctetString(iv)])

        # Result
        enc_private_key_info = DerSequence([
            # encryptionAlgorithm
            DerSequence([
                DerObjectId(_OID_PBES2),
                DerSequence([kdf_info, enc_info]),
            ]),
            DerOctetString(encrypted_data)
        ])
        return enc_private_key_info.encode()
예제 #33
0
 def testEncode4(self):
     # Explicit encoding
     number = DerInteger(0x34, explicit=3)
     self.assertEquals(number.encode(), b('\xa3\x03\x02\x01\x34'))