]> git.saurik.com Git - apple/security.git/blobdiff - securityd/tests/testutils.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / securityd / tests / testutils.cpp
diff --git a/securityd/tests/testutils.cpp b/securityd/tests/testutils.cpp
new file mode 100644 (file)
index 0000000..32f172f
--- /dev/null
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2000-2001,2003-2004 Apple Computer, Inc. All Rights Reserved.
+ * 
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+
+//
+// testutils - utilities for unit test drivers
+//
+#include "testutils.h"
+
+using namespace CssmClient;
+
+bool verbose = false;
+
+
+//
+// Error and diagnostic drivers
+//
+void error(const char *msg = NULL, ...)
+{
+       if (msg) {
+               va_list args;
+               va_start(args, msg);
+               vfprintf(stderr, msg, args);
+               va_end(args);
+               putc('\n', stderr);
+       }
+       abort();
+}
+
+void error(const CssmCommonError &err, const char *msg = NULL, ...)
+{
+       if (msg) {
+               va_list args;
+               va_start(args, msg);
+               vfprintf(stderr, msg, args);
+               va_end(args);
+               fprintf(stderr, ": %s", cssmErrorString(err.cssmError()).c_str());
+               putc('\n', stderr);
+       }
+       abort();
+}
+
+void detail(const char *msg = NULL, ...)
+{
+       if (verbose) {
+               va_list args;
+               va_start(args, msg);
+               vfprintf(stdout, msg, args);
+               va_end(args);
+               putc('\n', stdout);
+       }
+}
+
+void detail(const CssmCommonError &err, const char *msg)
+{
+       if (verbose)
+               printf("%s (ok): %s\n", msg, cssmErrorString(err).c_str());
+}
+
+void prompt(const char *msg)
+{
+       if (isatty(fileno(stdin)))
+               printf("[%s]", msg);
+}
+
+void prompt()
+{
+       if (isatty(fileno(stdin)))
+               printf(" OK\n");
+}
+
+
+//
+// FakeContext management
+//
+FakeContext::FakeContext(CSSM_CONTEXT_TYPE type, CSSM_ALGORITHMS alg, uint32 count)
+: Context(type, alg)
+{
+       NumberOfAttributes = count;
+       ContextAttributes = new Attr[count];
+}
+
+
+FakeContext::FakeContext(CSSM_CONTEXT_TYPE type, CSSM_ALGORITHMS alg, ...) 
+: Context(type, alg)
+{
+       // count arguments
+       va_list args;
+       va_start(args, alg);
+       uint32 count = 0;
+       while (va_arg(args, Attr *))
+               count++;
+       va_end(args);
+       
+       // make vector
+       NumberOfAttributes = count;
+       ContextAttributes = new Attr[count];
+       
+       // stuff vector
+       va_start(args, alg);
+       for (uint32 n = 0; n < count; n++)
+               (*this)[n] = *va_arg(args, Attr *);
+       va_end(args);
+}
+
+
+//
+// ACL test driver class
+//
+AclTester::AclTester(ClientSession &ss, const AclEntryInput *acl) : session(ss)
+{
+       // make up a DES key
+       StringData keyBits("Tweedle!");
+       CssmKey key(keyBits);
+       key.header().KeyClass = CSSM_KEYCLASS_SESSION_KEY;
+       
+       // wrap in the key
+       CssmData unwrappedData;
+       FakeContext unwrapContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_NONE, 0);
+    CssmKey::Header keyHeader;
+    ss.unwrapKey(noDb, unwrapContext, noKey, noKey,
+               key,
+               CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_DECRYPT,
+               CSSM_KEYATTR_EXTRACTABLE,
+               NULL /*cred*/, acl,
+               unwrappedData, keyRef, keyHeader);
+       detail("Key seeded with ACL");
+}
+
+
+void AclTester::testWrap(const AccessCredentials *cred, const char *howWrong)
+{
+       FakeContext wrapContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_NONE, 0);
+       CssmWrappedKey wrappedKey;
+       try {
+               session.wrapKey(wrapContext, noKey, keyRef,
+                       cred, NULL /*descriptive*/, wrappedKey);
+               if (howWrong) {
+                       error("WRAP MISTAKENLY SUCCEEDED: %s", howWrong);
+               }
+               detail("extract OK");
+       } catch (const CssmCommonError &err) {
+               if (!howWrong)
+                       error(err, "FAILED TO EXTRACT KEY");
+               detail(err, "extract failed OK");
+       }
+}
+
+void AclTester::testEncrypt(const AccessCredentials *cred, const char *howWrong)
+{
+    CssmKey keyForm; memset(&keyForm, 0, sizeof(keyForm));
+    StringData iv("Aardvark");
+    StringData clearText("blah");
+       CssmData remoteCipher;
+    try {
+        if (cred) {
+            FakeContext cryptoContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_DES,
+                &::Context::Attr(CSSM_ATTRIBUTE_KEY, keyForm),
+                &::Context::Attr(CSSM_ATTRIBUTE_INIT_VECTOR, iv),
+                &::Context::Attr(CSSM_ATTRIBUTE_MODE, CSSM_ALGMODE_CBC_IV8),
+                &::Context::Attr(CSSM_ATTRIBUTE_PADDING, CSSM_PADDING_PKCS1),
+                &::Context::Attr(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, *cred),
+                NULL);
+            session.encrypt(cryptoContext, keyRef, clearText, remoteCipher);
+        } else {
+            FakeContext cryptoContext(CSSM_ALGCLASS_SYMMETRIC, CSSM_ALGID_DES,
+                &::Context::Attr(CSSM_ATTRIBUTE_KEY, keyForm),
+                &::Context::Attr(CSSM_ATTRIBUTE_INIT_VECTOR, iv),
+                &::Context::Attr(CSSM_ATTRIBUTE_MODE, CSSM_ALGMODE_CBC_IV8),
+                &::Context::Attr(CSSM_ATTRIBUTE_PADDING, CSSM_PADDING_PKCS1),
+                NULL);
+            session.encrypt(cryptoContext, keyRef, clearText, remoteCipher);
+        }
+               if (howWrong) {
+                       error("ENCRYPT MISTAKENLY SUCCEEDED: %s", howWrong);
+               }
+               detail("encrypt OK");
+       } catch (CssmCommonError &err) {
+               if (!howWrong)
+                       error(err, "FAILED TO ENCRYPT");
+               detail(err, "encrypt failed");
+       }
+}
+
+
+//
+// Database test driver class
+//
+DbTester::DbTester(ClientSession &ss, const char *path,
+       const AccessCredentials *cred, int timeout, bool sleepLock) 
+: session(ss), dbId(ssuid, path, NULL)
+{
+       params.idleTimeout = timeout;
+       params.lockOnSleep = sleepLock;
+       dbRef = ss.createDb(dbId, cred, NULL, params);
+       detail("Database %s created", path);
+}
+
+
+void DbTester::unlock(const char *howWrong)
+{
+       session.lock(dbRef);
+       try {
+               session.unlock(dbRef);
+               if (howWrong)
+                       error("DATABASE MISTAKENLY UNLOCKED: %s", howWrong);
+       } catch (CssmError &err) {
+               if (!howWrong)
+                       error(err, howWrong);
+               detail(err, howWrong);
+       }
+}
+
+void DbTester::changePassphrase(const AccessCredentials *cred, const char *howWrong)
+{
+       session.lock(dbRef);
+       try {
+               session.changePassphrase(dbRef, cred);
+               if (howWrong)
+                       error("PASSPHRASE CHANGE MISTAKENLY SUCCEEDED: %s", howWrong);
+       } catch (CssmError &err) {
+               if (!howWrong)
+                       error(err, howWrong);
+               detail(err, howWrong);
+       }
+}