pkcs15-init: 'erase-application', 'update-lastUpdate', ...
New operations: - 'erase-application' -- erase on-card application indicated by it's AID; - 'update-lastupdate' -- parse tokenInfo, set 'lastUpdate' value to the current date and write back tokenInfo content; - 'ignore-ca-certificates' -- when importing PKCS#12 ignore all CA certificates;
This commit is contained in:
parent
fbc9bb35dc
commit
525f61af73
|
@ -64,6 +64,7 @@
|
||||||
#include "libopensc/log.h"
|
#include "libopensc/log.h"
|
||||||
#include "libopensc/cards.h"
|
#include "libopensc/cards.h"
|
||||||
#include "pkcs15init/pkcs15-init.h"
|
#include "pkcs15init/pkcs15-init.h"
|
||||||
|
#include "pkcs15init/profile.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#undef GET_KEY_ECHO_OFF
|
#undef GET_KEY_ECHO_OFF
|
||||||
|
@ -78,6 +79,7 @@ typedef int (*pkcs15_encoder)(sc_context_t *,
|
||||||
static int open_reader_and_card(char *);
|
static int open_reader_and_card(char *);
|
||||||
static int do_assert_pristine(sc_card_t *);
|
static int do_assert_pristine(sc_card_t *);
|
||||||
static int do_erase(sc_card_t *, struct sc_profile *);
|
static int do_erase(sc_card_t *, struct sc_profile *);
|
||||||
|
static int do_erase_application(sc_card_t *, struct sc_profile *);
|
||||||
static int do_delete_objects(struct sc_profile *, unsigned int myopt_delete_flags);
|
static int do_delete_objects(struct sc_profile *, unsigned int myopt_delete_flags);
|
||||||
static int do_change_attributes(struct sc_profile *, unsigned int myopt_type);
|
static int do_change_attributes(struct sc_profile *, unsigned int myopt_type);
|
||||||
static int do_init_app(struct sc_profile *);
|
static int do_init_app(struct sc_profile *);
|
||||||
|
@ -87,8 +89,6 @@ static int do_store_private_key(struct sc_profile *);
|
||||||
static int do_store_public_key(struct sc_profile *, EVP_PKEY *);
|
static int do_store_public_key(struct sc_profile *, EVP_PKEY *);
|
||||||
static int do_store_certificate(struct sc_profile *);
|
static int do_store_certificate(struct sc_profile *);
|
||||||
static int do_update_certificate(struct sc_profile *);
|
static int do_update_certificate(struct sc_profile *);
|
||||||
static int do_convert_private_key(struct sc_pkcs15_prkey *, EVP_PKEY *);
|
|
||||||
static int do_convert_public_key(struct sc_pkcs15_pubkey *, EVP_PKEY *);
|
|
||||||
static int do_convert_cert(sc_pkcs15_der_t *, X509 *);
|
static int do_convert_cert(sc_pkcs15_der_t *, X509 *);
|
||||||
static int is_cacert_already_present(struct sc_pkcs15init_certargs *);
|
static int is_cacert_already_present(struct sc_pkcs15init_certargs *);
|
||||||
static int do_finalize_card(sc_card_t *, struct sc_profile *);
|
static int do_finalize_card(sc_card_t *, struct sc_profile *);
|
||||||
|
@ -107,10 +107,10 @@ static int get_key_callback(struct sc_profile *,
|
||||||
int method, int reference,
|
int method, int reference,
|
||||||
const u8 *, size_t, u8 *, size_t *);
|
const u8 *, size_t, u8 *, size_t *);
|
||||||
|
|
||||||
static int do_read_private_key(const char *, const char *,
|
static int do_read_private_key(const char *, const char *, EVP_PKEY **, X509 **, unsigned int);
|
||||||
EVP_PKEY **, X509 **, unsigned int);
|
|
||||||
static int do_read_public_key(const char *, const char *, EVP_PKEY **);
|
static int do_read_public_key(const char *, const char *, EVP_PKEY **);
|
||||||
static int do_read_certificate(const char *, const char *, X509 **);
|
static int do_read_certificate(const char *, const char *, X509 **);
|
||||||
|
static char * cert_common_name(X509 *x509);
|
||||||
static void parse_commandline(int argc, char **argv);
|
static void parse_commandline(int argc, char **argv);
|
||||||
static void read_options_file(const char *);
|
static void read_options_file(const char *);
|
||||||
static void ossl_print_errors(void);
|
static void ossl_print_errors(void);
|
||||||
|
@ -134,6 +134,9 @@ enum {
|
||||||
OPT_VERIFY_PIN,
|
OPT_VERIFY_PIN,
|
||||||
OPT_SANITY_CHECK,
|
OPT_SANITY_CHECK,
|
||||||
OPT_BIND_TO_AID,
|
OPT_BIND_TO_AID,
|
||||||
|
OPT_UPDATE_LAST_UPDATE,
|
||||||
|
OPT_ERASE_APPLICATION,
|
||||||
|
OPT_IGNORE_CA_CERTIFICATES,
|
||||||
|
|
||||||
OPT_PIN1 = 0x10000, /* don't touch these values */
|
OPT_PIN1 = 0x10000, /* don't touch these values */
|
||||||
OPT_PUK1 = 0x10001,
|
OPT_PUK1 = 0x10001,
|
||||||
|
@ -157,6 +160,7 @@ const struct option options[] = {
|
||||||
{ "delete-objects", required_argument, NULL, 'D' },
|
{ "delete-objects", required_argument, NULL, 'D' },
|
||||||
{ "change-attributes", required_argument, NULL, 'A' },
|
{ "change-attributes", required_argument, NULL, 'A' },
|
||||||
{ "sanity-check", no_argument, NULL, OPT_SANITY_CHECK},
|
{ "sanity-check", no_argument, NULL, OPT_SANITY_CHECK},
|
||||||
|
{ "erase-application", required_argument, NULL, OPT_ERASE_APPLICATION},
|
||||||
|
|
||||||
{ "reader", required_argument, NULL, 'r' },
|
{ "reader", required_argument, NULL, 'r' },
|
||||||
{ "pin", required_argument, NULL, OPT_PIN1 },
|
{ "pin", required_argument, NULL, OPT_PIN1 },
|
||||||
|
@ -181,7 +185,9 @@ const struct option options[] = {
|
||||||
{ "passphrase", required_argument, NULL, OPT_PASSPHRASE },
|
{ "passphrase", required_argument, NULL, OPT_PASSPHRASE },
|
||||||
{ "authority", no_argument, NULL, OPT_AUTHORITY },
|
{ "authority", no_argument, NULL, OPT_AUTHORITY },
|
||||||
{ "key-usage", required_argument, NULL, 'u' },
|
{ "key-usage", required_argument, NULL, 'u' },
|
||||||
{ "finalize", no_argument, NULL, 'F' },
|
{ "finalize", no_argument, NULL, 'F' },
|
||||||
|
{ "update-last-update", no_argument, NULL, OPT_UPDATE_LAST_UPDATE},
|
||||||
|
{ "ignore-ca-certificates",no_argument, NULL, OPT_IGNORE_CA_CERTIFICATES},
|
||||||
|
|
||||||
{ "extractable", no_argument, NULL, OPT_EXTRACTABLE },
|
{ "extractable", no_argument, NULL, OPT_EXTRACTABLE },
|
||||||
{ "insecure", no_argument, NULL, OPT_INSECURE },
|
{ "insecure", no_argument, NULL, OPT_INSECURE },
|
||||||
|
@ -214,6 +220,7 @@ static const char * option_help[] = {
|
||||||
"Delete object(s) (use \"help\" for more information)",
|
"Delete object(s) (use \"help\" for more information)",
|
||||||
"Change attribute(s) (use \"help\" for more information)",
|
"Change attribute(s) (use \"help\" for more information)",
|
||||||
"Card specific sanity check and possibly update procedure",
|
"Card specific sanity check and possibly update procedure",
|
||||||
|
"Erase application with AID <arg>",
|
||||||
|
|
||||||
"Specify which reader to use",
|
"Specify which reader to use",
|
||||||
"Specify PIN",
|
"Specify PIN",
|
||||||
|
@ -239,6 +246,8 @@ static const char * option_help[] = {
|
||||||
"Mark certificate as a CA certificate",
|
"Mark certificate as a CA certificate",
|
||||||
"Specify X.509 key usage (use \"--key-usage help\" for more information)",
|
"Specify X.509 key usage (use \"--key-usage help\" for more information)",
|
||||||
"Finish initialization phase of the smart card",
|
"Finish initialization phase of the smart card",
|
||||||
|
"Update 'lastUpdate' attribut of tokenInfo",
|
||||||
|
"When storing PKCS#12 ignore CA certificates",
|
||||||
|
|
||||||
"Private key stored as an extractable key",
|
"Private key stored as an extractable key",
|
||||||
"Insecure mode: do not require a PIN for private key",
|
"Insecure mode: do not require a PIN for private key",
|
||||||
|
@ -272,6 +281,8 @@ enum {
|
||||||
ACTION_DELETE_OBJECTS,
|
ACTION_DELETE_OBJECTS,
|
||||||
ACTION_CHANGE_ATTRIBUTES,
|
ACTION_CHANGE_ATTRIBUTES,
|
||||||
ACTION_SANITY_CHECK,
|
ACTION_SANITY_CHECK,
|
||||||
|
ACTION_UPDATE_LAST_UPDATE,
|
||||||
|
ACTION_ERASE_APPLICATION,
|
||||||
|
|
||||||
ACTION_MAX
|
ACTION_MAX
|
||||||
};
|
};
|
||||||
|
@ -348,6 +359,7 @@ static unsigned int opt_type = 0;
|
||||||
static int ignore_cmdline_pins = 0;
|
static int ignore_cmdline_pins = 0;
|
||||||
static struct secret opt_secrets[MAX_SECRETS];
|
static struct secret opt_secrets[MAX_SECRETS];
|
||||||
static unsigned int opt_secret_count;
|
static unsigned int opt_secret_count;
|
||||||
|
static int opt_ignore_ca_certs = 0;
|
||||||
static int verbose = 0;
|
static int verbose = 0;
|
||||||
|
|
||||||
static struct sc_pkcs15init_callbacks callbacks = {
|
static struct sc_pkcs15init_callbacks callbacks = {
|
||||||
|
@ -437,7 +449,8 @@ main(int argc, char **argv)
|
||||||
sc_pkcs15init_set_callbacks(&callbacks);
|
sc_pkcs15init_set_callbacks(&callbacks);
|
||||||
|
|
||||||
/* Bind the card-specific operations and load the profile */
|
/* Bind the card-specific operations and load the profile */
|
||||||
if ((r = sc_pkcs15init_bind(card, opt_profile, opt_card_profile, NULL, &profile)) < 0) {
|
r = sc_pkcs15init_bind(card, opt_profile, opt_card_profile, NULL, &profile);
|
||||||
|
if (r < 0) {
|
||||||
printf("Couldn't bind to the card: %s\n", sc_strerror(r));
|
printf("Couldn't bind to the card: %s\n", sc_strerror(r));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -544,6 +557,12 @@ main(int argc, char **argv)
|
||||||
case ACTION_SANITY_CHECK:
|
case ACTION_SANITY_CHECK:
|
||||||
r = do_sanity_check(profile);
|
r = do_sanity_check(profile);
|
||||||
break;
|
break;
|
||||||
|
case ACTION_UPDATE_LAST_UPDATE:
|
||||||
|
profile->dirty = 1;
|
||||||
|
break;
|
||||||
|
case ACTION_ERASE_APPLICATION:
|
||||||
|
r = do_erase_application(card, profile);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
util_fatal("Action not yet implemented\n");
|
util_fatal("Action not yet implemented\n");
|
||||||
}
|
}
|
||||||
|
@ -670,6 +689,17 @@ do_erase(sc_card_t *in_card, struct sc_profile *profile)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_erase_application(sc_card_t *in_card, struct sc_profile *profile)
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
|
||||||
|
ignore_cmdline_pins--;
|
||||||
|
r = do_erase(in_card, profile);
|
||||||
|
ignore_cmdline_pins++;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
static int do_finalize_card(sc_card_t *in_card, struct sc_profile *profile)
|
static int do_finalize_card(sc_card_t *in_card, struct sc_profile *profile)
|
||||||
{
|
{
|
||||||
return sc_pkcs15init_finalize_card(in_card, profile);
|
return sc_pkcs15init_finalize_card(in_card, profile);
|
||||||
|
@ -845,15 +875,14 @@ do_store_private_key(struct sc_profile *profile)
|
||||||
if (ncerts) {
|
if (ncerts) {
|
||||||
char namebuf[256];
|
char namebuf[256];
|
||||||
|
|
||||||
printf("Importing %d certificates:\n", ncerts);
|
printf("Importing %d certificates:\n", opt_ignore_ca_certs ? 1 : ncerts);
|
||||||
for (i = 0; i < ncerts; i++) {
|
for (i = 0; i < ncerts && !(i && opt_ignore_ca_certs); i++)
|
||||||
printf(" %d: %s\n",
|
printf(" %d: %s\n", i, X509_NAME_oneline(cert[i]->cert_info->subject,
|
||||||
i, X509_NAME_oneline(cert[i]->cert_info->subject,
|
|
||||||
namebuf, sizeof(namebuf)));
|
namebuf, sizeof(namebuf)));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = do_convert_private_key(&args.key, pkey)) < 0)
|
r = sc_pkcs15_convert_prkey(&args.key, pkey);
|
||||||
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
init_gost_params(&args.params.gost, pkey);
|
init_gost_params(&args.params.gost, pkey);
|
||||||
|
|
||||||
|
@ -902,6 +931,9 @@ do_store_private_key(struct sc_profile *profile)
|
||||||
struct sc_pkcs15init_certargs cargs;
|
struct sc_pkcs15init_certargs cargs;
|
||||||
char namebuf[SC_PKCS15_MAX_LABEL_SIZE-1];
|
char namebuf[SC_PKCS15_MAX_LABEL_SIZE-1];
|
||||||
|
|
||||||
|
if (i && opt_ignore_ca_certs)
|
||||||
|
break;
|
||||||
|
|
||||||
memset(&cargs, 0, sizeof(cargs));
|
memset(&cargs, 0, sizeof(cargs));
|
||||||
|
|
||||||
/* Encode the cert */
|
/* Encode the cert */
|
||||||
|
@ -910,8 +942,9 @@ do_store_private_key(struct sc_profile *profile)
|
||||||
|
|
||||||
X509_check_purpose(cert[i], -1, -1);
|
X509_check_purpose(cert[i], -1, -1);
|
||||||
cargs.x509_usage = cert[i]->ex_kusage;
|
cargs.x509_usage = cert[i]->ex_kusage;
|
||||||
cargs.label = X509_NAME_oneline(cert[i]->cert_info->subject,
|
cargs.label = cert_common_name(cert[i]);
|
||||||
namebuf, sizeof(namebuf));
|
if (!cargs.label)
|
||||||
|
cargs.label = X509_NAME_oneline(cert[i]->cert_info->subject, namebuf, sizeof(namebuf));
|
||||||
|
|
||||||
/* Just the first certificate gets the same ID
|
/* Just the first certificate gets the same ID
|
||||||
* as the private key. All others get
|
* as the private key. All others get
|
||||||
|
@ -922,23 +955,20 @@ do_store_private_key(struct sc_profile *profile)
|
||||||
cargs.label = opt_cert_label;
|
cargs.label = opt_cert_label;
|
||||||
} else {
|
} else {
|
||||||
if (is_cacert_already_present(&cargs)) {
|
if (is_cacert_already_present(&cargs)) {
|
||||||
printf("Certificate #%d already present, "
|
printf("Certificate #%d already present, not stored.\n", i);
|
||||||
"not stored.\n", i);
|
|
||||||
goto next_cert;
|
goto next_cert;
|
||||||
}
|
}
|
||||||
cargs.authority = 1;
|
cargs.authority = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = sc_pkcs15init_store_certificate(p15card, profile,
|
r = sc_pkcs15init_store_certificate(p15card, profile, &cargs, NULL);
|
||||||
&cargs, NULL);
|
|
||||||
next_cert:
|
next_cert:
|
||||||
free(cargs.der_encoded.value);
|
free(cargs.der_encoded.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No certificates - store the public key */
|
/* No certificates - store the public key */
|
||||||
if (ncerts == 0) {
|
if (ncerts == 0)
|
||||||
r = do_store_public_key(profile, pkey);
|
r = do_store_public_key(profile, pkey);
|
||||||
}
|
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -1006,7 +1036,7 @@ do_store_public_key(struct sc_profile *profile, EVP_PKEY *pkey)
|
||||||
if (pkey == NULL)
|
if (pkey == NULL)
|
||||||
r = do_read_public_key(opt_infile, opt_format, &pkey);
|
r = do_read_public_key(opt_infile, opt_format, &pkey);
|
||||||
if (r >= 0) {
|
if (r >= 0) {
|
||||||
r = do_convert_public_key(&args.key, pkey);
|
r = sc_pkcs15_convert_pubkey(&args.key, pkey);
|
||||||
if (r >= 0)
|
if (r >= 0)
|
||||||
init_gost_params(&args.params.gost, pkey);
|
init_gost_params(&args.params.gost, pkey);
|
||||||
}
|
}
|
||||||
|
@ -2099,7 +2129,8 @@ do_read_certificate(const char *name, const char *format, X509 **out)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int determine_filesize(const char *filename) {
|
static int determine_filesize(const char *filename)
|
||||||
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
|
@ -2110,7 +2141,7 @@ static int determine_filesize(const char *filename) {
|
||||||
size = ftell(fp);
|
size = ftell(fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_read_data_object(const char *name, u8 **out, size_t *outlen)
|
do_read_data_object(const char *name, u8 **out, size_t *outlen)
|
||||||
|
@ -2120,9 +2151,9 @@ do_read_data_object(const char *name, u8 **out, size_t *outlen)
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
*out = malloc(filesize);
|
*out = malloc(filesize);
|
||||||
if (*out == NULL) {
|
if (*out == NULL)
|
||||||
return SC_ERROR_OUT_OF_MEMORY;
|
return SC_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
|
||||||
|
|
||||||
inf = fopen(name, "rb");
|
inf = fopen(name, "rb");
|
||||||
if (inf == NULL) {
|
if (inf == NULL) {
|
||||||
|
@ -2140,141 +2171,39 @@ do_read_data_object(const char *name, u8 **out, size_t *outlen)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static char *
|
||||||
do_convert_bignum(sc_pkcs15_bignum_t *dst, const BIGNUM *src)
|
cert_common_name(X509 *x509)
|
||||||
{
|
{
|
||||||
if (src == 0)
|
X509_NAME_ENTRY *ne = NULL;
|
||||||
return 0;
|
ASN1_STRING *a_str = NULL;
|
||||||
dst->len = BN_num_bytes(src);
|
char *out = NULL;
|
||||||
dst->data = malloc(dst->len);
|
unsigned char *tmp = NULL;
|
||||||
BN_bn2bin(src, dst->data);
|
int idx, out_len = 0;
|
||||||
return 1;
|
|
||||||
|
idx = X509_NAME_get_index_by_NID(X509_get_subject_name(x509), NID_commonName, -1);
|
||||||
|
if (idx < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
ne = X509_NAME_get_entry(X509_get_subject_name(x509), idx);
|
||||||
|
if (!ne)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
a_str = X509_NAME_ENTRY_get_data(ne);
|
||||||
|
if (!a_str)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
out_len = ASN1_STRING_to_UTF8(&tmp, a_str);
|
||||||
|
if (!tmp)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
out = calloc(1, out_len + 1);
|
||||||
|
if (out)
|
||||||
|
memcpy(out, tmp, out_len);
|
||||||
|
OPENSSL_free(tmp);
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_convert_private_key(struct sc_pkcs15_prkey *key, EVP_PKEY *pk)
|
|
||||||
{
|
|
||||||
switch (pk->type) {
|
|
||||||
case EVP_PKEY_RSA: {
|
|
||||||
struct sc_pkcs15_prkey_rsa *dst = &key->u.rsa;
|
|
||||||
RSA *src = EVP_PKEY_get1_RSA(pk);
|
|
||||||
|
|
||||||
key->algorithm = SC_ALGORITHM_RSA;
|
|
||||||
if (!do_convert_bignum(&dst->modulus, src->n)
|
|
||||||
|| !do_convert_bignum(&dst->exponent, src->e)
|
|
||||||
|| !do_convert_bignum(&dst->d, src->d)
|
|
||||||
|| !do_convert_bignum(&dst->p, src->p)
|
|
||||||
|| !do_convert_bignum(&dst->q, src->q))
|
|
||||||
util_fatal("Invalid/incomplete RSA key.\n");
|
|
||||||
if (src->iqmp && src->dmp1 && src->dmq1) {
|
|
||||||
do_convert_bignum(&dst->iqmp, src->iqmp);
|
|
||||||
do_convert_bignum(&dst->dmp1, src->dmp1);
|
|
||||||
do_convert_bignum(&dst->dmq1, src->dmq1);
|
|
||||||
}
|
|
||||||
RSA_free(src);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EVP_PKEY_DSA: {
|
|
||||||
struct sc_pkcs15_prkey_dsa *dst = &key->u.dsa;
|
|
||||||
DSA *src = EVP_PKEY_get1_DSA(pk);
|
|
||||||
|
|
||||||
key->algorithm = SC_ALGORITHM_DSA;
|
|
||||||
do_convert_bignum(&dst->pub, src->pub_key);
|
|
||||||
do_convert_bignum(&dst->p, src->p);
|
|
||||||
do_convert_bignum(&dst->q, src->q);
|
|
||||||
do_convert_bignum(&dst->g, src->g);
|
|
||||||
do_convert_bignum(&dst->priv, src->priv_key);
|
|
||||||
DSA_free(src);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
|
|
||||||
case NID_id_GostR3410_2001: {
|
|
||||||
struct sc_pkcs15_prkey_gostr3410 *dst = &key->u.gostr3410;
|
|
||||||
EC_KEY *src = EVP_PKEY_get0(pk);
|
|
||||||
|
|
||||||
assert(src);
|
|
||||||
key->algorithm = SC_ALGORITHM_GOSTR3410;
|
|
||||||
assert(EC_KEY_get0_private_key(src));
|
|
||||||
do_convert_bignum(&dst->d, EC_KEY_get0_private_key(src));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) */
|
|
||||||
default:
|
|
||||||
util_fatal("Unsupported key algorithm\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_convert_public_key(struct sc_pkcs15_pubkey *key, EVP_PKEY *pk)
|
|
||||||
{
|
|
||||||
switch (pk->type) {
|
|
||||||
case EVP_PKEY_RSA: {
|
|
||||||
struct sc_pkcs15_pubkey_rsa *dst = &key->u.rsa;
|
|
||||||
RSA *src = EVP_PKEY_get1_RSA(pk);
|
|
||||||
|
|
||||||
key->algorithm = SC_ALGORITHM_RSA;
|
|
||||||
if (!do_convert_bignum(&dst->modulus, src->n)
|
|
||||||
|| !do_convert_bignum(&dst->exponent, src->e))
|
|
||||||
util_fatal("Invalid/incomplete RSA key.\n");
|
|
||||||
RSA_free(src);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case EVP_PKEY_DSA: {
|
|
||||||
struct sc_pkcs15_pubkey_dsa *dst = &key->u.dsa;
|
|
||||||
DSA *src = EVP_PKEY_get1_DSA(pk);
|
|
||||||
|
|
||||||
key->algorithm = SC_ALGORITHM_DSA;
|
|
||||||
do_convert_bignum(&dst->pub, src->pub_key);
|
|
||||||
do_convert_bignum(&dst->p, src->p);
|
|
||||||
do_convert_bignum(&dst->q, src->q);
|
|
||||||
do_convert_bignum(&dst->g, src->g);
|
|
||||||
DSA_free(src);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC)
|
|
||||||
case NID_id_GostR3410_2001: {
|
|
||||||
struct sc_pkcs15_pubkey_gostr3410 *dst = &key->u.gostr3410;
|
|
||||||
EC_KEY *eckey = EVP_PKEY_get0(pk);
|
|
||||||
const EC_POINT *point;
|
|
||||||
BIGNUM *X, *Y;
|
|
||||||
int r = 0;
|
|
||||||
|
|
||||||
assert(eckey);
|
|
||||||
point = EC_KEY_get0_public_key(eckey);
|
|
||||||
if (!point)
|
|
||||||
return SC_ERROR_INTERNAL;
|
|
||||||
X = BN_new();
|
|
||||||
Y = BN_new();
|
|
||||||
if (X && Y && EC_KEY_get0_group(eckey))
|
|
||||||
r = EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(eckey),
|
|
||||||
point, X, Y, NULL);
|
|
||||||
if (r == 1) {
|
|
||||||
dst->xy.len = BN_num_bytes(X) + BN_num_bytes(Y);
|
|
||||||
dst->xy.data = malloc(dst->xy.len);
|
|
||||||
if (dst->xy.data) {
|
|
||||||
BN_bn2bin(Y, dst->xy.data);
|
|
||||||
BN_bn2bin(X, dst->xy.data + BN_num_bytes(Y));
|
|
||||||
r = sc_mem_reverse(dst->xy.data, dst->xy.len);
|
|
||||||
if (!r)
|
|
||||||
r = 1;
|
|
||||||
key->algorithm = SC_ALGORITHM_GOSTR3410;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
r = -1;
|
|
||||||
}
|
|
||||||
BN_free(X);
|
|
||||||
BN_free(Y);
|
|
||||||
if (r != 1)
|
|
||||||
return SC_ERROR_INTERNAL;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif /* OPENSSL_VERSION_NUMBER >= 0x10000000L && !defined(OPENSSL_NO_EC) */
|
|
||||||
default:
|
|
||||||
util_fatal("Unsupported key algorithm\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int do_convert_cert(sc_pkcs15_der_t *der, X509 *cert)
|
static int do_convert_cert(sc_pkcs15_der_t *der, X509 *cert)
|
||||||
{
|
{
|
||||||
|
@ -2573,6 +2502,16 @@ handle_option(const struct option *opt)
|
||||||
case OPT_SANITY_CHECK:
|
case OPT_SANITY_CHECK:
|
||||||
this_action = ACTION_SANITY_CHECK;
|
this_action = ACTION_SANITY_CHECK;
|
||||||
break;
|
break;
|
||||||
|
case OPT_UPDATE_LAST_UPDATE:
|
||||||
|
this_action = ACTION_UPDATE_LAST_UPDATE;
|
||||||
|
break;
|
||||||
|
case OPT_ERASE_APPLICATION:
|
||||||
|
opt_bind_to_aid = optarg;
|
||||||
|
this_action = ACTION_ERASE_APPLICATION;
|
||||||
|
break;
|
||||||
|
case OPT_IGNORE_CA_CERTIFICATES:
|
||||||
|
opt_ignore_ca_certs = 1;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
util_print_usage_and_die(app_name, options, option_help, NULL);
|
util_print_usage_and_die(app_name, options, option_help, NULL);
|
||||||
}
|
}
|
||||||
|
@ -2719,7 +2658,7 @@ ossl_print_errors(void)
|
||||||
*
|
*
|
||||||
* @hints dialog hints
|
* @hints dialog hints
|
||||||
* @out PIN entered by the user; must be freed.
|
* @out PIN entered by the user; must be freed.
|
||||||
* NULL if dialog was canceled.
|
* NULL if dialog was canceled.
|
||||||
*/
|
*/
|
||||||
int get_pin(sc_ui_hints_t *hints, char **out)
|
int get_pin(sc_ui_hints_t *hints, char **out)
|
||||||
{
|
{
|
||||||
|
@ -2728,17 +2667,16 @@ int get_pin(sc_ui_hints_t *hints, char **out)
|
||||||
int flags = hints->flags;
|
int flags = hints->flags;
|
||||||
|
|
||||||
pin_info = hints->info.pin;
|
pin_info = hints->info.pin;
|
||||||
if (pin_info && pin_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
|
if (pin_info && (pin_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN))
|
||||||
return SC_ERROR_NOT_SUPPORTED;
|
return SC_ERROR_NOT_SUPPORTED;
|
||||||
|
|
||||||
if (!(label = hints->obj_label)) {
|
if (!(label = hints->obj_label)) {
|
||||||
if (pin_info == NULL) {
|
if (pin_info == NULL)
|
||||||
label = "PIN";
|
label = "PIN";
|
||||||
} else if (pin_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN) {
|
else if (pin_info->attrs.pin.flags & SC_PKCS15_PIN_FLAG_SO_PIN)
|
||||||
label = "Security Officer PIN";
|
label = "Security Officer PIN";
|
||||||
} else {
|
else
|
||||||
label = "User PIN";
|
label = "User PIN";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hints->p15card) {
|
if (hints->p15card) {
|
||||||
|
|
Loading…
Reference in New Issue