X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/securityd/tests/testutils.cpp diff --git a/securityd/tests/testutils.cpp b/securityd/tests/testutils.cpp new file mode 100644 index 00000000..32f172f9 --- /dev/null +++ b/securityd/tests/testutils.cpp @@ -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); + } +}