~ubuntu-branches/ubuntu/precise/nss/precise-security

« back to all changes in this revision

Viewing changes to mozilla/security/nss/lib/ckfw/hash.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2013-11-14 14:58:07 UTC
  • mfrom: (1.1.19)
  • Revision ID: package-import@ubuntu.com-20131114145807-ay302kimn72ovt88
Tags: 3.15.3-0ubuntu0.12.04.1
* SECURITY UPDATE: New upstream release to fix multiple security issues
  and add TLSv1.2 support.
  - CVE-2013-1739
  - CVE-2013-1741
  - CVE-2013-5605
  - CVE-2013-5606
* Adjusted packaging for 3.15.3:
  - debian/patches/*: refreshed.
  - debian/patches/lower-dhe-priority.patch: removed, no longer needed,
    was a workaround for an old version of firefox.
  - debian/libnss3.symbols: added new symbols.
  - debian/rules: updated for new source layout.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
#ifdef DEBUG
6
 
static const char CVS_ID[] = "@(#) $RCSfile: hash.c,v $ $Revision: 1.6 $ $Date: 2012/04/25 14:49:28 $";
7
 
#endif /* DEBUG */
8
 
 
9
 
/*
10
 
 * hash.c
11
 
 *
12
 
 * This is merely a couple wrappers around NSPR's PLHashTable, using
13
 
 * the identity hash and arena-aware allocators.  The reason I did
14
 
 * this is that hash tables are used in a few places throughout the
15
 
 * NSS Cryptoki Framework in a fairly stereotyped way, and this allows
16
 
 * me to pull the commonalities into one place.  Should we ever want
17
 
 * to change the implementation, it's all right here.
18
 
 */
19
 
 
20
 
#ifndef CK_T
21
 
#include "ck.h"
22
 
#endif /* CK_T */
23
 
 
24
 
/*
25
 
 * nssCKFWHash
26
 
 *
27
 
 *  nssCKFWHash_Create
28
 
 *  nssCKFWHash_Destroy
29
 
 *  nssCKFWHash_Add
30
 
 *  nssCKFWHash_Remove
31
 
 *  nssCKFWHash_Count
32
 
 *  nssCKFWHash_Exists
33
 
 *  nssCKFWHash_Lookup
34
 
 *  nssCKFWHash_Iterate
35
 
 */
36
 
 
37
 
struct nssCKFWHashStr {
38
 
  NSSCKFWMutex *mutex;
39
 
 
40
 
  /*
41
 
   * The invariant that mutex protects is:
42
 
   *   The count accurately reflects the hashtable state.
43
 
   */
44
 
 
45
 
  PLHashTable *plHashTable;
46
 
  CK_ULONG count;
47
 
};
48
 
 
49
 
static PLHashNumber
50
 
nss_ckfw_identity_hash
51
 
(
52
 
  const void *key
53
 
)
54
 
{
55
 
  PRUint32 i = (PRUint32)key;
56
 
  PR_ASSERT(sizeof(PLHashNumber) == sizeof(PRUint32));
57
 
  return (PLHashNumber)i;
58
 
}
59
 
 
60
 
/*
61
 
 * nssCKFWHash_Create
62
 
 *
63
 
 */
64
 
NSS_IMPLEMENT nssCKFWHash *
65
 
nssCKFWHash_Create
66
 
(
67
 
  NSSCKFWInstance *fwInstance,
68
 
  NSSArena *arena,
69
 
  CK_RV *pError
70
 
)
71
 
{
72
 
  nssCKFWHash *rv;
73
 
 
74
 
#ifdef NSSDEBUG
75
 
  if (!pError) {
76
 
    return (nssCKFWHash *)NULL;
77
 
  }
78
 
 
79
 
  if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
80
 
    *pError = CKR_ARGUMENTS_BAD;
81
 
    return (nssCKFWHash *)NULL;
82
 
  }
83
 
#endif /* NSSDEBUG */
84
 
 
85
 
  rv = nss_ZNEW(arena, nssCKFWHash);
86
 
  if (!rv) {
87
 
    *pError = CKR_HOST_MEMORY;
88
 
    return (nssCKFWHash *)NULL;
89
 
  }
90
 
 
91
 
  rv->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
92
 
  if (!rv->mutex) {
93
 
    if( CKR_OK == *pError ) {
94
 
      (void)nss_ZFreeIf(rv);
95
 
      *pError = CKR_GENERAL_ERROR;
96
 
    }
97
 
    return (nssCKFWHash *)NULL;
98
 
  }
99
 
 
100
 
  rv->plHashTable = PL_NewHashTable(0, nss_ckfw_identity_hash, 
101
 
    PL_CompareValues, PL_CompareValues, &nssArenaHashAllocOps, arena);
102
 
  if (!rv->plHashTable) {
103
 
    (void)nssCKFWMutex_Destroy(rv->mutex);
104
 
    (void)nss_ZFreeIf(rv);
105
 
    *pError = CKR_HOST_MEMORY;
106
 
    return (nssCKFWHash *)NULL;
107
 
  }
108
 
 
109
 
  rv->count = 0;
110
 
 
111
 
  return rv;
112
 
}
113
 
 
114
 
/*
115
 
 * nssCKFWHash_Destroy
116
 
 *
117
 
 */
118
 
NSS_IMPLEMENT void
119
 
nssCKFWHash_Destroy
120
 
(
121
 
  nssCKFWHash *hash
122
 
)
123
 
{
124
 
  (void)nssCKFWMutex_Destroy(hash->mutex);
125
 
  PL_HashTableDestroy(hash->plHashTable);
126
 
  (void)nss_ZFreeIf(hash);
127
 
}
128
 
 
129
 
/*
130
 
 * nssCKFWHash_Add
131
 
 *
132
 
 */
133
 
NSS_IMPLEMENT CK_RV
134
 
nssCKFWHash_Add
135
 
(
136
 
  nssCKFWHash *hash,
137
 
  const void *key,
138
 
  const void *value
139
 
)
140
 
{
141
 
  CK_RV error = CKR_OK;
142
 
  PLHashEntry *he;
143
 
 
144
 
  error = nssCKFWMutex_Lock(hash->mutex);
145
 
  if( CKR_OK != error ) {
146
 
    return error;
147
 
  }
148
 
  
149
 
  he = PL_HashTableAdd(hash->plHashTable, key, (void *)value);
150
 
  if (!he) {
151
 
    error = CKR_HOST_MEMORY;
152
 
  } else {
153
 
    hash->count++;
154
 
  }
155
 
 
156
 
  (void)nssCKFWMutex_Unlock(hash->mutex);
157
 
 
158
 
  return error;
159
 
}
160
 
 
161
 
/*
162
 
 * nssCKFWHash_Remove
163
 
 *
164
 
 */
165
 
NSS_IMPLEMENT void
166
 
nssCKFWHash_Remove
167
 
(
168
 
  nssCKFWHash *hash,
169
 
  const void *it
170
 
)
171
 
{
172
 
  PRBool found;
173
 
 
174
 
  if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
175
 
    return;
176
 
  }
177
 
 
178
 
  found = PL_HashTableRemove(hash->plHashTable, it);
179
 
  if( found ) {
180
 
    hash->count--;
181
 
  }
182
 
 
183
 
  (void)nssCKFWMutex_Unlock(hash->mutex);
184
 
  return;
185
 
}
186
 
 
187
 
/*
188
 
 * nssCKFWHash_Count
189
 
 *
190
 
 */
191
 
NSS_IMPLEMENT CK_ULONG
192
 
nssCKFWHash_Count
193
 
(
194
 
  nssCKFWHash *hash
195
 
)
196
 
{
197
 
  CK_ULONG count;
198
 
 
199
 
  if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
200
 
    return (CK_ULONG)0;
201
 
  }
202
 
 
203
 
  count = hash->count;
204
 
 
205
 
  (void)nssCKFWMutex_Unlock(hash->mutex);
206
 
 
207
 
  return count;
208
 
}
209
 
 
210
 
/*
211
 
 * nssCKFWHash_Exists
212
 
 *
213
 
 */
214
 
NSS_IMPLEMENT CK_BBOOL
215
 
nssCKFWHash_Exists
216
 
(
217
 
  nssCKFWHash *hash,
218
 
  const void *it
219
 
)
220
 
{
221
 
  void *value;
222
 
 
223
 
  if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
224
 
    return CK_FALSE;
225
 
  }
226
 
 
227
 
  value = PL_HashTableLookup(hash->plHashTable, it);
228
 
 
229
 
  (void)nssCKFWMutex_Unlock(hash->mutex);
230
 
 
231
 
  if (!value) {
232
 
    return CK_FALSE;
233
 
  } else {
234
 
    return CK_TRUE;
235
 
  }
236
 
}
237
 
 
238
 
/*
239
 
 * nssCKFWHash_Lookup
240
 
 *
241
 
 */
242
 
NSS_IMPLEMENT void *
243
 
nssCKFWHash_Lookup
244
 
(
245
 
  nssCKFWHash *hash,
246
 
  const void *it
247
 
)
248
 
{
249
 
  void *rv;
250
 
 
251
 
  if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
252
 
    return (void *)NULL;
253
 
  }
254
 
 
255
 
  rv = PL_HashTableLookup(hash->plHashTable, it);
256
 
 
257
 
  (void)nssCKFWMutex_Unlock(hash->mutex);
258
 
 
259
 
  return rv;
260
 
}
261
 
 
262
 
struct arg_str {
263
 
  nssCKFWHashIterator fcn;
264
 
  void *closure;
265
 
};
266
 
 
267
 
static PRIntn
268
 
nss_ckfwhash_enumerator
269
 
(
270
 
  PLHashEntry *he,
271
 
  PRIntn index,
272
 
  void *arg
273
 
)
274
 
{
275
 
  struct arg_str *as = (struct arg_str *)arg;
276
 
  as->fcn(he->key, he->value, as->closure);
277
 
  return HT_ENUMERATE_NEXT;
278
 
}
279
 
 
280
 
/*
281
 
 * nssCKFWHash_Iterate
282
 
 *
283
 
 * NOTE that the iteration function will be called with the hashtable locked.
284
 
 */
285
 
NSS_IMPLEMENT void
286
 
nssCKFWHash_Iterate
287
 
(
288
 
  nssCKFWHash *hash,
289
 
  nssCKFWHashIterator fcn,
290
 
  void *closure
291
 
)
292
 
{
293
 
  struct arg_str as;
294
 
  as.fcn = fcn;
295
 
  as.closure = closure;
296
 
 
297
 
  if( CKR_OK != nssCKFWMutex_Lock(hash->mutex) ) {
298
 
    return;
299
 
  }
300
 
 
301
 
  PL_HashTableEnumerateEntries(hash->plHashTable, nss_ckfwhash_enumerator, &as);
302
 
 
303
 
  (void)nssCKFWMutex_Unlock(hash->mutex);
304
 
 
305
 
  return;
306
 
}