Issue #3: mobile client fallback version

This commit is contained in:
Jakub Lehotsky 2018-11-05 22:55:45 +01:00
parent 0bf075d49d
commit fdd1a727cb
15 changed files with 367 additions and 1321 deletions

View file

@ -13,11 +13,11 @@ import (
"golang.org/x/crypto/openpgp/packet"
)
//EncryptAttachmentBinKey ...
// Encrypt attachment. Takes input data and key data in binary form
func (pm *PmCrypto) EncryptAttachmentBinKey(plainData []byte, fileName string, publicKey []byte) (*models.EncryptedSplit, error) {
var outBuf bytes.Buffer
w, err := armor.Encode(&outBuf, armorUtils.MESSAGE_HEADER, internal.ArmorHeaders)
w, err := armor.Encode(&outBuf, armorUtils.PGP_MESSAGE_HEADER, internal.ArmorHeaders)
if err != nil {
return nil, err
}
@ -42,7 +42,7 @@ func (pm *PmCrypto) EncryptAttachmentBinKey(plainData []byte, fileName string, p
ew.Close()
w.Close()
split, err := armorUtils.SplitArmor(outBuf.String())
split, err := SplitArmor(outBuf.String())
if err != nil {
return nil, err
}
@ -50,7 +50,23 @@ func (pm *PmCrypto) EncryptAttachmentBinKey(plainData []byte, fileName string, p
return split, nil
}
//EncryptAttachment ...
// Helper method. Splits armored pgp session into key and packet data
func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
var err error
encryptedRaw, err := armorUtils.Unarmor(encrypted)
if err != nil {
return nil, err
}
encryptedReader := bytes.NewReader(encryptedRaw)
return SeparateKeyAndData(nil, encryptedReader)
}
// Encrypt attachment. Takes input data in binary form and key in as a string
func (pm *PmCrypto) EncryptAttachment(plainData []byte, fileName string, publicKey string) (*models.EncryptedSplit, error) {
rawPubKey, err := armorUtils.Unarmor(publicKey)
if err != nil {
@ -59,10 +75,7 @@ func (pm *PmCrypto) EncryptAttachment(plainData []byte, fileName string, publicK
return pm.EncryptAttachmentBinKey(plainData, fileName, rawPubKey)
}
//DecryptAttachmentBinKey ...
//keyPacket
//dataPacket
//privateKeys could be mutiple private keys
// Decrypt attachment. Takes input data and key data in binary form. privateKeys can contains more keys. passphrase is used to unlock keys
func (pm *PmCrypto) DecryptAttachmentBinKey(keyPacket []byte, dataPacket []byte, privateKeys []byte, passphrase string) ([]byte, error) {
privKeyRaw := bytes.NewReader(privateKeys)
privKeyEntries, err := openpgp.ReadKeyRing(privKeyRaw)
@ -105,7 +118,7 @@ func (pm *PmCrypto) DecryptAttachmentBinKey(keyPacket []byte, dataPacket []byte,
return b, nil
}
//DecryptAttachment ...
// Decrypt attachment. Takes input data and key data in binary form and key as an armored string. passphrase is used to unlock keys
func (pm *PmCrypto) DecryptAttachment(keyPacket []byte, dataPacket []byte, privateKey string, passphrase string) ([]byte, error) {
rawPrivKey, err := armorUtils.Unarmor(privateKey)
if err != nil {
@ -114,11 +127,11 @@ func (pm *PmCrypto) DecryptAttachment(keyPacket []byte, dataPacket []byte, priva
return pm.DecryptAttachmentBinKey(keyPacket, dataPacket, rawPrivKey, passphrase)
}
//EncryptAttachmentWithPassword ...
//Encrypt attachment. Use symmetrical cipher with key in password input string
func (pm *PmCrypto) EncryptAttachmentWithPassword(plainData []byte, password string) (string, error) {
var outBuf bytes.Buffer
w, err := armor.Encode(&outBuf, armorUtils.MESSAGE_HEADER, internal.ArmorHeaders)
w, err := armor.Encode(&outBuf, armorUtils.PGP_MESSAGE_HEADER, internal.ArmorHeaders)
if err != nil {
return "", err
}
@ -143,7 +156,7 @@ func (pm *PmCrypto) EncryptAttachmentWithPassword(plainData []byte, password str
return outBuf.String(), nil
}
//DecryptAttachmentWithPassword ...
//Decrypt attachment using password locked key.
func (pm *PmCrypto) DecryptAttachmentWithPassword(keyPacket []byte, dataPacket []byte, password string) ([]byte, error) {
encrypted := append(keyPacket, dataPacket...)

View file

@ -3,25 +3,266 @@ package crypto
import (
"bytes"
"crypto"
"encoding/base64"
"encoding/hex"
"errors"
"strings"
"time"
"fmt"
"github.com/ProtonMail/go-pm-crypto/armor"
"io"
"io/ioutil"
"math/big"
"time"
// "net/http"
// "net/url"
"strings"
//"github.com/ProtonMail/go-pm-crypto/armor"
"github.com/ProtonMail/go-pm-crypto/models"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
"math/big"
)
const (
ok = 0
notSigned = 1
noVerifier = 2
failed = 3
)
// A decrypted session key.
type SymmetricKey struct {
// The clear base64-encoded key.
//Key string
Key []byte
// The algorithm used by this key.
Algo string
}
//IsKeyExpiredBin ...
//18 with the 2 highest order bits set to 1
const SymmetricallyEncryptedTag = 210
var symKeyAlgos = map[string]packet.CipherFunction{
"3des": packet.Cipher3DES,
"tripledes": packet.Cipher3DES,
"cast5": packet.CipherCAST5,
"aes128": packet.CipherAES128,
"aes192": packet.CipherAES192,
"aes256": packet.CipherAES256,
}
// Get cipher function corresponding to an algorithm used in this SymmetricKey
func (sk *SymmetricKey) GetCipherFunc() packet.CipherFunction {
cf, ok := symKeyAlgos[sk.Algo]
if ok {
return cf
}
panic("pmapi: unsupported cipher function: " + sk.Algo)
}
// Returns a key as base64 encoded string
func (sk *SymmetricKey) GetBase64Key() string {
return base64.StdEncoding.EncodeToString(sk.Key)
}
func newSymmetricKey(ek *packet.EncryptedKey) *SymmetricKey {
var algo string
for k, v := range symKeyAlgos {
if v == ek.CipherFunc {
algo = k
break
}
}
if algo == "" {
panic(fmt.Sprintf("pmapi: unsupported cipher function: %v", ek.CipherFunc))
}
return &SymmetricKey{
Key: ek.Key, //base64.StdEncoding.EncodeToString(ek.Key),
Algo: algo,
}
}
// Decrypt and return a symmetric key
func DecryptAttKey(kr *KeyRing, keyPacket string) (key *SymmetricKey, err error) {
r := base64.NewDecoder(base64.StdEncoding, strings.NewReader(keyPacket))
packets := packet.NewReader(r)
var p packet.Packet
if p, err = packets.Next(); err != nil {
return
}
ek := p.(*packet.EncryptedKey)
var decryptErr error
for _, key := range kr.entities.DecryptionKeys() {
priv := key.PrivateKey
if priv.Encrypted {
continue
}
if decryptErr = ek.Decrypt(priv, nil); decryptErr == nil {
break
}
}
if decryptErr != nil {
err = fmt.Errorf("pmapi: cannot decrypt encrypted key packet: %v", decryptErr)
return
}
key = newSymmetricKey(ek)
return
}
// Separate key and data packets in a pgp session
func SeparateKeyAndData(kr *KeyRing, r io.Reader) (outSplit *models.EncryptedSplit, err error) {
packets := packet.NewReader(r)
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
if kr != nil {
for _, key := range kr.entities.DecryptionKeys() {
priv := key.PrivateKey
if priv.Encrypted {
continue
}
if decryptErr = ek.Decrypt(priv, nil); decryptErr == nil {
break
}
}
}
case *packet.SymmetricallyEncrypted:
var packetContents []byte
if packetContents, err = ioutil.ReadAll(p.Contents); err != nil {
return
}
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
}
}
if decryptErr != nil {
err = fmt.Errorf("pmapi: cannot decrypt encrypted key packet: %v", decryptErr)
return
}
if ek == nil {
err = errors.New("pmapi: packets don't include an encrypted key packet")
return
}
/*if ek.Key == nil {
err = errors.New("pmapi: could not find any key to decrypt key")
return
}*/
if kr == nil {
var buf bytes.Buffer
ek.Serialize(&buf)
outSplit.KeyPacket = buf.Bytes()
} else {
key := newSymmetricKey(ek)
outSplit.KeyPacket = key.Key
outSplit.Algo = key.Algo
}
return outSplit, nil
}
//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
}
// SetKey encrypts the provided key.
func SetKey(kr *KeyRing, symKey *SymmetricKey) (packets string, err error) {
b := &bytes.Buffer{}
w := base64.NewEncoder(base64.StdEncoding, b)
cf := symKey.GetCipherFunc()
//k, err := base64.StdEncoding.DecodeString(symKey.Key)
//if err != nil {
// err = fmt.Errorf("pmapi: cannot set key: %v", err)
// return
//}
if len(kr.entities) == 0 {
err = fmt.Errorf("pmapi: cannot set key: key ring is empty")
return
}
var pub *packet.PublicKey
for _, e := range kr.entities {
for _, subKey := range e.Subkeys {
if !subKey.Sig.FlagsValid || subKey.Sig.FlagEncryptStorage || subKey.Sig.FlagEncryptCommunications {
pub = subKey.PublicKey
break
}
}
if pub == nil && len(e.Identities) > 0 {
var i *openpgp.Identity
for _, i = range e.Identities {
break
}
if i.SelfSignature.FlagsValid || i.SelfSignature.FlagEncryptStorage || i.SelfSignature.FlagEncryptCommunications {
pub = e.PrimaryKey
}
}
if pub != nil {
break
}
}
if pub == nil {
err = fmt.Errorf("pmapi: cannot set key: no public key available")
return
}
if err = packet.SerializeEncryptedKey(w, pub, cf, symKey.Key, nil); err != nil {
err = fmt.Errorf("pmapi: cannot set key: %v", err)
return
}
if err = w.Close(); err != nil {
err = fmt.Errorf("pmapi: cannot set key: %v", err)
return
}
packets = b.String()
return
}
//Check if the given key is expired. Input in binary format
func (pm *PmCrypto) IsKeyExpiredBin(publicKey []byte) (bool, error) {
now := pm.getNow()
pubKeyReader := bytes.NewReader(publicKey)
@ -73,8 +314,14 @@ func (pm *PmCrypto) IsKeyExpiredBin(publicKey []byte) (bool, error) {
return true, errors.New("keys expired")
}
//IsKeyExpired ....
// will user the cached time to check
const (
ok = 0
notSigned = 1
noVerifier = 2
failed = 3
)
//Check if the given key is expired. Input in armored form
func (pm *PmCrypto) IsKeyExpired(publicKey string) (bool, error) {
rawPubKey, err := armor.Unarmor(publicKey)
if err != nil {
@ -170,7 +417,7 @@ func (pm *PmCrypto) GenerateKey(userName string, domain string, passphrase strin
return pm.generateKey(userName, domain, passphrase, keyType, bits, nil, nil, nil, nil)
}
// UpdatePrivateKeyPassphrase ...
// Decrypt given private key with oldPhrase and reencrypt with newPassphrase
func (pm *PmCrypto) UpdatePrivateKeyPassphrase(privateKey string, oldPassphrase string, newPassphrase string) (string, error) {
privKey := strings.NewReader(privateKey)

View file

@ -35,33 +35,8 @@ func (pm *PmCrypto) DecryptMessage(encryptedText string, privateKey string, pass
// privateKey : unarmored private use to decrypt message could be mutiple keys
// passphrase : match with private key to decrypt message
func (pm *PmCrypto) DecryptMessageBinKey(encryptedText string, privateKey []byte, passphrase string) (string, error) {
privKey := bytes.NewReader(privateKey)
privKeyEntries, err := openpgp.ReadKeyRing(privKey)
if err != nil {
return "", err
}
encryptedio, err := internal.Unarmor(encryptedText)
if err != nil {
return "", 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)
}
}
}
config := &packet.Config{Time: pm.getTimeGenerator()}
md, err := openpgp.ReadMessage(encryptedio.Body, privKeyEntries, nil, config)
md, err := pm.decryptCore(encryptedText, nil, privateKey, passphrase, pm.getTimeGenerator())
if err != nil {
return "", err
}
@ -123,10 +98,8 @@ func (pm *PmCrypto) DecryptMessageVerifyBinKey(encryptedText string, verifierKey
return pm.decryptMessageVerifyAllBin(encryptedText, verifierKey, privateKeyRaw, passphrase, verifyTime)
}
// decryptMessageVerifyAllBin
// decrypt_message_verify_single_key(private_key: string, passphras: string, encrypted : string, signature : string) : decrypt_sign_verify;
// decrypt_message_verify(passphras: string, encrypted : string, signature : string) : decrypt_sign_verify;
func (pm *PmCrypto) decryptMessageVerifyAllBin(encryptedText string, verifierKey []byte, privateKey []byte, passphrase string, verifyTime int64) (*models.DecryptSignedVerify, error) {
func (pm *PmCrypto) decryptCore(encryptedText string, additionalEntries openpgp.EntityList, privateKey []byte, passphrase string, timeFunc func() time.Time) (*openpgp.MessageDetails, error) {
privKey := bytes.NewReader(privateKey)
privKeyEntries, err := openpgp.ReadKeyRing(privKey)
if err != nil {
@ -147,22 +120,10 @@ func (pm *PmCrypto) decryptMessageVerifyAllBin(encryptedText string, verifierKey
}
}
out := &models.DecryptSignedVerify{}
out.Verify = failed
var verifierEntries openpgp.EntityList
if len(verifierKey) > 0 {
verifierReader := bytes.NewReader(verifierKey)
verifierEntries, err = openpgp.ReadKeyRing(verifierReader)
if err != nil {
return nil, err
}
for _, e := range verifierEntries {
if additionalEntries != nil {
for _, e := range additionalEntries {
privKeyEntries = append(privKeyEntries, e)
}
} else {
out.Verify = noVerifier
}
encryptedio, err := internal.Unarmor(encryptedText)
@ -170,16 +131,35 @@ func (pm *PmCrypto) decryptMessageVerifyAllBin(encryptedText string, verifierKey
return nil, err
}
config := &packet.Config{}
config.Time = func() time.Time {
return time.Unix(0, 0)
}
config := &packet.Config{Time: timeFunc}
md, err := openpgp.ReadMessage(encryptedio.Body, privKeyEntries, nil, config)
if err != nil {
return nil, err
return md, err
}
// decryptMessageVerifyAllBin
// decrypt_message_verify_single_key(private_key: string, passphras: string, encrypted : string, signature : string) : decrypt_sign_verify;
// decrypt_message_verify(passphras: string, encrypted : string, signature : string) : decrypt_sign_verify;
func (pm *PmCrypto) decryptMessageVerifyAllBin(encryptedText string, verifierKey []byte, privateKey []byte, passphrase string, verifyTime int64) (*models.DecryptSignedVerify, error) {
out := &models.DecryptSignedVerify{}
out.Verify = failed
var verifierEntries openpgp.EntityList
if len(verifierKey) > 0 {
verifierReader := bytes.NewReader(verifierKey)
var err error
verifierEntries, err = openpgp.ReadKeyRing(verifierReader)
if err != nil {
return nil, err
}
} else {
out.Verify = noVerifier
}
md, err := pm.decryptCore(encryptedText, verifierEntries, privateKey, passphrase, func() time.Time { return time.Unix(0, 0) }) // TODO: I doubt this time is correct
decrypted := md.UnverifiedBody
b, err := ioutil.ReadAll(decrypted)
if err != nil {
@ -256,7 +236,7 @@ func (pm *PmCrypto) EncryptMessageBinKey(plainText string, publicKey []byte, pri
plainText = internal.TrimNewlines(plainText)
}
var outBuf bytes.Buffer
w, err := armor.Encode(&outBuf, armorUtils.MESSAGE_HEADER, internal.ArmorHeaders)
w, err := armor.Encode(&outBuf, armorUtils.PGP_MESSAGE_HEADER, internal.ArmorHeaders)
if err != nil {
return "", err
}
@ -294,9 +274,7 @@ func (pm *PmCrypto) EncryptMessageBinKey(plainText string, publicKey []byte, pri
}
}
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pm.getTimeGenerator()}
ew, err := openpgp.Encrypt(w, pubKeyEntries, signEntity, nil, config)
ew, err := EncryptCore(w, pubKeyEntries, signEntity, "", false, pm.getTimeGenerator())
_, _ = ew.Write([]byte(plainText))
ew.Close()
@ -310,7 +288,7 @@ func (pm *PmCrypto) EncryptMessageBinKey(plainText string, publicKey []byte, pri
func (pm *PmCrypto) EncryptMessageWithPassword(plainText string, password string) (string, error) {
var outBuf bytes.Buffer
w, err := armor.Encode(&outBuf, armorUtils.MESSAGE_HEADER, internal.ArmorHeaders)
w, err := armor.Encode(&outBuf, armorUtils.PGP_MESSAGE_HEADER, internal.ArmorHeaders)
if err != nil {
return "", err
}

View file

@ -12,10 +12,6 @@ import (
"strings"
)
// ======================== Attachments Collector ==============
// Collect contents of all attachment parts and return
// them as a string
func (pm PmCrypto) parseMIME(mimeBody string, verifierKey []byte) (*pmmime.BodyCollector, int, []string, []string, error) {
pubKey := bytes.NewReader(verifierKey)
pubKeyEntries, err := openpgp.ReadKeyRing(pubKey)

View file

@ -1,39 +1,15 @@
// Package crypto contains all methods and classes needed for manipulation
// with underlying cryptographic operations. It uses lowlevel openpgp functions
// and provides higher level views. It uses models of messages, attachments
// and other higher-level entities
package crypto
import "time"
// PmCrypto structure to manage multiple address keys and user keys
// Called PGP crypto because it cannot have the same name as the package by gomobile's ridiculous rules.
// PmCrypto structure is used to manage server time shift. It should be also used for any
// other specific general cryptographic entities.
type PmCrypto struct {
//latestServerTime unix time cache
latestServerTime int64
latestClientTime time.Time
}
// //AddAddress add a new address to key ring
// //add a new address into addresses list
// func (pgp *PmCrypto) AddAddress(address *Address) (bool, error) {
// return true, errors.New("this is not implemented yet, will add this later")
// }
// //RemoveAddress remove address from the keyring
// //
// //#remove a exsit address from the list based on address id
// func (pgp *PmCrypto) RemoveAddress(addressID string) (bool, error) {
// return true, errors.New("this is not implemented yet, will add this later")
// }
// //CleanAddresses clear all addresses in keyring
// func (pgp *PmCrypto) CleanAddresses() (bool, error) {
// return true, errors.New("this is not implemented yet, will add this later")
// }
// //EncryptMessage encrypt message use address id
// func (pgp *PmCrypto) EncryptMessage(addressID string, plainText string, passphrase string, trim bool) (string, error) {
// return "", errors.New("this is not implemented yet, will add this later")
// }
// //DecryptMessage decrypt message, this will lookup all keys
// func (pgp *PmCrypto) DecryptMessage(encryptText string, passphras string) (string, error) {
// return "", errors.New("this is not implemented yet, will add this later")
// }

View file

@ -8,7 +8,6 @@ import (
"strings"
"github.com/ProtonMail/go-pm-crypto/armor"
"github.com/ProtonMail/go-pm-crypto/models"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
)
@ -35,7 +34,7 @@ func (pm *PmCrypto) RandomTokenWith(size int) ([]byte, error) {
}
//GetSessionFromKeyPacketBinkeys get session key no encoding in and out
func (pm *PmCrypto) GetSessionFromKeyPacketBinkeys(keyPackage []byte, privateKey []byte, passphrase string) (*models.SessionSplit, error) {
func (pm *PmCrypto) GetSessionFromKeyPacketBinkeys(keyPackage []byte, privateKey []byte, passphrase string) (*SymmetricKey, error) {
keyReader := bytes.NewReader(keyPackage)
packets := packet.NewReader(keyReader)
@ -76,7 +75,7 @@ func (pm *PmCrypto) GetSessionFromKeyPacketBinkeys(keyPackage []byte, privateKey
}
//GetSessionFromKeyPacket get session key no encoding in and out
func (pm *PmCrypto) GetSessionFromKeyPacket(keyPackage []byte, privateKey string, passphrase string) (*models.SessionSplit, error) {
func (pm *PmCrypto) GetSessionFromKeyPacket(keyPackage []byte, privateKey string, passphrase string) (*SymmetricKey, error) {
keyReader := bytes.NewReader(keyPackage)
packets := packet.NewReader(keyReader)
@ -117,7 +116,7 @@ func (pm *PmCrypto) GetSessionFromKeyPacket(keyPackage []byte, privateKey string
}
//KeyPacketWithPublicKey ...
func (pm *PmCrypto) KeyPacketWithPublicKey(sessionSplit *models.SessionSplit, publicKey string) ([]byte, error) {
func (pm *PmCrypto) KeyPacketWithPublicKey(sessionSplit *SymmetricKey, publicKey string) ([]byte, error) {
pubkeyRaw, err := armor.Unarmor(publicKey)
if err != nil {
return nil, err
@ -126,13 +125,13 @@ func (pm *PmCrypto) KeyPacketWithPublicKey(sessionSplit *models.SessionSplit, pu
}
// KeyPacketWithPublicKeyBin ...
func (pm *PmCrypto) KeyPacketWithPublicKeyBin(sessionSplit *models.SessionSplit, publicKey []byte) ([]byte, error) {
func (pm *PmCrypto) KeyPacketWithPublicKeyBin(sessionSplit *SymmetricKey, publicKey []byte) ([]byte, error) {
publicKeyReader := bytes.NewReader(publicKey)
pubKeyEntries, err := openpgp.ReadKeyRing(publicKeyReader)
outbuf := &bytes.Buffer{}
cf := cipherFunc(sessionSplit.Algo)
cf := sessionSplit.GetCipherFunc()
if len(pubKeyEntries) == 0 {
return nil, errors.New("cannot set key: key ring is empty")
@ -163,7 +162,7 @@ func (pm *PmCrypto) KeyPacketWithPublicKeyBin(sessionSplit *models.SessionSplit,
return nil, errors.New("cannot set key: no public key available")
}
if err = packet.SerializeEncryptedKey(outbuf, pub, cf, sessionSplit.Session, nil); err != nil {
if err = packet.SerializeEncryptedKey(outbuf, pub, cf, sessionSplit.Key, nil); err != nil {
err = fmt.Errorf("pmapi: cannot set key: %v", err)
return nil, errors.New("cannot set key: key ring is empty")
}
@ -171,7 +170,7 @@ func (pm *PmCrypto) KeyPacketWithPublicKeyBin(sessionSplit *models.SessionSplit,
}
//GetSessionFromSymmetricPacket ...
func (pm *PmCrypto) GetSessionFromSymmetricPacket(keyPackage []byte, password string) (*models.SessionSplit, error) {
func (pm *PmCrypto) GetSessionFromSymmetricPacket(keyPackage []byte, password string) (*SymmetricKey, error) {
keyReader := bytes.NewReader(keyPackage)
packets := packet.NewReader(keyReader)
@ -197,9 +196,9 @@ func (pm *PmCrypto) GetSessionFromSymmetricPacket(keyPackage []byte, password st
for _, s := range symKeys {
key, cipherFunc, err := s.Decrypt(pwdRaw)
if err == nil {
return &models.SessionSplit{
Session: key,
Algo: getAlgo(cipherFunc),
return &SymmetricKey{
Key: key,
Algo: getAlgo(cipherFunc),
}, nil
}
@ -210,10 +209,10 @@ func (pm *PmCrypto) GetSessionFromSymmetricPacket(keyPackage []byte, password st
}
// SymmetricKeyPacketWithPassword ...
func (pm *PmCrypto) SymmetricKeyPacketWithPassword(sessionSplit *models.SessionSplit, password string) ([]byte, error) {
func (pm *PmCrypto) SymmetricKeyPacketWithPassword(sessionSplit *SymmetricKey, password string) ([]byte, error) {
outbuf := &bytes.Buffer{}
cf := cipherFunc(sessionSplit.Algo)
cf := sessionSplit.GetCipherFunc()
if len(password) <= 0 {
return nil, errors.New("password can't be empty")
@ -225,32 +224,14 @@ func (pm *PmCrypto) SymmetricKeyPacketWithPassword(sessionSplit *models.SessionS
DefaultCipher: cf,
}
err := packet.SerializeSymmetricKeyEncryptedReuseKey(outbuf, sessionSplit.Session, pwdRaw, config)
err := packet.SerializeSymmetricKeyEncryptedReuseKey(outbuf, sessionSplit.Key, pwdRaw, config)
if err != nil {
return nil, err
}
return outbuf.Bytes(), nil
}
//symKeyAlgos ...
var symKeyAlgos = map[string]packet.CipherFunction{
"3des": packet.Cipher3DES,
"cast5": packet.CipherCAST5,
"aes128": packet.CipherAES128,
"aes192": packet.CipherAES192,
"aes256": packet.CipherAES256,
}
// Get cipher function.
func cipherFunc(algo string) packet.CipherFunction {
cf, ok := symKeyAlgos[algo]
if ok {
return cf
}
return packet.CipherAES256
}
func getSessionSplit(ek *packet.EncryptedKey) (*models.SessionSplit, error) {
func getSessionSplit(ek *packet.EncryptedKey) (*SymmetricKey, error) {
if ek == nil {
return nil, errors.New("can't decrypt key packet")
}
@ -266,9 +247,9 @@ func getSessionSplit(ek *packet.EncryptedKey) (*models.SessionSplit, error) {
return nil, errors.New("can't decrypt key packet key is nil")
}
return &models.SessionSplit{
Session: ek.Key,
Algo: algo,
return &SymmetricKey{
Key: ek.Key,
Algo: algo,
}, nil
}

View file

@ -58,7 +58,7 @@ func (pm *PmCrypto) SignTextDetached(plainText string, privateKey string, passph
return outBuf.String(), nil
}
// SignTextDetachedBinKey ...
// Sign detached text using binary key data
func (pm *PmCrypto) SignTextDetachedBinKey(plainText string, privateKey []byte, passphrase string, trim bool) (string, error) {
//sign with 0x01
var signEntity *openpgp.Entity
@ -103,7 +103,7 @@ func (pm *PmCrypto) SignTextDetachedBinKey(plainText string, privateKey []byte,
return outBuf.String(), nil
}
// SignBinDetached sign bin data
// Sign detached bin data using string key
func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey string, passphrase string) (string, error) {
//sign with 0x00
var signEntity *openpgp.Entity
@ -144,7 +144,7 @@ func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey string, passphr
return outBuf.String(), nil
}
// SignBinDetachedBinKey ...
// Sign detached binary data using binary key format
func (pm *PmCrypto) SignBinDetachedBinKey(plainData []byte, privateKey []byte, passphrase string) (string, error) {
//sign with 0x00
var signEntity *openpgp.Entity
@ -185,7 +185,7 @@ func (pm *PmCrypto) SignBinDetachedBinKey(plainData []byte, privateKey []byte, p
return outBuf.String(), nil
}
// VerifyTextSignDetached ...
// Verify detached text - check if signature is valid using a given publicKey
func (pm *PmCrypto) VerifyTextSignDetached(signature string, plainText string, publicKey string, verifyTime int64) (bool, error) {
pubKeyReader := strings.NewReader(publicKey)
@ -202,7 +202,7 @@ func (pm *PmCrypto) VerifyTextSignDetached(signature string, plainText string, p
return verifySignature(pubKeyEntries, origText, signature, verifyTime)
}
// VerifyTextSignDetachedBinKey ...
// Verify detached text - check if signature is valid using a given publicKey in binary format
func (pm *PmCrypto) VerifyTextSignDetachedBinKey(signature string, plainText string, publicKey []byte, verifyTime int64) (bool, error) {
pubKeyReader := bytes.NewReader(publicKey)
@ -261,7 +261,7 @@ func verifySignature(pubKeyEntries openpgp.EntityList, origText *bytes.Reader, s
return true, nil
}
// VerifyBinSignDetached ...
// Verify detached text in binary format - check if signature is valid using a given publicKey in string format
func (pm *PmCrypto) VerifyBinSignDetached(signature string, plainData []byte, publicKey string, verifyTime int64) (bool, error) {
pubKeyReader := strings.NewReader(publicKey)
@ -275,7 +275,7 @@ func (pm *PmCrypto) VerifyBinSignDetached(signature string, plainData []byte, pu
return verifySignature(pubKeyEntries, origText, signature, verifyTime)
}
// VerifyBinSignDetachedBinKey ...
// Verify detached text in binary format - check if signature is valid using a given publicKey in binary format
func (pm *PmCrypto) VerifyBinSignDetachedBinKey(signature string, plainData []byte, publicKey []byte, verifyTime int64) (bool, error) {
pubKeyReader := bytes.NewReader(publicKey)

View file

@ -4,6 +4,12 @@ import (
"time"
)
var pmCrypto = PmCrypto{}
func GetPmCrypto() *PmCrypto {
return &pmCrypto
}
// UpdateTime update cached time
func (pm *PmCrypto) UpdateTime(newTime int64) {
pm.latestServerTime = newTime