mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
scd:piv: Avoid conflict when writing a cert.
* scd/app-piv.c (map_curve_name_to_oid): New. (my_cmp_public_key): New. (do_writecert): Replace simple memcmp by cmp_canon_sexp. -- GnuPG-bug-id: 5061
This commit is contained in:
parent
b6ba6a79ce
commit
fbc1b199fd
@ -3355,6 +3355,66 @@ do_genkey (app_t app, ctrl_t ctrl, const char *keyrefstr, const char *keytype,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Map some names to an OID. */
|
||||
static const unsigned char *
|
||||
map_curve_name_to_oid (const unsigned char *name, size_t *namelenp)
|
||||
{
|
||||
if (*namelenp == 8 && !memcmp (name, "nistp256", 8))
|
||||
{
|
||||
*namelenp = 19;
|
||||
return "1.2.840.10045.3.1.7";
|
||||
}
|
||||
if (*namelenp == 8 && !memcmp (name, "nistp384", 8))
|
||||
{
|
||||
*namelenp = 12;
|
||||
return "1.3.132.0.34";
|
||||
}
|
||||
if (*namelenp == 8 && !memcmp (name, "nistp521", 8))
|
||||
{
|
||||
*namelenp = 12;
|
||||
return "1.3.132.0.35";
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
/* Communication object for my_cmp_public_key. */
|
||||
struct my_cmp_public_key_parm_s {
|
||||
int curve_seen;
|
||||
};
|
||||
|
||||
/* Compare function used with cmp_canon_sexp. */
|
||||
static int
|
||||
my_cmp_public_key (void *opaque, int depth,
|
||||
const unsigned char *aval, size_t alen,
|
||||
const unsigned char *bval, size_t blen)
|
||||
{
|
||||
struct my_cmp_public_key_parm_s *parm = opaque;
|
||||
|
||||
(void)depth;
|
||||
|
||||
if (parm->curve_seen)
|
||||
{
|
||||
/* Last token was "curve" - canonicalize its argument. */
|
||||
parm->curve_seen = 0;
|
||||
aval = map_curve_name_to_oid (aval, &alen);
|
||||
bval = map_curve_name_to_oid (bval, &blen);
|
||||
}
|
||||
else if (alen == 5 && !memcmp (aval, "curve", 5))
|
||||
parm->curve_seen = 1;
|
||||
else
|
||||
parm->curve_seen = 0;
|
||||
|
||||
if (alen > blen)
|
||||
return 1;
|
||||
else if (alen < blen)
|
||||
return -1;
|
||||
else
|
||||
return memcmp (aval, bval, alen);
|
||||
}
|
||||
|
||||
|
||||
/* Write the certificate (CERT,CERTLEN) to the card at CERTREFSTR.
|
||||
* CERTREFSTR is either the OID of the certificate's container data
|
||||
* object or of the form "PIV.<two_hexdigit_keyref>". */
|
||||
@ -3370,6 +3430,7 @@ do_writecert (app_t app, ctrl_t ctrl,
|
||||
unsigned char *pk = NULL;
|
||||
unsigned char *orig_pk = NULL;
|
||||
size_t pklen, orig_pklen;
|
||||
struct my_cmp_public_key_parm_s cmp_parm = { 0 };
|
||||
|
||||
(void)ctrl;
|
||||
(void)pincb; /* Not used; instead authentication is needed. */
|
||||
@ -3403,7 +3464,8 @@ do_writecert (app_t app, ctrl_t ctrl,
|
||||
err = app_help_pubkey_from_cert (cert, certlen, &pk, &pklen);
|
||||
if (err)
|
||||
goto leave; /* No public key in new certificate. */
|
||||
if (orig_pklen != pklen || memcmp (orig_pk, pk, pklen))
|
||||
if (cmp_canon_sexp (orig_pk, orig_pklen, pk, pklen,
|
||||
my_cmp_public_key, &cmp_parm))
|
||||
{
|
||||
err = gpg_error (GPG_ERR_CONFLICT);
|
||||
goto leave;
|
||||
|
Loading…
x
Reference in New Issue
Block a user