Advertisement
Kikku80

Untitled

Sep 23rd, 2019
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.88 KB | None | 0 0
  1. public async Task<(bool ApplicationCrytogramVerificationResult, byte[] ArpcResponse)> CardUnblockAsync(string PAN, string sequenceNumber, byte smiKeyIndex, byte smcKeyIndex, byte acKeyIndex,
  2.             byte[] applicationCryptogram, byte[] ATC)
  3.         {
  4.             HsmTcpConnection connection = null;
  5.             try
  6.             {
  7.                 if (string.IsNullOrEmpty(PAN) || string.IsNullOrEmpty(sequenceNumber))
  8.                     throw new HsmApplicationCryptogramVerifyException("PAN Data is not valid");
  9.  
  10.                 if (applicationCryptogram == null)
  11.                     throw new HsmApplicationCryptogramVerifyException("Application Cryptogram is not valid");
  12.  
  13.                 if (applicationCryptogram == null || applicationCryptogram.Length != 8)
  14.                     throw new HsmApplicationCryptogramVerifyException("Application Cryptogram is not valid");
  15.  
  16.                 if (ATC == null)
  17.                     throw new HsmApplicationCryptogramVerifyException("ATC is not valid");
  18.  
  19.                 int msgLength = 6 + 3 + 1 + 1 + 1 + 3 + 3 + 1 + 1 + 8 + 1 + applicationCryptogram.Length + 8 + 8 + 3 + 1 + 6 + 2 + 7 + ATC.Length + applicationCryptogram.Length;
  20.           //    int msgLength = 6 + 3 + 1 + 1 + 1 + 3 + 3 + 1 + 1 + (((PAN.Length + sequenceNumber.Length) /2) + ((PAN.Length+sequenceNumber.Length) %2)) + 1 + applicationCryptogram.Length + 8 + 8 + 3 + 1 + 6 + 2 + 7 + ATC.Length + applicationCryptogram.Length;
  21.    
  22.                 //header + function name + function modifier + function flag + scheme + SMI + SMC + IMKAC + (Len +PAN + SequenceNos) + (Len + AC) + (OLD & New PIN) + PPK
  23.                 //+ PinBlockFormat + ANB + ScriptDataPosition + Script Data
  24.  
  25.                 byte[] req = new byte[msgLength];
  26.                 req[0] = 0x01; // SOH Character
  27.                 req[1] = 0x01; // Version Number
  28.  
  29.                 var seqNum = GetNextSequenceNumber();
  30.                 req[2] = (byte)(seqNum >> 8); // Sequence Number
  31.                 req[3] = (byte)seqNum; // Sequence Number
  32.  
  33.                 req[4] = (byte)((msgLength - 6) >> 8); // length of message (header is not included that is why -6)
  34.                 req[5] = (byte)(msgLength - 6); // length of message
  35.  
  36.  
  37.                 req[6] = 0xEE; // Function name
  38.                 req[7] = 0x20;
  39.                 req[8] = 0x16;
  40.  
  41.                 req[9] = 0x00; // Function modifier
  42.                 req[10] = 0x00; //Function flag - 00= Pin Unblock only,
  43.                 req[11] = 0x01; //Scheme - 01=MasterCard
  44.  
  45.                 req[12] = 0x02; // Var Len
  46.                 req[13] = 0x00;
  47.                 req[14] = smiKeyIndex; // Key specifier for IMK SMI
  48.  
  49.                 req[15] = 0x02; // Var Len
  50.                 req[16] = 0x00;
  51.                 req[17] = smcKeyIndex; // Key specifier for IMK SMC
  52.  
  53.                 req[18] = 0x00; // IMK AC
  54.  
  55.                 //Formatted PAN and PAN Sequence Number
  56.                
  57. //                //Hardcoded PAN
  58. //                req[19] = 0x08;
  59. //                req[20] = 0x04;
  60. //                req[21] = 0x74;
  61. //                req[22] = 0x00;
  62. //                req[23] = 0x00;
  63. //                req[24] = 0x00;
  64. //                req[25] = 0x14;
  65. //                req[26] = 0x16;
  66. //
  67. //                //Hardcoded Sequence Number
  68. //                req[27] = 0x00;
  69.  
  70.                 req[19] = (byte) Convertor.StringToBCD(PAN + sequenceNumber,2, 16 ,req ,20);
  71. //
  72.               //  var pos = 28;
  73.              
  74.                 var pos = 20 + req[19];
  75.  
  76.                 req[pos++] = (byte) applicationCryptogram.Length;
  77.                 Buffer.BlockCopy(applicationCryptogram, 0, req, pos, applicationCryptogram.Length);
  78.                 pos += applicationCryptogram.Length;
  79.                
  80.                 req[pos++] = 0x32;
  81.                 req[pos++] = 0x13;
  82.                 req[pos++] = 0x17;
  83.                 req[pos++] = 0x5A;
  84.                 req[pos++] = 0xBC;
  85.                 req[pos++] = 0x32;
  86.                 req[pos++] = 0xB9;
  87.                 req[pos++] = 0x49;
  88.  
  89.                 req[pos++] = 0x32;
  90.                 req[pos++] = 0x13;
  91.                 req[pos++] = 0x17;
  92.                 req[pos++] = 0x5A;
  93.                 req[pos++] = 0xBC;
  94.                 req[pos++] = 0x32;
  95.                 req[pos++] = 0xB9;
  96.                 req[pos++] = 0x49;
  97.            
  98.  
  99. //                pos += 8; //Encrypted PIN Block (Existing PIN)
  100. //                pos += 8; //Encrypted PIN Block (New PIN)
  101.  
  102.                 req[pos++] = 0x02;
  103.                 req[pos++] = 0x00;
  104.                 req[pos++] = 0x07; //PPK. we should not be using this for this function - index 7 is staging , 2 is live
  105.  
  106.                 req[pos++] = 0x10; //PIN Block Format
  107.  
  108.                 //Account Number Block
  109.                 pos += Convertor.StringToBCD(PAN, PAN.Length - 13, 12, req, pos);//ANB
  110.  
  111.                 req[pos++] = 0x00; //Script Data Position
  112.                 req[pos++] = 0x0F;
  113.  
  114.                 req[pos++] = 0x10; //Script data len
  115.                 req[pos++] = 0x84; //Class
  116.                 req[pos++] = 0x24; //Ins
  117.                 req[pos++] = 0x00; //P1
  118.                 req[pos++] = 0x00;// P2
  119.                 req[pos++] = 0x08; //Lc
  120.  
  121.                 Buffer.BlockCopy(ATC, 0, req, pos, ATC.Length);
  122.                 pos += ATC.Length;
  123.  
  124.                 Buffer.BlockCopy(applicationCryptogram, 0, req, pos, applicationCryptogram.Length);
  125.                 pos += applicationCryptogram.Length;
  126.  
  127.                 req[pos++] = 0x80;
  128.                 Console.WriteLine($"Request Buffer: {ByteArrayToString(req)}");    
  129.                
  130.                 connection = GetConnection();
  131.                 var response = await connection.SendRequestAsync(req);
  132.                
  133.                 Console.WriteLine($"Response Buffer: {ByteArrayToString(response)}");    
  134.  
  135.  
  136.                 if (response == null || response.Length < 4)
  137.                     throw new HsmApplicationCryptogramVerifyException("EMV-PIN-CHANGE-UNBLOCK (EE2016) function returned invalid response");
  138.  
  139.  
  140.                 //check response code
  141.                 if (response[3] != 0x00 && response[3] != 0x08) //function failed
  142.                     throw new HsmApplicationCryptogramVerifyException(string.Format("EMV-PIN-CHANGE-UNBLOCK (EE2016) response is {0:X2}", response[3]));
  143.                 else if (response[3] == 0x08)
  144.                 {
  145.                     return (false, null);
  146.                 }
  147.                 else //0x00
  148.                 {
  149.                     _log.Debug("EMV-PIN-CHANGE-UNBLOCK (EE2016) succeeded");
  150.                     byte[] ARPC = new byte[response[4]];
  151.                     Buffer.BlockCopy(response, 5, ARPC, 0, response[4]);
  152.                     return (true, ARPC);
  153.                 }
  154.             }
  155.             finally
  156.             {
  157.                 //return connection to stack
  158.                 if (hsmConnections != null)
  159.                     hsmConnections.Push(connection);
  160.             }
  161.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement