forked from sparkle-project/Sparkle
-
Notifications
You must be signed in to change notification settings - Fork 1
/
SUCodeSigningVerifier.m
86 lines (67 loc) · 2.76 KB
/
SUCodeSigningVerifier.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//
// SUCodeSigningVerifier.m
// Sparkle
//
// Created by Andy Matuschak on 7/5/12.
//
//
#import <Security/CodeSigning.h>
#import "SUCodeSigningVerifier.h"
#import "SULog.h"
@implementation SUCodeSigningVerifier
extern OSStatus SecCodeCopySelf(SecCSFlags flags, SecCodeRef *self) __attribute__((weak_import));
extern OSStatus SecCodeCopyDesignatedRequirement(SecStaticCodeRef code, SecCSFlags flags, SecRequirementRef *requirement) __attribute__((weak_import));
extern OSStatus SecStaticCodeCreateWithPath(CFURLRef path, SecCSFlags flags, SecStaticCodeRef *staticCode) __attribute__((weak_import));
extern OSStatus SecStaticCodeCheckValidityWithErrors(SecStaticCodeRef staticCode, SecCSFlags flags, SecRequirementRef requirement, CFErrorRef *errors) __attribute__((weak_import));
+ (BOOL)codeSignatureIsValidAtPath:(NSString *)destinationPath error:(NSError **)error
{
// This API didn't exist prior to 10.6.
if (SecCodeCopySelf == NULL) return NO;
OSStatus result;
SecRequirementRef requirement = NULL;
SecStaticCodeRef staticCode = NULL;
SecCodeRef hostCode = NULL;
result = SecCodeCopySelf(kSecCSDefaultFlags, &hostCode);
if (result != 0) {
SULog(@"Failed to copy host code %d", result);
goto finally;
}
result = SecCodeCopyDesignatedRequirement(hostCode, kSecCSDefaultFlags, &requirement);
if (result != 0) {
SULog(@"Failed to copy designated requirement %d", result);
goto finally;
}
NSBundle *newBundle = [NSBundle bundleWithPath:destinationPath];
if (!newBundle) {
SULog(@"Failed to load NSBundle for update");
result = -1;
goto finally;
}
result = SecStaticCodeCreateWithPath((CFURLRef)[newBundle executableURL], kSecCSDefaultFlags, &staticCode);
if (result != 0) {
SULog(@"Failed to get static code %d", result);
goto finally;
}
result = SecStaticCodeCheckValidityWithErrors(staticCode, kSecCSDefaultFlags | kSecCSCheckAllArchitectures, requirement, (CFErrorRef *)error);
if (result != 0 && error) [*error autorelease];
finally:
if (hostCode) CFRelease(hostCode);
if (staticCode) CFRelease(staticCode);
if (requirement) CFRelease(requirement);
return (result == 0);
}
+ (BOOL)hostApplicationIsCodeSigned
{
// This API didn't exist prior to 10.6.
if (SecCodeCopySelf == NULL) return NO;
OSStatus result;
SecCodeRef hostCode = NULL;
result = SecCodeCopySelf(kSecCSDefaultFlags, &hostCode);
if (result != 0) return NO;
SecRequirementRef requirement = NULL;
result = SecCodeCopyDesignatedRequirement(hostCode, kSecCSDefaultFlags, &requirement);
if (hostCode) CFRelease(hostCode);
if (requirement) CFRelease(requirement);
return (result == 0);
}
@end