// 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;

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

// Enumerates various certificate profiles supported by the Attestation CA.
enum CertificateProfile {
  // A certificate intended for enterprise-owned devices.  It has the following
  // subjectName fields:
  //   CN=<stable device identifier>
  //   OU=state:[verified|developer]
  //   O=Chrome Device Enterprise
  ENTERPRISE_MACHINE_CERTIFICATE = 0;

  // A certificate intended for enterprise-owned user accounts.  It has the
  // following subjectName fields:
  //   OU=state:[verified|developer]
  //   O=Chrome Device Enterprise
  ENTERPRISE_USER_CERTIFICATE = 1;

  // A certificate intended for platform verification by providers of protected
  // content.  It has the following subjectName fields:
  //   O=Chrome Device Content Protection
  CONTENT_PROTECTION_CERTIFICATE = 2;

  // Like above, but it also includes a stable ID and origin.
  //   CN=<origin-specific device identifier>
  //   OU=<origin>
  //   O=Chrome Device Content Protection
  CONTENT_PROTECTION_CERTIFICATE_WITH_STABLE_ID = 3;

  // A certificate intended for cast devices.
  CAST_CERTIFICATE = 4;

  GFSC_CERTIFICATE = 5;

  JETSTREAM_CERTIFICATE = 6;

  // A certificate for enterprise enrollment.
  ENTERPRISE_ENROLLMENT_CERTIFICATE = 7;

  // A certificate for signing Android Testsuite Results using CTS-in-a-box.
  XTS_CERTIFICATE = 8;

  // An EK certificate for vTPM
  //   CN=CROS VTPM PRD EK ROOT CA
  ENTERPRISE_VTPM_EK_CERTIFICATE = 9;

  // A local authority certificate for binding software keys.
  //   CN=Local Authority
  //   O=Chrome Device Soft Bind
  SOFT_BIND_CERTIFICATE = 10;

  // A remote attestation certificate for proving device integrity.
  //   CN=<An opaque device identifier string>
  //   O=Chrome Device Setup
  DEVICE_SETUP_CERTIFICATE = 11;

  // The ARC TPM certifying key is a restricted key that is used to quote
  // various TPM data, such as PCR quotation or NVRAM quotation.
  // It is primarily used for Version Attestation in ARC Attestation.
  ARC_TPM_CERTIFYING_KEY_CERTIFICATE = 12;

  // The ARC Device Key is the Device Key used in Android Attestation for ARC.
  // It is an unrestricted key.
  ARC_ATTESTATION_DEVICE_KEY_CERTIFICATE = 13;

  // A certificate intended for the Device Trust flow on enterprise-owned user
  // accounts on unmanaged devices. It has the following subjectName fields:
  //   OU=state:[verified|developer]
  //   O=Chrome Device Enterprise
  DEVICE_TRUST_USER_CERTIFICATE = 14;
}

enum TpmVersion {
  TPM_1_2 = 1;  // NOTE: This is the default. It must remain listed first.
  TPM_2_0 = 2;
}

// Types of NVRAM quotes used for attestation.
enum NVRAMQuoteType {
  // Quote of the Cr50-backed BoardID.
  BOARD_ID = 0;
  // Quote of the Cr50-backed SN+RMA bits.
  SN_BITS = 1;
  // Quote of the Cr50-backed RSA public endorsement key certificate.
  RSA_PUB_EK_CERT = 2;
  // Quote of the Cr50-backed RSU device ID.
  RSU_DEVICE_ID = 3;
  // Quote of RMA bytes (a complement of RMA bits with optional leading zeroes).
  RMA_BYTES = 4;
  // Quote of the Cr50-backed G2f certificate.
  G2F_CERT = 5;
}

// Holds information about a quote generated by the TPM.
message Quote {
  // The quote; a signature generated with the AIK.
  optional bytes quote = 1;
  // The serialized data that was quoted; this assists in verifying the quote.
  optional bytes quoted_data = 2;
  // The value of the PCR(s) at the time the quote was generated.
  optional bytes quoted_pcr_value = 3;
  // Source data which was originally used to extend the PCR. If this field
  // exists it can be expected that SHA1(pcr_source_hint) was extended into the
  // PCR.
  optional bytes pcr_source_hint = 4;
}

// Holds encrypted data and information required to decrypt it.
message EncryptedData {
  // A key that has been sealed to the TPM or wrapped by another key.
  optional bytes wrapped_key = 2;
  // The initialization vector used during encryption.
  optional bytes iv = 3;
  // MAC of (iv + encrypted_data).
  optional bytes mac = 4;
  optional bytes encrypted_data = 5;
  // An identifier for the wrapping key to assist in decryption.
  optional bytes wrapping_key_id = 6;
}

// The wrapper message of any data and its signature.
message SignedData {
  // The data to be signed.
  optional bytes data = 1;
  // The signature of the data field.
  optional bytes signature = 2;
}

// The first two fields are suitable for passing to Tspi_TPM_ActivateIdentity()
// directly when using TPM 1.2. For TPM 2.0 the first two fields are not used.
message EncryptedIdentityCredential {
  // TPM_ASYM_CA_CONTENTS, encrypted with EK public key.
  optional bytes asym_ca_contents = 1;
  // TPM_SYM_CA_ATTESTATION, encrypted with the key in aysm_ca_contents.
  optional bytes sym_ca_attestation = 2;

  optional TpmVersion tpm_version = 3;

  // The following fields are used only for TPM 2.0. For details see the TPM 2.0
  // specification Part 1 Rev 1.16:
  // - Section 9.5.3.3: General description of the scheme.
  // - Section 24: More details including how to use the seed to compute the
  //               values for 'credential_mac' and 'wrapped_certificate->
  //               wrapped_key'
  // - Section B.10.4: Encrypting the seed with a RSA EK.
  // - Section C.7.4: Encrypting the seed with an EC EK.

  // A seed encrypted with the EK public key. The TPM will use this seed to
  // derive both an HMAC key to verify the 'credential_mac' field and an AES key
  // to unwrap the 'wrapped_certificate->wrapped_key' field.
  optional bytes encrypted_seed = 4;

  // An integrity value computed using HMAC-SHA256 over the
  // 'wrapped_certificate.wrapped_key' field and the 'Name' of the identity key.
  optional bytes credential_mac = 5;

  // A certificate encrypted with a 'credential' that is decrypted by the TPM.
  // The 'wrapped_key' field contains the encrypted credential which is
  // encrypted using AES-256-CFB with a zero IV. The encryption of the
  // certificate itself uses AES-256-CBC with PKCS #5 padding and a random IV.
  // The encryption key is derived from the 'credential' using:
  //   SHA256('ENCRYPT' + credential)
  // The mac uses HMAC-SHA256 with a key derived using:
  //   SHA256('MAC' + credential)
  optional EncryptedData wrapped_certificate = 6;
}

// This message holds all information to be sent to the attestation server in
// order to complete enrollment.
message AttestationEnrollmentRequest {
  // The EK cert, in X.509 form, encrypted using the server's public key with
  // the following parameters:
  //   Key encryption: RSA-OAEP with no custom parameters.
  //   Data encryption: 256-bit key, AES-CBC with PKCS5 padding.
  //   MAC: HMAC-SHA-512 using the AES key.
  optional EncryptedData encrypted_endorsement_credential = 1;
  // The AIK public key, the raw TPM format. (TPM_PUBKEY for TPM 1.2,
  // TPMT_PUBLIC for TPM 2.0).
  optional bytes identity_public_key = 2;
  // PCR0 quoted by AIK.
  optional Quote pcr0_quote = 3;
  // PCR1 quoted by AIK.
  optional Quote pcr1_quote = 4;
  // DEN for enterprise zero-touch enrollment (crbug/624187).
  optional bytes enterprise_enrollment_nonce = 5;
  // The device TPM version.
  optional TpmVersion tpm_version = 6;
  // An encrypted quote of the RSA EK cert, in X.509 form, if the endorsement
  // credential is not RSA.
  optional EncryptedData encrypted_rsa_endorsement_quote = 7;
}

enum ResponseStatus {
  OK = 0;
  // Internal server error.
  SERVER_ERROR = 1;
  // The server cannot parse the request.
  BAD_REQUEST = 2;
  // The server rejects the request.
  REJECT = 3;
  // Only appears in enrollment response. The server returns the same generated
  // id and reports the quota limit exceeded status when the number of reset
  // action in a specified time window is more than self reset limitation.
  QUOTA_LIMIT_EXCEEDED = 4;
}

