Example #1
0
    def generate_key(self,
                     slot,
                     algorithm,
                     pin_policy=PIN_POLICY.DEFAULT,
                     touch_policy=TOUCH_POLICY.DEFAULT):

        if ALGO.is_rsa(algorithm):
            ensure_not_cve201715361_vulnerable_firmware_version(self.version)

        if algorithm not in self.supported_algorithms:
            raise UnsupportedAlgorithm(
                'Algorithm not supported on this YubiKey: {}'.format(
                    algorithm),
                algorithm_id=algorithm)

        data = Tlv(TAG.ALGO, six.int2byte(algorithm))
        if pin_policy:
            data += Tlv(TAG.PIN_POLICY, six.int2byte(pin_policy))
        if touch_policy:
            data += Tlv(TAG.TOUCH_POLICY, six.int2byte(touch_policy))
        data = Tlv(0xac, data)
        resp = self.send_cmd(INS.GENERATE_ASYMMETRIC, 0, slot, data)
        if algorithm in [ALGO.RSA1024, ALGO.RSA2048]:
            data = _parse_tlv_dict(Tlv(resp[1:]).value)
            return rsa.RSAPublicNumbers(int_from_bytes(data[0x82], 'big'),
                                        int_from_bytes(data[0x81],
                                                       'big')).public_key(
                                                           default_backend())
        elif algorithm in [ALGO.ECCP256, ALGO.ECCP384]:
            curve = ec.SECP256R1 if algorithm == ALGO.ECCP256 else ec.SECP384R1
            return ec.EllipticCurvePublicNumbers.from_encoded_point(
                curve(), resp[5:]).public_key(default_backend())

        raise UnsupportedAlgorithm('Invalid algorithm: {}'.format(algorithm),
                                   algorithm_id=algorithm)
