<iso>

@schlagwort:

@rubrik:wissen

@arbeitstitel:zert_path2

@d:Prfen von Zertifikatspfaden in Java und .Net

@t:Gltige Pfade suchen und beschreiten

@a:Luigi Lo Iacono, Sibylle Hick, Michael Schneider

@v:

@$:Elektronische Signaturen bilden die Grundlage
fr sichere Transaktionen ber offene
Kommunikationsnetze. Gibt es auerdem eine Public
Key Infrastructure (PKI), in der eine unabhngige
vertrauenswrdige Instanz die ffentlichen
Signaturprfschlssel zertifiziert und damit
eindeutig einer Identitt zuordnet, lsst sich die
Integritt der Daten garantieren und ihr Ursprung
prfen. Bercksichtigt man weiterhin die
Anforderungen des Signaturgesetzes (SigG), 
entspricht die digitale in ihrer Rechtssicherheit
der handschriftlichen Signatur.

PKI etablieren Vertrauenshierarchien, die in einer
Wurzel beginnen und sich ber untergeordnete
Instanzen bis zu den Endnutzern erstrecken. 
Abbildung**1 <ref:Abbildung-1_SigG-ZDA_v1.3.jpg>
zeigt die derzeit im Rahmen des SigG
vorliegende PKI. Nach ~~3 des Gesetzes bildet die
zustndige Behrde -- die damalige
Regulierungsbehrde fr Telekommunikation und Post (RegTP)
und heutige Bundesnetzagentur (BNA) -- die Wurzel der
Hierachie und zertifiziert
Zertifizierungsdiensteanbieter (ZDA) durch die
Ausstellung eines qualifizierten Zertifikats. 
Das SigG geht von dieser dreistufigen Struktur aus,
wobei laengere Ketten zulaessig sind, wenn dies entsprechend
durch das Attribute pathLengthContraints in den
Zertifikatserweiterungen angeben ist.
Die Laenge von Zertifikatspfaden kann
durchaus variieren oder der Pfad
verlngert sich durch die Fderation von PKIs
durch Cross-Zertifizierung oder das Hinzufgen
einer bergeordneten Instanz, etwa einer Bridge-CA.

Folglich ist die Prfung elektronischer Signaturen
aufwendiger als ihr bloes Verifizieren durch
Anwendung des zugrundeliegenden kryptographischen
Verfahrens. Vielmehr muss sie die Kontrolle des
gesamten Pfads vom Endnutzer-Zertifikat (mit dem
die Signatur erzeugt wurde) bis zum
Vertrauensanker umfassen. Die Grundlagen zur
Gltigkeitsprfung von Signaturen beziehungsweise
Zertifikaten beschrieb ein <I>iX<I>-Artikel im
letzten Jahr [1]. Er ging auf die bei
Gltigkeitsprfungen notwendige Bildung von
Zertifikatspfaden ein und stellte die drei derzeit
verwendeten Gltigkeitsmodelle vor. Der
vorliegende Artikel baut darauf auf und betrachtet
die Konstruktion sowie die Gltigkeitsprfung von
Zertifikatspfaden in Java und .Net und er zeigt,
ber welche Gltigkeitsmodelle beide verfgen,
wobei der Schwerpunkt auf Java liegt. Analoge
.Net-Codefragemente in C# enthlt der Kasten <ref:Kasten_dotNET_LMS_v1.3_p2.txt>
Schliesslich verdeutlicht ein durchgaengiges Beispiel
die grundsaetzlichen Ausfuehrungen anhand der Validierung
elektronischer Rechnungen, die gemaess ~~14 Abs.3 Nr.1 UStG mit einer
qualifizierten elektronischen Signatur oder einer qualifizierten elektronischen 
Signatur mit Anbieter-Akkreditierung versehen sind. Derartige
Rechnung erfreuen sich wachsender Beliebtheit und erreichen den
ein oder anderen von uns vom Web-Hoster, Telekommunikations- bzw.
Mobilfunkanbieter oder ISP im Defacto-Standardformat als PDF-Dokument.

Knoten im Taschentuch

Zur Erinnerung und Einfhrung sei an dieser Stelle
nochmals erlutert, wie man eine elektronische
Signatur mit der Java Cryptography Architecture
(JCA) verifiziert. Hierzu erzeugt man im Programmcode als Erstes eine
Instanz der Klasse <I>java.security.Signature<I>,
die es anschlieend mit dem Zertifikat oder dem
ffentlichen Schlssel zur Signaturverifikation initialisiert.

@lf:
Signature sig = Signature.getInstance("ECDSA");
sig.initVerify(certificate);

@$:Dieses Codebeispiel instanziiert ein Objekt der
Klasse Signature nicht wie blich durch einen
Konstruktor, sondern verwendet das in der JCA
durchgngig umgesetzte Pattern "Factory Method"
[2], indem es die Klassenmethode
<I>getInstance()<I> aufruft, der man einen Signaturalgorithmus bergibt. 
Die signierten Daten, bekommt das Objekt per <I>update()<I>-Methode
bergeben:

@lf:sig.update(signedData);

@$:Zuletzt prft die Methode <I>verify()<I> des Signatur-Objekts die Signatur:

@lf:boolean isValid = sig.verify(signature);

@$:Sie liefert einen Wahrheitswert, der angibt, ob
die signierten Daten unverflscht sind und ob der
zur Prfung verwendete ffentliche mit dem
privaten Signaturschlssel korrespondiert. ber
die Gltigkeit der Signatur bzw. des Zertifikats lsst sich jedoch ohne
zustzliche Pruefungen keine Aussage treffen.

Die Methode <I>checkValidity()<I> der Klasse
<I>java.security.cert.X509Certificate<I> prueft,
ob das zugrundeliegende Zertifikat zurzeit gilt.
Weitergehende Prfungen des Zertifikats,
insbesondere Gltigkeitsprfungen in
hierarchischen Vertrauensmodellen gem einem der
in [1] vorgestellten Gltigkeitsmodelle, sind
hiermit nicht ohne weiteres mglich. Hierzu bedarf
es zustzlicher Klassen und Methoden, die im
folgenden vorgestellt werden. Die hier gewaehlte Beschreibung
orientiert sich dabei an der allgemeinen Vorgehensweise bei der
Gueltigkeitspruefung von Zertifikaten, die zunchst mit der
Konstruktion eines Zertifikatspafds beginnt und diesen
anschlieend gem einem Gltigkeitsmodell prft.

Bob der Baumeister

Die Vorgehensweise zur Konstruktion eines Zertifikatspfades
beginnt bei dem der Signatur zugrundeliegenden Endnutzer-Zertifikat
und versucht, eine Beziehung zu den Zertifikaten aufzubauen,
denen der Verifizierer vertraut. Im Bezug auf das SigG heisst dies,
dass ein Pfad vom Signaturzertifikat zu einem der Wurzelzertifikate
der BNA gesucht wird.

Zertifikatspfade werden in der JCA durch die Klasse
<I>java.security.cert.CertPath<I> repraesentiert.
Grundstzlich bietet die JCA zwei verschiedene
Varianten Instanzen dieser Klasse zu erzeugen, je nachdem, ob

1. alle Zertifikate des Pfades bereits vorliegen oder
2. einige der Zertifikate noch ermittelt und bezogen werden muessen.

Die erste Variante bedient sich der Klasse
<I>java.security.cert.CertificateFactory<I> und
ihrer Methoden. Die ursprnglich zur Erzeugung von Zertifikaten
und CRL-Objekten vorgesehene Klasse
enthlt seit J2SE~~1.4 zustzliche Methoden zur
Instanziierung von <I>CertPath<I>-Objekten.
Sie stellt den komfortableren Weg
zur Instanziierung von <I>CertPath<I>-Objekten dar,
ist allerdings nur dann anwendbar, wenn alle dafr
bentigten Zertifikate als Array, Keystore oder
gebndelt in einer Datei bereits vorliegen (siehe Listing**1
<ref:Listing-1_CertFactory_JCA_LMS_v1.3_p2.txt). Sind z.B.
alle Zertifikate im PDF-Dokument einer signierten
Rechnung enthalten (BNA -> ZDA -> Rechnungssteller), koennen
diese ausgelesen, in einem Array zusammengefasst und
daraus der Zertifikatspfad gebildet werden. Liegen die
Zertifikate in einer dedizierten Datei gebuendelt vor, muss
zunaechst die Unterstuezung des Dateiformats anhand der
Methode <I>getCertPathEncodings()<I> in der Klasse
<I>CertificateFactory<I> ermittelt werden. Das erste Element
der von ihr zurckgelieferten Liste ist gleichzeitig das
Default-Format. Der in der J2SE~~1.4 enthaltene
"SUN"-Provider bietet Support fr die in PKCS#7
definierte <I>SignedData<I>-Datenstruktur [3] und das
Java-proprietaere, so genannte <I>PkiPath<I>-Format, eine auf das
Wesentliche reduzierte Datenstruktur.

Die zweite Variante kommt zum Zuge, wenn die zur Kette
gehoerigen Zertifikate nicht in einer der beschriebenen Weisen
vorkonfektioniert vorliegen. In diesen Fall sucht die im J2SE~~1.4
eingefuehrte Klasse <I>java.security.cert.CertPathBuilder<I>
die fehlenden Zertifikate selbsttaetig unter zur Hilfenahme von
Zertifikatsverzeichnissen und/oder anderen Repositories, die als
Instanzen der 
<I>java.security.cert.CertStore<I> Klasse spzifiziert werden.
Der "SUN"-Provider kann Verzeichnisdienste auf Basis des LDAP als
<I>CertStore<I> reprsentieren (<I>type=LDAP<I>) oder Container des Types
<I>java.util.Collection<I> (<I>type=Collection<I>).
Wesentlich dabei ist, dass der Benutzer zunaechst die von ihm
als vertrauenswuerdig angesehenen Zertifikate als Vertrauensanker angibt
(z.B. das der BNA). Das CertPathBuilder-Objekt sucht zu
einem spezifizierten Endnutzer-Zertifikat aus den angegebenen <I>CertStores<I>
einen Pfad zu den Vertrauensankern (siehe Listing**2
<ref:Listing-2_PathBuilder_JCA_LMS_v1.3_p2.txt>).
Liegt einer PDF-Rechnung nur das Signaturzertifikat des Rechnungsstellers bei,
muss der Rechnungsempfaenger folglich das Wurzelzertifikat der BNA als
Vertrauensanker spezifizieren und das LDAP-Verzeichnis der BNA als <I>CertStore<I> angeben.

Der mit einer der beiden Varianten erzeugte Pfad enthlt alle
Zertifikate in der entsprechenden Reihenfolge
auer den zugrunde liegenden Vertrauensanker
beginnend mit dem Endnutzer-Zertifikat.
Ein SigG-konformer Zertifikatspfad, der sich
aus drei Zertifikaten zusammensetzt
(BNA -> ZDA -> Endnutzer) enthaelt also in
der JCA-Reprsentation <I>CertPath<I> genau zwei
Elemente, nmlich das Endnutzer- und
ZDA-Zertifikat. Der Vertrauensanker ist nicht in der <I>CertPath<I>-
Repraesentation enthalten, da er im Validierungsschritt nochmals
explizit angegeben werden muss. Die Klassen zur Pruefung der Zertifikatspfade
erwarten den Pfad genau in dieser Form, anderenfalls wird
der Pfad als ungueltig erklaert und eine <I>CertPathValidator<I>-Exception
ausgeloest.

Sogar in den wenigen Zeilen Code zur Konstruktion
von Zertifikatspfaden bewirken bereits kleinere
Programmierfehler, dass der Pfad nicht gebildet
werden kann. Die ausgelsten Exceptions sind
hufig wenig aussagekrftig, sodass fr die
Fehlersuche weitere Informationen wnschenswert
sind. Durch das Setzen der Property
<I>java.security.debug<I> auf <I>certpath<I>, etwa
beim Aufruf der VM durch

@lf:java -D java.security.debug=certpath ...

geben die <I>CertPath<I>-bezogenen Klassen der JCA zustzliche
Debugging-Informationen auf <I>stderr<I> aus.

Bob der Bauinspektor

Liegt ein Zertifikatspfad vor, muss er Zertifikat fr
Zertifikat geprft werden, um eine Aussage ber seine
Gltigkeit treffen zu knnen. Dabei kommt
es unter anderem darauf an, ob ein Zertifikat zu
einem bestimmten Zeitpunkt nicht gesperrt und
gltig ist oder war. Ob das Zertifikat gesperrt
ist, lsst sich durch Abfrage von Sperrlisten oder
durch eine OCSP-Anfrage nach RFC~~2560 bei einem
vertrauenswrdigen Server feststellen. Informationen
zu diesen Servern kann man entweder einem entsprechenden
Eintrag des zugrundeliegenden Zertifikats oder im Rahmen
des SigG auf den Webseiten der Bundesnetzagentur entnehmen.
Informationen zum Verzeichnisdienst der BNA stehen unter
http://www.nrca-ds.de/ bereit, der das Abrufen von Zertifikaten
und Sperrlisten via LDAP sowie Statusabfragen via OCSP unterstuetzt.

Das SigG trifft keine Festlegung hinsichtlich eines bestimmten
Gueltigkeitsmodells, sondern fordert fuer qualifizierte elektronische
Signaturen nach ~~2 Nr. 3a SigG, dass sie auf einem "zum Zeitpunkt ihrer Erzeugung gueltigen
Zertifikat" beruhen. Zu dieser Anforderung sind sowohl das modifizierte
Schalenmodell als auch das Kettenmodel konform, wobei das Kettenmodell
unausgesprochen dem SigG zugrundegelegt wird [1].

Ab J2SE~~1.4 enthlt das JCA-Paket
<I>java.security.cert<I> Klassen, Schnittstellen
und Exceptions zur Prfung der Gltigkeit von
Zertifikatspfaden. <I>java.security.cert.CertPathValidator<I>
beschreibt eine abstrakte Klasse zur Prfung von
Zertifikatsketten. Wie zuvor bei der Verwendung
der <I>CertificateFactory<I> instanziiert eine
Factory-Methode ihre Objekte, die den zur
Gltigkeitsprfung erforderlichen Algorithmus als
Parameter erwartet. Der einzige in der J2SE~~1.4
eingefhrte und in 1.5 noch enthaltene entspricht den
Festlegungen der PKIX-Arbeitsgruppe im RFC 3280.
Die Internet-Interpretation des ITU-T X.509v3 Standards
erlaubt, den Zeitpunkt der Gltigkeitsprfung
einer elektronischen Signatur, auf eine beliebige
Zeit in der Vergangenheit abzustellen. Damit
beinhaltet es sowohl das Schalenmodell als auch
das modifizierte Schalenmodell.

Einen nach Listing**1 oder 2 erstellten
Zertifikatspfad prfen die in Listing**3
<ref:Listing-3_PathVerifier_JCA_LMS_v1.3_p2.txt> 
aufgefhrten notwendigen Schritte.

Verwirrung komplett

Die Vermittlung komplexer Inhalte ist kein Leichtes und
beinhaltet meist ungewollte Informationsluecken oder
Unklarheiten, die durch Selbstverstaendlichkeiten auf Seiten
der Autoren ausgeloest werden. Auch wenn wir uns redlich
bemueht haben, koennen wir es auch im vorliegenden Fall nicht ausschliessen.
Daher folgt nun ein abschliessendes Beispiel, dass das
Gesamtbild nochmals versucht darzustellen. Der Ausgangspunkt
ist eine gemaess UStG qualifizierte elektronisch signierte 
Rechnung im PDF Format. Signierte PDF-Dokumente tragen die
Signatur im Dokument die gemaess PKCS#7-SignedData aufgebaut
ist [3]. Diese Datenstruktur kann die gesammte Zertifikatskette
enthalten, sprich BNA -> ZDA -> Endnutzer. Mit der Open Source
Bibliothek iText (http://www.lowagie.com/iText/, MPL oder LGPL) koennen diese
ausgelesen werden:

PdfReader reader = new PdfReader("signed_doc.pdf");
AcroFields af = reader.getAcroFields();
ArrayList names = af.getSignatureNames();

// Es liegt eine Signatur vor, die auf das
// gesamte Dokument zu beziehen ist.
String name = (String)names.get(0);
System.out.println("Signature name: " + name);
System.out.println("Signature covers whole document: " + af.signatureCoversWholeDocument(name));
PdfPKCS7 sigInfo = af.verifySignature(name);
Calendar signDate = sigInfo.getSignDate();
Certificate certs[] = sigInfo.getCertificates();

Fuer das Beispiel nehmen wir an, dass alle Zertifikate zur
Konstruktion des Pfades vorliegen (<I>certs.length = 3<I>,
und folglich anhand der Variante 1 vorgegangen werden kann:

CertificateFactory cf = CertificateFactory.getInstance("X.509");
CertPath cp = cf.generateCertPath(Arrays.asList(certs));

Der auf diese Weise erzeugte <I>CertPath<I> ist dann schliesslich
durch die folgenden Codezeilen gemaess dem modifizierten
Schalenmodell zu pruefen:

TrustAnchor taRoot = new TrustAnchor(BNACert, null);
HashSet trustAnchors = new HashSet();
ta.add(taRoot);

CertPathValidator cpv = CertPathValidator.getInstance(PKIX);
PKIXParameters params = new PKIXParameters(ta);
params.setRevocationEnabled(false);
params.setDate(signDate.getTime());

CertPathValidatorResult valResult = cpv.validate(cp, params);

Man beachte den kleinen aber feinen Unterschied. Wird in Listing**3
auf den Zeitpunkt der Pruefung abgestellt und somit gemaess des
Schalenmodells geprueft, stellen die oben angefuehrten Codezeilen
auf den Zeitpunkt der Signaturerzeugung ab (hinterlegt im PDF-Dokument)
und pruefen somit gemaess dem modifizierten Schalenmodells.

Am Rande sei noch erwaehnt, dass die im Abschlussbeispiel verdeutlichte
Funktionalitaet in der iText-Bibliothek durch die <I>PdfPKCS7<I>-Klassenmethode
<I>verifyCertificates()<I> enthalten ist.

Fazit

Moechte man eine zum SigG konforme Gueltigkeitspruefung
mit der JCA durchfuehren, steht einem prinzipiell hierfuer im Standardumfang
das modifizierte Schalenmodell zur Verfuegung. Da allerdings
das Kettenmodell dem SigG unausgesprochen zugrundegelegt, ist die SigG-konforme
Gueltigkeitspruefung aber aufgrund fehlender Unterstuezung in der
internationalen Standardisierung und damit auch seitens konkreter
Implementierung wie bspw. der JCA, in der Praxis i.d.R. nicht ohne weiteres
moeglich. Selbiges gilt fr das .Net-Framework. Soll in einer der beiden
Plattformen das Kettenmodell verwendet werden,
muss dieses hinzugefgt werden, was allerdings 
beide Architekturen untersttzen. (ck)

@lit:Literatur

@lit1:[1]~~Luigi Lo Iacono, Sibylle Mller, Michael Schneider; Digitale Signaturen; 
Gltige Pfade; Modelle zur Gltigkeitseitsprfung von Zertifikaten; 
<I>iX<I>**6/2006, S.**126

@lit2:[2]~~E. Gamma et al., Entwurfsmuster - Elemente wiederverwendbarer objektorientierter Software, Addison-Wesley, 1996.

@lit3:[3]~~Bundesamt fuer Sicherheit in der Informationstechnik, Grundlagen der elektronischen Signatur - Recht, Technik, Anwendung, SecuMedia, 2006.
