/* * Copyright (c) 2000-2001,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); } }