Add filename and time properties to message (#85)
* Add filename and time properties to message * Message time defaults to current time
This commit is contained in:
parent
7de8833ff6
commit
a4d89bce32
9 changed files with 134 additions and 51 deletions
17
CHANGELOG.md
17
CHANGELOG.md
|
|
@ -73,6 +73,21 @@ EncryptSignArmoredDetachedMobile(
|
||||||
) (wrappedTuple *EncryptSignArmoredDetachedMobileResult, err error)
|
) (wrappedTuple *EncryptSignArmoredDetachedMobileResult, err error)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
- `NewPlainMessageFromFile` Function to create new `PlainMessage`s with a filename:
|
||||||
|
```go
|
||||||
|
NewPlainMessageFromFile(data []byte, filename string, modTime int) *PlainMessage
|
||||||
|
```
|
||||||
|
|
||||||
|
- `GetFilename` to get the filename from a message:
|
||||||
|
```go
|
||||||
|
(msg *PlainMessage) GetFilename() string
|
||||||
|
```
|
||||||
|
|
||||||
|
- `GetModTime` to get the modification time of a file
|
||||||
|
```go
|
||||||
|
(msg *PlainMessage) GetModTime() uint32
|
||||||
|
```
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Improved key and message armoring testing
|
- Improved key and message armoring testing
|
||||||
- `EncryptSessionKey` now creates encrypted key packets for each valid encryption key in the provided keyring.
|
- `EncryptSessionKey` now creates encrypted key packets for each valid encryption key in the provided keyring.
|
||||||
|
|
@ -80,6 +95,8 @@ EncryptSignArmoredDetachedMobile(
|
||||||
- Use aes256 cipher for password-encrypted messages.
|
- Use aes256 cipher for password-encrypted messages.
|
||||||
- The helpers `EncryptSignMessageArmored`, `DecryptVerifyMessageArmored`, `DecryptVerifyAttachment`, and`DecryptBinaryMessageArmored`
|
- The helpers `EncryptSignMessageArmored`, `DecryptVerifyMessageArmored`, `DecryptVerifyAttachment`, and`DecryptBinaryMessageArmored`
|
||||||
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)
|
||||||
|
- All the Decrypt* functions return the filename, type, and time specified in the encrypted message
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Public key armoring headers
|
- Public key armoring headers
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"runtime"
|
"runtime"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
|
|
@ -52,7 +53,7 @@ func (ap *AttachmentProcessor) Finish() (*PGPSplitMessage, error) {
|
||||||
// newAttachmentProcessor creates an AttachmentProcessor which can be used to encrypt
|
// newAttachmentProcessor creates an AttachmentProcessor which can be used to encrypt
|
||||||
// a file. It takes an estimatedSize and fileName as hints about the file.
|
// a file. It takes an estimatedSize and fileName as hints about the file.
|
||||||
func (keyRing *KeyRing) newAttachmentProcessor(
|
func (keyRing *KeyRing) newAttachmentProcessor(
|
||||||
estimatedSize int, fileName string, garbageCollector int,
|
estimatedSize int, filename string, isBinary bool, modTime uint32, garbageCollector int,
|
||||||
) (*AttachmentProcessor, error) {
|
) (*AttachmentProcessor, error) {
|
||||||
attachmentProc := &AttachmentProcessor{}
|
attachmentProc := &AttachmentProcessor{}
|
||||||
// You could also add these one at a time if needed.
|
// You could also add these one at a time if needed.
|
||||||
|
|
@ -60,7 +61,9 @@ func (keyRing *KeyRing) newAttachmentProcessor(
|
||||||
attachmentProc.garbageCollector = garbageCollector
|
attachmentProc.garbageCollector = garbageCollector
|
||||||
|
|
||||||
hints := &openpgp.FileHints{
|
hints := &openpgp.FileHints{
|
||||||
FileName: fileName,
|
FileName: filename,
|
||||||
|
IsBinary: isBinary,
|
||||||
|
ModTime: time.Unix(int64(modTime), 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
config := &packet.Config{
|
config := &packet.Config{
|
||||||
|
|
@ -93,11 +96,22 @@ func (keyRing *KeyRing) newAttachmentProcessor(
|
||||||
return attachmentProc, nil
|
return attachmentProc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EncryptAttachment encrypts a file given a PlainMessage and a fileName.
|
// EncryptAttachment encrypts a file given a PlainMessage and a filename.
|
||||||
|
// If given a filename it will override the information in the PlainMessage object.
|
||||||
// Returns a PGPSplitMessage containing a session key packet and symmetrically encrypted data.
|
// Returns a PGPSplitMessage containing a session key packet and symmetrically encrypted data.
|
||||||
// Specifically designed for attachments rather than text messages.
|
// Specifically designed for attachments rather than text messages.
|
||||||
func (keyRing *KeyRing) EncryptAttachment(message *PlainMessage, fileName string) (*PGPSplitMessage, error) {
|
func (keyRing *KeyRing) EncryptAttachment(message *PlainMessage, filename string) (*PGPSplitMessage, error) {
|
||||||
ap, err := keyRing.newAttachmentProcessor(len(message.GetBinary()), fileName, -1)
|
if filename == "" {
|
||||||
|
filename = message.filename
|
||||||
|
}
|
||||||
|
|
||||||
|
ap, err := keyRing.newAttachmentProcessor(
|
||||||
|
len(message.GetBinary()),
|
||||||
|
filename,
|
||||||
|
message.IsBinary(),
|
||||||
|
message.GetTime(),
|
||||||
|
-1,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -114,9 +128,9 @@ func (keyRing *KeyRing) EncryptAttachment(message *PlainMessage, fileName string
|
||||||
// file. It is optimized for low-memory environments and collects garbage every
|
// file. It is optimized for low-memory environments and collects garbage every
|
||||||
// megabyte.
|
// megabyte.
|
||||||
func (keyRing *KeyRing) NewLowMemoryAttachmentProcessor(
|
func (keyRing *KeyRing) NewLowMemoryAttachmentProcessor(
|
||||||
estimatedSize int, fileName string,
|
estimatedSize int, filename string,
|
||||||
) (*AttachmentProcessor, error) {
|
) (*AttachmentProcessor, error) {
|
||||||
return keyRing.newAttachmentProcessor(estimatedSize, fileName, 1<<20)
|
return keyRing.newAttachmentProcessor(estimatedSize, filename, true, uint32(GetUnixTime()), 1<<20)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptAttachment takes a PGPSplitMessage, containing a session key packet and symmetrically encrypted data
|
// DecryptAttachment takes a PGPSplitMessage, containing a session key packet and symmetrically encrypted data
|
||||||
|
|
@ -143,5 +157,10 @@ func (keyRing *KeyRing) DecryptAttachment(message *PGPSplitMessage) (*PlainMessa
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewPlainMessage(b), nil
|
return &PlainMessage{
|
||||||
|
Data: b,
|
||||||
|
TextType: !md.LiteralData.IsBinary,
|
||||||
|
filename: md.LiteralData.FileName,
|
||||||
|
time: md.LiteralData.Time,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,9 +42,9 @@ func TestAttachmentSetKey(t *testing.T) {
|
||||||
|
|
||||||
func TestAttachmentEncryptDecrypt(t *testing.T) {
|
func TestAttachmentEncryptDecrypt(t *testing.T) {
|
||||||
var testAttachmentCleartext = "cc,\ndille."
|
var testAttachmentCleartext = "cc,\ndille."
|
||||||
var message = NewPlainMessage([]byte(testAttachmentCleartext))
|
var message = NewPlainMessageFromFile([]byte(testAttachmentCleartext), "test.txt", 1602518992)
|
||||||
|
|
||||||
encSplit, err := keyRingTestPrivate.EncryptAttachment(message, "s.txt")
|
encSplit, err := keyRingTestPrivate.EncryptAttachment(message, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Expected no error while encrypting attachment, got:", err)
|
t.Fatal("Expected no error while encrypting attachment, got:", err)
|
||||||
}
|
}
|
||||||
|
|
@ -59,9 +59,9 @@ func TestAttachmentEncryptDecrypt(t *testing.T) {
|
||||||
|
|
||||||
func TestAttachmentEncrypt(t *testing.T) {
|
func TestAttachmentEncrypt(t *testing.T) {
|
||||||
var testAttachmentCleartext = "cc,\ndille."
|
var testAttachmentCleartext = "cc,\ndille."
|
||||||
var message = NewPlainMessage([]byte(testAttachmentCleartext))
|
var message = NewPlainMessageFromFile([]byte(testAttachmentCleartext), "test.txt", 1602518992)
|
||||||
|
|
||||||
encSplit, err := keyRingTestPrivate.EncryptAttachment(message, "s.txt")
|
encSplit, err := keyRingTestPrivate.EncryptAttachment(message, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Expected no error while encrypting attachment, got:", err)
|
t.Fatal("Expected no error while encrypting attachment, got:", err)
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +78,7 @@ func TestAttachmentEncrypt(t *testing.T) {
|
||||||
|
|
||||||
func TestAttachmentDecrypt(t *testing.T) {
|
func TestAttachmentDecrypt(t *testing.T) {
|
||||||
var testAttachmentCleartext = "cc,\ndille."
|
var testAttachmentCleartext = "cc,\ndille."
|
||||||
var message = NewPlainMessage([]byte(testAttachmentCleartext))
|
var message = NewPlainMessageFromFile([]byte(testAttachmentCleartext), "test.txt", 1602518992)
|
||||||
|
|
||||||
encrypted, err := keyRingTestPrivate.Encrypt(message, nil)
|
encrypted, err := keyRingTestPrivate.Encrypt(message, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"crypto"
|
"crypto"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
"time"
|
||||||
|
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
|
|
@ -15,7 +16,7 @@ import (
|
||||||
// * message : The plaintext input as a PlainMessage.
|
// * message : The plaintext input as a PlainMessage.
|
||||||
// * privateKey : (optional) an unlocked private keyring to include signature in the message.
|
// * privateKey : (optional) an unlocked private keyring to include signature in the message.
|
||||||
func (keyRing *KeyRing) Encrypt(message *PlainMessage, privateKey *KeyRing) (*PGPMessage, error) {
|
func (keyRing *KeyRing) Encrypt(message *PlainMessage, privateKey *KeyRing) (*PGPMessage, error) {
|
||||||
encrypted, err := asymmetricEncrypt(message.GetBinary(), keyRing, privateKey, message.IsBinary())
|
encrypted, err := asymmetricEncrypt(message, keyRing, privateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -33,9 +34,7 @@ func (keyRing *KeyRing) Encrypt(message *PlainMessage, privateKey *KeyRing) (*PG
|
||||||
func (keyRing *KeyRing) Decrypt(
|
func (keyRing *KeyRing) Decrypt(
|
||||||
message *PGPMessage, verifyKey *KeyRing, verifyTime int64,
|
message *PGPMessage, verifyKey *KeyRing, verifyTime int64,
|
||||||
) (*PlainMessage, error) {
|
) (*PlainMessage, error) {
|
||||||
decrypted, err := asymmetricDecrypt(message.NewReader(), keyRing, verifyKey, verifyTime)
|
return asymmetricDecrypt(message.NewReader(), keyRing, verifyKey, verifyTime)
|
||||||
|
|
||||||
return NewPlainMessage(decrypted), err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignDetached generates and returns a PGPSignature for a given PlainMessage.
|
// SignDetached generates and returns a PGPSignature for a given PlainMessage.
|
||||||
|
|
@ -69,7 +68,7 @@ func (keyRing *KeyRing) VerifyDetached(message *PlainMessage, signature *PGPSign
|
||||||
// ------ INTERNAL FUNCTIONS -------
|
// ------ INTERNAL FUNCTIONS -------
|
||||||
|
|
||||||
// Core for encryption+signature functions.
|
// Core for encryption+signature functions.
|
||||||
func asymmetricEncrypt(data []byte, publicKey *KeyRing, privateKey *KeyRing, isBinary bool) ([]byte, error) {
|
func asymmetricEncrypt(plainMessage *PlainMessage, publicKey, privateKey *KeyRing) ([]byte, error) {
|
||||||
var outBuf bytes.Buffer
|
var outBuf bytes.Buffer
|
||||||
var encryptWriter io.WriteCloser
|
var encryptWriter io.WriteCloser
|
||||||
var signEntity *openpgp.Entity
|
var signEntity *openpgp.Entity
|
||||||
|
|
@ -86,11 +85,12 @@ func asymmetricEncrypt(data []byte, publicKey *KeyRing, privateKey *KeyRing, isB
|
||||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: getTimeGenerator()}
|
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: getTimeGenerator()}
|
||||||
|
|
||||||
hints := &openpgp.FileHints{
|
hints := &openpgp.FileHints{
|
||||||
IsBinary: isBinary,
|
IsBinary: plainMessage.IsBinary(),
|
||||||
FileName: "",
|
FileName: plainMessage.GetFilename(),
|
||||||
|
ModTime: time.Unix(int64(plainMessage.GetTime()), 0),
|
||||||
}
|
}
|
||||||
|
|
||||||
if isBinary {
|
if plainMessage.IsBinary() {
|
||||||
encryptWriter, err = openpgp.Encrypt(&outBuf, publicKey.entities, signEntity, hints, config)
|
encryptWriter, err = openpgp.Encrypt(&outBuf, publicKey.entities, signEntity, hints, config)
|
||||||
} else {
|
} else {
|
||||||
encryptWriter, err = openpgp.EncryptText(&outBuf, publicKey.entities, signEntity, hints, config)
|
encryptWriter, err = openpgp.EncryptText(&outBuf, publicKey.entities, signEntity, hints, config)
|
||||||
|
|
@ -99,7 +99,7 @@ func asymmetricEncrypt(data []byte, publicKey *KeyRing, privateKey *KeyRing, isB
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = encryptWriter.Write(data)
|
_, err = encryptWriter.Write(plainMessage.GetBinary())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -115,7 +115,7 @@ func asymmetricEncrypt(data []byte, publicKey *KeyRing, privateKey *KeyRing, isB
|
||||||
// Core for decryption+verification functions.
|
// Core for decryption+verification functions.
|
||||||
func asymmetricDecrypt(
|
func asymmetricDecrypt(
|
||||||
encryptedIO io.Reader, privateKey *KeyRing, verifyKey *KeyRing, verifyTime int64,
|
encryptedIO io.Reader, privateKey *KeyRing, verifyKey *KeyRing, verifyTime int64,
|
||||||
) (plaintext []byte, err error) {
|
) (message *PlainMessage, err error) {
|
||||||
privKeyEntries := privateKey.entities
|
privKeyEntries := privateKey.entities
|
||||||
var additionalEntries openpgp.EntityList
|
var additionalEntries openpgp.EntityList
|
||||||
|
|
||||||
|
|
@ -141,11 +141,13 @@ func asymmetricDecrypt(
|
||||||
|
|
||||||
if verifyKey != nil {
|
if verifyKey != nil {
|
||||||
processSignatureExpiration(messageDetails, verifyTime)
|
processSignatureExpiration(messageDetails, verifyTime)
|
||||||
|
err = verifyDetailsSignature(messageDetails, verifyKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
if verifyKey != nil {
|
return &PlainMessage{
|
||||||
return body, verifyDetailsSignature(messageDetails, verifyKey)
|
Data: body,
|
||||||
}
|
TextType: !messageDetails.LiteralData.IsBinary,
|
||||||
|
filename: messageDetails.LiteralData.FileName,
|
||||||
return body, nil
|
time: messageDetails.LiteralData.Time,
|
||||||
|
}, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,12 @@ import (
|
||||||
type PlainMessage struct {
|
type PlainMessage struct {
|
||||||
// The content of the message
|
// The content of the message
|
||||||
Data []byte
|
Data []byte
|
||||||
// if the content is text or binary
|
// If the content is text or binary
|
||||||
TextType bool
|
TextType bool
|
||||||
|
// The file's latest modification time
|
||||||
|
time uint32
|
||||||
|
// The encrypted message's filename
|
||||||
|
filename string
|
||||||
}
|
}
|
||||||
|
|
||||||
// PGPMessage stores a PGP-encrypted message.
|
// PGPMessage stores a PGP-encrypted message.
|
||||||
|
|
@ -62,6 +66,19 @@ func NewPlainMessage(data []byte) *PlainMessage {
|
||||||
return &PlainMessage{
|
return &PlainMessage{
|
||||||
Data: clone(data),
|
Data: clone(data),
|
||||||
TextType: false,
|
TextType: false,
|
||||||
|
time: uint32(GetUnixTime()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPlainMessageFromFile generates a new binary PlainMessage ready for encryption,
|
||||||
|
// signature, or verification from the unencrypted binary data.
|
||||||
|
// It assigns a filename and a modification time.
|
||||||
|
func NewPlainMessageFromFile(data []byte, filename string, time uint32) *PlainMessage {
|
||||||
|
return &PlainMessage{
|
||||||
|
Data: clone(data),
|
||||||
|
TextType: false,
|
||||||
|
filename: filename,
|
||||||
|
time: time,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,6 +88,7 @@ func NewPlainMessageFromString(text string) *PlainMessage {
|
||||||
return &PlainMessage{
|
return &PlainMessage{
|
||||||
Data: []byte(text),
|
Data: []byte(text),
|
||||||
TextType: true,
|
TextType: true,
|
||||||
|
time: uint32(GetUnixTime()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -201,6 +219,16 @@ func (msg *PlainMessage) IsBinary() bool {
|
||||||
return !msg.TextType
|
return !msg.TextType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFilename returns the file name of the message as a string.
|
||||||
|
func (msg *PlainMessage) GetFilename() string {
|
||||||
|
return msg.filename
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetTime returns the modification time of a file (if provided in the ciphertext).
|
||||||
|
func (msg *PlainMessage) GetTime() uint32 {
|
||||||
|
return msg.time
|
||||||
|
}
|
||||||
|
|
||||||
// GetBinary returns the unarmored binary content of the message as a []byte.
|
// GetBinary returns the unarmored binary content of the message as a []byte.
|
||||||
func (msg *PGPMessage) GetBinary() []byte {
|
func (msg *PGPMessage) GetBinary() []byte {
|
||||||
return msg.Data
|
return msg.Data
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package crypto
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io"
|
"io"
|
||||||
|
"time"
|
||||||
|
|
||||||
"golang.org/x/crypto/openpgp"
|
"golang.org/x/crypto/openpgp"
|
||||||
"golang.org/x/crypto/openpgp/packet"
|
"golang.org/x/crypto/openpgp/packet"
|
||||||
|
|
@ -16,7 +17,7 @@ import (
|
||||||
// * password: A password that will be derived into an encryption key.
|
// * password: A password that will be derived into an encryption key.
|
||||||
// * output : The encrypted data as PGPMessage.
|
// * output : The encrypted data as PGPMessage.
|
||||||
func EncryptMessageWithPassword(message *PlainMessage, password []byte) (*PGPMessage, error) {
|
func EncryptMessageWithPassword(message *PlainMessage, password []byte) (*PGPMessage, error) {
|
||||||
encrypted, err := passwordEncrypt(message.GetBinary(), password, message.IsBinary())
|
encrypted, err := passwordEncrypt(message, password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -29,13 +30,7 @@ func EncryptMessageWithPassword(message *PlainMessage, password []byte) (*PGPMes
|
||||||
// * password: A password that will be derived into an encryption key.
|
// * password: A password that will be derived into an encryption key.
|
||||||
// * output: The decrypted data as PlainMessage.
|
// * output: The decrypted data as PlainMessage.
|
||||||
func DecryptMessageWithPassword(message *PGPMessage, password []byte) (*PlainMessage, error) {
|
func DecryptMessageWithPassword(message *PGPMessage, password []byte) (*PlainMessage, error) {
|
||||||
decrypted, err := passwordDecrypt(message.NewReader(), password)
|
return passwordDecrypt(message.NewReader(), password)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
binMessage := NewPlainMessage(decrypted)
|
|
||||||
return binMessage, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecryptSessionKeyWithPassword decrypts the binary symmetrically encrypted
|
// DecryptSessionKeyWithPassword decrypts the binary symmetrically encrypted
|
||||||
|
|
@ -110,7 +105,7 @@ func EncryptSessionKeyWithPassword(sk *SessionKey, password []byte) ([]byte, err
|
||||||
|
|
||||||
// ----- INTERNAL FUNCTIONS ------
|
// ----- INTERNAL FUNCTIONS ------
|
||||||
|
|
||||||
func passwordEncrypt(message []byte, password []byte, isBinary bool) ([]byte, error) {
|
func passwordEncrypt(message *PlainMessage, password []byte) ([]byte, error) {
|
||||||
var outBuf bytes.Buffer
|
var outBuf bytes.Buffer
|
||||||
|
|
||||||
config := &packet.Config{
|
config := &packet.Config{
|
||||||
|
|
@ -118,13 +113,17 @@ func passwordEncrypt(message []byte, password []byte, isBinary bool) ([]byte, er
|
||||||
Time: getTimeGenerator(),
|
Time: getTimeGenerator(),
|
||||||
}
|
}
|
||||||
|
|
||||||
hints := &openpgp.FileHints{IsBinary: isBinary}
|
hints := &openpgp.FileHints{
|
||||||
|
IsBinary: message.IsBinary(),
|
||||||
|
FileName: message.GetFilename(),
|
||||||
|
ModTime: time.Unix(int64(message.GetTime()), 0),
|
||||||
|
}
|
||||||
|
|
||||||
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, err
|
||||||
}
|
}
|
||||||
_, err = encryptWriter.Write(message)
|
_, err = encryptWriter.Write(message.GetBinary())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -137,7 +136,7 @@ func passwordEncrypt(message []byte, password []byte, isBinary bool) ([]byte, er
|
||||||
return outBuf.Bytes(), nil
|
return outBuf.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func passwordDecrypt(encryptedIO io.Reader, password []byte) ([]byte, error) {
|
func passwordDecrypt(encryptedIO io.Reader, password []byte) (*PlainMessage, error) {
|
||||||
firstTimeCalled := true
|
firstTimeCalled := true
|
||||||
var prompt = func(keys []openpgp.Key, symmetric bool) ([]byte, error) {
|
var prompt = func(keys []openpgp.Key, symmetric bool) ([]byte, error) {
|
||||||
if firstTimeCalled {
|
if firstTimeCalled {
|
||||||
|
|
@ -163,5 +162,10 @@ func passwordDecrypt(encryptedIO io.Reader, password []byte) ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return messageBuf.Bytes(), nil
|
return &PlainMessage{
|
||||||
|
Data: messageBuf.Bytes(),
|
||||||
|
TextType: !md.LiteralData.IsBinary,
|
||||||
|
filename: md.LiteralData.FileName,
|
||||||
|
time: md.LiteralData.Time,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,13 @@ func (sk *SessionKey) Encrypt(message *PlainMessage) ([]byte, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptWriter, err = packet.SerializeLiteral(encryptWriter, message.IsBinary(), "", 0)
|
encryptWriter, err = packet.SerializeLiteral(
|
||||||
|
encryptWriter,
|
||||||
|
message.IsBinary(),
|
||||||
|
message.GetFilename(),
|
||||||
|
message.GetTime(),
|
||||||
|
)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "gopenpgp: unable to serialize")
|
return nil, errors.Wrap(err, "gopenpgp: unable to serialize")
|
||||||
}
|
}
|
||||||
|
|
@ -210,7 +216,12 @@ func (sk *SessionKey) Decrypt(dataPacket []byte) (*PlainMessage, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return NewPlainMessage(messageBuf.Bytes()), nil
|
return &PlainMessage{
|
||||||
|
Data: messageBuf.Bytes(),
|
||||||
|
TextType: !md.LiteralData.IsBinary,
|
||||||
|
filename: md.LiteralData.FileName,
|
||||||
|
time: md.LiteralData.Time,
|
||||||
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sk *SessionKey) checkSize() error {
|
func (sk *SessionKey) checkSize() error {
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,9 @@ func DecryptAttachment(keyPacket []byte, dataPacket []byte, keyRing *crypto.KeyR
|
||||||
// Returns a PGPSplitMessage containing a session key packet and symmetrically
|
// Returns a PGPSplitMessage containing a session key packet and symmetrically
|
||||||
// encrypted data. Specifically designed for attachments rather than text
|
// encrypted data. Specifically designed for attachments rather than text
|
||||||
// messages.
|
// messages.
|
||||||
func EncryptAttachment(plainData []byte, fileName string, keyRing *crypto.KeyRing) (*crypto.PGPSplitMessage, error) {
|
func EncryptAttachment(plainData []byte, filename string, keyRing *crypto.KeyRing) (*crypto.PGPSplitMessage, error) {
|
||||||
plainMessage := crypto.NewPlainMessage(plainData)
|
plainMessage := crypto.NewPlainMessageFromFile(plainData, filename, uint32(crypto.GetUnixTime()))
|
||||||
decrypted, err := keyRing.EncryptAttachment(plainMessage, fileName)
|
decrypted, err := keyRing.EncryptAttachment(plainMessage, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,22 @@
|
||||||
|
|
||||||
package helper
|
package helper
|
||||||
|
|
||||||
import "github.com/ProtonMail/gopenpgp/v2/crypto"
|
import (
|
||||||
|
"github.com/ProtonMail/gopenpgp/v2/crypto"
|
||||||
|
)
|
||||||
|
|
||||||
// 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
|
||||||
// and its passphrase, the filename, and the unencrypted file data.
|
// and its passphrase, the filename, and the unencrypted file data.
|
||||||
// Returns keypacket, dataPacket and unarmored (!) signature separate.
|
// Returns keypacket, dataPacket and unarmored (!) signature separate.
|
||||||
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 publicKeyObj, 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.NewPlainMessage(plainData)
|
var binMessage = crypto.NewPlainMessageFromFile(plainData, filename, uint32(crypto.GetUnixTime()))
|
||||||
|
|
||||||
if publicKeyObj, err = crypto.NewKeyFromArmored(publicKey); err != nil {
|
if publicKeyObj, err = crypto.NewKeyFromArmored(publicKey); err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
|
|
@ -45,7 +47,7 @@ func EncryptSignAttachment(
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if packets, err = publicKeyRing.EncryptAttachment(binMessage, fileName); err != nil {
|
if packets, err = publicKeyRing.EncryptAttachment(binMessage, ""); err != nil {
|
||||||
return nil, nil, nil, err
|
return nil, nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue