diff options
author | emaldona%redhat.com <devnull@localhost> | 2012-05-02 04:34:16 +0000 |
---|---|---|
committer | emaldona%redhat.com <devnull@localhost> | 2012-05-02 04:34:16 +0000 |
commit | 016d40229a9bb030c9aad5a68c03f0d40158c174 (patch) | |
tree | a75686fe7ee393c9e43e3f9f0981a6091e9c6894 | |
parent | c1b884865fed30235daef1a6f12014ba5f36f16a (diff) | |
download | nss-hg-016d40229a9bb030c9aad5a68c03f0d40158c174.tar.gz |
Bug 744651 - Refactor secutil into high and low level components, a=emaldonado, r=rrelyea
-rw-r--r-- | security/nss/cmd/bltest/blapitest.c | 2 | ||||
-rw-r--r-- | security/nss/cmd/lib/basicutil.c | 786 | ||||
-rw-r--r-- | security/nss/cmd/lib/basicutil.h | 191 | ||||
-rw-r--r-- | security/nss/cmd/lib/manifest.mn | 6 | ||||
-rw-r--r-- | security/nss/cmd/lib/secutil.c | 764 | ||||
-rw-r--r-- | security/nss/cmd/lib/secutil.h | 64 |
6 files changed, 992 insertions, 821 deletions
diff --git a/security/nss/cmd/bltest/blapitest.c b/security/nss/cmd/bltest/blapitest.c index 43207a9dd..e742feb67 100644 --- a/security/nss/cmd/bltest/blapitest.c +++ b/security/nss/cmd/bltest/blapitest.c @@ -13,7 +13,7 @@ #include "prsystem.h" #include "plstr.h" #include "nssb64.h" -#include "secutil.h" +#include "basicutil.h" #include "plgetopt.h" #include "softoken.h" #include "nspr.h" diff --git a/security/nss/cmd/lib/basicutil.c b/security/nss/cmd/lib/basicutil.c new file mode 100644 index 000000000..bad2c80b2 --- /dev/null +++ b/security/nss/cmd/lib/basicutil.c @@ -0,0 +1,786 @@ +/* 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> +#if !defined(_WIN32_WCE) +#include <sys/stat.h> +#include <errno.h> +#endif + +#ifdef XP_UNIX +#include <unistd.h> +#endif + +#include "secoid.h" + +extern long DER_GetInteger(SECItem *src); + +static PRBool wrapEnabled = PR_TRUE; + +void +SECU_EnableWrap(PRBool enable) +{ + wrapEnabled = enable; +} + +PRBool +SECU_GetWrapEnabled() +{ + return wrapEnabled; +} + +void +SECU_PrintErrMsg(FILE *out, int level, char *progName, 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(char *progName, char *msg, ...) +{ + va_list args; + PRErrorCode err = PORT_GetError(); + const char * errString = PORT_ErrorToString(err); + + va_start(args, msg); + + fprintf(stderr, "%s: ", progName); + vfprintf(stderr, msg, args); + if (errString != NULL && PORT_Strlen(errString) > 0) + fprintf(stderr, ": %s\n", errString); + else + fprintf(stderr, ": error %d\n", (int)err); + + va_end(args); +} + +void +SECU_PrintSystemError(char *progName, char *msg, ...) +{ + va_list args; + + va_start(args, msg); + fprintf(stderr, "%s: ", progName); + vfprintf(stderr, msg, args); +#if defined(_WIN32_WCE) + fprintf(stderr, ": %d\n", PR_GetOSError()); +#else + fprintf(stderr, ": %s\n", strerror(errno)); +#endif + 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, SECItem *data, const char *m, int level) +{ + unsigned i; + int column; + 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, SECItem *i, 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); + } + } +} + +void +SECU_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) +{ + SECU_Indent(out, level); fprintf(out, "%s:\n", m); + SECU_PrintInteger(out, &pk->u.rsa.modulus, "Modulus", level+1); + SECU_PrintInteger(out, &pk->u.rsa.publicExponent, "Exponent", level+1); + if (pk->u.rsa.publicExponent.len == 1 && + pk->u.rsa.publicExponent.data[0] == 1) { + SECU_Indent(out, level +1); fprintf(out, "Error: INVALID RSA KEY!\n"); + } +} + +void +SECU_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) +{ + SECU_Indent(out, level); fprintf(out, "%s:\n", m); + SECU_PrintInteger(out, &pk->u.dsa.params.prime, "Prime", level+1); + SECU_PrintInteger(out, &pk->u.dsa.params.subPrime, "Subprime", level+1); + SECU_PrintInteger(out, &pk->u.dsa.params.base, "Base", level+1); + SECU_PrintInteger(out, &pk->u.dsa.publicValue, "PublicValue", level+1); +} + +#ifdef NSS_ENABLE_ECC +static void +secu_PrintECPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) +{ + SECItem curveOID = { siBuffer, NULL, 0}; + + SECU_Indent(out, level); fprintf(out, "%s:\n", m); + SECU_PrintInteger(out, &pk->u.ec.publicValue, "PublicValue", level+1); + /* For named curves, the DEREncodedParams field contains an + * ASN Object ID (0x06 is SEC_ASN1_OBJECT_ID). + */ + if ((pk->u.ec.DEREncodedParams.len > 2) && + (pk->u.ec.DEREncodedParams.data[0] == 0x06)) { + curveOID.len = pk->u.ec.DEREncodedParams.data[1]; + curveOID.data = pk->u.ec.DEREncodedParams.data + 2; + SECU_PrintObjectID(out, &curveOID, "Curve", level +1); + } +} +#endif /* NSS_ENABLE_ECC */ + +#ifdef NSS_ENABLE_ECC +static void +secu_PrintECPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) +{ + SECItem curveOID = { siBuffer, NULL, 0}; + + SECU_Indent(out, level); fprintf(out, "%s:\n", m); + SECU_PrintInteger(out, &pk->u.ec.publicValue, "PublicValue", level+1); + /* For named curves, the DEREncodedParams field contains an + * ASN Object ID (0x06 is SEC_ASN1_OBJECT_ID). + */ + if ((pk->u.ec.DEREncodedParams.len > 2) && + (pk->u.ec.DEREncodedParams.data[0] == 0x06)) { + curveOID.len = pk->u.ec.DEREncodedParams.data[1]; + curveOID.data = pk->u.ec.DEREncodedParams.data + 2; + SECU_PrintObjectID(out, &curveOID, "Curve", level +1); + } +} +#endif /* NSS_ENABLE_ECC */ + +#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(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) +{ + 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; +} diff --git a/security/nss/cmd/lib/basicutil.h b/security/nss/cmd/lib/basicutil.h new file mode 100644 index 000000000..8a83bfcfc --- /dev/null +++ b/security/nss/cmd/lib/basicutil.h @@ -0,0 +1,191 @@ +/* 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 "key.h" +#include "prerror.h" +#include "base64.h" +#include "key.h" +#include "secpkcs7.h" +#include "secasn1.h" +#include "secder.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(char *progName, char *msg, ...); + +/* print out a system error message */ +extern void SECU_PrintSystemError(char *progName, char *msg, ...); + +/* print a formatted error message */ +extern void SECU_PrintErrMsg(FILE *out, int level, char *progName, 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, SECItem *i, char *m, int level); + +/* Print SECItem as hex */ +extern void SECU_PrintAsHex(FILE *out, 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); + +/* 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); + +#ifdef HAVE_EPV_TEMPLATE +/* Dump contents of private key */ +extern int SECU_PrintPrivateKey(FILE *out, SECItem *der, char *m, int level); +#endif + +/* 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); + +/* 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, SECItem *si, char *m, int level); +extern void SECU_PrintAny(FILE *out, SECItem *i, 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, SECItem *it, PRBool raw); + +extern char *SECU_SECModDBName(void); + +extern void SECU_PrintPRandOSError(char *progName); + +extern SECStatus SECU_RegisterDynamicOids(void); + +/* Identifies hash algorithm tag by its string representation. */ +extern SECOidTag SECU_StringToSignatureAlgTag(const char *alg); + +/* 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); + +/* + * + * 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" + +extern const char *hex; +extern const char printable[]; + +#endif /* _BASIC_UTILS_H_ */ diff --git a/security/nss/cmd/lib/manifest.mn b/security/nss/cmd/lib/manifest.mn index ce7c9eabe..4a971954a 100644 --- a/security/nss/cmd/lib/manifest.mn +++ b/security/nss/cmd/lib/manifest.mn @@ -11,11 +11,13 @@ MODULE = nss DEFINES = -DNSPR20 -PRIVATE_EXPORTS = secutil.h \ +PRIVATE_EXPORTS = basicutil.h \ + secutil.h \ pk11table.h \ $(NULL) -CSRCS = secutil.c \ +CSRCS = basicutil.c \ + secutil.c \ secpwd.c \ derprint.c \ moreoids.c \ diff --git a/security/nss/cmd/lib/secutil.c b/security/nss/cmd/lib/secutil.c index 5b01942a8..0bd514bb0 100644 --- a/security/nss/cmd/lib/secutil.c +++ b/security/nss/cmd/lib/secutil.c @@ -55,72 +55,6 @@ static char consoleName[] = { static PRBool wrapEnabled = PR_TRUE; -void -SECU_EnableWrap(PRBool enable) -{ - wrapEnabled = enable; -} - -PRBool -SECU_GetWrapEnabled() -{ - return wrapEnabled; -} - -void -SECU_PrintErrMsg(FILE *out, int level, char *progName, char *msg, ...) -{ - va_list args; - PRErrorCode err = PORT_GetError(); - const char * errString = SECU_Strerror(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(char *progName, char *msg, ...) -{ - va_list args; - PRErrorCode err = PORT_GetError(); - const char * errString = SECU_Strerror(err); - - va_start(args, msg); - - fprintf(stderr, "%s: ", progName); - vfprintf(stderr, msg, args); - if (errString != NULL && PORT_Strlen(errString) > 0) - fprintf(stderr, ": %s\n", errString); - else - fprintf(stderr, ": error %d\n", (int)err); - - va_end(args); -} - -void -SECU_PrintSystemError(char *progName, char *msg, ...) -{ - va_list args; - - va_start(args, msg); - fprintf(stderr, "%s: ", progName); - vfprintf(stderr, msg, args); -#if defined(_WIN32_WCE) - fprintf(stderr, ": %d\n", PR_GetOSError()); -#else - fprintf(stderr, ": %s\n", strerror(errno)); -#endif - va_end(args); -} static void secu_ClearPassword(char *p) @@ -563,127 +497,6 @@ SECU_GetClientAuthData(void *arg, PRFileDesc *fd, } 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; -} - -SECStatus SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii) { SECStatus rv; @@ -743,161 +556,6 @@ SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii) } #define INDENT_MULT 4 -void -SECU_Indent(FILE *out, int level) -{ - int i; - - for (i = 0; i < level; i++) { - fprintf(out, " "); - } -} - -static void secu_Newline(FILE *out) -{ - fprintf(out, "\n"); -} - -void -SECU_PrintAsHex(FILE *out, SECItem *data, const char *m, int level) -{ - unsigned i; - int column; - 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); - } -} - -static const char *hex = "0123456789abcdef"; - -static 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); - } -} SECStatus SECU_StripTagAndLength(SECItem *i) @@ -917,47 +575,6 @@ SECU_StripTagAndLength(SECItem *i) } -/* 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, SECItem *i, 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); - } - } -} static void secu_PrintRawStringQuotesOptional(FILE *out, SECItem *si, const char *m, @@ -981,7 +598,7 @@ secu_PrintRawStringQuotesOptional(FILE *out, SECItem *si, const char *m, for (i = 0; i < si->len; i++) { unsigned char val = si->data[i]; if (wrapEnabled && column > 76) { - secu_Newline(out); + SECU_Newline(out); SECU_Indent(out, level); column = level*INDENT_MULT; } @@ -993,7 +610,7 @@ secu_PrintRawStringQuotesOptional(FILE *out, SECItem *si, const char *m, } if (wrapEnabled && (column != level*INDENT_MULT || column > 76)) { - secu_Newline(out); + SECU_Newline(out); } } @@ -1736,49 +1353,6 @@ secu_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m, int level) } static void -secu_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) -{ - - SECU_Indent(out, level); fprintf(out, "%s:\n", m); - SECU_PrintInteger(out, &pk->u.rsa.modulus, "Modulus", level+1); - SECU_PrintInteger(out, &pk->u.rsa.publicExponent, "Exponent", level+1); - if (pk->u.rsa.publicExponent.len == 1 && - pk->u.rsa.publicExponent.data[0] == 1) { - SECU_Indent(out, level +1); fprintf(out, "Error: INVALID RSA KEY!\n"); - } -} - -static void -secu_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) -{ - SECU_Indent(out, level); fprintf(out, "%s:\n", m); - SECU_PrintInteger(out, &pk->u.dsa.params.prime, "Prime", level+1); - SECU_PrintInteger(out, &pk->u.dsa.params.subPrime, "Subprime", level+1); - SECU_PrintInteger(out, &pk->u.dsa.params.base, "Base", level+1); - SECU_PrintInteger(out, &pk->u.dsa.publicValue, "PublicValue", level+1); -} - -#ifdef NSS_ENABLE_ECC -static void -secu_PrintECPublicKey(FILE *out, SECKEYPublicKey *pk, char *m, int level) -{ - SECItem curveOID = { siBuffer, NULL, 0}; - - SECU_Indent(out, level); fprintf(out, "%s:\n", m); - SECU_PrintInteger(out, &pk->u.ec.publicValue, "PublicValue", level+1); - /* For named curves, the DEREncodedParams field contains an - * ASN Object ID (0x06 is SEC_ASN1_OBJECT_ID). - */ - if ((pk->u.ec.DEREncodedParams.len > 2) && - (pk->u.ec.DEREncodedParams.data[0] == 0x06)) { - curveOID.len = pk->u.ec.DEREncodedParams.data[1]; - curveOID.data = pk->u.ec.DEREncodedParams.data + 2; - SECU_PrintObjectID(out, &curveOID, "Curve", level +1); - } -} -#endif /* NSS_ENABLE_ECC */ - -static void secu_PrintSubjectPublicKeyInfo(FILE *out, PRArenaPool *arena, CERTSubjectPublicKeyInfo *i, char *msg, int level) { @@ -1791,11 +1365,11 @@ secu_PrintSubjectPublicKeyInfo(FILE *out, PRArenaPool *arena, if (pk) { switch (pk->keyType) { case rsaKey: - secu_PrintRSAPublicKey(out, pk, "RSA Public Key", level +1); + SECU_PrintRSAPublicKey(out, pk, "RSA Public Key", level +1); break; case dsaKey: - secu_PrintDSAPublicKey(out, pk, "DSA Public Key", level +1); + SECU_PrintDSAPublicKey(out, pk, "DSA Public Key", level +1); break; #ifdef NSS_ENABLE_ECC @@ -2383,7 +1957,7 @@ SECU_PrintExtensions(FILE *out, CERTCertExtension **extensions, break; } - secu_Newline(out); + SECU_Newline(out); extensions++; } } @@ -2432,7 +2006,7 @@ SECU_PrintNameQuotesOptional(FILE *out, CERTName *name, const char *msg, #else SECU_Indent(out, level); fprintf(out, "%s: ", msg); fprintf(out, str); - secu_Newline(out); + SECU_Newline(out); #endif PORT_Free(nameStr); } @@ -2667,28 +2241,6 @@ loser: } int -SECU_PrintRSAPublicKey(FILE *out, SECItem *der, char *m, int level) -{ - PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); - SECKEYPublicKey key; - int rv = SEC_ERROR_NO_MEMORY; - - if (!arena) - return rv; - - PORT_Memset(&key, 0, sizeof(key)); - rv = SEC_ASN1DecodeItem(arena, &key, - SEC_ASN1_GET(SECKEY_RSAPublicKeyTemplate), der); - if (!rv) { - /* Pretty print it out */ - secu_PrintRSAPublicKey(out, &key, m, level); - } - - PORT_FreeArena(arena, PR_FALSE); - return rv; -} - -int SECU_PrintSubjectPublicKeyInfo(FILE *out, SECItem *der, char *m, int level) { PRArenaPool *arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); @@ -3416,219 +2968,6 @@ SEC_PrintCertificateAndTrust(CERTCertificate *cert, return(SECSuccess); } -#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(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); - } -} - static char * bestCertName(CERTCertificate *cert) { @@ -3768,34 +3107,6 @@ SECU_printCertProblems(FILE *outfile, CERTCertDBHandle *handle, certUsage, pinArg, verbose, PR_Now()); } -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; -} - - SECStatus SECU_StoreCRL(PK11SlotInfo *slot, SECItem *derCrl, PRFileDesc *outFile, PRBool ascii, char *url) @@ -4088,69 +3399,6 @@ SECU_EncodeAndAddExtensionValue(PRArenaPool *arena, void *extHandle, return (rv); } -/* 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) -{ - 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; -} - CERTCertificate* SECU_FindCertByNicknameOrFilename(CERTCertDBHandle *handle, char *name, PRBool ascii, diff --git a/security/nss/cmd/lib/secutil.h b/security/nss/cmd/lib/secutil.h index 5755bccb2..16c4aba88 100644 --- a/security/nss/cmd/lib/secutil.h +++ b/security/nss/cmd/lib/secutil.h @@ -15,6 +15,10 @@ #include "secder.h" #include <stdio.h> +#include "basicutil.h" +#include "sslerr.h" + + #define SEC_CT_PRIVATE_KEY "private-key" #define SEC_CT_PUBLIC_KEY "public-key" #define SEC_CT_CERTIFICATE "certificate" @@ -34,12 +38,6 @@ #define SECU_Strerror PORT_ErrorToString -#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 typedef struct { enum { @@ -139,12 +137,6 @@ SECU_GetClientAuthData(void *arg, PRFileDesc *fd, extern PRBool SECU_GetWrapEnabled(); extern void SECU_EnableWrap(PRBool enable); -/* print out an error message */ -extern void SECU_PrintError(char *progName, char *msg, ...); - -/* print out a system error message */ -extern void SECU_PrintSystemError(char *progName, char *msg, ...); - /* revalidate the cert and print information about cert verification * failure at time == now */ extern void @@ -164,17 +156,10 @@ extern void SECU_displayVerifyLog(FILE *outfile, CERTVerifyLog *log, PRBool verbose); -/* 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); - /* Read in a DER from a file, may be ascii */ extern SECStatus SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii); -/* Indent based on "level" */ -extern void SECU_Indent(FILE *out, int level); - /* Print integer value and hex */ extern void SECU_PrintInteger(FILE *out, SECItem *i, char *m, int level); @@ -185,12 +170,6 @@ extern SECOidTag SECU_PrintObjectID(FILE *out, SECItem *oid, char *m, int level) extern void SECU_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m, int level); -/* Print SECItem as hex */ -extern void SECU_PrintAsHex(FILE *out, 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); - /* * 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; @@ -238,9 +217,6 @@ extern int SECU_PrintDERName(FILE *out, SECItem *der, const char *m, int level); extern void SECU_PrintTrustFlags(FILE *out, CERTCertTrust *trust, char *m, int level); -/* Dump contents of an RSA public key */ -extern int SECU_PrintRSAPublicKey(FILE *out, SECItem *der, char *m, int level); - extern int SECU_PrintSubjectPublicKeyInfo(FILE *out, SECItem *der, char *m, int level); @@ -384,38 +360,6 @@ 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); - -/* - * * Error messaging * */ |