int s_parse_cursor()

in source/der.c [385:428]


int s_parse_cursor(struct aws_der_decoder *decoder, struct aws_byte_cursor cur) {
    if (++decoder->depth > 16) {
        /* stream contains too many nested containers, probably malformed/attack */
        return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED);
    }

    while (cur.len) {
        struct der_tlv tlv = {0};
        if (s_der_read_tlv(&cur, &tlv)) {
            return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED);
        }
        /* skip trailing newlines in the stream after any TLV */
        while (cur.len && *cur.ptr == '\n') {
            aws_byte_cursor_advance(&cur, 1);
        }
        if (aws_array_list_push_back(&decoder->tlvs, &tlv)) {
            return aws_raise_error(AWS_ERROR_INVALID_STATE);
        }
        if (decoder->container) {
            decoder->container->count++;
        }
        /* if the last element was a container, expand it recursively to maintain order */
        if (tlv.tag & AWS_DER_FORM_CONSTRUCTED) {
            struct der_tlv *outer_container = decoder->container;
            struct der_tlv *container = NULL;
            aws_array_list_get_at_ptr(&decoder->tlvs, (void **)&container, decoder->tlvs.length - 1);
            decoder->container = container;

            if (!container) {
                return aws_raise_error(AWS_ERROR_INVALID_STATE);
            }

            struct aws_byte_cursor container_cur = aws_byte_cursor_from_array(container->value, container->length);
            if (s_parse_cursor(decoder, container_cur)) {
                return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED);
            }
            decoder->container = outer_container; /* restore the container stack */
        }
    }

    --decoder->depth;

    return AWS_OP_SUCCESS;
}