Procházet zdrojové kódy

Pull EVP_PKEY print hooks out of the main method table.

This allows the static linker to drop it in consumers which don't need this
stuff (i.e. all sane ones), once crypto/x509 falls off. This cuts down
on a number of dependencies from the core crypto bits on crypto/asn1 and
crypto/x509.

BUG=499653

Change-Id: I76a10a04dcc444c1ded31683df9f87725a95a4e6
Reviewed-on: https://boringssl-review.googlesource.com/5660
Reviewed-by: Adam Langley <agl@google.com>
kris/onging/CECPQ3_patch15
David Benjamin před 9 roky
committed by Adam Langley
rodič
revize
8c07ad3e3b
7 změnil soubory, kde provedl 479 přidání a 388 odebrání
  1. +1
    -0
      crypto/evp/CMakeLists.txt
  2. +0
    -36
      crypto/evp/evp.c
  3. +2
    -6
      crypto/evp/internal.h
  4. +0
    -91
      crypto/evp/p_dsa_asn1.c
  5. +0
    -124
      crypto/evp/p_ec_asn1.c
  6. +2
    -131
      crypto/evp/p_rsa_asn1.c
  7. +474
    -0
      crypto/evp/print.c

+ 1
- 0
crypto/evp/CMakeLists.txt Zobrazit soubor

@@ -15,6 +15,7 @@ add_library(
p_rsa.c
p_rsa_asn1.c
pbkdf.c
print.c
sign.c
)



+ 0
- 36
crypto/evp/evp.c Zobrazit soubor

@@ -59,7 +59,6 @@
#include <assert.h>
#include <string.h>

#include <openssl/bio.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#include <openssl/err.h>
@@ -358,41 +357,6 @@ int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {
return -2;
}

static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
const char *kstr) {
BIO_indent(out, indent, 128);
BIO_printf(out, "%s algorithm \"%s\" unsupported\n", kstr,
OBJ_nid2ln(pkey->type));
return 1;
}

int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx) {
if (pkey->ameth && pkey->ameth->pub_print) {
return pkey->ameth->pub_print(out, pkey, indent, pctx);
}

return print_unsupported(out, pkey, indent, "Public Key");
}

int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx) {
if (pkey->ameth && pkey->ameth->priv_print) {
return pkey->ameth->priv_print(out, pkey, indent, pctx);
}

return print_unsupported(out, pkey, indent, "Private Key");
}

int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx) {
if (pkey->ameth && pkey->ameth->param_print) {
return pkey->ameth->param_print(out, pkey, indent, pctx);
}

return print_unsupported(out, pkey, indent, "Parameters");
}

int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) {
return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0,
(void *)md);


+ 2
- 6
crypto/evp/internal.h Zobrazit soubor

@@ -59,6 +59,8 @@

#include <openssl/base.h>

#include <openssl/rsa.h>

#if defined(__cplusplus)
extern "C" {
#endif
@@ -83,7 +85,6 @@ struct evp_pkey_asn1_method_st {
int (*pub_encode)(CBB *out, const EVP_PKEY *key);

int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);

/* priv_decode decodes |params| and |key| as a PrivateKeyInfo and writes the
* result into |out|. It returns one on success and zero on error. |params| is
@@ -95,9 +96,6 @@ struct evp_pkey_asn1_method_st {
* |out|. It returns one on success and zero on error. */
int (*priv_encode)(CBB *out, const EVP_PKEY *key);

int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx);

/* pkey_opaque returns 1 if the |pk| is opaque. Opaque keys are backed by
* custom implementations which do not expose key material and parameters.*/
int (*pkey_opaque)(const EVP_PKEY *pk);
@@ -114,8 +112,6 @@ struct evp_pkey_asn1_method_st {
int (*param_missing)(const EVP_PKEY *pk);
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx);

void (*pkey_free)(EVP_PKEY *pkey);



+ 0
- 91
crypto/evp/p_dsa_asn1.c Zobrazit soubor

