]> git.saurik.com Git - apple/security.git/blob - RegressionTests/manifeststresstest/Keychain.m
Security-58286.251.4.tar.gz
[apple/security.git] / RegressionTests / manifeststresstest / Keychain.m
1 //
2 // Keychain.m
3 // Security
4 //
5 // Created by Ben Williamson on 6/2/17.
6 //
7 //
8
9 #import "Keychain.h"
10
11 /*
12 * This is to fool os services to not provide the Keychain manager
13 * interface that doens't work since we don't have unified headers
14 * between iOS and OS X. rdar://23405418/
15 */
16 #define __KEYCHAINCORE__ 1
17
18 #import <Security/Security.h>
19 #import <Security/SecItemPriv.h>
20 #import <Security/SecBasePriv.h>
21 #import <Security/SecIdentityPriv.h>
22
23 #if SEC_OS_OSX_INCLUDES
24 #import <Security/SecKeychain.h>
25 #endif
26
27 #import <stdio.h>
28 #import <stdlib.h>
29
30 static NSString *kAccessGroup = @"manifeststresstest";
31 static NSString *kService = @"manifeststresstest";
32
33
34
35 @implementation Keychain
36
37 - (OSStatus)addItem:(NSString *)name value:(NSString *)value view:(NSString *)view pRef:(NSArray **)result
38 {
39 NSDictionary *query = @{
40 (id)kSecClass : (id)kSecClassGenericPassword,
41 (id)kSecAttrAccessGroup : kAccessGroup,
42 (id)kSecAttrService : kService,
43 (id)kSecAttrAccount : name,
44 (id)kSecValueData : [value dataUsingEncoding:NSUTF8StringEncoding],
45 (id)kSecAttrSynchronizable: (id)kCFBooleanTrue,
46 (id)kSecAttrNoLegacy : (id)kCFBooleanTrue,
47 (id)kSecAttrSyncViewHint : view,
48 (id)kSecReturnPersistentRef: @YES,
49 };
50 CFArrayRef itemRef = NULL;
51 OSStatus status = SecItemAdd((__bridge CFDictionaryRef)query, (void *)&itemRef);
52 if (result) {
53 *result = CFBridgingRelease(itemRef);
54 }
55
56 return status;
57 }
58
59 - (OSStatus)addItem:(NSString *)name value:(NSString *)value view:(NSString *)view
60 {
61 return [self addItem:name value:value view:view pRef:nil];
62 }
63
64 - (OSStatus)updateItemWithName:(NSString *)name newValue:(NSString *)newValue
65 {
66
67 NSDictionary *query = @{
68 (id)kSecClass : (id)kSecClassGenericPassword,
69 (id)kSecAttrAccessGroup : kAccessGroup,
70 (id)kSecAttrService : kService,
71 (id)kSecAttrAccount : name,
72 (id)kSecAttrSynchronizable: (id)kCFBooleanTrue,
73 };
74 NSDictionary *modifications = @{
75 (id)kSecValueData : [newValue dataUsingEncoding:NSUTF8StringEncoding],
76 };
77 return SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)modifications);
78 }
79
80 - (OSStatus)updateItem:(id)pRef newValue:(NSString *)newValue
81 {
82 return [self updateItem:pRef modifications:@{
83 (id)kSecValueData : [newValue dataUsingEncoding:NSUTF8StringEncoding],
84 }];
85 }
86
87 - (OSStatus)updateItem:(id)pRef newName:(NSString *)newName
88 {
89 return [self updateItem:pRef modifications:@{
90 (id)kSecAttrAccount : newName,
91 }];
92 }
93
94 - (OSStatus)updateItem:(id)pRef newName:(NSString *)newName newValue:(NSString *)newValue
95 {
96 return [self updateItem:pRef modifications:@{
97 (id)kSecAttrAccount : newName,
98 (id)kSecValueData : [newValue dataUsingEncoding:NSUTF8StringEncoding],
99 }];
100 }
101
102 - (OSStatus)updateItem:(id)pRef modifications:(NSDictionary *)modifications
103 {
104 NSDictionary *query = @{
105 (id)kSecClass : (id)kSecClassGenericPassword,
106 (id)kSecValuePersistentRef: ([pRef isKindOfClass:[NSData class]] ? pRef : pRef[0]),
107 };
108 return SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)modifications);
109 }
110
111 - (OSStatus)deleteItem:(id)pRef
112 {
113 NSDictionary *query = @{
114 (id)kSecClass : (id)kSecClassGenericPassword,
115 (id)kSecValuePersistentRef: ([pRef isKindOfClass:[NSData class]] ? pRef : pRef[0]),
116 };
117 return SecItemDelete((__bridge CFDictionaryRef)query);
118 }
119
120 - (OSStatus)deleteItemWithName:(NSString *)name
121 {
122 NSDictionary *query = @{
123 (id)kSecClass : (id)kSecClassGenericPassword,
124 (id)kSecAttrAccessGroup : kAccessGroup,
125 (id)kSecAttrService : kService,
126 (id)kSecAttrSynchronizable: (id)kCFBooleanTrue,
127 (id)kSecAttrAccount : name,
128 };
129 return SecItemDelete((__bridge CFDictionaryRef)query);
130 }
131
132 - (OSStatus)deleteAllItems
133 {
134 NSDictionary *query = @{
135 (id)kSecClass : (id)kSecClassGenericPassword,
136 (id)kSecAttrAccessGroup : kAccessGroup,
137 (id)kSecAttrSynchronizable: (id)kCFBooleanTrue,
138 };
139 return SecItemDelete((__bridge CFDictionaryRef)query);
140 }
141
142 - (NSDictionary<NSString *, NSArray *> *)getAllItems
143 {
144 CFArrayRef result = NULL;
145 NSDictionary *query = @{
146 (id)kSecMatchLimit : (id)kSecMatchLimitAll,
147 (id)kSecReturnData : (id)kCFBooleanTrue,
148 (id)kSecReturnAttributes : (id)kCFBooleanTrue,
149 (id)kSecReturnPersistentRef : (id)kCFBooleanTrue,
150 (id)kSecClass : (id)kSecClassGenericPassword,
151 (id)kSecAttrAccessGroup : kAccessGroup,
152 (id)kSecAttrService : kService,
153 (id)kSecAttrNoLegacy : (id)kCFBooleanTrue,
154 (id)kSecAttrSynchronizable: (id)kCFBooleanTrue,
155 };
156 OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&result);
157 if (status == errSecItemNotFound) {
158 return @{};
159 }
160 if (status != errSecSuccess) {
161 printf("Error reading items to verify: %d\n", (int)status);
162 exit(1);
163 }
164 NSArray *arr = CFBridgingRelease(result);
165
166 NSMutableDictionary *items = [NSMutableDictionary dictionary];
167 for (NSDictionary *dict in arr) {
168 NSString *name = dict[(id)kSecAttrAccount];
169 NSData *data = dict[(id)kSecValueData];
170 NSData *ref = dict[(id)kSecValuePersistentRef];
171 NSString *value = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
172 if (!value) {
173 printf("Item %s has data that is not valid UTF-8.\n", [name UTF8String]);
174 exit(1);
175 }
176 items[name] = @[ref, value];
177 }
178 return items;
179 }
180
181 @end