mirror of
https://github.com/openssl/openssl.git
synced 2025-03-31 20:10:45 +08:00
Add support for custom signature parameters
Many signature types define the digest and public key type by a single OID such as ecdsa_with_sha256. Some types (RSA-PSS for example) use a single OID to indicate the signature scheme and additional parameters are encoded in the AlgorithmIdentifier. Add an X509_SIG_INFO structure to contain details about the signature type: specifically the digest algorithm, public key algorithm, security bits and various flags. This supports both existing algorithms and more complex types. Add accessors for the structure and a special case that retrieves signature information from a certificate. Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/3301)
This commit is contained in:
parent
7531b3a6cd
commit
786dd2c22c
crypto
include/openssl
@ -52,6 +52,8 @@ struct evp_pkey_asn1_method_st {
|
||||
int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
|
||||
X509_ALGOR *alg1, X509_ALGOR *alg2,
|
||||
ASN1_BIT_STRING *sig);
|
||||
int (*siginf_set) (X509_SIG_INFO *siginf, const X509_ALGOR *alg,
|
||||
const ASN1_STRING *sig);
|
||||
} /* EVP_PKEY_ASN1_METHOD */ ;
|
||||
|
||||
DEFINE_STACK_OF_CONST(EVP_PKEY_ASN1_METHOD)
|
||||
|
@ -37,6 +37,19 @@ struct X509_name_st {
|
||||
int canon_enclen;
|
||||
} /* X509_NAME */ ;
|
||||
|
||||
/* Signature info structure */
|
||||
|
||||
struct x509_sig_info_st {
|
||||
/* NID of message digest */
|
||||
int mdnid;
|
||||
/* NID of public key algorithm */
|
||||
int pknid;
|
||||
/* Security bits */
|
||||
int secbits;
|
||||
/* Various flags */
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
/* PKCS#10 certificate request */
|
||||
|
||||
struct X509_req_info_st {
|
||||
@ -146,6 +159,7 @@ struct x509_st {
|
||||
X509_CINF cert_info;
|
||||
X509_ALGOR sig_alg;
|
||||
ASN1_BIT_STRING signature;
|
||||
X509_SIG_INFO siginf;
|
||||
CRYPTO_REF_COUNT references;
|
||||
CRYPTO_EX_DATA ex_data;
|
||||
/* These contain copies of various extension values */
|
||||
@ -267,3 +281,5 @@ struct x509_object_st {
|
||||
|
||||
int a2i_ipadd(unsigned char *ipout, const char *ipasc);
|
||||
int x509_set1_time(ASN1_TIME **ptm, const ASN1_TIME *tm);
|
||||
|
||||
void x509_init_sig_info(X509 *x);
|
||||
|
@ -142,3 +142,6 @@ DEFINE_STACK_OF(BY_DIR_HASH)
|
||||
DEFINE_STACK_OF(BY_DIR_ENTRY)
|
||||
typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
|
||||
DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
|
||||
|
||||
void x509_set_signature_info(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
|
||||
const ASN1_STRING *sig);
|
||||
|
@ -13,7 +13,10 @@
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#include "internal/asn1_int.h"
|
||||
#include "internal/x509_int.h"
|
||||
#include "x509_lcl.h"
|
||||
|
||||
int X509_set_version(X509 *x, long version)
|
||||
{
|
||||
@ -157,3 +160,77 @@ const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x)
|
||||
{
|
||||
return &x->cert_info.signature;
|
||||
}
|
||||
|
||||
int X509_SIG_INFO_get(const X509_SIG_INFO *siginf, int *mdnid, int *pknid,
|
||||
int *secbits, uint32_t *flags)
|
||||
{
|
||||
if (mdnid != NULL)
|
||||
*mdnid = siginf->mdnid;
|
||||
if (pknid != NULL)
|
||||
*pknid = siginf->pknid;
|
||||
if (secbits != NULL)
|
||||
*secbits = siginf->secbits;
|
||||
if (flags != NULL)
|
||||
*flags = siginf->flags;
|
||||
return (siginf->flags & X509_SIG_INFO_VALID) != 0;
|
||||
}
|
||||
|
||||
void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid,
|
||||
int secbits, uint32_t flags)
|
||||
{
|
||||
siginf->mdnid = mdnid;
|
||||
siginf->pknid = pknid;
|
||||
siginf->secbits = secbits;
|
||||
siginf->flags = flags;
|
||||
}
|
||||
|
||||
int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits,
|
||||
uint32_t *flags)
|
||||
{
|
||||
X509_check_purpose(x, -1, -1);
|
||||
return X509_SIG_INFO_get(&x->siginf, mdnid, pknid, secbits, flags);
|
||||
}
|
||||
|
||||
static void x509_sig_info_init(X509_SIG_INFO *siginf, const X509_ALGOR *alg,
|
||||
const ASN1_STRING *sig)
|
||||
{
|
||||
int pknid, mdnid;
|
||||
const EVP_MD *md;
|
||||
|
||||
siginf->mdnid = NID_undef;
|
||||
siginf->pknid = NID_undef;
|
||||
siginf->secbits = -1;
|
||||
siginf->flags = 0;
|
||||
if (!OBJ_find_sigid_algs(OBJ_obj2nid(alg->algorithm), &mdnid, &pknid)
|
||||
|| pknid == NID_undef)
|
||||
return;
|
||||
siginf->pknid = pknid;
|
||||
if (mdnid == NID_undef) {
|
||||
/* If we have one, use a custom handler for this algorithm */
|
||||
const EVP_PKEY_ASN1_METHOD *ameth = EVP_PKEY_asn1_find(NULL, pknid);
|
||||
if (ameth == NULL || ameth->siginf_set == NULL
|
||||
|| ameth->siginf_set(siginf, alg, sig) == 0)
|
||||
return;
|
||||
siginf->flags |= X509_SIG_INFO_VALID;
|
||||
return;
|
||||
}
|
||||
siginf->flags |= X509_SIG_INFO_VALID;
|
||||
siginf->mdnid = mdnid;
|
||||
md = EVP_get_digestbynid(mdnid);
|
||||
if (md == NULL)
|
||||
return;
|
||||
/* Security bits: half number of bits in digest */
|
||||
siginf->secbits = EVP_MD_size(md) * 4;
|
||||
switch (mdnid) {
|
||||
case NID_sha1:
|
||||
case NID_sha256:
|
||||
case NID_sha384:
|
||||
case NID_sha512:
|
||||
siginf->flags |= X509_SIG_INFO_TLS;
|
||||
}
|
||||
}
|
||||
|
||||
void x509_init_sig_info(X509 *x)
|
||||
{
|
||||
x509_sig_info_init(&x->siginf, &x->sig_alg, &x->signature);
|
||||
}
|
||||
|
@ -488,6 +488,7 @@ static void x509v3_cache_extensions(X509 *x)
|
||||
break;
|
||||
}
|
||||
}
|
||||
x509_init_sig_info(x);
|
||||
x->ex_flags |= EXFLAG_SET;
|
||||
}
|
||||
|
||||
|
@ -131,6 +131,8 @@ typedef struct x509_lookup_st X509_LOOKUP;
|
||||
typedef struct x509_lookup_method_st X509_LOOKUP_METHOD;
|
||||
typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM;
|
||||
|
||||
typedef struct x509_sig_info_st X509_SIG_INFO;
|
||||
|
||||
typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
|
||||
|
||||
typedef struct v3_ext_ctx X509V3_CTX;
|
||||
|
@ -39,6 +39,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/* Flags for X509_get_signature_info() */
|
||||
/* Signature info is valid */
|
||||
# define X509_SIG_INFO_VALID 0x1
|
||||
/* Signature is suitable for TLS use */
|
||||
# define X509_SIG_INFO_TLS 0x2
|
||||
|
||||
# define X509_FILETYPE_PEM 1
|
||||
# define X509_FILETYPE_ASN1 2
|
||||
# define X509_FILETYPE_DEFAULT 3
|
||||
@ -549,6 +556,14 @@ X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length);
|
||||
|
||||
int i2d_re_X509_tbs(X509 *x, unsigned char **pp);
|
||||
|
||||
int X509_SIG_INFO_get(const X509_SIG_INFO *siginf, int *mdnid, int *pknid,
|
||||
int *secbits, uint32_t *flags);
|
||||
void X509_SIG_INFO_set(X509_SIG_INFO *siginf, int mdnid, int pknid,
|
||||
int secbits, uint32_t flags);
|
||||
|
||||
int X509_get_signature_info(X509 *x, int *mdnid, int *pknid, int *secbits,
|
||||
uint32_t *flags);
|
||||
|
||||
void X509_get0_signature(const ASN1_BIT_STRING **psig,
|
||||
const X509_ALGOR **palg, const X509 *x);
|
||||
int X509_get_signature_nid(const X509 *x);
|
||||
|
Loading…
x
Reference in New Issue
Block a user