@@ -55,14 +55,11 @@

#include <openssl/evp.h>

#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <openssl/digest.h>
#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>

#include "internal.h"
@@ -244,91 +241,6 @@ static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {

static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); }

static void update_buflen(const BIGNUM *b, size_t *pbuflen) {
size_t i;

if (!b) {
return;
}
i = BN_num_bytes(b);
if (*pbuflen < i) {
*pbuflen = i;
}
}

static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
uint8_t *m = NULL;
int ret = 0;
size_t buf_len = 0;
const char *ktype = NULL;

const BIGNUM *priv_key, *pub_key;

priv_key = NULL;
if (ptype == 2) {
priv_key = x->priv_key;
}

pub_key = NULL;
if (ptype > 0) {
pub_key = x->pub_key;
}

ktype = "DSA-Parameters";
if (ptype == 2) {
ktype = "Private-Key";
} else if (ptype == 1) {
ktype = "Public-Key";
}

update_buflen(x->p, &buf_len);
update_buflen(x->q, &buf_len);
update_buflen(x->g, &buf_len);
update_buflen(priv_key, &buf_len);
update_buflen(pub_key, &buf_len);

m = OPENSSL_malloc(buf_len + 10);
if (m == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}

if (priv_key) {
if (!BIO_indent(bp, off, 128) ||
BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) {
goto err;
}
}

if (!ASN1_bn_print(bp, "priv:", priv_key, m, off) ||
!ASN1_bn_print(bp, "pub: ", pub_key, m, off) ||
!ASN1_bn_print(bp, "P: ", x->p, m, off) ||
!ASN1_bn_print(bp, "Q: ", x->q, m, off) ||
!ASN1_bn_print(bp, "G: ", x->g, m, off)) {
goto err;
}
ret = 1;

err:
OPENSSL_free(m);
return ret;
}

static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
}

static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
}

static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
}

static int old_dsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
int derlen) {
DSA *dsa;
@@ -348,11 +260,9 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
dsa_pub_decode,
dsa_pub_encode,
dsa_pub_cmp,
dsa_pub_print,

dsa_priv_decode,
dsa_priv_encode,
dsa_priv_print,

NULL /* pkey_opaque */,
NULL /* pkey_supports_digest */,
@@ -363,7 +273,6 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
dsa_missing_parameters,
dsa_copy_parameters,
dsa_cmp_parameters,
dsa_param_print,

int_dsa_free,
old_dsa_priv_decode,


+ 0
- 124
crypto/evp/p_ec_asn1.c Zobrazit soubor

@@ -55,14 +55,12 @@

#include <openssl/evp.h>

#include <openssl/asn1t.h>
#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/ec.h>
#include <openssl/ec_key.h>
#include <openssl/ecdsa.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>

#include "internal.h"
@@ -236,125 +234,6 @@ static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) {

static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); }

static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
uint8_t *buffer = NULL;
const char *ecstr;
size_t buf_len = 0, i;
int ret = 0, reason = ERR_R_BIO_LIB;
BN_CTX *ctx = NULL;
const EC_GROUP *group;
const EC_POINT *public_key;
const BIGNUM *priv_key;
uint8_t *pub_key_bytes = NULL;
size_t pub_key_bytes_len = 0;

if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
reason = ERR_R_PASSED_NULL_PARAMETER;
goto err;
}

ctx = BN_CTX_new();
if (ctx == NULL) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}

if (ktype > 0) {
public_key = EC_KEY_get0_public_key(x);
if (public_key != NULL) {
pub_key_bytes_len = EC_POINT_point2oct(
group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
if (pub_key_bytes_len == 0) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
if (pub_key_bytes == NULL) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
pub_key_bytes_len =
EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
pub_key_bytes, pub_key_bytes_len, ctx);
if (pub_key_bytes_len == 0) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
buf_len = pub_key_bytes_len;
}
}

if (ktype == 2) {
priv_key = EC_KEY_get0_private_key(x);
if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
buf_len = i;
}
} else {
priv_key = NULL;
}

if (ktype > 0) {
buf_len += 10;
if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
}
if (ktype == 2) {
ecstr = "Private-Key";
} else if (ktype == 1) {
ecstr = "Public-Key";
} else {
ecstr = "ECDSA-Parameters";
}

if (!BIO_indent(bp, off, 128)) {
goto err;
}
const BIGNUM *order = EC_GROUP_get0_order(group);
if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
goto err;
}

if ((priv_key != NULL) &&
!ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) {
goto err;
}
if (pub_key_bytes != NULL) {
BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
}
/* TODO(fork): implement */
/*
if (!ECPKParameters_print(bp, group, off))
goto err; */
ret = 1;

err:
if (!ret) {
OPENSSL_PUT_ERROR(EVP, reason);
}
OPENSSL_free(pub_key_bytes);
BN_CTX_free(ctx);
OPENSSL_free(buffer);
return ret;
}

static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
}

static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
}


static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
}

static int eckey_opaque(const EVP_PKEY *pkey) {
return EC_KEY_is_opaque(pkey->pkey.ec);
}
@@ -377,11 +256,9 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
eckey_pub_decode,
eckey_pub_encode,
eckey_pub_cmp,
eckey_pub_print,

eckey_priv_decode,
eckey_priv_encode,
eckey_priv_print,

eckey_opaque,
0 /* pkey_supports_digest */,
@@ -392,7 +269,6 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
ec_missing_parameters,
ec_copy_parameters,
ec_cmp_parameters,
eckey_param_print,

int_ec_free,
old_ec_priv_decode,


+ 2
- 131
crypto/evp/p_rsa_asn1.c Zobrazit soubor

@@ -55,7 +55,7 @@

#include <openssl/evp.h>

#include <openssl/asn1.h>
#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/err.h>
@@ -175,133 +175,6 @@ static int rsa_bits(const EVP_PKEY *pkey) {

static void int_rsa_free(EVP_PKEY *pkey) { RSA_free(pkey->pkey.rsa); }

static void update_buflen(const BIGNUM *b, size_t *pbuflen) {
size_t i;

if (!b) {
return;
}

i = BN_num_bytes(b);
if (*pbuflen < i) {
*pbuflen = i;
}
}

static int do_rsa_print(BIO *out, const RSA *rsa, int off,
int include_private) {
char *str;
const char *s;
uint8_t *m = NULL;
int ret = 0, mod_len = 0;
size_t buf_len = 0;

update_buflen(rsa->n, &buf_len);
update_buflen(rsa->e, &buf_len);

if (include_private) {
update_buflen(rsa->d, &buf_len);
update_buflen(rsa->p, &buf_len);
update_buflen(rsa->q, &buf_len);
update_buflen(rsa->dmp1, &buf_len);
update_buflen(rsa->dmq1, &buf_len);
update_buflen(rsa->iqmp, &buf_len);

if (rsa->additional_primes != NULL) {
size_t i;

for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
i++) {
const RSA_additional_prime *ap =
sk_RSA_additional_prime_value(rsa->additional_primes, i);
update_buflen(ap->prime, &buf_len);
update_buflen(ap->exp, &buf_len);
update_buflen(ap->coeff, &buf_len);
}
}
}

m = OPENSSL_malloc(buf_len + 10);
if (m == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}

if (rsa->n != NULL) {
mod_len = BN_num_bits(rsa->n);
}

if (!BIO_indent(out, off, 128)) {
goto err;
}

if (include_private && rsa->d) {
if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) {
goto err;
}
str = "modulus:";
s = "publicExponent:";
} else {
if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) {
goto err;
}
str = "Modulus:";
s = "Exponent:";
}
if (!ASN1_bn_print(out, str, rsa->n, m, off) ||
!ASN1_bn_print(out, s, rsa->e, m, off)) {
goto err;
}

if (include_private) {
if (!ASN1_bn_print(out, "privateExponent:", rsa->d, m, off) ||
!ASN1_bn_print(out, "prime1:", rsa->p, m, off) ||
!ASN1_bn_print(out, "prime2:", rsa->q, m, off) ||
!ASN1_bn_print(out, "exponent1:", rsa->dmp1, m, off) ||
!ASN1_bn_print(out, "exponent2:", rsa->dmq1, m, off) ||
!ASN1_bn_print(out, "coefficient:", rsa->iqmp, m, off)) {
goto err;
}

if (rsa->additional_primes != NULL &&
sk_RSA_additional_prime_num(rsa->additional_primes) > 0) {
size_t i;

if (BIO_printf(out, "otherPrimeInfos:\n") <= 0) {
goto err;
}
for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
i++) {
const RSA_additional_prime *ap =
sk_RSA_additional_prime_value(rsa->additional_primes, i);

if (BIO_printf(out, "otherPrimeInfo (prime %u):\n",
(unsigned)(i + 3)) <= 0 ||
!ASN1_bn_print(out, "prime:", ap->prime, m, off) ||
!ASN1_bn_print(out, "exponent:", ap->exp, m, off) ||
!ASN1_bn_print(out, "coeff:", ap->coeff, m, off)) {
goto err;
}
}
}
}
ret = 1;

err:
OPENSSL_free(m);
return ret;
}

static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
}

static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
}

static int old_rsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
int derlen) {
RSA *rsa = d2i_RSAPrivateKey(NULL, pder, derlen);
@@ -320,11 +193,9 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
rsa_pub_decode,
rsa_pub_encode,
rsa_pub_cmp,
rsa_pub_print,

rsa_priv_decode,
rsa_priv_encode,
rsa_priv_print,

rsa_opaque,
rsa_supports_digest,
@@ -332,7 +203,7 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
int_rsa_size,
rsa_bits,

0,0,0,0,
0,0,0,

int_rsa_free,



+ 474
- 0
crypto/evp/print.c Zobrazit soubor

@@ -0,0 +1,474 @@
/* ====================================================================
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. All advertising materials mentioning features or use of this
* software must display the following acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
*
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
* endorse or promote products derived from this software without
* prior written permission. For written permission, please contact
* licensing@OpenSSL.org.
*
* 5. Products derived from this software may not be called "OpenSSL"
* nor may "OpenSSL" appear in their names without prior written
* permission of the OpenSSL Project.
*
* 6. Redistributions of any form whatsoever must retain the following
* acknowledgment:
* "This product includes software developed by the OpenSSL Project
* for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
*
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
* EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*
* This product includes cryptographic software written by Eric Young
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */

#include <openssl/evp.h>

#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#include <openssl/ec_key.h>
#include <openssl/mem.h>
#include <openssl/rsa.h>

#include "../rsa/internal.h"


static void update_buflen(const BIGNUM *b, size_t *pbuflen) {
size_t i;

if (!b) {
return;
}

i = BN_num_bytes(b);
if (*pbuflen < i) {
*pbuflen = i;
}
}

/* RSA keys. */

static int do_rsa_print(BIO *out, const RSA *rsa, int off,
int include_private) {
char *str;
const char *s;
uint8_t *m = NULL;
int ret = 0, mod_len = 0;
size_t buf_len = 0;

update_buflen(rsa->n, &buf_len);
update_buflen(rsa->e, &buf_len);

if (include_private) {
update_buflen(rsa->d, &buf_len);
update_buflen(rsa->p, &buf_len);
update_buflen(rsa->q, &buf_len);
update_buflen(rsa->dmp1, &buf_len);
update_buflen(rsa->dmq1, &buf_len);
update_buflen(rsa->iqmp, &buf_len);

if (rsa->additional_primes != NULL) {
size_t i;

for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
i++) {
const RSA_additional_prime *ap =
sk_RSA_additional_prime_value(rsa->additional_primes, i);
update_buflen(ap->prime, &buf_len);
update_buflen(ap->exp, &buf_len);
update_buflen(ap->coeff, &buf_len);
}
}
}

m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
if (m == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}

if (rsa->n != NULL) {
mod_len = BN_num_bits(rsa->n);
}

if (!BIO_indent(out, off, 128)) {
goto err;
}

if (include_private && rsa->d) {
if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) {
goto err;
}
str = "modulus:";
s = "publicExponent:";
} else {
if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) {
goto err;
}
str = "Modulus:";
s = "Exponent:";
}
if (!ASN1_bn_print(out, str, rsa->n, m, off) ||
!ASN1_bn_print(out, s, rsa->e, m, off)) {
goto err;
}

