コード例 #1
0
ファイル: yubikey.c プロジェクト: Dekryptor/winauth
///
/// Check if the specified slot has been configured
///
__declspec(dllexport) int IsSlotConfigured(int slot, bool* result)
{
	YK_INFO info;
	YK_KEY* key;

	key = yk_open_first_key();
	if (key == NULL)
	{
		_lastError = yk_errno;
		return ERROR_CANNOT_OPEN_KEY;
	}

	yk_get_status(key, &info.status);

	if (slot == 1 && (info.status.touchLevel & CONFIG1_VALID) != 0)
	{
		*result = true;
	}
	else if (slot == 2 && (info.status.touchLevel & CONFIG2_VALID) != 0)
	{
		*result = true;
	}
	else
	{
		*result = false;
	}

	yk_close_key(key);

	return 0;
}
コード例 #2
0
ファイル: util.c プロジェクト: mabels/yubico-pam
int
check_firmware_version(YK_KEY *yk, bool verbose, bool quiet)
{
	YK_STATUS *st = ykds_alloc();

	if (!yk_get_status(yk, st)) {
		free(st);
		return 0;
	}

	if (verbose) {
		printf("Firmware version %d.%d.%d\n",
		       ykds_version_major(st),
		       ykds_version_minor(st),
		       ykds_version_build(st));
		fflush(stdout);
	}

	if (ykds_version_major(st) < 2 ||
	    (ykds_version_major(st) == 2
         && ykds_version_minor(st) < 2)) {
		if (! quiet)
			fprintf(stderr, "Challenge-response not supported before YubiKey 2.2.\n");
		free(st);
		return 0;
	}

	free(st);
	return 1;
}
コード例 #3
0
int yk_check_firmware_version(YK_KEY *k)
{
	YK_STATUS st;

	if (!yk_get_status(k, &st))
		return 0;

	return yk_check_firmware_version2(&st);
}
コード例 #4
0
static int _yk_write(YK_KEY *yk, uint8_t yk_cmd, unsigned char *buf, size_t len)
{
	YK_STATUS stat;
	int seq;

	/* Get current sequence # from status block */

	if (!yk_get_status(yk, &stat /*, 0*/))
		return 0;

	seq = stat.pgmSeq;

	/* Write to Yubikey */
	if (!yk_write_to_key(yk, yk_cmd, buf, len))
		return 0;

	/* When the Yubikey clears the SLOT_WRITE_FLAG, it has processed the last write.
	 * This wait can't be done in yk_write_to_key since some users of that function
	 * want to get the bytes in the status message, but when writing configuration
	 * we don't expect any data back.
	 */
	if(!yk_wait_for_key_status(yk, yk_cmd, 0, WAIT_FOR_WRITE_FLAG, false, SLOT_WRITE_FLAG, NULL))
		return 0;

	/* Verify update */

	if (!yk_get_status(yk, &stat /*, 0*/))
		return 0;

	yk_errno = YK_EWRITEERR;

	/* when both configurations from a YubiKey is erased it will return
	 * pgmSeq 0, if one is still configured after an erase pgmSeq is
	 * counted up as usual. */
	if((stat.touchLevel & (CONFIG1_VALID | CONFIG2_VALID)) == 0 && stat.pgmSeq == 0) {
		return 1;
	}
	return stat.pgmSeq != seq;
}
コード例 #5
0
YK_KEY *yk_open_first_key(void)
{
	YK_KEY *yk = _ykusb_open_device(YUBICO_VID, YUBIKEY_PID);
	int rc = yk_errno;

	if (yk) {
		YK_STATUS st;

		if (!yk_get_status(yk, &st)) {
			rc = yk_errno;
			yk_close_key(yk);
			yk = NULL;
		}
	}
	yk_errno = rc;
	return yk;
}
コード例 #6
0
YK_KEY *yk_open_first_key(void)
{
	int pids[] = {YUBIKEY_PID, NEO_OTP_PID, NEO_OTP_CCID_PID};

	YK_KEY *yk = _ykusb_open_device(YUBICO_VID, pids, sizeof(pids));
	int rc = yk_errno;

	if (yk) {
		YK_STATUS st;

		if (!yk_get_status(yk, &st)) {
			rc = yk_errno;
			yk_close_key(yk);
			yk = NULL;
		}
	}
	yk_errno = rc;
	return yk;
}
コード例 #7
0
ファイル: yubikey.c プロジェクト: Dekryptor/winauth
///
/// Get the Info about the first YubiKey
///
__declspec(dllexport) int GetInfo(YK_INFO *info)
{
	int pid;
	YK_KEY* key = yk_open_first_key_with_pid(&pid);
	if (key == NULL)
	{
		_lastError = yk_errno;
		return ERROR_CANNOT_OPEN_KEY;
	}

	yk_get_status(key, &info->status);

	yk_get_serial(key, 0, 0, &info->serial);

	info->pid = pid;

	yk_close_key(key);

	return 0;
}
コード例 #8
0
YK_KEY *yk_open_key(int index)
{
	int pids[] = {YUBIKEY_PID, NEO_OTP_PID, NEO_OTP_CCID_PID,
		NEO_OTP_U2F_PID, NEO_OTP_U2F_CCID_PID, YK4_OTP_PID,
		YK4_OTP_U2F_PID, YK4_OTP_CCID_PID, YK4_OTP_U2F_CCID_PID,
		PLUS_U2F_OTP_PID};

	YK_KEY *yk = _ykusb_open_device(YUBICO_VID, pids, sizeof(pids) / sizeof(int), index);
	int rc = yk_errno;

	if (yk) {
		YK_STATUS st;

		if (!yk_get_status(yk, &st)) {
			rc = yk_errno;
			yk_close_key(yk);
			yk = NULL;
		}
	}
	yk_errno = rc;
	return yk;
}
コード例 #9
0
int yk_check_firmware_version(YK_KEY *k)
{
	YK_STATUS st;

	if (!yk_get_status(k, &st))
		return 0;
	if (!((st.versionMajor == 0 &&
	       (st.versionMinor == 9 ||
		st.versionBuild == 9)) ||
	      (st.versionMajor == 1 &&
	       (st.versionMinor == 0 ||
		st.versionMinor == 1 ||
		st.versionMinor == 2 ||
		st.versionMinor == 3)) ||
	      (st.versionMajor == 2 &&
	       (st.versionMinor == 0 ||
		st.versionMinor == 1 ||
		st.versionMinor == 2 ||
		st.versionMinor == 3)))) {
		yk_errno = YK_EFIRMWARE;
		return 0;
	}
	return 1;
}
コード例 #10
0
void YubiKeyWriter::writeConfig(YubiKeyConfig *ykConfig) {

    YubiKeyFinder::getInstance()->stop();

    YK_KEY *yk = 0;
    YK_STATUS *ykst = YubiKeyFinder::getInstance()->status();
    YKP_CONFIG *cfg = ykp_alloc();

    bool error = false;

    qDebug() << "-------------------------";
    qDebug() << "Starting write config";
    qDebug() << "-------------------------";

    try {
        if (!(yk = yk_open_first_key())) {
            throw 0;
        } else if (!yk_get_status(yk, ykst)) {
            throw 0;
        }

        ykp_configure_version(cfg, ykst);

        qDebug() << "writer:configuration slot:" << ykConfig->configSlot();

        bool useAccessCode;
        unsigned char accessCode[MAX_SIZE];

        if(!assembleConfig(ykConfig, cfg, &useAccessCode, accessCode)) {
            throw 0;
        }

        //Log configuration...
        qDebug() << "-------------------------";
        qDebug() << "Config data to be written to key configuration...";

        char conf_buf[1024];
        ykp_export_config(cfg, conf_buf, 1024, YKP_FORMAT_LEGACY);
        qDebug() << conf_buf;

        qDebug() << "-------------------------";

        // Write configuration...
        if (!yk_write_command(yk,
                              ykp_core_config(cfg), ykp_command(cfg),
                              useAccessCode ? accessCode : NULL)) {
            qDebug() << "Failure";
            throw 0;
        }
        qDebug() << "Success... config written";
        emit diagnostics(QString("Successfully wrote config to slot %1").arg(ykp_config_num(cfg)));

        YubiKeyLogger::logConfig(ykConfig);
        emit configWritten(true, NULL);
    }
    catch(...) {
        error = true;
    }

    if (cfg) {
        ykp_free_config(cfg);
    }

    if (yk && !yk_close_key(yk)) {
        error = true;
    }

    YubiKeyFinder::getInstance()->start();

    if(error) {
        qDebug() << "Config not written";
        QString errMsg = reportError();
        emit configWritten(false, errMsg);
    }

    qDebug() << "-------------------------";
    qDebug() << "Stopping write config";
    qDebug() << "-------------------------";
}
コード例 #11
0
int main(int argc, char **argv)
{
	YK_KEY *yk = 0;
	bool error = true;
	int exit_code = 0;

	/* Options */
	bool serial_dec = false;
	bool serial_modhex = false;
	bool serial_hex = false;
	bool version = false;
	bool touch_level = false;
	bool pgm_seq = false;
	bool slot1 = false;
	bool slot2 = false;
	bool vid = false;
	bool pid = false;

	bool quiet = false;

	yk_errno = 0;

	if (! parse_args(argc, argv,
				&serial_dec, &serial_modhex, &serial_hex,
				&version, &touch_level, &pgm_seq, &quiet,
				&slot1, &slot2, &vid, &pid,
				&exit_code))
		exit(exit_code);

	if (!yk_init()) {
		exit_code = 1;
		goto err;
	}

	if (!(yk = yk_open_first_key())) {
		exit_code = 1;
		goto err;
	}

	if(serial_dec || serial_modhex || serial_hex) {
		unsigned int serial;
		int ret = yk_get_serial(yk, 1, 0, &serial);
		if(!ret) {
			exit_code = 1;
			goto err;
		}
		if(serial_dec) {
			if(!quiet)
				printf("serial: ");
			printf("%d\n", serial);
		}
		if(serial_modhex || serial_hex) {
			char buf[64];
			char hex_serial[64];
			char modhex_serial[64];
			char *ptr = buf;

			int chars = snprintf(buf + 1, 63, "%x", serial);
			if(chars % 2 == 1) {
				buf[0] = '0';
			} else {
				ptr += 1;
			}
			if(serial_hex) {
				if(!quiet)
					printf("serial_hex: ");
				printf("%s\n", ptr);
			}
			if(serial_modhex) {
				yubikey_hex_decode(hex_serial, ptr, strlen(ptr));
				yubikey_modhex_encode(modhex_serial, hex_serial, strlen(hex_serial));
				if(!quiet)
					printf("serial_modhex: ");
				printf("%s\n", modhex_serial);
			}
		}
	}
	if(version || touch_level || pgm_seq || slot1 || slot2) {
		YK_STATUS *st = ykds_alloc();
		if(!yk_get_status(yk, st)) {
			ykds_free(st);
			exit_code = 1;
			goto err;
		}

		if(version) {
			if(!quiet)
				printf("version: ");
			printf("%d.%d.%d\n", ykds_version_major(st), ykds_version_minor(st), ykds_version_build(st));
		}
		if(touch_level) {
			if(!quiet)
				printf("touch_level: ");
			printf("%d\n", ykds_touch_level(st));
		}
		if(pgm_seq) {
			if(!quiet)
				printf("programming_sequence: ");
			printf("%d\n", ykds_pgm_seq(st));
		}
		if(slot1) {
			if(!quiet)
				printf("slot1_status: ");
			printf("%d\n", (ykds_touch_level(st) & CONFIG1_VALID) == CONFIG1_VALID);
		}
		if(slot2) {
			if(!quiet)
				printf("slot2_status: ");
			printf("%d\n", (ykds_touch_level(st) & CONFIG2_VALID) == CONFIG2_VALID);
		}
		ykds_free(st);
	}
	if(vid || pid) {
		int vendor_id, product_id;
		if(!yk_get_key_vid_pid(yk, &vendor_id, &product_id)) {
			exit_code = 1;
			goto err;
		}
		if(vid) {
			if(!quiet)
				printf("vendor_id: ");
			printf("%x\n", vendor_id);
		}
		if(pid) {
			if(!quiet)
				printf("product_id: ");
			printf("%x\n", product_id);
		}
	}

	exit_code = 0;
	error = false;

err:
	if (error || exit_code != 0) {
		report_yk_error();
	}

	if (yk && !yk_close_key(yk)) {
		report_yk_error();
		exit_code = 2;
	}

	if (!yk_release()) {
		report_yk_error();
		exit_code = 2;
	}

	exit(exit_code);
}
コード例 #12
0
ファイル: yubicrack.c プロジェクト: Nerzahd/yubicrack
int main(int argc, char** argv) {

	char showmessage = 1;
	if((argc == 2) && (strcmp(argv[1], "-y") == 0)) showmessage = 0;
	if(showmessage == 1) {
		puts("--------------------------------------------");
		puts("Hi! You're going to crack the access code of");
		puts("a Yubikey. As soon as the appropriate code  ");
		puts("is found, the AES key will be set to zeros.");
		puts("Brute forcing the code can take a very long ");
		puts("time, and with long I mean like more than a ");
		puts("year.");
		puts("(By the way you can bypass this message by  ");
		puts("passing the -y option to the program.) ");
		puts("--------------------------------------------");
		puts("Type \"start\" to continue.");

		char acknowledge[256];
		fgets(acknowledge, 256, stdin);
		if(strcmp(acknowledge, "start\n") != 0) {
			puts("Quitting.");
			return EXIT_SUCCESS;
		}
	} 

	yk = 0;
	unsigned char access_code[6];
	const char* aeshash="00000000000000000000000000000000";
	YKP_CONFIG *cfg = ykp_create_config();
	YK_STATUS *st = ykds_alloc();

	if(!yk_init()) {
		fputs("Failed to init Yubikey.\n", stderr);
		return EXIT_FAILURE;
	}
	if(!(yk = yk_open_first_key())) {
		fputs("No Yubikey found.\n", stderr);
		return EXIT_FAILURE;
	}
	if(!yk_get_status(yk,st)) {
		fputs("Failed to get status of the Yubikey.\n", stderr);
		return EXIT_FAILURE;
	}

	printf("Found Yubikey. Version: %d.%d.%d Touch level: %d\n",
		ykds_version_major(st),
		ykds_version_minor(st),
		ykds_version_build(st),
		ykds_touch_level(st));

	if(!ykp_configure_for(cfg, 1, st)) {
		printf("Can't set configuration to 1.\n");
		return EXIT_FAILURE;
	}
	if(ykp_AES_key_from_hex(cfg, aeshash)) {
		fputs("Bad AES key. WTF did you do to my source?", stderr);
		return EXIT_FAILURE;
	}

	coreconfig = ykp_core_config(cfg);
	coreconfignum = ykp_config_num(cfg);
	bruteforce(access_code, 5);

	if(st) free(st);
	if(!yk_close_key(yk)) {
		fputs("Can't close Yubikey! What the hell are you doing over there?", stderr);
		return EXIT_FAILURE;
	}
	if(!yk_release()) {
		fputs("Can't release Yubikey.", stderr);
		return EXIT_FAILURE;
	}

	if(cfg) ykp_free_config(cfg);

	return EXIT_SUCCESS;
}
コード例 #13
0
int main(int argc, char **argv)
{
	YK_KEY *yk = 0;
	bool error = true;
	int exit_code = 0;

	/* Options */
	bool serial_dec = false;
	bool serial_modhex = false;
	bool serial_hex = false;
	bool version = false;
	bool touch_level = false;
	bool pgm_seq = false;

	bool quiet = false;

	yk_errno = 0;

	if (! parse_args(argc, argv,
				&serial_dec, &serial_modhex, &serial_hex,
				&version, &touch_level, &pgm_seq, &quiet,
				&exit_code))
		exit(exit_code);

	if (!yk_init()) {
		exit_code = 1;
		goto err;
	}

	if (!(yk = yk_open_first_key())) {
		exit_code = 1;
		goto err;
	}

	if(serial_dec || serial_modhex || serial_hex) {
		unsigned int serial;
		int ret = yk_get_serial(yk, 1, 0, &serial);
		if(!ret) {
			exit_code = 1;
			goto err;
		}
		if(serial_dec) {
			if(!quiet)
				printf("serial: ");
			printf("%d\n", serial);
		}
		if(serial_hex) {
			if(!quiet)
				printf("serial_hex: ");
			printf("%x\n", serial);
		}
		if(serial_modhex) {
			char buf[64];
			char hex_serial[64];
			char modhex_serial[64];

			snprintf(buf, 64, "%x", serial);
			yubikey_hex_decode(hex_serial, buf, strlen(buf));
			yubikey_modhex_encode(modhex_serial, hex_serial, strlen(hex_serial));
			if(!quiet)
				printf("serial_modhex: ");
			printf("%s\n", modhex_serial);
		}
	}
	if(version || touch_level || pgm_seq) {
		YK_STATUS *st = ykds_alloc();
		if(!yk_get_status(yk, st)) {
			ykds_free(st);
			exit_code = 1;
			goto err;
		}

		if(version) {
			if(!quiet)
				printf("version: ");
			printf("%d.%d.%d\n", ykds_version_major(st), ykds_version_minor(st), ykds_version_build(st));
		}
		if(touch_level) {
			if(!quiet)
				printf("touch_level: ");
			printf("%d\n", ykds_touch_level(st));
		}
		if(pgm_seq) {
			if(!quiet)
				printf("programming_sequence: ");
			printf("%d\n", ykds_pgm_seq(st));
		}
		ykds_free(st);
	}

	exit_code = 0;
	error = false;

err:
	if (error || exit_code != 0) {
		report_yk_error();
	}

	if (yk && !yk_close_key(yk)) {
		report_yk_error();
		exit_code = 2;
	}

	if (!yk_release()) {
		report_yk_error();
		exit_code = 2;
	}

	exit(exit_code);
}
コード例 #14
0
int yk_write_config(YK_KEY *yk, YK_CONFIG *cfg, int confnum,
		    unsigned char *acc_code)
{
	unsigned char buf[sizeof(YK_CONFIG) + ACC_CODE_SIZE];
	YK_STATUS stat;
	int seq;
	uint8_t slot;

	/* Get current sequence # from status block */

	if (!yk_get_status(yk, &stat /*, 0*/))
		return 0;

	seq = stat.pgmSeq;

	/* Update checksum and insert config block in buffer if present */

	memset(buf, 0, sizeof(buf));

	if (cfg) {
		cfg->crc = ~yubikey_crc16 ((unsigned char *) cfg,
					   sizeof(YK_CONFIG) - sizeof(cfg->crc));
		cfg->crc = yk_endian_swap_16(cfg->crc);
		memcpy(buf, cfg, sizeof(YK_CONFIG));
	}

	/* Append current access code if present */

	if (acc_code)
		memcpy(buf + sizeof(YK_CONFIG), acc_code, ACC_CODE_SIZE);

	/* Write to Yubikey */

	switch(confnum) {
	case 1:
		slot = SLOT_CONFIG;
		break;
	case 2:
		slot = SLOT_CONFIG2;
		break;
	}

	if (!yk_write_to_key(yk, slot, buf, sizeof(buf)))
		return 0;

	/* When the Yubikey clears the SLOT_WRITE_FLAG, it has processed the last write.
	 * This wait can't be done in yk_write_to_key since some users of that function
	 * want to get the bytes in the status message, but when writing configuration
	 * we don't expect any data back.
	 */
	yk_wait_for_key_status(yk, slot, 0, WAIT_FOR_WRITE_FLAG, false, SLOT_WRITE_FLAG, NULL);

	/* Verify update */

	if (!yk_get_status(yk, &stat /*, 0*/))
		return 0;

	yk_errno = YK_EWRITEERR;
	if (cfg) {
		return stat.pgmSeq != seq;
	}

	return stat.pgmSeq == 0;

}