示例#1
0
 def verify(self, sign: bytes, data: bytes) -> None:
     with tempfile.TemporaryDirectory() as tmpdir:
         public_keyset_filename = os.path.join(tmpdir, 'public_keyset_file')
         with open(public_keyset_filename, 'wb') as f:
             cleartext_keyset_handle.write(tink.BinaryKeysetWriter(f),
                                           self._public_keyset_handle)
         signature_filename = os.path.join(tmpdir, 'signature_file')
         with open(signature_filename, 'wb') as f:
             f.write(sign)
         message_filename = os.path.join(tmpdir, 'message_file')
         with open(message_filename, 'wb') as f:
             f.write(data)
         output_filename = os.path.join(tmpdir, 'output_file')
         try:
             unused_return_value = subprocess.check_output([
                 self._cli, public_keyset_filename, signature_filename,
                 message_filename, output_filename
             ])
         except subprocess.CalledProcessError as e:
             raise tink.TinkError(e)
         with open(output_filename, 'rb') as f:
             output = f.read()
         if output != b'valid':
             raise tink.TinkError('verification failed')
         return None
示例#2
0
文件: cli_mac.py 项目: urandu/tink
 def verify_mac(self, mac_value: bytes, data: bytes) -> None:
     with tempfile.TemporaryDirectory() as tmpdir:
         keyset_filename = os.path.join(tmpdir, 'keyset_file')
         with open(keyset_filename, 'wb') as f:
             cleartext_keyset_handle.write(tink.BinaryKeysetWriter(f),
                                           self._keyset_handle)
         data_filename = os.path.join(tmpdir, 'data_file')
         with open(data_filename, 'wb') as f:
             f.write(data)
         mac_filename = os.path.join(tmpdir, 'mac_file')
         with open(mac_filename, 'wb') as f:
             f.write(mac_value)
         result_filename = os.path.join(tmpdir, 'result_file')
         try:
             unused_return_value = subprocess.check_output([
                 self._cli, keyset_filename, 'verify', data_filename,
                 mac_filename, result_filename
             ])
         except subprocess.CalledProcessError as e:
             raise tink.TinkError(e)
         with open(result_filename, 'rb') as f:
             result = f.read()
         if result != b'valid':
             raise tink.TinkError('verification failed')
         return None
示例#3
0
def _convert_to_ecdsa_key(
        key: Dict[str, Union[str, List[str]]]) -> tink_pb2.Keyset.Key:
    """Converts a EC Json Web Key (JWK) into a tink_pb2.Keyset.Key."""
    ecdsa_public_key = jwt_ecdsa_pb2.JwtEcdsaPublicKey()
    algorithm = _ECDSA_NAME_TO_ALGORITHM.get(key['alg'], None)
    if not algorithm:
        raise tink.TinkError('unknown ECDSA algorithm')
    if key.get('kty', None) != 'EC':
        raise tink.TinkError('invalid kty')
    _, crv = _ECDSA_PARAMS[algorithm]
    if key.get('crv', None) != crv:
        raise tink.TinkError('invalid crv')
    _validate_use_and_key_ops(key)
    if 'd' in key:
        raise tink.TinkError('cannot convert private ECDSA key')
    ecdsa_public_key.algorithm = algorithm
    ecdsa_public_key.x = _base64_decode(key['x'])
    ecdsa_public_key.y = _base64_decode(key['y'])
    if 'kid' in key:
        ecdsa_public_key.custom_kid.value = key['kid']
    proto_key = tink_pb2.Keyset.Key()
    proto_key.key_data.type_url = _JWT_ECDSA_PUBLIC_KEY_TYPE
    proto_key.key_data.value = ecdsa_public_key.SerializeToString()
    proto_key.key_data.key_material_type = tink_pb2.KeyData.ASYMMETRIC_PUBLIC
    proto_key.output_prefix_type = tink_pb2.RAW
    proto_key.status = tink_pb2.ENABLED
    return proto_key
