summaryrefslogtreecommitdiff
path: root/docs/content/implementation/c2ec.tex
blob: 089967058829323100127aed0aee21e22405e841 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
\section{C2EC}

\subsection{Decoupling steps}

To decouple different steps in the withdrawal process an event based architecture is implemented. This means that every write action to the database will represent an operation which will trigger an event. The applications processes are listening to those events. The consumer of the API can wait to be notified by the API, by registering to those events via a long polling request at the API. This long-polling will then wait until the listener receives the event and return the received event to the consumer.

Following a short list of events and from whom they are triggered and who listens to them:

\begin{itemize}
    \item Registration of the Withdrawal Operation.
    \begin{itemize}
        \item Registered by: Wallet
        \item Listened by: Terminal
    \end{itemize}
    \item Payment Confirmation sent to the Bank-Integration API of C2EC.
    \begin{itemize}
        \item Registered by: Terminal
        \item Listened by: Attestor
    \end{itemize}
    \item Payment attestation success will send a withdrawal operation status update event.
    \begin{itemize}
        \item Registered by: Attestor
        \item Listened by: Consumers (via Bank-Integration-API)
    \end{itemize}
    \item Payment attestation failure will trigger a retry event.
    \begin{itemize}
        \item Registered by: Attestor
        \item Listened by: Retrier
    \end{itemize}
\end{itemize}

\subsection{Bank-Integration API}

The Bank Integration API was implemented according to the specification \cite{taler-bank-integration-api}. It only implements messages and API specific to the indirect withdrawal operation.

Namely this are the following endpoints:

\begin{itemize}
    \item GET /config
    \item GET /withdrawal-operation/[WOPID]
    \item POST /withdrawal-operation/[WOPID]
    \item POST /withdrawal-operation/[WOPID]/payment
    \item POST /withdrawal-operation/[WOPID]/abort
\end{itemize}

\subsection{Wire-Gateway API}

The Wire-Gateway API delivers the transaction history to the exchange which will create reserves for the specific public keys and therefore allow the customers to finally withdraw the digital cash using their wallet.

Following endpoints are implemented by the wire gateway API implementation:

\begin{itemize}
    \item GET /config
    \item POST /transfer
    \item GET /history/incoming
    \item GET /history/outgoing
\end{itemize}

\subsubsection{Keeping track of transfers}

The Wire-Gateway specification requires the implementor of the API to keep track of incoming transfer requests in order to guarantee the idempotence of the API. Therefore the implementation keeps track of all transfers in the database table \textit{transfers}. It stores the transfer data in the database. If a request with the same UID is sent to the transfer-API, first it is checked that the incoming request is exactly the same as the previous one by comparing the request to the values stored in the database. Only if the hashes are the same, the transfer request is processed further. Otherwise the API responds with a conflict response.

\subsection{Payment Attestation}

The attestation of a transaction is crucial, since this is the action which allows the exchange to create a reserve and can proof to the provider and customer, that the transaction was successful and therefore can put the liability for the money on the provider. The attestation process is implemented using a provider client interface and a provider transaction interface. This allows the process to be the same for each individual provider and new providers can be added easily by providing a specific implementation of the interfaces.

\subsubsection{Provider Client}

The provider client interface is called by the attestation process depending on the notification received by the database upon receiving a payment notification of the provider's terminal. The specific provider clients are registered at the startup of the component and the attestation process will delegate the information gathering to the specific client, based on the notification received by the database.

The provider client interface defines three functions:

\begin{enumerate}
    \item SetupClient: The setup function is called by the startup of the application and used to initialize the client. Here it makes sense to check that everything needed for the specific client is in place and that properties like access credentials are available.
    \item GetTransaction: This function is used by the attestation process to retrieve the transaction of the provider system. It takes the transaction identifier supplied with the payment notification message and loads the information about the transaction. Based on this information the decision to confirm or abort the transaction is done.
    \item Refund: Since the transaction of the money itself is done by the provider, also refunds will be unwind by the provider. This functions mean is to trigger this refund transaction at the provider.
\end{enumerate}

\subsubsection{Provider Transaction}

Since the attestation process is implemented to support any provider, also the transaction received by the provider clients \textit{GetTransaction} function is abstracted using an interface. This interface must be implemented by any provider transaction which belongs to a specific provider client.

The provider client interface defines following functions:

\begin{enumerate}
    \item AllowWithdrawal: This function shall return true, when the transaction received by the provider enters a positive final state. This means that the provider accepted the transaction and could process it.
    \item AbortWithdrawal: It doesn't mean that if a transaction does not allow to do the withdrawal, that the transaction shall be cancelled immediately. It could also be that the transaction was not yet processed by the provider. In this case we need means to check if the provider transaction is in an abort state if it is not ready for withdrawal, before aborting it. AbortWithdrawal shall therefore answer the question if the provider transaction is in a negative final state, which means the transaction is to be aborted.
    \item Bytes: This function shall return a byte level representation of the transaction which will be used as proof of the transaction and stored in the exchanges database.
