Line data Source code
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/. */
4 :
5 : #include "nsCOMPtr.h"
6 : #include "nsComponentManagerUtils.h"
7 : #include "nsKeyModule.h"
8 : #include "nsString.h"
9 :
10 : using namespace mozilla;
11 : using namespace mozilla::psm;
12 :
13 0 : NS_IMPL_ISUPPORTS(nsKeyObject, nsIKeyObject)
14 :
15 0 : nsKeyObject::nsKeyObject()
16 0 : : mSymKey(nullptr)
17 : {
18 0 : }
19 :
20 0 : nsKeyObject::~nsKeyObject()
21 : {
22 0 : nsNSSShutDownPreventionLock locker;
23 0 : if (isAlreadyShutDown()) {
24 0 : return;
25 : }
26 0 : destructorSafeDestroyNSSReference();
27 0 : shutdown(ShutdownCalledFrom::Object);
28 0 : }
29 :
30 : void
31 0 : nsKeyObject::virtualDestroyNSSReference()
32 : {
33 0 : destructorSafeDestroyNSSReference();
34 0 : }
35 :
36 : void
37 0 : nsKeyObject::destructorSafeDestroyNSSReference()
38 : {
39 0 : mSymKey = nullptr;
40 0 : }
41 :
42 : //////////////////////////////////////////////////////////////////////////////
43 : // nsIKeyObject
44 :
45 : NS_IMETHODIMP
46 0 : nsKeyObject::InitKey(int16_t aAlgorithm, PK11SymKey* aKey)
47 : {
48 0 : if (!aKey || aAlgorithm != nsIKeyObject::HMAC) {
49 0 : return NS_ERROR_INVALID_ARG;
50 : }
51 :
52 0 : nsNSSShutDownPreventionLock locker;
53 0 : if (isAlreadyShutDown()) {
54 0 : return NS_ERROR_NOT_AVAILABLE;
55 : }
56 :
57 0 : mSymKey.reset(aKey);
58 0 : return NS_OK;
59 : }
60 :
61 : NS_IMETHODIMP
62 0 : nsKeyObject::GetKeyObj(PK11SymKey** _retval)
63 : {
64 0 : if (!_retval) {
65 0 : return NS_ERROR_INVALID_ARG;
66 : }
67 :
68 0 : *_retval = nullptr;
69 :
70 0 : nsNSSShutDownPreventionLock locker;
71 0 : if (isAlreadyShutDown()) {
72 0 : return NS_ERROR_NOT_AVAILABLE;
73 : }
74 :
75 0 : if (!mSymKey) {
76 0 : return NS_ERROR_NOT_INITIALIZED;
77 : }
78 :
79 0 : *_retval = mSymKey.get();
80 0 : return NS_OK;
81 : }
82 :
83 : NS_IMETHODIMP
84 0 : nsKeyObject::GetType(int16_t *_retval)
85 : {
86 0 : if (!_retval) {
87 0 : return NS_ERROR_INVALID_ARG;
88 : }
89 0 : *_retval = nsIKeyObject::SYM_KEY;
90 0 : return NS_OK;
91 : }
92 :
93 : //////////////////////////////////////////////////////////////////////////////
94 : // nsIKeyObjectFactory
95 :
96 0 : NS_IMPL_ISUPPORTS(nsKeyObjectFactory, nsIKeyObjectFactory)
97 :
98 0 : nsKeyObjectFactory::nsKeyObjectFactory()
99 : {
100 0 : }
101 :
102 0 : nsKeyObjectFactory::~nsKeyObjectFactory()
103 : {
104 0 : nsNSSShutDownPreventionLock locker;
105 0 : if (isAlreadyShutDown()) {
106 0 : return;
107 : }
108 0 : shutdown(ShutdownCalledFrom::Object);
109 0 : }
110 :
111 : NS_IMETHODIMP
112 0 : nsKeyObjectFactory::KeyFromString(int16_t aAlgorithm, const nsACString& aKey,
113 : nsIKeyObject** _retval)
114 : {
115 0 : if (!_retval || aAlgorithm != nsIKeyObject::HMAC) {
116 0 : return NS_ERROR_INVALID_ARG;
117 : }
118 :
119 0 : nsNSSShutDownPreventionLock locker;
120 0 : if (isAlreadyShutDown()) {
121 0 : return NS_ERROR_NOT_AVAILABLE;
122 : }
123 :
124 0 : CK_MECHANISM_TYPE cipherMech = CKM_GENERIC_SECRET_KEY_GEN;
125 0 : CK_ATTRIBUTE_TYPE cipherOperation = CKA_SIGN;
126 :
127 : nsresult rv;
128 : nsCOMPtr<nsIKeyObject> key(
129 0 : do_CreateInstance(NS_KEYMODULEOBJECT_CONTRACTID, &rv));
130 0 : if (NS_FAILED(rv)) {
131 0 : return rv;
132 : }
133 :
134 : // Convert the raw string into a SECItem
135 0 : const nsCString& flatKey = PromiseFlatCString(aKey);
136 : SECItem keyItem;
137 0 : keyItem.data = (unsigned char*)flatKey.get();
138 0 : keyItem.len = flatKey.Length();
139 :
140 0 : UniquePK11SlotInfo slot(PK11_GetBestSlot(cipherMech, nullptr));
141 0 : if (!slot) {
142 0 : return NS_ERROR_FAILURE;
143 : }
144 :
145 : UniquePK11SymKey symKey(PK11_ImportSymKey(slot.get(), cipherMech,
146 : PK11_OriginUnwrap, cipherOperation,
147 0 : &keyItem, nullptr));
148 0 : if (!symKey) {
149 0 : return NS_ERROR_FAILURE;
150 : }
151 :
152 0 : rv = key->InitKey(aAlgorithm, symKey.release());
153 0 : if (NS_FAILED(rv)) {
154 0 : return rv;
155 : }
156 :
157 0 : key.swap(*_retval);
158 0 : return NS_OK;
159 : }
|