Bug 1627973 - OpenPGP trust fixes for own key. r=PatrickBrunschwig DONTBUILD
authorKai Engert <kaie@kuix.de>
Tue, 07 Apr 2020 12:30:12 +0200
changeset 38785 123077a8532a74995de5401d560890b563359933
parent 38784 e7d1e30ba95af154b7ad9799ea17cafe6fdf147c
child 38786 464c3c056790fb7f330748e49c1b75a8ca15452b
push id401
push userclokep@gmail.com
push dateMon, 01 Jun 2020 20:41:59 +0000
reviewersPatrickBrunschwig
bugs1627973
Bug 1627973 - OpenPGP trust fixes for own key. r=PatrickBrunschwig DONTBUILD Differential Revision: https://phabricator.services.mozilla.com/D70024
mail/extensions/openpgp/content/modules/core.jsm
mail/extensions/openpgp/content/modules/data.jsm
mail/extensions/openpgp/content/modules/rnp.jsm
--- a/mail/extensions/openpgp/content/modules/core.jsm
+++ b/mail/extensions/openpgp/content/modules/core.jsm
@@ -21,20 +21,20 @@ const getEnigmailConsole = EnigmailLazy.
 const getEnigmailMimeEncrypt = EnigmailLazy.loader(
   "enigmail/mimeEncrypt.jsm",
   "EnigmailMimeEncrypt"
 );
 const getEnigmailProtocolHandler = EnigmailLazy.loader(
   "enigmail/protocolHandler.jsm",
   "EnigmailProtocolHandler"
 );
-const getEnigmailFiltersWrapper = EnigmailLazy.loader(
-  "enigmail/filtersWrapper.jsm",
-  "EnigmailFiltersWrapper"
-);
+//const getEnigmailFiltersWrapper = EnigmailLazy.loader(
+//  "enigmail/filtersWrapper.jsm",
+//  "EnigmailFiltersWrapper"
+//);
 const getEnigmailLog = EnigmailLazy.loader("enigmail/log.jsm", "EnigmailLog");
 const getEnigmailLocale = EnigmailLazy.loader(
   "enigmail/locale.jsm",
   "EnigmailLocale"
 );
 const getEnigmailCommandLine = EnigmailLazy.loader(
   "enigmail/commandLine.jsm",
   "EnigmailCommandLine"
@@ -55,20 +55,20 @@ const getEnigmailDialog = EnigmailLazy.l
   "enigmail/dialog.jsm",
   "EnigmailDialog"
 );
 const getEnigmailConfigure = EnigmailLazy.loader(
   "enigmail/configure.jsm",
   "EnigmailConfigure"
 );
 const getEnigmailApp = EnigmailLazy.loader("enigmail/app.jsm", "EnigmailApp");
-const getEnigmailWksMimeHandler = EnigmailLazy.loader(
-  "enigmail/wksMimeHandler.jsm",
-  "EnigmailWksMimeHandler"
-);
+//const getEnigmailWksMimeHandler = EnigmailLazy.loader(
+//  "enigmail/wksMimeHandler.jsm",
+//  "EnigmailWksMimeHandler"
+//);
 const getEnigmailPgpmimeHander = EnigmailLazy.loader(
   "enigmail/pgpmimeHandler.jsm",
   "EnigmailPgpmimeHander"
 );
 //const getEnigmailOverlays = EnigmailLazy.loader("enigmail/enigmailOverlays.jsm", "EnigmailOverlays");
 /*
 const getEnigmailSqlite = EnigmailLazy.loader(
   "enigmail/sqliteDb.jsm",
@@ -148,18 +148,18 @@ var EnigmailCore = {
             "\n" +
             ex.stack +
             "\n"
         );
       }
     }
 
     getEnigmailVerify().registerContentTypeHandler();
-    getEnigmailWksMimeHandler().registerContentTypeHandler();
-    getEnigmailFiltersWrapper().onStartup();
+    //getEnigmailWksMimeHandler().registerContentTypeHandler();
+    //getEnigmailFiltersWrapper().onStartup();
     continueStartup(1);
 
     let myName = getEnigmailLocale().getString("Enigmail");
     if (!myName) {
       console.log("core.jsm: couldn't load string from properties " + myName);
     }
   },
 
@@ -174,17 +174,17 @@ var EnigmailCore = {
     );
 
     if (this.factories) {
       for (let fct of this.factories) {
         fct.unregister();
       }
     }
 
-    getEnigmailFiltersWrapper().onShutdown();
+    //getEnigmailFiltersWrapper().onShutdown();
     getEnigmailVerify().unregisterContentTypeHandler();
 
     getEnigmailLocale().shutdown();
     getEnigmailLog().onShutdown();
 
     getEnigmailLog().setLogLevel(3);
     gEnigmailService = null;
   },
--- a/mail/extensions/openpgp/content/modules/data.jsm
+++ b/mail/extensions/openpgp/content/modules/data.jsm
@@ -18,16 +18,19 @@ function converter(charset) {
     Ci.nsIScriptableUnicodeConverter
   );
   unicodeConv.charset = charset || "utf-8";
   return unicodeConv;
 }
 
 var EnigmailData = {
   getUnicodeData(data) {
+    if (!data) {
+      throw new Error("EnigmailData.getUnicodeData invalid parameter");
+    }
     // convert output to Unicode
     var tmpStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(
       Ci.nsIStringInputStream
     );
     tmpStream.setData(data, data.length);
     var inStream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
       Ci.nsIScriptableInputStream
     );
--- a/mail/extensions/openpgp/content/modules/rnp.jsm
+++ b/mail/extensions/openpgp/content/modules/rnp.jsm
@@ -89,26 +89,29 @@ var RNP = {
 
     if (RNPLib.rnp_key_get_keyid(handle, key_id.address())) {
       throw new Error("rnp_key_get_keyid failed");
     }
     keyObj.keyId = key_id.readString();
     if (forListing) {
       keyObj.id = keyObj.keyId;
     }
+    RNPLib.rnp_buffer_destroy(key_id);
 
     if (RNPLib.rnp_key_get_fprint(handle, fingerprint.address())) {
       throw new Error("rnp_key_get_fprint failed");
     }
     keyObj.fpr = fingerprint.readString();
+    RNPLib.rnp_buffer_destroy(fingerprint);
 
     if (RNPLib.rnp_key_get_alg(handle, algo.address())) {
       throw new Error("rnp_key_get_alg failed");
     }
     keyObj.algoSym = algo.readString();
+    RNPLib.rnp_buffer_destroy(algo);
 
     if (RNPLib.rnp_key_get_bits(handle, bits.address())) {
       throw new Error("rnp_key_get_bits failed");
     }
     keyObj.keySize = bits.value;
 
     if (RNPLib.rnp_key_get_creation(handle, key_creation.address())) {
       throw new Error("rnp_key_get_creation failed");
@@ -348,46 +351,46 @@ var RNP = {
         }
 
         if (!is_revoked.value) {
           let uid_str = new ctypes.char.ptr();
           if (RNPLib.rnp_key_get_uid_at(handle, i, uid_str.address())) {
             throw new Error("rnp_key_get_uid_at failed");
           }
           let userIdStr = uid_str.readString();
+          RNPLib.rnp_buffer_destroy(uid_str);
           if (userIdStr !== RNP_PHOTO_USERID_ID) {
             if (!primary_uid_set) {
               keyObj.userId = userIdStr;
               if (forListing) {
                 keyObj.name = keyObj.userId;
               }
               primary_uid_set = true;
             }
 
             let uidObj = {};
-            uidObj.userId = uid_str.readString();
+            uidObj.userId = userIdStr;
             uidObj.type = "uid";
             uidObj.keyTrust = keyObj.keyTrust;
             uidObj.uidFpr = "??fpr??";
 
             keyObj.userIds.push(uidObj);
           }
-
-          RNPLib.rnp_buffer_destroy(uid_str);
         }
 
         RNPLib.rnp_uid_handle_destroy(uid_handle);
       }
 
       if (!keyObj.userId) {
         let prim_uid_str = new ctypes.char.ptr();
         if (RNPLib.rnp_key_get_primary_uid(handle, prim_uid_str.address())) {
           throw new Error("rnp_key_get_primary_uid failed");
         }
         keyObj.userId = prim_uid_str.readString();
+        RNPLib.rnp_buffer_destroy(prim_uid_str);
       }
 
       if (RNPLib.rnp_key_get_subkey_count(handle, sub_count.address())) {
         throw new Error("rnp_key_get_subkey_count failed");
       }
       for (let i = 0; i < sub_count.value; i++) {
         let sub_handle = new RNPLib.rnp_key_handle_t();
         if (RNPLib.rnp_key_get_subkey_at(handle, i, sub_handle.address())) {
@@ -448,16 +451,17 @@ var RNP = {
         }
 
         if (!is_revoked.value) {
           let uid_str = new ctypes.char.ptr();
           if (RNPLib.rnp_key_get_uid_at(handle, i, uid_str.address())) {
             throw new Error("rnp_key_get_uid_at failed");
           }
           let userIdStr = uid_str.readString();
+          RNPLib.rnp_buffer_destroy(uid_str);
 
           if (userIdStr !== RNP_PHOTO_USERID_ID) {
             let id = outputIndex;
             ++outputIndex;
 
             rList[id] = {};
             rList[id].created = mainKeyObj.created;
             rList[id].fpr = mainKeyObj.fpr;
@@ -510,16 +514,17 @@ var RNP = {
               if (
                 RNPLib.rnp_signature_get_keyid(sig_handle, sig_id_str.address())
               ) {
                 throw new Error("rnp_signature_get_keyid failed");
               }
 
               let sigIdStr = sig_id_str.readString();
               sigObj.signerKeyId = sigIdStr;
+              RNPLib.rnp_buffer_destroy(sig_id_str);
 
               let signerHandle = new RNPLib.rnp_key_handle_t();
 
               if (
                 RNPLib.rnp_signature_get_signer(
                   sig_handle,
                   signerHandle.address()
                 )
@@ -539,24 +544,24 @@ var RNP = {
                   RNPLib.rnp_key_get_primary_uid(
                     signerHandle,
                     signer_uid_str.address()
                   )
                 ) {
                   throw new Error("rnp_key_get_uid_at failed");
                 }
                 sigObj.userId = signer_uid_str.readString();
+                RNPLib.rnp_buffer_destroy(signer_uid_str);
                 sigObj.sigKnown = true;
                 rList[id].sigList.push(sigObj);
                 RNPLib.rnp_key_handle_destroy(signerHandle);
               }
               RNPLib.rnp_signature_handle_destroy(sig_handle);
             }
           }
-          RNPLib.rnp_buffer_destroy(uid_str);
         }
 
         RNPLib.rnp_uid_handle_destroy(uid_handle);
       }
     } catch (ex) {
       console.log(ex);
     } finally {
       RNPLib.rnp_key_handle_destroy(handle);
@@ -938,16 +943,17 @@ var RNP = {
 
     RNPLib.rnp_op_generate_destroy(genOp);
 
     let ctypes_key_id = new ctypes.char.ptr();
     if (RNPLib.rnp_key_get_keyid(primaryKey, ctypes_key_id.address())) {
       throw new Error("rnp_key_get_keyid failed");
     }
     newKeyId = ctypes_key_id.readString();
+    RNPLib.rnp_buffer_destroy(ctypes_key_id);
 
     if (
       RNPLib.rnp_op_generate_subkey_create(
         genOp.address(),
         RNPLib.ffi,
         primaryKey,
         subKeyType
       )
@@ -1377,16 +1383,17 @@ var RNP = {
 
         let fingerprint = new ctypes.char.ptr();
         if (RNPLib.rnp_key_get_fprint(found_handle, fingerprint.address())) {
           throw new Error("rnp_key_get_fprint failed");
         }
         console.debug(
           "found suitable subkey, fingerprint: " + fingerprint.readString()
         );
+        RNPLib.rnp_buffer_destroy(fingerprint);
         break;
       }
     }
 
     return found_handle;
   },
 
   addSuitableEncryptKey(key, op) {
@@ -1693,49 +1700,16 @@ var RNP = {
         if (key_revoked.value) {
           continue;
         }
 
         if (this.isKeyExpired(handle)) {
           continue;
         }
 
-        let acceptance = "";
-
-        if (onlyAcceptableAsPublic) {
-          let fingerprint = new ctypes.char.ptr();
-          if (RNPLib.rnp_key_get_fprint(handle, fingerprint.address())) {
-            throw new Error("rnp_key_get_fprint failed");
-          }
-          let fpr = fingerprint.readString();
-
-          let acceptanceResult = {};
-          try {
-            await PgpSqliteDb2.getAcceptance(
-              fpr,
-              emailWithoutBrackets,
-              acceptanceResult
-            );
-          } catch (ex) {
-            console.debug("getAcceptance failed: " + ex);
-          }
-
-          if (!acceptanceResult.emailDecided) {
-            continue;
-          }
-          acceptance = acceptanceResult.fingerprintAcceptance;
-          let isAcceptable =
-            acceptance == "unverified" || acceptance == "verified";
-          if (!isAcceptable) {
-            continue;
-          }
-        }
-
-        /* Ensure the desired email is still contained in the set of
-         * valid UIDs, hasn't been removed, nor revoked. */
         if (RNPLib.rnp_key_get_uid_count(handle, uid_count.address())) {
           throw new Error("rnp_key_get_uid_count failed");
         }
 
         let foundUid = false;
         for (let i = 0; i < uid_count.value && !foundUid; i++) {
           let uid_handle = new RNPLib.rnp_uid_handle_t();
           let is_revoked = new ctypes.bool();
@@ -1752,43 +1726,74 @@ var RNP = {
 
           if (!is_revoked.value) {
             let uid_str = new ctypes.char.ptr();
             if (RNPLib.rnp_key_get_uid_at(handle, i, uid_str.address())) {
               throw new Error("rnp_key_get_uid_at failed");
             }
 
             let userId = uid_str.readString();
+            RNPLib.rnp_buffer_destroy(uid_str);
             if (userId.includes(id)) {
               foundUid = true;
 
+              let haveSecret;
               if (onlyAcceptableAsPublic) {
-                if (acceptance == "unverified") {
+                // if secret key is available, any usage is allowed
+                let have_secret = new ctypes.bool();
+                if (RNPLib.rnp_key_have_secret(handle, have_secret.address())) {
+                  throw new Error("rnp_key_have_secret failed");
+                }
+                haveSecret = have_secret.value;
+              }
+
+              if (onlyAcceptableAsPublic && !haveSecret) {
+                let fingerprint = new ctypes.char.ptr();
+                if (RNPLib.rnp_key_get_fprint(handle, fingerprint.address())) {
+                  throw new Error("rnp_key_get_fprint failed");
+                }
+                let fpr = fingerprint.readString();
+                RNPLib.rnp_buffer_destroy(fingerprint);
+
+                let acceptanceResult = {};
+                try {
+                  await PgpSqliteDb2.getAcceptance(
+                    fpr,
+                    emailWithoutBrackets,
+                    acceptanceResult
+                  );
+                } catch (ex) {
+                  console.debug("getAcceptance failed: " + ex);
+                }
+
+                if (!acceptanceResult.emailDecided) {
+                  continue;
+                }
+                if (acceptanceResult.fingerprintAcceptance == "unverified") {
                   /* keep searching for a better, verified key */
                   if (!tentativeUnverifiedHandle) {
                     tentativeUnverifiedHandle = handle;
                     have_handle = false;
                   }
-                } else if (acceptance == "verified") {
+                } else if (
+                  acceptanceResult.fingerprintAcceptance == "verified"
+                ) {
                   foundHandle = handle;
                   have_handle = false;
                   if (tentativeUnverifiedHandle) {
                     RNPLib.rnp_key_handle_destroy(tentativeUnverifiedHandle);
                     tentativeUnverifiedHandle = null;
                   }
                 }
               } else {
                 foundHandle = handle;
                 have_handle = false;
               }
             }
-
-            RNPLib.rnp_buffer_destroy(uid_str);
           }
-
           RNPLib.rnp_uid_handle_destroy(uid_handle);
         }
       } catch (ex) {
         console.log(ex);
       } finally {
         if (have_handle) {
           RNPLib.rnp_key_handle_destroy(handle);
         }