\end{enumerate}

\subsubsection{Retries}

If the attestation fails, but the transaction is not in the refund state as specified by the provider's transaction, the problem could simply be that the service was not available or the transaction was not yet processed by the provider's backend. In order to not need to abort the transaction directly and give the system some robustness, a retry mechanism was implemented which allows retrying the attestation step.

The retry will only be executed, when the transaction attestation failed because the transaction was not in the abort state or if for some reason the transaction information could not have been retrieved. 

\subsection{Wallee Client}

The Wallee client is the first implementation of the provider client interface and allows the attestation of transactions using the Wallee backend system. The backend of Wallee provides a ReST-API to their customers, which allows them to request information about payments, refunds and so on. To access the API, the consumer must authenticate themself to Wallee by using their own authentication token as explained in \autoref{sec-security-auth-wallee}.

As indicated by the provider client interface, we will use two API of the Wallee backend:

\begin{itemize}
    \item Transaction service: The transaction service aims to provide information about a transaction registered using a Wallee terminal.
    \item Refund service: The refund service allows to trigger a refund for a given transaction using the transaction identifier. The refund will then be executed by the Wallee backend, back to the Customer.
\end{itemize}

\subsection{Security}

\subsubsection{Authenticating at the Wallee ReST API}
\label{sec-security-auth-wallee}

The Wallee API specifies four Wallee specific headers which are used to authenticate against the API. It defines its own authentication standard and flow. The flow builds on a MAC (message authentication code) which is built on a version, user identifier, and a timestamp. For the creation of the MAC the HMAC (hash based message authentication code) SHA-512 is leveraged which takes the so called \textit{application-user-key} (which is basically just an access-token, which the user receives when creating a new API user) as key and the above mentioned properties plus information about the requested http method and the exactly requested path (including request parameters) as message \cite{wallee-api-authentication}. The format of the message is specified like: 

\begin{center}
    \texttt{Version|User-Id|Unix-Timestamp|Http-Method|Path}
\end{center}

\begin{itemize}
    \item Version: The version of the algorithm
    \item User-Id: The user-id of the requesting user
    \item Unix-Timestamp: A unix timestamp (seconds since 01.01.1970)
    \item Http-Method: one of \texttt{HEAD}, \texttt{GET}, \texttt{POST}, \texttt{PUT}, \texttt{DELETE}, \texttt{TRACE}, \texttt{CONNECT}
    \item Path: The path of the requested URL including the query string (if any)
\end{itemize}

The resulting string must then be UTF-8 encoded according to RFC-3629 \cite{rfc3629}.

\subsubsection{API access}

\textbf{Bank-Integration API}

The Bank-Integration API is accessed by Wallets and Terminals. This results in two different device types for the autentication procedure. The Wallet should be able to authenticate against the exchange by using an access token according to the specified authentication flow of the core bank API \cite{taler-bank-core-authentication} which leverages a bearer token as specified by DD-49 \cite{taler-design-document-49}. For terminals the authentication mechanism is based on a basic auth scheme as specified by RFC-7617 \cite{rfc7617}. Therefore a generated access-token used as password and a username which is generated registering the terminal using the cli explained in \autoref{sec-security-registering-providers} are leveraged.

\textbf{Wire-Gateway API}

The wire gateway specifies a basic authentication scheme \cite{taler-wire-gateway-api-authentication} as described in RFC-7617 \cite{rfc7617}. Therefore the C2EC component allows the configuration of a username and password for the exchange. During the request of the exchange at the wire gateway API, the credentials are checked.

\subsubsection{Registering Providers and Terminals}
\label{sec-security-registering-providers}

A provider may want to register a new Terminal or maybe even a new provider shall be registered for the exchange. To make this step easier for the exchange operators, a simple cli program (command line interface) was implemented. The cli will either ask for a password or generate an access token in case of the terminal registration. The credentials are stored has hashes using a PBKDF (password based key derivation function) so that even if the database leaks, the credentials cannot be easily read by an attacker.

\subsubsection{Deactivating Terminals}

A Terminal can be stolen, hijacked or hacked by malicious actors. Therefore it must be possible to disable a terminal immediately and no longer allow withdrawals using this terminal. Therefore the \textit{active} flag can be set to \textit{false} for a registered terminal. The Bank-Integration API which processes withdrawals and authenticates terminals, must check that the requesting terminal is active and is allowed to initiate withdrawals. Since the check for the \textit{active} flag must be done for each request of a terminal, the check can be centralized and is implemented as part of the authentication flow. A Wallee terminal can be deactivated using the cli mentioned in \autoref{sec-security-registering-providers}.