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

syntax = "proto2";

option optimize_for = LITE_RUNTIME;

import "attestation_ca.proto";
import "keystore.proto";

package attestation;
option go_package = "chromiumos/system_api/attestation_proto";

enum AttestationStatus {
  STATUS_SUCCESS = 0;
  STATUS_UNEXPECTED_DEVICE_ERROR = 1;
  STATUS_NOT_AVAILABLE = 2;
  STATUS_NOT_READY = 3;
  STATUS_NOT_ALLOWED = 4;
  STATUS_INVALID_PARAMETER = 5;
  STATUS_REQUEST_DENIED_BY_CA = 6;
  STATUS_CA_NOT_AVAILABLE = 7;
  STATUS_NOT_SUPPORTED = 8;
  // The error that is translated into by the client to indicate any kind of
  // D-Bus error.
  STATUS_DBUS_ERROR = 9;
}

enum ACAType {
  DEFAULT_ACA = 0;
  TEST_ACA = 1;
}

enum VAType {
  DEFAULT_VA = 0;
  TEST_VA = 1;
}

message GetFeaturesRequest {}

message GetFeaturesReply {
  optional AttestationStatus status = 1;
  // If `false`, core attestation service is not available, including
  // preparation, enrollment, and certification.
  optional bool is_available = 2;
  // The supported key types of the certified keys.
  repeated KeyType supported_key_types = 3;
}

message GetKeyInfoRequest {
  optional string key_label = 1;
  optional string username = 2;
}

message GetKeyInfoReply {
  optional AttestationStatus status = 1;
  optional KeyType key_type = 2;
  optional KeyUsage key_usage = 3;
  // The public key (X.509/DER SubjectPublicKeyInfo).
  optional bytes public_key = 4;
  // The serialized TPM_CERTIFY_INFO or TPM2B_ATTEST for the new key.
  optional bytes certify_info = 5;
  // The signature of certify_info by the Attestation Key.
  optional bytes certify_info_signature = 6;
  // The certificate data associated with the key (if any).
  optional bytes certificate = 7;
  // The payload associated with the key.
  optional bytes payload = 8;
  // The certified key credential in DER format.
  optional bytes certified_key_credential = 9;
}

message GetEndorsementInfoRequest {
  reserved 1;
}

message GetEndorsementInfoReply {
  optional AttestationStatus status = 1;
  // The endorsement public key (X.509/DER SubjectPublicKeyInfo).
  optional bytes ek_public_key = 2;
  // The endorsement certificate (X.509/DER).
  optional bytes ek_certificate = 3;
  // Human-readable string with EK information. Contains EK certificate in PEM
  // format and SHA256 hash of the raw DER encoded certificate.
  optional string ek_info = 4;
}

message GetAttestationKeyInfoRequest {
  reserved 1;
  // What kind of ACA to use.
  optional ACAType aca_type = 2;
}

message GetAttestationKeyInfoReply {
  optional AttestationStatus status = 1;
  // The attestation public key (X.509/DER SubjectPublicKeyInfo).
  optional bytes public_key = 2;
  // The attestation public key in TPM_PUBKEY form.
  optional bytes public_key_tpm_format = 3;
  // The attestation key certificate.
  optional bytes certificate = 4;
  // A quote of PCR0 at the time of attestation key creation.
  optional Quote pcr0_quote = 5;
  // A quote of PCR1 at the time of attestation key creation.
  optional Quote pcr1_quote = 6;
}

message ActivateAttestationKeyRequest {
  reserved 1;
  optional EncryptedIdentityCredential encrypted_certificate = 2;
  // Whether, on success, the decrypted certificate should be retained in
  // association with the attestation key. When using an ACA, this is normally
  // set to true. Other protocols may use a nonce as the 'certificate' and in
  // these cases this field is normally set to false.
  optional bool save_certificate = 3;
  // What kind of ACA to use.
  optional ACAType aca_type = 4;
}

message ActivateAttestationKeyReply {
  optional AttestationStatus status = 1;
  // The decrypted attestation key certificate.
  optional bytes certificate = 2;
}

message CreateCertifiableKeyRequest {
  // An arbitrary label which can be used to reference the key later.
  optional string key_label = 1;
  // Provided if the new key should be accessible only by a
  // particular user. If this field is not set or is the empty
  // string, the key will be accessible system-wide.
  optional string username = 2;
  optional KeyType key_type = 3;
  optional KeyUsage key_usage = 4;
}

message CreateCertifiableKeyReply {
  optional AttestationStatus status = 1;
  // The new public key (X.509/DER SubjectPublicKeyInfo).
  optional bytes public_key = 2;
  // The serialized TPM_CERTIFY_INFO or TPM2B_ATTEST for the new key.
  optional bytes certify_info = 3;
  // The signature of certify_info by the Attestation Key.
  optional bytes certify_info_signature = 4;
}

message DecryptRequest {
  optional string key_label = 1;
  optional string username = 2;
  optional bytes encrypted_data = 3;
}

message DecryptReply {
  optional AttestationStatus status = 1;
  optional bytes decrypted_data = 2;
}

message SignRequest {
  optional string key_label = 1;
  optional string username = 2;
  optional bytes data_to_sign = 3;
}

message SignReply {
  optional AttestationStatus status = 1;
  optional bytes signature = 2;
}

message RegisterKeyWithChapsTokenRequest {
  optional string key_label = 1;
  optional string username = 2;
  optional bool include_certificates = 3;
}

message RegisterKeyWithChapsTokenReply {
  optional AttestationStatus status = 1;
}

// Message to check whether attestation is prepared for enrollment or not.
message GetEnrollmentPreparationsRequest {
  optional ACAType aca_type = 1;
}

// Reply to a check of whether attestation is prepared for enrollment or not.
message GetEnrollmentPreparationsReply {
  optional AttestationStatus status = 1;
  map<int32, bool> enrollment_preparations = 2;
}

message GetStatusRequest {
  // Get extended status (see GetStatusReply below).
  optional bool extended_status = 1;
}

message GetStatusReply {
  message Identity {
    // The identity features.
    optional int32 features = 1;
  }

  message IdentityCertificate {
    // The identity that is enrolled.
    optional int32 identity = 1;
    // The Privacy CA that the identity is enrolled with.
    optional int32 aca = 2;
  }

  optional AttestationStatus status = 1;
  // Is prepared for enrollment? True if prepared for *any* CA.
  optional bool prepared_for_enrollment = 2;
  // Is enrolled (AIK certificate created)? True if enrolled with *any* CA.
  optional bool enrolled = 3;
  // Is in verified boot mode (according to PCR0 quote)?
  // [Only included in reply if extended_status is set]
  optional bool verified_boot = 4;
  // List of identities and their identity features.
  repeated Identity identities = 5;
  // List of identity certificates.
  map<int32, IdentityCertificate> identity_certificates = 6;
  // Map of CA types to whether we are prepared for enrollment with that CA.
  map<int32, bool> enrollment_preparations = 7;
}

// Verify attestation data.
message VerifyRequest {
  // Use CrosCore CA to verify that the EK is endorsed.
  optional bool cros_core = 1;
  // Verify EK only.
  // Otherwise, in addition to EK, verify all attestation data as a CA would.
  optional bool ek_only = 2;
}

message VerifyReply {
  optional AttestationStatus status = 1;
  optional bool verified = 2;
}

// Create an enrollment request to be sent to the Privacy CA. This request
// is a serialized AttestationEnrollmentRequest protobuf. Attestation
// enrollment is a process by which the Privacy CA verifies the EK certificate
// of a device and issues a certificate for an AIK. The enrollment process can
// be finished by sending FinishEnrollRequest with the response from the CA.
message CreateEnrollRequestRequest {
  // What kind of ACA to use.
  optional ACAType aca_type = 1;
}

message CreateEnrollRequestReply {
  optional AttestationStatus status = 1;
  // AttestationEnrollmentRequest to be sent to CA server.
  optional bytes pca_request = 2;
}

// Finish the enrollment process.
message FinishEnrollRequest {
  // AttestationEnrollmentResponse received from CA server.
  optional bytes pca_response = 1;
  // What kind of ACA to use.
  optional ACAType aca_type = 2;
}

message FinishEnrollReply {
  optional AttestationStatus status = 1;
}

// Goes through the entire enrollment process, including creating enroll
// request, sending the request to the corresponding PCA server, and storing the
// response from PCA server if success. The message field is identical to
// |CreateEnrollRequestRequest|.
message EnrollRequest {
  // What kind of ACA to use.
  optional ACAType aca_type = 1;
  // No matter is the device is enrolled, (re-)enroll the device.
  optional bool forced = 2;
}

message EnrollReply {
  optional AttestationStatus status = 1;
}

// `DEVICE_SETUP_CERTIFICATE` specific request metadata.
message DeviceSetupCertificateRequestMetadata {
  // This will eventually be a DUSI. For now, this will be a 36 character GUID.
  // This will be used as the CN of the Remote Attestation certificate.
  optional string id = 1;

  // The generated certificate will be bound to this value. This is used to
  // prevent replay attacks. Currently it is the FIDO credential id.
  optional string content_binding = 2;
}

// Create an attestation certificate request to be sent to the Privacy CA.
// The request is a serialized AttestationCertificateRequest protobuf. The
// certificate request process generates and certifies a key in the TPM and
// sends the AIK certificate along with information about the certified key to
// the Privacy CA. The PCA verifies the information and issues a certificate
// for the certified key. The certificate request process can be finished by
// sending FinishCertificateRequestRequest with the response from the CA.
message CreateCertificateRequestRequest {
  // Type of certificate to be requested.
  optional CertificateProfile certificate_profile = 1;
  // The canonical username of the active user profile. Leave blank
  // if not associated with the current user.
  optional string username = 2;
  // Some certificate requests require information about the origin
  // of the request.  If no origin is needed, this can be empty.
  optional string request_origin = 3;
  // What kind of ACA to use.
  optional ACAType aca_type = 4;
  // The key algorithm of certified key.
  optional KeyType key_type = 5;
  // Certificate profile specific metadata.
  oneof metadata {
    // `DEVICE_SETUP_CERTIFICATE` specific request metadata.
    DeviceSetupCertificateRequestMetadata
        device_setup_certificate_request_metadata = 6;
  }
}

message CreateCertificateRequestReply {
  optional AttestationStatus status = 1;
  // The request to be sent to the Privacy CA.
  optional bytes pca_request = 2;
}

// Finish the certificate request process.  The |pca_response| from the PCA
// is a serialized AttestationCertificateResponse protobuf. This final step
// verifies the PCA operation succeeded and extracts the certificate for the
// certified key.  The certificate is stored with the key.
message FinishCertificateRequestRequest {
  // The Privacy CA's response to a certificate request.
  optional bytes pca_response = 1;
  // A name for the key.  If a key already exists with this name it
  // will be destroyed and replaced with this one.
  optional string key_label = 2;
  // This should match |username| in CreateCertificateRequestRequest.
  optional string username = 3;
}

message FinishCertificateRequestReply {
  optional AttestationStatus status = 1;
  // The PCA issued certificate chain in PEM format. By
  // convention the certified key certificate is listed
  // first followed by intermediate CA certificate(s).
  // The PCA root certificate is not included.
  optional bytes certificate = 2;
  // The public key (X.509/DER SubjectPublicKeyInfo).
  optional bytes public_key = 3;
  // The tpm key blob that the key can be loaded to TPM with.
  optional bytes key_blob = 4;
  // The PCA issued certificate in DER format.
  optional bytes certified_key_credential = 5;
}

// Goes through the entire cert process, including creating cert, sending the
// request to the corresponding PCA server, and storing the response from PCA
// server if success. The message fields are basically the union of
// |CreateCertificateRequestRequest| and |FinishCertificateRequestRequest|.
message GetCertificateRequest {
  // Type of certificate to be requested.
  optional CertificateProfile certificate_profile = 1;
  // The canonical username of the active user profile. Leave blank
  // if not associated with the current user.
  optional string username = 2;
  // Some certificate requests require information about the origin
  // of the request.  If no origin is needed, this can be empty.
  optional string request_origin = 3;
  // What kind of ACA to use.
  optional ACAType aca_type = 4;
  // The key algorithm of certified key.
  optional KeyType key_type = 5;
  // A name for the key.  If a key already exists with this name it
  // will be destroyed and replaced with this one.
  optional string key_label = 6;
  // Ignores the current certificate if any and gets the new certificate.
  optional bool forced = 7;
  // If set to |true|, this request also triggers enrollment process if the
  // device is not enrolled yet.
  optional bool shall_trigger_enrollment = 8;
  oneof metadata {
    // `DEVICE_SETUP_CERTIFICATE` specific request metadata.
    DeviceSetupCertificateRequestMetadata
        device_setup_certificate_request_metadata = 9;
  }
}

message GetCertificateReply {
  optional AttestationStatus status = 1;
  // The PCA issued certificate chain in PEM format. By
  // convention the certified key certificate is listed
  // first followed by intermediate CA certificate(s).
  // The PCA root certificate is not included.
  optional bytes certificate = 2;
  // The public key (X.509/DER SubjectPublicKeyInfo).
  optional bytes public_key = 3;
  // The tpm key blob that the key can be loaded to TPM with.
  optional bytes key_blob = 4;
  // The PCA issued certificate in DER format.
  optional bytes certified_key_credential = 5;
}

