Exemple #1
0
// Push pushes the generated keys to the api server and stores the
// local key security server half on the api server as well.
func (e *DeviceKeygen) Push(ctx *Context, pargs *DeviceKeygenPushArgs) error {
	var encSigner libkb.GenericKey
	eldestKID := pargs.EldestKID

	ds := []libkb.Delegator{}

	// append the signing key
	if pargs.IsEldest {
		ds = e.appendEldest(ds, ctx, pargs)
		encSigner = e.naclSignGen.GetKeyPair()
		eldestKID = encSigner.GetKID()
	} else if !pargs.SkipSignerPush {
		ds = e.appendSibkey(ds, ctx, pargs)
		encSigner = e.naclSignGen.GetKeyPair()
	} else {
		encSigner = pargs.Signer
	}

	ds = e.appendEncKey(ds, ctx, encSigner, eldestKID, pargs.User)

	e.pushErr = libkb.DelegatorAggregator(ctx.LoginContext, ds)

	// push the LKS server half
	e.pushLKS(ctx)

	return e.pushErr
}
// findAndDecryptPrivatePGPKeys gets the user's private pgp keys if
// any exist and decrypts them.
func (c *PassphraseChange) findAndDecryptPrivatePGPKeys(ctx *Context) ([]libkb.GenericKey, error) {
	ska := libkb.SecretKeyArg{
		Me:      c.me,
		KeyType: libkb.PGPKeyType,
	}

	// get all the pgp key skb blocks from the keyring:
	var blocks []*libkb.SKB
	err := c.G().LoginState().Keyring(func(kr *libkb.SKBKeyringFile) {
		blocks = kr.SearchWithComputedKeyFamily(c.me.GetComputedKeyFamily(), ska)
	}, "PassphraseChange - findAndDecryptPrivatePGPKey")
	if err != nil {
		return nil, err
	}

	// and the synced secret keys:
	syncKeys, err := c.me.AllSyncedSecretKeys(ctx.LoginContext)
	if err != nil {
		return nil, err
	}
	if syncKeys != nil {
		blocks = append(blocks, syncKeys...)
	}

	secretRetriever := libkb.NewSecretStore(c.G(), c.me.GetNormalizedName())

	// avoid duplicates:
	keys := make(map[keybase1.KID]libkb.GenericKey)
	for _, block := range blocks {
		block.SetUID(c.me.GetUID())
		var key libkb.GenericKey
		if c.usingPaper {
			key, err = block.UnlockWithStoredSecret(secretRetriever)
			if err != nil {
				switch err.(type) {
				case libkb.BadKeyError:
					// expected error, ok to proceed...
					continue
				default:
					// unexpected error type:
					return nil, err
				}
			}
		} else {
			parg := ctx.SecretKeyPromptArg(libkb.SecretKeyArg{}, "passphrase change")
			key, err = block.PromptAndUnlock(parg, "your keybase passphrase", secretRetriever, nil, c.me)
			if err != nil {
				return nil, err
			}
		}
		keys[key.GetKID()] = key
	}

	keyList := make([]libkb.GenericKey, 0, len(keys))
	for _, key := range keys {
		keyList = append(keyList, key)
	}

	return keyList, nil
}
Exemple #3
0
// fetchLKS gets the encrypted LKS client half from the server.
// It uses encKey to decrypt it.  It also returns the passphrase
// generation.
func fetchLKS(ctx *Context, g *libkb.GlobalContext, encKey libkb.GenericKey) (libkb.PassphraseGeneration, []byte, error) {
	arg := libkb.APIArg{
		Endpoint:    "passphrase/recover",
		NeedSession: true,
		Args: libkb.HTTPArgs{
			"kid": encKey.GetKID(),
		},
	}
	if ctx.LoginContext != nil {
		arg.SessionR = ctx.LoginContext.LocalSession()
	}
	res, err := g.API.Get(arg)
	if err != nil {
		return 0, nil, err
	}
	ctext, err := res.Body.AtKey("ctext").GetString()
	if err != nil {
		return 0, nil, err
	}
	ppGen, err := res.Body.AtKey("passphrase_generation").GetInt()
	if err != nil {
		return 0, nil, err
	}

	//  Now try to decrypt with the unlocked device key
	msg, _, err := encKey.DecryptFromString(ctext)
	if err != nil {
		return 0, nil, err
	}

	return libkb.PassphraseGeneration(ppGen), msg, nil
}
Exemple #4
0
func (e *UntrackEngine) storeRemoteUntrack(them *libkb.User, ctx *Context) (err error) {
	e.G().Log.Debug("+ StoreRemoteUntrack")
	defer e.G().Log.Debug("- StoreRemoteUntrack -> %s", libkb.ErrToOk(err))

	arg := libkb.SecretKeyArg{
		Me:      e.arg.Me,
		KeyType: libkb.DeviceSigningKeyType,
	}
	var signingKeyPriv libkb.GenericKey
	if signingKeyPriv, err = e.G().Keyrings.GetSecretKeyWithPrompt(ctx.LoginContext, arg, ctx.SecretUI, "untracking signature"); err != nil {
		return
	}

	var sig string
	var sigid keybase1.SigID
	if sig, sigid, err = signingKeyPriv.SignToString(e.untrackStatementBytes); err != nil {
		return
	}

	_, err = e.G().API.Post(libkb.APIArg{
		Endpoint:    "follow",
		NeedSession: true,
		Args: libkb.HTTPArgs{
			"sig_id_base":  libkb.S{Val: sigid.ToString(false)},
			"sig_id_short": libkb.S{Val: sigid.ToShortID()},
			"sig":          libkb.S{Val: sig},
			"uid":          libkb.UIDArg(them.GetUID()),
			"type":         libkb.S{Val: "untrack"},
			"signing_kid":  e.signingKeyPub.GetKID(),
		},
	})

	return
}
Exemple #5
0
// CurrentSession uses the global session to find the session.  If
// the user isn't logged in, it returns ErrNoSession.
func (h *SessionHandler) CurrentSession(_ context.Context, sessionID int) (keybase1.Session, error) {
	var s keybase1.Session
	var token string
	var username libkb.NormalizedUsername
	var uid keybase1.UID
	var deviceSubkey libkb.GenericKey
	var err error

	aerr := h.G().LoginState().Account(func(a *libkb.Account) {
		uid, username, token, deviceSubkey, err = a.UserInfo()
	}, "Service - SessionHandler - UserInfo")
	if aerr != nil {
		return s, aerr
	}
	if err != nil {
		if _, ok := err.(libkb.LoginRequiredError); ok {
			return s, ErrNoSession
		}
		return s, err
	}

	s.Uid = uid
	s.Username = username.String()
	s.Token = token
	s.DeviceSubkeyKid = deviceSubkey.GetKID()

	return s, nil
}
Exemple #6
0
// fetchLKS gets the encrypted LKS client half from the server.
// It uses encKey to decrypt it.  It also returns the passphrase
// generation.
func (c *PassphraseChange) fetchLKS(ctx *Context, encKey libkb.GenericKey) (libkb.PassphraseGeneration, []byte, error) {
	res, err := c.G().API.Get(
		libkb.APIArg{
			Endpoint:    "passphrase/recover",
			NeedSession: true,
			Args: libkb.HTTPArgs{
				"kid": encKey.GetKID(),
			},
		})
	if err != nil {
		return 0, nil, err
	}
	ctext, err := res.Body.AtKey("ctext").GetString()
	if err != nil {
		return 0, nil, err
	}
	ppGen, err := res.Body.AtKey("passphrase_generation").GetInt()
	if err != nil {
		return 0, nil, err
	}

	//  Now try to decrypt with the unlocked device key
	msg, _, err := encKey.DecryptFromString(ctext)
	if err != nil {
		return 0, nil, err
	}

	return libkb.PassphraseGeneration(ppGen), msg, nil
}
// encodePrivatePGPKey encrypts key with tsec and armor-encodes it.
// It includes the passphrase generation in the data.
func (c *PassphraseChange) encodePrivatePGPKey(key libkb.GenericKey, tsec *triplesec.Cipher, gen libkb.PassphraseGeneration) (string, error) {
	skb, err := key.ToServerSKB(c.G(), tsec, gen)
	if err != nil {
		return "", err
	}

	return skb.ArmoredEncode()
}
func (c *PassphraseChange) updatePassphrase(ctx *Context, sigKey libkb.GenericKey, ppGen libkb.PassphraseGeneration, oldClientHalf []byte) error {

	pgpKeys, err := c.findAndDecryptPrivatePGPKeys(ctx)
	if err != nil {
		return err
	}

	var acctErr error
	c.G().LoginState().Account(func(a *libkb.Account) {
		// Ready the update argument; almost done, but we need some more stuff.
		payload, err := c.commonArgs(a, oldClientHalf, pgpKeys, ppGen)
		if err != nil {
			acctErr = err
			return
		}

		// get the new passphrase hash out of the args
		pwh, ok := payload["pwh"].(string)
		if !ok || len(pwh) == 0 {
			acctErr = fmt.Errorf("no pwh found in common args")
			return
		}

		// Generate a signature with our unlocked sibling key from device.
		proof, err := c.me.UpdatePassphraseProof(sigKey, pwh, ppGen+1)
		if err != nil {
			acctErr = err
			return
		}

		sig, _, _, err := libkb.SignJSON(proof, sigKey)
		if err != nil {
			acctErr = err
			return
		}
		payload["sig"] = sig
		payload["signing_kid"] = sigKey.GetKID()

		postArg := libkb.APIArg{
			Endpoint:    "passphrase/sign",
			NeedSession: true,
			JSONPayload: payload,
			SessionR:    a.LocalSession(),
		}

		_, err = c.G().API.PostJSON(postArg)
		if err != nil {
			acctErr = fmt.Errorf("api post to passphrase/sign error: %s", err)
			return
		}
	}, "PassphraseChange.runForcedUpdate")
	if acctErr != nil {
		return acctErr
	}

	return nil
}
Exemple #9
0
func keySolvesProblemTLF(key libkb.GenericKey, tlf keybase1.ProblemTLF) bool {
	ourKid := key.GetKID()
	for _, kid := range tlf.Solution_kids {
		if kid.Equal(ourKid) {
			return true
		}
	}
	return false
}
Exemple #10
0
func logNoMatch(g *libkb.GlobalContext, key libkb.GenericKey, bundles []keybase1.CiphertextBundle) {
	if key == nil {
		g.Log.Debug("logNoMatch: key is nil")
		return
	}
	kid := key.GetKID()
	g.Log.Debug("logNoMatch: desired kid: %s", kid)
	for i, bundle := range bundles {
		g.Log.Debug("logNoMatch: kid %d: %s (%v)", i, bundle.Kid, kid.Equal(bundle.Kid))
	}
}
Exemple #11
0
func kidMatch(key libkb.GenericKey, bundles []keybase1.CiphertextBundle) (int, bool) {
	if key == nil {
		return -1, false
	}
	kid := key.GetKID()
	for i, bundle := range bundles {
		if kid.Equal(bundle.Kid) {
			return i, true
		}
	}
	return -1, false
}
Exemple #12
0
func (d *Locksmith) deviceSignPGPNext(ctx *Context, pgpk libkb.GenericKey) error {
	if pgpk.CanSign() == false {
		return fmt.Errorf("pgp key can't sign")
	}

	eldest := d.arg.User.GetEldestKID()
	ctx.LogUI.Debug("eldest kid from user: %s", eldest)
	if err := d.addDeviceKeyWithSigner(ctx, pgpk, eldest); err != nil {
		return err
	}

	return nil
}
Exemple #13
0
func (e *PGPKeyExportEngine) queryMatch(k libkb.GenericKey) bool {
	if len(e.arg.Query) == 0 {
		return true
	}
	var match bool
	switch e.qtype {
	case either:
		match = libkb.KeyMatchesQuery(k, e.arg.Query, e.arg.ExactMatch)
	case fingerprint:
		match = k.GetFingerprintP().Match(e.arg.Query, e.arg.ExactMatch)
	case kid:
		match = k.GetKID().Match(e.arg.Query, e.arg.ExactMatch)
	}
	return match
}
func makeKeyArgs(sigID keybase1.SigID, sig []byte, delType libkb.DelegationType, key libkb.GenericKey, eldestKID, signingKID keybase1.KID) (*libkb.HTTPArgs, error) {
	pub, err := key.Encode()
	if err != nil {
		return nil, err
	}
	args := libkb.HTTPArgs{
		"sig_id_base":     libkb.S{Val: sigID.ToString(false)},
		"sig_id_short":    libkb.S{Val: sigID.ToShortID()},
		"sig":             libkb.S{Val: string(sig)},
		"type":            libkb.S{Val: string(delType)},
		"is_remote_proof": libkb.B{Val: false},
		"public_key":      libkb.S{Val: pub},
		"eldest_kid":      libkb.S{Val: eldestKID.String()},
		"signing_kid":     libkb.S{Val: signingKID.String()},
	}
	return &args, nil
}