En PDF, du lige har signeret, er en B-B-signatur og ikke mere. Den beviser, hvem der signede, og at bytene ikke er flyttet, men den bærer intet bevis på, at underskrivercertifikatet var gyldigt på signeringstidspunktet, så en validator mange år senere må lede efter tilbagekaldelsesdata, der muligvis ikke længere findes. At lukke det hul betyder at skrive OCSP-svar og CRL'er ind i det dokumentniveau Document Security Store, og i HotPDF er det ét kald: PopulatePAdESLTVEvidence gennemløber hver indlæst signatur, afleder tilbagekaldelsesanmodningerne ud fra certifikatsættet, udfører dem gennem en transport, du leverer, og skriver det hentede materiale plus CMS-kæden ind i DSS. Den returnerer antallet af signaturer, hvis beviser landede, eller minus én, når dokumentet slet ikke har et signaturfelt
Designbeslutningen, der er værd at forstå, før du bruger den, er, at biblioteket aldrig åbner en socket. Hver byte, der ankommer fra netværket, ankommer gennem et callback, du skrev. Det er ikke forsigtighed for sin egen skyld; det er den eneste måde, denne funktion kan virke inde i de miljøer, der reelt kræver langtidsvalidering
Hvorfor nægter biblioteket at lave sin egen HTTP?
Fordi de steder, der kræver B-LT-signaturer, er de steder, hvor et bibliotek ikke kan betroes netværket. Signeringstjenester kører bag autentificerende proxies med virksomhedens root-certifikater. Air-gapped signeringstier har ingen rute til en responder og skal fodres med cachede beviser. Auditregimer kræver, at hver udgående anmodning logges af applikationen, ikke begraves i en afhængighed. Og testsuiter behøver deterministiske svar, hvilket er umuligt, hvis biblioteket selv ringer ud
Transporten er en almindelig funktionsreference med fast form, så politikken forbliver din. HotPDF giver dig en request-record, der beskriver præcis, hvad der skal hentes, inklusive content-typen og et svarstørrelsestag, og du returnerer bytes plus en status
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 siger, om dette er en OCSP POST eller en CRL GET;
// Request.ContentType og Request.Body er allerede forberedt,
// og Request.MaxResponseBytes er det loft, du må overholde
Response := HttpExchange(Request.URI, Request.ContentType,
Request.Body, Request.MaxResponseBytes);
Result := setsSucceeded;
except
on E: Exception do
begin
ErrorMessage := E.Message;
// setsRetry lader retry-politikken trække sig tilbage; brug
// setsPermanentFailure til en 404 eller en dårlig URL
Result := setsRetry;
end;
end;
end;
// Ét-kalds B-B til B-LT-opgradering for hver signatur i den indlæste fil
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
// Append-only-gemning: byterne, som de eksisterende signaturer
// dækker, bevares ordret
Pdf.SaveIncrementalUpdate('signed-lt.pdf');
finally
Pdf.Free;
end;
end;
Fejl er pr. signatur, ikke pr. dokument. En responder, der timeout for én underskriver, springer den underskrivers materiale over og efterlader resten af gennemløbet intakt, hvilket er den adfærd, du vil have i en batch: delvise beviser slår en afbrudt kørsel, og returværdien fortæller dig, hvor mange signaturer, der reelt forbedredes
Kæden, som CMS glemte at inkludere
Tilbagekaldelsestjek behøver issuer-certifikatet, og et overraskende antal signeringsstakke udelader intermediater fra CMS-containeren. Genfindingsvejen er Authority Information Access-udvidelsen, access method 1.3.6.1.5.5.7.48.2, som annoncerer en URL, hvor issuer-certifikatet kan downloades. HPDFFetchAIAIntermediates gennemløber de URL'er gennem samme transport, parser DER ud af hvert svar og returnerer kun de certifikater, som CMS ikke allerede bar, nøglet efter DER-hash, så duplikater og løkker ikke kan dreje rundt
To detaljer afgør, om dette virker mod rigtige certifikatautoriteter. Den første er kodning: CA-endpoints serverer certifikatet som bar DER omtrent lige så ofte, som de serverer det PEM-rustet, og der er ingen pålidelig content-type til at skelne dem. Den robuste sonde er tekstlig, derefter strukturel. Kig efter -----BEGIN CERTIFICATE------markøren, strip rustningen og dekod base64, hvis den er til stede, og i begge veje bekræft, at resultatets første byte er $30, DER-tag'et for en SEQUENCE. Den anden er dybde: et hentet intermedier kan selv annoncere en AIA-URL for sin egen issuer, så gennemløbet tilføjer nye kandidater til køen og fuldfører kæder, der mangler to eller tre hop. Det skal tages på, og det er det, parameteren MaxFetch er til
Hvad er en signatur-seed value, og hvorfor fejler den i stilhed?
En seed value er en begrænsning, som dokumentforfatteren knytter til et signaturfelt for at fortælle underskriveren, hvilken slags signatur der er acceptabel: hvilken SubFilter, hvilken digest-algoritme, hvilke grunde, hvilken minimums-PDF-version, om tilbagekaldelsesinformation skal indlejres. Den bor i en /SV-ordbog på feltet og er defineret i ISO 32000-1 §12.7.5.5. HotPDF skriver den med AttachPAdESSeedValue og tjekker den med CheckLoadedSignatureSeedValue, som returnerer True, når feltet er ubegrænset, eller alle tilstedeværende begrænsninger består, og ved False navngiver den første fejlende begrænsning gennem en outputparameter, du kan lægge direkte ind i en fejlmeddelelse
Mekanismen, der gør seed values lette at tage fejl af, er /Ff-flags-posten beskrevet i §12.7.5.5.3. En sat bit markerer sin begrænsning som påkrævet: en uoverensstemmelse er en fejl, og underskriveren må nægte. En nulstillet bit markerer samme begrænsning som en præference: værdien filtrerer, hvad UI'en bør tilbyde, og ikke mere. To fælder følger af det. For det første bor /Ff inde i /SV-ordbogen, ikke på widget-annotationen, så kode, der læser feltniveauets /Ff, får et tomt svar for altid og konkluderer, at intet er tvunget. For det andet er bittildelingerne ikke en simpel række af én, to, fire, otte; i HotPDF udsender writeren 2 for SubFilter, 4 for MinVersion, 32 for AddRevInfo og 64 for DigestMethod. En læser, der antager sekventielle bits, dekoder hver begrænsning som valgfri og består hver test undtagen den, der tæller
var
Violation: AnsiString;
begin
// Spørg feltet, om profilen, vi er ved at signere med, er tilladt
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));
// Begrænsning opfyldt: fortsæt signeringsgennemløbet
end;
Testen, der afslørede den oprindelige dekodefejl, var ikke en positiv test. Det var assertionen om, at en tvunget uoverensstemmelse må afvises, og det er den eneste slags test, der kan fange denne klasse af defekter: en dekoder, der læser den forkerte ordbog eller de forkerte bitpositioner, producerer "ingen begrænsninger brudt" for hvert input, hvilket ser præcis ud som korrekt adfærd, indtil du med vilje bryder én
Hvor dette ligger på LTV-stigen
Fire trin, og hvert behøver det under sig. B-B er den bare signatur. B-T tilføjer et betroet tidsstempel, som fastlægger signeringstidspunktet, så en validator ved, hvilket øjeblik tilbagekaldelse skal evalueres mod. B-LT tilføjer tilbagekaldelsesbeviserne til DSS, hvilket er det, PopulatePAdESLTVEvidence automatiserer. B-LTA tilføjer dokumenttidsstempler, der fornyes, før det foregående svækkes, og udvider gyldigheden på ubestemt tid; HotPDF eksponerer det som RenewPAdESLTATimestamp, som tilføjer et nyt tidsstempel som en inkrementel revision og bevarer hver tidligere signatur, tidsstempel og DSS-post urørt
En inkrementel opdateringsmodel er den eneste korrekte måde at tilføje beviser til et signeret dokument, for at omskrive filen ville bryde de byte-intervaller, de eksisterende signaturer dækker. Hvis du har brug for at ræsonnere om, hvad der ændredes mellem revisioner, og om de ændringer er af den slags, en signatur tillader, er den analyse dækket separat i DocMDP- og FieldMDP-revisionsanalysen. Signeringspipelinen selv, inklusive certifikatkilder og byte-ordre-fælder, er i PAdES-signeringsgennemgangen, og valideringssiden er i verificering af signaturer på indlæste dokumenter
Én praktisk advarsel om rækkefølge. Indsaml beviser så hurtigt som muligt efter signering, ideelt i samme job. Responderne, der kan svare for et certifikat, er online, mens certifikatet er aktuelt, og væk år senere, så et dokument, der forlader din pipeline som B-B, kan muligvis aldrig opgraderes igen. HotPDF kører som en native VCL-komponent til Delphi og C++Builder, og hele bevisgennemløbet er in-process bortset fra din egen transport; de understøttede profiler er opført på produktsiden HotPDF Delphi PDF component