2  * Attempt to decode either one file, or every file in cwd, 
   3  * as a cert. Used to study vulnerability to NISCC cert DOS attacks.  
   5 #include <Security/SecAsn1Coder.h> 
   6 #include <Security/X509Templates.h> 
   7 #include <security_cdsa_utils/cuFileIo.h> 
  14 static void usage(char **argv
) 
  16         printf("usage: %s [-l(oop))] [certFile]\n", argv
[0]); 
  21  * Known file names to NOT parse 
  23 static const char *skipTheseFiles
[] =  
  25         /* standard entries */ 
  30         /* the certs we know crash */ 
  42         "00011614",     // trouble somewhere in this neighborhood 
  49 /* returns false if specified fileName is in skipTheseFiles[] */ 
  50 static bool shouldWeParse( 
  51         const char *fileName
)           // C string 
  53         for(const char **stf
=skipTheseFiles
; *stf
!=NULL
; stf
++) {  
  54                 const char *tf 
= *stf
; 
  55                 if(!strcmp(fileName
, *stf
)) { 
  63  * Just try to decode - if SecAsn1Decode returns, good 'nuff. 
  64  * Returns true if it does (i.e. ignore decode error; we're trying 
  65  * to detect a crash when the decoder should return an error). 
  71         SecAsn1CoderRef coder 
= NULL
; 
  72         NSS_Certificate nssCert
; 
  73         NSS_SignedCertOrCRL certOrCrl
; 
  75         SecAsn1CoderCreate(&coder
); 
  77         /* first the full decode */ 
  78         memset(&nssCert
, 0, sizeof(nssCert
)); 
  79         SecAsn1Decode(coder
, certData
, certDataLen
,     kSecAsn1SignedCertTemplate
, &nssCert
); 
  81         /* now the "just TBS and sig" decode - this is actually harder 
  82          * due to nested SEC_ASN1_SAVE ops */ 
  83         memset(&certOrCrl
, 0, sizeof(NSS_SignedCertOrCRL
)); 
  84         SecAsn1Decode(coder
, certData
, certDataLen
,     kSecAsn1SignedCertOrCRLTemplate
, &certOrCrl
); 
  86         SecAsn1CoderRelease(coder
); 
  90 int main(int argc
, char **argv
) 
  93         unsigned char *certData
; 
 101         if((argc 
> 1) && (argv
[1][0] == '-')) { 
 113                 /* read & parse one file */ 
 114                 char *oneFile 
= argv
[filearg
]; 
 115                 if(readFile(oneFile
, &certData
, &certDataLen
)) { 
 116                         printf("\n***Error reading file %s. Aborting.\n", oneFile
); 
 121                                 printf("...%s", oneFile
); 
 124                         if(!decodeCert(certData
, certDataLen
)) { 
 125                                 printf("\n***GOT AN EXCEPTION ON %s\n", oneFile
); 
 132         DIR *dir 
= opendir("."); 
 134                 printf("Huh? Can't open . as a directory.\n"); 
 137         struct dirent 
*de 
= readdir(dir
); 
 139                 char filename
[MAXNAMLEN 
+ 1]; 
 140                 memmove(filename
, de
->d_name
, de
->d_namlen
); 
 141                 filename
[de
->d_namlen
] = '\0'; 
 142                 if(shouldWeParse(filename
)) { 
 144                                 printf("...%s", filename
); 
 147                         if(readFile(filename
, &certData
, &certDataLen
)) { 
 148                                 printf("\n***Error reading file %s. Aborting.\n", filename
); 
 151                         if(!decodeCert(certData
, certDataLen
)) { 
 152                                 printf("\n***GOT AN EXCEPTION ON %s\n", filename
); 
 160         printf("\ncertDecode did not crash.\n");