github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/libkb/pgp_key.go (about)

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