2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 // Tester - test driver for securityserver client side.
22 #include "testclient.h"
23 #include "testutils.h"
24 #include <unistd.h> // getopt(3)
31 const CssmData null
; // zero pointer, zero length constant data
32 const AccessCredentials nullCred
; // null credentials
34 CSSM_GUID ssguid
= { 1,2,3 };
35 CssmSubserviceUid
ssuid(ssguid
);
42 static void runtest(char type
);
48 static char testCodes
[] = ".cesaAbdkKt";
54 int main(int argc
, char *argv
[])
58 long ranseq
= 0; // random stress test count
59 long ranseed
= 1; // random seed for it
62 while ((arg
= getopt(argc
, argv
, "r:v")) != -1) {
65 ranseq
= atoi(optarg
);
66 if (const char *colon
= strchr(optarg
, ':'))
67 ranseed
= atoi(colon
+ 1);
69 ranseed
= getpid() ^ time(NULL
);
79 if (optind
< argc
- 1)
81 const char *sequence
= argv
[optind
];
82 if (sequence
&& !strcmp(sequence
, "+"))
85 if (ranseq
) { // repeated random (stress test) sequence
88 printf("*** Random stress test: %ld iterations from <%s> with seed=%ld\n",
89 ranseq
, sequence
, 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
);
97 printf("*** Random test sequence complete.\n");
99 } else { // single-pass selected tests sequence
101 sequence
= "."; // default to ping test
102 for (const char *s
= sequence
; *s
; s
++)
104 printf("*** Test sequence complete.\n");
111 fprintf(stderr
, "Usage: SSTester [-r count[:seed]] [-v] [%s|.|+]\n",
118 // Run a single type test
120 void runtest(char type
)
123 debug("SStest", "Start test <%c>", type
);
165 error("Invalid test selection (%c)", type
);
167 printf("** Test step complete.\n");
168 debug("SStest", "End test <%c>", type
);
169 } catch (CssmCommonError
&err
) {
170 error(err
, "Unexpected exception");
172 error("Unexpected system exception");
178 // Basic integrity test.
182 ClientSession
ss(CssmAllocator::standard(), CssmAllocator::standard());
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
]);
195 // @@@ Incomplete and not satisfactory
199 printf("* Database timeout locks test\n");
200 CssmAllocator
&alloc
= CssmAllocator::standard();
201 ClientSession
ss(alloc
, alloc
);
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
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
));
215 DbHandle db1
= ss
.createDb(dbId1
, &pwCred
, NULL
, initialParams1
);
216 DbHandle db2
= ss
.createDb(dbId2
, &pwCred
, NULL
, initialParams2
);
217 detail("Databases created");
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
),
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");
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
));
249 // Used for whatever is needed at the moment...
253 printf("* Ad-hoc test sequence (now what does it do *this* time?)\n");
261 Module
m1(gGuidAppleCSP
, cssm1
);
262 Module
m2(gGuidAppleCSP
, cssm2
);
266 Digest
d1(r1
, CSSM_ALGID_SHA1
);
267 Digest
d2(r2
, CSSM_ALGID_SHA1
);
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");
276 error("Digests mismatch");