コード例 #1
0
ファイル: pal_pkcs7.cpp プロジェクト: 553226713/corefx
extern "C" PKCS7* CryptoNative_Pkcs7CreateSigned()
{
    PKCS7* pkcs7 = PKCS7_new();

    if (pkcs7 == nullptr)
    {
        return nullptr;
    }

    if (!PKCS7_set_type(pkcs7, NID_pkcs7_signed) || !PKCS7_content_new(pkcs7, NID_pkcs7_data))
    {
        PKCS7_free(pkcs7);
        return nullptr;
    }

    return pkcs7;
}
コード例 #2
0
ファイル: pk7_lib.c プロジェクト: GrayKing/Leakfix-on-OpenSSL
int PKCS7_content_new(PKCS7 *p7, int type)
{
    PKCS7 *ret = NULL;

    if ((ret = PKCS7_new()) == NULL)
        goto err;
    if (!PKCS7_set_type(ret, type))
        goto err;
    if (!PKCS7_set_content(p7, ret))
        goto err;

    return (1);
 err:
    if (ret != NULL)
        PKCS7_free(ret);
    return (0);
}
コード例 #3
0
ファイル: ts.c プロジェクト: Beatzevo/openssl
static int verify_command(char *data, char *digest, char *queryfile,
                          char *in, int token_in,
                          char *CApath, char *CAfile, char *untrusted,
                          X509_VERIFY_PARAM *vpm)
{
    BIO *in_bio = NULL;
    PKCS7 *token = NULL;
    TS_RESP *response = NULL;
    TS_VERIFY_CTX *verify_ctx = NULL;
    int ret = 0;

    if ((in_bio = BIO_new_file(in, "rb")) == NULL)
        goto end;
    if (token_in) {
        if ((token = d2i_PKCS7_bio(in_bio, NULL)) == NULL)
            goto end;
    } else {
        if ((response = d2i_TS_RESP_bio(in_bio, NULL)) == NULL)
            goto end;
    }

    if ((verify_ctx = create_verify_ctx(data, digest, queryfile,
                                        CApath, CAfile, untrusted,
                                        vpm)) == NULL)
        goto end;

    ret = token_in
        ? TS_RESP_verify_token(verify_ctx, token)
        : TS_RESP_verify_response(verify_ctx, response);

 end:
    printf("Verification: ");
    if (ret)
        printf("OK\n");
    else {
        printf("FAILED\n");
        ERR_print_errors(bio_err);
    }

    BIO_free_all(in_bio);
    PKCS7_free(token);
    TS_RESP_free(response);
    TS_VERIFY_CTX_free(verify_ctx);
    return ret;
}
コード例 #4
0
int PEM_write_bio_SCEP_MSG(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;

	BIO_printf( bio, "-----BEGIN SCEP MESSAGE-----\n" );
	ret = B64_write_bio_PKCS7(bio, p7);
	BIO_printf( bio, "-----END SCEP MESSAGE-----\n" );
	PKCS7_free( p7 );

	ERR_clear_error();

	return ret;
}
コード例 #5
0
ファイル: ts.c プロジェクト: Heratom/Firefly-project
/* Reads a PKCS7 token and adds default 'granted' status info to it. */
static TS_RESP *
read_PKCS7(BIO * in_bio)
{
	int ret = 0;
	PKCS7 *token = NULL;
	TS_TST_INFO *tst_info = NULL;
	TS_RESP *resp = NULL;
	TS_STATUS_INFO *si = NULL;

	/* Read PKCS7 object and extract the signed time stamp info. */
	if (!(token = d2i_PKCS7_bio(in_bio, NULL)))
		goto end;
	if (!(tst_info = PKCS7_to_TS_TST_INFO(token)))
		goto end;

	/* Creating response object. */
	if (!(resp = TS_RESP_new()))
		goto end;

	/* Create granted status info. */
	if (!(si = TS_STATUS_INFO_new()))
		goto end;
	if (!(ASN1_INTEGER_set(si->status, TS_STATUS_GRANTED)))
		goto end;
	if (!TS_RESP_set_status_info(resp, si))
		goto end;

	/* Setting encapsulated token. */
	TS_RESP_set_tst_info(resp, token, tst_info);
	token = NULL;		/* Ownership is lost. */
	tst_info = NULL;	/* Ownership is lost. */

	ret = 1;
end:
	PKCS7_free(token);
	TS_TST_INFO_free(tst_info);
	if (!ret) {
		TS_RESP_free(resp);
		resp = NULL;
	}
	TS_STATUS_INFO_free(si);
	return resp;
}
コード例 #6
0
static VALUE
ossl_pkcs7_copy(VALUE self, VALUE other)
{
    PKCS7 *a, *b, *pkcs7;

    rb_check_frozen(self);
    if (self == other) return self;

    GetPKCS7(self, a);
    SafeGetPKCS7(other, b);

    pkcs7 = PKCS7_dup(b);
    if (!pkcs7) {
	ossl_raise(ePKCS7Error, NULL);
    }
    DATA_PTR(self) = pkcs7;
    PKCS7_free(a);

    return self;
}
コード例 #7
0
ファイル: pkcs7.c プロジェクト: chk-jxcn/lua-openssl
static LUA_FUNCTION(openssl_pkcs7_new)
{
  int type = luaL_optint(L, 1, NID_pkcs7_signed);
  int content_nid = luaL_optint(L, 1, NID_pkcs7_data);

  PKCS7 *p7 = PKCS7_new();
  if (p7)
  {
    int ret = 1;
    ret = PKCS7_set_type(p7, type);
    if (ret)
      ret = PKCS7_content_new(p7, content_nid);
    if (ret)
    {
      PUSH_OBJECT(p7, "openssl.pkcs7");
      return 1;
    }
    else
      PKCS7_free(p7);
  }
  return 0;
}
コード例 #8
0
ファイル: openssl_base.c プロジェクト: beike2020/source
void openssl_pkcs7_msg()
{
	int len;
	FILE *fp;
	PKCS7 *p7;
	unsigned char *der, *p, buf[SHA_DIGEST_LENGTH] = "pkcs7 msg";

	p7 = PKCS7_new();
	PKCS7_set_type(p7, NID_pkcs7_data);
	ASN1_OCTET_STRING_set(p7->d.data, buf, SHA_DIGEST_LENGTH);

	len = i2d_PKCS7(p7, NULL);
	der = (unsigned char *)malloc(len);
	p = der;
	len = i2d_PKCS7(p7, &p);
	fp = fopen("/tmp/test.cer", "wb");
	fwrite(der, 1, len, fp);
	fclose(fp);
	free(der);

	PKCS7_free(p7);
}
コード例 #9
0
ファイル: utils.c プロジェクト: Globik/meshcentwebrtc
// Sign this block of data, the first 32 bytes of the block must be avaialble to add the certificate hash.
int __fastcall util_sign(struct util_cert cert, char* data, int datalen, char** signature)
{
	int size = 0;
	unsigned int hashsize = UTIL_HASHSIZE;
	BIO *in = NULL;
	PKCS7 *message = NULL;
	*signature = NULL;
	if (datalen <= UTIL_HASHSIZE) return 0;

	// Add hash of the certificate to start of data
	X509_digest(cert.x509, EVP_sha256(), (unsigned char*)data, &hashsize);

	// Sign the block
	in = BIO_new_mem_buf(data, datalen);
	message = PKCS7_sign(cert.x509, cert.pkey, NULL, in, PKCS7_BINARY);
	if (message == NULL) goto error;
	size = i2d_PKCS7(message, (unsigned char**)signature);
	
error:
	if (message != NULL) PKCS7_free(message);
	if (in != NULL) BIO_free(in);
	return size;
}
コード例 #10
0
ファイル: eac_ca.c プロジェクト: RushOnline/openpace
int
EAC_CTX_init_ef_cardsecurity(const unsigned char *ef_cardsecurity,
            size_t ef_cardsecurity_len, EAC_CTX *ctx)
{
	PKCS7 *p7 = NULL, *signed_data;
    ASN1_OCTET_STRING *os;
    int r = 0;

    check(ef_cardsecurity, "Invalid arguments");

    if (!d2i_PKCS7(&p7, &ef_cardsecurity, ef_cardsecurity_len)
            || !PKCS7_type_is_signed(p7))
        goto err;

    if (ctx && ctx->ca_ctx &&
            !(ctx->ca_ctx->flags & CA_FLAG_DISABLE_PASSIVE_AUTH))
        check((CA_passive_authentication(ctx, p7) == 1),
                "Failed to perform passive authentication");

    signed_data = p7->d.sign->contents;
    if (OBJ_obj2nid(signed_data->type) != NID_id_SecurityObject
            || ASN1_TYPE_get(signed_data->d.other) != V_ASN1_OCTET_STRING)
        goto err;
    os = signed_data->d.other->value.octet_string;

    if (!EAC_CTX_init_ef_cardaccess(os->data, os->length, ctx)
            || !ctx || !ctx->ca_ctx || !ctx->ca_ctx->ka_ctx)
        goto err;

    r = 1;

err:
    if (p7)
        PKCS7_free(p7);

    return r;
}
コード例 #11
0
ファイル: utils.c プロジェクト: Globik/meshcentwebrtc
// Encrypt a block of data for a target certificate
int __fastcall util_encrypt(struct util_cert cert, char* data, int datalen, char** encdata)
{
	int size = 0;
	BIO *in = NULL;
	PKCS7 *message = NULL;
	STACK_OF(X509) *encerts = NULL;
	*encdata = NULL;
	if (datalen == 0) return 0;

	// Setup certificates
	encerts = sk_X509_new_null();
	sk_X509_push(encerts, cert.x509);

	// Encrypt the block
	*encdata = NULL;
	in = BIO_new_mem_buf(data, datalen);
	message = PKCS7_encrypt(encerts, in, EVP_aes_128_cbc(), PKCS7_BINARY);
	if (message == NULL) return 0;
	size = i2d_PKCS7(message, (unsigned char**)encdata);
	BIO_free(in);
	PKCS7_free(message);
	sk_X509_free(encerts);
	return size;
}
コード例 #12
0
ファイル: certificate.cpp プロジェクト: 151706061/DVTK-1
DVT_STATUS CERTIFICATE_FILE_CLASS::importPkcs7(const char* filename, bool, const char*)

//  DESCRIPTION     : Import certificates from a PKCS#7 formated file.
//  PRECONDITIONS   :
//  POSTCONDITIONS  :
//  EXCEPTIONS      : 
//  NOTES           : Returns MSG_OK, MSG_ERROR, MSG_FILE_NOT_EXIST, MSG_NO_VALUE, MSG_INVALID_PASSWORD
//<<===========================================================================
{
	DVT_STATUS status = MSG_ERROR;
	BIO* bio_ptr;
	unsigned long err;
	PKCS7 *p7_ptr = NULL;
	STACK_OF(X509) *certStack_ptr = NULL;
	int count = 0;


	// clear the error queue
	ERR_clear_error();

	// open the file
	bio_ptr = BIO_new(BIO_s_file_internal());
	if (bio_ptr == NULL)
	{
		openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "setting up to read PKCS #7 file");
		status = MSG_ERROR;
		goto end;
	}
	if (BIO_read_filename(bio_ptr, filename) <= 0)
	{
		err = ERR_peek_error();
		if ((ERR_GET_LIB(err) == ERR_LIB_SYS) && (ERR_GET_REASON(err) == ERROR_FILE_NOT_FOUND))
		{
			// file does not exist
			ERR_clear_error(); // eat any errors
			status = MSG_FILE_NOT_EXIST;
		}
		else
		{
			openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "opening PKCS #7 file for reading");
			status = MSG_ERROR;
		}
		goto end;
	}

	// try reading the file as a PEM file
	p7_ptr = PEM_read_bio_PKCS7(bio_ptr, NULL, NULL, NULL);

	if (p7_ptr == NULL)
	{
		err = ERR_peek_error();
		if ((ERR_GET_LIB(err) == ERR_LIB_PEM) && (ERR_GET_REASON(err) == PEM_R_NO_START_LINE))
		{
			// no PEM start line
			ERR_clear_error(); // eat any errors
			BIO_reset(bio_ptr); // reset the file to the beginning

			// try reading the file as DER
			p7_ptr = d2i_PKCS7_bio(bio_ptr, NULL);
		}
	}

	if (p7_ptr == NULL)
	{
		openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "reading PKCS #7 file");
		status = MSG_ERROR;
	}
	else
	{
		// get the certificates from the p7 structure
		int p7Type = OBJ_obj2nid(p7_ptr->type);
		switch (p7Type)
		{
		case NID_pkcs7_signed:
			certStack_ptr = p7_ptr->d.sign->cert;
			break;
		case NID_pkcs7_signedAndEnveloped:
			certStack_ptr = p7_ptr->d.signed_and_enveloped->cert;
			break;
		default:
			openSslM_ptr->printError(loggerM_ptr, LOG_ERROR, "unsupported PKCS #7 file type");
			status = MSG_ERROR;
			goto end;
		}


		if ((certStack_ptr != NULL) && (sk_X509_num(certStack_ptr) > 0))
		{
			X509* x509_ptr;

			// save each of the certificates
			while ((x509_ptr = sk_X509_shift(certStack_ptr)) != NULL)
			{
				if (!push(x509_ptr))
				{
					status = MSG_ERROR;
					goto end;
				}
				count++;
			}
		}

		if (count == 0)
		{
			status = MSG_NO_VALUE;
		}
		else
		{
			status = MSG_OK;
		}
	}

end:
	//	certStack_ptr freed by the PKCS7_free() below
	if (p7_ptr != NULL) PKCS7_free(p7_ptr);
	if (bio_ptr != NULL) BIO_free(bio_ptr);

	return status;
}
コード例 #13
0
ファイル: est.c プロジェクト: janetuk/mech_eap
static int pkcs7_to_cert(struct hs20_osu_client *ctx, const u8 *pkcs7,
			 size_t len, char *pem_file, char *der_file)
{
#ifdef OPENSSL_IS_BORINGSSL
	CBS pkcs7_cbs;
#else /* OPENSSL_IS_BORINGSSL */
	PKCS7 *p7 = NULL;
	const unsigned char *p = pkcs7;
#endif /* OPENSSL_IS_BORINGSSL */
	STACK_OF(X509) *certs;
	int i, num, ret = -1;
	BIO *out = NULL;

#ifdef OPENSSL_IS_BORINGSSL
	certs = sk_X509_new_null();
	if (!certs)
		goto fail;
	CBS_init(&pkcs7_cbs, pkcs7, len);
	if (!PKCS7_get_certificates(certs, &pkcs7_cbs)) {
		wpa_printf(MSG_INFO, "Could not parse PKCS#7 object: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		write_result(ctx, "Could not parse PKCS#7 object from EST");
		goto fail;
	}
#else /* OPENSSL_IS_BORINGSSL */
	p7 = d2i_PKCS7(NULL, &p, len);
	if (p7 == NULL) {
		wpa_printf(MSG_INFO, "Could not parse PKCS#7 object: %s",
			   ERR_error_string(ERR_get_error(), NULL));
		write_result(ctx, "Could not parse PKCS#7 object from EST");
		goto fail;
	}

	switch (OBJ_obj2nid(p7->type)) {
	case NID_pkcs7_signed:
		certs = p7->d.sign->cert;
		break;
	case NID_pkcs7_signedAndEnveloped:
		certs = p7->d.signed_and_enveloped->cert;
		break;
	default:
		certs = NULL;
		break;
	}
#endif /* OPENSSL_IS_BORINGSSL */

	if (!certs || ((num = sk_X509_num(certs)) == 0)) {
		wpa_printf(MSG_INFO, "No certificates found in PKCS#7 object");
		write_result(ctx, "No certificates found in PKCS#7 object");
		goto fail;
	}

	if (der_file) {
		FILE *f = fopen(der_file, "wb");
		if (f == NULL)
			goto fail;
		i2d_X509_fp(f, sk_X509_value(certs, 0));
		fclose(f);
	}

	if (pem_file) {
		out = BIO_new(BIO_s_file());
		if (out == NULL ||
		    BIO_write_filename(out, pem_file) <= 0)
			goto fail;

		for (i = 0; i < num; i++) {
			X509 *cert = sk_X509_value(certs, i);
			X509_print(out, cert);
			PEM_write_bio_X509(out, cert);
			BIO_puts(out, "\n");
		}
	}

	ret = 0;

fail:
#ifdef OPENSSL_IS_BORINGSSL
	if (certs)
		sk_X509_pop_free(certs, X509_free);
#else /* OPENSSL_IS_BORINGSSL */
	PKCS7_free(p7);
#endif /* OPENSSL_IS_BORINGSSL */
	if (out)
		BIO_free_all(out);

	return ret;
}
コード例 #14
0
ファイル: cert_scep.c プロジェクト: millken/zhuxianB30
/*******************************************************************************
函数名称: cert_pkcs7_unwrap
功能描述: 解析从服务器收到的信息,包括验证签名以及解密。
输入参数: struct scep *s, SCEP操作的结构体指针。

输出参数: 无
返 回 值: 1,成功;-1,失败
--------------------------------------------------------------------------------
最近一次修改记录:
修改作者:王朝
修改目的:添加新函数
修改日期:2009年12月28日
*********************************************************************************/
s32 cert_pkcs7_unwrap(struct scep *s)
{
	BIO	*memorybio = NULL;
	BIO	*outbio = NULL;
	BIO	*pkcs7bio = NULL;
	s32	bytes, used, retval = -1;
	STACK_OF(PKCS7_SIGNER_INFO)	*sk = NULL;
	PKCS7 *p7enc = NULL;
	PKCS7_SIGNER_INFO *si = NULL;
	STACK_OF(X509_ATTRIBUTE) *attribs = NULL;
	s8 *p = NULL;
	u8 buffer[1024];
	X509 *recipientcert = NULL;
	EVP_PKEY *recipientkey = NULL;


	/* Create new memory BIO for outer PKCS#7 */
	memorybio = BIO_new(BIO_s_mem());

	/* Read in data */
	if ((BIO_write(memorybio, s->reply_payload, s->reply_len)) <= 0)
    {
        goto end;
	}

	BIO_set_flags(memorybio, BIO_FLAGS_MEM_RDONLY);
	s->reply_p7 = d2i_PKCS7_bio(memorybio, NULL);

    BIO_free(memorybio);
    memorybio = NULL;

	 /* Make sure this is a signed PKCS#7 */
    if (!PKCS7_type_is_signed(s->reply_p7))
    {
        goto end;
    }

	/* Create BIO for content data */
	pkcs7bio = PKCS7_dataInit(s->reply_p7, NULL);
	if (pkcs7bio == NULL)
    {
        goto end;
	}

	/* */
	outbio = BIO_new(BIO_s_mem());
	used = 0;
	for (;;)
    {
		bytes = BIO_read(pkcs7bio, buffer, sizeof(buffer));
		used += bytes;
		if (bytes <= 0) break;
		BIO_write(outbio, buffer, bytes);
	}
	(void)BIO_flush(outbio);

	/* Get signer */
	sk = PKCS7_get_signer_info(s->reply_p7);
	if (sk == NULL)
    {
        goto end;
	}

	/* Verify signature */
	si = sk_PKCS7_SIGNER_INFO_value(sk, 0);

	if (PKCS7_signatureVerify(pkcs7bio, s->reply_p7, si, cert_cacert) <= 0)
    {
        goto end;
	}

	/* Get signed attributes */
	attribs = PKCS7_get_signed_attributes(si);
	if (attribs == NULL)
    {
        goto end;
	}

	/* Transaction id */
	if (1 != cert_get_signed_attribute(attribs, nid_transId,	V_ASN1_PRINTABLESTRING, &p))
    {
        goto end;
	}

	if (strncmp(s->transaction_id, p, strlen(p)))
    {
        goto end;
	}
	/* Message type, should be of type CertRep */
	if (1 != cert_get_signed_attribute(attribs, nid_messageType,	V_ASN1_PRINTABLESTRING, &p))
    {
        goto end;
	}
	if (atoi(p) != 3)
    {
        goto end;
	}

	/* Sender and recipient nonces: */
	if (1 == cert_get_signed_attribute(attribs, nid_senderNonce,	V_ASN1_OCTET_STRING, &p))
    {
		s->reply_sender_nonce = (u8 *)p;
	}
    else
    {
	    s->reply_sender_nonce = NULL;
    }
    
	if ( 1 != cert_get_signed_attribute(attribs, nid_recipientNonce,V_ASN1_OCTET_STRING, &p))
    {
		goto end;
	}
	s->reply_recipient_nonce = (u8 *)p;

	/* Get pkiStatus */
	if (1 != cert_get_signed_attribute(attribs, nid_pkiStatus,V_ASN1_PRINTABLESTRING, &p))
    {
		goto end;
	}
	switch (atoi(p))
    {
		case SCEP_PKISTATUS_SUCCESS:
			s->pki_status = SCEP_PKISTATUS_SUCCESS;
			break;
		case SCEP_PKISTATUS_FAILURE:
			s->pki_status = SCEP_PKISTATUS_FAILURE;
			break;
		case SCEP_PKISTATUS_PENDING:
			s->pki_status = SCEP_PKISTATUS_PENDING;
			break;
		default:
			goto end;
	}

	/* Get failInfo */
	if (s->pki_status == SCEP_PKISTATUS_FAILURE)
    {
		if (1 != cert_get_signed_attribute(attribs, nid_failInfo,V_ASN1_PRINTABLESTRING, &p)) 
        {
            goto end;
		}
		switch (atoi(p))
        {
			case SCEP_FAILINFO_BADALG:
				s->fail_info = SCEP_FAILINFO_BADALG;
				break;
			case SCEP_FAILINFO_BADMSGCHK:
				s->fail_info = SCEP_FAILINFO_BADMSGCHK;
				break;
			case SCEP_FAILINFO_BADREQ:
				s->fail_info = SCEP_FAILINFO_BADREQ;
				break;
			case SCEP_FAILINFO_BADTIME:
				s->fail_info = SCEP_FAILINFO_BADTIME;
				break;
			case SCEP_FAILINFO_BADCERTID:
				s->fail_info = SCEP_FAILINFO_BADCERTID;
				break;
			default:
				goto end;
		}
	}
	/* If FAILURE or PENDING, we can return */
	if (s->pki_status != SCEP_PKISTATUS_SUCCESS)
    {
		/* There shouldn't be any more data... */
		retval = 1;
        goto end;
	}
	/* We got success and expect data */
	if (used == 0)
    {
		goto end;
	}

	/* Decrypt the inner PKCS#7 */
	if ((s->request_type == SCEP_REQUEST_PKCSREQ) || (s->request_type == SCEP_REQUEST_GETCERTINIT))
    {
		recipientcert = s->signercert;
		recipientkey = s->signerkey;
	}
	else
    {
		recipientcert = cert_localcert;
		recipientkey = cert_rsa;
	}

	p7enc = d2i_PKCS7_bio(outbio, NULL);
	if (p7enc == NULL)
    {
		goto end;
	}

    BIO_free(outbio);
    outbio = NULL;

	/* Decrypt the data  */
	outbio = BIO_new(BIO_s_mem());
	if (PKCS7_decrypt(p7enc, recipientkey, recipientcert, outbio, 0) == 0)
    {
		goto end;
	}
	(void)BIO_flush(outbio);

	/* Write decrypted data */
	s->reply_len = BIO_get_mem_data(outbio, &s->reply_payload);

	BIO_set_flags(outbio, BIO_FLAGS_MEM_RDONLY);
	s->reply_p7 = d2i_PKCS7_bio(outbio, NULL);

    retval = 1;
end:
    if(NULL != outbio)
    {
        BIO_free(outbio);
    }

    if(NULL != memorybio)
    {
        BIO_free(memorybio);
    }

    if(NULL != pkcs7bio)
    {
        BIO_free(pkcs7bio);
    }

    if(NULL != p7enc)
    {
        PKCS7_free(p7enc);
    }

    return retval;
}
コード例 #15
0
ファイル: pesec.c プロジェクト: diogoleal/pev
static int parse_pkcs7_data(const options_t *options, const CRYPT_DATA_BLOB *blob)
{
	int result = 0;
	const cert_format_e input_fmt = CERT_FORMAT_DER;
	PKCS7 *p7 = NULL;
	BIO *in = NULL;

	CRYPTO_malloc_init();
	ERR_load_crypto_strings();
	OpenSSL_add_all_algorithms();

	in = BIO_new_mem_buf(blob->pbData, blob->cbData);
	if (in == NULL) {
		result = -2;
		goto error;
	}

	switch (input_fmt) {
		default: EXIT_ERROR("unhandled input format for certificate");
		case CERT_FORMAT_DER:
			p7 = d2i_PKCS7_bio(in, NULL);
			break;
		case CERT_FORMAT_PEM:
			p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
			break;
	}
	if (p7 == NULL) {
		ERR_print_errors_fp(stderr);
		result = -3;
		goto error;
	}

	STACK_OF(X509) *certs = NULL;

	int type = OBJ_obj2nid(p7->type);
	switch (type) {
		default: break;
		case NID_pkcs7_signed: // PKCS7_type_is_signed(p7)
			certs = p7->d.sign->cert;
			break;
		case NID_pkcs7_signedAndEnveloped: // PKCS7_type_is_signedAndEnveloped(p7)
			certs = p7->d.signed_and_enveloped->cert;
			break;
	}

	const int numcerts = certs != NULL ? sk_X509_num(certs) : 0;
	for (int i = 0; i < numcerts; i++) {
		X509 *cert = sk_X509_value(certs, i);
		print_certificate(options->certout, options->certoutform, cert);
		// NOTE: Calling X509_free(cert) is unnecessary.
	}

	// Print whether certificate signature is valid
	if (numcerts > 0) {
		X509 *subject = sk_X509_value(certs, 0);
		X509 *issuer = sk_X509_value(certs, numcerts - 1);
		int valid_sig = X509_verify(subject, X509_get_pubkey(issuer));
		output("Signature", valid_sig == 1 ? "valid" : "invalid");
	}

	// Print signers
	if (numcerts > 0) {
		output_open_scope("signers", OUTPUT_SCOPE_TYPE_ARRAY);
		for (int i = 0; i < numcerts; i++) {
			X509 *cert = sk_X509_value(certs, i);
			X509_NAME *name = X509_get_subject_name(cert);

			int issuer_name_len = X509_NAME_get_text_by_NID(name, NID_commonName, NULL, 0);
			if (issuer_name_len > 0) {
				output_open_scope("signer", OUTPUT_SCOPE_TYPE_OBJECT);
				char issuer_name[issuer_name_len + 1];
				X509_NAME_get_text_by_NID(name, NID_commonName, issuer_name, issuer_name_len + 1);
				output("Issuer", issuer_name);
				output_close_scope(); // signer
			}
		}
		output_close_scope(); // signers
	}

error:
	if (p7 != NULL)
		PKCS7_free(p7);
	if (in != NULL)
		BIO_free(in);

	// Deallocate everything from OpenSSL_add_all_algorithms
	EVP_cleanup();
	// Deallocate everything from ERR_load_crypto_strings
	ERR_free_strings();

	return result;
}
コード例 #16
0
ファイル: smime.c プロジェクト: dgervais/openssl
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);
}
コード例 #17
0
ファイル: crl2p7.c プロジェクト: 1Project/SafeBoardMessenger
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);
}
コード例 #18
0
ファイル: pkcs7.c プロジェクト: Corvusoft/openssl-dependency
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;
}
コード例 #19
0
ファイル: smime.c プロジェクト: 321543223/kbengine
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);
}
コード例 #20
0
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;
}
コード例 #21
0
ファイル: pkcs7.c プロジェクト: vocho/qnxpkgsrcmirror
int
easy_pkcs7_sign(const char *content, size_t len,
    char **signature, size_t *signature_len,
    const char *key_file, const char *cert_file)
{
	FILE *f;
	X509 *certificate;
	STACK_OF(X509) *c, *cert_chain;
	EVP_PKEY *private_key;
	char *tmp_sig;
	BIO *out, *in;
	PKCS7 *p7;
	int status;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	status = -1;
	private_key = NULL;
	cert_chain = NULL;
	in = NULL;

	c = file_to_certs(cert_file);

	if (sk_X509_num(c) != 1) {
		warnx("More then one certificate in the certificate file");
		goto cleanup;
	}
	certificate = sk_X509_value(c, 0);

	/* Compute ex_kusage */
	X509_check_purpose(certificate, -1, 0);

	if (check_ca(certificate)) {
		warnx("CA keys are not valid for signatures");
		goto cleanup;
	}

	if (certificate->ex_xkusage != pkg_key_usage) {
		warnx("Certificate must have CODE SIGNING "
		    "and EMAIL PROTECTION property");
		goto cleanup;
	}

	if (cert_chain_file)
		cert_chain = file_to_certs(cert_chain_file);

	if ((f = fopen(key_file, "r")) == NULL) {
		warn("Failed to open private key file %s", key_file);
		goto cleanup;
	}
	private_key = PEM_read_PrivateKey(f, NULL, ssl_pass_cb, NULL);
	fclose(f);
	if (private_key == NULL) {
		warnx("Can't read private key: %s", key_file);
		goto cleanup;
	}

	if (X509_check_private_key(certificate, private_key) != 1) {
		warnx("The private key %s doesn't match the certificate %s",
		    key_file, cert_file);
		goto cleanup;
	}

	in = BIO_new_mem_buf(__UNCONST(content), len);

	p7 = PKCS7_sign(certificate, private_key, cert_chain, in, 
	    PKCS7_DETACHED|PKCS7_NOATTR|PKCS7_BINARY);
	if (p7 == NULL) {
		warnx("Failed to create signature structure");
		goto cleanup;
	}

	out = BIO_new(BIO_s_mem());
	PEM_write_bio_PKCS7(out, p7);
	*signature_len = BIO_get_mem_data(out, &tmp_sig);
	*signature = xmalloc(*signature_len);
	memcpy(*signature, tmp_sig, *signature_len);
	BIO_free_all(out);

	PKCS7_free(p7);

	status = 0;

cleanup:
	sk_X509_free(c);
	sk_X509_free(cert_chain);
	EVP_PKEY_free(private_key);
	BIO_free(in);

	return status;
}
コード例 #22
0
ファイル: pkcs7.c プロジェクト: vocho/qnxpkgsrcmirror
int
easy_pkcs7_verify(const char *content, size_t len,
    const char *signature, size_t signature_len,
    const char *anchor, int is_pkg)
{
	STACK_OF(X509) *cert_chain, *signers;
	X509_STORE *store;
	BIO *sig, *in;
	PKCS7 *p7;
	int i, status;
	X509_NAME *name;
	char *subject;

	OpenSSL_add_all_algorithms();
	ERR_load_crypto_strings();

	status = -1;

	if (cert_chain_file)
		cert_chain = file_to_certs(cert_chain_file);
	else
		cert_chain = NULL;

	store = X509_STORE_new();
	if (store == NULL) {
		sk_X509_free(cert_chain);
		warnx("Failed to create certificate store");
		return -1;
	}

	X509_STORE_load_locations(store, anchor, NULL);

	in = BIO_new_mem_buf(__UNCONST(content), len);
	sig = BIO_new_mem_buf(__UNCONST(signature), signature_len);
	signers = NULL;

	p7 = PEM_read_bio_PKCS7(sig, NULL, NULL, NULL);
	if (p7 == NULL) {
		warnx("Failed to parse the signature");
		goto cleanup;
	}

	if (PKCS7_verify(p7, cert_chain, store, in, NULL, 0) != 1) {
		warnx("Failed to verify signature");
		goto cleanup;
	}

	signers = PKCS7_get0_signers(p7, NULL, 0);
	if (signers == NULL) {
		warnx("Failed to get signers");
		goto cleanup;
	}
    
	if (sk_X509_num(signers) == 0) {
		warnx("No signers found");
		goto cleanup;
	}

	for (i = 0; i < sk_X509_num(signers); i++) {
		/* Compute ex_xkusage */
		X509_check_purpose(sk_X509_value(signers, i), -1, -1);

		if (check_ca(sk_X509_value(signers, i))) {
			warnx("CA keys are not valid for signatures");
			goto cleanup;
		}
		if (is_pkg) {
			if (sk_X509_value(signers, i)->ex_xkusage != pkg_key_usage) {
				warnx("Certificate must have CODE SIGNING "
				    "and EMAIL PROTECTION property");
				goto cleanup;
			}
		} else {
			if (sk_X509_value(signers, i)->ex_xkusage != 0) {
				warnx("Certificate must not have any property");
				goto cleanup;
			}
		}
	}

	printf("Sigature ok, signed by:\n");

	for (i = 0; i < sk_X509_num(signers); i++) {
		name = X509_get_subject_name(sk_X509_value(signers, i));
		subject = X509_NAME_oneline(name, NULL, 0);

		printf("\t%s\n", subject);

		OPENSSL_free(subject);
	}

	status = 0;

cleanup:
	sk_X509_free(cert_chain);
	sk_X509_free(signers);
	X509_STORE_free(store);

	PKCS7_free(p7);
	BIO_free(in);
	BIO_free(sig);

	return status;
}
コード例 #23
0
ファイル: crl2p7.c プロジェクト: AimaTeam-hehai/openssl
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);
}
コード例 #24
0
ファイル: smsign.c プロジェクト: dlabs/openssl
int main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL, *tbio = NULL;
    X509 *scert = NULL;
    EVP_PKEY *skey = NULL;
    PKCS7 *p7 = NULL;
    int ret = 1;

    /*
     * For simple S/MIME signing use PKCS7_DETACHED. On OpenSSL 0.9.9 only:
     * for streaming detached set PKCS7_DETACHED|PKCS7_STREAM for streaming
     * non-detached set PKCS7_STREAM
     */
    int flags = PKCS7_DETACHED | PKCS7_STREAM;

    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    /* Read in signer certificate and private key */
    tbio = BIO_new_file("signer.pem", "r");

    if (!tbio)
        goto err;

    scert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

    BIO_reset(tbio);

    skey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

    if (!scert || !skey)
        goto err;

    /* Open content being signed */

    in = BIO_new_file("sign.txt", "r");

    if (!in)
        goto err;

    /* Sign content */
    p7 = PKCS7_sign(scert, skey, NULL, in, flags);

    if (!p7)
        goto err;

    out = BIO_new_file("smout.txt", "w");
    if (!out)
        goto err;

    if (!(flags & PKCS7_STREAM))
        BIO_reset(in);

    /* Write out S/MIME message */
    if (!SMIME_write_PKCS7(out, p7, in, flags))
        goto err;

    ret = 0;

err:

    if (ret) {
        fprintf(stderr, "Error Signing Data\n");
        ERR_print_errors_fp(stderr);
    }

    if (p7)
        PKCS7_free(p7);
    if (scert)
        X509_free(scert);
    if (skey)
        EVP_PKEY_free(skey);

    BIO_free(in);
    BIO_free(out);
    BIO_free(tbio);

    return ret;

}
コード例 #25
0
ファイル: pkgtrans.c プロジェクト: apprisi/illumos-gate
/* 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);
}
コード例 #26
0
ファイル: opkg_download.c プロジェクト: WhitePatches/snake-os
int
opkg_verify_file (char *text_file, char *sig_file)
{
#if defined HAVE_GPGME
    if (conf->check_signature == 0 )
        return 0;
    int status = -1;
    gpgme_ctx_t ctx;
    gpgme_data_t sig, text, key;
    gpgme_error_t err;
    gpgme_verify_result_t result;
    gpgme_signature_t s;
    char *trusted_path = NULL;

    gpgme_check_version (NULL);

    err = gpgme_new (&ctx);

    if (err)
	return -1;

    sprintf_alloc(&trusted_path, "%s/%s", conf->offline_root, "/etc/opkg/trusted.gpg");
    err = gpgme_data_new_from_file (&key, trusted_path, 1);
    free (trusted_path);
    if (err)
    {
      return -1;
    }
    err = gpgme_op_import (ctx, key);
    if (err)
    {
      gpgme_data_release (key);
      return -1;
    }
    gpgme_data_release (key);

    err = gpgme_data_new_from_file (&sig, sig_file, 1);
    if (err)
    {
	gpgme_release (ctx);
	return -1;
    }

    err = gpgme_data_new_from_file (&text, text_file, 1);
    if (err)
    {
        gpgme_data_release (sig);
	gpgme_release (ctx);
	return -1;
    }

    err = gpgme_op_verify (ctx, sig, text, NULL);

    result = gpgme_op_verify_result (ctx);
    if (!result)
	return -1;

    /* see if any of the signitures matched */
    s = result->signatures;
    while (s)
    {
	status = gpg_err_code (s->status);
	if (status == GPG_ERR_NO_ERROR)
	    break;
	s = s->next;
    }


    gpgme_data_release (sig);
    gpgme_data_release (text);
    gpgme_release (ctx);

    return status;
