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

116

Parfois, lorsque j'exécute une application sur un appareil à partir de Xcode, j'essaie d'accéder au trousseau mais j'échoue en raison de l'erreur -34018. Cela ne correspond à aucun des codes d'erreur du trousseau documentés et ne peut pas être reproduit de manière cohérente. (cela arrive peut-être 30% du temps, et je ne sais pas pourquoi cela se produit). Ce qui rend le débogage de ce problème très difficile, c'est le manque total de documentation. Une idée de ce qui cause cela et comment y remédier? J'utilise Xcode 5 et j'exécute iOS 7.0.4 sur l'appareil.

Il y a un problème ouvert à ce sujet ici: https://github.com/soffes/sskeychain/issues/52

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

J'utilise la SSKeychainbibliothèque pour m'interfacer 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 grande majorité 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, provoquant un échec d'assertion critique.

Tony
la source
J'ai le même problème et je ne peux pas le reproduire ... J'utilise la classe KeychainItemWrapper d'Apple. Parfois, il plante de Google Analytics avec le même message d'erreur. J'utilise Google Analytics v3.02.
Joey
En outre, cela semble être OK dans l'application de l'AppStore. cela se produit uniquement dans l'application de la version de développement.
Joey
2
J'ai des crashlytics pour la version de l'App Store et malheureusement, cela semble se produire également dans l'App Store, bien que moins fréquent que sur dev: /
Tony
3
Je pense à m'éloigner du trousseau car le fait que les données stockées dans le trousseau puissent être perdues de manière aléatoire comme cela est à peu près une erreur fatale pour l'application.
Tony
2
Nous constatons également ce problème intermittent. Nous lançons une exception lorsque nous obtenons un rc inattendu de secItemCopyMatching, y compris le cas -34018. Nous avons essayé (à contrecœur) d'ajouter un mécanisme dans lequel, une fois que nous obtenons la valeur dont nous avons besoin du trousseau, nous la mettons en cache dans la mémoire de l'application, puis la servons à partir de là sans accès au trousseau. Mais maintenant, nous voyons de rares occasions où cet accès au trousseau pour l'obtenir en premier lieu échoue avec un -34018. Quelqu'un a-t-il essayé de réessayer l'opération après un -34018?
Chris Markle

Réponses:

45

Correction d'iOS 10 / XCode 8:

Ajouter un droit d'accès au porte-clés, accédez aux paramètres du projet-> Capacités-> Partage du trousseau-> Ajouter des groupes de trousseaux + Activer

Une réponse ici, d'Apple:

MISE À JOUR: Nous avons enfin pu reproduire l'erreur -34018 sur iOS 8.3. Il s'agit de la première étape pour identifier la cause première, puis pour trouver un correctif.

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 que cela soit résolu.

Plus tôt, j'ai suggéré d'ajouter un petit retard dans l'application: didFinishLaunchingWithOptions et applicationDidBecomeActive: avant d'accéder au trousseau comme 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 autre que la relance de l'application.

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

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

METTRE À JOUR

OK, voici la dernière.
C'est un problème complexe avec plusieurs causes possibles:

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

Donc, si vous voyez ce problème sur un appareil utilisateur (celui qui n'a pas été abordé par Xcode) qui exécute iOS 9.3 ou une version ultérieure, veuillez déposer un rapport de bogue à ce sujet. Essayez d'inclure le journal du système de l'appareil dans votre rapport de bogue (je me rends compte que cela peut être délicat lorsque vous traitez avec les appareils des clients; une option consiste à demander au client d'installer Apple Configurator, ce qui lui permet d'afficher le journal du système). Et si vous déposez un bogue, veuillez indiquer votre numéro de bogue, juste pour information.

Au nom d'Apple, je tiens à remercier tout le monde pour leurs efforts pour aider à traquer ce problème plutôt horrible. Partagez et appréciez

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

Daidai
la source
2
Le problème se reproduit toujours sur iOS 9.2, iPhone 5S.
DevGansta
1
Il semble qu'iOS 9.3 devrait résoudre ce problème en fonction de la dernière réponse d'Apple dans le fil de discussion que vous avez lié. @daidai, pourriez-vous mettre à jour votre réponse avec ces nouvelles informations?
jf
1
@YoonLee le voit également avec iOS10 - en utilisant également le SDK 2.4.8 d'AWS. Erreur déclenchée dans la ligne 54 d'AWSClientContext.m. Avez-vous de la chance pour résoudre ce problème?
CharlesA
1
@YoonLee btw, vient de résoudre ce problème en utilisant l'une des réponses ci-dessous: `` Le partage de KeyChain est activé pour les capacités de la cible ''
CharlesA
1
@CharlesA Oui, j'ai résolu ce jour-là. Vous avez raison. Semble être «l'activation du droit d'accès KeyChain» résout le problème. Étonnamment, cette erreur ne se déclenche pas toujours. Quoi qu'il en soit, maintenant j'allume cela.
Yoon Lee
26

Fondamentalement, vous devez coder votre dossier .xcttest en ajoutant ce qui suit en tant que 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.

JorgeDeCorte
la source
Confirmé cela corrigé dans l'environnement de test. J'ai dû ajouter le script d'exécution sur la cible de test réelle (par exemple, ceux avec tous les tests unitaires, pas la cible de construction qui s'exécute sur l'appareil). A également confirmé qu'il ne s'agissait que d'un problème sur l'appareil, pas sur le simulateur.
iwasrobbed
2
J'obtiens ": aucune identité trouvée La commande / bin / sh a échoué avec le code de sortie 1" quand je fais cela? Je suppose que je n'ai pas de $ CODE_SIGN_IDENTITY. Une idée de la façon dont je règle ce problème?
Daniel Coffman
1
@DanielCoffman, vous devez vous rendre dans vos paramètres cibles et dans Identité de signature de code sélectionnez "Développeur iOS" (ou toute autre identité valide). Cela corrige l'erreur de construction, mais au moins pour moi, cela ne résout pas le problème du trousseau. Je reçois toujours le code d'erreur -34018.
Marcin
3
Merci Marcin. J'ai commencé à recevoir cette erreur lorsque je suis passé à la version bêta de xcode 6. Aucune suggestion dans ce fil n'a été résolue. Revenu au xcode 5 et -34018 ne se produit plus.
Daniel Coffman
Je rencontre également cette erreur pour la première fois depuis que j'utilise XCode 6.3.
Vladimír Slavík
13

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 d'application).

Votre application et le processus securityd `` parlent '' ensemble grâce à une technologie appelée XPC .

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

Je suppose ici qu'il est possible que, pour une raison inconnue, le démon de sécurité ne démarre pas ou le fasse trop lentement et ne soit pas prêt lorsque vous essayez de l'utiliser.

Vous pourriez peut-être réfléchir à la manière de pré-lancer le démon.

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

Vincent Zgueb
la source
2
Je reçois ce problème uniquement lorsque mon application est rouverte via un lien profond avec la méthode de délégué d'application suivante: - (BOOL) application: (UIApplication *) application handleOpenURL: (NSURL *) url. Si je viens de démarrer l'application, l'écriture du trousseau fonctionne, et si je minimise et maximise l'application, cela fonctionne toujours. Ce n'est que lorsque je rouvre avec le lien profond que ce problème se produit. MyApp.entitlements est configuré dans mon projet (Partage de trousseau dans l'onglet Capabilities) Xcode 7 beta 4.
FranticRock
Mon cas est similaire à celui d'Alex, qui ne se produit que lorsque l'application est liée en profondeur. Sinon, ça marche bien. Peut-être qu'un contexte n'est pas correct lorsque l'application est ouverte à partir d'une autre application.
CodeBrew
12

J'observe un comportement similaire après la création et l'exécution de mon code dans Xcode 6 beta avec iOS 8 SDK (il 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 du trousseau» dans l'onglet Capacités.

Cependant, j'ai un autre problème. Je développe une bibliothèque statique, qui est utilisée par (entre autres) l'application de démonstration. La solution ci-dessus fonctionne pour le projet d'application de démonstration, mais lorsque j'essaie de tester unitaire 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 l'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.

Marcin
la source
8
Et de retour dans iOS 8 beta 3 :)
Mustafa
7
Et de retour dans iOS 9.0
Alex Stone
4
Et maintenant de retour dans iOS 9.2 :-(
Vamos
4
De retour dans iOS 10 beta 2
Pranjal Bikash Das
3
Et de retour dans iOS 10 beta 5
Pascal
6

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

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

HeTzi
la source
Étrange. Semble résoudre ce problème pour moi aussi! Chaque fois que je commençais le débogage sur le simulateur, je pouvais rencontrer le -34018 OSStatus.
midori
4

J'ai juste eu le même problème sur le simulateur exécutant 7.1 et 8.0. En creusant, j'ai remarqué que l'exemple d'application Apple avait le partage de KeyChain 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 droits que j'ai laissé avec les valeurs par défaut et maintenant je n'obtiens plus d'erreurs -34018. Ce n'est pas idéal mais je vais vivre l'option de partage KeyChain pour le moment.

Laurent
la source
4

La création de codes d'un bundle .xctest n'est pas aussi simple que cela puisse paraître dans certains cas. Principalement JorgeDeCorte a raison avec sa réponse que la ligne courte donnée en tant que Run Scriptest suffisante pour la plupart des développeurs.

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

Mais lorsque 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)"

Une solution pour obtenir le bon certificat même avec plusieurs certificats est ce court script. Bien sûr, ce 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
Patrik
la source
4

J'ai aussi été mordu par cela et je n'ai eu aucun succès avec aucune des autres solutions de contournement. J'ai ensuite nettoyé mes profils d'approvisionnement sur les appareils eux-mêmes en supprimant tous ceux liés à mon application ainsi que tous les profils génériques (cela semble être le but). Pour ce faire, allez dans la fenêtre "Appareils" dans Xcode et faites un clic droit sur votre téléphone (connecté):

