2015-09-21 6 views
2

Я преобразовываю часть моего старого кода Objective-C в Swift, чтобы я мог отойти от некоторых устаревших методов, но я продолжаю получать сбой, и до сих пор я не могу понять, что вызывает его , Я получаю закрытый ключ от сертификата P12, и этот метод работает нормально, пока я не доберусь до той части, где мне действительно нужно получить словарь из CFArray, и хотя массив имеет значения в нем, приложение продолжает сбой , Вот код, который у меня есть:Проблемы с CFDictionaryRef в Swift

func privateKeyFromCertificate(p12Name: String, withPassword password: String) -> SecKeyRef { 
    let resourcePath: String = NSBundle.mainBundle().pathForResource(p12Name, ofType: "p12")! 
    let p12Data: NSData = NSData(contentsOfFile: resourcePath)! 
    let key : NSString = kSecImportExportPassphrase as NSString 
    let options : NSDictionary = [key : password] 

    var privateKeyRef: SecKeyRef? = nil 


    var items : CFArray? 


    let securityError: OSStatus = SecPKCS12Import(p12Data, options, &items) 

    let description : CFString = CFCopyDescription(items) 
    print(description) 

    if securityError == noErr && CFArrayGetCount(items) > 0 { 
     let objects : CFDictionaryRef = CFArrayGetValueAtIndex(items, 0) as! CFDictionaryRef 
     let kString : NSString = kSecImportItemIdentity as NSString 
     let identity : SecIdentityRef = CFDictionaryGetValue(objects, unsafeAddressOf(kString)) as! SecIdentityRef 
     let securityError = SecIdentityCopyPrivateKey(identity, &privateKeyRef) 
     if securityError != noErr { 
      privateKeyRef = nil 
     } 
    } 
    return privateKeyRef! 
} 

приложение продолжает врезаться прямо в заявлении, если на первой строке, где я пытаюсь получить CFDictiionaryRef от CFArray. Я добавил строку, чтобы напечатать описание CFArray как испытание и имеет значение:

<CFArray 0x7fd2d2e8c2f0 [0x10b61f7b0]>{type = mutable-small, count = 1, values = (
0 : <CFBasicHash 0x7fd2d2e8c190 [0x10b61f7b0]>{type = mutable dict, count = 3,entries => 
0 : <CFString 0x10bfdd2c0 [0x10b61f7b0]>{contents = "trust"} = <SecTrustRef: 0x7fd2d2e8ad30> 
1 : <CFString 0x10bfdd300 [0x10b61f7b0]>{contents = "identity"} = <SecIdentityRef: 0x7fd2d2e80390> 
2 : <CFString 0x10bfdd2e0 [0x10b61f7b0]>{contents = "chain"} = <CFArray 0x7fd2d2d016e0 [0x10b61f7b0]>{type = mutable-small, count = 1, values = (
0 : <cert(0x7fd2d2e8c610) s: Client (IPHONE-WebService) i:Client (IPHONE-WebService)>)}} 
+0

У меня такая же проблема :(, вы нашли решение? –

ответ

5

Я в конечном итоге изменить некоторые вещи вокруг, чтобы получить доступ к данным, это не самый красивый подход, но он работал для меня ,

func privateKeyFromCertificate() -> SecKeyRef { 
    let certName : String = //name of the certificate// 
    //get p12 file path 
    let resourcePath: String = NSBundle.mainBundle().pathForResource(certName, ofType: "p12")! 
    let p12Data: NSData = NSData(contentsOfFile: resourcePath)! 
    //create key dictionary for reading p12 file 
    let key : NSString = kSecImportExportPassphrase as NSString 
    let options : NSDictionary = [key : "password_for_certificate"] 
    //create variable for holding security information 
    var privateKeyRef: SecKeyRef? = nil 

    var items : CFArray? 

    let securityError: OSStatus = SecPKCS12Import(p12Data, options, &items) 
    //let description : CFString = CFCopyDescription(items) 
    //print(description) 

    let theArray : CFArray = items! 

    if securityError == noErr && CFArrayGetCount(theArray) > 0 { 
     let newArray = theArray as [AnyObject] as NSArray 
     let dictionary = newArray.objectAtIndex(0) 
     let secIdentity = dictionary.valueForKey(kSecImportItemIdentity as String) as! SecIdentityRef 
     let securityError = SecIdentityCopyPrivateKey(secIdentity , &privateKeyRef) 
     if securityError != noErr { 
      privateKeyRef = nil 
     } 
    } 
    return privateKeyRef! 
}