Add decryptMime and refactor package structure

This commit is contained in:
Kay Lukas 2018-09-11 11:09:28 +02:00
parent 07b3a2c739
commit 97e70855b8
27 changed files with 516 additions and 486 deletions

133
armor/armor.go Normal file
View file

@ -0,0 +1,133 @@
package armor
import (
"bytes"
"io/ioutil"
"golang.org/x/crypto/openpgp/armor"
"proton/pmcrypto/internal"
"golang.org/x/crypto/openpgp/clearsign"
"errors"
"golang.org/x/crypto/openpgp/packet"
"io"
"proton/pmcrypto/models"
)
// ArmorKey make bytes input key to armor format
func ArmorKey(input []byte) (string, error) {
return ArmorWithType(input, PUBLIC_KEY_HEADER)
}
// ArmorWithType make bytes input to armor format
func ArmorWithType(input []byte, armorType string) (string, error) {
var b bytes.Buffer
w, err := armor.Encode(&b, armorType, internal.ArmorHeaders)
if err != nil {
return "", err
}
_, err = w.Write(input)
if err != nil {
return "", err
}
w.Close()
return b.String(), nil
}
// UnArmor an armored key to bytes key
func UnArmor(input string) ([]byte, error) {
b, err := internal.UnArmor(input)
if err != nil {
return nil, err
}
return ioutil.ReadAll(b.Body)
}
//ReadClearSignedMessage read clear message from a clearsign package
func ReadClearSignedMessage(signedMessage string) (string, error) {
modulusBlock, rest := clearsign.Decode([]byte(signedMessage))
if len(rest) != 0 {
return "", errors.New("pmapi: extra data after modulus")
}
return string(modulusBlock.Bytes), nil
}
//SeparateKeyAndData ...
func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
var err error
encryptedRaw, err := UnArmor(encrypted)
if err != nil {
return nil, err
}
encryptedReader := bytes.NewReader(encryptedRaw)
//kr *KeyRing, r io.Reader) (key *SymmetricKey, symEncryptedData []byte,
packets := packet.NewReader(encryptedReader)
outSplit := &models.EncryptedSplit{}
// Save encrypted key and signature apart
var ek *packet.EncryptedKey
// var decryptErr error
for {
var p packet.Packet
if p, err = packets.Next(); err == io.EOF {
err = nil
break
}
switch p := p.(type) {
case *packet.EncryptedKey:
// We got an encrypted key. Try to decrypt it with each available key
if ek != nil && ek.Key != nil {
break
}
ek = p
break
case *packet.SymmetricallyEncrypted:
var packetContents []byte
if packetContents, err = ioutil.ReadAll(p.Contents); err != nil {
return nil, err
}
encodedLength := encodedLength(len(packetContents) + 1)
var symEncryptedData []byte
symEncryptedData = append(symEncryptedData, byte(210))
symEncryptedData = append(symEncryptedData, encodedLength...)
symEncryptedData = append(symEncryptedData, byte(1))
symEncryptedData = append(symEncryptedData, packetContents...)
outSplit.DataPacket = symEncryptedData
break
}
}
var buf bytes.Buffer
ek.Serialize(&buf)
outSplit.KeyPacket = buf.Bytes()
return outSplit, err
}
//encode length based on 4.2.2. in the RFC
func encodedLength(length int) (b []byte) {
if length < 192 {
b = append(b, byte(length))
} else if length < 8384 {
length = length - 192
b = append(b, 192+byte(length>>8))
b = append(b, byte(length))
} else {
b = append(b, byte(255))
b = append(b, byte(length>>24))
b = append(b, byte(length>>16))
b = append(b, byte(length>>8))
b = append(b, byte(length))
}
return
}