// DeviceSessionRequest produces a device-session-request with the given nonce, it also returns the encoded device serial assertion. It returns ErrNoSerial if the device serial is not yet initialized. func (ac *authContext) DeviceSessionRequest(nonce string) (deviceSessionRequest []byte, serial []byte, err error) { if ac.deviceAsserts == nil { return nil, nil, ErrNoSerial } req, ser, err := ac.deviceAsserts.DeviceSessionRequest(nonce) if err == state.ErrNoState { return nil, nil, ErrNoSerial } if err != nil { return nil, nil, err } return asserts.Encode(req), asserts.Encode(ser), nil }
func (chks *checkSuite) TestCheckForgery(c *C) { trustedKey := testPrivKey0 cfg := &asserts.DatabaseConfig{ Backstore: chks.bs, Trusted: []asserts.Assertion{asserts.BootstrapAccountKeyForTest("canonical", trustedKey.PublicKey())}, } db, err := asserts.OpenDatabase(cfg) c.Assert(err, IsNil) encoded := asserts.Encode(chks.a) content, encodedSig := chks.a.Signature() // forgery forgedSig := new(packet.Signature) forgedSig.PubKeyAlgo = packet.PubKeyAlgoRSA forgedSig.Hash = crypto.SHA512 forgedSig.CreationTime = time.Now() h := crypto.SHA512.New() h.Write(content) pk1 := packet.NewRSAPrivateKey(time.Unix(1, 0), testPrivKey1RSA) err = forgedSig.Sign(h, pk1, &packet.Config{DefaultHash: crypto.SHA512}) c.Assert(err, IsNil) buf := new(bytes.Buffer) forgedSig.Serialize(buf) b := append([]byte{0x1}, buf.Bytes()...) forgedSigEncoded := base64.StdEncoding.EncodeToString(b) forgedEncoded := bytes.Replace(encoded, encodedSig, []byte(forgedSigEncoded), 1) c.Assert(forgedEncoded, Not(DeepEquals), encoded) forgedAssert, err := asserts.Decode(forgedEncoded) c.Assert(err, IsNil) err = db.Check(forgedAssert) c.Assert(err, ErrorMatches, "failed signature verification: .*") }
func (s *FirstBootTestSuite) TestImportAssertionsFromSeedHappy(c *C) { ovld, err := overlord.New() c.Assert(err, IsNil) st := ovld.State() // add a bunch of assert files assertsChain := s.makeModelAssertionChain(c) for i, as := range assertsChain { fn := filepath.Join(dirs.SnapSeedDir, "assertions", strconv.Itoa(i)) err := ioutil.WriteFile(fn, asserts.Encode(as), 0644) c.Assert(err, IsNil) } // import them err = boot.ImportAssertionsFromSeed(st) c.Assert(err, IsNil) // verify that the model was added st.Lock() defer st.Unlock() db := assertstate.DB(st) as, err := db.Find(asserts.ModelType, map[string]string{ "series": "16", "brand-id": "my-brand", "model": "my-model", }) c.Assert(err, IsNil) _, ok := as.(*asserts.Model) c.Check(ok, Equals, true) ds, err := auth.Device(st) c.Assert(err, IsNil) c.Check(ds.Brand, Equals, "my-brand") c.Check(ds.Model, Equals, "my-model") }
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 (aks *accountKeySuite) TestAccountKeyRequestUntil(c *C) { db := aks.openDB(c) aks.prereqAccount(c, db) tests := []struct { untilHeader string until time.Time }{ {"", time.Time{}}, // zero time default {aks.until.Format(time.RFC3339), aks.until}, // in the future {aks.since.Format(time.RFC3339), aks.since}, // same as since } for _, test := range tests { c.Log(test) headers := map[string]interface{}{ "account-id": "acc-id1", "name": "default", "public-key-sha3-384": aks.keyID, "since": aks.since.Format(time.RFC3339), } if test.untilHeader != "" { headers["until"] = test.untilHeader } akr, err := asserts.SignWithoutAuthority(asserts.AccountKeyRequestType, headers, []byte(aks.pubKeyBody), aks.privKey) c.Assert(err, IsNil) a, err := asserts.Decode(asserts.Encode(akr)) c.Assert(err, IsNil) akr2 := a.(*asserts.AccountKeyRequest) c.Check(akr2.Until(), Equals, test.until) err = db.Check(akr2) c.Check(err, IsNil) } }
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) }
func generateSerialRequestAssertion() (string, error) { privateKey, err := generatePrivateKey() if err != nil { return "", err } encodedPubKey, err := asserts.EncodePublicKey(privateKey.PublicKey()) if err != nil { return "", err } // Generate a request-id r, _ := getRequestID() headers := map[string]interface{}{ "brand-id": request.Brand, "device-key": string(encodedPubKey), "request-id": r, "model": request.Model, "serial": request.SerialNumber, } sreq, err := asserts.SignWithoutAuthority(asserts.SerialRequestType, headers, []byte(""), privateKey) if err != nil { return "", err } assertSR := asserts.Encode(sreq) return string(assertSR), nil }
func (as *assertsSuite) TestSignFormatSanitySupportMultilineHeaderValues(c *C) { headers := map[string]interface{}{ "authority-id": "auth-id1", "primary-key": "0", } multilineVals := []string{ "a\n", "\na", "a\n\b\nc", "a\n\b\nc\n", "\na\n", "\n\na\n\nb\n\nc", } for _, multilineVal := range multilineVals { headers["multiline"] = multilineVal if len(multilineVal)%2 == 1 { headers["odd"] = "true" } a, err := asserts.AssembleAndSignInTest(asserts.TestOnlyType, headers, nil, testPrivKey1) c.Assert(err, IsNil) decoded, err := asserts.Decode(asserts.Encode(a)) c.Assert(err, IsNil) c.Check(decoded.Header("multiline"), Equals, multilineVal) } }
func (s *authContextSetupSuite) TestDeviceSessionRequest(c *C) { st := s.o.State() st.Lock() defer st.Unlock() st.Unlock() _, _, err := s.ac.DeviceSessionRequest("NONCE") st.Lock() c.Check(err, Equals, auth.ErrNoSerial) // setup serial and key in system state err = assertstate.Add(st, s.serial) c.Assert(err, IsNil) kpMgr, err := asserts.OpenFSKeypairManager(dirs.SnapDeviceDir) c.Assert(err, IsNil) err = kpMgr.Put(deviceKey) c.Assert(err, IsNil) auth.SetDevice(st, &auth.DeviceState{ Brand: s.serial.BrandID(), Model: s.serial.Model(), Serial: s.serial.Serial(), KeyID: deviceKey.PublicKey().ID(), }) st.Unlock() req, encSerial, err := s.ac.DeviceSessionRequest("NONCE") st.Lock() c.Assert(err, IsNil) c.Check(bytes.HasPrefix(req, []byte("type: device-session-request\n")), Equals, true) c.Check(encSerial, DeepEquals, asserts.Encode(s.serial)) }
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 (aks *accountKeySuite) TestAccountKeyRequestHappy(c *C) { akr, err := asserts.SignWithoutAuthority(asserts.AccountKeyRequestType, map[string]interface{}{ "account-id": "acc-id1", "name": "default", "public-key-sha3-384": aks.keyID, "since": aks.since.Format(time.RFC3339), }, []byte(aks.pubKeyBody), aks.privKey) c.Assert(err, IsNil) // roundtrip a, err := asserts.Decode(asserts.Encode(akr)) c.Assert(err, IsNil) akr2, ok := a.(*asserts.AccountKeyRequest) c.Assert(ok, Equals, true) db := aks.openDB(c) aks.prereqAccount(c, db) err = db.Check(akr2) c.Check(err, IsNil) c.Check(akr2.AccountID(), Equals, "acc-id1") c.Check(akr2.Name(), Equals, "default") c.Check(akr2.PublicKeyID(), Equals, aks.keyID) c.Check(akr2.Since(), Equals, aks.since) }
func getSerial(t *state.Task, privKey asserts.PrivateKey, device *auth.DeviceState, cfg *serialRequestConfig) (*asserts.Serial, error) { var serialSup serialSetup err := t.Get("serial-setup", &serialSup) if err != nil && err != state.ErrNoState { return nil, err } if serialSup.Serial != "" { // we got a serial, just haven't managed to save its info yet a, err := asserts.Decode([]byte(serialSup.Serial)) if err != nil { return nil, fmt.Errorf("internal error: cannot decode previously saved serial: %v", err) } return a.(*asserts.Serial), nil } client := &http.Client{Timeout: 30 * time.Second} // NB: until we get at least an Accepted (202) we need to // retry from scratch creating a new request-id because the // previous one used could have expired if serialSup.SerialRequest == "" { serialRequest, err := prepareSerialRequest(t, privKey, device, client, cfg) if err != nil { // errors & retries return nil, err } serialSup.SerialRequest = serialRequest } serial, err := submitSerialRequest(t, serialSup.SerialRequest, client, cfg) if err == errPoll { // we can/should reuse the serial-request t.Set("serial-setup", serialSup) return nil, errPoll } if err != nil { // errors & retries return nil, err } keyID := privKey.PublicKey().ID() if serial.BrandID() != device.Brand || serial.Model() != device.Model || serial.DeviceKey().ID() != keyID { return nil, fmt.Errorf("obtained serial assertion does not match provided device identity information (brand, model, key id): %s / %s / %s != %s / %s / %s", serial.BrandID(), serial.Model(), serial.DeviceKey().ID(), device.Brand, device.Model, keyID) } serialSup.Serial = string(asserts.Encode(serial)) t.Set("serial-setup", serialSup) if repeatRequestSerial == "after-got-serial" { // For testing purposes, ensure a crash in this state works. return nil, &state.Retry{} } return serial, nil }
func (s *imageSuite) TestHappyDecodeModelAssertion(c *C) { fn := filepath.Join(c.MkDir(), "model.assertion") err := ioutil.WriteFile(fn, asserts.Encode(s.model), 0644) c.Assert(err, IsNil) a, err := image.DecodeModelAssertion(&image.Options{ ModelFile: fn, }) c.Assert(err, IsNil) c.Check(a.Type(), Equals, asserts.ModelType) }
func (as *assertsSuite) TestSignFormatSanityEmptyBody(c *C) { headers := map[string]interface{}{ "authority-id": "auth-id1", "primary-key": "0", } a, err := asserts.AssembleAndSignInTest(asserts.TestOnlyType, headers, nil, testPrivKey1) c.Assert(err, IsNil) _, err = asserts.Decode(asserts.Encode(a)) c.Check(err, IsNil) }
func (s *FirstBootTestSuite) TestImportAssertionsFromSeedTwoModelAsserts(c *C) { st := s.overlord.State() st.Lock() defer st.Unlock() // write out two model assertions model := s.makeModelAssertion(c, "my-model") fn := filepath.Join(dirs.SnapSeedDir, "assertions", "model") err := ioutil.WriteFile(fn, asserts.Encode(model), 0644) c.Assert(err, IsNil) model2 := s.makeModelAssertion(c, "my-second-model") fn = filepath.Join(dirs.SnapSeedDir, "assertions", "model2") err = ioutil.WriteFile(fn, asserts.Encode(model2), 0644) c.Assert(err, IsNil) // try import and verify that its rejects because other assertions are // missing err = devicestate.ImportAssertionsFromSeed(st) c.Assert(err, ErrorMatches, "cannot add more than one model assertion") }
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 *storeTestSuite) TestAssertionsEndpointPreloaded(c *C) { // something preloaded resp, err := s.StoreGet(`/assertions/account/testrootorg`) c.Assert(err, IsNil) defer resp.Body.Close() c.Assert(resp.StatusCode, Equals, 200) c.Check(resp.Header.Get("Content-Type"), Equals, "application/x.ubuntu.assertion") body, err := ioutil.ReadAll(resp.Body) c.Assert(err, IsNil) c.Check(string(body), Equals, string(asserts.Encode(systestkeys.TestRootAccount))) }
func (as *assertsSuite) TestSignFormatSanityNonEmptyBody(c *C) { headers := map[string]interface{}{ "authority-id": "auth-id1", "primary-key": "0", } body := []byte("THE-BODY") a, err := asserts.AssembleAndSignInTest(asserts.TestOnlyType, headers, body, testPrivKey1) c.Assert(err, IsNil) c.Check(a.Body(), DeepEquals, body) decoded, err := asserts.Decode(asserts.Encode(a)) c.Assert(err, IsNil) c.Check(decoded.Body(), DeepEquals, body) }
func prepareSerialRequest(t *state.Task, privKey asserts.PrivateKey, device *auth.DeviceState, client *http.Client, cfg *serialRequestConfig) (string, error) { st := t.State() st.Unlock() defer st.Lock() req, err := http.NewRequest("POST", cfg.requestIDURL, nil) if err != nil { return "", fmt.Errorf("internal error: cannot create request-id request %q", cfg.requestIDURL) } cfg.applyHeaders(req) resp, err := client.Do(req) if err != nil { return "", retryErr(t, "cannot retrieve request-id for making a request for a serial: %v", err) } defer resp.Body.Close() if resp.StatusCode != 200 { return "", retryErr(t, "cannot retrieve request-id for making a request for a serial: unexpected status %d", resp.StatusCode) } dec := json.NewDecoder(resp.Body) var requestID requestIDResp err = dec.Decode(&requestID) if err != nil { // assume broken i/o return "", retryErr(t, "cannot read response with request-id for making a request for a serial: %v", err) } encodedPubKey, err := asserts.EncodePublicKey(privKey.PublicKey()) if err != nil { return "", fmt.Errorf("internal error: cannot encode device public key: %v", err) } headers := map[string]interface{}{ "brand-id": device.Brand, "model": device.Model, "request-id": requestID.RequestID, "device-key": string(encodedPubKey), } if cfg.proposedSerial != "" { headers["serial"] = cfg.proposedSerial } serialReq, err := asserts.SignWithoutAuthority(asserts.SerialRequestType, headers, cfg.body, privKey) if err != nil { return "", err } return string(asserts.Encode(serialReq)), nil }
func (x *cmdSignBuild) Execute(args []string) error { if len(args) > 0 { return ErrExtraArgs } snapDigest, snapSize, err := asserts.SnapFileSHA3_384(x.Positional.Filename) if err != nil { return err } gkm := asserts.NewGPGKeypairManager() privKey, err := gkm.GetByName(x.KeyName) if err != nil { // TRANSLATORS: %q is the key name, %v the error message return fmt.Errorf(i18n.G("cannot use %q key: %v"), x.KeyName, err) } pubKey := privKey.PublicKey() timestamp := time.Now().Format(time.RFC3339) headers := map[string]interface{}{ "developer-id": x.DeveloperID, "authority-id": x.DeveloperID, "snap-sha3-384": snapDigest, "snap-id": x.SnapID, "snap-size": fmt.Sprintf("%d", snapSize), "grade": x.Grade, "timestamp": timestamp, } adb, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ KeypairManager: gkm, }) if err != nil { return fmt.Errorf(i18n.G("cannot open the assertions database: %v"), err) } a, err := adb.Sign(asserts.SnapBuildType, headers, nil, pubKey.ID()) if err != nil { return fmt.Errorf(i18n.G("cannot sign assertion: %v"), err) } _, err = Stdout.Write(asserts.Encode(a)) if err != nil { return err } return nil }
func (as *assertsSuite) TestEncode(c *C) { encoded := []byte("type: test-only\n" + "authority-id: auth-id2\n" + "primary-key: xyz\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) encodeRes := asserts.Encode(a) c.Check(encodeRes, DeepEquals, encoded) }
// Sign produces the text of a signed assertion as specified by opts. func Sign(opts *Options, keypairMgr asserts.KeypairManager) ([]byte, error) { var headers map[string]interface{} err := json.Unmarshal(opts.Statement, &headers) if err != nil { return nil, fmt.Errorf("cannot parse the assertion input as JSON: %v", err) } typCand, ok := headers["type"] if !ok { return nil, fmt.Errorf("missing assertion type header") } typStr, ok := typCand.(string) if !ok { return nil, fmt.Errorf("assertion type must be a string, not: %v", typCand) } typ := asserts.Type(typStr) if typ == nil { return nil, fmt.Errorf("invalid assertion type: %v", headers["type"]) } var body []byte if bodyCand, ok := headers["body"]; ok { bodyStr, ok := bodyCand.(string) if !ok { return nil, fmt.Errorf("body if specified must be a string") } body = []byte(bodyStr) delete(headers, "body") } adb, err := asserts.OpenDatabase(&asserts.DatabaseConfig{ KeypairManager: keypairMgr, }) if err != nil { return nil, err } // TODO: teach Sign to cross check keyID and authority-id // against an account-key a, err := adb.Sign(typ, headers, body, opts.KeyID) if err != nil { return nil, err } return asserts.Encode(a), nil }
func (s *Store) assertionsEndpoint(w http.ResponseWriter, req *http.Request) { assertPath := strings.TrimPrefix(req.URL.Path, "/assertions/") bs, err := s.collectAssertions() if err != nil { http.Error(w, fmt.Sprintf("internal error collecting assertions: %v", err), http.StatusInternalServerError) return } comps := strings.Split(assertPath, "/") if len(comps) == 0 { http.Error(w, "missing assertion type", http.StatusBadRequest) return } typ := asserts.Type(comps[0]) if typ == nil { http.Error(w, fmt.Sprintf("unknown assertion type: %s", comps[0]), http.StatusBadRequest) return } if len(typ.PrimaryKey) != len(comps)-1 { http.Error(w, fmt.Sprintf("wrong primary key length: %v", comps), http.StatusBadRequest) return } a, err := s.retrieveAssertion(bs, typ, comps[1:]) if isAssertNotFound(err) { w.Header().Set("Content-Type", "application/problem+json") w.WriteHeader(404) w.Write([]byte(`{"status": 404}`)) return } if err != nil { http.Error(w, fmt.Sprintf("cannot retrieve assertion %v: %v", comps, err), http.StatusBadRequest) return } w.Header().Set("Content-Type", asserts.MediaType) w.WriteHeader(http.StatusOK) w.Write(asserts.Encode(a)) }
func (x *cmdExportKey) Execute(args []string) error { if len(args) > 0 { return ErrExtraArgs } keyName := string(x.Positional.KeyName) if keyName == "" { keyName = "default" } manager := asserts.NewGPGKeypairManager() if x.Account != "" { privKey, err := manager.GetByName(keyName) if err != nil { return err } pubKey := privKey.PublicKey() headers := map[string]interface{}{ "account-id": x.Account, "name": keyName, "public-key-sha3-384": pubKey.ID(), "since": time.Now().UTC().Format(time.RFC3339), // XXX: To support revocation, we need to check for matching known assertions and set a suitable revision if we find one. } body, err := asserts.EncodePublicKey(pubKey) if err != nil { return err } assertion, err := asserts.SignWithoutAuthority(asserts.AccountKeyRequestType, headers, body, privKey) if err != nil { return err } fmt.Fprint(Stdout, string(asserts.Encode(assertion))) } else { encoded, err := manager.Export(keyName) if err != nil { return err } fmt.Fprintf(Stdout, "%s\n", encoded) } return nil }
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 (s *FirstBootTestSuite) TestImportAssertionsFromSeedNoModelAsserts(c *C) { st := s.overlord.State() st.Lock() defer st.Unlock() assertsChain := s.makeModelAssertionChain(c) for _, as := range assertsChain { if as.Type() != asserts.ModelType { fn := filepath.Join(dirs.SnapSeedDir, "assertions", "model") err := ioutil.WriteFile(fn, asserts.Encode(as), 0644) c.Assert(err, IsNil) break } } // try import and verify that its rejects because other assertions are // missing err := devicestate.ImportAssertionsFromSeed(st) c.Assert(err, ErrorMatches, "need a model assertion") }
func (s *FirstBootTestSuite) TestImportAssertionsFromSeedMissingSig(c *C) { ovld, err := overlord.New() c.Assert(err, IsNil) st := ovld.State() // write out only the model assertion assertsChain := s.makeModelAssertionChain(c) for _, as := range assertsChain { if as.Type() == asserts.ModelType { fn := filepath.Join(dirs.SnapSeedDir, "assertions", "model") err := ioutil.WriteFile(fn, asserts.Encode(as), 0644) c.Assert(err, IsNil) break } } // try import and verify that its rejects because other assertions are // missing err = boot.ImportAssertionsFromSeed(st) c.Assert(err, ErrorMatches, "cannot find account-key .*: assertion not found") }
func (as *assertsSuite) TestSignFormatAndRevision(c *C) { headers := map[string]interface{}{ "authority-id": "auth-id1", "primary-key": "0", "format": "1", "revision": "11", } a, err := asserts.AssembleAndSignInTest(asserts.TestOnlyType, headers, nil, testPrivKey1) c.Check(a.Revision(), Equals, 11) c.Check(a.Format(), Equals, 1) c.Check(a.SupportedFormat(), Equals, true) a1, err := asserts.Decode(asserts.Encode(a)) c.Assert(err, IsNil) c.Check(a1.Revision(), Equals, 11) c.Check(a1.Format(), Equals, 1) c.Check(a1.SupportedFormat(), Equals, true) }
func generateSerialRequestAssertion(model, serial string) (string, error) { privateKey, _ := generatePrivateKey() encodedPubKey, _ := asserts.EncodePublicKey(privateKey.PublicKey()) headers := map[string]interface{}{ "brand-id": "System", "device-key": string(encodedPubKey), "request-id": "REQID", "model": model, } body := fmt.Sprintf("serial: %s", serial) sreq, err := asserts.SignWithoutAuthority(asserts.SerialRequestType, headers, []byte(body), privateKey) if err != nil { return "", err } assertSR := asserts.Encode(sreq) return string(assertSR), nil }
func (s *baseDeclSuite) TestBuiltin(c *C) { baseDecl := asserts.BuiltinBaseDeclaration() c.Check(baseDecl, IsNil) defer asserts.InitBuiltinBaseDeclaration(nil) const headers = ` type: base-declaration authority-id: canonical series: 16 revision: 0 plugs: network: true slots: network: allow-installation: slot-snap-type: - core ` err := asserts.InitBuiltinBaseDeclaration([]byte(headers)) c.Assert(err, IsNil) baseDecl = asserts.BuiltinBaseDeclaration() c.Assert(baseDecl, NotNil) cont, _ := baseDecl.Signature() c.Check(string(cont), Equals, strings.TrimSpace(headers)) c.Check(baseDecl.AuthorityID(), Equals, "canonical") c.Check(baseDecl.Series(), Equals, "16") c.Check(baseDecl.PlugRule("network").AllowAutoConnection[0].SlotAttributes, Equals, asserts.AlwaysMatchAttributes) c.Check(baseDecl.SlotRule("network").AllowInstallation[0].SlotSnapTypes, DeepEquals, []string{"core"}) enc := asserts.Encode(baseDecl) // it's expected that it cannot be decoded _, err = asserts.Decode(enc) c.Check(err, NotNil) }