zxid
view release on metacpan or search on metacpan
smime-vfy.c view on Meta::CPAN
if (data_out) *data_out = NULL;
if (!x509 || !pkey || !enc_entity || !data_out) GOTO_ERR("NULL arg(s)");
LOG_PRINT("decrypt: get_pkcs7_from_pem");
if (!(p7 = get_pkcs7_from_pem(enc_entity))) goto err;
/* Decrypt the symmetric key with private key and obtain symmetric
* cipher stream (BIO). The cert is needed here to look up one of
* possibly multiple recipient infos present in PKCS7 object. Issuer
* and serial number must match (these two fields form unique ID for
* cert). Actual public key part of the X509 cert is not used for
* anything here. */
LOG_PRINT("decrypt: dataDecode");
if (!(p7bio=PKCS7_dataDecode(p7,pkey,NULL/*detached*/,x509)))
GOTO_ERR("12 no recipient matches cert or private key could not decrypt, i.e. wrong key (PKCS7_dataDecode)");
LOG_PRINT("decrypt: ready to pump");
/* Pump data from p7bio to decrypt symmetric cipher */
if (!(wbio = BIO_new(BIO_s_mem()))) GOTO_ERR("no memory?");
for (;;) {
if ((i=BIO_read(p7bio,buf,sizeof(buf))) <= 0) break;
BIO_write(wbio,buf,i);
}
BIO_flush(wbio);
BIO_free_all(p7bio);
p7bio = NULL;
PKCS7_free(p7);
p7 = NULL;
LOG_PRINT("decrypt: pump done");
/* Return data (this should now be easier because we just freed
* some memory) */
n = get_written_BIO_data(wbio, data_out);
BIO_free_all(wbio);
return n;
err:
if (p7) PKCS7_free(p7);
if (wbio) BIO_free_all(wbio);
if (p7bio) BIO_free_all(p7bio);
return -1;
}
/* Called by: main */
int /* return size of data, -1 on failure */
smime_decrypt(const char* privkey,
const char* passwd,
const char* enc_entity,
char** data_out)
{
int n = -1;
EVP_PKEY *pkey = NULL;
X509 *x509 = NULL;
if (data_out) *data_out = NULL;
if (!privkey || !passwd || !enc_entity || !data_out) GOTO_ERR("NULL arg(s)");
if (!(pkey = open_private_key(privkey, passwd))) goto err;
if (!(x509 = extract_certificate(privkey))) goto err;
n = decrypt(x509, pkey, enc_entity, data_out);
err:
if (pkey) EVP_PKEY_free(pkey);
if (x509) X509_free(x509);
return n;
}
/* ------------------------------------------------ */
#if 0
/* copied from verify.c */
/* should be X509* but we can just have them as char*. (??? --Sampo) */
/* Called by: */
static int
verify_callback(int ok, X509_STORE_CTX *ctx) {
char buf[256];
X509 *err_cert;
int err,depth;
err_cert=X509_STORE_CTX_get_current_cert(ctx);
err= X509_STORE_CTX_get_error(ctx);
depth= X509_STORE_CTX_get_error_depth(ctx);
X509_NAME_oneline(X509_get_subject_name(err_cert),buf,sizeof(buf));
fprintf(stderr,"depth=%d %s\n",depth,buf);
if (!ok) {
fprintf(stderr,"verify error:num=%d:%s\n",err,
X509_verify_cert_error_string(err));
if (depth < 6) {
ok=1;
X509_STORE_CTX_set_error(ctx,X509_V_OK);
} else {
ok=0;
X509_STORE_CTX_set_error(ctx,X509_V_ERR_CERT_CHAIN_TOO_LONG);
}
}
switch (ctx->error) {
case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert),buf,sizeof(buf));
fprintf(stderr,"issuer= %s\n",buf);
break;
#if 1
case X509_V_ERR_CERT_NOT_YET_VALID:
case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
fprintf(stderr,"notBefore=");
/*ASN1_UTCTIME_print(bio_err,X509_get_notBefore(ctx->current_cert));
BIO_printf(bio_err,"\n");*/
break;
case X509_V_ERR_CERT_HAS_EXPIRED:
case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
fprintf(stderr,"notAfter=");
/*ASN1_UTCTIME_print(bio_err,X509_get_notAfter(ctx->current_cert));
BIO_printf(bio_err,"\n"); */
break;
#endif
}
fprintf(stderr,"verify return:%d\n",ok);
return(ok);
( run in 1.827 second using v1.01-cache-2.11-cpan-364913b4093 )