⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sm_handler.c

📁 linux 下通过802.1认证的安装包
💻 C
📖 第 1 页 / 共 3 页
字号:
      for (i=strlen(pin); i<8; i++)
	{
	  if (Strcat(buf2, sizeof(buf2), "FF") != 0)
	    {
	      fprintf(stderr, "Refusing to overflow string!\n");
	      return NULL;
	    }
	}
      
      len = MAXBUFF;
      if (cardio(card_hdl, buf2, reader_mode, MODE2G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
	{
	  debug_printf(DEBUG_NORMAL, "Error sending PIN to smart card! "
		       "(%s:%d)\n", __FUNCTION__, __LINE__);
	  return NULL;
	}

      // XXX When we get a GUI going, this should be sent to it.
      if ((len == 2) && (buf[0] = 0x98))
	{
	  if (buf[1] == 0x04)
	    {
	      debug_printf(DEBUG_NORMAL, "Incorrect PIN, at least one attempt "
			   "remaining!\n");
	      return NULL;
	    } 
	  else if (buf[1] == 0x40)
	    {
	      debug_printf(DEBUG_NORMAL, "Incorrect PIN, no attempts "
			   "remaining!\n");
	      return NULL;
	    }
	}
    }

  len = MAXBUFF;
  if (cardio(card_hdl, SELECT_EF_IMSI, reader_mode, MODE2G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error attempting to select the IMSI on the"
		   " smart card!  (%s:%d)\n", __FUNCTION__, __LINE__);
      return NULL;
    }

  len = MAXBUFF;
  memset((char *)&buf, 0x00, 512);
  if (cardio(card_hdl, GET_IMSI, reader_mode, MODE2G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error attempting to get the IMSI from the "
		   "smart card! (%s:%d)\n", __FUNCTION__, __LINE__);
      return NULL;
    }

  return decode_imsi((unsigned char *)&buf[1]);
}

