On Mon, 9 Jul 2001, Alexander op de Weegh wrote: > Hi all, > I have padding question. > I am using the following code for creating a PKCS#7 > signed and enveloped message: > > X509 *signer, *recipient; > RSA *signkey; > p7 = PKCS7_new(); > PKCS7_set_type(p7, NID_pkcs7_signedAndEnveloped); > PKCS7_add_certificate(p7, signer); > PKCS7_add_certificate(p7, recipient); > pkey = EVP_PKEY_new(); > EVP_PKEY_assign_RSA(pkey, signkey); > si = PKCS7_add_signature(p7, signer, pkey, EVP_md5()); > ri = PKCS7_add_recipient(p7, recipient); > PKCS7_set_cipher(p7, EVP_des_ede3_cbc()); > p7bio = PKCS7_dataInit(p7, NULL); > BIO_write(data, datalen); > PKCS7_dataFinal(p7, p7bio); I was capable to decode plaintext and verify the hash using the code attached, linked against 0.9.6b > After doing this, I write the PKCS#7 message as PEM, send it to another > machine and decode it there. I get an error, saying the no valid padding is > found. What was the code that says that? Any more details on the error? > Which is quite logical, if you ask me, since the data that is > encrypted using 3DES is not padded at all. So, I add padding and then do the > BIO_write(). Then the other machine, complaints about an invalid signature. > Which is also logical, because the receiver decrypts the data, removes the > padding and then calculates the hash and compares it with the signature. > But, on the sender's side, the signature is calculated including the > padding! > > Help! What should I do? Hope this code could be useful. Please remember to read http://eprint.iacr.org/2001/045/ps.gz before choosing SignedAndEnveloped, Signed-inside-Enveloped or friends. regards, Vadim
/* PKCS7 Signed And Enveloped basic operations */ #include <stdio.h> #include <string.h> #include <assert.h> #include <openssl/err.h> #include <openssl/pem.h> #include <openssl/rand.h> #include <openssl/pkcs7.h> int main() { PKCS7 *enc, *dec; BIO *p7bio, *fl; EVP_CIPHER *cph; PKCS7_SIGNER_INFO *si; PKCS7_RECIP_INFO *ri; X509 *recpt, *signer; EVP_PKEY *dec_key, *sig_key; int sz, res; #define BIG 10*1024 unsigned char *p, bf[BIG], *src = "Some data", decoded[BIG]; OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); // init PRNG! fl = BIO_new_file("recpt.cert", "r"); recpt = PEM_read_bio_X509(fl, NULL, NULL, NULL); BIO_free(fl); assert(recpt != NULL); fl = BIO_new_file("recpt.key", "r"); dec_key=PEM_read_bio_PrivateKey(fl, NULL, NULL, NULL); BIO_free(fl); assert(recpt != NULL); fl = BIO_new_file("signer.key", "r"); sig_key=PEM_read_bio_PrivateKey(fl, NULL, NULL, NULL); BIO_free(fl); assert(sig_key != NULL); fl = BIO_new_file("signer.cert", "r"); signer = PEM_read_bio_X509(fl, NULL, NULL, NULL); BIO_free(fl); assert(signer != NULL); // prepare an PKCS7 enc = PKCS7_new(); assert(enc != NULL); res = PKCS7_set_type(enc, NID_pkcs7_signedAndEnveloped); PKCS7_content_new(enc, NID_pkcs7_data); cph = EVP_des_ede3_cbc(); res = PKCS7_set_cipher(enc, cph); ri = PKCS7_add_recipient(enc, recpt); assert(ri != NULL); si = PKCS7_add_signature(enc, signer, sig_key, EVP_sha1()); assert(si != NULL); p7bio = PKCS7_dataInit(enc, NULL); sz = BIO_write(p7bio, src, strlen(src)); assert(sz != 0); BIO_flush(p7bio); res = PKCS7_dataFinal(enc, p7bio); assert(res != 0); // DER-encode p = bf; sz = i2d_PKCS7(enc, &p); // output/input encoded PKCS7 // decode p = bf; dec = d2i_PKCS7(NULL, &p, sz); p7bio = PKCS7_dataDecode(dec, dec_key, NULL, recpt); assert(p7bio != NULL); sz = BIO_read(p7bio, decoded, BIG); if(sz == strlen(src)) printf("Length Ok\n"); if(!strncmp(src, decoded, sz)) printf("Data Ok\n"); // actually, scan signers instead si = sk_PKCS7_SIGNER_INFO_value(dec->d.signed_and_enveloped->signer_info, 0); assert(si != NULL); // try to match calculated and decrypted digests // one should verify certificate(s) as well. res = PKCS7_signatureVerify(p7bio, dec, si, signer); if(res == 1) printf("Signature Ok\n"); return 0; }