/// <summary> /// Certificate expiry check /// </summary> /// <returns> /// True if the certificate is not expired and is according to the format MMyy /// </returns> /// <example>0918</example> private bool isExpOk() { DateTime certExp = DateTime.ParseExact(StringTools.ByteArrayToHexString(ExpDate), "MMyy", CultureInfo.InvariantCulture); int res = DateTime.Compare(certExp, DateTime.Today); return(res > 0); }
/// <summary> /// Validates the certificate based on EMVCO rules /// </summary> /// <param name="certificate">The certificate to validate</param> /// <param name="remainder">The key remainder</param> /// <param name="type">The certificate Type</param> /// <returns></returns> private EmvCertificate validateCertificate(string certificate, string remainder, CertificateType type) { var expTag = type == CertificateType.CA ? "9F32" : "9F47"; EmvCertificate cert = new EmvCertificate(certificate, remainder, type); var hashData = cert.GetHashData() + _app.GetTagValue(EmvConstants.ResponceType.ReaderRecord, expTag); var hash = GetSha1(hashData); if (hash != StringTools.ByteArrayToHexString(cert.Hash)) { throw new ApplicationException("Failed to Validate CA Hash"); } return(cert); }
/// <summary> /// Decrypt data using RSA Asymmetric Block Cipher /// </summary> /// <param name="data">The data to decrypt</param> /// <param name="exponent">The key exponent to use</param> /// <param name="key">The RSA key to use</param> /// <returns>The decrypted data</returns> public string DecryptRsa(string data, string exponent, string key) { BigInteger mod = new BigInteger(key, 16); BigInteger pubExp = new BigInteger(exponent, 16); RsaKeyParameters pubParameters = new RsaKeyParameters(false, mod, pubExp); IAsymmetricBlockCipher eng = new RsaEngine(); eng.Init(true, pubParameters); byte[] encdata = StringTools.HexStringToByteArray(data); encdata = eng.ProcessBlock(encdata, 0, encdata.Length); string result = StringTools.ByteArrayToHexString(encdata); return(result); }
public static byte[] parseTagLengthData(byte[] data) { int index = 0; List <byte> _tagList = new List <byte>(); while (index < data.Length) { var temptag = new List <byte>(); //Get the tag name temptag.Add(data[index]); if ((data[index] & EmvConstants.SeeSubsequentBytes) == EmvConstants.SeeSubsequentBytes) { index++; temptag.Add(data[index]); } Console.WriteLine("EmvTag " + StringTools.ByteArrayToHexString(temptag.ToArray())); index++; // Get the length of the data to follow if ((data[index] & 0x80) == 0x80) { int bytesForLenght = data[index] % 0x80; index++; for (int i = 0; i < bytesForLenght; i++) { index++; } } else { index++; } string tagname = StringTools.ByteArrayToHexString(temptag.ToArray()).ToUpper(); if (EmvConstants.PdolTags.ContainsKey(tagname)) { _tagList.AddRange(StringTools.HexStringToByteArray(EmvConstants.PdolTags[tagname])); } else { throw new Exception($"Unknown PDOL tag {tagname}"); } } return(_tagList.ToArray()); }
/// <summary> /// The offline authentication implementation.(Currently DDA only) /// </summary> private void BasicAuth() { var aid = StringTools.ByteArrayToHexString(_app.AID); var capkIndex = _app.GetTagValue(EmvConstants.ResponceType.ReaderRecord, "8F"); var IssuerPkCertificate = _app.GetTagValue(EmvConstants.ResponceType.ReaderRecord, "90"); var IssuerPkExponent = _app.GetTagValue(EmvConstants.ResponceType.ReaderRecord, "9F32"); _caKey = CaKeyStore.GetCaKey(aid.Substring(0, 10), capkIndex); var decryptedCACert = DecryptRsa(IssuerPkCertificate, IssuerPkExponent); var caRemainder = _app.GetTagValue(EmvConstants.ResponceType.ReaderRecord, "92"); EmvCertificate caCertificate = validateCertificate(decryptedCACert, caRemainder, CertificateType.CA); var iccPkCertificate = _app.GetTagValue(EmvConstants.ResponceType.ReaderRecord, "9F46"); var iccPkExponent = _app.GetTagValue(EmvConstants.ResponceType.ReaderRecord, "9F47"); var decryptedIccCert = DecryptRsa(iccPkCertificate, iccPkExponent, StringTools.ByteArrayToHexString(caCertificate.PublicKey)); EmvCertificate iccCertificate = validateCertificate(decryptedCACert, caRemainder, CertificateType.ICC); ICC_KEY_HASH = iccCertificate.Hash; }
/// <summary> /// The implementation of transmit with log /// </summary> /// <param name="reader">Reader Name</param> /// <param name="command">APDU command</param> /// <returns></returns> public static Response TransmitWithLog(this IsoReader reader, CommandApdu command) { SCardPCI receivePci = new SCardPCI(); // IO returned protocol control information. IntPtr sendPci = SCardPCI.GetPci(reader.ActiveProtocol); #if DEBUG System.Diagnostics.Debug.WriteLine(StringTools.ByteArrayToHexString(command.ToArray())); #endif var res = reader.Transmit(command); // data buffer #if DEBUG System.Diagnostics.Debug.WriteLine(StringTools.ByteArrayToHexString(res.GetData())); #endif if (res.SW1 != 0x61) { return(res); } CommandApdu apdu2 = new CommandApdu(IsoCase.Case2Short, reader.ActiveProtocol) { CLA = new ClassByte(ClaHighPart.Iso0x, SecureMessagingFormat.None, 0), Instruction = InstructionCode.GetResponse, P1 = 0x00, P2 = 00, Le = res.SW2 }; #if DEBUG System.Diagnostics.Debug.WriteLine(StringTools.ByteArrayToHexString(apdu2.ToArray())); #endif res = reader.Transmit(apdu2); #if DEBUG System.Diagnostics.Debug.WriteLine(StringTools.ByteArrayToHexString(res.GetData())); #endif return(res); }
public void GetSingleApplication(byte[] aid) { CommandApdu apdu = new CommandApdu(IsoCase.Case4Short, reader.ActiveProtocol); apdu.CLA = new ClassByte(ClaHighPart.Iso0x, SecureMessagingFormat.None, 0); apdu.Instruction = InstructionCode.SelectFile; apdu.P1 = 0x04; //select by name apdu.P2 = 00; // First or only occurrence apdu.Data = aid; System.Diagnostics.Debug.WriteLine(StringTools.ByteArrayToHexString(apdu.ToArray())); Response res = reader.Transmit( apdu); if (res.SW1 == 0x90) { Applications.Add(new SmartApplication(res.GetData(), reader)); } else { throw new PCSCException(SCardError.FileNotFound, "Select command failed"); } }
internal List <SmartTag> parsetlv(byte[] data, SmartTag parent = null) { List <SmartTag> tags = new List <SmartTag>(); int index = 0; while (index < data.Length) { var temptag = new List <byte>(); var tagValue = new List <byte>(); var tagLen = 0; //Get the tag name temptag.Add(data[index]); if ((data[index] & EmvConstants.SeeSubsequentBytes) == EmvConstants.SeeSubsequentBytes) { index++; temptag.Add(data[index]); } Console.WriteLine("EmvTag " + StringTools.ByteArrayToHexString(temptag.ToArray())); index++; // Get the length of the data to follow if ((data[index] & 0x80) == 0x80) { int bytesForLenght = data[index] % 0x80; index++; for (int i = 0; i < bytesForLenght; i++) { tagLen += data[index]; index++; } } else { tagLen = data[index]; index++; } // Get the value of the tag for (int i = 0; i < tagLen; i++) { try { tagValue.Add(data[index]); index++; } catch (Exception) { i = tagLen; } } string tagDesc = EmvConstants.getTagDescription(StringTools.ByteArrayToHexString(temptag.ToArray()).ToLower()); SmartTag smarttag = new SmartTag(temptag, tagLen, tagValue, tagDesc, parent); tags.Add(smarttag); if (smarttag.IsConstructed) { smarttag.Children = parsetlv(smarttag.TagValue.ToArray(), smarttag); } TagList.Add(smarttag); } return(tags); }