int i2d_SCEP_MSG_bio( BIO *bio, SCEP_MSG *msg, EVP_PKEY *pkey ) { PKCS7 *p7 = NULL; int ret = 0; /* Generate the signed pkcs7 message */ if( (p7 = i2pk7_SCEP_MSG( msg, pkey )) == NULL ) return 0; ret = i2d_PKCS7_bio(bio, p7); PKCS7_free( p7 ); ERR_clear_error(); return ret; }
/* Base 64 write of PKCS#7 structure */ int B64_write_bio_PKCS7 ( BIO *bio, PKCS7 *p7 ) { BIO *b64 = NULL; int ret = 0; if( !p7 ) return 0; if(!(b64 = BIO_new(BIO_f_base64()))) { PKCS7err(PKCS7_F_B64_WRITE_PKCS7,ERR_R_MALLOC_FAILURE); return 0; } bio = BIO_push(b64, bio); ret = i2d_PKCS7_bio(bio, p7); BIO_flush(bio); bio = BIO_pop(bio); BIO_free(b64); return ret; }
static LUA_FUNCTION(openssl_pkcs7_export) { int pem; PKCS7 * p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); int top = lua_gettop(L); BIO* bio_out = NULL; pem = top > 1 ? lua_toboolean(L, 2) : 1; bio_out = BIO_new(BIO_s_mem()); if (pem) { if (PEM_write_bio_PKCS7(bio_out, p7)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); lua_pushlstring(L, bio_buf->data, bio_buf->length); } else lua_pushnil(L); } else { if (i2d_PKCS7_bio(bio_out, p7)) { BUF_MEM *bio_buf; BIO_get_mem_ptr(bio_out, &bio_buf); lua_pushlstring(L, bio_buf->data, bio_buf->length); } else lua_pushnil(L); } BIO_free(bio_out); return 1; }
static int reply_command(CONF * conf, char *section, char *engine, char *queryfile, char *passin, char *inkey, char *signer, char *chain, const char *policy, char *in, int token_in, char *out, int token_out, int text) { int ret = 0; TS_RESP *response = NULL; BIO *in_bio = NULL; BIO *query_bio = NULL; BIO *inkey_bio = NULL; BIO *signer_bio = NULL; BIO *out_bio = NULL; /* Build response object either from response or query. */ if (in != NULL) { if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end; if (token_in) { /* * We have a ContentInfo (PKCS7) object, add * 'granted' status info around it. */ response = read_PKCS7(in_bio); } else { /* We have a ready-made TS_RESP object. */ response = d2i_TS_RESP_bio(in_bio, NULL); } } else { response = create_response(conf, section, engine, queryfile, passin, inkey, signer, chain, policy); if (response) BIO_printf(bio_err, "Response has been generated.\n"); else BIO_printf(bio_err, "Response is not generated.\n"); } if (response == NULL) goto end; /* Write response either in ASN.1 or text format. */ if ((out_bio = BIO_open_with_default(out, "wb", stdout)) == NULL) goto end; if (text) { /* Text output. */ if (token_out) { TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); if (!TS_TST_INFO_print_bio(out_bio, tst_info)) goto end; } else { if (!TS_RESP_print_bio(out_bio, response)) goto end; } } else { /* ASN.1 DER output. */ if (token_out) { PKCS7 *token = TS_RESP_get_token(response); if (!i2d_PKCS7_bio(out_bio, token)) goto end; } else { if (!i2d_TS_RESP_bio(out_bio, response)) goto end; } } ret = 1; end: ERR_print_errors(bio_err); /* Clean up. */ BIO_free_all(in_bio); BIO_free_all(query_bio); BIO_free_all(inkey_bio); BIO_free_all(signer_bio); BIO_free_all(out_bio); TS_RESP_free(response); return ret; }
/******************************************************************************* 函数名称: cert_pkcs7_wrap 功能描述: 将要发送的消息采用PKCS#7格式进行编码 输入参数: struct scep *s, SCEP操作的结构体指针。 s32 hasra, 是否使用RA证书,1,使用;0,不使用 输出参数: 无 返 回 值: 1,成功;-1,失败 -------------------------------------------------------------------------------- 最近一次修改记录: 修改作者:王朝 修改目的:添加新函数 修改日期:2009年12月28日 *********************************************************************************/ s32 cert_pkcs7_wrap(struct scep *s, s32 hasra) { BIO *databio = NULL; BIO *encbio = NULL; BIO *pkcs7bio = NULL; BIO *memorybio = NULL; BIO *outbio = NULL; BIO *base64bio = NULL; u8 *buffer = NULL; s32 len = 0; STACK_OF(X509) *recipients = NULL; PKCS7 *p7enc = NULL; PKCS7_SIGNER_INFO *si = NULL; STACK_OF(X509_ATTRIBUTE) *attributes = NULL; X509 *signercert = NULL; EVP_PKEY *signerkey = NULL; s32 retval = -1; /* sender nonce */ s->sender_nonce_len = 16; s->sender_nonce = (u8 *)malloc((u32)s->sender_nonce_len); RAND_bytes(s->sender_nonce, s->sender_nonce_len); /* Prepare data payload */ switch(s->request_type) { case SCEP_REQUEST_PKCSREQ: s->request_type_str = SCEP_REQUEST_PKCSREQ_STR; /* Signer cert */ signercert = s->signercert; signerkey = s->signerkey; /* Read request in memory bio */ databio = BIO_new(BIO_s_mem()); if ((i2d_X509_REQ_bio(databio, cert_request)) <= 0) { goto end; } (void)BIO_flush(databio); BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); break; case SCEP_REQUEST_GETCERTINIT: /* Set printable message type */ s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR; /* Signer cert */ signercert = s->signercert; signerkey = s->signerkey; /* Read data in memory bio */ databio = BIO_new(BIO_s_mem()); if ((i2d_pkcs7_issuer_and_subject_bio(databio, s->ias_getcertinit)) <= 0) { goto end; } (void)BIO_flush(databio); BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); break; default: goto end; } /* Below this is the common code for all request_type */ /* Read in the payload */ s->request_len = BIO_get_mem_data(databio, &s->request_payload); BIO_free(databio); databio = NULL; /* Create encryption certificate stack */ if (NULL == (recipients = sk_X509_new_null() )) { goto end; } /* Use different CA cert for encryption if requested */ if (1 == hasra) { if (sk_X509_push(recipients, cert_encert) <= 0) { goto end; } } else { /* Use same CA cert also for encryption */ if (sk_X509_push(recipients, cert_cacert) <= 0) { goto end; } } /* Create BIO for encryption */ if ((encbio = BIO_new_mem_buf(s->request_payload,s->request_len)) == NULL) { goto end; } /* Encrypt */ if (NULL == (p7enc = PKCS7_encrypt(recipients, encbio, cert_enc_alg, PKCS7_BINARY))) { goto end; } BIO_free(encbio); encbio = NULL; sk_X509_free(recipients); recipients = NULL; /* Write encrypted data */ memorybio = BIO_new(BIO_s_mem()); if (i2d_PKCS7_bio(memorybio, p7enc) <= 0) { goto end; } PKCS7_free(p7enc); p7enc = NULL; (void)BIO_flush(memorybio); BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); len = BIO_get_mem_data(memorybio, &buffer); /* Create outer PKCS#7 */ s->request_p7 = PKCS7_new(); if (s->request_p7 == NULL) { goto end; } if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed)) { goto end; } /* Add signer certificate and signature */ PKCS7_add_certificate(s->request_p7, signercert); if ((si = PKCS7_add_signature(s->request_p7,signercert, signerkey, cert_sig_alg)) == NULL) { goto end; } /* Set signed attributes */ attributes = sk_X509_ATTRIBUTE_new_null(); cert_add_attribute_string(attributes, nid_transId, s->transaction_id); cert_add_attribute_string(attributes, nid_messageType, s->request_type_str); cert_add_attribute_octet(attributes, nid_senderNonce, (s8 *)(s->sender_nonce),s->sender_nonce_len); PKCS7_set_signed_attributes(si, attributes); sk_X509_ATTRIBUTE_free(attributes); attributes = NULL; /* Add contentType */ if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType,V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) { goto end; } /* Create new content */ if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data)) { goto end; } /* Write data */ pkcs7bio = PKCS7_dataInit(s->request_p7, NULL); if (pkcs7bio == NULL) { goto end; } if (len != BIO_write(pkcs7bio, buffer, len)) { goto end; } BIO_free(memorybio); memorybio = NULL; /* Finalize PKCS#7 */ if (!PKCS7_dataFinal(s->request_p7, pkcs7bio)) { goto end; } /* base64-encode the data */ /* Create base64 filtering bio */ memorybio = BIO_new(BIO_s_mem()); base64bio = BIO_new(BIO_f_base64()); outbio = BIO_push(base64bio, memorybio); /* Copy PKCS#7 */ i2d_PKCS7_bio(outbio, s->request_p7); (void)BIO_flush(outbio); BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); s->request_len = BIO_get_mem_data(memorybio, &s->request_payload); retval = 1; end: if(NULL != databio) { BIO_free(databio); } if(NULL != encbio) { BIO_free(encbio); } if(NULL != p7enc) { PKCS7_free(p7enc); } if(NULL != pkcs7bio) { BIO_free(pkcs7bio); } if(NULL != memorybio) { BIO_free(memorybio); } if(NULL != base64bio) { BIO_free(base64bio); } if(NULL != recipients) { sk_X509_free(recipients); } if(NULL != attributes) { sk_X509_ATTRIBUTE_free(attributes); } return retval; }
int MAIN(int argc, char **argv) { ENGINE *e = NULL; int operation = 0; int ret = 0; char **args; const char *inmode = "r", *outmode = "w"; char *infile = NULL, *outfile = NULL; char *signerfile = NULL, *recipfile = NULL; char *certfile = NULL, *keyfile = NULL, *contfile=NULL; const EVP_CIPHER *cipher = NULL; PKCS7 *p7 = NULL; X509_STORE *store = NULL; X509 *cert = NULL, *recip = NULL, *signer = NULL; EVP_PKEY *key = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; BIO *in = NULL, *out = NULL, *indata = NULL; int badarg = 0; int flags = PKCS7_DETACHED; char *to = NULL, *from = NULL, *subject = NULL; char *CAfile = NULL, *CApath = NULL; char *passargin = NULL, *passin = NULL; char *inrand = NULL; int need_rand = 0; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME; int keyform = FORMAT_PEM; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif X509_VERIFY_PARAM *vpm = NULL; args = argv + 1; ret = 1; apps_startup(); if (bio_err == NULL) { if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE|BIO_FP_TEXT); } if (!load_config(bio_err, NULL)) goto end; while (!badarg && *args && *args[0] == '-') { if (!strcmp (*args, "-encrypt")) operation = SMIME_ENCRYPT; else if (!strcmp (*args, "-decrypt")) operation = SMIME_DECRYPT; else if (!strcmp (*args, "-sign")) operation = SMIME_SIGN; else if (!strcmp (*args, "-verify")) operation = SMIME_VERIFY; else if (!strcmp (*args, "-pk7out")) operation = SMIME_PK7OUT; #ifndef OPENSSL_NO_DES else if (!strcmp (*args, "-des3")) cipher = EVP_des_ede3_cbc(); else if (!strcmp (*args, "-des")) cipher = EVP_des_cbc(); #endif #ifndef OPENSSL_NO_SEED else if (!strcmp (*args, "-seed")) cipher = EVP_seed_cbc(); #endif #ifndef OPENSSL_NO_RC2 else if (!strcmp (*args, "-rc2-40")) cipher = EVP_rc2_40_cbc(); else if (!strcmp (*args, "-rc2-128")) cipher = EVP_rc2_cbc(); else if (!strcmp (*args, "-rc2-64")) cipher = EVP_rc2_64_cbc(); #endif #ifndef OPENSSL_NO_AES else if (!strcmp(*args,"-aes128")) cipher = EVP_aes_128_cbc(); else if (!strcmp(*args,"-aes192")) cipher = EVP_aes_192_cbc(); else if (!strcmp(*args,"-aes256")) cipher = EVP_aes_256_cbc(); #endif #ifndef OPENSSL_NO_CAMELLIA else if (!strcmp(*args,"-camellia128")) cipher = EVP_camellia_128_cbc(); else if (!strcmp(*args,"-camellia192")) cipher = EVP_camellia_192_cbc(); else if (!strcmp(*args,"-camellia256")) cipher = EVP_camellia_256_cbc(); #endif else if (!strcmp (*args, "-text")) flags |= PKCS7_TEXT; else if (!strcmp (*args, "-nointern")) flags |= PKCS7_NOINTERN; else if (!strcmp (*args, "-noverify")) flags |= PKCS7_NOVERIFY; else if (!strcmp (*args, "-nochain")) flags |= PKCS7_NOCHAIN; else if (!strcmp (*args, "-nocerts")) flags |= PKCS7_NOCERTS; else if (!strcmp (*args, "-noattr")) flags |= PKCS7_NOATTR; else if (!strcmp (*args, "-nodetach")) flags &= ~PKCS7_DETACHED; else if (!strcmp (*args, "-nosmimecap")) flags |= PKCS7_NOSMIMECAP; else if (!strcmp (*args, "-binary")) flags |= PKCS7_BINARY; else if (!strcmp (*args, "-nosigs")) flags |= PKCS7_NOSIGS; else if (!strcmp (*args, "-nooldmime")) flags |= PKCS7_NOOLDMIMETYPE; else if (!strcmp (*args, "-crlfeol")) flags |= PKCS7_CRLFEOL; else if (!strcmp(*args,"-rand")) { if (args[1]) { args++; inrand = *args; } else badarg = 1; need_rand = 1; } #ifndef OPENSSL_NO_ENGINE else if (!strcmp(*args,"-engine")) { if (args[1]) { args++; engine = *args; } else badarg = 1; } #endif else if (!strcmp(*args,"-passin")) { if (args[1]) { args++; passargin = *args; } else badarg = 1; } else if (!strcmp (*args, "-to")) { if (args[1]) { args++; to = *args; } else badarg = 1; } else if (!strcmp (*args, "-from")) { if (args[1]) { args++; from = *args; } else badarg = 1; } else if (!strcmp (*args, "-subject")) { if (args[1]) { args++; subject = *args; } else badarg = 1; } else if (!strcmp (*args, "-signer")) { if (args[1]) { args++; signerfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-recip")) { if (args[1]) { args++; recipfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-inkey")) { if (args[1]) { args++; keyfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-keyform")) { if (args[1]) { args++; keyform = str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-certfile")) { if (args[1]) { args++; certfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-CAfile")) { if (args[1]) { args++; CAfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-CApath")) { if (args[1]) { args++; CApath = *args; } else badarg = 1; } else if (!strcmp (*args, "-in")) { if (args[1]) { args++; infile = *args; } else badarg = 1; } else if (!strcmp (*args, "-inform")) { if (args[1]) { args++; informat = str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-outform")) { if (args[1]) { args++; outformat = str2fmt(*args); } else badarg = 1; } else if (!strcmp (*args, "-out")) { if (args[1]) { args++; outfile = *args; } else badarg = 1; } else if (!strcmp (*args, "-content")) { if (args[1]) { args++; contfile = *args; } else badarg = 1; } else if (args_verify(&args, NULL, &badarg, bio_err, &vpm)) continue; else badarg = 1; args++; } if (operation == SMIME_SIGN) { if (!signerfile) { BIO_printf(bio_err, "No signer certificate specified\n"); badarg = 1; } need_rand = 1; } else if (operation == SMIME_DECRYPT) { if (!recipfile && !keyfile) { BIO_printf(bio_err, "No recipient certificate or key specified\n"); badarg = 1; } } else if (operation == SMIME_ENCRYPT) { if (!*args) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); badarg = 1; } need_rand = 1; } else if (!operation) badarg = 1; if (badarg) { BIO_printf (bio_err, "Usage smime [options] cert.pem ...\n"); BIO_printf (bio_err, "where options are\n"); BIO_printf (bio_err, "-encrypt encrypt message\n"); BIO_printf (bio_err, "-decrypt decrypt encrypted message\n"); BIO_printf (bio_err, "-sign sign message\n"); BIO_printf (bio_err, "-verify verify signed message\n"); BIO_printf (bio_err, "-pk7out output PKCS#7 structure\n"); #ifndef OPENSSL_NO_DES BIO_printf (bio_err, "-des3 encrypt with triple DES\n"); BIO_printf (bio_err, "-des encrypt with DES\n"); #endif #ifndef OPENSSL_NO_SEED BIO_printf (bio_err, "-seed encrypt with SEED\n"); #endif #ifndef OPENSSL_NO_RC2 BIO_printf (bio_err, "-rc2-40 encrypt with RC2-40 (default)\n"); BIO_printf (bio_err, "-rc2-64 encrypt with RC2-64\n"); BIO_printf (bio_err, "-rc2-128 encrypt with RC2-128\n"); #endif #ifndef OPENSSL_NO_AES BIO_printf (bio_err, "-aes128, -aes192, -aes256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc aes\n"); #endif #ifndef OPENSSL_NO_CAMELLIA BIO_printf (bio_err, "-camellia128, -camellia192, -camellia256\n"); BIO_printf (bio_err, " encrypt PEM output with cbc camellia\n"); #endif BIO_printf (bio_err, "-nointern don't search certificates in message for signer\n"); BIO_printf (bio_err, "-nosigs don't verify message signature\n"); BIO_printf (bio_err, "-noverify don't verify signers certificate\n"); BIO_printf (bio_err, "-nocerts don't include signers certificate when signing\n"); BIO_printf (bio_err, "-nodetach use opaque signing\n"); BIO_printf (bio_err, "-noattr don't include any signed attributes\n"); BIO_printf (bio_err, "-binary don't translate message to text\n"); BIO_printf (bio_err, "-certfile file other certificates file\n"); BIO_printf (bio_err, "-signer file signer certificate file\n"); BIO_printf (bio_err, "-recip file recipient certificate file for decryption\n"); BIO_printf (bio_err, "-in file input file\n"); BIO_printf (bio_err, "-inform arg input format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-inkey file input private key (if not signer or recipient)\n"); BIO_printf (bio_err, "-keyform arg input private key format (PEM or ENGINE)\n"); BIO_printf (bio_err, "-out file output file\n"); BIO_printf (bio_err, "-outform arg output format SMIME (default), PEM or DER\n"); BIO_printf (bio_err, "-content file supply or override content for detached signature\n"); BIO_printf (bio_err, "-to addr to address\n"); BIO_printf (bio_err, "-from ad from address\n"); BIO_printf (bio_err, "-subject s subject\n"); BIO_printf (bio_err, "-text include or delete text MIME headers\n"); BIO_printf (bio_err, "-CApath dir trusted certificates directory\n"); BIO_printf (bio_err, "-CAfile file trusted certificates file\n"); BIO_printf (bio_err, "-crl_check check revocation status of signer's certificate using CRLs\n"); BIO_printf (bio_err, "-crl_check_all check revocation status of signer's certificate chain using CRLs\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf (bio_err, "-engine e use engine e, possibly a hardware device.\n"); #endif BIO_printf (bio_err, "-passin arg input file pass phrase source\n"); BIO_printf(bio_err, "-rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR); BIO_printf(bio_err, " load the file (or the files in the directory) into\n"); BIO_printf(bio_err, " the random number generator\n"); BIO_printf (bio_err, "cert.pem recipient certificate(s) for encryption\n"); goto end; } #ifndef OPENSSL_NO_ENGINE e = setup_engine(bio_err, engine, 0); #endif if (!app_passwd(bio_err, passargin, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (need_rand) { app_RAND_load_file(NULL, bio_err, (inrand != NULL)); if (inrand != NULL) BIO_printf(bio_err,"%ld semi-random bytes loaded\n", app_RAND_load_files(inrand)); } ret = 2; if (operation != SMIME_SIGN) flags &= ~PKCS7_DETACHED; if (operation & SMIME_OP) { if (flags & PKCS7_BINARY) inmode = "rb"; if (outformat == FORMAT_ASN1) outmode = "wb"; } else { if (flags & PKCS7_BINARY) outmode = "wb"; if (informat == FORMAT_ASN1) inmode = "rb"; } if (operation == SMIME_ENCRYPT) { if (!cipher) { #ifndef OPENSSL_NO_RC2 cipher = EVP_rc2_40_cbc(); #else BIO_printf(bio_err, "No cipher selected\n"); goto end; #endif } encerts = sk_X509_new_null(); while (*args) { if (!(cert = load_cert(bio_err,*args,FORMAT_PEM, NULL, e, "recipient certificate file"))) { #if 0 /* An appropriate message is already printed */ BIO_printf(bio_err, "Can't read recipient certificate file %s\n", *args); #endif goto end; } sk_X509_push(encerts, cert); cert = NULL; args++; } } if (signerfile && (operation == SMIME_SIGN)) { if (!(signer = load_cert(bio_err,signerfile,FORMAT_PEM, NULL, e, "signer certificate"))) { #if 0 /* An appropri message has already been printed */ BIO_printf(bio_err, "Can't read signer certificate file %s\n", signerfile); #endif goto end; } } if (certfile) { if (!(other = load_certs(bio_err,certfile,FORMAT_PEM, NULL, e, "certificate file"))) { #if 0 /* An appropriate message has already been printed */ BIO_printf(bio_err, "Can't read certificate file %s\n", certfile); #endif ERR_print_errors(bio_err); goto end; } } if (recipfile && (operation == SMIME_DECRYPT)) { if (!(recip = load_cert(bio_err,recipfile,FORMAT_PEM,NULL, e, "recipient certificate file"))) { #if 0 /* An appropriate message has alrady been printed */ BIO_printf(bio_err, "Can't read recipient certificate file %s\n", recipfile); #endif ERR_print_errors(bio_err); goto end; } } if (operation == SMIME_DECRYPT) { if (!keyfile) keyfile = recipfile; } else if (operation == SMIME_SIGN) { if (!keyfile) keyfile = signerfile; } else keyfile = NULL; if (keyfile) { key = load_key(bio_err, keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } if (infile) { if (!(in = BIO_new_file(infile, inmode))) { BIO_printf (bio_err, "Can't open input file %s\n", infile); goto end; } } else in = BIO_new_fp(stdin, BIO_NOCLOSE); if (outfile) { if (!(out = BIO_new_file(outfile, outmode))) { BIO_printf (bio_err, "Can't open output file %s\n", outfile); goto end; } } else { out = BIO_new_fp(stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } if (operation == SMIME_VERIFY) { if (!(store = setup_verify(bio_err, CAfile, CApath))) goto end; X509_STORE_set_verify_cb_func(store, smime_cb); if (vpm) X509_STORE_set1_param(store, vpm); } ret = 3; if (operation == SMIME_ENCRYPT) p7 = PKCS7_encrypt(encerts, in, cipher, flags); else if (operation == SMIME_SIGN) { /* If detached data and SMIME output enable partial * signing. */ if ((flags & PKCS7_DETACHED) && (outformat == FORMAT_SMIME)) flags |= PKCS7_STREAM; p7 = PKCS7_sign(signer, key, other, in, flags); } else { if (informat == FORMAT_SMIME) p7 = SMIME_read_PKCS7(in, &indata); else if (informat == FORMAT_PEM) p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); else if (informat == FORMAT_ASN1) p7 = d2i_PKCS7_bio(in, NULL); else { BIO_printf(bio_err, "Bad input format for PKCS#7 file\n"); goto end; } if (!p7) { BIO_printf(bio_err, "Error reading S/MIME message\n"); goto end; } if (contfile) { BIO_free(indata); if (!(indata = BIO_new_file(contfile, "rb"))) { BIO_printf(bio_err, "Can't read content file %s\n", contfile); goto end; } } } if (!p7) { BIO_printf(bio_err, "Error creating PKCS#7 structure\n"); goto end; } ret = 4; if (operation == SMIME_DECRYPT) { if (!PKCS7_decrypt(p7, key, recip, out, flags)) { BIO_printf(bio_err, "Error decrypting PKCS#7 structure\n"); goto end; } } else if (operation == SMIME_VERIFY) { STACK_OF(X509) *signers; if (PKCS7_verify(p7, other, store, indata, out, flags)) BIO_printf(bio_err, "Verification successful\n"); else { BIO_printf(bio_err, "Verification failure\n"); goto end; } signers = PKCS7_get0_signers(p7, other, flags); if (!save_certs(signerfile, signers)) { BIO_printf(bio_err, "Error writing signers to %s\n", signerfile); ret = 5; goto end; } sk_X509_free(signers); } else if (operation == SMIME_PK7OUT) PEM_write_bio_PKCS7(out, p7); else { if (to) BIO_printf(out, "To: %s\n", to); if (from) BIO_printf(out, "From: %s\n", from); if (subject) BIO_printf(out, "Subject: %s\n", subject); if (outformat == FORMAT_SMIME) SMIME_write_PKCS7(out, p7, in, flags); else if (outformat == FORMAT_PEM) PEM_write_bio_PKCS7(out,p7); else if (outformat == FORMAT_ASN1) i2d_PKCS7_bio(out,p7); else { BIO_printf(bio_err, "Bad output format for PKCS#7 file\n"); goto end; } } ret = 0; end: if (need_rand) app_RAND_write_file(NULL, bio_err); if (ret) ERR_print_errors(bio_err); sk_X509_pop_free(encerts, X509_free); sk_X509_pop_free(other, X509_free); if (vpm) X509_VERIFY_PARAM_free(vpm); X509_STORE_free(store); X509_free(cert); X509_free(recip); X509_free(signer); EVP_PKEY_free(key); PKCS7_free(p7); BIO_free(in); BIO_free(indata); BIO_free_all(out); if (passin) OPENSSL_free(passin); return (ret); }
int pkcs7_main(int argc, char **argv) { ENGINE *e = NULL; PKCS7 *p7 = NULL; BIO *in = NULL, *out = NULL; int informat = FORMAT_PEM, outformat = FORMAT_PEM; char *infile = NULL, *outfile = NULL, *prog; int i, print_certs = 0, text = 0, noout = 0, p7_print = 0, ret = 1; OPTION_CHOICE o; prog = opt_init(argc, argv, pkcs7_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(pkcs7_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) goto opthelp; break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_NOOUT: noout = 1; break; case OPT_TEXT: text = 1; break; case OPT_PRINT: p7_print = 1; break; case OPT_PRINT_CERTS: print_certs = 1; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; } } argc = opt_num_rest(); if (argc != 0) goto opthelp; in = bio_open_default(infile, 'r', informat); if (in == NULL) goto end; if (informat == FORMAT_ASN1) p7 = d2i_PKCS7_bio(in, NULL); else p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); if (p7 == NULL) { BIO_printf(bio_err, "unable to load PKCS7 object\n"); ERR_print_errors(bio_err); goto end; } out = bio_open_default(outfile, 'w', outformat); if (out == NULL) goto end; if (p7_print) PKCS7_print_ctx(out, p7, 0, NULL); if (print_certs) { STACK_OF(X509) *certs = NULL; STACK_OF(X509_CRL) *crls = NULL; i = OBJ_obj2nid(p7->type); switch (i) { case NID_pkcs7_signed: if (p7->d.sign != NULL) { certs = p7->d.sign->cert; crls = p7->d.sign->crl; } break; case NID_pkcs7_signedAndEnveloped: if (p7->d.signed_and_enveloped != NULL) { certs = p7->d.signed_and_enveloped->cert; crls = p7->d.signed_and_enveloped->crl; } break; default: break; } if (certs != NULL) { X509 *x; for (i = 0; i < sk_X509_num(certs); i++) { x = sk_X509_value(certs, i); if (text) X509_print(out, x); else dump_cert_text(out, x); if (!noout) PEM_write_bio_X509(out, x); BIO_puts(out, "\n"); } } if (crls != NULL) { X509_CRL *crl; for (i = 0; i < sk_X509_CRL_num(crls); i++) { crl = sk_X509_CRL_value(crls, i); X509_CRL_print_ex(out, crl, get_nameopt()); if (!noout) PEM_write_bio_X509_CRL(out, crl); BIO_puts(out, "\n"); } } ret = 0; goto end; } if (!noout) { if (outformat == FORMAT_ASN1) i = i2d_PKCS7_bio(out, p7); else i = PEM_write_bio_PKCS7(out, p7); if (!i) { BIO_printf(bio_err, "unable to write pkcs7 object\n"); ERR_print_errors(bio_err); goto end; } } ret = 0; end: PKCS7_free(p7); release_engine(e); BIO_free(in); BIO_free_all(out); return ret; }
int crl2pkcs7_main(int argc, char **argv) { BIO *in = NULL, *out = NULL; PKCS7 *p7 = NULL; PKCS7_SIGNED *p7s = NULL; STACK_OF(OPENSSL_STRING) *certflst = NULL; STACK_OF(X509) *cert_stack = NULL; STACK_OF(X509_CRL) *crl_stack = NULL; X509_CRL *crl = NULL; char *infile = NULL, *outfile = NULL, *prog, *certfile; int i = 0, informat = FORMAT_PEM, outformat = FORMAT_PEM, ret = 1, nocrl = 0; OPTION_CHOICE o; prog = opt_init(argc, argv, crl2pkcs7_options); while ((o = opt_next()) != OPT_EOF) { switch (o) { case OPT_EOF: case OPT_ERR: opthelp: BIO_printf(bio_err, "%s: Use -help for summary.\n", prog); goto end; case OPT_HELP: opt_help(crl2pkcs7_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat)) goto opthelp; break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUT: outfile = opt_arg(); break; case OPT_NOCRL: nocrl = 1; break; case OPT_CERTFILE: if ((certflst == NULL) && (certflst = sk_OPENSSL_STRING_new_null()) == NULL) goto end; if (!sk_OPENSSL_STRING_push(certflst, *(++argv))) { sk_OPENSSL_STRING_free(certflst); goto end; } break; } } argc = opt_num_rest(); argv = opt_rest(); if (!app_load_modules(NULL)) goto end; if (!nocrl) { in = bio_open_default(infile, RB(informat)); if (in == NULL) goto end; if (informat == FORMAT_ASN1) crl = d2i_X509_CRL_bio(in, NULL); else if (informat == FORMAT_PEM) crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); if (crl == NULL) { BIO_printf(bio_err, "unable to load CRL\n"); ERR_print_errors(bio_err); goto end; } } if ((p7 = PKCS7_new()) == NULL) goto end; if ((p7s = PKCS7_SIGNED_new()) == NULL) goto end; p7->type = OBJ_nid2obj(NID_pkcs7_signed); p7->d.sign = p7s; p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data); if (!ASN1_INTEGER_set(p7s->version, 1)) goto end; if ((crl_stack = sk_X509_CRL_new_null()) == NULL) goto end; p7s->crl = crl_stack; if (crl != NULL) { sk_X509_CRL_push(crl_stack, crl); crl = NULL; /* now part of p7 for OPENSSL_freeing */ } if ((cert_stack = sk_X509_new_null()) == NULL) goto end; p7s->cert = cert_stack; if (certflst) for (i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) { certfile = sk_OPENSSL_STRING_value(certflst, i); if (add_certs_from_file(cert_stack, certfile) < 0) { BIO_printf(bio_err, "error loading certificates\n"); ERR_print_errors(bio_err); goto end; } } sk_OPENSSL_STRING_free(certflst); out = bio_open_default(outfile, WB(outformat)); if (out == NULL) goto end; if (outformat == FORMAT_ASN1) i = i2d_PKCS7_bio(out, p7); else if (outformat == FORMAT_PEM) i = PEM_write_bio_PKCS7(out, p7); if (!i) { BIO_printf(bio_err, "unable to write pkcs7 object\n"); ERR_print_errors(bio_err); goto end; } ret = 0; end: BIO_free(in); BIO_free_all(out); PKCS7_free(p7); X509_CRL_free(crl); return (ret); }
/* * Wrap data in PKCS#7 envelopes and base64-encode the result. * Data is PKCS#10 request in PKCSReq, or pkcs7_issuer_and_subject * structure in GetCertInitial and PKCS7_ISSUER_AND_SERIAL in * GetCert and GETCrl. */ int pkcs7_wrap(struct scep *s) { BIO *databio = NULL; BIO *encbio = NULL; BIO *pkcs7bio = NULL; BIO *memorybio = NULL; BIO *outbio = NULL; BIO *base64bio = NULL; unsigned char *buffer = NULL; int rc, len = 0; STACK_OF(X509) *recipients; PKCS7 *p7enc; PKCS7_SIGNER_INFO *si; STACK_OF(X509_ATTRIBUTE) *attributes; X509 *signercert = NULL; EVP_PKEY *signerkey = NULL; /* Create a new sender nonce for all messages * XXXXXXXXXXXXXX should it be per transaction? */ s->sender_nonce_len = 16; s->sender_nonce = (unsigned char *)malloc(s->sender_nonce_len); RAND_bytes(s->sender_nonce, s->sender_nonce_len); /* Prepare data payload */ switch(s->request_type) { case SCEP_REQUEST_PKCSREQ: /* * Set printable message type * We set this later as an autheticated attribute * "messageType". */ s->request_type_str = SCEP_REQUEST_PKCSREQ_STR; /* Signer cert */ signercert = s->signercert; signerkey = s->signerkey; /* Create inner PKCS#7 */ if (v_flag) printf("%s: creating inner PKCS#7\n", pname); /* Read request in memory bio */ databio = BIO_new(BIO_s_mem()); if ((rc = i2d_X509_REQ_bio(databio, request)) <= 0) { fprintf(stderr, "%s: error writing " "certificate request in bio\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } BIO_flush(databio); BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); break; case SCEP_REQUEST_GETCERTINIT: /* Set printable message type */ s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR; /* Signer cert */ signercert = s->signercert; signerkey = s->signerkey; /* Create inner PKCS#7 */ if (v_flag) printf("%s: creating inner PKCS#7\n", pname); /* Read data in memory bio */ databio = BIO_new(BIO_s_mem()); if ((rc = i2d_pkcs7_issuer_and_subject_bio(databio, s->ias_getcertinit)) <= 0) { fprintf(stderr, "%s: error writing " "GetCertInitial data in bio\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } BIO_flush(databio); BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); break; case SCEP_REQUEST_GETCERT: /* Set printable message type */ s->request_type_str = SCEP_REQUEST_GETCERT_STR; /* Signer cert */ signercert = localcert; signerkey = rsa; /* Read data in memory bio */ databio = BIO_new(BIO_s_mem()); if ((rc = i2d_PKCS7_ISSUER_AND_SERIAL_bio(databio, s->ias_getcert)) <= 0) { fprintf(stderr, "%s: error writing " "GetCert data in bio\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } BIO_flush(databio); BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); break; case SCEP_REQUEST_GETCRL: /* Set printable message type */ s->request_type_str = SCEP_REQUEST_GETCRL_STR; /* Signer cert */ signercert = localcert; signerkey = rsa; /* Read data in memory bio */ databio = BIO_new(BIO_s_mem()); if ((rc = i2d_PKCS7_ISSUER_AND_SERIAL_bio(databio, s->ias_getcrl)) <= 0) { fprintf(stderr, "%s: error writing " "GetCert data in bio\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } BIO_flush(databio); BIO_set_flags(databio, BIO_FLAGS_MEM_RDONLY); break; } /* Below this is the common code for all request_type */ /* Read in the payload */ s->request_len = BIO_get_mem_data(databio, &s->request_payload); if (v_flag) printf("%s: data payload size: %d bytes\n", pname, s->request_len); BIO_free(databio); /* Create encryption certificate stack */ if ((recipients = sk_X509_new(NULL)) == NULL) { fprintf(stderr, "%s: error creating " "certificate stack\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } /* Use different CA cert for encryption if requested */ if (e_flag) { if (sk_X509_push(recipients, encert) <= 0) { fprintf(stderr, "%s: error adding recipient encryption " "certificate\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } /* Use same CA cert also for encryption */ } else { if (sk_X509_push(recipients, cacert) <= 0) { fprintf(stderr, "%s: error adding recipient encryption " "certificate\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } } /* Create BIO for encryption */ if ((encbio = BIO_new_mem_buf(s->request_payload, s->request_len)) == NULL) { fprintf(stderr, "%s: error creating data " "bio\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } /* Encrypt */ if (!(p7enc = PKCS7_encrypt(recipients, encbio, enc_alg, PKCS7_BINARY))) { fprintf(stderr, "%s: request payload encrypt failed\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } if (v_flag) printf("%s: successfully encrypted payload\n", pname); /* Write encrypted data */ memorybio = BIO_new(BIO_s_mem()); if (i2d_PKCS7_bio(memorybio, p7enc) <= 0) { fprintf(stderr, "%s: error writing encrypted data\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } BIO_flush(memorybio); BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); len = BIO_get_mem_data(memorybio, &buffer); if (v_flag) printf("%s: envelope size: %d bytes\n", pname, len); if (d_flag) { printf("%s: printing PEM fomatted PKCS#7\n", pname); PEM_write_PKCS7(stdout, p7enc); } BIO_free(memorybio); /* Create outer PKCS#7 */ if (v_flag) printf("%s: creating outer PKCS#7\n", pname); s->request_p7 = PKCS7_new(); if (s->request_p7 == NULL) { fprintf(stderr, "%s: failed creating PKCS#7 for signing\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed)) { fprintf(stderr, "%s: failed setting PKCS#7 type\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } /* Add signer certificate and signature */ PKCS7_add_certificate(s->request_p7, signercert); if ((si = PKCS7_add_signature(s->request_p7, signercert, signerkey, sig_alg)) == NULL) { fprintf(stderr, "%s: error adding PKCS#7 signature\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } if (v_flag) printf("%s: signature added successfully\n", pname); /* Set signed attributes */ if (v_flag) printf("%s: adding signed attributes\n", pname); attributes = sk_X509_ATTRIBUTE_new_null(); add_attribute_string(attributes, nid_transId, s->transaction_id); add_attribute_string(attributes, nid_messageType, s->request_type_str); add_attribute_octet(attributes, nid_senderNonce, s->sender_nonce, s->sender_nonce_len); PKCS7_set_signed_attributes(si, attributes); /* Add contentType */ if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) { fprintf(stderr, "%s: error adding NID_pkcs9_contentType\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } /* Create new content */ if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data)) { fprintf(stderr, "%s: failed setting PKCS#7 content type\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } /* Write data */ pkcs7bio = PKCS7_dataInit(s->request_p7, NULL); if (pkcs7bio == NULL) { fprintf(stderr, "%s: error opening bio for writing PKCS#7 " "data\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } if (len != BIO_write(pkcs7bio, buffer, len)) { fprintf(stderr, "%s: error writing PKCS#7 data\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } if (v_flag) printf("%s: PKCS#7 data written successfully\n", pname); /* Finalize PKCS#7 */ if (!PKCS7_dataFinal(s->request_p7, pkcs7bio)) { fprintf(stderr, "%s: error finalizing outer PKCS#7\n", pname); ERR_print_errors_fp(stderr); exit (SCEP_PKISTATUS_P7); } if (d_flag) { printf("%s: printing PEM fomatted PKCS#7\n", pname); PEM_write_PKCS7(stdout, s->request_p7); } /* base64-encode the data */ if (v_flag) printf("%s: applying base64 encoding\n",pname); /* Create base64 filtering bio */ memorybio = BIO_new(BIO_s_mem()); base64bio = BIO_new(BIO_f_base64()); outbio = BIO_push(base64bio, memorybio); /* Copy PKCS#7 */ i2d_PKCS7_bio(outbio, s->request_p7); BIO_flush(outbio); BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); s->request_len = BIO_get_mem_data(memorybio, &s->request_payload); if (v_flag) printf("%s: base64 encoded payload size: %d bytes\n", pname, s->request_len); BIO_free(outbio); return (0); }
int SCEP_MSG_print( BIO *bio, SCEP_MSG *msg, EVP_PKEY *pkey, X509 *cert ) { char buffer[1024]; unsigned char *data; BIO_printf( bio, "SCEP Message:\n" ); BIO_printf( bio, " Message Type: %s (%d)\n", SCEP_type2str(msg->messageType), msg->messageType ); BIO_printf( bio, " Signed Data:\n" ); BIO_printf( bio, " Signer Info:\n" ); if (msg->signer_cert == NULL) { BIO_printf(bio, " Serial Number: %s\n", BN_bn2hex(ASN1_INTEGER_to_BN(msg->signer_ias->serial, NULL))); BIO_printf(bio, " Issuer: "); X509_NAME_print_ex (bio, msg->signer_ias->issuer, 0, XN_FLAG_RFC2253&(~ASN1_STRFLGS_ESC_MSB)); BIO_printf(bio, "\n"); } else { X509 *sigcert; sigcert = msg->signer_cert; if( X509_NAME_cmp( X509_get_subject_name(sigcert), X509_get_issuer_name(sigcert) ) ) { BIO_printf(bio, " Serial Number: %s\n", BN_bn2hex(ASN1_INTEGER_to_BN( msg->signer_cert->cert_info->serialNumber, NULL))); } else { /* Silly Serial Number */ BIO_printf(bio, " Serial Number: %s\n", "0x0 (fake)" ); } BIO_printf(bio, " Subject: "); X509_NAME_print_ex (bio, X509_get_subject_name(msg->signer_cert), 0, XN_FLAG_RFC2253&(~ASN1_STRFLGS_ESC_MSB)); BIO_printf(bio, "\n"); BIO_printf(bio, " Issuer: "); X509_NAME_print_ex (bio, X509_get_issuer_name(msg->signer_cert), 0, XN_FLAG_RFC2253&(~ASN1_STRFLGS_ESC_MSB)); BIO_printf(bio, "\n"); } BIO_printf( bio, " Signed Attributes:\n" ); if( data = SCEP_get_string_attr_by_name( msg->attrs, "messageType")) { BIO_printf(bio, " Message Type:\n" " %s\n", data ); free(data); } if( data = SCEP_get_string_attr_by_name( msg->attrs, "transId" )) { BIO_printf(bio, " Transaction ID:\n" " %s\n", data ); free(data); } if( data = SCEP_get_string_attr_by_name( msg->attrs, "pkiStatus" )) { BIO_printf(bio, " PKI Status:\n" " %s\n", data ); free(data); } if( data = SCEP_get_string_attr_by_name( msg->attrs, "failInfo" )) { BIO_printf(bio, " Fail Info:\n" " %s\n", data ); free(data); } if( data = SCEP_get_string_attr_by_name( msg->attrs, "proxyAuthenticator" )) { BIO_printf(bio, " Proxy Authenticator:\n" " %s\n", data ); free(data); } if( data = SCEP_get_octect_attr_by_name( msg->attrs, "senderNonce", NULL )) { BIO_printf(bio, " Sender Nonce:\n" " %s\n", SCEP_MSG_sender_nonce2hex( msg )); free(data); } if( data = SCEP_get_octect_attr_by_name( msg->attrs, "recipientNonce", NULL )) { BIO_printf(bio, " Recipient Nonce:\n" " %s\n", SCEP_MSG_recipient_nonce2hex( msg )); free(data); } if( msg->env_data.p7env ) BIO_printf( bio, " Enveloped Data:\n" ); /* if( msg->env_data.algor ) { BIO_printf( bio, " Encryption Algorithm: "); i2a_ASN1_OBJECT(bio, msg->env_data.algor->algorithm); BIO_printf( bio, "\n"); } */ if( msg->env_data.recip_info.ias ) { BIO_printf( bio, " Recipient Info:\n" ); BIO_printf(bio, " Serial Number: 0x%s (%s)\n", BN_bn2hex(ASN1_INTEGER_to_BN( msg->env_data.recip_info.ias->serial, NULL)), BN_bn2dec(ASN1_INTEGER_to_BN( msg->env_data.recip_info.ias->serial, NULL))); BIO_printf(bio, " Issuer: "); X509_NAME_print_ex (bio, msg->env_data.recip_info.ias->issuer, 0, XN_FLAG_RFC2253&(~ASN1_STRFLGS_ESC_MSB)); BIO_printf(bio, "\n"); } if( pkey ) { unsigned char *data=NULL; long len = 0; data = (unsigned char *) SCEP_MSG_decrypt( msg, pkey, cert, &len); if( data ) { int i; char buf[1024]; switch ( msg->messageType ) { case MSG_GETCRL: case MSG_GETCERT: /* Print the issuer 'n serial */ BIO_printf( bio, " Issuer and Serial:\n"); BIO_printf( bio, " Issuer: "); X509_NAME_print_ex (bio, msg->env_data.content.ias->issuer, 0, XN_FLAG_RFC2253&(~ASN1_STRFLGS_ESC_MSB)); BIO_printf( bio, "\n Serial: 0x"); i2a_ASN1_INTEGER( bio, msg->env_data.content.ias->serial ); BIO_printf( bio, "\n"); break; default: BIO_printf( bio, " Decrypted Data:"); for (i=0; i<len; i++) { if ((i%18) == 0) if (BIO_write(bio, "\n ", 13) <= 0) return 0; if (BIO_printf(bio,"%02x%s", data[i], ((i+1) == len)?"":":") <= 0) return 0; } if (BIO_write(bio,"\n",1) != 1) return 0; free( data ); break; } } } else { BIO *p7bio = NULL; unsigned char buffer[1024]; long len = 0; int i; BIO_printf( bio, " Encrypted Bytes (DER):"); p7bio = BIO_new(BIO_s_mem()); if ( msg->env_data.p7env ) i = i2d_PKCS7_bio( p7bio, msg->env_data.p7env ); else return 1; if( i == 0 ) { BIO_printf( bio, "cannot write data to mem bio\n"); goto err; } for (;;) { len = BIO_read(p7bio, buffer, sizeof(buffer)); if (len <= 0) break; for (i=0; i<len; i++) { if ((i%18) == 0) if (BIO_write(bio,"\n ",13) <= 0) return 0; if (BIO_printf(bio,"%02x%s",buffer[i], ((i+1) == len)?"":":") <= 0) return 0; } if (BIO_write(bio,"\n",1) != 1) return 0; } if (p7bio) BIO_free ( p7bio ); } return 1; err: return 0; }
/* * Wrap data in PKCS#7 envelopes and base64-encode the result. * Data is PKCS#10 request in PKCSReq, or pkcs7_issuer_and_subject * structure in GetCertInitial and PKCS7_ISSUER_AND_SERIAL in * GetCert and GETCrl. */ int pkcs7_wrap(struct scep *s, struct sscep_ctx *ctx, struct sscep_operation_info *op_info) { BIO *databio = NULL; BIO *encbio = NULL; BIO *pkcs7bio = NULL; BIO *memorybio = NULL; BIO *outbio = NULL; unsigned char *buffer = NULL; int len = 0; STACK_OF(X509) *recipients = NULL; PKCS7 *p7enc = NULL; PKCS7_SIGNER_INFO *si; STACK_OF(X509_ATTRIBUTE) *attributes; X509 *signercert = NULL; EVP_PKEY *signerkey = NULL; int ret = SCEP_PKISTATUS_P7; char *payload = NULL; int payload_len; /* Create a new sender nonce for all messages * XXXXXXXXXXXXXX should it be per transaction? */ s->sender_nonce_len = 16; free(s->sender_nonce);/* Clean up from previous runs */ s->sender_nonce = (char *)malloc(s->sender_nonce_len * sizeof(char)); RAND_bytes((unsigned char *) s->sender_nonce, s->sender_nonce_len); /* Prepare data payload */ switch (s->request_type) { case SCEP_REQUEST_PKCSREQ: /* * Set printable message type * We set this later as an autheticated attribute * "messageType". */ s->request_type_str = SCEP_REQUEST_PKCSREQ_STR; /* Signer cert */ signercert = s->signercert; signerkey = s->signerkey; /* Create inner PKCS#7 */ if (ctx->verbose){ qeo_log_i("creating inner PKCS#7"); } /* Read request in memory bio */ databio = BIO_new(BIO_s_mem()); if (i2d_X509_REQ_bio(databio, op_info->request) <= 0) { qeo_log_e("error writing certificate request in bio"); goto error; } (void)BIO_flush(databio); break; case SCEP_REQUEST_GETCERTINIT: /* Set printable message type */ s->request_type_str = SCEP_REQUEST_GETCERTINIT_STR; /* Signer cert */ signercert = s->signercert; signerkey = s->signerkey; /* Create inner PKCS#7 */ if (ctx->verbose){ qeo_log_i("creating inner PKCS#7"); } /* Read data in memory bio */ databio = BIO_new(BIO_s_mem()); if (i2d_pkcs7_issuer_and_subject_bio(databio, s->ias_getcertinit)) { qeo_log_e("error writing GetCertInitial data in bio"); goto error; } (void)BIO_flush(databio); break; } /* Below this is the common code for all request_type */ /* Read in the payload */ payload_len = BIO_get_mem_data(databio, &payload); if (ctx->verbose){ qeo_log_i("data payload size: %d bytes", payload_len); } /* Create encryption certificate stack */ if ((recipients = sk_X509_new(NULL) ) == NULL) { qeo_log_e("error creating certificate stack"); goto error; } if (sk_X509_push(recipients, op_info->racert) <= 0) { qeo_log_e("error adding recipient encryption certificate"); goto error; } /* Create BIO for encryption */ if ((encbio = BIO_new_mem_buf(payload, payload_len)) == NULL ) { qeo_log_e("error creating data bio"); goto error; } /* Encrypt */ if (!(p7enc = PKCS7_encrypt(recipients, encbio, ctx->enc_alg, PKCS7_BINARY))) { qeo_log_e("request payload encrypt failed"); goto error; } if (ctx->verbose){ qeo_log_i("successfully encrypted payload"); } /* Write encrypted data */ memorybio = BIO_new(BIO_s_mem()); if (i2d_PKCS7_bio(memorybio, p7enc) <= 0) { qeo_log_e("error writing encrypted data"); goto error; } (void)BIO_flush(memorybio); BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY); len = BIO_get_mem_data(memorybio, &buffer); BIO_free(memorybio); memorybio=NULL; if (ctx->verbose){ qeo_log_i("envelope size: %d bytes", len); } if (ctx->debug) { qeo_log_i("printing PEM fomatted PKCS#7"); PEM_write_PKCS7(stdout, p7enc); } /* Create outer PKCS#7 */ if (ctx->verbose){ qeo_log_i("creating outer PKCS#7"); } s->request_p7 = PKCS7_new(); if (s->request_p7 == NULL ) { qeo_log_e("failed creating PKCS#7 for signing"); goto error; } if (!PKCS7_set_type(s->request_p7, NID_pkcs7_signed)) { qeo_log_e("failed setting PKCS#7 type"); goto error; } /* Add signer certificate and signature */ PKCS7_add_certificate(s->request_p7, signercert); if ((si = PKCS7_add_signature(s->request_p7, signercert, signerkey, ctx->sig_alg)) == NULL ) { qeo_log_e("error adding PKCS#7 signature"); goto error; } if (ctx->verbose){ qeo_log_i("signature added successfully"); } /* Set signed attributes */ if (ctx->verbose){ qeo_log_i("adding signed attributes"); } attributes = sk_X509_ATTRIBUTE_new_null(); add_attribute_string(attributes, ctx->nid_transId, s->transaction_id, ctx); add_attribute_string(attributes, ctx->nid_messageType, s->request_type_str, ctx); add_attribute_octet(attributes, ctx->nid_senderNonce, s->sender_nonce, s->sender_nonce_len, ctx); PKCS7_set_signed_attributes(si, attributes); sk_X509_ATTRIBUTE_pop_free(attributes, X509_ATTRIBUTE_free); /* Add contentType */ if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data))) { qeo_log_e("error adding NID_pkcs9_contentType"); goto error; } /* Create new content */ if (!PKCS7_content_new(s->request_p7, NID_pkcs7_data)) { qeo_log_e("failed setting PKCS#7 content type"); goto error; } /* Write data */ pkcs7bio = PKCS7_dataInit(s->request_p7, NULL ); if (pkcs7bio == NULL ) { qeo_log_e("error opening bio for writing PKCS#7 data"); goto error; } if (len != BIO_write(pkcs7bio, buffer, len)) { qeo_log_e("error writing PKCS#7 data"); goto error; } if (ctx->verbose){ qeo_log_i("PKCS#7 data written successfully"); } /* Finalize PKCS#7 */ if (!PKCS7_dataFinal(s->request_p7, pkcs7bio)) { qeo_log_e("error finalizing outer PKCS#7"); goto error; } if (ctx->debug) { qeo_log_i("printing PEM fomatted PKCS#7"); PEM_write_PKCS7(stdout, s->request_p7); } /* base64-encode the data */ if (ctx->verbose){ qeo_log_i("applying base64 encoding"); } /* Create base64 filtering bio */ memorybio = BIO_new(BIO_s_mem()); outbio = BIO_push(BIO_new(BIO_f_base64()), memorybio); /* Copy PKCS#7 */ i2d_PKCS7_bio(outbio, s->request_p7); (void)BIO_flush(outbio); payload_len = BIO_get_mem_data(memorybio, &payload); s->request_payload = (char*) malloc(sizeof(char)*payload_len); if (!s->request_payload){ goto error; } s->request_len = payload_len; memcpy(s->request_payload, payload, s->request_len); if (ctx->verbose){ qeo_log_i("base64 encoded payload size: %d bytes", payload_len); } ret = 0; error: BIO_free(databio); BIO_free(encbio); BIO_free_all(pkcs7bio); BIO_free(memorybio); BIO_free(outbio); if (recipients != NULL){ sk_X509_free(recipients);/* Only free the stack, not the certificates */ } PKCS7_free(p7enc); OPENSSL_free(buffer); return ret; }
static void sign(X509 *cert, EVP_PKEY *key, int pipefd) { PKCS7 *pkcs7; BIO *bio, *out; const EVP_MD *md; PKCS7_SIGNER_INFO *info; void *digest, *signature; size_t digest_len, signature_len; int ok; assert(cert != NULL); assert(key != NULL); receive_chunk(&digest, &digest_len, pipefd); bio = BIO_new_mem_buf(digest, digest_len); if (bio == NULL) { ERR_print_errors_fp(stderr); errx(1, "BIO_new_mem_buf(3) failed"); } pkcs7 = PKCS7_sign(NULL, NULL, NULL, bio, PKCS7_BINARY | PKCS7_PARTIAL); if (pkcs7 == NULL) { ERR_print_errors_fp(stderr); errx(1, "PKCS7_sign(3) failed"); } md = EVP_get_digestbyname(DIGEST); if (md == NULL) { ERR_print_errors_fp(stderr); errx(1, "EVP_get_digestbyname(\"%s\") failed", DIGEST); } info = PKCS7_sign_add_signer(pkcs7, cert, key, md, 0); if (info == NULL) { ERR_print_errors_fp(stderr); errx(1, "PKCS7_sign_add_signer(3) failed"); } /* * XXX: All the signed binaries seem to have this, but where is it * described in the spec? */ PKCS7_add_signed_attribute(info, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_txt2obj("1.3.6.1.4.1.311.2.1.4", 1)); magic(pkcs7, digest, digest_len); #if 0 out = BIO_new(BIO_s_file()); BIO_set_fp(out, stdout, BIO_NOCLOSE); PKCS7_print_ctx(out, pkcs7, 0, NULL); i2d_PKCS7_bio(out, pkcs7); #endif out = BIO_new(BIO_s_mem()); if (out == NULL) { ERR_print_errors_fp(stderr); errx(1, "BIO_new(3) failed"); } ok = i2d_PKCS7_bio(out, pkcs7); if (ok == 0) { ERR_print_errors_fp(stderr); errx(1, "i2d_PKCS7_bio(3) failed"); } signature_len = BIO_get_mem_data(out, &signature); if (signature_len <= 0) { ERR_print_errors_fp(stderr); errx(1, "BIO_get_mem_data(3) failed"); } (void)BIO_set_close(out, BIO_NOCLOSE); BIO_free(out); send_chunk(signature, signature_len, pipefd); }
int MAIN(int argc, char **argv) { PKCS7 *p7=NULL; int i,badops=0; BIO *in=NULL,*out=NULL; int informat,outformat; char *infile,*outfile,*prog; int print_certs=0,text=0,noout=0,p7_print=0; int ret=1; #ifndef OPENSSL_NO_ENGINE char *engine=NULL; #endif apps_startup(); if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err,OPENSSL_TYPE__FILE_STDERR,BIO_NOCLOSE|BIO_FP_TEXT); if (!load_config(bio_err, NULL)) goto end; infile=NULL; outfile=NULL; informat=FORMAT_PEM; outformat=FORMAT_PEM; prog=argv[0]; argc--; argv++; while (argc >= 1) { if (TINYCLR_SSL_STRCMP(*argv,"-inform") == 0) { if (--argc < 1) goto bad; informat=str2fmt(*(++argv)); } else if (TINYCLR_SSL_STRCMP(*argv,"-outform") == 0) { if (--argc < 1) goto bad; outformat=str2fmt(*(++argv)); } else if (TINYCLR_SSL_STRCMP(*argv,"-in") == 0) { if (--argc < 1) goto bad; infile= *(++argv); } else if (TINYCLR_SSL_STRCMP(*argv,"-out") == 0) { if (--argc < 1) goto bad; outfile= *(++argv); } else if (TINYCLR_SSL_STRCMP(*argv,"-noout") == 0) noout=1; else if (TINYCLR_SSL_STRCMP(*argv,"-text") == 0) text=1; else if (TINYCLR_SSL_STRCMP(*argv,"-print") == 0) p7_print=1; else if (TINYCLR_SSL_STRCMP(*argv,"-print_certs") == 0) print_certs=1; #ifndef OPENSSL_NO_ENGINE else if (TINYCLR_SSL_STRCMP(*argv,"-engine") == 0) { if (--argc < 1) goto bad; engine= *(++argv); } #endif else { BIO_printf(bio_err,"unknown option %s\n",*argv); badops=1; break; } argc--; argv++; } if (badops) { bad: BIO_printf(bio_err,"%s [options] <infile >outfile\n",prog); BIO_printf(bio_err,"where options are\n"); BIO_printf(bio_err," -inform arg input format - DER or PEM\n"); BIO_printf(bio_err," -outform arg output format - DER or PEM\n"); BIO_printf(bio_err," -in arg input file\n"); BIO_printf(bio_err," -out arg output file\n"); BIO_printf(bio_err," -print_certs print any certs or crl in the input\n"); BIO_printf(bio_err," -text print full details of certificates\n"); BIO_printf(bio_err," -noout don't output encoded data\n"); #ifndef OPENSSL_NO_ENGINE BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); #endif ret = 1; goto end; } ERR_load_crypto_strings(); #ifndef OPENSSL_NO_ENGINE setup_engine(bio_err, engine, 0); #endif in=BIO_new(BIO_s_file()); out=BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } if (infile == NULL) BIO_set_fp(in,OPENSSL_TYPE__FILE_STDIN,BIO_NOCLOSE); else { if (BIO_read_filename(in,infile) <= 0) if (in == NULL) { TINYCLR_SSL_PERROR(infile); goto end; } } if (informat == FORMAT_ASN1) p7=d2i_PKCS7_bio(in,NULL); else if (informat == FORMAT_PEM) p7=PEM_read_bio_PKCS7(in,NULL,NULL,NULL); else { BIO_printf(bio_err,"bad input format specified for pkcs7 object\n"); goto end; } if (p7 == NULL) { BIO_printf(bio_err,"unable to load PKCS7 object\n"); ERR_print_errors(bio_err); goto end; } if (outfile == NULL) { BIO_set_fp(out,OPENSSL_TYPE__FILE_STDOUT,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out,outfile) <= 0) { TINYCLR_SSL_PERROR(outfile); goto end; } } if (p7_print) PKCS7_print_ctx(out, p7, 0, NULL); if (print_certs) { STACK_OF(X509) *certs=NULL; STACK_OF(X509_CRL) *crls=NULL; i=OBJ_obj2nid(p7->type); switch (i) { case NID_pkcs7_signed: certs=p7->d.sign->cert; crls=p7->d.sign->crl; break; case NID_pkcs7_signedAndEnveloped: certs=p7->d.signed_and_enveloped->cert; crls=p7->d.signed_and_enveloped->crl; break; default: break; } if (certs != NULL) { X509 *x; for (i=0; i<sk_X509_num(certs); i++) { x=sk_X509_value(certs,i); if(text) X509_print(out, x); else dump_cert_text(out, x); if(!noout) PEM_write_bio_X509(out,x); BIO_puts(out,"\n"); } } if (crls != NULL) { X509_CRL *crl; for (i=0; i<sk_X509_CRL_num(crls); i++) { crl=sk_X509_CRL_value(crls,i); X509_CRL_print(out, crl); if(!noout)PEM_write_bio_X509_CRL(out,crl); BIO_puts(out,"\n"); } } ret=0; goto end; } if(!noout) { if (outformat == FORMAT_ASN1) i=i2d_PKCS7_bio(out,p7); else if (outformat == FORMAT_PEM) i=PEM_write_bio_PKCS7(out,p7); else { BIO_printf(bio_err,"bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err,"unable to write pkcs7 object\n"); ERR_print_errors(bio_err); goto end; } } ret=0; end: if (p7 != NULL) PKCS7_free(p7); if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); apps_shutdown(); OPENSSL_EXIT(ret); }
int pkcs7_main(int argc, char **argv) { PKCS7 *p7 = NULL; BIO *in = NULL, *out = NULL; int ret = 1; int i; memset(&pkcs7_config, 0, sizeof(pkcs7_config)); pkcs7_config.informat = FORMAT_PEM; pkcs7_config.outformat = FORMAT_PEM; if (options_parse(argc, argv, pkcs7_options, NULL, NULL) != 0) { pkcs7_usage(); goto end; } #ifndef OPENSSL_NO_ENGINE setup_engine(bio_err, pkcs7_config.engine, 0); #endif in = BIO_new(BIO_s_file()); out = BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } if (pkcs7_config.infile == NULL) BIO_set_fp(in, stdin, BIO_NOCLOSE); else { if (BIO_read_filename(in, pkcs7_config.infile) <= 0) { perror(pkcs7_config.infile); goto end; } } if (pkcs7_config.informat == FORMAT_ASN1) p7 = d2i_PKCS7_bio(in, NULL); else if (pkcs7_config.informat == FORMAT_PEM) p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL); else { BIO_printf(bio_err, "bad input format specified for pkcs7 object\n"); goto end; } if (p7 == NULL) { BIO_printf(bio_err, "unable to load PKCS7 object\n"); ERR_print_errors(bio_err); goto end; } if (pkcs7_config.outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); } else { if (BIO_write_filename(out, pkcs7_config.outfile) <= 0) { perror(pkcs7_config.outfile); goto end; } } if (pkcs7_config.p7_print) PKCS7_print_ctx(out, p7, 0, NULL); if (pkcs7_config.print_certs) { STACK_OF(X509) * certs = NULL; STACK_OF(X509_CRL) * crls = NULL; i = OBJ_obj2nid(p7->type); switch (i) { case NID_pkcs7_signed: certs = p7->d.sign->cert; crls = p7->d.sign->crl; break; case NID_pkcs7_signedAndEnveloped: certs = p7->d.signed_and_enveloped->cert; crls = p7->d.signed_and_enveloped->crl; break; default: break; } if (certs != NULL) { X509 *x; for (i = 0; i < sk_X509_num(certs); i++) { x = sk_X509_value(certs, i); if (pkcs7_config.text) X509_print(out, x); else dump_cert_text(out, x); if (!pkcs7_config.noout) PEM_write_bio_X509(out, x); BIO_puts(out, "\n"); } } if (crls != NULL) { X509_CRL *crl; for (i = 0; i < sk_X509_CRL_num(crls); i++) { crl = sk_X509_CRL_value(crls, i); X509_CRL_print(out, crl); if (!pkcs7_config.noout) PEM_write_bio_X509_CRL(out, crl); BIO_puts(out, "\n"); } } ret = 0; goto end; } if (!pkcs7_config.noout) { if (pkcs7_config.outformat == FORMAT_ASN1) i = i2d_PKCS7_bio(out, p7); else if (pkcs7_config.outformat == FORMAT_PEM) i = PEM_write_bio_PKCS7(out, p7); else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write pkcs7 object\n"); ERR_print_errors(bio_err); goto end; } } ret = 0; end: if (p7 != NULL) PKCS7_free(p7); if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); return (ret); }
static int reply_command(CONF *conf, char *section, char *engine, char *queryfile, char *passin, char *inkey, const EVP_MD *md, char *signer, char *chain, const char *policy, char *in, int token_in, char *out, int token_out, int text) { int ret = 0; TS_RESP *response = NULL; BIO *in_bio = NULL; BIO *query_bio = NULL; BIO *inkey_bio = NULL; BIO *signer_bio = NULL; BIO *out_bio = NULL; if (in != NULL) { if ((in_bio = BIO_new_file(in, "rb")) == NULL) goto end; if (token_in) { response = read_PKCS7(in_bio); } else { response = d2i_TS_RESP_bio(in_bio, NULL); } } else { response = create_response(conf, section, engine, queryfile, passin, inkey, md, signer, chain, policy); if (response) BIO_printf(bio_err, "Response has been generated.\n"); else BIO_printf(bio_err, "Response is not generated.\n"); } if (response == NULL) goto end; /* Write response. */ if (text) { if ((out_bio = bio_open_default(out, 'w', FORMAT_TEXT)) == NULL) goto end; if (token_out) { TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); if (!TS_TST_INFO_print_bio(out_bio, tst_info)) goto end; } else { if (!TS_RESP_print_bio(out_bio, response)) goto end; } } else { if ((out_bio = bio_open_default(out, 'w', FORMAT_ASN1)) == NULL) goto end; if (token_out) { PKCS7 *token = TS_RESP_get_token(response); if (!i2d_PKCS7_bio(out_bio, token)) goto end; } else { if (!i2d_TS_RESP_bio(out_bio, response)) goto end; } } ret = 1; end: ERR_print_errors(bio_err); BIO_free_all(in_bio); BIO_free_all(query_bio); BIO_free_all(inkey_bio); BIO_free_all(signer_bio); BIO_free_all(out_bio); TS_RESP_free(response); return ret; }
int MAIN(int argc, char **argv) { int i, badops = 0; BIO *in = NULL, *out = NULL; int informat, outformat; char *infile, *outfile, *prog, *certfile; PKCS7 *p7 = NULL; PKCS7_SIGNED *p7s = NULL; X509_CRL *crl = NULL; STACK_OF(OPENSSL_STRING) *certflst = NULL; STACK_OF(X509_CRL) *crl_stack = NULL; STACK_OF(X509) *cert_stack = NULL; int ret = 1, nocrl = 0; apps_startup(); if (bio_err == NULL) if ((bio_err = BIO_new(BIO_s_file())) != NULL) BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT); infile = NULL; outfile = NULL; informat = FORMAT_PEM; outformat = FORMAT_PEM; prog = argv[0]; argc--; argv++; while (argc >= 1) { if (strcmp(*argv, "-inform") == 0) { if (--argc < 1) goto bad; informat = str2fmt(*(++argv)); } else if (strcmp(*argv, "-outform") == 0) { if (--argc < 1) goto bad; outformat = str2fmt(*(++argv)); } else if (strcmp(*argv, "-in") == 0) { if (--argc < 1) goto bad; infile = *(++argv); } else if (strcmp(*argv, "-nocrl") == 0) { nocrl = 1; } else if (strcmp(*argv, "-out") == 0) { if (--argc < 1) goto bad; outfile = *(++argv); } else if (strcmp(*argv, "-certfile") == 0) { if (--argc < 1) goto bad; if (!certflst) certflst = sk_OPENSSL_STRING_new_null(); if (!certflst) goto end; if (!sk_OPENSSL_STRING_push(certflst, *(++argv))) { sk_OPENSSL_STRING_free(certflst); goto end; } } else { BIO_printf(bio_err, "unknown option %s\n", *argv); badops = 1; break; } argc--; argv++; } if (badops) { bad: BIO_printf(bio_err, "%s [options] <infile >outfile\n", prog); BIO_printf(bio_err, "where options are\n"); BIO_printf(bio_err, " -inform arg input format - DER or PEM\n"); BIO_printf(bio_err, " -outform arg output format - DER or PEM\n"); BIO_printf(bio_err, " -in arg input file\n"); BIO_printf(bio_err, " -out arg output file\n"); BIO_printf(bio_err, " -certfile arg certificates file of chain to a trusted CA\n"); BIO_printf(bio_err, " (can be used more than once)\n"); BIO_printf(bio_err, " -nocrl no crl to load, just certs from '-certfile'\n"); ret = 1; goto end; } ERR_load_crypto_strings(); in = BIO_new(BIO_s_file()); out = BIO_new(BIO_s_file()); if ((in == NULL) || (out == NULL)) { ERR_print_errors(bio_err); goto end; } if (!nocrl) { if (infile == NULL) BIO_set_fp(in, stdin, BIO_NOCLOSE); else { if (BIO_read_filename(in, infile) <= 0) { perror(infile); goto end; } } if (informat == FORMAT_ASN1) crl = d2i_X509_CRL_bio(in, NULL); else if (informat == FORMAT_PEM) crl = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); else { BIO_printf(bio_err, "bad input format specified for input crl\n"); goto end; } if (crl == NULL) { BIO_printf(bio_err, "unable to load CRL\n"); ERR_print_errors(bio_err); goto end; } } if ((p7 = PKCS7_new()) == NULL) goto end; if ((p7s = PKCS7_SIGNED_new()) == NULL) goto end; p7->type = OBJ_nid2obj(NID_pkcs7_signed); p7->d.sign = p7s; p7s->contents->type = OBJ_nid2obj(NID_pkcs7_data); if (!ASN1_INTEGER_set(p7s->version, 1)) goto end; if ((crl_stack = sk_X509_CRL_new_null()) == NULL) goto end; p7s->crl = crl_stack; if (crl != NULL) { sk_X509_CRL_push(crl_stack, crl); crl = NULL; /* now part of p7 for OPENSSL_freeing */ } if ((cert_stack = sk_X509_new_null()) == NULL) goto end; p7s->cert = cert_stack; if (certflst) for (i = 0; i < sk_OPENSSL_STRING_num(certflst); i++) { certfile = sk_OPENSSL_STRING_value(certflst, i); if (add_certs_from_file(cert_stack, certfile) < 0) { BIO_printf(bio_err, "error loading certificates\n"); ERR_print_errors(bio_err); goto end; } } sk_OPENSSL_STRING_free(certflst); if (outfile == NULL) { BIO_set_fp(out, stdout, BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); out = BIO_push(tmpbio, out); } #endif } else { if (BIO_write_filename(out, outfile) <= 0) { perror(outfile); goto end; } } if (outformat == FORMAT_ASN1) i = i2d_PKCS7_bio(out, p7); else if (outformat == FORMAT_PEM) i = PEM_write_bio_PKCS7(out, p7); else { BIO_printf(bio_err, "bad output format specified for outfile\n"); goto end; } if (!i) { BIO_printf(bio_err, "unable to write pkcs7 object\n"); ERR_print_errors(bio_err); goto end; } ret = 0; end: if (in != NULL) BIO_free(in); if (out != NULL) BIO_free_all(out); if (p7 != NULL) PKCS7_free(p7); if (crl != NULL) X509_CRL_free(crl); apps_shutdown(); OPENSSL_EXIT(ret); }
int SCEP_MSG_encrypt( SCEP_MSG *msg, X509 *recip_cert, EVP_CIPHER cipher ) { BIO *inbio = NULL; int ret = 0; int len = 0; BIO *debug_bio = NULL; if ((debug_bio=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(debug_bio,stderr,BIO_NOCLOSE|BIO_FP_TEXT); // printf("%s:%d Debug... *** ENCRYPT ***\n", __FILE__, __LINE__ ); /* Create the stack of the recipient(s) certificate(s) */ if( recip_cert ) { STACK_OF(X509) *sk = NULL; if((sk = sk_X509_new(NULL)) == NULL) goto err; sk_X509_push( sk, recip_cert ); msg->env_data.recip_info.sk_recip_certs = sk; } else { return 0; } inbio = BIO_new ( BIO_s_mem()); /* Any message type has different data to be encrypted * and checks to be done */ switch ( msg->messageType ) { case MSG_PKCSREQ: /* There must be a request added to the msg */ if(! msg->env_data.content.req ) goto err; /* Write the request to the inbio */ if( i2d_X509_REQ_bio( inbio, msg->env_data.content.req ) <= 0) goto err; break; case MSG_GETCRL: case MSG_GETCERT: if( !msg->env_data.content.ias ) goto err; len = i2d_PKCS7_ias_bio( inbio, msg->env_data.content.ias); if( len <= 0 ) goto err; break; case MSG_CERTREP: // printf("%s:%d: Debug ... Case: MSG_CERTREP\n", // __FILE__, __LINE__ ); /* if ( msg->env_data.content.issued_cert ) { len = i2d_X509_bio ( inbio, msg->env_data.content.issued_cert ); } */ if ( msg->env_data.p7 ) len = i2d_PKCS7_bio( inbio, msg->env_data.p7 ); break; default: printf("%s:%d Unsupported MessageType %d (%s)\n", __FILE__, __LINE__, msg->messageType, SCEP_type2str(msg->messageType) ); } BIO_flush( inbio ); BIO_set_flags( inbio, BIO_FLAGS_MEM_RDONLY ); /* Check for the recipients certs presence */ if( !msg->env_data.recip_info.sk_recip_certs ) goto err; /* If already present an encoded pkcs7, let's free */ if( msg->env_data.p7env ) PKCS7_free( msg->env_data.p7env ); /* Encrypt Data */ msg->env_data.p7env = PKCS7_encrypt( msg->env_data.recip_info.sk_recip_certs, inbio, &cipher, PKCS7_BINARY ); ERR_clear_error(); /* If an error occourred pkcs7 is empty */ if( msg->env_data.p7env == NULL ) goto err; ret = 1; err: if (inbio) BIO_free( inbio ); return ret; }