]>
Commit | Line | Data |
---|---|---|
e3d460c9 A |
1 | // |
2 | // Copyright 2015 - 2016 Apple. All rights reserved. | |
3 | // | |
4 | ||
5 | /* | |
6 | * This is to fool os services to not provide the Keychain manager | |
7 | * interface tht doens't work since we don't have unified headers | |
8 | * between iOS and OS X. rdar://23405418/ | |
9 | */ | |
10 | #define __KEYCHAINCORE__ 1 | |
11 | ||
12 | #include <Foundation/Foundation.h> | |
13 | #include <Security/Security.h> | |
14 | ||
15 | #include <TargetConditionals.h> | |
16 | ||
17 | #include <Security/SecItemPriv.h> | |
18 | #include <sys/stat.h> | |
19 | #include <err.h> | |
20 | ||
21 | #if TARGET_OS_SIMULATOR | |
22 | int | |
23 | main(void) | |
24 | { | |
25 | return 0; | |
26 | } | |
27 | #else | |
28 | ||
29 | #include <libaks.h> | |
30 | ||
fa7225c8 A |
31 | static NSData *keybag = NULL; |
32 | static NSString *keybaguuid = NULL; | |
33 | ||
34 | static void | |
e3d460c9 A |
35 | BagMe(void) |
36 | { | |
37 | keybag_handle_t handle; | |
38 | kern_return_t result; | |
fa7225c8 A |
39 | char uuidstr[37]; |
40 | uuid_t uuid; | |
e3d460c9 A |
41 | void *data = NULL; |
42 | int length; | |
43 | ||
44 | result = aks_create_bag("foo", 3, kAppleKeyStoreAsymmetricBackupBag, &handle); | |
45 | if (result) | |
46 | errx(1, "aks_create_bag: %08x", result); | |
47 | ||
48 | result = aks_save_bag(handle, &data, &length); | |
49 | if (result) | |
50 | errx(1, "aks_save_bag"); | |
51 | ||
fa7225c8 A |
52 | result = aks_get_bag_uuid(handle, uuid); |
53 | if (result) | |
54 | errx(1, "aks_get_bag_uuid"); | |
55 | ||
56 | uuid_unparse_lower(uuid, uuidstr); | |
57 | ||
58 | keybaguuid = [NSString stringWithUTF8String:uuidstr]; | |
59 | keybag = [NSData dataWithBytes:data length:length]; | |
e3d460c9 A |
60 | } |
61 | ||
62 | int main (int argc, const char * argv[]) | |
63 | { | |
64 | @autoreleasepool { | |
fa7225c8 | 65 | NSData *password = NULL; |
e3d460c9 | 66 | CFErrorRef error = NULL; |
fa7225c8 | 67 | NSString *uuid = NULL; |
e3d460c9 | 68 | |
fa7225c8 | 69 | BagMe(); |
e3d460c9 A |
70 | password = [NSData dataWithBytes:"foo" length:3]; |
71 | ||
fa7225c8 | 72 | NSData *backup = CFBridgingRelease(_SecKeychainCopyBackup((__bridge CFDataRef)keybag, (__bridge CFDataRef)password)); |
e3d460c9 A |
73 | if (backup == NULL) { |
74 | errx(1, "backup failed"); | |
75 | } | |
76 | ||
77 | char path[] = "/tmp/secbackuptestXXXXXXX"; | |
78 | int fd = mkstemp(path); | |
79 | ||
fa7225c8 | 80 | bool status = _SecKeychainWriteBackupToFileDescriptor((__bridge CFDataRef)keybag, (__bridge CFDataRef)password, fd, &error); |
e3d460c9 A |
81 | if (!status) { |
82 | NSLog(@"backup failed: %@", error); | |
83 | errx(1, "failed backup 2"); | |
84 | } | |
85 | ||
fa7225c8 A |
86 | uuid = CFBridgingRelease(_SecKeychainCopyKeybagUUIDFromFileDescriptor(fd, &error)); |
87 | if (uuid == NULL) { | |
88 | NSLog(@"getting uuid failed failed: %@", error); | |
89 | errx(1, "failed getting uuid"); | |
90 | } | |
91 | ||
92 | if (![uuid isEqual:keybaguuid]) { | |
93 | NSLog(@"getting uuid failed failed: %@ vs %@", uuid, keybaguuid); | |
94 | errx(1, "failed compare uuid"); | |
95 | } | |
96 | ||
e3d460c9 A |
97 | struct stat sb; |
98 | fstat(fd, &sb); | |
99 | ||
100 | if (sb.st_size != (off_t)[backup length]) | |
101 | warn("backup different "); | |
102 | ||
103 | if (abs((int)(sb.st_size - (off_t)[backup length])) > 1000) | |
104 | errx(1, "backup different enough to fail"); | |
105 | ||
fa7225c8 | 106 | status = _SecKeychainRestoreBackupFromFileDescriptor(fd, (__bridge CFDataRef)keybag, (__bridge CFDataRef)password, &error); |
e3d460c9 A |
107 | if (!status) { |
108 | NSLog(@"restore failed: %@", error); | |
109 | errx(1, "restore failed"); | |
110 | } | |
111 | ||
112 | close(fd); | |
113 | unlink(path); | |
114 | ||
fa7225c8 | 115 | NSData *backup2 = CFBridgingRelease(_SecKeychainCopyBackup((__bridge CFDataRef)keybag, (__bridge CFDataRef)password)); |
e3d460c9 A |
116 | if (backup2 == NULL) { |
117 | errx(1, "backup 3 failed"); | |
118 | } | |
119 | ||
120 | if (abs((int)(sb.st_size - (off_t)[backup2 length])) > 1000) | |
121 | errx(1, "backup different enough to fail (mem vs backup2): %d vs %d", (int)sb.st_size, (int)[backup2 length]); | |
122 | if (abs((int)([backup length] - [backup2 length])) > 1000) | |
123 | errx(1, "backup different enough to fail (backup1 vs backup2: %d vs %d", (int)[backup length], (int)[backup2 length]); | |
124 | ||
125 | return 0; | |
126 | } | |
127 | } | |
128 | ||
129 | #endif /* TARGET_OS_SIMULATOR */ | |
130 |