aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/o_str.c
diff options
context:
space:
mode:
authorRich Salz <rsalz@openssl.org>2016-04-13 15:58:28 -0400
committerRich Salz <rsalz@openssl.org>2016-04-18 09:02:11 -0400
commit14f051a0ae3d752c50f419d3583e85fdf4c5bfc9 (patch)
tree16bb50151db9c67cd1dec3b1d25cc537fd10f874 /crypto/o_str.c
parent9021a5dfb37fd3a6f7726f07ef0f27dcb71048e2 (diff)
downloadopenssl-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.c114
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;
+}