Report generated at: Fri Jan 16 13:00:10 CET 2009
| Total number of functions | 100 |
| Number of low risk functions | 66 |
| Number of moderate risk functions | 17 |
| Number of high risk functions | 9 |
| Number of untestable functions | 8 |
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 | 154 | 399 | 738 | lib/decoding.c |
asn1_retCode
asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
const void *ider, int len, char *errorDescription)
{
ASN1_TYPE 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_set_value_octet (p, der+counter, len2+len3);
temp2 = NULL;
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_set_value_octet (p, der+counter, len2);
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 | 118 | 301 | 520 | lib/decoding.c |
asn1_retCode
asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
char *errorDescription)
{
ASN1_TYPE node, p, p2, p3;
char temp[128];
int counter, len2, len3, len4, move, ris, tlen;
unsigned char class;
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_set_value_octet (p, der+counter, len2+len3);
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_set_value_octet (p, der+counter, len2);
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 | 111 | 207 | 342 | lib/element.c |
asn1_retCode
asn1_write_value (ASN1_TYPE node_root, const char *name,
const void *ivalue, int len)
{
ASN1_TYPE 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_set_value_octet (node, value_temp+k, len-k);
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_set_value_octet (node, value, len);
break;
case TYPE_GENERALSTRING:
if (len == 0)
len = strlen (value);
_asn1_set_value_octet (node, value, len);
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_m (node, temp, len2);
temp = NULL;
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_set_value_octet (node, value, len);
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)
{
ASN1_TYPE 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)
{
ASN1_TYPE 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)
{
ASN1_TYPE 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 | 74 | 105 | 197 | lib/decoding.c |
int
_asn1_extract_tag_der (ASN1_TYPE node, const unsigned char *der, int der_len,
int *ret_len)
{
ASN1_TYPE 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_ber (der + counter, der_len - counter,
&len2);
if (len3 < 0)
return ASN1_DER_ERROR;
counter += len2;
if (counter > der_len)
return ASN1_DER_ERROR;
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;
}
|
|||||
| ↓ | yyparse | 145 | 431 | 1015 | lib/ASN1.c |
int
yyparse (void *YYPARSE_PARAM)
#else
int
yyparse (YYPARSE_PARAM)
void *YYPARSE_PARAM;
#endif
#else /* ! YYPARSE_PARAM */
#if (defined __STDC__ || defined __C99__FUNC__ \
|| defined __cplusplus || defined _MSC_VER)
int
yyparse (void)
#else
int
yyparse ()
#endif
#endif
{
int yystate;
int yyn;
int yyresult;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
/* Look-ahead token as an internal (translated) token number. */
int yytoken = 0;
#if YYERROR_VERBOSE
/* Buffer for error messages, and its allocated size. */
char yymsgbuf[128];
char *yymsg = yymsgbuf;
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif
/* Three stacks and their tools:
`yyss': related to states,
`yyvs': related to semantic values,
`yyls': related to locations.
Refer to the stacks thru separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* The state stack. */
yytype_int16 yyssa[YYINITDEPTH];
yytype_int16 *yyss = yyssa;
yytype_int16 *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs = yyvsa;
YYSTYPE *yyvsp;
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
YYSIZE_T yystacksize = YYINITDEPTH;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
/* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */
int yylen = 0;
YYDPRINTF ((stderr, "Starting parse\n"));
yystate = 0;
yyerrstatus = 0;
yynerrs = 0;
yychar = YYEMPTY; /* Cause a token to be read. */
/* Initialize stack pointers.
Waste one element of value and location stack
so that they stay on the same level as the state stack.
The wasted elements are never initialized. */
yyssp = yyss;
yyvsp = yyvs;
goto yysetstate;
/*------------------------------------------------------------.
| yynewstate -- Push a new state, which is found in yystate. |
`------------------------------------------------------------*/
yynewstate:
/* In all cases, when you get here, the value and location stacks
have just been pushed. So pushing a state here evens the stacks. */
yyssp++;
yysetstate:
*yyssp = yystate;
if (yyss + yystacksize - 1 <= yyssp)
{
/* Get the current used size of the three stacks, in elements. */
YYSIZE_T yysize = yyssp - yyss + 1;
#ifdef yyoverflow
{
/* Give user a chance to reallocate the stack. Use copies of
these so that the &'s don't force the real ones into
memory. */
YYSTYPE *yyvs1 = yyvs;
yytype_int16 *yyss1 = yyss;
/* Each stack pointer address is followed by the size of the
data in use in that stack, in bytes. This used to be a
conditional around just the two extra args, but that might
be undefined if yyoverflow is a macro. */
yyoverflow (YY_("memory exhausted"),
&yyss1, yysize * sizeof (*yyssp),
&yyvs1, yysize * sizeof (*yyvsp),
&yystacksize);
yyss = yyss1;
yyvs = yyvs1;
}
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
goto yyexhaustedlab;
# else
/* Extend the stack our own way. */
if (YYMAXDEPTH <= yystacksize)
goto yyexhaustedlab;
yystacksize *= 2;
if (YYMAXDEPTH < yystacksize)
yystacksize = YYMAXDEPTH;
{
yytype_int16 *yyss1 = yyss;
union yyalloc *yyptr =
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
if (! yyptr)
goto yyexhaustedlab;
YYSTACK_RELOCATE (yyss);
YYSTACK_RELOCATE (yyvs);
# undef YYSTACK_RELOCATE
if (yyss1 != yyssa)
YYSTACK_FREE (yyss1);
}
# endif
#endif /* no yyoverflow */
yyssp = yyss + yysize - 1;
yyvsp = yyvs + yysize - 1;
YYDPRINTF ((stderr, "Stack size increased to %lu\n",
(unsigned long int) yystacksize));
if (yyss + yystacksize - 1 <= yyssp)
YYABORT;
}
YYDPRINTF ((stderr, "Entering state %d\n", yystate));
goto yybackup;
/*-----------.
| yybackup. |
`-----------*/
yybackup:
/* Do appropriate processing given the current state. Read a
look-ahead token if we need one and don't already have one. */
/* First try to decide what to do without reference to look-ahead token. */
yyn = yypact[yystate];
if (yyn == YYPACT_NINF)
goto yydefault;
/* Not known => get a look-ahead token if don't already have one. */
/* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
if (yychar == YYEMPTY)
{
YYDPRINTF ((stderr, "Reading a token: "));
yychar = YYLEX;
}
if (yychar <= YYEOF)
{
yychar = yytoken = YYEOF;
YYDPRINTF ((stderr, "Now at end of input.\n"));
}
else
{
yytoken = YYTRANSLATE (yychar);
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
}
/* If the proper action on seeing token YYTOKEN is to reduce or to
detect an error, take that action. */
yyn += yytoken;
if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
goto yydefault;
yyn = yytable[yyn];
if (yyn <= 0)
{
if (yyn == 0 || yyn == YYTABLE_NINF)
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
if (yyn == YYFINAL)
YYACCEPT;
/* Count tokens shifted since error; after three, turn off error
status. */
if (yyerrstatus)
yyerrstatus--;
/* Shift the look-ahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
/* Discard the shifted token unless it is eof. */
if (yychar != YYEOF)
yychar = YYEMPTY;
yystate = yyn;
*++yyvsp = yylval;
goto yynewstate;
/*-----------------------------------------------------------.
| yydefault -- do the default action for the current state. |
`-----------------------------------------------------------*/
yydefault:
yyn = yydefact[yystate];
if (yyn == 0)
goto yyerrlab;
goto yyreduce;
/*-----------------------------.
| yyreduce -- Do a reduction. |
`-----------------------------*/
yyreduce:
/* yyn is the number of a rule to reduce with. */
yylen = yyr2[yyn];
/* If YYLEN is nonzero, implement the default value of the action:
`$$ = $1'.
Otherwise, the following line sets YYVAL to garbage.
This behavior is undocumented and Bison
users should not rely upon it. Assigning to YYVAL
unconditionally makes the parser a bit smaller, and it avoids a
GCC warning that YYVAL may be used uninitialized. */
yyval = yyvsp[1-yylen];
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
case 2:
#line 127 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_DEFINITIONS|(yyvsp[(3) - (8)].constant));
_asn1_set_name((yyval.node),_asn1_get_name((yyvsp[(1) - (8)].node)));
_asn1_set_name((yyvsp[(1) - (8)].node),"");
_asn1_set_right((yyvsp[(1) - (8)].node),(yyvsp[(7) - (8)].node));
_asn1_set_down((yyval.node),(yyvsp[(1) - (8)].node));
p_tree=(yyval.node);
}
break;
case 3:
#line 137 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 4:
#line 138 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(2) - (2)].str));}
break;
case 5:
#line 141 "ASN1.y"
{strcpy((yyval.str),"-");
strcat((yyval.str),(yyvsp[(2) - (2)].str));}
break;
case 6:
#line 145 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 7:
#line 146 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 8:
#line 149 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 9:
#line 150 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 10:
#line 153 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 11:
#line 154 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 12:
#line 157 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_CONSTANT);
_asn1_set_value((yyval.node),(yyvsp[(2) - (3)].str),strlen((yyvsp[(2) - (3)].str))+1);}
break;
case 13:
#line 159 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_CONSTANT);
_asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));
_asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
break;
case 14:
#line 164 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 15:
#line 165 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (3)].node);
_asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (3)].node)),(yyvsp[(3) - (3)].node));}
break;
case 16:
#line 169 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_CONSTANT);
_asn1_set_value((yyval.node),(yyvsp[(1) - (1)].str),strlen((yyvsp[(1) - (1)].str))+1);}
break;
case 17:
#line 171 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_CONSTANT);
_asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));
_asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
break;
case 18:
#line 176 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 19:
#line 177 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (2)].node);
_asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (2)].node)),(yyvsp[(2) - (2)].node));}
break;
case 20:
#line 181 "ASN1.y"
{(yyval.constant)=CONST_UNIVERSAL;}
break;
case 21:
#line 182 "ASN1.y"
{(yyval.constant)=CONST_PRIVATE;}
break;
case 22:
#line 183 "ASN1.y"
{(yyval.constant)=CONST_APPLICATION;}
break;
case 23:
#line 186 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_TAG);
_asn1_set_value((yyval.node),(yyvsp[(2) - (3)].str),strlen((yyvsp[(2) - (3)].str))+1);}
break;
case 24:
#line 188 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_TAG | (yyvsp[(2) - (4)].constant));
_asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
break;
case 25:
#line 192 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 26:
#line 193 "ASN1.y"
{(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_EXPLICIT);}
break;
case 27:
#line 194 "ASN1.y"
{(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_IMPLICIT);}
break;
case 28:
#line 197 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_DEFAULT);
_asn1_set_value((yyval.node),(yyvsp[(2) - (2)].str),strlen((yyvsp[(2) - (2)].str))+1);}
break;
case 29:
#line 199 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_DEFAULT|CONST_TRUE);}
break;
case 30:
#line 200 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_DEFAULT|CONST_FALSE);}
break;
case 33:
#line 209 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_INTEGER);}
break;
case 34:
#line 210 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_INTEGER|CONST_LIST);
_asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
break;
case 35:
#line 212 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_INTEGER);}
break;
case 36:
#line 214 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_INTEGER|CONST_MIN_MAX);
_asn1_set_down((yyval.node),_asn1_add_node(TYPE_SIZE));
_asn1_set_value(_asn1_get_down((yyval.node)),(yyvsp[(6) - (7)].str),strlen((yyvsp[(6) - (7)].str))+1);
_asn1_set_name(_asn1_get_down((yyval.node)),(yyvsp[(3) - (7)].str));}
break;
case 37:
#line 220 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_BOOLEAN);}
break;
case 38:
#line 223 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_TIME|CONST_UTC);}
break;
case 39:
#line 224 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_TIME|CONST_GENERALIZED);}
break;
case 40:
#line 227 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_SIZE|CONST_1_PARAM);
_asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
break;
case 41:
#line 230 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_SIZE|CONST_MIN_MAX);
_asn1_set_value((yyval.node),(yyvsp[(3) - (7)].str),strlen((yyvsp[(3) - (7)].str))+1);
_asn1_set_name((yyval.node),(yyvsp[(6) - (7)].str));}
break;
case 42:
#line 235 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 43:
#line 236 "ASN1.y"
{(yyval.node)=(yyvsp[(2) - (3)].node);}
break;
case 44:
#line 239 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_GENERALSTRING);}
break;
case 45:
#line 240 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_GENERALSTRING|CONST_SIZE);
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
break;
case 46:
#line 244 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_OCTET_STRING);}
break;
case 47:
#line 245 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_OCTET_STRING|CONST_SIZE);
_asn1_set_down((yyval.node),(yyvsp[(3) - (3)].node));}
break;
case 48:
#line 249 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_CONSTANT);
_asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));
_asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
break;
case 49:
#line 254 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 50:
#line 255 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (3)].node);
_asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (3)].node)),(yyvsp[(3) - (3)].node));}
break;
case 51:
#line 259 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_BIT_STRING);}
break;
case 52:
#line 260 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_BIT_STRING|CONST_SIZE);}
break;
case 53:
#line 262 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_BIT_STRING|CONST_LIST);
_asn1_set_down((yyval.node),(yyvsp[(4) - (5)].node));}
break;
case 54:
#line 267 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_ENUMERATED|CONST_LIST);
_asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
break;
case 55:
#line 272 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_OBJECT_ID);}
break;
case 56:
#line 275 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_IDENTIFIER);
_asn1_set_value((yyval.node),(yyvsp[(1) - (1)].str),strlen((yyvsp[(1) - (1)].str))+1);}
break;
case 57:
#line 277 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_IDENTIFIER|CONST_SIZE);
_asn1_set_value((yyval.node),(yyvsp[(1) - (2)].str),strlen((yyvsp[(1) - (2)].str))+1);
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
break;
case 58:
#line 280 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 59:
#line 281 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 60:
#line 282 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 62:
#line 284 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 63:
#line 285 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 64:
#line 286 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 65:
#line 287 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 66:
#line 288 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 67:
#line 289 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 68:
#line 290 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 69:
#line 291 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 70:
#line 292 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_NULL);}
break;
case 71:
#line 295 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 72:
#line 296 "ASN1.y"
{(yyval.node)=_asn1_mod_type((yyvsp[(2) - (2)].node),CONST_TAG);
_asn1_set_right((yyvsp[(1) - (2)].node),_asn1_get_down((yyval.node)));
_asn1_set_down((yyval.node),(yyvsp[(1) - (2)].node));}
break;
case 73:
#line 301 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 74:
#line 302 "ASN1.y"
{(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_DEFAULT);
_asn1_set_right((yyvsp[(2) - (2)].node),_asn1_get_down((yyval.node)));
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
break;
case 75:
#line 305 "ASN1.y"
{(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_OPTION);}
break;
case 76:
#line 308 "ASN1.y"
{(yyval.node)=_asn1_set_name((yyvsp[(2) - (2)].node),(yyvsp[(1) - (2)].str));}
break;
case 77:
#line 311 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 78:
#line 312 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (3)].node);
_asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (3)].node)),(yyvsp[(3) - (3)].node));}
break;
case 79:
#line 316 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_SEQUENCE);
_asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
break;
case 80:
#line 318 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_SEQUENCE_OF);
_asn1_set_down((yyval.node),(yyvsp[(3) - (3)].node));}
break;
case 81:
#line 320 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_SEQUENCE_OF|CONST_SIZE);
_asn1_set_right((yyvsp[(2) - (4)].node),(yyvsp[(4) - (4)].node));
_asn1_set_down((yyval.node),(yyvsp[(2) - (4)].node));}
break;
case 82:
#line 325 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_SET);
_asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
break;
case 83:
#line 327 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_SET_OF);
_asn1_set_down((yyval.node),(yyvsp[(3) - (3)].node));}
break;
case 84:
#line 329 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_SET_OF|CONST_SIZE);
_asn1_set_right((yyvsp[(2) - (4)].node),(yyvsp[(4) - (4)].node));
_asn1_set_down((yyval.node),(yyvsp[(2) - (4)].node));}
break;
case 85:
#line 334 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_CHOICE);
_asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
break;
case 86:
#line 338 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_ANY);}
break;
case 87:
#line 339 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_ANY|CONST_DEFINED_BY);
_asn1_set_down((yyval.node),_asn1_add_node(TYPE_CONSTANT));
_asn1_set_name(_asn1_get_down((yyval.node)),(yyvsp[(4) - (4)].str));}
break;
case 88:
#line 344 "ASN1.y"
{(yyval.node)=_asn1_set_name((yyvsp[(3) - (3)].node),(yyvsp[(1) - (3)].str));}
break;
case 89:
#line 348 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN);
_asn1_set_name((yyval.node),(yyvsp[(1) - (7)].str));
_asn1_set_down((yyval.node),(yyvsp[(6) - (7)].node));}
break;
case 90:
#line 352 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
_asn1_set_name((yyval.node),(yyvsp[(1) - (6)].str));
_asn1_set_value((yyval.node),(yyvsp[(2) - (6)].str),strlen((yyvsp[(2) - (6)].str))+1);
_asn1_set_down((yyval.node),(yyvsp[(5) - (6)].node));}
break;
case 91:
#line 357 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_INTEGER|CONST_ASSIGN);
_asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));
_asn1_set_value((yyval.node),(yyvsp[(4) - (4)].str),strlen((yyvsp[(4) - (4)].str))+1);}
break;
case 92:
#line 362 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 93:
#line 363 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 94:
#line 366 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 95:
#line 367 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (2)].node);
_asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (2)].node)),(yyvsp[(2) - (2)].node));}
break;
case 96:
#line 371 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_OBJECT_ID);
_asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));
_asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));}
break;
case 97:
#line 374 "ASN1.y"
{(yyval.node)=_asn1_add_node(TYPE_OBJECT_ID);
_asn1_set_name((yyval.node),(yyvsp[(1) - (3)].str));}
break;
case 98:
#line 398 "ASN1.y"
{(yyval.constant)=CONST_EXPLICIT;}
break;
case 99:
#line 399 "ASN1.y"
{(yyval.constant)=CONST_IMPLICIT;}
break;
/* Line 1267 of yacc.c. */
#line 2141 "ASN1.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
YYPOPSTACK (yylen);
yylen = 0;
YY_STACK_PRINT (yyss, yyssp);
*++yyvsp = yyval;
/* Now `shift' the result of the reduction. Determine what state
that goes to, based on the state we popped back to and the rule
number reduced by. */
yyn = yyr1[yyn];
yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
yystate = yytable[yystate];
else
yystate = yydefgoto[yyn - YYNTOKENS];
goto yynewstate;
/*------------------------------------.
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
++yynerrs;
#if ! YYERROR_VERBOSE
yyerror (YY_("syntax error"));
#else
{
YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
{
YYSIZE_T yyalloc = 2 * yysize;
if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
yyalloc = YYSTACK_ALLOC_MAXIMUM;
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yyalloc);
if (yymsg)
yymsg_alloc = yyalloc;
else
{
yymsg = yymsgbuf;
yymsg_alloc = sizeof yymsgbuf;
}
}
if (0 < yysize && yysize <= yymsg_alloc)
{
(void) yysyntax_error (yymsg, yystate, yychar);
yyerror (yymsg);
}
else
{
yyerror (YY_("syntax error"));
if (yysize != 0)
goto yyexhaustedlab;
}
}
#endif
}
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse look-ahead token after an
error, discard it. */
if (yychar <= YYEOF)
{
/* Return failure if at end of input. */
if (yychar == YYEOF)
YYABORT;
}
else
{
yydestruct ("Error: discarding",
yytoken, &yylval);
yychar = YYEMPTY;
}
}
/* Else will try to reuse look-ahead token after shifting the error
token. */
goto yyerrlab1;
/*---------------------------------------------------.
| yyerrorlab -- error raised explicitly by YYERROR. |
`---------------------------------------------------*/
yyerrorlab:
/* Pacify compilers like GCC when the user code never invokes
YYERROR and the label yyerrorlab therefore never appears in user
code. */
if (/*CONSTCOND*/ 0)
goto yyerrorlab;
/* Do not reclaim the symbols of the rule which action triggered
this YYERROR. */
YYPOPSTACK (yylen);
yylen = 0;
YY_STACK_PRINT (yyss, yyssp);
yystate = *yyssp;
goto yyerrlab1;
/*-------------------------------------------------------------.
| yyerrlab1 -- common code for both syntax error and YYERROR. |
`-------------------------------------------------------------*/
yyerrlab1:
yyerrstatus = 3; /* Each real token shifted decrements this. */
for (;;)
{
yyn = yypact[yystate];
if (yyn != YYPACT_NINF)
{
yyn += YYTERROR;
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
{
yyn = yytable[yyn];
if (0 < yyn)
break;
}
}
/* Pop the current state because it cannot handle the error token. */
if (yyssp == yyss)
YYABORT;
yydestruct ("Error: popping",
yystos[yystate], yyvsp);
YYPOPSTACK (1);
yystate = *yyssp;
YY_STACK_PRINT (yyss, yyssp);
}
if (yyn == YYFINAL)
YYACCEPT;
*++yyvsp = yylval;
/* Shift the error token. */
YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
yystate = yyn;
goto yynewstate;
/*-------------------------------------.
| yyacceptlab -- YYACCEPT comes here. |
`-------------------------------------*/
yyacceptlab:
yyresult = 0;
goto yyreturn;
/*-----------------------------------.
| yyabortlab -- YYABORT comes here. |
`-----------------------------------*/
yyabortlab:
yyresult = 1;
goto yyreturn;
#ifndef yyoverflow
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
yyexhaustedlab:
yyerror (YY_("memory exhausted"));
yyresult = 2;
/* Fall through. */
#endif
yyreturn:
if (yychar != YYEOF && yychar != YYEMPTY)
yydestruct ("Cleanup: discarding lookahead",
yytoken, &yylval);
/* Do not reclaim the symbols of the rule which action triggered
this YYABORT or YYACCEPT. */
YYPOPSTACK (yylen);
YY_STACK_PRINT (yyss, yyssp);
while (yyssp != yyss)
{
yydestruct ("Cleanup: popping",
yystos[*yyssp], yyvsp);
YYPOPSTACK (1);
}
#ifndef yyoverflow
if (yyss != yyssa)
YYSTACK_FREE (yyss);
#endif
#if YYERROR_VERBOSE
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
#endif
/* Make sure YYID is used. */
return YYID (yyresult);
}
|
|||||
| ↓ | _asn1_expand_object_id | 44 | 95 | 169 | lib/parser_aux.c |
asn1_retCode
_asn1_expand_object_id (ASN1_TYPE node)
{
ASN1_TYPE 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_yylex | 44 | 53 | 79 | lib/ASN1.c |
static int
_asn1_yylex()
{
int c,counter=0,k,lastc;
char string[ASN1_MAX_NAME_SIZE+1]; /* will contain the next token */
while(1)
{
while((c=fgetc(file_asn1))==' ' || c=='\t' || c=='\n')
if(c=='\n') lineNumber++;
if(c==EOF){
strcpy(lastToken,"End Of File");
return 0;
}
if(c=='(' || c==')' || c=='[' || c==']' ||
c=='{' || c=='}' || c==',' || c=='.' ||
c=='+' || c=='|'){
lastToken[0]=c;lastToken[1]=0;
return c;
}
if(c=='-'){ /* Maybe the first '-' of a comment */
if((c=fgetc(file_asn1))!='-'){
ungetc(c,file_asn1);
lastToken[0]='-';lastToken[1]=0;
return '-';
}
else{ /* Comments */
lastc=0;
counter=0;
/* A comment finishes at the next double hypen or the end of line */
while((c=fgetc(file_asn1))!=EOF && c!='\n' &&
(lastc!='-' || (lastc=='-' && c!='-')))
lastc=c;
if(c==EOF){
strcpy(lastToken,"End Of File");
return 0;
}
else{
if(c=='\n') lineNumber++;
continue; /* next char, please! (repeat the search) */
}
}
}
string[counter++]=c;
/* Till the end of the token */
while(!((c=fgetc(file_asn1))==EOF || c==' '|| c=='\t' || c=='\n' ||
c=='(' || c==')' || c=='[' || c==']' ||
c=='{' || c=='}' || c==',' || c=='.'))
{
if(counter>=ASN1_MAX_NAME_SIZE){
result_parse=ASN1_NAME_TOO_LONG;
return 0;
}
string[counter++]=c;
}
ungetc(c,file_asn1);
string[counter]=0;
strcpy(lastToken,string);
/* Is STRING a number? */
for(k=0;k
|
|||||
| ↓ | 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)
{
ASN1_TYPE 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)
{
ASN1_TYPE 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 (ASN1_TYPE * node, ASN1_TYPE root)
{
ASN1_TYPE 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, ASN1_TYPE node)
{
struct vet
{
int end;
struct vet *next, *prev;
};
int counter, len, len2, change;
struct vet *first, *last, *p_vet, *p2_vet;
ASN1_TYPE 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_array2tree | 21 | 53 | 97 | lib/structure.c |
asn1_retCode
asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions,
char *errorDescription)
{
ASN1_TYPE 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 (ASN1_TYPE node, unsigned char *der, int *counter,
int *max_len)
{
ASN1_TYPE 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)
{
ASN1_TYPE 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 (ASN1_TYPE node)
{
ASN1_TYPE 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_get_octet_string | 17 | 47 | 82 | lib/decoding.c |
asn1_retCode
_asn1_get_octet_string (const unsigned char *der, ASN1_TYPE node, int *len)
{
int len2, len3, counter, tot_len, indefinite;
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)
{
unsigned char temp[DER_LEN];
int ret;
len2 = sizeof(temp);
asn1_length_der (tot_len, temp, &len2);
_asn1_set_value (node, temp, len2);
tot_len += len2;
ret = _asn1_extract_der_octet(node, der, *len);
if (ret!=ASN1_SUCCESS)
return ret;
}
}
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_ordering_set | 16 | 59 | 104 | lib/coding.c |
void
_asn1_ordering_set (unsigned char *der, int der_len, ASN1_TYPE node)
{
struct vet
{
int end;
unsigned long value;
struct vet *next, *prev;
};
int counter, len, len2;
struct vet *first, *last, *p_vet, *p2_vet;
ASN1_TYPE 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;
}
}
|
|||||
| ↓ | yysyntax_error | 15 | 62 | 100 | lib/ASN1.c |
static YYSIZE_T
yysyntax_error (char *yyresult, int yystate, int yychar)
{
int yyn = yypact[yystate];
if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
return 0;
else
{
int yytype = YYTRANSLATE (yychar);
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
YYSIZE_T yysize = yysize0;
YYSIZE_T yysize1;
int yysize_overflow = 0;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
int yyx;
# if 0
/* This is so xgettext sees the translatable formats that are
constructed on the fly. */
YY_("syntax error, unexpected %s");
YY_("syntax error, unexpected %s, expecting %s");
YY_("syntax error, unexpected %s, expecting %s or %s");
YY_("syntax error, unexpected %s, expecting %s or %s or %s");
YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
# endif
char *yyfmt;
char const *yyf;
static char const yyunexpected[] = "syntax error, unexpected %s";
static char const yyexpecting[] = ", expecting %s";
static char const yyor[] = " or %s";
char yyformat[sizeof yyunexpected
+ sizeof yyexpecting - 1
+ ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
* (sizeof yyor - 1))];
char const *yyprefix = yyexpecting;
/* Start YYX at -YYN if negative to avoid negative indexes in
YYCHECK. */
int yyxbegin = yyn < 0 ? -yyn : 0;
/* Stay within bounds of both yycheck and yytname. */
int yychecklim = YYLAST - yyn + 1;
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
int yycount = 1;
yyarg[0] = yytname[yytype];
yyfmt = yystpcpy (yyformat, yyunexpected);
for (yyx = yyxbegin; yyx < yyxend; ++yyx)
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
{
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
{
yycount = 1;
yysize = yysize0;
yyformat[sizeof yyunexpected - 1] = '\0';
break;
}
yyarg[yycount++] = yytname[yyx];
yysize1 = yysize + yytnamerr (0, yytname[yyx]);
yysize_overflow |= (yysize1 < yysize);
yysize = yysize1;
yyfmt = yystpcpy (yyfmt, yyprefix);
yyprefix = yyor;
}
yyf = YY_(yyformat);
yysize1 = yysize + yystrlen (yyf);
yysize_overflow |= (yysize1 < yysize);
yysize = yysize1;
if (yysize_overflow)
return YYSIZE_MAXIMUM;
if (yyresult)
{
/* Avoid sprintf, as that infringes on the user's name space.
Don't have undefined behavior even if the translation
produced a string with the wrong number of "%s"s. */
char *yyp = yyresult;
int yyi = 0;
while ((*yyp = *yyf) != '\0')
{
if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
{
yyp += yytnamerr (yyp, yyarg[yyi++]);
yyf += 2;
}
else
{
yyp++;
yyf++;
}
}
}
return yysize;
}
}
|
|||||
| ↓ | _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 (ASN1_TYPE root, const char *name, int *tagValue,
int *classValue)
{
ASN1_TYPE 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)
{
ASN1_TYPE 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 = ASN1_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 (ASN1_TYPE node)
{
ASN1_TYPE 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)
{
ASN1_TYPE 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;
ASN1_TYPE 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 |
ASN1_TYPE
_asn1_copy_structure3 (ASN1_TYPE source_node)
{
ASN1_TYPE 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)
{
ASN1_TYPE 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 < 2 || 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_parser2array | 9 | 48 | 95 | lib/ASN1.c | |
| asn1_find_structure_from_oid | 9 | 23 | 43 | lib/structure.c | |
| asn1_delete_structure | 8 | 25 | 50 | lib/structure.c | |
| yytnamerr | 11 | 20 | 38 | lib/ASN1.c | |
| asn1_get_length_der | 7 | 20 | 43 | lib/decoding.c | |
| _asn1_extract_der_octet | 7 | 20 | 40 | lib/decoding.c | |
| _asn1_append_sequence_set | 7 | 20 | 33 | lib/element.c | |
| _asn1_create_errorDescription | 11 | 29 | 42 | lib/ASN1.c | |
| asn1_parser2tree | 6 | 26 | 58 | lib/ASN1.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_delete_element | 5 | 14 | 25 | lib/structure.c | |
| _asn1_set_value | 5 | 14 | 23 | lib/parser_aux.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_append_value | 4 | 12 | 21 | lib/parser_aux.c | |
| _asn1_set_value_m | 4 | 11 | 21 | lib/parser_aux.c | |
| asn1_get_octet_der | 4 | 11 | 26 | lib/decoding.c | |
| _asn1_time_der | 4 | 11 | 19 | lib/coding.c | |
| yy_symbol_value_print | 3 | 6 | 24 | lib/ASN1.c | |
| asn1_get_length_ber | 3 | 9 | 17 | lib/decoding.c | |
| asn1_strerror | 3 | 7 | 11 | lib/errors.c | |
| _asn1_get_last_right | 3 | 7 | 12 | lib/parser_aux.c | |
| _asn1_str_cat | 3 | 7 | 19 | lib/gstr.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_set_value_octet | 3 | 10 | 17 | lib/parser_aux.c | |
| yydestruct | 2 | 5 | 32 | lib/ASN1.c | |
| yy_stack_print | 2 | 6 | 14 | lib/ASN1.c | |
| _asn1_delete_list_and_nodes | 2 | 6 | 13 | lib/parser_aux.c | |
| _asn1_add_node_only | 2 | 6 | 13 | lib/structure.c | |
| yystrlen | 2 | 6 | 24 | lib/ASN1.c | |
| yy_symbol_print | 2 | 5 | 18 | lib/ASN1.c | |
| _asn1_delete_list | 2 | 5 | 12 | lib/parser_aux.c | |
| _asn1_error_description_value_not_found | 2 | 5 | 14 | lib/coding.c | |
| yystpcpy | 2 | 5 | 17 | lib/ASN1.c | |
| _asn1_mod_type | 2 | 4 | 8 | lib/parser_aux.c | |
| _asn1_yyerror | 2 | 4 | 14 | lib/ASN1.c | |
| asn1_perror | 2 | 3 | 6 | lib/errors.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 | |
| yy_reduce_print | 2 | 10 | 24 | lib/ASN1.c | |
| asn1_create_element | 2 | 10 | 21 | lib/structure.c | |
| _asn1_copy_structure2 | 1 | 3 | 10 | lib/structure.c | |
| _asn1_error_description_tag_error | 1 | 3 | 10 | lib/decoding.c | |
| YYID | 1 | 1 | 10 | lib/ASN1.c | |
| libtasn1_strerror | 1 | 1 | 5 | lib/errors.c | |