161 lines
4.3 KiB
Protocol Buffer
161 lines
4.3 KiB
Protocol Buffer
//
|
|
// Copyright 2023 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
syntax = "proto3";
|
|
|
|
// iOS - package name determines class prefix
|
|
package SVR2Proto;
|
|
|
|
// Client protocol for SecureValueRecovery2 (SVR2).
|
|
//
|
|
// A client that wishes to store a secret should call Backup,
|
|
// followed by Expose. Backup adds the secret to the store,
|
|
// and Expose makes that secret available for restoration. Subsequent
|
|
// calls to Restore allow the client to retrieve the stored secret.
|
|
// Calls to Backup and Expose are idempotent. A client should call
|
|
// Backup until it succeeds, then call Expose until it succeeds.
|
|
// A client should NOT call Backup+Expose until the pair succeeds,
|
|
// as doing so potentially resets the `tries` counter and allows
|
|
// for brute force attempts against the pin. If Backup succeeds but
|
|
// a subsequent Expose call returns status=ERROR, the client can be
|
|
// pretty sure that something nefarious is going on, and they should
|
|
// reconsider storing their secret.
|
|
|
|
message Request {
|
|
|
|
// reserved for use by server (backupId)
|
|
reserved 1;
|
|
|
|
// oneof inner {
|
|
optional BackupRequest backup = 2;
|
|
optional ExposeRequest expose = 5;
|
|
optional RestoreRequest restore = 3;
|
|
optional DeleteRequest delete = 4;
|
|
// }
|
|
}
|
|
|
|
message Response {
|
|
// oneof inner {
|
|
optional BackupResponse backup = 1;
|
|
optional ExposeResponse expose = 4;
|
|
optional RestoreResponse restore = 2;
|
|
optional DeleteResponse delete = 3;
|
|
// }
|
|
}
|
|
|
|
//
|
|
// backup
|
|
//
|
|
|
|
message BackupRequest {
|
|
// If the backup_id does not already exist, a new backup will be created
|
|
//
|
|
// If a backup already exists, it will be overwritten and response will have
|
|
// status=OK.
|
|
bytes data = 1; // between 16 and 48 bytes
|
|
bytes pin = 2; // 32 bytes
|
|
uint32 max_tries = 3; // in range [1,255]
|
|
}
|
|
|
|
message BackupResponse {
|
|
enum Status {
|
|
UNSET = 0; // never returned
|
|
OK = 1; // successfully set db[backup_id]=data
|
|
}
|
|
|
|
Status status = 1;
|
|
}
|
|
|
|
//
|
|
// restore
|
|
//
|
|
|
|
message RestoreRequest {
|
|
bytes pin = 1; // 32 bytes
|
|
}
|
|
|
|
message RestoreResponse {
|
|
enum Status {
|
|
UNSET = 0; // never returned
|
|
OK = 1; // successfully restored, [data] will be set
|
|
MISSING = 2; // db[backup_id] does not exist
|
|
PIN_MISMATCH = 3; // pin did not match, tries were decremented
|
|
}
|
|
|
|
Status status = 1;
|
|
bytes data = 2; // between 16 and 48 bytes, if set
|
|
uint32 tries = 3; // in range [0,255]
|
|
}
|
|
|
|
//
|
|
// delete
|
|
//
|
|
|
|
message DeleteRequest {
|
|
}
|
|
|
|
message DeleteResponse {
|
|
}
|
|
|
|
//
|
|
// expose
|
|
//
|
|
|
|
message ExposeRequest {
|
|
bytes data = 1;
|
|
}
|
|
|
|
message ExposeResponse {
|
|
enum Status {
|
|
UNSET = 0; // never returned
|
|
OK = 1; // successfully restored, [data] will be set
|
|
|
|
// If this status comes back after a successful Backup() call,
|
|
// this should be cause for concern.
|
|
// It means that someone has either reset, deleted, or tried to brute-force
|
|
// the backup since it was created.
|
|
ERROR = 2;
|
|
}
|
|
|
|
Status status = 1;
|
|
}
|
|
|
|
message ClientHandshakeStart {
|
|
// Public key associated with this server's enclave. For use in test-only
|
|
// contexts where attestation is not available
|
|
bytes test_only_pubkey = 1;
|
|
|
|
// Remote-attestation evidence associated with the public key
|
|
bytes evidence = 2;
|
|
|
|
// Endorsements of remote-attestation evidence.
|
|
bytes endorsement = 3;
|
|
}
|
|
|
|
|
|
// RaftGroupConfig is a configuration shared by members of a Raft group.
|
|
// It's created only once, on creation of the Raft group. From that
|
|
// point forward, it's shared between replicas as they're added to the
|
|
// group, and it's not possible to modify it externally.
|
|
//
|
|
// An attested RaftGroupConfig will be returned as part of the evidence.
|
|
// Clients must validate that the attested configuration matches their
|
|
// expected configuration.
|
|
message RaftGroupConfig {
|
|
|
|
// The unique group id for the raft group
|
|
fixed64 group_id = 1;
|
|
|
|
// This raft group will refuse to serve client request with
|
|
// <min_voting_replicas, and will refuse to add new voting members
|
|
// when max_voting_replicas has been reached.
|
|
uint32 min_voting_replicas = 2;
|
|
uint32 max_voting_replicas = 3;
|
|
// Anything which, in normal Raft, would require quorum() participants
|
|
// to push forward will instead require quorum() + super_majority. Should
|
|
// there be fewer than super_majority total nodes in the Raft, all Raft
|
|
// nodes will be required.
|
|
uint32 super_majority = 4;
|
|
}
|