syntax = "proto3";

package sa;
option go_package = "github.com/letsencrypt/boulder/sa/proto";

import "core/proto/core.proto";
import "google/protobuf/empty.proto";

service StorageAuthority {
  // Getters
  rpc GetRegistration(RegistrationID) returns (core.Registration) {}
  rpc GetRegistrationByKey(JSONWebKey) returns (core.Registration) {}
  rpc GetSerialMetadata(Serial) returns (SerialMetadata) {}
  rpc GetCertificate(Serial) returns (core.Certificate) {}
  rpc GetPrecertificate(Serial) returns (core.Certificate) {}
  rpc GetCertificateStatus(Serial) returns (core.CertificateStatus) {}
  rpc CountCertificatesByNames(CountCertificatesByNamesRequest) returns (CountByNames) {}
  rpc CountRegistrationsByIP(CountRegistrationsByIPRequest) returns (Count) {}
  rpc CountRegistrationsByIPRange(CountRegistrationsByIPRequest) returns (Count) {}
  rpc CountOrders(CountOrdersRequest) returns (Count) {}
  // Return a count of authorizations with status "invalid" that belong to
  // a given registration ID and expire in the given time range.
  rpc CountFQDNSets(CountFQDNSetsRequest) returns (Count) {}
  rpc FQDNSetExists(FQDNSetExistsRequest) returns (Exists) {}
  rpc PreviousCertificateExists(PreviousCertificateExistsRequest) returns (Exists) {}
  rpc GetAuthorization2(AuthorizationID2) returns (core.Authorization) {}
  rpc GetAuthorizations2(GetAuthorizationsRequest) returns (Authorizations) {}
  rpc GetPendingAuthorization2(GetPendingAuthorizationRequest) returns (core.Authorization) {}
  rpc CountPendingAuthorizations2(RegistrationID) returns (Count) {}
  rpc GetValidOrderAuthorizations2(GetValidOrderAuthorizationsRequest) returns (Authorizations) {}
  rpc CountInvalidAuthorizations2(CountInvalidAuthorizationsRequest) returns (Count) {}
  rpc GetValidAuthorizations2(GetValidAuthorizationsRequest) returns (Authorizations) {}
  rpc KeyBlocked(KeyBlockedRequest) returns (Exists) {}
  // Adders
  rpc NewRegistration(core.Registration) returns (core.Registration) {}
  rpc UpdateRegistration(core.Registration) returns (google.protobuf.Empty) {}
  rpc AddCertificate(AddCertificateRequest) returns (AddCertificateResponse) {}
  rpc AddPrecertificate(AddCertificateRequest) returns (google.protobuf.Empty) {}
  rpc AddSerial(AddSerialRequest) returns (google.protobuf.Empty) {}
  rpc DeactivateRegistration(RegistrationID) returns (google.protobuf.Empty) {}
  rpc NewOrder(NewOrderRequest) returns (core.Order) {}
  rpc NewOrderAndAuthzs(NewOrderAndAuthzsRequest) returns (core.Order) {}
  rpc SetOrderProcessing(OrderRequest) returns (google.protobuf.Empty) {}
  rpc SetOrderError(SetOrderErrorRequest) returns (google.protobuf.Empty) {}
  rpc FinalizeOrder(FinalizeOrderRequest) returns (google.protobuf.Empty) {}
  rpc GetOrder(OrderRequest) returns (core.Order) {}
  rpc GetOrderForNames(GetOrderForNamesRequest) returns (core.Order) {}
  rpc RevokeCertificate(RevokeCertificateRequest) returns (google.protobuf.Empty) {}
  rpc UpdateRevokedCertificate(RevokeCertificateRequest) returns (google.protobuf.Empty) {}
  rpc NewAuthorizations2(AddPendingAuthorizationsRequest) returns (Authorization2IDs) {}
  rpc FinalizeAuthorization2(FinalizeAuthorizationRequest) returns (google.protobuf.Empty) {}
  rpc DeactivateAuthorization2(AuthorizationID2) returns (google.protobuf.Empty) {}
  rpc AddBlockedKey(AddBlockedKeyRequest) returns (google.protobuf.Empty) {}
}

message RegistrationID {
  int64 id = 1;
}

message JSONWebKey {
  bytes jwk = 1; 
}

message AuthorizationID {
  string id = 1;
}

message GetPendingAuthorizationRequest {
  int64 registrationID = 1;
  string identifierType = 2;
  string identifierValue = 3;
  // Result must be valid until at least this Unix timestamp (nanos)
  int64 validUntil = 4;
}

