Tekninen artikkeli

eIDAS-luottamusluettelot ja kvalifioidut allekirjoitukset

Sen päättäminen, että PDF-allekirjoitus on kvalifioitu eIDAS:n mukaan, tarkoittaa kysymykseen vastaamista, jolla ei ole mitään tekemistä kryptografian kanssa: myönsikö jäsenvaltion kvalifioiduksi luettelu luottamuspalvelu sertifikaatin sillä hetkellä, kun allekirjoitus tehtiin. Vastaus asuu luottamusluettelossa, alueittain julkaistussa XML-dokumentissa, ja koko kyseisen dokumentin arvo riippuu sen aitoudesta. Niinpä PDFium-komponentti kieltäytyy katsomasta sellaisen sisään, kunnes joku on taannut sen. TPdfEuropeanTrustedList.ParseAuthenticated ojittaa täydet raakatavut kutsujan toimittamalle IPdfTrustedListAuthenticatorille ennen kuin se jäsentää yhtään palvelua, ja se luo snapshotin vain, jos kyseinen autentikoija hyväksyy eksplisiittisesti

Autentikoi ennen jäsentämistä -kulku eurooppalaiselle luottamusluettelolle Delphissä: raaka XML tuoreesta hausta tai välimuistin snapshotista kulkee IPdfTrustedListAuthenticatorin läpi ennen kuin TPdfEuropeanTrustedList jäsentää mitään
Tuoreet ja välimuistiset luettelot kohtaavat saman autentikoijan, ja snapshot on olemassa vasta sen läpäistyä

Tuo järjestys on suunnittelu. Kaikki muu tässä ominaisuudessa seuraa siitä, mukaan lukien osat, jotka näyttävät hankalilta

Jäsennetty ei ole luotettu

Luottamusluettelo, joka jäsentyy puhtaasti, kertoo, että XML on hyvin muodostettu. Se ei kerro mitään siitä, kuka sen kirjoitti. Koska luettelo on se, mihin koko kvalifioidun tilan päätöksesi nojaa, yhden hyväksyminen sen vuoksi, että se jäsentyi, tekisi päätöksestä merkityksettömän: hyökkääjä, joka voi korvata luettelon, voi julistaa oman sertifikaattiviranomaisensa kvalifioiduksi

Sama päättely pätee välimuistitukseen, ja tämä on ansa, joka kannattaa nimetä. Snapshot-välimuisti tallentaa alkuperäisen XML:n yhdessä SHA-256-tiivisteen kanssa, ja olisi helppo käsitellä täsmäävää tiivistettä ladattaessa todisteena siitä, että luettelo on aito. Se ei ole. Tiiviste, jonka laski sama prosessi, joka tallensi tiedoston, ilman avainta, varmistaa vain, että tavut eivät ole muuttuneet sen jälkeen, kun kirjoitit ne; jos luettelo oli vilpillinen välimuistitettaessa, tiiviste vahvistaa, että kyseessä on sama vilpillinen luettelo. Niinpä välimuistin snapshotin lataaminen kulkee saman autentikoijan kautta kuin tuoreen jäsentäminen. Eheys ja aitous ovat eri ominaisuuksia, ja vain toinen niistä tarvitsee avaimen

uses
  FPdfTrustedList;

type
  TListAuthenticator = class(TInterfacedObject, IPdfTrustedListAuthenticator)
  public
    function Authenticate(const XmlData: TBytes;
      out AuthenticationDetails: string): Boolean;
  end;

function TListAuthenticator.Authenticate(const XmlData: TBytes;
  out AuthenticationDetails: string): Boolean;
begin
  // Politiikkasi asuu tässä: varmista XMLDSIG-kääreallekirjoitus
  // pinnaamaasi luetteloiden allekirjoitussertifikaattia vastaan,
  // ja kuvaa, mitä tarkistit auditointijäljelle
  Result := VerifyEnvelopedXmlSignature(XmlData, FPinnedListSigner);
  if Result then
    AuthenticationDetails := 'XMLDSIG verified against pinned LOTL signer';
end;

var
  List: TPdfEuropeanTrustedList;
  Cache: TFileStream;
begin
  List := TPdfEuropeanTrustedList.ParseAuthenticated(RawXml,
    TListAuthenticator.Create, TPdfTrustedListOptions.Default);
  // Snapshot on olemassa vain siksi, että autentikoija sanoi kyllä
  Cache := TFileStream.Create('tl-de.snapshot', fmCreate);
  try
    List.SaveCache(Cache);
  finally
    Cache.Free;
  end;
end;

Validoija ei omista verkkopolitiikkaa

PAdES-validoijalla ei ole asiaa päättää, miten luetteloiden luettelo tavoitetaan, käydäänkö välikäsen kautta, kuinka usein yritetään uudelleen tai mitä tehdään, kun alue on saavuttamaton. Nuo ovat sovellus- ja jakelupäätöksiä, ja säännellyissä ympäristöissä ne auditoidaan usein. Niinpä päivitykset saapuvat kohteen IPdfTrustedListSource kautta, jolle annetaan URI ja tavukatto ja joka palauttaa tavuja

Sen, mitä komponentti valvoo, ovat invariantit, jotka tekevät päivityksestä päivityksen eivät korvikkeita. Update vaatii, että alue on muuttumaton, että sarjanumero kasvaa tiukasti ja että myöntämisaika ei liiku taaksepäin. Nuo kolme tarkistusta kukistavat ilmeisimmät alennushyökkäykset: vanhemman luettelon toistaminen, joka yhä luetteloi sittemmin peruutetun palvelun, tai toisen alueen luettelon vaihtaminen paikalleen, jonka palveluihin et koskaan aikonut luottaa

Päivitysinvariantit, joita PDFium-luottamusluettelokomponentti valvoo: muuttumaton alue, tiukasti kasvava sarjanumero ja myöntämisaika, joka ei koskaan liiku taaksepäin, mikä yhdessä estää alennushyökkäykset
Kolme monotonista tarkistusta erottaa aidon päivityksen toistetusta tai korvatusta luettelosta

Jäsentimen rajat, ei DTD:tä lainkaan

TPdfTrustedListOptions rajoittaa XML:n koon, tokenien määrän, sisäkkäisyyssyvyyden, palveluiden määrän, sertifikaattien määrän ja yksittäisen sertifikaatin koon, ja luokkafunktio Default toimittaa käytettäviä arvoja. Luottamusluettelot ovat julkaistuja dokumentteja, joiden koko on ennustettava, joten rajat on halpaa asettaa, eikä mikään laillinen luettelo tarvitse ylittää niitä

Erikseen ja ehdottomasti jäsentin hylkää DTD- ja entiteettideklaraatiot. Se sulkee sekä entiteetin laajennuksen palvelunestohyökkäyksen että ulkoisen entiteetin paljastusreitin yhdellä kieltäytymisellä, eikä se maksa mitään, koska luottamusluettelot eivät käytä entiteettejä. Mikä tahansa XML-jäsentin, joka on saavutettavissa luotamattomasta syötteestä, pitäisi konfiguroida tällä tavalla; ero tässä on, ettei kieltäytyminen ole konfiguroitavissa, joten sitä ei voi kytkeä pois hyväntahtoisella asetusmuutoksella

Kvalifioitu tila tallennetaan ketjuluottamuksen viereen, ei sulauteta siihen

Arviointipuoli on tarkoituksella erillinen. TPadesTrustValidationOptions.QualifiedTrustEvaluator ottaa vastaan kohteen IPdfQualifiedTrustEvaluator, jonka luottamusluettelon snapshot toteuttaa. Validoinnin aikana arvioija vastaanottaa lehtisertifikaatin, ketjun ja validointiajan, täsmäyttää palvelusertifikaatit tarkalla DER-vertailulla allekirjoittajaan ja ketjuun, yhdistää palvelun tilan, palvelutyyppitunnisteen ja määrittelijä-URI:t sillä hetkellä ja palauttaa arviointitietueen

Tulos laskeutuu kahteen paikkaan jokaisella allekirjoituksella: QualifiedTrustStatus karkeana tilana ja QualifiedTrust täytenä arviointina alueella, palveluntarjoajan nimellä, palvelun nimellä, tyyppitunnisteella, tilalla ja tilan alkamisajalla. Se, mitä se ei tee, on muuttaa CertificateTrustStatusia. Järjestelmän ketjuluottamus ja kvalifioitu tila vastaavat eri kysymyksiin, ja raportti, joka yhdistää ne, ei voi erottaa toisistaan ”luotettu mutta ei kvalifioitu” ja ”kvalifioitu mutta ketju ei validoidu”, joista kumpikin on todellinen ja joista kummankin käsittely on erilainen

