~ubuntu-branches/ubuntu/trusty/xulrunner/trusty

« back to all changes in this revision

Viewing changes to security/nss-fips/lib/ckfw/nsprstub.c

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2008-08-25 13:04:18 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20080825130418-ck1i2ms384tzb9m0
Tags: 1.8.1.16+nobinonly-0ubuntu1
* New upstream release (taken from upstream CVS), LP: #254618.
* Fix MFSA 2008-35, MFSA 2008-34, MFSA 2008-33, MFSA 2008-32, MFSA 2008-31,
  MFSA 2008-30, MFSA 2008-29, MFSA 2008-28, MFSA 2008-27, MFSA 2008-25,
  MFSA 2008-24, MFSA 2008-23, MFSA 2008-22, MFSA 2008-21, MFSA 2008-26 also
  known as CVE-2008-2933, CVE-2008-2785, CVE-2008-2811, CVE-2008-2810,
  CVE-2008-2809, CVE-2008-2808, CVE-2008-2807, CVE-2008-2806, CVE-2008-2805,
  CVE-2008-2803, CVE-2008-2802, CVE-2008-2801, CVE-2008-2800, CVE-2008-2798.
* Drop 89_bz419350_attachment_306066 patch, merged upstream.
* Bump Standards-Version to 3.8.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
3
 *
 
4
 * The contents of this file are subject to the Mozilla Public License Version
 
5
 * 1.1 (the "License"); you may not use this file except in compliance with
 
6
 * the License. You may obtain a copy of the License at
 
7
 * http://www.mozilla.org/MPL/
 
8
 *
 
9
 * Software distributed under the License is distributed on an "AS IS" basis,
 
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
11
 * for the specific language governing rights and limitations under the
 
12
 * License.
 
13
 *
 
14
 * The Original Code is the Netscape security libraries.
 
15
 *
 
16
 * The Initial Developer of the Original Code is
 
17
 * Netscape Communications Corporation.
 
18
 * Portions created by the Initial Developer are Copyright (C) 1994-2000
 
19
 * the Initial Developer. All Rights Reserved.
 
20
 *
 
21
 * Contributor(s):
 
22
 *
 
23
 * Alternatively, the contents of this file may be used under the terms of
 
24
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
25
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
26
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
27
 * of those above. If you wish to allow use of your version of this file only
 
28
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
29
 * use your version of this file under the terms of the MPL, indicate your
 
30
 * decision by deleting the provisions above and replace them with the notice
 
31
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
32
 * the provisions above, a recipient may use your version of this file under
 
33
 * the terms of any one of the MPL, the GPL or the LGPL.
 
34
 *
 
35
 * ***** END LICENSE BLOCK ***** */
 
36
/*
 
37
 * secport.c - portability interfaces for security libraries
 
38
 *
 
39
 * This file abstracts out libc functionality that libsec depends on
 
40
 * 
 
41
 * NOTE - These are not public interfaces. These stubs are to allow the 
 
42
 * SW FORTEZZA to link with some low level security functions without dragging
 
43
 * in NSPR.
 
44
 *
 
45
 * $Id: nsprstub.c,v 1.6 2004/07/29 22:51:00 jpierre%netscape.com Exp $
 
46
 */
 
47
 
 
48
#include "seccomon.h"
 
49
#include "prmem.h"
 
50
#include "prerror.h"
 
51
#include "plarena.h"
 
52
#include "secerr.h"
 
53
#include "prmon.h"
 
54
#include "prbit.h"
 
55
#include "ck.h"
 
56
 
 
57
#ifdef notdef
 
58
unsigned long port_allocFailures;
 
59
 
 
60
/* locations for registering Unicode conversion functions.  
 
61
 *  Is this the appropriate location?  or should they be
 
62
 *     moved to client/server specific locations?
 
63
 */
 
64
PORTCharConversionFunc ucs4Utf8ConvertFunc;
 
65
PORTCharConversionFunc ucs2Utf8ConvertFunc;
 
66
PORTCharConversionWSwapFunc  ucs2AsciiConvertFunc;
 
67
 
 
68
void *
 
69
PORT_Alloc(size_t bytes)
 
70
{
 
71
    void *rv;
 
72
 
 
73
    /* Always allocate a non-zero amount of bytes */
 
74
    rv = (void *)malloc(bytes ? bytes : 1);
 
75
    if (!rv) {
 
76
        ++port_allocFailures;
 
77
    }
 
78
    return rv;
 
79
}
 
80
 
 
81
void *
 
82
PORT_Realloc(void *oldptr, size_t bytes)
 
83
{
 
84
    void *rv;
 
85
 
 
86
    rv = (void *)realloc(oldptr, bytes);
 
87
    if (!rv) {
 
88
        ++port_allocFailures;
 
89
    }
 
90
    return rv;
 
91
}
 
92
 
 
93
void *
 
94
PORT_ZAlloc(size_t bytes)
 
95
{
 
96
    void *rv;
 
97
 
 
98
    /* Always allocate a non-zero amount of bytes */
 
99
    rv = (void *)calloc(1, bytes ? bytes : 1);
 
100
    if (!rv) {
 
101
        ++port_allocFailures;
 
102
    }
 
103
    return rv;
 
104
}
 
105
 
 
106
void
 
107
PORT_Free(void *ptr)
 
108
{
 
109
    if (ptr) {
 
110
        free(ptr);
 
111
    }
 
112
}
 
113
 
 
114
void
 
115
PORT_ZFree(void *ptr, size_t len)
 
116
{
 
117
    if (ptr) {
 
118
        memset(ptr, 0, len);
 
119
        free(ptr);
 
120
    }
 
121
}
 
122
 
 
123
/********************* Arena code follows *****************************/
 
124
 
 
125
 
 
126
PLArenaPool *
 
127
PORT_NewArena(unsigned long chunksize)
 
128
{
 
129
    PLArenaPool *arena;
 
130
    
 
131
    arena = (PLArenaPool*)PORT_ZAlloc(sizeof(PLArenaPool));
 
132
    if ( arena != NULL ) {
 
133
        PR_InitArenaPool(arena, "security", chunksize, sizeof(double));
 
134
    }
 
135
    return(arena);
 
136
}
 
137
 
 
138
void *
 
139
PORT_ArenaAlloc(PLArenaPool *arena, size_t size)
 
140
{
 
141
    void *p;
 
142
 
 
143
    PL_ARENA_ALLOCATE(p, arena, size);
 
144
    if (p == NULL) {
 
145
        ++port_allocFailures;
 
146
    }
 
147
 
 
148
    return(p);
 
149
}
 
150
 
 
151
void *
 
152
PORT_ArenaZAlloc(PLArenaPool *arena, size_t size)
 
153
{
 
154
    void *p;
 
155
 
 
156
    PL_ARENA_ALLOCATE(p, arena, size);
 
157
    if (p == NULL) {
 
158
        ++port_allocFailures;
 
159
    } else {
 
160
        PORT_Memset(p, 0, size);
 
161
    }
 
162
 
 
163
    return(p);
 
164
}
 
165
 
 
166
/* need to zeroize!! */
 
167
void
 
168
PORT_FreeArena(PLArenaPool *arena, PRBool zero)
 
169
{
 
170
    PR_FinishArenaPool(arena);
 
171
    PORT_Free(arena);
 
172
}
 
173
 
 
174
void *
 
175
PORT_ArenaGrow(PLArenaPool *arena, void *ptr, size_t oldsize, size_t newsize)
 
176
{
 
177
    PORT_Assert(newsize >= oldsize);
 
178
    
 
179
    PL_ARENA_GROW(ptr, arena, oldsize, ( newsize - oldsize ) );
 
180
    
 
181
    return(ptr);
 
182
}
 
183
 
 
184
void *
 
185
PORT_ArenaMark(PLArenaPool *arena)
 
186
{
 
187
    void * result;
 
188
 
 
189
    result = PL_ARENA_MARK(arena);
 
190
    return result;
 
191
}
 
192
 
 
193
void
 
194
PORT_ArenaRelease(PLArenaPool *arena, void *mark)
 
195
{
 
196
    PL_ARENA_RELEASE(arena, mark);
 
197
}
 
198
 
 
199
void
 
200
PORT_ArenaUnmark(PLArenaPool *arena, void *mark)
 
201
{
 
202
    /* do nothing */
 
203
}
 
204
 
 
205
char *
 
206
PORT_ArenaStrdup(PLArenaPool *arena,const char *str) {
 
207
    int len = PORT_Strlen(str)+1;
 
208
    char *newstr;
 
209
 
 
210
    newstr = (char*)PORT_ArenaAlloc(arena,len);
 
211
    if (newstr) {
 
212
        PORT_Memcpy(newstr,str,len);
 
213
    }
 
214
    return newstr;
 
215
}
 
216
#endif
 
