passphrasePrompt prompts the user for a passphrase when this is required for encryption or decryption.
()
| 541 | // passphrasePrompt prompts the user for a passphrase when this is required for |
| 542 | // encryption or decryption. |
| 543 | func (key *MasterKey) passphrasePrompt() func(keys []openpgp.Key, symmetric bool) ([]byte, error) { |
| 544 | callCounter := 0 |
| 545 | maxCalls := 3 |
| 546 | return func(keys []openpgp.Key, symmetric bool) ([]byte, error) { |
| 547 | if callCounter >= maxCalls { |
| 548 | return nil, fmt.Errorf("function passphrasePrompt called too many times") |
| 549 | } |
| 550 | callCounter++ |
| 551 | |
| 552 | conn, err := gpgagent.NewConn() |
| 553 | if err == gpgagent.ErrNoAgent { |
| 554 | log.Infof("gpg-agent not found, continuing with manual passphrase " + |
| 555 | "input...") |
| 556 | fmt.Print("Enter PGP key passphrase: ") |
| 557 | pass, err := term.ReadPassword(int(os.Stdin.Fd())) |
| 558 | if err != nil { |
| 559 | return nil, err |
| 560 | } |
| 561 | for _, k := range keys { |
| 562 | k.PrivateKey.Decrypt(pass) |
| 563 | } |
| 564 | return pass, err |
| 565 | } |
| 566 | if err != nil { |
| 567 | return nil, fmt.Errorf("could not establish connection with gpg-agent: %s", err) |
| 568 | } |
| 569 | defer func(conn *gpgagent.Conn) { |
| 570 | if err := conn.Close(); err != nil { |
| 571 | log.Errorf("failed to close connection with gpg-agent: %s", err) |
| 572 | } |
| 573 | }(conn) |
| 574 | |
| 575 | for _, k := range keys { |
| 576 | req := gpgagent.PassphraseRequest{ |
| 577 | CacheKey: k.PublicKey.KeyIdShortString(), |
| 578 | Prompt: "Passphrase", |
| 579 | Desc: fmt.Sprintf("Unlock key %s to decrypt sops's key", k.PublicKey.KeyIdShortString()), |
| 580 | } |
| 581 | pass, err := conn.GetPassphrase(&req) |
| 582 | if err != nil { |
| 583 | return nil, fmt.Errorf("gpg-agent passphrase request errored: %s", err) |
| 584 | } |
| 585 | k.PrivateKey.Decrypt([]byte(pass)) |
| 586 | return []byte(pass), nil |
| 587 | } |
| 588 | |
| 589 | return nil, fmt.Errorf("no key to unlock") |
| 590 | } |
| 591 | } |
| 592 | |
| 593 | // loadRing attempts to load the keyring from the provided path. |
| 594 | // Unsupported keys are ignored as long as at least a single valid key is |
no test coverage detected