// The response from the attestation server for the enrollment request.
message AttestationEnrollmentResponse {
  optional ResponseStatus status = 1;
  // Short detail response message. Included when the result is not OK.
  optional string detail = 2;
  optional EncryptedIdentityCredential encrypted_identity_credential = 3;
  // Extra details included when the result is not OK.
  optional string extra_details = 4;
}

// `DEVICE_SETUP_CERTIFICATE` specific metadata.
message DeviceSetupCertificateMetadata {
  // 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;

  // Unix timestamp (in seconds) of the generation of the request.
  optional uint64 timestamp_seconds = 2;

  // 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 = 3;
}

// The certificate request to be sent to the attestation server.
message AttestationCertificateRequest {
  // The AIK cert in X.509 format.
  optional bytes identity_credential = 1;
  // A certified public key in TPM_PUBKEY (TPMT_PUBLIC for TPM 2.0).
  optional bytes certified_public_key = 3;
  // The serialized TPM_CERTIFY_INFO (TPMS_ATTEST for TPM 2.0) for the
  // certified key.
  optional bytes certified_key_info = 4;
  // The signature of the TPM_CERTIFY_INFO (TPMS_ATTEST for TPM 2.0) by the AIK.
  optional bytes certified_key_proof = 5;
  // A message identifier to be included in the response.
  optional bytes message_id = 10;
  // The certificate profile defines the type of certificate to issue.
  optional CertificateProfile profile = 11;
  // Information about the origin of the request which may be used depending on
  // the certificate profile.
  optional string origin = 12;
  // The index of a temporal value.  This may be used or ignored depending on
  // the certificate profile.
  optional int32 temporal_index = 13;
  // The device TPM version.
  optional TpmVersion tpm_version = 14;
  // NVRAM quoted by AIK. Keys are values of the NVRAMQuoteType. This is only
  // used for `ENTERPRISE_ENROLLMENT_CERTIFICATE` and
  // `ENTERPRISE_VTPM_EK_CERTIFICATE` profiles.
  map<int32, Quote> nvram_quotes = 15;
  // Certificate profile specific metadata.
  oneof metadata {
    // `DEVICE_SETUP_CERTIFICATE` specific metadata.
    DeviceSetupCertificateMetadata device_setup_certificate_metadata = 16;
  }
  // ADID read from the VPD. Used as the host identifier incorporated in the
  // certificates.
  // Used for `ENTERPRISE_ENROLLMENT_CERTIFICATE` and
  // `ENTERPRISE_VTPM_EK_CERTIFICATE` profiles only.
  optional bytes attested_device_id = 17;
}

// The response from the attestation server for the certificate request.
message AttestationCertificateResponse {
  optional ResponseStatus status = 1;
  // Short detail response message. Included when the result is not OK.
  optional string detail = 2;
  // The credential of the certified key in X.509 format.
  optional bytes certified_key_credential = 3;
  // The issuer intermediate CA certificate in X.509 format.
  optional bytes intermediate_ca_cert = 5;
  // A message identifier from the request this message is responding to.
  optional bytes message_id = 6;
  // Additional intermediate CA certificates that can help in validation.
  // Certificate chaining order is from the leaf to the root. That is,
  // |certified_key_credential| is signed by
  // |intermediate_ca_cert|, which is signed by
  // |additional_intermediate_ca_cert(0)|, which is signed by
  // |additional_intermediate_ca_cert(1)|, ... and so on.
  repeated bytes additional_intermediate_ca_cert = 7;
  // Extra details included when the result is not OK.
  optional string extra_details = 8;
}

// The reset request to be sent to the attestation server.
message AttestationResetRequest {
  // The AIK cert, in X.509 form, encrypted using the server's public key with
  // the following parameters:
  //   Key encryption: RSA-OAEP with no custom parameters.
  //   Data encryption: 256-bit key, AES-CBC with PKCS5 padding.
  //   MAC: HMAC-SHA-512 using the AES key.
  optional EncryptedData encrypted_identity_credential = 1;

  // The one time token to make sure the reset process can be triggered only
  // once.
  optional bytes token = 2;

  // The EK cert, in X.509 form, encrypted using the server's public key with
  // the following parameters:
  //   Key encryption: RSA-OAEP with no custom parameters.
  //   Data encryption: 256-bit key, AES-CBC with PKCS5 padding.
  //   MAC: HMAC-SHA-512 using the AES key.
  optional EncryptedData encrypted_endorsement_credential = 3;
}

