2017-02-11 9 views
0

Я пытаюсь извлечь секретный ключ моего приложения из брелка, чтобы его можно было использовать для аутентификации с сервером. Я успешно сохранил его там, но не могу его вернуть.Извлечь ключ из osx keychain

func getClientKey(){ 
    let keyValptr:UnsafeMutablePointer<UnsafeMutableRawPointer?>? 
    let lenPtr:UnsafeMutablePointer<UInt32>? = UInt32(13) //how do i do this? 
    _ = SecKeychainFindGenericPassword(nil, 
     UInt32(serviceName.characters.count), serviceName, 
     UInt32(accountName.characters.count), accountName, 
     lenPtr, keyValptr, nil) 

    print(keyValptr) 
} 

Я прокомментировал строку, с которой у меня возникают проблемы. Как получить правильный указатель для перехода в функцию? Он хочет UnsafeMutablePointer<UInt32>? (где я бы выбрал то, что значение на самом деле)

+0

'уаг Len: UInt32 = 13', а затем передать' & len' к вашей функции. – vacawama

ответ

1

Вообще, когда вы хотите передать UnsafeMutablePoiner<T>? (или UnsafeMutablePoiner<T>), вы объявляете переменную типа T (не указатель на T) и передать его в качестве параметр inout (префикс &).

Так что, в частности, ваша проблема, ваш способ прохождения keyValPtr также ошибочен.

Для параметра passwordLength: UnsafeMutablePointer<UInt32>?, вам необходимо объявить переменную типа UInt32. И для passwordData: UnsafeMutablePointer<UnsafeMutableRawPointer?>?, вам нужно объявить переменную типа UnsafeMutableRawPointer?.

И, к сожалению, во многих случаях это не может быть критической проблемой, вам необходимо рассчитать длину на основе представления UTF-8 при прохождении Swift String непосредственно до UnsafePointer<Int8>?.

Вам может понадобиться, чтобы написать что-то вроде этого:

func getClientKey() { 
    var keyVal: UnsafeMutableRawPointer? = nil 
    var len: UInt32 = 13 //<- this value is ignored though... 
    let status = SecKeychainFindGenericPassword(
     nil, 
     UInt32(serviceName.utf8.count), serviceName, //### Use `utf8.count` 
     UInt32(accountName.utf8.count), accountName, //### Use `utf8.count` 
     &len,  //### to pass `UnsafeMutablePointer<UInt32>?`, declare a variable of `UInt32`. 
     &keyVal, //### to pass `UnsafeMutablePointer<UnsafeMutableRawPointer?>?`, declare a variable of `UnsafeMutableRawPointer?`. 
     nil 
    ) 

    if status == noErr { 
     let keyData = Data(bytes: keyVal!, count: Int(len)) 
     //### As noted in the API reference of `SecKeychainFindGenericPassword`, 
     // "You should use the SecKeychainItemFreeContent function to free the memory pointed to by this parameter." 
     SecKeychainItemFreeContent(nil, keyVal) 

     print(keyData as NSData) 
     print(String(data: keyData, encoding: .utf8) ?? "?") 
    } else { 
     //You should not silently ignore erros... 
     print("Error: \(status)") 
    } 
}