Author: Pekka Riikonen <priikone@silcnet.org>
- Copyright (C) 2003 - 2007 Pekka Riikonen
+ Copyright (C) 2003 - 2008 Pekka Riikonen
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
*/
-#include "silc.h"
+#include "silccrypto.h"
#include "silcasn1.h"
#include "silcber.h"
#define SILC_ASN1_BUFFER_FREE(b, stack) if (!stack) silc_buffer_purge(b);
+#define SILC_ASN1_STACK(stack, asn1) stack ? stack : asn1->orig_stack
/************************** ASN.1 Encoder routines **************************/
goto fail; \
} \
silc_stack_push(asn1->stack2, &frame); \
- s = silc_smalloc_ua(stack2, s_len + 1); \
+ s = silc_smalloc(stack2, s_len + 1); \
if (s) { \
silc_utf8_decode(d, d_len, (enc), s, s_len); \
s[s_len] = '\0'; \
} \
len = silc_ber_encoded_len(tag, s_len, indef); \
- dest = silc_buffer_srealloc_size(stack1, dest, \
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest, \
silc_buffer_truelen(dest) + len); \
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE, \
tag, s, s_len, indef); \
/* Encode the explicit tag */
len = silc_ber_encoded_len(tag, silc_buffer_len(&buf), FALSE);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_CONSTRUCTED,
tag, buf.data, silc_buffer_len(&buf), FALSE);
SILC_LOG_DEBUG(("Error decoding underlaying node for ANY"));
goto fail;
}
- assert(enc == SILC_BER_ENC_CONSTRUCTED);
+ SILC_VERIFY(enc == SILC_BER_ENC_CONSTRUCTED);
/* Now encode with implicit tagging */
len = silc_ber_encoded_len(tag, d_len, FALSE);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_CONSTRUCTED,
tag, d, d_len, FALSE);
} else {
/* Copy the data directly into the tree. */
len = silc_buffer_len(node);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
if (!dest)
goto fail;
/* Encode the primitive data */
len = silc_ber_encoded_len(tag, silc_buffer_len(prim), FALSE);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE,
tag, prim->data, silc_buffer_len(prim), FALSE);
/* Encode the sequence */
len = silc_ber_encoded_len(tag, silc_buffer_len(&buf), indef);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_CONSTRUCTED,
tag, buf.data, silc_buffer_len(&buf), indef);
/* Encode the integer */
len = silc_ber_encoded_len(tag, len, indef);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE,
tag, buf.data, silc_buffer_len(&buf), FALSE);
/* Encode the integer */
len = silc_ber_encoded_len(tag, len, indef);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE,
tag, buf.data, silc_buffer_len(&buf), FALSE);
/* Get OID words from the string */
cp = strchr(oidstr, '.');
while (cp) {
- if (sscanf(oidstr, "%lu", (unsigned long *)&oid) != 1) {
+ if (sscanf(oidstr, "%lu", &oid) != 1) {
SILC_LOG_DEBUG(("Malformed OID string"));
goto fail;
}
cp = strchr(oidstr, '.');
if (!cp) {
- if (sscanf(oidstr, "%lu", (unsigned long *)&oid) != 1) {
+ if (sscanf(oidstr, "%lu", &oid) != 1) {
SILC_LOG_DEBUG(("Malformed OID string"));
goto fail;
}
}
len = silc_ber_encoded_len(tag, silc_buffer_len(&buf), indef);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE,
tag, buf.data, silc_buffer_len(&buf), FALSE);
assert(indef == FALSE);
len = silc_ber_encoded_len(tag, 1, FALSE);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE,
tag, val, 1, FALSE);
silc_buffer_push(&buf, 1);
len = silc_ber_encoded_len(tag, silc_buffer_len(&buf), indef);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE,
tag, buf.data, silc_buffer_len(&buf), indef);
case SILC_ASN1_TAG_NULL:
{
/* Encode empty BER block */
- assert(indef == FALSE);
+ SilcBool val = va_arg(asn1->ap, SilcUInt32);
+
+ SILC_VERIFY(indef == FALSE);
+
+ if (!val)
+ break;
+
len = silc_ber_encoded_len(tag, 0, FALSE);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE,
tag, NULL, 0, FALSE);
if (!ret)
goto fail;
+
break;
}
}
len = silc_ber_encoded_len(tag, strlen(timestr), indef);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE,
tag, timestr, strlen(timestr), indef);
}
len = silc_ber_encoded_len(tag, strlen(timestr), indef);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE,
tag, timestr, strlen(timestr), indef);
}
len = silc_ber_encoded_len(tag, d_len, indef);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE,
tag, d, d_len, indef);
SilcUInt32 d_len = va_arg(asn1->ap, SilcUInt32);
len = silc_ber_encoded_len(tag, d_len, indef);
- dest = silc_buffer_srealloc_size(stack1, dest,
+ dest = silc_buffer_srealloc_size(SILC_ASN1_STACK(stack1, asn1), dest,
silc_buffer_truelen(dest) + len);
ret = silc_ber_encode(dest, ber_class, SILC_BER_ENC_PRIMITIVE,
tag, d, d_len, indef);
SilcAsn1Options opts;
SilcBerClass ber_class;
SilcStackFrame frame1, frame2;
- SilcStack stack1 = NULL;
+ SilcStack stack1 = NULL, orig;
SilcBool ret;
if (!asn1)
va_start(asn1->ap, dest);
+ orig = asn1->orig_stack;
+ asn1->orig_stack = NULL;
+
/* Get the first arguments and call the encoder. */
SILC_ASN1_ARGS(asn1, type, tag, ber_class, opts);
if (!type) {
that stack aware calls revert to normal allocation routines. */
stack1 = asn1->stack1;
asn1->stack1 = NULL;
+ asn1->orig_stack = orig;
}
if (o & SILC_ASN1_ACCUMUL) {
if (stack1 && !asn1->stack1)
asn1->stack1 = stack1;
+ asn1->orig_stack = orig;
+
va_end(asn1->ap);
return ret;