~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/security/nss/cmd/crlutil/crlutil.c

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * The contents of this file are subject to the Mozilla Public
 
3
 * License Version 1.1 (the "License"); you may not use this file
 
4
 * except in compliance with the License. You may obtain a copy of
 
5
 * the License at http://www.mozilla.org/MPL/
 
6
 * 
 
7
 * Software distributed under the License is distributed on an "AS
 
8
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
9
 * implied. See the License for the specific language governing
 
10
 * rights and limitations under the License.
 
11
 * 
 
12
 * The Original Code is the Netscape security libraries.
 
13
 * 
 
14
 * The Initial Developer of the Original Code is Netscape
 
15
 * Communications Corporation.  Portions created by Netscape are 
 
16
 * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
 
17
 * Rights Reserved.
 
18
 * 
 
19
 * Contributor(s):
 
20
 * 
 
21
 * Alternatively, the contents of this file may be used under the
 
22
 * terms of the GNU General Public License Version 2 or later (the
 
23
 * "GPL"), in which case the provisions of the GPL are applicable 
 
24
 * instead of those above.  If you wish to allow use of your 
 
25
 * version of this file only under the terms of the GPL and not to
 
26
 * allow others to use your version of this file under the MPL,
 
27
 * indicate your decision by deleting the provisions above and
 
28
 * replace them with the notice and other provisions required by
 
29
 * the GPL.  If you do not delete the provisions above, a recipient
 
30
 * may use your version of this file under either the MPL or the
 
31
 * GPL.
 
32
 */
 
33
 
 
34
/*
 
35
** certutil.c
 
36
**
 
37
** utility for managing certificates and the cert database
 
38
**
 
39
*/
 
40
/* test only */
 
41
 
 
42
#include "nspr.h"
 
43
#include "plgetopt.h"
 
44
#include "secutil.h"
 
45
#include "cert.h"
 
46
#include "certdb.h"
 
47
#include "nss.h"
 
48
#include "pk11func.h"
 
49
 
 
50
#define SEC_CERT_DB_EXISTS 0
 
51
#define SEC_CREATE_CERT_DB 1
 
52
 
 
53
static char *progName;
 
54
 
 
55
static CERTSignedCrl *FindCRL
 
56
   (CERTCertDBHandle *certHandle, char *name, int type)
 
57
{
 
58
    CERTSignedCrl *crl = NULL;    
 
59
    CERTCertificate *cert = NULL;
 
60
 
 
61
 
 
62
    cert = CERT_FindCertByNickname(certHandle, name);
 
63
    if (!cert) {
 
64
        SECU_PrintError(progName, "could not find certificate named %s", name);
 
65
        return ((CERTSignedCrl *)NULL);
 
66
    }
 
67
        
 
68
    crl = SEC_FindCrlByName(certHandle, &cert->derSubject, type);
 
69
    if (crl ==NULL) 
 
70
        SECU_PrintError
 
71
                (progName, "could not find %s's CRL", name);
 
72
    CERT_DestroyCertificate (cert);
 
73
    return (crl);
 
74
}
 
75
 
 
76
static void DisplayCRL (CERTCertDBHandle *certHandle, char *nickName, int crlType)
 
77
{
 
78
    CERTCertificate *cert = NULL;
 
79
    CERTSignedCrl *crl = NULL;
 
80
 
 
81
    crl = FindCRL (certHandle, nickName, crlType);
 
82
        
 
83
    if (crl) {
 
84
        SECU_PrintCRLInfo (stdout, &crl->crl, "CRL Info:\n", 0);
 
85
        SEC_DestroyCrl (crl);
 
86
    }
 
87
}
 
88
 
 
89
static void ListCRLNames (CERTCertDBHandle *certHandle, int crlType, PRBool deletecrls)
 
90
{
 
91
    CERTCrlHeadNode *crlList = NULL;
 
92
    CERTCrlNode *crlNode = NULL;
 
93
    CERTName *name = NULL;
 
94
    PRArenaPool *arena = NULL;
 
95
    SECStatus rv;
 
96
 
 
97
    do {
 
98
        arena = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
 
99
        if (arena == NULL) {
 
100
            fprintf(stderr, "%s: fail to allocate memory\n", progName);
 
101
            break;
 
102
        }
 
103
        
 
104
        name = PORT_ArenaZAlloc (arena, sizeof(*name));
 
105
        if (name == NULL) {
 
106
            fprintf(stderr, "%s: fail to allocate memory\n", progName);
 
107
            break;
 
108
        }
 
109
        name->arena = arena;
 
110
            
 
111
        rv = SEC_LookupCrls (certHandle, &crlList, crlType);
 
112
        if (rv != SECSuccess) {
 
113
            fprintf(stderr, "%s: fail to look up CRLs (%s)\n", progName,
 
114
            SECU_Strerror(PORT_GetError()));
 
115
            break;
 
116
        }
 
117
        
 
118
        /* just in case */
 
119
        if (!crlList)
 
120
            break;
 
121
 
 
122
        crlNode  = crlList->first;
 
123
 
 
124
        fprintf (stdout, "\n");
 
125
        fprintf (stdout, "\n%-40s %-5s\n\n", "CRL names", "CRL Type");
 
126
        while (crlNode) {
 
127
           char* asciiname = NULL;
 
128
           name = &crlNode->crl->crl.name;
 
129
           if (!name){
 
130
                fprintf(stderr, "%s: fail to get the CRL issuer name (%s)\n", progName,
 
131
                SECU_Strerror(PORT_GetError()));
 
132
                break;
 
133
            }
 
134
 
 
135
            asciiname = CERT_NameToAscii(name);
 
136
            fprintf (stdout, "\n%-40s %-5s\n", asciiname, "CRL");
 
137
            if (asciiname) {
 
138
                PORT_Free(asciiname);
 
139
            }
 
140
            if ( PR_TRUE == deletecrls) {
 
141
                CERTSignedCrl* acrl = NULL;
 
142
                SECItem* issuer = &crlNode->crl->crl.derName;
 
143
                acrl = SEC_FindCrlByName(certHandle, issuer, crlType);
 
144
                if (acrl)
 
145
                {
 
146
                    SEC_DeletePermCRL(acrl);
 
147
                    SEC_DestroyCrl(acrl);
 
148
                }
 
149
            }
 
150
            crlNode = crlNode->next;
 
151
        } 
 
152
        
 
153
    } while (0);
 
154
    if (crlList)
 
155
        PORT_FreeArena (crlList->arena, PR_FALSE);
 
156
    PORT_FreeArena (arena, PR_FALSE);
 
157
}
 
158
 
 
159
static void ListCRL (CERTCertDBHandle *certHandle, char *nickName, int crlType)
 
160
{
 
161
    if (nickName == NULL)
 
162
        ListCRLNames (certHandle, crlType, PR_FALSE);
 
163
    else
 
164
        DisplayCRL (certHandle, nickName, crlType);
 
165
}
 
166
 
 
167
 
 
168
 
 
169
static SECStatus DeleteCRL (CERTCertDBHandle *certHandle, char *name, int type)
 
170
{
 
171
    CERTSignedCrl *crl = NULL;    
 
172
    SECStatus rv = SECFailure;
 
173
 
 
174
    crl = FindCRL (certHandle, name, type);
 
175
    if (!crl) {
 
176
        SECU_PrintError
 
177
                (progName, "could not find the issuer %s's CRL", name);
 
178
        return SECFailure;
 
179
    }
 
180
    rv = SEC_DeletePermCRL (crl);
 
181
    SEC_DestroyCrl(crl);
 
182
    if (rv != SECSuccess) {
 
183
        SECU_PrintError
 
184
                (progName, "fail to delete the issuer %s's CRL from the perm database (reason: %s)",
 
185
                 name, SECU_Strerror(PORT_GetError()));
 
186
        return SECFailure;
 
187
    }
 
188
    return (rv);
 
189
}
 
190
 
 
191
SECStatus ImportCRL (CERTCertDBHandle *certHandle, char *url, int type, 
 
192
                     PRFileDesc *inFile, PRInt32 importOptions, PRInt32 decodeOptions)
 
