void
yubikey_parse (const uint8_t token[32],
	       const uint8_t key[16], yubikey_token_t out)
{
  memset (out, 0, sizeof (*out));
  yubikey_modhex_decode ((void *) out, (char *) token, sizeof (*out));
  yubikey_aes_decrypt ((void *) out, key);
}
예제 #2
0
파일: zxpw.c 프로젝트: kiwiroy/zx
/* Called by:  zx_password_authn */
int zx_yubikey_authn(const char* cpath, char* uid, const char* passw, const char* pin)
{
  unsigned char uidpath[256];
  unsigned char pw_buf[256];
  unsigned char pw_hash[120];
  yubikey_token_st yktok;
  int len = strlen(uid);

  strcpy((char*)pw_hash, uid + len - 32);
  uid[len - 32] = 0;
  D("yubikey user(%s) ticket(%s) pin(%s)", uid, pw_hash, STRNULLCHK(pin));
  
  snprintf((char*)uidpath, sizeof(uidpath)-1, "%s" ZXID_UID_DIR "%s", cpath, uid);
  uidpath[sizeof(uidpath)-1] = 0;
  len = read_all(sizeof(pw_buf), (char*)pw_buf, "ykspent", 0, "%s/.ykspent/%s", uidpath, pw_hash);
  if (len) {
    ERR("The One Time Password has already been spent. ticket(%s%s) pw_buf(%.*s)", uid, pw_hash, len, pw_buf);
    return 0;
  }
  if (!write_all_path("ykspent", "%s/.ykspent/%s", (char*)uidpath, (char*)pw_hash, 1, "1"))
    return 0;
  
  len = read_all(sizeof(pw_buf), (char*)pw_buf, "ykaes", 1, "%s/.yk", uidpath);
  D("buf    (%s) got=%d", pw_buf, len);
  if (len < 32) {
    ERR("User's %s/.yk file must contain aes128 key as 32 hexadecimal characters. Too few characters %d ticket(%s)", uid, len, pw_hash);
    return 0;
  }
  if (len > 32) {
    INFO("User's %s/.yk file must contain aes128 key as 32 hexadecimal characters. Too many characters %d ticket(%s). Truncating.", uid, len, pw_hash);
    len = 32;
    pw_buf[len] = 0;
  }
  zx_hexdec((char*)pw_buf, (char*)pw_buf, len, hex_trans);
  ZERO(&yktok, sizeof(yktok));
  zx_hexdec((void*)&yktok, (char*)pw_hash, 32, ykmodhex_trans);
  yubikey_aes_decrypt((void*)&yktok, pw_buf);
  D("internal uid %02x %02x %02x %02x %02x %02x counter=%d 0x%x timestamp=%d (hi=%x lo=%x) use=%d 0x%x rnd=0x%x crc=0x%x", yktok.uid[0], yktok.uid[1], yktok.uid[2], yktok.uid[3], yktok.uid[4], yktok.uid[5], yktok.ctr, yktok.ctr, (yktok.tstph << 16) | yktok.tstpl, yktok.tstph, yktok.tstpl, yktok.use, yktok.use, yktok.rnd, yktok.crc);
  
  if (!yubikey_crc_ok_p((unsigned char*)&yktok)) {
    ERR("yubikey ticket validation failure %d", 0);
    return 0;
  }

  if (pin && *pin) { /* Pin supplied, may be we can perform two factor authn? */
    len = read_all(sizeof(pw_buf), (char*)pw_buf, "pin", 1, "%s/.pin", uidpath);
    if (zx_pw_chk(uid, (char*)pw_buf, pin, 0)) {
      D("Two factor pin+yubikey successful. %d", 1);
      return 4;
    }
    ERR("pin validation failure (after successful yubikey) %d", 0);
    return 0;
  }

  return 3;
}
예제 #3
0
파일: yubikey.c 프로젝트: SylvestreG/bitrig
int
yubikey_parse(const uint8_t *password, const uint8_t key[YUBIKEY_KEY_SIZE],
    yubikey_token_t out, int index)
{
	wchar_t *wpassword, *pp;
	char token[YUBIKEY_TOKEN_SIZE + 1], *lc_ctype;
	int len;

	if (index < 0 || index >= YUBIKEY_KEYMAP_COUNT)
		return -1;

	len = strlen(password);
	pp = wpassword = malloc(sizeof(wchar_t) * (len + 1));
	if (pp == NULL)
		return ENOMEM;
	
	memset(out, 0, sizeof(*out));
	memset(token, 0, YUBIKEY_TOKEN_SIZE + 1);

	lc_ctype = getenv("LC_CTYPE");
	setlocale(LC_CTYPE, lc_ctype ? lc_ctype : "C.UTF-8");
	len = mbstowcs(wpassword, password, len);
	if (len < 0) {
		return errno;
	}
	setlocale(LC_CTYPE, "C");

	if (len > YUBIKEY_TOKEN_SIZE)
		pp = pp + len - YUBIKEY_TOKEN_SIZE;
	if (len < YUBIKEY_TOKEN_SIZE)
		return EMSGSIZE;
	
	if (yubikey_keymap_decode(pp, token, index))
		return EINVAL;
	yubikey_modhex_decode((void *)out, token, sizeof(*out));
	yubikey_aes_decrypt((void *)out, key);
	return 0;
}
예제 #4
0
static void
aes_test1 (void)
{
  size_t i;
  uint8_t buf[1024];
  uint8_t key[16 + 1];

  memcpy (buf, "0123456789abcdef\0", 17);
  memcpy (key, "abcdef0123456789\0", 17);
  printf ("aes-decrypt (data=%s, key=%s)\n => ", (char *) buf, (char *) key);
  yubikey_aes_decrypt (buf, key);
  for (i = 0; i < 16; i++)
    printf ("%02x", buf[i] & 0xFF);
  printf ("\n");

  assert (memcmp (buf,
		  "\x83\x8a\x46\x7f\x34\x63\x95\x51"
		  "\x75\x5b\xd3\x2a\x4a\x2f\x15\xe1", 16) == 0);
  printf ("AES-1.1 success\n");

  yubikey_aes_encrypt (buf, key);
  assert (memcmp (buf, "0123456789abcdef", 16) == 0);
  printf ("AES-1.2 success\n");
}
예제 #5
0
int
main (void)
{
  char buf[1024];
  size_t i;
  int rc;
  yubikey_token_st tok;


  /* Test Modhex */
  yubikey_modhex_encode (buf, "test", 4);
  printf ("modhex-encode(\"test\") = %s\n", buf);
  if (strcmp (buf, "ifhgieif") != 0)
    {
      printf ("ModHex failure\n");
      return 1;
    }
  printf ("Modhex-1 success\n");

  printf ("modhex-decode(\"%s\") = ", buf);
  yubikey_modhex_decode (buf, buf, strlen ((char *) buf));
  printf ("%.*s\n", 4, buf);
  if (memcmp (buf, "test", 4) != 0)
    {
      printf ("ModHex failure\n");
      return 1;
    }
  printf ("Modhex-2 success\n");

  strcpy (buf, "cbdefghijklnrtuv");
  rc = yubikey_modhex_p (buf);
  printf ("hex-p(\"%s\") = %d\n", buf, rc);
  if (!rc)
    {
      printf ("Hex_p failure\n");
      return 1;
    }
  printf ("Hex-3 success\n");

  strcpy (buf, "0123Xabc");
  rc = yubikey_hex_p (buf);
  printf ("hex-p(\"%s\") = %d\n", buf, rc);
  if (rc)
    {
      printf ("Hex_p failure\n");
      return 1;
    }
  printf ("Hex-3 success\n");

  /* Test Hex */

  yubikey_hex_encode (buf, "test", 4);
  printf ("hex-encode(\"test\") = %s\n", buf);
  if (strcmp (buf, "74657374") != 0)
    {
      printf ("Hex failure\n");
      return 1;
    }
  printf ("Hex-1 success\n");

  printf ("hex-decode(\"%s\") = ", buf);
  yubikey_hex_decode (buf, buf, strlen ((char *) buf));
  printf ("%.*s\n", 4, buf);
  if (memcmp (buf, "test", 4) != 0)
    {
      printf ("Hex failure\n");
      return 1;
    }
  printf ("Hex-2 success\n");

  strcpy (buf, "0123456789abcdef");
  rc = yubikey_hex_p (buf);
  printf ("hex-p(\"%s\") = %d\n", buf, rc);
  if (!rc)
    {
      printf ("Hex_p failure\n");
      return 1;
    }
  printf ("Hex-3 success\n");

  strcpy (buf, "0123Xabc");
  rc = yubikey_hex_p (buf);
  printf ("hex-p(\"%s\") = %d\n", buf, rc);
  if (rc)
    {
      printf ("Hex_p failure\n");
      return 1;
    }
  printf ("Hex-3 success\n");

  /* Test AES */

  {
    uint8_t buf[1024];
    char out[1024];
    uint8_t key[16 + 1];

    memcpy (buf, "0123456789abcdef\0", 17);
    memcpy (key, "abcdef0123456789\0", 17);
    printf ("aes-decrypt (data=%s, key=%s)\n => ", (char *) buf,
	    (char *) key);
    yubikey_aes_decrypt (buf, key);
    for (i = 0; i < 16; i++)
      printf ("%02x", buf[i] & 0xFF);
    printf ("\n");

    if (memcmp (buf,
		"\x83\x8a\x46\x7f\x34\x63\x95\x51"
		"\x75\x5b\xd3\x2a\x4a\x2f\x15\xe1", 16) != 0)
      {
	printf ("AES failure\n");
	return 1;
      }
    printf ("AES-1 success\n");

    yubikey_aes_encrypt (buf, key);
    if (memcmp (buf, "0123456789abcdef", 16) != 0)
      {
	printf ("AES encryption failure\n");
	return 1;
      }
    printf ("AES-2 success\n");

    /* Test OTP */

    memcpy ((void *) &tok,
	    "\x16\xe1\xe5\xd9\xd3\x99\x10\x04\x45\x20\x07\xe3\x02\x00\x00",
	    16);
    memcpy (key, "abcdef0123456789", 16);

    yubikey_generate ((void *) &tok, key, out);
    yubikey_parse ((uint8_t *) out, key, &tok);

    if (memcmp
	(&tok, "\x16\xe1\xe5\xd9\xd3\x99\x10\x04\x45\x20\x07\xe3\x02\x00\x00",
	 16) != 0)
      {
	printf ("OTP generation - parse failure\n");
	return 1;
      }
    printf ("OTP-1 success\n");
  }

  return 0;
}