2026-09-12 08:57:29 +08:00
|
|
|
package onboarding
|
|
|
|
|
|
|
|
|
|
import (
|
2026-10-08 10:06:44 +08:00
|
|
|
"bytes"
|
2026-09-12 08:57:29 +08:00
|
|
|
"encoding/hex"
|
|
|
|
|
"encoding/json"
|
|
|
|
|
"os"
|
2026-10-08 10:06:44 +08:00
|
|
|
"strings"
|
2026-09-12 08:57:29 +08:00
|
|
|
"testing"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestDEVREQ1IndependentVector(t *testing.T) {
|
|
|
|
|
raw, err := os.ReadFile("../../test/fixtures/onboarding-devreq1.json")
|
|
|
|
|
must(t, err)
|
|
|
|
|
var v struct {
|
|
|
|
|
KeyHex, Method, Path, DeviceID, Nonce, RequestID, Body, Signature string
|
|
|
|
|
KeyVersion, Timestamp int64
|
|
|
|
|
}
|
|
|
|
|
must(t, json.Unmarshal(raw, &v))
|
|
|
|
|
key, err := hex.DecodeString(v.KeyHex)
|
|
|
|
|
must(t, err)
|
|
|
|
|
got := RequestMAC(key, v.Method, v.Path, v.DeviceID, v.KeyVersion, v.Timestamp, v.Nonce, v.RequestID, []byte(v.Body))
|
|
|
|
|
if got != v.Signature {
|
|
|
|
|
t.Fatalf("independent vector mismatch: %s", got)
|
|
|
|
|
}
|
|
|
|
|
if RequestMAC([]byte(v.KeyHex), v.Method, v.Path, v.DeviceID, v.KeyVersion, v.Timestamp, v.Nonce, v.RequestID, []byte(v.Body)) == v.Signature {
|
|
|
|
|
t.Fatal("text key accepted as raw key")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
func TestStrictJSONRejectsAmbiguousBodies(t *testing.T) {
|
|
|
|
|
for _, raw := range []string{`{"boot_id":"a","boot_id":"b"}`, `{"boot_id":"a","unknown":true}`, `[]`, `{} {}`, "{\"boot_id\":\"\xff\"}"} {
|
|
|
|
|
var out RegisterInput
|
|
|
|
|
if StrictJSON([]byte(raw), &out) == nil {
|
|
|
|
|
t.Fatalf("accepted invalid body %q", raw)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-10-08 10:06:44 +08:00
|
|
|
|
|
|
|
|
func TestSealDeviceKeyMatchesAuthenticationStorageFormat(t *testing.T) {
|
|
|
|
|
const deviceID = "11111111-1111-4111-8111-111111111111"
|
|
|
|
|
masterKey := strings.Repeat("15", 32)
|
|
|
|
|
key := bytes.Repeat([]byte{0x5a}, 32)
|
|
|
|
|
sealed, err := SealDeviceKey(masterKey, deviceID, 3, key)
|
|
|
|
|
must(t, err)
|
|
|
|
|
crypt, err := newCryptor(masterKey)
|
|
|
|
|
must(t, err)
|
|
|
|
|
opened, err := crypt.open(sealed, keyAAD(deviceID, 3))
|
|
|
|
|
must(t, err)
|
|
|
|
|
if !bytes.Equal(opened, key) {
|
|
|
|
|
t.Fatal("sealed device key did not round-trip through onboarding authentication format")
|
|
|
|
|
}
|
|
|
|
|
}
|