def test_generate_new_key_id_is_randomized(self): handle1 = tink.new_keyset_handle( mac.mac_key_templates.HMAC_SHA256_128BITTAG) handle2 = tink.new_keyset_handle( mac.mac_key_templates.HMAC_SHA256_128BITTAG) self.assertNotEqual(handle1.keyset_info().key_info[0].key_id, handle2.keyset_info().key_info[0].key_id)
def test_new_keyset_handle_invalid_aead_raises_exception(self): templates = hybrid.hybrid_key_templates key_template = templates._create_hpke_key_template( hpke_kem=hpke_pb2.DHKEM_X25519_HKDF_SHA256, hpke_kdf=hpke_pb2.HKDF_SHA256, hpke_aead=hpke_pb2.AEAD_UNKNOWN) with self.assertRaises(core.TinkError): tink.new_keyset_handle(key_template)
def test_invalid_params_throw_exception_aes_ctr_hmac_aead(self): template = aead.aead_key_templates.create_aes_ctr_hmac_aead_key_template( aes_key_size=42, iv_size=16, hmac_key_size=32, tag_size=32, hash_type=common_pb2.SHA256) with self.assertRaises(tink.TinkError): tink.new_keyset_handle(template)
def test_new_keyset_handle_on_public_key_fails(self): key_format = ecies_aead_hkdf_pb2.EciesAeadHkdfKeyFormat() key_template = tink_pb2.KeyTemplate() key_template.type_url = ( 'type.googleapis.com/google.crypto.tink.EciesAeadHkdfPublicKey') key_template.value = key_format.SerializeToString() key_template.output_prefix_type = tink_pb2.TINK with self.assertRaises(core.TinkError): tink.new_keyset_handle(key_template)
def test_new_keyset_handle_invalid_kdf_raises_exception(self): templates = hybrid.hybrid_key_templates key_template = templates._create_hpke_key_template( hpke_kem=hpke_pb2.DHKEM_X25519_HKDF_SHA256, hpke_kdf=hpke_pb2.KDF_UNKNOWN, hpke_aead=hpke_pb2.AES_128_GCM, output_prefix_type=tink_pb2.TINK) with self.assertRaises(core.TinkError): tink.new_keyset_handle(key_template)
def test_new_keyset_handle_invalid_params_throw_exception(self): templates = hybrid.hybrid_key_templates key_template = templates.create_ecies_aead_hkdf_key_template( curve_type=cast(common_pb2.EllipticCurveType, 100), ec_point_format=common_pb2.UNCOMPRESSED, hash_type=common_pb2.SHA256, dem_key_template=aead.aead_key_templates.AES128_GCM) with self.assertRaises(core.TinkError): tink.new_keyset_handle(key_template)
def test_verify_unknown_mac_fails(self, template): unknown_handle = tink.new_keyset_handle(template) unknown_primitive = unknown_handle.primitive(mac.Mac) unknown_tag = unknown_primitive.compute_mac(b'data') keyset_handle = tink.new_keyset_handle(template) primitive = keyset_handle.primitive(mac.Mac) with self.assertRaises(tink.TinkError): primitive.verify_mac(unknown_tag, b'data')
def test_new_public_keyset_handle_fails(self): params = ecdsa_pb2.EcdsaParams(hash_type=common_pb2.SHA256, curve=common_pb2.NIST_P256, encoding=ecdsa_pb2.DER) key_format = ecdsa_pb2.EcdsaKeyFormat(params=params) template = tink_pb2.KeyTemplate() template.type_url = 'type.googleapis.com/google.crypto.tink.EcdsaPublicKey' template.value = key_format.SerializeToString() with self.assertRaises(core.TinkError): tink.new_keyset_handle(template)
def test_decrypt_unknown_ciphertext_fails(self, template): unknown_private_handle = tink.new_keyset_handle(template) unknown_public_handle = unknown_private_handle.public_keyset_handle() unknown_enc = unknown_public_handle.primitive(hybrid.HybridEncrypt) unknown_ciphertext = unknown_enc.encrypt(b'plaintext', b'context') private_handle = tink.new_keyset_handle(template) hybrid_dec = private_handle.primitive(hybrid.HybridDecrypt) with self.assertRaises(core.TinkError): hybrid_dec.decrypt(unknown_ciphertext, b'context')
def test_create_ecdsa_handle_with_invalid_algorithm_fails(self): key_format = jwt_ecdsa_pb2.JwtEcdsaKeyFormat( algorithm=jwt_ecdsa_pb2.ES_UNKNOWN) template = tink_pb2.KeyTemplate( type_url= 'type.googleapis.com/google.crypto.tink.JwtEcdsaPrivateKey', value=key_format.SerializeToString(), output_prefix_type=tink_pb2.RAW) with self.assertRaises(tink.TinkError): tink.new_keyset_handle(template)
def test_verify_fails_on_unknown_signature(self, template): unknown_handle = tink.new_keyset_handle(template) unknown_sign_primitive = unknown_handle.primitive(signature.PublicKeySign) unknown_data_signature = unknown_sign_primitive.sign(b'data') private_handle = tink.new_keyset_handle(template) public_handle = private_handle.public_keyset_handle() verify_primitive = public_handle.primitive(signature.PublicKeyVerify) with self.assertRaises(tink.TinkError): verify_primitive.verify(unknown_data_signature, b'data')
def test_decrypt_unknown_ciphertext_fails(self, template): unknown_handle = tink.new_keyset_handle(template) unknown_primitive = unknown_handle.primitive(aead.Aead) unknown_ciphertext = unknown_primitive.encrypt(b'plaintext', b'associated_data') keyset_handle = tink.new_keyset_handle(template) primitive = keyset_handle.primitive(aead.Aead) with self.assertRaises(tink.TinkError): primitive.decrypt(unknown_ciphertext, b'associated_data')
def test_verify_with_other_key_fails(self): handle = tink.new_keyset_handle(jwt.jwt_es256_template()) sign = handle.primitive(jwt.JwtPublicKeySign) raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True) compact = sign.sign_and_encode(raw_jwt) other_handle = tink.new_keyset_handle(jwt.jwt_es256_template()) other_verify = other_handle.public_keyset_handle().primitive( jwt.JwtPublicKeyVerify) with self.assertRaises(tink.TinkError): other_verify.verify_and_decode( compact, jwt.new_validator(expected_issuer='issuer', allow_missing_expiration=True))
def test_aead_encrypt_decrypt(self): keyset_handle = tink.new_keyset_handle( aead.aead_key_templates.AES256_GCM) primitive = keyset_handle.primitive(aead.Aead) self.assertEqual( primitive.decrypt(primitive.encrypt(b'plaintext', b'ad'), b'ad'), b'plaintext')
def generate_jwt_signature_keyset_with_custom_kid( template_name: str, custom_kid: str) -> tink_pb2.Keyset: key_template = supported_key_types.KEY_TEMPLATE[template_name] keyset_handle = tink.new_keyset_handle(key_template) # parse key_data.value, set custom_kid and serialize key_data_value = keyset_handle._keyset.key[0].key_data.value if template_name.startswith('JWT_ES256'): private_key = jwt_ecdsa_pb2.JwtEcdsaPrivateKey.FromString( key_data_value) private_key.public_key.custom_kid.value = custom_kid key_data_value = private_key.SerializeToString() elif template_name.startswith('JWT_RS256'): private_key = jwt_rsa_ssa_pkcs1_pb2.JwtRsaSsaPkcs1PrivateKey.FromString( key_data_value) private_key.public_key.custom_kid.value = custom_kid key_data_value = private_key.SerializeToString() elif template_name.startswith('JWT_PS256'): private_key = jwt_rsa_ssa_pss_pb2.JwtRsaSsaPssPrivateKey.FromString( key_data_value) private_key.public_key.custom_kid.value = custom_kid key_data_value = private_key.SerializeToString() else: raise ValueError('unknown template name') keyset_handle._keyset.key[0].key_data.value = key_data_value keyset = keyset_handle._keyset return keyset
def test_only_tink_output_prefix_type_encodes_a_kid_header(self): handle = tink.new_keyset_handle(jwt.raw_jwt_hs256_template()) jwt_mac = handle.primitive(jwt.JwtMac) tink_handle = _change_output_prefix_to_tink(handle) tink_jwt_mac = tink_handle.primitive(jwt.JwtMac) raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True) token = jwt_mac.compute_mac_and_encode(raw_jwt) token_with_kid = tink_jwt_mac.compute_mac_and_encode(raw_jwt) _, header, _, _ = _jwt_format.split_signed_compact(token) self.assertNotIn('kid', _json_util.json_loads(header)) _, header_with_kid, _, _ = _jwt_format.split_signed_compact( token_with_kid) self.assertIn('kid', _json_util.json_loads(header_with_kid)) validator = jwt.new_validator(expected_issuer='issuer', allow_missing_expiration=True) jwt_mac.verify_mac_and_decode(token, validator) tink_jwt_mac.verify_mac_and_decode(token_with_kid, validator) # With output prefix type RAW, a kid header is ignored jwt_mac.verify_mac_and_decode(token_with_kid, validator) # With output prefix type TINK, a kid header is required. with self.assertRaises(tink.TinkError): tink_jwt_mac.verify_mac_and_decode(token, validator) other_handle = _change_key_id(tink_handle) other_jwt_mac = other_handle.primitive(jwt.JwtMac) # A token with a wrong kid is rejected, even if the signature is ok. with self.assertRaises(tink.TinkError): other_jwt_mac.verify_mac_and_decode(token_with_kid, validator)
def test_ps256_key_with_a_custom_kid_header(self): keyset_handle = tink.new_keyset_handle( jwt.raw_jwt_ps256_2048_f4_template()) # Add a custom kid to the key in keyset_handle value = keyset_handle._keyset.key[0].key_data.value pss_key = jwt_rsa_ssa_pss_pb2.JwtRsaSsaPssPrivateKey.FromString(value) pss_key.public_key.custom_kid.value = 'my kid' keyset_handle._keyset.key[ 0].key_data.value = pss_key.SerializeToString() sign = keyset_handle.primitive(jwt.JwtPublicKeySign) raw_jwt = jwt.new_raw_jwt(issuer='issuer', without_expiration=True) signed_compact = sign.sign_and_encode(raw_jwt) _, json_header, _, _ = _jwt_format.split_signed_compact(signed_compact) header = _jwt_format.json_loads(json_header) self.assertEqual(header['kid'], 'my kid') # Now, change the output prefix type to TINK. This should fail. keyset_handle._keyset.key[0].output_prefix_type = tink_pb2.TINK with self.assertRaises(tink.TinkError): tink_sign = keyset_handle.primitive(jwt.JwtPublicKeySign) tink_sign.sign_and_encode(raw_jwt)
def test_decrypt_wrong_associated_data_fails(self, template): keyset_handle = tink.new_keyset_handle(template) primitive = keyset_handle.primitive(aead.Aead) ciphertext = primitive.encrypt(b'plaintext', b'associated_data') with self.assertRaises(tink.TinkError): primitive.decrypt(ciphertext, b'wrong_associated_data')
def __init__(self, encoded_key=None): if encoded_key == None: self.keyset_handle = tink.new_keyset_handle(mac.mac_key_templates.HMAC_SHA256_256BITTAG) else: reader = tink.BinaryKeysetReader(base64.b64decode(encoded_key)) self.keyset_handle = cleartext_keyset_handle.read(reader) self.mac = self.keyset_handle.primitive(mac.Mac)
def test_verify_short_mac_fails(self, template): keyset_handle = tink.new_keyset_handle(template) primitive = keyset_handle.primitive(mac.Mac) with self.assertRaises(tink.TinkError): primitive.verify_mac(b'', b'data') with self.assertRaises(tink.TinkError): primitive.verify_mac(b'tag', b'data')
def test_mac_compute_verify(self): keyset_handle = tink.new_keyset_handle( mac.mac_key_templates.HMAC_SHA256_128BITTAG) primitive = keyset_handle.primitive(mac.Mac) mac_value = primitive.compute_mac(b'data') self.assertIsNone(primitive.verify_mac(mac_value, b'data')) self.assertEqual(primitive.compute_mac(b'data'), mac_value)
def test_encrypt_decrypt_success(self, template): keyset_handle = tink.new_keyset_handle(template) primitive = keyset_handle.primitive(aead.Aead) plaintext = b'plaintext' associated_data = b'associated_data' ciphertext = primitive.encrypt(plaintext, associated_data) self.assertEqual(primitive.decrypt(ciphertext, associated_data), plaintext)
def test_invalid_decrypt_raises_error(self, lang): private_keyset_handle = tink.new_keyset_handle( signature.signature_key_templates.ECDSA_P256) public_keyset_handle = private_keyset_handle.public_keyset_handle() verifier = cli_signature.CliPublicKeyVerify(lang, public_keyset_handle) with self.assertRaises(tink.TinkError): verifier.verify(b'invalid signature', b'message')
def test_invalid_decrypt_raises_error(self, lang): keyset_handle = tink.new_keyset_handle( daead.deterministic_aead_key_templates.AES256_SIV) p = cli_daead.CliDeterministicAead(lang, keyset_handle) with self.assertRaises(tink.TinkError): p.decrypt_deterministically(b'invalid ciphertext', b'associated_data')
def test_invalid_decrypt_raises_error(self): keyset_handle = tink.new_keyset_handle( daead.deterministic_aead_key_templates.AES256_SIV) daead_primitive = keyset_handle.primitive(daead.DeterministicAead) with self.assertRaises(core.TinkError): daead_primitive.decrypt_deterministically(b'bad ciphertext', b'associated_data')
def __init__(self, key_uri, creds, tmp_location=_TMP_LOCATION): """Init class for EncryptWithTink. Args: key_uri: string with the resource identifier for the KMS symmetric key creds: path to the creds.json file with the service account key for KMS tmp_location: temporary directory for encryption and decryption Returns: None """ self.tmp_location = tmp_location # Make the tmp dir if it doesn't exist if not os.path.isdir(self.tmp_location): # noinspection PyUnusedLocal try: os.makedirs(self.tmp_location) except FileExistsError: # This is ok because the directory already exists pass except OSError as os_error: error_and_exit(str(os_error)) # Initialize Tink try: aead.register() self.key_template = aead.aead_key_templates.AES128_EAX self.keyset_handle = tink.new_keyset_handle(self.key_template) gcp_client = gcpkms.GcpKmsClient(key_uri, creds) gcp_aead = gcp_client.get_aead(key_uri) self.env_aead = aead.KmsEnvelopeAead(self.key_template, gcp_aead) except TinkError as tink_init_error: error_and_exit('tink initialization failed: ' + str(tink_init_error))
def test_sign_verify(self, template): private_handle = tink.new_keyset_handle(template) public_handle = private_handle.public_keyset_handle() sign_primitive = private_handle.primitive(signature.PublicKeySign) verify_primitive = public_handle.primitive(signature.PublicKeyVerify) data_signature = sign_primitive.sign(b'data') verify_primitive.verify(data_signature, b'data')
def test_mac_success(self, key_template): keyset_handle = tink.new_keyset_handle(key_template) jwt_hmac = keyset_handle.primitive(jwt.JwtMac) token = jwt.new_raw_jwt(issuer='issuer', subject='subject') compact = jwt_hmac.compute_mac_and_encode(token) output_token = jwt_hmac.verify_mac_and_decode(compact, jwt.new_validator()) self.assertEqual(output_token.issuer(), token.issuer()) self.assertEqual(output_token.subject(), token.subject())
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 test_keyset_handle_conversion(self): keyset_handle1 = tink.new_keyset_handle(aead.aead_key_templates.AES128_GCM) p1 = keyset_handle1.primitive(aead.Aead) builder = keyset_builder.from_keyset_handle(keyset_handle1) keyset_handle2 = builder.keyset_handle() p2 = keyset_handle2.primitive(aead.Aead) ciphertext = p1.encrypt(b'plaintext', b'ad') self.assertEqual(p2.decrypt(ciphertext, b'ad'), b'plaintext')