1/*
2 * Copyright (c) 2006-2010,2012-2013 Apple Inc. All Rights Reserved.
3 */
4
5#include <CoreFoundation/CoreFoundation.h>
6#include <Security/SecItem.h>
7#include <Security/SecItemPriv.h>
8#include <Security/SecBase.h>
9#include <utilities/array_size.h>
10#include <stdlib.h>
11#include <unistd.h>
12
13#include "Security_regressions.h"
14
15/* Test basic add delete update copy matching stuff. */
16static void tests(void)
17{
18    const char *v_data = "test";
19    CFDataRef pwdata = CFDataCreate(NULL, (UInt8 *)v_data, strlen(v_data));
20    const void *keys[] = {
21		kSecClass,
22		kSecAttrAccount,
23		kSecAttrService,
24		kSecValueData
25    };
26    const void *values[] = {
27		kSecClassGenericPassword,
28		CFSTR("dankeen"),
29		CFSTR("iTools"),
30		pwdata
31    };
32    CFDictionaryRef item = CFDictionaryCreate(NULL, keys, values,
33	array_size(keys), NULL, NULL);
34    ok_status(SecItemAdd(item, NULL), "add generic password");
35
36    CFTypeRef results = NULL;
37    /* Create a dict with all attrs except the data. */
38    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
39	(array_size(keys)) - 1, NULL, NULL);
40    ok_status(SecItemCopyMatching(query, &results), "find generic password");
41    if (results) {
42        CFRelease(results);
43        results = NULL;
44    }
45
46    /* Modify the data of the item. */
47    const char *v_data2 = "different password data this time";
48    CFDataRef pwdata2 = CFDataCreate(NULL, (UInt8 *)v_data2, strlen(v_data2));
49    CFMutableDictionaryRef changes = CFDictionaryCreateMutable(NULL, 0, NULL, NULL);
50    CFDictionarySetValue(changes, kSecValueData, pwdata2);
51    ok_status(SecItemUpdate(query, changes), "update generic password");
52
53    CFDictionarySetValue(changes, kSecValueData, NULL);
54    is_status(SecItemUpdate(query, changes), errSecParam, "update NULL data");
55
56    /* This seems to be what we were seeing in
57       <rdar://problem/6940041> 466 Crashes in securityd: kc_encrypt_data (SecItemServer.c:971).
58       which is now fixed. */
59    CFDictionarySetValue(changes, kSecValueData, CFSTR("bogus"));
60    is_status(SecItemUpdate(query, changes), errSecParam, "update string data");
61
62    ok_status(SecItemDelete(query), "delete generic password");
63
64    if (changes) {
65        CFRelease(changes);
66        changes = NULL;
67    }
68
69    if (item) {
70        CFRelease(item);
71        item = NULL;
72    }
73
74    if (query) {
75        CFRelease(query);
76        query = NULL;
77    }
78
79    if (pwdata) {
80        CFRelease(pwdata);
81        pwdata = NULL;
82    }
83
84    if (pwdata2) {
85        CFRelease(pwdata2);
86        pwdata = NULL;
87    }
88}
89
90int si_11_update_data(int argc, char *const *argv)
91{
92	plan_tests(6);
93
94	tests();
95
96	return 0;
97}
98