ENCODER: Refactor provider implementations, and some cleanup

The encoder implementations were implemented by unnecessarily copying
code into numerous topical source files, making them hard to maintain.
This changes merges all those into two source files, one that encodes
into DER and PEM, the other to text.

Diverse small cleanups are included.

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/12803)
This commit is contained in:
Richard Levitte 2020-09-07 12:25:17 +02:00
parent ce43db7a3f
commit 8ae40cf57d
37 changed files with 2239 additions and 5033 deletions

View File

@ -40,12 +40,7 @@ int OSSL_ENCODER_CTX_set_passphrase(OSSL_ENCODER_CTX *ctx,
const unsigned char *kstr,
size_t klen)
{
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
params[0] = OSSL_PARAM_construct_octet_string(OSSL_ENCODER_PARAM_PASS,
(void *)kstr, klen);
return OSSL_ENCODER_CTX_set_params(ctx, params);
return ossl_pw_set_passphrase(&ctx->pwdata, kstr, klen);
}
int OSSL_ENCODER_CTX_set_passphrase_ui(OSSL_ENCODER_CTX *ctx,

View File

@ -2934,6 +2934,7 @@ PROV_R_MODULE_INTEGRITY_FAILURE:214:module integrity failure
PROV_R_NOT_A_PRIVATE_KEY:221:not a private key
PROV_R_NOT_A_PUBLIC_KEY:220:not a public key
PROV_R_NOT_INSTANTIATED:193:not instantiated
PROV_R_NOT_PARAMETERS:224:not parameters
PROV_R_NOT_SUPPORTED:136:not supported
PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length
PROV_R_NO_KEY_SET:114:no key set

View File

@ -735,7 +735,7 @@ OSSL_CORE_MAKE_FUNC(int, encoder_encode_data,
(void *ctx, const OSSL_PARAM[], OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg))
OSSL_CORE_MAKE_FUNC(int, encoder_encode_object,
(void *ctx, void *obj, OSSL_CORE_BIO *out,
(void *ctx, const void *obj, OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg))
# define OSSL_FUNC_DECODER_NEWCTX 1

View File

@ -131,6 +131,7 @@ int ERR_load_PROV_strings(void);
# define PROV_R_NOT_A_PRIVATE_KEY 221
# define PROV_R_NOT_A_PUBLIC_KEY 220
# define PROV_R_NOT_INSTANTIATED 193
# define PROV_R_NOT_PARAMETERS 224
# define PROV_R_NOT_SUPPORTED 136
# define PROV_R_NOT_XOF_OR_INVALID_LENGTH 113
# define PROV_R_NO_KEY_SET 114

View File

@ -136,6 +136,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PRIVATE_KEY), "not a private key"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_A_PUBLIC_KEY), "not a public key"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_INSTANTIATED), "not instantiated"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_PARAMETERS), "not parameters"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_SUPPORTED), "not supported"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_XOF_OR_INVALID_LENGTH),
"not xof or invalid length"},

View File

@ -11,102 +11,161 @@
# error Macro ENCODER undefined
#endif
ENCODER("RSA", "yes", "text", "private", rsa_priv_text_encoder_functions),
ENCODER("RSA", "yes", "text", "public", rsa_pub_text_encoder_functions),
ENCODER("RSA", "yes", "der", "private", rsa_priv_der_encoder_functions),
ENCODER("RSA", "yes", "der", "public", rsa_pub_der_encoder_functions),
ENCODER("RSA", "yes", "pem", "private", rsa_priv_pem_encoder_functions),
ENCODER("RSA", "yes", "pem", "public", rsa_pub_pem_encoder_functions),
ENCODER("RSA", "yes", "text", "private",
rsa_priv_to_text_encoder_functions),
ENCODER("RSA", "yes", "text", "public",
rsa_pub_to_text_encoder_functions),
ENCODER("RSA", "yes", "der", "private",
rsa_priv_to_der_encoder_functions),
ENCODER("RSA", "yes", "der", "public",
rsa_pub_to_der_encoder_functions),
ENCODER("RSA", "yes", "pem", "private",
rsa_priv_to_pem_encoder_functions),
ENCODER("RSA", "yes", "pem", "public",
rsa_pub_to_pem_encoder_functions),
ENCODER("RSA-PSS", "yes", "text", "private",
rsa_priv_text_encoder_functions),
ENCODER("RSA-PSS", "yes", "text", "public", rsa_pub_text_encoder_functions),
ENCODER("RSA-PSS", "yes", "der", "private", rsa_priv_der_encoder_functions),
ENCODER("RSA-PSS", "yes", "der", "public", rsa_pub_der_encoder_functions),
ENCODER("RSA-PSS", "yes", "pem", "private", rsa_priv_pem_encoder_functions),
ENCODER("RSA-PSS", "yes", "pem", "public", rsa_pub_pem_encoder_functions),
rsa_priv_to_text_encoder_functions),
ENCODER("RSA-PSS", "yes", "text", "public",
rsa_pub_to_text_encoder_functions),
ENCODER("RSA-PSS", "yes", "der", "private",
rsa_priv_to_der_encoder_functions),
ENCODER("RSA-PSS", "yes", "der", "public",
rsa_pub_to_der_encoder_functions),
ENCODER("RSA-PSS", "yes", "pem", "private",
rsa_priv_to_pem_encoder_functions),
ENCODER("RSA-PSS", "yes", "pem", "public",
rsa_pub_to_pem_encoder_functions),
#ifndef OPENSSL_NO_DH
ENCODER("DH", "yes", "text", "private", dh_priv_text_encoder_functions),
ENCODER("DH", "yes", "text", "public", dh_pub_text_encoder_functions),
ENCODER("DH", "yes", "text", "parameters", dh_param_text_encoder_functions),
ENCODER("DH", "yes", "der", "private", dh_priv_der_encoder_functions),
ENCODER("DH", "yes", "der", "public", dh_pub_der_encoder_functions),
ENCODER("DH", "yes", "der", "parameters", dh_param_der_encoder_functions),
ENCODER("DH", "yes", "pem", "private", dh_priv_pem_encoder_functions),
ENCODER("DH", "yes", "pem", "public", dh_pub_pem_encoder_functions),
ENCODER("DH", "yes", "pem", "parameters", dh_param_pem_encoder_functions),
ENCODER("DH", "yes", "text", "private",
dh_priv_to_text_encoder_functions),
ENCODER("DH", "yes", "text", "public",
dh_pub_to_text_encoder_functions),
ENCODER("DH", "yes", "text", "parameters",
dh_param_to_text_encoder_functions),
ENCODER("DH", "yes", "der", "private",
dh_priv_to_der_encoder_functions),
ENCODER("DH", "yes", "der", "public",
dh_pub_to_der_encoder_functions),
ENCODER("DH", "yes", "der", "parameters",
dh_param_to_der_encoder_functions),
ENCODER("DH", "yes", "pem", "private",
dh_priv_to_pem_encoder_functions),
ENCODER("DH", "yes", "pem", "public",
dh_pub_to_pem_encoder_functions),
ENCODER("DH", "yes", "pem", "parameters",
dh_param_to_pem_encoder_functions),
ENCODER("DHX", "yes", "text", "private", dh_priv_text_encoder_functions),
ENCODER("DHX", "yes", "text", "public", dh_pub_text_encoder_functions),
ENCODER("DHX", "yes", "text", "parameters", dh_param_text_encoder_functions),
ENCODER("DHX", "yes", "der", "private", dh_priv_der_encoder_functions),
ENCODER("DHX", "yes", "der", "public", dh_pub_der_encoder_functions),
ENCODER("DHX", "yes", "der", "parameters", dh_param_der_encoder_functions),
ENCODER("DHX", "yes", "pem", "private", dh_priv_pem_encoder_functions),
ENCODER("DHX", "yes", "pem", "public", dh_pub_pem_encoder_functions),
ENCODER("DHX", "yes", "pem", "parameters", dh_param_pem_encoder_functions),
ENCODER("DHX", "yes", "text", "private",
dh_priv_to_text_encoder_functions),
ENCODER("DHX", "yes", "text", "public",
dh_pub_to_text_encoder_functions),
ENCODER("DHX", "yes", "text", "parameters",
dh_param_to_text_encoder_functions),
ENCODER("DHX", "yes", "der", "private",
dh_priv_to_der_encoder_functions),
ENCODER("DHX", "yes", "der", "public",
dh_pub_to_der_encoder_functions),
ENCODER("DHX", "yes", "der", "parameters",
dh_param_to_der_encoder_functions),
ENCODER("DHX", "yes", "pem", "private",
dh_priv_to_pem_encoder_functions),
ENCODER("DHX", "yes", "pem", "public",
dh_pub_to_pem_encoder_functions),
ENCODER("DHX", "yes", "pem", "parameters",
dh_param_to_pem_encoder_functions),
#endif
#ifndef OPENSSL_NO_DSA
ENCODER("DSA", "yes", "text", "private", dsa_priv_text_encoder_functions),
ENCODER("DSA", "yes", "text", "public", dsa_pub_text_encoder_functions),
ENCODER("DSA", "yes", "text", "private",
dsa_priv_to_text_encoder_functions),
ENCODER("DSA", "yes", "text", "public",
dsa_pub_to_text_encoder_functions),
ENCODER("DSA", "yes", "text", "parameters",
dsa_param_text_encoder_functions),
ENCODER("DSA", "yes", "der", "private", dsa_priv_der_encoder_functions),
ENCODER("DSA", "yes", "der", "public", dsa_pub_der_encoder_functions),
ENCODER("DSA", "yes", "der", "parameters", dsa_param_der_encoder_functions),
ENCODER("DSA", "yes", "pem", "private", dsa_priv_pem_encoder_functions),
ENCODER("DSA", "yes", "pem", "public", dsa_pub_pem_encoder_functions),
ENCODER("DSA", "yes", "pem", "parameters", dsa_param_pem_encoder_functions),
dsa_param_to_text_encoder_functions),
ENCODER("DSA", "yes", "der", "private",
dsa_priv_to_der_encoder_functions),
ENCODER("DSA", "yes", "der", "public",
dsa_pub_to_der_encoder_functions),
ENCODER("DSA", "yes", "der", "parameters",
dsa_param_to_der_encoder_functions),
ENCODER("DSA", "yes", "pem", "private",
dsa_priv_to_pem_encoder_functions),
ENCODER("DSA", "yes", "pem", "public",
dsa_pub_to_pem_encoder_functions),
ENCODER("DSA", "yes", "pem", "parameters",
dsa_param_to_pem_encoder_functions),
#endif
#ifndef OPENSSL_NO_EC
ENCODER("X25519", "yes", "text", "private",
x25519_priv_print_encoder_functions),
x25519_priv_to_text_encoder_functions),
ENCODER("X25519", "yes", "text", "public",
x25519_pub_print_encoder_functions),
x25519_pub_to_text_encoder_functions),
ENCODER("X25519", "yes", "der", "private",
x25519_priv_der_encoder_functions),
ENCODER("X25519", "yes", "der", "public", x25519_pub_der_encoder_functions),
x25519_priv_to_der_encoder_functions),
ENCODER("X25519", "yes", "der", "public",
x25519_pub_to_der_encoder_functions),
ENCODER("X25519", "yes", "pem", "private",
x25519_priv_pem_encoder_functions),
ENCODER("X25519", "yes", "pem", "public", x25519_pub_pem_encoder_functions),
x25519_priv_to_pem_encoder_functions),
ENCODER("X25519", "yes", "pem", "public",
x25519_pub_to_pem_encoder_functions),
ENCODER("X448", "no", "text", "private", x448_priv_print_encoder_functions),
ENCODER("X448", "no", "text", "public", x448_pub_print_encoder_functions),
ENCODER("X448", "no", "der", "private", x448_priv_der_encoder_functions),
ENCODER("X448", "no", "der", "public", x448_pub_der_encoder_functions),
ENCODER("X448", "no", "pem", "private", x448_priv_pem_encoder_functions),
ENCODER("X448", "no", "pem", "public", x448_pub_pem_encoder_functions),
ENCODER("X448", "yes", "text", "private",
x448_priv_to_text_encoder_functions),
ENCODER("X448", "yes", "text", "public",
x448_pub_to_text_encoder_functions),
ENCODER("X448", "yes", "der", "private",
x448_priv_to_der_encoder_functions),
ENCODER("X448", "yes", "der", "public",
x448_pub_to_der_encoder_functions),
ENCODER("X448", "yes", "pem", "private",
x448_priv_to_pem_encoder_functions),
ENCODER("X448", "yes", "pem", "public",
x448_pub_to_pem_encoder_functions),
ENCODER("ED25519", "yes", "text", "private",
ed25519_priv_print_encoder_functions),
ed25519_priv_to_text_encoder_functions),
ENCODER("ED25519", "yes", "text", "public",
ed25519_pub_print_encoder_functions),
ed25519_pub_to_text_encoder_functions),
ENCODER("ED25519", "yes", "der", "private",
ed25519_priv_der_encoder_functions),
ed25519_priv_to_der_encoder_functions),
ENCODER("ED25519", "yes", "der", "public",
ed25519_pub_der_encoder_functions),
ed25519_pub_to_der_encoder_functions),
ENCODER("ED25519", "yes", "pem", "private",
ed25519_priv_pem_encoder_functions),
ed25519_priv_to_pem_encoder_functions),
ENCODER("ED25519", "yes", "pem", "public",
ed25519_pub_pem_encoder_functions),
ed25519_pub_to_pem_encoder_functions),
ENCODER("ED448", "no", "text", "private",
ed448_priv_print_encoder_functions),
ENCODER("ED448", "no", "text", "public", ed448_pub_print_encoder_functions),
ENCODER("ED448", "no", "der", "private", ed448_priv_der_encoder_functions),
ENCODER("ED448", "no", "der", "public", ed448_pub_der_encoder_functions),
ENCODER("ED448", "no", "pem", "private", ed448_priv_pem_encoder_functions),
ENCODER("ED448", "no", "pem", "public", ed448_pub_pem_encoder_functions),
ENCODER("ED448", "yes", "text", "private",
ed448_priv_to_text_encoder_functions),
ENCODER("ED448", "yes", "text", "public",
ed448_pub_to_text_encoder_functions),
ENCODER("ED448", "yes", "der", "private",
ed448_priv_to_der_encoder_functions),
ENCODER("ED448", "yes", "der", "public",
ed448_pub_to_der_encoder_functions),
ENCODER("ED448", "yes", "pem", "private",
ed448_priv_to_pem_encoder_functions),
ENCODER("ED448", "yes", "pem", "public",
ed448_pub_to_pem_encoder_functions),
ENCODER("EC", "yes", "text", "private", ec_priv_text_encoder_functions),
ENCODER("EC", "yes", "text", "public", ec_pub_text_encoder_functions),
ENCODER("EC", "yes", "text", "parameters", ec_param_text_encoder_functions),
ENCODER("EC", "yes", "der", "private", ec_priv_der_encoder_functions),
ENCODER("EC", "yes", "der", "public", ec_pub_der_encoder_functions),
ENCODER("EC", "yes", "der", "parameters", ec_param_der_encoder_functions),
ENCODER("EC", "yes", "pem", "private", ec_priv_pem_encoder_functions),
ENCODER("EC", "yes", "pem", "public", ec_pub_pem_encoder_functions),
ENCODER("EC", "yes", "pem", "parameters", ec_param_pem_encoder_functions),
ENCODER("EC", "yes", "text", "private",
ec_priv_to_text_encoder_functions),
ENCODER("EC", "yes", "text", "public",
ec_pub_to_text_encoder_functions),
ENCODER("EC", "yes", "text", "parameters",
ec_param_to_text_encoder_functions),
ENCODER("EC", "yes", "der", "private",
ec_priv_to_der_encoder_functions),
ENCODER("EC", "yes", "der", "public",
ec_pub_to_der_encoder_functions),
ENCODER("EC", "yes", "der", "parameters",
ec_param_to_der_encoder_functions),
ENCODER("EC", "yes", "pem", "private",
ec_priv_to_pem_encoder_functions),
ENCODER("EC", "yes", "pem", "public",
ec_pub_to_pem_encoder_functions),
ENCODER("EC", "yes", "pem", "parameters",
ec_param_to_pem_encoder_functions),
#endif

View File

@ -10,26 +10,12 @@ $DSA_GOAL=../../libimplementations.a
$ECX_GOAL=../../libimplementations.a
$EC_GOAL=../../libimplementations.a
SOURCE[$ENCODER_GOAL]=encoder_common.c decode_common.c
SOURCE[$ENCODER_GOAL]=endecoder_common.c
SOURCE[$DECODER_GOAL]=decode_der2key.c decode_pem2der.c
IF[{- !$disabled{dsa} -}]
SOURCE[$DECODER_GOAL]=decode_ms2key.c
ENDIF
SOURCE[$RSA_GOAL]=encoder_rsa.c encoder_rsa_priv.c encoder_rsa_pub.c
DEPEND[encoder_rsa.o]=../../common/include/prov/der_rsa.h
IF[{- !$disabled{"dh"} || !$disabled{"dsa"} -}]
SOURCE[$FFC_GOAL]=encoder_ffc_params.c
ENDIF
IF[{- !$disabled{dh} -}]
SOURCE[$DH_GOAL]=encoder_dh.c encoder_dh_priv.c encoder_dh_pub.c encoder_dh_param.c
ENDIF
IF[{- !$disabled{dsa} -}]
SOURCE[$DSA_GOAL]=encoder_dsa.c encoder_dsa_priv.c encoder_dsa_pub.c encoder_dsa_param.c
ENDIF
IF[{- !$disabled{ec} -}]
SOURCE[$ECX_GOAL]=encoder_ecx.c encoder_ecx_priv.c encoder_ecx_pub.c
SOURCE[$EC_GOAL]=encoder_ec.c encoder_ec_priv.c encoder_ec_pub.c encoder_ec_param.c
ENDIF
SOURCE[$DECODER_GOAL]=encode_key2any.c encode_key2text.c
DEPEND[encode_key2any.o]=../../common/include/prov/der_rsa.h

View File

@ -1,116 +0,0 @@
/*
* Copyright 2020 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
*/
#include <openssl/core_names.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/buffer.h>
#include <openssl/pem.h> /* For public PEM and PVK functions */
#include <openssl/pkcs12.h>
#include "internal/pem.h" /* For internal PVK and "blob" functions */
#include "internal/cryptlib.h"
#include "internal/asn1.h"
#include "internal/passphrase.h"
#include "prov/bio.h" /* ossl_prov_bio_printf() */
#include "prov/providercommonerr.h" /* PROV_R_READ_KEY */
#include "encoder_local.h"
int ossl_prov_read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
unsigned char **data, long *len)
{
BUF_MEM *mem = NULL;
BIO *in = bio_new_from_core_bio(provctx, cin);
int ok = (asn1_d2i_read_bio(in, &mem) >= 0);
if (ok) {
*data = (unsigned char *)mem->data;
*len = (long)mem->length;
OPENSSL_free(mem);
}
BIO_free(in);
return ok;
}
int ossl_prov_read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
char **pem_name, char **pem_header,
unsigned char **data, long *len)
{
BIO *in = bio_new_from_core_bio(provctx, cin);
int ok = (PEM_read_bio(in, pem_name, pem_header, data, len) > 0);
BIO_free(in);
return ok;
}
#ifndef OPENSSL_NO_DSA
EVP_PKEY *ossl_prov_read_msblob(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
int *ispub)
{
BIO *in = bio_new_from_core_bio(provctx, cin);
EVP_PKEY *pkey = ossl_b2i_bio(in, ispub);
BIO_free(in);
return pkey;
}
# ifndef OPENSSL_NO_RC4
EVP_PKEY *ossl_prov_read_pvk(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
{
BIO *in = NULL;
EVP_PKEY *pkey = NULL;
struct ossl_passphrase_data_st pwdata;
memset(&pwdata, 0, sizeof(pwdata));
if (!ossl_pw_set_ossl_passphrase_cb(&pwdata, pw_cb, pw_cbarg))
return NULL;
in = bio_new_from_core_bio(provctx, cin);
pkey = b2i_PVK_bio(in, ossl_pw_pem_password, &pwdata);
BIO_free(in);
return pkey;
}
# endif
#endif
int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len,
unsigned char *input_der, long input_der_len,
OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
{
const unsigned char *derp;
X509_SIG *p8 = NULL;
int ok = 0;
if (!ossl_assert(new_der != NULL && *new_der == NULL)
|| !ossl_assert(new_der_len != NULL))
return 0;
derp = input_der;
if ((p8 = d2i_X509_SIG(NULL, &derp, input_der_len)) != NULL) {
char pbuf[PEM_BUFSIZE];
size_t plen = 0;
if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) {
ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY);
} else {
const X509_ALGOR *alg = NULL;
const ASN1_OCTET_STRING *oct = NULL;
int len = 0;
X509_SIG_get0(p8, &alg, &oct);
if (PKCS12_pbe_crypt(alg, pbuf, plen, oct->data, oct->length,
new_der, &len, 0) != NULL)
ok = 1;
*new_der_len = len;
}
}
X509_SIG_free(p8);
return ok;
}

View File

@ -17,13 +17,71 @@
#include <openssl/core_names.h>
#include <openssl/core_object.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/params.h>
#include <openssl/pem.h> /* PEM_BUFSIZE and public PEM functions */
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include "internal/cryptlib.h" /* ossl_assert() */
#include "internal/asn1.h"
#include "crypto/ecx.h"
#include "prov/bio.h"
#include "prov/implementations.h"
#include "encoder_local.h"
#include "prov/providercommonerr.h"
#include "endecoder_local.h"
static OSSL_FUNC_decoder_newctx_fn der2rsa_newctx;
static int read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
unsigned char **data, long *len)
{
BUF_MEM *mem = NULL;
BIO *in = bio_new_from_core_bio(provctx, cin);
int ok = (asn1_d2i_read_bio(in, &mem) >= 0);
if (ok) {
*data = (unsigned char *)mem->data;
*len = (long)mem->length;
OPENSSL_free(mem);
}
BIO_free(in);
return ok;
}
static int der_from_p8(unsigned char **new_der, long *new_der_len,
unsigned char *input_der, long input_der_len,
OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
{
const unsigned char *derp;
X509_SIG *p8 = NULL;
int ok = 0;
if (!ossl_assert(new_der != NULL && *new_der == NULL)
|| !ossl_assert(new_der_len != NULL))
return 0;
derp = input_der;
if ((p8 = d2i_X509_SIG(NULL, &derp, input_der_len)) != NULL) {
char pbuf[PEM_BUFSIZE];
size_t plen = 0;
if (!pw_cb(pbuf, sizeof(pbuf), &plen, NULL, pw_cbarg)) {
ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY);
} else {
const X509_ALGOR *alg = NULL;
const ASN1_OCTET_STRING *oct = NULL;
int len = 0;
X509_SIG_get0(p8, &alg, &oct);
if (PKCS12_pbe_crypt(alg, pbuf, plen, oct->data, oct->length,
new_der, &len, 0) != NULL)
ok = 1;
*new_der_len = len;
}
}
X509_SIG_free(p8);
return ok;
}
/* ---------------------------------------------------------------------- */
static OSSL_FUNC_decoder_freectx_fn der2key_freectx;
static OSSL_FUNC_decoder_gettable_params_fn der2key_gettable_params;
@ -109,15 +167,14 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin,
void *key = NULL;
int ok = 0;
if (!ossl_prov_read_der(ctx->provctx, cin, &der, &der_len))
if (!read_der(ctx->provctx, cin, &der, &der_len))
return 0;
/*
* Opportunistic attempt to decrypt. If it doesn't work, we try to
* decode our input unencrypted.
*/
if (ossl_prov_der_from_p8(&new_der, &new_der_len, der, der_len,
pw_cb, pw_cbarg)) {
if (der_from_p8(&new_der, &new_der_len, der, der_len, pw_cb, pw_cbarg)) {
OPENSSL_free(der);
der = new_der;
der_len = new_der_len;
@ -203,6 +260,7 @@ static int der2key_export_object(void *vctx,
{ EVP_PKEY_##KEYTYPE, KEYTYPEstr, keytype##_keymgmt_functions, \
(extract_key_fn *)extract, \
(free_key_fn *)free }; \
static OSSL_FUNC_decoder_newctx_fn der2##keytype##_newctx; \
static void *der2##keytype##_newctx(void *provctx) \
{ \
return der2key_newctx(provctx, &keytype##_desc); \

View File

@ -13,16 +13,51 @@
*/
#include "internal/deprecated.h"
#include <string.h>
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/core_object.h>
#include <openssl/crypto.h>
#include <openssl/params.h>
#include <openssl/pem.h> /* For public PVK functions */
#include <openssl/x509.h>
#include "internal/pem.h" /* For PVK and "blob" PEM headers */
#include "internal/pem.h" /* For internal PVK and "blob" headers */
#include "internal/passphrase.h"
#include "prov/bio.h"
#include "prov/implementations.h"
#include "encoder_local.h"
#include "endecoder_local.h"
#ifndef OPENSSL_NO_DSA
static EVP_PKEY *read_msblob(PROV_CTX *provctx, OSSL_CORE_BIO *cin, int *ispub)
{
BIO *in = bio_new_from_core_bio(provctx, cin);
EVP_PKEY *pkey = ossl_b2i_bio(in, ispub);
BIO_free(in);
return pkey;
}
# ifndef OPENSSL_NO_RC4
static EVP_PKEY *read_pvk(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
{
BIO *in = NULL;
EVP_PKEY *pkey = NULL;
struct ossl_passphrase_data_st pwdata;
memset(&pwdata, 0, sizeof(pwdata));
if (!ossl_pw_set_ossl_passphrase_cb(&pwdata, pw_cb, pw_cbarg))
return NULL;
in = bio_new_from_core_bio(provctx, cin);
pkey = b2i_PVK_bio(in, ossl_pw_pem_password, &pwdata);
BIO_free(in);
return pkey;
}
# endif
#endif
static OSSL_FUNC_decoder_freectx_fn ms2key_freectx;
static OSSL_FUNC_decoder_gettable_params_fn ms2key_gettable_params;
@ -159,7 +194,7 @@ static int msblob2key_decode(void *vctx, OSSL_CORE_BIO *cin,
{
struct ms2key_ctx_st *ctx = vctx;
int ispub = -1;
EVP_PKEY *pkey = ossl_prov_read_msblob(ctx->provctx, cin, &ispub);
EVP_PKEY *pkey = read_msblob(ctx->provctx, cin, &ispub);
int ok = ms2key_post(ctx, pkey, data_cb, data_cbarg);
EVP_PKEY_free(pkey);
@ -172,7 +207,7 @@ static int pvk2key_decode(void *vctx, OSSL_CORE_BIO *cin,
OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
{
struct ms2key_ctx_st *ctx = vctx;
EVP_PKEY *pkey = ossl_prov_read_pvk(ctx->provctx, cin, pw_cb, pw_cbarg);
EVP_PKEY *pkey = read_pvk(ctx->provctx, cin, pw_cb, pw_cbarg);
int ok = ms2key_post(ctx, pkey, data_cb, data_cbarg);
EVP_PKEY_free(pkey);

View File

@ -24,7 +24,18 @@
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/providercommonerr.h"
#include "encoder_local.h"
#include "endecoder_local.h"
static int read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
char **pem_name, char **pem_header,
unsigned char **data, long *len)
{
BIO *in = bio_new_from_core_bio(provctx, cin);
int ok = (PEM_read_bio(in, pem_name, pem_header, data, len) > 0);
BIO_free(in);
return ok;
}
static OSSL_FUNC_decoder_newctx_fn pem2der_newctx;
static OSSL_FUNC_decoder_freectx_fn pem2der_freectx;
@ -104,8 +115,8 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin,
long der_len = 0;
int ok = 0;
if (ossl_prov_read_pem(ctx->provctx, cin, &pem_name, &pem_header,
&der, &der_len) <= 0)
if (read_pem(ctx->provctx, cin, &pem_name, &pem_header,
&der, &der_len) <= 0)
return 0;
/*

View File

@ -0,0 +1,924 @@
/*
* Copyright 2020 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 <openssl/core.h>
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/crypto.h>
#include <openssl/params.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/pkcs12.h> /* PKCS8_encrypt() */
#include <openssl/dh.h>
#include <openssl/dsa.h>
#include <openssl/ec.h>
#include "internal/passphrase.h"
#include "internal/cryptlib.h"
#include "crypto/ecx.h"
#include "crypto/rsa.h"
#include "prov/implementations.h"
#include "prov/providercommonerr.h"
#include "prov/bio.h"
#include "prov/provider_ctx.h"
#include "prov/der_rsa.h"
#include "endecoder_local.h"
struct key2any_ctx_st {
PROV_CTX *provctx;
/* Set to 1 if intending to encrypt/decrypt, otherwise 0 */
int cipher_intent;
EVP_CIPHER *cipher;
struct ossl_passphrase_data_st pwdata;
};
typedef int key_to_paramstring_fn(const void *key, int nid,
void **str, int *strtype);
typedef int key_to_der_fn(BIO *out, const void *key, int key_nid,
key_to_paramstring_fn *p2s, i2d_of_void *k2d,
struct key2any_ctx_st *ctx);
typedef int write_bio_of_void_fn(BIO *bp, const void *x);
static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid,
void *params, int params_type,
i2d_of_void *k2d)
{
/* der, derlen store the key DER output and its length */
unsigned char *der = NULL;
int derlen;
/* The final PKCS#8 info */
PKCS8_PRIV_KEY_INFO *p8info = NULL;
if ((p8info = PKCS8_PRIV_KEY_INFO_new()) == NULL
|| (derlen = k2d(key, &der)) <= 0
|| !PKCS8_pkey_set0(p8info, OBJ_nid2obj(key_nid), 0,
params_type, params, der, derlen)) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
PKCS8_PRIV_KEY_INFO_free(p8info);
OPENSSL_free(der);
p8info = NULL;
}
return p8info;
}
static X509_SIG *p8info_to_encp8(PKCS8_PRIV_KEY_INFO *p8info,
struct key2any_ctx_st *ctx)
{
X509_SIG *p8 = NULL;
char kstr[PEM_BUFSIZE];
size_t klen = 0;
if (ctx->cipher == NULL)
return NULL;
if (!ossl_pw_get_passphrase(kstr, sizeof(kstr), &klen, NULL, 1,
&ctx->pwdata)) {
ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY);
return NULL;
}
/* First argument == -1 means "standard" */
p8 = PKCS8_encrypt(-1, ctx->cipher, kstr, klen, NULL, 0, 0, p8info);
OPENSSL_cleanse(kstr, klen);
return p8;
}
static X509_SIG *key_to_encp8(const void *key, int key_nid,
void *params, int params_type,
i2d_of_void *k2d, struct key2any_ctx_st *ctx)
{
PKCS8_PRIV_KEY_INFO *p8info =
key_to_p8info(key, key_nid, params, params_type, k2d);
X509_SIG *p8 = p8info_to_encp8(p8info, ctx);
PKCS8_PRIV_KEY_INFO_free(p8info);
return p8;
}
static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid,
void *params, int params_type,
i2d_of_void k2d)
{
/* der, derlen store the key DER output and its length */
unsigned char *der = NULL;
int derlen;
/* The final X509_PUBKEY */
X509_PUBKEY *xpk = NULL;
if ((xpk = X509_PUBKEY_new()) == NULL
|| (derlen = k2d(key, &der)) <= 0
|| !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(key_nid),
params_type, params, der, derlen)) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
X509_PUBKEY_free(xpk);
OPENSSL_free(der);
xpk = NULL;
}
return xpk;
}
static int key_to_der_pkcs8_bio(BIO *out, const void *key, int key_nid,
key_to_paramstring_fn *p2s, i2d_of_void *k2d,
struct key2any_ctx_st *ctx)
{
int ret = 0;
void *str = NULL;
int strtype = V_ASN1_UNDEF;
if (p2s != NULL && !p2s(key, key_nid, &str, &strtype))
return 0;
if (ctx->cipher_intent) {
X509_SIG *p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx);
if (p8 != NULL)
ret = i2d_PKCS8_bio(out, p8);
X509_SIG_free(p8);
} else {
PKCS8_PRIV_KEY_INFO *p8info =
key_to_p8info(key, key_nid, str, strtype, k2d);
if (p8info != NULL)
ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info);
PKCS8_PRIV_KEY_INFO_free(p8info);
}
return ret;
}
static int key_to_pem_pkcs8_bio(BIO *out, const void *key, int key_nid,
key_to_paramstring_fn *p2s, i2d_of_void *k2d,
struct key2any_ctx_st *ctx)
{
int ret = 0;
void *str = NULL;
int strtype = V_ASN1_UNDEF;
if (p2s != NULL && !p2s(key, key_nid, &str, &strtype))
return 0;
if (ctx->cipher_intent) {
X509_SIG *p8 = key_to_encp8(key, key_nid, str, strtype, k2d, ctx);
if (p8 != NULL)
ret = PEM_write_bio_PKCS8(out, p8);
X509_SIG_free(p8);
} else {
PKCS8_PRIV_KEY_INFO *p8info =
key_to_p8info(key, key_nid, str, strtype, k2d);
if (p8info != NULL)
ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info);
PKCS8_PRIV_KEY_INFO_free(p8info);
}
return ret;
}
static int key_to_der_pubkey_bio(BIO *out, const void *key, int key_nid,
key_to_paramstring_fn *p2s, i2d_of_void *k2d,
struct key2any_ctx_st *ctx)
{
int ret = 0;
void *str = NULL;
int strtype = V_ASN1_UNDEF;
X509_PUBKEY *xpk = NULL;
if (p2s != NULL && !p2s(key, key_nid, &str, &strtype))
return 0;
xpk = key_to_pubkey(key, key_nid, str, strtype, k2d);
if (xpk != NULL)
ret = i2d_X509_PUBKEY_bio(out, xpk);
/* Also frees |str| */
X509_PUBKEY_free(xpk);
return ret;
}
static int key_to_pem_pubkey_bio(BIO *out, const void *key, int key_nid,
key_to_paramstring_fn *p2s, i2d_of_void *k2d,
struct key2any_ctx_st *ctx)
{
int ret = 0;
void *str = NULL;
int strtype = V_ASN1_UNDEF;
X509_PUBKEY *xpk = NULL;
if (p2s != NULL && !p2s(key, key_nid, &str, &strtype))
return 0;
xpk = key_to_pubkey(key, key_nid, str, strtype, k2d);
if (xpk != NULL)
ret = PEM_write_bio_X509_PUBKEY(out, xpk);
/* Also frees |str| */
X509_PUBKEY_free(xpk);
return ret;
}
/* ---------------------------------------------------------------------- */
#ifndef OPENSSL_NO_DH
# define dh_param_selection OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
# define dh_pub_selection (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
| dh_param_selection)
# define dh_priv_selection (OSSL_KEYMGMT_SELECT_KEYPAIR \
| dh_param_selection)
static int dh_type_to_evp(const DH *dh)
{
return DH_test_flags(dh, DH_FLAG_TYPE_DHX) ? EVP_PKEY_DHX : EVP_PKEY_DH;
}
static int prepare_dh_params(const void *dh, int nid,
void **pstr, int *pstrtype)
{
ASN1_STRING *params = ASN1_STRING_new();
if (params == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return 0;
}
if (nid == EVP_PKEY_DHX)
params->length = i2d_DHxparams(dh, &params->data);
else
params->length = i2d_DHparams(dh, &params->data);
if (params->length <= 0) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
ASN1_STRING_free(params);
return 0;
}
params->type = V_ASN1_SEQUENCE;
*pstr = params;
*pstrtype = V_ASN1_SEQUENCE;
return 1;
}
static int dh_pub_to_der(const void *dh, unsigned char **pder)
{
const BIGNUM *bn = NULL;
ASN1_INTEGER *pub_key = NULL;
int ret;
if ((bn = DH_get0_pub_key(dh)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
return 0;
}
if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
return 0;
}
ret = i2d_ASN1_INTEGER(pub_key, pder);
ASN1_STRING_clear_free(pub_key);
return ret;
}
static int dh_priv_to_der(const void *dh, unsigned char **pder)
{
const BIGNUM *bn = NULL;
ASN1_INTEGER *priv_key = NULL;
int ret;
if ((bn = DH_get0_priv_key(dh)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
return 0;
}
if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
return 0;
}
ret = i2d_ASN1_INTEGER(priv_key, pder);
ASN1_STRING_clear_free(priv_key);
return ret;
}
static int dh_params_to_der_bio(BIO *out, const void *key)
{
return i2d_DHparams_bio(out, key);
}
static int dh_params_to_pem_bio(BIO *out, const void *key)
{
return PEM_write_bio_DHparams(out, key);
}
#endif
/* ---------------------------------------------------------------------- */
#ifndef OPENSSL_NO_DSA
# define dsa_param_selection OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
# define dsa_pub_selection (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
| dsa_param_selection)
# define dsa_priv_selection (OSSL_KEYMGMT_SELECT_KEYPAIR \
| dsa_param_selection)
# define dsa_type_to_evp(key) EVP_PKEY_DSA
static int prepare_some_dsa_params(const void *dsa, int nid,
void **pstr, int *pstrtype)
{
ASN1_STRING *params = ASN1_STRING_new();
if (params == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return 0;
}
params->length = i2d_DSAparams(dsa, &params->data);
if (params->length <= 0) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
ASN1_STRING_free(params);
return 0;
}
*pstrtype = V_ASN1_SEQUENCE;
*pstr = params;
return 1;
}
static int prepare_all_dsa_params(const void *dsa, int nid,
void **pstr, int *pstrtype)
{
const BIGNUM *p = DSA_get0_p(dsa);
const BIGNUM *q = DSA_get0_q(dsa);
const BIGNUM *g = DSA_get0_g(dsa);
if (p != NULL && q != NULL && g != NULL)
return prepare_some_dsa_params(dsa, nid, pstr, pstrtype);
*pstr = NULL;
*pstrtype = V_ASN1_UNDEF;
return 1;
}
static int prepare_dsa_params(const void *dsa, int nid,
void **pstr, int *pstrtype)
{
/*
* TODO(v3.0) implement setting save_parameters, see dsa_pub_encode()
* in crypto/dsa/dsa_ameth.c
*/
int save_parameters = 1;
return save_parameters
? prepare_all_dsa_params(dsa, nid, pstr, pstrtype)
: prepare_some_dsa_params(dsa, nid, pstr, pstrtype);
}
static int dsa_pub_to_der(const void *dsa, unsigned char **pder)
{
const BIGNUM *bn = NULL;
ASN1_INTEGER *pub_key = NULL;
int ret;
if ((bn = DSA_get0_pub_key(dsa)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
return 0;
}
if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
return 0;
}
ret = i2d_ASN1_INTEGER(pub_key, pder);
ASN1_STRING_clear_free(pub_key);
return ret;
}
static int dsa_priv_to_der(const void *dsa, unsigned char **pder)
{
const BIGNUM *bn = NULL;
ASN1_INTEGER *priv_key = NULL;
int ret;
if ((bn = DSA_get0_priv_key(dsa)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
return 0;
}
if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
return 0;
}
ret = i2d_ASN1_INTEGER(priv_key, pder);
ASN1_STRING_clear_free(priv_key);
return ret;
}
static int dsa_params_to_der_bio(BIO *out, const void *key)
{
return i2d_DSAparams_bio(out, key);
}
static int dsa_params_to_pem_bio(BIO *out, const void *key)
{
return PEM_write_bio_DSAparams(out, key);
}
#endif
/* ---------------------------------------------------------------------- */
#ifndef OPENSSL_NO_EC
# define ec_param_selection OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
# define ec_pub_selection (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
| ec_param_selection)
# define ec_priv_selection (OSSL_KEYMGMT_SELECT_KEYPAIR \
| ec_param_selection)
# define ec_type_to_evp(key) EVP_PKEY_EC
static int prepare_ec_explicit_params(const void *eckey,
void **pstr, int *pstrtype)
{
ASN1_STRING *params = ASN1_STRING_new();
if (params == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return 0;
}
params->length = i2d_ECParameters(eckey, &params->data);
if (params->length <= 0) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
ASN1_STRING_free(params);
return 0;
}
*pstrtype = V_ASN1_SEQUENCE;
*pstr = params;
return 1;
}
static int prepare_ec_params(const void *eckey, int nid,
void **pstr, int *pstrtype)
{
int curve_nid;
const EC_GROUP *group = EC_KEY_get0_group(eckey);
ASN1_OBJECT *params = NULL;
if (group == NULL)
return 0;
curve_nid = EC_GROUP_get_curve_name(group);
if (curve_nid != NID_undef) {
params = OBJ_nid2obj(curve_nid);
if (params == NULL)
return 0;
}
if (curve_nid != NID_undef
&& (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE)) {
if (OBJ_length(params) == 0) {
/* Some curves might not have an associated OID */
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_OID);
ASN1_OBJECT_free(params);
return 0;
}
*pstr = params;
*pstrtype = V_ASN1_OBJECT;
return 1;
} else {
return prepare_ec_explicit_params(eckey, pstr, pstrtype);
}
}
static int ec_params_to_der_bio(BIO *out, const void *eckey)
{
return i2d_ECPKParameters_bio(out, EC_KEY_get0_group(eckey));
}
static int ec_params_to_pem_bio(BIO *out, const void *eckey)
{
return PEM_write_bio_ECPKParameters(out, EC_KEY_get0_group(eckey));
}
static int ec_pub_to_der(const void *eckey, unsigned char **pder)
{
return i2o_ECPublicKey(eckey, pder);
}
static int ec_priv_to_der(const void *veckey, unsigned char **pder)
{
EC_KEY *eckey = (EC_KEY *)veckey;
unsigned int old_flags;
int ret = 0;
/*
* For PKCS8 the curve name appears in the PKCS8_PRIV_KEY_INFO object
* as the pkeyalg->parameter field. (For a named curve this is an OID)
* The pkey field is an octet string that holds the encoded
* ECPrivateKey SEQUENCE with the optional parameters field omitted.
* We omit this by setting the EC_PKEY_NO_PARAMETERS flag.
*/
old_flags = EC_KEY_get_enc_flags(eckey); /* save old flags */
EC_KEY_set_enc_flags(eckey, old_flags | EC_PKEY_NO_PARAMETERS);
ret = i2d_ECPrivateKey(eckey, pder);
EC_KEY_set_enc_flags(eckey, old_flags); /* restore old flags */
return ret; /* return the length of the der encoded data */
}
#endif
/* ---------------------------------------------------------------------- */
#ifndef OPENSSL_NO_EC
# define ecx_pub_selection OSSL_KEYMGMT_SELECT_PUBLIC_KEY
# define ecx_priv_selection OSSL_KEYMGMT_SELECT_KEYPAIR
# define ed25519_type_to_evp(key) EVP_PKEY_ED25519
# define ed448_type_to_evp(key) EVP_PKEY_ED448
# define x25519_type_to_evp(key) EVP_PKEY_X25519
# define x448_type_to_evp(key) EVP_PKEY_X448
# define prepare_ecx_params NULL
static int ecx_pub_to_der(const void *vecxkey, unsigned char **pder)
{
const ECX_KEY *ecxkey = vecxkey;
unsigned char *keyblob;
if (ecxkey == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
keyblob = OPENSSL_memdup(ecxkey->pubkey, ecxkey->keylen);
if (keyblob == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return 0;
}
*pder = keyblob;
return ecxkey->keylen;
}
static int ecx_priv_to_der(const void *vecxkey, unsigned char **pder)
{
const ECX_KEY *ecxkey = vecxkey;
ASN1_OCTET_STRING oct;
int keybloblen;
if (ecxkey == NULL || ecxkey->privkey == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
oct.data = ecxkey->privkey;
oct.length = ecxkey->keylen;
oct.flags = 0;
keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder);
if (keybloblen < 0) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return 0;
}
return keybloblen;
}
# define ecx_params_to_der_bio NULL
# define ecx_params_to_pem_bio NULL
#endif
/* ---------------------------------------------------------------------- */
#define rsa_param_selection OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS
#define rsa_pub_selection (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
| rsa_param_selection)
#define rsa_priv_selection (OSSL_KEYMGMT_SELECT_KEYPAIR \
| rsa_param_selection)
static int rsa_type_to_evp(const RSA *rsa)
{
switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
case RSA_FLAG_TYPE_RSA:
return EVP_PKEY_RSA;
case RSA_FLAG_TYPE_RSASSAPSS:
return EVP_PKEY_RSA_PSS;
}
/* Currently unsupported RSA key type */
return EVP_PKEY_NONE;
}
/*
* Helper functions to prepare RSA-PSS params for encoding. We would
* have simply written the whole AlgorithmIdentifier, but existing libcrypto
* functionality doesn't allow that.
*/
static int prepare_rsa_params(const void *rsa, int nid,
void **pstr, int *pstrtype)
{
const RSA_PSS_PARAMS_30 *pss = rsa_get0_pss_params_30((RSA *)rsa);
*pstr = NULL;
switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
case RSA_FLAG_TYPE_RSA:
/* If plain RSA, the parameters shall be NULL */
*pstrtype = V_ASN1_NULL;
return 1;
case RSA_FLAG_TYPE_RSASSAPSS:
if (rsa_pss_params_30_is_unrestricted(pss)) {
*pstrtype = V_ASN1_UNDEF;
return 1;
} else {
ASN1_STRING *astr = NULL;
WPACKET pkt;
unsigned char *str = NULL;
size_t str_sz = 0;
int i;
for (i = 0; i < 2; i++) {
switch (i) {
case 0:
if (!WPACKET_init_null_der(&pkt))
goto err;
break;
case 1:
if ((str = OPENSSL_malloc(str_sz)) == NULL
|| !WPACKET_init_der(&pkt, str, str_sz)) {
goto err;
}
break;
}
if (!DER_w_RSASSA_PSS_params(&pkt, -1, pss)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &str_sz))
goto err;
WPACKET_cleanup(&pkt);
/*
* If no PSS parameters are going to be written, there's no
* point going for another iteration.
* This saves us from getting |str| allocated just to have it
* immediately de-allocated.
*/
if (str_sz == 0)
break;
}
if ((astr = ASN1_STRING_new()) == NULL)
goto err;
*pstrtype = V_ASN1_SEQUENCE;
ASN1_STRING_set0(astr, str, (int)str_sz);
*pstr = astr;
return 1;
err:
OPENSSL_free(str);
return 0;
}
}
/* Currently unsupported RSA key type */
return 0;
}
#define rsa_params_to_der_bio NULL
#define rsa_params_to_pem_bio NULL
#define rsa_priv_to_der (i2d_of_void *)i2d_RSAPrivateKey
#define rsa_pub_to_der (i2d_of_void *)i2d_RSAPublicKey
/* ---------------------------------------------------------------------- */
static OSSL_FUNC_decoder_newctx_fn key2any_newctx;
static OSSL_FUNC_decoder_freectx_fn key2any_freectx;
static void *key2any_newctx(void *provctx)
{
struct key2any_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx != NULL)
ctx->provctx = provctx;
return ctx;
}
static void key2any_freectx(void *vctx)
{
struct key2any_ctx_st *ctx = vctx;
ossl_pw_clear_passphrase_data(&ctx->pwdata);
EVP_CIPHER_free(ctx->cipher);
OPENSSL_free(ctx);
}
static const OSSL_PARAM *key2any_settable_ctx_params(ossl_unused void *provctx)
{
static const OSSL_PARAM settables[] = {
OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_PROPERTIES, NULL, 0),
OSSL_PARAM_END,
};
return settables;
}
static int key2any_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
struct key2any_ctx_st *ctx = vctx;
OPENSSL_CTX *libctx = PROV_CTX_get0_library_context(ctx->provctx);
const OSSL_PARAM *cipherp =
OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER);
const OSSL_PARAM *propsp =
OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
if (cipherp != NULL) {
const char *ciphername = NULL;
const char *props = NULL;
if (!OSSL_PARAM_get_utf8_string_ptr(cipherp, &ciphername))
return 0;
if (propsp != NULL && !OSSL_PARAM_get_utf8_string_ptr(propsp, &props))
return 0;
EVP_CIPHER_free(ctx->cipher);
ctx->cipher_intent = ciphername != NULL;
if (ciphername != NULL
&& ((ctx->cipher =
EVP_CIPHER_fetch(libctx, ciphername, props)) == NULL))
return 0;
}
return 1;
}
static int key2any_encode(struct key2any_ctx_st *ctx,
const void *key, int type,
OSSL_CORE_BIO *cout, key_to_der_fn *writer,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg,
key_to_paramstring_fn *key2paramstring,
i2d_of_void *key2der)
{
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
int ret = 0;
if (out != NULL
&& writer != NULL
&& ossl_pw_set_ossl_passphrase_cb(&ctx->pwdata, cb, cbarg))
ret = writer(out, key, type, key2paramstring, key2der, ctx);
BIO_free(out);
return ret;
}
static int key2any_encode_params(struct key2any_ctx_st *ctx, const void *key,
OSSL_CORE_BIO *cout,
write_bio_of_void_fn *writer)
{
int ret = 0;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
if (out != NULL && writer != NULL)
ret = writer(out, key);
BIO_free(out);
return ret;
}
#define ALLOWED_SELECTORS \
(OSSL_KEYMGMT_SELECT_ALL_PARAMETERS | OSSL_KEYMGMT_SELECT_KEYPAIR)
#define MAKE_ENCODER_KIND(impl, kind, type, evp_type, output) \
static OSSL_FUNC_encoder_encode_data_fn \
impl##_##kind##2##output##_encode_d; \
static OSSL_FUNC_encoder_encode_object_fn \
impl##_##kind##2##output##_encode_o; \
static int \
impl##_##kind##2##output##_encode_d(void *vctx, \
const OSSL_PARAM params[], \
OSSL_CORE_BIO *cout, \
OSSL_PASSPHRASE_CALLBACK *cb, \
void *cbarg) \
{ \
struct key2any_ctx_st *ctx = vctx; \
int selection = type##_##kind##_selection; \
void *key = ossl_prov_import_key(impl##_keymgmt_functions, \
ctx->provctx, selection, \
params); \
int ret; \
\
if (key == NULL) \
return 0; \
\
ret = impl##_##kind##2##output##_encode_o(ctx, key, cout, \
cb, cbarg); \
ossl_prov_free_key(impl##_keymgmt_functions, key); \
return ret; \
} \
static int \
impl##_##kind##2##output##_encode_o(void *vctx, const void *key, \
OSSL_CORE_BIO *cout, \
OSSL_PASSPHRASE_CALLBACK *cb, \
void *cbarg) \
{ \
int selection = type##_##kind##_selection; \
\
if (!ossl_assert(selection != 0) \
|| !ossl_assert((selection & ~ALLOWED_SELECTORS) == 0)) { \
ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); \
return 0; \
} \
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) \
return key2any_encode(vctx, key, impl##_type_to_evp(key), \
cout, key_to_##output##_pkcs8_bio, \
cb, cbarg, \
prepare_##type##_params, \
type##_priv_to_der); \
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) \
return key2any_encode(vctx, key, impl##_type_to_evp(key), \
cout, key_to_##output##_pubkey_bio, \
cb, cbarg, \
prepare_##type##_params, \
type##_pub_to_der); \
return key2any_encode_params(vctx, key, cout, \
type##_params_to_##output##_bio); \
} \
const OSSL_DISPATCH \
impl##_##kind##_to_##output##_encoder_functions[] = { \
{ OSSL_FUNC_ENCODER_NEWCTX, \
(void (*)(void))key2any_newctx }, \
{ OSSL_FUNC_ENCODER_FREECTX, \
(void (*)(void))key2any_freectx }, \
{ OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS, \
(void (*)(void))key2any_settable_ctx_params }, \
{ OSSL_FUNC_ENCODER_SET_CTX_PARAMS, \
(void (*)(void))key2any_set_ctx_params }, \
{ OSSL_FUNC_ENCODER_ENCODE_DATA, \
(void (*)(void))impl##_##kind##2##output##_encode_d }, \
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, \
(void (*)(void))impl##_##kind##2##output##_encode_o }, \
{ 0, NULL } \
}
#define MAKE_ENCODER(impl, type, evp_type, output) \
MAKE_ENCODER_KIND(impl, param, type, evp_type, output); \
MAKE_ENCODER_KIND(impl, pub, type, evp_type, output); \
MAKE_ENCODER_KIND(impl, priv, type, evp_type, output)
#define MAKE_ENCODER_NOPARAM(impl, type, evp_type, output) \
MAKE_ENCODER_KIND(impl, pub, type, evp_type, output); \
MAKE_ENCODER_KIND(impl, priv, type, evp_type, output)
#ifndef OPENSSL_NO_DH
MAKE_ENCODER(dh, dh, EVP_PKEY_DH, der);
MAKE_ENCODER(dh, dh, EVP_PKEY_DH, pem);
#endif
#ifndef OPENSSL_NO_DSA
MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, der);
MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, pem);
#endif
#ifndef OPENSSL_NO_EC
MAKE_ENCODER(ec, ec, EVP_PKEY_EC, der);
MAKE_ENCODER(ec, ec, EVP_PKEY_EC, pem);
MAKE_ENCODER_NOPARAM(ed25519, ecx, EVP_PKEY_ED25519, der);
MAKE_ENCODER_NOPARAM(ed25519, ecx, EVP_PKEY_ED25519, pem);
MAKE_ENCODER_NOPARAM(ed448, ecx, EVP_PKEY_ED448, der);
MAKE_ENCODER_NOPARAM(ed448, ecx, EVP_PKEY_ED448, pem);
MAKE_ENCODER_NOPARAM(x25519, ecx, EVP_PKEY_X25519, der);
MAKE_ENCODER_NOPARAM(x25519, ecx, EVP_PKEY_X25519, pem);
MAKE_ENCODER_NOPARAM(x448, ecx, EVP_PKEY_ED448, der);
MAKE_ENCODER_NOPARAM(x448, ecx, EVP_PKEY_ED448, pem);
#endif
/*
* RSA-PSS does have parameters, but we don't have a separate output for them,
* so we don't pretend we do. Parameter handling remains internal within the
* RSA helper functions.
*/
MAKE_ENCODER_NOPARAM(rsa, rsa, EVP_PKEY_RSA, der);
MAKE_ENCODER_NOPARAM(rsa, rsa, EVP_PKEY_RSA, pem);

View File

@ -0,0 +1,891 @@
/*
* Copyright 2020 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 "internal/ffc.h"
#include "crypto/bn.h" /* bn_get_words() */
#include "crypto/dh.h" /* dh_get0_params() */
#include "crypto/dsa.h" /* dsa_get0_params() */
#include "crypto/ec.h" /* 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 "prov/providercommonerr.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
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;
}
#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 char *name = ffc_named_group_from_uid(ffc->nid);
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
# define dh_param_selection OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
# define dh_pub_selection (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
| dh_param_selection)
# define dh_priv_selection (OSSL_KEYMGMT_SELECT_KEYPAIR \
| dh_param_selection)
static int dh_to_text(BIO *out, const void *key, int selection)
{
const DH *dh = key;
const char *type_label = NULL;
const BIGNUM *priv_key = NULL, *pub_key = NULL;
const FFC_PARAMS *params = NULL;
const BIGNUM *p = NULL;
if (out == NULL || dh == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
type_label = "DH Private-Key";
else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
type_label = "DH Public-Key";
else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
type_label = "DH Parameters";
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
priv_key = DH_get0_priv_key(dh);
if (priv_key == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
return 0;
}
}
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
pub_key = DH_get0_pub_key(dh);
if (pub_key == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
return 0;
}
}
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
params = dh_get0_params((DH *)dh);
if (params == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS);
return 0;
}
}
p = DH_get0_p(dh);
if (p == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
return 0;
}
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))
return 0;
if (pub_key != NULL
&& !print_labeled_bignum(out, "public-key:", pub_key))
return 0;
if (params != NULL
&& !ffc_params_to_text(out, params))
return 0;
return 1;
}
#endif
/* ---------------------------------------------------------------------- */
#ifndef OPENSSL_NO_DSA
# define dsa_param_selection OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
# define dsa_pub_selection (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
| dsa_param_selection)
# define dsa_priv_selection (OSSL_KEYMGMT_SELECT_KEYPAIR \
| dsa_param_selection)
static int dsa_to_text(BIO *out, const void *key, int selection)
{
const DSA *dsa = key;
const char *type_label = NULL;
const BIGNUM *priv_key = NULL, *pub_key = NULL;
const FFC_PARAMS *params = NULL;
const BIGNUM *p = NULL;
if (out == NULL || dsa == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
type_label = "Private-Key";
else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
type_label = "Public-Key";
else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
type_label = "DSA-Parameters";
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
priv_key = DSA_get0_priv_key(dsa);
if (priv_key == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
return 0;
}
}
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
pub_key = DSA_get0_pub_key(dsa);
if (pub_key == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
return 0;
}
}
if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
params = dsa_get0_params((DSA *)dsa);
if (params == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_PARAMETERS);
return 0;
}
}
p = DSA_get0_p(dsa);
if (p == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
return 0;
}
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))
return 0;
if (pub_key != NULL
&& !print_labeled_bignum(out, "pub: ", pub_key))
return 0;
if (params != NULL
&& !ffc_params_to_text(out, params))
return 0;
return 1;
}
#endif
/* ---------------------------------------------------------------------- */
#ifndef OPENSSL_NO_EC
# define ec_param_selection OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
# define ec_pub_selection (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
| ec_param_selection)
# define ec_priv_selection (OSSL_KEYMGMT_SELECT_KEYPAIR \
| ec_param_selection)
static int ec_param_explicit_curve_to_text(BIO *out, const EC_GROUP *group,
BN_CTX *ctx)
{
const char *plabel = "Prime:";
BIGNUM *p = NULL, *a = NULL, *b = NULL;
p = BN_CTX_get(ctx);
a = BN_CTX_get(ctx);
b = BN_CTX_get(ctx);
if (b == NULL
|| !EC_GROUP_get_curve(group, p, a, b, ctx))
return 0;
if (EC_GROUP_get_field_type(group) == NID_X9_62_characteristic_two_field) {
int basis_type = EC_GROUP_get_basis_type(group);
/* print the 'short name' of the base type OID */
if (basis_type == NID_undef
|| BIO_printf(out, "Basis Type: %s\n", OBJ_nid2sn(basis_type)) <= 0)
return 0;
plabel = "Polynomial:";
}
return print_labeled_bignum(out, plabel, p)
&& print_labeled_bignum(out, "A: ", a)
&& print_labeled_bignum(out, "B: ", b);
}
static int ec_param_explicit_gen_to_text(BIO *out, const EC_GROUP *group,
BN_CTX *ctx)
{
const EC_POINT *point = NULL;
BIGNUM *gen = NULL;
const char *glabel = NULL;
point_conversion_form_t form;
form = EC_GROUP_get_point_conversion_form(group);
point = EC_GROUP_get0_generator(group);
gen = BN_CTX_get(ctx);
if (gen == NULL
|| point == NULL
|| EC_POINT_point2bn(group, point, form, gen, ctx) == NULL)
return 0;
if (gen != NULL) {
switch (form) {
case POINT_CONVERSION_COMPRESSED:
glabel = "Generator (compressed):";
break;
case POINT_CONVERSION_UNCOMPRESSED:
glabel = "Generator (uncompressed):";
break;
case POINT_CONVERSION_HYBRID:
glabel = "Generator (hybrid):";
break;
default:
return 0;
}
return print_labeled_bignum(out, glabel, gen);
}
return 1;
}
/* Print explicit parameters */
static int ec_param_explicit_to_text(BIO *out, const EC_GROUP *group,
OPENSSL_CTX *libctx)
{
int ret = 0, tmp_nid;
BN_CTX *ctx = NULL;
const BIGNUM *order = NULL, *cofactor = NULL;
const unsigned char *seed;
size_t seed_len = 0;
ctx = BN_CTX_new_ex(libctx);
if (ctx == NULL)
return 0;
BN_CTX_start(ctx);
tmp_nid = EC_GROUP_get_field_type(group);
order = EC_GROUP_get0_order(group);
if (order == NULL)
goto err;
seed = EC_GROUP_get0_seed(group);
if (seed != NULL)
seed_len = EC_GROUP_get_seed_len(group);
cofactor = EC_GROUP_get0_cofactor(group);
/* print the 'short name' of the field type */
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)
|| (cofactor != NULL
&& !print_labeled_bignum(out, "Cofactor: ", cofactor))
|| (seed != NULL
&& !print_labeled_buf(out, "Seed:", seed, seed_len)))
goto err;
ret = 1;
err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
return ret;
}
static int ec_param_to_text(BIO *out, const EC_GROUP *group,
OPENSSL_CTX *libctx)
{
if (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) {
const char *curve_name;
int curve_nid = EC_GROUP_get_curve_name(group);
/* Explicit parameters */
if (curve_nid == NID_undef)
return 0;
if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0)
return 0;
curve_name = EC_curve_nid2nist(curve_nid);
return (curve_name == NULL
|| BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0);
} else {
return ec_param_explicit_to_text(out, group, libctx);
}
}
static int ec_to_text(BIO *out, const void *key, int selection)
{
const EC_KEY *ec = key;
const char *type_label = NULL;
unsigned char *priv = NULL, *pub = NULL;
size_t priv_len = 0, pub_len = 0;
const EC_GROUP *group;
int ret = 0;
if (out == NULL || ec == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if ((group = EC_KEY_get0_group(ec)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
return 0;
}
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
type_label = "Private-Key";
else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
type_label = "Public-Key";
else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0)
type_label = "EC-Parameters";
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
const BIGNUM *priv_key = EC_KEY_get0_private_key(ec);
if (priv_key == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
goto err;
}
priv_len = EC_KEY_priv2buf(ec, &priv);
if (priv_len == 0)
goto err;
}
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
const EC_POINT *pub_pt = EC_KEY_get0_public_key(ec);
if (pub_pt == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
goto err;
}
pub_len = EC_KEY_key2buf(ec, EC_KEY_get_conv_form(ec), &pub, NULL);
if (pub_len == 0)
goto err;
}
if (BIO_printf(out, "%s: (%d bit)\n", type_label,
EC_GROUP_order_bits(group)) <= 0)
goto err;
if (priv != NULL
&& !print_labeled_buf(out, "priv:", priv, priv_len))
goto err;
if (pub != NULL
&& !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, ec_key_get_libctx(ec));
err:
OPENSSL_clear_free(priv, priv_len);
OPENSSL_free(pub);
return ret;
}
#endif
/* ---------------------------------------------------------------------- */
#ifndef OPENSSL_NO_EC
# define ecx_pub_selection OSSL_KEYMGMT_SELECT_PUBLIC_KEY
# define ecx_priv_selection OSSL_KEYMGMT_SELECT_KEYPAIR
static int ecx_to_text(BIO *out, const void *key, int selection)
{
const ECX_KEY *ecx = key;
const char *type_label = NULL;
if (out == NULL || ecx == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
if (ecx->privkey == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
return 0;
}
switch (ecx->type) {
case ECX_KEY_TYPE_X25519:
type_label = "X25519 Private-Key";
break;
case ECX_KEY_TYPE_X448:
type_label = "X448 Private-Key";
break;
case ECX_KEY_TYPE_ED25519:
type_label = "ED25519 Private-Key";
break;
case ECX_KEY_TYPE_ED448:
type_label = "ED448 Private-Key";
break;
}
} else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
/* ecx->pubkey is an array, not a pointer... */
if (!ecx->haspubkey) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
return 0;
}
switch (ecx->type) {
case ECX_KEY_TYPE_X25519:
type_label = "X25519 Public-Key";
break;
case ECX_KEY_TYPE_X448:
type_label = "X448 Public-Key";
break;
case ECX_KEY_TYPE_ED25519:
type_label = "ED25519 Public-Key";
break;
case ECX_KEY_TYPE_ED448:
type_label = "ED448 Public-Key";
break;
}
}
if (BIO_printf(out, "%s:\n", type_label) <= 0)
return 0;
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
&& !print_labeled_buf(out, "priv:", ecx->privkey, ecx->keylen))
return 0;
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0
&& !print_labeled_buf(out, "pub:", ecx->pubkey, ecx->keylen))
return 0;
return 1;
}
#endif
/* ---------------------------------------------------------------------- */
#define rsa_param_selection OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS
#define rsa_pub_selection (OSSL_KEYMGMT_SELECT_PUBLIC_KEY \
| rsa_param_selection)
#define rsa_priv_selection (OSSL_KEYMGMT_SELECT_KEYPAIR \
| rsa_param_selection)
static int rsa_to_text(BIO *out, const void *key, int selection)
{
const RSA *rsa = key;
const char *type_label = "RSA key";
const char *modulus_label;
const char *exponent_label;
const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL;
STACK_OF(BIGNUM_const) *factors = NULL;
STACK_OF(BIGNUM_const) *exps = NULL;
STACK_OF(BIGNUM_const) *coeffs = NULL;
int primes;
const RSA_PSS_PARAMS_30 *pss_params = rsa_get0_pss_params_30((RSA *)rsa);
int ret = 0;
if (out == NULL || rsa == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
goto err;
}
factors = sk_BIGNUM_const_new_null();
exps = sk_BIGNUM_const_new_null();
coeffs = sk_BIGNUM_const_new_null();
if (factors == NULL || exps == NULL || coeffs == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
goto err;
}
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
type_label = "Private-Key";
modulus_label = "modulus:";
exponent_label = "publicExponent:";
} else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
type_label = "Public-Key";
modulus_label = "Modulus:";
exponent_label = "Exponent:";
}
RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
rsa_get0_all_params((RSA *)rsa, factors, exps, coeffs);
primes = sk_BIGNUM_const_num(factors);
if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
if (BIO_printf(out, "%s: (%d bit, %d primes)\n",
type_label, BN_num_bits(rsa_n), primes) <= 0)
goto err;
} else {
if (BIO_printf(out, "%s: (%d bit)\n",
type_label, BN_num_bits(rsa_n)) <= 0)
goto err;
}
if (!print_labeled_bignum(out, modulus_label, rsa_n))
goto err;
if (!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))
goto err;
if (!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)))
goto err;
if (!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)))
goto err;
if (!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)))
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)))
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)))
goto err;
}
}
if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0) {
switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
case RSA_FLAG_TYPE_RSA:
if (!rsa_pss_params_30_is_unrestricted(pss_params)) {
if (BIO_printf(out, "(INVALID PSS PARAMETERS)\n") <= 0)
goto err;
}
break;
case RSA_FLAG_TYPE_RSASSAPSS:
if (rsa_pss_params_30_is_unrestricted(pss_params)) {
if (BIO_printf(out, "No PSS parameter restrictions\n") <= 0)
goto err;
} else {
int hashalg_nid = rsa_pss_params_30_hashalg(pss_params);
int maskgenalg_nid = rsa_pss_params_30_maskgenalg(pss_params);
int maskgenhashalg_nid =
rsa_pss_params_30_maskgenhashalg(pss_params);
int saltlen = rsa_pss_params_30_saltlen(pss_params);
int trailerfield = rsa_pss_params_30_trailerfield(pss_params);
if (BIO_printf(out, "PSS parameter restrictions:\n") <= 0)
goto err;
if (BIO_printf(out, " Hash Algorithm: %s%s\n",
rsa_oaeppss_nid2name(hashalg_nid),
(hashalg_nid == NID_sha1
? " (default)" : "")) <= 0)
goto err;
if (BIO_printf(out, " Mask Algorithm: %s with %s%s\n",
rsa_mgf_nid2name(maskgenalg_nid),
rsa_oaeppss_nid2name(maskgenhashalg_nid),
(maskgenalg_nid == NID_mgf1
&& maskgenhashalg_nid == NID_sha1
? " (default)" : "")) <= 0)
goto err;
if (BIO_printf(out, " Minimum Salt Length: %d%s\n",
saltlen,
(saltlen == 20 ? " (default)" : "")) <= 0)
goto err;
/*
* TODO(3.0) Should we show the ASN.1 trailerField value, or
* the actual trailerfield byte (i.e. 0xBC for 1)?
* crypto/rsa/rsa_ameth.c isn't very clear on that, as it
* does display 0xBC when the default applies, but the ASN.1
* trailerField value otherwise...
*/
if (BIO_printf(out, " Trailer Field: 0x%x%s\n",
trailerfield,
(trailerfield == 1 ? " (default)" : "")) <= 0)
goto err;
}
break;
}
}
ret = 1;
err:
sk_BIGNUM_const_free(factors);
sk_BIGNUM_const_free(exps);
sk_BIGNUM_const_free(coeffs);
return ret;
}
/* ---------------------------------------------------------------------- */
static void *key2text_newctx(void *provctx)
{
return provctx;
}
static void key2text_freectx(ossl_unused void *vctx)
{
}
static int key2text_encode(void *vctx, const void *key, int selection,
OSSL_CORE_BIO *cout,
int (*key2text)(BIO *out, const void *key,
int selection),
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(vctx, cout);
int ret;
if (out == NULL)
return 0;
ret = key2text(out, key, selection);
BIO_free(out);
return ret;
}
#define MAKE_TEXT_ENCODER_KIND(impl, kind, type) \
static OSSL_FUNC_encoder_encode_data_fn \
impl##_##kind##2text_encode_d; \
static OSSL_FUNC_encoder_encode_object_fn \
impl##_##kind##2text_encode_o; \
static int \
impl##_##kind##2text_encode_d(void *ctx, const OSSL_PARAM params[], \
OSSL_CORE_BIO *cout, \
OSSL_PASSPHRASE_CALLBACK *cb, \
void *cbarg) \
{ \
int selection = type##_##kind##_selection; \
void *key = ossl_prov_import_key(impl##_keymgmt_functions, \
ctx, selection, params); \
int ret; \
\
if (key == NULL) \
return 0; \
\
ret = impl##_##kind##2text_encode_o(ctx, key, cout, cb, cbarg); \
ossl_prov_free_key(impl##_keymgmt_functions, key); \
return ret; \
} \
static int \
impl##_##kind##2text_encode_o(void *vctx, const void *key, \
OSSL_CORE_BIO *cout, \
OSSL_PASSPHRASE_CALLBACK *cb, \
void *cbarg) \
{ \
int selection = type##_##kind##_selection; \
\
return key2text_encode(vctx, key, selection, cout, \
type##_to_text, cb, cbarg); \
} \
const OSSL_DISPATCH impl##_##kind##_to_text_encoder_functions[] = { \
{ OSSL_FUNC_ENCODER_NEWCTX, \
(void (*)(void))key2text_newctx }, \
{ OSSL_FUNC_ENCODER_FREECTX, \
(void (*)(void))key2text_freectx }, \
{ OSSL_FUNC_ENCODER_ENCODE_DATA, \
(void (*)(void))impl##_##kind##2text_encode_d }, \
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, \
(void (*)(void))impl##_##kind##2text_encode_o }, \
{ 0, NULL } \
}
#define MAKE_TEXT_ENCODER(impl, type) \
MAKE_TEXT_ENCODER_KIND(impl, param, type); \
MAKE_TEXT_ENCODER_KIND(impl, pub, type); \
MAKE_TEXT_ENCODER_KIND(impl, priv, type)
#define MAKE_TEXT_ENCODER_NOPARAM(impl, type) \
MAKE_TEXT_ENCODER_KIND(impl, pub, type); \
MAKE_TEXT_ENCODER_KIND(impl, priv, type)
#ifndef OPENSSL_NO_DH
MAKE_TEXT_ENCODER(dh, dh);
#endif
#ifndef OPENSSL_NO_DSA
MAKE_TEXT_ENCODER(dsa, dsa);
#endif
#ifndef OPENSSL_NO_EC
MAKE_TEXT_ENCODER(ec, ec);
MAKE_TEXT_ENCODER_NOPARAM(ed25519, ecx);
MAKE_TEXT_ENCODER_NOPARAM(ed448, ecx);
MAKE_TEXT_ENCODER_NOPARAM(x25519, ecx);
MAKE_TEXT_ENCODER_NOPARAM(x448, ecx);
#endif
MAKE_TEXT_ENCODER_NOPARAM(rsa, rsa);

View File

@ -1,397 +0,0 @@
/*
* Copyright 2019-2020 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
*/
#include <openssl/opensslconf.h> /* SIXTY_FOUR_BIT_LONG, ... */
#include <openssl/err.h>
#include <openssl/pem.h> /* PEM_BUFSIZE */
#include <openssl/pkcs12.h> /* PKCS8_encrypt() */
#include <openssl/types.h>
#include <openssl/x509.h> /* i2d_X509_PUBKEY_bio() */
#include "crypto/bn.h" /* bn_get_words() */
#include "crypto/ctype.h"
#include "crypto/ecx.h"
#include "prov/bio.h" /* ossl_prov_bio_printf() */
#include "prov/implementations.h"
#include "prov/providercommonerr.h" /* PROV_R_READ_KEY */
#include "encoder_local.h"
static PKCS8_PRIV_KEY_INFO *
ossl_prov_p8info_from_obj(const void *obj, int obj_nid,
void *params,
int params_type,
int (*k2d)(const void *obj,
unsigned char **pder))
{
/* der, derlen store the key DER output and its length */
unsigned char *der = NULL;
int derlen;
/* The final PKCS#8 info */
PKCS8_PRIV_KEY_INFO *p8info = NULL;
if ((p8info = PKCS8_PRIV_KEY_INFO_new()) == NULL
|| (derlen = k2d(obj, &der)) <= 0
|| !PKCS8_pkey_set0(p8info, OBJ_nid2obj(obj_nid), 0,
params_type, params, der, derlen)) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
PKCS8_PRIV_KEY_INFO_free(p8info);
OPENSSL_free(der);
p8info = NULL;
}
return p8info;
}
static X509_SIG *ossl_prov_encp8_from_p8info(PKCS8_PRIV_KEY_INFO *p8info,
struct pkcs8_encrypt_ctx_st *ctx)
{
X509_SIG *p8 = NULL;
char buf[PEM_BUFSIZE];
const void *kstr = ctx->cipher_pass;
size_t klen = ctx->cipher_pass_length;
if (ctx->cipher == NULL)
return NULL;
if (kstr == NULL) {
if (!ctx->cb(buf, sizeof(buf), &klen, NULL, ctx->cbarg)) {
ERR_raise(ERR_LIB_PROV, PROV_R_READ_KEY);
return NULL;
}
kstr = buf;
}
/* NID == -1 means "standard" */
p8 = PKCS8_encrypt(-1, ctx->cipher, kstr, klen, NULL, 0, 0, p8info);
if (kstr == buf)
OPENSSL_cleanse(buf, klen);
return p8;
}
static X509_SIG *ossl_prov_encp8_from_obj(const void *obj, int obj_nid,
void *params,
int params_type,
int (*k2d)(const void *obj,
unsigned char **pder),
struct pkcs8_encrypt_ctx_st *ctx)
{
PKCS8_PRIV_KEY_INFO *p8info =
ossl_prov_p8info_from_obj(obj, obj_nid, params, params_type, k2d);
X509_SIG *p8 = ossl_prov_encp8_from_p8info(p8info, ctx);
PKCS8_PRIV_KEY_INFO_free(p8info);
return p8;
}
static X509_PUBKEY *ossl_prov_pubkey_from_obj(const void *obj, int obj_nid,
void *params,
int params_type,
int (*k2d)(const void *obj,
unsigned char **pder))
{
/* der, derlen store the key DER output and its length */
unsigned char *der = NULL;
int derlen;
/* The final X509_PUBKEY */
X509_PUBKEY *xpk = NULL;
if ((xpk = X509_PUBKEY_new()) == NULL
|| (derlen = k2d(obj, &der)) <= 0
|| !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(obj_nid),
params_type, params, der, derlen)) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
X509_PUBKEY_free(xpk);
OPENSSL_free(der);
xpk = NULL;
}
return xpk;
}
OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns)
{
/* Pilfer the keymgmt dispatch table */
for (; fns->function_id != 0; fns++)
if (fns->function_id == OSSL_FUNC_KEYMGMT_NEW)
return OSSL_FUNC_keymgmt_new(fns);
return NULL;
}
OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns)
{
/* Pilfer the keymgmt dispatch table */
for (; fns->function_id != 0; fns++)
if (fns->function_id == OSSL_FUNC_KEYMGMT_FREE)
return OSSL_FUNC_keymgmt_free(fns);
return NULL;
}
OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns)
{
/* Pilfer the keymgmt dispatch table */
for (; fns->function_id != 0; fns++)
if (fns->function_id == OSSL_FUNC_KEYMGMT_IMPORT)
return OSSL_FUNC_keymgmt_import(fns);
return NULL;
}
OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns)
{
/* Pilfer the keymgmt dispatch table */
for (; fns->function_id != 0; fns++)
if (fns->function_id == OSSL_FUNC_KEYMGMT_EXPORT)
return OSSL_FUNC_keymgmt_export(fns);
return NULL;
}
# 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
int ossl_prov_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 ? ":" : "",
ossl_tolower(p[0]), ossl_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
int ossl_prov_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;
}
/* p2s = param to asn1, k2d = key to der */
int ossl_prov_write_priv_der_from_obj(BIO *out, const void *obj, int obj_nid,
int (*p2s)(const void *obj, int nid,
void **str,
int *strtype),
int (*k2d)(const void *obj,
unsigned char **pder),
struct pkcs8_encrypt_ctx_st *ctx)
{
int ret = 0;
void *str = NULL;
int strtype = V_ASN1_UNDEF;
if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype))
return 0;
if (ctx->cipher_intent) {
X509_SIG *p8 =
ossl_prov_encp8_from_obj(obj, obj_nid, str, strtype, k2d, ctx);
if (p8 != NULL)
ret = i2d_PKCS8_bio(out, p8);
X509_SIG_free(p8);
} else {
PKCS8_PRIV_KEY_INFO *p8info =
ossl_prov_p8info_from_obj(obj, obj_nid, str, strtype, k2d);
if (p8info != NULL)
ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info);
PKCS8_PRIV_KEY_INFO_free(p8info);
}
return ret;
}
int ossl_prov_write_priv_pem_from_obj(BIO *out, const void *obj, int obj_nid,
int (*p2s)(const void *obj, int nid,
void **str,
int *strtype),
int (*k2d)(const void *obj,
unsigned char **pder),
struct pkcs8_encrypt_ctx_st *ctx)
{
int ret = 0;
void *str = NULL;
int strtype = V_ASN1_UNDEF;
if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype))
return 0;
if (ctx->cipher_intent) {
X509_SIG *p8 = ossl_prov_encp8_from_obj(obj, obj_nid, str, strtype,
k2d, ctx);
if (p8 != NULL)
ret = PEM_write_bio_PKCS8(out, p8);
X509_SIG_free(p8);
} else {
PKCS8_PRIV_KEY_INFO *p8info =
ossl_prov_p8info_from_obj(obj, obj_nid, str, strtype, k2d);
if (p8info != NULL)
ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info);
PKCS8_PRIV_KEY_INFO_free(p8info);
}
return ret;
}
int ossl_prov_write_pub_der_from_obj(BIO *out, const void *obj, int obj_nid,
int (*p2s)(const void *obj, int nid,
void **str,
int *strtype),
int (*k2d)(const void *obj,
unsigned char **pder))
{
int ret = 0;
void *str = NULL;
int strtype = V_ASN1_UNDEF;
X509_PUBKEY *xpk = NULL;
if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype))
return 0;
xpk = ossl_prov_pubkey_from_obj(obj, obj_nid, str, strtype, k2d);
if (xpk != NULL)
ret = i2d_X509_PUBKEY_bio(out, xpk);
/* Also frees |str| */
X509_PUBKEY_free(xpk);
return ret;
}
int ossl_prov_write_pub_pem_from_obj(BIO *out, const void *obj, int obj_nid,
int (*p2s)(const void *obj, int nid,
void **str,
int *strtype),
int (*k2d)(const void *obj,
unsigned char **pder))
{
int ret = 0;
void *str = NULL;
int strtype = V_ASN1_UNDEF;
X509_PUBKEY *xpk = NULL;
if (p2s != NULL && !p2s(obj, obj_nid, &str, &strtype))
return 0;
xpk = ossl_prov_pubkey_from_obj(obj, obj_nid, str, strtype, k2d);
if (xpk != NULL)
ret = PEM_write_bio_X509_PUBKEY(out, xpk);
/* Also frees |str| */
X509_PUBKEY_free(xpk);
return ret;
}

View File

@ -1,166 +0,0 @@
/*
* Copyright 2019-2020 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
*/
/*
* DH low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/err.h>
#include "prov/bio.h" /* ossl_prov_bio_printf() */
#include "prov/implementations.h" /* rsa_keymgmt_functions */
#include "prov/providercommonerr.h" /* PROV_R_BN_ERROR */
#include "internal/ffc.h"
#include "crypto/dh.h"
#include "encoder_local.h"
OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dh_new(void)
{
return ossl_prov_get_keymgmt_new(dh_keymgmt_functions);
}
OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dh_free(void)
{
return ossl_prov_get_keymgmt_free(dh_keymgmt_functions);
}
OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dh_import(void)
{
return ossl_prov_get_keymgmt_import(dh_keymgmt_functions);
}
int ossl_prov_print_dh(BIO *out, DH *dh, enum dh_print_type type)
{
const char *type_label = NULL;
const BIGNUM *priv_key = NULL, *pub_key = NULL;
const BIGNUM *p = NULL;
switch (type) {
case dh_print_priv:
type_label = "DH Private-Key";
break;
case dh_print_pub:
type_label = "DH Public-Key";
break;
case dh_print_params:
type_label = "DH Parameters";
break;
}
if (type == dh_print_priv) {
priv_key = DH_get0_priv_key(dh);
if (priv_key == NULL)
goto null_err;
}
if (type == dh_print_priv || type == dh_print_pub) {
pub_key = DH_get0_pub_key(dh);
if (pub_key == NULL)
goto null_err;
}
p = DH_get0_p(dh);
if (p == NULL)
goto null_err;
if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p))
<= 0)
goto err;
if (priv_key != NULL
&& !ossl_prov_print_labeled_bignum(out, "private-key:", priv_key))
goto err;
if (pub_key != NULL
&& !ossl_prov_print_labeled_bignum(out, "public-key:", pub_key))
goto err;
if (!ffc_params_prov_print(out, dh_get0_params(dh)))
goto err;
return 1;
err:
return 0;
null_err:
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
goto err;
}
int ossl_prov_prepare_dh_params(const void *dh, int nid,
void **pstr, int *pstrtype)
{
ASN1_STRING *params = ASN1_STRING_new();
if (params == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return 0;
}
if (nid == EVP_PKEY_DHX)
params->length = i2d_DHxparams(dh, &params->data);
else
params->length = i2d_DHparams(dh, &params->data);
if (params->length <= 0) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
ASN1_STRING_free(params);
return 0;
}
params->type = V_ASN1_SEQUENCE;
*pstr = params;
*pstrtype = V_ASN1_SEQUENCE;
return 1;
}
int ossl_prov_dh_pub_to_der(const void *dh, unsigned char **pder)
{
const BIGNUM *bn = NULL;
ASN1_INTEGER *pub_key = NULL;
int ret;
if ((bn = DH_get0_pub_key(dh)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
return 0;
}
if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
return 0;
}
ret = i2d_ASN1_INTEGER(pub_key, pder);
ASN1_STRING_clear_free(pub_key);
return ret;
}
int ossl_prov_dh_priv_to_der(const void *dh, unsigned char **pder)
{
const BIGNUM *bn = NULL;
ASN1_INTEGER *priv_key = NULL;
int ret;
if ((bn = DH_get0_priv_key(dh)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
return 0;
}
if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
return 0;
}
ret = i2d_ASN1_INTEGER(priv_key, pder);
ASN1_STRING_clear_free(priv_key);
return ret;
}
int ossl_prov_dh_type_to_evp(const DH *dh)
{
return DH_test_flags(dh, DH_FLAG_TYPE_DHX) ? EVP_PKEY_DHX : EVP_PKEY_DH;
}

View File

@ -1,186 +0,0 @@
/*
* Copyright 2019-2020 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
*/
/*
* DH low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/core_dispatch.h>
#include <openssl/pem.h>
#include <openssl/dh.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/providercommonerr.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
static OSSL_FUNC_encoder_newctx_fn dh_param_newctx;
static OSSL_FUNC_encoder_freectx_fn dh_param_freectx;
static OSSL_FUNC_encoder_encode_data_fn dh_param_der_data;
static OSSL_FUNC_encoder_encode_object_fn dh_param_der;
static OSSL_FUNC_encoder_encode_data_fn dh_param_pem_data;
static OSSL_FUNC_encoder_encode_object_fn dh_param_pem;
static OSSL_FUNC_encoder_encode_data_fn dh_param_print_data;
static OSSL_FUNC_encoder_encode_object_fn dh_param_print;
/* Parameters : context */
/*
* There's no specific implementation context, so we use the provider context
*/
static void *dh_param_newctx(void *provctx)
{
return provctx;
}
static void dh_param_freectx(void *ctx)
{
}
/* Public key : DER */
static int dh_param_der_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
int ok = 0;
if (dh_import != NULL) {
DH *dh;
/* ctx == provctx */
if ((dh = dh_new(ctx)) != NULL
&& dh_import(dh, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, params)
&& dh_param_der(ctx, dh, out, cb, cbarg))
ok = 1;
dh_free(dh);
}
return ok;
}
static int dh_param_der(void *ctx, void *dh, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = i2d_DHparams_bio(out, dh);
BIO_free(out);
return ret;
}
/* Public key : PEM */
static int dh_param_pem_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
int ok = 0;
if (dh_import != NULL) {
DH *dh;
/* ctx == provctx */
if ((dh = dh_new(ctx)) != NULL
&& dh_import(dh, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, params)
&& dh_param_pem(ctx, dh, out, cb, cbarg))
ok = 1;
dh_free(dh);
}
return ok;
}
static int dh_param_pem(void *ctx, void *dh, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = PEM_write_bio_DHparams(out, dh);
BIO_free(out);
return ret;
}
static int dh_param_print_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
int ok = 0;
if (dh_import != NULL) {
DH *dh;
/* ctx == provctx */
if ((dh = dh_new(ctx)) != NULL
&& dh_import(dh, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, params)
&& dh_param_print(ctx, dh, out, cb, cbarg))
ok = 1;
dh_free(dh);
}
return ok;
}
static int dh_param_print(void *ctx, void *dh, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_dh(out, dh, dh_print_params);
BIO_free(out);
return ret;
}
const OSSL_DISPATCH dh_param_der_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_param_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_param_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_param_der_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_param_der },
{ 0, NULL }
};
const OSSL_DISPATCH dh_param_pem_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_param_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_param_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_param_pem_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_param_pem },
{ 0, NULL }
};
const OSSL_DISPATCH dh_param_text_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_param_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_param_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_param_print },
{ OSSL_FUNC_ENCODER_ENCODE_DATA,
(void (*)(void))dh_param_print_data },
{ 0, NULL }
};

View File

@ -1,295 +0,0 @@
/*
* Copyright 2019-2020 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
*/
/*
* DH low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/dh.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
#define DH_SELECT_PRIVATE_IMPORTABLE \
(OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
static OSSL_FUNC_encoder_newctx_fn dh_priv_newctx;
static OSSL_FUNC_encoder_freectx_fn dh_priv_freectx;
static OSSL_FUNC_encoder_set_ctx_params_fn dh_priv_set_ctx_params;
static OSSL_FUNC_encoder_settable_ctx_params_fn dh_priv_settable_ctx_params;
static OSSL_FUNC_encoder_encode_data_fn dh_priv_der_data;
static OSSL_FUNC_encoder_encode_object_fn dh_priv_der;
static OSSL_FUNC_encoder_encode_data_fn dh_pem_priv_data;
static OSSL_FUNC_encoder_encode_object_fn dh_pem_priv;
static OSSL_FUNC_encoder_newctx_fn dh_print_newctx;
static OSSL_FUNC_encoder_freectx_fn dh_print_freectx;
static OSSL_FUNC_encoder_encode_data_fn dh_priv_print_data;
static OSSL_FUNC_encoder_encode_object_fn dh_priv_print;
/*
* Context used for private key encoding.
*/
struct dh_priv_ctx_st {
void *provctx;
struct pkcs8_encrypt_ctx_st sc;
};
/* Private key : context */
static void *dh_priv_newctx(void *provctx)
{
struct dh_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx != NULL) {
ctx->provctx = provctx;
/* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
ctx->sc.pbe_nid = -1;
}
return ctx;
}
static void dh_priv_freectx(void *vctx)
{
struct dh_priv_ctx_st *ctx = vctx;
EVP_CIPHER_free(ctx->sc.cipher);
OPENSSL_free(ctx->sc.cipher_pass);
OPENSSL_free(ctx);
}
static const OSSL_PARAM *dh_priv_settable_ctx_params(ossl_unused void *provctx)
{
static const OSSL_PARAM settables[] = {
OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
OSSL_PARAM_END,
};
return settables;
}
static int dh_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
struct dh_priv_ctx_st *ctx = vctx;
const OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
!= NULL) {
const OSSL_PARAM *propsp =
OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
const char *props = NULL;
if (p->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
props = (propsp != NULL ? propsp->data : NULL);
EVP_CIPHER_free(ctx->sc.cipher);
ctx->sc.cipher_intent = p->data != NULL;
if (p->data != NULL
&& ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props))
== NULL))
return 0;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
!= NULL) {
OPENSSL_free(ctx->sc.cipher_pass);
ctx->sc.cipher_pass = NULL;
if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
&ctx->sc.cipher_pass_length))
return 0;
}
return 1;
}
/* Private key : DER */
static int dh_priv_der_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct dh_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
int ok = 0;
if (dh_import != NULL) {
DH *dh;
if ((dh = dh_new(ctx->provctx)) != NULL
&& dh_import(dh, DH_SELECT_PRIVATE_IMPORTABLE, params)
&& dh_priv_der(ctx, dh, out, cb, cbarg))
ok = 1;
dh_free(dh);
}
return ok;
}
static int dh_priv_der(void *vctx, void *dh, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct dh_priv_ctx_st *ctx = vctx;
int ret;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
if (out == NULL)
return 0;
ctx->sc.cb = cb;
ctx->sc.cbarg = cbarg;
ret = ossl_prov_write_priv_der_from_obj(out, dh,
ossl_prov_dh_type_to_evp(dh),
ossl_prov_prepare_dh_params,
ossl_prov_dh_priv_to_der,
&ctx->sc);
BIO_free(out);
return ret;
}
/* Private key : PEM */
static int dh_pem_priv_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct dh_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
int ok = 0;
if (dh_import != NULL) {
DH *dh;
if ((dh = dh_new(ctx->provctx)) != NULL
&& dh_import(dh, DH_SELECT_PRIVATE_IMPORTABLE, params)
&& dh_pem_priv(ctx->provctx, dh, out, cb, cbarg))
ok = 1;
dh_free(dh);
}
return ok;
}
static int dh_pem_priv(void *vctx, void *dh, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct dh_priv_ctx_st *ctx = vctx;
int ret;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
if (out == NULL)
return 0;
ctx->sc.cb = cb;
ctx->sc.cbarg = cbarg;
ret = ossl_prov_write_priv_pem_from_obj(out, dh,
ossl_prov_dh_type_to_evp(dh),
ossl_prov_prepare_dh_params,
ossl_prov_dh_priv_to_der,
&ctx->sc);
BIO_free(out);
return ret;
}
/*
* There's no specific print context, so we use the provider context
*/
static void *dh_print_newctx(void *provctx)
{
return provctx;
}
static void dh_print_freectx(void *ctx)
{
}
static int dh_priv_print_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct dh_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
int ok = 0;
if (dh_import != NULL) {
DH *dh;
if ((dh = dh_new(ctx->provctx)) != NULL
&& dh_import(dh, DH_SELECT_PRIVATE_IMPORTABLE, params)
&& dh_priv_print(ctx, dh, out, cb, cbarg))
ok = 1;
dh_free(dh);
}
return ok;
}
static int dh_priv_print(void *ctx, void *dh, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_dh(out, dh, dh_print_priv);
BIO_free(out);
return ret;
}
const OSSL_DISPATCH dh_priv_der_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_priv_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_priv_freectx },
{ OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
(void (*)(void))dh_priv_set_ctx_params },
{ OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
(void (*)(void))dh_priv_settable_ctx_params },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_priv_der_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_priv_der },
{ 0, NULL }
};
const OSSL_DISPATCH dh_priv_pem_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_priv_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_priv_freectx },
{ OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
(void (*)(void))dh_priv_set_ctx_params },
{ OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
(void (*)(void))dh_priv_settable_ctx_params },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_pem_priv_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_pem_priv },
{ 0, NULL }
};
const OSSL_DISPATCH dh_priv_text_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_print_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_print_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_priv_print },
{ OSSL_FUNC_ENCODER_ENCODE_DATA,
(void (*)(void))dh_priv_print_data },
{ 0, NULL }
};

View File

@ -1,196 +0,0 @@
/*
* Copyright 2019-2020 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
*/
/*
* DH low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/core_dispatch.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/dh.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
static OSSL_FUNC_encoder_newctx_fn dh_pub_newctx;
static OSSL_FUNC_encoder_freectx_fn dh_pub_freectx;
static OSSL_FUNC_encoder_encode_data_fn dh_pub_der_data;
static OSSL_FUNC_encoder_encode_object_fn dh_pub_der;
static OSSL_FUNC_encoder_encode_data_fn dh_pub_pem_data;
static OSSL_FUNC_encoder_encode_object_fn dh_pub_pem;
static OSSL_FUNC_encoder_encode_data_fn dh_pub_print_data;
static OSSL_FUNC_encoder_encode_object_fn dh_pub_print;
#define DH_SELECT_PUBLIC_IMPORTABLE \
(OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
/* Public key : context */
/*
* There's no specific implementation context, so we use the provider context
*/
static void *dh_pub_newctx(void *provctx)
{
return provctx;
}
static void dh_pub_freectx(void *ctx)
{
}
/* Public key : DER */
static int dh_pub_der_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
int ok = 0;
if (dh_import != NULL) {
DH *dh;
/* ctx == provctx */
if ((dh = dh_new(ctx)) != NULL
&& dh_import(dh, DH_SELECT_PUBLIC_IMPORTABLE, params)
&& dh_pub_der(ctx, dh, out, cb, cbarg))
ok = 1;
dh_free(dh);
}
return ok;
}
static int dh_pub_der(void *ctx, void *dh, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_write_pub_der_from_obj(out, dh,
ossl_prov_dh_type_to_evp(dh),
ossl_prov_prepare_dh_params,
ossl_prov_dh_pub_to_der);
BIO_free(out);
return ret;
}
/* Public key : PEM */
static int dh_pub_pem_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
int ok = 0;
if (dh_import != NULL) {
DH *dh;
/* ctx == provctx */
if ((dh = dh_new(ctx)) != NULL
&& dh_import(dh, DH_SELECT_PUBLIC_IMPORTABLE, params)
&& dh_pub_pem(ctx, dh, out, cb, cbarg))
ok = 1;
dh_free(dh);
}
return ok;
}
static int dh_pub_pem(void *ctx, void *dh, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_write_pub_pem_from_obj(out, dh,
ossl_prov_dh_type_to_evp(dh),
ossl_prov_prepare_dh_params,
ossl_prov_dh_pub_to_der);
BIO_free(out);
return ret;
}
static int dh_pub_print_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *dh_new = ossl_prov_get_keymgmt_dh_new();
OSSL_FUNC_keymgmt_free_fn *dh_free = ossl_prov_get_keymgmt_dh_free();
OSSL_FUNC_keymgmt_import_fn *dh_import = ossl_prov_get_keymgmt_dh_import();
int ok = 0;
if (dh_import != NULL) {
DH *dh;
/* ctx == provctx */
if ((dh = dh_new(ctx)) != NULL
&& dh_import(dh, DH_SELECT_PUBLIC_IMPORTABLE, params)
&& dh_pub_print(ctx, dh, out, cb, cbarg))
ok = 1;
dh_free(dh);
}
return ok;
}
static int dh_pub_print(void *ctx, void *dh, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_dh(out, dh, dh_print_pub);
BIO_free(out);
return ret;
}
const OSSL_DISPATCH dh_pub_der_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_pub_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_pub_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_pub_der_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_pub_der },
{ 0, NULL }
};
const OSSL_DISPATCH dh_pub_pem_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_pub_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_pub_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dh_pub_pem_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_pub_pem },
{ 0, NULL }
};
const OSSL_DISPATCH dh_pub_text_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dh_pub_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dh_pub_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dh_pub_print },
{ OSSL_FUNC_ENCODER_ENCODE_DATA,
(void (*)(void))dh_pub_print_data },
{ 0, NULL }
};

View File

@ -1,173 +0,0 @@
/*
* Copyright 2019-2020 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
*/
/*
* DSA low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/dsa.h>
#include <openssl/err.h>
#include "prov/bio.h" /* ossl_prov_bio_printf() */
#include "prov/implementations.h" /* rsa_keymgmt_functions */
#include "prov/providercommonerr.h" /* PROV_R_BN_ERROR */
#include "encoder_local.h"
#include "internal/ffc.h"
#include "crypto/dsa.h"
OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dsa_new(void)
{
return ossl_prov_get_keymgmt_new(dsa_keymgmt_functions);
}
OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dsa_free(void)
{
return ossl_prov_get_keymgmt_free(dsa_keymgmt_functions);
}
OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dsa_import(void)
{
return ossl_prov_get_keymgmt_import(dsa_keymgmt_functions);
}
int ossl_prov_print_dsa(BIO *out, DSA *dsa, enum dsa_print_type type)
{
const char *type_label = NULL;
const BIGNUM *priv_key = NULL, *pub_key = NULL;
const BIGNUM *p = NULL;
switch (type) {
case dsa_print_priv:
type_label = "Private-Key";
break;
case dsa_print_pub:
type_label = "Public-Key";
break;
case dsa_print_params:
type_label = "DSA-Parameters";
break;
}
if (type == dsa_print_priv) {
priv_key = DSA_get0_priv_key(dsa);
if (priv_key == NULL)
goto null_err;
}
if (type == dsa_print_priv || type == dsa_print_pub) {
pub_key = DSA_get0_pub_key(dsa);
if (pub_key == NULL)
goto null_err;
}
p = DSA_get0_p(dsa);
if (p == NULL)
goto null_err;
if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0)
goto err;
if (priv_key != NULL
&& !ossl_prov_print_labeled_bignum(out, "priv:", priv_key))
goto err;
if (pub_key != NULL
&& !ossl_prov_print_labeled_bignum(out, "pub: ", pub_key))
goto err;
if (!ffc_params_prov_print(out, dsa_get0_params(dsa)))
goto err;
return 1;
err:
return 0;
null_err:
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
goto err;
}
int ossl_prov_prepare_dsa_params(const void *dsa, int nid,
void **pstr, int *pstrtype)
{
ASN1_STRING *params = ASN1_STRING_new();
if (params == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return 0;
}
params->length = i2d_DSAparams(dsa, &params->data);
if (params->length <= 0) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
ASN1_STRING_free(params);
return 0;
}
*pstrtype = V_ASN1_SEQUENCE;
*pstr = params;
return 1;
}
int ossl_prov_prepare_all_dsa_params(const void *dsa, int nid,
void **pstr, int *pstrtype)
{
const BIGNUM *p = DSA_get0_p(dsa);
const BIGNUM *q = DSA_get0_q(dsa);
const BIGNUM *g = DSA_get0_g(dsa);
if (p != NULL && q != NULL && g != NULL)
return ossl_prov_prepare_dsa_params(dsa, nid, pstr, pstrtype);
*pstr = NULL;
*pstrtype = V_ASN1_UNDEF;
return 1;
}
int ossl_prov_dsa_pub_to_der(const void *dsa, unsigned char **pder)
{
const BIGNUM *bn = NULL;
ASN1_INTEGER *pub_key = NULL;
int ret;
if ((bn = DSA_get0_pub_key(dsa)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
return 0;
}
if ((pub_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
return 0;
}
ret = i2d_ASN1_INTEGER(pub_key, pder);
ASN1_STRING_clear_free(pub_key);
return ret;
}
int ossl_prov_dsa_priv_to_der(const void *dsa, unsigned char **pder)
{
const BIGNUM *bn = NULL;
ASN1_INTEGER *priv_key = NULL;
int ret;
if ((bn = DSA_get0_priv_key(dsa)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
return 0;
}
if ((priv_key = BN_to_ASN1_INTEGER(bn, NULL)) == NULL) {
ERR_raise(ERR_LIB_PROV, PROV_R_BN_ERROR);
return 0;
}
ret = i2d_ASN1_INTEGER(priv_key, pder);
ASN1_STRING_clear_free(priv_key);
return ret;
}

View File

@ -1,187 +0,0 @@
/*
* Copyright 2019-2020 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
*/
/*
* DSA low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/core_dispatch.h>
#include <openssl/pem.h>
#include <openssl/dsa.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/providercommonerr.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
static OSSL_FUNC_encoder_newctx_fn dsa_param_newctx;
static OSSL_FUNC_encoder_freectx_fn dsa_param_freectx;
static OSSL_FUNC_encoder_encode_data_fn dsa_param_der_data;
static OSSL_FUNC_encoder_encode_object_fn dsa_param_der;
static OSSL_FUNC_encoder_encode_data_fn dsa_param_pem_data;
static OSSL_FUNC_encoder_encode_object_fn dsa_param_pem;
static OSSL_FUNC_encoder_encode_data_fn dsa_param_print_data;
static OSSL_FUNC_encoder_encode_object_fn dsa_param_print;
/* Parameters : context */
/*
* There's no specific implementation context, so we use the provider context
*/
static void *dsa_param_newctx(void *provctx)
{
return provctx;
}
static void dsa_param_freectx(void *ctx)
{
}
/* Public key : DER */
static int dsa_param_der_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
int ok = 0;
if (dsa_import != NULL) {
DSA *dsa;
/* ctx == provctx */
if ((dsa = dsa_new(ctx)) != NULL
&& dsa_import(dsa, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, params)
&& dsa_param_der(ctx, dsa, out, cb, cbarg))
ok = 1;
dsa_free(dsa);
}
return ok;
}
static int dsa_param_der(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = i2d_DSAparams_bio(out, dsa);
BIO_free(out);
return ret;
}
/* Public key : PEM */
static int dsa_param_pem_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
int ok = 0;
if (dsa_import != NULL) {
DSA *dsa;
/* ctx == provctx */
if ((dsa = dsa_new(ctx)) != NULL
&& dsa_import(dsa, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, params)
&& dsa_param_pem(ctx, dsa, out, cb, cbarg))
ok = 1;
dsa_free(dsa);
}
return ok;
}
static int dsa_param_pem(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = PEM_write_bio_DSAparams(out, dsa);
BIO_free(out);
return ret;
}
static int dsa_param_print_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
int ok = 0;
if (dsa_import != NULL) {
DSA *dsa;
/* ctx == provctx */
if ((dsa = dsa_new(ctx)) != NULL
&& dsa_import(dsa, OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS, params)
&& dsa_param_print(ctx, dsa, out, cb, cbarg))
ok = 1;
dsa_free(dsa);
}
return ok;
}
static int dsa_param_print(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_dsa(out, dsa, dsa_print_params);
BIO_free(out);
return ret;
}
const OSSL_DISPATCH dsa_param_der_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_param_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_param_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dsa_param_der_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_param_der },
{ 0, NULL }
};
const OSSL_DISPATCH dsa_param_pem_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_param_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_param_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dsa_param_pem_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_param_pem },
{ 0, NULL }
};
const OSSL_DISPATCH dsa_param_text_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_param_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_param_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_param_print },
{ OSSL_FUNC_ENCODER_ENCODE_DATA,
(void (*)(void))dsa_param_print_data },
{ 0, NULL }
};

View File

@ -1,293 +0,0 @@
/*
* Copyright 2019-2020 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
*/
/*
* DSA low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/dsa.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
#define DSA_SELECT_PRIVATE_IMPORTABLE \
(OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
static OSSL_FUNC_encoder_newctx_fn dsa_priv_newctx;
static OSSL_FUNC_encoder_freectx_fn dsa_priv_freectx;
static OSSL_FUNC_encoder_set_ctx_params_fn dsa_priv_set_ctx_params;
static OSSL_FUNC_encoder_settable_ctx_params_fn dsa_priv_settable_ctx_params;
static OSSL_FUNC_encoder_encode_data_fn dsa_priv_der_data;
static OSSL_FUNC_encoder_encode_object_fn dsa_priv_der;
static OSSL_FUNC_encoder_encode_data_fn dsa_pem_priv_data;
static OSSL_FUNC_encoder_encode_object_fn dsa_pem_priv;
static OSSL_FUNC_encoder_newctx_fn dsa_print_newctx;
static OSSL_FUNC_encoder_freectx_fn dsa_print_freectx;
static OSSL_FUNC_encoder_encode_data_fn dsa_priv_print_data;
static OSSL_FUNC_encoder_encode_object_fn dsa_priv_print;
/*
* Context used for private key encoding.
*/
struct dsa_priv_ctx_st {
void *provctx;
struct pkcs8_encrypt_ctx_st sc;
};
/* Private key : context */
static void *dsa_priv_newctx(void *provctx)
{
struct dsa_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx != NULL) {
ctx->provctx = provctx;
/* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
ctx->sc.pbe_nid = -1;
}
return ctx;
}
static void dsa_priv_freectx(void *vctx)
{
struct dsa_priv_ctx_st *ctx = vctx;
EVP_CIPHER_free(ctx->sc.cipher);
OPENSSL_free(ctx->sc.cipher_pass);
OPENSSL_free(ctx);
}
static const OSSL_PARAM *dsa_priv_settable_ctx_params(ossl_unused void *provctx)
{
static const OSSL_PARAM settables[] = {
OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
OSSL_PARAM_END,
};
return settables;
}
static int dsa_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
struct dsa_priv_ctx_st *ctx = vctx;
const OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
!= NULL) {
const OSSL_PARAM *propsp =
OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
const char *props = NULL;
if (p->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
props = (propsp != NULL ? propsp->data : NULL);
EVP_CIPHER_free(ctx->sc.cipher);
ctx->sc.cipher_intent = p->data != NULL;
if (p->data != NULL
&& ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props))
== NULL))
return 0;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
!= NULL) {
OPENSSL_free(ctx->sc.cipher_pass);
ctx->sc.cipher_pass = NULL;
if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
&ctx->sc.cipher_pass_length))
return 0;
}
return 1;
}
/* Private key : DER */
static int dsa_priv_der_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct dsa_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
int ok = 0;
if (dsa_import != NULL) {
DSA *dsa;
if ((dsa = dsa_new(ctx->provctx)) != NULL
&& dsa_import(dsa, DSA_SELECT_PRIVATE_IMPORTABLE, params)
&& dsa_priv_der(ctx, dsa, out, cb, cbarg))
ok = 1;
dsa_free(dsa);
}
return ok;
}
static int dsa_priv_der(void *vctx, void *dsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct dsa_priv_ctx_st *ctx = vctx;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
int ret;
if (out == NULL)
return 0;
ctx->sc.cb = cb;
ctx->sc.cbarg = cbarg;
ret = ossl_prov_write_priv_der_from_obj(out, dsa, EVP_PKEY_DSA,
ossl_prov_prepare_dsa_params,
ossl_prov_dsa_priv_to_der,
&ctx->sc);
BIO_free(out);
return ret;
}
/* Private key : PEM */
static int dsa_pem_priv_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct dsa_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
int ok = 0;
if (dsa_import != NULL) {
DSA *dsa;
if ((dsa = dsa_new(ctx->provctx)) != NULL
&& dsa_import(dsa, DSA_SELECT_PRIVATE_IMPORTABLE, params)
&& dsa_pem_priv(ctx, dsa, out, cb, cbarg))
ok = 1;
dsa_free(dsa);
}
return ok;
}
static int dsa_pem_priv(void *vctx, void *dsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct dsa_priv_ctx_st *ctx = vctx;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
int ret;
if (out == NULL)
return 0;
ctx->sc.cb = cb;
ctx->sc.cbarg = cbarg;
ret = ossl_prov_write_priv_pem_from_obj(out, dsa, EVP_PKEY_DSA,
ossl_prov_prepare_dsa_params,
ossl_prov_dsa_priv_to_der,
&ctx->sc);
BIO_free(out);
return ret;
}
/*
* There's no specific print context, so we use the provider context
*/
static void *dsa_print_newctx(void *provctx)
{
return provctx;
}
static void dsa_print_freectx(void *ctx)
{
}
static int dsa_priv_print_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct dsa_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
int ok = 0;
if (dsa_import != NULL) {
DSA *dsa;
if ((dsa = dsa_new(ctx->provctx)) != NULL
&& dsa_import(dsa, DSA_SELECT_PRIVATE_IMPORTABLE, params)
&& dsa_priv_print(ctx, dsa, out, cb, cbarg))
ok = 1;
dsa_free(dsa);
}
return ok;
}
static int dsa_priv_print(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_dsa(out, dsa, dsa_print_priv);
BIO_free(out);
return ret;
}
const OSSL_DISPATCH dsa_priv_der_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_priv_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_priv_freectx },
{ OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
(void (*)(void))dsa_priv_set_ctx_params },
{ OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
(void (*)(void))dsa_priv_settable_ctx_params },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dsa_priv_der_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_priv_der },
{ 0, NULL }
};
const OSSL_DISPATCH dsa_priv_pem_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_priv_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_priv_freectx },
{ OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
(void (*)(void))dsa_priv_set_ctx_params },
{ OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
(void (*)(void))dsa_priv_settable_ctx_params },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dsa_pem_priv_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_pem_priv },
{ 0, NULL }
};
const OSSL_DISPATCH dsa_priv_text_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_print_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_print_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_priv_print },
{ OSSL_FUNC_ENCODER_ENCODE_DATA,
(void (*)(void))dsa_priv_print_data },
{ 0, NULL }
};

View File

@ -1,205 +0,0 @@
/*
* Copyright 2019-2020 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
*/
/*
* DSA low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/core_dispatch.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/dsa.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
#define DSA_SELECT_PUBLIC_IMPORTABLE \
(OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS)
static OSSL_FUNC_encoder_newctx_fn dsa_pub_newctx;
static OSSL_FUNC_encoder_freectx_fn dsa_pub_freectx;
static OSSL_FUNC_encoder_encode_data_fn dsa_pub_der_data;
static OSSL_FUNC_encoder_encode_object_fn dsa_pub_der;
static OSSL_FUNC_encoder_encode_data_fn dsa_pub_pem_data;
static OSSL_FUNC_encoder_encode_object_fn dsa_pub_pem;
static OSSL_FUNC_encoder_encode_data_fn dsa_pub_print_data;
static OSSL_FUNC_encoder_encode_object_fn dsa_pub_print;
/* Public key : context */
/*
* There's no specific implementation context, so we use the provider context
*/
static void *dsa_pub_newctx(void *provctx)
{
return provctx;
}
static void dsa_pub_freectx(void *ctx)
{
}
/* Public key : DER */
static int dsa_pub_der_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
int ok = 0;
if (dsa_import != NULL) {
DSA *dsa;
/* ctx == provctx */
if ((dsa = dsa_new(ctx)) != NULL
&& dsa_import(dsa, DSA_SELECT_PUBLIC_IMPORTABLE, params)
&& dsa_pub_der(ctx, dsa, out, cb, cbarg))
ok = 1;
dsa_free(dsa);
}
return ok;
}
static int dsa_pub_der(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
/*
* TODO(v3.0) implement setting save_parameters, see dsa_pub_encode()
* in crypto/dsa/dsa_ameth.c
*/
int save_parameters = 1;
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret =
save_parameters
? ossl_prov_write_pub_der_from_obj(out, dsa, EVP_PKEY_DSA,
ossl_prov_prepare_all_dsa_params,
ossl_prov_dsa_pub_to_der)
: ossl_prov_write_pub_der_from_obj(out, dsa, EVP_PKEY_DSA,
ossl_prov_prepare_dsa_params,
ossl_prov_dsa_pub_to_der);
BIO_free(out);
return ret;
}
/* Public key : PEM */
static int dsa_pub_pem_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
int ok = 0;
if (dsa_import != NULL) {
DSA *dsa;
/* ctx == provctx */
if ((dsa = dsa_new(ctx)) != NULL
&& dsa_import(dsa, DSA_SELECT_PUBLIC_IMPORTABLE, params)
&& dsa_pub_pem(ctx, dsa, out, cb, cbarg))
ok = 1;
dsa_free(dsa);
}
return ok;
}
static int dsa_pub_pem(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_write_pub_pem_from_obj(out, dsa, EVP_PKEY_DSA,
ossl_prov_prepare_dsa_params,
ossl_prov_dsa_pub_to_der);
BIO_free(out);
return ret;
}
static int dsa_pub_print_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *dsa_new = ossl_prov_get_keymgmt_dsa_new();
OSSL_FUNC_keymgmt_free_fn *dsa_free = ossl_prov_get_keymgmt_dsa_free();
OSSL_FUNC_keymgmt_import_fn *dsa_import = ossl_prov_get_keymgmt_dsa_import();
int ok = 0;
if (dsa_import != NULL) {
DSA *dsa;
/* ctx == provctx */
if ((dsa = dsa_new(ctx)) != NULL
&& dsa_import(dsa, DSA_SELECT_PUBLIC_IMPORTABLE, params)
&& dsa_pub_print(ctx, dsa, out, cb, cbarg))
ok = 1;
dsa_free(dsa);
}
return ok;
}
static int dsa_pub_print(void *ctx, void *dsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_dsa(out, dsa, dsa_print_pub);
BIO_free(out);
return ret;
}
const OSSL_DISPATCH dsa_pub_der_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_pub_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_pub_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dsa_pub_der_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_pub_der },
{ 0, NULL }
};
const OSSL_DISPATCH dsa_pub_pem_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_pub_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_pub_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))dsa_pub_pem_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_pub_pem },
{ 0, NULL }
};
const OSSL_DISPATCH dsa_pub_text_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))dsa_pub_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))dsa_pub_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))dsa_pub_print },
{ OSSL_FUNC_ENCODER_ENCODE_DATA,
(void (*)(void))dsa_pub_print_data },
{ 0, NULL }
};

View File

@ -1,293 +0,0 @@
/*
* Copyright 2020 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
*/
#include <openssl/err.h>
#include "crypto/ec.h"
#include "prov/bio.h" /* ossl_prov_bio_printf() */
#include "prov/implementations.h" /* ec_keymgmt_functions */
#include "prov/providercommonerr.h" /* PROV_R_MISSING_OID */
#include "encoder_local.h"
void ec_get_new_free_import(OSSL_FUNC_keymgmt_new_fn **ec_new,
OSSL_FUNC_keymgmt_free_fn **ec_free,
OSSL_FUNC_keymgmt_import_fn **ec_import)
{
*ec_new = ossl_prov_get_keymgmt_new(ec_keymgmt_functions);
*ec_free = ossl_prov_get_keymgmt_free(ec_keymgmt_functions);
*ec_import = ossl_prov_get_keymgmt_import(ec_keymgmt_functions);
}
static int ossl_prov_print_ec_param_explicit_curve(BIO *out,
const EC_GROUP *group,
BN_CTX *ctx)
{
const char *plabel = "Prime:";
BIGNUM *p = NULL, *a = NULL, *b = NULL;
p = BN_CTX_get(ctx);
a = BN_CTX_get(ctx);
b = BN_CTX_get(ctx);
if (b == NULL
|| !EC_GROUP_get_curve(group, p, a, b, ctx))
return 0;
if (EC_GROUP_get_field_type(group) == NID_X9_62_characteristic_two_field) {
int basis_type = EC_GROUP_get_basis_type(group);
/* print the 'short name' of the base type OID */
if (basis_type == NID_undef
|| BIO_printf(out, "Basis Type: %s\n", OBJ_nid2sn(basis_type)) <= 0)
return 0;
plabel = "Polynomial:";
}
return ossl_prov_print_labeled_bignum(out, plabel, p)
&& ossl_prov_print_labeled_bignum(out, "A: ", a)
&& ossl_prov_print_labeled_bignum(out, "B: ", b);
}
static int ossl_prov_print_ec_param_explicit_gen(BIO *out,
const EC_GROUP *group,
BN_CTX *ctx)
{
const EC_POINT *point = NULL;
BIGNUM *gen = NULL;
const char *glabel = NULL;
point_conversion_form_t form;
form = EC_GROUP_get_point_conversion_form(group);
point = EC_GROUP_get0_generator(group);
gen = BN_CTX_get(ctx);
if (gen == NULL
|| point == NULL
|| EC_POINT_point2bn(group, point, form, gen, ctx) == NULL)
return 0;
switch (form) {
case POINT_CONVERSION_COMPRESSED:
glabel = "Generator (compressed):";
break;
case POINT_CONVERSION_UNCOMPRESSED:
glabel = "Generator (uncompressed):";
break;
case POINT_CONVERSION_HYBRID:
glabel = "Generator (hybrid):";
break;
default:
return 0;
}
return ossl_prov_print_labeled_bignum(out, glabel, gen);
}
/* Print explicit parameters */
static int ossl_prov_print_ec_param_explicit(BIO *out, const EC_GROUP *group,
OPENSSL_CTX *libctx)
{
int ret = 0, tmp_nid;
BN_CTX *ctx = NULL;
const BIGNUM *order = NULL, *cofactor = NULL;
const unsigned char *seed;
size_t seed_len = 0;
ctx = BN_CTX_new_ex(libctx);
if (ctx == NULL)
return 0;
BN_CTX_start(ctx);
tmp_nid = EC_GROUP_get_field_type(group);
order = EC_GROUP_get0_order(group);
if (order == NULL)
goto err;
seed = EC_GROUP_get0_seed(group);
if (seed != NULL)
seed_len = EC_GROUP_get_seed_len(group);
cofactor = EC_GROUP_get0_cofactor(group);
/* print the 'short name' of the field type */
if (BIO_printf(out, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0
|| !ossl_prov_print_ec_param_explicit_curve(out, group, ctx)
|| !ossl_prov_print_ec_param_explicit_gen(out, group, ctx)
|| !ossl_prov_print_labeled_bignum(out, "Order: ", order)
|| (cofactor != NULL
&& !ossl_prov_print_labeled_bignum(out, "Cofactor: ", cofactor))
|| (seed != NULL
&& !ossl_prov_print_labeled_buf(out, "Seed:", seed, seed_len)))
goto err;
ret = 1;
err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
return ret;
}
static int ossl_prov_print_ec_param(BIO *out, const EC_GROUP *group,
OPENSSL_CTX *libctx)
{
if (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE) {
const char *curve_name;
int curve_nid = EC_GROUP_get_curve_name(group);
/* Explicit parameters */
if (curve_nid == NID_undef)
return 0;
if (BIO_printf(out, "%s: %s\n", "ASN1 OID", OBJ_nid2sn(curve_nid)) <= 0)
return 0;
/* TODO(3.0): Only named curves are currently supported */
curve_name = EC_curve_nid2nist(curve_nid);
return (curve_name == NULL
|| BIO_printf(out, "%s: %s\n", "NIST CURVE", curve_name) > 0);
} else {
return ossl_prov_print_ec_param_explicit(out, group, libctx);
}
}
int ossl_prov_print_eckey(BIO *out, EC_KEY *eckey, enum ec_print_type type)
{
int ret = 0;
const char *type_label = NULL;
unsigned char *priv = NULL, *pub = NULL;
size_t priv_len = 0, pub_len = 0;
const EC_GROUP *group;
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL)
goto null_err;
switch (type) {
case ec_print_priv:
type_label = "Private-Key";
break;
case ec_print_pub:
type_label = "Public-Key";
break;
case ec_print_params:
type_label = "EC-Parameters";
break;
}
if (type == ec_print_priv) {
const BIGNUM *priv_key = EC_KEY_get0_private_key(eckey);
if (priv_key == NULL)
goto null_err;
priv_len = EC_KEY_priv2buf(eckey, &priv);
if (priv_len == 0)
goto err;
}
if (type == ec_print_priv || type == ec_print_pub) {
const EC_POINT *pub_pt = EC_KEY_get0_public_key(eckey);
if (pub_pt == NULL)
goto null_err;
pub_len = EC_KEY_key2buf(eckey, EC_KEY_get_conv_form(eckey), &pub, NULL);
if (pub_len == 0)
goto err;
}
if (BIO_printf(out, "%s: (%d bit)\n", type_label,
EC_GROUP_order_bits(group)) <= 0)
goto err;
if (priv != NULL
&& !ossl_prov_print_labeled_buf(out, "priv:", priv, priv_len))
goto err;
if (pub != NULL
&& !ossl_prov_print_labeled_buf(out, "pub:", pub, pub_len))
goto err;
ret = ossl_prov_print_ec_param(out, group, ec_key_get_libctx(eckey));
err:
OPENSSL_clear_free(priv, priv_len);
OPENSSL_free(pub);
return ret;
null_err:
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
goto err;
}
static int ossl_prov_prepare_ec_explicit_params(const void *eckey,
void **pstr, int *pstrtype)
{
ASN1_STRING *params = ASN1_STRING_new();
if (params == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return 0;
}
params->length = i2d_ECParameters(eckey, &params->data);
if (params->length <= 0) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
ASN1_STRING_free(params);
return 0;
}
*pstrtype = V_ASN1_SEQUENCE;
*pstr = params;
return 1;
}
int ossl_prov_prepare_ec_params(const void *eckey, int nid,
void **pstr, int *pstrtype)
{
int curve_nid;
const EC_GROUP *group = EC_KEY_get0_group(eckey);
ASN1_OBJECT *params = NULL;
if (group == NULL)
return 0;
curve_nid = EC_GROUP_get_curve_name(group);
if (curve_nid != NID_undef) {
params = OBJ_nid2obj(curve_nid);
if (params == NULL)
return 0;
}
if (curve_nid != NID_undef
&& (EC_GROUP_get_asn1_flag(group) & OPENSSL_EC_NAMED_CURVE)) {
if (OBJ_length(params) == 0) {
/* Some curves might not have an associated OID */
ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_OID);
ASN1_OBJECT_free(params);
return 0;
}
*pstr = params;
*pstrtype = V_ASN1_OBJECT;
return 1;
} else {
return ossl_prov_prepare_ec_explicit_params(eckey, pstr, pstrtype);
}
}
int ossl_prov_ec_pub_to_der(const void *eckey, unsigned char **pder)
{
return i2o_ECPublicKey(eckey, pder);
}
int ossl_prov_ec_priv_to_der(const void *veckey, unsigned char **pder)
{
EC_KEY *eckey = (EC_KEY *)veckey;
unsigned int old_flags;
int ret = 0;
/*
* For PKCS8 the curve name appears in the PKCS8_PRIV_KEY_INFO object
* as the pkeyalg->parameter field. (For a named curve this is an OID)
* The pkey field is an octet string that holds the encoded
* ECPrivateKey SEQUENCE with the optional parameters field omitted.
* We omit this by setting the EC_PKEY_NO_PARAMETERS flag.
*/
old_flags = EC_KEY_get_enc_flags(eckey); /* save old flags */
EC_KEY_set_enc_flags(eckey, old_flags | EC_PKEY_NO_PARAMETERS);
ret = i2d_ECPrivateKey(eckey, pder);
EC_KEY_set_enc_flags(eckey, old_flags); /* restore old flags */
return ret; /* return the length of the der encoded data */
}

