Сбой в расширении Firefox с использованием NSS

Я новичок в разработке расширений Firefox.

У нас есть расширение firefox, которое подписывает PDF (инкапсулированная подпись), работающее для всех версий firefox до 22 (22 не включено) с использованием NSS 3.12. После этой версии Firefox в используемом им NSS есть модификация. Это расширение представляет собой расширение JS, вызывающее функции C++ с использованием ctypes.

Моя цель - заставить это расширение работать с версией Firefox выше 22.

Я получил в своих библиотеках расширений nspr4.dll, nss3.dll, nssutil3.dll, plc4.dll, plds4.dll, созданные с помощью сборки mozilla из выпуска NSS.

код, который мы получили, очень похож на тот, что вы можете найти здесь: https://github.com/metajack/nss/blob/master/cmd/p7sign/p7sign.c

код работает хорошо (он успешно получает информацию о сертификатах, создает SEC_PKCS7ContentInfo с помощью SEC_PKCS7CreateSignedData(...), устанавливает его содержимое с помощью SEC_PKCS7SetContent(..), включает цепочки сертификатов) до вызова SEC_PKCS7Encode. при использовании этого метода происходит сбой fireFox.

Я использовал WinDBG для получения трассировки стека и вот что у меня получилось:

*******************************************************************************
*                                                                             *
*                           Exception Analysis                                *
*                                                                             *
*******************************************************************************


FAULTING_IP: 
plds4!PL_HashTableLookupConst+c
721b1c7c 8b4f0c          mov     ecx,dword ptr [edi+0Ch]

EXCEPTION_RECORD:  ffffffffffffffff -- (.exr 0xffffffffffffffff)
.exr 0xffffffffffffffff
ExceptionAddress: 00000000721b1c7c (plds4!PL_HashTableLookupConst+0x000000000000000c)
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 0000000000000000
   Parameter[1]: 000000000000000c
Attempt to read from address 000000000000000c

CONTEXT:  0000000000000000 -- (.cxr 0x0;r)
.cxr 0x0;r
eax=063e7b90 ebx=00000000 ecx=dd4c128b edx=063e7c98 esi=063e7b90 edi=00000000
eip=721b1c7c esp=0067c1e8 ebp=063e7898 iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00210206
plds4!PL_HashTableLookupConst+0xc:
721b1c7c 8b4f0c          mov     ecx,dword ptr [edi+0Ch] ds:002b:0000000c=????????
.cxr

FAULTING_THREAD:  00000000000016cc

PROCESS_NAME:  firefox.exe

ERROR_CODE: (NTSTATUS) 0xc0000005 - L

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - L

EXCEPTION_PARAMETER1:  0000000000000000

EXCEPTION_PARAMETER2:  000000000000000c

READ_ADDRESS:  000000000000000c 

FOLLOWUP_IP: 
plds4!PL_HashTableLookupConst+c
721b1c7c 8b4f0c          mov     ecx,dword ptr [edi+0Ch]

APPLICATION_VERIFIER_FLAGS:  0

APP:  firefox.exe

ANALYSIS_VERSION: 6.3.9600.17029 (debuggers(dbg).140219-1702) amd64fre

BUGCHECK_STR:  APPLICATION_FAULT_NULL_CLASS_PTR_READ_ZEROED_STACK

PRIMARY_PROBLEM_CLASS:  NULL_CLASS_PTR_READ

DEFAULT_BUCKET_ID:  NULL_CLASS_PTR_READ

LAST_CONTROL_TRANSFER:  from 00000000716b9231 to 00000000721b1c7c

STACK_TEXT:  
WARNING: Stack unwind information not available. Following frames may be wrong.
0067c1f4 716b9231 00000000 063e7b90 063e7ca0 plds4!PL_HashTableLookupConst+0xc
00000000 00000000 00000000 00000000 00000000 nssutil3!SECOID_FindOIDTag_Util+0x11


STACK_COMMAND:  .cxr 0x0 ; kb

SYMBOL_STACK_INDEX:  0

SYMBOL_NAME:  plds4!PL_HashTableLookupConst+c

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: plds4

IMAGE_NAME:  plds4.dll

DEBUG_FLR_IMAGE_TIMESTAMP:  53a04c1e

FAILURE_BUCKET_ID:  NULL_CLASS_PTR_READ_c0000005_plds4.dll!PL_HashTableLookupConst

BUCKET_ID:  
APPLICATION_FAULT_NULL_CLASS_PTR_READ_ZEROED_STACK_plds4!PL_HashTableLookupConst+c

ANALYSIS_SOURCE:  UM

FAILURE_ID_HASH_STRING:                          um:null_class_ptr_read_c0000005_plds4.dll!pl_hashtablelookupconst

FAILURE_ID_HASH:  {2f7bb160-6820-dd99-35e3-03bb56e8aca4}

Followup: MachineOwner
---------

Это означает, что при вызове SEC_PKCS7Encode вызывается метод в PLDS4.DLL, вызывающий сбой Firefox.

Я попытался вызвать SEC_PKCS7Encode, используя пустой SEC_PKCS7ContentInfo (с SEC_PKCS7CreateData()), и это не привело к сбою. Он падает только при заполнении SEC_PKCS7ContentInfo.

После некоторых исследований я обнаружил эту проблему: https://bugzilla.mozilla.org/show_bug.cgi?id=702307 Я не знаю, является ли эта проблема причиной сбоя моего Firefox.

Пробовал использовать разные версии NSS (3.12, 3.15, 3.16.2) результаты точно такие же.

Есть ли способ избежать этой проблемы? есть ли способ закодировать мой SEC_PKCS7ContentInfo без использования SEC_PKCS7Encode?

заранее спасибо.

РЕДАКТИРОВАТЬ 07.11.2014

Как упоминалось в ответе nmaier, проблема, по-видимому, заключается в использовании двух разных NSS (даже если это одна и та же версия nss, потому что, например, версия в Mozilla имеет разные зависимости).

Подпись (и другие процессы) выполняются в проекте C++ (Dll, используемая моим расширением, создается из этого проекта с помощью Visual Studio 2013). Но для компиляции и сборки DLL в проекте должны быть NSS-либы и инклюзы (это вполне нормально, я в своем проекте использую NSS-методы). Главный вопрос заключается в том, как я могу ссылаться на библиотеки MOZILLA FIREFOX NSS и включать их. Я скомпилировал NSS той же версии NSS Firefox, но зависимости разные. Я также пытался получить исходники FireFox и скомпилировать его NSS со сборкой Mozilla, но получил ошибки. Если бы я мог получить библиотеки NSS для Firefox, я мог бы просто загрузить dll NSS для Firefox в свое расширение.

Как я могу ссылаться на библиотеки NSS Mozilla firefox в моем проекте C++ для создания моей собственной DLL с использованием правильных библиотек?


person brosini    schedule 04.07.2014    source источник
comment
Вы, конечно, имеете в виду C функции, а не C++ функции (ctypes не поддерживает последние)?   -  person nmaier    schedule 04.07.2014


Ответы (2)


Я ожидаю, что это будет вести себя неправильно: Firefox уже загружает nss и зависимые библиотеки. Попытка снова загрузить «ту же» DLL, но в другой версии, заставит загрузчик DLL разрешать зависимый импорт, используя экспорт из изначально загруженной DLL, поставляемой с Firefox, а не ваши копии более старых версий той же DLL. И эта смесь нового и старого материала затем ломается и падает.

Вам следует:

  • Не создавать и отправлять библиотеки DLL в первую очередь...
  • но используйте библиотеки DLL, которые уже поставляются с Firefox. (например, см. WeaveCrypto.js)
  • Обновите вызовы ctypes, если используемый им nss API за это время изменился.
  • Убедитесь, что ваши ctypes декларации верны и актуальны.
person nmaier    schedule 04.07.2014
comment
Спасибо за ваш ответ. На самом деле у меня уже есть проект C++, который использует NSS и выполняет все процессы, которые я хочу. Моя IDE — это Visual Studio 2010. Проблема в том, что я не знаю, как ссылаться на Firefox NSS в моем проекте, который генерирует DLL. Он принимает только NSS-библиотеки, включенные в мой проект, поэтому я могу ссылаться только на домашнюю сборку NSS (со сборкой Mozilla) (у меня нет библиотек и включений библиотеки NSS, встроенной в firefox). - person brosini; 11.07.2014
comment
Я не уверен, что понял это... У вас есть собственная DLL, которая связывает библиотеки nss. И ctypes будет взаимодействовать с этой пользовательской DLL, но не напрямую с библиотеками nss? - person nmaier; 11.07.2014
comment
Точно, пользовательская DLL выполняет весь процесс подписи и специфики, вызывая NSS, но для создания этой DLL я должен ссылаться в Visual Studio (мой инструмент сборки) на библиотеки NSS. - person brosini; 11.07.2014

Я это сделал.

Чтобы указать NSS firefox в моем проекте, мне пришлось собрать весь Firefox с помощью инструмента сборки mozilla, а затем восстановить библиотеки и включить их в каталог OBJ.

это сгенерирует мой проект как DLL, которая ссылается на хорошую версию DLL.

(Я думаю, что это не самое лучшее решение, так как между Firefox 21 и 22 есть изменение NSS NSS, поэтому мое решение будет работать только для Firefox между 22 и следующей версией Firefox, которая включает изменения NSS.)

person brosini    schedule 21.07.2014
comment
Спасибо, что поделился :) - person Noitidart; 21.07.2014