fix typo / improve documentatation

This commit is contained in:
William Gotti 2019-05-13 12:33:01 +00:00 committed by Daniel Huigens
parent 701dc26ab5
commit 5cdec38a18
16 changed files with 77 additions and 187 deletions

View file

@ -12,20 +12,17 @@ import (
"io/ioutil" "io/ioutil"
) )
// ArmorKey make bytes input key to armor format // ArmorKey makes bytes input key to armor format
// Use: ios/android only
func ArmorKey(input []byte) (string, error) { func ArmorKey(input []byte) (string, error) {
return ArmorWithType(input, constants.PublicKeyHeader) return ArmorWithType(input, constants.PublicKeyHeader)
} }
// ArmorWithTypeBuffered take input from io.Writer and returns io.WriteCloser which can be read for armored code // ArmorWithTypeBuffered takes input from io.Writer and returns io.WriteCloser which can be read for armored code
// Use: go-pm-crypto, keyring.go
func ArmorWithTypeBuffered(w io.Writer, armorType string) (io.WriteCloser, error) { func ArmorWithTypeBuffered(w io.Writer, armorType string) (io.WriteCloser, error) {
return armor.Encode(w, armorType, nil) return armor.Encode(w, armorType, nil)
} }
// ArmorWithType make bytes input to armor format // ArmorWithType makes bytes input to armor format
// Use: go-pm-crypto
func ArmorWithType(input []byte, armorType string) (string, error) { func ArmorWithType(input []byte, armorType string) (string, error) {
var b bytes.Buffer var b bytes.Buffer
@ -43,7 +40,6 @@ func ArmorWithType(input []byte, armorType string) (string, error) {
} }
// Unarmor an armored key to bytes key // Unarmor an armored key to bytes key
// Use: go-pm-crypto, attachment.go, keyring.go, session.go, message.go
func Unarmor(input string) ([]byte, error) { func Unarmor(input string) ([]byte, error) {
b, err := internal.Unarmor(input) b, err := internal.Unarmor(input)
if err != nil { if err != nil {
@ -52,8 +48,7 @@ func Unarmor(input string) ([]byte, error) {
return ioutil.ReadAll(b.Body) return ioutil.ReadAll(b.Body)
} }
//ReadClearSignedMessage read clear message from a clearsign package (package containing cleartext and signature) // ReadClearSignedMessage reads clear message from a clearsign package (package containing cleartext and signature)
// Use: ios/android only
func ReadClearSignedMessage(signedMessage string) (string, error) { func ReadClearSignedMessage(signedMessage string) (string, error) {
modulusBlock, rest := clearsign.Decode([]byte(signedMessage)) modulusBlock, rest := clearsign.Decode([]byte(signedMessage))
if len(rest) != 0 { if len(rest) != 0 {

View file

@ -13,7 +13,7 @@ import (
"golang.org/x/crypto/openpgp/packet" "golang.org/x/crypto/openpgp/packet"
) )
//EncryptedSplit when encrypt attachment // EncryptedSplit when encrypt attachment
type AttachmentProcessor struct { type AttachmentProcessor struct {
w *io.WriteCloser w *io.WriteCloser
pipe *io.PipeWriter pipe *io.PipeWriter
@ -23,12 +23,12 @@ type AttachmentProcessor struct {
err error err error
} }
// Use: ios/android only // Process allows the attachment processor to write the encrypted attachment
func (ap *AttachmentProcessor) Process(plainData []byte) { func (ap *AttachmentProcessor) Process(plainData []byte) {
(*ap.w).Write(plainData) (*ap.w).Write(plainData)
} }
// Use: ios/android only // Finish attachment process
func (ap *AttachmentProcessor) Finish() (*models.EncryptedSplit, error) { func (ap *AttachmentProcessor) Finish() (*models.EncryptedSplit, error) {
if ap.err != nil { if ap.err != nil {
return nil, ap.err return nil, ap.err
@ -42,8 +42,7 @@ func (ap *AttachmentProcessor) Finish() (*models.EncryptedSplit, error) {
return ap.split, nil return ap.split, nil
} }
// Use: ios/android only // Encrypts attachment. Takes input data and key data in binary form
// 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) { func (pm *PmCrypto) encryptAttachment(estimatedSize int, fileName string, publicKey *KeyRing, garbageCollector int) (*AttachmentProcessor, error) {
attachmentProc := &AttachmentProcessor{} attachmentProc := &AttachmentProcessor{}
// you can also add these one at // you can also add these one at
@ -84,7 +83,7 @@ func (pm *PmCrypto) encryptAttachment(estimatedSize int, fileName string, public
return attachmentProc, nil return attachmentProc, nil
} }
// Use: ios/android only // EncryptAttachment encrypts attachment. Takes input data and key data in binary form
func (pm *PmCrypto) EncryptAttachment(plainData []byte, fileName string, publicKey *KeyRing) (*models.EncryptedSplit, error) { func (pm *PmCrypto) EncryptAttachment(plainData []byte, fileName string, publicKey *KeyRing) (*models.EncryptedSplit, error) {
ap, err := pm.encryptAttachment(len(plainData), fileName, publicKey, -1) ap, err := pm.encryptAttachment(len(plainData), fileName, publicKey, -1)
if err != nil { if err != nil {
@ -99,15 +98,13 @@ func (pm *PmCrypto) EncryptAttachment(plainData []byte, fileName string, publicK
} }
// Use: ios/android only // EncryptAttachmentLowMemory ...
//EncryptAttachment ...
func (pm *PmCrypto) EncryptAttachmentLowMemory(estimatedSize int, fileName string, publicKey *KeyRing) (*AttachmentProcessor, error) { func (pm *PmCrypto) EncryptAttachmentLowMemory(estimatedSize int, fileName string, publicKey *KeyRing) (*AttachmentProcessor, error) {
// Garbage collect every megabyte // Garbage collect every megabyte
return pm.encryptAttachment(estimatedSize, fileName, publicKey, 1<<20) return pm.encryptAttachment(estimatedSize, fileName, publicKey, 1<<20)
} }
// Helper method. Splits armored pgp session into key and packet data // SplitArmor is a Helper method. Splits armored pgp session into key and packet data
// Use: ios/android only
func SplitArmor(encrypted string) (*models.EncryptedSplit, error) { func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
var err error var err error
@ -121,7 +118,6 @@ func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
return SeparateKeyAndData(nil, encryptedReader, len(encrypted), -1) return SeparateKeyAndData(nil, encryptedReader, len(encrypted), -1)
} }
// 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 // 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) { func (pm *PmCrypto) DecryptAttachment(keyPacket []byte, dataPacket []byte, kr *KeyRing, passphrase string) ([]byte, error) {

View file

@ -24,7 +24,6 @@ import (
// SymmetricKey stores a decrypted session key. // SymmetricKey stores a decrypted session key.
type SymmetricKey struct { type SymmetricKey struct {
// The clear base64-encoded key. // The clear base64-encoded key.
//Key string
Key []byte Key []byte
// The algorithm used by this key. // The algorithm used by this key.
Algo string Algo string
@ -42,8 +41,7 @@ var symKeyAlgos = map[string]packet.CipherFunction{
"aes256": packet.CipherAES256, "aes256": packet.CipherAES256,
} }
// GetCipherFunc returns functin corresponding to an algorithm used in this SymmetricKey // GetCipherFunc returns function corresponding to an algorithm used in this SymmetricKey
// Use: go-pm-crypto, key.go, session.go
func (sk *SymmetricKey) GetCipherFunc() packet.CipherFunction { func (sk *SymmetricKey) GetCipherFunc() packet.CipherFunction {
cf, ok := symKeyAlgos[sk.Algo] cf, ok := symKeyAlgos[sk.Algo]
if ok { if ok {
@ -54,7 +52,6 @@ func (sk *SymmetricKey) GetCipherFunc() packet.CipherFunction {
} }
// GetBase64Key returns a key as base64 encoded string // GetBase64Key returns a key as base64 encoded string
// Use: bridge
func (sk *SymmetricKey) GetBase64Key() string { func (sk *SymmetricKey) GetBase64Key() string {
return base64.StdEncoding.EncodeToString(sk.Key) return base64.StdEncoding.EncodeToString(sk.Key)
} }
@ -77,8 +74,7 @@ func newSymmetricKey(ek *packet.EncryptedKey) *SymmetricKey {
} }
} }
// DecryptAttKey and return a symmetric key // DecryptAttKey and returns a symmetric key
// Use: bridge
func DecryptAttKey(kr *KeyRing, keyPacket string) (key *SymmetricKey, err error) { func DecryptAttKey(kr *KeyRing, keyPacket string) (key *SymmetricKey, err error) {
r := base64.NewDecoder(base64.StdEncoding, strings.NewReader(keyPacket)) r := base64.NewDecoder(base64.StdEncoding, strings.NewReader(keyPacket))
packets := packet.NewReader(r) packets := packet.NewReader(r)
@ -112,7 +108,6 @@ func DecryptAttKey(kr *KeyRing, keyPacket string) (key *SymmetricKey, err error)
} }
// SeparateKeyAndData from packets in a pgp session // SeparateKeyAndData from packets in a pgp session
// Use: bridge, ios/android, go-pm-crypto, attachment.go, keyring.go
func SeparateKeyAndData(kr *KeyRing, r io.Reader, estimatedLength int, garbageCollector int) (outSplit *models.EncryptedSplit, err error) { func SeparateKeyAndData(kr *KeyRing, r io.Reader, estimatedLength int, garbageCollector int) (outSplit *models.EncryptedSplit, err error) {
// For info on each, see: https://golang.org/pkg/runtime/#MemStats // For info on each, see: https://golang.org/pkg/runtime/#MemStats
packets := packet.NewReader(r) packets := packet.NewReader(r)
@ -209,10 +204,6 @@ func SeparateKeyAndData(kr *KeyRing, r io.Reader, estimatedLength int, garbageCo
err = errors.New("pm-crypto: packets don't include an encrypted key packet") err = errors.New("pm-crypto: packets don't include an encrypted key packet")
return return
} }
/*if ek.Key == nil {
err = errors.New("pm-crypto: could not find any key to decrypt key")
return
}*/
if kr == nil { if kr == nil {
var buf bytes.Buffer var buf bytes.Buffer
@ -227,38 +218,13 @@ func SeparateKeyAndData(kr *KeyRing, r io.Reader, estimatedLength int, garbageCo
return outSplit, nil 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. // SetKey encrypts the provided key.
// Use: bridge
func SetKey(kr *KeyRing, symKey *SymmetricKey) (packets string, err error) { func SetKey(kr *KeyRing, symKey *SymmetricKey) (packets string, err error) {
b := &bytes.Buffer{} b := &bytes.Buffer{}
w := base64.NewEncoder(base64.StdEncoding, b) w := base64.NewEncoder(base64.StdEncoding, b)
cf := symKey.GetCipherFunc() cf := symKey.GetCipherFunc()
//k, err := base64.StdEncoding.DecodeString(symKey.Key)
//if err != nil {
// err = fmt.Errorf("pm-crypto: cannot set key: %v", err)
// return
//}
if len(kr.entities) == 0 { if len(kr.entities) == 0 {
err = fmt.Errorf("pm-crypto: cannot set key: key ring is empty") err = fmt.Errorf("pm-crypto: cannot set key: key ring is empty")
return return
@ -305,7 +271,6 @@ func SetKey(kr *KeyRing, symKey *SymmetricKey) (packets string, err error) {
} }
// IsKeyExpiredBin checks if the given key is expired. Input in binary format // IsKeyExpiredBin checks if the given key is expired. Input in binary format
//Use: ios/android only
func (pm *PmCrypto) IsKeyExpiredBin(publicKey []byte) (bool, error) { func (pm *PmCrypto) IsKeyExpiredBin(publicKey []byte) (bool, error) {
now := pm.getNow() now := pm.getNow()
pubKeyReader := bytes.NewReader(publicKey) pubKeyReader := bytes.NewReader(publicKey)
@ -365,7 +330,6 @@ const (
) )
// IsKeyExpired checks if the given key is expired. Input in armored format // IsKeyExpired checks if the given key is expired. Input in armored format
// Use: ios/android only
func (pm *PmCrypto) IsKeyExpired(publicKey string) (bool, error) { func (pm *PmCrypto) IsKeyExpired(publicKey string) (bool, error) {
rawPubKey, err := armor.Unarmor(publicKey) rawPubKey, err := armor.Unarmor(publicKey)
if err != nil { if err != nil {
@ -378,7 +342,7 @@ func (pm *PmCrypto) generateKey(userName string, domain string, passphrase strin
prime1 []byte, prime2 []byte, prime3 []byte, prime4 []byte) (string, error) { prime1 []byte, prime2 []byte, prime3 []byte, prime4 []byte) (string, error) {
if len(userName) <= 0 { if len(userName) <= 0 {
return "", errors.New("Invalid user name format") return "", errors.New("invalid user name format")
} }
var email = userName var email = userName
@ -447,7 +411,6 @@ func (pm *PmCrypto) generateKey(userName string, domain string, passphrase strin
} }
// GenerateRSAKeyWithPrimes generates RSA key with given primes. // GenerateRSAKeyWithPrimes generates RSA key with given primes.
// Use: TODO
func (pm *PmCrypto) GenerateRSAKeyWithPrimes( func (pm *PmCrypto) GenerateRSAKeyWithPrimes(
userName, domain, passphrase string, userName, domain, passphrase string,
bits int, bits int,
@ -457,19 +420,11 @@ func (pm *PmCrypto) GenerateRSAKeyWithPrimes(
} }
// GenerateKey and generate primes // GenerateKey and generate primes
// TODO: is it really disabled -> no this is used by android
// disabled now, will enable later
// #generat new key with email address. Fix the UserID issue in protonmail system. on Feb 28, 17
// #static generate_key_with_email(email : string, passphrase : string, bits : i32) : open_pgp_key;
// # generate new key
// #static generate_new_key(user_id : string, email : string, passphrase : string, bits : i32) : open_pgp_key;
// Use: ios/android only
func (pm *PmCrypto) GenerateKey(userName string, domain string, passphrase string, keyType string, bits int) (string, error) { func (pm *PmCrypto) GenerateKey(userName string, domain string, passphrase string, keyType string, bits int) (string, error) {
return pm.generateKey(userName, domain, passphrase, keyType, bits, nil, nil, nil, nil) return pm.generateKey(userName, domain, passphrase, keyType, bits, nil, nil, nil, nil)
} }
// UpdatePrivateKeyPassphrase decrypts the given private key with oldPhrase and reencrypt with the newPassphrase // UpdatePrivateKeyPassphrase decrypts the given private key with oldPhrase and re-encrypts with the newPassphrase
// Use ios/android only
func (pm *PmCrypto) UpdatePrivateKeyPassphrase(privateKey string, oldPassphrase string, newPassphrase string) (string, error) { func (pm *PmCrypto) UpdatePrivateKeyPassphrase(privateKey string, oldPassphrase string, newPassphrase string) (string, error) {
privKey := strings.NewReader(privateKey) privKey := strings.NewReader(privateKey)
privKeyEntries, err := openpgp.ReadArmoredKeyRing(privKey) privKeyEntries, err := openpgp.ReadArmoredKeyRing(privKey)
@ -513,8 +468,7 @@ func (pm *PmCrypto) UpdatePrivateKeyPassphrase(privateKey string, oldPassphrase
return armor.ArmorWithType(serialized, constants.PrivateKeyHeader) return armor.ArmorWithType(serialized, constants.PrivateKeyHeader)
} }
// CheckKey print out the key and subkey fingerprint // CheckKey prints out the key and subkey fingerprint
// Use: ios/android only
func (pm *PmCrypto) CheckKey(pubKey string) (string, error) { func (pm *PmCrypto) CheckKey(pubKey string) (string, error) {
pubKeyReader := strings.NewReader(pubKey) pubKeyReader := strings.NewReader(pubKey)
entries, err := openpgp.ReadArmoredKeyRing(pubKeyReader) entries, err := openpgp.ReadArmoredKeyRing(pubKeyReader)

View file

@ -35,7 +35,7 @@ type pmKeyObject struct {
Primary int Primary int
} }
// Use: only ios/android (internal) // PrivateKeyReader
func (ko *pmKeyObject) PrivateKeyReader() io.Reader { func (ko *pmKeyObject) PrivateKeyReader() io.Reader {
return strings.NewReader(ko.PrivateKey) return strings.NewReader(ko.PrivateKey)
} }
@ -63,14 +63,12 @@ type SignedString struct {
var errKeyringNotUnlocked = errors.New("pm-crypto: cannot sign message, key ring is not unlocked") var errKeyringNotUnlocked = errors.New("pm-crypto: cannot sign message, key ring is not unlocked")
// Err returns a non-nil error if the signature is invalid. // Err returns a non-nil error if the signature is invalid.
// Use: not used by bridge
func (s *Signature) Err() error { func (s *Signature) Err() error {
return s.md.SignatureError return s.md.SignatureError
} }
// KeyRing returns the key ring that was used to produce the signature, if // KeyRing returns the key ring that was used to produce the signature, if
// available. // available.
// Use: not used by bridge
func (s *Signature) KeyRing() *KeyRing { func (s *Signature) KeyRing() *KeyRing {
if s.md.SignedBy == nil { if s.md.SignedBy == nil {
return nil return nil
@ -82,7 +80,6 @@ func (s *Signature) KeyRing() *KeyRing {
} }
// IsBy returns true if the signature has been created by kr's owner. // IsBy returns true if the signature has been created by kr's owner.
// Use: not used by bridge
func (s *Signature) IsBy(kr *KeyRing) bool { func (s *Signature) IsBy(kr *KeyRing) bool {
// Use fingerprint if possible // Use fingerprint if possible
if s.md.SignedBy != nil { if s.md.SignedBy != nil {
@ -117,8 +114,6 @@ func (kr *KeyRing) GetEntities() openpgp.EntityList {
} }
// GetSigningEntity returns first private signing entity from keyring // GetSigningEntity returns first private signing entity from keyring
// 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 { func (kr *KeyRing) GetSigningEntity(passphrase string) *openpgp.Entity {
var signEntity *openpgp.Entity var signEntity *openpgp.Entity
@ -140,7 +135,6 @@ func (kr *KeyRing) GetSigningEntity(passphrase string) *openpgp.Entity {
// Encrypt encrypts data to this keyring's owner. If sign is not nil, it also // 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 // 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. // the case an error will be returned.
// Use: go-pmapi
func (kr *KeyRing) Encrypt(w io.Writer, sign *KeyRing, filename string, canonicalizeText bool) (io.WriteCloser, error) { func (kr *KeyRing) Encrypt(w io.Writer, sign *KeyRing, filename string, canonicalizeText bool) (io.WriteCloser, error) {
// The API returns keys sorted by descending priority // The API returns keys sorted by descending priority
// Only encrypt to the first one // Only encrypt to the first one
@ -170,7 +164,6 @@ func (kr *KeyRing) Encrypt(w io.Writer, sign *KeyRing, filename string, canonica
} }
// EncryptCore is common encryption method for desktop and mobile clients // EncryptCore is common encryption method for desktop and mobile clients
// Use: go-pm-crypto, keyring.go
func EncryptCore(w io.Writer, encryptEntities []*openpgp.Entity, signEntity *openpgp.Entity, filename string, canonicalizeText bool, timeGenerator func() time.Time) (io.WriteCloser, error) { 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} config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: timeGenerator}
@ -190,7 +183,7 @@ type armorEncryptWriter struct {
ew io.WriteCloser // Encrypted writer ew io.WriteCloser // Encrypted writer
} }
// Encrypt data // Write encrypted data
func (w *armorEncryptWriter) Write(b []byte) (n int, err error) { func (w *armorEncryptWriter) Write(b []byte) (n int, err error) {
return w.ew.Write(b) return w.ew.Write(b)
} }
@ -205,7 +198,6 @@ func (w *armorEncryptWriter) Close() (err error) {
} }
// EncryptArmored encrypts and armors data to the keyring's owner. // EncryptArmored encrypts and armors data to the keyring's owner.
// Use: go-pm-crypto, keyring.go
func (kr *KeyRing) EncryptArmored(w io.Writer, sign *KeyRing) (wc io.WriteCloser, err error) { func (kr *KeyRing) EncryptArmored(w io.Writer, sign *KeyRing) (wc io.WriteCloser, err error) {
aw, err := armorUtils.ArmorWithTypeBuffered(w, constants.PGPMessageHeader) aw, err := armorUtils.ArmorWithTypeBuffered(w, constants.PGPMessageHeader)
if err != nil { if err != nil {
@ -223,7 +215,6 @@ func (kr *KeyRing) EncryptArmored(w io.Writer, sign *KeyRing) (wc io.WriteCloser
} }
// EncryptString encrypts and armors a string to the keyring's owner. // EncryptString encrypts and armors a string to the keyring's owner.
// Use go-pmapi
func (kr *KeyRing) EncryptString(s string, sign *KeyRing) (encrypted string, err error) { func (kr *KeyRing) EncryptString(s string, sign *KeyRing) (encrypted string, err error) {
var b bytes.Buffer var b bytes.Buffer
w, err := kr.EncryptArmored(&b, sign) w, err := kr.EncryptArmored(&b, sign)
@ -243,7 +234,6 @@ func (kr *KeyRing) EncryptString(s string, sign *KeyRing) (encrypted string, err
} }
// EncryptSymmetric data using generated symmetric key encrypted with this KeyRing // EncryptSymmetric data using generated symmetric key encrypted with this KeyRing
// Use: bridge
func (kr *KeyRing) EncryptSymmetric(textToEncrypt string, canonicalizeText bool) (outSplit *models.EncryptedSplit, err error) { func (kr *KeyRing) EncryptSymmetric(textToEncrypt string, canonicalizeText bool) (outSplit *models.EncryptedSplit, err error) {
var encryptedWriter io.WriteCloser var encryptedWriter io.WriteCloser
buffer := &bytes.Buffer{} buffer := &bytes.Buffer{}
@ -267,7 +257,6 @@ func (kr *KeyRing) EncryptSymmetric(textToEncrypt string, canonicalizeText bool)
// DecryptString decrypts an armored string sent to the keypair's owner. // DecryptString decrypts an armored string sent to the keypair's owner.
// If error is errors.ErrSignatureExpired (from golang.org/x/crypto/openpgp/errors), // 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 // contents are still provided if library clients wish to process this message further
// Use go-pmapi
func (kr *KeyRing) DecryptString(encrypted string) (SignedString, error) { func (kr *KeyRing) DecryptString(encrypted string) (SignedString, error) {
r, signed, err := kr.DecryptArmored(strings.NewReader(encrypted)) r, signed, err := kr.DecryptArmored(strings.NewReader(encrypted))
if err != nil && err != pgperrors.ErrSignatureExpired { if err != nil && err != pgperrors.ErrSignatureExpired {
@ -286,7 +275,6 @@ func (kr *KeyRing) DecryptString(encrypted string) (SignedString, error) {
// DecryptStringIfNeeded data if has armored PGP message format, if not return original data. // DecryptStringIfNeeded data if has armored PGP message format, if not return original data.
// If error is errors.ErrSignatureExpired (from golang.org/x/crypto/openpgp/errors), // 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 // contents are still provided if library clients wish to process this message further
// Use go-pmapi
func (kr *KeyRing) DecryptStringIfNeeded(data string) (decrypted string, err error) { func (kr *KeyRing) DecryptStringIfNeeded(data string) (decrypted string, err error) {
if re := regexp.MustCompile("^-----BEGIN " + constants.PGPMessageHeader + "-----(?s:.+)-----END " + constants.PGPMessageHeader + "-----"); re.MatchString(data) { if re := regexp.MustCompile("^-----BEGIN " + constants.PGPMessageHeader + "-----(?s:.+)-----END " + constants.PGPMessageHeader + "-----"); re.MatchString(data) {
var signed SignedString var signed SignedString
@ -298,8 +286,7 @@ func (kr *KeyRing) DecryptStringIfNeeded(data string) (decrypted string, err err
return return
} }
// SignString sings a string message, using this KeyRing. canonicalizeText identifies if newlines are canonicalized // SignString signs a string message, using this KeyRing. canonicalizeText identifies if newlines are canonicalized
// Use go-pmapi
func (kr *KeyRing) SignString(message string, canonicalizeText bool) (signed string, err error) { func (kr *KeyRing) SignString(message string, canonicalizeText bool) (signed string, err error) {
var sig bytes.Buffer var sig bytes.Buffer
err = kr.DetachedSign(&sig, strings.NewReader(message), canonicalizeText, true) err = kr.DetachedSign(&sig, strings.NewReader(message), canonicalizeText, true)
@ -312,8 +299,6 @@ func (kr *KeyRing) SignString(message string, canonicalizeText bool) (signed str
// DetachedSign will sign a separate ("detached") data from toSign, writing to // DetachedSign will sign a separate ("detached") data from toSign, writing to
// w writer. The canonicalizeText identifies if newlines are canonicalized // w writer. The canonicalizeText identifies if newlines are canonicalized
// Use: go-pmapi
// Use: go-pm-crypto, keyring.go
func (kr *KeyRing) DetachedSign(w io.Writer, toSign io.Reader, canonicalizeText bool, armored bool) (err error) { func (kr *KeyRing) DetachedSign(w io.Writer, toSign io.Reader, canonicalizeText bool, armored bool) (err error) {
var signEntity *openpgp.Entity var signEntity *openpgp.Entity
for _, e := range kr.entities { for _, e := range kr.entities {
@ -351,8 +336,7 @@ func (kr *KeyRing) DetachedSign(w io.Writer, toSign io.Reader, canonicalizeText
// VerifyString may return errors.ErrSignatureExpired (defined in // VerifyString may return errors.ErrSignatureExpired (defined in
// golang.org/x/crypto/openpgp/errors) In this case signature has been verified // golang.org/x/crypto/openpgp/errors) In this case signature has been verified
// successfuly, but it is either expired or in the future. // successfully, but it is either expired or in the future.
// Use: go-pmapi
func (kr *KeyRing) VerifyString(message, signature string, sign *KeyRing) (err error) { func (kr *KeyRing) VerifyString(message, signature string, sign *KeyRing) (err error) {
messageReader := strings.NewReader(message) messageReader := strings.NewReader(message)
signatureReader := strings.NewReader(signature) signatureReader := strings.NewReader(signature)
@ -381,8 +365,6 @@ func (kr *KeyRing) VerifyString(message, signature string, sign *KeyRing) (err e
// err == nil does not mean that all keys have been successfully decrypted. // err == nil does not mean that all keys have been successfully decrypted.
// If err != nil, the password is wrong for every key, and err is the last error // If err != nil, the password is wrong for every key, and err is the last error
// encountered. // encountered.
// Use: go-pmapi
// Use: go-pm-crypto, attachment.go, message.go
func (kr *KeyRing) Unlock(passphrase []byte) error { func (kr *KeyRing) Unlock(passphrase []byte) error {
// Build a list of keys to decrypt // Build a list of keys to decrypt
var keys []*packet.PrivateKey var keys []*packet.PrivateKey
@ -426,8 +408,6 @@ func (kr *KeyRing) Unlock(passphrase []byte) error {
// signed, signed will be nil. // signed, signed will be nil.
// If error is errors.ErrSignatureExpired (from golang.org/x/crypto/openpgp/errors), // 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 // contents are still provided if library clients wish to process this message further
// Use: go-pmapi
// Use: go-pm-crypto, keyring.go
func (kr *KeyRing) Decrypt(r io.Reader) (decrypted io.Reader, signed *Signature, err error) { func (kr *KeyRing) Decrypt(r io.Reader) (decrypted io.Reader, signed *Signature, err error) {
md, err := openpgp.ReadMessage(r, kr.entities, nil, nil) md, err := openpgp.ReadMessage(r, kr.entities, nil, nil)
if err != nil && err != pgperrors.ErrSignatureExpired { if err != nil && err != pgperrors.ErrSignatureExpired {
@ -444,7 +424,6 @@ func (kr *KeyRing) Decrypt(r io.Reader) (decrypted io.Reader, signed *Signature,
// DecryptArmored decrypts an armored message sent to the keypair's owner. // DecryptArmored decrypts an armored message sent to the keypair's owner.
// If error is errors.ErrSignatureExpired (from golang.org/x/crypto/openpgp/errors), // 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 // contents are still provided if library clients wish to process this message further
// Use: go-pm-crypto, keyring.go
func (kr *KeyRing) DecryptArmored(r io.Reader) (decrypted io.Reader, signed *Signature, err error) { func (kr *KeyRing) DecryptArmored(r io.Reader) (decrypted io.Reader, signed *Signature, err error) {
block, err := armor.Decode(r) block, err := armor.Decode(r)
if err != nil && err != pgperrors.ErrSignatureExpired { if err != nil && err != pgperrors.ErrSignatureExpired {
@ -460,7 +439,6 @@ func (kr *KeyRing) DecryptArmored(r io.Reader) (decrypted io.Reader, signed *Sig
} }
// WriteArmoredPublicKey outputs armored public keys from the keyring to w. // WriteArmoredPublicKey outputs armored public keys from the keyring to w.
// Use: go-pm-crypto, keyring.go
func (kr *KeyRing) WriteArmoredPublicKey(w io.Writer) (err error) { func (kr *KeyRing) WriteArmoredPublicKey(w io.Writer) (err error) {
aw, err := armor.Encode(w, openpgp.PublicKeyType, nil) aw, err := armor.Encode(w, openpgp.PublicKeyType, nil)
if err != nil { if err != nil {
@ -479,7 +457,6 @@ func (kr *KeyRing) WriteArmoredPublicKey(w io.Writer) (err error) {
} }
// ArmoredPublicKeyString returns the armored public keys from this keyring. // ArmoredPublicKeyString returns the armored public keys from this keyring.
// Use: bridge
func (kr *KeyRing) ArmoredPublicKeyString() (s string, err error) { func (kr *KeyRing) ArmoredPublicKeyString() (s string, err error) {
b := &bytes.Buffer{} b := &bytes.Buffer{}
if err = kr.WriteArmoredPublicKey(b); err != nil { if err = kr.WriteArmoredPublicKey(b); err != nil {
@ -533,7 +510,6 @@ func (kr *KeyRing) readFrom(r io.Reader, armored bool) error {
} }
// BuildKeyRing reads keyring from binary data // BuildKeyRing reads keyring from binary data
// Use: ios/android only
func (pm *PmCrypto) BuildKeyRing(binKeys []byte) (kr *KeyRing, err error) { func (pm *PmCrypto) BuildKeyRing(binKeys []byte) (kr *KeyRing, err error) {
kr = &KeyRing{} kr = &KeyRing{}
entriesReader := bytes.NewReader(binKeys) entriesReader := bytes.NewReader(binKeys)
@ -543,14 +519,12 @@ func (pm *PmCrypto) BuildKeyRing(binKeys []byte) (kr *KeyRing, err error) {
} }
// BuildKeyRingNoError does not return error on fail // BuildKeyRingNoError does not return error on fail
// Use: ios/android only
func (pm *PmCrypto) BuildKeyRingNoError(binKeys []byte) (kr *KeyRing) { func (pm *PmCrypto) BuildKeyRingNoError(binKeys []byte) (kr *KeyRing) {
kr, _ = pm.BuildKeyRing(binKeys) kr, _ = pm.BuildKeyRing(binKeys)
return return
} }
// BuildKeyRingArmored reads armored string and returns keyring // BuildKeyRingArmored reads armored string and returns keyring
// Use: ios/android only
func (pm *PmCrypto) BuildKeyRingArmored(key string) (kr *KeyRing, err error) { func (pm *PmCrypto) BuildKeyRingArmored(key string) (kr *KeyRing, err error) {
keyRaw, err := armorUtils.Unarmor(key) keyRaw, err := armorUtils.Unarmor(key)
keyReader := bytes.NewReader(keyRaw) keyReader := bytes.NewReader(keyRaw)
@ -559,8 +533,6 @@ func (pm *PmCrypto) BuildKeyRingArmored(key string) (kr *KeyRing, err error) {
} }
// UnmarshalJSON implements encoding/json.Unmarshaler. // UnmarshalJSON implements encoding/json.Unmarshaler.
// Use: go-pmapi
// Use: ios/android
func (kr *KeyRing) UnmarshalJSON(b []byte) (err error) { func (kr *KeyRing) UnmarshalJSON(b []byte) (err error) {
kr.entities = nil kr.entities = nil
@ -584,7 +556,6 @@ func (kr *KeyRing) UnmarshalJSON(b []byte) (err error) {
} }
// Identities returns the list of identities associated with this key ring. // Identities returns the list of identities associated with this key ring.
// Use: bridge
func (kr *KeyRing) Identities() []*Identity { func (kr *KeyRing) Identities() []*Identity {
var identities []*Identity var identities []*Identity
for _, e := range kr.entities { for _, e := range kr.entities {
@ -599,7 +570,6 @@ func (kr *KeyRing) Identities() []*Identity {
} }
// KeyIds returns array of IDs of keys in this KeyRing // KeyIds returns array of IDs of keys in this KeyRing
// Use: not used by bridge
func (kr *KeyRing) KeyIds() []uint64 { func (kr *KeyRing) KeyIds() []uint64 {
var res []uint64 var res []uint64
for _, e := range kr.entities { for _, e := range kr.entities {
@ -609,7 +579,6 @@ func (kr *KeyRing) KeyIds() []uint64 {
} }
// ReadArmoredKeyRing reads an armored data into keyring. // ReadArmoredKeyRing reads an armored data into keyring.
// Use: go-pmapi
func ReadArmoredKeyRing(r io.Reader) (kr *KeyRing, err error) { func ReadArmoredKeyRing(r io.Reader) (kr *KeyRing, err error) {
kr = &KeyRing{} kr = &KeyRing{}
err = kr.readFrom(r, true) err = kr.readFrom(r, true)
@ -617,7 +586,6 @@ func ReadArmoredKeyRing(r io.Reader) (kr *KeyRing, err error) {
} }
// ReadKeyRing reads an binary data into keyring. // ReadKeyRing reads an binary data into keyring.
// Use: bridge
func ReadKeyRing(r io.Reader) (kr *KeyRing, err error) { func ReadKeyRing(r io.Reader) (kr *KeyRing, err error) {
kr = &KeyRing{} kr = &KeyRing{}
err = kr.readFrom(r, false) err = kr.readFrom(r, false)
@ -627,7 +595,6 @@ func ReadKeyRing(r io.Reader) (kr *KeyRing, err error) {
// FilterExpiredKeys takes a given KeyRing list and it returns only those // FilterExpiredKeys takes a given KeyRing list and it returns only those
// KeyRings which contain at least, one unexpired Key. It returns only unexpired // KeyRings which contain at least, one unexpired Key. It returns only unexpired
// parts of these KeyRings // parts of these KeyRings
// Use: bridge
func FilterExpiredKeys(contactKeys []*KeyRing) (filteredKeys []*KeyRing, err error) { func FilterExpiredKeys(contactKeys []*KeyRing) (filteredKeys []*KeyRing, err error) {
now := time.Now() now := time.Now()
hasExpiredEntity := false hasExpiredEntity := false

View file

@ -19,11 +19,10 @@ import (
"github.com/ProtonMail/go-pm-crypto/models" "github.com/ProtonMail/go-pm-crypto/models"
) )
// DecryptMessageStringKey decrypt encrypted message use private key (string ) // DecryptMessageStringKey decrypts encrypted message use private key (string )
// encryptedText : string armored encrypted // encryptedText : string armored encrypted
// privateKey : armored private use to decrypt message // privateKey : armored private use to decrypt message
// passphrase : match with private key to decrypt message // passphrase : match with private key to decrypt message
// Use: ios/android only
func (pm *PmCrypto) DecryptMessageStringKey(encryptedText string, privateKey string, passphrase string) (string, error) { func (pm *PmCrypto) DecryptMessageStringKey(encryptedText string, privateKey string, passphrase string) (string, error) {
privKeyRaw, err := armorUtils.Unarmor(privateKey) privKeyRaw, err := armorUtils.Unarmor(privateKey)
if err != nil { if err != nil {
@ -40,9 +39,8 @@ func (pm *PmCrypto) DecryptMessageStringKey(encryptedText string, privateKey str
// DecryptMessage decrypts encrypted string using keyring // DecryptMessage decrypts encrypted string using keyring
// encryptedText : string armored encrypted // encryptedText : string armored encrypted
// privateKey : keyring with private key to decrypt message, could be mutiple keys // privateKey : keyring with private key to decrypt message, could be multiple keys
// passphrase : match with private key to decrypt message // passphrase : match with private key to decrypt message
// Use ios/android only
func (pm *PmCrypto) DecryptMessage(encryptedText string, privateKey *KeyRing, passphrase string) (string, error) { func (pm *PmCrypto) DecryptMessage(encryptedText string, privateKey *KeyRing, passphrase string) (string, error) {
md, err := decryptCore(encryptedText, nil, privateKey, passphrase, pm.getTimeGenerator()) md, err := decryptCore(encryptedText, nil, privateKey, passphrase, pm.getTimeGenerator())
if err != nil { if err != nil {
@ -85,12 +83,12 @@ func decryptCore(encryptedText string, additionalEntries openpgp.EntityList, pri
return md, err return md, err
} }
// Use: ios/android only // DecryptMessageVerify decrypts message and verify the signature
// encryptedText: string armored encrypted
// verifierKey []byte: unarmored verifier keys
// privateKeyRing []byte: unarmored private key to decrypt. could be multiple
// passphrase: match with private key to decrypt message
func (pm *PmCrypto) DecryptMessageVerify(encryptedText string, verifierKey *KeyRing, 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 := &models.DecryptSignedVerify{}
out.Verify = failed out.Verify = failed
@ -134,7 +132,7 @@ func (pm *PmCrypto) DecryptMessageVerify(encryptedText string, verifierKey *KeyR
return out, nil return out, nil
} }
// Handle signature time verification manually, so we can add a margin to the creationTime check. // processSignatureExpiration handles signature time verification manually, so we can add a margin to the creationTime check.
func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) { func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
if md.SignatureError == pgpErrors.ErrSignatureExpired { if md.SignatureError == pgpErrors.ErrSignatureExpired {
if verifyTime > 0 { if verifyTime > 0 {
@ -153,10 +151,9 @@ func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
} }
} }
// Use: ios/android only // EncryptMessageWithPassword encrypts a plain text to pgp message with a password
//EncryptMessageWithPassword encrypt a plain text to pgp message with a password // plainText string: clear text
//plainText string: clear text // output string: armored pgp message
//output string: armored pgp message
func (pm *PmCrypto) EncryptMessageWithPassword(plainText string, password string) (string, error) { func (pm *PmCrypto) EncryptMessageWithPassword(plainText string, password string) (string, error) {
var outBuf bytes.Buffer var outBuf bytes.Buffer
@ -184,12 +181,12 @@ func (pm *PmCrypto) EncryptMessageWithPassword(plainText string, password string
return outBuf.String(), nil return outBuf.String(), nil
} }
// Use ios/android only // EncryptMessage encrypts message with unarmored public key, if pass private key and passphrase will also sign the message
// EncryptMessageBinKey encrypt message with unarmored public key, if pass private key and passphrase will also sign the message
// publicKey : bytes unarmored public key // publicKey : bytes unarmored public key
// plainText : the input // plainText : the input
// privateKey : optional required when you want to sign // privateKey : optional required when you want to sign
// passphrase : optional required when you pass the private key and this passphrase must could decrypt the private key // passphrase : optional required when you pass the private key and this passphrase should decrypt the private key
// trim : bool true if need to trim new lines
func (pm *PmCrypto) EncryptMessage(plainText string, publicKey *KeyRing, privateKey *KeyRing, passphrase string, trim bool) (string, error) { func (pm *PmCrypto) EncryptMessage(plainText string, publicKey *KeyRing, privateKey *KeyRing, passphrase string, trim bool) (string, error) {
if trim { if trim {
@ -220,10 +217,9 @@ func (pm *PmCrypto) EncryptMessage(plainText string, publicKey *KeyRing, private
return outBuf.String(), nil return outBuf.String(), nil
} }
// Use: ios/android only // DecryptMessageWithPassword decrypts a pgp message with a password
//DecryptMessageWithPassword decrypt a pgp message with a password // encrypted string : armored pgp message
//encrypted string : armored pgp message // output string : clear text
//output string : clear text
func (pm *PmCrypto) DecryptMessageWithPassword(encrypted string, password string) (string, error) { func (pm *PmCrypto) DecryptMessageWithPassword(encrypted string, password string) (string, error) {
encryptedio, err := internal.Unarmor(encrypted) encryptedio, err := internal.Unarmor(encrypted)
if err != nil { if err != nil {

View file

@ -45,7 +45,7 @@ func (pm PmCrypto) parseMIME(mimeBody string, verifierKey *KeyRing) (*pmmime.Bod
return body, verified, atts, attHeaders, nil return body, verified, atts, attHeaders, nil
} }
// define call back interface // MIMECallbacks defines a call back interface
type MIMECallbacks interface { type MIMECallbacks interface {
OnBody(body string, mimetype string) OnBody(body string, mimetype string)
OnAttachment(headers string, data []byte) OnAttachment(headers string, data []byte)
@ -55,7 +55,7 @@ type MIMECallbacks interface {
OnError(err error) OnError(err error)
} }
// Use ios/android only // DecryptMIMEMessage decrypts a MIME message
func (pm *PmCrypto) DecryptMIMEMessage(encryptedText string, verifierKey *KeyRing, privateKeyRing *KeyRing, func (pm *PmCrypto) DecryptMIMEMessage(encryptedText string, verifierKey *KeyRing, privateKeyRing *KeyRing,
passphrase string, callbacks MIMECallbacks, verifyTime int64) { passphrase string, callbacks MIMECallbacks, verifyTime int64) {
decsignverify, err := pm.DecryptMessageVerify(encryptedText, verifierKey, privateKeyRing, passphrase, verifyTime) decsignverify, err := pm.DecryptMessageVerify(encryptedText, verifierKey, privateKeyRing, passphrase, verifyTime)

View file

@ -1,5 +1,5 @@
// Package crypto contains all methods and classes needed for manipulation // Package crypto contains all methods and classes needed for manipulation
// with underlying cryptographic operations. It uses lowlevel openpgp functions // with underlying cryptographic operations. It uses low-level openpgp functions
// and provides higher level views. It uses models of messages, attachments // and provides higher level views. It uses models of messages, attachments
// and other higher-level entities // and other higher-level entities
package crypto package crypto

View file

@ -11,8 +11,7 @@ import (
"golang.org/x/crypto/openpgp/packet" "golang.org/x/crypto/openpgp/packet"
) )
//RandomToken ... // RandomToken with a default key size
// Use: ios/android only
func (pm *PmCrypto) RandomToken() ([]byte, error) { func (pm *PmCrypto) RandomToken() ([]byte, error) {
config := &packet.Config{DefaultCipher: packet.CipherAES256} config := &packet.Config{DefaultCipher: packet.CipherAES256}
keySize := config.DefaultCipher.KeySize() keySize := config.DefaultCipher.KeySize()
@ -23,8 +22,7 @@ func (pm *PmCrypto) RandomToken() ([]byte, error) {
return symKey, nil return symKey, nil
} }
// RandomTokenWith ... // RandomTokenWith a given key size
// Use: ios/android only
func (pm *PmCrypto) RandomTokenWith(size int) ([]byte, error) { func (pm *PmCrypto) RandomTokenWith(size int) ([]byte, error) {
config := &packet.Config{DefaultCipher: packet.CipherAES256} config := &packet.Config{DefaultCipher: packet.CipherAES256}
symKey := make([]byte, size) symKey := make([]byte, size)
@ -34,8 +32,7 @@ func (pm *PmCrypto) RandomTokenWith(size int) ([]byte, error) {
return symKey, nil return symKey, nil
} }
// GetSessionFromKeyPacket get session key no encoding in and out // GetSessionFromKeyPacket gets session key no encoding in and out
// Use: ios/android only
func (pm *PmCrypto) GetSessionFromKeyPacket(keyPackage []byte, privateKey *KeyRing, passphrase string) (*SymmetricKey, error) { func (pm *PmCrypto) GetSessionFromKeyPacket(keyPackage []byte, privateKey *KeyRing, passphrase string) (*SymmetricKey, error) {
keyReader := bytes.NewReader(keyPackage) keyReader := bytes.NewReader(keyPackage)
@ -74,8 +71,7 @@ func (pm *PmCrypto) GetSessionFromKeyPacket(keyPackage []byte, privateKey *KeyRi
return getSessionSplit(ek) return getSessionSplit(ek)
} }
//KeyPacketWithPublicKey ... // KeyPacketWithPublicKey
// Use: ios/android only
func (pm *PmCrypto) KeyPacketWithPublicKey(sessionSplit *SymmetricKey, publicKey string) ([]byte, error) { func (pm *PmCrypto) KeyPacketWithPublicKey(sessionSplit *SymmetricKey, publicKey string) ([]byte, error) {
pubkeyRaw, err := armor.Unarmor(publicKey) pubkeyRaw, err := armor.Unarmor(publicKey)
if err != nil { if err != nil {
@ -84,8 +80,7 @@ func (pm *PmCrypto) KeyPacketWithPublicKey(sessionSplit *SymmetricKey, publicKey
return pm.KeyPacketWithPublicKeyBin(sessionSplit, pubkeyRaw) return pm.KeyPacketWithPublicKeyBin(sessionSplit, pubkeyRaw)
} }
// KeyPacketWithPublicKeyBin ... // KeyPacketWithPublicKeyBin
// Use: ios/android only
func (pm *PmCrypto) KeyPacketWithPublicKeyBin(sessionSplit *SymmetricKey, publicKey []byte) ([]byte, error) { func (pm *PmCrypto) KeyPacketWithPublicKeyBin(sessionSplit *SymmetricKey, publicKey []byte) ([]byte, error) {
publicKeyReader := bytes.NewReader(publicKey) publicKeyReader := bytes.NewReader(publicKey)
pubKeyEntries, err := openpgp.ReadKeyRing(publicKeyReader) pubKeyEntries, err := openpgp.ReadKeyRing(publicKeyReader)
@ -130,7 +125,7 @@ func (pm *PmCrypto) KeyPacketWithPublicKeyBin(sessionSplit *SymmetricKey, public
return outbuf.Bytes(), nil return outbuf.Bytes(), nil
} }
//GetSessionFromSymmetricPacket ... // GetSessionFromSymmetricPacket
func (pm *PmCrypto) GetSessionFromSymmetricPacket(keyPackage []byte, password string) (*SymmetricKey, error) { func (pm *PmCrypto) GetSessionFromSymmetricPacket(keyPackage []byte, password string) (*SymmetricKey, error) {
keyReader := bytes.NewReader(keyPackage) keyReader := bytes.NewReader(keyPackage)
@ -169,8 +164,7 @@ func (pm *PmCrypto) GetSessionFromSymmetricPacket(keyPackage []byte, password st
return nil, errors.New("password incorrect") return nil, errors.New("password incorrect")
} }
// SymmetricKeyPacketWithPassword ... // SymmetricKeyPacketWithPassword
// Use: ios/android only
func (pm *PmCrypto) SymmetricKeyPacketWithPassword(sessionSplit *SymmetricKey, password string) ([]byte, error) { func (pm *PmCrypto) SymmetricKeyPacketWithPassword(sessionSplit *SymmetricKey, password string) ([]byte, error) {
outbuf := &bytes.Buffer{} outbuf := &bytes.Buffer{}

View file

@ -13,8 +13,7 @@ import (
"io" "io"
) )
// Use: ios/android only // SignTextDetached signs detached text type
// SignTextDetached sign detached text type
func (pm *PmCrypto) SignTextDetached(plainText string, privateKey *KeyRing, passphrase string, trim bool) (string, error) { func (pm *PmCrypto) SignTextDetached(plainText string, privateKey *KeyRing, passphrase string, trim bool) (string, error) {
//sign with 0x01 text //sign with 0x01 text
if trim { if trim {
@ -40,8 +39,7 @@ func (pm *PmCrypto) SignTextDetached(plainText string, privateKey *KeyRing, pass
return outBuf.String(), nil return outBuf.String(), nil
} }
// Use: ios/android only // SignBinDetached Signs detached bin data using string key
// Sign detached bin data using string key
func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey *KeyRing, passphrase string) (string, error) { func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey *KeyRing, passphrase string) (string, error) {
//sign with 0x00 //sign with 0x00
signEntity := privateKey.GetSigningEntity(passphrase) signEntity := privateKey.GetSigningEntity(passphrase)
@ -63,10 +61,8 @@ func (pm *PmCrypto) SignBinDetached(plainData []byte, privateKey *KeyRing, passp
return outBuf.String(), nil return outBuf.String(), nil
} }
// Use: ios/android only // VerifyTextSignDetachedBinKey Verifies detached text - check if signature is valid using a given publicKey in binary format
// 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) { func (pm *PmCrypto) VerifyTextSignDetachedBinKey(signature string, plainText string, publicKey *KeyRing, verifyTime int64) (bool, error) {
plainText = internal.TrimNewlines(plainText) plainText = internal.TrimNewlines(plainText)
origText := bytes.NewReader(bytes.NewBufferString(plainText).Bytes()) origText := bytes.NewReader(bytes.NewBufferString(plainText).Bytes())
@ -81,7 +77,7 @@ func verifySignature(pubKeyEntries openpgp.EntityList, origText *bytes.Reader, s
} }
} else { } else {
config.Time = func() time.Time { config.Time = func() time.Time {
return time.Unix(verifyTime+internal.CreationTimeOffset, 0) return time.Unix(verifyTime + internal.CreationTimeOffset, 0)
} }
} }
signatureReader := strings.NewReader(signature) signatureReader := strings.NewReader(signature)
@ -116,10 +112,8 @@ func verifySignature(pubKeyEntries openpgp.EntityList, origText *bytes.Reader, s
return true, nil return true, nil
} }
// Use: ios/android only // VerifyBinSignDetachedBinKey Verifies detached text in binary format - check if signature is valid using a given publicKey in binary format
// 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) { func (pm *PmCrypto) VerifyBinSignDetachedBinKey(signature string, plainData []byte, publicKey *KeyRing, verifyTime int64) (bool, error) {
origText := bytes.NewReader(plainData) origText := bytes.NewReader(plainData)
return verifySignature(publicKey.entities, origText, signature, verifyTime) return verifySignature(publicKey.entities, origText, signature, verifyTime)

View file

@ -13,7 +13,7 @@ import (
"golang.org/x/crypto/openpgp/packet" "golang.org/x/crypto/openpgp/packet"
) )
// Use: ios/android only // SignatureCollector structure
type SignatureCollector struct { type SignatureCollector struct {
config *packet.Config config *packet.Config
keyring openpgp.KeyRing keyring openpgp.KeyRing
@ -22,18 +22,19 @@ type SignatureCollector struct {
verified int verified int
} }
func newSignatureCollector(targetAccepter pmmime.VisitAcceptor, keyring openpgp.KeyRing, config *packet.Config) *SignatureCollector { func newSignatureCollector(targetAcceptor pmmime.VisitAcceptor, keyring openpgp.KeyRing, config *packet.Config) *SignatureCollector {
return &SignatureCollector{ return &SignatureCollector{
target: targetAccepter, target: targetAcceptor,
config: config, config: config,
keyring: keyring, keyring: keyring,
} }
} }
// Accept
func (sc *SignatureCollector) Accept(part io.Reader, header textproto.MIMEHeader, hasPlainSibling bool, isFirst, isLast bool) (err error) { func (sc *SignatureCollector) Accept(part io.Reader, header textproto.MIMEHeader, hasPlainSibling bool, isFirst, isLast bool) (err error) {
parentMediaType, params, _ := mime.ParseMediaType(header.Get("Content-Type")) parentMediaType, params, _ := mime.ParseMediaType(header.Get("Content-Type"))
if parentMediaType == "multipart/signed" { if parentMediaType == "multipart/signed" {
newPart, rawBody := pmmime.GetRawMimePart(part, "--"+params["boundary"]) newPart, rawBody := pmmime.GetRawMimePart(part, "--" + params["boundary"])
var multiparts []io.Reader var multiparts []io.Reader
var multipartHeaders []textproto.MIMEHeader var multipartHeaders []textproto.MIMEHeader
if multiparts, multipartHeaders, err = pmmime.GetMultipartParts(newPart, params); err == nil { if multiparts, multipartHeaders, err = pmmime.GetMultipartParts(newPart, params); err == nil {
@ -61,7 +62,7 @@ func (sc *SignatureCollector) Accept(part io.Reader, header textproto.MIMEHeader
if err != nil { if err != nil {
return return
} }
// TODO: Sunny proposed to move this also to pm-mime library
partData, _ := ioutil.ReadAll(multiparts[1]) partData, _ := ioutil.ReadAll(multiparts[1])
decodedPart := pmmime.DecodeContentEncoding(bytes.NewReader(partData), multipartHeaders[1].Get("Content-Transfer-Encoding")) decodedPart := pmmime.DecodeContentEncoding(bytes.NewReader(partData), multipartHeaders[1].Get("Content-Transfer-Encoding"))
buffer, err := ioutil.ReadAll(decodedPart) buffer, err := ioutil.ReadAll(decodedPart)
@ -94,6 +95,7 @@ func (sc *SignatureCollector) Accept(part io.Reader, header textproto.MIMEHeader
return nil return nil
} }
func (ac SignatureCollector) GetSignature() string { // GetSignature
return ac.signature func (sc SignatureCollector) GetSignature() string {
return sc.signature
} }

View file

@ -8,7 +8,6 @@ import (
) )
// EncryptWithoutIntegrity encrypts data with AES-CTR. Note: this encryption mode is not secure when stored/sent on an untrusted medium. // EncryptWithoutIntegrity encrypts data with AES-CTR. Note: this encryption mode is not secure when stored/sent on an untrusted medium.
// Use: ios/android only
func EncryptWithoutIntegrity(key, input, iv []byte) (output []byte, err error) { func EncryptWithoutIntegrity(key, input, iv []byte) (output []byte, err error) {
var block cipher.Block var block cipher.Block
if block, err = aes.NewCipher(key); err != nil { if block, err = aes.NewCipher(key); err != nil {
@ -21,14 +20,12 @@ func EncryptWithoutIntegrity(key, input, iv []byte) (output []byte, err error) {
} }
// DecryptWithoutIntegrity decrypts data encrypted with AES-CTR. // DecryptWithoutIntegrity decrypts data encrypted with AES-CTR.
// Use: ios/android only
func DecryptWithoutIntegrity(key, input, iv []byte) ([]byte, error) { func DecryptWithoutIntegrity(key, input, iv []byte) ([]byte, error) {
// AES-CTR decryption is identical to encryption. // AES-CTR decryption is identical to encryption.
return EncryptWithoutIntegrity(key, input, iv) return EncryptWithoutIntegrity(key, input, iv)
} }
// 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. // 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.
// Use: ios/android only
func DeriveKey(password string, salt []byte, N int) ([]byte, error) { func DeriveKey(password string, salt []byte, N int) ([]byte, error) {
return scrypt.Key([]byte(password), salt, N, 8, 1, 32) return scrypt.Key([]byte(password), salt, N, 8, 1, 32)
} }

View file

@ -6,29 +6,30 @@ import (
var pmCrypto = PmCrypto{} var pmCrypto = PmCrypto{}
// GetPmCrypto
func GetPmCrypto() *PmCrypto { func GetPmCrypto() *PmCrypto {
return &pmCrypto return &pmCrypto
} }
// UpdateTime update cached time // UpdateTime updates cached time
func (pm *PmCrypto) UpdateTime(newTime int64) { func (pm *PmCrypto) UpdateTime(newTime int64) {
pm.latestServerTime = newTime pm.latestServerTime = newTime
pm.latestClientTime = time.Now() pm.latestClientTime = time.Now()
} }
//GetTime get latest cached time // GetTimeUnix gets latest cached time
func (pm *PmCrypto) GetTimeUnix() int64 { func (pm *PmCrypto) GetTimeUnix() int64 {
return pm.getNow().Unix() return pm.getNow().Unix()
} }
//GetTime get latest cached time // GetTime gets latest cached time
func (pm *PmCrypto) GetTime() time.Time { func (pm *PmCrypto) GetTime() time.Time {
return pm.getNow() return pm.getNow()
} }
func (pm *PmCrypto) getNow() time.Time { func (pm *PmCrypto) getNow() time.Time {
if pm.latestServerTime > 0 && !pm.latestClientTime.IsZero() { if pm.latestServerTime > 0 && !pm.latestClientTime.IsZero() {
// Sub is monotome, it uses a monotime time clock in this case instead of the wall clock // Sub is monotonic, it uses a monotonic clock in this case instead of the wall clock
extrapolate := int64(pm.latestClientTime.Sub(time.Now()).Seconds()) extrapolate := int64(pm.latestClientTime.Sub(time.Now()).Seconds())
return time.Unix(pm.latestServerTime+extrapolate, 0) return time.Unix(pm.latestServerTime+extrapolate, 0)
} }

View file

@ -11,9 +11,8 @@ func TrimNewlines(input string) string {
return re.ReplaceAllString(input, "") return re.ReplaceAllString(input, "")
} }
// CreationTimeOffset stores amount of seconds that a signature may be created // CreationTimeOffset stores the amount of seconds that a signature may be
// after the verify time Consistent with the 2 day slack allowed in the // created in the future, to compensate for clock skew
// ProtonMail Email Parser
const CreationTimeOffset = int64(60 * 60 * 24 * 2) const CreationTimeOffset = int64(60 * 60 * 24 * 2)
// ArmorHeaders from golang pm-crypto // ArmorHeaders from golang pm-crypto

View file

@ -9,8 +9,7 @@ import (
"golang.org/x/crypto/openpgp" "golang.org/x/crypto/openpgp"
) )
// Use: ios/android only // GetFingerprint gets an armored public key fingerprint
// GetFingerprint get a armored public key fingerprint
func GetFingerprint(publicKey string) (string, error) { func GetFingerprint(publicKey string) (string, error) {
rawPubKey, err := armor.Unarmor(publicKey) rawPubKey, err := armor.Unarmor(publicKey)
if err != nil { if err != nil {
@ -19,8 +18,7 @@ func GetFingerprint(publicKey string) (string, error) {
return GetFingerprintBinKey(rawPubKey) return GetFingerprintBinKey(rawPubKey)
} }
// Use: ios/android only // GetFingerprintBinKey gets an unarmored public key fingerprint
// GetFingerprintBinKey get a unarmored public key fingerprint
func GetFingerprintBinKey(publicKey []byte) (string, error) { func GetFingerprintBinKey(publicKey []byte) (string, error) {
pubKeyReader := bytes.NewReader(publicKey) pubKeyReader := bytes.NewReader(publicKey)
pubKeyEntries, err := openpgp.ReadKeyRing(pubKeyReader) pubKeyEntries, err := openpgp.ReadKeyRing(pubKeyReader)
@ -31,5 +29,5 @@ func GetFingerprintBinKey(publicKey []byte) (string, error) {
fp := e.PrimaryKey.Fingerprint fp := e.PrimaryKey.Fingerprint
return hex.EncodeToString(fp[:]), nil return hex.EncodeToString(fp[:]), nil
} }
return "", errors.New("Can't find public key") return "", errors.New("can't find public key")
} }

View file

@ -11,8 +11,7 @@ import (
"strings" "strings"
) )
// Use: ios/android only // CheckPassphrase checks if private key passphrase ok
//CheckPassphrase check is private key passphrase ok
func CheckPassphrase(privateKey string, passphrase string) bool { func CheckPassphrase(privateKey string, passphrase string) bool {
privKeyReader := strings.NewReader(privateKey) privKeyReader := strings.NewReader(privateKey)
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader) entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
@ -42,8 +41,7 @@ func CheckPassphrase(privateKey string, passphrase string) bool {
return true return true
} }
// Use: ios/android only // PublicKey gets a public key from a private key
// PublicKey get a public key from a private key
func PublicKey(privateKey string) (string, error) { func PublicKey(privateKey string) (string, error) {
privKeyReader := strings.NewReader(privateKey) privKeyReader := strings.NewReader(privateKey)
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader) entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
@ -64,8 +62,7 @@ func PublicKey(privateKey string) (string, error) {
return outString, nil return outString, nil
} }
// Use: ios/android only // PublicKeyBinOut gets a public key from a private key
// PublicKeyBinOut get a public key from a private key
func PublicKeyBinOut(privateKey string) ([]byte, error) { func PublicKeyBinOut(privateKey string) ([]byte, error) {
privKeyReader := strings.NewReader(privateKey) privKeyReader := strings.NewReader(privateKey)
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader) entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)

View file

@ -1,20 +1,20 @@
// Provides high-level public data models used for communication mainly with mobile clients // Provides high-level public data models used for communication mainly with mobile clients
package models package models
//EncryptedSplit when encrypt attachemt // EncryptedSplit when encrypt attachment
type EncryptedSplit struct { type EncryptedSplit struct {
DataPacket []byte DataPacket []byte
KeyPacket []byte KeyPacket []byte
Algo string Algo string
} }
//EncryptedSigned encrypt_sign_package // EncryptedSigned encrypt_sign_package
type EncryptedSigned struct { type EncryptedSigned struct {
Encrypted string Encrypted string
Signature string Signature string
} }
//DecryptSignedVerify decrypt_sign_verify // DecryptSignedVerify decrypt_sign_verify
type DecryptSignedVerify struct { type DecryptSignedVerify struct {
//clear text //clear text
Plaintext string Plaintext string