diff --git a/armor/armor.go b/armor/armor.go index ed8b430..fdde685 100644 --- a/armor/armor.go +++ b/armor/armor.go @@ -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 { diff --git a/crypto/attachment.go b/crypto/attachment.go index ef931d4..b04ac68 100644 --- a/crypto/attachment.go +++ b/crypto/attachment.go @@ -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) { diff --git a/crypto/key.go b/crypto/key.go index d42c40e..2182290 100644 --- a/crypto/key.go +++ b/crypto/key.go @@ -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) diff --git a/crypto/keyring.go b/crypto/keyring.go index 17dcad0..5de8acf 100644 --- a/crypto/keyring.go +++ b/crypto/keyring.go @@ -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 diff --git a/crypto/message.go b/crypto/message.go index d86d958..48b2299 100644 --- a/crypto/message.go +++ b/crypto/message.go @@ -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 { diff --git a/crypto/mime.go b/crypto/mime.go index 68c8532..19da35d 100644 --- a/crypto/mime.go +++ b/crypto/mime.go @@ -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) diff --git a/crypto/pmcrypto.go b/crypto/pmcrypto.go index 239b253..1ed21f5 100644 --- a/crypto/pmcrypto.go +++ b/crypto/pmcrypto.go @@ -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 diff --git a/crypto/session.go b/crypto/session.go index b43906b..4dfb697 100644 --- a/crypto/session.go +++ b/crypto/session.go @@ -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{} diff --git a/crypto/sign_detached.go b/crypto/sign_detached.go index 4a2982f..f713454 100644 --- a/crypto/sign_detached.go +++ b/crypto/sign_detached.go @@ -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) diff --git a/crypto/signature_collector.go b/crypto/signature_collector.go index e0877c7..03f5d3f 100644 --- a/crypto/signature_collector.go +++ b/crypto/signature_collector.go @@ -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 } diff --git a/crypto/subtle.go b/crypto/subtle.go index 35f181d..9a3f078 100644 --- a/crypto/subtle.go +++ b/crypto/subtle.go @@ -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) } diff --git a/crypto/time.go b/crypto/time.go index 366d334..9ea3a5a 100644 --- a/crypto/time.go +++ b/crypto/time.go @@ -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) } diff --git a/internal/common.go b/internal/common.go index 198bc08..7653355 100644 --- a/internal/common.go +++ b/internal/common.go @@ -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 diff --git a/key/fingerprint.go b/key/fingerprint.go index 3214004..532fa88 100644 --- a/key/fingerprint.go +++ b/key/fingerprint.go @@ -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") } diff --git a/key/key.go b/key/key.go index 280c332..d00b8f5 100644 --- a/key/key.go +++ b/key/key.go @@ -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) diff --git a/models/models.go b/models/models.go index 2fa65b9..4fd60ff 100644 --- a/models/models.go +++ b/models/models.go @@ -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