]> git.saurik.com Git - apple/securityd.git/blob - tests/testclient.cpp
05b72fd2dea38e374d2ddcc17e0fe31755428c20
[apple/securityd.git] / tests / testclient.cpp
1 /*
2 * Copyright (c) 2000-2001,2004 Apple Computer, Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
7 *
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25
26
27 //
28 // Tester - test driver for securityserver client side.
29 //
30 #include "testclient.h"
31 #include "testutils.h"
32 #include <unistd.h> // getopt(3)
33 #include <set>
34
35
36 //
37 // Global constants
38 //
39 const CssmData null; // zero pointer, zero length constant data
40 const AccessCredentials nullCred; // null credentials
41
42 CSSM_GUID ssguid = { 1,2,3 };
43 CssmSubserviceUid ssuid(ssguid);
44
45
46 //
47 // Local functions
48 //
49 static void usage();
50 static void runtest(char type);
51
52
53 //
54 // Default test set
55 //
56 static char testCodes[] = ".cesaAbdkKt";
57
58
59 //
60 // Main program
61 //
62 int main(int argc, char *argv[])
63 {
64 setbuf(stdout, NULL);
65
66 long ranseq = 0; // random stress test count
67 long ranseed = 1; // random seed for it
68
69 int arg;
70 while ((arg = getopt(argc, argv, "r:v")) != -1) {
71 switch (arg) {
72 case 'r': {
73 ranseq = atoi(optarg);
74 if (const char *colon = strchr(optarg, ':'))
75 ranseed = atoi(colon + 1);
76 else
77 ranseed = getpid() ^ time(NULL);
78 break;
79 }
80 case 'v':
81 verbose = true;
82 break;
83 default:
84 usage();
85 }
86 }
87 if (optind < argc - 1)
88 usage();
89 const char *sequence = argv[optind];
90 if (sequence && !strcmp(sequence, "+"))
91 sequence = testCodes;
92
93 if (ranseq) { // repeated random (stress test) sequence
94 if (!sequence)
95 sequence = testCodes;
96 printf("*** Random stress test: %ld iterations from <%s> with seed=%ld\n",
97 ranseq, sequence, ranseed);
98 srandom(ranseed);
99 int setSize = strlen(sequence);
100 for (long n = 0; n < ranseq; n++) {
101 char type = sequence[random() % setSize];
102 printf("\n[%ld:%c]", n, type);
103 runtest(type);
104 }
105 printf("*** Random test sequence complete.\n");
106 exit(0);
107 } else { // single-pass selected tests sequence
108 if (!sequence)
109 sequence = "."; // default to ping test
110 for (const char *s = sequence; *s; s++)
111 runtest(*s);
112 printf("*** Test sequence complete.\n");
113 exit(0);
114 }
115 }
116
117 void usage()
118 {
119 fprintf(stderr, "Usage: SSTester [-r count[:seed]] [-v] [%s|.|+]\n",
120 testCodes);
121 exit(2);
122 }
123
124
125 //
126 // Run a single type test
127 //
128 void runtest(char type)
129 {
130 try {
131 debug("SStest", "Start test <%c>", type);
132 switch (type) {
133 case '.': // default
134 integrity();
135 break;
136 case '-':
137 adhoc();
138 break;
139 case 'a':
140 acls();
141 break;
142 case 'A':
143 authAcls();
144 break;
145 case 'b':
146 blobs();
147 break;
148 case 'c':
149 codeSigning();
150 break;
151 case 'd':
152 databases();
153 break;
154 case 'e':
155 desEncryption();
156 break;
157 case 'k':
158 keychainAcls();
159 break;
160 case 'K':
161 keyBlobs();
162 break;
163 case 's':
164 signWithRSA();
165 break;
166 case 't':
167 authorizations();
168 break;
169 case 'T':
170 timeouts();
171 break;
172 default:
173 error("Invalid test selection (%c)", type);
174 }
175 printf("** Test step complete.\n");
176 debug("SStest", "End test <%c>", type);
177 } catch (CssmCommonError &err) {
178 error(err, "Unexpected exception");
179 } catch (...) {
180 error("Unexpected system exception");
181 }
182 }
183
184
185 //
186 // Basic integrity test.
187 //
188 void integrity()
189 {
190 ClientSession ss(CssmAllocator::standard(), CssmAllocator::standard());
191
192 printf("* Generating random sample: ");
193 DataBuffer<11> sample;
194 ss.generateRandom(sample);
195 for (uint32 n = 0; n < sample.length(); n++)
196 printf("%.2x", ((unsigned char *)sample)[n]);
197 printf("\n");
198 }
199
200
201 //
202 // Database timeouts
203 // @@@ Incomplete and not satisfactory
204 //
205 void timeouts()
206 {
207 printf("* Database timeout locks test\n");
208 CssmAllocator &alloc = CssmAllocator::standard();
209 ClientSession ss(alloc, alloc);
210
211 DLDbIdentifier dbId1(ssuid, "/tmp/one", NULL);
212 DLDbIdentifier dbId2(ssuid, "/tmp/two", NULL);
213 DBParameters initialParams1 = { 4, false }; // 4 seconds timeout
214 DBParameters initialParams2 = { 8, false }; // 8 seconds timeout
215
216 // credential to set keychain passphrase
217 AutoCredentials pwCred(alloc);
218 StringData password("mumbojumbo");
219 pwCred += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK,
220 new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
221 new(alloc) ListElement(password));
222
223 DbHandle db1 = ss.createDb(dbId1, &pwCred, NULL, initialParams1);
224 DbHandle db2 = ss.createDb(dbId2, &pwCred, NULL, initialParams2);
225 detail("Databases created");
226
227 // generate a key
228 const CssmCryptoData seed(StringData("rain tonight"));
229 FakeContext genContext(CSSM_ALGCLASS_KEYGEN, CSSM_ALGID_DES,
230 &::Context::Attr(CSSM_ATTRIBUTE_KEY_LENGTH, 64),
231 &::Context::Attr(CSSM_ATTRIBUTE_SEED, seed),
232 NULL);
233 KeyHandle key;
234 CssmKey::Header header;
235 ss.generateKey(db1, genContext, CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
236 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT,
237 /*cred*/NULL, NULL, key, header);
238 ss.generateKey(db2, genContext, CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
239 CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT,
240 /*cred*/NULL, NULL, key, header);
241 detail("Keys generated and stored");
242
243 // credential to provide keychain passphrase
244 AutoCredentials pwCred2(alloc);
245 pwCred += TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
246 new(alloc) ListElement(CSSM_SAMPLE_TYPE_PASSWORD),
247 new(alloc) ListElement(password));
248
249 //@@@ incomplete
250 ss.releaseDb(db1);
251 ss.releaseDb(db2);
252 }
253
254
255 //
256 // Ad-hoc test area.
257 // Used for whatever is needed at the moment...
258 //
259 void adhoc()
260 {
261 printf("* Ad-hoc test sequence (now what does it do *this* time?)\n");
262
263 Cssm cssm1;
264 Cssm cssm2;
265 cssm1->init();
266 cssm2->init();
267
268 {
269 Module m1(gGuidAppleCSP, cssm1);
270 Module m2(gGuidAppleCSP, cssm2);
271 CSP r1(m1);
272 CSP r2(m2);
273
274 Digest d1(r1, CSSM_ALGID_SHA1);
275 Digest d2(r2, CSSM_ALGID_SHA1);
276
277 StringData foo("foo de doo da blech");
278 DataBuffer<30> digest1, digest2;
279 d1.digest(foo, digest1);
280 d2.digest(foo, digest2);
281 if (digest1 == digest2)
282 detail("Digests verify");
283 else
284 error("Digests mismatch");
285 }
286
287 cssm1->terminate();
288 cssm2->terminate();
289 }