]> git.saurik.com Git - apple/security.git/blob - secdxctests/KeychainAPITests.m
Security-58286.260.20.tar.gz
[apple/security.git] / secdxctests / KeychainAPITests.m
1 /*
2 * Copyright (c) 2018 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #import "KeychainXCTest.h"
25 #import "SecDbKeychainItem.h"
26 #import "SecdTestKeychainUtilities.h"
27 #import "CKKS.h"
28 #import "SecDbKeychainItemV7.h"
29 #import "SecItemPriv.h"
30 #import "SecItemServer.h"
31 #import "spi.h"
32 #import "SecDbKeychainSerializedItemV7.h"
33 #import "SecDbKeychainSerializedMetadata.h"
34 #import "SecDbKeychainSerializedSecretData.h"
35 #import "SecDbKeychainSerializedAKSWrappedKey.h"
36 #import <utilities/SecCFWrappers.h>
37 #import <SecurityFoundation/SFEncryptionOperation.h>
38 #import <XCTest/XCTest.h>
39 #import <OCMock/OCMock.h>
40
41 void* testlist = NULL;
42
43 #if USE_KEYSTORE
44
45 @interface KeychainAPITests : KeychainXCTest
46 @end
47
48 @implementation KeychainAPITests
49
50 + (void)setUp
51 {
52 [super setUp];
53
54 SecCKKSDisable();
55 securityd_init(NULL);
56 }
57
58 - (void)setUp
59 {
60 [super setUp];
61
62 NSArray* partsOfName = [self.name componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" ]"]];
63 secd_test_setup_temp_keychain([partsOfName[1] UTF8String], NULL);
64 }
65
66 - (void)testReturnValuesInSecItemUpdate
67 {
68 NSDictionary* addQuery = @{ (id)kSecClass : (id)kSecClassGenericPassword,
69 (id)kSecValueData : [@"password" dataUsingEncoding:NSUTF8StringEncoding],
70 (id)kSecAttrAccount : @"TestAccount",
71 (id)kSecAttrService : @"TestService",
72 (id)kSecAttrNoLegacy : @(YES),
73 (id)kSecReturnAttributes : @(YES)
74 };
75
76 NSDictionary* updateQueryWithNoReturn = @{ (id)kSecClass : (id)kSecClassGenericPassword,
77 (id)kSecAttrAccount : @"TestAccount",
78 (id)kSecAttrService : @"TestService",
79 (id)kSecAttrNoLegacy : @(YES)
80 };
81
82 CFTypeRef result = NULL;
83
84 // Add the item
85 XCTAssertEqual(SecItemAdd((__bridge CFDictionaryRef)addQuery, &result), errSecSuccess, @"Should have succeeded in adding test item to keychain");
86 XCTAssertNotNil((__bridge id)result, @"Should have received a dictionary back from SecItemAdd");
87 CFReleaseNull(result);
88
89 // And we can update the item
90 XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithNoReturn, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"otherpassword" dataUsingEncoding:NSUTF8StringEncoding]}), errSecSuccess, "failed to update item with clean update query");
91
92 // great, a normal update works
93 // now let's do updates with various queries which include return parameters to ensure they succeed on macOS and throw errors on iOS.
94 // this is a status-quo compromise between changing iOS match macOS (which has lamé no-op characteristics) and changing macOS to match iOS, which risks breaking existing clients
95
96 #if TARGET_OS_OSX
97 NSMutableDictionary* updateQueryWithReturnAttributes = updateQueryWithNoReturn.mutableCopy;
98 updateQueryWithReturnAttributes[(id)kSecReturnAttributes] = @(YES);
99 XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnAttributes, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-attributes" dataUsingEncoding:NSUTF8StringEncoding]}), errSecSuccess, "failed to update item with return attributes query");
100
101 NSMutableDictionary* updateQueryWithReturnData = updateQueryWithNoReturn.mutableCopy;
102 updateQueryWithReturnAttributes[(id)kSecReturnData] = @(YES);
103 XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnData, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-data" dataUsingEncoding:NSUTF8StringEncoding]}), errSecSuccess, "failed to update item with return data query");
104
105 NSMutableDictionary* updateQueryWithReturnRef = updateQueryWithNoReturn.mutableCopy;
106 updateQueryWithReturnAttributes[(id)kSecReturnRef] = @(YES);
107 XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnRef, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-ref" dataUsingEncoding:NSUTF8StringEncoding]}), errSecSuccess, "failed to update item with return ref query");
108
109 NSMutableDictionary* updateQueryWithReturnPersistentRef = updateQueryWithNoReturn.mutableCopy;
110 updateQueryWithReturnAttributes[(id)kSecReturnPersistentRef] = @(YES);
111 XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnPersistentRef, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-persistent-ref" dataUsingEncoding:NSUTF8StringEncoding]}), errSecSuccess, "failed to update item with return persistent ref query");
112 #else
113 NSMutableDictionary* updateQueryWithReturnAttributes = updateQueryWithNoReturn.mutableCopy;
114 updateQueryWithReturnAttributes[(id)kSecReturnAttributes] = @(YES);
115 XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnAttributes, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-attributes" dataUsingEncoding:NSUTF8StringEncoding]}), errSecParam, "failed to generate error updating item with return attributes query");
116
117 NSMutableDictionary* updateQueryWithReturnData = updateQueryWithNoReturn.mutableCopy;
118 updateQueryWithReturnData[(id)kSecReturnData] = @(YES);
119 XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnData, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-data" dataUsingEncoding:NSUTF8StringEncoding]}), errSecParam, "failed to generate error updating item with return data query");
120
121 NSMutableDictionary* updateQueryWithReturnRef = updateQueryWithNoReturn.mutableCopy;
122 updateQueryWithReturnRef[(id)kSecReturnRef] = @(YES);
123 XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnRef, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-ref" dataUsingEncoding:NSUTF8StringEncoding]}), errSecParam, "failed to generate error updating item with return ref query");
124
125 NSMutableDictionary* updateQueryWithReturnPersistentRef = updateQueryWithNoReturn.mutableCopy;
126 updateQueryWithReturnPersistentRef[(id)kSecReturnPersistentRef] = @(YES);
127 XCTAssertEqual(SecItemUpdate((__bridge CFDictionaryRef)updateQueryWithReturnPersistentRef, (__bridge CFDictionaryRef)@{(id)kSecValueData: [@"return-persistent-ref" dataUsingEncoding:NSUTF8StringEncoding]}), errSecParam, "failed to generate error updating item with return persistent ref query");
128 #endif
129 }
130
131 @end
132
133 #endif