syntax = "proto3";
//Version 1.0
package pb;
import "google/api/annotations.proto";

service WAVE {
  //Create a new WAVE entity, but do not publish it
  rpc CreateEntity(CreateEntityParams) returns (CreateEntityResponse) {
    option (google.api.http) = {
      post: "/v1/CreateEntity"
      body: "*"
    };
  }
  //Create a WAVE attestation, both the source and destination entities must
  //be published
  rpc CreateAttestation(CreateAttestationParams) returns (CreateAttestationResponse) {
    option (google.api.http) = {
      post: "/v1/CreateAttestation"
      body: "*"
    };
  }
  //Publish the given entity
  rpc PublishEntity(PublishEntityParams) returns (PublishEntityResponse)  {
    option (google.api.http) = {
      post: "/v1/PublishEntity"
      body: "*"
    };
  }
  //Publish an attestation
  rpc PublishAttestation(PublishAttestationParams) returns (PublishAttestationResponse)  {
    option (google.api.http) = {
      post: "/v1/PublishAttestation"
      body: "*"
    };
  }
  //Add an attestation to the given perspective graph
  rpc AddAttestation(AddAttestationParams) returns (AddAttestationResponse)  {
    option (google.api.http) = {
      post: "/v1/AddAttestation"
      body: "*"
    };
  }
  rpc LookupAttestations(LookupAttestationsParams) returns (LookupAttestationsResponse)  {
    option (google.api.http) = {
      post: "/v1/LookupAttestation"
      body: "*"
    };
  }
  rpc ResyncPerspectiveGraph(ResyncPerspectiveGraphParams) returns (ResyncPerspectiveGraphResponse)  {
    option (google.api.http) = {
      post: "/v1/ResyncPerspectiveGraph"
      body: "*"
    };
  }
  rpc SyncStatus(SyncParams) returns (SyncResponse)  {
    option (google.api.http) = {
      post: "/v1/SyncStatus"
      body: "*"
    };
  }
  rpc WaitForSyncComplete(SyncParams) returns (stream SyncResponse);
  rpc BuildRTreeProof(BuildRTreeProofParams) returns (BuildRTreeProofResponse) {
    option (google.api.http) = {
      post: "/v1/BuildRTreeProof"
      body: "*"
    };
  }
  rpc VerifyProof(VerifyProofParams) returns (VerifyProofResponse) {
    option (google.api.http) = {
      post: "/v1/VerifyProof"
      body: "*"
    };
  }
  rpc ListLocations(ListLocationsParams) returns (ListLocationsResponse) {
    option (google.api.http) = {
      post: "/v1/ListLocations"
      body: "*"
    };
  }
  rpc Inspect(InspectParams) returns (InspectResponse) {
    option (google.api.http) = {
      post: "/v1/Inspect"
      body: "*"
    };
  }
  rpc ResolveHash(ResolveHashParams) returns (ResolveHashResponse) {
    option (google.api.http) = {
      post: "/v1/ResolveHash"
      body: "*"
    };
  }
  rpc EncryptMessage(EncryptMessageParams) returns (EncryptMessageResponse) {
    option (google.api.http) = {
      post: "/v1/EncryptMessage"
      body: "*"
    };
  }
  rpc DecryptMessage(DecryptMessageParams) returns (DecryptMessageResponse) {
    option (google.api.http) = {
      post: "/v1/DecryptMessage"
      body: "*"
    };
  }
  rpc CreateNameDeclaration(CreateNameDeclarationParams) returns (CreateNameDeclarationResponse) {
    option (google.api.http) = {
      post: "/v1/CreateNameDeclaration"
      body: "*"
    };
  }
  rpc ResolveName(ResolveNameParams) returns (ResolveNameResponse) {
    option (google.api.http) = {
      post: "/v1/ResolveName"
      body: "*"
    };
  }
  rpc MarkEntityInteresting(MarkEntityInterestingParams) returns (MarkEntityInterestingResponse) {
    option (google.api.http) = {
      post: "/v1/MarkEntityInteresting"
      body: "*"
    };
  }
  rpc ResolveReverseName(ResolveReverseNameParams) returns (ResolveReverseNameResponse) {
    option (google.api.http) = {
      post: "/v1/ResolveReverseName"
      body: "*"
    };
  }
  rpc Revoke(RevokeParams) returns (RevokeResponse) {
    option (google.api.http) = {
      post: "/v1/Revoke"
      body: "*"
    };
  }
  rpc CompactProof(CompactProofParams) returns (CompactProofResponse) {
    option (google.api.http) = {
      post: "/v1/CompactProof"
      body: "*"
    };
  }
  rpc Sign(SignParams) returns (SignResponse) {
    option (google.api.http) = {
      post: "/v1/Sign"
      body: "*"
    };
  }
  rpc VerifySignature(VerifySignatureParams) returns (VerifySignatureResponse) {
    option (google.api.http) = {
      post: "/v1/VerifySignature"
      body: "*"
    };
  }
}

message SignParams {
  Perspective perspective = 1;
  bytes content = 2;
}
message SignResponse {
  Error error = 1;
  bytes signature = 2;
}
message VerifySignatureParams {
  bytes signer = 1;
  Location signerLocation = 2;
  bytes signature = 3;
  bytes content = 4;
}
message VerifySignatureResponse {
  Error error = 1;
}
message CompactProofParams {
  bytes DER = 1;
}
message CompactProofResponse {
  Error error = 1;
  bytes proofDER = 2;
}
message RevokeParams {
  Perspective perspective = 1;
  bytes attestationHash = 2;
  bytes nameDeclarationHash = 3;
  bool revokePerspective = 4;
}
message RevokeResponse {
  Error error = 1;
}
message ResolveReverseNameParams {
  Perspective perspective = 1;
  bytes hash = 2;
}
message ResolveReverseNameResponse {
  Error error = 1;
  string name = 2;
}
message MarkEntityInterestingParams {
  Perspective perspective = 1;
  bytes entity = 2;
  Location entityLocation = 3;
}
message MarkEntityInterestingResponse {
  Error error = 1;
}
message CreateNameDeclarationParams {
  Perspective perspective = 1;
  string name = 2;
  bytes subject = 3;
  Location subjectLocation = 4;
  //ms since epoch, if omitted default = now
  int64 validFrom = 5;
  //ms since epoch if omitted default = now+3 years
  int64 validUntil = 6;
  //if specified, the name declaration will be encrypted
  bytes namespace = 7;
  Location namespaceLocation = 8;
  repeated bytes partition = 9;
}
message CreateNameDeclarationResponse {
  Error error = 1;
  bytes DER = 2;
  bytes hash = 3;
}
message ResolveNameParams {
  Perspective perspective = 1;
  string name = 2;
  //If omitted, the perspective entity is used
  bytes topLevelAttester = 3;
}
message NameDeclaration {
  bytes hash = 1;
  string name = 2;
  bytes subject = 3;
  Location subjectLocation = 4;
  bytes attester = 5;
  Location attesterLocation = 6;
  int64 validFrom = 7;
  int64 validUntil = 8;
  bytes namespace = 9;
  Location namespaceLocation = 10;
  repeated bytes partition = 11;
  NameDeclarationValidity validity = 12;
}
message ResolveNameResponse {
  Error error = 1;
  Entity entity = 2;
  repeated NameDeclaration derivation = 3;
  Location location = 4;
}

message ResolveHashParams {
  bytes hash = 1;
  Perspective perspective = 2;
}
message ResolveHashResponse {
  Error error = 1;
  Location location = 2;
  Entity entity = 3;
  Attestation attestation = 4;
}
message InspectParams {
  bytes content = 1;
  bytes proverKey = 2;
  bytes verifierKey = 3;
}
message InspectResponse {
  Error error = 1;
  Entity entity = 2;
  Attestation attestation = 3;
}
message ListLocationsParams {

}
message ListLocationsResponse {
  Error error = 1;
  map<string, Location> agentLocations = 2;
}

message CreateEntityParams {
  //Milliseconds since the epoch
  int64 validFrom = 1;
  int64 validUntil = 2;
  Location revocationLocation = 3;
  string SecretPassphrase = 4;
}
message CreateEntityResponse {
  Error error = 1;
  bytes PublicDER = 2;
  bytes SecretDER = 3;
  bytes hash = 4;
}
message Entity {
  bytes hash = 1;
  int64 validFrom = 2;
  int64 validUntil = 3;
  EntityValidity validity = 4;
}
message CreateAttestationParams {
  Perspective perspective = 1;
  //If omitted will default to wr1
  string bodyScheme = 2;
  bytes subjectHash = 3;
  Location subjectLocation = 4;
  //If 0, will be set to time.Now. Ms since epoch
  int64 validFrom = 5;
  //If 0, will be set to some arbitrary default. Ms since epoch
  int64 validUntil = 6;
  Policy policy = 7;
  bool publish = 8;
}
message ResyncPerspectiveGraphParams {
  Perspective perspective = 1;
}
message ResyncPerspectiveGraphResponse {
  Error error = 1;
}
message SyncParams {
  Perspective perspective = 1;
}
message EncryptMessageParams {
  //This is no longer required
  Perspective unused = 1;

  //The payload of the message
  bytes content = 2;

  //If present, a direct decryption key will be generated
  bytes subjectHash = 3;
  Location subjectLocation = 4;

  //If present, an OAQUE decryption key will be generated
  bytes namespace = 5;
  Location namespaceLocation = 6;
  string resource = 7;
  //ms since epoch, if zero set to now
  int64 validFrom = 8;
  //ms since epoch, if zero set to now
  int64 validUntil = 9;
}
message EncryptMessageResponse {
  Error error = 1;
  bytes ciphertext = 2;
}
message DecryptMessageParams {
  Perspective perspective = 1;
  bytes ciphertext = 2;
  bool resyncFirst = 3;
}
message DecryptMessageResponse {
  Error error = 1;
  bytes content = 2;
}
message SyncResponse {
  Error error = 1;
  map<string, StorageDriverStatus> storageStatus = 2;
	int64 totalSyncRequests = 3;
	int64 completedSyncs = 4;
}
message StorageDriverStatus {
  bool operational = 1;
  map<string, string> info = 2;
}
message CreateAttestationResponse {
  Error error = 1;
  bytes DER = 2;
  bytes verifierKey = 3;
  bytes proverKey = 4;
  bytes hash = 5;
}
message PublishEntityParams {
  bytes DER = 1;
  Location location = 2;
}
message PublishEntityResponse {
  Error error = 1;
  bytes hash = 2;
}
message PublishAttestationParams {
  bytes DER = 1;
}
message PublishAttestationResponse {
  Error error = 1;
  bytes hash = 2;
}
message AddAttestationParams {
  Perspective perspective = 1;
  bytes DER = 2;
  bytes proverKey = 3;
}
message AddAttestationResponse {
  Error error = 1;
}
message LookupAttestationsParams {
  Perspective perspective = 1;
  bytes fromEntity = 2;
  bytes toEntity = 3;
}
message LookupAttestationsResponse {
  Error error = 1;
  repeated Attestation results = 2;
}

message Error {
  int32 code = 1;
  string message = 2;
}
message Perspective {
  EntitySecret entitySecret = 1;
  Location location = 2;
}
message Location {
  //One of the following
  LocationURI locationURI = 1;
  //The name of a location in the agent config
  string agentLocation = 2;
}
message LocationURI {
  string URI = 1;
  int32 version = 2;
}
message EntitySecret {
  bytes DER = 1;
  bytes passphrase = 2;
}
message Attestation {
  bytes DER = 1;
  bytes hash = 2;
  AttestationBody body = 3;
  bytes verifierKey = 4;
  bytes proverKey = 5;
  bytes subjectHash = 6;
  Location subjectLocation = 7;
  AttestationValidity validity = 8;
  repeated bytes partition = 9;
}

message AttestationBody {
  bytes DecodedBodyDER = 1;
  bytes attesterHash = 2;
  Location attesterLocation = 3;
  Policy policy = 4;
  int64 validFrom = 5;
  int64 validUntil = 6;
}

message AttestationValidity {
  bool valid = 1;
  bool revoked = 2;
  bool expired = 3;
  bool malformed = 4;
  bool notDecrypted = 5;
  bool srcInvalid = 6;
  bool dstInvalid = 7;
  string message = 8;
  bool notValidYet = 9;
}
message EntityValidity {
  bool valid = 1;
  bool revoked = 2;
  bool expired = 3;
  bool malformed = 4;
  string message = 5;
  bool notValidYet = 6;
}
message NameDeclarationValidity {
  bool valid = 1;
  bool revoked = 2;
  bool expired = 3;
  bool malformed = 4;
  string message = 5;
  bool notValidYet = 6;
}
message Policy {
  TrustLevelPolicy trustLevelPolicy = 1;
  RTreePolicy rTreePolicy = 2;
}
message TrustLevelPolicy {
  int32 trust = 1;
}
message RTreePolicy {
  bytes namespace = 1;
  uint32 indirections = 2;
  repeated RTreePolicyStatement statements = 3;
  repeated bytes visibilityURI = 4;
}
message RTreePolicyStatement {
  bytes permissionSet = 1;
  repeated string permissions = 2;
  string resource = 3;
}
message BuildRTreeProofParams {
  Perspective perspective = 1;
  //If omitted, will default to the perspective entity
  bytes subjectHash = 2;
  bytes namespace = 3;
  repeated RTreePolicyStatement statements = 4;
  bool resyncFirst = 5;
}
message BuildRTreeProofResponse {
  Error error = 1;
  Proof result = 2;
  bytes proofDER = 3;
}
message VerifyProofParams {
  bytes       proofDER = 1;
  RTreePolicy requiredRTreePolicy = 2;
  bytes     subject = 3;
}
message VerifyProofResponse {
  Error error = 1;
  Proof result = 2;
}
message Proof {
  repeated Attestation elements = 1;
  repeated ProofPath paths = 2;
  Policy policy = 3;
  int64 expiry = 4;
  bytes subject = 5;
  Location subjectLocation = 6;
}
message ProofPath {
  repeated int32 elements = 1;
}
