2 * Copyright (c) 2000-2001,2004 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
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
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.
23 * @APPLE_LICENSE_HEADER_END@
28 // Tester - test driver for securityserver client side.
30 #include "testclient.h"
31 #include "testutils.h"
32 #include <unistd.h> // getopt(3)
39 const CssmData null
; // zero pointer, zero length constant data
40 const AccessCredentials nullCred
; // null credentials
42 CSSM_GUID ssguid
= { 1,2,3 };
43 CssmSubserviceUid
ssuid(ssguid
);
50 static void runtest(char type
);
56 static char testCodes
[] = ".cesaAbdkKt";
62 int main(int argc
, char *argv
[])
66 long ranseq
= 0; // random stress test count
67 long ranseed
= 1; // random seed for it
70 while ((arg
= getopt(argc
, argv
, "r:v")) != -1) {
73 ranseq
= atoi(optarg
);
74 if (const char *colon
= strchr(optarg
, ':'))
75 ranseed
= atoi(colon
+ 1);
77 ranseed
= getpid() ^ time(NULL
);
87 if (optind
< argc
- 1)
89 const char *sequence
= argv
[optind
];
90 if (sequence
&& !strcmp(sequence
, "+"))
93 if (ranseq
) { // repeated random (stress test) sequence
96 printf("*** Random stress test: %ld iterations from <%s> with seed=%ld\n",
97 ranseq
, sequence
, 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
);
105 printf("*** Random test sequence complete.\n");
107 } else { // single-pass selected tests sequence
109 sequence
= "."; // default to ping test
110 for (const char *s
= sequence
; *s
; s
++)
112 printf("*** Test sequence complete.\n");
119 fprintf(stderr
, "Usage: SSTester [-r count[:seed]] [-v] [%s|.|+]\n",
126 // Run a single type test
128 void runtest(char type
)
131 debug("SStest", "Start test <%c>", type
);
173 error("Invalid test selection (%c)", type
);
175 printf("** Test step complete.\n");
176 debug("SStest", "End test <%c>", type
);
177 } catch (CssmCommonError
&err
) {
178 error(err
, "Unexpected exception");
180 error("Unexpected system exception");
186 // Basic integrity test.
190 ClientSession
ss(CssmAllocator::standard(), CssmAllocator::standard());
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
]);
203 // @@@ Incomplete and not satisfactory
207 printf("* Database timeout locks test\n");
208 CssmAllocator
&alloc
= CssmAllocator::standard();
209 ClientSession
ss(alloc
, alloc
);
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
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
));
223 DbHandle db1
= ss
.createDb(dbId1
, &pwCred
, NULL
, initialParams1
);
224 DbHandle db2
= ss
.createDb(dbId2
, &pwCred
, NULL
, initialParams2
);
225 detail("Databases created");
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
),
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");
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
));
257 // Used for whatever is needed at the moment...
261 printf("* Ad-hoc test sequence (now what does it do *this* time?)\n");
269 Module
m1(gGuidAppleCSP
, cssm1
);
270 Module
m2(gGuidAppleCSP
, cssm2
);
274 Digest
d1(r1
, CSSM_ALGID_SHA1
);
275 Digest
d2(r2
, CSSM_ALGID_SHA1
);
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");
284 error("Digests mismatch");