Read from p12 file in objective c and covert Array - objective-c

I have the following Code to read from a .p12 certificate and I want to hand the certifcate data over to an autentication challenge:
- (SecIdentityRef)getClientCertificate {
NSString *thePath = [[NSBundle mainBundle] pathForResource:#"fest" ofType:#"p12"];
if(!thePath)
return NULL;
NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:thePath] ;
CFDataRef inPKCS12Data = (CFDataRef)CFBridgingRetain(PKCS12Data);
CFStringRef password = CFSTR("fest");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef optionsDictionary = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus ret = SecPKCS12Import(inPKCS12Data, optionsDictionary, &items);
if (ret != errSecSuccess)
{
// TODO: handle error.
NSLog(#"-> SecPKCS12Import error (%ld)", ret);
}
CFRelease(optionsDictionary);
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
SecIdentityRef identityApp = nil;
if(!identityDict)
return nil;
identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
SecIdentityRef identity;
SecCertificateRef cert;
OSStatus err;
CFStringRef certName;
identity = identityApp;
assert( (identity != NULL) && (CFGetTypeID(identity) == SecIdentityGetTypeID()) );
cert = NULL;
err = SecIdentityCopyCertificate(identity, &cert);
assert(err == noErr);
assert(cert != NULL);
certName = SecCertificateCopySubjectSummary(cert);
assert(certName != NULL);
NSLog(#"%#" , (id) CFBridgingRelease(certName));
//NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:(id)CFBridgingRelease(certName),#"USERID",nil];
[[NSNotificationCenter defaultCenter] postNotificationName:#"UserInfoReceived" object:nil];
//CFRelease(cert);
//CFRelease(certName);
return identityApp;
_identities = [[NSMutableArray alloc] initWithArray:(__bridge NSArray *)(items)];
_certs = [[NSMutableArray alloc] initWithArray:(__bridge NSArray *)(cert)];
}
At the end I want to assign the items CFArrayRef to the identities Array. But is does not work. Has somebody an idea?
Thanks!

A CFArrayRef is toll-free bridged to NSArray *, so you can cast it as such and then create a mutable copy. Try this:
_identities = [(NSArray *)items mutableCopy];

Related

Sample function to store and retrieve a p12 certificate in keychain - Objective C

I need two functions one which stores the p12 certificate in iOS Keychain and the other function to retrieve the stored p12 certificate.
-(BOOL)addItem:(NSData*)item forKey:(NSString*)key {
NSMutableDictionary *dict = [self newItemDictionaryForKey:key];
[dict setObject:item forKey:(id)kSecValueData];
OSStatus ossstatus = SecItemAdd((CFDictionaryRef)dict, NULL);
if(errSecSuccess != ossstatus) {
NSLog(#"Unable to add item for key %# %ld request dict:%#",key,ossstatus,dict);
}
return (errSecSuccess == ossstatus);
}
To the above function i am sending the NSData that i get from p12 file.
You have to split this into two tasks:
Converting certificate from p12 data to SecIdentityRef. With this I can help
Store private key and certificate chain in keychain - I'm struggling with this too, but I'm couple steps ahead comparing with you.
To perform a conversion, here is a code I'm using:
- (NSError *)setClientIdentityCertificateFromPKCS12Data: (NSData *)PKCS12Data withPassword: (NSString *)password
{
OSStatus securityError = errSecSuccess;
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { (__bridge CFStringRef)password };
CFDictionaryRef optionsDictionary = NULL;
optionsDictionary = CFDictionaryCreate(
NULL, keys,
values, (password.length!=0 ? 1 : 0),
NULL, NULL);
CFArrayRef items = NULL;
securityError = SecPKCS12Import((__bridge CFDataRef)PKCS12Data,
optionsDictionary,
&items);
if (securityError == 0) {
CFDictionaryRef identityDic = (CFDictionaryRef)CFArrayGetValueAtIndex(items, 0);
SecIdentityRef secIdentity = (SecIdentityRef)CFDictionaryGetValue(identityDic, kSecImportItemIdentity);
CFArrayRef identityCertChain = (CFArrayRef)CFDictionaryGetValue(identityDic, kSecImportItemCertChain);
securityError = [self setClientIdentity: secIdentity withCertificateChain: identityCertChain];
}
if (optionsDictionary) {
CFRelease(optionsDictionary);
}
if (items) {
CFRelease(items);
}
NSError *error = nil;
if (securityError != errSecSuccess)
{
NSDictionary *info = nil;
#if !TARGET_OS_IPHONE
NSString *errorDescription = nil;
errorDescription = (__bridge_transfer NSString *)SecCopyErrorMessageString(securityError, NULL);
if (errorDescription)
{
info = #{ NSLocalizedDescriptionKey:errorDescription };
}
#endif
error = [NSError errorWithDomain: NSOSStatusErrorDomain
code: securityError
userInfo: info];
}
return error;
}

How to parse NSString value from __NSCFType?

I am trying to get all the startup(login) application of my OSX10. In order to do so I have written the this code (given below):
-(NSMutableArray*)getStartUpApplicaitonPaths{
// Get the LoginItems list.
LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
if (loginItemsRef == nil) return nil;
// Iterate over the LoginItems.
NSArray *loginItems = (__bridge NSArray *)LSSharedFileListCopySnapshot(loginItemsRef, nil);
NSMutableArray* data = [NSMutableArray arrayWithArray:loginItems];
return data;
}
From the above code I am getting an NSMutableArray of __NSCFType objects. When I am trying to get the path by converting a object of the array
NSString* file = [NSString stringWithFormat:#"%#", [startupFiles objectAtIndex:0]];
I am getting the result given below:
BundleBinding [0x103] URL:
file:///Applications/iTunes.app/Contents/MacOS/iTunesHelper.app/
bundle identifier: com.apple.iTunesHelper iTunesHelper
I need to parse the URL of and Identifier from the string given above. Please help.
The objects ar eof type: LSSharedFileListItem which is only documented in the header file.
Here is some code that may help, it will NSLog() all the file names:
NSURL *itemURL = [[NSBundle mainBundle] bundleURL];
CFURLRef URLToToggle = (__bridge CFURLRef)itemURL;
LSSharedFileListRef loginItems = LSSharedFileListCreate(kCFAllocatorDefault, kLSSharedFileListSessionLoginItems, /*options*/ NULL);
if (loginItems) {
UInt32 seed = 0U;
Boolean found;
CFArrayRef currentLoginItems = LSSharedFileListCopySnapshot(loginItems,
&seed);
const CFIndex count = CFArrayGetCount(currentLoginItems);
for (CFIndex idx = 0; idx < count; ++idx) {
LSSharedFileListItemRef item = (LSSharedFileListItemRef)CFArrayGetValueAtIndex(currentLoginItems, idx);
CFURLRef outURL = NULL;
const UInt32 resolutionFlags = kLSSharedFileListNoUserInteraction | kLSSharedFileListDoNotMountVolumes;
#if (__MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_10)
outURL = LSSharedFileListItemCopyResolvedURL(item, resolutionFlags, /*outError*/ NULL);
if (outURL == NULL) {
if (outURL)
CFRelease(outURL);
continue;
}
#else
OSStatus err = LSSharedFileListItemResolve(item, resolutionFlags, &outURL, /*outRef*/ NULL);
if (err != noErr || outURL == NULL) {
if (outURL)
CFRelease(outURL);
continue;
}
#endif
found = CFEqual(outURL, URLToToggle);
NSLog(#"%#", outURL);
CFRelease(outURL);
}
CFRelease(currentLoginItems);
CFRelease(loginItems);
}
Output in my instance:
file:///Volumes/User/dgrassi/Library/PreferencePanes/MouseLocator.prefPane/Contents/Resources/MouseLocatorAgent.app/
file:///Applications/iTunes.app/Contents/MacOS/iTunesHelper.app/
file:///Applications/Dropbox.app/
file:///Library/PreferencePanes/Screens%20Connect.prefPane/Contents/MacOS/Screens%20Connect.app/
file:///Library/Application%20Support/EyeTV/EyeTV%20Helper.app/
file:///Applications/Carbon%20Copy%20Cloner.app/Contents/Library/LoginItems/CCC%20User%20Agent.app/
This came from seafile-client

accessing phone number and display country name or the country code

I accessing contacts and sending it to server, my question is do I have any possibility of detecting which country contact belongs to?
Thank you.
Follow the steps below.
1 : Fetch the phone numbers from device.
2 : You need to find the country code from the phone number. Phone numbers can be saved in the device in different formats. International format, local format, with country code, without country code etc. So you need to consider all these cases to split the country code from the phone number. The following code may help you to get the country code from the phone number.
- (NSString *)getDiallingCodeFromPhoneNumber:(NSString *)phoneNumber
{
NSString *countryCode = #"not found";
NSString *code;
NSString *dialledNumber = [[phoneNumber componentsSeparatedByCharactersInSet:[NSCharacterSet
characterSetWithCharactersInString:#"-() "]]
componentsJoinedByString:#""];
NSString *interNationalCode = [dialledNumber substringToIndex:2];
NSArray *allCodes = [self.diallingCodesDictionary allValues];
int idx;
if([dialledNumber hasPrefix:#"+"])
{
dialledNumber = [dialledNumber substringFromIndex:1];
}
else if([interNationalCode isEqualToString:#"00"])
{
dialledNumber = [dialledNumber substringFromIndex:2];
}
for (idx = 1 ; idx < dialledNumber.length; idx++) {
code = [dialledNumber substringToIndex:idx];
if([allCodes containsObject:code])
{
countryCode = code;
break;
}
}
return countryCode;
}
3 : You will get the list of country codes and country name from internet. Add it as a plist in your bundle. (I took this plist from a third part, HMDiallingCode)
4 : Now you will get the country name corresponding to your country code from that plist.
5 : If you got countryCode = not found, it means that the phone number is not saved with country code. This makes it clear that, that particular phone number is a local number. So in this case you can select the country name from NSLocale.
Try this code function you can get all of information would you like.
+(NSArray *)getAllContacts
{
CFErrorRef *error = nil;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
__block BOOL accessGranted = NO;
if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
accessGranted = granted;
dispatch_semaphore_signal(sema);
});
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
else { // we're on iOS 5 or older
accessGranted = YES;
}
if (accessGranted) {
NSLog(#"Fetching contact info ----> ");
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, error);
ABRecordRef source = ABAddressBookCopyDefaultSource(addressBook);
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(addressBook, source, kABPersonSortByFirstName);
CFIndex nPeople = CFArrayGetCount(allPeople);
NSMutableArray* items = [NSMutableArray arrayWithCapacity:nPeople];
for (int i = 0; i < nPeople; i++)
{
ContactDetailModel *contacts = [[ContactDetailModel alloc] init]; // it is NsObject class. this is contained variables and array which required for get contact information. It is not necessary for you. you can maintain according your requirments.
ABRecordRef person = CFArrayGetValueAtIndex(allPeople, i);
if((__bridge NSString*)ABRecordCopyCompositeName(person)){
contacts.compse_name = (__bridge NSString*)ABRecordCopyCompositeName(person);
NSLog(#"compse_name = %#",contacts.compse_name);
}
if (!contacts.compse_name) {
contacts.compse_name = #"";
}
//get First Name and Last Name
if((__bridge NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty)){
contacts.first_name = (__bridge NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
}
if((__bridge NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty)){
contacts.last_name = (__bridge NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
}
if (!contacts.first_name) {
contacts.first_name = #"";
}
if (!contacts.last_name) {
contacts.last_name = #"";
}
NSLog(#"fname and lname = %# %#",contacts.first_name,contacts.last_name);
/// URL
ABMultiValueRef webpages = ABRecordCopyValue(person, kABPersonURLProperty);
NSString* homepage;
// Then iterate thru webpages to get the homepage
for (CFIndex k=0; k < ABMultiValueGetCount(webpages); k++)
{
homepage = (__bridge NSString*)ABMultiValueCopyValueAtIndex(webpages, k);
NSLog(#"homepage = %#",homepage);
}
NSLog(#"URL = %#",homepage);
//// get BirthDay
if((__bridge NSString*)ABRecordCopyValue(person, kABPersonBirthdayProperty)){
contacts.birthday = (__bridge NSString*)ABRecordCopyValue(person, kABPersonBirthdayProperty);
}
if (!contacts.birthday) {
contacts.birthday = #"";
}
//// get Company Name
if((__bridge NSString*)ABRecordCopyValue(person, kABPersonOrganizationProperty)){
contacts.company = (__bridge NSString*)ABRecordCopyValue(person, kABPersonOrganizationProperty);
}
if (!contacts.company) {
contacts.company = #"";
}
// get contacts picture, if pic doesn't exists, show standart one
contacts.img_data = (__bridge NSData *)ABPersonCopyImageData(person);
if (!contacts.img_data) {
UIImage *image = [UIImage imageNamed:#"profile#2x.png"];
NSData *img_data = UIImagePNGRepresentation(image);
contacts.img_data = img_data;
}
//get Phone Numbers
NSMutableArray *phoneNumbers = [[NSMutableArray alloc] init];
ABMultiValueRef multiPhones = ABRecordCopyValue(person, kABPersonPhoneProperty);
for(CFIndex i=0;i<ABMultiValueGetCount(multiPhones);i++) {
CFStringRef phoneNumberRef = ABMultiValueCopyValueAtIndex(multiPhones, i);
NSString *phoneNumber = (__bridge NSString *) phoneNumberRef;
NSString * strippedNumber = [phoneNumber stringByReplacingOccurrencesOfString:#"[^0-9]" withString:#"" options:NSRegularExpressionSearch range:NSMakeRange(0, [phoneNumber length])];
[phoneNumbers addObject:strippedNumber];
//NSLog(#"All numbers %#", phoneNumbers);
}
contacts.arrCallIDs = phoneNumbers;
/// get Addresss
NSMutableArray *arry_address = [[NSMutableArray alloc] init];
ABMutableMultiValueRef multiAddress = ABRecordCopyValue(person, kABPersonAddressProperty);
for(CFIndex i=0; i<ABMultiValueGetCount(multiAddress);i++){
CFDictionaryRef address = ABMultiValueCopyValueAtIndex(multiAddress, i);
NSString *street = (NSString*) CFDictionaryGetValue(address, kABPersonAddressStreetKey);
NSString *city = (NSString*) CFDictionaryGetValue(address, kABPersonAddressCityKey);
NSString *state = (NSString*) CFDictionaryGetValue(address, kABPersonAddressStateKey);
NSString *postal = (NSString*) CFDictionaryGetValue(address, kABPersonAddressZIPKey);
NSString *country = (NSString*) CFDictionaryGetValue(address, kABPersonAddressCountryKey);
NSString *country_id = (NSString*) CFDictionaryGetValue(address, kABPersonAddressCountryCodeKey);
NSMutableDictionary *add_field = [[NSMutableDictionary alloc] init];
[add_field setValue:street forKey:#"street"];
[add_field setValue:city forKey:#"city"];
[add_field setValue:state forKey:#"state"];
[add_field setValue:postal forKey:#"postal"];
[add_field setValue:country forKey:#"country"];
[add_field setValue:country_id forKey:#"country_id"];
// NSLog(#"Address = %#",add_field);
[arry_address addObject:add_field];
}
contacts.arrAddress = arry_address;
//get Contact email
NSMutableArray *contactEmails = [NSMutableArray new];
ABMultiValueRef multiEmails = ABRecordCopyValue(person, kABPersonEmailProperty);
for (CFIndex i=0; i<ABMultiValueGetCount(multiEmails); i++) {
CFStringRef contactEmailRef = ABMultiValueCopyValueAtIndex(multiEmails, i);
NSString *contactEmail = (__bridge NSString *)contactEmailRef;
[contactEmails addObject:contactEmail];
// NSLog(#"All emails are:%#", contactEmails);
}
contacts.arrEmails = contactEmails;
[items addObject:contacts];
//NSLog(#"Person is: %#", contacts.firstNames);
//NSLog(#"Phones are: %#", contacts.numbers);
//NSLog(#"Email is:%#", contacts.emails);
}
return items;
} else {
NSLog(#"Cannot fetch Contacts :( ");
return NO;
}
}

IOS::How to get the contact number from ABAddressBook

Phone number getting like this.
Phone ABMultiValueRef 0x17674380 with 1 value(s)
0: $!!$ (0x176740e0) - 7124779070 (0x176742a0)
How to get this number"7124779070" from the above line.
I'm using this code for ios 7.Is it correct or wrong ,Please sugggest me.
int i;
ABAddressBookRef contactBook = ABAddressBookCreateWithOptions(NULL, NULL);
NSMutableArray *allData = ( NSMutableArray *)(ABAddressBookCopyArrayOfAllPeople(contactBook));
CFIndex contactNum = CFArrayGetCount((__bridge CFArrayRef)(allData));
for (i = 0; i < contactNum; i++)
{
ABRecordRef ref = CFArrayGetValueAtIndex((__bridge CFMutableArrayRef)(allData), i);
NSString* firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
NSString* lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
NSString* phonesNum = ABRecordCopyValue(ref, kABPersonPhoneProperty);
// Remove all formatting symbols that might be in both phone number being compared
NSCharacterSet *toExclude = [NSCharacterSet characterSetWithCharactersInString:#"/.()- "];
phonesNum = [[phonesNum componentsSeparatedByCharactersInSet:toExclude] componentsJoinedByString: #""];
NSString *phoneNumber = [[phonesNum componentsSeparatedByCharactersInSet:toExclude] componentsJoinedByString: #""];
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
if (firstName!=nil)
{
[dic setObject:(__bridge id)(firstName) forKey:#"firstName"];
}
if (lastName !=nil) {
[dic setObject:(__bridge id)(lastName) forKey:#"lastName"];
}
if (phonesNum!=nil) {
[dic setObject:(__bridge id)(phonesNum) forKey:#"phonesNum"];
}
[arr_Contacts addObject:dic];
NSLog(#"First name %#", firstName);
NSLog(#"Last Name %#", lastName);
NSLog(#"Phone %#", phonesNum);
}
First, request permission:
ABAuthorizationStatus status = ABAddressBookGetAuthorizationStatus();
if (status != kABAuthorizationStatusAuthorized && status != kABAuthorizationStatusNotDetermined) {
// tell user to enable contacts in privacy settings
NSLog(#"You previously denied access: You must enable access to contacts in settings");
return;
}
CFErrorRef error = NULL;
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, &error);
if (!addressBook) {
NSLog(#"ABAddressBookCreateWithOptions error: %#", CFBridgingRelease(error));
return;
}
ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
if (error) {
NSLog(#"ABAddressBookRequestAccessWithCompletion error: %#", CFBridgingRelease(error));
}
if (granted) {
[self getContacts:addressBook];
} else {
// tell user to enable contacts in privacy settings
NSLog(#"You just denied access: You must enable access to contacts in settings");
}
CFRelease(addressBook);
});
Second, to retrieve the phone numbers, use ABMultiValueCopyValueAtIndex:
- (void)getContacts:(ABAddressBookRef)addressBook
{
NSArray *allData = CFBridgingRelease(ABAddressBookCopyArrayOfAllPeople(addressBook));
NSInteger contactCount = [allData count];
for (int i = 0; i < contactCount; i++) {
ABRecordRef person = CFArrayGetValueAtIndex((__bridge CFArrayRef)allData, i);
NSString *firstName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonFirstNameProperty));
NSString *lastName = CFBridgingRelease(ABRecordCopyValue(person, kABPersonLastNameProperty));
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
if (firstName) {
dictionary[#"firstName"] = firstName;
}
if (lastName) {
dictionary[#"lastName"] = lastName;
}
ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
CFIndex phoneNumberCount = ABMultiValueGetCount(phones);
if (phoneNumberCount > 0) {
NSString *phone = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, 0));
dictionary[#"phone"] = phone;
}
// or if you wanted to iterate through all of them, you could do something like:
//
// for (int j = 0; j < phoneNumberCount; j++) {
// NSString *phone = CFBridgingRelease(ABMultiValueCopyValueAtIndex(phones, j));
//
// // do something with `phone`
// }
if (phones) {
CFRelease(phones);
}
[arr_Contacts addObject:dictionary];
}
}
A couple of additional issues addressed above:
The ABAddressBookCreateWithOptions does not return a mutable array. It's an immutable array. Replace all of those mutable references with immutable.
You must honor the Create Rule, namely that you're responsible for releasing any object returned from a Core Foundation method with either Create or Copy in its name. If the object supports toll-free bridging (e.g. the array of contacts, the first name string, the last name string, etc.), you can transfer ownership to ARC with CFBridgingRelease or __bridge_transfer. If the object doesn't support toll-free bridging (such as the phones or addressBook objects, above), then you must explicitly call CFRelease for the object in question.
Make sure to run your code through the static analyzer (shift+command+B, or choose "Analyze" from Xcode's "Product" menu), and it will identify these sorts of issues for you.
If a function, such as ABAddressBookCreateWithOptions offers an error parameter, you should avail yourself of it. I illustrate the proper use of the CFErrorRef object above.
What do you recive in console from Phone %# NSLog ? if Phone ABMultiValueRef 0x17674380 with 1 value(s) 0: $!!$ (0x176740e0) - 7124779070 (0x176742a0)just substring after '-'
NSString *myString = #"Phone ABMultiValueRef 0x17674380 with 1 value(s) 0: $!!$ (0x176740e0) - 7124779070 (0x176742a0)";
NSArray *myArray = [myString componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:#"-"]];
and this is my method to get phone's
- (void) getContacts
{
NSMutableDictionary *response = [[NSMutableDictionary alloc] init];
ABAddressBookRef contactBook = ABAddressBookCreateWithOptions(NULL, NULL);
arr_Contacts = [[NSMutableArray alloc] init];
ABAddressBookRef allPeople = contactBook;
CFArrayRef allContacts = ABAddressBookCopyArrayOfAllPeople(allPeople);
CFIndex numberOfContacts = ABAddressBookGetPersonCount(allPeople);
NSLog(#"contact == %#",allContacts);
NSLog(#"numberOfContacts------------------------------------%ld",numberOfContacts);
for(int i = 0; i < numberOfContacts; i++){
NSString* name = #"";
NSString* phone = #"";
NSString* email = #"";
ABRecordRef aPerson = CFArrayGetValueAtIndex(allContacts, i);
ABMultiValueRef fnameProperty = ABRecordCopyValue(aPerson, kABPersonFirstNameProperty);
ABMultiValueRef lnameProperty = ABRecordCopyValue(aPerson, kABPersonLastNameProperty);
ABMultiValueRef phoneProperty = ABRecordCopyValue(aPerson, kABPersonPhoneProperty);\
ABMultiValueRef emailProperty = ABRecordCopyValue(aPerson, kABPersonEmailProperty);
NSArray *emailArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(emailProperty);
NSArray *phoneArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneProperty);
if (fnameProperty != nil) {
name = [NSString stringWithFormat:#"%#", fnameProperty];
}
if (lnameProperty != nil) {
name = [name stringByAppendingString:[NSString stringWithFormat:#" %#", lnameProperty]];
}
if ([phoneArray count] > 0) {
if ([phoneArray count] > 1) {
for (int i = 0; i < [phoneArray count]; i++) {
phone = [phone stringByAppendingString:[NSString stringWithFormat:#"%#, ", [phoneArray objectAtIndex:i]]];
}
}else {
phone = [NSString stringWithFormat:#"%#", [phoneArray objectAtIndex:0]];
}
}
if ([emailArray count] > 0) {
if ([emailArray count] > 1) {
for (int i = 0; i < [emailArray count]; i++) {
email = [email stringByAppendingString:[NSString stringWithFormat:#"%#\n", [emailArray objectAtIndex:i]]];
}
}else {
email = [NSString stringWithFormat:#"%#", [emailArray objectAtIndex:0]];
}
}
NSLog(#"NAME : %#",name);
NSLog(#"PHONE: %#",phone);
NSLog(#"EMAIL: %#",email);
NSLog(#"\n");
[response setObject:name forKey:#"name"];
[response setObject:phone forKey:#"phone"];
[response setObject:email forKey:#"email"];
[arr_Contacts addObject:response];
}
}
Cheers

How to generate ds:X509Certificate value from .p12 in Objective-C?

I've a private key file .p12.
I'm using Objective-C.
I need to generate Signed digital signature XML like this:
The problem is, I cannot find out how to generate the value in <ds:X509Certificate>. I know it is a public key base64 encoded. But, I can't get the same string after testing various encoding methods..
Need your help!
Found the solution myself. It is so easy.
Using Apple's security.framework:
NSString* pfile = [[NSBundle mainBundle] pathForResource:#"rsa_user" ofType:#"p12" ];
// Load Certificate
NSData *p12data = [NSData dataWithContentsOfFile:pfile];
CFDataRef inP12data = (__bridge CFDataRef)p12data;
SecIdentityRef myIdentity;
SecTrustRef myTrust;
extractIdentityAndTrust(inP12data, &myIdentity, &myTrust);
SecCertificateRef myCertificate;
SecIdentityCopyCertificate(myIdentity, &myCertificate);
NSData *certificateData = (__bridge NSData *) SecCertificateCopyData(myCertificate);
// Output certificate base64 value. (This value goes to <ds:X509Certificate> tag )
NSLog(#"%#", [certificateData base64EncodedString]);
// Helper function
OSStatus extractIdentityAndTrust(CFDataRef inP12data, SecIdentityRef *identity, SecTrustRef *trust)
{
OSStatus securityError = errSecSuccess;
CFStringRef password = CFSTR("password");
const void *keys[] = { kSecImportExportPassphrase };
const void *values[] = { password };
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
securityError = SecPKCS12Import(inP12data, options, &items);
if (securityError == 0) {
CFDictionaryRef myIdentityAndTrust = CFArrayGetValueAtIndex(items, 0);
const void *tempIdentity = NULL;
tempIdentity = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemIdentity);
*identity = (SecIdentityRef)tempIdentity;
const void *tempTrust = NULL;
tempTrust = CFDictionaryGetValue(myIdentityAndTrust, kSecImportItemTrust);
*trust = (SecTrustRef)tempTrust;
}
if (options) {
CFRelease(options);
}
return securityError;
}