-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCredentialsStore.m
98 lines (88 loc) · 3.34 KB
/
CredentialsStore.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
87
88
89
90
91
92
93
94
95
96
97
98
//
// CredentialsStore.m
// AvocadoTest1
//
// Created by Christophe Biocca on 12-01-26.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "CredentialsStore.h"
#import <Security/Security.h>
#import <CommonCrypto/CommonDigest.h>
@implementation CredentialsStore
static CredentialsStore* store = nil;
+(void)initialize{
if(!store){
store = [[CredentialsStore alloc] init];
}
}
+(CredentialsStore*)credentialsStore{
return store;
}
-(void)obtainSecureAppID{
CFStringRef accessKey = (CFStringRef) @"CroutonLabs - Security Key";
CFStringRef serviceKey = (CFStringRef) @"service";
CFMutableDictionaryRef searchDict =
CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
CFDictionaryAddValue(searchDict, kSecClass, kSecClassGenericPassword);
CFDictionaryAddValue(searchDict, kSecAttrService, serviceKey);
CFDictionaryAddValue(searchDict, kSecAttrAccount, accessKey);
#if !TARGET_IPHONE_SIMULATOR
CFDictionaryAddValue(searchDict, kSecAttrAccessGroup, @"AP5C358JXU.com.croutonlabs.restaurantapps");
#endif
CFDictionaryAddValue(searchDict, kSecReturnData, kCFBooleanTrue);
CFDataRef data = nil;
OSStatus res = SecItemCopyMatching(searchDict, (CFTypeRef*)&data);
if(res == errSecSuccess){
appID = [[[NSString alloc] initWithData:(__bridge NSData*)data encoding:NSASCIIStringEncoding] lowercaseString];
CFRelease(data);
} else if(res == errSecItemNotFound){
// Create it.
NSString* uuidString = [Utilities uuid];
CFDataRef data = (__bridge CFDataRef)[uuidString dataUsingEncoding:NSASCIIStringEncoding];
CFDictionaryRemoveValue(searchDict, kSecReturnData);
CFDictionaryAddValue(searchDict, kSecAttrAccessible, kSecAttrAccessibleAfterFirstUnlock);
CFDictionaryAddValue(searchDict, kSecValueData, data);
res = SecItemAdd(searchDict, NULL);
if(res == errSecSuccess){
appID = uuidString;
} else {
NSAssert(NO, @"WTF GENTLEMEN, we got this %ld", res);
}
} else {
NSAssert(NO, @"WTF GENTLEMEN, we got this %ld", res);
}
CFRelease(searchDict);
}
-(NSString*)appID{
if(!appID){
// Fetch it from the secure chain
[self obtainSecureAppID];
}
return appID;
}
// We need to start thinking whether we should be collecting phone ids at all,
// they're useless for authentication, and apple considers them deprecated.
-(NSString*)phoneID{
if(!phoneID){
phoneID = [[UIDevice currentDevice] performSelector:@selector(uniqueIdentifier)];
}
return phoneID;
}
static NSString* signingString = @"THIS IS A TEST GUYS";
-(NSString*)signature{
if(!signature){
NSData* dataToHash = [[NSString stringWithFormat:@"%@%@%@",
[self appID],
[self phoneID],
signingString] dataUsingEncoding:NSASCIIStringEncoding];
unsigned char hash[CC_SHA512_DIGEST_LENGTH];
CC_SHA512([dataToHash bytes], [dataToHash length], hash);
NSMutableString* hexHash = [NSMutableString string];
for(NSInteger i = 0; i < CC_SHA512_DIGEST_LENGTH; ++i){
[hexHash appendFormat:@"%02x", hash[i]];
}
signature = hexHash;
}
return signature;
}
@end