- first working version of signer plugin
git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@63 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
06fc4565ba
commit
0fbe06b8eb
|
@ -4,13 +4,14 @@ PLUGIN_DEFINES=-DXP_UNIX -I/usr/include/mozilla -I/usr/include/mozilla/java
|
|||
CC= gcc
|
||||
OPTIMIZER= -g
|
||||
CFLAGS=-Wall $(OPTIMIZER) $(PLUGIN_DEFINES)
|
||||
LDFLAGS=-lopensc -lcrypto
|
||||
|
||||
SRC= signer.c stubs.c
|
||||
OBJ= signer.o stubs.o
|
||||
SRC= signer.c stubs.c opensc-crypto.c opensc-support.c
|
||||
OBJ= signer.o stubs.o opensc-crypto.o opensc-support.o
|
||||
|
||||
SHAREDTARGET=signer.so
|
||||
|
||||
default all: $(SHAREDTARGET)
|
||||
default all: $(SHAREDTARGET) testprog
|
||||
|
||||
$(SHAREDTARGET): $(OBJ)
|
||||
$(CC) -shared -o $(SHAREDTARGET) $(OBJ) $(LDFLAGS)
|
||||
|
@ -27,3 +28,6 @@ clean:
|
|||
test:
|
||||
.do cp $(SHAREDTARGET) /usr/lib/mozilla/plugins
|
||||
.do cp $(SHAREDTARGET) /usr/lib/netscape/plugins-libc6
|
||||
|
||||
testprog: $(OBJ) testprog.o opensc-crypto.o opensc-support.o
|
||||
gcc -Wall -g -o testprog testprog.o opensc-crypto.o opensc-support.o -lopensc -lcrypto -ldl
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
|
||||
#include <opensc-pkcs15.h>
|
||||
#include <opensc.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include "opensc-crypto.h"
|
||||
|
||||
#define SC_HARDCODED_PIN "1234"
|
||||
|
||||
#define DBG(x) { x; }
|
||||
|
||||
void
|
||||
sc_close(struct sc_priv_data *priv)
|
||||
{
|
||||
if (priv->p15card) {
|
||||
sc_pkcs15_destroy(priv->p15card);
|
||||
priv->p15card = NULL;
|
||||
}
|
||||
if (priv->card) {
|
||||
sc_disconnect_card(priv->card);
|
||||
priv->card = NULL;
|
||||
}
|
||||
if (priv->ctx) {
|
||||
sc_destroy_context(priv->ctx);
|
||||
priv->ctx = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
sc_init(struct sc_priv_data *priv)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = sc_establish_context(&priv->ctx);
|
||||
if (r)
|
||||
goto err;
|
||||
r = sc_connect_card(priv->ctx, priv->reader_id, &priv->card);
|
||||
if (r)
|
||||
goto err;
|
||||
r = sc_pkcs15_init(priv->card, &priv->p15card);
|
||||
if (r)
|
||||
goto err;
|
||||
return 0;
|
||||
err:
|
||||
sc_close(priv);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int sc_private_decrypt(int flen, u_char *from, u_char *to, RSA *rsa,
|
||||
int padding)
|
||||
{
|
||||
int r;
|
||||
struct sc_priv_data *priv;
|
||||
struct sc_pkcs15_prkey_info *key;
|
||||
struct sc_pkcs15_pin_info *pin;
|
||||
|
||||
if (padding != RSA_PKCS1_PADDING)
|
||||
return -1;
|
||||
priv = (struct sc_priv_data *) RSA_get_app_data(rsa);
|
||||
if (priv == NULL)
|
||||
return -1;
|
||||
if (priv->p15card == NULL) {
|
||||
sc_close(priv);
|
||||
r = sc_init(priv);
|
||||
if (r) {
|
||||
//error("SmartCard init failed: %s", sc_strerror(r));
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
r = sc_pkcs15_find_prkey_by_id(priv->p15card, &priv->cert_id, &key);
|
||||
if (r) {
|
||||
//error("Unable to find private key from SmartCard: %s", sc_strerror(r));
|
||||
goto err;
|
||||
}
|
||||
r = sc_pkcs15_find_pin_by_auth_id(priv->p15card, &key->com_attr.auth_id, &pin);
|
||||
if (r) {
|
||||
// error("Unable to find PIN object from SmartCard: %s", sc_strerror(r));
|
||||
goto err;
|
||||
}
|
||||
r = sc_pkcs15_verify_pin(priv->p15card, pin, SC_HARDCODED_PIN,
|
||||
strlen(SC_HARDCODED_PIN));
|
||||
if (r) {
|
||||
// error("PIN code verification failed: %s", sc_strerror(r));
|
||||
goto err;
|
||||
}
|
||||
r = sc_pkcs15_decipher(priv->p15card, key, from, flen, to, flen);
|
||||
if (r < 0) {
|
||||
// error("sc_pkcs15_decipher() failed: %s", sc_strerror(r));
|
||||
goto err;
|
||||
}
|
||||
return r;
|
||||
err:
|
||||
sc_close(priv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
sc_private_encrypt(int flen, u_char *from, u_char *to, RSA *rsa, int padding)
|
||||
{
|
||||
// error("unsupported function sc_private_encrypt() called");
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
sc_sign(int type, u_char *m, unsigned int m_len,
|
||||
unsigned char *sigret, unsigned int *siglen, RSA *rsa)
|
||||
{
|
||||
int r;
|
||||
struct sc_priv_data *priv;
|
||||
struct sc_pkcs15_prkey_info *key;
|
||||
struct sc_pkcs15_pin_info *pin;
|
||||
|
||||
priv = (struct sc_priv_data *) RSA_get_app_data(rsa);
|
||||
if (priv == NULL)
|
||||
return -1;
|
||||
// debug("sc_sign() called on cert %02X: type = %d, m_len = %d",
|
||||
// priv->cert_id.value[0], type, m_len);
|
||||
DBG(printf("sc_sign() called\n"));
|
||||
if (priv->p15card == NULL) {
|
||||
sc_close(priv);
|
||||
r = sc_init(priv);
|
||||
if (r) {
|
||||
DBG(printf("SmartCard init failed: %s", sc_strerror(r)));
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
r = sc_pkcs15_find_prkey_by_id(priv->p15card, &priv->cert_id, &key);
|
||||
if (r) {
|
||||
DBG(printf("Unable to find private key from SmartCard: %s", sc_strerror(r)));
|
||||
goto err;
|
||||
}
|
||||
r = sc_pkcs15_find_pin_by_auth_id(priv->p15card, &key->com_attr.auth_id, &pin);
|
||||
if (r) {
|
||||
DBG(printf("Unable to find PIN object from SmartCard: %s", sc_strerror(r)));
|
||||
goto err;
|
||||
}
|
||||
r = sc_pkcs15_verify_pin(priv->p15card, pin, SC_HARDCODED_PIN,
|
||||
strlen(SC_HARDCODED_PIN));
|
||||
if (r) {
|
||||
DBG(printf("PIN code verification failed: %s", sc_strerror(r)));
|
||||
goto err;
|
||||
}
|
||||
r = sc_pkcs15_compute_signature(priv->p15card, key, SC_PKCS15_HASH_SHA1,
|
||||
m, m_len, sigret, RSA_size(rsa));
|
||||
if (r < 0) {
|
||||
DBG(printf("sc_pkcs15_compute_signature() failed: %s", sc_strerror(r)));
|
||||
goto err;
|
||||
}
|
||||
*siglen = r;
|
||||
return 1;
|
||||
err:
|
||||
printf("Returning with error %s\n", sc_strerror(r));
|
||||
sc_close(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (*orig_finish)(RSA *rsa) = NULL;
|
||||
|
||||
static int
|
||||
sc_finish(RSA *rsa)
|
||||
{
|
||||
struct sc_priv_data *priv;
|
||||
|
||||
DBG(printf("sc_finish() called\n"));
|
||||
priv = RSA_get_app_data(rsa);
|
||||
if (priv != NULL) {
|
||||
priv->ref_count--;
|
||||
if (priv->ref_count == 0) {
|
||||
sc_close(priv);
|
||||
free(priv);
|
||||
}
|
||||
}
|
||||
if (orig_finish)
|
||||
orig_finish(rsa);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static RSA_METHOD libsc_rsa =
|
||||
{
|
||||
"OpenSC",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
NULL,
|
||||
};
|
||||
|
||||
RSA_METHOD * sc_get_method()
|
||||
{
|
||||
RSA_METHOD *def;
|
||||
|
||||
def = RSA_get_default_method();
|
||||
|
||||
orig_finish = def->finish;
|
||||
|
||||
/* overload */
|
||||
libsc_rsa.rsa_priv_enc = sc_private_encrypt;
|
||||
libsc_rsa.rsa_priv_dec = sc_private_decrypt;
|
||||
libsc_rsa.rsa_sign = sc_sign;
|
||||
libsc_rsa.finish = sc_finish;
|
||||
|
||||
/* just use the OpenSSL version */
|
||||
libsc_rsa.rsa_pub_enc = def->rsa_pub_enc;
|
||||
libsc_rsa.rsa_pub_dec = def->rsa_pub_dec;
|
||||
libsc_rsa.rsa_mod_exp = def->rsa_mod_exp;
|
||||
libsc_rsa.bn_mod_exp = def->bn_mod_exp;
|
||||
libsc_rsa.init = def->init;
|
||||
libsc_rsa.flags = def->flags | RSA_FLAG_SIGN_VER;
|
||||
libsc_rsa.app_data = def->app_data;
|
||||
libsc_rsa.rsa_verify = def->rsa_verify;
|
||||
|
||||
return &libsc_rsa;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#ifndef _OPENSC_CRYPTO_H
|
||||
#define _OPENSC_CRYPTO_H
|
||||
|
||||
#include <opensc-pkcs15.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
struct sc_priv_data
|
||||
{
|
||||
struct sc_pkcs15_card *p15card;
|
||||
struct sc_card *card;
|
||||
struct sc_context *ctx;
|
||||
struct sc_pkcs15_id cert_id;
|
||||
int ref_count, reader_id;
|
||||
};
|
||||
|
||||
extern RSA_METHOD * sc_get_method();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,234 @@
|
|||
|
||||
#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;
|
||||
int r, i;
|
||||
X509 *x509;
|
||||
struct sc_pkcs15_id cert_id;
|
||||
u8 *p;
|
||||
|
||||
r = sc_pkcs15_enum_private_keys(inst->p15card);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return SC_ERROR_OBJECT_NOT_FOUND;
|
||||
cert_id.len = 0;
|
||||
for (i = 0; i < inst->p15card->prkey_count; i++) {
|
||||
struct sc_pkcs15_prkey_info *key = &inst->p15card->prkey_info[i];
|
||||
|
||||
// if (key->usage & SC_PKCS15_PRKEY_USAGE_NONREPUDIATION) {
|
||||
/* Use the first available non-repudiation key */
|
||||
cert_id = key->id;
|
||||
break;
|
||||
// }
|
||||
}
|
||||
if (cert_id.len == 0)
|
||||
return SC_ERROR_OBJECT_NOT_FOUND;
|
||||
r = sc_pkcs15_find_cert_by_id(inst->p15card, &cert_id, &cinfo);
|
||||
if (r)
|
||||
return r;
|
||||
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);
|
||||
if (r)
|
||||
return r;
|
||||
r = sc_connect_card(inst->ctx, 0, &inst->card);
|
||||
if (r)
|
||||
return r;
|
||||
r = sc_pkcs15_init(inst->card, &inst->p15card);
|
||||
if (r)
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void close_pkcs15(PluginInstance *inst)
|
||||
{
|
||||
if (inst->p15card) {
|
||||
sc_pkcs15_destroy(inst->p15card);
|
||||
inst->p15card = NULL;
|
||||
}
|
||||
if (inst->card) {
|
||||
sc_disconnect_card(inst->card);
|
||||
inst->card = NULL;
|
||||
}
|
||||
if (inst->ctx) {
|
||||
sc_destroy_context(inst->ctx);
|
||||
inst->ctx = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static 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 = 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 = 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 (si)
|
||||
PKCS7_SIGNER_INFO_free(si); */
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#ifndef _OPENSC_SUPPORT_H
|
||||
#define _OPENSC_SUPPORT_H
|
||||
|
||||
#include "signer.h"
|
||||
|
||||
extern int create_envelope(PluginInstance *inst, u8 **data, int *datalen);
|
||||
|
||||
#endif
|
|
@ -1,57 +1,13 @@
|
|||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
/******************************************************************************
|
||||
* Copyright (c) 1996 Netscape Communications. All rights reserved.
|
||||
******************************************************************************/
|
||||
/*
|
||||
* UnixShell.c
|
||||
*
|
||||
* Netscape Client Plugin API
|
||||
* - Function that need to be implemented by plugin developers
|
||||
*
|
||||
* This file defines a "Template" plugin that plugin developers can use
|
||||
* as the basis for a real plugin. This shell just provides empty
|
||||
* implementations of all functions that the plugin can implement
|
||||
* that will be called by Netscape (the NPP_xxx methods defined in
|
||||
* npapi.h).
|
||||
*
|
||||
* dp Suresh <dp@netscape.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "npapi.h"
|
||||
|
||||
/***********************************************************************
|
||||
* Instance state information about the plugin.
|
||||
*
|
||||
* PLUGIN DEVELOPERS:
|
||||
* Use this struct to hold per-instance information that you'll
|
||||
* need in the various functions in this file.
|
||||
***********************************************************************/
|
||||
|
||||
typedef struct _PluginInstance
|
||||
{
|
||||
int nothing;
|
||||
char *postUrl;
|
||||
char *dataToSign;
|
||||
} PluginInstance;
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
*
|
||||
* Empty implementations of plugin API functions
|
||||
*
|
||||
* PLUGIN DEVELOPERS:
|
||||
* You will need to implement these functions as required by your
|
||||
* plugin.
|
||||
*
|
||||
***********************************************************************/
|
||||
#include "signer.h"
|
||||
#include "opensc-support.h"
|
||||
|
||||
char*
|
||||
NPP_GetMIMEDescription(void)
|
||||
{
|
||||
return("text/x-text-to-sign:sample:Text to be signed");
|
||||
return("text/x-text-to-sign:sgn:Text to be signed");
|
||||
}
|
||||
|
||||
NPError
|
||||
|
@ -98,25 +54,35 @@ NPP_Shutdown(void)
|
|||
|
||||
static NPError
|
||||
post_data(NPP instance, const char *url, const char *target, uint32 len,
|
||||
const char* buf)
|
||||
const char *buf, const char *tag)
|
||||
{
|
||||
NPError rv;
|
||||
char headers[256], *sendbuf;
|
||||
int hdrlen;
|
||||
char *content;
|
||||
unsigned int content_len, hdrlen, taglen;
|
||||
|
||||
sprintf(headers, "Content-type: text/plain\r\n"
|
||||
"Content-Length: %u\r\n\r\n", (unsigned int) len);
|
||||
taglen = strlen(tag);
|
||||
content_len = taglen + len + 1;
|
||||
content = NPN_MemAlloc(content_len);
|
||||
if (content == NULL)
|
||||
return NPERR_OUT_OF_MEMORY_ERROR;
|
||||
memcpy(content, tag, taglen);
|
||||
content[taglen] = '=';
|
||||
memcpy(content+taglen+1, buf, len);
|
||||
|
||||
sprintf(headers, "Content-type: application/x-www-form-urlencoded\r\n"
|
||||
"Content-Length: %u\r\n\r\n", (unsigned int) content_len);
|
||||
hdrlen = strlen(headers);
|
||||
sendbuf = NPN_MemAlloc(hdrlen + len + 1);
|
||||
sendbuf = NPN_MemAlloc(hdrlen + content_len);
|
||||
if (sendbuf == NULL)
|
||||
return NPERR_OUT_OF_MEMORY_ERROR;
|
||||
memcpy(sendbuf, headers, hdrlen);
|
||||
memcpy(sendbuf + hdrlen, buf, len);
|
||||
sendbuf[hdrlen + len] = 0;
|
||||
memcpy(sendbuf + hdrlen, content, content_len);
|
||||
sendbuf[hdrlen + content_len] = 0;
|
||||
NPN_MemFree(content);
|
||||
printf("Sending:\n---\n%s---\n", sendbuf);
|
||||
printf("Url: '%s', target: '%s', len: %d\n", url, target, hdrlen + len);
|
||||
rv = NPN_PostURL(instance, url, target, hdrlen + len, sendbuf, FALSE);
|
||||
// NPN_MemFree(sendbuf);
|
||||
printf("Url: '%s', target: '%s', len: %ld\n", url, target, hdrlen + len);
|
||||
rv = NPN_PostURL(instance, url, target, hdrlen + content_len, sendbuf, FALSE);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -130,10 +96,11 @@ NPP_New(NPMIMEType pluginType,
|
|||
char* argv[],
|
||||
NPSavedData* saved)
|
||||
{
|
||||
PluginInstance* This;
|
||||
PluginInstance* This = NULL;
|
||||
NPError rv;
|
||||
int i;
|
||||
const char *resp = "Testing...1234567890 And testing, and testing\n";
|
||||
int r, i, datalen, b64datalen;
|
||||
u8 *data = NULL, *b64data = NULL;
|
||||
char *postUrl = NULL, *dataToSign = NULL, *fieldName = NULL;
|
||||
|
||||
printf("NPP_New()\n");
|
||||
if (instance == NULL)
|
||||
|
@ -145,24 +112,61 @@ NPP_New(NPMIMEType pluginType,
|
|||
if (This == NULL)
|
||||
return NPERR_OUT_OF_MEMORY_ERROR;
|
||||
|
||||
This->postUrl = This->dataToSign = NULL;
|
||||
This->ctx = NULL;
|
||||
This->card = NULL;
|
||||
This->p15card = NULL;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (strcmp(argn[i], "wsxaction") == 0) {
|
||||
This->postUrl = strdup(argv[i]);
|
||||
postUrl = strdup(argv[i]);
|
||||
} else if (strcmp(argn[i], "wsxdatatosign") == 0) {
|
||||
This->dataToSign = strdup(argv[i]);
|
||||
dataToSign = strdup(argv[i]);
|
||||
} else if (strcmp(argn[i], "wsxname") == 0) {
|
||||
fieldName = strdup(argv[i]);
|
||||
} else
|
||||
printf("'%s' = '%s'\n", argn[i], argv[i]);
|
||||
}
|
||||
if (This->postUrl == NULL)
|
||||
return NPERR_GENERIC_ERROR;
|
||||
printf("Posting to '%s'\n", This->postUrl);
|
||||
rv = post_data(instance, This->postUrl, "_self", strlen(resp), resp);
|
||||
printf("PostURL returned %d\n", rv);
|
||||
return NPERR_NO_ERROR;
|
||||
if (postUrl == NULL || dataToSign == NULL) {
|
||||
r = NPERR_GENERIC_ERROR;
|
||||
goto err;
|
||||
}
|
||||
if (fieldName == NULL)
|
||||
fieldName = strdup("SignedData");
|
||||
This->signdata = dataToSign;
|
||||
This->signdata_len = strlen(dataToSign);
|
||||
r = create_envelope(This, &data, &datalen);
|
||||
if (r) {
|
||||
r = NPERR_GENERIC_ERROR;
|
||||
goto err;
|
||||
}
|
||||
b64datalen = datalen * 4 / 3 + 4;
|
||||
b64data = malloc(b64datalen);
|
||||
r = sc_base64_encode(data, datalen, b64data, b64datalen, 0);
|
||||
if (r) {
|
||||
r = NPERR_GENERIC_ERROR;
|
||||
goto err;
|
||||
}
|
||||
printf("Posting to '%s'\n", postUrl);
|
||||
printf("Data to sign: %s\n", dataToSign);
|
||||
printf("Signed: %s\n", b64data);
|
||||
rv = post_data(instance, postUrl, "_self", strlen(b64data), b64data,
|
||||
fieldName);
|
||||
printf("post_data returned %d\n", rv);
|
||||
r = NPERR_NO_ERROR;
|
||||
err:
|
||||
if (fieldName)
|
||||
free(fieldName);
|
||||
if (dataToSign)
|
||||
free(dataToSign);
|
||||
if (postUrl)
|
||||
free(postUrl);
|
||||
if (data)
|
||||
free(data);
|
||||
if (b64data)
|
||||
free(b64data);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
NPError
|
||||
NPP_Destroy(NPP instance, NPSavedData** save)
|
||||
{
|
||||
|
@ -183,10 +187,6 @@ NPP_Destroy(NPP instance, NPSavedData** save)
|
|||
if (This == NULL)
|
||||
return NPERR_NO_ERROR;
|
||||
|
||||
if (This->postUrl)
|
||||
NPN_MemFree(This->postUrl);
|
||||
if (This->dataToSign)
|
||||
NPN_MemFree(This->dataToSign);
|
||||
NPN_MemFree(instance->pdata);
|
||||
instance->pdata = NULL;
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
#ifndef _SIGNER_H
|
||||
#define _SIGNER_H
|
||||
|
||||
#include <opensc.h>
|
||||
#include <opensc-pkcs15.h>
|
||||
|
||||
typedef struct _PluginInstance
|
||||
{
|
||||
char *signdata;
|
||||
int signdata_len;
|
||||
struct sc_context *ctx;
|
||||
struct sc_card *card;
|
||||
struct sc_pkcs15_card *p15card;
|
||||
} PluginInstance;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,50 @@
|
|||
#include <opensc.h>
|
||||
#include <opensc-pkcs15.h>
|
||||
#include <openssl/pkcs7.h>
|
||||
#include <string.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rsa.h>
|
||||
|
||||
#include "opensc-support.h"
|
||||
#include "opensc-crypto.h"
|
||||
#include "signer.h"
|
||||
|
||||
int test()
|
||||
{
|
||||
BIO *in;
|
||||
PKCS7 *p7;
|
||||
|
||||
in = BIO_new_file("sample.pem", "r");
|
||||
p7 = PEM_read_bio_PKCS7(in, NULL, NULL, NULL);
|
||||
if (p7 == NULL) {
|
||||
goto err;
|
||||
}
|
||||
// return prp7(p7);
|
||||
return 0;
|
||||
err:
|
||||
ERR_load_crypto_strings();
|
||||
ERR_print_errors_fp(stderr);
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
PluginInstance pl;
|
||||
u8 *data;
|
||||
int datalen, r;
|
||||
|
||||
#if 0
|
||||
test();
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
pl.signdata = strdup("12345\nMoro moro, mitä poro\nTesting 1234567890");
|
||||
pl.signdata_len = strlen(pl.signdata);
|
||||
r = create_envelope(&pl, &data, &datalen);
|
||||
if (r) {
|
||||
printf("create_env() failed\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue