1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/manager/ssl/src/nsKeyModule.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,198 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +#include "nsComponentManagerUtils.h" 1.9 +#include "nsCOMPtr.h" 1.10 +#include "nsKeyModule.h" 1.11 +#include "nsString.h" 1.12 +#include "ScopedNSSTypes.h" 1.13 + 1.14 +using namespace mozilla; 1.15 +using namespace mozilla::psm; 1.16 + 1.17 +NS_IMPL_ISUPPORTS(nsKeyObject, nsIKeyObject) 1.18 + 1.19 +nsKeyObject::nsKeyObject() 1.20 + : mKeyType(0), mSymKey(nullptr), mPrivateKey(nullptr), 1.21 + mPublicKey(nullptr) 1.22 +{ 1.23 +} 1.24 + 1.25 +nsKeyObject::~nsKeyObject() 1.26 +{ 1.27 + CleanUp(); 1.28 +} 1.29 + 1.30 +void 1.31 +nsKeyObject::CleanUp() 1.32 +{ 1.33 + switch (mKeyType) { 1.34 + case nsIKeyObject::SYM_KEY: 1.35 + PK11_FreeSymKey(mSymKey); 1.36 + break; 1.37 + 1.38 + case nsIKeyObject::PRIVATE_KEY: 1.39 + PK11_DeleteTokenPrivateKey(mPrivateKey, true /* force */); 1.40 + break; 1.41 + 1.42 + case nsIKeyObject::PUBLIC_KEY: 1.43 + PK11_DeleteTokenPublicKey(mPublicKey); 1.44 + break; 1.45 + 1.46 + default: 1.47 + // probably not initialized, do nothing 1.48 + break; 1.49 + } 1.50 + mKeyType = 0; 1.51 +} 1.52 + 1.53 +////////////////////////////////////////////////////////////////////////////// 1.54 +// nsIKeyObject 1.55 + 1.56 +/* [noscript] void initKey (in short aKeyType, in voidPtr aKey); */ 1.57 +NS_IMETHODIMP 1.58 +nsKeyObject::InitKey(int16_t aAlgorithm, void * aKey) 1.59 +{ 1.60 + // Clear previous key data if it exists 1.61 + CleanUp(); 1.62 + 1.63 + switch (aAlgorithm) { 1.64 + case nsIKeyObject::RC4: 1.65 + case nsIKeyObject::HMAC: 1.66 + mSymKey = reinterpret_cast<PK11SymKey*>(aKey); 1.67 + 1.68 + if (!mSymKey) { 1.69 + NS_ERROR("no symkey"); 1.70 + break; 1.71 + } 1.72 + mKeyType = nsIKeyObject::SYM_KEY; 1.73 + break; 1.74 + 1.75 + case nsIKeyObject::AES_CBC: 1.76 + return NS_ERROR_NOT_IMPLEMENTED; 1.77 + 1.78 + default: 1.79 + return NS_ERROR_INVALID_ARG; 1.80 + } 1.81 + 1.82 + // One of these should have been created 1.83 + if (!mSymKey && !mPrivateKey && !mPublicKey) 1.84 + return NS_ERROR_FAILURE; 1.85 + 1.86 + return NS_OK; 1.87 +} 1.88 + 1.89 +/* [noscript] voidPtr getKeyObj (); */ 1.90 +NS_IMETHODIMP 1.91 +nsKeyObject::GetKeyObj(void * *_retval) 1.92 +{ 1.93 + if (mKeyType == 0) 1.94 + return NS_ERROR_NOT_INITIALIZED; 1.95 + 1.96 + switch (mKeyType) { 1.97 + case nsIKeyObject::SYM_KEY: 1.98 + *_retval = (void*)mSymKey; 1.99 + break; 1.100 + 1.101 + case nsIKeyObject::PRIVATE_KEY: 1.102 + *_retval = (void*)mPublicKey; 1.103 + break; 1.104 + 1.105 + case nsIKeyObject::PUBLIC_KEY: 1.106 + *_retval = (void*)mPrivateKey; 1.107 + break; 1.108 + 1.109 + default: 1.110 + // unknown key type? How did that happen? 1.111 + return NS_ERROR_FAILURE; 1.112 + } 1.113 + return NS_OK; 1.114 +} 1.115 + 1.116 +/* short getType (); */ 1.117 +NS_IMETHODIMP 1.118 +nsKeyObject::GetType(int16_t *_retval) 1.119 +{ 1.120 + if (mKeyType == 0) 1.121 + return NS_ERROR_NOT_INITIALIZED; 1.122 + 1.123 + *_retval = mKeyType; 1.124 + return NS_OK; 1.125 +} 1.126 + 1.127 +////////////////////////////////////////////////////////////////////////////// 1.128 +// nsIKeyObjectFactory 1.129 + 1.130 +NS_IMPL_ISUPPORTS(nsKeyObjectFactory, nsIKeyObjectFactory) 1.131 + 1.132 +nsKeyObjectFactory::nsKeyObjectFactory() 1.133 +{ 1.134 +} 1.135 + 1.136 +/* nsIKeyObject lookupKeyByName (in ACString aName); */ 1.137 +NS_IMETHODIMP 1.138 +nsKeyObjectFactory::LookupKeyByName(const nsACString & aName, 1.139 + nsIKeyObject **_retval) 1.140 +{ 1.141 + return NS_ERROR_NOT_IMPLEMENTED; 1.142 +} 1.143 + 1.144 +NS_IMETHODIMP 1.145 +nsKeyObjectFactory::UnwrapKey(int16_t aAlgorithm, const uint8_t *aWrappedKey, 1.146 + uint32_t aWrappedKeyLen, nsIKeyObject **_retval) 1.147 +{ 1.148 + return NS_ERROR_NOT_IMPLEMENTED; 1.149 +} 1.150 + 1.151 +NS_IMETHODIMP 1.152 +nsKeyObjectFactory::KeyFromString(int16_t aAlgorithm, const nsACString & aKey, 1.153 + nsIKeyObject **_retval) 1.154 +{ 1.155 + CK_MECHANISM_TYPE cipherMech; 1.156 + CK_ATTRIBUTE_TYPE cipherOperation; 1.157 + switch (aAlgorithm) 1.158 + { 1.159 + case nsIKeyObject::HMAC: 1.160 + cipherMech = CKM_GENERIC_SECRET_KEY_GEN; 1.161 + cipherOperation = CKA_SIGN; 1.162 + break; 1.163 + 1.164 + case nsIKeyObject::RC4: 1.165 + cipherMech = CKM_RC4; 1.166 + cipherOperation = CKA_ENCRYPT; 1.167 + break; 1.168 + 1.169 + default: 1.170 + return NS_ERROR_INVALID_ARG; 1.171 + } 1.172 + 1.173 + nsresult rv; 1.174 + nsCOMPtr<nsIKeyObject> key = 1.175 + do_CreateInstance(NS_KEYMODULEOBJECT_CONTRACTID, &rv); 1.176 + NS_ENSURE_SUCCESS(rv, rv); 1.177 + 1.178 + // Convert the raw string into a SECItem 1.179 + const nsCString& flatKey = PromiseFlatCString(aKey); 1.180 + SECItem keyItem; 1.181 + keyItem.data = (unsigned char*)flatKey.get(); 1.182 + keyItem.len = flatKey.Length(); 1.183 + 1.184 + ScopedPK11SlotInfo slot(PK11_GetBestSlot(cipherMech, nullptr)); 1.185 + if (!slot) { 1.186 + NS_ERROR("no slot"); 1.187 + return NS_ERROR_FAILURE; 1.188 + } 1.189 + 1.190 + PK11SymKey* symKey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap, 1.191 + cipherOperation, &keyItem, nullptr); 1.192 + if (!symKey) { 1.193 + return NS_ERROR_FAILURE; 1.194 + } 1.195 + 1.196 + rv = key->InitKey(aAlgorithm, (void*)symKey); 1.197 + NS_ENSURE_SUCCESS(rv, rv); 1.198 + 1.199 + key.swap(*_retval); 1.200 + return NS_OK; 1.201 +}