def test_wrapped_encrypt_decrypt_two_keys(self, input_stream_factory):
        template = (streaming_aead.streaming_aead_key_templates.
                    AES128_CTR_HMAC_SHA256_4KB)
        old_keyset = tink_pb2.Keyset()
        key1 = old_keyset.key.add()
        key1.key_data.CopyFrom(tink.core.Registry.new_key_data(template))
        key1.status = tink_pb2.ENABLED
        key1.key_id = 1234
        key1.output_prefix_type = template.output_prefix_type
        old_keyset.primary_key_id = key1.key_id
        old_keyset_handle = cleartext_keyset_handle.from_keyset(old_keyset)
        old_primitive = old_keyset_handle.primitive(
            streaming_aead.StreamingAead)

        new_keyset = tink_pb2.Keyset()
        new_keyset.CopyFrom(old_keyset)
        key2 = new_keyset.key.add()
        key2.key_data.CopyFrom(tink.core.Registry.new_key_data(template))
        key2.status = tink_pb2.ENABLED
        key2.key_id = 5678
        key2.output_prefix_type = template.output_prefix_type
        new_keyset.primary_key_id = key2.key_id
        new_keyset_handle = cleartext_keyset_handle.from_keyset(new_keyset)
        new_primitive = new_keyset_handle.primitive(
            streaming_aead.StreamingAead)

        plaintext1 = b' '.join(b'%d' % i for i in range(100 * 1000))
        ciphertext1_dest = bytes_io.BytesIOWithValueAfterClose()
        with old_primitive.new_encrypting_stream(ciphertext1_dest,
                                                 b'aad1') as es:
            es.write(plaintext1)
        ciphertext1 = ciphertext1_dest.value_after_close()

        plaintext2 = b' '.join(b'%d' % i for i in range(100 * 1001))
        ciphertext2_dest = bytes_io.BytesIOWithValueAfterClose()
        with new_primitive.new_encrypting_stream(ciphertext2_dest,
                                                 b'aad2') as es:
            es.write(plaintext2)
        ciphertext2 = ciphertext2_dest.value_after_close()

        # old_primitive can read 1st ciphertext, but not the 2nd
        with old_primitive.new_decrypting_stream(
                cast(BinaryIO, input_stream_factory(ciphertext1)),
                b'aad1') as ds:
            self.assertEqual(ds.read(), plaintext1)
        with old_primitive.new_decrypting_stream(
                cast(BinaryIO, input_stream_factory(ciphertext2)),
                b'aad2') as ds:
            with self.assertRaises(tink.TinkError):
                ds.read()

        # new_primitive can read both ciphertexts
        with new_primitive.new_decrypting_stream(
                cast(BinaryIO, input_stream_factory(ciphertext1)),
                b'aad1') as ds:
            self.assertEqual(ds.read(), plaintext1)
        with new_primitive.new_decrypting_stream(
                cast(BinaryIO, input_stream_factory(ciphertext2)),
                b'aad2') as ds:
            self.assertEqual(ds.read(), plaintext2)
def _set_custom_kid(keyset_handle: tink.KeysetHandle,
                    custom_kid: str) -> tink.KeysetHandle:
  """Sets the custom_kid field of the first key."""
  buffer = io.BytesIO()
  cleartext_keyset_handle.write(
      tink.BinaryKeysetWriter(buffer), keyset_handle)
  keyset = tink_pb2.Keyset.FromString(buffer.getvalue())
  if keyset.key[0].key_data.type_url.endswith('JwtEcdsaPrivateKey'):
    jwt_ecdsa_key = jwt_ecdsa_pb2.JwtEcdsaPrivateKey.FromString(
        keyset.key[0].key_data.value)
    jwt_ecdsa_key.public_key.custom_kid.value = custom_kid
    keyset.key[0].key_data.value = jwt_ecdsa_key.SerializeToString()
  elif keyset.key[0].key_data.type_url.endswith('JwtRsaSsaPkcs1PrivateKey'):
    rsa_key = jwt_rsa_ssa_pkcs1_pb2.JwtRsaSsaPkcs1PrivateKey.FromString(
        keyset.key[0].key_data.value)
    rsa_key.public_key.custom_kid.value = custom_kid
    keyset.key[0].key_data.value = rsa_key.SerializeToString()
  elif keyset.key[0].key_data.type_url.endswith('JwtRsaSsaPssPrivateKey'):
    rsa_key = jwt_rsa_ssa_pss_pb2.JwtRsaSsaPssPrivateKey.FromString(
        keyset.key[0].key_data.value)
    rsa_key.public_key.custom_kid.value = custom_kid
    keyset.key[0].key_data.value = rsa_key.SerializeToString()
  else:
    raise tink.TinkError('unknown key type')
  return cleartext_keyset_handle.from_keyset(keyset)
예제 #3
0
 def test_from_keyset(self):
     handle = tink.new_keyset_handle(
         mac.mac_key_templates.HMAC_SHA256_128BITTAG)
     keyset = handle._keyset
     handle2 = cleartext_keyset_handle.from_keyset(keyset)
     # Check that handle2 has the same primitive as handle.
     handle2.primitive(mac.Mac).verify_mac(
         handle.primitive(mac.Mac).compute_mac(b'data'), b'data')
def _change_output_prefix_to_tink(
    keyset_handle: tink.KeysetHandle) -> tink.KeysetHandle:
  """Changes the output prefix type of the first key to TINK."""
  buffer = io.BytesIO()
  cleartext_keyset_handle.write(
      tink.BinaryKeysetWriter(buffer), keyset_handle)
  keyset = tink_pb2.Keyset.FromString(buffer.getvalue())
  keyset.key[0].output_prefix_type = tink_pb2.TINK
  return cleartext_keyset_handle.from_keyset(keyset)
def _change_key_id(keyset_handle: tink.KeysetHandle) -> tink.KeysetHandle:
  """Changes the key id of the first key and makes it primary."""
  buffer = io.BytesIO()
  cleartext_keyset_handle.write(
      tink.BinaryKeysetWriter(buffer), keyset_handle)
  keyset = tink_pb2.Keyset.FromString(buffer.getvalue())
  # XOR the key id with an arbitrary 32-bit string to get a new key id.
  new_key_id = keyset.key[0].key_id ^ 0xdeadbeef
  keyset.key[0].key_id = new_key_id
  keyset.primary_key_id = new_key_id
  return cleartext_keyset_handle.from_keyset(keyset)
예제 #6
0
def _set_custom_kid(keyset_handle: tink.KeysetHandle,
                    custom_kid: str) -> tink.KeysetHandle:
    """Set the custom_kid field of the first key."""
    buffer = io.BytesIO()
    cleartext_keyset_handle.write(tink.BinaryKeysetWriter(buffer),
                                  keyset_handle)
    keyset = tink_pb2.Keyset.FromString(buffer.getvalue())
    hmac_key = jwt_hmac_pb2.JwtHmacKey.FromString(keyset.key[0].key_data.value)
    hmac_key.custom_kid.value = custom_kid
    keyset.key[0].key_data.value = hmac_key.SerializeToString()
    return cleartext_keyset_handle.from_keyset(keyset)
예제 #7
0
def _mac() -> mac.Mac:
  hmac_key = hmac_pb2.HmacKey(
      version=0, key_value=base64.urlsafe_b64decode(KEY_VALUE))
  hmac_key.params.hash = common_pb2.SHA256
  hmac_key.params.tag_size = 32
  keyset = tink_pb2.Keyset()
  key = keyset.key.add()
  key.key_data.type_url = ('type.googleapis.com/google.crypto.tink.HmacKey')
  key.key_data.value = hmac_key.SerializeToString()
  key.key_data.key_material_type = tink_pb2.KeyData.SYMMETRIC
  key.status = tink_pb2.ENABLED
  key.key_id = 123
  key.output_prefix_type = tink_pb2.RAW
  keyset.primary_key_id = 123
  keyset_handle = cleartext_keyset_handle.from_keyset(keyset)
  return keyset_handle.primitive(mac.Mac)
예제 #8
0
def to_public_keyset_handle(jwk_set: str) -> tink.KeysetHandle:
    """Converts a Json Web Key (JWK) set into a Tink KeysetHandle with JWT keys.

  JWK is defined in https://www.rfc-editor.org/rfc/rfc7517.txt.

  All keys are converted into Tink keys with output prefix type "RAW".

  Currently, public keys for algorithms ES256, ES384, ES512, RS256, RS384,
  RS512, PS256, PS384 and PS512 supported.

  Args:
    jwk_set: A JWK set, which is a JSON encoded string.

  Returns:
    A tink.KeysetHandle.

  Raises:
    TinkError if the key cannot be converted.
  """
    try:
        keys_dict = json.loads(jwk_set)
    except json.decoder.JSONDecodeError as e:
        raise tink.TinkError('error parsing JWK set: %s' % e.msg)
    if 'keys' not in keys_dict:
        raise tink.TinkError('invalid JWK set: keys not found')
    proto_keyset = tink_pb2.Keyset()
    for key in keys_dict['keys']:
        if 'alg' not in key:
            raise tink.TinkError('invalid JWK: alg not found')
        alg = key['alg']
        if alg.startswith('ES'):
            proto_key = _convert_to_ecdsa_key(key)
        elif alg.startswith('RS'):
            proto_key = _convert_to_rsa_ssa_pkcs1_key(key)
        elif alg.startswith('PS'):
            proto_key = _convert_to_rsa_ssa_pss_key(key)
        else:
            raise tink.TinkError('unknown alg')
        new_id = _generate_unused_key_id(proto_keyset)
        proto_key.key_id = new_id
        proto_keyset.key.append(proto_key)
        # JWK sets do not really have a primary key (see RFC 7517, Section 5.1).
        # To verify signature, it also does not matter which key is primary. We
        # simply set it to the last key.
        proto_keyset.primary_key_id = new_id
    return cleartext_keyset_handle.from_keyset(proto_keyset)
예제 #9
0
 def keyset_handle(self) -> tink.KeysetHandle:
     keyset_copy = tink_pb2.Keyset()
     keyset_copy.CopyFrom(self._keyset)
     return cleartext_keyset_handle.from_keyset(keyset_copy)
예제 #10
0
def generate_keyset_handle(key_template) -> tink.KeysetHandle:
    """Generates a keyset handle from a key templates."""
    return cleartext_keyset_handle.from_keyset(generate_keyset(key_template))