#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <lber.h>
#include <security/cryptoki.h>
#include "softDSA.h"
#include "softDH.h"
#include "softRSA.h"
#include "softObject.h"
#include "softASN1.h"
#define OID_TAG 0x06
#define MAX_DH_KEY MAX_DH_KEYLENGTH_IN_BYTES
static uchar_t DH_OID[] = {
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x03, 0x01
};
#define MAX_DH942_KEY MAX_DH_KEYLENGTH_IN_BYTES
static uchar_t DH942_OID[] = {
0x2A, 0x86, 0x48, 0xCE, 0x3E, 0x01
};
#define MAX_DSA_KEY MAX_DSA_KEY_LEN
static uchar_t DSA_OID[] = {
0x2A, 0x86, 0x48, 0xCE, 0x38, 0x04, 0x01
};
#define MAX_RSA_KEY MAX_RSA_KEYLENGTH_IN_BYTES
static uchar_t RSA_OID[] = {
0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01
};
static CK_RV
pad_bigint_attr(biginteger_t *src, biginteger_t *dst)
{
int padding;
if (src == NULL || dst == NULL)
return (CKR_HOST_MEMORY);
if (src->big_value_len == 0) {
dst->big_value = NULL;
dst->big_value_len = 0;
return (CKR_OK);
}
if (dst->big_value != NULL)
explicit_bzero(dst->big_value, dst->big_value_len);
padding = (src->big_value[0] < 0x80) ? 0 : 1;
dst->big_value_len = src->big_value_len + padding;
dst->big_value = realloc(dst->big_value, dst->big_value_len);
if (dst->big_value == NULL)
return (CKR_HOST_MEMORY);
dst->big_value[0] = 0x0;
(void) memcpy(&(dst->big_value[padding]), src->big_value,
src->big_value_len);
return (CKR_OK);
}
static CK_RV
unpad_bigint_attr(biginteger_t src, biginteger_t *dst)
{
int offset;
if (dst == NULL)
return (CKR_HOST_MEMORY);
if (src.big_value_len == 0) {
dst->big_value = NULL;
dst->big_value_len = 0;
return (CKR_OK);
}
offset = (src.big_value[0] == 0x00) ? 1 : 0;
dst->big_value_len = src.big_value_len - offset;
dst->big_value = malloc(dst->big_value_len);
if (dst->big_value == NULL)
return (CKR_HOST_MEMORY);
(void) memcpy(dst->big_value, &(src.big_value[offset]),
dst->big_value_len);
return (CKR_OK);
}
static CK_RV
rsa_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
{
CK_RV rv = CKR_OK;
BerElement *key_asn = NULLBER, *p8obj_asn = NULLBER;
BerValue *key_octs = NULL, *p8obj_octs = NULL;
int version = SOFT_ASN_VERSION;
biginteger_t tmp_pad = { NULL, 0 };
if ((key_asn = ber_alloc()) == NULLBER)
return (CKR_HOST_MEMORY);
if (ber_printf(key_asn, "{i", version) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_rsapri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_RSA_MOD(objp), &tmp_pad)) != CKR_OK)
goto cleanup_rsapri2asn;
if (ber_printf(key_asn, "to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_rsapri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PUBEXPO(objp), &tmp_pad)) !=
CKR_OK)
goto cleanup_rsapri2asn;
else if (ber_printf(key_asn, "to", LBER_INTEGER, tmp_pad.big_value,
tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_rsapri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PRIEXPO(objp), &tmp_pad)) !=
CKR_OK)
goto cleanup_rsapri2asn;
if (ber_printf(key_asn, "to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_rsapri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PRIME1(objp), &tmp_pad)) !=
CKR_OK)
goto cleanup_rsapri2asn;
else if (ber_printf(key_asn, "to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_rsapri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_RSA_PRIME2(objp), &tmp_pad)) !=
CKR_OK)
goto cleanup_rsapri2asn;
else if (ber_printf(key_asn, "to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_rsapri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_RSA_EXPO1(objp), &tmp_pad)) != CKR_OK)
goto cleanup_rsapri2asn;
else if (ber_printf(key_asn, "to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_rsapri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_RSA_EXPO2(objp), &tmp_pad)) != CKR_OK)
goto cleanup_rsapri2asn;
else if (ber_printf(key_asn, "to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_rsapri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_RSA_COEF(objp), &tmp_pad)) != CKR_OK)
goto cleanup_rsapri2asn;
else if (ber_printf(key_asn, "to}", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_rsapri2asn;
}
if (ber_flatten(key_asn, &key_octs) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_rsapri2asn;
}
if ((p8obj_asn = ber_alloc()) == NULLBER) {
rv = CKR_HOST_MEMORY;
goto cleanup_rsapri2asn;
}
if (ber_printf(p8obj_asn, "{i{ton}o}", version,
OID_TAG, RSA_OID, sizeof (RSA_OID),
key_octs->bv_val, key_octs->bv_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_rsapri2asn;
}
if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_rsapri2asn;
}
#ifdef _LP64
if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
#else
if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
#endif
*buf_len = p8obj_octs->bv_len;
rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
goto cleanup_rsapri2asn;
}
*buf_len = p8obj_octs->bv_len;
(void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
cleanup_rsapri2asn:
freezero(tmp_pad.big_value, tmp_pad.big_value_len);
if (key_asn != NULLBER)
ber_free(key_asn, 1);
if (key_octs != NULL)
ber_bvfree(key_octs);
if (p8obj_asn != NULLBER)
ber_free(p8obj_asn, 1);
if (p8obj_octs != NULL)
ber_bvfree(p8obj_octs);
return (rv);
}
static CK_RV
dsa_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
{
CK_RV rv = CKR_OK;
BerElement *key_asn = NULLBER, *p8obj_asn = NULLBER;
BerValue *key_octs = NULL, *p8obj_octs = NULL;
int version = SOFT_ASN_VERSION;
biginteger_t tmp_pad = { NULL, 0 };
if ((key_asn = ber_alloc()) == NULLBER)
return (CKR_HOST_MEMORY);
if ((rv = pad_bigint_attr(OBJ_PRI_DSA_VALUE(objp), &tmp_pad)) != CKR_OK)
goto cleanup_dsapri2asn;
if (ber_printf(key_asn, "to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dsapri2asn;
}
if (ber_flatten(key_asn, &key_octs) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dsapri2asn;
}
if ((p8obj_asn = ber_alloc()) == NULLBER) {
rv = CKR_HOST_MEMORY;
goto cleanup_dsapri2asn;
}
if (ber_printf(p8obj_asn, "{i{to", version,
OID_TAG, DSA_OID, sizeof (DSA_OID)) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dsapri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_DSA_PRIME(objp), &tmp_pad)) != CKR_OK)
goto cleanup_dsapri2asn;
if (ber_printf(p8obj_asn, "{to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dsapri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_DSA_SUBPRIME(objp), &tmp_pad)) !=
CKR_OK)
goto cleanup_dsapri2asn;
if (ber_printf(p8obj_asn, "to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dsapri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_DSA_BASE(objp), &tmp_pad)) != CKR_OK)
goto cleanup_dsapri2asn;
if (ber_printf(p8obj_asn, "to}", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dsapri2asn;
}
if (ber_printf(p8obj_asn, "}o}",
key_octs->bv_val, key_octs->bv_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dsapri2asn;
}
if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dsapri2asn;
}
#ifdef _LP64
if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
#else
if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
#endif
*buf_len = p8obj_octs->bv_len;
rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
goto cleanup_dsapri2asn;
}
*buf_len = p8obj_octs->bv_len;
(void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
cleanup_dsapri2asn:
freezero(tmp_pad.big_value, tmp_pad.big_value_len);
if (key_asn != NULLBER)
ber_free(key_asn, 1);
if (key_octs != NULL)
ber_bvfree(key_octs);
if (p8obj_asn != NULLBER)
ber_free(p8obj_asn, 1);
if (p8obj_octs != NULL)
ber_bvfree(p8obj_octs);
return (rv);
}
static CK_RV
dh_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
{
CK_RV rv = CKR_OK;
BerElement *key_asn = NULLBER, *p8obj_asn = NULLBER;
BerValue *key_octs = NULL, *p8obj_octs = NULL;
int version = SOFT_ASN_VERSION;
biginteger_t tmp_pad = { NULL, 0 };
if ((key_asn = ber_alloc()) == NULLBER)
return (CKR_HOST_MEMORY);
if ((rv = pad_bigint_attr(OBJ_PRI_DH_VALUE(objp), &tmp_pad)) != CKR_OK)
goto cleanup_dhpri2asn;
if (ber_printf(key_asn, "to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dhpri2asn;
}
if (ber_flatten(key_asn, &key_octs) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dhpri2asn;
}
if ((p8obj_asn = ber_alloc()) == NULLBER) {
rv = CKR_HOST_MEMORY;
goto cleanup_dhpri2asn;
}
if (ber_printf(p8obj_asn, "{i{to", version,
OID_TAG, DH_OID, sizeof (DH_OID)) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dhpri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_DH_PRIME(objp), &tmp_pad)) != CKR_OK)
goto cleanup_dhpri2asn;
if (ber_printf(p8obj_asn, "{to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dhpri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_DH_BASE(objp), &tmp_pad)) != CKR_OK)
goto cleanup_dhpri2asn;
if (ber_printf(p8obj_asn, "to}", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dhpri2asn;
}
if (ber_printf(p8obj_asn, "}o}",
key_octs->bv_val, key_octs->bv_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dhpri2asn;
}
if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_dhpri2asn;
}
#ifdef _LP64
if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
#else
if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
#endif
*buf_len = p8obj_octs->bv_len;
rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
goto cleanup_dhpri2asn;
}
*buf_len = p8obj_octs->bv_len;
(void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
cleanup_dhpri2asn:
freezero(tmp_pad.big_value, tmp_pad.big_value_len);
if (key_asn != NULLBER)
ber_free(key_asn, 1);
if (key_octs != NULL)
ber_bvfree(key_octs);
if (p8obj_asn != NULLBER)
ber_free(p8obj_asn, 1);
if (p8obj_octs != NULL)
ber_bvfree(p8obj_octs);
return (rv);
}
static CK_RV
x942_dh_pri_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
{
CK_RV rv = CKR_OK;
BerElement *key_asn = NULLBER, *p8obj_asn = NULLBER;
BerValue *key_octs = NULL, *p8obj_octs = NULL;
int version = SOFT_ASN_VERSION;
biginteger_t tmp_pad = { NULL, 0 };
if ((key_asn = ber_alloc()) == NULLBER)
return (CKR_HOST_MEMORY);
if ((rv = pad_bigint_attr(OBJ_PRI_DH942_VALUE(objp), &tmp_pad)) !=
CKR_OK)
goto cleanup_x942dhpri2asn;
if (ber_printf(key_asn, "to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_x942dhpri2asn;
}
if (ber_flatten(key_asn, &key_octs) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_x942dhpri2asn;
}
if ((p8obj_asn = ber_alloc()) == NULLBER) {
rv = CKR_HOST_MEMORY;
goto cleanup_x942dhpri2asn;
}
if (ber_printf(p8obj_asn, "{i{to", version,
OID_TAG, DH942_OID, sizeof (DH942_OID)) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_x942dhpri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_DH942_PRIME(objp), &tmp_pad)) !=
CKR_OK)
goto cleanup_x942dhpri2asn;
if (ber_printf(p8obj_asn, "{to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_x942dhpri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_DH942_BASE(objp), &tmp_pad)) !=
CKR_OK)
goto cleanup_x942dhpri2asn;
if (ber_printf(p8obj_asn, "to", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_x942dhpri2asn;
}
if ((rv = pad_bigint_attr(OBJ_PRI_DH942_SUBPRIME(objp), &tmp_pad)) !=
CKR_OK)
goto cleanup_x942dhpri2asn;
if (ber_printf(p8obj_asn, "to}", LBER_INTEGER,
tmp_pad.big_value, tmp_pad.big_value_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_x942dhpri2asn;
}
if (ber_printf(p8obj_asn, "}o}",
key_octs->bv_val, key_octs->bv_len) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_x942dhpri2asn;
}
if (ber_flatten(p8obj_asn, &p8obj_octs) == -1) {
rv = CKR_GENERAL_ERROR;
goto cleanup_x942dhpri2asn;
}
#ifdef _LP64
if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
#else
if ((buf == NULL) || ((ber_len_t)(*buf_len) < p8obj_octs->bv_len)) {
#endif
*buf_len = p8obj_octs->bv_len;
rv = (buf == NULL) ? CKR_OK : CKR_BUFFER_TOO_SMALL;
goto cleanup_x942dhpri2asn;
}
*buf_len = p8obj_octs->bv_len;
(void) memcpy(buf, p8obj_octs->bv_val, *buf_len);
cleanup_x942dhpri2asn:
freezero(tmp_pad.big_value, tmp_pad.big_value_len);
if (key_asn != NULLBER)
ber_free(key_asn, 1);
if (key_octs != NULL)
ber_bvfree(key_octs);
if (p8obj_asn != NULLBER)
ber_free(p8obj_asn, 1);
if (p8obj_octs != NULL)
ber_bvfree(p8obj_octs);
return (rv);
}
CK_RV
soft_object_to_asn1(soft_object_t *objp, uchar_t *buf, ulong_t *buf_len)
{
CK_OBJECT_CLASS class = objp->class;
CK_KEY_TYPE keytype = objp->key_type;
switch (class) {
case CKO_PRIVATE_KEY:
switch (keytype) {
case CKK_RSA:
return (rsa_pri_to_asn1(objp, buf, buf_len));
case CKK_DSA:
return (dsa_pri_to_asn1(objp, buf, buf_len));
case CKK_DH:
return (dh_pri_to_asn1(objp, buf, buf_len));
case CKK_X9_42_DH:
return (x942_dh_pri_to_asn1(objp, buf, buf_len));
default:
return (CKR_FUNCTION_NOT_SUPPORTED);
}
default:
return (CKR_FUNCTION_NOT_SUPPORTED);
}
}
static CK_RV
asn1_to_rsa_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
{
CK_RV rv = CKR_OK;
BerValue p8obj_octs, key_octs;
BerElement *p8obj_asn = NULLBER, *key_asn = NULLBER;
ber_len_t size, tmplen;
char *cookie;
int version;
uchar_t oid[sizeof (RSA_OID) + 1];
biginteger_t tmp, tmp_nopad = { NULL, 0 };
p8obj_octs.bv_val = (char *)buf;
#ifdef _LP64
p8obj_octs.bv_len = (ber_len_t)buf_len;
#else
p8obj_octs.bv_len = (ber_len_t)buf_len;
#endif
key_octs.bv_val = NULL;
key_octs.bv_len = 0;
if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
return (CKR_GENERAL_ERROR);
if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2rsapri;
}
(void) ber_scanf(p8obj_asn, "i", &version);
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2rsapri;
}
(void) ber_scanf(p8obj_asn, "{");
if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2rsapri;
}
if (size != sizeof (RSA_OID)) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto cleanup_asn2rsapri;
}
size = sizeof (oid);
(void) ber_scanf(p8obj_asn, "s", oid, &size);
if (memcmp(oid, RSA_OID, size) != 0) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto cleanup_asn2rsapri;
}
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_NULL) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2rsapri;
}
(void) ber_scanf(p8obj_asn, "n");
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2rsapri;
}
key_octs.bv_len = size + 1;
if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
rv = CKR_HOST_MEMORY;
goto cleanup_asn2rsapri;
}
(void) ber_scanf(p8obj_asn, "s",
key_octs.bv_val, &key_octs.bv_len);
if ((key_asn = ber_init(&key_octs)) == NULLBER) {
rv = CKR_GENERAL_ERROR;
goto cleanup_asn2rsapri;
}
if (ber_first_element(key_asn, &size, &cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2rsapri;
}
(void) ber_scanf(key_asn, "i", &version);
if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2rsapri;
}
if (size > MAX_RSA_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto cleanup_asn2rsapri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto cleanup_asn2rsapri;
}
(void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto cleanup_asn2rsapri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_MOD(keyp));
if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2rsapri;
}
if (size > MAX_RSA_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2rsapri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2rsapri;
}
(void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2rsapri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PUBEXPO(keyp));
if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2rsapri;
}
if (size > MAX_RSA_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2rsapri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2rsapri;
}
(void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2rsapri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIEXPO(keyp));
if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2rsapri;
}
if (size > MAX_RSA_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2rsapri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2rsapri;
}
(void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2rsapri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIME1(keyp));
if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2rsapri;
}
if (size > MAX_RSA_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2rsapri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2rsapri;
}
(void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2rsapri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_PRIME2(keyp));
if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2rsapri;
}
if (size > MAX_RSA_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2rsapri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2rsapri;
}
(void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2rsapri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_EXPO1(keyp));
if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2rsapri;
}
if (size > MAX_RSA_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2rsapri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2rsapri;
}
(void) ber_scanf(key_asn, "s", tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2rsapri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_EXPO2(keyp));
if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2rsapri;
}
if (size > MAX_RSA_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2rsapri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2rsapri;
}
(void) ber_scanf(key_asn, "s",
tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2rsapri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_RSA_COEF(keyp));
goto cleanup_asn2rsapri;
error_asn2rsapri:
bigint_attr_cleanup(KEY_PRI_RSA_MOD(keyp));
bigint_attr_cleanup(KEY_PRI_RSA_PUBEXPO(keyp));
bigint_attr_cleanup(KEY_PRI_RSA_PRIEXPO(keyp));
bigint_attr_cleanup(KEY_PRI_RSA_PRIME1(keyp));
bigint_attr_cleanup(KEY_PRI_RSA_PRIME2(keyp));
bigint_attr_cleanup(KEY_PRI_RSA_EXPO1(keyp));
bigint_attr_cleanup(KEY_PRI_RSA_EXPO2(keyp));
bigint_attr_cleanup(KEY_PRI_RSA_COEF(keyp));
cleanup_asn2rsapri:
freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
if (p8obj_asn != NULLBER)
ber_free(p8obj_asn, 1);
if (key_octs.bv_val != NULL)
free(key_octs.bv_val);
if (key_asn != NULLBER)
ber_free(key_asn, 1);
return (rv);
}
static CK_RV
asn1_to_dsa_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
{
CK_RV rv = CKR_OK;
BerValue p8obj_octs, key_octs;
BerElement *p8obj_asn = NULLBER, *key_asn = NULLBER;
ber_len_t size, tmplen;
char *cookie;
int version;
uchar_t oid[sizeof (DSA_OID) + 1];
biginteger_t tmp, tmp_nopad = { NULL, 0 };
p8obj_octs.bv_val = (char *)buf;
#ifdef _LP64
p8obj_octs.bv_len = (ber_len_t)buf_len;
#else
p8obj_octs.bv_len = (ber_len_t)buf_len;
#endif
key_octs.bv_val = NULL;
key_octs.bv_len = 0;
if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
return (CKR_GENERAL_ERROR);
if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2dsapri;
}
(void) ber_scanf(p8obj_asn, "i", &version);
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2dsapri;
}
(void) ber_scanf(p8obj_asn, "{");
if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2dsapri;
}
if (size != sizeof (DSA_OID)) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto cleanup_asn2dsapri;
}
size = sizeof (oid);
(void) ber_scanf(p8obj_asn, "s", oid, &size);
if (memcmp(oid, DSA_OID, size) != 0) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto cleanup_asn2dsapri;
}
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2dsapri;
}
(void) ber_scanf(p8obj_asn, "{");
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2dsapri;
}
if (size > MAX_DSA_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto cleanup_asn2dsapri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto cleanup_asn2dsapri;
}
(void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto cleanup_asn2dsapri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_PRIME(keyp));
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2dsapri;
}
if (size > MAX_DSA_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2dsapri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2dsapri;
}
(void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2dsapri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_SUBPRIME(keyp));
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2dsapri;
}
if (size > MAX_DSA_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2dsapri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2dsapri;
}
(void) ber_scanf(p8obj_asn, "s",
tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2dsapri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_BASE(keyp));
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2dsapri;
}
key_octs.bv_len = size + 1;
if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2dsapri;
}
(void) ber_scanf(p8obj_asn, "s",
key_octs.bv_val, &key_octs.bv_len);
if ((key_asn = ber_init(&key_octs)) == NULLBER) {
rv = CKR_GENERAL_ERROR;
goto error_asn2dsapri;
}
if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2dsapri;
}
if (size > MAX_DSA_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2dsapri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2dsapri;
}
(void) ber_scanf(key_asn, "s",
tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2dsapri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_DSA_VALUE(keyp));
goto cleanup_asn2dsapri;
error_asn2dsapri:
bigint_attr_cleanup(KEY_PRI_DSA_PRIME(keyp));
bigint_attr_cleanup(KEY_PRI_DSA_SUBPRIME(keyp));
bigint_attr_cleanup(KEY_PRI_DSA_BASE(keyp));
bigint_attr_cleanup(KEY_PRI_DSA_VALUE(keyp));
cleanup_asn2dsapri:
freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
if (p8obj_asn != NULLBER)
ber_free(p8obj_asn, 1);
if (key_octs.bv_val != NULL)
free(key_octs.bv_val);
if (key_asn != NULLBER)
ber_free(key_asn, 1);
return (rv);
}
static CK_RV
asn1_to_dh_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
{
CK_RV rv = CKR_OK;
BerValue p8obj_octs, key_octs;
BerElement *p8obj_asn = NULLBER, *key_asn = NULLBER;
ber_len_t size, tmplen;
char *cookie;
int version;
uchar_t oid[sizeof (DH_OID) + 1];
biginteger_t tmp, tmp_nopad = { NULL, 0 };
p8obj_octs.bv_val = (char *)buf;
#ifdef _LP64
p8obj_octs.bv_len = (ber_len_t)buf_len;
#else
p8obj_octs.bv_len = (ber_len_t)buf_len;
#endif
key_octs.bv_val = NULL;
key_octs.bv_len = 0;
if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
return (CKR_GENERAL_ERROR);
if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2dhpri;
}
(void) ber_scanf(p8obj_asn, "i", &version);
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2dhpri;
}
(void) ber_scanf(p8obj_asn, "{");
if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2dhpri;
}
if (size != sizeof (DH_OID)) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto cleanup_asn2dhpri;
}
size = sizeof (oid);
(void) ber_scanf(p8obj_asn, "s", oid, &size);
if (memcmp(oid, DH_OID, size) != 0) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto cleanup_asn2dhpri;
}
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2dhpri;
}
(void) ber_scanf(p8obj_asn, "{");
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2dhpri;
}
if (size > MAX_DH_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto cleanup_asn2dhpri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto cleanup_asn2dhpri;
}
(void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto cleanup_asn2dhpri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_PRIME(keyp));
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2dhpri;
}
if (size > MAX_DH_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2dhpri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2dhpri;
}
(void) ber_scanf(p8obj_asn, "s",
tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2dhpri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_BASE(keyp));
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2dhpri;
}
key_octs.bv_len = size + 1;
if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2dhpri;
}
(void) ber_scanf(p8obj_asn, "s",
key_octs.bv_val, &key_octs.bv_len);
if ((key_asn = ber_init(&key_octs)) == NULLBER) {
rv = CKR_GENERAL_ERROR;
goto error_asn2dhpri;
}
if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2dhpri;
}
if (size > MAX_DH_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2dhpri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2dhpri;
}
(void) ber_scanf(key_asn, "s",
tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2dhpri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_DH_VALUE(keyp));
goto cleanup_asn2dhpri;
error_asn2dhpri:
bigint_attr_cleanup(KEY_PRI_DH_PRIME(keyp));
bigint_attr_cleanup(KEY_PRI_DH_BASE(keyp));
bigint_attr_cleanup(KEY_PRI_DH_VALUE(keyp));
cleanup_asn2dhpri:
freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
if (p8obj_asn != NULLBER)
ber_free(p8obj_asn, 1);
if (key_octs.bv_val != NULL)
free(key_octs.bv_val);
if (key_asn != NULLBER)
ber_free(key_asn, 1);
return (rv);
}
static CK_RV
asn1_to_x942_dh_pri(private_key_obj_t *keyp, uchar_t *buf, ulong_t buf_len)
{
CK_RV rv = CKR_OK;
BerValue p8obj_octs, key_octs;
BerElement *p8obj_asn = NULLBER, *key_asn = NULLBER;
ber_len_t size, tmplen;
char *cookie;
int version;
uchar_t oid[sizeof (DH942_OID) + 1];
biginteger_t tmp, tmp_nopad = { NULL, 0 };
p8obj_octs.bv_val = (char *)buf;
#ifdef _LP64
p8obj_octs.bv_len = (ber_len_t)buf_len;
#else
p8obj_octs.bv_len = (ber_len_t)buf_len;
#endif
key_octs.bv_val = NULL;
key_octs.bv_len = 0;
if ((p8obj_asn = ber_init(&p8obj_octs)) == NULLBER)
return (CKR_GENERAL_ERROR);
if (ber_first_element(p8obj_asn, &size, &cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2x942dhpri;
}
(void) ber_scanf(p8obj_asn, "i", &version);
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2x942dhpri;
}
(void) ber_scanf(p8obj_asn, "{");
if (ber_next_element(p8obj_asn, &size, cookie) != OID_TAG) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2x942dhpri;
}
if (size != sizeof (DH942_OID)) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto cleanup_asn2x942dhpri;
}
size = sizeof (oid);
(void) ber_scanf(p8obj_asn, "s", oid, &size);
if (memcmp(oid, DH942_OID, size) != 0) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto cleanup_asn2x942dhpri;
}
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_SEQUENCE) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2x942dhpri;
}
(void) ber_scanf(p8obj_asn, "{");
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto cleanup_asn2x942dhpri;
}
if (size > MAX_DH942_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto cleanup_asn2x942dhpri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto cleanup_asn2x942dhpri;
}
(void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto cleanup_asn2x942dhpri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_PRIME(keyp));
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2x942dhpri;
}
if (size > MAX_DH942_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2x942dhpri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2x942dhpri;
}
(void) ber_scanf(p8obj_asn, "s", tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2x942dhpri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_BASE(keyp));
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2x942dhpri;
}
if (size > MAX_DH942_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2x942dhpri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2x942dhpri;
}
(void) ber_scanf(p8obj_asn, "s",
tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2x942dhpri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_SUBPRIME(keyp));
if (ber_next_element(p8obj_asn, &size, cookie) != LBER_OCTETSTRING) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2x942dhpri;
}
key_octs.bv_len = size + 1;
if ((key_octs.bv_val = malloc(size + 1)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2x942dhpri;
}
(void) ber_scanf(p8obj_asn, "s",
key_octs.bv_val, &key_octs.bv_len);
if ((key_asn = ber_init(&key_octs)) == NULLBER) {
rv = CKR_GENERAL_ERROR;
goto error_asn2x942dhpri;
}
if (ber_next_element(key_asn, &size, cookie) != LBER_INTEGER) {
rv = CKR_WRAPPED_KEY_INVALID;
goto error_asn2x942dhpri;
}
if (size > MAX_DH942_KEY) {
rv = CKR_FUNCTION_NOT_SUPPORTED;
goto error_asn2x942dhpri;
}
tmplen = size + 1;
if ((tmp.big_value = malloc(tmplen)) == NULL) {
rv = CKR_HOST_MEMORY;
goto error_asn2x942dhpri;
}
(void) ber_scanf(key_asn, "s",
tmp.big_value, &tmplen);
tmp.big_value_len = tmplen;
if ((rv = unpad_bigint_attr(tmp, &tmp_nopad)) != CKR_OK) {
free(tmp.big_value);
goto error_asn2x942dhpri;
}
free(tmp.big_value);
copy_bigint_attr(&tmp_nopad, KEY_PRI_DH942_VALUE(keyp));
goto cleanup_asn2x942dhpri;
error_asn2x942dhpri:
bigint_attr_cleanup(KEY_PRI_DH942_PRIME(keyp));
bigint_attr_cleanup(KEY_PRI_DH942_BASE(keyp));
bigint_attr_cleanup(KEY_PRI_DH942_SUBPRIME(keyp));
bigint_attr_cleanup(KEY_PRI_DH942_VALUE(keyp));
cleanup_asn2x942dhpri:
freezero(tmp_nopad.big_value, tmp_nopad.big_value_len);
if (p8obj_asn != NULLBER)
ber_free(p8obj_asn, 1);
if (key_octs.bv_val != NULL)
free(key_octs.bv_val);
if (key_asn != NULLBER)
ber_free(key_asn, 1);
return (rv);
}
CK_RV
soft_asn1_to_object(soft_object_t *objp, uchar_t *buf, ulong_t buf_len)
{
CK_RV rv = CKR_OK;
CK_OBJECT_CLASS class = objp->class;
CK_KEY_TYPE keytype = objp->key_type;
private_key_obj_t *pvk;
switch (class) {
case CKO_PRIVATE_KEY:
if ((pvk = calloc(1, sizeof (private_key_obj_t))) == NULL) {
rv = CKR_HOST_MEMORY;
return (rv);
}
switch (keytype) {
case CKK_RSA:
rv = asn1_to_rsa_pri(pvk, buf, buf_len);
break;
case CKK_DSA:
rv = asn1_to_dsa_pri(pvk, buf, buf_len);
break;
case CKK_DH:
rv = asn1_to_dh_pri(pvk, buf, buf_len);
break;
case CKK_X9_42_DH:
rv = asn1_to_x942_dh_pri(pvk, buf, buf_len);
break;
default:
rv = CKR_FUNCTION_NOT_SUPPORTED;
break;
}
if (rv != CKR_OK)
free(pvk);
else
objp->object_class_u.private_key = pvk;
break;
default:
rv = CKR_FUNCTION_NOT_SUPPORTED;
break;
}
return (rv);
}