mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
sm: Remove duplicated code.
* sm/minip12.c (struct tag_info): Change type of length and nhdr. (dump_tag_info): Adjust. (parse_tag): Re-implement using the parse_ber_header.
This commit is contained in:
parent
25b59cf6ce
commit
c926967d85
@ -150,13 +150,16 @@ find_tlv_unchecked (const unsigned char *buffer, size_t length,
|
|||||||
|
|
||||||
|
|
||||||
/* ASN.1 BER parser: Parse BUFFER of length SIZE and return the tag
|
/* ASN.1 BER parser: Parse BUFFER of length SIZE and return the tag
|
||||||
and the length part from the TLV triplet. Update BUFFER and SIZE
|
* and the length part from the TLV triplet. Update BUFFER and SIZE
|
||||||
on success. */
|
* on success. Note that this function does not check that the value
|
||||||
|
* fits into the provided buffer; this allows to work on the TL part
|
||||||
|
* of a TLV. */
|
||||||
gpg_error_t
|
gpg_error_t
|
||||||
parse_ber_header (unsigned char const **buffer, size_t *size,
|
parse_ber_header (unsigned char const **buffer, size_t *size,
|
||||||
int *r_class, int *r_tag,
|
int *r_class, int *r_tag,
|
||||||
int *r_constructed, int *r_ndef,
|
int *r_constructed, int *r_ndef,
|
||||||
size_t *r_length, size_t *r_nhdr){
|
size_t *r_length, size_t *r_nhdr)
|
||||||
|
{
|
||||||
int c;
|
int c;
|
||||||
unsigned long tag;
|
unsigned long tag;
|
||||||
const unsigned char *buf = *buffer;
|
const unsigned char *buf = *buffer;
|
||||||
|
109
sm/minip12.c
109
sm/minip12.c
@ -138,8 +138,8 @@ struct tag_info
|
|||||||
int class;
|
int class;
|
||||||
int is_constructed;
|
int is_constructed;
|
||||||
unsigned long tag;
|
unsigned long tag;
|
||||||
unsigned long length; /* length part of the TLV */
|
size_t length; /* length part of the TLV */
|
||||||
int nhdr;
|
size_t nhdr;
|
||||||
int ndef; /* It is an indefinite length */
|
int ndef; /* It is an indefinite length */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -174,14 +174,17 @@ p12_set_verbosity (int verbose)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* static void */
|
#if 0
|
||||||
/* dump_tag_info (struct tag_info *ti) */
|
static void
|
||||||
/* { */
|
dump_tag_info (const char *text, struct tag_info *ti)
|
||||||
/* log_debug ("p12_parse: ti.class=%d tag=%lu len=%lu nhdr=%d %s%s\n", */
|
{
|
||||||
/* ti->class, ti->tag, ti->length, ti->nhdr, */
|
log_debug ("p12_parse(%s): ti.class=%d tag=%lu len=%zu nhdr=%zu %s%s\n",
|
||||||
/* ti->is_constructed?" cons":"", */
|
text,
|
||||||
/* ti->ndef?" ndef":""); */
|
ti->class, ti->tag, ti->length, ti->nhdr,
|
||||||
/* } */
|
ti->is_constructed?" cons":"",
|
||||||
|
ti->ndef?" ndef":"");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* Wrapper around tlv_builder_add_ptr to add an OID. When we
|
/* Wrapper around tlv_builder_add_ptr to add an OID. When we
|
||||||
@ -277,84 +280,28 @@ builder_add_mpi (tlv_builder_t tb, int class, int tag, gcry_mpi_t mpi,
|
|||||||
|
|
||||||
|
|
||||||
/* Parse the buffer at the address BUFFER which is of SIZE and return
|
/* Parse the buffer at the address BUFFER which is of SIZE and return
|
||||||
the tag and the length part from the TLV triplet. Update BUFFER
|
* the tag and the length part from the TLV triplet. Update BUFFER
|
||||||
and SIZE on success. Checks that the encoded length does not
|
* and SIZE on success. Checks that the encoded length does not
|
||||||
exhaust the length of the provided buffer. */
|
* exhaust the length of the provided buffer. */
|
||||||
static int
|
static int
|
||||||
parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
|
parse_tag (unsigned char const **buffer, size_t *size, struct tag_info *ti)
|
||||||
{
|
{
|
||||||
int c;
|
gpg_error_t err;
|
||||||
unsigned long tag;
|
int tag;
|
||||||
const unsigned char *buf = *buffer;
|
|
||||||
size_t length = *size;
|
|
||||||
|
|
||||||
ti->length = 0;
|
err = parse_ber_header (buffer, size,
|
||||||
ti->ndef = 0;
|
&ti->class, &tag,
|
||||||
ti->nhdr = 0;
|
&ti->is_constructed, &ti->ndef,
|
||||||
|
&ti->length, &ti->nhdr);
|
||||||
/* Get the tag */
|
if (err)
|
||||||
if (!length)
|
return err;
|
||||||
return -1; /* premature eof */
|
if (tag < 0)
|
||||||
c = *buf++; length--;
|
return gpg_error (GPG_ERR_EOVERFLOW);
|
||||||
ti->nhdr++;
|
|
||||||
|
|
||||||
ti->class = (c & 0xc0) >> 6;
|
|
||||||
ti->is_constructed = !!(c & 0x20);
|
|
||||||
tag = c & 0x1f;
|
|
||||||
|
|
||||||
if (tag == 0x1f)
|
|
||||||
{
|
|
||||||
tag = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
tag <<= 7;
|
|
||||||
if (!length)
|
|
||||||
return -1; /* premature eof */
|
|
||||||
c = *buf++; length--;
|
|
||||||
ti->nhdr++;
|
|
||||||
tag |= c & 0x7f;
|
|
||||||
}
|
|
||||||
while (c & 0x80);
|
|
||||||
}
|
|
||||||
ti->tag = tag;
|
ti->tag = tag;
|
||||||
|
|
||||||
/* Get the length */
|
if (ti->length > *size)
|
||||||
if (!length)
|
return gpg_error (GPG_ERR_BUFFER_TOO_SHORT); /* data larger than buffer. */
|
||||||
return -1; /* prematureeof */
|
|
||||||
c = *buf++; length--;
|
|
||||||
ti->nhdr++;
|
|
||||||
|
|
||||||
if ( !(c & 0x80) )
|
|
||||||
ti->length = c;
|
|
||||||
else if (c == 0x80)
|
|
||||||
ti->ndef = 1;
|
|
||||||
else if (c == 0xff)
|
|
||||||
return -1; /* forbidden length value */
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned long len = 0;
|
|
||||||
int count = c & 0x7f;
|
|
||||||
|
|
||||||
for (; count; count--)
|
|
||||||
{
|
|
||||||
len <<= 8;
|
|
||||||
if (!length)
|
|
||||||
return -1; /* premature_eof */
|
|
||||||
c = *buf++; length--;
|
|
||||||
ti->nhdr++;
|
|
||||||
len |= c & 0xff;
|
|
||||||
}
|
|
||||||
ti->length = len;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ti->class == CLASS_UNIVERSAL && !ti->tag)
|
|
||||||
ti->length = 0;
|
|
||||||
|
|
||||||
if (ti->length > length)
|
|
||||||
return -1; /* data larger than buffer. */
|
|
||||||
|
|
||||||
*buffer = buf;
|
|
||||||
*size = length;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user