Report generated at: Sun Mar 24 11:36:40 CET 2013
| Total number of functions | 103 |
| Number of low risk functions | 69 |
| Number of moderate risk functions | 15 |
| Number of high risk functions | 13 |
| Number of untestable functions | 6 |
| 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 | Modified Cyclo |
Number of
Statements |
Number of
Lines |
Source File | |
| ↓ | asn1_der_decoding_element | 138 | 401 | 776 | decoding.c |
int
asn1_der_decoding_element (asn1_node * structure, const char *elementName,
const void *ider, int len, char *errorDescription)
{
asn1_node node, p, p2, p3, nodeFound = NULL;
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;
unsigned long tag;
int indefinite, result;
const unsigned char *der = ider;
node = *structure;
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
if (elementName == NULL)
{
result = ASN1_ELEMENT_NOT_FOUND;
goto cleanup;
}
if (node->type & CONST_OPTION)
{
result = ASN1_GENERIC_ERROR;
goto cleanup;
}
if ((*structure)->name[0] != 0)
{ /* Has *structure got a name? */
nameLen -= strlen ((*structure)->name);
if (nameLen > 0)
strcpy (currentName, (*structure)->name);
else
{
result = ASN1_MEM_ERROR;
goto cleanup;
}
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 = _asn1_strtol (p2->value, NULL, 10);
if (counter == len2)
{
p = p2;
move = UP;
continue;
}
else if (counter > len2)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
p2 = p2->down;
while (p2)
{
if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
{
if (type_field (p2->type) != ASN1_ETYPE_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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
}
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
p2 = _asn1_find_up (p);
len2 = _asn1_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) == ASN1_ETYPE_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)
{
result = ASN1_ERROR_TYPE_ANY;
goto cleanup;
}
else
{
p2 = p->down;
asn1_delete_structure (&p2);
}
}
if (p->down == NULL)
{
if (!(p->type & CONST_OPTION))
{
result = ASN1_DER_ERROR;
goto cleanup;
}
}
else
p = p->down;
}
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
p2 = _asn1_find_up (p);
len2 = _asn1_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);
result = ASN1_TAG_ERROR;
goto cleanup;
}
}
else
counter += len2;
}
if (ris == ASN1_SUCCESS)
{
switch (type_field (p->type))
{
case ASN1_ETYPE_NULL:
if (der[counter])
{
result = ASN1_DER_ERROR;
goto cleanup;
}
if (p == nodeFound)
state = EXIT;
counter++;
move = RIGHT;
break;
case ASN1_ETYPE_BOOLEAN:
if (der[counter++] != 1)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
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 ASN1_ETYPE_INTEGER:
case ASN1_ETYPE_ENUMERATED:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
if (state == FOUND)
{
if (len3 + len2 > len - counter)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
_asn1_set_value (p, der + counter, len3 + len2);
if (p == nodeFound)
state = EXIT;
}
counter += len3 + len2;
move = RIGHT;
break;
case ASN1_ETYPE_OBJECT_ID:
if (state == FOUND)
{
result =
_asn1_get_objectid_der (der + counter, len - counter,
&len2, temp, sizeof (temp));
if (result != ASN1_SUCCESS)
goto cleanup;
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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
len2 += len3;
}
counter += len2;
move = RIGHT;
break;
case ASN1_ETYPE_GENERALIZED_TIME:
case ASN1_ETYPE_UTC_TIME:
if (state == FOUND)
{
result =
_asn1_get_time_der (der + counter, len - counter, &len2,
temp, sizeof (temp) - 1);
if (result != ASN1_SUCCESS)
goto cleanup;
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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
len2 += len3;
}
counter += len2;
move = RIGHT;
break;
case ASN1_ETYPE_OCTET_STRING:
len3 = len - counter;
if (state == FOUND)
{
result = _asn1_get_octet_string (der + counter, p, &len3);
if (p == nodeFound)
state = EXIT;
}
else
result = _asn1_get_octet_string (der + counter, NULL, &len3);
if (result != ASN1_SUCCESS)
goto cleanup;
counter += len3;
move = RIGHT;
break;
case ASN1_ETYPE_GENERALSTRING:
case ASN1_ETYPE_NUMERIC_STRING:
case ASN1_ETYPE_IA5_STRING:
case ASN1_ETYPE_TELETEX_STRING:
case ASN1_ETYPE_PRINTABLE_STRING:
case ASN1_ETYPE_UNIVERSAL_STRING:
case ASN1_ETYPE_BMP_STRING:
case ASN1_ETYPE_UTF8_STRING:
case ASN1_ETYPE_VISIBLE_STRING:
case ASN1_ETYPE_BIT_STRING:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
if (state == FOUND)
{
if (len3 + len2 > len - counter)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
_asn1_set_value (p, der + counter, len3 + len2);
if (p == nodeFound)
state = EXIT;
}
counter += len3 + len2;
move = RIGHT;
break;
case ASN1_ETYPE_SEQUENCE:
case ASN1_ETYPE_SET:
if (move == UP)
{
len2 = _asn1_strtol (p->value, NULL, 10);
_asn1_set_value (p, NULL, 0);
if (len2 == -1)
{ /* indefinite length method */
if ((der[counter]) || der[counter + 1])
{
result = ASN1_DER_ERROR;
goto cleanup;
}
counter += 2;
}
else
{ /* definite length method */
if (len2 != counter)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
}
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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
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) != ASN1_ETYPE_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 ASN1_ETYPE_SEQUENCE_OF:
case ASN1_ETYPE_SET_OF:
if (move == UP)
{
len2 = _asn1_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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
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) == ASN1_ETYPE_TAG)
|| (type_field (p2->type) ==
ASN1_ETYPE_SIZE))
p2 = p2->right;
if (p2->right == NULL)
_asn1_append_sequence_set (p);
p = p2;
state = FOUND;
}
}
}
break;
case ASN1_ETYPE_ANY:
if (asn1_get_tag_der
(der + counter, len - counter, &class, &len2,
&tag) != ASN1_SUCCESS)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
if (counter + len2 > len)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
len4 =
asn1_get_length_der (der + counter + len2,
len - counter - len2, &len3);
if (len4 < -1)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
if (len4 != -1)
{
len2 += len4;
if (state == FOUND)
{
_asn1_set_value_lv (p, der + counter, len2 + len3);
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;
result =
_asn1_get_indefinite_length_string (der + counter, &len2);
if (result != ASN1_SUCCESS)
goto cleanup;
if (state == FOUND)
{
_asn1_set_value_lv (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
{
result = ASN1_DER_ERROR;
goto cleanup;
}
}
}
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
{
result = ASN1_MEM_ERROR;
goto cleanup;
}
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
{
result = ASN1_MEM_ERROR;
goto cleanup;
}
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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
return ASN1_SUCCESS;
cleanup:
asn1_delete_structure (structure);
return result;
}
|
|||||
| ↓ | asn1_der_decoding | 102 | 299 | 551 | decoding.c |
int
asn1_der_decoding (asn1_node * element, const void *ider, int len,
char *errorDescription)
{
asn1_node 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 (errorDescription != NULL)
errorDescription[0] = 0;
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
if (node->type & CONST_OPTION)
{
result = ASN1_GENERIC_ERROR;
goto cleanup;
}
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 = _asn1_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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
p2 = p2->down;
while (p2)
{
if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
{
if (type_field (p2->type) != ASN1_ETYPE_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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
}
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
p2 = _asn1_find_up (p);
len2 = _asn1_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) == ASN1_ETYPE_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)
{
result = ASN1_ERROR_TYPE_ANY;
goto cleanup;
}
else
{
p2 = p->down;
asn1_delete_structure (&p2);
}
}
if (p->down == NULL)
{
if (!(p->type & CONST_OPTION))
{
result = ASN1_DER_ERROR;
goto cleanup;
}
}
else
p = p->down;
}
if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
{
p2 = _asn1_find_up (p);
len2 = _asn1_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);
result = ASN1_TAG_ERROR;
goto cleanup;
}
}
else
counter += len2;
}
if (ris == ASN1_SUCCESS)
{
switch (type_field (p->type))
{
case ASN1_ETYPE_NULL:
if (der[counter])
{
result = ASN1_DER_ERROR;
goto cleanup;
}
counter++;
move = RIGHT;
break;
case ASN1_ETYPE_BOOLEAN:
if (der[counter++] != 1)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
if (der[counter++] == 0)
_asn1_set_value (p, "F", 1);
else
_asn1_set_value (p, "T", 1);
move = RIGHT;
break;
case ASN1_ETYPE_INTEGER:
case ASN1_ETYPE_ENUMERATED:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
_asn1_set_value (p, der + counter, len3 + len2);
counter += len3 + len2;
move = RIGHT;
break;
case ASN1_ETYPE_OBJECT_ID:
result =
_asn1_get_objectid_der (der + counter, len - counter, &len2,
temp, sizeof (temp));
if (result != ASN1_SUCCESS)
goto cleanup;
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
counter += len2;
move = RIGHT;
break;
case ASN1_ETYPE_GENERALIZED_TIME:
case ASN1_ETYPE_UTC_TIME:
result =
_asn1_get_time_der (der + counter, len - counter, &len2, temp,
sizeof (temp) - 1);
if (result != ASN1_SUCCESS)
goto cleanup;
tlen = strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen);
counter += len2;
move = RIGHT;
break;
case ASN1_ETYPE_OCTET_STRING:
len3 = len - counter;
result = _asn1_get_octet_string (der + counter, p, &len3);
if (result != ASN1_SUCCESS)
goto cleanup;
counter += len3;
move = RIGHT;
break;
case ASN1_ETYPE_GENERALSTRING:
case ASN1_ETYPE_NUMERIC_STRING:
case ASN1_ETYPE_IA5_STRING:
case ASN1_ETYPE_TELETEX_STRING:
case ASN1_ETYPE_PRINTABLE_STRING:
case ASN1_ETYPE_UNIVERSAL_STRING:
case ASN1_ETYPE_BMP_STRING:
case ASN1_ETYPE_UTF8_STRING:
case ASN1_ETYPE_VISIBLE_STRING:
case ASN1_ETYPE_BIT_STRING:
len2 =
asn1_get_length_der (der + counter, len - counter, &len3);
if (len2 < 0)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
_asn1_set_value (p, der + counter, len3 + len2);
counter += len3 + len2;
move = RIGHT;
break;
case ASN1_ETYPE_SEQUENCE:
case ASN1_ETYPE_SET:
if (move == UP)
{
len2 = _asn1_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])
{
result = ASN1_DER_ERROR;
goto cleanup;
}
}
else
{
result = ASN1_DER_ERROR;
goto cleanup;
}
counter += 2;
}
else
{ /* definite length method */
if (len2 != counter)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
}
move = RIGHT;
}
else
{ /* move==DOWN || move==RIGHT */
len3 =
asn1_get_length_der (der + counter, len - counter, &len2);
if (len3 < -1)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
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) != ASN1_ETYPE_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 ASN1_ETYPE_SEQUENCE_OF:
case ASN1_ETYPE_SET_OF:
if (move == UP)
{
len2 = _asn1_strtol (p->value, NULL, 10);
if (len2 == -1)
{ /* indefinite length method */
if ((counter + 2) > len)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
}
}
else
{ /* move==DOWN || move==RIGHT */
len3 =
asn1_get_length_der (der + counter, len - counter, &len2);
if (len3 < -1)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
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) == ASN1_ETYPE_TAG)
|| (type_field (p2->type) == ASN1_ETYPE_SIZE))
p2 = p2->right;
if (p2->right == NULL)
_asn1_append_sequence_set (p);
p = p2;
}
}
move = RIGHT;
break;
case ASN1_ETYPE_ANY:
if (asn1_get_tag_der
(der + counter, len - counter, &class, &len2,
&tag) != ASN1_SUCCESS)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
if (counter + len2 > len)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
len4 =
asn1_get_length_der (der + counter + len2,
len - counter - len2, &len3);
if (len4 < -1)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
if (len4 != -1)
{
len2 += len4;
_asn1_set_value_lv (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;
result =
_asn1_get_indefinite_length_string (der + counter, &len2);
if (result != ASN1_SUCCESS)
goto cleanup;
_asn1_set_value_lv (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
{
result = ASN1_DER_ERROR;
goto cleanup;
}
}
}
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)
{
result = ASN1_DER_ERROR;
goto cleanup;
}
return ASN1_SUCCESS;
cleanup:
asn1_delete_structure (element);
return result;
}
|
|||||
| ↓ | asn1_write_value | 92 | 207 | 341 | element.c |
int
asn1_write_value (asn1_node node_root, const char *name,
const void *ivalue, int len)
{
asn1_node node, p, p2;
unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
int len2, k, k2, negative;
size_t i;
const unsigned char *value = ivalue;
unsigned int type;
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;
}
type = type_field (node->type);
if ((type == ASN1_ETYPE_SEQUENCE_OF) && (value == NULL) && (len == 0))
{
p = node->down;
while ((type_field (p->type) == ASN1_ETYPE_TAG)
|| (type_field (p->type) == ASN1_ETYPE_SIZE))
p = p->right;
while (p->right)
asn1_delete_structure (&p->right);
return ASN1_SUCCESS;
}
switch (type)
{
case ASN1_ETYPE_BOOLEAN:
if (!_asn1_strcmp (value, "TRUE"))
{
if (node->type & CONST_DEFAULT)
{
p = node->down;
while (type_field (p->type) != ASN1_ETYPE_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 (!_asn1_strcmp (value, "FALSE"))
{
if (node->type & CONST_DEFAULT)
{
p = node->down;
while (type_field (p->type) != ASN1_ETYPE_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 ASN1_ETYPE_INTEGER:
case ASN1_ETYPE_ENUMERATED:
if (len == 0)
{
if ((isdigit (value[0])) || (value[0] == '-'))
{
value_temp = 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) == ASN1_ETYPE_CONSTANT)
{
if (!_asn1_strcmp (p->name, value))
{
value_temp = 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 = 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) == ASN1_ETYPE_ENUMERATED))
{
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_lv (node, value_temp + k, len - k);
if (node->type & CONST_DEFAULT)
{
p = node->down;
while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
p = p->right;
if ((isdigit (p->value[0])) || (p->value[0] == '-'))
{
default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
if (default_temp == NULL)
{
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))
{
free (value_temp);
return ASN1_VALUE_NOT_VALID;
}
p2 = node->down;
while (p2)
{
if (type_field (p2->type) == ASN1_ETYPE_CONSTANT)
{
if (!_asn1_strcmp (p2->name, p->value))
{
default_temp = malloc (SIZEOF_UNSIGNED_LONG_INT);
if (default_temp == NULL)
{
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)
{
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);
}
free (default_temp);
}
free (value_temp);
break;
case ASN1_ETYPE_OBJECT_ID:
for (i = 0; i < _asn1_strlen (value); i++)
if ((!isdigit (value[i])) && (value[i] != '.') && (value[i] != '+'))
return ASN1_VALUE_NOT_VALID;
if (node->type & CONST_DEFAULT)
{
p = node->down;
while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
p = p->right;
if (!_asn1_strcmp (value, p->value))
{
_asn1_set_value (node, NULL, 0);
break;
}
}
_asn1_set_value (node, value, _asn1_strlen (value) + 1);
break;
case ASN1_ETYPE_UTC_TIME:
{
len = _asn1_strlen (value);
if (len < 11)
return ASN1_VALUE_NOT_VALID;
for (k = 0; k < 10; k++)
if (!isdigit (value[k]))
return ASN1_VALUE_NOT_VALID;
switch (len)
{
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, len);
}
break;
case ASN1_ETYPE_GENERALIZED_TIME:
len = _asn1_strlen (value);
_asn1_set_value (node, value, len);
break;
case ASN1_ETYPE_OCTET_STRING:
case ASN1_ETYPE_GENERALSTRING:
case ASN1_ETYPE_NUMERIC_STRING:
case ASN1_ETYPE_IA5_STRING:
case ASN1_ETYPE_TELETEX_STRING:
case ASN1_ETYPE_PRINTABLE_STRING:
case ASN1_ETYPE_UNIVERSAL_STRING:
case ASN1_ETYPE_BMP_STRING:
case ASN1_ETYPE_UTF8_STRING:
case ASN1_ETYPE_VISIBLE_STRING:
if (len == 0)
len = _asn1_strlen (value);
_asn1_set_value_lv (node, value, len);
break;
case ASN1_ETYPE_BIT_STRING:
if (len == 0)
len = _asn1_strlen (value);
asn1_length_der ((len >> 3) + 2, NULL, &len2);
temp = 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 ASN1_ETYPE_CHOICE:
p = node->down;
while (p)
{
if (!_asn1_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 ASN1_ETYPE_ANY:
_asn1_set_value_lv (node, value, len);
break;
case ASN1_ETYPE_SEQUENCE_OF:
case ASN1_ETYPE_SET_OF:
if (_asn1_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 | 82 | 216 | 327 | structure.c |
void
asn1_print_structure (FILE * out, asn1_node structure, const char *name,
int mode)
{
asn1_node 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[0] != 0)
fprintf (out, "%s ", p->name);
else
fprintf (out, "NULL ");
}
else
{
switch (type_field (p->type))
{
case ASN1_ETYPE_CONSTANT:
case ASN1_ETYPE_TAG:
case ASN1_ETYPE_SIZE:
break;
default:
for (k = 0; k < indent; k++)
fprintf (out, " ");
fprintf (out, "name:");
if (p->name[0] != 0)
fprintf (out, "%s ", p->name);
else
fprintf (out, "NULL ");
}
}
if (mode != ASN1_PRINT_NAME)
{
unsigned type = type_field (p->type);
switch (type)
{
case ASN1_ETYPE_CONSTANT:
if (mode == ASN1_PRINT_ALL)
fprintf (out, "type:CONST");
break;
case ASN1_ETYPE_TAG:
if (mode == ASN1_PRINT_ALL)
fprintf (out, "type:TAG");
break;
case ASN1_ETYPE_SIZE:
if (mode == ASN1_PRINT_ALL)
fprintf (out, "type:SIZE");
break;
case ASN1_ETYPE_DEFAULT:
fprintf (out, "type:DEFAULT");
break;
case ASN1_ETYPE_IDENTIFIER:
fprintf (out, "type:IDENTIFIER");
break;
case ASN1_ETYPE_ANY:
fprintf (out, "type:ANY");
break;
case ASN1_ETYPE_CHOICE:
fprintf (out, "type:CHOICE");
break;
case ASN1_ETYPE_DEFINITIONS:
fprintf (out, "type:DEFINITIONS");
break;
CASE_HANDLED_ETYPES:
fprintf (out, "%s", _asn1_tags[type].desc);
break;
default:
break;
}
}
if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
{
switch (type_field (p->type))
{
case ASN1_ETYPE_CONSTANT:
if (mode == ASN1_PRINT_ALL)
if (p->value)
fprintf (out, " value:%s", p->value);
break;
case ASN1_ETYPE_TAG:
if (mode == ASN1_PRINT_ALL)
if (p->value)
fprintf (out, " value:%s", p->value);
break;
case ASN1_ETYPE_SIZE:
if (mode == ASN1_PRINT_ALL)
if (p->value)
fprintf (out, " value:%s", p->value);
break;
case ASN1_ETYPE_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 ASN1_ETYPE_IDENTIFIER:
if (p->value)
fprintf (out, " value:%s", p->value);
break;
case ASN1_ETYPE_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 ASN1_ETYPE_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 ASN1_ETYPE_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 ASN1_ETYPE_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 ASN1_ETYPE_GENERALIZED_TIME:
case ASN1_ETYPE_UTC_TIME:
if (p->value)
{
fprintf (out, " value:");
for (k = 0; k < p->value_len; k++)
fprintf (out, "%c", (p->value)[k]);
}
break;
case ASN1_ETYPE_GENERALSTRING:
case ASN1_ETYPE_NUMERIC_STRING:
case ASN1_ETYPE_IA5_STRING:
case ASN1_ETYPE_TELETEX_STRING:
case ASN1_ETYPE_PRINTABLE_STRING:
case ASN1_ETYPE_UNIVERSAL_STRING:
case ASN1_ETYPE_UTF8_STRING:
case ASN1_ETYPE_VISIBLE_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, "%c", (p->value)[k + len2]);
}
break;
case ASN1_ETYPE_BMP_STRING:
case ASN1_ETYPE_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 ASN1_ETYPE_OBJECT_ID:
if (p->value)
fprintf (out, " value:%s", p->value);
break;
case ASN1_ETYPE_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 ASN1_ETYPE_SET:
case ASN1_ETYPE_SET_OF:
case ASN1_ETYPE_CHOICE:
case ASN1_ETYPE_DEFINITIONS:
case ASN1_ETYPE_SEQUENCE_OF:
case ASN1_ETYPE_SEQUENCE:
case ASN1_ETYPE_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 ASN1_ETYPE_CONSTANT:
case ASN1_ETYPE_TAG:
case ASN1_ETYPE_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 | 72 | 172 | 315 | decoding.c |
int
asn1_der_decoding_startEnd (asn1_node element, const void *ider, int len,
const char *name_element, int *start, int *end)
{
asn1_node 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 == NULL)
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)
{
if (p == NULL)
return ASN1_DER_ERROR;
ris = ASN1_SUCCESS;
if (move != UP)
{
if (p->type & CONST_SET)
{
p2 = _asn1_find_up (p);
if (p2 == NULL)
return ASN1_DER_ERROR;
len2 = _asn1_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) != ASN1_ETYPE_CHOICE)
ris =
_asn1_extract_tag_der (p2, der + counter,
len - counter, &len2);
else
{
p3 = p2->down;
if (p3 == NULL)
return ASN1_DER_ERROR;
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) == ASN1_ETYPE_CHOICE)
{
p = p->down;
if (p == NULL)
return ASN1_DER_ERROR;
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 ASN1_ETYPE_NULL:
if (der[counter])
return ASN1_DER_ERROR;
counter++;
move = RIGHT;
break;
case ASN1_ETYPE_BOOLEAN:
if (der[counter++] != 1)
return ASN1_DER_ERROR;
counter++;
move = RIGHT;
break;
case ASN1_ETYPE_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 ASN1_ETYPE_UTC_TIME:
case ASN1_ETYPE_GENERALIZED_TIME:
case ASN1_ETYPE_OBJECT_ID:
case ASN1_ETYPE_INTEGER:
case ASN1_ETYPE_ENUMERATED:
case ASN1_ETYPE_GENERALSTRING:
case ASN1_ETYPE_NUMERIC_STRING:
case ASN1_ETYPE_IA5_STRING:
case ASN1_ETYPE_TELETEX_STRING:
case ASN1_ETYPE_PRINTABLE_STRING:
case ASN1_ETYPE_UNIVERSAL_STRING:
case ASN1_ETYPE_BMP_STRING:
case ASN1_ETYPE_UTF8_STRING:
case ASN1_ETYPE_VISIBLE_STRING:
case ASN1_ETYPE_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 ASN1_ETYPE_SEQUENCE:
case ASN1_ETYPE_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 ASN1_ETYPE_SEQUENCE_OF:
case ASN1_ETYPE_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) == ASN1_ETYPE_TAG) ||
(type_field (p2->type) == ASN1_ETYPE_SIZE))
p2 = p2->right;
p = p2;
}
}
else
{
if (!der[counter] && !der[counter + 1]) /* indefinite length method */
counter += 2;
}
move = RIGHT;
break;
case ASN1_ETYPE_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 | 64 | 198 | 330 | coding.c |
int
asn1_der_coding (asn1_node element, const char *name, void *ider, int *len,
char *ErrorDescription)
{
asn1_node node, p, p2;
unsigned char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
int 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 ASN1_ETYPE_NULL:
max_len--;
if (max_len >= 0)
der[counter] = 0;
counter++;
move = RIGHT;
break;
case ASN1_ETYPE_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 ASN1_ETYPE_INTEGER:
case ASN1_ETYPE_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 ASN1_ETYPE_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 ASN1_ETYPE_GENERALIZED_TIME:
case ASN1_ETYPE_UTC_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, p->value_len, der + counter, &len2);
if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
goto error;
max_len -= len2;
counter += len2;
move = RIGHT;
break;
case ASN1_ETYPE_OCTET_STRING:
case ASN1_ETYPE_GENERALSTRING:
case ASN1_ETYPE_NUMERIC_STRING:
case ASN1_ETYPE_IA5_STRING:
case ASN1_ETYPE_TELETEX_STRING:
case ASN1_ETYPE_PRINTABLE_STRING:
case ASN1_ETYPE_UNIVERSAL_STRING:
case ASN1_ETYPE_BMP_STRING:
case ASN1_ETYPE_UTF8_STRING:
case ASN1_ETYPE_VISIBLE_STRING:
case ASN1_ETYPE_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 ASN1_ETYPE_SEQUENCE:
case ASN1_ETYPE_SET:
if (move != UP)
{
_asn1_ltostr (counter, (char *) temp);
tlen = _asn1_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) == ASN1_ETYPE_TAG))
p2 = p2->right;
if (p2)
{
p = p2;
move = RIGHT;
continue;
}
move = UP;
continue;
}
}
else
{ /* move==UP */
len2 = _asn1_strtol (p->value, NULL, 10);
_asn1_set_value (p, NULL, 0);
if ((type_field (p->type) == ASN1_ETYPE_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 ASN1_ETYPE_SEQUENCE_OF:
case ASN1_ETYPE_SET_OF:
if (move != UP)
{
_asn1_ltostr (counter, (char *) temp);
tlen = _asn1_strlen (temp);
if (tlen > 0)
_asn1_set_value (p, temp, tlen + 1);
p = p->down;
while ((type_field (p->type) == ASN1_ETYPE_TAG)
|| (type_field (p->type) == ASN1_ETYPE_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 = _asn1_strtol (p->value, NULL, 10);
_asn1_set_value (p, NULL, 0);
if ((type_field (p->type) == ASN1_ETYPE_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 ASN1_ETYPE_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_expand_object_id | 44 | 95 | 173 | parser_aux.c |
int
_asn1_expand_object_id (asn1_node node)
{
asn1_node 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) == ASN1_ETYPE_OBJECT_ID)
&& (p->type & CONST_ASSIGN))
{
p2 = p->down;
if (p2 && (type_field (p2->type) == ASN1_ETYPE_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),
(char *) p2->value);
p3 = asn1_find_node (node, name2);
if (!p3
|| (type_field (p3->type) != ASN1_ETYPE_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) == ASN1_ETYPE_CONSTANT)
{
p5 =
_asn1_add_single_node (ASN1_ETYPE_CONSTANT);
_asn1_set_name (p5, p4->name);
tlen = _asn1_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) == ASN1_ETYPE_OBJECT_ID) &&
(p->type & CONST_DEFAULT))
{
p2 = p->down;
if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
{
_asn1_str_cpy (name2, sizeof (name2), name_root);
_asn1_str_cat (name2, sizeof (name2), ".");
_asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
p3 = asn1_find_node (node, name2);
if (!p3 || (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID)
|| !(p3->type & CONST_ASSIGN))
return ASN1_ELEMENT_NOT_FOUND;
p4 = p3->down;
name2[0] = 0;
while (p4)
{
if (type_field (p4->type) == ASN1_ETYPE_CONSTANT)
{
if (name2[0])
_asn1_str_cat (name2, sizeof (name2), ".");
_asn1_str_cat (name2, sizeof (name2),
(char *) 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 | 54 | 95 | ASN1.c |
static int
_asn1_yylex ()
{
int c, counter = 0, k, lastc;
char string[ASN1_MAX_NAME_SIZE + 1]; /* will contain the next token */
size_t i;
while (1)
{
while ((c = fgetc (file_asn1)) == ' ' || c == '\t' || c == '\n')
if (c == '\n')
line_number++;
if (c == EOF)
{
strcpy (last_token, "End Of File");
return 0;
}
if (c == '(' || c == ')' || c == '[' || c == ']' ||
c == '{' || c == '}' || c == ',' || c == '.' ||
c == '+' || c == '|')
{
last_token[0] = c;
last_token[1] = 0;
return c;
}
if (c == '-')
{ /* Maybe the first '-' of a comment */
if ((c = fgetc (file_asn1)) != '-')
{
ungetc (c, file_asn1);
last_token[0] = '-';
last_token[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 (last_token, "End Of File");
return 0;
}
else
{
if (c == '\n')
line_number++;
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 (last_token, string);
/* Is STRING a number? */
for (k = 0; k < counter; k++)
if (!isdigit (string[k]))
break;
if (k >= counter)
{
strcpy (yylval.str, string);
return NUM; /* return the number */
}
/* Is STRING a keyword? */
for (i = 0; i < (sizeof (key_word) / sizeof (char *)); i++)
if (!strcmp (string, key_word[i]))
return key_word_token[i];
/* STRING is an IDENTIFIER */
strcpy (yylval.str, string);
return IDENTIFIER;
}
}
|
|||||
| ↓ | yyparse | 44 | 496 | 1407 | 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;
/* Number of tokens to shift before error messages enabled. */
int yyerrstatus;
/* The stacks and their tools:
`yyss': related to states.
`yyvs': related to semantic values.
Refer to the stacks thru separate pointers, to allow yyoverflow
to reallocate them elsewhere. */
/* The state stack. */
yytype_int16 yyssa[YYINITDEPTH];
yytype_int16 *yyss;
yytype_int16 *yyssp;
/* The semantic value stack. */
YYSTYPE yyvsa[YYINITDEPTH];
YYSTYPE *yyvs;
YYSTYPE *yyvsp;
YYSIZE_T yystacksize;
int yyn;
int yyresult;
/* Lookahead token as an internal (translated) token number. */
int yytoken;
/* The variables used to return semantic value and location from the
action routines. */
YYSTYPE yyval;
#if YYERROR_VERBOSE
/* Buffer for error messages, and its allocated size. */
char yymsgbuf[128];
char *yymsg = yymsgbuf;
YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
/* The number of symbols on the RHS of the reduced rule.
Keep to zero when no symbol should be popped. */
int yylen = 0;
yytoken = 0;
yyss = yyssa;
yyvs = yyvsa;
yystacksize = YYINITDEPTH;
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_alloc, yyss);
YYSTACK_RELOCATE (yyvs_alloc, 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));
if (yystate == YYFINAL)
YYACCEPT;
goto yybackup;
/*-----------.
| yybackup. |
`-----------*/
yybackup:
/* Do appropriate processing given the current state. Read a
lookahead token if we need one and don't already have one. */
/* First try to decide what to do without reference to lookahead token. */
yyn = yypact[yystate];
if (yypact_value_is_default (yyn))
goto yydefault;
/* Not known => get a lookahead token if don't already have one. */
/* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead 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 (yytable_value_is_error (yyn))
goto yyerrlab;
yyn = -yyn;
goto yyreduce;
}
/* Count tokens shifted since error; after three, turn off error
status. */
if (yyerrstatus)
yyerrstatus--;
/* Shift the lookahead token. */
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
/* Discard the shifted token. */
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 1806 of yacc.c */
#line 137 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_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 1806 of yacc.c */
#line 147 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 4:
/* Line 1806 of yacc.c */
#line 148 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(2) - (2)].str));}
break;
case 5:
/* Line 1806 of yacc.c */
#line 151 "ASN1.y"
{strcpy((yyval.str),"-");
strcat((yyval.str),(yyvsp[(2) - (2)].str));}
break;
case 6:
/* Line 1806 of yacc.c */
#line 155 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 7:
/* Line 1806 of yacc.c */
#line 156 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 8:
/* Line 1806 of yacc.c */
#line 159 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 9:
/* Line 1806 of yacc.c */
#line 160 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 10:
/* Line 1806 of yacc.c */
#line 163 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 11:
/* Line 1806 of yacc.c */
#line 164 "ASN1.y"
{strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
break;
case 12:
/* Line 1806 of yacc.c */
#line 167 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
_asn1_set_value((yyval.node),(yyvsp[(2) - (3)].str),strlen((yyvsp[(2) - (3)].str))+1);}
break;
case 13:
/* Line 1806 of yacc.c */
#line 169 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_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 1806 of yacc.c */
#line 174 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 15:
/* Line 1806 of yacc.c */
#line 175 "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 1806 of yacc.c */
#line 179 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_CONSTANT);
_asn1_set_value((yyval.node),(yyvsp[(1) - (1)].str),strlen((yyvsp[(1) - (1)].str))+1);}
break;
case 17:
/* Line 1806 of yacc.c */
#line 181 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_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 1806 of yacc.c */
#line 186 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 19:
/* Line 1806 of yacc.c */
#line 187 "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 1806 of yacc.c */
#line 191 "ASN1.y"
{(yyval.constant)=CONST_UNIVERSAL;}
break;
case 21:
/* Line 1806 of yacc.c */
#line 192 "ASN1.y"
{(yyval.constant)=CONST_PRIVATE;}
break;
case 22:
/* Line 1806 of yacc.c */
#line 193 "ASN1.y"
{(yyval.constant)=CONST_APPLICATION;}
break;
case 23:
/* Line 1806 of yacc.c */
#line 196 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TAG);
_asn1_set_value((yyval.node),(yyvsp[(2) - (3)].str),strlen((yyvsp[(2) - (3)].str))+1);}
break;
case 24:
/* Line 1806 of yacc.c */
#line 198 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TAG | (yyvsp[(2) - (4)].constant));
_asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
break;
case 25:
/* Line 1806 of yacc.c */
#line 202 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 26:
/* Line 1806 of yacc.c */
#line 203 "ASN1.y"
{(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_EXPLICIT);}
break;
case 27:
/* Line 1806 of yacc.c */
#line 204 "ASN1.y"
{(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_IMPLICIT);}
break;
case 28:
/* Line 1806 of yacc.c */
#line 207 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_DEFAULT);
_asn1_set_value((yyval.node),(yyvsp[(2) - (2)].str),strlen((yyvsp[(2) - (2)].str))+1);}
break;
case 29:
/* Line 1806 of yacc.c */
#line 209 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_DEFAULT|CONST_TRUE);}
break;
case 30:
/* Line 1806 of yacc.c */
#line 210 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_DEFAULT|CONST_FALSE);}
break;
case 33:
/* Line 1806 of yacc.c */
#line 219 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_INTEGER);}
break;
case 34:
/* Line 1806 of yacc.c */
#line 220 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_LIST);
_asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
break;
case 35:
/* Line 1806 of yacc.c */
#line 222 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_INTEGER);}
break;
case 36:
/* Line 1806 of yacc.c */
#line 224 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_INTEGER|CONST_MIN_MAX);
_asn1_set_down((yyval.node),_asn1_add_static_node(ASN1_ETYPE_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 1806 of yacc.c */
#line 230 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BOOLEAN);}
break;
case 38:
/* Line 1806 of yacc.c */
#line 233 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UTC_TIME);}
break;
case 39:
/* Line 1806 of yacc.c */
#line 234 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_GENERALIZED_TIME);}
break;
case 40:
/* Line 1806 of yacc.c */
#line 237 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SIZE|CONST_1_PARAM);
_asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
break;
case 41:
/* Line 1806 of yacc.c */
#line 240 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_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 1806 of yacc.c */
#line 245 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 43:
/* Line 1806 of yacc.c */
#line 246 "ASN1.y"
{(yyval.node)=(yyvsp[(2) - (3)].node);}
break;
case 44:
/* Line 1806 of yacc.c */
#line 249 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_GENERALSTRING);}
break;
case 45:
/* Line 1806 of yacc.c */
#line 250 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_GENERALSTRING|CONST_SIZE);
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
break;
case 46:
/* Line 1806 of yacc.c */
#line 254 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_UNIVERSAL);}
break;
case 47:
/* Line 1806 of yacc.c */
#line 255 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_NUMERIC_STRING|CONST_SIZE);
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
break;
case 48:
/* Line 1806 of yacc.c */
#line 259 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING);}
break;
case 49:
/* Line 1806 of yacc.c */
#line 260 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_IA5_STRING|CONST_SIZE);
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
break;
case 50:
/* Line 1806 of yacc.c */
#line 264 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING);}
break;
case 51:
/* Line 1806 of yacc.c */
#line 265 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_TELETEX_STRING|CONST_SIZE);
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
break;
case 52:
/* Line 1806 of yacc.c */
#line 269 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING);}
break;
case 53:
/* Line 1806 of yacc.c */
#line 270 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_PRINTABLE_STRING|CONST_SIZE);
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
break;
case 54:
/* Line 1806 of yacc.c */
#line 274 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING);}
break;
case 55:
/* Line 1806 of yacc.c */
#line 275 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UNIVERSAL_STRING|CONST_SIZE);
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
break;
case 56:
/* Line 1806 of yacc.c */
#line 279 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING);}
break;
case 57:
/* Line 1806 of yacc.c */
#line 280 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BMP_STRING|CONST_SIZE);
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
break;
case 58:
/* Line 1806 of yacc.c */
#line 284 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING);}
break;
case 59:
/* Line 1806 of yacc.c */
#line 285 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_UTF8_STRING|CONST_SIZE);
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
break;
case 60:
/* Line 1806 of yacc.c */
#line 289 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING);}
break;
case 61:
/* Line 1806 of yacc.c */
#line 290 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_VISIBLE_STRING|CONST_SIZE);
_asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
break;
case 62:
/* Line 1806 of yacc.c */
#line 294 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OCTET_STRING);}
break;
case 63:
/* Line 1806 of yacc.c */
#line 295 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OCTET_STRING|CONST_SIZE);
_asn1_set_down((yyval.node),(yyvsp[(3) - (3)].node));}
break;
case 64:
/* Line 1806 of yacc.c */
#line 299 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_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 65:
/* Line 1806 of yacc.c */
#line 304 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 66:
/* Line 1806 of yacc.c */
#line 305 "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 67:
/* Line 1806 of yacc.c */
#line 309 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING);}
break;
case 68:
/* Line 1806 of yacc.c */
#line 310 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING|CONST_SIZE);}
break;
case 69:
/* Line 1806 of yacc.c */
#line 312 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_BIT_STRING|CONST_LIST);
_asn1_set_down((yyval.node),(yyvsp[(4) - (5)].node));}
break;
case 70:
/* Line 1806 of yacc.c */
#line 317 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_ENUMERATED|CONST_LIST);
_asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
break;
case 71:
/* Line 1806 of yacc.c */
#line 322 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);}
break;
case 72:
/* Line 1806 of yacc.c */
#line 325 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_IDENTIFIER);
_asn1_set_value((yyval.node),(yyvsp[(1) - (1)].str),strlen((yyvsp[(1) - (1)].str))+1);}
break;
case 73:
/* Line 1806 of yacc.c */
#line 327 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_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 74:
/* Line 1806 of yacc.c */
#line 330 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 75:
/* Line 1806 of yacc.c */
#line 331 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 76:
/* Line 1806 of yacc.c */
#line 332 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 78:
/* Line 1806 of yacc.c */
#line 334 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 79:
/* Line 1806 of yacc.c */
#line 335 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 80:
/* Line 1806 of yacc.c */
#line 336 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 81:
/* Line 1806 of yacc.c */
#line 337 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 82:
/* Line 1806 of yacc.c */
#line 338 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 83:
/* Line 1806 of yacc.c */
#line 339 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 84:
/* Line 1806 of yacc.c */
#line 340 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 85:
/* Line 1806 of yacc.c */
#line 341 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 86:
/* Line 1806 of yacc.c */
#line 342 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 87:
/* Line 1806 of yacc.c */
#line 343 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 88:
/* Line 1806 of yacc.c */
#line 344 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 89:
/* Line 1806 of yacc.c */
#line 345 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 90:
/* Line 1806 of yacc.c */
#line 346 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 91:
/* Line 1806 of yacc.c */
#line 347 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 92:
/* Line 1806 of yacc.c */
#line 348 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 93:
/* Line 1806 of yacc.c */
#line 349 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 94:
/* Line 1806 of yacc.c */
#line 350 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_NULL);}
break;
case 95:
/* Line 1806 of yacc.c */
#line 353 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 96:
/* Line 1806 of yacc.c */
#line 354 "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 97:
/* Line 1806 of yacc.c */
#line 359 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 98:
/* Line 1806 of yacc.c */
#line 360 "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 99:
/* Line 1806 of yacc.c */
#line 363 "ASN1.y"
{(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_OPTION);}
break;
case 100:
/* Line 1806 of yacc.c */
#line 366 "ASN1.y"
{(yyval.node)=_asn1_set_name((yyvsp[(2) - (2)].node),(yyvsp[(1) - (2)].str));}
break;
case 101:
/* Line 1806 of yacc.c */
#line 369 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 102:
/* Line 1806 of yacc.c */
#line 370 "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 103:
/* Line 1806 of yacc.c */
#line 374 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE);
_asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
break;
case 104:
/* Line 1806 of yacc.c */
#line 376 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SEQUENCE_OF);
_asn1_set_down((yyval.node),(yyvsp[(3) - (3)].node));}
break;
case 105:
/* Line 1806 of yacc.c */
#line 378 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_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 106:
/* Line 1806 of yacc.c */
#line 383 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SET);
_asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
break;
case 107:
/* Line 1806 of yacc.c */
#line 385 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_SET_OF);
_asn1_set_down((yyval.node),(yyvsp[(3) - (3)].node));}
break;
case 108:
/* Line 1806 of yacc.c */
#line 387 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_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 109:
/* Line 1806 of yacc.c */
#line 392 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_CHOICE);
_asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
break;
case 110:
/* Line 1806 of yacc.c */
#line 396 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_ANY);}
break;
case 111:
/* Line 1806 of yacc.c */
#line 397 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_ANY|CONST_DEFINED_BY);
_asn1_set_down((yyval.node),_asn1_add_static_node(ASN1_ETYPE_CONSTANT));
_asn1_set_name(_asn1_get_down((yyval.node)),(yyvsp[(4) - (4)].str));}
break;
case 112:
/* Line 1806 of yacc.c */
#line 402 "ASN1.y"
{(yyval.node)=_asn1_set_name((yyvsp[(3) - (3)].node),(yyvsp[(1) - (3)].str));}
break;
case 113:
/* Line 1806 of yacc.c */
#line 404 "ASN1.y"
{(yyval.node)=_asn1_set_name((yyvsp[(3) - (3)].node), last_error_token);}
break;
case 114:
/* Line 1806 of yacc.c */
#line 408 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID|CONST_ASSIGN);
_asn1_set_name((yyval.node),(yyvsp[(1) - (7)].str));
_asn1_set_down((yyval.node),(yyvsp[(6) - (7)].node));}
break;
case 115:
/* Line 1806 of yacc.c */
#line 412 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_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 116:
/* Line 1806 of yacc.c */
#line 417 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_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 117:
/* Line 1806 of yacc.c */
#line 422 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 118:
/* Line 1806 of yacc.c */
#line 423 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 119:
/* Line 1806 of yacc.c */
#line 426 "ASN1.y"
{(yyval.node)=(yyvsp[(1) - (1)].node);}
break;
case 120:
/* Line 1806 of yacc.c */
#line 427 "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 121:
/* Line 1806 of yacc.c */
#line 431 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
_asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));
_asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));}
break;
case 122:
/* Line 1806 of yacc.c */
#line 434 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
_asn1_set_name((yyval.node),(yyvsp[(1) - (3)].str));}
break;
case 123:
/* Line 1806 of yacc.c */
#line 436 "ASN1.y"
{(yyval.node)=_asn1_add_static_node(ASN1_ETYPE_OBJECT_ID);
_asn1_set_name((yyval.node),(yyvsp[(1) - (1)].str));}
break;
case 124:
/* Line 1806 of yacc.c */
#line 460 "ASN1.y"
{(yyval.constant)=CONST_EXPLICIT;}
break;
case 125:
/* Line 1806 of yacc.c */
#line 461 "ASN1.y"
{(yyval.constant)=CONST_IMPLICIT;}
break;
/* Line 1806 of yacc.c */
#line 2648 "ASN1.c"
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
that yytoken be updated with the new translation. We take the
approach of translating immediately before every use of yytoken.
One alternative is translating here after every semantic action,
but that translation would be missed if the semantic action invokes
YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
incorrect destructor might then be invoked immediately. In the
case of YYERROR or YYBACKUP, subsequent parser actions might lead
to an incorrect destructor call or verbose syntax error message
before the lookahead is translated. */
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:
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
/* If not already recovering from an error, report this error. */
if (!yyerrstatus)
{
++yynerrs;
#if ! YYERROR_VERBOSE
yyerror (YY_("syntax error"));
#else
# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
yyssp, yytoken)
{
char const *yymsgp = YY_("syntax error");
int yysyntax_error_status;
yysyntax_error_status = YYSYNTAX_ERROR;
if (yysyntax_error_status == 0)
yymsgp = yymsg;
else if (yysyntax_error_status == 1)
{
if (yymsg != yymsgbuf)
YYSTACK_FREE (yymsg);
yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
if (!yymsg)
{
yymsg = yymsgbuf;
yymsg_alloc = sizeof yymsgbuf;
yysyntax_error_status = 2;
}
else
{
yysyntax_error_status = YYSYNTAX_ERROR;
yymsgp = yymsg;
}
}
yyerror (yymsgp);
if (yysyntax_error_status == 2)
goto yyexhaustedlab;
}
# undef YYSYNTAX_ERROR
#endif
}
if (yyerrstatus == 3)
{
/* If just tried and failed to reuse lookahead 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 lookahead 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 (!yypact_value_is_default (yyn))
{
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);
}
*++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;
#if !defined(yyoverflow) || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here. |
`-------------------------------------------------*/
yyexhaustedlab:
yyerror (YY_("memory exhausted"));
yyresult = 2;
/* Fall through. */
#endif
yyreturn:
if (yychar != YYEMPTY)
{
/* Make sure we have latest lookahead translation. See comments at
user semantic actions for why this is necessary. */
yytoken = YYTRANSLATE (yychar);
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_any_defined_by | 41 | 101 | 211 | decoding.c |
int
asn1_expand_any_defined_by (asn1_node definitions, asn1_node * element)
{
char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
value[ASN1_MAX_NAME_SIZE];
int retCode = ASN1_SUCCESS, result;
int len, len2, len3;
asn1_node p, p2, p3, aux = NULL;
char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
if ((definitions == NULL) || (*element == NULL))
return ASN1_ELEMENT_NOT_FOUND;
strcpy (definitionsName, definitions->name);
strcat (definitionsName, ".");
p = *element;
while (p)
{
switch (type_field (p->type))
{
case ASN1_ETYPE_ANY:
if ((p->type & CONST_DEFINED_BY) && (p->value))
{
/* search the "DEF_BY" element */
p2 = p->down;
while ((p2) && (type_field (p2->type) != ASN1_ETYPE_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 (!(strcmp (p3->name, p2->name)))
break;
p3 = p3->right;
}
if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_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 (!(strcmp (p3->name, p2->name)))
break;
p3 = p3->right;
}
if ((!p3) || (type_field (p3->type) != ASN1_ETYPE_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) == ASN1_ETYPE_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)
&& (!_asn1_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_cpy_name (aux, p);
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 = NULL;
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_extract_tag_der | 40 | 76 | 171 | decoding.c |
static int
_asn1_extract_tag_der (asn1_node node, const unsigned char *der, int der_len,
int *ret_len)
{
asn1_node 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) == ASN1_ETYPE_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) == ASN1_ETYPE_SEQUENCE) ||
(type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF)
|| (type_field (node->type) == ASN1_ETYPE_SET)
|| (type_field (node->type) == ASN1_ETYPE_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) == ASN1_ETYPE_OCTET_STRING)
{
class_implicit |= ASN1_CLASS_STRUCTURED;
if ((class != class_implicit) || (tag != tag_implicit))
return ASN1_TAG_ERROR;
}
else
return ASN1_TAG_ERROR;
}
}
else
{
unsigned type = type_field (node->type);
if (type == ASN1_ETYPE_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)
{
case ASN1_ETYPE_NULL:
case ASN1_ETYPE_BOOLEAN:
case ASN1_ETYPE_INTEGER:
case ASN1_ETYPE_ENUMERATED:
case ASN1_ETYPE_OBJECT_ID:
case ASN1_ETYPE_GENERALSTRING:
case ASN1_ETYPE_NUMERIC_STRING:
case ASN1_ETYPE_IA5_STRING:
case ASN1_ETYPE_TELETEX_STRING:
case ASN1_ETYPE_PRINTABLE_STRING:
case ASN1_ETYPE_UNIVERSAL_STRING:
case ASN1_ETYPE_BMP_STRING:
case ASN1_ETYPE_UTF8_STRING:
case ASN1_ETYPE_VISIBLE_STRING:
case ASN1_ETYPE_BIT_STRING:
case ASN1_ETYPE_SEQUENCE:
case ASN1_ETYPE_SEQUENCE_OF:
case ASN1_ETYPE_SET:
case ASN1_ETYPE_SET_OF:
case ASN1_ETYPE_GENERALIZED_TIME:
case ASN1_ETYPE_UTC_TIME:
if ((class != _asn1_tags[type].class)
|| (tag != _asn1_tags[type].tag))
return ASN1_DER_ERROR;
break;
case ASN1_ETYPE_OCTET_STRING:
/* OCTET STRING is handled differently to allow
* BER encodings (structured class). */
if (((class != ASN1_CLASS_UNIVERSAL)
&& (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
|| (tag != ASN1_TAG_OCTET_STRING))
return ASN1_DER_ERROR;
break;
case ASN1_ETYPE_ANY:
counter -= len2;
break;
default:
return ASN1_DER_ERROR;
break;
}
}
counter += len2;
*ret_len = counter;
return ASN1_SUCCESS;
}
|
|||||
| ↓ | asn1_read_value_type | 36 | 83 | 170 | element.c |
int
asn1_read_value_type (asn1_node root, const char *name, void *ivalue,
int *len, unsigned int *etype)
{
asn1_node node, p, p2;
int len2, len3;
int value_size = *len;
unsigned char *value = ivalue;
unsigned type;
node = asn1_find_node (root, name);
if (node == NULL)
return ASN1_ELEMENT_NOT_FOUND;
type = type_field (node->type);
if ((type != ASN1_ETYPE_NULL) &&
(type != ASN1_ETYPE_CHOICE) &&
!(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
(node->value == NULL))
return ASN1_VALUE_NOT_FOUND;
if (etype)
*etype = type;
switch (type)
{
case ASN1_ETYPE_NULL:
PUT_STR_VALUE (value, value_size, "NULL");
break;
case ASN1_ETYPE_BOOLEAN:
if ((node->type & CONST_DEFAULT) && (node->value == NULL))
{
p = node->down;
while (type_field (p->type) != ASN1_ETYPE_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 ASN1_ETYPE_INTEGER:
case ASN1_ETYPE_ENUMERATED:
if ((node->type & CONST_DEFAULT) && (node->value == NULL))
{
p = node->down;
while (type_field (p->type) != ASN1_ETYPE_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) == ASN1_ETYPE_CONSTANT)
{
if (!_asn1_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 ASN1_ETYPE_OBJECT_ID:
if (node->type & CONST_ASSIGN)
{
value[0] = 0;
p = node->down;
while (p)
{
if (type_field (p->type) == ASN1_ETYPE_CONSTANT)
{
ADD_STR_VALUE (value, value_size, p->value);
if (p->right)
{
ADD_STR_VALUE (value, value_size, ".");
}
}
p = p->right;
}
*len = _asn1_strlen (value) + 1;
}
else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
{
p = node->down;
while (type_field (p->type) != ASN1_ETYPE_DEFAULT)
p = p->right;
PUT_STR_VALUE (value, value_size, p->value);
}
else
{
PUT_STR_VALUE (value, value_size, node->value);
}
break;
case ASN1_ETYPE_GENERALIZED_TIME:
case ASN1_ETYPE_UTC_TIME:
PUT_AS_STR_VALUE (value, value_size, node->value, node->value_len);
break;
case ASN1_ETYPE_OCTET_STRING:
case ASN1_ETYPE_GENERALSTRING:
case ASN1_ETYPE_NUMERIC_STRING:
case ASN1_ETYPE_IA5_STRING:
case ASN1_ETYPE_TELETEX_STRING:
case ASN1_ETYPE_PRINTABLE_STRING:
case ASN1_ETYPE_UNIVERSAL_STRING:
case ASN1_ETYPE_BMP_STRING:
case ASN1_ETYPE_UTF8_STRING:
case ASN1_ETYPE_VISIBLE_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 ASN1_ETYPE_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 ASN1_ETYPE_CHOICE:
PUT_STR_VALUE (value, value_size, node->down->name);
break;
case ASN1_ETYPE_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 | 27 | 52 | 94 | parser_aux.c |
int
_asn1_check_identifier (asn1_node node)
{
asn1_node 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) == ASN1_ETYPE_IDENTIFIER)
{
_asn1_str_cpy (name2, sizeof (name2), node->name);
_asn1_str_cat (name2, sizeof (name2), ".");
_asn1_str_cat (name2, sizeof (name2), (char *) p->value);
p2 = asn1_find_node (node, name2);
if (p2 == NULL)
{
if (p->value)
_asn1_strcpy (_asn1_identifierMissing, p->value);
else
_asn1_strcpy (_asn1_identifierMissing, "(null)");
return ASN1_IDENTIFIER_NOT_FOUND;
}
}
else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
(p->type & CONST_DEFAULT))
{
p2 = p->down;
if (p2 && (type_field (p2->type) == ASN1_ETYPE_DEFAULT))
{
_asn1_str_cpy (name2, sizeof (name2), node->name);
_asn1_str_cat (name2, sizeof (name2), ".");
_asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
_asn1_strcpy (_asn1_identifierMissing, p2->value);
p2 = asn1_find_node (node, name2);
if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) ||
!(p2->type & CONST_ASSIGN))
return ASN1_IDENTIFIER_NOT_FOUND;
else
_asn1_identifierMissing[0] = 0;
}
}
else if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) &&
(p->type & CONST_ASSIGN))
{
p2 = p->down;
if (p2 && (type_field (p2->type) == ASN1_ETYPE_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), (char *) p2->value);
_asn1_strcpy (_asn1_identifierMissing, p2->value);
p2 = asn1_find_node (node, name2);
if (!p2 || (type_field (p2->type) != ASN1_ETYPE_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 | 66 | 105 | structure.c |
static int
_asn1_expand_identifier (asn1_node * node, asn1_node root)
{
asn1_node 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) == ASN1_ETYPE_IDENTIFIER)
{
snprintf (name2, sizeof (name2), "%s.%s", root->name, p->value);
p2 = _asn1_copy_structure2 (root, name2);
if (p2 == NULL)
{
return ASN1_IDENTIFIER_NOT_FOUND;
}
_asn1_cpy_name (p2, p);
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 | coding.c |
static void
_asn1_ordering_set_of (unsigned char *der, int der_len, asn1_node node)
{
struct vet
{
int end;
struct vet *next, *prev;
};
int counter, len, len2, change;
struct vet *first, *last, *p_vet, *p2_vet;
asn1_node p;
unsigned char *temp, class;
unsigned long k, max;
counter = 0;
if (type_field (node->type) != ASN1_ETYPE_SET_OF)
return;
p = node->down;
while ((type_field (p->type) == ASN1_ETYPE_TAG)
|| (type_field (p->type) == ASN1_ETYPE_SIZE))
p = p->right;
p = p->right;
if ((p == NULL) || (p->right == NULL))
return;
first = last = NULL;
while (p)
{
p_vet = 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 = 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);
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;
free (p_vet);
p_vet = first;
}
}
|
|||||
| ↓ | asn1_expand_octet_string | 22 | 65 | 123 | decoding.c |
int
asn1_expand_octet_string (asn1_node definitions, asn1_node * element,
const char *octetName, const char *objectName)
{
char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
int retCode = ASN1_SUCCESS, result;
int len, len2, len3;
asn1_node p2, aux = NULL;
asn1_node octetNode = NULL, objectNode = NULL;
char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
if ((definitions == NULL) || (*element == NULL))
return ASN1_ELEMENT_NOT_FOUND;
octetNode = asn1_find_node (*element, octetName);
if (octetNode == NULL)
return ASN1_ELEMENT_NOT_FOUND;
if (type_field (octetNode->type) != ASN1_ETYPE_OCTET_STRING)
return ASN1_ELEMENT_NOT_FOUND;
if (octetNode->value == NULL)
return ASN1_VALUE_NOT_FOUND;
objectNode = asn1_find_node (*element, objectName);
if (objectNode == NULL)
return ASN1_ELEMENT_NOT_FOUND;
if (type_field (objectNode->type) != ASN1_ETYPE_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) == ASN1_ETYPE_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)
&& (!_asn1_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_cpy_name (aux, octetNode);
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 = NULL;
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;
}
|
|||||
| ↓ | yysyntax_error | 22 | 54 | 127 | ASN1.c |
static int
yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
yytype_int16 *yyssp, int yytoken)
{
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
YYSIZE_T yysize = yysize0;
YYSIZE_T yysize1;
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
/* Internationalized format string. */
const char *yyformat = 0;
/* Arguments of yyformat. */
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
/* Number of reported tokens (one for the "unexpected", one per
"expected"). */
int yycount = 0;
/* There are many possibilities here to consider:
- Assume YYFAIL is not used. It's too flawed to consider. See
|
|||||
| ↓ | asn1_find_node | 21 | 58 | 106 | parser_aux.c |
asn1_node
asn1_find_node (asn1_node pointer, const char *name)
{
asn1_node p;
char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
const char *n_start;
unsigned int nsize;
unsigned int nhash;
if (pointer == NULL)
return NULL;
if (name == NULL)
return NULL;
p = pointer;
n_start = name;
if (p->name[0] != 0)
{ /* has *pointer got a name ? */
n_end = strchr (n_start, '.'); /* search the first dot */
if (n_end)
{
nsize = n_end - n_start;
memcpy (n, n_start, nsize);
n[nsize] = 0;
n_start = n_end;
n_start++;
nhash = hash_pjw_bare (n, nsize);
}
else
{
nsize = _asn1_str_cpy (n, sizeof (n), n_start);
nhash = hash_pjw_bare (n, nsize);
n_start = NULL;
}
while (p)
{
if ((p->name) && nhash == p->name_hash && (!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)
{
nsize = n_end - n_start;
memcpy (n, n_start, nsize);
n[nsize] = 0;
n_start = n_end;
n_start++;
nhash = hash_pjw_bare (n, nsize);
}
else
{
nsize = _asn1_str_cpy (n, sizeof (n), n_start);
nhash = hash_pjw_bare (n, nsize);
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_hash == nhash && !strcmp (p->name, n))
break;
else
p = p->right;
}
if (p == NULL)
return NULL;
}
} /* while */
return p;
}
|
|||||
| ↓ | asn1_array2tree | 21 | 55 | 100 | structure.c |
int
asn1_array2tree (const asn1_static_node * array, asn1_node * definitions,
char *errorDescription)
{
asn1_node p, p_last = NULL;
unsigned long k;
int move;
int result;
unsigned int type;
if (*definitions != NULL)
return ASN1_ELEMENT_NOT_EMPTY;
move = UP;
k = 0;
while (array[k].value || array[k].type || array[k].name)
{
type = convert_old_type (array[k].type);
p = _asn1_add_static_node (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 (type & CONST_DOWN)
move = DOWN;
else if (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 = NULL;
}
else
_asn1_delete_list ();
return result;
}
|
|||||
| ↓ | _asn1_type_choice_config | 20 | 47 | 84 | structure.c |
static int
_asn1_type_choice_config (asn1_node node)
{
asn1_node 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) == ASN1_ETYPE_CHOICE)
&& (p->type & CONST_TAG))
{
p2 = p->down;
while (p2)
{
if (type_field (p2->type) != ASN1_ETYPE_TAG)
{
p2->type |= CONST_TAG;
p3 = _asn1_find_left (p2);
while (p3)
{
if (type_field (p3->type) == ASN1_ETYPE_TAG)
{
p4 = _asn1_add_single_node (p3->type);
tlen = _asn1_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) == ASN1_ETYPE_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_insert_tag_der | 19 | 50 | 100 | coding.c |
static int
_asn1_insert_tag_der (asn1_node node, unsigned char *der, int *counter,
int *max_len)
{
asn1_node p;
int tag_len, is_tag_implicit;
unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
unsigned long tag_implicit = 0;
unsigned 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) == ASN1_ETYPE_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,
_asn1_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, (char *) temp);
_asn1_set_name (p, (const char *) temp);
is_tag_implicit = 0;
}
else
{ /* CONST_IMPLICIT */
if (!is_tag_implicit)
{
if ((type_field (node->type) == ASN1_ETYPE_SEQUENCE) ||
(type_field (node->type) == ASN1_ETYPE_SEQUENCE_OF)
|| (type_field (node->type) == ASN1_ETYPE_SET)
|| (type_field (node->type) == ASN1_ETYPE_SET_OF))
class |= ASN1_CLASS_STRUCTURED;
class_implicit = class;
tag_implicit = _asn1_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
{
unsigned type = type_field (node->type);
switch (type)
{
CASE_HANDLED_ETYPES:
_asn1_tag_der (_asn1_tags[type].class, _asn1_tags[type].tag,
tag_der, &tag_len);
break;
case ASN1_ETYPE_TAG:
case ASN1_ETYPE_CHOICE:
case ASN1_ETYPE_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_ordering_set | 16 | 59 | 104 | coding.c |
static void
_asn1_ordering_set (unsigned char *der, int der_len, asn1_node 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_node p;
unsigned char class, *temp;
unsigned long tag;
counter = 0;
if (type_field (node->type) != ASN1_ETYPE_SET)
return;
p = node->down;
while ((type_field (p->type) == ASN1_ETYPE_TAG)
|| (type_field (p->type) == ASN1_ETYPE_SIZE))
p = p->right;
if ((p == NULL) || (p->right == NULL))
return;
first = last = NULL;
while (p)
{
p_vet = 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 = 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);
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;
free (p_vet);
p_vet = first;
}
}
|
|||||
| ↓ | _asn1_get_octet_string | 16 | 44 | 79 | decoding.c |
static int
_asn1_get_octet_string (const unsigned char *der, asn1_node 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);
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;
counter = len3 + len2;
if (node)
_asn1_set_value (node, der, counter);
}
*len = counter;
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_convert_integer | 15 | 35 | 50 | element.c |
int
_asn1_convert_integer (const unsigned 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 = _asn1_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];
#if 0
printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
printf (", vOut[%d]=%d", k, value_out[k]);
printf ("\n");
#endif
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_objectid_der | 14 | 46 | 71 | coding.c |
static int
_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;
int str_len = _asn1_strlen (str);
max_len = *der_len;
temp = malloc (str_len + 2);
if (temp == NULL)
return ASN1_MEM_ALLOC_ERROR;
memcpy (temp, str, str_len);
temp[str_len] = '.';
temp[str_len + 1] = 0;
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;
free (temp);
if (max_len < (*der_len))
return ASN1_MEM_ERROR;
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_get_objectid_der | 14 | 38 | 61 | decoding.c |
static int
_asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
char *str, int str_size)
{
int len_len, len, k;
int leading;
char temp[20];
unsigned long val, val1;
*ret_len = 0;
if (str && str_size > 0)
str[0] = 0; /* no oid */
if (str == NULL || der_len <= 0)
return ASN1_GENERIC_ERROR;
len = asn1_get_length_der (der, der_len, &len_len);
if (len < 0 || len > der_len || len_len > der_len)
return ASN1_DER_ERROR;
val1 = der[len_len] / 40;
val = der[len_len] - val1 * 40;
_asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
_asn1_str_cat (str, str_size, ".");
_asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
val = 0;
leading = 1;
for (k = 1; k < len; k++)
{
/* X.690 mandates that the leading byte must never be 0x80
*/
if (leading != 0 && der[len_len + k] == 0x80)
return ASN1_DER_ERROR;
leading = 0;
/* check for wrap around */
if (INT_LEFT_SHIFT_OVERFLOW (val, 7))
return ASN1_DER_ERROR;
val = val << 7;
val |= der[len_len + k] & 0x7F;
if (!(der[len_len + k] & 0x80))
{
_asn1_str_cat (str, str_size, ".");
_asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
val = 0;
leading = 1;
}
}
if (INT_ADD_OVERFLOW (len, len_len))
return ASN1_DER_ERROR;
*ret_len = len + len_len;
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_type_set_config | 14 | 30 | 58 | parser_aux.c |
int
_asn1_type_set_config (asn1_node node)
{
asn1_node 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) == ASN1_ETYPE_SET)
{
p2 = p->down;
while (p2)
{
if (type_field (p2->type) != ASN1_ETYPE_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_read_tag | 13 | 31 | 64 | element.c |
int
asn1_read_tag (asn1_node root, const char *name, int *tagValue,
int *classValue)
{
asn1_node 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) == ASN1_ETYPE_TAG)
{
if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
pTag = p;
else if (p->type & CONST_EXPLICIT)
pTag = NULL;
}
p = p->right;
}
}
if (pTag)
{
*tagValue = _asn1_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
{
unsigned type = type_field (node->type);
*classValue = ASN1_CLASS_UNIVERSAL;
switch (type)
{
CASE_HANDLED_ETYPES:
*tagValue = _asn1_tags[type].tag;
break;
case ASN1_ETYPE_TAG:
case ASN1_ETYPE_CHOICE:
case ASN1_ETYPE_ANY:
*tagValue = -1;
break;
default:
break;
}
}
return ASN1_SUCCESS;
}
|
|||||
| ↓ | asn1_get_tag_der | 13 | 31 | 54 | decoding.c |
int
asn1_get_tag_der (const unsigned char *der, int der_len,
unsigned char *cls, int *len, unsigned long *tag)
{
unsigned int ris;
int punt;
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)
{
if (INT_MULTIPLY_OVERFLOW (ris, 128))
return ASN1_DER_ERROR;
ris *= 128;
if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
return ASN1_DER_ERROR;
ris += (der[punt] & 0x7F);
punt++;
}
if (punt >= der_len)
return ASN1_DER_ERROR;
if (INT_MULTIPLY_OVERFLOW (ris, 128))
return ASN1_DER_ERROR;
ris *= 128;
if (INT_ADD_OVERFLOW (ris, ((unsigned) (der[punt] & 0x7F))))
return ASN1_DER_ERROR;
ris += (der[punt] & 0x7F);
punt++;
*len = punt;
}
if (tag)
*tag = ris;
return ASN1_SUCCESS;
}
|
|||||
| ↓ | _asn1_delete_not_used | 13 | 30 | 58 | decoding.c |
static int
_asn1_delete_not_used (asn1_node node)
{
asn1_node 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 | parser_aux.c |
int
_asn1_set_default_tag (asn1_node node)
{
asn1_node p;
if ((node == NULL) || (type_field (node->type) != ASN1_ETYPE_DEFINITIONS))
return ASN1_ELEMENT_NOT_FOUND;
p = node;
while (p)
{
if ((type_field (p->type) == ASN1_ETYPE_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 | structure.c |
int
_asn1_create_static_structure (asn1_node pointer, char *output_file_name,
char *vector_name)
{
FILE *file;
asn1_node 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_change_integer_value | 12 | 28 | 57 | parser_aux.c |
int
_asn1_change_integer_value (asn1_node node)
{
asn1_node 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) == ASN1_ETYPE_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_length_der | 11 | 30 | 55 | decoding.c |
long
asn1_get_length_der (const unsigned char *der, int der_len, int *len)
{
unsigned int ans;
int k, punt, sum;
*len = 0;
if (der_len <= 0)
return 0;
if (!(der[0] & 128))
{
/* short form */
*len = 1;
ans = der[0];
}
else
{
/* Long form */
k = der[0] & 0x7F;
punt = 1;
if (k)
{ /* definite length method */
ans = 0;
while (punt <= k && punt < der_len)
{
if (INT_MULTIPLY_OVERFLOW (ans, 256))
return -2;
ans *= 256;
if (INT_ADD_OVERFLOW (ans, ((unsigned) der[punt])))
return -2;
ans += der[punt];
punt++;
}
}
else
{ /* indefinite length method */
*len = punt;
return -1;
}
*len = punt;
}
sum = ans;
if (ans >= INT_MAX || INT_ADD_OVERFLOW (sum, (*len)))
return -2;
sum += *len;
if (sum > der_len)
return -4;
return ans;
}
|
|||||
| _asn1_yyerror | 10 | 9 | 32 | ASN1.c | |
| _asn1_get_indefinite_length_string | 10 | 27 | 49 | decoding.c | |
| _asn1_complete_explicit_tag | 10 | 26 | 56 | coding.c | |
| _asn1_copy_structure3 | 9 | 33 | 56 | structure.c | |
| asn1_decode_simple_der | 9 | 27 | 44 | decoding.c | |
| asn1_find_structure_from_oid | 9 | 23 | 43 | structure.c | |
| asn1_parser2array | 8 | 47 | 107 | ASN1.c | |
| asn1_delete_structure | 8 | 25 | 50 | structure.c | |
| yytnamerr | 8 | 20 | 38 | ASN1.c | |
| asn1_encode_simple_der | 7 | 24 | 42 | coding.c | |
| _asn1_append_value | 7 | 22 | 39 | parser_aux.c | |
| _asn1_extract_der_octet | 7 | 20 | 44 | decoding.c | |
| _asn1_append_sequence_set | 7 | 20 | 33 | element.c | |
| _asn1_set_value | 7 | 17 | 31 | parser_aux.c | |
| asn1_length_der | 6 | 16 | 34 | coding.c | |
| asn1_parser2tree | 5 | 25 | 62 | ASN1.c | |
| asn1_copy_node | 5 | 21 | 40 | structure.c | |
| _asn1_tag_der | 5 | 16 | 32 | coding.c | |
| asn1_delete_element | 5 | 14 | 25 | structure.c | |
| asn1_number_of_elements | 5 | 13 | 25 | structure.c | |
| _asn1_set_value_m | 5 | 12 | 22 | parser_aux.c | |
| _asn1_get_time_der | 5 | 10 | 17 | decoding.c | |
| _asn1_find_up | 4 | 7 | 15 | parser_aux.c | |
| _asn1_remove_node | 4 | 5 | 10 | parser_aux.c | |
| _asn1_find_left | 4 | 3 | 8 | structure.c | |
| _asn1_ltostr | 4 | 22 | 32 | parser_aux.c | |
| _asn1_hierarchical_name | 4 | 12 | 25 | element.c | |
| asn1_get_bit_der | 4 | 12 | 25 | decoding.c | |
| _asn1_time_der | 4 | 11 | 20 | coding.c | |
| asn1_get_octet_der | 4 | 11 | 26 | decoding.c | |
| yy_symbol_value_print | 4 | 6 | 24 | ASN1.c | |
| _asn1_create_errorDescription | 3 | 12 | 31 | ASN1.c | |
| _asn1_cpy_name | 3 | 9 | 18 | parser_aux.c | |
| asn1_get_length_ber | 3 | 9 | 17 | decoding.c | |
| asn1_strerror | 3 | 7 | 11 | errors.c | |
| _asn1_get_last_right | 3 | 7 | 12 | parser_aux.c | |
| _asn1_str_cat | 3 | 7 | 19 | gstr.c | |
| _asn1_set_down | 3 | 6 | 10 | parser_aux.h | |
| _asn1_set_right | 3 | 6 | 10 | parser_aux.c | |
| asn1_octet_der | 3 | 6 | 13 | coding.c | |
| asn1_check_version | 3 | 3 | 8 | version.c | |
| _asn1_add_static_node | 3 | 14 | 25 | parser_aux.c | |
| asn1_bit_der | 3 | 13 | 21 | coding.c | |
| _asn1_str_cpy | 3 | 10 | 23 | gstr.c | |
| _asn1_set_name | 3 | 10 | 20 | parser_aux.c | |
| _asn1_set_value_lv | 3 | 10 | 17 | parser_aux.c | |
| convert_old_type | 3 | 10 | 20 | int.h | |
| yydestruct | 3 | 5 | 23 | ASN1.c | |
| yy_stack_print | 2 | 7 | 17 | ASN1.c | |
| _asn1_delete_list_and_nodes | 2 | 6 | 13 | parser_aux.c | |
| _asn1_add_single_node | 2 | 6 | 13 | structure.c | |
| yystrlen | 2 | 6 | 13 | ASN1.c | |
| _asn1_delete_list | 2 | 5 | 12 | parser_aux.c | |
| _asn1_error_description_value_not_found | 2 | 5 | 14 | coding.c | |
| yystpcpy | 2 | 5 | 17 | ASN1.c | |
| yy_symbol_print | 2 | 5 | 18 | ASN1.c | |
| _asn1_mod_type | 2 | 4 | 8 | parser_aux.h | |
| _asn1_get_right | 2 | 3 | 7 | parser_aux.h | |
| asn1_perror | 2 | 3 | 6 | errors.c | |
| _asn1_get_name | 2 | 3 | 7 | parser_aux.h | |
| _asn1_get_down | 2 | 3 | 7 | parser_aux.h | |
| asn1_create_element | 2 | 10 | 21 | structure.c | |
| yy_reduce_print | 2 | 10 | 24 | ASN1.c | |
| asn1_read_node_value | 1 | 5 | 10 | element.c | |
| _asn1_copy_structure2 | 1 | 3 | 10 | structure.c | |
| _asn1_error_description_tag_error | 1 | 3 | 10 | decoding.c | |
| asn1_read_value | 1 | 1 | 5 | element.c | |
| YYID | 1 | 1 | 10 | ASN1.c | |
| type_field | 1 | 1 | 5 | int.h | |