/*
* Copyright 2020-2021 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
*/
/*
* Low level APIs are deprecated for public use, but still ok for internal use.
*/
#include "internal/deprecated.h"
#include <ctype.h>
#include <openssl/core.h>
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/bn.h>
#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 */
#include "crypto/ecx.h" /* ECX_KEY, etc... */
#include "crypto/rsa.h" /* RSA_PSS_PARAMS_30, etc... */
#include "prov/bio.h"
#include "prov/implementations.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);
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 doesnt have a : */
}
if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "",
tolower(p[0]), tolower(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