2001-11-06 18:34:19 +00:00
|
|
|
/*
|
2002-01-17 11:44:27 +00:00
|
|
|
* pkcs15-prkey.c: PKCS #15 private key functions
|
2001-11-01 15:43:20 +00:00
|
|
|
*
|
2006-12-19 21:31:17 +00:00
|
|
|
* Copyright (C) 2001, 2002 Juha Yrjölä <juha.yrjola@iki.fi>
|
2001-11-06 18:34:19 +00:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
2001-11-01 15:43:20 +00:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
2001-11-06 18:34:19 +00:00
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2001-11-01 15:43:20 +00:00
|
|
|
*
|
2001-11-06 18:34:19 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
2001-11-01 15:43:20 +00:00
|
|
|
*/
|
|
|
|
|
2010-03-04 08:14:36 +00:00
|
|
|
#include "config.h"
|
|
|
|
|
2001-11-01 15:43:20 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
2010-03-04 08:14:36 +00:00
|
|
|
#include "internal.h"
|
|
|
|
#include "asn1.h"
|
|
|
|
#include "pkcs15.h"
|
|
|
|
|
2002-01-17 23:47:03 +00:00
|
|
|
static const struct sc_asn1_entry c_asn1_com_key_attr[] = {
|
2006-01-20 20:52:36 +00:00
|
|
|
{ "iD", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, 0, NULL, NULL },
|
|
|
|
{ "usage", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL },
|
|
|
|
{ "native", SC_ASN1_BOOLEAN, SC_ASN1_TAG_BOOLEAN, SC_ASN1_OPTIONAL, NULL, NULL },
|
|
|
|
{ "accessFlags", SC_ASN1_BIT_FIELD, SC_ASN1_TAG_BIT_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
|
|
|
|
{ "keyReference",SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
|
2010-12-31 10:52:15 +00:00
|
|
|
/* IAS/ECC and ECC(CEN/TS 15480-2:2007) defines 'algReference' member of 'CommonKeyAttributes'.
|
|
|
|
* It's absent in PKCS#15 v1.1 .
|
|
|
|
* Will see if any card will really need it.
|
|
|
|
* { "algReference", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_CTX | 1, SC_ASN1_OPTIONAL, NULL, NULL },
|
|
|
|
*/
|
2005-08-05 07:24:43 +00:00
|
|
|
{ NULL, 0, 0, 0, NULL, NULL }
|
2002-01-17 23:47:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct sc_asn1_entry c_asn1_com_prkey_attr[] = {
|
2010-07-08 08:09:46 +00:00
|
|
|
{ "subjectName", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS,
|
|
|
|
SC_ASN1_EMPTY_ALLOWED | SC_ASN1_ALLOC | SC_ASN1_OPTIONAL, NULL, NULL },
|
2005-08-05 07:24:43 +00:00
|
|
|
{ NULL, 0, 0, 0, NULL, NULL }
|
2002-01-17 23:47:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct sc_asn1_entry c_asn1_rsakey_attr[] = {
|
2011-01-02 14:14:24 +00:00
|
|
|
{ "value", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_EMPTY_ALLOWED, NULL, NULL },
|
2006-01-20 20:52:36 +00:00
|
|
|
{ "modulusLength", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
|
|
|
|
{ "keyInfo", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
|
2005-08-05 07:24:43 +00:00
|
|
|
{ NULL, 0, 0, 0, NULL, NULL }
|
2002-01-17 23:47:03 +00:00
|
|
|
};
|
|
|
|
|
2002-03-15 12:48:06 +00:00
|
|
|
static const struct sc_asn1_entry c_asn1_prk_rsa_attr[] = {
|
2006-01-20 20:52:36 +00:00
|
|
|
{ "privateRSAKeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
|
2005-08-05 07:24:43 +00:00
|
|
|
{ NULL, 0, 0, 0, NULL, NULL }
|
2002-01-17 23:47:03 +00:00
|
|
|
};
|
|
|
|
|
2009-10-05 20:10:07 +00:00
|
|
|
static const struct sc_asn1_entry c_asn1_gostr3410key_attr[] = {
|
|
|
|
{ "value", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
|
|
|
|
{ "params_r3410", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
|
|
|
|
{ "params_r3411", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
|
|
|
|
{ "params_28147", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, SC_ASN1_OPTIONAL, NULL, NULL },
|
|
|
|
{ NULL, 0, 0, 0, NULL, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
static const struct sc_asn1_entry c_asn1_prk_gostr3410_attr[] = {
|
|
|
|
{ "privateGOSTR3410KeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
|
|
|
|
{ NULL, 0, 0, 0, NULL, NULL }
|
|
|
|
};
|
|
|
|
|
2002-04-17 08:58:57 +00:00
|
|
|
static const struct sc_asn1_entry c_asn1_dsakey_i_p_attr[] = {
|
2006-01-20 20:52:36 +00:00
|
|
|
{ "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
|
2005-08-05 07:24:43 +00:00
|
|
|
{ NULL, 0, 0, 0, NULL, NULL }
|
2002-04-17 08:58:57 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct sc_asn1_entry c_asn1_dsakey_value_attr[] = {
|
2006-01-20 20:52:36 +00:00
|
|
|
{ "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
|
2005-08-05 07:24:43 +00:00
|
|
|
{ "pathProtected",SC_ASN1_STRUCT, SC_ASN1_CTX | 1 | SC_ASN1_CONS, 0, NULL, NULL},
|
|
|
|
{ NULL, 0, 0, 0, NULL, NULL }
|
2002-04-17 08:58:57 +00:00
|
|
|
};
|
|
|
|
|
2002-03-15 12:48:06 +00:00
|
|
|
static const struct sc_asn1_entry c_asn1_dsakey_attr[] = {
|
2005-08-05 07:24:43 +00:00
|
|
|
{ "value", SC_ASN1_CHOICE, 0, 0, NULL, NULL },
|
|
|
|
{ NULL, 0, 0, 0, NULL, NULL }
|
2002-03-15 12:48:06 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct sc_asn1_entry c_asn1_prk_dsa_attr[] = {
|
2006-01-20 20:52:36 +00:00
|
|
|
{ "privateDSAKeyAttributes", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
|
2005-08-05 07:24:43 +00:00
|
|
|
{ NULL, 0, 0, 0, NULL, NULL }
|
2002-03-15 12:48:06 +00:00
|
|
|
};
|
|
|
|
|
2002-01-17 23:47:03 +00:00
|
|
|
static const struct sc_asn1_entry c_asn1_prkey[] = {
|
2006-01-20 20:52:36 +00:00
|
|
|
{ "privateRSAKey", SC_ASN1_PKCS15_OBJECT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
|
2005-08-05 07:24:43 +00:00
|
|
|
{ "privateDSAKey", SC_ASN1_PKCS15_OBJECT, 2 | SC_ASN1_CTX | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
|
2009-10-05 20:10:07 +00:00
|
|
|
{ "privateGOSTR3410Key", SC_ASN1_PKCS15_OBJECT, 3 | SC_ASN1_CTX | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
|
2005-08-05 07:24:43 +00:00
|
|
|
{ NULL, 0, 0, 0, NULL, NULL }
|
2009-10-05 20:10:07 +00:00
|
|
|
};
|
2002-01-17 23:47:03 +00:00
|
|
|
|
2002-01-24 16:02:54 +00:00
|
|
|
int sc_pkcs15_decode_prkdf_entry(struct sc_pkcs15_card *p15card,
|
|
|
|
struct sc_pkcs15_object *obj,
|
|
|
|
const u8 ** buf, size_t *buflen)
|
2001-11-01 15:43:20 +00:00
|
|
|
{
|
2005-03-08 20:59:35 +00:00
|
|
|
sc_context_t *ctx = p15card->card->ctx;
|
2002-01-24 16:02:54 +00:00
|
|
|
struct sc_pkcs15_prkey_info info;
|
2009-10-05 20:10:07 +00:00
|
|
|
int r, gostr3410_params[3];
|
|
|
|
struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams;
|
2002-05-26 12:31:23 +00:00
|
|
|
size_t usage_len = sizeof(info.usage);
|
|
|
|
size_t af_len = sizeof(info.access_flags);
|
2010-07-05 13:29:10 +00:00
|
|
|
struct sc_asn1_entry asn1_com_key_attr[6], asn1_com_prkey_attr[2];
|
2002-03-15 12:48:06 +00:00
|
|
|
struct sc_asn1_entry asn1_rsakey_attr[4], asn1_prk_rsa_attr[2];
|
2002-04-17 08:58:57 +00:00
|
|
|
struct sc_asn1_entry asn1_dsakey_attr[2], asn1_prk_dsa_attr[2],
|
|
|
|
asn1_dsakey_i_p_attr[2],
|
|
|
|
asn1_dsakey_value_attr[3];
|
2009-10-05 20:10:07 +00:00
|
|
|
struct sc_asn1_entry asn1_gostr3410key_attr[5], asn1_prk_gostr3410_attr[2];
|
|
|
|
struct sc_asn1_entry asn1_prkey[4];
|
2002-03-15 12:48:06 +00:00
|
|
|
struct sc_asn1_pkcs15_object rsa_prkey_obj = { obj, asn1_com_key_attr,
|
|
|
|
asn1_com_prkey_attr, asn1_prk_rsa_attr };
|
|
|
|
struct sc_asn1_pkcs15_object dsa_prkey_obj = { obj, asn1_com_key_attr,
|
|
|
|
asn1_com_prkey_attr, asn1_prk_dsa_attr };
|
2009-10-05 20:10:07 +00:00
|
|
|
struct sc_asn1_pkcs15_object gostr3410_prkey_obj = { obj, asn1_com_key_attr,
|
|
|
|
asn1_com_prkey_attr,
|
|
|
|
asn1_prk_gostr3410_attr };
|
2001-12-21 23:34:47 +00:00
|
|
|
|
2009-10-05 20:10:07 +00:00
|
|
|
sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey);
|
2002-03-15 12:48:06 +00:00
|
|
|
|
2009-10-05 20:10:07 +00:00
|
|
|
sc_copy_asn1_entry(c_asn1_prk_rsa_attr, asn1_prk_rsa_attr);
|
|
|
|
sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr);
|
|
|
|
sc_copy_asn1_entry(c_asn1_prk_dsa_attr, asn1_prk_dsa_attr);
|
|
|
|
sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr);
|
2002-04-17 08:58:57 +00:00
|
|
|
sc_copy_asn1_entry(c_asn1_dsakey_value_attr, asn1_dsakey_value_attr);
|
2009-10-05 20:10:07 +00:00
|
|
|
sc_copy_asn1_entry(c_asn1_dsakey_i_p_attr, asn1_dsakey_i_p_attr);
|
|
|
|
sc_copy_asn1_entry(c_asn1_prk_gostr3410_attr, asn1_prk_gostr3410_attr);
|
|
|
|
sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr);
|
2002-03-15 12:48:06 +00:00
|
|
|
|
2009-10-05 20:10:07 +00:00
|
|
|
sc_copy_asn1_entry(c_asn1_com_prkey_attr, asn1_com_prkey_attr);
|
|
|
|
sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr);
|
2002-01-17 23:47:03 +00:00
|
|
|
|
2002-03-15 12:48:06 +00:00
|
|
|
sc_format_asn1_entry(asn1_prkey + 0, &rsa_prkey_obj, NULL, 0);
|
|
|
|
sc_format_asn1_entry(asn1_prkey + 1, &dsa_prkey_obj, NULL, 0);
|
2009-10-05 20:10:07 +00:00
|
|
|
sc_format_asn1_entry(asn1_prkey + 2, &gostr3410_prkey_obj, NULL, 0);
|
2002-01-17 23:47:03 +00:00
|
|
|
|
2002-03-15 12:48:06 +00:00
|
|
|
sc_format_asn1_entry(asn1_prk_rsa_attr + 0, asn1_rsakey_attr, NULL, 0);
|
|
|
|
sc_format_asn1_entry(asn1_prk_dsa_attr + 0, asn1_dsakey_attr, NULL, 0);
|
2009-10-05 20:10:07 +00:00
|
|
|
sc_format_asn1_entry(asn1_prk_gostr3410_attr + 0, asn1_gostr3410key_attr, NULL, 0);
|
2002-01-17 23:47:03 +00:00
|
|
|
|
2002-01-24 16:02:54 +00:00
|
|
|
sc_format_asn1_entry(asn1_rsakey_attr + 0, &info.path, NULL, 0);
|
|
|
|
sc_format_asn1_entry(asn1_rsakey_attr + 1, &info.modulus_length, NULL, 0);
|
2002-01-17 23:47:03 +00:00
|
|
|
|
2002-04-17 08:58:57 +00:00
|
|
|
sc_format_asn1_entry(asn1_dsakey_attr + 0, asn1_dsakey_value_attr, NULL, 0);
|
|
|
|
sc_format_asn1_entry(asn1_dsakey_value_attr + 0, &info.path, NULL, 0);
|
|
|
|
sc_format_asn1_entry(asn1_dsakey_value_attr + 1, asn1_dsakey_i_p_attr, NULL, 0);
|
|
|
|
sc_format_asn1_entry(asn1_dsakey_i_p_attr + 0, &info.path, NULL, 0);
|
|
|
|
|
2009-10-05 20:10:07 +00:00
|
|
|
sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &info.path, NULL, 0);
|
|
|
|
sc_format_asn1_entry(asn1_gostr3410key_attr + 1, &gostr3410_params[0], NULL, 0);
|
|
|
|
sc_format_asn1_entry(asn1_gostr3410key_attr + 2, &gostr3410_params[1], NULL, 0);
|
|
|
|
sc_format_asn1_entry(asn1_gostr3410key_attr + 3, &gostr3410_params[2], NULL, 0);
|
2002-03-15 12:48:06 +00:00
|
|
|
|
2002-01-24 16:02:54 +00:00
|
|
|
sc_format_asn1_entry(asn1_com_key_attr + 0, &info.id, NULL, 0);
|
|
|
|
sc_format_asn1_entry(asn1_com_key_attr + 1, &info.usage, &usage_len, 0);
|
|
|
|
sc_format_asn1_entry(asn1_com_key_attr + 2, &info.native, NULL, 0);
|
|
|
|
sc_format_asn1_entry(asn1_com_key_attr + 3, &info.access_flags, &af_len, 0);
|
|
|
|
sc_format_asn1_entry(asn1_com_key_attr + 4, &info.key_reference, NULL, 0);
|
2002-01-17 23:47:03 +00:00
|
|
|
|
2010-07-05 13:29:10 +00:00
|
|
|
sc_format_asn1_entry(asn1_com_prkey_attr + 0, &info.subject.value, &info.subject.len, 0);
|
|
|
|
|
2002-01-17 23:47:03 +00:00
|
|
|
/* Fill in defaults */
|
2002-01-24 16:02:54 +00:00
|
|
|
memset(&info, 0, sizeof(info));
|
|
|
|
info.key_reference = -1;
|
|
|
|
info.native = 1;
|
2009-10-05 20:10:07 +00:00
|
|
|
memset(gostr3410_params, 0, sizeof(gostr3410_params));
|
2001-12-21 23:34:47 +00:00
|
|
|
|
2002-03-15 12:48:06 +00:00
|
|
|
r = sc_asn1_decode_choice(ctx, asn1_prkey, *buf, *buflen, buf, buflen);
|
2002-01-24 16:02:54 +00:00
|
|
|
if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
|
|
|
|
return r;
|
2010-03-15 12:17:13 +00:00
|
|
|
SC_TEST_RET(ctx, SC_LOG_DEBUG_NORMAL, r, "ASN.1 decoding failed");
|
2003-11-19 20:29:54 +00:00
|
|
|
if (asn1_prkey[0].flags & SC_ASN1_PRESENT) {
|
2002-03-15 12:48:06 +00:00
|
|
|
obj->type = SC_PKCS15_TYPE_PRKEY_RSA;
|
2003-11-19 20:29:54 +00:00
|
|
|
} else if (asn1_prkey[1].flags & SC_ASN1_PRESENT) {
|
2002-03-15 12:48:06 +00:00
|
|
|
obj->type = SC_PKCS15_TYPE_PRKEY_DSA;
|
2002-04-17 08:58:57 +00:00
|
|
|
/* If the value was indirect-protected, mark the path */
|
|
|
|
if (asn1_dsakey_i_p_attr[0].flags & SC_ASN1_PRESENT)
|
|
|
|
info.path.type = SC_PATH_TYPE_PATH_PROT;
|
2009-10-05 20:10:07 +00:00
|
|
|
} else if (asn1_prkey[2].flags & SC_ASN1_PRESENT) {
|
|
|
|
obj->type = SC_PKCS15_TYPE_PRKEY_GOSTR3410;
|
|
|
|
assert(info.modulus_length == 0);
|
|
|
|
info.modulus_length = SC_PKCS15_GOSTR3410_KEYSIZE;
|
2011-05-01 19:18:14 +00:00
|
|
|
assert(info.params.len == 0);
|
|
|
|
info.params.len = sizeof(struct sc_pkcs15_keyinfo_gostparams);
|
|
|
|
info.params.data = malloc(info.params.len);
|
|
|
|
if (info.params.data == NULL)
|
2010-03-15 12:17:13 +00:00
|
|
|
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
|
2011-05-01 19:18:14 +00:00
|
|
|
assert(sizeof(*keyinfo_gostparams) == info.params.len);
|
|
|
|
keyinfo_gostparams = info.params.data;
|
2009-10-05 20:10:07 +00:00
|
|
|
keyinfo_gostparams->gostr3410 = gostr3410_params[0];
|
|
|
|
keyinfo_gostparams->gostr3411 = gostr3410_params[1];
|
|
|
|
keyinfo_gostparams->gost28147 = gostr3410_params[2];
|
2003-11-19 20:29:54 +00:00
|
|
|
} else {
|
2010-09-25 20:35:59 +00:00
|
|
|
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Neither RSA or DSA or GOSTR3410 key in PrKDF entry.");
|
2010-03-15 12:17:13 +00:00
|
|
|
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INVALID_ASN1_OBJECT);
|
2003-11-19 20:29:54 +00:00
|
|
|
}
|
2011-01-18 16:31:41 +00:00
|
|
|
|
|
|
|
if (!p15card->app || !p15card->app->ddo.aid.len) {
|
|
|
|
r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &info.path);
|
|
|
|
if (r < 0) {
|
2011-05-01 19:18:14 +00:00
|
|
|
sc_pkcs15_free_key_params(&info.params);
|
2011-01-18 16:31:41 +00:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
info.path.aid = p15card->app->ddo.aid;
|
2009-10-05 20:10:07 +00:00
|
|
|
}
|
2011-01-18 16:31:41 +00:00
|
|
|
sc_debug(ctx, SC_LOG_DEBUG_ASN1, "PrivKey path '%s'", sc_print_path(&info.path));
|
2009-12-18 13:33:03 +00:00
|
|
|
|
|
|
|
/* OpenSC 0.11.4 and older encoded "keyReference" as a negative
|
|
|
|
value. Fixed in 0.11.5 we need to add a hack, so old cards
|
|
|
|
continue to work. */
|
2011-03-06 12:35:35 +00:00
|
|
|
if (info.key_reference < -1)
|
|
|
|
info.key_reference += 256;
|
2009-12-18 13:33:03 +00:00
|
|
|
|
2002-01-24 16:02:54 +00:00
|
|
|
obj->data = malloc(sizeof(info));
|
2009-10-05 20:10:07 +00:00
|
|
|
if (obj->data == NULL) {
|
2011-05-01 19:18:14 +00:00
|
|
|
sc_pkcs15_free_key_params(&info.params);
|
2010-03-15 12:17:13 +00:00
|
|
|
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_OUT_OF_MEMORY);
|
2009-10-05 20:10:07 +00:00
|
|
|
}
|
2002-01-24 16:02:54 +00:00
|
|
|
memcpy(obj->data, &info, sizeof(info));
|
|
|
|
|
|
|
|
return 0;
|
2001-12-21 23:34:47 +00:00
|
|
|
}
|
2002-03-15 12:48:06 +00:00
|
|
|
|
2005-03-08 20:59:35 +00:00
|
|
|
int sc_pkcs15_encode_prkdf_entry(sc_context_t *ctx,
|
2002-01-17 23:47:03 +00:00
|
|
|
const struct sc_pkcs15_object *obj,
|
|
|
|
u8 **buf, size_t *buflen)
|
|
|
|
{
|
2010-07-05 13:29:10 +00:00
|
|
|
struct sc_asn1_entry asn1_com_key_attr[6], asn1_com_prkey_attr[2];
|
2002-03-15 12:48:06 +00:00
|
|
|
struct sc_asn1_entry asn1_rsakey_attr[4], asn1_prk_rsa_attr[2];
|
2002-04-17 08:58:57 +00:00
|
|
|
struct sc_asn1_entry asn1_dsakey_attr[2], asn1_prk_dsa_attr[2],
|
|
|
|
asn1_dsakey_value_attr[3],
|
|
|
|
asn1_dsakey_i_p_attr[2];
|
2009-10-05 20:10:07 +00:00
|
|
|
struct sc_asn1_entry asn1_gostr3410key_attr[5], asn1_prk_gostr3410_attr[2];
|
|
|
|
struct sc_asn1_entry asn1_prkey[4];
|
2002-03-15 12:48:06 +00:00
|
|
|
struct sc_asn1_pkcs15_object rsa_prkey_obj = { (struct sc_pkcs15_object *) obj, asn1_com_key_attr,
|
|
|
|
asn1_com_prkey_attr, asn1_prk_rsa_attr };
|
|
|
|
struct sc_asn1_pkcs15_object dsa_prkey_obj = { (struct sc_pkcs15_object *) obj, asn1_com_key_attr,
|
|
|
|
asn1_com_prkey_attr, asn1_prk_dsa_attr };
|
2009-10-05 20:10:07 +00:00
|
|
|
struct sc_asn1_pkcs15_object gostr3410_prkey_obj = { (struct sc_pkcs15_object *) obj,
|
|
|
|
asn1_com_key_attr, asn1_com_prkey_attr,
|
|
|
|
asn1_prk_gostr3410_attr };
|
2002-01-17 23:47:03 +00:00
|
|
|
struct sc_pkcs15_prkey_info *prkey =
|
|
|
|
(struct sc_pkcs15_prkey_info *) obj->data;
|
2009-10-05 20:10:07 +00:00
|
|
|
struct sc_pkcs15_keyinfo_gostparams *keyinfo_gostparams;
|
2002-01-17 23:47:03 +00:00
|
|
|
int r;
|
2002-05-26 12:31:23 +00:00
|
|
|
size_t af_len, usage_len;
|
2002-01-17 23:47:03 +00:00
|
|
|
|
2009-10-05 20:10:07 +00:00
|
|
|
sc_copy_asn1_entry(c_asn1_prkey, asn1_prkey);
|
2002-03-15 12:48:06 +00:00
|
|
|
|
2009-10-05 20:10:07 +00:00
|
|
|
sc_copy_asn1_entry(c_asn1_prk_rsa_attr, asn1_prk_rsa_attr);
|
|
|
|
sc_copy_asn1_entry(c_asn1_rsakey_attr, asn1_rsakey_attr);
|
|
|
|
sc_copy_asn1_entry(c_asn1_prk_dsa_attr, asn1_prk_dsa_attr);
|
|
|
|
sc_copy_asn1_entry(c_asn1_dsakey_attr, asn1_dsakey_attr);
|
2002-04-17 08:58:57 +00:00
|
|
|
sc_copy_asn1_entry(c_asn1_dsakey_value_attr, asn1_dsakey_value_attr);
|
|
|
|
sc_copy_asn1_entry(c_asn1_dsakey_i_p_attr, asn1_dsakey_i_p_attr);
|
2009-10-05 20:10:07 +00:00
|
|
|
sc_copy_asn1_entry(c_asn1_prk_gostr3410_attr, asn1_prk_gostr3410_attr);
|
|
|
|
sc_copy_asn1_entry(c_asn1_gostr3410key_attr, asn1_gostr3410key_attr);
|
2002-03-15 12:48:06 +00:00
|
|
|
|
2009-10-05 20:10:07 +00:00
|
|
|
sc_copy_asn1_entry(c_asn1_com_prkey_attr, asn1_com_prkey_attr);
|
|
|
|
sc_copy_asn1_entry(c_asn1_com_key_attr, asn1_com_key_attr);
|
2002-01-17 23:47:03 +00:00
|
|
|
|
2002-03-15 12:48:06 +00:00
|
|
|
switch (obj->type) {
|
|
|
|
case SC_PKCS15_TYPE_PRKEY_RSA:
|
|
|
|
sc_format_asn1_entry(asn1_prkey + 0, &rsa_prkey_obj, NULL, 1);
|
|
|
|
sc_format_asn1_entry(asn1_prk_rsa_attr + 0, asn1_rsakey_attr, NULL, 1);
|
|
|
|
sc_format_asn1_entry(asn1_rsakey_attr + 0, &prkey->path, NULL, 1);
|
|
|
|
sc_format_asn1_entry(asn1_rsakey_attr + 1, &prkey->modulus_length, NULL, 1);
|
|
|
|
break;
|
|
|
|
case SC_PKCS15_TYPE_PRKEY_DSA:
|
|
|
|
sc_format_asn1_entry(asn1_prkey + 1, &dsa_prkey_obj, NULL, 1);
|
2007-06-21 10:07:01 +00:00
|
|
|
sc_format_asn1_entry(asn1_prk_dsa_attr + 0, asn1_dsakey_value_attr, NULL, 1);
|
2002-04-17 08:58:57 +00:00
|
|
|
if (prkey->path.type != SC_PATH_TYPE_PATH_PROT) {
|
|
|
|
/* indirect: just add the path */
|
|
|
|
sc_format_asn1_entry(asn1_dsakey_value_attr + 0,
|
|
|
|
&prkey->path, NULL, 1);
|
|
|
|
} else {
|
|
|
|
/* indirect-protected */
|
|
|
|
sc_format_asn1_entry(asn1_dsakey_value_attr + 1,
|
|
|
|
asn1_dsakey_i_p_attr, NULL, 1);
|
|
|
|
sc_format_asn1_entry(asn1_dsakey_i_p_attr + 0,
|
|
|
|
&prkey->path, NULL, 1);
|
|
|
|
}
|
2002-03-15 12:48:06 +00:00
|
|
|
break;
|
2009-10-05 20:10:07 +00:00
|
|
|
case SC_PKCS15_TYPE_PRKEY_GOSTR3410:
|
|
|
|
sc_format_asn1_entry(asn1_prkey + 2, &gostr3410_prkey_obj, NULL, 1);
|
|
|
|
sc_format_asn1_entry(asn1_prk_gostr3410_attr + 0, asn1_gostr3410key_attr, NULL, 1);
|
|
|
|
sc_format_asn1_entry(asn1_gostr3410key_attr + 0, &prkey->path, NULL, 1);
|
2011-05-01 19:18:14 +00:00
|
|
|
if (prkey->params.len == sizeof(*keyinfo_gostparams))
|
2009-10-05 20:10:07 +00:00
|
|
|
{
|
2011-05-01 19:18:14 +00:00
|
|
|
keyinfo_gostparams = prkey->params.data;
|
2009-10-05 20:10:07 +00:00
|
|
|
sc_format_asn1_entry(asn1_gostr3410key_attr + 1,
|
|
|
|
&keyinfo_gostparams->gostr3410, NULL, 1);
|
|
|
|
sc_format_asn1_entry(asn1_gostr3410key_attr + 2,
|
|
|
|
&keyinfo_gostparams->gostr3411, NULL, 1);
|
|
|
|
sc_format_asn1_entry(asn1_gostr3410key_attr + 3,
|
|
|
|
&keyinfo_gostparams->gost28147, NULL, 1);
|
|
|
|
}
|
|
|
|
break;
|
2002-03-15 12:48:06 +00:00
|
|
|
default:
|
2010-09-25 20:35:59 +00:00
|
|
|
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Invalid private key type: %X", obj->type);
|
2010-03-15 12:17:13 +00:00
|
|
|
SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_NORMAL, SC_ERROR_INTERNAL);
|
2002-03-15 12:48:06 +00:00
|
|
|
break;
|
|
|
|
}
|
2002-01-17 23:47:03 +00:00
|
|
|
sc_format_asn1_entry(asn1_com_key_attr + 0, &prkey->id, NULL, 1);
|
2003-04-16 20:52:26 +00:00
|
|
|
usage_len = sizeof(prkey->usage);
|
2002-01-17 23:47:03 +00:00
|
|
|
sc_format_asn1_entry(asn1_com_key_attr + 1, &prkey->usage, &usage_len, 1);
|
|
|
|
if (prkey->native == 0)
|
|
|
|
sc_format_asn1_entry(asn1_com_key_attr + 2, &prkey->native, NULL, 1);
|
|
|
|
if (prkey->access_flags) {
|
2003-04-16 20:52:26 +00:00
|
|
|
af_len = sizeof(prkey->access_flags);
|
2002-01-17 23:47:03 +00:00
|
|
|
sc_format_asn1_entry(asn1_com_key_attr + 3, &prkey->access_flags, &af_len, 1);
|
|
|
|
}
|
|
|
|
if (prkey->key_reference >= 0)
|
|
|
|
sc_format_asn1_entry(asn1_com_key_attr + 4, &prkey->key_reference, NULL, 1);
|
2010-07-05 13:29:10 +00:00
|
|
|
|
|
|
|
sc_format_asn1_entry(asn1_com_prkey_attr + 0, prkey->subject.value, &prkey->subject.len, prkey->subject.len != 0);
|
|
|
|
|
2002-01-17 23:47:03 +00:00
|
|
|
r = sc_asn1_encode(ctx, asn1_prkey, buf, buflen);
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
2002-04-17 08:58:57 +00:00
|
|
|
|
2011-05-28 22:14:07 +00:00
|
|
|
static void
|
2002-04-18 10:58:11 +00:00
|
|
|
sc_pkcs15_erase_prkey(struct sc_pkcs15_prkey *key)
|
|
|
|
{
|
|
|
|
assert(key != NULL);
|
|
|
|
switch (key->algorithm) {
|
|
|
|
case SC_ALGORITHM_RSA:
|
|
|
|
free(key->u.rsa.modulus.data);
|
|
|
|
free(key->u.rsa.exponent.data);
|
2010-02-12 16:53:07 +00:00
|
|
|
free(key->u.rsa.d.data);
|
2002-04-18 10:58:11 +00:00
|
|
|
free(key->u.rsa.p.data);
|
|
|
|
free(key->u.rsa.q.data);
|
|
|
|
free(key->u.rsa.iqmp.data);
|
|
|
|
free(key->u.rsa.dmp1.data);
|
|
|
|
free(key->u.rsa.dmq1.data);
|
|
|
|
break;
|
|
|
|
case SC_ALGORITHM_DSA:
|
|
|
|
free(key->u.dsa.pub.data);
|
|
|
|
free(key->u.dsa.p.data);
|
|
|
|
free(key->u.dsa.q.data);
|
|
|
|
free(key->u.dsa.g.data);
|
|
|
|
free(key->u.dsa.priv.data);
|
|
|
|
break;
|
2009-10-05 20:10:07 +00:00
|
|
|
case SC_ALGORITHM_GOSTR3410:
|
|
|
|
assert(key->u.gostr3410.d.data);
|
|
|
|
free(key->u.gostr3410.d.data);
|
|
|
|
break;
|
2010-12-01 20:08:42 +00:00
|
|
|
case SC_ALGORITHM_EC:
|
|
|
|
/* TODO: -DEE may not need much */
|
|
|
|
break;
|
2002-04-18 10:58:11 +00:00
|
|
|
}
|
2005-09-17 10:44:45 +00:00
|
|
|
sc_mem_clear(key, sizeof(key));
|
2002-04-18 10:58:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
sc_pkcs15_free_prkey(struct sc_pkcs15_prkey *key)
|
|
|
|
{
|
|
|
|
sc_pkcs15_erase_prkey(key);
|
|
|
|
free(key);
|
|
|
|
}
|
2004-12-18 14:14:57 +00:00
|
|
|
|
|
|
|
void sc_pkcs15_free_prkey_info(sc_pkcs15_prkey_info_t *key)
|
|
|
|
{
|
2010-07-05 13:29:10 +00:00
|
|
|
if (key->subject.value)
|
|
|
|
free(key->subject.value);
|
2011-05-01 19:18:14 +00:00
|
|
|
|
|
|
|
sc_pkcs15_free_key_params(&key->params);
|
|
|
|
|
2004-12-18 14:14:57 +00:00
|
|
|
free(key);
|
|
|
|
}
|