summaryrefslogtreecommitdiff
path: root/lib/coding.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/coding.c')
-rw-r--r--lib/coding.c187
1 files changed, 96 insertions, 91 deletions
diff --git a/lib/coding.c b/lib/coding.c
index 7141df7..46e67ff 100644
--- a/lib/coding.c
+++ b/lib/coding.c
@@ -265,6 +265,9 @@ _asn1_time_der (unsigned char *str, int str_len, unsigned char *der,
int len_len;
int max_len;
+ if (der == NULL)
+ return ASN1_VALUE_NOT_VALID;
+
max_len = *der_len;
asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len);
@@ -342,6 +345,9 @@ _asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
max_len = *der_len;
+ if (der == NULL && max_len > 0)
+ return ASN1_VALUE_NOT_VALID;
+
temp = malloc (str_len + 2);
if (temp == NULL)
return ASN1_MEM_ALLOC_ERROR;
@@ -473,6 +479,10 @@ _asn1_complete_explicit_tag (asn1_node node, unsigned char *der,
int is_tag_implicit, len2, len3;
unsigned char temp[SIZEOF_UNSIGNED_INT];
+ if (der == NULL && *max_len > 0) {
+ return ASN1_VALUE_NOT_VALID;
+ }
+
is_tag_implicit = 0;
if (node->type & CONST_TAG)
@@ -830,6 +840,39 @@ error:
return err;
}
+struct vet
+{
+ unsigned char *ptr;
+ int size;
+};
+
+static int setof_compar(const void *_e1, const void *_e2)
+{
+ unsigned length;
+ const struct vet *e1 = _e1, *e2 = _e2;
+ int rval;
+
+ /* The encodings of the component values of a set-of value shall
+ * appear in ascending order, the encodings being compared
+ * as octet strings with the shorter components being
+ * padded at their trailing end with 0-octets.
+ * The padding octets are for comparison purposes and
+ * do not appear in the encodings.
+ */
+ length = MIN(e1->size, e2->size);
+
+ rval = memcmp(e1->ptr, e2->ptr, length);
+ if (rval == 0 && e1->size != e2->size)
+ {
+ if (e1->size > e2->size)
+ rval = 1;
+ else if (e2->size > e1->size)
+ rval = -1;
+ }
+
+ return rval;
+}
+
/******************************************************/
/* Function : _asn1_ordering_set_of */
/* Description: puts the elements of a SET OF type in */
@@ -844,19 +887,19 @@ error:
static int
_asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
{
- struct vet
- {
- int end;
- struct vet *next, *prev;
- };
-
- int counter, len, len2, change;
- struct vet *first, *last, *p_vet, *p2_vet;
+ int counter, len, len2;
+ struct vet *list = NULL, *tlist;
+ unsigned list_size = 0;
+ struct vet *p_vet;
asn1_node p;
- unsigned char *temp, class;
- unsigned long k, length;
+ unsigned char class;
+ unsigned i;
+ unsigned char *out = NULL;
int err;
+ if (der == NULL)
+ return ASN1_VALUE_NOT_VALID;
+
counter = 0;
if (type_field (node->type) != ASN1_ETYPE_SET_OF)
@@ -873,33 +916,30 @@ _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
if ((p == NULL) || (p->right == NULL))
return ASN1_SUCCESS;
- first = last = NULL;
while (p)
{
- p_vet = malloc (sizeof (struct vet));
- if (p_vet == NULL)
+ list_size++;
+ tlist = realloc (list, list_size*sizeof(struct vet));
+ if (tlist == NULL)
{
err = ASN1_MEM_ALLOC_ERROR;
goto error;
}
+ list = tlist;
+ p_vet = &list[list_size-1];
- p_vet->next = NULL;
- p_vet->prev = last;
- if (first == NULL)
- first = p_vet;
- else
- last->next = p_vet;
- last = p_vet;
+ p_vet->ptr = der+counter;
+ p_vet->size = 0;
/* extraction of tag and length */
if (der_len - counter > 0)
{
-
err = asn1_get_tag_der (der + counter, der_len - counter, &class,
&len, NULL);
if (err != ASN1_SUCCESS)
goto error;
counter += len;
+ p_vet->size += len;
len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
if (len2 < 0)
@@ -908,84 +948,46 @@ _asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
goto error;
}
counter += len + len2;
+ p_vet->size += len + len2;
+
}
else
{
err = ASN1_DER_ERROR;
goto error;
}
-
- p_vet->end = counter;
p = p->right;
}
- p_vet = first;
-
- while (p_vet)
+ if (counter > der_len)
{
- p2_vet = p_vet->next;
- counter = 0;
- while (p2_vet)
- {
- length = MIN(p_vet->end - counter, p2_vet->end - p_vet->end);
- change = -1;
- for (k = 0; k < length; k++)
- if (der[counter + k] > der[p_vet->end + k])
- {
- change = 1;
- break;
- }
- else if (der[counter + k] < der[p_vet->end + k])
- {
- change = 0;
- break;
- }
-
- if ((change == -1)
- && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
- change = 1;
-
- if (change == 1)
- {
- /* change position */
- temp = malloc (p_vet->end - counter);
- if (temp == NULL)
- {
- err = ASN1_MEM_ALLOC_ERROR;
- goto error;
- }
+ err = ASN1_DER_ERROR;
+ goto error;
+ }
- memcpy (temp, der + counter, (p_vet->end) - counter);
- memcpy (der + counter, der + (p_vet->end),
- (p2_vet->end) - (p_vet->end));
- memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
- (p_vet->end) - counter);
- free (temp);
+ qsort(list, list_size, sizeof(struct vet), setof_compar);
- p_vet->end = counter + (p2_vet->end - p_vet->end);
- }
- counter = p_vet->end;
+ out = malloc(der_len);
+ if (out == NULL)
+ {
+ err = ASN1_MEM_ERROR;
+ goto error;
+ }
- p2_vet = p2_vet->next;
- p_vet = p_vet->next;
- }
+ /* the sum of p_vet->size == der_len */
+ counter = 0;
+ for (i=0;i<list_size;i++) {
+ p_vet = &list[i];
+ memcpy(out+counter, p_vet->ptr, p_vet->size);
+ counter += p_vet->size;
+ }
+ memcpy(der, out, der_len);
+ free(out);
- if (p_vet != first)
- p_vet->prev->next = NULL;
- else
- first = NULL;
- free (p_vet);
- p_vet = first;
- }
- return ASN1_SUCCESS;
+ err = ASN1_SUCCESS;
error:
- while (first != NULL)
- {
- p_vet = first;
- first = first->next;
- free(p_vet);
- }
+ free(list);
return err;
}
@@ -1011,7 +1013,7 @@ error:
* length needed.
**/
int
-asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
+asn1_der_coding (asn1_node_const element, const char *name, void *ider, int *len,
char *ErrorDescription)
{
asn1_node node, p, p2;
@@ -1037,6 +1039,9 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
max_len = *len;
+ if (der == NULL && max_len > 0)
+ return ASN1_VALUE_NOT_VALID;
+
counter = 0;
move = DOWN;
p = node;
@@ -1057,7 +1062,7 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
{
case ASN1_ETYPE_NULL:
max_len--;
- if (max_len >= 0)
+ if (der != NULL && max_len >= 0)
der[counter] = 0;
counter++;
move = RIGHT;
@@ -1078,7 +1083,7 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
goto error;
}
max_len -= 2;
- if (max_len >= 0)
+ if (der != NULL && max_len >= 0)
{
der[counter++] = 1;
if (p->value[0] == 'F')
@@ -1114,7 +1119,7 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
goto error;
}
max_len -= len2 + len3;
- if (max_len >= 0)
+ if (der != NULL && max_len >= 0)
memcpy (der + counter, p->value, len3 + len2);
counter += len3 + len2;
}
@@ -1186,7 +1191,7 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
goto error;
}
max_len -= len2 + len3;
- if (max_len >= 0)
+ if (der != NULL && max_len >= 0)
memcpy (der + counter, p->value, len3 + len2);
counter += len3 + len2;
move = RIGHT;
@@ -1228,7 +1233,7 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
}
asn1_length_der (counter - len2, temp, &len3);
max_len -= len3;
- if (max_len >= 0)
+ if (der != NULL && max_len >= 0)
{
memmove (der + len2 + len3, der + len2, counter - len2);
memcpy (der + len2, temp, len3);
@@ -1269,7 +1274,7 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
}
asn1_length_der (counter - len2, temp, &len3);
max_len -= len3;
- if (max_len >= 0)
+ if (der != NULL && max_len >= 0)
{
memmove (der + len2 + len3, der + len2, counter - len2);
memcpy (der + len2, temp, len3);
@@ -1292,7 +1297,7 @@ asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
goto error;
}
max_len -= len2;
- if (max_len >= 0)
+ if (der != NULL && max_len >= 0)
memcpy (der + counter, p->value + len3, len2);
counter += len2;
move = RIGHT;