web-dev-qa-db-fra.com

SecItemAdd et SecItemCopyMatching retourne le code d'erreur -34018 (errSecMissingEntitlement)

Parfois, lorsque j'exécutais une application sur un périphérique à partir de Xcode, j'essayais d'accéder au trousseau, mais j'échouais à cause de l'erreur -34018. Cela ne correspond à aucun des codes d'erreur de trousseau documentés et ne peut pas être reproduit de manière cohérente. (Cela arrive peut-être 30% du temps, et je ne comprends pas pourquoi cela se produit). Ce qui rend le débogage très difficile, c’est le manque total de documentation. Une idée de ce qui cause ceci et comment le réparer? J'utilise Xcode 5 et j'utilise iOS 7.0.4 sur mon appareil.

Il existe un problème en suspens à ce sujet ici: https://github.com/soffes/sskeychain/issues/52

EDIT: Ajout du code d'accès au trousseau par demande

J'utilise la bibliothèque SSKeychain pour l'interfaçage avec le trousseau. Voici l'extrait.

#define SERVICE @"default"

@implementation SSKeychain (EXT)

+ (void)setValue:(NSString *)value forKey:(NSString *)key {
    NSError *error = nil;
    BOOL success = NO;
    if (value) {
        success = [self setPassword:value forService:SERVICE account:key error:&error];
    } else {
        success = [self deletePasswordForService:SERVICE account:key error:&error];
    }
    NSAssert(success, @"Unable to set keychain value %@ for key %@ error %@", value, key, error);
    if (!success) {
        LogError(@"Unable to set value to keychain %@", error);
    }
    LogTrace(@"Will set keychain account %@. is to nil? %d", key, value == nil);
    if (value == nil)
        LogWarn(@"Setting keychain %@ to nil!!!", key);
}

+ (NSString *)valueForKey:(NSString *)key {
    NSError *error = nil;
    NSString *value = [self passwordForService:SERVICE account:key error:&error];
    if (error && error.code != errSecItemNotFound) {
        NSAssert(!error, @"Unable to retrieve keychain value for key %@ error %@", key, error);
        LogError(@"Unable to retrieve keychain value for key %@ error %@", key, error);
    }
    return value;
}

+ (BOOL)removeAllValues {
    LogInfo(@"Completely Reseting Keychain");
    return [[self accountsForService:SERVICE] all:^BOOL(NSDictionary *accountInfo) {
        return [self deletePasswordForService:SERVICE account:accountInfo[@"acct"]];
    }];
}

@end

La plupart du temps, c'est très bien. Parfois, je rencontre des échecs d’assertion où je suis incapable d’écrire ou de lire à partir du trousseau, ce qui provoque un échec d’assertion critique. 

116
Tony

correctif iOS 10/XCode 8:

Ajouter un droit au KeyChain, Aller au projet Paramètres-> Capacités-> Partage de trousseau-> Ajouter des groupes de trousseau + Activer

Une réponse ici, de Apple: 

MISE À JOUR: Nous avons enfin été en mesure de reproduire l'erreur -34018 sur iOS 8.3. Il s’agit de la première étape dans l’identification de la cause fondamentale, suivie d’une solution.

Comme d'habitude, nous ne pouvons pas nous engager sur un calendrier de publication, mais cela a affecté de nombreux développeurs et nous voulons vraiment résoudre ce problème.

Plus tôt, j'ai suggéré d'ajouter un petit retard dans application: didFinishLaunchingWithOptions et applicationDidBecomeActive: avant d'accéder au trousseau en tant que solution de contournement. Cependant, cela ne semble pas vraiment aider. Cela signifie qu'il n'y a pas de solution de contournement connue pour le moment à part relancer l'application.

Le problème semble être lié à la pression de la mémoire, donc peut-être plus agressif dans le traitement des avertissements de mémoire peut atténuer le problème

https://forums.developer.Apple.com/thread/4743#14441

METTRE À JOUR

