From: tb Date: Fri, 29 Dec 2023 10:59:00 +0000 (+0000) Subject: Move the EVP_PKEY_asn1_* API that will stay to evp/p_lib.c X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=049ee4e232dfc75f92dcd0e54f31453ba154d906;p=openbsd Move the EVP_PKEY_asn1_* API that will stay to evp/p_lib.c Most of these functions are only called from this file internally apart from the pem_str lookups from pem/. In the next major bump we can then remove asn/ameth_lib.c. Also move EVP_PKEY_ASN1_METHOD to evp_local.h. While this is used to dispatch to various ASN.1 decoding routines, it doesn't fit into asn1/ at all. --- diff --git a/lib/libcrypto/asn1/ameth_lib.c b/lib/libcrypto/asn1/ameth_lib.c index 2165bf06b55..cf3a965a646 100644 --- a/lib/libcrypto/asn1/ameth_lib.c +++ b/lib/libcrypto/asn1/ameth_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ameth_lib.c,v 1.39 2023/12/29 10:17:26 tb Exp $ */ +/* $OpenBSD: ameth_lib.c,v 1.40 2023/12/29 10:59:00 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -62,146 +62,8 @@ #include #include -#include "asn1_local.h" #include "evp_local.h" -extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[]; -extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD gostimit_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD gostr01_asn1_meths[]; -extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[]; -extern const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD x25519_asn1_meth; - -static const EVP_PKEY_ASN1_METHOD *asn1_methods[] = { - &cmac_asn1_meth, - &dh_asn1_meth, - &dsa_asn1_meths[0], - &dsa_asn1_meths[1], - &dsa_asn1_meths[2], - &dsa_asn1_meths[3], - &dsa_asn1_meths[4], - &eckey_asn1_meth, - &ed25519_asn1_meth, - &gostimit_asn1_meth, - &gostr01_asn1_meths[0], - &gostr01_asn1_meths[1], - &gostr01_asn1_meths[2], - &hmac_asn1_meth, - &rsa_asn1_meths[0], - &rsa_asn1_meths[1], - &rsa_pss_asn1_meth, - &x25519_asn1_meth, -}; - -#define N_ASN1_METHODS (sizeof(asn1_methods) / sizeof(asn1_methods[0])) - -int -EVP_PKEY_asn1_get_count(void) -{ - return N_ASN1_METHODS; -} - -const EVP_PKEY_ASN1_METHOD * -EVP_PKEY_asn1_get0(int idx) -{ - if (idx < 0 || idx >= N_ASN1_METHODS) - return NULL; - - return asn1_methods[idx]; -} - -static const EVP_PKEY_ASN1_METHOD * -pkey_asn1_find(int pkey_id) -{ - const EVP_PKEY_ASN1_METHOD *ameth; - int i; - - for (i = EVP_PKEY_asn1_get_count() - 1; i >= 0; i--) { - ameth = EVP_PKEY_asn1_get0(i); - if (ameth->pkey_id == pkey_id) - return ameth; - } - - return NULL; -} - -/* - * XXX - fix this. In what looks like an infinite loop, this API only makes two - * calls to pkey_asn1_find(): If the type resolves to an aliased ASN.1 method, - * the second call will find the method it aliases. Codify this in regress and - * make this explicit in code. - */ -const EVP_PKEY_ASN1_METHOD * -EVP_PKEY_asn1_find(ENGINE **pe, int type) -{ - const EVP_PKEY_ASN1_METHOD *mp; - - if (pe != NULL) - *pe = NULL; - - for (;;) { - if ((mp = pkey_asn1_find(type)) == NULL) - break; - if ((mp->pkey_flags & ASN1_PKEY_ALIAS) == 0) - break; - type = mp->pkey_base_id; - } - - return mp; -} - -const EVP_PKEY_ASN1_METHOD * -EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, int len) -{ - const EVP_PKEY_ASN1_METHOD *ameth; - int i; - - if (len == -1) - len = strlen(str); - if (pe != NULL) - *pe = NULL; - for (i = EVP_PKEY_asn1_get_count() - 1; i >= 0; i--) { - ameth = EVP_PKEY_asn1_get0(i); - if (ameth->pkey_flags & ASN1_PKEY_ALIAS) - continue; - if (((int)strlen(ameth->pem_str) == len) && - !strncasecmp(ameth->pem_str, str, len)) - return ameth; - } - return NULL; -} - -int -EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags, - const char **pinfo, const char **ppem_str, - const EVP_PKEY_ASN1_METHOD *ameth) -{ - if (!ameth) - return 0; - if (ppkey_id) - *ppkey_id = ameth->pkey_id; - if (ppkey_base_id) - *ppkey_base_id = ameth->pkey_base_id; - if (ppkey_flags) - *ppkey_flags = ameth->pkey_flags; - if (pinfo) - *pinfo = ameth->info; - if (ppem_str) - *ppem_str = ameth->pem_str; - return 1; -} - -const EVP_PKEY_ASN1_METHOD* -EVP_PKEY_get0_asn1(const EVP_PKEY *pkey) -{ - return pkey->ameth; -} - /* * XXX - remove all the API below here in the next major bump. */ diff --git a/lib/libcrypto/asn1/asn1_local.h b/lib/libcrypto/asn1/asn1_local.h index 566ace798b2..c1dfa6f68c2 100644 --- a/lib/libcrypto/asn1/asn1_local.h +++ b/lib/libcrypto/asn1/asn1_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: asn1_local.h,v 1.4 2023/07/28 10:00:10 tb Exp $ */ +/* $OpenBSD: asn1_local.h,v 1.5 2023/12/29 10:59:00 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2006. */ @@ -89,70 +89,6 @@ struct asn1_pctx_st { unsigned long str_flags; } /* ASN1_PCTX */; -/* ASN1 public key method structure */ - -struct evp_pkey_asn1_method_st { - int pkey_id; - int pkey_base_id; - unsigned long pkey_flags; - - char *pem_str; - char *info; - - int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub); - int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk); - int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); - int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); - - int (*priv_decode)(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf); - int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk); - int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); - - int (*pkey_size)(const EVP_PKEY *pk); - int (*pkey_bits)(const EVP_PKEY *pk); - int (*pkey_security_bits)(const EVP_PKEY *pk); - - int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, - int derlen); - int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder); - int (*param_missing)(const EVP_PKEY *pk); - int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from); - int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); - int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, - ASN1_PCTX *pctx); - int (*sig_print)(BIO *out, const X509_ALGOR *sigalg, - const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx); - - void (*pkey_free)(EVP_PKEY *pkey); - int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2); - - /* Legacy functions for old PEM */ - - int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder, - int derlen); - int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder); - /* Custom ASN1 signature verification */ - int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey); - int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, - X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig); - - int (*pkey_check)(const EVP_PKEY *pk); - int (*pkey_public_check)(const EVP_PKEY *pk); - int (*pkey_param_check)(const EVP_PKEY *pk); - - int (*set_priv_key)(EVP_PKEY *pk, const unsigned char *private_key, - size_t len); - int (*set_pub_key)(EVP_PKEY *pk, const unsigned char *public_key, - size_t len); - int (*get_priv_key)(const EVP_PKEY *pk, unsigned char *out_private_key, - size_t *out_len); - int (*get_pub_key)(const EVP_PKEY *pk, unsigned char *out_public_key, - size_t *out_len); -} /* EVP_PKEY_ASN1_METHOD */; - /* Method to handle CRL access. * In general a CRL could be very large (several Mb) and can consume large * amounts of resources if stored in memory by multiple processes. diff --git a/lib/libcrypto/asn1/t_x509.c b/lib/libcrypto/asn1/t_x509.c index cd98997f6a6..6f7bdc79fe4 100644 --- a/lib/libcrypto/asn1/t_x509.c +++ b/lib/libcrypto/asn1/t_x509.c @@ -1,4 +1,4 @@ -/* $OpenBSD: t_x509.c,v 1.43 2023/07/07 19:37:52 beck Exp $ */ +/* $OpenBSD: t_x509.c,v 1.44 2023/12/29 10:59:00 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -77,7 +77,7 @@ #include #endif -#include "asn1_local.h" +#include "evp_local.h" #include "x509_local.h" int diff --git a/lib/libcrypto/evp/evp_local.h b/lib/libcrypto/evp/evp_local.h index 1034b88a1a2..d21919ac9b4 100644 --- a/lib/libcrypto/evp/evp_local.h +++ b/lib/libcrypto/evp/evp_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: evp_local.h,v 1.9 2023/12/22 17:25:47 tb Exp $ */ +/* $OpenBSD: evp_local.h,v 1.10 2023/12/29 10:59:00 tb Exp $ */ /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL * project 2000. */ @@ -89,6 +89,68 @@ struct ecx_key_st { size_t pub_key_len; }; +struct evp_pkey_asn1_method_st { + int pkey_id; + int pkey_base_id; + unsigned long pkey_flags; + + char *pem_str; + char *info; + + int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub); + int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk); + int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + + int (*priv_decode)(EVP_PKEY *pk, const PKCS8_PRIV_KEY_INFO *p8inf); + int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk); + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + + int (*pkey_size)(const EVP_PKEY *pk); + int (*pkey_bits)(const EVP_PKEY *pk); + int (*pkey_security_bits)(const EVP_PKEY *pk); + + int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, + int derlen); + int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder); + int (*param_missing)(const EVP_PKEY *pk); + int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from); + int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*sig_print)(BIO *out, const X509_ALGOR *sigalg, + const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx); + + void (*pkey_free)(EVP_PKEY *pkey); + int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2); + + /* Legacy functions for old PEM */ + + int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder, + int derlen); + int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder); + /* Custom ASN1 signature verification */ + int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey); + int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *alg1, X509_ALGOR *alg2, ASN1_BIT_STRING *sig); + + int (*pkey_check)(const EVP_PKEY *pk); + int (*pkey_public_check)(const EVP_PKEY *pk); + int (*pkey_param_check)(const EVP_PKEY *pk); + + int (*set_priv_key)(EVP_PKEY *pk, const unsigned char *private_key, + size_t len); + int (*set_pub_key)(EVP_PKEY *pk, const unsigned char *public_key, + size_t len); + int (*get_priv_key)(const EVP_PKEY *pk, unsigned char *out_private_key, + size_t *out_len); + int (*get_pub_key)(const EVP_PKEY *pk, unsigned char *out_public_key, + size_t *out_len); +} /* EVP_PKEY_ASN1_METHOD */; + /* Type needs to be a bit field * Sub-type needs to be for variations on the method, as in, can it do * arbitrary encryption.... */ diff --git a/lib/libcrypto/evp/p_lib.c b/lib/libcrypto/evp/p_lib.c index f92684fdd75..24e1dbb14c7 100644 --- a/lib/libcrypto/evp/p_lib.c +++ b/lib/libcrypto/evp/p_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: p_lib.c,v 1.50 2023/12/25 22:41:50 tb Exp $ */ +/* $OpenBSD: p_lib.c,v 1.51 2023/12/29 10:59:00 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -55,13 +55,62 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ #include +#include +#include -#include - -#include +#include +#include #include +#include #include #include #include @@ -73,13 +122,152 @@ #ifndef OPENSSL_NO_DSA #include #endif +#ifndef OPENSSL_NO_EC +#include +#endif #ifndef OPENSSL_NO_RSA #include #endif -#include "asn1_local.h" #include "evp_local.h" +extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD gostimit_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD gostr01_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD rsa_pss_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD x25519_asn1_meth; + +static const EVP_PKEY_ASN1_METHOD *asn1_methods[] = { + &cmac_asn1_meth, + &dh_asn1_meth, + &dsa_asn1_meths[0], + &dsa_asn1_meths[1], + &dsa_asn1_meths[2], + &dsa_asn1_meths[3], + &dsa_asn1_meths[4], + &eckey_asn1_meth, + &ed25519_asn1_meth, + &gostimit_asn1_meth, + &gostr01_asn1_meths[0], + &gostr01_asn1_meths[1], + &gostr01_asn1_meths[2], + &hmac_asn1_meth, + &rsa_asn1_meths[0], + &rsa_asn1_meths[1], + &rsa_pss_asn1_meth, + &x25519_asn1_meth, +}; + +#define N_ASN1_METHODS (sizeof(asn1_methods) / sizeof(asn1_methods[0])) + +int +EVP_PKEY_asn1_get_count(void) +{ + return N_ASN1_METHODS; +} + +const EVP_PKEY_ASN1_METHOD * +EVP_PKEY_asn1_get0(int idx) +{ + if (idx < 0 || idx >= N_ASN1_METHODS) + return NULL; + + return asn1_methods[idx]; +} + +static const EVP_PKEY_ASN1_METHOD * +pkey_asn1_find(int pkey_id) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + int i; + + for (i = EVP_PKEY_asn1_get_count() - 1; i >= 0; i--) { + ameth = EVP_PKEY_asn1_get0(i); + if (ameth->pkey_id == pkey_id) + return ameth; + } + + return NULL; +} + +/* + * XXX - fix this. In what looks like an infinite loop, this API only makes two + * calls to pkey_asn1_find(): If the type resolves to an aliased ASN.1 method, + * the second call will find the method it aliases. Codify this in regress and + * make this explicit in code. + */ +const EVP_PKEY_ASN1_METHOD * +EVP_PKEY_asn1_find(ENGINE **pe, int type) +{ + const EVP_PKEY_ASN1_METHOD *mp; + + if (pe != NULL) + *pe = NULL; + + for (;;) { + if ((mp = pkey_asn1_find(type)) == NULL) + break; + if ((mp->pkey_flags & ASN1_PKEY_ALIAS) == 0) + break; + type = mp->pkey_base_id; + } + + return mp; +} + +const EVP_PKEY_ASN1_METHOD * +EVP_PKEY_asn1_find_str(ENGINE **pe, const char *str, int len) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + int i; + + if (len == -1) + len = strlen(str); + if (pe != NULL) + *pe = NULL; + for (i = EVP_PKEY_asn1_get_count() - 1; i >= 0; i--) { + ameth = EVP_PKEY_asn1_get0(i); + if (ameth->pkey_flags & ASN1_PKEY_ALIAS) + continue; + if (((int)strlen(ameth->pem_str) == len) && + !strncasecmp(ameth->pem_str, str, len)) + return ameth; + } + return NULL; +} + +int +EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags, + const char **pinfo, const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth) +{ + if (!ameth) + return 0; + if (ppkey_id) + *ppkey_id = ameth->pkey_id; + if (ppkey_base_id) + *ppkey_base_id = ameth->pkey_base_id; + if (ppkey_flags) + *ppkey_flags = ameth->pkey_flags; + if (pinfo) + *pinfo = ameth->info; + if (ppem_str) + *ppem_str = ameth->pem_str; + return 1; +} + +const EVP_PKEY_ASN1_METHOD* +EVP_PKEY_get0_asn1(const EVP_PKEY *pkey) +{ + return pkey->ameth; +} + int EVP_PKEY_bits(const EVP_PKEY *pkey) {