Improve error handling, fix linter (#92)
* Improve error handling, fix linter
This commit is contained in:
parent
6b2ac0b11c
commit
53a85837e0
23 changed files with 194 additions and 186 deletions
|
|
@ -29,3 +29,4 @@ linters:
|
||||||
- gofumpt # Enforce a stricter format than gofmt
|
- gofumpt # Enforce a stricter format than gofmt
|
||||||
- gci # Enforce blank lines check
|
- gci # Enforce blank lines check
|
||||||
- nlreturn # Enforce blank lines for return statements
|
- nlreturn # Enforce blank lines for return statements
|
||||||
|
- exhaustivestruct # Enforce structures to be fully filled on instantiation - terrible with openpgp configs
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ NewPlainMessageFromFile(data []byte, filename string, modTime int) *PlainMessage
|
||||||
now accept private keys as public keys and perform automatic casting if the keys are locked.
|
now accept private keys as public keys and perform automatic casting if the keys are locked.
|
||||||
- The `PlainMessage` struct now contains the fields `Filename` (string) and `Time` (uint32)
|
- The `PlainMessage` struct now contains the fields `Filename` (string) and `Time` (uint32)
|
||||||
- All the Decrypt* functions return the filename, type, and time specified in the encrypted message
|
- All the Decrypt* functions return the filename, type, and time specified in the encrypted message
|
||||||
|
- Improved error wrapping and management
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Public key armoring headers
|
- Public key armoring headers
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/ProtonMail/gopenpgp/v2/constants"
|
"github.com/ProtonMail/gopenpgp/v2/constants"
|
||||||
"github.com/ProtonMail/gopenpgp/v2/internal"
|
"github.com/ProtonMail/gopenpgp/v2/internal"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/crypto/openpgp/armor"
|
"golang.org/x/crypto/openpgp/armor"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -46,7 +46,7 @@ func ArmorWithTypeAndCustomHeaders(input []byte, armorType, version, comment str
|
||||||
func Unarmor(input string) ([]byte, error) {
|
func Unarmor(input string) ([]byte, error) {
|
||||||
b, err := internal.Unarmor(input)
|
b, err := internal.Unarmor(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopengp: unable to unarmor")
|
||||||
}
|
}
|
||||||
return ioutil.ReadAll(b.Body)
|
return ioutil.ReadAll(b.Body)
|
||||||
}
|
}
|
||||||
|
|
@ -57,13 +57,13 @@ func armorWithTypeAndHeaders(input []byte, armorType string, headers map[string]
|
||||||
w, err := armor.Encode(&b, armorType, headers)
|
w, err := armor.Encode(&b, armorType, headers)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopengp: unable to encode armoring")
|
||||||
}
|
}
|
||||||
if _, err = w.Write(input); err != nil {
|
if _, err = w.Write(input); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopengp: unable to write armored to buffer")
|
||||||
}
|
}
|
||||||
if err := w.Close(); err != nil {
|
if err := w.Close(); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopengp: unable to close armor buffer")
|
||||||
}
|
}
|
||||||
return b.String(), nil
|
return b.String(), nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
)
|
)
|
||||||
|
|
@ -36,11 +37,11 @@ func (ap *AttachmentProcessor) Finish() (*PGPSplitMessage, error) {
|
||||||
return nil, ap.err
|
return nil, ap.err
|
||||||
}
|
}
|
||||||
if err := (*ap.w).Close(); err != nil {
|
if err := (*ap.w).Close(); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopengpp: unable to close writer")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := (*ap.pipe).Close(); err != nil {
|
if err := (*ap.pipe).Close(); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopengpp: unable to close pipe")
|
||||||
}
|
}
|
||||||
|
|
||||||
ap.done.Wait()
|
ap.done.Wait()
|
||||||
|
|
@ -88,7 +89,7 @@ func (keyRing *KeyRing) newAttachmentProcessor(
|
||||||
var encryptErr error
|
var encryptErr error
|
||||||
ew, encryptErr = openpgp.Encrypt(writer, keyRing.entities, nil, hints, config)
|
ew, encryptErr = openpgp.Encrypt(writer, keyRing.entities, nil, hints, config)
|
||||||
if encryptErr != nil {
|
if encryptErr != nil {
|
||||||
return nil, encryptErr
|
return nil, errors.Wrap(encryptErr, "gopengpp: unable to encrypt attachment")
|
||||||
}
|
}
|
||||||
attachmentProc.w = &ew
|
attachmentProc.w = &ew
|
||||||
attachmentProc.pipe = writer
|
attachmentProc.pipe = writer
|
||||||
|
|
@ -148,13 +149,13 @@ func (keyRing *KeyRing) DecryptAttachment(message *PGPSplitMessage) (*PlainMessa
|
||||||
|
|
||||||
md, err := openpgp.ReadMessage(encryptedReader, privKeyEntries, nil, config)
|
md, err := openpgp.ReadMessage(encryptedReader, privKeyEntries, nil, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopengpp: unable to read attachment")
|
||||||
}
|
}
|
||||||
|
|
||||||
decrypted := md.UnverifiedBody
|
decrypted := md.UnverifiedBody
|
||||||
b, err := ioutil.ReadAll(decrypted)
|
b, err := ioutil.ReadAll(decrypted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopengpp: unable to read attachment body")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PlainMessage{
|
return &PlainMessage{
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,11 @@ func (key *Key) Serialize() ([]byte, error) {
|
||||||
err = key.entity.SerializePrivateWithoutSigning(&buffer, nil)
|
err = key.entity.SerializePrivateWithoutSigning(&buffer, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
return buffer.Bytes(), err
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "gopenpgp: error in serializing key")
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Armor returns the armored key as a string with default gopenpgp headers.
|
// Armor returns the armored key as a string with default gopenpgp headers.
|
||||||
|
|
@ -235,7 +239,7 @@ func (key *Key) GetArmoredPublicKeyWithCustomHeaders(comment, version string) (s
|
||||||
func (key *Key) GetPublicKey() (b []byte, err error) {
|
func (key *Key) GetPublicKey() (b []byte, err error) {
|
||||||
var outBuf bytes.Buffer
|
var outBuf bytes.Buffer
|
||||||
if err = key.entity.Serialize(&outBuf); err != nil {
|
if err = key.entity.Serialize(&outBuf); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in serializing public key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return outBuf.Bytes(), nil
|
return outBuf.Bytes(), nil
|
||||||
|
|
@ -397,7 +401,7 @@ func (key *Key) readFrom(r io.Reader, armored bool) error {
|
||||||
entities, err = openpgp.ReadKeyRing(r)
|
entities, err = openpgp.ReadKeyRing(r)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "gopenpgp: error in reading key ring")
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(entities) > 1 {
|
if len(entities) > 1 {
|
||||||
|
|
@ -456,7 +460,7 @@ func generateKey(
|
||||||
|
|
||||||
newEntity, err := openpgp.NewEntity(name, comments, email, cfg)
|
newEntity, err := openpgp.NewEntity(name, comments, email, cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopengpp: error in encoding new entity")
|
||||||
}
|
}
|
||||||
|
|
||||||
if newEntity.PrivateKey == nil {
|
if newEntity.PrivateKey == nil {
|
||||||
|
|
|
||||||
|
|
@ -82,8 +82,7 @@ func (keyRing *KeyRing) getSigningEntity() (*openpgp.Entity, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if signEntity == nil {
|
if signEntity == nil {
|
||||||
err := errors.New("gopenpgp: cannot sign message, unable to unlock signer key")
|
return nil, errors.New("gopenpgp: cannot sign message, unable to unlock signer key")
|
||||||
return signEntity, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return signEntity, nil
|
return signEntity, nil
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
)
|
)
|
||||||
|
|
@ -47,7 +48,7 @@ func (keyRing *KeyRing) SignDetached(message *PlainMessage) (*PGPSignature, erro
|
||||||
var outBuf bytes.Buffer
|
var outBuf bytes.Buffer
|
||||||
// sign bin
|
// sign bin
|
||||||
if err := openpgp.DetachSign(&outBuf, signEntity, message.NewReader(), config); err != nil {
|
if err := openpgp.DetachSign(&outBuf, signEntity, message.NewReader(), config); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in signing")
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewPGPSignature(outBuf.Bytes()), nil
|
return NewPGPSignature(outBuf.Bytes()), nil
|
||||||
|
|
@ -95,17 +96,17 @@ func asymmetricEncrypt(plainMessage *PlainMessage, publicKey, privateKey *KeyRin
|
||||||
encryptWriter, err = openpgp.EncryptText(&outBuf, publicKey.entities, signEntity, hints, config)
|
encryptWriter, err = openpgp.EncryptText(&outBuf, publicKey.entities, signEntity, hints, config)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in encrypting asymmetrically")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = encryptWriter.Write(plainMessage.GetBinary())
|
_, err = encryptWriter.Write(plainMessage.GetBinary())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in writing to message")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = encryptWriter.Close()
|
err = encryptWriter.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in closing message")
|
||||||
}
|
}
|
||||||
|
|
||||||
return outBuf.Bytes(), nil
|
return outBuf.Bytes(), nil
|
||||||
|
|
@ -130,12 +131,12 @@ func asymmetricDecrypt(
|
||||||
|
|
||||||
messageDetails, err := openpgp.ReadMessage(encryptedIO, privKeyEntries, nil, config)
|
messageDetails, err := openpgp.ReadMessage(encryptedIO, privKeyEntries, nil, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in reading message")
|
||||||
}
|
}
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(messageDetails.UnverifiedBody)
|
body, err := ioutil.ReadAll(messageDetails.UnverifiedBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in reading message body")
|
||||||
}
|
}
|
||||||
|
|
||||||
if verifyKey != nil {
|
if verifyKey != nil {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package crypto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
@ -18,7 +17,7 @@ func (keyRing *KeyRing) DecryptSessionKey(keyPacket []byte) (*SessionKey, error)
|
||||||
var p packet.Packet
|
var p packet.Packet
|
||||||
var err error
|
var err error
|
||||||
if p, err = packets.Next(); err != nil {
|
if p, err = packets.Next(); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in reading packets")
|
||||||
}
|
}
|
||||||
|
|
||||||
ek := p.(*packet.EncryptedKey)
|
ek := p.(*packet.EncryptedKey)
|
||||||
|
|
@ -35,7 +34,7 @@ func (keyRing *KeyRing) DecryptSessionKey(keyPacket []byte) (*SessionKey, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
if decryptErr != nil {
|
if decryptErr != nil {
|
||||||
return nil, decryptErr
|
return nil, errors.Wrap(decryptErr, "gopenpgp: error in decrypting")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ek == nil {
|
if ek == nil {
|
||||||
|
|
@ -68,8 +67,7 @@ func (keyRing *KeyRing) EncryptSessionKey(sk *SessionKey) ([]byte, error) {
|
||||||
|
|
||||||
for _, pub := range pubKeys {
|
for _, pub := range pubKeys {
|
||||||
if err := packet.SerializeEncryptedKey(outbuf, pub, cf, sk.Key, nil); err != nil {
|
if err := packet.SerializeEncryptedKey(outbuf, pub, cf, sk.Key, nil); err != nil {
|
||||||
err = fmt.Errorf("gopenpgp: cannot set key: %v", err)
|
return nil, errors.Wrap(err, "gopenpgp: cannot set key")
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return outbuf.Bytes(), nil
|
return outbuf.Bytes(), nil
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@ package crypto
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
goerrors "errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
@ -15,7 +14,7 @@ import (
|
||||||
"github.com/ProtonMail/gopenpgp/v2/armor"
|
"github.com/ProtonMail/gopenpgp/v2/armor"
|
||||||
"github.com/ProtonMail/gopenpgp/v2/constants"
|
"github.com/ProtonMail/gopenpgp/v2/constants"
|
||||||
"github.com/ProtonMail/gopenpgp/v2/internal"
|
"github.com/ProtonMail/gopenpgp/v2/internal"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/crypto/openpgp/clearsign"
|
"golang.org/x/crypto/openpgp/clearsign"
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
)
|
)
|
||||||
|
|
@ -68,6 +67,7 @@ func NewPlainMessage(data []byte) *PlainMessage {
|
||||||
return &PlainMessage{
|
return &PlainMessage{
|
||||||
Data: clone(data),
|
Data: clone(data),
|
||||||
TextType: false,
|
TextType: false,
|
||||||
|
Filename: "",
|
||||||
Time: uint32(GetUnixTime()),
|
Time: uint32(GetUnixTime()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -90,6 +90,7 @@ func NewPlainMessageFromString(text string) *PlainMessage {
|
||||||
return &PlainMessage{
|
return &PlainMessage{
|
||||||
Data: []byte(strings.ReplaceAll(strings.ReplaceAll(text, "\r\n", "\n"), "\n", "\r\n")),
|
Data: []byte(strings.ReplaceAll(strings.ReplaceAll(text, "\r\n", "\n"), "\n", "\r\n")),
|
||||||
TextType: true,
|
TextType: true,
|
||||||
|
Filename: "",
|
||||||
Time: uint32(GetUnixTime()),
|
Time: uint32(GetUnixTime()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -105,12 +106,12 @@ func NewPGPMessage(data []byte) *PGPMessage {
|
||||||
func NewPGPMessageFromArmored(armored string) (*PGPMessage, error) {
|
func NewPGPMessageFromArmored(armored string) (*PGPMessage, error) {
|
||||||
encryptedIO, err := internal.Unarmor(armored)
|
encryptedIO, err := internal.Unarmor(armored)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in unarmoring message")
|
||||||
}
|
}
|
||||||
|
|
||||||
message, err := ioutil.ReadAll(encryptedIO.Body)
|
message, err := ioutil.ReadAll(encryptedIO.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in reading armored message")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PGPMessage{
|
return &PGPMessage{
|
||||||
|
|
@ -150,12 +151,12 @@ func NewPGPSignature(data []byte) *PGPSignature {
|
||||||
func NewPGPSignatureFromArmored(armored string) (*PGPSignature, error) {
|
func NewPGPSignatureFromArmored(armored string) (*PGPSignature, error) {
|
||||||
encryptedIO, err := internal.Unarmor(armored)
|
encryptedIO, err := internal.Unarmor(armored)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in unarmoring signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
signature, err := ioutil.ReadAll(encryptedIO.Body)
|
signature, err := ioutil.ReadAll(encryptedIO.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in reading armored signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PGPSignature{
|
return &PGPSignature{
|
||||||
|
|
@ -182,7 +183,7 @@ func NewClearTextMessageFromArmored(signedMessage string) (*ClearTextMessage, er
|
||||||
|
|
||||||
signature, err := ioutil.ReadAll(modulusBlock.ArmoredSignature.Body)
|
signature, err := ioutil.ReadAll(modulusBlock.ArmoredSignature.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in reading cleartext message")
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewClearTextMessage(modulusBlock.Bytes, signature), nil
|
return NewClearTextMessage(modulusBlock.Bytes, signature), nil
|
||||||
|
|
@ -257,7 +258,7 @@ func (msg *PGPMessage) GetEncryptionKeyIDs() ([]uint64, bool) {
|
||||||
Loop:
|
Loop:
|
||||||
for {
|
for {
|
||||||
var p packet.Packet
|
var p packet.Packet
|
||||||
if p, err = packets.Next(); err == io.EOF {
|
if p, err = packets.Next(); goerrors.Is(err, io.EOF) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch p := p.(type) {
|
switch p := p.(type) {
|
||||||
|
|
@ -333,7 +334,7 @@ func (msg *PGPMessage) SeparateKeyAndData(estimatedLength, garbageCollector int)
|
||||||
var encryptedKey *packet.EncryptedKey
|
var encryptedKey *packet.EncryptedKey
|
||||||
for {
|
for {
|
||||||
var p packet.Packet
|
var p packet.Packet
|
||||||
if p, err = packets.Next(); err == io.EOF {
|
if p, err = packets.Next(); goerrors.Is(err, io.EOF) {
|
||||||
err = nil
|
err = nil
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
@ -354,22 +355,22 @@ func (msg *PGPMessage) SeparateKeyAndData(estimatedLength, garbageCollector int)
|
||||||
b.Grow(1<<16 + estimatedLength)
|
b.Grow(1<<16 + estimatedLength)
|
||||||
// empty encoded length + start byte
|
// empty encoded length + start byte
|
||||||
if _, err := b.Write(make([]byte, 6)); err != nil {
|
if _, err := b.Write(make([]byte, 6)); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in writing data packet header")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := b.WriteByte(byte(1)); err != nil {
|
if err := b.WriteByte(byte(1)); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in writing data packet header")
|
||||||
}
|
}
|
||||||
|
|
||||||
actualLength := 1
|
actualLength := 1
|
||||||
block := make([]byte, 128)
|
block := make([]byte, 128)
|
||||||
for {
|
for {
|
||||||
n, err := p.Contents.Read(block)
|
n, err := p.Contents.Read(block)
|
||||||
if err == io.EOF {
|
if goerrors.Is(err, io.EOF) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if _, err := b.Write(block[:n]); err != nil {
|
if _, err := b.Write(block[:n]); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in writing data packet body")
|
||||||
}
|
}
|
||||||
actualLength += n
|
actualLength += n
|
||||||
gcCounter += n
|
gcCounter += n
|
||||||
|
|
@ -409,7 +410,7 @@ func (msg *PGPMessage) SeparateKeyAndData(estimatedLength, garbageCollector int)
|
||||||
|
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
if err := encryptedKey.Serialize(&buf); err != nil {
|
if err := encryptedKey.Serialize(&buf); err != nil {
|
||||||
return nil, fmt.Errorf("gopenpgp: cannot serialize encrypted key: %v", err)
|
return nil, errors.Wrap(err, "gopenpgp: cannot serialize encrypted key")
|
||||||
}
|
}
|
||||||
outSplit.KeyPacket = buf.Bytes()
|
outSplit.KeyPacket = buf.Bytes()
|
||||||
|
|
||||||
|
|
@ -456,7 +457,7 @@ func (msg *ClearTextMessage) GetBinarySignature() []byte {
|
||||||
func (msg *ClearTextMessage) GetArmored() (string, error) {
|
func (msg *ClearTextMessage) GetArmored() (string, error) {
|
||||||
armSignature, err := armor.ArmorWithType(msg.GetBinarySignature(), constants.PGPSignatureHeader)
|
armSignature, err := armor.ArmorWithType(msg.GetBinarySignature(), constants.PGPSignatureHeader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: error in armoring cleartext message")
|
||||||
}
|
}
|
||||||
|
|
||||||
str := "-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: SHA512\r\n\r\n"
|
str := "-----BEGIN PGP SIGNED MESSAGE-----\r\nHash: SHA512\r\n\r\n"
|
||||||
|
|
@ -486,7 +487,7 @@ func getSignatureKeyIDs(data []byte) ([]uint64, bool) {
|
||||||
Loop:
|
Loop:
|
||||||
for {
|
for {
|
||||||
var p packet.Packet
|
var p packet.Packet
|
||||||
if p, err = packets.Next(); err == io.EOF {
|
if p, err = packets.Next(); goerrors.Is(err, io.EOF) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
switch p := p.(type) {
|
switch p := p.(type) {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package crypto
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -24,7 +25,7 @@ func TestTextMessageEncryptionWithPassword(t *testing.T) {
|
||||||
for {
|
for {
|
||||||
var p packet.Packet
|
var p packet.Packet
|
||||||
var errEOF error
|
var errEOF error
|
||||||
if p, errEOF = packets.Next(); errEOF == io.EOF {
|
if p, errEOF = packets.Next(); errors.Is(errEOF, io.EOF) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
sessionKey, ok := p.(*packet.SymmetricKeyEncrypted)
|
sessionKey, ok := p.(*packet.SymmetricKeyEncrypted)
|
||||||
|
|
@ -138,7 +139,7 @@ func TestIssue11(t *testing.T) {
|
||||||
|
|
||||||
issue11Keyring, err := NewKeyRing(issue11Key)
|
issue11Keyring, err := NewKeyRing(issue11Key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Expected no error while bulding private keyring, got:", err)
|
t.Fatal("Expected no error while building private keyring, got:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
senderKey, err := NewKeyFromArmored(readTestFile("issue11_publickey", false))
|
senderKey, err := NewKeyFromArmored(readTestFile("issue11_publickey", false))
|
||||||
|
|
@ -154,7 +155,7 @@ func TestIssue11(t *testing.T) {
|
||||||
|
|
||||||
pgpMessage, err := NewPGPMessageFromArmored(readTestFile("issue11_message", false))
|
pgpMessage, err := NewPGPMessageFromArmored(readTestFile("issue11_message", false))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Expected no error while unlocking private keyring, got:", err)
|
t.Fatal("Expected no error while reading ciphertext, got:", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
plainMessage, err := issue11Keyring.Decrypt(pgpMessage, senderKeyring, 0)
|
plainMessage, err := issue11Keyring.Decrypt(pgpMessage, senderKeyring, 0)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
gomime "github.com/ProtonMail/go-mime"
|
gomime "github.com/ProtonMail/go-mime"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
)
|
)
|
||||||
|
|
@ -53,14 +53,14 @@ func parseMIME(
|
||||||
) (*gomime.BodyCollector, []string, []string, error) {
|
) (*gomime.BodyCollector, []string, []string, error) {
|
||||||
mm, err := mail.ReadMessage(strings.NewReader(mimeBody))
|
mm, err := mail.ReadMessage(strings.NewReader(mimeBody))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, errors.Wrap(err, "gopenpgp: error in reading message")
|
||||||
}
|
}
|
||||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: getTimeGenerator()}
|
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: getTimeGenerator()}
|
||||||
|
|
||||||
h := textproto.MIMEHeader(mm.Header)
|
h := textproto.MIMEHeader(mm.Header)
|
||||||
mmBodyData, err := ioutil.ReadAll(mm.Body)
|
mmBodyData, err := ioutil.ReadAll(mm.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, errors.Wrap(err, "gopenpgp: error in reading message body data")
|
||||||
}
|
}
|
||||||
|
|
||||||
printAccepter := gomime.NewMIMEPrinter()
|
printAccepter := gomime.NewMIMEPrinter()
|
||||||
|
|
|
||||||
|
|
@ -119,16 +119,16 @@ func passwordEncrypt(message *PlainMessage, password []byte) ([]byte, error) {
|
||||||
|
|
||||||
encryptWriter, err := openpgp.SymmetricallyEncrypt(&outBuf, password, hints, config)
|
encryptWriter, err := openpgp.SymmetricallyEncrypt(&outBuf, password, hints, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in encrypting message symmetrically")
|
||||||
}
|
}
|
||||||
_, err = encryptWriter.Write(message.GetBinary())
|
_, err = encryptWriter.Write(message.GetBinary())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in writing data to message")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = encryptWriter.Close()
|
err = encryptWriter.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in closing writer")
|
||||||
}
|
}
|
||||||
|
|
||||||
return outBuf.Bytes(), nil
|
return outBuf.Bytes(), nil
|
||||||
|
|
@ -151,13 +151,13 @@ func passwordDecrypt(encryptedIO io.Reader, password []byte) (*PlainMessage, err
|
||||||
var emptyKeyRing openpgp.EntityList
|
var emptyKeyRing openpgp.EntityList
|
||||||
md, err := openpgp.ReadMessage(encryptedIO, emptyKeyRing, prompt, config)
|
md, err := openpgp.ReadMessage(encryptedIO, emptyKeyRing, prompt, config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in reading password protected message")
|
||||||
}
|
}
|
||||||
|
|
||||||
messageBuf := bytes.NewBuffer(nil)
|
messageBuf := bytes.NewBuffer(nil)
|
||||||
_, err = io.Copy(messageBuf, md.UnverifiedBody)
|
_, err = io.Copy(messageBuf, md.UnverifiedBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in reading password protected message body")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PlainMessage{
|
return &PlainMessage{
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ func RandomToken(size int) ([]byte, error) {
|
||||||
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
||||||
symKey := make([]byte, size)
|
symKey := make([]byte, size)
|
||||||
if _, err := io.ReadFull(config.Random(), symKey); err != nil {
|
if _, err := io.ReadFull(config.Random(), symKey); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in generating random token")
|
||||||
}
|
}
|
||||||
return symKey, nil
|
return symKey, nil
|
||||||
}
|
}
|
||||||
|
|
@ -152,12 +152,12 @@ func (sk *SessionKey) Encrypt(message *PlainMessage) ([]byte, error) {
|
||||||
|
|
||||||
_, err = encryptWriter.Write(message.GetBinary())
|
_, err = encryptWriter.Write(message.GetBinary())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in writing message")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = encryptWriter.Close()
|
err = encryptWriter.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in closing message")
|
||||||
}
|
}
|
||||||
|
|
||||||
return encBuf.Bytes(), nil
|
return encBuf.Bytes(), nil
|
||||||
|
|
@ -213,7 +213,7 @@ func (sk *SessionKey) Decrypt(dataPacket []byte) (*PlainMessage, error) {
|
||||||
messageBuf := new(bytes.Buffer)
|
messageBuf := new(bytes.Buffer)
|
||||||
_, err = messageBuf.ReadFrom(md.UnverifiedBody)
|
_, err = messageBuf.ReadFrom(md.UnverifiedBody)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: error in reading message body")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &PlainMessage{
|
return &PlainMessage{
|
||||||
|
|
@ -221,7 +221,7 @@ func (sk *SessionKey) Decrypt(dataPacket []byte) (*PlainMessage, error) {
|
||||||
TextType: !md.LiteralData.IsBinary,
|
TextType: !md.LiteralData.IsBinary,
|
||||||
Filename: md.LiteralData.FileName,
|
Filename: md.LiteralData.FileName,
|
||||||
Time: md.LiteralData.Time,
|
Time: md.LiteralData.Time,
|
||||||
}, err
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sk *SessionKey) checkSize() error {
|
func (sk *SessionKey) checkSize() error {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package crypto
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto"
|
"crypto"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
|
@ -43,8 +44,8 @@ func (e SignatureVerificationError) Error() string {
|
||||||
// SignatureFailed.
|
// SignatureFailed.
|
||||||
func newSignatureFailed() SignatureVerificationError {
|
func newSignatureFailed() SignatureVerificationError {
|
||||||
return SignatureVerificationError{
|
return SignatureVerificationError{
|
||||||
constants.SIGNATURE_FAILED,
|
Status: constants.SIGNATURE_FAILED,
|
||||||
"Invalid signature",
|
Message: "Invalid signature",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -52,8 +53,8 @@ func newSignatureFailed() SignatureVerificationError {
|
||||||
// SignatureFailed, with a message describing the signature as insecure.
|
// SignatureFailed, with a message describing the signature as insecure.
|
||||||
func newSignatureInsecure() SignatureVerificationError {
|
func newSignatureInsecure() SignatureVerificationError {
|
||||||
return SignatureVerificationError{
|
return SignatureVerificationError{
|
||||||
constants.SIGNATURE_FAILED,
|
Status: constants.SIGNATURE_FAILED,
|
||||||
"Insecure signature",
|
Message: "Insecure signature",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,8 +62,8 @@ func newSignatureInsecure() SignatureVerificationError {
|
||||||
// SignatureNotSigned.
|
// SignatureNotSigned.
|
||||||
func newSignatureNotSigned() SignatureVerificationError {
|
func newSignatureNotSigned() SignatureVerificationError {
|
||||||
return SignatureVerificationError{
|
return SignatureVerificationError{
|
||||||
constants.SIGNATURE_NOT_SIGNED,
|
Status: constants.SIGNATURE_NOT_SIGNED,
|
||||||
"Missing signature",
|
Message: "Missing signature",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,15 +71,15 @@ func newSignatureNotSigned() SignatureVerificationError {
|
||||||
// SignatureNoVerifier.
|
// SignatureNoVerifier.
|
||||||
func newSignatureNoVerifier() SignatureVerificationError {
|
func newSignatureNoVerifier() SignatureVerificationError {
|
||||||
return SignatureVerificationError{
|
return SignatureVerificationError{
|
||||||
constants.SIGNATURE_NO_VERIFIER,
|
Status: constants.SIGNATURE_NO_VERIFIER,
|
||||||
"No matching signature",
|
Message: "No matching signature",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// processSignatureExpiration handles signature time verification manually, so
|
// processSignatureExpiration handles signature time verification manually, so
|
||||||
// we can add a margin to the creationTime check.
|
// we can add a margin to the creationTime check.
|
||||||
func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
|
func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
|
||||||
if md.SignatureError != pgpErrors.ErrSignatureExpired {
|
if !errors.Is(md.SignatureError, pgpErrors.ErrSignatureExpired) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if verifyTime == 0 {
|
if verifyTime == 0 {
|
||||||
|
|
@ -131,7 +132,7 @@ func verifySignature(pubKeyEntries openpgp.EntityList, origText io.Reader, signa
|
||||||
|
|
||||||
signer, err := openpgp.CheckDetachedSignatureAndHash(pubKeyEntries, origText, signatureReader, allowedHashes, config)
|
signer, err := openpgp.CheckDetachedSignatureAndHash(pubKeyEntries, origText, signatureReader, allowedHashes, config)
|
||||||
|
|
||||||
if err == pgpErrors.ErrSignatureExpired && signer != nil && verifyTime > 0 {
|
if errors.Is(err, pgpErrors.ErrSignatureExpired) && signer != nil && verifyTime > 0 {
|
||||||
// if verifyTime = 0: time check disabled, everything is okay
|
// if verifyTime = 0: time check disabled, everything is okay
|
||||||
// Maybe the creation time offset pushed it over the edge
|
// Maybe the creation time offset pushed it over the edge
|
||||||
// Retry with the actual verification time
|
// Retry with the actual verification time
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"net/textproto"
|
"net/textproto"
|
||||||
|
|
||||||
gomime "github.com/ProtonMail/go-mime"
|
gomime "github.com/ProtonMail/go-mime"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
)
|
)
|
||||||
|
|
@ -58,7 +58,7 @@ func (sc *SignatureCollector) Accept(
|
||||||
sc.verified = newSignatureNotSigned()
|
sc.verified = newSignatureNotSigned()
|
||||||
// Invalid multipart/signed format just pass along
|
// Invalid multipart/signed format just pass along
|
||||||
if _, err = ioutil.ReadAll(rawBody); err != nil {
|
if _, err = ioutil.ReadAll(rawBody); err != nil {
|
||||||
return err
|
return errors.Wrap(err, "gopenpgp: error in reading raw message body")
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, p := range multiparts {
|
for i, p := range multiparts {
|
||||||
|
|
@ -72,12 +72,12 @@ func (sc *SignatureCollector) Accept(
|
||||||
// actual multipart/signed format
|
// actual multipart/signed format
|
||||||
err = sc.target.Accept(multiparts[0], multipartHeaders[0], hasPlainChild, true, true)
|
err = sc.target.Accept(multiparts[0], multipartHeaders[0], hasPlainChild, true, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "gopenpgp: error in parsing body")
|
||||||
}
|
}
|
||||||
|
|
||||||
partData, err := ioutil.ReadAll(multiparts[1])
|
partData, err := ioutil.ReadAll(multiparts[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "gopenpgp: error in ready part data")
|
||||||
}
|
}
|
||||||
|
|
||||||
decodedPart := gomime.DecodeContentEncoding(
|
decodedPart := gomime.DecodeContentEncoding(
|
||||||
|
|
@ -86,12 +86,12 @@ func (sc *SignatureCollector) Accept(
|
||||||
|
|
||||||
buffer, err := ioutil.ReadAll(decodedPart)
|
buffer, err := ioutil.ReadAll(decodedPart)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "gopenpgp: error in reading decoded data")
|
||||||
}
|
}
|
||||||
mediaType, _, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
mediaType, _, _ := mime.ParseMediaType(header.Get("Content-Type"))
|
||||||
buffer, err = gomime.DecodeCharset(buffer, mediaType, params)
|
buffer, err = gomime.DecodeCharset(buffer, mediaType, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "gopenpgp: error in decoding charset")
|
||||||
}
|
}
|
||||||
sc.signature = string(buffer)
|
sc.signature = string(buffer)
|
||||||
str, _ := ioutil.ReadAll(rawBody)
|
str, _ := ioutil.ReadAll(rawBody)
|
||||||
|
|
@ -107,7 +107,8 @@ func (sc *SignatureCollector) Accept(
|
||||||
} else {
|
} else {
|
||||||
sc.verified = newSignatureNoVerifier()
|
sc.verified = newSignatureNoVerifier()
|
||||||
}
|
}
|
||||||
return err
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSignature collected by Accept.
|
// GetSignature collected by Accept.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"regexp"
|
"regexp"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
|
@ -44,7 +45,8 @@ func TestVerifyTextDetachedSigWrong(t *testing.T) {
|
||||||
|
|
||||||
assert.EqualError(t, verificationError, "Signature Verification Error: Invalid signature")
|
assert.EqualError(t, verificationError, "Signature Verification Error: Invalid signature")
|
||||||
|
|
||||||
err, _ := verificationError.(SignatureVerificationError)
|
err := &SignatureVerificationError{}
|
||||||
|
_ = errors.As(verificationError, err)
|
||||||
assert.Exactly(t, constants.SIGNATURE_FAILED, err.Status)
|
assert.Exactly(t, constants.SIGNATURE_FAILED, err.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package helper
|
||||||
import (
|
import (
|
||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
"github.com/ProtonMail/gopenpgp/v2/internal"
|
"github.com/ProtonMail/gopenpgp/v2/internal"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SignCleartextMessageArmored signs text given a private key and its
|
// SignCleartextMessageArmored signs text given a private key and its
|
||||||
|
|
@ -11,18 +12,18 @@ import (
|
||||||
func SignCleartextMessageArmored(privateKey string, passphrase []byte, text string) (string, error) {
|
func SignCleartextMessageArmored(privateKey string, passphrase []byte, text string) (string, error) {
|
||||||
signingKey, err := crypto.NewKeyFromArmored(privateKey)
|
signingKey, err := crypto.NewKeyFromArmored(privateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: error in creating key object")
|
||||||
}
|
}
|
||||||
|
|
||||||
unlockedKey, err := signingKey.Unlock(passphrase)
|
unlockedKey, err := signingKey.Unlock(passphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: error in unlocking key")
|
||||||
}
|
}
|
||||||
defer unlockedKey.ClearPrivateParams()
|
defer unlockedKey.ClearPrivateParams()
|
||||||
|
|
||||||
keyRing, err := crypto.NewKeyRing(unlockedKey)
|
keyRing, err := crypto.NewKeyRing(unlockedKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: error in creating keyring")
|
||||||
}
|
}
|
||||||
|
|
||||||
return SignCleartextMessage(keyRing, text)
|
return SignCleartextMessage(keyRing, text)
|
||||||
|
|
@ -34,12 +35,12 @@ func SignCleartextMessageArmored(privateKey string, passphrase []byte, text stri
|
||||||
func VerifyCleartextMessageArmored(publicKey, armored string, verifyTime int64) (string, error) {
|
func VerifyCleartextMessageArmored(publicKey, armored string, verifyTime int64) (string, error) {
|
||||||
signingKey, err := crypto.NewKeyFromArmored(publicKey)
|
signingKey, err := crypto.NewKeyFromArmored(publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: error in creating key object")
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyKeyRing, err := crypto.NewKeyRing(signingKey)
|
verifyKeyRing, err := crypto.NewKeyRing(signingKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: error in creating key ring")
|
||||||
}
|
}
|
||||||
|
|
||||||
return VerifyCleartextMessage(verifyKeyRing, armored, verifyTime)
|
return VerifyCleartextMessage(verifyKeyRing, armored, verifyTime)
|
||||||
|
|
@ -53,7 +54,7 @@ func SignCleartextMessage(keyRing *crypto.KeyRing, text string) (string, error)
|
||||||
|
|
||||||
signature, err := keyRing.SignDetached(message)
|
signature, err := keyRing.SignDetached(message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: error in signing cleartext message")
|
||||||
}
|
}
|
||||||
|
|
||||||
return crypto.NewClearTextMessage(message.GetBinary(), signature.GetBinary()).GetArmored()
|
return crypto.NewClearTextMessage(message.GetBinary(), signature.GetBinary()).GetArmored()
|
||||||
|
|
@ -65,14 +66,14 @@ func SignCleartextMessage(keyRing *crypto.KeyRing, text string) (string, error)
|
||||||
func VerifyCleartextMessage(keyRing *crypto.KeyRing, armored string, verifyTime int64) (string, error) {
|
func VerifyCleartextMessage(keyRing *crypto.KeyRing, armored string, verifyTime int64) (string, error) {
|
||||||
clearTextMessage, err := crypto.NewClearTextMessageFromArmored(armored)
|
clearTextMessage, err := crypto.NewClearTextMessageFromArmored(armored)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopengpp: unable to unarmor cleartext message")
|
||||||
}
|
}
|
||||||
|
|
||||||
message := crypto.NewPlainMessageFromString(clearTextMessage.GetString())
|
message := crypto.NewPlainMessageFromString(clearTextMessage.GetString())
|
||||||
signature := crypto.NewPGPSignature(clearTextMessage.GetBinarySignature())
|
signature := crypto.NewPGPSignature(clearTextMessage.GetBinarySignature())
|
||||||
err = keyRing.VerifyDetached(message, signature, verifyTime)
|
err = keyRing.VerifyDetached(message, signature, verifyTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopengpp: unable to verify cleartext message")
|
||||||
}
|
}
|
||||||
|
|
||||||
return message.GetString(), nil
|
return message.GetString(), nil
|
||||||
|
|
|
||||||
122
helper/helper.go
122
helper/helper.go
|
|
@ -2,9 +2,8 @@
|
||||||
package helper
|
package helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
|
|
||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EncryptMessageWithPassword encrypts a string with a passphrase using AES256.
|
// EncryptMessageWithPassword encrypts a string with a passphrase using AES256.
|
||||||
|
|
@ -14,11 +13,11 @@ func EncryptMessageWithPassword(password []byte, plaintext string) (ciphertext s
|
||||||
var message = crypto.NewPlainMessageFromString(plaintext)
|
var message = crypto.NewPlainMessageFromString(plaintext)
|
||||||
|
|
||||||
if pgpMessage, err = crypto.EncryptMessageWithPassword(message, password); err != nil {
|
if pgpMessage, err = crypto.EncryptMessageWithPassword(message, password); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to encrypt message with password")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ciphertext, err = pgpMessage.GetArmored(); err != nil {
|
if ciphertext, err = pgpMessage.GetArmored(); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to armor ciphertext")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ciphertext, nil
|
return ciphertext, nil
|
||||||
|
|
@ -31,11 +30,11 @@ func DecryptMessageWithPassword(password []byte, ciphertext string) (plaintext s
|
||||||
var pgpMessage *crypto.PGPMessage
|
var pgpMessage *crypto.PGPMessage
|
||||||
|
|
||||||
if pgpMessage, err = crypto.NewPGPMessageFromArmored(ciphertext); err != nil {
|
if pgpMessage, err = crypto.NewPGPMessageFromArmored(ciphertext); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to unarmor ciphertext")
|
||||||
}
|
}
|
||||||
|
|
||||||
if message, err = crypto.DecryptMessageWithPassword(pgpMessage, password); err != nil {
|
if message, err = crypto.DecryptMessageWithPassword(pgpMessage, password); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to decrypt message with password")
|
||||||
}
|
}
|
||||||
|
|
||||||
return message.GetString(), nil
|
return message.GetString(), nil
|
||||||
|
|
@ -63,24 +62,24 @@ func EncryptSignMessageArmored(
|
||||||
}
|
}
|
||||||
|
|
||||||
if privateKeyObj, err = crypto.NewKeyFromArmored(privateKey); err != nil {
|
if privateKeyObj, err = crypto.NewKeyFromArmored(privateKey); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to read key")
|
||||||
}
|
}
|
||||||
|
|
||||||
if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil {
|
if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to unlock key")
|
||||||
}
|
}
|
||||||
defer unlockedKeyObj.ClearPrivateParams()
|
defer unlockedKeyObj.ClearPrivateParams()
|
||||||
|
|
||||||
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
|
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to create new keyring")
|
||||||
}
|
}
|
||||||
|
|
||||||
if pgpMessage, err = publicKeyRing.Encrypt(message, privateKeyRing); err != nil {
|
if pgpMessage, err = publicKeyRing.Encrypt(message, privateKeyRing); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to encrypt message")
|
||||||
}
|
}
|
||||||
|
|
||||||
if ciphertext, err = pgpMessage.GetArmored(); err != nil {
|
if ciphertext, err = pgpMessage.GetArmored(); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to armor ciphertext")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ciphertext, nil
|
return ciphertext, nil
|
||||||
|
|
@ -116,24 +115,24 @@ func DecryptVerifyMessageArmored(
|
||||||
}
|
}
|
||||||
|
|
||||||
if privateKeyObj, err = crypto.NewKeyFromArmored(privateKey); err != nil {
|
if privateKeyObj, err = crypto.NewKeyFromArmored(privateKey); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to unarmor private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil {
|
if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to unlock private key")
|
||||||
}
|
}
|
||||||
defer unlockedKeyObj.ClearPrivateParams()
|
defer unlockedKeyObj.ClearPrivateParams()
|
||||||
|
|
||||||
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
|
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to create new keyring")
|
||||||
}
|
}
|
||||||
|
|
||||||
if pgpMessage, err = crypto.NewPGPMessageFromArmored(ciphertext); err != nil {
|
if pgpMessage, err = crypto.NewPGPMessageFromArmored(ciphertext); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to unarmor ciphertext")
|
||||||
}
|
}
|
||||||
|
|
||||||
if message, err = privateKeyRing.Decrypt(pgpMessage, publicKeyRing, crypto.GetUnixTime()); err != nil {
|
if message, err = privateKeyRing.Decrypt(pgpMessage, publicKeyRing, crypto.GetUnixTime()); err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to decrypt message")
|
||||||
}
|
}
|
||||||
|
|
||||||
return message.GetString(), nil
|
return message.GetString(), nil
|
||||||
|
|
@ -191,31 +190,31 @@ func encryptSignArmoredDetached(
|
||||||
publicKey, privateKey string,
|
publicKey, privateKey string,
|
||||||
passphrase, plainData []byte,
|
passphrase, plainData []byte,
|
||||||
) (ciphertext, encryptedSignature string, err error) {
|
) (ciphertext, encryptedSignature string, err error) {
|
||||||
var message *crypto.PlainMessage = crypto.NewPlainMessage(plainData)
|
var message = crypto.NewPlainMessage(plainData)
|
||||||
|
|
||||||
// We generate the session key
|
// We generate the session key
|
||||||
sessionKey, err := crypto.GenerateSessionKey()
|
sessionKey, err := crypto.GenerateSessionKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", errors.Wrap(err, "gopenpgp: unable to generate session key")
|
||||||
}
|
}
|
||||||
|
|
||||||
// We encrypt the message with the session key
|
// We encrypt the message with the session key
|
||||||
messageDataPacket, err := sessionKey.Encrypt(message)
|
messageDataPacket, err := sessionKey.Encrypt(message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", errors.Wrap(err, "gopenpgp: unable to encrypt message")
|
||||||
}
|
}
|
||||||
|
|
||||||
// We sign the message
|
// We sign the message
|
||||||
detachedSignature, err := signDetached(privateKey, passphrase, message)
|
detachedSignature, err := signDetached(privateKey, passphrase, message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", errors.Wrap(err, "gopenpgp: unable to sign the message")
|
||||||
}
|
}
|
||||||
|
|
||||||
// We encrypt the signature with the session key
|
// We encrypt the signature with the session key
|
||||||
signaturePlaintext := crypto.NewPlainMessage(detachedSignature.GetBinary())
|
signaturePlaintext := crypto.NewPlainMessage(detachedSignature.GetBinary())
|
||||||
signatureDataPacket, err := sessionKey.Encrypt(signaturePlaintext)
|
signatureDataPacket, err := sessionKey.Encrypt(signaturePlaintext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", errors.Wrap(err, "gopenpgp: unable to encrypt signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
// We encrypt the session key
|
// We encrypt the session key
|
||||||
|
|
@ -227,11 +226,11 @@ func encryptSignArmoredDetached(
|
||||||
// We join the key packets and datapackets and armor the message
|
// We join the key packets and datapackets and armor the message
|
||||||
ciphertext, err = crypto.NewPGPSplitMessage(keyPacket, messageDataPacket).GetArmored()
|
ciphertext, err = crypto.NewPGPSplitMessage(keyPacket, messageDataPacket).GetArmored()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", errors.Wrap(err, "gopenpgp: unable to armor message")
|
||||||
}
|
}
|
||||||
encryptedSignature, err = crypto.NewPGPSplitMessage(keyPacket, signatureDataPacket).GetArmored()
|
encryptedSignature, err = crypto.NewPGPSplitMessage(keyPacket, signatureDataPacket).GetArmored()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", errors.Wrap(err, "gopenpgp: unable to armor signature")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ciphertext, encryptedSignature, nil
|
return ciphertext, encryptedSignature, nil
|
||||||
|
|
@ -323,45 +322,44 @@ func DecryptSessionKey(
|
||||||
passphrase, encryptedSessionKey []byte,
|
passphrase, encryptedSessionKey []byte,
|
||||||
) (sessionKey *crypto.SessionKey, err error) {
|
) (sessionKey *crypto.SessionKey, err error) {
|
||||||
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
|
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to read armored key")
|
||||||
}
|
}
|
||||||
|
|
||||||
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
|
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to unlock private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
defer privateKeyUnlocked.ClearPrivateParams()
|
defer privateKeyUnlocked.ClearPrivateParams()
|
||||||
|
|
||||||
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
|
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to create new keyring")
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionKey, err = privateKeyRing.DecryptSessionKey(encryptedSessionKey)
|
sessionKey, err = privateKeyRing.DecryptSessionKey(encryptedSessionKey)
|
||||||
return
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt session key")
|
||||||
|
}
|
||||||
|
|
||||||
|
return sessionKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func encryptMessageArmored(key string, message *crypto.PlainMessage) (string, error) {
|
func encryptMessageArmored(key string, message *crypto.PlainMessage) (string, error) {
|
||||||
publicKeyRing, err := createPublicKeyRing(key)
|
publicKeyRing, err := createPublicKeyRing(key)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
pgpMessage, err := publicKeyRing.Encrypt(message, nil)
|
pgpMessage, err := publicKeyRing.Encrypt(message, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to encrypt message")
|
||||||
}
|
}
|
||||||
|
|
||||||
ciphertext, err := pgpMessage.GetArmored()
|
ciphertext, err := pgpMessage.GetArmored()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to armor message")
|
||||||
}
|
}
|
||||||
|
|
||||||
return ciphertext, nil
|
return ciphertext, nil
|
||||||
|
|
@ -369,35 +367,30 @@ func encryptMessageArmored(key string, message *crypto.PlainMessage) (string, er
|
||||||
|
|
||||||
func decryptMessageArmored(privateKey string, passphrase []byte, ciphertext string) (*crypto.PlainMessage, error) {
|
func decryptMessageArmored(privateKey string, passphrase []byte, ciphertext string) (*crypto.PlainMessage, error) {
|
||||||
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
|
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to parse private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
|
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to unlock private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
defer privateKeyUnlocked.ClearPrivateParams()
|
defer privateKeyUnlocked.ClearPrivateParams()
|
||||||
|
|
||||||
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
|
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to create new keyring")
|
||||||
}
|
}
|
||||||
|
|
||||||
pgpMessage, err := crypto.NewPGPMessageFromArmored(ciphertext)
|
pgpMessage, err := crypto.NewPGPMessageFromArmored(ciphertext)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to unarmor ciphertext")
|
||||||
}
|
}
|
||||||
|
|
||||||
message, err := privateKeyRing.Decrypt(pgpMessage, nil, 0)
|
message, err := privateKeyRing.Decrypt(pgpMessage, nil, 0)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt message")
|
||||||
}
|
}
|
||||||
|
|
||||||
return message, nil
|
return message, nil
|
||||||
|
|
@ -405,29 +398,25 @@ func decryptMessageArmored(privateKey string, passphrase []byte, ciphertext stri
|
||||||
|
|
||||||
func signDetached(privateKey string, passphrase []byte, message *crypto.PlainMessage) (detachedSignature *crypto.PGPSignature, err error) {
|
func signDetached(privateKey string, passphrase []byte, message *crypto.PlainMessage) (detachedSignature *crypto.PGPSignature, err error) {
|
||||||
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
|
privateKeyObj, err := crypto.NewKeyFromArmored(privateKey)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to parse private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
|
privateKeyUnlocked, err := privateKeyObj.Unlock(passphrase)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to unlock key")
|
||||||
}
|
}
|
||||||
|
|
||||||
defer privateKeyUnlocked.ClearPrivateParams()
|
defer privateKeyUnlocked.ClearPrivateParams()
|
||||||
|
|
||||||
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
|
privateKeyRing, err := crypto.NewKeyRing(privateKeyUnlocked)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to create new keyring")
|
||||||
}
|
}
|
||||||
|
|
||||||
detachedSignature, err = privateKeyRing.SignDetached(message)
|
detachedSignature, err = privateKeyRing.SignDetached(message)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to sign message")
|
||||||
}
|
}
|
||||||
|
|
||||||
return detachedSignature, nil
|
return detachedSignature, nil
|
||||||
|
|
@ -438,7 +427,7 @@ func verifyDetachedArmored(publicKey string, message *crypto.PlainMessage, armor
|
||||||
|
|
||||||
// We unarmor the signature
|
// We unarmor the signature
|
||||||
if detachedSignature, err = crypto.NewPGPSignatureFromArmored(armoredSignature); err != nil {
|
if detachedSignature, err = crypto.NewPGPSignatureFromArmored(armoredSignature); err != nil {
|
||||||
return false, err
|
return false, errors.Wrap(err, "gopenpgp: unable to unarmor signature")
|
||||||
}
|
}
|
||||||
// we verify the signature
|
// we verify the signature
|
||||||
return verifyDetached(publicKey, message, detachedSignature)
|
return verifyDetached(publicKey, message, detachedSignature)
|
||||||
|
|
@ -471,40 +460,41 @@ func decryptAttachment(
|
||||||
|
|
||||||
// prepare the private key for decryption
|
// prepare the private key for decryption
|
||||||
if privateKeyObj, err = crypto.NewKeyFromArmored(privateKey); err != nil {
|
if privateKeyObj, err = crypto.NewKeyFromArmored(privateKey); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to parse private key")
|
||||||
}
|
}
|
||||||
if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil {
|
if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to unlock private key")
|
||||||
}
|
}
|
||||||
defer unlockedKeyObj.ClearPrivateParams()
|
defer unlockedKeyObj.ClearPrivateParams()
|
||||||
|
|
||||||
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
|
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to create new keyring")
|
||||||
}
|
}
|
||||||
|
|
||||||
if message, err = privateKeyRing.DecryptAttachment(packets); err != nil {
|
if message, err = privateKeyRing.DecryptAttachment(packets); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt attachment")
|
||||||
}
|
}
|
||||||
|
|
||||||
return message, nil
|
return message, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createPublicKeyRing(
|
func createPublicKeyRing(publicKey string) (*crypto.KeyRing, error) {
|
||||||
publicKey string,
|
|
||||||
) (publicKeyRing *crypto.KeyRing, err error) {
|
|
||||||
publicKeyObj, err := crypto.NewKeyFromArmored(publicKey)
|
publicKeyObj, err := crypto.NewKeyFromArmored(publicKey)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to parse public key")
|
||||||
}
|
}
|
||||||
|
|
||||||
if publicKeyObj.IsPrivate() {
|
if publicKeyObj.IsPrivate() {
|
||||||
publicKeyObj, err = publicKeyObj.ToPublic()
|
publicKeyObj, err = publicKeyObj.ToPublic()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to extract public key from private key")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
publicKeyRing, err = crypto.NewKeyRing(publicKeyObj)
|
publicKeyRing, err := crypto.NewKeyRing(publicKeyObj)
|
||||||
return
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "gopenpgp: unable to create new keyring")
|
||||||
|
}
|
||||||
|
|
||||||
|
return publicKeyRing, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,8 @@ func TestAESEncryption(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = DecryptMessageWithPassword([]byte("Wrong passphrase"), ciphertext)
|
_, err = DecryptMessageWithPassword([]byte("Wrong passphrase"), ciphertext)
|
||||||
assert.EqualError(t, err, "gopenpgp: wrong password in symmetric decryption")
|
assert.EqualError(t, err, "gopenpgp: unable to decrypt message with password: "+
|
||||||
|
"gopenpgp: error in reading password protected message: gopenpgp: wrong password in symmetric decryption")
|
||||||
|
|
||||||
decrypted, err := DecryptMessageWithPassword(passphrase, ciphertext)
|
decrypted, err := DecryptMessageWithPassword(passphrase, ciphertext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -71,7 +72,7 @@ func TestArmoredTextMessageEncryptionVerification(t *testing.T) {
|
||||||
testMailboxPassword, // Password defined in base_test
|
testMailboxPassword, // Password defined in base_test
|
||||||
armored,
|
armored,
|
||||||
)
|
)
|
||||||
assert.EqualError(t, err, "Signature Verification Error: No matching signature")
|
assert.EqualError(t, err, "gopenpgp: unable to decrypt message: Signature Verification Error: No matching signature")
|
||||||
|
|
||||||
decrypted, err := DecryptVerifyMessageArmored(
|
decrypted, err := DecryptVerifyMessageArmored(
|
||||||
readTestFile("keyring_privateKey", false),
|
readTestFile("keyring_privateKey", false),
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// UpdatePrivateKeyPassphrase decrypts the given armored privateKey with oldPassphrase,
|
// UpdatePrivateKeyPassphrase decrypts the given armored privateKey with oldPassphrase,
|
||||||
|
|
@ -12,21 +13,26 @@ func UpdatePrivateKeyPassphrase(
|
||||||
) (string, error) {
|
) (string, error) {
|
||||||
key, err := crypto.NewKeyFromArmored(privateKey)
|
key, err := crypto.NewKeyFromArmored(privateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to parse key")
|
||||||
}
|
}
|
||||||
|
|
||||||
unlocked, err := key.Unlock(oldPassphrase)
|
unlocked, err := key.Unlock(oldPassphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to unlock old key")
|
||||||
}
|
}
|
||||||
defer unlocked.ClearPrivateParams()
|
defer unlocked.ClearPrivateParams()
|
||||||
|
|
||||||
locked, err := unlocked.Lock(newPassphrase)
|
locked, err := unlocked.Lock(newPassphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to lock new key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return locked.Armor()
|
armored, err := locked.Armor()
|
||||||
|
if err != nil {
|
||||||
|
return "", errors.Wrap(err, "gopenpgp: unable to armor new key")
|
||||||
|
}
|
||||||
|
|
||||||
|
return armored, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GenerateKey generates a key of the given keyType ("rsa" or "x25519"), encrypts it, and returns an armored string.
|
// GenerateKey generates a key of the given keyType ("rsa" or "x25519"), encrypts it, and returns an armored string.
|
||||||
|
|
@ -35,13 +41,13 @@ func UpdatePrivateKeyPassphrase(
|
||||||
func GenerateKey(name, email string, passphrase []byte, keyType string, bits int) (string, error) {
|
func GenerateKey(name, email string, passphrase []byte, keyType string, bits int) (string, error) {
|
||||||
key, err := crypto.GenerateKey(name, email, keyType, bits)
|
key, err := crypto.GenerateKey(name, email, keyType, bits)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to generate new key")
|
||||||
}
|
}
|
||||||
defer key.ClearPrivateParams()
|
defer key.ClearPrivateParams()
|
||||||
|
|
||||||
locked, err := key.Lock(passphrase)
|
locked, err := key.Lock(passphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", errors.Wrap(err, "gopenpgp: unable to lock new key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return locked.Armor()
|
return locked.Armor()
|
||||||
|
|
@ -50,7 +56,7 @@ func GenerateKey(name, email string, passphrase []byte, keyType string, bits int
|
||||||
func GetSHA256Fingerprints(publicKey string) ([]string, error) {
|
func GetSHA256Fingerprints(publicKey string) ([]string, error) {
|
||||||
key, err := crypto.NewKeyFromArmored(publicKey)
|
key, err := crypto.NewKeyFromArmored(publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to parse key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return key.GetSHA256Fingerprints(), nil
|
return key.GetSHA256Fingerprints(), nil
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,10 @@ package helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
goerrors "errors"
|
||||||
|
|
||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ExplicitVerifyMessage struct {
|
type ExplicitVerifyMessage struct {
|
||||||
|
|
@ -24,14 +26,15 @@ func DecryptExplicitVerify(
|
||||||
message, err := privateKeyRing.Decrypt(pgpMessage, publicKeyRing, verifyTime)
|
message, err := privateKeyRing.Decrypt(pgpMessage, publicKeyRing, verifyTime)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
castedErr, isType := err.(crypto.SignatureVerificationError)
|
castedErr := &crypto.SignatureVerificationError{}
|
||||||
|
isType := goerrors.As(err, castedErr)
|
||||||
if !isType {
|
if !isType {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt message")
|
||||||
}
|
}
|
||||||
|
|
||||||
explicitVerify = &ExplicitVerifyMessage{
|
explicitVerify = &ExplicitVerifyMessage{
|
||||||
Message: message,
|
Message: message,
|
||||||
SignatureVerificationError: &castedErr,
|
SignatureVerificationError: castedErr,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
explicitVerify = &ExplicitVerifyMessage{
|
explicitVerify = &ExplicitVerifyMessage{
|
||||||
|
|
@ -51,7 +54,7 @@ func DecryptAttachment(keyPacket []byte, dataPacket []byte, keyRing *crypto.KeyR
|
||||||
|
|
||||||
decrypted, err := keyRing.DecryptAttachment(splitMessage)
|
decrypted, err := keyRing.DecryptAttachment(splitMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to decrypt attachment")
|
||||||
}
|
}
|
||||||
return decrypted, nil
|
return decrypted, nil
|
||||||
}
|
}
|
||||||
|
|
@ -64,7 +67,7 @@ func EncryptAttachment(plainData []byte, filename string, keyRing *crypto.KeyRin
|
||||||
plainMessage := crypto.NewPlainMessageFromFile(plainData, filename, uint32(crypto.GetUnixTime()))
|
plainMessage := crypto.NewPlainMessageFromFile(plainData, filename, uint32(crypto.GetUnixTime()))
|
||||||
decrypted, err := keyRing.EncryptAttachment(plainMessage, "")
|
decrypted, err := keyRing.EncryptAttachment(plainMessage, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to encrypt attachment")
|
||||||
}
|
}
|
||||||
return decrypted, nil
|
return decrypted, nil
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +77,7 @@ func EncryptAttachment(plainData []byte, filename string, keyRing *crypto.KeyRin
|
||||||
func GetJsonSHA256Fingerprints(publicKey string) ([]byte, error) {
|
func GetJsonSHA256Fingerprints(publicKey string) ([]byte, error) {
|
||||||
key, err := crypto.NewKeyFromArmored(publicKey)
|
key, err := crypto.NewKeyFromArmored(publicKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to parse key")
|
||||||
}
|
}
|
||||||
|
|
||||||
return json.Marshal(key.GetSHA256Fingerprints())
|
return json.Marshal(key.GetSHA256Fingerprints())
|
||||||
|
|
@ -94,5 +97,9 @@ func EncryptSignArmoredDetachedMobile(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &EncryptSignArmoredDetachedMobileResult{ciphertext, encryptedSignature}, nil
|
|
||||||
|
return &EncryptSignArmoredDetachedMobileResult{
|
||||||
|
Ciphertext: ciphertext,
|
||||||
|
EncryptedSignature: encryptedSignature,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ package helper
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EncryptSignAttachment encrypts an attachment using a detached signature, given a publicKey, a privateKey
|
// EncryptSignAttachment encrypts an attachment using a detached signature, given a publicKey, a privateKey
|
||||||
|
|
@ -13,46 +14,36 @@ import (
|
||||||
func EncryptSignAttachment(
|
func EncryptSignAttachment(
|
||||||
publicKey, privateKey string, passphrase []byte, filename string, plainData []byte,
|
publicKey, privateKey string, passphrase []byte, filename string, plainData []byte,
|
||||||
) (keyPacket, dataPacket, signature []byte, err error) {
|
) (keyPacket, dataPacket, signature []byte, err error) {
|
||||||
var publicKeyObj, privateKeyObj, unlockedKeyObj *crypto.Key
|
var privateKeyObj, unlockedKeyObj *crypto.Key
|
||||||
var publicKeyRing, privateKeyRing *crypto.KeyRing
|
var publicKeyRing, privateKeyRing *crypto.KeyRing
|
||||||
var packets *crypto.PGPSplitMessage
|
var packets *crypto.PGPSplitMessage
|
||||||
var signatureObj *crypto.PGPSignature
|
var signatureObj *crypto.PGPSignature
|
||||||
|
|
||||||
var binMessage = crypto.NewPlainMessageFromFile(plainData, filename, uint32(crypto.GetUnixTime()))
|
var binMessage = crypto.NewPlainMessageFromFile(plainData, filename, uint32(crypto.GetUnixTime()))
|
||||||
|
|
||||||
if publicKeyObj, err = crypto.NewKeyFromArmored(publicKey); err != nil {
|
if publicKeyRing, err = createPublicKeyRing(publicKey); err != nil {
|
||||||
return nil, nil, nil, err
|
|
||||||
}
|
|
||||||
if publicKeyObj.IsPrivate() {
|
|
||||||
publicKeyObj, err = publicKeyObj.ToPublic()
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if publicKeyRing, err = crypto.NewKeyRing(publicKeyObj); err != nil {
|
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if privateKeyObj, err = crypto.NewKeyFromArmored(privateKey); err != nil {
|
if privateKeyObj, err = crypto.NewKeyFromArmored(privateKey); err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, errors.Wrap(err, "gopenpgp: unable to parse private key")
|
||||||
}
|
}
|
||||||
|
|
||||||
if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil {
|
if unlockedKeyObj, err = privateKeyObj.Unlock(passphrase); err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, errors.Wrap(err, "gopenpgp: unable to unlock key")
|
||||||
}
|
}
|
||||||
defer unlockedKeyObj.ClearPrivateParams()
|
defer unlockedKeyObj.ClearPrivateParams()
|
||||||
|
|
||||||
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
|
if privateKeyRing, err = crypto.NewKeyRing(unlockedKeyObj); err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, errors.Wrap(err, "gopenpgp: unable to create private keyring")
|
||||||
}
|
}
|
||||||
|
|
||||||
if packets, err = publicKeyRing.EncryptAttachment(binMessage, ""); err != nil {
|
if packets, err = publicKeyRing.EncryptAttachment(binMessage, ""); err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, errors.Wrap(err, "gopenpgp: unable to encrypt attachment")
|
||||||
}
|
}
|
||||||
|
|
||||||
if signatureObj, err = privateKeyRing.SignDetached(binMessage); err != nil {
|
if signatureObj, err = privateKeyRing.SignDetached(binMessage); err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, errors.Wrap(err, "gopenpgp: unable to sign attachment")
|
||||||
}
|
}
|
||||||
|
|
||||||
return packets.GetBinaryKeyPacket(), packets.GetBinaryDataPacket(), signatureObj.GetBinary(), nil
|
return packets.GetBinaryKeyPacket(), packets.GetBinaryDataPacket(), signatureObj.GetBinary(), nil
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package internal
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/crypto/openpgp/armor"
|
"golang.org/x/crypto/openpgp/armor"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -11,7 +12,7 @@ func Unarmor(input string) (*armor.Block, error) {
|
||||||
io := strings.NewReader(input)
|
io := strings.NewReader(input)
|
||||||
b, err := armor.Decode(io)
|
b, err := armor.Decode(io)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "gopenpgp: unable to armor")
|
||||||
}
|
}
|
||||||
return b, nil
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue