1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * Low level APIs are deprecated for public use, but still ok for internal use. 12e1051a39Sopenharmony_ci */ 13e1051a39Sopenharmony_ci#include "internal/deprecated.h" 14e1051a39Sopenharmony_ci 15e1051a39Sopenharmony_ci#include <ctype.h> 16e1051a39Sopenharmony_ci 17e1051a39Sopenharmony_ci#include <openssl/core.h> 18e1051a39Sopenharmony_ci#include <openssl/core_dispatch.h> 19e1051a39Sopenharmony_ci#include <openssl/core_names.h> 20e1051a39Sopenharmony_ci#include <openssl/bn.h> 21e1051a39Sopenharmony_ci#include <openssl/err.h> 22e1051a39Sopenharmony_ci#include <openssl/safestack.h> 23e1051a39Sopenharmony_ci#include <openssl/proverr.h> 24e1051a39Sopenharmony_ci#include "internal/ffc.h" 25e1051a39Sopenharmony_ci#include "crypto/bn.h" /* bn_get_words() */ 26e1051a39Sopenharmony_ci#include "crypto/dh.h" /* ossl_dh_get0_params() */ 27e1051a39Sopenharmony_ci#include "crypto/dsa.h" /* ossl_dsa_get0_params() */ 28e1051a39Sopenharmony_ci#include "crypto/ec.h" /* ossl_ec_key_get_libctx */ 29e1051a39Sopenharmony_ci#include "crypto/ecx.h" /* ECX_KEY, etc... */ 30e1051a39Sopenharmony_ci#include "crypto/rsa.h" /* RSA_PSS_PARAMS_30, etc... */ 31e1051a39Sopenharmony_ci#include "prov/bio.h" 32e1051a39Sopenharmony_ci#include "prov/implementations.h" 33e1051a39Sopenharmony_ci#include "endecoder_local.h" 34e1051a39Sopenharmony_ci 35e1051a39Sopenharmony_ciDEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) 36e1051a39Sopenharmony_ci 37e1051a39Sopenharmony_ci# ifdef SIXTY_FOUR_BIT_LONG 38e1051a39Sopenharmony_ci# define BN_FMTu "%lu" 39e1051a39Sopenharmony_ci# define BN_FMTx "%lx" 40e1051a39Sopenharmony_ci# endif 41e1051a39Sopenharmony_ci 42e1051a39Sopenharmony_ci# ifdef SIXTY_FOUR_BIT 43e1051a39Sopenharmony_ci# define BN_FMTu "%llu" 44e1051a39Sopenharmony_ci# define BN_FMTx "%llx" 45e1051a39Sopenharmony_ci# endif 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_ci# ifdef THIRTY_TWO_BIT 48e1051a39Sopenharmony_ci# define BN_FMTu "%u" 49e1051a39Sopenharmony_ci# define BN_FMTx "%x" 50e1051a39Sopenharmony_ci# endif 51e1051a39Sopenharmony_ci 52e1051a39Sopenharmony_cistatic int print_labeled_bignum(BIO *out, const char *label, const BIGNUM *bn) 53e1051a39Sopenharmony_ci{ 54e1051a39Sopenharmony_ci int ret = 0, use_sep = 0; 55e1051a39Sopenharmony_ci char *hex_str = NULL, *p; 56e1051a39Sopenharmony_ci const char spaces[] = " "; 57e1051a39Sopenharmony_ci const char *post_label_spc = " "; 58e1051a39Sopenharmony_ci 59e1051a39Sopenharmony_ci const char *neg = ""; 60e1051a39Sopenharmony_ci int bytes; 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_ci if (bn == NULL) 63e1051a39Sopenharmony_ci return 0; 64e1051a39Sopenharmony_ci if (label == NULL) { 65e1051a39Sopenharmony_ci label = ""; 66e1051a39Sopenharmony_ci post_label_spc = ""; 67e1051a39Sopenharmony_ci } 68e1051a39Sopenharmony_ci 69e1051a39Sopenharmony_ci if (BN_is_zero(bn)) 70e1051a39Sopenharmony_ci return BIO_printf(out, "%s%s0\n", label, post_label_spc); 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci if (BN_num_bytes(bn) <= BN_BYTES) { 73e1051a39Sopenharmony_ci BN_ULONG *words = bn_get_words(bn); 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_ci if (BN_is_negative(bn)) 76e1051a39Sopenharmony_ci neg = "-"; 77e1051a39Sopenharmony_ci 78e1051a39Sopenharmony_ci return BIO_printf(out, "%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n", 79e1051a39Sopenharmony_ci label, post_label_spc, neg, words[0], neg, words[0]); 80e1051a39Sopenharmony_ci } 81e1051a39Sopenharmony_ci 82e1051a39Sopenharmony_ci hex_str = BN_bn2hex(bn); 83e1051a39Sopenharmony_ci if (hex_str == NULL) 84e1051a39Sopenharmony_ci return 0; 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_ci p = hex_str; 87e1051a39Sopenharmony_ci if (*p == '-') { 88e1051a39Sopenharmony_ci ++p; 89e1051a39Sopenharmony_ci neg = " (Negative)"; 90e1051a39Sopenharmony_ci } 91e1051a39Sopenharmony_ci if (BIO_printf(out, "%s%s\n", label, neg) <= 0) 92e1051a39Sopenharmony_ci goto err; 93e1051a39Sopenharmony_ci 94e1051a39Sopenharmony_ci /* Keep track of how many bytes we have printed out so far */ 95e1051a39Sopenharmony_ci bytes = 0; 96e1051a39Sopenharmony_ci 97e1051a39Sopenharmony_ci if (BIO_printf(out, "%s", spaces) <= 0) 98e1051a39Sopenharmony_ci goto err; 99e1051a39Sopenharmony_ci 100e1051a39Sopenharmony_ci /* Add a leading 00 if the top bit is set */ 101e1051a39Sopenharmony_ci if (*p >= '8') { 102e1051a39Sopenharmony_ci if (BIO_printf(out, "%02x", 0) <= 0) 103e1051a39Sopenharmony_ci goto err; 104e1051a39Sopenharmony_ci ++bytes; 105e1051a39Sopenharmony_ci use_sep = 1; 106e1051a39Sopenharmony_ci } 107e1051a39Sopenharmony_ci while (*p != '\0') { 108e1051a39Sopenharmony_ci /* Do a newline after every 15 hex bytes + add the space indent */ 109e1051a39Sopenharmony_ci if ((bytes % 15) == 0 && bytes > 0) { 110e1051a39Sopenharmony_ci if (BIO_printf(out, ":\n%s", spaces) <= 0) 111e1051a39Sopenharmony_ci goto err; 112e1051a39Sopenharmony_ci use_sep = 0; /* The first byte on the next line doesnt have a : */ 113e1051a39Sopenharmony_ci } 114e1051a39Sopenharmony_ci if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "", 115e1051a39Sopenharmony_ci tolower(p[0]), tolower(p[1])) <= 0) 116e1051a39Sopenharmony_ci goto err; 117e1051a39Sopenharmony_ci ++bytes; 118e1051a39Sopenharmony_ci p += 2; 119e1051a39Sopenharmony_ci use_sep = 1; 120e1051a39Sopenharmony_ci } 121e1051a39Sopenharmony_ci if (BIO_printf(out, "\n") <= 0) 122e1051a39Sopenharmony_ci goto err; 123e1051a39Sopenharmony_ci ret = 1; 124e1051a39Sopenharmony_cierr: 125e1051a39Sopenharmony_ci OPENSSL_free(hex_str); 126e1051a39Sopenharmony_ci return ret; 127e1051a39Sopenharmony_ci} 128e1051a39Sopenharmony_ci 129e1051a39Sopenharmony_ci/* Number of octets per line */ 130e1051a39Sopenharmony_ci#define LABELED_BUF_PRINT_WIDTH 15 131e1051a39Sopenharmony_ci 132e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) 133e1051a39Sopenharmony_cistatic int print_labeled_buf(BIO *out, const char *label, 134e1051a39Sopenharmony_ci const unsigned char *buf, size_t buflen) 135e1051a39Sopenharmony_ci{ 136e1051a39Sopenharmony_ci size_t i; 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ci if (BIO_printf(out, "%s\n", label) <= 0) 139e1051a39Sopenharmony_ci return 0; 140e1051a39Sopenharmony_ci 141e1051a39Sopenharmony_ci for (i = 0; i < buflen; i++) { 142e1051a39Sopenharmony_ci if ((i % LABELED_BUF_PRINT_WIDTH) == 0) { 143e1051a39Sopenharmony_ci if (i > 0 && BIO_printf(out, "\n") <= 0) 144e1051a39Sopenharmony_ci return 0; 145e1051a39Sopenharmony_ci if (BIO_printf(out, " ") <= 0) 146e1051a39Sopenharmony_ci return 0; 147e1051a39Sopenharmony_ci } 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ci if (BIO_printf(out, "%02x%s", buf[i], 150e1051a39Sopenharmony_ci (i == buflen - 1) ? "" : ":") <= 0) 151e1051a39Sopenharmony_ci return 0; 152e1051a39Sopenharmony_ci } 153e1051a39Sopenharmony_ci if (BIO_printf(out, "\n") <= 0) 154e1051a39Sopenharmony_ci return 0; 155e1051a39Sopenharmony_ci 156e1051a39Sopenharmony_ci return 1; 157e1051a39Sopenharmony_ci} 158e1051a39Sopenharmony_ci#endif 159e1051a39Sopenharmony_ci 160e1051a39Sopenharmony_ci#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) 161e1051a39Sopenharmony_cistatic int ffc_params_to_text(BIO *out, const FFC_PARAMS *ffc) 162e1051a39Sopenharmony_ci{ 163e1051a39Sopenharmony_ci if (ffc->nid != NID_undef) { 164e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DH 165e1051a39Sopenharmony_ci const DH_NAMED_GROUP *group = ossl_ffc_uid_to_dh_named_group(ffc->nid); 166e1051a39Sopenharmony_ci const char *name = ossl_ffc_named_group_get_name(group); 167e1051a39Sopenharmony_ci 168e1051a39Sopenharmony_ci if (name == NULL) 169e1051a39Sopenharmony_ci goto err; 170e1051a39Sopenharmony_ci if (BIO_printf(out, "GROUP: %s\n", name) <= 0) 171e1051a39Sopenharmony_ci goto err; 172e1051a39Sopenharmony_ci return 1; 173e1051a39Sopenharmony_ci#else 174e1051a39Sopenharmony_ci /* How could this be? We should not have a nid in a no-dh build. */ 175e1051a39Sopenharmony_ci goto err; 176e1051a39Sopenharmony_ci#endif 177e1051a39Sopenharmony_ci } 178e1051a39Sopenharmony_ci 179e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, "P: ", ffc->p)) 180e1051a39Sopenharmony_ci goto err; 181e1051a39Sopenharmony_ci if (ffc->q != NULL) { 182e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, "Q: ", ffc->q)) 183e1051a39Sopenharmony_ci goto err; 184e1051a39Sopenharmony_ci } 185e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, "G: ", ffc->g)) 186e1051a39Sopenharmony_ci goto err; 187e1051a39Sopenharmony_ci if (ffc->j != NULL) { 188e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, "J: ", ffc->j)) 189e1051a39Sopenharmony_ci goto err; 190e1051a39Sopenharmony_ci } 191e1051a39Sopenharmony_ci if (ffc->seed != NULL) { 192e1051a39Sopenharmony_ci if (!print_labeled_buf(out, "SEED:", ffc->seed, ffc->seedlen)) 193e1051a39Sopenharmony_ci goto err; 194e1051a39Sopenharmony_ci } 195e1051a39Sopenharmony_ci if (ffc->gindex != -1) { 196e1051a39Sopenharmony_ci if (BIO_printf(out, "gindex: %d\n", ffc->gindex) <= 0) 197e1051a39Sopenharmony_ci goto err; 198e1051a39Sopenharmony_ci } 199e1051a39Sopenharmony_ci if (ffc->pcounter != -1) { 200e1051a39Sopenharmony_ci if (BIO_printf(out, "pcounter: %d\n", ffc->pcounter) <= 0) 201e1051a39Sopenharmony_ci goto err; 202e1051a39Sopenharmony_ci } 203e1051a39Sopenharmony_ci if (ffc->h != 0) { 204e1051a39Sopenharmony_ci if (BIO_printf(out, "h: %d\n", ffc->h) <= 0) 205e1051a39Sopenharmony_ci goto err; 206e1051a39Sopenharmony_ci } 207e1051a39Sopenharmony_ci return 1; 208e1051a39Sopenharmony_cierr: 209e1051a39Sopenharmony_ci return 0; 210e1051a39Sopenharmony_ci} 211e1051a39Sopenharmony_ci#endif 212e1051a39Sopenharmony_ci 213e1051a39Sopenharmony_ci/* ---------------------------------------------------------------------- */ 214e1051a39Sopenharmony_ci 215e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DH 216e1051a39Sopenharmony_cistatic int dh_to_text(BIO *out, const void *key, int selection) 217e1051a39Sopenharmony_ci{ 218e1051a39Sopenharmony_ci const DH *dh = key; 219e1051a39Sopenharmony_ci const char *type_label = NULL; 220e1051a39Sopenharmony_ci const BIGNUM *priv_key = NULL, *pub_key = NULL; 221e1051a39Sopenharmony_ci const FFC_PARAMS *params = NULL; 222e1051a39Sopenharmony_ci const BIGNUM *p = NULL; 223e1051a39Sopenharmony_ci long length; 224e1051a39Sopenharmony_ci 225e1051a39Sopenharmony_ci if (out == NULL || dh == NULL) { 226e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 227e1051a39Sopenharmony_ci return 0; 228e1051a39Sopenharmony_ci } 229e1051a39Sopenharmony_ci 230e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 231e1051a39Sopenharmony_ci type_label = "DH Private-Key"; 232e1051a39Sopenharmony_ci else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 233e1051a39Sopenharmony_ci type_label = "DH Public-Key"; 234e1051a39Sopenharmony_ci else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 235e1051a39Sopenharmony_ci type_label = "DH Parameters"; 236e1051a39Sopenharmony_ci 237e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 238e1051a39Sopenharmony_ci priv_key = DH_get0_priv_key(dh); 239e1051a39Sopenharmony_ci if (priv_key == NULL) { 240e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 241e1051a39Sopenharmony_ci return 0; 242e1051a39Sopenharmony_ci } 243e1051a39Sopenharmony_ci } 244e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 245e1051a39Sopenharmony_ci pub_key = DH_get0_pub_key(dh); 246e1051a39Sopenharmony_ci if (pub_key == NULL) { 247e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 248e1051a39Sopenharmony_ci return 0; 249e1051a39Sopenharmony_ci } 250e1051a39Sopenharmony_ci } 251e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { 252e1051a39Sopenharmony_ci params = ossl_dh_get0_params((DH *)dh); 253e1051a39Sopenharmony_ci if (params == NULL) { 254e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS); 255e1051a39Sopenharmony_ci return 0; 256e1051a39Sopenharmony_ci } 257e1051a39Sopenharmony_ci } 258e1051a39Sopenharmony_ci 259e1051a39Sopenharmony_ci p = DH_get0_p(dh); 260e1051a39Sopenharmony_ci if (p == NULL) { 261e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); 262e1051a39Sopenharmony_ci return 0; 263e1051a39Sopenharmony_ci } 264e1051a39Sopenharmony_ci 265e1051a39Sopenharmony_ci if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) 266e1051a39Sopenharmony_ci return 0; 267e1051a39Sopenharmony_ci if (priv_key != NULL 268e1051a39Sopenharmony_ci && !print_labeled_bignum(out, "private-key:", priv_key)) 269e1051a39Sopenharmony_ci return 0; 270e1051a39Sopenharmony_ci if (pub_key != NULL 271e1051a39Sopenharmony_ci && !print_labeled_bignum(out, "public-key:", pub_key)) 272e1051a39Sopenharmony_ci return 0; 273e1051a39Sopenharmony_ci if (params != NULL 274e1051a39Sopenharmony_ci && !ffc_params_to_text(out, params)) 275e1051a39Sopenharmony_ci return 0; 276e1051a39Sopenharmony_ci length = DH_get_length(dh); 277e1051a39Sopenharmony_ci if (length > 0 278e1051a39Sopenharmony_ci && BIO_printf(out, "recommended-private-length: %ld bits\n", 279e1051a39Sopenharmony_ci length) <= 0) 280e1051a39Sopenharmony_ci return 0; 281e1051a39Sopenharmony_ci 282e1051a39Sopenharmony_ci return 1; 283e1051a39Sopenharmony_ci} 284e1051a39Sopenharmony_ci 285e1051a39Sopenharmony_ci# define dh_input_type "DH" 286e1051a39Sopenharmony_ci# define dhx_input_type "DHX" 287e1051a39Sopenharmony_ci#endif 288e1051a39Sopenharmony_ci 289e1051a39Sopenharmony_ci/* ---------------------------------------------------------------------- */ 290e1051a39Sopenharmony_ci 291e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DSA 292e1051a39Sopenharmony_cistatic int dsa_to_text(BIO *out, const void *key, int selection) 293e1051a39Sopenharmony_ci{ 294e1051a39Sopenharmony_ci const DSA *dsa = key; 295e1051a39Sopenharmony_ci const char *type_label = NULL; 296e1051a39Sopenharmony_ci const BIGNUM *priv_key = NULL, *pub_key = NULL; 297e1051a39Sopenharmony_ci const FFC_PARAMS *params = NULL; 298e1051a39Sopenharmony_ci const BIGNUM *p = NULL; 299e1051a39Sopenharmony_ci 300e1051a39Sopenharmony_ci if (out == NULL || dsa == NULL) { 301e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 302e1051a39Sopenharmony_ci return 0; 303e1051a39Sopenharmony_ci } 304e1051a39Sopenharmony_ci 305e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 306e1051a39Sopenharmony_ci type_label = "Private-Key"; 307e1051a39Sopenharmony_ci else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 308e1051a39Sopenharmony_ci type_label = "Public-Key"; 309e1051a39Sopenharmony_ci else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 310e1051a39Sopenharmony_ci type_label = "DSA-Parameters"; 311e1051a39Sopenharmony_ci 312e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 313e1051a39Sopenharmony_ci priv_key = DSA_get0_priv_key(dsa); 314e1051a39Sopenharmony_ci if (priv_key == NULL) { 315e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 316e1051a39Sopenharmony_ci return 0; 317e1051a39Sopenharmony_ci } 318e1051a39Sopenharmony_ci } 319e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 320e1051a39Sopenharmony_ci pub_key = DSA_get0_pub_key(dsa); 321e1051a39Sopenharmony_ci if (pub_key == NULL) { 322e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 323e1051a39Sopenharmony_ci return 0; 324e1051a39Sopenharmony_ci } 325e1051a39Sopenharmony_ci } 326e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) { 327e1051a39Sopenharmony_ci params = ossl_dsa_get0_params((DSA *)dsa); 328e1051a39Sopenharmony_ci if (params == NULL) { 329e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS); 330e1051a39Sopenharmony_ci return 0; 331e1051a39Sopenharmony_ci } 332e1051a39Sopenharmony_ci } 333e1051a39Sopenharmony_ci 334e1051a39Sopenharmony_ci p = DSA_get0_p(dsa); 335e1051a39Sopenharmony_ci if (p == NULL) { 336e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); 337e1051a39Sopenharmony_ci return 0; 338e1051a39Sopenharmony_ci } 339e1051a39Sopenharmony_ci 340e1051a39Sopenharmony_ci if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) 341e1051a39Sopenharmony_ci return 0; 342e1051a39Sopenharmony_ci if (priv_key != NULL 343e1051a39Sopenharmony_ci && !print_labeled_bignum(out, "priv:", priv_key)) 344e1051a39Sopenharmony_ci return 0; 345e1051a39Sopenharmony_ci if (pub_key != NULL 346e1051a39Sopenharmony_ci && !print_labeled_bignum(out, "pub: ", pub_key)) 347e1051a39Sopenharmony_ci return 0; 348e1051a39Sopenharmony_ci if (params != NULL 349e1051a39Sopenharmony_ci && !ffc_params_to_text(out, params)) 350e1051a39Sopenharmony_ci return 0; 351e1051a39Sopenharmony_ci 352e1051a39Sopenharmony_ci return 1; 353e1051a39Sopenharmony_ci} 354e1051a39Sopenharmony_ci 355e1051a39Sopenharmony_ci# define dsa_input_type "DSA" 356e1051a39Sopenharmony_ci#endif 357e1051a39Sopenharmony_ci 358e1051a39Sopenharmony_ci/* ---------------------------------------------------------------------- */ 359e1051a39Sopenharmony_ci 360e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC 361e1051a39Sopenharmony_cistatic int ec_param_explicit_curve_to_text(BIO *out, const EC_GROUP *group, 362e1051a39Sopenharmony_ci BN_CTX *ctx) 363e1051a39Sopenharmony_ci{ 364e1051a39Sopenharmony_ci const char *plabel = "Prime:"; 365e1051a39Sopenharmony_ci BIGNUM *p = NULL, *a = NULL, *b = NULL; 366e1051a39Sopenharmony_ci 367e1051a39Sopenharmony_ci p = BN_CTX_get(ctx); 368e1051a39Sopenharmony_ci a = BN_CTX_get(ctx); 369e1051a39Sopenharmony_ci b = BN_CTX_get(ctx); 370e1051a39Sopenharmony_ci if (b == NULL 371e1051a39Sopenharmony_ci || !EC_GROUP_get_curve(group, p, a, b, ctx)) 372e1051a39Sopenharmony_ci return 0; 373e1051a39Sopenharmony_ci 374e1051a39Sopenharmony_ci if (EC_GROUP_get_field_type(group) == NID_X9_62_characteristic_two_field) { 375e1051a39Sopenharmony_ci int basis_type = EC_GROUP_get_basis_type(group); 376e1051a39Sopenharmony_ci 377e1051a39Sopenharmony_ci /* print the 'short name' of the base type OID */ 378e1051a39Sopenharmony_ci if (basis_type == NID_undef 379e1051a39Sopenharmony_ci || BIO_printf(out, "Basis Type: %s\n", OBJ_nid2sn(basis_type)) <= 0) 380e1051a39Sopenharmony_ci return 0; 381e1051a39Sopenharmony_ci plabel = "Polynomial:"; 382e1051a39Sopenharmony_ci } 383e1051a39Sopenharmony_ci return print_labeled_bignum(out, plabel, p) 384e1051a39Sopenharmony_ci && print_labeled_bignum(out, "A: ", a) 385e1051a39Sopenharmony_ci && print_labeled_bignum(out, "B: ", b); 386e1051a39Sopenharmony_ci} 387e1051a39Sopenharmony_ci 388e1051a39Sopenharmony_cistatic int ec_param_explicit_gen_to_text(BIO *out, const EC_GROUP *group, 389e1051a39Sopenharmony_ci BN_CTX *ctx) 390e1051a39Sopenharmony_ci{ 391e1051a39Sopenharmony_ci int ret; 392e1051a39Sopenharmony_ci size_t buflen; 393e1051a39Sopenharmony_ci point_conversion_form_t form; 394e1051a39Sopenharmony_ci const EC_POINT *point = NULL; 395e1051a39Sopenharmony_ci const char *glabel = NULL; 396e1051a39Sopenharmony_ci unsigned char *buf = NULL; 397e1051a39Sopenharmony_ci 398e1051a39Sopenharmony_ci form = EC_GROUP_get_point_conversion_form(group); 399e1051a39Sopenharmony_ci point = EC_GROUP_get0_generator(group); 400e1051a39Sopenharmony_ci 401e1051a39Sopenharmony_ci if (point == NULL) 402e1051a39Sopenharmony_ci return 0; 403e1051a39Sopenharmony_ci 404e1051a39Sopenharmony_ci switch (form) { 405e1051a39Sopenharmony_ci case POINT_CONVERSION_COMPRESSED: 406e1051a39Sopenharmony_ci glabel = "Generator (compressed):"; 407e1051a39Sopenharmony_ci break; 408e1051a39Sopenharmony_ci case POINT_CONVERSION_UNCOMPRESSED: 409e1051a39Sopenharmony_ci glabel = "Generator (uncompressed):"; 410e1051a39Sopenharmony_ci break; 411e1051a39Sopenharmony_ci case POINT_CONVERSION_HYBRID: 412e1051a39Sopenharmony_ci glabel = "Generator (hybrid):"; 413e1051a39Sopenharmony_ci break; 414e1051a39Sopenharmony_ci default: 415e1051a39Sopenharmony_ci return 0; 416e1051a39Sopenharmony_ci } 417e1051a39Sopenharmony_ci 418e1051a39Sopenharmony_ci buflen = EC_POINT_point2buf(group, point, form, &buf, ctx); 419e1051a39Sopenharmony_ci if (buflen == 0) 420e1051a39Sopenharmony_ci return 0; 421e1051a39Sopenharmony_ci 422e1051a39Sopenharmony_ci ret = print_labeled_buf(out, glabel, buf, buflen); 423e1051a39Sopenharmony_ci OPENSSL_clear_free(buf, buflen); 424e1051a39Sopenharmony_ci return ret; 425e1051a39Sopenharmony_ci} 426e1051a39Sopenharmony_ci 427e1051a39Sopenharmony_ci/* Print explicit parameters */ 428e1051a39Sopenharmony_cistatic int ec_param_explicit_to_text(BIO *out, const EC_GROUP *group, 429e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx) 430e1051a39Sopenharmony_ci{ 431e1051a39Sopenharmony_ci int ret = 0, tmp_nid; 432e1051a39Sopenharmony_ci BN_CTX *ctx = NULL; 433e1051a39Sopenharmony_ci const BIGNUM *order = NULL, *cofactor = NULL; 434e1051a39Sopenharmony_ci const unsigned char *seed; 435e1051a39Sopenharmony_ci size_t seed_len = 0; 436e1051a39Sopenharmony_ci 437e1051a39Sopenharmony_ci ctx = BN_CTX_new_ex(libctx); 438e1051a39Sopenharmony_ci if (ctx == NULL) 439e1051a39Sopenharmony_ci return 0; 440e1051a39Sopenharmony_ci BN_CTX_start(ctx); 441e1051a39Sopenharmony_ci 442e1051a39Sopenharmony_ci tmp_nid = EC_GROUP_get_field_type(group); 443e1051a39Sopenharmony_ci order = EC_GROUP_get0_order(group); 444e1051a39Sopenharmony_ci if (order == NULL) 445e1051a39Sopenharmony_ci goto err; 446e1051a39Sopenharmony_ci 447e1051a39Sopenharmony_ci seed = EC_GROUP_get0_seed(group); 448e1051a39Sopenharmony_ci if (seed != NULL) 449e1051a39Sopenharmony_ci seed_len = EC_GROUP_get_seed_len(group); 450e1051a39Sopenharmony_ci cofactor = EC_GROUP_get0_cofactor(group); 451e1051a39Sopenharmony_ci 452e1051a39Sopenharmony_ci /* print the 'short name' of the field type */ 453e1051a39Sopenharmony_ci if (BIO_printf(out, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0 454e1051a39Sopenharmony_ci || !ec_param_explicit_curve_to_text(out, group, ctx) 455e1051a39Sopenharmony_ci || !ec_param_explicit_gen_to_text(out, group, ctx) 456e1051a39Sopenharmony_ci || !print_labeled_bignum(out, "Order: ", order) 457e1051a39Sopenharmony_ci || (cofactor != NULL 458e1051a39Sopenharmony_ci && !print_labeled_bignum(out, "Cofactor: ", cofactor)) 459e1051a39Sopenharmony_ci || (seed != NULL 460e1051a39Sopenharmony_ci && !print_labeled_buf(out, "Seed:", seed, seed_len))) 461e1051a39Sopenharmony_ci goto err; 462e1051a39Sopenharmony_ci ret = 1; 463e1051a39Sopenharmony_cierr: 464e1051a39Sopenharmony_ci BN_CTX_end(ctx); 465e1051a39Sopenharmony_ci BN_CTX_free(ctx); 466e1051a39Sopenharmony_ci return ret; 467e1051a39Sopenharmony_ci} 468e1051a39Sopenharmony_ci 469e1051a39Sopenharmony_cistatic int ec_param_to_text(BIO *out, const EC_GROUP *group, 470e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx) 471e1051a39Sopenharmony_ci{ 472e1051a39Sopenharmony_ci if (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) { 473e1051a39Sopenharmony_ci const char *curve_name; 474e1051a39Sopenharmony_ci int curve_nid = EC_GROUP_get_curve_name(group); 475e1051a39Sopenharmony_ci 476e1051a39Sopenharmony_ci /* Explicit parameters */ 477e1051a39Sopenharmony_ci if (curve_nid == NID_undef) 478e1051a39Sopenharmony_ci return 0; 479e1051a39Sopenharmony_ci 480e1051a39Sopenharmony_ci if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0) 481e1051a39Sopenharmony_ci return 0; 482e1051a39Sopenharmony_ci 483e1051a39Sopenharmony_ci curve_name = EC_curve_nid2nist(curve_nid); 484e1051a39Sopenharmony_ci return (curve_name == NULL 485e1051a39Sopenharmony_ci || BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0); 486e1051a39Sopenharmony_ci } else { 487e1051a39Sopenharmony_ci return ec_param_explicit_to_text(out, group, libctx); 488e1051a39Sopenharmony_ci } 489e1051a39Sopenharmony_ci} 490e1051a39Sopenharmony_ci 491e1051a39Sopenharmony_cistatic int ec_to_text(BIO *out, const void *key, int selection) 492e1051a39Sopenharmony_ci{ 493e1051a39Sopenharmony_ci const EC_KEY *ec = key; 494e1051a39Sopenharmony_ci const char *type_label = NULL; 495e1051a39Sopenharmony_ci unsigned char *priv = NULL, *pub = NULL; 496e1051a39Sopenharmony_ci size_t priv_len = 0, pub_len = 0; 497e1051a39Sopenharmony_ci const EC_GROUP *group; 498e1051a39Sopenharmony_ci int ret = 0; 499e1051a39Sopenharmony_ci 500e1051a39Sopenharmony_ci if (out == NULL || ec == NULL) { 501e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 502e1051a39Sopenharmony_ci return 0; 503e1051a39Sopenharmony_ci } 504e1051a39Sopenharmony_ci 505e1051a39Sopenharmony_ci if ((group = EC_KEY_get0_group(ec)) == NULL) { 506e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY); 507e1051a39Sopenharmony_ci return 0; 508e1051a39Sopenharmony_ci } 509e1051a39Sopenharmony_ci 510e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) 511e1051a39Sopenharmony_ci type_label = "Private-Key"; 512e1051a39Sopenharmony_ci else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) 513e1051a39Sopenharmony_ci type_label = "Public-Key"; 514e1051a39Sopenharmony_ci else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 515e1051a39Sopenharmony_ci type_label = "EC-Parameters"; 516e1051a39Sopenharmony_ci 517e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 518e1051a39Sopenharmony_ci const BIGNUM *priv_key = EC_KEY_get0_private_key(ec); 519e1051a39Sopenharmony_ci 520e1051a39Sopenharmony_ci if (priv_key == NULL) { 521e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 522e1051a39Sopenharmony_ci goto err; 523e1051a39Sopenharmony_ci } 524e1051a39Sopenharmony_ci priv_len = EC_KEY_priv2buf(ec, &priv); 525e1051a39Sopenharmony_ci if (priv_len == 0) 526e1051a39Sopenharmony_ci goto err; 527e1051a39Sopenharmony_ci } 528e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 529e1051a39Sopenharmony_ci const EC_POINT *pub_pt = EC_KEY_get0_public_key(ec); 530e1051a39Sopenharmony_ci 531e1051a39Sopenharmony_ci if (pub_pt == NULL) { 532e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 533e1051a39Sopenharmony_ci goto err; 534e1051a39Sopenharmony_ci } 535e1051a39Sopenharmony_ci 536e1051a39Sopenharmony_ci pub_len = EC_KEY_key2buf(ec, EC_KEY_get_conv_form(ec), &pub, NULL); 537e1051a39Sopenharmony_ci if (pub_len == 0) 538e1051a39Sopenharmony_ci goto err; 539e1051a39Sopenharmony_ci } 540e1051a39Sopenharmony_ci 541e1051a39Sopenharmony_ci if (BIO_printf(out, "%s: (%d bit)\n", type_label, 542e1051a39Sopenharmony_ci EC_GROUP_order_bits(group)) <= 0) 543e1051a39Sopenharmony_ci goto err; 544e1051a39Sopenharmony_ci if (priv != NULL 545e1051a39Sopenharmony_ci && !print_labeled_buf(out, "priv:", priv, priv_len)) 546e1051a39Sopenharmony_ci goto err; 547e1051a39Sopenharmony_ci if (pub != NULL 548e1051a39Sopenharmony_ci && !print_labeled_buf(out, "pub:", pub, pub_len)) 549e1051a39Sopenharmony_ci goto err; 550e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) 551e1051a39Sopenharmony_ci ret = ec_param_to_text(out, group, ossl_ec_key_get_libctx(ec)); 552e1051a39Sopenharmony_cierr: 553e1051a39Sopenharmony_ci OPENSSL_clear_free(priv, priv_len); 554e1051a39Sopenharmony_ci OPENSSL_free(pub); 555e1051a39Sopenharmony_ci return ret; 556e1051a39Sopenharmony_ci} 557e1051a39Sopenharmony_ci 558e1051a39Sopenharmony_ci# define ec_input_type "EC" 559e1051a39Sopenharmony_ci 560e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_SM2 561e1051a39Sopenharmony_ci# define sm2_input_type "SM2" 562e1051a39Sopenharmony_ci# endif 563e1051a39Sopenharmony_ci#endif 564e1051a39Sopenharmony_ci 565e1051a39Sopenharmony_ci/* ---------------------------------------------------------------------- */ 566e1051a39Sopenharmony_ci 567e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC 568e1051a39Sopenharmony_cistatic int ecx_to_text(BIO *out, const void *key, int selection) 569e1051a39Sopenharmony_ci{ 570e1051a39Sopenharmony_ci const ECX_KEY *ecx = key; 571e1051a39Sopenharmony_ci const char *type_label = NULL; 572e1051a39Sopenharmony_ci 573e1051a39Sopenharmony_ci if (out == NULL || ecx == NULL) { 574e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 575e1051a39Sopenharmony_ci return 0; 576e1051a39Sopenharmony_ci } 577e1051a39Sopenharmony_ci 578e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 579e1051a39Sopenharmony_ci if (ecx->privkey == NULL) { 580e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 581e1051a39Sopenharmony_ci return 0; 582e1051a39Sopenharmony_ci } 583e1051a39Sopenharmony_ci 584e1051a39Sopenharmony_ci switch (ecx->type) { 585e1051a39Sopenharmony_ci case ECX_KEY_TYPE_X25519: 586e1051a39Sopenharmony_ci type_label = "X25519 Private-Key"; 587e1051a39Sopenharmony_ci break; 588e1051a39Sopenharmony_ci case ECX_KEY_TYPE_X448: 589e1051a39Sopenharmony_ci type_label = "X448 Private-Key"; 590e1051a39Sopenharmony_ci break; 591e1051a39Sopenharmony_ci case ECX_KEY_TYPE_ED25519: 592e1051a39Sopenharmony_ci type_label = "ED25519 Private-Key"; 593e1051a39Sopenharmony_ci break; 594e1051a39Sopenharmony_ci case ECX_KEY_TYPE_ED448: 595e1051a39Sopenharmony_ci type_label = "ED448 Private-Key"; 596e1051a39Sopenharmony_ci break; 597e1051a39Sopenharmony_ci } 598e1051a39Sopenharmony_ci } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 599e1051a39Sopenharmony_ci /* ecx->pubkey is an array, not a pointer... */ 600e1051a39Sopenharmony_ci if (!ecx->haspubkey) { 601e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); 602e1051a39Sopenharmony_ci return 0; 603e1051a39Sopenharmony_ci } 604e1051a39Sopenharmony_ci 605e1051a39Sopenharmony_ci switch (ecx->type) { 606e1051a39Sopenharmony_ci case ECX_KEY_TYPE_X25519: 607e1051a39Sopenharmony_ci type_label = "X25519 Public-Key"; 608e1051a39Sopenharmony_ci break; 609e1051a39Sopenharmony_ci case ECX_KEY_TYPE_X448: 610e1051a39Sopenharmony_ci type_label = "X448 Public-Key"; 611e1051a39Sopenharmony_ci break; 612e1051a39Sopenharmony_ci case ECX_KEY_TYPE_ED25519: 613e1051a39Sopenharmony_ci type_label = "ED25519 Public-Key"; 614e1051a39Sopenharmony_ci break; 615e1051a39Sopenharmony_ci case ECX_KEY_TYPE_ED448: 616e1051a39Sopenharmony_ci type_label = "ED448 Public-Key"; 617e1051a39Sopenharmony_ci break; 618e1051a39Sopenharmony_ci } 619e1051a39Sopenharmony_ci } 620e1051a39Sopenharmony_ci 621e1051a39Sopenharmony_ci if (BIO_printf(out, "%s:\n", type_label) <= 0) 622e1051a39Sopenharmony_ci return 0; 623e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0 624e1051a39Sopenharmony_ci && !print_labeled_buf(out, "priv:", ecx->privkey, ecx->keylen)) 625e1051a39Sopenharmony_ci return 0; 626e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0 627e1051a39Sopenharmony_ci && !print_labeled_buf(out, "pub:", ecx->pubkey, ecx->keylen)) 628e1051a39Sopenharmony_ci return 0; 629e1051a39Sopenharmony_ci 630e1051a39Sopenharmony_ci return 1; 631e1051a39Sopenharmony_ci} 632e1051a39Sopenharmony_ci 633e1051a39Sopenharmony_ci# define ed25519_input_type "ED25519" 634e1051a39Sopenharmony_ci# define ed448_input_type "ED448" 635e1051a39Sopenharmony_ci# define x25519_input_type "X25519" 636e1051a39Sopenharmony_ci# define x448_input_type "X448" 637e1051a39Sopenharmony_ci#endif 638e1051a39Sopenharmony_ci 639e1051a39Sopenharmony_ci/* ---------------------------------------------------------------------- */ 640e1051a39Sopenharmony_ci 641e1051a39Sopenharmony_cistatic int rsa_to_text(BIO *out, const void *key, int selection) 642e1051a39Sopenharmony_ci{ 643e1051a39Sopenharmony_ci const RSA *rsa = key; 644e1051a39Sopenharmony_ci const char *type_label = "RSA key"; 645e1051a39Sopenharmony_ci const char *modulus_label = NULL; 646e1051a39Sopenharmony_ci const char *exponent_label = NULL; 647e1051a39Sopenharmony_ci const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL; 648e1051a39Sopenharmony_ci STACK_OF(BIGNUM_const) *factors = NULL; 649e1051a39Sopenharmony_ci STACK_OF(BIGNUM_const) *exps = NULL; 650e1051a39Sopenharmony_ci STACK_OF(BIGNUM_const) *coeffs = NULL; 651e1051a39Sopenharmony_ci int primes; 652e1051a39Sopenharmony_ci const RSA_PSS_PARAMS_30 *pss_params = ossl_rsa_get0_pss_params_30((RSA *)rsa); 653e1051a39Sopenharmony_ci int ret = 0; 654e1051a39Sopenharmony_ci 655e1051a39Sopenharmony_ci if (out == NULL || rsa == NULL) { 656e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); 657e1051a39Sopenharmony_ci goto err; 658e1051a39Sopenharmony_ci } 659e1051a39Sopenharmony_ci 660e1051a39Sopenharmony_ci factors = sk_BIGNUM_const_new_null(); 661e1051a39Sopenharmony_ci exps = sk_BIGNUM_const_new_null(); 662e1051a39Sopenharmony_ci coeffs = sk_BIGNUM_const_new_null(); 663e1051a39Sopenharmony_ci 664e1051a39Sopenharmony_ci if (factors == NULL || exps == NULL || coeffs == NULL) { 665e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 666e1051a39Sopenharmony_ci goto err; 667e1051a39Sopenharmony_ci } 668e1051a39Sopenharmony_ci 669e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 670e1051a39Sopenharmony_ci type_label = "Private-Key"; 671e1051a39Sopenharmony_ci modulus_label = "modulus:"; 672e1051a39Sopenharmony_ci exponent_label = "publicExponent:"; 673e1051a39Sopenharmony_ci } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { 674e1051a39Sopenharmony_ci type_label = "Public-Key"; 675e1051a39Sopenharmony_ci modulus_label = "Modulus:"; 676e1051a39Sopenharmony_ci exponent_label = "Exponent:"; 677e1051a39Sopenharmony_ci } 678e1051a39Sopenharmony_ci 679e1051a39Sopenharmony_ci RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d); 680e1051a39Sopenharmony_ci ossl_rsa_get0_all_params((RSA *)rsa, factors, exps, coeffs); 681e1051a39Sopenharmony_ci primes = sk_BIGNUM_const_num(factors); 682e1051a39Sopenharmony_ci 683e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 684e1051a39Sopenharmony_ci if (BIO_printf(out, "%s: (%d bit, %d primes)\n", 685e1051a39Sopenharmony_ci type_label, BN_num_bits(rsa_n), primes) <= 0) 686e1051a39Sopenharmony_ci goto err; 687e1051a39Sopenharmony_ci } else { 688e1051a39Sopenharmony_ci if (BIO_printf(out, "%s: (%d bit)\n", 689e1051a39Sopenharmony_ci type_label, BN_num_bits(rsa_n)) <= 0) 690e1051a39Sopenharmony_ci goto err; 691e1051a39Sopenharmony_ci } 692e1051a39Sopenharmony_ci 693e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, modulus_label, rsa_n)) 694e1051a39Sopenharmony_ci goto err; 695e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, exponent_label, rsa_e)) 696e1051a39Sopenharmony_ci goto err; 697e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { 698e1051a39Sopenharmony_ci int i; 699e1051a39Sopenharmony_ci 700e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, "privateExponent:", rsa_d)) 701e1051a39Sopenharmony_ci goto err; 702e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, "prime1:", 703e1051a39Sopenharmony_ci sk_BIGNUM_const_value(factors, 0))) 704e1051a39Sopenharmony_ci goto err; 705e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, "prime2:", 706e1051a39Sopenharmony_ci sk_BIGNUM_const_value(factors, 1))) 707e1051a39Sopenharmony_ci goto err; 708e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, "exponent1:", 709e1051a39Sopenharmony_ci sk_BIGNUM_const_value(exps, 0))) 710e1051a39Sopenharmony_ci goto err; 711e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, "exponent2:", 712e1051a39Sopenharmony_ci sk_BIGNUM_const_value(exps, 1))) 713e1051a39Sopenharmony_ci goto err; 714e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, "coefficient:", 715e1051a39Sopenharmony_ci sk_BIGNUM_const_value(coeffs, 0))) 716e1051a39Sopenharmony_ci goto err; 717e1051a39Sopenharmony_ci for (i = 2; i < sk_BIGNUM_const_num(factors); i++) { 718e1051a39Sopenharmony_ci if (BIO_printf(out, "prime%d:", i + 1) <= 0) 719e1051a39Sopenharmony_ci goto err; 720e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, NULL, 721e1051a39Sopenharmony_ci sk_BIGNUM_const_value(factors, i))) 722e1051a39Sopenharmony_ci goto err; 723e1051a39Sopenharmony_ci if (BIO_printf(out, "exponent%d:", i + 1) <= 0) 724e1051a39Sopenharmony_ci goto err; 725e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, NULL, 726e1051a39Sopenharmony_ci sk_BIGNUM_const_value(exps, i))) 727e1051a39Sopenharmony_ci goto err; 728e1051a39Sopenharmony_ci if (BIO_printf(out, "coefficient%d:", i + 1) <= 0) 729e1051a39Sopenharmony_ci goto err; 730e1051a39Sopenharmony_ci if (!print_labeled_bignum(out, NULL, 731e1051a39Sopenharmony_ci sk_BIGNUM_const_value(coeffs, i - 1))) 732e1051a39Sopenharmony_ci goto err; 733e1051a39Sopenharmony_ci } 734e1051a39Sopenharmony_ci } 735e1051a39Sopenharmony_ci 736e1051a39Sopenharmony_ci if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) { 737e1051a39Sopenharmony_ci switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) { 738e1051a39Sopenharmony_ci case RSA_FLAG_TYPE_RSA: 739e1051a39Sopenharmony_ci if (!ossl_rsa_pss_params_30_is_unrestricted(pss_params)) { 740e1051a39Sopenharmony_ci if (BIO_printf(out, "(INVALID PSS PARAMETERS)\n") <= 0) 741e1051a39Sopenharmony_ci goto err; 742e1051a39Sopenharmony_ci } 743e1051a39Sopenharmony_ci break; 744e1051a39Sopenharmony_ci case RSA_FLAG_TYPE_RSASSAPSS: 745e1051a39Sopenharmony_ci if (ossl_rsa_pss_params_30_is_unrestricted(pss_params)) { 746e1051a39Sopenharmony_ci if (BIO_printf(out, "No PSS parameter restrictions\n") <= 0) 747e1051a39Sopenharmony_ci goto err; 748e1051a39Sopenharmony_ci } else { 749e1051a39Sopenharmony_ci int hashalg_nid = ossl_rsa_pss_params_30_hashalg(pss_params); 750e1051a39Sopenharmony_ci int maskgenalg_nid = 751e1051a39Sopenharmony_ci ossl_rsa_pss_params_30_maskgenalg(pss_params); 752e1051a39Sopenharmony_ci int maskgenhashalg_nid = 753e1051a39Sopenharmony_ci ossl_rsa_pss_params_30_maskgenhashalg(pss_params); 754e1051a39Sopenharmony_ci int saltlen = ossl_rsa_pss_params_30_saltlen(pss_params); 755e1051a39Sopenharmony_ci int trailerfield = 756e1051a39Sopenharmony_ci ossl_rsa_pss_params_30_trailerfield(pss_params); 757e1051a39Sopenharmony_ci 758e1051a39Sopenharmony_ci if (BIO_printf(out, "PSS parameter restrictions:\n") <= 0) 759e1051a39Sopenharmony_ci goto err; 760e1051a39Sopenharmony_ci if (BIO_printf(out, " Hash Algorithm: %s%s\n", 761e1051a39Sopenharmony_ci ossl_rsa_oaeppss_nid2name(hashalg_nid), 762e1051a39Sopenharmony_ci (hashalg_nid == NID_sha1 763e1051a39Sopenharmony_ci ? " (default)" : "")) <= 0) 764e1051a39Sopenharmony_ci goto err; 765e1051a39Sopenharmony_ci if (BIO_printf(out, " Mask Algorithm: %s with %s%s\n", 766e1051a39Sopenharmony_ci ossl_rsa_mgf_nid2name(maskgenalg_nid), 767e1051a39Sopenharmony_ci ossl_rsa_oaeppss_nid2name(maskgenhashalg_nid), 768e1051a39Sopenharmony_ci (maskgenalg_nid == NID_mgf1 769e1051a39Sopenharmony_ci && maskgenhashalg_nid == NID_sha1 770e1051a39Sopenharmony_ci ? " (default)" : "")) <= 0) 771e1051a39Sopenharmony_ci goto err; 772e1051a39Sopenharmony_ci if (BIO_printf(out, " Minimum Salt Length: %d%s\n", 773e1051a39Sopenharmony_ci saltlen, 774e1051a39Sopenharmony_ci (saltlen == 20 ? " (default)" : "")) <= 0) 775e1051a39Sopenharmony_ci goto err; 776e1051a39Sopenharmony_ci if (BIO_printf(out, " Trailer Field: 0x%x%s\n", 777e1051a39Sopenharmony_ci trailerfield, 778e1051a39Sopenharmony_ci (trailerfield == 1 ? " (default)" : "")) <= 0) 779e1051a39Sopenharmony_ci goto err; 780e1051a39Sopenharmony_ci } 781e1051a39Sopenharmony_ci break; 782e1051a39Sopenharmony_ci } 783e1051a39Sopenharmony_ci } 784e1051a39Sopenharmony_ci 785e1051a39Sopenharmony_ci ret = 1; 786e1051a39Sopenharmony_ci err: 787e1051a39Sopenharmony_ci sk_BIGNUM_const_free(factors); 788e1051a39Sopenharmony_ci sk_BIGNUM_const_free(exps); 789e1051a39Sopenharmony_ci sk_BIGNUM_const_free(coeffs); 790e1051a39Sopenharmony_ci return ret; 791e1051a39Sopenharmony_ci} 792e1051a39Sopenharmony_ci 793e1051a39Sopenharmony_ci#define rsa_input_type "RSA" 794e1051a39Sopenharmony_ci#define rsapss_input_type "RSA-PSS" 795e1051a39Sopenharmony_ci 796e1051a39Sopenharmony_ci/* ---------------------------------------------------------------------- */ 797e1051a39Sopenharmony_ci 798e1051a39Sopenharmony_cistatic void *key2text_newctx(void *provctx) 799e1051a39Sopenharmony_ci{ 800e1051a39Sopenharmony_ci return provctx; 801e1051a39Sopenharmony_ci} 802e1051a39Sopenharmony_ci 803e1051a39Sopenharmony_cistatic void key2text_freectx(ossl_unused void *vctx) 804e1051a39Sopenharmony_ci{ 805e1051a39Sopenharmony_ci} 806e1051a39Sopenharmony_ci 807e1051a39Sopenharmony_cistatic int key2text_encode(void *vctx, const void *key, int selection, 808e1051a39Sopenharmony_ci OSSL_CORE_BIO *cout, 809e1051a39Sopenharmony_ci int (*key2text)(BIO *out, const void *key, 810e1051a39Sopenharmony_ci int selection), 811e1051a39Sopenharmony_ci OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg) 812e1051a39Sopenharmony_ci{ 813e1051a39Sopenharmony_ci BIO *out = ossl_bio_new_from_core_bio(vctx, cout); 814e1051a39Sopenharmony_ci int ret; 815e1051a39Sopenharmony_ci 816e1051a39Sopenharmony_ci if (out == NULL) 817e1051a39Sopenharmony_ci return 0; 818e1051a39Sopenharmony_ci 819e1051a39Sopenharmony_ci ret = key2text(out, key, selection); 820e1051a39Sopenharmony_ci BIO_free(out); 821e1051a39Sopenharmony_ci 822e1051a39Sopenharmony_ci return ret; 823e1051a39Sopenharmony_ci} 824e1051a39Sopenharmony_ci 825e1051a39Sopenharmony_ci#define MAKE_TEXT_ENCODER(impl, type) \ 826e1051a39Sopenharmony_ci static OSSL_FUNC_encoder_import_object_fn \ 827e1051a39Sopenharmony_ci impl##2text_import_object; \ 828e1051a39Sopenharmony_ci static OSSL_FUNC_encoder_free_object_fn \ 829e1051a39Sopenharmony_ci impl##2text_free_object; \ 830e1051a39Sopenharmony_ci static OSSL_FUNC_encoder_encode_fn impl##2text_encode; \ 831e1051a39Sopenharmony_ci \ 832e1051a39Sopenharmony_ci static void *impl##2text_import_object(void *ctx, int selection, \ 833e1051a39Sopenharmony_ci const OSSL_PARAM params[]) \ 834e1051a39Sopenharmony_ci { \ 835e1051a39Sopenharmony_ci return ossl_prov_import_key(ossl_##impl##_keymgmt_functions, \ 836e1051a39Sopenharmony_ci ctx, selection, params); \ 837e1051a39Sopenharmony_ci } \ 838e1051a39Sopenharmony_ci static void impl##2text_free_object(void *key) \ 839e1051a39Sopenharmony_ci { \ 840e1051a39Sopenharmony_ci ossl_prov_free_key(ossl_##impl##_keymgmt_functions, key); \ 841e1051a39Sopenharmony_ci } \ 842e1051a39Sopenharmony_ci static int impl##2text_encode(void *vctx, OSSL_CORE_BIO *cout, \ 843e1051a39Sopenharmony_ci const void *key, \ 844e1051a39Sopenharmony_ci const OSSL_PARAM key_abstract[], \ 845e1051a39Sopenharmony_ci int selection, \ 846e1051a39Sopenharmony_ci OSSL_PASSPHRASE_CALLBACK *cb, \ 847e1051a39Sopenharmony_ci void *cbarg) \ 848e1051a39Sopenharmony_ci { \ 849e1051a39Sopenharmony_ci /* We don't deal with abstract objects */ \ 850e1051a39Sopenharmony_ci if (key_abstract != NULL) { \ 851e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_INVALID_ARGUMENT); \ 852e1051a39Sopenharmony_ci return 0; \ 853e1051a39Sopenharmony_ci } \ 854e1051a39Sopenharmony_ci return key2text_encode(vctx, key, selection, cout, \ 855e1051a39Sopenharmony_ci type##_to_text, cb, cbarg); \ 856e1051a39Sopenharmony_ci } \ 857e1051a39Sopenharmony_ci const OSSL_DISPATCH ossl_##impl##_to_text_encoder_functions[] = { \ 858e1051a39Sopenharmony_ci { OSSL_FUNC_ENCODER_NEWCTX, \ 859e1051a39Sopenharmony_ci (void (*)(void))key2text_newctx }, \ 860e1051a39Sopenharmony_ci { OSSL_FUNC_ENCODER_FREECTX, \ 861e1051a39Sopenharmony_ci (void (*)(void))key2text_freectx }, \ 862e1051a39Sopenharmony_ci { OSSL_FUNC_ENCODER_IMPORT_OBJECT, \ 863e1051a39Sopenharmony_ci (void (*)(void))impl##2text_import_object }, \ 864e1051a39Sopenharmony_ci { OSSL_FUNC_ENCODER_FREE_OBJECT, \ 865e1051a39Sopenharmony_ci (void (*)(void))impl##2text_free_object }, \ 866e1051a39Sopenharmony_ci { OSSL_FUNC_ENCODER_ENCODE, \ 867e1051a39Sopenharmony_ci (void (*)(void))impl##2text_encode }, \ 868e1051a39Sopenharmony_ci { 0, NULL } \ 869e1051a39Sopenharmony_ci } 870e1051a39Sopenharmony_ci 871e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DH 872e1051a39Sopenharmony_ciMAKE_TEXT_ENCODER(dh, dh); 873e1051a39Sopenharmony_ciMAKE_TEXT_ENCODER(dhx, dh); 874e1051a39Sopenharmony_ci#endif 875e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_DSA 876e1051a39Sopenharmony_ciMAKE_TEXT_ENCODER(dsa, dsa); 877e1051a39Sopenharmony_ci#endif 878e1051a39Sopenharmony_ci#ifndef OPENSSL_NO_EC 879e1051a39Sopenharmony_ciMAKE_TEXT_ENCODER(ec, ec); 880e1051a39Sopenharmony_ci# ifndef OPENSSL_NO_SM2 881e1051a39Sopenharmony_ciMAKE_TEXT_ENCODER(sm2, ec); 882e1051a39Sopenharmony_ci# endif 883e1051a39Sopenharmony_ciMAKE_TEXT_ENCODER(ed25519, ecx); 884e1051a39Sopenharmony_ciMAKE_TEXT_ENCODER(ed448, ecx); 885e1051a39Sopenharmony_ciMAKE_TEXT_ENCODER(x25519, ecx); 886e1051a39Sopenharmony_ciMAKE_TEXT_ENCODER(x448, ecx); 887e1051a39Sopenharmony_ci#endif 888e1051a39Sopenharmony_ciMAKE_TEXT_ENCODER(rsa, rsa); 889e1051a39Sopenharmony_ciMAKE_TEXT_ENCODER(rsapss, rsa); 890