Initial checkin of signver source.
git-svn-id: svn://10.0.0.236/trunk@65044 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
4d745519cb
commit
e5fda9b634
70
mozilla/security/nss/cmd/signver/Makefile
Normal file
70
mozilla/security/nss/cmd/signver/Makefile
Normal file
@ -0,0 +1,70 @@
|
||||
#! 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 $(CORE_DEPTH)/security/cmd/platlibs.mk
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
52
mozilla/security/nss/cmd/signver/manifest.mn
Normal file
52
mozilla/security/nss/cmd/signver/manifest.mn
Normal file
@ -0,0 +1,52 @@
|
||||
# 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 = signver.c \
|
||||
pk7print.c \
|
||||
$(NULL)
|
||||
|
||||
REQUIRES = security dbm seccmd
|
||||
|
||||
PROGRAM = signver
|
||||
|
||||
PACKAGE_FILES = README.txt signedForm.html signedForm.pl form.pl
|
||||
ifeq ($(subst /,_,$(shell uname -s)),WINNT)
|
||||
PACKAGE_FILES += signedForm.nt.pl signver.exe
|
||||
else
|
||||
PACKAGE_FILES += signver
|
||||
endif
|
||||
|
||||
ARCHIVE_NAME = signver
|
||||
918
mozilla/security/nss/cmd/signver/pk7print.c
Normal file
918
mozilla/security/nss/cmd/signver/pk7print.c
Normal file
@ -0,0 +1,918 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
** secutil.c - various functions used by security stuff
|
||||
**
|
||||
*/
|
||||
|
||||
/* pkcs #7 -related functions */
|
||||
|
||||
|
||||
#include "secutil.h"
|
||||
#include "secpkcs7.h"
|
||||
#include "secoid.h"
|
||||
#include <sys/stat.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* for SEC_TraverseNames */
|
||||
#include "cert.h"
|
||||
#include "prtypes.h"
|
||||
#include "prtime.h"
|
||||
|
||||
#include "prlong.h"
|
||||
#include "secmod.h"
|
||||
#include "pk11func.h"
|
||||
#include "prerror.h"
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** PKCS7 Support
|
||||
*/
|
||||
|
||||
/* forward declaration */
|
||||
int
|
||||
sv_PrintPKCS7ContentInfo(FILE *, SEC_PKCS7ContentInfo *, char *);
|
||||
|
||||
|
||||
void
|
||||
sv_PrintAsHex(FILE *out, SECItem *data, char *m)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (m) fprintf(out, m);
|
||||
|
||||
for (i = 0; i < data->len; i++) {
|
||||
if (i < data->len - 1) {
|
||||
fprintf(out, "%02x:", data->data[i]);
|
||||
} else {
|
||||
fprintf(out, "%02x\n", data->data[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sv_PrintInteger(FILE *out, SECItem *i, char *m)
|
||||
{
|
||||
int iv;
|
||||
|
||||
if (i->len > 4) {
|
||||
sv_PrintAsHex(out, i, m);
|
||||
} else {
|
||||
iv = DER_GetInteger(i);
|
||||
fprintf(out, "%s%d (0x%x)\n", m, iv, iv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sv_PrintUTCTime(FILE *out, SECItem *t, char *m)
|
||||
{
|
||||
PRExplodedTime printableTime;
|
||||
int64 time;
|
||||
char *timeString;
|
||||
int rv;
|
||||
|
||||
rv = DER_UTCTimeToTime(&time, t);
|
||||
if (rv) return rv;
|
||||
|
||||
/* Converse to local time */
|
||||
PR_ExplodeTime(time, PR_GMTParameters, &printableTime);
|
||||
|
||||
timeString = (char *)PORT_Alloc(100);
|
||||
|
||||
if ( timeString ) {
|
||||
PR_FormatTime( timeString, 100, "%a %b %d %H:%M:%S %Y", &printableTime );
|
||||
fprintf(out, "%s%s\n", m, timeString);
|
||||
PORT_Free(timeString);
|
||||
return 0;
|
||||
}
|
||||
return SECFailure;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sv_PrintValidity(FILE *out, CERTValidity *v, char *m)
|
||||
{
|
||||
int rv;
|
||||
|
||||
fprintf(out, m);
|
||||
rv = sv_PrintUTCTime(out, &v->notBefore, "notBefore=");
|
||||
if (rv) return rv;
|
||||
fprintf(out, m);
|
||||
sv_PrintUTCTime(out, &v->notAfter, "notAfter=");
|
||||
return rv;
|
||||
}
|
||||
|
||||
void
|
||||
sv_PrintObjectID(FILE *out, SECItem *oid, char *m)
|
||||
{
|
||||
char *name;
|
||||
SECOidData *oiddata;
|
||||
|
||||
oiddata = SECOID_FindOID(oid);
|
||||
if (oiddata == NULL) {
|
||||
sv_PrintAsHex(out, oid, m);
|
||||
return;
|
||||
}
|
||||
name = oiddata->desc;
|
||||
|
||||
if (m != NULL)
|
||||
fprintf(out, "%s", m);
|
||||
fprintf(out, "%s\n", name);
|
||||
}
|
||||
|
||||
void
|
||||
sv_PrintAlgorithmID(FILE *out, SECAlgorithmID *a, char *m)
|
||||
{
|
||||
sv_PrintObjectID(out, &a->algorithm, m);
|
||||
|
||||
if ((a->parameters.len != 2) ||
|
||||
(PORT_Memcmp(a->parameters.data, "\005\000", 2) != 0)) {
|
||||
/* Print args to algorithm */
|
||||
sv_PrintAsHex(out, &a->parameters, "Args=");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sv_PrintAttribute(FILE *out, SEC_PKCS7Attribute *attr, char *m)
|
||||
{
|
||||
SECItem *value;
|
||||
int i;
|
||||
char om[100];
|
||||
|
||||
fprintf(out, m);
|
||||
|
||||
/*
|
||||
* XXX Make this smarter; look at the type field and then decode
|
||||
* and print the value(s) appropriately!
|
||||
*/
|
||||
sv_PrintObjectID(out, &(attr->type), "type=");
|
||||
if (attr->values != NULL) {
|
||||
i = 0;
|
||||
while ((value = attr->values[i]) != NULL) {
|
||||
sprintf(om, "%svalue[%d]=%s", m, i++, attr->encoded ? "(encoded)" : "");
|
||||
if (attr->encoded || attr->typeTag == NULL) {
|
||||
sv_PrintAsHex(out, value, om);
|
||||
} else {
|
||||
switch (attr->typeTag->offset) {
|
||||
default:
|
||||
sv_PrintAsHex(out, value, om);
|
||||
break;
|
||||
case SEC_OID_PKCS9_CONTENT_TYPE:
|
||||
sv_PrintObjectID(out, value, om);
|
||||
break;
|
||||
case SEC_OID_PKCS9_SIGNING_TIME:
|
||||
sv_PrintUTCTime(out, value, om);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sv_PrintName(FILE *out, CERTName *name, char *msg)
|
||||
{
|
||||
char *str;
|
||||
|
||||
str = CERT_NameToAscii(name);
|
||||
fprintf(out, "%s%s\n", msg, str);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/*
|
||||
** secu_PrintPKCS7EncContent
|
||||
** Prints a SEC_PKCS7EncryptedContentInfo (without decrypting it)
|
||||
*/
|
||||
void
|
||||
secu_PrintPKCS7EncContent(FILE *out, SEC_PKCS7EncryptedContentInfo *src,
|
||||
char *m, int level)
|
||||
{
|
||||
if (src->contentTypeTag == NULL)
|
||||
src->contentTypeTag = SECOID_FindOID(&(src->contentType));
|
||||
|
||||
secu_Indent(out, level);
|
||||
fprintf(out, "%s:\n", m);
|
||||
secu_Indent(out, level + 1);
|
||||
fprintf(out, "Content Type: %s\n",
|
||||
(src->contentTypeTag != NULL) ? src->contentTypeTag->desc
|
||||
: "Unknown");
|
||||
sv_PrintAlgorithmID(out, &(src->contentEncAlg),
|
||||
"Content Encryption Algorithm");
|
||||
sv_PrintAsHex(out, &(src->encContent),
|
||||
"Encrypted Content", level+1);
|
||||
}
|
||||
|
||||
/*
|
||||
** secu_PrintRecipientInfo
|
||||
** Prints a PKCS7RecipientInfo type
|
||||
*/
|
||||
void
|
||||
secu_PrintRecipientInfo(FILE *out, SEC_PKCS7RecipientInfo *info, char *m,
|
||||
int level)
|
||||
{
|
||||
secu_Indent(out, level); fprintf(out, "%s:\n", m);
|
||||
sv_PrintInteger(out, &(info->version), "Version");
|
||||
|
||||
sv_PrintName(out, &(info->issuerAndSN->issuer), "Issuer");
|
||||
sv_PrintInteger(out, &(info->issuerAndSN->serialNumber),
|
||||
"Serial Number");
|
||||
|
||||
/* Parse and display encrypted key */
|
||||
sv_PrintAlgorithmID(out, &(info->keyEncAlg),
|
||||
"Key Encryption Algorithm");
|
||||
sv_PrintAsHex(out, &(info->encKey), "Encrypted Key", level + 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
** secu_PrintSignerInfo
|
||||
** Prints a PKCS7SingerInfo type
|
||||
*/
|
||||
void
|
||||
sv_PrintSignerInfo(FILE *out, SEC_PKCS7SignerInfo *info, char *m)
|
||||
{
|
||||
SEC_PKCS7Attribute *attr;
|
||||
int iv;
|
||||
|
||||
fprintf(out, m);
|
||||
sv_PrintInteger(out, &(info->version), "version=");
|
||||
|
||||
fprintf(out, m);
|
||||
sv_PrintName(out, &(info->issuerAndSN->issuer), "issuerName=");
|
||||
fprintf(out, m);
|
||||
sv_PrintInteger(out, &(info->issuerAndSN->serialNumber),
|
||||
"serialNumber=");
|
||||
|
||||
fprintf(out, m);
|
||||
sv_PrintAlgorithmID(out, &(info->digestAlg), "digestAlgorithm=");
|
||||
|
||||
if (info->authAttr != NULL) {
|
||||
char mm[120];
|
||||
|
||||
iv = 0;
|
||||
while (info->authAttr[iv] != NULL) iv++;
|
||||
fprintf(out, "%sauthenticatedAttributes=%d\n", m, iv);
|
||||
iv = 0;
|
||||
while ((attr = info->authAttr[iv]) != NULL) {
|
||||
sprintf(mm, "%sattribute[%d].", m, iv++);
|
||||
sv_PrintAttribute(out, attr, mm);
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse and display signature */
|
||||
fprintf(out, m);
|
||||
sv_PrintAlgorithmID(out, &(info->digestEncAlg), "digestEncryptionAlgorithm=");
|
||||
fprintf(out, m);
|
||||
sv_PrintAsHex(out, &(info->encDigest), "encryptedDigest=");
|
||||
|
||||
if (info->unAuthAttr != NULL) {
|
||||
char mm[120];
|
||||
|
||||
iv = 0;
|
||||
while (info->unAuthAttr[iv] != NULL) iv++;
|
||||
fprintf(out, "%sunauthenticatedAttributes=%d\n", m, iv);
|
||||
iv = 0;
|
||||
while ((attr = info->unAuthAttr[iv]) != NULL) {
|
||||
sprintf(mm, "%sattribute[%d].", m, iv++);
|
||||
sv_PrintAttribute(out, attr, mm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sv_PrintRSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m)
|
||||
{
|
||||
fprintf(out, m);
|
||||
sv_PrintInteger(out, &pk->u.rsa.modulus, "modulus=");
|
||||
fprintf(out, m);
|
||||
sv_PrintInteger(out, &pk->u.rsa.publicExponent, "exponent=");
|
||||
}
|
||||
|
||||
void
|
||||
sv_PrintDSAPublicKey(FILE *out, SECKEYPublicKey *pk, char *m)
|
||||
{
|
||||
fprintf(out, m);
|
||||
sv_PrintInteger(out, &pk->u.dsa.params.prime, "prime=");
|
||||
fprintf(out, m);
|
||||
sv_PrintInteger(out, &pk->u.dsa.params.subPrime, "subprime=");
|
||||
fprintf(out, m);
|
||||
sv_PrintInteger(out, &pk->u.dsa.params.base, "base=");
|
||||
fprintf(out, m);
|
||||
sv_PrintInteger(out, &pk->u.dsa.publicValue, "publicValue=");
|
||||
}
|
||||
|
||||
int
|
||||
sv_PrintSubjectPublicKeyInfo(FILE *out, PRArenaPool *arena,
|
||||
CERTSubjectPublicKeyInfo *i, char *msg)
|
||||
{
|
||||
SECKEYPublicKey *pk;
|
||||
int rv;
|
||||
char mm[200];
|
||||
|
||||
sprintf(mm, "%s.publicKeyAlgorithm=", msg);
|
||||
sv_PrintAlgorithmID(out, &i->algorithm, mm);
|
||||
|
||||
pk = (SECKEYPublicKey*) PORT_ZAlloc(sizeof(SECKEYPublicKey));
|
||||
if (!pk) return PORT_GetError();
|
||||
|
||||
DER_ConvertBitString(&i->subjectPublicKey);
|
||||
switch(SECOID_FindOIDTag(&i->algorithm.algorithm)) {
|
||||
case SEC_OID_PKCS1_RSA_ENCRYPTION:
|
||||
rv = SEC_ASN1DecodeItem(arena, pk, SECKEY_RSAPublicKeyTemplate,
|
||||
&i->subjectPublicKey);
|
||||
if (rv) return rv;
|
||||
sprintf(mm, "%s.rsaPublicKey.", msg);
|
||||
sv_PrintRSAPublicKey(out, pk, mm);
|
||||
break;
|
||||
case SEC_OID_ANSIX9_DSA_SIGNATURE:
|
||||
rv = SEC_ASN1DecodeItem(arena, pk, SECKEY_DSAPublicKeyTemplate,
|
||||
&i->subjectPublicKey);
|
||||
if (rv) return rv;
|
||||
sprintf(mm, "%s.dsaPublicKey.", msg);
|
||||
sv_PrintDSAPublicKey(out, pk, mm);
|
||||
break;
|
||||
default:
|
||||
fprintf(out, "%s=bad SPKI algorithm type\n", msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
sv_PrintInvalidDateExten (FILE *out, SECItem *value, char *msg)
|
||||
{
|
||||
SECItem decodedValue;
|
||||
SECStatus rv;
|
||||
int64 invalidTime;
|
||||
char *formattedTime = NULL;
|
||||
|
||||
decodedValue.data = NULL;
|
||||
rv = SEC_ASN1DecodeItem (NULL, &decodedValue, SEC_GeneralizedTimeTemplate,
|
||||
value);
|
||||
if (rv == SECSuccess) {
|
||||
rv = DER_GeneralizedTimeToTime(&invalidTime, &decodedValue);
|
||||
if (rv == SECSuccess) {
|
||||
formattedTime = CERT_GenTime2FormattedAscii(invalidTime, "%a %b %d %H:%M:%S %Y");
|
||||
fprintf (out, "%s: %s\n", msg, formattedTime);
|
||||
PORT_Free (formattedTime);
|
||||
}
|
||||
}
|
||||
PORT_Free (decodedValue.data);
|
||||
|
||||
return (rv);
|
||||
}
|
||||
|
||||
int
|
||||
sv_PrintExtensions(FILE *out, CERTCertExtension **extensions, char *msg)
|
||||
{
|
||||
SECOidTag oidTag;
|
||||
|
||||
if (extensions) {
|
||||
|
||||
while ( *extensions ) {
|
||||
SECItem *tmpitem;
|
||||
|
||||
fprintf(out, "%sname=", msg);
|
||||
|
||||
tmpitem = &(*extensions)->id;
|
||||
sv_PrintObjectID(out, tmpitem, NULL);
|
||||
|
||||
tmpitem = &(*extensions)->critical;
|
||||
if ( tmpitem->len )
|
||||
fprintf(out, "%scritical=%s\n", msg,
|
||||
(tmpitem->data && tmpitem->data[0])? "True": "False");
|
||||
|
||||
oidTag = SECOID_FindOIDTag (&((*extensions)->id));
|
||||
|
||||
fprintf(out, msg);
|
||||
tmpitem = &((*extensions)->value);
|
||||
if (oidTag == SEC_OID_X509_INVALID_DATE)
|
||||
sv_PrintInvalidDateExten (out, tmpitem,"invalidExt");
|
||||
else
|
||||
sv_PrintAsHex(out,tmpitem, "data=");
|
||||
|
||||
/*fprintf(out, "\n");*/
|
||||
extensions++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
sv_PrintCRLInfo(FILE *out, CERTCrl *crl, char *m)
|
||||
{
|
||||
CERTCrlEntry *entry;
|
||||
int iv;
|
||||
char om[100];
|
||||
|
||||
fprintf(out, m);
|
||||
sv_PrintAlgorithmID(out, &(crl->signatureAlg), "signatureAlgorithm=");
|
||||
fprintf(out, m);
|
||||
sv_PrintName(out, &(crl->name), "name=");
|
||||
fprintf(out, m);
|
||||
sv_PrintUTCTime(out, &(crl->lastUpdate), "lastUpdate=");
|
||||
fprintf(out, m);
|
||||
sv_PrintUTCTime(out, &(crl->nextUpdate), "nextUpdate=");
|
||||
|
||||
if (crl->entries != NULL) {
|
||||
iv = 0;
|
||||
while ((entry = crl->entries[iv]) != NULL) {
|
||||
fprintf(out, "%sentry[%d].", m, iv);
|
||||
sv_PrintInteger(out, &(entry->serialNumber), "serialNumber=");
|
||||
fprintf(out, "%sentry[%d].", m, iv);
|
||||
sv_PrintUTCTime(out, &(entry->revocationDate), "revocationDate=");
|
||||
sprintf(om, "%sentry[%d].signedCRLEntriesExtensions.", m, iv++);
|
||||
sv_PrintExtensions(out, entry->extensions, om);
|
||||
}
|
||||
}
|
||||
sprintf(om, "%ssignedCRLEntriesExtensions.", m);
|
||||
sv_PrintExtensions(out, crl->extensions, om);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sv_PrintCertificate(FILE *out, SECItem *der, char *m, int level)
|
||||
{
|
||||
PRArenaPool *arena = NULL;
|
||||
CERTCertificate *c;
|
||||
int rv;
|
||||
int iv;
|
||||
char mm[200];
|
||||
|
||||
/* Decode certificate */
|
||||
c = (CERTCertificate*) PORT_ZAlloc(sizeof(CERTCertificate));
|
||||
if (!c) return PORT_GetError();
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!arena) return SEC_ERROR_NO_MEMORY;
|
||||
|
||||
rv = SEC_ASN1DecodeItem(arena, c, CERT_CertificateTemplate, der);
|
||||
if (rv) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Pretty print it out */
|
||||
iv = DER_GetInteger(&c->version);
|
||||
fprintf(out, "%sversion=%d (0x%x)\n", m, iv + 1, iv);
|
||||
sprintf(mm, "%sserialNumber=", m);
|
||||
sv_PrintInteger(out, &c->serialNumber, mm);
|
||||
sprintf(mm, "%ssignatureAlgorithm=", m);
|
||||
sv_PrintAlgorithmID(out, &c->signature, mm);
|
||||
sprintf(mm, "%sissuerName=", m);
|
||||
sv_PrintName(out, &c->issuer, mm);
|
||||
sprintf(mm, "%svalidity.", m);
|
||||
sv_PrintValidity(out, &c->validity, mm);
|
||||
sprintf(mm, "%ssubject=", m);
|
||||
sv_PrintName(out, &c->subject, mm);
|
||||
sprintf(mm, "%ssubjectPublicKeyInfo", m);
|
||||
rv = sv_PrintSubjectPublicKeyInfo(out, arena, &c->subjectPublicKeyInfo, mm);
|
||||
if (rv) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
sprintf(mm, "%ssignedExtensions.", m);
|
||||
sv_PrintExtensions(out, c->extensions, mm);
|
||||
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
sv_PrintSignedData(FILE *out, SECItem *der, char *m, SECU_PPFunc inner)
|
||||
{
|
||||
PRArenaPool *arena = NULL;
|
||||
CERTSignedData *sd;
|
||||
int rv;
|
||||
|
||||
/* Strip off the signature */
|
||||
sd = (CERTSignedData*) PORT_ZAlloc(sizeof(CERTSignedData));
|
||||
if (!sd) return PORT_GetError();
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!arena) return SEC_ERROR_NO_MEMORY;
|
||||
|
||||
rv = SEC_ASN1DecodeItem(arena, sd, CERT_SignedDataTemplate, der);
|
||||
if (rv) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* fprintf(out, "%s:\n", m); */
|
||||
PORT_Strcat(m, "data.");
|
||||
|
||||
rv = (*inner)(out, &sd->data, m, 0);
|
||||
if (rv) {
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return rv;
|
||||
}
|
||||
|
||||
m[PORT_Strlen(m) - 5] = 0;
|
||||
fprintf(out, m);
|
||||
sv_PrintAlgorithmID(out, &sd->signatureAlgorithm, "signatureAlgorithm=");
|
||||
DER_ConvertBitString(&sd->signature);
|
||||
fprintf(out, m);
|
||||
sv_PrintAsHex(out, &sd->signature, "signature=");
|
||||
|
||||
PORT_FreeArena(arena, PR_FALSE);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** secu_PrintPKCS7Signed
|
||||
** Pretty print a PKCS7 signed data type (up to version 1).
|
||||
*/
|
||||
int
|
||||
sv_PrintPKCS7Signed(FILE *out, SEC_PKCS7SignedData *src)
|
||||
{
|
||||
SECAlgorithmID *digAlg; /* digest algorithms */
|
||||
SECItem *aCert; /* certificate */
|
||||
CERTSignedCrl *aCrl; /* certificate revocation list */
|
||||
SEC_PKCS7SignerInfo *sigInfo; /* signer information */
|
||||
int rv, iv;
|
||||
char om[120];
|
||||
|
||||
sv_PrintInteger(out, &(src->version), "pkcs7.version=");
|
||||
|
||||
/* Parse and list digest algorithms (if any) */
|
||||
if (src->digestAlgorithms != NULL) {
|
||||
iv = 0;
|
||||
while (src->digestAlgorithms[iv] != NULL)
|
||||
iv++;
|
||||
fprintf(out, "pkcs7.digestAlgorithmListLength=%d\n", iv);
|
||||
iv = 0;
|
||||
while ((digAlg = src->digestAlgorithms[iv]) != NULL) {
|
||||
sprintf(om, "pkcs7.digestAlgorithm[%d]=", iv++);
|
||||
sv_PrintAlgorithmID(out, digAlg, om);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now for the content */
|
||||
rv = sv_PrintPKCS7ContentInfo(out, &(src->contentInfo),
|
||||
"pkcs7.contentInformation=");
|
||||
if (rv != 0) return rv;
|
||||
|
||||
/* Parse and list certificates (if any) */
|
||||
if (src->rawCerts != NULL) {
|
||||
iv = 0;
|
||||
while (src->rawCerts[iv] != NULL)
|
||||
iv++;
|
||||
fprintf(out, "pkcs7.certificateListLength=%d\n", iv);
|
||||
|
||||
iv = 0;
|
||||
while ((aCert = src->rawCerts[iv]) != NULL) {
|
||||
sprintf(om, "certificate[%d].", iv++);
|
||||
rv = sv_PrintSignedData(out, aCert, om, sv_PrintCertificate);
|
||||
if (rv) return rv;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse and list CRL's (if any) */
|
||||
if (src->crls != NULL) {
|
||||
iv = 0;
|
||||
while (src->crls[iv] != NULL) iv++;
|
||||
fprintf(out, "pkcs7.signedRevocationLists=%d\n", iv);
|
||||
iv = 0;
|
||||
while ((aCrl = src->crls[iv]) != NULL) {
|
||||
sprintf(om, "signedRevocationList[%d].", iv);
|
||||
fprintf(out, om);
|
||||
sv_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm,
|
||||
"signatureAlgorithm=");
|
||||
DER_ConvertBitString(&aCrl->signatureWrap.signature);
|
||||
fprintf(out, om);
|
||||
sv_PrintAsHex(out, &aCrl->signatureWrap.signature, "signature=");
|
||||
sprintf(om, "certificateRevocationList[%d].", iv);
|
||||
sv_PrintCRLInfo(out, &aCrl->crl, om);
|
||||
iv++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse and list signatures (if any) */
|
||||
if (src->signerInfos != NULL) {
|
||||
iv = 0;
|
||||
while (src->signerInfos[iv] != NULL)
|
||||
iv++;
|
||||
fprintf(out, "pkcs7.signerInformationListLength=%d\n", iv);
|
||||
iv = 0;
|
||||
while ((sigInfo = src->signerInfos[iv]) != NULL) {
|
||||
sprintf(om, "signerInformation[%d].", iv++);
|
||||
sv_PrintSignerInfo(out, sigInfo, om);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
** secu_PrintPKCS7Enveloped
|
||||
** Pretty print a PKCS7 enveloped data type (up to version 1).
|
||||
*/
|
||||
void
|
||||
secu_PrintPKCS7Enveloped(FILE *out, SEC_PKCS7EnvelopedData *src,
|
||||
char *m, int level)
|
||||
{
|
||||
SEC_PKCS7RecipientInfo *recInfo; /* pointer for signer information */
|
||||
int iv;
|
||||
char om[100];
|
||||
|
||||
secu_Indent(out, level); fprintf(out, "%s:\n", m);
|
||||
sv_PrintInteger(out, &(src->version), "Version", level + 1);
|
||||
|
||||
/* Parse and list recipients (this is not optional) */
|
||||
if (src->recipientInfos != NULL) {
|
||||
secu_Indent(out, level + 1);
|
||||
fprintf(out, "Recipient Information List:\n");
|
||||
iv = 0;
|
||||
while ((recInfo = src->recipientInfos[iv++]) != NULL) {
|
||||
sprintf(om, "Recipient Information (%x)", iv);
|
||||
secu_PrintRecipientInfo(out, recInfo, om, level + 2);
|
||||
}
|
||||
}
|
||||
|
||||
secu_PrintPKCS7EncContent(out, &src->encContentInfo,
|
||||
"Encrypted Content Information", level + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
** secu_PrintPKCS7SignedEnveloped
|
||||
** Pretty print a PKCS7 singed and enveloped data type (up to version 1).
|
||||
*/
|
||||
int
|
||||
secu_PrintPKCS7SignedAndEnveloped(FILE *out,
|
||||
SEC_PKCS7SignedAndEnvelopedData *src,
|
||||
char *m, int level)
|
||||
{
|
||||
SECAlgorithmID *digAlg; /* pointer for digest algorithms */
|
||||
SECItem *aCert; /* pointer for certificate */
|
||||
CERTSignedCrl *aCrl; /* pointer for certificate revocation list */
|
||||
SEC_PKCS7SignerInfo *sigInfo; /* pointer for signer information */
|
||||
SEC_PKCS7RecipientInfo *recInfo; /* pointer for recipient information */
|
||||
int rv, iv;
|
||||
char om[100];
|
||||
|
||||
secu_Indent(out, level); fprintf(out, "%s:\n", m);
|
||||
sv_PrintInteger(out, &(src->version), "Version", level + 1);
|
||||
|
||||
/* Parse and list recipients (this is not optional) */
|
||||
if (src->recipientInfos != NULL) {
|
||||
secu_Indent(out, level + 1);
|
||||
fprintf(out, "Recipient Information List:\n");
|
||||
iv = 0;
|
||||
while ((recInfo = src->recipientInfos[iv++]) != NULL) {
|
||||
sprintf(om, "Recipient Information (%x)", iv);
|
||||
secu_PrintRecipientInfo(out, recInfo, om, level + 2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse and list digest algorithms (if any) */
|
||||
if (src->digestAlgorithms != NULL) {
|
||||
secu_Indent(out, level + 1); fprintf(out, "Digest Algorithm List:\n");
|
||||
iv = 0;
|
||||
while ((digAlg = src->digestAlgorithms[iv++]) != NULL) {
|
||||
sprintf(om, "Digest Algorithm (%x)", iv);
|
||||
sv_PrintAlgorithmID(out, digAlg, om);
|
||||
}
|
||||
}
|
||||
|
||||
secu_PrintPKCS7EncContent(out, &src->encContentInfo,
|
||||
"Encrypted Content Information", level + 1);
|
||||
|
||||
/* Parse and list certificates (if any) */
|
||||
if (src->rawCerts != NULL) {
|
||||
secu_Indent(out, level + 1); fprintf(out, "Certificate List:\n");
|
||||
iv = 0;
|
||||
while ((aCert = src->rawCerts[iv++]) != NULL) {
|
||||
sprintf(om, "Certificate (%x)", iv);
|
||||
rv = SECU_PrintSignedData(out, aCert, om, level + 2,
|
||||
SECU_PrintCertificate);
|
||||
if (rv)
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse and list CRL's (if any) */
|
||||
if (src->crls != NULL) {
|
||||
secu_Indent(out, level + 1);
|
||||
fprintf(out, "Signed Revocation Lists:\n");
|
||||
iv = 0;
|
||||
while ((aCrl = src->crls[iv++]) != NULL) {
|
||||
sprintf(om, "Signed Revocation List (%x)", iv);
|
||||
secu_Indent(out, level + 2); fprintf(out, "%s:\n", om);
|
||||
sv_PrintAlgorithmID(out, &aCrl->signatureWrap.signatureAlgorithm,
|
||||
"Signature Algorithm");
|
||||
DER_ConvertBitString(&aCrl->signatureWrap.signature);
|
||||
sv_PrintAsHex(out, &aCrl->signatureWrap.signature, "Signature",
|
||||
level+3);
|
||||
SECU_PrintCRLInfo(out, &aCrl->crl, "Certificate Revocation List",
|
||||
level + 3);
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse and list signatures (if any) */
|
||||
if (src->signerInfos != NULL) {
|
||||
secu_Indent(out, level + 1);
|
||||
fprintf(out, "Signer Information List:\n");
|
||||
iv = 0;
|
||||
while ((sigInfo = src->signerInfos[iv++]) != NULL) {
|
||||
sprintf(om, "Signer Information (%x)", iv);
|
||||
secu_PrintSignerInfo(out, sigInfo, om, level + 2);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(int)
|
||||
SECU_PrintCrl (FILE *out, SECItem *der, char *m, int level)
|
||||
{
|
||||
PRArenaPool *arena = NULL;
|
||||
CERTCrl *c = NULL;
|
||||
int rv;
|
||||
|
||||
do {
|
||||
/* Decode CRL */
|
||||
c = (CERTCrl*) PORT_ZAlloc(sizeof(CERTCrl));
|
||||
if (!c) {
|
||||
rv = PORT_GetError();
|
||||
break;
|
||||
}
|
||||
|
||||
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
|
||||
if (!arena) {
|
||||
rv = SEC_ERROR_NO_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
rv = SEC_ASN1DecodeItem(arena, c, CERT_CrlTemplate, der);
|
||||
if (rv != SECSuccess)
|
||||
break;
|
||||
SECU_PrintCRLInfo (out, c, m, level);
|
||||
} while (0);
|
||||
PORT_FreeArena (arena, PR_FALSE);
|
||||
PORT_Free (c);
|
||||
return (rv);
|
||||
}
|
||||
|
||||
/*
|
||||
** secu_PrintPKCS7Encrypted
|
||||
** Pretty print a PKCS7 encrypted data type (up to version 1).
|
||||
*/
|
||||
void
|
||||
secu_PrintPKCS7Encrypted(FILE *out, SEC_PKCS7EncryptedData *src,
|
||||
char *m, int level)
|
||||
{
|
||||
secu_Indent(out, level); fprintf(out, "%s:\n", m);
|
||||
sv_PrintInteger(out, &(src->version), "Version", level + 1);
|
||||
|
||||
secu_PrintPKCS7EncContent(out, &src->encContentInfo,
|
||||
"Encrypted Content Information", level + 1);
|
||||
}
|
||||
|
||||
/*
|
||||
** secu_PrintPKCS7Digested
|
||||
** Pretty print a PKCS7 digested data type (up to version 1).
|
||||
*/
|
||||
void
|
||||
sv_PrintPKCS7Digested(FILE *out, SEC_PKCS7DigestedData *src)
|
||||
{
|
||||
secu_Indent(out, level); fprintf(out, "%s:\n", m);
|
||||
sv_PrintInteger(out, &(src->version), "Version", level + 1);
|
||||
|
||||
sv_PrintAlgorithmID(out, &src->digestAlg, "Digest Algorithm");
|
||||
sv_PrintPKCS7ContentInfo(out, &src->contentInfo, "Content Information",
|
||||
level + 1);
|
||||
sv_PrintAsHex(out, &src->digest, "Digest", level + 1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
** secu_PrintPKCS7ContentInfo
|
||||
** Takes a SEC_PKCS7ContentInfo type and sends the contents to the
|
||||
** appropriate function
|
||||
*/
|
||||
int
|
||||
sv_PrintPKCS7ContentInfo(FILE *out, SEC_PKCS7ContentInfo *src, char *m)
|
||||
{
|
||||
char *desc;
|
||||
SECOidTag kind;
|
||||
int rv;
|
||||
|
||||
if (src->contentTypeTag == NULL)
|
||||
src->contentTypeTag = SECOID_FindOID(&(src->contentType));
|
||||
|
||||
if (src->contentTypeTag == NULL) {
|
||||
desc = "Unknown";
|
||||
kind = SEC_OID_PKCS7_DATA;
|
||||
} else {
|
||||
desc = src->contentTypeTag->desc;
|
||||
kind = src->contentTypeTag->offset;
|
||||
}
|
||||
|
||||
fprintf(out, "%s%s\n", m, desc);
|
||||
|
||||
if (src->content.data == NULL) {
|
||||
fprintf(out, "pkcs7.data=<no content>\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = 0;
|
||||
switch (kind) {
|
||||
case SEC_OID_PKCS7_SIGNED_DATA: /* Signed Data */
|
||||
rv = sv_PrintPKCS7Signed(out, src->content.signedData);
|
||||
break;
|
||||
|
||||
case SEC_OID_PKCS7_ENVELOPED_DATA: /* Enveloped Data */
|
||||
fprintf(out, "pkcs7EnvelopedData=<unsupported>\n");
|
||||
/*sv_PrintPKCS7Enveloped(out, src->content.envelopedData);*/
|
||||
break;
|
||||
|
||||
case SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA: /* Signed and Enveloped */
|
||||
fprintf(out, "pkcs7SignedEnvelopedData=<unsupported>\n");
|
||||
/*rv = sv_PrintPKCS7SignedAndEnveloped(out,
|
||||
src->content.signedAndEnvelopedData);*/
|
||||
break;
|
||||
|
||||
case SEC_OID_PKCS7_DIGESTED_DATA: /* Digested Data */
|
||||
fprintf(out, "pkcs7DigestedData=<unsupported>\n");
|
||||
/*sv_PrintPKCS7Digested(out, src->content.digestedData);*/
|
||||
break;
|
||||
|
||||
case SEC_OID_PKCS7_ENCRYPTED_DATA: /* Encrypted Data */
|
||||
fprintf(out, "pkcs7EncryptedData=<unsupported>\n");
|
||||
/*sv_PrintPKCS7Encrypted(out, src->content.encryptedData);*/
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(out, "pkcs7UnknownData=<unsupported>\n");
|
||||
/*sv_PrintAsHex(out, src->content.data);*/
|
||||
break;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
SV_PrintPKCS7ContentInfo(FILE *out, SECItem *der)
|
||||
{
|
||||
SEC_PKCS7ContentInfo *cinfo;
|
||||
int rv = -1;
|
||||
|
||||
cinfo = SEC_PKCS7DecodeItem(der, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
if (cinfo != NULL) {
|
||||
rv = sv_PrintPKCS7ContentInfo(out, cinfo, "pkcs7.contentInfo=");
|
||||
SEC_PKCS7DestroyContentInfo(cinfo);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
/*
|
||||
** End of PKCS7 functions
|
||||
*/
|
||||
458
mozilla/security/nss/cmd/signver/signver.c
Normal file
458
mozilla/security/nss/cmd/signver/signver.c
Normal file
@ -0,0 +1,458 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "secutil.h"
|
||||
#include "secmod.h"
|
||||
#include "cdbhdl.h"
|
||||
#include "cert.h"
|
||||
#include "secoid.h"
|
||||
|
||||
/* NSPR 2.0 header files */
|
||||
#include "prinit.h"
|
||||
#include "prprf.h"
|
||||
#include "prsystem.h"
|
||||
#include "prmem.h"
|
||||
/* Portable layer header files */
|
||||
#include "plstr.h"
|
||||
|
||||
static int debugInfo = 0;
|
||||
|
||||
static char *usageInfo[] = {
|
||||
"Options:",
|
||||
" -a signature file is ASCII",
|
||||
" -d certdir directory containing cert database",
|
||||
" -i dataFileName input file name containing data,",
|
||||
" leave filename blank to use stdin",
|
||||
" -s signatureFileName input file name containing signature,",
|
||||
" leave filename blank to use stdin",
|
||||
" -o outputFileName output file name, default stdout",
|
||||
" -A display all information from pkcs #7",
|
||||
" -C display all information from all certs",
|
||||
" -C -n display number of certificates",
|
||||
" -C -n certNum display all information from the certNum",
|
||||
" certificate in pkcs #7 signed object",
|
||||
" -C -n certNum f1 ... fN display information about specified",
|
||||
" fields from the certNum certificate in",
|
||||
" the pkcs #7 signed object",
|
||||
" -S display signer information list",
|
||||
" -S -n display number of signer information blocks",
|
||||
" -S -n signerNum display all information from the signerNum",
|
||||
" signer information block in pkcs #7",
|
||||
" -S -n signerNum f1 ... fN display information about specified",
|
||||
" fields from the signerNum signer",
|
||||
" information block in pkcs #7 object",
|
||||
" -V verify the signed object and display result",
|
||||
" -V -v verify the signed object and display",
|
||||
" result and reason for failure",
|
||||
"Version 2.0"
|
||||
};
|
||||
static int nUsageInfo = sizeof(usageInfo)/sizeof(char *);
|
||||
|
||||
extern int SV_PrintPKCS7ContentInfo(FILE *, SECItem *);
|
||||
|
||||
static void Usage(char *progName, FILE *outFile)
|
||||
{
|
||||
int i;
|
||||
fprintf(outFile, "Usage: %s options\n", progName);
|
||||
for (i = 0; i < nUsageInfo; i++)
|
||||
fprintf(outFile, "%s\n", usageInfo[i]);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
static HASH_HashType
|
||||
AlgorithmToHashType(SECAlgorithmID *digestAlgorithms)
|
||||
{
|
||||
SECOidTag tag;
|
||||
|
||||
tag = SECOID_GetAlgorithmTag(digestAlgorithms);
|
||||
|
||||
switch (tag) {
|
||||
case SEC_OID_MD2:
|
||||
if (debugInfo) PR_fprintf(PR_STDERR, "Hash algorithm: HASH_AlgMD2 SEC_OID_MD2\n");
|
||||
return HASH_AlgMD2;
|
||||
case SEC_OID_MD5:
|
||||
if (debugInfo) PR_fprintf(PR_STDERR, "Hash algorithm: HASH_AlgMD5 SEC_OID_MD5\n");
|
||||
return HASH_AlgMD5;
|
||||
case SEC_OID_SHA1:
|
||||
if (debugInfo) PR_fprintf(PR_STDERR, "Hash algorithm: HASH_AlgSHA1 SEC_OID_SHA1\n");
|
||||
return HASH_AlgSHA1;
|
||||
default:
|
||||
if (debugInfo) PR_fprintf(PR_STDERR, "should never get here\n");
|
||||
return HASH_AlgNULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
DigestData (unsigned char *digest, unsigned char *data,
|
||||
unsigned int *len, unsigned int maxLen,
|
||||
HASH_HashType hashType)
|
||||
{
|
||||
SECHashObject *hashObj;
|
||||
void *hashcx;
|
||||
|
||||
hashObj = &SECHashObjects[hashType];
|
||||
hashcx = (* hashObj->create)();
|
||||
if (hashcx == NULL)
|
||||
return -1;
|
||||
|
||||
(* hashObj->begin)(hashcx);
|
||||
(* hashObj->update)(hashcx, data, PORT_Strlen(data));
|
||||
(* hashObj->end)(hashcx, digest, len, maxLen);
|
||||
(* hashObj->destroy)(hashcx, PR_TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
enum {
|
||||
cmd_DisplayAllPCKS7Info = 0,
|
||||
cmd_DisplayCertInfo,
|
||||
cmd_DisplaySignerInfo,
|
||||
cmd_VerifySignedObj
|
||||
};
|
||||
|
||||
enum {
|
||||
opt_ASCII,
|
||||
opt_CertDir,
|
||||
opt_InputDataFile,
|
||||
opt_ItemNumber,
|
||||
opt_OutputFile,
|
||||
opt_InputSigFile,
|
||||
opt_TypeTag,
|
||||
opt_PrintWhyFailure
|
||||
};
|
||||
|
||||
static secuCommandFlag signver_commands[] =
|
||||
{
|
||||
{ /* cmd_DisplayAllPCKS7Info*/ 'A', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* cmd_DisplayCertInfo */ 'C', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* cmd_DisplaySignerInfo */ 'S', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* cmd_VerifySignedObj */ 'V', PR_FALSE, 0, PR_FALSE }
|
||||
};
|
||||
|
||||
static secuCommandFlag signver_options[] =
|
||||
{
|
||||
{ /* opt_ASCII */ 'a', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_CertDir */ 'd', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_InputDataFile */ 'i', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_ItemNumber */ 'n', PR_FALSE, 0, PR_FALSE },
|
||||
{ /* opt_OutputFile */ 'o', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_InputSigFile */ 's', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_TypeTag */ 't', PR_TRUE, 0, PR_FALSE },
|
||||
{ /* opt_PrintWhyFailure */ 'v', PR_FALSE, 0, PR_FALSE }
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
PRExplodedTime explodedCurrent;
|
||||
SECItem der, data;
|
||||
char *progName;
|
||||
int rv;
|
||||
PRFileDesc *dataFile = 0;
|
||||
PRFileDesc *signFile = 0;
|
||||
FILE *outFile = stdout;
|
||||
char *typeTag = 0;
|
||||
PRBool displayAllCerts = PR_FALSE;
|
||||
PRBool displayAllSigners = PR_FALSE;
|
||||
PRFileInfo info;
|
||||
PRInt32 nb;
|
||||
|
||||
secuCommand signver;
|
||||
signver.numCommands = sizeof(signver_commands) /sizeof(secuCommandFlag);
|
||||
signver.numOptions = sizeof(signver_options) / sizeof(secuCommandFlag);
|
||||
signver.commands = signver_commands;
|
||||
signver.options = signver_options;
|
||||
|
||||
#ifdef XP_PC
|
||||
progName = strrchr(argv[0], '\\');
|
||||
#else
|
||||
progName = strrchr(argv[0], '/');
|
||||
#endif
|
||||
progName = progName ? progName+1 : argv[0];
|
||||
|
||||
/*_asm int 3*/
|
||||
|
||||
PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &explodedCurrent);
|
||||
#if 0
|
||||
if (explodedCurrent.tm_year >= 1998
|
||||
&& explodedCurrent.tm_month >= 5 /* months past tm_year (0-11, Jan = 0) */
|
||||
&& explodedCurrent.tm_mday >= 1) {
|
||||
PR_fprintf(PR_STDERR, "%s: expired\n", progName);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
SECU_ParseCommandLine(argc, argv, progName, &signver);
|
||||
|
||||
/* Set the certdb directory (default is ~/.{browser}) */
|
||||
SECU_ConfigDirectory(signver.options[opt_CertDir].arg);
|
||||
|
||||
/* Set the certificate type. */
|
||||
typeTag = SECU_GetOptionArg(&signver, opt_TypeTag);
|
||||
|
||||
/* -i and -s without filenames */
|
||||
if (signver.options[opt_InputDataFile].activated &&
|
||||
signver.options[opt_InputSigFile].activated &&
|
||||
!signver.options[opt_InputDataFile].arg &&
|
||||
!signver.options[opt_InputSigFile].arg)
|
||||
PR_fprintf(PR_STDERR,
|
||||
"%s: Only data or signature file can use stdin (not both).\n",
|
||||
progName);
|
||||
|
||||
/* Open the input data file (no arg == use stdin). */
|
||||
if (signver.options[opt_InputDataFile].activated) {
|
||||
if (signver.options[opt_InputDataFile].arg)
|
||||
dataFile = PR_Open(signver.options[opt_InputDataFile].arg,
|
||||
PR_RDONLY, 0);
|
||||
else
|
||||
dataFile = PR_STDIN;
|
||||
if (!dataFile) {
|
||||
PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for reading.\n",
|
||||
progName, signver.options[opt_InputDataFile].arg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Open the input signature file (no arg == use stdin). */
|
||||
if (signver.options[opt_InputSigFile].activated) {
|
||||
if (signver.options[opt_InputSigFile].arg)
|
||||
signFile = PR_Open(signver.options[opt_InputSigFile].arg,
|
||||
PR_RDONLY, 0);
|
||||
else
|
||||
signFile = PR_STDIN;
|
||||
if (!signFile) {
|
||||
PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for reading.\n",
|
||||
progName, signver.options[opt_InputSigFile].arg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!typeTag) ascii = 1;
|
||||
#endif
|
||||
|
||||
/* Open|Create the output file. */
|
||||
if (signver.options[opt_OutputFile].activated) {
|
||||
outFile = fopen(signver.options[opt_OutputFile].arg, "w");
|
||||
/*
|
||||
outFile = PR_Open(signver.options[opt_OutputFile].arg,
|
||||
PR_WRONLY|PR_CREATE_FILE|PR_TRUNCATE, 00660);
|
||||
*/
|
||||
if (!outFile) {
|
||||
PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for writing.\n",
|
||||
progName, signver.options[opt_OutputFile].arg);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (signver.commands[cmd_DisplayCertInfo].activated &&
|
||||
!signver.options[opt_ItemNumber].arg)
|
||||
displayAllCerts = PR_TRUE;
|
||||
|
||||
if (signver.commands[cmd_DisplaySignerInfo].activated &&
|
||||
!signver.options[opt_ItemNumber].arg)
|
||||
displayAllSigners = PR_TRUE;
|
||||
|
||||
#if 0
|
||||
case 'W':
|
||||
debugInfo = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
if (!signFile && !dataFile && !typeTag)
|
||||
Usage(progName, outFile);
|
||||
|
||||
if (!signFile && !dataFile &&
|
||||
signver.commands[cmd_VerifySignedObj].activated) {
|
||||
PR_fprintf(PR_STDERR,
|
||||
"%s: unable to read all data from standard input\n",
|
||||
progName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
PR_SetError(0, 0); /* PR_Init("pp", 1, 1, 0);*/
|
||||
SECU_PKCS11Init(PR_FALSE);
|
||||
SEC_Init();
|
||||
|
||||
rv = SECU_ReadDERFromFile(&der, signFile,
|
||||
signver.options[opt_ASCII].activated);
|
||||
|
||||
/* Data is untyped, using the specified type */
|
||||
data.data = der.data;
|
||||
data.len = der.len;
|
||||
|
||||
|
||||
/* Signature Verification */
|
||||
if (!signver.options[opt_TypeTag].activated) {
|
||||
if (signver.commands[cmd_VerifySignedObj].activated) {
|
||||
SEC_PKCS7ContentInfo *cinfo;
|
||||
|
||||
cinfo = SEC_PKCS7DecodeItem(&data, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
if (cinfo != NULL) {
|
||||
#if 0
|
||||
if (debugInfo) {
|
||||
PR_fprintf(PR_STDERR, "Content %s encrypted.\n",
|
||||
SEC_PKCS7ContentIsEncrypted(cinfo) ? "was" : "was not");
|
||||
|
||||
PR_fprintf(PR_STDERR, "Content %s signed.\n",
|
||||
SEC_PKCS7ContentIsSigned(cinfo) ? "was" : "was not");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (SEC_PKCS7ContentIsSigned(cinfo)) {
|
||||
SEC_PKCS7SignedData *signedData;
|
||||
HASH_HashType digestType;
|
||||
SECItem digest, data;
|
||||
unsigned char *dataToVerify, digestBuffer[32];
|
||||
|
||||
signedData = cinfo->content.signedData;
|
||||
|
||||
/* assume that there is only one digest algorithm for now */
|
||||
digestType =
|
||||
AlgorithmToHashType(signedData->digestAlgorithms[0]);
|
||||
if (digestType == HASH_AlgNULL) {
|
||||
PR_fprintf(PR_STDERR, "Invalid hash algorithmID\n");
|
||||
return (-1);
|
||||
}
|
||||
rv = SECU_FileToItem(&data, dataFile);
|
||||
dataToVerify = data.data;
|
||||
if (dataToVerify) {
|
||||
SECKEYKeyDBHandle *keyHandle;
|
||||
CERTCertDBHandle *certHandle;
|
||||
/*certUsageObjectSigner;*/
|
||||
SECCertUsage usage = certUsageEmailSigner;
|
||||
|
||||
|
||||
#if 0
|
||||
if (debugInfo)
|
||||
PR_fprintf(PR_STDERR, "dataToVerify=%s\n",
|
||||
dataToVerify);
|
||||
#endif
|
||||
digest.data = digestBuffer;
|
||||
if (DigestData (digest.data, dataToVerify,
|
||||
&digest.len, 32, digestType)) {
|
||||
PR_fprintf(PR_STDERR, "Fail to compute message digest for verification. Reason: %s\n",
|
||||
SECU_ErrorString((int16)PORT_GetError()));
|
||||
return (-1);
|
||||
}
|
||||
#if 0
|
||||
if (debugInfo) {
|
||||
PR_fprintf(PR_STDERR, "Data Digest=:");
|
||||
for (i = 0; i < digest.len; i++)
|
||||
PR_fprintf(PR_STDERR, "%02x:", digest.data[i]);
|
||||
PR_fprintf(PR_STDERR, "\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
keyHandle = SECKEY_GetDefaultKeyDB();
|
||||
if (keyHandle == NULL) {
|
||||
PR_fprintf(PR_STDERR, ": %s\n", SECU_ErrorString((int16)PORT_GetError()));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* open cert database */
|
||||
certHandle = SECU_OpenCertDB(PR_TRUE);
|
||||
if (certHandle == NULL) {
|
||||
PR_fprintf(PR_STDERR, "%s Problem open the cert dbase\n",
|
||||
progName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (signver.commands[cmd_VerifySignedObj].activated)
|
||||
fprintf(outFile, "signatureValid=");
|
||||
PORT_SetError(0);
|
||||
if (SEC_PKCS7VerifyDetachedSignature (cinfo, usage,
|
||||
&digest, digestType, PR_FALSE)) {
|
||||
if (signver.commands[cmd_VerifySignedObj].activated)
|
||||
fprintf(outFile, "yes");
|
||||
} else {
|
||||
if (signver.commands[cmd_VerifySignedObj].activated){
|
||||
fprintf(outFile, "no");
|
||||
if (signver.options[opt_PrintWhyFailure].activated)
|
||||
fprintf(outFile, ":%s", SECU_ErrorString((int16)PORT_GetError()));
|
||||
}
|
||||
}
|
||||
if (signver.commands[cmd_VerifySignedObj].activated)
|
||||
fprintf(outFile, "\n");
|
||||
|
||||
SECITEM_FreeItem(&data, PR_FALSE);
|
||||
} else {
|
||||
PR_fprintf(PR_STDERR, "Cannot read data\n");
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
SEC_PKCS7DestroyContentInfo(cinfo);
|
||||
} else
|
||||
PR_fprintf(PR_STDERR, "Unable to decode PKCS7 data\n");
|
||||
}
|
||||
|
||||
if (signver.commands[cmd_DisplayAllPCKS7Info].activated)
|
||||
SV_PrintPKCS7ContentInfo(outFile, &data);
|
||||
|
||||
if (displayAllCerts)
|
||||
PR_fprintf(PR_STDERR, "-C option is not implemented in this version\n");
|
||||
|
||||
if (displayAllSigners)
|
||||
PR_fprintf(PR_STDERR, "-S option is not implemented in this version\n");
|
||||
|
||||
/* Pretty print it */
|
||||
} else if (PL_strcmp(typeTag, SEC_CT_CERTIFICATE) == 0) {
|
||||
rv = SECU_PrintSignedData(outFile, &data, "Certificate", 0,
|
||||
SECU_PrintCertificate);
|
||||
} else if (PL_strcmp(typeTag, SEC_CT_CERTIFICATE_REQUEST) == 0) {
|
||||
rv = SECU_PrintSignedData(outFile, &data, "Certificate Request", 0,
|
||||
SECU_PrintCertificateRequest);
|
||||
} else if (PL_strcmp (typeTag, SEC_CT_CRL) == 0) {
|
||||
rv = SECU_PrintSignedData (outFile, &data, "CRL", 0, SECU_PrintCrl);
|
||||
} else if (PL_strcmp(typeTag, SEC_CT_PRIVATE_KEY) == 0) {
|
||||
rv = SECU_PrintPrivateKey(outFile, &data, "Private Key", 0);
|
||||
} else if (PL_strcmp(typeTag, SEC_CT_PUBLIC_KEY) == 0) {
|
||||
rv = SECU_PrintPublicKey(outFile, &data, "Public Key", 0);
|
||||
} else if (PL_strcmp(typeTag, SEC_CT_PKCS7) == 0) {
|
||||
rv = SECU_PrintPKCS7ContentInfo(outFile, &data,
|
||||
"PKCS #7 Content Info", 0);
|
||||
} else {
|
||||
PR_fprintf(PR_STDERR, "%s: don't know how to print out '%s' files\n",
|
||||
progName, typeTag);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rv) {
|
||||
PR_fprintf(PR_STDERR, "%s: problem converting data (%s)\n",
|
||||
progName, SECU_ErrorString((int16)PORT_GetError()));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user