// Sign a challenge for an enterprise device/user. This challenge is typically
// generated by and the response verified by the Verified Access Server API
// (VA).
message SignEnterpriseChallengeRequest {
  // The key name. This is the same name previously passed to
  // FinishCertficateRequestRequest.
  optional string key_label = 1;
  // The canonical username of the active user profile.
  // When this is set, a user key is used to perform the challenge.
  // When this is unset or empty, a device key is used to perform the challenge.
  optional string username = 2;
  // A domain value to be included in the challenge response.
  // This is supposed to be the user's canonical e-mail address.
  optional string domain = 3;
  // A device identifier to be included in the challenge response.
  optional bytes device_id = 4;
  // Whether the challenge response should include
  // a SignedPublicKeyAndChallenge.
  optional bool include_signed_public_key = 5;
  // The challenge to be signed.
  optional bytes challenge = 6;
  // The VA server that will handle the challenge.
  optional VAType va_type = 7;
  // The name of the key used for SignedPublicKeyAndChallenge. If left empty,
  // the same key used to sign the challenge response (EMK or EUK) will be used
  // for SignedPublicKeyAndChallenge.
  optional string key_name_for_spkac = 8;
  // Device Trust Signals
  // Deprecated due to signals collection change to store signals in a
  // dictionary and converting them to a JSON string. Use
  // `device_trust_signals_json` instead.
  reserved 9;
  // Device Trust Signals
  optional string device_trust_signals_json = 10;
  // Whether the challenge response should include the customer id.
  optional bool include_customer_id = 11;
  // Determines the VA flow type, which should be used on VA.
  optional VerifiedAccessFlow flow_type = 12;
  // Whether the challenge response should include the certificate of the
  // signing key. When set to true, key_name_for_spkac will be ignored.
  optional bool include_certificate = 13;
}

message SignEnterpriseChallengeReply {
  optional AttestationStatus status = 1;
  // The challenge response.
  optional bytes challenge_response = 2;
}

// Sign a challenge outside of an enterprise context: generate a random nonce
// and append it to challenge, then sign and return the signature in the
// |challenge_response|.
// This challenge is typically generated by some module running within Chrome.
message SignSimpleChallengeRequest {
  // The key name. This is the same name previously passed to
  // FinishCertficateRequestRequest.
  optional string key_label = 1;
  // The canonical username of the active user profile. Leave blank
  // if not associated with the current user.
  optional string username = 2;
  // The challenge to be signed.
  optional bytes challenge = 3;
}

message SignSimpleChallengeReply {
  optional AttestationStatus status = 1;
  // The challenge response.
  optional bytes challenge_response = 2;
}

// Set a payload for a key; any previous payload will be overwritten.
message SetKeyPayloadRequest {
  // The key name. This is the same name previously passed to
  // FinishCertficateRequestRequest.
  optional string key_label = 1;
  // The canonical username of the active user profile. Leave blank
  // if not associated with the current user.
  optional string username = 2;
  optional bytes payload = 3;
}

message SetKeyPayloadReply {
  optional AttestationStatus status = 1;
}

// Delete keys either by key label prefix or by exact key label.
message DeleteKeysRequest {
  enum MatchBehavior {
    // Match type not specified. Behavior defaults to |MATCH_TYPE_PREFIX|.
    MATCH_BEHAVIOR_UNSPECIFIED = 0;

    // Will delete all keys that start with |key_label_match|.
    // If no such key exists, the operation still succeeds.
    MATCH_BEHAVIOR_PREFIX = 1;

    // Will delete the key which has a key_label exactly matching
    // |key_label_match|.
    // If no such key exists, the operation still succeeds.
    MATCH_BEHAVIOR_EXACT = 2;
  }
  // The key label prefix or the exact key label (depends on |match_behavior|).
  optional string key_label_match = 1;
  // The canonical username of the active user profile. Leave blank
  // if not associated with the current user.
  optional string username = 2;
  // The matching behavior - see comments on the enum values. If omitted,
  // defaults to MATCH_BEHAVIOR_PREFIX for backwards compatibility.
  optional MatchBehavior match_behavior = 3;
}

message DeleteKeysReply {
  optional AttestationStatus status = 1;
}

// Create a request to be sent to the PCA which will reset the identity for
// this device on future AIK enrollments.  The |reset_token| is put in the
// request protobuf verbatim.
message ResetIdentityRequest {
  optional string reset_token = 1;
}

message ResetIdentityReply {
  optional AttestationStatus status = 1;
  // Request to be sent to the CA.
  optional bytes reset_request = 2;
}

message GetEnrollmentIdRequest {
  optional bool ignore_cache = 1;
}

message GetEnrollmentIdReply {
  optional AttestationStatus status = 1;
  optional string enrollment_id = 2;
}

// Gets a copy of the specific NV data, signed using the key with the specified
// label, eg "attest-ent-machine".
message GetCertifiedNvIndexRequest {
  optional int32 nv_index = 1;
  optional int32 nv_size = 2;
  optional string key_label = 3;
}

message GetCertifiedNvIndexReply {
  optional AttestationStatus status = 1;
  optional bytes certified_data = 2;
  optional bytes signature = 3;
  optional bytes key_certificate = 4;
}