def _load_ssh_ecdsa_public_key(expected_key_type, decoded_data, backend):
    curve_name, rest = _read_next_string(decoded_data)
    data, rest = _read_next_string(rest)

    if expected_key_type != b"ecdsa-sha2-" + curve_name:
        raise ValueError(
            'Key header and key body contain different key type values.')

    if rest:
        raise ValueError('Key body contains extra bytes.')

    curve = {
        b"nistp256": ec.SECP256R1,
        b"nistp384": ec.SECP384R1,
        b"nistp521": ec.SECP521R1,
    }[curve_name]()

    if six.indexbytes(data, 0) != 4:
        raise NotImplementedError(
            "Compressed elliptic curve points are not supported")

    # key_size is in bits, and sometimes it's not evenly divisible by 8, so we
    # add 7 to round up the number of bytes.
    if len(data) != 1 + 2 * ((curve.key_size + 7) // 8):
        raise ValueError("Malformed key bytes")

    x = utils.int_from_bytes(data[1:1 + (curve.key_size + 7) // 8],
                             byteorder='big')
    y = utils.int_from_bytes(data[1 + (curve.key_size + 7) // 8:],
                             byteorder='big')
    return ec.EllipticCurvePublicNumbers(x, y, curve).public_key(backend)
Example #3
0
    def generate_rsa_key(self, key_slot, key_size, timestamp=None):
        """Requires Admin PIN verification."""
        ensure_not_cve201715361_vulnerable_firmware_version(self.version)

        if timestamp is None:
            timestamp = int(time.time())

        neo = self.version < (4, 0, 0)
        if not neo:
            attributes = _format_rsa_attributes(key_size)
            self._put_data(key_slot.key_id, attributes)
        elif key_size != 2048:
            raise ValueError('Unsupported key size!')
        resp = self.send_cmd(0, INS.GENERATE_ASYM, 0x80, 0x00, key_slot.crt)

        data = Tlv.parse_dict(Tlv.unpack(0x7f49, resp))
        numbers = rsa.RSAPublicNumbers(
            int_from_bytes(data[0x82], 'big'),
            int_from_bytes(data[0x81], 'big')
        )

        self._put_data(key_slot.gen_time, struct.pack('>I', timestamp))
        # TODO: Calculate and write fingerprint

        return numbers.public_key(default_backend())
Example #4
0
def _load_ssh_ecdsa_public_key(expected_key_type, decoded_data, backend):
    curve_name, rest = _read_next_string(decoded_data)
    data, rest = _read_next_string(rest)

    if expected_key_type != b"ecdsa-sha2-" + curve_name:
        raise ValueError(
            'Key header and key body contain different key type values.'
        )

    if rest:
        raise ValueError('Key body contains extra bytes.')

    curve = {
        b"nistp256": ec.SECP256R1,
        b"nistp384": ec.SECP384R1,
        b"nistp521": ec.SECP521R1,
    }[curve_name]()

    if six.indexbytes(data, 0) != 4:
        raise NotImplementedError(
            "Compressed elliptic curve points are not supported"
        )

    # key_size is in bits, and sometimes it's not evenly divisible by 8, so we
    # add 7 to round up the number of bytes.
    if len(data) != 1 + 2 * ((curve.key_size + 7) // 8):
        raise ValueError("Malformed key bytes")

    x = utils.int_from_bytes(
        data[1:1 + (curve.key_size + 7) // 8], byteorder='big'
    )
    y = utils.int_from_bytes(
        data[1 + (curve.key_size + 7) // 8:], byteorder='big'
    )
    return ec.EllipticCurvePublicNumbers(x, y, curve).public_key(backend)
Example #5
0
def _get_e_n(backend, handle):
        # TODO: These buffers could be dynamically sized in the future, but
        # it would require two calls to the PKCS11 layer. Right now it will
        # work with a single call as long as the key is 8192-bit or smaller and
        # the modulus isn't some ludicrous value.
        attrs = build_attributes([
            (
                backend._binding.CKA_MODULUS,
                backend._ffi.new("unsigned char[]", 1024)
            ),
            (
                backend._binding.CKA_PUBLIC_EXPONENT,
                backend._ffi.new("unsigned char[]", 64)
            ),
        ], backend)
        session = backend._session_pool.acquire()
        res = backend._lib.C_GetAttributeValue(
            session[0], handle, attrs.template, len(attrs.template)
        )
        backend._check_error(res)
        n = utils.int_from_bytes(
            backend._ffi.buffer(
                attrs.template[0].value, attrs.template[0].value_len
            )[:],
            'big'
        )
        e = utils.int_from_bytes(
            backend._ffi.buffer(
                attrs.template[1].value, attrs.template[1].value_len
            )[:],
            'big'
        )

        return e, n
Example #6
0
    def generate_key(self, slot, algorithm, pin_policy=PIN_POLICY.DEFAULT,
                     touch_policy=TOUCH_POLICY.DEFAULT):

        if ALGO.is_rsa(algorithm):
            ensure_not_cve201715361_vulnerable_firmware_version(self.version)

        if algorithm not in self.supported_algorithms:
            raise UnsupportedAlgorithm(
                'Algorithm not supported on this YubiKey: {}'
                .format(algorithm),
                algorithm_id=algorithm)

        data = Tlv(TAG.ALGO, six.int2byte(algorithm))
        if pin_policy:
            data += Tlv(TAG.PIN_POLICY, six.int2byte(pin_policy))
        if touch_policy:
            data += Tlv(TAG.TOUCH_POLICY, six.int2byte(touch_policy))
        data = Tlv(0xac, data)
        resp = self.send_cmd(INS.GENERATE_ASYMMETRIC, 0, slot, data)
        if algorithm in [ALGO.RSA1024, ALGO.RSA2048]:
            data = _parse_tlv_dict(Tlv(resp[1:]).value)
            return rsa.RSAPublicNumbers(
                int_from_bytes(data[0x82], 'big'),
                int_from_bytes(data[0x81], 'big')
            ).public_key(default_backend())
        elif algorithm in [ALGO.ECCP256, ALGO.ECCP384]:
            curve = ec.SECP256R1 if algorithm == ALGO.ECCP256 else ec.SECP384R1
            return ec.EllipticCurvePublicNumbers.from_encoded_point(
                curve(),
                resp[5:]
            ).public_key(default_backend())

        raise UnsupportedAlgorithm(
            'Invalid algorithm: {}'.format(algorithm),
            algorithm_id=algorithm)
Example #7
0
    def get_public_key(self):
        """Get the public key of the key pair.

        This will return either a
        :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey`
        or a
        :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`
        depending on the algorithm of the key.

        Ed25519 keys use an internal representation which can be serialized
        using the :func:`~yubihsm.eddsa.serialize_ed25519_public_key` function.

        :return: The public key of the key pair.
        """
        msg = struct.pack('!H', self.id)
        ret = self.session.send_secure_cmd(COMMAND.GET_PUBLIC_KEY, msg)
        algo = ALGORITHM(six.indexbytes(ret, 0))
        raw_key = ret[1:]
        if algo in [ALGORITHM.RSA_2048, ALGORITHM.RSA_3072, ALGORITHM.RSA_4096]:
            num = int_from_bytes(raw_key, 'big')
            pubkey = rsa.RSAPublicNumbers(e=0x10001, n=num)
        elif algo in [
            ALGORITHM.EC_P224, ALGORITHM.EC_P256, ALGORITHM.EC_P384,
            ALGORITHM.EC_P521, ALGORITHM.EC_K256, ALGORITHM.EC_BP256,
            ALGORITHM.EC_BP384, ALGORITHM.EC_BP512
        ]:
            c_len = len(raw_key) // 2
            x = int_from_bytes(raw_key[:c_len], 'big')
            y = int_from_bytes(raw_key[c_len:], 'big')
            pubkey = ec.EllipticCurvePublicNumbers(
                curve=algo.to_curve(), x=x, y=y)
        elif algo in [ALGORITHM.EC_ED25519]:
            return _Ed25519PublicKey(raw_key)

        return pubkey.public_key(backend=default_backend())
    def from_jwk(cls, jwk):
        """
        Create a :py:class:`~oneid.keychain.Keypair` from a JWK

        :param jwk: oneID-standard JWK
        :return: :py:class:`~oneid.keychain.Keypair` instance
        :raises InvalidFormatError: if not a valid JWK
        """
        if jwk['kty'] != 'EC' or jwk['crv'] != 'P-256':
            raise exceptions.InvalidFormatError

        public_numbers = ec.EllipticCurvePublicNumbers(
            x=int_from_bytes(utils.base64url_decode(jwk['x']), 'big'),
            y=int_from_bytes(utils.base64url_decode(jwk['y']), 'big'),
            curve=ec.SECP256R1(),
        )

        ret = cls()
        ret._public_key = public_numbers.public_key(_BACKEND)

        if 'd' in jwk:
            private_numbers = ec.EllipticCurvePrivateNumbers(
                private_value=int_from_bytes(utils.base64url_decode(jwk['d']), 'big'),
                public_numbers=public_numbers,
            )
            ret._private_key = private_numbers.private_key(_BACKEND)

        if 'kid' in jwk:
            ret.identity = jwk['kid']

        return ret
Example #9
0
        def from_jwk(jwk):

            try:
                obj = json.loads(jwk)
            except ValueError:
                raise InvalidKeyError("Key is not valid JSON")

            if obj.get("kty") != "EC":
                raise InvalidKeyError("Not an Elliptic curve key")

            if "x" not in obj or "y" not in obj:
                raise InvalidKeyError("Not an Elliptic curve key")

            x = base64url_decode(force_bytes(obj.get("x")))
            y = base64url_decode(force_bytes(obj.get("y")))

            curve = obj.get("crv")
            if curve == "P-256":
                if len(x) == len(y) == 32:
                    curve_obj = ec.SECP256R1()
                else:
                    raise InvalidKeyError(
                        "Coords should be 32 bytes for curve P-256"
                    )
            elif curve == "P-384":
                if len(x) == len(y) == 48:
                    curve_obj = ec.SECP384R1()
                else:
                    raise InvalidKeyError(
                        "Coords should be 48 bytes for curve P-384"
                    )
            elif curve == "P-521":
                if len(x) == len(y) == 66:
                    curve_obj = ec.SECP521R1()
                else:
                    raise InvalidKeyError(
                        "Coords should be 66 bytes for curve P-521"
                    )
            else:
                raise InvalidKeyError("Invalid curve: {}".format(curve))

            public_numbers = ec.EllipticCurvePublicNumbers(
                x=int_from_bytes(x, "big"),
                y=int_from_bytes(y, "big"),
                curve=curve_obj,
            )

            if "d" not in obj:
                return public_numbers.public_key()

            d = base64url_decode(force_bytes(obj.get("d")))
            if len(d) != len(x):
                raise InvalidKeyError(
                    "D should be {} bytes for curve {}", len(x), curve
                )

            return ec.EllipticCurvePrivateNumbers(
                int_from_bytes(d, "big"), public_numbers
            ).private_key()
Example #10
0
    def __init__(self):
        if CRYPTOGRAPHY_MISSING:
            self.active = False
        else:

            self.DH_PRIME_1024 = int_from_bytes(self.DH_PRIME_1024_BYTES,
                                                'big')

            self.pkey = int_from_bytes(os.urandom(128), 'big')
            self.pubkey = pow(2, self.pkey, self.DH_PRIME_1024)
    def _raw_to_der(self, raw_signature):
        """Convert signature from RAW encoding to DER encoding."""
        component_length = self._sig_component_length()
        if len(raw_signature) != int(2 * component_length):
            raise ValueError("Invalid signature")

        r_bytes = raw_signature[:component_length]
        s_bytes = raw_signature[component_length:]
        r = int_from_bytes(r_bytes, "big")
        s = int_from_bytes(s_bytes, "big")
        return encode_dss_signature(r, s)
    def _raw_to_der(self, raw_signature):
        """Convert signature from RAW encoding to DER encoding."""
        component_length = self._sig_component_length()
        if len(raw_signature) != int(2 * component_length):
            raise ValueError("Invalid signature")

        r_bytes = raw_signature[:component_length]
        s_bytes = raw_signature[component_length:]
        r = int_from_bytes(r_bytes, "big")
        s = int_from_bytes(s_bytes, "big")
        return encode_dss_signature(r, s)
Example #13
0
    def _split_raw_signature(sig):
        """
        Split raw signature into components

        :param sig: The signature
        :return: A 2-tuple
        """
        c_length = len(sig) // 2
        r = int_from_bytes(sig[:c_length], byteorder="big")
        s = int_from_bytes(sig[c_length:], byteorder="big")
        return r, s
Example #14
0
        def from_jwk(jwk):

            try:
                obj = json.loads(jwk)
            except ValueError:
                raise InvalidKeyError('Key is not valid JSON')

            if obj.get('kty') != 'EC':
                raise InvalidKeyError('Not an Elliptic curve key')

            if 'x' not in obj or 'y' not in obj:
                raise InvalidKeyError('Not an Elliptic curve key')

            x = base64url_decode(force_bytes(obj.get('x')))
            y = base64url_decode(force_bytes(obj.get('y')))

            curve = obj.get('crv')
            if curve == 'P-256':
                if len(x) == len(y) == 32:
                    curve_obj = ec.SECP256R1()
                else:
                    raise InvalidKeyError(
                        "Coords should be 32 bytes for curve P-256")
            elif curve == 'P-384':
                if len(x) == len(y) == 48:
                    curve_obj = ec.SECP384R1()
                else:
                    raise InvalidKeyError(
                        "Coords should be 48 bytes for curve P-384")
            elif curve == 'P-521':
                if len(x) == len(y) == 66:
                    curve_obj = ec.SECP521R1()
                else:
                    raise InvalidKeyError(
                        "Coords should be 66 bytes for curve P-521")
            else:
                raise InvalidKeyError("Invalid curve: {}".format(curve))

            public_numbers = ec.EllipticCurvePublicNumbers(
                x=int_from_bytes(x, 'big'),
                y=int_from_bytes(y, 'big'),
                curve=curve_obj)

            if 'd' not in obj:
                return public_numbers.public_key(default_backend())

            d = base64url_decode(force_bytes(obj.get('d')))
            if len(d) != len(x):
                raise InvalidKeyError("D should be {} bytes for curve {}",
                                      len(x), curve)

            return ec.EllipticCurvePrivateNumbers(int_from_bytes(
                d, 'big'), public_numbers).private_key(default_backend())
Example #15
0
def _load_ecdsa(key, is_verifier):
    if key.get('kty') != 'EC':
        raise JWKError('Not an Elliptic curve key')

    if 'x' not in key or 'y' not in key:
        raise JWKError('Not an Elliptic curve key')

    x = base64.urlsafe_b64decode(key.get('x'))
    y = base64.urlsafe_b64decode(key.get('y'))

    curve = key.get('crv')
    if curve == 'P-256':
        if len(x) == len(y) == 32:
            alg = 'ES256'
            curve_obj = ec.SECP256R1()
        else:
            raise JWKError("Coords should be 32 bytes for curve P-256")
    elif curve == 'P-384':
        if len(x) == len(y) == 48:
            alg = "ES384"
            curve_obj = ec.SECP384R1()
        else:
            raise JWKError("Coords should be 48 bytes for curve P-384")
    elif curve == 'P-521':
        if len(x) == len(y) == 66:
            alg = "ES512"
            curve_obj = ec.SECP521R1()
        else:
            raise JWKError("Coords should be 66 bytes for curve P-521")
    else:
        raise JWKError("Invalid curve: {}".format(curve))

    public_numbers = ec.EllipticCurvePublicNumbers(x=int_from_bytes(x, 'big'),
                                                   y=int_from_bytes(y, 'big'),
                                                   curve=curve_obj)

    if not is_verifier:
        if 'd' not in key:
            raise JWKError("Signing ECDSA keys must contain private key")
        d = base64.urlsafe_b64decode(key.get('d'))
        if len(d) != len(x):
            raise JWKError("D should be {} bytes for curve {}", len(x), curve)

        key = ec.EllipticCurvePrivateNumbers(int_from_bytes(
            d, 'big'), public_numbers).private_key(default_backend())
    else:
        key = public_numbers.public_key(default_backend())

    return alg, key
    def verify(self, message, signature):
        # First convert (r||s) raw signature to ASN1 encoded signature.
        sig_bytes = _helpers.to_bytes(signature)
        if len(sig_bytes) != 64:
            return False
        r = utils.int_from_bytes(sig_bytes[:32], byteorder="big")
        s = utils.int_from_bytes(sig_bytes[32:], byteorder="big")
        asn1_sig = encode_dss_signature(r, s)

        message = _helpers.to_bytes(message)
        try:
            self._pubkey.verify(asn1_sig, message, ec.ECDSA(hashes.SHA256()))
            return True
        except (ValueError, cryptography.exceptions.InvalidSignature):
            return False
Example #17
0
    def from_encoded_point(cls, curve, data):
        if not isinstance(curve, EllipticCurve):
            raise TypeError("curve must be an EllipticCurve instance")

        if data.startswith(b'\x04'):
            # key_size is in bits. Convert to bytes and round up
            byte_length = (curve.key_size + 7) // 8
            if len(data) == 2 * byte_length + 1:
                x = utils.int_from_bytes(data[1:byte_length + 1], 'big')
                y = utils.int_from_bytes(data[byte_length + 1:], 'big')
                return cls(x, y, curve)
            else:
                raise ValueError('Invalid elliptic curve point data length')
        else:
            raise ValueError('Unsupported elliptic curve point type')
Example #18
0
    def test_dh_vectors_with_q(self, backend, vector):
        parameters = dh.DHParameterNumbers(
            int(vector["p"], 16), int(vector["g"], 16), int(vector["q"], 16)
        )
        public1 = dh.DHPublicNumbers(int(vector["ystatcavs"], 16), parameters)
        private1 = dh.DHPrivateNumbers(int(vector["xstatcavs"], 16), public1)
        public2 = dh.DHPublicNumbers(int(vector["ystatiut"], 16), parameters)
        private2 = dh.DHPrivateNumbers(int(vector["xstatiut"], 16), public2)
        key1 = private1.private_key(backend)
        key2 = private2.private_key(backend)
        symkey1 = key1.exchange(public2.public_key(backend))
        symkey2 = key2.exchange(public1.public_key(backend))

        assert int_from_bytes(symkey1, "big") == int(vector["z"], 16)
        assert int_from_bytes(symkey2, "big") == int(vector["z"], 16)
Example #19
0
    def from_encoded_point(cls, curve, data):
        if not isinstance(curve, EllipticCurve):
            raise TypeError("curve must be an EllipticCurve instance")

        if data.startswith(b'\x04'):
            # key_size is in bits. Convert to bytes and round up
            byte_length = (curve.key_size + 7) // 8
            if len(data) == 2 * byte_length + 1:
                x = utils.int_from_bytes(data[1:byte_length + 1], 'big')
                y = utils.int_from_bytes(data[byte_length + 1:], 'big')
                return cls(x, y, curve)
            else:
                raise ValueError('Invalid elliptic curve point data length')
        else:
            raise ValueError('Unsupported elliptic curve point type')
Example #20
0
    def test_dh_vectors_with_q(self, backend, vector):
        parameters = dh.DHParameterNumbers(int(vector["p"], 16),
                                           int(vector["g"], 16),
                                           int(vector["q"], 16))
        public1 = dh.DHPublicNumbers(int(vector["ystatcavs"], 16), parameters)
        private1 = dh.DHPrivateNumbers(int(vector["xstatcavs"], 16), public1)
        public2 = dh.DHPublicNumbers(int(vector["ystatiut"], 16), parameters)
        private2 = dh.DHPrivateNumbers(int(vector["xstatiut"], 16), public2)
        key1 = private1.private_key(backend)
        key2 = private2.private_key(backend)
        symkey1 = key1.exchange(public2.public_key(backend))
        symkey2 = key2.exchange(public1.public_key(backend))

        assert int_from_bytes(symkey1, 'big') == int(vector["z"], 16)
        assert int_from_bytes(symkey2, 'big') == int(vector["z"], 16)
Example #21
0
def generate_self_signed_certificate(common_name="Test",
                                     valid_from=None,
                                     valid_to=None):

    valid_from = valid_from if valid_from else datetime.datetime.utcnow()
    valid_to = valid_to if valid_to else valid_from + datetime.timedelta(
        days=1)

    private_key = _generate_private_key()
    public_key = private_key.public_key()

    builder = x509.CertificateBuilder()
    builder = builder.public_key(public_key)
    builder = builder.subject_name(
        x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, common_name)]))

    # Same as subject on self-signed certificates.
    builder = builder.issuer_name(
        x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, common_name)]))

    # x509.random_serial_number added in cryptography 1.6
    serial = int_from_bytes(os.urandom(20), "big") >> 1
    builder = builder.serial_number(serial)

    builder = builder.not_valid_before(valid_from)
    builder = builder.not_valid_after(valid_to)

    return _sign_cert(private_key, builder)
Example #22
0
 def __init__(self, private_key=None):
     '''
     takes in a b64 encoded string or standard text private key and returns a PrivateKey object
     '''
     if private_key:
         base64_data = False
         if isinstance(private_key, str):
             private_key = private_key.encode()
         try:
             data = base64.b64encode(base64.b64decode(private_key))
             if data == private_key:
                 private_key = base64.b64decode(data)
                 base64_data = True
         except binascii.Error:
             pass
         if isinstance(private_key, bytes) and not base64_data:
             self.key = sz.load_pem_private_key(private_key, None,
                                                default_backend())
         elif isinstance(private_key, bytes) and base64_data:
             data = utils.int_from_bytes(private_key, 'big')
             self.key = ec.derive_private_key(data, ec.SECP256R1(),
                                              default_backend())
     else:
         self.key = ec.generate_private_key(ec.SECP256R1(),
                                            default_backend())
     self._pub_key = PEMPublicKey(self.key.public_key())
Example #23
0
def dh_shared_secret(message: bytes, private_secret: dh.DHPublicNumbers) -> dh.DHPrivateNumbers:
    """
    Compute the shared secret from private secret and the other party's message.
    """
    gx  = utils.int_from_bytes(message, 'big')
    gxy = pow(gx, private_secret.y, private_secret.parameter_numbers.p)
    return dh.DHPrivateNumbers(gxy, private_secret)
Example #24
0
	def __init__(self) -> None:
		self.object_path = None  # type: Optional[str]
		self.aes_key = None  # type: Optional[bytes]
		self.encrypted = True
		# 128-bytes-long strong random number
		self.my_private_key = int_from_bytes(os.urandom(0x80), 'big')
		self.my_public_key = pow(2, self.my_private_key, DH_PRIME_1024)
Example #25
0
    def test_rsa_pkcs1_decrypt_errors(self):
        rawmessages = [
            # no actual padding bytes:
            b"\x00\x02\x00" + b"\xc3" * 236 + b"\x00",
            # first byte != 0x00:
            b"\x01\x02" + b"\xc3" * 237 + b"\x00",
            # second byte != 0x02:
            b"\x00\x01" + b"\xc3" * 237 + b"\x00",
            # only 7 bytes of padding:
            b"\x00\x02" + b"\xc3" * 7 + b"\x00" + b"\x3c" * 246,
        ]

        rsakey = rsa.generate_private_key(public_exponent=0x10001,
                                          key_size=2048,
                                          backend=default_backend())

        key = AsymmetricKey.put(self.session, 0, "pkcs1 test", 0xFFFF,
                                CAPABILITY.DECRYPT_PKCS, rsakey)

        numbers = key.get_public_key().public_numbers()

        for m in rawmessages:
            error = ERROR.OK
            m = m.ljust(256, b"\xc3")
            m_int = int_from_bytes(m, "big")
            enc = pow(m_int, numbers.e, numbers.n)
            try:
                key.decrypt_pkcs1v1_5(int_to_bytes(enc).rjust(256, b"\x00"))
            except YubiHsmDeviceError as e:
                error = e.code
            self.assertEqual(error, ERROR.INVALID_DATA)

        key.delete()
