/* * Copyright (c) 2001 Markus Friedl * Copyright (c) 2002 Juha Yrjölä * Copyright (c) 2002 Olaf Kirch * Copyright (c) 2003 Kevin Stefanik * Copyright (c) 2016-2017 Michał Trojnara * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "engine.h" #include #include static int hex_to_bin(ENGINE_CTX *ctx, const char *in, unsigned char *out, size_t *outlen) { size_t left, count = 0; if (in == NULL || *in == '\0') { *outlen = 0; return 1; } left = *outlen; while (*in != '\0') { int byte = 0, nybbles = 2; while (nybbles-- && *in && *in != ':') { char c; byte <<= 4; c = *in++; if ('0' <= c && c <= '9') c -= '0'; else if ('a' <= c && c <= 'f') c = c - 'a' + 10; else if ('A' <= c && c <= 'F') c = c - 'A' + 10; else { ctx_log(ctx, 0, "hex_to_bin(): invalid char '%c' in hex string\n", c); *outlen = 0; return 0; } byte |= c; } if (*in == ':') in++; if (left == 0) { ctx_log(ctx, 0, "hex_to_bin(): hex string too long\n"); *outlen = 0; return 0; } out[count++] = (unsigned char)byte; left--; } *outlen = count; return 1; } /* parse string containing slot and id information */ int parse_slot_id_string(ENGINE_CTX *ctx, const char *slot_id, int *slot, unsigned char *id, size_t *id_len, char **label) { int n, i; /* support for several formats */ #define HEXDIGITS "01234567890ABCDEFabcdef" #define DIGITS "0123456789" /* first: pure hex number (id, slot is undefined) */ if (strspn(slot_id, HEXDIGITS) == strlen(slot_id)) { /* ah, easiest case: only hex. */ if ((strlen(slot_id) + 1) / 2 > *id_len) { ctx_log(ctx, 0, "ID string too long!\n"); return 0; } *slot = -1; return hex_to_bin(ctx, slot_id, id, id_len); } /* second: slot:id. slot is an digital int. */ if (sscanf(slot_id, "%d", &n) == 1) { i = strspn(slot_id, DIGITS); if (slot_id[i] != ':') { ctx_log(ctx, 0, "Could not parse string!\n"); return 0; } i++; if (slot_id[i] == 0) { *slot = n; *id_len = 0; return 1; } if (strspn(slot_id + i, HEXDIGITS) + i != strlen(slot_id)) { ctx_log(ctx, 0, "Could not parse string!\n"); return 0; } /* ah, rest is hex */ if ((strlen(slot_id) - i + 1) / 2 > *id_len) { ctx_log(ctx, 0, "ID string too long!\n"); return 0; } *slot = n; return hex_to_bin(ctx, slot_id + i, id, id_len); } /* third: id_, slot is undefined */ if (strncmp(slot_id, "id_", 3) == 0) { if (strspn(slot_id + 3, HEXDIGITS) + 3 != strlen(slot_id)) { ctx_log(ctx, 0, "Could not parse string!\n"); return 0; } /* ah, rest is hex */ if ((strlen(slot_id) - 3 + 1) / 2 > *id_len) { ctx_log(ctx, 0, "ID string too long!\n"); return 0; } *slot = -1; return hex_to_bin(ctx, slot_id + 3, id, id_len); } /* label_