]> git.saurik.com Git - apple/security.git/blob - SecurityServer/tests/testutils.cpp
Security-29.tar.gz
[apple/security.git] / SecurityServer / tests / testutils.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 // testutils - utilities for unit test drivers
21 //
22 #include "testutils.h"
23
24 using namespace CssmClient;
25
26 bool verbose = false;
27
28
29 //
30 // Error and diagnostic drivers
31 //
32 void error(const char *msg = NULL, ...)
33 {
34 if (msg) {
35 va_list args;
36 va_start(args, msg);
37 vfprintf(stderr, msg, args);
38 va_end(args);
39 putc('\n', stderr);
40 }
41 abort();
42 }
43
44 void error(const CssmCommonError &err, const char *msg = NULL, ...)
45 {
46 if (msg) {
47 va_list args;
48 va_start(args, msg);
49 vfprintf(stderr, msg, args);
50 va_end(args);
51 fprintf(stderr, ": %s", cssmErrorString(err.cssmError()).c_str());
52 putc('\n', stderr);
53 }
54 abort();
55 }
56
57 void detail(const char *msg = NULL, ...)
58 {
59 if (verbose) {
60 va_list args;
61 va_start(args, msg);
62 vfprintf(stdout, msg, args);
63 va_end(args);
64 putc('\n', stdout);
65 }
66 }
67
68 void detail(const CssmCommonError &err, const char *msg)
69 {
70 if (verbose)
71 printf("%s (ok): %s\n", msg, cssmErrorString(err).c_str());
72 }
73
74 void prompt(const char *msg)
75 {
76 if (isatty(fileno(stdin)))
77 printf("[%s]", msg);
78 }
79
80 void prompt()
81 {
82 if (isatty(fileno(stdin)))
83 printf(" OK\n");
84 }
85
86
87 //
88 // FakeContext management
89 //
90 FakeContext::FakeContext(CSSM_CONTEXT_TYPE type, CSSM_ALGORITHMS alg, uint32 count)
91 : Context(type, alg)
92 {
93 NumberOfAttributes = count;
94 ContextAttributes = new Attr[count];
95 }
96
97
98 FakeContext::FakeContext(CSSM_CONTEXT_TYPE type, CSSM_ALGORITHMS alg, ...)
99 : Context(type, alg)
100 {
101 // count arguments
102 va_list args;
103 va_start(args, alg);
104 uint32 count = 0;
105 while (va_arg(args, Attr *))
106 count++;
107 va_end(args);
108
109 // make vector
110 NumberOfAttributes = count;
111 ContextAttributes = new Attr[count];
112
113 // stuff vector
114 va_start(args, alg);
115 for (uint32 n = 0; n < count; n++)
116 (*this)[n] = *va_arg(args, Attr *);
117 va_end(args);
118 }
119
120
121 //
122 // ACL test driver class
123 //
124 AclTester::AclTester(ClientSession &ss, const AclEntryInput *acl) : session(ss)
125 {
126 // make up a DES key
127 StringData keyBits("Tweedle!");
128 CssmKey key(keyBits);
129 key.header().KeyClass = CSSM_KEYCLASS_SESSION_KEY;
130
131 // wrap in the key
132 CssmData unwrappedData;
133 FakeContext unwrapContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_NONE, 0);
134 CssmKey::Header keyHeader;
135 ss.unwrapKey(noDb, unwrapContext, noKey, noKey,
136 key,
137 CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
138 CSSM_KEYATTR_EXTRACTABLE,
139 NULL /*cred*/, acl,
140 unwrappedData, keyRef, keyHeader);
141 detail("Key seeded with ACL");
142 }
143
144
145 void AclTester::testWrap(const AccessCredentials *cred, const char *howWrong)
146 {
147 FakeContext wrapContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_NONE, 0);
148 CssmWrappedKey wrappedKey;
149 try {
150 session.wrapKey(wrapContext, noKey, keyRef,
151 cred, NULL /*descriptive*/, wrappedKey);
152 if (howWrong) {
153 error("WRAP MISTAKENLY SUCCEEDED: %s", howWrong);
154 }
155 detail("extract OK");
156 } catch (const CssmCommonError &err) {
157 if (!howWrong)
158 error(err, "FAILED TO EXTRACT KEY");
159 detail(err, "extract failed OK");
160 }
161 }
162
163 void AclTester::testEncrypt(const AccessCredentials *cred, const char *howWrong)
164 {
165 CssmKey keyForm; memset(&keyForm, 0, sizeof(keyForm));
166 StringData iv("Aardvark");
167 StringData clearText("blah");
168 CssmData remoteCipher;
169 try {
170 if (cred) {
171 FakeContext cryptoContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_DES,
172 &::Context::Attr(CSSM_ATTRIBUTE_KEY, keyForm),
173 &::Context::Attr(CSSM_ATTRIBUTE_INIT_VECTOR, iv),
174 &::Context::Attr(CSSM_ATTRIBUTE_MODE, CSSM_ALGMODE_CBC_IV8),
175 &::Context::Attr(CSSM_ATTRIBUTE_PADDING, CSSM_PADDING_PKCS1),
176 &::Context::Attr(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, *cred),
177 NULL);
178 session.encrypt(cryptoContext, keyRef, clearText, remoteCipher);
179 } else {
180 FakeContext cryptoContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_DES,
181 &::Context::Attr(CSSM_ATTRIBUTE_KEY, keyForm),
182 &::Context::Attr(CSSM_ATTRIBUTE_INIT_VECTOR, iv),
183 &::Context::Attr(CSSM_ATTRIBUTE_MODE, CSSM_ALGMODE_CBC_IV8),
184 &::Context::Attr(CSSM_ATTRIBUTE_PADDING, CSSM_PADDING_PKCS1),
185 NULL);
186 session.encrypt(cryptoContext, keyRef, clearText, remoteCipher);
187 }
188 if (howWrong) {
189 error("ENCRYPT MISTAKENLY SUCCEEDED: %s", howWrong);
190 }
191 detail("encrypt OK");
192 } catch (CssmCommonError &err) {
193 if (!howWrong)
194 error(err, "FAILED TO ENCRYPT");
195 detail(err, "encrypt failed");
196 }
197 }
198
199
200 //
201 // Database test driver class
202 //
203 DbTester::DbTester(ClientSession &ss, const char *path,
204 const AccessCredentials *cred, int timeout, bool sleepLock)
205 : session(ss), dbId(ssuid, path, NULL)
206 {
207 params.idleTimeout = timeout;
208 params.lockOnSleep = sleepLock;
209 dbRef = ss.createDb(dbId, cred, NULL, params);
210 detail("Database %s created", path);
211 }
212
213
214 void DbTester::unlock(const char *howWrong)
215 {
216 session.lock(dbRef);
217 try {
218 session.unlock(dbRef);
219 if (howWrong)
220 error("DATABASE MISTAKENLY UNLOCKED: %s", howWrong);
221 } catch (CssmError &err) {
222 if (!howWrong)
223 error(err, howWrong);
224 detail(err, howWrong);
225 }
226 }
227
228 void DbTester::changePassphrase(const AccessCredentials *cred, const char *howWrong)
229 {
230 session.lock(dbRef);
231 try {
232 session.changePassphrase(dbRef, cred);
233 if (howWrong)
234 error("PASSPHRASE CHANGE MISTAKENLY SUCCEEDED: %s", howWrong);
235 } catch (CssmError &err) {
236 if (!howWrong)
237 error(err, howWrong);
238 detail(err, howWrong);
239 }
240 }