home *** CD-ROM | disk | FTP | other *** search
/ Freelog 112 / FreelogNo112-NovembreDecembre2012.iso / Programmation / RJ_TextEd / RJ_TextEd_Portable.exe / components / crypto-SDR.js < prev    next >
Text File  |  2010-01-01  |  9KB  |  254 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is mozilla.org code.
  15.  *
  16.  * The Initial Developer of the Original Code is Mozilla Foundation.
  17.  * Portions created by the Initial Developer are Copyright (C) 2009
  18.  * the Initial Developer. All Rights Reserved.
  19.  *
  20.  * Contributor(s):
  21.  *  Justin Dolske <dolske@mozilla.com> (original author)
  22.  *
  23.  * Alternatively, the contents of this file may be used under the terms of
  24.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  25.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  26.  * in which case the provisions of the GPL or the LGPL are applicable instead
  27.  * of those above. If you wish to allow use of your version of this file only
  28.  * under the terms of either the GPL or the LGPL, and not to allow others to
  29.  * use your version of this file under the terms of the MPL, indicate your
  30.  * decision by deleting the provisions above and replace them with the notice
  31.  * and other provisions required by the GPL or the LGPL. If you do not delete
  32.  * the provisions above, a recipient may use your version of this file under
  33.  * the terms of any one of the MPL, the GPL or the LGPL.
  34.  *
  35.  * ***** END LICENSE BLOCK ***** */
  36.  
  37.  
  38. const Cc = Components.classes;
  39. const Ci = Components.interfaces;
  40. const Cr = Components.results;
  41.  
  42. Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
  43. Components.utils.import("resource://gre/modules/Services.jsm");
  44.  
  45. function LoginManagerCrypto_SDR() {
  46.     this.init();
  47. };
  48.  
  49. LoginManagerCrypto_SDR.prototype = {
  50.  
  51.     classID : Components.ID("{dc6c2976-0f73-4f1f-b9ff-3d72b4e28309}"),
  52.     QueryInterface : XPCOMUtils.generateQI([Ci.nsILoginManagerCrypto]),
  53.  
  54.     __sdrSlot : null, // PKCS#11 slot being used by the SDR.
  55.     get _sdrSlot() {
  56.         if (!this.__sdrSlot) {
  57.             let modules = Cc["@mozilla.org/security/pkcs11moduledb;1"].
  58.                           getService(Ci.nsIPKCS11ModuleDB);
  59.             this.__sdrSlot = modules.findSlotByName("");
  60.         }
  61.         return this.__sdrSlot;
  62.     },
  63.  
  64.     __decoderRing : null,  // nsSecretDecoderRing service
  65.     get _decoderRing() {
  66.         if (!this.__decoderRing)
  67.             this.__decoderRing = Cc["@mozilla.org/security/sdr;1"].
  68.                                  getService(Ci.nsISecretDecoderRing);
  69.         return this.__decoderRing;
  70.     },
  71.  
  72.     __utfConverter : null, // UCS2 <--> UTF8 string conversion
  73.     get _utfConverter() {
  74.         if (!this.__utfConverter) {
  75.             this.__utfConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
  76.                                   createInstance(Ci.nsIScriptableUnicodeConverter);
  77.             this.__utfConverter.charset = "UTF-8";
  78.         }
  79.         return this.__utfConverter;
  80.     },
  81.  
  82.     _utfConverterReset : function() {
  83.         this.__utfConverter = null;
  84.     },
  85.  
  86.     _debug  : false, // mirrors signon.debug
  87.     _uiBusy : false,
  88.  
  89.  
  90.     /*
  91.      * log
  92.      *
  93.      * Internal function for logging debug messages to the Error Console.
  94.      */
  95.     log : function (message) {
  96.         if (!this._debug)
  97.             return;
  98.         dump("PwMgr cryptoSDR: " + message + "\n");
  99.         Services.console.logStringMessage("PwMgr cryptoSDR: " + message);
  100.     },
  101.  
  102.  
  103.     init : function () {
  104.         // Connect to the correct preferences branch.
  105.         this._prefBranch = Services.prefs.getBranch("signon.");
  106.         this._prefBranch.QueryInterface(Ci.nsIPrefBranch2);
  107.  
  108.         this._debug = this._prefBranch.getBoolPref("debug");
  109.  
  110.         // Check to see if the internal PKCS#11 token has been initialized.
  111.         // If not, set a blank password.
  112.         let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].
  113.                       getService(Ci.nsIPK11TokenDB);
  114.  
  115.         let token = tokenDB.getInternalKeyToken();
  116.         if (token.needsUserInit) {
  117.             this.log("Initializing key3.db with default blank password.");
  118.             token.initPassword("");
  119.         }
  120.     },
  121.  
  122.  
  123.     /*
  124.      * encrypt
  125.      *
  126.      * Encrypts the specified string, using the SecretDecoderRing.
  127.      *
  128.      * Returns the encrypted string, or throws an exception if there was a
  129.      * problem.
  130.      */
  131.     encrypt : function (plainText) {
  132.         let cipherText = null;
  133.  
  134.         let wasLoggedIn = this.isLoggedIn;
  135.         let canceledMP = false;
  136.  
  137.         this._uiBusy = true;
  138.         try {
  139.             let plainOctet = this._utfConverter.ConvertFromUnicode(plainText);
  140.             plainOctet += this._utfConverter.Finish();
  141.             cipherText = this._decoderRing.encryptString(plainOctet);
  142.         } catch (e) {
  143.             this.log("Failed to encrypt string. (" + e.name + ")");
  144.             // If the user clicks Cancel, we get NS_ERROR_FAILURE.
  145.             // (unlike decrypting, which gets NS_ERROR_NOT_AVAILABLE).
  146.             if (e.result == Cr.NS_ERROR_FAILURE) {
  147.                 canceledMP = true;
  148.                 throw Components.Exception("User canceled master password entry", Cr.NS_ERROR_ABORT);
  149.             } else {
  150.                 throw Components.Exception("Couldn't encrypt string", Cr.NS_ERROR_FAILURE);
  151.             }
  152.         } finally {
  153.             this._uiBusy = false;
  154.             // If we triggered a master password prompt, notify observers.
  155.             if (!wasLoggedIn && this.isLoggedIn)
  156.                 this._notifyObservers("passwordmgr-crypto-login");
  157.             else if (canceledMP)
  158.                 this._notifyObservers("passwordmgr-crypto-loginCanceled");
  159.         }
  160.         return cipherText;
  161.     },
  162.  
  163.  
  164.     /*
  165.      * decrypt
  166.      *
  167.      * Decrypts the specified string, using the SecretDecoderRing.
  168.      *
  169.      * Returns the decrypted string, or throws an exception if there was a
  170.      * problem.
  171.      */
  172.     decrypt : function (cipherText) {
  173.         let plainText = null;
  174.  
  175.         let wasLoggedIn = this.isLoggedIn;
  176.         let canceledMP = false;
  177.  
  178.         this._uiBusy = true;
  179.         try {
  180.             let plainOctet;
  181.             if (cipherText.charAt(0) == '~') {
  182.                 // The old Wallet file format obscured entries by
  183.                 // base64-encoding them. These entries are signaled by a
  184.                 // leading '~' character.
  185.                 plainOctet = atob(cipherText.substring(1));
  186.             } else {
  187.                 plainOctet = this._decoderRing.decryptString(cipherText);
  188.             }
  189.             plainText = this._utfConverter.ConvertToUnicode(plainOctet);
  190.         } catch (e) {
  191.             this.log("Failed to decrypt string: " + cipherText +
  192.                 " (" + e.name + ")");
  193.  
  194.             // In the unlikely event the converter threw, reset it.
  195.             this._utfConverterReset();
  196.  
  197.             // If the user clicks Cancel, we get NS_ERROR_NOT_AVAILABLE.
  198.             // If the cipherText is bad / wrong key, we get NS_ERROR_FAILURE
  199.             // Wrong passwords are handled by the decoderRing reprompting;
  200.             // we get no notification.
  201.             if (e.result == Cr.NS_ERROR_NOT_AVAILABLE) {
  202.                 canceledMP = true;
  203.                 throw Components.Exception("User canceled master password entry", Cr.NS_ERROR_ABORT);
  204.             } else {
  205.                 throw Components.Exception("Couldn't decrypt string", Cr.NS_ERROR_FAILURE);
  206.             }
  207.         } finally {
  208.             this._uiBusy = false;
  209.             // If we triggered a master password prompt, notify observers.
  210.             if (!wasLoggedIn && this.isLoggedIn)
  211.                 this._notifyObservers("passwordmgr-crypto-login");
  212.             else if (canceledMP)
  213.                 this._notifyObservers("passwordmgr-crypto-loginCanceled");
  214.         }
  215.  
  216.         return plainText;
  217.     },
  218.  
  219.  
  220.     /*
  221.      * uiBusy
  222.      */
  223.     get uiBusy() {
  224.         return this._uiBusy;
  225.     },
  226.  
  227.  
  228.     /*
  229.      * isLoggedIn
  230.      */
  231.     get isLoggedIn() {
  232.         let status = this._sdrSlot.status;
  233.         this.log("SDR slot status is " + status);
  234.         if (status == Ci.nsIPKCS11Slot.SLOT_READY ||
  235.             status == Ci.nsIPKCS11Slot.SLOT_LOGGED_IN)
  236.             return true;
  237.         if (status == Ci.nsIPKCS11Slot.SLOT_NOT_LOGGED_IN)
  238.             return false;
  239.         throw Components.Exception("unexpected slot status: " + status, Cr.NS_ERROR_FAILURE);
  240.     },
  241.  
  242.  
  243.     /*
  244.      * _notifyObservers
  245.      */
  246.     _notifyObservers : function(topic) {
  247.         this.log("Prompted for a master password, notifying for " + topic);
  248.         Services.obs.notifyObservers(null, topic, null);
  249.      },
  250. }; // end of nsLoginManagerCrypto_SDR implementation
  251.  
  252. let component = [LoginManagerCrypto_SDR];
  253. var NSGetFactory = XPCOMUtils.generateNSGetFactory(component);
  254.