chromium/chromeos/crosapi/mojom/keystore_service.mojom

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module crosapi.mojom;

import "chromeos/crosapi/mojom/keystore_error.mojom";

// This interface mirrors the enterprise.platformKeys extension API.
// TODO(crbug.com/40719380): Figure out the appropriate API surface for
// long-term stabilization.

// The system has a keystore and a certificate store. Keys are tuples
// of (private key, public key). These are generated by the system and the
// private key is never shared. Certificates provide proof of ownership of a
// private key. There are many uses for keys and certificates -- this interface
// currently focuses on the use cases for the enterprise_platform_keys extension
// API.

// Unless otherwise noted, all certificates are DER encoded X.509. In addition,
// the certificates allow UTF-8 encoding in fields where PrintableString is
// expected to support enterprises with non-compliant DER-encodings. See
// crbug.com/770323 and crbug.com/788655.

// Both keystores and certificate stores have two variants: device and user.
// Device keys/certificates are available to all affiliated users on the device.
// User keys/certificates are only available to the current user.
[Stable, Extensible]
enum KeystoreType {
  kUser = 0,
  kDevice = 1,
};

// Input parameters for RSASSA-PKCS1-v1_5. Parameters other than modulus_length
// and sw_backed are currently not supported when used as inputs to
// GenerateKey().
[Stable]
struct KeystorePKCS115Params {
  [MinVersion=0]
  uint32 modulus_length@0;
  [MinVersion=1]
  array<uint8>? public_exponent@1;
  // If true, generate a software-backed key.
  [MinVersion=16]
  bool sw_backed@2;
};

// Input parameters for ECDSA. |named_curve| uses WebCrypto nomenclature.
// Currently "P-256" is the only supported curve.
[Stable]
struct KeystoreECDSAParams {
  string named_curve;
};

// A signing algorithm is fully described by choice of algorithm and parameters.
[Stable]
union KeystoreSigningAlgorithm {
  KeystorePKCS115Params pkcs115;
  KeystoreECDSAParams ecdsa;
};

// The name of a WebCrypto signing algorithm.
[Stable, Extensible]
enum KeystoreSigningAlgorithmName {
  [Default] kUnknown = 0,
  kRsassaPkcs115 = 1,
  kEcdsa = 2,
};

// Recognized WebCrypto signing schemes.
[Stable, Extensible]
enum KeystoreSigningScheme {
  [Default] kUnknown = 0,
  kRsassaPkcs1V15None = 1,  // The data is PKCS#1 v1.5 padded but not hashed.
  kRsassaPkcs1V15Sha1 = 2,
  kRsassaPkcs1V15Sha256 = 3,
  kRsassaPkcs1V15Sha384 = 4,
  kRsassaPkcs1V15Sha512 = 5,
  kEcdsaSha1 = 6,
  kEcdsaSha256 = 7,
  kEcdsaSha384 = 8,
  kEcdsaSha512 = 9,
};

// Returned by ChallengeAttestationOnlyKeystore().
[Stable]
union ChallengeAttestationOnlyKeystoreResult {
  // Implies failure.
  string error_message;

  // Implies success.
  array<uint8> challenge_response;
};

[Stable]
union KeystoreBinaryResult {
  // Implies failure.
  KeystoreError error;

  // Implies success.
  array<uint8> blob;
};

// Returned by GetCertificates().
[Stable]
union GetCertificatesResult {
  // Implies failure.
  KeystoreError error;

  // Implies success.
  array<array<uint8>> certificates;
};

// Returned by SelectClientCertificates().
[Stable]
union KeystoreSelectClientCertificatesResult {
  // Implies failure.
  KeystoreError error;

  // A list of DER encoded X.509 certificates. Implies success.
  array<array<uint8>> certificates;
};

// Returned by GetKeyStores().
[Stable]
union GetKeyStoresResult {
  // Implies failure.
  KeystoreError error;

  // Implies success.
  array<KeystoreType> key_stores;
};

// Returned by GetPublicKey() on success.
[Stable]
struct GetPublicKeySuccessResult {
  // The public key of the matching certificate.
  array<uint8> public_key;

  // Provides details about the signing algorithm.
  KeystoreSigningAlgorithm algorithm_properties;
};

// Returned by GetPublicKey().
[Stable]
union GetPublicKeyResult {
  // Implies failure.
  KeystoreError error;

  // Implies success.
  GetPublicKeySuccessResult success_result;
};

// The enum of possible tags that can be attached to a key pair. The tag values
// must be powers of 2.
[Stable, Extensible]
enum KeyTag {
  kNoTags = 0,
  kCorporate = 1,
};

[Stable]
union GetKeyTagsResult {
  // Implies failure.
  KeystoreError error;

  // Implies success. A bitmask of `KeyTag` flags.
  uint64 tags;
};

// DEPRECATED, use `KeystoreBinaryResult` instead.
[Stable]
union DEPRECATED_ExtensionKeystoreBinaryResult {
  // Implies failure.
  string error_message;

  // Implies success.
  array<uint8> blob;
};

// DEPRECATED, use `GetPublicKeyResult` instead.
// Returned by DEPRECATED_GetPublicKey().
[Stable]
union DEPRECATED_GetPublicKeyResult {
  // Implies failure.
  string error_message;

  // Implies success.
  GetPublicKeySuccessResult success_result;
};

// DEPRECATED, use `GetKeyStoresResult` instead.
// Returned by DEPRECATED_GetKeyStores().
[Stable]
union DEPRECATED_GetKeyStoresResult {
  // Implies failure.
  string error_message;

  // Implies success.
  array<KeystoreType> key_stores;
};

// DEPRECATED, use `GetCertificatesResult` instead.
// Returned by DEPRECATED_GetCertificates().
[Stable]
union DEPRECATED_GetCertificatesResult {
  // Implies failure.
  string error_message;

  // Implies success.
  array<array<uint8>> certificates;
};

// DEPRECATED, use `KeystoreBinaryResult` instead.
// Returned by methods that either return a string, or an error.
[Stable, RenamedFrom="crosapi.mojom.KeystoreStringResult"]
union DEPRECATED_KeystoreStringResult {
  // Implies failure.
  string error_message;

  // Implies success.
  string challenge_response;
};

// This interface is implemented by ash-chrome. It provides lacros-chrome a
// mechanism to modify and query the attestation-only and generate purpose
// keystores.
[Stable, Uuid="308635fd-110b-4f24-bfa8-9f43be31c61e"]
interface KeystoreService {
  // This API serves a challenge to a special "attestation-only" keystore. This
  // keystore only contains 2 private keys (1 for the user, 1 for the device).
  // The challenge must be generated via the Verified Access Web API. If
  // |migrate| is true, then after the attestation, the key is migrated
  // from the attestation-only keystore to the regular keystore. A new
  // "attestation-only" key is generated on demand if a key does not exist
  // because it was recently migrated. If a key is migrated, the expectation is
  // that the caller will later call ImportCertificate() to associate a
  // certificate with the migrated key.
  [MinVersion=15]
  ChallengeAttestationOnlyKeystore@20(
      KeystoreType type, array<uint8> challenge, bool migrate,
      [MinVersion=17] KeystoreSigningAlgorithmName algorithm) =>
      (ChallengeAttestationOnlyKeystoreResult result);

  // Returns the keystores available to the client. These are used as inputs to
  // the other methods on this interface.
  [MinVersion=12]
  GetKeyStores@16() => (GetKeyStoresResult result);

  // Returns the list of all certificates that were issued by one of the
  // |certificate_authorities|. |certificate_authorities| is a list of
  // DER-encoded X.509 DistinguishedName of certificate authorities. If
  // |certificate_authorities| is empty, all certificates will be returned.
  [MinVersion=9]
  SelectClientCertificates@11(array<array<uint8>> certificate_authorities)
      => (KeystoreSelectClientCertificatesResult result);

  // Returns the certificates in the indicated keystore. The result is an array
  // of DER encoded X.509 certificates.
  [MinVersion=13]
  GetCertificates@17(KeystoreType keystore) =>
      (GetCertificatesResult result);

  // Adds a DER encoded X.509 certificate to the indicated keystore. Returns
  // empty string on success. It is only valid to call this with a certificate
  // whose corresponding private key is already present in the key store. This
  // must have been previously generated via GenerateKey().
  // TODO(crbug.com/40489779): combine |is_error| and |error| into an optional
  // |error| when mojo supports optional enums.
  [MinVersion=14]
  AddCertificate@18(KeystoreType keystore, array<uint8> certificate) =>
      (bool is_error, KeystoreError error);

  // Removes a DER encoded X.509 certificate from the indicated keystore.
  // Returns empty string on success.
  // TODO(crbug.com/40489779): combine |is_error| and |error| into an optional
  // |error| when mojo supports optional enums.
  [MinVersion=14]
  RemoveCertificate@19(KeystoreType keystore, array<uint8> certificate) =>
      (bool is_error, KeystoreError error);

  // Checks whether |certificate| certifies a key that allows usage of the
  // WebCrypto algorithm |algorithm_name|. If so, returns the key info and
  // details about the signing algorithm. |certificate| must be a DER encoded
  // X.509 certificate.
  [MinVersion=11]
  GetPublicKey@15(array<uint8> certificate,
      KeystoreSigningAlgorithmName algorithm_name) =>
      (GetPublicKeyResult result);

  // Generates a private/public key-pair with |algorithm| and stores the results
  // in |keystore|. Returns the public key as a binary blob.
  [MinVersion=6]
  GenerateKey@8(KeystoreType keystore,
      KeystoreSigningAlgorithm algorithm) =>
      (KeystoreBinaryResult result);

  // Removes the key pair if no matching certificates exist. Only keys in the
  // given |keystore| are considered. |is_error| indicates if the operation
  // succeeded. If |is_error| is true, then |error| contains the error code.
  // TODO(crbug.com/40489779): combine |is_error| and |error| into an optional
  // |error| when mojo supports optional enums.
  [MinVersion=8]
  RemoveKey@10(KeystoreType keystore,
      array<uint8> public_key) =>
      (bool is_error, KeystoreError error);

  // Signs some data using a previously generated key, indicated with
  // |public_key|. |scheme| is the WebCrypto signing scheme. If
  // |is_keystore_provided| is true, |keystore| holds a valid value. Otherwise
  // the key will be searched in all available key stores.
  // TODO(crbug.com/40489779): combine |is_keystore_provided| and |keystore|
  // into an optional |keystore| when mojo supports optional enums.
  [MinVersion=7]
  Sign@9(bool is_keystore_provided, KeystoreType keystore,
      array<uint8> public_key, KeystoreSigningScheme scheme,
      array<uint8> data) =>
      (KeystoreBinaryResult result);

  // Returns key tags assigned to the key pair of the |public_key|.
  [MinVersion=10]
  GetKeyTags@12(array<uint8> public_key) => (GetKeyTagsResult result);

  // Adds new tags to the key pair of the |public_key|.
  [MinVersion=10]
  AddKeyTags@13(array<uint8> public_key, uint64 tags) =>
      (bool is_error, KeystoreError error);

  // Returns true if the current ChromeOS user can grant unlimited sign
  // permission for |public_key| to extensions.
  [MinVersion=10]
  CanUserGrantPermissionForKey@14(array<uint8> public_key) =>
      (bool is_allowed);

  // DEPRECATED, use `GenerateKey` instead.
  // Generates a private/public key-pair with |algorithm| and stores the results
  // in |keystore|. Returns the public key as a binary blob. Also generates
  // additional metadata to make the key available for future ExtensionSign
  // calls.
  [MinVersion=2]
  DEPRECATED_ExtensionGenerateKey@3(KeystoreType keystore,
      KeystoreSigningAlgorithm algorithm,
      [MinVersion=5]
      string? extension_id) =>
      (DEPRECATED_ExtensionKeystoreBinaryResult result);

  // DEPRECATED, use `Sign` instead.
  // Signs some data using a previously generated key, indicated with
  // |public_key|. |scheme| is the WebCrypto signing scheme. |extension_id| is
  // needed to determine if the extension is allowed to use the key.
  [MinVersion=4]
  DEPRECATED_ExtensionSign@7(KeystoreType keystore, array<uint8> public_key,
      KeystoreSigningScheme scheme,
      array<uint8> data, string extension_id) =>
      (DEPRECATED_ExtensionKeystoreBinaryResult result);

  // DEPRECATED, use `GetPublicKey` instead.
  // Checks whether |certificate| certifies a key that allows usage of the
  // WebCrypto algorithm |algorithm_name|. If so, returns the key info and
  // details about the signing algorithm. |certificate| must be a DER encoded
  // X.509 certificate.
  DEPRECATED_GetPublicKey@6(array<uint8> certificate,
      KeystoreSigningAlgorithmName algorithm_name) =>
      (DEPRECATED_GetPublicKeyResult result);

  // DEPRECATED, use `GetKeyStores` instead.
  // Returns the keystores available to the client. These are used as inputs to
  // the other methods on this interface.
  [MinVersion=1]
  DEPRECATED_GetKeyStores@1() => (DEPRECATED_GetKeyStoresResult result);

  // DEPRECATED, use `GetCertificates` instead.
  // Returns the certificates in the indicated keystore. The result is an array
  // of DER encoded X.509 certificates.
  [MinVersion=2]
  DEPRECATED_GetCertificates@2(KeystoreType keystore) =>
      (DEPRECATED_GetCertificatesResult result);

  // DEPRECATED, use `AddCertificate` instead.
  // Adds a DER encoded X.509 certificate to the indicated keystore. Returns
  // empty string on success. It is only valid to call this with a certificate
  // whose corresponding private key is already present in the key store. This
  // must have been previously generated via GenerateKey().
  [MinVersion=2]
  DEPRECATED_AddCertificate@4(KeystoreType keystore,
      array<uint8> certificate) =>
      (string error);

  // DEPRECATED, use `RemoveCertificate` instead.
  // Removes a DER encoded X.509 certificate from the indicated keystore.
  // Returns empty string on success.
  [MinVersion=2]
  DEPRECATED_RemoveCertificate@5(KeystoreType keystore,
      array<uint8> certificate) =>
      (string error);

  // DEPRECATED, use `ChallengeAttestationOnlyKeystore` instead.
  // This API serves a challenge to a special "attestation-only" keystore. This
  // keystore only contains 2 private keys (1 for the user, 1 for the device).
  // The challenge must be generated via the Verified Access Web API. If
  // |migrate| is true, then after the attestation, the key is migrated
  // from the attestation-only keystore to the regular keystore. A new
  // "attestation-only" key is generated on demand if a key does not exist
  // because it was recently migrated. If a key is migrated, the expectation is
  // that the caller will later call ImportCertificate() to associate a
  // certificate with the migrated key.
  DEPRECATED_ChallengeAttestationOnlyKeystore@0(
      string challenge, KeystoreType type, bool migrate) =>
          (DEPRECATED_KeystoreStringResult result);
};