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	"bufio"
8	"bytes"
9	"crypto/sha256"
10	"encoding/hex"
11	"errors"
12	"fmt"
13	"io"
14	"regexp"
15	"strings"
16
17	"github.com/keybase/client/go/kbcrypto"
18	keybase1 "github.com/keybase/client/go/protocol/keybase1"
19	"github.com/keybase/go-crypto/openpgp"
20	"github.com/keybase/go-crypto/openpgp/armor"
21	"github.com/keybase/go-crypto/openpgp/packet"
22	jsonw "github.com/keybase/go-jsonw"
23	_ "golang.org/x/crypto/ripemd160" // imported so that keybase/go-crypto/openpgp supports ripemd160
24)
25
26var _ GenericKey = (*PGPKeyBundle)(nil)
27
28type PGPKeyBundle struct {
29	*openpgp.Entity
30
31	// GPGFallbackKey to be used as a fallback if given dummy a PrivateKey.
32	GPGFallbackKey GenericKey
33
34	// We make the (fairly dangerous) assumption that the key will never be
35	// modified. This avoids the issue that encoding an openpgp.Entity is
36	// nondeterministic due to Go's randomized iteration order (so different
37	// exports of the same key may hash differently).
38	//
39	// If you're *sure* that you're creating a PGPKeyBundle from an armored
40	// *public* key, you can prefill this field and Export() will use it.
41	ArmoredPublicKey string
42
43	// True if this key was generated by this program
44	Generated bool
45}
46
47func NewPGPKeyBundle(entity *openpgp.Entity) *PGPKeyBundle {
48	return &PGPKeyBundle{Entity: entity}
49}
50
51func NewGeneratedPGPKeyBundle(entity *openpgp.Entity) *PGPKeyBundle {
52	return &PGPKeyBundle{Entity: entity, Generated: true}
53}
54
55const (
56	PGPFingerprintLen = 20
57)
58
59type PGPFingerprint [PGPFingerprintLen]byte
60
61func ImportPGPFingerprint(f keybase1.PGPFingerprint) PGPFingerprint {
62	var ret PGPFingerprint
63	copy(ret[:], f[:])
64	return ret
65}
66
67func PGPFingerprintFromHex(s string) (*PGPFingerprint, error) {
68	var fp PGPFingerprint
69	err := DecodeHexFixed(fp[:], []byte(s))
70	switch err.(type) {
71	case nil:
72		return &fp, nil
73	case HexWrongLengthError:
74		return nil, fmt.Errorf("Bad fingerprint; wrong length: %d", len(s))
75	default:
76		return nil, err
77	}
78}
79
80func PGPFingerprintFromSlice(b []byte) (*PGPFingerprint, error) {
81	if len(b) != PGPFingerprintLen {
82		return nil, fmt.Errorf("Bad fingerprint; wrong length: %d", PGPFingerprintLen)
83	}
84	var fp PGPFingerprint
85	copy(fp[:], b)
86	return &fp, nil
87}
88
89func PGPFingerprintFromHexNoError(s string) *PGPFingerprint {
90	if len(s) == 0 {
91		return nil
92	} else if f, e := PGPFingerprintFromHex(s); e == nil {
93		return f
94	} else {
95		return nil
96	}
97}
98
99func (p PGPFingerprint) String() string {
100	return hex.EncodeToString(p[:])
101}
102
103func (p PGPFingerprint) ToQuads() string {
104	x := []byte(strings.ToUpper(p.String()))
105	totlen := len(x)*5/4 - 1
106	ret := make([]byte, totlen)
107	j := 0
108	for i, b := range x {
109		ret[j] = b
110		j++
111		if (i%4) == 3 && j < totlen {
112			ret[j] = ' '
113			j++
114		}
115	}
116	return string(ret)
117}
118
119func (p PGPFingerprint) ToKeyID() string {
120	return strings.ToUpper(hex.EncodeToString(p[12:20]))
121}
122
123func (p PGPFingerprint) ToDisplayString(verbose bool) string {
124	if verbose {
125		return p.String()
126	}
127	return p.ToKeyID()
128}
129
130func (p *PGPFingerprint) Match(q string, exact bool) bool {
131	if p == nil {
132		return false
133	}
134	if exact {
135		return strings.EqualFold(p.String(), q)
136	}
137	return strings.HasSuffix(strings.ToLower(p.String()), strings.ToLower(q))
138}
139
140func (k *PGPKeyBundle) InitGPGKey() {
141	k.GPGFallbackKey = &GPGKey{
142		fp:  k.GetFingerprintP(),
143		kid: k.GetKID(),
144	}
145}
146
147func (k *PGPKeyBundle) FullHash() (string, error) {
148	keyBlob, err := k.Encode()
149	if err != nil {
150		return "", err
151	}
152
153	keySum := sha256.Sum256([]byte(strings.TrimSpace(keyBlob)))
154	return hex.EncodeToString(keySum[:]), nil
155}
156
157// StripRevocations returns a copy of the key with revocations removed
158func (k *PGPKeyBundle) StripRevocations() (strippedKey *PGPKeyBundle) {
159	strippedKey = nil
160	if k.ArmoredPublicKey != "" {
161		// Re-read the key because we want to return a copy, that does
162		// not reference PGPKeyBundle `k` anywhere.
163		strippedKey, _, _ = ReadOneKeyFromString(k.ArmoredPublicKey)
164	}
165
166	if strippedKey == nil {
167		// Either Armored key was not saved or ReadOneKeyFromString
168		// failed. Do old behavior here - we won't have a proper copy
169		// of the key (there is a lot of pointers in the key structs),
170		// but at least we won't have to bail out completely.
171		entityCopy := *k.Entity
172		strippedKey = &PGPKeyBundle{Entity: &entityCopy}
173	}
174
175	strippedKey.Revocations = nil
176
177	oldSubkeys := strippedKey.Subkeys
178	strippedKey.Subkeys = nil
179	for _, subkey := range oldSubkeys {
180		// Skip revoked subkeys
181		if subkey.Sig.SigType == packet.SigTypeSubkeyBinding && subkey.Revocation == nil {
182			strippedKey.Subkeys = append(strippedKey.Subkeys, subkey)
183		}
184	}
185	return
186}
187
188func (k *PGPKeyBundle) StoreToLocalDb(g *GlobalContext) error {
189	s, err := k.Encode()
190	if err != nil {
191		return err
192	}
193	val := jsonw.NewString(s)
194	g.Log.Debug("| Storing Key (kid=%s) to Local DB", k.GetKID())
195	return g.LocalDb.Put(DbKey{Typ: DBPGPKey, Key: k.GetKID().String()}, []DbKey{}, val)
196}
197
198func (p PGPFingerprint) Eq(p2 PGPFingerprint) bool {
199	return FastByteArrayEq(p[:], p2[:])
200}
201
202func GetPGPFingerprint(w *jsonw.Wrapper) (*PGPFingerprint, error) {
203	s, err := w.GetString()
204	if err != nil {
205		return nil, err
206	}
207	return PGPFingerprintFromHex(s)
208}
209
210func GetPGPFingerprintVoid(w *jsonw.Wrapper, p *PGPFingerprint, e *error) {
211	ret, err := GetPGPFingerprint(w)
212	if err != nil {
213		*e = err
214	} else {
215		*p = *ret
216	}
217}
218
219func (p *PGPFingerprint) UnmarshalJSON(b []byte) error {
220	tmp, err := PGPFingerprintFromHex(keybase1.Unquote(b))
221	if err != nil {
222		return err
223	}
224	*p = *tmp
225	return nil
226}
227
228func (p *PGPFingerprint) MarshalJSON() ([]byte, error) {
229	return keybase1.Quote(p.String()), nil
230}
231
232func (k PGPKeyBundle) toList() openpgp.EntityList {
233	list := make(openpgp.EntityList, 1)
234	list[0] = k.Entity
235	return list
236}
237
238func (k PGPKeyBundle) GetFingerprint() PGPFingerprint {
239	return PGPFingerprint(k.PrimaryKey.Fingerprint)
240}
241
242func (k PGPKeyBundle) GetFingerprintP() *PGPFingerprint {
243	fp := k.GetFingerprint()
244	return &fp
245}
246
247func GetPGPFingerprintFromGenericKey(k GenericKey) *PGPFingerprint {
248	switch pgp := k.(type) {
249	case *PGPKeyBundle:
250		return pgp.GetFingerprintP()
251	default:
252		return nil
253	}
254}
255
256func (k PGPKeyBundle) KeysById(id uint64, fp []byte) []openpgp.Key {
257	return k.toList().KeysById(id, fp)
258}
259
260func (k PGPKeyBundle) KeysByIdUsage(id uint64, fp []byte, usage byte) []openpgp.Key {
261	return k.toList().KeysByIdUsage(id, fp, usage)
262}
263
264func (k PGPKeyBundle) DecryptionKeys() []openpgp.Key {
265	return k.toList().DecryptionKeys()
266}
267
268func (k PGPKeyBundle) MatchesKey(key *openpgp.Key) bool {
269	return FastByteArrayEq(k.PrimaryKey.Fingerprint[:],
270		key.Entity.PrimaryKey.Fingerprint[:])
271}
272
273func (k PGPKeyBundle) SamePrimaryAs(k2 PGPKeyBundle) bool {
274	return FastByteArrayEq(k.PrimaryKey.Fingerprint[:], k2.PrimaryKey.Fingerprint[:])
275}
276
277func (k *PGPKeyBundle) Encode() (ret string, err error) {
278	if k.ArmoredPublicKey != "" {
279		return k.ArmoredPublicKey, nil
280	}
281	buf := bytes.Buffer{}
282	err = k.EncodeToStream(NopWriteCloser{&buf}, false)
283	if err == nil {
284		ret = buf.String()
285		k.ArmoredPublicKey = ret
286	}
287	return
288}
289
290func PGPKeyRawToArmored(raw []byte, priv bool) (ret string, err error) {
291
292	var writer io.WriteCloser
293	var out bytes.Buffer
294	var which string
295
296	if priv {
297		which = "PRIVATE"
298	} else {
299		which = "PUBLIC"
300	}
301	hdr := fmt.Sprintf("PGP %s KEY BLOCK", which)
302
303	writer, err = armor.Encode(&out, hdr, PGPArmorHeaders)
304
305	if err != nil {
306		return
307	}
308	if _, err = writer.Write(raw); err != nil {
309		return
310	}
311	writer.Close()
312	ret = out.String()
313	return
314}
315
316func (k *PGPKeyBundle) SerializePrivate(w io.Writer) error {
317	return k.Entity.SerializePrivate(w, &packet.Config{ReuseSignaturesOnSerialize: !k.Generated})
318}
319
320func (k *PGPKeyBundle) EncodeToStream(wc io.WriteCloser, private bool) error {
321	// See Issue #32
322	which := "PUBLIC"
323	if private {
324		which = "PRIVATE"
325	}
326	writer, err := armor.Encode(wc, fmt.Sprintf("PGP %s KEY BLOCK", which), PGPArmorHeaders)
327	if err != nil {
328		return err
329	}
330
331	if private {
332		err = k.SerializePrivate(writer)
333	} else {
334		err = k.Entity.Serialize(writer)
335	}
336	if err != nil {
337		return err
338	}
339
340	return writer.Close()
341}
342
343var cleanPGPInputRxx = regexp.MustCompile(`[ \t\r]*\n[ \t\r]*`)
344var bug8612PrepassRxx = regexp.MustCompile(`^(?P<header>-{5}BEGIN PGP (.*?)-{5})(\s*(?P<junk>.+?))$`)
345
346func cleanPGPInput(s string) string {
347	s = strings.TrimSpace(s)
348	v := cleanPGPInputRxx.Split(s, -1)
349	ret := strings.Join(v, "\n")
350	return ret
351}
352
353// note:  openpgp.ReadArmoredKeyRing only returns the first block.
354// It will never return multiple entities.
355func ReadOneKeyFromString(originalArmor string) (*PGPKeyBundle, *Warnings, error) {
356	return readOneKeyFromString(originalArmor, false /* liberal */)
357}
358
359// bug8612Prepass cleans off any garbage trailing the "-----" in the first line of a PGP
360// key. For years, the server allowed this junk through, so some keys on the server side
361// (and hashed into chains) have junk here. It's pretty safe to strip it out when replaying
362// sigchains, so do it.
363func bug8612Prepass(a string) string {
364	idx := strings.Index(a, "\n")
365	if idx < 0 {
366		return a
367	}
368	line0 := a[0:idx]
369	rest := a[idx:]
370	match := bug8612PrepassRxx.FindStringSubmatch(line0)
371	if len(match) == 0 {
372		return a
373	}
374	result := make(map[string]string)
375	for i, name := range bug8612PrepassRxx.SubexpNames() {
376		if i != 0 {
377			result[name] = match[i]
378		}
379	}
380	return result["header"] + rest
381}
382
383// note:  openpgp.ReadArmoredKeyRing only returns the first block.
384// It will never return multiple entities.
385func ReadOneKeyFromStringLiberal(originalArmor string) (*PGPKeyBundle, *Warnings, error) {
386	return readOneKeyFromString(originalArmor, true /* liberal */)
387}
388
389func readOneKeyFromString(originalArmor string, liberal bool) (*PGPKeyBundle, *Warnings, error) {
390	cleanArmor := cleanPGPInput(originalArmor)
391	if liberal {
392		cleanArmor = bug8612Prepass(cleanArmor)
393	}
394	reader := strings.NewReader(cleanArmor)
395	el, err := openpgp.ReadArmoredKeyRing(reader)
396	return finishReadOne(el, originalArmor, err)
397}
398
399// firstPrivateKey scans s for a private key block.
400func firstPrivateKey(s string) (string, error) {
401	scanner := bufio.NewScanner(strings.NewReader(s))
402	var lines []string
403	looking := true
404	complete := false
405	for scanner.Scan() {
406		line := scanner.Text()
407		if looking && strings.HasPrefix(line, "-----BEGIN PGP PRIVATE KEY BLOCK-----") {
408			looking = false
409
410		}
411		if looking {
412			continue
413		}
414		lines = append(lines, line)
415		if strings.HasPrefix(line, "-----END PGP PRIVATE KEY BLOCK-----") {
416			complete = true
417			break
418		}
419	}
420	if err := scanner.Err(); err != nil {
421		return "", err
422	}
423	if looking {
424		// never found a private key block
425		return "", NoSecretKeyError{}
426	}
427	if !complete {
428		// string ended without the end tag
429		return "", errors.New("never found end block line")
430	}
431	return strings.Join(lines, "\n"), nil
432}
433
434// ReadPrivateKeyFromString finds the first private key block in s
435// and decodes it into a PGPKeyBundle.  It is useful in the case
436// where s contains multiple key blocks and you want the private
437// key block.  For example, the result of gpg export.
438func ReadPrivateKeyFromString(s string) (*PGPKeyBundle, *Warnings, error) {
439	priv, err := firstPrivateKey(s)
440	if err != nil {
441		return nil, &Warnings{}, err
442	}
443	return ReadOneKeyFromString(priv)
444}
445
446func mergeKeysIfPossible(out *PGPKeyBundle, lst []*openpgp.Entity) error {
447	for _, e := range lst {
448		tmp := PGPKeyBundle{Entity: e}
449		if out.SamePrimaryAs(tmp) {
450			out.MergeKey(&tmp)
451		} else {
452			return TooManyKeysError{len(lst) + 1}
453		}
454	}
455	return nil
456}
457
458func finishReadOne(lst []*openpgp.Entity, armored string, err error) (*PGPKeyBundle, *Warnings, error) {
459	w := &Warnings{}
460	if err != nil {
461		return nil, w, err
462	}
463	if len(lst) == 0 {
464		return nil, w, NoKeyError{"No keys found in primary bundle"}
465	}
466	first := &PGPKeyBundle{Entity: lst[0]}
467
468	if len(lst) > 1 {
469
470		// Some keys like Sheldon Hern's (https://github.com/keybase/client/issues/2130)
471		// have the same primary key twice in their list of keys. In this case, we should just
472		// perform a merge if possible, since the server-side accepts and merges such key exports.
473		err = mergeKeysIfPossible(first, lst[1:])
474		if err != nil {
475			return nil, w, err
476		}
477	}
478
479	for _, bs := range first.Entity.BadSubkeys {
480		w.Push(Warningf("Bad subkey: %s", bs.Err))
481	}
482
483	if first.Entity.PrivateKey == nil {
484		first.ArmoredPublicKey = armored
485	}
486	return first, w, nil
487}
488
489func ReadOneKeyFromBytes(b []byte) (*PGPKeyBundle, *Warnings, error) {
490	reader := bytes.NewBuffer(b)
491	el, err := openpgp.ReadKeyRing(reader)
492	return finishReadOne(el, "", err)
493}
494
495func GetOneKey(jw *jsonw.Wrapper) (*PGPKeyBundle, *Warnings, error) {
496	s, err := jw.GetString()
497	if err != nil {
498		return nil, &Warnings{}, err
499	}
500	return ReadOneKeyFromString(s)
501}
502
503// XXX for now this is OK but probably we need a PGP uid parser
504// as in pgp-utils
505func (k *PGPKeyBundle) FindKeybaseUsername(un string) bool {
506
507	rxx := regexp.MustCompile("(?i)< " + un + "@keybase.io>$")
508
509	for _, id := range k.Identities {
510		if rxx.MatchString(id.Name) {
511			return true
512		}
513	}
514	return false
515}
516
517func (k PGPKeyBundle) VerboseDescription() string {
518	lines := k.UsersDescription()
519	lines = append(lines, k.KeyDescription())
520	return strings.Join(lines, "\n")
521}
522
523func (k PGPKeyBundle) HumanDescription() string {
524	user := k.GetPrimaryUID()
525	keyID := k.GetFingerprint().ToKeyID()
526	return fmt.Sprintf("PGP key %s %s", user, keyID)
527}
528
529func (k PGPKeyBundle) UsersDescription() []string {
530	id := k.GetPrimaryUID()
531	if len(id) == 0 {
532		return nil
533	}
534	return []string{"user: " + id}
535}
536
537// GetPrimaryUID gets the primary UID in the given key bundle, returned
538// in the 'Max K (foo) <bar@baz.com>' convention.
539func (k PGPKeyBundle) GetPrimaryUID() string {
540
541	var pri *openpgp.Identity
542	var s string
543	if len(k.Identities) == 0 {
544		return ""
545	}
546	var first *openpgp.Identity
547	for _, id := range k.Identities {
548		if first == nil {
549			first = id
550		}
551		if id.SelfSignature != nil && id.SelfSignature.IsPrimaryId != nil && *id.SelfSignature.IsPrimaryId {
552			pri = id
553			break
554		}
555	}
556	if pri == nil {
557		pri = first
558	}
559	if pri.UserId != nil {
560		s = pri.UserId.Id
561	} else {
562		s = pri.Name
563	}
564	return s
565}
566
567// HasSecretKey checks if the PGPKeyBundle contains secret key. This
568// function returning true does not indicate that the key is
569// functional - it may also be a key stub.
570func (k *PGPKeyBundle) HasSecretKey() bool {
571	return k.PrivateKey != nil
572}
573
574// FindPGPPrivateKey checks if supposed secret key PGPKeyBundle
575// contains any valid PrivateKey entities. Sometimes primary private
576// key is stoopped out but there are subkeys with secret keys.
577func FindPGPPrivateKey(k *PGPKeyBundle) bool {
578	if k.PrivateKey.PrivateKey != nil {
579		return true
580	}
581
582	for _, subKey := range k.Subkeys {
583		if subKey.PrivateKey != nil && subKey.PrivateKey.PrivateKey != nil {
584			return true
585		}
586	}
587
588	return false
589}
590
591func (k *PGPKeyBundle) CheckSecretKey() (err error) {
592	if k.PrivateKey == nil {
593		err = NoSecretKeyError{}
594	} else if k.PrivateKey.Encrypted {
595		err = kbcrypto.BadKeyError{Msg: "PGP key material should be unencrypted"}
596	} else if !FindPGPPrivateKey(k) && k.GPGFallbackKey == nil {
597		err = kbcrypto.BadKeyError{Msg: "no private key material or GPGKey"}
598	}
599	return
600}
601
602func (k *PGPKeyBundle) CanSign() bool {
603	return (k.PrivateKey != nil && !k.PrivateKey.Encrypted) || k.GPGFallbackKey != nil
604}
605
606func (k *PGPKeyBundle) GetBinaryKID() keybase1.BinaryKID {
607
608	prefix := []byte{
609		byte(kbcrypto.KeybaseKIDV1),
610		byte(k.PrimaryKey.PubKeyAlgo),
611	}
612
613	// XXX Hack;  Because PublicKey.serializeWithoutHeaders is off-limits
614	// to us, we need to do a full serialize and then strip off the header.
615	// The further annoyance is that the size of the header varies with the
616	// bitlen of the key.  Small keys (<191 bytes total) yield 8 bytes of header
617	// material --- for instance, 1024-bit test keys.  For longer keys, we
618	// have 9 bytes of header material, to encode a 2-byte frame, rather than
619	// a 1-byte frame.
620	buf := bytes.Buffer{}
621	_ = k.PrimaryKey.Serialize(&buf)
622	byts := buf.Bytes()
623	hdrBytes := 8
624	if len(byts) >= 193 {
625		hdrBytes++
626	}
627	sum := sha256.Sum256(buf.Bytes()[hdrBytes:])
628
629	out := append(prefix, sum[:]...)
630	out = append(out, byte(kbcrypto.IDSuffixKID))
631
632	return keybase1.BinaryKID(out)
633}
634
635func (k *PGPKeyBundle) GetKID() keybase1.KID {
636	return k.GetBinaryKID().ToKID()
637}
638
639func (k PGPKeyBundle) GetAlgoType() kbcrypto.AlgoType {
640	return kbcrypto.AlgoType(k.PrimaryKey.PubKeyAlgo)
641}
642
643func (k PGPKeyBundle) KeyDescription() string {
644	algo, kid, creation := k.KeyInfo()
645	return fmt.Sprintf("%s, ID %s, created %s", algo, kid, creation)
646}
647
648func (k PGPKeyBundle) KeyInfo() (algorithm, kid, creation string) {
649	pubkey := k.PrimaryKey
650
651	var typ string
652	switch pubkey.PubKeyAlgo {
653	case packet.PubKeyAlgoRSA, packet.PubKeyAlgoRSAEncryptOnly, packet.PubKeyAlgoRSASignOnly:
654		typ = "RSA"
655	case packet.PubKeyAlgoDSA:
656		typ = "DSA"
657	case packet.PubKeyAlgoECDSA:
658		typ = "ECDSA"
659	case packet.PubKeyAlgoEdDSA:
660		typ = "EdDSA"
661	default:
662		typ = "<UNKNOWN TYPE>"
663	}
664
665	bl, err := pubkey.BitLength()
666	if err != nil {
667		bl = 0
668	}
669
670	algorithm = fmt.Sprintf("%d-bit %s key", bl, typ)
671	kid = pubkey.KeyIdString()
672	creation = pubkey.CreationTime.Format("2006-01-02")
673
674	return
675}
676
677// Generates hash security warnings given a CKF
678func (k PGPKeyBundle) SecurityWarnings(kind HashSecurityWarningType) (warnings HashSecurityWarnings) {
679	fingerprint := k.GetFingerprint()
680	for _, identity := range k.Entity.Identities {
681		if identity.SelfSignature == nil ||
682			IsHashSecure(identity.SelfSignature.Hash) {
683			continue
684		}
685
686		warnings = append(
687			warnings,
688			NewHashSecurityWarning(
689				kind,
690				identity.SelfSignature.Hash,
691				&fingerprint,
692			),
693		)
694		return
695	}
696	return
697}
698
699func unlockPrivateKey(k *packet.PrivateKey, pw string) error {
700	if !k.Encrypted {
701		return nil
702	}
703	err := k.Decrypt([]byte(pw))
704	if err != nil && strings.HasSuffix(err.Error(), "private key checksum failure") {
705		// XXX this is gross, the openpgp library should return a better
706		// error if the PW was incorrectly specified
707		err = PassphraseError{}
708	}
709	return err
710}
711
712func (k *PGPKeyBundle) isAnyKeyEncrypted() bool {
713	if k.PrivateKey.Encrypted {
714		return true
715	}
716
717	for _, subkey := range k.Subkeys {
718		if subkey.PrivateKey.Encrypted {
719			return true
720		}
721	}
722
723	return false
724}
725
726func (k *PGPKeyBundle) unlockAllPrivateKeys(pw string) error {
727	if err := unlockPrivateKey(k.PrivateKey, pw); err != nil {
728		return err
729	}
730	for _, subkey := range k.Subkeys {
731		if err := unlockPrivateKey(subkey.PrivateKey, pw); err != nil {
732			return err
733		}
734	}
735	return nil
736}
737
738func (k *PGPKeyBundle) Unlock(m MetaContext, reason string, secretUI SecretUI) error {
739	if !k.isAnyKeyEncrypted() {
740		m.Debug("Key is not encrypted, skipping Unlock.")
741		return nil
742	}
743
744	unlocker := func(pw string, _ bool) (ret GenericKey, err error) {
745		if err = k.unlockAllPrivateKeys(pw); err != nil {
746			return nil, err
747		}
748		return k, nil
749	}
750
751	_, err := NewKeyUnlocker(5, reason, k.VerboseDescription(), PassphraseTypePGP, false, secretUI, unlocker).Run(m)
752	return err
753}
754
755func (k *PGPKeyBundle) CheckFingerprint(fp *PGPFingerprint) error {
756	if k == nil {
757		return UnexpectedKeyError{}
758	}
759	if fp == nil {
760		return UnexpectedKeyError{}
761	}
762	fp2 := k.GetFingerprint()
763	if !fp2.Eq(*fp) {
764		return BadFingerprintError{fp2, *fp}
765	}
766	return nil
767}
768
769func (k *PGPKeyBundle) SignToString(msg []byte) (sig string, id keybase1.SigIDBase, err error) {
770	if sig, id, err = SimpleSign(msg, *k); err != nil && k.GPGFallbackKey != nil {
771		return k.GPGFallbackKey.SignToString(msg)
772	}
773	return
774}
775
776func (k PGPKeyBundle) VerifyStringAndExtract(ctx VerifyContext, sig string) (msg []byte, id keybase1.SigIDBase, err error) {
777	var ps *ParsedSig
778	if ps, err = PGPOpenSig(sig); err != nil {
779		return
780	} else if err = ps.Verify(k); err != nil {
781		ctx.Debug("Failing key----------\n%s", k.ArmoredPublicKey)
782		ctx.Debug("Failing sig----------\n%s", sig)
783		return
784	}
785	msg = ps.LiteralData
786	id = ps.ID()
787	return
788}
789
790func (k PGPKeyBundle) VerifyString(ctx VerifyContext, sig string, msg []byte) (id keybase1.SigIDBase, err error) {
791	extractedMsg, resID, err := k.VerifyStringAndExtract(ctx, sig)
792	if err != nil {
793		return
794	}
795	if !FastByteArrayEq(extractedMsg, msg) {
796		err = BadSigError{"wrong payload"}
797		return
798	}
799	id = resID
800	return
801}
802
803func IsPGPAlgo(algo kbcrypto.AlgoType) bool {
804	switch algo {
805	case kbcrypto.KIDPGPRsa, kbcrypto.KIDPGPElgamal, kbcrypto.KIDPGPDsa, kbcrypto.KIDPGPEcdh, kbcrypto.KIDPGPEcdsa, kbcrypto.KIDPGPBase, kbcrypto.KIDPGPEddsa:
806		return true
807	}
808	return false
809}
810
811func (k *PGPKeyBundle) FindEmail(em string) bool {
812	for _, ident := range k.Identities {
813		if i, e := ParseIdentity(ident.Name); e == nil && i.Email == em {
814			return true
815		}
816	}
817	return false
818}
819
820func (k *PGPKeyBundle) IdentityNames() []string {
821	var names []string
822	for _, ident := range k.Identities {
823		names = append(names, ident.Name)
824	}
825	return names
826}
827
828func (k *PGPKeyBundle) GetPGPIdentities() []keybase1.PGPIdentity {
829	ret := make([]keybase1.PGPIdentity, len(k.Identities))
830	for _, pgpIdentity := range k.Identities {
831		ret = append(ret, ExportPGPIdentity(pgpIdentity))
832	}
833	return ret
834}
835
836// CheckIdentity finds the foo_user@keybase.io PGP identity and figures out when it
837// was created and when it's slated to expire. We plan to start phasing out use of
838// PGP-specified Expiration times as far as sigchain walking is concerned. But for now,
839// there are a few places where it's still used (see ComputedKeyInfos#InsertServerEldestKey).
840func (k *PGPKeyBundle) CheckIdentity(kbid Identity) (match bool, ctime int64, etime int64) {
841	ctime, etime = -1, -1
842	for _, pgpIdentity := range k.Identities {
843		if Cicmp(pgpIdentity.UserId.Email, kbid.Email) {
844			match = true
845			ctime = pgpIdentity.SelfSignature.CreationTime.Unix()
846			// This is a special case in OpenPGP, so we used KeyLifetimeSecs
847			lifeSeconds := pgpIdentity.SelfSignature.KeyLifetimeSecs
848			if lifeSeconds == nil {
849				// No expiration time is OK, it just means it never expires.
850				etime = 0
851			} else {
852				etime = ctime + int64(*lifeSeconds)
853			}
854			break
855		}
856	}
857	return
858}
859
860// EncryptToString fails for this type of key, since we haven't implemented it yet
861func (k *PGPKeyBundle) EncryptToString(plaintext []byte, sender GenericKey) (ciphertext string, err error) {
862	err = KeyCannotEncryptError{}
863	return
864}
865
866// DecryptFromString fails for this type of key, since we haven't implemented it yet
867func (k *PGPKeyBundle) DecryptFromString(ciphertext string) (msg []byte, sender keybase1.KID, err error) {
868	err = KeyCannotDecryptError{}
869	return
870}
871
872// CanEncrypt returns false for now, since we haven't implemented PGP encryption of packets
873// for metadata operations
874func (k *PGPKeyBundle) CanEncrypt() bool { return false }
875
876// CanDecrypt returns false for now, since we haven't implemented PGP encryption of packets
877// for metadata operations
878func (k *PGPKeyBundle) CanDecrypt() bool { return false }
879
880func (k *PGPKeyBundle) ExportPublicAndPrivate() (public RawPublicKey, private RawPrivateKey, err error) {
881	var publicKey, privateKey bytes.Buffer
882
883	serializePublic := func() error { return k.Entity.Serialize(&publicKey) }
884	serializePrivate := func() error { return k.SerializePrivate(&privateKey) }
885
886	// NOTE(maxtaco): For imported keys, it is crucial to serialize the public key
887	// **before** the private key, since the latter operation destructively
888	// removes signature subpackets from the key serialization.
889	// This was the cause of keybase/keybase-issues#1906.
890	//
891	// Urg, there's still more.  For generated keys, it's the opposite.
892	// We have to sign the key components first (via SerializePrivate)
893	// so we can export them publicly.
894
895	if k.Generated {
896		err = serializePrivate()
897		if err == nil {
898			err = serializePublic()
899		}
900	} else {
901		err = serializePublic()
902
903		if err == nil {
904			err = serializePrivate()
905		}
906	}
907
908	if err != nil {
909		return nil, nil, err
910	}
911
912	return RawPublicKey(publicKey.Bytes()), RawPrivateKey(privateKey.Bytes()), nil
913}
914
915func (k *PGPKeyBundle) SecretSymmetricKey(reason EncryptionReason) (NaclSecretBoxKey, error) {
916	return NaclSecretBoxKey{}, KeyCannotEncryptError{}
917}
918
919//===================================================
920
921// Fulfill the TrackIdComponent interface
922
923func (p PGPFingerprint) ToIDString() string {
924	return p.String()
925}
926
927func (p PGPFingerprint) ToKeyValuePair() (string, string) {
928	return PGPAssertionKey, p.ToIDString()
929}
930
931func (p PGPFingerprint) GetProofState() keybase1.ProofState {
932	return keybase1.ProofState_OK
933}
934
935func (p PGPFingerprint) LastWriterWins() bool {
936	return false
937}
938
939func (p PGPFingerprint) GetProofType() keybase1.ProofType {
940	return keybase1.ProofType_PGP
941}
942
943//===================================================
944
945func EncryptPGPKey(bundle *openpgp.Entity, passphrase string) error {
946	passBytes := []byte(passphrase)
947
948	if bundle.PrivateKey != nil && bundle.PrivateKey.PrivateKey != nil {
949		// Primary private key exists and is not stubbed.
950		if err := bundle.PrivateKey.Encrypt(passBytes, nil); err != nil {
951			return err
952		}
953	}
954
955	for _, subkey := range bundle.Subkeys {
956		if subkey.PrivateKey == nil || subkey.PrivateKey.PrivateKey == nil {
957			// There has to be a private key and not stubbed.
958			continue
959		}
960
961		if err := subkey.PrivateKey.Encrypt(passBytes, nil); err != nil {
962			return err
963		}
964	}
965
966	return nil
967}
968