View File

@ -1,184 +0,0 @@
/*
* Copyright 2020 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
*/
#include <openssl/core_dispatch.h>
#include <openssl/pem.h>
#include <openssl/ec.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/providercommonerr.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
static OSSL_FUNC_encoder_newctx_fn ec_param_newctx;
static OSSL_FUNC_encoder_freectx_fn ec_param_freectx;
static OSSL_FUNC_encoder_encode_data_fn ec_param_der_data;
static OSSL_FUNC_encoder_encode_object_fn ec_param_der;
static OSSL_FUNC_encoder_encode_data_fn ec_param_pem_data;
static OSSL_FUNC_encoder_encode_object_fn ec_param_pem;
static OSSL_FUNC_encoder_encode_data_fn ec_param_print_data;
static OSSL_FUNC_encoder_encode_object_fn ec_param_print;
/* There is no specific implementation context, so use the provider context */
static void *ec_param_newctx(void *provctx)
{
return provctx;
}
static void ec_param_freectx(void *vctx)
{
}
/* Public key : DER */
static int ec_param_der_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *ec_new;
OSSL_FUNC_keymgmt_free_fn *ec_free;
OSSL_FUNC_keymgmt_import_fn *ec_import;
int ok = 0;
ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
if (ec_import != NULL) {
EC_KEY *eckey;
/* vctx == provctx */
if ((eckey = ec_new(vctx)) != NULL
&& ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params)
&& ec_param_der(vctx, eckey, out, cb, cbarg))
ok = 1;
ec_free(eckey);
}
return ok;
}
static int ec_param_der(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(vctx, cout);
int ret;
if (out == NULL)
return 0;
ret = i2d_ECPKParameters_bio(out, EC_KEY_get0_group(eckey));
BIO_free(out);
return ret;
}
/* Public key : PEM */
static int ec_param_pem_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *ec_new;
OSSL_FUNC_keymgmt_free_fn *ec_free;
OSSL_FUNC_keymgmt_import_fn *ec_import;
int ok = 0;
ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
if (ec_import != NULL) {
EC_KEY *eckey;
/* vctx == provctx */
if ((eckey = ec_new(vctx)) != NULL
&& ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params)
&& ec_param_pem(vctx, eckey, out, cb, cbarg))
ok = 1;
ec_free(eckey);
}
return ok;
}
static int ec_param_pem(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(vctx, cout);
int ret;
if (out == NULL)
return 0;
ret = PEM_write_bio_ECPKParameters(out, EC_KEY_get0_group(eckey));
BIO_free(out);
return ret;
}
static int ec_param_print_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *ec_new;
OSSL_FUNC_keymgmt_free_fn *ec_free;
OSSL_FUNC_keymgmt_import_fn *ec_import;
int ok = 0;
ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
if (ec_import != NULL) {
EC_KEY *eckey;
/* vctx == provctx */
if ((eckey = ec_new(vctx)) != NULL
&& ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL_PARAMETERS, params)
&& ec_param_print(vctx, eckey, out, cb, cbarg))
ok = 1;
ec_free(eckey);
}
return ok;
}
static int ec_param_print(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(vctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_eckey(out, eckey, ec_print_params);
BIO_free(out);
return ret;
}
const OSSL_DISPATCH ec_param_der_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_param_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_param_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))ec_param_der_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_param_der },
{ 0, NULL }
};
const OSSL_DISPATCH ec_param_pem_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_param_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_param_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))ec_param_pem_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_param_pem },
{ 0, NULL }
};
const OSSL_DISPATCH ec_param_text_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_param_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_param_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_param_print },
{ OSSL_FUNC_ENCODER_ENCODE_DATA,
(void (*)(void))ec_param_print_data },
{ 0, NULL }
};

View File

@ -1,290 +0,0 @@
/*
* Copyright 2020 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
*/
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/ec.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
static OSSL_FUNC_encoder_newctx_fn ec_priv_newctx;
static OSSL_FUNC_encoder_freectx_fn ec_priv_freectx;
static OSSL_FUNC_encoder_set_ctx_params_fn ec_priv_set_ctx_params;
static OSSL_FUNC_encoder_settable_ctx_params_fn ec_priv_settable_ctx_params;
static OSSL_FUNC_encoder_encode_data_fn ec_priv_der_data;
static OSSL_FUNC_encoder_encode_object_fn ec_priv_der;
static OSSL_FUNC_encoder_encode_data_fn ec_pem_priv_data;
static OSSL_FUNC_encoder_encode_object_fn ec_pem_priv;
static OSSL_FUNC_encoder_newctx_fn ec_print_newctx;
static OSSL_FUNC_encoder_freectx_fn ec_print_freectx;
static OSSL_FUNC_encoder_encode_data_fn ec_priv_print_data;
static OSSL_FUNC_encoder_encode_object_fn ec_priv_print;
/*
* Context used for private key encoding.
*/
struct ec_priv_ctx_st {
void *provctx;
struct pkcs8_encrypt_ctx_st sc;
};
/* Private key : context */
static void *ec_priv_newctx(void *provctx)
{
struct ec_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx != NULL) {
ctx->provctx = provctx;
/* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
ctx->sc.pbe_nid = -1;
}
return ctx;
}
static void ec_priv_freectx(void *vctx)
{
struct ec_priv_ctx_st *ctx = vctx;
EVP_CIPHER_free(ctx->sc.cipher);
OPENSSL_free(ctx->sc.cipher_pass);
OPENSSL_free(ctx);
}
static const OSSL_PARAM *ec_priv_settable_ctx_params(ossl_unused void *provctx)
{
static const OSSL_PARAM settables[] = {
OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
OSSL_PARAM_END,
};
return settables;
}
static int ec_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
struct ec_priv_ctx_st *ctx = vctx;
const OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
!= NULL) {
const OSSL_PARAM *propsp =
OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
const char *props = NULL;
if (p->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
props = (propsp != NULL ? propsp->data : NULL);
EVP_CIPHER_free(ctx->sc.cipher);
ctx->sc.cipher_intent = p->data != NULL;
if (p->data != NULL
&& ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props))
== NULL))
return 0;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
!= NULL) {
OPENSSL_free(ctx->sc.cipher_pass);
ctx->sc.cipher_pass = NULL;
if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
&ctx->sc.cipher_pass_length))
return 0;
}
return 1;
}
/* Private key : DER */
static int ec_priv_der_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ec_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *ec_new;
OSSL_FUNC_keymgmt_free_fn *ec_free;
OSSL_FUNC_keymgmt_import_fn *ec_import;
int ok = 0;
ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
if (ec_import != NULL) {
EC_KEY *eckey;
if ((eckey = ec_new(ctx->provctx)) != NULL
&& ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL, params)
&& ec_priv_der(ctx, eckey, out, cb, cbarg))
ok = 1;
ec_free(eckey);
}
return ok;
}
static int ec_priv_der(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ec_priv_ctx_st *ctx = vctx;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
int ret;
if (out == NULL)
return 0;
ctx->sc.cb = cb;
ctx->sc.cbarg = cbarg;
ret = ossl_prov_write_priv_der_from_obj(out, eckey, EVP_PKEY_EC,
ossl_prov_prepare_ec_params,
ossl_prov_ec_priv_to_der,
&ctx->sc);
BIO_free(out);
return ret;
}
/* Private key : PEM */
static int ec_pem_priv_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ec_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *ec_new;
OSSL_FUNC_keymgmt_free_fn *ec_free;
OSSL_FUNC_keymgmt_import_fn *ec_import;
int ok = 0;
ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
if (ec_import != NULL) {
EC_KEY *eckey;
if ((eckey = ec_new(ctx->provctx)) != NULL
&& ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL, params)
&& ec_pem_priv(ctx, eckey, out, cb, cbarg))
ok = 1;
ec_free(eckey);
}
return ok;
}
static int ec_pem_priv(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ec_priv_ctx_st *ctx = vctx;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
int ret;
if (out == NULL)
return 0;
ctx->sc.cb = cb;
ctx->sc.cbarg = cbarg;
ret = ossl_prov_write_priv_pem_from_obj(out, eckey, EVP_PKEY_EC,
ossl_prov_prepare_ec_params,
ossl_prov_ec_priv_to_der,
&ctx->sc);
BIO_free(out);
return ret;
}
/*
* There's no specific print context, so we use the provider context
*/
static void *ec_print_newctx(void *provctx)
{
return provctx;
}
static void ec_print_freectx(void *ctx)
{
}
static int ec_priv_print_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ec_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *ec_new;
OSSL_FUNC_keymgmt_free_fn *ec_free;
OSSL_FUNC_keymgmt_import_fn *ec_import;
int ok = 0;
ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
if (ec_import != NULL) {
EC_KEY *eckey;
if ((eckey = ec_new(ctx->provctx)) != NULL
&& ec_import(eckey, OSSL_KEYMGMT_SELECT_ALL, params)
&& ec_priv_print(ctx, eckey, out, cb, cbarg))
ok = 1;
ec_free(eckey);
}
return ok;
}
static int ec_priv_print(void *ctx, void *eckey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_eckey(out, eckey, ec_print_priv);
BIO_free(out);
return ret;
}
const OSSL_DISPATCH ec_priv_der_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_priv_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_priv_freectx },
{ OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
(void (*)(void))ec_priv_set_ctx_params },
{ OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
(void (*)(void))ec_priv_settable_ctx_params },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))ec_priv_der_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_priv_der },
{ 0, NULL }
};
const OSSL_DISPATCH ec_priv_pem_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_priv_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_priv_freectx },
{ OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
(void (*)(void))ec_priv_set_ctx_params },
{ OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
(void (*)(void))ec_priv_settable_ctx_params },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))ec_pem_priv_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_pem_priv },
{ 0, NULL }
};
const OSSL_DISPATCH ec_priv_text_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_print_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_print_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_priv_print },
{ OSSL_FUNC_ENCODER_ENCODE_DATA,
(void (*)(void))ec_priv_print_data },
{ 0, NULL }
};

View File

@ -1,192 +0,0 @@
/*
* Copyright 2020 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
*/
#include <openssl/core_dispatch.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
#define EC_SELECT_PUBLIC_IMPORTABLE \
OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS
static OSSL_FUNC_encoder_newctx_fn ec_pub_newctx;
static OSSL_FUNC_encoder_freectx_fn ec_pub_freectx;
static OSSL_FUNC_encoder_encode_data_fn ec_pub_der_data;
static OSSL_FUNC_encoder_encode_object_fn ec_pub_der;
static OSSL_FUNC_encoder_encode_data_fn ec_pub_pem_data;
static OSSL_FUNC_encoder_encode_object_fn ec_pub_pem;
static OSSL_FUNC_encoder_encode_data_fn ec_pub_print_data;
static OSSL_FUNC_encoder_encode_object_fn ec_pub_print;
/* Public key : context */
/*
* There's no specific implementation context, so we use the provider context
*/
static void *ec_pub_newctx(void *provctx)
{
return provctx;
}
static void ec_pub_freectx(void *ctx)
{
}
/* Public key : DER */
static int ec_pub_der_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *ec_new;
OSSL_FUNC_keymgmt_free_fn *ec_free;
OSSL_FUNC_keymgmt_import_fn *ec_import;
int ok = 0;
ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
if (ec_import != NULL) {
EC_KEY *eckey;
/* vctx == provctx */
if ((eckey = ec_new(vctx)) != NULL
&& ec_import(eckey, EC_SELECT_PUBLIC_IMPORTABLE, params)
&& ec_pub_der(vctx, eckey, out, cb, cbarg))
ok = 1;
ec_free(eckey);
}
return ok;
}
static int ec_pub_der(void *ctx, void *eckey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_write_pub_der_from_obj(out, eckey, EVP_PKEY_EC,
ossl_prov_prepare_ec_params,
ossl_prov_ec_pub_to_der);
BIO_free(out);
return ret;
}
/* Public key : PEM */
static int ec_pub_pem_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *ec_new;
OSSL_FUNC_keymgmt_free_fn *ec_free;
OSSL_FUNC_keymgmt_import_fn *ec_import;
int ok = 0;
ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
if (ec_import != NULL) {
EC_KEY *eckey;
/* ctx == provctx */
if ((eckey = ec_new(vctx)) != NULL
&& ec_import(eckey, EC_SELECT_PUBLIC_IMPORTABLE, params)
&& ec_pub_pem(vctx, eckey, out, cb, cbarg))
ok = 1;
ec_free(eckey);
}
return ok;
}
static int ec_pub_pem(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(vctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_write_pub_pem_from_obj(out, eckey, EVP_PKEY_EC,
ossl_prov_prepare_ec_params,
ossl_prov_ec_pub_to_der);
BIO_free(out);
return ret;
}
static int ec_pub_print_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *ec_new;
OSSL_FUNC_keymgmt_free_fn *ec_free;
OSSL_FUNC_keymgmt_import_fn *ec_import;
int ok = 0;
ec_get_new_free_import(&ec_new, &ec_free, &ec_import);
if (ec_import != NULL) {
EC_KEY *eckey;
/* ctx == provctx */
if ((eckey = ec_new(vctx)) != NULL
&& ec_import(eckey, EC_SELECT_PUBLIC_IMPORTABLE, params)
&& ec_pub_print(vctx, eckey, out, cb, cbarg))
ok = 1;
ec_free(eckey);
}
return ok;
}
static int ec_pub_print(void *vctx, void *eckey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(vctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_eckey(out, eckey, ec_print_pub);
BIO_free(out);
return ret;
}
const OSSL_DISPATCH ec_pub_der_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_pub_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_pub_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))ec_pub_der_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_pub_der },
{ 0, NULL }
};
const OSSL_DISPATCH ec_pub_pem_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_pub_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_pub_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))ec_pub_pem_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_pub_pem },
{ 0, NULL }
};
const OSSL_DISPATCH ec_pub_text_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))ec_pub_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ec_pub_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))ec_pub_print },
{ OSSL_FUNC_ENCODER_ENCODE_DATA,
(void (*)(void))ec_pub_print_data },
{ 0, NULL }
};

View File

@ -1,145 +0,0 @@
/*
* Copyright 2020 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
*/
#include <openssl/err.h>
#include "crypto/ecx.h"
#include "prov/bio.h" /* ossl_prov_bio_printf() */
#include "prov/implementations.h" /* ecx_keymgmt_functions */
#include "encoder_local.h"
void ecx_get_new_free_import(ECX_KEY_TYPE type,
OSSL_FUNC_keymgmt_new_fn **ecx_new,
OSSL_FUNC_keymgmt_free_fn **ecx_free,
OSSL_FUNC_keymgmt_import_fn **ecx_import)
{
if (type == ECX_KEY_TYPE_X25519) {
*ecx_new = ossl_prov_get_keymgmt_new(x25519_keymgmt_functions);
*ecx_free = ossl_prov_get_keymgmt_free(x25519_keymgmt_functions);
*ecx_import = ossl_prov_get_keymgmt_import(x25519_keymgmt_functions);
} else if (type == ECX_KEY_TYPE_X448) {
*ecx_new = ossl_prov_get_keymgmt_new(x448_keymgmt_functions);
*ecx_free = ossl_prov_get_keymgmt_free(x448_keymgmt_functions);
*ecx_import = ossl_prov_get_keymgmt_import(x448_keymgmt_functions);
} else if (type == ECX_KEY_TYPE_ED25519) {
*ecx_new = ossl_prov_get_keymgmt_new(ed25519_keymgmt_functions);
*ecx_free = ossl_prov_get_keymgmt_free(ed25519_keymgmt_functions);
*ecx_import = ossl_prov_get_keymgmt_import(ed25519_keymgmt_functions);
} else if (type == ECX_KEY_TYPE_ED448) {
*ecx_new = ossl_prov_get_keymgmt_new(ed448_keymgmt_functions);
*ecx_free = ossl_prov_get_keymgmt_free(ed448_keymgmt_functions);
*ecx_import = ossl_prov_get_keymgmt_import(ed448_keymgmt_functions);
} else {
*ecx_new = NULL;
*ecx_free = NULL;
*ecx_import = NULL;
}
}
int ossl_prov_print_ecx(BIO *out, ECX_KEY *ecxkey, enum ecx_print_type type)
{
const char *type_label = NULL;
switch (type) {
case ecx_print_priv:
switch (ecxkey->type) {
case ECX_KEY_TYPE_X25519:
type_label = "X25519 Private-Key";
break;
case ECX_KEY_TYPE_X448:
type_label = "X448 Private-Key";
break;
case ECX_KEY_TYPE_ED25519:
type_label = "ED25519 Private-Key";
break;
case ECX_KEY_TYPE_ED448:
type_label = "ED448 Private-Key";
break;
}
break;
case ecx_print_pub:
switch (ecxkey->type) {
case ECX_KEY_TYPE_X25519:
type_label = "X25519 Public-Key";
break;
case ECX_KEY_TYPE_X448:
type_label = "X448 Public-Key";
break;
case ECX_KEY_TYPE_ED25519:
type_label = "ED25519 Public-Key";
break;
case ECX_KEY_TYPE_ED448:
type_label = "ED448 Public-Key";
break;
}
break;
}
if (type == ecx_print_priv && ecxkey->privkey == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (BIO_printf(out, "%s:\n", type_label) <= 0)
return 0;
if (type == ecx_print_priv
&& !ossl_prov_print_labeled_buf(out, "priv:", ecxkey->privkey,
ecxkey->keylen))
return 0;
if (!ossl_prov_print_labeled_buf(out, "pub:", ecxkey->pubkey,
ecxkey->keylen))
return 0;
return 1;
}
int ossl_prov_ecx_pub_to_der(const void *vecxkey, unsigned char **pder)
{
const ECX_KEY *ecxkey = vecxkey;
unsigned char *keyblob;
if (ecxkey == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
keyblob = OPENSSL_memdup(ecxkey->pubkey, ecxkey->keylen);
if (keyblob == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return 0;
}
*pder = keyblob;
return ecxkey->keylen;
}
int ossl_prov_ecx_priv_to_der(const void *vecxkey, unsigned char **pder)
{
const ECX_KEY *ecxkey = vecxkey;
ASN1_OCTET_STRING oct;
int keybloblen;
if (ecxkey == NULL || ecxkey->privkey == NULL) {
ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
oct.data = ecxkey->privkey;
oct.length = ecxkey->keylen;
oct.flags = 0;
keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder);
if (keybloblen < 0) {
ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
return 0;
}
return keybloblen;
}

View File

@ -1,307 +0,0 @@
/*
* Copyright 2020 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
*/
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include "crypto/ecx.h"
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
static OSSL_FUNC_encoder_newctx_fn x25519_priv_newctx;
static OSSL_FUNC_encoder_newctx_fn x448_priv_newctx;
static OSSL_FUNC_encoder_newctx_fn ed25519_priv_newctx;
static OSSL_FUNC_encoder_newctx_fn ed448_priv_newctx;
static OSSL_FUNC_encoder_freectx_fn ecx_priv_freectx;
static OSSL_FUNC_encoder_set_ctx_params_fn ecx_priv_set_ctx_params;
static OSSL_FUNC_encoder_settable_ctx_params_fn ecx_priv_settable_ctx_params;
static OSSL_FUNC_encoder_encode_data_fn ecx_priv_der_data;
static OSSL_FUNC_encoder_encode_object_fn ecx_priv_der;
static OSSL_FUNC_encoder_encode_data_fn ecx_priv_pem_data;
static OSSL_FUNC_encoder_encode_object_fn ecx_priv_pem;
static OSSL_FUNC_encoder_encode_data_fn ecx_priv_print_data;
static OSSL_FUNC_encoder_encode_object_fn ecx_priv_print;
/*
* Context used for private key encoding.
*/
struct ecx_priv_ctx_st {
void *provctx;
struct pkcs8_encrypt_ctx_st sc;
ECX_KEY_TYPE type;
};
/* Private key : context */
static void *ecx_priv_newctx(void *provctx, ECX_KEY_TYPE type)
{
struct ecx_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx != NULL) {
ctx->provctx = provctx;
/* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
ctx->sc.pbe_nid = -1;
ctx->type = type;
}
return ctx;
}
static void *x25519_priv_newctx(void *provctx)
{
return ecx_priv_newctx(provctx, ECX_KEY_TYPE_X25519);
}
static void *x448_priv_newctx(void *provctx)
{
return ecx_priv_newctx(provctx, ECX_KEY_TYPE_X448);
}
static void *ed25519_priv_newctx(void *provctx)
{
return ecx_priv_newctx(provctx, ECX_KEY_TYPE_ED25519);
}
static void *ed448_priv_newctx(void *provctx)
{
return ecx_priv_newctx(provctx, ECX_KEY_TYPE_ED448);
}
static void ecx_priv_freectx(void *vctx)
{
struct ecx_priv_ctx_st *ctx = vctx;
EVP_CIPHER_free(ctx->sc.cipher);
OPENSSL_free(ctx->sc.cipher_pass);
OPENSSL_free(ctx);
}
static const OSSL_PARAM *ecx_priv_settable_ctx_params(ossl_unused void *provctx)
{
static const OSSL_PARAM settables[] = {
OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
OSSL_PARAM_END,
};
return settables;
}
static int ecx_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
struct ecx_priv_ctx_st *ctx = vctx;
const OSSL_PARAM *p;
p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER);
if (p != NULL) {
const OSSL_PARAM *propsp =
OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
const char *props;
if (p->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
props = (propsp != NULL ? propsp->data : NULL);
EVP_CIPHER_free(ctx->sc.cipher);
ctx->sc.cipher_intent = p->data != NULL;
if (p->data != NULL
&& ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props))
== NULL))
return 0;
}
p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS);
if (p != NULL) {
OPENSSL_free(ctx->sc.cipher_pass);
ctx->sc.cipher_pass = NULL;
if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
&ctx->sc.cipher_pass_length))
return 0;
}
return 1;
}
/* Private key : DER */
static int ecx_priv_der_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ecx_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *ecx_new;
OSSL_FUNC_keymgmt_free_fn *ecx_free;
OSSL_FUNC_keymgmt_import_fn *ecx_import;
int ok = 0;
ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
if (ecx_import != NULL) {
ECX_KEY *ecxkey;
if ((ecxkey = ecx_new(ctx->provctx)) != NULL
&& ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params)
&& ecx_priv_der(ctx, ecxkey, out, cb, cbarg))
ok = 1;
ecx_free(ecxkey);
}
return ok;
}
static int ecx_priv_der(void *vctx, void *vecxkey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ecx_priv_ctx_st *ctx = vctx;
ECX_KEY *ecxkey = vecxkey;
int ret;
int nid = KEYTYPE2NID(ctx->type);
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
if (out == NULL)
return 0;
ctx->sc.cb = cb;
ctx->sc.cbarg = cbarg;
ret = ossl_prov_write_priv_der_from_obj(out, ecxkey,
nid,
NULL,
ossl_prov_ecx_priv_to_der,
&ctx->sc);
BIO_free(out);
return ret;
}
/* Private key : PEM */
static int ecx_priv_pem_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ecx_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *ecx_new;
OSSL_FUNC_keymgmt_free_fn *ecx_free;
OSSL_FUNC_keymgmt_import_fn *ecx_import;
int ok = 0;
ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
if (ecx_import != NULL) {
ECX_KEY *ecxkey;
if ((ecxkey = ecx_new(ctx->provctx)) != NULL
&& ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params)
&& ecx_priv_pem(ctx->provctx, ecxkey, out, cb, cbarg))
ok = 1;
ecx_free(ecxkey);
}
return ok;
}
static int ecx_priv_pem(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ecx_priv_ctx_st *ctx = vctx;
int ret;
int nid = KEYTYPE2NID(ctx->type);
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
if (out == NULL)
return 0;
ctx->sc.cb = cb;
ctx->sc.cbarg = cbarg;
ret = ossl_prov_write_priv_pem_from_obj(out, ecxkey,
nid,
NULL,
ossl_prov_ecx_priv_to_der,
&ctx->sc);
BIO_free(out);
return ret;
}
static int ecx_priv_print_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ecx_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *ecx_new;
OSSL_FUNC_keymgmt_free_fn *ecx_free;
OSSL_FUNC_keymgmt_import_fn *ecx_import;
int ok = 0;
ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
if (ecx_import != NULL) {
ECX_KEY *ecxkey;
if ((ecxkey = ecx_new(ctx->provctx)) != NULL
&& ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_KEYPAIR, params)
&& ecx_priv_print(ctx, ecxkey, out, cb, cbarg))
ok = 1;
ecx_free(ecxkey);
}
return ok;
}
static int ecx_priv_print(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ecx_priv_ctx_st *ctx = vctx;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_ecx(out, ecxkey, ecx_print_priv);
BIO_free(out);
return ret;
}
#define MAKE_ENCODER_FUNCTIONS(alg, type) \
const OSSL_DISPATCH alg##_priv_##type##_encoder_functions[] = { \
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))alg##_priv_newctx }, \
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ecx_priv_freectx }, \
{ OSSL_FUNC_ENCODER_SET_CTX_PARAMS, \
(void (*)(void))ecx_priv_set_ctx_params }, \
{ OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS, \
(void (*)(void))ecx_priv_settable_ctx_params }, \
{ OSSL_FUNC_ENCODER_ENCODE_DATA, \
(void (*)(void))ecx_priv_##type##_data }, \
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, \
(void (*)(void))ecx_priv_##type }, \
{ 0, NULL } \
};
#define MAKE_ENCODER_FUNCTIONS_GROUP(alg) \
MAKE_ENCODER_FUNCTIONS(alg, der) \
MAKE_ENCODER_FUNCTIONS(alg, pem) \
const OSSL_DISPATCH alg##_priv_print_encoder_functions[] = { \
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))alg##_priv_newctx }, \
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ecx_priv_freectx }, \
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, \
(void (*)(void))ecx_priv_print }, \
{ OSSL_FUNC_ENCODER_ENCODE_DATA, \
(void (*)(void))ecx_priv_print_data }, \
{ 0, NULL } \
};
MAKE_ENCODER_FUNCTIONS_GROUP(x25519)
MAKE_ENCODER_FUNCTIONS_GROUP(x448)
MAKE_ENCODER_FUNCTIONS_GROUP(ed25519)
MAKE_ENCODER_FUNCTIONS_GROUP(ed448)

View File

@ -1,226 +0,0 @@
/*
* Copyright 2020 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
*/
#include <openssl/core_dispatch.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include "crypto/ecx.h"
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
static OSSL_FUNC_encoder_newctx_fn x25519_pub_newctx;
static OSSL_FUNC_encoder_newctx_fn x448_pub_newctx;
static OSSL_FUNC_encoder_newctx_fn ed25519_pub_newctx;
static OSSL_FUNC_encoder_newctx_fn ed448_pub_newctx;
static OSSL_FUNC_encoder_freectx_fn ecx_pub_freectx;
static OSSL_FUNC_encoder_encode_data_fn ecx_pub_der_data;
static OSSL_FUNC_encoder_encode_object_fn ecx_pub_der;
static OSSL_FUNC_encoder_encode_data_fn ecx_pub_pem_data;
static OSSL_FUNC_encoder_encode_object_fn ecx_pub_pem;
static OSSL_FUNC_encoder_encode_data_fn ecx_pub_print_data;
static OSSL_FUNC_encoder_encode_object_fn ecx_pub_print;
/*
* Context used for public key encoding.
*/
struct ecx_pub_ctx_st {
void *provctx;
ECX_KEY_TYPE type;
};
/* Public key : context */
static void *ecx_pub_newctx(void *provctx, ECX_KEY_TYPE type)
{
struct ecx_pub_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx != NULL) {
ctx->provctx = provctx;
ctx->type = type;
}
return ctx;
}
static void *x25519_pub_newctx(void *provctx)
{
return ecx_pub_newctx(provctx, ECX_KEY_TYPE_X25519);
}
static void *x448_pub_newctx(void *provctx)
{
return ecx_pub_newctx(provctx, ECX_KEY_TYPE_X448);
}
static void *ed25519_pub_newctx(void *provctx)
{
return ecx_pub_newctx(provctx, ECX_KEY_TYPE_ED25519);
}
static void *ed448_pub_newctx(void *provctx)
{
return ecx_pub_newctx(provctx, ECX_KEY_TYPE_ED448);
}
static void ecx_pub_freectx(void *ctx)
{
OPENSSL_free(ctx);
}
/* Public key : DER */
static int ecx_pub_der_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ecx_pub_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *ecx_new;
OSSL_FUNC_keymgmt_free_fn *ecx_free;
OSSL_FUNC_keymgmt_import_fn *ecx_import;
int ok = 0;
ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
if (ecx_import != NULL) {
ECX_KEY *ecxkey;
if ((ecxkey = ecx_new(ctx->provctx)) != NULL
&& ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, params)
&& ecx_pub_der(ctx, ecxkey, out, cb, cbarg))
ok = 1;
ecx_free(ecxkey);
}
return ok;
}
static int ecx_pub_der(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ecx_pub_ctx_st *ctx = vctx;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_write_pub_der_from_obj(out, ecxkey,
KEYTYPE2NID(ctx->type),
NULL,
ossl_prov_ecx_pub_to_der);
BIO_free(out);
return ret;
}
/* Public key : PEM */
static int ecx_pub_pem_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ecx_pub_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *ecx_new;
OSSL_FUNC_keymgmt_free_fn *ecx_free;
OSSL_FUNC_keymgmt_import_fn *ecx_import;
int ok = 0;
ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
if (ecx_import != NULL) {
ECX_KEY *ecxkey;
if ((ecxkey = ecx_new(ctx->provctx)) != NULL
&& ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, params)
&& ecx_pub_pem(ctx, ecxkey, out, cb, cbarg))
ok = 1;
ecx_free(ecxkey);
}
return ok;
}
static int ecx_pub_pem(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ecx_pub_ctx_st *ctx = vctx;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_write_pub_pem_from_obj(out, ecxkey,
KEYTYPE2NID(ctx->type),
NULL,
ossl_prov_ecx_pub_to_der);
BIO_free(out);
return ret;
}
static int ecx_pub_print_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ecx_pub_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *ecx_new;
OSSL_FUNC_keymgmt_free_fn *ecx_free;
OSSL_FUNC_keymgmt_import_fn *ecx_import;
int ok = 0;
ecx_get_new_free_import(ctx->type, &ecx_new, &ecx_free, &ecx_import);
if (ecx_import != NULL) {
ECX_KEY *ecxkey;
if ((ecxkey = ecx_new(ctx)) != NULL
&& ecx_import(ecxkey, OSSL_KEYMGMT_SELECT_PUBLIC_KEY, params)
&& ecx_pub_print(ctx, ecxkey, out, cb, cbarg))
ok = 1;
ecx_free(ecxkey);
}
return ok;
}
static int ecx_pub_print(void *vctx, void *ecxkey, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct ecx_pub_ctx_st *ctx = vctx;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_ecx(out, ecxkey, ecx_print_pub);
BIO_free(out);
return ret;
}
#define MAKE_ENCODER_FUNCTIONS(alg, type) \
const OSSL_DISPATCH alg##_pub_##type##_encoder_functions[] = { \
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))alg##_pub_newctx }, \
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))ecx_pub_freectx }, \
{ OSSL_FUNC_ENCODER_ENCODE_DATA, \
(void (*)(void))ecx_pub_##type##_data }, \
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, \
(void (*)(void))ecx_pub_##type }, \
{ 0, NULL } \
};
#define MAKE_ENCODER_FUNCTIONS_GROUP(alg) \
MAKE_ENCODER_FUNCTIONS(alg, der) \
MAKE_ENCODER_FUNCTIONS(alg, pem) \
MAKE_ENCODER_FUNCTIONS(alg, print)
MAKE_ENCODER_FUNCTIONS_GROUP(x25519)
MAKE_ENCODER_FUNCTIONS_GROUP(x448)
MAKE_ENCODER_FUNCTIONS_GROUP(ed25519)
MAKE_ENCODER_FUNCTIONS_GROUP(ed448)

View File

@ -1,63 +0,0 @@
/*
* Copyright 2020 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
*/
/* Utility function for printing DSA/DH params. */
#include "prov/bio.h"
#include "encoder_local.h"
int ffc_params_prov_print(BIO *out, const FFC_PARAMS *ffc)
{
if (ffc->nid != NID_undef) {
#ifndef OPENSSL_NO_DH
const char *name = ffc_named_group_from_uid(ffc->nid);
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_prov_print_labeled_bignum(out, "P: ", ffc->p))
goto err;
if (ffc->q != NULL) {
if (!ossl_prov_print_labeled_bignum(out, "Q: ", ffc->q))
goto err;
}
if (!ossl_prov_print_labeled_bignum(out, "G: ", ffc->g))
goto err;
if (ffc->j != NULL) {
if (!ossl_prov_print_labeled_bignum(out, "J: ", ffc->j))
goto err;
}
if (ffc->seed != NULL) {
if (!ossl_prov_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;
}

View File

@ -1,183 +0,0 @@
/*
* Copyright 2019-2020 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
*/
#include <openssl/core.h>
#include <openssl/core_dispatch.h>
#include <openssl/bn.h>
#include <openssl/asn1.h> /* i2d_of_void */
#include <openssl/x509.h> /* X509_SIG */
#include <openssl/types.h>
#include <crypto/ecx.h>
#include "internal/ffc.h"
struct pkcs8_encrypt_ctx_st {
/* Set to 1 if intending to encrypt/decrypt, otherwise 0 */
int cipher_intent;
EVP_CIPHER *cipher;
int pbe_nid; /* For future variation */
/* Passphrase that was passed by the caller */
void *cipher_pass;
size_t cipher_pass_length;
/* This callback is only used of |cipher_pass| is NULL */
OSSL_PASSPHRASE_CALLBACK *cb;
void *cbarg;
};
OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns);
OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns);
OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns);
OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns);
OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsa_new(void);
OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsapss_new(void);
OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_rsa_free(void);
OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_rsa_import(void);
OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsa_export(void);
OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsapss_export(void);
OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dh_new(void);
OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dh_free(void);
OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dh_import(void);
OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_dsa_new(void);
OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_dsa_free(void);
OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_dsa_import(void);
void ec_get_new_free_import(OSSL_FUNC_keymgmt_new_fn **ec_new,
OSSL_FUNC_keymgmt_free_fn **ec_free,
OSSL_FUNC_keymgmt_import_fn **ec_import);
int ossl_prov_prepare_ec_params(const void *eckey, int nid,
void **pstr, int *pstrtype);
int ossl_prov_ec_pub_to_der(const void *eckey, unsigned char **pder);
int ossl_prov_ec_priv_to_der(const void *eckey, unsigned char **pder);
int ffc_params_prov_print(BIO *out, const FFC_PARAMS *ffc);
int ossl_prov_prepare_dh_params(const void *dh, int nid,
void **pstr, int *pstrtype);
int ossl_prov_dh_pub_to_der(const void *dh, unsigned char **pder);
int ossl_prov_dh_priv_to_der(const void *dh, unsigned char **pder);
int ossl_prov_dh_type_to_evp(const DH *dh);
#ifndef OPENSSL_NO_EC
void ecx_get_new_free_import(ECX_KEY_TYPE type,
OSSL_FUNC_keymgmt_new_fn **ecx_new,
OSSL_FUNC_keymgmt_free_fn **ecx_free,
OSSL_FUNC_keymgmt_import_fn **ecx_import);
int ossl_prov_ecx_pub_to_der(const void *ecxkey, unsigned char **pder);
int ossl_prov_ecx_priv_to_der(const void *ecxkey, unsigned char **pder);
#endif
int ossl_prov_prepare_dsa_params(const void *dsa, int nid,
void **pstr, int *pstrtype);
/*
* Special variant of ossl_prov_prepare_dsa_params() that requires all
* three parameters (P, Q and G) to be set. This is used when encoding
* the public key.
*/
int ossl_prov_prepare_all_dsa_params(const void *dsa, int nid,
void **pstr, int *pstrtype);
int ossl_prov_dsa_pub_to_der(const void *dsa, unsigned char **pder);
int ossl_prov_dsa_priv_to_der(const void *dsa, unsigned char **pder);
/*
* ossl_prov_prepare_rsa_params() is designed to work with the ossl_prov_write_
* functions, hence 'void *rsa' rather than 'RSA *rsa'.
*/
int ossl_prov_prepare_rsa_params(const void *rsa, int nid,
void **pstr, int *pstrtype);
int ossl_prov_rsa_type_to_evp(const RSA *rsa);
int ossl_prov_print_labeled_bignum(BIO *out, const char *label,
const BIGNUM *bn);
int ossl_prov_print_labeled_buf(BIO *out, const char *label,
const unsigned char *buf, size_t buflen);
int ossl_prov_print_rsa(BIO *out, RSA *rsa, int priv);
enum dh_print_type {
dh_print_priv,
dh_print_pub,
dh_print_params
};
int ossl_prov_print_dh(BIO *out, DH *dh, enum dh_print_type type);
#ifndef OPENSSL_NO_EC
enum ec_print_type {
ec_print_priv,
ec_print_pub,
ec_print_params
};
int ossl_prov_print_eckey(BIO *out, EC_KEY *eckey, enum ec_print_type type);
#endif /* OPENSSL_NO_EC */
enum dsa_print_type {
dsa_print_priv,
dsa_print_pub,
dsa_print_params
};
int ossl_prov_print_dsa(BIO *out, DSA *dsa, enum dsa_print_type type);
enum ecx_print_type {
ecx_print_priv,
ecx_print_pub
};
#ifndef OPENSSL_NO_EC
int ossl_prov_print_ecx(BIO *out, ECX_KEY *ecxkey, enum ecx_print_type type);
#endif
int ossl_prov_write_priv_der_from_obj(BIO *out, const void *obj, int obj_nid,
int (*p2s)(const void *obj, int nid,
void **str,
int *strtype),
int (*k2d)(const void *obj,
unsigned char **pder),
struct pkcs8_encrypt_ctx_st *ctx);
int ossl_prov_write_priv_pem_from_obj(BIO *out, const void *obj, int obj_nid,
int (*p2s)(const void *obj, int nid,
void **str,
int *strtype),
int (*k2d)(const void *obj,
unsigned char **pder),
struct pkcs8_encrypt_ctx_st *ctx);
int ossl_prov_write_pub_der_from_obj(BIO *out, const void *obj, int obj_nid,
int (*p2s)(const void *obj, int nid,
void **str,
int *strtype),
int (*k2d)(const void *obj,
unsigned char **pder));
int ossl_prov_write_pub_pem_from_obj(BIO *out, const void *obj, int obj_nid,
int (*p2s)(const void *obj, int nid,
void **str,
int *strtype),
int (*k2d)(const void *obj,
unsigned char **pder));
int ossl_prov_read_der(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
unsigned char **data, long *len);
int ossl_prov_read_pem(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
char **pem_name, char **pem_header,
unsigned char **data, long *len);
#ifndef OPENSSL_NO_DSA
EVP_PKEY *ossl_prov_read_msblob(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
int *ispub);
# ifndef OPENSSL_NO_RC4
EVP_PKEY *ossl_prov_read_pvk(PROV_CTX *provctx, OSSL_CORE_BIO *cin,
OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg);
# endif
#endif
int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len,
unsigned char *input_der, long input_der_len,
OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg);

View File

@ -1,277 +0,0 @@
/*
* Copyright 2019-2020 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
*/
/*
* RSA low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include "internal/packet.h"
#include "crypto/rsa.h" /* rsa_get0_all_params() */
#include "prov/bio.h" /* ossl_prov_bio_printf() */
#include "prov/der_rsa.h" /* DER_w_RSASSA_PSS_params() */
#include "prov/implementations.h" /* rsa_keymgmt_functions */
#include "encoder_local.h"
DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM)
OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsa_new(void)
{
return ossl_prov_get_keymgmt_new(rsa_keymgmt_functions);
}
OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_rsapss_new(void)
{
return ossl_prov_get_keymgmt_new(rsapss_keymgmt_functions);
}
OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_rsa_free(void)
{
return ossl_prov_get_keymgmt_free(rsa_keymgmt_functions);
}
OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_rsa_import(void)
{
return ossl_prov_get_keymgmt_import(rsa_keymgmt_functions);
}
OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsa_export(void)
{
return ossl_prov_get_keymgmt_export(rsa_keymgmt_functions);
}
OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_rsapss_export(void)
{
return ossl_prov_get_keymgmt_export(rsapss_keymgmt_functions);
}
int ossl_prov_print_rsa(BIO *out, RSA *rsa, int priv)
{
const char *modulus_label;
const char *exponent_label;
const BIGNUM *rsa_d = NULL, *rsa_n = NULL, *rsa_e = NULL;
STACK_OF(BIGNUM_const) *factors = sk_BIGNUM_const_new_null();
STACK_OF(BIGNUM_const) *exps = sk_BIGNUM_const_new_null();
STACK_OF(BIGNUM_const) *coeffs = sk_BIGNUM_const_new_null();
RSA_PSS_PARAMS_30 *pss_params = rsa_get0_pss_params_30(rsa);
int ret = 0;
if (rsa == NULL || factors == NULL || exps == NULL || coeffs == NULL)
goto err;
RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);
rsa_get0_all_params(rsa, factors, exps, coeffs);
if (priv && rsa_d != NULL) {
if (BIO_printf(out, "Private-Key: (%d bit, %d primes)\n",
BN_num_bits(rsa_n),
sk_BIGNUM_const_num(factors)) <= 0)
goto err;
modulus_label = "modulus:";
exponent_label = "publicExponent:";
} else {
if (BIO_printf(out, "Public-Key: (%d bit)\n", BN_num_bits(rsa_n)) <= 0)
goto err;
modulus_label = "Modulus:";
exponent_label = "Exponent:";
}
if (!ossl_prov_print_labeled_bignum(out, modulus_label, rsa_n))
goto err;
if (!ossl_prov_print_labeled_bignum(out, exponent_label, rsa_e))
goto err;
if (priv) {
int i;
if (!ossl_prov_print_labeled_bignum(out, "privateExponent:", rsa_d))
goto err;
if (!ossl_prov_print_labeled_bignum(out, "prime1:",
sk_BIGNUM_const_value(factors, 0)))
goto err;
if (!ossl_prov_print_labeled_bignum(out, "prime2:",
sk_BIGNUM_const_value(factors, 1)))
goto err;
if (!ossl_prov_print_labeled_bignum(out, "exponent1:",
sk_BIGNUM_const_value(exps, 0)))
goto err;
if (!ossl_prov_print_labeled_bignum(out, "exponent2:",
sk_BIGNUM_const_value(exps, 1)))
goto err;
if (!ossl_prov_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 (!ossl_prov_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 (!ossl_prov_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 (!ossl_prov_print_labeled_bignum(out, NULL,
sk_BIGNUM_const_value(coeffs,
i - 1)))
goto err;
}
}
switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
case RSA_FLAG_TYPE_RSA:
if (!rsa_pss_params_30_is_unrestricted(pss_params)) {
if (BIO_printf(out, "(INVALID PSS PARAMETERS)\n") <= 0)
goto err;
}
break;
case RSA_FLAG_TYPE_RSASSAPSS:
if (rsa_pss_params_30_is_unrestricted(pss_params)) {
if (BIO_printf(out, "No PSS parameter restrictions\n") <= 0)
goto err;
} else {
int hashalg_nid = rsa_pss_params_30_hashalg(pss_params);
int maskgenalg_nid = rsa_pss_params_30_maskgenalg(pss_params);
int maskgenhashalg_nid =
rsa_pss_params_30_maskgenhashalg(pss_params);
int saltlen = rsa_pss_params_30_saltlen(pss_params);
int trailerfield = rsa_pss_params_30_trailerfield(pss_params);
if (BIO_printf(out, "PSS parameter restrictions:\n") <= 0)
goto err;
if (BIO_printf(out, " Hash Algorithm: %s%s\n",
rsa_oaeppss_nid2name(hashalg_nid),
(hashalg_nid == NID_sha1
? " (default)" : "")) <= 0)
goto err;
if (BIO_printf(out, " Mask Algorithm: %s with %s%s\n",
rsa_mgf_nid2name(maskgenalg_nid),
rsa_oaeppss_nid2name(maskgenhashalg_nid),
(maskgenalg_nid == NID_mgf1
&& maskgenhashalg_nid == NID_sha1
? " (default)" : "")) <= 0)
goto err;
if (BIO_printf(out, " Minimum Salt Length: %d%s\n",
saltlen,
(saltlen == 20 ? " (default)" : "")) <= 0)
goto err;
/*
* TODO(3.0) Should we show the ASN.1 trailerField value, or
* the actual trailerfield byte (i.e. 0xBC for 1)?
* crypto/rsa/rsa_ameth.c isn't very clear on that, as it
* does display 0xBC when the default applies, but the ASN.1
* trailerField value otherwise...
*/
if (BIO_printf(out, " Trailer Field: 0x%x%s\n",
trailerfield,
(trailerfield == 1 ? " (default)" : ""))
<= 0)
goto err;
}
break;
}
ret = 1;
err:
sk_BIGNUM_const_free(factors);
sk_BIGNUM_const_free(exps);
sk_BIGNUM_const_free(coeffs);
return ret;
}
/*
* Helper functions to prepare RSA-PSS params for encoding. We would
* have simply written the whole AlgorithmIdentifier, but existing libcrypto
* functionality doesn't allow that.
*/
int ossl_prov_prepare_rsa_params(const void *rsa, int nid,
void **pstr, int *pstrtype)
{
const RSA_PSS_PARAMS_30 *pss = rsa_get0_pss_params_30((RSA *)rsa);
*pstr = NULL;
switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
case RSA_FLAG_TYPE_RSA:
/* If plain RSA, the parameters shall be NULL */
*pstrtype = V_ASN1_NULL;
return 1;
case RSA_FLAG_TYPE_RSASSAPSS:
if (rsa_pss_params_30_is_unrestricted(pss)) {
*pstrtype = V_ASN1_UNDEF;
return 1;
} else {
ASN1_STRING *astr = NULL;
WPACKET pkt;
unsigned char *str = NULL;
size_t str_sz = 0;
int i;
for (i = 0; i < 2; i++) {
switch (i) {
case 0:
if (!WPACKET_init_null_der(&pkt))
goto err;
break;
case 1:
if ((str = OPENSSL_malloc(str_sz)) == NULL
|| !WPACKET_init_der(&pkt, str, str_sz)) {
goto err;
}
break;
}
if (!DER_w_RSASSA_PSS_params(&pkt, -1, pss)
|| !WPACKET_finish(&pkt)
|| !WPACKET_get_total_written(&pkt, &str_sz))
goto err;
WPACKET_cleanup(&pkt);
/*
* If no PSS parameters are going to be written, there's no
* point going for another iteration.
* This saves us from getting |str| allocated just to have it
* immediately de-allocated.
*/
if (str_sz == 0)
break;
}
if ((astr = ASN1_STRING_new()) == NULL)
goto err;
*pstrtype = V_ASN1_SEQUENCE;
ASN1_STRING_set0(astr, str, (int)str_sz);
*pstr = astr;
return 1;
err:
OPENSSL_free(str);
return 0;
}
}
/* Currently unsupported RSA key type */
return 0;
}
int ossl_prov_rsa_type_to_evp(const RSA *rsa)
{
switch (RSA_test_flags(rsa, RSA_FLAG_TYPE_MASK)) {
case RSA_FLAG_TYPE_RSA:
return EVP_PKEY_RSA;
case RSA_FLAG_TYPE_RSASSAPSS:
return EVP_PKEY_RSA_PSS;
}
/* Currently unsupported RSA key type */
return EVP_PKEY_NONE;
}

View File

