]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/NISCC/TLS_SSL/nisccCertVerify/nisccCertVerify.cpp
Security-57031.10.10.tar.gz
[apple/security.git] / SecurityTests / clxutils / NISCC / TLS_SSL / nisccCertVerify / nisccCertVerify.cpp
1 /*
2 * Attempt to verify either one cert file, or every file in cwd,
3 * with specified issuer cert. Used to study vulnerability to
4 * NISCC cert DOS attacks.
5 */
6 #include <Security/Security.h>
7 #include <Security/cuFileIo.h>
8 #include <Security/cuCdsaUtils.h>
9 #include <sys/types.h>
10 #include <dirent.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13
14 static void usage(char **argv)
15 {
16 printf("usage: %s [-v(erbose)] issuerCertFile [certFile]\n", argv[0]);
17 exit(1);
18 }
19
20 /*
21 * Known file names to NOT parse
22 */
23 static const char *skipTheseFiles[] =
24 {
25 /* standard entries */
26 ".",
27 "..",
28 "CVS",
29 ".cvsignore",
30 NULL
31 };
32
33 /* returns false if specified fileName is in skipTheseFiles[] */
34 static bool shouldWeParse(
35 const char *fileName) // C string
36 {
37 for(const char **stf=skipTheseFiles; *stf!=NULL; stf++) {
38 const char *tf = *stf;
39 if(!strcmp(fileName, *stf)) {
40 return false;
41 }
42 }
43 return true;
44 }
45
46 /*
47 * Just try to verify. Returns true on any reasonable outcome.
48 */
49 static bool vfyCert(
50 CSSM_CL_HANDLE clHand,
51 CSSM_CC_HANDLE ccHand,
52 const unsigned char *certData,
53 unsigned certDataLen,
54 bool verbose)
55 {
56 CSSM_DATA cdata = {certDataLen, (uint8 *)certData};
57 CSSM_RETURN crtn;
58
59 crtn = CSSM_CL_CertVerifyWithKey(clHand, ccHand, &cdata);
60
61 /* hard-coded list of acceptable outcomes */
62 switch(crtn) {
63 case CSSM_OK:
64 if(verbose) {
65 printf("-ok-");
66 }
67 return true;
68 case CSSMERR_CL_VERIFICATION_FAILURE:
69 if(verbose) {
70 printf("-vfy_fail-");
71 }
72 return true;
73 case CSSMERR_CL_UNKNOWN_FORMAT:
74 if(verbose) {
75 printf("-format-");
76 }
77 return true;
78 default:
79 cuPrintError("CSSM_CL_CertVerifyWithKey", crtn);
80 return false;
81 }
82 return true;
83 }
84
85 int main(int argc, char **argv)
86 {
87 bool quiet = false;
88 unsigned char *certData;
89 unsigned certDataLen;
90 unsigned char *issuerData;
91 unsigned issuerDataLen;
92 DIR *dir;
93 struct dirent *de;
94 bool verbose = false;
95 int filearg = 1;
96
97 if((argc < 2 ) || (argc > 4)) {
98 usage(argv);
99 }
100 if(argv[1][0] == '-') {
101 switch(argv[1][1]) {
102 case 'v':
103 verbose = true;
104 break;
105 default:
106 usage(argv);
107 }
108 filearg++;
109 argc--;
110 }
111
112 CSSM_CSP_HANDLE cspHand = cuCspStartup(CSSM_TRUE);
113 CSSM_CL_HANDLE clHand = cuClStartup();
114 if((cspHand == 0) || (clHand == 0)) {
115 exit(1);
116 }
117
118 /* read issuer cert, extract its public key for quick verify */
119 char *fn = argv[filearg++];
120 if(readFile(fn, &issuerData, &issuerDataLen)) {
121 printf("\n***Error reading file %s. Aborting.\n", fn);
122 exit(1);
123 }
124 CSSM_DATA issuerCert = {issuerDataLen, issuerData};
125 CSSM_KEY_PTR issuerPubKey;
126 CSSM_RETURN crtn = CSSM_CL_CertGetKeyInfo(clHand, &issuerCert,
127 &issuerPubKey);
128 if(crtn) {
129 cuPrintError("CSSM_CL_CertGetKeyInfo", crtn);
130 exit(1);
131 }
132
133 /* a reusable signature context */
134 CSSM_CC_HANDLE ccHand;
135 crtn = CSSM_CSP_CreateSignatureContext(cspHand,
136 CSSM_ALGID_SHA1WithRSA,
137 NULL, // AccessCred
138 issuerPubKey,
139 &ccHand);
140 if(crtn) {
141 cuPrintError("CSSM_CSP_CreateSignatureContext", crtn);
142 exit(1);
143 }
144
145 if(argc == 3) {
146 /* read & parse one file */
147 char *fn = argv[filearg++];
148 if(!quiet) {
149 printf("...reading %s\n", fn);
150 }
151 if(readFile(fn, &certData, &certDataLen)) {
152 printf("\n***Error reading file %s. Aborting.\n", fn);
153 exit(1);
154 }
155 if(!vfyCert(clHand, ccHand, certData, certDataLen, verbose)) {
156 printf("\n***GOT AN EXCEPTION ON %s\n", fn);
157 exit(1);
158 }
159 goto done;
160 }
161 dir = opendir(".");
162 if(dir == NULL) {
163 printf("Huh? Can't open . as a directory.\n");
164 exit(1);
165 }
166 de = readdir(dir);
167 while(de != NULL) {
168 char filename[MAXNAMLEN + 1];
169 memmove(filename, de->d_name, de->d_namlen);
170 filename[de->d_namlen] = '\0';
171 if(shouldWeParse(filename)) {
172 if(!quiet) {
173 printf("...%s", filename);
174 fflush(stdout);
175 }
176 if(readFile(filename, &certData, &certDataLen)) {
177 printf("\n***Error reading file %s. Aborting.\n", filename);
178 exit(1);
179 }
180 if(!vfyCert(clHand, ccHand, certData, certDataLen, verbose)) {
181 printf("\n***GOT AN EXCEPTION ON %s\n", filename);
182 exit(1);
183 }
184 free(certData);
185 }
186 de = readdir(dir);
187 }
188 closedir(dir);
189 done:
190 printf("\nisccCertVerify did not crash.\n");
191 free(issuerData);
192 return 0;
193 }
194