diff --git a/src/libp11/Makefile.am b/src/libp11/Makefile.am index a642f007..f7d79e16 100644 --- a/src/libp11/Makefile.am +++ b/src/libp11/Makefile.am @@ -12,7 +12,7 @@ lib_LTLIBRARIES = libp11.la libp11_la_SOURCES = p11_attr.c p11_cert.c p11_err.c p11_key.c \ p11_load.c p11_misc.c p11_rsa.c p11_slot.c p11_ops.c -libp11_la_CFLAGS = -I$(srcdir) +libp11_la_CFLAGS = -I$(srcdir) -I$(srcdir)/../pkcs11 libp11_la_LDFLAGS = -version-info @OPENSC_LT_CURRENT@:@OPENSC_LT_REVISION@:@OPENSC_LT_AGE@ libp11_la_LIBADD = @LIBSCCONF@ ../pkcs11/libpkcs11.la @LIBDL@ @LIBCRYPTO@ diff --git a/src/libp11/libp11-int.h b/src/libp11/libp11-int.h index f52e7e50..8853b501 100644 --- a/src/libp11/libp11-int.h +++ b/src/libp11/libp11-int.h @@ -61,14 +61,24 @@ #include #include #include -#include + +#ifndef _WIN32 +#include +#include +#else +#include +#pragma pack(push, cryptoki, 1) +#include +#pragma pack(pop, cryptoki) +#endif + +#include + +extern void *C_LoadModule(const char *name, CK_FUNCTION_LIST_PTR_PTR); +extern CK_RV C_UnloadModule(void *module); #include -#ifdef __cplusplus -extern "C" { -#endif - /* get private implementations of PKCS11 structures */ /* @@ -106,9 +116,9 @@ typedef struct pkcs11_token_private { #define TOKEN2CTX(token) SLOT2CTX(TOKEN2SLOT(token)) typedef struct pkcs11_key_ops { - int type; /* EVP_PKEY_xxx */ - int (*get_public) (PKCS11_KEY *, EVP_PKEY *); - int (*get_private) (PKCS11_KEY *, EVP_PKEY *); + int type; /* EVP_PKEY_xxx */ + int (*get_public) (PKCS11_KEY *, EVP_PKEY *); + int (*get_private) (PKCS11_KEY *, EVP_PKEY *); } PKCS11_KEY_ops; typedef struct pkcs11_key_private { @@ -174,6 +184,12 @@ extern int pkcs11_getattr_var(PKCS11_TOKEN *, CK_OBJECT_HANDLE, extern int pkcs11_getattr_bn(PKCS11_TOKEN *, CK_OBJECT_HANDLE, unsigned int, BIGNUM **); +#define key_getattr(key, t, p, s) \ + pkcs11_getattr(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s)) + +#define key_getattr_bn(key, t, bn) \ + pkcs11_getattr_bn(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (bn)) + typedef int (*pkcs11_i2d_fn) (void *, unsigned char **); extern void pkcs11_addattr(CK_ATTRIBUTE_PTR, int, const void *, size_t); extern void pkcs11_addattr_int(CK_ATTRIBUTE_PTR, int, unsigned long); @@ -186,7 +202,15 @@ extern void *memdup(const void *, size_t); extern PKCS11_KEY_ops pkcs11_rsa_ops; -#ifdef __cplusplus -} -#endif +extern int pkcs11_find_key(PKCS11_CTX * ctx, PKCS11_KEY **key, + char* passphrase, char* s_slot_key_id, int verbose); +extern int pkcs11_sign(int type, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, const PKCS11_KEY * key); +extern int pkcs11_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, const PKCS11_KEY * rsa, int padding); +extern int pkcs11_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, PKCS11_KEY * key, int padding); +extern int pkcs11_verify(int type, const unsigned char *m, unsigned int m_len, + unsigned char *signature, unsigned int siglen, PKCS11_KEY * key); + #endif diff --git a/src/libp11/libp11.h b/src/libp11/libp11.h index 6893b27f..45740cb3 100644 --- a/src/libp11/libp11.h +++ b/src/libp11/libp11.h @@ -61,7 +61,6 @@ #include #include #include -#include #ifdef __cplusplus extern "C" { @@ -154,8 +153,15 @@ extern int PKCS11_enumerate_keys(PKCS11_TOKEN *, PKCS11_KEY **, unsigned int *); /* Get the key type (as EVP_PKEY_XXX) */ extern int PKCS11_get_key_type(PKCS11_KEY *); +/* Get size of key modulus in number of bytes */ +extern int PKCS11_get_key_size(PKCS11_KEY *); +/* Get actual modules and public exponent as BIGNUM */ +extern int PKCS11_get_key_modulus(PKCS11_KEY *, BIGNUM **); +extern int PKCS11_get_key_exponent(PKCS11_KEY *, BIGNUM **); + /* Get the enveloped private key */ extern EVP_PKEY *PKCS11_get_private_key(PKCS11_KEY *); +extern EVP_PKEY *PKCS11_get_public_key(PKCS11_KEY *); /* Find the corresponding certificate (if any) */ extern PKCS11_CERT *PKCS11_find_certificate(PKCS11_KEY *); diff --git a/src/libp11/p11_rsa.c b/src/libp11/p11_rsa.c index 5b728f46..823601c5 100644 --- a/src/libp11/p11_rsa.c +++ b/src/libp11/p11_rsa.c @@ -69,11 +69,6 @@ static int pkcs11_get_rsa_public(PKCS11_KEY *, EVP_PKEY *); static int pkcs11_get_rsa_private(PKCS11_KEY *, EVP_PKEY *); RSA_METHOD *pkcs11_get_rsa_method(void); -#define key_getattr(key, t, p, s) \ - pkcs11_getattr(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (p), (s)) - -#define key_getattr_bn(key, t, bn) \ - pkcs11_getattr_bn(KEY2TOKEN((key)), PRIVKEY((key))->object, (t), (bn)) /* * Get RSA key material @@ -123,130 +118,32 @@ int pkcs11_get_rsa_public(PKCS11_KEY * key, EVP_PKEY * pk) { /* TBD */ return 0; +/* return pkcs11_get_rsa_private(key,pk);*/ } + static int pkcs11_rsa_decrypt(int flen, const unsigned char *from, unsigned char *to, RSA * rsa, int padding) { - CK_RV rv; - PKCS11_KEY *key = (PKCS11_KEY *) RSA_get_app_data(rsa); - PKCS11_KEY_private *priv; - PKCS11_SLOT *slot; - PKCS11_CTX *ctx; - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - CK_ULONG size; - - if (padding != RSA_PKCS1_PADDING) { - fprintf(stderr, "pkcs11 engine: only RSA_PKCS1_PADDING allowed so far\n"); - return -1; - } - if (key == NULL) - return -1; - /* PKCS11 calls go here */ - - ctx = KEY2CTX(key); - priv = PRIVKEY(key); - slot = TOKEN2SLOT(priv->parent); - session = PRIVSLOT(slot)->session; - memset(&mechanism, 0, sizeof(mechanism)); - mechanism.mechanism = CKM_RSA_PKCS; - - if( (rv = CRYPTOKI_call(ctx, C_DecryptInit(session, &mechanism, priv->object))) == 0) { - rv = CRYPTOKI_call(ctx, C_Decrypt - (session, (CK_BYTE *) from, (CK_ULONG)flen, - (CK_BYTE_PTR)to, &size)); - } - - if (rv) { - PKCS11err(PKCS11_F_PKCS11_RSA_DECRYPT, pkcs11_map_err(rv)); - } - return (rv) ? 0 : size; + return pkcs11_private_decrypt( flen, from, to, (PKCS11_KEY *) RSA_get_app_data(rsa), padding); } static int pkcs11_rsa_encrypt(int flen, const unsigned char *from, unsigned char *to, RSA * rsa, int padding) { - /* PKCS11 calls go here */ - PKCS11err(PKCS11_F_PKCS11_RSA_ENCRYPT, PKCS11_NOT_SUPPORTED); - return -1; + return pkcs11_private_encrypt(flen,from,to,(PKCS11_KEY *) RSA_get_app_data(rsa), padding); } static int pkcs11_rsa_sign(int type, const unsigned char *m, unsigned int m_len, unsigned char *sigret, unsigned int *siglen, const RSA * rsa) { - PKCS11_KEY *key = (PKCS11_KEY *) RSA_get_app_data(rsa); - PKCS11_KEY_private *priv; - PKCS11_SLOT *slot; - PKCS11_CTX *ctx; - CK_SESSION_HANDLE session; - CK_MECHANISM mechanism; - int rv, ssl = ((type == NID_md5_sha1) ? 1 : 0); - int rsa_size = RSA_size(rsa); - CK_ULONG sigsize = rsa_size; - unsigned char *encoded = NULL; - - if (key == NULL) - return 0; - ctx = KEY2CTX(key); - priv = PRIVKEY(key); - slot = TOKEN2SLOT(priv->parent); - session = PRIVSLOT(slot)->session; - - if (ssl) { - if((m_len != 36) /* SHA1 + MD5 */ || - ((m_len + RSA_PKCS1_PADDING) > rsa_size)) { - return(0); /* the size is wrong */ - } - } else { - ASN1_TYPE parameter = { V_ASN1_NULL, { NULL } }; - ASN1_STRING digest = { m_len, V_ASN1_OCTET_STRING, (unsigned char *)m }; - X509_ALGOR algor = { NULL, ¶meter }; - X509_SIG digest_info = { &algor, &digest }; - int size; - /* Fetch the OID of the algorithm used */ - if((algor.algorithm = OBJ_nid2obj(type)) && - (algor.algorithm->length) && - /* Get the size of the encoded DigestInfo */ - (size = i2d_X509_SIG(&digest_info, NULL)) && - /* Check that size is compatible with PKCS#11 padding */ - (size + RSA_PKCS1_PADDING <= rsa_size) && - (encoded = (unsigned char *) malloc(rsa_size))) { - unsigned char *tmp = encoded; - /* Actually do the encoding */ - i2d_X509_SIG(&digest_info,&tmp); - m = encoded; - m_len = size; - } else { - return(0); - } - } - - memset(&mechanism, 0, sizeof(mechanism)); - mechanism.mechanism = CKM_RSA_PKCS; - - /* API is somewhat fishy here. *siglen is 0 on entry (cleared - * by OpenSSL). The library assumes that the memory passed - * by the caller is always big enough */ - if((rv = CRYPTOKI_call(ctx, C_SignInit - (session, &mechanism, priv->object))) == 0) { - rv = CRYPTOKI_call(ctx, C_Sign - (session, (CK_BYTE *) m, m_len, - sigret, &sigsize)); - } - *siglen = sigsize; - free(encoded); - - if (rv) { - PKCS11err(PKCS11_F_PKCS11_RSA_SIGN, pkcs11_map_err(rv)); - } - return (rv) ? 0 : 1; + + return pkcs11_sign(type,m,m_len,sigret,siglen,(PKCS11_KEY *) RSA_get_app_data(rsa)); } - /* Lousy hack alert. If RSA_verify detects that the key has the * RSA_FLAG_SIGN_VER flags set, it will assume that verification * is implemented externally as well.