|
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-2018 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 |
* p11_cert.c - Handle certificates residing on a PKCS11 token
|
|
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 <string.h>
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
static int pkcs11_find_certs(PKCS11_TOKEN *);
|
|
Packit |
6b81fa |
static int pkcs11_next_cert(PKCS11_CTX *, PKCS11_TOKEN *, CK_SESSION_HANDLE);
|
|
Packit |
6b81fa |
static int pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
|
Packit |
6b81fa |
CK_SESSION_HANDLE session, CK_OBJECT_HANDLE o, PKCS11_CERT **);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/*
|
|
Packit |
6b81fa |
* Enumerate all certs on the card
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
int pkcs11_enumerate_certs(PKCS11_TOKEN *token,
|
|
Packit |
6b81fa |
PKCS11_CERT **certp, unsigned int *countp)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
|
Packit |
6b81fa |
PKCS11_CTX *ctx = SLOT2CTX(slot);
|
|
Packit |
6b81fa |
PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
|
|
Packit |
6b81fa |
PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
|
|
Packit |
6b81fa |
PKCS11_CTX_private *cpriv = PRIVCTX(ctx);
|
|
Packit |
6b81fa |
int rv;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Make sure we have a session */
|
|
Packit |
6b81fa |
if (!spriv->haveSession && PKCS11_open_session(slot, 0))
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
CRYPTO_THREAD_write_lock(cpriv->rwlock);
|
|
Packit |
6b81fa |
rv = pkcs11_find_certs(token);
|
|
Packit |
6b81fa |
CRYPTO_THREAD_unlock(cpriv->rwlock);
|
|
Packit |
6b81fa |
if (rv < 0) {
|
|
Packit |
6b81fa |
pkcs11_destroy_certs(token);
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
if (certp)
|
|
Packit |
6b81fa |
*certp = tpriv->certs;
|
|
Packit |
6b81fa |
if (countp)
|
|
Packit |
6b81fa |
*countp = tpriv->ncerts;
|
|
Packit |
6b81fa |
return 0;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/**
|
|
Packit |
6b81fa |
* Remove a certificate from the associated token
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
int pkcs11_remove_certificate(PKCS11_CERT *cert){
|
|
Packit |
6b81fa |
PKCS11_SLOT *slot = CERT2SLOT(cert);
|
|
Packit |
6b81fa |
PKCS11_CTX *ctx = CERT2CTX(cert);
|
|
Packit |
6b81fa |
PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
|
|
Packit |
6b81fa |
CK_OBJECT_HANDLE obj;
|
|
Packit |
6b81fa |
CK_ULONG count;
|
|
Packit |
6b81fa |
CK_ATTRIBUTE search_parameters[32];
|
|
Packit |
6b81fa |
unsigned int n = 0;
|
|
Packit |
6b81fa |
int rv;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* First, make sure we have a session */
|
|
Packit |
6b81fa |
if (!spriv->haveSession && PKCS11_open_session(slot, 1)){
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
pkcs11_addattr_int(search_parameters + n++, CKA_CLASS, CKO_CERTIFICATE);
|
|
Packit |
6b81fa |
if (cert->id && cert->id_len){
|
|
Packit |
6b81fa |
pkcs11_addattr(search_parameters + n++, CKA_ID, cert->id, cert->id_len);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
if (cert->label){
|
|
Packit |
6b81fa |
pkcs11_addattr_s(search_parameters + n++, CKA_LABEL, cert->label);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
rv = CRYPTOKI_call(ctx,
|
|
Packit |
6b81fa |
C_FindObjectsInit(spriv->session, search_parameters, n));
|
|
Packit |
6b81fa |
CRYPTOKI_checkerr(CKR_F_PKCS11_REMOVE_CERTIFICATE, rv);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
rv = CRYPTOKI_call(ctx, C_FindObjects(spriv->session, &obj, 1, &count));
|
|
Packit |
6b81fa |
CRYPTOKI_checkerr(CKR_F_PKCS11_REMOVE_CERTIFICATE, rv);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
CRYPTOKI_call(ctx, C_FindObjectsFinal(spriv->session));
|
|
Packit |
6b81fa |
if (count!=1){
|
|
Packit |
6b81fa |
pkcs11_zap_attrs(search_parameters, n);
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
rv = CRYPTOKI_call(ctx, C_DestroyObject(spriv->session, obj));
|
|
Packit |
6b81fa |
if (rv != CKR_OK){
|
|
Packit |
6b81fa |
pkcs11_zap_attrs(search_parameters, n);
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
pkcs11_zap_attrs(search_parameters, n);
|
|
Packit |
6b81fa |
return 0;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/*
|
|
Packit |
6b81fa |
* Find certificate matching a key
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
PKCS11_CERT *pkcs11_find_certificate(PKCS11_KEY *key)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
PKCS11_KEY_private *kpriv;
|
|
Packit |
6b81fa |
PKCS11_CERT_private *cpriv;
|
|
Packit |
6b81fa |
PKCS11_CERT *cert;
|
|
Packit |
6b81fa |
unsigned int n, count;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
kpriv = PRIVKEY(key);
|
|
Packit |
6b81fa |
if (PKCS11_enumerate_certs(KEY2TOKEN(key), &cert, &count))
|
|
Packit |
6b81fa |
return NULL;
|
|
Packit |
6b81fa |
for (n = 0; n < count; n++, cert++) {
|
|
Packit |
6b81fa |
cpriv = PRIVCERT(cert);
|
|
Packit |
6b81fa |
if (cpriv->id_len == kpriv->id_len
|
|
Packit |
6b81fa |
&& !memcmp(cpriv->id, kpriv->id, kpriv->id_len))
|
|
Packit |
6b81fa |
return cert;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
return NULL;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/*
|
|
Packit |
6b81fa |
* Find all certs of a given type (public or private)
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
static int pkcs11_find_certs(PKCS11_TOKEN *token)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
|
Packit |
6b81fa |
PKCS11_CTX *ctx = SLOT2CTX(slot);
|
|
Packit |
6b81fa |
PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
|
|
Packit |
6b81fa |
CK_OBJECT_CLASS cert_search_class;
|
|
Packit |
6b81fa |
CK_ATTRIBUTE cert_search_attrs[] = {
|
|
Packit |
6b81fa |
{CKA_CLASS, &cert_search_class, sizeof(cert_search_class)},
|
|
Packit |
6b81fa |
};
|
|
Packit |
6b81fa |
int rv, res = -1;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Tell the PKCS11 lib to enumerate all matching objects */
|
|
Packit |
6b81fa |
cert_search_class = CKO_CERTIFICATE;
|
|
Packit |
6b81fa |
rv = CRYPTOKI_call(ctx, C_FindObjectsInit(spriv->session, cert_search_attrs, 1));
|
|
Packit |
6b81fa |
CRYPTOKI_checkerr(CKR_F_PKCS11_FIND_CERTS, rv);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
do {
|
|
Packit |
6b81fa |
res = pkcs11_next_cert(ctx, token, spriv->session);
|
|
Packit |
6b81fa |
} while (res == 0);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
CRYPTOKI_call(ctx, C_FindObjectsFinal(spriv->session));
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
return (res < 0) ? -1 : 0;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
static int pkcs11_next_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
|
Packit |
6b81fa |
CK_SESSION_HANDLE session)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
CK_OBJECT_HANDLE obj;
|
|
Packit |
6b81fa |
CK_ULONG count;
|
|
Packit |
6b81fa |
int rv;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Get the next matching object */
|
|
Packit |
6b81fa |
rv = CRYPTOKI_call(ctx, C_FindObjects(session, &obj, 1, &count));
|
|
Packit |
6b81fa |
CRYPTOKI_checkerr(CKR_F_PKCS11_NEXT_CERT, rv);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
if (count == 0)
|
|
Packit |
6b81fa |
return 1;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
if (pkcs11_init_cert(ctx, token, session, obj, NULL))
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
return 0;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
static int pkcs11_init_cert(PKCS11_CTX *ctx, PKCS11_TOKEN *token,
|
|
Packit |
6b81fa |
CK_SESSION_HANDLE session, CK_OBJECT_HANDLE obj, PKCS11_CERT ** ret)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
PKCS11_TOKEN_private *tpriv;
|
|
Packit |
6b81fa |
PKCS11_CERT_private *cpriv;
|
|
Packit |
6b81fa |
PKCS11_CERT *cert, *tmp;
|
|
Packit |
6b81fa |
unsigned char *data;
|
|
Packit |
6b81fa |
CK_CERTIFICATE_TYPE cert_type;
|
|
Packit |
6b81fa |
size_t size;
|
|
Packit |
6b81fa |
int i;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
(void)ctx;
|
|
Packit |
6b81fa |
(void)session;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Ignore unknown certificate types */
|
|
Packit |
6b81fa |
size = sizeof(CK_CERTIFICATE_TYPE);
|
|
Packit |
6b81fa |
if (pkcs11_getattr_var(token, obj, CKA_CERTIFICATE_TYPE, (CK_BYTE *)&cert_type, &size))
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
if (cert_type != CKC_X_509)
|
|
Packit |
6b81fa |
return 0;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Prevent re-adding existing PKCS#11 object handles */
|
|
Packit |
6b81fa |
/* TODO: Rewrite the O(n) algorithm as O(log n),
|
|
Packit |
6b81fa |
* or it may be too slow with a large number of certificates */
|
|
Packit |
6b81fa |
for (i=0; i < PRIVTOKEN(token)->ncerts; ++i)
|
|
Packit |
6b81fa |
if (PRIVCERT(PRIVTOKEN(token)->certs + i)->object == obj)
|
|
Packit |
6b81fa |
return 0;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Allocate memory */
|
|
Packit |
6b81fa |
cpriv = OPENSSL_malloc(sizeof(PKCS11_CERT_private));
|
|
Packit |
6b81fa |
if (cpriv == NULL)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
memset(cpriv, 0, sizeof(PKCS11_CERT_private));
|
|
Packit |
6b81fa |
tpriv = PRIVTOKEN(token);
|
|
Packit |
6b81fa |
tmp = OPENSSL_realloc(tpriv->certs,
|
|
Packit |
6b81fa |
(tpriv->ncerts + 1) * sizeof(PKCS11_CERT));
|
|
Packit |
6b81fa |
if (tmp == NULL)
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
tpriv->certs = tmp;
|
|
Packit |
6b81fa |
cert = tpriv->certs + tpriv->ncerts++;
|
|
Packit |
6b81fa |
memset(cert, 0, sizeof(PKCS11_CERT));
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Fill public properties */
|
|
Packit |
6b81fa |
pkcs11_getattr_alloc(token, obj, CKA_LABEL, (CK_BYTE **)&cert->label, NULL);
|
|
Packit |
6b81fa |
size = 0;
|
|
Packit |
6b81fa |
if (!pkcs11_getattr_alloc(token, obj, CKA_VALUE, &data, &size)) {
|
|
Packit |
6b81fa |
const unsigned char *p = data;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
cert->x509 = d2i_X509(NULL, &p, (long)size);
|
|
Packit |
6b81fa |
OPENSSL_free(data);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
cert->id_len = 0;
|
|
Packit |
6b81fa |
pkcs11_getattr_alloc(token, obj, CKA_ID, &cert->id, &cert->id_len);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Fill private properties */
|
|
Packit |
6b81fa |
cert->_private = cpriv;
|
|
Packit |
6b81fa |
cpriv->object = obj;
|
|
Packit |
6b81fa |
cpriv->parent = token;
|
|
Packit |
6b81fa |
cpriv->id_len = sizeof cpriv->id;
|
|
Packit |
6b81fa |
if (pkcs11_getattr_var(token, obj, CKA_ID, cpriv->id, &cpriv->id_len))
|
|
Packit |
6b81fa |
cpriv->id_len = 0;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
if (ret)
|
|
Packit |
6b81fa |
*ret = cert;
|
|
Packit |
6b81fa |
return 0;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/*
|
|
Packit |
6b81fa |
* Destroy all certs
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
void pkcs11_destroy_certs(PKCS11_TOKEN *token)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
PKCS11_TOKEN_private *tpriv = PRIVTOKEN(token);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
while (tpriv->ncerts > 0) {
|
|
Packit |
6b81fa |
PKCS11_CERT *cert = &tpriv->certs[--(tpriv->ncerts)];
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
if (cert->x509)
|
|
Packit |
6b81fa |
X509_free(cert->x509);
|
|
Packit |
6b81fa |
OPENSSL_free(cert->label);
|
|
Packit |
6b81fa |
if (cert->id)
|
|
Packit |
6b81fa |
OPENSSL_free(cert->id);
|
|
Packit |
6b81fa |
if (cert->_private != NULL)
|
|
Packit |
6b81fa |
OPENSSL_free(cert->_private);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
if (tpriv->certs)
|
|
Packit |
6b81fa |
OPENSSL_free(tpriv->certs);
|
|
Packit |
6b81fa |
tpriv->certs = NULL;
|
|
Packit |
6b81fa |
tpriv->ncerts = 0;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/*
|
|
Packit |
6b81fa |
* Store certificate
|
|
Packit |
6b81fa |
*/
|
|
Packit |
6b81fa |
int pkcs11_store_certificate(PKCS11_TOKEN *token, X509 *x509, char *label,
|
|
Packit |
6b81fa |
unsigned char *id, size_t id_len, PKCS11_CERT ** ret_cert)
|
|
Packit |
6b81fa |
{
|
|
Packit |
6b81fa |
PKCS11_SLOT *slot = TOKEN2SLOT(token);
|
|
Packit |
6b81fa |
PKCS11_CTX *ctx = SLOT2CTX(slot);
|
|
Packit |
6b81fa |
PKCS11_SLOT_private *spriv = PRIVSLOT(slot);
|
|
Packit |
6b81fa |
CK_OBJECT_HANDLE object;
|
|
Packit |
6b81fa |
CK_ATTRIBUTE attrs[32];
|
|
Packit |
6b81fa |
unsigned int n = 0;
|
|
Packit |
6b81fa |
int rv;
|
|
Packit |
6b81fa |
const EVP_MD* evp_md;
|
|
Packit |
6b81fa |
CK_MECHANISM_TYPE ckm_md;
|
|
Packit |
6b81fa |
unsigned char md[EVP_MAX_MD_SIZE];
|
|
Packit |
6b81fa |
unsigned int md_len;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* First, make sure we have a session */
|
|
Packit |
6b81fa |
if (!PRIVSLOT(slot)->haveSession && PKCS11_open_session(slot, 1))
|
|
Packit |
6b81fa |
return -1;
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Now build the template */
|
|
Packit |
6b81fa |
pkcs11_addattr_int(attrs + n++, CKA_CLASS, CKO_CERTIFICATE);
|
|
Packit |
6b81fa |
pkcs11_addattr_bool(attrs + n++, CKA_TOKEN, TRUE);
|
|
Packit |
6b81fa |
pkcs11_addattr_int(attrs + n++, CKA_CERTIFICATE_TYPE, CKC_X_509);
|
|
Packit |
6b81fa |
pkcs11_addattr_obj(attrs + n++, CKA_SUBJECT,
|
|
Packit |
6b81fa |
(pkcs11_i2d_fn)i2d_X509_NAME, X509_get_subject_name(x509));
|
|
Packit |
6b81fa |
pkcs11_addattr_obj(attrs + n++, CKA_ISSUER,
|
|
Packit |
6b81fa |
(pkcs11_i2d_fn)i2d_X509_NAME, X509_get_issuer_name(x509));
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Get digest algorithm from x509 certificate */
|
|
Packit |
6b81fa |
evp_md = EVP_get_digestbynid(X509_get_signature_nid(x509));
|
|
Packit |
6b81fa |
switch (EVP_MD_type(evp_md)) {
|
|
Packit |
6b81fa |
default:
|
|
Packit |
6b81fa |
case NID_sha1:
|
|
Packit |
6b81fa |
ckm_md = CKM_SHA_1;
|
|
Packit |
6b81fa |
break;
|
|
Packit |
6b81fa |
case NID_sha224:
|
|
Packit |
6b81fa |
ckm_md = CKM_SHA224;
|
|
Packit |
6b81fa |
break;
|
|
Packit |
6b81fa |
case NID_sha256:
|
|
Packit |
6b81fa |
ckm_md = CKM_SHA256;
|
|
Packit |
6b81fa |
break;
|
|
Packit |
6b81fa |
case NID_sha512:
|
|
Packit |
6b81fa |
ckm_md = CKM_SHA512;
|
|
Packit |
6b81fa |
break;
|
|
Packit |
6b81fa |
case NID_sha384:
|
|
Packit |
6b81fa |
ckm_md = CKM_SHA384;
|
|
Packit |
6b81fa |
break;
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Set hash algorithm; default is SHA-1 */
|
|
Packit |
6b81fa |
pkcs11_addattr_int(attrs + n++, CKA_NAME_HASH_ALGORITHM, ckm_md);
|
|
Packit |
6b81fa |
if(X509_pubkey_digest(x509,evp_md,md,&md_len))
|
|
Packit |
6b81fa |
pkcs11_addattr(attrs + n++, CKA_HASH_OF_SUBJECT_PUBLIC_KEY,md,md_len);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
pkcs11_addattr_obj(attrs + n++, CKA_VALUE, (pkcs11_i2d_fn)i2d_X509, x509);
|
|
Packit |
6b81fa |
if (label)
|
|
Packit |
6b81fa |
pkcs11_addattr_s(attrs + n++, CKA_LABEL, label);
|
|
Packit |
6b81fa |
if (id && id_len)
|
|
Packit |
6b81fa |
pkcs11_addattr(attrs + n++, CKA_ID, id, id_len);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Now call the pkcs11 module to create the object */
|
|
Packit |
6b81fa |
rv = CRYPTOKI_call(ctx, C_CreateObject(spriv->session, attrs, n, &object));
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Zap all memory allocated when building the template */
|
|
Packit |
6b81fa |
pkcs11_zap_attrs(attrs, n);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
CRYPTOKI_checkerr(CKR_F_PKCS11_STORE_CERTIFICATE, rv);
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* Gobble the key object */
|
|
Packit |
6b81fa |
return pkcs11_init_cert(ctx, token, spriv->session, object, ret_cert);
|
|
Packit |
6b81fa |
}
|
|
Packit |
6b81fa |
|
|
Packit |
6b81fa |
/* vim: set noexpandtab: */
|