Merge branch 'improve-doc' into 'master'

fix typo / improve documentatation

See merge request ProtonMail/go-pm-crypto!11
This commit is contained in:
Daniel Huigens 2019-05-13 12:33:01 +00:00
commit e797299d64
16 changed files with 77 additions and 187 deletions

View file

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

View file

@ -13,7 +13,7 @@ import (
"golang.org/x/crypto/openpgp/packet"
)
//EncryptedSplit when encrypt attachment
// EncryptedSplit when encrypt attachment
type AttachmentProcessor struct {
w *io.WriteCloser
pipe *io.PipeWriter
@ -23,12 +23,12 @@ type AttachmentProcessor struct {
err error
}
// Use: ios/android only
// Process allows the attachment processor to write the encrypted attachment
func (ap *AttachmentProcessor) Process(plainData []byte) {
(*ap.w).Write(plainData)
}
// Use: ios/android only
// Finish attachment process
func (ap *AttachmentProcessor) Finish() (*models.EncryptedSplit, error) {
if ap.err != nil {
return nil, ap.err
@ -42,8 +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
// Encrypts 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{}
// you can also add these one at
@ -84,7 +83,7 @@ func (pm *PmCrypto) encryptAttachment(estimatedSize int, fileName string, public
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) {
ap, err := pm.encryptAttachment(len(plainData), fileName, publicKey, -1)
if err != nil {
@ -99,15 +98,13 @@ func (pm *PmCrypto) EncryptAttachment(plainData []byte, fileName string, publicK
}
// Use: ios/android only
//EncryptAttachment ...
// EncryptAttachmentLowMemory ...
func (pm *PmCrypto) EncryptAttachmentLowMemory(estimatedSize int, fileName string, publicKey *KeyRing) (*AttachmentProcessor, error) {
// Garbage collect every megabyte
return pm.encryptAttachment(estimatedSize, fileName, publicKey, 1<<20)
}
// Helper method. Splits armored pgp session into key and packet data
// Use: ios/android only
// SplitArmor is a Helper method. Splits armored pgp session into key and packet data
func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
var err error
@ -121,7 +118,6 @@ func SplitArmor(encrypted string) (*models.EncryptedSplit, error) {
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
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.
type SymmetricKey struct {
// The clear base64-encoded key.
//Key string
Key []byte
// The algorithm used by this key.
Algo string
@ -42,8 +41,7 @@ var symKeyAlgos = map[string]packet.CipherFunction{
"aes256": packet.CipherAES256,
}
// GetCipherFunc returns functin corresponding to an algorithm used in this SymmetricKey
// Use: go-pm-crypto, key.go, session.go
// GetCipherFunc returns function corresponding to an algorithm used in this SymmetricKey
func (sk *SymmetricKey) GetCipherFunc() packet.CipherFunction {
cf, ok := symKeyAlgos[sk.Algo]
if ok {
@ -54,7 +52,6 @@ func (sk *SymmetricKey) GetCipherFunc() packet.CipherFunction {
}
// GetBase64Key returns a key as base64 encoded string
// Use: bridge
func (sk *SymmetricKey) GetBase64Key() string {
return base64.StdEncoding.EncodeToString(sk.Key)
}
@ -77,8 +74,7 @@ func newSymmetricKey(ek *packet.EncryptedKey) *SymmetricKey {
}
}
// DecryptAttKey and return a symmetric key
// Use: bridge
// DecryptAttKey and returns a symmetric key
func DecryptAttKey(kr *KeyRing, keyPacket string) (key *SymmetricKey, err error) {
r := base64.NewDecoder(base64.StdEncoding, strings.NewReader(keyPacket))
packets := packet.NewReader(r)
@ -112,7 +108,6 @@ func DecryptAttKey(kr *KeyRing, keyPacket string) (key *SymmetricKey, err error)
}
// 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) {
// For info on each, see: https://golang.org/pkg/runtime/#MemStats
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")
return
}
/*if ek.Key == nil {
err = errors.New("pm-crypto: could not find any key to decrypt key")
return
}*/
if kr == nil {
var buf bytes.Buffer
@ -227,38 +218,13 @@ func SeparateKeyAndData(kr *KeyRing, r io.Reader, estimatedLength int, garbageCo
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.
// Use: bridge
func SetKey(kr *KeyRing, symKey *SymmetricKey) (packets string, err error) {
b := &bytes.Buffer{}
w := base64.NewEncoder(base64.StdEncoding, b)
cf := symKey.GetCipherFunc()
//k, err := base64.StdEncoding.DecodeString(symKey.Key)
//if err != nil {
// err = fmt.Errorf("pm-crypto: cannot set key: %v", err)
// return
//}
if len(kr.entities) == 0 {
err = fmt.Errorf("pm-crypto: cannot set key: key ring is empty")
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
//Use: ios/android only
func (pm *PmCrypto) IsKeyExpiredBin(publicKey []byte) (bool, error) {
now := pm.getNow()
pubKeyReader := bytes.NewReader(publicKey)
@ -365,7 +330,6 @@ const (
)
// IsKeyExpired checks if the given key is expired. Input in armored format
// Use: ios/android only
func (pm *PmCrypto) IsKeyExpired(publicKey string) (bool, error) {
rawPubKey, err := armor.Unarmor(publicKey)
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) {
if len(userName) <= 0 {
return "", errors.New("Invalid user name format")
return "", errors.New("invalid user name format")
}
var email = userName
@ -447,7 +411,6 @@ func (pm *PmCrypto) generateKey(userName string, domain string, passphrase strin
}
// GenerateRSAKeyWithPrimes generates RSA key with given primes.
// Use: TODO
func (pm *PmCrypto) GenerateRSAKeyWithPrimes(
userName, domain, passphrase string,
bits int,
@ -457,19 +420,11 @@ func (pm *PmCrypto) GenerateRSAKeyWithPrimes(
}
// 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) {
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
// Use ios/android only
// UpdatePrivateKeyPassphrase decrypts the given private key with oldPhrase and re-encrypts with the newPassphrase
func (pm *PmCrypto) UpdatePrivateKeyPassphrase(privateKey string, oldPassphrase string, newPassphrase string) (string, error) {
privKey := strings.NewReader(privateKey)
privKeyEntries, err := openpgp.ReadArmoredKeyRing(privKey)
@ -513,8 +468,7 @@ func (pm *PmCrypto) UpdatePrivateKeyPassphrase(privateKey string, oldPassphrase
return armor.ArmorWithType(serialized, constants.PrivateKeyHeader)
}
// CheckKey print out the key and subkey fingerprint
// Use: ios/android only
// CheckKey prints out the key and subkey fingerprint
func (pm *PmCrypto) CheckKey(pubKey string) (string, error) {
pubKeyReader := strings.NewReader(pubKey)
entries, err := openpgp.ReadArmoredKeyRing(pubKeyReader)

View file

@ -35,7 +35,7 @@ type pmKeyObject struct {
Primary int
}
// Use: only ios/android (internal)
// PrivateKeyReader
func (ko *pmKeyObject) PrivateKeyReader() io.Reader {
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")
// Err returns a non-nil error if the signature is invalid.
// Use: not used by bridge
func (s *Signature) Err() error {
return s.md.SignatureError
}
// KeyRing returns the key ring that was used to produce the signature, if
// available.
// Use: not used by bridge
func (s *Signature) KeyRing() *KeyRing {
if s.md.SignedBy == 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.
// Use: not used by bridge
func (s *Signature) IsBy(kr *KeyRing) bool {
// Use fingerprint if possible
if s.md.SignedBy != nil {
@ -117,8 +114,6 @@ func (kr *KeyRing) GetEntities() openpgp.EntityList {
}
// 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 {
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
// 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.
// Use: go-pmapi
func (kr *KeyRing) Encrypt(w io.Writer, sign *KeyRing, filename string, canonicalizeText bool) (io.WriteCloser, error) {
// The API returns keys sorted by descending priority
// 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
// 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) {
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: timeGenerator}
@ -190,7 +183,7 @@ type armorEncryptWriter struct {
ew io.WriteCloser // Encrypted writer
}
// Encrypt data
// Write encrypted data
func (w *armorEncryptWriter) Write(b []byte) (n int, err error) {
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.
// Use: go-pm-crypto, keyring.go
func (kr *KeyRing) EncryptArmored(w io.Writer, sign *KeyRing) (wc io.WriteCloser, err error) {
aw, err := armorUtils.ArmorWithTypeBuffered(w, constants.PGPMessageHeader)
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.
// Use go-pmapi
func (kr *KeyRing) EncryptString(s string, sign *KeyRing) (encrypted string, err error) {
var b bytes.Buffer
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
// Use: bridge
func (kr *KeyRing) EncryptSymmetric(textToEncrypt string, canonicalizeText bool) (outSplit *models.EncryptedSplit, err error) {
var encryptedWriter io.WriteCloser
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.
// 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
// Use go-pmapi
func (kr *KeyRing) DecryptString(encrypted string) (SignedString, error) {
r, signed, err := kr.DecryptArmored(strings.NewReader(encrypted))
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.
// 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
// Use go-pmapi
func (kr *KeyRing) DecryptStringIfNeeded(data string) (decrypted string, err error) {
if re := regexp.MustCompile("^-----BEGIN " + constants.PGPMessageHeader + "-----(?s:.+)-----END " + constants.PGPMessageHeader + "-----"); re.MatchString(data) {
var signed SignedString
@ -298,8 +286,7 @@ func (kr *KeyRing) DecryptStringIfNeeded(data string) (decrypted string, err err
return
}
// SignString sings a string message, using this KeyRing. canonicalizeText identifies if newlines are canonicalized
// Use go-pmapi
// SignString signs a string message, using this KeyRing. canonicalizeText identifies if newlines are canonicalized
func (kr *KeyRing) SignString(message string, canonicalizeText bool) (signed string, err error) {
var sig bytes.Buffer
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
// 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) {
var signEntity *openpgp.Entity
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
// golang.org/x/crypto/openpgp/errors) In this case signature has been verified
// successfuly, but it is either expired or in the future.
// Use: go-pmapi
// successfully, but it is either expired or in the future.
func (kr *KeyRing) VerifyString(message, signature string, sign *KeyRing) (err error) {
messageReader := strings.NewReader(message)
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.
// If err != nil, the password is wrong for every key, and err is the last error
// encountered.
// Use: go-pmapi
// Use: go-pm-crypto, attachment.go, message.go
func (kr *KeyRing) Unlock(passphrase []byte) error {
// Build a list of keys to decrypt
var keys []*packet.PrivateKey
@ -426,8 +408,6 @@ func (kr *KeyRing) Unlock(passphrase []byte) error {
// signed, signed will be nil.
// 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
// Use: go-pmapi
// Use: go-pm-crypto, keyring.go
func (kr *KeyRing) Decrypt(r io.Reader) (decrypted io.Reader, signed *Signature, err error) {
md, err := openpgp.ReadMessage(r, kr.entities, nil, nil)
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.
// 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
// Use: go-pm-crypto, keyring.go
func (kr *KeyRing) DecryptArmored(r io.Reader) (decrypted io.Reader, signed *Signature, err error) {
block, err := armor.Decode(r)
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.
// Use: go-pm-crypto, keyring.go
func (kr *KeyRing) WriteArmoredPublicKey(w io.Writer) (err error) {
aw, err := armor.Encode(w, openpgp.PublicKeyType, 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.
// Use: bridge
func (kr *KeyRing) ArmoredPublicKeyString() (s string, err error) {
b := &bytes.Buffer{}
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
// Use: ios/android only
func (pm *PmCrypto) BuildKeyRing(binKeys []byte) (kr *KeyRing, err error) {
kr = &KeyRing{}
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
// Use: ios/android only
func (pm *PmCrypto) BuildKeyRingNoError(binKeys []byte) (kr *KeyRing) {
kr, _ = pm.BuildKeyRing(binKeys)
return
}
// BuildKeyRingArmored reads armored string and returns keyring
// Use: ios/android only
func (pm *PmCrypto) BuildKeyRingArmored(key string) (kr *KeyRing, err error) {
keyRaw, err := armorUtils.Unarmor(key)
keyReader := bytes.NewReader(keyRaw)
@ -559,8 +533,6 @@ func (pm *PmCrypto) BuildKeyRingArmored(key string) (kr *KeyRing, err error) {
}
// UnmarshalJSON implements encoding/json.Unmarshaler.
// Use: go-pmapi
// Use: ios/android
func (kr *KeyRing) UnmarshalJSON(b []byte) (err error) {
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.
// Use: bridge
func (kr *KeyRing) Identities() []*Identity {
var identities []*Identity
for _, e := range kr.entities {
@ -599,7 +570,6 @@ func (kr *KeyRing) Identities() []*Identity {
}
// KeyIds returns array of IDs of keys in this KeyRing
// Use: not used by bridge
func (kr *KeyRing) KeyIds() []uint64 {
var res []uint64
for _, e := range kr.entities {
@ -609,7 +579,6 @@ func (kr *KeyRing) KeyIds() []uint64 {
}
// ReadArmoredKeyRing reads an armored data into keyring.
// Use: go-pmapi
func ReadArmoredKeyRing(r io.Reader) (kr *KeyRing, err error) {
kr = &KeyRing{}
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.
// Use: bridge
func ReadKeyRing(r io.Reader) (kr *KeyRing, err error) {
kr = &KeyRing{}
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
// KeyRings which contain at least, one unexpired Key. It returns only unexpired
// parts of these KeyRings
// Use: bridge
func FilterExpiredKeys(contactKeys []*KeyRing) (filteredKeys []*KeyRing, err error) {
now := time.Now()
hasExpiredEntity := false

View file

@ -19,11 +19,10 @@ import (
"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
// privateKey : armored private use 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) {
privKeyRaw, err := armorUtils.Unarmor(privateKey)
if err != nil {
@ -40,9 +39,8 @@ func (pm *PmCrypto) DecryptMessageStringKey(encryptedText string, privateKey str
// DecryptMessage decrypts encrypted string using keyring
// 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
// Use ios/android only
func (pm *PmCrypto) DecryptMessage(encryptedText string, privateKey *KeyRing, passphrase string) (string, error) {
md, err := decryptCore(encryptedText, nil, privateKey, passphrase, pm.getTimeGenerator())
if err != nil {
@ -85,12 +83,12 @@ func decryptCore(encryptedText string, additionalEntries openpgp.EntityList, pri
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) {
// DecryptMessageVerifyBinKeyPrivBinKeys decrypt message and verify the signature
// verifierKey []byte: unarmored verifier keys
// privateKey []byte: unarmored private key to decrypt. could be mutiple
out := &models.DecryptSignedVerify{}
out.Verify = failed
@ -134,7 +132,7 @@ func (pm *PmCrypto) DecryptMessageVerify(encryptedText string, verifierKey *KeyR
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) {
if md.SignatureError == pgpErrors.ErrSignatureExpired {
if verifyTime > 0 {
@ -153,10 +151,9 @@ 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
// EncryptMessageWithPassword encrypts a plain text to pgp message with a password
// plainText string: clear text
// output string: armored pgp message
func (pm *PmCrypto) EncryptMessageWithPassword(plainText string, password string) (string, error) {
var outBuf bytes.Buffer
@ -184,12 +181,12 @@ 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
// EncryptMessage encrypts message with unarmored public key, if pass private key and passphrase will also sign the message
// publicKey : bytes unarmored public key
// plainText : the input
// 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) {
if trim {
@ -220,10 +217,9 @@ 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
// DecryptMessageWithPassword decrypts a pgp message with a password
// encrypted string : armored pgp message
// output string : clear text
func (pm *PmCrypto) DecryptMessageWithPassword(encrypted string, password string) (string, error) {
encryptedio, err := internal.Unarmor(encrypted)
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
}
// define call back interface
// MIMECallbacks defines a call back interface
type MIMECallbacks interface {
OnBody(body string, mimetype string)
OnAttachment(headers string, data []byte)
@ -55,7 +55,7 @@ type MIMECallbacks interface {
OnError(err error)
}
// Use ios/android only
// DecryptMIMEMessage decrypts a MIME message
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)

View file

@ -1,5 +1,5 @@
// 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 other higher-level entities
package crypto

View file

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

View file

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

View file

@ -13,7 +13,7 @@ import (
"golang.org/x/crypto/openpgp/packet"
)
// Use: ios/android only
// SignatureCollector structure
type SignatureCollector struct {
config *packet.Config
keyring openpgp.KeyRing
@ -22,18 +22,19 @@ type SignatureCollector struct {
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{
target: targetAccepter,
target: targetAcceptor,
config: config,
keyring: keyring,
}
}
// Accept
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"))
if parentMediaType == "multipart/signed" {
newPart, rawBody := pmmime.GetRawMimePart(part, "--"+params["boundary"])
newPart, rawBody := pmmime.GetRawMimePart(part, "--" + params["boundary"])
var multiparts []io.Reader
var multipartHeaders []textproto.MIMEHeader
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 {
return
}
// TODO: Sunny proposed to move this also to pm-mime library
partData, _ := ioutil.ReadAll(multiparts[1])
decodedPart := pmmime.DecodeContentEncoding(bytes.NewReader(partData), multipartHeaders[1].Get("Content-Transfer-Encoding"))
buffer, err := ioutil.ReadAll(decodedPart)
@ -94,6 +95,7 @@ func (sc *SignatureCollector) Accept(part io.Reader, header textproto.MIMEHeader
return nil
}
func (ac SignatureCollector) GetSignature() string {
return ac.signature
// GetSignature
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.
// Use: ios/android only
func EncryptWithoutIntegrity(key, input, iv []byte) (output []byte, err error) {
var block cipher.Block
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.
// Use: ios/android only
func DecryptWithoutIntegrity(key, input, iv []byte) ([]byte, error) {
// AES-CTR decryption is identical to encryption.
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.
// Use: ios/android only
func DeriveKey(password string, salt []byte, N int) ([]byte, error) {
return scrypt.Key([]byte(password), salt, N, 8, 1, 32)
}

View file

@ -6,29 +6,30 @@ import (
var pmCrypto = PmCrypto{}
// GetPmCrypto
func GetPmCrypto() *PmCrypto {
return &pmCrypto
}
// UpdateTime update cached time
// UpdateTime updates cached time
func (pm *PmCrypto) UpdateTime(newTime int64) {
pm.latestServerTime = newTime
pm.latestClientTime = time.Now()
}
//GetTime get latest cached time
// GetTimeUnix gets latest cached time
func (pm *PmCrypto) GetTimeUnix() int64 {
return pm.getNow().Unix()
}
//GetTime get latest cached time
// GetTime gets latest cached time
func (pm *PmCrypto) GetTime() time.Time {
return pm.getNow()
}
func (pm *PmCrypto) getNow() time.Time {
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())
return time.Unix(pm.latestServerTime+extrapolate, 0)
}

View file

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

View file

@ -9,8 +9,7 @@ import (
"golang.org/x/crypto/openpgp"
)
// Use: ios/android only
// GetFingerprint get a armored public key fingerprint
// GetFingerprint gets an armored public key fingerprint
func GetFingerprint(publicKey string) (string, error) {
rawPubKey, err := armor.Unarmor(publicKey)
if err != nil {
@ -19,8 +18,7 @@ func GetFingerprint(publicKey string) (string, error) {
return GetFingerprintBinKey(rawPubKey)
}
// Use: ios/android only
// GetFingerprintBinKey get a unarmored public key fingerprint
// GetFingerprintBinKey gets an unarmored public key fingerprint
func GetFingerprintBinKey(publicKey []byte) (string, error) {
pubKeyReader := bytes.NewReader(publicKey)
pubKeyEntries, err := openpgp.ReadKeyRing(pubKeyReader)
@ -31,5 +29,5 @@ func GetFingerprintBinKey(publicKey []byte) (string, error) {
fp := e.PrimaryKey.Fingerprint
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"
)
// Use: ios/android only
//CheckPassphrase check is private key passphrase ok
// CheckPassphrase checks if private key passphrase ok
func CheckPassphrase(privateKey string, passphrase string) bool {
privKeyReader := strings.NewReader(privateKey)
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
@ -42,8 +41,7 @@ func CheckPassphrase(privateKey string, passphrase string) bool {
return true
}
// Use: ios/android only
// PublicKey get a public key from a private key
// PublicKey gets a public key from a private key
func PublicKey(privateKey string) (string, error) {
privKeyReader := strings.NewReader(privateKey)
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)
@ -64,8 +62,7 @@ func PublicKey(privateKey string) (string, error) {
return outString, nil
}
// Use: ios/android only
// PublicKeyBinOut get a public key from a private key
// PublicKeyBinOut gets a public key from a private key
func PublicKeyBinOut(privateKey string) ([]byte, error) {
privKeyReader := strings.NewReader(privateKey)
entries, err := openpgp.ReadArmoredKeyRing(privKeyReader)

View file

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