// The response from the attestation server for the reset request.
message AttestationResetResponse {
  // The response status.
  optional ResponseStatus status = 1;
  // Short detail response message. Included when the result is not OK.
  optional string detail = 2;
  // Extra details included when the result is not OK.
  optional string extra_details = 3;
}

// The challenge data (as in challenge-response) generated by the server.
// Before transmitted to the client, this message will be wrapped as a
// SignedData message, in which the data field is the serialized Challenge
// message, and the signature field is the signature of the data field signed
// by the enterprise server using a hard-coded key. The signature algorithm is
// RSASSA-PKCS1-v1_5-SHA256.
message Challenge {
  // A string for the client to sanity check a legitimate challenge.
  optional string prefix = 1;
  // A 256-bit random value generated by the server.
  optional bytes nonce = 2;
  // A timestamp for a stateless server to limit the timeframe during which the
  // challenge may be replayed.
  optional int64 timestamp = 3;
}

// The response data (as in challenge-response) generated by the client.
// Before transmitted to the server, this message will be wrapped as a
// SignedData message, in which the data field is the serialized
// ChallengeResponse message, and the signature field is the signature of the
// data field signed by the client using the key being challenged. The
// signature algorithm is RSASSA-PKCS1-v1_5-SHA256.
message ChallengeResponse {
  // The original challenge data.
  optional SignedData challenge = 1;
  // A 256-bit random value generated by the client. Mixing in this nonce
  // prevents a caller from using a challenge to sign arbitrary data.
  optional bytes nonce = 2;
  // The KeyInfo message encrypted using a public encryption key, pushed via
  // policy with the following parameters:
  //   Key encryption: RSA-OAEP with no custom parameters.
  //   Data encryption: 256-bit key, AES-CBC with PKCS5 padding.
  //   MAC: HMAC-SHA-512 using the AES key.
  optional EncryptedData encrypted_key_info = 3;
}

// The data type of the message decrypted from
// ChallengeResponse.encrypted_key_info.encrypted_data field. This message holds
// information required by the Verified Access server API (VA) to complete the
// verification.
message KeyInfo {
  // Determines the verification flow on VA and the content of the VA response.
  optional VerifiedAccessFlow flow_type = 1;
  // Domain information about the device or user associated with the VA flow
  // type. For `flow_type` ENTERPRISE_MACHINE, this value is the enrolled
  // domain. For `flow_type` ENTERPRISE_USER, this value is the user's email
  // address.
  optional string domain = 2;
  // The virtual device ID associated with the device or user.
  optional bytes device_id = 3;
  // If the `flow_type` is ENTERPRISE_MACHINE, this value is the PCA-issued
  // certificate for the key.
  optional bytes certificate = 4;
  // If the `flow_type` is ENTERPRISE_USER, this value may hold a
  // SignedPublicKeyAndChallenge with a random challenge.  The
  // SignedPublicKeyAndChallenge specification is here:
  // https://developer.mozilla.org/en-US/docs/HTML/Element/keygen.
  optional bytes signed_public_key_and_challenge = 5;
  // The identifier of the customer, as defined by the Google Admin SDK at
  // https://developers.google.com/admin-sdk/directory/v1/guides/manage-customers
  optional string customer_id = 6;
  // A new field which contains public key generated by the CBCM-enrolled
  // browser if key type is CBCM
  optional bytes browser_instance_public_key = 7;
  // A new field which indicated the signing scheme used for the outer
  // SignedData message. We should populate this for any `flow_type`. For
  // `flow_type` ENTERPRISE_USER/ENTERPRISE_MACHINE (ChromeOS use case), this
  // will currently say "SHA256withRSA" at all times, but we should start
  // supporting ECDSA signing in the near future as per 2020 OKRs. For
  // `flow_type` CBCM, this will be one of the permitted_schemes from
  // DeviceIdentity policy.
  optional string signing_scheme = 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;
  // DM token to be used for this request.
  optional string dm_token = 11;
  // The identifier of the customer for the managed user, as defined by the
  // Google Admin SDK at
  // https://developers.google.com/admin-sdk/directory/v1/guides/manage-customers.
  optional string user_customer_id = 12;
  // Obfuscated gaia ID associated with the signed in managed user.
  optional string obfuscated_gaia_id = 13;
  // The ID of a profile on the device.
  optional string profile_id = 14;
}

