## Anmeldung

Die zu speichernden Daten haben einen sehr hohen Schutzbedarf und müssen dementsprechend
verschlüsselt gespeichert und übertragen werden und brauchen eine Zugriffskontrolle. Das BSI
verlangt hierfür eine Zwei-Faktor-Authentifizierung.

Für die Anwendung wurde eine Zwei-Faktor-Authentifizierung ausgewählt, welche auf Wissen (Passwort)
und Besitz (FIDO-Key) basiert. Die Authentisierung erfolgt in folgenden Schritten (vergleiche
Abbildung \ref{fido-anmeldung-1}):

\begin{myfigure}{Der Anmeldefluss mit Nutzername, Passwort und FIDO.}{fido-anmeldung-1} \centering

\begin{sequencediagram}
   \newthread{user}{Nutzer}
   \newinst[0.5]{os}{Browser}
   \newinst[0.5]{ui}{Front-End (UI)}
   \newinst[0.5]{server}{Backend (Server)}
   \newinst[0.5]{db}{Datenbank}

   \begin{call}{user}{Zugangsdaten}{server}{Erfolgsmeldung}
      \begin{call}{server}{\shortstack{
         Anfrage der\\
         Nutzerliste
      }}{db}{Nutzerliste}
      \end{call}

      \begin{messcall}{server}{Fehlermeldung}{user}
      \end{messcall}

      \begin{call}{server}{FIDO Anfrage}{os}{FIDO Antwort}
         \begin{call}{os}{\shortstack{FIDO\\Anfrage}}{user}{\shortstack{FIDO\\Key}}
         \postlevel
         \end{call}
      \end{call}
      \postlevel

      \begin{messcall}{server}{Fehlermeldung}{user}
      \end{messcall}

      \prelevel
      \begin{messcall}{server}{\shortstack{
         Datenbank\\
         öffnen
      }}{db}
      \end{messcall}
   \end{call}

\end{sequencediagram}

\begin{footnotesize}
Der Übersichtlichkeit halber wurden einige Vermittlungsphasen rausgelassen. Die einzelnen Instanzen können nur mit dem jeweiligen Nachbarn direkt kommunizieren.
\end{footnotesize}

\end{myfigure}

1. Der Nutzer öffnet die Oberfläche in seinem Browser und wird nach Benutzername und Passwort
   gefragt. 
2. Der Server prüft, ob eine Datenbank diesen Nutzer hinterlegt hat. Wenn nein gibt es eine
   Fehlermeldung und die Authentifizierung werden abgebrochen.
3. Dann wird geprüft, ob der Wert von `SHA256(Passwort + Salt)` mit dem gespeicherten Wert
   übereinstimmt. Der Salt ist ein zufälliger Wert, welcher bei der Erstellung der Datenbank
   angelegt wurde. Falls es hier ein Fehler gab, wird dies angezeigt.
4. Die Oberfläche fragt über die WebAuthn Schnittstelle des Browsers (ist in jeden modernen Browser
   implementiert) nach dem FIDO Key. Das ist ein kleiner spezieller USB-Stick, welcher eingesteckt
   werden muss.
5. Der FIDO Key bekommt 1024 zufällige Bytes vom Server und soll diesen mit seinen lokalen privaten
   Key signieren.
6. Der Browser lieft die Signatur an die Oberfläche und diese an den Server.
7. Die Signatur wird mit dem gespeicherten Public Key geprüft. Wenn nicht gibt es wieder eine
   Fehlermeldung und ein anderer FIDO-Key wird verlangt.
8. Die Datenbank wird geöffnet.

Es können in einer Anwendung mehrere Datenbanken hinterlegt werden, bei der der Nutzer für jede
Datenbank ein anderes Passwort oder FIDO-Key nutzen kann. Am Anfang wird mit jeder Datenbank
verglichen und nach und nach werden die noch gültige Datenbank ausgesiebt, welche noch damit
angemeldet werden können. Sobald zu einem Zeitpunkt keine Datenbank mehr möglich ist, so wird dies
als Fehler ausgegeben. Am Ende können mehrere Datenbanken gleichzeitig authentifiziert werden
(sofern Nutzername, Passwort und FIDO bei allen gleich sind). Datenbanken, welche gerade nicht
geöffnet werden konnten, können auch noch nachträglich geöffnet werden. Dazu wird der Anmeldeprozess
wiederholt und schon offene Datenbanken ignoriert.

