- When storing a p12 bag, check if the CA cert is already present and skip
it if so. git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1571 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
parent
60892cd0a3
commit
a9d9aa2877
|
@ -73,6 +73,7 @@ static int do_store_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 is_cacert_already_present(struct sc_pkcs15init_certargs *);
|
||||
|
||||
static int do_read_data_object(const char *name, u8 **out, size_t *outlen);
|
||||
static int do_store_data_object(struct sc_profile *profile);
|
||||
|
@ -697,22 +698,32 @@ do_store_private_key(struct sc_profile *profile)
|
|||
char namebuf[SC_PKCS15_MAX_LABEL_SIZE-1];
|
||||
|
||||
memset(&cargs, 0, sizeof(cargs));
|
||||
/* Just the first certificate gets the same ID
|
||||
* as the private key. All others get
|
||||
* an ID of their own */
|
||||
if (i == 0)
|
||||
cargs.id = args.id;
|
||||
else
|
||||
cargs.authority = 1;
|
||||
|
||||
/* Encode the cert */
|
||||
if ((r = do_convert_cert(&cargs.der_encoded, cert[i])) < 0)
|
||||
return r;
|
||||
|
||||
cargs.x509_usage = cert[i]->ex_kusage;
|
||||
cargs.label = X509_NAME_oneline(cert[i]->cert_info->subject,
|
||||
namebuf, sizeof(namebuf));
|
||||
|
||||
cargs.x509_usage = cert[i]->ex_kusage;
|
||||
r = do_convert_cert(&cargs.der_encoded, cert[i]);
|
||||
if (r >= 0)
|
||||
r = sc_pkcs15init_store_certificate(p15card, profile,
|
||||
/* Just the first certificate gets the same ID
|
||||
* as the private key. All others get
|
||||
* an ID of their own */
|
||||
if (i == 0) {
|
||||
cargs.id = args.id;
|
||||
} else {
|
||||
if (is_cacert_already_present(&cargs)) {
|
||||
printf("Certificate #%d already present, "
|
||||
"not stored.\n", i);
|
||||
goto next_cert;
|
||||
}
|
||||
cargs.authority = 1;
|
||||
}
|
||||
|
||||
r = sc_pkcs15init_store_certificate(p15card, profile,
|
||||
&cargs, NULL);
|
||||
next_cert:
|
||||
free(cargs.der_encoded.value);
|
||||
}
|
||||
|
||||
|
@ -724,6 +735,47 @@ do_store_private_key(struct sc_profile *profile)
|
|||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the CA certificate is already present
|
||||
*/
|
||||
static int
|
||||
is_cacert_already_present(struct sc_pkcs15init_certargs *args)
|
||||
{
|
||||
sc_pkcs15_object_t *objs[32];
|
||||
sc_pkcs15_cert_info_t *cinfo;
|
||||
sc_pkcs15_cert_t *cert;
|
||||
int i, count, r, match = 0;
|
||||
|
||||
r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_CERT_X509, objs, 32);
|
||||
if (r <= 0)
|
||||
return 0;
|
||||
|
||||
count = r;
|
||||
for (i = 0; !match && i < count; i++) {
|
||||
cinfo = (sc_pkcs15_cert_info_t *) objs[i]->data;
|
||||
|
||||
if (!cinfo->authority)
|
||||
continue;
|
||||
if (args->label && objs[i]->label
|
||||
&& strcmp(args->label, objs[i]->label))
|
||||
continue;
|
||||
/* XXX we should also match the usage field here */
|
||||
|
||||
/* Compare the DER representation of the certificates */
|
||||
r = sc_pkcs15_read_certificate(p15card, cinfo, &cert);
|
||||
if (r < 0)
|
||||
continue;
|
||||
|
||||
match = cert->data_len == args->der_encoded.len
|
||||
&& !memcmp(cert->data, args->der_encoded.value,
|
||||
cert->data_len);
|
||||
|
||||
sc_pkcs15_free_certificate(cert);
|
||||
}
|
||||
|
||||
return match;
|
||||
}
|
||||
|
||||
/*
|
||||
* Store a public key
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue