PrintableString, UniversalString, BMPString, UTF8String. When re-defined
a warning is being print instead of failing.
- Parser outputs more detailed syntax error message.
-- Added asn1_decode_string_der() and asn1_encode_string_der().
+- Added asn1_decode_simple_der() and asn1_encode_simple_der().
* Noteworthy changes in release 3.0 (2012-10-28) [stable]
- Added tool in tests/ to benchmark X.509 structure decoding.
/**
- * asn1_encode_string_der:
+ * asn1_encode_simple_der:
* @etype: The type of the string to be encoded (ASN1_ETYPE_)
* @str: the string data.
* @str_len: the string length
- * @der: the encoded string
- * @der_len: the bytes of the encoded string
+ * @tl: the encoded tag and length
+ * @tl_len: the bytes of the @tl field
*
- * Creates the DER encoding for the various ASN.1 STRING types.
- * The DER encoding of the input data will be placed in the @der variable.
+ * Creates the DER encoding for various simple ASN.1 types like strings etc.
+ * It stores the tag and length in @tl, which should have space for at least
+ * %ASN1_MAX_TL_SIZE bytes. Initially @tl_len should contain the size of @tl.
+ *
+ * The complete DER encoding should consist of the value in @tl appended
+ * with the provided @str.
*
* Returns: %ASN1_SUCCESS if successful or an error value.
**/
int
-asn1_encode_string_der (unsigned int etype, const unsigned char *str, unsigned int str_len,
- unsigned char **der, unsigned int *der_len)
+asn1_encode_simple_der (unsigned int etype, const unsigned char *str, unsigned int str_len,
+ unsigned char *tl, unsigned int *tl_len)
{
- int tag_len, len_len, tlen;
+ int tag_len, len_len;
+ unsigned tlen;
unsigned char der_tag[ASN1_MAX_TAG_SIZE];
unsigned char der_length[ASN1_MAX_LENGTH_SIZE];
unsigned char* p;
- if (der == NULL)
+ if (str == NULL)
return ASN1_VALUE_NOT_VALID;
if (ETYPE_OK(etype) == 0)
return ASN1_VALUE_NOT_VALID;
+
_asn1_tag_der (ETYPE_CLASS(etype), ETYPE_TAG(etype),
der_tag, &tag_len);
if (tag_len <= 0 || len_len <= 0)
return ASN1_VALUE_NOT_VALID;
- tlen = tag_len + len_len + str_len;
-
- p = malloc(tlen);
- if (p == NULL)
- return ASN1_MEM_ALLOC_ERROR;
-
- *der = p;
- *der_len = tag_len + len_len + str_len;
+ tlen = tag_len + len_len;
+ if (*tl_len < tlen)
+ return ASN1_MEM_ERROR;
+
+ p = tl;
memcpy(p, der_tag, tag_len);
p+=tag_len;
memcpy(p, der_length, len_len);
- p+=len_len;
- memcpy(p, str, str_len);
+
+ *tl_len = tlen;
return ASN1_SUCCESS;
}
}
/**
- * asn1_decode_string_der:
+ * asn1_decode_simple_der:
* @etype: The type of the string to be encoded (ASN1_ETYPE_)
* @der: the encoded string
* @der_len: the bytes of the encoded string
- * @str: the decoded string data.
- * @str_len: the string length
+ * @str: a pointer to the data
+ * @str_len: the length of the data
*
- * Creates the DER encoding for the various ASN.1 STRING types.
- * The DER encoding of the input data will be placed in the @der variable.
+ * Decodes a simple DER encoded type (e.g. a string, which is not constructed).
+ * The output is a pointer inside the @der.
*
* Returns: %ASN1_SUCCESS if successful or an error value.
**/
int
-asn1_decode_string_der (unsigned int etype, const unsigned char *der, unsigned int der_len,
- unsigned char **str, unsigned int *str_len)
+asn1_decode_simple_der (unsigned int etype, const unsigned char *der, unsigned int der_len,
+ const unsigned char **str, unsigned int *str_len)
{
- int tag_len, len_len, tlen;
+ int tag_len, len_len;
const unsigned char* p;
unsigned char class;
unsigned long tag;
ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag);
if (ret != ASN1_SUCCESS)
return ret;
+
+ if (class != ETYPE_CLASS(etype) || tag != ETYPE_TAG(etype))
+ return ASN1_DER_ERROR;
p += tag_len;
der_len -= tag_len;
p += len_len;
der_len -= len_len;
- tlen = ret;
-
- *str = malloc(tlen);
- if (*str == NULL)
- return ASN1_MEM_ALLOC_ERROR;
-
- memcpy(*str, p, tlen);
- *str_len = tlen;
+
+ *str_len = ret;
+ *str = p;
return ASN1_SUCCESS;
}
#include <libtasn1.h>
#define ASN1_SMALL_VALUE_SIZE 16
-#define ASN1_MAX_TAG_SIZE 4
/* This structure is also in libtasn1.h, but then contains less
fields. You cannot make any modifications to these first fields
extern ASN1_API void asn1_perror (int error);
+#define ASN1_MAX_TAG_SIZE 4
#define ASN1_MAX_LENGTH_SIZE 9
+#define ASN1_MAX_TL_SIZE (ASN1_MAX_TAG_SIZE+ASN1_MAX_LENGTH_SIZE)
extern ASN1_API long
asn1_get_length_der (const unsigned char *der, int der_len, int *len);
/* Other utility functions. */
extern ASN1_API
- int asn1_decode_string_der (unsigned int etype, const unsigned char *der, unsigned int der_len,
- unsigned char **str, unsigned int *str_len);
+ int asn1_decode_simple_der (unsigned int etype, const unsigned char *der, unsigned int der_len,
+ const unsigned char **str, unsigned int *str_len);
- extern ASN1_API
- int asn1_encode_string_der (unsigned int etype, const unsigned char *str, unsigned int str_len,
- unsigned char **der, unsigned int *der_len);
+ extern ASN1_API int
+ asn1_encode_simple_der (unsigned int etype, const unsigned char *str, unsigned int str_len,
+ unsigned char *tl, unsigned int *tl_len);
extern ASN1_API asn1_node
asn1_find_node (asn1_node pointer, const char *name);
asn1_strerror;
asn1_write_value;
asn1_read_node_value;
- asn1_encode_string_der;
- asn1_decode_string_der;
+ asn1_encode_simple_der;
+ asn1_decode_simple_der;
# Old symbols
libtasn1_strerror;
static const struct tv tv[] = {
{ASN1_ETYPE_IA5_STRING, 20, "\x63\x73\x63\x61\x40\x70\x61\x73\x73\x70\x6f\x72\x74\x2e\x67\x6f\x76\x2e\x67\x72",
- 22, "\x16\x14\x63\x73\x63\x61\x40\x70\x61\x73\x73\x70\x6f\x72\x74\x2e\x67\x6f\x76\x2e\x67\x72"},
+ 22, "\x16\x14\x63\x73\x63\x61\x40\x70\x61\x73\x73\x70\x6f\x72\x74\x2e\x67\x6f\x76\x2e\x67\x72"},
{ASN1_ETYPE_PRINTABLE_STRING, 5, "\x4e\x69\x6b\x6f\x73",
7, "\x13\x05\x4e\x69\x6b\x6f\x73"},
{ASN1_ETYPE_UTF8_STRING, 12, "Αττική",
main (int argc, char *argv[])
{
int ret;
- unsigned char* der;
- unsigned int der_len;
+ unsigned char tl[ASN1_MAX_TL_SIZE];
+ unsigned int tl_len, der_len, str_len;
+ const unsigned char* str;
unsigned int i;
/* Dummy test */
for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
{
/* Encode */
- ret = asn1_encode_string_der(tv[i].etype, tv[i].str, tv[i].str_len,
- &der, &der_len);
+ tl_len = sizeof(tl);
+ ret = asn1_encode_simple_der(tv[i].etype, tv[i].str, tv[i].str_len,
+ tl, &tl_len);
if (ret != ASN1_SUCCESS)
{
fprintf(stderr, "Encoding error in %u: %s\n", i, asn1_strerror(ret));
return 1;
}
+ der_len = tl_len+tv[i].str_len;
- if (der_len != tv[i].der_len || memcmp(der, tv[i].der, der_len) != 0)
+ if (der_len != tv[i].der_len || memcmp(tl, tv[i].der, tl_len) != 0)
{
fprintf(stderr, "DER encoding differs in %u! (size: %u, expected: %u)\n", i, der_len, tv[i].der_len);
return 1;
}
- free(der);
/* decoding */
- ret = asn1_decode_string_der(tv[i].etype, tv[i].der, tv[i].der_len, &der, &der_len);
+ ret = asn1_decode_simple_der(tv[i].etype, tv[i].der, tv[i].der_len, &str, &str_len);
if (ret != ASN1_SUCCESS)
{
fprintf(stderr, "Decoding error in %u: %s\n", i, asn1_strerror(ret));
return 1;
}
- if (der_len != tv[i].str_len || memcmp(der, tv[i].str, der_len) != 0)
+ if (str_len != tv[i].str_len || memcmp(str, tv[i].str, str_len) != 0)
{
fprintf(stderr, "DER decoded data differ in %u! (size: %u, expected: %u)\n", i, der_len, tv[i].str_len);
return 1;
}
- free(der);
}