func (l *SigChainLoader) LoadLinksFromStorage() (err error) { var curr LinkID var links []*ChainLink var mt *MerkleTriple goodKey := true uid := l.user.GetUID() l.G().Log.Debug("+ SigChainLoader.LoadFromStorage(%s)", uid) defer func() { l.G().Log.Debug("- SigChainLoader.LoadFromStorage(%s) -> %s", uid, ErrToOk(err)) }() if mt, err = l.LoadLastLinkIDFromStorage(); err != nil || mt == nil { l.G().Log.Debug("| Failed to load last link ID") if err == nil { l.G().Log.Debug("| no error loading last link ID from storage") } if mt == nil { l.G().Log.Debug("| mt (MerkleTriple) nil result from load last link ID from storage") } return err } // Load whatever the last fingerprint was in the chain if we're not loading // allKeys. We have to load something... Note that we don't use l.fp // here (as we used to) since if the user used to have chainlinks, and then // removed their key, we still want to load their last chainlinks. var loadKID keybase1.KID curr = mt.LinkID var link *ChainLink suid := l.selfUID() for curr != nil && goodKey { l.G().VDL.Log(VLog1, "| loading link; curr=%s", curr) if link, err = ImportLinkFromStorage(curr, suid, l.G()); err != nil { return } kid2 := link.ToEldestKID() if loadKID.IsNil() { loadKID = kid2 l.G().Log.Debug("| Setting loadKID=%s", kid2) } else if !l.allKeys && loadKID.Exists() && !loadKID.Equal(kid2) { goodKey = false l.G().Log.Debug("| Stop loading at KID=%s (!= KID=%s)", loadKID, kid2) } if goodKey { links = append(links, link) curr = link.GetPrev() } } reverse(links) l.G().Log.Debug("| Loaded %d links", len(links)) l.links = links return }
// To add a device key as the eldest key, signer and eldestKID // should be nil. func (d *Locksmith) addDeviceKeyWithSigner(ctx *Context, signer libkb.GenericKey, eldestKID keybase1.KID) error { devname, err := d.deviceName(ctx) if err != nil { return err } pps, err := d.ppStream(ctx) if err != nil { return err } d.lks = libkb.NewLKSec(pps, d.arg.User.GetUID(), d.G()) args := &DeviceWrapArgs{ Me: d.arg.User, DeviceName: devname, DeviceType: libkb.DeviceTypeDesktop, Lks: d.lks, IsEldest: false, Signer: signer, EldestKID: eldestKID, } if signer == nil && eldestKID.IsNil() { args.IsEldest = true } eng := NewDeviceWrap(args, d.G()) if err := RunEngine(eng, ctx); err != nil { return err } d.signingKey = eng.SigningKey() return nil }
func (sc *SigChain) VerifySigsAndComputeKeys(eldest keybase1.KID, ckf *ComputedKeyFamily) (cached bool, err error) { cached = false sc.G().Log.Debug("+ VerifySigsAndComputeKeys for user %s (eldest = %s)", sc.uid, eldest) defer func() { sc.G().Log.Debug("- VerifySigsAndComputeKeys for user %s -> %s", sc.uid, ErrToOk(err)) }() if err = sc.VerifyChain(); err != nil { return } if sc.allKeys || sc.loadedFromLinkOne { if first := sc.getFirstSeqno(); first > Seqno(1) { err = ChainLinkWrongSeqnoError{fmt.Sprintf("Wanted a chain from seqno=1, but got seqno=%d", first)} return } } if ckf.kf == nil || eldest.IsNil() { sc.G().Log.Debug("| VerifyWithKey short-circuit, since no Key available") sc.localCki = NewComputedKeyInfos(sc.G()) ckf.cki = sc.localCki return } links, err := sc.GetCurrentSubchain(eldest) if err != nil { return } if links == nil || len(links) == 0 { sc.G().Log.Debug("| Empty chain after we limited to eldest %s", eldest) eldestKey, _ := ckf.FindKeyWithKIDUnsafe(eldest) sc.localCki = NewComputedKeyInfos(sc.G()) err = sc.localCki.InsertServerEldestKey(eldestKey, sc.username) ckf.cki = sc.localCki return } if cached, ckf.cki, err = sc.verifySubchain(*ckf.kf, links); err != nil { return } // We used to check for a self-signature of one's keybase username // here, but that doesn't make sense because we haven't accounted // for revocations. We'll go it later, after reconstructing // the id_table. See LoadUser in user.go and // https://github.com/keybase/go/issues/43 return }
// GetEncryptionSubkeyForDevice gets the current encryption subkey for the given // device. Note that many devices might share an encryption public key but // might have different secret keys. func (ckf *ComputedKeyFamily) GetEncryptionSubkeyForDevice(did keybase1.DeviceID) (key GenericKey, err error) { var kid keybase1.KID if kid, err = ckf.getSibkeyKidForDevice(did); err != nil { return } if kid.IsNil() { return } if cki, found := ckf.cki.Infos[kid]; !found { return } else if !cki.Subkey.IsValid() { return } else { key, err = ckf.FindActiveEncryptionSubkey(cki.Subkey) } return }