2 // secsecstaticcodeapitest.c
3 // secsecstaticcodeapitest
10 #include <AssertMacros.h>
11 #include <sys/xattr.h>
12 #include <Security/SecCodePriv.h>
13 #include <Security/SecCode.h>
14 #include <Security/SecStaticCode.h>
18 fprintf(stdout, "[BEGIN] %s\n", __FUNCTION__); \
21 #define INFO(fmt, ...) \
23 fprintf(stdout, fmt "\n", ##__VA_ARGS__); \
26 #define PASS(fmt, ...) \
28 fprintf(stdout, "[PASS] %s " fmt "\n", __FUNCTION__, ##__VA_ARGS__); \
31 #define FAIL(fmt, ...) \
33 fprintf(stdout, "[FAIL] %s " fmt "\n", __FUNCTION__, ##__VA_ARGS__); \
36 #define SAFE_RELEASE(x) \
44 #define kCommandRedirectOutputToDevNULL " >/dev/null 2>&1"
45 #define BUILD_COMMAND(x) x kCommandRedirectOutputToDevNULL
47 #define kFAT32DiskImageFileDirectory "/tmp"
48 #define kFAT32DiskImageFileName "Security_SecStaticCodeAPITest.dmg"
49 #define kFAT32DiskImageFilePath kFAT32DiskImageFileDirectory "/" kFAT32DiskImageFileName
51 #define kFAT32DiskImageVolumeDirectory "/Volumes"
52 #define kFAT32DiskImageVolumeName "SEC_TEST"
53 #define kFAT32DiskImageVolumePath kFAT32DiskImageVolumeDirectory "/" kFAT32DiskImageVolumeName
55 #define kApplicationsPath "/Applications"
56 #define kSafariBundleName "Safari.app"
57 #define kSafariBundleOnSystemPath kApplicationsPath "/" kSafariBundleName
58 #define kSafariBundleOnVolumePath kFAT32DiskImageVolumePath "/" kSafariBundleName
61 _cleanUpFAT32DiskImage(void)
64 const char *command
= BUILD_COMMAND("rm -rf " kFAT32DiskImageFilePath
);
68 command
= BUILD_COMMAND("hdiutil detach " kFAT32DiskImageVolumePath
);
73 _createFAT32DiskImage(void)
75 const char *command
= BUILD_COMMAND("hdiutil create -fs FAT32 -size 256m -volname " kFAT32DiskImageVolumeName
" " kFAT32DiskImageFilePath
);
76 return system(command
);
80 _attachFAT32DiskImage(void)
82 const char *command
= BUILD_COMMAND("hdiutil attach " kFAT32DiskImageFilePath
);
83 return system(command
);
87 _copySafariBundleToVolume(void)
89 const char *command
= BUILD_COMMAND("cp -R " kSafariBundleOnSystemPath
" " kSafariBundleOnVolumePath
);
90 return system(command
);
94 _confirmValidationPolicy(const char *path
)
97 SecStaticCodeRef codeRef
= NULL
;
98 SecCSFlags createFlags
= kSecCSDefaultFlags
;
99 SecCSFlags validateFlags
= kSecCSDefaultFlags
| kSecCSStrictValidateStructure
;
101 CFStringRef stringRef
= NULL
;
102 CFURLRef pathRef
= NULL
;
106 stringRef
= CFStringCreateWithBytes(kCFAllocatorDefault
, (const UInt8
*)path
, strlen(path
), kCFStringEncodingASCII
, false);
107 require(stringRef
, done
);
109 pathRef
= CFURLCreateWithFileSystemPath(kCFAllocatorDefault
, stringRef
, kCFURLPOSIXPathStyle
, false);
110 require(pathRef
, done
);
112 OSStatus status
= SecStaticCodeCreateWithPath(pathRef
, createFlags
, &codeRef
);
113 require_noerr(status
, done
);
114 require(codeRef
, done
);
116 // Validate binary without kSecCSSkipXattrFiles. Expectation is this should fail.
117 status
= SecStaticCodeCheckValidity(codeRef
, validateFlags
, NULL
);
119 INFO("%s validated without kSecCSSkipXattrFiles flag", path
);
122 SAFE_RELEASE(codeRef
);
124 // Create codeRef again to clear state.
125 status
= SecStaticCodeCreateWithPath(pathRef
, createFlags
, &codeRef
);
126 require_noerr(status
, done
);
127 require(codeRef
, done
);
129 // Validate binary with kSecCSSkipXattrFiles. Expectation is this should pass.
130 validateFlags
|= kSecCSSkipXattrFiles
;
131 status
= SecStaticCodeCheckValidity(codeRef
, validateFlags
, NULL
);
133 INFO("%s is not valid even with kSecCSSkipXattrFiles flag", path
);
141 SAFE_RELEASE(codeRef
);
142 SAFE_RELEASE(stringRef
);
143 SAFE_RELEASE(pathRef
);
148 CheckCheckValidity_kSecCSSkipXattrFiles(void)
154 // Create FAT32 disk image.
155 if (_createFAT32DiskImage()) {
156 FAIL("_createFAT32DiskImage error");
159 INFO("Created " kFAT32DiskImageFilePath
);
161 // Attach disk image to the system.
162 if (_attachFAT32DiskImage()) {
163 FAIL("_attachFAT32DiskImage error");
166 INFO("Attached " kFAT32DiskImageFilePath
" as " kFAT32DiskImageVolumePath
);
168 // Copy Safari.app to the attached volume.
169 if (_copySafariBundleToVolume()) {
170 FAIL("_copySafariBundleToVolume error");
173 INFO("Copied " kSafariBundleOnSystemPath
" to " kSafariBundleOnVolumePath
);
175 // Write "com.apple.dummy" xattr to Safari.
176 const char *xattrName
= "com.apple.dummy";
177 const uint32_t xattrValue
= 0;
179 const char *safariBinary
= kSafariBundleOnVolumePath
"/Contents/MacOS/Safari";
180 if (setxattr(safariBinary
, xattrName
, &xattrValue
, sizeof(xattrValue
), 0, 0)) {
181 FAIL("%s setxattr error: %d [%s]", safariBinary
, errno
, strerror(errno
));
184 INFO("Wrote xattr \'%s\' to %s", xattrName
, safariBinary
);
186 const char *safariCodeResources
= kSafariBundleOnVolumePath
"/Contents/_CodeSignature/CodeResources";
187 if (setxattr(safariCodeResources
, xattrName
, &xattrValue
, sizeof(xattrValue
), 0, 0)) {
188 FAIL("%s setxattr error: %d [%s]", safariCodeResources
, errno
, strerror(errno
));
191 INFO("Wrote xattr \'%s\' to %s", xattrName
, safariCodeResources
);
193 // Validate Safari.app with and without kSecCSSkipXattrFiles flag.
194 if (_confirmValidationPolicy(kSafariBundleOnVolumePath
)) {
195 FAIL("%s _confirmValidationPolicy error", kSafariBundleOnVolumePath
);
198 INFO("Validation policy on %s confirmed", kSafariBundleOnVolumePath
);
200 PASS("Completed validation policy check with kSecCSSkipXattrFiles");
204 _cleanUpFAT32DiskImage();
210 fprintf(stdout
, "[TEST] secsecstaticcodeapitest\n");
213 int (*testList
[])(void) = {
214 CheckCheckValidity_kSecCSSkipXattrFiles
216 const int numberOfTests
= sizeof(testList
) / sizeof(*testList
);
217 int testResults
[numberOfTests
] = {0};
219 for (i
= 0; i
< numberOfTests
; i
++) {
220 testResults
[i
] = testList
[i
]();
223 fprintf(stdout
, "[SUMMARY]\n");
224 for (i
= 0; i
< numberOfTests
; i
++) {
225 fprintf(stdout
, "%d. %s\n", i
+1, testResults
[i
] == 0 ? "Passed" : "Failed");