Hey there, I am working on a multiplatform project...
# kotlin-native
c
Hey there, I am working on a multiplatform project (android and iOS) and currently dealing with crypto operation on iOS. Thanks to @olonho I managed create an RSA key via
SecKeyCreateRandomKey
and `CFBridgingRetain`:
Copy code
val privateKeyRef = SecKeyCreateRandomKey(cfKeyGenerationAttributes, error.ptr)
println("Key generated: ${CFBridgingRelease(privateKeyRef)} ")
This works nicely. When I try to retrieve my key at later date I have either crashes or the key is not found. I suspect this is due to how I define the application data string tag in my dictionary:
Copy code
CFDictionaryAddValue(cfKeyGenerationAttributes,kSecAttrApplicationTag,CFBridgingRetain(keyAlias.wcstr.ptr))
I tried few combination but I never seem to be able to retrieve the key that is successfully created: it is either crashing or saying that the key is not found. What is the proper way to pass a string to the dictionary and overall to Kotlin Native for Object C?
o
Hmm, the way how you use retain operation on raw string pointer (.wcstr.ptr) look wrong - this operation returns pointer to C style string, so reference counter operations doesn’t make sense
c
Sorry that was the last of my attempt
I tried with, without, with cstr instead. MAybe I should try to cast a Kotlin String into a NString?
o
Please post the whole code
c
RSA generation:
Copy code
val cfKeyGenerationAttributes = CFDictionaryCreateMutable(null, 0, null, null)
CFDictionaryAddValue(cfKeyGenerationAttributes, kSecAttrKeyType, kSecAttrKeyTypeRSA)
CFDictionaryAddValue(cfKeyGenerationAttributes, kSecAttrKeySizeInBits, CFBridgingRetain(NSNumber(int = rsaSpec.keyLength)))
CFDictionaryAddValue(cfKeyGenerationAttributes, kSecAttrIsPermanent, CFBridgingRetain(shouldBePersisted))
CFDictionaryAddValue(cfKeyGenerationAttributes, kSecAttrApplicationTag, keyAlias.cstr)

val error = alloc<CFErrorRefVar>()
val privateKeyRef = SecKeyCreateRandomKey(cfKeyGenerationAttributes, error.ptr)
println("Private Key generated: ${CFBridgingRelease(privateKeyRef)} ")

val publicKeySecRef = SecKeyCopyPublicKey(privateKeyRef)
println("Public Key generated: ${CFBridgingRelease(publicKeySecRef)} ")
RSA retrieval:
Copy code
val cfKeyQueryAttributes = CFDictionaryCreateMutable(null, 0, null, null)
CFDictionaryAddValue(cfKeyQueryAttributes, kSecClass, kSecClassKey)
CFDictionaryAddValue(cfKeyQueryAttributes, kSecAttrKeyType, kSecAttrKeyTypeRSA)
CFDictionaryAddValue(cfKeyQueryAttributes, kSecAttrApplicationTag, keyAlias.cstr)
CFDictionaryAddValue(cfKeyQueryAttributes, kSecReturnRef, CFBridgingRetain(true))

val secKeyRef = alloc<CFTypeRefVar>()
val status = SecItemCopyMatching(cfKeyQueryAttributes, secKeyRef.ptr)
val errMsg = CFBridgingRelease(SecCopyErrorMessageString(status, null))
println("status is: ${errMsg!!}")
This produces a segmentation fault Everytime, every attempt, the error is when
SecItemCopyMatching
is called. Generation displays the messages I did several different attempts where I change how the alias is used for both generation and retrieval: - with
val cfString: CFStringRef = CFBridgingRetain(keyAlias)!!.reinterpret()
SecItemCopyMatching
produces:
No keychain is available. You may need to restart your computer.
- with
CFBridgingRetain(keyAlias.cstr)
SecItemCopyMatching
produces
One or more parameters passed to a function were not valid
s
CFBridgingRetain(keyAlias)
seems to be correct. Have you tried writing the same code in Swift?
c
Does that work for you?
I haven't tried in Swift yet. maybe I should do that
s
I haven’t tried, but this seems to be correct according to framework documentation and Kotlin/Native rules for importing Objective-C.
c
I have chatted with some iOS people and they say that for keychain related unit test they need attached the unit test to a host Application (something you can do through XCode)
Do you know if there will be a way to generate the framework and attach it to an host app ?
235 Views