mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-23 10:29:58 +01:00
scd:p15: Prepare AODF parsing for other authentication types.
* scd/app-p15.c (auth_type_t): New. (struct aodf_object_s): Add field auth_type. (read_ef_aodf): Distinguish between pin and authkey types. Include the authtype in the verbose mode diags. -- Note that the bulk of changes are just indentation changes. There should be no functional change. Signed-off-by: Werner Koch <wk@gnupg.org> (cherry picked from commit e387cc97c82313457e4f79729a137e5871891bc1)
This commit is contained in:
parent
80cf64c651
commit
29fd805818
769
scd/app-p15.c
769
scd/app-p15.c
@ -156,6 +156,14 @@ typedef enum
|
|||||||
PIN_TYPE_ISO9564_1 = 4
|
PIN_TYPE_ISO9564_1 = 4
|
||||||
} pin_type_t;
|
} pin_type_t;
|
||||||
|
|
||||||
|
/* The AuthenticationTypes as defined in pkcs#15 v1.1 (6.8.1) */
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
AUTH_TYPE_PIN = -1,
|
||||||
|
AUTH_TYPE_BIOMETRIC = 0,
|
||||||
|
AUTH_TYPE_AUTHKEY = 1,
|
||||||
|
AUTH_TYPE_EXTERNAL = 2,
|
||||||
|
} auth_type_t;
|
||||||
|
|
||||||
/* A bit array with for the key usage flags from the
|
/* A bit array with for the key usage flags from the
|
||||||
commonKeyAttributes. */
|
commonKeyAttributes. */
|
||||||
@ -376,6 +384,11 @@ struct aodf_object_s
|
|||||||
/* The file ID of this AODF. */
|
/* The file ID of this AODF. */
|
||||||
unsigned short fid;
|
unsigned short fid;
|
||||||
|
|
||||||
|
/* The type of this authentication object. */
|
||||||
|
auth_type_t auth_type;
|
||||||
|
|
||||||
|
/* Info used for AUTH_TYPE_PIN: */
|
||||||
|
|
||||||
/* The PIN Flags. */
|
/* The PIN Flags. */
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
@ -423,6 +436,9 @@ struct aodf_object_s
|
|||||||
may be NULL. Malloced.*/
|
may be NULL. Malloced.*/
|
||||||
size_t pathlen;
|
size_t pathlen;
|
||||||
unsigned short *path;
|
unsigned short *path;
|
||||||
|
|
||||||
|
/* Info used for AUTH_TYPE_AUTHKEY: */
|
||||||
|
|
||||||
};
|
};
|
||||||
typedef struct aodf_object_s *aodf_object_t;
|
typedef struct aodf_object_s *aodf_object_t;
|
||||||
|
|
||||||
@ -2638,37 +2654,46 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
SEQUENCE {
|
* SEQUENCE {
|
||||||
SEQUENCE { -- CommonObjectAttributes
|
* SEQUENCE { -- CommonObjectAttributes
|
||||||
UTF8String 'specific PIN for DS'
|
* UTF8String 'specific PIN for DS'
|
||||||
BIT STRING 0 unused bits
|
* BIT STRING 0 unused bits
|
||||||
'00000011'B
|
* '00000011'B
|
||||||
}
|
* }
|
||||||
SEQUENCE { -- CommonAuthenticationObjectAttributes
|
* SEQUENCE { -- CommonAuthenticationObjectAttributes
|
||||||
OCTET STRING
|
* OCTET STRING
|
||||||
07 -- iD
|
* 07 -- iD
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
[1] { -- typeAttributes
|
* [1] { -- typeAttributes
|
||||||
SEQUENCE { -- PinAttributes
|
* SEQUENCE { -- PinAttributes
|
||||||
BIT STRING 0 unused bits
|
* BIT STRING 0 unused bits
|
||||||
'0000100000110010'B -- local,initialized,needs-padding
|
* '0000100000110010'B -- local,initialized,needs-padding
|
||||||
-- exchangeRefData
|
* -- exchangeRefData
|
||||||
ENUMERATED 1 -- ascii-numeric
|
* ENUMERATED 1 -- ascii-numeric
|
||||||
INTEGER 6 -- minLength
|
* INTEGER 6 -- minLength
|
||||||
INTEGER 6 -- storedLength
|
* INTEGER 6 -- storedLength
|
||||||
INTEGER 8 -- maxLength
|
* INTEGER 8 -- maxLength
|
||||||
[0]
|
* [0]
|
||||||
02 -- pinReference
|
* 02 -- pinReference
|
||||||
GeneralizedTime 19/04/2002 12:12 GMT -- lastPinChange
|
* GeneralizedTime 19/04/2002 12:12 GMT -- lastPinChange
|
||||||
SEQUENCE {
|
* SEQUENCE {
|
||||||
OCTET STRING
|
* OCTET STRING
|
||||||
3F 00 40 16 -- path to DF of PIN
|
* 3F 00 40 16 -- path to DF of PIN
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
|
*
|
||||||
|
* Or for an authKey:
|
||||||
|
*
|
||||||
|
* [1] { -- typeAttributes
|
||||||
|
* SEQUENCE { -- AuthKeyAttributes
|
||||||
|
* BOOLEAN TRUE -- derivedKey
|
||||||
|
* OCTET STRING 02 -- authKeyId
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
/* Read and parse an Authentication Object Directory File identified
|
/* Read and parse an Authentication Object Directory File identified
|
||||||
by FID. On success a newlist of AODF objects gets stored at RESULT
|
by FID. On success a newlist of AODF objects gets stored at RESULT
|
||||||
@ -2705,6 +2730,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
|
|||||||
size_t nn;
|
size_t nn;
|
||||||
int where;
|
int where;
|
||||||
const char *errstr = NULL;
|
const char *errstr = NULL;
|
||||||
|
auth_type_t auth_type;
|
||||||
aodf_object_t aodf = NULL;
|
aodf_object_t aodf = NULL;
|
||||||
unsigned long ul;
|
unsigned long ul;
|
||||||
const char *s;
|
const char *s;
|
||||||
@ -2717,13 +2743,14 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
|
|||||||
else if (objlen > n)
|
else if (objlen > n)
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
else if (class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE)
|
else if (class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE)
|
||||||
; /* PinAttributes */
|
auth_type = AUTH_TYPE_PIN; /* PinAttributes */
|
||||||
|
else if (class == CLASS_CONTEXT && tag == 1 )
|
||||||
|
auth_type = AUTH_TYPE_AUTHKEY; /* AuthKeyAttributes */
|
||||||
else if (class == CLASS_CONTEXT)
|
else if (class == CLASS_CONTEXT)
|
||||||
{
|
{
|
||||||
switch (tag)
|
switch (tag)
|
||||||
{
|
{
|
||||||
case 0: errstr = "biometric auth types are not supported"; break;
|
case 0: errstr = "biometric auth types are not supported"; break;
|
||||||
case 1: errstr = "authKey auth types are not supported"; break;
|
|
||||||
case 2: errstr = "external auth type are not supported"; break;
|
case 2: errstr = "external auth type are not supported"; break;
|
||||||
default: errstr = "unknown privateKeyObject"; break;
|
default: errstr = "unknown privateKeyObject"; break;
|
||||||
}
|
}
|
||||||
@ -2735,7 +2762,6 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
|
|||||||
goto parse_error;
|
goto parse_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
log_error ("p15: error parsing AODF record: %s\n",
|
log_error ("p15: error parsing AODF record: %s\n",
|
||||||
@ -2752,6 +2778,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
|
|||||||
if (!aodf)
|
if (!aodf)
|
||||||
goto no_core;
|
goto no_core;
|
||||||
aodf->fid = fid;
|
aodf->fid = fid;
|
||||||
|
aodf->auth_type = auth_type;
|
||||||
|
|
||||||
/* Parse the commonObjectAttributes. */
|
/* Parse the commonObjectAttributes. */
|
||||||
where = __LINE__;
|
where = __LINE__;
|
||||||
@ -2810,7 +2837,7 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
|
|||||||
else if (!err && objlen > nn)
|
else if (!err && objlen > nn)
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
else if (class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE)
|
else if (class == CLASS_UNIVERSAL && tag == TAG_SEQUENCE)
|
||||||
; /* A typeAttribute always starts with a sequence */
|
; /* Okay */
|
||||||
else
|
else
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
if (err)
|
if (err)
|
||||||
@ -2818,323 +2845,330 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
|
|||||||
|
|
||||||
nn = objlen;
|
nn = objlen;
|
||||||
|
|
||||||
/* PinFlags */
|
if (auth_type == AUTH_TYPE_PIN)
|
||||||
where = __LINE__;
|
{
|
||||||
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
/* PinFlags */
|
||||||
&ndef, &objlen, &hdrlen);
|
where = __LINE__;
|
||||||
if (!err && (objlen > nn || !objlen
|
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
||||||
|| class != CLASS_UNIVERSAL || tag != TAG_BIT_STRING))
|
&ndef, &objlen, &hdrlen);
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
if (!err && (objlen > nn || !objlen
|
||||||
if (err)
|
|| class != CLASS_UNIVERSAL || tag != TAG_BIT_STRING))
|
||||||
goto parse_error;
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
if (err)
|
||||||
{
|
|
||||||
unsigned int bits, mask;
|
|
||||||
int unused, full;
|
|
||||||
|
|
||||||
unused = *pp++; nn--; objlen--;
|
|
||||||
if ((!objlen && unused) || unused/8 > objlen)
|
|
||||||
{
|
|
||||||
err = gpg_error (GPG_ERR_ENCODING_PROBLEM);
|
|
||||||
goto parse_error;
|
goto parse_error;
|
||||||
}
|
|
||||||
full = objlen - (unused+7)/8;
|
|
||||||
unused %= 8;
|
|
||||||
mask = 0;
|
|
||||||
for (i=1; unused; i <<= 1, unused--)
|
|
||||||
mask |= i;
|
|
||||||
|
|
||||||
/* The first octet */
|
|
||||||
bits = 0;
|
|
||||||
if (objlen)
|
|
||||||
{
|
{
|
||||||
bits = *pp++; nn--; objlen--;
|
unsigned int bits, mask;
|
||||||
if (full)
|
int unused, full;
|
||||||
full--;
|
|
||||||
else
|
unused = *pp++; nn--; objlen--;
|
||||||
|
if ((!objlen && unused) || unused/8 > objlen)
|
||||||
{
|
{
|
||||||
bits &= ~mask;
|
err = gpg_error (GPG_ERR_ENCODING_PROBLEM);
|
||||||
mask = 0;
|
goto parse_error;
|
||||||
}
|
}
|
||||||
}
|
full = objlen - (unused+7)/8;
|
||||||
if ((bits & 0x80)) /* ASN.1 bit 0. */
|
unused %= 8;
|
||||||
aodf->pinflags.case_sensitive = 1;
|
mask = 0;
|
||||||
if ((bits & 0x40)) /* ASN.1 bit 1. */
|
for (i=1; unused; i <<= 1, unused--)
|
||||||
aodf->pinflags.local = 1;
|
mask |= i;
|
||||||
if ((bits & 0x20))
|
|
||||||
aodf->pinflags.change_disabled = 1;
|
/* The first octet */
|
||||||
if ((bits & 0x10))
|
bits = 0;
|
||||||
aodf->pinflags.unblock_disabled = 1;
|
if (objlen)
|
||||||
if ((bits & 0x08))
|
|
||||||
aodf->pinflags.initialized = 1;
|
|
||||||
if ((bits & 0x04))
|
|
||||||
aodf->pinflags.needs_padding = 1;
|
|
||||||
if ((bits & 0x02))
|
|
||||||
aodf->pinflags.unblocking_pin = 1;
|
|
||||||
if ((bits & 0x01))
|
|
||||||
aodf->pinflags.so_pin = 1;
|
|
||||||
/* The second octet. */
|
|
||||||
bits = 0;
|
|
||||||
if (objlen)
|
|
||||||
{
|
|
||||||
bits = *pp++; nn--; objlen--;
|
|
||||||
if (full)
|
|
||||||
full--;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
bits &= ~mask;
|
bits = *pp++; nn--; objlen--;
|
||||||
|
if (full)
|
||||||
|
full--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bits &= ~mask;
|
||||||
|
mask = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if ((bits & 0x80)) /* ASN.1 bit 0. */
|
||||||
|
aodf->pinflags.case_sensitive = 1;
|
||||||
|
if ((bits & 0x40)) /* ASN.1 bit 1. */
|
||||||
|
aodf->pinflags.local = 1;
|
||||||
|
if ((bits & 0x20))
|
||||||
|
aodf->pinflags.change_disabled = 1;
|
||||||
|
if ((bits & 0x10))
|
||||||
|
aodf->pinflags.unblock_disabled = 1;
|
||||||
|
if ((bits & 0x08))
|
||||||
|
aodf->pinflags.initialized = 1;
|
||||||
|
if ((bits & 0x04))
|
||||||
|
aodf->pinflags.needs_padding = 1;
|
||||||
|
if ((bits & 0x02))
|
||||||
|
aodf->pinflags.unblocking_pin = 1;
|
||||||
|
if ((bits & 0x01))
|
||||||
|
aodf->pinflags.so_pin = 1;
|
||||||
|
/* The second octet. */
|
||||||
|
bits = 0;
|
||||||
|
if (objlen)
|
||||||
|
{
|
||||||
|
bits = *pp++; nn--; objlen--;
|
||||||
|
if (full)
|
||||||
|
full--;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bits &= ~mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((bits & 0x80))
|
||||||
|
aodf->pinflags.disable_allowed = 1;
|
||||||
|
if ((bits & 0x40))
|
||||||
|
aodf->pinflags.integrity_protected = 1;
|
||||||
|
if ((bits & 0x20))
|
||||||
|
aodf->pinflags.confidentiality_protected = 1;
|
||||||
|
if ((bits & 0x10))
|
||||||
|
aodf->pinflags.exchange_ref_data = 1;
|
||||||
|
/* Skip remaining bits. */
|
||||||
|
pp += objlen;
|
||||||
|
nn -= objlen;
|
||||||
}
|
}
|
||||||
if ((bits & 0x80))
|
|
||||||
aodf->pinflags.disable_allowed = 1;
|
|
||||||
if ((bits & 0x40))
|
|
||||||
aodf->pinflags.integrity_protected = 1;
|
|
||||||
if ((bits & 0x20))
|
|
||||||
aodf->pinflags.confidentiality_protected = 1;
|
|
||||||
if ((bits & 0x10))
|
|
||||||
aodf->pinflags.exchange_ref_data = 1;
|
|
||||||
/* Skip remaining bits. */
|
|
||||||
pp += objlen;
|
|
||||||
nn -= objlen;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* PinType */
|
||||||
|
where = __LINE__;
|
||||||
|
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
||||||
|
&ndef, &objlen, &hdrlen);
|
||||||
|
if (!err && (objlen > nn
|
||||||
|
|| class != CLASS_UNIVERSAL || tag != TAG_ENUMERATED))
|
||||||
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
if (!err && objlen > sizeof (ul))
|
||||||
|
err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
|
||||||
|
if (err)
|
||||||
|
goto parse_error;
|
||||||
|
|
||||||
/* PinType */
|
|
||||||
where = __LINE__;
|
|
||||||
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
|
||||||
&ndef, &objlen, &hdrlen);
|
|
||||||
if (!err && (objlen > nn
|
|
||||||
|| class != CLASS_UNIVERSAL || tag != TAG_ENUMERATED))
|
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
|
||||||
if (!err && objlen > sizeof (ul))
|
|
||||||
err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
|
|
||||||
if (err)
|
|
||||||
goto parse_error;
|
|
||||||
|
|
||||||
for (ul=0; objlen; objlen--)
|
|
||||||
{
|
|
||||||
ul <<= 8;
|
|
||||||
ul |= (*pp++) & 0xff;
|
|
||||||
nn--;
|
|
||||||
}
|
|
||||||
aodf->pintype = ul;
|
|
||||||
|
|
||||||
|
|
||||||
/* minLength */
|
|
||||||
where = __LINE__;
|
|
||||||
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
|
||||||
&ndef, &objlen, &hdrlen);
|
|
||||||
if (!err && (objlen > nn
|
|
||||||
|| class != CLASS_UNIVERSAL || tag != TAG_INTEGER))
|
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
|
||||||
if (!err && objlen > sizeof (ul))
|
|
||||||
err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
|
|
||||||
if (err)
|
|
||||||
goto parse_error;
|
|
||||||
for (ul=0; objlen; objlen--)
|
|
||||||
{
|
|
||||||
ul <<= 8;
|
|
||||||
ul |= (*pp++) & 0xff;
|
|
||||||
nn--;
|
|
||||||
}
|
|
||||||
aodf->min_length = ul;
|
|
||||||
|
|
||||||
|
|
||||||
/* storedLength */
|
|
||||||
where = __LINE__;
|
|
||||||
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
|
||||||
&ndef, &objlen, &hdrlen);
|
|
||||||
if (!err && (objlen > nn
|
|
||||||
|| class != CLASS_UNIVERSAL || tag != TAG_INTEGER))
|
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
|
||||||
if (!err && objlen > sizeof (ul))
|
|
||||||
err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
|
|
||||||
if (err)
|
|
||||||
goto parse_error;
|
|
||||||
for (ul=0; objlen; objlen--)
|
|
||||||
{
|
|
||||||
ul <<= 8;
|
|
||||||
ul |= (*pp++) & 0xff;
|
|
||||||
nn--;
|
|
||||||
}
|
|
||||||
aodf->stored_length = ul;
|
|
||||||
|
|
||||||
/* optional maxLength */
|
|
||||||
where = __LINE__;
|
|
||||||
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
|
||||||
&ndef, &objlen, &hdrlen);
|
|
||||||
if (gpg_err_code (err) == GPG_ERR_EOF)
|
|
||||||
goto ready;
|
|
||||||
if (!err && objlen > nn)
|
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
|
||||||
if (err)
|
|
||||||
goto parse_error;
|
|
||||||
if (class == CLASS_UNIVERSAL && tag == TAG_INTEGER)
|
|
||||||
{
|
|
||||||
if (objlen > sizeof (ul))
|
|
||||||
{
|
|
||||||
err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
for (ul=0; objlen; objlen--)
|
for (ul=0; objlen; objlen--)
|
||||||
{
|
{
|
||||||
ul <<= 8;
|
ul <<= 8;
|
||||||
ul |= (*pp++) & 0xff;
|
ul |= (*pp++) & 0xff;
|
||||||
nn--;
|
nn--;
|
||||||
}
|
}
|
||||||
aodf->max_length = ul;
|
aodf->pintype = ul;
|
||||||
aodf->max_length_valid = 1;
|
|
||||||
|
|
||||||
|
/* minLength */
|
||||||
where = __LINE__;
|
where = __LINE__;
|
||||||
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
||||||
&ndef, &objlen, &hdrlen);
|
&ndef, &objlen, &hdrlen);
|
||||||
if (gpg_err_code (err) == GPG_ERR_EOF)
|
if (!err && (objlen > nn
|
||||||
goto ready;
|
|
||||||
if (!err && objlen > nn)
|
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
|
||||||
if (err)
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Optional pinReference. */
|
|
||||||
if (class == CLASS_CONTEXT && tag == 0)
|
|
||||||
{
|
|
||||||
if (objlen > sizeof (ul))
|
|
||||||
{
|
|
||||||
err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
for (ul=0; objlen; objlen--)
|
|
||||||
{
|
|
||||||
ul <<= 8;
|
|
||||||
ul |= (*pp++) & 0xff;
|
|
||||||
nn--;
|
|
||||||
}
|
|
||||||
aodf->pin_reference = ul;
|
|
||||||
aodf->pin_reference_valid = 1;
|
|
||||||
|
|
||||||
where = __LINE__;
|
|
||||||
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
|
||||||
&ndef, &objlen, &hdrlen);
|
|
||||||
if (gpg_err_code (err) == GPG_ERR_EOF)
|
|
||||||
goto ready;
|
|
||||||
if (!err && objlen > nn)
|
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
|
||||||
if (err)
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Optional padChar. */
|
|
||||||
if (class == CLASS_UNIVERSAL && tag == TAG_OCTET_STRING)
|
|
||||||
{
|
|
||||||
if (objlen != 1)
|
|
||||||
{
|
|
||||||
errstr = "padChar is not of size(1)";
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
aodf->pad_char = *pp++; nn--;
|
|
||||||
aodf->pad_char_valid = 1;
|
|
||||||
|
|
||||||
where = __LINE__;
|
|
||||||
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
|
||||||
&ndef, &objlen, &hdrlen);
|
|
||||||
if (gpg_err_code (err) == GPG_ERR_EOF)
|
|
||||||
goto ready;
|
|
||||||
if (!err && objlen > nn)
|
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
|
||||||
if (err)
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip optional lastPinChange. */
|
|
||||||
if (class == CLASS_UNIVERSAL && tag == TAG_GENERALIZED_TIME)
|
|
||||||
{
|
|
||||||
pp += objlen;
|
|
||||||
nn -= objlen;
|
|
||||||
|
|
||||||
where = __LINE__;
|
|
||||||
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
|
||||||
&ndef, &objlen, &hdrlen);
|
|
||||||
if (gpg_err_code (err) == GPG_ERR_EOF)
|
|
||||||
goto ready;
|
|
||||||
if (!err && objlen > nn)
|
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
|
||||||
if (err)
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Optional Path object. */
|
|
||||||
if (class == CLASS_UNIVERSAL || tag == TAG_SEQUENCE)
|
|
||||||
{
|
|
||||||
const unsigned char *ppp = pp;
|
|
||||||
size_t nnn = objlen;
|
|
||||||
|
|
||||||
pp += objlen;
|
|
||||||
nn -= objlen;
|
|
||||||
|
|
||||||
where = __LINE__;
|
|
||||||
err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
|
|
||||||
&ndef, &objlen, &hdrlen);
|
|
||||||
if (!err && objlen > nnn)
|
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
|
||||||
if (err)
|
|
||||||
goto parse_error;
|
|
||||||
|
|
||||||
/* Make sure that the next element is a non zero FID and of
|
|
||||||
even length (FID are two bytes each). */
|
|
||||||
if (class != CLASS_UNIVERSAL || tag != TAG_OCTET_STRING
|
|
||||||
|| !objlen || (objlen & 1) )
|
|
||||||
{
|
|
||||||
errstr = "invalid path reference";
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
aodf->pathlen = objlen/2;
|
|
||||||
aodf->path = xtrycalloc (aodf->pathlen, sizeof *aodf->path);
|
|
||||||
if (!aodf->path)
|
|
||||||
goto no_core;
|
|
||||||
for (i=0; i < aodf->pathlen; i++, ppp += 2, nnn -= 2)
|
|
||||||
aodf->path[i] = ((ppp[0] << 8) | ppp[1]);
|
|
||||||
|
|
||||||
if (nnn)
|
|
||||||
{
|
|
||||||
/* An index and length follows. */
|
|
||||||
aodf->have_off = 1;
|
|
||||||
where = __LINE__;
|
|
||||||
err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
|
|
||||||
&ndef, &objlen, &hdrlen);
|
|
||||||
if (!err && (objlen > nnn
|
|
||||||
|| class != CLASS_UNIVERSAL || tag != TAG_INTEGER))
|
|| class != CLASS_UNIVERSAL || tag != TAG_INTEGER))
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
if (err)
|
if (!err && objlen > sizeof (ul))
|
||||||
goto parse_error;
|
err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
|
||||||
|
if (err)
|
||||||
|
goto parse_error;
|
||||||
|
for (ul=0; objlen; objlen--)
|
||||||
|
{
|
||||||
|
ul <<= 8;
|
||||||
|
ul |= (*pp++) & 0xff;
|
||||||
|
nn--;
|
||||||
|
}
|
||||||
|
aodf->min_length = ul;
|
||||||
|
|
||||||
|
/* storedLength */
|
||||||
|
where = __LINE__;
|
||||||
|
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
||||||
|
&ndef, &objlen, &hdrlen);
|
||||||
|
if (!err && (objlen > nn
|
||||||
|
|| class != CLASS_UNIVERSAL || tag != TAG_INTEGER))
|
||||||
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
if (!err && objlen > sizeof (ul))
|
||||||
|
err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
|
||||||
|
if (err)
|
||||||
|
goto parse_error;
|
||||||
|
for (ul=0; objlen; objlen--)
|
||||||
|
{
|
||||||
|
ul <<= 8;
|
||||||
|
ul |= (*pp++) & 0xff;
|
||||||
|
nn--;
|
||||||
|
}
|
||||||
|
aodf->stored_length = ul;
|
||||||
|
|
||||||
|
/* optional maxLength */
|
||||||
|
where = __LINE__;
|
||||||
|
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
||||||
|
&ndef, &objlen, &hdrlen);
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_EOF)
|
||||||
|
goto ready;
|
||||||
|
if (!err && objlen > nn)
|
||||||
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
if (err)
|
||||||
|
goto parse_error;
|
||||||
|
if (class == CLASS_UNIVERSAL && tag == TAG_INTEGER)
|
||||||
|
{
|
||||||
|
if (objlen > sizeof (ul))
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
|
||||||
|
goto parse_error;
|
||||||
|
}
|
||||||
for (ul=0; objlen; objlen--)
|
for (ul=0; objlen; objlen--)
|
||||||
{
|
{
|
||||||
ul <<= 8;
|
ul <<= 8;
|
||||||
ul |= (*ppp++) & 0xff;
|
ul |= (*pp++) & 0xff;
|
||||||
nnn--;
|
nn--;
|
||||||
}
|
}
|
||||||
aodf->off = ul;
|
aodf->max_length = ul;
|
||||||
|
aodf->max_length_valid = 1;
|
||||||
|
|
||||||
|
where = __LINE__;
|
||||||
|
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
||||||
|
&ndef, &objlen, &hdrlen);
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_EOF)
|
||||||
|
goto ready;
|
||||||
|
if (!err && objlen > nn)
|
||||||
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
if (err)
|
||||||
|
goto parse_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional pinReference. */
|
||||||
|
if (class == CLASS_CONTEXT && tag == 0)
|
||||||
|
{
|
||||||
|
if (objlen > sizeof (ul))
|
||||||
|
{
|
||||||
|
err = gpg_error (GPG_ERR_UNSUPPORTED_ENCODING);
|
||||||
|
goto parse_error;
|
||||||
|
}
|
||||||
|
for (ul=0; objlen; objlen--)
|
||||||
|
{
|
||||||
|
ul <<= 8;
|
||||||
|
ul |= (*pp++) & 0xff;
|
||||||
|
nn--;
|
||||||
|
}
|
||||||
|
aodf->pin_reference = ul;
|
||||||
|
aodf->pin_reference_valid = 1;
|
||||||
|
|
||||||
|
where = __LINE__;
|
||||||
|
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
||||||
|
&ndef, &objlen, &hdrlen);
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_EOF)
|
||||||
|
goto ready;
|
||||||
|
if (!err && objlen > nn)
|
||||||
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
if (err)
|
||||||
|
goto parse_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional padChar. */
|
||||||
|
if (class == CLASS_UNIVERSAL && tag == TAG_OCTET_STRING)
|
||||||
|
{
|
||||||
|
if (objlen != 1)
|
||||||
|
{
|
||||||
|
errstr = "padChar is not of size(1)";
|
||||||
|
goto parse_error;
|
||||||
|
}
|
||||||
|
aodf->pad_char = *pp++; nn--;
|
||||||
|
aodf->pad_char_valid = 1;
|
||||||
|
|
||||||
|
where = __LINE__;
|
||||||
|
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
||||||
|
&ndef, &objlen, &hdrlen);
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_EOF)
|
||||||
|
goto ready;
|
||||||
|
if (!err && objlen > nn)
|
||||||
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
if (err)
|
||||||
|
goto parse_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip optional lastPinChange. */
|
||||||
|
if (class == CLASS_UNIVERSAL && tag == TAG_GENERALIZED_TIME)
|
||||||
|
{
|
||||||
|
pp += objlen;
|
||||||
|
nn -= objlen;
|
||||||
|
|
||||||
|
where = __LINE__;
|
||||||
|
err = parse_ber_header (&pp, &nn, &class, &tag, &constructed,
|
||||||
|
&ndef, &objlen, &hdrlen);
|
||||||
|
if (gpg_err_code (err) == GPG_ERR_EOF)
|
||||||
|
goto ready;
|
||||||
|
if (!err && objlen > nn)
|
||||||
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
if (err)
|
||||||
|
goto parse_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Optional Path object. */
|
||||||
|
if (class == CLASS_UNIVERSAL || tag == TAG_SEQUENCE)
|
||||||
|
{
|
||||||
|
const unsigned char *ppp = pp;
|
||||||
|
size_t nnn = objlen;
|
||||||
|
|
||||||
|
pp += objlen;
|
||||||
|
nn -= objlen;
|
||||||
|
|
||||||
where = __LINE__;
|
where = __LINE__;
|
||||||
err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
|
err = parse_ber_header (&ppp, &nnn, &class, &tag, &constructed,
|
||||||
&ndef, &objlen, &hdrlen);
|
&ndef, &objlen, &hdrlen);
|
||||||
if (!err && (objlen > nnn
|
if (!err && objlen > nnn)
|
||||||
|| class != CLASS_CONTEXT || tag != 0))
|
|
||||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
if (err)
|
if (err)
|
||||||
goto parse_error;
|
goto parse_error;
|
||||||
|
|
||||||
for (ul=0; objlen; objlen--)
|
/* Make sure that the next element has a path of even
|
||||||
|
* length (FIDs are two bytes each). */
|
||||||
|
if (class != CLASS_UNIVERSAL || tag != TAG_OCTET_STRING
|
||||||
|
|| (objlen & 1) )
|
||||||
{
|
{
|
||||||
ul <<= 8;
|
errstr = "invalid path reference";
|
||||||
ul |= (*ppp++) & 0xff;
|
goto parse_error;
|
||||||
nnn--;
|
}
|
||||||
|
|
||||||
|
aodf->pathlen = objlen/2;
|
||||||
|
aodf->path = xtrycalloc (aodf->pathlen, sizeof *aodf->path);
|
||||||
|
if (!aodf->path)
|
||||||
|
goto no_core;
|
||||||
|
for (i=0; i < aodf->pathlen; i++, ppp += 2, nnn -= 2)
|
||||||
|
aodf->path[i] = ((ppp[0] << 8) | ppp[1]);
|
||||||
|
|
||||||
|
if (nnn)
|
||||||
|
{
|
||||||
|
/* An index and length follows. */
|
||||||
|
aodf->have_off = 1;
|
||||||
|
where = __LINE__;
|
||||||
|
err = parse_ber_header (&ppp, &nnn, &class, &tag,
|
||||||
|
&constructed,
|
||||||
|
&ndef, &objlen, &hdrlen);
|
||||||
|
if (!err && (objlen > nnn
|
||||||
|
|| class != CLASS_UNIVERSAL
|
||||||
|
|| tag != TAG_INTEGER))
|
||||||
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
if (err)
|
||||||
|
goto parse_error;
|
||||||
|
|
||||||
|
for (ul=0; objlen; objlen--)
|
||||||
|
{
|
||||||
|
ul <<= 8;
|
||||||
|
ul |= (*ppp++) & 0xff;
|
||||||
|
nnn--;
|
||||||
|
}
|
||||||
|
aodf->off = ul;
|
||||||
|
|
||||||
|
where = __LINE__;
|
||||||
|
err = parse_ber_header (&ppp, &nnn, &class, &tag,
|
||||||
|
&constructed,
|
||||||
|
&ndef, &objlen, &hdrlen);
|
||||||
|
if (!err && (objlen > nnn
|
||||||
|
|| class != CLASS_CONTEXT || tag != 0))
|
||||||
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
|
if (err)
|
||||||
|
goto parse_error;
|
||||||
|
|
||||||
|
for (ul=0; objlen; objlen--)
|
||||||
|
{
|
||||||
|
ul <<= 8;
|
||||||
|
ul |= (*ppp++) & 0xff;
|
||||||
|
nnn--;
|
||||||
|
}
|
||||||
|
aodf->len = ul;
|
||||||
}
|
}
|
||||||
aodf->len = ul;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (auth_type == AUTH_TYPE_AUTHKEY)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Ignore further objects which might be there due to future
|
/* Ignore further objects which might be there due to future
|
||||||
extensions of pkcs#15. */
|
extensions of pkcs#15. */
|
||||||
@ -3150,6 +3184,9 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
|
|||||||
if (aodf->label)
|
if (aodf->label)
|
||||||
log_printf (" (%s)", aodf->label);
|
log_printf (" (%s)", aodf->label);
|
||||||
log_info ("p15: ");
|
log_info ("p15: ");
|
||||||
|
log_printf (" %s",
|
||||||
|
aodf->auth_type == AUTH_TYPE_PIN? "pin" :
|
||||||
|
aodf->auth_type == AUTH_TYPE_AUTHKEY? "authkey" : "?");
|
||||||
if (aodf->pathlen)
|
if (aodf->pathlen)
|
||||||
{
|
{
|
||||||
log_printf (" path=");
|
log_printf (" path=");
|
||||||
@ -3164,58 +3201,64 @@ read_ef_aodf (app_t app, unsigned short fid, aodf_object_t *result)
|
|||||||
for (i=0; i < aodf->authidlen; i++)
|
for (i=0; i < aodf->authidlen; i++)
|
||||||
log_printf ("%02X", aodf->authid[i]);
|
log_printf ("%02X", aodf->authid[i]);
|
||||||
}
|
}
|
||||||
if (aodf->pin_reference_valid)
|
if (aodf->auth_type == AUTH_TYPE_PIN)
|
||||||
log_printf (" pinref=0x%02lX", aodf->pin_reference);
|
{
|
||||||
log_printf (" min=%lu", aodf->min_length);
|
if (aodf->pin_reference_valid)
|
||||||
log_printf (" stored=%lu", aodf->stored_length);
|
log_printf (" pinref=0x%02lX", aodf->pin_reference);
|
||||||
if (aodf->max_length_valid)
|
log_printf (" min=%lu", aodf->min_length);
|
||||||
log_printf (" max=%lu", aodf->max_length);
|
log_printf (" stored=%lu", aodf->stored_length);
|
||||||
if (aodf->pad_char_valid)
|
if (aodf->max_length_valid)
|
||||||
log_printf (" pad=0x%02x", aodf->pad_char);
|
log_printf (" max=%lu", aodf->max_length);
|
||||||
|
if (aodf->pad_char_valid)
|
||||||
|
log_printf (" pad=0x%02x", aodf->pad_char);
|
||||||
|
|
||||||
log_info ("p15: flags=");
|
log_info ("p15: flags=");
|
||||||
s = "";
|
s = "";
|
||||||
if (aodf->pinflags.case_sensitive)
|
if (aodf->pinflags.case_sensitive)
|
||||||
log_printf ("%scase_sensitive", s), s = ",";
|
log_printf ("%scase_sensitive", s), s = ",";
|
||||||
if (aodf->pinflags.local)
|
if (aodf->pinflags.local)
|
||||||
log_printf ("%slocal", s), s = ",";
|
log_printf ("%slocal", s), s = ",";
|
||||||
if (aodf->pinflags.change_disabled)
|
if (aodf->pinflags.change_disabled)
|
||||||
log_printf ("%schange_disabled", s), s = ",";
|
log_printf ("%schange_disabled", s), s = ",";
|
||||||
if (aodf->pinflags.unblock_disabled)
|
if (aodf->pinflags.unblock_disabled)
|
||||||
log_printf ("%sunblock_disabled", s), s = ",";
|
log_printf ("%sunblock_disabled", s), s = ",";
|
||||||
if (aodf->pinflags.initialized)
|
if (aodf->pinflags.initialized)
|
||||||
log_printf ("%sinitialized", s), s = ",";
|
log_printf ("%sinitialized", s), s = ",";
|
||||||
if (aodf->pinflags.needs_padding)
|
if (aodf->pinflags.needs_padding)
|
||||||
log_printf ("%sneeds_padding", s), s = ",";
|
log_printf ("%sneeds_padding", s), s = ",";
|
||||||
if (aodf->pinflags.unblocking_pin)
|
if (aodf->pinflags.unblocking_pin)
|
||||||
log_printf ("%sunblocking_pin", s), s = ",";
|
log_printf ("%sunblocking_pin", s), s = ",";
|
||||||
if (aodf->pinflags.so_pin)
|
if (aodf->pinflags.so_pin)
|
||||||
log_printf ("%sso_pin", s), s = ",";
|
log_printf ("%sso_pin", s), s = ",";
|
||||||
if (aodf->pinflags.disable_allowed)
|
if (aodf->pinflags.disable_allowed)
|
||||||
log_printf ("%sdisable_allowed", s), s = ",";
|
log_printf ("%sdisable_allowed", s), s = ",";
|
||||||
if (aodf->pinflags.integrity_protected)
|
if (aodf->pinflags.integrity_protected)
|
||||||
log_printf ("%sintegrity_protected", s), s = ",";
|
log_printf ("%sintegrity_protected", s), s = ",";
|
||||||
if (aodf->pinflags.confidentiality_protected)
|
if (aodf->pinflags.confidentiality_protected)
|
||||||
log_printf ("%sconfidentiality_protected", s), s = ",";
|
log_printf ("%sconfidentiality_protected", s), s = ",";
|
||||||
if (aodf->pinflags.exchange_ref_data)
|
if (aodf->pinflags.exchange_ref_data)
|
||||||
log_printf ("%sexchange_ref_data", s), s = ",";
|
log_printf ("%sexchange_ref_data", s), s = ",";
|
||||||
{
|
|
||||||
char numbuf[50];
|
|
||||||
const char *s2;
|
|
||||||
|
|
||||||
switch (aodf->pintype)
|
|
||||||
{
|
{
|
||||||
case PIN_TYPE_BCD: s2 = "bcd"; break;
|
char numbuf[50];
|
||||||
case PIN_TYPE_ASCII_NUMERIC: s2 = "ascii-numeric"; break;
|
const char *s2;
|
||||||
case PIN_TYPE_UTF8: s2 = "utf8"; break;
|
|
||||||
case PIN_TYPE_HALF_NIBBLE_BCD: s2 = "half-nibble-bcd"; break;
|
switch (aodf->pintype)
|
||||||
case PIN_TYPE_ISO9564_1: s2 = "iso9564-1"; break;
|
{
|
||||||
default:
|
case PIN_TYPE_BCD: s2 = "bcd"; break;
|
||||||
sprintf (numbuf, "%lu", (unsigned long)aodf->pintype);
|
case PIN_TYPE_ASCII_NUMERIC: s2 = "ascii-numeric"; break;
|
||||||
s2 = numbuf;
|
case PIN_TYPE_UTF8: s2 = "utf8"; break;
|
||||||
|
case PIN_TYPE_HALF_NIBBLE_BCD: s2 = "half-nibble-bcd"; break;
|
||||||
|
case PIN_TYPE_ISO9564_1: s2 = "iso9564-1"; break;
|
||||||
|
default:
|
||||||
|
sprintf (numbuf, "%lu", (unsigned long)aodf->pintype);
|
||||||
|
s2 = numbuf;
|
||||||
|
}
|
||||||
|
log_printf ("%stype=%s", s, s2); s = ",";
|
||||||
}
|
}
|
||||||
log_printf ("%stype=%s", s, s2); s = ",";
|
}
|
||||||
}
|
else if (aodf->auth_type == AUTH_TYPE_AUTHKEY)
|
||||||
|
{
|
||||||
|
}
|
||||||
log_printf ("\n");
|
log_printf ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user