Exemple #1
0
    def __init__(self, backend, algorithm, ctx=None):
        self.algorithm = algorithm

        self._backend = backend

        if ctx is None:
            ctx = self._backend._lib.EVP_MD_CTX_create()
            ctx = self._backend._ffi.gc(ctx,
                                        self._backend._lib.EVP_MD_CTX_destroy)
            evp_md = self._backend._lib.EVP_get_digestbyname(
                algorithm.name.encode("ascii"))
            if evp_md == self._backend._ffi.NULL:
                raise UnsupportedAlgorithm(
                    "{0} is not a supported hash on this backend".format(
                        algorithm.name)
                )
            res = self._backend._lib.EVP_DigestInit_ex(ctx, evp_md,
                                                       self._backend._ffi.NULL)
            assert res != 0

        self._ctx = ctx
Exemple #2
0
    def __init__(self, algorithm, length, sharedinfo, backend=None):
        backend = _get_backend(backend)

        max_len = algorithm.digest_size * (2**32 - 1)
        if length > max_len:
            raise ValueError(
                "Can not derive keys larger than {} bits.".format(max_len))
        if sharedinfo is not None:
            utils._check_bytes("sharedinfo", sharedinfo)

        self._algorithm = algorithm
        self._length = length
        self._sharedinfo = sharedinfo

        if not isinstance(backend, HashBackend):
            raise UnsupportedAlgorithm(
                "Backend object does not implement HashBackend.",
                _Reasons.BACKEND_MISSING_INTERFACE,
            )
        self._backend = backend
        self._used = False
    def __init__(self, backend, algorithm, ctx=None):
        self._algorithm = algorithm

        self._backend = backend

        if ctx is None:
            ctx = self._backend._lib.EVP_MD_CTX_new()
            ctx = self._backend._ffi.gc(ctx,
                                        self._backend._lib.EVP_MD_CTX_free)
            evp_md = self._backend._evp_md_from_algorithm(algorithm)
            if evp_md == self._backend._ffi.NULL:
                raise UnsupportedAlgorithm(
                    "{} is not a supported hash on this backend.".format(
                        algorithm.name),
                    _Reasons.UNSUPPORTED_HASH,
                )
            res = self._backend._lib.EVP_DigestInit_ex(ctx, evp_md,
                                                       self._backend._ffi.NULL)
            self._backend.openssl_assert(res != 0)

        self._ctx = ctx
Exemple #4
0
    def public_bytes(self, encoding, format):
        if format is not serialization.PublicFormat.SubjectPublicKeyInfo:
            raise ValueError("DH public keys support only "
                             "SubjectPublicKeyInfo serialization")

        if not self._backend._lib.Cryptography_HAS_EVP_PKEY_DHX:
            q = self._backend._ffi.new("BIGNUM **")
            self._backend._lib.DH_get0_pqg(
                self._dh_cdata,
                self._backend._ffi.NULL,
                q,
                self._backend._ffi.NULL,
            )
            if q[0] != self._backend._ffi.NULL:
                raise UnsupportedAlgorithm(
                    "DH X9.42 serialization is not supported",
                    _Reasons.UNSUPPORTED_SERIALIZATION,
                )

        return self._backend._public_key_bytes(encoding, format, self,
                                               self._evp_pkey, None)
Exemple #5
0
    def __init__(self, backend, key, algorithm, ctx=None):
        self._algorithm = algorithm
        self._backend = backend

        if ctx is None:
            ctx = self._backend._lib.Cryptography_HMAC_CTX_new()
            self._backend.openssl_assert(ctx != self._backend._ffi.NULL)
            ctx = self._backend._ffi.gc(
                ctx, self._backend._lib.Cryptography_HMAC_CTX_free)
            evp_md = self._backend._lib.EVP_get_digestbyname(
                algorithm.name.encode('ascii'))
            if evp_md == self._backend._ffi.NULL:
                raise UnsupportedAlgorithm(
                    "{0} is not a supported hash on this backend.".format(
                        algorithm.name), _Reasons.UNSUPPORTED_HASH)
            res = self._backend._lib.HMAC_Init_ex(ctx, key, len(key), evp_md,
                                                  self._backend._ffi.NULL)
            self._backend.openssl_assert(res != 0)

        self._ctx = ctx
        self._key = key
    def _get_keyidv2(pubkey):
        """ Calculate the keyidv2 of a given public key object. The keyidv2
            are the lowest 4 bytes of the sha1 hash over the public key bytes
            of a DER-encoded key in PKCS1 format.
        """
        if isinstance(pubkey, RSAPublicKey):
            fmt = serialization.PublicFormat.PKCS1
            pubbytes = pubkey.public_bytes(encoding=serialization.Encoding.DER,
                                           format=fmt)
        elif isinstance(pubkey, EllipticCurvePublicKey):
            fmt = serialization.PublicFormat.UncompressedPoint
            pubbytes = pubkey.public_bytes(encoding=serialization.Encoding.X962,
                                           format=fmt)
        else:
            raise UnsupportedAlgorithm(f"Unsupported public key type {type(pubkey)}")

        default_be = backends.default_backend()
        digest = hashes.Hash(hashes.SHA1(), backend=default_be)
        digest.update(pubbytes)
        keydigest = digest.finalize()
        return int.from_bytes(keydigest[16:], 'big')
Exemple #7
0
    def __init__(
        self,
        algorithm: hashes.HashAlgorithm,
        length: int,
        otherinfo: typing.Optional[bytes],
        backend=None,
    ):
        backend = _get_backend(backend)

        _common_args_checks(algorithm, length, otherinfo)
        self._algorithm = algorithm
        self._length = length
        self._otherinfo: bytes = otherinfo if otherinfo is not None else b""

        if not isinstance(backend, HashBackend):
            raise UnsupportedAlgorithm(
                "Backend object does not implement HashBackend.",
                _Reasons.BACKEND_MISSING_INTERFACE,
            )
        self._backend = backend
        self._used = False
Exemple #8
0
    def parameter_bytes(
        self,
        encoding: serialization.Encoding,
        format: serialization.ParameterFormat,
    ) -> bytes:
        if format is not serialization.ParameterFormat.PKCS3:
            raise ValueError("Only PKCS3 serialization is supported")
        if not self._backend._lib.Cryptography_HAS_EVP_PKEY_DHX:
            q = self._backend._ffi.new("BIGNUM **")
            self._backend._lib.DH_get0_pqg(
                self._dh_cdata,
                self._backend._ffi.NULL,
                q,
                self._backend._ffi.NULL,
            )
            if q[0] != self._backend._ffi.NULL:
                raise UnsupportedAlgorithm(
                    "DH X9.42 serialization is not supported",
                    _Reasons.UNSUPPORTED_SERIALIZATION,
                )

        return self._backend._parameter_bytes(encoding, format, self._dh_cdata)
Exemple #9
0
    def __init__(self, backend, key, algorithm, ctx=None):
        self._algorithm = algorithm
        self._backend = backend

        if ctx is None:
            ctx = self._backend._lib.Cryptography_HMAC_CTX_new()
            self._backend.openssl_assert(ctx != self._backend._ffi.NULL)
            ctx = self._backend._ffi.gc(
                ctx, self._backend._lib.Cryptography_HMAC_CTX_free)
            evp_md = self._backend._evp_md_from_algorithm(algorithm)
            if evp_md == self._backend._ffi.NULL:
                raise UnsupportedAlgorithm(
                    "{} is not a supported hash on this backend".format(
                        algorithm.name), _Reasons.UNSUPPORTED_HASH)
            key_ptr = self._backend._ffi.from_buffer(key)
            res = self._backend._lib.HMAC_Init_ex(ctx, key_ptr, len(key),
                                                  evp_md,
                                                  self._backend._ffi.NULL)
            self._backend.openssl_assert(res != 0)

        self._ctx = ctx
        self._key = key
def load_ssh_public_key(data, backend):
    key_parts = data.split(b' ')

    if len(key_parts) != 2 and len(key_parts) != 3:
        raise ValueError(
            'Key is not in the proper format or contains extra data.')

    key_type = key_parts[0]
    key_body = key_parts[1]

    try:
        decoded_data = base64.b64decode(key_body)
    except TypeError:
        raise ValueError('Key is not in the proper format.')

    if key_type == b'ssh-rsa':
        return _load_ssh_rsa_public_key(decoded_data, backend)
    elif key_type == b'ssh-dss':
        return _load_ssh_dss_public_key(decoded_data, backend)
    else:
        raise UnsupportedAlgorithm(
            'Only RSA and DSA keys are currently supported.')
