mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-07 07:47:30 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
49
security/nss/cmd/lib/Makefile
Normal file
49
security/nss/cmd/lib/Makefile
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#! gmake
|
||||
#
|
||||
# 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/.
|
||||
|
||||
#######################################################################
|
||||
# (1) Include initial platform-independent assignments (MANDATORY). #
|
||||
#######################################################################
|
||||
|
||||
include manifest.mn
|
||||
|
||||
#######################################################################
|
||||
# (2) Include "global" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
include config.mk
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
export:: private_export
|
||||
|
||||
|
||||
829
security/nss/cmd/lib/basicutil.c
Normal file
829
security/nss/cmd/lib/basicutil.c
Normal file
|
|
@ -0,0 +1,829 @@
|
|||
/* 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/. */
|
||||
/*
|
||||
** 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"
|
||||
#include "prenv.h"
|
||||
#include "prnetdb.h"
|
||||
|
||||
#include "basicutil.h"
|
||||
#include <stdarg.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "secoid.h"
|
||||
#include "sslt.h"
|
||||
|
||||
extern long DER_GetInteger(const SECItem *src);
|
||||
|
||||
static PRBool wrapEnabled = PR_TRUE;
|
||||
|
||||
void
|
||||
SECU_EnableWrap(PRBool enable)
|
||||
{
|
||||
wrapEnabled = enable;
|
||||
}
|
||||
|
||||
PRBool
|
||||
SECU_GetWrapEnabled(void)
|
||||
{
|
||||
return wrapEnabled;
|
||||
}
|
||||
|
||||
void
|
||||
SECU_PrintErrMsg(FILE *out, int level, const char *progName, const char *msg,
|
||||
...)
|
||||
{
|
||||
va_list args;
|
||||
PRErrorCode err = PORT_GetError();
|
||||
const char *errString = PORT_ErrorToString(err);
|
||||
|
||||
va_start(args, msg);
|
||||
|
||||
SECU_Indent(out, level);
|
||||
fprintf(out, "%s: ", progName);
|
||||
vfprintf(out, msg, args);
|
||||
if (errString != NULL && PORT_Strlen(errString) > 0)
|
||||
fprintf(out, ": %s\n", errString);
|
||||
else
|
||||
fprintf(out, ": error %d\n", (int)err);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
SECU_PrintError(const char *progName, const char *msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
PRErrorCode err = PORT_GetError();
|
||||
const char *errName = PR_ErrorToName(err);
|
||||
const char *errString = PR_ErrorToString(err, 0);
|
||||
|
||||
va_start(args, msg);
|
||||
|
||||
fprintf(stderr, "%s: ", progName);
|
||||
vfprintf(stderr, msg, args);
|
||||
|
||||
if (errName != NULL) {
|
||||
fprintf(stderr, ": %s", errName);
|
||||
} else {
|
||||
fprintf(stderr, ": error %d", (int)err);
|
||||
}
|
||||
|
||||
if (errString != NULL && PORT_Strlen(errString) > 0)
|
||||
fprintf(stderr, ": %s\n", errString);
|
||||
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void
|
||||
SECU_PrintSystemError(const char *progName, const char *msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, msg);
|
||||
fprintf(stderr, "%s: ", progName);
|
||||
vfprintf(stderr, msg, args);
|
||||
fprintf(stderr, ": %s\n", strerror(errno));
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
secu_StdinToItem(SECItem *dst)
|
||||
{
|
||||
unsigned char buf[1000];
|
||||
PRInt32 numBytes;
|
||||
PRBool notDone = PR_TRUE;
|
||||
|
||||
dst->len = 0;
|
||||
dst->data = NULL;
|
||||
|
||||
while (notDone) {
|
||||
numBytes = PR_Read(PR_STDIN, buf, sizeof(buf));
|
||||
|
||||
if (numBytes < 0) {
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
if (numBytes == 0)
|
||||
break;
|
||||
|
||||
if (dst->data) {
|
||||
unsigned char *p = dst->data;
|
||||
dst->data = (unsigned char *)PORT_Realloc(p, dst->len + numBytes);
|
||||
if (!dst->data) {
|
||||
PORT_Free(p);
|
||||
}
|
||||
} else {
|
||||
dst->data = (unsigned char *)PORT_Alloc(numBytes);
|
||||
}
|
||||
if (!dst->data) {
|
||||
return SECFailure;
|
||||
}
|
||||
PORT_Memcpy(dst->data + dst->len, buf, numBytes);
|
||||
dst->len += numBytes;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SECU_FileToItem(SECItem *dst, PRFileDesc *src)
|
||||
{
|
||||
PRFileInfo info;
|
||||
PRInt32 numBytes;
|
||||
PRStatus prStatus;
|
||||
|
||||
if (src == PR_STDIN)
|
||||
return secu_StdinToItem(dst);
|
||||
|
||||
prStatus = PR_GetOpenFileInfo(src, &info);
|
||||
|
||||
if (prStatus != PR_SUCCESS) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* XXX workaround for 3.1, not all utils zero dst before sending */
|
||||
dst->data = 0;
|
||||
if (!SECITEM_AllocItem(NULL, dst, info.size))
|
||||
goto loser;
|
||||
|
||||
numBytes = PR_Read(src, dst->data, info.size);
|
||||
if (numBytes != info.size) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
loser:
|
||||
SECITEM_FreeItem(dst, PR_FALSE);
|
||||
dst->data = NULL;
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SECU_TextFileToItem(SECItem *dst, PRFileDesc *src)
|
||||
{
|
||||
PRFileInfo info;
|
||||
PRInt32 numBytes;
|
||||
PRStatus prStatus;
|
||||
unsigned char *buf;
|
||||
|
||||
if (src == PR_STDIN)
|
||||
return secu_StdinToItem(dst);
|
||||
|
||||
prStatus = PR_GetOpenFileInfo(src, &info);
|
||||
|
||||
if (prStatus != PR_SUCCESS) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
buf = (unsigned char *)PORT_Alloc(info.size);
|
||||
if (!buf)
|
||||
return SECFailure;
|
||||
|
||||
numBytes = PR_Read(src, buf, info.size);
|
||||
if (numBytes != info.size) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (buf[numBytes - 1] == '\n')
|
||||
numBytes--;
|
||||
#ifdef _WINDOWS
|
||||
if (buf[numBytes - 1] == '\r')
|
||||
numBytes--;
|
||||
#endif
|
||||
|
||||
/* XXX workaround for 3.1, not all utils zero dst before sending */
|
||||
dst->data = 0;
|
||||
if (!SECITEM_AllocItem(NULL, dst, numBytes))
|
||||
goto loser;
|
||||
|
||||
memcpy(dst->data, buf, numBytes);
|
||||
|
||||
PORT_Free(buf);
|
||||
return SECSuccess;
|
||||
loser:
|
||||
PORT_Free(buf);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
#define INDENT_MULT 4
|
||||
void
|
||||
SECU_Indent(FILE *out, int level)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < level; i++) {
|
||||
fprintf(out, " ");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SECU_Newline(FILE *out)
|
||||
{
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
SECU_PrintAsHex(FILE *out, const SECItem *data, const char *m, int level)
|
||||
{
|
||||
unsigned i;
|
||||
int column = 0;
|
||||
PRBool isString = PR_TRUE;
|
||||
PRBool isWhiteSpace = PR_TRUE;
|
||||
PRBool printedHex = PR_FALSE;
|
||||
unsigned int limit = 15;
|
||||
|
||||
if (m) {
|
||||
SECU_Indent(out, level);
|
||||
fprintf(out, "%s:", m);
|
||||
level++;
|
||||
if (wrapEnabled)
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
|
||||
if (wrapEnabled) {
|
||||
SECU_Indent(out, level);
|
||||
column = level * INDENT_MULT;
|
||||
}
|
||||
if (!data->len) {
|
||||
fprintf(out, "(empty)\n");
|
||||
return;
|
||||
}
|
||||
/* take a pass to see if it's all printable. */
|
||||
for (i = 0; i < data->len; i++) {
|
||||
unsigned char val = data->data[i];
|
||||
if (!val || !isprint(val)) {
|
||||
isString = PR_FALSE;
|
||||
break;
|
||||
}
|
||||
if (isWhiteSpace && !isspace(val)) {
|
||||
isWhiteSpace = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Short values, such as bit strings (which are printed with this
|
||||
** function) often look like strings, but we want to see the bits.
|
||||
** so this test assures that short values will be printed in hex,
|
||||
** perhaps in addition to being printed as strings.
|
||||
** The threshold size (4 bytes) is arbitrary.
|
||||
*/
|
||||
if (!isString || data->len <= 4) {
|
||||
for (i = 0; i < data->len; i++) {
|
||||
if (i != data->len - 1) {
|
||||
fprintf(out, "%02x:", data->data[i]);
|
||||
column += 3;
|
||||
} else {
|
||||
fprintf(out, "%02x", data->data[i]);
|
||||
column += 2;
|
||||
break;
|
||||
}
|
||||
if (wrapEnabled &&
|
||||
(column > 76 || (i % 16 == limit))) {
|
||||
SECU_Newline(out);
|
||||
SECU_Indent(out, level);
|
||||
column = level * INDENT_MULT;
|
||||
limit = i % 16;
|
||||
}
|
||||
}
|
||||
printedHex = PR_TRUE;
|
||||
}
|
||||
if (isString && !isWhiteSpace) {
|
||||
if (printedHex != PR_FALSE) {
|
||||
SECU_Newline(out);
|
||||
SECU_Indent(out, level);
|
||||
column = level * INDENT_MULT;
|
||||
}
|
||||
for (i = 0; i < data->len; i++) {
|
||||
unsigned char val = data->data[i];
|
||||
|
||||
if (val) {
|
||||
fprintf(out, "%c", val);
|
||||
column++;
|
||||
} else {
|
||||
column = 77;
|
||||
}
|
||||
if (wrapEnabled && column > 76) {
|
||||
SECU_Newline(out);
|
||||
SECU_Indent(out, level);
|
||||
column = level * INDENT_MULT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (column != level * INDENT_MULT) {
|
||||
SECU_Newline(out);
|
||||
}
|
||||
}
|
||||
|
||||
const char *hex = "0123456789abcdef";
|
||||
|
||||
const char printable[257] = {
|
||||
"................" /* 0x */
|
||||
"................" /* 1x */
|
||||
" !\"#$%&'()*+,-./" /* 2x */
|
||||
"0123456789:;<=>?" /* 3x */
|
||||
"@ABCDEFGHIJKLMNO" /* 4x */
|
||||
"PQRSTUVWXYZ[\\]^_" /* 5x */
|
||||
"`abcdefghijklmno" /* 6x */
|
||||
"pqrstuvwxyz{|}~." /* 7x */
|
||||
"................" /* 8x */
|
||||
"................" /* 9x */
|
||||
"................" /* ax */
|
||||
"................" /* bx */
|
||||
"................" /* cx */
|
||||
"................" /* dx */
|
||||
"................" /* ex */
|
||||
"................" /* fx */
|
||||
};
|
||||
|
||||
void
|
||||
SECU_PrintBuf(FILE *out, const char *msg, const void *vp, int len)
|
||||
{
|
||||
const unsigned char *cp = (const unsigned char *)vp;
|
||||
char buf[80];
|
||||
char *bp;
|
||||
char *ap;
|
||||
|
||||
fprintf(out, "%s [Len: %d]\n", msg, len);
|
||||
memset(buf, ' ', sizeof buf);
|
||||
bp = buf;
|
||||
ap = buf + 50;
|
||||
while (--len >= 0) {
|
||||
unsigned char ch = *cp++;
|
||||
*bp++ = hex[(ch >> 4) & 0xf];
|
||||
*bp++ = hex[ch & 0xf];
|
||||
*bp++ = ' ';
|
||||
*ap++ = printable[ch];
|
||||
if (ap - buf >= 66) {
|
||||
*ap = 0;
|
||||
fprintf(out, " %s\n", buf);
|
||||
memset(buf, ' ', sizeof buf);
|
||||
bp = buf;
|
||||
ap = buf + 50;
|
||||
}
|
||||
}
|
||||
if (bp > buf) {
|
||||
*ap = 0;
|
||||
fprintf(out, " %s\n", buf);
|
||||
}
|
||||
}
|
||||
|
||||
/* This expents i->data[0] to be the MSB of the integer.
|
||||
** if you want to print a DER-encoded integer (with the tag and length)
|
||||
** call SECU_PrintEncodedInteger();
|
||||
*/
|
||||
void
|
||||
SECU_PrintInteger(FILE *out, const SECItem *i, const char *m, int level)
|
||||
{
|
||||
int iv;
|
||||
|
||||
if (!i || !i->len || !i->data) {
|
||||
SECU_Indent(out, level);
|
||||
if (m) {
|
||||
fprintf(out, "%s: (null)\n", m);
|
||||
} else {
|
||||
fprintf(out, "(null)\n");
|
||||
}
|
||||
} else if (i->len > 4) {
|
||||
SECU_PrintAsHex(out, i, m, level);
|
||||
} else {
|
||||
if (i->type == siUnsignedInteger && *i->data & 0x80) {
|
||||
/* Make sure i->data has zero in the highest bite
|
||||
* if i->data is an unsigned integer */
|
||||
SECItem tmpI;
|
||||
char data[] = { 0, 0, 0, 0, 0 };
|
||||
|
||||
PORT_Memcpy(data + 1, i->data, i->len);
|
||||
tmpI.len = i->len + 1;
|
||||
tmpI.data = (void *)data;
|
||||
|
||||
iv = DER_GetInteger(&tmpI);
|
||||
} else {
|
||||
iv = DER_GetInteger(i);
|
||||
}
|
||||
SECU_Indent(out, level);
|
||||
if (m) {
|
||||
fprintf(out, "%s: %d (0x%x)\n", m, iv, iv);
|
||||
} else {
|
||||
fprintf(out, "%d (0x%x)\n", iv, iv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG) || defined(FORCE_PR_ASSERT)
|
||||
/* Returns true iff a[i].flag has a duplicate in a[i+1 : count-1] */
|
||||
static PRBool
|
||||
HasShortDuplicate(int i, secuCommandFlag *a, int count)
|
||||
{
|
||||
char target = a[i].flag;
|
||||
int j;
|
||||
|
||||
/* duplicate '\0' flags are okay, they are used with long forms */
|
||||
for (j = i + 1; j < count; j++) {
|
||||
if (a[j].flag && a[j].flag == target) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* Returns true iff a[i].longform has a duplicate in a[i+1 : count-1] */
|
||||
static PRBool
|
||||
HasLongDuplicate(int i, secuCommandFlag *a, int count)
|
||||
{
|
||||
int j;
|
||||
char *target = a[i].longform;
|
||||
|
||||
if (!target)
|
||||
return PR_FALSE;
|
||||
|
||||
for (j = i + 1; j < count; j++) {
|
||||
if (a[j].longform && strcmp(a[j].longform, target) == 0) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* Returns true iff a has no short or long form duplicates
|
||||
*/
|
||||
PRBool
|
||||
HasNoDuplicates(secuCommandFlag *a, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
if (a[i].flag && HasShortDuplicate(i, a, count)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (a[i].longform && HasLongDuplicate(i, a, count)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
SECStatus
|
||||
SECU_ParseCommandLine(int argc, char **argv, char *progName,
|
||||
const secuCommand *cmd)
|
||||
{
|
||||
PRBool found;
|
||||
PLOptState *optstate;
|
||||
PLOptStatus status;
|
||||
char *optstring;
|
||||
PLLongOpt *longopts = NULL;
|
||||
int i, j;
|
||||
int lcmd = 0, lopt = 0;
|
||||
|
||||
PR_ASSERT(HasNoDuplicates(cmd->commands, cmd->numCommands));
|
||||
PR_ASSERT(HasNoDuplicates(cmd->options, cmd->numOptions));
|
||||
|
||||
optstring = (char *)PORT_Alloc(cmd->numCommands + 2 * cmd->numOptions + 1);
|
||||
if (optstring == NULL)
|
||||
return SECFailure;
|
||||
|
||||
j = 0;
|
||||
for (i = 0; i < cmd->numCommands; i++) {
|
||||
if (cmd->commands[i].flag) /* single character option ? */
|
||||
optstring[j++] = cmd->commands[i].flag;
|
||||
if (cmd->commands[i].longform)
|
||||
lcmd++;
|
||||
}
|
||||
for (i = 0; i < cmd->numOptions; i++) {
|
||||
if (cmd->options[i].flag) {
|
||||
optstring[j++] = cmd->options[i].flag;
|
||||
if (cmd->options[i].needsArg)
|
||||
optstring[j++] = ':';
|
||||
}
|
||||
if (cmd->options[i].longform)
|
||||
lopt++;
|
||||
}
|
||||
|
||||
optstring[j] = '\0';
|
||||
|
||||
if (lcmd + lopt > 0) {
|
||||
longopts = PORT_NewArray(PLLongOpt, lcmd + lopt + 1);
|
||||
if (!longopts) {
|
||||
PORT_Free(optstring);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
for (i = 0; j < lcmd && i < cmd->numCommands; i++) {
|
||||
if (cmd->commands[i].longform) {
|
||||
longopts[j].longOptName = cmd->commands[i].longform;
|
||||
longopts[j].longOption = 0;
|
||||
longopts[j++].valueRequired = cmd->commands[i].needsArg;
|
||||
}
|
||||
}
|
||||
lopt += lcmd;
|
||||
for (i = 0; j < lopt && i < cmd->numOptions; i++) {
|
||||
if (cmd->options[i].longform) {
|
||||
longopts[j].longOptName = cmd->options[i].longform;
|
||||
longopts[j].longOption = 0;
|
||||
longopts[j++].valueRequired = cmd->options[i].needsArg;
|
||||
}
|
||||
}
|
||||
longopts[j].longOptName = NULL;
|
||||
}
|
||||
|
||||
optstate = PL_CreateLongOptState(argc, argv, optstring, longopts);
|
||||
if (!optstate) {
|
||||
PORT_Free(optstring);
|
||||
PORT_Free(longopts);
|
||||
return SECFailure;
|
||||
}
|
||||
/* Parse command line arguments */
|
||||
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
|
||||
const char *optstatelong;
|
||||
char option = optstate->option;
|
||||
|
||||
/* positional parameter, single-char option or long opt? */
|
||||
if (optstate->longOptIndex == -1) {
|
||||
/* not a long opt */
|
||||
if (option == '\0')
|
||||
continue; /* it's a positional parameter */
|
||||
optstatelong = "";
|
||||
} else {
|
||||
/* long opt */
|
||||
if (option == '\0')
|
||||
option = '\377'; /* force unequal with all flags */
|
||||
optstatelong = longopts[optstate->longOptIndex].longOptName;
|
||||
}
|
||||
|
||||
found = PR_FALSE;
|
||||
|
||||
for (i = 0; i < cmd->numCommands; i++) {
|
||||
if (cmd->commands[i].flag == option ||
|
||||
cmd->commands[i].longform == optstatelong) {
|
||||
cmd->commands[i].activated = PR_TRUE;
|
||||
if (optstate->value) {
|
||||
cmd->commands[i].arg = (char *)optstate->value;
|
||||
}
|
||||
found = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < cmd->numOptions; i++) {
|
||||
if (cmd->options[i].flag == option ||
|
||||
cmd->options[i].longform == optstatelong) {
|
||||
cmd->options[i].activated = PR_TRUE;
|
||||
if (optstate->value) {
|
||||
cmd->options[i].arg = (char *)optstate->value;
|
||||
} else if (cmd->options[i].needsArg) {
|
||||
status = PL_OPT_BAD;
|
||||
goto loser;
|
||||
}
|
||||
found = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
status = PL_OPT_BAD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
loser:
|
||||
PL_DestroyOptState(optstate);
|
||||
PORT_Free(optstring);
|
||||
if (longopts)
|
||||
PORT_Free(longopts);
|
||||
if (status == PL_OPT_BAD)
|
||||
return SECFailure;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
char *
|
||||
SECU_GetOptionArg(const secuCommand *cmd, int optionNum)
|
||||
{
|
||||
if (optionNum < 0 || optionNum >= cmd->numOptions)
|
||||
return NULL;
|
||||
if (cmd->options[optionNum].activated)
|
||||
return PL_strdup(cmd->options[optionNum].arg);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
SECU_PrintPRandOSError(const char *progName)
|
||||
{
|
||||
char buffer[513];
|
||||
PRInt32 errLen = PR_GetErrorTextLength();
|
||||
if (errLen > 0 && errLen < sizeof buffer) {
|
||||
PR_GetErrorText(buffer);
|
||||
}
|
||||
SECU_PrintError(progName, "function failed");
|
||||
if (errLen > 0 && errLen < sizeof buffer) {
|
||||
PR_fprintf(PR_STDERR, "\t%s\n", buffer);
|
||||
}
|
||||
}
|
||||
|
||||
SECOidTag
|
||||
SECU_StringToSignatureAlgTag(const char *alg)
|
||||
{
|
||||
SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
|
||||
|
||||
if (alg) {
|
||||
if (!PL_strcmp(alg, "MD2")) {
|
||||
hashAlgTag = SEC_OID_MD2;
|
||||
} else if (!PL_strcmp(alg, "MD4")) {
|
||||
hashAlgTag = SEC_OID_MD4;
|
||||
} else if (!PL_strcmp(alg, "MD5")) {
|
||||
hashAlgTag = SEC_OID_MD5;
|
||||
} else if (!PL_strcmp(alg, "SHA1")) {
|
||||
hashAlgTag = SEC_OID_SHA1;
|
||||
} else if (!PL_strcmp(alg, "SHA224")) {
|
||||
hashAlgTag = SEC_OID_SHA224;
|
||||
} else if (!PL_strcmp(alg, "SHA256")) {
|
||||
hashAlgTag = SEC_OID_SHA256;
|
||||
} else if (!PL_strcmp(alg, "SHA384")) {
|
||||
hashAlgTag = SEC_OID_SHA384;
|
||||
} else if (!PL_strcmp(alg, "SHA512")) {
|
||||
hashAlgTag = SEC_OID_SHA512;
|
||||
}
|
||||
}
|
||||
return hashAlgTag;
|
||||
}
|
||||
|
||||
/* Caller ensures that dst is at least item->len*2+1 bytes long */
|
||||
void
|
||||
SECU_SECItemToHex(const SECItem *item, char *dst)
|
||||
{
|
||||
if (dst && item && item->data) {
|
||||
unsigned char *src = item->data;
|
||||
unsigned int len = item->len;
|
||||
for (; len > 0; --len, dst += 2) {
|
||||
sprintf(dst, "%02x", *src++);
|
||||
}
|
||||
*dst = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char
|
||||
nibble(char c)
|
||||
{
|
||||
c = PORT_Tolower(c);
|
||||
return (c >= '0' && c <= '9') ? c - '0' : (c >= 'a' && c <= 'f') ? c - 'a' + 10 : -1;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SECU_SECItemHexStringToBinary(SECItem *srcdest)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!srcdest) {
|
||||
PORT_SetError(SEC_ERROR_INVALID_ARGS);
|
||||
return SECFailure;
|
||||
}
|
||||
if (srcdest->len < 4 || (srcdest->len % 2)) {
|
||||
/* too short to convert, or even number of characters */
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return SECFailure;
|
||||
}
|
||||
if (PORT_Strncasecmp((const char *)srcdest->data, "0x", 2)) {
|
||||
/* wrong prefix */
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
/* 1st pass to check for hex characters */
|
||||
for (i = 2; i < srcdest->len; i++) {
|
||||
char c = PORT_Tolower(srcdest->data[i]);
|
||||
if (!((c >= '0' && c <= '9') ||
|
||||
(c >= 'a' && c <= 'f'))) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DATA);
|
||||
return SECFailure;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2nd pass to convert */
|
||||
for (i = 2; i < srcdest->len; i += 2) {
|
||||
srcdest->data[(i - 2) / 2] = (nibble(srcdest->data[i]) << 4) +
|
||||
nibble(srcdest->data[i + 1]);
|
||||
}
|
||||
|
||||
/* adjust length */
|
||||
srcdest->len -= 2;
|
||||
srcdest->len /= 2;
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
SSLNamedGroup
|
||||
groupNameToNamedGroup(char *name)
|
||||
{
|
||||
if (PL_strlen(name) == 4) {
|
||||
if (!strncmp(name, "P256", 4)) {
|
||||
return ssl_grp_ec_secp256r1;
|
||||
}
|
||||
if (!strncmp(name, "P384", 4)) {
|
||||
return ssl_grp_ec_secp384r1;
|
||||
}
|
||||
if (!strncmp(name, "P521", 4)) {
|
||||
return ssl_grp_ec_secp521r1;
|
||||
}
|
||||
}
|
||||
if (PL_strlen(name) == 6) {
|
||||
if (!strncmp(name, "x25519", 6)) {
|
||||
return ssl_grp_ec_curve25519;
|
||||
}
|
||||
if (!strncmp(name, "FF2048", 6)) {
|
||||
return ssl_grp_ffdhe_2048;
|
||||
}
|
||||
if (!strncmp(name, "FF3072", 6)) {
|
||||
return ssl_grp_ffdhe_3072;
|
||||
}
|
||||
if (!strncmp(name, "FF4096", 6)) {
|
||||
return ssl_grp_ffdhe_4096;
|
||||
}
|
||||
if (!strncmp(name, "FF6144", 6)) {
|
||||
return ssl_grp_ffdhe_6144;
|
||||
}
|
||||
if (!strncmp(name, "FF8192", 6)) {
|
||||
return ssl_grp_ffdhe_8192;
|
||||
}
|
||||
}
|
||||
|
||||
return ssl_grp_none;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
|
||||
unsigned int *enabledGroupsCount)
|
||||
{
|
||||
SSLNamedGroup *groups;
|
||||
char *str;
|
||||
char *p;
|
||||
unsigned int numValues = 0;
|
||||
unsigned int count = 0;
|
||||
|
||||
/* Count the number of groups. */
|
||||
str = PORT_Strdup(arg);
|
||||
if (!str) {
|
||||
return SECFailure;
|
||||
}
|
||||
p = strtok(str, ",");
|
||||
while (p) {
|
||||
++numValues;
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
PORT_Free(str);
|
||||
str = NULL;
|
||||
groups = PORT_ZNewArray(SSLNamedGroup, numValues);
|
||||
if (!groups) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Get group names. */
|
||||
str = PORT_Strdup(arg);
|
||||
if (!str) {
|
||||
goto done;
|
||||
}
|
||||
p = strtok(str, ",");
|
||||
while (p) {
|
||||
SSLNamedGroup group = groupNameToNamedGroup(p);
|
||||
if (group == ssl_grp_none) {
|
||||
count = 0;
|
||||
goto done;
|
||||
}
|
||||
groups[count++] = group;
|
||||
p = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
done:
|
||||
if (str) {
|
||||
PORT_Free(str);
|
||||
}
|
||||
if (!count) {
|
||||
PORT_Free(groups);
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
*enabledGroupsCount = count;
|
||||
*enabledGroups = groups;
|
||||
return SECSuccess;
|
||||
}
|
||||
137
security/nss/cmd/lib/basicutil.h
Normal file
137
security/nss/cmd/lib/basicutil.h
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/* 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/. */
|
||||
#ifndef _BASIC_UTILS_H_
|
||||
#define _BASIC_UTILS_H_
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secitem.h"
|
||||
#include "secoid.h"
|
||||
#include "secoidt.h"
|
||||
#include "secport.h"
|
||||
#include "prerror.h"
|
||||
#include "base64.h"
|
||||
#include "secasn1.h"
|
||||
#include "secder.h"
|
||||
#include "sslt.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef SECUTIL_NEW
|
||||
typedef int (*SECU_PPFunc)(PRFileDesc *out, SECItem *item,
|
||||
char *msg, int level);
|
||||
#else
|
||||
typedef int (*SECU_PPFunc)(FILE *out, SECItem *item, char *msg, int level);
|
||||
#endif
|
||||
|
||||
/* print out an error message */
|
||||
extern void SECU_PrintError(const char *progName, const char *msg, ...);
|
||||
|
||||
/* print out a system error message */
|
||||
extern void SECU_PrintSystemError(const char *progName, const char *msg, ...);
|
||||
|
||||
/* print a formatted error message */
|
||||
extern void SECU_PrintErrMsg(FILE *out, int level, const char *progName,
|
||||
const char *msg, ...);
|
||||
|
||||
/* Read the contents of a file into a SECItem */
|
||||
extern SECStatus SECU_FileToItem(SECItem *dst, PRFileDesc *src);
|
||||
extern SECStatus SECU_TextFileToItem(SECItem *dst, PRFileDesc *src);
|
||||
|
||||
/* Indent based on "level" */
|
||||
extern void SECU_Indent(FILE *out, int level);
|
||||
|
||||
/* Print a newline to out */
|
||||
extern void SECU_Newline(FILE *out);
|
||||
|
||||
/* Print integer value and hex */
|
||||
extern void SECU_PrintInteger(FILE *out, const SECItem *i, const char *m,
|
||||
int level);
|
||||
|
||||
/* Print SECItem as hex */
|
||||
extern void SECU_PrintAsHex(FILE *out, const SECItem *i, const char *m,
|
||||
int level);
|
||||
|
||||
/* dump a buffer in hex and ASCII */
|
||||
extern void SECU_PrintBuf(FILE *out, const char *msg, const void *vp, int len);
|
||||
|
||||
#ifdef HAVE_EPV_TEMPLATE
|
||||
/* Dump contents of private key */
|
||||
extern int SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level);
|
||||
#endif
|
||||
|
||||
/* Init PKCS11 stuff */
|
||||
extern SECStatus SECU_PKCS11Init(PRBool readOnly);
|
||||
|
||||
/* Dump contents of signed data */
|
||||
extern int SECU_PrintSignedData(FILE *out, SECItem *der, const char *m,
|
||||
int level, SECU_PPFunc inner);
|
||||
|
||||
extern void SECU_PrintString(FILE *out, const SECItem *si, const char *m,
|
||||
int level);
|
||||
extern void SECU_PrintAny(FILE *out, const SECItem *i, const char *m, int level);
|
||||
|
||||
extern void SECU_PrintPRandOSError(const char *progName);
|
||||
|
||||
/* Caller ensures that dst is at least item->len*2+1 bytes long */
|
||||
void
|
||||
SECU_SECItemToHex(const SECItem *item, char *dst);
|
||||
|
||||
/* Requires 0x prefix. Case-insensitive. Will do in-place replacement if
|
||||
* successful */
|
||||
SECStatus
|
||||
SECU_SECItemHexStringToBinary(SECItem *srcdest);
|
||||
|
||||
/*
|
||||
*
|
||||
* Utilities for parsing security tools command lines
|
||||
*
|
||||
*/
|
||||
|
||||
/* A single command flag */
|
||||
typedef struct {
|
||||
char flag;
|
||||
PRBool needsArg;
|
||||
char *arg;
|
||||
PRBool activated;
|
||||
char *longform;
|
||||
} secuCommandFlag;
|
||||
|
||||
/* A full array of command/option flags */
|
||||
typedef struct
|
||||
{
|
||||
int numCommands;
|
||||
int numOptions;
|
||||
|
||||
secuCommandFlag *commands;
|
||||
secuCommandFlag *options;
|
||||
} secuCommand;
|
||||
|
||||
/* fill the "arg" and "activated" fields for each flag */
|
||||
SECStatus
|
||||
SECU_ParseCommandLine(int argc, char **argv, char *progName,
|
||||
const secuCommand *cmd);
|
||||
char *
|
||||
SECU_GetOptionArg(const secuCommand *cmd, int optionNum);
|
||||
|
||||
SECStatus parseGroupList(const char *arg, SSLNamedGroup **enabledGroups,
|
||||
unsigned int *enabledGroupsCount);
|
||||
SSLNamedGroup groupNameToNamedGroup(char *name);
|
||||
|
||||
/*
|
||||
*
|
||||
* Error messaging
|
||||
*
|
||||
*/
|
||||
|
||||
void printflags(char *trusts, unsigned int flags);
|
||||
|
||||
#if !defined(XP_UNIX) && !defined(XP_OS2)
|
||||
extern int ffs(unsigned int i);
|
||||
#endif
|
||||
|
||||
#include "secerr.h"
|
||||
|
||||
extern const char *hex;
|
||||
extern const char printable[];
|
||||
|
||||
#endif /* _BASIC_UTILS_H_ */
|
||||
388
security/nss/cmd/lib/berparse.c
Normal file
388
security/nss/cmd/lib/berparse.c
Normal file
|
|
@ -0,0 +1,388 @@
|
|||
/* 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/. */
|
||||
#include "secutil.h"
|
||||
|
||||
typedef enum {
|
||||
tagDone,
|
||||
lengthDone,
|
||||
leafDone,
|
||||
compositeDone,
|
||||
notDone,
|
||||
parseError,
|
||||
parseComplete
|
||||
} ParseState;
|
||||
|
||||
typedef unsigned char Byte;
|
||||
typedef void (*ParseProc)(BERParse *h, unsigned char **buf, int *len);
|
||||
typedef struct {
|
||||
SECArb arb;
|
||||
int pos; /* length from global start to item start */
|
||||
SECArb *parent;
|
||||
} ParseStackElem;
|
||||
|
||||
struct BERParseStr {
|
||||
PLArenaPool *his;
|
||||
PLArenaPool *mine;
|
||||
ParseProc proc;
|
||||
int stackDepth;
|
||||
ParseStackElem *stackPtr;
|
||||
ParseStackElem *stack;
|
||||
int pending; /* bytes remaining to complete this part */
|
||||
int pos; /* running length of consumed characters */
|
||||
ParseState state;
|
||||
PRBool keepLeaves;
|
||||
PRBool derOnly;
|
||||
BERFilterProc filter;
|
||||
void *filterArg;
|
||||
BERNotifyProc before;
|
||||
void *beforeArg;
|
||||
BERNotifyProc after;
|
||||
void *afterArg;
|
||||
};
|
||||
|
||||
#define UNKNOWN -1
|
||||
|
||||
static unsigned char
|
||||
NextChar(BERParse *h, unsigned char **buf, int *len)
|
||||
{
|
||||
unsigned char c = *(*buf)++;
|
||||
(*len)--;
|
||||
h->pos++;
|
||||
if (h->filter)
|
||||
(*h->filter)(h->filterArg, &c, 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
static void
|
||||
ParseTag(BERParse *h, unsigned char **buf, int *len)
|
||||
{
|
||||
SECArb *arb = &(h->stackPtr->arb);
|
||||
arb->tag = NextChar(h, buf, len);
|
||||
|
||||
PORT_Assert(h->state == notDone);
|
||||
|
||||
/*
|
||||
* NOTE: This does not handle the high-tag-number form
|
||||
*/
|
||||
if ((arb->tag & DER_HIGH_TAG_NUMBER) == DER_HIGH_TAG_NUMBER) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
h->state = parseError;
|
||||
return;
|
||||
}
|
||||
|
||||
h->pending = UNKNOWN;
|
||||
arb->length = UNKNOWN;
|
||||
if (arb->tag & DER_CONSTRUCTED) {
|
||||
arb->body.cons.numSubs = 0;
|
||||
arb->body.cons.subs = NULL;
|
||||
} else {
|
||||
arb->body.item.len = UNKNOWN;
|
||||
arb->body.item.data = NULL;
|
||||
}
|
||||
|
||||
h->state = tagDone;
|
||||
}
|
||||
|
||||
static void
|
||||
ParseLength(BERParse *h, unsigned char **buf, int *len)
|
||||
{
|
||||
Byte b;
|
||||
SECArb *arb = &(h->stackPtr->arb);
|
||||
|
||||
PORT_Assert(h->state == notDone);
|
||||
|
||||
if (h->pending == UNKNOWN) {
|
||||
b = NextChar(h, buf, len);
|
||||
if ((b & 0x80) == 0) { /* short form */
|
||||
arb->length = b;
|
||||
/*
|
||||
* if the tag and the length are both zero bytes, then this
|
||||
* should be the marker showing end of list for the
|
||||
* indefinite length composite
|
||||
*/
|
||||
if (arb->length == 0 && arb->tag == 0)
|
||||
h->state = compositeDone;
|
||||
else
|
||||
h->state = lengthDone;
|
||||
return;
|
||||
}
|
||||
|
||||
h->pending = b & 0x7f;
|
||||
/* 0 implies this is an indefinite length */
|
||||
if (h->pending > 4) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
h->state = parseError;
|
||||
return;
|
||||
}
|
||||
arb->length = 0;
|
||||
}
|
||||
|
||||
while ((*len > 0) && (h->pending > 0)) {
|
||||
b = NextChar(h, buf, len);
|
||||
arb->length = (arb->length << 8) + b;
|
||||
h->pending--;
|
||||
}
|
||||
if (h->pending == 0) {
|
||||
if (h->derOnly && (arb->length == 0))
|
||||
h->state = parseError;
|
||||
else
|
||||
h->state = lengthDone;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
ParseLeaf(BERParse *h, unsigned char **buf, int *len)
|
||||
{
|
||||
int count;
|
||||
SECArb *arb = &(h->stackPtr->arb);
|
||||
|
||||
PORT_Assert(h->state == notDone);
|
||||
PORT_Assert(h->pending >= 0);
|
||||
|
||||
if (*len < h->pending)
|
||||
count = *len;
|
||||
else
|
||||
count = h->pending;
|
||||
|
||||
if (h->keepLeaves)
|
||||
memcpy(arb->body.item.data + arb->body.item.len, *buf, count);
|
||||
if (h->filter)
|
||||
(*h->filter)(h->filterArg, *buf, count);
|
||||
*buf += count;
|
||||
*len -= count;
|
||||
arb->body.item.len += count;
|
||||
h->pending -= count;
|
||||
h->pos += count;
|
||||
if (h->pending == 0) {
|
||||
h->state = leafDone;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
CreateArbNode(BERParse *h)
|
||||
{
|
||||
SECArb *arb = PORT_ArenaAlloc(h->his, sizeof(SECArb));
|
||||
|
||||
*arb = h->stackPtr->arb;
|
||||
|
||||
/*
|
||||
* Special case closing the root
|
||||
*/
|
||||
if (h->stackPtr == h->stack) {
|
||||
PORT_Assert(arb->tag & DER_CONSTRUCTED);
|
||||
h->state = parseComplete;
|
||||
} else {
|
||||
SECArb *parent = h->stackPtr->parent;
|
||||
parent->body.cons.subs = DS_ArenaGrow(
|
||||
h->his, parent->body.cons.subs,
|
||||
(parent->body.cons.numSubs) * sizeof(SECArb *),
|
||||
(parent->body.cons.numSubs + 1) * sizeof(SECArb *));
|
||||
parent->body.cons.subs[parent->body.cons.numSubs] = arb;
|
||||
parent->body.cons.numSubs++;
|
||||
h->proc = ParseTag;
|
||||
h->state = notDone;
|
||||
h->pending = UNKNOWN;
|
||||
}
|
||||
if (h->after)
|
||||
(*h->after)(h->afterArg, arb, h->stackPtr - h->stack, PR_FALSE);
|
||||
}
|
||||
|
||||
SECStatus
|
||||
BER_ParseSome(BERParse *h, unsigned char *buf, int len)
|
||||
{
|
||||
if (h->state == parseError)
|
||||
return PR_TRUE;
|
||||
|
||||
while (len) {
|
||||
(*h->proc)(h, &buf, &len);
|
||||
if (h->state == parseComplete) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
h->state = parseError;
|
||||
return PR_TRUE;
|
||||
}
|
||||
if (h->state == parseError)
|
||||
return PR_TRUE;
|
||||
PORT_Assert(h->state != parseComplete);
|
||||
|
||||
if (h->state <= compositeDone) {
|
||||
if (h->proc == ParseTag) {
|
||||
PORT_Assert(h->state == tagDone);
|
||||
h->proc = ParseLength;
|
||||
h->state = notDone;
|
||||
} else if (h->proc == ParseLength) {
|
||||
SECArb *arb = &(h->stackPtr->arb);
|
||||
PORT_Assert(h->state == lengthDone || h->state == compositeDone);
|
||||
|
||||
if (h->before)
|
||||
(*h->before)(h->beforeArg, arb,
|
||||
h->stackPtr - h->stack, PR_TRUE);
|
||||
|
||||
/*
|
||||
* Check to see if this is the end of an indefinite
|
||||
* length composite
|
||||
*/
|
||||
if (h->state == compositeDone) {
|
||||
SECArb *parent = h->stackPtr->parent;
|
||||
PORT_Assert(parent);
|
||||
PORT_Assert(parent->tag & DER_CONSTRUCTED);
|
||||
if (parent->length != 0) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
h->state = parseError;
|
||||
return PR_TRUE;
|
||||
}
|
||||
/*
|
||||
* NOTE: This does not check for an indefinite length
|
||||
* composite being contained inside a definite length
|
||||
* composite. It is not clear that is legal.
|
||||
*/
|
||||
h->stackPtr--;
|
||||
CreateArbNode(h);
|
||||
} else {
|
||||
h->stackPtr->pos = h->pos;
|
||||
|
||||
if (arb->tag & DER_CONSTRUCTED) {
|
||||
SECArb *parent;
|
||||
/*
|
||||
* Make sure there is room on the stack before we
|
||||
* stick anything else there.
|
||||
*/
|
||||
PORT_Assert(h->stackPtr - h->stack < h->stackDepth);
|
||||
if (h->stackPtr - h->stack == h->stackDepth - 1) {
|
||||
int newDepth = h->stackDepth * 2;
|
||||
h->stack = DS_ArenaGrow(h->mine, h->stack,
|
||||
sizeof(ParseStackElem) *
|
||||
h->stackDepth,
|
||||
sizeof(ParseStackElem) *
|
||||
newDepth);
|
||||
h->stackPtr = h->stack + h->stackDepth + 1;
|
||||
h->stackDepth = newDepth;
|
||||
}
|
||||
parent = &(h->stackPtr->arb);
|
||||
h->stackPtr++;
|
||||
h->stackPtr->parent = parent;
|
||||
h->proc = ParseTag;
|
||||
h->state = notDone;
|
||||
h->pending = UNKNOWN;
|
||||
} else {
|
||||
if (arb->length < 0) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
h->state = parseError;
|
||||
return PR_TRUE;
|
||||
}
|
||||
arb->body.item.len = 0;
|
||||
if (arb->length > 0 && h->keepLeaves) {
|
||||
arb->body.item.data =
|
||||
PORT_ArenaAlloc(h->his, arb->length);
|
||||
} else {
|
||||
arb->body.item.data = NULL;
|
||||
}
|
||||
h->proc = ParseLeaf;
|
||||
h->state = notDone;
|
||||
h->pending = arb->length;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ParseStackElem *parent;
|
||||
PORT_Assert(h->state = leafDone);
|
||||
PORT_Assert(h->proc == ParseLeaf);
|
||||
|
||||
for (;;) {
|
||||
CreateArbNode(h);
|
||||
if (h->stackPtr == h->stack)
|
||||
break;
|
||||
parent = (h->stackPtr - 1);
|
||||
PORT_Assert(parent->arb.tag & DER_CONSTRUCTED);
|
||||
if (parent->arb.length == 0) /* need explicit end */
|
||||
break;
|
||||
if (parent->pos + parent->arb.length > h->pos)
|
||||
break;
|
||||
if (parent->pos + parent->arb.length < h->pos) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
h->state = parseError;
|
||||
return PR_TRUE;
|
||||
}
|
||||
h->stackPtr = parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
BERParse *
|
||||
BER_ParseInit(PLArenaPool *arena, PRBool derOnly)
|
||||
{
|
||||
BERParse *h;
|
||||
PLArenaPool *temp = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (temp == NULL) {
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
h = PORT_ArenaAlloc(temp, sizeof(BERParse));
|
||||
if (h == NULL) {
|
||||
PORT_FreeArena(temp, PR_FALSE);
|
||||
PORT_SetError(SEC_ERROR_NO_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
h->his = arena;
|
||||
h->mine = temp;
|
||||
h->proc = ParseTag;
|
||||
h->stackDepth = 20;
|
||||
h->stack = PORT_ArenaZAlloc(h->mine,
|
||||
sizeof(ParseStackElem) * h->stackDepth);
|
||||
h->stackPtr = h->stack;
|
||||
h->state = notDone;
|
||||
h->pos = 0;
|
||||
h->keepLeaves = PR_TRUE;
|
||||
h->before = NULL;
|
||||
h->after = NULL;
|
||||
h->filter = NULL;
|
||||
h->derOnly = derOnly;
|
||||
return h;
|
||||
}
|
||||
|
||||
SECArb *
|
||||
BER_ParseFini(BERParse *h)
|
||||
{
|
||||
PLArenaPool *myArena = h->mine;
|
||||
SECArb *arb;
|
||||
|
||||
if (h->state != parseComplete) {
|
||||
arb = NULL;
|
||||
} else {
|
||||
arb = PORT_ArenaAlloc(h->his, sizeof(SECArb));
|
||||
*arb = h->stackPtr->arb;
|
||||
}
|
||||
|
||||
PORT_FreeArena(myArena, PR_FALSE);
|
||||
|
||||
return arb;
|
||||
}
|
||||
|
||||
void
|
||||
BER_SetFilter(BERParse *h, BERFilterProc proc, void *instance)
|
||||
{
|
||||
h->filter = proc;
|
||||
h->filterArg = instance;
|
||||
}
|
||||
|
||||
void
|
||||
BER_SetLeafStorage(BERParse *h, PRBool keep)
|
||||
{
|
||||
h->keepLeaves = keep;
|
||||
}
|
||||
|
||||
void
|
||||
BER_SetNotifyProc(BERParse *h, BERNotifyProc proc, void *instance,
|
||||
PRBool beforeData)
|
||||
{
|
||||
if (beforeData) {
|
||||
h->before = proc;
|
||||
h->beforeArg = instance;
|
||||
} else {
|
||||
h->after = proc;
|
||||
h->afterArg = instance;
|
||||
}
|
||||
}
|
||||
15
security/nss/cmd/lib/config.mk
Normal file
15
security/nss/cmd/lib/config.mk
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#
|
||||
# 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/.
|
||||
|
||||
#
|
||||
# Override TARGETS variable so that only static libraries
|
||||
# are specifed as dependencies within rules.mk.
|
||||
#
|
||||
|
||||
TARGETS = $(LIBRARY)
|
||||
SHARED_LIBRARY =
|
||||
IMPORT_LIBRARY =
|
||||
PROGRAM =
|
||||
|
||||
594
security/nss/cmd/lib/derprint.c
Normal file
594
security/nss/cmd/lib/derprint.c
Normal file
|
|
@ -0,0 +1,594 @@
|
|||
/* 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/. */
|
||||
#include "secutil.h"
|
||||
#include "secoid.h"
|
||||
|
||||
#ifdef __sun
|
||||
extern int fprintf(FILE *strm, const char *format, ... /* args */);
|
||||
extern int fflush(FILE *stream);
|
||||
#endif
|
||||
|
||||
#define RIGHT_MARGIN 24
|
||||
/*#define RAW_BYTES 1 */
|
||||
|
||||
static int prettyColumn = 0;
|
||||
|
||||
static int
|
||||
getInteger256(const unsigned char *data, unsigned int nb)
|
||||
{
|
||||
int val;
|
||||
|
||||
switch (nb) {
|
||||
case 1:
|
||||
val = data[0];
|
||||
break;
|
||||
case 2:
|
||||
val = (data[0] << 8) | data[1];
|
||||
break;
|
||||
case 3:
|
||||
val = (data[0] << 16) | (data[1] << 8) | data[2];
|
||||
break;
|
||||
case 4:
|
||||
/* If the most significant bit of data[0] is 1, val would be negative.
|
||||
* Treat it as an error.
|
||||
*/
|
||||
if (data[0] & 0x80) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return -1;
|
||||
}
|
||||
val = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
|
||||
break;
|
||||
default:
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static int
|
||||
prettyNewline(FILE *out)
|
||||
{
|
||||
int rv;
|
||||
|
||||
if (prettyColumn != -1) {
|
||||
rv = fprintf(out, "\n");
|
||||
prettyColumn = -1;
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
prettyIndent(FILE *out, unsigned level)
|
||||
{
|
||||
unsigned int i;
|
||||
int rv;
|
||||
|
||||
if (prettyColumn == -1) {
|
||||
prettyColumn = level;
|
||||
for (i = 0; i < level; i++) {
|
||||
rv = fprintf(out, " ");
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
prettyPrintByte(FILE *out, unsigned char item, unsigned int level)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = prettyIndent(out, level);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
rv = fprintf(out, "%02x ", item);
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
|
||||
prettyColumn++;
|
||||
if (prettyColumn >= RIGHT_MARGIN) {
|
||||
return prettyNewline(out);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
prettyPrintLeaf(FILE *out, const unsigned char *data,
|
||||
unsigned int len, unsigned int lv)
|
||||
{
|
||||
unsigned int i;
|
||||
int rv;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
rv = prettyPrintByte(out, *data++, lv);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
}
|
||||
return prettyNewline(out);
|
||||
}
|
||||
|
||||
static int
|
||||
prettyPrintStringStart(FILE *out, const unsigned char *str,
|
||||
unsigned int len, unsigned int level)
|
||||
{
|
||||
#define BUF_SIZE 100
|
||||
unsigned char buf[BUF_SIZE];
|
||||
int rv;
|
||||
|
||||
if (len >= BUF_SIZE)
|
||||
len = BUF_SIZE - 1;
|
||||
|
||||
rv = prettyNewline(out);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
rv = prettyIndent(out, level);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
memcpy(buf, str, len);
|
||||
buf[len] = '\000';
|
||||
|
||||
rv = fprintf(out, "\"%s\"", buf);
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
#undef BUF_SIZE
|
||||
}
|
||||
|
||||
static int
|
||||
prettyPrintString(FILE *out, const unsigned char *str,
|
||||
unsigned int len, unsigned int level, PRBool raw)
|
||||
{
|
||||
int rv;
|
||||
|
||||
rv = prettyPrintStringStart(out, str, len, level);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
rv = prettyNewline(out);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
if (raw) {
|
||||
rv = prettyPrintLeaf(out, str, len, level);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
prettyPrintTime(FILE *out, const unsigned char *str,
|
||||
unsigned int len, unsigned int level, PRBool raw, PRBool utc)
|
||||
{
|
||||
SECItem time_item;
|
||||
int rv;
|
||||
|
||||
rv = prettyPrintStringStart(out, str, len, level);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
time_item.data = (unsigned char *)str;
|
||||
time_item.len = len;
|
||||
|
||||
rv = fprintf(out, " (");
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (utc)
|
||||
SECU_PrintUTCTime(out, &time_item, NULL, 0);
|
||||
else
|
||||
SECU_PrintGeneralizedTime(out, &time_item, NULL, 0);
|
||||
|
||||
rv = fprintf(out, ")");
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = prettyNewline(out);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
if (raw) {
|
||||
rv = prettyPrintLeaf(out, str, len, level);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
prettyPrintObjectID(FILE *out, const unsigned char *data,
|
||||
unsigned int len, unsigned int level, PRBool raw)
|
||||
{
|
||||
SECOidData *oiddata;
|
||||
SECItem oiditem;
|
||||
unsigned int i;
|
||||
unsigned long val;
|
||||
int rv;
|
||||
|
||||
/*
|
||||
* First print the Object Id in numeric format
|
||||
*/
|
||||
|
||||
rv = prettyIndent(out, level);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
if (len == 0) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return -1;
|
||||
}
|
||||
val = data[0];
|
||||
i = val % 40;
|
||||
val = val / 40;
|
||||
rv = fprintf(out, "%lu %u ", val, i);
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
|
||||
val = 0;
|
||||
for (i = 1; i < len; ++i) {
|
||||
unsigned long j;
|
||||
|
||||
j = data[i];
|
||||
val = (val << 7) | (j & 0x7f);
|
||||
if (j & 0x80)
|
||||
continue;
|
||||
rv = fprintf(out, "%lu ", val);
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
val = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now try to look it up and print a symbolic version.
|
||||
*/
|
||||
oiditem.data = (unsigned char *)data;
|
||||
oiditem.len = len;
|
||||
oiddata = SECOID_FindOID(&oiditem);
|
||||
if (oiddata != NULL) {
|
||||
i = PORT_Strlen(oiddata->desc);
|
||||
if ((prettyColumn + 1 + (i / 3)) > RIGHT_MARGIN) {
|
||||
rv = prettyNewline(out);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = prettyIndent(out, level);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
rv = fprintf(out, "(%s)", oiddata->desc);
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
rv = prettyNewline(out);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
if (raw) {
|
||||
rv = prettyPrintLeaf(out, data, len, level);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *prettyTagType[32] = {
|
||||
"End of Contents",
|
||||
"Boolean",
|
||||
"Integer",
|
||||
"Bit String",
|
||||
"Octet String",
|
||||
"NULL",
|
||||
"Object Identifier",
|
||||
"0x07",
|
||||
"0x08",
|
||||
"0x09",
|
||||
"Enumerated",
|
||||
"0x0B",
|
||||
"UTF8 String",
|
||||
"0x0D",
|
||||
"0x0E",
|
||||
"0x0F",
|
||||
"Sequence",
|
||||
"Set",
|
||||
"0x12",
|
||||
"Printable String",
|
||||
"T61 String",
|
||||
"0x15",
|
||||
"IA5 String",
|
||||
"UTC Time",
|
||||
"Generalized Time",
|
||||
"0x19",
|
||||
"Visible String",
|
||||
"0x1B",
|
||||
"Universal String",
|
||||
"0x1D",
|
||||
"BMP String",
|
||||
"High-Tag-Number"
|
||||
};
|
||||
|
||||
static int
|
||||
prettyPrintTag(FILE *out, const unsigned char *src, const unsigned char *end,
|
||||
unsigned char *codep, unsigned int level, PRBool raw)
|
||||
{
|
||||
int rv;
|
||||
unsigned char code, tagnum;
|
||||
|
||||
if (src >= end) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
code = *src;
|
||||
tagnum = code & SEC_ASN1_TAGNUM_MASK;
|
||||
|
||||
/*
|
||||
* NOTE: This code does not (yet) handle the high-tag-number form!
|
||||
*/
|
||||
if (tagnum == SEC_ASN1_HIGH_TAG_NUMBER) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (raw)
|
||||
rv = prettyPrintByte(out, code, level);
|
||||
else
|
||||
rv = prettyIndent(out, level);
|
||||
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
if (code & SEC_ASN1_CONSTRUCTED) {
|
||||
rv = fprintf(out, "C-");
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
switch (code & SEC_ASN1_CLASS_MASK) {
|
||||
case SEC_ASN1_UNIVERSAL:
|
||||
rv = fprintf(out, "%s ", prettyTagType[tagnum]);
|
||||
break;
|
||||
case SEC_ASN1_APPLICATION:
|
||||
rv = fprintf(out, "Application: %d ", tagnum);
|
||||
break;
|
||||
case SEC_ASN1_CONTEXT_SPECIFIC:
|
||||
rv = fprintf(out, "[%d] ", tagnum);
|
||||
break;
|
||||
case SEC_ASN1_PRIVATE:
|
||||
rv = fprintf(out, "Private: %d ", tagnum);
|
||||
break;
|
||||
}
|
||||
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*codep = code;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
prettyPrintLength(FILE *out, const unsigned char *data, const unsigned char *end,
|
||||
int *lenp, PRBool *indefinitep, unsigned int lv, PRBool raw)
|
||||
{
|
||||
unsigned char lbyte;
|
||||
int lenLen;
|
||||
int rv;
|
||||
|
||||
if (data >= end) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rv = fprintf(out, " ");
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*indefinitep = PR_FALSE;
|
||||
|
||||
lbyte = *data++;
|
||||
lenLen = 1;
|
||||
if (lbyte >= 0x80) {
|
||||
/* Multibyte length */
|
||||
unsigned nb = (unsigned)(lbyte & 0x7f);
|
||||
if (nb > 4) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return -1;
|
||||
}
|
||||
if (nb > 0) {
|
||||
int il;
|
||||
|
||||
if ((data + nb) > end) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return -1;
|
||||
}
|
||||
il = getInteger256(data, nb);
|
||||
if (il < 0)
|
||||
return -1;
|
||||
*lenp = (unsigned)il;
|
||||
} else {
|
||||
*lenp = 0;
|
||||
*indefinitep = PR_TRUE;
|
||||
}
|
||||
lenLen += nb;
|
||||
if (raw) {
|
||||
unsigned int i;
|
||||
|
||||
rv = prettyPrintByte(out, lbyte, lv);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
for (i = 0; i < nb; i++) {
|
||||
rv = prettyPrintByte(out, data[i], lv);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*lenp = lbyte;
|
||||
if (raw) {
|
||||
rv = prettyPrintByte(out, lbyte, lv);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
if (*indefinitep)
|
||||
rv = fprintf(out, "(indefinite)\n");
|
||||
else
|
||||
rv = fprintf(out, "(%d)\n", *lenp);
|
||||
if (rv < 0) {
|
||||
PORT_SetError(SEC_ERROR_IO);
|
||||
return rv;
|
||||
}
|
||||
|
||||
prettyColumn = -1;
|
||||
return lenLen;
|
||||
}
|
||||
|
||||
static int
|
||||
prettyPrintItem(FILE *out, const unsigned char *data, const unsigned char *end,
|
||||
unsigned int lv, PRBool raw)
|
||||
{
|
||||
int slen;
|
||||
int lenLen;
|
||||
const unsigned char *orig = data;
|
||||
int rv;
|
||||
|
||||
while (data < end) {
|
||||
unsigned char code;
|
||||
PRBool indefinite;
|
||||
|
||||
slen = prettyPrintTag(out, data, end, &code, lv, raw);
|
||||
if (slen < 0)
|
||||
return slen;
|
||||
data += slen;
|
||||
|
||||
lenLen = prettyPrintLength(out, data, end, &slen, &indefinite, lv, raw);
|
||||
if (lenLen < 0)
|
||||
return lenLen;
|
||||
data += lenLen;
|
||||
|
||||
/*
|
||||
* Just quit now if slen more bytes puts us off the end.
|
||||
*/
|
||||
if ((data + slen) > end) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (code & SEC_ASN1_CONSTRUCTED) {
|
||||
if (slen > 0 || indefinite) {
|
||||
slen = prettyPrintItem(out, data,
|
||||
slen == 0 ? end : data + slen,
|
||||
lv + 1, raw);
|
||||
if (slen < 0)
|
||||
return slen;
|
||||
data += slen;
|
||||
}
|
||||
} else if (code == 0) {
|
||||
if (slen != 0 || lenLen != 1) {
|
||||
PORT_SetError(SEC_ERROR_BAD_DER);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
switch (code) {
|
||||
case SEC_ASN1_PRINTABLE_STRING:
|
||||
case SEC_ASN1_IA5_STRING:
|
||||
case SEC_ASN1_VISIBLE_STRING:
|
||||
rv = prettyPrintString(out, data, slen, lv + 1, raw);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
break;
|
||||
case SEC_ASN1_UTC_TIME:
|
||||
rv = prettyPrintTime(out, data, slen, lv + 1, raw, PR_TRUE);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
break;
|
||||
case SEC_ASN1_GENERALIZED_TIME:
|
||||
rv = prettyPrintTime(out, data, slen, lv + 1, raw, PR_FALSE);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
break;
|
||||
case SEC_ASN1_OBJECT_ID:
|
||||
rv = prettyPrintObjectID(out, data, slen, lv + 1, raw);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
break;
|
||||
case SEC_ASN1_BOOLEAN: /* could do nicer job */
|
||||
case SEC_ASN1_INTEGER: /* could do nicer job */
|
||||
case SEC_ASN1_BIT_STRING: /* could do nicer job */
|
||||
case SEC_ASN1_OCTET_STRING:
|
||||
case SEC_ASN1_NULL:
|
||||
case SEC_ASN1_ENUMERATED: /* could do nicer job, as INTEGER */
|
||||
case SEC_ASN1_UTF8_STRING:
|
||||
case SEC_ASN1_T61_STRING: /* print as printable string? */
|
||||
case SEC_ASN1_UNIVERSAL_STRING:
|
||||
case SEC_ASN1_BMP_STRING:
|
||||
default:
|
||||
rv = prettyPrintLeaf(out, data, slen, lv + 1);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
break;
|
||||
}
|
||||
data += slen;
|
||||
}
|
||||
}
|
||||
|
||||
rv = prettyNewline(out);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
return data - orig;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
DER_PrettyPrint(FILE *out, const SECItem *it, PRBool raw)
|
||||
{
|
||||
int rv;
|
||||
|
||||
prettyColumn = -1;
|
||||
|
||||
rv = prettyPrintItem(out, it->data, it->data + it->len, 0, raw);
|
||||
if (rv < 0)
|
||||
return SECFailure;
|
||||
return SECSuccess;
|
||||
}
|
||||
27
security/nss/cmd/lib/exports.gyp
Normal file
27
security/nss/cmd/lib/exports.gyp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
# 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/.
|
||||
{
|
||||
'includes': [
|
||||
'../../coreconf/config.gypi'
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'cmd_lib_exports',
|
||||
'type': 'none',
|
||||
'copies': [
|
||||
{
|
||||
'files': [
|
||||
'basicutil.h',
|
||||
'pk11table.h',
|
||||
'secutil.h'
|
||||
],
|
||||
'destination': '<(nss_private_dist_dir)/<(module)'
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
'variables': {
|
||||
'module': 'nss'
|
||||
}
|
||||
}
|
||||
21
security/nss/cmd/lib/ffs.c
Normal file
21
security/nss/cmd/lib/ffs.c
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/* 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/. */
|
||||
#if !defined(XP_UNIX) && !defined(XP_OS2)
|
||||
|
||||
int
|
||||
ffs(unsigned int i)
|
||||
{
|
||||
int rv = 1;
|
||||
|
||||
if (!i)
|
||||
return 0;
|
||||
|
||||
while (!(i & 1)) {
|
||||
i >>= 1;
|
||||
++rv;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
36
security/nss/cmd/lib/lib.gyp
Normal file
36
security/nss/cmd/lib/lib.gyp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# 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/.
|
||||
{
|
||||
'includes': [
|
||||
'../../coreconf/config.gypi'
|
||||
],
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'sectool',
|
||||
'type': 'static_library',
|
||||
'standalone_static_library': 1,
|
||||
'sources': [
|
||||
'basicutil.c',
|
||||
'derprint.c',
|
||||
'ffs.c',
|
||||
'moreoids.c',
|
||||
'pk11table.c',
|
||||
'pppolicy.c',
|
||||
'secpwd.c',
|
||||
'secutil.c'
|
||||
],
|
||||
'dependencies': [
|
||||
'<(DEPTH)/exports.gyp:nss_exports'
|
||||
]
|
||||
}
|
||||
],
|
||||
'target_defaults': {
|
||||
'defines': [
|
||||
'NSPR20'
|
||||
]
|
||||
},
|
||||
'variables': {
|
||||
'module': 'nss'
|
||||
}
|
||||
}
|
||||
39
security/nss/cmd/lib/manifest.mn
Normal file
39
security/nss/cmd/lib/manifest.mn
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# 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/.
|
||||
CORE_DEPTH = ../..
|
||||
|
||||
LIBRARY_NAME = sectool
|
||||
|
||||
# MODULE public and private header directories are implicitly REQUIRED.
|
||||
MODULE = nss
|
||||
|
||||
DEFINES = -DNSPR20
|
||||
|
||||
ifdef NSS_BUILD_SOFTOKEN_ONLY
|
||||
PRIVATE_EXPORTS = basicutil.h \
|
||||
pk11table.h \
|
||||
$(NULL)
|
||||
|
||||
CSRCS = basicutil.c \
|
||||
pk11table.c \
|
||||
$(NULL)
|
||||
else
|
||||
PRIVATE_EXPORTS = basicutil.h \
|
||||
secutil.h \
|
||||
pk11table.h \
|
||||
$(NULL)
|
||||
|
||||
CSRCS = basicutil.c \
|
||||
secutil.c \
|
||||
secpwd.c \
|
||||
derprint.c \
|
||||
moreoids.c \
|
||||
pppolicy.c \
|
||||
ffs.c \
|
||||
pk11table.c \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
NO_MD_RELEASE = 1
|
||||
167
security/nss/cmd/lib/moreoids.c
Normal file
167
security/nss/cmd/lib/moreoids.c
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/* 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/. */
|
||||
|
||||
#include "secoid.h"
|
||||
#include "secmodt.h" /* for CKM_INVALID_MECHANISM */
|
||||
|
||||
#define OI(x) \
|
||||
{ \
|
||||
siDEROID, (unsigned char *)x, sizeof x \
|
||||
}
|
||||
#define OD(oid, tag, desc, mech, ext) \
|
||||
{ \
|
||||
OI(oid) \
|
||||
, tag, desc, mech, ext \
|
||||
}
|
||||
#define ODN(oid, desc) \
|
||||
{ \
|
||||
OI(oid) \
|
||||
, 0, desc, CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION \
|
||||
}
|
||||
|
||||
#define OIDT static const unsigned char
|
||||
|
||||
/* OIW Security Special Interest Group defined algorithms. */
|
||||
#define OIWSSIG 0x2B, 13, 3, 2
|
||||
|
||||
OIDT oiwMD5RSA[] = { OIWSSIG, 3 };
|
||||
OIDT oiwDESCBC[] = { OIWSSIG, 7 };
|
||||
OIDT oiwRSAsig[] = { OIWSSIG, 11 };
|
||||
OIDT oiwDSA[] = { OIWSSIG, 12 };
|
||||
OIDT oiwMD5RSAsig[] = { OIWSSIG, 25 };
|
||||
OIDT oiwSHA1[] = { OIWSSIG, 26 };
|
||||
OIDT oiwDSASHA1[] = { OIWSSIG, 27 };
|
||||
OIDT oiwDSASHA1param[] = { OIWSSIG, 28 };
|
||||
OIDT oiwSHA1RSA[] = { OIWSSIG, 29 };
|
||||
|
||||
/* Microsoft OIDs. (1 3 6 1 4 1 311 ... ) */
|
||||
#define MICROSOFT 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37
|
||||
|
||||
OIDT mCTL[] = { MICROSOFT, 10, 3, 1 }; /* Cert Trust List signing */
|
||||
OIDT mTSS[] = { MICROSOFT, 10, 3, 2 }; /* Time Stamp Signing */
|
||||
OIDT mSGC[] = { MICROSOFT, 10, 3, 3 }; /* Server gated cryptography */
|
||||
OIDT mEFS[] = { MICROSOFT, 10, 3, 4 }; /* Encrypted File System */
|
||||
OIDT mSMIME[] = { MICROSOFT, 16, 4 }; /* SMIME encryption key prefs */
|
||||
|
||||
OIDT mECRTT[] = { MICROSOFT, 20, 2 }; /* Enrollment cert type xtn */
|
||||
OIDT mEAGNT[] = { MICROSOFT, 20, 2, 1 }; /* Enrollment Agent */
|
||||
OIDT mKPSCL[] = { MICROSOFT, 20, 2, 2 }; /* KP SmartCard Logon */
|
||||
OIDT mNTPN[] = { MICROSOFT, 20, 2, 3 }; /* NT Principal Name */
|
||||
OIDT mCASRV[] = { MICROSOFT, 21, 1 }; /* CertServ CA version */
|
||||
|
||||
/* AOL OIDs (1 3 6 1 4 1 1066 ... ) */
|
||||
#define AOL 0x2B, 0x06, 0x01, 0x04, 0x01, 0x88, 0x2A
|
||||
|
||||
/* PKIX IDs (1 3 6 1 5 5 7 ...) */
|
||||
#define ID_PKIX 0x2B, 6, 1, 5, 5, 7
|
||||
/* PKIX Access Descriptors (methods for Authority Info Access Extns) */
|
||||
#define ID_AD ID_PKIX, 48
|
||||
|
||||
OIDT padOCSP[] = { ID_AD, 1 }; /* OCSP method */
|
||||
OIDT padCAissuer[] = { ID_AD, 2 }; /* URI (for CRL ?) */
|
||||
OIDT padTimeStamp[] = { ID_AD, 3 }; /* time stamping */
|
||||
|
||||
/* ISO Cert Extension type OIDs (id-ce) (2 5 29 ...) */
|
||||
#define X500 0x55
|
||||
#define X520_ATTRIBUTE_TYPE X500, 0x04
|
||||
#define X500_ALG X500, 0x08
|
||||
#define X500_ALG_ENCRYPTION X500_ALG, 0x01
|
||||
#define ID_CE X500, 29
|
||||
|
||||
OIDT cePlcyObs[] = { ID_CE, 3 }; /* Cert policies, obsolete. */
|
||||
OIDT cePlcyCns[] = { ID_CE, 36 }; /* Cert policy constraints. */
|
||||
|
||||
/* US Company arc (2 16 840 1 ...) */
|
||||
#define USCOM 0x60, 0x86, 0x48, 0x01
|
||||
#define USGOV USCOM, 0x65
|
||||
#define USDOD USGOV, 2
|
||||
#define ID_INFOSEC USDOD, 1
|
||||
|
||||
/* Verisign PKI OIDs (2 16 840 1 113733 1 ...) */
|
||||
#define VERISIGN_PKI USCOM, 0x86, 0xf8, 0x45, 1
|
||||
#define VERISIGN_XTN VERISIGN_PKI, 6
|
||||
#define VERISIGN_POL VERISIGN_PKI, 7 /* Cert policies */
|
||||
#define VERISIGN_TNET VERISIGN_POL, 23 /* Verisign Trust Network */
|
||||
|
||||
OIDT vcx7[] = { VERISIGN_XTN, 7 }; /* Cert Extension 7 (?) */
|
||||
OIDT vcp1[] = { VERISIGN_TNET, 1 }; /* class 1 cert policy */
|
||||
OIDT vcp2[] = { VERISIGN_TNET, 2 }; /* class 2 cert policy */
|
||||
OIDT vcp3[] = { VERISIGN_TNET, 3 }; /* class 3 cert policy */
|
||||
OIDT vcp4[] = { VERISIGN_TNET, 4 }; /* class 4 cert policy */
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
static const SECOidData oids[] = {
|
||||
/* OIW Security Special Interest Group OIDs */
|
||||
ODN(oiwMD5RSA, "OIWSecSIG MD5 with RSA"),
|
||||
ODN(oiwDESCBC, "OIWSecSIG DES CBC"),
|
||||
ODN(oiwRSAsig, "OIWSecSIG RSA signature"),
|
||||
ODN(oiwDSA, "OIWSecSIG DSA"),
|
||||
ODN(oiwMD5RSAsig, "OIWSecSIG MD5 with RSA signature"),
|
||||
ODN(oiwSHA1, "OIWSecSIG SHA1"),
|
||||
ODN(oiwDSASHA1, "OIWSecSIG DSA with SHA1"),
|
||||
ODN(oiwDSASHA1param, "OIWSecSIG DSA with SHA1 with params"),
|
||||
ODN(oiwSHA1RSA, "OIWSecSIG MD5 with RSA"),
|
||||
|
||||
/* Microsoft OIDs */
|
||||
ODN(mCTL, "Microsoft Cert Trust List signing"),
|
||||
ODN(mTSS, "Microsoft Time Stamp signing"),
|
||||
ODN(mSGC, "Microsoft SGC SSL server"),
|
||||
ODN(mEFS, "Microsoft Encrypted File System"),
|
||||
ODN(mSMIME, "Microsoft SMIME preferences"),
|
||||
ODN(mECRTT, "Microsoft Enrollment Cert Type Extension"),
|
||||
ODN(mEAGNT, "Microsoft Enrollment Agent"),
|
||||
ODN(mKPSCL, "Microsoft KP SmartCard Logon"),
|
||||
ODN(mNTPN, "Microsoft NT Principal Name"),
|
||||
ODN(mCASRV, "Microsoft CertServ CA version"),
|
||||
|
||||
/* PKIX OIDs */
|
||||
ODN(padOCSP, "PKIX OCSP method"),
|
||||
ODN(padCAissuer, "PKIX CA Issuer method"),
|
||||
ODN(padTimeStamp, "PKIX Time Stamping method"),
|
||||
|
||||
/* ID_CE OIDs. */
|
||||
ODN(cePlcyObs, "Certificate Policies (Obsolete)"),
|
||||
ODN(cePlcyCns, "Certificate Policy Constraints"),
|
||||
|
||||
/* Verisign OIDs. */
|
||||
ODN(vcx7, "Verisign Cert Extension 7 (?)"),
|
||||
ODN(vcp1, "Verisign Class 1 Certificate Policy"),
|
||||
ODN(vcp2, "Verisign Class 2 Certificate Policy"),
|
||||
ODN(vcp3, "Verisign Class 3 Certificate Policy"),
|
||||
ODN(vcp4, "Verisign Class 4 Certificate Policy"),
|
||||
|
||||
};
|
||||
|
||||
static const unsigned int numOids = (sizeof oids) / (sizeof oids[0]);
|
||||
|
||||
/* Fetch and register an oid if it hasn't been done already */
|
||||
void
|
||||
SECU_cert_fetchOID(SECOidTag *data, const SECOidData *src)
|
||||
{
|
||||
if (*data == SEC_OID_UNKNOWN) {
|
||||
/* AddEntry does the right thing if someone else has already
|
||||
* added the oid. (that is return that oid tag) */
|
||||
*data = SECOID_AddEntry(src);
|
||||
}
|
||||
}
|
||||
|
||||
SECStatus
|
||||
SECU_RegisterDynamicOids(void)
|
||||
{
|
||||
unsigned int i;
|
||||
SECStatus rv = SECSuccess;
|
||||
|
||||
for (i = 0; i < numOids; ++i) {
|
||||
SECOidTag tag = SECOID_AddEntry(&oids[i]);
|
||||
if (tag == SEC_OID_UNKNOWN) {
|
||||
rv = SECFailure;
|
||||
#ifdef DEBUG_DYN_OIDS
|
||||
fprintf(stderr, "Add OID[%d] failed\n", i);
|
||||
} else {
|
||||
fprintf(stderr, "Add OID[%d] returned tag %d\n", i, tag);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
1517
security/nss/cmd/lib/pk11table.c
Normal file
1517
security/nss/cmd/lib/pk11table.c
Normal file
File diff suppressed because it is too large
Load diff
178
security/nss/cmd/lib/pk11table.h
Normal file
178
security/nss/cmd/lib/pk11table.h
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/* 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/. */
|
||||
#ifndef _PK11_TABLE_H_
|
||||
#define _PK11_TABLE_H_
|
||||
|
||||
/*
|
||||
* Supported functions..
|
||||
*/
|
||||
#include <pkcs11.h>
|
||||
#include "nspr.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
typedef enum {
|
||||
F_No_Function,
|
||||
#undef CK_NEED_ARG_LIST
|
||||
#define CK_PKCS11_FUNCTION_INFO(func) F_##func,
|
||||
#include "pkcs11f.h"
|
||||
#undef CK_NEED_ARG_LISt
|
||||
#undef CK_PKCS11_FUNCTION_INFO
|
||||
F_SetVar,
|
||||
F_SetStringVar,
|
||||
F_NewArray,
|
||||
F_NewInitializeArgs,
|
||||
F_NewTemplate,
|
||||
F_NewMechanism,
|
||||
F_BuildTemplate,
|
||||
F_SetTemplate,
|
||||
F_Print,
|
||||
F_SaveVar,
|
||||
F_RestoreVar,
|
||||
F_Increment,
|
||||
F_Decrement,
|
||||
F_Delete,
|
||||
F_List,
|
||||
F_Run,
|
||||
F_Load,
|
||||
F_Unload,
|
||||
F_System,
|
||||
F_Loop,
|
||||
F_Time,
|
||||
F_Help,
|
||||
F_Quit,
|
||||
F_QuitIf,
|
||||
F_QuitIfString
|
||||
} FunctionType;
|
||||
|
||||
/*
|
||||
* Supported Argument Types
|
||||
*/
|
||||
typedef enum {
|
||||
ArgNone,
|
||||
ArgVar,
|
||||
ArgULong,
|
||||
ArgChar,
|
||||
ArgUTF8,
|
||||
ArgInfo,
|
||||
ArgSlotInfo,
|
||||
ArgTokenInfo,
|
||||
ArgSessionInfo,
|
||||
ArgAttribute,
|
||||
ArgMechanism,
|
||||
ArgMechanismInfo,
|
||||
ArgInitializeArgs,
|
||||
ArgFunctionList,
|
||||
/* Modifier Flags */
|
||||
ArgMask = 0xff,
|
||||
ArgOut = 0x100,
|
||||
ArgArray = 0x200,
|
||||
ArgNew = 0x400,
|
||||
ArgFile = 0x800,
|
||||
ArgStatic = 0x1000,
|
||||
ArgOpt = 0x2000,
|
||||
ArgFull = 0x4000
|
||||
} ArgType;
|
||||
|
||||
typedef enum _constType {
|
||||
ConstNone,
|
||||
ConstBool,
|
||||
ConstInfoFlags,
|
||||
ConstSlotFlags,
|
||||
ConstTokenFlags,
|
||||
ConstSessionFlags,
|
||||
ConstMechanismFlags,
|
||||
ConstInitializeFlags,
|
||||
ConstUsers,
|
||||
ConstSessionState,
|
||||
ConstObject,
|
||||
ConstHardware,
|
||||
ConstKeyType,
|
||||
ConstCertType,
|
||||
ConstAttribute,
|
||||
ConstMechanism,
|
||||
ConstResult,
|
||||
ConstTrust,
|
||||
ConstAvailableSizes,
|
||||
ConstCurrentSize
|
||||
} ConstType;
|
||||
|
||||
typedef struct _constant {
|
||||
const char *name;
|
||||
CK_ULONG value;
|
||||
ConstType type;
|
||||
ConstType attrType;
|
||||
} Constant;
|
||||
|
||||
/*
|
||||
* Values structures.
|
||||
*/
|
||||
typedef struct _values {
|
||||
ArgType type;
|
||||
ConstType constType;
|
||||
int size;
|
||||
char *filename;
|
||||
void *data;
|
||||
int reference;
|
||||
int arraySize;
|
||||
} Value;
|
||||
|
||||
/*
|
||||
* Variables
|
||||
*/
|
||||
typedef struct _variable Variable;
|
||||
struct _variable {
|
||||
Variable *next;
|
||||
char *vname;
|
||||
Value *value;
|
||||
};
|
||||
|
||||
/* NOTE: if you change MAX_ARGS, you need to change the commands array
|
||||
* below as well.
|
||||
*/
|
||||
|
||||
#define MAX_ARGS 10
|
||||
/*
|
||||
* structure for master command array
|
||||
*/
|
||||
typedef struct _commands {
|
||||
char *fname;
|
||||
FunctionType fType;
|
||||
char *helpString;
|
||||
ArgType args[MAX_ARGS];
|
||||
} Commands;
|
||||
|
||||
typedef struct _module {
|
||||
PRLibrary *library;
|
||||
CK_FUNCTION_LIST *functionList;
|
||||
} Module;
|
||||
|
||||
typedef struct _topics {
|
||||
char *name;
|
||||
char *helpString;
|
||||
} Topics;
|
||||
|
||||
/*
|
||||
* the command array itself. Make name to function and it's arguments
|
||||
*/
|
||||
|
||||
extern const char **valueString;
|
||||
extern const int valueCount;
|
||||
extern const char **constTypeString;
|
||||
extern const int constTypeCount;
|
||||
extern const Constant *consts;
|
||||
extern const unsigned int constCount;
|
||||
extern const Commands *commands;
|
||||
extern const int commandCount;
|
||||
extern const Topics *topics;
|
||||
extern const int topicCount;
|
||||
|
||||
extern const char *
|
||||
getName(CK_ULONG value, ConstType type);
|
||||
|
||||
extern const char *
|
||||
getNameFromAttribute(CK_ATTRIBUTE_TYPE type);
|
||||
|
||||
extern unsigned int totalKnownType(ConstType type);
|
||||
|
||||
#endif /* _PK11_TABLE_H_ */
|
||||
263
security/nss/cmd/lib/pppolicy.c
Normal file
263
security/nss/cmd/lib/pppolicy.c
Normal file
|
|
@ -0,0 +1,263 @@
|
|||
/* 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/. */
|
||||
|
||||
/*
|
||||
* Support for various policy related extensions
|
||||
*/
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secport.h"
|
||||
#include "secder.h"
|
||||
#include "cert.h"
|
||||
#include "secoid.h"
|
||||
#include "secasn1.h"
|
||||
#include "secerr.h"
|
||||
#include "nspr.h"
|
||||
#include "secutil.h"
|
||||
|
||||
/* This implementation is derived from the one in nss/lib/certdb/policyxtn.c .
|
||||
** The chief difference is the addition of the OPTIONAL flag to many
|
||||
** parts. The idea is to be able to parse and print as much of the
|
||||
** policy extension as possible, even if some parts are invalid.
|
||||
**
|
||||
** If this approach still is unable to decode policy extensions that
|
||||
** contain invalid parts, then the next approach will be to parse
|
||||
** the PolicyInfos as a SEQUENCE of ANYs, and then parse each of them
|
||||
** as PolicyInfos, with the PolicyQualifiers being ANYs, and finally
|
||||
** parse each of the PolicyQualifiers.
|
||||
*/
|
||||
|
||||
static const SEC_ASN1Template secu_PolicyQualifierTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(CERTPolicyQualifier) },
|
||||
{ SEC_ASN1_OBJECT_ID,
|
||||
offsetof(CERTPolicyQualifier, qualifierID) },
|
||||
{ SEC_ASN1_ANY | SEC_ASN1_OPTIONAL,
|
||||
offsetof(CERTPolicyQualifier, qualifierValue) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const SEC_ASN1Template secu_PolicyInfoTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE,
|
||||
0, NULL, sizeof(CERTPolicyInfo) },
|
||||
{ SEC_ASN1_OBJECT_ID,
|
||||
offsetof(CERTPolicyInfo, policyID) },
|
||||
{ SEC_ASN1_SEQUENCE_OF | SEC_ASN1_OPTIONAL,
|
||||
offsetof(CERTPolicyInfo, policyQualifiers),
|
||||
secu_PolicyQualifierTemplate },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const SEC_ASN1Template secu_CertificatePoliciesTemplate[] = {
|
||||
{ SEC_ASN1_SEQUENCE_OF,
|
||||
offsetof(CERTCertificatePolicies, policyInfos),
|
||||
secu_PolicyInfoTemplate, sizeof(CERTCertificatePolicies) }
|
||||
};
|
||||
|
||||
static CERTCertificatePolicies *
|
||||
secu_DecodeCertificatePoliciesExtension(SECItem *extnValue)
|
||||
{
|
||||
PLArenaPool *arena = NULL;
|
||||
SECStatus rv;
|
||||
CERTCertificatePolicies *policies;
|
||||
CERTPolicyInfo **policyInfos, *policyInfo;
|
||||
CERTPolicyQualifier **policyQualifiers, *policyQualifier;
|
||||
SECItem newExtnValue;
|
||||
|
||||
/* make a new arena */
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
if (!arena) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* allocate the certifiate policies structure */
|
||||
policies = PORT_ArenaZNew(arena, CERTCertificatePolicies);
|
||||
if (policies == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
policies->arena = arena;
|
||||
|
||||
/* copy the DER into the arena, since Quick DER returns data that points
|
||||
into the DER input, which may get freed by the caller */
|
||||
rv = SECITEM_CopyItem(arena, &newExtnValue, extnValue);
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* decode the policy info */
|
||||
rv = SEC_QuickDERDecodeItem(arena, policies,
|
||||
secu_CertificatePoliciesTemplate,
|
||||
&newExtnValue);
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* initialize the oid tags */
|
||||
policyInfos = policies->policyInfos;
|
||||
while (policyInfos != NULL && *policyInfos != NULL) {
|
||||
policyInfo = *policyInfos;
|
||||
policyInfo->oid = SECOID_FindOIDTag(&policyInfo->policyID);
|
||||
policyQualifiers = policyInfo->policyQualifiers;
|
||||
while (policyQualifiers && *policyQualifiers != NULL) {
|
||||
policyQualifier = *policyQualifiers;
|
||||
policyQualifier->oid =
|
||||
SECOID_FindOIDTag(&policyQualifier->qualifierID);
|
||||
policyQualifiers++;
|
||||
}
|
||||
policyInfos++;
|
||||
}
|
||||
|
||||
return (policies);
|
||||
|
||||
loser:
|
||||
if (arena != NULL) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
static char *
|
||||
itemToString(SECItem *item)
|
||||
{
|
||||
char *string;
|
||||
|
||||
string = PORT_ZAlloc(item->len + 1);
|
||||
if (string == NULL)
|
||||
return NULL;
|
||||
PORT_Memcpy(string, item->data, item->len);
|
||||
string[item->len] = 0;
|
||||
return string;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
secu_PrintUserNoticeQualifier(FILE *out, SECItem *qualifierValue,
|
||||
char *msg, int level)
|
||||
{
|
||||
CERTUserNotice *userNotice = NULL;
|
||||
if (qualifierValue)
|
||||
userNotice = CERT_DecodeUserNotice(qualifierValue);
|
||||
if (userNotice) {
|
||||
if (userNotice->noticeReference.organization.len != 0) {
|
||||
char *string =
|
||||
itemToString(&userNotice->noticeReference.organization);
|
||||
SECItem **itemList = userNotice->noticeReference.noticeNumbers;
|
||||
|
||||
while (itemList && *itemList) {
|
||||
SECU_PrintInteger(out, *itemList, string, level + 1);
|
||||
itemList++;
|
||||
}
|
||||
PORT_Free(string);
|
||||
}
|
||||
if (userNotice->displayText.len != 0) {
|
||||
SECU_PrintString(out, &userNotice->displayText,
|
||||
"Display Text", level + 1);
|
||||
}
|
||||
CERT_DestroyUserNotice(userNotice);
|
||||
return SECSuccess;
|
||||
}
|
||||
return SECFailure; /* caller will print this value */
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
secu_PrintPolicyQualifier(FILE *out, CERTPolicyQualifier *policyQualifier,
|
||||
char *msg, int level)
|
||||
{
|
||||
SECStatus rv;
|
||||
SECItem *qualifierValue = &policyQualifier->qualifierValue;
|
||||
|
||||
SECU_PrintObjectID(out, &policyQualifier->qualifierID,
|
||||
"Policy Qualifier Name", level);
|
||||
if (!qualifierValue->data) {
|
||||
SECU_Indent(out, level);
|
||||
fprintf(out, "Error: missing qualifier\n");
|
||||
} else
|
||||
switch (policyQualifier->oid) {
|
||||
case SEC_OID_PKIX_USER_NOTICE_QUALIFIER:
|
||||
rv = secu_PrintUserNoticeQualifier(out, qualifierValue, msg, level);
|
||||
if (SECSuccess == rv)
|
||||
break;
|
||||
/* fall through on error */
|
||||
case SEC_OID_PKIX_CPS_POINTER_QUALIFIER:
|
||||
default:
|
||||
SECU_PrintAny(out, qualifierValue, "Policy Qualifier Data", level);
|
||||
break;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
static SECStatus
|
||||
secu_PrintPolicyInfo(FILE *out, CERTPolicyInfo *policyInfo, char *msg, int level)
|
||||
{
|
||||
CERTPolicyQualifier **policyQualifiers;
|
||||
|
||||
policyQualifiers = policyInfo->policyQualifiers;
|
||||
SECU_PrintObjectID(out, &policyInfo->policyID, "Policy Name", level);
|
||||
|
||||
while (policyQualifiers && *policyQualifiers != NULL) {
|
||||
secu_PrintPolicyQualifier(out, *policyQualifiers, "", level + 1);
|
||||
policyQualifiers++;
|
||||
}
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
SECU_PrintPolicy(FILE *out, SECItem *value, char *msg, int level)
|
||||
{
|
||||
CERTCertificatePolicies *policies = NULL;
|
||||
CERTPolicyInfo **policyInfos;
|
||||
|
||||
if (msg) {
|
||||
SECU_Indent(out, level);
|
||||
fprintf(out, "%s: \n", msg);
|
||||
level++;
|
||||
}
|
||||
policies = secu_DecodeCertificatePoliciesExtension(value);
|
||||
if (policies == NULL) {
|
||||
SECU_PrintAny(out, value, "Invalid Policy Data", level);
|
||||
return;
|
||||
}
|
||||
|
||||
policyInfos = policies->policyInfos;
|
||||
while (policyInfos && *policyInfos != NULL) {
|
||||
secu_PrintPolicyInfo(out, *policyInfos, "", level);
|
||||
policyInfos++;
|
||||
}
|
||||
|
||||
CERT_DestroyCertificatePoliciesExtension(policies);
|
||||
}
|
||||
|
||||
void
|
||||
SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
|
||||
char *msg, int level)
|
||||
{
|
||||
CERTPrivKeyUsagePeriod *prd;
|
||||
PLArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
|
||||
if (!arena) {
|
||||
goto loser;
|
||||
}
|
||||
prd = CERT_DecodePrivKeyUsagePeriodExtension(arena, value);
|
||||
if (!prd) {
|
||||
goto loser;
|
||||
}
|
||||
if (prd->notBefore.data) {
|
||||
SECU_PrintGeneralizedTime(out, &prd->notBefore, "Not Before", level);
|
||||
}
|
||||
if (prd->notAfter.data) {
|
||||
SECU_PrintGeneralizedTime(out, &prd->notAfter, "Not After ", level);
|
||||
}
|
||||
if (!prd->notBefore.data && !prd->notAfter.data) {
|
||||
SECU_Indent(out, level);
|
||||
fprintf(out, "Error: notBefore or notAfter MUST be present.\n");
|
||||
loser:
|
||||
SECU_PrintAny(out, value, msg, level);
|
||||
}
|
||||
if (arena) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
}
|
||||
}
|
||||
168
security/nss/cmd/lib/secpwd.c
Normal file
168
security/nss/cmd/lib/secpwd.c
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
/* 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/. */
|
||||
#include "secutil.h"
|
||||
|
||||
/*
|
||||
* NOTE: The contents of this file are NOT used by the client.
|
||||
* (They are part of the security library as a whole, but they are
|
||||
* NOT USED BY THE CLIENT.) Do not change things on behalf of the
|
||||
* client (like localizing strings), or add things that are only
|
||||
* for the client (put them elsewhere).
|
||||
*/
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <termios.h>
|
||||
#endif
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_BEOS)
|
||||
#include <unistd.h> /* for isatty() */
|
||||
#endif
|
||||
|
||||
#if defined(_WINDOWS)
|
||||
#include <conio.h>
|
||||
#include <io.h>
|
||||
#define QUIET_FGETS quiet_fgets
|
||||
static char *quiet_fgets(char *buf, int length, FILE *input);
|
||||
#else
|
||||
#define QUIET_FGETS fgets
|
||||
#endif
|
||||
|
||||
static void
|
||||
echoOff(int fd)
|
||||
{
|
||||
#if defined(XP_UNIX)
|
||||
if (isatty(fd)) {
|
||||
struct termios tio;
|
||||
tcgetattr(fd, &tio);
|
||||
tio.c_lflag &= ~ECHO;
|
||||
tcsetattr(fd, TCSAFLUSH, &tio);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
echoOn(int fd)
|
||||
{
|
||||
#if defined(XP_UNIX)
|
||||
if (isatty(fd)) {
|
||||
struct termios tio;
|
||||
tcgetattr(fd, &tio);
|
||||
tio.c_lflag |= ECHO;
|
||||
tcsetattr(fd, TCSAFLUSH, &tio);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
char *
|
||||
SEC_GetPassword(FILE *input, FILE *output, char *prompt,
|
||||
PRBool (*ok)(char *))
|
||||
{
|
||||
#if defined(_WINDOWS)
|
||||
int isTTY = (input == stdin);
|
||||
#define echoOn(x)
|
||||
#define echoOff(x)
|
||||
#else
|
||||
int infd = fileno(input);
|
||||
int isTTY = isatty(infd);
|
||||
#endif
|
||||
char phrase[200] = { '\0' }; /* ensure EOF doesn't return junk */
|
||||
|
||||
for (;;) {
|
||||
/* Prompt for password */
|
||||
if (isTTY) {
|
||||
fprintf(output, "%s", prompt);
|
||||
fflush(output);
|
||||
echoOff(infd);
|
||||
}
|
||||
|
||||
if (QUIET_FGETS(phrase, sizeof(phrase), input) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (isTTY) {
|
||||
fprintf(output, "\n");
|
||||
echoOn(infd);
|
||||
}
|
||||
|
||||
/* stomp on newline */
|
||||
phrase[PORT_Strlen(phrase) - 1] = 0;
|
||||
|
||||
/* Validate password */
|
||||
if (!(*ok)(phrase)) {
|
||||
/* Not weird enough */
|
||||
if (!isTTY)
|
||||
return NULL;
|
||||
fprintf(output, "Password must be at least 8 characters long with one or more\n");
|
||||
fprintf(output, "non-alphabetic characters\n");
|
||||
continue;
|
||||
}
|
||||
return (char *)PORT_Strdup(phrase);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
SEC_CheckPassword(char *cp)
|
||||
{
|
||||
int len;
|
||||
char *end;
|
||||
|
||||
len = PORT_Strlen(cp);
|
||||
if (len < 8) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
end = cp + len;
|
||||
while (cp < end) {
|
||||
unsigned char ch = *cp++;
|
||||
if (!((ch >= 'A') && (ch <= 'Z')) &&
|
||||
!((ch >= 'a') && (ch <= 'z'))) {
|
||||
/* pass phrase has at least one non alphabetic in it */
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
SEC_BlindCheckPassword(char *cp)
|
||||
{
|
||||
if (cp != NULL) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* Get a password from the input terminal, without echoing */
|
||||
|
||||
#if defined(_WINDOWS)
|
||||
static char *
|
||||
quiet_fgets(char *buf, int length, FILE *input)
|
||||
{
|
||||
int c;
|
||||
char *end = buf;
|
||||
|
||||
/* fflush (input); */
|
||||
memset(buf, 0, length);
|
||||
|
||||
if (!isatty(fileno(input))) {
|
||||
return fgets(buf, length, input);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
c = getch(); /* getch gets a character from the console */
|
||||
|
||||
if (c == '\b') {
|
||||
if (end > buf)
|
||||
end--;
|
||||
}
|
||||
|
||||
else if (--length > 0)
|
||||
*end++ = c;
|
||||
|
||||
if (!c || c == '\n' || c == '\r')
|
||||
break;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
#endif
|
||||
3877
security/nss/cmd/lib/secutil.c
Normal file
3877
security/nss/cmd/lib/secutil.c
Normal file
File diff suppressed because it is too large
Load diff
432
security/nss/cmd/lib/secutil.h
Normal file
432
security/nss/cmd/lib/secutil.h
Normal file
|
|
@ -0,0 +1,432 @@
|
|||
/* 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/. */
|
||||
#ifndef _SEC_UTIL_H_
|
||||
#define _SEC_UTIL_H_
|
||||
|
||||
#include "seccomon.h"
|
||||
#include "secitem.h"
|
||||
#include "secport.h"
|
||||
#include "prerror.h"
|
||||
#include "base64.h"
|
||||
#include "key.h"
|
||||
#include "secpkcs7.h"
|
||||
#include "secasn1.h"
|
||||
#include "secder.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "basicutil.h"
|
||||
#include "sslerr.h"
|
||||
#include "sslt.h"
|
||||
|
||||
#define SEC_CT_PRIVATE_KEY "private-key"
|
||||
#define SEC_CT_PUBLIC_KEY "public-key"
|
||||
#define SEC_CT_CERTIFICATE "certificate"
|
||||
#define SEC_CT_CERTIFICATE_REQUEST "certificate-request"
|
||||
#define SEC_CT_CERTIFICATE_ID "certificate-identity"
|
||||
#define SEC_CT_PKCS7 "pkcs7"
|
||||
#define SEC_CT_CRL "crl"
|
||||
#define SEC_CT_NAME "name"
|
||||
|
||||
#define NS_CERTREQ_HEADER "-----BEGIN NEW CERTIFICATE REQUEST-----"
|
||||
#define NS_CERTREQ_TRAILER "-----END NEW CERTIFICATE REQUEST-----"
|
||||
|
||||
#define NS_CERT_HEADER "-----BEGIN CERTIFICATE-----"
|
||||
#define NS_CERT_TRAILER "-----END CERTIFICATE-----"
|
||||
|
||||
#define NS_CRL_HEADER "-----BEGIN CRL-----"
|
||||
#define NS_CRL_TRAILER "-----END CRL-----"
|
||||
|
||||
#define SECU_Strerror PORT_ErrorToString
|
||||
|
||||
typedef struct {
|
||||
enum {
|
||||
PW_NONE = 0,
|
||||
PW_FROMFILE = 1,
|
||||
PW_PLAINTEXT = 2,
|
||||
PW_EXTERNAL = 3
|
||||
} source;
|
||||
char *data;
|
||||
} secuPWData;
|
||||
|
||||
/*
|
||||
** Change a password on a token, or initialize a token with a password
|
||||
** if it does not already have one.
|
||||
** Use passwd to send the password in plaintext, pwFile to specify a
|
||||
** file containing the password, or NULL for both to prompt the user.
|
||||
*/
|
||||
SECStatus SECU_ChangePW(PK11SlotInfo *slot, char *passwd, char *pwFile);
|
||||
|
||||
/*
|
||||
** Change a password on a token, or initialize a token with a password
|
||||
** if it does not already have one.
|
||||
** In this function, you can specify both the old and new passwords
|
||||
** as either a string or file. NOTE: any you don't specify will
|
||||
** be prompted for
|
||||
*/
|
||||
SECStatus SECU_ChangePW2(PK11SlotInfo *slot, char *oldPass, char *newPass,
|
||||
char *oldPwFile, char *newPwFile);
|
||||
|
||||
/* These were stolen from the old sec.h... */
|
||||
/*
|
||||
** Check a password for legitimacy. Passwords must be at least 8
|
||||
** characters long and contain one non-alphabetic. Return DSTrue if the
|
||||
** password is ok, DSFalse otherwise.
|
||||
*/
|
||||
extern PRBool SEC_CheckPassword(char *password);
|
||||
|
||||
/*
|
||||
** Blind check of a password. Complement to SEC_CheckPassword which
|
||||
** ignores length and content type, just retuning DSTrue is the password
|
||||
** exists, DSFalse if NULL
|
||||
*/
|
||||
extern PRBool SEC_BlindCheckPassword(char *password);
|
||||
|
||||
/*
|
||||
** Get a password.
|
||||
** First prompt with "msg" on "out", then read the password from "in".
|
||||
** The password is then checked using "chkpw".
|
||||
*/
|
||||
extern char *SEC_GetPassword(FILE *in, FILE *out, char *msg,
|
||||
PRBool (*chkpw)(char *));
|
||||
|
||||
char *SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg);
|
||||
|
||||
char *SECU_GetPasswordString(void *arg, char *prompt);
|
||||
|
||||
/*
|
||||
** Write a dongle password.
|
||||
** Uses MD5 to hash constant system data (hostname, etc.), and then
|
||||
** creates RC4 key to encrypt a password "pw" into a file "fd".
|
||||
*/
|
||||
extern SECStatus SEC_WriteDongleFile(int fd, char *pw);
|
||||
|
||||
/*
|
||||
** Get a dongle password.
|
||||
** Uses MD5 to hash constant system data (hostname, etc.), and then
|
||||
** creates RC4 key to decrypt and return a password from file "fd".
|
||||
*/
|
||||
extern char *SEC_ReadDongleFile(int fd);
|
||||
|
||||
/* End stolen headers */
|
||||
|
||||
/* Just sticks the two strings together with a / if needed */
|
||||
char *SECU_AppendFilenameToDir(char *dir, char *filename);
|
||||
|
||||
/* Returns result of PR_GetEnvSecure("SSL_DIR") or NULL */
|
||||
extern char *SECU_DefaultSSLDir(void);
|
||||
|
||||
/*
|
||||
** Should be called once during initialization to set the default
|
||||
** directory for looking for cert.db, key.db, and cert-nameidx.db files
|
||||
** Removes trailing '/' in 'base'
|
||||
** If 'base' is NULL, defaults to set to .netscape in home directory.
|
||||
*/
|
||||
extern char *SECU_ConfigDirectory(const char *base);
|
||||
|
||||
/*
|
||||
** Basic callback function for SSL_GetClientAuthDataHook
|
||||
*/
|
||||
extern int
|
||||
SECU_GetClientAuthData(void *arg, PRFileDesc *fd,
|
||||
struct CERTDistNamesStr *caNames,
|
||||
struct CERTCertificateStr **pRetCert,
|
||||
struct SECKEYPrivateKeyStr **pRetKey);
|
||||
|
||||
extern PRBool SECU_GetWrapEnabled(void);
|
||||
extern void SECU_EnableWrap(PRBool enable);
|
||||
|
||||
extern PRBool SECU_GetUtf8DisplayEnabled(void);
|
||||
extern void SECU_EnableUtf8Display(PRBool enable);
|
||||
|
||||
/* revalidate the cert and print information about cert verification
|
||||
* failure at time == now */
|
||||
extern void
|
||||
SECU_printCertProblems(FILE *outfile, CERTCertDBHandle *handle,
|
||||
CERTCertificate *cert, PRBool checksig,
|
||||
SECCertificateUsage certUsage, void *pinArg, PRBool verbose);
|
||||
|
||||
/* revalidate the cert and print information about cert verification
|
||||
* failure at specified time */
|
||||
extern void
|
||||
SECU_printCertProblemsOnDate(FILE *outfile, CERTCertDBHandle *handle,
|
||||
CERTCertificate *cert, PRBool checksig, SECCertificateUsage certUsage,
|
||||
void *pinArg, PRBool verbose, PRTime datetime);
|
||||
|
||||
/* print out CERTVerifyLog info. */
|
||||
extern void
|
||||
SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log,
|
||||
PRBool verbose);
|
||||
|
||||
/* Read in a DER from a file, may be ascii */
|
||||
extern SECStatus
|
||||
SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii,
|
||||
PRBool warnOnPrivateKeyInAsciiFile);
|
||||
|
||||
/* Print integer value and hex */
|
||||
extern void SECU_PrintInteger(FILE *out, const SECItem *i, const char *m,
|
||||
int level);
|
||||
|
||||
/* Print ObjectIdentifier symbolically */
|
||||
extern SECOidTag SECU_PrintObjectID(FILE *out, const SECItem *oid,
|
||||
const char *m, int level);
|
||||
|
||||
/* Print AlgorithmIdentifier symbolically */
|
||||
extern void SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m,
|
||||
int level);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
extern void SECU_PrintUTCTime(FILE *out, const SECItem *t, const char *m,
|
||||
int 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.
|
||||
*/
|
||||
extern void SECU_PrintGeneralizedTime(FILE *out, const SECItem *t,
|
||||
const char *m, int level);
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
extern void SECU_PrintTimeChoice(FILE *out, const SECItem *t, const char *m,
|
||||
int level);
|
||||
|
||||
/* callback for listing certs through pkcs11 */
|
||||
extern SECStatus SECU_PrintCertNickname(CERTCertListNode *cert, void *data);
|
||||
|
||||
/* Dump all certificate nicknames in a database */
|
||||
extern SECStatus
|
||||
SECU_PrintCertificateNames(CERTCertDBHandle *handle, PRFileDesc *out,
|
||||
PRBool sortByName, PRBool sortByTrust);
|
||||
|
||||
/* See if nickname already in database. Return 1 true, 0 false, -1 error */
|
||||
int SECU_CheckCertNameExists(CERTCertDBHandle *handle, char *nickname);
|
||||
|
||||
/* Dump contents of cert req */
|
||||
extern int SECU_PrintCertificateRequest(FILE *out, SECItem *der, char *m,
|
||||
int level);
|
||||
|
||||
/* Dump contents of certificate */
|
||||
extern int SECU_PrintCertificate(FILE *out, const SECItem *der, const char *m,
|
||||
int level);
|
||||
|
||||
extern int SECU_PrintCertificateBasicInfo(FILE *out, const SECItem *der, const char *m,
|
||||
int level);
|
||||
|
||||
extern int SECU_PrintDumpDerIssuerAndSerial(FILE *out, SECItem *der, char *m,
|
||||
int level);
|
||||
|
||||
/* Dump contents of a DER certificate name (issuer or subject) */
|
||||
extern int SECU_PrintDERName(FILE *out, SECItem *der, const char *m, int level);
|
||||
|
||||
/* print trust flags on a cert */
|
||||
extern void SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, char *m,
|
||||
int level);
|
||||
|
||||
extern int SECU_PrintSubjectPublicKeyInfo(FILE *out, SECItem *der, char *m,
|
||||
int level);
|
||||
|
||||
#ifdef HAVE_EPV_TEMPLATE
|
||||
/* Dump contents of private key */
|
||||
extern int SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level);
|
||||
#endif
|
||||
|
||||
/* Dump contents of an RSA public key */
|
||||
extern void SECU_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level);
|
||||
|
||||
/* Dump contents of a DSA public key */
|
||||
extern void SECU_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level);
|
||||
|
||||
/* Print the MD5 and SHA1 fingerprints of a cert */
|
||||
extern int SECU_PrintFingerprints(FILE *out, SECItem *derCert, char *m,
|
||||
int level);
|
||||
|
||||
/* Pretty-print any PKCS7 thing */
|
||||
extern int SECU_PrintPKCS7ContentInfo(FILE *out, SECItem *der, char *m,
|
||||
int level);
|
||||
|
||||
/* Init PKCS11 stuff */
|
||||
extern SECStatus SECU_PKCS11Init(PRBool readOnly);
|
||||
|
||||
/* Dump contents of signed data */
|
||||
extern int SECU_PrintSignedData(FILE *out, SECItem *der, const char *m,
|
||||
int level, SECU_PPFunc inner);
|
||||
|
||||
/* Dump contents of signed data, excluding the signature */
|
||||
extern int SECU_PrintSignedContent(FILE *out, SECItem *der, char *m, int level,
|
||||
SECU_PPFunc inner);
|
||||
|
||||
/* Print cert data and its trust flags */
|
||||
extern SECStatus SEC_PrintCertificateAndTrust(CERTCertificate *cert,
|
||||
const char *label,
|
||||
CERTCertTrust *trust);
|
||||
|
||||
extern int SECU_PrintCrl(FILE *out, SECItem *der, char *m, int level);
|
||||
|
||||
extern void
|
||||
SECU_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m, int level);
|
||||
|
||||
extern void SECU_PrintString(FILE *out, const SECItem *si, const char *m,
|
||||
int level);
|
||||
extern void SECU_PrintAny(FILE *out, const SECItem *i, const char *m, int level);
|
||||
|
||||
extern void SECU_PrintPolicy(FILE *out, SECItem *value, char *msg, int level);
|
||||
extern void SECU_PrintPrivKeyUsagePeriodExtension(FILE *out, SECItem *value,
|
||||
char *msg, int level);
|
||||
|
||||
extern void SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions,
|
||||
char *msg, int level);
|
||||
|
||||
extern void SECU_PrintNameQuotesOptional(FILE *out, CERTName *name,
|
||||
const char *msg, int level,
|
||||
PRBool quotes);
|
||||
extern void SECU_PrintName(FILE *out, CERTName *name, const char *msg,
|
||||
int level);
|
||||
extern void SECU_PrintRDN(FILE *out, CERTRDN *rdn, const char *msg, int level);
|
||||
|
||||
#ifdef SECU_GetPassword
|
||||
/* Convert a High public Key to a Low public Key */
|
||||
extern SECKEYLowPublicKey *SECU_ConvHighToLow(SECKEYPublicKey *pubHighKey);
|
||||
#endif
|
||||
|
||||
extern char *SECU_GetModulePassword(PK11SlotInfo *slot, PRBool retry, void *arg);
|
||||
|
||||
extern SECStatus DER_PrettyPrint(FILE *out, const SECItem *it, PRBool raw);
|
||||
|
||||
extern char *SECU_SECModDBName(void);
|
||||
|
||||
/* Fetch and register an oid if it hasn't been done already */
|
||||
extern void SECU_cert_fetchOID(SECOidTag *data, const SECOidData *src);
|
||||
|
||||
extern SECStatus SECU_RegisterDynamicOids(void);
|
||||
|
||||
/* Identifies hash algorithm tag by its string representation. */
|
||||
extern SECOidTag SECU_StringToSignatureAlgTag(const char *alg);
|
||||
|
||||
/* Store CRL in output file or pk11 db. Also
|
||||
* encodes with base64 and exports to file if ascii flag is set
|
||||
* and file is not NULL. */
|
||||
extern SECStatus SECU_StoreCRL(PK11SlotInfo *slot, SECItem *derCrl,
|
||||
PRFileDesc *outFile, PRBool ascii, char *url);
|
||||
|
||||
/*
|
||||
** DER sign a single block of data using private key encryption and the
|
||||
** MD5 hashing algorithm. This routine first computes a digital signature
|
||||
** using SEC_SignData, then wraps it with an CERTSignedData and then der
|
||||
** encodes the result.
|
||||
** "arena" is the memory arena to use to allocate data from
|
||||
** "sd" returned CERTSignedData
|
||||
** "result" the final der encoded data (memory is allocated)
|
||||
** "buf" the input data to sign
|
||||
** "len" the amount of data to sign
|
||||
** "pk" the private key to encrypt with
|
||||
*/
|
||||
extern SECStatus SECU_DerSignDataCRL(PLArenaPool *arena, CERTSignedData *sd,
|
||||
unsigned char *buf, int len,
|
||||
SECKEYPrivateKey *pk, SECOidTag algID);
|
||||
|
||||
typedef enum {
|
||||
noKeyFound = 1,
|
||||
noSignatureMatch = 2,
|
||||
failToEncode = 3,
|
||||
failToSign = 4,
|
||||
noMem = 5
|
||||
} SignAndEncodeFuncExitStat;
|
||||
|
||||
extern SECStatus
|
||||
SECU_SignAndEncodeCRL(CERTCertificate *issuer, CERTSignedCrl *signCrl,
|
||||
SECOidTag hashAlgTag, SignAndEncodeFuncExitStat *resCode);
|
||||
|
||||
extern SECStatus
|
||||
SECU_CopyCRL(PLArenaPool *destArena, CERTCrl *destCrl, CERTCrl *srcCrl);
|
||||
|
||||
/*
|
||||
** Finds the crl Authority Key Id extension. Returns NULL if no such extension
|
||||
** was found.
|
||||
*/
|
||||
CERTAuthKeyID *
|
||||
SECU_FindCRLAuthKeyIDExten(PLArenaPool *arena, CERTSignedCrl *crl);
|
||||
|
||||
/*
|
||||
* Find the issuer of a crl. Cert usage should be checked before signing a crl.
|
||||
*/
|
||||
CERTCertificate *
|
||||
SECU_FindCrlIssuer(CERTCertDBHandle *dbHandle, SECItem *subject,
|
||||
CERTAuthKeyID *id, PRTime validTime);
|
||||
|
||||
/* call back function used in encoding of an extension. Called from
|
||||
* SECU_EncodeAndAddExtensionValue */
|
||||
typedef SECStatus (*EXTEN_EXT_VALUE_ENCODER)(PLArenaPool *extHandleArena,
|
||||
void *value, SECItem *encodedValue);
|
||||
|
||||
/* Encodes and adds extensions to the CRL or CRL entries. */
|
||||
SECStatus
|
||||
SECU_EncodeAndAddExtensionValue(PLArenaPool *arena, void *extHandle,
|
||||
void *value, PRBool criticality, int extenType,
|
||||
EXTEN_EXT_VALUE_ENCODER EncodeValueFn);
|
||||
|
||||
/* Caller ensures that dst is at least item->len*2+1 bytes long */
|
||||
void
|
||||
SECU_SECItemToHex(const SECItem *item, char *dst);
|
||||
|
||||
/* Requires 0x prefix. Case-insensitive. Will do in-place replacement if
|
||||
* successful */
|
||||
SECStatus
|
||||
SECU_SECItemHexStringToBinary(SECItem *srcdest);
|
||||
|
||||
/* Parse a version range string, with "min" and "max" version numbers,
|
||||
* separated by colon (":"), and return the result in vr and v2.
|
||||
*
|
||||
* Both min and max values are optional.
|
||||
* The following syntax is used to specify the enabled protocol versions:
|
||||
* A string with only a max value is expected as ":{max}",
|
||||
* and all implemented versions less than or equal to max will be enabled.
|
||||
* A string with only a min value is expected as "{min}:",
|
||||
* and all implemented versions greater than or equal to min will be enabled.
|
||||
* A string consisting of a colon only means "all versions enabled".
|
||||
*
|
||||
* In order to avoid a link dependency from libsectool to libssl,
|
||||
* the caller must provide the desired default values for the min/max values,
|
||||
* by providing defaultVersionRange (which can be obtained from libssl by
|
||||
* calling SSL_VersionRangeGetSupported).
|
||||
*/
|
||||
SECStatus
|
||||
SECU_ParseSSLVersionRangeString(const char *input,
|
||||
const SSLVersionRange defaultVersionRange,
|
||||
SSLVersionRange *vrange);
|
||||
/*
|
||||
** Read a hex string into a SecItem.
|
||||
*/
|
||||
extern SECItem *SECU_HexString2SECItem(PLArenaPool *arena, SECItem *item,
|
||||
const char *str);
|
||||
|
||||
/*
|
||||
*
|
||||
* Error messaging
|
||||
*
|
||||
*/
|
||||
|
||||
void printflags(char *trusts, unsigned int flags);
|
||||
|
||||
#if !defined(XP_UNIX) && !defined(XP_OS2)
|
||||
extern int ffs(unsigned int i);
|
||||
#endif
|
||||
|
||||
/* Finds certificate by searching it in the DB or by examinig file
|
||||
* in the local directory. */
|
||||
CERTCertificate *
|
||||
SECU_FindCertByNicknameOrFilename(CERTCertDBHandle *handle,
|
||||
char *name, PRBool ascii,
|
||||
void *pwarg);
|
||||
#include "secerr.h"
|
||||
#include "sslerr.h"
|
||||
|
||||
#endif /* _SEC_UTIL_H_ */
|
||||
Loading…
Add table
Add a link
Reference in a new issue