193
{
 
194
    CERTCertificate *cert = NULL;
 
195
    CERTSignedCrl *crl = NULL;
 
196
    SECItem crlDER;
 
197
    PK11SlotInfo* slot = NULL;
 
198
    int rv;
 
199
    PRIntervalTime starttime, endtime, elapsed;
 
200
    PRUint32 mins, secs, msecs;
 
201
 
 
202
    crlDER.data = NULL;
 
203
 
 
204
 
 
205
    /* Read in the entire file specified with the -f argument */
 
206
        rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE);
 
207
    if (rv != SECSuccess) {
 
208
        SECU_PrintError(progName, "unable to read input file");
 
209
        return (SECFailure);
 
210
    }
 
211
 
 
212
    decodeOptions |= CRL_DECODE_DONT_COPY_DER;
 
213
 
 
214
    slot = PK11_GetInternalKeySlot();
 
215
 
 
216
    starttime = PR_IntervalNow();
 
217
    crl = PK11_ImportCRL(slot, &crlDER, url, type,
 
218
          NULL, importOptions, NULL, decodeOptions);
 
219
    endtime = PR_IntervalNow();
 
220
    elapsed = endtime - starttime;
 
221
    mins = PR_IntervalToSeconds(elapsed) / 60;
 
222
    secs = PR_IntervalToSeconds(elapsed) % 60;
 
223
    msecs = PR_IntervalToMilliseconds(elapsed) % 1000;
 
224
    printf("Elapsed : %2d:%2d.%3d\n", mins, secs, msecs);
 
225
    if (!crl) {
 
226
        const char *errString;
 
227
 
 
228
        errString = SECU_Strerror(PORT_GetError());
 
229
        if ( errString && PORT_Strlen (errString) == 0)
 
230
            SECU_PrintError
 
231
                    (progName, "CRL is not imported (error: input CRL is not up to date.)");
 
232
        else    
 
233
            SECU_PrintError
 
234
                    (progName, "unable to import CRL");
 
235
    }
 
236
    SEC_DestroyCrl (crl);
 
237
    if (slot) {
 
238
        PK11_FreeSlot(slot);
 
239
    }
 
240
    return (rv);
 
241
}
 
242
            
 
243
 
 
244
static void Usage(char *progName)
 
245
{
 
246
    fprintf(stderr,
 
247
            "Usage:  %s -L [-n nickname] [-d keydir] [-P dbprefix] [-t crlType]\n"
 
248
            "        %s -D -n nickname [-d keydir] [-P dbprefix]\n"
 
249
            "        %s -I -i crl -t crlType [-u url] [-d keydir] [-P dbprefix] [-B]\n"
 
250
            "        %s -E -t crlType [-d keydir] [-P dbprefix]\n"
 
251
            "        %s -T\n", progName, progName, progName, progName, progName);
 
252
 
 
253
    fprintf (stderr, "%-15s List CRL\n", "-L");
 
254
    fprintf(stderr, "%-20s Specify the nickname of the CA certificate\n",
 
255
            "-n nickname");
 
256
    fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
 
257
            "-d keydir");
 
258
    fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
 
259
            "-P dbprefix");
 
260
   
 
261
    fprintf (stderr, "%-15s Delete a CRL from the cert database\n", "-D");    
 
262
    fprintf(stderr, "%-20s Specify the nickname for the CA certificate\n",
 
263
            "-n nickname");
 
264
    fprintf(stderr, "%-20s Specify the crl type.\n", "-t crlType");
 
265
    fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
 
266
            "-d keydir");
 
267
    fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
 
268
            "-P dbprefix");
 
269
 
 
270
    fprintf (stderr, "%-15s Erase all CRLs of specified type from hte cert database\n", "-E");
 
271
    fprintf(stderr, "%-20s Specify the crl type.\n", "-t crlType");
 
272
    fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
 
273
            "-d keydir");
 
274
    fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
 
275
            "-P dbprefix");
 
276
 
 
277
    fprintf (stderr, "%-15s Import a CRL to the cert database\n", "-I");    
 
278
    fprintf(stderr, "%-20s Specify the file which contains the CRL to import\n",
 
279
            "-i crl");
 
280
    fprintf(stderr, "%-20s Specify the url.\n", "-u url");
 
281
    fprintf(stderr, "%-20s Specify the crl type.\n", "-t crlType");
 
282
    fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
 
283
            "-d keydir");
 
284
    fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
 
285
            "-P dbprefix");
 
286
#ifdef DEBUG
 
287
    fprintf (stderr, "%-15s Test . Only for debugging purposes. See source code\n", "-T");
 
288
#endif
 
289
    fprintf(stderr, "%-20s CRL Types (default is SEC_CRL_TYPE):\n", " ");
 
290
    fprintf(stderr, "%-20s \t 0 - SEC_KRL_TYPE\n", " ");
 
291
    fprintf(stderr, "%-20s \t 1 - SEC_CRL_TYPE\n", " ");        
 
292
    fprintf(stderr, "\n%-20s Bypass CA certificate checks.\n", "-B");
 
293
    fprintf(stderr, "\n%-20s Partial decode for faster operation.\n", "-p");
 
294
    fprintf(stderr, "%-20s Repeat the operation.\n", "-r <iterations>");
 
295
 
 
296
    exit(-1);
 
297
}
 
298
 
 
299
int main(int argc, char **argv)
 
300
{
 
301
    SECItem privKeyDER;
 
302
    CERTCertDBHandle *certHandle;
 
303
    FILE *certFile;
 
304
    PRFileDesc *inFile;
 
305
    int listCRL;
 
306
    int importCRL;
 
307
    int deleteCRL;
 
308
    int rv;
 
309
    char *nickName;
 
310
    char *url;
 
311
    char *dbPrefix = "";
 
312
    int crlType;
 
313
    PLOptState *optstate;
 
314
    PLOptStatus status;
 
315
    SECStatus secstatus;
 
316
    PRBool bypassChecks = PR_FALSE;
 
317
    PRInt32 decodeOptions = CRL_DECODE_DEFAULT_OPTIONS;
 
318
    PRInt32 importOptions = CRL_IMPORT_DEFAULT_OPTIONS;
 
319
    PRBool test = PR_FALSE;
 
320
    PRBool erase = PR_FALSE;
 
321
    PRInt32 i = 0;
 
322
    PRInt32 iterations = 1;
 
323
 
 
324
    progName = strrchr(argv[0], '/');
 
325
    progName = progName ? progName+1 : argv[0];
 
326
 
 
327
    rv = 0;
 
328
    deleteCRL = importCRL = listCRL = 0;
 
329
    certFile = NULL;
 
330
    inFile = NULL;
 
331
    nickName = url = NULL;
 
332
    privKeyDER.data = NULL;
 
333
    certHandle = NULL;
 
334
    crlType = SEC_CRL_TYPE;
 
335
    /*
 
336
     * Parse command line arguments
 
337
     */
 
338
    optstate = PL_CreateOptState(argc, argv, "BCDILP:d:i:n:pt:u:TEr:");
 
339
    while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
 
340
        switch (optstate->option) {
 
341
          case '?':
 
342
            Usage(progName);
 
343
            break;
 
344
 
 
345
          case 'T':
 
346
            test = PR_TRUE;
 
347
            break;
 
348
 
 
349
          case 'E':
 
350
            erase = PR_TRUE;
 
351
            break;
 
352
 
 
353
          case 'B':
 
354
            importOptions |= CRL_IMPORT_BYPASS_CHECKS;
 
355
            break;
 
356
 
 
357
          case 'C':
 
358
              listCRL = 1;
 
359
              break;
 
360
 
 
361
          case 'D':
 
362
              deleteCRL = 1;
 
363
              break;
 
364
 
 
365
          case 'I':
 
366
              importCRL = 1;
 
367
              break;
 
368
                   
 
369
          case 'L':
 
370
              listCRL = 1;
 
371
              break;
 
372
 
 
373
          case 'P':
 
374
            dbPrefix = strdup(optstate->value);
 
375
            break;
 
376
                   
 
377
          case 'd':
 
378
            SECU_ConfigDirectory(optstate->value);
 
379
            break;
 
380
 
 
381
          case 'i':
 
382
            inFile = PR_Open(optstate->value, PR_RDONLY, 0);
 
383
            if (!inFile) {
 
384
                fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
 
385
                        progName, optstate->value);
 
386
                PL_DestroyOptState(optstate);
 
387
                return -1;
 
388
            }
 
389
            break;
 
390
            
 
391
          case 'n':
 
392
            nickName = strdup(optstate->value);
 
393
            break;
 
394
 
 
395
          case 'p':
 
396
            decodeOptions |= CRL_DECODE_SKIP_ENTRIES;
 
397
            break;
 
398
 
 
399
          case 'r': {
 
400
            const char* str = optstate->value;
 
401
            if (str && atoi(str)>0)
 
402
                iterations = atoi(str);
 
403
            }
 
404
            break;
 
405
            
 
406
          case 't': {
 
407
            char *type;
 
408
            
 
409
            type = strdup(optstate->value);
 
410
            crlType = atoi (type);
 
411
            if (crlType != SEC_CRL_TYPE && crlType != SEC_KRL_TYPE) {
 
412
                fprintf(stderr, "%s: invalid crl type\n", progName);
 
413
                PL_DestroyOptState(optstate);
 
414
                return -1;
 
415
            }
 
416
            break;
 
417
 
 
418
          case 'u':
 
419
            url = strdup(optstate->value);
 
420
            break;
 
421
          }
 
422
        }
 
423
    }
 
424
    PL_DestroyOptState(optstate);
 
425
 
 
426
    if (deleteCRL && !nickName) Usage (progName);
 
427
    if (!(listCRL || deleteCRL || importCRL || test || erase)) Usage (progName);
 
428
    if (importCRL && !inFile) Usage (progName);
 
429
    
 
430
    PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
 
431
    secstatus = NSS_Initialize(SECU_ConfigDirectory(NULL), dbPrefix, dbPrefix,
 
432
                               "secmod.db", 0);
 
433
    if (secstatus != SECSuccess) {
 
434
        SECU_PrintPRandOSError(progName);
 
435
        return -1;
 
436
    }
 
437
 
 
438
    certHandle = CERT_GetDefaultCertDB();
 
439
    if (certHandle == NULL) {
 
440
        SECU_PrintError(progName, "unable to open the cert db");                
 
441
        /*ignoring return value of NSS_Shutdown() as code returns -1*/
 
442
        (void) NSS_Shutdown();
 
443
        return (-1);
 
444
    }
 
445
 
 
446
    for (i=0; i<iterations; i++) {
 
447
        /* Read in the private key info */
 
448
        if (deleteCRL) 
 
449
            DeleteCRL (certHandle, nickName, crlType);
 
450
        else if (listCRL) {
 
451
            ListCRL (certHandle, nickName, crlType);
 
452
        }
 
453
        else if (importCRL) {
 
454
            rv = ImportCRL (certHandle, url, crlType, inFile, importOptions,
 
455
                            decodeOptions);
 
456
        }
 
457
        else if (erase) {
 
458
            /* list and delete all CRLs */
 
459
            ListCRLNames (certHandle, crlType, PR_TRUE);
 
460
        }
 
461
#ifdef DEBUG
 
462
        else if (test) {
 
463
            /* list and delete all CRLs */
 
464
            ListCRLNames (certHandle, crlType, PR_TRUE);
 
465
            /* list CRLs */
 
466
            ListCRLNames (certHandle, crlType, PR_FALSE);
 
467
            /* import CRL as a blob */
 
468
            rv = ImportCRL (certHandle, url, crlType, inFile, importOptions,
 
469
                            decodeOptions);
 
470
            /* list CRLs */
 
471
            ListCRLNames (certHandle, crlType, PR_FALSE);
 
472
        }
 
473
#endif    
 
474
    }
 
475
    if (NSS_Shutdown() != SECSuccess) {
 
476
        exit(1);
 
477
    }
 
478
 
 
479
    return (rv);
 
480
}