func TestListTrackingJSON(t *testing.T) { tc := SetupEngineTest(t, "track") defer tc.Cleanup() fu := CreateAndSignupFakeUser(tc, "track") fu.LoginOrBust(tc) trackAlice(tc, fu) defer untrackAlice(tc, fu) arg := ListTrackingEngineArg{JSON: true, Verbose: true} eng := NewListTrackingEngine(&arg, tc.G) ctx := Context{} err := RunEngine(eng, &ctx) if err != nil { t.Fatal("Error in ListTrackingEngine:", err) } jw, err := jsonw.Unmarshal([]byte(eng.JSONResult())) if err != nil { t.Fatal(err) } pgpKeys := jw.AtIndex(0).AtPath("body.track.pgp_keys") n, err := pgpKeys.Len() if err != nil { t.Fatal(err) } if n != 1 { t.Errorf("num pgp_keys: %d, expected 1", n) } }
func (h ConfigHandler) SetValue(_ context.Context, arg keybase1.SetValueArg) (err error) { w := h.G().Env.GetConfigWriter() if arg.Path == "users" { err = fmt.Errorf("The field 'users' cannot be edited for fear of config corruption") return err } switch { case arg.Value.IsNull: w.SetNullAtPath(arg.Path) case arg.Value.S != nil: w.SetStringAtPath(arg.Path, *arg.Value.S) case arg.Value.I != nil: w.SetIntAtPath(arg.Path, *arg.Value.I) case arg.Value.B != nil: w.SetBoolAtPath(arg.Path, *arg.Value.B) case arg.Value.O != nil: var jw *jsonw.Wrapper jw, err = jsonw.Unmarshal([]byte(*arg.Value.O)) if err == nil { err = w.SetWrapperAtPath(arg.Path, jw) } default: err = fmt.Errorf("Bad type for setting a value") } if err == nil { h.G().ConfigReload() } return err }
// CounterSign implements CounterSign in kex2.Provisioner. func (e *Kex2Provisioner) CounterSign(input keybase1.HelloRes) (sig []byte, err error) { e.G().Log.Debug("+ CounterSign()") defer func() { e.G().Log.Debug("- CounterSign() -> %s", libkb.ErrToOk(err)) }() jw, err := jsonw.Unmarshal([]byte(input)) if err != nil { return nil, err } // check the reverse signature if err = e.checkReverseSig(jw); err != nil { e.G().Log.Debug("provisioner failed to verify reverse sig: %s", err) return nil, err } e.G().Log.Debug("provisioner verified reverse sig") // remember some device information for ProvisionUI.ProvisionerSuccess() if err = e.rememberDeviceInfo(jw); err != nil { return nil, err } // sign the whole thing with provisioner's signing key s, _, _, err := libkb.SignJSON(jw, e.signingKey) if err != nil { return nil, err } return []byte(s), nil }
func (j *JSONLocalDb) Lookup(id DbKey) (*jsonw.Wrapper, error) { bytes, found, err := j.engine.Lookup(id) var ret *jsonw.Wrapper if found { ret, err = jsonw.Unmarshal(bytes) } return ret, err }
func (path PathSteps) VerifyPath(curr NodeHash, uidS string) (juser *jsonw.Wrapper, err error) { bpath := uidS pos := 0 lastTyp := 0 for i, step := range path { payload := step.node if !curr.Check(payload) { err = fmt.Errorf("Hash mismatch at level=%d", i) break } var jw *jsonw.Wrapper jw, err = jsonw.Unmarshal([]byte(payload)) if err != nil { err = fmt.Errorf("Can't parse JSON at level=%d: %s", i, err) break } plen := len(step.prefix) epos := pos + plen if bpath[pos:epos] != step.prefix { err = fmt.Errorf("Path mismatch at level %d: %s != %s", i, bpath[pos:epos], step.prefix) break } pos = epos lastTyp, err = jw.AtKey("type").GetInt() if err != nil { err = fmt.Errorf("At level %d, failed to get a valid 'type'", i) break } if lastTyp == MerkleTreeNode { if plen == 0 { err = fmt.Errorf("Empty prefix len at level=%d", i) return } curr, err = GetNodeHash(jw.AtKey("tab").AtKey(step.prefix)) if err != nil { err = MerkleNotFoundError{uidS, err.Error()} break } juser = nil } else { juser = jw.AtKey("tab").AtKey(uidS) } } if err == nil && juser == nil { err = MerkleNotFoundError{uidS, "tree path didn't end in a leaf"} } return }
func (h IdentifyUIHandler) handleShowTrackerPopupCreate(ctx context.Context, cli gregor1.IncomingInterface, item gregor.Item) error { h.G().Log.Debug("handleShowTrackerPopupCreate: %+v", item) if item.Body() == nil { return errors.New("gregor handler for show_tracker_popup: nil message body") } body, err := jsonw.Unmarshal(item.Body().Bytes()) if err != nil { h.G().Log.Debug("body failed to unmarshal", err) return err } uidString, err := body.AtPath("uid").GetString() if err != nil { h.G().Log.Debug("failed to extract uid", err) return err } uid, err := keybase1.UIDFromString(uidString) if err != nil { h.G().Log.Debug("failed to convert UID from string", err) return err } identifyUI, err := h.G().UIRouter.GetIdentifyUI() if err != nil { h.G().Log.Debug("failed to get IdentifyUI", err) return err } if identifyUI == nil { h.G().Log.Debug("got nil IdentifyUI") return errors.New("got nil IdentifyUI") } secretUI, err := h.G().UIRouter.GetSecretUI(0) if err != nil { h.G().Log.Debug("failed to get SecretUI", err) return err } if secretUI == nil { h.G().Log.Debug("got nil SecretUI") return errors.New("got nil SecretUI") } engineContext := engine.Context{ IdentifyUI: identifyUI, SecretUI: secretUI, } identifyReason := keybase1.IdentifyReason{ Type: keybase1.IdentifyReasonType_TRACK, // TODO: text here? } identifyArg := keybase1.Identify2Arg{Uid: uid, Reason: identifyReason} identifyEng := engine.NewIdentify2WithUID(h.G(), &identifyArg) identifyEng.SetResponsibleGregorItem(item) return identifyEng.Run(&engineContext) }
func importTrackingLink(t *testing.T, g *libkb.GlobalContext) *libkb.TrackChainLink { jw, err := jsonw.Unmarshal([]byte(trackingServerReply)) if err != nil { t.Fatal(err) } cl, err := libkb.ImportLinkFromServer(g, nil, jw, trackingUID) if err != nil { t.Fatal(err) } gl := libkb.GenericChainLink{ChainLink: cl} tcl, err := libkb.ParseTrackChainLink(gl) if err != nil { t.Fatal(err) } return tcl }
func (h IdentifyUIHandler) handleShowTrackerPopupDismiss(ctx context.Context, cli gregor1.IncomingInterface, item gregor.Item) error { h.G().Log.Debug("handleShowTrackerPopupDismiss: %+v", item) if item.Body() == nil { return errors.New("gregor dismissal for show_tracker_popup: nil message body") } body, err := jsonw.Unmarshal(item.Body().Bytes()) if err != nil { h.G().Log.Debug("body failed to unmarshal", err) return err } uidString, err := body.AtPath("uid").GetString() if err != nil { h.G().Log.Debug("failed to extract uid", err) return err } uid, err := keybase1.UIDFromString(uidString) if err != nil { h.G().Log.Debug("failed to convert UID from string", err) return err } user, err := libkb.LoadUser(libkb.NewLoadUserByUIDArg(h.G(), uid)) if err != nil { h.G().Log.Debug("failed to load user from UID", err) return err } identifyUI, err := h.G().UIRouter.GetIdentifyUI() if err != nil { h.G().Log.Debug("failed to get IdentifyUI", err) return err } if identifyUI == nil { h.G().Log.Debug("got nil IdentifyUI") return errors.New("got nil IdentifyUI") } reason := keybase1.DismissReason{ Type: keybase1.DismissReasonType_HANDLED_ELSEWHERE, } identifyUI.Dismiss(user.GetName(), reason) return nil }
func NewMerkleRootFromJSON(jw *jsonw.Wrapper, g *GlobalContext) (ret *MerkleRoot, err error) { var seqno int64 var sigs *jsonw.Wrapper var payloadJSONString string var pj *jsonw.Wrapper var fp PGPFingerprint var rh, lurh NodeHash var ctime int64 if sigs, err = jw.AtKey("sigs").ToDictionary(); err != nil { return } if payloadJSONString, err = jw.AtKey("payload_json").GetString(); err != nil { return } if pj, err = jsonw.Unmarshal([]byte(payloadJSONString)); err != nil { return } GetPGPFingerprintVoid(pj.AtPath("body.key.fingerprint"), &fp, &err) pj.AtPath("body.seqno").GetInt64Void(&seqno, &err) GetNodeHashVoid(pj.AtPath("body.root"), &rh, &err) lurh, _ = GetNodeHash(pj.AtPath("body.legacy_uid_root")) pj.AtKey("ctime").GetInt64Void(&ctime, &err) if err != nil { return } ret = &MerkleRoot{ seqno: Seqno(seqno), pgpFingerprint: fp, sigs: sigs, payloadJSONString: payloadJSONString, payloadJSON: pj, rootHash: rh, legacyUIDRootHash: lurh, ctime: ctime, Contextified: NewContextified(g), } return }
func (s *sendInvitationMock) Post(arg APIArg) (*APIRes, error) { if _, err := s.APIArgRecorder.Post(arg); err != nil { return nil, err } jw, err := jsonw.Unmarshal([]byte(`{"status":{"code":0,"name":"OK"},"short_code":"clip outside broccoli culture","invitation_id":"2b25175f6da1d9155f23800d","csrf_token":"lgHZIDBlNjRhNDBhOTQ3ZWYyMTMxOWQ4MzM1Y2M4YjQ1YjE5zlcVNMHOAAFRgMDEIFyHOIg/AetihKRvVMNT2NoBNNG1QoCVxtDfzEK7/rdF"}`)) if err != nil { return nil, err } return &APIRes{ Status: jw.AtKey("status"), Body: jw, HTTPStatus: 200, AppStatus: &AppStatus{ Code: SCOk, Name: "OK", Desc: "Ok", }, }, nil }
// HandleHello implements HandleHello in kex2.Provisionee. func (e *Kex2Provisionee) HandleHello(harg keybase1.HelloArg) (res keybase1.HelloRes, err error) { e.G().Log.Debug("+ HandleHello()") defer func() { e.G().Log.Debug("- HandleHello() -> %s", libkb.ErrToOk(err)) }() // save parts of the hello arg for later: e.uid = harg.Uid e.sessionToken = harg.Token e.csrfToken = harg.Csrf e.pps = harg.Pps jw, err := jsonw.Unmarshal([]byte(harg.SigBody)) if err != nil { return res, err } // need the username later: e.username, err = jw.AtPath("body.key.username").GetString() if err != nil { return res, err } e.eddsa, err = libkb.GenerateNaclSigningKeyPair() if err != nil { return res, err } if err = e.addDeviceSibkey(jw); err != nil { return res, err } if err = e.reverseSig(jw); err != nil { return res, err } out, err := jw.Marshal() if err != nil { return res, err } return keybase1.HelloRes(out), err }
func TestAPIServerPostJSON(t *testing.T) { tc := libkb.SetupTest(t, "apiserver", 2) defer tc.Cleanup() tc.G.SetService() _, err := kbtest.CreateAndSignupFakeUser("apivr", tc.G) if err != nil { t.Fatal(err) } jsonPayload := []keybase1.StringKVPair{ {Key: "sigs", Value: "[]"}, } arg := keybase1.PostJSONArg{ Endpoint: "key/multi", JSONPayload: jsonPayload, } handler := NewAPIServerHandler(nil, tc.G) res, err := handler.doPostJSON(arg) if err != nil { t.Fatal(err) } jw, err := jsonw.Unmarshal([]byte(res.Body)) if err != nil { t.Fatal(err) } namew := jw.AtKey("status").AtKey("name") name, err := namew.GetString() if err != nil { t.Fatal(err) } if name != "OK" { t.Fatalf("wrong name returned: %s != %s", name, "OK") } }
func TestAPIServerGet(t *testing.T) { tc := libkb.SetupTest(t, "apiserver", 2) defer tc.Cleanup() tc.G.SetService() _, err := kbtest.CreateAndSignupFakeUser("apivr", tc.G) if err != nil { t.Fatal(err) } harg := []keybase1.StringKVPair{ {Key: "username", Value: "t_alice"}, {Key: "fields", Value: "basics"}, } arg := keybase1.GetArg{ Endpoint: "user/lookup", Args: harg, } handler := NewAPIServerHandler(nil, tc.G) res, err := handler.doGet(arg) if err != nil { t.Fatal(err) } jw, err := jsonw.Unmarshal([]byte(res.Body)) if err != nil { t.Fatal(err) } usernamew := jw.AtKey("them").AtKey("basics").AtKey("username") username, err := usernamew.GetString() if err != nil { t.Fatal(err) } if username != "t_alice" { t.Fatalf("wrong username returned: %s != %s", username, "t_alice") } }
func (g *gregorHandler) kbfsFavorites(ctx context.Context, m gregor.OutOfBandMessage) error { if m.Body() == nil { return errors.New("gregor handler for kbfs.favorites: nil message body") } body, err := jsonw.Unmarshal(m.Body().Bytes()) if err != nil { return err } action, err := body.AtPath("action").GetString() if err != nil { return err } switch action { case "create", "delete": return g.notifyFavoritesChanged(ctx, m.UID()) default: return fmt.Errorf("unhandled kbfs.favorites action %q", action) } }
func (e *Kex2Provisionee) decodeSig(sig []byte) (*decodedSig, error) { body, err := base64.StdEncoding.DecodeString(string(sig)) if err != nil { return nil, err } packet, err := libkb.DecodePacket(body) if err != nil { return nil, err } naclSig, ok := packet.Body.(*libkb.NaclSigInfo) if !ok { return nil, libkb.UnmarshalError{T: "Nacl signature"} } jw, err := jsonw.Unmarshal(naclSig.Payload) if err != nil { return nil, err } res := decodedSig{ sigID: libkb.ComputeSigIDFromSigBody(body), linkID: libkb.ComputeLinkID(naclSig.Payload), } res.seqno, err = jw.AtKey("seqno").GetInt() if err != nil { return nil, err } seldestKID, err := jw.AtPath("body.key.eldest_kid").GetString() if err != nil { return nil, err } res.eldestKID = keybase1.KIDFromString(seldestKID) ssigningKID, err := jw.AtPath("body.key.kid").GetString() if err != nil { return nil, err } res.signingKID = keybase1.KIDFromString(ssigningKID) return &res, nil }
func (c *ChainLink) Unpack(trusted bool, selfUID keybase1.UID) (err error) { tmp := ChainLinkUnpacked{} c.packed.AtKey("sig").GetStringVoid(&tmp.sig, &err) tmp.sigID, err = GetSigID(c.packed.AtKey("sig_id"), true) c.packed.AtKey("payload_json").GetStringVoid(&tmp.payloadJSONStr, &err) if err != nil { return err } c.payloadJSON, err = jsonw.Unmarshal([]byte(tmp.payloadJSONStr)) if err != nil { return err } err = c.UnpackPayloadJSON(&tmp) if err != nil { return err } // Set the unpacked.kid member if it's not already set. If it is set, check // that the value is consistent with what's in the outer JSON blob. serverKID, err := GetKID(c.packed.AtKey("kid")) if err != nil { return err } if tmp.kid.IsNil() { tmp.kid = serverKID } else if tmp.kid != serverKID { return ChainLinkKIDMismatchError{ fmt.Sprintf("Payload KID (%s) doesn't match server KID (%s).", tmp.kid, serverKID), } } // only unpack the proof_text_full if owner of this link if tmp.uid.Equal(selfUID) { ptf := c.packed.AtKey("proof_text_full") if !ptf.IsNil() { ptf.GetStringVoid(&tmp.proofText, &err) } } c.unpacked = &tmp // IF we're loaded from *trusted* storage, like our local // DB, then we can skip verification later if trusted { b, e2 := c.packed.AtKey("sig_verified").GetBool() if e2 == nil && b { c.sigVerified = true c.G().VDL.Log(VLog1, "| Link is marked as 'sig_verified'") if e3 := c.UnpackComputedKeyInfos(c.packed.AtKey("computed_key_infos")); e3 != nil { c.G().Log.Warning("Problem unpacking computed key infos: %s\n", e3) } } } c.G().VDL.Log(VLog1, "| Unpacked Link %s", c.id) return err }
func (k *KexProvisioner) handlePleaseSign(ctx *Context, m *kex.Msg) error { eddsa := m.Args().SigningKey sig := m.Args().Sig keypair := libkb.NaclSigningKeyPair{Public: eddsa} sigPayload, _, err := keypair.VerifyStringAndExtract(sig) if err != nil { return err } k.G().Log.Debug("Got PleaseSign() on verified JSON blob %s\n", string(sigPayload)) // k.deviceSibkey is public only if k.sigKey == nil { var err error arg := libkb.SecretKeyArg{ Me: k.user, KeyType: libkb.DeviceSigningKeyType, } k.sigKey, err = k.G().Keyrings.GetSecretKeyWithPrompt(nil, arg, k.engctx.SecretUI, "new device install") if err != nil { return err } } jw, err := jsonw.Unmarshal(sigPayload) if err != nil { return err } var newKID keybase1.KID var newKey libkb.GenericKey if newKID, err = libkb.GetKID(jw.AtPath("body.sibkey.kid")); err != nil { return err } if newKey, err = libkb.ImportKeypairFromKID(newKID); err != nil { return err } if err = k.verifyPleaseSign(jw, newKID); err != nil { return err } if err = jw.SetValueAtPath("body.sibkey.reverse_sig", jsonw.NewString(sig)); err != nil { return err } del := libkb.Delegator{ NewKey: newKey, ExistingKey: k.sigKey, Me: k.user, Expire: libkb.NaclEdDSAExpireIn, DelegationType: libkb.SibkeyType, EldestKID: k.user.GetEldestKID(), Contextified: libkb.NewContextified(k.G()), } if err = del.CheckArgs(); err != nil { return err } if err = del.SignAndPost(ctx.LoginContext, jw); err != nil { return err } return nil }
func doChainTest(t *testing.T, testCase TestCase) { inputJSON, exists := testvectors.ChainTestInputs[testCase.Input] if !exists { t.Fatal("missing test input: " + testCase.Input) } // Unmarshal test input in two ways: once for the structured data and once // for the chain link blobs. var input TestInput err := json.Unmarshal([]byte(inputJSON), &input) if err != nil { t.Fatal(err) } inputBlob, err := jsonw.Unmarshal([]byte(inputJSON)) if err != nil { t.Fatal(err) } uid, err := UIDFromHex(input.UID) if err != nil { t.Fatal(err) } chainLen, err := inputBlob.AtKey("chain").Len() if err != nil { t.Fatal(err) } // Get the eldest key. This is assumed to be the first key in the list of // bundles, unless the "eldest" field is given in the test description, in // which case the eldest key is specified by name. var eldestKID keybase1.KID if testCase.Eldest == "" { eldestKey, err := ParseGenericKey(input.Keys[0]) if err != nil { t.Fatal(err) } eldestKID = eldestKey.GetKID() } else { eldestKIDStr, found := input.LabelKids[testCase.Eldest] if !found { t.Fatalf("No KID found for label %s", testCase.Eldest) } eldestKID = keybase1.KIDFromString(eldestKIDStr) } // Parse all the key bundles. keyFamily, err := createKeyFamily(input.Keys) if err != nil { t.Fatal(err) } // Run the actual sigchain parsing and verification. This is most of the // code that's actually being tested. var sigchainErr error ckf := ComputedKeyFamily{kf: keyFamily} sigchain := SigChain{username: NewNormalizedUsername(input.Username), uid: uid, loadedFromLinkOne: true} for i := 0; i < chainLen; i++ { linkBlob := inputBlob.AtKey("chain").AtIndex(i) link, err := ImportLinkFromServer(&sigchain, linkBlob, uid) if err != nil { sigchainErr = err break } sigchain.chainLinks = append(sigchain.chainLinks, link) } if sigchainErr == nil { _, sigchainErr = sigchain.VerifySigsAndComputeKeys(eldestKID, &ckf) } // Some tests expect an error. If we get one, make sure it's the right // type. if testCase.ErrType != "" { if sigchainErr == nil { t.Fatalf("Expected %s error from VerifySigsAndComputeKeys. No error returned.", testCase.ErrType) } foundType := reflect.TypeOf(sigchainErr) expectedTypes := getErrorTypesMap()[testCase.ErrType] if expectedTypes == nil || len(expectedTypes) == 0 { msg := "No Go error types defined for expected failure %s.\n" + "This could be because of new test cases in github.com/keybase/keybase-test-vectors.\n" + "Go error returned: %s" t.Fatalf(msg, testCase.ErrType, foundType) } if expectedTypes[foundType] { // Success! We found the error we expected. This test is done. G.Log.Debug("EXPECTED error encountered", sigchainErr) return } // Got an error, but one of the wrong type. Tests with error names // that are missing from the map (maybe because we add new test // cases in the future) will also hit this branch. t.Fatalf("Wrong error type encountered. Expected %v (%s), got %s: %s", expectedTypes, testCase.ErrType, foundType, sigchainErr) } // Tests that expected an error terminated above. Tests that get here // should succeed without errors. if sigchainErr != nil { t.Fatal(err) } // Check the expected results: total unrevoked links, sibkeys, and subkeys. unrevokedCount := 0 // XXX we should really contextify this idtable, err := NewIdentityTable(nil, eldestKID, &sigchain, nil) if err != nil { t.Fatal(err) } for _, link := range idtable.links { if !link.IsRevoked() { unrevokedCount++ } } if unrevokedCount != testCase.Len { t.Fatalf("Expected %d unrevoked links, but found %d.", testCase.Len, unrevokedCount) } // Don't use the current time to get keys, because that will cause test // failures 5 years from now :-D testTime := getCurrentTimeForTest(sigchain, keyFamily) numSibkeys := len(ckf.GetAllActiveSibkeysAtTime(testTime)) if numSibkeys != testCase.Sibkeys { t.Fatalf("Expected %d sibkeys, got %d", testCase.Sibkeys, numSibkeys) } numSubkeys := len(ckf.GetAllActiveSubkeysAtTime(testTime)) if numSubkeys != testCase.Subkeys { t.Fatalf("Expected %d subkeys, got %d", testCase.Subkeys, numSubkeys) } // Success! }