#elif defined HAVE_OPENSSL
    X509_STORE *store = NULL;
    PKCS7 *p7 = NULL;
    BIO *in = NULL, *indata = NULL;

    // Sig check failed by default !
    int status = -1;

    openssl_init();

    // Set-up the key store
    if(!(store = setup_verify(conf->signature_ca_file, conf->signature_ca_path))){
        opkg_msg(ERROR, "Can't open CA certificates.\n");
        goto verify_file_end;
    }

    // Open a BIO to read the sig file
    if (!(in = BIO_new_file(sig_file, "rb"))){
        opkg_msg(ERROR, "Can't open signature file %s.\n", sig_file);
        goto verify_file_end;
    }

    // Read the PKCS7 block contained in the sig file
    p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
    if(!p7){
        opkg_msg(ERROR, "Can't read signature file %s (Corrupted ?).\n",
		sig_file);
        goto verify_file_end;
    }
#if defined(HAVE_PATHFINDER)
    if(conf->check_x509_path){
	if(!pkcs7_pathfinder_verify_signers(p7)){
	    opkg_msg(ERROR, "pkcs7_pathfinder_verify_signers: "
		    "Path verification failed.\n");
	    goto verify_file_end;
	}
    }
#endif

    // Open the Package file to authenticate
    if (!(indata = BIO_new_file(text_file, "rb"))){
        opkg_msg(ERROR, "Can't open file %s.\n", text_file);
        goto verify_file_end;
    }

    // Let's verify the autenticity !
    if (PKCS7_verify(p7, NULL, store, indata, NULL, PKCS7_BINARY) != 1){
        // Get Off My Lawn!
        opkg_msg(ERROR, "Verification failure.\n");
    }else{
        // Victory !
        status = 0;
    }

