diff options
author | Viktor Dukhovni <openssl-users@dukhovni.org> | 2025-01-20 07:25:03 +0100 |
---|---|---|
committer | Viktor Dukhovni <openssl-users@dukhovni.org> | 2025-01-21 10:09:57 +0100 |
commit | c374f7954905643607a78a90bf09005f302637b6 (patch) | |
tree | 25567e41426a06bc12c0de0df41615dcfd3256c7 | |
parent | Check return of OSSL_PROVIDER_do_all to avoid coverity noise (diff) | |
download | openssl-c374f7954905643607a78a90bf09005f302637b6.tar.xz openssl-c374f7954905643607a78a90bf09005f302637b6.zip |
Move some encode helpers to crypt/encode_decode/
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26487)
-rw-r--r-- | crypto/encode_decode/encoder_lib.c | 181 | ||||
-rw-r--r-- | include/internal/encoder.h | 27 | ||||
-rw-r--r-- | providers/implementations/encode_decode/encode_key2text.c | 254 |
3 files changed, 245 insertions, 217 deletions
diff --git a/crypto/encode_decode/encoder_lib.c b/crypto/encode_decode/encoder_lib.c index d1e3aca7a2..1e524276dd 100644 --- a/crypto/encode_decode/encoder_lib.c +++ b/crypto/encode_decode/encoder_lib.c @@ -7,6 +7,8 @@ * https://www.openssl.org/source/license.html */ +#include <ctype.h> + #include <openssl/core_names.h> #include <openssl/bio.h> #include <openssl/encoder.h> @@ -14,10 +16,31 @@ #include <openssl/params.h> #include <openssl/provider.h> #include <openssl/trace.h> +#include <crypto/bn.h> #include "internal/bio.h" +#include "internal/ffc.h" #include "internal/provider.h" +#include "internal/encoder.h" #include "encoder_local.h" +/* Number of octets per line */ +#define LABELED_BUF_PRINT_WIDTH 15 + +# ifdef SIXTY_FOUR_BIT_LONG +# define BN_FMTu "%lu" +# define BN_FMTx "%lx" +# endif + +# ifdef SIXTY_FOUR_BIT +# define BN_FMTu "%llu" +# define BN_FMTx "%llx" +# endif + +# ifdef THIRTY_TWO_BIT +# define BN_FMTu "%u" +# define BN_FMTx "%x" +# endif + struct encoder_process_data_st { OSSL_ENCODER_CTX *ctx; @@ -675,3 +698,161 @@ static int encoder_process(struct encoder_process_data_st *data) data->ctx->cleanup(data->ctx->construct_data); return ok; } + +int ossl_bio_print_labeled_bignum(BIO *out, const char *label, const BIGNUM *bn) +{ + int ret = 0, use_sep = 0; + char *hex_str = NULL, *p; + const char spaces[] = " "; + const char *post_label_spc = " "; + + const char *neg = ""; + int bytes; + + if (bn == NULL) + return 0; + if (label == NULL) { + label = ""; + post_label_spc = ""; + } + + if (BN_is_zero(bn)) + return BIO_printf(out, "%s%s0\n", label, post_label_spc); + + if (BN_num_bytes(bn) <= BN_BYTES) { + BN_ULONG *words = bn_get_words(bn); + + if (BN_is_negative(bn)) + neg = "-"; + + return BIO_printf(out, "%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n", + label, post_label_spc, neg, words[0], neg, words[0]); + } + + hex_str = BN_bn2hex(bn); + if (hex_str == NULL) + return 0; + + p = hex_str; + if (*p == '-') { + ++p; + neg = " (Negative)"; + } + if (BIO_printf(out, "%s%s\n", label, neg) <= 0) + goto err; + + /* Keep track of how many bytes we have printed out so far */ + bytes = 0; + + if (BIO_printf(out, "%s", spaces) <= 0) + goto err; + + /* Add a leading 00 if the top bit is set */ + if (*p >= '8') { + if (BIO_printf(out, "%02x", 0) <= 0) + goto err; + ++bytes; + use_sep = 1; + } + while (*p != '\0') { + /* Do a newline after every 15 hex bytes + add the space indent */ + if ((bytes % 15) == 0 && bytes > 0) { + if (BIO_printf(out, ":\n%s", spaces) <= 0) + goto err; + use_sep = 0; /* The first byte on the next line doesn't have a : */ + } + if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "", + tolower((unsigned char)p[0]), + tolower((unsigned char)p[1])) <= 0) + goto err; + ++bytes; + p += 2; + use_sep = 1; + } + if (BIO_printf(out, "\n") <= 0) + goto err; + ret = 1; +err: + OPENSSL_free(hex_str); + return ret; +} + +int ossl_bio_print_labeled_buf(BIO *out, const char *label, + const unsigned char *buf, size_t buflen) +{ + size_t i; + + if (BIO_printf(out, "%s\n", label) <= 0) + return 0; + + for (i = 0; i < buflen; i++) { + if ((i % LABELED_BUF_PRINT_WIDTH) == 0) { + if (i > 0 && BIO_printf(out, "\n") <= 0) + return 0; + if (BIO_printf(out, " ") <= 0) + return 0; + } + + if (BIO_printf(out, "%02x%s", buf[i], + (i == buflen - 1) ? "" : ":") <= 0) + return 0; + } + if (BIO_printf(out, "\n") <= 0) + return 0; + + return 1; +} + +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) +int ossl_bio_print_ffc_params(BIO *out, const FFC_PARAMS *ffc) +{ + if (ffc->nid != NID_undef) { +#ifndef OPENSSL_NO_DH + const DH_NAMED_GROUP *group = ossl_ffc_uid_to_dh_named_group(ffc->nid); + const char *name = ossl_ffc_named_group_get_name(group); + + if (name == NULL) + goto err; + if (BIO_printf(out, "GROUP: %s\n", name) <= 0) + goto err; + return 1; +#else + /* How could this be? We should not have a nid in a no-dh build. */ + goto err; +#endif + } + + if (!ossl_bio_print_labeled_bignum(out, "P: ", ffc->p)) + goto err; + if (ffc->q != NULL) { + if (!ossl_bio_print_labeled_bignum(out, "Q: ", ffc->q)) + goto err; + } + if (!ossl_bio_print_labeled_bignum(out, "G: ", ffc->g)) + goto err; + if (ffc->j != NULL) { + if (!ossl_bio_print_labeled_bignum(out, "J: ", ffc->j)) + goto err; + } + if (ffc->seed != NULL) { + if (!ossl_bio_print_labeled_buf(out, "SEED:", ffc->seed, ffc->seedlen)) + goto err; + } + if (ffc->gindex != -1) { + if (BIO_printf(out, "gindex: %d\n", ffc->gindex) <= 0) + goto err; + } + if (ffc->pcounter != -1) { + if (BIO_printf(out, "pcounter: %d\n", ffc->pcounter) <= 0) + goto err; + } + if (ffc->h != 0) { + if (BIO_printf(out, "h: %d\n", ffc->h) <= 0) + goto err; + } + return 1; +err: + return 0; +} + +#endif diff --git a/include/internal/encoder.h b/include/internal/encoder.h new file mode 100644 index 0000000000..d7ad2097f4 --- /dev/null +++ b/include/internal/encoder.h @@ -0,0 +1,27 @@ +/* + * Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#ifndef OSSL_INTERNAL_ENCODER_H +# define OSSL_INTERNAL_ENCODER_H +# pragma once + +# include <openssl/bio.h> +# include <openssl/buffer.h> +# include <openssl/types.h> +# include "internal/ffc.h" + +int ossl_bio_print_labeled_bignum(BIO *out, const char *label, + const BIGNUM *bn); +int ossl_bio_print_labeled_buf(BIO *out, const char *label, + const unsigned char *buf, size_t buflen); +# if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) +int ossl_bio_print_ffc_params(BIO *out, const FFC_PARAMS *ffc); +# endif + +#endif diff --git a/providers/implementations/encode_decode/encode_key2text.c b/providers/implementations/encode_decode/encode_key2text.c index 7a47c61ee8..ebad2e1876 100644 --- a/providers/implementations/encode_decode/encode_key2text.c +++ b/providers/implementations/encode_decode/encode_key2text.c @@ -12,8 +12,6 @@ */ #include "internal/deprecated.h" -#include <ctype.h> - #include <openssl/core.h> #include <openssl/core_dispatch.h> #include <openssl/core_names.h> @@ -21,8 +19,6 @@ #include <openssl/err.h> #include <openssl/safestack.h> #include <openssl/proverr.h> -#include "internal/ffc.h" -#include "crypto/bn.h" /* bn_get_words() */ #include "crypto/dh.h" /* ossl_dh_get0_params() */ #include "crypto/dsa.h" /* ossl_dsa_get0_params() */ #include "crypto/ec.h" /* ossl_ec_key_get_libctx */ @@ -30,187 +26,11 @@ #include "crypto/rsa.h" /* RSA_PSS_PARAMS_30, etc... */ #include "prov/bio.h" #include "prov/implementations.h" +#include "internal/encoder.h" #include "endecoder_local.h" DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) -# ifdef SIXTY_FOUR_BIT_LONG -# define BN_FMTu "%lu" -# define BN_FMTx "%lx" -# endif - -# ifdef SIXTY_FOUR_BIT -# define BN_FMTu "%llu" -# define BN_FMTx "%llx" -# endif - -# ifdef THIRTY_TWO_BIT -# define BN_FMTu "%u" -# define BN_FMTx "%x" -# endif - -static int print_labeled_bignum(BIO *out, const char *label, const BIGNUM *bn) -{ - int ret = 0, use_sep = 0; - char *hex_str = NULL, *p; - const char spaces[] = " "; - const char *post_label_spc = " "; - - const char *neg = ""; - int bytes; - - if (bn == NULL) - return 0; - if (label == NULL) { - label = ""; - post_label_spc = ""; - } - - if (BN_is_zero(bn)) - return BIO_printf(out, "%s%s0\n", label, post_label_spc); - - if (BN_num_bytes(bn) <= BN_BYTES) { - BN_ULONG *words = bn_get_words(bn); - - if (BN_is_negative(bn)) - neg = "-"; - - return BIO_printf(out, "%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n", - label, post_label_spc, neg, words[0], neg, words[0]); - } - - hex_str = BN_bn2hex(bn); - if (hex_str == NULL) - return 0; - - p = hex_str; - if (*p == '-') { - ++p; - neg = " (Negative)"; - } - if (BIO_printf(out, "%s%s\n", label, neg) <= 0) - goto err; - - /* Keep track of how many bytes we have printed out so far */ - bytes = 0; - - if (BIO_printf(out, "%s", spaces) <= 0) - goto err; - - /* Add a leading 00 if the top bit is set */ - if (*p >= '8') { - if (BIO_printf(out, "%02x", 0) <= 0) - goto err; - ++bytes; - use_sep = 1; - } - while (*p != '\0') { - /* Do a newline after every 15 hex bytes + add the space indent */ - if ((bytes % 15) == 0 && bytes > 0) { - if (BIO_printf(out, ":\n%s", spaces) <= 0) - goto err; - use_sep = 0; /* The first byte on the next line doesn't have a : */ - } - if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "", - tolower((unsigned char)p[0]), - tolower((unsigned char)p[1])) <= 0) - goto err; - ++bytes; - p += 2; - use_sep = 1; - } - if (BIO_printf(out, "\n") <= 0) - goto err; - ret = 1; -err: - OPENSSL_free(hex_str); - return ret; -} - -/* Number of octets per line */ -#define LABELED_BUF_PRINT_WIDTH 15 - -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) -static int print_labeled_buf(BIO *out, const char *label, - const unsigned char *buf, size_t buflen) -{ - size_t i; - - if (BIO_printf(out, "%s\n", label) <= 0) - return 0; - - for (i = 0; i < buflen; i++) { - if ((i % LABELED_BUF_PRINT_WIDTH) == 0) { - if (i > 0 && BIO_printf(out, "\n") <= 0) - return 0; - if (BIO_printf(out, " ") <= 0) - return 0; - } - - if (BIO_printf(out, "%02x%s", buf[i], - (i == buflen - 1) ? "" : ":") <= 0) - return 0; - } - if (BIO_printf(out, "\n") <= 0) - return 0; - - return 1; -} -#endif - -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) -static int ffc_params_to_text(BIO *out, const FFC_PARAMS *ffc) -{ - if (ffc->nid != NID_undef) { -#ifndef OPENSSL_NO_DH - const DH_NAMED_GROUP *group = ossl_ffc_uid_to_dh_named_group(ffc->nid); - const char *name = ossl_ffc_named_group_get_name(group); - - if (name == NULL) - goto err; - if (BIO_printf(out, "GROUP: %s\n", name) <= 0) - goto err; - return 1; -#else - /* How could this be? We should not have a nid in a no-dh build. */ - goto err; -#endif - } - - if (!print_labeled_bignum(out, "P: ", ffc->p)) - goto err; - if (ffc->q != NULL) { - if (!print_labeled_bignum(out, "Q: ", ffc->q)) - goto err; - } - if (!print_labeled_bignum(out, "G: ", ffc->g)) - goto err; - if (ffc->j != NULL) { - if (!print_labeled_bignum(out, "J: ", ffc->j)) - goto err; - } - if (ffc->seed != NULL) { - if (!print_labeled_buf(out, "SEED:", ffc->seed, ffc->seedlen)) - goto err; - } - if (ffc->gindex != -1) { - if (BIO_printf(out, "gindex: %d\n", ffc->gindex) <= 0) - goto err; - } - if (ffc->pcounter != -1) { - if (BIO_printf(out, "pcounter: %d\n", ffc->pcounter) <= 0) - goto err; - } - if (ffc->h != 0) { - if (BIO_printf(out, "h: %d\n", ffc->h) <= 0) - goto err; - } - return 1; -err: - return 0; -} -#endif - /* ---------------------------------------------------------------------- */ #ifndef OPENSSL_NO_DH @@ -266,13 +86,13 @@ static int dh_to_text(BIO *out, const void *key, int selection) if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) return 0; if (priv_key != NULL - && !print_labeled_bignum(out, "private-key:", priv_key)) + && !ossl_bio_print_labeled_bignum(out, "private-key:", priv_key)) return 0; if (pub_key != NULL - && !print_labeled_bignum(out, "public-key:", pub_key)) + && !ossl_bio_print_labeled_bignum(out, "public-key:", pub_key)) return 0; if (params != NULL - && !ffc_params_to_text(out, params)) + && !ossl_bio_print_ffc_params(out, params)) return 0; length = DH_get_length(dh); if (length > 0 @@ -338,13 +158,13 @@ static int dsa_to_text(BIO *out, const void *key, int selection) if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) return 0; if (priv_key != NULL - && !print_labeled_bignum(out, "priv:", priv_key)) + && !ossl_bio_print_labeled_bignum(out, "priv:", priv_key)) return 0; if (pub_key != NULL - && !print_labeled_bignum(out, "pub: ", pub_key)) + && !ossl_bio_print_labeled_bignum(out, "pub: ", pub_key)) return 0; if (params != NULL - && !ffc_params_to_text(out, params)) + && !ossl_bio_print_ffc_params(out, params)) return 0; return 1; @@ -376,9 +196,9 @@ static int ec_param_explicit_curve_to_text(BIO *out, const EC_GROUP *group, return 0; plabel = "Polynomial:"; } - return print_labeled_bignum(out, plabel, p) - && print_labeled_bignum(out, "A: ", a) - && print_labeled_bignum(out, "B: ", b); + return ossl_bio_print_labeled_bignum(out, plabel, p) + && ossl_bio_print_labeled_bignum(out, "A: ", a) + && ossl_bio_print_labeled_bignum(out, "B: ", b); } static int ec_param_explicit_gen_to_text(BIO *out, const EC_GROUP *group, @@ -415,7 +235,7 @@ static int ec_param_explicit_gen_to_text(BIO *out, const EC_GROUP *group, if (buflen == 0) return 0; - ret = print_labeled_buf(out, glabel, buf, buflen); + ret = ossl_bio_print_labeled_buf(out, glabel, buf, buflen); OPENSSL_clear_free(buf, buflen); return ret; } @@ -449,11 +269,11 @@ static int ec_param_explicit_to_text(BIO *out, const EC_GROUP *group, if (BIO_printf(out, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0 || !ec_param_explicit_curve_to_text(out, group, ctx) || !ec_param_explicit_gen_to_text(out, group, ctx) - || !print_labeled_bignum(out, "Order: ", order) + || !ossl_bio_print_labeled_bignum(out, "Order: ", order) || (cofactor != NULL - && !print_labeled_bignum(out, "Cofactor: ", cofactor)) + && !ossl_bio_print_labeled_bignum(out, "Cofactor: ", cofactor)) || (seed != NULL - && !print_labeled_buf(out, "Seed:", seed, seed_len))) + && !ossl_bio_print_labeled_buf(out, "Seed:", seed, seed_len))) goto err; ret = 1; err: @@ -540,10 +360,10 @@ static int ec_to_text(BIO *out, const void *key, int selection) EC_GROUP_order_bits(group)) <= 0) goto err; if (priv != NULL - && !print_labeled_buf(out, "priv:", priv, priv_len)) + && !ossl_bio_print_labeled_buf(out, "priv:", priv, priv_len)) goto err; if (pub != NULL - && !print_labeled_buf(out, "pub:", pub, pub_len)) + && !ossl_bio_print_labeled_buf(out, "pub:", pub, pub_len)) goto err; if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) ret = ec_param_to_text(out, group, ossl_ec_key_get_libctx(ec)); @@ -590,7 +410,7 @@ static int ecx_to_text(BIO *out, const void *key, int selection) if (BIO_printf(out, "%s Private-Key:\n", type_label) <= 0) return 0; - if (!print_labeled_buf(out, "priv:", ecx->privkey, ecx->keylen)) + if (!ossl_bio_print_labeled_buf(out, "priv:", ecx->privkey, ecx->keylen)) return 0; } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { /* ecx->pubkey is an array, not a pointer... */ @@ -603,7 +423,7 @@ static int ecx_to_text(BIO *out, const void *key, int selection) return 0; } - if (!print_labeled_buf(out, "pub:", ecx->pubkey, ecx->keylen)) + if (!ossl_bio_print_labeled_buf(out, "pub:", ecx->pubkey, ecx->keylen)) return 0; return 1; @@ -665,45 +485,45 @@ static int rsa_to_text(BIO *out, const void *key, int selection) goto err; } - if (!print_labeled_bignum(out, modulus_label, rsa_n)) + if (!ossl_bio_print_labeled_bignum(out, modulus_label, rsa_n)) goto err; - if (!print_labeled_bignum(out, exponent_label, rsa_e)) + if (!ossl_bio_print_labeled_bignum(out, exponent_label, rsa_e)) goto err; if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { int i; - if (!print_labeled_bignum(out, "privateExponent:", rsa_d)) + if (!ossl_bio_print_labeled_bignum(out, "privateExponent:", rsa_d)) goto err; - if (!print_labeled_bignum(out, "prime1:", - sk_BIGNUM_const_value(factors, 0))) + if (!ossl_bio_print_labeled_bignum(out, "prime1:", + sk_BIGNUM_const_value(factors, 0))) goto err; - if (!print_labeled_bignum(out, "prime2:", - sk_BIGNUM_const_value(factors, 1))) + if (!ossl_bio_print_labeled_bignum(out, "prime2:", + sk_BIGNUM_const_value(factors, 1))) goto err; - if (!print_labeled_bignum(out, "exponent1:", - sk_BIGNUM_const_value(exps, 0))) + if (!ossl_bio_print_labeled_bignum(out, "exponent1:", + sk_BIGNUM_const_value(exps, 0))) goto err; - if (!print_labeled_bignum(out, "exponent2:", - sk_BIGNUM_const_value(exps, 1))) + if (!ossl_bio_print_labeled_bignum(out, "exponent2:", + sk_BIGNUM_const_value(exps, 1))) goto err; - if (!print_labeled_bignum(out, "coefficient:", - sk_BIGNUM_const_value(coeffs, 0))) + if (!ossl_bio_print_labeled_bignum(out, "coefficient:", + sk_BIGNUM_const_value(coeffs, 0))) goto err; for (i = 2; i < sk_BIGNUM_const_num(factors); i++) { if (BIO_printf(out, "prime%d:", i + 1) <= 0) goto err; - if (!print_labeled_bignum(out, NULL, - sk_BIGNUM_const_value(factors, i))) + if (!ossl_bio_print_labeled_bignum(out, NULL, + sk_BIGNUM_const_value(factors, i))) goto err; if (BIO_printf(out, "exponent%d:", i + 1) <= 0) goto err; - if (!print_labeled_bignum(out, NULL, - sk_BIGNUM_const_value(exps, i))) + if (!ossl_bio_print_labeled_bignum(out, NULL, + sk_BIGNUM_const_value(exps, i))) goto err; if (BIO_printf(out, "coefficient%d:", i + 1) <= 0) goto err; - if (!print_labeled_bignum(out, NULL, - sk_BIGNUM_const_value(coeffs, i - 1))) + if (!ossl_bio_print_labeled_bignum(out, NULL, + sk_BIGNUM_const_value(coeffs, i - 1))) goto err; } } |