1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
5 */
6
7"use strict";
8
9const EXPORTED_SYMBOLS = ["KeyLookupHelper"];
10
11const { XPCOMUtils } = ChromeUtils.import(
12  "resource://gre/modules/XPCOMUtils.jsm"
13);
14
15XPCOMUtils.defineLazyModuleGetters(this, {
16  EnigmailDialog: "chrome://openpgp/content/modules/dialog.jsm",
17  EnigmailKey: "chrome://openpgp/content/modules/key.jsm",
18  EnigmailKeyRing: "chrome://openpgp/content/modules/keyRing.jsm",
19  EnigmailKeyServer: "chrome://openpgp/content/modules/keyserver.jsm",
20  EnigmailKeyserverURIs: "chrome://openpgp/content/modules/keyserverUris.jsm",
21  EnigmailWkdLookup: "chrome://openpgp/content/modules/wkdLookup.jsm",
22});
23
24XPCOMUtils.defineLazyGetter(this, "l10n", () => {
25  return new Localization(["messenger/openpgp/openpgp.ftl"], true);
26});
27
28var KeyLookupHelper = {
29  async lookupAndImportOnKeyserver(window, identifier, giveFeedbackToUser) {
30    let defKs = EnigmailKeyserverURIs.getDefaultKeyServer();
31    if (!defKs) {
32      return false;
33    }
34
35    let somethingWasImported = false;
36    let vks = await EnigmailKeyServer.downloadNoImport(identifier, defKs);
37    if (vks && "keyData" in vks) {
38      let keyList = EnigmailKey.getKeyListFromKeyBlock(
39        vks.keyData,
40        {},
41        false,
42        true,
43        false
44      );
45      if (keyList) {
46        somethingWasImported = EnigmailKeyRing.importKeyDataWithConfirmation(
47          window,
48          keyList,
49          vks.keyData,
50          true
51        );
52      } else {
53        EnigmailDialog.alert(window, await l10n.formatValue("preview-failed"));
54      }
55    } else {
56      console.debug("searchKeysOnInternet no data in keys.openpgp.org");
57    }
58
59    return somethingWasImported;
60  },
61
62  /**
63   * @param {string} searchTerm - The 0x prefxed keyId or email address to search for.
64   * @param {boolean} giveFeedbackToUser - Whether to show feedback to user or handle it silently.
65   * @param {Function} whenDoneCB - Callback function.
66   * @return {boolean} true if a key was imported
67   */
68  async lookupAndImportBySearchTerm(
69    window,
70    searchTerm,
71    giveFeedbackToUser,
72    whenDoneCB
73  ) {
74    let somethingWasImported = await this.lookupAndImportOnKeyserver(
75      window,
76      searchTerm,
77      giveFeedbackToUser
78    );
79    if (somethingWasImported && whenDoneCB) {
80      whenDoneCB(somethingWasImported);
81    }
82    if (!somethingWasImported) {
83      let value = await l10n.formatValue("no-key-found");
84      EnigmailDialog.alert(window, value);
85    }
86    return somethingWasImported;
87  },
88
89  async lookupAndImportByKeyID(window, keyId, giveFeedbackToUser, whenDoneCB) {
90    if (!/^0x/i.test(keyId)) {
91      keyId = "0x" + keyId;
92    }
93    return this.lookupAndImportBySearchTerm(
94      window,
95      keyId,
96      giveFeedbackToUser,
97      whenDoneCB
98    );
99  },
100
101  async lookupAndImportByEmail(window, email, giveFeedbackToUser, whenDoneCB) {
102    let wkdKeys = await EnigmailWkdLookup.downloadKey(email);
103    if (!wkdKeys) {
104      console.debug("searchKeysOnInternet no wkd data for " + email);
105    } else {
106      let keyList = EnigmailKey.getKeyListFromKeyBlock(
107        wkdKeys.keyData,
108        {},
109        false,
110        true,
111        false
112      );
113      if (!keyList) {
114        EnigmailDialog.alert(window, await l10n.formatValue("preview-failed"));
115      } else {
116        let somethingWasImported = EnigmailKeyRing.importKeyDataWithConfirmation(
117          window,
118          keyList,
119          wkdKeys.keyData,
120          true
121        );
122        if (somethingWasImported) {
123          if (whenDoneCB) {
124            whenDoneCB(somethingWasImported);
125          }
126          return somethingWasImported;
127        }
128      }
129    }
130
131    return this.lookupAndImportBySearchTerm(
132      window,
133      email,
134      giveFeedbackToUser,
135      whenDoneCB
136    );
137  },
138};
139