message GetValidAuthorizationsRequest {
  int64 registrationID = 1;
  repeated string domains = 2;
  int64 now = 3; // Unix timestamp (nanoseconds)
}

message ValidAuthorizations {
  message MapElement {
          string domain = 1;
          core.Authorization authz = 2;
  }
  repeated MapElement valid = 1;
}

message Serial {
  string serial = 1;
}

message SerialMetadata {
  string serial = 1;
  int64 registrationID = 2;
  int64 created = 3; // Unix timestamp (nanoseconds)
  int64 expires = 4; // Unix timestamp (nanoseconds)
}

message Range {
  int64 earliest = 1; // Unix timestamp (nanoseconds)
  int64 latest = 2;   // Unix timestamp (nanoseconds)
}

message Count {
  int64 count = 1;
}

message CountCertificatesByNamesRequest {
  Range range = 1;
  repeated string names = 2;
}

message CountByNames {
  map<string, int64> counts = 1;
}

message CountRegistrationsByIPRequest {
  bytes ip = 1;
  Range range = 2;
}

message CountInvalidAuthorizationsRequest {
  int64 registrationID = 1;
  string hostname = 2;
  // Count authorizations that expire in this range.
  Range range = 3;
}

message CountOrdersRequest {
  int64 accountID = 1;
  Range range = 2;
}

message CountFQDNSetsRequest {
  int64 window = 1;
  repeated string domains = 2;
}

message FQDNSetExistsRequest {
  repeated string domains = 1;
}

message PreviousCertificateExistsRequest {
  string domain = 1;
  int64 regID = 2;
}

message Exists {
  bool exists = 1;
}

message AddSerialRequest {
  int64 regID = 1;
  string serial = 2;
  int64 created = 3; // Unix timestamp (nanoseconds)
  int64 expires = 4; // Unix timestamp (nanoseconds)
}

message AddCertificateRequest {
  bytes der = 1;
  int64 regID = 2;
  // A signed OCSP response for the certificate contained in "der".
  // Note: The certificate status in the OCSP response is assumed to be 0 (good).
  bytes ocsp = 3;
  // An issued time. When not present the SA defaults to using
  // the current time. The orphan-finder uses this parameter to add
  // certificates with the correct historic issued date
  int64 issued = 4;
  int64 issuerID = 5;
}

message AddCertificateResponse {
  string digest = 1;
}

message OrderRequest {
  int64 id = 1;
}

message NewOrderRequest {
  int64 registrationID = 1;
  int64 expires = 2;
  repeated string names = 3;
  repeated int64 v2Authorizations = 4;
}

message NewOrderAndAuthzsRequest {
  NewOrderRequest newOrder = 1;
  repeated core.Authorization newAuthzs = 2;
}

message SetOrderErrorRequest {
  int64 id = 1;
  core.ProblemDetails error = 2;
}

message GetValidOrderAuthorizationsRequest {
  int64 id = 1;
  int64 acctID = 2;
}

message GetOrderForNamesRequest {
  int64 acctID = 1;
  repeated string names = 2;
}

message FinalizeOrderRequest {
  int64 id = 1;
  string certificateSerial = 2;
}

message GetAuthorizationsRequest {
  int64 registrationID = 1;
  repeated string domains = 2;
  int64 now = 3; // Unix timestamp (nanoseconds)
}

message Authorizations {
  message MapElement {
          string domain = 1;
          core.Authorization authz = 2;
  }
  repeated MapElement authz = 1;
}

message AddPendingAuthorizationsRequest {
  repeated core.Authorization authz = 1;
}

message AuthorizationIDs {
  repeated string ids = 1;
}

message AuthorizationID2 {
  int64 id = 1;
}

message Authorization2IDs {
  repeated int64 ids = 1;
}

message RevokeCertificateRequest {
  string serial = 1;
  int64 reason = 2;
  int64 date = 3; // Unix timestamp (nanoseconds)
  int64 backdate = 5; // Unix timestamp (nanoseconds)
  bytes response = 4;
}

message FinalizeAuthorizationRequest {
  int64 id = 1;
  string status = 2;
  int64 expires = 3; // Unix timestamp (nanoseconds)
  string attempted = 4;
  repeated core.ValidationRecord validationRecords = 5;
  core.ProblemDetails validationError = 6;
  int64 attemptedAt = 7; // Unix timestamp (nanoseconds)
}

message AddBlockedKeyRequest {
  bytes keyHash = 1;
  int64 added = 2; // Unix timestamp (nanoseconds)
  string source = 3;
  string comment = 4;
  int64 revokedBy = 5;
}

message KeyBlockedRequest {
  bytes keyHash = 1;
}
