Module: Smartcard::Iso::IsoCardMixin
- Included in:
- Gp::GpCardMixin, JcopRemoteTransport, PcscTransport
- Defined in:
- lib/smartcard/iso/iso_card_mixin.rb
Overview
Module intended to be mixed into transport implementations to mediate between a high level format for ISO7816-specific APDUs and the wire-level APDU request and response formats.
The mix-in calls exchange_apdu in the transport implementation. It supplies the APDU data as an array of integers between 0 and 255, and expects a response in the same format.
Class Method Summary collapse
-
.deserialize_response(response) ⇒ Object
De-serializes a ISO7816 response APDU.
-
.serialize_apdu(apdu_data) ⇒ Object
Serializes an APDU for wire transmission.
Instance Method Summary collapse
-
#iso_apdu(apdu_data) ⇒ Object
Performs an APDU exchange with the ISO7816 card.
-
#iso_apdu!(apdu_data) ⇒ Object
APDU exchange with the ISO7816 card, raising an ApduError if the return code is not success (0x9000).
Class Method Details
.deserialize_response(response) ⇒ Object
De-serializes a ISO7816 response APDU.
:call-seq:
IsoCardMixin.deserialize_response(response) -> hash
The response contains the following keys:
status:: the 2-byte status code (e.g. 0x9000 is OK)
data:: the additional data in the response
90 91 92 |
# File 'lib/smartcard/iso/iso_card_mixin.rb', line 90 def self.deserialize_response(response) { :status => response[-2] * 256 + response[-1], :data => response[0...-2] } end |
.serialize_apdu(apdu_data) ⇒ Object
Serializes an APDU for wire transmission.
:call-seq:
IsoCardMixin.serialize_apdu(apdu_data) -> array
The following keys are recognized in the APDU hash:
cla:: the CLA byte in the APDU (optional, defaults to 0)
ins:: the INS byte in the APDU -- the first byte seen by a JavaCard applet
p12:: 2-byte array containing the P1 and P2 bytes in the APDU
p1, p2:: the P1 and P2 bytes in the APDU (optional, both default to 0)
data:: the extra data in the APDU (optional, defaults to nothing)
le:: the expected data length (defaults to 0; set to +false+ to avoid
sending an Le byte)
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/smartcard/iso/iso_card_mixin.rb', line 60 def self.serialize_apdu(apdu_data) raise 'Unspecified INS in apdu_data' unless apdu_data[:ins] apdu = [ apdu_data[:cla] || 0, apdu_data[:ins] ] if apdu_data[:p12] unless apdu_data[:p12].length == 2 raise "Malformed P1,P2 - #{apdu_data[:p12]}" end apdu += apdu_data[:p12] else apdu << (apdu_data[:p1] || 0) apdu << (apdu_data[:p2] || 0) end if apdu_data[:data] apdu << apdu_data[:data].length apdu += apdu_data[:data] else apdu << 0 end apdu << (apdu_data[:le] || 0) unless apdu_data[:le] == false apdu end |
Instance Method Details
#iso_apdu(apdu_data) ⇒ Object
Performs an APDU exchange with the ISO7816 card.
:call-seq:
transport.iso_apdu(apdu_data) -> hash
The apdu_data should be in the format expected by IsoCardMixin#serialize_apdu. The response will be as specified in IsoCardMixin#deserialize_response.
42 43 44 45 |
# File 'lib/smartcard/iso/iso_card_mixin.rb', line 42 def iso_apdu(apdu_data) response = self.exchange_apdu IsoCardMixin.serialize_apdu(apdu_data) IsoCardMixin.deserialize_response response end |
#iso_apdu!(apdu_data) ⇒ Object
APDU exchange with the ISO7816 card, raising an ApduError if the return code is not success (0x9000).
:call_seq:
transport.iso_apdu!(apdu_data) -> array
The apdu_data should be in the format expected by IsoCardMixin#serialize_apdu. Returns the response data, if the response status indicates success (0x9000). Otherwise, raises an ApduError.
28 29 30 31 32 |
# File 'lib/smartcard/iso/iso_card_mixin.rb', line 28 def iso_apdu!(apdu_data) response = self.iso_apdu apdu_data return response[:data] if response[:status] == 0x9000 raise ApduError, response end |