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, "")
}
Exemple #4
0
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:.*`)
}
Exemple #5
0
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))
		}
	}))
}
Exemple #6
0
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")
}
Exemple #8
0
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))
	}
}