diff options
author | Rich Salz <rsalz@openssl.org> | 2016-04-13 15:58:28 -0400 |
---|---|---|
committer | Rich Salz <rsalz@openssl.org> | 2016-04-18 09:02:11 -0400 |
commit | 14f051a0ae3d752c50f419d3583e85fdf4c5bfc9 (patch) | |
tree | 16bb50151db9c67cd1dec3b1d25cc537fd10f874 /crypto/o_str.c | |
parent | 9021a5dfb37fd3a6f7726f07ef0f27dcb71048e2 (diff) | |
download | openssl-14f051a0ae3d752c50f419d3583e85fdf4c5bfc9.tar.gz |
Make string_to_hex/hex_to_string public
Give the API new names, document it.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Diffstat (limited to 'crypto/o_str.c')
-rw-r--r-- | crypto/o_str.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/crypto/o_str.c b/crypto/o_str.c index 84005e66b5..9811e2df2b 100644 --- a/crypto/o_str.c +++ b/crypto/o_str.c @@ -192,3 +192,117 @@ size_t OPENSSL_strlcat(char *dst, const char *src, size_t size) l++; return l + OPENSSL_strlcpy(dst, src, size); } + +int OPENSSL_hexchar2int(unsigned char c) +{ +#ifdef CHARSET_EBCDIC + c = os_toebcdic[c]; +#endif + + switch (c) { + case '0': + return 0; + case '1': + return 1; + case '2': + return 2; + case '3': + return 3; + case '4': + return 4; + case '5': + return 5; + case '6': + return 6; + case '7': + return 7; + case '8': + return 8; + case '9': + return 9; + case 'a': case 'A': + return 0x0A; + case 'b': case 'B': + return 0x0B; + case 'c': case 'C': + return 0x0C; + case 'd': case 'D': + return 0x0D; + case 'e': case 'E': + return 0x0E; + case 'f': case 'F': + return 0x0F; + } + return -1; +} + +/* + * Give a string of hex digits convert to a buffer + */ +unsigned char *OPENSSL_hexstr2buf(const char *str, long *len) +{ + unsigned char *hexbuf, *q; + unsigned char ch, cl; + const unsigned char *p; + size_t s; + + s = strlen(str); + if ((hexbuf = OPENSSL_malloc(s >> 1)) == NULL) { + CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (p = (const unsigned char *)str, q = hexbuf; *p; ) { + ch = *p++; + if (ch == ':') + continue; + cl = *p++; + if (!cl) { + CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, + CRYPTO_R_ODD_NUMBER_OF_DIGITS); + OPENSSL_free(hexbuf); + return NULL; + } + cl = OPENSSL_hexchar2int(cl); + ch = OPENSSL_hexchar2int(ch); + if (cl < 0 || ch < 0) { + OPENSSL_free(hexbuf); + CRYPTOerr(CRYPTO_F_OPENSSL_HEXSTR2BUF, CRYPTO_R_ILLEGAL_HEX_DIGIT); + return NULL; + } + *q++ = (ch << 4) | cl; + } + + if (len) + *len = q - hexbuf; + return hexbuf; +} + +/* + * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its + * hex representation @@@ (Contents of buffer are always kept in ASCII, also + * on EBCDIC machines) + */ +char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len) +{ + const static char hexdig[] = "0123456789ABCDEF"; + char *tmp, *q; + const unsigned char *p; + int i; + + if ((tmp = OPENSSL_malloc(len * 3 + 1)) == NULL) { + CRYPTOerr(CRYPTO_F_OPENSSL_BUF2HEXSTR, ERR_R_MALLOC_FAILURE); + return NULL; + } + q = tmp; + for (i = 0, p = buffer; i < len; i++, p++) { + *q++ = hexdig[(*p >> 4) & 0xf]; + *q++ = hexdig[*p & 0xf]; + *q++ = ':'; + } + q[-1] = 0; +#ifdef CHARSET_EBCDIC + ebcdic2ascii(tmp, tmp, q - tmp - 1); +#endif + + return tmp; +} |