security/manager/ssl/src/nsStreamCipher.cpp

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "nsIKeyModule.h"
     6 #include "nsStreamCipher.h"
     7 #include "nsStreamUtils.h"
     8 #include "base64.h"
    10 NS_IMPL_ISUPPORTS(nsStreamCipher, nsIStreamCipher)
    12 nsStreamCipher::nsStreamCipher()
    13   : mContext(nullptr)
    14 {
    15 }
    17 nsStreamCipher::~nsStreamCipher()
    18 {
    19   if (mContext)
    20     PK11_DestroyContext(mContext, true /* free sub-objects */);
    21 }
    23 nsresult
    24 nsStreamCipher::InitWithIV_(nsIKeyObject *aKey, SECItem* aIV)
    25 {
    26   NS_ENSURE_ARG_POINTER(aKey);
    28   // Make sure we have a SYM_KEY.
    29   int16_t keyType;
    30   nsresult rv = aKey->GetType(&keyType);
    31   NS_ENSURE_SUCCESS(rv, rv);
    32   if (keyType != nsIKeyObject::SYM_KEY)
    33     return NS_ERROR_INVALID_ARG;
    35   if (mContext)
    36     PK11_DestroyContext(mContext, true /* free sub-objects */);
    38   // Get the PK11SymKey out of the key object and create the PK11Context.
    39   void* keyObj;
    40   rv = aKey->GetKeyObj(&keyObj);
    41   NS_ENSURE_SUCCESS(rv, rv);
    43   PK11SymKey *symkey = reinterpret_cast<PK11SymKey*>(keyObj);
    44   if (!symkey)
    45     return NS_ERROR_FAILURE;
    47   CK_MECHANISM_TYPE cipherMech = PK11_GetMechanism(symkey);
    49   SECItem *param = nullptr;
    50   // aIV may be null
    51   param = PK11_ParamFromIV(cipherMech, aIV);
    52   if (!param)
    53     return NS_ERROR_FAILURE;
    55   mContext = PK11_CreateContextBySymKey(cipherMech, CKA_ENCRYPT,
    56                                         symkey, param);
    58   SECITEM_FreeItem(param, true);
    60   // Something went wrong if mContext doesn't exist.
    61   if (!mContext)
    62     return NS_ERROR_FAILURE;
    64   // Everything went ok.      
    65   mValue.Truncate();
    66   return NS_OK;
    67 }
    69 /////////////////////////////////////////////////////////////////////////////
    70 // nsIStreamCipher
    72 NS_IMETHODIMP nsStreamCipher::Init(nsIKeyObject *aKey)
    73 {
    74   return InitWithIV_(aKey, nullptr);
    75 }
    77 NS_IMETHODIMP nsStreamCipher::InitWithIV(nsIKeyObject *aKey,
    78                                          const uint8_t *aIV, uint32_t aIVLen)
    79 {
    80   SECItem IV;
    81   IV.data = (unsigned char*)aIV;
    82   IV.len = aIVLen;
    83   return InitWithIV_(aKey, &IV);
    84 }
    86 NS_IMETHODIMP nsStreamCipher::Update(const uint8_t *aData, uint32_t aLen)
    87 {
    88   if (!mContext)
    89     return NS_ERROR_NOT_INITIALIZED;
    91   unsigned char* output = new unsigned char[aLen];
    92   unsigned char* input = (unsigned char*)aData;
    94   int32_t setLen;
    96 #ifdef DEBUG
    97   SECStatus rv =
    98 #endif
    99     PK11_CipherOp(mContext, output, &setLen, aLen, input, aLen);
   100   NS_ASSERTION(rv == SECSuccess, "failed to encrypt");
   101   NS_ASSERTION((uint32_t)setLen == aLen, "data length should not change");
   103   mValue.Append((const char*)output, aLen);
   105   delete [] output;
   107   return NS_OK;
   108 }
   110 NS_IMETHODIMP nsStreamCipher::UpdateFromStream(nsIInputStream *aStream,
   111                                                int32_t aLen)
   112 {
   113   if (!mContext)
   114     return NS_ERROR_NOT_INITIALIZED;
   116   nsCString inputString;
   117   nsresult rv = NS_ConsumeStream(aStream, aLen, inputString);
   118   NS_ENSURE_SUCCESS(rv, rv);
   120   return UpdateFromString(inputString);
   121 }
   123 NS_IMETHODIMP nsStreamCipher::UpdateFromString(const nsACString& aInput)
   124 {
   125   if (!mContext)
   126     return NS_ERROR_NOT_INITIALIZED;
   128   const nsCString& flatInput = PromiseFlatCString(aInput);
   129   unsigned char* input = (unsigned char*)flatInput.get();
   130   uint32_t len = aInput.Length();
   132   unsigned char* output = new unsigned char[len];
   134   int32_t setLen;
   136 #ifdef DEBUG
   137   SECStatus rv =
   138 #endif
   139     PK11_CipherOp(mContext, output, &setLen, len, input, len);
   140   NS_ASSERTION(rv == SECSuccess, "failed to encrypt");
   141   NS_ASSERTION((uint32_t)setLen == len, "data length should not change");
   143   mValue.Append((const char*)output, len);
   144   delete [] output;
   146   return NS_OK;
   147 }
   149 NS_IMETHODIMP nsStreamCipher::Finish(bool aASCII, nsACString & _retval)
   150 {
   151   if (!mContext)
   152     return NS_ERROR_NOT_INITIALIZED;
   154   if (aASCII) {
   155     char *asciiData = BTOA_DataToAscii((unsigned char*)(mValue.get()),
   156                                        mValue.Length());
   157     _retval.Assign(asciiData);
   158     PORT_Free(asciiData);
   159   } else {
   160     _retval.Assign(mValue);
   161   }
   163   return NS_OK;
   164 }
   166 NS_IMETHODIMP nsStreamCipher::Discard(int32_t aLen)
   167 {
   168   if (!mContext)
   169     return NS_ERROR_NOT_INITIALIZED;
   171   unsigned char* output = new unsigned char[aLen];
   172   unsigned char* input = new unsigned char[aLen];
   174   int32_t setLen;
   176 #ifdef DEBUG
   177   SECStatus rv =
   178 #endif
   179     PK11_CipherOp(mContext, output, &setLen, aLen, input, aLen);
   180   NS_ASSERTION(rv == SECSuccess, "failed to encrypt");
   181   NS_ASSERTION(setLen == aLen, "data length should not change");
   183   delete [] output;
   184   delete [] input;
   185   return NS_OK;
   186 }

mercurial