Android-side KeyRing reuse refactoring support

This commit is contained in:
Jakub Lehotsky 2018-11-09 13:03:46 +01:00
parent 984f8eb391
commit d57b71e5ec
4 changed files with 23 additions and 112 deletions

View file

@ -55,13 +55,6 @@ func (pm *PmCrypto) DecryptMessage(encryptedText string, privateKey *KeyRing, pa
return string(b), nil
}
// DecryptMessageVerifyBinKeyPrivBinKeys decrypt message and verify the signature
// verifierKey []byte: unarmored verifier keys
// privateKey []byte: unarmored private key to decrypt. could be mutiple
func (pm *PmCrypto) DecryptMessageVerify(encryptedText string, verifierKey []byte, privateKeysRing *KeyRing, passphrase string, verifyTime int64) (*models.DecryptSignedVerify, error) {
return pm.decryptMessageVerify(encryptedText, verifierKey, privateKeysRing, passphrase, verifyTime)
}
func decryptCore(encryptedText string, additionalEntries openpgp.EntityList, privKeyEntries openpgp.EntityList, passphrase string, timeFunc func() time.Time) (*openpgp.MessageDetails, error) {
rawPwd := []byte(passphrase)
@ -95,24 +88,16 @@ func decryptCore(encryptedText string, additionalEntries openpgp.EntityList, pri
return md, err
}
// decryptMessageVerify
// 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) decryptMessageVerify(encryptedText string, verifierKey []byte, privateKeyRing *KeyRing, passphrase string, verifyTime int64) (*models.DecryptSignedVerify, error) {
func (pm *PmCrypto) DecryptMessageVerify(encryptedText string, verifierKey *KeyRing, privateKeyRing *KeyRing, passphrase string, verifyTime int64) (*models.DecryptSignedVerify, error) {
// DecryptMessageVerifyBinKeyPrivBinKeys decrypt message and verify the signature
// verifierKey []byte: unarmored verifier keys
// privateKey []byte: unarmored private key to decrypt. could be mutiple
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 {
if len(verifierKey.entities) == 0 {
out.Verify = noVerifier
}
@ -129,8 +114,8 @@ func (pm *PmCrypto) decryptMessageVerify(encryptedText string, verifierKey []byt
out.Plaintext = string(b)
if md.IsSigned {
if md.SignedBy != nil {
if verifierEntries != nil {
matches := verifierEntries.KeysById(md.SignedByKeyId)
if len(verifierKey.entities) > 0 {
matches := verifierKey.entities.KeysById(md.SignedByKeyId)
if len(matches) > 0 {
if md.SignatureError == nil {
out.Verify = ok

View file

@ -2,9 +2,7 @@ package crypto
import (
"bytes"
"github.com/ProtonMail/go-pm-crypto/armor"
"github.com/ProtonMail/go-pm-mime"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
"io/ioutil"
"net/mail"
@ -12,9 +10,7 @@ import (
"strings"
)
func (pm PmCrypto) parseMIME(mimeBody string, verifierKey []byte) (*pmmime.BodyCollector, int, []string, []string, error) {
pubKey := bytes.NewReader(verifierKey)
pubKeyEntries, err := openpgp.ReadKeyRing(pubKey)
func (pm PmCrypto) parseMIME(mimeBody string, verifierKey *KeyRing) (*pmmime.BodyCollector, int, []string, []string, error) {
mm, err := mail.ReadMessage(strings.NewReader(mimeBody))
if err != nil {
@ -31,9 +27,8 @@ func (pm PmCrypto) parseMIME(mimeBody string, verifierKey []byte) (*pmmime.BodyC
mimeVisitor := pmmime.NewMimeVisitor(attachmentsCollector)
// TODO: build was failing on this unused 'str' variable. This code looks like WIP
//str, err := armor.ArmorKey(verifierKey)
_, err = armor.ArmorKey(verifierKey)
signatureCollector := newSignatureCollector(mimeVisitor, pubKeyEntries, config)
signatureCollector := newSignatureCollector(mimeVisitor, verifierKey.entities, config)
err = pmmime.VisitAll(bytes.NewReader(mmBodyData), h, signatureCollector)
verified := signatureCollector.verified
@ -54,9 +49,9 @@ type MIMECallbacks interface {
OnError(err error)
}
func (pm *PmCrypto) DecryptMIMEMessage(encryptedText string, verifierKey []byte, privateKeyRing *KeyRing,
func (pm *PmCrypto) DecryptMIMEMessage(encryptedText string, verifierKey *KeyRing, privateKeyRing *KeyRing,
passphrase string, callbacks MIMECallbacks, verifyTime int64) {
decsignverify, err := pm.decryptMessageVerify(encryptedText, verifierKey, privateKeyRing, passphrase, verifyTime)
decsignverify, err := pm.DecryptMessageVerify(encryptedText, verifierKey, privateKeyRing, passphrase, verifyTime)
if err != nil {
callbacks.OnError(err)
return

View file

@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
"strings"
"github.com/ProtonMail/go-pm-crypto/armor"
"golang.org/x/crypto/openpgp"
@ -34,7 +33,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) (*SymmetricKey, error) {
func (pm *PmCrypto) GetSessionFromKeyPacket(keyPackage []byte, privateKey *KeyRing, passphrase string) (*SymmetricKey, error) {
keyReader := bytes.NewReader(keyPackage)
packets := packet.NewReader(keyReader)
@ -47,55 +46,12 @@ func (pm *PmCrypto) GetSessionFromKeyPacketBinkeys(keyPackage []byte, privateKey
ek := p.(*packet.EncryptedKey)
privKey := bytes.NewReader(privateKey)
privKeyEntries, err := openpgp.ReadKeyRing(privKey)
if err != nil {
return nil, err
}
rawPwd := []byte(passphrase)
var decryptErr error
for _, key := range privKeyEntries.DecryptionKeys() {
priv := key.PrivateKey
if priv.Encrypted {
if err := priv.Decrypt(rawPwd); err != nil {
continue
}
}
if decryptErr = ek.Decrypt(priv, nil); decryptErr == nil {
break
}
}
if decryptErr != nil {
return nil, err
}
return getSessionSplit(ek)
}
//GetSessionFromKeyPacket get session key no encoding in and out
func (pm *PmCrypto) GetSessionFromKeyPacket(keyPackage []byte, privateKey string, passphrase string) (*SymmetricKey, error) {
keyReader := bytes.NewReader(keyPackage)
packets := packet.NewReader(keyReader)
var p packet.Packet
var err error
if p, err = packets.Next(); err != nil {
return nil, err
}
ek := p.(*packet.EncryptedKey)
privKey := strings.NewReader(privateKey)
privKeyEntries, err := openpgp.ReadArmoredKeyRing(privKey)
if err != nil {
return nil, err
}
rawPwd := []byte(passphrase)
var decryptErr error
for _, key := range privKeyEntries.DecryptionKeys() {
for _, key := range privateKey.entities.DecryptionKeys() {
priv := key.PrivateKey
if priv.Encrypted {
if err := priv.Decrypt(rawPwd); err != nil {

View file

@ -14,7 +14,7 @@ import (
)
// SignTextDetached sign detached text type
func (pm *PmCrypto) SignTextDetached(plainText string, privateKey string, passphrase string, trim bool) (string, error) {
func (pm *PmCrypto) SignTextDetached(plainText string, privateKey *KeyRing, passphrase string, trim bool) (string, error) {
//sign with 0x01 text
var signEntity *openpgp.Entity
@ -22,13 +22,7 @@ func (pm *PmCrypto) SignTextDetached(plainText string, privateKey string, passph
plainText = internal.TrimNewlines(plainText)
}
signerReader := strings.NewReader(privateKey)
signerEntries, err := openpgp.ReadArmoredKeyRing(signerReader)
if err != nil {
return "", err
}
for _, e := range signerEntries {
for _, e := range privateKey.entities {
// Entity.PrivateKey must be a signing key
if e.PrivateKey != nil {
if e.PrivateKey.Encrypted {
@ -51,7 +45,7 @@ func (pm *PmCrypto) SignTextDetached(plainText string, privateKey string, passph
var outBuf bytes.Buffer
//SignText
if err = openpgp.ArmoredDetachSignText(&outBuf, signEntity, att, config); err != nil {
if err := openpgp.ArmoredDetachSignText(&outBuf, signEntity, att, config); err != nil {
return "", err
}
@ -59,17 +53,11 @@ func (pm *PmCrypto) SignTextDetached(plainText string, privateKey string, passph
}
// Sign detached bin data using string key
func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey string, passphrase string) (string, error) {
func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey *KeyRing, passphrase string) (string, error) {
//sign with 0x00
var signEntity *openpgp.Entity
signerReader := strings.NewReader(privateKey)
signerEntries, err := openpgp.ReadArmoredKeyRing(signerReader)
if err != nil {
return "", err
}
for _, e := range signerEntries {
for _, e := range privateKey.entities {
// Entity.PrivateKey must be a signing key
if e.PrivateKey != nil {
if e.PrivateKey.Encrypted {
@ -92,7 +80,7 @@ func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey string, passphr
var outBuf bytes.Buffer
//sign bin
if err = openpgp.ArmoredDetachSign(&outBuf, signEntity, att, config); err != nil {
if err := openpgp.ArmoredDetachSign(&outBuf, signEntity, att, config); err != nil {
return "", err
}
@ -100,19 +88,12 @@ func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey string, passphr
}
// 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)
pubKeyEntries, err := openpgp.ReadKeyRing(pubKeyReader)
if err != nil {
return false, err
}
func (pm *PmCrypto) VerifyTextSignDetachedBinKey(signature string, plainText string, publicKey *KeyRing, verifyTime int64) (bool, error) {
plainText = internal.TrimNewlines(plainText)
origText := bytes.NewReader(bytes.NewBufferString(plainText).Bytes())
return verifySignature(pubKeyEntries, origText, signature, verifyTime)
return verifySignature(publicKey.entities, origText, signature, verifyTime)
}
func verifySignature(pubKeyEntries openpgp.EntityList, origText *bytes.Reader, signature string, verifyTime int64) (bool, error) {
@ -159,15 +140,9 @@ func verifySignature(pubKeyEntries openpgp.EntityList, origText *bytes.Reader, s
}
// 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)
pubKeyEntries, err := openpgp.ReadKeyRing(pubKeyReader)
if err != nil {
return false, err
}
func (pm *PmCrypto) VerifyBinSignDetachedBinKey(signature string, plainData []byte, publicKey *KeyRing, verifyTime int64) (bool, error) {
origText := bytes.NewReader(plainData)
return verifySignature(pubKeyEntries, origText, signature, verifyTime)
return verifySignature(publicKey.entities, origText, signature, verifyTime)
}