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