1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-03 22:56:33 +02:00

common: Add an easy to use DER builder.

* common/tlv-builder.c: New.
* common/tlv.c: Remove stuff only used by GnuPG 1.
(put_tlv_to_membuf, get_tlv_length): Move to ...
* common/tlv-builder.c: here.
* common/tlv.h (tlv_builder_t): New.
--

Such code should actually go into libksba and we will eventually do
that.  However, for now it is easier to keep it here.

Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
Werner Koch 2020-04-24 13:14:05 +02:00
parent c03f80dc19
commit 5ea878274e
No known key found for this signature in database
GPG key ID: E3FDFF218E45B72B
4 changed files with 416 additions and 120 deletions

View file

@ -32,21 +32,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#if GNUPG_MAJOR_VERSION == 1
#define GPG_ERR_EOF (-1)
#define GPG_ERR_BAD_BER (1) /*G10ERR_GENERAL*/
#define GPG_ERR_INV_SEXP (45) /*G10ERR_INV_ARG*/
typedef int gpg_error_t;
#define gpg_make_err(x,n) (n)
#else
#include <gpg-error.h>
#endif
#include "util.h"
#include "tlv.h"
static const unsigned char *
do_find_tlv (const unsigned char *buffer, size_t length,
int tag, size_t *nbytes, int nestlevel)
@ -157,107 +149,6 @@ 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. */