Technisch artikel

PAdES LTV-bewijs en seed values in HotPDF

Een PDF die u net heeft ondertekend is een B-B-handtekening en niets meer. Die bewijst wie heeft ondertekend en dat de bytes niet zijn verplaatst, maar die draagt geen bewijs dat het ondertekenaarscertificaat op het moment van ondertekening geldig was, dus een validator die jaren later kijkt moet op zoek naar intrekkingsgegevens die misschien niet meer bestaan. Dat gat dichten betekent OCSP-antwoorden en CRLs in de documentniveau-Document Security Store wegschrijven, en in HotPDF is dat één aanroep: PopulatePAdESLTVEvidence loopt langs elke geladen handtekening, leidt de intrekkingsverzoeken af uit de certificaatset, voert ze uit via een transport dat u aanlevert en schrijft het opgehaalde materiaal plus de CMS-keten in de DSS. Die geeft het aantal handtekeningen terug waarvan het bewijs is geland, of min één wanneer het document helemaal geen handtekeningveld heeft

De ontwerpbeslissing die het begrijpen waard is voordat u die gebruikt, is dat de bibliotheek nooit een socket opent. Elke byte die van het netwerk komt, komt binnen via een callback die u heeft geschreven. Dat is geen voorzichtigheid om de voorzichtigheid; het is de enige manier waarop deze functie kan werken in de omgevingen die langetermijnvalidatie daadwerkelijk eisen

Waarom weigert de bibliotheek eigen HTTP te doen?

Omdat de plekken die B-LT-handtekeningen eisen de plekken zijn waar een bibliotheek niet met het netwerk kan worden vertrouwd. Ondertekendiensten draaien achter authenticerende proxies met bedrijfsroots. Luchtdichte ondertekenlagen hebben geen route naar een responder en moeten gevoed worden met gecachte bewijzen. Auditregimes eisen dat elk uitgaand verzoek door de applicatie wordt gelogd, niet begraven in een afhankelijkheid. En testsuites hebben deterministische antwoorden nodig, wat onmogelijk is als de bibliotheek zelfstandig uitbelt

Het transport is een kale functiereferentie met een vaste vorm, dus het beleid blijft van u. HotPDF geeft u een verzoekrecord mee dat exact omschrijft wat opgehaald moet worden, inclusief het contenttype en een cap op de antwoordgrootte, en u geeft de bytes plus een status terug

Flow van HotPDF PopulatePAdESLTVEvidence: het FetchEvidence-transport van de aanroeper, verzoekrecordvelden en per-handtekening statusuitkomsten
Elke netwerkbyte passeert uw FetchEvidence-callback en elke handtekening krijgt een eigen status zodat één timeout nooit de hele passe afbreekt
function FetchEvidence(const Request: THPDFSignatureEvidenceRequest;
  Attempt: Integer; CancellationToken: THPDFCancellationToken;
  out Response: TBytes; out RetryAfterMS: Cardinal;
  out ErrorMessage: UnicodeString): THPDFSignatureEvidenceTransportStatus;
begin
  RetryAfterMS := 0;
  try
    // Request.Kind zegt of dit een OCSP POST of een CRL GET is;
    // Request.ContentType en Request.Body zijn al klaargezet,
    // en Request.MaxResponseBytes is de cap die u moet respecteren
    Response := HttpExchange(Request.URI, Request.ContentType,
      Request.Body, Request.MaxResponseBytes);
    Result := setsSucceeded;
  except
    on E: Exception do
    begin
      ErrorMessage := E.Message;
      // setsRetry laat het retrybeleid wachten; gebruik
      // setsPermanentFailure voor een 404 of een slechte URL
      Result := setsRetry;
    end;
  end;
end;

// B-B naar B-LT-upgrade in één aanroep voor elke handtekening in het geladen bestand
var
  Pdf: THotPDF;
  Upgraded: Integer;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.BeginIncrementalUpdate('signed.pdf');
    Upgraded := Pdf.PopulatePAdESLTVEvidence(FetchEvidence,
      THPDFSignatureEvidenceRetryPolicy.Default);
    if Upgraded > 0 then
      // Alleen-toevoegen-opslag: de bytes die de bestaande handtekeningen
      // dekken blijven woord voor woord behouden
      Pdf.SaveIncrementalUpdate('signed-lt.pdf');
  finally
    Pdf.Free;
  end;
end;

Fouten gelden per handtekening, niet per document. Een responder die voor één ondertekenaar een timeout geeft, slaat het materiaal van die ondertekenaar over en laat de rest van de passe intact, wat precies het gedrag is dat u in een batch wilt: partieel bewijs verslaat een afgebroken run, en de returnwaarde vertelt u hoeveel handtekeningen er werkelijk zijn verbeterd

De keten die de CMS vergat mee te sturen

Intrekkingscontrole heeft het uitgeverscertificaat nodig, en een verassend aantal ondertekenstacks laat intermediates weg uit de CMS-container. De herstelroute is de Authority Information Access-extensie, access method 1.3.6.1.5.5.7.48.2, die een URL adverteert waar het uitgeverscertificaat gedownload kan worden. HPDFFetchAIAIntermediates loopt die URLs af via hetzelfde transport, parseert de DER uit elk antwoord en geeft alleen de certificaten terug die de CMS nog niet droeg, gesleuteld op DER-hash zodat duplicaten en lussen niet kunnen ronddraaien

Twee details bepalen of dit tegen echte certificeringsinstanties werkt. De eerste is codering: CA-eindpunten serveren het certificaat net zo vaak als kale DER als PEM-gepantserd, en er is geen betrouwbaar contenttype om ze te onderscheiden. De robuuste sonde is eerst tekstueel en dan structureel. Zoek naar de markering -----BEGIN CERTIFICATE-----, haal het pantser eraf en decodeer base64 als die aanwezig is, en bevestig in beide paden dat de eerste byte van het resultaat $30 is, de DER-tag voor een SEQUENCE. De tweede is diepte: een opgehaalde intermediate kan zelf een AIA-URL adverteren voor zijn eigen uitgever, dus de wandeling voegt nieuwe kandidaten toe aan de wachtrij en maakt ketens af die twee of drie sprongen tekortkomen. Dat moet worden begrensd, en daarvoor is de parameter MaxFetch er

Diagram van AIA-ketenafmaking voor HotPDF: caIssuers-URL ophalen, PEM versus DER-sonde, DER-hash-deduplicatie en de MaxFetch-dieptecap
HPDFFetchAIAIntermediates loopt caIssuers-URLs af via hetzelfde transport, toetst PEM-pantser en begrenst de wachtrij met MaxFetch

Wat is een signatuur-seed value, en waarom faalt die geruisloos?

Een seed value is een beperking die de documentauteur aan een handtekeningveld hangt om de ondertekenaar te vertellen welk soort handtekening acceptabel is: welke SubFilter, welk digest-algoritme, welke redenen, welke minimale PDF-versie, of intrekkingsinformatie ingebed moet zijn. Die staat in een /SV-woordenboek op het veld en is gedefinieerd in ISO 32000-1 §12.7.5.5. HotPDF schrijft die met AttachPAdESSeedValue en controleert die met CheckLoadedSignatureSeedValue, die True teruggeeft wanneer het veld onbeperkt is of elke aanwezige beperking slaagt, en bij False de eerste falende beperking benoemt via een outputparameter die u rechtstreeks in een foutmelding kunt zetten

