func (as *assertsSuite) TestAssembleRoundtrip(c *C) { encoded := []byte("type: test-only\n" + "format: 1\n" + "authority-id: auth-id2\n" + "primary-key: abc\n" + "revision: 5\n" + "header1: value1\n" + "header2: value2\n" + "body-length: 8\n" + "sign-key-sha3-384: Jv8_JiHiIzJVcO9M55pPdqSDWUvuhfDIBJUS-3VW7F_idjix7Ffn5qMxB21ZQuij\n\n" + "THE-BODY" + "\n\n" + "AXNpZw==") a, err := asserts.Decode(encoded) c.Assert(err, IsNil) cont, sig := a.Signature() reassembled, err := asserts.Assemble(a.Headers(), a.Body(), cont, sig) c.Assert(err, IsNil) c.Check(reassembled.Headers(), DeepEquals, a.Headers()) c.Check(reassembled.Body(), DeepEquals, a.Body()) reassembledEncoded := asserts.Encode(reassembled) c.Check(reassembledEncoded, DeepEquals, encoded) }
// serialRequestToSerial converts a serial-request to a serial assertion func serialRequestToSerial(assertion asserts.Assertion, signingLog *SigningLog) (asserts.Assertion, error) { // Create the serial assertion header from the serial-request headers serialHeaders := assertion.Headers() headers := map[string]interface{}{ "type": asserts.SerialType.Name, "authority-id": serialHeaders["brand-id"], "brand-id": serialHeaders["brand-id"], "serial": serialHeaders["serial"], "device-key": serialHeaders["device-key"], "sign-key-sha3-384": serialHeaders["sign-key-sha3-384"], "device-key-sha3-384": serialHeaders["sign-key-sha3-384"], "model": serialHeaders["model"], "timestamp": time.Now().Format(time.RFC3339), } // Get the serial-number from the header, but fallback to the body if it is not there if headers["serial"] == nil || headers["serial"].(string) == "" { // Decode the body which must be YAML, ignore errors body := make(map[string]interface{}) yaml.Unmarshal(assertion.Body(), &body) // Get the extra headers from the body headers["serial"] = body["serial"] } // Check that we have a serial if headers["serial"] == nil { logMessage("SIGN", "create-assertion", ErrorEmptySerial.Message) return nil, errors.New(ErrorEmptySerial.Message) } // Check that we have not already signed this device, and get the max. revision number for the serial number signingLog.SerialNumber = headers["serial"].(string) duplicateExists, maxRevision, err := Environ.DB.CheckForDuplicate(signingLog) if err != nil { logMessage("SIGN", "duplicate-assertion", err.Error()) return nil, errors.New(ErrorDuplicateAssertion.Message) } if duplicateExists { logMessage("SIGN", "duplicate-assertion", "The serial number and/or device-key have already been used to sign a device") } // Set the revision number, incrementing the previously used one signingLog.Revision = maxRevision + 1 headers["revision"] = fmt.Sprintf("%d", signingLog.Revision) // If we have a body, set the body length if len(assertion.Body()) > 0 { headers["body-length"] = serialHeaders["body-length"] } // Create a new serial assertion content, signature := assertion.Signature() return asserts.Assemble(headers, assertion.Body(), content, signature) }
func (as *assertsSuite) TestAssembleHeadersCheck(c *C) { cont := []byte("type: test-only\n" + "authority-id: auth-id2\n" + "primary-key: abc\n" + "revision: 5") headers := map[string]interface{}{ "type": "test-only", "authority-id": "auth-id2", "primary-key": "abc", "revision": 5, // must be a string actually! } _, err := asserts.Assemble(headers, nil, cont, nil) c.Check(err, ErrorMatches, `header "revision": header values must be strings or nested lists or maps with strings as the only scalars: 5`) }
// serialRequestToSerial converts a serial-request to a serial assertion func serialRequestToSerial(assertion asserts.Assertion) (asserts.Assertion, error) { headers := assertion.Headers() headers["type"] = asserts.SerialType.Name headers["authority-id"] = headers["brand-id"] headers["timestamp"] = time.Now().Format(time.RFC3339) delete(headers, "request-id") // Decode the body which must be YAML, ignore errors body := make(map[string]interface{}) yaml.Unmarshal(assertion.Body(), &body) // Get the extra headers from the body headers["serial"] = body["serial"] // Create a new serial assertion content, signature := assertion.Signature() return asserts.Assemble(headers, assertion.Body(), content, signature) }