+++ /dev/null
-/*
- * Copyright (c) 2010 Apple 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@
- */
-
-
-
-#import "SecTransform.h"
-#import "SecCustomTransform.h"
-#import "SecDigestTransform.h"
-#import "SecEncryptTransform.h"
-#import "SecEncodeTransform.h"
-#import "SecDecodeTransform.h"
-#import "SecSignVerifyTransform.h"
-#import "SecNullTransform.h"
-#import "SecExternalSourceTransform.h"
-#import <Security/SecItem.h>
-#import "misc.h"
-#import "Utilities.h"
-#import "SecNullTransform.h"
-#include "regex.h"
-#include <dispatch/dispatch.h>
-#import "SecMaskGenerationFunctionTransform.h"
-#import "SecTransformInternal.h"
-#import "custom.h"
-#include "SecTransformReadTransform.h"
-#import "SecTransformValidator.h"
-#include <sys/types.h>
-#include <sys/sysctl.h>
-#include <ctype.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <CommonCrypto/CommonCryptor.h>
-#include <sys/stat.h>
-#import "NSData+HexString.h"
-#include <CoreFoundation/CFBase.h>
-#include <CoreFoundation/CFData.h>
-#include <CoreFoundation/CFRuntime.h>
-
-// compatibility layer
-struct SecTransformCreateBlockParameters {
- CFTypeRef (^send)(SecTransformStringOrAttributeRef attribute, SecTransformMetaAttributeType type, CFTypeRef value);
- CFTypeRef (^get)(SecTransformStringOrAttributeRef attribute, SecTransformMetaAttributeType type);
- CFTypeRef (^pushback)(SecTransformStringOrAttributeRef attribute, CFTypeRef value);
- CFErrorRef (^overrideTransform)(CFStringRef action, SecTransformActionBlock newAction);
- CFErrorRef (^overrideAttribute)(CFStringRef action, SecTransformStringOrAttributeRef attribute, SecTransformAttributeActionBlock newAction);
-};
-
-typedef void (^SecTransformCreateBlock)(CFStringRef name, SecTransformRef new_transform, const SecTransformCreateBlockParameters *params);
-
-SecTransformCreateBlock global_create_block;
-
-static SecTransformInstanceBlock block_for_custom_transform(CFStringRef name, SecTransformRef tr, SecTransformImplementationRef ir)
-{
- SecTransformInstanceBlock b = ^{
- // XXX: leak, need to override Finalize and clean up… (and need to handle caller overriding finalize…)
- SecTransformCreateBlockParameters *params = static_cast<SecTransformCreateBlockParameters *>(malloc(sizeof(SecTransformCreateBlockParameters)));
-
- params->overrideAttribute = ^(CFStringRef action, SecTransformStringOrAttributeRef attribute, SecTransformAttributeActionBlock newAction) {
- // We don't need to special case ProcessData to call SecTransformSetDataAction as there are no longer any uses of it
- return SecTransformSetAttributeAction(ir, action, attribute, newAction);
- };
-
- params->overrideTransform = ^(CFStringRef action, SecTransformActionBlock newAction) {
- return SecTransformSetTransformAction(ir, action, newAction);
- };
-
- params->get = ^(SecTransformStringOrAttributeRef attribute, SecTransformMetaAttributeType type) {
- return SecTranformCustomGetAttribute(ir, attribute, type);
- };
-
- params->send = ^(SecTransformStringOrAttributeRef attribute, SecTransformMetaAttributeType type, CFTypeRef value) {
- return SecTransformCustomSetAttribute(ir, attribute, type, value);
- };
-
- params->pushback = ^(SecTransformStringOrAttributeRef attribute, CFTypeRef value) {
- return SecTransformPushbackAttribute(ir, attribute, value);
- };
-
- params->overrideAttribute = Block_copy(params->overrideAttribute);
- params->overrideTransform = Block_copy(params->overrideTransform);
- params->get = Block_copy(params->get);
- params->send = Block_copy(params->send);
- params->pushback = Block_copy(params->pushback);
-
- global_create_block(name, tr, params);
-
- return (CFErrorRef)NULL;
- };
-
- return Block_copy(b);
-}
-
-// Sort of a bridge from the old Custom SPI to the new API, but is also
-// useful when you REALLY need to access stack locals as __block variables,
-// but don't need multithreading, or generic internalizing.
-static SecTransformRef custom_transform(CFStringRef base_name, SecTransformCreateBlock cb)
-{
- static int ct_cnt = 0;
- static dispatch_queue_t cnt_q = dispatch_queue_create("com.apple.security.custom_trasnform-cnt", 0);
- __block CFStringRef name = NULL;
- __block SecTransformRef ret = NULL;
-
- dispatch_sync(cnt_q, ^{
- CFErrorRef err = NULL;
-
- name = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@.%d"), base_name, ct_cnt++);
- global_create_block = cb;
- if (SecTransformRegister(name, block_for_custom_transform, &err)) {
- ret = SecTransformCreate(name, &err);
- if (err) {
- CFfprintf(stderr, "Error %@ creating %@\n", err, base_name);
- CFRelease(err);
- }
- } else {
- CFfprintf(stderr, "Error %@ registering %@\n", err, base_name);
- CFRelease(err);
- }
- global_create_block = NULL;
- CFRelease(name);
- });
-
- return ret;
-}
-
-
-#define STAssertErrorHas(err, rx, msg...) STAssertTrue(ErrorHas(err, rx), ##msg);
-
-static BOOL ErrorHas(NSError *error, NSString *rx) {
- if (!error) {
- return NO;
- }
- if (![error isKindOfClass:[NSError class]]) {
- return NO;
- }
-
- NSString *es = [error description];
- if (!es) {
- return NO;
- }
- return [es rangeOfString:rx options:NSRegularExpressionSearch].location != NSNotFound;
-}
-
-
-static SecTransformInstanceBlock DelayTransformBlock(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
-
-
- SecTransformSetDataAction(ref, kSecTransformActionProcessData,
- ^(CFTypeRef value)
- {
-
- if (NULL != value && CFNumberGetTypeID() == CFGetTypeID(value))
- {
- long long n;
- CFNumberGetValue((CFNumberRef)value, kCFNumberLongLongType, &n);
- usleep((useconds_t)(n / NSEC_PER_USEC));
- }
-
- return value;
- });
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
-static SecTransformRef delay_transform(long long nsec) {
- CFStringRef name = CFSTR("com.apple.security.unit-test.delay");
-
-
-
- static dispatch_once_t once;
- __block Boolean ok = TRUE;
-
- dispatch_block_t aBlock = ^
- {
- ok = SecTransformRegister(name, &DelayTransformBlock, NULL);
- };
-
- dispatch_once(&once, aBlock);
-
- if (!ok)
- {
- return NULL;
- }
-
- SecTransformRef ct = SecTransformCreate(name, NULL);
- CFNumberRef nr = CFNumberCreate(NULL, kCFNumberLongLongType, &nsec);
- SecTransformSetAttribute(ct, CFSTR("DELAY"), nr, NULL);
- CFRelease(nr);
-
- return ct;
-}
-
-@implementation custom
-
-class BufferStream
-{
-protected:
- const char* mBuffer;
- size_t mLength;
- size_t mStringLength;
- size_t mPos;
-
- char *mCurrentString;
-
-public:
- BufferStream(const char* buffer, size_t length) : mBuffer(buffer), mLength(length), mStringLength(0), mPos(0), mCurrentString(NULL) {}
- ~BufferStream();
-
- const char* GetNextString();
- void SplitString(const char*& stringA, const char*& stringB);
-};
-
-
-
-BufferStream::~BufferStream()
-{
- if (NULL != mCurrentString)
- {
- free(mCurrentString);
- }
-}
-
-
-
-const char* BufferStream::GetNextString()
-{
- size_t p = mPos;
- if (p >= mLength)
- {
- return NULL; // eof
- }
-
- // run to either the end of the buffer or a return
- while (p < mLength && mBuffer[p] != '\n')
- {
- p += 1;
- }
-
- if (p != mLength)
- {
- // handle the end of the buffer specially, since it doesn't point
- // to valid space
- p -= 1;
- }
-
- // p now points to the last character in the string
- // allocate memory for our buffer
- mStringLength = p - mPos + 1;
- mCurrentString = (char*) realloc(mCurrentString, mStringLength + 1);
- memmove(mCurrentString, mBuffer + mPos, mStringLength);
- mCurrentString[mStringLength] = 0;
- mPos = p + 2;
-
- return mCurrentString;
-}
-
-
-
-void BufferStream::SplitString(const char*& a, const char*& b)
-{
- // scan the buffer, looking for a ':'
- size_t p = 0;
- while (mCurrentString[p] != 0 && mCurrentString[p] != ':')
- {
- p += 1;
- }
-
- // the first string is always our buffer pointer
- a = mCurrentString;
-
- if (mCurrentString[p] == ':')
- {
- mCurrentString[p] = 0;
-
- // look for the beginning of the next string
- p += 1;
- while (p < mLength && isspace(mCurrentString[p]))
- {
- p += 1;
- }
-
- b = mCurrentString + p;
- }
- else
- {
- b = NULL;
- }
-}
-
-
-
--(void)disabledtestzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
-{
- // open leaks and make a connection to it.
- char* name;
-
- const int kChunkSize = 16384;
- char buffer[kChunkSize];
- pid_t thePid = getpid();
- asprintf(&name, "/tmp/leaks%d.txt", thePid);
- sprintf(buffer, "/usr/bin/leaks %d >%s", thePid, name);
- system(buffer);
-
- struct stat st;
- stat(name, &st);
-
- char* rBuffer = (char*) malloc((size_t)st.st_size);
- FILE* f = fopen(name, "r");
- fread(rBuffer, 1, (size_t)st.st_size, f);
- fclose(f);
-
- // set up our output parser
- BufferStream bStream(rBuffer, (size_t)st.st_size);
- const char* s = bStream.GetNextString();
-
- bool didError = true;
-
- if (NULL != s)
- {
- // we have our string, split it and see what it means
- const char* key;
- const char* value;
-
- bStream.SplitString(key, value);
- if (strcmp(key, "leaks Report Version") != 0 || strcmp(value, "2.0") != 0)
- {
- didError = true;
- }
- else
- {
- didError = false;
- }
- }
-
- if (!didError)
- {
- const char* key;
- const char* value;
-
- // figure out what our target line will look like
- char* target;
- asprintf(&target, "Process %d", thePid);
-
- const char* nextString = bStream.GetNextString();
- while (nextString)
- {
- bStream.SplitString(key, value);
- if (strcmp(key, target) == 0) // we found our target!!!
- {
- // do it again
- bStream.GetNextString();
- bStream.SplitString(key, value);
-
- if (value[0] != '0') // we have a non-zero result... :(
- {
- didError = true;
- }
- }
-
- nextString = bStream.GetNextString();
- }
-
- free(target);
- }
-
- STAssertFalse(didError, @"You have leaks!");
-
- if (didError)
- {
- // dump to our output file
- // make a file name for the leaks output
- FILE* f = fopen(name, "w");
- fwrite(rBuffer, 1, (size_t)st.st_size, f);
- fclose(f);
- }
- else
- {
- unlink(name);
- }
-
- free(name);
-}
-
-
-
-static const char* gHMACText = "The judicial Power shall extend to all Cases, in "
- "Law and Equity, arising under this Constitution, "
- "the Laws of the United States, and Treaties made, "
- "or which shall be made, under their Authority;--to "
- "all Cases affecting Ambassadors, other public "
- "Ministers and Consuls;--to all Cases of admiralty "
- "and maritime Jurisdiction;--to Controversies to "
- "which the United States shall be a Party;--to "
- "Controversies between two or more States;-- "
- "between a State and Citizens of another State, "
- "--between Citizens of different States,-- "
- "between Citizens of the same State claiming Lands "
- "under Grants of different States, and between a "
- "State, or the Citizens thereof, and foreign "
- "States, Citizens or Subjects";
-
-const NSString* gAbortTransformName = (NSString*) kSecTransformAbortAttributeName;
-
-static const char* gHMACKey = "No person shall be held to answer for a capital, or "
- "otherwise infamous crime, unless on a presentment "
- "or indictment of a Grand Jury, except in cases "
- "arising in the land or naval forces, or in the "
- "Militia, when in actual service in time of War or "
- "public danger; nor shall any person be subject for "
- "the same offence to be twice put in jeopardy of life "
- "or limb; nor shall be compelled in any criminal case "
- "to be a witness against himself, nor be deprived of "
- "life, liberty, or property, without due process of "
- "law; nor shall private property be taken for public "
- "use, without just compensation.";
-
-static const u_int8_t gSHA1HMAC[] = {0x2f, 0x68, 0x4b, 0x6b, 0x4f,
- 0xf7, 0x41, 0xc3, 0x76, 0x3d,
- 0x0b, 0xc3, 0x25, 0x02, 0x99,
- 0x03, 0xfa, 0xa5, 0xe9, 0xde};
-
-static const u_int8_t gSHA256HMAC[] = {0xc2, 0x5c, 0x9a, 0x65, 0x08, 0x9e, 0x61, 0xb5,
- 0x03, 0xfe, 0xcb, 0x57, 0xb7, 0x55, 0x4f, 0x69,
- 0xdb, 0xef, 0xdb, 0xe7, 0x0d, 0xe2, 0x78, 0x2e,
- 0xf9, 0x48, 0xbd, 0xf6, 0x4f, 0x4b, 0x94, 0x0c};
--(void)testPaddings
-{
- CFStringRef paddings[] = {kSecPaddingNoneKey, kSecPaddingPKCS7Key, kSecPaddingPKCS5Key, kSecPaddingPKCS1Key};
-
- for(int i = 0; i < sizeof(paddings) / sizeof(*paddings); i++) {
- CFErrorRef error = NULL;
- SecKeyRef cryptokey = NULL;
- SecTransformRef encrypt = NULL, decrypt = NULL;
- CFDataRef cfdatacryptokey = NULL, sourceData = NULL, encryptedData = NULL, decryptedData = NULL;
- const uint8_t rawcryptokey[16] = { 63, 17, 27, 99, 185, 231, 1, 191, 217, 74, 141, 16, 12, 99, 253, 41 }; // 128-bit AES key.
- const char *sourceCString = "All these worlds are yours except Europa."; // I'm not so sure about that Earth one either
-
- CFMutableDictionaryRef parameters = CFDictionaryCreateMutable(
- kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
-
- CFDictionarySetValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeAES);
-
- cfdatacryptokey = CFDataCreate(kCFAllocatorDefault, rawcryptokey,
- sizeof(rawcryptokey));
- cryptokey = SecKeyCreateFromData(parameters,
- cfdatacryptokey, &error);
- STAssertNil((id)error, @"Unexpected SecKeyCreateFromData error: %@", error);
-
- size_t len = strlen(sourceCString) +1;
- if (paddings[i] == kSecPaddingNoneKey) {
- STAssertTrue(len >= kCCBlockSizeAES128, @"Had at least one block");
- // Get to an AES block multiple, discarding bytes wildly.
- len -= len % kCCBlockSizeAES128;
- }
- sourceData = (CFDataRef)[NSData dataWithBytes:sourceCString length:len];
-
- encrypt = SecEncryptTransformCreate(cryptokey, &error);
- STAssertNil((id)error, @"Unexpected error creating encrypt transform: %@", error);
- decrypt = SecDecryptTransformCreate(cryptokey, &error);
- STAssertNil((id)error, @"Unexpected error creating decrypt transform: %@", error);
-
- /* Set the padding on the transforms */
- SecTransformSetAttribute(encrypt, kSecPaddingKey, paddings[i], &error);
- STAssertNil((id)error, @"Couldn't set encrypt padding to %@: %@", paddings[i], error);
- SecTransformSetAttribute(decrypt, kSecPaddingKey, paddings[i], &error);
- STAssertNil((id)error, @"Couldn't set decrypt padding to %@: %@", paddings[i], error);
-
- SecTransformSetAttribute(encrypt, kSecTransformInputAttributeName, sourceData, &error);
- STAssertNil((id)error, @"Couldn't set encrypt transform input: %@", error);
-
- encryptedData = (CFDataRef)SecTransformExecute(encrypt, &error);
- STAssertNil((id)error, @"Couldn't execute encrypt: %@ (padding %@)", paddings[i], error);
- STAssertNotNil((id)encryptedData, @"Didn't get encrypted data");
-
- SecTransformSetAttribute(decrypt, kSecTransformInputAttributeName, encryptedData, &error);
- STAssertNil((id)error, @"Couldn't set decrypt transform input: %@", error);
-
- decryptedData = (CFDataRef)SecTransformExecute(decrypt, &error);
- STAssertNil((id)error, @"Couldn't execute decrypt: %@", error);
- STAssertNotNil((id)decryptedData, @"Didn't get decrypt data");
-
- STAssertEqualObjects((id)decryptedData, (id)sourceData, @"Decrypt output didn't match encrypt input for padding %@", paddings[i]);
- }
-}
-
-static SecTransformInstanceBlock nopInstance(CFStringRef name, SecTransformRef newTransform, SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock = ^{
- return (CFErrorRef)NULL;
- };
-
- return Block_copy(instanceBlock);
-}
-
-
--(void)test_manyregister
-{
- dispatch_apply(4000, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^(size_t i) {
- NSString *name = [NSString stringWithFormat:@"many%luregister", i];
- CFErrorRef err = NULL;
- BOOL ok = SecTransformRegister((CFStringRef)name, nopInstance, &err);
- STAssertTrue(ok, @"register not ok");
- STAssertNil((id)err, @"register error: %@", err);
- });
-}
-
--(void)test_emptyOAEP
-{
- SecKeychainRef tmp_keychain = NULL;
- char *kcfname;
- asprintf(&kcfname, "%s-OAEP-XXXXXXXXXX", "/tmp/");
- const char *passwd = "sekret";
- // NOTE: "mktemp" isn't as safe as you might think...but this is test code and doesn't have to be, but
- // if you copy it elsewhere you may well need to rewrite it. (use mkstemp)
- mktemp(kcfname);
- OSStatus status = SecKeychainCreate(kcfname, (UInt32)strlen(passwd), passwd, NO, NULL, &tmp_keychain);
- STAssertTrue(status == 0, @"Expected to make keychain, but got error 0x%x", status);
-
- const char *pem_key_bytes[] = {
- // From the spec
- "-----BEGIN PUBLIC KEY-----\nMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC7+C8JBoLOnCM4rCudqHH3No0H\n7tQQQ6RA1rbwdFT1H7jfuq8DXAKrYepIzutvzUh27VINYOHsRhlxnYpbi4B/r7jg\no9/HN3I+5rS32TolhO5qZJ0GCVN0iDSyRUWYOU7gqrEte2GlH1J6mkH2wWh/4lNy\nmMoqj1lG+OX9CR29ywIBEQ==\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICWwIBAAKBgQC7+C8JBoLOnCM4rCudqHH3No0H7tQQQ6RA1rbwdFT1H7jfuq8D\nXAKrYepIzutvzUh27VINYOHsRhlxnYpbi4B/r7jgo9/HN3I+5rS32TolhO5qZJ0G\nCVN0iDSyRUWYOU7gqrEte2GlH1J6mkH2wWh/4lNymMoqj1lG+OX9CR29ywIBEQKB\ngQCl2vxTQfryicS5iNswwc34PzElHgZotCeEgTgBV5ZBspQQs8eZjWvEZXReXDkm\nadaHDaLAgqk543/cuC7JPtrJf/OtWVCsz7wRHHbxqVKUROVqr2jFbAks043DvvXS\nCpOZJu1PdKE+3fvhoc7MSJSvlCjCt7iIP+RGOkvIWxyzwQJBAO7ProGxubPJCIEL\nEKG1YAGZ659ErvT9pJO4Gp49hPYyEk7wI25dHjt+KPrnqgQKLVslIXZFnR85dUG6\nKlj7ZZkCQQDJf7HwJ/RT9jQSM+qq0dk1P2xC0IhmsdBaDyA1AoudhphAtBZmtC6S\n6g2jtDIEtc/OM1JSTQQWpaRB5wCvRhUDAkBUSUymProDN+TiQCP81ppa6wfd3AGD\npNCsm1SwUfKxPtlJCXXqt3QU/1nB92kumi4gKzj8kQpHQXStyTwfZ8mBAkBHHgKQ\n/wrwdQNRt/h4hkypYa29Oop+mRxcBVapTDFGp/mAP49viuNC6TH9iuR6Ig0bmaSV\nhJgH/jn5JFqYNto9AkEAsGxP2rtjARmNJlvbrpQjs4Dycfc0U4hQkwd/zTniEZ/J\nhjIVT1iDsWepZ79AK06eLg+WVuaY6jZm7fsleYA59w==\n-----END RSA PRIVATE KEY-----\n",
- NULL,
- };
- struct key_pair {
- SecKeyRef pubKey, privKey;
- };
- key_pair keys[1];
-
- int i;
- for(i = 0; i < sizeof(keys)/sizeof(key_pair); i++) {
- NSAssert(pem_key_bytes[i] != NULL, @"Expected a key");
- NSLog(@"Importing: %s", pem_key_bytes[i]);
- CFDataRef pem_data = CFDataCreate(NULL, (UInt8*)(pem_key_bytes[i]), strlen(pem_key_bytes[i]));
- SecKeyImportExportParameters import_params;
- bzero(&import_params, sizeof(import_params));
-
- import_params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
- import_params.keyUsage = CSSM_KEYUSE_ANY;
- import_params.keyAttributes = CSSM_KEYATTR_PERMANENT|CSSM_KEYATTR_SENSITIVE;
- import_params.accessRef = NULL;
- import_params.passphrase = CFSTR("");
- import_params.alertPrompt = CFSTR("");
-
- CFArrayRef keypair = NULL;
- SecExternalFormat key_format = kSecFormatOpenSSL;
- SecExternalItemType itemType = kSecItemTypeUnknown;
- status = SecKeychainItemImport(pem_data, CFSTR(".pem"), &key_format, &itemType, 0, &import_params, tmp_keychain, &keypair);
- STAssertTrue(status == 0, @"Expected pubkey import to be ok, got err=0x%x", status);
- NSAssert(keypair != NULL, @"Expected to get some keys back");
- STAssertNotNil((id)keypair, @"Expected to get some keys back");
- STAssertTrue(CFArrayGetCount(keypair) == 2, @"Expected 2 keys, got %@", keypair);
- keys[i].pubKey = (SecKeyRef)CFArrayGetValueAtIndex(keypair, 0);
- keys[i].privKey = (SecKeyRef)CFArrayGetValueAtIndex(keypair, 1);
- }
- STAssertNil((id)pem_key_bytes[i], @"Expected to convert all pem keys, but found at least: %s", pem_key_bytes[i]);
- CFDataRef encoding_parameters = CFDataCreate(NULL, NULL, 0);
-
-
- CFErrorRef err = NULL;
-
- SecTransformRef encryptor = SecEncryptTransformCreate(keys[0].pubKey, &err);
-
- CFReadStreamRef empty_stream = CFReadStreamCreateWithBytesNoCopy(NULL, (UInt8*)"", 0, kCFAllocatorNull);
- SecTransformSetAttribute(encryptor, kSecTransformInputAttributeName, empty_stream, &err);
- SecTransformSetAttribute(encryptor, kSecPaddingKey, kSecPaddingOAEPKey, &err);
- SecTransformSetAttribute(encryptor, kSecOAEPEncodingParametersAttributeName, encoding_parameters, &err);
-
- CFTypeRef encryptedData = SecTransformExecute(encryptor, &err);
- STAssertNotNil((id)encryptedData, @"Expected to get encrypted data");
- STAssertNil((NSError*)err, @"Expected no error, got err=%@", err);
- // Can't support "seed" with commoncrypto, just check round trip.
- //STAssertEqualObjects((id)encryptedData, (id)tests[i].encryptedMessage, @"encrypted data should have matched test vector (%@) data", tests[i].label);
- CFRelease(encryptor);
-
- SecTransformRef decryptor = SecDecryptTransformCreate(keys[0].privKey, NULL);
- // XXX: totally round trip, not even partial KAT (KAT can't really be done on OAEP
- // without supporitng settign the seed externally)
- SecTransformSetAttribute(decryptor, kSecTransformInputAttributeName, encryptedData, NULL);
- SecTransformSetAttribute(decryptor, kSecPaddingKey, kSecPaddingOAEPKey, NULL);
- SecTransformSetAttribute(decryptor, kSecOAEPEncodingParametersAttributeName, encoding_parameters, NULL);
- CFTypeRef decryptedData = SecTransformExecute(decryptor, &err);
- STAssertNil((id)err, @"Expected no error, got: %@", err);
- STAssertNotNil((id)decryptedData, @"Expected to get decrypted data");
- // What do we expect an empty enc/dec to look like? Mostly "not a crash"
- CFDataRef empty_data = CFDataCreate(NULL, (UInt8*)"", 0);
- STAssertEqualObjects((id)decryptedData, (id)empty_data, @"Expected decrypted data to match original message");
- CFRelease(decryptor);
- sleep(5);
-
- return;
-}
-
--(void)testzzzzZZZZ
-{
- // Give xcode a little time to parse all the output before the unit tests exit
- sleep(2);
-}
-
--(void)test_multiOAEP
-{
- SecKeychainRef tmp_keychain = NULL;
- char *kcfname;
- asprintf(&kcfname, "%s-OAEP-XXXXXXXXXX", "/tmp/");
- const char *passwd = "sekret";
- // NOTE: "mktemp" isn't as safe as you might think...but this is test code and doesn't have to be, but
- // if you copy it elsewhere you may well need to rewrite it. (use mkstemp)
- mktemp(kcfname);
- OSStatus status = SecKeychainCreate(kcfname, (UInt32)strlen(passwd), passwd, NO, NULL, &tmp_keychain);
- STAssertTrue(status == 0, @"Expected to make keychain, but got error 0x%x", status);
-
- const char *pem_key_bytes[] = {
- // From the spec
- "-----BEGIN PUBLIC KEY-----\nMIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC7+C8JBoLOnCM4rCudqHH3No0H\n7tQQQ6RA1rbwdFT1H7jfuq8DXAKrYepIzutvzUh27VINYOHsRhlxnYpbi4B/r7jg\no9/HN3I+5rS32TolhO5qZJ0GCVN0iDSyRUWYOU7gqrEte2GlH1J6mkH2wWh/4lNy\nmMoqj1lG+OX9CR29ywIBEQ==\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICWwIBAAKBgQC7+C8JBoLOnCM4rCudqHH3No0H7tQQQ6RA1rbwdFT1H7jfuq8D\nXAKrYepIzutvzUh27VINYOHsRhlxnYpbi4B/r7jgo9/HN3I+5rS32TolhO5qZJ0G\nCVN0iDSyRUWYOU7gqrEte2GlH1J6mkH2wWh/4lNymMoqj1lG+OX9CR29ywIBEQKB\ngQCl2vxTQfryicS5iNswwc34PzElHgZotCeEgTgBV5ZBspQQs8eZjWvEZXReXDkm\nadaHDaLAgqk543/cuC7JPtrJf/OtWVCsz7wRHHbxqVKUROVqr2jFbAks043DvvXS\nCpOZJu1PdKE+3fvhoc7MSJSvlCjCt7iIP+RGOkvIWxyzwQJBAO7ProGxubPJCIEL\nEKG1YAGZ659ErvT9pJO4Gp49hPYyEk7wI25dHjt+KPrnqgQKLVslIXZFnR85dUG6\nKlj7ZZkCQQDJf7HwJ/RT9jQSM+qq0dk1P2xC0IhmsdBaDyA1AoudhphAtBZmtC6S\n6g2jtDIEtc/OM1JSTQQWpaRB5wCvRhUDAkBUSUymProDN+TiQCP81ppa6wfd3AGD\npNCsm1SwUfKxPtlJCXXqt3QU/1nB92kumi4gKzj8kQpHQXStyTwfZ8mBAkBHHgKQ\n/wrwdQNRt/h4hkypYa29Oop+mRxcBVapTDFGp/mAP49viuNC6TH9iuR6Ig0bmaSV\nhJgH/jn5JFqYNto9AkEAsGxP2rtjARmNJlvbrpQjs4Dycfc0U4hQkwd/zTniEZ/J\nhjIVT1iDsWepZ79AK06eLg+WVuaY6jZm7fsleYA59w==\n-----END RSA PRIVATE KEY-----\n",
- // The next 10 are from oaep-vect.txt (via a lot of OpenSSL higgerdy-jiggerdey)
- "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCos7KEr461CzhwNKhg8UbEkZ8x\nh2PNbFWYyK5IEaHgq8TH4LCC1pOl5/ztZ1z0ZoUSdywMvGSnQsbGMPUzyMxy9iro\nM8QL8lhC6YS7eL2/l8AQfVW9tmL1xOD6uYRctRSO9zkt06r/k64ea2Z7s9QkdhbU\n9boQ1M/SJt6I058W+wIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCos7KEr461CzhwNKhg8UbEkZ8xh2PNbFWYyK5IEaHgq8TH4LCC\n1pOl5/ztZ1z0ZoUSdywMvGSnQsbGMPUzyMxy9iroM8QL8lhC6YS7eL2/l8AQfVW9\ntmL1xOD6uYRctRSO9zkt06r/k64ea2Z7s9QkdhbU9boQ1M/SJt6I058W+wIDAQAB\nAoGAUzOc/befyEZqZVxzFqyoXFX9j23YmP2vEZUX709S6P2OJY35P+4YD6Dkqylp\nPNg7FSpVPUrE0YEri5+lrw5/Vf5zBN9BVwkm8zEfFcTWWnMsSDEW7j09LQrzVJrZ\nv3y/t4rYhPhNW+sEck3HNpsx3vN9DPU56c/N095lNynq1dECQQDTJzfnJn/+E0Gy\n1cDRUKgbWG+zEyvtL41SYoZKnLnzCvOL5EhZjUE6Fy77gCwhrPHBHFIMLyakcdyt\nIS6sfKOdAkEAzIhT0dVNpjD6wAT0cfKBx7iYLYIkpJDtvrM9Pj1cyTxHZXA9HdeR\nZC8fEWoN2FK+JBmyr3K/6aAw6GCwKItddwJADhK/FxjpzvVZm6HDiC/oBGqQh07v\nzo8szCDk8nQfsKM6OEiuyckwX77L0tdoGZZ9RnGsxkMeQDeWjbN4eOaVwQJBAJUp\new+Vovpn0AcH1gnf1PwFyJ2vwu9tbqVb7HceozNzTZJR55CC7NqGbv7xPEWeGmMT\nhrfjVMiZ9fESyoXXFYMCQE9FbFAkk73A7Sq3VqOm7U1nNSppfUIW6TISsSemPVQR\nzm+pjV2+/XMmPjcoFCdDgYFm7X3WNofdKoyh0vT72OE=\n-----END RSA PRIVATE KEY-----\n",
- "RSA key ok\n-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQGUfH/OkEJfRyeecIUfJdXmIxb+\nih3xk3Hj5ijiYFQ+SQHvYIH2jAuBQRkNKujaun0SUOxttjbpROw3Iod8fB0KZ/FL\nFpTF8DeUUaQ+SaMt3oNnC3PakaHJm8I7Q2pgBVxhDwuvmcGgeVZblaPxUmYy0dTa\nYPIO2iXmU8TwAnZvRQIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQGUfH/OkEJfRyeecIUfJdXmIxb+ih3xk3Hj5ijiYFQ+SQHvYIH2\njAuBQRkNKujaun0SUOxttjbpROw3Iod8fB0KZ/FLFpTF8DeUUaQ+SaMt3oNnC3Pa\nkaHJm8I7Q2pgBVxhDwuvmcGgeVZblaPxUmYy0dTaYPIO2iXmU8TwAnZvRQIDAQAB\nAoGAaHJZomJX8Thzf5M4nNltSXcIKgRKRSY4w4ucRRBw0ICTslduV9bD5cWEjYTm\nCg0b3M3ur0ndFhFJGdedusRlzrJ3phMQcCvg8AygYOPN4gqYbIqz7xshfRxwQoGT\nGwFbOc4FQzlmlGna+VJDZ8sxykucXXKZh+wfN0vR7xXmj6UCQQFZ294Eoz7wb7YI\nuAsZD00+IrzBOsjkoIEDOr+kFu2wsziqCLVzCepaUkDn3G5UN4xpQUwx2X3bH0Bt\ns3acxBpDAkEBK2UvMEA7OLQJlf1v9BoazIracDcyNrcgLTmy7jDPtG2wlRH28wfM\nYcwhYGwYp1uKYvgi3wMboN8Nr9VQb1aL1wJAQ271CN5zZRnC2kxYDZjILLdFKj+1\n763Ducd4mhvGWE95Wt270yQ5x0aGVS7LbCwwek069/U57sFXJIx7MfGiVQJBASsV\nqJ89+ys5Bz5z8CvdDBp7N53UNfBc3eLv+eRilIt87GLukFDV4IFuB4WoVrSRCNy3\nXzaDh00cpjKaGQEwZv8CQAJw2xfVkUsBjXYRiyQ4mnNQ7INrAGOiFyEjb9jtttib\nUefuuHthG3Eyy36nNWwjFRwed1FQfHhtnuF5QXCoyOg=\n-----END RSA PRIVATE KEY-----\n",
- "RSA key ok\n-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQK1j+wDmoYHAKTXtkYvk+bN1JEW\nHd109OgQtA48FlIAalwneyd0wRMFpMurWnjvpX4XqG33o/o2/EsdIknyLsfC3WpG\nMjKszqkG1m6+gLVwSxBynab4MyNKu1791KKSy/rTO00z+noUuMOXtW46zSEgNCi3\nfN+jOm2nBrPYsPxD6QIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQK1j+wDmoYHAKTXtkYvk+bN1JEWHd109OgQtA48FlIAalwneyd0\nwRMFpMurWnjvpX4XqG33o/o2/EsdIknyLsfC3WpGMjKszqkG1m6+gLVwSxBynab4\nMyNKu1791KKSy/rTO00z+noUuMOXtW46zSEgNCi3fN+jOm2nBrPYsPxD6QIDAQAB\nAoGAFbSKW1aDqUZw4jtXGPgU+g4T+FA49QcRGCy6YVEFgfPSLH4jLvk34i5VHWi4\nbi+MsarYvi5Ij13379J54/Vo1Orzb4DPcUGs5g/MkRP7bEqEH9ULvHxRL/y+/yFI\neqgR6zyoxiAFNGqG3oa/odipSP0/NIwi6q3zM8PObOEyCP0CQQG/AdIW1zWVzwJw\nwr63jUCg2ER9MdqRmpg/fup4G3fYX+Nxs+k3PntpIX0xUKAtiVjef62dVVFglYtE\nVBJ+Dn6vAkEBjTOZZYFm2zgpgW17KVQWdZ6ckZh/Wy2K7NY7BLSL17L88im7f4pt\nyIuhPdLjmtVbbRoGFgcI+XAL6AuP03RM5wJABsCiSdIKby7nXIi0lNU/aq6ZqkJ8\niMKLFjp2lEXl85DPQMJ0/W6mMppc58fOA6IVg5buKnhFeG4J4ohalyjk5QJBANHS\nfCn+3ZLYbDSO3QzL+sFPdG4FHOHRgR3zXWHy7hyX1L8oBIAvZCcYe6jpCor0QkO0\nB5sDRF5gLin6UZPmT+kCQQCMsvdWvYlBsdO3cOWtMe43Oyis2mn/m29A/leLnxr7\nhYNvlifTes/3PCd55jS7JgEcLI9/M2GuKp6mXtaJ42Oa\n-----END RSA PRIVATE KEY-----\n",
- "RSA key ok\n-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQUSQLbMAAT6SNATRnHAeMfI3sOz\n4vJbwlZEZzOds4hT0GuF7qWy3jU7/0KsLka8l/rmrJYY2pU3pcj1U8HjV2JZkdYQ\njc14hfs6JUE/U+/K2UjLNc2bmunBxnYm0RPVfd5MW+p2u1u33pbADQc3LpaFptdc\n+dI5+hSNcJMbXz+wOQIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXgIBAAKBgQUSQLbMAAT6SNATRnHAeMfI3sOz4vJbwlZEZzOds4hT0GuF7qWy\n3jU7/0KsLka8l/rmrJYY2pU3pcj1U8HjV2JZkdYQjc14hfs6JUE/U+/K2UjLNc2b\nmunBxnYm0RPVfd5MW+p2u1u33pbADQc3LpaFptdc+dI5+hSNcJMbXz+wOQIDAQAB\nAoGBAQs6yuW+80dZiYsOKwgFVIpiYEI86so8fGlkHNnPRLaL5jYRY4Yn+yk4Z87t\nT54uYnTs/ZBsHd7wfycQcI6NRC5hgVY5sbQKDJDJIHgDPvxewvmE+mgbRFo7v4RH\nGGacGivrZVhXdDMpOm3KyxRfToWUJIq6IhT0AeURYrezGJABAkECdFjBnsFjaRnn\nNsmvJdYJpRuPVh0Zxr9pQ90e4auKSj8jIQC9QLiN7Ma6I1VItu95KhHJ3oI9Cnki\nxwlbbrpXAQJBAhDumzOrYXFuJ9JRvUZfSzWhojLi2gCQHClL8iNQzkkNCZ9kK1N1\nYS22O6HyA4ZJK/BNNLPCK865CdE0QbU7UTkCQDn6AouCbojBEht1CoskL6mjXFtm\nvf0fpjfTzEioSk9FehlOdyfkn3vMblpaQSZX/EcMcyLrw3QW70WMMHqMCQECQQFd\nmahBlZQ5efqeG+LDwbafQy9G/QPkfVvvu7/WsdE3HYPvszCj4CCUKy/tEV5dAr4k\n/ZLJAZ0c7NbdTPHlTMiZAkEB8LcBUXCz9eQiI7owMBxBpth8u3DjDLfTxn0lRz2x\n9svwPj+RJuPpeWgnmoZbLCtCZSTPxSpoPTHtMOuYS+QSug==\n-----END RSA PRIVATE KEY-----\n",
- "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQqt8/nBJeXYkfMaxEjpk97+WA+A\nK0X51/IrpQIenEdXa1oeaAMbqdtObavk2Wodbz0mcmjP9AgAXxGO/K25mIjRwjRG\ncWayorhJoFqInAYKwNoMX66LVfMJumLnA3QvoDJvLRCwEQIUif9Jd3AZDYlf059S\nKTw579c6aYvaufEO2QIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXwIBAAKBgQqt8/nBJeXYkfMaxEjpk97+WA+AK0X51/IrpQIenEdXa1oeaAMb\nqdtObavk2Wodbz0mcmjP9AgAXxGO/K25mIjRwjRGcWayorhJoFqInAYKwNoMX66L\nVfMJumLnA3QvoDJvLRCwEQIUif9Jd3AZDYlf059SKTw579c6aYvaufEO2QIDAQAB\nAoGBAlbrTLpwZ/LSvlQNzf9FgqNrfTHRyQmbshS3mEhGaiaPgPWKSawEwONkiTSg\nIGwEU3wZsjZkOmCCcyFE33X6IXWI95RoK+iRaCdtxybFwMvbhNMbvybQpDr0lXF/\nfVKKz+40FWH2/zyuBcV4+EcNloL5wNBy+fYGi1bViA9oK+LFAkEDsNOWL20XVJy/\nyhEpQ0jc8Ofjn4wrxoJPIWS2BtaHhg2uHmMjk8/t9RMigikGni9g5KzX5jOkNgY/\ngjhfSJk3BwJBAuTDLi9Rcmm3ByMJ8AwOMTZffOKLI2uCkS3yOavzlXLPDtYEsCmC\n5TVkxS1qBTl95cBSov3cFB73GJg2NGrrMx8CQQHoSxGdJRYfpnsAJWpb2bZF0rIy\n7LBbAVGAApqIYircPwmzrqzeYWGrfN4iwq0m53l99U4HLL07JnOACz5DONvVAkEA\n65CqGkATW0zqBxl87ciBm+Hny/8lR2YhFvRlpKn0h6sS87pP7xOCImWmUpfZi3ve\n2TcuP/6Bo4s+lgD+0FV1TwJBAS9/gTj5QEBi64WkKSRSCzj1u4hqAZb0i7jc6mD9\nkswCfxjngVijSlxdX4YKD2wEBxp9ATEsBlBi8etIt50cg8s=\n-----END RSA PRIVATE KEY-----\n",
- "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgRKxf22tLs0Z/0bcE/eGDwng4M+2\nd7OKUlkjBc6vAiwWbbkNBKwp4z990S2fr2bggWu2Pq0mfMfUbBfDe+IUvKKiLXI6\nZOREB0Nrb8llcprvwlVPN2zV3OpoKTeApivznQApSFoWC7ueXcCXLSGlBPUuXuAo\nqkFjMvUQsunP9fcirwIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXwIBAAKBgRKxf22tLs0Z/0bcE/eGDwng4M+2d7OKUlkjBc6vAiwWbbkNBKwp\n4z990S2fr2bggWu2Pq0mfMfUbBfDe+IUvKKiLXI6ZOREB0Nrb8llcprvwlVPN2zV\n3OpoKTeApivznQApSFoWC7ueXcCXLSGlBPUuXuAoqkFjMvUQsunP9fcirwIDAQAB\nAoGBApXso1YGGDaVWc7NMDqpz9r8HZ8GlZ33X/75KaqJaWG80ZDcaZftp/WWPnJN\nB7TcEfMGXlrpfZaDURIoC5CEuxTyoh69ToidQbnEEy7BlW/KuLsv7QV1iEk2Uixf\n99MyYZBIJOfK3uTguzctJFfPeOK9EoYij/g/EHMc5jyQz/P5AkEEps6Lc1jfppvc\n90JhcAWvtThfXzpYok73SiKowFy3zDjr1Mydmp14mmLND2Dwy5QdNCPJaS76T+Ot\n/ykMR0mjiwJBBATJqAM3H+20xb4588ALAJ5eCKY74eQANc2spQEcxwHPfuvLmfD/\n4Xz9Ckv3vv0t1TaslG23l/28Sr6PKTSbke0CQQOWHI92CqK9UVTHqv13Ils7rNAT\nmue1lI6jMR/M2G+5XHWvp2coS5st5VlXLxXY0ETH64Ohvl+t8sw3fA2EdSlLAkEC\nIZfgZnQhlqq8A/ov7rTnCxXLeH1hes0xu3XHvCNK1wb3xI0hgtHw/5wijc9Blnts\nC6bSwK0RChuFeDHsJF4ssQJBBAHEwMU9RdvbXp2W0P7PQnXfCXS8Sgc2tKdMMmkF\nPvtoas4kBuIsngWN20rlQGJ64v2wgmHo5+S8vJlNqvowXEU=\n-----END RSA PRIVATE KEY-----\n",
- "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgTERefC8/JudPKMV0A7zDXvdOiz6\n6ZEb/ty5SLOkeC0HMrarRKpL8DdBpkTcAb7D5psBoDPmddis18SSXGsa7DEZBR39\niXYtIV1FR1/8tZ+QgUhiPzcXcVb2robdenxfQ9weH5CCVAWKKEpfBsACF5OofxrF\n/v99yu5pxeUaN4njcwIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXgIBAAKBgTERefC8/JudPKMV0A7zDXvdOiz66ZEb/ty5SLOkeC0HMrarRKpL\n8DdBpkTcAb7D5psBoDPmddis18SSXGsa7DEZBR39iXYtIV1FR1/8tZ+QgUhiPzcX\ncVb2robdenxfQ9weH5CCVAWKKEpfBsACF5OofxrF/v99yu5pxeUaN4njcwIDAQAB\nAoGBDzqRUfoVnGZsj2ERtdIReUPr7lHhc7vwmaiXu8lr0u3M+4ykPwZag4vIgs6V\nbBN42triUblREfJy9PtH26X7cC0twt93fImTyuAcrKSNXKQIizI0XrhyB/9ewQv8\nkuI8dQugKhVIO+A1Ii2HPT7q9BC1DS9aYZ/PUzUQ68WM7b2BAkEHSSYsERzUcOwl\nZuazcy/AkylGmqGQcdO5wBkGUUxvHSa6oUvqsJcci35hGk95AJ1v6ndpKMolKFsN\n42Q9Gj+McQJBBrweUOlsAr9jbp7qi4mbvr92Ud533UdMPpvCO62BgrYZBMfZffvr\n+x4AEIh4tuZ+QVOR1nlCwrK/m0Q1+IsMsCMCQQO8fqfwqrFDq8bOi5cRhjajAXLk\nz+Asj6Ddo7e6r5D4CSmCmFUl9Ii9/LS9cm4iY5rGSjCSq3/8vx1TNM+lC1vxAkEC\nYqaqKcKjxn3FNGwGOBr9mHqjzJPPv+z1T92fnXh9f1mlI9OYl52hN6L2OB/pSAH3\nyU2iFRjcNMtAhwxGl5lK2QJAZJ1MF7buFyHnctA4mlWcPTzflVDUV8RrA3t0ZBsd\nUhZq+KITyDliBs37pEIvGNb2Hby10hTJcb9IKuuXanNwwg==\n-----END RSA PRIVATE KEY-----\n",
- "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgVvfDjDTId2lFH+IJAj6aRlUgN+P\ngNP26L9YGFBPNkJ8qbH1VAucZaj2l0z4RHokTZKAIBu0n8u+Y3jRlEzSJ+Iw+W49\nEPgZ3O8nbGSgCypLZwHn0B3l+r3jsemg34L0YxNZzSJmlkf7sXFyRhNO17SXz/+9\nxCtZxzqW7ZAWYhLf9wIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIICXwIBAAKBgVvfDjDTId2lFH+IJAj6aRlUgN+PgNP26L9YGFBPNkJ8qbH1VAuc\nZaj2l0z4RHokTZKAIBu0n8u+Y3jRlEzSJ+Iw+W49EPgZ3O8nbGSgCypLZwHn0B3l\n+r3jsemg34L0YxNZzSJmlkf7sXFyRhNO17SXz/+9xCtZxzqW7ZAWYhLf9wIDAQAB\nAoGBD30enlqqJf0T5KBmOuFE4NFfXNGLzbCd8sx+ZOPF6RWtYmRTBBYdCYxxW7er\ni9AdB+rz/tfH7QivKopi70SrFrMg4Ur3Kkj5av4mKgrkz2XmNekQeQzU7lzqdopL\nJjn35vZ3s/C7a+MrdXR9iQkDbwJk9Y1AHNuhMXFhV6dez2MxAkEKAu+ESNn62LvQ\n0ATIwqqXUe+XIcGw0DI2pUsN+UfLrtWiVe6ejiDUkeoXI/4JRwSpdi6Ir9Fuu1mU\nQSypZtxPnwJBCS02Ln7ToL/Z6f0ObAMBtt8pFZz1DMg7mwz01u6nGmHgArRuCuny\n3mLSW110UtSYuByaxvxYWT1MP7T11y37sKkCQQfHFBCvEDli2zZ0BON66FC6pOnC\nndkhRYFSlKZ8fRxt7SY6oDCptjOuUDA+FANdGvAUEj66aHggMI2OvIW2lX19AkEA\nrix1OAwCwBatBYkbMwHeiB8orhFxGCtrLIO+p8UV7KnKKYx7HKtYF6WXBo/IUGDe\nTaigFjeKrkPH+We8w3kEuQJBBZjRBZ462k9jIHUsCdgF/30fGuDQF67u6c76DX3X\n/3deRLV4Mi9kBdYhHaGVGWZqqH/cTNjIj2tuPWfpYdy7o9A=\n-----END RSA PRIVATE KEY-----\n",
- "-----BEGIN PUBLIC KEY-----\nMIHfMA0GCSqGSIb3DQEBAQUAA4HNADCByQKBwQDPLNQeNMo6co6ly4r/ZMNtJ73v\nU2TjNv1o0xI8WhlqjChwE+hT1RVtWNFRlUUg+09texertoF3ZZCcV2EZZZ2QKxkG\n7YorEMFVwk0SRSjaue6uN5vqxm5KQReG3Lj9AGLrwDDeEhmgTCqMG33TEx5Na2yu\n4uMaXtQawVCbLvHuKrGDZL5WjKlBwl7MhP+dZDtewaquECog1z9Hm3gP1tqRB1IS\n2erAOgZ02JnrouQx9MRLYVtroiMr1LM7rtc9Yl0CAwEAAQ==\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIIDfgIBAAKBwQDPLNQeNMo6co6ly4r/ZMNtJ73vU2TjNv1o0xI8WhlqjChwE+hT\n1RVtWNFRlUUg+09texertoF3ZZCcV2EZZZ2QKxkG7YorEMFVwk0SRSjaue6uN5vq\nxm5KQReG3Lj9AGLrwDDeEhmgTCqMG33TEx5Na2yu4uMaXtQawVCbLvHuKrGDZL5W\njKlBwl7MhP+dZDtewaquECog1z9Hm3gP1tqRB1IS2erAOgZ02JnrouQx9MRLYVtr\noiMr1LM7rtc9Yl0CAwEAAQKBwQCBIn4tPdZ3zAQiT9caDiLKHSWE0cRm5FXcSwRo\n3fhNs4NZKO99oaozeFMwuQxX3I3LvhgpDh9w3rve15BMlkw6GsME0Hd5FH6OCAim\nRLmMbKzbpwnmszz3x870Xwxnlx7xZblxuoKHiq4tjuoOK2FETNi979bB1jGO0xrA\nd8Oap2AMKBju4OmNpRdzjTKaMVyFavjn7HKHZ2Pp2Y45K/X+hIv0Kx8xx7kkaix7\nyxQLIVKMPjoanViwHTxWls9mUQECYQD8jWwEvsTrmoGSynkAy+U24ui1Gd7PM7JF\nl5jGkJ308XbbfSMZD8criGWnGK+JXxvNkUUpgCdCO2BecKR89YOQqMPoj8jEjosy\n49ohDfvj6IHqVnS2o0jCHpP55V6mXv0CYQDSANReeIqs6mBqQB0EYPh91cECfhLc\nGg11huiTnZz3ibQPUawEQpYd59Icwh4FyDFVwfKqkZM4fP35VstI0VO6JwQG+bu6\nU31Jh9ni+ZQtehTL//6nT+zdqSjSPiWfXuECYQDbFoAveaLw1F81jWn9M+RLgfro\nKGIuk6VCU+mX0BsHQ3WdoOgStKpObIvqsjKNVDGVWkGKZ/8mqMXIB6XaNU4F7zHM\njPdY9GNzKVCwPiZXJvuU451qVyomJEqwjbdXUq0CYQCgoxfP598UI/h6be6EUfTi\ntKZ+VJfym08eToMLn63ZQBFnAm9VluWjnJeBfg9fFuJ+GeyZAuAdfqb7mqPHYK/u\nHjgbad5qycB1haBq2cS6AL91yK0vqJikeegK4pT+0qECYAsh8zXDUzQutEw6okRF\neAwtZVuUAXTK44x8ik5kk8C6n9MDdIJnsIO5p6bLYeQts2K4yYlttwZOAq1a5hWH\n2hW0ZJyQWUkJ/rN9vLZUvrcmjsgB5ai0qjkRvr2IVC8Fvg==\n-----END RSA PRIVATE KEY-----\n",
- "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArkXtVgHOxrjMBfgDk1xn\nTdvg11xMCf15UfxrDK7DE6jfOZcMUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn\n9UBLVp5O4b3PPB+wPvETgC1PhV65tRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4j\nwSrZK5gIhMZB9aj6wmva1KAzgaIv4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2\nAMKu6uVuAvfPefwUzzvcfNhP67v5UMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQ\ndle5V4V+/eYBCYirfeQX/IjY84TE5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muD\nuwIDAQAB\n-----END PUBLIC KEY-----\n-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEArkXtVgHOxrjMBfgDk1xnTdvg11xMCf15UfxrDK7DE6jfOZcM\nUYv/ul7Wjz8NfyKkAp1BPxrgfk6+nkF3ziPn9UBLVp5O4b3PPB+wPvETgC1PhV65\ntRNLWnyAha3K5vovoUF+w3Y74XGwxit2Dt4jwSrZK5gIhMZB9aj6wmva1KAzgaIv\n4bdUiFCUyCUG1AGaU1ooav6ycbubpZLeGNz2AMKu6uVuAvfPefwUzzvcfNhP67v5\nUMqQMEsiGaeqBjrvosPBmA5WDNZK/neVhbYQdle5V4V+/eYBCYirfeQX/IjY84TE\n5ucsP5Q+DDHAxKXMNvh52KOsnX1Zhg6q2muDuwIDAQABAoIBAFyN+sxwzVaxEnoh\nDBUZQCwTmMgH1sJ/gg1O17O2pRgt2dAGLp6okbpzX9RYElzxEtXompxfM9chDw+R\niYVLgIe6C8kG7rHpUsSFt97VvhuW9OLKOiq3ApAeC0vzzwz41o7379DzXD4RWWcF\n8f9XbvnKPehvKCcL/D/x7KuRCHlfcePoXxNqn5d8sTvh6/sn+8FRT63/A5FYxhQX\nMt8loVGw8ezKX5U98U/gvoSWCK6lJ4YEcBgdlIewIj0ueWehA7cLMzzPpVxtqp1J\nFEw1ruWhwGiIIPHEgj8tnyAq17lDs6I/Drx0MGJ9eWQNpn0RVRDluALBIuf5RjU1\ntCRJU+ECgYEA7PWuzR5VFf/6y9daKBbG6/SQGM37RjjhhdZqc5a2+AkPgBjH/ZXM\nNLhX3BfwzGUWuxNGq01YLK2te0EDNSOHtwM40IQEfJ2VObZJYgSz3W6kQkmSB77A\nH5ZCh/9jNsOYRlgzaEb1bkaGGIHBAjPSF2vxWl6W3ceAvIaKp30852kCgYEAvEbE\nZPxqxMp4Ow6wijyEG3cvfpsvKLq9WIroheGgxh5IWKD7JawpmZDzW+hRZMJZuhF1\nzdcZJwcTUYSZK2wpt0bdDSyr4UKDX30UjMFhUktKCZRtSLgoRz8c52tstohsNFwD\n4F9B1RtcOpCj8kBzx9dKT+JdnPIcdZYPP8OGMYMCgYEAxzVkVx0A+xXQij3plXpQ\nkV1xJulELaz0K8guhi5Wc/9qAI7U0uN0YX34nxehYLQ7f9qctra3QhhgmBX31Fyi\nY8FZqjLSctEn+vS8jKLXc3jorrGbCtfaPLPeCucxSYD2K21LCoddHfA8G645zNgz\n72zX4tlSi/CE0flp55Tp9sECgYAmWLN/bfnBAwvh22gRf6nYfjnqK2k7fm06L3CU\ndBPuxhQuGPuN/LasVF18hqCtSPhFcXDw77JrxIEmxT79HRaSAZjcKhEH3CgttqgM\n0wYjYLo/oT9w5DEv8abNa4/EzZxcPbF8bWpXIS9zrin2GTJ7rVmxU4WFhbpOKLYK\nYqReSQKBgG84Ums5JQhVNO8+QVqDbt6LhhWKLHy/7MsL2DQwT+xoO6jU9HnEM9Q0\nFuYyaWI86hAHdtha/0AdP/9hDuZUEc47E2PWOpcJ7t5CZHzqVhST1UVwqHnBhoLN\nl3ELliBewxEX1ztfNiI/rdboupDdfA7mHUThYyUeIMf2brMFEXy4\n-----END RSA PRIVATE KEY-----\n",
- NULL,
- };
- struct key_pair {
- SecKeyRef pubKey, privKey;
- };
- key_pair keys[11];
-
- int i;
- for(i = 0; i < sizeof(keys)/sizeof(key_pair); i++) {
- NSAssert(pem_key_bytes[i] != NULL, @"Expected a key");
- NSLog(@"Importing: %s", pem_key_bytes[i]);
- CFDataRef pem_data = CFDataCreate(NULL, (UInt8*)(pem_key_bytes[i]), strlen(pem_key_bytes[i]));
- SecKeyImportExportParameters import_params;
- bzero(&import_params, sizeof(import_params));
-
- import_params.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
- import_params.keyUsage = CSSM_KEYUSE_ANY;
- import_params.keyAttributes = CSSM_KEYATTR_PERMANENT|CSSM_KEYATTR_SENSITIVE;
- import_params.accessRef = NULL;
- import_params.passphrase = CFSTR("");
- import_params.alertPrompt = CFSTR("");
-
- CFArrayRef keypair = NULL;
- SecExternalFormat key_format = kSecFormatOpenSSL;
- SecExternalItemType itemType = kSecItemTypeUnknown;
- status = SecKeychainItemImport(pem_data, CFSTR(".pem"), &key_format, &itemType, 0, &import_params, tmp_keychain, &keypair);
- STAssertTrue(status == 0, @"Expected pubkey import to be ok, got err=0x%x", status);
- NSAssert(keypair != NULL, @"Expected to get some keys back");
- STAssertNotNil((id)keypair, @"Expected to get some keys back");
- STAssertTrue(CFArrayGetCount(keypair) == 2, @"Expected 2 keys, got %@", keypair);
- keys[i].pubKey = (SecKeyRef)CFArrayGetValueAtIndex(keypair, 0);
- keys[i].privKey = (SecKeyRef)CFArrayGetValueAtIndex(keypair, 1);
- }
- STAssertNil((id)pem_key_bytes[i], @"Expected to convert all pem keys, but found at least: %s", pem_key_bytes[i]);
- CFDataRef encoding_parameters = CFDataCreate(NULL, NULL, 0);
-
- struct KAT {
- NSData *message, *seed, *encryptedMessage;
- NSString *label;
- key_pair keys;
- };
- KAT tests[] = {
- // This first one is from the spec
- {
- .message = [NSData dataWithHexString:@"d436e99569fd32a7c8a05bbc90d32c49"],
- .seed = [NSData dataWithHexString:@"aafd12f659cae63489b479e5076ddec2f06cb58f"],
- .encryptedMessage = [NSData dataWithHexString:@"1253e04dc0a5397bb44a7ab87e9bf2a039a33d1e996fc82a94ccd30074c95df763722017069e5268da5d1c0b4f872cf653c11df82314a67968dfeae28def04bb6d84b1c31d654a1970e5783bd6eb96a024c2ca2f4a90fe9f2ef5c9c140e5bb48da9536ad8700c84fc9130adea74e558d51a74ddf85d8b50de96838d6063e0955"],
- .keys = keys[0],
- .label = @"From spec",
- },
- // The next 60 are from oaep-vect.txt
- {
- .message = [NSData dataWithHexString:@"6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34"],
- .seed = [NSData dataWithHexString:@"18b776ea21069d69776a33e96bad48e1dda0a5ef"],
- .encryptedMessage = [NSData dataWithHexString:@"354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535fa9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a"],
- .keys = keys[1],
- .label = @"1-1",
- },
- {
- .message = [NSData dataWithHexString:@"750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"],
- .seed = [NSData dataWithHexString:@"0cc742ce4a9b7f32f951bcb251efd925fe4fe35f"],
- .encryptedMessage = [NSData dataWithHexString:@"640db1acc58e0568fe5407e5f9b701dff8c3c91e716c536fc7fcec6cb5b71c1165988d4a279e1577d730fc7a29932e3f00c81515236d8d8e31017a7a09df4352d904cdeb79aa583adcc31ea698a4c05283daba9089be5491f67c1a4ee48dc74bbbe6643aef846679b4cb395a352d5ed115912df696ffe0702932946d71492b44"],
- .keys = keys[1],
- .label = @"1-2",
- },
- {
- .message = [NSData dataWithHexString:@"d94ae0832e6445ce42331cb06d531a82b1db4baad30f746dc916df24d4e3c2451fff59a6423eb0e1d02d4fe646cf699dfd818c6e97b051"],
- .seed = [NSData dataWithHexString:@"2514df4695755a67b288eaf4905c36eec66fd2fd"],
- .encryptedMessage = [NSData dataWithHexString:@"423736ed035f6026af276c35c0b3741b365e5f76ca091b4e8c29e2f0befee603595aa8322d602d2e625e95eb81b2f1c9724e822eca76db8618cf09c5343503a4360835b5903bc637e3879fb05e0ef32685d5aec5067cd7cc96fe4b2670b6eac3066b1fcf5686b68589aafb7d629b02d8f8625ca3833624d4800fb081b1cf94eb"],
- .keys = keys[1],
- .label = @"1-3",
- },
- {
- .message = [NSData dataWithHexString:@"52e650d98e7f2a048b4f86852153b97e01dd316f346a19f67a85"],
- .seed = [NSData dataWithHexString:@"c4435a3e1a18a68b6820436290a37cefb85db3fb"],
- .encryptedMessage = [NSData dataWithHexString:@"45ead4ca551e662c9800f1aca8283b0525e6abae30be4b4aba762fa40fd3d38e22abefc69794f6ebbbc05ddbb11216247d2f412fd0fba87c6e3acd888813646fd0e48e785204f9c3f73d6d8239562722dddd8771fec48b83a31ee6f592c4cfd4bc88174f3b13a112aae3b9f7b80e0fc6f7255ba880dc7d8021e22ad6a85f0755"],
- .keys = keys[1],
- .label = @"1-4",
- },
- {
- .message = [NSData dataWithHexString:@"8da89fd9e5f974a29feffb462b49180f6cf9e802"],
- .seed = [NSData dataWithHexString:@"b318c42df3be0f83fea823f5a7b47ed5e425a3b5"],
- .encryptedMessage = [NSData dataWithHexString:@"36f6e34d94a8d34daacba33a2139d00ad85a9345a86051e73071620056b920e219005855a213a0f23897cdcd731b45257c777fe908202befdd0b58386b1244ea0cf539a05d5d10329da44e13030fd760dcd644cfef2094d1910d3f433e1c7c6dd18bc1f2df7f643d662fb9dd37ead9059190f4fa66ca39e869c4eb449cbdc439"],
- .keys = keys[1],
- .label = @"1-5",
- },
- {
- .message = [NSData dataWithHexString:@"26521050844271"],
- .seed = [NSData dataWithHexString:@"e4ec0982c2336f3a677f6a356174eb0ce887abc2"],
- .encryptedMessage = [NSData dataWithHexString:@"42cee2617b1ecea4db3f4829386fbd61dafbf038e180d837c96366df24c097b4ab0fac6bdf590d821c9f10642e681ad05b8d78b378c0f46ce2fad63f74e0ad3df06b075d7eb5f5636f8d403b9059ca761b5c62bb52aa45002ea70baace08ded243b9d8cbd62a68ade265832b56564e43a6fa42ed199a099769742df1539e8255"],
- .keys = keys[1],
- .label = @"1-6",
- },
-
- {
- .message = [NSData dataWithHexString:@"8ff00caa605c702830634d9a6c3d42c652b58cf1d92fec570beee7"],
- .seed = [NSData dataWithHexString:@"8c407b5ec2899e5099c53e8ce793bf94e71b1782"],
- .encryptedMessage = [NSData dataWithHexString:@"0181af8922b9fcb4d79d92ebe19815992fc0c1439d8bcd491398a0f4ad3a329a5bd9385560db532683c8b7da04e4b12aed6aacdf471c34c9cda891addcc2df3456653aa6382e9ae59b54455257eb099d562bbe10453f2b6d13c59c02e10f1f8abb5da0d0570932dacf2d0901db729d0fefcc054e70968ea540c81b04bcaefe720e"],
- .keys = keys[2],
- .label = @"2-1",
- },
- {
- .message = [NSData dataWithHexString:@"2d"],
- .seed = [NSData dataWithHexString:@"b600cf3c2e506d7f16778c910d3a8b003eee61d5"],
- .encryptedMessage = [NSData dataWithHexString:@"018759ff1df63b2792410562314416a8aeaf2ac634b46f940ab82d64dbf165eee33011da749d4bab6e2fcd18129c9e49277d8453112b429a222a8471b070993998e758861c4d3f6d749d91c4290d332c7a4ab3f7ea35ff3a07d497c955ff0ffc95006b62c6d296810d9bfab024196c7934012c2df978ef299aba239940cba10245"],
- .keys = keys[2],
- .label = @"2-2",
- },
- {
- .message = [NSData dataWithHexString:@"74fc88c51bc90f77af9d5e9a4a70133d4b4e0b34da3c37c7ef8e"],
- .seed = [NSData dataWithHexString:@"a73768aeeaa91f9d8c1ed6f9d2b63467f07ccae3"],
- .encryptedMessage = [NSData dataWithHexString:@"018802bab04c60325e81c4962311f2be7c2adce93041a00719c88f957575f2c79f1b7bc8ced115c706b311c08a2d986ca3b6a9336b147c29c6f229409ddec651bd1fdd5a0b7f610c9937fdb4a3a762364b8b3206b4ea485fd098d08f63d4aa8bb2697d027b750c32d7f74eaf5180d2e9b66b17cb2fa55523bc280da10d14be2053"],
- .keys = keys[2],
- .label = @"2-3",
- },
- {
- .message = [NSData dataWithHexString:@"a7eb2a5036931d27d4e891326d99692ffadda9bf7efd3e34e622c4adc085f721dfe885072c78a203b151739be540fa8c153a10f00a"],
- .seed = [NSData dataWithHexString:@"9a7b3b0e708bd96f8190ecab4fb9b2b3805a8156"],
- .encryptedMessage = [NSData dataWithHexString:@"00a4578cbc176318a638fba7d01df15746af44d4f6cd96d7e7c495cbf425b09c649d32bf886da48fbaf989a2117187cafb1fb580317690e3ccd446920b7af82b31db5804d87d01514acbfa9156e782f867f6bed9449e0e9a2c09bcecc6aa087636965e34b3ec766f2fe2e43018a2fddeb140616a0e9d82e5331024ee0652fc7641"],
- .keys = keys[2],
- .label = @"2-4",
- },
- {
- .message = [NSData dataWithHexString:@"2ef2b066f854c33f3bdcbb5994a435e73d6c6c"],
- .seed = [NSData dataWithHexString:@"eb3cebbc4adc16bb48e88c8aec0e34af7f427fd3"],
- .encryptedMessage = [NSData dataWithHexString:@"00ebc5f5fda77cfdad3c83641a9025e77d72d8a6fb33a810f5950f8d74c73e8d931e8634d86ab1246256ae07b6005b71b7f2fb98351218331ce69b8ffbdc9da08bbc9c704f876deb9df9fc2ec065cad87f9090b07acc17aa7f997b27aca48806e897f771d95141fe4526d8a5301b678627efab707fd40fbebd6e792a25613e7aec"],
- .keys = keys[2],
- .label = @"2-5",
- },
- {
- .message = [NSData dataWithHexString:@"8a7fb344c8b6cb2cf2ef1f643f9a3218f6e19bba89c0"],
- .seed = [NSData dataWithHexString:@"4c45cf4d57c98e3d6d2095adc51c489eb50dff84"],
- .encryptedMessage = [NSData dataWithHexString:@"010839ec20c27b9052e55befb9b77e6fc26e9075d7a54378c646abdf51e445bd5715de81789f56f1803d9170764a9e93cb78798694023ee7393ce04bc5d8f8c5a52c171d43837e3aca62f609eb0aa5ffb0960ef04198dd754f57f7fbe6abf765cf118b4ca443b23b5aab266f952326ac4581100644325f8b721acd5d04ff14ef3a"],
- .keys = keys[2],
- .label = @"2-6",
- },
-
- {
- .message = [NSData dataWithHexString:@"087820b569e8fa8d"],
- .seed = [NSData dataWithHexString:@"8ced6b196290805790e909074015e6a20b0c4894"],
- .encryptedMessage = [NSData dataWithHexString:@"026a0485d96aebd96b4382085099b962e6a2bdec3d90c8db625e14372de85e2d5b7baab65c8faf91bb5504fb495afce5c988b3f6a52e20e1d6cbd3566c5cd1f2b8318bb542cc0ea25c4aab9932afa20760eaddec784396a07ea0ef24d4e6f4d37e5052a7a31e146aa480a111bbe926401307e00f410033842b6d82fe5ce4dfae80"],
- .keys = keys[3],
- .label = @"3-1",
- },
- {
- .message = [NSData dataWithHexString:@"4653acaf171960b01f52a7be63a3ab21dc368ec43b50d82ec3781e04"],
- .seed = [NSData dataWithHexString:@"b4291d6567550848cc156967c809baab6ca507f0"],
- .encryptedMessage = [NSData dataWithHexString:@"024db89c7802989be0783847863084941bf209d761987e38f97cb5f6f1bc88da72a50b73ebaf11c879c4f95df37b850b8f65d7622e25b1b889e80fe80baca2069d6e0e1d829953fc459069de98ea9798b451e557e99abf8fe3d9ccf9096ebbf3e5255d3b4e1c6d2ecadf067a359eea86405acd47d5e165517ccafd47d6dbee4bf5"],
- .keys = keys[3],
- .label = @"3-2",
- },
- {
- .message = [NSData dataWithHexString:@"d94cd0e08fa404ed89"],
- .seed = [NSData dataWithHexString:@"ce8928f6059558254008badd9794fadcd2fd1f65"],
- .encryptedMessage = [NSData dataWithHexString:@"0239bce681032441528877d6d1c8bb28aa3bc97f1df584563618995797683844ca86664732f4bed7a0aab083aaabfb7238f582e30958c2024e44e57043b97950fd543da977c90cdde5337d618442f99e60d7783ab59ce6dd9d69c47ad1e962bec22d05895cff8d3f64ed5261d92b2678510393484990ba3f7f06818ae6ffce8a3a"],
- .keys = keys[3],
- .label = @"3-3",
- },
- {
- .message = [NSData dataWithHexString:@"6cc641b6b61e6f963974dad23a9013284ef1"],
- .seed = [NSData dataWithHexString:@"6e2979f52d6814a57d83b090054888f119a5b9a3"],
- .encryptedMessage = [NSData dataWithHexString:@"02994c62afd76f498ba1fd2cf642857fca81f4373cb08f1cbaee6f025c3b512b42c3e8779113476648039dbe0493f9246292fac28950600e7c0f32edf9c81b9dec45c3bde0cc8d8847590169907b7dc5991ceb29bb0714d613d96df0f12ec5d8d3507c8ee7ae78dd83f216fa61de100363aca48a7e914ae9f42ddfbe943b09d9a0"],
- .keys = keys[3],
- .label = @"3-4",
- },
- {
- .message = [NSData dataWithHexString:@"df5151832b61f4f25891fb4172f328d2eddf8371ffcfdbe997939295f30eca6918017cfda1153bf7a6af87593223"],
- .seed = [NSData dataWithHexString:@"2d760bfe38c59de34cdc8b8c78a38e66284a2d27"],
- .encryptedMessage = [NSData dataWithHexString:@"0162042ff6969592a6167031811a239834ce638abf54fec8b99478122afe2ee67f8c5b18b0339805bfdbc5a4e6720b37c59cfba942464c597ff532a119821545fd2e59b114e61daf71820529f5029cf524954327c34ec5e6f5ba7efcc4de943ab8ad4ed787b1454329f70db798a3a8f4d92f8274e2b2948ade627ce8ee33e43c60"],
- .keys = keys[3],
- .label = @"3-5",
- },
- {
- .message = [NSData dataWithHexString:@"3c3bad893c544a6d520ab022319188c8d504b7a788b850903b85972eaa18552e1134a7ad6098826254ff7ab672b3d8eb3158fac6d4cbaef1"],
- .seed = [NSData dataWithHexString:@"f174779c5fd3cfe007badcb7a36c9b55bfcfbf0e"],
- .encryptedMessage = [NSData dataWithHexString:@"00112051e75d064943bc4478075e43482fd59cee0679de6893eec3a943daa490b9691c93dfc0464b6623b9f3dbd3e70083264f034b374f74164e1a00763725e574744ba0b9db83434f31df96f6e2a26f6d8eba348bd4686c2238ac07c37aac3785d1c7eea2f819fd91491798ed8e9cef5e43b781b0e0276e37c43ff9492d005730"],
- .label = @"3-6",
- .keys = keys[3],
- },
-
- {
- .message = [NSData dataWithHexString:@"4a86609534ee434a6cbca3f7e962e76d455e3264c19f605f6e5ff6137c65c56d7fb344cd52bc93374f3d166c9f0c6f9c506bad19330972d2"],
- .seed = [NSData dataWithHexString:@"1cac19ce993def55f98203f6852896c95ccca1f3"],
- .encryptedMessage = [NSData dataWithHexString:@"04cce19614845e094152a3fe18e54e3330c44e5efbc64ae16886cb1869014cc5781b1f8f9e045384d0112a135ca0d12e9c88a8e4063416deaae3844f60d6e96fe155145f4525b9a34431ca3766180f70e15a5e5d8e8b1a516ff870609f13f896935ced188279a58ed13d07114277d75c6568607e0ab092fd803a223e4a8ee0b1a8"],
- .keys = keys[4],
- .label = @"4-1",
- },
- {
- .message = [NSData dataWithHexString:@"b0adc4f3fe11da59ce992773d9059943c03046497ee9d9f9a06df1166db46d98f58d27ec074c02eee6cbe2449c8b9fc5080c5c3f4433092512ec46aa793743c8"],
- .seed = [NSData dataWithHexString:@"f545d5897585e3db71aa0cb8da76c51d032ae963"],
- .encryptedMessage = [NSData dataWithHexString:@"0097b698c6165645b303486fbf5a2a4479c0ee85889b541a6f0b858d6b6597b13b854eb4f839af03399a80d79bda6578c841f90d645715b280d37143992dd186c80b949b775cae97370e4ec97443136c6da484e970ffdb1323a20847821d3b18381de13bb49aaea66530c4a4b8271f3eae172cd366e07e6636f1019d2a28aed15e"],
- .keys = keys[4],
- .label = @"4-2",
- },
- {
- .message = [NSData dataWithHexString:@"bf6d42e701707b1d0206b0c8b45a1c72641ff12889219a82bdea965b5e79a96b0d0163ed9d578ec9ada20f2fbcf1ea3c4089d83419ba81b0c60f3606da99"],
- .seed = [NSData dataWithHexString:@"ad997feef730d6ea7be60d0dc52e72eacbfdd275"],
- .encryptedMessage = [NSData dataWithHexString:@"0301f935e9c47abcb48acbbe09895d9f5971af14839da4ff95417ee453d1fd77319072bb7297e1b55d7561cd9d1bb24c1a9a37c619864308242804879d86ebd001dce5183975e1506989b70e5a83434154d5cbfd6a24787e60eb0c658d2ac193302d1192c6e622d4a12ad4b53923bca246df31c6395e37702c6a78ae081fb9d065"],
- .keys = keys[4],
- .label = @"4-3",
- },
- {
- .message = [NSData dataWithHexString:@"fb2ef112f5e766eb94019297934794f7be2f6fc1c58e"],
- .seed = [NSData dataWithHexString:@"136454df5730f73c807a7e40d8c1a312ac5b9dd3"],
- .encryptedMessage = [NSData dataWithHexString:@"02d110ad30afb727beb691dd0cf17d0af1a1e7fa0cc040ec1a4ba26a42c59d0a796a2e22c8f357ccc98b6519aceb682e945e62cb734614a529407cd452bee3e44fece8423cc19e55548b8b994b849c7ecde4933e76037e1d0ce44275b08710c68e430130b929730ed77e09b015642c5593f04e4ffb9410798102a8e96ffdfe11e4"],
- .keys = keys[4],
- .label = @"4-4",
- },
- {
- .message = [NSData dataWithHexString:@"28ccd447bb9e85166dabb9e5b7d1adadc4b9d39f204e96d5e440ce9ad928bc1c2284"],
- .seed = [NSData dataWithHexString:@"bca8057f824b2ea257f2861407eef63d33208681"],
- .encryptedMessage = [NSData dataWithHexString:@"00dbb8a7439d90efd919a377c54fae8fe11ec58c3b858362e23ad1b8a44310799066b99347aa525691d2adc58d9b06e34f288c170390c5f0e11c0aa3645959f18ee79e8f2be8d7ac5c23d061f18dd74b8c5f2a58fcb5eb0c54f99f01a83247568292536583340948d7a8c97c4acd1e98d1e29dc320e97a260532a8aa7a758a1ec2"],
- .keys = keys[4],
- .label = @"4-5",
- },
- {
- .message = [NSData dataWithHexString:@"f22242751ec6b1"],
- .seed = [NSData dataWithHexString:@"2e7e1e17f647b5ddd033e15472f90f6812f3ac4e"],
- .encryptedMessage = [NSData dataWithHexString:@"00a5ffa4768c8bbecaee2db77e8f2eec99595933545520835e5ba7db9493d3e17cddefe6a5f567624471908db4e2d83a0fbee60608fc84049503b2234a07dc83b27b22847ad8920ff42f674ef79b76280b00233d2b51b8cb2703a9d42bfbc8250c96ec32c051e57f1b4ba528db89c37e4c54e27e6e64ac69635ae887d9541619a9"],
- .keys = keys[4],
- .label = @"4-6",
- },
-
- {
- .message = [NSData dataWithHexString:@"af71a901e3a61d3132f0fc1fdb474f9ea6579257ffc24d164170145b3dbde8"],
- .seed = [NSData dataWithHexString:@"44c92e283f77b9499c603d963660c87d2f939461"],
- .encryptedMessage = [NSData dataWithHexString:@"036046a4a47d9ed3ba9a89139c105038eb7492b05a5d68bfd53accff4597f7a68651b47b4a4627d927e485eed7b4566420e8b409879e5d606eae251d22a5df799f7920bfc117b992572a53b1263146bcea03385cc5e853c9a101c8c3e1bda31a519807496c6cb5e5efb408823a352b8fa0661fb664efadd593deb99fff5ed000e5"],
- .keys = keys[5],
- .label = @"5-1",
- },
- {
- .message = [NSData dataWithHexString:@"a3b844a08239a8ac41605af17a6cfda4d350136585903a417a79268760519a4b4ac3303ec73f0f87cfb32399"],
- .seed = [NSData dataWithHexString:@"cb28f5860659fceee49c3eeafce625a70803bd32"],
- .encryptedMessage = [NSData dataWithHexString:@"03d6eb654edce615bc59f455265ed4e5a18223cbb9be4e4069b473804d5de96f54dcaaa603d049c5d94aa1470dfcd2254066b7c7b61ff1f6f6770e3215c51399fd4e34ec5082bc48f089840ad04354ae66dc0f1bd18e461a33cc1258b443a2837a6df26759aa2302334986f87380c9cc9d53be9f99605d2c9a97da7b0915a4a7ad"],
- .keys = keys[5],
- .label = @"5-2",
- },
- {
- .message = [NSData dataWithHexString:@"308b0ecbd2c76cb77fc6f70c5edd233fd2f20929d629f026953bb62a8f4a3a314bde195de85b5f816da2aab074d26cb6acddf323ae3b9c678ac3cf12fbdde7"],
- .seed = [NSData dataWithHexString:@"2285f40d770482f9a9efa2c72cb3ac55716dc0ca"],
- .encryptedMessage = [NSData dataWithHexString:@"0770952181649f9f9f07ff626ff3a22c35c462443d905d456a9fd0bff43cac2ca7a9f554e9478b9acc3ac838b02040ffd3e1847de2e4253929f9dd9ee4044325a9b05cabb808b2ee840d34e15d105a3f1f7b27695a1a07a2d73fe08ecaaa3c9c9d4d5a89ff890d54727d7ae40c0ec1a8dd86165d8ee2c6368141016a48b55b6967"],
- .keys = keys[5],
- .label = @"5-3",
- },
- {
- .message = [NSData dataWithHexString:@"15c5b9ee1185"],
- .seed = [NSData dataWithHexString:@"49fa45d3a78dd10dfd577399d1eb00af7eed5513"],
- .encryptedMessage = [NSData dataWithHexString:@"0812b76768ebcb642d040258e5f4441a018521bd96687e6c5e899fcd6c17588ff59a82cc8ae03a4b45b31299af1788c329f7dcd285f8cf4ced82606b97612671a45bedca133442144d1617d114f802857f0f9d739751c57a3f9ee400912c61e2e6992be031a43dd48fa6ba14eef7c422b5edc4e7afa04fdd38f402d1c8bb719abf"],
- .keys = keys[5],
- .label = @"5-4",
- },
- {
- .message = [NSData dataWithHexString:@"21026e6800c7fa728fcaaba0d196ae28d7a2ac4ffd8abce794f0985f60c8a6737277365d3fea11db8923a2029a"],
- .seed = [NSData dataWithHexString:@"f0287413234cc5034724a094c4586b87aff133fc"],
- .encryptedMessage = [NSData dataWithHexString:@"07b60e14ec954bfd29e60d0047e789f51d57186c63589903306793ced3f68241c743529aba6a6374f92e19e0163efa33697e196f7661dfaaa47aac6bde5e51deb507c72c589a2ca1693d96b1460381249b2cdb9eac44769f2489c5d3d2f99f0ee3c7ee5bf64a5ac79c42bd433f149be8cb59548361640595513c97af7bc2509723"],
- .keys = keys[5],
- .label = @"5-5",
- },
- {
- .message = [NSData dataWithHexString:@"541e37b68b6c8872b84c02"],
- .seed = [NSData dataWithHexString:@"d9fba45c96f21e6e26d29eb2cdcb6585be9cb341"],
- .encryptedMessage = [NSData dataWithHexString:@"08c36d4dda33423b2ed6830d85f6411ba1dcf470a1fae0ebefee7c089f256cef74cb96ea69c38f60f39abee44129bcb4c92de7f797623b20074e3d9c2899701ed9071e1efa0bdd84d4c3e5130302d8f0240baba4b84a71cc032f2235a5ff0fae277c3e8f9112bef44c9ae20d175fc9a4058bfc930ba31b02e2e4f444483710f24a"],
- .keys = keys[5],
- .label = @"5-6",
- },
- {
- .label = @"6-1",
- .keys = keys[6],
- .message = [NSData dataWithHexString:@"4046ca8baa3347ca27f49e0d81f9cc1d71be9ba517d4"],
- .seed = [NSData dataWithHexString:@"dd0f6cfe415e88e5a469a51fbba6dfd40adb4384"],
- .encryptedMessage = [NSData dataWithHexString:@"0630eebcd2856c24f798806e41f9e67345eda9ceda386acc9facaea1eeed06ace583709718d9d169fadf414d5c76f92996833ef305b75b1e4b95f662a20faedc3bae0c4827a8bf8a88edbd57ec203a27a841f02e43a615bab1a8cac0701de34debdef62a088089b55ec36ea7522fd3ec8d06b6a073e6df833153bc0aefd93bd1a3"],
- },
- {
- .label = @"6-2",
- .keys = keys[6],
- .message = [NSData dataWithHexString:@"5cc72c60231df03b3d40f9b57931bc31109f972527f28b19e7480c7288cb3c92b22512214e4be6c914792ddabdf57faa8aa7"],
- .seed = [NSData dataWithHexString:@"8d14bd946a1351148f5cae2ed9a0c653e85ebd85"],
- .encryptedMessage = [NSData dataWithHexString:@"0ebc37376173a4fd2f89cc55c2ca62b26b11d51c3c7ce49e8845f74e7607317c436bc8d23b9667dfeb9d087234b47bc6837175ae5c0559f6b81d7d22416d3e50f4ac533d8f0812f2db9e791fe9c775ac8b6ad0f535ad9ceb23a4a02014c58ab3f8d3161499a260f39348e714ae2a1d3443208fd8b722ccfdfb393e98011f99e63f"],
- },
- {
- .label = @"6-3",
- .keys = keys[6],
- .message = [NSData dataWithHexString:@"b20e651303092f4bccb43070c0f86d23049362ed96642fc5632c27db4a52e3d831f2ab068b23b149879c002f6bf3feee97591112562c"],
- .seed = [NSData dataWithHexString:@"6c075bc45520f165c0bf5ea4c5df191bc9ef0e44"],
- .encryptedMessage = [NSData dataWithHexString:@"0a98bf1093619394436cf68d8f38e2f158fde8ea54f3435f239b8d06b8321844202476aeed96009492480ce3a8d705498c4c8c68f01501dc81db608f60087350c8c3b0bd2e9ef6a81458b7c801b89f2e4fe99d4900ba6a4b5e5a96d865dc676c7755928794130d6280a8160a190f2df3ea7cf9aa0271d88e9e6905ecf1c5152d65"],
- },
- {
- .label = @"6-4",
- .keys = keys[6],
- .message = [NSData dataWithHexString:@"684e3038c5c041f7"],
- .seed = [NSData dataWithHexString:@"3bbc3bd6637dfe12846901029bf5b0c07103439c"],
- .encryptedMessage = [NSData dataWithHexString:@"008e7a67cacfb5c4e24bec7dee149117f19598ce8c45808fef88c608ff9cd6e695263b9a3c0ad4b8ba4c95238e96a8422b8535629c8d5382374479ad13fa39974b242f9a759eeaf9c83ad5a8ca18940a0162ba755876df263f4bd50c6525c56090267c1f0e09ce0899a0cf359e88120abd9bf893445b3cae77d3607359ae9a52f8"],
- },
- {
- .label = @"6-5",
- .keys = keys[6],
- .message = [NSData dataWithHexString:@"32488cb262d041d6e4dd35f987bf3ca696db1f06ac29a44693"],
- .seed = [NSData dataWithHexString:@"b46b41893e8bef326f6759383a83071dae7fcabc"],
- .encryptedMessage = [NSData dataWithHexString:@"00003474416c7b68bdf961c385737944d7f1f40cb395343c693cc0b4fe63b31fedf1eaeeac9ccc0678b31dc32e0977489514c4f09085f6298a9653f01aea4045ff582ee887be26ae575b73eef7f3774921e375a3d19adda0ca31aa1849887c1f42cac9677f7a2f4e923f6e5a868b38c084ef187594dc9f7f048fea2e02955384ab"],
- },
- {
- .label = @"6-6",
- .keys = keys[6],
- .message = [NSData dataWithHexString:@"50ba14be8462720279c306ba"],
- .seed = [NSData dataWithHexString:@"0a2403312a41e3d52f060fbc13a67de5cf7609a7"],
- .encryptedMessage = [NSData dataWithHexString:@"0a026dda5fc8785f7bd9bf75327b63e85e2c0fdee5dadb65ebdcac9ae1de95c92c672ab433aa7a8e69ce6a6d8897fac4ac4a54de841ae5e5bbce7687879d79634cea7a30684065c714d52409b928256bbf53eabcd5231eb7259504537399bd29164b726d33a46da701360a4168a091ccab72d44a62fed246c0ffea5b1348ab5470"],
- },
- {
- .label = @"7-1",
- .keys = keys[7],
- .message = [NSData dataWithHexString:@"47aae909"],
- .seed = [NSData dataWithHexString:@"43dd09a07ff4cac71caa4632ee5e1c1daee4cd8f"],
- .encryptedMessage = [NSData dataWithHexString:@"1688e4ce7794bba6cb7014169ecd559cede2a30b56a52b68d9fe18cf1973ef97b2a03153951c755f6294aa49adbdb55845ab6875fb3986c93ecf927962840d282f9e54ce8b690f7c0cb8bbd73440d9571d1b16cd9260f9eab4783cc482e5223dc60973871783ec27b0ae0fd47732cbc286a173fc92b00fb4ba6824647cd93c85c1"],
- },
- {
- .label = @"7-2",
- .keys = keys[7],
- .message = [NSData dataWithHexString:@"1d9b2e2223d9bc13bfb9f162ce735db48ba7c68f6822a0a1a7b6ae165834e7"],
- .seed = [NSData dataWithHexString:@"3a9c3cec7b84f9bd3adecbc673ec99d54b22bc9b"],
- .encryptedMessage = [NSData dataWithHexString:@"1052ed397b2e01e1d0ee1c50bf24363f95e504f4a03434a08fd822574ed6b9736edbb5f390db10321479a8a139350e2bd4977c3778ef331f3e78ae118b268451f20a2f01d471f5d53c566937171b2dbc2d4bde459a5799f0372d6574239b2323d245d0bb81c286b63c89a361017337e4902f88a467f4c7f244bfd5ab46437ff3b6"],
- },
- {
- .label = @"7-3",
- .keys = keys[7],
- .message = [NSData dataWithHexString:@"d976fc"],
- .seed = [NSData dataWithHexString:@"76a75e5b6157a556cf8884bb2e45c293dd545cf5"],
- .encryptedMessage = [NSData dataWithHexString:@"2155cd843ff24a4ee8badb7694260028a490813ba8b369a4cbf106ec148e5298707f5965be7d101c1049ea8584c24cd63455ad9c104d686282d3fb803a4c11c1c2e9b91c7178801d1b6640f003f5728df007b8a4ccc92bce05e41a27278d7c85018c52414313a5077789001d4f01910b72aad05d220aa14a58733a7489bc54556b"],
- },
- {
- .label = @"7-4",
- .keys = keys[7],
- .message = [NSData dataWithHexString:@"d4738623df223aa43843df8467534c41d013e0c803c624e263666b239bde40a5f29aeb8de79e3daa61dd0370f49bd4b013834b98212aef6b1c5ee373b3cb"],
- .seed = [NSData dataWithHexString:@"7866314a6ad6f2b250a35941db28f5864b585859"],
- .encryptedMessage = [NSData dataWithHexString:@"0ab14c373aeb7d4328d0aaad8c094d88b9eb098b95f21054a29082522be7c27a312878b637917e3d819e6c3c568db5d843802b06d51d9e98a2be0bf40c031423b00edfbff8320efb9171bd2044653a4cb9c5122f6c65e83cda2ec3c126027a9c1a56ba874d0fea23f380b82cf240b8cf540004758c4c77d934157a74f3fc12bfac"],
- },
- {
- .label = @"7-5",
- .keys = keys[7],
- .message = [NSData dataWithHexString:@"bb47231ca5ea1d3ad46c99345d9a8a61"],
- .seed = [NSData dataWithHexString:@"b2166ed472d58db10cab2c6b000cccf10a7dc509"],
- .encryptedMessage = [NSData dataWithHexString:@"028387a318277434798b4d97f460068df5298faba5041ba11761a1cb7316b24184114ec500257e2589ed3b607a1ebbe97a6cc2e02bf1b681f42312a33b7a77d8e7855c4a6de03e3c04643f786b91a264a0d6805e2cea91e68177eb7a64d9255e4f27e713b7ccec00dc200ebd21c2ea2bb890feae4942df941dc3f97890ed347478"],
- },
- {
- .label = @"7-6",
- .keys = keys[7],
- .message = [NSData dataWithHexString:@"2184827095d35c3f86f600e8e59754013296"],
- .seed = [NSData dataWithHexString:@"52673bde2ca166c2aa46131ac1dc808d67d7d3b1"],
- .encryptedMessage = [NSData dataWithHexString:@"14c678a94ad60525ef39e959b2f3ba5c097a94ff912b67dbace80535c187abd47d075420b1872152bba08f7fc31f313bbf9273c912fc4c0149a9b0cfb79807e346eb332069611bec0ff9bcd168f1f7c33e77313cea454b94e2549eecf002e2acf7f6f2d2845d4fe0aab2e5a92ddf68c480ae11247935d1f62574842216ae674115"],
- },
- {
- .label = @"8-1",
- .keys = keys[8],
- .message = [NSData dataWithHexString:@"050b755e5e6880f7b9e9d692a74c37aae449b31bfea6deff83747a897f6c2c825bb1adbf850a3c96994b5de5b33cbc7d4a17913a7967"],
- .seed = [NSData dataWithHexString:@"7706ffca1ecfb1ebee2a55e5c6e24cd2797a4125"],
- .encryptedMessage = [NSData dataWithHexString:@"09b3683d8a2eb0fb295b62ed1fb9290b714457b7825319f4647872af889b30409472020ad12912bf19b11d4819f49614824ffd84d09c0a17e7d17309d12919790410aa2995699f6a86dbe3242b5acc23af45691080d6b1ae810fb3e3057087f0970092ce00be9562ff4053b6262ce0caa93e13723d2e3a5ba075d45f0d61b54b61"],
- },
- {
- .label = @"8-2",
- .keys = keys[8],
- .message = [NSData dataWithHexString:@"4eb68dcd93ca9b19df111bd43608f557026fe4aa1d5cfac227a3eb5ab9548c18a06dded23f81825986b2fcd71109ecef7eff88873f075c2aa0c469f69c92bc"],
- .seed = [NSData dataWithHexString:@"a3717da143b4dcffbc742665a8fa950585548343"],
- .encryptedMessage = [NSData dataWithHexString:@"2ecf15c97c5a15b1476ae986b371b57a24284f4a162a8d0c8182e7905e792256f1812ba5f83f1f7a130e42dcc02232844edc14a31a68ee97ae564a383a3411656424c5f62ddb646093c367be1fcda426cf00a06d8acb7e57776fbbd855ac3df506fc16b1d7c3f2110f3d8068e91e186363831c8409680d8da9ecd8cf1fa20ee39d"],
- },
- {
- .label = @"8-3",
- .keys = keys[8],
- .message = [NSData dataWithHexString:@"8604ac56328c1ab5ad917861"],
- .seed = [NSData dataWithHexString:@"ee06209073cca026bb264e5185bf8c68b7739f86"],
- .encryptedMessage = [NSData dataWithHexString:@"4bc89130a5b2dabb7c2fcf90eb5d0eaf9e681b7146a38f3173a3d9cfec52ea9e0a41932e648a9d69344c50da763f51a03c95762131e8052254dcd2248cba40fd31667786ce05a2b7b531ac9dac9ed584a59b677c1a8aed8c5d15d68c05569e2be780bf7db638fd2bfd2a85ab276860f3777338fca989ffd743d13ee08e0ca9893f"],
- },
- {
- .label = @"8-4",
- .keys = keys[8],
- .message = [NSData dataWithHexString:@"fdda5fbf6ec361a9d9a4ac68af216a0686f438b1e0e5c36b955f74e107f39c0dddcc"],
- .seed = [NSData dataWithHexString:@"990ad573dc48a973235b6d82543618f2e955105d"],
- .encryptedMessage = [NSData dataWithHexString:@"2e456847d8fc36ff0147d6993594b9397227d577752c79d0f904fcb039d4d812fea605a7b574dd82ca786f93752348438ee9f5b5454985d5f0e1699e3e7ad175a32e15f03deb042ab9fe1dd9db1bb86f8c089ccb45e7ef0c5ee7ca9b7290ca6b15bed47039788a8a93ff83e0e8d6244c71006362deef69b6f416fb3c684383fbd0"],
- },
- {
- .label = @"8-5",
- .keys = keys[8],
- .message = [NSData dataWithHexString:@"4a5f4914bee25de3c69341de07"],
- .seed = [NSData dataWithHexString:@"ecc63b28f0756f22f52ac8e6ec1251a6ec304718"],
- .encryptedMessage = [NSData dataWithHexString:@"1fb9356fd5c4b1796db2ebf7d0d393cc810adf6145defc2fce714f79d93800d5e2ac211ea8bbecca4b654b94c3b18b30dd576ce34dc95436ef57a09415645923359a5d7b4171ef22c24670f1b229d3603e91f76671b7df97e7317c97734476d5f3d17d21cf82b5ba9f83df2e588d36984fd1b584468bd23b2e875f32f68953f7b2"],
- },
- {
- .label = @"8-6",
- .keys = keys[8],
- .message = [NSData dataWithHexString:@"8e07d66f7b880a72563abcd3f35092bc33409fb7f88f2472be"],
- .seed = [NSData dataWithHexString:@"3925c71b362d40a0a6de42145579ba1e7dd459fc"],
- .encryptedMessage = [NSData dataWithHexString:@"3afd9c6600147b21798d818c655a0f4c9212db26d0b0dfdc2a7594ccb3d22f5bf1d7c3e112cd73fc7d509c7a8bafdd3c274d1399009f9609ec4be6477e453f075aa33db382870c1c3409aef392d7386ae3a696b99a94b4da0589447e955d16c98b17602a59bd736279fcd8fb280c4462d590bfa9bf13fed570eafde97330a2c210"],
- },
- {
- .label = @"9-1",
- .keys = keys[9],
- .message = [NSData dataWithHexString:@"f735fd55ba92592c3b52b8f9c4f69aaa1cbef8fe88add095595412467f9cf4ec0b896c59eda16210e7549c8abb10cdbc21a12ec9b6b5b8fd2f10399eb6"],
- .seed = [NSData dataWithHexString:@"8ec965f134a3ec9931e92a1ca0dc8169d5ea705c"],
- .encryptedMessage = [NSData dataWithHexString:@"267bcd118acab1fc8ba81c85d73003cb8610fa55c1d97da8d48a7c7f06896a4db751aa284255b9d36ad65f37653d829f1b37f97b8001942545b2fc2c55a7376ca7a1be4b1760c8e05a33e5aa2526b8d98e317088e7834c755b2a59b12631a182c05d5d43ab1779264f8456f515ce57dfdf512d5493dab7b7338dc4b7d78db9c091ac3baf537a69fc7f549d979f0eff9a94fda4169bd4d1d19a69c99e33c3b55490d501b39b1edae118ff6793a153261584d3a5f39f6e682e3d17c8cd1261fa72"],
- },
- {
- .label = @"9-2",
- .keys = keys[9],
- .message = [NSData dataWithHexString:@"81b906605015a63aabe42ddf11e1978912f5404c7474b26dce3ed482bf961ecc818bf420c54659"],
- .seed = [NSData dataWithHexString:@"ecb1b8b25fa50cdab08e56042867f4af5826d16c"],
- .encryptedMessage = [NSData dataWithHexString:@"93ac9f0671ec29acbb444effc1a5741351d60fdb0e393fbf754acf0de49761a14841df7772e9bc82773966a1584c4d72baea00118f83f35cca6e537cbd4d811f5583b29783d8a6d94cd31be70d6f526c10ff09c6fa7ce069795a3fcd0511fd5fcb564bcc80ea9c78f38b80012539d8a4ddf6fe81e9cddb7f50dbbbbcc7e5d86097ccf4ec49189fb8bf318be6d5a0715d516b49af191258cd32dc833ce6eb4673c03a19bbace88cc54895f636cc0c1ec89096d11ce235a265ca1764232a689ae8"],
- },
- {
- .label = @"9-3",
- .keys = keys[9],
- .message = [NSData dataWithHexString:@"fd326429df9b890e09b54b18b8f34f1e24"],
- .seed = [NSData dataWithHexString:@"e89bb032c6ce622cbdb53bc9466014ea77f777c0"],
- .encryptedMessage = [NSData dataWithHexString:@"81ebdd95054b0c822ef9ad7693f5a87adfb4b4c4ce70df2df84ed49c04da58ba5fc20a19e1a6e8b7a3900b22796dc4e869ee6b42792d15a8eceb56c09c69914e813cea8f6931e4b8ed6f421af298d595c97f4789c7caa612c7ef360984c21b93edc5401068b5af4c78a8771b984d53b8ea8adf2f6a7d4a0ba76c75e1dd9f658f20ded4a46071d46d7791b56803d8fea7f0b0f8e41ae3f09383a6f9585fe7753eaaffd2bf94563108beecc207bbb535f5fcc705f0dde9f708c62f49a9c90371d3"],
- },
- {
- .label = @"9-4",
- .keys = keys[9],
- .message = [NSData dataWithHexString:@"f1459b5f0c92f01a0f723a2e5662484d8f8c0a20fc29dad6acd43bb5f3effdf4e1b63e07fdfe6628d0d74ca19bf2d69e4a0abf86d293925a796772f8088e"],
- .seed = [NSData dataWithHexString:@"606f3b99c0b9ccd771eaa29ea0e4c884f3189ccc"],
- .encryptedMessage = [NSData dataWithHexString:@"bcc35f94cde66cb1136625d625b94432a35b22f3d2fa11a613ff0fca5bd57f87b902ccdc1cd0aebcb0715ee869d1d1fe395f6793003f5eca465059c88660d446ff5f0818552022557e38c08a67ead991262254f10682975ec56397768537f4977af6d5f6aaceb7fb25dec5937230231fd8978af49119a29f29e424ab8272b47562792d5c94f774b8829d0b0d9f1a8c9eddf37574d5fa248eefa9c5271fc5ec2579c81bdd61b410fa61fe36e424221c113addb275664c801d34ca8c6351e4a858"],
- },
- {
- .label = @"9-5",
- .keys = keys[9],
- .message = [NSData dataWithHexString:@"53e6e8c729d6f9c319dd317e74b0db8e4ccca25f3c8305746e137ac63a63ef3739e7b595abb96e8d55e54f7bd41ab433378ffb911d"],
- .seed = [NSData dataWithHexString:@"fcbc421402e9ecabc6082afa40ba5f26522c840e"],
- .encryptedMessage = [NSData dataWithHexString:@"232afbc927fa08c2f6a27b87d4a5cb09c07dc26fae73d73a90558839f4fd66d281b87ec734bce237ba166698ed829106a7de6942cd6cdce78fed8d2e4d81428e66490d036264cef92af941d3e35055fe3981e14d29cbb9a4f67473063baec79a1179f5a17c9c1832f2838fd7d5e59bb9659d56dce8a019edef1bb3accc697cc6cc7a778f60a064c7f6f5d529c6210262e003de583e81e3167b89971fb8c0e15d44fffef89b53d8d64dd797d159b56d2b08ea5307ea12c241bd58d4ee278a1f2e"],
- },
- {
- .label = @"9-6",
- .keys = keys[9],
- .message = [NSData dataWithHexString:@"b6b28ea2198d0c1008bc64"],
- .seed = [NSData dataWithHexString:@"23aade0e1e08bb9b9a78d2302a52f9c21b2e1ba2"],
- .encryptedMessage = [NSData dataWithHexString:@"438cc7dc08a68da249e42505f8573ba60e2c2773d5b290f4cf9dff718e842081c383e67024a0f29594ea987b9d25e4b738f285970d195abb3a8c8054e3d79d6b9c9a8327ba596f1259e27126674766907d8d582ff3a8476154929adb1e6d1235b2ccb4ec8f663ba9cc670a92bebd853c8dbf69c6436d016f61add836e94732450434207f9fd4c43dec2a12a958efa01efe2669899b5e604c255c55fb7166de5589e369597bb09168c06dd5db177e06a1740eb2d5c82faeca6d92fcee9931ba9f"],
- },
- {
- .label = @"10-1",
- .keys = keys[10],
- .message = [NSData dataWithHexString:@"8bba6bf82a6c0f86d5f1756e97956870b08953b06b4eb205bc1694ee"],
- .seed = [NSData dataWithHexString:@"47e1ab7119fee56c95ee5eaad86f40d0aa63bd33"],
- .encryptedMessage = [NSData dataWithHexString:@"53ea5dc08cd260fb3b858567287fa91552c30b2febfba213f0ae87702d068d19bab07fe574523dfb42139d68c3c5afeee0bfe4cb7969cbf382b804d6e61396144e2d0e60741f8993c3014b58b9b1957a8babcd23af854f4c356fb1662aa72bfcc7e586559dc4280d160c126785a723ebeebeff71f11594440aaef87d10793a8774a239d4a04c87fe1467b9daf85208ec6c7255794a96cc29142f9a8bd418e3c1fd67344b0cd0829df3b2bec60253196293c6b34d3f75d32f213dd45c6273d505adf4cced1057cb758fc26aeefa441255ed4e64c199ee075e7f16646182fdb464739b68ab5daff0e63e9552016824f054bf4d3c8c90a97bb6b6553284eb429fcc"],
- },
- {
- .label = @"10-2",
- .keys = keys[10],
- .message = [NSData dataWithHexString:@"e6ad181f053b58a904f2457510373e57"],
- .seed = [NSData dataWithHexString:@"6d17f5b4c1ffac351d195bf7b09d09f09a4079cf"],
- .encryptedMessage = [NSData dataWithHexString:@"a2b1a430a9d657e2fa1c2bb5ed43ffb25c05a308fe9093c01031795f5874400110828ae58fb9b581ce9dddd3e549ae04a0985459bde6c626594e7b05dc4278b2a1465c1368408823c85e96dc66c3a30983c639664fc4569a37fe21e5a195b5776eed2df8d8d361af686e750229bbd663f161868a50615e0c337bec0ca35fec0bb19c36eb2e0bbcc0582fa1d93aacdb061063f59f2ce1ee43605e5d89eca183d2acdfe9f81011022ad3b43a3dd417dac94b4e11ea81b192966e966b182082e71964607b4f8002f36299844a11f2ae0faeac2eae70f8f4f98088acdcd0ac556e9fccc511521908fad26f04c64201450305778758b0538bf8b5bb144a828e629795"],
- },
- {
- .label = @"10-3",
- .keys = keys[10],
- .message = [NSData dataWithHexString:@"510a2cf60e866fa2340553c94ea39fbc256311e83e94454b4124"],
- .seed = [NSData dataWithHexString:@"385387514deccc7c740dd8cdf9daee49a1cbfd54"],
- .encryptedMessage = [NSData dataWithHexString:@"9886c3e6764a8b9a84e84148ebd8c3b1aa8050381a78f668714c16d9cfd2a6edc56979c535d9dee3b44b85c18be8928992371711472216d95dda98d2ee8347c9b14dffdff84aa48d25ac06f7d7e65398ac967b1ce90925f67dce049b7f812db0742997a74d44fe81dbe0e7a3feaf2e5c40af888d550ddbbe3bc20657a29543f8fc2913b9bd1a61b2ab2256ec409bbd7dc0d17717ea25c43f42ed27df8738bf4afc6766ff7aff0859555ee283920f4c8a63c4a7340cbafddc339ecdb4b0515002f96c932b5b79167af699c0ad3fccfdf0f44e85a70262bf2e18fe34b850589975e867ff969d48eabf212271546cdc05a69ecb526e52870c836f307bd798780ede"],
- },
- {
- .label = @"10-4",
- .keys = keys[10],
- .message = [NSData dataWithHexString:@"bcdd190da3b7d300df9a06e22caae2a75f10c91ff667b7c16bde8b53064a2649a94045c9"],
- .seed = [NSData dataWithHexString:@"5caca6a0f764161a9684f85d92b6e0ef37ca8b65"],
- .encryptedMessage = [NSData dataWithHexString:@"6318e9fb5c0d05e5307e1683436e903293ac4642358aaa223d7163013aba87e2dfda8e60c6860e29a1e92686163ea0b9175f329ca3b131a1edd3a77759a8b97bad6a4f8f4396f28cf6f39ca58112e48160d6e203daa5856f3aca5ffed577af499408e3dfd233e3e604dbe34a9c4c9082de65527cac6331d29dc80e0508a0fa7122e7f329f6cca5cfa34d4d1da417805457e008bec549e478ff9e12a763c477d15bbb78f5b69bd57830fc2c4ed686d79bc72a95d85f88134c6b0afe56a8ccfbc855828bb339bd17909cf1d70de3335ae07039093e606d655365de6550b872cd6de1d440ee031b61945f629ad8a353b0d40939e96a3c450d2a8d5eee9f678093c8"],
- },
- {
- .label = @"10-5",
- .keys = keys[10],
- .message = [NSData dataWithHexString:@"a7dd6c7dc24b46f9dd5f1e91ada4c3b3df947e877232a9"],
- .seed = [NSData dataWithHexString:@"95bca9e3859894b3dd869fa7ecd5bbc6401bf3e4"],
- .encryptedMessage = [NSData dataWithHexString:@"75290872ccfd4a4505660d651f56da6daa09ca1301d890632f6a992f3d565cee464afded40ed3b5be9356714ea5aa7655f4a1366c2f17c728f6f2c5a5d1f8e28429bc4e6f8f2cff8da8dc0e0a9808e45fd09ea2fa40cb2b6ce6ffff5c0e159d11b68d90a85f7b84e103b09e682666480c657505c0929259468a314786d74eab131573cf234bf57db7d9e66cc6748192e002dc0deea930585f0831fdcd9bc33d51f79ed2ffc16bcf4d59812fcebcaa3f9069b0e445686d644c25ccf63b456ee5fa6ffe96f19cdf751fed9eaf35957754dbf4bfea5216aa1844dc507cb2d080e722eba150308c2b5ff1193620f1766ecf4481bafb943bd292877f2136ca494aba0"],
- },
- {
- .label = @"10-6",
- .keys = keys[10],
- .message = [NSData dataWithHexString:@"eaf1a73a1b0c4609537de69cd9228bbcfb9a8ca8c6c3efaf056fe4a7f4634ed00b7c39ec6922d7b8ea2c04ebac"],
- .seed = [NSData dataWithHexString:@"9f47ddf42e97eea856a9bdbc714eb3ac22f6eb32"],
- .encryptedMessage = [NSData dataWithHexString:@"2d207a73432a8fb4c03051b3f73b28a61764098dfa34c47a20995f8115aa6816679b557e82dbee584908c6e69782d7deb34dbd65af063d57fca76a5fd069492fd6068d9984d209350565a62e5c77f23038c12cb10c6634709b547c46f6b4a709bd85ca122d74465ef97762c29763e06dbc7a9e738c78bfca0102dc5e79d65b973f28240caab2e161a78b57d262457ed8195d53e3c7ae9da021883c6db7c24afdd2322eac972ad3c354c5fcef1e146c3a0290fb67adf007066e00428d2cec18ce58f9328698defef4b2eb5ec76918fde1c198cbb38b7afc67626a9aefec4322bfd90d2563481c9a221f78c8272c82d1b62ab914e1c69f6af6ef30ca5260db4a46"],
- },
-
- };
-
- int max_cycles = 100;
- if (!getenv("SUBMISSION_TEST")) {
- max_cycles = 10;
- CFfprintf(stderr, "Running the far faster but far less reliable fast test.\nSet the SUBMISSION_TEST environment variable for full testing\n");
- }
-
- for (int j = 0; j < max_cycles; j++) {
- NSLog(@"Cycle %d", j);
- for (i = 0; i < sizeof(tests)/sizeof(KAT); i++) {
- NSLog(@"test#%d %@ L(IN)=%lu, L(OUT)=%lu", i, tests[i].label, (unsigned long)[tests[i].message length], (unsigned long)[tests[i].encryptedMessage length]);
- CFErrorRef err = NULL;
-
- SecTransformRef encryptor = SecEncryptTransformCreate(tests[i].keys.pubKey, &err);
-
- SecTransformSetAttribute(encryptor, kSecTransformInputAttributeName, tests[i].message, &err);
- SecTransformSetAttribute(encryptor, kSecPaddingKey, kSecPaddingOAEPKey, &err);
- SecTransformSetAttribute(encryptor, kSecOAEPEncodingParametersAttributeName, encoding_parameters, &err);
- SecTransformSetAttribute(encryptor, CFSTR("FixedSeedForOAEPTesting"), tests[i].seed, &err);
-
- CFTypeRef encryptedData = SecTransformExecute(encryptor, &err);
- STAssertNotNil((id)encryptedData, @"Expected to get encrypted data");
- STAssertNil((NSError*)err, @"Expected no error, got err=%@", err);
- // Can't support "seed" with commoncrypto, just check round trip.
- //STAssertEqualObjects((id)encryptedData, (id)tests[i].encryptedMessage, @"encrypted data should have matched test vector (%@) data", tests[i].label);
- CFRelease(encryptor);
-
- SecTransformRef decryptor = SecDecryptTransformCreate(tests[i].keys.privKey, NULL);
- SecTransformSetAttribute(decryptor, kSecTransformInputAttributeName, tests[i].encryptedMessage, NULL);
- // XXX: totally round trip, not even partial KAT (KAT can't really be done on OAEP
- // without supporitng settign the seed externally)
- SecTransformSetAttribute(decryptor, kSecTransformInputAttributeName, encryptedData, NULL);
- SecTransformSetAttribute(decryptor, kSecPaddingKey, kSecPaddingOAEPKey, NULL);
- SecTransformSetAttribute(decryptor, kSecOAEPEncodingParametersAttributeName, encoding_parameters, NULL);
- CFTypeRef decryptedData = SecTransformExecute(decryptor, &err);
- STAssertNil((id)err, @"Expected no error, got: %@", err);
- STAssertNotNil((id)decryptedData, @"Expected to get decrypted data");
- STAssertEqualObjects((id)decryptedData, tests[i].message, @"Expected decrypted data to match original message (%@)", tests[i].label);
- CFRelease(decryptor);
- }
- }
-
- return;
-}
-
--(void)testNoSignKeyMakesError
-{
- NSData *data = [NSData dataWithBytes:"" length:1];
-
- struct test_case {
- NSString *name;
- CFErrorRef createError;
- SecTransformRef transform;
- } test_cases[] = {
- {
- .name = @"Sign",
- .createError = NULL,
- .transform = SecSignTransformCreate(NULL, &(test_cases[0].createError))
- },
- {
- .name = @"Verify",
- .createError = NULL,
- .transform = SecVerifyTransformCreate(NULL, (CFDataRef)data, &(test_cases[1].createError))
- }
- };
-
- for(int i = 0; i < sizeof(test_cases) / sizeof(test_case); i++) {
- struct test_case *test = test_cases + i;
- STAssertNil((id)test->createError, @"Testing %@, unexpected error: %@", test->name, test->createError);
- STAssertNotNil((id)test->transform, @"Didn't manage to create transform for %@", test->name);
- if (!test->transform) {
- continue;
- }
-
- __block CFErrorRef err = NULL;
- SecTransformSetAttribute(test->transform, kSecTransformInputAttributeName, data, &err);
- STAssertNil((id)err, @"Error setting input for %@: %@", test->name, err);
-
- dispatch_group_t execute_done = dispatch_group_create();
- dispatch_group_enter(execute_done);
-
- SecTransformExecuteAsync(test->transform, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) {
- if (error) {
- err = error;
- }
- if (isFinal) {
- dispatch_group_leave(execute_done);
- }
- });
-
- STAssertFalse(dispatch_group_wait(execute_done, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * 5)), @"Timeout waiting for %@ transform", test->name);
- STAssertErrorHas((id)err, @"missing required attributes?:.*KEY", @"Unexpected error during %@ test, expected one about missing keys: %@", test->name, err);
- dispatch_group_notify(execute_done, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, NULL), ^(void) {
- dispatch_release(execute_done);
- });
- }
-}
-
--(void)testHMAC
-{
- // make the data for the key and the data to be HMAC'd
- CFDataRef hmacData = CFDataCreate(NULL, (u_int8_t*) gHMACText, strlen(gHMACText));
- CFDataRef hmacKey = CFDataCreate(NULL, (u_int8_t*) gHMACKey, strlen(gHMACKey));
- SecTransformRef hmacRef;
- CFErrorRef error = NULL;
- CFDataRef result;
- CFDataRef rightAnswer;
- CFComparisonResult ok;
-
- // create the object
- hmacRef = SecDigestTransformCreate(kSecDigestHMACSHA1, 20, &error);
- STAssertNil((id) error, @"Unexpected error returned.");
-
- // set the key
- SecTransformSetAttribute(hmacRef, kSecDigestHMACKeyAttribute, hmacKey, &error);
- STAssertNil((id) error, @"Unexpected error returned.");
-
- // digest the data
- SecTransformSetAttribute(hmacRef, kSecTransformInputAttributeName, hmacData, &error);
- STAssertNil((id) error, @"Unexpected error returned.");
-
- result = (CFDataRef) SecTransformExecute(hmacRef, &error);
- if (error)
- {
- CFShow(error);
- STAssertNil((id) error, @"Unexpected error returned.");
- CFRelease(error);
- }
-
- STAssertNotNil((id) result, @"No data returned for SHA1");
-
- // check to make sure we got the right answer
- rightAnswer = CFDataCreate(NULL, gSHA1HMAC, sizeof(gSHA1HMAC));
- ok = CFEqual(rightAnswer, result);
- CFRelease(rightAnswer);
- CFRelease(hmacRef);
- CFRelease(result);
-
- if (error)
- {
- CFRelease(error);
- }
-
- STAssertTrue(ok, @"Digest returned incorrect HMACSHA1 result.");
-
- //+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
-
- // create the object
- hmacRef = SecDigestTransformCreate(kSecDigestHMACSHA2, 256, &error);
- STAssertNil((id) error, @"Unexpected error returned.");
-
- // set the key
- SecTransformSetAttribute(hmacRef, kSecDigestHMACKeyAttribute, hmacKey, &error);
- STAssertNil((id) error, @"Unexpected error returned.");
-
- // digest the data
- SecTransformSetAttribute(hmacRef, kSecTransformInputAttributeName, hmacData, &error);
- STAssertNil((id) error, @"Unexpected error returned.");
-
- result = (CFDataRef) SecTransformExecute(hmacRef, &error);
- if (error != nil)
- {
- CFShow(error);
- STAssertNil((id) error, @"Unexpected error returned.");
- CFRelease(error);
- }
-
- STAssertNotNil((id) result, @"No data returned for SHA256");
-
- rightAnswer = CFDataCreate(NULL, gSHA256HMAC, sizeof(gSHA256HMAC));
- ok = CFEqual(result, rightAnswer);
-
- CFRelease(rightAnswer);
- CFRelease(hmacRef);
-
- CFRelease(hmacData);
- CFRelease(hmacKey);
- CFRelease(result);
-
- STAssertTrue(ok, @"Digest returned incorrect HMACSHA256 result.");
-}
-
-
-
--(void)echoParams:(NSString*)p1 p2:(NSString*)p2
-{
-}
-
--(void)testReadStreamTransform
-{
- // point to our test data
- CFURLRef url = CFURLCreateWithFileSystemPath(NULL, CFSTR("/usr/share/dict/words"), kCFURLPOSIXPathStyle, false);
- FSRef force_resolve;
- STAssertTrue(CFURLGetFSRef(url, &force_resolve), @"Expected to create FSRef from %@", url);
- CFURLRef resolved_url = CFURLCreateFromFSRef(NULL, &force_resolve);
- CFNumberRef size_on_disk = NULL;
- CFURLCopyResourcePropertyForKey(resolved_url, kCFURLFileSizeKey, &size_on_disk, NULL);
- STAssertNotNil((id)size_on_disk, @"Expected to fetch size");
-
- CFReadStreamRef readStreamRef = CFReadStreamCreateWithFile(NULL, url);
- SecTransformRef transform = SecTransformCreateReadTransformWithReadStream(readStreamRef);
- STAssertNotNil((id) transform, @"Returned transform should not be nil.");
-
- dispatch_semaphore_t waitSemaphore = dispatch_semaphore_create(0);
- dispatch_queue_t queue = dispatch_queue_create("ReadStream queue", NULL);
- __block ssize_t bytes_presented = 0;
-
- SecTransformExecuteAsync(transform, queue,
- ^(CFTypeRef message, CFErrorRef error, Boolean isFinal)
- {
- if (message)
- {
- bytes_presented += CFDataGetLength((CFDataRef)message);
- }
- if (isFinal)
- {
- STAssertNil((id)error, @"Unexpected error!");
- dispatch_semaphore_signal(waitSemaphore);
- }
- });
-
- dispatch_semaphore_wait(waitSemaphore, DISPATCH_TIME_FOREVER);
- NSNumber *size_via_stream = [NSNumber numberWithLongLong:bytes_presented];
- STAssertEqualObjects(size_via_stream, (NSNumber*)size_on_disk, @"Expected sizes to match");
- CFRelease(size_on_disk);
-
- dispatch_release(queue);
- dispatch_release(waitSemaphore);
- CFRelease(transform);
- CFRelease(readStreamRef);
- CFRelease(url);
- CFRelease(resolved_url);
-}
-
--(void)testMGF
-{
- UInt8 raw_seed[] = {0xaa, 0xfd, 0x12, 0xf6, 0x59, 0xca, 0xe6, 0x34, 0x89, 0xb4, 0x79, 0xe5, 0x07, 0x6d, 0xde, 0xc2, 0xf0, 0x6c, 0xb5, 0x8f};
- UInt8 raw_mgf107[] = {0x06, 0xe1, 0xde, 0xb2, 0x36, 0x9a, 0xa5, 0xa5, 0xc7, 0x07, 0xd8, 0x2c, 0x8e, 0x4e, 0x93, 0x24, 0x8a, 0xc7, 0x83, 0xde, 0xe0, 0xb2, 0xc0, 0x46, 0x26, 0xf5, 0xaf, 0xf9, 0x3e, 0xdc, 0xfb, 0x25, 0xc9, 0xc2, 0xb3, 0xff, 0x8a, 0xe1, 0x0e, 0x83, 0x9a, 0x2d, 0xdb, 0x4c, 0xdc, 0xfe, 0x4f, 0xf4, 0x77, 0x28, 0xb4, 0xa1, 0xb7, 0xc1, 0x36, 0x2b, 0xaa, 0xd2, 0x9a, 0xb4, 0x8d, 0x28, 0x69, 0xd5, 0x02, 0x41, 0x21, 0x43, 0x58, 0x11, 0x59, 0x1b, 0xe3, 0x92, 0xf9, 0x82, 0xfb, 0x3e, 0x87, 0xd0, 0x95, 0xae, 0xb4, 0x04, 0x48, 0xdb, 0x97, 0x2f, 0x3a, 0xc1, 0x4e, 0xaf, 0xf4, 0x9c, 0x8c, 0x3b, 0x7c, 0xfc, 0x95, 0x1a, 0x51, 0xec, 0xd1, 0xdd, 0xe6, 0x12, 0x64};
- CFDataRef seed = CFDataCreate(NULL, raw_seed, sizeof(raw_seed));
- CFDataRef mgf107 = CFDataCreate(NULL, raw_mgf107, sizeof(raw_mgf107));
- CFErrorRef err = NULL;
-
- SecTransformRef mgfTransform = SecCreateMaskGenerationFunctionTransform(NULL, 107, &err);
- STAssertNotNil((id)mgfTransform, @"Expected to create a MGF transform e=%@", err);
- err = NULL;
- SecTransformSetAttribute(mgfTransform, kSecTransformInputAttributeName, seed, &err);
- STAssertNil((id)err, @"Expected no error setting MGF's input, got %@", err);
- err = NULL;
- CFDataRef mgfOutput = (CFDataRef)SecTransformExecute(mgfTransform, &err);
- STAssertNotNil((id)mgfOutput, @"Expected output from mgf, got error %@", err);
- STAssertEqualObjects((id)mgfOutput, (id)mgf107, @"Expected matching output");
-
- CFRelease(mgfTransform);
- // XXX: leak test??
-
- UInt8 raw_maskedDB[] = {0xdc, 0xd8, 0x7d, 0x5c, 0x68, 0xf1, 0xee, 0xa8, 0xf5, 0x52, 0x67, 0xc3, 0x1b, 0x2e, 0x8b, 0xb4, 0x25, 0x1f, 0x84, 0xd7, 0xe0, 0xb2, 0xc0, 0x46, 0x26, 0xf5, 0xaf, 0xf9, 0x3e, 0xdc, 0xfb, 0x25, 0xc9, 0xc2, 0xb3, 0xff, 0x8a, 0xe1, 0x0e, 0x83, 0x9a, 0x2d, 0xdb, 0x4c, 0xdc, 0xfe, 0x4f, 0xf4, 0x77, 0x28, 0xb4, 0xa1, 0xb7, 0xc1, 0x36, 0x2b, 0xaa, 0xd2, 0x9a, 0xb4, 0x8d, 0x28, 0x69, 0xd5, 0x02, 0x41, 0x21, 0x43, 0x58, 0x11, 0x59, 0x1b, 0xe3, 0x92, 0xf9, 0x82, 0xfb, 0x3e, 0x87, 0xd0, 0x95, 0xae, 0xb4, 0x04, 0x48, 0xdb, 0x97, 0x2f, 0x3a, 0xc1, 0x4f, 0x7b, 0xc2, 0x75, 0x19, 0x52, 0x81, 0xce, 0x32, 0xd2, 0xf1, 0xb7, 0x6d, 0x4d, 0x35, 0x3e, 0x2d};
-
- UInt8 raw_mgf20[] = {0x41, 0x87, 0x0b, 0x5a, 0xb0, 0x29, 0xe6, 0x57, 0xd9, 0x57, 0x50, 0xb5, 0x4c, 0x28, 0x3c, 0x08, 0x72, 0x5d, 0xbe, 0xa9};
- CFDataRef maskedDB = CFDataCreate(NULL, raw_maskedDB, sizeof(raw_maskedDB));
- CFDataRef mgf20 = CFDataCreate(NULL, raw_mgf20, sizeof(raw_mgf20));
- err = NULL;
-
- mgfTransform = SecCreateMaskGenerationFunctionTransform(kSecDigestSHA1, 20, &err);
- STAssertNotNil((id)mgfTransform, @"Expected to create a MGF transform e=%@", err);
- err = NULL;
- SecTransformSetAttribute(mgfTransform, kSecTransformInputAttributeName, maskedDB, &err);
- STAssertNil((id)err, @"Expected no error setting MGF's input, got %@", err);
- err = NULL;
- mgfOutput = (CFDataRef)SecTransformExecute(mgfTransform, &err);
- STAssertNotNil((id)mgfOutput, @"Expected output from mgf, got error %@", err);
- STAssertEqualObjects((id)mgfOutput, (id)mgf20, @"Expected matching output");
-}
-
--(void)testAbortParams
-{
- // make a simple transform
- SecTransformRef a = SecNullTransformCreate();
-
- // try to abort the transform
- CFErrorRef errorRef = NULL;
- STAssertFalse(SecTransformSetAttribute(a, CFSTR("ABORT"), NULL, &errorRef), @"SecTransformSetAttribute should have returned FALSE");
- STAssertNotNil((id) errorRef, @"SecTransformSetAttribute should have had an error.");
- if (errorRef != NULL)
- {
- CFRelease(errorRef);
- }
-
- CFRelease(a);
-
- // We have instant end of stream, it is wired directly to null_abort's ABORT. It is wired to the final drain via a delay and some other
- // things. If the end of stream makes it to the final drain we get an empty CFData. If the abort triggers then abort has invalidly
- // triggered off of a NULL value.
- SecGroupTransformRef test_null_abort_via_connection = SecTransformCreateGroupTransform();
- SecTransformRef pass_through = SecNullTransformCreate();
- SecTransformRef null_abort = SecNullTransformCreate();
-
- CFURLRef dev_null_url = CFURLCreateWithFileSystemPath(NULL, CFSTR("/dev/null"), kCFURLPOSIXPathStyle, NO);
- CFReadStreamRef dev_null_stream = CFReadStreamCreateWithFile(NULL, dev_null_url);
- CFReadStreamOpen(dev_null_stream);
- CFRelease(dev_null_url);
-
- SecTransformSetAttribute(pass_through, kSecTransformInputAttributeName, dev_null_stream, NULL);
- SecTransformConnectTransforms(pass_through, kSecTransformOutputAttributeName, null_abort, kSecTransformAbortAttributeName, test_null_abort_via_connection, NULL);
-
- SecTransformRef delay_null = delay_transform(NSEC_PER_SEC / 10);
- SecTransformConnectTransforms(pass_through, kSecTransformOutputAttributeName, delay_null, kSecTransformInputAttributeName, test_null_abort_via_connection, NULL);
- SecTransformConnectTransforms(delay_null, kSecTransformOutputAttributeName, null_abort, kSecTransformInputAttributeName, test_null_abort_via_connection, NULL);
-
-
- CFErrorRef err = NULL;
- CFTypeRef not_null = SecTransformExecute(test_null_abort_via_connection, &err);
-
- STAssertNotNil((id)not_null, @"aborted via a NULL from a connection? err=%@", err);
-
- if (err)
- {
- CFRelease(err);
- }
-
- CFRelease(test_null_abort_via_connection);
- CFRelease(pass_through);
- CFRelease(null_abort);
- CFRelease(delay_null);
-
- CFReadStreamClose(dev_null_stream);
- CFRelease(dev_null_stream);
-}
-
-
--(void)testDisconnect
-{
- SecTransformRef a = SecNullTransformCreate();
- SecTransformRef b = SecNullTransformCreate();
- SecTransformRef c = SecNullTransformCreate();
- SecGroupTransformRef g = SecTransformCreateGroupTransform();
-
- SecTransformConnectTransforms(a, kSecTransformOutputAttributeName, b, kSecTransformInputAttributeName, g, NULL);
- SecTransformConnectTransforms(a, kSecTransformOutputAttributeName, c, kSecTransformInputAttributeName, g, NULL);
-
- SecTransformDisconnectTransforms(a, kSecTransformOutputAttributeName, b, kSecTransformInputAttributeName);
- STAssertTrue(SecGroupTransformHasMember(g, a), @"A should still be in the group, but isn't");
-
- SecTransformDisconnectTransforms(a, kSecTransformOutputAttributeName, c, kSecTransformInputAttributeName);
- STAssertFalse(SecGroupTransformHasMember(g, a), @"A should no longer be in the group, but is");
-
- CFRelease(g);
- CFRelease(c);
- CFRelease(b);
- CFRelease(a);
-}
-
-
--(void)testAbort
-{
- CFStringRef abort_test_name = CFSTR("com.apple.security.unit-test.abortTest");
-
- SecTransformCreateBlock setupBlock =
- ^(CFStringRef name, SecTransformRef new_transform, const SecTransformCreateBlockParameters *params)
- {
- params->send(kSecTransformInputAttributeName, kSecTransformMetaAttributeDeferred, kCFBooleanTrue);
-
- params->overrideAttribute(kSecTransformActionAttributeNotification, CFSTR("PB"), ^(SecTransformAttributeRef ah, CFTypeRef value) {
- // Makes sure we can shut down (via ABORT) a transform that has a pending pushback
- params->pushback(ah, value);
- return (CFTypeRef)NULL;
- });
- };
-
-
- SecTransformRef a;
- SecTransformRef dt;
- SecGroupTransformRef group = SecTransformCreateGroupTransform();
-
- // make two of these transforms and link them together
- a = custom_transform(abort_test_name, setupBlock);
- STAssertNotNil((id) a, @"SecCustomTransformCreate failed");
-
- dt = delay_transform(NSEC_PER_SEC / 10);
- STAssertNotNil((id) dt, @"SecCustomTransformCreate failed");
-
- // connect the two transforms
- CFErrorRef error;
-
- // hook the output up so that the abort automatically fires.
- SecTransformConnectTransforms(dt, kSecTransformOutputAttributeName, a, CFSTR("ABORT"), group, &error);
- STAssertNil((id) error, @"SecTransformConnectTransforms failed.");
-
- // also hook it up to the input because the input attribute is required on a null transform
- SecTransformConnectTransforms(dt, CFSTR("NOVALUES"), a, kSecTransformInputAttributeName, group, &error);
- STAssertNil((id) error, @"SecTransformConnectTransforms failed.");
-
- // pass a plain piece of data down the transform just for fun...
- const u_int8_t data[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 4};
-
- CFDataRef dataRef = CFDataCreateWithBytesNoCopy(NULL, data, sizeof(data), kCFAllocatorNull);
- SecTransformSetAttribute(dt, kSecTransformInputAttributeName, dataRef, NULL);
-
- CFStringRef str = CFStringCreateMutable(NULL, 0);
- SecTransformSetAttribute(a, CFSTR("PB"), str, NULL);
-
- CFTypeRef er = SecTransformExecute(a, &error);
-
- STAssertNil((id)er, @"Didn't expect an result from aborted transform");
- STAssertNotNil((id)error, @"Expected error from execute");
-
- if (error)
- {
- CFShow(error);
-
- // while we are at it, make sure that the user dictionary has the originating transform
- CFDictionaryRef userDictionary = CFErrorCopyUserInfo(error);
- STAssertNotNil((id) CFDictionaryGetValue(userDictionary, kSecTransformAbortOriginatorKey), @"Originating transform not listed.");
- CFRelease(error);
- }
-
- CFRelease(a);
- CFRelease(dt);
- CFRelease(group);
- CFRelease(dataRef);
-
-/*
- // XXX: these should both be 1, not 3 or 4. WTF? Is this an abort issue, or a generic leak?
- // STAssertEquals(rc0, CFGetRetainCount(str), @"The value we sent to PB hasn't been released (value retained by pushback)");
- // STAssertEquals(rc0, CFGetRetainCount(dataRef), @"The value we sent to INPUT hasn't been released");
-*/
-}
-
--(void)testPreAbort {
- CFErrorRef error = NULL;
- SecTransformRef prebort = SecNullTransformCreate();
- SecTransformSetAttribute(prebort, kSecTransformInputAttributeName, CFSTR("quux"), NULL);
- SecTransformSetAttribute(prebort, CFSTR("ABORT"), CFSTR("OOPS"), NULL);
- CFTypeRef er = SecTransformExecute(prebort, &error);
- STAssertNil((id)er, @"Didn't expect an result from pre-aborted transform");
- STAssertNotNil((id)error, @"Expected error from execute of pre-aborted transform");
- CFRelease(error);
-}
-
-#ifdef DEBUG
--(void)testFireAndForget
-{
- bool isGC = false;
- NSGarbageCollector* gc = [NSGarbageCollector defaultCollector];
- if (gc)
- {
- isGC = [gc isEnabled];
- }
-
- CFIndex retCount = 0;
-
- // make transforms
- SecNullTransformRef a = SecNullTransformCreate();
- SecNullTransformRef b = SecNullTransformCreate();
- SecGroupTransformRef group = SecTransformCreateGroupTransform();
- SecTransformConnectTransforms(a, kSecTransformOutputAttributeName, b, kSecTransformInputAttributeName, group, NULL);
-
- if (!isGC)
- {
- retCount = CFGetRetainCount(group);
- }
-
- // set up a blob of data to fire
- const u_int8_t data[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 4};
- CFDataRef dataRef = CFDataCreateWithBytesNoCopy(NULL, data, sizeof(data), kCFAllocatorNull);
- SecTransformSetAttribute(a, kSecTransformInputAttributeName, dataRef, NULL);
- CFRelease(dataRef);
-
- // make dispatch related stuff
- dispatch_queue_t queue = dispatch_queue_create("ffqueue", NULL);
- // semaphore0's job is to be signaled when we know ExecuteAsync is actually executing (so we don't sample the retain
- // count too soone), semaphore signals when we are about done with ExecuteAsync (I'm not sure why we need to know),
- // and semaphore2 is signaled to let the execute block know we are done sampling retain counts.
- dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
- dispatch_semaphore_t semaphore2 = dispatch_semaphore_create(0);
-
- // launch the chain
- SecTransformExecuteAsync(group, queue,
- ^(CFTypeRef message, CFErrorRef error, Boolean isFinal)
- {
- CFfprintf(stderr, "message %p, final %d\n", message, isFinal ? 1 : 0);
- STAssertEquals(queue, const_cast<const dispatch_queue_t>(dispatch_get_current_queue()), @"Expected to be executing on own queue, got %s", dispatch_queue_get_label(dispatch_get_current_queue()));
- if (isFinal)
- {
- fprintf(stderr, "Final message received.\n");
- dispatch_semaphore_wait(semaphore2, DISPATCH_TIME_FOREVER); // make sure that the other chain has released its material
- dispatch_semaphore_signal(semaphore);
- }
- });
- CFRelease(a);
- CFRelease(b);
- CFRelease(group);
- dispatch_semaphore_signal(semaphore2);
- dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
-
- // no crash? Life is good.
-}
-#endif
-
--(void)testExternalSource
-{
- CFErrorRef err = NULL;
- SecTransformRef xs = SecExternalSourceTransformCreate(&err);
- SecTransformRef tee = SecNullTransformCreate();
- SecTransformRef group = SecTransformCreateGroupTransform();
-
- SecTransformConnectTransforms(xs, kSecTransformOutputAttributeName, tee, kSecTransformInputAttributeName, group, &err);
-
- dispatch_queue_t q = dispatch_queue_create("com.apple.security.unit-tests.test-external-source", 0);
- dispatch_group_t dg = dispatch_group_create();
- dispatch_group_enter(dg);
- __block bool got_ping = false;
-
- SecTransformExecuteAsync(group, q, ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) {
- CFfprintf(stderr, "B: message %@, e %p, f %d\n", message ? message : (CFTypeRef)CFSTR("(NULL)"), error, isFinal);
-
- if (message) {
- if (CFEqual(message, CFSTR("PING"))) {
- got_ping = true;
- } else {
- STFail(@"expected ping, got: %@", message);
- }
- }
-
- if (error) {
- STFail(@"unexpected error: %@", error);
- }
-
- if (isFinal) {
- if (!got_ping) {
- STFail(@"never got ping");
- }
- dispatch_group_leave(dg);
- }
- });
-
- SecExternalSourceSetValue(tee, CFSTR("PONG"), &err);
- STAssertNotNil((id)err, @"Expected error setting tee");
- STAssertErrorHas((id)err, @"ExternalSource", @"Error should note what should be passed in: %@", err);
- CFRelease(err);
- err = NULL;
- SecExternalSourceSetValue(xs, CFSTR("PING"), &err);
- STAssertNil((id)err, @"unexpected error setting xs: %@", err);
- SecExternalSourceSetValue(xs, NULL, &err);
- STAssertNil((id)err, @"unexpected error setting xs: %@", err);
- dispatch_group_wait(dg, DISPATCH_TIME_FOREVER);
-
- dispatch_release(dg);
- dispatch_release(q);
- CFRelease(xs);
- CFRelease(tee);
- CFRelease(group);
-}
-
--(void)testFindLastAndMonitor
-{
- SecNullTransformRef a = delay_transform(NSEC_PER_SEC / 10);
- SecNullTransformRef b = SecNullTransformCreate();
-
- SecGroupTransformRef groupRef = SecTransformCreateGroupTransform();
- CFErrorRef error = NULL;
- SecTransformConnectTransforms(a, kSecTransformOutputAttributeName, b, kSecTransformInputAttributeName, groupRef, &error);
- STAssertNil((id)error, @"An error was returned when none was expected.");
- SecTransformSetAttribute(a, kSecTransformInputAttributeName, kCFNull, &error);
- STAssertNil((id)error, @"An error was returned when none was expected.");
-
-
- // get the last transform in the chain (unexecuted). It had better be b...
- SecTransformRef tr = SecGroupTransformFindLastTransform(groupRef);
- STAssertNotNil((id)tr, @"FindLastTransform returned NULL");
- STAssertTrue(tr == b, @"FindLastTransform returned incorrect result");
- STAssertFalse(tr == a, @"FindLastTransform returned the head of the chain");
-
- // execute the transform. This should attach an output monitor
- dispatch_queue_t queue = dispatch_queue_create("test delivery queue", NULL);
- dispatch_semaphore_t last_block_run = dispatch_semaphore_create(0L);
- dispatch_semaphore_t last_assert_run = dispatch_semaphore_create(0L);
- SecTransformExecuteAsync(groupRef, queue,
- ^(CFTypeRef message, CFErrorRef error, Boolean isFinal)
- {
- if (isFinal)
- {
- dispatch_semaphore_signal(last_block_run);
- dispatch_semaphore_wait(last_assert_run, DISPATCH_TIME_FOREVER);
- dispatch_release(last_assert_run);
- }
-
- });
-
- dispatch_semaphore_wait(last_block_run, DISPATCH_TIME_FOREVER);
-
- // see if the returned transform is the same now
- tr = SecGroupTransformFindLastTransform(groupRef);
- STAssertNotNil((id) tr, @"FindLastTransform returned NULL");
- STAssertTrue(tr == b, @"FindLastTransform returned incorrect result");
- STAssertFalse(tr == a, @"FindLastTransform returned the head of the chain");
-
- // get the monitor, it had better not be a or b
- tr = SecGroupTransformFindMonitor(groupRef);
- STAssertNotNil((id) tr, @"FindMonitor returned NULL");
- STAssertFalse(tr == a, @"FindLastTransform returned the head of the chain");
- STAssertFalse(tr == b, @"FindLastTransform returned the head of the chain");
-
- dispatch_semaphore_signal(last_assert_run);
- dispatch_release(queue);
- dispatch_release(last_block_run);
- CFRelease(a);
- CFRelease(b);
- CFRelease(groupRef);
-}
-
-
--(void)testConnectUnsetAttributes /* <rdar://problem/7769955> Can't connect transform attributes with no setting */
-{
- SecNullTransformRef a = SecNullTransformCreate();
- SecNullTransformRef b = SecNullTransformCreate();
-
- SecGroupTransformRef group = SecTransformCreateGroupTransform();
- CFErrorRef error = NULL;
- SecTransformConnectTransforms(a, CFSTR("RANDOM_NAME"), b, CFSTR("RANDOM_DESTINATION"), group, &error);
- CFRelease(group);
- CFRelease(b);
- CFRelease(a);
- STAssertNil((id) error, @"An error was returned when none was expected.");
-}
-
--(void)testNoDataFlowPriorToInit /* <rdar://problem/8163542> Monitor must be attached before the data flow becomes active */
-{
- CFStringRef name = CFSTR("com.apple.security.unit-test.flow-check");
- SecTransformCreateBlock cb = ^(CFStringRef name, SecTransformRef new_transform, const SecTransformCreateBlockParameters *params) {
- __block bool inited = false;
- __block bool saw_x_start = false;
- __block bool saw_null = false;
- __block int post_send_left = 8;
- SecTransformAttributeRef out_ah = params->get(kSecTransformOutputAttributeName, kSecTransformMetaAttributeRef);
- params->send(out_ah, kSecTransformMetaAttributeValue, CFSTR("create"));
-
- params->overrideTransform(kSecTransformActionStartingExecution, ^{
- params->send(out_ah, kSecTransformMetaAttributeValue, CFSTR("x-start"));
- inited = true;
- return (CFTypeRef)NULL;
- });
-
- params->overrideTransform(kSecTransformActionCanExecute, ^{
- params->send(out_ah, kSecTransformMetaAttributeValue, CFSTR("can-x"));
- return (CFTypeRef)NULL;
- });
-
- params->overrideAttribute(kSecTransformActionAttributeNotification, kSecTransformInputAttributeName, ^(SecTransformAttributeRef ah, CFTypeRef value) {
- if (inited) {
- if (value) {
- if (!saw_x_start) {
- saw_x_start = CFStringHasPrefix((CFStringRef)value, CFSTR("x-start"));
- }
- if (saw_null) {
- params->send(kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, CreateGenericErrorRef(name, 88, "saw %@ after NULL", value));
- }
- if (post_send_left--) {
- params->send(out_ah, kSecTransformMetaAttributeValue, CFSTR("post-init"));
- }
- } else {
- saw_null = true;
- // The FIRST flow transform should not see x-start (it is the OUTPUT of the flow transform
- // before you in the chain), but all the other transforms should see it.
- if (params->get(CFSTR("FIRST"), kSecTransformMetaAttributeValue)) {
- if (saw_x_start) {
- params->send(kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, CreateGenericErrorRef(name, 42, "saw bogus x-start on FIRST flow transform"));
- } else {
- params->send(out_ah, kSecTransformMetaAttributeValue, value);
- }
- } else {
- if (saw_x_start) {
- params->send(out_ah, kSecTransformMetaAttributeValue, value);
- } else {
- params->send(kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, CreateGenericErrorRef(name, 42, "never saw x-start before EOS"));
- return (CFTypeRef)kCFNull;
- }
- }
- }
- } else {
- // attempting to put the value in the error string sometimes blows up, so I've left it out.
- params->send(kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, CreateGenericErrorRef(name, 42, "got: value before init"));
- return (CFTypeRef)kCFNull;
- }
- return (CFTypeRef)value;
- });
- };
-
- // Reliably reproduces with 100000 transforms in our group, but
- // not at 1000...doesn't even seem to do it at 50000.
- // Likely a timing issue triggered by heavy swapping.
- int n_transforms = 100000;
-
- if (!getenv("SUBMISSION_TEST")) {
- n_transforms = 10000;
- CFfprintf(stderr, "Running the far faster but far less reliable fast test.\nSet the SUBMISSION_TEST environment variable for full testing\n");
- }
-
- int i;
- CFMutableArrayRef ta = CFArrayCreateMutable(NULL, n_transforms, &kCFTypeArrayCallBacks);
- CFErrorRef err = NULL;
-
- for(i = 0; i < n_transforms; ++i) {
- SecTransformRef tr = custom_transform(name, cb);
- STAssertNil((id)err, @"Failure %@ creating %@ transform", err, name);
- CFStringRef l = CFStringCreateWithFormat(NULL, NULL, CFSTR("flow-%d"), i);
- SecTransformSetAttribute(tr, kSecTransformTransformName, l, &err);
- if (0 == i % 1000) {
- CFfprintf(stderr, "Created %@ of %d\n", l, n_transforms);
- }
- CFRelease(l);
- STAssertNil((id)err, @"Can't set name %@", err);
- CFArrayAppendValue(ta, tr);
- assert(CFArrayGetCount(ta));
- assert(CFArrayGetCount(ta) == i+1);
- }
-
- SecTransformRef prev_tr = NULL;
- SecTransformRef group = SecTransformCreateGroupTransform();
- CFIndex cnt;
-
- while ((cnt = CFArrayGetCount(ta))) {
- CFIndex r = arc4random() % cnt;
- SecTransformRef tr = CFArrayGetValueAtIndex(ta, r);
- if (prev_tr) {
- SecTransformConnectTransforms(tr, kSecTransformOutputAttributeName, prev_tr, kSecTransformInputAttributeName, group, &err);
- STAssertNil((id)err, @"Can't connect %@ to %@", tr, prev_tr);
- STAssertNotNil((id)group, @"nil group after connect");
- CFRelease(prev_tr);
- }
- prev_tr = tr;
- CFArrayRemoveValueAtIndex(ta, r);
-
- if (0 == cnt % 1000) {
- CFfprintf(stderr, "%d left to hook up\n", cnt);
- }
- }
-
- CFTypeRef ptl = SecTransformGetAttribute(prev_tr, kSecTransformTransformName);
- CFfprintf(stderr, "Setting INPUT for %@\n", ptl);
- SecTransformSetAttribute(prev_tr, kSecTransformInputAttributeName, CFSTR("First!"), &err);
- STAssertNil((id)err, @"Can't set first's input? %@", err);
- SecTransformSetAttribute(prev_tr, CFSTR("FIRST"), kCFBooleanTrue, &err);
- STAssertNil((id)err, @"Can't set FIRST? %@", err);
- CFTypeRef r = SecTransformExecute(group, &err);
- STAssertNil((id)err, @"execution error: %@", err);
- STAssertNotNil((id)r, @"result expected from execute");
- CFRelease(group);
- CFRelease(prev_tr);
-}
-
--(void)testNoDataDescription /* <rdar://problem/7791122> CFShow(SecCustomTransformNoData()) crashes */
-{
- CFStringRef result = CFCopyDescription(SecTransformNoData()); // this is called under the hood in CFShow, and it doesn't dump output
- STAssertNotNil((id)result, @"SecTransformNoData can be formatted");
- CFRelease(result);
-}
-
-static SecTransformInstanceBlock KnownProblemPlumbing(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- // At the moment fully disconnecting a transform from a group leaves it in the group, so it can't have any
- // kSecTransformMetaAttributeRequiresOutboundConnection=TRUE attributes (by default OUTPUT requires an outbound connection)
- SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName,
- kSecTransformMetaAttributeRequiresOutboundConnection, kCFBooleanFalse);
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, kSecTransformInputAttributeName,
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- return (CFTypeRef)CFErrorCreate(NULL, kCFErrorDomainPOSIX, EOPNOTSUPP, NULL);
- });
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
--(void)knownProblemPlumbing // note, this test has been disconnected!
-{
- SecNullTransformRef a = SecNullTransformCreate();
- CFStringRef name = CFSTR("com.apple.security.unit-test.error+outputless");
- CFErrorRef err = NULL;
-
- SecTransformRegister(name, &KnownProblemPlumbing, &err);
-
- SecTransformRef b = SecTransformCreate(name, NULL);
- SecGroupTransformRef group = SecTransformCreateGroupTransform();
-
- SecTransformConnectTransforms(a, kSecTransformOutputAttributeName, b, kSecTransformInputAttributeName, group, NULL);
- SecTransformDisconnectTransforms(a, kSecTransformOutputAttributeName, b, kSecTransformInputAttributeName);
-
-
- CFStringRef data = CFSTR("Test");
-
- SecTransformSetAttribute(a, kSecTransformInputAttributeName, data, NULL);
- CFTypeRef result = SecTransformExecute(a, &err);
-
- STAssertEqualObjects((id)data, (id)result, @"Plumbing disconnect failed.");
- STAssertNil((id)err, @"Unexpected error=%@", err);
- CFRelease(a);
- CFRelease(b);
- CFRelease(group);
-}
-
--(void)testUnknownEncodeType {
- CFErrorRef err1 = NULL;
- CFStringRef invalid_encode_type = CFSTR("no such encoding type ☃✪");
- SecTransformRef not_created = SecEncodeTransformCreate(invalid_encode_type, &err1);
- STAssertNil((id)not_created, @"Created encode transform with bad type");
- STAssertErrorHas((NSError*)err1, @"☃✪", @"Error mentions bad encoding type: %@", err1);
- fprintf(stderr, "Err1 = %p\n", err1);
- if (err1) CFRelease(err1);
- err1 = NULL;
-
- CFErrorRef err2 = NULL;
- SecTransformRef no_type_at_create = SecEncodeTransformCreate(NULL, &err2);
- fprintf(stderr, "Err2 = %p\n", err2);
- STAssertNotNil((id)no_type_at_create, @"should be able to create encoder with unset type, but got error %@", err2);
-
- if (no_type_at_create) {
- CFErrorRef err3 = NULL;
- SecTransformSetAttribute(no_type_at_create, kSecTransformInputAttributeName, NULL, &err3);
- STAssertNil((id)err3, @"Can't set INPUT: %@", err3);
- if (err3) {
- CFRelease(err3);
- err3 = NULL;
- }
- STAssertTrue(SecTransformSetAttribute(no_type_at_create, kSecEncodeTypeAttribute, kSecBase32Encoding, &err3), @"Can't set encode to valid type error: %@", err3);
- STAssertFalse(SecTransformSetAttribute(no_type_at_create, kSecEncodeTypeAttribute, invalid_encode_type, &err3), @"Set encode to invalid type, no error signaled", err3);
- fprintf(stderr, "Err3 = %p\n", err3);
- if (err3) CFRelease(err3);
-
- CFErrorRef err4 = NULL;
- CFTypeRef no_result = SecTransformExecute(no_type_at_create, &err4);
- STAssertNil((id)no_result, @"Got result when none expected %@");
- STAssertNotNil((id)err4, @"No error when one expected");
- fprintf(stderr, "Err4 = %p\n", err4);
- if (err4) CFRelease(err4);
- } else {
- STFail(@"Unable to run some tests");
- }
-
- CFRelease(no_type_at_create);
- CFRelease(invalid_encode_type);
-}
-
--(void)testNoUnderscores
-{
- SecTransformRef zt = SecEncodeTransformCreate(kSecZLibEncoding, NULL);
- CFErrorRef err = NULL;
- SecTransformSetAttribute(zt, CFSTR("_FAIL"), kCFBooleanTrue, &err);
- STAssertNotNil((id)err, @"Expeced an error setting _FAIL");
- STAssertErrorHas((id)err, @"_FAIL", @"Expected error to contain _FAIL");
- STAssertErrorHas((id)err, @"Encoder", @"Expecting error to name offending transform", err);
- CFTypeRef v = SecTransformGetAttribute(zt, CFSTR("_FAIL"));
- STAssertNil((id)v, @"Expected nil result, got v=%p", v);
- CFRelease(err);
- CFRelease(zt);
-}
-
--(void)testCanFetchDigestSizes
-{
- NSDictionary *digests = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithInt:128/8], kSecDigestMD2,
- [NSNumber numberWithInt:128/8], kSecDigestMD4,
- [NSNumber numberWithInt:128/8], kSecDigestMD5,
- [NSNumber numberWithInt:160/8], kSecDigestSHA1,
- [NSNumber numberWithInt:512/8], kSecDigestSHA2,
- nil];
- NSData *zero = [NSData dataWithBytes:"" length:1];
-
- for (NSString *digestType in digests) {
- CFErrorRef err = NULL;
- SecTransformRef digest = SecDigestTransformCreate(digestType, 0, &err);
- STAssertNotNil((id)digest, @"Expected to make digest (err=%@)", err);
- STAssertNil((id)err, @"Unexpected error: %@", err);
- NSNumber *actualLength = (NSNumber*)SecTransformGetAttribute(digest, kSecDigestLengthAttribute);
- STAssertTrue([actualLength intValue] != 0, @"Got zero length back");
- STAssertNotNil(actualLength, @"Expected to get a length");
- STAssertEqualObjects(actualLength, [digests objectForKey:digestType], @"Expected lengths to match for %@", digestType);
-
- SecTransformSetAttribute(digest, kSecTransformInputAttributeName, zero, &err);
- STAssertNil((id)err, @"Unexpected error: %@", err);
-
- NSData *output = (NSData *)SecTransformExecute(digest, &err);
- STAssertNil((id)err, @"Unexpected error: %@", err);
- STAssertNotNil((id)output, @"No output");
-
- STAssertEquals([actualLength intValue], (int)[output length], @"Actual output not expected length");
-
- [output release];
- CFRelease(digest);
- }
-}
-
--(void)testBadTransformTypeNames
-{
- CFErrorRef error = NULL;
- Boolean ok = SecTransformRegister(CFSTR("Not valid: has a col..co...double dot thing"), DelayTransformBlock, &error);
- STAssertFalse(ok, @"Register of name with : fails");
- STAssertErrorHas((id)error, @":", @"Error mentions invalid character (error=%@)", error);
-
- ok = SecTransformRegister(CFSTR("Not/valid has a slash"), DelayTransformBlock, &error);
- STAssertFalse(ok, @"Register of name with / fails");
- STAssertErrorHas((id)error, @"/", @"Error mentions invalid character (error=%@)", error);
-
- ok = SecTransformRegister(CFSTR("https://NOT/VALID"), DelayTransformBlock, &error);
- STAssertFalse(ok, @"Register of name with : and / fails");
- STAssertErrorHas((id)error, @"[:/]", @"Error mentions invalid character (error=%@)", error);
-
- ok = SecTransformRegister(CFSTR("_not valid at start"), DelayTransformBlock, &error);
- STAssertFalse(ok, @"Register of _name fails");
- STAssertErrorHas((id)error, @"_", @"Error mentions invalid character (error=%@)", error);
-
- ok = SecTransformRegister(CFSTR("it is ok to have a _ after start"), DelayTransformBlock, &error);
- STAssertTrue(ok, @"Register of _ IN should have worked (error=%@)", error);
-}
-
--(void)testExecuteBlock {
- unsigned char *raw_data = (unsigned char *)"Just some bytes, you know";
- //NSData *empty = [NSData dataWithBytes:NULL length:0];
- NSData *data = [NSData dataWithBytes:raw_data length:strlen((const char *)raw_data)];
- //NSUInteger ecnt = [empty retainCount];
-
- SecTransformRef zt = SecEncodeTransformCreate(kSecZLibEncoding, NULL);
- SecTransformSetAttribute(zt, kSecTransformInputAttributeName, data, NULL);
- dispatch_queue_t q = dispatch_queue_create("com.apple.security.testingQ", NULL);
- dispatch_queue_t q_sync = dispatch_queue_create("com.apple.security.testingQ_sync", NULL);
- dispatch_suspend((dispatch_object_t)q_sync);
- __block BOOL ran_block = NO;
-
- SecTransformExecuteAsync(zt, q, ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) {
-// if ([empty length]) {
-// NSLog(@"Empty data not so empty");
-// }
- STAssertTrue(dispatch_get_current_queue() == q, @"block dispatched to proper queue");
-
- if (!ran_block) {
- usleep(200);
- ran_block = YES;
- }
-
- if (message == NULL) {
- dispatch_resume((dispatch_object_t)q_sync);
- }
- });
-
- //STAssertTrue(ecnt < [empty retainCount], @"SecTransformExecute retained block");
- dispatch_sync(q_sync, ^{ });
- STAssertTrue(ran_block, @"Block executed");
-
- dispatch_release(q_sync);
- dispatch_release(q);
- CFRelease(zt);
-
- // test for 7735698
- // STAssertTrue(ecnt == [empty retainCount], @"SecTransformExecute released block");
-}
-
-static SecTransformInstanceBlock ConnectionCheck(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- __block SecTransformMetaAttributeType dir = kSecTransformMetaAttributeValue;
-
- SecTransformAttributeRef out_ah =
- SecTranformCustomGetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeRef);
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("DIRECTION"),
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- if (CFEqual(value, CFSTR("<")))
- {
- dir = kSecTransformMetaAttributeHasInboundConnection;
- }
- else if (CFEqual(value, CFSTR(">")))
- {
- dir = kSecTransformMetaAttributeHasOutboundConnections;
- }
- else
- {
- return (CFTypeRef)CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, "Unsupported direction %@, expected < or >", value);
- }
- return value;
- });
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("INPUT"),
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- if (dir != kSecTransformMetaAttributeValue)
- {
- if (value)
- {
- SecTransformCustomSetAttribute(ref, out_ah, kSecTransformMetaAttributeValue,
- SecTranformCustomGetAttribute(ref, value, dir));
- }
- else
- {
- SecTransformCustomSetAttribute(ref, out_ah, kSecTransformMetaAttributeValue, NULL);
- }
- }
- else
- {
- SecTransformPushbackAttribute(ref, ah, value);
- }
-
- return value;
- });
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
--(void)testConnectionChecks {
-
- CFStringRef name = CFSTR("com.apple.security.unit-test.connection-checks");
- CFErrorRef error = NULL;
- SecTransformRegister(name, &*ConnectionCheck, &error);
-
- struct test_case {
- NSString *attr, *dir;
- CFBooleanRef expect;
- } cases[] = {
- {@"INPUT", @"<", kCFBooleanTrue},
- {@"OUTPUT", @">", kCFBooleanTrue},
- {@"INPUT", @">", kCFBooleanFalse},
- {@"OUTPUT", @"<", kCFBooleanFalse},
- {@"DIRECTION", @"<", kCFBooleanFalse},
- {@"DIRECTION", @">", kCFBooleanFalse},
- };
-
- CFIndex i, n = sizeof(cases)/sizeof(test_case);
- for(i = 0; i < n; ++i)
- {
- test_case *t = cases + i;
-
- SecTransformRef cct = SecTransformCreate(name, NULL);
- SecTransformRef tee0 = SecNullTransformCreate();
- SecTransformRef tee1 = SecNullTransformCreate();
- SecTransformRef group = SecTransformCreateGroupTransform();
-
- SecTransformSetAttribute(cct, CFSTR("DEBUG"), kCFBooleanTrue, NULL);
- SecTransformSetAttribute(tee0, CFSTR("DEBUG"), kCFBooleanTrue, NULL);
- SecTransformSetAttribute(tee1, CFSTR("DEBUG"), kCFBooleanTrue, NULL);
-
- SecTransformSetAttribute(tee0, CFSTR("NAME"), CFSTR("tee0"), NULL);
- SecTransformSetAttribute(tee1, CFSTR("NAME"), CFSTR("tee1"), NULL);
-
- SecTransformConnectTransforms(cct, CFSTR("OUTPUT"), tee1, CFSTR("INPUT"), group, NULL);
- SecTransformConnectTransforms(tee0, CFSTR("OUTPUT"), cct, CFSTR("INPUT"), group, NULL);
-
- SecTransformSetAttribute(cct, CFSTR("DIRECTION"), t->dir, NULL);
- SecTransformSetAttribute(tee0, CFSTR("INPUT"), t->attr, NULL);
- CFErrorRef err = NULL;
- CFTypeRef r = SecTransformExecute(group, &err);
- STAssertNil((id)err, @"Error=%@ for case#%d", err, i);
- STAssertNotNil((id)r, @"Nil result for case#%d", i);
- STAssertEqualObjects((id)(t->expect), (id)r, @"Expected result for case#%d %@%@", i, t->dir, t->attr);
-
- CFRelease(cct);
- CFRelease(tee0);
- CFRelease(tee1);
- CFRelease(group);
- }
-
-}
-
-static SecTransformInstanceBlock PushBackTest(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- __block CFStringRef input_d = NULL;
- __block CFStringRef data_d = NULL;
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("DATA"),
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- if (!input_d)
- {
- SecTransformPushbackAttribute(ref, ah, value);
- }
- else
- {
- if (data_d)
- {
- CFRelease(data_d);
- }
- data_d = (CFStringRef)CFRetain(value);
- }
- return value;
- });
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("INPUT"),
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- if (value)
- {
- if (input_d)
- {
- CFRelease(input_d);
- }
- input_d = (CFStringRef)CFRetain(value);
- if (!data_d)
- {
- SecTransformPushbackAttribute(ref, ah, value);
- return value;
- }
- }
- else
- {
- if (data_d)
- {
- SecTransformPushbackAttribute(ref, ah, NULL);
- value = data_d;
- data_d = NULL;
- }
- }
- SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeValue, value);
- return value;
- });
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
--(void)testPushback {
-
- CFStringRef name = CFSTR("com.apple.security.unit-test.basic-pushback");
- CFStringRef one = CFSTR("1");
- CFStringRef two = CFSTR("2");
- CFStringRef expect = CFSTR("12");
-
- // This unit test makes pushback look very complex, but that is because we are abusing it for test purposes.
- // normally it is a simple "if I need X before I can go on, and X isn't here yet pushback". Here we attempt
- // to carefully sequence 2 attributes to be the inverse of the normal order AND test pushback of NULL as well
- // as normal values.
-
- CFErrorRef error = NULL;
- SecTransformRegister(name, &PushBackTest, &error);
-
- SecTransformRef pt = SecTransformCreate(name, NULL);
-
- SecTransformSetAttribute(pt, CFSTR("DATA"), two, NULL);
- SecTransformSetAttribute(pt, CFSTR("INPUT"), one, NULL);
-
- CFTypeRef result = SecTransformExecute(pt, NULL);
-
- STAssertEqualObjects((id)result, (id)expect, @"Testing pushback");
-
- CFRelease(pt);
-
- // NOTE: we want to test doing a double pushback, but that sets the Abort attribute which currently causes an abort not an orderly shutdown
-
-}
-
-static SecTransformInstanceBlock CustomExternalization(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- // Create a non-attribute 'instance' variable which will contain
- // the version number of this class
-
- __block float versionNumber = 1.0;
-
- // Register the custom externalize override
- SecTransformActionBlock ExternalizeExtraDataOverride =
- ^{
- CFStringRef key = CFSTR("VersionNumber");
- CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &versionNumber);
-
- CFDictionaryRef result = CFDictionaryCreate(kCFAllocatorDefault,
- (const void **)&key, (const void **)&value,
- 1, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-
- CFRelease(value);
-
-
- return (CFTypeRef)result;
-
- };
- SecTransformSetTransformAction(ref, kSecTransformActionExternalizeExtraData, ExternalizeExtraDataOverride);
-
- // Register the custom internalize override
- SecTransformDataBlock InternalizeExtraDataOverride =
- ^(CFTypeRef d)
- {
- CFTypeRef internalizeResult = NULL;
- //id testObj = (id)d;
-
- //STAssertNotNil(testObj, @"Internalize did NOT get a dictionary!");
-
- if (CFDictionaryGetTypeID() == CFGetTypeID(d))
- {
- CFStringRef key = CFSTR("VersionNumber");
- CFDictionaryRef dict = (CFDictionaryRef)d;
- CFNumberRef varsNum = (CFNumberRef)CFDictionaryGetValue(dict, key);
- // STAssertNotNil((NSNumber *)varsNum,
- // @"Unable to retrieve the dictionary when the internalized data override");
- if (NULL != varsNum)
- {
- Boolean numResult = CFNumberGetValue(varsNum, kCFNumberFloatType, &versionNumber);
- // STAssertTrue(numResult, @"Could not get the version number from the CFNumberRef");
- if (numResult)
- {
- //float knownVersion = 1.0;
- // STAssertTrue(knownVersion == versionNumber, @"Versions do not Match!");
- }
- }
- }
- return internalizeResult;
- };
- SecTransformSetDataAction(ref, kSecTransformActionInternalizeExtraData,
- InternalizeExtraDataOverride);
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
-/* --------------------------------------------------------------------------
- method: testCustomExternalization
- description: Test the ability to write out custom external data
- -------------------------------------------------------------------------- */
-- (void)testCustomExternalization
-{
- NSString* ctName = @"com.apple.security.unit-test-customExternalization";
- NSError* error = nil;
-
- CFStringRef aName = (CFStringRef)ctName;
- CFErrorRef* anError = (CFErrorRef *)&error;
-
- Boolean registerResult = SecTransformRegister(aName, &CustomExternalization, anError);
- STAssertTrue(registerResult, @"Unable to register the custom externalization transform");
-
- SecTransformRef externalTrans = SecTransformCreate((CFStringRef)ctName,
- (CFErrorRef *)&error);
-
- STAssertNotNil((id)externalTrans, @"Could not create the custom externalization transform");
-
- CFDictionaryRef externalData = SecTransformCopyExternalRepresentation(externalTrans);
- STAssertNotNil((NSDictionary *)externalData, @"Did not get a dictionary from SecTransformCopyExternalRepresentation");
-
- CFRelease(externalTrans);
-
- externalTrans = NULL;
- externalTrans = SecTransformCreateFromExternalRepresentation(externalData, (CFErrorRef *)&error);
- STAssertNotNil((id)externalTrans, @"Could not create the custom external representation");
- CFRelease(externalData);
- if (NULL != externalTrans)
- {
- CFRelease(externalTrans);
- }
-}
-
-static SecTransformInstanceBlock TestString(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- SecTransformSetDataAction(ref, kSecTransformActionProcessData,
- ^(CFTypeRef value)
- {
- CFDataRef d = (CFDataRef)value;
- if (d) {
- return (CFTypeRef)CFStringCreateWithBytes(NULL, CFDataGetBytePtr(d), CFDataGetLength(d), kCFStringEncodingMacRoman, FALSE);
- } else {
- return (CFTypeRef)d;
- }
- });
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
--(void)testStringResults {
- CFStringRef name = CFSTR("com.apple.security.unit-test.string-converter");
- CFErrorRef error = NULL;
- SecTransformRegister(name, &TestString, &error);
-
- SecTransformRef sr = SecTransformCreate(name, NULL);
-
- unsigned char *msg = (unsigned char *)"This is a test message, it isn't large, but it will get broken into parts by the encode/decode transforms...";
- CFDataRef data = CFDataCreate(NULL, msg, strlen((const char *)msg));
- NSString *ns_msg = [NSString stringWithCString:(const char *)msg encoding:NSMacOSRomanStringEncoding];
-
- SecTransformRef er = SecEncodeTransformCreate(kSecBase32Encoding, NULL);
- SecTransformRef dr = SecDecodeTransformCreate(kSecBase32Encoding, NULL);
-
- SecTransformSetAttribute(er, kSecTransformInputAttributeName, data, NULL);
-
- SecGroupTransformRef group = SecTransformCreateGroupTransform();
- SecTransformConnectTransforms(er, kSecTransformOutputAttributeName, dr, kSecTransformInputAttributeName, group, NULL);
- SecTransformConnectTransforms(dr, kSecTransformOutputAttributeName, sr, kSecTransformInputAttributeName, group, NULL);
-
-
- CFStringRef result = (CFStringRef)SecTransformExecute(sr, NULL);
- STAssertEqualObjects(ns_msg, (NSString *)result, @"string results");
-
- CFRelease(result);
- CFRelease(group);
- CFRelease(dr);
- CFRelease(er);
- CFRelease(sr);
- if (error)
- {
- CFRelease(error);
- }
-}
-
-static CFNumberRef MakeNumber1(long n)
-{
- return CFNumberCreate(NULL, kCFNumberLongType, &n);
-}
-
-
-
-static SecTransformInstanceBlock TestRegisterCreate(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
-
-
- SecTransformInstanceBlock instanceBlock =
- ^{
- __block long count = 0;
-
- __block CFNumberRef countNum = MakeNumber1(count);;
- SecTransformCustomSetAttribute(ref, CFSTR("Count"), kSecTransformMetaAttributeValue, countNum);
- CFRelease(countNum);
- fprintf(stderr, "countNum = %p\n", countNum);
-
- CFErrorRef result = NULL;
- SecTransformSetDataAction(ref, kSecTransformActionProcessData,
- ^(CFTypeRef value)
- {
- CFDataRef d = (CFDataRef)value;
- if (d)
- {
- count += CFDataGetLength(d);
-
- CFNumberRef countNum2 = CFNumberCreate(kCFAllocatorDefault, kCFNumberLongType, &count);
- SecTransformCustomSetAttribute(ref, CFSTR("Count"), kSecTransformMetaAttributeValue, countNum2);
- CFRelease(countNum2);
- fprintf(stderr, "countNum = %p\n", countNum);
-
- } else
- {
- SecTransformCustomSetAttribute(ref, CFSTR("Count"), kSecTransformMetaAttributeValue, NULL);
- }
- return value;
- });
-
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
-- (void)testRegisterCreate
-{
- CFStringRef name = CFSTR("com.apple.security.unit-test.novel-unique-at-least-unusual-name");
- long count = 0;
- CFNumberRef countNum = NULL;
- CFErrorRef error = NULL;
- Boolean ok = SecTransformRegister(name, &TestRegisterCreate, &error);
- STAssertTrue(ok, @"Successful register");
-
- SecTransformRef tr = SecTransformCreate(name, NULL);
- STAssertNotNil((NSObject *)tr, @"newly created custom transform");
- SecTransformSetAttribute(tr, CFSTR("DEBUG"), kCFBooleanTrue, NULL);
-
- char *data_bytes = (char *)"It was the best of transforms, it was the worst of transforms.";
- CFDataRef data = CFDataCreate(NULL, (const UInt8 *)data_bytes, strlen(data_bytes));
-
- SecTransformSetAttribute(tr, kSecTransformInputAttributeName, data, NULL);
-
- SecTransformRef nt = SecNullTransformCreate();
- SecTransformRef tg = SecTransformCreateGroupTransform();
- SecTransformConnectTransforms(tr, CFSTR("OUTPUT"), nt, CFSTR("DISCARD"), tg, &error);
- STAssertNil((id)error, @"Connected tr's output to nt's discard: %@", error);
- SecTransformConnectTransforms(tr, CFSTR("Count"), nt, CFSTR("INPUT"), tg, &error);
- STAssertNil((id)error, @"Connected tr's count to nt's input: %@", error);
-
- SecTransformSetAttribute(nt, CFSTR("DEBUG"), kCFBooleanTrue, NULL);
-
- usleep(100);
- countNum = (CFNumberRef)SecTransformGetAttribute(tr, CFSTR("Count"));
- CFNumberGetValue(countNum, kCFNumberLongType, &count);
- CFRelease(countNum);
- STAssertTrue(count == 0, @"length unchanged before execute");
-
- countNum = (CFNumberRef)SecTransformExecute(tg, NULL);
- STAssertNotNil((id)countNum, @"Got result from execute");
- STAssertEquals(CFGetTypeID(countNum), CFNumberGetTypeID(), @"expected a number from execute");
- CFNumberGetValue(countNum, kCFNumberLongType, &count);
- CFRelease(countNum);
-
- STAssertTrue(count == CFDataGetLength(data), @"Wrong data length");
-
- CFRelease(tg);
- CFRelease(nt);
- CFRelease(tr);
- CFRelease(data);
-}
-
-
-static SecTransformInstanceBlock CountTransformTest(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- SecTransformSetAttributeAction(ref,kSecTransformActionAttributeNotification, CFSTR("INPUT"),
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- if (value) {
- if (CFGetTypeID(value) != CFNumberGetTypeID()) {
- SecTransformCustomSetAttribute(ref, CFSTR("ABORT"), kSecTransformMetaAttributeValue, CFSTR("Bad type"));
- return value;
- }
- CFNumberRef nr = (CFNumberRef)value;
- int max, i;
- CFNumberGetValue(nr, kCFNumberIntType, &max);
- for(i = 0; i < max; ++i) {
- nr = CFNumberCreate(NULL, kCFNumberIntType, &i);
- SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeValue, nr);
- CFRelease(nr);
- }
- } else {
- SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeValue, value);
- }
-
- return value;
- });
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
-static SecTransformRef count_transform(int n) {
- CFStringRef name = CFSTR("com.apple.security.unit-test.count");
- static dispatch_once_t once;
-
- dispatch_once(&once,
- ^{
- SecTransformRegister(name, &CountTransformTest, NULL);
- });
-
- SecTransformRef ct = SecTransformCreate(name, NULL);
- CFNumberRef num = CFNumberCreate(NULL, kCFNumberIntType, &n);
- SecTransformSetAttribute(ct, CFSTR("INPUT"), num, NULL);
- CFRelease(num);
-
- return ct;
-}
-
-
-static SecTransformInstanceBlock StallTest(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- __block bool go = false;
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("GO"),
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- go = true;
- return value;
- });
-
- SecTransformAttributeRef in_ah = SecTransformCustomGetAttribute(ref, CFSTR("INPUT"), kSecTransformMetaAttributeRef);
- SecTransformAttributeRef out_ah = SecTransformCustomGetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeRef);
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, NULL,
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- if (!go) {
- SecTransformPushbackAttribute(ref, ah, value);
- } else {
- if (ah == in_ah) {
- SecTransformCustomSetAttribute(ref, out_ah, kSecTransformMetaAttributeValue, value);
- }
- }
- return value;
- });
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
--(void)testStall {
- CFStringRef name = CFSTR("com.apple.security.unit-test.stall");
-
- (void)SecTransformRegister(name, &StallTest, NULL);
-
- SecTransformRef stall = SecTransformCreate(name, NULL);
- SecTransformRef seven = count_transform(7);
- SecTransformRef group = SecTransformCreateGroupTransform();
- SecTransformRef delay = delay_transform(NSEC_PER_SEC / 10);
-
- SecTransformConnectTransforms(seven, CFSTR("OUTPUT"), stall, CFSTR("FOO"), group, NULL);
- SecTransformConnectTransforms(seven, CFSTR("OUTPUT"), stall, CFSTR("BAR"), group, NULL);
- SecTransformConnectTransforms(seven, CFSTR("OUTPUT"), stall, CFSTR("BAZ"), group, NULL);
- SecTransformConnectTransforms(seven, CFSTR("OUTPUT"), stall, CFSTR("INPUT"), group, NULL);
- SecTransformConnectTransforms(delay, CFSTR("OUTPUT"), stall, CFSTR("GO"), group, NULL);
-
- SecTransformSetAttribute(delay, CFSTR("INPUT"), (CFNumberRef)[NSNumber numberWithInt:42], NULL);
-
- CFErrorRef err = NULL;
- CFTypeRef r = SecTransformExecute(group, &err);
-
- STAssertNotNil((id)r, @"Results from testStall");
- STAssertNil((id)err, @"Got %@ error from testStall", err);
- NSArray *array_seven = [NSArray arrayWithObjects:[NSNumber numberWithInt:0], [NSNumber numberWithInt:1], [NSNumber numberWithInt:2], [NSNumber numberWithInt:3], [NSNumber numberWithInt:4], [NSNumber numberWithInt:5], [NSNumber numberWithInt:6], NULL];
- STAssertEqualObjects((id)r, array_seven, @"Correct stall test results");
-
- CFRelease(delay);
- CFRelease(group);
- CFRelease(seven);
- CFRelease(stall);
-}
-
--(void)testInappropriateExecution
-{
- // We want to have more then enough work for all the CPUs to help force a race, so twice
- // the number of logical CPUs should do it. NOTE: the completion blocks got to a low
- // priority concurrent queue to encourage them to finish out of order and put more
- // stress on the system we are testing.
-
- int logical_cpus = 1;
- size_t int_size = sizeof(logical_cpus);
- int return_code = sysctlbyname("hw.logicalcpu_max", &logical_cpus, &int_size, NULL, 0);
- int e = errno; // Save this value so it doesn't get trashed by any subsequent syscalls
- STAssertEquals(return_code, 0, @"sysctlbyname failed %s (%d), assuming 1 CPU", strerror(e), e);
-
- SecTransformRef count_a_bunch = count_transform(logical_cpus * 2);
- CFErrorRef err = NULL;
- dispatch_group_t wait_for_async_to_complete = dispatch_group_create();
- dispatch_group_t outstanding_executions = dispatch_group_create();
- SecTransformRef count_group = SecTransformCreateGroupTransform();
-
- SecTransformConnectTransforms(count_a_bunch, CFSTR("kludge1"), count_a_bunch, CFSTR("kludge2"), count_group, &err);
- STAssertNil((id)err, @"Error (%@) connecting count transform to itself", err);
-
- dispatch_group_enter(wait_for_async_to_complete);
- SecTransformExecuteAsync(count_a_bunch, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^(CFTypeRef message, CFErrorRef error, Boolean isFinal)
- {
- dispatch_group_enter(outstanding_executions);
-
- CFErrorRef err = NULL;
- CFTypeRef no_result = SecTransformExecute(count_a_bunch, &err);
- STAssertNil((id)no_result, @"Attempting to execute an already executing transform should fail, not provide results: %@", no_result);
- STAssertNotNil((id)err, @"Attempting to execute an already executing transform should produce some sort of error");
- CFRelease(err);
-
- dispatch_group_leave(outstanding_executions);
-
- if (isFinal)
- {
- // Give any pending executions time to get to the group_enter
- usleep(100);
- dispatch_group_wait(outstanding_executions, DISPATCH_TIME_FOREVER);
- dispatch_release(outstanding_executions);
- dispatch_group_leave(wait_for_async_to_complete);
- }
- });
-
- // Before that SecTransformExecuteAsync completes, we do some more work at >low priority to help
- // keep the completion blocks landing out of order. In particular we run a transform to
- // completion, and then confirm that we can't run it again.
-
- SecTransformRef no_work = SecNullTransformCreate();
- SecTransformRef no_work_group = SecTransformCreateGroupTransform();
- SecTransformConnectTransforms(no_work, CFSTR("kludge1"), no_work, CFSTR("kludge2"), no_work_group, &err);
- STAssertNil((id)err, @"Can't connect no_work to itself (to make no_work_group), err=%@", err);
-
- SecTransformSetAttribute(no_work, CFSTR("INPUT"), CFSTR("value"), NULL);
- CFTypeRef no_result = SecTransformExecute(no_work_group, &err);
- STAssertNil((id)err, @"First execute of Null Transform should be ok, got e=%@", err);
- STAssertNotNil((id)no_result, @"First execute of Null Transform should produce a value");
-
- no_result = SecTransformExecute(no_work_group, &err);
-
- STAssertNotNil((id)err, @"Second execute of Null Transform should fail!");
- STAssertNil((id)no_result, @"Second execute of Null Transform shouldn't produce a value, got r=%@", no_result);
- CFRelease(err);
-
- // Now we wait for that first batch of tests to finish, we don't want to call STFail after self goes away.
-
- dispatch_group_wait(wait_for_async_to_complete, DISPATCH_TIME_FOREVER);
- dispatch_release(wait_for_async_to_complete);
-
- if (no_result) CFRelease(no_result);
- if (no_work) CFRelease(no_work);
- if (no_work_group) CFRelease(no_work_group);
- if (count_group) CFRelease(count_group);
- if (count_a_bunch) CFRelease(count_a_bunch);
-}
-
-static SecTransformInstanceBlock ConnectionReqTest(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- SecTransformAttributeRef xah =
- (SecTransformAttributeRef)SecTranformCustomGetAttribute(ref, CFSTR("XYZZY"), kSecTransformMetaAttributeRef);
-
- SecTransformCustomSetAttribute(ref, xah, kSecTransformMetaAttributeRequiresOutboundConnection, kCFBooleanTrue);
- SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeRequiresOutboundConnection, kCFBooleanFalse);
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("INPUT"),
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- SecTransformCustomSetAttribute(ref, xah, kSecTransformMetaAttributeValue, value);
- return value;
- });
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
-
--(void)testConnectionReq {
-
- CFStringRef req_xyzzy_name = CFSTR("com.apple.security.unit-test.req_xyzzy");
-
- (void)SecTransformRegister(req_xyzzy_name, &ConnectionReqTest, NULL);
-
- SecTransformRef tr_req_xyzzy = SecTransformCreate(req_xyzzy_name, NULL);
-
- CFTypeRef in_value = (CFTypeRef)@"Fnord";
- SecTransformSetAttribute(tr_req_xyzzy, CFSTR("INPUT"), in_value, NULL);
-
- CFErrorRef err = NULL;
- CFTypeRef r = SecTransformExecute(tr_req_xyzzy, &err);
-
- STAssertNil((id)r, @"Execute of tr_req_xyzzy with no xyzzy r=%@", r);
- STAssertErrorHas((id)err, @"req_xyzzy", @"Error failed to refer to the transform by name (%@)", err);
- STAssertErrorHas((id)err, @"XYZZY", @"Error failed to refer to missing attribute by name (%@)", err);
- STAssertErrorHas((id)err, @"requires.*outbound connection", @"Error failed to diagnose invalid condition (%@)", err);
-
- CFRelease(err);
- CFRelease(tr_req_xyzzy);
- if (r) CFRelease(r);
-
- /*
-
- Note For Josh:
-
- To make this work we need Josh's fix for FindLastTransform!
-
- CFRelease(tr_req_xyzzy);
- tr_req_xyzzy = SecTransformCreate(req_xyzzy_name, NULL);
- SecTransformSetAttribute(tr_req_xyzzy, CFSTR("INPUT"), in_value, NULL);
-
- SecTransformRef group = SecTransformCreateGroupTransform();
- SecTransformRef tee = SecNullTransformCreate();
- SecTransformConnectTransforms(tr_req_xyzzy, CFSTR("XYZZY"), tee, kSecTransformInputAttributeName, group, &err);
- STAssertNil((id)err, @"err=%@ from connect", err);
- STAssertNotNil((id)group, @"No group after connect");
- r = SecTransformExecute(group, &err);
- STAssertNil((id)err, @"Execute err=%@");
- STAssertEqualObjects((id)in_value, (id)r, @"Execution Result");
-
- */
-}
-
-static SecTransformInstanceBlock DeferredTest(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- SecTransformCustomSetAttribute(ref, CFSTR("LATE"), kSecTransformMetaAttributeDeferred, kCFBooleanTrue);
- SecTransformCustomSetAttribute(ref, CFSTR("INPUT"), kSecTransformMetaAttributeDeferred, kCFBooleanFalse);
-
- __block CFTypeRef in_v = NULL, late_v = NULL;
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("INPUT"),
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- if (NULL != late_v) {
- SecTransformCustomSetAttribute(ref, kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue,
- CreateGenericErrorRef(CFSTR("FAIL"), 1, "LATE (%@) should process after INPUT (%@)", late_v, value));
- }
- in_v = value;
- return value;
- });
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("LATE"),
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- if (NULL == in_v) {
- SecTransformCustomSetAttribute(ref, kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue,
- CreateGenericErrorRef(CFSTR("FAIL"), 1, "INPUT (%@) should process before LATE (%@)", in_v, value));
- }
-
- late_v = value;
- SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeValue, NULL);
- return value;
- });
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
-
--(void)testDeferred {
- CFStringRef deferred_name = CFSTR("com.apple.security.unit-test.deferred");
-
- (void)SecTransformRegister(deferred_name, &DeferredTest, NULL);
-
- SecTransformRef dt = SecTransformCreate(deferred_name, NULL);
-
- // these set attribute calls are failing, but we're ignoring the failures
- SecTransformSetAttribute(dt, CFSTR("INPUT"), (CFTypeRef)CFSTR("BLAH"), NULL);
- SecTransformSetAttribute(dt, CFSTR("LATE"), (CFTypeRef)CFSTR("QUUX"), NULL);
- CFErrorRef err = NULL;
- SecTransformExecute(dt, &err);
- STAssertNil((id)err, @"Error from execute err=%@", err);
-
- if (err) CFRelease(err);
- // CFRelease(dt);
-}
-
-static SecTransformInstanceBlock SaveRestoreTest(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- SecTransformCustomSetAttribute(ref, CFSTR("Needed"), kSecTransformMetaAttributeRequired, kCFBooleanTrue);
- SecTransformCustomSetAttribute(ref, CFSTR("NoSaves"), kSecTransformMetaAttributeExternalize, kCFBooleanFalse);
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
--(void)testSaveRestore
-{
-
- unsigned char raw_data[] = "Val-U-Sav, nw wth lss vwls!";
- CFDataRef data = CFDataCreate(NULL, (const UInt8*)&raw_data, sizeof(raw_data));
- CFErrorRef err = NULL;
-
- CFStringRef name = CFSTR("com.apple.security.unit-test.SaveRestoreTest");
-
- (void)SecTransformRegister(name, &SaveRestoreTest, NULL);
-
- SecTransformRef tr1 = SecTransformCreate(name, NULL);
-
- SecTransformSetAttribute(tr1, CFSTR("Optional"), CFSTR("42"), NULL);
- SecTransformSetAttribute(tr1, CFSTR("Needed"), CFSTR("and provided"), NULL);
- SecTransformSetAttribute(tr1, CFSTR("NoSaves"), CFSTR("42"), NULL);
-
- CFDictionaryRef xr = SecTransformCopyExternalRepresentation(tr1);
- STAssertNotNil((NSDictionary *)xr, @"external rep");
- SecTransformRef tr2 = SecTransformCreateFromExternalRepresentation(xr, NULL);
- SecTransformSetAttribute(tr2, kSecTransformInputAttributeName, data, NULL);
- CFTypeRef none = SecTransformGetAttribute(tr2, CFSTR("NoSaves"));
- STAssertNil((id)none, @"Expected %@ to be nil", none);
- CFTypeRef forty_two = SecTransformGetAttribute(tr2, CFSTR("Optional"));
- STAssertEqualObjects((id)forty_two, @"42", @"restored incorrect value");
-
- CFDataRef d = (CFDataRef)SecTransformExecute((NSObject *)tr2, &err);
-
- STAssertNotNil((NSData * )d, @"execute result (err=%@)", err);
-
- if (err) {
- CFRelease(err);
- }
-
- CFRelease(tr1);
- CFRelease(tr2);
- CFRelease(xr);
-
- tr1 = SecTransformCreate(name, NULL);
- SecTransformSetAttribute(tr1, CFSTR("Needed"), CFSTR("and provided"), NULL);
- SecTransformSetAttribute(tr1, CFSTR("NoSaves"), CFSTR("42"), NULL);
- xr = SecTransformCopyExternalRepresentation(tr1);
- tr2 = SecTransformCreateFromExternalRepresentation(xr, NULL);
-
-
-
- //tr2 = SecTransformCreateFromExternalRepresentation(xr, NULL);
- SecTransformRef tga = SecTransformCreateGroupTransform();
- SecTransformSetAttribute(tr1, kSecTransformInputAttributeName, data, NULL);
-
- // XXX did not swap
- SecTransformConnectTransforms(tr1, CFSTR("OUTPUT"), tr2, CFSTR("INPUT"), tga, NULL);
- CFStringRef has1 = CFSTR("I has one!");
- CFStringRef has2 = CFSTR("I has two of them!");
- SecTransformSetAttribute(tr1, CFSTR("Needed"), has1, NULL);
- SecTransformSetAttribute(tr2, CFSTR("Needed"), has2, NULL);
- xr = SecTransformCopyExternalRepresentation(tr1);
- STAssertNotNil((NSDictionary *)xr, @"external rep for 2");
- NSLog(@"xr=%@", xr);
-
- SecTransformRef tgb = SecTransformCreateFromExternalRepresentation(xr, &err);
- STAssertNil((id)tgb, @"made transform group with duplicate labels");
- STAssertErrorHas((id)err, (NSString*)name, @"Error failed to identify the transform (%@)", err);
- STAssertErrorHas((id)err, @"damage|duplicate", @"Error failed to diagnose the invalid condition (%@)", err);
-
- CFStringRef new_name2 = CFSTR("SaveRestoreTestThingie#2");
- CFStringRef fetched_name;
- int attempts;
-
- for(attempts = 0; attempts < 20; ++attempts)
- {
- SecTransformSetAttribute(tr2, CFSTR("NAME"), new_name2, &err);
- fetched_name = (CFStringRef)SecTransformGetAttribute(tr2, CFSTR("NAME"));
-
- STAssertNil((id)err, @"Error from setting tr2's name: %@", err);
- STAssertEqualObjects((id)fetched_name, (id)new_name2, @"Set tr2's name, attempt %d", attempts);
- if (CFEqual(fetched_name, new_name2))
- {
- break;
- }
- if (attempts > 10)
- {
- usleep(1000);
- }
- }
-
- xr = SecTransformCopyExternalRepresentation(tr1);
- STAssertNotNil((NSDictionary *)xr, @"external rep for 2, take 2");
- NSLog(@"xr=%@", xr);
-
- tgb = SecTransformCreateFromExternalRepresentation(xr, &err);
- STAssertNotNil((id)tgb, @"made transform group (take 2)");
- STAssertNil((id)err, @"error from make 2 take 2 (err=%@)", err);
-
- SecTransformRef tr1b = SecTransformFindByName(tgb, (CFStringRef)SecTransformGetAttribute(tr1, CFSTR("NAME")));
- STAssertNotNil((id)tr1b, @"Found tr1b");
- SecTransformRef tr2b = SecTransformFindByName(tgb, (CFStringRef)SecTransformGetAttribute(tr2, CFSTR("NAME")));
- STAssertNotNil((id)tr2b, @"Found tr2b");
-
- CFStringRef has1b = (CFStringRef)SecTransformGetAttribute(tr1b, CFSTR("Needed"));
- STAssertNotNil((id)tr1b, @"tr1b's name");
- CFStringRef has2b = (CFStringRef)SecTransformGetAttribute(tr2b, CFSTR("Needed"));
- STAssertNotNil((id)tr2b, @"tr1b's name");
-
- STAssertEqualObjects((id)has1, (id)has1b, @"has1 == has1b");
- STAssertEqualObjects((id)has2, (id)has2b, @"has2 == has2b");
-
-}
-
--(void)testRequiredAttributes
-{
- CFStringRef name = CFSTR("com.apple.security.unit-test.requiresStuffThings");
- CFErrorRef error;
- // In addition to testing required attributes, this also does a partial "lifecycle" test, making sure we
- // pass through the stages, don't regress stages, and don't receive the wrong events in the wrong stages.
- typedef enum { S_INITED = 0, S_STARTED, S_RUN, S_EOS, S_GONE } state_t;
-
- __block state_t state = S_INITED;
- dispatch_group_t leave_on_finalize = dispatch_group_create();
-
- SecTransformCreateBlock required_attributes_create_block = ^(CFStringRef name, SecTransformRef new_transform, const SecTransformCreateBlockParameters *params) {
- params->overrideAttribute(kSecTransformActionAttributeNotification, kSecTransformInputAttributeName, ^(SecTransformAttributeRef attribute, CFTypeRef value) {
- // NOTE: this is for testing with a single data value, not a series.
- if (value)
- {
- STAssertTrue(state == S_STARTED, @"Init'ed for data (state=%d)", state);
- state = S_RUN;
- } else {
- STAssertTrue(state == S_RUN, @"In run state at EOS (state=%d)", state);
- state = S_EOS;
- }
- params->send(kSecTransformOutputAttributeName, kSecTransformMetaAttributeValue, value);
- return value;
- });
-
- params->send(CFSTR("Stuff"), kSecTransformMetaAttributeRequired, kCFBooleanTrue);
- params->send(CFSTR("Things"), kSecTransformMetaAttributeRequired, kCFBooleanTrue);
-
- params->overrideTransform(kSecTransformActionStartingExecution, ^{
- STAssertTrue(state == S_INITED, @"Inited (state=%d)");
- state = S_STARTED;
- return (CFTypeRef)NULL;
- });
-
- params->overrideTransform(kSecTransformActionFinalize, ^{
- state = S_GONE;
- dispatch_group_leave(leave_on_finalize);
- return (CFTypeRef)NULL;
- });
- };
-
- dispatch_group_enter(leave_on_finalize);
- SecTransformRef tr = custom_transform(name, required_attributes_create_block);
- STAssertNotNil((NSObject *)tr, @"newly created custom transform");
-
- char *data_bytes = (char *)"It was the best of transforms, it was the worst of transforms.";
- CFDataRef data = CFDataCreate(NULL, (const UInt8*)data_bytes, strlen(data_bytes));
- SecTransformSetAttribute(tr, kSecTransformInputAttributeName, data, NULL);
- usleep(100);
- STAssertTrue(state == S_INITED, @"not run yet");
- CFDataRef rdata = (CFDataRef)SecTransformExecute((NSObject *)tr, &error);
-
- STAssertTrue(rdata == NULL, @"Expected no result, but got: %@", rdata);
- STAssertErrorHas((id)error, @"missing required attributes?", @"Error describes condition (%@)", error);
- STAssertErrorHas((id)error, @" Things[ ,)]", @"Missing attributes named (%@)", error);
- STAssertErrorHas((id)error, @" Stuff[ ,)]", @"Missing attributes named (%@)", error);
- STAssertErrorHas((id)error, @"requiresStuffThings", @"Name of erroring Transform in message (%@)", error);
-
- if (error) {
- CFRelease(error);
- }
- CFRelease(tr);
-
- STAssertFalse(dispatch_group_wait(leave_on_finalize, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC)), @"group was ready");
- STAssertTrue(state == S_GONE, @"Transform should be gone, state=%d", state);
-
- dispatch_group_enter(leave_on_finalize);
- state = S_INITED;
- tr = custom_transform(name, required_attributes_create_block);
- STAssertNotNil((NSObject *)tr, @"newly created custom transform");
-
- error = NULL;
- SecTransformSetAttribute(tr, kSecTransformInputAttributeName, data, NULL);
- SecTransformSetAttribute(tr, CFSTR("Things"), CFSTR("grubby things"), NULL);
- SecTransformSetAttribute(tr, CFSTR("Stuff"), CFSTR("Cool stuff"), NULL);
- rdata = (CFDataRef)SecTransformExecute(tr, &error);
-
- STAssertNotNil((NSData *)rdata, @"Got data back");
- STAssertEqualObjects((NSData *)rdata, (NSData *)data, @"Data unchanged");
- STAssertTrue(state == S_EOS, @"Transform hit EOS");
- STAssertTrue(error == NULL, @"Error not set");
-
- CFRelease(tr);
- STAssertFalse(dispatch_group_wait(leave_on_finalize, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC)), @"group was ready");
- STAssertTrue(state == S_GONE, @"Transform gone (state=%d)", state);
- dispatch_group_notify(leave_on_finalize, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
- dispatch_release(leave_on_finalize);
- });
-}
-
-static SecTransformInstanceBlock AttributeNotificationTest(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
-
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, NULL,
- ^(SecTransformStringOrAttributeRef ah, CFTypeRef value)
- {
- SecTransformCustomSetAttribute(ref, CFSTR("Generic"), kSecTransformMetaAttributeValue, kCFBooleanTrue);
- return value;
- });
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("Specific"),
- ^(SecTransformStringOrAttributeRef ah, CFTypeRef value)
- {
- SecTransformCustomSetAttribute(ref, CFSTR("Specific"), kSecTransformMetaAttributeValue, kCFBooleanTrue);
- return value;
-
- });
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("AlsoSpecific"),
- ^(SecTransformStringOrAttributeRef ah, CFTypeRef value)
- {
- SecTransformCustomSetAttribute(ref, CFSTR("AlsoSpecific"), kSecTransformMetaAttributeValue, kCFBooleanTrue);
-
- return value;
- });
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
--(void)testAttributeNotifications
-{
- NSString *name = @"com.apple.security.unit-test.testAttributeNotifications";
- Boolean generic_called = NO;
- Boolean specific_called = NO;
- Boolean also_specific_called = NO;
-
- Boolean ok = SecTransformRegister((CFStringRef)name, &AttributeNotificationTest, NULL);
-
- STAssertTrue(ok, @"Successful register");
-
- SecTransformRef tr = SecTransformCreate((CFStringRef)name, NULL);
-
- CFStringRef aNameStr = ((CFStringRef)name);
- SecTransformSetAttribute(tr, CFSTR("Generic"), aNameStr, NULL);
- SecTransformSetAttribute(tr, CFSTR("Specific"), aNameStr, NULL);
- SecTransformSetAttribute(tr, CFSTR("AlsoSpecific"), aNameStr, NULL);
-
- generic_called = (kCFBooleanTrue == (CFBooleanRef)SecTransformGetAttribute(tr, CFSTR("Generic")));
- specific_called = (kCFBooleanTrue == (CFBooleanRef)SecTransformGetAttribute(tr, CFSTR("Specific")));
- also_specific_called = (kCFBooleanTrue == (CFBooleanRef)SecTransformGetAttribute(tr, CFSTR("AlsoSpecific")));
-
-
- STAssertTrue(generic_called, @"generic called");
- STAssertTrue(specific_called, @"specific called");
- STAssertTrue(also_specific_called, @"also specific called");
-
- CFRelease(tr);
-}
-
--(void)testEncryptAndDecryptTransforms
-{
- NSAutoreleasePool *pool = [NSAutoreleasePool new];
-
- // generate a symmetrical key for testing
- OSStatus err = errSecSuccess;
-
- NSString* algNames[] =
- {
- @"AES 128",
- @"AES 192",
- @"AES 256",
- @"DES",
- @"3DES",
- @"CAST",
- @"RC4"
- };
-
- CSSM_ALGORITHMS symmetricalAlgos[] =
- {
- CSSM_ALGID_AES,
- CSSM_ALGID_AES,
- CSSM_ALGID_AES,
- CSSM_ALGID_DES,
- CSSM_ALGID_3DES_3KEY_EDE,
- CSSM_ALGID_CAST,
- CSSM_ALGID_RC4
- };
-
- uint32 keySizes[] =
- {
- 128,
- 192,
- 256,
- 64,
- 192,
- 40,
- 8
- };
-
- CSSM_KEYUSE keyUse = CSSM_KEYUSE_ANY;
- CSSM_KEYATTR_FLAGS keyAttrFlags = CSSM_KEYATTR_RETURN_DEFAULT;
- SecAccessRef accessRef = NULL;
- CSSM_CC_HANDLE handle = ((CSSM_CC_HANDLE)0);
-
- NSString* dataStr = @"At the round earth's imagined corners blow\
- Your trumpets, angels, and arise, arise\
- From death, you numberless infinities\
- Of souls, and to your scattered bodies go,\
- All whom the flood did, and fire shall, overthrow,\
- All whom war, dearth, age, agues, tyrannies,\
- Despair, law, chance, hath slain, and you whose eyes\
- Shall behold God, and never taste death's woe.\
- But let them sleep, Lord, and me mourn a space,\
- For, if above all these my sins abound,\
- 'Tis late to ask abundance of Thy grace,\
- When we are there. Here on this lowly ground\
- Teach me how to repent; for that's as good\
- As if Thou'dst sealed my pardon, with Thy blood.";
-
- NSData* testData = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
- int numItems = (sizeof(symmetricalAlgos) / sizeof(CSSM_ALGORITHMS));
- int iCnt = 0;
-
- for (iCnt = 0; iCnt < numItems; iCnt++)
- {
- SecKeyRef testKey = NULL;
- CSSM_ALGORITHMS algoToUse = symmetricalAlgos[iCnt];
- uint32 keySizeInBits = keySizes[iCnt];
-
- err = SecKeyGenerate(NULL, algoToUse, keySizeInBits, handle, keyUse, keyAttrFlags, accessRef, &testKey);
- STAssertTrue(err == errSecSuccess, [NSString stringWithFormat:@"Unable to create a symmetrical key %@", algNames[iCnt]]);
- if (errSecSuccess != err)
- {
- continue;
- }
- __block CFErrorRef error = NULL;
-
- SecTransformRef encryptSymRef = NULL;
- encryptSymRef = SecEncryptTransformCreate(testKey, &error);
- if (NULL != error)
- {
- CFRelease(testKey);
- STAssertTrue(NO, [NSString stringWithFormat:@"Unable to create the encrypt transform for key %@", algNames[iCnt]]);
- continue;
- }
-
- SecTransformRef decryptSymRef = SecDecryptTransformCreate(testKey, &error);
- if (NULL != error)
- {
- CFRelease(testKey);
- CFRelease(encryptSymRef);
- STAssertTrue(NO, [NSString stringWithFormat:@"Unable to create the decrypt transform for key %@", algNames[iCnt]]);
- continue;
- }
-
- // connect the output of the encryption to the input of the decryption transform
-
- SecGroupTransformRef group = SecTransformCreateGroupTransform();
- (void)SecTransformConnectTransforms(encryptSymRef, kSecTransformOutputAttributeName,
- decryptSymRef, kSecTransformInputAttributeName,
- group, &error);
- if (NULL != error)
- {
- CFRelease(testKey);
- CFRelease(encryptSymRef);
- CFRelease(decryptSymRef);
- STAssertTrue(NO, [NSString stringWithFormat:@"Unable to connect transforms for key %@", algNames[iCnt]]);
- continue;
- }
-
-
- NSInputStream* dataStream = [NSInputStream inputStreamWithData:testData];
- [dataStream open];
-
- SecTransformSetAttribute(encryptSymRef, kSecTransformInputAttributeName, (CFTypeRef)dataStream, &error);
- if (NULL != error)
- {
- CFRelease(testKey);
- CFRelease(encryptSymRef);
- CFRelease(decryptSymRef);
- STAssertTrue(NO, [NSString stringWithFormat:@"Unable to set the input for key %@", algNames[iCnt]]);
- continue;
- }
-
- CFTypeRef transformResult = SecTransformExecute(encryptSymRef, &error);
- CFRelease(group);
- CFRelease(encryptSymRef);
- CFRelease(decryptSymRef);
-
- if (NULL != error)
- {
- STAssertTrue(NO, [NSString stringWithFormat:@"returned an error for algo %@", algNames[iCnt]]);
- continue;
- CFRelease(error);
- }
-
- if (NULL == transformResult || 0 == [(NSData*)transformResult length])
- {
- STAssertTrue(NO, [NSString stringWithFormat:@"transformResult was NULL or empty for %@", algNames[iCnt]]);
- continue;
- }
-
- NSData* resultData = nil;
- if (CFGetTypeID(transformResult) == CFDataGetTypeID())
- {
- resultData = (NSData*)transformResult;
- [resultData autorelease];
- }
-
- CFRelease(testKey);
-
- STAssertTrue([testData isEqualToData:resultData], @"The output of the decrypt transform does NOT match the original input!");
- }
-
-
- SecKeyRef publicKey = NULL;
- SecKeyRef privateKey = NULL;
-
- keyAttrFlags = CSSM_KEYATTR_RETURN_REF;
-
- const uint32 publicKeyAttributes = CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_RETURN_REF;
- const uint32 privateKeyAttributes = CSSM_KEYATTR_SENSITIVE | CSSM_KEYATTR_RETURN_REF | CSSM_KEYATTR_PERMANENT | CSSM_KEYATTR_EXTRACTABLE;
-
- CSSM_KEYUSE pubKeyUse = CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_WRAP;
- CSSM_KEYUSE privKeyUse = CSSM_KEYUSE_SIGN | CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_UNWRAP;
-
-
- err = SecKeyCreatePair(NULL, CSSM_ALGID_RSA, 2048, ((CSSM_CC_HANDLE)0),
- pubKeyUse, publicKeyAttributes,
- privKeyUse, privateKeyAttributes,
- NULL, &publicKey, &privateKey);
-
- STAssertTrue(errSecSuccess == err, @"Unable to create a key pair");
- if (errSecSuccess != err)
- {
- cssmPerror(NULL, err);
- return;
- }
-
- CFErrorRef error = NULL;
- SecTransformRef encryptSymRef = SecEncryptTransformCreate(publicKey , &error);
- if (NULL != error)
- {
- CFRelease(publicKey);
- CFRelease(privateKey);
- STAssertTrue(NO, [NSString stringWithFormat:@"Unable to create the encrypt transform for key RSA"]);
- return;
- }
-
- SecTransformRef decryptSymRef = SecDecryptTransformCreate(privateKey, &error);
- if (NULL != error)
- {
- CFRelease(publicKey);
- CFRelease(privateKey);
- CFRelease(encryptSymRef);
- STAssertTrue(NO, [NSString stringWithFormat:@"Unable to create the decrypt transform for key RSA"]);
- return;
- }
-
- // connect the output of the encryption to the input of the decryption transform
-
- SecGroupTransformRef group = SecTransformCreateGroupTransform();
- (void)SecTransformConnectTransforms( encryptSymRef, kSecTransformOutputAttributeName,
- decryptSymRef, kSecTransformInputAttributeName,
- group, &error);
- if (NULL != error)
- {
- CFRelease(publicKey);
- CFRelease(privateKey);
- CFRelease(encryptSymRef);
- CFRelease(decryptSymRef);
- STAssertTrue(NO, [NSString stringWithFormat:@"Unable to connect transforms for key RSA"]);
- return;
- }
-
- NSInputStream* dataStream = [NSInputStream inputStreamWithData:testData];
- [dataStream open];
-
- SecTransformSetAttribute(encryptSymRef, kSecTransformInputAttributeName, (CFTypeRef)dataStream, &error);
- if (NULL != error)
- {
- CFRelease(publicKey);
- CFRelease(privateKey);
- CFRelease(encryptSymRef);
- CFRelease(decryptSymRef);
- STAssertTrue(NO, [NSString stringWithFormat:@"Unable to set the input for key RSA"]);
- return;
- }
- CFTypeRef transformResult = SecTransformExecute(encryptSymRef, &error);
- if (NULL != error)
- {
- STAssertTrue(NO, [NSString stringWithFormat:@"returned an error for RSA"]);
- CFRelease(error);
- return;
- }
-
- if (NULL == transformResult || 0 == [(NSData*)transformResult length])
- {
- STAssertTrue(NO, [NSString stringWithFormat:@"transformResult was NULL or empty for RSA"]);
- return;
- }
-
- NSData* resultData = nil;
- if (CFGetTypeID(transformResult) == CFDataGetTypeID())
- {
- resultData = (NSData*)transformResult;
- [resultData autorelease];
- }
-
- CFRelease(publicKey);
- CFRelease(privateKey);
- CFRelease(encryptSymRef);
- CFRelease(decryptSymRef);
-
- STAssertTrue([testData isEqualToData:resultData], @"(RSA)The output of the decrypt transform does NOT match the original input!");
-
- [pool drain];
-}
-
-// NOTE: this test is largely the same as testEncryptAndDecryptTransforms, but
-// we make a single key and use it from many threads at once. This uncovered
-// some locking issues, so makes a good regression test.
--(void)testMultiEncryptWithSameKey {
- // generate a symmetrical key for testing
- CSSM_KEYUSE keyUse = CSSM_KEYUSE_ANY;
- CSSM_KEYATTR_FLAGS keyAttrFlags = CSSM_KEYATTR_RETURN_DEFAULT;
- SecAccessRef accessRef = NULL;
- CSSM_CC_HANDLE handle = ((CSSM_CC_HANDLE)0);
-
- NSString* dataStr = @"Reduce, reuse, recycle. No crashes please.";
- NSData* testData = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
-
- SecKeyRef testKey = NULL;
- {
- OSStatus err;
- err = SecKeyGenerate(NULL, CSSM_ALGID_AES, 256, handle, keyUse, keyAttrFlags, accessRef, &testKey);
- STAssertTrue(err == errSecSuccess, @"Unable to create a symmetrical key err=%x", err);
- }
-
- // The number of iterations is somewhat arbitrary. When we use to have failures they were
- // within 2*#logicalCPUs iterations, but nothing says we won't have a regression that happens
- // outside that window.
- dispatch_apply(128, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t i) {
- __block CFErrorRef error = NULL;
-
- SecTransformRef encryptSymRef = NULL;
- encryptSymRef = SecEncryptTransformCreate(testKey, &error);
- if (NULL != error)
- {
- STFail(@"Unable to create the encrypt transform iteration#%d error=%@", i, error);
- return;
- }
- if (NULL == encryptSymRef) {
- STFail(@"Unable to create the encrypt transform iteration#%d, error=NULL", i);
- return;
- }
-
- SecTransformRef decryptSymRef = SecDecryptTransformCreate(testKey, &error);
- if (NULL != error)
- {
- CFRelease(encryptSymRef);
- STFail(@"Unable to create the decrypt transform iteration#%d error=%@", i, error);
- return;
- }
- if (NULL == decryptSymRef) {
- CFRelease(encryptSymRef);
- STFail(@"Unable to create the decrypt transform iteration#%d, error=NULL", i);
- return;
- }
-
- // connect the output of the encryption to the input of the decryption transform
-
- SecGroupTransformRef group = SecTransformCreateGroupTransform();
- (void)SecTransformConnectTransforms(encryptSymRef, kSecTransformOutputAttributeName,
- decryptSymRef, kSecTransformInputAttributeName,
- group, &error);
- if (NULL != error)
- {
- CFRelease(encryptSymRef);
- CFRelease(decryptSymRef);
- STFail(@"Unable to connect transforms on iteration %d error=%@", i, error);
- return;
- }
-
-
- NSInputStream* dataStream = [NSInputStream inputStreamWithData:testData];
- [dataStream open];
-
- SecTransformSetAttribute(encryptSymRef, kSecTransformInputAttributeName, (CFTypeRef)dataStream, &error);
- if (NULL != error)
- {
- CFRelease(encryptSymRef);
- CFRelease(decryptSymRef);
- STFail(@"Unable to set the input on iteration %d error=%@", i, error);
- return;
- }
-
- CFTypeRef transformResult = SecTransformExecute(encryptSymRef, &error);
- CFRelease(group);
-
- if (NULL != error)
- {
- STFail(@"returned an error on iteration %d error=%@", i, error);
- CFRelease(error);
- return;
- }
-
- if (NULL == transformResult || 0 == [(NSData*)transformResult length])
- {
- STFail(@"transformResult was NULL or empty for iteration %d", i);
- return;
- }
-
- NSData* resultData = nil;
- if (CFGetTypeID(transformResult) == CFDataGetTypeID())
- {
- resultData = (NSData*)transformResult;
- [resultData autorelease];
- }
-
- CFRelease(encryptSymRef);
- CFRelease(decryptSymRef);
-
- STAssertEqualObjects(testData, resultData, @"The output of the decrypt transform does NOT match the original input iteration %d", i);
- });
-
- CFRelease(testKey);
-}
-
-static SecTransformInstanceBlock RoundTripCheck(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- __block CFDataRef remainder = NULL;
- __block SecTransformStringOrAttributeRef ahead = NULL;
- __block int eof_count = 0;
- __block bool drain = false;
-
- SecTransformCustomSetAttribute(ref, CFSTR("INPUT2"), kSecTransformMetaAttributeDeferred, kCFBooleanTrue);
- SecTransformCustomSetAttribute(ref, CFSTR("INPUT2"), kSecTransformMetaAttributeStream, kCFBooleanTrue);
-
- dispatch_block_t not_equal =
- ^{
- // not equal
- SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName, kSecTransformMetaAttributeValue, kCFBooleanFalse);
- SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName, kSecTransformMetaAttributeValue, NULL);
- drain = true;
- };
-
- SecTransformAttributeActionBlock action =
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- if (drain)
- {
- return (CFTypeRef)NULL;
- }
-
- if (ahead == ah)
- {
- SecTransformPushbackAttribute(ref, ah, value);
- }
- else if (value)
- {
- CFDataRef d = (CFDataRef)value;
- if (remainder)
- {
- CFIndex compare_length;
- CFIndex remainder_length = CFDataGetLength(remainder);
- CFIndex d_length = CFDataGetLength(d);
- CFDataRef new_remainder = NULL;
- SecTransformAttributeRef new_ahead = NULL;
-
- if (remainder_length == d_length)
- {
- compare_length = d_length;
- }
- else if (remainder_length < d_length)
- {
- new_remainder = CFDataCreate(NULL, CFDataGetBytePtr(d) + remainder_length, d_length - remainder_length);
- compare_length = remainder_length;
- new_ahead = ah;
- } else
- {
- new_remainder = CFDataCreate(NULL, CFDataGetBytePtr(remainder) + d_length, remainder_length - d_length);
- compare_length = d_length;
- new_ahead = ahead;
- }
-
- if (bcmp(CFDataGetBytePtr(d), CFDataGetBytePtr(remainder), compare_length)) {
- not_equal();
- } else
- {
- // same, keep going
- CFRelease(remainder);
- remainder = new_remainder;
- ahead = new_ahead;
- }
- }
- else
- {
- if (!eof_count)
- {
- ahead = ah;
- remainder = CFDataCreateCopy(NULL, d);
- }
- else
- {
- if (CFDataGetLength(d))
- {
- not_equal();
- }
- }
- }
- }
- else
- { // EOF case
- ahead = NULL;
- if (++eof_count == 2)
- {
- if (remainder)
- {
- SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName,
- kSecTransformMetaAttributeValue,
- CFDataGetLength(remainder) ? kCFBooleanFalse : kCFBooleanTrue);
-
- CFRelease(remainder);
- }
- else
- {
- SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName,
- kSecTransformMetaAttributeValue, kCFBooleanTrue);
- }
-
- SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName,
- kSecTransformMetaAttributeValue, NULL);
- }
- }
-
- return (CFTypeRef)NULL;
- };
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("INPUT2"), action);
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, kSecTransformInputAttributeName, action);
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
-static BOOL RoundTrip(CFStringRef fname, SecTransformRef in, SecTransformRef out, BOOL share)
-{
- static dispatch_once_t once;
- CFStringRef name = CFSTR("com.apple.examples.cmp");
- // concepts: pushback, SecTransformSetAttributeAction vs. ProcessData, ah==, & send value to output
-
- dispatch_once(&once,
- ^{
- SecTransformRegister(name, &RoundTripCheck, NULL);
- });
-
- SecTransformRef cmp = SecTransformCreate(name, NULL);
- SecTransformRef group = SecTransformCreateGroupTransform();
- CFErrorRef err = NULL;
- SecTransformConnectTransforms(in, kSecTransformOutputAttributeName, out, kSecTransformInputAttributeName, group, NULL);
- SecTransformConnectTransforms(out, kSecTransformOutputAttributeName, cmp, kSecTransformInputAttributeName, group, NULL);
- NSInputStream *is = [NSInputStream inputStreamWithFileAtPath:(NSString *)fname];
- // XXX: failure to do this seem to crash SecTransformExecute when it releases the error, track down & fix or file radar
- [is open];
-
- NSInputStream *is2 = nil;
-
- if (share)
- {
- SecTransformRef tee = SecNullTransformCreate();
- SecTransformConnectTransforms(tee, kSecTransformOutputAttributeName, in, kSecTransformInputAttributeName, group, NULL);
- SecTransformConnectTransforms(tee, kSecTransformOutputAttributeName, cmp, CFSTR("INPUT2"), group, NULL);
- SecTransformSetAttribute(tee, kSecTransformInputAttributeName, (CFTypeRef)is, NULL);
- CFRelease(tee);
- } else {
- is2 = [NSInputStream inputStreamWithFileAtPath:(NSString *)fname];
- [is2 open];
- SecTransformSetAttribute(in, kSecTransformInputAttributeName, (CFTypeRef)is, &err);
- SecTransformSetAttribute(cmp, CFSTR("INPUT2"), (CFTypeRef)is2, &err);
- }
-
- assert(err == NULL);
- CFTypeRef r = SecTransformExecute(group, &err);
-
- if (err)
- {
- CFRelease(err);
- }
-
- CFRelease(group);
- CFRelease(cmp);
-
- if (is2)
- {
- [is2 close];
- }
-
- if (is)
- {
- [is close];
- }
-
- if (r)
- {
- return r == kCFBooleanTrue;
- }
- else
- {
- CFfprintf(stderr, "round trip error: %@", err);
- return NO;
- }
-}
-
-static SecTransformInstanceBlock LineLengthCheck(CFStringRef name, SecTransformRef newTransform, SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock = ^{
- CFErrorRef result = NULL;
- __block int bytesPastLastEOL = 0;
- __block int max = 0;
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("MAX"), ^(SecTransformAttributeRef ah, CFTypeRef value) {
- CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &max);
- return value;
- });
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, kSecTransformInputAttributeName, ^(SecTransformAttributeRef ah, CFTypeRef value) {
- if (NULL != value) {
- CFDataRef d = (CFDataRef)value;
- CFIndex len = CFDataGetLength(d);
- const UInt8 *bytes = CFDataGetBytePtr(d);
-
- for(int i = 0; i < len; i++) {
- if (bytes[i] == '\n') {
- bytesPastLastEOL = 0;
- } else {
- bytesPastLastEOL++;
- if (bytesPastLastEOL > max) {
- SecTransformCustomSetAttribute(ref, kSecTransformAbortAttributeName, kSecTransformMetaAttributeValue, CreateSecTransformErrorRef(kSecTransformErrorInvalidInput, "MAX line length of %d exceeded", max));
- break;
- }
- }
- }
- }
- SecTransformCustomSetAttribute(ref, kSecTransformOutputAttributeName, kSecTransformMetaAttributeValue, value);
- return value;
- });
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
--(void)testLargeChunkEncode
-{
- NSError *err = NULL;
- NSData *d = [NSData dataWithContentsOfFile:@"/usr/share/dict/web2a" options:NSDataReadingMapped error: &err];
- STAssertNil(err, @"dataWithContentsOfFile %@", err);
- CFStringRef types[] = {kSecZLibEncoding, kSecBase64Encoding, kSecBase32Encoding, NULL};
-
- dispatch_group_t dg = dispatch_group_create();
-
- CFStringRef lengthCheckName = CFSTR("com.apple.security.unit-test.lineLengthCheck");
- SecTransformRegister(lengthCheckName, LineLengthCheck, (CFErrorRef *)&err);
- STAssertNil(err, @"Expected to register %@", lengthCheckName);
-
- for(int i = 0; types[i]; i++) {
- int max_j = 80;
- CFStringRef etype = types[i];
-
- void (^trial)(NSString *testName, id lineLength, int maxLineLength) = ^(NSString *testName, id lineLength, int maxLineLength) {
- SecGroupTransformRef group = SecTransformCreateGroupTransform();
-
- SecTransformRef et = SecEncodeTransformCreate(etype, (CFErrorRef *)&err);
- SecTransformRef dt = SecDecodeTransformCreate(etype, (CFErrorRef *)&err);
-
- SecTransformRef lineLengthChecker = (etype == kSecZLibEncoding) ? SecNullTransformCreate() : SecTransformCreate(lengthCheckName, NULL);
- STAssertNotNil((id)lineLengthChecker, @"Expected to create line length checker");
- SecTransformSetAttribute(lineLengthChecker, CFSTR("MAX"), [NSNumber numberWithInt:maxLineLength], NULL);
-
- SecTransformConnectTransforms(et, kSecTransformOutputAttributeName, lineLengthChecker, kSecTransformInputAttributeName, group, (CFErrorRef *)&err);
- SecTransformConnectTransforms(lineLengthChecker, kSecTransformOutputAttributeName, dt, kSecTransformInputAttributeName, group, (CFErrorRef *)&err);
-
- SecTransformSetAttribute(et, kSecTransformInputAttributeName, (CFDataRef)d, (CFErrorRef *)&err);
- SecTransformSetAttribute(et, kSecEncodeLineLengthAttribute, lineLength, (CFErrorRef *)&err);
- SecTransformSetAttribute(et, CFSTR("NAME"), (CFStringRef)testName, (CFErrorRef *)&err);
-
- dispatch_group_async(dg, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- CFDataRef result = (CFDataRef)SecTransformExecute(group, (CFErrorRef *)&err);
-
- STAssertNil(err, @"execute for %@ got %@", testName, err);
- STAssertNotNil((id)result, @"No result from execute of %@", testName);
-
- if (result) {
- STAssertEqualObjects(d, (id)result, @"test %@ failed", testName);
- }
- });
- };
-
- for(int j = max_j; j > 70; --j) {
- if (etype == kSecZLibEncoding && j != max_j) {
- break;
- }
- trial([NSString stringWithFormat:@"%@-%d", etype, j], [NSNumber numberWithInt:j], j);
- }
-
- if (etype != kSecZLibEncoding) {
- trial([NSString stringWithFormat:@"%@-LL64", etype], (id)kSecLineLength64, 64);
- trial([NSString stringWithFormat:@"%@-LL76", etype], (id)kSecLineLength76, 76);
- }
- }
-
- dispatch_group_wait(dg, DISPATCH_TIME_FOREVER);
-}
-
--(void)testZLib {
- SecTransformRef et = SecEncodeTransformCreate(kSecZLibEncoding, NULL);
- SecTransformRef dt = SecDecodeTransformCreate(kSecZLibEncoding, NULL);
-
- // using a tee would require >10 buffered items (we need to buffer about 64K), so we pass share=NO
- STAssertTrue(RoundTrip((CFStringRef)@"/usr/share/dict/web2a", et, dt, NO), @"Roundtrip /usr/share/dict/web2a");
-
- CFRelease(et);
- CFRelease(dt);
-
- /*
- If we want this we need a 'new' custom transform that will get receive the ratio data and be able to
- query that data.
-
- CFNumberRef r1 = (CFNumberRef)SecTransformGetAttribute(et, kSecCompressionRatio);
- CFNumberRef r2 = (CFNumberRef)SecTransformGetAttribute(dt, kSecCompressionRatio);
-
- STAssertNotNil((NSNumber *)r1, @"encode ratio");
- STAssertNotNil((NSNumber *)r2, @"decode ratio");
- STAssertEqualObjects((NSNumber *)r1, (NSNumber *)r2, @"same ratios");
- */
-}
-
-static SecTransformInstanceBlock CycleCheckTest(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- int zero = 0;
- __block CFNumberRef feedback = CFNumberCreate(NULL, kCFNumberIntType, &zero);
-
- SecTransformCustomSetAttribute(ref, CFSTR("FEEDBACK"), kSecTransformMetaAttributeCanCycle, kCFBooleanTrue);
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("INPUT"),
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- if (value == NULL) {
- SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeValue, value);
- return value;
- }
- if (feedback == NULL) {
- SecTransformPushbackAttribute(ref, ah, value);
- return (CFTypeRef)NULL;
- }
-
- int x, y;
- CFNumberGetValue((CFNumberRef)value, kCFNumberIntType, &x);
- CFNumberGetValue(feedback, kCFNumberIntType, &y);
- x ^= y;
- CFNumberRef res = CFNumberCreate(NULL, kCFNumberIntType, &x);
- SecTransformCustomSetAttribute(ref, CFSTR("OUTPUT"), kSecTransformMetaAttributeValue, res);
- CFRelease(res);
- CFRelease(feedback);
- feedback = NULL;
- return (CFTypeRef)NULL;
- });
-
- SecTransformSetAttributeAction(ref, kSecTransformActionAttributeNotification, CFSTR("FEEDBACK"),
- ^(SecTransformAttributeRef ah, CFTypeRef value)
- {
- if (value) {
- if (feedback) {
- SecTransformPushbackAttribute(ref, ah, value);
- } else {
- feedback = (CFNumberRef)CFRetain(value);
- }
- }
-
- return (CFTypeRef)NULL;
- });
-
- return result;
-
- };
-
- return Block_copy(instanceBlock);
-}
-
--(void)testCycleCheck {
-
- SecTransformRef cat = SecNullTransformCreate();
- SecTransformRef group = SecTransformCreateGroupTransform();
- CFErrorRef err = NULL;
-
- CFStringRef name = CFSTR("com.apple.examples.unit-test.loop-test");
-
- SecTransformRegister(name, &CycleCheckTest, NULL);
-
- SecTransformRef twenty = count_transform(20);
-
- // this is getting an internal error, but it's being ignored.
- SecTransformRef xxor = SecTransformCreate(name, &err);
-
- SecTransformConnectTransforms(xxor, CFSTR("OUTPUT"), cat, CFSTR("INPUT"), group, &err);
- STAssertNil((id)err, @"xor->cat");
- SecTransformConnectTransforms(xxor, CFSTR("OUTPUT"), xxor, CFSTR("FEEDBACK"), group, &err);
- STAssertNil((id)err, @"xor->xor");
- SecTransformConnectTransforms(twenty, CFSTR("OUTPUT"), xxor, CFSTR("INPUT"), group, &err);
- STAssertNil((id)err, @"twenty->xor");
-
- //SecTransformSetAttribute(xxor, CFSTR("DEBUG"), kCFBooleanTrue, &err);
-
- CFTypeRef r = SecTransformExecute(group, &err);
- STAssertNil((id)err, @"execute err=%@", err);
- STAssertNotNil((id)r, @"no results from execute");
-
- if (r) {
- CFNumberRef z = (CFNumberRef)[NSNumber numberWithInt:0];
- CFIndex n = CFArrayGetCountOfValue((CFArrayRef)r, CFRangeMake(0, CFArrayGetCount((CFArrayRef)r)), z);
- // There should be six zeros in the xor->feedback chain from 0 to 19.
- STAssertEquals(n, (CFIndex) 6, @"There should be six zeros in %@", r);
- }
-
- CFRelease(r);
- CFRelease(group);
- CFRelease(twenty);
- CFRelease(xxor);
- CFRelease(cat);
-}
-
--(void)testValidate {
- SecTransformRef group = SecTransformCreateGroupTransform();
- CFErrorRef err = NULL;
-
- CFStringRef data_or_null_name = CFSTR("com.apple.examples.unit-test.data-or-null");
- SecTransformCreateBlock data_or_null = ^(CFStringRef name, SecTransformRef new_transform, const SecTransformCreateBlockParameters *params) {
- params->overrideAttribute(kSecTransformActionAttributeValidation, CFSTR("INPUT"), SecTransformCreateValidatorForCFtype(CFDataGetTypeID(), YES));
- };
-
-
- SecTransformRef makes_numbers = count_transform(20);
- SecTransformRef wants_data = custom_transform(data_or_null_name, data_or_null);
-
- SecTransformConnectTransforms(makes_numbers, CFSTR("OUTPUT"), wants_data, CFSTR("INPUT"), group, NULL);
- STAssertNil((id)err, @"unexpected connect error: %@", err);
- CFTypeRef r = SecTransformExecute(group, &err);
- STAssertNil((id)r, @"Got non-null result (%@) when expecting null!", r);
- STAssertNotNil((id)err, @"Expected an error!", err);
- STAssertErrorHas((id)err, @"/INPUT", @"Error indicated attribute that was set incorrectly");
- STAssertErrorHas((id)err, @" type CFNumber", @"Error indicated provided type");
- STAssertErrorHas((id)err, @" a CFData", @"Error indicated required type");
-
- if (err) {
- CFRelease(err);
- }
- err = NULL;
- CFRelease(wants_data);
-
- wants_data = custom_transform(data_or_null_name, data_or_null);
-
- char raw_data[] = "`Twas brillig, and the slithy toves / Did gyre and gimble in the wabe: / All mimsy were the borogoves, / And the mome raths outgrabe.";
- CFDataRef the_data = CFDataCreate(NULL, (UInt8*)raw_data, strlen(raw_data));
- SecTransformSetAttribute(wants_data, kSecTransformInputAttributeName, the_data, &err);
- CFRelease(the_data);
-
- STAssertNil((id)err, @"unexpected set error: %@", err);
- r = SecTransformExecute(wants_data, &err);
- STAssertNotNil((id)r, @"Expected a result, got error: %@", err);
- if (r) {
- STAssertEqualObjects((id)the_data, (id)r, @"Invalid result");
- }
-
- CFStringRef numbers_only_name = CFSTR("com.apple.examples.unit-test.numbers-only");
- SecTransformCreateBlock numbers_only = ^(CFStringRef name, SecTransformRef new_transform, const SecTransformCreateBlockParameters *params) {
- params->overrideAttribute(kSecTransformActionAttributeValidation, CFSTR("INPUT"), SecTransformCreateValidatorForCFtype(CFNumberGetTypeID(), NO));
- };
-
- CFRelease(group);
- CFRelease(makes_numbers);
- CFRelease(wants_data);
-
- group = SecTransformCreateGroupTransform();
- makes_numbers = count_transform(20);
- SecTransformRef wants_numbers = custom_transform(numbers_only_name, numbers_only);
-
- SecTransformConnectTransforms(makes_numbers, CFSTR("OUTPUT"), wants_numbers, CFSTR("INPUT"), group, NULL);
- STAssertNil((id)err, @"unexpected connect error: %@", err);
- r = SecTransformExecute(group, &err);
- CFfprintf(stderr, "r=%@; err=%@\n", r, err);
- STAssertNil((id)r, @"Got non-null result (%@) when expecting null!", r);
- STAssertNotNil((id)err, @"Expected an error!", err);
- STAssertErrorHas((id)err, @"/INPUT", @"Error indicated attribute that was set incorrectly");
- STAssertErrorHas((id)err, @"received NULL value", @"Error indicated provided value is NULL");
- STAssertErrorHas((id)err, @" a CFNumber", @"Error indicated required type");
-
- CFRelease(err);
- CFRelease(group);
- CFRelease(makes_numbers);
- CFRelease(wants_numbers);
-}
-
--(void)testCodeBase32 {
- struct base32_test_vector {
- const char *plain_text;
- const char *base32_rfc4648;
- const char *base32_fde;
- };
-
- // RFC 4648 test vectors
- static base32_test_vector base32_test_vectors[] = {
- {"", "", ""},
- {"f", "MY======", "MY======"},
- {"fo", "MZXQ====", "MZXQ===="},
- {"foo", "MZXW6===", "MZXW6==="},
- {"foob", "MZXW6YQ=", "MZXW6YQ="},
- {"fooba", "MZXW6YTB", "MZXW6YTB"},
- {"foobar", "MZXW6YTBOI======", "MZXW6YTBO8======"}};
-
- void (^test)(NSString *test_name, SecTransformRef transform, const char *input, const char *expected_output, NSString *error_format) =
- ^(NSString *test_name, SecTransformRef transform, const char *input, const char *expected_output, NSString *error_format)
- {
- if (!transform) {
- STFail(@"No transform for %@", test_name);
- return;
- }
-
- CFErrorRef err = NULL;
- NSData *input_data = [NSData dataWithBytes:input length:strlen(input)];
- NSData *expected_output_data = [NSData dataWithBytes:expected_output length:strlen(expected_output)];
- SecTransformSetAttribute(transform, kSecTransformInputAttributeName, input_data, &err);
- STAssertNil((NSError *)err, @"unexpected error %@ from SecTransformSetAttribute for %@", err, test_name);
- NSData *output_data = (NSData *)SecTransformExecute(transform, &err);
- [output_data autorelease];
- STAssertNil((NSError *)err, @"Error from %@ execute (in=%s, err=%s)", test_name, input, err);
- STAssertNotNil(output_data, @"Unexpected nil output from %@ execute (in=%s)", test_name, input);
- if (output_data) {
- NSString *output_string = [NSString alloc];
- output_string = [output_string initWithBytes:[output_data bytes] length:[output_data length] encoding:NSMacOSRomanStringEncoding];
- [output_string autorelease];
- NSString *msg = [NSString stringWithFormat:error_format, input, expected_output, output_string];
- STAssertEqualObjects(expected_output_data, output_data, @"%@ %@", test_name, msg);
- }
- CFRelease(transform);
- };
-
- for(int idx = 0; idx < sizeof(base32_test_vectors)/sizeof(*base32_test_vectors); idx++)
- {
- SecTransformRef base32encoder = SecEncodeTransformCreate(kSecBase32Encoding, NULL);
- test(@"base32 encode", base32encoder, base32_test_vectors[idx].plain_text, base32_test_vectors[idx].base32_rfc4648, @"B32(\"%1$s\") should be \"%2$s\", got \"%3$@\"");
-
- SecTransformRef base32decoder = SecDecodeTransformCreate(kSecBase32Encoding, NULL);
- test(@"base32 decode", base32decoder, base32_test_vectors[idx].base32_rfc4648, base32_test_vectors[idx].plain_text, @"B32dec(\"%1$s\") should be \"%2$s\", got \"%3$@\"");
-
- SecTransformRef base32FDEencoder = SecEncodeTransformCreate(CFSTR("base32FDE"), NULL);
- test(@"base32FDE encode", base32FDEencoder, base32_test_vectors[idx].plain_text, base32_test_vectors[idx].base32_fde, @"B32(\"%1$s\") should be \"%2$s\", got \"%3$@\"");
-
- SecTransformRef base32FDEdecoder = SecDecodeTransformCreate(CFSTR("base32FDE"), NULL);
- test(@"base32FDE decode", base32FDEdecoder, base32_test_vectors[idx].base32_fde, base32_test_vectors[idx].plain_text, @"B32dec(\"%1$s\") should be \"%2$s\", got \"%3$@\"");
- }
-
- SecTransformRef bet = SecEncodeTransformCreate(kSecBase32Encoding, NULL);
- STAssertNotNil((id)bet, @"got bulk base 32 encoder");
- SecTransformRef bdt = SecDecodeTransformCreate(kSecBase32Encoding, NULL);
- STAssertNotNil((id)bdt, @"got bulk base 32 decoder");
- STAssertTrue(RoundTrip((CFStringRef)@"/usr/share/dict/words", bet, bdt, YES), @"Roundtrip base32 /usr/share/dict/words");
-
- CFRelease(bet);
- CFRelease(bdt);
-
- // FDE uses a modified base32 alphabet, we want to test it here.
- SecTransformRef FDE_encode_transform = SecEncodeTransformCreate(@"base32FDE", NULL);
- STAssertNotNil((id)FDE_encode_transform, @"got FDE encoder");
- SecTransformRef FDE_decode_transform = SecDecodeTransformCreate(@"base32FDE", NULL);
- STAssertNotNil((id)FDE_decode_transform, @"got bulk base 32 decoder");
- STAssertTrue(RoundTrip((CFStringRef)@"/usr/share/dict/words", FDE_encode_transform, FDE_decode_transform, YES), @"Roundtrip base32FDE /usr/share/dict/words");
-
- CFRelease(FDE_encode_transform);
- CFRelease(FDE_decode_transform);
-}
-
--(void)testCodeBase64 {
- CFErrorRef error = NULL;
-
-#if 0
- SecTransformRef tr = SecDecodeTransformCreate(@"Not a real encoding", &error);
- // XXX: known failure in Transform::SetAttribute 7707822 -- I would fix on this branch, but I think that code has diverged
- STAssertTrue(tr == NULL, @"Checks for invalid encodings");
- NSLog(@"Error: %@", error);
-#endif
-
- SecTransformRef dt = SecDecodeTransformCreate(kSecBase64Encoding, NULL);
- STAssertNotNil((id)dt, @"Got decoder");
-
- const char raw_data0[] = "Tm90IHV1ZW5jb2RlZAo=";
- const char raw_data1[] = "Not uuencoded\n";
- CFDataRef data0 = CFDataCreate(NULL, (const UInt8*)raw_data0, strlen(raw_data0));
- CFDataRef data1 = CFDataCreate(NULL, (const UInt8*)raw_data1, strlen(raw_data1));
- SecTransformSetAttribute(dt, kSecTransformInputAttributeName, data0, NULL);
-
- CFDataRef decoded_data = (CFDataRef)SecTransformExecute(dt, &error);
- STAssertNotNil((NSData *)decoded_data, @"Got a decode result");
- STAssertEqualObjects((NSData *)decoded_data, (NSData *)data1, @"Proper decode results");
-
- SecTransformRef et = SecEncodeTransformCreate(kSecBase64Encoding, NULL);
- STAssertNotNil((id)et, @"Got encoder");
-
- SecTransformSetAttribute(et, kSecTransformInputAttributeName, data1, NULL);
-
- CFDataRef encoded_data = (CFDataRef)SecTransformExecute(et, NULL);
- STAssertNotNil((NSData *)encoded_data, @"Got an encode result");
-
- STAssertEqualObjects((NSData *)encoded_data, (NSData *)data0, @"Proper encode results");
-
- // Negative testing, assume the following struct
- // struct __CFData {
- // CFRuntimeBase _base;
- // CFIndex _length; /* number of bytes */
- // CFIndex _capacity; /* maximum number of bytes */
- // CFAllocatorRef _bytesDeallocator; /* used only for immutable; if NULL, no deallocation */
- // uint8_t *_bytes; /* compaction: direct access to _bytes is only valid when data is not inline */
- // };
- SecTransformRef et_neg = SecEncodeTransformCreate(kSecBase64Encoding, NULL);
- STAssertNotNil((id)et_neg, @"Got encoder for negative testing");
-
- CFIndex *data1_length=(CFIndex*)((unsigned char *)data1 + sizeof(CFRuntimeBase));
- CFIndex data1_backup=*data1_length;
- if (sizeof(CFIndex)==8)
- {
- *data1_length=0x5ffffffffffffff7;
- }
- else if (sizeof(CFIndex)==4)
- {
- *data1_length=0x5ffffff7;
- }
- else
- {
- STAssertTrue(false, @"Test error, representation of CFIndex not supported. Sizeof(CFIndex)=%d. Only support 4 or 8",sizeof(CFIndex));
- }
- STAssertTrue(CFDataGetLength(data1)==*data1_length, @"Length not properly set - test bug - reads %lu expect %lu",CFDataGetLength(data1),*data1_length);
- SecTransformSetAttribute(et_neg, kSecTransformInputAttributeName, data1, NULL);
- CFDataRef encoded_data2 = (CFDataRef)SecTransformExecute(et_neg, &error);
- STAssertNil((id)encoded_data2, @"No encoded data for negative testing");
- STAssertNotNil((id)error, @"Got error for negative testing");
- *data1_length=data1_backup;
- if (error!=NULL)
- {
- STAssertTrue((CFErrorGetCode(error)==kSecTransformErrorInvalidLength),
- @"Error for invalid length, got %lu expect %lu",CFErrorGetCode(error),kSecTransformErrorInvalidLength);
- }
- // XXX also for general testing we want a "RandomChunkSizer" that copies INPUT to OUTPUT, but makes random size chunks (incl 0) as it goes.
-
- SecTransformRef dt2 = SecDecodeTransformCreate(kSecBase64Encoding, NULL);
- SecTransformRef et2 = SecEncodeTransformCreate(kSecBase64Encoding, NULL);
- int ll = 75;
- SecTransformSetAttribute(et2, kSecEncodeLineLengthAttribute, CFNumberCreate(NULL, kCFNumberIntType, &ll), NULL);
-
- STAssertTrue(RoundTrip((CFStringRef)@"/usr/share/dict/words", et2, dt2, YES), @"Roundtrip base64 /usr/share/dict/words");
-
- CFRelease(et2);
- CFRelease(dt2);
- CFRelease(et);
- CFRelease(et_neg);
- CFRelease(dt);
-}
-
-static SecTransformInstanceBlock ErrorResultsTest(CFStringRef name,
- SecTransformRef newTransform,
- SecTransformImplementationRef ref)
-{
- SecTransformInstanceBlock instanceBlock =
- ^{
- CFErrorRef result = NULL;
- SecTransformSetDataAction(ref, kSecTransformActionProcessData,
- ^(CFTypeRef value)
- {
- if (value != NULL)
- {
- return (CFTypeRef)CFErrorCreate(NULL, CFSTR("expected error"), 42, NULL);
- }
- else
- {
- return SecTransformNoData();
- }
- });
-
- return result;
- };
-
- return Block_copy(instanceBlock);
-}
-
-
--(void)testErrorResults {
- CFStringRef name = CFSTR("com.apple.security.unit-test.error-results");
- SecTransformRegister(name, &ErrorResultsTest, NULL);
-
- SecTransformRef tr = SecTransformCreate(name, NULL);
- CFDataRef data = CFDataCreate(NULL, NULL, 0);
- SecTransformSetAttribute(tr, kSecTransformInputAttributeName, data, NULL);
-
- CFErrorRef err = NULL;
- CFTypeRef no_result = SecTransformExecute(tr, &err);
-
- STAssertErrorHas((id)err, @"expected error", @"Signaled error has original string");
- STAssertErrorHas((id)err, @"42", @"Signaled error has original error code");
- STAssertNil((id)no_result, @"No result from erroring transform");
- CFRelease(data);
- CFRelease(tr);
- CFRelease(err);
-}
-
--(void)testErrorExecutesInRightQueue {
- // testExecuteBlock checks to see if blocks are generally executed on the proper queue, this specifically checks
- // for an error while starting (which was originally improperly coded).
-
- SecTransformRef unassigned_input = SecNullTransformCreate();
- dispatch_queue_t q = dispatch_queue_create("com.apple.unit-test.ErrorExecutesInRightQueue", NULL);
- dispatch_group_t got_final = dispatch_group_create();
- dispatch_group_enter(got_final);
- __block bool saw_data = false;
- __block bool saw_error = false;
-
- SecTransformExecuteAsync(unassigned_input, q, ^(CFTypeRef message, CFErrorRef error, Boolean isFinal) {
- STAssertEquals(q, const_cast<const dispatch_queue_t>(dispatch_get_current_queue()), @"Should be running on %p, but is running on %p", q, dispatch_get_current_queue());
- saw_data = saw_data || (message != NULL);
- saw_error = saw_error || (error != NULL);
- if (isFinal) {
- dispatch_group_leave(got_final);
- }
- });
-
- STAssertFalse(dispatch_group_wait(got_final, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC)), @"Execute completed");
- STAssertFalse(saw_data, @"Should have seen no data (but did)");
- STAssertTrue(saw_error, @"Should have seen error (but didn't)");
-
- CFRelease(unassigned_input);
- dispatch_group_notify(got_final, q, ^{
- dispatch_release(got_final);
- dispatch_release(q);
- });
-
-}
-
--(void)testSignVerify {
- unsigned char *raw_message = (unsigned char *)"Controlling complexity is the essence of computer programming. - Brian Kernigan";
- dispatch_group_t dg = dispatch_group_create();
- CFErrorRef err = NULL;
- CFDataRef message = CFDataCreate(NULL, raw_message, strlen((const char *)raw_message));
- __block SecKeyRef rsa_pub_key = NULL;
- __block SecKeyRef rsa_priv_key = NULL;
- __block SecKeyRef ecdsa_pub_key = NULL;
- __block SecKeyRef ecdsa_priv_key = NULL;
- __block SecKeyRef dsa_pub_key = NULL;
- __block SecKeyRef dsa_priv_key = NULL;
-
- char *tmp_dir;
- asprintf(&tmp_dir, "%s/sign-verify-test-keychain-", getenv("TMPDIR") ? getenv("TMPDIR") : "/tmp");
-
- unsigned char *raw_bad_message = (unsigned char *)"Standards are great, there are so many to choose from - Andrew S. Tanenbaum (maybe)";
- CFDataRef bad_message = CFDataCreate(NULL, raw_bad_message, strlen((const char *)raw_bad_message));
-
- // when safe replace with a concurrent queue
- dispatch_queue_t key_q = dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
-
- dispatch_group_async(dg, key_q,
- ^{
- NSAutoreleasePool *pool = [NSAutoreleasePool new];
-
- // (note the key must be bigger then a SHA2-256 signature plus the DER.1 packing of the OID, so 1024 was chosen for that, not speed or safety)
- NSDictionary *key_opts = [NSDictionary dictionaryWithObjectsAndKeys:
- (NSString *)kSecAttrKeyTypeRSA, (NSString *)kSecAttrKeyType,
- [NSNumber numberWithInt:1024], (NSString *)kSecAttrKeySizeInBits,
- @"RSA transform unit test key", (NSString *)kSecAttrLabel,
- nil];
- OSStatus gp_status = SecKeyGeneratePair((CFDictionaryRef)key_opts, &rsa_pub_key, &rsa_priv_key);
- STAssertTrue(gp_status == 0, @"RSA (gp_status=0x%x)", gp_status);
- [pool drain];
- });
-
- dispatch_group_async(dg, key_q,
- ^{
- OSStatus gp_status;
-#if 0
- // I don't know how "safe" a 512 bit ECDSA key is, but again this is just for testing, not for signing any real data
- NSDictionary *key_opts = [NSDictionary dictionaryWithObjectsAndKeys:
- (NSString *)kSecAttrKeyTypeECDSA, (NSString *)kSecAttrKeyType,
- [NSNumber numberWithInt:512], (NSString *)kSecAttrKeySizeInBits,
- @"ECDSA transform unit test key", (NSString *)kSecAttrLabel,
- nil];
- gp_status = SecKeyGeneratePair((CFDictionaryRef)key_opts, &ecdsa_pub_key, &ecdsa_priv_key);
-#else
- {
- SecKeychainRef tmp_keychain = NULL;
- gp_status = SecKeyCreatePair(tmp_keychain, CSSM_ALGID_ECDSA, 256, NULL,
- CSSM_KEYUSE_VERIFY,
- CSSM_KEYATTR_EXTRACTABLE|CSSM_KEYATTR_PERMANENT,
- CSSM_KEYUSE_SIGN,
- CSSM_KEYATTR_EXTRACTABLE|CSSM_KEYATTR_PERMANENT,
- NULL, &ecdsa_pub_key, &ecdsa_priv_key);
- }
-#endif
- if (gp_status)
- {
- STAssertTrue(gp_status == 0, @"ECDSA (gp_status=0x%x)", gp_status);
- }
- });
-
- dispatch_group_async(dg, key_q,
- ^{
- OSStatus gp_status;
-#if 0
- // I don't know how "safe" a 1024 bit DSA key is, but again this is just for testing, not for signing any real data
- NSDictionary *key_opts = [NSDictionary dictionaryWithObjectsAndKeys:(NSString *)kSecAttrKeyTypeDSA,
- (NSString *)kSecAttrKeyType, [NSNumber numberWithInt:512], (NSString *)kSecAttrKeySizeInBits, nil];
- gp_status = SecKeyGeneratePair((CFDictionaryRef)key_opts, &ecdsa_pub_key, &ecdsa_priv_key);
-#else
- {
- const char *passwd = "this is not secret";
- SecKeychainRef tmp_keychain = NULL;
- char *kcfname;
- asprintf(&kcfname, "%s-DSA-XXXXXXXXXX", tmp_dir);
- // NOTE: "mktemp" isn't as safe as you might think...but this is test code and doesn't have to be, but
- // if you copy it elsewhere you may well need to rewrite it. (use mkstemp)
- mktemp(kcfname);
- gp_status = SecKeychainCreate(kcfname, (UInt32) strlen(passwd), passwd, NO, NULL, &tmp_keychain);
- STAssertTrue(gp_status == 0, @"SecKeychainCreate (gp_status=0x%x)", gp_status);
- gp_status = SecKeyCreatePair(tmp_keychain, CSSM_ALGID_DSA, 512, NULL,
- CSSM_KEYUSE_VERIFY|CSSM_KEYUSE_ENCRYPT|CSSM_KEYUSE_WRAP,
- CSSM_KEYATTR_EXTRACTABLE|CSSM_KEYATTR_PERMANENT|CSSM_KEYATTR_RETURN_REF,
- CSSM_KEYUSE_SIGN|CSSM_KEYUSE_DECRYPT|CSSM_KEYUSE_UNWRAP,
- CSSM_KEYATTR_EXTRACTABLE|CSSM_KEYATTR_PERMANENT|CSSM_KEYATTR_RETURN_REF,
- NULL, &dsa_pub_key, &dsa_priv_key);
- free(kcfname);
- }
-#endif
- STAssertTrue(gp_status == 0, @"DSA (gp_status=0x%x)", gp_status);
- });
-
- struct sv_test {
- NSString *name;
- SecKeyRef pub_key, priv_key;
- CFDataRef msg_sign, msg_verify;
- CFTypeRef dalgo_sign, dalgo_verify;
- int dlen_sign, dlen_verify;
- BOOL pass;
- };
-
- dispatch_group_wait(dg, DISPATCH_TIME_FOREVER);
-
- struct sv_test sv_tests[] =
- {
- {@"Basic RSA", rsa_pub_key, rsa_priv_key, message, message, NULL, NULL, 0, 0, YES},
- {@"Basic RSA (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, NULL, NULL, 0, 0, NO},
- {@"RSA, mismatched digest algos", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA1, 0, 0, NO},
-
- {@"RSA SHA1 MD5", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA1, kSecDigestSHA1, 0, 0, YES},
- {@"RSA SHA1 MD5 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestSHA1, kSecDigestSHA1, 0, 0, NO},
-
- {@"RSA MD5", rsa_pub_key, rsa_priv_key, message, message, kSecDigestMD5, kSecDigestMD5, 0, 0, YES},
- {@"RSA MD5 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestMD5, kSecDigestMD5, 0, 0, NO},
-
- {@"RSA MD2", rsa_pub_key, rsa_priv_key, message, message, kSecDigestMD2, kSecDigestMD2, 0, 0, YES},
- {@"RSA MD2 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestMD2, kSecDigestMD2, 0, 0, NO},
-
- {@"RSA SHA2 512", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 512, 512, YES},
- {@"RSA SHA2 512 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 512, 512, NO},
- {@"RSA SHA2 512 vs. 384", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 512, 384, NO},
-
- {@"RSA SHA2 384", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 384, 384, YES},
- {@"RSA SHA2 384 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 384, 384, NO},
-
- {@"RSA SHA2 256", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 256, 256, YES},
- {@"RSA SHA2 256 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 256, 256, NO},
-
- {@"RSA SHA2 224", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 224, 224, YES},
- {@"RSA SHA2 224 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 224, 224, NO},
-
- {@"RSA SHA2 0", rsa_pub_key, rsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 0, 0, YES},
- {@"RSA SHA2 0 (tampered data)", rsa_pub_key, rsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 0, 0, NO},
-
- {@"Basic ECDSA", ecdsa_pub_key, ecdsa_priv_key, message, message, NULL, NULL, 0, 0, YES},
- {@"Basic ECDSA (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, NULL, NULL, 0, 0, NO},
- {@"ECDSA (mismatched digest algos)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA1, 0, 0, NO},
-
- {@"ECDSA SHA1", ecdsa_pub_key, ecdsa_priv_key, message, message, kSecDigestSHA1, kSecDigestSHA1, 0, 0, YES},
- {@"ECDSA SHA1 (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA1, kSecDigestSHA1, 0, 0, NO},
-
- {@"ECDSA SHA2 224", ecdsa_pub_key, ecdsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 224, 224, YES},
- {@"ECDSA SHA2 224 (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 224, 224, NO},
-
- {@"ECDSA SHA2 256", ecdsa_pub_key, ecdsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 256, 256, YES},
- {@"ECDSA SHA2 256 (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 256, 256, NO},
-
- {@"ECDSA SHA2 384", ecdsa_pub_key, ecdsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 384, 384, YES},
- {@"ECDSA SHA2 384 (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 384, 384, NO},
-
- {@"ECDSA SHA2 512", ecdsa_pub_key, ecdsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 512, 512, YES},
- {@"ECDSA SHA2 512 (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 512, 512, NO},
-
- {@"ECDSA SHA2 0", ecdsa_pub_key, ecdsa_priv_key, message, message, kSecDigestSHA2, kSecDigestSHA2, 0, 0, YES},
- {@"ECDSA SHA2 0 (tampered data)", ecdsa_pub_key, ecdsa_priv_key, message, bad_message, kSecDigestSHA2, kSecDigestSHA2, 0, 0, NO},
-
- {@"Basic DSA", dsa_pub_key, dsa_priv_key, message, message, NULL, NULL, 0, 0, YES},
- {@"Basic DSA (tampered data)", dsa_pub_key, dsa_priv_key, message, bad_message, NULL, NULL, 0, 0, NO},
- // only SHA1 is supported, so no mismatched digest algo test is available
-
- {@"DSA SHA1", dsa_pub_key, dsa_priv_key, message, message, kSecDigestSHA1, kSecDigestSHA1, 0, 0, YES},
- {@"DSA SHA1 (tampered data)", dsa_pub_key, dsa_priv_key, message, bad_message, kSecDigestSHA1, kSecDigestSHA1, 0, 0, NO},
- };
-
- free(tmp_dir);
-
- int i;
- for(i = 0; i < sizeof(sv_tests)/sizeof(sv_test); i++)
- {
- CFStringRef input_cases[] = {kSecInputIsPlainText, kSecInputIsDigest};
- //CFStringRef input_cases[] = {kSecInputIsPlainText, kSecInputIsDigest, kSecInputIsRaw};
- const int ilim = sizeof(input_cases)/sizeof(input_cases[0]);
- int ii = 0, ij = 0;
- for(; ii < ilim; ++ii)
- {
- for(ij = 0; ij < ilim; ++ij)
- {
- err = NULL;
- struct sv_test *tst = sv_tests + i;
- NSString *tname = [NSString stringWithFormat:@"%@ %@ %@", tst->name, input_cases[ii], input_cases[ij]];
-
- CFStringRef sign_input_is = input_cases[ii];
- CFStringRef verify_input_is = input_cases[ij];
-
- if (sign_input_is != kSecInputIsPlainText && tst->dalgo_sign == NULL) {
- continue;
- }
- if (verify_input_is != kSecInputIsPlainText && tst->dalgo_verify == NULL) {
- continue;
- }
-
- if ((sign_input_is == kSecInputIsRaw || verify_input_is == kSecInputIsRaw) && [tst->name rangeOfString:@"RSA"].location == NSNotFound) {
- // we can only synthesize these tests for RSA
- NSLog(@"No %@ test", tname);
- continue;
- }
-
- STAssertNotNil((id)tst->pub_key, @"Have pub_key for %@", tname);
- STAssertNotNil((id)tst->priv_key, @"Have priv_key for %@", tname);
-
- if (tst->pub_key == nil || tst->priv_key == nil) {
- continue;
- }
-
- SecTransformRef sign = SecSignTransformCreate(tst->priv_key, &err);
- STAssertNil((NSError *)err, @"creating sign for %@", tname);
- STAssertNotNil((id)sign, @"Creating sign for %@", tname);
-
- if (sign == NULL) {
- continue;
- }
-
- SecTransformRef verify = SecVerifyTransformCreate(tst->pub_key, NULL, &err);
- STAssertNotNil((id)verify, @"Creating verify for %@", tname);
- STAssertNil((NSError *)err, @"Creating verify for %@", tname);
-
- if (verify == NULL) {
- continue;
- }
-
- SecTransformRef sign_digest = NULL;
- SecTransformRef verify_digest = NULL;
- SecTransformRef sign2 = NULL;
-
- if (tst->dalgo_sign)
- {
- SecTransformSetAttribute(sign, kSecDigestTypeAttribute, tst->dalgo_sign, &err);
- STAssertNil((NSError *)err, @"Setting sign's digest type for %@", tname);
- SecTransformSetAttribute(sign, kSecDigestLengthAttribute, [NSNumber numberWithInt:tst->dlen_sign], &err);
- STAssertNil((NSError *)err, @"Setting sign's digest length for %@", tname);
-
- if (sign_input_is == kSecInputIsDigest)
- {
- sign_digest = SecDigestTransformCreate(tst->dalgo_sign, tst->dlen_sign, &err);
- STAssertNotNil((id)sign_digest, @"Create sign's %@-%d digest transform (for %@)", tst->dalgo_sign, tst->dlen_sign, tname);
- STAssertNil((NSError *)err, @"Making sign's digester (for %@) - err=%@", tname, err);
-
- SecTransformSetAttribute(sign, kSecInputIsAttributeName, sign_input_is, &err);
- STAssertNil((NSError *)err, @"Setting sign's InputIs (for %@) - err=%@", tname, err);
- }
- }
-
- if (tst->dalgo_verify) {
- SecTransformSetAttribute(verify, kSecDigestTypeAttribute, tst->dalgo_verify, &err);
- STAssertNil((NSError *)err, @"Setting verify's digest type for %@", tname);
- SecTransformSetAttribute(verify, kSecDigestLengthAttribute, [NSNumber numberWithInt:tst->dlen_verify], &err);
- STAssertNil((NSError *)err, @"Setting verify's digest length for %@", tname);
-
- if (verify_input_is == kSecInputIsDigest) {
- verify_digest = SecDigestTransformCreate(tst->dalgo_verify, tst->dlen_verify, &err);
- STAssertNotNil((id)verify_digest, @"Create verify's %@-%d digest transform (for %@)", tst->dalgo_verify, tst->dlen_verify, tname);
- STAssertNil((NSError *)err, @"Making verify's digester (for %@) - err=%@", tname, err);
-
- SecTransformSetAttribute(verify, kSecInputIsAttributeName, verify_input_is, &err);
- STAssertNil((NSError *)err, @"Setting verify's InputIs (for %@) - err=%@", tname, err);
- }
- }
-
- SecGroupTransformRef group = SecTransformCreateGroupTransform();
- SecTransformSetAttribute(sign_digest ? sign_digest : sign, kSecTransformInputAttributeName, tst->msg_sign, (CFErrorRef *)&err);
- if (sign_digest) {
- STAssertNil((NSError *)err, @"Setting sign's digest's input for %@", tname);
- SecTransformConnectTransforms(sign_digest, kSecTransformOutputAttributeName,
- sign, kSecTransformInputAttributeName, group, NULL);
- } else {
- STAssertNil((NSError *)err, @"Setting sign's input for %@", tname);
- }
-
-
- SecTransformSetAttribute(verify_digest ? verify_digest : verify, kSecTransformInputAttributeName, tst->msg_verify, (CFErrorRef *)&err);
- if (verify_digest) {
- STAssertNil((NSError *)err, @"Setting verify's digest's input for %@", tname);
- SecTransformConnectTransforms(verify_digest, kSecTransformOutputAttributeName,
- verify, kSecTransformInputAttributeName, group, NULL);
- } else {
- STAssertNil((NSError *)err, @"Setting verify's input for %@", tname);
- }
-
- SecTransformConnectTransforms(sign2 ? sign2 : sign, kSecTransformOutputAttributeName, verify, kSecSignatureAttributeName, group, NULL);
-
- dispatch_group_enter(dg);
- dispatch_queue_t temp_q = dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
- SecTransformExecuteAsync(sign, temp_q,
- ^(CFTypeRef message, CFErrorRef error, Boolean isFinal)
- {
- if (message)
- {
- if (tst->pass)
- {
- STAssertTrue(message == kCFBooleanTrue, @"Failed to verify proper signature %@; message = %@", tname, message);
- } else
- {
- STAssertTrue(message == kCFBooleanFalse, @"Failed to detect tampering %@; message = %@", tname, message);
- }
- }
-
- STAssertNil((NSError *)err, @"Executed ok for %@ (err=%@)", tname, error);
-
- if (isFinal)
- {
- dispatch_group_leave(dg);
- }
- });
-
- CFRelease(sign);
- CFRelease(verify);
- CFRelease(group);
- }
- }
- }
-
- struct raw_test {
- SecKeyRef pub, priv;
- NSString *name;
- } raw_tests[] = {
- {rsa_pub_key, rsa_priv_key, @"RSA raw test"},
- {dsa_pub_key, dsa_priv_key, @"DSA raw test"},
- {ecdsa_pub_key, ecdsa_priv_key, @"ECDSA raw test"},
- };
-
- for(i = 0; i < sizeof(raw_tests)/sizeof(raw_tests[0]); ++i) {
- raw_test *t = raw_tests + i;
- SecTransformRef tee = SecNullTransformCreate();
- const char *raw_bytes = "some bytes";
- CFDataRef bytes = CFDataCreate(NULL, (UInt8*)raw_bytes, strlen(raw_bytes));
- CFErrorRef err = NULL;
-
- SecTransformRef sign = SecSignTransformCreate(t->priv, &err);
- STAssertNil((id)err, @"%@ test sign create err=%@", t->name, err);
-
- SecTransformRef verify = SecVerifyTransformCreate(t->pub, NULL, &err);
- STAssertNil((id)err, @"%@ test verify create err=%@", t->name, err);
-
- SecGroupTransformRef group = SecTransformCreateGroupTransform();
- SecTransformConnectTransforms(sign, kSecTransformOutputAttributeName, verify, kSecSignatureAttributeName, group, &err);
- SecTransformConnectTransforms(tee, kSecTransformOutputAttributeName, sign, kSecTransformInputAttributeName, group, &err);
- SecTransformConnectTransforms(tee, kSecTransformOutputAttributeName, verify, kSecTransformInputAttributeName, group, &err);
- SecTransformSetAttribute(tee, kSecTransformInputAttributeName, bytes, &err);
- STAssertNil((id)err, @"%@ setup error=%@", t->name, err);
- CFRetain(group);
- dispatch_group_async(dg, dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- CFErrorRef xerr = NULL;
- CFTypeRef result = SecTransformExecute(group, &xerr);
- CFRelease(group);
-
- if (result) {
- STAssertTrue(result == kCFBooleanTrue, @"%@ sign result=%@", t->name, result);
- } else {
- STFail(@"%@ no result", t->name);
- }
- STAssertNil((id)err, @"%@ execute error=%@", t->name, xerr);
- });
- CFRelease(group);
- }
-
- // Test some things we want to fail for:
-
- SecTransformRef tee = SecNullTransformCreate();
- SecTransformSetAttribute(tee, kSecTransformInputAttributeName, message, NULL);
- SecTransformRef vrfy = SecVerifyTransformCreate(ecdsa_pub_key, NULL, NULL);
-
- SecGroupTransformRef group = SecTransformCreateGroupTransform();
- SecTransformConnectTransforms(tee, kSecTransformOutputAttributeName, vrfy, kSecSignatureAttributeName, group, NULL);
- SecTransformSetAttribute(vrfy, kSecDigestTypeAttribute, CFSTR("No such type"), NULL);
- SecTransformSetAttribute(vrfy, kSecTransformInputAttributeName, message, NULL);
- err = NULL;
- CFTypeRef no_result = SecTransformExecute(group, (CFErrorRef*)&err);
- CFRelease(group);
-
- STAssertNil((id)no_result, @"No result from nonexistent digest");
- STAssertErrorHas((id)err, @"[Ii]nvalid digest algorithm", @"Error message describes nature of error (%@)", err);
- STAssertErrorHas((id)err, @"ECDSA signature", @"Error is not overly general (%@)", err);
- STAssertErrorHas((id)err, @"ECDSA signature", @"Error is not overly general (%@)", err);
- STAssertErrorHas((id)err, @"SHA1.*SHA2", @"Error describes valid algorithms (%@)", err);
- CFRelease(vrfy);
-
- // It would be awesome if we supported all the digests, and this test went away.
- vrfy = SecVerifyTransformCreate(dsa_pub_key, message, NULL);
- tee = SecNullTransformCreate();
-
- group = SecTransformCreateGroupTransform();
- SecTransformConnectTransforms(vrfy, kSecSignatureAttributeName, tee, kSecTransformOutputAttributeName, group, NULL);
- SecTransformConnectTransforms(tee, kSecTransformOutputAttributeName, vrfy, kSecTransformInputAttributeName, group, NULL);
- SecTransformSetAttribute(vrfy, kSecDigestTypeAttribute, kSecDigestSHA2, NULL);
- SecTransformSetAttribute(tee, kSecTransformInputAttributeName, message, NULL);
- err = NULL;
- no_result = SecTransformExecute(group, (CFErrorRef*)&err);
- CFRelease(group);
-
- STAssertNil((id)no_result, @"No result from invalid digest");
- STAssertErrorHas((id)err, @"[Ii]nvalid digest algorithm", @"Error message gives problem statement (%@)", err);
- STAssertErrorHas((id)err, @"[^A-Z]DSA signature", @"Error is not overly general (%@)", err);
- STAssertErrorHas((id)err, @"SHA1", @"Correct algorithm is named (%@)", err);
-
- dispatch_group_wait(dg, DISPATCH_TIME_FOREVER);
-}
-
-static BOOL keyWithBytes(CFDataRef keyData, SecKeyRef* key, CFTypeRef keyClass) {
- CFErrorRef errorRef=NULL;
- CFMutableDictionaryRef parameters;
- parameters = CFDictionaryCreateMutable(kCFAllocatorDefault, 10, NULL, NULL);
-
- /*
- kSecAttrKeyClass values:
- kSecAttrKeyClassPublic
- kSecAttrKeyClassPrivate
- kSecAttrKeyClassSymmetric
- */
- CFDictionaryAddValue(parameters, kSecAttrKeyClass, keyClass);
- CFDictionaryAddValue(parameters, kSecAttrIsPermanent, kCFBooleanFalse); /* also means we have raw bits */
- CFDictionaryAddValue(parameters, kSecAttrKeyType, kSecAttrKeyTypeRSA); /* also means we have raw bits */
- *key = SecKeyCreateFromData(parameters, keyData, &errorRef);
- CFRelease(parameters);
- return (key != NULL);
-}
-
--(void)testVerifyWithKeyFromBytes {
- /*
- static const uint8_t original_pubKeyData[] =
- {
- 0x30, 0x48, 0x02, 0x41, 0x00, 0xd1, 0x4d, 0x1c, 0xe6, 0xbd, 0xd6, 0x8c, 0x4b, 0x77, 0x1e, 0x9f,
- 0xbc, 0xe1, 0xf6, 0x96, 0xf2, 0x55, 0xa2, 0xdc, 0x28, 0x36, 0x39, 0xf4, 0xec, 0x5b, 0x85, 0x9b,
- 0x3c, 0x7f, 0x98, 0xe0, 0xed, 0x49, 0xf5, 0x44, 0xb1, 0x87, 0xa8, 0xf6, 0x7f, 0x55, 0xc0, 0x39,
- 0xf0, 0xe7, 0xcc, 0x9c, 0x84, 0xde, 0x7d, 0x9a, 0x87, 0x38, 0xf2, 0x4b, 0x11, 0x6f, 0x63, 0x90,
- 0xfc, 0x72, 0x2c, 0x86, 0xa3, 0x02, 0x03, 0x01, 0x00, 0x01
- }; */
-
- // openssl genrsa -out /tmp/rsa512.pem
- // openssl rsa -inform PEM -in /tmp/rsa512.pem -outform DER -out /tmp/rsa512.der
- // hexdump -C /tmp/rsa512.der | cut -c10-58 | tr -s ' ' ' ' | sed -e 's/ /, 0x/g' -e 's/$/,/' | cut -c3-|pbcopy
- static const uint8_t pubKeyData[] = {
- 0x30, 0x5c, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
- 0x00, 0x03, 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xbf, 0xd5, 0xce, 0x43, 0x59, 0xd5, 0xf8,
- 0x41, 0xb2, 0xe1, 0x16, 0x02, 0x2a, 0x16, 0xcb, 0xef, 0x49, 0xea, 0x98, 0x71, 0xf8, 0xfb, 0x94,
- 0x23, 0x12, 0xf7, 0xbc, 0x80, 0xd0, 0x8b, 0xfd, 0x29, 0xb8, 0xfc, 0x2c, 0x3d, 0x13, 0x6f, 0x37,
- 0xef, 0xa7, 0x1e, 0xf9, 0x4c, 0x3d, 0x38, 0x3a, 0x2f, 0x6b, 0xa8, 0x16, 0x00, 0x27, 0x5a, 0xbe,
- 0x3d, 0x61, 0xdd, 0x18, 0x45, 0x22, 0xdb, 0x1a, 0xff, 0x02, 0x03, 0x01, 0x00, 0x01,
- };
- static const uint8_t signatureData[] =
- {
- 0xbc, 0x76, 0x2a, 0x50, 0x4e, 0x17, 0x0b, 0xa9, 0x31, 0x3b, 0xc5, 0xb0, 0x4d, 0x2a, 0x01, 0x9a,
- 0xbb, 0x5e, 0x7b, 0x6e, 0x90, 0x2f, 0xaf, 0x3f, 0x40, 0xdb, 0xb0, 0xfc, 0x49, 0xcf, 0xbb, 0xb6,
- 0x08, 0xf0, 0xbb, 0x04, 0x5f, 0x89, 0x0b, 0x10, 0x47, 0x06, 0x93, 0xb3, 0xb7, 0x0b, 0x4e, 0x17,
- 0xe9, 0xb1, 0x55, 0x94, 0x63, 0x30, 0x0b, 0xa3, 0xb1, 0x28, 0xba, 0xe8, 0xef, 0xb4, 0xbd, 0xc5
- };
-
- const char *raw_data = "Data to verify";
- CFDataRef data = CFDataCreate(NULL, (UInt8*) raw_data, strlen(raw_data));
-
- SecKeyRef key;
- CFDataRef cfkeybytes;
- CFErrorRef error;
- cfkeybytes = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, pubKeyData, sizeof(pubKeyData),kCFAllocatorNull);
-
- if(keyWithBytes(cfkeybytes, &key, kSecAttrKeyClassPublic)){
- CFDataRef signature = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, signatureData, sizeof(signatureData),kCFAllocatorNull);
- SecTransformRef vt = SecVerifyTransformCreate(key,signature,&error);
- SecTransformSetAttribute(vt, kSecTransformDebugAttributeName, @"YES", NULL);
- SecTransformSetAttribute(vt, kSecTransformInputAttributeName, data, &error);
- CFBooleanRef signature_ok = (CFBooleanRef) SecTransformExecute(vt, &error);
-
- CFRelease(vt);
- CFRelease(key);
- CFRelease(signature);
- CFRelease(data);
- CFRelease(cfkeybytes);
-
- NSLog(@"STE result %@, err=%@", signature_ok, error);
- STAssertNil((id)error, @"Error from SecTransformExecute: %@", error);
- } else {
- STFail(@"Can't get SecKeyCreateFromData to work");
- }
-}
-
--(void)testAESAndCastKeysFromBytes {
- CFErrorRef err = NULL;
- struct tcase {
- const char *name;
- CFTypeRef key_type;
- NSData *key_data;
- };
- const char *aes_kbytes = "0123456789012345";
- const char *cast_kbytes = "01234567";
-
- struct tcase cases[] = {
- {"AES", kSecAttrKeyTypeAES, [NSData dataWithBytes:aes_kbytes length:strlen(aes_kbytes)]},
- {"CAST", kSecAttrKeyTypeCAST, [NSData dataWithBytes:cast_kbytes length:strlen(cast_kbytes)]},
- };
-
- int i;
- for(i = 0; i < sizeof(cases)/sizeof(cases[0]); ++i) {
- NSDictionary *parm = [NSDictionary dictionaryWithObjectsAndKeys:
- (id)kSecAttrKeyClassSymmetric, kSecAttrKeyClass,
- (id)cases[i].key_type, kSecAttrKeyType,
- (id)kCFBooleanFalse, kSecAttrIsPermanent,
- NULL];
-
- SecKeyRef k = SecKeyCreateFromData((CFDictionaryRef)parm, (CFDataRef)cases[i].key_data, (CFErrorRef *)&err);
- STAssertNotNil((id)k, @"%s SecKeyCreateFromData didn't", cases[i].name);
- STAssertNil((id)err, @"%s SecKeyCreateFromData err=%@", err);
-
- SecTransformRef et = SecEncryptTransformCreate(k, &err);
- STAssertNotNil((id)et, @"No %s EncryptTransform created", cases[i].name);
- STAssertNil((id)err, @"Error from %s SecEncryptTransformCreate err=%@", cases[i].name, err);
-
- SecTransformRef dt = SecDecryptTransformCreate(k, &err);
- STAssertNotNil((id)dt, @"No %s DecryptTransform created", cases[i].name);
- STAssertNil((id)err, @"Error from %s SecDecryptTransformCreate err=%@", cases[i].name, err);
-
- if (k) {
- BOOL rt_ok = RoundTrip(CFSTR("/usr/share/dict/propernames"), et, dt, YES);
- CFRelease(et);
- CFRelease(dt);
- STAssertTrue(rt_ok, @"%s's round trip", cases[i].name);
- }
- }
-}
-
--(void)testDispatchAsumptions {
- // Failures here don't directly indicate we have a bug. It would indicate that
- // either dispatch has one, or that we rely on something dispatch never promised
- // and has changed.
-
- dispatch_semaphore_t pre_sem = dispatch_semaphore_create(0);
- dispatch_semaphore_t post_sem = dispatch_semaphore_create(0);
- __block bool pre_wait_works = false;
-
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.1 * NSEC_PER_SEC), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
- STAssertTrue(0 == dispatch_semaphore_wait(pre_sem, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC)), @"semaphore signal prior to wait pre-wakes");
- pre_wait_works = true;
- dispatch_semaphore_signal(post_sem);
- });
- dispatch_semaphore_signal(pre_sem);
- STAssertTrue(0 == dispatch_semaphore_wait(post_sem, dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC)), @"signal after wait wakes");
- STAssertTrue(pre_wait_works, @"pre-wait worked");
-
-
-}
-
-// Build a group containing 3 subgroups, G1 which has 2 encoders, G2 and G3 which have one
-// decoder each. Exports and attributes are hooked up so execution results in a CFData
-// with the same contents as input_data. "self" is used by the STAssert macros.
-// The various transforms are assigned names: G1, G2, G3, E64, EZLIB, DZLIB, D64.
-static SecTransformRef build_nested_groups(id self, CFDataRef input_data) {
- SecGroupTransformRef outer = SecTransformCreateGroupTransform();
- SecGroupTransformRef g1 = SecTransformCreateGroupTransform();
- SecGroupTransformRef g2 = SecTransformCreateGroupTransform();
- SecGroupTransformRef g3 = SecTransformCreateGroupTransform();
-
- CFErrorRef err = NULL;
-
- SecTransformSetAttribute(outer, kSecTransformTransformName, CFSTR("OUTER"), &err);
- STAssertNil((id)err, @"Can't set outer's name: %@", err);
- SecTransformSetAttribute(g1, kSecTransformTransformName, CFSTR("G1"), &err);
- STAssertNil((id)err, @"Can't set g1's name: %@", err);
- SecTransformSetAttribute(g2, kSecTransformTransformName, CFSTR("G2"), &err);
- STAssertNil((id)err, @"Can't set g2's name: %@", err);
- SecTransformSetAttribute(g3, kSecTransformTransformName, CFSTR("G3"), &err);
- STAssertNil((id)err, @"Can't set g3's name: %@", err);
-
- SecTransformRef e64 = SecEncodeTransformCreate(kSecBase64Encoding, &err);
- STAssertNil((id)err, @"Expected err to be nil, got: %@", err);
- STAssertNotNil((id)e64, @"Could not make Encode64 transform");
- SecTransformSetAttribute(e64, kSecTransformTransformName, CFSTR("E64"), NULL);
- SecTransformRef ezlib = SecEncodeTransformCreate(kSecZLibEncoding, &err);
- STAssertNil((id)err, @"Expected err to be nil, got: %@", err);
- STAssertNotNil((id)ezlib, @"Could not make Encode ZLib transform");
- SecTransformSetAttribute(ezlib, kSecTransformTransformName, CFSTR("EZLIB"), NULL);
-
- SecTransformConnectTransforms(e64, kSecTransformOutputAttributeName, ezlib, kSecTransformInputAttributeName, g1, &err);
- STAssertNil((id)err, @"Can't connect e64 to ezlib: %@", err);
- SecTransformConnectTransforms(g1, kSecTransformInputAttributeName, e64, kSecTransformInputAttributeName, g1, &err);
- STAssertNil((id)err, @"Can't connect g1's input to e64's input: %@", err);
- SecTransformConnectTransforms(ezlib, kSecTransformOutputAttributeName, g1, kSecTransformOutputAttributeName, g1, &err);
- STAssertNil((id)err, @"Can't connect ezlib's output to g1's output: %@", err);
-
- SecTransformRef dzlib = SecDecodeTransformCreate(kSecZLibEncoding, &err);
- STAssertNil((id)err, @"Expected err to be nil, got: %@", err);
- STAssertNotNil((id)dzlib, @"Could not make Decode ZLib transform");
- SecTransformSetAttribute(dzlib, kSecTransformTransformName, CFSTR("dzlib"), NULL);
- SecTransformRef d64 = SecDecodeTransformCreate(kSecBase64Encoding, &err);
- STAssertNil((id)err, @"Expected err to be nil, got: %@", err);
- STAssertNotNil((id)d64, @"Could not make Decode64 transform");
- SecTransformSetAttribute(dzlib, kSecTransformTransformName, CFSTR("D64"), NULL);
-
- // putting just one transform in g2 and g3
- SecTransformConnectTransforms(g2, kSecTransformInputAttributeName, dzlib, kSecTransformInputAttributeName, g2, &err);
- STAssertNil((id)err, @"Can't connect g2's input to dzlib's input: %@", err);
- SecTransformConnectTransforms(dzlib, kSecTransformOutputAttributeName, g2, kSecTransformOutputAttributeName, g2, &err);
- STAssertNil((id)err, @"Can't connect dzlib's output to g2's output: %@", err);
-
- SecTransformConnectTransforms(g3, kSecTransformInputAttributeName, d64, kSecTransformInputAttributeName, g3, &err);
- STAssertNil((id)err, @"Can't connect g2's input to d64's input: %@", err);
- SecTransformConnectTransforms(d64, kSecTransformOutputAttributeName, g3, kSecTransformOutputAttributeName, g3, &err);
- STAssertNil((id)err, @"Can't connect d64's output to g2's output: %@", err);
-
- SecTransformConnectTransforms(g1, kSecTransformOutputAttributeName, g2, kSecTransformInputAttributeName, outer, &err);
- STAssertNil((id)err, @"Can't connect g1 to g2 (dzlib): %@", err);
- SecTransformConnectTransforms(g2, kSecTransformOutputAttributeName, g3, kSecTransformInputAttributeName, outer, &err);
- STAssertNil((id)err, @"Can't connect g2 (dzlib) to g3 (d64): %@", err);
-
- SecTransformSetAttribute(g1, kSecTransformInputAttributeName, input_data, &err);
- STAssertNil((id)err, @"Can't set g1's input: %@", err);
-
-
- CFRelease(e64);
- CFRelease(ezlib);
- CFRelease(dzlib);
- CFRelease(d64);
- CFRelease(g1);
- CFRelease(g2);
- CFRelease(g3);
- return outer;
-}
-
--(void)testGroupsInGroups {
- UInt8 original_bytes[] = "'Twas brillig and the...was that smiley toads? Something with chives? Aw heck!";
- CFDataRef original = CFDataCreate(NULL, original_bytes, sizeof(original_bytes));
-
- // Test executing the top group, a sub group, and a non-group member.
- for (NSString *name in [NSArray arrayWithObjects:@"OUTER", @"G1", @"D64", nil]) {
- CFErrorRef err = NULL;
- SecGroupTransformRef outer = build_nested_groups(self, original);
- SecTransformRef start_at = SecTransformFindByName(outer, (CFStringRef)name);
- STAssertNotNil((id)start_at, @"Expected to find %@", name);
-
- CFDataRef output = (CFDataRef)SecTransformExecute(start_at, &err);
- STAssertNil((id)err, @"Can't execute directly created nested transform starting at %@: %@", start_at, err);
- STAssertEqualObjects((id)output, (id)original, @"Output and original should match (started at %@)", start_at);
- CFRelease(outer);
- if (err) {
- CFRelease(err);
- }
- }
-
- {
- SecGroupTransformRef bad_outer = build_nested_groups(self, original);
- SecTransformRef d64 = SecTransformFindByName(bad_outer, CFSTR("D64"));
- STAssertNotNil((id)d64, @"Expected to find d64");
- CFErrorRef err = NULL;
- // d64 is in a group in bad_outer, we set things up to fail
- // and later expect execute to fail because of it.
- SecTransformSetAttribute(d64, kSecDecodeTypeAttribute, CFSTR("NOT valid"), &err);
- if (err) {
- // It can fail right away
- ErrorHas((NSError*)err, @"Unsupported decode type");
- } else {
- // Or later (see below)
- STAssertNil((id)err, @"Expected to set decode type: %@", err);
- }
-
- SecTransformRef e64 = SecTransformFindByName(bad_outer, CFSTR("E64"));
- STAssertNotNil((id)e64, @"Expected to find e64");
- CFStringRef any = CFSTR("ANY");
- // e64 and d64 aren't in the same groups, but they are in outer.
- // There should be no way to (directly) connect them, so try all
- // 4 groups and make sure none work.
- for (NSString *group_name in [NSArray arrayWithObjects:@"OUTER", @"G1", @"G2", @"G3", nil]) {
- SecTransformRef connect_in = SecTransformFindByName(bad_outer, (CFStringRef)group_name);
- STAssertNotNil((id)connect_in, @"Expected to find %@", group_name);
- err = NULL;
- SecTransformConnectTransforms(d64, any, e64, any, bad_outer, &err);
- STAssertNotNil((id)err, @"Expected error on cross group connect (in %@)", group_name);
- if (err) {
- STAssertEquals(CFErrorGetCode(err), (CFIndex)kSecTransformErrorInvalidConnection, @"error code (in %@)", group_name);
- STAssertEqualObjects((id)CFErrorGetDomain(err), (id)kSecTransformErrorDomain, @"error domain (in %@)", group_name);
- CFRelease(err);
- err = NULL;
- }
-
- // While we are here, make sure we can't set a non-exported group attribute
- SecTransformSetAttribute((SecTransformRef)connect_in, CFSTR("nobody-exports-me"), CFSTR("VALUE"), &err);
- STAssertNotNil((id)err, @"Expected an error setting a non-exported attribute on %@", connect_in);
- // Make sure this is the error we expect, not something unrelated to our transgression
- ErrorHas((NSError*)err, @"non-exported attribute");
- // Error should have the name of the offending attribute
- ErrorHas((NSError*)err, @"nobody-exports-me");
- if (err) {
- CFRelease(err);
- err = NULL;
- }
- }
-
- CFTypeRef no_result = SecTransformExecute(bad_outer, &err);
- STAssertNotNil((id)err, @"Expected error");
- ErrorHas((NSError*)err, @"Unsupported decode type");
- STAssertNil((id)no_result, @"Expected no result, got: %@", no_result);
- CFRelease(bad_outer);
-
- // Make sure we can't connect to or from non-exported group attributes
- bad_outer = build_nested_groups(self, original);
- STAssertNotNil((id)bad_outer, @"Expected to build nested transform");
- SecTransformRef g1 = SecTransformFindByName(bad_outer, CFSTR("G1"));
- STAssertNotNil((id)g1, @"Expected to find g1");
- SecTransformRef appendix = SecNullTransformCreate();
- SecTransformConnectTransforms(appendix, kSecTransformOutputAttributeName, g1, CFSTR("NONE"), bad_outer, &err);
- STAssertNotNil((id)err, @"Expected to fail connecting appendix to g1, but didn't");
- ErrorHas((NSError*)err, @"non-exported attribute");
- if (err) {
- CFRelease(err);
- err = NULL;
- }
- SecTransformConnectTransforms(g1, CFSTR("DOES_NOT_EXIST"), appendix, kSecTransformInputAttributeName, bad_outer, &err);
- STAssertNotNil((id)err, @"Expected to fail connecting g1 to appendix, but didn't");
- ErrorHas((NSError*)err, @"non-exported attribute");
- if (err) {
- CFRelease(err);
- err = NULL;
- }
-
- CFRelease(bad_outer);
- CFRelease(appendix);
- }
-}
-
-// 10080968 covers this case. It isn't a regression (it was impossible to create nested groups
-// until recently), but it needs to be addressed before we ship.
--(void)disabledUntilPR_10080968_testExternalizeGroupsInGroups {
- CFErrorRef err = NULL;
- UInt8 original_bytes[] = "Sic Semper Tyrannosaurus!";
- CFDataRef original = CFDataCreate(NULL, original_bytes, sizeof(original_bytes));
-
- SecGroupTransformRef outer = build_nested_groups(self, original);
- NSLog(@"outer=%@", SecTransformDotForDebugging(outer));
- SecTransformRef d64 = SecTransformFindByName(outer, CFSTR("D64"));
- STAssertNotNil((id)d64, @"Expected to find d64");
-
- CFDictionaryRef freezeDriedNestedGroups = SecTransformCopyExternalRepresentation(d64);
- STAssertNotNil((id)freezeDriedNestedGroups, @"Expected to externalize group");
-
- SecTransformRef outer2 = SecTransformCreateFromExternalRepresentation(freezeDriedNestedGroups, &err);
- STAssertNil((id)err, @"Can't create nested group err: %@", err);
- STAssertNotNil((id)outer2, @"Expected transform fron xrep: %@", freezeDriedNestedGroups);
- NSLog(@"outer2=%@", SecTransformDotForDebugging(outer2));
-
- CFTypeRef output2 = SecTransformExecute(outer2, &err);
- STAssertNil((id)err, @"Can't execute outer2: %@", err);
- STAssertEqualObjects((id)output2, (id)original, @"Output2 and original should match");
-}
-
-static NSString *CopyLeakLine()
-{
- static char os_build[16];
- static dispatch_once_t get_os_build_once;
- static BOOL broken_leaks_command = NO;
-
- dispatch_once(&get_os_build_once, ^{
- int mib[] = { CTL_KERN, KERN_OSVERSION };
- size_t bufsz = sizeof(os_build);
- sysctl(mib, 2, os_build, &bufsz, NULL, 0);
-
- if (4 == sizeof(char*) && 0 == strcmp(os_build, "12A75")) {
- // 12A75's leaks command was badly broken for 32 bit.
- // Running it suspends otest, and it is too hard to
- // recover.
- broken_leaks_command = YES;
- }
- });
-
- if (broken_leaks_command) {
- return [NSString stringWithFormat:@"Leaks command is broken in %s", os_build];
- }
-
- NSRegularExpression *matchLeaksLine = [NSRegularExpression regularExpressionWithPattern:@"^Process \\d+: \\d+ leaks for \\d+ total leaked bytes.$" options:NSRegularExpressionAnchorsMatchLines error:NULL];
-
- char *leak_command = NULL;
- NSString *fname = [NSString stringWithFormat:@"/tmp/L%d-%d", getpid(), (int)arc4random()];
- asprintf(&leak_command, "(/usr/bin/leaks %d >%s || (echo OOPS; kill -CONT %d))", getpid(), [fname UTF8String], getpid());
- system(leak_command);
- free(leak_command);
- NSString *output = [NSString stringWithContentsOfFile:fname encoding:NSUTF8StringEncoding error:NULL];
- NSTextCheckingResult *result = [matchLeaksLine firstMatchInString:output options:0 range:NSMakeRange(0, [output length])];
- if (result.range.location == NSNotFound) {
- return NULL;
- }
- NSRange matchRange = result.range;
- return [output substringWithRange:matchRange];
-}
-
--(void)testAAASimpleLeakTest {
- NSString *starting_leaks = CopyLeakLine();
- STAssertNotNil(starting_leaks, @"Found initial leaks");
- for(int i = 0; i < 10; i++) {
- CFRelease(SecTransformCreateGroupTransform());
- }
-
- NSString *current_leaks = NULL;
-
- // Some of the destruction is async, so if they don't pan out the same, a little sleep and retry
- // can legitimately fix it.
- for(int i = 0; i < 10; i++) {
- current_leaks = CopyLeakLine();
- if ([current_leaks isEqualToString:starting_leaks]) {
- break;
- } else {
- sleep(1);
- }
- }
-
- STAssertNotNil(current_leaks, @"Found current leaks");
- STAssertEqualObjects(current_leaks, starting_leaks, @"Expected no new leaks");
-}
-
--(void)testAAASimpleishLeakTest {
- NSLog(@"pid=%d", getpid());
- NSString *starting_leaks = CopyLeakLine();
- STAssertNotNil(starting_leaks, @"Found initial leaks");
- CFErrorRef err = NULL;
-
- // Derived from Matt Wright's 10242560 test.c
- int fd = open("/dev/random", O_RDONLY);
- SecTransformRef b64encode = SecEncodeTransformCreate(kSecBase64Encoding, NULL);
- const int buffer_size = 1024;
- void *buffer = malloc(buffer_size);
- // For this test, ignore short reads
- read(fd, buffer, buffer_size);
- CFDataRef data = CFDataCreateWithBytesNoCopy(NULL, (UInt8*)buffer, buffer_size, kCFAllocatorMalloc);
- SecTransformSetAttribute(b64encode, kSecTransformInputAttributeName, data, &err);
- STAssertNil((id)err, @"Expected no SecTransformSetAttribute error, got: %@", err);
- CFRelease(data);
- CFTypeRef output = SecTransformExecute(b64encode, &err);
- STAssertNotNil((id)output, @"Expected result");
- STAssertNil((id)err, @"Expected no execute error, got: %@", err);
- CFRelease(output);
- CFRelease(b64encode);
-
- NSString *current_leaks = NULL;
-
- // Some of the destruction is async, so if they don't pan out the same, a little sleep and retry
- // can legitimately fix it.
- for(int i = 0; i < 10; i++) {
- current_leaks = CopyLeakLine();
- if ([current_leaks isEqualToString:starting_leaks]) {
- break;
- } else {
- sleep(1);
- }
- }
-
- STAssertNotNil(current_leaks, @"Found current leaks");
- STAssertEqualObjects(current_leaks, starting_leaks, @"Expected no new leaks");
-}
-
-@end