/*
 * ***** BEGIN LICENSE BLOCK *****
 * OpenPGP Zimbra Secure is the open source digital signature and encrypt for Zimbra Collaboration Open Source Edition software
 * Copyright (C) 2016-present OpenPGP Zimbra Secure

 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>
 * ***** END LICENSE BLOCK *****
 *
 * OpenPGP MIME Secure Email Zimlet
 *
 * Written by nguyennv1981@gmail.com
 */

OpenPGPEncrypt = function(opts, mimeBuilder, pgp) {
    opts = opts || {
        privateKey: '',
        publicKeys: [],
        passphrase: '',
        shouldEncrypt: false,
        onEncrypted: false,
        onError: false
    };
    var self = this;
    this._mimeBuilder = mimeBuilder;
    this._pgp = pgp || openpgp;
    this._pgpKey = this._pgp.key;
    this._shouldEncrypt = opts.shouldEncrypt;
    this._onEncrypted = opts.onEncrypted;
    this._onError = opts.onError;

    var privateKey = this._pgpKey.readArmored(opts.privateKey).keys[0];
    if (!privateKey.decrypt(opts.passphrase)) {
        throw new Error('Wrong passphrase! Could not decrypt the private key!');
    }
    this._privateKey = privateKey;
    this._publicKeys = [];
    OpenPGPUtils.forEach(opts.publicKeys, function(key) {
        self._publicKeys = self._publicKeys.concat(self._pgpKey.readArmored(key).keys);
    });
};

OpenPGPEncrypt.prototype = new Object();
OpenPGPEncrypt.prototype.constructor = OpenPGPEncrypt;

OpenPGPEncrypt.prototype.encrypt = function() {
    var self = this;
    var sequence = Promise.resolve();

    return sequence.then(function() {
        var opts = {
            data: self._mimeBuilder.toString(),
            privateKeys: self._privateKey,
            armor: true
        };
        return self._pgp.sign(opts).then(function(signedText) {
            var signatureHeader = '-----BEGIN PGP SIGNATURE-----';
            var signature = signatureHeader + signedText.data.split(signatureHeader).pop();
            self._mimeBuilder.buildSignedMessage(signature);
            return self._mimeBuilder;
        });
    })
    .then(function(builder) {
        if (self._shouldEncrypt) {
            var opts = {
                data: self._mimeBuilder.toString(),
                publicKeys: self._publicKeys,
                armor: true
            };
            return self._pgp.encrypt(opts).then(function(cipherText) {
                self._mimeBuilder.buildEncryptedMessage(cipherText.data);
                if (AjxUtil.isFunction(self._onEncrypted)) {
                    self._onEncrypted(self, self._mimeBuilder);
                }
                return self._mimeBuilder;
            }, function(err) {
                if (AjxUtil.isFunction(self._onError)) {
                    self._onError(self, err);
                }
            });
        }
        else {
            if (AjxUtil.isFunction(self._onEncrypted)) {
                self._onEncrypted(self, self._mimeBuilder);
            }
            return self._mimeBuilder;
        }
    });
};

@@ -1451,16 +1451,46 @@
 Error;%0A%0A
+    this._privateKey = false;%0A
     var 
@@ -1561,17 +1561,16 @@
     if (
-!
 privateK
@@ -1596,24 +1596,80 @@
 sphrase)) %7B%0A
+        this._privateKey = privateKey;%0A    %7D%0A    else %7B%0A
         thro
@@ -1739,24 +1739,25 @@
 y!');%0A    %7D%0A
+%0A
     this._pr
@@ -1759,42 +1759,37 @@
 s._p
-rivate
+ublic
 Key
+s
  = 
-privateKey;%0A    thi
+%5B%5D;%0A    if (opt
 s.
-_
 publ
@@ -1798,40 +1798,20 @@
 Keys
- = %5B%5D;%0A    OpenPGPUtils.forEach(
+) %7B%0A        
 opts
@@ -1821,18 +1821,25 @@
 blicKeys
-, 
+.forEach(
 function
@@ -1850,24 +1850,28 @@
 ) %7B%0A        
+  
+  
 self._public
@@ -1938,27 +1938,37 @@
 .keys);%0A    
-%7D);
+    %7D);%0A    %7D
 %0A%7D;%0A%0AOpenPGP
@@ -2199,24 +2199,60 @@
 unction() %7B%0A
+        if (self._privateKey) %7B%0A    
         var 
@@ -2252,32 +2252,36 @@
    var opts = %7B%0A
+    
             data
@@ -2316,32 +2316,36 @@
 (),%0A            
+    
 privateKeys: sel
@@ -2363,32 +2363,36 @@
 ey,%0A            
+    
 armor: true%0A    
@@ -2387,35 +2387,43 @@
 r: true%0A        
+  
+  
 %7D;%0A
+    
         return s
@@ -2462,32 +2462,36 @@
 n(signedText) %7B%0A
+    
             var 
@@ -2545,32 +2545,36 @@
 -';%0A            
+    
 var signature = 
@@ -2641,32 +2641,36 @@
 ();%0A            
+    
 self._mimeBuilde
@@ -2702,16 +2702,99 @@
 ature);%0A
+                return self._mimeBuilder;%0A            %7D);%0A        %7D%0A        else %7B%0A
         
@@ -2828,26 +2828,24 @@
 r;%0A        %7D
-);
 %0A    %7D)%0A    
@@ -2901,16 +2901,47 @@
 dEncrypt
+ && self._publicKeys.length %3E 0
 ) %7B%0A    

Update pgp encryptor