Exemple #11
0
    def __init__(self,
                 key: bytes,
                 algorithm: hashes.HashAlgorithm,
                 backend=None,
                 ctx=None):
        backend = _get_backend(backend)
        if not isinstance(backend, HMACBackend):
            raise UnsupportedAlgorithm(
                "Backend object does not implement HMACBackend.",
                _Reasons.BACKEND_MISSING_INTERFACE,
            )

        if not isinstance(algorithm, hashes.HashAlgorithm):
            raise TypeError("Expected instance of hashes.HashAlgorithm.")
        self._algorithm = algorithm

        self._backend = backend
        self._key = key
        if ctx is None:
            self._ctx = self._backend.create_hmac_ctx(key, self.algorithm)
        else:
            self._ctx = ctx
Exemple #12
0
    def __init__(
        self,
        backend: "Backend",
        algorithm: "ciphers.BlockCipherAlgorithm",
        ctx=None,
    ) -> None:
        if not backend.cmac_algorithm_supported(algorithm):
            raise UnsupportedAlgorithm(
                "This backend does not support CMAC.",
                _Reasons.UNSUPPORTED_CIPHER,
            )

        self._backend = backend
        self._key = algorithm.key
        self._algorithm = algorithm
        self._output_length = algorithm.block_size // 8

        if ctx is None:
            registry = self._backend._cipher_registry
            adapter = registry[type(algorithm), CBC]

            evp_cipher = adapter(self._backend, algorithm, CBC)

            ctx = self._backend._lib.CMAC_CTX_new()

            self._backend.openssl_assert(ctx != self._backend._ffi.NULL)
            ctx = self._backend._ffi.gc(ctx, self._backend._lib.CMAC_CTX_free)

            key_ptr = self._backend._ffi.from_buffer(self._key)
            res = self._backend._lib.CMAC_Init(
                ctx,
                key_ptr,
                len(self._key),
                evp_cipher,
                self._backend._ffi.NULL,
            )
            self._backend.openssl_assert(res == 1)

        self._ctx = ctx
Exemple #13
0
    def __init__(self, key, length, algorithm, backend):
        if not isinstance(backend, HMACBackend):
            raise UnsupportedAlgorithm(
                "Backend object does not implement HMACBackend.",
                _Reasons.BACKEND_MISSING_INTERFACE)

        if len(key) < 16:
            raise ValueError("Key length has to be at least 128 bits.")

        if not isinstance(length, six.integer_types):
            raise TypeError("Length parameter must be an integer type.")

        if length < 6 or length > 8:
            raise ValueError("Length of HOTP has to be between 6 to 8.")

        if not isinstance(algorithm, (SHA1, SHA256, SHA512)):
            raise TypeError("Algorithm must be SHA1, SHA256 or SHA512.")

        self._key = key
        self._length = length
        self._algorithm = algorithm
        self._backend = backend
Exemple #14
0
    def __init__(
        self,
        algorithm: CipherAlgorithm,
        mode: typing.Optional[modes.Mode],
        backend=None,
    ):
        backend = _get_backend(backend)
        if not isinstance(backend, CipherBackend):
            raise UnsupportedAlgorithm(
                "Backend object does not implement CipherBackend.",
                _Reasons.BACKEND_MISSING_INTERFACE,
            )

        if not isinstance(algorithm, CipherAlgorithm):
            raise TypeError("Expected interface of CipherAlgorithm.")

        if mode is not None:
            mode.validate_for_algorithm(algorithm)

        self.algorithm = algorithm
        self.mode = mode
        self._backend = backend
    def __init__(
        self,
        algorithm: ciphers.BlockCipherAlgorithm,
        backend: typing.Optional[Backend] = None,
        ctx=None,
    ):
        backend = _get_backend(backend)
        if not isinstance(backend, CMACBackend):
            raise UnsupportedAlgorithm(
                "Backend object does not implement CMACBackend.",
                _Reasons.BACKEND_MISSING_INTERFACE,
            )

        if not isinstance(algorithm, ciphers.BlockCipherAlgorithm):
            raise TypeError("Expected instance of BlockCipherAlgorithm.")
        self._algorithm = algorithm

        self._backend = backend
        if ctx is None:
            self._ctx = self._backend.create_cmac_ctx(self._algorithm)
        else:
            self._ctx = ctx
