libopensc: remove more traces of software token/non-native private key related code.

pkcs15-wrap.c can be removed. Clarified/changed the meaning of "insecure" flag to pkcs15-init tool,
which will be needed to explicitly enforce the creation of a key which does not require a PIN.

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@5510 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
martin 2011-05-28 22:14:07 +00:00
parent 7179778e22
commit 215c133ba0
10 changed files with 18 additions and 664 deletions

View File

@ -145,10 +145,6 @@
<para>
<command>pkcs15-init --store-private-key okir.pem --id 45 --auth-id 01</command>
</para>
<para>
If the key is protected by a pass phrase, <command>pkcs15-init</command>
will prompt you for a pass phrase to unlock the key.
</para>
<para>
In addition to storing the private portion of the key on the card,
<command>pkcs15-init</command> will also store the the public portion of the
@ -397,17 +393,6 @@
</listitem>
</varlistentry>
<varlistentry>
<term><option>--passphrase</option></term>
<listitem>
<para>
When downloading a private key, this option can be used to specify
the pass phrase to unlock the private key. The same caveat applies
here as in the case of the <option>--pin</option> options.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--options-file</option> <emphasis>filename</emphasis></term>
<listitem>

View File

@ -24,8 +24,7 @@ libopensc_la_SOURCES = \
\
pkcs15.c pkcs15-cert.c pkcs15-data.c pkcs15-pin.c \
pkcs15-prkey.c pkcs15-pubkey.c pkcs15-sec.c \
pkcs15-wrap.c pkcs15-algo.c pkcs15-cache.c pkcs15-syn.c \
pkcs15-gemsafeV1.c \
pkcs15-algo.c pkcs15-cache.c pkcs15-syn.c \
\
muscle.c muscle-filesystem.c \
\
@ -45,7 +44,7 @@ libopensc_la_SOURCES = \
pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.c pkcs15-gemsafeGPK.c \
pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \
pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c pkcs15-oberthur.c \
pkcs15-itacns.c \
pkcs15-itacns.c pkcs15-gemsafeV1.c \
compression.c p15card-helper.c \
libopensc.exports
if WIN32

View File

@ -7,8 +7,7 @@ OBJECTS = \
\
pkcs15.obj pkcs15-cert.obj pkcs15-data.obj pkcs15-pin.obj \
pkcs15-prkey.obj pkcs15-pubkey.obj pkcs15-sec.obj \
pkcs15-wrap.obj pkcs15-algo.obj pkcs15-cache.obj pkcs15-syn.obj \
pkcs15-gemsafeV1.obj \
pkcs15-algo.obj pkcs15-cache.obj pkcs15-syn.obj \
\
muscle.obj muscle-filesystem.obj \
\
@ -28,7 +27,7 @@ OBJECTS = \
pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj pkcs15-gemsafeGPK.obj \
pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \
pkcs15-esinit.obj pkcs15-westcos.obj pkcs15-pteid.obj pkcs15-oberthur.obj \
pkcs15-itacns.obj \
pkcs15-itacns.obj pkcs15-gemsafeV1.obj \
compression.obj p15card-helper.obj \
$(TOPDIR)\win32\versioninfo.res

View File

@ -137,9 +137,7 @@ sc_pkcs15_decipher
sc_pkcs15_decode_aodf_entry
sc_pkcs15_decode_cdf_entry
sc_pkcs15_decode_dodf_entry
sc_pkcs15_decode_enveloped_data
sc_pkcs15_decode_prkdf_entry
sc_pkcs15_decode_prkey
sc_pkcs15_decode_pubkey
sc_pkcs15_decode_pubkey_dsa
sc_pkcs15_decode_pubkey_rsa
@ -150,10 +148,8 @@ sc_pkcs15_encode_aodf_entry
sc_pkcs15_encode_cdf_entry
sc_pkcs15_encode_df
sc_pkcs15_encode_dodf_entry
sc_pkcs15_encode_enveloped_data
sc_pkcs15_encode_odf
sc_pkcs15_encode_prkdf_entry
sc_pkcs15_encode_prkey
sc_pkcs15_encode_pubkey
sc_pkcs15_encode_pubkey_dsa
sc_pkcs15_encode_pubkey_rsa
@ -162,7 +158,6 @@ sc_pkcs15_encode_pubkey_gostr3410
sc_pkcs15_encode_pukdf_entry
sc_pkcs15_encode_tokeninfo
sc_pkcs15_encode_unusedspace
sc_pkcs15_erase_prkey
sc_pkcs15_erase_pubkey
sc_pkcs15_find_cert_by_id
sc_pkcs15_find_data_object_by_app_oid
@ -205,7 +200,6 @@ sc_pkcs15_read_cached_file
sc_pkcs15_read_certificate
sc_pkcs15_read_data_object
sc_pkcs15_read_file
sc_pkcs15_read_prkey
sc_pkcs15_read_pubkey
sc_pkcs15_pubkey_from_prvkey
sc_pkcs15_pubkey_from_cert
@ -215,9 +209,7 @@ sc_pkcs15_remove_unusedspace
sc_pkcs15_search_objects
sc_pkcs15_unbind
sc_pkcs15_unblock_pin
sc_pkcs15_unwrap_data
sc_pkcs15_verify_pin
sc_pkcs15_wrap_data
sc_pkcs15emu_add_data_object
sc_pkcs15emu_add_pin_obj
sc_pkcs15emu_add_rsa_prkey

View File

@ -333,152 +333,7 @@ int sc_pkcs15_encode_prkdf_entry(sc_context_t *ctx,
return r;
}
/*
* Store private keys on the card, encrypted
*/
static const struct sc_asn1_entry c_asn1_dsa_prkey_obj[] = {
{ "privateKey", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_INTEGER, SC_ASN1_ALLOC, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
static int
sc_pkcs15_encode_prkey_dsa(sc_context_t *ctx,
struct sc_pkcs15_prkey_dsa *key,
u8 **buf, size_t *buflen)
{
struct sc_asn1_entry asn1_dsa_prkey_obj[2];
sc_copy_asn1_entry(c_asn1_dsa_prkey_obj, asn1_dsa_prkey_obj);
sc_format_asn1_entry(asn1_dsa_prkey_obj + 0,
key->priv.data, &key->priv.len, 1);
return sc_asn1_encode(ctx, asn1_dsa_prkey_obj, buf, buflen);
}
static int
sc_pkcs15_decode_prkey_dsa(sc_context_t *ctx,
struct sc_pkcs15_prkey_dsa *key,
const u8 *buf, size_t buflen)
{
struct sc_asn1_entry asn1_dsa_prkey_obj[2];
sc_copy_asn1_entry(c_asn1_dsa_prkey_obj, asn1_dsa_prkey_obj);
sc_format_asn1_entry(asn1_dsa_prkey_obj + 0,
&key->priv.data, &key->priv.len, 0);
return sc_asn1_decode(ctx, asn1_dsa_prkey_obj, buf, buflen, NULL, NULL);
}
int
sc_pkcs15_encode_prkey(sc_context_t *ctx,
struct sc_pkcs15_prkey *key,
u8 **buf, size_t *len)
{
if (key->algorithm == SC_ALGORITHM_DSA)
return sc_pkcs15_encode_prkey_dsa(ctx, &key->u.dsa, buf, len);
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Cannot encode private key type %u.",
key->algorithm);
return SC_ERROR_NOT_SUPPORTED;
}
int
sc_pkcs15_decode_prkey(sc_context_t *ctx,
struct sc_pkcs15_prkey *key,
const u8 *buf, size_t len)
{
if (key->algorithm == SC_ALGORITHM_DSA)
return sc_pkcs15_decode_prkey_dsa(ctx, &key->u.dsa, buf, len);
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Cannot decode private key type %u.",
key->algorithm);
return SC_ERROR_NOT_SUPPORTED;
}
int
sc_pkcs15_read_prkey(struct sc_pkcs15_card *p15card,
const struct sc_pkcs15_object *obj,
const char *passphrase,
struct sc_pkcs15_prkey **out)
{
sc_context_t *ctx = p15card->card->ctx;
struct sc_pkcs15_prkey_info *info;
struct sc_pkcs15_prkey key;
sc_path_t path;
u8 *data = NULL;
size_t len;
int r;
memset(&key, 0, sizeof(key));
switch (obj->type) {
case SC_PKCS15_TYPE_PRKEY_RSA:
key.algorithm = SC_ALGORITHM_RSA;
break;
case SC_PKCS15_TYPE_PRKEY_DSA:
key.algorithm = SC_ALGORITHM_DSA;
break;
default:
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unsupported object type.");
return SC_ERROR_NOT_SUPPORTED;
}
info = (struct sc_pkcs15_prkey_info *) obj->data;
if (info->native) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Private key is native, will not read.");
return SC_ERROR_NOT_ALLOWED;
}
path = info->path;
if (path.type == SC_PATH_TYPE_PATH_PROT)
path.type = SC_PATH_TYPE_PATH;
r = sc_pkcs15_read_file(p15card, &path, &data, &len, NULL);
if (r < 0) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to read private key file.");
return r;
}
/* Is this a protected file? */
if (info->path.type == SC_PATH_TYPE_PATH_PROT) {
u8 *clear;
size_t clear_len;
if (passphrase == NULL) {
r = SC_ERROR_PASSPHRASE_REQUIRED;
goto fail;
}
r = sc_pkcs15_unwrap_data(ctx,
passphrase,
data, len,
&clear, &clear_len);
if (r < 0) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Failed to unwrap privat key.");
goto fail;
}
free(data);
data = clear;
len = clear_len;
}
r = sc_pkcs15_decode_prkey(ctx, &key, data, len);
if (r < 0) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unable to decode private key");
goto fail;
}
*out = malloc(sizeof(key));
if (*out == NULL) {
r = SC_ERROR_OUT_OF_MEMORY;
goto fail;
}
**out = key;
free(data);
return 0;
fail: if (data)
free(data);
return r;
}
void
static void
sc_pkcs15_erase_prkey(struct sc_pkcs15_prkey *key)
{
assert(key != NULL);

View File

@ -1,407 +0,0 @@
/*
* pkcs15.c: PKCS #15 wrap/unwrap functions
*
* Copyright (C) 2002 Olaf Kirch <okir@lst.de>
*
* 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,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* 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
*/
#include "config.h"
#ifdef ENABLE_OPENSSL
#include <openssl/evp.h>
#include <openssl/rand.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/*
* The asn.1 stuff from openssl and the one from opensc don't
* coexist very well. Openssl has typedef ... ASN1_OBJECT; while
* in opensc has a #define ASN1_OBJECT 6.
*
* Everything seems to work fine however if the openssl one is included
* first.
*/
#include "internal.h"
#include "asn1.h"
#include "pkcs15.h"
#ifndef ENABLE_OPENSSL
int
sc_pkcs15_wrap_data(sc_context_t *ctx,
const char *passphrase,
const u8 *in, size_t in_len,
u8 **out, size_t *out_len)
{
return SC_ERROR_NOT_SUPPORTED;
}
int
sc_pkcs15_unwrap_data(sc_context_t *ctx,
const char *passphrase,
const u8 *in, size_t in_len,
u8 **out, size_t *out_len)
{
return SC_ERROR_NOT_SUPPORTED;
}
#else /* ENABLE_OPENSSL */
static int
sc_pkcs15_derive_key(sc_context_t *ctx,
const struct sc_algorithm_id *der_alg,
const struct sc_algorithm_id *enc_alg,
const char *passphrase,
EVP_CIPHER_CTX *crypt_ctx, int enc_dec)
{
struct sc_pbkdf2_params *info;
unsigned int key_len;
const EVP_CIPHER *cipher;
u8 *iv = NULL, key[64];
int r;
if (!ctx || ! der_alg || !enc_alg)
return SC_ERROR_NOT_SUPPORTED;
/* XXX: We might also encounter PBES2 here */
if (der_alg->algorithm != SC_ALGORITHM_PBKDF2) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unsupported key derivation algorithm.\n");
return SC_ERROR_NOT_SUPPORTED;
}
switch (enc_alg->algorithm) {
case SC_ALGORITHM_3DES:
cipher = EVP_des_ede3_cbc();
iv = (u8 *) enc_alg->params;
break;
case SC_ALGORITHM_DES:
cipher = EVP_des_cbc();
iv = (u8 *) enc_alg->params;
break;
default:
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unsupported key encryption algorithm.\n");
return SC_ERROR_NOT_SUPPORTED;
}
if (!iv) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Unsupported key encryption parameters.\n");
return SC_ERROR_NOT_SUPPORTED;
}
key_len = EVP_CIPHER_key_length(cipher);
info = (struct sc_pbkdf2_params *) der_alg->params;
if (!info) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Key parameters missing.\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
if (info->key_length && info->key_length != key_len) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Incompatible key length.\n");
return SC_ERROR_INVALID_ARGUMENTS;
}
if (key_len > sizeof(key)) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Huge key length (%u).\n", key_len);
return SC_ERROR_INVALID_ARGUMENTS;
}
r = PKCS5_PBKDF2_HMAC_SHA1(passphrase, -1,
info->salt, info->salt_len,
info->iterations, key_len, key);
if (r == 0) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Key derivation failed.\n");
return SC_ERROR_INTERNAL; /* for lack of something better */
}
/* Now we have the key. Set up the cipher context */
memset(crypt_ctx, 0, sizeof(*crypt_ctx));
EVP_CipherInit(crypt_ctx, cipher, key, iv, enc_dec);
return 0;
}
static int
do_cipher(EVP_CIPHER_CTX *cipher_ctx, const u8 *in, size_t in_len,
u8 **out, size_t *out_len)
{
const u8 *end;
u8 *p;
size_t bl, left, total;
int done;
*out = p = malloc(in_len + EVP_CIPHER_CTX_key_length(cipher_ctx));
*out_len = total = 0;
bl = EVP_CIPHER_CTX_block_size(cipher_ctx);
end = in + in_len;
while (in < end) {
if ((left = end - in) > bl)
left = bl;
if (!EVP_CipherUpdate(cipher_ctx,
p + total, &done,
(u8 *) in, (int)left))
goto fail;
total += done;
in += left;
}
if (1 || total < in_len) {
if (!EVP_CipherFinal(cipher_ctx, p + total, &done))
goto fail;
total += done;
}
*out_len = total;
return 0;
fail: free(p);
return SC_ERROR_INTERNAL;
}
int
sc_pkcs15_wrap_data(sc_context_t *ctx,
const char *passphrase,
const u8 *in, size_t in_len,
u8 **out, size_t *out_len)
{
struct sc_pkcs15_enveloped_data envdata;
EVP_CIPHER_CTX cipher_ctx;
struct sc_pbkdf2_params der_info;
u8 des_iv[8];
int r;
memset(&envdata, 0, sizeof(envdata));
memset(&der_info, 0, sizeof(der_info));
RAND_bytes(des_iv, sizeof(des_iv));
der_info.salt_len = sizeof(der_info.salt);
RAND_bytes(der_info.salt, sizeof(der_info.salt));
der_info.iterations = 32;
der_info.hash_alg.algorithm = SC_ALGORITHM_SHA1;
envdata.id.len = 1;
envdata.ke_alg.algorithm = SC_ALGORITHM_PBKDF2;
envdata.ke_alg.params = &der_info;
envdata.ce_alg.algorithm = SC_ALGORITHM_3DES;
envdata.ce_alg.params = des_iv;
envdata.key = (u8 *) "";
r = sc_pkcs15_derive_key(ctx, &envdata.ke_alg, &envdata.ce_alg,
passphrase, &cipher_ctx, 1);
if (r < 0)
return r;
/* Now encrypt the data using the derived key */
r = do_cipher(&cipher_ctx, in, in_len,
&envdata.content, &envdata.content_len);
if (r < 0)
return r;
/* Finally, DER encode the whole mess */
r = sc_pkcs15_encode_enveloped_data(ctx, &envdata, out, out_len);
free(envdata.content);
return r;
}
int
sc_pkcs15_unwrap_data(sc_context_t *ctx,
const char *passphrase,
const u8 *in, size_t in_len,
u8 **out, size_t *out_len)
{
struct sc_pkcs15_enveloped_data envdata;
EVP_CIPHER_CTX cipher_ctx;
int r;
memset(&envdata, 0, sizeof(envdata));
r = sc_pkcs15_decode_enveloped_data(ctx, &envdata, in, in_len);
if (r < 0) {
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "Failed to decode EnvelopedData.\n");
return r;
}
/* Derive the key using the info in EnvelopedData */
r = sc_pkcs15_derive_key(ctx, &envdata.ke_alg, &envdata.ce_alg,
passphrase, &cipher_ctx, 0);
if (r < 0)
return r;
/* Now decrypt the data using the derived key */
r = do_cipher(&cipher_ctx, envdata.content, envdata.content_len,
out, out_len);
if (r < 0)
return r;
if (envdata.ce_alg.params)
free(envdata.ce_alg.params);
if (envdata.ke_alg.params)
free(envdata.ke_alg.params);
free(envdata.content);
return r;
}
#endif /* ENABLE_OPENSSL */
/*
* Encode/decode EnvelopedData
* Note we cheat with the recipientInfo field, which is a SET OF:
* we treat it as if there's always just one element in the set.
*/
static const struct sc_asn1_entry c_asn1_enveloped_data_attr[] = {
{ "version", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
{ "originator", SC_ASN1_STRUCT, SC_ASN1_CONS| SC_ASN1_TAG_SEQUENCE, SC_ASN1_OPTIONAL, NULL, NULL },
{ "recipients", SC_ASN1_STRUCT, SC_ASN1_CONS| SC_ASN1_TAG_SET, 0, NULL, NULL },
{ "contentInfo",SC_ASN1_STRUCT, SC_ASN1_CONS| SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL },
/* some more optional foo we ignore for now */
{ NULL, 0, 0, 0, NULL, NULL}
};
static const struct sc_asn1_entry c_asn1_content_attr[] = {
{ "contentType",SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, 0, NULL, NULL },
{ "contentEncrAlg", SC_ASN1_ALGORITHM_ID, SC_ASN1_CONS| SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL },
{ "encrContent",SC_ASN1_STRUCT, SC_ASN1_CTX | 0 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
static const struct sc_asn1_entry c_asn1_encr_content[] = {
{ "data", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_ALLOC, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
static const struct sc_asn1_entry c_asn1_recipients_attr[] = {
{ "kekri", SC_ASN1_STRUCT, SC_ASN1_CTX | 2 | SC_ASN1_CONS , 0, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
static const struct sc_asn1_entry c_asn1_kekri_attr[] = {
{ "version", SC_ASN1_INTEGER, SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
{ "id", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL },
{ "keyEncrAlg", SC_ASN1_ALGORITHM_ID, SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL },
{ "keyEncrKey", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_ALLOC, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
static const struct sc_asn1_entry c_asn1_kek_attr[] = {
{ "id", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_OCTET_STRING, 0, NULL, NULL },
{ "date", SC_ASN1_OCTET_STRING, SC_ASN1_TAG_GENERALIZEDTIME, SC_ASN1_OPTIONAL, NULL, NULL },
{ "other", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, SC_ASN1_OPTIONAL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
int
sc_pkcs15_decode_enveloped_data(sc_context_t *ctx,
struct sc_pkcs15_enveloped_data *result,
const u8 *buf, size_t buflen)
{
struct sc_asn1_entry asn1_enveloped_data_attr[5],
asn1_content_attr[4],
asn1_encr_content[2],
asn1_recipients_attr[2],
asn1_kekri_attr[5],
asn1_kek_attr[4];
struct sc_pkcs15_enveloped_data data;
int r;
sc_copy_asn1_entry(c_asn1_enveloped_data_attr, asn1_enveloped_data_attr);
sc_copy_asn1_entry(c_asn1_content_attr, asn1_content_attr);
sc_copy_asn1_entry(c_asn1_encr_content, asn1_encr_content);
sc_copy_asn1_entry(c_asn1_recipients_attr, asn1_recipients_attr);
sc_copy_asn1_entry(c_asn1_kekri_attr, asn1_kekri_attr);
sc_copy_asn1_entry(c_asn1_kek_attr, asn1_kek_attr);
sc_format_asn1_entry(asn1_enveloped_data_attr + 2,
asn1_recipients_attr, NULL, 0);
sc_format_asn1_entry(asn1_enveloped_data_attr + 3,
asn1_content_attr, NULL, 0);
sc_format_asn1_entry(asn1_content_attr + 1, &data.ce_alg, NULL, 0);
sc_format_asn1_entry(asn1_content_attr + 2,
asn1_encr_content, NULL, 0);
sc_format_asn1_entry(asn1_encr_content + 0,
&data.content, &data.content_len, 0);
sc_format_asn1_entry(asn1_recipients_attr + 0,
asn1_kekri_attr, NULL, 0);
sc_format_asn1_entry(asn1_kekri_attr + 1,
asn1_kek_attr, NULL, 0);
sc_format_asn1_entry(asn1_kekri_attr + 2,
&data.ke_alg, NULL, 0);
sc_format_asn1_entry(asn1_kekri_attr + 3,
&data.key, &data.key_len, 0);
sc_format_asn1_entry(asn1_kek_attr + 0,
&data.id, &data.id.len, 0);
memset(&data, 0, sizeof(data));
r = sc_asn1_decode(ctx, asn1_enveloped_data_attr, buf, buflen, NULL, NULL);
if (r >= 0)
*result = data;
return r;
}
int
sc_pkcs15_encode_enveloped_data(sc_context_t *ctx,
struct sc_pkcs15_enveloped_data *data,
u8 **buf, size_t *buflen)
{
static struct sc_object_id oid_id_data = {{ 1, 2, 840, 113549, 1, 7, 1, -1 }};
struct sc_asn1_entry asn1_enveloped_data_attr[5],
asn1_content_attr[4],
asn1_encr_content[2],
asn1_recipients_attr[2],
asn1_kekri_attr[5],
asn1_kek_attr[4];
int version2 = 2, version4 = 4, r;
sc_copy_asn1_entry(c_asn1_enveloped_data_attr, asn1_enveloped_data_attr);
sc_copy_asn1_entry(c_asn1_content_attr, asn1_content_attr);
sc_copy_asn1_entry(c_asn1_encr_content, asn1_encr_content);
sc_copy_asn1_entry(c_asn1_recipients_attr, asn1_recipients_attr);
sc_copy_asn1_entry(c_asn1_kekri_attr, asn1_kekri_attr);
sc_copy_asn1_entry(c_asn1_kek_attr, asn1_kek_attr);
sc_format_asn1_entry(asn1_enveloped_data_attr + 0,
&version2, NULL, 1);
sc_format_asn1_entry(asn1_enveloped_data_attr + 2,
asn1_recipients_attr, NULL, 1);
sc_format_asn1_entry(asn1_enveloped_data_attr + 3,
asn1_content_attr, NULL, 1);
sc_format_asn1_entry(asn1_content_attr + 0, &oid_id_data, NULL, 1);
sc_format_asn1_entry(asn1_content_attr + 1, &data->ce_alg, NULL, 1);
sc_format_asn1_entry(asn1_content_attr + 2,
asn1_encr_content, NULL, 1);
sc_format_asn1_entry(asn1_encr_content + 0,
data->content, &data->content_len, 1);
sc_format_asn1_entry(asn1_recipients_attr + 0,
asn1_kekri_attr, NULL, 1);
sc_format_asn1_entry(asn1_kekri_attr + 0,
&version4, NULL, 1);
sc_format_asn1_entry(asn1_kekri_attr + 1,
asn1_kek_attr, NULL, 1);
sc_format_asn1_entry(asn1_kekri_attr + 2,
&data->ke_alg, NULL, 1);
sc_format_asn1_entry(asn1_kekri_attr + 3,
data->key, &data->key_len, 1);
sc_format_asn1_entry(asn1_kek_attr + 0,
&data->id, &data->id.len, 1);
memset(&data, 0, sizeof(data));
r = sc_asn1_encode(ctx, asn1_enveloped_data_attr, buf, buflen);
return r;
}

View File

@ -584,17 +584,9 @@ int sc_pkcs15_pubkey_from_spki_filename(struct sc_context *,
char *, sc_pkcs15_pubkey_t ** );
int sc_pkcs15_pubkey_from_spki(struct sc_context *,
sc_pkcs15_pubkey_t **, u8 *, size_t, int);
int sc_pkcs15_read_prkey(struct sc_pkcs15_card *,
const struct sc_pkcs15_object *,
const char *passphrase,
struct sc_pkcs15_prkey **);
int sc_pkcs15_decode_prkey(struct sc_context *,
struct sc_pkcs15_prkey *,
const u8 *, size_t);
int sc_pkcs15_encode_prkey(struct sc_context *,
struct sc_pkcs15_prkey *,
u8 **, size_t *);
void sc_pkcs15_erase_prkey(struct sc_pkcs15_prkey *prkey);
void sc_pkcs15_free_prkey(struct sc_pkcs15_prkey *prkey);
void sc_pkcs15_free_key_params(struct sc_pkcs15_key_params *params);
@ -756,16 +748,6 @@ void sc_pkcs15_free_data_info(sc_pkcs15_data_info_t *data);
void sc_pkcs15_free_pin_info(sc_pkcs15_pin_info_t *pin);
void sc_pkcs15_free_object(sc_pkcs15_object_t *obj);
/* File content wrapping */
int sc_pkcs15_wrap_data(struct sc_context *ctx,
const char *passphrase,
const u8 *in, size_t in_len,
u8 **out, size_t *out_len);
int sc_pkcs15_unwrap_data(struct sc_context *ctx,
const char *passphrase,
const u8 *in, size_t in_len,
u8 **out, size_t *out_len);
/* Generic file i/o */
int sc_pkcs15_read_file(struct sc_pkcs15_card *p15card,
const struct sc_path *path,

View File

@ -212,9 +212,6 @@ struct sc_pkcs15init_prkeyargs {
} params;
struct sc_pkcs15_prkey key;
/* support for non-native keys */
char * passphrase;
};
struct sc_pkcs15init_keygen_args {
@ -222,8 +219,6 @@ struct sc_pkcs15init_keygen_args {
const char * pubkey_label;
};
#define SC_PKCS15INIT_NO_PASSPHRASE 0x0002
struct sc_pkcs15init_pubkeyargs {
struct sc_pkcs15_id id;
struct sc_pkcs15_id auth_id;

View File

@ -1323,9 +1323,6 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card,
* the key as extractable. */
if (!(keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE))
LOG_TEST_RET(ctx, SC_ERROR_INCOMPATIBLE_KEY, "Card does not support this key.");
if (!keyargs->passphrase && !(keyargs->flags & SC_PKCS15INIT_NO_PASSPHRASE))
LOG_TEST_RET(ctx, SC_ERROR_PASSPHRASE_REQUIRED, "No key encryption passphrase given.");
}
/* Select a intrinsic Key ID if user didn't specify one */
@ -1349,42 +1346,12 @@ sc_pkcs15init_store_private_key(struct sc_pkcs15_card *p15card,
/* Get the number of private keys already on this card */
idx = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_PRKEY, NULL, 0);
if (!(keyargs->access_flags & SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE)) {
r = profile->ops->create_key(profile, p15card, object);
LOG_TEST_RET(ctx, r, "Card specific 'create key' failed");
r = profile->ops->store_key(profile, p15card, object, &key);
LOG_TEST_RET(ctx, r, "Card specific 'store key' failed");
} else {
struct sc_pkcs15_der encoded, wrapped, *der = &encoded;
r = profile->ops->create_key(profile, p15card, object);
LOG_TEST_RET(ctx, r, "Card specific 'create key' failed");
/* DER encode the private key */
encoded.value = wrapped.value = NULL;
r = sc_pkcs15_encode_prkey(ctx, &key, &encoded.value, &encoded.len);
LOG_TEST_RET(ctx, r, "Failed to encode private key");
if (keyargs->passphrase) {
r = sc_pkcs15_wrap_data(ctx, keyargs->passphrase, der->value, der->len,
&wrapped.value, &wrapped.len);
if (r < 0) {
free(der->value);
LOG_TEST_RET(ctx, r, "Failed to wrap private key data");
}
der = &wrapped;
}
r = sc_pkcs15init_store_data(p15card, profile, object, der, &key_info->path);
/* If the key is encrypted, flag the PrKDF entry as
* indirect-protected */
if (keyargs->passphrase)
key_info->path.type = SC_PATH_TYPE_PATH_PROT;
free(encoded.value);
free(wrapped.value);
LOG_TEST_RET(ctx, r, "Failed to store private key data");
}
r = profile->ops->store_key(profile, p15card, object, &key);
LOG_TEST_RET(ctx, r, "Card specific 'store key' failed");
/* Now update the PrKDF */
r = sc_pkcs15init_add_object(p15card, profile, SC_PKCS15_PRKDF, object);
@ -1894,8 +1861,7 @@ check_keygen_params_consistency(struct sc_card *card, struct sc_pkcs15init_keyge
* Check whether the card has native crypto support for this key.
*/
static int
check_key_compatibility(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey *key,
unsigned int x509_usage, unsigned int key_length, unsigned int flags)
check_key_compatibility(struct sc_pkcs15_card *p15card, struct sc_pkcs15_prkey *key, unsigned int x509_usage, unsigned int key_length, unsigned int flags)
{
struct sc_algorithm_info *info;
unsigned int count;

View File

@ -121,7 +121,7 @@ enum {
OPT_PASSPHRASE,
OPT_PUBKEY,
OPT_EXTRACTABLE,
OPT_UNPROTECTED,
OPT_INSECURE,
OPT_AUTHORITY,
OPT_ASSERT_PRISTINE,
OPT_SECRET,
@ -184,7 +184,7 @@ const struct option options[] = {
{ "finalize", no_argument, NULL, 'F' },
{ "extractable", no_argument, NULL, OPT_EXTRACTABLE },
{ "insecure", no_argument, NULL, OPT_UNPROTECTED },
{ "insecure", no_argument, NULL, OPT_INSECURE },
{ "use-default-transport-keys",
no_argument, NULL, 'T' },
{ "no-prompt", no_argument, NULL, OPT_NO_PROMPT },
@ -241,7 +241,7 @@ static const char * option_help[] = {
"Finish initialization phase of the smart card",
"Private key stored as an extractable key",
"Insecure mode: do not require PIN/passphrase for private key",
"Insecure mode: do not require a PIN for private key",
"Do not ask for transport keys if the driver thinks it knows the key",
"Do not prompt the user; if no PINs supplied, pinpad will be used",
@ -316,7 +316,7 @@ static struct sc_pkcs15_card * p15card = NULL;
static char * opt_reader = NULL;
static unsigned int opt_actions;
static int opt_extractable = 0,
opt_unprotected = 0,
opt_insecure = 0,
opt_authority = 0,
opt_no_prompt = 0,
opt_no_sopin = 0,
@ -1493,25 +1493,13 @@ static int init_keyargs(struct sc_pkcs15init_prkeyargs *args)
sc_pkcs15_format_id(opt_objectid, &args->id);
if (opt_authid) {
sc_pkcs15_format_id(opt_authid, &args->auth_id);
} else if (!opt_unprotected) {
} else if (!opt_insecure) {
util_error("no PIN given for key - either use --insecure or \n"
"specify a PIN using --auth-id");
return SC_ERROR_INVALID_ARGUMENTS;
}
if (opt_extractable) {
args->access_flags |= SC_PKCS15_PRKEY_ACCESS_EXTRACTABLE;
if (opt_passphrase) {
args->passphrase = opt_passphrase;
} else {
if (!opt_unprotected) {
util_error("no pass phrase given for key - "
"either use --insecure or\n"
"specify a pass phrase using "
"--passphrase");
return SC_ERROR_PASSPHRASE_REQUIRED;
}
args->flags |= SC_PKCS15INIT_NO_PASSPHRASE;
}
}
args->label = opt_label;
args->x509_usage = opt_x509_usage;
@ -2538,11 +2526,11 @@ handle_option(const struct option *opt)
this_action = ACTION_STORE_PUBKEY;
opt_infile = optarg;
break;
case OPT_UNPROTECTED:
opt_unprotected++;
case OPT_INSECURE:
opt_insecure = 1;
break;
case OPT_EXTRACTABLE:
opt_extractable++;
opt_extractable = 1;
break;
case OPT_AUTHORITY:
opt_authority = 1;