@ -1,297 +0,0 @@
/*
* Copyright 2019-2020 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
*/
/*
* RSA low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include <openssl/safestack.h>
#include "crypto/rsa.h"
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/providercommonerr.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
#define RSA_SELECT_PRIVATE_IMPORTABLE \
(OSSL_KEYMGMT_SELECT_KEYPAIR | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS)
static OSSL_FUNC_encoder_newctx_fn rsa_priv_newctx;
static OSSL_FUNC_encoder_freectx_fn rsa_priv_freectx;
static OSSL_FUNC_encoder_set_ctx_params_fn rsa_priv_set_ctx_params;
static OSSL_FUNC_encoder_settable_ctx_params_fn rsa_priv_settable_ctx_params;
static OSSL_FUNC_encoder_encode_data_fn rsa_priv_der_data;
static OSSL_FUNC_encoder_encode_object_fn rsa_priv_der;
static OSSL_FUNC_encoder_encode_data_fn rsa_pem_priv_data;
static OSSL_FUNC_encoder_encode_object_fn rsa_pem_priv;
static OSSL_FUNC_encoder_newctx_fn rsa_print_newctx;
static OSSL_FUNC_encoder_freectx_fn rsa_print_freectx;
static OSSL_FUNC_encoder_encode_data_fn rsa_priv_print_data;
static OSSL_FUNC_encoder_encode_object_fn rsa_priv_print;
/*
* Context used for private key encoding.
*/
struct rsa_priv_ctx_st {
void *provctx;
struct pkcs8_encrypt_ctx_st sc;
};
/* Private key : context */
static void *rsa_priv_newctx(void *provctx)
{
struct rsa_priv_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx));
if (ctx != NULL) {
ctx->provctx = provctx;
/* -1 is the "whatever" indicator, i.e. the PKCS8 library default PBE */
ctx->sc.pbe_nid = -1;
}
return ctx;
}
static void rsa_priv_freectx(void *vctx)
{
struct rsa_priv_ctx_st *ctx = vctx;
EVP_CIPHER_free(ctx->sc.cipher);
OPENSSL_free(ctx->sc.cipher_pass);
OPENSSL_free(ctx);
}
static const OSSL_PARAM *rsa_priv_settable_ctx_params(ossl_unused void *provctx)
{
static const OSSL_PARAM settables[] = {
OSSL_PARAM_utf8_string(OSSL_ENCODER_PARAM_CIPHER, NULL, 0),
OSSL_PARAM_octet_string(OSSL_ENCODER_PARAM_PASS, NULL, 0),
OSSL_PARAM_END,
};
return settables;
}
static int rsa_priv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
{
struct rsa_priv_ctx_st *ctx = vctx;
const OSSL_PARAM *p;
if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER))
!= NULL) {
const OSSL_PARAM *propsp =
OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PROPERTIES);
const char *props = NULL;
if (p->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
if (propsp != NULL && propsp->data_type != OSSL_PARAM_UTF8_STRING)
return 0;
props = (propsp != NULL ? propsp->data : NULL);
EVP_CIPHER_free(ctx->sc.cipher);
ctx->sc.cipher_intent = p->data != NULL;
if (p->data != NULL
&& ((ctx->sc.cipher = EVP_CIPHER_fetch(NULL, p->data, props))
== NULL))
return 0;
}
if ((p = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_PASS))
!= NULL) {
OPENSSL_free(ctx->sc.cipher_pass);
ctx->sc.cipher_pass = NULL;
if (!OSSL_PARAM_get_octet_string(p, &ctx->sc.cipher_pass, 0,
&ctx->sc.cipher_pass_length))
return 0;
}
return 1;
}
/* Private key : DER */
static int rsa_priv_der_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct rsa_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new();
OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free();
OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import();
int ok = 0;
if (rsa_import != NULL) {
RSA *rsa;
if ((rsa = rsa_new(ctx->provctx)) != NULL
&& rsa_import(rsa, RSA_SELECT_PRIVATE_IMPORTABLE, params)
&& rsa_priv_der(ctx, rsa, out, cb, cbarg))
ok = 1;
rsa_free(rsa);
}
return ok;
}
static int rsa_priv_der(void *vctx, void *rsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct rsa_priv_ctx_st *ctx = vctx;
int ret;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
if (out == NULL)
return 0;
ctx->sc.cb = cb;
ctx->sc.cbarg = cbarg;
ret = ossl_prov_write_priv_der_from_obj(out, rsa,
ossl_prov_rsa_type_to_evp(rsa),
ossl_prov_prepare_rsa_params,
(i2d_of_void *)i2d_RSAPrivateKey,
&ctx->sc);
BIO_free(out);
return ret;
}
/* Private key : PEM */
static int rsa_pem_priv_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct rsa_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new();
OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free();
OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import();
int ok = 0;
if (rsa_import != NULL) {
RSA *rsa;
if ((rsa = rsa_new(ctx->provctx)) != NULL
&& rsa_import(rsa, RSA_SELECT_PRIVATE_IMPORTABLE, params)
&& rsa_pem_priv(ctx, rsa, out, cb, cbarg))
ok = 1;
rsa_free(rsa);
}
return ok;
}
static int rsa_pem_priv(void *vctx, void *rsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct rsa_priv_ctx_st *ctx = vctx;
int ret;
BIO *out = bio_new_from_core_bio(ctx->provctx, cout);
if (out == NULL)
return 0;
ctx->sc.cb = cb;
ctx->sc.cbarg = cbarg;
ret = ossl_prov_write_priv_pem_from_obj(out, rsa,
ossl_prov_rsa_type_to_evp(rsa),
ossl_prov_prepare_rsa_params,
(i2d_of_void *)i2d_RSAPrivateKey,
&ctx->sc);
BIO_free(out);
return ret;
}
/*
* There's no specific print context, so we use the provider context
*/
static void *rsa_print_newctx(void *provctx)
{
return provctx;
}
static void rsa_print_freectx(void *ctx)
{
}
static int rsa_priv_print_data(void *vctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
struct rsa_priv_ctx_st *ctx = vctx;
OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new();
OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free();
OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import();
int ok = 0;
if (rsa_import != NULL) {
RSA *rsa;
if ((rsa = rsa_new(ctx->provctx)) != NULL
&& rsa_import(rsa, RSA_SELECT_PRIVATE_IMPORTABLE, params)
&& rsa_priv_print(ctx, rsa, out, cb, cbarg))
ok = 1;
rsa_free(rsa);
}
return ok;
}
static int rsa_priv_print(void *ctx, void *rsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_rsa(out, rsa, 1);
BIO_free(out);
return ret;
}
const OSSL_DISPATCH rsa_priv_der_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))rsa_priv_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))rsa_priv_freectx },
{ OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
(void (*)(void))rsa_priv_set_ctx_params },
{ OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
(void (*)(void))rsa_priv_settable_ctx_params },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))rsa_priv_der_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))rsa_priv_der },
{ 0, NULL }
};
const OSSL_DISPATCH rsa_priv_pem_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))rsa_priv_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))rsa_priv_freectx },
{ OSSL_FUNC_ENCODER_SET_CTX_PARAMS,
(void (*)(void))rsa_priv_set_ctx_params },
{ OSSL_FUNC_ENCODER_SETTABLE_CTX_PARAMS,
(void (*)(void))rsa_priv_settable_ctx_params },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))rsa_pem_priv_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))rsa_pem_priv },
{ 0, NULL }
};
const OSSL_DISPATCH rsa_priv_text_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))rsa_print_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))rsa_print_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))rsa_priv_print },
{ OSSL_FUNC_ENCODER_ENCODE_DATA,
(void (*)(void))rsa_priv_print_data },
{ 0, NULL }
};

View File

@ -1,196 +0,0 @@
/*
* Copyright 2019-2020 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
*/
/*
* RSA low level APIs are deprecated for public use, but still ok for
* internal use.
*/
#include "internal/deprecated.h"
#include <openssl/core_dispatch.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/types.h>
#include <openssl/params.h>
#include "prov/bio.h"
#include "prov/implementations.h"
#include "prov/providercommonerr.h"
#include "prov/provider_ctx.h"
#include "encoder_local.h"
#define RSA_SELECT_PUBLIC_IMPORTABLE \
(OSSL_KEYMGMT_SELECT_PUBLIC_KEY | OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS)
static OSSL_FUNC_encoder_newctx_fn rsa_pub_newctx;
static OSSL_FUNC_encoder_freectx_fn rsa_pub_freectx;
static OSSL_FUNC_encoder_encode_data_fn rsa_pub_der_data;
static OSSL_FUNC_encoder_encode_object_fn rsa_pub_der;
static OSSL_FUNC_encoder_encode_data_fn rsa_pub_pem_data;
static OSSL_FUNC_encoder_encode_object_fn rsa_pub_pem;
static OSSL_FUNC_encoder_encode_data_fn rsa_pub_print_data;
static OSSL_FUNC_encoder_encode_object_fn rsa_pub_print;
/* Public key : context */
/*
* There's no specific implementation context, so we use the provider context
*/
static void *rsa_pub_newctx(void *provctx)
{
return provctx;
}
static void rsa_pub_freectx(void *ctx)
{
}
/* Public key : DER */
static int rsa_pub_der_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new();
OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free();
OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import();
int ok = 0;
if (rsa_import != NULL) {
RSA *rsa;
/* ctx == provctx */
if ((rsa = rsa_new(ctx)) != NULL
&& rsa_import(rsa, RSA_SELECT_PUBLIC_IMPORTABLE, params)
&& rsa_pub_der(ctx, rsa, out, cb, cbarg))
ok = 1;
rsa_free(rsa);
}
return ok;
}
static int rsa_pub_der(void *ctx, void *rsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_write_pub_der_from_obj(out, rsa,
ossl_prov_rsa_type_to_evp(rsa),
ossl_prov_prepare_rsa_params,
(i2d_of_void *)i2d_RSAPublicKey);
BIO_free(out);
return ret;
}
/* Public key : PEM */
static int rsa_pub_pem_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new();
OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free();
OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import();
int ok = 0;
if (rsa_import != NULL) {
RSA *rsa;
/* ctx == provctx */
if ((rsa = rsa_new(ctx)) != NULL
&& rsa_import(rsa, RSA_SELECT_PUBLIC_IMPORTABLE, params)
&& rsa_pub_pem(ctx, rsa, out, cb, cbarg))
ok = 1;
rsa_free(rsa);
}
return ok;
}
static int rsa_pub_pem(void *ctx, void *rsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_write_pub_pem_from_obj(out, rsa,
ossl_prov_rsa_type_to_evp(rsa),
ossl_prov_prepare_rsa_params,
(i2d_of_void *)i2d_RSAPublicKey);
BIO_free(out);
return ret;
}
static int rsa_pub_print_data(void *ctx, const OSSL_PARAM params[],
OSSL_CORE_BIO *out,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
OSSL_FUNC_keymgmt_new_fn *rsa_new = ossl_prov_get_keymgmt_rsa_new();
OSSL_FUNC_keymgmt_free_fn *rsa_free = ossl_prov_get_keymgmt_rsa_free();
OSSL_FUNC_keymgmt_import_fn *rsa_import = ossl_prov_get_keymgmt_rsa_import();
int ok = 0;
if (rsa_import != NULL) {
RSA *rsa;
/* ctx == provctx */
if ((rsa = rsa_new(ctx)) != NULL
&& rsa_import(rsa, RSA_SELECT_PUBLIC_IMPORTABLE, params)
&& rsa_pub_print(ctx, rsa, out, cb, cbarg))
ok = 1;
rsa_free(rsa);
}
return ok;
}
static int rsa_pub_print(void *ctx, void *rsa, OSSL_CORE_BIO *cout,
OSSL_PASSPHRASE_CALLBACK *cb, void *cbarg)
{
BIO *out = bio_new_from_core_bio(ctx, cout);
int ret;
if (out == NULL)
return 0;
ret = ossl_prov_print_rsa(out, rsa, 0);
BIO_free(out);
return ret;
}
const OSSL_DISPATCH rsa_pub_der_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))rsa_pub_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))rsa_pub_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))rsa_pub_der_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))rsa_pub_der },
{ 0, NULL }
};
const OSSL_DISPATCH rsa_pub_pem_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))rsa_pub_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))rsa_pub_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_DATA, (void (*)(void))rsa_pub_pem_data },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))rsa_pub_pem },
{ 0, NULL }
};
const OSSL_DISPATCH rsa_pub_text_encoder_functions[] = {
{ OSSL_FUNC_ENCODER_NEWCTX, (void (*)(void))rsa_pub_newctx },
{ OSSL_FUNC_ENCODER_FREECTX, (void (*)(void))rsa_pub_freectx },
{ OSSL_FUNC_ENCODER_ENCODE_OBJECT, (void (*)(void))rsa_pub_print },
{ OSSL_FUNC_ENCODER_ENCODE_DATA,
(void (*)(void))rsa_pub_print_data },
{ 0, NULL }
};

View File

@ -0,0 +1,84 @@
/*
* Copyright 2020 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
*/
#include <openssl/core.h>
#include "endecoder_local.h"
OSSL_FUNC_keymgmt_new_fn *
ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns)
{
/* Pilfer the keymgmt dispatch table */
for (; fns->function_id != 0; fns++)
if (fns->function_id == OSSL_FUNC_KEYMGMT_NEW)
return OSSL_FUNC_keymgmt_new(fns);
return NULL;
}
OSSL_FUNC_keymgmt_free_fn *
ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns)
{
/* Pilfer the keymgmt dispatch table */
for (; fns->function_id != 0; fns++)
if (fns->function_id == OSSL_FUNC_KEYMGMT_FREE)
return OSSL_FUNC_keymgmt_free(fns);
return NULL;
}
OSSL_FUNC_keymgmt_import_fn *
ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns)
{
/* Pilfer the keymgmt dispatch table */
for (; fns->function_id != 0; fns++)
if (fns->function_id == OSSL_FUNC_KEYMGMT_IMPORT)
return OSSL_FUNC_keymgmt_import(fns);
return NULL;
}
OSSL_FUNC_keymgmt_export_fn *
ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns)
{
/* Pilfer the keymgmt dispatch table */
for (; fns->function_id != 0; fns++)
if (fns->function_id == OSSL_FUNC_KEYMGMT_EXPORT)
return OSSL_FUNC_keymgmt_export(fns);
return NULL;
}
void *ossl_prov_import_key(const OSSL_DISPATCH *fns, void *provctx,
int selection, const OSSL_PARAM params[])
{
OSSL_FUNC_keymgmt_new_fn *kmgmt_new = ossl_prov_get_keymgmt_new(fns);
OSSL_FUNC_keymgmt_free_fn *kmgmt_free = ossl_prov_get_keymgmt_free(fns);
OSSL_FUNC_keymgmt_import_fn *kmgmt_import =
ossl_prov_get_keymgmt_import(fns);
void *key = NULL;
if (kmgmt_new != NULL && kmgmt_import != NULL && kmgmt_free != NULL) {
if ((key = kmgmt_new(provctx)) == NULL
|| !kmgmt_import(key, selection, params)) {
kmgmt_free(key);
key = NULL;
}
}
return key;
}
void ossl_prov_free_key(const OSSL_DISPATCH *fns, void *key)
{
OSSL_FUNC_keymgmt_free_fn *kmgmt_free = ossl_prov_get_keymgmt_free(fns);
if (kmgmt_free != NULL)
kmgmt_free(key);
}

View File

@ -0,0 +1,26 @@
/*
* Copyright 2020 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
*/
#include <openssl/core.h>
#include <openssl/core_dispatch.h>
#include <openssl/types.h>
#include "prov/provider_ctx.h"
OSSL_FUNC_keymgmt_new_fn *ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns);
OSSL_FUNC_keymgmt_free_fn *ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns);
OSSL_FUNC_keymgmt_import_fn *ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns);
OSSL_FUNC_keymgmt_export_fn *ossl_prov_get_keymgmt_export(const OSSL_DISPATCH *fns);
int ossl_prov_der_from_p8(unsigned char **new_der, long *new_der_len,
unsigned char *input_der, long input_der_len,
OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg);
void *ossl_prov_import_key(const OSSL_DISPATCH *fns, void *provctx,
int selection, const OSSL_PARAM params[]);
void ossl_prov_free_key(const OSSL_DISPATCH *fns, void *key);

View File

@ -305,71 +305,72 @@ extern const OSSL_DISPATCH mac_legacy_cmac_signature_functions[];
extern const OSSL_DISPATCH rsa_asym_cipher_functions[];
/* Encoders */
extern const OSSL_DISPATCH rsa_priv_text_encoder_functions[];
extern const OSSL_DISPATCH rsa_pub_text_encoder_functions[];
extern const OSSL_DISPATCH rsa_priv_der_encoder_functions[];
extern const OSSL_DISPATCH rsa_pub_der_encoder_functions[];
extern const OSSL_DISPATCH rsa_priv_pem_encoder_functions[];
extern const OSSL_DISPATCH rsa_pub_pem_encoder_functions[];
extern const OSSL_DISPATCH rsa_priv_to_text_encoder_functions[];
extern const OSSL_DISPATCH rsa_pub_to_text_encoder_functions[];
extern const OSSL_DISPATCH rsa_priv_to_der_encoder_functions[];
extern const OSSL_DISPATCH rsa_pub_to_der_encoder_functions[];
extern const OSSL_DISPATCH rsa_priv_to_pem_encoder_functions[];
extern const OSSL_DISPATCH rsa_pub_to_pem_encoder_functions[];
extern const OSSL_DISPATCH dh_priv_text_encoder_functions[];
extern const OSSL_DISPATCH dh_pub_text_encoder_functions[];
extern const OSSL_DISPATCH dh_param_text_encoder_functions[];
extern const OSSL_DISPATCH dh_priv_der_encoder_functions[];
extern const OSSL_DISPATCH dh_pub_der_encoder_functions[];
extern const OSSL_DISPATCH dh_param_der_encoder_functions[];
extern const OSSL_DISPATCH dh_priv_pem_encoder_functions[];
extern const OSSL_DISPATCH dh_pub_pem_encoder_functions[];
extern const OSSL_DISPATCH dh_param_pem_encoder_functions[];
extern const OSSL_DISPATCH dh_priv_to_text_encoder_functions[];
extern const OSSL_DISPATCH dh_pub_to_text_encoder_functions[];
extern const OSSL_DISPATCH dh_param_to_text_encoder_functions[];
extern const OSSL_DISPATCH dh_priv_to_der_encoder_functions[];
extern const OSSL_DISPATCH dh_pub_to_der_encoder_functions[];
extern const OSSL_DISPATCH dh_param_to_der_encoder_functions[];
extern const OSSL_DISPATCH dh_priv_to_pem_encoder_functions[];
extern const OSSL_DISPATCH dh_pub_to_pem_encoder_functions[];
extern const OSSL_DISPATCH dh_param_to_pem_encoder_functions[];
extern const OSSL_DISPATCH dsa_priv_text_encoder_functions[];
extern const OSSL_DISPATCH dsa_pub_text_encoder_functions[];
extern const OSSL_DISPATCH dsa_param_text_encoder_functions[];
extern const OSSL_DISPATCH dsa_priv_der_encoder_functions[];
extern const OSSL_DISPATCH dsa_pub_der_encoder_functions[];
extern const OSSL_DISPATCH dsa_param_der_encoder_functions[];
extern const OSSL_DISPATCH dsa_priv_pem_encoder_functions[];
extern const OSSL_DISPATCH dsa_pub_pem_encoder_functions[];
extern const OSSL_DISPATCH dsa_param_pem_encoder_functions[];
extern const OSSL_DISPATCH dsa_priv_to_text_encoder_functions[];
extern const OSSL_DISPATCH dsa_pub_to_text_encoder_functions[];
extern const OSSL_DISPATCH dsa_param_to_text_encoder_functions[];
extern const OSSL_DISPATCH dsa_priv_to_der_encoder_functions[];
extern const OSSL_DISPATCH dsa_pub_to_der_encoder_functions[];
extern const OSSL_DISPATCH dsa_param_to_der_encoder_functions[];
extern const OSSL_DISPATCH dsa_priv_to_pem_encoder_functions[];
extern const OSSL_DISPATCH dsa_pub_to_pem_encoder_functions[];
extern const OSSL_DISPATCH dsa_param_to_pem_encoder_functions[];
extern const OSSL_DISPATCH x25519_priv_print_encoder_functions[];
extern const OSSL_DISPATCH x25519_pub_print_encoder_functions[];
extern const OSSL_DISPATCH x25519_priv_der_encoder_functions[];
extern const OSSL_DISPATCH x25519_pub_der_encoder_functions[];
extern const OSSL_DISPATCH x25519_priv_pem_encoder_functions[];
extern const OSSL_DISPATCH x25519_pub_pem_encoder_functions[];
extern const OSSL_DISPATCH x25519_priv_to_text_encoder_functions[];
extern const OSSL_DISPATCH x25519_pub_to_text_encoder_functions[];
extern const OSSL_DISPATCH x25519_priv_to_der_encoder_functions[];
extern const OSSL_DISPATCH x25519_pub_to_der_encoder_functions[];
extern const OSSL_DISPATCH x25519_priv_to_pem_encoder_functions[];
extern const OSSL_DISPATCH x25519_pub_to_pem_encoder_functions[];
extern const OSSL_DISPATCH x448_priv_print_encoder_functions[];
extern const OSSL_DISPATCH x448_pub_print_encoder_functions[];
extern const OSSL_DISPATCH x448_priv_der_encoder_functions[];
extern const OSSL_DISPATCH x448_pub_der_encoder_functions[];
extern const OSSL_DISPATCH x448_priv_pem_encoder_functions[];
extern const OSSL_DISPATCH x448_pub_pem_encoder_functions[];
extern const OSSL_DISPATCH x448_priv_to_text_encoder_functions[];
extern const OSSL_DISPATCH x448_pub_to_text_encoder_functions[];
extern const OSSL_DISPATCH x448_priv_to_der_encoder_functions[];
extern const OSSL_DISPATCH x448_pub_to_der_encoder_functions[];
extern const OSSL_DISPATCH x448_priv_to_pem_encoder_functions[];
extern const OSSL_DISPATCH x448_pub_to_pem_encoder_functions[];
extern const OSSL_DISPATCH ed25519_priv_print_encoder_functions[];
extern const OSSL_DISPATCH ed25519_pub_print_encoder_functions[];
extern const OSSL_DISPATCH ed25519_priv_der_encoder_functions[];
extern const OSSL_DISPATCH ed25519_pub_der_encoder_functions[];
extern const OSSL_DISPATCH ed25519_priv_pem_encoder_functions[];
extern const OSSL_DISPATCH ed25519_pub_pem_encoder_functions[];
extern const OSSL_DISPATCH ed25519_priv_to_text_encoder_functions[];
extern const OSSL_DISPATCH ed25519_pub_to_text_encoder_functions[];
extern const OSSL_DISPATCH ed25519_priv_to_der_encoder_functions[];
extern const OSSL_DISPATCH ed25519_pub_to_der_encoder_functions[];
extern const OSSL_DISPATCH ed25519_priv_to_pem_encoder_functions[];
extern const OSSL_DISPATCH ed25519_pub_to_pem_encoder_functions[];
extern const OSSL_DISPATCH ed448_priv_print_encoder_functions[];
extern const OSSL_DISPATCH ed448_pub_print_encoder_functions[];
extern const OSSL_DISPATCH ed448_priv_der_encoder_functions[];
extern const OSSL_DISPATCH ed448_pub_der_encoder_functions[];
extern const OSSL_DISPATCH ed448_priv_pem_encoder_functions[];
extern const OSSL_DISPATCH ed448_pub_pem_encoder_functions[];
extern const OSSL_DISPATCH ed448_priv_to_text_encoder_functions[];
extern const OSSL_DISPATCH ed448_pub_to_text_encoder_functions[];
extern const OSSL_DISPATCH ed448_priv_to_der_encoder_functions[];
extern const OSSL_DISPATCH ed448_pub_to_der_encoder_functions[];
extern const OSSL_DISPATCH ed448_priv_to_pem_encoder_functions[];
extern const OSSL_DISPATCH ed448_pub_to_pem_encoder_functions[];
extern const OSSL_DISPATCH ec_priv_text_encoder_functions[];
extern const OSSL_DISPATCH ec_pub_text_encoder_functions[];
extern const OSSL_DISPATCH ec_param_text_encoder_functions[];
extern const OSSL_DISPATCH ec_priv_der_encoder_functions[];
extern const OSSL_DISPATCH ec_pub_der_encoder_functions[];
extern const OSSL_DISPATCH ec_param_der_encoder_functions[];
extern const OSSL_DISPATCH ec_priv_pem_encoder_functions[];
extern const OSSL_DISPATCH ec_pub_pem_encoder_functions[];
extern const OSSL_DISPATCH ec_param_pem_encoder_functions[];
extern const OSSL_DISPATCH ec_priv_to_text_encoder_functions[];
extern const OSSL_DISPATCH ec_pub_to_text_encoder_functions[];
extern const OSSL_DISPATCH ec_param_to_text_encoder_functions[];
extern const OSSL_DISPATCH ec_priv_to_der_encoder_functions[];
extern const OSSL_DISPATCH ec_pub_to_der_encoder_functions[];
extern const OSSL_DISPATCH ec_param_to_der_encoder_functions[];
extern const OSSL_DISPATCH ec_priv_to_pem_encoder_functions[];
extern const OSSL_DISPATCH ec_pub_to_pem_encoder_functions[];
extern const OSSL_DISPATCH ec_param_to_pem_encoder_functions[];
/* Decoders */
extern const OSSL_DISPATCH der_to_dh_decoder_functions[];
extern const OSSL_DISPATCH der_to_dhx_decoder_functions[];
extern const OSSL_DISPATCH der_to_dsa_decoder_functions[];