2 * Copyright (c) 2000-2001,2003-2004 Apple Computer, Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
26 // Tester - test driver for securityserver client side.
28 #include "testclient.h"
29 #include "testutils.h"
30 #include <unistd.h> // getopt(3)
37 const CssmData null
; // zero pointer, zero length constant data
38 const AccessCredentials nullCred
; // null credentials
40 CSSM_GUID ssguid
= { 1,2,3 };
41 CssmSubserviceUid
ssuid(ssguid
);
48 static void runtest(char type
);
54 static char testCodes
[] = ".cesaAbdkKt";
60 int main(int argc
, char *argv
[])
64 long ranseq
= 0; // random stress test count
65 long ranseed
= 1; // random seed for it
68 while ((arg
= getopt(argc
, argv
, "r:v")) != -1) {
71 ranseq
= atoi(optarg
);
72 if (const char *colon
= strchr(optarg
, ':'))
73 ranseed
= atoi(colon
+ 1);
75 ranseed
= getpid() ^ time(NULL
);
85 if (optind
< argc
- 1)
87 const char *sequence
= argv
[optind
];
88 if (sequence
&& !strcmp(sequence
, "+"))
91 if (ranseq
) { // repeated random (stress test) sequence
94 printf("*** Random stress test: %ld iterations from <%s> with seed=%ld\n",
95 ranseq
, sequence
, ranseed
);
97 int setSize
= strlen(sequence
);
98 for (long n
= 0; n
< ranseq
; n
++) {
99 char type
= sequence
[random() % setSize
];
100 printf("\n[%ld:%c]", n
, type
);
103 printf("*** Random test sequence complete.\n");
105 } else { // single-pass selected tests sequence
107 sequence
= "."; // default to ping test
108 for (const char *s
= sequence
; *s
; s
++)
110 printf("*** Test sequence complete.\n");
117 fprintf(stderr
, "Usage: SSTester [-r count[:seed]] [-v] [%s|.|+]\n",
124 // Run a single type test
126 void runtest(char type
)
129 debug("SStest", "Start test <%c>", type
);
171 error("Invalid test selection (%c)", type
);
173 printf("** Test step complete.\n");
174 debug("SStest", "End test <%c>", type
);
175 } catch (CssmCommonError
&err
) {
176 error(err
, "Unexpected exception");
178 error("Unexpected system exception");
184 // Basic integrity test.
188 ClientSession
ss(CssmAllocator::standard(), CssmAllocator::standard());
190 printf("* Generating random sample: ");
191 DataBuffer
<11> sample
;
192 ss
.generateRandom(sample
);
193 for (uint32 n
= 0; n
< sample
.length(); n
++)
194 printf("%.2x", ((unsigned char *)sample
)[n
]);
201 // @@@ Incomplete and not satisfactory
205 printf("* Database timeout locks test\n");
206 CssmAllocator
&alloc
= CssmAllocator::standard();
207 ClientSession
ss(alloc
, alloc
);
209 DLDbIdentifier
dbId1(ssuid
, "/tmp/one", NULL
);
210 DLDbIdentifier
dbId2(ssuid
, "/tmp/two", NULL
);
211 DBParameters initialParams1
= { 4, false }; // 4 seconds timeout
212 DBParameters initialParams2
= { 8, false }; // 8 seconds timeout
214 // credential to set keychain passphrase
215 AutoCredentials
pwCred(alloc
);
216 StringData
password("mumbojumbo");
217 pwCred
+= TypedList(alloc
, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK
,
218 new(alloc
) ListElement(CSSM_SAMPLE_TYPE_PASSWORD
),
219 new(alloc
) ListElement(password
));
221 DbHandle db1
= ss
.createDb(dbId1
, &pwCred
, NULL
, initialParams1
);
222 DbHandle db2
= ss
.createDb(dbId2
, &pwCred
, NULL
, initialParams2
);
223 detail("Databases created");
226 const CssmCryptoData
seed(StringData("rain tonight"));
227 FakeContext
genContext(CSSM_ALGCLASS_KEYGEN
, CSSM_ALGID_DES
,
228 &::Context::Attr(CSSM_ATTRIBUTE_KEY_LENGTH
, 64),
229 &::Context::Attr(CSSM_ATTRIBUTE_SEED
, seed
),
232 CssmKey::Header header
;
233 ss
.generateKey(db1
, genContext
, CSSM_KEYUSE_ENCRYPT
| CSSM_KEYUSE_DECRYPT
,
234 CSSM_KEYATTR_RETURN_REF
| CSSM_KEYATTR_PERMANENT
,
235 /*cred*/NULL
, NULL
, key
, header
);
236 ss
.generateKey(db2
, genContext
, CSSM_KEYUSE_ENCRYPT
| CSSM_KEYUSE_DECRYPT
,
237 CSSM_KEYATTR_RETURN_REF
| CSSM_KEYATTR_PERMANENT
,
238 /*cred*/NULL
, NULL
, key
, header
);
239 detail("Keys generated and stored");
241 // credential to provide keychain passphrase
242 AutoCredentials
pwCred2(alloc
);
243 pwCred
+= TypedList(alloc
, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK
,
244 new(alloc
) ListElement(CSSM_SAMPLE_TYPE_PASSWORD
),
245 new(alloc
) ListElement(password
));
255 // Used for whatever is needed at the moment...
259 printf("* Ad-hoc test sequence (now what does it do *this* time?)\n");
267 Module
m1(gGuidAppleCSP
, cssm1
);
268 Module
m2(gGuidAppleCSP
, cssm2
);
272 Digest
d1(r1
, CSSM_ALGID_SHA1
);
273 Digest
d2(r2
, CSSM_ALGID_SHA1
);
275 StringData
foo("foo de doo da blech");
276 DataBuffer
<30> digest1
, digest2
;
277 d1
.digest(foo
, digest1
);
278 d2
.digest(foo
, digest2
);
279 if (digest1
== digest2
)
280 detail("Digests verify");
282 error("Digests mismatch");