Exemple #16
0
    def __init__(self, algorithm, length, salt, otherinfo, backend):

        _common_args_checks(algorithm, length, otherinfo)
        self._algorithm = algorithm
        self._length = length
        self._otherinfo = otherinfo
        if self._otherinfo is None:
            self._otherinfo = b""

        if salt is None:
            salt = b"\x00" * algorithm.block_size
        else:
            utils._check_bytes("salt", salt)

        self._salt = salt

        if not isinstance(backend, HMACBackend):
            raise UnsupportedAlgorithm(
                "Backend object does not implement HMACBackend.",
                _Reasons.BACKEND_MISSING_INTERFACE)
        self._backend = backend
        self._used = False
Exemple #17
0
    def __init__(self, backend, cipher, mode, operation):
        self._backend = backend
        self._cipher = cipher
        self._mode = mode
        self._operation = operation
        self._tag = None

        registry = self._backend._cipher_registry
        try:
            cipher_enum, mode_enum = registry[type(cipher), type(mode)]
        except KeyError:
            raise UnsupportedAlgorithm(
                "cipher {0} in {1} mode is not supported "
                "by this backend.".format(
                    cipher.name, mode.name if mode else mode),
                _Reasons.UNSUPPORTED_CIPHER
            )

        ctx = self._backend._ffi.new("CCCryptorRef *")
        ctx = self._backend._ffi.gc(ctx, self._backend._release_cipher_ctx)

        self._ctx = ctx

        res = self._backend._lib.CCCryptorCreateWithMode(
            operation,
            mode_enum, cipher_enum,
            self._backend._lib.ccNoPadding,
            self._backend._ffi.NULL,
            cipher.key, len(cipher.key),
            self._backend._ffi.NULL, 0, 0, 0, self._ctx)
        self._backend._check_cipher_response(res)

        res = self._backend._lib.CCCryptorGCMAddIV(
            self._ctx[0],
            mode.initialization_vector,
            len(mode.initialization_vector)
        )
        self._backend._check_cipher_response(res)
Exemple #18
0
    def __init__(self, backend, cipher, mode, operation):
        self._backend = backend
        self._cipher = cipher
        self._mode = mode
        self._operation = operation
        self._tag = None

        registry = self._backend._cipher_registry
        try:
            cipher_enum, mode_enum = registry[type(cipher), type(mode)]
        except KeyError:
            raise UnsupportedAlgorithm(
                "cipher {0} in {1} mode is not supported "
                "by this backend.".format(cipher.name,
                                          mode.name if mode else mode),
                _Reasons.UNSUPPORTED_CIPHER)

        ctx = self._backend._ffi.new("CCCryptorRef *")
        ctx = self._backend._ffi.gc(ctx, self._backend._release_cipher_ctx)

        self._ctx = ctx

        res = self._backend._lib.CCCryptorCreateWithMode(
            operation, mode_enum, cipher_enum, self._backend._lib.ccNoPadding,
            self._backend._ffi.NULL, cipher.key, len(cipher.key),
            self._backend._ffi.NULL, 0, 0, 0, self._ctx)
        self._backend._check_cipher_response(res)

        res = self._backend._lib.CCCryptorGCMAddIV(
            self._ctx[0], mode.initialization_vector,
            len(mode.initialization_vector))
        self._backend._check_cipher_response(res)
        # CommonCrypto has a bug where calling update without at least one
        # call to authenticate_additional_data will result in null byte output
        # for ciphertext. The following empty byte string call prevents the
        # issue, which is present in at least 10.8 and 10.9.
        # Filed as rdar://18314544
        self.authenticate_additional_data(b"")
Exemple #19
0
    def parameter_bytes(
        self,
        encoding: serialization.Encoding,
        format: serialization.ParameterFormat,
    ) -> bytes:
        if encoding is serialization.Encoding.OpenSSH:
            raise TypeError("OpenSSH encoding is not supported")

        if format is not serialization.ParameterFormat.PKCS3:
            raise ValueError("Only PKCS3 serialization is supported")

        q = self._backend._ffi.new("BIGNUM **")
        self._backend._lib.DH_get0_pqg(self._dh_cdata, self._backend._ffi.NULL,
                                       q, self._backend._ffi.NULL)
        if (q[0] != self._backend._ffi.NULL
                and not self._backend._lib.Cryptography_HAS_EVP_PKEY_DHX):
            raise UnsupportedAlgorithm(
                "DH X9.42 serialization is not supported",
                _Reasons.UNSUPPORTED_SERIALIZATION,
            )

        if encoding is serialization.Encoding.PEM:
            if q[0] != self._backend._ffi.NULL:
                write_bio = self._backend._lib.PEM_write_bio_DHxparams
            else:
                write_bio = self._backend._lib.PEM_write_bio_DHparams
        elif encoding is serialization.Encoding.DER:
            if q[0] != self._backend._ffi.NULL:
                write_bio = self._backend._lib.Cryptography_i2d_DHxparams_bio
            else:
                write_bio = self._backend._lib.i2d_DHparams_bio
        else:
            raise TypeError("encoding must be an item from the Encoding enum")

        bio = self._backend._create_mem_bio_gc()
        res = write_bio(bio, self._dh_cdata)
        self._backend.openssl_assert(res == 1)
        return self._backend._read_mem_bio(bio)
Exemple #20
0
def load_ssh_public_key(data, backend):
    key_parts = data.split(b' ', 2)

    if len(key_parts) < 2:
        raise ValueError(
            'Key is not in the proper format or contains extra table_s.')

    key_type = key_parts[0]

    if key_type == b'ssh-rsa':
        loader = _load_ssh_rsa_public_key
    elif key_type == b'ssh-dss':
        loader = _load_ssh_dss_public_key
    elif key_type in [
            b'ecdsa-sha2-nistp256',
            b'ecdsa-sha2-nistp384',
            b'ecdsa-sha2-nistp521',
    ]:
        loader = _load_ssh_ecdsa_public_key
    elif key_type == b'ssh-ed25519':
        loader = _load_ssh_ed25519_public_key
    else:
        raise UnsupportedAlgorithm('Key type is not supported.')

    key_body = key_parts[1]

    try:
        decoded_data = base64.b64decode(key_body)
    except TypeError:
        raise ValueError('Key is not in the proper format.')

    inner_key_type, rest = _ssh_read_next_string(decoded_data)

    if inner_key_type != key_type:
        raise ValueError(
            'Key header and key body contain different key type values.')

    return loader(key_type, rest, backend)
Exemple #21
0
    def generate_elliptic_curve_private_key(self, curve):
        """
        Generate a new private key on the named curve.
        """

        if self.elliptic_curve_supported(curve):
            curve_nid = self._elliptic_curve_to_nid(curve)

            ctx = self._lib.EC_KEY_new_by_curve_name(curve_nid)
            assert ctx != self._ffi.NULL
            ctx = self._ffi.gc(ctx, self._lib.EC_KEY_free)

            res = self._lib.EC_KEY_generate_key(ctx)
            assert res == 1

            res = self._lib.EC_KEY_check_key(ctx)
            assert res == 1

            return _EllipticCurvePrivateKey(self, ctx, curve)
        else:
            raise UnsupportedAlgorithm(
                "Backend object does not support {0}.".format(curve.name),
                _Reasons.UNSUPPORTED_ELLIPTIC_CURVE)
Exemple #22
0
    def derive_pbkdf2_hmac(self, algorithm, length, salt, iterations,
                           key_material):
        buf = self._ffi.new("char[]", length)
        if self._lib.Cryptography_HAS_PBKDF2_HMAC:
            evp_md = self._lib.EVP_get_digestbyname(
                algorithm.name.encode("ascii"))
            assert evp_md != self._ffi.NULL
            res = self._lib.PKCS5_PBKDF2_HMAC(key_material, len(key_material),
                                              salt, len(salt), iterations,
                                              evp_md, length, buf)
            assert res == 1
        else:
            if not isinstance(algorithm, hashes.SHA1):
                raise UnsupportedAlgorithm(
                    "This version of OpenSSL only supports PBKDF2HMAC with "
                    "SHA1.", _Reasons.UNSUPPORTED_HASH)
            res = self._lib.PKCS5_PBKDF2_HMAC_SHA1(key_material,
                                                   len(key_material), salt,
                                                   len(salt), iterations,
                                                   length, buf)
            assert res == 1

        return self._ffi.buffer(buf)[:]
