Back to index

lightning-sunbird  0.9+nobinonly
nsKeyModule.cpp
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Initial Developer of the Original Code is Google Inc.
00015  * Portions created by the Initial Developer are Copyright (C) 2006
00016  * the Initial Developer. All Rights Reserved.
00017  *
00018  * Contributor(s):
00019  *   Tony Chang <tc@google.com>
00020  *
00021  * Alternatively, the contents of this file may be used under the terms of
00022  * either the GNU General Public License Version 2 or later (the "GPL"), or
00023  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00024  * in which case the provisions of the GPL or the LGPL are applicable instead
00025  * of those above. If you wish to allow use of your version of this file only
00026  * under the terms of either the GPL or the LGPL, and not to allow others to
00027  * use your version of this file under the terms of the MPL, indicate your
00028  * decision by deleting the provisions above and replace them with the notice
00029  * and other provisions required by the GPL or the LGPL. If you do not delete
00030  * the provisions above, a recipient may use your version of this file under
00031  * the terms of any one of the MPL, the GPL or the LGPL.
00032  *
00033  * ***** END LICENSE BLOCK ***** */
00034 
00035 #include "nsComponentManagerUtils.h"
00036 #include "nsCOMPtr.h"
00037 #include "nsKeyModule.h"
00038 #include "nsString.h"
00039 
00040 NS_IMPL_ISUPPORTS1(nsKeyObject, nsIKeyObject)
00041 
00042 nsKeyObject::nsKeyObject()
00043   : mKeyType(0), mSymKey(nsnull), mPrivateKey(nsnull),
00044     mPublicKey(nsnull)
00045 {
00046 }
00047 
00048 nsKeyObject::~nsKeyObject()
00049 {
00050   CleanUp();
00051 }
00052 
00053 void
00054 nsKeyObject::CleanUp()
00055 {
00056   switch (mKeyType) {
00057     case nsIKeyObject::SYM_KEY:
00058       PK11_FreeSymKey(mSymKey);
00059       break;
00060     
00061     case nsIKeyObject::PRIVATE_KEY:
00062       PK11_DeleteTokenPrivateKey(mPrivateKey, PR_TRUE /* force */);
00063       break;
00064 
00065     case nsIKeyObject::PUBLIC_KEY:
00066       PK11_DeleteTokenPublicKey(mPublicKey);
00067       break;
00068     
00069     default:
00070       // probably not initialized, do nothing
00071       break;
00072   }
00073   mKeyType = 0;
00074 }
00075 
00077 // nsIKeyObject
00078 
00079 /* [noscript] void initKey (in short aKeyType, in voidPtr aKey); */
00080 NS_IMETHODIMP
00081 nsKeyObject::InitKey(PRInt16 aAlgorithm, void * aKey)
00082 {
00083   // Clear previous key data if it exists
00084   CleanUp();
00085 
00086   switch (aAlgorithm) {
00087     case nsIKeyObject::RC4:
00088       mSymKey = NS_REINTERPRET_CAST(PK11SymKey*, aKey);
00089 
00090       if (!mSymKey) {
00091         NS_ERROR("no symkey");
00092         break;
00093       }
00094       mKeyType = nsIKeyObject::SYM_KEY;
00095       break;
00096 
00097     case nsIKeyObject::AES_CBC:
00098       return NS_ERROR_NOT_IMPLEMENTED;
00099 
00100     default:
00101       return NS_ERROR_INVALID_ARG;
00102   }
00103 
00104   // One of these should have been created
00105   if (!mSymKey && !mPrivateKey && !mPublicKey)
00106     return NS_ERROR_FAILURE;
00107 
00108   return NS_OK;
00109 }
00110 
00111 /* [noscript] voidPtr getKeyObj (); */
00112 NS_IMETHODIMP
00113 nsKeyObject::GetKeyObj(void * *_retval)
00114 {
00115   if (mKeyType == 0)
00116     return NS_ERROR_NOT_INITIALIZED;
00117 
00118   switch (mKeyType) {
00119     case nsIKeyObject::SYM_KEY:
00120       *_retval = (void*)mSymKey;
00121       break;
00122 
00123     case nsIKeyObject::PRIVATE_KEY:
00124       *_retval = (void*)mPublicKey;
00125       break;
00126 
00127     case nsIKeyObject::PUBLIC_KEY:
00128       *_retval = (void*)mPrivateKey;
00129       break;
00130 
00131     default:
00132       // unknown key type?  How did that happen?
00133       return NS_ERROR_FAILURE;
00134   }
00135   return NS_OK;
00136 }
00137 
00138 /* short getType (); */
00139 NS_IMETHODIMP
00140 nsKeyObject::GetType(PRInt16 *_retval)
00141 {
00142   if (mKeyType == 0)
00143     return NS_ERROR_NOT_INITIALIZED;
00144 
00145   *_retval = mKeyType;
00146   return NS_OK;
00147 }
00148 
00150 // nsIKeyObjectFactory
00151 
00152 NS_IMPL_ISUPPORTS1(nsKeyObjectFactory, nsIKeyObjectFactory)
00153 
00154 nsKeyObjectFactory::nsKeyObjectFactory()
00155 {
00156 }
00157 
00158 /* nsIKeyObject lookupKeyByName (in ACString aName); */
00159 NS_IMETHODIMP
00160 nsKeyObjectFactory::LookupKeyByName(const nsACString & aName,
00161                                     nsIKeyObject **_retval)
00162 {
00163   return NS_ERROR_NOT_IMPLEMENTED;
00164 }
00165  
00166 NS_IMETHODIMP
00167 nsKeyObjectFactory::UnwrapKey(PRInt16 aAlgorithm, const PRUint8 *aWrappedKey,
00168                               PRUint32 aWrappedKeyLen, nsIKeyObject **_retval)
00169 {
00170   return NS_ERROR_NOT_IMPLEMENTED;
00171 }
00172 
00173 NS_IMETHODIMP
00174 nsKeyObjectFactory::KeyFromString(PRInt16 aAlgorithm, const nsACString & aKey,
00175                                   nsIKeyObject **_retval)
00176 {
00177   if (aAlgorithm != nsIKeyObject::RC4)
00178     return NS_ERROR_INVALID_ARG;
00179   
00180   nsresult rv;
00181   nsCOMPtr<nsIKeyObject> key =
00182       do_CreateInstance(NS_KEYMODULEOBJECT_CONTRACTID, &rv);
00183   NS_ENSURE_SUCCESS(rv, rv);
00184 
00185   // Convert the raw string into a SECItem
00186   const nsCString& flatKey = PromiseFlatCString(aKey);
00187   SECItem keyItem;
00188   keyItem.data = (unsigned char*)flatKey.get();
00189   keyItem.len = flatKey.Length();
00190 
00191   PK11SlotInfo *slot = nsnull;
00192   CK_MECHANISM_TYPE cipherMech;
00193   cipherMech = CKM_RC4;
00194   slot = PK11_GetBestSlot(cipherMech, nsnull);
00195   if (!slot) {
00196     NS_ERROR("no slot");
00197     return NS_ERROR_FAILURE;
00198   }
00199 
00200   PK11SymKey* symKey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap,
00201                                          CKA_ENCRYPT, &keyItem, nsnull);
00202   // cleanup code
00203   if (slot)
00204     PK11_FreeSlot(slot);
00205 
00206   if (!symKey) {
00207     return NS_ERROR_FAILURE;
00208   }
00209   
00210   rv = key->InitKey(aAlgorithm, (void*)symKey);
00211   NS_ENSURE_SUCCESS(rv, rv);
00212 
00213   key.swap(*_retval);
00214   return NS_OK;
00215 }