OK, voici le dernier.
C'est un problème complexe avec plusieurs causes possibles: 

  • Certaines occurrences du problème sont dues à une erreur signature de l'application. Vous pouvez facilement distinguer ce cas parce que le problème est 100% reproductible. 
  • Certaines occurrences du problème sont causées par un bug dans la façon dont iOS prend en charge le développement d'applications (r. 23 991 853). Débogage ceci était compliqué par le fait qu’un autre bogue dans le système d’exploitation (r .. 23 770 418) masquait son effet, ce qui signifiait que le problème ne faisait que surgir lorsque l'appareil était sous pression de la mémoire. Nous croyons en ces problèmes ont été résolus dans iOS 9.3. 
  • Nous soupçonnons qu'il peut y avoir encore plus de causes de ce problème. 

Ainsi, si vous rencontrez ce problème sur une machine utilisateur (un Auquel Xcode n’a pas parlé) et qui exécute iOS 9.3 ou une version ultérieure, s'il vous plaît faites un rapport de bogue à ce sujet. Essayez d'inclure le périphérique journal système dans votre rapport de bogue (je réalise que cela peut être délicat lorsque traiter avec les périphériques du client; une option consiste à demander au client d’installer Apple Configurator, ce qui leur permet d’afficher le journal du système). Et si vous enregistrez un bogue, veuillez indiquer votre numéro de bogue, uniquement pour le record. 

Au nom d’Apple, je voudrais remercier tout le monde pour leur efforts pour aider à traquer ce problème plutôt horrible. Partager et Prendre plaisir

https://forums.developer.Apple.com/thread/4743#126088

44
daidai

En gros, vous devez codifier votre dossier .xcttest en ajoutant ce qui suit sous forme de script d'exécution dans votre cible de test.

codesign --verify --force --sign "$CODE_SIGN_IDENTITY" "$CODESIGNING_FOLDER_PATH"

J'ai eu beaucoup d'erreurs -34018 lors du test de mon trousseau sur l'appareil et cela a réussi à le réparer.

Si le problème n'existe pas dans votre cible de test, ce n'est probablement pas la solution.

24
JorgeDeCorte

Après avoir inspecté le code source . J'ai remarqué que les fonctionnalités du trousseau sont accessibles via un démon de sécurité qui s'exécute dans son propre processus (séparé du processus de l'application).

Votre application et le processus securityd "dialoguent" ensemble grâce à une technologie appelée XPC .

Si nécessaire, le securityd est lancé via la commande launchd bien connue de XPC. Vous pouvez probablement vérifier que le démon est en cours d'exécution dans l'application Activity Monitor (bien sûr, dans Simulator) et que son processus parent est launchd. 

Mon hypothèse est qu'il est possible que, pour une raison inconnue, le démon de sécurité ne puisse pas démarrer ou le fasse trop lentement et qu'il ne soit pas prêt lorsque vous essayez de l'utiliser. 

Peut-être que vous pourriez penser à la manière de pré-lancer le démon.

Je m'excuse de ne pas être plus précis. J'espère que cela pourrait vous aider à aller plus loin dans vos enquêtes.

13
Vincent Zgueb

Je constate un comportement similaire après la création et l’exécution de mon code dans Xcode 6 beta avec iOS 8 SDK (cela fonctionne correctement avec Xcode 5/iOS 7). Dans Xcode 6, dans iOS Simulator, SecItemCopyMatching renvoie toujours -34018. Il a commencé à fonctionner après avoir activé le «partage de trousseau» dans l'onglet Capacités.

Cependant, j'ai un autre problème. Je développe une bibliothèque statique, utilisée par (entre autres) l’application de démonstration. La solution ci-dessus fonctionne pour le projet d'application Demo, mais lorsque j'essaie de tester un peu mon projet de bibliothèque statique, j'ai exactement la même erreur. Et le problème est que mon projet de bibliothèque statique n’a pas d’onglet Capabilities (car ce n’est pas l’application autonome).

J’ai essayé la solution publiée ici par JorgeDeCorte, avec la signature de code dans la cible de test, mais cela ne fonctionne pas pour moi.

12
Marcin

Essayez désactivez tous les points d'arrêt lors du lancement de l'application à partir de Xcode . Vous pourrez les activer par la suite 

(Aucune des solutions ci-dessus n'a fonctionné pour moi)

6
HeTzi

Je me suis aussi fait piquer par cela et je n’ai eu aucun succès avec les autres solutions de contournement . J'ai ensuite nettoyé mes profils de provisioning sur les périphériques lui-même en les supprimant tous en rapport avec mon application, ainsi Pour ce faire, accédez à la fenêtre "Périphériques" de Xcode et cliquez avec le bouton droit de la souris sur votre téléphone (connecté):

 

Cliquez sur "Afficher les profils d'approvisionnement" et supprimez ceux qui sont liés, et en particulier les profils d'équipe:

 

y compris ceux avec l'astérisque . Après la réinstallation de l'application, tout est revenu à la normale.

4
k1th

Je viens d'avoir le même problème sur le simulateur exécutant 7.1 & 8.0. Tout en creusant un peu, j'ai remarqué que l'application d'exemple Apple avait KeyChain Sharing activé pour ses capacités cibles. Je l'ai activé pour mon application, ce qui a entraîné la création d'un fichier de droit que j'ai laissé avec les valeurs par défaut. Désormais, je ne reçois plus d'erreur -34018. Ce n'est pas idéal, mais je vais vivre l'option de partage KeyChain pour le moment.

4
Laurent

J'ai résolu ce problème (je pense). J'avais un profil de provisioning générique sur mon appareil qui montrait qu'il n'avait pas d'identité de signature valide. J'ai également eu un profil d'approvisionnement pour mon application qui était valide. Lorsque j'ai supprimé le profil générique, j'ai cessé de recevoir les erreurs -34018.

Je me suis également assuré que l'identité de signature de code et le profil d'approvisionnement répertoriés dans la section Signature de code des paramètres de construction de la cible étaient identiques à ceux de l'application (pas celui "générique iPhone")

3
Dave Hirsch

La codification de codes pour un paquet .xctest n’est pas aussi facile que cela en a parfois l’air. En gros, JorgeDeCorte a raison avec sa réponse que la courte ligne donnée en tant que Run Script est suffisante pour la plupart des développeurs.

codesign --verify --force --sign "$CODE_SIGN_IDENTITY" "$CODESIGNING_FOLDER_PATH"

Mais si vous avez plusieurs certificats dans votre trousseau, cela échouera avec la ligne suivante

iPhone Developer: ambiguous (matches "iPhone Developer: Your Name (ABC123DEF45)" and "iPhone Developer: Your Name (123ABC456DE)"

Ce court script est une solution pour obtenir le bon certificat même avec plusieurs certificats. Bien sûr, cela n’est pas idéal, mais à ma connaissance, vous n’avez aucune chance d’obtenir le certificat que Xcode a trouvé et utilise pour signer votre .app.

echo "codesign --verify --force --sign \"$CODE_SIGN_IDENTITY\" \"$CODESIGNING_FOLDER_PATH\""
IDENTITIES=`security find-identity -v -s "Code Signing" | grep "iPhone Developer" | awk '{ print $2 }'`

for SHA in $IDENTITIES; do
    codesign --verify --force --sign $SHA "$CODESIGNING_FOLDER_PATH"
    if [ $? -eq 0 ]; then
        echo "Matching identity found: $SHA"
        exit 0
    fi
done;

exit 1
3
Patrik

J'avais très rarement -34018 erreur dans mon application (iOS 8.4). Après enquête, j'ai constaté que ce problème se produisait lorsque l'application demandait des données au trousseau trop souvent .
Par exemple, dans mon cas, il s'agissait de deux demandes de lecture simultanées pour une clé spécifique provenant de différents modules d'application.
Pour corriger cela, je viens d’ajouter la mise en cache de cette valeur en mémoire

2
somedev

Je viens de me faire avoir par ce bug sur Xcode 8 Beta 3. Activer le trousseau Le partage semble être la seule solution. 

1
XCool

J'ai eu le même problème. Corrigé en configurant le partage de trousseau.

1
lumenela

(ce n'est pas une réponse directe à la question du PO, mais pourrait aider les autres)

A commencé à obtenir systématiquement l'erreur -34018 du trousseau dans le simulateur après la mise à jour de Xcode de la version 7.3.1 à 8.0.

En suivant ce conseil de réponse de daidai

Certaines occurrences du problème sont dues à une signature d'application incorrecte. Vous pouvez facilement distinguer ce cas car le problème est reproductible à 100%. 

il a été découvert que le profil d'approvisionnement avait été défini sur Aucune dans les sections de signature de la cible.

Cependant, définir les champs du profil d'approvisionnement sur des valeurs valides ne suffisait pas pour résoudre le problème dans ce cas.

Une enquête plus approfondie a montré que le droit aux notifications push affichait également une erreur. "Ajouter la fonctionnalité de notifications Push à votre identifiant d'application" l’étape était terminée, mais l’étape "Ajouter le droit à des notifications push à votre fichier de droits" ne l’était pas.

Après avoir appuyé sur "Corriger le problème" pour résoudre le problème de notification push, l'erreur du trousseau a été résolue.

Pour cette cible particulière, le droit "Partage de trousseau" avait déjà été activé à un moment antérieur. Le désactiver n’a pas encore provoqué l’erreur de trousseau. Il n’est donc pas clair si elle est nécessaire dans ce cas.

1
jk7

J'avais le même problème, à l'improviste, sur un appareil de test avec Xcode 6.2, iPhone 6, iOS 8.3. Pour être clair, cela n'a pas été expérimenté lors de l'exécution de tests Xcode, mais plutôt lors de l'exécution de l'application réelle sur mon appareil. Dans le simulateur, tout allait bien et, si vous utilisiez l'application elle-même, tout allait bien jusqu'à récemment.

J'ai essayé toutes les suggestions que je pouvais trouver ici, telles que la suppression des profils d'approvisionnement sur mon appareil (je les ai toutes supprimées), l'activation temporaire de la fonctionnalité de partage du trousseau dans mon projet (même si nous n'en avons pas vraiment besoin), Assurez-vous que mon compte de développement dans Xcode a été totalement actualisé avec tous les certificats et profils de provisioning, etc. Rien n’a aidé.

Ensuite, j'ai temporairement modifié le niveau d'accessibilité de kSecAttrAccessibleAfterFirstUnlock à kSecAttrAccessibleAlwaysThisDeviceOnly, lancé l'application, et tout a bien fonctionné et j'ai pu écrire dans le trousseau. Ensuite, je l'ai reconverti en kSecAttrAccessibleAfterFirstUnlock, et le problème semble avoir disparu "de manière permanente".

1
Mason G. Zhwiti

Dans iOS 9, j'ai désactivé Address Sanitizer et le programme a commencé à fonctionner.

0
pulse4life

J'ai rencontré ce problème -34018 aujourd'hui lors de l'exécution de l'API SecItemDelete . Ce que j'ai fait pour résoudre ce problème est le suivant: 1. Suite à la k1ème solution https://stackoverflow.com/a/33085955/889892 2. Exécutez SecItemDelete dans le thread principal (Auparavant, il était lu depuis le thread principal, donc alignez-le simplement sur la suppression).

Désolé, ça revient encore :(

0
Senry

Pour moi, c'était un problème de signature d'application. Je suis simplement passé à l'équipe de signature appropriée dans Xcode et l'erreur ne s'est plus produite

0
Adam Smith

Ce qui a fonctionné pour moi

  • Activer le partage de trousseau.
  • Utilisez le moins possible le trousseau et mettez en cache les données en mémoire, les préférences utilisateur, le disque, etc. 
  • Réessayez plusieurs fois les opérations CRUD avec le trousseau si elles ont échoué. 
  • Utilisez DispatchQueue.sync pour stocker/supprimer/mettre à jour les données.
0
rockdaswift

Activez le partage du trousseau dans les capacités de votre projet, cela devrait résoudre le problème.  enter image description here

0
Rizwan Ahmed

La seule solution qui a fonctionné pour moi a d'abord été de stocker nil pour la clé spécifiée, puis de stocker ma nouvelle valeur avec une opération distincte. Si je tentais d'écraser la valeur existante, cela échouerait à cause de l'erreur -34018. Mais tant que je stocke nil en premier, la valeur mise à jour sera stockée avec succès immédiatement après. 

0
FranticRock