提交 492a9e24 编写于 作者: D Dr. Stephen Henson

Allow public key ASN1 methods to set PKCS#7 SignerInfo structures.

上级 7bf7333d
......@@ -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)
{
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;
}
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)
if (pkey->ameth && pkey->ameth->pkey_ctrl)
{
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;
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
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
},
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册