From: Rich Salz Date: Wed, 13 Apr 2016 19:58:28 +0000 (-0400) Subject: Make string_to_hex/hex_to_string public X-Git-Tag: OpenSSL_1_1_0-pre5~3 X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff_plain;h=14f051a0ae3d752c50f419d3583e85fdf4c5bfc9 Make string_to_hex/hex_to_string public Give the API new names, document it. Reviewed-by: Richard Levitte --- diff --git a/apps/apps.c b/apps/apps.c index 7ba12fea5a..6d8c4897d0 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -2340,45 +2340,6 @@ int app_access(const char* name, int flag) #endif } -int app_hex(char c) -{ - switch (c) { - default: - 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; - } -} - /* app_isdir section */ #ifdef _WIN32 int app_isdir(const char *name) diff --git a/apps/apps.h b/apps/apps.h index a310dd2b78..10e1534503 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -624,7 +624,6 @@ void store_setup_crl_download(X509_STORE *st); # define SERIAL_RAND_BITS 64 -int app_hex(char); int app_isdir(const char *); int app_access(const char *, int flag); int raw_read_stdin(void *, int); diff --git a/apps/cms.c b/apps/cms.c index a74ca9d4ca..95f21245eb 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -453,7 +453,7 @@ int cms_main(int argc, char **argv) noout = print = 1; break; case OPT_SECRETKEY: - secret_key = string_to_hex(opt_arg(), <mp); + secret_key = OPENSSL_hexstr2buf(opt_arg(), <mp); if (secret_key == NULL) { BIO_printf(bio_err, "Invalid key %s\n", opt_arg()); goto end; @@ -461,7 +461,7 @@ int cms_main(int argc, char **argv) secret_keylen = (size_t)ltmp; break; case OPT_SECRETKEYID: - secret_keyid = string_to_hex(opt_arg(), <mp); + secret_keyid = OPENSSL_hexstr2buf(opt_arg(), <mp); if (secret_keyid == NULL) { BIO_printf(bio_err, "Invalid id %s\n", opt_arg()); goto opthelp; diff --git a/apps/enc.c b/apps/enc.c index 7f25009ba9..9e7d069264 100644 --- a/apps/enc.c +++ b/apps/enc.c @@ -636,7 +636,7 @@ static int set_hex(char *in, unsigned char *out, int size) BIO_printf(bio_err, "non-hex digit\n"); return (0); } - j = (unsigned char)app_hex(j); + j = (unsigned char)OPENSSL_hexchar2int(j); if (i & 1) out[i / 2] |= j; else diff --git a/apps/ocsp.c b/apps/ocsp.c index 24d88da5c3..ca293a9709 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -1075,7 +1075,9 @@ static int urldecode(char *p) if (*p != '%') *out++ = *p; else if (isxdigit(_UC(p[1])) && isxdigit(_UC(p[2]))) { - *out++ = (app_hex(p[1]) << 4) | app_hex(p[2]); + /* Don't check, can't fail because of ixdigit() call. */ + *out++ = (OPENSSL_hexchar2int(p[1]) << 4) + | OPENSSL_hexchar2int(p[2]); p += 2; } else diff --git a/apps/rehash.c b/apps/rehash.c index 38084a247f..895a222f0c 100644 --- a/apps/rehash.c +++ b/apps/rehash.c @@ -210,7 +210,7 @@ static int handle_symlink(const char *filename, const char *fullpath) if (!isxdigit(ch)) return -1; hash <<= 4; - hash += app_hex(ch); + hash += OPENSSL_hexchar2int(ch); } if (filename[i++] != '.') return -1; diff --git a/apps/ts.c b/apps/ts.c index ec0cfa9d92..70a9013e2b 100644 --- a/apps/ts.c +++ b/apps/ts.c @@ -567,7 +567,7 @@ static int create_digest(BIO *input, char *digest, const EVP_MD *md, EVP_MD_CTX_free(md_ctx); } else { long digest_len; - *md_value = string_to_hex(digest, &digest_len); + *md_value = OPENSSL_hexstr2buf(digest, &digest_len); if (!*md_value || md_value_len != digest_len) { OPENSSL_free(*md_value); *md_value = NULL; @@ -939,7 +939,7 @@ static TS_VERIFY_CTX *create_verify_ctx(char *data, char *digest, goto err; } else if (digest != NULL) { long imprint_len; - unsigned char *hexstr = string_to_hex(digest, &imprint_len); + unsigned char *hexstr = OPENSSL_hexstr2buf(digest, &imprint_len); f |= TS_VFY_IMPRINT; if (TS_VERIFY_CTX_set_imprint(ctx, hexstr, imprint_len) == NULL) { BIO_printf(bio_err, "invalid digest string\n"); diff --git a/crypto/asn1/asn1_gen.c b/crypto/asn1/asn1_gen.c index fc69e31987..59a99edf2f 100644 --- a/crypto/asn1/asn1_gen.c +++ b/crypto/asn1/asn1_gen.c @@ -743,7 +743,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) } if (format == ASN1_GEN_FORMAT_HEX) { - if ((rdata = string_to_hex((char *)str, &rdlen)) == NULL) { + if ((rdata = OPENSSL_hexstr2buf((char *)str, &rdlen)) == NULL) { ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); goto bad_str; } diff --git a/crypto/cpt_err.c b/crypto/cpt_err.c index e9a0a22585..8ad93a9738 100644 --- a/crypto/cpt_err.c +++ b/crypto/cpt_err.c @@ -84,15 +84,17 @@ static ERR_STRING_DATA CRYPTO_str_functs[] = { {ERR_FUNC(CRYPTO_F_INT_DUP_EX_DATA), "INT_DUP_EX_DATA"}, {ERR_FUNC(CRYPTO_F_INT_FREE_EX_DATA), "INT_FREE_EX_DATA"}, {ERR_FUNC(CRYPTO_F_INT_NEW_EX_DATA), "INT_NEW_EX_DATA"}, + {ERR_FUNC(CRYPTO_F_OPENSSL_BUF2HEXSTR), "OPENSSL_buf2hexstr"}, {ERR_FUNC(CRYPTO_F_OPENSSL_INIT_CRYPTO), "OPENSSL_init_crypto"}, {ERR_FUNC(CRYPTO_F_OPENSSL_MEMDUP), "OPENSSL_MEMDUP"}, + {ERR_FUNC(CRYPTO_F_OPENSSL_HEXSTR2BUF), "OPENSSL_hexstr2buf"}, {0, NULL} }; static ERR_STRING_DATA CRYPTO_str_reasons[] = { {ERR_REASON(CRYPTO_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, - {ERR_REASON(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK), - "no dynlock create callback"}, + {ERR_REASON(CRYPTO_R_ILLEGAL_HEX_DIGIT), "illegal hex digit"}, + {ERR_REASON(CRYPTO_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"}, {0, NULL} }; diff --git a/crypto/engine/eng_openssl.c b/crypto/engine/eng_openssl.c index fa26700d1e..0ec51bb7bf 100644 --- a/crypto/engine/eng_openssl.c +++ b/crypto/engine/eng_openssl.c @@ -618,7 +618,7 @@ static int ossl_hmac_ctrl_str(EVP_PKEY_CTX *ctx, unsigned char *key; int r; long keylen; - key = string_to_hex(value, &keylen); + key = OPENSSL_hexstr2buf(value, &keylen); if (!key) return 0; r = ossl_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c index ff5baa7d2c..08466efe9f 100644 --- a/crypto/evp/pmeth_lib.c +++ b/crypto/evp/pmeth_lib.c @@ -402,7 +402,7 @@ int EVP_PKEY_CTX_hex2ctrl(EVP_PKEY_CTX *ctx, int cmd, const char *hex) long binlen; int rv = -1; - bin = string_to_hex(hex, &binlen); + bin = OPENSSL_hexstr2buf(hex, &binlen); if (bin == NULL) return 0; if (binlen <= INT_MAX) 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; +} diff --git a/crypto/rsa/rsa_pmeth.c b/crypto/rsa/rsa_pmeth.c index 22089a3267..b128d736f7 100644 --- a/crypto/rsa/rsa_pmeth.c +++ b/crypto/rsa/rsa_pmeth.c @@ -636,7 +636,7 @@ static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, unsigned char *lab; long lablen; int ret; - lab = string_to_hex(value, &lablen); + lab = OPENSSL_hexstr2buf(value, &lablen); if (!lab) return 0; ret = EVP_PKEY_CTX_set0_rsa_oaep_label(ctx, lab, lablen); diff --git a/crypto/x509v3/v3_akey.c b/crypto/x509v3/v3_akey.c index 4690292cee..edf63961c1 100644 --- a/crypto/x509v3/v3_akey.c +++ b/crypto/x509v3/v3_akey.c @@ -90,14 +90,14 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, { char *tmp; if (akeyid->keyid) { - tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length); + tmp = OPENSSL_buf2hexstr(akeyid->keyid->data, akeyid->keyid->length); X509V3_add_value("keyid", tmp, &extlist); OPENSSL_free(tmp); } if (akeyid->issuer) extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); if (akeyid->serial) { - tmp = hex_to_string(akeyid->serial->data, akeyid->serial->length); + tmp = OPENSSL_buf2hexstr(akeyid->serial->data, akeyid->serial->length); X509V3_add_value("serial", tmp, &extlist); OPENSSL_free(tmp); } diff --git a/crypto/x509v3/v3_conf.c b/crypto/x509v3/v3_conf.c index 01a3aa3da1..c7d268247d 100644 --- a/crypto/x509v3/v3_conf.c +++ b/crypto/x509v3/v3_conf.c @@ -283,7 +283,7 @@ static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, } if (gen_type == 1) - ext_der = string_to_hex(value, &ext_len); + ext_der = OPENSSL_hexstr2buf(value, &ext_len); else if (gen_type == 2) ext_der = generic_asn1(value, ctx, &ext_len); diff --git a/crypto/x509v3/v3_pci.c b/crypto/x509v3/v3_pci.c index 75bed9f4af..cadedef629 100644 --- a/crypto/x509v3/v3_pci.c +++ b/crypto/x509v3/v3_pci.c @@ -119,11 +119,9 @@ static int process_pci_value(CONF_VALUE *val, } if (strncmp(val->value, "hex:", 4) == 0) { unsigned char *tmp_data2 = - string_to_hex(val->value + 4, &val_len); + OPENSSL_hexstr2buf(val->value + 4, &val_len); if (!tmp_data2) { - X509V3err(X509V3_F_PROCESS_PCI_VALUE, - X509V3_R_ILLEGAL_HEX_DIGIT); X509V3_conf_err(val); goto err; } diff --git a/crypto/x509v3/v3_skey.c b/crypto/x509v3/v3_skey.c index 074b7128f4..e633cd8217 100644 --- a/crypto/x509v3/v3_skey.c +++ b/crypto/x509v3/v3_skey.c @@ -75,7 +75,7 @@ const X509V3_EXT_METHOD v3_skey_id = { char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct) { - return hex_to_string(oct->data, oct->length); + return OPENSSL_buf2hexstr(oct->data, oct->length); } ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, @@ -89,7 +89,7 @@ ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, return NULL; } - if ((oct->data = string_to_hex(str, &length)) == NULL) { + if ((oct->data = OPENSSL_hexstr2buf(str, &length)) == NULL) { ASN1_OCTET_STRING_free(oct); return NULL; } diff --git a/crypto/x509v3/v3_utl.c b/crypto/x509v3/v3_utl.c index f791c2f37c..ae9645d687 100644 --- a/crypto/x509v3/v3_utl.c +++ b/crypto/x509v3/v3_utl.c @@ -396,108 +396,6 @@ static char *strip_spaces(char *name) return p; } -/* hex string utilities */ - -/* - * 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 *hex_to_string(const unsigned char *buffer, long len) -{ - char *tmp, *q; - const unsigned char *p; - int i; - const static char hexdig[] = "0123456789ABCDEF"; - if (!buffer || !len) - return NULL; - if ((tmp = OPENSSL_malloc(len * 3 + 1)) == NULL) { - X509V3err(X509V3_F_HEX_TO_STRING, 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; -} - -/* - * Give a string of hex digits convert to a buffer - */ - -unsigned char *string_to_hex(const char *str, long *len) -{ - unsigned char *hexbuf, *q; - unsigned char ch, cl, *p; - if (!str) { - X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_INVALID_NULL_ARGUMENT); - return NULL; - } - if ((hexbuf = OPENSSL_malloc(strlen(str) >> 1)) == NULL) - goto err; - for (p = (unsigned char *)str, q = hexbuf; *p;) { - ch = *p++; -#ifdef CHARSET_EBCDIC - ch = os_toebcdic[ch]; -#endif - if (ch == ':') - continue; - cl = *p++; -#ifdef CHARSET_EBCDIC - cl = os_toebcdic[cl]; -#endif - if (!cl) { - X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ODD_NUMBER_OF_DIGITS); - OPENSSL_free(hexbuf); - return NULL; - } - if (isupper(ch)) - ch = tolower(ch); - if (isupper(cl)) - cl = tolower(cl); - - if ((ch >= '0') && (ch <= '9')) - ch -= '0'; - else if ((ch >= 'a') && (ch <= 'f')) - ch -= 'a' - 10; - else - goto badhex; - - if ((cl >= '0') && (cl <= '9')) - cl -= '0'; - else if ((cl >= 'a') && (cl <= 'f')) - cl -= 'a' - 10; - else - goto badhex; - - *q++ = (ch << 4) | cl; - } - - if (len) - *len = q - hexbuf; - - return hexbuf; - - err: - OPENSSL_free(hexbuf); - X509V3err(X509V3_F_STRING_TO_HEX, ERR_R_MALLOC_FAILURE); - return NULL; - - badhex: - OPENSSL_free(hexbuf); - X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ILLEGAL_HEX_DIGIT); - return NULL; - -} /* * V2I name comparison function: returns zero if 'name' matches cmp or cmp.* diff --git a/crypto/x509v3/v3err.c b/crypto/x509v3/v3err.c index c35a30a5c4..e399b294b8 100644 --- a/crypto/x509v3/v3err.c +++ b/crypto/x509v3/v3err.c @@ -82,7 +82,6 @@ static ERR_STRING_DATA X509V3_str_functs[] = { {ERR_FUNC(X509V3_F_DO_EXT_NCONF), "do_ext_nconf"}, {ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS), "DO_I2V_NAME_CONSTRAINTS"}, {ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME), "gnames_from_sectname"}, - {ERR_FUNC(X509V3_F_HEX_TO_STRING), "hex_to_string"}, {ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED), "i2s_ASN1_ENUMERATED"}, {ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING), "i2s_ASN1_IA5STRING"}, {ERR_FUNC(X509V3_F_I2S_ASN1_INTEGER), "i2s_ASN1_INTEGER"}, @@ -100,7 +99,6 @@ static ERR_STRING_DATA X509V3_str_functs[] = { {ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID), "S2I_ASN1_SKEY_ID"}, {ERR_FUNC(X509V3_F_S2I_SKEY_ID), "s2i_skey_id"}, {ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME), "set_dist_point_name"}, - {ERR_FUNC(X509V3_F_STRING_TO_HEX), "string_to_hex"}, {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC), "SXNET_add_id_asc"}, {ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER), "SXNET_add_id_INTEGER"}, {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG), "SXNET_add_id_ulong"}, @@ -124,8 +122,8 @@ static ERR_STRING_DATA X509V3_str_functs[] = { {ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS), "v2i_POLICY_MAPPINGS"}, {ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT), "v2i_subject_alt"}, {ERR_FUNC(X509V3_F_V2I_TLS_FEATURE), "v2i_TLS_FEATURE"}, - {ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL), - "v3_addr_validate_path_internal"}, + {ERR_FUNC(X509V3_F_ADDR_VALIDATE_PATH_INTERNAL), + "addr_validate_path_internal"}, {ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION), "v3_generic_extension"}, {ERR_FUNC(X509V3_F_X509V3_ADD1_I2D), "X509V3_add1_i2d"}, {ERR_FUNC(X509V3_F_X509V3_ADD_VALUE), "X509V3_add_value"}, @@ -164,7 +162,6 @@ static ERR_STRING_DATA X509V3_str_reasons[] = { "extension setting not supported"}, {ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR), "extension value error"}, {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION), "illegal empty extension"}, - {ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT), "illegal hex digit"}, {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG), "incorrect policy syntax tag"}, {ERR_REASON(X509V3_R_INVALID_ASNUMBER), "invalid asnumber"}, diff --git a/doc/crypto/OPENSSL_malloc.pod b/doc/crypto/OPENSSL_malloc.pod index e0271ca977..7ce00b28a8 100644 --- a/doc/crypto/OPENSSL_malloc.pod +++ b/doc/crypto/OPENSSL_malloc.pod @@ -8,6 +8,7 @@ OPENSSL_clear_realloc, OPENSSL_clear_free, OPENSSL_cleanse CRYPTO_malloc, CRYPTO_zalloc, CRYPTO_realloc, CRYPTO_free, OPENSSL_strdup, OPENSSL_strndup, OPENSSL_memdup, OPENSSL_strlcpy, OPENSSL_strlcat, +OPENSSL_hexstr2buf, OPENSSL_buf2hexstr, OPENSSL_hexchar2int, CRYPTO_clear_realloc, CRYPTO_clear_free, CRYPTO_get_mem_functions, CRYPTO_set_mem_functions, CRYPTO_set_mem_debug, CRYPTO_mem_ctrl, @@ -31,6 +32,10 @@ CRYPTO_mem_leaks, CRYPTO_mem_leaks_fp - Memory allocation functions void OPENSSL_clear_free(void *str, size_t num) void OPENSSL_cleanse(void *ptr, size_t len); + unsigned char *OPENSSL_hexstr2buf(const char *str, long *len); + char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len); + int OPENSSL_hexchar2int(unsigned char c); + void *CRYPTO_malloc(size_t num, const char *file, int line) void *CRYPTO_zalloc(size_t num, const char *file, int line) void *CRYPTO_realloc(void *p, size_t num, const char *file, int line) @@ -103,6 +108,20 @@ OPENSSL_strlcpy(), OPENSSL_strlcat() and OPENSSL_strnlen() are equivalents of the common C library functions and are provided for portability. +OPENSSL_hexstr2buf() parses B as a hex string and returns a +pointer to the parsed value. The memory is allocated by calling +OPENSSL_malloc() and should be released by calling OPENSSL_free(). +If B is not NULL, it is filled in with the output length. +Colons between two-character hex "bytes" are ignored. +An odd number of hex digits is an error. + +OPENSSL_buf2hexstr() takes the specified buffer and length, and returns +a hex string for value, or NULL on error. +B cannot be NULL; if B is NULL an empty string is returned. + +OPENSSL_hexchar2int() converts a character to the hexadecimal equivalent, +or returns -1 on error. + If no allocations have been done, it is possible to "swap out" the default implementations for OPENSSL_malloc(), OPENSSL_realloc and OPENSSL_free() and replace them with alternate versions (hooks). @@ -155,6 +174,7 @@ OPENSSL_malloc(), OPENSSL_zalloc(), OPENSSL_realloc(), OPENSSL_clear_realloc(), CRYPTO_malloc(), CRYPTO_zalloc(), CRYPTO_realloc(), CRYPTO_clear_realloc(), +OPENSSL_buf2hexstr(), OPENSSL_hexstr2buf(), OPENSSL_strdup(), and OPENSSL_strndup() return a pointer to allocated memory or NULL on error. diff --git a/include/openssl/crypto.h b/include/openssl/crypto.h index 32b88439f2..968b1b3928 100644 --- a/include/openssl/crypto.h +++ b/include/openssl/crypto.h @@ -255,6 +255,9 @@ int CRYPTO_mem_ctrl(int mode); size_t OPENSSL_strlcpy(char *dst, const char *src, size_t siz); size_t OPENSSL_strlcat(char *dst, const char *src, size_t siz); size_t OPENSSL_strnlen(const char *str, size_t maxlen); +char *OPENSSL_buf2hexstr(const unsigned char *buffer, long len); +unsigned char *OPENSSL_hexstr2buf(const char *str, long *len); +int OPENSSL_hexchar2int(unsigned char c); # define OPENSSL_MALLOC_MAX_NELEMS(type) (((1U<<(sizeof(int)*8-1))-1)/sizeof(type)) @@ -510,12 +513,15 @@ void ERR_load_CRYPTO_strings(void); # define CRYPTO_F_INT_DUP_EX_DATA 106 # define CRYPTO_F_INT_FREE_EX_DATA 107 # define CRYPTO_F_INT_NEW_EX_DATA 108 +# define CRYPTO_F_OPENSSL_BUF2HEXSTR 117 # define CRYPTO_F_OPENSSL_INIT_CRYPTO 116 # define CRYPTO_F_OPENSSL_MEMDUP 114 +# define CRYPTO_F_OPENSSL_HEXSTR2BUF 118 /* Reason codes. */ # define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 -# define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100 +# define CRYPTO_R_ILLEGAL_HEX_DIGIT 102 +# define CRYPTO_R_ODD_NUMBER_OF_DIGITS 103 #ifdef __cplusplus } diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h index d05e43028d..c44ebf5ab4 100644 --- a/include/openssl/x509v3.h +++ b/include/openssl/x509v3.h @@ -679,8 +679,11 @@ X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, int crit, unsigned long flags); -char *hex_to_string(const unsigned char *buffer, long len); -unsigned char *string_to_hex(const char *str, long *len); +#if OPENSSL_API_COMPAT < 0x00101000L +/* The new declarations are in crypto.h, but the old ones were here. */ +# define hex_to_string OPENSSL_buf2hexstr +# define string_to_hex OPENSSL_hexstr2buf +#endif void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, int ml); @@ -930,7 +933,6 @@ void ERR_load_X509V3_strings(void); # define X509V3_F_DO_EXT_NCONF 151 # define X509V3_F_DO_I2V_NAME_CONSTRAINTS 148 # define X509V3_F_GNAMES_FROM_SECTNAME 156 -# define X509V3_F_HEX_TO_STRING 111 # define X509V3_F_I2S_ASN1_ENUMERATED 121 # define X509V3_F_I2S_ASN1_IA5STRING 149 # define X509V3_F_I2S_ASN1_INTEGER 120 @@ -947,7 +949,6 @@ void ERR_load_X509V3_strings(void); # define X509V3_F_S2I_ASN1_SKEY_ID 114 # define X509V3_F_S2I_SKEY_ID 115 # define X509V3_F_SET_DIST_POINT_NAME 158 -# define X509V3_F_STRING_TO_HEX 113 # define X509V3_F_SXNET_ADD_ID_ASC 125 # define X509V3_F_SXNET_ADD_ID_INTEGER 126 # define X509V3_F_SXNET_ADD_ID_ULONG 127 @@ -970,7 +971,6 @@ void ERR_load_X509V3_strings(void); # define X509V3_F_V2I_POLICY_MAPPINGS 145 # define X509V3_F_V2I_SUBJECT_ALT 154 # define X509V3_F_V2I_TLS_FEATURE 165 -# define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL 160 # define X509V3_F_V3_GENERIC_EXTENSION 116 # define X509V3_F_X509V3_ADD1_I2D 140 # define X509V3_F_X509V3_ADD_VALUE 105 @@ -1004,7 +1004,6 @@ void ERR_load_X509V3_strings(void); # define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 # define X509V3_R_EXTENSION_VALUE_ERROR 116 # define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 -# define X509V3_R_ILLEGAL_HEX_DIGIT 113 # define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 # define X509V3_R_INVALID_ASNUMBER 162 # define X509V3_R_INVALID_ASRANGE 163 diff --git a/test/evp_test.c b/test/evp_test.c index 2e3987cfe0..56c821bd9e 100644 --- a/test/evp_test.c +++ b/test/evp_test.c @@ -199,7 +199,7 @@ static int test_bin(const char *value, unsigned char **buf, size_t *buflen) return 1; } - *buf = string_to_hex(value, &len); + *buf = OPENSSL_hexstr2buf(value, &len); if (!*buf) { fprintf(stderr, "Value=%s\n", value); ERR_print_errors_fp(stderr); diff --git a/util/libcrypto.num b/util/libcrypto.num index 1a98180c44..533935801e 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -1084,7 +1084,7 @@ X509_STORE_CTX_set_error 1052 1_1_0 EXIST::FUNCTION: EC_KEY_METHOD_set_keygen 1053 1_1_0 EXIST::FUNCTION:EC CRYPTO_free 1054 1_1_0 EXIST::FUNCTION: BN_GF2m_mod_exp 1055 1_1_0 EXIST::FUNCTION:EC2M -hex_to_string 1056 1_1_0 EXIST::FUNCTION: +OPENSSL_buf2hexstr 1056 1_1_0 EXIST::FUNCTION: DES_encrypt2 1057 1_1_0 EXIST::FUNCTION:DES DH_up_ref 1058 1_1_0 EXIST::FUNCTION:DH RC2_ofb64_encrypt 1059 1_1_0 EXIST::FUNCTION:RC2 @@ -1869,7 +1869,7 @@ X509_EXTENSION_get_data 1815 1_1_0 EXIST::FUNCTION: RC5_32_encrypt 1816 1_1_0 EXIST::FUNCTION:RC5 DIST_POINT_set_dpname 1817 1_1_0 EXIST::FUNCTION: BIO_sock_info 1818 1_1_0 EXIST::FUNCTION: -string_to_hex 1819 1_1_0 EXIST::FUNCTION: +OPENSSL_hexstr2buf 1819 1_1_0 EXIST::FUNCTION: EVP_add_cipher 1820 1_1_0 EXIST::FUNCTION: X509V3_EXT_add_list 1821 1_1_0 EXIST::FUNCTION: CMS_compress 1822 1_1_0 EXIST::FUNCTION:CMS @@ -4206,3 +4206,4 @@ X509_STORE_CTX_get_verify_cb 4080 1_1_0 EXIST::FUNCTION: X509_STORE_CTX_get_cert 4081 1_1_0 NOEXIST::FUNCTION: X509_STORE_CTX_set0_verified_chain 4082 1_1_0 EXIST::FUNCTION: X509_STORE_CTX_set0_untrusted 4083 1_1_0 EXIST::FUNCTION: +OPENSSL_hexchar2int 4084 1_1_0 EXIST::FUNCTION: