⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 opensc-support.c

📁 读写Smart卡加解密接口的程序
💻 C
字号:
#include "opensc-support.h"#include "opensc-crypto.h"#include <openssl/x509.h>#include <openssl/rsa.h>#include <openssl/pkcs7.h>static int get_certificate(PluginInstance *inst,                           X509 **cert_out, struct sc_pkcs15_id *certid_out){        struct sc_pkcs15_cert *cert;        struct sc_pkcs15_cert_info *cinfo;	struct sc_pkcs15_object *objs[32], *cert_obj;        int r, i, count;        X509 *x509;        struct sc_pkcs15_id cert_id;        u8 *p;        r = sc_pkcs15_get_objects(inst->p15card, SC_PKCS15_TYPE_PRKEY_RSA, objs, 32);        if (r < 0)                return r;        if (r == 0)                return SC_ERROR_OBJECT_NOT_FOUND;        cert_id.len = 0;        count = r;        for (i = 0; i < count; i++) {                struct sc_pkcs15_prkey_info *key = (struct sc_pkcs15_prkey_info *) objs[i]->data;#if 0                if (key->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION) {#endif                        /* Use the first available non-repudiation key */                        cert_id = key->id;                        break;#if 0                }#endif        }        if (cert_id.len == 0)                return SC_ERROR_OBJECT_NOT_FOUND;        r = sc_pkcs15_find_cert_by_id(inst->p15card, &cert_id, &cert_obj);        if (r)                return r;	cinfo = (struct sc_pkcs15_cert_info *) cert_obj->data;        r = sc_pkcs15_read_certificate(inst->p15card, cinfo, &cert);        if (r)                return r;        x509 = X509_new();        p = cert->data;        if (!d2i_X509(&x509, &p, cert->data_len)) {                return -1; /* FIXME */        }        *certid_out = cinfo->id;        sc_pkcs15_free_certificate(cert);        *cert_out = x509;        return 0;}static int init_pkcs15(PluginInstance *inst){        int r;                r = sc_establish_context(&inst->ctx, "opensc-signer");        if (r)                return r;        inst->reader_id = 0;        r = sc_connect_card(inst->ctx->reader[inst->reader_id], 0, &inst->card);        if (r)                return r;        r = sc_pkcs15_bind(inst->card, &inst->p15card);        if (r)                return r;        return 0;}#if 0static void close_pkcs15(PluginInstance *inst){        if (inst->p15card) {                sc_pkcs15_unbind(inst->p15card);                inst->p15card = NULL;        }        if (inst->card) {                sc_disconnect_card(inst->card, 0);                inst->card = NULL;        }        if (inst->ctx) {                sc_release_context(inst->ctx);                inst->ctx = NULL;        }}#endifstatic int extract_certificate_and_pkey(PluginInstance *inst,					X509 **x509_out,					EVP_PKEY **pkey_out){	int r;	X509 *x509 = NULL;	struct sc_pkcs15_id cert_id;	struct sc_priv_data *priv = NULL;        EVP_PKEY *pkey = NULL;        RSA *rsa = NULL;	        r = init_pkcs15(inst);        if (r)                goto err;        r = get_certificate(inst, &x509, &cert_id);        if (r)                goto err;	r = -1;        pkey = X509_get_pubkey(x509);        if (pkey == NULL)        	goto err;        if (pkey->type != EVP_PKEY_RSA)        	goto err;	rsa = EVP_PKEY_get1_RSA(pkey); /* increases ref count */	if (rsa == NULL)		goto err;	rsa->flags |= RSA_FLAG_SIGN_VER;	RSA_set_method(rsa, sc_get_method());	priv = (struct sc_priv_data *) malloc(sizeof(*priv));	if (priv == NULL)		goto err;	memset(priv, 0, sizeof(struct sc_priv_data));	priv->cert_id = cert_id;	priv->ref_count = 1;	RSA_set_app_data(rsa, priv);	RSA_free(rsa);		/* decreases ref count */		*x509_out = x509;	*pkey_out = pkey;	return 0;err:	if (pkey)		EVP_PKEY_free(pkey);	if (x509)		X509_free(x509);	return -1;	}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 buf[1024];		int i = BIO_read(in, buf, sizeof(buf));		if (i <= 0)			break;		BIO_write(p7bio, buf, 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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -