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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблема с дуплексным режимом 
V
    Опции темы
romul
Дата 31.3.2008, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Доброе время суток.

Есть проблема с обновременным получением/передачей данных за один вызов функции SCardTransmit. 
Есть апплет написаный мною для карточки. Есть Java клиент (опять же мой), который вполне нормально работает с карточкой в любом режиме. Принимает и получает данные. 
Но когда я воспользовался функцией SCardTransmit из winscard.dll, то она мне вернула "error 87". 
Если я вызываю функцию апплета которая только читает данные но не возвращает в буфер, все ок - 90 00. 
Если функцию апплета которая только возвращает данные (в буфер ничего не ложу), тоже 90 00. 
Как только функция апплета использует буфер и для приема и для передачи - 87 error. 

В апплете используются самые примитивные функции получения /отдачи данных? и к тому же они отлизаны с помощью Java клиента. На них не приходится "грешить". 
Единственный момент в котором может быть трабла, SCardTransmit вызывается из дельфового компонента. Но на первый взгляд реализация вызова внушает доверие. 

Пока даже не знаю куда копать. Может быть кто-то сталкивался с такой проблемой?

Я понимаю, что вопрос на совсем по Java, но точно по Java Card-ам :)

(Прошу прощенья за дубль темы. Глючил браузер)

Это сообщение отредактировал(а) romul - 31.3.2008, 17:32
PM MAIL   Вверх
firstone
Дата 1.4.2008, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 25.9.2007
Где: Кровью залитая Св ятая Земля

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



Это не ошибка класса SCARD_ERROR.
Первое, что нужно проверить, является ли эта ошибка производной 6A87 (если конечно 87 в шестнадцатиричной системе). T.e. incorrect parameters (см. таблицу кодов ISO/IEC 7816 например здесь: http://forum.vingrad.ru/articles/topic-192...-card-iso.html)
Второе, используете ли Вы какие-либо крипто функции в самом апплете при обработке APDU?

Вы можете опубликовать здесь trace log посланных APDU?

Если это возможно, скопируйте сюда код который работает с буфером.

Это сообщение отредактировал(а) firstone - 1.4.2008, 13:50
--------------------
В программировании я конфуцианец. В жизни я либерал-демократ. В душе я буддист.Добавлено через 1 минуту и 9 секундА на самом деле я лентяй.
PM MAIL   Вверх
firstone
Дата 1.4.2008, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 25.9.2007
Где: Кровью залитая Св ятая Земля

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



Вот пример того, как происходит считывание из буфера и запись в него. Может будет helpful:
Код

    public void process(APDU apdu) {
        // Good practice: Return 9000 on SELECT
        if (selectingApplet()) {
            return;
        }

        
        bacKmacKey3.setKey(bacKeyValue, (short)0);
        
        byte[] apduBuffer = apdu.getBuffer();
        switch (apduBuffer[ISO7816.OFFSET_INS]) {
        case (byte) 0x00:
         bacMacSign.init(bacKmacKey3, Signature.MODE_SIGN);
         bacMacSign.sign(inBuff, (short)0, DATA_TO_SIGN_LENGTH, outBuff1, (short)0);
            break;
        case (byte) 0x01:
         init(bacKmacKey3, Signature.MODE_SIGN);
         sign(inBuff, (short)0, DATA_TO_SIGN_LENGTH, outBuff1, (short)0);
         break;
        default:
            // good practice: If you don't know the INStruction, say so:
            ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
        }

        short le = apdu.setOutgoing();
        if (le < (short)8) ISOException.throwIt( ISO7816.SW_WRONG_LENGTH );
        apdu.setOutgoingLength((short)8);
        for (short index = 0; index < SIGNATURE_LENGTH; index++) {
            apduBuffer[index] = outBuff1[index];
        }
        apdu.sendBytes((short)0, SIGNATURE_LENGTH);
    }

--------------------
В программировании я конфуцианец. В жизни я либерал-демократ. В душе я буддист.Добавлено через 1 минуту и 9 секундА на самом деле я лентяй.
PM MAIL   Вверх
romul
Дата 1.4.2008, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



В отдельных функциях я использую криптофункции. Но в случае моего теста я упростил все до минимума.
Вот кусочек апплета

Код

package
....
public class DemoApplet extends Applet {
...
  final static byte CHECK_INPUT_INS = (byte) 0x11;
  final static byte CMD_INPUT_INS = (byte) 0x1A;
  final static byte CMD_OUTPUT_INS = (byte) 0x1B;
..

public void process(APDU apdu) {
  switch (buffer[ISO7816.OFFSET_INS]) {
    case (byte) CHECK_INPUT_INS: checkInput(apdu); return;          // Проверка ввода/вывода
    case (byte) CMD_INPUT_INS: commandInput(apdu); return;        // Проверка ввода данных
    case (byte) CMD_OUTPUT_INS: commandOutput(apdu); return;  // Проверка вывода данных
    ...
    default: ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED);
  }
  return;
}    

// Это процедурка вычитывающая данные из буфера обмена
private byte[] getDataBytes(APDU apdu) {  
  byte[] buffer = apdu.getBuffer();
  short cntBytes = (short)(buffer[ISO7816.OFFSET_LC] & 0xFF);
  short read_count = apdu.setIncomingAndReceive();
  if (read_count != cntBytes) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  byte[] dataBytes = new byte[cntBytes];
  for (short i = 0; i < cntBytes; i++) {
    dataBytes[i] = buffer[i + ISO7816.OFFSET_CDATA];
  }
  return dataBytes; 
}

// Это собственно неработающая процедурка
private void checkInput(APDU apdu) {
  byte[] buffer = apdu.getBuffer();                    // Получаем ссылку на буфер
  byte[] testWord = getDataBytes(apdu);        // Вычитываем дынные из буфера

  short le = (short) testWord.length;                // Находим длинну полученных данных
  apdu.setOutgoing();                                       //Переводим карту в режим ответа
  apdu.setOutgoingLength((byte)le);                // Устанавливаем длину ответа (столько же сколько пришло на вход)
  for (short i = 0; i < le; i++) buffer[i] = (byte)i; // Заполняем данными от фонаря 01 02 03...
  buffer[0] = (byte) (le & 0xFF);                         // В нулевой байт данных записываем длину данных для проверки
  apdu.sendBytes((short)0, le);                         // Посылаем данные клиенту
}

// Исключительно ввод данных в апплет и сохранение их в памяти апплета.
// Получаем данные из буфера и примитивно переписываем их побайтно во внутренний буфер
private void commandInput(APDU apdu) { 
  byte[] buffer = apdu.getBuffer();
  short cntBytes = (short)(buffer[ISO7816.OFFSET_LC] & 0xFF);
  short read_count = apdu.setIncomingAndReceive();
  if (read_count != cntBytes) ISOException.throwIt(ISO7816.SW_WRONG_LENGTH);
  lastReadLength = cntBytes; 
  for (short i = 0; i < lastReadLength; i++) {
    lastRead[i] = buffer[i + ISO7816.OFFSET_CDATA];
  }

// Получение данных из апплета ранее введенных функцией commandInput
// Ни как не контролируем входные данные а просто отдаем внутренний буфер клиенту
private void commandOutput(APDU apdu) { 
  byte[] buffer = apdu.getBuffer();
  apdu.setOutgoing();
  apdu.setOutgoingLength((short)(lastReadLength + 1));
  for (short i = 0; i < lastReadLength; i++) {
    buffer[i+1] = lastRead[i];
  }
  buffer[0] = (byte) (lastReadLength & 0xFF);
  apdu.sendBytes((short)0, (short)(lastReadLength + 1));
}
...


Вот  trace log из клиента Java: Видно что команды нормально отрабатывают:
Код

=> 00 A4 04 00 10 00 00 10 70 00 FF 00 01 00 01 00 01 00 01 00 00 00
<= 90 00
Status: No Error
=> B0 1A 00 00 03 FF FF FF
<= 90 00
Status: No Error
=> B0 1B 00 00 04
<= 03 FF FF FF 90 00
Status: No Error
=> B0 11 00 00 03 01 02 03 FF
<= 03 01 02 90 00
Status: No Error


А вот  trace log из клиента Delphi:
Код

Send: 00A40400100000107000FF00010001000100010000
Response: 90 00  (.)
Send: B0 1A 00 00 03 FF FF FF
Response: 90 00  (.)
Send: B0 1B 00 00 04
Response: 03 FF FF FF 90 00  (.ÿÿÿ.)
Send: B0 11 00 00 03 01 02 03 FF
Transmitt error 87
Response:  () // Возврата нет.  Возникает перехватываемая ошибка. Возвращаемый буфер пуст.


Казалось бы виноват Делфи компонент который рулит SCardTransmit из dll. Но ведь он и отправляет и получает данные командами 1A и 1B. Когда идет обмед данными в одну сторону. Но в случае когда обмен данными идет в обе стороны напрочь отказывается работать.
Возможно я не учитываю какую-то особенность работы с карточкой или с мелкософтовской библиотечкой winscard.dll для работы  PS/CS... Попытки чего-то изменить методом нацчного тыка в компоненте не привели ни к чему хорошему smile
Вот кстати вызов функции в компоненте, несколько мной упрощенный для форума:
Код

function TPCSCConnector.GetResponseFromCard(const APdu: string): string;
var
  RetVar : cardinal;
  SBuf   : string;
  SLen   : cardinal;
  RBuf   : string;
  RLen   : cardinal;
begin
  SBuf := APdu;
  RBuf := StringOfChar(#0, MAXAPDULENGTH);
  if Length(SBuf) <= MAXAPDULENGTH then
  begin
    SLen := Length(APdu);
    RLen := Length(RBuf);
    RetVar := SCardTransmit(FCardHandle, nil, Pointer(SBuf), SLen, nil, Pointer(RBuf), @RLen);
    if RetVar = SCARD_S_SUCCESS then Result := Copy(RBuf, 1, RLen)
    else begin
      Result := '';
      if Assigned(FOnError) then FOnError(Self, esTransmit, RetVar); // Тут генериться та самая "ошибка 87" и буфер пуст
    end;
  end;
end;

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


Новичок



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

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



Я слишком много вывалил? smile
PM MAIL   Вверх
romul
Дата 2.4.2008, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Народ, хелп плиз! Скажите хотябы где спросить можно. Форум, контакт. Или где почитать. У меня проект стал :(
PM MAIL   Вверх
Kangaroo
Дата 2.4.2008, 15:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


AA - Aussie Animal
****


Профиль
Группа: Участник Клуба
Сообщений: 2042
Регистрация: 7.10.2006
Где: US

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



Цитата(romul @  2.4.2008,  14:41 Найти цитируемый пост)
Скажите хотябы где спросить можно. Форум, контакт. Или где почитать. У меня проект стал :( 

Попробуй напиши firstone'y  в личку. Я так понимаю, он пока один у нас эксперт в Java Card  smile 


--------------------
Lost....
PM MAIL MSN   Вверх
romul
Дата 2.4.2008, 18:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Kangaroo @ 2.4.2008,  15:45)
Попробуй напиши firstone'y  в личку. Я так понимаю, он пока один у нас эксперт в Java Card

Спасибо, так и сделаю.
PM MAIL   Вверх
firstone
Дата 6.4.2008, 15:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 25.9.2007
Где: Кровью залитая Св ятая Земля

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



 Извиняюсь за поздний ответ.

Только чтo запустил Ваш апплет на карте. И все работает. Клиент я написал сам. Использовал windows PC/SC.

 Видимо Ваш клиент работает неправильно. 

К сожалению сказать где именно ошибка в клиенте невозможно за неимением егo кода. Предлагаю залогить вызовы PC/SC функций (с параметрами) и опубликовать лог здесь.

Если нужен работающий PC/SC framework на .NET, я могу Вам послать.

С уважением, firstone.
--------------------
В программировании я конфуцианец. В жизни я либерал-демократ. В душе я буддист.Добавлено через 1 минуту и 9 секундА на самом деле я лентяй.
PM MAIL   Вверх
romul
Дата 7.4.2008, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо за ответ. То, что с клиентом не так это 100%, поскольку работающий клиент на Java обменивается данными на ура.

Наиболее важную часть своего клиента я в большом своем письме привел самым последним. Но чтобы не мотать туда-сюда страничку повторю и добавлю подробности:

Это функция вызывающая SCardTransmit из MS-овской библиотечки winscard.dll для работы  PS/CS.
Код

function TPCSCConnector.GetResponseFromCard(const APdu: string): string;
var
  RetVar : cardinal;
  SBuf   : string;
  SLen   : cardinal;
  RBuf   : string;
  RLen   : cardinal;
begin
  SBuf := APdu;
  RBuf := StringOfChar(#0, MAXAPDULENGTH);
  if Length(SBuf) <= MAXAPDULENGTH then
  begin
    SLen := Length(APdu);
    RLen := Length(RBuf);
    RetVar := SCardTransmit(FCardHandle, nil, Pointer(SBuf), SLen, nil, Pointer(RBuf), @RLen);
    if RetVar = SCARD_S_SUCCESS then Result := Copy(RBuf, 1, RLen)
    else begin
      Result := '';
      if Assigned(FOnError) then FOnError(Self, esTransmit, RetVar); // Тут генериться та самая "ошибка 87" и буфер пуст
    end;
  end;
end;


Вызываю ее со следущими строками (Send мой запрос, Responce получаемый ответ):
Код

Send: 00A40400100000107000FF00010001000100010000 // Выбор апплета
Response: 90 00  (.) // Результат ожидаемый
Send: B01A000003FFFFFF // Сохраняем данные в апплете
Response: 90 00  (.)  // Данные сохранены
Send: B01B000004 // Проверяем сохраненные данные
Response: 03 FF FF FF 90 00  (.ÿÿÿ.) // Данные возвращены и корректны
Send: B011000003010203FF // Посылаем данные и надеемся получить ответ
Transmitt error 87
Response:  () // Возврата нет.  Возникает перехватываемая ошибка. Возвращаемый буфер пуст.


К сообщению прикрепляю полный код клиента и компонента для работы с библиотечкой.


Это сообщение отредактировал(а) romul - 7.4.2008, 15:00
PM MAIL   Вверх
firstone
Дата 7.4.2008, 13:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 25.9.2007
Где: Кровью залитая Св ятая Земля

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



Странно. У меня Ваш клиент работает:
Код

Open card... Status: No Error
Connect to card... Status: No Error
Check status... Opened. Connected.
Card was inserted
Send: 00A404000CA000000000666F72756D5F74
Response: 90 00  (.)
Send: 00A404000CA000000000666F72756D5F74
Response: 90 00  (.)
Send: B0 11 00 00 03 01 02 03 FF
Response: 03 01 02 90 00  (....)
Send: B0 1A 00 00 03 FF FF FF
Response: 90 00  (.)
Send: B0 1B 00 00 04
Response: 03 FF FF FF 90 00  (.ÿÿÿ.)
Send: B0 1B 00 00 02 76 67 04
Response: 03 FF FF FF 90 00  (.ÿÿÿ.)



Добавлено через 10 минут и 26 секунд
Каким ридером Вы пользуетесь? 
--------------------
В программировании я конфуцианец. В жизни я либерал-демократ. В душе я буддист.Добавлено через 1 минуту и 9 секундА на самом деле я лентяй.
PM MAIL   Вверх
romul
Дата 7.4.2008, 14:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата
Странно. У меня Ваш клиент работает:

Это хорошая новость!

Цитата
Каким ридером Вы пользуетесь? 

А это хорошая мысль. Зря я ее отгонял так далеко от себя.
Smart Card Reader ACR38T. Вроди бы китайский какой-то. Попробую другие использовать.
PM MAIL   Вверх
romul
Дата 7.4.2008, 17:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Попробовал 3 разных кардридера от 2 производителя. Попробовал 2 разных карточки разных производителя. Эффект тот же.
Очень странно.
PM MAIL   Вверх
firstone
Дата 7.4.2008, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 116
Регистрация: 25.9.2007
Где: Кровью залитая Св ятая Земля

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



Попробуйте на другом компьютере.
--------------------
В программировании я конфуцианец. В жизни я либерал-демократ. В душе я буддист.Добавлено через 1 минуту и 9 секундА на самом деле я лентяй.
PM MAIL   Вверх
romul
Дата 8.4.2008, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Не работает на 3-х компьютерах. Эксперименты продолжаю. Наверно легче убить "сибя ап стенку", чем заставить ее заработать.
А каким ридером пользуетесь Вы? И что у вас за карточка на которой эксперимент был удачным?

И на какой оси пробовали?

Это сообщение отредактировал(а) romul - 8.4.2008, 11:08
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java Card | Следующая тема »


 




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


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

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