/// <summary> /// Update the current APDU with selected parameters /// </summary> /// <param name="apduParam">APDU parameters</param> public void Update(APDUParam apduParam) { if (apduParam.UseData) { baData = apduParam.Data; } if (apduParam.UseLe) { bLe = apduParam.Le; } if (apduParam.UseP1) { bP1 = apduParam.P1; } if (apduParam.UseP2) { bP2 = apduParam.P2; } if (apduParam.UseChannel) { bCla += apduParam.Channel; } }
public APDUResponse ProcessCommand(string cmdClass, string cmdIns, APDUParam apduParam) { byte bClass = byte.Parse(cmdClass, NumberStyles.AllowHexSpecifier); byte bIns = byte.Parse(cmdIns, NumberStyles.AllowHexSpecifier); APDUCommand apduCommand = new APDUCommand(bClass, bIns, 0, 0, null, 0); apduCommand.Update(apduParam); return(ExecuteApduCommand(apduCommand)); }
/// <summary> /// Process a command of a sequence of APDU /// </summary> /// <param name="xmlCmd">XML node representing the command</param> /// <param name="seqParam">List of parameters of the sequence</param> /// <returns>APDUResponse object of command executed</returns> // private APDUResponse ProcessSeqCmd(XmlNode xmlCmd, Dictionary<string, string> seqParam) private APDUResponse ProcessSeqCmd(XmlNode xmlCmd, SequenceParameter seqParam) { bool bApdu = false; bool bSeq = false; string sApduName = null; string sSeqName = null; APDUResponse apduResp = null; // Get the APDU or Sequence name try { // Get the Apdu name to run sApduName = xmlCmd.Attributes[xmlAttrApdu].Value; bApdu = true; } catch { } finally { try { sSeqName = xmlCmd.Attributes[xmlAttrSequence].Value; bSeq = true; } catch { } if ((bSeq | bApdu) == false) { throw new ApduCommandException(ApduCommandException.MissingApduOrCommand); } } if (bApdu) { APDUParam apduParams = BuildCommandParam(xmlCmd.Attributes, seqParam); apduResp = ProcessCommand(sApduName, apduParams); } if (bSeq) { // Process a sub sequence apduResp = ProcessSequence(sSeqName, seqParam); } return(apduResp); }
/// <summary> /// Process a simple APDU command, Parameters can be provided in the APDUParam object /// </summary> /// <param name="command">APDU command name</param> /// <param name="apduParam">Parameters for the command</param> /// <returns>An APDUResponse object with the response of the card </returns> public APDUResponse ProcessCommand(string apduName, APDUParam apduParam) { APDUCommand apduCmd = null; // Get the base APDU apduCmd = APDUByName(apduName); if (apduCmd == null) { throw new ApduCommandException(ApduCommandException.NoSuchCommand); } apduCmd.Update(apduParam); return(ExecuteApduCommand(apduCmd)); }
/// <summary> /// Copy constructor (used for cloning) /// </summary> /// <param name="param"></param> public APDUParam(APDUParam param) { // Copy field if (param.m_baData != null) param.m_baData.CopyTo(m_baData, 0); m_bClass = param.m_bClass; m_bChannel = param.m_bChannel; m_bP1 = param.m_bP1; m_bP2 = param.m_bP2; m_nLe = param.m_nLe; // Copy flags field m_fChannel = param.m_fChannel; m_fClass = param.m_fClass; m_fData = param.m_fData; m_fLe = param.m_fLe; m_fUseP1 = param.m_fUseP1; m_fUseP2 = param.m_fUseP2; }
/// <summary> /// Copy constructor (used for cloning) /// </summary> /// <param name="other"></param> public APDUParam(APDUParam other) { // Copy field if (other.baData != null) { baData = new byte[other.baData.Length]; other.baData.CopyTo(baData, 0); } bClass = other.bClass; bChannel = other.bChannel; bP1 = other.bP1; bP2 = other.bP2; nLe = other.nLe; // Copy flags field useChannel = other.useChannel; useClass = other.useClass; useData = other.useData; useLe = other.useLe; useP1 = other.useP1; useP2 = other.useP2; }
/// <summary> /// Update the current APDU with selected parameters /// </summary> /// <param name="apduParam">APDU parameters</param> public void Update(APDUParam apduParam) { if (apduParam.UseData) m_baData = apduParam.Data; if (apduParam.UseLe) m_bLe = apduParam.Le; if (apduParam.UseP1) m_bP1 = apduParam.P1; if (apduParam.UseP2) m_bP2 = apduParam.P2; if (apduParam.UseChannel) m_bCla += apduParam.Channel; }
private void DisplayAPDUCommand(APDUCommand apduCmd) { if (apduCmd != null) { textClass.Text = string.Format("{0:X02}", apduCmd.Class); textIns.Text = string.Format("{0:X02}", apduCmd.Ins); textP1.Text = string.Format("{0:X02}", apduCmd.P1); textP2.Text = string.Format("{0:X02}", apduCmd.P2); textLe.Text = apduCmd.Le.ToString(); textData.Text = (apduCmd.Data != null) ? ByteArray.ToString(apduCmd.Data) : string.Empty; apduParam = new APDUParam(); apduParam.P1 = apduCmd.P1; apduParam.P2 = apduCmd.P2; apduParam.Le = apduCmd.Le; } }
private APDUParam BuildAPDUParameters() { byte bP1 = byte.Parse(textP1.Text, NumberStyles.AllowHexSpecifier); byte bP2 = byte.Parse(textP2.Text, NumberStyles.AllowHexSpecifier); byte bLe = byte.Parse(textLe.Text); APDUParam apduParam = new APDUParam(); apduParam.P1 = bP1; apduParam.P2 = bP2; apduParam.Le = bLe; byte[] data = ByteArray.Parse(textData.Text); if (data.Length > 0) { apduParam.Data = data; } // Update Current param apduParam = apduParam.Clone(); return apduParam; }
/// <summary> /// This program tests the API with a SIM card. /// If your PIN is activated be carefull when presenting the PIN to your card! /// </summary> /// <param name="args"></param> static void Main(string[] args) { try { APDUResponse apduResp; CardNative iCard = new CardNative(); string[] readers = iCard.ListReaders(); iCard.Connect(readers[0], SHARE.Shared, PROTOCOL.T0orT1); Console.WriteLine("Connects card on reader: " + readers[0]); // Verify the PIN (if necessary) byte[] pin = new byte[] { 0x31, 0x32, 0x33, 0x34, 0xFF, 0xFF, 0xFF, 0xFF}; APDUParam apduParam = new APDUParam(); apduParam.Data = pin; apduVerifyCHV.Update(apduParam); //apduResp = iCard.Transmit(apduVerifyCHV); // Select the MF (3F00) apduParam.Data = new byte[] { 0x3F, 0x00 }; apduSelectFile.Update(apduParam); apduResp = iCard.Transmit(apduSelectFile); if (apduResp.Status != SC_OK && apduResp.SW1 != SC_PENDING) throw new Exception("Select command failed: " + apduResp.ToString()); Console.WriteLine("MF selected"); // Select the EFtelecom (7F10) apduParam.Data = new byte[] { 0x7F, 0x10 }; apduSelectFile.Update(apduParam); apduResp = iCard.Transmit(apduSelectFile); if (apduResp.Status != SC_OK && apduResp.SW1 != SC_PENDING) throw new Exception("Select command failed: " + apduResp.ToString()); Console.WriteLine("DFtelecom selected"); // Select the EFadn (6F3A) apduParam.Data = new byte[] { 0x6F, 0x3A }; apduSelectFile.Update(apduParam); apduResp = iCard.Transmit(apduSelectFile); if (apduResp.Status != SC_OK && apduResp.SW1 != SC_PENDING) throw new Exception("Select command failed: " + apduResp.ToString()); Console.WriteLine("EFadn (Phone numbers) selected"); // Read the response if (apduResp.SW1 == SC_PENDING) { apduParam.Reset(); apduParam.Le = apduResp.SW2; apduParam.Data = null; apduGetResponse.Update(apduParam); apduResp = iCard.Transmit(apduGetResponse); if (apduResp.Status != SC_OK) throw new Exception("Select command failed: " + apduResp.ToString()); } // Get the length of the record int recordLength = apduResp.Data[14]; Console.WriteLine("Reading the Phone number 10 first entries"); // Read the 10 first record of the file for (int nI = 0; nI < 10; nI++) { apduParam.Reset(); apduParam.Le = (byte) recordLength; apduParam.P1 = (byte) (nI + 1); apduReadRecord.Update(apduParam); apduResp = iCard.Transmit(apduReadRecord); if (apduResp.Status != SC_OK) throw new Exception("ReadRecord command failed: " + apduResp.ToString()); Console.WriteLine("Record #" + ((int) (nI + 1)).ToString()); Console.WriteLine(apduResp.ToString()); } iCard.Disconnect(DISCONNECT.Unpower); } catch (Exception ex) { Console.WriteLine(ex.Message); } }
private void DisplayAPDUCommand(APDUCommand apduCmd) { if (apduCmd != null) { textClass.Text = string.Format("{0:X02}", apduCmd.Class); textIns.Text = string.Format("{0:X02}", apduCmd.Ins); textP1.Text = string.Format("{0:X02}", apduCmd.P1); textP2.Text = string.Format("{0:X02}", apduCmd.P2); textLe.Text = apduCmd.Le.ToString(); if (apduCmd.Data != null) { StringBuilder sData = new StringBuilder(apduCmd.Data.Length * 2); for (int nI = 0; nI < apduCmd.Data.Length; nI++) sData.AppendFormat("{0:X02}", apduCmd.Data[nI]); textData.Text = sData.ToString(); } else textData.Text = ""; m_apduParam = new APDUParam(); m_apduParam.P1 = apduCmd.P1; m_apduParam.P2 = apduCmd.P2; m_apduParam.Le = apduCmd.Le; } }
private APDUParam BuildParam() { byte bP1 = byte.Parse(textP1.Text, NumberStyles.AllowHexSpecifier); byte bP2 = byte.Parse(textP2.Text, NumberStyles.AllowHexSpecifier); byte bLe = byte.Parse(textLe.Text); APDUParam apduParam = new APDUParam(); apduParam.P1 = bP1; apduParam.P2 = bP2; apduParam.Le = bLe; // Update Current param m_apduParam = apduParam.Clone(); return apduParam; }
/// <summary> /// Builds an APDUParam object from the parameters of a command and a set of parameter for a sequence /// </summary> /// <param name="xmlAttrs">List of parameters of the APDU</param> /// <param name="seqParam">List of parameters of the sequence</param> /// <returns>APDUParam object</returns> private APDUParam BuildCommandParam(XmlAttributeCollection xmlAttrs, SequenceParameter seqParam) { APDUParam apduParam = null; string sVal = null; apduParam = new APDUParam(); for (int nI = 0; nI < xmlAttrs.Count; nI++) { XmlNode xmlParam = xmlAttrs.Item(nI); switch (xmlParam.Name) { case xmlAttrP1: { try { sVal = seqParam[xmlParam.Value]; } catch { sVal = xmlParam.Value; } finally { apduParam.P1 = byte.Parse(sVal, NumberStyles.AllowHexSpecifier); } break; } case xmlAttrP2: { try { sVal = seqParam[xmlParam.Value]; } catch { sVal = xmlParam.Value; } finally { apduParam.P2 = byte.Parse(sVal, NumberStyles.AllowHexSpecifier); } break; } case xmlAttrData: { try { sVal = seqParam[xmlParam.Value]; } catch { sVal = xmlParam.Value; } finally { apduParam.Data = ByteArray.Parse(sVal); } break; } } } return(apduParam); }