security/manager/ssl/src/nsSDR.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     2  *
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "stdlib.h"
     8 #include "plstr.h"
     9 #include "plbase64.h"
    11 #include "mozilla/Services.h"
    12 #include "nsMemory.h"
    13 #include "nsString.h"
    14 #include "nsCOMPtr.h"
    15 #include "nsThreadUtils.h"
    16 #include "nsIInterfaceRequestor.h"
    17 #include "nsIInterfaceRequestorUtils.h"
    18 #include "nsIServiceManager.h"
    19 #include "nsITokenPasswordDialogs.h"
    21 #include "nsISecretDecoderRing.h"
    22 #include "nsCRT.h"
    23 #include "nsSDR.h"
    24 #include "nsNSSComponent.h"
    25 #include "nsNSSShutDown.h"
    26 #include "ScopedNSSTypes.h"
    28 #include "pk11func.h"
    29 #include "pk11sdr.h" // For PK11SDR_Encrypt, PK11SDR_Decrypt
    31 #include "ssl.h" // For SSL_ClearSessionCache
    33 using namespace mozilla;
    35 // Standard ISupports implementation
    36 // NOTE: Should these be the thread-safe versions?
    37 NS_IMPL_ISUPPORTS(nsSecretDecoderRing, nsISecretDecoderRing, nsISecretDecoderRingConfig)
    39 // nsSecretDecoderRing constructor
    40 nsSecretDecoderRing::nsSecretDecoderRing()
    41 {
    42   // initialize superclass
    43 }
    45 // nsSecretDecoderRing destructor
    46 nsSecretDecoderRing::~nsSecretDecoderRing()
    47 {
    48 }
    50 /* [noscript] long encrypt (in buffer data, in long dataLen, out buffer result); */
    51 NS_IMETHODIMP nsSecretDecoderRing::
    52 Encrypt(unsigned char * data, int32_t dataLen, unsigned char * *result, int32_t *_retval)
    53 {
    54   nsNSSShutDownPreventionLock locker;
    55   nsresult rv = NS_OK;
    56   ScopedPK11SlotInfo slot;
    57   SECItem keyid;
    58   SECItem request;
    59   SECItem reply;
    60   SECStatus s;
    61   nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
    63   slot = PK11_GetInternalKeySlot();
    64   if (!slot) { rv = NS_ERROR_NOT_AVAILABLE; goto loser; }
    66   /* Make sure token is initialized. */
    67   rv = setPassword(slot, ctx);
    68   if (NS_FAILED(rv))
    69     goto loser;
    71   /* Force authentication */
    72   s = PK11_Authenticate(slot, true, ctx);
    73   if (s != SECSuccess) { rv = NS_ERROR_FAILURE; goto loser; }
    75   /* Use default key id */
    76   keyid.data = 0;
    77   keyid.len = 0;
    78   request.data = data;
    79   request.len = dataLen;
    80   reply.data = 0;
    81   reply.len = 0;
    82   s= PK11SDR_Encrypt(&keyid, &request, &reply, ctx);
    83   if (s != SECSuccess) { rv = NS_ERROR_FAILURE; goto loser; }
    85   *result = reply.data;
    86   *_retval = reply.len;
    88 loser:
    89   return rv;
    90 }
    92 /* [noscript] long decrypt (in buffer data, in long dataLen, out buffer result); */
    93 NS_IMETHODIMP nsSecretDecoderRing::
    94 Decrypt(unsigned char * data, int32_t dataLen, unsigned char * *result, int32_t *_retval)
    95 {
    96   nsNSSShutDownPreventionLock locker;
    97   nsresult rv = NS_OK;
    98   ScopedPK11SlotInfo slot;
    99   SECStatus s;
   100   SECItem request;
   101   SECItem reply;
   102   nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
   104   *result = 0;
   105   *_retval = 0;
   107   /* Find token with SDR key */
   108   slot = PK11_GetInternalKeySlot();
   109   if (!slot) { rv = NS_ERROR_NOT_AVAILABLE; goto loser; }
   111   /* Force authentication */
   112   if (PK11_Authenticate(slot, true, ctx) != SECSuccess)
   113   {
   114     rv = NS_ERROR_NOT_AVAILABLE;
   115     goto loser;
   116   }
   118   request.data = data;
   119   request.len = dataLen;
   120   reply.data = 0;
   121   reply.len = 0;
   122   s = PK11SDR_Decrypt(&request, &reply, ctx);
   123   if (s != SECSuccess) { rv = NS_ERROR_FAILURE; goto loser; }
   125   *result = reply.data;
   126   *_retval = reply.len;
   128 loser:
   129   return rv;
   130 }
   132 /* string encryptString (in string text); */
   133 NS_IMETHODIMP nsSecretDecoderRing::
   134 EncryptString(const char *text, char **_retval)
   135 {
   136   nsNSSShutDownPreventionLock locker;
   137   nsresult rv = NS_OK;
   138   unsigned char *encrypted = 0;
   139   int32_t eLen;
   141   if (!text || !_retval) {
   142     rv = NS_ERROR_INVALID_POINTER;
   143     goto loser;
   144   }
   146   rv = Encrypt((unsigned char *)text, strlen(text), &encrypted, &eLen);
   147   if (rv != NS_OK) { goto loser; }
   149   rv = encode(encrypted, eLen, _retval);
   151 loser:
   152   if (encrypted) PORT_Free(encrypted);
   154   return rv;
   155 }
   157 /* string decryptString (in string crypt); */
   158 NS_IMETHODIMP nsSecretDecoderRing::
   159 DecryptString(const char *crypt, char **_retval)
   160 {
   161   nsNSSShutDownPreventionLock locker;
   162   nsresult rv = NS_OK;
   163   char *r = 0;
   164   unsigned char *decoded = 0;
   165   int32_t decodedLen;
   166   unsigned char *decrypted = 0;
   167   int32_t decryptedLen;
   169   if (!crypt || !_retval) {
   170     rv = NS_ERROR_INVALID_POINTER;
   171     goto loser;
   172   }
   174   rv = decode(crypt, &decoded, &decodedLen);
   175   if (rv != NS_OK) goto loser;
   177   rv = Decrypt(decoded, decodedLen, &decrypted, &decryptedLen);
   178   if (rv != NS_OK) goto loser;
   180   // Convert to NUL-terminated string
   181   r = (char *)nsMemory::Alloc(decryptedLen+1);
   182   if (!r) { rv = NS_ERROR_OUT_OF_MEMORY; goto loser; }
   184   memcpy(r, decrypted, decryptedLen);
   185   r[decryptedLen] = 0;
   187   *_retval = r;
   188   r = 0;
   190 loser:
   191   if (decrypted) PORT_Free(decrypted);
   192   if (decoded) PR_DELETE(decoded);
   194   return rv;
   195 }
   197 /* void changePassword(); */
   198 NS_IMETHODIMP nsSecretDecoderRing::
   199 ChangePassword()
   200 {
   201   nsNSSShutDownPreventionLock locker;
   202   nsresult rv;
   203   ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot());
   204   if (!slot) return NS_ERROR_NOT_AVAILABLE;
   206   /* Convert UTF8 token name to UCS2 */
   207   NS_ConvertUTF8toUTF16 tokenName(PK11_GetTokenName(slot));
   209   /* Get the set password dialog handler imlementation */
   210   nsCOMPtr<nsITokenPasswordDialogs> dialogs;
   212   rv = getNSSDialogs(getter_AddRefs(dialogs),
   213                      NS_GET_IID(nsITokenPasswordDialogs),
   214                      NS_TOKENPASSWORDSDIALOG_CONTRACTID);
   215   if (NS_FAILED(rv)) return rv;
   217   nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
   218   bool canceled;
   220   {
   221     nsPSMUITracker tracker;
   222     if (tracker.isUIForbidden()) {
   223       rv = NS_ERROR_NOT_AVAILABLE;
   224     }
   225     else {
   226       rv = dialogs->SetPassword(ctx, tokenName.get(), &canceled);
   227     }
   228   }
   230   /* canceled is ignored */
   232   return rv;
   233 }
   235 NS_IMETHODIMP nsSecretDecoderRing::
   236 Logout()
   237 {
   238   static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
   240   nsresult rv;
   241   nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
   242   if (NS_FAILED(rv))
   243     return rv;
   245   {
   246     nsNSSShutDownPreventionLock locker;
   247     PK11_LogoutAll();
   248     SSL_ClearSessionCache();
   249   }
   251   return NS_OK;
   252 }
   254 NS_IMETHODIMP nsSecretDecoderRing::
   255 LogoutAndTeardown()
   256 {
   257   static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
   259   nsresult rv;
   260   nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
   261   if (NS_FAILED(rv))
   262     return rv;
   264   {
   265     nsNSSShutDownPreventionLock locker;
   266     PK11_LogoutAll();
   267     SSL_ClearSessionCache();
   268   }
   270   rv = nssComponent->LogoutAuthenticatedPK11();
   272   // After we just logged out, we need to prune dead connections to make
   273   // sure that all connections that should be stopped, are stopped. See
   274   // bug 517584.
   275   nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
   276   if (os)
   277     os->NotifyObservers(nullptr, "net:prune-dead-connections", nullptr);
   279   return rv;
   280 }
   282 /* void setWindow(in nsISupports w); */
   283 NS_IMETHODIMP nsSecretDecoderRing::
   284 SetWindow(nsISupports *w)
   285 {
   286   return NS_OK;
   287 }
   289 // Support routines
   291 nsresult nsSecretDecoderRing::
   292 encode(const unsigned char *data, int32_t dataLen, char **_retval)
   293 {
   294   nsresult rv = NS_OK;
   296   char *result = PL_Base64Encode((const char *)data, dataLen, nullptr);
   297   if (!result) { rv = NS_ERROR_OUT_OF_MEMORY; goto loser; }
   299   *_retval = NS_strdup(result);
   300   PR_DELETE(result);
   301   if (!*_retval) { rv = NS_ERROR_OUT_OF_MEMORY; goto loser; }
   303 loser:
   304   return rv;
   305 }
   307 nsresult nsSecretDecoderRing::
   308 decode(const char *data, unsigned char **result, int32_t * _retval)
   309 {
   310   nsresult rv = NS_OK;
   311   uint32_t len = strlen(data);
   312   int adjust = 0;
   314   /* Compute length adjustment */
   315   if (data[len-1] == '=') {
   316     adjust++;
   317     if (data[len-2] == '=') adjust++;
   318   }
   320   *result = (unsigned char *)PL_Base64Decode(data, len, nullptr);
   321   if (!*result) { rv = NS_ERROR_ILLEGAL_VALUE; goto loser; }
   323   *_retval = (len*3)/4 - adjust;
   325 loser:
   326   return rv;
   327 }

mercurial