Skip to content

Commit

Permalink
Fixed race condition in pgpEncrypt and pgpSign
Browse files Browse the repository at this point in the history
  • Loading branch information
BenjaminGuzman committed Apr 23, 2022
1 parent 0a5e005 commit 2ed4781
Showing 1 changed file with 23 additions and 35 deletions.
58 changes: 23 additions & 35 deletions email-strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -549,35 +549,29 @@ func pgpEncrypt(data []byte, senderId string, recipientsIds ...string) ([]byte,

log.Debugln("Encrypting data. Executing gpg", gpgArgs)
encryptCmd := exec.Command("gpg", gpgArgs...)
var stdout, stderr bytes.Buffer
encryptCmd.Stderr = &stderr
encryptCmd.Stdout = &stdout

stdin, err := encryptCmd.StdinPipe()
if err != nil {
return nil, err
}
stdout, err := encryptCmd.StdoutPipe()
if err != nil {
return nil, err
}
stderr, _ := encryptCmd.StderrPipe()

if err := encryptCmd.Start(); err != nil {
return nil, err
}

if _, err = stdin.Write(data); err != nil {
return nil, err
}
_ = stdin.Close() // we need to close it, otherwise gpg will keep reading from it and block the thread
go func() {
defer stdin.Close() // we need to close it, otherwise gpg will keep reading from it and block the thread
_, err = stdin.Write(data)
}()

encrypted, err := io.ReadAll(stdout)
if err != nil {
if err := encryptCmd.Start(); err != nil {
return nil, err
}

e, _ := io.ReadAll(stderr)
if err = encryptCmd.Wait(); err != nil { // if recipient's key doesn't exist, this will return an error
return nil, fmt.Errorf("error while encrypting PGP message, pgp stderr: \"%s\". %w", e, err)
if err := encryptCmd.Wait(); err != nil { // if recipient's key doesn't exist, this will return an error
return nil, fmt.Errorf("error while encrypting PGP message, pgp stderr: \"%s\". %w", stderr.Bytes(), err)
}

encrypted := stdout.Bytes()
return encrypted, nil
}

Expand All @@ -597,35 +591,29 @@ func pgpSign(data []byte, senderId string, passphraseFile string) ([]byte, error

log.Debugln("Signing data. Executing gpg", gpgArgs)
signCmd := exec.Command("gpg", gpgArgs...)
var stdout, stderr bytes.Buffer
signCmd.Stderr = &stderr
signCmd.Stdout = &stdout

stdin, err := signCmd.StdinPipe()
if err != nil {
return nil, err
}
stdout, err := signCmd.StdoutPipe()
if err != nil {
return nil, err
}
stderr, _ := signCmd.StderrPipe()

if err := signCmd.Start(); err != nil {
return nil, err
}

if _, err = stdin.Write(data); err != nil {
return nil, err
}
_ = stdin.Close() // we need to close it, otherwise gpg will keep reading from it and will block the thread
go func() {
defer stdin.Close() // we need to close it, otherwise gpg will keep reading from it and block the thread
_, err = stdin.Write(data)
}()

signed, err := io.ReadAll(stdout)
if err != nil {
if err := signCmd.Start(); err != nil {
return nil, err
}

e, _ := io.ReadAll(stderr)
if err := signCmd.Wait(); err != nil { // if recipient's key doesn't exist, this will return an error
return nil, fmt.Errorf("error while signing PGP message, pgp stderr: \"%s\". %w", e, err)
return nil, fmt.Errorf("error while signing PGP message, pgp stderr: \"%s\". %w", stderr.Bytes(), err)
}

signed := stdout.Bytes()
return signed, nil
}

Expand Down

0 comments on commit 2ed4781

Please sign in to comment.