Merge "Revert "Transport protocol v1""
diff --git a/citadel/updater/updater.cpp b/citadel/updater/updater.cpp
index ecc8c35..3d7fd8c 100644
--- a/citadel/updater/updater.cpp
+++ b/citadel/updater/updater.cpp
@@ -675,6 +675,7 @@
   std::vector<uint8_t> data(sizeof(struct nugget_app_enable_update));
   struct nugget_app_enable_update *s =
     (struct nugget_app_enable_update*)data.data();
+  std::vector<uint8_t> reply;
 
   memset(&s->password, 0xff, sizeof(s->password));
   if (pw && *pw) {
@@ -687,10 +688,12 @@
   s->which_headers = options.enable_ro ? NUGGET_ENABLE_HEADER_RO : 0;
   s->which_headers |= options.enable_rw ? NUGGET_ENABLE_HEADER_RW : 0;
 
-  uint32_t rv = app.Call(NUGGET_PARAM_ENABLE_UPDATE, data, nullptr);
+  reply.reserve(1);
+  uint32_t rv = app.Call(NUGGET_PARAM_ENABLE_UPDATE, data, &reply);
 
   if (is_app_success(rv))
-    printf("Update enabled\n");
+    /* Reply byte is true only if header was CHANGED to valid */
+    printf("Update %s enabled\n", reply[0] ? "changed to" : "is already");
 
   return rv;
 }
diff --git a/nugget/include/app_nugget.h b/nugget/include/app_nugget.h
index f8e8fda..72572b9 100644
--- a/nugget/include/app_nugget.h
+++ b/nugget/include/app_nugget.h
@@ -110,12 +110,13 @@
 #define NUGGET_PARAM_ENABLE_UPDATE 0x0003
 /*
  * Mark the specified image header(s) as valid, if the provided password
- * matches.
+ * matches. Returns true if either header was CHANGED to valid, which is an
+ * indication that the AP should request a reboot so that it can take effect.
  *
  * @param args         struct nugget_app_enable_update
  * @param arg_len      sizeof(struct nugget_app_enable_update)
- * @param reply        <none>
- * @param reply_len    0
+ * @param reply        0 or 1
+ * @param reply_len    1 byte
  *
  * @errors             APP_ERROR_BOGUS_ARGS
  */
diff --git a/nugget/proto/nugget/app/keymaster/keymaster.options b/nugget/proto/nugget/app/keymaster/keymaster.options
index f765aaf..554b2dc 100644
--- a/nugget/proto/nugget/app/keymaster/keymaster.options
+++ b/nugget/proto/nugget/app/keymaster/keymaster.options
@@ -13,3 +13,5 @@
 nugget.app.keymaster.GetBootInfoResponse.boot_key max_size:32
 nugget.app.keymaster.GetBootInfoResponse.boot_hash max_size:32
 nugget.app.keymaster.ProvisionPresharedSecretRequest.preshared_secret max_size:32
+nugget.app.keymaster.StartAttestKeyRequest.not_before max_size:13
+nugget.app.keymaster.StartAttestKeyRequest.not_after max_size:13
diff --git a/nugget/proto/nugget/app/keymaster/keymaster.proto b/nugget/proto/nugget/app/keymaster/keymaster.proto
index 9559106..705bc85 100644
--- a/nugget/proto/nugget/app/keymaster/keymaster.proto
+++ b/nugget/proto/nugget/app/keymaster/keymaster.proto
@@ -52,7 +52,7 @@
   rpc GetKeyCharacteristics (GetKeyCharacteristicsRequest) returns (GetKeyCharacteristicsResponse);
   rpc ImportKey (ImportKeyRequest) returns (ImportKeyResponse);
   rpc ExportKey (ExportKeyRequest) returns (ExportKeyResponse);
-  rpc AttestKey (AttestKeyRequest) returns (AttestKeyResponse);
+  rpc StartAttestKey (StartAttestKeyRequest) returns (StartAttestKeyResponse);
   rpc UpgradeKey (UpgradeKeyRequest) returns (UpgradeKeyResponse);
   rpc DeleteKey (DeleteKeyRequest) returns (DeleteKeyResponse);
   rpc DeleteAllKeys (DeleteAllKeysRequest) returns (DeleteAllKeysResponse);
@@ -103,6 +103,13 @@
    * Called during provisioning by the CitadelProvision tool.
    */
   rpc ProvisionPresharedSecret (ProvisionPresharedSecretRequest) returns (ProvisionPresharedSecretResponse);
+
+  /*
+   * Additional attestation methods.
+   */
+  rpc ContinueAttestKey(ContinueAttestKeyRequest) returns (ContinueAttestKeyResponse);
+  rpc FinishAttestKey(FinishAttestKeyRequest) returns (FinishAttestKeyResponse);
+
   // These are implemented with a enum, so new RPCs must be appended, and
   // deprecated RPCs need placeholders.
 }
@@ -167,14 +174,38 @@
   ECKey ec = 4;
 };
 
-// AttestKey
-message AttestKeyRequest {
+// StartAttestKey
+message StartAttestKeyRequest {
   KeyBlob blob = 1;
   KeyParameters params = 2;
+  uint32 attestation_app_id_len = 3;
+  AttestationSelector selector = 4;
+  bytes not_before = 5;      // strftime('%y%m%d%H%M%SZ') [13 octects]
+  bytes not_after = 6;       // strftime('%y%m%d%H%M%SZ') [13 octects]
 }
-message AttestKeyResponse {
+message StartAttestKeyResponse {
   ErrorCode error_code = 1;
-  CertificateChain chain = 2;
+  OperationHandle handle = 2;
+  bytes certificate_prologue = 3;
+}
+
+// ContinueAttestKeyRequest
+message ContinueAttestKeyRequest {
+  OperationHandle handle = 1;
+  bytes attestation_app_id = 2;
+}
+message  ContinueAttestKeyResponse {
+  ErrorCode error_code = 1;
+  bytes certificate_body = 2;
+}
+
+// FinishAttestKeyRequest
+message FinishAttestKeyRequest {
+  OperationHandle handle = 1;
+}
+message  FinishAttestKeyResponse {
+  ErrorCode error_code = 1;
+  bytes certificate_epilogue = 2;
 }
 
 // UpgradeKey
diff --git a/nugget/proto/nugget/app/keymaster/keymaster_types.proto b/nugget/proto/nugget/app/keymaster/keymaster_types.proto
index 977595c..d56ff16 100644
--- a/nugget/proto/nugget/app/keymaster/keymaster_types.proto
+++ b/nugget/proto/nugget/app/keymaster/keymaster_types.proto
@@ -101,3 +101,9 @@
   NOT_SET = 0;
   ALREADY_SET = 1;
 }
+
+enum AttestationSelector {
+  ATTEST_TEST = 0;
+  ATTEST_BATCH = 1;
+  ATTEST_INDIVIDUAL = 2;
+}