Make string_to_hex/hex_to_string public

Give the API new names, document it.

Reviewed-by: Richard Levitte <levitte@openssl.org>
diff --git a/crypto/o_str.c b/crypto/o_str.c
index 84005e6..9811e2d 100644
--- a/crypto/o_str.c
+++ b/crypto/o_str.c
@@ -192,3 +192,117 @@
         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;
+}