Skip to content

Latest commit

 

History

History
3894 lines (3455 loc) · 114 KB

secutil.c

File metadata and controls

3894 lines (3455 loc) · 114 KB
 
Mar 20, 2012
Mar 20, 2012
1
2
3
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Mar 31, 2000
Mar 31, 2000
4
5
6
7
8
9
10
11
12
13
14
/*
** secutil.c - various functions used by security stuff
**
*/
#include "prtypes.h"
#include "prtime.h"
#include "prlong.h"
#include "prerror.h"
#include "prprf.h"
#include "plgetopt.h"
Apr 4, 2002
Apr 4, 2002
15
#include "prenv.h"
Jan 29, 2004
Jan 29, 2004
16
#include "prnetdb.h"
Mar 31, 2000
Mar 31, 2000
17
Apr 12, 2005
Apr 12, 2005
18
#include "cryptohi.h"
Mar 31, 2000
Mar 31, 2000
19
20
#include "secutil.h"
#include "secpkcs7.h"
Feb 14, 2008
Feb 14, 2008
21
#include "secpkcs5.h"
Mar 31, 2000
Mar 31, 2000
22
#include <stdarg.h>
Apr 4, 2002
Apr 4, 2002
23
#include <sys/stat.h>
Jan 6, 2001
Jan 6, 2001
24
#include <errno.h>
Mar 31, 2000
Mar 31, 2000
25
26
27
28
29
30
31
32
33
34
#ifdef XP_UNIX
#include <unistd.h>
#endif
/* for SEC_TraverseNames */
#include "cert.h"
#include "certt.h"
#include "certdb.h"
Feb 9, 2017
Feb 9, 2017
35
#include "secmod.h"
Mar 31, 2000
Mar 31, 2000
36
37
38
#include "pk11func.h"
#include "secoid.h"
Apr 21, 2016
Apr 21, 2016
39
static char consoleName[] = {
Mar 31, 2000
Mar 31, 2000
40
41
#ifdef XP_UNIX
"/dev/tty"
Aug 24, 2002
Aug 24, 2002
42
43
44
#else
#ifdef XP_OS2
"\\DEV\\CON"
Mar 31, 2000
Mar 31, 2000
45
46
47
#else
"CON:"
#endif
Aug 24, 2002
Aug 24, 2002
48
#endif
Mar 31, 2000
Mar 31, 2000
49
50
};
Aug 17, 2011
Aug 17, 2011
51
52
#include "nssutil.h"
#include "ssl.h"
Sep 27, 2012
Sep 27, 2012
53
#include "sslproto.h"
Nov 4, 2003
Nov 4, 2003
54
May 29, 2014
May 29, 2014
55
56
static PRBool utf8DisplayEnabled = PR_FALSE;
Aug 30, 2017
Aug 30, 2017
57
58
59
60
/* The minimum password/pin length (in Unicode characters) in FIPS mode,
* defined in lib/softoken/pkcs11i.h. */
#define FIPS_MIN_PIN 7
May 29, 2014
May 29, 2014
61
62
63
64
65
66
67
68
69
70
71
void
SECU_EnableUtf8Display(PRBool enable)
{
utf8DisplayEnabled = enable;
}
PRBool
SECU_GetUtf8DisplayEnabled(void)
{
return utf8DisplayEnabled;
}
Mar 31, 2000
Mar 31, 2000
72
73
74
75
76
static void
secu_ClearPassword(char *p)
{
if (p) {
Apr 21, 2016
Apr 21, 2016
77
78
PORT_Memset(p, 0, PORT_Strlen(p));
PORT_Free(p);
Mar 31, 2000
Mar 31, 2000
79
80
81
82
83
84
85
86
87
88
89
90
91
}
}
char *
SECU_GetPasswordString(void *arg, char *prompt)
{
#ifndef _WINDOWS
char *p = NULL;
FILE *input, *output;
/* open terminal */
input = fopen(consoleName, "r");
if (input == NULL) {
Apr 21, 2016
Apr 21, 2016
92
93
fprintf(stderr, "Error opening input terminal for read\n");
return NULL;
Mar 31, 2000
Mar 31, 2000
94
95
96
97
}
output = fopen(consoleName, "w");
if (output == NULL) {
Apr 21, 2016
Apr 21, 2016
98
99
100
fprintf(stderr, "Error opening output terminal for write\n");
fclose(input);
return NULL;
Mar 31, 2000
Mar 31, 2000
101
102
}
Apr 21, 2016
Apr 21, 2016
103
p = SEC_GetPassword(input, output, prompt, SEC_BlindCheckPassword);
Mar 31, 2000
Mar 31, 2000
104
105
106
107
108
109
110
111
112
113
114
115
fclose(input);
fclose(output);
return p;
#else
/* Win32 version of above. opening the console may fail
on windows95, and certainly isn't necessary.. */
char *p = NULL;
Apr 21, 2016
Apr 21, 2016
116
p = SEC_GetPassword(stdin, stdout, prompt, SEC_BlindCheckPassword);
Mar 31, 2000
Mar 31, 2000
117
118
119
120
121
122
return p;
#endif
}
/*
Apr 21, 2016
Apr 21, 2016
123
* p a s s w o r d _ h a r d c o d e
Mar 31, 2000
Mar 31, 2000
124
125
*
* A function to use the password passed in the -f(pwfile) argument
Apr 21, 2016
Apr 21, 2016
126
* of the command line.
Mar 31, 2000
Mar 31, 2000
127
128
129
130
131
132
* After use once, null it out otherwise PKCS11 calls us forever.?
*
*/
char *
SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg)
{
Apr 21, 2016
Apr 21, 2016
133
char *phrases, *phrase;
Mar 31, 2000
Mar 31, 2000
134
135
136
PRFileDesc *fd;
PRInt32 nb;
char *pwFile = arg;
Sep 15, 2000
Sep 15, 2000
137
int i;
Jun 16, 2008
Jun 16, 2008
138
const long maxPwdFileSize = 4096;
Apr 21, 2016
Apr 21, 2016
139
char *tokenName = NULL;
Jun 16, 2008
Jun 16, 2008
140
int tokenLen = 0;
Mar 31, 2000
Mar 31, 2000
141
142
if (!pwFile)
Apr 21, 2016
Apr 21, 2016
143
return 0;
Mar 31, 2000
Mar 31, 2000
144
145
if (retry) {
Apr 21, 2016
Apr 21, 2016
146
return 0; /* no good retrying - the files contents will be the same */
Jun 16, 2008
Jun 16, 2008
147
148
149
150
151
152
153
}
phrases = PORT_ZAlloc(maxPwdFileSize);
if (!phrases) {
return 0; /* out of memory */
}
Apr 21, 2016
Apr 21, 2016
154
Mar 31, 2000
Mar 31, 2000
155
156
fd = PR_Open(pwFile, PR_RDONLY, 0);
if (!fd) {
Apr 21, 2016
Apr 21, 2016
157
fprintf(stderr, "No password file \"%s\" exists.\n", pwFile);
Jun 16, 2008
Jun 16, 2008
158
PORT_Free(phrases);
Apr 21, 2016
Apr 21, 2016
159
return NULL;
Mar 31, 2000
Mar 31, 2000
160
161
}
Jun 16, 2008
Jun 16, 2008
162
nb = PR_Read(fd, phrases, maxPwdFileSize);
Apr 21, 2016
Apr 21, 2016
163
Mar 31, 2000
Mar 31, 2000
164
PR_Close(fd);
Jun 16, 2008
Jun 16, 2008
165
Sep 15, 2000
Sep 15, 2000
166
if (nb == 0) {
Apr 21, 2016
Apr 21, 2016
167
fprintf(stderr, "password file contains no data\n");
Jun 16, 2008
Jun 16, 2008
168
169
170
171
172
173
174
175
176
PORT_Free(phrases);
return NULL;
}
if (slot) {
tokenName = PK11_GetTokenName(slot);
if (tokenName) {
tokenLen = PORT_Strlen(tokenName);
}
Mar 31, 2000
Mar 31, 2000
177
}
Jun 16, 2008
Jun 16, 2008
178
i = 0;
Apr 21, 2016
Apr 21, 2016
179
do {
Jun 16, 2008
Jun 16, 2008
180
181
182
183
int startphrase = i;
int phraseLen;
/* handle the Windows EOL case */
Apr 21, 2016
Apr 21, 2016
184
185
while (phrases[i] != '\r' && phrases[i] != '\n' && i < nb)
i++;
Jun 16, 2008
Jun 16, 2008
186
187
188
/* terminate passphrase */
phrases[i++] = '\0';
/* clean up any EOL before the start of the next passphrase */
Apr 21, 2016
Apr 21, 2016
189
while ((i < nb) && (phrases[i] == '\r' || phrases[i] == '\n')) {
Jun 16, 2008
Jun 16, 2008
190
191
192
193
194
195
phrases[i++] = '\0';
}
/* now analyze the current passphrase */
phrase = &phrases[startphrase];
if (!tokenName)
break;
Apr 21, 2016
Apr 21, 2016
196
197
if (PORT_Strncmp(phrase, tokenName, tokenLen))
continue;
Jun 16, 2008
Jun 16, 2008
198
phraseLen = PORT_Strlen(phrase);
Apr 21, 2016
Apr 21, 2016
199
200
201
202
203
if (phraseLen < (tokenLen + 1))
continue;
if (phrase[tokenLen] != ':')
continue;
phrase = &phrase[tokenLen + 1];
Jun 16, 2008
Jun 16, 2008
204
205
break;
Apr 21, 2016
Apr 21, 2016
206
} while (i < nb);
Jun 16, 2008
Jun 16, 2008
207
Apr 21, 2016
Apr 21, 2016
208
phrase = PORT_Strdup((char *)phrase);
Jun 16, 2008
Jun 16, 2008
209
210
PORT_Free(phrases);
return phrase;
Mar 31, 2000
Mar 31, 2000
211
212
213
}
char *
Apr 21, 2016
Apr 21, 2016
214
SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg)
Mar 31, 2000
Mar 31, 2000
215
216
{
char prompt[255];
Aug 12, 2001
Aug 12, 2001
217
secuPWData *pwdata = (secuPWData *)arg;
Mar 31, 2000
Mar 31, 2000
218
secuPWData pwnull = { PW_NONE, 0 };
Jan 21, 2004
Jan 21, 2004
219
secuPWData pwxtrn = { PW_EXTERNAL, "external" };
Mar 31, 2000
Mar 31, 2000
220
Aug 12, 2001
Aug 12, 2001
221
if (pwdata == NULL)
Apr 21, 2016
Apr 21, 2016
222
pwdata = &pwnull;
Mar 31, 2000
Mar 31, 2000
223
Jan 21, 2004
Jan 21, 2004
224
if (PK11_ProtectedAuthenticationPath(slot)) {
Apr 21, 2016
Apr 21, 2016
225
pwdata = &pwxtrn;
Jan 21, 2004
Jan 21, 2004
226
}
Mar 31, 2000
Mar 31, 2000
227
if (retry && pwdata->source != PW_NONE) {
Apr 21, 2016
Apr 21, 2016
228
229
PR_fprintf(PR_STDERR, "Incorrect password/PIN entered.\n");
return NULL;
Mar 31, 2000
Mar 31, 2000
230
231
232
}
switch (pwdata->source) {
Apr 21, 2016
Apr 21, 2016
233
234
235
236
237
case PW_NONE:
sprintf(prompt, "Enter Password or Pin for \"%s\":",
PK11_GetTokenName(slot));
return SECU_GetPasswordString(NULL, prompt);
case PW_FROMFILE:
Jun 27, 2016
Jun 27, 2016
238
return SECU_FilePasswd(slot, retry, pwdata->data);
Apr 21, 2016
Apr 21, 2016
239
240
241
242
243
244
245
246
247
248
case PW_EXTERNAL:
sprintf(prompt,
"Press Enter, then enter PIN for \"%s\" on external device.\n",
PK11_GetTokenName(slot));
(void)SECU_GetPasswordString(NULL, prompt);
/* Fall Through */
case PW_PLAINTEXT:
return PL_strdup(pwdata->data);
default:
break;
Mar 31, 2000
Mar 31, 2000
249
250
}
Aug 9, 2001
Aug 9, 2001
251
PR_fprintf(PR_STDERR, "Password check failed: No password found.\n");
Mar 31, 2000
Mar 31, 2000
252
253
254
return NULL;
}
Nov 16, 2011
Nov 16, 2011
255
char *
Mar 31, 2000
Mar 31, 2000
256
257
258
259
260
261
262
secu_InitSlotPassword(PK11SlotInfo *slot, PRBool retry, void *arg)
{
char *p0 = NULL;
char *p1 = NULL;
FILE *input, *output;
secuPWData *pwdata = arg;
Dec 21, 2000
Dec 21, 2000
263
if (pwdata->source == PW_FROMFILE) {
Apr 21, 2016
Apr 21, 2016
264
265
return SECU_FilePasswd(slot, retry, pwdata->data);
}
Oct 16, 2002
Oct 16, 2002
266
if (pwdata->source == PW_PLAINTEXT) {
Apr 21, 2016
Apr 21, 2016
267
return PL_strdup(pwdata->data);
Dec 21, 2000
Dec 21, 2000
268
}
Apr 21, 2016
Apr 21, 2016
269
270
271
/* PW_NONE - get it from tty */
/* open terminal */
Jun 29, 2000
Jun 29, 2000
272
#ifdef _WINDOWS
Dec 21, 2000
Dec 21, 2000
273
input = stdin;
Jun 29, 2000
Jun 29, 2000
274
#else
Dec 21, 2000
Dec 21, 2000
275
input = fopen(consoleName, "r");
Sep 15, 2000
Sep 15, 2000
276
#endif
Dec 21, 2000
Dec 21, 2000
277
if (input == NULL) {
Apr 21, 2016
Apr 21, 2016
278
279
PR_fprintf(PR_STDERR, "Error opening input terminal for read\n");
return NULL;
Mar 31, 2000
Mar 31, 2000
280
281
}
Dec 21, 2000
Dec 21, 2000
282
/* we have no password, so initialize database with one */
Aug 30, 2017
Aug 30, 2017
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
if (PK11_IsFIPS()) {
PR_fprintf(PR_STDERR,
"Enter a password which will be used to encrypt your keys.\n"
"The password should be at least %d characters long,\n"
"and should consist of at least three character classes.\n"
"The available character classes are: digits (0-9), ASCII\n"
"lowercase letters, ASCII uppercase letters, ASCII\n"
"non-alphanumeric characters, and non-ASCII characters.\n\n"
"If an ASCII uppercase letter appears at the beginning of\n"
"the password, it is not counted toward its character class.\n"
"Similarly, if a digit appears at the end of the password,\n"
"it is not counted toward its character class.\n\n",
FIPS_MIN_PIN);
} else {
PR_fprintf(PR_STDERR,
"Enter a password which will be used to encrypt your keys.\n"
"The password should be at least 8 characters long,\n"
"and should contain at least one non-alphabetic character.\n\n");
}
Dec 21, 2000
Dec 21, 2000
302
Mar 31, 2000
Mar 31, 2000
303
304
output = fopen(consoleName, "w");
if (output == NULL) {
Apr 21, 2016
Apr 21, 2016
305
PR_fprintf(PR_STDERR, "Error opening output terminal for write\n");
Oct 13, 2014
Oct 13, 2014
306
#ifndef _WINDOWS
Apr 21, 2016
Apr 21, 2016
307
fclose(input);
Oct 13, 2014
Oct 13, 2014
308
#endif
Apr 21, 2016
Apr 21, 2016
309
return NULL;
Mar 31, 2000
Mar 31, 2000
310
311
312
}
for (;;) {
Apr 21, 2016
Apr 21, 2016
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
if (p0)
PORT_Free(p0);
p0 = SEC_GetPassword(input, output, "Enter new password: ",
SEC_BlindCheckPassword);
if (p1)
PORT_Free(p1);
p1 = SEC_GetPassword(input, output, "Re-enter password: ",
SEC_BlindCheckPassword);
if (p0 && p1 && !PORT_Strcmp(p0, p1)) {
break;
}
PR_fprintf(PR_STDERR, "Passwords do not match. Try again.\n");
}
Mar 31, 2000
Mar 31, 2000
328
329
/* clear out the duplicate password string */
secu_ClearPassword(p1);
Apr 21, 2016
Apr 21, 2016
330
Mar 31, 2000
Mar 31, 2000
331
332
333
334
335
336
337
338
fclose(input);
fclose(output);
return p0;
}
SECStatus
SECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile)
Jun 12, 2007
Jun 12, 2007
339
340
341
342
343
344
{
return SECU_ChangePW2(slot, passwd, 0, pwFile, 0);
}
SECStatus
SECU_ChangePW2(PK11SlotInfo *slot, char *oldPass, char *newPass,
Apr 21, 2016
Apr 21, 2016
345
char *oldPwFile, char *newPwFile)
Mar 31, 2000
Mar 31, 2000
346
347
348
349
350
{
SECStatus rv;
secuPWData pwdata, newpwdata;
char *oldpw = NULL, *newpw = NULL;
Jun 12, 2007
Jun 12, 2007
351
if (oldPass) {
Apr 21, 2016
Apr 21, 2016
352
353
pwdata.source = PW_PLAINTEXT;
pwdata.data = oldPass;
Jun 12, 2007
Jun 12, 2007
354
} else if (oldPwFile) {
Apr 21, 2016
Apr 21, 2016
355
356
pwdata.source = PW_FROMFILE;
pwdata.data = oldPwFile;
Mar 31, 2000
Mar 31, 2000
357
} else {
Apr 21, 2016
Apr 21, 2016
358
359
pwdata.source = PW_NONE;
pwdata.data = NULL;
Mar 31, 2000
Mar 31, 2000
360
361
}
Jun 12, 2007
Jun 12, 2007
362
if (newPass) {
Apr 21, 2016
Apr 21, 2016
363
364
newpwdata.source = PW_PLAINTEXT;
newpwdata.data = newPass;
Jun 12, 2007
Jun 12, 2007
365
} else if (newPwFile) {
Apr 21, 2016
Apr 21, 2016
366
367
newpwdata.source = PW_FROMFILE;
newpwdata.data = newPwFile;
Jun 12, 2007
Jun 12, 2007
368
} else {
Apr 21, 2016
Apr 21, 2016
369
370
newpwdata.source = PW_NONE;
newpwdata.data = NULL;
Jun 12, 2007
Jun 12, 2007
371
372
}
Mar 31, 2000
Mar 31, 2000
373
if (PK11_NeedUserInit(slot)) {
Apr 21, 2016
Apr 21, 2016
374
375
376
newpw = secu_InitSlotPassword(slot, PR_FALSE, &pwdata);
rv = PK11_InitPin(slot, (char *)NULL, newpw);
goto done;
Mar 31, 2000
Mar 31, 2000
377
378
379
}
for (;;) {
Apr 21, 2016
Apr 21, 2016
380
381
382
383
384
385
386
387
388
389
oldpw = SECU_GetModulePassword(slot, PR_FALSE, &pwdata);
if (PK11_CheckUserPassword(slot, oldpw) != SECSuccess) {
if (pwdata.source == PW_NONE) {
PR_fprintf(PR_STDERR, "Invalid password. Try again.\n");
} else {
PR_fprintf(PR_STDERR, "Invalid password.\n");
PORT_Memset(oldpw, 0, PL_strlen(oldpw));
PORT_Free(oldpw);
rv = SECFailure;
Aug 17, 2015
Aug 17, 2015
390
goto done;
Apr 21, 2016
Apr 21, 2016
391
392
393
}
} else
break;
Mar 31, 2000
Mar 31, 2000
394
Apr 21, 2016
Apr 21, 2016
395
PORT_Free(oldpw);
Mar 31, 2000
Mar 31, 2000
396
397
398
399
}
newpw = secu_InitSlotPassword(slot, PR_FALSE, &newpwdata);
Aug 17, 2015
Aug 17, 2015
400
401
rv = PK11_ChangePW(slot, oldpw, newpw);
if (rv != SECSuccess) {
Apr 21, 2016
Apr 21, 2016
402
PR_fprintf(PR_STDERR, "Failed to change password.\n");
Aug 17, 2015
Aug 17, 2015
403
404
} else {
PR_fprintf(PR_STDOUT, "Password changed successfully.\n");
Mar 31, 2000
Mar 31, 2000
405
406
407
408
409
410
}
PORT_Memset(oldpw, 0, PL_strlen(oldpw));
PORT_Free(oldpw);
done:
Aug 17, 2015
Aug 17, 2015
411
412
413
414
415
if (newpw) {
PORT_Memset(newpw, 0, PL_strlen(newpw));
PORT_Free(newpw);
}
return rv;
Mar 31, 2000
Mar 31, 2000
416
417
418
419
420
421
422
423
424
425
426
427
428
429
}
struct matchobj {
SECItem index;
char *nname;
PRBool found;
};
char *
SECU_DefaultSSLDir(void)
{
char *dir;
static char sslDir[1000];
Jan 29, 2016
Jan 29, 2016
430
dir = PR_GetEnvSecure("SSL_DIR");
Mar 31, 2000
Mar 31, 2000
431
if (!dir)
Apr 21, 2016
Apr 21, 2016
432
return NULL;
Mar 31, 2000
Mar 31, 2000
433
Oct 27, 2015
Oct 27, 2015
434
if (strlen(dir) >= PR_ARRAY_SIZE(sslDir)) {
Apr 21, 2016
Apr 21, 2016
435
return NULL;
Oct 27, 2015
Oct 27, 2015
436
}
Mar 31, 2000
Mar 31, 2000
437
438
sprintf(sslDir, "%s", dir);
Apr 21, 2016
Apr 21, 2016
439
440
if (sslDir[strlen(sslDir) - 1] == '/')
sslDir[strlen(sslDir) - 1] = 0;
Mar 31, 2000
Mar 31, 2000
441
442
443
444
445
446
447
448
449
return sslDir;
}
char *
SECU_AppendFilenameToDir(char *dir, char *filename)
{
static char path[1000];
Apr 21, 2016
Apr 21, 2016
450
451
if (dir[strlen(dir) - 1] == '/')
sprintf(path, "%s%s", dir, filename);
Mar 31, 2000
Mar 31, 2000
452
else
Apr 21, 2016
Apr 21, 2016
453
sprintf(path, "%s/%s", dir, filename);
Mar 31, 2000
Mar 31, 2000
454
455
456
457
return path;
}
char *
Apr 21, 2016
Apr 21, 2016
458
SECU_ConfigDirectory(const char *base)
Mar 31, 2000
Mar 31, 2000
459
460
461
462
463
464
{
static PRBool initted = PR_FALSE;
const char *dir = ".netscape";
char *home;
static char buf[1000];
Apr 21, 2016
Apr 21, 2016
465
466
if (initted)
return buf;
Mar 31, 2000
Mar 31, 2000
467
468
if (base == NULL || *base == 0) {
Apr 21, 2016
Apr 21, 2016
469
470
471
home = PR_GetEnvSecure("HOME");
if (!home)
home = "";
Mar 31, 2000
Mar 31, 2000
472
Apr 21, 2016
Apr 21, 2016
473
474
475
476
if (*home && home[strlen(home) - 1] == '/')
sprintf(buf, "%.900s%s", home, dir);
else
sprintf(buf, "%.900s/%s", home, dir);
Mar 31, 2000
Mar 31, 2000
477
} else {
Apr 21, 2016
Apr 21, 2016
478
479
480
sprintf(buf, "%.900s", base);
if (buf[strlen(buf) - 1] == '/')
buf[strlen(buf) - 1] = 0;
Mar 31, 2000
Mar 31, 2000
481
482
483
484
485
486
487
}
initted = PR_TRUE;
return buf;
}
SECStatus
Jun 11, 2013
Jun 11, 2013
488
SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii,
Apr 21, 2016
Apr 21, 2016
489
PRBool warnOnPrivateKeyInAsciiFile)
Mar 31, 2000
Mar 31, 2000
490
491
492
{
SECStatus rv;
if (ascii) {
Apr 21, 2016
Apr 21, 2016
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
/* First convert ascii to binary */
SECItem filedata;
char *asc, *body;
/* Read in ascii data */
rv = SECU_FileToItem(&filedata, inFile);
if (rv != SECSuccess)
return rv;
asc = (char *)filedata.data;
if (!asc) {
fprintf(stderr, "unable to read data from input file\n");
return SECFailure;
}
if (warnOnPrivateKeyInAsciiFile && strstr(asc, "PRIVATE KEY")) {
fprintf(stderr, "Warning: ignoring private key. Consider to use "
"pk12util.\n");
}
/* check for headers and trailers and remove them */
if ((body = strstr(asc, "-----BEGIN")) != NULL) {
char *trailer = NULL;
asc = body;
body = PORT_Strchr(body, '\n');
if (!body)
body = PORT_Strchr(asc, '\r'); /* maybe this is a MAC file */
if (body)
trailer = strstr(++body, "-----END");
if (trailer != NULL) {
*trailer = '\0';
} else {
fprintf(stderr, "input has header but no trailer\n");
PORT_Free(filedata.data);
return SECFailure;
}
} else {
/* need one additional byte for zero terminator */
rv = SECITEM_ReallocItemV2(NULL, &filedata, filedata.len + 1);
if (rv != SECSuccess) {
PORT_Free(filedata.data);
return rv;
}
body = (char *)filedata.data;
body[filedata.len - 1] = '\0';
}
/* Convert to binary */
rv = ATOB_ConvertAsciiToItem(der, body);
if (rv != SECSuccess) {
fprintf(stderr, "error converting ascii to binary (%s)\n",
SECU_Strerror(PORT_GetError()));
PORT_Free(filedata.data);
return SECFailure;
}
PORT_Free(filedata.data);
Mar 31, 2000
Mar 31, 2000
549
} else {
Apr 21, 2016
Apr 21, 2016
550
551
552
553
554
555
556
/* Read in binary der */
rv = SECU_FileToItem(der, inFile);
if (rv != SECSuccess) {
fprintf(stderr, "error converting der (%s)\n",
SECU_Strerror(PORT_GetError()));
return SECFailure;
}
Mar 31, 2000
Mar 31, 2000
557
558
559
560
}
return SECSuccess;
}
Apr 21, 2016
Apr 21, 2016
561
#define INDENT_MULT 4
Mar 20, 2001
Mar 20, 2001
562
Nov 4, 2003
Nov 4, 2003
563
564
565
566
567
568
569
570
571
572
573
574
575
SECStatus
SECU_StripTagAndLength(SECItem *i)
{
unsigned int start;
if (!i || !i->data || i->len < 2) { /* must be at least tag and length */
return SECFailure;
}
start = ((i->data[1] & 0x80) ? (i->data[1] & 0x7f) + 2 : 2);
if (i->len < start) {
return SECFailure;
}
i->data += start;
Apr 21, 2016
Apr 21, 2016
576
i->len -= start;
Nov 4, 2003
Nov 4, 2003
577
578
579
580
return SECSuccess;
}
static void
Apr 21, 2016
Apr 21, 2016
581
582
secu_PrintRawStringQuotesOptional(FILE *out, SECItem *si, const char *m,
int level, PRBool quotes)
Mar 31, 2000
Mar 31, 2000
583
{
Nov 4, 2003
Nov 4, 2003
584
585
int column;
unsigned int i;
Mar 31, 2000
Mar 31, 2000
586
Apr 21, 2016
Apr 21, 2016
587
588
589
590
591
if (m) {
SECU_Indent(out, level);
fprintf(out, "%s: ", m);
column = (level * INDENT_MULT) + strlen(m) + 2;
level++;
Jan 29, 2004
Jan 29, 2004
592
} else {
Apr 21, 2016
Apr 21, 2016
593
594
SECU_Indent(out, level);
column = level * INDENT_MULT;
Mar 31, 2000
Mar 31, 2000
595
}
Mar 10, 2012
Mar 10, 2012
596
if (quotes) {
Apr 21, 2016
Apr 21, 2016
597
598
fprintf(out, "\"");
column++;
Mar 10, 2012
Mar 10, 2012
599
}
Mar 31, 2000
Mar 31, 2000
600
Nov 4, 2003
Nov 4, 2003
601
for (i = 0; i < si->len; i++) {
Apr 21, 2016
Apr 21, 2016
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
unsigned char val = si->data[i];
unsigned char c;
if (SECU_GetWrapEnabled() && column > 76) {
SECU_Newline(out);
SECU_Indent(out, level);
column = level * INDENT_MULT;
}
if (utf8DisplayEnabled) {
if (val < 32)
c = '.';
else
c = val;
} else {
c = printable[val];
}
fprintf(out, "%c", c);
column++;
Mar 31, 2000
Mar 31, 2000
620
}
Nov 4, 2003
Nov 4, 2003
621
Mar 10, 2012
Mar 10, 2012
622
if (quotes) {
Apr 21, 2016
Apr 21, 2016
623
624
fprintf(out, "\"");
column++;
Mar 10, 2012
Mar 10, 2012
625
}
May 21, 2012
May 21, 2012
626
if (SECU_GetWrapEnabled() &&
Apr 21, 2016
Apr 21, 2016
627
628
(column != level * INDENT_MULT || column > 76)) {
SECU_Newline(out);
Nov 4, 2003
Nov 4, 2003
629
630
631
}
}
Mar 10, 2012
Mar 10, 2012
632
633
634
static void
secu_PrintRawString(FILE *out, SECItem *si, const char *m, int level)
{
Mar 10, 2012
Mar 10, 2012
635
secu_PrintRawStringQuotesOptional(out, si, m, level, PR_TRUE);
Mar 10, 2012
Mar 10, 2012
636
637
}
Nov 4, 2003
Nov 4, 2003
638
void
Mar 23, 2013
Mar 23, 2013
639
SECU_PrintString(FILE *out, const SECItem *si, const char *m, int level)
Nov 4, 2003
Nov 4, 2003
640
641
642
643
{
SECItem my = *si;
if (SECSuccess != SECU_StripTagAndLength(&my) || !my.len)
Apr 21, 2016
Apr 21, 2016
644
return;
Nov 4, 2003
Nov 4, 2003
645
secu_PrintRawString(out, &my, m, level);
Mar 31, 2000
Mar 31, 2000
646
647
}
Nov 4, 2003
Nov 4, 2003
648
/* print an unencoded boolean */
Mar 31, 2000
Mar 31, 2000
649
static void
Nov 16, 2011
Nov 16, 2011
650
secu_PrintBoolean(FILE *out, SECItem *i, const char *m, int level)
Mar 31, 2000
Mar 31, 2000
651
652
{
int val = 0;
Apr 21, 2016
Apr 21, 2016
653
654
655
if (i->data && i->len) {
val = i->data[0];
Mar 31, 2000
Mar 31, 2000
656
657
}
Nov 4, 2003
Nov 4, 2003
658
if (!m) {
Apr 21, 2016
Apr 21, 2016
659
m = "Boolean";
Mar 31, 2000
Mar 31, 2000
660
}
Apr 21, 2016
Apr 21, 2016
661
SECU_Indent(out, level);
Nov 4, 2003
Nov 4, 2003
662
fprintf(out, "%s: %s\n", m, (val ? "True" : "False"));
Mar 31, 2000
Mar 31, 2000
663
664
665
666
667
668
669
670
}
/*
* Format and print "time". If the tag message "m" is not NULL,
* do indent formatting based on "level" and add a newline afterward;
* otherwise just print the formatted time string only.
*/
static void
Mar 23, 2013
Mar 23, 2013
671
secu_PrintTime(FILE *out, const PRTime time, const char *m, int level)
Mar 31, 2000
Mar 31, 2000
672
{
Apr 21, 2016
Apr 21, 2016
673
PRExplodedTime printableTime;
Mar 31, 2000
Mar 31, 2000
674
675
676
677
678
char *timeString;
/* Convert to local time */
PR_ExplodeTime(time, PR_GMTParameters, &printableTime);
Oct 6, 2008
Oct 6, 2008
679
timeString = PORT_Alloc(256);
Mar 31, 2000
Mar 31, 2000
680
if (timeString == NULL)
Apr 21, 2016
Apr 21, 2016
681
return;
Mar 31, 2000
Mar 31, 2000
682
683
if (m != NULL) {
Apr 21, 2016
Apr 21, 2016
684
685
SECU_Indent(out, level);
fprintf(out, "%s: ", m);
Mar 31, 2000
Mar 31, 2000
686
687
}
Oct 6, 2008
Oct 6, 2008
688
if (PR_FormatTime(timeString, 256, "%a %b %d %H:%M:%S %Y", &printableTime)) {
Mar 28, 2010
Mar 28, 2010
689
fputs(timeString, out);
Oct 6, 2008
Oct 6, 2008
690
}
Mar 31, 2000
Mar 31, 2000
691
692
if (m != NULL)
Apr 21, 2016
Apr 21, 2016
693
fprintf(out, "\n");
Mar 31, 2000
Mar 31, 2000
694
695
696
697
698
699
700
701
702
703
PORT_Free(timeString);
}
/*
* Format and print the UTC Time "t". If the tag message "m" is not NULL,
* do indent formatting based on "level" and add a newline afterward;
* otherwise just print the formatted time string only.
*/
void
Mar 23, 2013
Mar 23, 2013
704
SECU_PrintUTCTime(FILE *out, const SECItem *t, const char *m, int level)
Mar 31, 2000
Mar 31, 2000
705
{
May 3, 2013
May 3, 2013
706
PRTime time;
Mar 31, 2000
Mar 31, 2000
707
708
709
710
SECStatus rv;
rv = DER_UTCTimeToTime(&time, t);
if (rv != SECSuccess)
Apr 21, 2016
Apr 21, 2016
711
return;
Mar 31, 2000
Mar 31, 2000
712
713
714
715
716
717
718
719
720
721
secu_PrintTime(out, time, m, level);
}
/*
* Format and print the Generalized Time "t". If the tag message "m"
* is not NULL, * do indent formatting based on "level" and add a newline
* afterward; otherwise just print the formatted time string only.
*/
void
Mar 23, 2013
Mar 23, 2013
722
SECU_PrintGeneralizedTime(FILE *out, const SECItem *t, const char *m, int level)
Mar 31, 2000
Mar 31, 2000
723
{
May 3, 2013
May 3, 2013
724
PRTime time;
Mar 31, 2000
Mar 31, 2000
725
726
727
728
SECStatus rv;
rv = DER_GeneralizedTimeToTime(&time, t);
if (rv != SECSuccess)
Apr 21, 2016
Apr 21, 2016
729
return;
Mar 31, 2000
Mar 31, 2000
730
731
732
733
secu_PrintTime(out, time, m, level);
}
Sep 26, 2003
Sep 26, 2003
734
735
736
737
738
739
/*
* Format and print the UTC or Generalized Time "t". If the tag message
* "m" is not NULL, do indent formatting based on "level" and add a newline
* afterward; otherwise just print the formatted time string only.
*/
void
Mar 23, 2013
Mar 23, 2013
740
SECU_PrintTimeChoice(FILE *out, const SECItem *t, const char *m, int level)
Sep 26, 2003
Sep 26, 2003
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
{
switch (t->type) {
case siUTCTime:
SECU_PrintUTCTime(out, t, m, level);
break;
case siGeneralizedTime:
SECU_PrintGeneralizedTime(out, t, m, level);
break;
default:
PORT_Assert(0);
break;
}
}
Nov 4, 2003
Nov 4, 2003
757
/* This prints a SET or SEQUENCE */
Mar 23, 2013
Mar 23, 2013
758
759
static void
SECU_PrintSet(FILE *out, const SECItem *t, const char *m, int level)
Mar 31, 2000
Mar 31, 2000
760
{
Apr 21, 2016
Apr 21, 2016
761
762
763
764
int type = t->data[0] & SEC_ASN1_TAGNUM_MASK;
int constructed = t->data[0] & SEC_ASN1_CONSTRUCTED;
const char *label;
SECItem my = *t;
Nov 4, 2003
Nov 4, 2003
765
766
if (!constructed) {
Apr 21, 2016
Apr 21, 2016
767
SECU_PrintAsHex(out, t, m, level);
Nov 4, 2003
Nov 4, 2003
768
769
770
return;
}
if (SECSuccess != SECU_StripTagAndLength(&my))
Apr 21, 2016
Apr 21, 2016
771
return;
Mar 31, 2000
Mar 31, 2000
772
773
774
SECU_Indent(out, level);
if (m) {
Apr 21, 2016
Apr 21, 2016
775
fprintf(out, "%s: ", m);
Mar 31, 2000
Mar 31, 2000
776
}
Jan 29, 2002
Jan 29, 2002
777
Nov 4, 2003
Nov 4, 2003
778
if (type == SEC_ASN1_SET)
Apr 21, 2016
Apr 21, 2016
779
label = "Set ";
Nov 19, 2003
Nov 19, 2003
780
else if (type == SEC_ASN1_SEQUENCE)
Apr 21, 2016
Apr 21, 2016
781
label = "Sequence ";
Nov 4, 2003
Nov 4, 2003
782
else
Apr 21, 2016
Apr 21, 2016
783
784
label = "";
fprintf(out, "%s{\n", label); /* } */
Nov 4, 2003
Nov 4, 2003
785
786
while (my.len >= 2) {
Apr 21, 2016
Apr 21, 2016
787
SECItem tmp = my;
Nov 4, 2003
Nov 4, 2003
788
789
if (tmp.data[1] & 0x80) {
Apr 21, 2016
Apr 21, 2016
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
unsigned int i;
unsigned int lenlen = tmp.data[1] & 0x7f;
if (lenlen > sizeof tmp.len)
break;
tmp.len = 0;
for (i = 0; i < lenlen; i++) {
tmp.len = (tmp.len << 8) | tmp.data[2 + i];
}
tmp.len += lenlen + 2;
} else {
tmp.len = tmp.data[1] + 2;
}
if (tmp.len > my.len) {
tmp.len = my.len;
}
my.data += tmp.len;
my.len -= tmp.len;
SECU_PrintAny(out, &tmp, NULL, level + 1);
}
SECU_Indent(out, level);
fprintf(out, /* { */ "}\n");
Jan 29, 2002
Jan 29, 2002
811
}
Oct 16, 2002
Oct 16, 2002
812
Jan 29, 2002
Jan 29, 2002
813
static void
Mar 23, 2013
Mar 23, 2013
814
secu_PrintContextSpecific(FILE *out, const SECItem *i, const char *m, int level)
Jan 29, 2002
Jan 29, 2002
815
{
Apr 21, 2016
Apr 21, 2016
816
int type = i->data[0] & SEC_ASN1_TAGNUM_MASK;
Nov 4, 2003
Nov 4, 2003
817
int constructed = i->data[0] & SEC_ASN1_CONSTRUCTED;
Jan 29, 2002
Jan 29, 2002
818
SECItem tmp;
Nov 4, 2003
Nov 4, 2003
819
820
if (constructed) {
Apr 21, 2016
Apr 21, 2016
821
822
823
824
825
826
827
828
829
830
char *m2;
if (!m)
m2 = PR_smprintf("[%d]", type);
else
m2 = PR_smprintf("%s: [%d]", m, type);
if (m2) {
SECU_PrintSet(out, i, m2, level);
PR_smprintf_free(m2);
}
return;
Nov 4, 2003
Nov 4, 2003
831
}
Jan 29, 2002
Jan 29, 2002
832
833
834
SECU_Indent(out, level);
if (m) {
Apr 21, 2016
Apr 21, 2016
835
fprintf(out, "%s: ", m);
Jan 29, 2002
Jan 29, 2002
836
}
Apr 21, 2016
Apr 21, 2016
837
fprintf(out, "[%d]\n", type);
Nov 4, 2003
Nov 4, 2003
838
839
840
tmp = *i;
if (SECSuccess == SECU_StripTagAndLength(&tmp))
Apr 21, 2016
Apr 21, 2016
841
SECU_PrintAsHex(out, &tmp, m, level + 1);
Mar 31, 2000
Mar 31, 2000
842
843
}
Oct 16, 2002
Oct 16, 2002
844
static void
Mar 23, 2013
Mar 23, 2013
845
secu_PrintOctetString(FILE *out, const SECItem *i, const char *m, int level)
Oct 16, 2002
Oct 16, 2002
846
{
Nov 4, 2003
Nov 4, 2003
847
848
SECItem tmp = *i;
if (SECSuccess == SECU_StripTagAndLength(&tmp))
Apr 21, 2016
Apr 21, 2016
849
SECU_PrintAsHex(out, &tmp, m, level);
Oct 16, 2002
Oct 16, 2002
850
851
852
}
static void
Mar 23, 2013
Mar 23, 2013
853
secu_PrintBitString(FILE *out, const SECItem *i, const char *m, int level)
Oct 16, 2002
Oct 16, 2002
854
855
{
int unused_bits;
Nov 4, 2003
Nov 4, 2003
856
857
858
SECItem tmp = *i;
if (SECSuccess != SECU_StripTagAndLength(&tmp) || tmp.len < 2)
Apr 21, 2016
Apr 21, 2016
859
return;
Nov 4, 2003
Nov 4, 2003
860
861
862
unused_bits = *tmp.data++;
tmp.len--;
Oct 16, 2002
Oct 16, 2002
863
864
865
SECU_PrintAsHex(out, &tmp, m, level);
if (unused_bits) {
Apr 21, 2016
Apr 21, 2016
866
867
SECU_Indent(out, level + 1);
fprintf(out, "(%d least significant bits unused)\n", unused_bits);
Oct 16, 2002
Oct 16, 2002
868
869
870
}
}
Jan 29, 2004
Jan 29, 2004
871
872
/* in a decoded bit string, the len member is a bit length. */
static void
Mar 23, 2013
Mar 23, 2013
873
secu_PrintDecodedBitString(FILE *out, const SECItem *i, const char *m, int level)
Jan 29, 2004
Jan 29, 2004
874
875
876
877
878
879
880
881
882
{
int unused_bits;
SECItem tmp = *i;
unused_bits = (tmp.len & 0x7) ? 8 - (tmp.len & 7) : 0;
DER_ConvertBitString(&tmp); /* convert length to byte length */
SECU_PrintAsHex(out, &tmp, m, level);
if (unused_bits) {
Apr 21, 2016
Apr 21, 2016
883
884
SECU_Indent(out, level + 1);
fprintf(out, "(%d least significant bits unused)\n", unused_bits);
Jan 29, 2004
Jan 29, 2004
885
886
887
}
}
Nov 4, 2003
Nov 4, 2003
888
889
/* Print a DER encoded Boolean */
void
Mar 23, 2013
Mar 23, 2013
890
SECU_PrintEncodedBoolean(FILE *out, const SECItem *i, const char *m, int level)
Nov 4, 2003
Nov 4, 2003
891
{
Apr 21, 2016
Apr 21, 2016
892
SECItem my = *i;
Nov 4, 2003
Nov 4, 2003
893
if (SECSuccess == SECU_StripTagAndLength(&my))
Apr 21, 2016
Apr 21, 2016
894
secu_PrintBoolean(out, &my, m, level);
Nov 4, 2003
Nov 4, 2003
895
896
897
898
}
/* Print a DER encoded integer */
void
Mar 23, 2013
Mar 23, 2013
899
SECU_PrintEncodedInteger(FILE *out, const SECItem *i, const char *m, int level)
Nov 4, 2003
Nov 4, 2003
900
{
Apr 21, 2016
Apr 21, 2016
901
SECItem my = *i;
Nov 4, 2003
Nov 4, 2003
902
if (SECSuccess == SECU_StripTagAndLength(&my))
Apr 21, 2016
Apr 21, 2016
903
SECU_PrintInteger(out, &my, m, level);
Nov 4, 2003
Nov 4, 2003
904
905
906
907
}
/* Print a DER encoded OID */
void
Mar 23, 2013
Mar 23, 2013
908
SECU_PrintEncodedObjectID(FILE *out, const SECItem *i, const char *m, int level)
Nov 4, 2003
Nov 4, 2003
909
{
Apr 21, 2016
Apr 21, 2016
910
SECItem my = *i;
Nov 4, 2003
Nov 4, 2003
911
if (SECSuccess == SECU_StripTagAndLength(&my))
Apr 21, 2016
Apr 21, 2016
912
SECU_PrintObjectID(out, &my, m, level);
Nov 4, 2003
Nov 4, 2003
913
914
}
Jan 29, 2004
Jan 29, 2004
915
static void
Mar 23, 2013
Mar 23, 2013
916
secu_PrintBMPString(FILE *out, const SECItem *i, const char *m, int level)
Jan 29, 2004
Jan 29, 2004
917
{
Apr 21, 2016
Apr 21, 2016
918
919
920
921
922
unsigned char *s;
unsigned char *d;
int len;
SECItem tmp = { 0, 0, 0 };
SECItem my = *i;
Jan 29, 2004
Jan 29, 2004
923
924
if (SECSuccess != SECU_StripTagAndLength(&my))
Apr 21, 2016
Apr 21, 2016
925
926
927
goto loser;
if (my.len % 2)
goto loser;
Jan 29, 2004
Jan 29, 2004
928
929
930
len = (int)(my.len / 2);
tmp.data = (unsigned char *)PORT_Alloc(len);
if (!tmp.data)
Apr 21, 2016
Apr 21, 2016
931
goto loser;
Jan 29, 2004
Jan 29, 2004
932
tmp.len = len;
Apr 21, 2016
Apr 21, 2016
933
934
935
936
937
938
for (s = my.data, d = tmp.data; len > 0; len--) {
PRUint32 bmpChar = (s[0] << 8) | s[1];
s += 2;
if (!isprint(bmpChar))
goto loser;
*d++ = (unsigned char)bmpChar;
Jan 29, 2004
Jan 29, 2004
939
940
941
942
943
944
945
946
}
secu_PrintRawString(out, &tmp, m, level);
PORT_Free(tmp.data);
return;
loser:
SECU_PrintAsHex(out, i, m, level);
if (tmp.data)
Apr 21, 2016
Apr 21, 2016
947
PORT_Free(tmp.data);
Jan 29, 2004
Jan 29, 2004
948
949
950
}
static void
Mar 23, 2013
Mar 23, 2013
951
secu_PrintUniversalString(FILE *out, const SECItem *i, const char *m, int level)
Jan 29, 2004
Jan 29, 2004
952
{
Apr 21, 2016
Apr 21, 2016
953
954
955
956
957
unsigned char *s;
unsigned char *d;
int len;
SECItem tmp = { 0, 0, 0 };
SECItem my = *i;
Jan 29, 2004
Jan 29, 2004
958
959
if (SECSuccess != SECU_StripTagAndLength(&my))
Apr 21, 2016
Apr 21, 2016
960
961
962
goto loser;
if (my.len % 4)
goto loser;
Jan 29, 2004
Jan 29, 2004
963
964
965
len = (int)(my.len / 4);
tmp.data = (unsigned char *)PORT_Alloc(len);
if (!tmp.data)
Apr 21, 2016
Apr 21, 2016
966
goto loser;
Jan 29, 2004
Jan 29, 2004
967
tmp.len = len;
Apr 21, 2016
Apr 21, 2016
968
969
970
for (s = my.data, d = tmp.data; len > 0; len--) {
PRUint32 bmpChar = (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3];
s += 4;
Jul 10, 2017
Jul 10, 2017
971
if (!isprint(bmpChar & 0xFF))
Apr 21, 2016
Apr 21, 2016
972
973
goto loser;
*d++ = (unsigned char)bmpChar;
Jan 29, 2004
Jan 29, 2004
974
975
976
977
978
979
980
981
}
secu_PrintRawString(out, &tmp, m, level);
PORT_Free(tmp.data);
return;
loser:
SECU_PrintAsHex(out, i, m, level);
if (tmp.data)
Apr 21, 2016
Apr 21, 2016
982
PORT_Free(tmp.data);
Jan 29, 2004
Jan 29, 2004
983
984
}
Mar 15, 2002
Mar 15, 2002
985
static void
Mar 23, 2013
Mar 23, 2013
986
secu_PrintUniversal(FILE *out, const SECItem *i, const char *m, int level)
Mar 31, 2000
Mar 31, 2000
987
{
Apr 21, 2016
Apr 21, 2016
988
989
990
991
992
993
994
995
996
997
998
999
1000
switch (i->data[0] & SEC_ASN1_TAGNUM_MASK) {
case SEC_ASN1_ENUMERATED:
case SEC_ASN1_INTEGER:
SECU_PrintEncodedInteger(out, i, m, level);
break;
case SEC_ASN1_OBJECT_ID:
SECU_PrintEncodedObjectID(out, i, m, level);
break;
case SEC_ASN1_BOOLEAN:
SECU_PrintEncodedBoolean(out, i, m, level);
break;
case SEC_ASN1_UTF8_STRING:
case SEC_ASN1_PRINTABLE_STRING: