Hello, my main project uses Objective-C, so my code here is in Objective-C as well, but feel free to provide examples in Swift—I can translate them into Objective-C myself.
I am able to obtain both SecCertificateRef and SecKeyRef without any issues. However, my problem lies in the next step, where I need to use them to generate a SecIdentityRef. I attempted to follow the suggestions found online to store SecCertificateRef and SecKeyRef in the keychain and then retrieve the SecIdentityRef, but this approach failed, as shown in the demo in my email, or in the example below.
SecCertificateRef certificateRef = [self certificateRef]; // get it not null
SecKeyRef privateKeyRef = [self privateKeyRef]; // get it not null too
NSString *privateTag = @"yc_clinet_pri_tag";
NSString *certTag = @"yc_clinet_cert_tag";
NSMutableDictionary * privateKeyAttr = [[NSMutableDictionary alloc] init];
[privateKeyAttr setObject:(id)kSecClassKey forKey:(id)kSecClass];
[privateKeyAttr setObject:(id)kSecAttrKeyTypeEC forKey:(id)kSecAttrKeyType];
[privateKeyAttr setObject:privateTag forKey:(id)kSecAttrLabel];
[privateKeyAttr setObject:privateTag forKey:(id)kSecAttrApplicationTag];
[privateKeyAttr setObject:(__bridge id _Nonnull)(privateKeyRef) forKey:(id)kSecValueRef];
[privateKeyAttr setObject:(id)kSecAttrKeyClassPrivate forKey:(id)kSecAttrKeyClass];
[privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnPersistentRef];
[privateKeyAttr setObject:(__bridge id)kSecAttrAccessibleAfterFirstUnlock forKey:(id)kSecAttrAccessible];
OSStatus privateKeyAttrCheck = SecItemAdd((CFDictionaryRef) privateKeyAttr, nil);
NSString *priKeyMsg = (__bridge_transfer NSString *)SecCopyErrorMessageString(privateKeyAttrCheck, NULL) ?: [NSString stringWithFormat:@"%d", (int)privateKeyAttrCheck];
NSLog(@"query privateKey: %@", priKeyMsg);
if ((privateKeyAttrCheck != noErr) && (privateKeyAttrCheck != errSecDuplicateItem)){
return nil;
}
NSMutableDictionary * queryCertificate = [[NSMutableDictionary alloc] init];
[queryCertificate setObject:(id)kSecClassCertificate forKey:(id)kSecClass];
[queryCertificate setObject:certTag forKey:(id)kSecAttrLabel];
[queryCertificate setObject:(__bridge id)certificateRef forKey:(id)kSecValueRef];
[queryCertificate setObject:(__bridge id)kSecAttrAccessibleAfterFirstUnlock forKey:(id)kSecAttrAccessible];
OSStatus certCheck = SecItemAdd((CFDictionaryRef)queryCertificate, nil);
NSString *certMsg = (__bridge_transfer NSString *)SecCopyErrorMessageString(certCheck, NULL) ?: [NSString stringWithFormat:@"%d", (int)certCheck];
NSLog(@"query certificate: %@", certMsg);
if ((certCheck != noErr) && (certCheck != errSecDuplicateItem)) {
return nil;
}
SecIdentityRef identityRef = NULL;
NSMutableDictionary * queryIdentityRef = [[NSMutableDictionary alloc] init];
[queryIdentityRef setObject:(id)kSecClassIdentity forKey:(id)kSecClass];
[queryIdentityRef setObject:privateTag forKey:(id)kSecAttrApplicationTag];
[queryIdentityRef setObject:certTag forKey:(id)kSecAttrLabel];
[queryIdentityRef setObject:(id)kSecAttrKeyTypeEC forKey:(id)kSecAttrKeyType];
[queryIdentityRef setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnRef];
OSStatus identityCheck = SecItemCopyMatching((CFDictionaryRef)queryIdentityRef, (CFTypeRef *)&identityRef);
NSString *identityMsg = (__bridge_transfer NSString *)SecCopyErrorMessageString(identityCheck, NULL) ?: [NSString stringWithFormat:@"%d", (int)identityCheck];
NSLog(@"query identity: %@", identityMsg); // here print null
if (identityCheck != noErr) {
return nil;
}
return identityRef;
please help
Topic:
App & System Services
SubTopic:
Networking
Tags: