/* * Given a hex encoded string, decode it into a chunk. * * If this function fails, crash and burn. It is fed static data * so should never ever have a problem. * The caller must free the chunk. */ chunk_t decode_hex_to_chunk(const char *original, const char *string) { /* The decoded buffer can't be bigger than half the encoded string. */ chunk_t chunk = zalloc_chunk((strlen(string)+1)/2, original); chunk.len = 0; const char *pos = string; for (;;) { /* skip leading/trailing space */ while (*pos == ' ') { pos++; } if (*pos == '\0') { break; } /* Expecting <HEX><HEX> */ char buf[3] = { '\0', '\0', '\0' }; if (isxdigit(*pos)) { buf[0] = *pos++; if (isxdigit(*pos)) { buf[1] = *pos++; } } if (buf[1] == '\0') { PASSERT_FAIL("expected hex digit at offset %tu in hex buffer \"%s\" but found \"%.1s\"", pos - string, string, pos); } char *end; chunk.ptr[chunk.len] = strtoul(buf, &end, 16); passert(*end == '\0'); chunk.len++; } return chunk; }
/* * Given an ASCII string, convert it onto a buffer of bytes. If the * buffer is prefixed by 0x assume the contents are hex (with spaces) * and decode it; otherwise it is assumed that the ascii (minus the * NUL) should be copied. */ chunk_t decode_to_chunk(const char *prefix, const char *original) { DBG(DBG_CRYPT, DBG_log("decode_to_chunk: %s: input \"%s\"", prefix, original)); chunk_t chunk; if (startswith(original, "0x")) { chunk = decode_hex_to_chunk(original, original + strlen("0x")); } else { chunk = zalloc_chunk(strlen(original), original); memcpy(chunk.ptr, original, chunk.len); } DBG(DBG_CRYPT, DBG_dump_chunk("decode_to_chunk: output: ", chunk)); return chunk; }
/* * Given a hex encode string, decode it into a chunk. * * If this function fails, crash and burn. Its been fed static data * so should never ever have a problem. */ chunk_t decode_hex_to_chunk(const char *original, const char *string) { /* The decoded buffer can't be bigger than the encoded string. */ chunk_t chunk = zalloc_chunk(strlen(string), original); chunk.len = 0; const char *pos = string; while (*pos != '\0') { /* skip leading/trailing space */ while (*pos == ' ') { pos++; } if (*pos == '\0') { break; } /* Expecting <HEX><HEX>, at least *pos is valid. */ char buf[3]; int i = 0; do { buf[i++] = *pos++; } while (*pos != ' ' && *pos != '\0' && i < 2); buf[i] = '\0'; if (i != 2) { loglog(RC_INTERNALERR, "decode_hex_to_chunk: hex buffer \"%s\" contains unexpected space or NUL at \"%s\"\n", string, pos); exit_pluto(1); } char *end; chunk.ptr[chunk.len] = strtoul(buf, &end, 16); if (end - buf != 2) { loglog(RC_INTERNALERR, "decode_hex_to_chunk: hex buffer \"%s\" invalid hex character at \"%s\"\n", string, pos); exit_pluto(1); } chunk.len++; } return chunk; }