def sign(self, message):
        message = _helpers.to_bytes(message)
        asn1_signature = self._key.sign(message, ec.ECDSA(hashes.SHA256()))

        # Convert ASN1 encoded signature to (r||s) raw signature.
        (r, s) = decode_dss_signature(asn1_signature)
        return utils.int_to_bytes(r, 32) + utils.int_to_bytes(s, 32)
Exemplo n.º 2
0
 def encode_point(self):
     # key_size is in bits. Convert to bytes and round up
     byte_length = (self.curve.key_size + 7) // 8
     return (
         b'\x04' + utils.int_to_bytes(self.x, byte_length) +
         utils.int_to_bytes(self.y, byte_length)
     )
Exemplo n.º 3
0
def add_kid(kid_b64, key_b64):
    kid = b64decode(kid_b64)
    asn1data = b64decode(key_b64)

    pub = serialization.load_der_public_key(asn1data)
    if (isinstance(pub, RSAPublicKey)):
        kids[kid_b64] = CoseKey.from_dict({
            KpKty:
            KtyRSA,
            KpAlg:
            Ps256,  # RSSASSA-PSS-with-SHA-256-and-MFG1
            RSAKpE:
            int_to_bytes(pub.public_numbers().e),
            RSAKpN:
            int_to_bytes(pub.public_numbers().n)
        })
    elif (isinstance(pub, EllipticCurvePublicKey)):
        kids[kid_b64] = CoseKey.from_dict({
            KpKty:
            KtyEC2,
            EC2KpCurve:
            P256,  # Ought o be pk.curve - but the two libs clash
            KpAlg:
            Es256,  # ecdsa-with-SHA256
            EC2KpX:
            pub.public_numbers().x.to_bytes(32, byteorder="big"),
            EC2KpY:
            pub.public_numbers().y.to_bytes(32, byteorder="big")
        })
    else:
        print(
            f"Skipping unexpected/unknown key type (keyid={kid_b64}, {pub.__class__.__name__}).",
            file=sys.stderr)
Exemplo n.º 4
0
 def encode_point(self):
     # key_size is in bits. Convert to bytes and round up
     byte_length = (self.curve.key_size + 7) // 8
     return (
         b'\x04' + utils.int_to_bytes(self.x, byte_length) +
         utils.int_to_bytes(self.y, byte_length)
     )
Exemplo n.º 5
0
    def _get_key_data(self, key):
        def _der_len(data):
            ln = len(data)
            if ln <= 128:
                res = [ln]
            elif ln <= 255:
                res = [0x81, ln]
            else:
                res = [0x82, (ln >> 8) & 0xff, ln & 0xff]
            return bytearray(res)

        private_numbers = key.private_numbers()
        data = a2b_hex('B603840181')

        if isinstance(key, rsa.RSAPrivateKey):
            ln = key.key_size // 8 // 2
            data += b'\x7f\x48\x08\x91\x03\x92\x81\x80\x93\x81\x80\x5f\x48\x82\x01\x03\x01\x00\x01'  # noqa: E501
            data += int_to_bytes(private_numbers.p, ln)
            data += int_to_bytes(private_numbers.q, ln)
            return b'\x4d' + _der_len(data) + data
        elif isinstance(key, ec.EllipticCurvePrivateKey):
            ln = key.key_size // 8
            privkey = int_to_bytes(private_numbers.private_value, ln)
            data += b'\x7f\x48\x02\x92' + _der_len(privkey)
            data += b'\x5f\x48' + _der_len(privkey) + privkey
            return b'\x4d' + _der_len(data) + data
Exemplo n.º 6
0
    def derive(self, key_material: bytes) -> bytes:
        if self._used:
            raise AlreadyFinalized

        utils._check_byteslike("key_material", key_material)
        self._used = True

        # inverse floor division (equivalent to ceiling)
        rounds = -(-self._length // self._algorithm.digest_size)

        output = [b""]

        # For counter mode, the number of iterations shall not be
        # larger than 2^r-1, where r <= 32 is the binary length of the counter
        # This ensures that the counter values used as an input to the
        # PRF will not repeat during a particular call to the KDF function.
        r_bin = utils.int_to_bytes(1, self._rlen)
        if rounds > pow(2, len(r_bin) * 8) - 1:
            raise ValueError("There are too many iterations.")

        for i in range(1, rounds + 1):
            h = hmac.HMAC(key_material, self._algorithm, backend=self._backend)

            counter = utils.int_to_bytes(i, self._rlen)
            if self._location == CounterLocation.BeforeFixed:
                h.update(counter)

            h.update(self._generate_fixed_input())

            if self._location == CounterLocation.AfterFixed:
                h.update(counter)

            output.append(h.finalize())

        return b"".join(output)[:self._length]
Exemplo n.º 7
0
    def derive(self, key_material):
        if self._used:
            raise AlreadyFinalized

        utils._check_byteslike("key_material", key_material)
        self._used = True

        # inverse floor division (equivalent to ceiling)
        rounds = -(-self._length // self._algorithm.digest_size)

        output = [b'']

        # For counter mode, the number of iterations shall not be
        # larger than 2^r-1, where r <= 32 is the binary length of the counter
        # This ensures that the counter values used as an input to the
        # PRF will not repeat during a particular call to the KDF function.
        r_bin = utils.int_to_bytes(1, self._rlen)
        if rounds > pow(2, len(r_bin) * 8) - 1:
            raise ValueError('There are too many iterations.')

        for i in range(1, rounds + 1):
            h = hmac.HMAC(key_material, self._algorithm, backend=self._backend)

            counter = utils.int_to_bytes(i, self._rlen)
            if self._location == CounterLocation.BeforeFixed:
                h.update(counter)

            h.update(self._generate_fixed_input())

            if self._location == CounterLocation.AfterFixed:
                h.update(counter)

            output.append(h.finalize())

        return b''.join(output)[:self._length]
Exemplo n.º 8
0
def get_key_alg_and_jwk(key):
    if isinstance(key, rsa.RSAPrivateKey):
        # See https://tools.ietf.org/html/rfc7518#section-6.3
        numbers = key.public_key().public_numbers()
        return "RS256", {
            "kty": "RSA",
            "e": bytes_to_base64url(int_to_bytes(numbers.e)),
            "n": bytes_to_base64url(int_to_bytes(numbers.n))
        }
    elif isinstance(key, ec.EllipticCurvePrivateKey):
        # See https://tools.ietf.org/html/rfc7518#section-6.2
        numbers = key.public_key().public_numbers()
        if isinstance(numbers.curve, ec.SECP256R1):
            alg = 'ES256'
            crv = 'P-256'
        elif isinstance(numbers.curve, ec.SECP384R1):
            alg = 'ES384'
            crv = 'P-384'
        elif isinstance(numbers.curve, ec.SECP521R1):
            alg = 'ES512'
            crv = 'P-521'
        else:
            raise ValueError("Unsupported EC curve in key: {}".format(key))
        full_octets = (int(crv[2:]) + 7) // 8
        return alg, {
            "kty": "EC",
            "crv": crv,
            "x": bytes_to_base64url(int_to_bytes(numbers.x, full_octets)),
            "y": bytes_to_base64url(int_to_bytes(numbers.y, full_octets))
        }
    elif "cryptography.hazmat.primitives.asymmetric.ed25519" in sys.modules and isinstance(
            key, ed25519.Ed25519PrivateKey):
        # See https://tools.ietf.org/html/rfc8037#appendix-A.2
        return "EdDSA", {
            "kty":
            "OKP",
            "crv":
            "Ed25519",
            "x":
            bytes_to_base64url(key.public_key().public_bytes(
                encoding=serialization.Encoding.Raw,
                format=serialization.PublicFormat.Raw))
        }
    elif "cryptography.hazmat.primitives.asymmetric.ed448" in sys.modules and isinstance(
            key, ed448.Ed448PrivateKey):
        return "EdDSA", {
            "kty":
            "OKP",
            "crv":
            "Ed448",
            "x":
            bytes_to_base64url(key.public_key().public_bytes(
                encoding=serialization.Encoding.Raw,
                format=serialization.PublicFormat.Raw))
        }
    else:
        raise ValueError("Unsupported key: {}".format(key))
    def encode_manifest(self, ca_key_path=None, ca_cert_path=None):
        """
        Function generate secure signed element object which contains payload,
        protected, header and signature.

        Inputs:
              ca_key_path        log signer key path which sign the jws data
              ca_cert_path       log signer cert path which contains cert
                                 extension and cert fingerprint

        Outputs:
              signed_se          return encoded manifest which contains
                                 securesignedelement object
              ca_key_path        log signer key path which sign the jws data
              ca_cert_path       log signer cert path which contains cert
                                 extension and cert fingerprint
        """
        # Read ca key
        if ca_key_path is None:
            ca_cert_path = None

        ca_key_path, ca_key = self.__load_ca_key(ca_key_path)
        ca_cert_path, ca_cert = self.__load_ca_cert(ca_key, ca_cert_path)

        # Precompute the JWT header
        sse_protected_header = {
            'typ': 'JWT',
            'alg': 'ES256',
            'kid': self.__jws_b64encode(
                ca_cert.extensions.get_extension_for_class(
                    x509.SubjectKeyIdentifier).value.digest),
            'x5t#S256': self.__jws_b64encode(ca_cert.fingerprint(hashes.SHA256()))
        }

        se_object = self.get_manifest()
        signed_se = {
            'payload': self.__jws_b64encode(json.dumps(
                se_object).encode('ascii')),
            'protected': self.__jws_b64encode(
                json.dumps(sse_protected_header).encode('ascii')),
            'header': {
                'uniqueId': self.uniqueId
            }
        }

        # Sign sse object
        tbs = signed_se['protected'] + '.' + signed_se['payload']
        signature = ca_key.sign(tbs.encode('ascii'), ec.ECDSA(hashes.SHA256()))
        r_int, s_int = crypto_utils.decode_dss_signature(signature)
        signed_se['signature'] = self.__jws_b64encode(
            int_to_bytes(r_int, 32) + int_to_bytes(s_int, 32))

        return {
            'signed_se': signed_se,
            'ca_key_path': ca_key_path,
            'ca_cert_path': ca_cert_path
        }
Exemplo n.º 10
0
    def sign(self, message):
        message = _helpers.to_bytes(message)
        asn1_signature = self._key.sign(message, ec.ECDSA(hashes.SHA256()))

        # Convert ASN1 encoded signature to (r||s) raw signature.
        (r, s) = decode_dss_signature(asn1_signature)
        return ((r.to_bytes(32, byteorder="big") +
                 s.to_bytes(32, byteorder="big")) if _helpers.is_python_3()
                else (utils.int_to_bytes(r, 32) + utils.int_to_bytes(s, 32)))
Exemplo n.º 11
0
 def _decode_signature(signature, hash_algorithm):
     hash_algorithms_map = {'SHA256': 256}
     try:
         num_bits = hash_algorithms_map[hash_algorithm]
     except KeyError:
         raise ValueError(
             f'Wrong hash algorithm: {hash_algorithm}. Allowed: {list(hash_algorithms_map.keys())}'
         )
     num_bytes = (num_bits + 7) // 8
     r, s = decode_dss_signature(signature)
     return int_to_bytes(r, num_bytes) + int_to_bytes(s, num_bytes)
Exemplo n.º 12
0
    def to_map(self):
        public_key_map = self.public_key().to_map()
        d_bytes = cry_utils.int_to_bytes(self.numbers.private_value)
        octet_length = (len(cry_utils.int_to_bytes(self.numbers.private_value - 1)) + 7) >> 3

        d_bytes = b'\x00' * (octet_length - len(d_bytes)) + d_bytes
        private_key_map = {
            'd': util.jose_base64_url_encode(d_bytes).decode('utf-8')
        }

        private_key_map.update(public_key_map)
        return private_key_map
Exemplo n.º 13
0
def _dsc(config_env: Dict):
    if TEST_CONTEXT in config_env.keys(
    ) and CERTIFICATE in config_env[TEST_CONTEXT].keys():
        cert_code = config_env[TEST_CONTEXT][CERTIFICATE]
        x = y = e = n = None
        cert = x509.load_pem_x509_certificate(
            f'-----BEGIN CERTIFICATE-----\n{cert_code}\n-----END CERTIFICATE-----'
            .encode())

        fingerprint = cert.fingerprint(SHA256())
        keyid = fingerprint[0:8]

        if isinstance(cert.public_key(), rsa.RSAPublicKey):
            e = int_to_bytes(cert.public_key().public_numbers().e)
            n = int_to_bytes(cert.public_key().public_numbers().n)
        elif isinstance(cert.public_key(), ec.EllipticCurvePublicKey):
            x = int_to_bytes(cert.public_key().public_numbers().x)
            y = int_to_bytes(cert.public_key().public_numbers().y)
        else:
            raise Exception(
                f'Unsupported Certificate Algorithm: {cert.signature_algorithm_oid} for verification.'
            )
        try:
            dsc_supported_operations = {
                eku.dotted_string
                for eku in cert.extensions.get_extension_for_class(
                    x509.ExtendedKeyUsage).value
            }
        except ExtensionNotFound:
            dsc_supported_operations = set()
        dsc_not_valid_before = cert.not_valid_before.replace(
            tzinfo=timezone.utc)
        dsc_not_valid_after = cert.not_valid_after.replace(tzinfo=timezone.utc)
        key = None
        if x and y:
            key = CoseKey.from_dict({
                KpKeyOps: [VerifyOp],
                KpKty: KtyEC2,
                EC2KpCurve:
                P256,  # Ought o be pk.curve - but the two libs clash
                KpAlg: Es256,  # ECDSA using P-256 and SHA-256
                EC2KpX: x,
                EC2KpY: y,
            })
        elif e and n:
            key = CoseKey.from_dict({
                KpKeyOps: [VerifyOp],
                KpKty: KtyRSA,
                KpAlg: Ps256,  # RSASSA-PSS using SHA-256 and MGF1 with SHA-256
                RSAKpE: e,
                RSAKpN: n,
            })
        return key, keyid, dsc_supported_operations, dsc_not_valid_before, dsc_not_valid_after
Exemplo n.º 14
0
 def encode_point(self):
     warnings.warn(
         "encode_point has been deprecated on EllipticCurvePublicNumbers"
         " and will be removed in a future version. Please use "
         "EllipticCurvePublicKey.public_bytes to obtain both "
         "compressed and uncompressed point encoding.",
         utils.PersistentlyDeprecated2019,
         stacklevel=2,
     )
     # key_size is in bits. Convert to bytes and round up
     byte_length = (self.curve.key_size + 7) // 8
     return (b"\x04" + utils.int_to_bytes(self.x, byte_length) +
             utils.int_to_bytes(self.y, byte_length))
Exemplo n.º 15
0
 def crypto_sign_msg(self, msg):
     if self.algo == 'rsa':
         return self.privkey.sign(msg, padding.PKCS1v15(), hashes.SHA256())
     elif self.algo == 'ec':
         hash_algos = {
             256: hashes.SHA256(),
             384: hashes.SHA384(),
             521: hashes.SHA512()
         }
         sig_der = self.privkey.sign(msg, ec.ECDSA(hash_algos[self.bits]))
         num_bytes = (self.bits + 7) // 8
         r, s = utils.decode_dss_signature(sig_der)
         return int_to_bytes(r, num_bytes) + int_to_bytes(s, num_bytes)
Exemplo n.º 16
0
 def put_key(
     self,
     slot: SLOT,
     private_key: Union[rsa.RSAPrivateKeyWithSerialization,
                        ec.EllipticCurvePrivateKeyWithSerialization, ],
     pin_policy: PIN_POLICY = PIN_POLICY.DEFAULT,
     touch_policy: TOUCH_POLICY = TOUCH_POLICY.DEFAULT,
 ) -> None:
     key_type = KEY_TYPE.from_public_key(private_key.public_key())
     _check_key_support(self.version, key_type, pin_policy, touch_policy)
     ln = key_type.bit_len // 8
     numbers = private_key.private_numbers()
     if key_type.algorithm == ALGORITHM.RSA:
         numbers = cast(rsa.RSAPrivateNumbers, numbers)
         if numbers.public_numbers.e != 65537:
             raise ValueError("RSA exponent must be 65537")
         ln //= 2
         data = (Tlv(0x01, int_to_bytes(numbers.p, ln)) +
                 Tlv(0x02, int_to_bytes(numbers.q, ln)) +
                 Tlv(0x03, int_to_bytes(numbers.dmp1, ln)) +
                 Tlv(0x04, int_to_bytes(numbers.dmq1, ln)) +
                 Tlv(0x05, int_to_bytes(numbers.iqmp, ln)))
     else:
         numbers = cast(ec.EllipticCurvePrivateNumbers, numbers)
         data = Tlv(0x06, int_to_bytes(numbers.private_value, ln))
     if pin_policy:
         data += Tlv(TAG_PIN_POLICY, int_to_bytes(pin_policy))
     if touch_policy:
         data += Tlv(TAG_TOUCH_POLICY, int_to_bytes(touch_policy))
     self.protocol.send_apdu(0, INS_IMPORT_KEY, key_type, slot, data)
     return key_type
Exemplo n.º 17
0
    def test_token_info_by_ec(self):
        ec_key = generate_ec_private_key()

        public_numbers = ec_key.public_key().public_numbers()
        x = urlsafe_b64encode(int_to_bytes(public_numbers.x)).decode()
        y = urlsafe_b64encode(int_to_bytes(public_numbers.y)).decode()

        private_key = ec_key.private_bytes(
            encoding=serialization.Encoding.PEM,
            format=serialization.PrivateFormat.TraditionalOpenSSL,
            encryption_algorithm=serialization.NoEncryption()).decode()

        payload = {
            'sub': 'testuser',
            'u_idx': 123123,
            'exp': int(time.time()) + 60 * 60,
            'client_id': 'asfeih29snv8as213i',
            'scope': 'all'
        }
        headers = {
            'kid': 'ES999',
        }

        valid_token = jwt.encode(payload=payload,
                                 key=private_key,
                                 algorithm='ES256',
                                 headers=headers).decode()

        with requests_mock.Mocker() as m:
            m.get(RidiOAuth2Config.get_key_url(),
                  text=json.dumps({
                      'keys': [{
                          "kty": "EC",
                          "use": "sig",
                          "crv": "P-256",
                          "kid": "ES999",
                          "x": x,
                          "y": y,
                          "alg": "ES256"
                      }]
                  }))

            token_info = get_token_info(token=valid_token)

        self.assertEqual(token_info.subject, payload['sub'])
        self.assertEqual(token_info.u_idx, payload['u_idx'])
        self.assertEqual(token_info.expire_timestamp, payload['exp'])
        self.assertEqual(token_info.client_id, payload['client_id'])
        self.assertIn(payload['scope'], token_info.scope)
Exemplo n.º 18
0
 def jwk(self):
     pubnums = self.pubkey.public_numbers()
     if self.algo == 'rsa':
         return {
             'kty': 'RSA',
             'n': acme_b64encode(int_to_bytes(pubnums.n)),
             'e': acme_b64encode(int_to_bytes(pubnums.e))
         }
     elif self.algo == 'ec':
         return {
             'kty': 'EC',
             'crv': 'P-{0}'.format(self.bits),
             'x': acme_b64encode(int_to_bytes(pubnums.x)),
             'y': acme_b64encode(int_to_bytes(pubnums.y))
         }
Exemplo n.º 19
0
    def test_blobEC(self):
        """
        Return the over-the-wire SSH format of the EC public key.
        """
        from cryptography import utils

        byteLength = (self.ecObj.curve.key_size + 7) // 8
        self.assertEqual(
            keys.Key(self.ecObj).blob(),
            common.NS(keydata.ECDatanistp256['curve']) +
            common.NS(keydata.ECDatanistp256['curve'][-8:]) + common.
            NS(b'\x04' + utils.int_to_bytes(
                self.ecObj.private_numbers().public_numbers.x, byteLength) +
               utils.int_to_bytes(
                   self.ecObj.private_numbers().public_numbers.y, byteLength)))
Exemplo n.º 20
0
 def encode_point(self):
     warnings.warn(
         "encode_point has been deprecated on EllipticCurvePublicNumbers"
         " and will be removed in a future version. Please use "
         "EllipticCurvePublicKey.public_bytes to obtain both "
         "compressed and uncompressed point encoding.",
         utils.DeprecatedIn25,
         stacklevel=2,
     )
     # key_size is in bits. Convert to bytes and round up
     byte_length = (self.curve.key_size + 7) // 8
     return (
         b'\x04' + utils.int_to_bytes(self.x, byte_length) +
         utils.int_to_bytes(self.y, byte_length)
     )
Exemplo n.º 21
0
def ssh_public_key(keypair: rsa.RSAPrivateKeyWithSerialization) -> str:
    """
    converts an rsa keypair to openssh format public key

    :param keypair: keypair.
    :type keypair: cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization
    :return: string of public key
    """
    eb = utils.int_to_bytes(keypair.public_key().public_numbers().e)
    nb = utils.int_to_bytes(keypair.public_key().public_numbers().n)
    if eb[0] & 0x80: eb = bytes([0x00]) + eb
    if nb[0] & 0x80: nb = bytes([0x00]) + nb
    keyparts = [b'ssh-rsa', eb, nb]
    keystring = b''.join([struct.pack(">I", len(kp)) + kp for kp in keyparts])
    return str(b'ssh-rsa ' + b64encode(keystring), encoding='utf-8')
Exemplo n.º 22
0
def ssh_public_key(keypair: rsa.RSAPrivateKeyWithSerialization) -> str:
    """
    converts an rsa keypair to openssh format public key

    :param keypair: keypair.
    :type keypair: cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization
    :return: string of public key
    """
    eb = utils.int_to_bytes(keypair.public_key().public_numbers().e)
    nb = utils.int_to_bytes(keypair.public_key().public_numbers().n)
    if eb[0] & 0x80: eb = bytes([0x00]) + eb
    if nb[0] & 0x80: nb = bytes([0x00]) + nb
    keyparts = [b'ssh-rsa', eb, nb]
    keystring = b''.join([struct.pack(">I", len(kp)) + kp for kp in keyparts])
    return str(b'ssh-rsa ' + b64encode(keystring), encoding='utf-8')
Exemplo n.º 23
0
    def put(cls, session, object_id, label, domains, capabilities, key):
        """Import a private key into the YubiHSM.

        RSA and EC keys can be created by using the cryptography APIs. You can
        then pass either a
        :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey`
        or a
        :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey`
        as `key`.

        EdDSA keys can be created using the Cryptography APIs if available, or
        by calling
        :func:`~yubihsm.eddsa.load_ed25519_private_key`.

        :param AuthSession session: The session to import via.
        :param int object_id: The ID to set for the object. Set to 0 to let the
            YubiHSM designate an ID.
        :param str label: A text label to give the object.
        :param int domains: The set of domains to assign the object to.
        :param int capabilities: The set of capabilities to give the object.
        :param key: The private key to import.
        :return: A reference to the newly created object.
        :rtype: AsymmetricKey
        """
        if isinstance(key, rsa.RSAPrivateKey):
            numbers = key.private_numbers()
            serialized = int_to_bytes(numbers.p) + int_to_bytes(numbers.q)
            algo = getattr(ALGORITHM, "RSA_%d" % key.key_size)
        elif isinstance(key, ec.EllipticCurvePrivateKey):
            numbers = key.private_numbers()
            serialized = int_to_bytes(numbers.private_value,
                                      (key.curve.key_size + 7) // 8)
            algo = ALGORITHM.for_curve(key.curve)
        elif _is_ed25519_private_key(key):
            serialized = _serialize_ed25519_private_key(key)
            algo = ALGORITHM.EC_ED25519
        else:
            raise ValueError("Unsupported key")

        msg = (struct.pack(
            "!H%dsHQB" % LABEL_LENGTH,
            object_id,
            _label_pack(label),
            domains,
            capabilities,
            algo,
        ) + serialized)
        return cls._from_command(session, COMMAND.PUT_ASYMMETRIC_KEY, msg)
Exemplo n.º 24
0
def _key_identifier_from_public_key(public_key):
    if isinstance(public_key, RSAPublicKey):
        data = public_key.public_bytes(
            serialization.Encoding.DER,
            serialization.PublicFormat.PKCS1,
        )
    elif isinstance(public_key, EllipticCurvePublicKey):
        data = public_key.public_numbers().encode_point()
    else:
        # This is a very slow way to do this.
        serialized = public_key.public_bytes(
            serialization.Encoding.DER,
            serialization.PublicFormat.SubjectPublicKeyInfo)
        spki, remaining = decoder.decode(serialized,
                                         asn1Spec=_SubjectPublicKeyInfo())
        assert not remaining
        # the univ.BitString object is a tuple of bits. We need bytes and
        # pyasn1 really doesn't want to give them to us. To get it we'll
        # build an integer and convert that to bytes.
        bits = 0
        for bit in spki.getComponentByName("subjectPublicKey"):
            bits = bits << 1 | bit

        data = utils.int_to_bytes(bits)

    return hashlib.sha1(data).digest()
Exemplo n.º 25
0
    def enable_encryptor_by_pem_file(self, pem_pub_file, curve_name = 'secp256k1', strength = 128):
        if not self.can_encryptor:
            raise Exception("can not enable encryptor after a quest send")
        if curve_name not in ['secp256k1', 'secp256r1', 'secp192r1', 'secp224r1']:
            curve_name = 'secp256k1'
        self.encryptor_curve = ec.SECP256K1()
        if curve_name == 'secp256k1':
            self.encryptor_curve = ec.SECP256K1()
        elif curve_name == 'secp256r1':
            self.encryptor_curve = ec.SECP256R1()
        elif curve_name == 'secp192r1':
            self.encryptor_curve = ec.SECP192R1()
        else:
            self.encryptor_curve = ec.SECP224R1()
        if strength not in [128, 256]:
            strength = 128
        self.encryptor_strength = strength

        pri_key = ec.generate_private_key(self.encryptor_curve, default_backend())
        pub_key = pri_key.public_key()
        peer_pub_key = load_pem_public_key(open(pem_pub_file, 'rb').read(), backend=default_backend()) 
        
        secret = pri_key.exchange(ec.ECDH(), peer_pub_key)
        self.encrypted_iv = hashlib.md5(secret).digest()
        if strength == 128:
            self.encrypted_key = secret[0:16]
        else:
            if len(secret) == 32:
                self.encrypted_key = secret
            else:
                self.encrypted_key = hashlib.sha256(secret).digest()
        self.encrypted_send_pub_key = utils.int_to_bytes(pub_key.public_numbers().x, 32) + utils.int_to_bytes(pub_key.public_numbers().y, 32)
Exemplo n.º 26
0
def dh_message(private_secret: dh.DHPublicNumbers) -> bytes:
    """
    Generate the public part, a message to be sent to the other party.
    """
    gx = pow(private_secret.parameter_numbers.g, private_secret.y,
             private_secret.parameter_numbers.p)
    return utils.int_to_bytes(gx)
Exemplo n.º 27
0
def dh_message(private_secret: dh.DHPublicNumbers) -> bytes:
    """
    Generate the public part, a message to be sent to the other party.
    """
    gx = pow(private_secret.parameter_numbers.g, private_secret.y,
            private_secret.parameter_numbers.p)
    return utils.int_to_bytes(gx)
Exemplo n.º 28
0
    def to_map(self):
        jwk = {
            'kty': self.key_type(),
            'kid': self.key_id(),
            'crv': self.curve_name,
        }
        x_bytes = cry_utils.int_to_bytes(self.numbers.x)
        y_bytes = cry_utils.int_to_bytes(self.numbers.y)
        octet_length = (self.curve.bit_size() + 7) >> 3

        x_bytes = b'\x00' * (octet_length - len(x_bytes)) + x_bytes
        y_bytes = b'\x00' * (octet_length - len(y_bytes)) + y_bytes

        jwk['x'] = util.jose_base64_url_encode(x_bytes).decode('utf-8')
        jwk['y'] = util.jose_base64_url_encode(y_bytes).decode('utf-8')
        return jwk
Exemplo n.º 29
0
def _key_identifier_from_public_key(public_key):
    if isinstance(public_key, RSAPublicKey):
        data = public_key.public_bytes(
            serialization.Encoding.DER,
            serialization.PublicFormat.PKCS1,
        )
    elif isinstance(public_key, EllipticCurvePublicKey):
        data = public_key.public_numbers().encode_point()
    else:
        # This is a very slow way to do this.
        serialized = public_key.public_bytes(
            serialization.Encoding.DER,
            serialization.PublicFormat.SubjectPublicKeyInfo
        )
        spki, remaining = decoder.decode(
            serialized, asn1Spec=_SubjectPublicKeyInfo()
        )
        assert not remaining
        # the univ.BitString object is a tuple of bits. We need bytes and
        # pyasn1 really doesn't want to give them to us. To get it we'll
        # build an integer and convert that to bytes.
        bits = 0
        for bit in spki.getComponentByName("subjectPublicKey"):
            bits = bits << 1 | bit

        data = utils.int_to_bytes(bits)

    return hashlib.sha1(data).digest()
Exemplo n.º 30
0
    def _generate_fixed_input(self):
        if self._fixed_data and isinstance(self._fixed_data, bytes):
            return self._fixed_data

        l = utils.int_to_bytes(self._length * 8, self._llen)

        return b"".join([self._label, b"\x00", self._context, l])
Exemplo n.º 31
0
 def _get_key_attributes(self, key):
     if isinstance(key, rsa.RSAPrivateKey):
         return struct.pack('>BHHB', 0x01, key.key_size, 32, 0)
     if isinstance(key, ec.EllipticCurvePrivateKey):
         return int_to_bytes(self._get_opgp_algo_id_from_ec(key)) + a2b_hex(
             self._get_oid_from_ec(key))
     raise ValueError('Not a valid private key!')
Exemplo n.º 32
0
 def to_map(self):
     return {
         'kty': self.key_type(),
         'kid': self.key_id(),
         'n': util.jose_base64_url_encode(cry_utils.int_to_bytes(self.numbers.n)).decode('utf-8'),
         'e': util.jose_base64_url_encode(util.serialize_rsa_public_exponent_param(self.numbers.e)).decode('utf-8')
     }
Exemplo n.º 33
0
    def _generate_fixed_input(self) -> bytes:
        if self._fixed_data and isinstance(self._fixed_data, bytes):
            return self._fixed_data

        l_val = utils.int_to_bytes(self._length * 8, self._llen)

        return b"".join([self._label, b"\x00", self._context, l_val])
Exemplo n.º 34
0
def encode_der_integer(x):
    if not isinstance(x, int):
        raise ValueError("Value must be an integer")
    if x < 0:
        raise ValueError("Negative integers are not supported")
    n = x.bit_length() // 8 + 1
    return int_to_bytes(x, n)
Exemplo n.º 35
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()
Exemplo n.º 36
0
def number_as_bytes(number, pad_bits=None):
    """
    Given a number, format as a little endian array of bytes
    """
    result = int_to_bytes(number)[::-1]
    while pad_bits is not None and len(result) < (pad_bits // 8):
        result += b'\x00'
    return result
Exemplo n.º 37
0
def _to_mpint(val):
    """Storage format for signed bigint."""
    if val < 0:
        raise ValueError("negative mpint not allowed")
    if not val:
        return b""
    nbytes = (val.bit_length() + 8) // 8
    return utils.int_to_bytes(val, nbytes)
Exemplo n.º 38
0
def MP(number):
    if number == 0:
        return b'\000' * 4
    assert number > 0
    bn = int_to_bytes(number)
    if ord(bn[0:1]) & 128:
        bn = b'\000' + bn
    return struct.pack('>L', len(bn)) + bn
Exemplo n.º 39
0
    def _valid_byte_length(self, value):
        if not isinstance(value, int):
            raise TypeError('value must be of type int')

        value_bin = utils.int_to_bytes(1, value)
        if not 1 <= len(value_bin) <= 4:
            return False
        return True
Exemplo n.º 40
0
    def load_rsa_public_numbers(self, numbers):
        rsa._check_public_key_components(numbers.e, numbers.n)

        attrs = build_attributes([
            (self._binding.CKA_TOKEN, False),  # don't persist it
            (self._binding.CKA_CLASS, self._binding.CKO_PUBLIC_KEY),
            (self._binding.CKA_KEY_TYPE, self._binding.CKK_RSA),
            (self._binding.CKA_MODULUS, utils.int_to_bytes(numbers.n)),
            (self._binding.CKA_PUBLIC_EXPONENT, utils.int_to_bytes(numbers.e)),
        ], self)

        session = self._session_pool.acquire()
        # TODO: do we want to delete the object from the session when it
        # is no longer in scope?
        object_handle = self._ffi.new("CK_OBJECT_HANDLE *")
        res = self._lib.C_CreateObject(
            session[0], attrs.template, len(attrs.template), object_handle
        )
        self._check_error(res)

        return _RSAPublicKey(self, object_handle[0])
Exemplo n.º 41
0
    def generate_rsa_private_key(self, public_exponent, key_size):
        # TODO: we need to be able to pass templates in. right now all keys
        # are generated as session only and exportable. And this is all
        # untested so far
        session = self._session_pool.acquire()
        public_handle = self._ffi.new("CK_OBJECT_HANDLE *")
        private_handle = self._ffi.new("CK_OBJECT_HANDLE *")
        mech = self._ffi.new("CK_MECHANISM *")
        mech.mechanism = self._binding.CKM_RSA_PKCS_KEY_PAIR_GEN
        pub_attrs = build_attributes([
            (
                self._binding.CKA_PUBLIC_EXPONENT,
                utils.int_to_bytes(public_exponent)
            ),
            (self._binding.CKA_MODULUS_BITS, key_size),
            (self._binding.CKA_TOKEN, False),  # don't persist it
            (self._binding.CKA_PRIVATE, False),
            (self._binding.CKA_ENCRYPT, True),
            (self._binding.CKA_VERIFY, True),
        ], self)
        priv_attrs = build_attributes([
            (self._binding.CKA_TOKEN, False),  # don't persist it
            (self._binding.CKA_PRIVATE, False),
            (self._binding.CKA_DECRYPT, True),
            (self._binding.CKA_SIGN, True),
            (self._binding.CKA_EXTRACTABLE, True)
        ], self)
        # TODO: remember that you can get the public key values from
        # CKA_MODULUS and CKA_PUBLIC_EXPONENT. but you can't perform
        # operations on them so we probably still need to think of these as
        # keypairs
        res = self._lib.C_GenerateKeyPair(
            session[0], mech, pub_attrs.template, len(pub_attrs.template),
            priv_attrs.template, len(priv_attrs.template), public_handle,
            private_handle
        )
        self._check_error(res)

        return _RSAPrivateKey(self, private_handle[0])
Exemplo n.º 42
0
def _get_key_data(key):
    if isinstance(key, rsa.RSAPrivateKey):
        if key.public_key().public_numbers().e != 65537:
            raise UnsupportedAlgorithm(
                'Unsupported RSA exponent: %d'
                % key.public_key().public_numbers().e,
                key=key)

        if key.key_size == 1024:
            algo = ALGO.RSA1024
            ln = 64
        elif key.key_size == 2048:
            algo = ALGO.RSA2048
            ln = 128
        else:
            raise UnsupportedAlgorithm(
                'Unsupported RSA key size: %d' % key.key_size, key=key)

        priv = key.private_numbers()
        data = Tlv(0x01, int_to_bytes(priv.p, ln)) + \
            Tlv(0x02, int_to_bytes(priv.q, ln)) + \
            Tlv(0x03, int_to_bytes(priv.dmp1, ln)) + \
            Tlv(0x04, int_to_bytes(priv.dmq1, ln)) + \
            Tlv(0x05, int_to_bytes(priv.iqmp, ln))
    elif isinstance(key, ec.EllipticCurvePrivateKey):
        if isinstance(key.curve, ec.SECP256R1):
            algo = ALGO.ECCP256
            ln = 32
        elif isinstance(key.curve, ec.SECP384R1):
            algo = ALGO.ECCP384
            ln = 48
        else:
            raise UnsupportedAlgorithm(
                    'Unsupported elliptic curve: %s', key.curve, key=key)
        priv = key.private_numbers()
        data = Tlv(0x06, int_to_bytes(priv.private_value, ln))
    else:
        raise UnsupportedAlgorithm('Unsupported key type!', key=key)
    return algo, data
Exemplo n.º 43
0
 def _der_to_raw(self, der_signature):
     """Convert signature from DER encoding to RAW encoding."""
     r, s = decode_dss_signature(der_signature)
     component_length = self._sig_component_length()
     return int_to_bytes(r, component_length) + int_to_bytes(s, component_length)
Exemplo n.º 44
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())
Exemplo n.º 45
0
def _encode_general_name(backend, name):
    if isinstance(name, x509.DNSName):
        gn = backend._lib.GENERAL_NAME_new()
        backend.openssl_assert(gn != backend._ffi.NULL)
        gn.type = backend._lib.GEN_DNS

        ia5 = backend._lib.ASN1_IA5STRING_new()
        backend.openssl_assert(ia5 != backend._ffi.NULL)
        # ia5strings are supposed to be ITU T.50 but to allow round-tripping
        # of broken certs that encode utf8 we'll encode utf8 here too.
        value = name.value.encode("utf8")

        res = backend._lib.ASN1_STRING_set(ia5, value, len(value))
        backend.openssl_assert(res == 1)
        gn.d.dNSName = ia5
    elif isinstance(name, x509.RegisteredID):
        gn = backend._lib.GENERAL_NAME_new()
        backend.openssl_assert(gn != backend._ffi.NULL)
        gn.type = backend._lib.GEN_RID
        obj = backend._lib.OBJ_txt2obj(
            name.value.dotted_string.encode('ascii'), 1
        )
        backend.openssl_assert(obj != backend._ffi.NULL)
        gn.d.registeredID = obj
    elif isinstance(name, x509.DirectoryName):
        gn = backend._lib.GENERAL_NAME_new()
        backend.openssl_assert(gn != backend._ffi.NULL)
        dir_name = _encode_name(backend, name.value)
        gn.type = backend._lib.GEN_DIRNAME
        gn.d.directoryName = dir_name
    elif isinstance(name, x509.IPAddress):
        gn = backend._lib.GENERAL_NAME_new()
        backend.openssl_assert(gn != backend._ffi.NULL)
        if isinstance(name.value, ipaddress.IPv4Network):
            packed = (
                name.value.network_address.packed +
                utils.int_to_bytes(((1 << 32) - name.value.num_addresses), 4)
            )
        elif isinstance(name.value, ipaddress.IPv6Network):
            packed = (
                name.value.network_address.packed +
                utils.int_to_bytes((1 << 128) - name.value.num_addresses, 16)
            )
        else:
            packed = name.value.packed
        ipaddr = _encode_asn1_str(backend, packed, len(packed))
        gn.type = backend._lib.GEN_IPADD
        gn.d.iPAddress = ipaddr
    elif isinstance(name, x509.OtherName):
        gn = backend._lib.GENERAL_NAME_new()
        backend.openssl_assert(gn != backend._ffi.NULL)
        other_name = backend._lib.OTHERNAME_new()
        backend.openssl_assert(other_name != backend._ffi.NULL)

        type_id = backend._lib.OBJ_txt2obj(
            name.type_id.dotted_string.encode('ascii'), 1
        )
        backend.openssl_assert(type_id != backend._ffi.NULL)
        data = backend._ffi.new("unsigned char[]", name.value)
        data_ptr_ptr = backend._ffi.new("unsigned char **")
        data_ptr_ptr[0] = data
        value = backend._lib.d2i_ASN1_TYPE(
            backend._ffi.NULL, data_ptr_ptr, len(name.value)
        )
        if value == backend._ffi.NULL:
            backend._consume_errors()
            raise ValueError("Invalid ASN.1 data")
        other_name.type_id = type_id
        other_name.value = value
        gn.type = backend._lib.GEN_OTHERNAME
        gn.d.otherName = other_name
    elif isinstance(name, x509.RFC822Name):
        gn = backend._lib.GENERAL_NAME_new()
        backend.openssl_assert(gn != backend._ffi.NULL)
        # ia5strings are supposed to be ITU T.50 but to allow round-tripping
        # of broken certs that encode utf8 we'll encode utf8 here too.
        data = name.value.encode("utf8")
        asn1_str = _encode_asn1_str(backend, data, len(data))
        gn.type = backend._lib.GEN_EMAIL
        gn.d.rfc822Name = asn1_str
    elif isinstance(name, x509.UniformResourceIdentifier):
        gn = backend._lib.GENERAL_NAME_new()
        backend.openssl_assert(gn != backend._ffi.NULL)
        # ia5strings are supposed to be ITU T.50 but to allow round-tripping
        # of broken certs that encode utf8 we'll encode utf8 here too.
        data = name.value.encode("utf8")
        asn1_str = _encode_asn1_str(backend, data, len(data))
        gn.type = backend._lib.GEN_URI
        gn.d.uniformResourceIdentifier = asn1_str
    else:
        raise ValueError(
            "{0} is an unknown GeneralName type".format(name)
        )

    return gn
Exemplo n.º 46
0
def _ssh_write_mpint(value):
    data = utils.int_to_bytes(value)
    if six.indexbytes(data, 0) & 0x80:
        data = b"\x00" + data
    return _ssh_write_string(data)