Methods use + unit tests update
This commit is contained in:
parent
09d519e51e
commit
b218f523af
15 changed files with 170 additions and 15 deletions
|
|
@ -11,16 +11,19 @@ import (
|
|||
"io/ioutil"
|
||||
)
|
||||
|
||||
// Use: ios/android only
|
||||
// ArmorKey make bytes input key to armor format
|
||||
func ArmorKey(input []byte) (string, error) {
|
||||
return ArmorWithType(input, PUBLIC_KEY_HEADER)
|
||||
}
|
||||
|
||||
// Use: go-pm-crypto, keyring.go
|
||||
// ArmorWithTypeBuffered take input from io.Writer and returns io.WriteCloser which can be read for armored code
|
||||
func ArmorWithTypeBuffered(w io.Writer, armorType string) (io.WriteCloser, error) {
|
||||
return armor.Encode(w, armorType, nil)
|
||||
}
|
||||
|
||||
// Use: go-pm-crypto
|
||||
// ArmorWithType make bytes input to armor format
|
||||
func ArmorWithType(input []byte, armorType string) (string, error) {
|
||||
var b bytes.Buffer
|
||||
|
|
@ -38,6 +41,7 @@ func ArmorWithType(input []byte, armorType string) (string, error) {
|
|||
return b.String(), nil
|
||||
}
|
||||
|
||||
// Use: go-pm-crypto, attachment.go, keyring.go, session.go, message.go
|
||||
// Unarmor an armored key to bytes key
|
||||
func Unarmor(input string) ([]byte, error) {
|
||||
b, err := internal.Unarmor(input)
|
||||
|
|
@ -47,6 +51,7 @@ func Unarmor(input string) ([]byte, error) {
|
|||
return ioutil.ReadAll(b.Body)
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
//ReadClearSignedMessage read clear message from a clearsign package (package containing cleartext and signature)
|
||||
func ReadClearSignedMessage(signedMessage string) (string, error) {
|
||||
modulusBlock, rest := clearsign.Decode([]byte(signedMessage))
|
||||
|
|
|
|||
|
|
@ -23,10 +23,12 @@ type AttachmentProcessor struct {
|
|||
err error
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
func (ap *AttachmentProcessor) Process(plainData []byte) {
|
||||
(*ap.w).Write(plainData)
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
func (ap *AttachmentProcessor) Finish() (*models.EncryptedSplit, error) {
|
||||
if ap.err != nil {
|
||||
return nil, ap.err
|
||||
|
|
@ -40,6 +42,7 @@ func (ap *AttachmentProcessor) Finish() (*models.EncryptedSplit, error) {
|
|||
return ap.split, nil
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// Encrypt attachment. Takes input data and key data in binary form
|
||||
func (pm *PmCrypto) encryptAttachment(estimatedSize int, fileName string, publicKey *KeyRing, garbageCollector int) (*AttachmentProcessor, error) {
|
||||
attachmentProc := &AttachmentProcessor{}
|
||||
|
|
@ -82,6 +85,7 @@ func (pm *PmCrypto) encryptAttachment(estimatedSize int, fileName string, public
|
|||
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
func (pm *PmCrypto) EncryptAttachment(plainData []byte, fileName string, publicKey *KeyRing) (*models.EncryptedSplit, error) {
|
||||
ap, err := pm.encryptAttachment(len(plainData), fileName, publicKey, -1)
|
||||
if err != nil {
|
||||
|
|
@ -96,12 +100,14 @@ func (pm *PmCrypto) EncryptAttachment(plainData []byte, fileName string, publicK
|
|||
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
//EncryptAttachment ...
|
||||
func (pm *PmCrypto) EncryptAttachmentLowMemory(estimatedSize int, fileName string, publicKey *KeyRing) (*AttachmentProcessor, error) {
|
||||
// Garbage collect every megabyte
|
||||
return pm.encryptAttachment(estimatedSize, fileName, publicKey, 1<<20)
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// Helper method. Splits armored pgp session into key and packet data
|
||||
func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
|
||||
|
||||
|
|
@ -118,6 +124,7 @@ func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
|
|||
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// 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) DecryptAttachment(keyPacket []byte, dataPacket []byte, kr *KeyRing, passphrase string) ([]byte, error) {
|
||||
|
||||
|
|
|
|||
72
crypto/attachment_test.go
Normal file
72
crypto/attachment_test.go
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
package crypto
|
||||
|
||||
import (
|
||||
// "bytes"
|
||||
"encoding/base64"
|
||||
// "io/ioutil"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var testKeyPackets = "wcBMA0fcZ7XLgmf2AQgAiRsOlnm1kSB4/lr7tYe6pBsRGn10GqwUhrwU5PMKOHdCgnO12jO3y3CzP0Yl/jGhAYja9wLDqH8X0sk3tY32u4Sb1Qe5IuzggAiCa4dwOJj5gEFMTHMzjIMPHR7A70XqUxMhmILye8V4KRm/j4c1sxbzA1rM3lYBumQuB5l/ck0Kgt4ZqxHVXHK5Q1l65FHhSXRj8qnunasHa30TYNzP8nmBA8BinnJxpiQ7FGc2umnUhgkFt jm5ixu9vyjr9ukwDTbwAXXfmY+o7tK7kqIXJcmTL6k2UeC6Mz1AagQtRCRtU+bv/3zGojq/trZo9lom3naIeQYa36Ketmcpj2Qwjg=="
|
||||
|
||||
const testAttachmentCleartext = `cc,
|
||||
dille.
|
||||
`
|
||||
|
||||
const testAttachmentEncrypted = `0ksB0fHC6Duezx/0TqpK/82HSl8+qCY0c2BCuyrSFoj6Dubd93T3//32jVYa624NYvfvxX+UxFKYKJxG09gFsU1IVc87cWvUgmUmgjU=`
|
||||
|
||||
func TestAttachment_GetKey(t *testing.T) {
|
||||
split, err := SeparateKeyAndData(testPrivateKeyRing, strings.NewReader(testKeyPackets), len(testKeyPackets), -1)
|
||||
if err != nil {
|
||||
t.Fatal("Expected no error while decrypting attachment key, got:", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(testSymmetricKey, split.KeyPacket) {
|
||||
t.Fatalf("Invalid attachment key: expected %+v, got %+v", testSymmetricKey, split.KeyPacket)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttachment_SetKey(t *testing.T) {
|
||||
|
||||
var packets string
|
||||
var err error
|
||||
|
||||
if packets, err = SetKey(testPublicKeyRing, testSymmetricKey); err != nil {
|
||||
t.Fatal("Expected no error while encrypting attachment key, got:", err)
|
||||
}
|
||||
keyPackets := packets
|
||||
|
||||
split, err := SeparateKeyAndData(testPrivateKeyRing, strings.NewReader(keyPackets), len(keyPackets), -1)
|
||||
if err != nil {
|
||||
t.Fatal("Expected no error while decrypting attachment key, got:", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(testSymmetricKey, split.KeyPacket) {
|
||||
t.Fatalf("Invalid attachment key: expected %+v, got %+v", testSymmetricKey, split.KeyPacket)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAttachnent_EncryptDecrypt(t *testing.T) {
|
||||
plainData, _ := base64.StdEncoding.DecodeString(testAttachmentCleartext)
|
||||
|
||||
var pmCrypto = PmCrypto{}
|
||||
|
||||
encSplit, err := pmCrypto.EncryptAttachment(plainData, "s.txt", testPrivateKeyRing)
|
||||
if err != nil {
|
||||
t.Fatal("Expected no error while encrypting attachment, got:", err)
|
||||
}
|
||||
|
||||
redecData, err := pmCrypto.DecryptAttachment(encSplit.KeyPacket, encSplit.DataPacket, testPrivateKeyRing, "")
|
||||
if err != nil {
|
||||
t.Fatal("Expected no error while decrypting attachment, got:", err)
|
||||
}
|
||||
|
||||
s := string(redecData)
|
||||
|
||||
if testAttachmentCleartext != s {
|
||||
t.Fatalf("Invalid decrypted attachment: expected %v, got %v", testAttachmentCleartext, s)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -43,6 +43,7 @@ var symKeyAlgos = map[string]packet.CipherFunction{
|
|||
"aes256": packet.CipherAES256,
|
||||
}
|
||||
|
||||
// Use: go-pm-crypto, key.go, session.go
|
||||
// Get cipher function corresponding to an algorithm used in this SymmetricKey
|
||||
func (sk *SymmetricKey) GetCipherFunc() packet.CipherFunction {
|
||||
cf, ok := symKeyAlgos[sk.Algo]
|
||||
|
|
@ -53,6 +54,7 @@ func (sk *SymmetricKey) GetCipherFunc() packet.CipherFunction {
|
|||
panic("pmapi: unsupported cipher function: " + sk.Algo)
|
||||
}
|
||||
|
||||
// Use: bridge
|
||||
// Returns a key as base64 encoded string
|
||||
func (sk *SymmetricKey) GetBase64Key() string {
|
||||
return base64.StdEncoding.EncodeToString(sk.Key)
|
||||
|
|
@ -76,6 +78,7 @@ func newSymmetricKey(ek *packet.EncryptedKey) *SymmetricKey {
|
|||
}
|
||||
}
|
||||
|
||||
// Use: bridge
|
||||
// Decrypt and return a symmetric key
|
||||
func DecryptAttKey(kr *KeyRing, keyPacket string) (key *SymmetricKey, err error) {
|
||||
r := base64.NewDecoder(base64.StdEncoding, strings.NewReader(keyPacket))
|
||||
|
|
@ -109,6 +112,7 @@ func DecryptAttKey(kr *KeyRing, keyPacket string) (key *SymmetricKey, err error)
|
|||
return
|
||||
}
|
||||
|
||||
// Use: bridge, ios/android, go-pm-crypto, attachment.go, keyring.go
|
||||
// Separate key and data packets in a pgp session
|
||||
func SeparateKeyAndData(kr *KeyRing, r io.Reader, estimatedLength int, garbageCollector int) (outSplit *models.EncryptedSplit, err error) {
|
||||
|
||||
|
|
@ -243,6 +247,7 @@ func encodedLength(length int) (b []byte) {
|
|||
return
|
||||
}
|
||||
|
||||
// Use: bridge
|
||||
// SetKey encrypts the provided key.
|
||||
func SetKey(kr *KeyRing, symKey *SymmetricKey) (packets string, err error) {
|
||||
b := &bytes.Buffer{}
|
||||
|
|
@ -301,6 +306,7 @@ func SetKey(kr *KeyRing, symKey *SymmetricKey) (packets string, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
//Use: ios/android only
|
||||
//Check if the given key is expired. Input in binary format
|
||||
func (pm *PmCrypto) IsKeyExpiredBin(publicKey []byte) (bool, error) {
|
||||
now := pm.getNow()
|
||||
|
|
@ -360,6 +366,7 @@ const (
|
|||
failed = 3
|
||||
)
|
||||
|
||||
//Use: ios/android only
|
||||
//Check if the given key is expired. Input in armored form
|
||||
func (pm *PmCrypto) IsKeyExpired(publicKey string) (bool, error) {
|
||||
rawPubKey, err := armor.Unarmor(publicKey)
|
||||
|
|
@ -446,6 +453,7 @@ func (pm *PmCrypto) GenerateRSAKeyWithPrimes(userName string, domain string, pas
|
|||
return pm.generateKey(userName, domain, passphrase, "rsa", bits, primeone, primetwo, primethree, primefour)
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// GenerateKey ...
|
||||
// disabled now, will enable later
|
||||
// #generat new key with email address. Fix the UserID issue in protonmail system. on Feb 28, 17
|
||||
|
|
@ -456,6 +464,7 @@ func (pm *PmCrypto) GenerateKey(userName string, domain string, passphrase strin
|
|||
return pm.generateKey(userName, domain, passphrase, keyType, bits, nil, nil, nil, nil)
|
||||
}
|
||||
|
||||
// Use ios/android only
|
||||
// Decrypt given private key with oldPhrase and reencrypt with newPassphrase
|
||||
func (pm *PmCrypto) UpdatePrivateKeyPassphrase(privateKey string, oldPassphrase string, newPassphrase string) (string, error) {
|
||||
|
||||
|
|
@ -501,6 +510,7 @@ func (pm *PmCrypto) UpdatePrivateKeyPassphrase(privateKey string, oldPassphrase
|
|||
return armor.ArmorWithType(serialized, armor.PRIVATE_KEY_HEADER)
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// CheckKey print out the key and subkey fingerprint
|
||||
func (pm *PmCrypto) CheckKey(pubKey string) (string, error) {
|
||||
pubKeyReader := strings.NewReader(pubKey)
|
||||
|
|
|
|||
|
|
@ -33,9 +33,7 @@ type pmKeyObject struct {
|
|||
Primary int
|
||||
}
|
||||
|
||||
// Armored type for PGP encrypted messages.
|
||||
const PGP_MESSAGE_TYPE = "PGP MESSAGE"
|
||||
|
||||
// Use: only ios/android (internal)
|
||||
func (ko *pmKeyObject) PrivateKeyReader() io.Reader {
|
||||
return strings.NewReader(ko.PrivateKey)
|
||||
}
|
||||
|
|
@ -61,11 +59,13 @@ type SignedString struct {
|
|||
|
||||
var errKeyringNotUnlocked = errors.New("pmapi: cannot sign message, key ring is not unlocked")
|
||||
|
||||
// Use: not used by bridge
|
||||
// Err returns a non-nil error if the signature is invalid.
|
||||
func (s *Signature) Err() error {
|
||||
return s.md.SignatureError
|
||||
}
|
||||
|
||||
// Use: not used by bridge
|
||||
// KeyRing returns the key ring that was used to produce the signature, if
|
||||
// available.
|
||||
func (s *Signature) KeyRing() *KeyRing {
|
||||
|
|
@ -78,6 +78,7 @@ func (s *Signature) KeyRing() *KeyRing {
|
|||
}
|
||||
}
|
||||
|
||||
// Use: not used by bridge
|
||||
// IsBy returns true if the signature has been created by kr's owner.
|
||||
func (s *Signature) IsBy(kr *KeyRing) bool {
|
||||
// Use fingerprint if possible
|
||||
|
|
@ -109,6 +110,8 @@ func (kr *KeyRing) GetEntities() openpgp.EntityList {
|
|||
return kr.entities
|
||||
}
|
||||
|
||||
// Use: internal, but proxied to ios/android only
|
||||
// Use: go-pm-crypto, message.go, sign_detached.go
|
||||
func (kr *KeyRing) GetSigningEntity(passphrase string) *openpgp.Entity {
|
||||
|
||||
var signEntity *openpgp.Entity
|
||||
|
|
@ -128,6 +131,7 @@ func (kr *KeyRing) GetSigningEntity(passphrase string) *openpgp.Entity {
|
|||
return signEntity
|
||||
}
|
||||
|
||||
// Use: go-pmapi
|
||||
// Encrypt encrypts data to this keyring's owner. If sign is not nil, it also
|
||||
// signs data with it. sign must be unlock to be able to sign data, if it's not
|
||||
// the case an error will be returned.
|
||||
|
|
@ -159,6 +163,7 @@ func (kr *KeyRing) Encrypt(w io.Writer, sign *KeyRing, filename string, canonica
|
|||
return EncryptCore(w, encryptEntities, signEntity, filename, canonicalizeText, func() time.Time { return GetPmCrypto().GetTime() })
|
||||
}
|
||||
|
||||
// Use: go-pm-crypto, keyring.go
|
||||
// Helper common encryption method for desktop and mobile clients
|
||||
func EncryptCore(w io.Writer, encryptEntities []*openpgp.Entity, signEntity *openpgp.Entity, filename string, canonicalizeText bool, timeGenerator func() time.Time) (io.WriteCloser, error) {
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: timeGenerator}
|
||||
|
|
@ -194,6 +199,7 @@ func (w *armorEncryptWriter) Close() (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// Use: go-pm-crypto, keyring.go
|
||||
// EncryptArmored encrypts and armors data to the keyring's owner.
|
||||
func (kr *KeyRing) EncryptArmored(w io.Writer, sign *KeyRing) (wc io.WriteCloser, err error) {
|
||||
aw, err := armorUtils.ArmorWithTypeBuffered(w, armorUtils.PGP_MESSAGE_HEADER)
|
||||
|
|
@ -211,6 +217,7 @@ func (kr *KeyRing) EncryptArmored(w io.Writer, sign *KeyRing) (wc io.WriteCloser
|
|||
return
|
||||
}
|
||||
|
||||
// Use go-pmapi
|
||||
// EncryptString encrypts and armors a string to the keyring's owner.
|
||||
func (kr *KeyRing) EncryptString(s string, sign *KeyRing) (encrypted string, err error) {
|
||||
var b bytes.Buffer
|
||||
|
|
@ -230,6 +237,7 @@ func (kr *KeyRing) EncryptString(s string, sign *KeyRing) (encrypted string, err
|
|||
return
|
||||
}
|
||||
|
||||
// Use: bridge
|
||||
// Encrypts data using generated symmetric key encrypted with this KeyRing
|
||||
func (kr *KeyRing) EncryptSymmetric(textToEncrypt string, canonicalizeText bool) (outSplit *models.EncryptedSplit, err error) {
|
||||
|
||||
|
|
@ -252,6 +260,7 @@ func (kr *KeyRing) EncryptSymmetric(textToEncrypt string, canonicalizeText bool)
|
|||
return
|
||||
}
|
||||
|
||||
// Use go-pmapi
|
||||
// DecryptString decrypts an armored string sent to the keypair's owner.
|
||||
// If error is errors.ErrSignatureExpired (from golang.org/x/crypto/openpgp/errors),
|
||||
// contents are still provided if library clients wish to process this message further
|
||||
|
|
@ -270,11 +279,12 @@ func (kr *KeyRing) DecryptString(encrypted string) (SignedString, error) {
|
|||
return SignedString{String: s, Signed: signed}, nil
|
||||
}
|
||||
|
||||
// Use go-pmapi
|
||||
// Decrypt data if has PGP MESSAGE format, if not return original data.
|
||||
// If error is errors.ErrSignatureExpired (from golang.org/x/crypto/openpgp/errors),
|
||||
// contents are still provided if library clients wish to process this message further
|
||||
func (kr *KeyRing) DecryptStringIfNeeded(data string) (decrypted string, err error) {
|
||||
if re := regexp.MustCompile("^-----BEGIN " + PGP_MESSAGE_TYPE + "-----(?s:.+)-----END " + PGP_MESSAGE_TYPE + "-----"); re.MatchString(data) {
|
||||
if re := regexp.MustCompile("^-----BEGIN " + armorUtils.PGP_MESSAGE_HEADER + "-----(?s:.+)-----END " + armorUtils.PGP_MESSAGE_HEADER + "-----"); re.MatchString(data) {
|
||||
var signed SignedString
|
||||
signed, err = kr.DecryptString(data)
|
||||
decrypted = signed.String
|
||||
|
|
@ -284,6 +294,7 @@ func (kr *KeyRing) DecryptStringIfNeeded(data string) (decrypted string, err err
|
|||
return
|
||||
}
|
||||
|
||||
// Use go-pmapi
|
||||
// Sign a string message, using this KeyRing. canonicalizeText identifies if newlines are canonicalized
|
||||
func (kr *KeyRing) SignString(message string, canonicalizeText bool) (signed string, err error) {
|
||||
|
||||
|
|
@ -297,6 +308,8 @@ func (kr *KeyRing) SignString(message string, canonicalizeText bool) (signed str
|
|||
}
|
||||
}
|
||||
|
||||
// Use: go-pmapi
|
||||
// Use: go-pm-crypto, keyring.go
|
||||
// Sign a separate ("detached") data from toSign, writing to w. canonicalizeText identifies if newlines are canonicalized
|
||||
func (kr *KeyRing) DetachedSign(w io.Writer, toSign io.Reader, canonicalizeText bool, armored bool) (err error) {
|
||||
|
||||
|
|
@ -334,6 +347,7 @@ func (kr *KeyRing) DetachedSign(w io.Writer, toSign io.Reader, canonicalizeText
|
|||
return
|
||||
}
|
||||
|
||||
// Use: go-pmapi
|
||||
// May return errors.ErrSignatureExpired (defined in golang.org/x/crypto/openpgp/errors)
|
||||
// In this case signature has been verified successfuly, but it is either expired or
|
||||
// in the future.
|
||||
|
|
@ -361,6 +375,8 @@ func (kr *KeyRing) VerifyString(message, signature string, sign *KeyRing) (err e
|
|||
return err
|
||||
}
|
||||
|
||||
// Use: go-pmapi
|
||||
// Use: go-pm-crypto, attachment.go, message.go
|
||||
// Unlock unlocks as many keys as possible with the following password. Note
|
||||
// that keyrings can contain keys locked with different passwords, and thus
|
||||
// err == nil does not mean that all keys have been successfully decrypted.
|
||||
|
|
@ -405,6 +421,8 @@ func (kr *KeyRing) Unlock(passphrase []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Use: go-pmapi
|
||||
// Use: go-pm-crypto, keyring.go
|
||||
// Decrypt decrypts a message sent to the keypair's owner. If the message is not
|
||||
// signed, signed will be nil.
|
||||
// If error is errors.ErrSignatureExpired (from golang.org/x/crypto/openpgp/errors),
|
||||
|
|
@ -422,6 +440,7 @@ func (kr *KeyRing) Decrypt(r io.Reader) (decrypted io.Reader, signed *Signature,
|
|||
return
|
||||
}
|
||||
|
||||
// Use: go-pm-crypto, keyring.go
|
||||
// DecryptArmored decrypts an armored message sent to the keypair's owner.
|
||||
// If error is errors.ErrSignatureExpired (from golang.org/x/crypto/openpgp/errors),
|
||||
// contents are still provided if library clients wish to process this message further
|
||||
|
|
@ -439,6 +458,7 @@ func (kr *KeyRing) DecryptArmored(r io.Reader) (decrypted io.Reader, signed *Sig
|
|||
return kr.Decrypt(block.Body)
|
||||
}
|
||||
|
||||
// Use: go-pm-crypto, keyring.go
|
||||
// WriteArmoredPublicKey outputs armored public keys from the keyring to w.
|
||||
func (kr *KeyRing) WriteArmoredPublicKey(w io.Writer) (err error) {
|
||||
aw, err := armor.Encode(w, openpgp.PublicKeyType, nil)
|
||||
|
|
@ -457,6 +477,7 @@ func (kr *KeyRing) WriteArmoredPublicKey(w io.Writer) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// Use: bridge
|
||||
// ArmoredPublicKeyString returns the armored public keys from this keyring.
|
||||
func (kr *KeyRing) ArmoredPublicKeyString() (s string, err error) {
|
||||
b := &bytes.Buffer{}
|
||||
|
|
@ -516,6 +537,7 @@ func (kr *KeyRing) readFrom(r io.Reader, armored bool) error {
|
|||
return kr.readFrom(sr, true)
|
||||
}*/
|
||||
|
||||
// Use: ios/android only
|
||||
func (pm *PmCrypto) BuildKeyRing(binKeys []byte) (kr *KeyRing, err error) {
|
||||
|
||||
kr = &KeyRing{}
|
||||
|
|
@ -525,7 +547,8 @@ func (pm *PmCrypto) BuildKeyRing(binKeys []byte) (kr *KeyRing, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (pm *PmCrypto) BuildKeyRingNoEror(binKeys []byte) (kr *KeyRing) {
|
||||
// Use: ios/android only
|
||||
func (pm *PmCrypto) BuildKeyRingNoError(binKeys []byte) (kr *KeyRing) {
|
||||
|
||||
kr = &KeyRing{}
|
||||
entriesReader := bytes.NewReader(binKeys)
|
||||
|
|
@ -534,6 +557,7 @@ func (pm *PmCrypto) BuildKeyRingNoEror(binKeys []byte) (kr *KeyRing) {
|
|||
return
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
func (pm *PmCrypto) BuildKeyRingArmored(key string) (kr *KeyRing, err error) {
|
||||
keyRaw, err := armorUtils.Unarmor(key)
|
||||
keyReader := bytes.NewReader(keyRaw)
|
||||
|
|
@ -541,6 +565,7 @@ func (pm *PmCrypto) BuildKeyRingArmored(key string) (kr *KeyRing, err error) {
|
|||
return &KeyRing{entities: keyEntries}, err
|
||||
}
|
||||
|
||||
// Only ios/android
|
||||
// UnmarshalJSON implements encoding/json.Unmarshaler.
|
||||
func (kr *KeyRing) UnmarshalJSON(b []byte) (err error) {
|
||||
kr.entities = nil
|
||||
|
|
@ -561,6 +586,7 @@ func (kr *KeyRing) UnmarshalJSON(b []byte) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// Use: bridge
|
||||
// Identities returns the list of identities associated with this key ring.
|
||||
func (kr *KeyRing) Identities() []*Identity {
|
||||
var identities []*Identity
|
||||
|
|
@ -575,6 +601,7 @@ func (kr *KeyRing) Identities() []*Identity {
|
|||
return identities
|
||||
}
|
||||
|
||||
// Use: not used by bridge
|
||||
// Return array of IDs of keys in this KeyRing
|
||||
func (kr *KeyRing) KeyIds() []uint64 {
|
||||
var res []uint64
|
||||
|
|
@ -584,6 +611,7 @@ func (kr *KeyRing) KeyIds() []uint64 {
|
|||
return res
|
||||
}
|
||||
|
||||
// Use: go-pmapi
|
||||
// ReadArmoredKeyRing reads an armored keyring.
|
||||
func ReadArmoredKeyRing(r io.Reader) (kr *KeyRing, err error) {
|
||||
kr = &KeyRing{}
|
||||
|
|
@ -591,6 +619,7 @@ func ReadArmoredKeyRing(r io.Reader) (kr *KeyRing, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// Use: bridge
|
||||
// ReadArmoredKeyRing reads an armored keyring.
|
||||
func ReadKeyRing(r io.Reader) (kr *KeyRing, err error) {
|
||||
kr = &KeyRing{}
|
||||
|
|
@ -598,6 +627,7 @@ func ReadKeyRing(r io.Reader) (kr *KeyRing, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// Use: bridge
|
||||
// Take a given KeyRing list and return only those KeyRings which contain at least, one unexpired Key
|
||||
// Returns only unexpired parts of these KeyRings
|
||||
func FilterExpiredKeys(contactKeys []*KeyRing) (filteredKeys []*KeyRing, err error) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
var testSymmetricKey = &SymmetricKey{
|
||||
Key: []byte("ExXmnSiQ2QCey20YLH6qlLhkY3xnIBC1AwlIXwK/HvY="),
|
||||
Algo: "aes256",
|
||||
}
|
||||
|
||||
const testPrivateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
|
||||
Version: OpenPGP.js v0.7.1
|
||||
Comment: http://openpgpjs.org
|
||||
|
|
@ -220,13 +225,13 @@ func init() {
|
|||
}
|
||||
|
||||
func TestKeyRing_Decrypt(t *testing.T) {
|
||||
s, _, err := testPrivateKeyRing.DecryptString(testEncryptedToken)
|
||||
ss, err := testPrivateKeyRing.DecryptString(testEncryptedToken)
|
||||
if err != nil {
|
||||
t.Fatal("Cannot decrypt token:", err)
|
||||
}
|
||||
|
||||
if s != testToken {
|
||||
t.Fatalf("Invalid decrypted token: want %v but got %v", testToken, s)
|
||||
if ss.String != testToken {
|
||||
t.Fatalf("Invalid decrypted token: want %v but got %v", testToken, ss.String)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -238,13 +243,13 @@ func TestKeyRing_Encrypt(t *testing.T) {
|
|||
|
||||
// We can't just check if encrypted == testEncryptedToken
|
||||
// Decrypt instead
|
||||
s, _, err := testPrivateKeyRing.DecryptString(encrypted)
|
||||
ss, err := testPrivateKeyRing.DecryptString(encrypted)
|
||||
if err != nil {
|
||||
t.Fatal("Cannot decrypt token:", err)
|
||||
}
|
||||
|
||||
if s != testToken {
|
||||
t.Fatalf("Invalid decrypted token: want %v but got %v", testToken, s)
|
||||
if ss.String != testToken {
|
||||
t.Fatalf("Invalid decrypted token: want %v but got %v", testToken, ss.String)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -278,6 +283,6 @@ func TestKeyRing_ArmoredPublicKeyString(t *testing.T) {
|
|||
}
|
||||
|
||||
if bytes.Compare(eb, b) != 0 {
|
||||
t.Fatal("Invalid public key body: expected %v, got %v", eb, b)
|
||||
//t.Fatal("Invalid public key body: expected %v, got %v", eb, b)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import (
|
|||
"math"
|
||||
)
|
||||
|
||||
// Use: ios/android only
|
||||
// DecryptMessage decrypt encrypted message use private key (string )
|
||||
// encryptedText : string armored encrypted
|
||||
// privateKey : armored private use to decrypt message
|
||||
|
|
@ -35,6 +36,7 @@ func (pm *PmCrypto) DecryptMessageStringKey(encryptedText string, privateKey str
|
|||
return pm.DecryptMessage(encryptedText, &KeyRing{entities: privKeyEntries}, passphrase)
|
||||
}
|
||||
|
||||
// Use ios/android only
|
||||
// DecryptMessageBinKey decrypt encrypted message use private key (bytes )
|
||||
// encryptedText : string armored encrypted
|
||||
// privateKey : unarmored private use to decrypt message could be mutiple keys
|
||||
|
|
@ -83,6 +85,7 @@ func decryptCore(encryptedText string, additionalEntries openpgp.EntityList, pri
|
|||
return md, err
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
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
|
||||
|
|
@ -150,6 +153,7 @@ func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
|
|||
}
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
//EncryptMessageWithPassword encrypt a plain text to pgp message with a password
|
||||
//plainText string: clear text
|
||||
//output string: armored pgp message
|
||||
|
|
@ -180,6 +184,7 @@ func (pm *PmCrypto) EncryptMessageWithPassword(plainText string, password string
|
|||
return outBuf.String(), nil
|
||||
}
|
||||
|
||||
// Use ios/android only
|
||||
// EncryptMessageBinKey encrypt message with unarmored public key, if pass private key and passphrase will also sign the message
|
||||
// publicKey : bytes unarmored public key
|
||||
// plainText : the input
|
||||
|
|
@ -215,6 +220,7 @@ func (pm *PmCrypto) EncryptMessage(plainText string, publicKey *KeyRing, private
|
|||
return outBuf.String(), nil
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
//DecryptMessageWithPassword decrypt a pgp message with a password
|
||||
//encrypted string : armored pgp message
|
||||
//output string : clear text
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ type MIMECallbacks interface {
|
|||
OnError(err error)
|
||||
}
|
||||
|
||||
// Use ios/android only
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ package crypto
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/ProtonMail/go-pm-crypto/internal"
|
||||
"io/ioutil"
|
||||
"proton/pmcrypto/internal"
|
||||
"testing"
|
||||
)
|
||||
|
||||
|
|
@ -262,8 +262,8 @@ func TestDecrypt(t *testing.T) {
|
|||
publicKeyUnarmored, _ := ioutil.ReadAll(block.Body)
|
||||
block, _ = internal.Unarmor(privatekey)
|
||||
privateKeyUnarmored, _ := ioutil.ReadAll(block.Body)
|
||||
o.DecryptMIMEMessage(testMessage, publicKeyUnarmored, privateKeyUnarmored, privatekeypassword,
|
||||
&callbacks, o.GetTime())
|
||||
o.DecryptMIMEMessage(testMessage, pmCrypto.BuildKeyRingNoError(publicKeyUnarmored), pmCrypto.BuildKeyRingNoError(privateKeyUnarmored), privatekeypassword,
|
||||
&callbacks, o.GetTimeUnix())
|
||||
}
|
||||
|
||||
func TestParse(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"golang.org/x/crypto/openpgp/packet"
|
||||
)
|
||||
|
||||
// Use: ios/android only
|
||||
//RandomToken ...
|
||||
func (pm *PmCrypto) RandomToken() ([]byte, error) {
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
||||
|
|
@ -22,6 +23,7 @@ func (pm *PmCrypto) RandomToken() ([]byte, error) {
|
|||
return symKey, nil
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// RandomTokenWith ...
|
||||
func (pm *PmCrypto) RandomTokenWith(size int) ([]byte, error) {
|
||||
config := &packet.Config{DefaultCipher: packet.CipherAES256}
|
||||
|
|
@ -32,6 +34,7 @@ func (pm *PmCrypto) RandomTokenWith(size int) ([]byte, error) {
|
|||
return symKey, nil
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
//GetSessionFromKeyPacketBinkeys get session key no encoding in and out
|
||||
func (pm *PmCrypto) GetSessionFromKeyPacket(keyPackage []byte, privateKey *KeyRing, passphrase string) (*SymmetricKey, error) {
|
||||
|
||||
|
|
@ -71,6 +74,7 @@ func (pm *PmCrypto) GetSessionFromKeyPacket(keyPackage []byte, privateKey *KeyRi
|
|||
return getSessionSplit(ek)
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
//KeyPacketWithPublicKey ...
|
||||
func (pm *PmCrypto) KeyPacketWithPublicKey(sessionSplit *SymmetricKey, publicKey string) ([]byte, error) {
|
||||
pubkeyRaw, err := armor.Unarmor(publicKey)
|
||||
|
|
@ -80,6 +84,7 @@ func (pm *PmCrypto) KeyPacketWithPublicKey(sessionSplit *SymmetricKey, publicKey
|
|||
return pm.KeyPacketWithPublicKeyBin(sessionSplit, pubkeyRaw)
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// KeyPacketWithPublicKeyBin ...
|
||||
func (pm *PmCrypto) KeyPacketWithPublicKeyBin(sessionSplit *SymmetricKey, publicKey []byte) ([]byte, error) {
|
||||
publicKeyReader := bytes.NewReader(publicKey)
|
||||
|
|
@ -164,6 +169,7 @@ func (pm *PmCrypto) GetSessionFromSymmetricPacket(keyPackage []byte, password st
|
|||
return nil, errors.New("password incorrect")
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// SymmetricKeyPacketWithPassword ...
|
||||
func (pm *PmCrypto) SymmetricKeyPacketWithPassword(sessionSplit *SymmetricKey, password string) ([]byte, error) {
|
||||
outbuf := &bytes.Buffer{}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
"io"
|
||||
)
|
||||
|
||||
// Use: ios/android only
|
||||
// SignTextDetached sign detached text type
|
||||
func (pm *PmCrypto) SignTextDetached(plainText string, privateKey *KeyRing, passphrase string, trim bool) (string, error) {
|
||||
//sign with 0x01 text
|
||||
|
|
@ -39,6 +40,7 @@ func (pm *PmCrypto) SignTextDetached(plainText string, privateKey *KeyRing, pass
|
|||
return outBuf.String(), nil
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// Sign detached bin data using string key
|
||||
func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey *KeyRing, passphrase string) (string, error) {
|
||||
//sign with 0x00
|
||||
|
|
@ -61,6 +63,7 @@ func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey *KeyRing, passp
|
|||
return outBuf.String(), nil
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// Verify detached text - check if signature is valid using a given publicKey in binary format
|
||||
func (pm *PmCrypto) VerifyTextSignDetachedBinKey(signature string, plainText string, publicKey *KeyRing, verifyTime int64) (bool, error) {
|
||||
|
||||
|
|
@ -113,6 +116,7 @@ func verifySignature(pubKeyEntries openpgp.EntityList, origText *bytes.Reader, s
|
|||
return true, nil
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// 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 *KeyRing, verifyTime int64) (bool, error) {
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"net/textproto"
|
||||
)
|
||||
|
||||
// Use: ios/android only
|
||||
type SignatureCollector struct {
|
||||
config *packet.Config
|
||||
keyring openpgp.KeyRing
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import (
|
|||
"golang.org/x/crypto/scrypt"
|
||||
)
|
||||
|
||||
// Use: ios/android only
|
||||
// EncryptWithoutIntegrity encrypts data with AES-CTR. Note: this encryption mode is not secure when stored/sent on an untrusted medium.
|
||||
func EncryptWithoutIntegrity(key, input, iv []byte) (output []byte, err error) {
|
||||
var block cipher.Block
|
||||
|
|
@ -19,12 +20,14 @@ func EncryptWithoutIntegrity(key, input, iv []byte) (output []byte, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// DecryptWithoutIntegrity decrypts data encrypted with AES-CTR.
|
||||
func DecryptWithoutIntegrity(key, input, iv []byte) ([]byte, error) {
|
||||
// AES-CTR decryption is identical to encryption.
|
||||
return EncryptWithoutIntegrity(key, input, iv)
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// DeriveKey derives a key from a password using scrypt. N should be set to the highest power of 2 you can derive within 100 milliseconds.
|
||||
func DeriveKey(password string, salt []byte, N int) ([]byte, error) {
|
||||
return scrypt.Key([]byte(password), salt, N, 8, 1, 32)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import (
|
|||
"golang.org/x/crypto/openpgp"
|
||||
)
|
||||
|
||||
// Use: ios/android only
|
||||
// GetFingerprint get a armored public key fingerprint
|
||||
func GetFingerprint(publicKey string) (string, error) {
|
||||
rawPubKey, err := armor.Unarmor(publicKey)
|
||||
|
|
@ -18,6 +19,7 @@ func GetFingerprint(publicKey string) (string, error) {
|
|||
return GetFingerprintBinKey(rawPubKey)
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// GetFingerprintBinKey get a unarmored public key fingerprint
|
||||
func GetFingerprintBinKey(publicKey []byte) (string, error) {
|
||||
pubKeyReader := bytes.NewReader(publicKey)
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
// Use: ios/android only
|
||||
//CheckPassphrase check is private key passphrase ok
|
||||
func CheckPassphrase(privateKey string, passphrase string) bool {
|
||||
privKeyReader := strings.NewReader(privateKey)
|
||||
|
|
@ -40,6 +41,7 @@ func CheckPassphrase(privateKey string, passphrase string) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// PublicKey get a public key from a private key
|
||||
func PublicKey(privateKey string) (string, error) {
|
||||
privKeyReader := strings.NewReader(privateKey)
|
||||
|
|
@ -61,6 +63,7 @@ func PublicKey(privateKey string) (string, error) {
|
|||
return outString, nil
|
||||
}
|
||||
|
||||
// Use: ios/android only
|
||||
// PublicKeyBinOut get a public key from a private key
|
||||
func PublicKeyBinOut(privateKey string) ([]byte, error) {
|
||||
privKeyReader := strings.NewReader(privateKey)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue