mirror of
git://git.gnupg.org/gnupg.git
synced 2024-09-22 15:11:41 +02: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.
|
/* Write the certificate (CERT,CERTLEN) to the card at CERTREFSTR.
|
||||||
* CERTREFSTR is either the OID of the certificate's container data
|
* CERTREFSTR is either the OID of the certificate's container data
|
||||||
* object or of the form "PIV.<two_hexdigit_keyref>". */
|
* 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 *pk = NULL;
|
||||||
unsigned char *orig_pk = NULL;
|
unsigned char *orig_pk = NULL;
|
||||||
size_t pklen, orig_pklen;
|
size_t pklen, orig_pklen;
|
||||||
|
struct my_cmp_public_key_parm_s cmp_parm = { 0 };
|
||||||
|
|
||||||
(void)ctrl;
|
(void)ctrl;
|
||||||
(void)pincb; /* Not used; instead authentication is needed. */
|
(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);
|
err = app_help_pubkey_from_cert (cert, certlen, &pk, &pklen);
|
||||||
if (err)
|
if (err)
|
||||||
goto leave; /* No public key in new certificate. */
|
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);
|
err = gpg_error (GPG_ERR_CONFLICT);
|
||||||
goto leave;
|
goto leave;
|
||||||
|
Loading…
Reference in New Issue
Block a user