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 }