Exemple #23
0
    def private_bytes(self, encoding, format, encryption_algorithm):
        if format is not serialization.PrivateFormat.PKCS8:
            raise ValueError(
                "DH private keys support only PKCS8 serialization"
            )
        if not self._backend._lib.Cryptography_HAS_EVP_PKEY_DHX:
            q = self._backend._ffi.new("BIGNUM **")
            self._backend._lib.DH_get0_pqg(self._dh_cdata,
                                           self._backend._ffi.NULL,
                                           q,
                                           self._backend._ffi.NULL)
            if q[0] != self._backend._ffi.NULL:
                raise UnsupportedAlgorithm(
                    "DH X9.42 serialization is not supported",
                    _Reasons.UNSUPPORTED_SERIALIZATION)

        return self._backend._private_key_bytes(
            encoding,
            format,
            encryption_algorithm,
            self._evp_pkey,
            self._dh_cdata
        )
Exemple #24
0
    def exchange(self, algorithm, peer_public_key):
        if not (self._backend.elliptic_curve_exchange_algorithm_supported(
                algorithm, self.curve)):
            raise UnsupportedAlgorithm(
                "This backend does not support the ECDH algorithm.",
                _Reasons.UNSUPPORTED_EXCHANGE_ALGORITHM)

        if peer_public_key.curve.name != self.curve.name:
            raise ValueError(
                "peer_public_key and self are not on the same curve")

        group = self._backend._lib.EC_KEY_get0_group(self._ec_key)
        z_len = (self._backend._lib.EC_GROUP_get_degree(group) + 7) // 8
        self._backend.openssl_assert(z_len > 0)
        z_buf = self._backend._ffi.new("uint8_t[]", z_len)
        peer_key = self._backend._lib.EC_KEY_get0_public_key(
            peer_public_key._ec_key)

        r = self._backend._lib.ECDH_compute_key(z_buf, z_len, peer_key,
                                                self._ec_key,
                                                self._backend._ffi.NULL)
        self._backend.openssl_assert(r > 0)
        return self._backend._ffi.buffer(z_buf)[:z_len]
Exemple #25
0
    def __init__(
        self,
        algorithm: HashAlgorithm,
        backend: typing.Optional[Backend] = None,
        ctx: typing.Optional["HashContext"] = None,
    ):
        backend = _get_backend(backend)
        if not isinstance(backend, HashBackend):
            raise UnsupportedAlgorithm(
                "Backend object does not implement HashBackend.",
                _Reasons.BACKEND_MISSING_INTERFACE,
            )

        if not isinstance(algorithm, HashAlgorithm):
            raise TypeError("Expected instance of hashes.HashAlgorithm.")
        self._algorithm = algorithm

        self._backend = backend

        if ctx is None:
            self._ctx = self._backend.create_hash_ctx(self.algorithm)
        else:
            self._ctx = ctx
    def __init__(self, salt, length, n, r, p, backend):
        if not isinstance(backend, ScryptBackend):
            raise UnsupportedAlgorithm(
                "Backend object does not implement ScryptBackend.",
                _Reasons.BACKEND_MISSING_INTERFACE)

        self._length = length
        utils._check_bytes("salt", salt)
        if n < 2 or (n & (n - 1)) != 0:
            raise ValueError("n must be greater than 1 and be a power of 2.")

        if r < 1:
            raise ValueError("r must be greater than or equal to 1.")

        if p < 1:
            raise ValueError("p must be greater than or equal to 1.")

        self._used = False
        self._salt = salt
        self._n = n
        self._r = r
        self._p = p
        self._backend = backend
