Allow public key ASN1 methods to set PKCS#7 SignerInfo structures.
This commit is contained in:
parent
7bf7333d68
commit
492a9e2415
5
CHANGES
5
CHANGES
@ -4,6 +4,11 @@
|
||||
|
||||
Changes between 0.9.8a and 0.9.9 [xx XXX xxxx]
|
||||
|
||||
*) Remove algorithm specific dependencies when setting PKCS7_SIGNER_INFO
|
||||
structures for PKCS7_sign(). They are now set up by the relevant public
|
||||
key ASN1 method.
|
||||
[Steve Henson]
|
||||
|
||||
*) Add provisional EC pkey method with support for ECDSA and ECDH.
|
||||
[Steve Henson]
|
||||
|
||||
|
@ -340,7 +340,7 @@ void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
void (*pkey_ctrl)(EVP_PKEY *pkey, int op,
|
||||
int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
|
||||
long arg1, void *arg2))
|
||||
{
|
||||
ameth->pkey_ctrl = pkey_ctrl;
|
||||
|
@ -104,7 +104,7 @@ struct evp_pkey_asn1_method_st
|
||||
ASN1_PCTX *pctx);
|
||||
|
||||
void (*pkey_free)(EVP_PKEY *pkey);
|
||||
void (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
|
||||
int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
|
||||
|
||||
/* Legacy functions for old PEM */
|
||||
|
||||
|
@ -528,6 +528,29 @@ static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
|
||||
return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
|
||||
}
|
||||
|
||||
static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case ASN1_PKEY_CTRL_PKCS7_SIGN:
|
||||
if (arg1 == 0)
|
||||
{
|
||||
X509_ALGOR *alg1, *alg2;
|
||||
PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
|
||||
X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_sha1),
|
||||
V_ASN1_NULL, 0);
|
||||
X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_dsaWithSHA1),
|
||||
V_ASN1_UNDEF, 0);
|
||||
}
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* NB these are sorted in pkey_id order, lowest first */
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
|
||||
@ -585,7 +608,7 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] =
|
||||
dsa_param_print,
|
||||
|
||||
int_dsa_free,
|
||||
0,
|
||||
dsa_pkey_ctrl,
|
||||
old_dsa_priv_decode,
|
||||
old_dsa_priv_encode
|
||||
}
|
||||
|
@ -570,6 +570,29 @@ static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
|
||||
return i2d_ECPrivateKey(pkey->pkey.ec, pder);
|
||||
}
|
||||
|
||||
static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case ASN1_PKEY_CTRL_PKCS7_SIGN:
|
||||
if (arg1 == 0)
|
||||
{
|
||||
X509_ALGOR *alg1, *alg2;
|
||||
PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
|
||||
X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_sha1),
|
||||
V_ASN1_NULL, 0);
|
||||
X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_ecdsa_with_SHA1),
|
||||
V_ASN1_NULL, 0);
|
||||
}
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
|
||||
{
|
||||
EVP_PKEY_EC,
|
||||
@ -598,7 +621,7 @@ EVP_PKEY_ASN1_METHOD eckey_asn1_meth =
|
||||
eckey_param_print,
|
||||
|
||||
int_ec_free,
|
||||
0,
|
||||
ec_pkey_ctrl,
|
||||
old_ec_priv_decode,
|
||||
old_ec_priv_encode
|
||||
};
|
||||
|
@ -860,6 +860,8 @@ void EVP_PBE_cleanup(void);
|
||||
#define ASN1_PKEY_ALIAS 0x1
|
||||
#define ASN1_PKEY_DYNAMIC 0x2
|
||||
|
||||
#define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1
|
||||
|
||||
int EVP_PKEY_asn1_get_count(void);
|
||||
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx);
|
||||
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(int type);
|
||||
@ -899,7 +901,7 @@ void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
void (*pkey_free)(EVP_PKEY *pkey));
|
||||
void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
void (*pkey_ctrl)(EVP_PKEY *pkey, int op,
|
||||
int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
|
||||
long arg1, void *arg2));
|
||||
|
||||
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
#include "asn1_locl.h"
|
||||
|
||||
long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg)
|
||||
{
|
||||
@ -340,13 +341,8 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
|
||||
int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
|
||||
const EVP_MD *dgst)
|
||||
{
|
||||
int nid;
|
||||
char is_dsa;
|
||||
int ret;
|
||||
|
||||
if (pkey->type == EVP_PKEY_DSA || pkey->type == EVP_PKEY_EC)
|
||||
is_dsa = 1;
|
||||
else
|
||||
is_dsa = 0;
|
||||
/* We now need to add another PKCS7_SIGNER_INFO entry */
|
||||
if (!ASN1_INTEGER_set(p7i->version,1))
|
||||
goto err;
|
||||
@ -366,50 +362,28 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
|
||||
p7i->pkey=pkey;
|
||||
|
||||
/* Set the algorithms */
|
||||
if (is_dsa) p7i->digest_alg->algorithm=OBJ_nid2obj(NID_sha1);
|
||||
else
|
||||
p7i->digest_alg->algorithm=OBJ_nid2obj(EVP_MD_type(dgst));
|
||||
|
||||
if (p7i->digest_alg->parameter != NULL)
|
||||
ASN1_TYPE_free(p7i->digest_alg->parameter);
|
||||
if ((p7i->digest_alg->parameter=ASN1_TYPE_new()) == NULL)
|
||||
goto err;
|
||||
p7i->digest_alg->parameter->type=V_ASN1_NULL;
|
||||
X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)),
|
||||
V_ASN1_NULL, NULL);
|
||||
|
||||
if (p7i->digest_enc_alg->parameter != NULL)
|
||||
ASN1_TYPE_free(p7i->digest_enc_alg->parameter);
|
||||
nid = EVP_PKEY_type(pkey->type);
|
||||
if (nid == EVP_PKEY_RSA)
|
||||
if (pkey->ameth && pkey->ameth->pkey_ctrl)
|
||||
{
|
||||
p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_rsaEncryption);
|
||||
if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
|
||||
goto err;
|
||||
p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
|
||||
ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN,
|
||||
0, p7i);
|
||||
if (ret > 0)
|
||||
return 1;
|
||||
if (ret != -2)
|
||||
{
|
||||
PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
|
||||
PKCS7_R_SIGNING_CTRL_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (nid == EVP_PKEY_DSA)
|
||||
{
|
||||
#if 1
|
||||
/* use 'dsaEncryption' OID for compatibility with other software
|
||||
* (PKCS #7 v1.5 does specify how to handle DSA) ... */
|
||||
p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsa);
|
||||
#else
|
||||
/* ... although the 'dsaWithSHA1' OID (as required by RFC 2630 for CMS)
|
||||
* would make more sense. */
|
||||
p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_dsaWithSHA1);
|
||||
#endif
|
||||
p7i->digest_enc_alg->parameter = NULL; /* special case for DSA: omit 'parameter'! */
|
||||
}
|
||||
else if (nid == EVP_PKEY_EC)
|
||||
{
|
||||
p7i->digest_enc_alg->algorithm=OBJ_nid2obj(NID_ecdsa_with_SHA1);
|
||||
if (!(p7i->digest_enc_alg->parameter=ASN1_TYPE_new()))
|
||||
goto err;
|
||||
p7i->digest_enc_alg->parameter->type=V_ASN1_NULL;
|
||||
}
|
||||
else
|
||||
return(0);
|
||||
|
||||
return(1);
|
||||
PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET,
|
||||
PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE);
|
||||
return 0;
|
||||
err:
|
||||
return(0);
|
||||
}
|
||||
@ -424,6 +398,8 @@ PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey,
|
||||
if (!PKCS7_add_signer(p7,si)) goto err;
|
||||
return(si);
|
||||
err:
|
||||
if (si)
|
||||
PKCS7_SIGNER_INFO_free(si);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
@ -459,6 +435,17 @@ STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7)
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
|
||||
X509_ALGOR **pdig, X509_ALGOR **psig)
|
||||
{
|
||||
if (pk)
|
||||
*pk = si->pkey;
|
||||
if (pdig)
|
||||
*pdig = si->digest_alg;
|
||||
if (psig)
|
||||
*psig = si->digest_enc_alg;
|
||||
}
|
||||
|
||||
PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509)
|
||||
{
|
||||
PKCS7_RECIP_INFO *ri;
|
||||
|
@ -340,6 +340,8 @@ int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md);
|
||||
STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7);
|
||||
|
||||
PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
|
||||
void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk,
|
||||
X509_ALGOR **pdig, X509_ALGOR **psig);
|
||||
int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri);
|
||||
int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509);
|
||||
int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
|
||||
@ -409,6 +411,7 @@ void ERR_load_PKCS7_strings(void);
|
||||
#define PKCS7_F_PKCS7_SET_TYPE 110
|
||||
#define PKCS7_F_PKCS7_SIGN 116
|
||||
#define PKCS7_F_PKCS7_SIGNATUREVERIFY 113
|
||||
#define PKCS7_F_PKCS7_SIGNER_INFO_SET 129
|
||||
#define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119
|
||||
#define PKCS7_F_PKCS7_VERIFY 117
|
||||
#define PKCS7_F_SMIME_READ_PKCS7 122
|
||||
@ -450,6 +453,8 @@ void ERR_load_PKCS7_strings(void);
|
||||
#define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127
|
||||
#define PKCS7_R_SIGNATURE_FAILURE 105
|
||||
#define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128
|
||||
#define PKCS7_R_SIGNING_CTRL_FAILURE 147
|
||||
#define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148
|
||||
#define PKCS7_R_SIG_INVALID_MIME_TYPE 141
|
||||
#define PKCS7_R_SMIME_TEXT_ERROR 129
|
||||
#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106
|
||||
|
@ -78,7 +78,7 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO), "PKCS7_add_recipient_info"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST), "PKCS7_BIO_ADD_DIGEST"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_ctrl"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_CTRL"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL), "PKCS7_dataFinal"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_DATAINIT), "PKCS7_dataInit"},
|
||||
@ -87,13 +87,14 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_FIND_DIGEST"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_get0_signers"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_GET0_SIGNERS"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER), "PKCS7_set_cipher"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT), "PKCS7_set_content"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST), "PKCS7_set_digest"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE), "PKCS7_set_type"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET), "PKCS7_SIGNER_INFO_set"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"},
|
||||
{ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"},
|
||||
{ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7), "SMIME_read_PKCS7"},
|
||||
@ -138,6 +139,8 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
|
||||
{ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE),"private key does not match certificate"},
|
||||
{ERR_REASON(PKCS7_R_SIGNATURE_FAILURE) ,"signature failure"},
|
||||
{ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND),"signer certificate not found"},
|
||||
{ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE),"signing ctrl failure"},
|
||||
{ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE),"signing not supported for this key type"},
|
||||
{ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"},
|
||||
{ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR) ,"smime text error"},
|
||||
{ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE),"unable to find certificate"},
|
||||
|
@ -261,6 +261,29 @@ static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
|
||||
return do_rsa_print(bp, pkey->pkey.rsa, indent, 1);
|
||||
}
|
||||
|
||||
|
||||
static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case ASN1_PKEY_CTRL_PKCS7_SIGN:
|
||||
if (arg1 == 0)
|
||||
{
|
||||
X509_ALGOR *alg;
|
||||
PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg);
|
||||
X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption),
|
||||
V_ASN1_NULL, 0);
|
||||
}
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return -2;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
|
||||
{
|
||||
{
|
||||
@ -286,7 +309,7 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] =
|
||||
0,0,0,0,0,0,
|
||||
|
||||
int_rsa_free,
|
||||
0,
|
||||
rsa_pkey_ctrl,
|
||||
old_rsa_priv_decode,
|
||||
old_rsa_priv_encode
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user