2014-09-24 11 views
8

Ho scavato attorno ai forum Apple e SO per questo problema senza alcun risultato. Usando il KeychainItemWrapper (ARCified) di Apple, tentando di impostare l'attributo kSecAttrAccessible su qualsiasi cosa tranne il valore predefinito (kSecAttrAccessibleWhenUnlocked), si verifica un errore di asserzione da parte di SecItemUpdate che restituisce un errore.iOS8 + KeychainItemWrapper di Apple provoca un crash

KeychainItemWrapper *wrapper = [[KeyChainItemWrapper alloc] initWithIdentifier:kMyIdentifier accessGroup:nil]; 
[wrapper setObject:kMyServiceName forKey:(__bridge NSString*)kSecAttrService]; 
[wrapper setObject:kMyAccountToken forKey:(__bridge NSString*)kSecAttrAccount]; 
[wrapper setObject:(__bridge NSString*)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly forKey:(__bridge NSString*)kSecAttrAccessible]; 

Il resto dei nostri aggiornamenti portachiavi sembrano essere passare attraverso bene, ma i risultati ultima riga:

*** Assertion failure in -[KeychainItemWrapper writeToKeychain], /Users/john.hammerlund/.../KeychainItemWrapper.m:299 

L'errore di asserzione è dovuto SecItemUpdate() restituendo uno stato di -50, che sembra essere un errore generico di "parametri non validi".

L'impostazione immediata della chiave kSecAttrAccessible non ha alcun impatto, ma impostandola sul valore predefinito kSecAttrAccessibleWhenUnlocked attenua il problema (ma elimina il punto). This other question sono le uniche informazioni aggiuntive che ho trovato relative a iOS 8 che causano l'arresto anomalo di KeychainItemWrapper. Costruire su un dispositivo con iOS 7 o un simulatore su iOS 7/8 elimina il problema; è solo divampare su un dispositivo reale utilizzando iOS 8.

Aggiornamento

Ecco un'ampia panoramica del dizionario query:

{ accc = "<SecAccessControlRef: 0x1687cc70>"; acct = ...; agrp = ...; cdat = "2014-10-13 22:22:47 +0000"; desc = ""; gena = ...; labl = ""; mdat = "2014-10-13 22:34:16 +0000"; pdmn = cku; <-- kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly svce = ...; sync = 0; tomb = 0; "v_Data" = <>; }

e il parametro attributesToUpdate:

{ accc = "<SecAccessControlRef: 0x1687cc70>"; acct = ...; agrp = ...; cdat = "2014-10-13 22:22:47 +0000"; desc = ""; gena = ...; labl = ""; mdat = "2014-10-13 22:34:16 +0000"; pdmn = ak; <-- kSecAttrAccessibleWhenUnlocked svce = ...; sync = 0; tomb = 0; "v_Data" = <>; }

Ho c ha affermato che cambiando altri campi (ad es. kSecAttrService, kSecAttrAccount) hanno lo stesso effetto sui campi corrispondenti nei dizionari, ma con uno stato previsto di 0.

+1

si dovrà scaricare i 2 dizionari passati a "SecItemUpdate' in' writeToKeychain' in modo da poter vedere il problema –

+0

@John qualsiasi aggiornamento su questo? –

+0

È passato un po 'di tempo, ma grazie a @singhSan per avermi riportato a questo. Ho assunto questo è un bug di Apple, come descritto di seguito. – John

risposta

2

Ho anche avuto il problema esatto. Mi ha dato:

OSStatus errore -50 - in conflitto kSecAccess e attributi kSecAccessControl

Crashed a tutti i miei utenti di App Store subito dopo hanno aggiornato.

Lo stesso di Peter.Accompagna i dati, elimina l'elemento e lo inserisce come nuovo elemento invece di provare ad aggiornare quello esistente.

Immagino che questo sia un bug di Apple.

Ho aperto un TSI ma non mi hanno ancora contattato.

Da quello che ho capito, succede agli utenti aggiornati da iOS7 a iOS 8, dove la loro prima app è stata compilata con XCode per iOS7 (prima che iOS 8 fosse fuori), e poi su iOS8 aggiornato alla nuova app che è stata compilata con XCode su iOS8.

2

Un colpo nel buio qui:

Forse il dispositivo iOS è iCloud sincronizzazione abilitato e l'aggiunta di un l'elemento che non è specifico del dispositivo e che quindi lo rende ThisDevice, produce solo l'errore. Anche iOS8 potrebbe aver cambiato il comportamento.

Puoi provare a cambiare l'ordine degli attributi che sono impostati al portachiavi

KeychainItemWrapper *wrapper = [[KeyChainItemWrapper alloc] initWithIdentifier:kMyIdentifier accessGroup:nil]; 
[wrapper setObject:(__bridge NSString*)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly forKey:(__bridge NSString*)kSecAttrAccessible]; 
[wrapper setObject:kMyServiceName forKey:(__bridge NSString*)kSecAttrService]; 
[wrapper setObject:kMyAccountToken forKey:(__bridge NSString*)kSecAttrAccount]; 

Se questo non risolve il problema, è necessario modificare KeychainItemWrapper a guardare come questo

- (void)resetKeychainItem 
{ 
    if (!keychainItemData) 
    { 
     keychainItemData = [[NSMutableDictionary alloc] init]; 
     [keychainItemData setObject:(__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible]; 
    } 
+0

Sì, tutti i valori tranne i valori pdmn e i riferimenti accc sono gli stessi. – John

+0

Ho aggiornato la risposta. Hai provato ciò che è menzionato qui? –

+0

Ho fatto ... nessun dado. Sto scavando attraverso quel wrapper per ore e ancora non riesco a capirlo. – John

4

Ho avuto lo stesso problema. Ho finito per testare kSecAttrAccessibile e se non era quello che volevo, ho registrato il valore e gli attributi nel portachiavi in ​​variabili locali, reimpostato il portachiavi, impostato kSecAttrAccessible come desiderato e quindi impostare il valore e gli attributi nel portachiavi alle loro impostazioni originali.

+0

Grazie Peter Ci è voluto un sacco di dolore per capire il motivo del crash. Sembra che il crash provenga dalle mele. Spero che lo risolvano presto. Ho fatto lo stesso come suggerivo e ha funzionato per me + upvoted. – Allamaprabhu

+1

@peter Sto riscontrando gli stessi problemi, ho provato a reimpostare il portachiavi ma ho ancora ricevuto l'errore. Puoi per favore postare un frammento di come sei riuscito a farlo funzionare? – rmp