De mechaniek die seed values foutgevoelig maakt is de /Ff-vlaggeningang die in §12.7.5.5.3 wordt beschreven. Een gezette bit markeert zijn beperking als verplicht: een mismatch is een fout en de ondertekenaar moet weigeren. Een kale bit markeert dezelfde beperking als voorkeur: de waarde filtert wat de UI zou moeten aanbieden en niets meer. Daaruit volgen twee valkuilen. Ten eerste leeft /Ff binnen het /SV-woordenboek, niet op de widgetannotatie, dus code die de veldniveau-/Ff leest krijgt eeuwig een leeg antwoord en concludeert dat niets verplicht is. Ten tweede zijn de bittoewijzingen geen simpele reeks van een, twee, vier, acht; in HotPDF zendt de writer 2 uit voor SubFilter, 4 voor MinVersion, 32 voor AddRevInfo en 64 voor DigestMethod. Een lezer die opeenvolgende bits aanneemt decodeert elke beperking als optioneel en slaagt voor elke test behalve de enige die telt

Seed value-vlaggentabel voor HotPDF PAdES-ondertekening met Ff-bits 2, 4, 32 en 64 en de afhandeling van verplichte versus gewenste beperkingen
De /Ff-ingang leeft binnen /SV en elke bitpositie bepaalt of een mismatch een harde weigering is of een UI-voorkeur
var
  Violation: AnsiString;
begin
  // Vraag het veld of het profiel waarmee we gaan ondertekenen is toegestaan
  if not Pdf.CheckLoadedSignatureSeedValue(0, 'ETSI.CAdES.detached',
       'SHA256', 'Approved for payment', 1, Violation) then
    raise Exception.Create('Signature field rejects this profile: ' +
      String(Violation));
  // Beperking gehonoreerd: ga verder met de ondertekenpasse
end;

De test die de oorspronkelijke decodeerbug aan het licht bracht was geen positieve test. Het was de assertie dat een verplichte mismatch geweigerd moet worden, en het is de enige soort test die dit soort defecten kan vangen: een decoder die het verkeerde woordenboek of de verkeerde bitposities leest produceert voor elke input "geen beperking geschonden", wat er exact uitziet als correct gedrag totdat u er bewust één schendt

Waar dit op de LTV-ladder staat

Vier sporten, en elke sport heeft de onder hem nodig. B-B is de kale handtekening. B-T voegt een vertrouwd tijdstempel toe, die de ondertekentijd fixeert zodat een validator weet tegen welk moment intrekking beoordeeld moet worden. B-LT voegt het intrekkingsbewijs aan de DSS toe, en dat is wat PopulatePAdESLTVEvidence automatiseert. B-LTA voegt documenttijdstempels toe die worden vernieuwd voordat de vorige verzwakt, wat de geldigheid onbeperkt verlengt; HotPDF stelt dat bloot als RenewPAdESLTATimestamp, die een nieuwe tijdstempel als incrementele revisie toevoegt en elke eerdere handtekening, tijdstempel en DSS-ingang onaangetast laat

Een incrementeel-update-model is de enige correcte manier om bewijs aan een ondertekend document toe te voegen, want het bestand herschrijven zou de bytebereiken breken die de bestaande handtekeningen dekken. Als u moet redeneren over wat er tussen revisies is veranderd en of die veranderingen het soort zijn dat een handtekening toestaat, dan wordt die analyse apart behandeld in de DocMDP- en FieldMDP-revisieanalyse. De ondertekenpijplijn zelf, inclusief certificaatbronnen en bytevolgorde-valkuilen, staat in de PAdES-ondertekenwalkthrough, en de validatiekant staat in handtekeningen op geladen documenten verifiëren

Eén praktische waarschuwing over de volgorde. Verzamel bewijs zo snel mogelijk na het ondertekenen, bij voorkeur in dezelfde taak. De responders die voor een certificaat kunnen antwoorden zijn online zolang het certificaat actueel is en jaren later verdwenen, dus een document dat uw pijplijn verlaat als B-B is misschien nooit meer opwaardeerbaar. HotPDF draait als een native VCL-component voor Delphi en C++Builder, en de hele bewijspasse verloopt in-proces behalve uw eigen transport; de ondersteunde profielen staan op de productpagina van de HotPDF Delphi PDF component