158 lines
3.7 KiB
Go
158 lines
3.7 KiB
Go
package pm
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"io/ioutil"
|
|
|
|
"golang.org/x/crypto/openpgp"
|
|
"golang.org/x/crypto/openpgp/armor"
|
|
"golang.org/x/crypto/openpgp/packet"
|
|
)
|
|
|
|
//EncryptAttachmentBinKey ...
|
|
func (o *OpenPGP) EncryptAttachmentBinKey(plainData []byte, fileName string, publicKey []byte) (*EncryptedSplit, error) {
|
|
|
|
var outBuf bytes.Buffer
|
|
w, err := armor.Encode(&outBuf, pgpMessageType.string(), armorHeader)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
pubKeyReader := bytes.NewReader(publicKey)
|
|
pubKeyEntries, err := openpgp.ReadKeyRing(pubKeyReader)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
hints := &openpgp.FileHints{
|
|
FileName: fileName,
|
|
}
|
|
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
|
|
|
ew, err := openpgp.Encrypt(w, pubKeyEntries, nil, hints, config)
|
|
|
|
_, _ = ew.Write(plainData)
|
|
ew.Close()
|
|
w.Close()
|
|
|
|
splited, err := SeparateKeyAndData(outBuf.String())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
splited.Algo = "aes256"
|
|
return splited, nil
|
|
}
|
|
|
|
//EncryptAttachment ...
|
|
func (o *OpenPGP) EncryptAttachment(plainData []byte, fileName string, publicKey string) (*EncryptedSplit, error) {
|
|
rawPubKey, err := UnArmor(publicKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return o.EncryptAttachmentBinKey(plainData, fileName, rawPubKey)
|
|
}
|
|
|
|
//DecryptAttachmentBinKey ...
|
|
//keyPacket
|
|
//dataPacket
|
|
//privateKeys could be mutiple private keys
|
|
func (o *OpenPGP) DecryptAttachmentBinKey(keyPacket []byte, dataPacket []byte, privateKeys []byte, passphrase string) ([]byte, error) {
|
|
privKeyRaw := bytes.NewReader(privateKeys)
|
|
privKeyEntries, err := openpgp.ReadKeyRing(privKeyRaw)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rawPwd := []byte(passphrase)
|
|
for _, e := range privKeyEntries {
|
|
|
|
if e.PrivateKey != nil && e.PrivateKey.Encrypted {
|
|
e.PrivateKey.Decrypt(rawPwd)
|
|
}
|
|
|
|
for _, sub := range e.Subkeys {
|
|
if sub.PrivateKey != nil && sub.PrivateKey.Encrypted {
|
|
sub.PrivateKey.Decrypt(rawPwd)
|
|
}
|
|
}
|
|
}
|
|
|
|
keyReader := bytes.NewReader(keyPacket)
|
|
dataReader := bytes.NewReader(dataPacket)
|
|
|
|
encryptedReader := io.MultiReader(keyReader, dataReader)
|
|
|
|
md, err := openpgp.ReadMessage(encryptedReader, privKeyEntries, nil, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
decrypted := md.UnverifiedBody
|
|
b, err := ioutil.ReadAll(decrypted)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return b, nil
|
|
}
|
|
|
|
//DecryptAttachment ...
|
|
func (o *OpenPGP) DecryptAttachment(keyPacket []byte, dataPacket []byte, privateKey string, passphrase string) ([]byte, error) {
|
|
rawPrivKey, err := UnArmor(privateKey)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return o.DecryptAttachmentBinKey(keyPacket, dataPacket, rawPrivKey, passphrase)
|
|
}
|
|
|
|
//EncryptAttachmentWithPassword ...
|
|
func (o *OpenPGP) EncryptAttachmentWithPassword(plainData []byte, password string) (string, error) {
|
|
|
|
var outBuf bytes.Buffer
|
|
w, err := armor.Encode(&outBuf, pgpMessageType.string(), armorHeader)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
plaintext, err := openpgp.SymmetricallyEncrypt(w, []byte(password), nil, nil)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
_, err = plaintext.Write(plainData)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
err = plaintext.Close()
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
w.Close()
|
|
|
|
return outBuf.String(), nil
|
|
}
|
|
|
|
//DecryptAttachmentWithPassword ...
|
|
func (o *OpenPGP) DecryptAttachmentWithPassword(keyPacket []byte, dataPacket []byte, password string) ([]byte, error) {
|
|
|
|
encrypted := append(keyPacket, dataPacket...)
|
|
|
|
encryptedReader := bytes.NewReader(encrypted)
|
|
|
|
var prompt = func(keys []openpgp.Key, symmetric bool) ([]byte, error) {
|
|
return []byte(password), nil
|
|
}
|
|
|
|
md, err := openpgp.ReadMessage(encryptedReader, nil, prompt, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
messageBuf := bytes.NewBuffer(nil)
|
|
_, err = io.Copy(messageBuf, md.UnverifiedBody)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return messageBuf.Bytes(), nil
|
|
}
|