示例#1
0
static LUA_FUNCTION(openssl_csr_export)
{
  X509_REQ * csr = CHECK_OBJECT(1, X509_REQ, "openssl.x509_req");
  int fmt = luaL_checkoption(L, 2, "pem", format);
  int notext = lua_isnoneornil(L, 3) ? 1 : lua_toboolean(L, 3);
  BIO *out  = NULL;

  luaL_argcheck(L, fmt == FORMAT_DER || fmt == FORMAT_PEM, 2,
                "only accept der or pem");
  out = BIO_new(BIO_s_mem());
  if (fmt == FORMAT_PEM)
  {
    if (!notext)
    {
      X509_REQ_print(out, csr);
    }

    if (PEM_write_bio_X509_REQ(out, csr))
    {
      BUF_MEM *bio_buf;

      BIO_get_mem_ptr(out, &bio_buf);
      lua_pushlstring(L, bio_buf->data, bio_buf->length);
    }
    else
    {
      lua_pushnil(L);
    }
  }
  else
  {
    if (i2d_X509_REQ_bio(out, csr))
    {
      BUF_MEM *bio_buf;

      BIO_get_mem_ptr(out, &bio_buf);
      lua_pushlstring(L, bio_buf->data, bio_buf->length);
    }
    else
    {
      lua_pushnil(L);
    }
  }
  BIO_free(out);
  return 1;
}
示例#2
0
/*******************************************************************************
函数名称: 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;
}
示例#3
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;
}
示例#4
0
文件: pkcs7.c 项目: OPSF/uClinux
/*
 * 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);
}
		inline void certificate_request::write_der(bio::bio_ptr bio) const
		{
			error::throw_error_if_not(i2d_X509_REQ_bio(bio.raw(), ptr().get()) != 0);
		}
示例#6
0
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;
}