/// <summary> /// /// </summary> /// <param name="aCommandAPDU"></param> /// <returns></returns> public CardResponseAPDU RunGsmAlgo(byte[] rand) { _Select(0x7F20); CardCommandAPDU aCommandAPDU = new CardCommandAPDU(0xA0, 0x88, 0x00, 0x00, rand); CardResponseAPDU resp = _SendSimCommand(aCommandAPDU); return(resp); }
/// <summary> /// /// </summary> /// <param name="aCommandAPDU"></param> /// <returns></returns> CardResponseAPDU _SendSimCommand(CardCommandAPDU aCommandAPDU) { CardResponseAPDU aResponseAPDU = m_aCard.SendCommand(aCommandAPDU); if ((aResponseAPDU.SW1 == 0x9F) && (aResponseAPDU.Lr == 0)) { CardCommandAPDU aGetResponseAPDU = new CardCommandAPDU(0xA0, 0xC0, 0x00, 0x00, aResponseAPDU.SW2); aResponseAPDU = m_aCard.SendCommand(aGetResponseAPDU); } else if ((aResponseAPDU.SW1 == 0x67) && (aResponseAPDU.SW2 != 0x00)) { aCommandAPDU.Le = aResponseAPDU.SW2; aResponseAPDU = m_aCard.SendCommand(aCommandAPDU); } return(aResponseAPDU); }
internal byte[] RunGsmAlgo(byte[] rand) { if (!aSim.SelectDFTelecom()) { MessageBox.Show("Error reading GSM SIM card!"); _DisposeSim(aSim); aSim = null; return(null); } CardResponseAPDU sres = aSim.RunGsmAlgo(rand); if (sres != null && sres.GetData() != null) { txtLog.AppendText("SRES resp " + CardHex.FromByteArray(rand) + "[" + rand.Length + "] -> " + CardHex.FromByteArray(sres.GetData()) + Environment.NewLine); return(sres.GetData()); } txtLog.AppendText("SRES fail " + CardHex.FromByteArray(rand) + "[" + rand.Length + "] -> <failed> " + CardHex.FromByte(sres.SW1) + " " + CardHex.FromByte(sres.SW2) + Environment.NewLine); return(null); }
/// <summary> /// /// </summary> /// <returns></returns> public bool SelectDFTelecom() { CardResponseAPDU aResponseAPDU = _Select(0x7F10); return(aResponseAPDU.IsSuccessful); }
/// <summary> /// Wysyła do karty polecenie APDU /// </summary> /// <param name="command">Polecenie APDU</param> /// <param name="checkSuccessful">Ma sprawdzać, czy odpowiedź jest poprawna (90 00)</param> /// <exception cref="APDUException"></exception> /// <returns>Odpowiedź na polecenie APDU</returns> public ByteArray SendCommand(ByteArray command, bool checkSuccessful = true) { ConnectCard(false); CardCommandAPDU apdu = null; if (command.Length == 4) { apdu = new CardCommandAPDU(command[0], command[1], command[2], command[3]); } else if (command.Length == 5) { apdu = new CardCommandAPDU(command[0], command[1], command[2], command[3], command[4]); } else if (command.Length > 5) { ByteArray data = command.Extract(5, command[4]); int length = 5 + command[4]; if (length == command.Length) { apdu = new CardCommandAPDU(command[0], command[1], command[2], command[3], data.ByteData); } else { apdu = new CardCommandAPDU(command[0], command[1], command[2], command[3], data.ByteData, command[command.Length - 1]); } } if (apdu == null) { throw new Exception("Nieprawidłowa komenda APDU: " + command); } int tryCounter = 5; CardResponseAPDU response = null; do { try { Logger.Log("[Encoder] -> " + command); response = CardHandle.SendCommand(apdu); break; } catch (System.Runtime.InteropServices.COMException comException) { tryCounter--; if (tryCounter == 0) { throw new Exception("Sprzętowy błąd wykonywania komendy APDU (Message: " + comException.Message + ", HResult: " + comException.ErrorCode + ")"); } } catch (SCardException scException) { tryCounter--; if (tryCounter == 0) { throw new Exception("Sprzętowy błąd wykonywania komendy APDU (Kod: " + scException.ResponseCode + ").", scException); } } catch (Exception terminalException) { tryCounter--; if (tryCounter == 0) { throw new Exception("Sprzętowy błąd wykonywania komendy APDU.", terminalException); } } } while (true); ByteArray result = new ByteArray(response.GenerateBytes()); Logger.Log("[Encoder] <- " + result); if (checkSuccessful && !response.IsSuccessful && !response.IsWarning) { throw new APDUException("Błąd wykonywania komendy APDU", command, new ByteArray(response.GenerateBytes()), response.SW1, response.SW2); } return(result); }
private void btnReadDetails_Click(object sender, System.EventArgs e) { if (aSim == null) { aSim = _ObtainSim(); if (aSim == null) { return; } } try { byte[] data = aSim.ReadIccIdentification(); if (data == null) { MessageBox.Show("Error reading GSM SIM card!"); _DisposeSim(aSim); aSim = null; return; } txtLog.AppendText("ICCID: " + CardHex.FromByteArray(data) + Environment.NewLine); /* check access to SIM card. fails if CHV required */ if (aSim.ReadImsi() == null) { CardResponseAPDU aRespAPDU = aSim.VerifyChv(this, m_aCardForm, "PIN Verification", "In order to access your SIM the PIN is required."); if (aRespAPDU == null) { // The PIN entry has been cancelled by the user. _DisposeSim(aSim); aSim = null; return; } if (!aRespAPDU.IsSuccessful) { string sHeading = "Failed to verify PIN!"; switch (aRespAPDU.SW) { case 0x9804: m_aCardForm.Notify(this, MessageBoxIcon.Warning, sHeading, "Wrong PIN!"); break; case 0x9840: m_aCardForm.Notify(this, MessageBoxIcon.Warning, sHeading, "Wrong PIN! The SIM has been blocked."); break; case 0x9808: m_aCardForm.Notify(this, MessageBoxIcon.Warning, sHeading, "The SIM is blocked. Please use mobile phone " + "in order to unblock the SIM with the PUK."); break; default: m_aCardForm.Notify(this, MessageBoxIcon.Warning, sHeading, "Unknown reason: (" + aRespAPDU.SW + ")"); break; } _DisposeSim(aSim); aSim = null; return; } } data = aSim.ReadImsi(); if (data == null) { MessageBox.Show("Error reading IMSI!"); _DisposeSim(aSim); aSim = null; return; } txtLog.AppendText("IMSI: " + CardHex.FromByteArray(data) + Environment.NewLine); if (!aSim.SelectDFTelecom()) { MessageBox.Show("Error selecting GSM file!"); _DisposeSim(aSim); aSim = null; return; } byte[] rand = CardHex.ToByteArray(txtRand.Text); byte[] resp = RunGsmAlgo(rand); /**/ } catch (Exception) { _DisposeSim(aSim); aSim = null; } }