+++ /dev/null
-/*
- * Attempt to decode either one file, or every file in cwd,
- * as a cert. Used to study vulnerability to NISCC cert DOS attacks.
- */
-#include <Security/SecAsn1Coder.h>
-#include <Security/X509Templates.h>
-#include <security_cdsa_utils/cuFileIo.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <strings.h>
-
-static void usage(char **argv)
-{
- printf("usage: %s [-l(oop))] [certFile]\n", argv[0]);
- exit(1);
-}
-
-/*
- * Known file names to NOT parse
- */
-static const char *skipTheseFiles[] =
-{
- /* standard entries */
- ".",
- "..",
- "CVS",
- ".cvsignore",
- /* the certs we know crash */
- #if 0
- "00000668",
- "00000681",
- "00001980",
- "00002040",
- "00002892",
- "00007472",
- "00008064",
- "00008656",
- "00009840",
- "00010432",
- "00011614", // trouble somewhere in this neighborhood
- "00011615",
- "00011616",
- #endif
- NULL
-};
-
-/* returns false if specified fileName is in skipTheseFiles[] */
-static bool shouldWeParse(
- const char *fileName) // C string
-{
- for(const char **stf=skipTheseFiles; *stf!=NULL; stf++) {
- const char *tf = *stf;
- if(!strcmp(fileName, *stf)) {
- return false;
- }
- }
- return true;
-}
-
-/*
- * Just try to decode - if SecAsn1Decode returns, good 'nuff.
- * Returns true if it does (i.e. ignore decode error; we're trying
- * to detect a crash when the decoder should return an error).
- */
-bool decodeCert(
- const void *certData,
- size_t certDataLen)
-{
- SecAsn1CoderRef coder = NULL;
- NSS_Certificate nssCert;
- NSS_SignedCertOrCRL certOrCrl;
-
- SecAsn1CoderCreate(&coder);
-
- /* first the full decode */
- memset(&nssCert, 0, sizeof(nssCert));
- SecAsn1Decode(coder, certData, certDataLen, kSecAsn1SignedCertTemplate, &nssCert);
-
- /* now the "just TBS and sig" decode - this is actually harder
- * due to nested SEC_ASN1_SAVE ops */
- memset(&certOrCrl, 0, sizeof(NSS_SignedCertOrCRL));
- SecAsn1Decode(coder, certData, certDataLen, kSecAsn1SignedCertOrCRLTemplate, &certOrCrl);
-
- SecAsn1CoderRelease(coder);
- return true;
-}
-
-int main(int argc, char **argv)
-{
- bool quiet = false;
- unsigned char *certData;
- unsigned certDataLen;
- bool loop = false;
- int filearg = 1;
-
- if(argc > 3 ) {
- usage(argv);
- }
- if((argc > 1) && (argv[1][0] == '-')) {
- switch(argv[1][1]) {
- case 'l':
- loop = true;
- break;
- default:
- usage(argv);
- }
- filearg++;
- argc--;
- }
- if(argc == 2) {
- /* read & parse one file */
- char *oneFile = argv[filearg];
- if(readFile(oneFile, &certData, &certDataLen)) {
- printf("\n***Error reading file %s. Aborting.\n", oneFile);
- exit(1);
- }
- do {
- if(!quiet) {
- printf("...%s", oneFile);
- fflush(stdout);
- }
- if(!decodeCert(certData, certDataLen)) {
- printf("\n***GOT AN EXCEPTION ON %s\n", oneFile);
- exit(1);
- }
- } while(loop);
- free(certData);
- exit(0);
- }
- DIR *dir = opendir(".");
- if(dir == NULL) {
- printf("Huh? Can't open . as a directory.\n");
- exit(1);
- }
- struct dirent *de = readdir(dir);
- while(de != NULL) {
- char filename[MAXNAMLEN + 1];
- memmove(filename, de->d_name, de->d_namlen);
- filename[de->d_namlen] = '\0';
- if(shouldWeParse(filename)) {
- if(!quiet) {
- printf("...%s", filename);
- fflush(stdout);
- }
- if(readFile(filename, &certData, &certDataLen)) {
- printf("\n***Error reading file %s. Aborting.\n", filename);
- exit(1);
- }
- if(!decodeCert(certData, certDataLen)) {
- printf("\n***GOT AN EXCEPTION ON %s\n", filename);
- exit(1);
- }
- free(certData);
- }
- de = readdir(dir);
- }
- closedir(dir);
- printf("\ncertDecode did not crash.\n");
- return 0;
-}
-