Report generated at: Mon Oct 13 11:27:22 CEST 2008
| Total number of functions | 78 |
| Number of low risk functions | 47 |
| Number of moderate risk functions | 15 |
| Number of high risk functions | 9 |
| Number of untestable functions | 7 |
Used ranges:
| Cyclomatic Complexity | Risk Evaluation | |
| 0 - 10 | Simple module, without much risk | |
| 11 - 20 | More complex module, moderate risk | |
| 21 - 50 | Complex module, high risk | |
| greater than 50 | Untestable module, very high risk |
| Function Name |
Cyclomatic
Complexity |
Number of
Statements |
Number of
Lines |
Source File | |
| ↓ | asn1_der_decoding_element | 156 | 412 | 759 | lib/decoding.c |
asn1_retCode
asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
const void *ider, int len, char *errorDescription)
{
node_asn *node, *p, *p2, *p3, *nodeFound = ASN1_TYPE_EMPTY;
char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
int counter, len2, len3, len4, move, ris, tlen;
unsigned char class, *temp2;
unsigned long tag;
int indefinite, result;
const unsigned char *der = ider;
node = *structure;
if (node == ASN1_TYPE_EMPTY)
return ASN1_ELEMENT_NOT_FOUND;
if (elementName == NULL)
{
asn1_delete_structure (structure);
return ASN1_ELEMENT_NOT_FOUND;
}
if (node->type & CONST_OPTION)
{
asn1_delete_structure (structure);
return ASN1_GENERIC_ERROR;
}
if ((*structure)->name)
{ /* Has *structure got a name? */
nameLen -= strlen ((*structure)->name);
if (nameLen > 0)
strcpy (currentName, (*structure)->name);
else
{
asn1_delete_structure (structure);
return ASN1_MEM_ERROR;
}
if (!(strcmp (currentName, elementName)))
{
state = FOUND;
nodeFound = *structure;
}
else if (!memcmp (currentName, elementName, strlen (currentName)))
state = SAME_BRANCH;
else
state = OTHER_BRANCH;
}
else
{ /* *structure doesn't have a name? */
currentName[0] = 0;
if (elementName[0] == 0)
{
state = FOUND;
nodeFound = *structure;
}
else
{
state = SAME_BRANCH;
}
}
counter = 0;
move = DOWN;
p = node;
while (1)
{
ris = ASN1_SUCCESS;
if (move != UP)
{
if (p->type & CONST_SET)
{
p2 = _asn1_find_up (p);
len2 = strtol (p2->value, NULL, 10);
if (counter == len2)
{
p = p2;
move = UP;
continue;
}
else if (counter > len2)
{
asn1_delete_structure (structure);
return ASN1_DER_ERROR;
}
p2 = p2->down;
while (p2)
{
if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
{
if (type_field (p2->type) != TYPE_CHOICE)
ris =
_asn1_extract_tag_der (p2, der + counter,
len - counter, &len2);
else
{
p3 = p2->down;
while (p3)
{
ris =
_asn1_extract_tag_der (p3, der + counter,
len - counter, &len2);
if (ris == ASN1_SUCCESS)
break;
p3 = p3->right;
}
}
if (ris == ASN1_SUCCESS)
{
p2->type &= ~CONST_NOT_USED;
p = p2;
break;
}
}
p2 = p2->right;
}
if (p2 == NULL)
{
asn1_delete_structure (structure);
return ASN1_DER_ERROR;
}
}
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
p2 = _asn1_find_up (p);
len2 = strtol (p2->value, NULL, 10);
if (counter == len2)
{
if (p->right)
{
p2 = p->right;
move = RIGHT;
}
else
move = UP;
if (p->type & CONST_OPTION)
asn1_delete_structure (&p);
p = p2;
continue;
}
}
if (type_field (p->type) == TYPE_CHOICE)
{
while (p->down)
{
if (counter < len)
ris =
_asn1_extract_tag_der (p->down, der + counter,
len - counter, &len2);
else
ris = ASN1_DER_ERROR;
if (ris == ASN1_SUCCESS)
{
while (p->down->right)
{
p2 = p->down->right;
asn1_delete_structure (&p2);
}
break;
}
else if (ris == ASN1_ERROR_TYPE_ANY)
{
asn1_delete_structure (structure);
return ASN1_ERROR_TYPE_ANY;
}
else
{
p2 = p->down;
asn1_delete_structure (&p2);
}
}
if (p->down == NULL)
{
if (!(p->type & CONST_OPTION))
{
asn1_delete_structure (structure);
return ASN1_DER_ERROR;
}
}
else
p = p->down;
}
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
p2 = _asn1_find_up (p);
len2 = strtol (p2->value, NULL, 10);
if (counter > len2)
ris = ASN1_TAG_ERROR;
}
if (ris == ASN1_SUCCESS)
ris =
_asn1_extract_tag_der (p, der + counter, len - counter, &len2);
if (ris != ASN1_SUCCESS)
{
if (p->type & CONST_OPTION)
{
p->type |= CONST_NOT_USED;
move = RIGHT;
}
else if (p->type & CONST_DEFAULT)
{
_asn1_set_value (p, NULL, 0);
move = RIGHT;
}
else
{
if (errorDescription != NULL)
_asn1_error_description_tag_error (p, errorDescription);
asn1_delete_structure (structure);
return ASN1_TAG_ERROR;
}
}
else
counter += len2;
}
if (ris == ASN1_SUCCESS)
{
switch (type_field (p->type))
{
case TYPE_NULL:
if (der[counter])
{
asn1_delete_structure (structure);
return ASN1_DER_ERROR;
}
if (p == nodeFound)
state = EXIT;
counter++;
move = RIGHT;
break;
case TYPE_BOOLEAN:
if (der[counter++] != 1)
{
asn1_delete_structure (structure);
return ASN1_DER_ERROR;
}
if (state == FOUND)
{
if (der[counter++] == 0)
_asn1_set_value (p, "F", 1);
else
_asn1_set_value (p, "T", 1);
if (p == nodeFound)
state = EXIT;
}
else
counter++;
move = RIGHT;
break;
case TYPE_INTEGER:
case TYPE_ENUMERATED:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
if (state == FOUND)
{
if (len3 + len2 > len - counter)
return ASN1_DER_ERROR;
_asn1_set_value (p, der + counter, len3 + len2);
if (p == nodeFound)
state = EXIT;
}
counter += len3 + len2;
move = RIGHT;
break;
case TYPE_OBJECT_ID:
if (state == FOUND)
{
_asn1_get_objectid_der (der + counter, len - counter, &len2,
temp, sizeof (temp));
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
if (p == nodeFound)
state = EXIT;
}
else
{
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
len2 += len3;
}
counter += len2;
move = RIGHT;
break;
case TYPE_TIME:
if (state == FOUND)
{
result =
_asn1_get_time_der (der + counter, len - counter, &len2,
temp, sizeof (temp) - 1);
if (result != ASN1_SUCCESS)
{
asn1_delete_structure (structure);
return result;
}
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
if (p == nodeFound)
state = EXIT;
}
else
{
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
len2 += len3;
}
counter += len2;
move = RIGHT;
break;
case TYPE_OCTET_STRING:
len3 = len - counter;
if (state == FOUND)
{
ris = _asn1_get_octet_string (der + counter, p, &len3);
if (p == nodeFound)
state = EXIT;
}
else
ris = _asn1_get_octet_string (der + counter, NULL, &len3);
if (ris != ASN1_SUCCESS)
return ris;
counter += len3;
move = RIGHT;
break;
case TYPE_GENERALSTRING:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
if (state == FOUND)
{
if (len3 + len2 > len - counter)
return ASN1_DER_ERROR;
_asn1_set_value (p, der + counter, len3 + len2);
if (p == nodeFound)
state = EXIT;
}
counter += len3 + len2;
move = RIGHT;
break;
case TYPE_BIT_STRING:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
if (state == FOUND)
{
if (len3 + len2 > len - counter)
return ASN1_DER_ERROR;
_asn1_set_value (p, der + counter, len3 + len2);
if (p == nodeFound)
state = EXIT;
}
counter += len3 + len2;
move = RIGHT;
break;
case TYPE_SEQUENCE:
case TYPE_SET:
if (move == UP)
{
len2 = strtol (p->value, NULL, 10);
_asn1_set_value (p, NULL, 0);
if (len2 == -1)
{ /* indefinite length method */
if ((der[counter]) || der[counter + 1])
{
asn1_delete_structure (structure);
return ASN1_DER_ERROR;
}
counter += 2;
}
else
{ /* definite length method */
if (len2 != counter)
{
asn1_delete_structure (structure);
return ASN1_DER_ERROR;
}
}
if (p == nodeFound)
state = EXIT;
move = RIGHT;
}
else
{ /* move==DOWN || move==RIGHT */
if (state == OTHER_BRANCH)
{
len3 =
asn1_get_length_der (der + counter, len - counter,
&len2);
if (len3 < 0)
return ASN1_DER_ERROR;
counter += len2 + len3;
move = RIGHT;
}
else
{ /* state==SAME_BRANCH or state==FOUND */
len3 =
asn1_get_length_der (der + counter, len - counter,
&len2);
if (len3 < 0)
return ASN1_DER_ERROR;
counter += len2;
if (len3 > 0)
{
_asn1_ltostr (counter + len3, temp);
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
move = DOWN;
}
else if (len3 == 0)
{
p2 = p->down;
while (p2)
{
if (type_field (p2->type) != TYPE_TAG)
{
p3 = p2->right;
asn1_delete_structure (&p2);
p2 = p3;
}
else
p2 = p2->right;
}
move = RIGHT;
}
else
{ /* indefinite length method */
_asn1_set_value (p, "-1", 3);
move = DOWN;
}
}
}
break;
case TYPE_SEQUENCE_OF:
case TYPE_SET_OF:
if (move == UP)
{
len2 = strtol (p->value, NULL, 10);
if (len2 > counter)
{
_asn1_append_sequence_set (p);
p = p->down;
while (p->right)
p = p->right;
move = RIGHT;
continue;
}
_asn1_set_value (p, NULL, 0);
if (len2 != counter)
{
asn1_delete_structure (structure);
return ASN1_DER_ERROR;
}
if (p == nodeFound)
state = EXIT;
}
else
{ /* move==DOWN || move==RIGHT */
if (state == OTHER_BRANCH)
{
len3 =
asn1_get_length_der (der + counter, len - counter,
&len2);
if (len3 < 0)
return ASN1_DER_ERROR;
counter += len2 + len3;
move = RIGHT;
}
else
{ /* state==FOUND or state==SAME_BRANCH */
len3 =
asn1_get_length_der (der + counter, len - counter,
&len2);
if (len3 < 0)
return ASN1_DER_ERROR;
counter += len2;
if (len3)
{
_asn1_ltostr (counter + len3, temp);
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
p2 = p->down;
while ((type_field (p2->type) == TYPE_TAG)
|| (type_field (p2->type) == TYPE_SIZE))
p2 = p2->right;
if (p2->right == NULL)
_asn1_append_sequence_set (p);
p = p2;
state = FOUND;
}
}
}
break;
case TYPE_ANY:
if (asn1_get_tag_der
(der + counter, len - counter, &class, &len2,
&tag) != ASN1_SUCCESS)
return ASN1_DER_ERROR;
if (counter + len2 > len)
return ASN1_DER_ERROR;
len4 =
asn1_get_length_der (der + counter + len2,
len - counter - len2, &len3);
if (len4 < -1)
return ASN1_DER_ERROR;
if (len4 != -1)
{
len2 += len4;
if (state == FOUND)
{
asn1_length_der (len2 + len3, NULL, &len4);
temp2 =
(unsigned char *) _asn1_malloc (len2 + len3 + len4);
if (temp2 == NULL)
{
asn1_delete_structure (structure);
return ASN1_MEM_ALLOC_ERROR;
}
asn1_octet_der (der + counter, len2 + len3, temp2,
&len4);
_asn1_set_value (p, temp2, len4);
_asn1_free (temp2);
if (p == nodeFound)
state = EXIT;
}
counter += len2 + len3;
}
else
{ /* indefinite length */
/* Check indefinite lenth method in an EXPLICIT TAG */
if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
indefinite = 1;
else
indefinite = 0;
len2 = len - counter;
ris =
_asn1_get_indefinite_length_string (der + counter, &len2);
if (ris != ASN1_SUCCESS)
{
asn1_delete_structure (structure);
return ris;
}
if (state == FOUND)
{
asn1_length_der (len2, NULL, &len4);
temp2 = (unsigned char *) _asn1_malloc (len2 + len4);
if (temp2 == NULL)
{
asn1_delete_structure (structure);
return ASN1_MEM_ALLOC_ERROR;
}
asn1_octet_der (der + counter, len2, temp2, &len4);
_asn1_set_value (p, temp2, len4);
_asn1_free (temp2);
if (p == nodeFound)
state = EXIT;
}
counter += len2;
/* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
an indefinite length method. */
if (indefinite)
{
if (!der[counter] && !der[counter + 1])
{
counter += 2;
}
else
{
asn1_delete_structure (structure);
return ASN1_DER_ERROR;
}
}
}
move = RIGHT;
break;
default:
move = (move == UP) ? RIGHT : DOWN;
break;
}
}
if ((p == node && move != DOWN) || (state == EXIT))
break;
if (move == DOWN)
{
if (p->down)
{
p = p->down;
if (state != FOUND)
{
nameLen -= strlen (p->name) + 1;
if (nameLen > 0)
{
if (currentName[0])
strcat (currentName, ".");
strcat (currentName, p->name);
}
else
{
asn1_delete_structure (structure);
return ASN1_MEM_ERROR;
}
if (!(strcmp (currentName, elementName)))
{
state = FOUND;
nodeFound = p;
}
else
if (!memcmp
(currentName, elementName, strlen (currentName)))
state = SAME_BRANCH;
else
state = OTHER_BRANCH;
}
}
else
move = RIGHT;
}
if ((move == RIGHT) && !(p->type & CONST_SET))
{
if (p->right)
{
p = p->right;
if (state != FOUND)
{
dot_p = char_p = currentName;
while ((char_p = strchr (char_p, '.')))
{
dot_p = char_p++;
dot_p++;
}
nameLen += strlen (currentName) - (dot_p - currentName);
*dot_p = 0;
nameLen -= strlen (p->name);
if (nameLen > 0)
strcat (currentName, p->name);
else
{
asn1_delete_structure (structure);
return ASN1_MEM_ERROR;
}
if (!(strcmp (currentName, elementName)))
{
state = FOUND;
nodeFound = p;
}
else
if (!memcmp
(currentName, elementName, strlen (currentName)))
state = SAME_BRANCH;
else
state = OTHER_BRANCH;
}
}
else
move = UP;
}
if (move == UP)
{
p = _asn1_find_up (p);
if (state != FOUND)
{
dot_p = char_p = currentName;
while ((char_p = strchr (char_p, '.')))
{
dot_p = char_p++;
dot_p++;
}
nameLen += strlen (currentName) - (dot_p - currentName);
*dot_p = 0;
if (!(strcmp (currentName, elementName)))
{
state = FOUND;
nodeFound = p;
}
else
if (!memcmp (currentName, elementName, strlen (currentName)))
state = SAME_BRANCH;
else
state = OTHER_BRANCH;
}
}
}
_asn1_delete_not_used (*structure);
if (counter > len)
{
asn1_delete_structure (structure);
return ASN1_DER_ERROR;
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | asn1_der_decoding | 120 | 315 | 539 | lib/decoding.c |
asn1_retCode
asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
char *errorDescription)
{
node_asn *node, *p, *p2, *p3;
char temp[128];
int counter, len2, len3, len4, move, ris, tlen;
unsigned char class, *temp2;
unsigned long tag;
int indefinite, result;
const unsigned char *der = ider;
node = *element;
if (node == ASN1_TYPE_EMPTY)
return ASN1_ELEMENT_NOT_FOUND;
if (node->type & CONST_OPTION)
{
asn1_delete_structure (element);
return ASN1_GENERIC_ERROR;
}
counter = 0;
move = DOWN;
p = node;
while (1)
{
ris = ASN1_SUCCESS;
if (move != UP)
{
if (p->type & CONST_SET)
{
p2 = _asn1_find_up (p);
len2 = strtol (p2->value, NULL, 10);
if (len2 == -1)
{
if (!der[counter] && !der[counter + 1])
{
p = p2;
move = UP;
counter += 2;
continue;
}
}
else if (counter == len2)
{
p = p2;
move = UP;
continue;
}
else if (counter > len2)
{
asn1_delete_structure (element);
return ASN1_DER_ERROR;
}
p2 = p2->down;
while (p2)
{
if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
{
if (type_field (p2->type) != TYPE_CHOICE)
ris =
_asn1_extract_tag_der (p2, der + counter,
len - counter, &len2);
else
{
p3 = p2->down;
while (p3)
{
ris =
_asn1_extract_tag_der (p3, der + counter,
len - counter, &len2);
if (ris == ASN1_SUCCESS)
break;
p3 = p3->right;
}
}
if (ris == ASN1_SUCCESS)
{
p2->type &= ~CONST_NOT_USED;
p = p2;
break;
}
}
p2 = p2->right;
}
if (p2 == NULL)
{
asn1_delete_structure (element);
return ASN1_DER_ERROR;
}
}
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
p2 = _asn1_find_up (p);
len2 = strtol (p2->value, NULL, 10);
if (counter == len2)
{
if (p->right)
{
p2 = p->right;
move = RIGHT;
}
else
move = UP;
if (p->type & CONST_OPTION)
asn1_delete_structure (&p);
p = p2;
continue;
}
}
if (type_field (p->type) == TYPE_CHOICE)
{
while (p->down)
{
if (counter < len)
ris =
_asn1_extract_tag_der (p->down, der + counter,
len - counter, &len2);
else
ris = ASN1_DER_ERROR;
if (ris == ASN1_SUCCESS)
{
while (p->down->right)
{
p2 = p->down->right;
asn1_delete_structure (&p2);
}
break;
}
else if (ris == ASN1_ERROR_TYPE_ANY)
{
asn1_delete_structure (element);
return ASN1_ERROR_TYPE_ANY;
}
else
{
p2 = p->down;
asn1_delete_structure (&p2);
}
}
if (p->down == NULL)
{
if (!(p->type & CONST_OPTION))
{
asn1_delete_structure (element);
return ASN1_DER_ERROR;
}
}
else
p = p->down;
}
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
p2 = _asn1_find_up (p);
len2 = strtol (p2->value, NULL, 10);
if ((len2 != -1) && (counter > len2))
ris = ASN1_TAG_ERROR;
}
if (ris == ASN1_SUCCESS)
ris =
_asn1_extract_tag_der (p, der + counter, len - counter, &len2);
if (ris != ASN1_SUCCESS)
{
if (p->type & CONST_OPTION)
{
p->type |= CONST_NOT_USED;
move = RIGHT;
}
else if (p->type & CONST_DEFAULT)
{
_asn1_set_value (p, NULL, 0);
move = RIGHT;
}
else
{
if (errorDescription != NULL)
_asn1_error_description_tag_error (p, errorDescription);
asn1_delete_structure (element);
return ASN1_TAG_ERROR;
}
}
else
counter += len2;
}
if (ris == ASN1_SUCCESS)
{
switch (type_field (p->type))
{
case TYPE_NULL:
if (der[counter])
{
asn1_delete_structure (element);
return ASN1_DER_ERROR;
}
counter++;
move = RIGHT;
break;
case TYPE_BOOLEAN:
if (der[counter++] != 1)
{
asn1_delete_structure (element);
return ASN1_DER_ERROR;
}
if (der[counter++] == 0)
_asn1_set_value (p, "F", 1);
else
_asn1_set_value (p, "T", 1);
move = RIGHT;
break;
case TYPE_INTEGER:
case TYPE_ENUMERATED:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
if (len2 + len3 > len - counter)
return ASN1_DER_ERROR;
_asn1_set_value (p, der + counter, len3 + len2);
counter += len3 + len2;
move = RIGHT;
break;
case TYPE_OBJECT_ID:
_asn1_get_objectid_der (der + counter, len - counter, &len2,
temp, sizeof (temp));
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
counter += len2;
move = RIGHT;
break;
case TYPE_TIME:
result =
_asn1_get_time_der (der + counter, len - counter, &len2, temp,
sizeof (temp) - 1);
if (result != ASN1_SUCCESS)
{
asn1_delete_structure (element);
return result;
}
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
counter += len2;
move = RIGHT;
break;
case TYPE_OCTET_STRING:
len3 = len - counter;
ris = _asn1_get_octet_string (der + counter, p, &len3);
if (ris != ASN1_SUCCESS)
return ris;
counter += len3;
move = RIGHT;
break;
case TYPE_GENERALSTRING:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
if (len3 + len2 > len - counter)
return ASN1_DER_ERROR;
_asn1_set_value (p, der + counter, len3 + len2);
counter += len3 + len2;
move = RIGHT;
break;
case TYPE_BIT_STRING:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
if (len3 + len2 > len - counter)
return ASN1_DER_ERROR;
_asn1_set_value (p, der + counter, len3 + len2);
counter += len3 + len2;
move = RIGHT;
break;
case TYPE_SEQUENCE:
case TYPE_SET:
if (move == UP)
{
len2 = strtol (p->value, NULL, 10);
_asn1_set_value (p, NULL, 0);
if (len2 == -1)
{ /* indefinite length method */
if (len - counter + 1 > 0)
{
if ((der[counter]) || der[counter + 1])
{
asn1_delete_structure (element);
return ASN1_DER_ERROR;
}
}
else
return ASN1_DER_ERROR;
counter += 2;
}
else
{ /* definite length method */
if (len2 != counter)
{
asn1_delete_structure (element);
return ASN1_DER_ERROR;
}
}
move = RIGHT;
}
else
{ /* move==DOWN || move==RIGHT */
len3 =
asn1_get_length_der (der + counter, len - counter, &len2);
if (len3 < -1)
return ASN1_DER_ERROR;
counter += len2;
if (len3 > 0)
{
_asn1_ltostr (counter + len3, temp);
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
move = DOWN;
}
else if (len3 == 0)
{
p2 = p->down;
while (p2)
{
if (type_field (p2->type) != TYPE_TAG)
{
p3 = p2->right;
asn1_delete_structure (&p2);
p2 = p3;
}
else
p2 = p2->right;
}
move = RIGHT;
}
else
{ /* indefinite length method */
_asn1_set_value (p, "-1", 3);
move = DOWN;
}
}
break;
case TYPE_SEQUENCE_OF:
case TYPE_SET_OF:
if (move == UP)
{
len2 = strtol (p->value, NULL, 10);
if (len2 == -1)
{ /* indefinite length method */
if ((counter + 2) > len)
return ASN1_DER_ERROR;
if ((der[counter]) || der[counter + 1])
{
_asn1_append_sequence_set (p);
p = p->down;
while (p->right)
p = p->right;
move = RIGHT;
continue;
}
_asn1_set_value (p, NULL, 0);
counter += 2;
}
else
{ /* definite length method */
if (len2 > counter)
{
_asn1_append_sequence_set (p);
p = p->down;
while (p->right)
p = p->right;
move = RIGHT;
continue;
}
_asn1_set_value (p, NULL, 0);
if (len2 != counter)
{
asn1_delete_structure (element);
return ASN1_DER_ERROR;
}
}
}
else
{ /* move==DOWN || move==RIGHT */
len3 =
asn1_get_length_der (der + counter, len - counter, &len2);
if (len3 < -1)
return ASN1_DER_ERROR;
counter += len2;
if (len3)
{
if (len3 > 0)
{ /* definite length method */
_asn1_ltostr (counter + len3, temp);
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
}
else
{ /* indefinite length method */
_asn1_set_value (p, "-1", 3);
}
p2 = p->down;
while ((type_field (p2->type) == TYPE_TAG)
|| (type_field (p2->type) == TYPE_SIZE))
p2 = p2->right;
if (p2->right == NULL)
_asn1_append_sequence_set (p);
p = p2;
}
}
move = RIGHT;
break;
case TYPE_ANY:
if (asn1_get_tag_der
(der + counter, len - counter, &class, &len2,
&tag) != ASN1_SUCCESS)
return ASN1_DER_ERROR;
if (counter + len2 > len)
return ASN1_DER_ERROR;
len4 =
asn1_get_length_der (der + counter + len2,
len - counter - len2, &len3);
if (len4 < -1)
return ASN1_DER_ERROR;
if (len4 > len - counter + len2 + len3)
return ASN1_DER_ERROR;
if (len4 != -1)
{
len2 += len4;
asn1_length_der (len2 + len3, NULL, &len4);
temp2 = (unsigned char *) _asn1_malloc (len2 + len3 + len4);
if (temp2 == NULL)
{
asn1_delete_structure (element);
return ASN1_MEM_ALLOC_ERROR;
}
asn1_octet_der (der + counter, len2 + len3, temp2, &len4);
_asn1_set_value (p, temp2, len4);
_asn1_free (temp2);
counter += len2 + len3;
}
else
{ /* indefinite length */
/* Check indefinite lenth method in an EXPLICIT TAG */
if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
indefinite = 1;
else
indefinite = 0;
len2 = len - counter;
ris =
_asn1_get_indefinite_length_string (der + counter, &len2);
if (ris != ASN1_SUCCESS)
{
asn1_delete_structure (element);
return ris;
}
asn1_length_der (len2, NULL, &len4);
temp2 = (unsigned char *) _asn1_malloc (len2 + len4);
if (temp2 == NULL)
{
asn1_delete_structure (element);
return ASN1_MEM_ALLOC_ERROR;
}
asn1_octet_der (der + counter, len2, temp2, &len4);
_asn1_set_value (p, temp2, len4);
_asn1_free (temp2);
counter += len2;
/* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
an indefinite length method. */
if (indefinite)
{
if (!der[counter] && !der[counter + 1])
{
counter += 2;
}
else
{
asn1_delete_structure (element);
return ASN1_DER_ERROR;
}
}
}
move = RIGHT;
break;
default:
move = (move == UP) ? RIGHT : DOWN;
break;
}
}
if (p == node && move != DOWN)
break;
if (move == DOWN)
{
if (p->down)
p = p->down;
else
move = RIGHT;
}
if ((move == RIGHT) && !(p->type & CONST_SET))
{
if (p->right)
p = p->right;
else
move = UP;
}
if (move == UP)
p = _asn1_find_up (p);
}
_asn1_delete_not_used (*element);
if (counter != len)
{
asn1_delete_structure (element);
return ASN1_DER_ERROR;
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | asn1_write_value | 115 | 232 | 375 | lib/element.c |
asn1_retCode
asn1_write_value (ASN1_TYPE node_root, const char *name,
const void *ivalue, int len)
{
node_asn *node, *p, *p2;
unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
int len2, k, k2, negative;
const unsigned char *value = ivalue;
node = asn1_find_node (node_root, name);
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
{
asn1_delete_structure (&node);
return ASN1_SUCCESS;
}
if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL)
&& (len == 0))
{
p = node->down;
while ((type_field (p->type) == TYPE_TAG)
|| (type_field (p->type) == TYPE_SIZE))
p = p->right;
while (p->right)
asn1_delete_structure (&p->right);
return ASN1_SUCCESS;
}
switch (type_field (node->type))
{
case TYPE_BOOLEAN:
if (!strcmp (value, "TRUE"))
{
if (node->type & CONST_DEFAULT)
{
p = node->down;
while (type_field (p->type) != TYPE_DEFAULT)
p = p->right;
if (p->type & CONST_TRUE)
_asn1_set_value (node, NULL, 0);
else
_asn1_set_value (node, "T", 1);
}
else
_asn1_set_value (node, "T", 1);
}
else if (!strcmp (value, "FALSE"))
{
if (node->type & CONST_DEFAULT)
{
p = node->down;
while (type_field (p->type) != TYPE_DEFAULT)
p = p->right;
if (p->type & CONST_FALSE)
_asn1_set_value (node, NULL, 0);
else
_asn1_set_value (node, "F", 1);
}
else
_asn1_set_value (node, "F", 1);
}
else
return ASN1_VALUE_NOT_VALID;
break;
case TYPE_INTEGER:
case TYPE_ENUMERATED:
if (len == 0)
{
if ((isdigit (value[0])) || (value[0] == '-'))
{
value_temp =
(unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
if (value_temp == NULL)
return ASN1_MEM_ALLOC_ERROR;
_asn1_convert_integer (value, value_temp,
SIZEOF_UNSIGNED_LONG_INT, &len);
}
else
{ /* is an identifier like v1 */
if (!(node->type & CONST_LIST))
return ASN1_VALUE_NOT_VALID;
p = node->down;
while (p)
{
if (type_field (p->type) == TYPE_CONSTANT)
{
if ((p->name) && (!strcmp (p->name, value)))
{
value_temp =
(unsigned char *)
_asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
if (value_temp == NULL)
return ASN1_MEM_ALLOC_ERROR;
_asn1_convert_integer (p->value,
value_temp,
SIZEOF_UNSIGNED_LONG_INT,
&len);
break;
}
}
p = p->right;
}
if (p == NULL)
return ASN1_VALUE_NOT_VALID;
}
}
else
{ /* len != 0 */
value_temp = (unsigned char *) _asn1_malloc (len);
if (value_temp == NULL)
return ASN1_MEM_ALLOC_ERROR;
memcpy (value_temp, value, len);
}
if (value_temp[0] & 0x80)
negative = 1;
else
negative = 0;
if (negative && (type_field (node->type) == TYPE_ENUMERATED))
{
_asn1_free (value_temp);
return ASN1_VALUE_NOT_VALID;
}
for (k = 0; k < len - 1; k++)
if (negative && (value_temp[k] != 0xFF))
break;
else if (!negative && value_temp[k])
break;
if ((negative && !(value_temp[k] & 0x80)) ||
(!negative && (value_temp[k] & 0x80)))
k--;
asn1_length_der (len - k, NULL, &len2);
temp = (unsigned char *) _asn1_malloc (len - k + len2);
if (temp == NULL)
{
_asn1_free (value_temp);
return ASN1_MEM_ALLOC_ERROR;
}
asn1_octet_der (value_temp + k, len - k, temp, &len2);
_asn1_set_value (node, temp, len2);
_asn1_free (temp);
if (node->type & CONST_DEFAULT)
{
p = node->down;
while (type_field (p->type) != TYPE_DEFAULT)
p = p->right;
if ((isdigit (p->value[0])) || (p->value[0] == '-'))
{
default_temp =
(unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
if (default_temp == NULL)
{
_asn1_free (value_temp);
return ASN1_MEM_ALLOC_ERROR;
}
_asn1_convert_integer (p->value, default_temp,
SIZEOF_UNSIGNED_LONG_INT, &len2);
}
else
{ /* is an identifier like v1 */
if (!(node->type & CONST_LIST))
{
_asn1_free (value_temp);
return ASN1_VALUE_NOT_VALID;
}
p2 = node->down;
while (p2)
{
if (type_field (p2->type) == TYPE_CONSTANT)
{
if ((p2->name) && (!strcmp (p2->name, p->value)))
{
default_temp =
(unsigned char *)
_asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
if (default_temp == NULL)
{
_asn1_free (value_temp);
return ASN1_MEM_ALLOC_ERROR;
}
_asn1_convert_integer (p2->value,
default_temp,
SIZEOF_UNSIGNED_LONG_INT,
&len2);
break;
}
}
p2 = p2->right;
}
if (p2 == NULL)
{
_asn1_free (value_temp);
return ASN1_VALUE_NOT_VALID;
}
}
if ((len - k) == len2)
{
for (k2 = 0; k2 < len2; k2++)
if (value_temp[k + k2] != default_temp[k2])
{
break;
}
if (k2 == len2)
_asn1_set_value (node, NULL, 0);
}
_asn1_free (default_temp);
}
_asn1_free (value_temp);
break;
case TYPE_OBJECT_ID:
for (k = 0; k < strlen (value); k++)
if ((!isdigit (value[k])) && (value[k] != '.') && (value[k] != '+'))
return ASN1_VALUE_NOT_VALID;
if (node->type & CONST_DEFAULT)
{
p = node->down;
while (type_field (p->type) != TYPE_DEFAULT)
p = p->right;
if (!strcmp (value, p->value))
{
_asn1_set_value (node, NULL, 0);
break;
}
}
_asn1_set_value (node, value, strlen (value) + 1);
break;
case TYPE_TIME:
if (node->type & CONST_UTC)
{
if (strlen (value) < 11)
return ASN1_VALUE_NOT_VALID;
for (k = 0; k < 10; k++)
if (!isdigit (value[k]))
return ASN1_VALUE_NOT_VALID;
switch (strlen (value))
{
case 11:
if (value[10] != 'Z')
return ASN1_VALUE_NOT_VALID;
break;
case 13:
if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
(value[12] != 'Z'))
return ASN1_VALUE_NOT_VALID;
break;
case 15:
if ((value[10] != '+') && (value[10] != '-'))
return ASN1_VALUE_NOT_VALID;
for (k = 11; k < 15; k++)
if (!isdigit (value[k]))
return ASN1_VALUE_NOT_VALID;
break;
case 17:
if ((!isdigit (value[10])) || (!isdigit (value[11])))
return ASN1_VALUE_NOT_VALID;
if ((value[12] != '+') && (value[12] != '-'))
return ASN1_VALUE_NOT_VALID;
for (k = 13; k < 17; k++)
if (!isdigit (value[k]))
return ASN1_VALUE_NOT_VALID;
break;
default:
return ASN1_VALUE_NOT_FOUND;
}
_asn1_set_value (node, value, strlen (value) + 1);
}
else
{ /* GENERALIZED TIME */
if (value)
_asn1_set_value (node, value, strlen (value) + 1);
}
break;
case TYPE_OCTET_STRING:
if (len == 0)
len = strlen (value);
asn1_length_der (len, NULL, &len2);
temp = (unsigned char *) _asn1_malloc (len + len2);
if (temp == NULL)
return ASN1_MEM_ALLOC_ERROR;
asn1_octet_der (value, len, temp, &len2);
_asn1_set_value (node, temp, len2);
_asn1_free (temp);
break;
case TYPE_GENERALSTRING:
if (len == 0)
len = strlen (value);
asn1_length_der (len, NULL, &len2);
temp = (unsigned char *) _asn1_malloc (len + len2);
if (temp == NULL)
return ASN1_MEM_ALLOC_ERROR;
asn1_octet_der (value, len, temp, &len2);
_asn1_set_value (node, temp, len2);
_asn1_free (temp);
break;
case TYPE_BIT_STRING:
if (len == 0)
len = strlen (value);
asn1_length_der ((len >> 3) + 2, NULL, &len2);
temp = (unsigned char *) _asn1_malloc ((len >> 3) + 2 + len2);
if (temp == NULL)
return ASN1_MEM_ALLOC_ERROR;
asn1_bit_der (value, len, temp, &len2);
_asn1_set_value (node, temp, len2);
_asn1_free (temp);
break;
case TYPE_CHOICE:
p = node->down;
while (p)
{
if (!strcmp (p->name, value))
{
p2 = node->down;
while (p2)
{
if (p2 != p)
{
asn1_delete_structure (&p2);
p2 = node->down;
}
else
p2 = p2->right;
}
break;
}
p = p->right;
}
if (!p)
return ASN1_ELEMENT_NOT_FOUND;
break;
case TYPE_ANY:
asn1_length_der (len, NULL, &len2);
temp = (unsigned char *) _asn1_malloc (len + len2);
if (temp == NULL)
return ASN1_MEM_ALLOC_ERROR;
asn1_octet_der (value, len, temp, &len2);
_asn1_set_value (node, temp, len2);
_asn1_free (temp);
break;
case TYPE_SEQUENCE_OF:
case TYPE_SET_OF:
if (strcmp (value, "NEW"))
return ASN1_VALUE_NOT_VALID;
_asn1_append_sequence_set (node);
break;
default:
return ASN1_ELEMENT_NOT_FOUND;
break;
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | asn1_print_structure | 125 | 235 | 349 | lib/structure.c |
void
asn1_print_structure (FILE * out, ASN1_TYPE structure, const char *name,
int mode)
{
node_asn *p, *root;
int k, indent = 0, len, len2, len3;
if (out == NULL)
return;
root = asn1_find_node (structure, name);
if (root == NULL)
return;
p = root;
while (p)
{
if (mode == ASN1_PRINT_ALL)
{
for (k = 0; k < indent; k++)
fprintf (out, " ");
fprintf (out, "name:");
if (p->name)
fprintf (out, "%s ", p->name);
else
fprintf (out, "NULL ");
}
else
{
switch (type_field (p->type))
{
case TYPE_CONSTANT:
case TYPE_TAG:
case TYPE_SIZE:
break;
default:
for (k = 0; k < indent; k++)
fprintf (out, " ");
fprintf (out, "name:");
if (p->name)
fprintf (out, "%s ", p->name);
else
fprintf (out, "NULL ");
}
}
if (mode != ASN1_PRINT_NAME)
{
switch (type_field (p->type))
{
case TYPE_CONSTANT:
if (mode == ASN1_PRINT_ALL)
fprintf (out, "type:CONST");
break;
case TYPE_TAG:
if (mode == ASN1_PRINT_ALL)
fprintf (out, "type:TAG");
break;
case TYPE_SIZE:
if (mode == ASN1_PRINT_ALL)
fprintf (out, "type:SIZE");
break;
case TYPE_DEFAULT:
fprintf (out, "type:DEFAULT");
break;
case TYPE_NULL:
fprintf (out, "type:NULL");
break;
case TYPE_IDENTIFIER:
fprintf (out, "type:IDENTIFIER");
break;
case TYPE_INTEGER:
fprintf (out, "type:INTEGER");
break;
case TYPE_ENUMERATED:
fprintf (out, "type:ENUMERATED");
break;
case TYPE_TIME:
fprintf (out, "type:TIME");
break;
case TYPE_BOOLEAN:
fprintf (out, "type:BOOLEAN");
break;
case TYPE_SEQUENCE:
fprintf (out, "type:SEQUENCE");
break;
case TYPE_BIT_STRING:
fprintf (out, "type:BIT_STR");
break;
case TYPE_OCTET_STRING:
fprintf (out, "type:OCT_STR");
break;
case TYPE_GENERALSTRING:
fprintf (out, "type:GENERALSTRING");
break;
case TYPE_SEQUENCE_OF:
fprintf (out, "type:SEQ_OF");
break;
case TYPE_OBJECT_ID:
fprintf (out, "type:OBJ_ID");
break;
case TYPE_ANY:
fprintf (out, "type:ANY");
break;
case TYPE_SET:
fprintf (out, "type:SET");
break;
case TYPE_SET_OF:
fprintf (out, "type:SET_OF");
break;
case TYPE_CHOICE:
fprintf (out, "type:CHOICE");
break;
case TYPE_DEFINITIONS:
fprintf (out, "type:DEFINITIONS");
break;
default:
break;
}
}
if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
{
switch (type_field (p->type))
{
case TYPE_CONSTANT:
if (mode == ASN1_PRINT_ALL)
if (p->value)
fprintf (out, " value:%s", p->value);
break;
case TYPE_TAG:
if (mode == ASN1_PRINT_ALL)
if (p->value)
fprintf (out, " value:%s", p->value);
break;
case TYPE_SIZE:
if (mode == ASN1_PRINT_ALL)
if (p->value)
fprintf (out, " value:%s", p->value);
break;
case TYPE_DEFAULT:
if (p->value)
fprintf (out, " value:%s", p->value);
else if (p->type & CONST_TRUE)
fprintf (out, " value:TRUE");
else if (p->type & CONST_FALSE)
fprintf (out, " value:FALSE");
break;
case TYPE_IDENTIFIER:
if (p->value)
fprintf (out, " value:%s", p->value);
break;
case TYPE_INTEGER:
if (p->value)
{
len2 = -1;
len = asn1_get_length_der (p->value, p->value_len, &len2);
fprintf (out, " value:0x");
if (len > 0)
for (k = 0; k < len; k++)
fprintf (out, "%02x", (p->value)[k + len2]);
}
break;
case TYPE_ENUMERATED:
if (p->value)
{
len2 = -1;
len = asn1_get_length_der (p->value, p->value_len, &len2);
fprintf (out, " value:0x");
if (len > 0)
for (k = 0; k < len; k++)
fprintf (out, "%02x", (p->value)[k + len2]);
}
break;
case TYPE_TIME:
if (p->value)
fprintf (out, " value:%s", p->value);
break;
case TYPE_BOOLEAN:
if (p->value)
{
if (p->value[0] == 'T')
fprintf (out, " value:TRUE");
else if (p->value[0] == 'F')
fprintf (out, " value:FALSE");
}
break;
case TYPE_BIT_STRING:
if (p->value)
{
len2 = -1;
len = asn1_get_length_der (p->value, p->value_len, &len2);
if (len > 0)
{
fprintf (out, " value(%i):",
(len - 1) * 8 - (p->value[len2]));
for (k = 1; k < len; k++)
fprintf (out, "%02x", (p->value)[k + len2]);
}
}
break;
case TYPE_OCTET_STRING:
if (p->value)
{
len2 = -1;
len = asn1_get_length_der (p->value, p->value_len, &len2);
fprintf (out, " value:");
if (len > 0)
for (k = 0; k < len; k++)
fprintf (out, "%02x", (p->value)[k + len2]);
}
break;
case TYPE_GENERALSTRING:
if (p->value)
{
len2 = -1;
len = asn1_get_length_der (p->value, p->value_len, &len2);
fprintf (out, " value:");
if (len > 0)
for (k = 0; k < len; k++)
fprintf (out, "%02x", (p->value)[k + len2]);
}
break;
case TYPE_OBJECT_ID:
if (p->value)
fprintf (out, " value:%s", p->value);
break;
case TYPE_ANY:
if (p->value)
{
len3 = -1;
len2 = asn1_get_length_der (p->value, p->value_len, &len3);
fprintf (out, " value:");
if (len2 > 0)
for (k = 0; k < len2; k++)
fprintf (out, "%02x", (p->value)[k + len3]);
}
break;
case TYPE_SET:
case TYPE_SET_OF:
case TYPE_CHOICE:
case TYPE_DEFINITIONS:
case TYPE_SEQUENCE_OF:
case TYPE_SEQUENCE:
case TYPE_NULL:
break;
default:
break;
}
}
if (mode == ASN1_PRINT_ALL)
{
if (p->type & 0x1FFFFF00)
{
fprintf (out, " attr:");
if (p->type & CONST_UNIVERSAL)
fprintf (out, "UNIVERSAL,");
if (p->type & CONST_PRIVATE)
fprintf (out, "PRIVATE,");
if (p->type & CONST_APPLICATION)
fprintf (out, "APPLICATION,");
if (p->type & CONST_EXPLICIT)
fprintf (out, "EXPLICIT,");
if (p->type & CONST_IMPLICIT)
fprintf (out, "IMPLICIT,");
if (p->type & CONST_TAG)
fprintf (out, "TAG,");
if (p->type & CONST_DEFAULT)
fprintf (out, "DEFAULT,");
if (p->type & CONST_TRUE)
fprintf (out, "TRUE,");
if (p->type & CONST_FALSE)
fprintf (out, "FALSE,");
if (p->type & CONST_LIST)
fprintf (out, "LIST,");
if (p->type & CONST_MIN_MAX)
fprintf (out, "MIN_MAX,");
if (p->type & CONST_OPTION)
fprintf (out, "OPTION,");
if (p->type & CONST_1_PARAM)
fprintf (out, "1_PARAM,");
if (p->type & CONST_SIZE)
fprintf (out, "SIZE,");
if (p->type & CONST_DEFINED_BY)
fprintf (out, "DEF_BY,");
if (p->type & CONST_GENERALIZED)
fprintf (out, "GENERALIZED,");
if (p->type & CONST_UTC)
fprintf (out, "UTC,");
if (p->type & CONST_SET)
fprintf (out, "SET,");
if (p->type & CONST_NOT_USED)
fprintf (out, "NOT_USED,");
if (p->type & CONST_ASSIGN)
fprintf (out, "ASSIGNMENT,");
}
}
if (mode == ASN1_PRINT_ALL)
{
fprintf (out, "\n");
}
else
{
switch (type_field (p->type))
{
case TYPE_CONSTANT:
case TYPE_TAG:
case TYPE_SIZE:
break;
default:
fprintf (out, "\n");
}
}
if (p->down)
{
p = p->down;
indent += 2;
}
else if (p == root)
{
p = NULL;
break;
}
else if (p->right)
p = p->right;
else
{
while (1)
{
p = _asn1_find_up (p);
if (p == root)
{
p = NULL;
break;
}
indent -= 2;
if (p->right)
{
p = p->right;
break;
}
}
}
}
}
|
|||||
| ↓ | asn1_der_decoding_startEnd | 85 | 188 | 320 | lib/decoding.c |
asn1_retCode
asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len,
const char *name_element, int *start, int *end)
{
node_asn *node, *node_to_find, *p, *p2, *p3;
int counter, len2, len3, len4, move, ris;
unsigned char class;
unsigned long tag;
int indefinite;
const unsigned char *der = ider;
node = element;
if (node == ASN1_TYPE_EMPTY)
return ASN1_ELEMENT_NOT_FOUND;
node_to_find = asn1_find_node (node, name_element);
if (node_to_find == NULL)
return ASN1_ELEMENT_NOT_FOUND;
if (node_to_find == node)
{
*start = 0;
*end = len - 1;
return ASN1_SUCCESS;
}
if (node->type & CONST_OPTION)
return ASN1_GENERIC_ERROR;
counter = 0;
move = DOWN;
p = node;
while (1)
{
ris = ASN1_SUCCESS;
if (move != UP)
{
if (p->type & CONST_SET)
{
p2 = _asn1_find_up (p);
len2 = strtol (p2->value, NULL, 10);
if (len2 == -1)
{
if (!der[counter] && !der[counter + 1])
{
p = p2;
move = UP;
counter += 2;
continue;
}
}
else if (counter == len2)
{
p = p2;
move = UP;
continue;
}
else if (counter > len2)
return ASN1_DER_ERROR;
p2 = p2->down;
while (p2)
{
if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
{ /* CONTROLLARE */
if (type_field (p2->type) != TYPE_CHOICE)
ris =
_asn1_extract_tag_der (p2, der + counter,
len - counter, &len2);
else
{
p3 = p2->down;
ris =
_asn1_extract_tag_der (p3, der + counter,
len - counter, &len2);
}
if (ris == ASN1_SUCCESS)
{
p2->type &= ~CONST_NOT_USED;
p = p2;
break;
}
}
p2 = p2->right;
}
if (p2 == NULL)
return ASN1_DER_ERROR;
}
if (p == node_to_find)
*start = counter;
if (type_field (p->type) == TYPE_CHOICE)
{
p = p->down;
ris =
_asn1_extract_tag_der (p, der + counter, len - counter,
&len2);
if (p == node_to_find)
*start = counter;
}
if (ris == ASN1_SUCCESS)
ris =
_asn1_extract_tag_der (p, der + counter, len - counter, &len2);
if (ris != ASN1_SUCCESS)
{
if (p->type & CONST_OPTION)
{
p->type |= CONST_NOT_USED;
move = RIGHT;
}
else if (p->type & CONST_DEFAULT)
{
move = RIGHT;
}
else
{
return ASN1_TAG_ERROR;
}
}
else
counter += len2;
}
if (ris == ASN1_SUCCESS)
{
switch (type_field (p->type))
{
case TYPE_NULL:
if (der[counter])
return ASN1_DER_ERROR;
counter++;
move = RIGHT;
break;
case TYPE_BOOLEAN:
if (der[counter++] != 1)
return ASN1_DER_ERROR;
counter++;
move = RIGHT;
break;
case TYPE_INTEGER:
case TYPE_ENUMERATED:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
counter += len3 + len2;
move = RIGHT;
break;
case TYPE_OBJECT_ID:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
counter += len2 + len3;
move = RIGHT;
break;
case TYPE_TIME:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
counter += len2 + len3;
move = RIGHT;
break;
case TYPE_OCTET_STRING:
len3 = len - counter;
ris = _asn1_get_octet_string (der + counter, NULL, &len3);
if (ris != ASN1_SUCCESS)
return ris;
counter += len3;
move = RIGHT;
break;
case TYPE_GENERALSTRING:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
counter += len3 + len2;
move = RIGHT;
break;
case TYPE_BIT_STRING:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
counter += len3 + len2;
move = RIGHT;
break;
case TYPE_SEQUENCE:
case TYPE_SET:
if (move != UP)
{
len3 =
asn1_get_length_der (der + counter, len - counter, &len2);
if (len3 < -1)
return ASN1_DER_ERROR;
counter += len2;
if (len3 == 0)
move = RIGHT;
else
move = DOWN;
}
else
{
if (!der[counter] && !der[counter + 1]) /* indefinite length method */
counter += 2;
move = RIGHT;
}
break;
case TYPE_SEQUENCE_OF:
case TYPE_SET_OF:
if (move != UP)
{
len3 =
asn1_get_length_der (der + counter, len - counter, &len2);
if (len3 < -1)
return ASN1_DER_ERROR;
counter += len2;
if ((len3 == -1) && !der[counter] && !der[counter + 1])
counter += 2;
else if (len3)
{
p2 = p->down;
while ((type_field (p2->type) == TYPE_TAG) ||
(type_field (p2->type) == TYPE_SIZE))
p2 = p2->right;
p = p2;
}
}
else
{
if (!der[counter] && !der[counter + 1]) /* indefinite length method */
counter += 2;
}
move = RIGHT;
break;
case TYPE_ANY:
if (asn1_get_tag_der
(der + counter, len - counter, &class, &len2,
&tag) != ASN1_SUCCESS)
return ASN1_DER_ERROR;
if (counter + len2 > len)
return ASN1_DER_ERROR;
len4 =
asn1_get_length_der (der + counter + len2,
len - counter - len2, &len3);
if (len4 < -1)
return ASN1_DER_ERROR;
if (len4 != -1)
{
counter += len2 + len4 + len3;
}
else
{ /* indefinite length */
/* Check indefinite lenth method in an EXPLICIT TAG */
if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
indefinite = 1;
else
indefinite = 0;
len2 = len - counter;
ris =
_asn1_get_indefinite_length_string (der + counter, &len2);
if (ris != ASN1_SUCCESS)
return ris;
counter += len2;
/* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
an indefinite length method. */
if (indefinite)
{
if (!der[counter] && !der[counter + 1])
counter += 2;
else
return ASN1_DER_ERROR;
}
}
move = RIGHT;
break;
default:
move = (move == UP) ? RIGHT : DOWN;
break;
}
}
if ((p == node_to_find) && (move == RIGHT))
{
*end = counter - 1;
return ASN1_SUCCESS;
}
if (p == node && move != DOWN)
break;
if (move == DOWN)
{
if (p->down)
p = p->down;
else
move = RIGHT;
}
if ((move == RIGHT) && !(p->type & CONST_SET))
{
if (p->right)
p = p->right;
else
move = UP;
}
if (move == UP)
p = _asn1_find_up (p);
}
return ASN1_ELEMENT_NOT_FOUND;
}
|
|||||
| ↓ | asn1_der_coding | 83 | 226 | 357 | lib/coding.c |
asn1_retCode
asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len,
char *ErrorDescription)
{
node_asn *node, *p, *p2;
char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
asn1_retCode err;
unsigned char *der = ider;
node = asn1_find_node (element, name);
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
/* Node is now a locally allocated variable.
* That is because in some point we modify the
* structure, and I don't know why! --nmav
*/
node = _asn1_copy_structure3 (node);
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
max_len = *len;
counter = 0;
move = DOWN;
p = node;
while (1)
{
counter_old = counter;
max_len_old = max_len;
if (move != UP)
{
err = _asn1_insert_tag_der (p, der, &counter, &max_len);
if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
goto error;
}
switch (type_field (p->type))
{
case TYPE_NULL:
max_len--;
if (max_len >= 0)
der[counter] = 0;
counter++;
move = RIGHT;
break;
case TYPE_BOOLEAN:
if ((p->type & CONST_DEFAULT) && (p->value == NULL))
{
counter = counter_old;
max_len = max_len_old;
}
else
{
if (p->value == NULL)
{
_asn1_error_description_value_not_found (p,
ErrorDescription);
err = ASN1_VALUE_NOT_FOUND;
goto error;
}
max_len -= 2;
if (max_len >= 0)
{
der[counter++] = 1;
if (p->value[0] == 'F')
der[counter++] = 0;
else
der[counter++] = 0xFF;
}
else
counter += 2;
}
move = RIGHT;
break;
case TYPE_INTEGER:
case TYPE_ENUMERATED:
if ((p->type & CONST_DEFAULT) && (p->value == NULL))
{
counter = counter_old;
max_len = max_len_old;
}
else
{
if (p->value == NULL)
{
_asn1_error_description_value_not_found (p,
ErrorDescription);
err = ASN1_VALUE_NOT_FOUND;
goto error;
}
len2 = asn1_get_length_der (p->value, p->value_len, &len3);
if (len2 < 0)
{
err = ASN1_DER_ERROR;
goto error;
}
max_len -= len2 + len3;
if (max_len >= 0)
memcpy (der + counter, p->value, len3 + len2);
counter += len3 + len2;
}
move = RIGHT;
break;
case TYPE_OBJECT_ID:
if ((p->type & CONST_DEFAULT) && (p->value == NULL))
{
counter = counter_old;
max_len = max_len_old;
}
else
{
if (p->value == NULL)
{
_asn1_error_description_value_not_found (p,
ErrorDescription);
err = ASN1_VALUE_NOT_FOUND;
goto error;
}
len2 = max_len;
err = _asn1_objectid_der (p->value, der + counter, &len2);
if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
goto error;
max_len -= len2;
counter += len2;
}
move = RIGHT;
break;
case TYPE_TIME:
if (p->value == NULL)
{
_asn1_error_description_value_not_found (p, ErrorDescription);
err = ASN1_VALUE_NOT_FOUND;
goto error;
}
len2 = max_len;
err = _asn1_time_der (p->value, der + counter, &len2);
if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
goto error;
max_len -= len2;
counter += len2;
move = RIGHT;
break;
case TYPE_OCTET_STRING:
if (p->value == NULL)
{
_asn1_error_description_value_not_found (p, ErrorDescription);
err = ASN1_VALUE_NOT_FOUND;
goto error;
}
len2 = asn1_get_length_der (p->value, p->value_len, &len3);
if (len2 < 0)
{
err = ASN1_DER_ERROR;
goto error;
}
max_len -= len2 + len3;
if (max_len >= 0)
memcpy (der + counter, p->value, len3 + len2);
counter += len3 + len2;
move = RIGHT;
break;
case TYPE_GENERALSTRING:
if (p->value == NULL)
{
_asn1_error_description_value_not_found (p, ErrorDescription);
err = ASN1_VALUE_NOT_FOUND;
goto error;
}
len2 = asn1_get_length_der (p->value, p->value_len, &len3);
if (len2 < 0)
{
err = ASN1_DER_ERROR;
goto error;
}
max_len -= len2 + len3;
if (max_len >= 0)
memcpy (der + counter, p->value, len3 + len2);
counter += len3 + len2;
move = RIGHT;
break;
case TYPE_BIT_STRING:
if (p->value == NULL)
{
_asn1_error_description_value_not_found (p, ErrorDescription);
err = ASN1_VALUE_NOT_FOUND;
goto error;
}
len2 = asn1_get_length_der (p->value, p->value_len, &len3);
if (len2 < 0)
{
err = ASN1_DER_ERROR;
goto error;
}
max_len -= len2 + len3;
if (max_len >= 0)
memcpy (der + counter, p->value, len3 + len2);
counter += len3 + len2;
move = RIGHT;
break;
case TYPE_SEQUENCE:
case TYPE_SET:
if (move != UP)
{
_asn1_ltostr (counter, temp);
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
if (p->down == NULL)
{
move = UP;
continue;
}
else
{
p2 = p->down;
while (p2 && (type_field (p2->type) == TYPE_TAG))
p2 = p2->right;
if (p2)
{
p = p2;
move = RIGHT;
continue;
}
move = UP;
continue;
}
}
else
{ /* move==UP */
len2 = strtol (p->value, NULL, 10);
_asn1_set_value (p, NULL, 0);
if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
_asn1_ordering_set (der + len2, max_len - len2, p);
asn1_length_der (counter - len2, temp, &len3);
max_len -= len3;
if (max_len >= 0)
{
memmove (der + len2 + len3, der + len2, counter - len2);
memcpy (der + len2, temp, len3);
}
counter += len3;
move = RIGHT;
}
break;
case TYPE_SEQUENCE_OF:
case TYPE_SET_OF:
if (move != UP)
{
_asn1_ltostr (counter, temp);
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
p = p->down;
while ((type_field (p->type) == TYPE_TAG)
|| (type_field (p->type) == TYPE_SIZE))
p = p->right;
if (p->right)
{
p = p->right;
move = RIGHT;
continue;
}
else
p = _asn1_find_up (p);
move = UP;
}
if (move == UP)
{
len2 = strtol (p->value, NULL, 10);
_asn1_set_value (p, NULL, 0);
if ((type_field (p->type) == TYPE_SET_OF)
&& (max_len - len2 > 0))
{
_asn1_ordering_set_of (der + len2, max_len - len2, p);
}
asn1_length_der (counter - len2, temp, &len3);
max_len -= len3;
if (max_len >= 0)
{
memmove (der + len2 + len3, der + len2, counter - len2);
memcpy (der + len2, temp, len3);
}
counter += len3;
move = RIGHT;
}
break;
case TYPE_ANY:
if (p->value == NULL)
{
_asn1_error_description_value_not_found (p, ErrorDescription);
err = ASN1_VALUE_NOT_FOUND;
goto error;
}
len2 = asn1_get_length_der (p->value, p->value_len, &len3);
if (len2 < 0)
{
err = ASN1_DER_ERROR;
goto error;
}
max_len -= len2;
if (max_len >= 0)
memcpy (der + counter, p->value + len3, len2);
counter += len2;
move = RIGHT;
break;
default:
move = (move == UP) ? RIGHT : DOWN;
break;
}
if ((move != DOWN) && (counter != counter_old))
{
err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
goto error;
}
if (p == node && move != DOWN)
break;
if (move == DOWN)
{
if (p->down)
p = p->down;
else
move = RIGHT;
}
if (move == RIGHT)
{
if (p->right)
p = p->right;
else
move = UP;
}
if (move == UP)
p = _asn1_find_up (p);
}
*len = counter;
if (max_len < 0)
{
err = ASN1_MEM_ERROR;
goto error;
}
err = ASN1_SUCCESS;
error:
asn1_delete_structure (&node);
return err;
}
|
|||||
| ↓ | _asn1_extract_tag_der | 73 | 103 | 191 | lib/decoding.c |
int
_asn1_extract_tag_der (node_asn * node, const unsigned char *der, int der_len,
int *ret_len)
{
node_asn *p;
int counter, len2, len3, is_tag_implicit;
unsigned long tag, tag_implicit = 0;
unsigned char class, class2, class_implicit = 0;
if (der_len <= 0)
return ASN1_GENERIC_ERROR;
counter = is_tag_implicit = 0;
if (node->type & CONST_TAG)
{
p = node->down;
while (p)
{
if (type_field (p->type) == TYPE_TAG)
{
if (p->type & CONST_APPLICATION)
class2 = ASN1_CLASS_APPLICATION;
else if (p->type & CONST_UNIVERSAL)
class2 = ASN1_CLASS_UNIVERSAL;
else if (p->type & CONST_PRIVATE)
class2 = ASN1_CLASS_PRIVATE;
else
class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
if (p->type & CONST_EXPLICIT)
{
if (asn1_get_tag_der
(der + counter, der_len - counter, &class, &len2,
&tag) != ASN1_SUCCESS)
return ASN1_DER_ERROR;
if (counter + len2 > der_len)
return ASN1_DER_ERROR;
counter += len2;
len3 =
asn1_get_length_der (der + counter, der_len - counter,
&len2);
if (len3 < 0)
return ASN1_DER_ERROR;
counter += len2;
if (!is_tag_implicit)
{
if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
(tag != strtoul ((char *) p->value, NULL, 10)))
return ASN1_TAG_ERROR;
}
else
{ /* ASN1_TAG_IMPLICIT */
if ((class != class_implicit) || (tag != tag_implicit))
return ASN1_TAG_ERROR;
}
is_tag_implicit = 0;
}
else
{ /* ASN1_TAG_IMPLICIT */
if (!is_tag_implicit)
{
if ((type_field (node->type) == TYPE_SEQUENCE) ||
(type_field (node->type) == TYPE_SEQUENCE_OF) ||
(type_field (node->type) == TYPE_SET) ||
(type_field (node->type) == TYPE_SET_OF))
class2 |= ASN1_CLASS_STRUCTURED;
class_implicit = class2;
tag_implicit = strtoul ((char *) p->value, NULL, 10);
is_tag_implicit = 1;
}
}
}
p = p->right;
}
}
if (is_tag_implicit)
{
if (asn1_get_tag_der
(der + counter, der_len - counter, &class, &len2,
&tag) != ASN1_SUCCESS)
return ASN1_DER_ERROR;
if (counter + len2 > der_len)
return ASN1_DER_ERROR;
if ((class != class_implicit) || (tag != tag_implicit))
{
if (type_field (node->type) == TYPE_OCTET_STRING)
{
class_implicit |= ASN1_CLASS_STRUCTURED;
if ((class != class_implicit) || (tag != tag_implicit))
return ASN1_TAG_ERROR;
}
else
return ASN1_TAG_ERROR;
}
}
else
{
if (type_field (node->type) == TYPE_TAG)
{
counter = 0;
*ret_len = counter;
return ASN1_SUCCESS;
}
if (asn1_get_tag_der
(der + counter, der_len - counter, &class, &len2,
&tag) != ASN1_SUCCESS)
return ASN1_DER_ERROR;
if (counter + len2 > der_len)
return ASN1_DER_ERROR;
switch (type_field (node->type))
{
case TYPE_NULL:
if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
return ASN1_DER_ERROR;
break;
case TYPE_BOOLEAN:
if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
return ASN1_DER_ERROR;
break;
case TYPE_INTEGER:
if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
return ASN1_DER_ERROR;
break;
case TYPE_ENUMERATED:
if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
return ASN1_DER_ERROR;
break;
case TYPE_OBJECT_ID:
if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
return ASN1_DER_ERROR;
break;
case TYPE_TIME:
if (node->type & CONST_UTC)
{
if ((class != ASN1_CLASS_UNIVERSAL)
|| (tag != ASN1_TAG_UTCTime))
return ASN1_DER_ERROR;
}
else
{
if ((class != ASN1_CLASS_UNIVERSAL)
|| (tag != ASN1_TAG_GENERALIZEDTime))
return ASN1_DER_ERROR;
}
break;
case TYPE_OCTET_STRING:
if (((class != ASN1_CLASS_UNIVERSAL)
&& (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
|| (tag != ASN1_TAG_OCTET_STRING))
return ASN1_DER_ERROR;
break;
case TYPE_GENERALSTRING:
if ((class != ASN1_CLASS_UNIVERSAL)
|| (tag != ASN1_TAG_GENERALSTRING))
return ASN1_DER_ERROR;
break;
case TYPE_BIT_STRING:
if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
return ASN1_DER_ERROR;
break;
case TYPE_SEQUENCE:
case TYPE_SEQUENCE_OF:
if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
|| (tag != ASN1_TAG_SEQUENCE))
return ASN1_DER_ERROR;
break;
case TYPE_SET:
case TYPE_SET_OF:
if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
|| (tag != ASN1_TAG_SET))
return ASN1_DER_ERROR;
break;
case TYPE_ANY:
counter -= len2;
break;
default:
return ASN1_DER_ERROR;
break;
}
}
counter += len2;
*ret_len = counter;
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_expand_object_id | 44 | 95 | 169 | lib/parser_aux.c |
asn1_retCode
_asn1_expand_object_id (ASN1_TYPE node)
{
node_asn *p, *p2, *p3, *p4, *p5;
char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
int move, tlen;
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
_asn1_str_cpy (name_root, sizeof (name_root), node->name);
p = node;
move = DOWN;
while (!((p == node) && (move == UP)))
{
if (move != UP)
{
if ((type_field (p->type) == TYPE_OBJECT_ID)
&& (p->type & CONST_ASSIGN))
{
p2 = p->down;
if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
{
if (p2->value && !isdigit (p2->value[0]))
{
_asn1_str_cpy (name2, sizeof (name2), name_root);
_asn1_str_cat (name2, sizeof (name2), ".");
_asn1_str_cat (name2, sizeof (name2), p2->value);
p3 = asn1_find_node (node, name2);
if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
!(p3->type & CONST_ASSIGN))
return ASN1_ELEMENT_NOT_FOUND;
_asn1_set_down (p, p2->right);
_asn1_remove_node (p2);
p2 = p;
p4 = p3->down;
while (p4)
{
if (type_field (p4->type) == TYPE_CONSTANT)
{
p5 = _asn1_add_node_only (TYPE_CONSTANT);
_asn1_set_name (p5, p4->name);
tlen = strlen (p4->value);
if (tlen > 0)
_asn1_set_value (p5, p4->value, tlen + 1);
if (p2 == p)
{
_asn1_set_right (p5, p->down);
_asn1_set_down (p, p5);
}
else
{
_asn1_set_right (p5, p2->right);
_asn1_set_right (p2, p5);
}
p2 = p5;
}
p4 = p4->right;
}
move = DOWN;
continue;
}
}
}
move = DOWN;
}
else
move = RIGHT;
if (move == DOWN)
{
if (p->down)
p = p->down;
else
move = RIGHT;
}
if (p == node)
{
move = UP;
continue;
}
if (move == RIGHT)
{
if (p->right)
p = p->right;
else
move = UP;
}
if (move == UP)
p = _asn1_find_up (p);
}
/*******************************/
/* expand DEFAULT */
/*******************************/
p = node;
move = DOWN;
while (!((p == node) && (move == UP)))
{
if (move != UP)
{
if ((type_field (p->type) == TYPE_OBJECT_ID) &&
(p->type & CONST_DEFAULT))
{
p2 = p->down;
if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
{
_asn1_str_cpy (name2, sizeof (name2), name_root);
_asn1_str_cat (name2, sizeof (name2), ".");
_asn1_str_cat (name2, sizeof (name2), p2->value);
p3 = asn1_find_node (node, name2);
if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
!(p3->type & CONST_ASSIGN))
return ASN1_ELEMENT_NOT_FOUND;
p4 = p3->down;
name2[0] = 0;
while (p4)
{
if (type_field (p4->type) == TYPE_CONSTANT)
{
if (name2[0])
_asn1_str_cat (name2, sizeof (name2), ".");
_asn1_str_cat (name2, sizeof (name2), p4->value);
}
p4 = p4->right;
}
tlen = strlen (name2);
if (tlen > 0)
_asn1_set_value (p2, name2, tlen + 1);
}
}
move = DOWN;
}
else
move = RIGHT;
if (move == DOWN)
{
if (p->down)
p = p->down;
else
move = RIGHT;
}
if (p == node)
{
move = UP;
continue;
}
if (move == RIGHT)
{
if (p->right)
p = p->right;
else
move = UP;
}
if (move == UP)
p = _asn1_find_up (p);
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | asn1_expand_any_defined_by | 43 | 101 | 211 | lib/decoding.c |
asn1_retCode
asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element)
{
char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
value[ASN1_MAX_NAME_SIZE];
asn1_retCode retCode = ASN1_SUCCESS, result;
int len, len2, len3;
ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY;
char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
return ASN1_ELEMENT_NOT_FOUND;
strcpy (definitionsName, definitions->name);
strcat (definitionsName, ".");
p = *element;
while (p)
{
switch (type_field (p->type))
{
case TYPE_ANY:
if ((p->type & CONST_DEFINED_BY) && (p->value))
{
/* search the "DEF_BY" element */
p2 = p->down;
while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
p2 = p2->right;
if (!p2)
{
retCode = ASN1_ERROR_TYPE_ANY;
break;
}
p3 = _asn1_find_up (p);
if (!p3)
{
retCode = ASN1_ERROR_TYPE_ANY;
break;
}
p3 = p3->down;
while (p3)
{
if ((p3->name) && !(strcmp (p3->name, p2->name)))
break;
p3 = p3->right;
}
if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
(p3->value == NULL))
{
p3 = _asn1_find_up (p);
p3 = _asn1_find_up (p3);
if (!p3)
{
retCode = ASN1_ERROR_TYPE_ANY;
break;
}
p3 = p3->down;
while (p3)
{
if ((p3->name) && !(strcmp (p3->name, p2->name)))
break;
p3 = p3->right;
}
if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
(p3->value == NULL))
{
retCode = ASN1_ERROR_TYPE_ANY;
break;
}
}
/* search the OBJECT_ID into definitions */
p2 = definitions->down;
while (p2)
{
if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
(p2->type & CONST_ASSIGN))
{
strcpy (name, definitionsName);
strcat (name, p2->name);
len = ASN1_MAX_NAME_SIZE;
result =
asn1_read_value (definitions, name, value, &len);
if ((result == ASN1_SUCCESS)
&& (!strcmp (p3->value, value)))
{
p2 = p2->right; /* pointer to the structure to
use for expansion */
while ((p2) && (p2->type & CONST_ASSIGN))
p2 = p2->right;
if (p2)
{
strcpy (name, definitionsName);
strcat (name, p2->name);
result =
asn1_create_element (definitions, name, &aux);
if (result == ASN1_SUCCESS)
{
_asn1_set_name (aux, p->name);
len2 =
asn1_get_length_der (p->value,
p->value_len, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
result =
asn1_der_decoding (&aux, p->value + len3,
len2,
errorDescription);
if (result == ASN1_SUCCESS)
{
_asn1_set_right (aux, p->right);
_asn1_set_right (p, aux);
result = asn1_delete_structure (&p);
if (result == ASN1_SUCCESS)
{
p = aux;
aux = ASN1_TYPE_EMPTY;
break;
}
else
{ /* error with asn1_delete_structure */
asn1_delete_structure (&aux);
retCode = result;
break;
}
}
else
{ /* error with asn1_der_decoding */
retCode = result;
break;
}
}
else
{ /* error with asn1_create_element */
retCode = result;
break;
}
}
else
{ /* error with the pointer to the structure to exapand */
retCode = ASN1_ERROR_TYPE_ANY;
break;
}
}
}
p2 = p2->right;
} /* end while */
if (!p2)
{
retCode = ASN1_ERROR_TYPE_ANY;
break;
}
}
break;
default:
break;
}
if (p->down)
{
p = p->down;
}
else if (p == *element)
{
p = NULL;
break;
}
else if (p->right)
p = p->right;
else
{
while (1)
{
p = _asn1_find_up (p);
if (p == *element)
{
p = NULL;
break;
}
if (p->right)
{
p = p->right;
break;
}
}
}
}
return retCode;
}
|
|||||
| ↓ | asn1_read_value | 47 | 83 | 161 | lib/element.c |
asn1_retCode
asn1_read_value (ASN1_TYPE root, const char *name, void *ivalue, int *len)
{
node_asn *node, *p, *p2;
int len2, len3;
int value_size = *len;
unsigned char *value = ivalue;
node = asn1_find_node (root, name);
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
if ((type_field (node->type) != TYPE_NULL) &&
(type_field (node->type) != TYPE_CHOICE) &&
!(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
(node->value == NULL))
return ASN1_VALUE_NOT_FOUND;
switch (type_field (node->type))
{
case TYPE_NULL:
PUT_STR_VALUE (value, value_size, "NULL");
break;
case TYPE_BOOLEAN:
if ((node->type & CONST_DEFAULT) && (node->value == NULL))
{
p = node->down;
while (type_field (p->type) != TYPE_DEFAULT)
p = p->right;
if (p->type & CONST_TRUE)
{
PUT_STR_VALUE (value, value_size, "TRUE");
}
else
{
PUT_STR_VALUE (value, value_size, "FALSE");
}
}
else if (node->value[0] == 'T')
{
PUT_STR_VALUE (value, value_size, "TRUE");
}
else
{
PUT_STR_VALUE (value, value_size, "FALSE");
}
break;
case TYPE_INTEGER:
case TYPE_ENUMERATED:
if ((node->type & CONST_DEFAULT) && (node->value == NULL))
{
p = node->down;
while (type_field (p->type) != TYPE_DEFAULT)
p = p->right;
if ((isdigit (p->value[0])) || (p->value[0] == '-')
|| (p->value[0] == '+'))
{
if (_asn1_convert_integer
(p->value, value, value_size, len) != ASN1_SUCCESS)
return ASN1_MEM_ERROR;
}
else
{ /* is an identifier like v1 */
p2 = node->down;
while (p2)
{
if (type_field (p2->type) == TYPE_CONSTANT)
{
if ((p2->name) && (!strcmp (p2->name, p->value)))
{
if (_asn1_convert_integer
(p2->value, value, value_size,
len) != ASN1_SUCCESS)
return ASN1_MEM_ERROR;
break;
}
}
p2 = p2->right;
}
}
}
else
{
len2 = -1;
if (asn1_get_octet_der
(node->value, node->value_len, &len2, value, value_size,
len) != ASN1_SUCCESS)
return ASN1_MEM_ERROR;
}
break;
case TYPE_OBJECT_ID:
if (node->type & CONST_ASSIGN)
{
value[0] = 0;
p = node->down;
while (p)
{
if (type_field (p->type) == TYPE_CONSTANT)
{
ADD_STR_VALUE (value, value_size, p->value);
if (p->right)
{
ADD_STR_VALUE (value, value_size, ".");
}
}
p = p->right;
}
*len = strlen (value) + 1;
}
else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
{
p = node->down;
while (type_field (p->type) != TYPE_DEFAULT)
p = p->right;
PUT_STR_VALUE (value, value_size, p->value);
}
else
{
PUT_STR_VALUE (value, value_size, node->value);
}
break;
case TYPE_TIME:
PUT_STR_VALUE (value, value_size, node->value);
break;
case TYPE_OCTET_STRING:
len2 = -1;
if (asn1_get_octet_der
(node->value, node->value_len, &len2, value, value_size,
len) != ASN1_SUCCESS)
return ASN1_MEM_ERROR;
break;
case TYPE_GENERALSTRING:
len2 = -1;
if (asn1_get_octet_der
(node->value, node->value_len, &len2, value, value_size,
len) != ASN1_SUCCESS)
return ASN1_MEM_ERROR;
break;
case TYPE_BIT_STRING:
len2 = -1;
if (asn1_get_bit_der
(node->value, node->value_len, &len2, value, value_size,
len) != ASN1_SUCCESS)
return ASN1_MEM_ERROR;
break;
case TYPE_CHOICE:
PUT_STR_VALUE (value, value_size, node->down->name);
break;
case TYPE_ANY:
len3 = -1;
len2 = asn1_get_length_der (node->value, node->value_len, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
PUT_VALUE (value, value_size, node->value + len3, len2);
break;
default:
return ASN1_ELEMENT_NOT_FOUND;
break;
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_check_identifier | 26 | 50 | 91 | lib/parser_aux.c |
asn1_retCode
_asn1_check_identifier (ASN1_TYPE node)
{
node_asn *p, *p2;
char name2[ASN1_MAX_NAME_SIZE * 2 + 2];
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
p = node;
while (p)
{
if (type_field (p->type) == TYPE_IDENTIFIER)
{
_asn1_str_cpy (name2, sizeof (name2), node->name);
_asn1_str_cat (name2, sizeof (name2), ".");
_asn1_str_cat (name2, sizeof (name2), p->value);
p2 = asn1_find_node (node, name2);
if (p2 == NULL)
{
strcpy (_asn1_identifierMissing, p->value);
return ASN1_IDENTIFIER_NOT_FOUND;
}
}
else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
(p->type & CONST_DEFAULT))
{
p2 = p->down;
if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
{
_asn1_str_cpy (name2, sizeof (name2), node->name);
_asn1_str_cat (name2, sizeof (name2), ".");
_asn1_str_cat (name2, sizeof (name2), p2->value);
strcpy (_asn1_identifierMissing, p2->value);
p2 = asn1_find_node (node, name2);
if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
!(p2->type & CONST_ASSIGN))
return ASN1_IDENTIFIER_NOT_FOUND;
else
_asn1_identifierMissing[0] = 0;
}
}
else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
(p->type & CONST_ASSIGN))
{
p2 = p->down;
if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
{
if (p2->value && !isdigit (p2->value[0]))
{
_asn1_str_cpy (name2, sizeof (name2), node->name);
_asn1_str_cat (name2, sizeof (name2), ".");
_asn1_str_cat (name2, sizeof (name2), p2->value);
strcpy (_asn1_identifierMissing, p2->value);
p2 = asn1_find_node (node, name2);
if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
!(p2->type & CONST_ASSIGN))
return ASN1_IDENTIFIER_NOT_FOUND;
else
_asn1_identifierMissing[0] = 0;
}
}
}
if (p->down)
{
p = p->down;
}
else if (p->right)
p = p->right;
else
{
while (1)
{
p = _asn1_find_up (p);
if (p == node)
{
p = NULL;
break;
}
if (p->right)
{
p = p->right;
break;
}
}
}
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_expand_identifier | 25 | 68 | 107 | lib/structure.c |
asn1_retCode
_asn1_expand_identifier (node_asn ** node, node_asn * root)
{
node_asn *p, *p2, *p3;
char name2[ASN1_MAX_NAME_SIZE + 2];
int move;
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
p = *node;
move = DOWN;
while (!((p == *node) && (move == UP)))
{
if (move != UP)
{
if (type_field (p->type) == TYPE_IDENTIFIER)
{
_asn1_str_cpy (name2, sizeof (name2), root->name);
_asn1_str_cat (name2, sizeof (name2), ".");
_asn1_str_cat (name2, sizeof (name2), p->value);
p2 = _asn1_copy_structure2 (root, name2);
if (p2 == NULL)
{
return ASN1_IDENTIFIER_NOT_FOUND;
}
_asn1_set_name (p2, p->name);
p2->right = p->right;
p2->left = p->left;
if (p->right)
p->right->left = p2;
p3 = p->down;
if (p3)
{
while (p3->right)
p3 = p3->right;
_asn1_set_right (p3, p2->down);
_asn1_set_down (p2, p->down);
}
p3 = _asn1_find_left (p);
if (p3)
_asn1_set_right (p3, p2);
else
{
p3 = _asn1_find_up (p);
if (p3)
_asn1_set_down (p3, p2);
else
{
p2->left = NULL;
}
}
if (p->type & CONST_SIZE)
p2->type |= CONST_SIZE;
if (p->type & CONST_TAG)
p2->type |= CONST_TAG;
if (p->type & CONST_OPTION)
p2->type |= CONST_OPTION;
if (p->type & CONST_DEFAULT)
p2->type |= CONST_DEFAULT;
if (p->type & CONST_SET)
p2->type |= CONST_SET;
if (p->type & CONST_NOT_USED)
p2->type |= CONST_NOT_USED;
if (p == *node)
*node = p2;
_asn1_remove_node (p);
p = p2;
move = DOWN;
continue;
}
move = DOWN;
}
else
move = RIGHT;
if (move == DOWN)
{
if (p->down)
p = p->down;
else
move = RIGHT;
}
if (p == *node)
{
move = UP;
continue;
}
if (move == RIGHT)
{
if (p->right)
p = p->right;
else
move = UP;
}
if (move == UP)
p = _asn1_find_up (p);
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_ordering_set_of | 23 | 72 | 124 | lib/coding.c |
void
_asn1_ordering_set_of (unsigned char *der, int der_len, node_asn * node)
{
struct vet
{
int end;
struct vet *next, *prev;
};
int counter, len, len2, change;
struct vet *first, *last, *p_vet, *p2_vet;
node_asn *p;
unsigned char *temp, class;
unsigned long k, max;
counter = 0;
if (type_field (node->type) != TYPE_SET_OF)
return;
p = node->down;
while ((type_field (p->type) == TYPE_TAG)
|| (type_field (p->type) == TYPE_SIZE))
p = p->right;
p = p->right;
if ((p == NULL) || (p->right == NULL))
return;
first = last = NULL;
while (p)
{
p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
if (p_vet == NULL)
return;
p_vet->next = NULL;
p_vet->prev = last;
if (first == NULL)
first = p_vet;
else
last->next = p_vet;
last = p_vet;
/* extraction of tag and length */
if (der_len - counter > 0)
{
if (asn1_get_tag_der
(der + counter, der_len - counter, &class, &len,
NULL) != ASN1_SUCCESS)
return;
counter += len;
len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
if (len2 < 0)
return;
counter += len + len2;
}
p_vet->end = counter;
p = p->right;
}
p_vet = first;
while (p_vet)
{
p2_vet = p_vet->next;
counter = 0;
while (p2_vet)
{
if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
max = p_vet->end - counter;
else
max = p2_vet->end - p_vet->end;
change = -1;
for (k = 0; k < max; 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 = (unsigned char *) _asn1_malloc (p_vet->end - counter);
if (temp == NULL)
return;
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);
_asn1_free (temp);
p_vet->end = counter + (p2_vet->end - p_vet->end);
}
counter = p_vet->end;
p2_vet = p2_vet->next;
p_vet = p_vet->next;
}
if (p_vet != first)
p_vet->prev->next = NULL;
else
first = NULL;
_asn1_free (p_vet);
p_vet = first;
}
}
|
|||||
| ↓ | asn1_expand_octet_string | 22 | 65 | 123 | lib/decoding.c |
asn1_retCode
asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element,
const char *octetName, const char *objectName)
{
char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
asn1_retCode retCode = ASN1_SUCCESS, result;
int len, len2, len3;
ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY;
ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY;
char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
return ASN1_ELEMENT_NOT_FOUND;
octetNode = asn1_find_node (*element, octetName);
if (octetNode == ASN1_TYPE_EMPTY)
return ASN1_ELEMENT_NOT_FOUND;
if (type_field (octetNode->type) != TYPE_OCTET_STRING)
return ASN1_ELEMENT_NOT_FOUND;
if (octetNode->value == NULL)
return ASN1_VALUE_NOT_FOUND;
objectNode = asn1_find_node (*element, objectName);
if (objectNode == ASN1_TYPE_EMPTY)
return ASN1_ELEMENT_NOT_FOUND;
if (type_field (objectNode->type) != TYPE_OBJECT_ID)
return ASN1_ELEMENT_NOT_FOUND;
if (objectNode->value == NULL)
return ASN1_VALUE_NOT_FOUND;
/* search the OBJECT_ID into definitions */
p2 = definitions->down;
while (p2)
{
if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
(p2->type & CONST_ASSIGN))
{
strcpy (name, definitions->name);
strcat (name, ".");
strcat (name, p2->name);
len = sizeof (value);
result = asn1_read_value (definitions, name, value, &len);
if ((result == ASN1_SUCCESS)
&& (!strcmp (objectNode->value, value)))
{
p2 = p2->right; /* pointer to the structure to
use for expansion */
while ((p2) && (p2->type & CONST_ASSIGN))
p2 = p2->right;
if (p2)
{
strcpy (name, definitions->name);
strcat (name, ".");
strcat (name, p2->name);
result = asn1_create_element (definitions, name, &aux);
if (result == ASN1_SUCCESS)
{
_asn1_set_name (aux, octetNode->name);
len2 =
asn1_get_length_der (octetNode->value,
octetNode->value_len, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
result =
asn1_der_decoding (&aux, octetNode->value + len3,
len2, errorDescription);
if (result == ASN1_SUCCESS)
{
_asn1_set_right (aux, octetNode->right);
_asn1_set_right (octetNode, aux);
result = asn1_delete_structure (&octetNode);
if (result == ASN1_SUCCESS)
{
aux = ASN1_TYPE_EMPTY;
break;
}
else
{ /* error with asn1_delete_structure */
asn1_delete_structure (&aux);
retCode = result;
break;
}
}
else
{ /* error with asn1_der_decoding */
retCode = result;
break;
}
}
else
{ /* error with asn1_create_element */
retCode = result;
break;
}
}
else
{ /* error with the pointer to the structure to exapand */
retCode = ASN1_VALUE_NOT_VALID;
break;
}
}
}
p2 = p2->right;
}
if (!p2)
retCode = ASN1_VALUE_NOT_VALID;
return retCode;
}
|
|||||
| ↓ | _asn1_get_octet_string | 21 | 62 | 106 | lib/decoding.c |
asn1_retCode
_asn1_get_octet_string (const unsigned char *der, node_asn * node, int *len)
{
int len2, len3, counter, counter2, counter_end, tot_len, indefinite;
unsigned char *temp, *temp2;
counter = 0;
if (*(der - 1) & ASN1_CLASS_STRUCTURED)
{
tot_len = 0;
indefinite = asn1_get_length_der (der, *len, &len3);
if (indefinite < -1)
return ASN1_DER_ERROR;
counter += len3;
if (indefinite >= 0)
indefinite += len3;
while (1)
{
if (counter > (*len))
return ASN1_DER_ERROR;
if (indefinite == -1)
{
if ((der[counter] == 0) && (der[counter + 1] == 0))
{
counter += 2;
break;
}
}
else if (counter >= indefinite)
break;
if (der[counter] != ASN1_TAG_OCTET_STRING)
return ASN1_DER_ERROR;
counter++;
len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
if (len2 <= 0)
return ASN1_DER_ERROR;
counter += len3 + len2;
tot_len += len2;
}
/* copy */
if (node)
{
asn1_length_der (tot_len, NULL, &len2);
temp = _asn1_malloc (len2 + tot_len);
if (temp == NULL)
{
return ASN1_MEM_ALLOC_ERROR;
}
asn1_length_der (tot_len, temp, &len2);
tot_len += len2;
temp2 = temp + len2;
len2 = asn1_get_length_der (der, *len, &len3);
if (len2 < -1)
return ASN1_DER_ERROR;
counter2 = len3 + 1;
if (indefinite == -1)
counter_end = counter - 2;
else
counter_end = counter;
while (counter2 < counter_end)
{
len2 =
asn1_get_length_der (der + counter2, *len - counter, &len3);
if (len2 < -1)
return ASN1_DER_ERROR;
/* FIXME: to be checked. Is this ok? Has the
* size been checked before?
*/
memcpy (temp2, der + counter2 + len3, len2);
temp2 += len2;
counter2 += len2 + len3 + 1;
}
_asn1_set_value (node, temp, tot_len);
_asn1_free (temp);
}
}
else
{ /* NOT STRUCTURED */
len2 = asn1_get_length_der (der, *len, &len3);
if (len2 < 0)
return ASN1_DER_ERROR;
if (len3 + len2 > *len)
return ASN1_DER_ERROR;
if (node)
_asn1_set_value (node, der, len3 + len2);
counter = len3 + len2;
}
*len = counter;
return ASN1_SUCCESS;
}
|
|||||
| ↓ | asn1_array2tree | 21 | 53 | 97 | lib/structure.c |
asn1_retCode
asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions,
char *errorDescription)
{
node_asn *p, *p_last = NULL;
unsigned long k;
int move;
asn1_retCode result;
if (*definitions != ASN1_TYPE_EMPTY)
return ASN1_ELEMENT_NOT_EMPTY;
move = UP;
k = 0;
while (array[k].value || array[k].type || array[k].name)
{
p = _asn1_add_node (array[k].type & (~CONST_DOWN));
if (array[k].name)
_asn1_set_name (p, array[k].name);
if (array[k].value)
_asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
if (*definitions == NULL)
*definitions = p;
if (move == DOWN)
_asn1_set_down (p_last, p);
else if (move == RIGHT)
_asn1_set_right (p_last, p);
p_last = p;
if (array[k].type & CONST_DOWN)
move = DOWN;
else if (array[k].type & CONST_RIGHT)
move = RIGHT;
else
{
while (1)
{
if (p_last == *definitions)
break;
p_last = _asn1_find_up (p_last);
if (p_last == NULL)
break;
if (p_last->type & CONST_RIGHT)
{
p_last->type &= ~CONST_RIGHT;
move = RIGHT;
break;
}
} /* while */
}
k++;
} /* while */
if (p_last == *definitions)
{
result = _asn1_check_identifier (*definitions);
if (result == ASN1_SUCCESS)
{
_asn1_change_integer_value (*definitions);
_asn1_expand_object_id (*definitions);
}
}
else
{
result = ASN1_ARRAY_ERROR;
}
if (errorDescription != NULL)
{
if (result == ASN1_IDENTIFIER_NOT_FOUND)
{
Estrcpy (errorDescription, ":: identifier '");
Estrcat (errorDescription, _asn1_identifierMissing);
Estrcat (errorDescription, "' not found");
}
else
errorDescription[0] = 0;
}
if (result != ASN1_SUCCESS)
{
_asn1_delete_list_and_nodes ();
*definitions = ASN1_TYPE_EMPTY;
}
else
_asn1_delete_list ();
return result;
}
|
|||||
| ↓ | _asn1_insert_tag_der | 35 | 75 | 151 | lib/coding.c |
asn1_retCode
_asn1_insert_tag_der (node_asn * node, unsigned char *der, int *counter,
int *max_len)
{
node_asn *p;
int tag_len, is_tag_implicit;
unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
unsigned long tag_implicit = 0;
char tag_der[MAX_TAG_LEN];
is_tag_implicit = 0;
if (node->type & CONST_TAG)
{
p = node->down;
while (p)
{
if (type_field (p->type) == TYPE_TAG)
{
if (p->type & CONST_APPLICATION)
class = ASN1_CLASS_APPLICATION;
else if (p->type & CONST_UNIVERSAL)
class = ASN1_CLASS_UNIVERSAL;
else if (p->type & CONST_PRIVATE)
class = ASN1_CLASS_PRIVATE;
else
class = ASN1_CLASS_CONTEXT_SPECIFIC;
if (p->type & CONST_EXPLICIT)
{
if (is_tag_implicit)
_asn1_tag_der (class_implicit, tag_implicit, tag_der,
&tag_len);
else
_asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
strtoul (p->value, NULL, 10), tag_der,
&tag_len);
*max_len -= tag_len;
if (*max_len >= 0)
memcpy (der + *counter, tag_der, tag_len);
*counter += tag_len;
_asn1_ltostr (*counter, temp);
_asn1_set_name (p, temp);
is_tag_implicit = 0;
}
else
{ /* CONST_IMPLICIT */
if (!is_tag_implicit)
{
if ((type_field (node->type) == TYPE_SEQUENCE) ||
(type_field (node->type) == TYPE_SEQUENCE_OF) ||
(type_field (node->type) == TYPE_SET) ||
(type_field (node->type) == TYPE_SET_OF))
class |= ASN1_CLASS_STRUCTURED;
class_implicit = class;
tag_implicit = strtoul (p->value, NULL, 10);
is_tag_implicit = 1;
}
}
}
p = p->right;
}
}
if (is_tag_implicit)
{
_asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
}
else
{
switch (type_field (node->type))
{
case TYPE_NULL:
_asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der,
&tag_len);
break;
case TYPE_BOOLEAN:
_asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der,
&tag_len);
break;
case TYPE_INTEGER:
_asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der,
&tag_len);
break;
case TYPE_ENUMERATED:
_asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der,
&tag_len);
break;
case TYPE_OBJECT_ID:
_asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der,
&tag_len);
break;
case TYPE_TIME:
if (node->type & CONST_UTC)
{
_asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
&tag_len);
}
else
_asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
tag_der, &tag_len);
break;
case TYPE_OCTET_STRING:
_asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der,
&tag_len);
break;
case TYPE_GENERALSTRING:
_asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
tag_der, &tag_len);
break;
case TYPE_BIT_STRING:
_asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der,
&tag_len);
break;
case TYPE_SEQUENCE:
case TYPE_SEQUENCE_OF:
_asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
ASN1_TAG_SEQUENCE, tag_der, &tag_len);
break;
case TYPE_SET:
case TYPE_SET_OF:
_asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
ASN1_TAG_SET, tag_der, &tag_len);
break;
case TYPE_TAG:
tag_len = 0;
break;
case TYPE_CHOICE:
tag_len = 0;
break;
case TYPE_ANY:
tag_len = 0;
break;
default:
return ASN1_GENERIC_ERROR;
}
}
*max_len -= tag_len;
if (*max_len >= 0)
memcpy (der + *counter, tag_der, tag_len);
*counter += tag_len;
if (*max_len < 0)
return ASN1_MEM_ERROR;
return ASN1_SUCCESS;
}
|
|||||
| ↓ | asn1_find_node | 20 | 50 | 95 | lib/parser_aux.c |
ASN1_TYPE
asn1_find_node (ASN1_TYPE pointer, const char *name)
{
node_asn *p;
char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
const char *n_start;
if (pointer == NULL)
return NULL;
if (name == NULL)
return NULL;
p = pointer;
n_start = name;
if (p->name != NULL)
{ /* has *pointer got a name ? */
n_end = strchr (n_start, '.'); /* search the first dot */
if (n_end)
{
memcpy (n, n_start, n_end - n_start);
n[n_end - n_start] = 0;
n_start = n_end;
n_start++;
}
else
{
_asn1_str_cpy (n, sizeof (n), n_start);
n_start = NULL;
}
while (p)
{
if ((p->name) && (!strcmp (p->name, n)))
break;
else
p = p->right;
} /* while */
if (p == NULL)
return NULL;
}
else
{ /* *pointer doesn't have a name */
if (n_start[0] == 0)
return p;
}
while (n_start)
{ /* Has the end of NAME been reached? */
n_end = strchr (n_start, '.'); /* search the next dot */
if (n_end)
{
memcpy (n, n_start, n_end - n_start);
n[n_end - n_start] = 0;
n_start = n_end;
n_start++;
}
else
{
_asn1_str_cpy (n, sizeof (n), n_start);
n_start = NULL;
}
if (p->down == NULL)
return NULL;
p = p->down;
/* The identifier "?LAST" indicates the last element
in the right chain. */
if (!strcmp (n, "?LAST"))
{
if (p == NULL)
return NULL;
while (p->right)
p = p->right;
}
else
{ /* no "?LAST" */
while (p)
{
if ((p->name) && (!strcmp (p->name, n)))
break;
else
p = p->right;
}
if (p == NULL)
return NULL;
}
} /* while */
return p;
}
|
|||||
| ↓ | _asn1_type_choice_config | 20 | 47 | 83 | lib/structure.c |
asn1_retCode
_asn1_type_choice_config (node_asn * node)
{
node_asn *p, *p2, *p3, *p4;
int move, tlen;
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
p = node;
move = DOWN;
while (!((p == node) && (move == UP)))
{
if (move != UP)
{
if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG))
{
p2 = p->down;
while (p2)
{
if (type_field (p2->type) != TYPE_TAG)
{
p2->type |= CONST_TAG;
p3 = _asn1_find_left (p2);
while (p3)
{
if (type_field (p3->type) == TYPE_TAG)
{
p4 = _asn1_add_node_only (p3->type);
tlen = strlen (p3->value);
if (tlen > 0)
_asn1_set_value (p4, p3->value, tlen + 1);
_asn1_set_right (p4, p2->down);
_asn1_set_down (p2, p4);
}
p3 = _asn1_find_left (p3);
}
}
p2 = p2->right;
}
p->type &= ~(CONST_TAG);
p2 = p->down;
while (p2)
{
p3 = p2->right;
if (type_field (p2->type) == TYPE_TAG)
asn1_delete_structure (&p2);
p2 = p3;
}
}
move = DOWN;
}
else
move = RIGHT;
if (move == DOWN)
{
if (p->down)
p = p->down;
else
move = RIGHT;
}
if (p == node)
{
move = UP;
continue;
}
if (move == RIGHT)
{
if (p->right)
p = p->right;
else
move = UP;
}
if (move == UP)
p = _asn1_find_up (p);
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_ordering_set | 16 | 59 | 104 | lib/coding.c |
void
_asn1_ordering_set (unsigned char *der, int der_len, node_asn * node)
{
struct vet
{
int end;
unsigned long value;
struct vet *next, *prev;
};
int counter, len, len2;
struct vet *first, *last, *p_vet, *p2_vet;
node_asn *p;
unsigned char class, *temp;
unsigned long tag;
counter = 0;
if (type_field (node->type) != TYPE_SET)
return;
p = node->down;
while ((type_field (p->type) == TYPE_TAG)
|| (type_field (p->type) == TYPE_SIZE))
p = p->right;
if ((p == NULL) || (p->right == NULL))
return;
first = last = NULL;
while (p)
{
p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
if (p_vet == NULL)
return;
p_vet->next = NULL;
p_vet->prev = last;
if (first == NULL)
first = p_vet;
else
last->next = p_vet;
last = p_vet;
/* tag value calculation */
if (asn1_get_tag_der
(der + counter, der_len - counter, &class, &len2,
&tag) != ASN1_SUCCESS)
return;
p_vet->value = (class << 24) | tag;
counter += len2;
/* extraction and length */
len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
if (len2 < 0)
return;
counter += len + len2;
p_vet->end = counter;
p = p->right;
}
p_vet = first;
while (p_vet)
{
p2_vet = p_vet->next;
counter = 0;
while (p2_vet)
{
if (p_vet->value > p2_vet->value)
{
/* change position */
temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
if (temp == NULL)
return;
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);
_asn1_free (temp);
tag = p_vet->value;
p_vet->value = p2_vet->value;
p2_vet->value = tag;
p_vet->end = counter + (p2_vet->end - p_vet->end);
}
counter = p_vet->end;
p2_vet = p2_vet->next;
p_vet = p_vet->next;
}
if (p_vet != first)
p_vet->prev->next = NULL;
else
first = NULL;
_asn1_free (p_vet);
p_vet = first;
}
}
|
|||||
| ↓ | _asn1_convert_integer | 15 | 35 | 52 | lib/element.c |
asn1_retCode
_asn1_convert_integer (const char *value, unsigned char *value_out,
int value_out_size, int *len)
{
char negative;
unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
long valtmp;
int k, k2;
valtmp = strtol (value, NULL, 10);
for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
{
val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
}
if (val[0] & 0x80)
negative = 1;
else
negative = 0;
for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
{
if (negative && (val[k] != 0xFF))
break;
else if (!negative && val[k])
break;
}
if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
k--;
*len = SIZEOF_UNSIGNED_LONG_INT - k;
if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
/* VALUE_OUT is too short to contain the value conversion */
return ASN1_MEM_ERROR;
for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
value_out[k2 - k] = val[k2];
#ifdef LIBTASN1_DEBUG_INTEGER
_libtasn1_log ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
_libtasn1_log (", vOut[%d]=%d", k, value_out[k]);
_libtasn1_log ("\n");
#endif
return ASN1_SUCCESS;
}
|
|||||
| ↓ | asn1_read_tag | 29 | 51 | 101 | lib/element.c |
asn1_retCode
asn1_read_tag (node_asn * root, const char *name, int *tagValue,
int *classValue)
{
node_asn *node, *p, *pTag;
node = asn1_find_node (root, name);
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
p = node->down;
/* pTag will points to the IMPLICIT TAG */
pTag = NULL;
if (node->type & CONST_TAG)
{
while (p)
{
if (type_field (p->type) == TYPE_TAG)
{
if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
pTag = p;
else if (p->type & CONST_EXPLICIT)
pTag = NULL;
}
p = p->right;
}
}
if (pTag)
{
*tagValue = strtoul (pTag->value, NULL, 10);
if (pTag->type & CONST_APPLICATION)
*classValue = ASN1_CLASS_APPLICATION;
else if (pTag->type & CONST_UNIVERSAL)
*classValue = ASN1_CLASS_UNIVERSAL;
else if (pTag->type & CONST_PRIVATE)
*classValue = ASN1_CLASS_PRIVATE;
else
*classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
}
else
{
*classValue = ASN1_CLASS_UNIVERSAL;
switch (type_field (node->type))
{
case TYPE_NULL:
*tagValue = ASN1_TAG_NULL;
break;
case TYPE_BOOLEAN:
*tagValue = ASN1_TAG_BOOLEAN;
break;
case TYPE_INTEGER:
*tagValue = ASN1_TAG_INTEGER;
break;
case TYPE_ENUMERATED:
*tagValue = ASN1_TAG_ENUMERATED;
break;
case TYPE_OBJECT_ID:
*tagValue = ASN1_TAG_OBJECT_ID;
break;
case TYPE_TIME:
if (node->type & CONST_UTC)
{
*tagValue = ASN1_TAG_UTCTime;
}
else
*tagValue = ASN1_TAG_GENERALIZEDTime;
break;
case TYPE_OCTET_STRING:
*tagValue = ASN1_TAG_OCTET_STRING;
break;
case TYPE_GENERALSTRING:
*tagValue = ASN1_TAG_GENERALSTRING;
break;
case TYPE_BIT_STRING:
*tagValue = ASN1_TAG_BIT_STRING;
break;
case TYPE_SEQUENCE:
case TYPE_SEQUENCE_OF:
*tagValue = ASN1_TAG_SEQUENCE;
break;
case TYPE_SET:
case TYPE_SET_OF:
*tagValue = ASN1_TAG_SET;
break;
case TYPE_TAG:
case TYPE_CHOICE:
case TYPE_ANY:
break;
default:
break;
}
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_objectid_der | 14 | 44 | 69 | lib/coding.c |
asn1_retCode
_asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
{
int len_len, counter, k, first, max_len;
char *temp, *n_end, *n_start;
unsigned char bit7;
unsigned long val, val1 = 0;
max_len = *der_len;
temp = (char *) _asn1_malloc (strlen (str) + 2);
if (temp == NULL)
return ASN1_MEM_ALLOC_ERROR;
strcpy (temp, str);
strcat (temp, ".");
counter = 0;
n_start = temp;
while ((n_end = strchr (n_start, '.')))
{
*n_end = 0;
val = strtoul (n_start, NULL, 10);
counter++;
if (counter == 1)
val1 = val;
else if (counter == 2)
{
if (max_len > 0)
der[0] = 40 * val1 + val;
*der_len = 1;
}
else
{
first = 0;
for (k = 4; k >= 0; k--)
{
bit7 = (val >> (k * 7)) & 0x7F;
if (bit7 || first || !k)
{
if (k)
bit7 |= 0x80;
if (max_len > (*der_len))
der[*der_len] = bit7;
(*der_len)++;
first = 1;
}
}
}
n_start = n_end + 1;
}
asn1_length_der (*der_len, NULL, &len_len);
if (max_len >= (*der_len + len_len))
{
memmove (der + len_len, der, *der_len);
asn1_length_der (*der_len, der, &len_len);
}
*der_len += len_len;
_asn1_free (temp);
if (max_len < (*der_len))
return ASN1_MEM_ERROR;
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_type_set_config | 14 | 30 | 58 | lib/parser_aux.c |
asn1_retCode
_asn1_type_set_config (ASN1_TYPE node)
{
node_asn *p, *p2;
int move;
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
p = node;
move = DOWN;
while (!((p == node) && (move == UP)))
{
if (move != UP)
{
if (type_field (p->type) == TYPE_SET)
{
p2 = p->down;
while (p2)
{
if (type_field (p2->type) != TYPE_TAG)
p2->type |= CONST_SET | CONST_NOT_USED;
p2 = p2->right;
}
}
move = DOWN;
}
else
move = RIGHT;
if (move == DOWN)
{
if (p->down)
p = p->down;
else
move = RIGHT;
}
if (p == node)
{
move = UP;
continue;
}
if (move == RIGHT)
{
if (p->right)
p = p->right;
else
move = UP;
}
if (move == UP)
p = _asn1_find_up (p);
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | asn1_check_version | 14 | 15 | 30 | lib/parser_aux.c |
const char *
asn1_check_version (const char *req_version)
{
const char *ver = LIBTASN1_VERSION;
int my_major, my_minor, my_micro;
int rq_major, rq_minor, rq_micro;
const char *my_plvl, *rq_plvl;
if (!req_version)
return ver;
my_plvl = parse_version_string (ver, &my_major, &my_minor, &my_micro);
if (!my_plvl)
return NULL; /* very strange our own version is bogus */
rq_plvl = parse_version_string (req_version, &rq_major, &rq_minor,
&rq_micro);
if (!rq_plvl)
return NULL; /* req version string is invalid */
if (my_major > rq_major
|| (my_major == rq_major && my_minor > rq_minor)
|| (my_major == rq_major && my_minor == rq_minor
&& my_micro > rq_micro)
|| (my_major == rq_major && my_minor == rq_minor
&& my_micro == rq_micro && strcmp (my_plvl, rq_plvl) >= 0))
{
return ver;
}
return NULL;
}
|
|||||
| ↓ | _asn1_delete_not_used | 13 | 30 | 58 | lib/decoding.c |
int
_asn1_delete_not_used (node_asn * node)
{
node_asn *p, *p2;
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
p = node;
while (p)
{
if (p->type & CONST_NOT_USED)
{
p2 = NULL;
if (p != node)
{
p2 = _asn1_find_left (p);
if (!p2)
p2 = _asn1_find_up (p);
}
asn1_delete_structure (&p);
p = p2;
}
if (!p)
break; /* reach node */
if (p->down)
{
p = p->down;
}
else
{
if (p == node)
p = NULL;
else if (p->right)
p = p->right;
else
{
while (1)
{
p = _asn1_find_up (p);
if (p == node)
{
p = NULL;
break;
}
if (p->right)
{
p = p->right;
break;
}
}
}
}
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_set_default_tag | 13 | 22 | 47 | lib/parser_aux.c |
asn1_retCode
_asn1_set_default_tag (ASN1_TYPE node)
{
node_asn *p;
if ((node == NULL) || (type_field (node->type) != TYPE_DEFINITIONS))
return ASN1_ELEMENT_NOT_FOUND;
p = node;
while (p)
{
if ((type_field (p->type) == TYPE_TAG) &&
!(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
{
if (node->type & CONST_EXPLICIT)
p->type |= CONST_EXPLICIT;
else
p->type |= CONST_IMPLICIT;
}
if (p->down)
{
p = p->down;
}
else if (p->right)
p = p->right;
else
{
while (1)
{
p = _asn1_find_up (p);
if (p == node)
{
p = NULL;
break;
}
if (p->right)
{
p = p->right;
break;
}
}
}
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_create_static_structure | 12 | 41 | 78 | lib/structure.c |
asn1_retCode
_asn1_create_static_structure (ASN1_TYPE pointer, char *output_file_name,
char *vector_name)
{
FILE *file;
node_asn *p;
unsigned long t;
file = fopen (output_file_name, "w");
if (file == NULL)
return ASN1_FILE_NOT_FOUND;
fprintf (file, "#if HAVE_CONFIG_H\n");
fprintf (file, "# include \"config.h\"\n");
fprintf (file, "#endif\n\n");
fprintf (file, "#include
|
|||||
| ↓ | _asn1_copy_structure3 | 12 | 37 | 67 | lib/structure.c |
node_asn *
_asn1_copy_structure3 (node_asn * source_node)
{
node_asn *dest_node, *p_s, *p_d, *p_d_prev;
int move;
if (source_node == NULL)
return NULL;
dest_node = _asn1_add_node_only (source_node->type);
p_s = source_node;
p_d = dest_node;
move = DOWN;
do
{
if (move != UP)
{
if (p_s->name)
_asn1_set_name (p_d, p_s->name);
if (p_s->value)
_asn1_set_value (p_d, p_s->value, p_s->value_len);
move = DOWN;
}
else
move = RIGHT;
if (move == DOWN)
{
if (p_s->down)
{
p_s = p_s->down;
p_d_prev = p_d;
p_d = _asn1_add_node_only (p_s->type);
_asn1_set_down (p_d_prev, p_d);
}
else
move = RIGHT;
}
if (p_s == source_node)
break;
if (move == RIGHT)
{
if (p_s->right)
{
p_s = p_s->right;
p_d_prev = p_d;
p_d = _asn1_add_node_only (p_s->type);
_asn1_set_right (p_d_prev, p_d);
}
else
move = UP;
}
if (move == UP)
{
p_s = _asn1_find_up (p_s);
p_d = _asn1_find_up (p_d);
}
}
while (p_s != source_node);
return dest_node;
}
|
|||||
| ↓ | _asn1_change_integer_value | 12 | 28 | 56 | lib/parser_aux.c |
asn1_retCode
_asn1_change_integer_value (ASN1_TYPE node)
{
node_asn *p;
unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
int len;
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
p = node;
while (p)
{
if ((type_field (p->type) == TYPE_INTEGER) && (p->type & CONST_ASSIGN))
{
if (p->value)
{
_asn1_convert_integer (p->value, val, sizeof (val), &len);
asn1_octet_der (val, len, val2, &len);
_asn1_set_value (p, val2, len);
}
}
if (p->down)
{
p = p->down;
}
else
{
if (p == node)
p = NULL;
else if (p->right)
p = p->right;
else
{
while (1)
{
p = _asn1_find_up (p);
if (p == node)
{
p = NULL;
break;
}
if (p->right)
{
p = p->right;
break;
}
}
}
}
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | asn1_get_tag_der | 11 | 24 | 44 | lib/decoding.c |
int
asn1_get_tag_der (const unsigned char *der, int der_len,
unsigned char *cls, int *len, unsigned long *tag)
{
int punt, ris;
if (der == NULL || der_len <= 0 || len == NULL)
return ASN1_DER_ERROR;
*cls = der[0] & 0xE0;
if ((der[0] & 0x1F) != 0x1F)
{
/* short form */
*len = 1;
ris = der[0] & 0x1F;
}
else
{
/* Long form */
punt = 1;
ris = 0;
while (punt <= der_len && der[punt] & 128)
{
int last = ris;
ris = ris * 128 + (der[punt++] & 0x7F);
if (ris < last)
/* wrapper around, and no bignums... */
return ASN1_DER_ERROR;
}
if (punt >= der_len)
return ASN1_DER_ERROR;
{
int last = ris;
ris = ris * 128 + (der[punt++] & 0x7F);
if (ris < last)
/* wrapper around, and no bignums... */
return ASN1_DER_ERROR;
}
*len = punt;
}
if (tag)
*tag = ris;
return ASN1_SUCCESS;
}
|
|||||
| _asn1_get_indefinite_length_string | 10 | 27 | 49 | lib/decoding.c | |
| _asn1_get_objectid_der | 10 | 27 | 40 | lib/decoding.c | |
| _asn1_complete_explicit_tag | 10 | 26 | 56 | lib/coding.c | |
| asn1_find_structure_from_oid | 9 | 23 | 43 | lib/structure.c | |
| asn1_delete_structure | 8 | 25 | 50 | lib/structure.c | |
| asn1_get_length_der | 7 | 20 | 43 | lib/decoding.c | |
| _asn1_append_sequence_set | 7 | 20 | 33 | lib/element.c | |
| asn1_length_der | 6 | 15 | 31 | lib/coding.c | |
| parse_version_string | 6 | 15 | 21 | lib/parser_aux.c | |
| _asn1_set_name | 6 | 13 | 25 | lib/parser_aux.c | |
| asn1_number_of_elements | 6 | 13 | 25 | lib/structure.c | |
| asn1_copy_node | 5 | 21 | 40 | lib/structure.c | |
| _asn1_set_value | 5 | 15 | 23 | lib/parser_aux.c | |
| asn1_delete_element | 5 | 14 | 25 | lib/structure.c | |
| parse_version_number | 5 | 11 | 15 | lib/parser_aux.c | |
| _asn1_get_time_der | 5 | 10 | 17 | lib/decoding.c | |
| _asn1_find_up | 4 | 7 | 15 | lib/parser_aux.c | |
| _asn1_remove_node | 4 | 7 | 12 | lib/parser_aux.c | |
| _asn1_find_left | 4 | 3 | 8 | lib/structure.c | |
| _asn1_ltostr | 4 | 22 | 32 | lib/parser_aux.c | |
| _asn1_tag_der | 4 | 14 | 29 | lib/coding.c | |
| _asn1_hierarchical_name | 4 | 12 | 25 | lib/element.c | |
| asn1_get_bit_der | 4 | 12 | 25 | lib/decoding.c | |
| _asn1_time_der | 4 | 11 | 19 | lib/coding.c | |
| asn1_get_octet_der | 4 | 11 | 26 | lib/decoding.c | |
| _asn1_str_cat | 3 | 7 | 19 | lib/gstr.c | |
| _asn1_get_last_right | 3 | 7 | 12 | lib/parser_aux.c | |
| _asn1_str_cpy | 3 | 6 | 18 | lib/gstr.c | |
| _asn1_set_down | 3 | 6 | 10 | lib/parser_aux.c | |
| _asn1_set_right | 3 | 6 | 10 | lib/parser_aux.c | |
| asn1_octet_der | 3 | 6 | 12 | lib/coding.c | |
| _asn1_add_node | 3 | 14 | 25 | lib/parser_aux.c | |
| asn1_bit_der | 3 | 13 | 20 | lib/coding.c | |
| _asn1_add_node_only | 2 | 6 | 13 | lib/structure.c | |
| _asn1_delete_list_and_nodes | 2 | 6 | 13 | lib/parser_aux.c | |
| _asn1_error_description_value_not_found | 2 | 5 | 14 | lib/coding.c | |
| _asn1_delete_list | 2 | 5 | 12 | lib/parser_aux.c | |
| _asn1_mod_type | 2 | 4 | 8 | lib/parser_aux.c | |
| _asn1_get_name | 2 | 3 | 7 | lib/parser_aux.c | |
| _asn1_get_down | 2 | 3 | 7 | lib/parser_aux.c | |
| _asn1_get_right | 2 | 3 | 7 | lib/parser_aux.c | |
| asn1_create_element | 2 | 10 | 21 | lib/structure.c | |
| _libtasn1_log | 1 | 1 | 5 | lib/errors.c | |
| libtasn1_perror | 1 | 3 | 11 | lib/errors.c | |
| _asn1_copy_structure2 | 1 | 3 | 10 | lib/structure.c | |
| _asn1_error_description_tag_error | 1 | 3 | 10 | lib/decoding.c | |
| libtasn1_strerror | 1 | 3 | 10 | lib/errors.c | |