verify_file_end:
    BIO_free(in);
    BIO_free(indata);
    PKCS7_free(p7);
    X509_STORE_free(store);

    return status;
#else
    /* mute `unused variable' warnings. */
    (void) sig_file;
    (void) text_file;
    (void) conf;
    return 0;
#endif
}
コード例 #27
0
ファイル: signature.c プロジェクト: ikeydoherty/swupd-client
/* Verifies that the file and the signature exists, and does a signature check
 * afterwards. If any error is to be considered a verify failure, then
 * ERRORS_FATAL should be set to true.
 *
 * returns: true if able to validate the signature, false otherwise */
static bool verify_signature(const char *data_filename, const char *sig_filename, bool errors_fatal)
{
	int ret;
	bool result = false;
	struct stat st;
	char *errorstr = NULL;

	int data_fd = -1;
	size_t data_len;
	unsigned char *data = NULL;
	BIO *data_BIO = NULL;

	int sig_fd = -1;
	size_t sig_len;
	unsigned char *sig = NULL;
	BIO *sig_BIO = NULL;

	PKCS7 *p7 = NULL;
	BIO *verify_BIO = NULL;

	/* get the signature */
	sig_fd = open(sig_filename, O_RDONLY);
	if (sig_fd == -1) {
		string_or_die(&errorstr, "Failed open %s: %s\n", sig_filename, strerror(errno));
		goto error;
	}
	if (fstat(sig_fd, &st) != 0) {
		string_or_die(&errorstr, "Failed to stat %s file\n", sig_filename);
		goto error;
	}
	sig_len = st.st_size;
	sig = mmap(NULL, sig_len, PROT_READ, MAP_PRIVATE, sig_fd, 0);
	if (sig == MAP_FAILED) {
		string_or_die(&errorstr, "Failed to mmap %s signature\n", sig_filename);
		goto error;
	}
	sig_BIO = BIO_new_mem_buf(sig, sig_len);
	if (!sig_BIO) {
		string_or_die(&errorstr, "Failed to read %s signature into BIO\n", sig_filename);
		goto error;
	}

	/* the signature is in DER format, so d2i it into verification pkcs7 form */
	p7 = d2i_PKCS7_bio(sig_BIO, NULL);
	if (p7 == NULL) {
		string_or_die(&errorstr, "NULL PKCS7 File\n");
		goto error;
	}

	/* get the data to be verified */
	data_fd = open(data_filename, O_RDONLY);
	if (data_fd == -1) {
		string_or_die(&errorstr, "Failed open %s\n", data_filename);
		goto error;
	}
	if (fstat(data_fd, &st) != 0) {
		string_or_die(&errorstr, "Failed to stat %s\n", data_filename);
		goto error;
	}
	data_len = st.st_size;
	data = mmap(NULL, data_len, PROT_READ, MAP_PRIVATE, data_fd, 0);
	if (data == MAP_FAILED) {
		string_or_die(&errorstr, "Failed to mmap %s\n", data_filename);
		goto error;
	}
	data_BIO = BIO_new_mem_buf(data, data_len);
	if (!data_BIO) {
		string_or_die(&errorstr, "Failed to read %s into BIO\n", data_filename);
		goto error;
	}

	/* munge the signature and data into a verifiable format */
	verify_BIO = PKCS7_dataInit(p7, data_BIO);
	if (!verify_BIO) {
		string_or_die(&errorstr, "Failed PKCS7_dataInit()\n");
		goto error;
	}

	/* Verify the signature, outdata can be NULL because we don't use it */
	ret = PKCS7_verify(p7, x509_stack, store, verify_BIO, NULL, 0);
	if (ret == 1) {
		result = true;
	} else {
		string_or_die(&errorstr, "Signature check failed!\n");
	}

error:
	if (!result && errors_fatal) {
		fputs(errorstr, stderr);
		ERR_print_errors_fp(stderr);
	}

	free(errorstr);

	if (sig) {
		munmap(sig, sig_len);
	}
	if (sig_fd >= 0) {
		close(sig_fd);
	}
	if (data) {
		munmap(data, data_len);
	}
	if (data_fd >= 0) {
		close(data_fd);
	}
	if (sig_BIO) {
		BIO_free(sig_BIO);
	}
	if (data_BIO) {
		BIO_free(data_BIO);
	}
	if (verify_BIO) {
		BIO_free(verify_BIO);
	}
	if (p7) {
		PKCS7_free(p7);
	}

	return result;
}
コード例 #28
0
ファイル: pdf-pkcs7.c プロジェクト: n1tehawk/mupdf
static int verify_sig(char *sig, int sig_len, char *file, int (*byte_range)[2], int byte_range_len, char *ebuf, int ebufsize)
{
	PKCS7 *pk7sig = NULL;
	PKCS7 *pk7cert = NULL;
	X509_STORE *st = NULL;
	BIO *bsig = NULL;
	BIO *bcert = NULL;
	BIO *bdata = NULL;
	BIO *bsegs = NULL;
	STACK_OF(X509) *certs = NULL;
	int t;
	int res = 0;

	bsig = BIO_new_mem_buf(sig, sig_len);
	pk7sig = d2i_PKCS7_bio(bsig, NULL);
	if (pk7sig == NULL)
		goto exit;

	bdata = BIO_new(BIO_s_file());
	if (bdata == NULL)
		goto exit;
	BIO_read_filename(bdata, file);

	bsegs = BIO_new(BIO_f_segments());
	if (bsegs == NULL)
		goto exit;

	bsegs->next_bio = bdata;
	BIO_set_segments(bsegs, byte_range, byte_range_len);

	/* Find the certificates in the pk7 file */
	bcert = BIO_new_mem_buf(adobe_ca, sizeof(adobe_ca));
	pk7cert = d2i_PKCS7_bio(bcert, NULL);
	if (pk7cert == NULL)
		goto exit;

	t = OBJ_obj2nid(pk7cert->type);
	switch (t)
	{
	case NID_pkcs7_signed:
		certs = pk7cert->d.sign->cert;
		break;

	case NID_pkcs7_signedAndEnveloped:
		certs = pk7cert->d.sign->cert;
		break;

	default:
		break;
	}

	st = X509_STORE_new();
	if (st == NULL)
		goto exit;

	/* Add the certificates to the store */
	if (certs != NULL)
	{
		int i, n = sk_X509_num(certs);

		for (i = 0; i < n; i++)
		{
			X509 *c = sk_X509_value(certs, i);
			X509_STORE_add_cert(st, c);
		}
	}

	res = pk7_verify(st, pk7sig, bsegs, ebuf, ebufsize);

exit:
	BIO_free(bsig);
	BIO_free(bdata);
	BIO_free(bsegs);
	BIO_free(bcert);
	PKCS7_free(pk7sig);
	PKCS7_free(pk7cert);
	X509_STORE_free(st);

	return res;
}
コード例 #29
0
ファイル: smdec.c プロジェクト: 277800076/openssl
int main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL, *tbio = NULL;
    X509 *rcert = NULL;
    EVP_PKEY *rkey = NULL;
    PKCS7 *p7 = NULL;
    int ret = 1;

    OpenSSL_add_all_algorithms();
    ERR_load_crypto_strings();

    /* Read in recipient certificate and private key */
    tbio = BIO_new_file("signer.pem", "r");

    if (!tbio)
        goto err;

    rcert = PEM_read_bio_X509(tbio, NULL, 0, NULL);

    BIO_reset(tbio);

    rkey = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);

    if (!rcert || !rkey)
        goto err;

    /* Open content being signed */

    in = BIO_new_file("smencr.txt", "r");

    if (!in)
        goto err;

    /* Sign content */
    p7 = SMIME_read_PKCS7(in, NULL);

    if (!p7)
        goto err;

    out = BIO_new_file("encrout.txt", "w");
    if (!out)
        goto err;

    /* Decrypt S/MIME message */
    if (!PKCS7_decrypt(p7, rkey, rcert, out, 0))
        goto err;

    ret = 0;

 err:
    if (ret) {
        fprintf(stderr, "Error Signing Data\n");
        ERR_print_errors_fp(stderr);
    }
    PKCS7_free(p7);
    X509_free(rcert);
    EVP_PKEY_free(rkey);
    BIO_free(in);
    BIO_free(out);
    BIO_free(tbio);

    return ret;

}
コード例 #30
0
ファイル: cert_scep.c プロジェクト: millken/zhuxianB30
/*******************************************************************************
函数名称: 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;
}