checkcert.c
来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 637 行 · 第 1/2 页
C
637 行
SECAlgorithmID sha1WithRSAEncryption, rsaEncryption; SECItem spk; int selfSigned=0; int invalid=0; char *inFileName = NULL, *issuerCertFileName = NULL; PLOptState *optstate; PLOptStatus status; PORT_Memset(&md5WithRSAEncryption, 0, sizeof(md5WithRSAEncryption)); PORT_Memset(&md2WithRSAEncryption, 0, sizeof(md2WithRSAEncryption)); PORT_Memset(&sha1WithRSAEncryption, 0, sizeof(sha1WithRSAEncryption)); PORT_Memset(&rsaEncryption, 0, sizeof(rsaEncryption)); progName = strrchr(argv[0], '/'); progName = progName ? progName+1 : argv[0]; optstate = PL_CreateOptState(argc, argv, "aAvf"); while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) { switch (optstate->option) { case 'v': verbose = 1; break; case 'f': force = 1; break; case 'a': ascii = 1; break; case 'A': issuerAscii = 1; break; case '\0': if (!inFileName) inFileName = PL_strdup(optstate->value); else if (!issuerCertFileName) issuerCertFileName = PL_strdup(optstate->value); else Usage(progName); break; } } if (!inFileName || !issuerCertFileName || status == PL_OPT_BAD) { /* insufficient or excess args */ Usage(progName); } inFile = PR_Open(inFileName, PR_RDONLY, 0); if (!inFile) { fprintf(stderr, "%s: unable to open \"%s\" for reading\n", progName, inFileName); exit(1); } issuerCertFile = PR_Open(issuerCertFileName, PR_RDONLY, 0); if (!issuerCertFile) { fprintf(stderr, "%s: unable to open \"%s\" for reading\n", progName, issuerCertFileName); exit(1); } if (SECU_ReadDERFromFile(&derCert, inFile, ascii) != SECSuccess) { printf("Couldn't read input certificate as DER binary or base64\n"); exit(1); } arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if (arena == 0) { fprintf(stderr,"%s: can't allocate scratch arena!", progName); exit(1); } if (issuerCertFile) { CERTSignedData *issuerCertSD=0; if (SECU_ReadDERFromFile(&derIssuerCert, issuerCertFile, issuerAscii) != SECSuccess) { printf("Couldn't read issuer certificate as DER binary or base64.\n"); exit(1); } issuerCertSD = (CERTSignedData *) PORT_ArenaZAlloc(arena, sizeof(CERTSignedData)); if (!issuerCertSD) { fprintf(stderr,"%s: can't allocate issuer signed data!", progName); exit(1); } rv = SEC_ASN1DecodeItem(arena, issuerCertSD, CERT_SignedDataTemplate, &derIssuerCert); if (rv) { fprintf(stderr, "%s: Issuer cert isn't X509 SIGNED Data?\n", progName); exit(1); } issuerCert = createEmptyCertificate(); if (!issuerCert) { printf("%s: can't allocate space for issuer cert.", progName); exit(1); } rv = SEC_ASN1DecodeItem(arena, issuerCert, CERT_CertificateTemplate, &issuerCertSD->data); if (rv) { printf("%s: Does not appear to be an X509 Certificate.\n", progName); exit(1); } } signedData = (CERTSignedData *) PORT_ArenaZAlloc(arena,sizeof(CERTSignedData)); if (!signedData) { fprintf(stderr,"%s: can't allocate signedData!", progName); exit(1); } rv = SEC_ASN1DecodeItem(arena, signedData, CERT_SignedDataTemplate, &derCert); if (rv) { fprintf(stderr, "%s: Does not appear to be X509 SIGNED Data.\n", progName); exit(1); } if (verbose) { printf("Decoded ok as X509 SIGNED data.\n"); } cert = createEmptyCertificate(); if (!cert) { fprintf(stderr, "%s: can't allocate cert", progName); exit(1); } rv = SEC_ASN1DecodeItem(arena, cert, CERT_CertificateTemplate, &signedData->data); if (rv) { fprintf(stderr, "%s: Does not appear to be an X509 Certificate.\n", progName); exit(1); } if (verbose) { printf("Decoded ok as an X509 certificate.\n"); } rv = SECU_PrintSignedData(stdout, &derCert, "Certificate", 0, SECU_PrintCertificate); if (rv) { fprintf(stderr, "%s: Unable to pretty print cert. Error: %d\n", progName, PORT_GetError()); if (!force) { exit(1); } } /* Do various checks on the cert */ printf("\n"); /* Check algorithms */ SECOID_SetAlgorithmID(arena, &md5WithRSAEncryption, SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION, NULL); SECOID_SetAlgorithmID(arena, &md2WithRSAEncryption, SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION, NULL); SECOID_SetAlgorithmID(arena, &sha1WithRSAEncryption, SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION, NULL); SECOID_SetAlgorithmID(arena, &rsaEncryption, SEC_OID_PKCS1_RSA_ENCRYPTION, NULL); { int isMD5RSA = (SECOID_CompareAlgorithmID(&cert->signature, &md5WithRSAEncryption) == 0); int isMD2RSA = (SECOID_CompareAlgorithmID(&cert->signature, &md2WithRSAEncryption) == 0); int isSHA1RSA = (SECOID_CompareAlgorithmID(&cert->signature, &sha1WithRSAEncryption) == 0); if (verbose) { printf("\nDoing algorithm checks.\n"); } if (!(isMD5RSA || isMD2RSA || isSHA1RSA)) { printf("PROBLEM: Signature not PKCS1 MD5, MD2, or SHA1 + RSA.\n"); } else if (!isMD5RSA) { printf("WARNING: Signature not PKCS1 MD5 with RSA Encryption\n"); } if (SECOID_CompareAlgorithmID(&cert->signature, &signedData->signatureAlgorithm)) { printf("PROBLEM: Algorithm in sig and certInfo don't match.\n"); } } if (SECOID_CompareAlgorithmID(&cert->subjectPublicKeyInfo.algorithm, &rsaEncryption)) { printf("PROBLEM: Public key algorithm is not PKCS1 RSA Encryption.\n"); } /* Check further public key properties */ spk = cert->subjectPublicKeyInfo.subjectPublicKey; DER_ConvertBitString(&spk); if (verbose) { printf("\nsubjectPublicKey DER\n"); rv = DER_PrettyPrint(stdout, &spk, PR_FALSE); printf("\n"); } rsapubkey = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena,sizeof(SECKEYPublicKey)); if (!rsapubkey) { fprintf(stderr, "%s: rsapubkey allocation failed.\n", progName); exit(1); } rv = SEC_ASN1DecodeItem(arena, rsapubkey, SECKEY_RSAPublicKeyTemplate, &spk); if (rv) { printf("PROBLEM: subjectPublicKey is not a DER PKCS1 RSAPublicKey.\n"); } else { int mlen; int pubexp; if (verbose) { printf("Decoded RSA Public Key ok. Doing key checks.\n"); } PORT_Assert(rsapubkey->keyType == rsaKey); /* XXX RSA */ mlen = checkInteger(&rsapubkey->u.rsa.modulus, "Modulus", verbose); printf("INFO: Public Key modulus length in bits: %d\n", mlen); if (mlen > MAX_MODULUS) { printf("PROBLEM: Modulus length exceeds %d bits.\n", MAX_MODULUS); } if (mlen < 512) { printf("WARNING: Short modulus.\n"); } if (mlen != (1 << (ffs(mlen)-1))) { printf("WARNING: Unusual modulus length (not a power of two).\n"); } checkInteger(&rsapubkey->u.rsa.publicExponent, "Public Exponent", verbose); pubexp = DER_GetInteger(&rsapubkey->u.rsa.publicExponent); if (pubexp != 17 && pubexp != 3 && pubexp != 65537) { printf("WARNING: Public exponent not any of: 3, 17, 65537\n"); } } /* Name checks */ checkName(&cert->issuer, "Issuer Name", verbose); checkName(&cert->subject, "Subject Name", verbose); if (issuerCert) { SECComparison c = CERT_CompareName(&cert->issuer, &issuerCert->subject); if (c) { printf("PROBLEM: Issuer Name and Subject in Issuing Cert differ\n"); } } /* Check if self-signed */ selfSigned = (CERT_CompareName(&cert->issuer, &cert->subject) == 0); if (selfSigned) { printf("INFO: Certificate is self signed.\n"); } else { printf("INFO: Certificate is NOT self-signed.\n"); } /* Validity time check */ if (CERT_CertTimesValid(cert) == SECSuccess) { printf("INFO: Inside validity period of certificate.\n"); } else { printf("PROBLEM: Not in validity period of certificate.\n"); invalid = 1; } /* Signature check if self-signed */ if (selfSigned && !invalid) { if (rsapubkey->u.rsa.modulus.len) { SECStatus ver; if (verbose) { printf("Checking self signature.\n"); } ver = OurVerifySignedData(signedData, cert); if (ver != SECSuccess) { printf("PROBLEM: Verification of self-signature failed!\n"); } else { printf("INFO: Self-signature verifies ok.\n"); } } else { printf("INFO: Not checking signature due to key problems.\n"); } } else if (!selfSigned && !invalid && issuerCert) { SECStatus ver; ver = OurVerifySignedData(signedData, issuerCert); if (ver != SECSuccess) { printf("PROBLEM: Verification of issuer's signature failed!\n"); } else { printf("INFO: Issuer's signature verifies ok.\n"); } } else { printf("INFO: Not checking signature.\n"); } return 0; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?