Microsoft Active Directory Certificate Services bietet die Möglichkeit, eigene Policy- und Exitmodule zu entwickeln, um die Funktionalität der Zertifizierungsstelle zu erweitern.
Nachfolgend die notwendigen Schritte, um ein Exit Modul in C# mit Visual Studio 2019 zu erstellen. Das Exit Modul wird ausgestellte Zertifikate in ein konfigurierbares Verzeichnis im Dateisystem schreiben.
Dankenswerterweise hat ein nicht namentlich genannter Verfasser die meiste Vorarbeit bereits erledigt. Mein Dank geht an dieser Stelle an diese Person! Ich habe seinen Beispielcode als Ausgangsbasis genommen.
Visual Studio beschaffen
Visual Studio 2019 kann in der Community Edition kostenlos von Microsoft bezogen werden. Bitte die Lizenzbedingungen beachten und berücksichtigen.
Bei der Installation muss die Option "Desktop Development with C#" ausgewählt werden.
Interop Assemblies erzeugen
Kennen Sie TameMyCerts? TameMyCerts ist ein Add-On für die Microsoft Zertifizierungsstelle (Active Directory Certificate Services). Es erweitert die Funktion der Zertifizierungsstelle und ermöglicht die Anwendung von Regelwerken, um die sichere Automatisierung von Zertifikat-Ausstellungen zu realisieren. TameMyCerts ist einzigartig im Microsoft-Ökosystem, hat sich bereits in unzähligen Unternehmen auf der ganzen Welt bewährt und steht unter einer freien Lizenz. Es kann über GitHub heruntergeladen und kostenlos verwendet werden. Professionelle Wartung wird ebenfalls angeboten.
Die Entwicklung muss nicht auf einem System erfolgen, auf dem die Zertifizierungsstelle installiert ist. Ein üblicher Windows 10 PC ist ausreichend. Wir benötigen jedoch zwei DLL-Dateien von der Zertifizierungsstelle, welche von einem Windows Server System kopiert werden müssen:
- certxds.dll
- certcli.dll
Die beiden DLL-Dateien befinden sich auf dem Zertifizierungsstellen-Server unter C:\Windows\System32.
Für diese beiden DLL-Dateien müssen Interop-Dateien erzeugt werden. Dies kann mit dem Programm tlbimport erfolgen, welches mit Visual Studio ausgeliefert wird.
Hierzu wird die Developer Command Prompt gestartet. Anschließend werden folgende Befehle eingegeben:
tlbimp certxds.dll tlbimp certcli.dll
Der Befehl wird die beiden folgenden Interop Assemblies als DLL-Dateien erzeugen:
- CERTEXITLib.dll
- CERTCLILib.dll
Anpassen der CERTCLILIB.dll
Bei der Übersetzung vom zugrundeliegenden C++ Code auf C# ist die Konvertierung der Datentypen nicht in jedem Fall korrekt (siehe hier für weitere Informationen). Daher muss die eben erzeugte CERTCLILIB zunächst disassembliert werden:
"C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\ildasm.exe" ^ CERTCLILib.dll ^ /out:CERTCLILIB.il
Die originale CERTCLILIB.dll muss nun gelöscht werden.
Innerhalb der CERTCLILIB.in werden alle Vorkommnisse von GetCertificateProperty ausgetauscht von…
GetCertificateProperty([in] string marshal( bstr) strPropertyName, [in] int32 PropertyType) runtime managed internalcall
Zu…
GetCertificateProperty([in] string marshal( bstr) strPropertyName, [in] int32 PropertyType, [out] native int pvarPropertyValue) runtime managed internalcall
Möchte man GetRequestProperty verwenden um z.B. das "RawRequest" Attribut auszulesen, muss für GetRequestProperty nach dem gleichen Schema vorgegangen werden.
Anschließend kann die DLL wieder assembliert werden.
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\ilasm.exe" ^ /DLL CERTCLILIB.il ^ /res:CERTCLILIB.res ^ /out=CERTCLILIB.dll
Projekt erzeugen
Nach dem Start von Visual Studio wird ein neues Projekt erzeugt.
Wir benötigen eine Class Library mit dem .NET Framework.
Das Projekt erhält im nächsten Schritt einen Namen und einen Speicheort, dann kann es losgehen.
Referenzieren der Interop-DLL-Dateien
Die zuvor erzeugen Interop-DLL-Dateien CERTEXITLib.dll und CERTCLILib.dll werden ins Projektverzeichnis kopiert.
Anschließend werden die beiden DLL-Dateien referenziert.
Erzeugen der Klassen-Dateien
Es müssen zwei Klassen erzeugt werden. Beispiele für die beiden Klassendateien finden sich in meinem Beispiel-Projekt auf GitHub:
Neue GUID vergeben
Wenn die Beispiel-Datei verwendet werden soll, sollte jeweils eine neue GUID in beiden Dateien eingetragen werden.
Die GUID darf in beiden Dateien nicht identisch sein.
Eine neue GUID kann beispielsweise mit dem PowerShell-Befehl "New-Guid" erzeugt werden.
New-GUID
Modul-Parameter definieren
Die Parameter für das Modul wie Name, Beschreibung, Version und Copyrighthinweis können in der GetProperty Methode in der ExitManageClass.cs definiert werden.
Übersetzen des Quellcodes
Nun kann das Exit Modul kompiliert werden.
Registrieren des Exit-Moduls auf der Zertifizierungsstelle
Die erzeugte DLL-Datei kann nun auf den Ziel-Server kopiert werden. Sie muss in zwei Verzeichnisse gespeichert werden:
- C:\Windows\System32
- C:\Windows\SysWOW64
Anschließend muss die DLL-Datei mit folgendem Befehl registriert werden:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\regasm.exe ^ C:\Windows\System32\MyFirstExitModule.dll
Es handelt sich bei der regasm.exe um das .NET Äquivalent zur regsvr32.exe.
Der certsvr Prozess ist ein 64-Bit Prozess, daher muss die DLL auch als 64-Bit registriert werden (regasm.exe aus dem Framework64 Verzeichnis). Aktuelle Windows-Versionen werden nur noch in 64-Bit ausgeliefert, historisch gab es jedoch auch 32-Bit Versionen des Dienstes.
In meinem Beispielprojekt auf GitHub liegt auch ein Installations/Deinstallations Script.
Exit Modul konfigurieren
Im Beispielprojekt schreibt das Exit Modul ausgestellte Zertifikate in einen Ordner im Dateisystem. Der Pfad muss als REG_SZ (String Value) namens "OutputDirectory" unterhalb des folgenden Registry Schlüssels konfiguriert werden.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\{Common-Name-der-Zertifizierungsstelle}\ExitModules\MyFirstExitModule
Zertifizierungsstellen-Dienst neu starten
Anschließend muss der Zertifizierungsstellen-Dienst neu gestartet werden.
net stop certsvc net start certsvc
Sollte das Exit-Modul nicht geladen werden können, oder einen Fehler verursachen, wird die Zertifizierungsstelle das Ereignis Nr. 46 protokollieren.
Öffnet man nun die Verwaltungskonsole für die Zertifizierungsstelle (certsrv.msc), sollte in der Karteikarte "Exit Modules" unter "Add" das neu erzeugte Exit-Modul zur Auswahl stehen.
Stellt die Zertifizierungsstelle ein Zertifikat aus, sollte dieses nun in das konfigurierte Verzeichnis exportiert werden.
Ab dieser Stelle ist das Projekt bereit für Eigenentwicklungen. Hier einige Ideen:
- Speichern ausgestellter Zertifikate in einer Datenbank
- Direktes melden einer Veränderung des Sperrstatus (Sperrent/Entsperren) eines Zertifikats an eine Datenbank
- Direktes Exportieren der Zertifikat-Seriennummern ins Dateisystem für das deterministische Good des Onlineresponders (OCSP)
- Aufruf einer Web-API zur Übermittlung der Zertifikatinformationen zur weiteren Bearbeitung (ausgestellte Zertifikate, Sperrungen, Entsperrungen)
- Entwicklung eines Exitmoduls, welches per SMTP Nachrichten versenden kann und im Gegensatz zum Standard Microsoft Exit Modul auch auf Server Core lauffähig ist
Weiterführende Links:
Externe Quellen
- Exit Modules (A programmers decent)
- How to modify an Interop assembly to change the return type of a method (VB.NET) (Microsoft)
- Certificate Services Architecture (Microsoft)
- Exit Modules (Microsoft)
- Writing Custom Exit Modules (Microsoft)
- ICertExit interface (certexit.h) (Microsoft)
- ICertServerExit interface (certif.h) (Microsoft)
4 Gedanken zu „Ein Exit Modul für die Zertifizierungsstelle in C# erstellen“
Kommentare sind geschlossen.