// Device Trust Signals
message DeviceTrustSignals {
  option deprecated = true;
  // Device Id
  optional string device_id = 1;
  // Obfuscated CBCM-enrolled Customer Id
  optional string obfuscated_customer_id = 2;
  // Device serial number
  optional string serial_number = 3;
  // Human readable name for this device
  optional string display_name = 4;
  // OS running on the device (e.g. Chrome OS)
  optional string os = 5;
  // Device manufacturer (e.g. Dell)
  optional string device_manufacturer = 6;
  // Device model (e.g. iPhone 12 Max)
  optional string device_model = 7;
  // OS version (e.g. macOS 10.15.7)
  optional string os_version = 8;
  // IMEI
  repeated string imei = 9;
  // MEID
  repeated string meid = 10;
  // Hash of the EKPub certificate of the TPM on the device, if available.
  optional string tpm_hash = 11;
  // Is the disk encrypted
  optional bool is_disk_encrypted = 12;
  // Value of the AllowScreenLock policy.
  // https://chromeenterprise.google/policies/?policy=AllowScreenLock
  optional bool allow_screen_lock = 13;
  // Is the access to the OS user protected by a password
  optional bool is_protected_by_password = 14;
  // Is the device jailbroken or modified
  optional bool is_jailbroken = 15;
  // The CBCM enrollment domain of the browser.
  optional string enrollment_domain = 16;
  // Browser Version
  optional string browser_version = 17;
  // Value of the SafeBrowsingProtectionLevel policy.
  // https://chromeenterprise.google/policies/#SafeBrowsingProtectionLevel
  optional int32 safe_browsing_protection_level = 18;
  // Value of the SitePerProcess policy.
  // https://chromeenterprise.google/policies/#SitePerProcess
  optional bool site_isolation_enabled = 19;
  // ThirdPartyBlockingEnabled
  optional bool third_party_blocking_enabled = 20;
  // To determine whether users can access other computers
  // from Chrome using Chrome Remote Desktop
  optional bool remote_desktop_available = 21;
  // Signed in profile name
  optional string signed_in_profile_name = 22;
  // ChromeCleanupEnabled
  optional bool chrome_cleanup_enabled = 23;
  // PasswordProtectionWarningTrigger
  optional int32 password_protection_warning_trigger = 24;
  // DNS address
  optional string dns_address = 25;
  // BuiltInDnsClientEnabled
  optional bool built_in_dns_client_enabled = 26;
  // Whether the OS firewall is turned on
  optional bool firewall_on = 27;
  // The Windows domain the device has joined
  optional string windows_domain = 28;
}

// Possible VA flows supported by the Verified Access server API and chromium.
// The values will be used to distinguish between different prerequisites,
// verification methods and contents of VA challenge response.
enum VerifiedAccessFlow {
  // The flow of creating a challenge response for enterprise machine
  // verification. The VA challenge will be signed with the EMK. ChromeOS only.
  // Uses CertificateProfile: ENTERPRISE_MACHINE_CERTIFICATE
  // Uses AttestationKeyType: KEY_DEVICE
  ENTERPRISE_MACHINE = 0;
  // The flow of creating a challenge response for enterprise user verification.
  // The VA challenge will be signed with the EUK. ChromeOS only.
  // Uses CertificateProfile: ENTERPRISE_USER_CERTIFICATE
  // Uses AttestationKeyType: KEY_USER
  ENTERPRISE_USER = 1;
  // The flow of creating a challenge response for verifying a managed Chrome
  // Browser. It does not use remote attestation and instead relies on a key
  // exchange to sign the VA challenge. Chrome Browser only.
  // Uses CertificateProfile: n.a.
  // Uses AttestationKeyType: n.a.
  CBCM = 2;
  // The flow of creating a challenge response for verification during the
  // Device Trust Connector handshake. The VA challenge will be signed with a
  // device key. ChromeOS only.
  // Uses CertificateProfile: DEVICE_TRUST_USER_CERTIFICATE
  // Uses AttestationKeyType: KEY_DEVICE
  DEVICE_TRUST_CONNECTOR = 3;
}