int sm_handler_do_2g_auth(SCARDHANDLE *card_hdl, char reader_mode, 
			  unsigned char *challenge, unsigned char *response, 
			  unsigned char *ckey)
{
  unsigned char buf[MAXBUFF], buff2[MAXBUFF], buff3[MAXBUFF];
  int i;
  DWORD len;

  if ((!challenge) || (!response) || (!ckey))
    {
      debug_printf(DEBUG_NORMAL, "Invalid data passed to "
		   "sm_handler_do_2g_auth!\n");
      return -1;
    }

  strcpy(buff2, RUN_GSM);
  memset(&buff3, 0x00, MAXBUFF);

  for (i = 0; i < 16; i++)
    {
      sprintf(buff3,"%02X",challenge[i]);
      if (Strcat(buff2, sizeof(buff2), buff3) != 0)
	{
	  fprintf(stderr, "Refusing to overflow string!\n");
	  return -1;
	}
    }

  len = MAXBUFF;
  if (cardio(card_hdl, buff2, reader_mode, MODE2G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error attempting to run the GSM algorithm!\n");
      return -1;
    }

  memcpy(response, &buf[0], 4);

  memcpy(ckey, &buf[4], 8);
  return XENONE;
}


char *sm_handler_3g_imsi(SCARDHANDLE *card_hdl, char reader_mode, char *pin)
{
  DWORD len;
  unsigned char buf[MAXBUFF], buf2[MAXBUFF], aid[MAXBUFF], temp[MAXBUFF], *p;
  unsigned char cmd[MAXBUFF], buf3[MAXBUFF];
  int i,l,q, foundaid=0, pinretries=0;
  unsigned char threeG[2] = { 0x10, 0x02 };
  struct t_efdir *t;

  if (!card_hdl)
    {
      debug_printf(DEBUG_NORMAL, "Invalid card handle passed to "
		   "sm_handler_3g_imsi()!\n");
      return NULL;
    }

  if (strlen(pin) > 8)
    {
      // XXX This should be returned to a GUI when we have one!
      debug_printf(DEBUG_NORMAL, "PIN is too long!\n");
      return NULL;
    }

  // Select the USIM master file.
  if (cardio(card_hdl, SELECT_MF_USIM, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error attempting to select the master file "
		   "on the SIM card! (%s:%d)\n", __FUNCTION__, __LINE__);
      return NULL;
    }

  if (buf[0] == 0x6e)
    {
      debug_printf(DEBUG_NORMAL, "3G mode not supported by this card!\n");
      return NULL;
    }

  // Select the ICCID of the card.
  if (cardio(card_hdl, SELECT_EF_ICCID, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error attempting to select the ICCID of "
		   "this SIM card! (%s:%d)\n", __FUNCTION__, __LINE__);
      return NULL;
    }

  if (cardio(card_hdl, SELECT_FCP, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error attempting to select the FCP of this "
		   "SIM card!  (%s:%d)\n", __FUNCTION__, __LINE__);
      return NULL;
    }

  if (cardio(card_hdl, SELECT_EFDIR, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error selecting the EFDIR on this SIM card!"
		   " (%s:%d)\n", __FUNCTION__, __LINE__);
      return NULL;
    }

  if (cardio(card_hdl, EFDIR_READREC1, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error attempting to read record #1 from "
		   "this SIM card! (%s:%d)\n", __FUNCTION__, __LINE__);
      return NULL;
    }

  l = buf[len-1];
  i = 1;

  // Loop over EFdir
  do {
    
    sprintf(buf, "00B2%2.2X04%2.2X",i,l);
    if (cardio(card_hdl, buf, reader_mode, MODE3G, (LPBYTE)&buf2, &len, DO_DEBUG) != 0)
      {
	debug_printf(DEBUG_NORMAL, "Error attempting to read a record from "
		     "this SIM card! (%s:%d)\n", __FUNCTION__, __LINE__);
	return NULL;
      }
    i++;
    t = (struct t_efdir *)&buf2;
    
    if (!memcmp(&t->app_code, &threeG, 2))
      {
	memset((unsigned char *)&aid, 0x00, MAXBUFF);

	p = (unsigned char *)&t->rid;
	for (q=0; q< 12; q++)
	  {
	    sprintf(temp, "%02X", *p++);
	    if (Strcat(aid, sizeof(aid), temp) != 0)
	      {
		fprintf(stderr, "Refusing to overflow string!\n");
		return NULL;
	      }
	  }
	foundaid = 1;
      }
    
  } while ((buf2[len-2] == 0x90) && (buf2[len-1] == 0));

  // Select the USIM aid.
  strcpy(cmd, "00A404040C");
  if (Strcat(cmd, sizeof(cmd), aid) != 0)
    {
      fprintf(stderr, "Refusing to overflow string!\n");
      return NULL;
    }

  if (cardio(card_hdl, cmd, reader_mode, MODE3G, (LPBYTE)&buf2, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Couldn't select the USIM application ID! "
		   "(%s:%d)\n", __FUNCTION__, __LINE__);
      return NULL;
    }

  // Determine remaining CHV retires.
  if (cardio(card_hdl, CHV_RETRIES, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error requesting the remaining number of "
		   "PIN attempts from this SIM!  (%s:%d)\n", __FUNCTION__,
		   __LINE__);
      return NULL;
    }

  if (buf[0] == 0x63)
    {
      pinretries = buf[1] & 0x0f;
    }

  //  if (!(buf2[13] & 0x80))
    {
      if (pinretries == 0)
	{
	  debug_printf(DEBUG_NORMAL, "No PIN retries remaining!\n");
	  return NULL;
	}

      // Otherwise, enter the PIN.
      strcpy(buf2, CHV_ATTEMPT);
      for (i=0;i < strlen(pin); i++)
	{
	  memset((char *)&buf3, 0x00, 8);
	  sprintf(buf3, "%02X", pin[i]);
	  if (Strcat(buf2, sizeof(buf2), buf3) != 0)
	    {
	      fprintf(stderr, "Refusing to overflow string!\n");
	      return NULL;
	    }
	}
      for (i=strlen(pin); i<8; i++)
	{
	  if (Strcat(buf2, sizeof(buf2), "FF") != 0)
	    {
	      fprintf(stderr, "Refusing to overflow string!\n");
	      return NULL;
	    }
	}

      if (cardio(card_hdl, buf2, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
	{
	  debug_printf(DEBUG_NORMAL, "Invalid PIN! (%d tries remain.)\n",
		       pinretries-1);
	  return NULL;
	}

      if (cardio(card_hdl, buf2, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
	{
	  debug_printf(DEBUG_NORMAL, "Invalid PIN! (%d tries remain.)\n",
		       pinretries-1);
	  return NULL;
	}
    } //else {
      //      debug_printf(DEBUG_SMARTCARD, "PIN not needed!\n");
      //}

  // Now, get the IMSI
  if (cardio(card_hdl, USELECT_EF_IMSI, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error attempting to select the IMSI for this"
		   " SIM card! (%s:%d)\n", __FUNCTION__, __LINE__);
      return NULL;
    }

  // XXX For now, assume that IMSIs are 9 bytes.
  if (cardio(card_hdl, READ_IMSI, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error reading the IMSI on this SIM card! "
		   "(%s:%d)\n", __FUNCTION__, __LINE__);
      return NULL;
    }

  return decode_imsi((unsigned char *)&buf[1]);
}

/* tack on a sequence of hex command bytes to a string
 * buffer is assumed to already contain a zero-terminated string
 */
int
addhex(u8 *buffer, unsigned int buflen, const u8 *bytes, int len)
{
  u8 temp[5];
  int i;

  for (i = 0; i < len; i++) {
      sprintf(temp,"%02X", *bytes++);
      if (Strcat(buffer, buflen, temp) != 0)
	{
	  fprintf(stderr, "Refusing to overflow string!\n");
	  return -1;
	}
  }

  return 0;
}

// return -2 on sync failure. -1 for all other errors.
int sm_handler_do_3g_auth(SCARDHANDLE *card_hdl, char reader_mode, 
			  unsigned char *Rand, unsigned char *autn, 
			  unsigned char *c_auts, char *res_len, 
			  unsigned char *c_sres, unsigned char *c_ck, 
			  unsigned char *c_ik, unsigned char *c_kc)
{
  unsigned char cmd[MAXBUFF], buf[MAXBUFF], sw1, sw2, *s;
  DWORD len;

  if (Strcpy(cmd, sizeof(cmd), "008800812210") != 0)
    {
      fprintf(stderr, "Refusing to overflow string!\n");
      return -1;
    }

  if (addhex(cmd, sizeof(cmd), Rand, 16) != 0)
    {
      fprintf(stderr, "Refusing to overflow string!\n");
      return -1;
    }

  if (Strcat(cmd, sizeof(cmd), "10") != 0)
    {
      fprintf(stderr, "Refusing to overflow string!\n");
      return -1;
    }

  if (addhex(cmd, sizeof(cmd), autn, 16) != 0)
    {
      fprintf(stderr, "Refusing to overflow string!\n");
      return -1;
    }

  debug_printf(DEBUG_SMARTCARD, "Sending in '%s'\n", cmd);

  len = MAXBUFF;

  if (cardio(card_hdl, cmd, reader_mode, MODE3G, (LPBYTE)&buf, &len, DO_DEBUG) != 0)
    {
      debug_printf(DEBUG_NORMAL, "Error attempting to execute 3G "
		   "authentication! (%s:%d)\n", __FUNCTION__, __LINE__);
      return -1;
    }

  sw1 = buf[len-2]; sw2 = buf[len-1];

  if ((sw1 == 0x90) && (sw2 == 0x00) && (buf[0] == 0xdc))
    {
      debug_printf(DEBUG_NORMAL, "Sync failure! (Result length = %d)\n",
		   len);
      memcpy(c_auts, buf+2, len);
      return -2;
    }

  if ((sw1 == 0x90) && (sw2 == 0x00) && (buf[0] == 0xdb))
    {
      // Success.
      s = buf+1;
      *res_len = *s;
      memcpy(c_sres, s+1, *s); 
      s += (*s+1);  // Step over TLV vectors
      memcpy(c_ck, s+1, *s);
      s += (*s+1);  // Ditto.
      memcpy(c_ik, s+1, *s);
      s += (*s+1);
      memcpy(c_kc, s+1, *s); s += *s;
      return 0;
    }
  
  // Otherwise, we failed.
  return -1;
}

int sm_handler_card_disconnect(SCARDHANDLE *card_hdl)
{
  long ret = 0;

  if (card_hdl)
    {
      ret = SCardDisconnect(*card_hdl, SCARD_UNPOWER_CARD);
      if (ret != SCARD_S_SUCCESS)
	{
	  debug_printf(DEBUG_NORMAL, "Couldn't disconnect from Smart Card! ");
	  print_sc_error(ret);
	} else {
	  card_hdl = NULL;
	}
    }
  
  return ret;
}


int sm_handler_close_sc(SCARDHANDLE *card_hdl, SCARDCONTEXT *card_ctx)
{
  long ret;

  if (card_hdl)
    {
      ret = SCardDisconnect(*card_hdl, SCARD_UNPOWER_CARD);
      if (ret != SCARD_S_SUCCESS)
	{
	  debug_printf(DEBUG_NORMAL, "Couldn't disconnect from Smart Card! ");
	  print_sc_error(ret);
	}
    }

  if (card_ctx)
    {
      ret = SCardReleaseContext(*card_ctx);
      if (ret != SCARD_S_SUCCESS)
	{
	  debug_printf(DEBUG_NORMAL, "Couldn't release Smart Card context!  ");
	  print_sc_error(ret);
	}
    }

  return 0;
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -