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 + -
显示快捷键?