Example #26
0
def parse_ec_coordinate(cb64url, curve):
    curve_byte_len = (curve.bit_size() + 7) >> 3
    c_bytes = jose_base64_url_decode(cb64url)

    if len(c_bytes) != curve_byte_len:
        raise Exception("invalid number of octets: got %d, should be %d", len(c_bytes), curve_byte_len)
    return cry_utils.int_from_bytes(c_bytes, 'big')
Example #27
0
    def generate_self_signed_certificate(
            self, slot, public_key, common_name, valid_from, valid_to,
            touch_callback=None):

        algorithm = ALGO.from_public_key(public_key)

        builder = x509.CertificateBuilder()
        builder = builder.public_key(public_key)
        builder = builder.subject_name(
            x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, common_name), ]))

        # Same as subject on self-signed certificates.
        builder = builder.issuer_name(
            x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, common_name), ]))

        # x509.random_serial_number added in cryptography 1.6
        serial = int_from_bytes(os.urandom(20), 'big') >> 1
        builder = builder.serial_number(serial)

        builder = builder.not_valid_before(valid_from)
        builder = builder.not_valid_after(valid_to)

        try:
            cert = self.sign_cert_builder(
                slot, algorithm, builder, touch_callback)
        except APDUError as e:
            logger.error('Failed to generate certificate for slot %s', slot,
                         exc_info=e)
            raise

        self.import_certificate(slot, cert, verify=False)
def verify_host(digest, signature, public_key_data):
    """
    verify a signature using the host software
    """
    try:
        public_key_data = b'\x04' + public_key_data

        r = int_from_bytes(signature[0:32], byteorder='big', signed=False)
        s = int_from_bytes(signature[32:64], byteorder='big', signed=False)
        sig = utils.encode_dss_signature(r, s)
    
        public_key = ec.EllipticCurvePublicNumbers.from_encoded_point(ec.SECP256R1(), public_key_data).public_key(default_backend())
        public_key.verify(sig, digest, ec.ECDSA(utils.Prehashed(hashes.SHA256())))
        return True
    except InvalidSignature:
        return False
Example #29
0
    def generate_self_signed_certificate(
            self, slot, public_key, common_name, valid_from, valid_to,
            touch_callback=None):

        algorithm = ALGO.from_public_key(public_key)

        builder = x509.CertificateBuilder()
        builder = builder.public_key(public_key)
        builder = builder.subject_name(
            x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, common_name), ]))

        # Same as subject on self-signed certificates.
        builder = builder.issuer_name(
            x509.Name([x509.NameAttribute(NameOID.COMMON_NAME, common_name), ]))

        # x509.random_serial_number added in cryptography 1.6
        serial = int_from_bytes(os.urandom(20), 'big') >> 1
        builder = builder.serial_number(serial)

        builder = builder.not_valid_before(valid_from)
        builder = builder.not_valid_after(valid_to)

        try:
            cert = self.sign_cert_builder(
                slot, algorithm, builder, touch_callback)
        except APDUError as e:
            logger.error('Failed to generate certificate for slot %s', slot,
                         exc_info=e)
            raise

        self.import_certificate(slot, cert, verify=False)
Example #30
0
 def __init__(self):
     self.object_path = None
     self.server_public_key = None
     self.aes_key = None
     self.encrypted = True
     # 128-bytes-long strong random number
     self.my_private_key = int_from_bytes(os.urandom(0x80), 'big')
     self.my_public_key = pow(2, self.my_private_key, DH_PRIME_1024)
Example #31
0
def _unpad_message(padded, padding):
    e = 65537
    dummy = rsa.generate_private_key(e, len(padded) * 8, default_backend())
    # Raw (textbook) RSA encrypt
    n = dummy.public_key().public_numbers().n
    encrypted = int_to_bytes(pow(int_from_bytes(padded, "big"), e, n),
                             len(padded))
    return dummy.decrypt(encrypted, padding)
Example #32
0
    def test_dh_vectors(self, backend, vector):
        parameters = dh.DHParameterNumbers(int(vector["p"]), int(vector["g"]))
        public = dh.DHPublicNumbers(int(vector["y"]), parameters)
        private = dh.DHPrivateNumbers(int(vector["x"]), public)
        key = private.private_key(backend)
        symkey = key.exchange(public.public_key(backend))

        assert int_from_bytes(symkey, 'big') == int(vector["k"], 16)
def challenge_response(s, key_clie_pri, key_clie_pub, key_serv_pub):
    # implement a Challenge-Response Authentication protocol and derive a session key

    # Stage 1
    # Client Sends to server a magic number (serial) and the signature of magic number
    # encrypted with the servers public key

    seq_id = 1  # holds the sequence numbers in packet's

    serial = int_from_bytes(os.urandom(4), byteorder="big")
    m = size_in_8bit(seq_id) + size_in_32bit(serial)
    serial_sig = rsa_module.sign_data(m, key_clie_pri)
    message1 = serial_sig + m
    ciphertext1 = rsa_module.rsa_cbc_encrypt(message1, key_serv_pub)
    s.sendall(ciphertext1)

    # time delay if under attack
    time.sleep(1)

    # Stage 2
    # Recieve Data
    ciphertext2 = s.recv(size)
    # Decrypt Data
    message2 = rsa_module.rsa_cbc_dencrypt(ciphertext2, key_clie_pri)
    # Verify Data
    serial_sig_server = message2[:256]
    rsa_module.verify_data(message2[256:], serial_sig_server, key_serv_pub)
    # Extract Data
    seq_id_server = message2[256:256 + 8]
    serial_reply = message2[256 + 8:256 + 8 + 32]
    serial_server = message2[256 + 8 + 32:256 + 8 + 32 + 32]

    if serial_reply != size_in_32bit(serial):
        print "Signature don't match"
        return False
    print "Server is authenticated"

    # update sequence id
    seq_id = seq_id + size_bin_int(seq_id_server)

    m = size_in_8bit(seq_id) + serial_server
    serial_sig = rsa_module.sign_data(m, key_clie_pri)
    message3 = serial_sig + m
    ciphertext3 = rsa_module.rsa_cbc_encrypt(message3, key_serv_pub)
    s.sendall(ciphertext3)
    time.sleep(1)

    print "Challenge Response was Successful"
    # Stage 4 get AES key from server (Session Key)
    session_key = s.recv(size)
    session_key = b64decode(session_key)

    aes_data = rsa_module.rsa_cbc_dencrypt(session_key, key_clie_pri)
    aes_sig = aes_data[:256]
    aes_key = aes_data[256:]

    rsa_module.verify_data(aes_key, aes_sig, key_serv_pub)
    return aes_key
Example #34
0
def dh_shared_secret(
        message: bytes,
        private_secret: dh.DHPublicNumbers) -> dh.DHPrivateNumbers:
    """
    Compute the shared secret from private secret and the other party's message.
    """
    gx = utils.int_from_bytes(message, 'big')
    gxy = pow(gx, private_secret.y, private_secret.parameter_numbers.p)
    return dh.DHPrivateNumbers(gxy, private_secret)
Example #35
0
    def test_dh_vectors(self, backend, vector):
        parameters = dh.DHParameterNumbers(int(vector["p"]),
                                           int(vector["g"]))
        public = dh.DHPublicNumbers(int(vector["y"]), parameters)
        private = dh.DHPrivateNumbers(int(vector["x"]), public)
        key = private.private_key(backend)
        symkey = key.exchange(public.public_key(backend))

        assert int_from_bytes(symkey, 'big') == int(vector["k"], 16)
Example #36
0
 def test_dh_parameters_allows_rfc3526_groups(self, backend, vector):
     p = int_from_bytes(binascii.unhexlify(vector["p"]), 'big')
     params = dh.DHParameterNumbers(p, int(vector["g"]))
     param = params.parameters(backend)
     key = param.generate_private_key()
     # This confirms that a key generated with this group
     # will pass DH_check when we serialize and de-serialize it via
     # the Numbers path.
     roundtripped_key = key.private_numbers().private_key(backend)
     assert key.private_numbers() == roundtripped_key.private_numbers()
Example #37
0
 def test_dh_parameters_allows_rfc3526_groups(self, backend, vector):
     p = int_from_bytes(binascii.unhexlify(vector["p"]), 'big')
     params = dh.DHParameterNumbers(p, int(vector["g"]))
     param = params.parameters(backend)
     key = param.generate_private_key()
     # This confirms that a key generated with this group
     # will pass DH_check when we serialize and de-serialize it via
     # the Numbers path.
     roundtripped_key = key.private_numbers().private_key(backend)
     assert key.private_numbers() == roundtripped_key.private_numbers()
def _read_next_mpint(data):
    """
    Reads the next mpint from the data.

    Currently, all mpints are interpreted as unsigned.
    """
    mpint_data, rest = _read_next_string(data)

    return (utils.int_from_bytes(mpint_data, byteorder='big',
                                 signed=False), rest)
Example #39
0
	def set_server_public_key(self, server_public_key):
		common_secret = pow(int_from_bytes(server_public_key, 'big'), self.pkey, self.DH_PRIME_1024)
		common_secret = self.int_to_bytes(common_secret)
		# Prepend NULL bytes if needed
		common_secret = b'\x00' * (0x80 - len(common_secret)) + common_secret
		# HKDF with null salt, empty info and SHA-256 hash
		salt = b'\x00' * 0x20
		pseudo_random_key = hmac.new(salt, common_secret, sha256).digest()
		output_block = hmac.new(pseudo_random_key, b'\x01', sha256).digest()
		# Resulting AES key should be 128-bit
		self.aes_key = output_block[:0x10]
Example #40
0
def _ssh_read_next_mpint(data):
    """
    Reads the next mpint from the data.

    Currently, all mpints are interpreted as unsigned.
    """
    mpint_data, rest = _ssh_read_next_string(data)

    return (
        utils.int_from_bytes(mpint_data, byteorder='big', signed=False), rest
    )
Example #41
0
    def set_server_public_key(self, server_public_key: Sequence):
        common_secret = pow(int_from_bytes(server_public_key, 'big'),
                            self.pkey, self.DH_PRIME_1024)
        common_secret = int_to_bytes(common_secret)

        hkdf = HKDF(algorithm=hashes.SHA256(),
                    length=16,
                    salt=None,
                    info=None,
                    backend=default_backend())
        self.aes_key = hkdf.derive(common_secret)
Example #42
0
    def from_encoded_point(cls, curve, data):
        if not isinstance(curve, EllipticCurve):
            raise TypeError("curve must be an EllipticCurve instance")

        warnings.warn(
            "Support for unsafe construction of public numbers from "
            "encoded data will be removed in a future version. "
            "Please use EllipticCurvePublicKey.from_encoded_point",
            utils.DeprecatedIn25,
            stacklevel=2,
        )

        if data.startswith(b'\x04'):
            # key_size is in bits. Convert to bytes and round up
            byte_length = (curve.key_size + 7) // 8
            if len(data) == 2 * byte_length + 1:
                x = utils.int_from_bytes(data[1:byte_length + 1], 'big')
                y = utils.int_from_bytes(data[byte_length + 1:], 'big')
                return cls(x, y, curve)
            else:
                raise ValueError('Invalid elliptic curve point data length')
        else:
            raise ValueError('Unsupported elliptic curve point type')
Example #43
0
    def test_exchange_algorithm(self, backend):
        parameters = dh.generate_parameters(2, 512, backend)

        key1 = parameters.generate_private_key()
        key2 = parameters.generate_private_key()

        shared_key_bytes = key2.exchange(key1.public_key())
        symkey = int_from_bytes(shared_key_bytes, 'big')

        symkey_manual = pow(key1.public_key().public_numbers().y,
                            key2.private_numbers().x,
                            parameters.parameter_numbers().p)

        assert symkey == symkey_manual
Example #44
0
def getMP(data, count=1):
    """
    Get multiple precision integer out of the string.  A multiple precision
    integer is stored as a 4-byte length followed by length bytes of the
    integer.  If count is specified, get count integers out of the string.
    The return value is a tuple of count integers followed by the rest of
    the data.
    """
    mp = []
    c = 0
    for i in range(count):
        length, = struct.unpack('>L', data[c:c + 4])
        mp.append(int_from_bytes(data[c + 4:c + 4 + length], 'big'))
        c += 4 + length
    return tuple(mp) + (data[c:],)
def test_certificate():
    from cryptography import utils
    from cryptography import x509
    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.primitives.asymmetric import rsa
    from cryptography.hazmat.primitives import serialization
    from cryptography.x509.oid import NameOID

    one_day = datetime.timedelta(1, 0, 0)
    private_key = rsa.generate_private_key(
        public_exponent=65537,
        key_size=2048,
        backend=default_backend())
    public_key = private_key.public_key()
    builder = x509.CertificateBuilder()

    builder = builder.subject_name(x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, u'example.com'),
    ]))
    builder = builder.issuer_name(x509.Name([
        x509.NameAttribute(NameOID.COMMON_NAME, u'example.com'),
    ]))
    builder = builder.not_valid_before(datetime.datetime.today() - one_day)
    builder = builder.not_valid_after(datetime.datetime.today() + one_day)
    builder = builder.serial_number(
        utils.int_from_bytes(os.urandom(20), "big") >> 1)
    builder = builder.public_key(public_key)

    builder = builder.add_extension(
        x509.BasicConstraints(ca=False, path_length=None), critical=True)

    certificate = builder.sign(
        private_key=private_key, algorithm=hashes.SHA256(),
        backend=default_backend())

    certificate_pem = certificate.public_bytes(serialization.Encoding.PEM)
    public_key_bytes = certificate.public_key().public_bytes(
        serialization.Encoding.DER,
        serialization.PublicFormat.SubjectPublicKeyInfo)
    private_key_bytes = private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption())

    yield certificate, certificate_pem, public_key_bytes, private_key_bytes
def test_int_from_bytes_bytearray():
    assert utils.int_from_bytes(bytearray(b"\x02\x10"), "big") == 528
    with pytest.raises(TypeError):
        utils.int_from_bytes(["list", "is", "not", "bytes"], "big")
Example #47
0
from paramiko.client import SSHClient as ParamikoSSHClient
from paramiko import py3compat

from sshaolin import common
from sshaolin.models import CommandResponse

# this is a hack to preimport dependencies imported in a thread during connect
# which causes a deadlock. https://github.com/paramiko/paramiko/issues/104
py3compat.u("".encode())

# dirty hack 2.0 also issue 104
# Try / Catch to prevent users using paramiko<2.0.0 from raising an ImportError
try:
    from cryptography.hazmat.backends import default_backend
    from cryptography.utils import int_from_bytes
    int_from_bytes(b"a", "big")
    default_backend()
except ImportError:
    pass


class CommandOperationTimeOut(socket.timeout):
    pass


class ProxyTypes(object):
    SOCKS5 = 2
    SOCKS4 = 1


def read_pipe(pipe, fp_out):
Example #48
0
  def _digest_for_signature(self, signing_key, signature):
    """
    Provides the signed digest we should have given this key and signature.

    :param str signing_key: key block used to make this signature
    :param str signature: signed digest for this descriptor content

    :returns: the digest string encoded in uppercase hex

    :raises: ValueError if unable to provide a validly signed digest
    """

    if not stem.prereq.is_crypto_available():
      raise ValueError('Generating the signed digest requires the cryptography module')

    from cryptography.hazmat.backends import default_backend
    from cryptography.hazmat.primitives.serialization import load_der_public_key
    from cryptography.utils import int_to_bytes, int_from_bytes

    key = load_der_public_key(_bytes_for_block(signing_key), default_backend())
    modulus = key.public_numbers().n
    public_exponent = key.public_numbers().e

    sig_as_bytes = _bytes_for_block(signature)
    sig_as_long = int_from_bytes(sig_as_bytes, byteorder='big')  # convert signature to an int
    blocksize = len(sig_as_bytes)  # 256B for NetworkStatusDocuments, 128B for others

    # use the public exponent[e] & the modulus[n] to decrypt the int
    decrypted_int = pow(sig_as_long, public_exponent, modulus)

    # convert the int to a byte array
    decrypted_bytes = int_to_bytes(decrypted_int, blocksize)

    ############################################################################
    # The decrypted bytes should have a structure exactly along these lines.
    # 1 byte  - [null '\x00']
    # 1 byte  - [block type identifier '\x01'] - Should always be 1
    # N bytes - [padding '\xFF' ]
    # 1 byte  - [separator '\x00' ]
    # M bytes - [message]
    # Total   - 128 bytes
    # More info here http://www.ietf.org/rfc/rfc2313.txt
    #                esp the Notes in section 8.1
    ############################################################################

    try:
      if decrypted_bytes.index(DIGEST_TYPE_INFO) != 0:
        raise ValueError('Verification failed, identifier missing')
    except ValueError:
      raise ValueError('Verification failed, malformed data')

    try:
      identifier_offset = 2

      # find the separator
      seperator_index = decrypted_bytes.index(DIGEST_SEPARATOR, identifier_offset)
    except ValueError:
      raise ValueError('Verification failed, seperator not found')

    digest_hex = codecs.encode(decrypted_bytes[seperator_index + 1:], 'hex_codec')
    return stem.util.str_tools._to_unicode(digest_hex.upper())
Example #49
0
def random_serial_number():
    return utils.int_from_bytes(os.urandom(20), "big") >> 1
def test_int_from_bytes_bytearray():
    assert utils.int_from_bytes(bytearray(b"\x02\x10"), "big") == 528
Example #51
0
def random_nat(n: int) -> int:
    """
    Generate a random natural number L{n} bytes long.
    """
    return utils.int_from_bytes(random_bytes(n), 'big', signed=False)