Cliquez sur "Afficher les profils de provisionnement" et supprimez les profils associés, et notamment les profils d'équipe:

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

k1th
la source
Cela m'a aidé à exécuter l'application à partir de Xcode et à poursuivre le processus de développement.
salabaha
Lors de la création d'une version AdHoc, vous pouvez vérifier quels PP sont utilisés. si vous voyez des profils XC:, supprimez-les et actualisez votre PP!
dogsgod
Je peux voir comment cela pourrait être un facteur. Quel gâchis là-dedans !! Faire du nettoyage d'automne
David
3

J'ai résolu ce problème (je pense). J'avais un profil de provisionnement générique sur mon appareil qui montrait qu'il n'avait pas d'identité de signature valide. J'avais également 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 "Développeur iPhone")

Dave Hirsch
la source
Similaire à cela l'a corrigé pour moi. Définissez la signature du code au niveau du projet sur "Développeur iPhone" pour le débogage et "Distribution iPhone" pour la version. J'ai ensuite supprimé les remplacements sur la cible principale afin qu'ils affichent la même chose. Avant, l'enregistrement dans le trousseau échouait 100% du temps. Par la suite, l'enregistrement dans le trousseau semble stable.
jowie
2

Je recevais -34018 erreur dans mon application (iOS 8.4) très rarement. Après quelques recherches, j'ai constaté que ce problème se produit lorsque l'application demande trop souvent des données au trousseau .
Par exemple, dans ma situation, il s'agissait de deux demandes de lecture pour une clé spécifique en même temps à partir de différents modules d'application.
Pour résoudre ce problème, je viens d'ajouter la mise en cache de cette valeur en mémoire

somedev
la source
1

J'avais le même problème, à l'improviste, en cours d'exécution sur un appareil de test avec Xcode 6.2, iPhone 6, iOS 8.3. Pour être clair, cela ne s'est pas produit lors de l'exécution des 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 fonctionnant sur l'application elle-même, tout allait parfaitement bien jusqu'à récemment.

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

Ensuite, j'ai temporairement changé le niveau d'accessibilité de kSecAttrAccessibleAfterFirstUnlockà kSecAttrAccessibleAlwaysThisDeviceOnly, exécuté l'application, et cela a bien fonctionné et j'ai pu écrire sur le trousseau. Ensuite, je l'ai changé à nouveau kSecAttrAccessibleAfterFirstUnlocket le problème semble avoir disparu «définitivement».

Mason G. Zhwiti
la source
1

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

XCool
la source
1

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

Lumenela
la source
1

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

Commencé à obtenir l'erreur de trousseau -34018 de manière cohérente dans le simulateur après la mise à jour de Xcode de la version 7.3.1 à 8.0.

Suite à cette astuce de la réponse de daidai ,

Certaines instances du problème sont causées par une signature d'application incorrecte. Vous pouvez facilement distinguer ce cas car le problème est reproductible à 100%.

il a été découvert que Provisioning Profile avait en quelque sorte été défini sur Aucun dans les sections Signature de la cible.

Cependant, la définition des champs de profil d'approvisionnement sur des valeurs valides n'était pas suffisante 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. Il disait "Ajouter la fonction de notifications push à votre identifiant d'application". l'étape a été terminée, mais l'étape «Ajouter le droit de 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 de trousseau a été résolue.

Pour cette cible particulière, le droit «Partage de trousseau» avait déjà été activé à un moment donné. La désactivation n'a pas fait réapparaître l'erreur du trousseau jusqu'à présent, il n'est donc pas clair si cela est nécessaire dans ce cas.

jk7
la source
0

Dans iOS 9, j'ai désactivé Address Sanitizer et il a commencé à fonctionner sur l'appareil.

pulse4life
la source
0

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. Il échouerait en raison de l'erreur -34018 si j'essayais d'écraser la valeur existante. Mais tant que je stockais nil en premier, la valeur mise à jour serait stockée avec succès immédiatement après.

FranticRock
la source
0

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: 1. Suite à la solution @ k1th https://stackoverflow.com/a/33085955/889892 2. Exécutez SecItemDelete dans le thread principal (auparavant, il est lu à partir du thread principal, alors alignez-le simplement avec la suppression) .

Désolé, il revient :(

Senry
la source
0

Activez le partage de trousseau dans les capacités de votre projet, cela devrait résoudre le problème. entrez la description de l'image ici

Rizwan Ahmed
la source
0

Ce qui a fonctionné pour moi

  • Activez le partage du trousseau.
  • Utilisez le moins possible le trousseau et mettez en cache les données dans la mémoire, les préférences utilisateur, le disque, etc.
  • Réessayez plusieurs fois les opérations CRUD du trousseau en cas d'échec.
  • Utilisez DispatchQueue.sync pour stocker / supprimer / mettre à jour les données.
rockdaswift
la source
0

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

Adam Smith
la source