acvp: detect header element in JSON.
Sometimes JSON vector files contain a header element that must be
duplicated into the output and sometimes they don't. Auto-detect this by
looking for a “url” field in the first element.
Change-Id: I76046adb8ea64fe5ac9bae9d6583546504723918
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/45524
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/util/fipstools/acvp/acvptool/acvp.go b/util/fipstools/acvp/acvptool/acvp.go
index 87c2f87..f497532 100644
--- a/util/fipstools/acvp/acvptool/acvp.go
+++ b/util/fipstools/acvp/acvptool/acvp.go
@@ -178,6 +178,20 @@
return s
}
+// looksLikeHeaderElement returns true iff element looks like it's a header,
+// not a test. Some ACVP files contain a header as the first element that
+// should be duplicated into the response, and some don't. If the element
+// contains a "url" field then we guess that it's a header.
+func looksLikeHeaderElement(element json.RawMessage) bool {
+ var headerFields struct {
+ URL string `json:"url"`
+ }
+ if err := json.Unmarshal(element, &headerFields); err != nil {
+ return false
+ }
+ return len(headerFields.URL) > 0
+}
+
// processFile reads a file containing vector sets, at least in the format
// preferred by our lab, and writes the results to stdout.
func processFile(filename string, supportedAlgos []map[string]interface{}, middle Middle) error {
@@ -191,11 +205,18 @@
return err
}
- // There must be at least a header and one vector set in the file.
- if len(elements) < 2 {
- return fmt.Errorf("only %d elements in JSON array", len(elements))
+ // There must be at least one element in the file.
+ if len(elements) < 1 {
+ return errors.New("JSON input is empty")
}
- header := elements[0]
+
+ var header json.RawMessage
+ if looksLikeHeaderElement(elements[0]) {
+ header, elements = elements[0], elements[1:]
+ if len(elements) == 0 {
+ return errors.New("JSON input is empty")
+ }
+ }
// Build a map of which algorithms our Middle supports.
algos := make(map[string]struct{})
@@ -213,13 +234,17 @@
var result bytes.Buffer
result.WriteString("[")
- headerBytes, err := json.MarshalIndent(header, "", " ")
- if err != nil {
- return err
- }
- result.Write(headerBytes)
- for i, element := range elements[1:] {
+ if header != nil {
+ headerBytes, err := json.MarshalIndent(header, "", " ")
+ if err != nil {
+ return err
+ }
+ result.Write(headerBytes)
+ result.WriteString(",")
+ }
+
+ for i, element := range elements {
var commonFields struct {
Algo string `json:"algorithm"`
ID uint64 `json:"vsId"`
@@ -247,7 +272,9 @@
return err
}
- result.WriteString(",")
+ if i != 0 {
+ result.WriteString(",")
+ }
result.Write(replyBytes)
}