Exemple #27
0
    def __init__(self, algorithm, length, salt, info, backend):
        if not isinstance(backend, HMACBackend):
            raise UnsupportedAlgorithm(
                "Backend object does not implement HMACBackend",
                _Reasons.BACKEND_MISSING_INTERFACE)

        self._algorithm = algorithm

        max_length = 255 * (algorithm.digest_size // 8)

        if length > max_length:
            raise ValueError(
                "Can not derive keys larger than {0} octets.".format(
                    max_length))

        self._length = length

        if isinstance(salt, six.text_type):
            raise TypeError(
                "Unicode-objects must be encoded before using them as a salt.")

        if salt is None:
            salt = b"\x00" * (self._algorithm.digest_size // 8)

        self._salt = salt

        if isinstance(info, six.text_type):
            raise TypeError(
                "Unicode-objects must be encoded before using them as info.")

        if info is None:
            info = b""

        self._info = info
        self._backend = backend

        self._used = False
Exemple #28
0
    def __init__(self, backend, key, algorithm, ctx=None):
        self.algorithm = algorithm
        self._backend = backend

        if ctx is None:
            ctx = self._backend._ffi.new("HMAC_CTX *")
            self._backend._lib.HMAC_CTX_init(ctx)
            ctx = self._backend._ffi.gc(
                ctx, self._backend._lib.HMAC_CTX_cleanup
            )
            evp_md = self._backend._lib.EVP_get_digestbyname(
                algorithm.name.encode('ascii'))
            if evp_md == self._backend._ffi.NULL:
                raise UnsupportedAlgorithm(
                    "{0} is not a supported hash on this backend".format(
                        algorithm.name)
                )
            res = self._backend._lib.Cryptography_HMAC_Init_ex(
                ctx, key, len(key), evp_md, self._backend._ffi.NULL
            )
            assert res != 0

        self._ctx = ctx
        self._key = key
Exemple #29
0
    def from_pem(cls, pem: bytes) -> RSAKeyPair:
        """Import an RSA key pair from a PEM-encoded private key.

        Parameters
        ----------
        pem : `bytes`
            The PEM-encoded key (must not be password-protected).

        Returns
        -------
        keypair : `RSAKeyPair`
            The corresponding key pair.

        Raises
        ------
        cryptography.exceptions.UnsupportedAlgorithm
            The provided key is not an RSA private key.
        """
        private_key = load_pem_private_key(
            pem, password=None, backend=default_backend()
        )
        if not isinstance(private_key, rsa.RSAPrivateKeyWithSerialization):
            raise UnsupportedAlgorithm("Key is not an RSA private key")
        return cls(private_key)
Exemple #30
0
def load_ssh_private_key(data, password, backend):
    """Load private key from OpenSSH custom encoding.
    """
    utils._check_byteslike("data", data)
    if password is not None:
        utils._check_bytes("password", password)

    m = _PEM_RC.search(data)
    if not m:
        raise ValueError("Not OpenSSH private key format")
    p1 = m.start(1)
    p2 = m.end(1)
    data = binascii.a2b_base64(memoryview(data)[p1:p2])
    if not data.startswith(_SK_MAGIC):
        raise ValueError("Not OpenSSH private key format")
    data = memoryview(data)[len(_SK_MAGIC):]

    # parse header
    ciphername, data = _get_sshstr(data)
    kdfname, data = _get_sshstr(data)
    kdfoptions, data = _get_sshstr(data)
    nkeys, data = _get_u32(data)
    if nkeys != 1:
        raise ValueError("Only one key supported")

    # load public key data
    pubdata, data = _get_sshstr(data)
    pub_key_type, pubdata = _get_sshstr(pubdata)
    kformat = _lookup_kformat(pub_key_type)
    pubfields, pubdata = kformat.get_public(pubdata)
    _check_empty(pubdata)

    # load secret data
    edata, data = _get_sshstr(data)
    _check_empty(data)

    if (ciphername, kdfname) != (_NONE, _NONE):
        ciphername = ciphername.tobytes()
        if ciphername not in _SSH_CIPHERS:
            raise UnsupportedAlgorithm("Unsupported cipher: %r" % ciphername)
        if kdfname != _BCRYPT:
            raise UnsupportedAlgorithm("Unsupported KDF: %r" % kdfname)
        blklen = _SSH_CIPHERS[ciphername][3]
        _check_block_size(edata, blklen)
        salt, kbuf = _get_sshstr(kdfoptions)
        rounds, kbuf = _get_u32(kbuf)
        _check_empty(kbuf)
        ciph = _init_cipher(ciphername, password, salt.tobytes(), rounds,
                            backend)
        edata = memoryview(ciph.decryptor().update(edata))
    else:
        blklen = 8
        _check_block_size(edata, blklen)
    ck1, edata = _get_u32(edata)
    ck2, edata = _get_u32(edata)
    if ck1 != ck2:
        raise ValueError("Corrupt data: broken checksum")

    # load per-key struct
    key_type, edata = _get_sshstr(edata)
    if key_type != pub_key_type:
        raise ValueError("Corrupt data: key type mismatch")
    private_key, edata = kformat.load_private(edata, pubfields, backend)
    comment, edata = _get_sshstr(edata)

    # yes, SSH does padding check *after* all other parsing is done.
    # need to follow as it writes zero-byte padding too.
    if edata != _PADDING[:len(edata)]:
        raise ValueError("Corrupt data: invalid padding")

    return private_key