Подтвердить что ты не робот

Действие уведомления iOS 8: "Ошибка доступа к объекту при попытке блокировки связки ключей" при доступе к цепочке ключей в "doneFinishLaunchingWithOptions"

Я наблюдаю за ошибкой keychain в консоли устройства, которую выбрал SecItemCopyMatching при действии на push-уведомление iOS 8 на заблокированном телефоне. Подробные шаги воспроизведения следующие:

  • Удалите все предыдущие версии приложения. Создайте версию приложения Appstore на устройстве. Сила покидает приложение.
  • Увеличить номер сборки и создать новую версию на устройстве. Это имитирует поток обновления приложения. Force quit the app (В реальной жизни приложение может быть убито ОС из-за давления памяти. Силовое прекращение имитирует это поведение).
  • Отправить push-уведомление для приложения, когда телефон заблокирован.
  • При заблокированном телефоне проведите пальцем влево, чтобы увидеть кнопки действий, и нажмите одну из кнопок действий.
  • Приложение проснулось, didFinishLaunchingWithOptions получает вызов, который пытается получить доступ к элементу keychain. При запуске SecItemCopyMatching в консоли устройства появляется сообщение об ошибке Access to item attempted while keychain is locked.

Полный журнал ошибок показан ниже. В последней строке отображается конкретное сообщение об ошибке приложения.

ReportCrash[32481] <Error>: task_set_exception_ports(B07, 400, D03, 0, 0) failed with error (4: (os/kern) invalid argument)
ReportCrash[32481] <Notice>: ReportCrash acting against PID 31423
diagnosticd[32258] <Error>: error evaluating process info - pid: 31423, punique: 131317
ReportCrash[32481] <Notice>: Formulating crash report for process cfprefsd[31423]
com.apple.xpc.launchd[1] (com.apple.cfprefsd.xpc.daemon[31423]) <Notice>: Service exited due to signal: Bus error: 10
My App[32480] <Error>: assertion failed: 12F70: libxpc.dylib + 71768 [B870B51D-AA85-3686-A7D9-ACD48C5FE153]: 0x7d
Unknown[32480] <Error>: 
ReportCrash[32481] <Notice>: Saved report to /Library/Logs/CrashReporter/cfprefsd_2015-07-02-150139_Xianjing-Hus-iPhone.ips
securityd[32279] <Error>:  s3dl_query_row decode genp,rowid=8099 failed (-25308): The operation couldn’t be completed. (OSStatus error -25308 - ks_crypt: e00002e2 failed to     unwrap item (class 6, bag: 0) Access to item attempted while keychain is locked.)
securityd[32279] <Error>:  securityd_xpc_dictionary_handler Okta Verify[32480] copy_matching The operation couldn’t be completed. (OSStatus error -25308 - ks_crypt:     e00002e2 failed to unwrap item (class 6, bag: 0) Access to item attempted while keychain is locked.)
My App[32480] <Error>:  SecOSStatusWith error:[-25308] The operation couldn’t be completed. (OSStatus error -25308 - Remote error : The operation couldn't be completed. (OSStatus error -25308 - ks_crypt: e00002e2 failed to unwrap item (class 6, bag: 0) Access to item attempted while keychain is locked.))

Несколько вещей:

  • Доступность элемента keychain устанавливается на kSecAttrAccessibleAlways.
  • Как видно из вышеприведенного журнала устройств, перед проблемой всегда происходит сбой процесса cfprefsd.
  • Эта проблема возникает только в сборках Appstore, а не в сборках отладки.
  • Эта проблема возникает только при попытке выполнить уведомление о заблокированном телефоне.
  • Эта проблема возникает только в том случае, когда приложение обновляется, как описано в вышеописанных этажах.
  • Поскольку я принудительно завершаю приложение, когда появляется push-уведомление, и я нажал кнопку действия, мое приложение будет запущено в фоновом режиме. didFinishLaunchingWithOptions вызывается, и внутри этого метода делегата я делаю свой доступ к keychain, который выдает ошибку.

Кто-нибудь видел подобную ошибку, и если да, то как вы решили проблему? Любая помощь приветствуется.

Обновление: прикрепление cfprefsd журнала сбоев

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Subtype: unknown at 0x00000001007d4000
Triggered by Thread:  2

Thread 0 name:  Dispatch queue: com.apple.libdispatch-manager
Thread 0:
0   libsystem_kernel.dylib          0x0000000197d88c24 kevent64 + 8
1   libdispatch.dylib               0x0000000197c6de6c _dispatch_mgr_invoke + 272
2   libdispatch.dylib               0x0000000197c5f998 _dispatch_mgr_thread + 48

Thread 1 name:  Dispatch queue: com.apple.root.default-qos.overcommit
Thread 1:
0   libsystem_kernel.dylib          0x0000000197da3984 __sigsuspend_nocancel + 8
1   libdispatch.dylib               0x0000000197c6921c _dispatch_sigsuspend + 24
2   libdispatch.dylib               0x0000000197c69200 _dispatch_sig_thread + 44

Thread 2 name:  Dispatch queue: src
Thread 2 Crashed:
0   libsystem_platform.dylib        0x0000000197e35300 _platform_memmove + 176
1   libxpc.dylib                    0x0000000197e6567c xpc_data_create + 84
2   CoreFoundation                  0x0000000185d5a9b8 -[CFPDSource acceptMessage:] + 1956
3   CoreFoundation                  0x0000000185dc0da8 __handle_synchronize_message_block_invoke103 + 172
4   CoreFoundation                  0x0000000185d57c58 __88+[CFPDSource withSourceForDomain:inContainer:user:byHost:managed:synchronously:perform:]_block_invoke_2 + 24
5   CoreFoundation                  0x0000000185d5955c __25-[CFPDSource lockedSync:]_block_invoke + 44
6   libdispatch.dylib               0x0000000197c5d950 _dispatch_client_callout + 12
7   libdispatch.dylib               0x0000000197c671e0 _dispatch_barrier_sync_f_invoke + 72
8   CoreFoundation                  0x0000000185d59520 -[CFPDSource lockedSync:] + 80
9   CoreFoundation                  0x0000000185d57c0c __88+[CFPDSource withSourceForDomain:inContainer:user:byHost:managed:synchronously:perform:]_block_invoke + 504
10  libdispatch.dylib               0x0000000197c5d950 _dispatch_client_callout + 12
11  libdispatch.dylib               0x0000000197c671e0 _dispatch_barrier_sync_f_invoke + 72
12  CoreFoundation                  0x0000000185d576fc +[CFPDSource withSourceForDomain:inContainer:user:byHost:managed:synchronously:perform:] + 364
13  CoreFoundation                  0x0000000185dc0508 handle_message + 1312
14  CoreFoundation                  0x0000000185dc081c __handle_multi_message_block_invoke_2 + 124
15  libxpc.dylib                    0x0000000197e657c0 xpc_array_apply + 76
16  CoreFoundation                  0x0000000185dc05f8 handle_message + 1552
17  CoreFoundation                  0x0000000185dbffd4 ____CFXPreferencesDaemon_main_block_invoke_5 + 132
18  libxpc.dylib                    0x0000000197e64cc8 _xpc_connection_call_event_handler + 64
19  libxpc.dylib                    0x0000000197e62bcc _xpc_connection_mach_event + 2156
20  libdispatch.dylib               0x0000000197c5da24 _dispatch_client_callout4 + 12
21  libdispatch.dylib               0x0000000197c6113c _dispatch_mach_msg_invoke + 488
22  libdispatch.dylib               0x0000000197c682d0 _dispatch_queue_drain + 2004
23  libdispatch.dylib               0x0000000197c60664 _dispatch_mach_invoke + 132
24  libdispatch.dylib               0x0000000197c6a314 _dispatch_root_queue_drain + 716
25  libdispatch.dylib               0x0000000197c6bc48 _dispatch_worker_thread3 + 104
26  libsystem_pthread.dylib         0x0000000197e3d228 _pthread_wqthread + 812
27  libsystem_pthread.dylib         0x0000000197e3ceec start_wqthread + 0
4b9b3361

Ответ 1

Эта ошибка, безусловно, вызвана попыткой доступа к элементу kSecAttrAccessibleWhenUnlocked, пока устройство все еще заблокировано. Вы можете сказать это, просто просмотрев следующую строку журнала, который вы предоставили:

securityd[32279] <Error>:  securityd_xpc_dictionary_handler Okta Verify[32480] copy_matching The operation couldn’t be completed. (OSStatus error -25308 - ks_crypt:     e00002e2 failed to unwrap item (class 6, bag: 0) Access to item attempted while keychain is locked.)

Класс 6 - kSecAttrAccessibleWhenUnlockedkSecAttrAccessibleAlways - класс 8) - см. слайд 15 эту колоду для получения более подробной информации - так что поведение, которое вы видите, ожидается.

Реальный вопрос в том, почему элемент заканчивается как kSecAttrAccessibleWhenUnlocked, пока вы думаете, что он kSecAttrAccessibleAlways. Трудно сказать, не видя больше кода и/или имея больше информации, но вот несколько вещей, которые следует учитывать:

  • Элементы связки ключей не удаляются, когда приложение удаляется - они переустанавливают/обновляют приложение. Поэтому, если более ранняя версия приложения создала элемент как kSecAttrAccessibleWhenUnlocked, он мог бы просто продолжить. Попробуйте удалить элемент и создать его снова (и проверить возвращаемые значения SecItemDelete() и SecItemAdd(), чтобы убедиться в этом).
  • Двойная проверка, что kSecAttrAccessibleAlways передается на SecItemAdd(), так что iOS не применяет значения по умолчанию самостоятельно.
  • Обратите внимание, что класс доступности должен быть передан при создании элемента (т.е. до SecItemAdd()), а не при его извлечении (т.е. не в SecItemCopyMatching()). Это очевидно, но никогда не мешает повторять.

Если ни одно из приведенных выше вопросов не поможет, разместите соответствующий код, показывающий, как создается элемент, а затем как он читается.

Ответ 2

Доступ к цепочке ключей заблокирован, когда у вас есть пароль на устройстве, и устройство заблокировано. Поэтому, если у вас есть пароль, вы не можете делать какие-либо действия с keychain из экрана блокировки.