diff --git a/mozilla/security/manager/ssl/public/Makefile.in b/mozilla/security/manager/ssl/public/Makefile.in index 91a9071d75e..9db7f425327 100644 --- a/mozilla/security/manager/ssl/public/Makefile.in +++ b/mozilla/security/manager/ssl/public/Makefile.in @@ -91,6 +91,8 @@ XPIDLSRCS = \ nsICRLManager.idl \ nsISMimeCert.idl \ nsICipherInfo.idl \ + nsIStreamCipher.idl \ + nsIKeyModule.idl \ $(NULL) ifdef MOZ_XUL diff --git a/mozilla/security/manager/ssl/public/nsIKeyModule.idl b/mozilla/security/manager/ssl/public/nsIKeyModule.idl new file mode 100644 index 00000000000..82924f80072 --- /dev/null +++ b/mozilla/security/manager/ssl/public/nsIKeyModule.idl @@ -0,0 +1,78 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tony Chang + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" + +// An opaque key object. +[scriptable, uuid(4b31f4ed-9424-4710-b946-79b7e33cf3a8)] +interface nsIKeyObject : nsISupports +{ + // Key types + const short SYM_KEY = 1; + const short PRIVATE_KEY = 2; + const short PUBLIC_KEY = 3; + + // Algorithm types + const short RC4 = 1; + const short AES_CBC = 2; + + // aAlgorithm is an algorithm type + // aKey is either a PK11SymKey, SECKEYPublicKey, or a SECKEYPrivateKey. + // The nsIKeyObject will take ownership of the key and be responsible + // for freeing the key memory when destroyed. + [noscript] void initKey(in short aAlgorithm, in voidPtr aKey); + + // Return a pointer to the underlying key object + [noscript] voidPtr getKeyObj(); + + // Will return NS_ERROR_NOT_INITIALIZED if initKey hasn't been run + short getType(); +}; + +[scriptable, uuid(264eb54d-e20d-49a0-890c-1a5986ea81c4)] +interface nsIKeyObjectFactory : nsISupports +{ + nsIKeyObject lookupKeyByName(in ACString aName); + + nsIKeyObject unwrapKey(in short aAlgorithm, + [const, array, size_is(aWrappedKeyLen)] in octet aWrappedKey, + in unsigned long aWrappedKeyLen); + + // TODO: deriveKeyFrom* + + + // DO NOT USE + // This is not FIPS compliant and should not be used. + nsIKeyObject keyFromString(in short aAlgorithm, in ACString aKey); +}; diff --git a/mozilla/security/manager/ssl/public/nsIStreamCipher.idl b/mozilla/security/manager/ssl/public/nsIStreamCipher.idl new file mode 100644 index 00000000000..bb743c45428 --- /dev/null +++ b/mozilla/security/manager/ssl/public/nsIStreamCipher.idl @@ -0,0 +1,91 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tony Chang + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsISupports.idl" +#include "nsIKeyModule.idl" + +interface nsIInputStream; + +/** + * Stream cipher interface. We're basically copying the interface from + * nsICryptoHash interface. + */ +[scriptable, uuid(1d507cd6-1630-4710-af1b-4012dbcc514c)] +interface nsIStreamCipher : nsISupports +{ + /** + * Initialize a stream cipher. + * @param aKey nsIKeyObject + */ + void init(in nsIKeyObject aKey); + + /** + * Initialize a stream cipher with an initialization vector. + * @param aKey nsIKeyObject + * @param aIV the initialization vector + * @param aIVLen the length of the initialization vector + */ + void initWithIV(in nsIKeyObject aKey, + [const, array, size_is(aIVLen)] in octet aIV, + in unsigned long aIVLen); + + /** + * Update from an array of bytes. + */ + void update([const, array, size_is(aLen)] in octet aData, in unsigned long aLen); + + /** + * Update from a stream. + */ + void updateFromStream(in nsIInputStream aStream, in long aLen); + + /** + * A more script friendly method (not in nsICryptoHash interface). + */ + void updateFromString(in ACString aInput); + + /** + * @param aASCII if true then the returned value is a base-64 + * encoded string. if false, then the returned value is + * binary data. + */ + ACString finish(in PRBool aASCII); + + /** + * Discard aLen bytes of the keystream. + * These days 1536 is considered a decent amount to drop to get + * the key state warmed-up enough for secure usage. + */ + void discard(in long aLen); +}; diff --git a/mozilla/security/manager/ssl/src/Makefile.in b/mozilla/security/manager/ssl/src/Makefile.in index d99e9bd8f7c..949f33576c6 100644 --- a/mozilla/security/manager/ssl/src/Makefile.in +++ b/mozilla/security/manager/ssl/src/Makefile.in @@ -92,6 +92,8 @@ CPPSRCS = \ nsNTLMAuthModule.cpp \ nsSmartCardMonitor.cpp \ nsSmartCardEvent.cpp \ + nsStreamCipher.cpp \ + nsKeyModule.cpp \ $(NULL) ifdef MOZ_XUL diff --git a/mozilla/security/manager/ssl/src/nsKeyModule.cpp b/mozilla/security/manager/ssl/src/nsKeyModule.cpp new file mode 100644 index 00000000000..40d3affb06b --- /dev/null +++ b/mozilla/security/manager/ssl/src/nsKeyModule.cpp @@ -0,0 +1,215 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tony Chang + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsComponentManagerUtils.h" +#include "nsCOMPtr.h" +#include "nsKeyModule.h" +#include "nsString.h" + +NS_IMPL_ISUPPORTS1(nsKeyObject, nsIKeyObject) + +nsKeyObject::nsKeyObject() + : mKeyType(0), mSymKey(nsnull), mPrivateKey(nsnull), + mPublicKey(nsnull) +{ +} + +nsKeyObject::~nsKeyObject() +{ + CleanUp(); +} + +void +nsKeyObject::CleanUp() +{ + switch (mKeyType) { + case nsIKeyObject::SYM_KEY: + PK11_FreeSymKey(mSymKey); + break; + + case nsIKeyObject::PRIVATE_KEY: + PK11_DeleteTokenPrivateKey(mPrivateKey, PR_TRUE /* force */); + break; + + case nsIKeyObject::PUBLIC_KEY: + PK11_DeleteTokenPublicKey(mPublicKey); + break; + + default: + // probably not initialized, do nothing + break; + } + mKeyType = 0; +} + +////////////////////////////////////////////////////////////////////////////// +// nsIKeyObject + +/* [noscript] void initKey (in short aKeyType, in voidPtr aKey); */ +NS_IMETHODIMP +nsKeyObject::InitKey(PRInt16 aAlgorithm, void * aKey) +{ + // Clear previous key data if it exists + CleanUp(); + + switch (aAlgorithm) { + case nsIKeyObject::RC4: + mSymKey = NS_REINTERPRET_CAST(PK11SymKey*, aKey); + + if (!mSymKey) { + NS_ERROR("no symkey"); + break; + } + mKeyType = nsIKeyObject::SYM_KEY; + break; + + case nsIKeyObject::AES_CBC: + return NS_ERROR_NOT_IMPLEMENTED; + + default: + return NS_ERROR_INVALID_ARG; + } + + // One of these should have been created + if (!mSymKey && !mPrivateKey && !mPublicKey) + return NS_ERROR_FAILURE; + + return NS_OK; +} + +/* [noscript] voidPtr getKeyObj (); */ +NS_IMETHODIMP +nsKeyObject::GetKeyObj(void * *_retval) +{ + if (mKeyType == 0) + return NS_ERROR_NOT_INITIALIZED; + + switch (mKeyType) { + case nsIKeyObject::SYM_KEY: + *_retval = (void*)mSymKey; + break; + + case nsIKeyObject::PRIVATE_KEY: + *_retval = (void*)mPublicKey; + break; + + case nsIKeyObject::PUBLIC_KEY: + *_retval = (void*)mPrivateKey; + break; + + default: + // unknown key type? How did that happen? + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +/* short getType (); */ +NS_IMETHODIMP +nsKeyObject::GetType(PRInt16 *_retval) +{ + if (mKeyType == 0) + return NS_ERROR_NOT_INITIALIZED; + + *_retval = mKeyType; + return NS_OK; +} + +////////////////////////////////////////////////////////////////////////////// +// nsIKeyObjectFactory + +NS_IMPL_ISUPPORTS1(nsKeyObjectFactory, nsIKeyObjectFactory) + +nsKeyObjectFactory::nsKeyObjectFactory() +{ +} + +/* nsIKeyObject lookupKeyByName (in ACString aName); */ +NS_IMETHODIMP +nsKeyObjectFactory::LookupKeyByName(const nsACString & aName, + nsIKeyObject **_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsKeyObjectFactory::UnwrapKey(PRInt16 aAlgorithm, const PRUint8 *aWrappedKey, + PRUint32 aWrappedKeyLen, nsIKeyObject **_retval) +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsKeyObjectFactory::KeyFromString(PRInt16 aAlgorithm, const nsACString & aKey, + nsIKeyObject **_retval) +{ + if (aAlgorithm != nsIKeyObject::RC4) + return NS_ERROR_INVALID_ARG; + + nsresult rv; + nsCOMPtr key = + do_CreateInstance(NS_KEYMODULEOBJECT_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + // Convert the raw string into a SECItem + const nsCString& flatKey = PromiseFlatCString(aKey); + SECItem keyItem; + keyItem.data = (unsigned char*)flatKey.get(); + keyItem.len = flatKey.Length(); + + PK11SlotInfo *slot = nsnull; + CK_MECHANISM_TYPE cipherMech; + cipherMech = CKM_RC4; + slot = PK11_GetBestSlot(cipherMech, nsnull); + if (!slot) { + NS_ERROR("no slot"); + return NS_ERROR_FAILURE; + } + + PK11SymKey* symKey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap, + CKA_ENCRYPT, &keyItem, nsnull); + // cleanup code + if (slot) + PK11_FreeSlot(slot); + + if (!symKey) { + return NS_ERROR_FAILURE; + } + + rv = key->InitKey(aAlgorithm, (void*)symKey); + NS_ENSURE_SUCCESS(rv, rv); + + key.swap(*_retval); + return NS_OK; +} diff --git a/mozilla/security/manager/ssl/src/nsKeyModule.h b/mozilla/security/manager/ssl/src/nsKeyModule.h new file mode 100644 index 00000000000..41902bc1432 --- /dev/null +++ b/mozilla/security/manager/ssl/src/nsKeyModule.h @@ -0,0 +1,96 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tony Chang + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _NS_KEYMODULE_H_ +#define _NS_KEYMODULE_H_ + +#include "nsIKeyModule.h" +#include "pk11pub.h" + +#define NS_KEYMODULEOBJECT_CLASSNAME "Key Object Component" +/* eae599aa-ecef-49c6-a8af-6ddcc6feb484 */ +#define NS_KEYMODULEOBJECT_CID \ +{ 0xeae599aa, 0xecef, 0x49c6, {0xa8, 0xaf, 0x6d, 0xdc, 0xc6, 0xfe, 0xb4, 0x84} } +#define NS_KEYMODULEOBJECT_CONTRACTID "@mozilla.org/security/keyobject;1" + +#define NS_KEYMODULEOBJECTFACTORY_CLASSNAME "Key Object Factory Component" +/* a39e0e9d-e567-41e3-b12c-5df67f18174d */ +#define NS_KEYMODULEOBJECTFACTORY_CID \ +{ 0xa39e0e9d, 0xe567, 0x41e3, {0xb1, 0x2c, 0x5d, 0xf6, 0x7f, 0x18, 0x17, 0x4d} } +#define NS_KEYMODULEOBJECTFACTORY_CONTRACTID \ +"@mozilla.org/security/keyobjectfactory;1" + +class nsKeyObject : public nsIKeyObject +{ +public: + nsKeyObject(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIKEYOBJECT + +private: + ~nsKeyObject(); + + // Disallow copy constructor + nsKeyObject(nsKeyObject&); + + // 0 if not yet set, otherwise one of the nsIKeyObject::*KEY values + PRUint32 mKeyType; + + // A union of our possible key types + PK11SymKey* mSymKey; + SECKEYPrivateKey* mPrivateKey; + SECKEYPublicKey* mPublicKey; + + // Helper method to free memory used by keys. + void CleanUp(); +}; + + +class nsKeyObjectFactory : public nsIKeyObjectFactory +{ +public: + nsKeyObjectFactory(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIKEYOBJECTFACTORY + +private: + ~nsKeyObjectFactory() {}; + + // Disallow copy constructor + nsKeyObjectFactory(nsKeyObjectFactory&); +}; + +#endif // _NS_KEYMODULE_H_ diff --git a/mozilla/security/manager/ssl/src/nsNSSModule.cpp b/mozilla/security/manager/ssl/src/nsNSSModule.cpp index 1d237925528..7c6baae3314 100644 --- a/mozilla/security/manager/ssl/src/nsNSSModule.cpp +++ b/mozilla/security/manager/ssl/src/nsNSSModule.cpp @@ -69,6 +69,8 @@ #include "nsCRLManager.h" #include "nsCipherInfo.h" #include "nsNTLMAuthModule.h" +#include "nsStreamCipher.h" +#include "nsKeyModule.h" // We must ensure that the nsNSSComponent has been loaded before // creating any other components. @@ -184,6 +186,9 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsCRLManager) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsCipherInfoService) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(PR_FALSE, nsNTLMAuthModule, InitTest) NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsCryptoHash) +NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsStreamCipher) +NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsKeyObject) +NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(PR_FALSE, nsKeyObjectFactory) static NS_METHOD RegisterPSMContentListeners( nsIComponentManager *aCompMgr, @@ -404,6 +409,27 @@ static const nsModuleComponentInfo components[] = NS_NTLMAUTHMODULE_CID, NS_NTLMAUTHMODULE_CONTRACTID, nsNTLMAuthModuleConstructor + }, + + { + NS_STREAMCIPHER_CLASSNAME, + NS_STREAMCIPHER_CID, + NS_STREAMCIPHER_CONTRACTID, + nsStreamCipherConstructor + }, + + { + NS_KEYMODULEOBJECT_CLASSNAME, + NS_KEYMODULEOBJECT_CID, + NS_KEYMODULEOBJECT_CONTRACTID, + nsKeyObjectConstructor + }, + + { + NS_KEYMODULEOBJECTFACTORY_CLASSNAME, + NS_KEYMODULEOBJECTFACTORY_CID, + NS_KEYMODULEOBJECTFACTORY_CONTRACTID, + nsKeyObjectFactoryConstructor } }; diff --git a/mozilla/security/manager/ssl/src/nsStreamCipher.cpp b/mozilla/security/manager/ssl/src/nsStreamCipher.cpp new file mode 100644 index 00000000000..55b30c69a18 --- /dev/null +++ b/mozilla/security/manager/ssl/src/nsStreamCipher.cpp @@ -0,0 +1,214 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tony Chang + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsIKeyModule.h" +#include "nsStreamCipher.h" +#include "nsStreamUtils.h" +#include "base64.h" + +NS_IMPL_ISUPPORTS1(nsStreamCipher, nsIStreamCipher) + +nsStreamCipher::nsStreamCipher() + : mContext(NULL) +{ +} + +nsStreamCipher::~nsStreamCipher() +{ + if (mContext) + PK11_DestroyContext(mContext, PR_TRUE /* free sub-objects */); +} + +nsresult +nsStreamCipher::InitWithIV_(nsIKeyObject *aKey, const SECItem* aIV) +{ + NS_ENSURE_ARG_POINTER(aKey); + + // Make sure we have a SYM_KEY. + PRInt16 keyType; + nsresult rv = aKey->GetType(&keyType); + NS_ENSURE_SUCCESS(rv, rv); + if (keyType != nsIKeyObject::SYM_KEY) + return NS_ERROR_INVALID_ARG; + + if (mContext) + PK11_DestroyContext(mContext, PR_TRUE /* free sub-objects */); + + // Get the PK11SymKey out of the key object and create the PK11Context. + void* keyObj; + rv = aKey->GetKeyObj(&keyObj); + NS_ENSURE_SUCCESS(rv, rv); + + PK11SymKey *symkey = NS_REINTERPRET_CAST(PK11SymKey*, keyObj); + if (!symkey) + return NS_ERROR_FAILURE; + + CK_MECHANISM_TYPE cipherMech = PK11_GetMechanism(symkey); + SECItem *param = nsnull; + // aIV may be null + param = PK11_ParamFromIV(cipherMech, aIV); + if (!param) + return NS_ERROR_FAILURE; + + mContext = PK11_CreateContextBySymKey(cipherMech, CKA_ENCRYPT, + symkey, param); + + SECITEM_FreeItem(param, PR_TRUE); + + // Something went wrong if mContext doesn't exist. + if (!mContext) + return NS_ERROR_FAILURE; + + // Everything went ok. + mValue.Truncate(); + return NS_OK; +} + +///////////////////////////////////////////////////////////////////////////// +// nsIStreamCipher + +NS_IMETHODIMP nsStreamCipher::Init(nsIKeyObject *aKey) +{ + return InitWithIV_(aKey, nsnull); +} + +NS_IMETHODIMP nsStreamCipher::InitWithIV(nsIKeyObject *aKey, + const PRUint8 *aIV, PRUint32 aIVLen) +{ + SECItem IV; + IV.data = aIV; + IV.len = aIVLen; + return InitWithIV_(aKey, &IV); +} + +NS_IMETHODIMP nsStreamCipher::Update(const PRUint8 *aData, PRUint32 aLen) +{ + if (!mContext) + return NS_ERROR_NOT_INITIALIZED; + + unsigned char* output = new unsigned char[aLen]; + if (!output) + return NS_ERROR_OUT_OF_MEMORY; + unsigned char* input = (unsigned char*)aData; + + PRInt32 setLen; + SECStatus rv = PK11_CipherOp(mContext, output, &setLen, aLen, input, aLen); + NS_ASSERTION(rv == SECSuccess, "failed to encrypt"); + NS_ASSERTION((PRUint32)setLen == aLen, "data length should not change"); + + mValue.Append((const char*)output, aLen); + + delete [] output; + + return NS_OK; +} + +NS_IMETHODIMP nsStreamCipher::UpdateFromStream(nsIInputStream *aStream, + PRInt32 aLen) +{ + if (!mContext) + return NS_ERROR_NOT_INITIALIZED; + + nsCString inputString; + nsresult rv = NS_ConsumeStream(aStream, aLen, inputString); + NS_ENSURE_SUCCESS(rv, rv); + + return UpdateFromString(inputString); +} + +NS_IMETHODIMP nsStreamCipher::UpdateFromString(const nsACString& aInput) +{ + if (!mContext) + return NS_ERROR_NOT_INITIALIZED; + + const nsCString& flatInput = PromiseFlatCString(aInput); + unsigned char* input = (unsigned char*)flatInput.get(); + PRUint32 len = aInput.Length(); + + unsigned char* output = new unsigned char[len]; + if (!output) + return NS_ERROR_OUT_OF_MEMORY; + + PRInt32 setLen; + SECStatus rv = PK11_CipherOp(mContext, output, &setLen, len, input, len); + NS_ASSERTION(rv == SECSuccess, "failed to encrypt"); + NS_ASSERTION((PRUint32)setLen == len, "data length should not change"); + + mValue.Append((const char*)output, len); + delete [] output; + + return NS_OK; +} + +NS_IMETHODIMP nsStreamCipher::Finish(PRBool aASCII, nsACString & _retval) +{ + if (!mContext) + return NS_ERROR_NOT_INITIALIZED; + + if (aASCII) { + char *asciiData = BTOA_DataToAscii((unsigned char*)(mValue.get()), + mValue.Length()); + _retval.Assign(asciiData); + PORT_Free(asciiData); + } else { + _retval.Assign(mValue); + } + + return NS_OK; +} + +NS_IMETHODIMP nsStreamCipher::Discard(PRInt32 aLen) +{ + if (!mContext) + return NS_ERROR_NOT_INITIALIZED; + + unsigned char* output = new unsigned char[aLen]; + if (!output) + return NS_ERROR_OUT_OF_MEMORY; + + unsigned char* input = new unsigned char[aLen]; + if (!input) { + delete [] output; + return NS_ERROR_OUT_OF_MEMORY; + } + + PRInt32 setLen; + SECStatus rv = PK11_CipherOp(mContext, output, &setLen, aLen, input, aLen); + NS_ASSERTION(rv == SECSuccess, "failed to encrypt"); + NS_ASSERTION(setLen == aLen, "data length should not change"); + + delete [] output; + delete [] input; + return NS_OK; +} diff --git a/mozilla/security/manager/ssl/src/nsStreamCipher.h b/mozilla/security/manager/ssl/src/nsStreamCipher.h new file mode 100644 index 00000000000..869934da065 --- /dev/null +++ b/mozilla/security/manager/ssl/src/nsStreamCipher.h @@ -0,0 +1,73 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is Google Inc. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Tony Chang + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _NS_STREAMCIPHER_H_ +#define _NS_STREAMCIPHER_H_ + +#include "nsIStreamCipher.h" +#include "nsString.h" +#include "pk11func.h" + +#define NS_STREAMCIPHER_CLASSNAME "Stream Cipher Component" +/* dbfcbe4a-10f7-4d6f-a481-68e6d6b71d21 */ +#define NS_STREAMCIPHER_CID \ +{ 0xdbfcbe4a, 0x10f7, 0x4d6f, {0xa4, 0x81, 0x68, 0xe6, 0xd6, 0xb7, 0x1d, 0x21}} +#define NS_STREAMCIPHER_CONTRACTID "@mozilla.org/security/streamcipher;1" + +class nsStreamCipher : public nsIStreamCipher +{ +public: + nsStreamCipher(); + + NS_DECL_ISUPPORTS + NS_DECL_NSISTREAMCIPHER + +private: + ~nsStreamCipher(); + + // Helper method for initializing this object. + // aIV may be null. + nsresult InitWithIV_(nsIKeyObject *aKey, const SECItem* aIV); + + // Disallow copy constructor + nsStreamCipher(nsStreamCipher&); + + // Holds our stream cipher context. + PK11Context* mContext; + + // Holds the amount we've computed so far. + nsCString mValue; +}; + +#endif // _NS_STREAMCIPHER_H_