Pkcs7SignedDataBuilder::Pkcs7SignedDataBuilder(MessageDigest::Algorithm mesDigAlgorithm, Certificate &cert, PrivateKey &privKey, bool attached) throw (Pkcs7Exception) { int rc; PKCS7_SIGNER_INFO *si; PKCS7_set_type(this->pkcs7, NID_pkcs7_signed); PKCS7_content_new(this->pkcs7, NID_pkcs7_data); if (!attached) { PKCS7_set_detached(this->pkcs7, 1); } si = PKCS7_add_signature(this->pkcs7, cert.getX509(), privKey.getEvpPkey(), MessageDigest::getMessageDigest(mesDigAlgorithm)); if (!si) { PKCS7_free(this->pkcs7); this->pkcs7 = NULL; throw Pkcs7Exception(Pkcs7Exception::ADDING_SIGNER, "Pkcs7SignedDataBuilder::Pkcs7SignedDataBuilder", true); } rc = PKCS7_add_certificate(this->pkcs7, cert.getX509()); if (!rc) { PKCS7_free(this->pkcs7); this->pkcs7 = NULL; throw Pkcs7Exception(Pkcs7Exception::ADDING_CERTIFICATE, "Pkcs7SignedDataBuilder::Pkcs7SignedDataBuilder", true); } this->state = Pkcs7Builder::INIT; }
static LUA_FUNCTION(openssl_pkcs7_add) { PKCS7 *p7 = CHECK_OBJECT(1, PKCS7, "openssl.pkcs7"); int n = lua_gettop(L); int i, ret; ret = 1; luaL_argcheck(L, lua_isuserdata(L, 2), 2, "must supply certificate or crl object"); for (i = 2; i <= n; i++) { luaL_argcheck(L, auxiliar_isclass(L, "openssl.x509", i) || auxiliar_isclass(L, "openssl.x509_crl", i), i, "must supply certificate or crl object"); if (auxiliar_isclass(L, "openssl.x509", i)) { X509* x = CHECK_OBJECT(i, X509, "openssl.x509"); ret = PKCS7_add_certificate(p7, x); } else { X509_CRL *crl = CHECK_OBJECT(i, X509_CRL, "openssl.x509_crl"); ret = PKCS7_add_crl(p7, crl); } luaL_argcheck(L, ret, i, "add to pkcs7 fail"); } return openssl_pushresult(L, ret); }
void pki_pkcs7::addCert(pki_x509 *crt) { if (p7 == NULL || crt == NULL) return; PKCS7_add_certificate(p7, crt->getCert()); openssl_error(); }
int PKI_X509_PKCS7_add_signer ( PKI_X509_PKCS7 *p7, PKI_X509_CERT *signer, PKI_X509_KEYPAIR *k, PKI_DIGEST_ALG *md ) { PKCS7_SIGNER_INFO *signerInfo = NULL; if ( !p7 || !signer || !k ) { if ( !p7 ) PKI_log_debug ( "!p7"); if ( !signer ) PKI_log_debug ( "!signer"); if ( !k ) PKI_log_debug ( "!key"); return PKI_ERR; } if ( !p7->value || !signer->value || !k->value ) { if ( !p7->value ) PKI_log_debug ( "!p7->value"); if ( !signer->value ) PKI_log_debug ( "!signer->value"); if ( !k->value ) PKI_log_debug ( "!key->value"); return PKI_ERR; } if( !md ) md = PKI_DIGEST_ALG_DEFAULT; if((signerInfo = PKCS7_add_signature( p7->value, signer->value, k->value, md)) == NULL) { return ( PKI_ERR ); } PKCS7_add_certificate ( p7->value, signer->value ); return ( PKI_OK ); }
extern "C" int32_t CryptoNative_Pkcs7AddCertificate(PKCS7* p7, X509* x509) { if (p7 == nullptr || x509 == nullptr) { return 0; } return PKCS7_add_certificate(p7, x509); }
int32_t CryptoNative_Pkcs7AddCertificate(PKCS7* p7, X509* x509) { if (p7 == NULL || x509 == NULL) { return 0; } return PKCS7_add_certificate(p7, x509); }
int PKI_X509_PKCS7_add_cert (PKI_X509_PKCS7 *p7, PKI_X509_CERT *x) { if ( !p7 || !p7->value || !x || !x->value ) { PKI_log_err( "PKI_X509_PKCS7_add_cert()::Missing required param!"); return PKI_ERR; } PKCS7_add_certificate( p7->value, x->value ); return( PKI_OK ); }
static VALUE ossl_pkcs7_add_certificate(VALUE self, VALUE cert) { PKCS7 *pkcs7; X509 *x509; GetPKCS7(self, pkcs7); x509 = GetX509CertPtr(cert); /* NO NEED TO DUP */ if (!PKCS7_add_certificate(pkcs7, x509)){ ossl_raise(ePKCS7Error, NULL); } return self; }
void Pkcs7SignedDataBuilder::addCertificate(Certificate &cert) throw (Pkcs7Exception, InvalidStateException) { int rc; if (this->state != Pkcs7Builder::INIT && this->state != Pkcs7Builder::UPDATE) { throw InvalidStateException("Pkcs7SignedDataBuilder::addCertificate"); } rc = PKCS7_add_certificate(this->pkcs7, cert.getX509()); if (!rc) { PKCS7_free(this->pkcs7); this->pkcs7 = NULL; throw Pkcs7Exception(Pkcs7Exception::ADDING_CERTIFICATE, "Pkcs7SignedDataBuilder::addCertificate", true); } }
int PKI_X509_PKCS7_add_cert_stack ( PKI_X509_PKCS7 *p7, PKI_X509_CERT_STACK *x_sk ) { int i; if( !p7 || !p7->value || !x_sk ) { PKI_log_err( "PKI_X509_PKCS7_add_crl_stack()::Missing param!"); return PKI_ERR; } for( i=0; i < PKI_STACK_X509_CERT_elements( x_sk ); i++ ) { PKI_X509_CERT *x = NULL; if(( x = PKI_STACK_X509_CERT_get_num( x_sk, i )) == NULL) { continue; } PKCS7_add_certificate( p7->value, x->value ); } return ( PKI_OK ); }
void Pkcs7SignedDataBuilder::addSigner(MessageDigest::Algorithm mesDigAlgorithm, Certificate &cert, PrivateKey &privKey) throw (Pkcs7Exception, InvalidStateException) { int rc; if (this->state != Pkcs7Builder::INIT) { throw InvalidStateException("Pkcs7SignedDataBuilder::addSigner"); } if (!PKCS7_add_signature(this->pkcs7, cert.getX509(), privKey.getEvpPkey(), MessageDigest::getMessageDigest(mesDigAlgorithm))) { PKCS7_free(this->pkcs7); this->pkcs7 = NULL; throw Pkcs7Exception(Pkcs7Exception::ADDING_SIGNER, "Pkcs7SignedDataBuilder::addSigner", true); } rc = PKCS7_add_certificate(this->pkcs7, cert.getX509()); if (!rc)//inversor adicionado (martin 28/11/07) { PKCS7_free(this->pkcs7); this->pkcs7 = NULL; throw Pkcs7Exception(Pkcs7Exception::ADDING_CERTIFICATE, "Pkcs7SignedDataBuilder::addSigner", true); } }
void Pkcs7SignedDataBuilder::init(MessageDigest::Algorithm mesDigAlgorithm, Certificate &cert, PrivateKey &privKey, bool attached) throw (Pkcs7Exception) { int rc; if (this->state != Pkcs7Builder::NO_INIT) { PKCS7_free(this->pkcs7); this->pkcs7 = NULL; if (this->state == Pkcs7Builder::UPDATE) { BIO_free(this->p7bio); this->p7bio = NULL; } } this->pkcs7 = PKCS7_new(); PKCS7_set_type(this->pkcs7, NID_pkcs7_signed); if (!attached) { PKCS7_set_detached(this->pkcs7, 1); } if (!PKCS7_add_signature(this->pkcs7, cert.getX509(), privKey.getEvpPkey(), MessageDigest::getMessageDigest(mesDigAlgorithm))) { PKCS7_free(this->pkcs7); this->pkcs7 = NULL; throw Pkcs7Exception(Pkcs7Exception::ADDING_SIGNER, "Pkcs7SignedDataBuilder::Pkcs7SignedDataBuilder", true); } rc = PKCS7_add_certificate(this->pkcs7, cert.getX509()); if (!rc)//inversor adicionado (martin 28/11/07) { PKCS7_free(this->pkcs7); this->pkcs7 = NULL; throw Pkcs7Exception(Pkcs7Exception::ADDING_CERTIFICATE, "Pkcs7SignedDataBuilder::Pkcs7SignedDataBuilder", true); } this->state = Pkcs7Builder::INIT; }
/******************************************************************************* 函数名称: 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 create_envelope(PluginInstance *inst, u8 **data, int *datalen) { int r; PKCS7 *p7 = NULL; X509 *x509 = NULL; PKCS7_SIGNER_INFO *si = NULL; EVP_PKEY *pkey = NULL; BIO *in = NULL, *p7bio = NULL; u8 *buf; r = extract_certificate_and_pkey(inst, &x509, &pkey); if (r) goto err; p7 = PKCS7_new(); if (p7 == NULL) { r = -1; goto err; } r = PKCS7_set_type(p7, NID_pkcs7_signed); if (r != 1) { r = -1; goto err; } EVP_add_digest(EVP_sha1()); si = PKCS7_add_signature(p7, x509, pkey, EVP_sha1()); if (si == NULL) { r = -1; goto err; } PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)); r = PKCS7_add_certificate(p7, x509); if (r != 1) { printf("PKCS7_add_certificate failed.\n"); goto err; } PKCS7_content_new(p7, NID_pkcs7_data); p7bio = PKCS7_dataInit(p7, NULL); if (p7bio == NULL) { r = -1; goto err; } in = BIO_new_mem_buf(inst->signdata, inst->signdata_len); if (in == NULL) { r = -1; goto err; } for (;;) { char lbuf[1024]; int i = BIO_read(in, lbuf, sizeof(lbuf)); if (i <= 0) break; BIO_write(p7bio, lbuf, i); } if (!PKCS7_dataFinal(p7, p7bio)) { r = -1; goto err; } /* FIXME: remove this */ r = i2d_PKCS7(p7, NULL); if (r <= 0) { r = -1; goto err; } buf = (u8 *) malloc(r); if (buf == NULL) goto err; *data = buf; r = i2d_PKCS7(p7, &buf); *datalen = r; if (r <= 0) { free(buf); r = -1; goto err; } r = 0; err: if (p7) PKCS7_free(p7); if (in) BIO_free(in); if (p7bio) BIO_free(p7bio); #if 0 if (si) PKCS7_SIGNER_INFO_free(si); #endif if (pkey) EVP_PKEY_free(pkey); if (x509) X509_free(x509); if (r) { #if 0 ERR_load_crypto_strings(); ERR_print_errors_fp(stderr); #endif } return r; }
/* * 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; }
/* will return 0, 1, 3, or 99 */ static int _pkgtrans(char *device1, char *device2, char **pkg, int options, keystore_handle_t keystore, char *keystore_alias) { BIO *p7_bio = NULL; EVP_PKEY *privkey = NULL; PKCS7 *sec_pkcs7 = NULL; PKCS7_SIGNER_INFO *sec_signerinfo = NULL; PKG_ERR *err; STACK_OF(X509) *cacerts = NULL; STACK_OF(X509) *clcerts = NULL; STACK_OF(X509) *sec_chain = NULL; X509 *pubcert = NULL; boolean_t making_sig = B_FALSE; char *src, *dst; int errflg, i, n; struct dm_buf *hdr; making_sig = (keystore != NULL) ? B_TRUE : B_FALSE; if (making_sig) { /* new error object */ err = pkgerr_new(); /* find matching cert and key */ if (find_key_cert_pair(err, keystore, keystore_alias, &privkey, &pubcert) != 0) { pkgerr(err); pkgerr_free(err); return (1); } /* get CA certificates */ if (find_ca_certs(err, keystore, &cacerts) != 0) { pkgerr(err); pkgerr_free(err); return (1); } /* get CL (aka "chain") certificates */ if (find_cl_certs(err, keystore, &clcerts) != 0) { pkgerr(err); pkgerr_free(err); return (1); } /* initialize PKCS7 object to be filled in later */ sec_pkcs7 = PKCS7_new(); (void) PKCS7_set_type(sec_pkcs7, NID_pkcs7_signed); sec_signerinfo = PKCS7_add_signature(sec_pkcs7, pubcert, privkey, EVP_sha1()); if (sec_signerinfo == NULL) { progerr(gettext(ERR_SEC), keystore_alias); ERR_print_errors_fp(stderr); pkgerr_free(err); return (1); } /* add signer cert into signature */ (void) PKCS7_add_certificate(sec_pkcs7, pubcert); /* attempt to resolve cert chain starting at the signer cert */ if (get_cert_chain(err, pubcert, clcerts, cacerts, &sec_chain) != 0) { pkgerr(err); pkgerr_free(err); return (1); } /* * add the verification chain of certs into the signature. * The first cert is the user cert, which we don't need, * since it's baked in already, so skip it */ for (i = 1; i < sk_X509_num(sec_chain); i++) { (void) PKCS7_add_certificate(sec_pkcs7, sk_X509_value(sec_chain, i)); } pkgerr_free(err); err = NULL; } if (signal_received > 0) { return (1); } /* transfer spool to appropriate device */ if (devtype(device1, &srcdev)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_BADDEV), device1); return (1); } srcdev.rdonly++; /* check for datastream */ ids_name = NULL; if (srcdev.bdevice) { if (n = _getvol(srcdev.bdevice, NULL, NULL, pkg_gt("Insert %v into %p."), srcdev.norewind)) { cleanup(); if (n == 3) return (3); progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_GETVOL)); return (1); } if (ds_readbuf(srcdev.cdevice)) ids_name = srcdev.cdevice; } if (srcdev.cdevice && !srcdev.bdevice) ids_name = srcdev.cdevice; else if (srcdev.pathname) { ids_name = srcdev.pathname; if (access(ids_name, 0) == -1) { progerr(ERR_TRANSFER); logerr(pkg_gt(MSG_GETVOL)); return (1); } } if (!ids_name && device2 == (char *)0) { if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) { cleanup(); return (n); } if (srcdev.mount && *srcdev.mount) pkgdir = strdup(srcdev.mount); return (0); } if (ids_name && device2 == (char *)0) { tmppath = tmpnam(NULL); tmppath = strdup(tmppath); if (tmppath == NULL) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_MEM)); return (1); } if (mkdir(tmppath, 0755)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_MKDIR), tmppath); return (1); } device2 = tmppath; } if (devtype(device2, &dstdev)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_BADDEV), device2); return (1); } if ((srcdev.cdevice && dstdev.cdevice) && strcmp(srcdev.cdevice, dstdev.cdevice) == 0) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_SAMEDEV)); return (1); } ods_name = NULL; if (dstdev.cdevice && !dstdev.bdevice || dstdev.pathname) options |= PT_ODTSTREAM; if (options & PT_ODTSTREAM) { if (!((ods_name = dstdev.cdevice) != NULL || (ods_name = dstdev.pathname) != NULL)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_BADDEV), device2); return (1); } if (ids_name) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_TWODSTREAM)); return (1); } } else { /* * output device isn't a stream. If we're making a signed * package, then fail, since we can't make signed, * non-stream pkgs */ if (making_sig) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(ERR_CANTSIGN)); return (1); } } if ((srcdev.dirname && dstdev.dirname) && strcmp(srcdev.dirname, dstdev.dirname) == 0) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_SAMEDEV)); return (1); } if ((srcdev.pathname && dstdev.pathname) && strcmp(srcdev.pathname, dstdev.pathname) == 0) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_SAMEDEV)); return (1); } if (signal_received > 0) { return (1); } if (ids_name) { if (srcdev.cdevice && !srcdev.bdevice && (n = _getvol(srcdev.cdevice, NULL, NULL, NULL, srcdev.norewind))) { cleanup(); if (n == 3) return (3); progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_GETVOL)); return (1); } if (srcdev.dirname = tmpnam(NULL)) tmpdir = srcdev.dirname = strdup(srcdev.dirname); if ((srcdev.dirname == NULL) || mkdir(srcdev.dirname, 0755) || chdir(srcdev.dirname)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_NOTEMP), srcdev.dirname); cleanup(); return (1); } if (ds_init(ids_name, pkg, srcdev.norewind)) { cleanup(); return (1); } } else if (srcdev.mount) { if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) { cleanup(); return (n); } } src = srcdev.dirname; dst = dstdev.dirname; if (chdir(src)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_CHDIR), src); cleanup(); return (1); } if (signal_received > 0) { return (1); } xpkg = pkg = gpkglist(src, pkg, NULL); if (!pkg) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_NOPKGS), src); cleanup(); return (1); } for (nxpkg = 0; pkg[nxpkg]; /* void */) { nxpkg++; /* count */ } if (ids_name) { ds_order(pkg); /* order requests */ } if (signal_received > 0) { return (1); } if (options & PT_ODTSTREAM) { char line[128]; if (!dstdev.pathname && (n = _getvol(ods_name, NULL, DM_FORMAT, NULL, dstdev.norewind))) { cleanup(); if (n == 3) return (3); progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_GETVOL)); return (1); } if ((hdr = genheader(src, pkg)) == NULL) { cleanup(); return (1); } if (making_sig) { /* start up signature data stream */ (void) PKCS7_content_new(sec_pkcs7, NID_pkcs7_data); (void) PKCS7_set_detached(sec_pkcs7, 1); p7_bio = PKCS7_dataInit(sec_pkcs7, NULL); /* * Here we generate all the data that will go into * the package, and send it through the signature * generator, essentially calculating the signature * of the entire package so we can place it in the * header. Otherwise we'd have to place it at the end * of the pkg, which would break the ABI */ if (!(options & PT_SILENT)) { (void) fprintf(stderr, pkg_gt(MSG_SIGNING), get_subject_display_name(pubcert)); } if (dump_hdr_and_pkgs(p7_bio, hdr, pkg) != 0) { progerr(gettext(ERR_NOGEN)); logerr(pkg_gt(MSG_GETVOL)); cleanup(); return (1); } BIO_flush(p7_bio); /* * now generate PKCS7 signature */ if (!PKCS7_dataFinal(sec_pkcs7, p7_bio)) { progerr(gettext(ERR_NOGEN)); logerr(pkg_gt(MSG_GETVOL)); cleanup(); return (1); } (void) BIO_free(p7_bio); } /* write out header to stream, which includes signature */ if (wdsheader(hdr, src, ods_name, pkg, sec_pkcs7)) { cleanup(); return (1); } if (sec_pkcs7 != NULL) { /* nuke in-memory signature for safety */ PKCS7_free(sec_pkcs7); sec_pkcs7 = NULL; } ds_volno = 1; /* number of volumes in datastream */ pinput = hdrbuf.text_buffer; /* skip past first line in header */ (void) mgets(line, 128); } if (signal_received > 0) { return (1); } errflg = 0; for (i = 0; pkg[i]; i++) { if (signal_received > 0) { return (1); } if (!(options & PT_ODTSTREAM) && dstdev.mount) { if (n = pkgmount(&dstdev, NULL, 0, 0, 1)) { cleanup(); return (n); } } if (errflg = pkgxfer(pkg[i], options)) { pkg[i] = NULL; if ((options & PT_ODTSTREAM) || (errflg != 2)) break; } else if (strcmp(dstinst, pkg[i])) pkg[i] = strdup(dstinst); } if (!(options & PT_ODTSTREAM) && dst) { pkgdir = strdup(dst); } /* * No cleanup of temporary directories created in this * function is done here. The calling function must do * the cleanup. */ return (signal_received > 0 ? 1 : errflg); }
/* * 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); }
char* sign_and_encrypt(const char *data, RSA *rsa, X509 *x509, X509 *PPx509, int verbose) /* sign and encrypt button data for safe delivery to paypal */ { char *ret = NULL; EVP_PKEY *pkey; PKCS7 *p7 = NULL; BIO *p7bio = NULL; BIO *bio = NULL; PKCS7_SIGNER_INFO* si; int len; char *str; pkey = EVP_PKEY_new(); if (EVP_PKEY_set1_RSA(pkey, rsa) == 0) { fprintf(stderr,"Fatal Error: Unable to create EVP_KEY from RSA key\n");fflush(stderr); goto end; } else if (verbose) { printf("Successfully created EVP_KEY from RSA key\n"); } /* Create a signed and enveloped PKCS7 */ p7 = PKCS7_new(); PKCS7_set_type(p7, NID_pkcs7_signedAndEnveloped); si = PKCS7_add_signature(p7, x509, pkey, EVP_sha1()); if (si) { if (PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, V_ASN1_OBJECT, OBJ_nid2obj(NID_pkcs7_data)) <= 0) { fprintf(stderr,"Fatal Error: Unable to add signed attribute to certificate\n"); fprintf(stderr,"OpenSSL Error: %s\n", ERR_error_string(ERR_get_error(), NULL)); fflush(stderr); goto end; } else if (verbose) { printf("Successfully added signed attribute to certificate\n"); } } else { fprintf(stderr,"Fatal Error: Failed to sign PKCS7\n");fflush(stderr); goto end; } /* Encryption */ if (PKCS7_set_cipher(p7, EVP_des_ede3_cbc()) <= 0) { fprintf(stderr,"Fatal Error: Failed to set encryption algorithm\n"); fprintf(stderr,"OpenSSL Error: %s\n", ERR_error_string(ERR_get_error(), NULL)); fflush(stderr); goto end; } else if (verbose) { printf("Successfully added encryption algorithm\n"); } if (PKCS7_add_recipient(p7, PPx509) <= 0) { fprintf(stderr,"Fatal Error: Failed to add PKCS7 recipient\n"); fprintf(stderr,"OpenSSL Error: %s\n", ERR_error_string(ERR_get_error(), NULL)); fflush(stderr); goto end; } else if (verbose) { printf("Successfully added recipient\n"); } if (PKCS7_add_certificate(p7, x509) <= 0) { fprintf(stderr,"Fatal Error: Failed to add PKCS7 certificate\n"); fprintf(stderr,"OpenSSL Error: %s\n", ERR_error_string(ERR_get_error(), NULL)); fflush(stderr); goto end; } else if (verbose) { printf("Successfully added certificate\n"); } p7bio = PKCS7_dataInit(p7, NULL); if (!p7bio) { fprintf(stderr,"OpenSSL Error: %s\n", ERR_error_string(ERR_get_error(), NULL)); fflush(stderr); goto end; } /* Pump data to special PKCS7 BIO. This encrypts and signs it. */ BIO_write(p7bio, data, strlen(data)); BIO_flush(p7bio); PKCS7_dataFinal(p7, p7bio); /* Write PEM encoded PKCS7 */ bio = BIO_new(BIO_s_mem()); if (!bio || (PEM_write_bio_PKCS7(bio, p7) == 0)) { fprintf(stderr,"Fatal Error: Failed to create PKCS7 PEM\n");fflush(stderr); } else if (verbose) { printf("Successfully created PKCS7 PEM\n"); } BIO_flush(bio); len = BIO_get_mem_data(bio, &str); ret = malloc(sizeof(char)*(len+1)); memcpy(ret, str, len); ret[len] = 0; end: /* Free everything */ if (bio) BIO_free_all(bio); if (p7bio) BIO_free_all(p7bio); if (p7) PKCS7_free(p7); if (pkey) EVP_PKEY_free(pkey); return ret; }
int main(int argc, char* argv[]) { PKCS7 *p7, *innerp7; FILE *fp = NULL; EVP_PKEY *pkey = NULL; PKCS7_SIGNER_INFO *p7i; PKCS7_RECIP_INFO *pri; BIO *mybio, *inbio; X509 *user; X509_ALGOR *md; int ret, len; unsigned char data[2048], *p, *buf; unsigned char* greet = "hello openssl"; unsigned long errorno; unsigned char* errordesc; OpenSSL_add_all_algorithms(); //必须要显式进行调用 inbio = BIO_new(BIO_s_mem()); ret = BIO_write(inbio, greet, strlen(greet)); p7 = PKCS7_new(); ret = PKCS7_set_type(p7, NID_pkcs7_signedAndEnveloped); //加载用户证书 fp = fopen("mycert4p12.cer", "rb"); if(fp == NULL) return 0; len = fread(data, 1, 1024, fp); fclose(fp); p = data; user = d2i_X509(NULL, (const unsigned char**)&p, len); ret = PKCS7_add_certificate(p7, user); pri = PKCS7_add_recipient(p7, user); //读取私钥 fp = fopen("myprivkey.pem", "rb"); if(fp == NULL) return 0; len = fread(data, 1, 1024, fp); fclose(fp); p = data; pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, (const unsigned char**)&p, len); //第一个用户增加SignerInfo到列表中 p7i = PKCS7_add_signature(p7, user, pkey, EVP_md5()); //加载用户证书 fp = fopen("user2.cer", "rb"); if(fp == NULL) return 0; len = fread(data, 1, 1024, fp); fclose(fp); p = data; user = d2i_X509(NULL, (const unsigned char**)&p, len); ret = PKCS7_add_certificate(p7, user); pri = PKCS7_add_recipient(p7, user); //读取私钥 fp = fopen("user2_privatekey.pem", "rb"); if(fp == NULL) return 0; len = fread(data, 1, 1024, fp); fclose(fp); p = data; pkey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, (const unsigned char**)&p, len); //第二个签名者增加到SignerInfo列表中 p7i = PKCS7_add_signature(p7, user, pkey, EVP_md5()); ret = PKCS7_set_cipher(p7, EVP_des_ede3_cbc()); ret = PKCS7_final(p7, inbio, 0); //制作数字信封 len = i2d_PKCS7(p7, NULL); p = buf = malloc(len); len = i2d_PKCS7(p7, &p); printf("in i2d len = %d\n", len); fp = fopen("p7signandenv.cer", "wb"); fwrite(buf, len, 1, fp); fclose(fp); PKCS7_free(p7); }
/* will return 0, 1, 3, or 99 */ static int _pkgtrans(char *device1, char *device2, char **pkg, int options, keystore_handle_t keystore, char *keystore_alias) { #ifdef USE_KEYSTORE BIO *p7_bio = NULL; EVP_PKEY *privkey = NULL; #endif PKCS7 *sec_pkcs7 = NULL; #ifdef USE_KEYSTORE PKCS7_SIGNER_INFO *sec_signerinfo = NULL; PKG_ERR *err; STACK_OF(X509) *cacerts = NULL; STACK_OF(X509) *clcerts = NULL; STACK_OF(X509) *sec_chain = NULL; X509 *pubcert = NULL; #endif boolean_t making_sig = B_FALSE; char *src, *dst; int errflg, i, n; struct dm_buf *hdr; making_sig = (keystore != NULL) ? B_TRUE : B_FALSE; #ifdef USE_KEYSTORE if (making_sig) { /* new error object */ err = pkgerr_new(); /* find matching cert and key */ if (find_key_cert_pair(err, keystore, keystore_alias, &privkey, &pubcert) != 0) { pkgerr(err); pkgerr_free(err); return (1); } /* get CA certificates */ if (find_ca_certs(err, keystore, &cacerts) != 0) { pkgerr(err); pkgerr_free(err); return (1); } /* get CL (aka "chain") certificates */ if (find_cl_certs(err, keystore, &clcerts) != 0) { pkgerr(err); pkgerr_free(err); return (1); } /* initialize PKCS7 object to be filled in later */ sec_pkcs7 = PKCS7_new(); PKCS7_set_type(sec_pkcs7, NID_pkcs7_signed); sec_signerinfo = PKCS7_add_signature(sec_pkcs7, pubcert, privkey, EVP_sha1()); if (sec_signerinfo == NULL) { progerr(gettext(ERR_SEC), keystore_alias); ERR_print_errors_fp(stderr); pkgerr_free(err); return (1); } /* add signer cert into signature */ PKCS7_add_certificate(sec_pkcs7, pubcert); /* attempt to resolve cert chain starting at the signer cert */ if (get_cert_chain(err, pubcert, clcerts, cacerts, &sec_chain) != 0) { pkgerr(err); pkgerr_free(err); return (1); } /* * add the verification chain of certs into the signature. * The first cert is the user cert, which we don't need, * since it's baked in already, so skip it */ for (i = 1; i < sk_X509_num(sec_chain); i++) { PKCS7_add_certificate(sec_pkcs7, sk_X509_value(sec_chain, i)); } pkgerr_free(err); err = NULL; } #endif /* USE_KEYSTORE */ if (signal_received > 0) { return (1); } /* transfer spool to appropriate device */ if (devtype(device1, &srcdev)) { progerr(pkg_gt(ERR_TRANSFER)); logerr(pkg_gt(MSG_BADDEV), device1); return (1); } srcdev.rdonly++; /* check for datastream */ ids_name = NULL; if (srcdev.bdevice) { if (ds_readbuf(srcdev.cdevice)) ids_name = srcdev.cdevice; } if (srcdev.cdevice && !srcdev.bdevice) ids_name = srcdev.cdevice; else if (srcdev.pathname) { ids_name = srcdev.pathname; if (access(ids_name, 0) == -1) { progerr(ERR_TRANSFER); logerr(pkg_gt(MSG_GETVOL)); return (1); } } if (!ids_name && device2 == (char *)0) { if (n = pkgmount(&srcdev, NULL, 1, 0, 0)) { cleanup(); return (n); } if (srcdev.mount && *srcdev.mount) pkgdir = strdup(srcdev.mount); return (0); } if (ids_name && device2 == (char *)0) { char template[] = "/var/tmp/ptXXXXXX";
int smime_main(int argc, char **argv) { BIO *in = NULL, *out = NULL, *indata = NULL; EVP_PKEY *key = NULL; PKCS7 *p7 = NULL; STACK_OF(OPENSSL_STRING) *sksigners = NULL, *skkeys = NULL; STACK_OF(X509) *encerts = NULL, *other = NULL; X509 *cert = NULL, *recip = NULL, *signer = NULL; X509_STORE *store = NULL; X509_VERIFY_PARAM *vpm = NULL; const EVP_CIPHER *cipher = NULL; const EVP_MD *sign_md = NULL; const char *CAfile = NULL, *CApath = NULL, *prog = NULL; char *certfile = NULL, *keyfile = NULL, *contfile = NULL, *inrand = NULL; char *infile = NULL, *outfile = NULL, *signerfile = NULL, *recipfile = NULL; char *passinarg = NULL, *passin = NULL, *to = NULL, *from = NULL, *subject = NULL; OPTION_CHOICE o; int noCApath = 0, noCAfile = 0; int flags = PKCS7_DETACHED, operation = 0, ret = 0, need_rand = 0, indef = 0; int informat = FORMAT_SMIME, outformat = FORMAT_SMIME, keyform = FORMAT_PEM; int vpmtouched = 0, rv = 0; ENGINE *e = NULL; const char *mime_eol = "\n"; if ((vpm = X509_VERIFY_PARAM_new()) == NULL) return 1; prog = opt_init(argc, argv, smime_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(smime_options); ret = 0; goto end; case OPT_INFORM: if (!opt_format(opt_arg(), OPT_FMT_PDS, &informat)) goto opthelp; break; case OPT_IN: infile = opt_arg(); break; case OPT_OUTFORM: if (!opt_format(opt_arg(), OPT_FMT_PDS, &outformat)) goto opthelp; break; case OPT_OUT: outfile = opt_arg(); break; case OPT_ENCRYPT: operation = SMIME_ENCRYPT; break; case OPT_DECRYPT: operation = SMIME_DECRYPT; break; case OPT_SIGN: operation = SMIME_SIGN; break; case OPT_RESIGN: operation = SMIME_RESIGN; break; case OPT_VERIFY: operation = SMIME_VERIFY; break; case OPT_PK7OUT: operation = SMIME_PK7OUT; break; case OPT_TEXT: flags |= PKCS7_TEXT; break; case OPT_NOINTERN: flags |= PKCS7_NOINTERN; break; case OPT_NOVERIFY: flags |= PKCS7_NOVERIFY; break; case OPT_NOCHAIN: flags |= PKCS7_NOCHAIN; break; case OPT_NOCERTS: flags |= PKCS7_NOCERTS; break; case OPT_NOATTR: flags |= PKCS7_NOATTR; break; case OPT_NODETACH: flags &= ~PKCS7_DETACHED; break; case OPT_NOSMIMECAP: flags |= PKCS7_NOSMIMECAP; break; case OPT_BINARY: flags |= PKCS7_BINARY; break; case OPT_NOSIGS: flags |= PKCS7_NOSIGS; break; case OPT_STREAM: case OPT_INDEF: indef = 1; break; case OPT_NOINDEF: indef = 0; break; case OPT_CRLFEOL: flags |= PKCS7_CRLFEOL; mime_eol = "\r\n"; break; case OPT_RAND: inrand = opt_arg(); need_rand = 1; break; case OPT_ENGINE: e = setup_engine(opt_arg(), 0); break; case OPT_PASSIN: passinarg = opt_arg(); break; case OPT_TO: to = opt_arg(); break; case OPT_FROM: from = opt_arg(); break; case OPT_SUBJECT: subject = opt_arg(); break; case OPT_SIGNER: /* If previous -signer argument add signer to list */ if (signerfile) { if (sksigners == NULL && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); if (keyfile == NULL) keyfile = signerfile; if (skkeys == NULL && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(skkeys, keyfile); keyfile = NULL; } signerfile = opt_arg(); break; case OPT_RECIP: recipfile = opt_arg(); break; case OPT_MD: if (!opt_md(opt_arg(), &sign_md)) goto opthelp; break; case OPT_CIPHER: if (!opt_cipher(opt_unknown(), &cipher)) goto opthelp; break; case OPT_INKEY: /* If previous -inkey argument add signer to list */ if (keyfile) { if (signerfile == NULL) { BIO_printf(bio_err, "%s: Must have -signer before -inkey\n", prog); goto opthelp; } if (sksigners == NULL && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); signerfile = NULL; if (skkeys == NULL && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(skkeys, keyfile); } keyfile = opt_arg(); break; case OPT_KEYFORM: if (!opt_format(opt_arg(), OPT_FMT_ANY, &keyform)) goto opthelp; break; case OPT_CERTFILE: certfile = opt_arg(); break; case OPT_CAFILE: CAfile = opt_arg(); break; case OPT_CAPATH: CApath = opt_arg(); break; case OPT_NOCAFILE: noCAfile = 1; break; case OPT_NOCAPATH: noCApath = 1; break; case OPT_CONTENT: contfile = opt_arg(); break; case OPT_V_CASES: if (!opt_verify(o, vpm)) goto opthelp; vpmtouched++; break; } } argc = opt_num_rest(); argv = opt_rest(); if (!(operation & SMIME_SIGNERS) && (skkeys || sksigners)) { BIO_puts(bio_err, "Multiple signers or keys not allowed\n"); goto opthelp; } if (operation & SMIME_SIGNERS) { /* Check to see if any final signer needs to be appended */ if (keyfile && !signerfile) { BIO_puts(bio_err, "Illegal -inkey without -signer\n"); goto opthelp; } if (signerfile) { if (!sksigners && (sksigners = sk_OPENSSL_STRING_new_null()) == NULL) goto end; sk_OPENSSL_STRING_push(sksigners, signerfile); if (!skkeys && (skkeys = sk_OPENSSL_STRING_new_null()) == NULL) goto end; if (!keyfile) keyfile = signerfile; sk_OPENSSL_STRING_push(skkeys, keyfile); } if (!sksigners) { BIO_printf(bio_err, "No signer certificate specified\n"); goto opthelp; } signerfile = NULL; keyfile = NULL; need_rand = 1; } else if (operation == SMIME_DECRYPT) { if (!recipfile && !keyfile) { BIO_printf(bio_err, "No recipient certificate or key specified\n"); goto opthelp; } } else if (operation == SMIME_ENCRYPT) { if (argc == 0) { BIO_printf(bio_err, "No recipient(s) certificate(s) specified\n"); goto opthelp; } need_rand = 1; } else if (!operation) goto opthelp; if (!app_passwd(passinarg, NULL, &passin, NULL)) { BIO_printf(bio_err, "Error getting password\n"); goto end; } if (need_rand) { app_RAND_load_file(NULL, (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_SIGNERS)) flags &= ~PKCS7_DETACHED; if (!(operation & SMIME_OP)) { if (flags & PKCS7_BINARY) outformat = FORMAT_BINARY; } if (!(operation & SMIME_IP)) { if (flags & PKCS7_BINARY) informat = FORMAT_BINARY; } if (operation == SMIME_ENCRYPT) { if (!cipher) { #ifndef OPENSSL_NO_DES cipher = EVP_des_ede3_cbc(); #else BIO_printf(bio_err, "No cipher selected\n"); goto end; #endif } encerts = sk_X509_new_null(); if (!encerts) goto end; while (*argv) { cert = load_cert(*argv, FORMAT_PEM, "recipient certificate file"); if (cert == NULL) goto end; sk_X509_push(encerts, cert); cert = NULL; argv++; } } if (certfile) { if (!load_certs(certfile, &other, FORMAT_PEM, NULL, "certificate file")) { ERR_print_errors(bio_err); goto end; } } if (recipfile && (operation == SMIME_DECRYPT)) { if ((recip = load_cert(recipfile, FORMAT_PEM, "recipient certificate file")) == NULL) { 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(keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; } in = bio_open_default(infile, 'r', informat); if (in == NULL) goto end; if (operation & SMIME_IP) { 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")) == NULL) { BIO_printf(bio_err, "Can't read content file %s\n", contfile); goto end; } } } out = bio_open_default(outfile, 'w', outformat); if (out == NULL) goto end; if (operation == SMIME_VERIFY) { if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL) goto end; X509_STORE_set_verify_cb(store, smime_cb); if (vpmtouched) X509_STORE_set1_param(store, vpm); } ret = 3; if (operation == SMIME_ENCRYPT) { if (indef) flags |= PKCS7_STREAM; p7 = PKCS7_encrypt(encerts, in, cipher, flags); } else if (operation & SMIME_SIGNERS) { int i; /* * If detached data content we only enable streaming if S/MIME output * format. */ if (operation == SMIME_SIGN) { if (flags & PKCS7_DETACHED) { if (outformat == FORMAT_SMIME) flags |= PKCS7_STREAM; } else if (indef) flags |= PKCS7_STREAM; flags |= PKCS7_PARTIAL; p7 = PKCS7_sign(NULL, NULL, other, in, flags); if (!p7) goto end; if (flags & PKCS7_NOCERTS) { for (i = 0; i < sk_X509_num(other); i++) { X509 *x = sk_X509_value(other, i); PKCS7_add_certificate(p7, x); } } } else flags |= PKCS7_REUSE_DIGEST; for (i = 0; i < sk_OPENSSL_STRING_num(sksigners); i++) { signerfile = sk_OPENSSL_STRING_value(sksigners, i); keyfile = sk_OPENSSL_STRING_value(skkeys, i); signer = load_cert(signerfile, FORMAT_PEM, "signer certificate"); if (!signer) goto end; key = load_key(keyfile, keyform, 0, passin, e, "signing key file"); if (!key) goto end; if (!PKCS7_sign_add_signer(p7, signer, key, sign_md, flags)) goto end; X509_free(signer); signer = NULL; EVP_PKEY_free(key); key = NULL; } /* If not streaming or resigning finalize structure */ if ((operation == SMIME_SIGN) && !(flags & PKCS7_STREAM)) { if (!PKCS7_final(p7, in, flags)) 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%s", to, mime_eol); if (from) BIO_printf(out, "From: %s%s", from, mime_eol); if (subject) BIO_printf(out, "Subject: %s%s", subject, mime_eol); if (outformat == FORMAT_SMIME) { if (operation == SMIME_RESIGN) rv = SMIME_write_PKCS7(out, p7, indata, flags); else rv = SMIME_write_PKCS7(out, p7, in, flags); } else if (outformat == FORMAT_PEM) rv = PEM_write_bio_PKCS7_stream(out, p7, in, flags); else if (outformat == FORMAT_ASN1) rv = i2d_PKCS7_bio_stream(out, p7, in, flags); else { BIO_printf(bio_err, "Bad output format for PKCS#7 file\n"); goto end; } if (rv == 0) { BIO_printf(bio_err, "Error writing output\n"); ret = 3; goto end; } } ret = 0; end: if (need_rand) app_RAND_write_file(NULL); if (ret) ERR_print_errors(bio_err); sk_X509_pop_free(encerts, X509_free); sk_X509_pop_free(other, X509_free); X509_VERIFY_PARAM_free(vpm); sk_OPENSSL_STRING_free(sksigners); sk_OPENSSL_STRING_free(skkeys); X509_STORE_free(store); X509_free(cert); X509_free(recip); X509_free(signer); EVP_PKEY_free(key); PKCS7_free(p7); release_engine(e); BIO_free(in); BIO_free(indata); BIO_free_all(out); OPENSSL_free(passin); return (ret); }
/* Allocate the SCEP_MSG structures */ SCEP_MSG *SCEP_MSG_new( int messageType, X509 *cert, EVP_PKEY *pkey, X509 *recip_cert, SCEP_MSG *inMsg, X509_REQ *req, X509 *issued_cert, SCEP_ISSUER_AND_SUBJECT *cert_info, PKCS7_ISSUER_AND_SERIAL *ias, X509_CRL *crl, X509 *cacert, EVP_CIPHER cipher ) { SCEP_MSG *msg = NULL; PKCS7_SIGNER_INFO *si = NULL; EVP_MD *dgst=NULL; unsigned char *raw_data = NULL; int envelope = 0; long raw_len = 0; BIO *debug_bio = NULL; BIO *p7ebio = NULL; BIO *inbio = NULL; char buf[256]; if ((debug_bio=BIO_new(BIO_s_file())) != NULL) BIO_set_fp(debug_bio,stderr,BIO_NOCLOSE|BIO_FP_TEXT); //if( !cert || !pkey || !recip_cert ) if( !cert || !pkey ) return NULL; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] Generating New SCEP-Message...\n", __FILE__, __LINE__); /* Allocate memory and initialize structures */ if((msg = SCEP_MSG_new_null()) == NULL) return NULL; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] Allocate memory\n", __FILE__, __LINE__); /* Signed Infos */ dgst = (EVP_MD *) EVP_get_digestbyname("md5"); if( (si = PKCS7_SIGNER_INFO_new()) == NULL ) goto err; if(!PKCS7_SIGNER_INFO_set(si, cert, pkey, dgst)) goto err; sk_PKCS7_SIGNER_INFO_push( msg->sk_signer_info, si ); msg->signer_ias = si->issuer_and_serial; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] signer infos set\n", __FILE__, __LINE__); /* If pkey, let's add to the message structure to ease * message encryption (enveloped data content creation) */ SCEP_MSG_set_pkey ( msg, pkey ); // msg->signer_pkey = pkey; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] encryption key set\n", __FILE__, __LINE__); /* If not explicit, we guess the certificate to be present * in the passed inMsg structure, if any. Otherwise ERROR! */ if( !recip_cert && inMsg ) recip_cert = inMsg->signer_cert; /* Set the messageType */ SCEP_set_messageType ( msg, messageType ); if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] message type set\n", __FILE__, __LINE__); switch( messageType ) { case MSG_CERTREP: if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for CERTREP\n", __FILE__, __LINE__); msg->env_data.NID_p7data = NID_pkcs7_signed; msg->env_data.p7 = PKCS7_new(); PKCS7_set_type( msg->env_data.p7, NID_pkcs7_signed ); PKCS7_content_new( msg->env_data.p7, NID_pkcs7_data ); if( issued_cert ) { if (debug) BIO_printf( debug_bio, "%s:%d: creating inner degenerated PKCS7... \n", __FILE__, __LINE__); /* Adds issued certificate */ PKCS7_add_certificate( msg->env_data.p7, issued_cert ); // PKCS7_add_certificate( msg->env_data.p7, cert ); envelope = 1; if (debug) BIO_printf( debug_bio, "%s:%d: done \n", __FILE__, __LINE__); } else if( crl ) { if (debug) BIO_printf( debug_bio, "%s:%d: Adding CRL ... \n", __FILE__, __LINE__); /* Adds crl */ PKCS7_add_crl( msg->env_data.p7, crl ); envelope = 1; if (debug) BIO_printf( debug_bio, "%s:%d: done \n", __FILE__, __LINE__); } if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); break; case MSG_PKCSREQ: if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for PKCSREQ\n", __FILE__, __LINE__); /* The inner pkcs7 structure is signed * and enveloped and the data is to be * the X509_REQ passed */ msg->env_data.NID_p7data = NID_pkcs7_signedAndEnveloped; if( req ) { msg->env_data.content.req = req; /* Ask for the data p7 to be generated and * encrypted */ envelope = 1; } if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); break; case MSG_GETCRL: if (debug) { BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for GETCRL\n", __FILE__, __LINE__); BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } break; case MSG_GETCERT: if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for GETCERT\n", __FILE__, __LINE__); msg->env_data.NID_p7data = NID_pkcs7_signedAndEnveloped; /* If it is a query for a general certificate * the CAcert should be included in the enveloped * data*/ /* Otherwise, if it is a request for its own * certificate, the self-signed certificate should * be included */ // if( cacert ) // msg->env_data.cacert = cacert; /* Issuer and Serial should be present ! */ if( !ias ) goto err; msg->env_data.content.ias = ias; envelope = 1; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); break; case MSG_GETCERTINITIAL: if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for GETCERTINITIAL\n", __FILE__, __LINE__); msg->env_data.NID_p7data = NID_pkcs7_signed; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); break; case MSG_V2REQUEST: /* Not currently handled */ if (debug) { BIO_printf( debug_bio, "%s:%d: [Debug Info] Actions for V2REQUEST\n", __FILE__, __LINE__); BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } default: goto err; } if (debug) BIO_printf( debug_bio, "%s:%d: Debug ... \n", __FILE__, __LINE__); /* If different from NULL, we have to encode something */ if( envelope == 1 ) { if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] encode\n", __FILE__, __LINE__); /* Encrypt the message data */ if( !SCEP_MSG_encrypt( msg, recip_cert, cipher )) goto err; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] add sign-cert to structure\n", __FILE__, __LINE__); /* Signer certificate */ msg->signer_cert = cert; if (debug) PEM_write_bio_SCEP_MSG( debug_bio, msg, pkey ); if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] add attributes\n", __FILE__, __LINE__); /* Set message attributes, if any */ if ( inMsg ) { char *tmp = NULL; int len = 0; if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] take data from request\n", __FILE__, __LINE__); switch ( msg->messageType ) { default: if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] set transId\n", __FILE__, __LINE__); /* The transId is ever required */ tmp = SCEP_get_string_attr_by_name( inMsg->attrs, "transId"); if( tmp ) { SCEP_set_transId( msg, tmp, strlen(tmp)); OPENSSL_free( tmp ); if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] set recipient nonce (sendernonce from req)\n", __FILE__, __LINE__); /* Copy the sendernonce to the recipient nonce and * generate a new sendernonce for the generated msg */ tmp = SCEP_get_octect_attr_by_name( inMsg->attrs, "senderNonce", &len); if( tmp ) { if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] %d\n", __FILE__, __LINE__, tmp); SCEP_set_recipientNonce( msg, tmp, len ); OPENSSL_free( tmp ); } if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] set sender nonce\n", __FILE__, __LINE__); SCEP_set_senderNonce_new(msg); if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] set pki_status\n", __FILE__, __LINE__); SCEP_set_pkiStatus ( msg, PKI_PENDING ); if (debug) { BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } } else { if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] generate new data\n", __FILE__, __LINE__); SCEP_set_senderNonce_new ( msg ); SCEP_set_recipientNonce_new ( msg ); SCEP_set_transId_new ( msg ); if (debug) BIO_printf( debug_bio, "%s:%d: [Debug Info] done\n", __FILE__, __LINE__); } if (debug) PEM_write_bio_SCEP_MSG( debug_bio, msg, pkey ); return (msg); err: ERR_print_errors_fp(stderr); return(NULL); }