int load_chalresp_state(FILE *f, CR_STATE *state, bool verbose) { /* * Load the current challenge and expected response information from a file handle. * * Format is hex(challenge):hex(response):slot num */ char challenge_hex[CR_CHALLENGE_SIZE * 2 + 1], response_hex[CR_RESPONSE_SIZE * 2 + 1]; int slot; int r; if (! f) goto out; /* XXX not ideal with hard coded lengths in this scan string. * 126 corresponds to twice the size of CR_CHALLENGE_SIZE, * 40 is twice the size of CR_RESPONSE_SIZE * (twice because we hex encode the challenge and response) */ r = fscanf(f, "v1:%126[0-9a-z]:%40[0-9a-z]:%d", &challenge_hex[0], &response_hex[0], &slot); if (r != 3) { D(("Could not parse contents of chalresp_state file (%i)", r)); goto out; } if (verbose) D(("Challenge: %s, expected response: %s, slot: %d", challenge_hex, response_hex, slot)); if (! yubikey_hex_p(challenge_hex)) { D(("Invalid challenge hex input : %s", challenge_hex)); goto out; } if (! yubikey_hex_p(response_hex)) { D(("Invalid expected response hex input : %s", response_hex)); goto out; } if (slot != 1 && slot != 2) { D(("Invalid slot input : %i", slot)); goto out; } yubikey_hex_decode(state->challenge, challenge_hex, sizeof(state->challenge)); state->challenge_len = strlen(challenge_hex) / 2; yubikey_hex_decode(state->response, response_hex, sizeof(state->response)); state->response_len = strlen(response_hex) / 2; state->slot = slot; return 1; out: return 0; }
static void hex_test1 (void) { char buf[1024]; int rc; strcpy (buf, "0123Xabc"); rc = yubikey_hex_p (buf); printf ("hex-p(\"%s\") = %d\n", buf, rc); assert (rc == 0); printf ("Hex-1 success\n"); }
static void hex_test3 (void) { char buf[1024]; int rc; strcpy (buf, "0123456789abcdef"); rc = yubikey_hex_p (buf); printf ("hex-p(\"%s\") = %d\n", buf, rc); assert (rc == 1); printf ("Hex-3 success\n"); }
/* Decode 128 bit AES key into cfg->ykcore_config.key */ int ykp_AES_key_from_hex(YKP_CONFIG *cfg, const char *hexkey) { char aesbin[256]; /* Make sure that the hexkey is exactly 32 characters */ if (strlen(hexkey) != 32) { return 1; /* Bad AES key */ } /* Make sure that the hexkey is made up of only [0-9a-f] */ if (! yubikey_hex_p(hexkey)) return 1; yubikey_hex_decode(aesbin, hexkey, sizeof(aesbin)); memcpy(cfg->ykcore_config.key, aesbin, sizeof(cfg->ykcore_config.key)); return 0; }
/* Decode 160 bits HMAC key, used with OATH and HMAC challenge-response. * * The first 128 bits of the HMAC go key into cfg->ykcore_config.key, * and 32 bits into the first four bytes of cfg->ykcore_config.uid. */ int ykp_HMAC_key_from_hex(YKP_CONFIG *cfg, const char *hexkey) { char aesbin[256]; int i; /* Make sure that the hexkey is exactly 40 characters */ if (strlen(hexkey) != 40) { return 1; /* Bad HMAC key */ } /* Make sure that the hexkey is made up of only [0-9a-f] */ if (! yubikey_hex_p(hexkey)) return 1; yubikey_hex_decode(aesbin, hexkey, sizeof(aesbin)); i = sizeof(cfg->ykcore_config.key); memcpy(cfg->ykcore_config.key, aesbin, i); memcpy(cfg->ykcore_config.uid, aesbin + i, 20 - i); return 0; }
static int hex_modhex_decode(unsigned char *result, size_t *resultlen, const char *str, size_t strl, size_t minsize, size_t maxsize, bool primarily_modhex) { if (strl >= 2) { if (strncmp(str, "m:", 2) == 0 || strncmp(str, "M:", 2) == 0) { str += 2; strl -= 2; primarily_modhex = true; } else if (strncmp(str, "h:", 2) == 0 || strncmp(str, "H:", 2) == 0) { str += 2; strl -= 2; primarily_modhex = false; } } if ((strl % 2 != 0) || (strl < minsize) || (strl > maxsize)) { return -1; } *resultlen = strl / 2; if (primarily_modhex) { if (yubikey_modhex_p(str)) { yubikey_modhex_decode((char *)result, str, strl); return 1; } } else { if (yubikey_hex_p(str)) { yubikey_hex_decode((char *)result, str, strl); return 1; } } return 0; }
int YubiKeyUtil::hexModhexDecode(unsigned char *result, size_t *resultLen, const char *str, size_t strLen, size_t minSize, size_t maxSize, bool modhex) { if ((strLen % 2 != 0) || (strLen < minSize) || (strLen > maxSize)) { return -1; } *resultLen = strLen / 2; if (modhex) { if (yubikey_modhex_p(str)) { yubikey_modhex_decode((char *)result, str, strLen); return 1; } } else { if (yubikey_hex_p(str)) { yubikey_hex_decode((char *)result, str, strLen); return 1; } } return 0; }
int load_chalresp_state(FILE *f, CR_STATE *state, bool verbose) { /* * Load the current challenge and expected response information from a file handle. * * Format is hex(challenge):hex(response):slot num */ char challenge_hex[CR_CHALLENGE_SIZE * 2 + 1], response_hex[CR_RESPONSE_SIZE * 2 + 1]; char salt_hex[CR_SALT_SIZE * 2 + 1]; unsigned int iterations; int slot; int r; if (! f) goto out; /* XXX not ideal with hard coded lengths in this scan string. * 126 corresponds to twice the size of CR_CHALLENGE_SIZE, * 40 is twice the size of CR_RESPONSE_SIZE * (twice because we hex encode the challenge and response) */ r = fscanf(f, "v2:%126[0-9a-z]:%40[0-9a-z]:%64[0-9a-z]:%d:%d", challenge_hex, response_hex, salt_hex, &iterations, &slot); if(r == 5) { if (! yubikey_hex_p(salt_hex)) { D(("Invalid salt hex input : %s", salt_hex)); goto out; } if(verbose) { D(("Challenge: %s, hashed response: %s, salt: %s, iterations: %d, slot: %d", challenge_hex, response_hex, salt_hex, iterations, slot)); } yubikey_hex_decode(state->salt, salt_hex, sizeof(state->salt)); state->salt_len = strlen(salt_hex) / 2; } else { rewind(f); r = fscanf(f, "v1:%126[0-9a-z]:%40[0-9a-z]:%d", challenge_hex, response_hex, &slot); if (r != 3) { D(("Could not parse contents of chalresp_state file (%i)", r)); goto out; } if (verbose) { D(("Challenge: %s, expected response: %s, slot: %d", challenge_hex, response_hex, slot)); } iterations = CR_DEFAULT_ITERATIONS; } state->iterations = iterations; if (! yubikey_hex_p(challenge_hex)) { D(("Invalid challenge hex input : %s", challenge_hex)); goto out; } if (! yubikey_hex_p(response_hex)) { D(("Invalid expected response hex input : %s", response_hex)); goto out; } if (slot != 1 && slot != 2) { D(("Invalid slot input : %i", slot)); goto out; } yubikey_hex_decode(state->challenge, challenge_hex, sizeof(state->challenge)); state->challenge_len = strlen(challenge_hex) / 2; yubikey_hex_decode(state->response, response_hex, sizeof(state->response)); state->response_len = strlen(response_hex) / 2; state->slot = slot; return 1; out: return 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; }