checkcert.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 637 行 · 第 1/2 页

C
637
字号
/* * 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 "plgetopt.h"#include "cert.h"#include "secoid.h"#include "cryptohi.h"/* maximum supported modulus length in bits (indicate problem if over this) */#define MAX_MODULUS (1024)static void Usage(char *progName){    fprintf(stderr, "Usage: %s [aAvf] [certtocheck] [issuingcert]\n",	    progName);    fprintf(stderr, "%-20s Cert to check is base64 encoded\n",	    "-a");    fprintf(stderr, "%-20s Issuer's cert is base64 encoded\n",	    "-A");    fprintf(stderr, "%-20s Verbose (indicate decoding progress etc.)\n",	    "-v");    fprintf(stderr, "%-20s Force sanity checks even if pretty print fails.\n",	    "-f");    fprintf(stderr, "%-20s Define an output file to use (default is stdout)\n",	    "-o output");    fprintf(stderr, "%-20s Specify the input type (no default)\n",	    "-t type");    exit(-1);}/* * Check integer field named fieldName, printing out results and * returning the length of the integer in bits */   staticint checkInteger(SECItem *intItem, char *fieldName, int verbose) {    int len, bitlen;    if (verbose) {	printf("Checking %s\n", fieldName);    }        len = intItem->len;        if (len && (intItem->data[0] & 0x80)) {	printf("PROBLEM: %s is NEGATIVE 2's-complement integer.\n",	       fieldName);    }            /* calculate bit length and check for unnecessary leading zeros */    bitlen = len << 3;    if (len > 1 && intItem->data[0] == 0) {	/* leading zero byte(s) */	if (!(intItem->data[1] & 0x80)) {	    printf("PROBLEM: %s has unneeded leading zeros.  Violates DER.\n",		   fieldName);	}	/* strip leading zeros in length calculation */	{	    int i=0;	    while (bitlen > 8 && intItem->data[i] == 0) {		bitlen -= 8;		i++;	    }	}    }    return bitlen;}staticvoid checkName(CERTName *n, char *fieldName, int verbose){    char *v=0;    if (verbose) {	printf("Checking %s\n", fieldName);    }        v = CERT_GetCountryName(n);    if (!v) {	printf("PROBLEM: %s lacks Country Name (C)\n",	       fieldName);    }    PORT_Free(v);        v = CERT_GetOrgName(n);    if (!v) {	printf("PROBLEM: %s lacks Organization Name (O)\n",	       fieldName);    }    PORT_Free(v);        v = CERT_GetOrgUnitName(n);    if (!v) {	printf("WARNING: %s lacks Organization Unit Name (OU)\n",	       fieldName);    }    PORT_Free(v);	        v = CERT_GetCommonName(n);    if (!v) {	printf("PROBLEM: %s lacks Common Name (CN)\n",	       fieldName);    }    PORT_Free(v);}/* * Private version of verification that checks for agreement between * signature algorithm oid (at the SignedData level) and oid in DigestInfo. * */          /* Returns the tag for the hash algorithm in the given signature algorithm */     static     int hashAlg(int sigAlgTag) {	 int rv;	 switch(sigAlgTag) {	   case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION:	     rv = SEC_OID_MD2;	     break;	   case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION:	     rv = SEC_OID_MD5;	     break;	   case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:	     rv = SEC_OID_SHA1;	     break;	   default:	     rv = -1;	 }	 return rv;     }struct VFYContextStr {    int alg;    unsigned char digest[32];    void *hasher;    void (*begin)(void *);    void (*update)(void *, unsigned char*, unsigned);    SECStatus (*end)(void *, unsigned char*, unsigned int*, unsigned);    void (*destroy)(void *, PRBool);};staticSECStatusOurVerifyData(unsigned char *buf, int len, SECKEYPublicKey *key,	      SECItem *sig, SECAlgorithmID *sigAlgorithm){    SECStatus rv;    VFYContext *cx;    SECOidData *sigAlgOid, *oiddata;    int sigAlgTag;    int hashAlgTag;    int showDigestOid=0;        cx = VFY_CreateContext(key, sig, SECOID_GetAlgorithmTag(sigAlgorithm),			   NULL);    if (cx == NULL)	return SECFailure;        sigAlgOid = SECOID_FindOID(&sigAlgorithm->algorithm);    if (sigAlgOid == 0)	return SECFailure;    sigAlgTag = sigAlgOid->offset;        hashAlgTag = hashAlg(sigAlgTag);    if (hashAlgTag == -1) {	printf("PROBLEM: Unsupported Digest Algorithm in DigestInfo");	showDigestOid = 1;    } else if (hashAlgTag != cx->alg) {	printf("PROBLEM: Digest OID in DigestInfo is incompatible "	       "with Signature Algorithm\n");	showDigestOid = 1;    }     if (showDigestOid) {	oiddata = SECOID_FindOIDByTag(cx->alg);	if ( oiddata ) {	    printf("PROBLEM: (cont) Digest OID is %s\n", oiddata->desc);	} else {	    SECU_PrintAsHex(stdout,			    &oiddata->oid, "PROBLEM: UNKNOWN OID", 0);	}    }        rv = VFY_Begin(cx);    if (rv == SECSuccess) {	rv = VFY_Update(cx, buf, len);	if (rv == SECSuccess)	    rv = VFY_End(cx);    }        VFY_DestroyContext(cx, PR_TRUE);    return rv;}staticSECStatusOurVerifySignedData(CERTSignedData *sd, CERTCertificate *cert){    SECItem sig;    SECKEYPublicKey *pubKey = 0;    SECStatus rv;        /* check the certificate's validity */    rv = CERT_CertTimesValid(cert);    if ( rv ) {	return(SECFailure);    }        /* get cert's public key */    pubKey = CERT_ExtractPublicKey(cert);    if ( !pubKey ) {	return(SECFailure);    }        /* check the signature */    sig = sd->signature;    DER_ConvertBitString(&sig);    rv = OurVerifyData(sd->data.data, sd->data.len, pubKey, &sig,		       &sd->signatureAlgorithm);        SECKEY_DestroyPublicKey(pubKey);        if ( rv ) {	return(SECFailure);    }        return(SECSuccess);}staticCERTCertificate *createEmptyCertificate(void){    PRArenaPool *arena = 0;    CERTCertificate *c = 0;        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);    if ( !arena ) {	return 0;    }            c = (CERTCertificate *) PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));        if (c) {	c->referenceCount = 1;	c->arena = arena;    } else {	PORT_FreeArena(arena,PR_TRUE);    }        return c;}    int main(int argc, char **argv){    int rv, verbose=0, force=0;    int ascii=0, issuerAscii=0;    char *progName=0;    PRFileDesc *inFile=0, *issuerCertFile=0;    SECItem derCert, derIssuerCert;    PRArenaPool *arena=0;    CERTSignedData *signedData=0;    CERTCertificate *cert=0, *issuerCert=0;    SECKEYPublicKey *rsapubkey=0;    SECAlgorithmID md5WithRSAEncryption, md2WithRSAEncryption;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?