mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
common: Add functions to help create DER objects.
* common/tlv.c (put_tlv_to_membuf): New. (get_tlv_length): New. * common/tlv.h: Include membuf.h. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
8dfef5197a
commit
5d015b38eb
101
common/tlv.c
101
common/tlv.c
@ -157,6 +157,107 @@ find_tlv_unchecked (const unsigned char *buffer, size_t length,
|
||||
}
|
||||
|
||||
|
||||
/* Write TAG of CLASS to MEMBUF. CONSTRUCTED is a flag telling
|
||||
* whether the value is constructed. LENGTH gives the length of the
|
||||
* value, if it is 0 undefinite length is assumed. LENGTH is ignored
|
||||
* for the NULL tag. TAG must be less that 0x1f. */
|
||||
void
|
||||
put_tlv_to_membuf (membuf_t *membuf, int class, int tag,
|
||||
int constructed, size_t length)
|
||||
{
|
||||
unsigned char buf[20];
|
||||
int buflen = 0;
|
||||
int i;
|
||||
|
||||
if (tag < 0x1f)
|
||||
{
|
||||
*buf = (class << 6) | tag;
|
||||
if (constructed)
|
||||
*buf |= 0x20;
|
||||
buflen++;
|
||||
}
|
||||
else
|
||||
BUG ();
|
||||
|
||||
if (!tag && !class)
|
||||
buf[buflen++] = 0; /* end tag */
|
||||
else if (tag == TAG_NULL && !class)
|
||||
buf[buflen++] = 0; /* NULL tag */
|
||||
else if (!length)
|
||||
buf[buflen++] = 0x80; /* indefinite length */
|
||||
else if (length < 128)
|
||||
buf[buflen++] = length;
|
||||
else
|
||||
{
|
||||
/* If we know the sizeof a size_t we could support larger
|
||||
* objects - however this is pretty ridiculous */
|
||||
i = (length <= 0xff ? 1:
|
||||
length <= 0xffff ? 2:
|
||||
length <= 0xffffff ? 3: 4);
|
||||
|
||||
buf[buflen++] = (0x80 | i);
|
||||
if (i > 3)
|
||||
buf[buflen++] = length >> 24;
|
||||
if (i > 2)
|
||||
buf[buflen++] = length >> 16;
|
||||
if (i > 1)
|
||||
buf[buflen++] = length >> 8;
|
||||
buf[buflen++] = length;
|
||||
}
|
||||
|
||||
put_membuf (membuf, buf, buflen);
|
||||
}
|
||||
|
||||
|
||||
/* Return the length of the to be constructed TLV. CONSTRUCTED is a
|
||||
* flag telling whether the value is constructed. LENGTH gives the
|
||||
* length of the value, if it is 0 undefinite length is assumed.
|
||||
* LENGTH is ignored for the NULL tag. TAG must be less that 0x1f. */
|
||||
size_t
|
||||
get_tlv_length (int class, int tag, int constructed, size_t length)
|
||||
{
|
||||
size_t buflen = 0;
|
||||
int i;
|
||||
|
||||
(void)constructed; /* Not used, but passed for uniformity of such calls. */
|
||||
|
||||
if (tag < 0x1f)
|
||||
{
|
||||
buflen++;
|
||||
}
|
||||
else
|
||||
{
|
||||
buflen++; /* assume one and let the actual write function bail out */
|
||||
}
|
||||
|
||||
if (!tag && !class)
|
||||
buflen++; /* end tag */
|
||||
else if (tag == TAG_NULL && !class)
|
||||
buflen++; /* NULL tag */
|
||||
else if (!length)
|
||||
buflen++; /* indefinite length */
|
||||
else if (length < 128)
|
||||
buflen++;
|
||||
else
|
||||
{
|
||||
i = (length <= 0xff ? 1:
|
||||
length <= 0xffff ? 2:
|
||||
length <= 0xffffff ? 3: 4);
|
||||
|
||||
buflen++;
|
||||
if (i > 3)
|
||||
buflen++;
|
||||
if (i > 2)
|
||||
buflen++;
|
||||
if (i > 1)
|
||||
buflen++;
|
||||
buflen++;
|
||||
}
|
||||
|
||||
return buflen + length;
|
||||
}
|
||||
|
||||
|
||||
/* 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
|
||||
on success. */
|
||||
|
12
common/tlv.h
12
common/tlv.h
@ -30,6 +30,7 @@
|
||||
#ifndef SCD_TLV_H
|
||||
#define SCD_TLV_H 1
|
||||
|
||||
#include "membuf.h"
|
||||
|
||||
enum tlv_tag_class {
|
||||
CLASS_UNIVERSAL = 0,
|
||||
@ -86,13 +87,20 @@ const unsigned char *find_tlv_unchecked (const unsigned char *buffer,
|
||||
size_t length,
|
||||
int tag, size_t *nbytes);
|
||||
|
||||
/* Wite a TLV header to MEMBUF. */
|
||||
void put_tlv_to_membuf (membuf_t *membuf, int class, int tag,
|
||||
int constructed, size_t length);
|
||||
|
||||
/* Count the length of a to be constructed TLV. */
|
||||
size_t get_tlv_length (int class, int tag, int constructed, size_t length);
|
||||
|
||||
|
||||
/* 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
|
||||
on success. */
|
||||
gpg_error_t parse_ber_header (unsigned char const **buffer, size_t *size,
|
||||
int *r_class, int *r_tag,
|
||||
int *r_constructed,
|
||||
int *r_class, int *r_tag,
|
||||
int *r_constructed,
|
||||
int *r_ndef, size_t *r_length, size_t *r_nhdr);
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user