if (include_private) {
if (!ASN1_bn_print(out, "privateExponent:", rsa->d, m, off) ||
!ASN1_bn_print(out, "prime1:", rsa->p, m, off) ||
!ASN1_bn_print(out, "prime2:", rsa->q, m, off) ||
!ASN1_bn_print(out, "exponent1:", rsa->dmp1, m, off) ||
!ASN1_bn_print(out, "exponent2:", rsa->dmq1, m, off) ||
!ASN1_bn_print(out, "coefficient:", rsa->iqmp, m, off)) {
goto err;
}

if (rsa->additional_primes != NULL &&
sk_RSA_additional_prime_num(rsa->additional_primes) > 0) {
size_t i;

if (BIO_printf(out, "otherPrimeInfos:\n") <= 0) {
goto err;
}
for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
i++) {
const RSA_additional_prime *ap =
sk_RSA_additional_prime_value(rsa->additional_primes, i);

if (BIO_printf(out, "otherPrimeInfo (prime %u):\n",
(unsigned)(i + 3)) <= 0 ||
!ASN1_bn_print(out, "prime:", ap->prime, m, off) ||
!ASN1_bn_print(out, "exponent:", ap->exp, m, off) ||
!ASN1_bn_print(out, "coeff:", ap->coeff, m, off)) {
goto err;
}
}
}
}
ret = 1;

err:
OPENSSL_free(m);
return ret;
}

static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_rsa_print(bp, pkey->pkey.rsa, indent, 0);
}

static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
}


/* DSA keys. */

static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
uint8_t *m = NULL;
int ret = 0;
size_t buf_len = 0;
const char *ktype = NULL;

const BIGNUM *priv_key, *pub_key;

priv_key = NULL;
if (ptype == 2) {
priv_key = x->priv_key;
}

pub_key = NULL;
if (ptype > 0) {
pub_key = x->pub_key;
}

ktype = "DSA-Parameters";
if (ptype == 2) {
ktype = "Private-Key";
} else if (ptype == 1) {
ktype = "Public-Key";
}

update_buflen(x->p, &buf_len);
update_buflen(x->q, &buf_len);
update_buflen(x->g, &buf_len);
update_buflen(priv_key, &buf_len);
update_buflen(pub_key, &buf_len);

m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
if (m == NULL) {
OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}

if (priv_key) {
if (!BIO_indent(bp, off, 128) ||
BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) {
goto err;
}
}

if (!ASN1_bn_print(bp, "priv:", priv_key, m, off) ||
!ASN1_bn_print(bp, "pub: ", pub_key, m, off) ||
!ASN1_bn_print(bp, "P: ", x->p, m, off) ||
!ASN1_bn_print(bp, "Q: ", x->q, m, off) ||
!ASN1_bn_print(bp, "G: ", x->g, m, off)) {
goto err;
}
ret = 1;

err:
OPENSSL_free(m);
return ret;
}

static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
}

static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
}

static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
}


/* EC keys. */

static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
uint8_t *buffer = NULL;
const char *ecstr;
size_t buf_len = 0, i;
int ret = 0, reason = ERR_R_BIO_LIB;
BIGNUM *order = NULL;
BN_CTX *ctx = NULL;
const EC_GROUP *group;
const EC_POINT *public_key;
const BIGNUM *priv_key;
uint8_t *pub_key_bytes = NULL;
size_t pub_key_bytes_len = 0;

if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) {
reason = ERR_R_PASSED_NULL_PARAMETER;
goto err;
}

ctx = BN_CTX_new();
if (ctx == NULL) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}

if (ktype > 0) {
public_key = EC_KEY_get0_public_key(x);
if (public_key != NULL) {
pub_key_bytes_len = EC_POINT_point2oct(
group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx);
if (pub_key_bytes_len == 0) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len);
if (pub_key_bytes == NULL) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
pub_key_bytes_len =
EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x),
pub_key_bytes, pub_key_bytes_len, ctx);
if (pub_key_bytes_len == 0) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
buf_len = pub_key_bytes_len;
}
}

if (ktype == 2) {
priv_key = EC_KEY_get0_private_key(x);
if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) {
buf_len = i;
}
} else {
priv_key = NULL;
}

if (ktype > 0) {
buf_len += 10;
if ((buffer = OPENSSL_malloc(buf_len)) == NULL) {
reason = ERR_R_MALLOC_FAILURE;
goto err;
}
}
if (ktype == 2) {
ecstr = "Private-Key";
} else if (ktype == 1) {
ecstr = "Public-Key";
} else {
ecstr = "ECDSA-Parameters";
}

if (!BIO_indent(bp, off, 128)) {
goto err;
}
order = BN_new();
if (order == NULL || !EC_GROUP_get_order(group, order, NULL) ||
BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) {
goto err;
}

if ((priv_key != NULL) &&
!ASN1_bn_print(bp, "priv:", priv_key, buffer, off)) {
goto err;
}
if (pub_key_bytes != NULL) {
BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off);
}
/* TODO(fork): implement */
/*
if (!ECPKParameters_print(bp, group, off))
goto err; */
ret = 1;

err:
if (!ret) {
OPENSSL_PUT_ERROR(EVP, reason);
}
OPENSSL_free(pub_key_bytes);
BN_free(order);
BN_CTX_free(ctx);
OPENSSL_free(buffer);
return ret;
}

static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0);
}

static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1);
}


static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *ctx) {
return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2);
}


typedef struct {
int type;
int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx);
int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx);
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx);
} EVP_PKEY_PRINT_METHOD;

static EVP_PKEY_PRINT_METHOD kPrintMethods[] = {
{
EVP_PKEY_RSA,
rsa_pub_print,
rsa_priv_print,
NULL /* param_print */,
},
{
EVP_PKEY_DSA,
dsa_pub_print,
dsa_priv_print,
dsa_param_print,
},
{
EVP_PKEY_EC,
eckey_pub_print,
eckey_priv_print,
eckey_param_print,
},
};

static size_t kPrintMethodsLen =
sizeof(kPrintMethods) / sizeof(kPrintMethods[0]);

static EVP_PKEY_PRINT_METHOD *find_method(int type) {
size_t i;
for (i = 0; i < kPrintMethodsLen; i++) {
if (kPrintMethods[i].type == type) {
return &kPrintMethods[i];
}
}
return NULL;
}

static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent,
const char *kstr) {
BIO_indent(out, indent, 128);
BIO_printf(out, "%s algorithm \"%s\" unsupported\n", kstr,
OBJ_nid2ln(pkey->type));
return 1;
}

int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx) {
EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
if (method != NULL && method->pub_print != NULL) {
return method->pub_print(out, pkey, indent, pctx);
}
return print_unsupported(out, pkey, indent, "Public Key");
}

int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx) {
EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
if (method != NULL && method->priv_print != NULL) {
return method->priv_print(out, pkey, indent, pctx);
}
return print_unsupported(out, pkey, indent, "Private Key");
}

int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent,
ASN1_PCTX *pctx) {
EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type);
if (method != NULL && method->param_print != NULL) {
return method->param_print(out, pkey, indent, pctx);
}
return print_unsupported(out, pkey, indent, "Parameters");
}

Načítá se…
Zrušit
Uložit