// Run starts the engine. func (d *DevList) Run(ctx *Context) error { uid := d.G().GetMyUID() var err error var devs libkb.DeviceKeyMap aerr := d.G().LoginState().Account(func(a *libkb.Account) { if err = libkb.RunSyncer(a.SecretSyncer(), uid, a.LoggedIn(), a.LocalSession()); err != nil { return } devs, err = a.SecretSyncer().ActiveDevices(libkb.AllDeviceTypes) }, "DevList - ActiveDevices") if aerr != nil { return aerr } if err != nil { return err } var pdevs []keybase1.Device for k, v := range devs { pdevs = append(pdevs, keybase1.Device{ Type: v.Type, Name: v.Display(), DeviceID: k, CTime: keybase1.TimeFromSeconds(v.CTime), MTime: keybase1.TimeFromSeconds(v.MTime), }) } sort.Sort(dname(pdevs)) d.devices = pdevs return nil }
func (ckf ComputedKeyFamily) exportPublicKey(key GenericKey) (pk keybase1.PublicKey) { pk.KID = key.GetKID() if pgpBundle, isPGP := key.(*PGPKeyBundle); isPGP { pk.PGPFingerprint = pgpBundle.GetFingerprint().String() ids := make([]keybase1.PGPIdentity, len(pgpBundle.Identities)) i := 0 for _, identity := range pgpBundle.Identities { ids[i] = ExportPGPIdentity(identity) i++ } pk.PGPIdentities = ids } pk.DeviceID = ckf.cki.KIDToDeviceID[pk.KID] device := ckf.cki.Devices[pk.DeviceID] if device != nil { if device.Description != nil { pk.DeviceDescription = *device.Description } pk.DeviceType = device.Type } cki, ok := ckf.cki.Infos[pk.KID] if ok && cki != nil { if cki.Parent.IsValid() { pk.ParentID = cki.Parent.String() } pk.IsSibkey = cki.Sibkey pk.IsEldest = cki.Eldest pk.CTime = keybase1.TimeFromSeconds(cki.CTime) pk.ETime = keybase1.TimeFromSeconds(cki.ETime) } return pk }
func (ckf ComputedKeyFamily) Export() []keybase1.PublicKey { exportedKeys := []keybase1.PublicKey{} addKey := func(key GenericKey) { kid := key.GetKID() fingerprintStr := "" identities := []keybase1.PGPIdentity{} if pgpBundle, isPGP := key.(*PGPKeyBundle); isPGP { fingerprintStr = pgpBundle.GetFingerprint().String() for _, identity := range pgpBundle.Identities { identities = append(identities, ExportPGPIdentity(identity)) } } cki := ckf.cki.Infos[kid] deviceID := ckf.cki.KIDToDeviceID[kid] device := ckf.cki.Devices[deviceID] deviceDescription := "" deviceType := "" if device != nil { if device.Description != nil { deviceDescription = *device.Description } if device.Type != "" { deviceType = device.Type } } parentID := "" if cki.Parent.IsValid() { parentID = cki.Parent.String() } exportedKeys = append(exportedKeys, keybase1.PublicKey{ KID: kid, PGPFingerprint: fingerprintStr, PGPIdentities: identities, IsSibkey: cki.Sibkey, IsEldest: cki.Eldest, ParentID: parentID, DeviceID: deviceID, DeviceType: deviceType, DeviceDescription: deviceDescription, CTime: keybase1.TimeFromSeconds(cki.CTime), ETime: keybase1.TimeFromSeconds(cki.ETime), }) } for _, sibkey := range ckf.GetAllActiveSibkeys() { addKey(sibkey) } for _, subkey := range ckf.GetAllActiveSubkeys() { addKey(subkey) } sort.Sort(PublicKeyList(exportedKeys)) return exportedKeys }
// OutputSignatureSuccess prints the details of a successful verification. func OutputSignatureSuccess(ctx *Context, fingerprint libkb.PGPFingerprint, owner *libkb.User, signatureTime time.Time) { arg := keybase1.OutputSignatureSuccessArg{ Fingerprint: fingerprint.String(), Username: owner.GetName(), SignedAt: keybase1.TimeFromSeconds(signatureTime.Unix()), } ctx.PgpUI.OutputSignatureSuccess(context.TODO(), arg) }
func (ckf ComputedKeyFamily) ExportRevokedDeviceKeys() []keybase1.RevokedKey { var ex []keybase1.RevokedKey for _, key := range ckf.GetRevokedKeys() { if _, isPGP := key.Key.(*PGPKeyBundle); isPGP { continue } rkey := keybase1.RevokedKey{ Key: ckf.exportPublicKey(key.Key), Time: keybase1.KeybaseTime{ Unix: keybase1.TimeFromSeconds(key.RevokedAt.Unix), Chain: key.RevokedAt.Chain, }, } ex = append(ex, rkey) } return ex }
func (e *DeviceHistory) loadDevices() error { ckf := e.user.GetComputedKeyFamily() if ckf == nil { return errors.New("nil ComputedKeyFamily for user") } ckis := e.user.GetComputedKeyInfos() if ckis == nil { return errors.New("nil ComputedKeyInfos for user") } for _, d := range ckf.GetAllDevices() { exp := keybase1.DeviceDetail{Device: *(d.ProtExport())} cki, ok := ckis.Infos[d.Kid] if !ok { return fmt.Errorf("no ComputedKeyInfo for device %s, kid %s", d.ID, d.Kid) } if cki.Eldest { exp.Eldest = true } else { prov, err := e.provisioner(d, ckis, cki) if err != nil { return err } if prov != nil { exp.Provisioner = prov.ProtExport() t := keybase1.TimeFromSeconds(cki.DelegatedAt.Unix) exp.ProvisionedAt = &t } } if cki.RevokedAt != nil { rt := keybase1.TimeFromSeconds(cki.RevokedAt.Unix) exp.RevokedAt = &rt } if !cki.RevokedBy.IsNil() { exp.RevokedBy = cki.RevokedBy if deviceID, ok := ckis.KIDToDeviceID[cki.RevokedBy]; ok { if device, ok := ckis.Devices[deviceID]; ok { exp.RevokedByDevice = device.ProtExport() } } } if e.G().Env.GetDeviceID().Eq(d.ID) { exp.CurrentDevice = true } e.devices = append(e.devices, exp) } // Load the last used times, but only if these are your own devices. The // API won't give you those times for other people's devices. if e.user.GetNormalizedName().Eq(e.G().Env.GetUsername()) { lastUsedTimes, err := e.getLastUsedTimes() if err != nil { return err } for i := range e.devices { detail := &e.devices[i] lastUsedTime, ok := lastUsedTimes[detail.Device.DeviceID] if !ok { if detail.RevokedAt != nil { // The server only provides last used times for active devices. continue } return fmt.Errorf("Failed to load last used time for device %s", detail.Device.DeviceID) } detail.Device.LastUsedTime = keybase1.TimeFromSeconds(lastUsedTime.Unix()) } } return nil }