I am trying to implement signature verification for PDFs. It is a big topic so I am taking it one step at a time, first I am trying to actually return a positive in the case of a PDF I have signed myself, using all the default values with the current Acrobat — that should be SHA256 for the digest, and a PKCS7 detached signature. So, I crack out openssl, and by reading the byte range given in the PDF and calling the SHA256_*
functions I have a hash to compare against. So now I need to read the certificate data etc, and use the PKCS7_*
functions. This one looks to be the one I want:
int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, BIO *indata, BIO *out, int flags);
as found in the documentation. Except said documentation doesn't tell me how to construct any of these things. Ok, so I think the BIO *indata
can be made with some of the functions in here and the array of certs using these (despite having not worked out the precise details), but what about the PKCS7 *p7
, or the STACK_OF(x)
called for. I cannot find any documented way of initialising these structures. There are some pkcs7_ctrl functions in the pkcs7.h
header:-
long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg);
int PKCS7_set_type(PKCS7 *p7, int type);
int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other);
int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data);
int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, const EVP_MD *dgst);
int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si);
int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i);
int PKCS7_add_certificate(PKCS7 *p7, X509 *x509);
int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509);
int PKCS7_content_new(PKCS7 *p7, int nid);
int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx,
BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si);
int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, X509 *x509);
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 *pcert);
but without some guidelines this doesn't seem like a forest it would be efficacious to start blindly poking around in.
Have I missed something obvious? How do I go about calling this function with the data values I have parsed from the PDF?