]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
nts: fix error response to NTS-KE request
authorMiroslav Lichvar <mlichvar@redhat.com>
Thu, 23 Jul 2020 13:46:57 +0000 (15:46 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Thu, 23 Jul 2020 13:53:24 +0000 (15:53 +0200)
When the request has an unrecognized critical record before the
NEXT_PROTOCOL and AEAD_ALGORITHM records, respond with error 0
(unrecognized critical record) instead of 1 (bad request).

When the request has multiple NEXT_PROTOCOL or AEAD_ALGORITHM records,
respond with error 1 (bad request).

nts_ke_server.c
test/unit/nts_ke_server.c

index daf7e593c725c14564464770a8e064eee96d2188..1049da00a0eed18c801c3faf6e1ab0b9c098fce5 100644 (file)
@@ -330,6 +330,15 @@ prepare_response(NKSN_Instance session, int error, int next_protocol, int aead_a
     datum = htons(error);
     if (!NKSN_AddRecord(session, 1, NKE_RECORD_ERROR, &datum, sizeof (datum)))
       return 0;
+  } else if (next_protocol < 0) {
+    if (!NKSN_AddRecord(session, 1, NKE_RECORD_NEXT_PROTOCOL, NULL, 0))
+      return 0;
+  } else if (aead_algorithm < 0) {
+    datum = htons(next_protocol);
+    if (!NKSN_AddRecord(session, 1, NKE_RECORD_NEXT_PROTOCOL, &datum, sizeof (datum)))
+      return 0;
+    if (!NKSN_AddRecord(session, 1, NKE_RECORD_AEAD_ALGORITHM, NULL, 0))
+      return 0;
   } else {
     datum = htons(next_protocol);
     if (!NKSN_AddRecord(session, 1, NKE_RECORD_NEXT_PROTOCOL, &datum, sizeof (datum)))
@@ -376,6 +385,8 @@ prepare_response(NKSN_Instance session, int error, int next_protocol, int aead_a
 static int
 process_request(NKSN_Instance session)
 {
+  int next_protocol_records = 0, aead_algorithm_records = 0;
+  int next_protocol_values = 0, aead_algorithm_values = 0;
   int next_protocol = -1, aead_algorithm = -1, error = -1;
   int i, critical, type, length;
   uint16_t data[NKE_MAX_RECORD_BODY_LENGTH / sizeof (uint16_t)];
@@ -383,7 +394,7 @@ process_request(NKSN_Instance session)
   assert(NKE_MAX_RECORD_BODY_LENGTH % sizeof (uint16_t) == 0);
   assert(sizeof (uint16_t) == 2);
 
-  while (error == -1) {
+  while (error < 0) {
     if (!NKSN_GetRecord(session, &critical, &type, &length, &data, sizeof (data)))
       break;
 
@@ -393,7 +404,11 @@ process_request(NKSN_Instance session)
           error = NKE_ERROR_BAD_REQUEST;
           break;
         }
+
+        next_protocol_records++;
+
         for (i = 0; i < MIN(length, sizeof (data)) / 2; i++) {
+          next_protocol_values++;
           if (ntohs(data[i]) == NKE_NEXT_PROTOCOL_NTPV4)
             next_protocol = NKE_NEXT_PROTOCOL_NTPV4;
         }
@@ -403,7 +418,11 @@ process_request(NKSN_Instance session)
           error = NKE_ERROR_BAD_REQUEST;
           break;
         }
+
+        aead_algorithm_records++;
+
         for (i = 0; i < MIN(length, sizeof (data)) / 2; i++) {
+          aead_algorithm_values++;
           if (ntohs(data[i]) == AEAD_AES_SIV_CMAC_256)
             aead_algorithm = AEAD_AES_SIV_CMAC_256;
         }
@@ -419,8 +438,12 @@ process_request(NKSN_Instance session)
     }
   }
 
-  if (aead_algorithm < 0 || next_protocol < 0)
-    error = NKE_ERROR_BAD_REQUEST;
+  if (error < 0) {
+    if (next_protocol_records != 1 || next_protocol_values < 1 ||
+        (next_protocol == NKE_NEXT_PROTOCOL_NTPV4 &&
+         (aead_algorithm_records != 1 || aead_algorithm_values < 1)))
+      error = NKE_ERROR_BAD_REQUEST;
+  }
 
   if (!prepare_response(session, error, next_protocol, aead_algorithm))
     return 0;
index 33b6108bbb38f87d197e2c82c203da129a489950..f4f03a102ad6ebde381954cb2f46f71d16c98cbe 100644 (file)
@@ -50,7 +50,7 @@ prepare_request(NKSN_Instance session, int valid)
   if (valid)
     index = -1;
   else
-    index = random() % 7;
+    index = random() % 9;
   DEBUG_LOG("index=%d", index);
 
   NKSN_BeginMessage(session);
@@ -61,30 +61,34 @@ prepare_request(NKSN_Instance session, int valid)
 
   if (index != 0) {
     memset(data, NKE_NEXT_PROTOCOL_NTPV4 + 1, sizeof (data));
+    data[0] = htons(NKE_NEXT_PROTOCOL_NTPV4);
     if (index == 1)
-      data[0] = htons(NKE_NEXT_PROTOCOL_NTPV4 + random() % 10 + 1);
-    else
-      data[0] = htons(NKE_NEXT_PROTOCOL_NTPV4);
-    if (index == 2)
+      length = 0;
+    else if (index == 2)
       length = 3 + random() % 15 * 2;
     else
       length = 2 + random() % 16 * 2;
     TEST_CHECK(NKSN_AddRecord(session, 1, NKE_RECORD_NEXT_PROTOCOL, data, length));
   }
 
-  if (index != 3) {
-    if (index == 4)
-      data[0] = htons(AEAD_AES_SIV_CMAC_256 + random() % 10 + 1);
-    else
-      data[0] = htons(AEAD_AES_SIV_CMAC_256);
+  if (index == 3)
+    TEST_CHECK(NKSN_AddRecord(session, 1, NKE_RECORD_NEXT_PROTOCOL, data, length));
+
+  if (index != 4) {
+    data[0] = htons(AEAD_AES_SIV_CMAC_256);
     if (index == 5)
+      length = 0;
+    else if (index == 6)
       length = 3 + random() % 15 * 2;
     else
       length = 2 + random() % 16 * 2;
     TEST_CHECK(NKSN_AddRecord(session, 1, NKE_RECORD_AEAD_ALGORITHM, data, length));
   }
 
-  if (index == 6) {
+  if (index == 7)
+    TEST_CHECK(NKSN_AddRecord(session, 1, NKE_RECORD_AEAD_ALGORITHM, data, length));
+
+  if (index == 8) {
     length = random() % (sizeof (data) + 1);
     TEST_CHECK(NKSN_AddRecord(session, 1, 1000 + random() % 1000, data, length));
   }