[23-Dec-1998] down below; but in later
versions, these hyphens are gone.]
+ *) Reorganise the PKCS#7 library and get rid of some of the more obvious
+ problems: find RecipientInfo structure that matches recipient certificate
+ and initialise the ASN1 structures properly based on passed cipher.
+ [Steve Henson]
+
*) Belatedly make the BN tests actually check the results.
[Ben Laurie]
int EVP_PKEY_save_parameters(EVP_PKEY *pkey,int mode);
int EVP_PKEY_cmp_parameters(EVP_PKEY *a,EVP_PKEY *b);
-int EVP_CIPHER_type(EVP_CIPHER *ctx);
+int EVP_CIPHER_type(const EVP_CIPHER *ctx);
/* calls methods */
int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
{ERR_PACK(0,EVP_F_EVP_OPENINIT,0), "EVP_OpenInit"},
{ERR_PACK(0,EVP_F_EVP_PBE_ALGOR_CIPHERINIT,0), "EVP_PBE_ALGOR_CipherInit"},
{ERR_PACK(0,EVP_F_EVP_PBE_ALG_ADD,0), "EVP_PBE_alg_add"},
-{ERR_PACK(0,EVP_F_EVP_PBE_CIPHERINIT,0), "EVP_PBE_CIPHERINIT"},
+{ERR_PACK(0,EVP_F_EVP_PBE_CIPHERINIT,0), "EVP_PBE_CipherInit"},
{ERR_PACK(0,EVP_F_EVP_PKCS82PKEY,0), "EVP_PKCS82PKEY"},
{ERR_PACK(0,EVP_F_EVP_PKCS8_SET_BROKEN,0), "EVP_PKCS8_SET_BROKEN"},
{ERR_PACK(0,EVP_F_EVP_PKEY2PKCS8,0), "EVP_PKEY2PKCS8"},
}
/* Convert the various cipher NIDs and dummies to a proper OID NID */
-int EVP_CIPHER_type(EVP_CIPHER *ctx)
+int EVP_CIPHER_type(const EVP_CIPHER *ctx)
{
int nid;
nid = EVP_CIPHER_nid(ctx);
/* We need to process the data */
/* We cannot support detached encryption */
- p7bio=PKCS7_dataDecode(p7,pkey,detached,cert_store);
+ p7bio=PKCS7_dataDecode(p7,pkey,detached,x509);
if (p7bio == NULL)
{
case NID_pkcs7_signedAndEnveloped:
rsk=p7->d.signed_and_enveloped->recipientinfo;
md_sk=p7->d.signed_and_enveloped->md_algs;
- evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(p7->d.signed_and_enveloped->enc_data->algorithm->algorithm)));
+ xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
+ evp_cipher=p7->d.signed_and_enveloped->enc_data->cipher;
if (evp_cipher == NULL)
{
- PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT,
+ PKCS7_R_CIPHER_NOT_INITIALIZED);
goto err;
}
- xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
break;
case NID_pkcs7_enveloped:
rsk=p7->d.enveloped->recipientinfo;
- evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(p7->d.enveloped->enc_data->algorithm->algorithm)));
+ xalg=p7->d.enveloped->enc_data->algorithm;
+ evp_cipher=p7->d.enveloped->enc_data->cipher;
if (evp_cipher == NULL)
{
- PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+ PKCS7err(PKCS7_F_PKCS7_DATAINIT,
+ PKCS7_R_CIPHER_NOT_INITIALIZED);
goto err;
}
- xalg=p7->d.enveloped->enc_data->algorithm;
break;
default:
PKCS7err(PKCS7_F_PKCS7_DATAINIT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
int keylen,ivlen;
int jj,max;
unsigned char *tmp;
+ EVP_CIPHER_CTX *ctx;
if ((btmp=BIO_new(BIO_f_cipher())) == NULL)
{
PKCS7err(PKCS7_F_PKCS7_DATAINIT,ERR_R_BIO_LIB);
goto err;
}
+ BIO_get_cipher_ctx(btmp, &ctx);
keylen=EVP_CIPHER_key_length(evp_cipher);
ivlen=EVP_CIPHER_iv_length(evp_cipher);
+ RAND_bytes(key,keylen);
+ EVP_CipherInit(ctx, evp_cipher, key, iv, 1);
+ memset(key, 0, keylen);
+ xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
if (ivlen > 0) {
- EVP_CIPHER_CTX *ctx;
- BIO_get_cipher_ctx(btmp, &ctx);
+ RAND_bytes(iv,ivlen);
if (xalg->parameter == NULL)
xalg->parameter=ASN1_TYPE_new();
if(EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0)
goto err;
}
- RAND_bytes(key,keylen);
/* Lets do the pub key stuff :-) */
max=0;
}
Free(tmp);
- BIO_set_cipher(btmp,evp_cipher,key,iv,1);
-
if (out == NULL)
out=btmp;
else
}
/* int */
-BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio,
- X509_STORE *xs)
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
{
int i,j;
BIO *out=NULL,*btmp=NULL,*etmp=NULL,*bio=NULL;
evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));
if (evp_cipher == NULL)
{
- PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
goto err;
}
xalg=p7->d.signed_and_enveloped->enc_data->algorithm;
evp_cipher=EVP_get_cipherbyname(OBJ_nid2sn(OBJ_obj2nid(enc_alg->algorithm)));
if (evp_cipher == NULL)
{
- PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CIPHER_TYPE);
goto err;
}
xalg=p7->d.enveloped->enc_data->algorithm;
break;
default:
- PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNSUPPORTED_CONTENT_TYPE);
goto err;
}
xa=(X509_ALGOR *)sk_value(md_sk,i);
if ((btmp=BIO_new(BIO_f_md())) == NULL)
{
- PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_BIO_LIB);
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
goto err;
}
evp_md=EVP_get_digestbyname(OBJ_nid2sn(j));
if (evp_md == NULL)
{
- PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_UNKNOWN_DIGEST_TYPE);
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,PKCS7_R_UNKNOWN_DIGEST_TYPE);
goto err;
}
if ((etmp=BIO_new(BIO_f_cipher())) == NULL)
{
- PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_BIO_LIB);
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_BIO_LIB);
goto err;
}
/* It was encrypted, we need to decrypt the secret key
* with the private key */
- /* We need to find a private key for one of the people in the
- * recipentinfo list */
- if (rsk == NULL)
- return(NULL);
-
- /* FIXME: this assumes that the passed private key
- * corresponds to the first RecipientInfo. This in
- * general is not true
+ /* Find the recipientInfo which matches the passed certificate
+ * (if any)
*/
- ri=(PKCS7_RECIP_INFO *)sk_value(rsk,0);
-#if 0
- X509_STORE_CTX_init(&s_ctx,xs,NULL,NULL);
- for (i=0; i<sk_num(rsk); i++)
- {
+ for (i=0; i<sk_num(rsk); i++) {
ri=(PKCS7_RECIP_INFO *)sk_value(rsk,i);
- uf (X509_STORE_get_by_issuer_serial(&s_ctx,
- X509_LU_PKEY,
- ri->issuer_and_serial->issuer,
- ri->issuer_and_serial->serial,
- &ret))
- break;
+ if(!X509_NAME_cmp(ri->issuer_and_serial->issuer,
+ pcert->cert_info->issuer) &&
+ !ASN1_INTEGER_cmp(pcert->cert_info->serialNumber,
+ ri->issuer_and_serial->serial)) break;
ri=NULL;
- }
- if (ri == NULL) return(NULL);
- pkey=ret.data.pkey;
-#endif
- if (pkey == NULL)
- {
+ }
+ if (ri == NULL) {
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+ PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE);
return(NULL);
- }
+ }
jj=EVP_PKEY_size(pkey);
tmp=Malloc(jj+10);
if (tmp == NULL)
{
- PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_MALLOC_FAILURE);
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_MALLOC_FAILURE);
goto err;
}
pkey);
if (jj <= 0)
{
- PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,ERR_R_EVP_LIB);
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,ERR_R_EVP_LIB);
goto err;
}
if (jj != EVP_CIPHER_CTX_key_length(evp_ctx))
{
- PKCS7err(PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
+ PKCS7err(PKCS7_F_PKCS7_DATADECODE,
+ PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH);
goto err;
}
EVP_CipherInit(evp_ctx,NULL,(unsigned char *)tmp,NULL,0);
return(NULL);
}
-int PKCS7_set_cipher(PKCS7 *p7, EVP_CIPHER *cipher)
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher)
{
int i;
PKCS7_ENC_CONTENT *ec;
return(0);
}
- ec->algorithm->algorithm=OBJ_nid2obj(EVP_CIPHER_type(cipher));
- return(ec->algorithm->algorithm != NULL);
+ /* Setup cipher OID */
+
+ ec->cipher = cipher;
+ return 1;
}
ASN1_OBJECT *content_type;
X509_ALGOR *algorithm;
ASN1_OCTET_STRING *enc_data; /* [ 0 ] */
+ const EVP_CIPHER *cipher;
} PKCS7_ENC_CONTENT;
typedef struct pkcs7_enveloped_st
STACK /* PKCS7_RECIP_INFO */ *recipientinfo;
PKCS7_ENC_CONTENT *enc_data;
} PKCS7_ENVELOPE;
-
+
typedef struct pkcs7_signedandenveloped_st
{
ASN1_INTEGER *version; /* version 1 */
BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio);
int PKCS7_dataFinal(PKCS7 *p7, BIO *bio);
-BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509_STORE *xs);
+BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert);
PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509,
PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509);
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, EVP_CIPHER *cipher);
+int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher);
PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx);
ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK *sk);
#define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102
#define PKCS7_F_PKCS7_ADD_SIGNER 103
#define PKCS7_F_PKCS7_CTRL 104
+#define PKCS7_F_PKCS7_DATADECODE 112
#define PKCS7_F_PKCS7_DATAINIT 105
#define PKCS7_F_PKCS7_DATASIGN 106
#define PKCS7_F_PKCS7_DATAVERIFY 107
#define PKCS7_F_PKCS7_SET_CIPHER 108
#define PKCS7_F_PKCS7_SET_CONTENT 109
#define PKCS7_F_PKCS7_SET_TYPE 110
-#define PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT 111
/* Reason codes. */
+#define PKCS7_R_CIPHER_NOT_INITIALIZED 116
#define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100
#define PKCS7_R_DIGEST_FAILURE 101
#define PKCS7_R_INTERNAL_ERROR 102
#define PKCS7_R_MISSING_CERIPEND_INFO 103
+#define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115
#define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104
#define PKCS7_R_SIGNATURE_FAILURE 105
#define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106
{ERR_PACK(0,PKCS7_F_PKCS7_ADD_RECIPIENT_INFO,0), "PKCS7_add_recipient_info"},
{ERR_PACK(0,PKCS7_F_PKCS7_ADD_SIGNER,0), "PKCS7_add_signer"},
{ERR_PACK(0,PKCS7_F_PKCS7_CTRL,0), "PKCS7_ctrl"},
+{ERR_PACK(0,PKCS7_F_PKCS7_DATADECODE,0), "PKCS7_dataDecode"},
{ERR_PACK(0,PKCS7_F_PKCS7_DATAINIT,0), "PKCS7_dataInit"},
{ERR_PACK(0,PKCS7_F_PKCS7_DATASIGN,0), "PKCS7_DATASIGN"},
{ERR_PACK(0,PKCS7_F_PKCS7_DATAVERIFY,0), "PKCS7_dataVerify"},
{ERR_PACK(0,PKCS7_F_PKCS7_SET_CIPHER,0), "PKCS7_set_cipher"},
{ERR_PACK(0,PKCS7_F_PKCS7_SET_CONTENT,0), "PKCS7_set_content"},
{ERR_PACK(0,PKCS7_F_PKCS7_SET_TYPE,0), "PKCS7_set_type"},
-{ERR_PACK(0,PKCS7_F_PKCS7_SIGNENVELOPEDECRYPT,0), "PKCS7_SIGNENVELOPEDECRYPT"},
{0,NULL}
};
static ERR_STRING_DATA PKCS7_str_reasons[]=
{
+{PKCS7_R_CIPHER_NOT_INITIALIZED ,"cipher not initialized"},
{PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH ,"decrypted key is wrong length"},
{PKCS7_R_DIGEST_FAILURE ,"digest failure"},
{PKCS7_R_INTERNAL_ERROR ,"internal error"},
{PKCS7_R_MISSING_CERIPEND_INFO ,"missing ceripend info"},
+{PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE,"no recipient matches certificate"},
{PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE,"operation not supported on this type"},
{PKCS7_R_SIGNATURE_FAILURE ,"signature failure"},
{PKCS7_R_UNABLE_TO_FIND_CERTIFICATE ,"unable to find certificate"},