1// Copyright 2015 Keybase, Inc. All rights reserved. Use of
2// this source code is governed by the included BSD license.
3
4package libkb
5
6import (
7	keybase1 "github.com/keybase/client/go/protocol/keybase1"
8	"github.com/keybase/saltpack"
9)
10
11func PGPLookup(mctx MetaContext, id uint64) (username string, uid keybase1.UID, err error) {
12	return keyLookup(mctx, keyLookupArg{uintID: id})
13}
14
15func PGPLookupHex(mctx MetaContext, hexID string) (username string, uid keybase1.UID, err error) {
16	return keyLookup(mctx, keyLookupArg{hexID: hexID})
17}
18
19func PGPLookupFingerprint(mctx MetaContext, fp *PGPFingerprint) (username string, uid keybase1.UID, err error) {
20	return keyLookup(mctx, keyLookupArg{fp: fp})
21}
22
23func KeyLookupKIDIncludingRevoked(mctx MetaContext, k keybase1.KID) (username string, uid keybase1.UID, err error) {
24	return keyLookup(mctx, keyLookupArg{kid: k, includeRevoked: true})
25}
26
27func KeyLookupByBoxPublicKey(mctx MetaContext, k saltpack.BoxPublicKey) (username string, uid keybase1.UID, err error) {
28	return keyLookup(mctx, keyLookupArg{kid: BoxPublicKeyToKeybaseKID(k)})
29}
30
31type keyLookupArg struct {
32	fp             *PGPFingerprint
33	hexID          string
34	uintID         uint64
35	kid            keybase1.KID
36	includeRevoked bool
37}
38
39type keyBasicsReply struct {
40	Status   AppStatus `json:"status"`
41	Username string    `json:"username"`
42	UID      string    `json:"uid"`
43}
44
45func (k *keyBasicsReply) GetAppStatus() *AppStatus {
46	return &k.Status
47}
48
49func keyLookup(mctx MetaContext, arg keyLookupArg) (username string, uid keybase1.UID, err error) {
50	httpArgs := make(HTTPArgs)
51	httpArgs["include_revoked"] = B{Val: arg.includeRevoked}
52	switch {
53	case arg.fp != nil:
54		httpArgs["fingerprint"] = S{arg.fp.String()}
55	case len(arg.hexID) > 0:
56		httpArgs["pgp_key_id"] = S{Val: arg.hexID}
57	case arg.uintID > 0:
58		httpArgs["pgp_key_id"] = UHex{Val: arg.uintID}
59	case !arg.kid.IsNil():
60		httpArgs["kid"] = S{Val: arg.kid.String()}
61	default:
62		return username, uid, InvalidArgumentError{Msg: "invalid pgp lookup arg"}
63	}
64
65	var data keyBasicsReply
66
67	// lookup key on api server
68	args := APIArg{
69		Endpoint: "key/basics",
70		Args:     httpArgs,
71	}
72
73	if err = mctx.G().API.GetDecode(mctx, args, &data); err != nil {
74		if ase, ok := err.(AppStatusError); ok && ase.Code == SCKeyNotFound {
75			err = NotFoundError{}
76		}
77		return username, uid, err
78	}
79
80	uid, err = keybase1.UIDFromString(data.UID)
81	if err != nil {
82		return username, uid, err
83	}
84	return data.Username, uid, nil
85}
86