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