func (s *SnapKeysSuite) TestExportKeyAccount(c *C) { rootPrivKey, _ := assertstest.GenerateKey(1024) storePrivKey, _ := assertstest.GenerateKey(752) storeSigning := assertstest.NewStoreStack("canonical", rootPrivKey, storePrivKey) manager := asserts.NewGPGKeypairManager() assertstest.NewAccount(storeSigning, "developer1", nil, "") rest, err := snap.Parser().ParseArgs([]string{"export-key", "another", "--account=developer1"}) c.Assert(err, IsNil) c.Assert(rest, DeepEquals, []string{}) assertion, err := asserts.Decode(s.stdout.Bytes()) c.Assert(err, IsNil) c.Check(assertion.Type(), Equals, asserts.AccountKeyRequestType) c.Check(assertion.Revision(), Equals, 0) c.Check(assertion.HeaderString("account-id"), Equals, "developer1") c.Check(assertion.HeaderString("name"), Equals, "another") c.Check(assertion.HeaderString("public-key-sha3-384"), Equals, "DVQf1U4mIsuzlQqAebjjTPYtYJ-GEhJy0REuj3zvpQYTZ7EJj7adBxIXLJ7Vmk3L") since, err := time.Parse(time.RFC3339, assertion.HeaderString("since")) c.Assert(err, IsNil) zone, offset := since.Zone() c.Check(zone, Equals, "UTC") c.Check(offset, Equals, 0) c.Check(s.Stderr(), Equals, "") privKey, err := manager.Get(assertion.HeaderString("public-key-sha3-384")) c.Assert(err, IsNil) err = asserts.SignatureCheck(assertion, privKey.PublicKey()) c.Assert(err, IsNil) }
func (ss *serialSuite) TestDeviceSessionRequest(c *C) { ts := time.Now().UTC().Round(time.Second) sessReq, err := asserts.SignWithoutAuthority(asserts.DeviceSessionRequestType, map[string]interface{}{ "brand-id": "brand-id1", "model": "baz-3000", "serial": "99990", "nonce": "NONCE", "timestamp": ts.Format(time.RFC3339), }, nil, ss.deviceKey) c.Assert(err, IsNil) // roundtrip a, err := asserts.Decode(asserts.Encode(sessReq)) c.Assert(err, IsNil) sessReq2, ok := a.(*asserts.DeviceSessionRequest) c.Assert(ok, Equals, true) // standalone signature check err = asserts.SignatureCheck(sessReq2, ss.deviceKey.PublicKey()) c.Check(err, IsNil) c.Check(sessReq2.BrandID(), Equals, "brand-id1") c.Check(sessReq2.Model(), Equals, "baz-3000") c.Check(sessReq2.Serial(), Equals, "99990") c.Check(sessReq2.Nonce(), Equals, "NONCE") c.Check(sessReq2.Timestamp().Equal(ts), Equals, true) }
func (ss *serialSuite) TestSerialRequestHappy(c *C) { sreq, err := asserts.SignWithoutAuthority(asserts.SerialRequestType, map[string]interface{}{ "brand-id": "brand-id1", "model": "baz-3000", "device-key": ss.encodedDevKey, "request-id": "REQID", }, []byte("HW-DETAILS"), ss.deviceKey) c.Assert(err, IsNil) // roundtrip a, err := asserts.Decode(asserts.Encode(sreq)) c.Assert(err, IsNil) sreq2, ok := a.(*asserts.SerialRequest) c.Assert(ok, Equals, true) // standalone signature check err = asserts.SignatureCheck(sreq2, sreq2.DeviceKey()) c.Check(err, IsNil) c.Check(sreq2.BrandID(), Equals, "brand-id1") c.Check(sreq2.Model(), Equals, "baz-3000") c.Check(sreq2.RequestID(), Equals, "REQID") c.Check(sreq2.Serial(), Equals, "") }
func (ss *serialSuite) TestSignatureCheckError(c *C) { sreq, err := asserts.SignWithoutAuthority(asserts.TestOnlyNoAuthorityType, map[string]interface{}{ "hdr": "FOO", }, nil, testPrivKey1) c.Assert(err, IsNil) err = asserts.SignatureCheck(sreq, testPrivKey2.PublicKey()) c.Check(err, ErrorMatches, `failed signature verification:.*`) }
func (s *deviceMgrSuite) mockServer(c *C, reqID string) *httptest.Server { var mu sync.Mutex count := 0 return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case "/identity/api/v1/request-id": w.WriteHeader(http.StatusOK) io.WriteString(w, fmt.Sprintf(`{"request-id": "%s"}`, reqID)) case "/identity/api/v1/serial": c.Check(r.Header.Get("X-Extra-Header"), Equals, "extra") fallthrough case "/identity/api/v1/devices": mu.Lock() serialNum := 9999 + count count++ mu.Unlock() b, err := ioutil.ReadAll(r.Body) c.Assert(err, IsNil) a, err := asserts.Decode(b) c.Assert(err, IsNil) serialReq, ok := a.(*asserts.SerialRequest) c.Assert(ok, Equals, true) err = asserts.SignatureCheck(serialReq, serialReq.DeviceKey()) c.Assert(err, IsNil) c.Check(serialReq.BrandID(), Equals, "canonical") c.Check(serialReq.Model(), Equals, "pc") if reqID == "REQID-POLL" && serialNum != 10002 { w.WriteHeader(http.StatusAccepted) return } serialStr := fmt.Sprintf("%d", serialNum) if serialReq.Serial() != "" { // use proposed serial serialStr = serialReq.Serial() } serial, err := s.storeSigning.Sign(asserts.SerialType, map[string]interface{}{ "brand-id": "canonical", "model": "pc", "serial": serialStr, "device-key": serialReq.HeaderString("device-key"), "device-key-sha3-384": serialReq.SignKeyID(), "timestamp": time.Now().Format(time.RFC3339), }, serialReq.Body(), "") c.Assert(err, IsNil) w.Header().Set("Content-Type", asserts.MediaType) w.WriteHeader(http.StatusOK) w.Write(asserts.Encode(serial)) } })) }
func (s *deviceMgrSuite) TestDeviceAssertionsDeviceSessionRequest(c *C) { // nothing there _, _, err := s.mgr.DeviceSessionRequest("NONCE-1") c.Check(err, Equals, state.ErrNoState) // setup state as done by device initialisation s.state.Lock() devKey, _ := assertstest.GenerateKey(1024) encDevKey, err := asserts.EncodePublicKey(devKey.PublicKey()) c.Check(err, IsNil) seriala, err := s.storeSigning.Sign(asserts.SerialType, map[string]interface{}{ "brand-id": "canonical", "model": "pc", "serial": "8989", "device-key": string(encDevKey), "device-key-sha3-384": devKey.PublicKey().ID(), "timestamp": time.Now().Format(time.RFC3339), }, nil, "") c.Assert(err, IsNil) err = assertstate.Add(s.state, seriala) c.Assert(err, IsNil) auth.SetDevice(s.state, &auth.DeviceState{ Brand: "canonical", Model: "pc", Serial: "8989", KeyID: devKey.PublicKey().ID(), }) s.mgr.KeypairManager().Put(devKey) s.state.Unlock() sessReq, serial, err := s.mgr.DeviceSessionRequest("NONCE-1") c.Assert(err, IsNil) c.Check(serial.Serial(), Equals, "8989") // correctly signed with device key err = asserts.SignatureCheck(sessReq, devKey.PublicKey()) c.Check(err, IsNil) c.Check(sessReq.BrandID(), Equals, "canonical") c.Check(sessReq.Model(), Equals, "pc") c.Check(sessReq.Serial(), Equals, "8989") c.Check(sessReq.Nonce(), Equals, "NONCE-1") }
func (ss *serialSuite) TestSerialProofHappy(c *C) { sproof, err := asserts.SignWithoutAuthority(asserts.SerialProofType, map[string]interface{}{ "nonce": "NONCE", }, nil, ss.deviceKey) c.Assert(err, IsNil) // roundtrip a, err := asserts.Decode(asserts.Encode(sproof)) c.Assert(err, IsNil) sproof2, ok := a.(*asserts.SerialProof) c.Assert(ok, Equals, true) // standalone signature check err = asserts.SignatureCheck(sproof2, ss.deviceKey.PublicKey()) c.Check(err, IsNil) c.Check(sproof2.Nonce(), Equals, "NONCE") }
func handle(w http.ResponseWriter, r *http.Request) { switch r.URL.Path { case "/request-id": w.WriteHeader(http.StatusOK) io.WriteString(w, fmt.Sprintf(`{"request-id": "REQ-ID"}`)) case "/serial": db, err := asserts.OpenDatabase(&asserts.DatabaseConfig{}) if err != nil { internalError(w, "cannot open signing db: %v", err) return } err = db.ImportKey(devPrivKey) if err != nil { internalError(w, "cannot import signing key: %v", err) return } b, err := ioutil.ReadAll(r.Body) if err != nil { internalError(w, "cannot read request: %v", err) return } a, err := asserts.Decode(b) if err != nil { badRequestError(w, "cannot decode request: %v", err) return } serialReq, ok := a.(*asserts.SerialRequest) if !ok { badRequestError(w, "request is not a serial-request") return } err = asserts.SignatureCheck(serialReq, serialReq.DeviceKey()) if err != nil { badRequestError(w, "bad serial-request: %v", err) return } serialStr := "7777" if r.Header.Get("X-Use-Proposed") == "yes" { // use proposed serial serialStr = serialReq.Serial() } serial, err := db.Sign(asserts.SerialType, map[string]interface{}{ "authority-id": "developer1", "brand-id": "developer1", "model": serialReq.Model(), "serial": serialStr, "device-key": serialReq.HeaderString("device-key"), "device-key-sha3-384": serialReq.SignKeyID(), "timestamp": time.Now().Format(time.RFC3339), }, serialReq.Body(), devPrivKey.PublicKey().ID()) if err != nil { internalError(w, "cannot sign serial: %v", err) return } w.Header().Set("Content-Type", asserts.MediaType) w.WriteHeader(http.StatusOK) w.Write(asserts.Encode(serial)) } }