Module Smartcard::Iso::IsoCardMixin
In: lib/smartcard/iso/iso_card_mixin.rb

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.


Public Class methods

De-serializes a ISO7816 response APDU.

The response contains the following keys:

  status:: the 2-byte status code (e.g. 0x9000 is OK)
  data:: the additional data in the response


    # File lib/smartcard/iso/iso_card_mixin.rb, line 88
88:   def self.deserialize_response(response)
89:     { :status => response[-2] * 256 + response[-1], :data => response[0...-2] }
90:   end

Serializes an APDU for wire transmission.

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)


    # File lib/smartcard/iso/iso_card_mixin.rb, line 58
58:   def self.serialize_apdu(apdu_data)
59:     raise 'Unspecified INS in apdu_data' unless apdu_data[:ins]
60:     apdu = [ apdu_data[:cla] || 0, apdu_data[:ins] ]
61:     if apdu_data[:p12]
62:       unless apdu_data[:p12].length == 2
63:         raise "Malformed P1,P2 - #{apdu_data[:p12]}"
64:       end
65:       apdu += apdu_data[:p12]
66:     else
67:       apdu << (apdu_data[:p1] || 0)
68:       apdu << (apdu_data[:p2] || 0)
69:     end
70:     if apdu_data[:data]
71:       apdu << apdu_data[:data].length
72:       apdu += apdu_data[:data]
73:     else
74:       apdu << 0
75:     end
76:     apdu << (apdu_data[:le] || 0)
77:     apdu
78:   end

Public Instance methods

Performs an APDU exchange with the ISO7816 card.

The apdu_data should be in the format expected by IsoCardMixin#serialize_apdu. The response will be as specified in IsoCardMixin#deserialize_response.


    # File lib/smartcard/iso/iso_card_mixin.rb, line 42
42:   def iso_apdu(apdu_data)
43:     response = self.exchange_apdu IsoCardMixin.serialize_apdu(apdu_data)
44:     IsoCardMixin.deserialize_response response
45:   end

APDU exchange with the ISO7816 card, raising an ApduError if the return code is not success (0x9000).


  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.


    # File lib/smartcard/iso/iso_card_mixin.rb, line 28
28:   def iso_apdu!(apdu_data)
29:     response = self.iso_apdu apdu_data
30:     return response[:data] if response[:status] == 0x9000
31:     raise ApduError, response
32:   end