Files
pdfsign/sign/revocation.go
Paul van Brouwershaven bacc810a68 Fix linting errors
2024-11-14 13:33:46 +01:00

91 lines
2.2 KiB
Go

package sign
import (
"crypto/x509"
"encoding/base64"
"fmt"
"io"
"net/http"
"strings"
"github.com/digitorus/pdfsign/revocation"
"golang.org/x/crypto/ocsp"
)
func embedOCSPRevocationStatus(cert, issuer *x509.Certificate, i *revocation.InfoArchival) error {
req, err := ocsp.CreateRequest(cert, issuer, nil)
if err != nil {
return err
}
ocspUrl := fmt.Sprintf("%s/%s", strings.TrimRight(cert.OCSPServer[0], "/"),
base64.StdEncoding.EncodeToString(req))
resp, err := http.Get(ocspUrl)
if err != nil {
return err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
// check if we got a valid OCSP response
_, err = ocsp.ParseResponseForCert(body, cert, issuer)
if err != nil {
return err
}
return i.AddOCSP(body)
}
// embedCRLRevocationStatus requires an issuer as it needs to implement the
// the interface, a nil argment might be given if the issuer is not known.
func embedCRLRevocationStatus(cert, issuer *x509.Certificate, i *revocation.InfoArchival) error {
resp, err := http.Get(cert.CRLDistributionPoints[0])
if err != nil {
return err
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
// TODO: verify crl and certificate before embedding
return i.AddCRL(body)
}
func DefaultEmbedRevocationStatusFunction(cert, issuer *x509.Certificate, i *revocation.InfoArchival) error {
// For each certificate a revoction status needs to be included, this can be done
// by embedding a CRL or OCSP response. In most cases an OCSP response is smaller
// to embed in the document but and empty CRL (often seen of dediced high volume
// hirachies) can be smaller.
//
// There have been some reports that the usage of a CRL would result in a better
// compatibility.
//
// TODO: Find and embed link about compatibility
// TODO: Implement revocation status caching (required for higher volume signing)
// using an OCSP server
// OCSP requires issuer certificate.
if issuer != nil && len(cert.OCSPServer) > 0 {
err := embedOCSPRevocationStatus(cert, issuer, i)
if err != nil {
return err
}
}
// using a crl
if len(cert.CRLDistributionPoints) > 0 {
err := embedCRLRevocationStatus(cert, issuer, i)
if err != nil {
return err
}
}
return nil
}