]>
Commit | Line | Data |
---|---|---|
d8f41ccd A |
1 | /* |
2 | * certsFromDb.cpp - extract all certs from a DB, write to files or parse to stdout. | |
3 | */ | |
4 | #include <security_cdsa_utils/cuFileIo.h> | |
5 | #include <utilLib/common.h> | |
6 | #include <utilLib/cspwrap.h> | |
7 | #include <security_cdsa_utils/cuPrintCert.h> | |
8 | #include <stdlib.h> | |
9 | #include <stdio.h> | |
10 | #include <string.h> | |
11 | #include <Security/cssm.h> | |
12 | #include <string.h> | |
13 | ||
14 | static void usage(char **argv) | |
15 | { | |
16 | printf("Usage: \n"); | |
17 | printf(" %s keychainFile f certFileBase [option...]\n", argv[0]); | |
18 | printf(" %s keychainFile p(arse) [option...]\n", argv[0]); | |
19 | printf("Options:\n"); | |
20 | printf(" R fetch CRLs, not certs\n"); | |
21 | printf(" P pause for MallocDebug one each item\n"); | |
22 | printf(" q Quiet\n"); | |
23 | exit(1); | |
24 | } | |
25 | ||
26 | int main(int argc, char **argv) | |
27 | { | |
28 | int rtn; | |
29 | CSSM_DL_DB_HANDLE dlDbHand; | |
30 | CSSM_RETURN crtn; | |
31 | char filePath[300]; | |
32 | unsigned certNum=0; | |
33 | CSSM_QUERY query; | |
34 | CSSM_DB_UNIQUE_RECORD_PTR record = NULL; | |
35 | CSSM_HANDLE resultHand; | |
36 | CSSM_DATA theData = {0, NULL}; | |
37 | char *fileBase = NULL; | |
38 | CSSM_BOOL doPause = CSSM_FALSE; | |
39 | CSSM_BOOL isCrl = CSSM_FALSE; | |
40 | CSSM_BOOL quiet = CSSM_FALSE; | |
41 | int optarg = 3; | |
42 | ||
43 | if(argc < 3) { | |
44 | usage(argv); | |
45 | } | |
46 | switch(argv[2][0]) { | |
47 | case 'f': | |
48 | if(argc < 4) { | |
49 | usage(argv); | |
50 | } | |
51 | fileBase = argv[3]; | |
52 | optarg = 4; | |
53 | break; | |
54 | case 'p': | |
55 | /* default, parse mode */ | |
56 | break; | |
57 | default: | |
58 | usage(argv); | |
59 | } | |
60 | for(int arg=optarg; arg<argc; arg++) { | |
61 | switch(argv[arg][0]) { | |
62 | case 'q': | |
63 | quiet = CSSM_TRUE; | |
64 | break; | |
65 | case 'P': | |
66 | doPause = CSSM_TRUE; | |
67 | break; | |
68 | case 'R': | |
69 | isCrl = CSSM_TRUE; | |
70 | break; | |
71 | default: | |
72 | usage(argv); | |
73 | } | |
74 | } | |
75 | ||
76 | /* attach to specified keychain as a DL/DB */ | |
77 | dlDbHand.DLHandle = dlStartup(); | |
78 | if(dlDbHand.DLHandle == 0) { | |
79 | exit(1); | |
80 | } | |
81 | crtn = dbCreateOpen(dlDbHand.DLHandle, argv[1], | |
82 | CSSM_FALSE, // doCreate | |
83 | CSSM_FALSE, // deleteExist | |
84 | NULL, // pwd | |
85 | &dlDbHand.DBHandle); | |
86 | if(crtn) { | |
87 | exit(1); | |
88 | } | |
89 | ||
90 | loopTop: | |
91 | /* search by record type, no predicates, no returned attributes. We just want | |
92 | * the data. */ | |
93 | query.RecordType = isCrl ? CSSM_DL_DB_RECORD_X509_CRL : | |
94 | CSSM_DL_DB_RECORD_X509_CERTIFICATE; | |
95 | query.Conjunctive = CSSM_DB_NONE; | |
96 | query.NumSelectionPredicates = 0; | |
97 | query.SelectionPredicate = NULL; | |
98 | query.QueryLimits.TimeLimit = 0; // FIXME - meaningful? | |
99 | query.QueryLimits.SizeLimit = 1; // FIXME - meaningful? | |
100 | query.QueryFlags = CSSM_QUERY_RETURN_DATA; // FIXME - used? | |
101 | ||
102 | crtn = CSSM_DL_DataGetFirst(dlDbHand, | |
103 | &query, | |
104 | &resultHand, | |
105 | NULL, | |
106 | &theData, | |
107 | &record); | |
108 | if(crtn) { | |
109 | printError("CSSM_DL_DataGetFirst", crtn); | |
110 | printf("Error fetching certs from %s. Aborting.\n", argv[1]); | |
111 | exit(1); | |
112 | } | |
113 | CSSM_DL_FreeUniqueRecord(dlDbHand, record); | |
114 | ||
115 | if(doPause) { | |
116 | fpurge(stdin); | |
117 | printf("set up MallocDebug, then any key to continue: "); | |
118 | getchar(); | |
119 | } | |
120 | if(fileBase) { | |
121 | /* write the data */ | |
122 | sprintf(filePath, "%s_%d", fileBase, certNum); | |
123 | rtn = writeFile(filePath, theData.Data, theData.Length); | |
124 | if(rtn == 0) { | |
125 | if(!quiet) { | |
126 | printf("...wrote %u bytes to %s\n", (unsigned)theData.Length, | |
127 | filePath); | |
128 | } | |
129 | } | |
130 | else { | |
131 | printf("***Error writing %s: %s\n", filePath, strerror(rtn)); | |
132 | exit(1); | |
133 | } | |
134 | } | |
135 | else { | |
136 | if(isCrl) { | |
137 | printf("CRL 0:\n"); | |
138 | printCrl(theData.Data, theData.Length, CSSM_FALSE); | |
139 | } | |
140 | else { | |
141 | printf("Cert 0:\n"); | |
142 | printCert(theData.Data, theData.Length, CSSM_FALSE); | |
143 | } | |
144 | } | |
145 | CSSM_FREE(theData.Data); | |
146 | certNum++; | |
147 | ||
148 | /* again */ | |
149 | for(;;) { | |
150 | crtn = CSSM_DL_DataGetNext(dlDbHand, | |
151 | resultHand, | |
152 | NULL, | |
153 | &theData, | |
154 | &record); | |
155 | switch(crtn) { | |
156 | case CSSM_OK: | |
157 | if(fileBase) { | |
158 | sprintf(filePath, "%s_%d", fileBase, certNum); | |
159 | rtn = writeFile(filePath, theData.Data, theData.Length); | |
160 | if(rtn == 0) { | |
161 | if(!quiet) { | |
162 | printf("...wrote %u bytes to %s\n", (unsigned)theData.Length, | |
163 | filePath); | |
164 | } | |
165 | } | |
166 | else { | |
167 | printf("***Error writing %s: %s\n", filePath, strerror(rtn)); | |
168 | exit(1); | |
169 | } | |
170 | } | |
171 | else { | |
172 | if(isCrl) { | |
173 | printf("CRL 0:\n"); | |
174 | printCrl(theData.Data, theData.Length, CSSM_FALSE); | |
175 | } | |
176 | else { | |
177 | printf("Cert %u:\n", certNum); | |
178 | printCert(theData.Data, theData.Length, CSSM_FALSE); | |
179 | } | |
180 | } | |
181 | certNum++; | |
182 | CSSM_FREE(theData.Data); | |
183 | CSSM_DL_FreeUniqueRecord(dlDbHand, record); | |
184 | break; // and go again | |
185 | case CSSMERR_DL_ENDOFDATA: | |
186 | /* normal termination */ | |
187 | break; | |
188 | default: | |
189 | printError("DataGetNext", crtn); | |
190 | break; | |
191 | } | |
192 | if(crtn != CSSM_OK) { | |
193 | break; | |
194 | } | |
195 | } | |
196 | CSSM_DL_DataAbortQuery(dlDbHand, resultHand); | |
197 | if(doPause) { | |
198 | fpurge(stdin); | |
199 | printf("End of loop, l to loop, enything else to end: "); | |
200 | char c = getchar(); | |
201 | if(c == 'l') { | |
202 | goto loopTop; | |
203 | } | |
204 | } | |
205 | if(!quiet) { | |
206 | printf("...%d %s extracted.\n", certNum, isCrl ? "CRLs" : "certs"); | |
207 | } | |
208 | return 0; | |
209 | } | |
210 |