Below is my code, which used to work fine till iOS 9.
- (NSData *)encryptWithDataPublicKey:(NSString*)data keyTag:(NSString*)tag { SecKeyRef publicKey = NULL; NSData *publicTag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]]; NSMutableDictionary *queryPublicKey = [[NSMutableDictionary alloc] init]; [queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass]; [queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag]; [queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; [queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef]; OSStatus status = SecItemCopyMatching ((__bridge CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKey); NSData *encodedData = nil; if (status == noErr && publicKey) { NSData *dataToEncrypt = [data dataUsingEncoding:NSUTF8StringEncoding]; encodedData = [self encryptData:dataToEncrypt withKeyRef:publicKey]; CFRelease(publicKey); } return encodedData; }
This method used to work fine till iOS 9.x, But today when I have updated my XCode to 8 and run on iOS 10 device. Application is getting crashed at
CFRelease(publicKey).
Before crashing below is the log from console.
could not load any Objective-C class information. This will significantly reduce the quality of type information available
Could not able to get the issue exactly.
When I enabled Zombie, and reproduce the crash. Below is the log from console.
*** -[Not A Type release]: message sent to deallocated instance 0x170225880
Thanks in advance.
I got the Issue. there is an inner method encodedData = [self encryptData:dataToEncrypt withKeyRef:publicKey];
where SecKeyRef object is getting released.
But I wonder how this worked till iOS9???????
-(NSData *)encryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{ const uint8_t *srcbuf = (const uint8_t *)[data bytes]; size_t srclen = (size_t)data.length; size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t); void *outbuf = malloc(block_size); size_t src_block_size = block_size - 11; NSMutableData *ret = [[NSMutableData alloc] init]; for(int idx=0; idx<srclen; idx+=src_block_size){ size_t data_len = srclen - idx; if(data_len > src_block_size){ data_len = src_block_size; } size_t outlen = block_size; OSStatus status = noErr; status = SecKeyEncrypt(keyRef, kSecPaddingPKCS1, srcbuf + idx, data_len, outbuf, &outlen ); if (status != 0) { ret = nil; break; }else{ [ret appendBytes:outbuf length:outlen]; } } free(outbuf); CFRelease(keyRef); return ret; }