217
 
 
218
/*
 
219
 * replace the nice thread-safe Error stack code with something
 
220
 * that will work without all the NSPR features.
 
221
 */
 
222
static PRInt32 stack[2] = {0, 0};
 
223
 
 
224
PR_IMPLEMENT(void)
 
225
nss_SetError(PRUint32 value)
 
226
{       
 
227
    stack[0] = value;
 
228
    return;
 
229
}
 
230
 
 
231
PR_IMPLEMENT(PRInt32)
 
232
NSS_GetError(void)
 
233
{
 
234
    return(stack[0]);
 
235
}
 
236
 
 
237
 
 
238
PR_IMPLEMENT(PRInt32 *)
 
239
NSS_GetErrorStack(void)
 
240
{
 
241
    return(&stack[0]);
 
242
}
 
243
 
 
244
PR_IMPLEMENT(void)
 
245
nss_ClearErrorStack(void)
 
246
{
 
247
    stack[0] = 0;
 
248
    return;
 
249
}
 
250
 
 
251
#ifdef DEBUG
 
252
/*
 
253
 * replace the pointer tracking stuff for the same reasons.
 
254
 *  If you want to turn pointer tracking on, simply ifdef out this code and 
 
255
 *  link with real NSPR.
 
256
 */
 
257
PR_IMPLEMENT(PRStatus)
 
258
nssPointerTracker_initialize(nssPointerTracker *tracker)
 
259
{
 
260
    return PR_SUCCESS;
 
261
}
 
262
 
 
263
 
 
264
PR_IMPLEMENT(PRStatus)
 
265
nssPointerTracker_finalize(nssPointerTracker *tracker)
 
266
{
 
267
    return PR_SUCCESS;
 
268
}
 
269
 
 
270
PR_IMPLEMENT(PRStatus)
 
271
nssPointerTracker_add(nssPointerTracker *tracker, const void *pointer)
 
272
{
 
273
     return PR_SUCCESS;
 
274
}
 
275
 
 
276
PR_IMPLEMENT(PRStatus)
 
277
nssPointerTracker_remove(nssPointerTracker *tracker, const void *pointer)
 
278
{
 
279
     return PR_SUCCESS;
 
280
}
 
281
 
 
282
PR_IMPLEMENT(PRStatus)
 
283
nssPointerTracker_verify(nssPointerTracker *tracker, const void *pointer)
 
284
{
 
285
     return PR_SUCCESS;
 
286
}
 
287
#endif
 
288
 
 
289
/*
 
290
 * Do not use NSPR stubs for MinGW because they can't resolve references
 
291
 * to the _imp__PR_XXX symbols.  This is merely an expedient hack and not
 
292
 * the right solution.
 
293
 */
 
294
#if !(defined(WIN32) && defined(__GNUC__))
 
295
PR_IMPLEMENT(PRThread *)
 
296
PR_GetCurrentThread(void)
 
297
{
 
298
     return (PRThread *)1;
 
299
}
 
300
 
 
301
 
 
302
 
 
303
PR_IMPLEMENT(void)
 
304
PR_Assert(const char *expr, const char *file, int line) {
 
305
    return; 
 
306
}
 
307
 
 
308
PR_IMPLEMENT(void *)
 
309
PR_Alloc(PRUint32 bytes) { return malloc(bytes); }
 
310
 
 
311
PR_IMPLEMENT(void *)
 
312
PR_Malloc(PRUint32 bytes) { return malloc(bytes); }
 
313
 
 
314
PR_IMPLEMENT(void *)
 
315
PR_Calloc(PRUint32 blocks, PRUint32 bytes) { return calloc(blocks,bytes); }
 
316
 
 
317
PR_IMPLEMENT(void *)
 
318
PR_Realloc(void * blocks, PRUint32 bytes) { return realloc(blocks,bytes); }
 
319
 
 
320
PR_IMPLEMENT(void)
 
321
PR_Free(void *ptr) { free(ptr); }
 
322
 
 
323
#ifdef notdef
 
324
/* Old template; want to expunge it eventually. */
 
325
#include "secasn1.h"
 
326
#include "secoid.h"
 
327
 
 
328
const SEC_ASN1Template SECOID_AlgorithmIDTemplate[] = {
 
329
    { SEC_ASN1_SEQUENCE,
 
330
          0, NULL, sizeof(SECAlgorithmID) },
 
331
    { SEC_ASN1_OBJECT_ID,
 
332
          offsetof(SECAlgorithmID,algorithm), },
 
333
    { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
 
334
          offsetof(SECAlgorithmID,parameters), },
 
335
    { 0, }
 
336
};
 
337
 
 
338
PR_IMPLEMENT(PRStatus) PR_Sleep(PRIntervalTime ticks) { return PR_SUCCESS; }
 
339
 
 
340
/* This is not atomic! */
 
341
PR_IMPLEMENT(PRInt32) PR_AtomicDecrement(PRInt32 *val) { return --(*val); }
 
342
 
 
343
PR_IMPLEMENT(PRInt32) PR_AtomicSet(PRInt32 *val) { return ++(*val); }
 
344
 
 
345
#endif
 
346
 
 
347
/* now make the RNG happy */ /* This is not atomic! */
 
348
PR_IMPLEMENT(PRInt32) PR_AtomicIncrement(PRInt32 *val) { return ++(*val); }
 
349
#endif /* ! (WIN32 && GCC) */
 
350
 
 
351
static CK_C_INITIALIZE_ARGS_PTR nssstub_pInitArgs = NULL;
 
352
static CK_C_INITIALIZE_ARGS nssstub_initArgs;
 
353
static NSSArena *nssstub_arena = NULL;
 
354
static CryptokiLockingState nssstub_LockingState = SingleThreaded;
 
355
 
 
356
PR_IMPLEMENT(CK_RV)
 
357
nssSetLockArgs(CK_C_INITIALIZE_ARGS_PTR pInitArgs, CryptokiLockingState* returned)
 
358
{
 
359
    CK_ULONG count = (CK_ULONG)0;
 
360
    CK_BBOOL os_ok = CK_FALSE;
 
361
    CK_RV rv = CKR_OK;
 
362
    if (nssstub_pInitArgs == NULL) {
 
363
        if (pInitArgs != NULL) {
 
364
            nssstub_initArgs = *pInitArgs;
 
365
            nssstub_pInitArgs = &nssstub_initArgs;
 
366
            if( (CK_CREATEMUTEX )NULL != pInitArgs->CreateMutex  ) count++;
 
367
            if( (CK_DESTROYMUTEX)NULL != pInitArgs->DestroyMutex ) count++;
 
368
            if( (CK_LOCKMUTEX   )NULL != pInitArgs->LockMutex    ) count++;
 
369
            if( (CK_UNLOCKMUTEX )NULL != pInitArgs->UnlockMutex  ) count++;
 
370
            os_ok = (pInitArgs->flags & CKF_OS_LOCKING_OK) ? CK_TRUE : CK_FALSE;
 
371
 
 
372
            if( (0 != count) && (4 != count) ) {
 
373
                rv = CKR_ARGUMENTS_BAD;
 
374
                goto loser;
 
375
            }
 
376
        } else {
 
377
            nssstub_pInitArgs = pInitArgs;
 
378
        }
 
379
        /* nssstub_arena = NSSArena_Create(); */
 
380
    }
 
381
 
 
382
    if( (0 == count) && (CK_TRUE == os_ok) ) {
 
383
      /*
 
384
       * This is case #2 in the description of C_Initialize:
 
385
       * The library will be called in a multithreaded way, but
 
386
       * no routines were specified: os locking calls should be
 
387
       * used.  Unfortunately, this can be hard.. like, I think
 
388
       * I may have to dynamically look up the entry points in
 
389
       * the instance of NSPR already going in the application.
 
390
       *
 
391
       * I know that *we* always specify routines, so this only
 
392
       * comes up if someone is using NSS to create their own
 
393
       * PCKS#11 modules for other products.  Oh, heck, I'll 
 
394
       * worry about this then.
 
395
       */
 
396
      rv = CKR_CANT_LOCK;
 
397
      goto loser;
 
398
    }
 
399
 
 
400
    if( 0 == count ) {
 
401
      /*
 
402
       * With the above test out of the way, we know this is case
 
403
       * #1 in the description of C_Initialize: this library will
 
404
       * not be called in a multithreaded way.
 
405
       */
 
406
 
 
407
      nssstub_LockingState = SingleThreaded;
 
408
    } else {
 
409
      /*
 
410
       * We know that we're in either case #3 or #4 in the description
 
411
       * of C_Initialize.  Case #3 says we should use the specified
 
412
       * functions, case #4 cays we can use either the specified ones
 
413
       * or the OS ones.  I'll use the specified ones.
 
414
       */
 
415
      nssstub_LockingState = MultiThreaded;
 
416
    }
 
417
 
 
418
    loser:
 
419
    *returned = nssstub_LockingState;
 
420
    return rv;
 
421
}
 
422
 
 
423
/*
 
424
 * Do not use NSPR stubs for MinGW because they can't resolve references
 
425
 * to the _imp__PR_XXX symbols.  This is merely an expedient hack and not
 
426
 * the right solution.
 
427
 */
 
428
#if !(defined(WIN32) && defined(__GNUC__))
 
429
#include "prlock.h"
 
430
PR_IMPLEMENT(PRLock *)
 
431
PR_NewLock(void) {
 
432
        PRLock *lock = NULL;
 
433
        NSSCKFWMutex *mlock = NULL;
 
434
        CK_RV error;
 
435
 
 
436
        mlock = nssCKFWMutex_Create(nssstub_pInitArgs,nssstub_LockingState,nssstub_arena,&error);
 
437
        lock = (PRLock *)mlock;
 
438
 
 
439
        /* if we don't have a lock, nssCKFWMutex can deal with things */
 
440
        if (lock == NULL) lock=(PRLock *) 1;
 
441
        return lock;
 
442
}
 
443
 
 
444
PR_IMPLEMENT(void) 
 
445
PR_DestroyLock(PRLock *lock) {
 
446
        NSSCKFWMutex *mlock = (NSSCKFWMutex *)lock;
 
447
        if (lock == (PRLock *)1) return;
 
448
        nssCKFWMutex_Destroy(mlock);
 
449
}
 
450
 
 
451
PR_IMPLEMENT(void) 
 
452
PR_Lock(PRLock *lock) {
 
453
        NSSCKFWMutex *mlock = (NSSCKFWMutex *)lock;
 
454
        if (lock == (PRLock *)1) return;
 
455
        nssCKFWMutex_Lock(mlock);
 
456
}
 
457
 
 
458
PR_IMPLEMENT(PRStatus) 
 
459
PR_Unlock(PRLock *lock) {
 
460
        NSSCKFWMutex *mlock = (NSSCKFWMutex *)lock;
 
461
        if (lock == (PRLock *)1) return PR_SUCCESS;
 
462
        nssCKFWMutex_Unlock(mlock);
 
463
        return PR_SUCCESS;
 
464
}
 
465
 
 
466
#ifdef notdef
 
467
#endif
 
468
/* this implementation is here to satisfy the PRMonitor use in plarena.c.
 
469
** It appears that it doesn't need re-entrant locks.  It could have used
 
470
** PRLock instead of PRMonitor.  So, this implementation just uses 
 
471
** PRLock for a PRMonitor.
 
472
*/
 
473
PR_IMPLEMENT(PRMonitor*) 
 
474
PR_NewMonitor(void)
 
475
{
 
476
    return (PRMonitor *) PR_NewLock();
 
477
}
 
478
 
 
479
 
 
480
PR_IMPLEMENT(void) 
 
481
PR_EnterMonitor(PRMonitor *mon)
 
482
{
 
483
    PR_Lock( (PRLock *)mon );
 
484
}
 
485
 
 
486
PR_IMPLEMENT(PRStatus) 
 
487
PR_ExitMonitor(PRMonitor *mon)
 
488
{
 
489
    return PR_Unlock( (PRLock *)mon );
 
490
}
 
491
 
 
492
#include "prinit.h"
 
493
 
 
494
/* This is NOT threadsafe.  It is merely a pseudo-functional stub.
 
495
*/
 
496
PR_IMPLEMENT(PRStatus) PR_CallOnce(
 
497
    PRCallOnceType *once,
 
498
    PRCallOnceFN    func)
 
499
{
 
500
    /* This is not really atomic! */
 
501
    if (1 == PR_AtomicIncrement(&once->initialized)) {
 
502
        once->status = (*func)();
 
503
    }  else {
 
504
        /* Should wait to be sure that func has finished before returning. */
 
505
    }
 
506
    return once->status;
 
507
}
 
508
 
 
509
/*
 
510
** Compute the log of the least power of 2 greater than or equal to n
 
511
*/
 
512
PRIntn PR_CeilingLog2(PRUint32 i) {
 
513
        PRIntn log2;
 
514
        PR_CEILING_LOG2(log2,i);
 
515
        return log2;
 
516
}
 
517
#endif /* ! (WIN32 && GCC) */
 
518
 
 
519
/********************** end of arena functions ***********************/
 
520