PAdES:n kvalifioidun luottamuksen arviointi Delphissä: IPdfQualifiedTrustEvaluator täsmäyttää palvelusertifikaatit tarkalla DER-vertailulla ja täyttää kentät QualifiedTrustStatus ja QualifiedTrust, kun taas CertificateTrustStatus pysyy koskemattomana
Ketjuluottamus ja eIDAS:n kvalifioitu tila tallennetaan rinnakkain, joten molemmat löydökset pysyvät näkyvillä
var
  Options: TPadesTrustValidationOptions;
  Report: TPadesValidationResult;
  I: Integer;
begin
  Options := TPadesTrustValidationOptions.Default;
  Options.CheckRevocation := True;
  Options.QualifiedTrustEvaluator := List;      // autentikoitu snapshot
  Options.QualifiedValidationTime := SigningTime; // ei Now
  Report := Pdf.ValidatePadesTrust(Options);

  for I := 0 to High(Report.Signatures) do
    if Report.Signatures[I].QualifiedTrustStatus = pcsValid then
      Writeln(Format('signature %d qualified by %s / %s (%s)',
        [I, Report.Signatures[I].QualifiedTrust.Territory,
         Report.Signatures[I].QualifiedTrust.ProviderName,
         Report.Signatures[I].QualifiedTrust.ServiceName]))
    else if Report.Signatures[I].QualifiedTrustStatus = pcsIndeterminate then
      // Ei täsmäävää palvelua tai snapshot ei voi vastata tälle ajalle
      Writeln(Format('signature %d: qualified status undetermined', [I]));
end;

Miksi validointiaika ei ole nyt

Koska kvalifiointi on hetken ominaisuus. Luottamuspalvelulle voidaan myöntää kvalifioitu tila, se voidaan myöhemmin peruuttaa ja vielä myöhemmin palauttaa, ja jokainen kyseisistä siirtymistä kantaa alkamisaikaa luettelossa. Allekirjoitus, joka tehtiin sillä aikaa, kun palvelu oli kvalifioitu, pysyy kvalifioituna jälkeenpäin; allekirjoitus, joka tehtiin ennen myöntämistä, ei tule kvalifioiduksi takautuvasti. Arviointi nykyhetkeen siksi antaa väärän vastauksen molempiin suuntiin

Luettelo kantaa sen, mitä tähän tarvitaan: jokaisella palvelutietueella on tilan alkamisaika ja lippu, joka erottaa historialliset merkinnät nykyisistä, ja arvioija yhdistää ne toimittamaasi aikaa vasten. Käytännössä tuo aika tulee luotetusta aikaleimasta allekirjoituksessa eikä CMS:ssä väitetystä allekirjoitusajasta, mistä syystä pitkän aikavälin validointimateriaali merkitsee jopa kysymykselle, joka näyttää politiikkahaulta; aikaleiman ja DSS:n puoli käsitellään artikkelissa pitkän aikavälin allekirjoitus

Mitä sinun pitää yhä rakentaa

Kolme asiaa, eikä mikään niistä kuulu PDF-kirjastoon. Autentikoija, tarkoittaen todellista XMLDSIG-varmennusta luettelon allekirjoitussertifikaattia vastaan, jonka hankit kanavan kautta, johon luotat. Hakupolitiikka, tarkoittaen sitä, miten ja kuinka usein päivität, ja mitä sovelluksesi tekee, kun päivitys epäonnistuu. Ja alueellinen laajuus, tarkoittaen sitä, mitkä luettelot kannat ylipäätään, mikä on liiketoimintapäätös siitä, missä jäsenvaltioissa vastapuolesi allekirjoittavat

Se, mitä saat komponentilta, on se osa, jonka voi saada hienovaraisesti väärin: autentikoi ennen jäsentämistä -järjestys, rajattu ja entiteettivapaa XML-jäsennys, monotoniset päivitysinvariantit, tarkka DER-palvelutäsmäytys, historiallinen tilan arviointi ja tulos, joka pysyy erillään tavallisesta ketjuluottamuksesta. Jos välitön ongelmasi on perustavampi, se, että validoija hylkää allekirjoituksen, jonka uskot olevan kunnossa, tavalliset syyt on lueteltu artikkelissa miksi validoijat hylkäävät PAdES-allekirjoitukset, ja allekirjoitusten tarkastuspinta on kuvattu artikkelissa allekirjoitusten ja PAdES-tasojen tarkastaminen. Komponentin kyvykkyydet on lueteltu PDFium Delphi -komponentin tuotesivulla