\FloatBarrier

Das Neuanlegen einer Anmeldemöglichkeit (z. B. bei Neuerzeugung einer Datenbank oder Hinzufügen eines
weiteren Nutzers) werden folgende Schritte abgehandelt (vergleiche Abbildung \ref{fido-register-1}):

\begin{myfigure}{Erstellung neuer Datenbankzugangsdaten}{fido-register-1}
\centering

\begin{sequencediagram}
   \newinst{user}{Nutzer}
   \newinst[0.5]{os}{Browser}
   \newinst[0.5]{ui}{Front-End (UI)}

   \newinst[0.5]{server}{Backend (Server)}
   \stepcounter{threadnum}
   \node[below of=inst\theinstnum,node distance=0.8cm] (thread\thethreadnum) {};
   \tikzstyle{threadcolor\thethreadnum}=[fill=gray!30]
   \tikzstyle{instcolorserver}=[fill=gray!30]

   \newinst[0.5]{db}{Datenbank}

   \begin{call}{server}{Zugangsanfrage}{db}{Ergebnis}
   \end{call}

   \begin{messcall}{server}{Fehlermeldung}{user}
   \end{messcall}

   \begin{call}{server}{Anfrage von Benutzername + Passwort}{user}{Benutzername + Passwort}
      \postlevel
   \end{call}

   \postlevel
   \begin{call}{server}{FIDO Anfrage}{os}{FIDO Antwort}
      \begin{call}{os}{\shortstack{FIDO\\Anfrage}}{user}{\shortstack{FIDO\\Key}}
      \postlevel
      \end{call}
   \end{call}
   \postlevel

   \begin{messcall}{server}{Fehlermeldung}{user}
   \end{messcall}

   \begin{messcall}{server}{Zugangsdaten}{db}
   \end{messcall}

   \prelevel\prelevel
   \begin{messcall}{server}{Erfolgsmeldung}{user}
   \end{messcall}

\end{sequencediagram}

\begin{footnotesize}
Der Übersichtlichkeit halber wurden einige Vermittlungsphasen rausgelassen. Die einzelnen Instanzen können nur mit dem jeweiligen Nachbarn direkt kommunizieren.
\end{footnotesize}

\end{myfigure}

1. Zuerst wird geprüft, ob Zugang überhaupt besteht. Bei neuen Datenbanken ist dies implizit. Bei
   bestehenden muss der Nutzer sich erneut anmelden, da der Server den Entschlüsselungs-Key nicht
   permanent im RAM hält.
2. Der Nutzer muss eine Benutzernamen und Passwort angeben und bestätigen.
3. Nutzer wird von der Oberfläche nach einen FIDO-Key gefragt.
4. Es wird der Public-Key und eine Prüfung abgefragt.
5. Der Server prüft das. Bei Misserfolg wird dies angezeigt.
6. Die Prüfsummen für die Anmeldung werden erzeugt und bei der Datenbank parallel hinterlegt.
7. Datenbank wird verbunden, sofern noch nicht geschehen.

Des Weiteren wird bei der Anmeldung nicht der eigentliche Key für die Datenbank erzeugt. Stattdessen
wird für jede Anmeldemöglichkeit der eigentliche Key für die Datenbank separat verschlüsselt und ist
nur mit dem gesalzenen Passwort aus der Anmeldung entschlüsselbar. Dadurch ist es auch relativ
einfach möglich, mehreren Nutzern Zugang zur gleichen Datenbank zu geben, ihnen zu erlauben, ihre
Passwörter zu ändern oder den Zugang wiederherzustellen, falls der mal verloren gegangen ist.

\FloatBarrier
