Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Access violation 
:(
    Опции темы
romych2004
Дата 24.8.2017, 10:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 12.9.2011

Репутация: нет
Всего: нет



Добрый день

Вопрос, возможно, глупый, но это же ветка для новичков smile

Есть некая структура в Си
Объявляется она вот так:
Код

CRYPT_SIGN_MESSAGE_PARA param;
memset(&param, 0, sizeof(CRYPT_SIGN_MESSAGE_PARA));


Далее пытаюсь установить поле rgAuthAttr для этой структуры. Объявляю его вот так:
Код

CRYPT_ATTRIBUTE ca[1];
...
param.rgAuthAttr = ca;


И далее при передаче &param в функцию CryptSignMessage вываливается ошибка Access Violation. В дебаггере до этой функции все ок, а после вызова - поле rgAuthAttr сбрасывается. При чем как-то нестабильно все.. то сбросится сразу, то сбросится со второго вызова CryptSignMessage(первый получает размер, второй вызов получает сами данные)
Если же ca объявить как указатель и выделить память malloc'ом, то все работает без ошибок

Собственно, с ошибкой-то методом тыка разобрался, все работает, но не хватает теоретических знаний, почему если не выделить память динамически, то ссылка на объект теряется?
Ну и второй вопрос в догонку, при использовании memset - память же не надо очищать? Она же просто уже выделенную заполняет?

Заранее спасибо smile
PM MAIL   Вверх
xvr
Дата 24.8.2017, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Читаем описание параметра rgAuthAttr в MSDN:
Цитата

rgAuthAttr -  Array of pointers to CRYPT_ATTRIBUTE structures, each holding authenticated attribute information. If there are authenticated attributes present, the PKCS #9 standard dictates that there must be at least two attributes present, the content type object identifier (OID), and the hash of the message itself. These attributes are automatically added by the system.
Т.е. в массиве должно быть как минимум 2 элемента, а у вас задан 1

Чтоу вас задано в cAuthAttr?
Цитата

cAuthAttr - Number of elements in the rgAuthAttr array. If no authenticated attributes are present in rgAuthAttr, this member is set to zero.


PM MAIL   Вверх
romych2004
Дата 24.8.2017, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 12.9.2011

Репутация: нет
Всего: нет



Цитата(xvr @ 24.8.2017,  13:05)
Читаем описание параметра rgAuthAttr в MSDN:
Цитата

rgAuthAttr -  Array of pointers to CRYPT_ATTRIBUTE structures, each holding authenticated attribute information. If there are authenticated attributes present, the PKCS #9 standard dictates that there must be at least two attributes present, the content type object identifier (OID), and the hash of the message itself. These attributes are automatically added by the system.
Т.е. в массиве должно быть как минимум 2 элемента, а у вас задан 1

Чтоу вас задано в cAuthAttr?
Цитата

cAuthAttr - Number of elements in the rgAuthAttr array. If no authenticated attributes are present in rgAuthAttr, this member is set to zero.

Спасибо за ответ

Два параметра, судя по описанию - для стандарта PKCS#9, мне нужен PKCS#7, по этому стандарту указание атрибута не обязательно. На саммо деле не суть важно, я пробовал выставлять вместо rgAuthAttr - rgUnauthAttr

Вот так работает:
Код

... получение param ...

CRYPT_ATTR_BLOB *cablob;
CRYPT_ATTRIBUTE *ca;

... получение cbAuth и pbAuth ...

cablob = (CRYPT_ATTR_BLOB *)malloc(sizeof(CRYPT_ATTR_BLOB));
cablob[0].cbData = cbAuth;
cablob[0].pbData = pbAuth;

ca = (CRYPT_ATTRIBUTE *)malloc(sizeof(CRYPT_ATTRIBUTE));
ca[0].pszObjId = szOID_RSA_signingTime;
ca[0].cValue = 1;
ca[0].rgValue = cablob;

param.cAuthAttr = 1;
param.rgAuthAttr = ca;


Вот так не работает:
Код

... получение param ...

CRYPT_ATTR_BLOB cablob[1];
CRYPT_ATTRIBUTE ca[1];

... получение cbAuth и pbAuth ...

cablob[0].cbData = cbAuth;
cablob[0].pbData = pbAuth;

ca[0].pszObjId = szOID_RSA_signingTime;
ca[0].cValue = 1;
ca[0].rgValue = cablob;

param.cAuthAttr = 1;
param.rgAuthAttr = ca;

*т.е. все работает, все назначается, но в функции CryptSignMessage вылетает исключение Access violation, и param.rgAuthAttr затирается(а перед вызовом там все ок)


p.s. хм, залез сейчас на msdn и заметил что структура другая, в моей структуре CRYPT_SIGN_MESSAGE_PARA (wincrypt.h) нет параметров
  CRYPT_ALGORITHM_IDENTIFIER HashEncryptionAlgorithm;
  void                       pvHashEncryptionAuxInfo;
Они только для CMS.. может ли быть в этом проблема?

Это сообщение отредактировал(а) romych2004 - 24.8.2017, 13:31
PM MAIL   Вверх
xvr
Дата 24.8.2017, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



У вас явно пишется что то за границы структур. Поэтому с malloc и 'работает' - оно просто затирает не локалы в стеке, а кучу в программе. Все равно сломается  smile 
Цитата

p.s. хм, залез сейчас на msdn и заметил что структура другая, в моей структуре CRYPT_SIGN_MESSAGE_PARA (wincrypt.h) нет параметров
А вот это проблема. А что вы пишете в поле param.cbSize ?

Добавлено через 8 минут и 11 секунд
Может у вас выходной буфер для CryptSignMessage залез на ваши структуры? Покажите весь код.

PM MAIL   Вверх
romych2004
Дата 25.8.2017, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 12.9.2011

Репутация: нет
Всего: нет



Ну примерно вот такой:
Код

HCERTSTORE hStoreHandle = CertOpenSystemStore(0, _TEXT("MY"));

PCCERT_CONTEXT pUserCert = CryptUIDlgSelectCertificateFromStore(
    hStoreHandle, 
    NULL,
    NULL,
    NULL,
    CRYPTUI_SELECT_LOCATION_COLUMN,
    0,
    NULL);

char OID[64] = szOID_CP_GOST_R3411;

CRYPT_SIGN_MESSAGE_PARA param;

memset(&param, 0, sizeof(CRYPT_SIGN_MESSAGE_PARA));
param.cbSize = sizeof(CRYPT_SIGN_MESSAGE_PARA);
param.dwMsgEncodingType = MSG_ENCODING_TYPE_DER;
param.pSigningCert = pUserCert;
param.HashAlgorithm.pszObjId = OID;
param.HashAlgorithm.Parameters.cbData = 0;
param.HashAlgorithm.Parameters.pbData = NULL;
param.pvHashAuxInfo = NULL;
param.cMsgCert = 1;    
param.rgpMsgCert = &pUserCert;
param.cAuthAttr = 0;
param.dwInnerContentType = 0;
param.cMsgCrl = 0;
param.cUnauthAttr = 0;
param.rgpMsgCrl = 0;

// добавляем время подписи

CRYPT_ATTR_BLOB cablob[1];
CRYPT_ATTRIBUTE ca[1];
LPBYTE pbAuth = NULL;
DWORD cbAuth = 0;
FILETIME fileTime;
SYSTEMTIME systemTime;

GetSystemTime(&systemTime);
SystemTimeToFileTime(&systemTime, &fileTime);

ret = CryptEncodeObject(MSG_ENCODING_TYPE_DER,
    szOID_RSA_signingTime,
    (LPVOID)&fileTime,
    NULL,
    &cbAuth);

if (!ret) return 0;

pbAuth = (BYTE*)malloc(cbAuth);
if (!pbAuth) return 0;

ret = CryptEncodeObject(MSG_ENCODING_TYPE_DER,
    szOID_RSA_signingTime,
    (LPVOID)&fileTime,
    pbAuth,
    &cbAuth);

if (!ret) return 0;

//cablob = (CRYPT_ATTR_BLOB *) malloc(sizeof(CRYPT_ATTR_BLOB));
cablob[0].cbData = cbAuth;
cablob[0].pbData = pbAuth;

//ca = (CRYPT_ATTRIBUTE *) malloc(sizeof(CRYPT_ATTRIBUTE));
ca[0].pszObjId = szOID_RSA_signingTime;
ca[0].cValue = 1;
ca[0].rgValue = cablob;

param.cAuthAttr = 1;
param.rgAuthAttr = ca;

param.dwFlags = 0;


Ну и сама подпись:

Код

int doSign(CRYPT_SIGN_MESSAGE_PARA &param, BOOL detached, BYTE *data, DWORD dataLen, BYTE **signedMem, DWORD &signedLen) {
    int ret = 0;

    DWORD messageSizeArray[1];
    const BYTE *messageArray[1];

    messageArray[0] = data;
    messageSizeArray[0] = dataLen;

    ret = CryptSignMessage(
        &param,
        detached,
        1,
        messageArray,
        messageSizeArray,
        NULL,
        &signedLen);

    if (!ret) return 0;

    *signedMem = (BYTE*)malloc(signedLen);
    if (!*signedMem) return 0;

    ret = CryptSignMessage(
        &param,
        detached,
        1,
        messageArray,
        messageSizeArray,
        *signedMem,
        &signedLen);

    if (!ret) return 0;
    return 1;
}



Это сообщение отредактировал(а) romych2004 - 25.8.2017, 13:16
PM MAIL   Вверх
xvr
Дата 25.8.2017, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Вроде криминала не видно.

В MSDN есть очень подозрительный кусок:
Цитата

rgAuthAttr -  Array of pointers to CRYPT_ATTRIBUTE structures, each holding authenticated attribute information. If there are authenticated attributes present, the PKCS #9 standard dictates that there must be at least two attributes present, the content type object identifier (OID), and the hash of the message itself. These attributes are automatically added by the system.
Судя по нему rgAuthAttr это массив указателей на структуры CRYPT_ATTRIBUTE, а не массив структур. Однако описание поля явно этому противоречит  smile 
Попробуй не подавать время (оставь поля param.cAuthAttr и param.rgAuthAttr в 0). Если перестанет ломаться - то это где то в этом районе  smile 

PM MAIL   Вверх
romych2004
Дата 25.8.2017, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 12.9.2011

Репутация: нет
Всего: нет



Пробовал, без этого все нормально smile И если динамически выделить память - все ок.. странно что так не работает, хотел понять почему smile
PM MAIL   Вверх
xvr
Дата 27.8.2017, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



А с параметром время в подпись правильно попадает? Может туда мусор заливается?

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1319 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.