|
Packit |
6b81fa |
/* libp11, a simple layer on to of PKCS#11 API
|
|
Packit |
6b81fa |
* Copyright (C) 2005 Olaf Kirch <okir@lst.de>
|
|
Packit |
6b81fa |
* Copyright (C) 2016 MichaĆ Trojnara <Michal.Trojnara@stunnel.org>
|
|
Packit |
6b81fa |
*
|
|
Packit |
6b81fa |
* This library is free software; you can redistribute it and/or
|
|
Packit |
6b81fa |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit |
6b81fa |
* License as published by the Free Software Foundation; either
|
|
Packit |
6b81fa |
* version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
6b81fa |
*
|
|
Packit |
6b81fa |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
6b81fa |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
6b81fa |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
6b81fa |
* Lesser General Public License for more details.
|
|
Packit |
6b81fa |
*
|
|
Packit |
6b81fa |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit |
6b81fa |
* License along with this library; if not, write to the Free Software
|
|
Packit |
6b81fa |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/*
|
|
Packit |
6b81fa |
* PKCS11 attribute querying.
|
|
Packit |
6b81fa |
*
|
|
Packit |
6b81fa |
* The number of layers we stack on top of each other here
|
|
Packit |
6b81fa |
* is frightening.
|
|
Packit |
6b81fa |
*
|
|
Packit |
6b81fa |
* Copyright (C) 2002, Olaf Kirch <okir@lst.de>
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
#include "libp11-int.h"
|
|
Packit |
6b81fa |
#include <assert.h>
|
|
Packit |
6b81fa |
#include <string.h>
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/*
|
|
Packit |
6b81fa |
* Query pkcs11 attributes
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
static int pkcs11_getattr_int(PKCS11_CTX *ctx, CK_SESSION_HANDLE session,
|
|
Packit |
6b81fa |
CK_OBJECT_HANDLE o, CK_ATTRIBUTE_TYPE type, CK_BYTE *value,
|
|
Packit |
6b81fa |
size_t *size)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
CK_ATTRIBUTE templ;
|
|
Packit |
6b81fa |
int rv;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
templ.type = type;
|
|
Packit |
6b81fa |
templ.pValue = value;
|
|
Packit |
6b81fa |
templ.ulValueLen = *size;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
rv = CRYPTOKI_call(ctx, C_GetAttributeValue(session, o, &templ, 1));
|
|
Packit |
6b81fa |
CRYPTOKI_checkerr(CKR_F_PKCS11_GETATTR_INT, rv);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
*size = templ.ulValueLen;
|
|
Packit |
6b81fa |
return 0;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int pkcs11_getattr_var(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
|
|
Packit |
6b81fa |
unsigned int type, CK_BYTE *value, size_t *size)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
return pkcs11_getattr_int(TOKEN2CTX(token),
|
|
Packit |
6b81fa |
PRIVSLOT(TOKEN2SLOT(token))->session,
|
|
Packit |
6b81fa |
object, type, value, size);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int pkcs11_getattr_val(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
|
|
Packit |
6b81fa |
unsigned int type, void *value, size_t size)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
return pkcs11_getattr_var(token, object, type, value, &size);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int pkcs11_getattr_alloc(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
|
|
Packit |
6b81fa |
unsigned int type, CK_BYTE **value, size_t *size)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
CK_BYTE *data;
|
|
Packit |
6b81fa |
size_t len = 0;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
if (pkcs11_getattr_var(token, object, type, NULL, &len))
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
data = OPENSSL_malloc(len+1);
|
|
Packit |
6b81fa |
if (data == NULL) {
|
|
Packit |
6b81fa |
CKRerr(CKR_F_PKCS11_GETATTR_ALLOC, CKR_HOST_MEMORY);
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
memset(data, 0, len+1); /* also null-terminate the allocated data */
|
|
Packit |
6b81fa |
if (pkcs11_getattr_var(token, object, type, data, &len)) {
|
|
Packit |
6b81fa |
OPENSSL_free(data);
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
if (value)
|
|
Packit |
6b81fa |
*value = data;
|
|
Packit |
6b81fa |
if (size)
|
|
Packit |
6b81fa |
*size = len;
|
|
Packit |
6b81fa |
return 0;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
int pkcs11_getattr_bn(PKCS11_TOKEN *token, CK_OBJECT_HANDLE object,
|
|
Packit |
6b81fa |
unsigned int type, BIGNUM **bn)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
CK_BYTE *binary;
|
|
Packit |
6b81fa |
size_t size;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
size = 0;
|
|
Packit |
6b81fa |
if (pkcs11_getattr_alloc(token, object, type, &binary, &size))
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
/*
|
|
Packit |
6b81fa |
* @ALON: invalid object,
|
|
Packit |
6b81fa |
* not sure it will survive the ulValueLen->size_t and keep sign at all platforms
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
if (size == (size_t)-1) {
|
|
Packit |
6b81fa |
CKRerr(CKR_F_PKCS11_GETATTR_BN, CKR_ATTRIBUTE_TYPE_INVALID);
|
|
Packit |
6b81fa |
OPENSSL_free(binary);
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
*bn = BN_bin2bn(binary, (int)size, *bn);
|
|
Packit |
6b81fa |
OPENSSL_free(binary);
|
|
Packit |
6b81fa |
return *bn ? 0 : -1;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/*
|
|
Packit |
6b81fa |
* Add attributes to template
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
void pkcs11_addattr(CK_ATTRIBUTE_PTR ap, int type, const void *data, size_t size)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
ap->type = type;
|
|
Packit |
6b81fa |
ap->pValue = OPENSSL_malloc(size);
|
|
Packit |
6b81fa |
if (ap->pValue == NULL)
|
|
Packit |
6b81fa |
return;
|
|
Packit |
6b81fa |
memcpy(ap->pValue, data, size);
|
|
Packit |
6b81fa |
ap->ulValueLen = size;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* In PKCS11, virtually every integer is a CK_ULONG */
|
|
Packit |
6b81fa |
void pkcs11_addattr_int(CK_ATTRIBUTE_PTR ap, int type, unsigned long value)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
CK_ULONG ulValue = value;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
pkcs11_addattr(ap, type, &ulValue, sizeof(ulValue));
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
void pkcs11_addattr_bool(CK_ATTRIBUTE_PTR ap, int type, int value)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
pkcs11_addattr(ap, type, &value, sizeof(CK_BBOOL));
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
void pkcs11_addattr_s(CK_ATTRIBUTE_PTR ap, int type, const char *s)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
pkcs11_addattr(ap, type, s, s ? strlen(s) : 0); /* RFC2279 string an unpadded string of CK_UTF8CHARs with no null-termination */
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
void pkcs11_addattr_bn(CK_ATTRIBUTE_PTR ap, int type, const BIGNUM *bn)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
unsigned char temp[1024];
|
|
Packit |
6b81fa |
unsigned int n;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
assert((size_t)BN_num_bytes(bn) <= sizeof(temp));
|
|
Packit |
6b81fa |
n = BN_bn2bin(bn, temp);
|
|
Packit |
6b81fa |
pkcs11_addattr(ap, type, temp, n);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
void pkcs11_addattr_obj(CK_ATTRIBUTE_PTR ap, int type, pkcs11_i2d_fn enc, void *obj)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
unsigned char *p;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
ap->type = type;
|
|
Packit |
6b81fa |
ap->ulValueLen = enc(obj, NULL);
|
|
Packit |
6b81fa |
ap->pValue = OPENSSL_malloc(ap->ulValueLen);
|
|
Packit |
6b81fa |
if (ap->pValue == NULL)
|
|
Packit |
6b81fa |
return;
|
|
Packit |
6b81fa |
p = ap->pValue;
|
|
Packit |
6b81fa |
enc(obj, &p);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
void pkcs11_zap_attrs(CK_ATTRIBUTE_PTR ap, unsigned int n)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
while (n--) {
|
|
Packit |
6b81fa |
if (ap[n].pValue)
|
|
Packit |
6b81fa |
OPENSSL_free(ap[n].pValue);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* vim: set noexpandtab: */
|