提交 399a6f0b 编写于 作者: D Dr. Stephen Henson

Update PKCS#7 enveloped data to new API.

上级 3d479299
...@@ -2,7 +2,14 @@ ...@@ -2,7 +2,14 @@
OpenSSL CHANGES OpenSSL CHANGES
_______________ _______________
Changes between 0.9.8a and 0.9.9 [xx XXX xxxx] Changes between 0.9.8b and 0.9.9 [xx XXX xxxx]
*) Update PKCS#7 enveloped data routines to use new API. This is now
supported by any public key method supporting the encrypt operation. A
ctrl is added to allow the public key algorithm to examine or modify
the PKCS#7 RecipientInfo structure if it needs to: for RSA this is
a no op.
[Steve Henson]
*) Add a ctrl to asn1 method to allow a public key algorithm to express *) Add a ctrl to asn1 method to allow a public key algorithm to express
a default digest type to use. In most cases this will be SHA1 but some a default digest type to use. In most cases this will be SHA1 but some
......
...@@ -765,6 +765,7 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); ...@@ -765,6 +765,7 @@ int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b);
/* Since this is used to store all sorts of things, via macros, for now, make /* Since this is used to store all sorts of things, via macros, for now, make
its data void * */ its data void * */
int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len);
void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len);
int ASN1_STRING_length(const ASN1_STRING *x); int ASN1_STRING_length(const ASN1_STRING *x);
void ASN1_STRING_length_set(ASN1_STRING *x, int n); void ASN1_STRING_length_set(ASN1_STRING *x, int n);
int ASN1_STRING_type(ASN1_STRING *x); int ASN1_STRING_type(ASN1_STRING *x);
......
...@@ -393,6 +393,14 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) ...@@ -393,6 +393,14 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
return(1); return(1);
} }
void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
{
if (str->data)
OPENSSL_free(str->data);
str->data = data;
str->length = len;
}
ASN1_STRING *ASN1_STRING_new(void) ASN1_STRING *ASN1_STRING_new(void)
{ {
return(ASN1_STRING_type_new(V_ASN1_OCTET_STRING)); return(ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
......
...@@ -882,7 +882,10 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, ...@@ -882,7 +882,10 @@ void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
EVP_PKEY_CTRL_MD, 0, (void *)md) EVP_PKEY_CTRL_MD, 0, (void *)md)
#define EVP_PKEY_CTRL_MD 1 #define EVP_PKEY_CTRL_MD 1
#define EVP_PKEY_CTRL_PEER_KEY 2 #define EVP_PKEY_CTRL_PEER_KEY 2
#define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3
#define EVP_PKEY_CTRL_PKCS7_DECRYPT 4
#define EVP_PKEY_ALG_CTRL 0x1000 #define EVP_PKEY_ALG_CTRL 0x1000
......
...@@ -138,6 +138,66 @@ static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) ...@@ -138,6 +138,66 @@ static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg)
} }
static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri,
unsigned char *key, int keylen)
{
EVP_PKEY_CTX *pctx = NULL;
EVP_PKEY *pkey = NULL;
unsigned char *ek = NULL;
int ret = 0;
int eklen;
pkey = X509_get_pubkey(ri->cert);
if (!pkey)
return 0;
pctx = EVP_PKEY_CTX_new(pkey, NULL);
if (!pctx)
return 0;
if (EVP_PKEY_encrypt_init(pctx) <= 0)
goto err;
if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT,
EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0)
{
PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR);
goto err;
}
if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0)
goto err;
ek = OPENSSL_malloc(eklen);
if (ek == NULL)
{
PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE);
goto err;
}
if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0)
goto err;
ASN1_STRING_set0(ri->enc_key, ek, eklen);
ek = NULL;
ret = 1;
err:
if (pkey)
EVP_PKEY_free(pkey);
if (pctx)
EVP_PKEY_CTX_free(pctx);
if (ek)
OPENSSL_free(ek);
return ret;
}
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
{ {
int i; int i;
...@@ -148,7 +208,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) ...@@ -148,7 +208,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL; STACK_OF(PKCS7_RECIP_INFO) *rsk=NULL;
X509_ALGOR *xalg=NULL; X509_ALGOR *xalg=NULL;
PKCS7_RECIP_INFO *ri=NULL; PKCS7_RECIP_INFO *ri=NULL;
EVP_PKEY *pkey;
ASN1_OCTET_STRING *os=NULL; ASN1_OCTET_STRING *os=NULL;
i=OBJ_obj2nid(p7->type); i=OBJ_obj2nid(p7->type);
...@@ -204,8 +263,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) ...@@ -204,8 +263,6 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
unsigned char key[EVP_MAX_KEY_LENGTH]; unsigned char key[EVP_MAX_KEY_LENGTH];
unsigned char iv[EVP_MAX_IV_LENGTH]; unsigned char iv[EVP_MAX_IV_LENGTH];
int keylen,ivlen; int keylen,ivlen;
int jj,max;
unsigned char *tmp;
EVP_CIPHER_CTX *ctx; EVP_CIPHER_CTX *ctx;
if ((btmp=BIO_new(BIO_f_cipher())) == NULL) if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
...@@ -233,46 +290,12 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) ...@@ -233,46 +290,12 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
} }
/* Lets do the pub key stuff :-) */ /* Lets do the pub key stuff :-) */
max=0;
for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
{
ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
if (ri->cert == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_MISSING_CERIPEND_INFO);
goto err;
}
pkey=X509_get_pubkey(ri->cert);
jj=EVP_PKEY_size(pkey);
EVP_PKEY_free(pkey);
if (max < jj) max=jj;
}
if ((tmp=(unsigned char *)OPENSSL_malloc(max)) == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_MALLOC_FAILURE);
goto err;
}
for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++) for (i=0; i<sk_PKCS7_RECIP_INFO_num(rsk); i++)
{ {
ri=sk_PKCS7_RECIP_INFO_value(rsk,i); ri=sk_PKCS7_RECIP_INFO_value(rsk,i);
pkey=X509_get_pubkey(ri->cert); if (pkcs7_encode_rinfo(ri, key, keylen) <= 0)
jj=EVP_PKEY_encrypt_old(tmp,key,keylen,pkey);
EVP_PKEY_free(pkey);
if (jj <= 0)
{
PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_EVP_LIB);
OPENSSL_free(tmp);
goto err;
}
if (!M_ASN1_OCTET_STRING_set(ri->enc_key,tmp,jj))
{
PKCS7err(PKCS7_F_PKCS7_DATAINIT,
ERR_R_MALLOC_FAILURE);
OPENSSL_free(tmp);
goto err; goto err;
}
} }
OPENSSL_free(tmp);
OPENSSL_cleanse(key, keylen); OPENSSL_cleanse(key, keylen);
if (out == NULL) if (out == NULL)
......
...@@ -404,6 +404,7 @@ void ERR_load_PKCS7_strings(void); ...@@ -404,6 +404,7 @@ void ERR_load_PKCS7_strings(void);
#define PKCS7_F_PKCS7_DATASIGN 106 #define PKCS7_F_PKCS7_DATASIGN 106
#define PKCS7_F_PKCS7_DATAVERIFY 107 #define PKCS7_F_PKCS7_DATAVERIFY 107
#define PKCS7_F_PKCS7_DECRYPT 114 #define PKCS7_F_PKCS7_DECRYPT 114
#define PKCS7_F_PKCS7_ENCODE_RINFO 132
#define PKCS7_F_PKCS7_ENCRYPT 115 #define PKCS7_F_PKCS7_ENCRYPT 115
#define PKCS7_F_PKCS7_FIND_DIGEST 127 #define PKCS7_F_PKCS7_FIND_DIGEST 127
#define PKCS7_F_PKCS7_GET0_SIGNERS 124 #define PKCS7_F_PKCS7_GET0_SIGNERS 124
...@@ -425,6 +426,7 @@ void ERR_load_PKCS7_strings(void); ...@@ -425,6 +426,7 @@ void ERR_load_PKCS7_strings(void);
#define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 #define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144
#define PKCS7_R_CIPHER_NOT_INITIALIZED 116 #define PKCS7_R_CIPHER_NOT_INITIALIZED 116
#define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 #define PKCS7_R_CONTENT_AND_DATA_PRESENT 118
#define PKCS7_R_CTRL_ERROR 152
#define PKCS7_R_DECODE_ERROR 130 #define PKCS7_R_DECODE_ERROR 130
#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100 #define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100
#define PKCS7_R_DECRYPT_ERROR 119 #define PKCS7_R_DECRYPT_ERROR 119
......
...@@ -86,6 +86,7 @@ static ERR_STRING_DATA PKCS7_str_functs[]= ...@@ -86,6 +86,7 @@ static ERR_STRING_DATA PKCS7_str_functs[]=
{ERR_FUNC(PKCS7_F_PKCS7_DATASIGN), "PKCS7_DATASIGN"}, {ERR_FUNC(PKCS7_F_PKCS7_DATASIGN), "PKCS7_DATASIGN"},
{ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"}, {ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"},
{ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"}, {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"},
{ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO), "PKCS7_ENCODE_RINFO"},
{ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"}, {ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"},
{ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_FIND_DIGEST"}, {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"},
...@@ -110,6 +111,7 @@ static ERR_STRING_DATA PKCS7_str_reasons[]= ...@@ -110,6 +111,7 @@ static ERR_STRING_DATA PKCS7_str_reasons[]=
{ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"}, {ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
{ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED),"cipher not initialized"}, {ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED),"cipher not initialized"},
{ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),"content and data present"}, {ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT),"content and data present"},
{ERR_REASON(PKCS7_R_CTRL_ERROR) ,"ctrl error"},
{ERR_REASON(PKCS7_R_DECODE_ERROR) ,"decode error"}, {ERR_REASON(PKCS7_R_DECODE_ERROR) ,"decode error"},
{ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH),"decrypted key is wrong length"}, {ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH),"decrypted key is wrong length"},
{ERR_REASON(PKCS7_R_DECRYPT_ERROR) ,"decrypt error"}, {ERR_REASON(PKCS7_R_DECRYPT_ERROR) ,"decrypt error"},
......
...@@ -405,6 +405,10 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) ...@@ -405,6 +405,10 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
rctx->md = p2; rctx->md = p2;
return 1; return 1;
case EVP_PKEY_CTRL_PKCS7_ENCRYPT:
case EVP_PKEY_CTRL_PKCS7_DECRYPT:
return 1;
default: default:
return -2; return -2;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册