示例#4
0
def _convert_to_rsa_ssa_pss_key(
        key: Dict[str, Union[str, List[str]]]) -> tink_pb2.Keyset.Key:
    """Converts a JWK into a JwtEcdsaPublicKey."""
    public_key = jwt_rsa_ssa_pss_pb2.JwtRsaSsaPssPublicKey()
    algorithm = _RSA_SSA_PSS_NAME_TO_ALGORITHM.get(key['alg'], None)
    if not algorithm:
        raise tink.TinkError('unknown RSA SSA PSS algorithm')
    if key.get('kty', None) != 'RSA':
        raise tink.TinkError('invalid kty')
    _validate_use_and_key_ops(key)
    if ('p' in key or 'q' in key or 'dp' in key or 'dq' in key or 'd' in key
            or 'qi' in key):
        raise tink.TinkError('importing RSA private keys is not implemented')
    public_key.algorithm = algorithm
    public_key.n = _base64_decode(key['n'])
    public_key.e = _base64_decode(key['e'])
    if 'kid' in key:
        public_key.custom_kid.value = key['kid']
    proto_key = tink_pb2.Keyset.Key()
    proto_key.key_data.type_url = _JWT_RSA_SSA_PSS_PUBLIC_KEY_TYPE
    proto_key.key_data.value = public_key.SerializeToString()
    proto_key.key_data.key_material_type = tink_pb2.KeyData.ASYMMETRIC_PUBLIC
    proto_key.output_prefix_type = tink_pb2.RAW
    proto_key.status = tink_pb2.ENABLED
    return proto_key
示例#5
0
def _validate_use_and_key_ops(key: Dict[str, Union[str, List[str]]]):
    """Checks that 'key_ops' and 'use' have the right values if present."""
    if 'key_ops' in key:
        key_ops = key['key_ops']
        if len(key_ops) != 1 or key_ops[0] != 'verify':
            raise tink.TinkError('invalid key_ops')
    if 'use' in key and key['use'] != 'sig':
        raise tink.TinkError('invalid use')
示例#6
0
 def disable_key(self, key_id: int) -> None:
     """Disables a key."""
     for key in self._keyset.key:
         if key.key_id == key_id:
             key.status = tink_pb2.DISABLED
             return
     raise tink.TinkError('key not found: %d' % key_id)
示例#7
0
def public_keyset(stub: testing_api_pb2_grpc.KeysetStub,
                  private_keyset: bytes) -> bytes:
  request = testing_api_pb2.KeysetPublicRequest(private_keyset=private_keyset)
  response = stub.Public(request)
  if response.err:
    raise tink.TinkError(response.err)
  return response.public_keyset
示例#8
0
 def sign_and_encode(self, raw_jwt: jwt.RawJwt) -> Text:
     request = testing_api_pb2.JwtSignRequest(
         keyset=self._keyset, raw_jwt=raw_jwt_to_proto(raw_jwt))
     response = self._stub.PublicKeySignAndEncode(request)
     if response.err:
         raise tink.TinkError(response.err)
     return response.signed_compact_jwt
示例#9
0
 def _run(self, operation: Text, input_data: bytes,
          associated_data: bytes) -> bytes:
     with tempfile.TemporaryDirectory() as tmpdir:
         keyset_filename = os.path.join(tmpdir, 'keyset_file')
         input_filename = os.path.join(tmpdir, 'input_file')
         associated_data_filename = os.path.join(tmpdir,
                                                 'associated_data_file')
         output_filename = os.path.join(tmpdir, 'output_file')
         with open(keyset_filename, 'wb') as f:
             cleartext_keyset_handle.write(tink.BinaryKeysetWriter(f),
                                           self._keyset_handle)
         with open(input_filename, 'wb') as f:
             f.write(input_data)
         with open(associated_data_filename, 'wb') as f:
             f.write(associated_data)
         try:
             unused_return_value = subprocess.check_output([
                 self._cli, keyset_filename, operation, input_filename,
                 associated_data_filename, output_filename
             ])
         except subprocess.CalledProcessError as e:
             raise tink.TinkError(e)
         with open(output_filename, 'rb') as f:
             output_data = f.read()
         return output_data
示例#10
0
 def delete_key(self, key_id: int) -> None:
     """Deletes a key."""
     for key in self._keyset.key:
         if key.key_id == key_id:
             self._keyset.key.remove(key)
             return
     raise tink.TinkError('key not found: %d' % key_id)
示例#11
0
 def sign(self, data: bytes) -> bytes:
     request = testing_api_pb2.SignatureSignRequest(
         private_keyset=self._private_handle, data=data)
     response = self._stub.Sign(request)
     if response.err:
         raise tink.TinkError(response.err)
     return response.signature
示例#12
0
 def set_primary_key(self, key_id: int) -> None:
     """Sets a key as primary."""
     for key in self._keyset.key:
         if key.key_id == key_id:
             self._keyset.primary_key_id = key_id
             return
     raise tink.TinkError('key not found: %d' % key_id)
示例#13
0
 def compute_mac_and_encode(self, raw_jwt: jwt.RawJwt) -> str:
     request = testing_api_pb2.JwtSignRequest(
         keyset=self._keyset, raw_jwt=raw_jwt_to_proto(raw_jwt))
     response = self._stub.ComputeMacAndEncode(request)
     if response.err:
         raise tink.TinkError(response.err)
     return response.signed_compact_jwt
示例#14
0
def jwk_set_from_keyset(stub: testing_api_pb2_grpc.JwtStub,
                        keyset: bytes) -> str:
    request = testing_api_pb2.JwtToJwkSetRequest(keyset=keyset)
    response = stub.ToJwkSet(request)
    if response.err:
        raise tink.TinkError(response.err)
    return response.jwk_set
示例#15
0
def jwk_set_to_keyset(stub: testing_api_pb2_grpc.JwtStub,
                      jwk_set: str) -> bytes:
    request = testing_api_pb2.JwtFromJwkSetRequest(jwk_set=jwk_set)
    response = stub.FromJwkSet(request)
    if response.err:
        raise tink.TinkError(response.err)
    return response.keyset
示例#16
0
def keyset_to_json(stub: testing_api_pb2_grpc.KeysetStub,
                   keyset: bytes) -> Text:
    request = testing_api_pb2.KeysetToJsonRequest(keyset=keyset)
    response = stub.ToJson(request)
    if response.err:
        raise tink.TinkError(response.err)
    return response.json_keyset
示例#17
0
def keyset_from_json(stub: testing_api_pb2_grpc.KeysetStub,
                     json_keyset: Text) -> bytes:
    request = testing_api_pb2.KeysetFromJsonRequest(json_keyset=json_keyset)
    response = stub.FromJson(request)
    if response.err:
        raise tink.TinkError(response.err)
    return response.keyset
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)
示例#19
0
 def verify_mac(self, mac_value: bytes, data: bytes) -> None:
     request = testing_api_pb2.VerifyMacRequest(keyset=self._keyset,
                                                mac_value=mac_value,
                                                data=data)
     response = self._stub.VerifyMac(request)
     if response.err:
         raise tink.TinkError(response.err)
示例#20
0
 def compute_mac(self, data: bytes) -> bytes:
     request = testing_api_pb2.ComputeMacRequest(keyset=self._keyset,
                                                 data=data)
     response = self._stub.ComputeMac(request)
     if response.err:
         raise tink.TinkError(response.err)
     return response.mac_value
示例#21
0
def key_template(stub: testing_api_pb2_grpc.KeysetStub,
                 template_name: str) -> tink_pb2.KeyTemplate:
  request = testing_api_pb2.KeysetTemplateRequest(template_name=template_name)
  response = stub.GetTemplate(request)
  if response.err:
    raise tink.TinkError(response.err)
  return tink_pb2.KeyTemplate.FromString(response.key_template)
示例#22
0
def from_public_keyset_handle(keyset_handle: tink.KeysetHandle) -> str:
    """Converts a Tink KeysetHandle with JWT keys into a Json Web Key (JWK) set.

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

  Disabled keys are skipped.

  Keys with output prefix type "TINK" will include the encoded key ID as "kid"
  value. Keys with output prefix type "RAW" will not have a "kid" value set.

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

  Args:
    keyset_handle: A Tink KeysetHandle that contains JWT Keys.

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

  Raises:
    TinkError if the keys are not of the expected type, or if they have a
    ouput prefix type that is not supported.
  """
    output_stream = io.BytesIO()
    writer = tink.BinaryKeysetWriter(output_stream)
    keyset_handle.write_no_secret(writer)
    keyset = tink_pb2.Keyset.FromString(output_stream.getvalue())

    keys = []
    for key in keyset.key:
        if key.status != tink_pb2.ENABLED:
            continue
        if key.key_data.key_material_type != tink_pb2.KeyData.ASYMMETRIC_PUBLIC:
            raise tink.TinkError('wrong key material type')
        if key.output_prefix_type not in [tink_pb2.RAW, tink_pb2.TINK]:
            raise tink.TinkError('unsupported output prefix type')
        if key.key_data.type_url == _JWT_ECDSA_PUBLIC_KEY_TYPE:
            keys.append(_convert_jwt_ecdsa_key(key))
        elif key.key_data.type_url == _JWT_RSA_SSA_PKCS1_PUBLIC_KEY_TYPE:
            keys.append(_convert_jwt_rsa_ssa_pkcs1_key(key))
        elif key.key_data.type_url == _JWT_RSA_SSA_PSS_PUBLIC_KEY_TYPE:
            keys.append(_convert_jwt_rsa_ssa_pss_key(key))
        else:
            raise tink.TinkError('unknown key type: %s' %
                                 key.key_data.type_url)
    return json.dumps({'keys': keys}, separators=(',', ':'))
示例#23
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)
示例#24
0
def new_keyset(stub: testing_api_pb2_grpc.KeysetStub,
               key_template: tink_pb2.KeyTemplate) -> bytes:
    gen_request = testing_api_pb2.KeysetGenerateRequest(
        template=key_template.SerializeToString())
    gen_response = stub.Generate(gen_request)
    if gen_response.err:
        raise tink.TinkError(gen_response.err)
    return gen_response.keyset
示例#25
0
 def decrypt(self, ciphertext: bytes, associated_data: bytes) -> bytes:
     dec_request = testing_api_pb2.AeadDecryptRequest(
         keyset=self._keyset,
         ciphertext=ciphertext,
         associated_data=associated_data)
     dec_response = self._stub.Decrypt(dec_request)
     if dec_response.err:
         raise tink.TinkError(dec_response.err)
     return dec_response.plaintext
示例#26
0
 def encrypt(self, plaintext: bytes, associated_data: bytes) -> bytes:
     enc_request = testing_api_pb2.AeadEncryptRequest(
         keyset=self._keyset,
         plaintext=plaintext,
         associated_data=associated_data)
     enc_response = self._stub.Encrypt(enc_request)
     if enc_response.err:
         raise tink.TinkError(enc_response.err)
     return enc_response.ciphertext
示例#27
0
 def verify_mac(self, mac_value: bytes, data: bytes) -> None:
     logging.info('verify_mac in lang %s.', self.lang)
     request = testing_api_pb2.VerifyMacRequest(keyset=self._keyset,
                                                mac_value=mac_value,
                                                data=data)
     response = self._stub.VerifyMac(request)
     if response.err:
         logging.info('error verify_mac in %s: %s', self.lang, response.err)
         raise tink.TinkError(response.err)
示例#28
0
 def verify(self, signature: bytes, data: bytes) -> None:
     logging.info('signature verify in lang %s.', self.lang)
     request = testing_api_pb2.SignatureVerifyRequest(
         public_keyset=self._public_handle, signature=signature, data=data)
     response = self._stub.Verify(request)
     if response.err:
         logging.info('error signature verify in %s: %s', self.lang,
                      response.err)
         raise tink.TinkError(response.err)
示例#29
0
 def encrypt(self, plaintext: bytes, context_info: bytes) -> bytes:
     enc_request = testing_api_pb2.HybridEncryptRequest(
         public_keyset=self._public_handle,
         plaintext=plaintext,
         context_info=context_info)
     enc_response = self._stub.Encrypt(enc_request)
     if enc_response.err:
         raise tink.TinkError(enc_response.err)
     return enc_response.ciphertext
示例#30
0
 def decrypt(self, ciphertext: bytes, context_info: bytes) -> bytes:
     dec_request = testing_api_pb2.HybridDecryptRequest(
         private_keyset=self._private_handle,
         ciphertext=ciphertext,
         context_info=context_info)
     dec_response = self._stub.Decrypt(dec_request)
     if dec_response.err:
         raise tink.TinkError(dec_response.err)
     return dec_response.plaintext