VSTO 3.0 Security

Im dotNet Magazin, Ausgabe 4/08 habe ich das Security-Modell und den Deployment-Mechanismus von VSTO 3.0 beschrieben. Da sicherlich nicht jeder (oder doch?) diese Ausgabe gelesen hat und die Länge des Artikels begrenzt war, hier noch ein paar Gedanken dazu.

VSTO 3.0 verwendet nach wie vor Code Access Security, wenn es um Add-Ins oder Dokumentzentrische Lösungen für Office 2003 geht. Zielen wir aber auf Office 2007, so können wir dieses Modell nicht mehr verwenden. Die verwendeten Manifeste (Application und Deployment Manifest) müssen digital signiert werden (ClickOnce Security Modell). Und dazu brauchen wir ein Digitales Zertifikat. Dieses sollte bei professionellen Lösungen von einer vertrauenswürdigen Internet Zertifikats-Authorität stammen (Verisign, Thawte, etc.) oder bei Unternehmenslösungen von einem im Unternehmen stehenden Zertifikatsserver (der MS Certificate Server ist im Windows Server enthalten).

Vor dem Deployment der eigentlichen Anwendung muß dann nur das zum Signieren benutzte Zertifikat auf den Clients bekannt gemacht werden, sprich ein sog. Trusted Publisher eingerichtet werden. Das Zertifikat der herausgebenden Authorität muß dabei im Root Certificate Store zu finden sein, damit eine Trust Chain aufgebaut werden kann. Damit kann eindeutig bestimmt werden, daß die zu installierende Anwendung von einem Herausgeber stammt, dem das System vertraut. Das ist nichts anderes als das, was größere Unternehmen mit einer intakten PKI (Public Key Infrastructure) heute schon bei der Verteilung von In-Haus-Anwendungen verwenden.

Doch, erstens kann/will nicht jeder Geld für Zertifikate ausgeben, zweitens hat nicht jeder die Infrastruktur für einen eigenen Zertifikatsserver und drittens sind die Sicherheitsanforderungen bei Einzel-PCs nicht die gleichen wie bei durch Administratoren verwalteten Netzwerken. Was also tun?

Die Manifeste von VSTO-Projekten in Visual Studio 2008 werden mit Zertifikaten signiert, die mit MakeCert.exe erzeugt werden (self-signed). Das sind universale Code Signing Zertifikate, denen aber ein wichtiger Teil fehlt: Die Manufacturer bzw. Publisher Information. Damit kann keine Trust Chain aufgebaut werden! Also doch ein Zertifikat kaufen?

 VS SelfCert

Hier kommt eine Ausnahme ins Spiel. Die Inclusion List. Wird ein solches VSTO 3.0-Setup (ClickOnce Application) gestartet, fehlt die Trust Chain und ein Trust Prompt teilt dem Anwender mit, daß das verwendete Zertifikat nicht vertrauenswürdig ist (es wurde entweder ein vollständiges Zertifikat verwendet, aber der Herausgeber ist nicht in Trusted Root Certificates zu finden oder das Zertifikat wurde mit MakeCert erstellt und es fehlen die entsprechenden Infos). Weiterhin wird (nicht immer, aber dazu weiter unten im Text) gefragt, ob die Anwendung dennoch installiert werden soll.

Entscheidet sich der Anwender für ein Installieren, so wird neben den bekannten Infos auch ein Eintrag in die Inclusion List gesetzt. Diese Liste (HKCU\Software\Microsoft\VSTO\Security\Inclusion) enthält je einen Schlüssel mit zwei Werten (Public Key der Signatur und die URL zum Deployment Manifest) für eine VSTO 3.0 Lösung. Solange sich die Signatur der Anwendung nicht ändert, wird Ihr (auch nach Updates) vertraut.

In verwalteten Umgebungen, wo ein Netzwerk-Administrator sich darum kümmert, wer was darf und warum, ist dieses Verhalten nicht erwünscht und kann auch abgeschaltet werden. Auch bei Anwendungen, die aus unsicheren Zonen wie dem Internet kommen, könnte das ein Problem werden.

Aus diesem Grund kann das TrustPrompt-Verhalten separat gesteuert werden. Dazu wird in der Registry unter HKLM\SOFTWARE\Microsoft\.NETFramework\Security\TrustManager\ ein Key PromptingLevel angelegt und für die gewünschte Zone (siehe Tabelle) der Wert auf Enabled, AuthenticodeRequired bzw. Disabled gesetzt werden. (An dieser Stelle war die Erklärung im dotNet Magazin etwas zu kurz gekommen)

Enabled ist klar, TrustPrompts sind erlaubt.

AuthenticodeRequired bedeutet, dass Trust Prompts erlaubt sind, wenn:

  • ein Zertifikat mit einer bekannten Identität (Publisher Informationen) verwendet wird (was ein in Visual Studio mit makecert.exe selbst erzeugtes Zertifikat nicht besitzt)
  • dieses Zertifikat nicht im Trusted Publisher Store zu finden ist
  • das Zertifikat des Herausgebers (bspw. das des eigenen Zertifikatsservers) im Trusted Root Store liegt

In diesem Fall spricht man von sog. Friendly Trust Prompts, da sie das Installieren erlauben:

Friendly Trust Prompt

Ein Klick auf "More Information ..." enthüllt Details:

Friendly Trust Prompt Info

Man kann also schon anhand des Icons im Dialog gewissse Rückschlüsse ziehen. Die Publisher Informationen sind bei einem Self-Cert (also mit MakeCert erstelltem Zertifikat nicht zu sehen, weil nicht vorhanden.

Bei Disabled besteht keine Chance des Umgehens. Nur vertrauenswürdige Zertifikate (mit vollständiger Trust Chain, also Trusted Publisher und Trusted Root Zertifikate vorhanden und gültig) sind erlaubt. Das betrifft auch schon vorhandene Inclusion List Einträge, die in diesem Fall ignoriert werden, da die Zertifikatsauswertung Priorität vor der Inclusion List besitzt.

Sind diese Voraussetzungen nicht gegeben, so erhält man ein sog. Unfriendly Trust Prompt, nur um zusagen: Pech gehabt, die Lösung kann nicht installiert werden:

Unfriendly Trust Prompt

Auch hier erhüllt ein Klick aud Details die Hintergründe:

Unfriendly Trust Prompt Details 

Einen Ausweg stellt die Aufnahme des entsprechenden (Installations-)Pfades in die Liste der TrustedSites sein. Dafür gibt es einen eigenen PromptingLevel-Eintrag, der i.d.R. auf Enabled gesetzt sein dürfte. Das funktioniert aber nur, wenn der Pfad nicht unter UntrustedSites gelisted ist.

Wurde dagegen das PromptingLevel nach der Installation einer mit einem nicht vertrauten Zertifikat signierten Lösung (dabei wurde der TrustPromt positiv bestätigt) von Enabled auf AuthenticodeRequired oder Disabled geändert, so läuft die Lösung trotzdem, da die Prüfung während der ClickOnce Installation abläuft und nicht beim Start der Anwendung.

Obwohl der Key PromptingLevel i.d.R. nicht vorhanden ist, sind folgende Werte aktiv:

Name Typ Wert
Internet REG_SZ AuthenticodeRequired
LocalIntranet REG_SZ Enabled
MyComputer REG_SZ Enabled
TrustedSites REG_SZ Enabled
UntrustedSites REG_SZ Disabled

Visual Studio 2008 selbst legt übrigens für jedes VSTO-Projekt (für Office 2007) einen Eintrag in der Inclusion List an. (Vorsicht also bei Testen von ClickOnce Deployment für Öffice Lösungen auf der Entwickler-Maschine, es müssen nach dem Publish-Prozess zuerst die Add-In Einträge für Office und der Eintrag in der Inclusion List entfernt werden!)

Außerdem überprüft VS auch, ob eine intakte Trust Chain für nicht selbst generierte Zertifikate besteht und bricht das Kompilieren ab, wenn das nicht der Fall ist. (Beispiel: Code Signing Certifikat im Trusted Publisher Store, aber kein Trusted Root vorhanden)

CertNotTrusted in VS

Tools:

Zum Handhaben der Zertifikate sollte man die Management Console (MMC) mit dem Snap-In Zertifikate verwenden. In gewissem Umfang kann auch der Browser (Tools - Options - Content - Certificates) verwendet werden, jedoch zeigt dieser nicht alle Stores an.

Übrigens, wenn beim Signieren ein TimeStamp (offizieller Zeitstempel einer bekannten Internet Authorität, TimeStamp Server) verwendet wird, dann laufen Ihre Lösungen auch noch nach Ablauf des Gültigkeitsdatums des Zertifikates, da der Zeitpunkt des Signierens innerhalt des Gültigkeitzeitraums lag und das auch nachgewiesen werden kann (anhand des TimeStamps). Ansonsten müssen Zertifikate nach Ablauf erneuert werden. Er handelt sich dabei um kein komplett neues Zertifikat, sondern es enthält Informationen des ursprünglich erstellten. Somit müssen bei erneuerten Zertifikate die einmal verteilten Lösungen nicht erneut signiert werden.

Fazit:

In der Regel wird sich der Entwickler nicht um die PKI (Public Key Infrastructure) kümmern, da dies von Administratoren erledigt wird. Erstens ist aber gut zu wissen, wie es funktioniert und zweitens kommt es wahrscheinlich schon vor, dass Admin und Entwickler eine Personalunion bilden.