Exemplo n.º 1
0
static int _set_fixed(char *opt, YKP_CONFIG *cfg) {
	const char *fixed = opt;
	size_t fixedlen = strlen (fixed);
	unsigned char fixedbin[256];
	size_t fixedbinlen = 0;
	int rc = hex_modhex_decode(fixedbin, &fixedbinlen,
				   fixed, fixedlen,
				   0, 32, true);
	if (rc <= 0)
		return 0;

	ykp_set_fixed(cfg, fixedbin, fixedbinlen);
	return 1;
}
int YubiKeyWriter::assembleConfig(YubiKeyConfig *ykConfig, YKP_CONFIG *cfg, bool *useAccessCode, unsigned char *accessCode) {
    // Check features support
    bool flagSrNoSupport = false;
    bool flagUpdateSupport = false;
    bool flagImfSupport = false;
    bool flagLedInvSupport = false;

    YubiKeyFinder *finder = YubiKeyFinder::getInstance();
    if(finder->checkFeatureSupport(
            YubiKeyFinder::Feature_SerialNumber)) {
        flagSrNoSupport = true;
    }
    if(finder->checkFeatureSupport(
          YubiKeyFinder::Feature_Updatable)) {
        flagUpdateSupport = true;
    }
    if(finder->checkFeatureSupport(
          YubiKeyFinder::Feature_MovingFactor)) {
        flagImfSupport = true;
    }
    if(finder->checkFeatureSupport(
          YubiKeyFinder::Feature_LedInvert)) {
        flagLedInvSupport = true;
    }

    //Programming Mode...
    bool longSecretKey = false;

    int command = ykConfig->configSlot() == 2 ? SLOT_CONFIG2 : SLOT_CONFIG;

    switch(ykConfig->programmingMode()) {
        case YubiKeyConfig::Mode_Update:
            // if we're doing an update it's other commands.
            command = ykConfig->configSlot() == 2 ? SLOT_UPDATE2 : SLOT_UPDATE1;
            break;

        case YubiKeyConfig::Mode_Swap:
            // swap has it's own command
            command = SLOT_SWAP;
            break;

        case YubiKeyConfig::Mode_YubicoOtp:
            break;

        case YubiKeyConfig::Mode_Static:
            CFGFLAG(STATIC_TICKET,      ykConfig->staticTicket());
            CFGFLAG(SHORT_TICKET,       ykConfig->shortTicket());
            CFGFLAG(STRONG_PW1,         ykConfig->strongPw1());
            CFGFLAG(STRONG_PW2,         ykConfig->strongPw2());
            CFGFLAG(MAN_UPDATE,         ykConfig->manUpdate());
            CFGFLAG(SEND_REF,           ykConfig->sendRef());
            break;

        case YubiKeyConfig::Mode_OathHotp:
            TKTFLAG(OATH_HOTP, true);

            CFGFLAG(OATH_HOTP8,         ykConfig->oathHotp8());
            CFGFLAG(OATH_FIXED_MODHEX1, ykConfig->oathFixedModhex1());
            CFGFLAG(OATH_FIXED_MODHEX2, ykConfig->oathFixedModhex2());
            CFGFLAG(OATH_FIXED_MODHEX,  ykConfig->oathFixedModhex());

            //Moving Factor Seed...
            if(flagImfSupport && !ykp_set_oath_imf(cfg, ykConfig->oathMovingFactorSeed())) {
                return 0;
            }

            //For OATH-HOTP, 160 bits key is also valid
            longSecretKey = true;
            break;

        case YubiKeyConfig::Mode_ChalRespYubico:
            TKTFLAG(CHAL_RESP, true);

            CFGFLAG(CHAL_YUBICO,        ykConfig->chalYubico());
            CFGFLAG(CHAL_BTN_TRIG,      ykConfig->chalBtnTrig());
            break;

        case YubiKeyConfig::Mode_ChalRespHmac:
            TKTFLAG(CHAL_RESP, true);

            CFGFLAG(CHAL_HMAC,          ykConfig->chalHmac());
            CFGFLAG(HMAC_LT64,          ykConfig->hmacLT64());
            CFGFLAG(CHAL_BTN_TRIG,      ykConfig->chalBtnTrig());

            //For HMAC (not Yubico) challenge-response, 160 bits key is also valid
            longSecretKey = true;
            break;
    }

    //Configuration slot...
    if (!ykp_configure_command(cfg, command)) {
        return 0;
    }

    //Public ID...
    if(ykConfig->pubIdTxt().length() > 0) {
        qDebug() << "Pub id: " << ykConfig->pubIdTxt()
            << "length:" << ykConfig->pubIdTxt().length();

        char pubIdStr[MAX_SIZE];
        YubiKeyUtil::qstrToRaw(pubIdStr, sizeof(pubIdStr),
                ykConfig->pubIdTxt());
        size_t pubIdStrLen = strlen(pubIdStr);

        unsigned char pubId[MAX_SIZE];
        size_t pubIdLen = 0;

        int rc = YubiKeyUtil::hexModhexDecode(pubId, &pubIdLen,
                pubIdStr, pubIdStrLen,
                0, FIXED_SIZE * 2,
                !ykConfig->pubIdInHex());

        if (rc <= 0) {
            qDebug("Invalid public id: %s", pubIdStr);
            return 0;
        }
        ykp_set_fixed(cfg, pubId, pubIdLen);
    }

    //Private ID...
    if(ykConfig->pvtIdTxt().length() > 0) {
        qDebug() << "Pvt id: " << ykConfig->pvtIdTxt()
            << "length:" << ykConfig->pvtIdTxt().length();

        char pvtIdStr[MAX_SIZE];
        YubiKeyUtil::qstrToRaw(pvtIdStr, sizeof(pvtIdStr),
                ykConfig->pvtIdTxt());
        size_t pvtIdStrLen = strlen(pvtIdStr);

        unsigned char pvtId[MAX_SIZE];
        size_t pvtIdLen = 0;

        int rc = YubiKeyUtil::hexModhexDecode(pvtId, &pvtIdLen,
                pvtIdStr, pvtIdStrLen,
                UID_SIZE * 2,
                UID_SIZE * 2,
                false);

        if (rc <= 0) {
            qDebug("Invalid private id: %s", pvtIdStr);
            return 0;
        }
        ykp_set_uid(cfg, pvtId, pvtIdLen);
    }

    //Secret Key...
    if(ykConfig->secretKeyTxt().length() > 0) {
        qDebug() << "Secret key: " << ykConfig->secretKeyTxt()
            << "length:" << ykConfig->secretKeyTxt().length();

        char secretKeyStr[MAX_SIZE];
        YubiKeyUtil::qstrToRaw(secretKeyStr, sizeof(secretKeyStr),
                ykConfig->secretKeyTxt());

        int res = 0;

        if(longSecretKey && strlen(secretKeyStr) == 40) {
            res = ykp_HMAC_key_from_hex(cfg, secretKeyStr);
        } else {
            res = ykp_AES_key_from_hex(cfg, secretKeyStr);
        }

        if (res) {
            qDebug() << "Bad secret key: " << secretKeyStr;
            return 0;
        }
    }


    //Configuration protection...
    //Current Access Code...
    size_t accessCodeLen = 0;

    if(ykConfig->currentAccessCodeTxt().length() > 0) {
        int rc = encodeAccessCode(ykConfig->currentAccessCodeTxt(), accessCode, &accessCodeLen);
        if (rc <= 0) {
            qDebug() << "Invalid current access code: " << ykConfig->currentAccessCodeTxt();
            return 0;
        }
    }

    //New Access Code...
    unsigned char newAccessCode[MAX_SIZE];
    size_t newAccessCodeLen = 0;

    if(ykConfig->newAccessCodeTxt().length() > 0) {
        int rc = encodeAccessCode(ykConfig->newAccessCodeTxt(), newAccessCode, &newAccessCodeLen);
        if (rc <= 0) {
            qDebug() << "Invalid new access code: " << ykConfig->newAccessCodeTxt();
            return 0;
        }
        if(ykConfig->accMode() > 0) {
            int accMode = 0;
            if(ykConfig->accMode() == Acc_None) {
                accMode = YKP_ACCCODE_NONE;
            } else if(ykConfig->accMode() == Acc_Serial) {
                accMode = YKP_ACCCODE_SERIAL;
            } else if(ykConfig->accMode() == Acc_Random) {
                accMode = YKP_ACCCODE_RANDOM;
            }
            ykp_set_acccode_type(cfg, accMode);
        }
    }

    if(accessCodeLen > 0) {
        *useAccessCode = true;
    }

    if(newAccessCodeLen > 0) {
        //Enable/change protection
        ykp_set_access_code(cfg, newAccessCode, newAccessCodeLen);

    } else if(accessCodeLen > 0) {
        //Keep same protection
        ykp_set_access_code(cfg, accessCode, accessCodeLen);
    }

    TKTFLAG(TAB_FIRST,          ykConfig->tabFirst());
    TKTFLAG(APPEND_TAB1,        ykConfig->appendTab1());
    TKTFLAG(APPEND_TAB2,        ykConfig->appendTab2());
    TKTFLAG(APPEND_CR,          ykConfig->appendCr());
    TKTFLAG(APPEND_DELAY1,      ykConfig->appendDelay1());
    TKTFLAG(APPEND_DELAY2,      ykConfig->appendDelay2());
    //TKTFLAG(PROTECT_CFG2,     ykConfig->protectCfg2());

    //CFGFLAG(SEND_REF,         ykConfig->sendRef());
    //CFGFLAG(TICKET_FIRST,     ykConfig->ticketFirst());
    CFGFLAG(PACING_10MS,        ykConfig->pacing10ms());
    CFGFLAG(PACING_20MS,        ykConfig->pacing20ms());
    //CFGFLAG(ALLOW_HIDTRIG,    ykConfig->allowHidtrig());

    //Serial # visibility...
    if(flagSrNoSupport) {
        EXTFLAG(SERIAL_BTN_VISIBLE, ykConfig->serialBtnVisible());
        EXTFLAG(SERIAL_USB_VISIBLE, ykConfig->serialUsbVisible());
        EXTFLAG(SERIAL_API_VISIBLE, ykConfig->serialApiVisible());
    }

    if(flagUpdateSupport) {
        EXTFLAG(ALLOW_UPDATE, ykConfig->allowUpdate());
        // XXX: let update support mean these as well..
        EXTFLAG(DORMANT, ykConfig->dormant());
        EXTFLAG(FAST_TRIG, ykConfig->fastTrig());
        EXTFLAG(USE_NUMERIC_KEYPAD, ykConfig->useNumericKeypad());
    }

    if(flagLedInvSupport) {
        EXTFLAG(LED_INV, ykConfig->ledInvert());
    }
    return 1;
}
Exemplo n.º 3
0
static int _set_oath_id(char *opt, YKP_CONFIG *cfg, struct config_st *ycfg, YK_KEY *yk, YK_STATUS *st) {
	/* For details, see YubiKey Manual 2010-09-16 section 5.3.4 - OATH-HOTP Token Identifier */
	if (!(ycfg->tktFlags & TKTFLAG_OATH_HOTP) == TKTFLAG_OATH_HOTP) {
		fprintf(stderr,
			"Option oath-id= only valid with -ooath-hotp or -ooath-hotp8.\n"
			);
		return 0;
	}
	if (! ykp_set_cfgflag_OATH_FIXED_MODHEX2(cfg, true))
		return 0;
	if (! ykp_set_extflag_SERIAL_API_VISIBLE(cfg, true))
		return 0;

	if (strlen(opt) > 7) {
		if (_set_fixed(opt + 8, cfg) != 1) {
			fprintf(stderr,
				"Invalid OATH token identifier %s supplied with oath-id=.\n", opt + 8
				);
			return 0;
		}
	} else {
		/* No Token Id supplied, try to create one automatically based on
		 * the serial number of the YubiKey.
		 */
		unsigned int serial;
		uint8_t oath_id[12] = {0};
		if (ykds_version_major(st) > 2 ||
		    (ykds_version_major(st) == 2 &&
		     ykds_version_minor(st) >= 2)) {
			if (! yk_get_serial(yk, 0, 0, &serial)) {
				fprintf(stderr,
					"YubiKey refuses reading serial number. "
					"Can't use -ooath-id.\n"
					);
				return 0;
			}
		} else {
			fprintf(stderr,
				"YubiKey %d.%d.%d does not support reading serial number. "
				"Can't use -ooath-id.\n",
				ykds_version_major(st),
				ykds_version_minor(st),
				ykds_version_build(st)
				);
			return 0;
		}

		if (_format_oath_id(oath_id, sizeof(oath_id), YUBICO_OATH_VENDOR_ID_HEX,
				    YUBICO_HOTP_EVENT_TOKEN_TYPE, serial) != 1) {
			fprintf(stderr, "Failed formatting OATH token identifier.\n");
			return 0;
		}

		if (ykp_set_fixed(cfg, oath_id, 6) != 1) {
			fprintf(stderr,
				"Failed setting OATH token identifier.\n"
				);
			return 0;
		}
	}

	return 1;
}