Layer Design

OpenXPKI tries to implement a MVC design (Model-View-Controller). The parts are defined as follows:

Model
The model is implemented by a workflow engine. This includes things like the configuration or the state handling.
Controller
The controllers are represented by the different workflow activities. Every activity can manipulate the state of a workflow including its properties.
View
The view is represented by the user interfaces. I have to admit though that the term is not fully correct. The user interface consists of several layers to get better code:
  • the service layer
  • the messaging or serialization layer
  • the transport layer

The major idea is to make the user interfaces much more flexible. It should be possible to use different transport protocol and it must also be possible to user other frontend language than Perl (e.g. PHP). The different layers are defined as follows:

  1. The service layer

    This layer parses queries, executes necessary commands and build resulting answers. The format of the queries and answers are defined by the interface itself but in the native language (Perl). This means that a message can look like this:

      my %msg = (COMMAND => "search_csr",
                 PARAMS  => {CN => "*Doe*"},
                 LIMIT   => 20);
    

    The service layer defines a communication protocol but only on the level of native Perl messages. This means that a client send the above message but the answer is:

      my %msg = (ANSWER_TYPE => "COMMAND",
                 COMMAND     => "GET_PKI_REALM",
                 PKI_REALMS  => {"root_ca" => "Our super root CA",
                                 "user_ca" => "User CA"});
    

    If this happens then the client must answer with root_ca or user_ca. Usually the next answer is the request for a login stack followed by the real login. Additionally the first answer can include a session ID. Like you see it is possible to implement a real communication protocol here. The only important thing is that we do not define any aspect of the serialization (the message representation) and the transport here.

    Please note that it is highly important that every message contains a hash key SERVICE. This is necessary to signal the receiver of a message which service should be used after the deserialization of a message.

  2. The messaging or serialization layer

    The service layer only defines how messages should look like in the used native language (Perl). This means a message is usually a hash. The serialization layer must produce now a plain text representation of this data. This can be a XML file or every other specially formatted text file. Please note that file does not mean that we write it on the disk. It is only a string in the memory.

    This layer only has to serialize datastructures and to deserialize strings. It is not the job of this layer to distinguish between different message types. This is the job of the service layer which defines the real protocol. It is possible of course that some messages are serialized another way because they carry a special flag but this makes no difference for the interface usage and behaviour of this layer.

  3. The transport layer

    The job of the transport layer is simple. It gets a plain text string and must bring this string to the other peer. The transport layer must not contain any knowledge about the communication protocol.

    The minimum interface looks like this until now:

    • new (incl. open)
    • close
    • write
    • read

    The problem is that this interface is fully synchronous. Actually I see no problem here but perhaps we must extend this interface in the future to support asynchronous mechanisms too. Nevertheless PKI is today mainly a synchronous business.

Reference Implementation

The practical handling of this protocol stack is really simple. The server gets an incoming connection. The first line of the incoming connection must be start simple. This signals the server which transport protocol must be used. After the initialization of the transport protocol the first message is read. The first message is the name of the serialization protocol. An example could be Simple. The server answers OK and the next message is parsed with the appropriate class OpenXPKI::Serialization::Simple. The parsed data structure must include a hash key SERVICE which announces the used service class.

Service Protocol

The first step is that we define a normal protocol workflow. If it is possible then we should express the whole protocol as one formula.

    session ::= (init_session|continue_session).
                use_session*.
                (stop_session|nothing)

    init_session ::= create_session_id.
                     select_pki_realm.
                     select_auth_stack.
                     login

    use_session ::= request_command.
                    (
                     token_login*.
                     send_answer*.
                    )*.
                    (answer_complete|error)

    stop_session ::= delete_session_id

This is a first abstraction for a session. Please note that this works for web clients which cut the connection everytime and for shell clients which are connected until they logout.

Serialization

Please see "perldoc OpenXPKI::Serialization::Simple" .

Transport

Please see "perldoc OpenXPKI::Transport::Simple" .

Example

Server View

Client View