diff options
Diffstat (limited to 'security/nss/cmd/p7verify')
-rw-r--r-- | security/nss/cmd/p7verify/Makefile | 75 | ||||
-rw-r--r-- | security/nss/cmd/p7verify/manifest.mn | 46 | ||||
-rw-r--r-- | security/nss/cmd/p7verify/p7verify.c | 301 |
3 files changed, 422 insertions, 0 deletions
diff --git a/security/nss/cmd/p7verify/Makefile b/security/nss/cmd/p7verify/Makefile new file mode 100644 index 000000000..4e39ffc3f --- /dev/null +++ b/security/nss/cmd/p7verify/Makefile @@ -0,0 +1,75 @@ +#! gmake +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Netscape security libraries. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1994-2000 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License Version 2 or later (the +# "GPL"), in which case the provisions of the GPL are applicable +# instead of those above. If you wish to allow use of your +# version of this file only under the terms of the GPL and not to +# allow others to use your version of this file under the MPL, +# indicate your decision by deleting the provisions above and +# replace them with the notice and other provisions required by +# the GPL. If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +####################################################################### +# (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 ../platlibs.mk + +####################################################################### +# (5) Execute "global" rules. (OPTIONAL) # +####################################################################### + +include $(CORE_DEPTH)/coreconf/rules.mk + +####################################################################### +# (6) Execute "component" rules. (OPTIONAL) # +####################################################################### + + + +####################################################################### +# (7) Execute "local" rules. (OPTIONAL). # +####################################################################### + + +include ../platrules.mk + diff --git a/security/nss/cmd/p7verify/manifest.mn b/security/nss/cmd/p7verify/manifest.mn new file mode 100644 index 000000000..51fd7091d --- /dev/null +++ b/security/nss/cmd/p7verify/manifest.mn @@ -0,0 +1,46 @@ +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Netscape security libraries. +# +# The Initial Developer of the Original Code is Netscape +# Communications Corporation. Portions created by Netscape are +# Copyright (C) 1994-2000 Netscape Communications Corporation. All +# Rights Reserved. +# +# Contributor(s): +# +# Alternatively, the contents of this file may be used under the +# terms of the GNU General Public License Version 2 or later (the +# "GPL"), in which case the provisions of the GPL are applicable +# instead of those above. If you wish to allow use of your +# version of this file only under the terms of the GPL and not to +# allow others to use your version of this file under the MPL, +# indicate your decision by deleting the provisions above and +# replace them with the notice and other provisions required by +# the GPL. If you do not delete the provisions above, a recipient +# may use your version of this file under either the MPL or the +# GPL. +# + +CORE_DEPTH = ../../.. + +MODULE = security + +CSRCS = p7verify.c + +REQUIRES = seccmd dbm + +PROGRAM = p7verify +# PROGRAM = ./$(OBJDIR)/p7verify.exe + +USE_STATIC_LIBS = 1 + diff --git a/security/nss/cmd/p7verify/p7verify.c b/security/nss/cmd/p7verify/p7verify.c new file mode 100644 index 000000000..5677f853b --- /dev/null +++ b/security/nss/cmd/p7verify/p7verify.c @@ -0,0 +1,301 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1994-2000 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License Version 2 or later (the + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your + * version of this file only under the terms of the GPL and not to + * allow others to use your version of this file under the MPL, + * indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by + * the GPL. If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +/* + * p7verify -- A command to do a verification of a *detached* pkcs7 signature. + * + * $Id$ + */ + +#include "nspr.h" +#include "secutil.h" +#include "plgetopt.h" +#include "secpkcs7.h" +#include "cert.h" +#include "certdb.h" +#include "secoid.h" +#include "sechash.h" /* for HASH_GetHashObject() */ +#include "nss.h" + +#if defined(XP_UNIX) +#include <unistd.h> +#endif + +#include <stdio.h> +#include <string.h> + +#if (defined(XP_WIN) && !defined(WIN32)) || (defined(__sun) && !defined(SVR4)) +extern int fread(char *, size_t, size_t, FILE*); +extern int fprintf(FILE *, char *, ...); +#endif + + +static HASH_HashType +AlgorithmToHashType(SECAlgorithmID *digestAlgorithms) +{ + + SECOidTag tag; + + tag = SECOID_GetAlgorithmTag(digestAlgorithms); + + switch (tag) { + case SEC_OID_MD2: + return HASH_AlgMD2; + case SEC_OID_MD5: + return HASH_AlgMD5; + case SEC_OID_SHA1: + return HASH_AlgSHA1; + default: + fprintf(stderr, "should never get here\n"); + return HASH_AlgNULL; + } +} + +static int +DigestFile(unsigned char *digest, unsigned int *len, unsigned int maxLen, + FILE *inFile, HASH_HashType hashType) +{ + int nb; + char ibuf[4096]; + const SECHashObject *hashObj; + void *hashcx; + + hashObj = HASH_GetHashObject(hashType); + + hashcx = (* hashObj->create)(); + if (hashcx == NULL) + return -1; + + (* hashObj->begin)(hashcx); + + for (;;) { + if (feof(inFile)) break; + nb = fread(ibuf, 1, sizeof(ibuf), inFile); + if (nb != sizeof(ibuf)) { + if (nb == 0) { + if (ferror(inFile)) { + PORT_SetError(SEC_ERROR_IO); + (* hashObj->destroy)(hashcx, PR_TRUE); + return -1; + } + /* eof */ + break; + } + } + (* hashObj->update)(hashcx, ibuf, nb); + } + + (* hashObj->end)(hashcx, digest, len, maxLen); + (* hashObj->destroy)(hashcx, PR_TRUE); + + return 0; +} + + +static void +Usage(char *progName) +{ + fprintf(stderr, + "Usage: %s -c content -s signature [-d dbdir] [-u certusage]\n", + progName); + fprintf(stderr, "%-20s content file that was signed\n", + "-c content"); + fprintf(stderr, "%-20s file containing signature for that content\n", + "-s signature"); + fprintf(stderr, + "%-20s Key/Cert database directory (default is ~/.netscape)\n", + "-d dbdir"); + fprintf(stderr, "%-20s Define the type of certificate usage (default is certUsageEmailSigner)\n", + "-u certusage"); + fprintf(stderr, "%-25s 0 - certUsageSSLClient\n", " "); + fprintf(stderr, "%-25s 1 - certUsageSSLServer\n", " "); + fprintf(stderr, "%-25s 2 - certUsageSSLServerWithStepUp\n", " "); + fprintf(stderr, "%-25s 3 - certUsageSSLCA\n", " "); + fprintf(stderr, "%-25s 4 - certUsageEmailSigner\n", " "); + fprintf(stderr, "%-25s 5 - certUsageEmailRecipient\n", " "); + fprintf(stderr, "%-25s 6 - certUsageObjectSigner\n", " "); + fprintf(stderr, "%-25s 7 - certUsageUserCertImport\n", " "); + fprintf(stderr, "%-25s 8 - certUsageVerifyCA\n", " "); + fprintf(stderr, "%-25s 9 - certUsageProtectedObjectSigner\n", " "); + fprintf(stderr, "%-25s 10 - certUsageStatusResponder\n", " "); + fprintf(stderr, "%-25s 11 - certUsageAnyCA\n", " "); + + exit(-1); +} + +static int +HashDecodeAndVerify(FILE *out, FILE *content, PRFileDesc *signature, + SECCertUsage usage, char *progName) +{ + SECItem derdata; + SEC_PKCS7ContentInfo *cinfo; + SEC_PKCS7SignedData *signedData; + HASH_HashType digestType; + SECItem digest; + unsigned char buffer[32]; + + if (SECU_ReadDERFromFile(&derdata, signature, PR_FALSE) != SECSuccess) { + SECU_PrintError(progName, "error reading signature file"); + return -1; + } + + cinfo = SEC_PKCS7DecodeItem(&derdata, NULL, NULL, NULL, NULL, + NULL, NULL, NULL); + if (cinfo == NULL) + return -1; + + if (! SEC_PKCS7ContentIsSigned(cinfo)) { + fprintf (out, "Signature file is pkcs7 data, but not signed.\n"); + return -1; + } + + signedData = cinfo->content.signedData; + + /* assume that there is only one digest algorithm for now */ + digestType = AlgorithmToHashType(signedData->digestAlgorithms[0]); + if (digestType == HASH_AlgNULL) { + fprintf (out, "Invalid hash algorithmID\n"); + return -1; + } + + digest.data = buffer; + if (DigestFile (digest.data, &digest.len, 32, content, digestType)) { + SECU_PrintError (progName, "problem computing message digest"); + return -1; + } + + fprintf(out, "Signature is "); + if (SEC_PKCS7VerifyDetachedSignature (cinfo, usage, &digest, digestType, + PR_FALSE)) + fprintf(out, "valid.\n"); + else + fprintf(out, "invalid (Reason: %s).\n", + SECU_Strerror(PORT_GetError())); + + SEC_PKCS7DestroyContentInfo(cinfo); + return 0; +} + + +int +main(int argc, char **argv) +{ + char *progName; + FILE *contentFile, *outFile; + PRFileDesc *signatureFile; + SECCertUsage certUsage = certUsageEmailSigner; + PLOptState *optstate; + PLOptStatus status; + SECStatus rv; + + progName = strrchr(argv[0], '/'); + progName = progName ? progName+1 : argv[0]; + + contentFile = NULL; + signatureFile = NULL; + outFile = NULL; + + /* + * Parse command line arguments + */ + optstate = PL_CreateOptState(argc, argv, "c:d:o:s:u:"); + while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { + switch (optstate->option) { + case '?': + Usage(progName); + break; + + case 'c': + contentFile = fopen(optstate->value, "r"); + if (!contentFile) { + fprintf(stderr, "%s: unable to open \"%s\" for reading\n", + progName, optstate->value); + return -1; + } + break; + + case 'd': + SECU_ConfigDirectory(optstate->value); + break; + + case 'o': + outFile = fopen(optstate->value, "w"); + if (!outFile) { + fprintf(stderr, "%s: unable to open \"%s\" for writing\n", + progName, optstate->value); + return -1; + } + break; + + case 's': + signatureFile = PR_Open(optstate->value, PR_RDONLY, 0); + if (!signatureFile) { + fprintf(stderr, "%s: unable to open \"%s\" for reading\n", + progName, optstate->value); + return -1; + } + break; + + case 'u': { + int usageType; + + usageType = atoi (strdup(optstate->value)); + if (usageType < certUsageSSLClient || usageType > certUsageAnyCA) + return -1; + certUsage = (SECCertUsage)usageType; + break; + } + + } + } + + if (!contentFile) Usage (progName); + if (!signatureFile) Usage (progName); + if (!outFile) outFile = stdout; + + /* Call the libsec initialization routines */ + PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); + rv = NSS_Init(SECU_ConfigDirectory(NULL)); + if (rv != SECSuccess) { + SECU_PrintPRandOSError(progName); + return -1; + } + + if (HashDecodeAndVerify(outFile, contentFile, signatureFile, + certUsage, progName)) { + SECU_PrintError(progName, "problem decoding/verifying signature"); + return -1; + } + + return 0; +} |