Question

I am trying to create a NSURLCredential by using the +credentialWithIdentity:certificates:persistence: method. However it's returning nil.

I've done the following steps. First I create a private and public key, then generated a certificate and add it to my keychain. The first problem, when I do this:

static const uint8_t certificateIdentifier[] = "test.certificate";    
NSData * certificateTag = [NSData dataWithBytes:certificateIdentifier length:sizeof(certificateIdentifier)];
SecCertificateRef cert = SecCertificateCreateWithData(NULL, (__bridge CFDataRef) certificadoData);
NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init];
[dictionary setObject:(__bridge id)kSecClassCertificate forKey:(__bridge id)kSecClass];
[dictionary setObject:certificateTag forKey:(__bridge id)kSecAttrApplicationTag];
[dictionary setObject:(__bridge id)(cert) forKey:(__bridge id<NSCopying>)(kSecValueRef)];
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)dictionary, NULL);

The status tell me that my certificateTag is an invalid argument. If I don't put this tag and I can put the certificate on my keychain, then inside the method

(void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge

I put

SecIdentityRef myIdentity;
SecCertificateRef myCertificate;

NSMutableDictionary * queryCertificate = [[NSMutableDictionary alloc] init];
[queryCertificate setObject:(__bridge id)kSecClassIdentity forKey:(__bridge id)kSecClass];
[queryCertificate setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];

OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)queryCertificate, (CFTypeRef *)&myIdentity);

status = SecIdentityCopyCertificate(myIdentity, &myCertificate);

const void *certs[] = { myCertificate };
CFArrayRef certsArray = CFArrayCreate(NULL, certs, 1, NULL);
NSURLCredential *credential = [NSURLCredential credentialWithIdentity:myIdentity certificates:(__bridge NSArray*)certsArray persistence:NSURLCredentialPersistencePermanent];

[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];

I got the identity and certificate right, but the credential keeps returning nothing, not an error, just null. Any idea why?

Was it helpful?

Solution

In the first part of my question, I was trying to add a kSecAttrApplicationTag in a kSecClassCertificate, but the kSecAttrApplicationTag is only accepted in kSecClassKey.

In the second part, the result of the credential (<NSURLCredential: 0x1e20d140>: (null)) was right, this "null" doesn't means that the value is actually null. Keeping this way my code work fine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top