func getIntermediates(p7 *pkcs7.PKCS7, validationInfo RevocationInfo) (*x509.CertPool, error) {
	intermediates := x509.NewCertPool()
	for _, cert := range p7.Certificates {
		intermediates.AddCert(cert)
	}
	if len(validationInfo.Certs) > 0 {
		log.Println("verify: adding vri certificates for pkcs7 verification")
	}
	for _, cert := range validationInfo.Certs {
		intermediates.AddCert(cert)
	}
	return intermediates, nil
}
getIntermediates returns a certpool given a pkcs7 signature
package pdf_sign
import (
	"bytes"
	"crypto"
	"crypto/x509"
	"crypto/x509/pkix"
	"encoding/asn1"
	"errors"
	"io/ioutil"
	"log"
	"time"
	"github.com/philhug/go-trustlists/pkg/trustlists"
	"go.mozilla.org/pkcs7"
	"golang.org/x/crypto/ocsp"
)
func VerifyPkcs7(p7 *pkcs7.PKCS7, signingTime time.Time, content []byte, validationInfo RevocationInfo, trustedAnchors *x509.CertPool) (bool, error) {
	signers := p7.Signers
	if len(signers) != 1 {
		return false, errors.New("signature must have exactly one signer")
	}
	signerInfo := signers[0]
	authAttrs := signerInfo.AuthenticatedAttributes
	var digest []byte
	for _, authAttr := range authAttrs {
		var OIDAttributeMessageDigest = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 4}
		if authAttr.Type.Equal(OIDAttributeMessageDigest) {
			_, err := asn1.Unmarshal(authAttr.Value.Bytes, &digest)
			if err != nil {
				return false, err
			}
			log.Printf("verify: extracted digest from pkcs7")
		}
	}  
	if len(digest) == 0 {
		return false, errors.New("message digest not found among authenticated attributes")
	}
	hashp, err := getDigestAlgorithmFromOid(signerInfo.DigestAlgorithm.Algorithm)
	if err != nil {
		return false, err
	}
	hash := *hashp
	h := hash.New()
	h.Write(content)
	computed := h.Sum(make([]byte, 0))
	if bytes.Compare(computed, digest) == 0 {
		log.Println("verify: computed hash == digest on pkcs7")
	} else {
		log.Println("ERROR: Computed != Digest")
		log.Println("Expected: ", digest)
		log.Println("Computed: ", computed)
		return false, errors.New("computed digest does not match expected digest")
	}
	signerCertificate := p7.GetOnlySigner()
	if signingTime.Before(signerCertificate.NotBefore) || signingTime.After(signerCertificate.NotAfter) {
		return false, errors.New("signer certificate was not valid as for the timestamped signing time")
	}
	log.Println("verify: the signing certificate was valid as for the timestamped signing time")
	intermediates, err := getIntermediates(p7, validationInfo)
	if err != nil {
		return false, nil
	}
	verifyOptions := x509.VerifyOptions{
		Roots:         trustedAnchors,
		Intermediates: intermediates,
		KeyUsages:     []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
		CurrentTime:   signingTime,
	}
	_, err = signerCertificate.Verify(verifyOptions)
	if err != nil {
		return false, err
	}
	log.Printf("verify: signer certificate verification was succesfull")
	return true, nil
}
func VerifyRevocationInfo(revocationInfo RevocationInfo, signature *pkcs7.PKCS7) (bool, error) {
	foundOcsp := len(revocationInfo.Ocsps) > 0
	if foundOcsp {
		ocsp := revocationInfo.Ocsps[0]
		err := VerifyOcsp(ocsp)
		if err != nil {
			return false, err
		}
	} else {
		log.Println("there is no ocsp to validate")
	}
	foundCrl := len(revocationInfo.Ocsps) > 0
	if foundCrl {
		crl := revocationInfo.Crls[0]
		err := VerifyCrl(crl, signature)
		if err != nil {
			return false, err
		}
	} else {
		log.Println("there is no crl to validate against")
	}
	if !foundCrl && !foundOcsp {
		return false, nil
	}
	return true, nil
}
func VerifyOcsp(ocspresponse *ocsp.Response) error {
	if ocspresponse.Status == ocsp.Revoked {
		return errors.New("ocsp response status is: REVOKED")
	} else if ocspresponse.Status != ocsp.Good {
		return errors.New("ocsp response status is: NOT valid")
	}
	log.Printf("verify: ocsp response status is GOOD")
	return nil
}
func VerifyCrl(crl *pkix.CertificateList, signature *pkcs7.PKCS7) error {
	signer := signature.GetOnlySigner()
	if signer == nil {
		return errors.New("no signers for timestamp signature")
	}
	serialNumber := signer.SerialNumber
	list := crl.TBSCertList
	revokedlist := list.RevokedCertificates
	if len(revokedlist) == 0 {
		log.Println("verify: list of revoked certificates is empty")
	} else {
		for _, revoked := range revokedlist {
			if serialNumber != nil {
				if serialNumber == revoked.SerialNumber {
					return errors.New("signing certificate is revoked according with the CRL")
				}
			}
		}
		log.Println("verify: signing certificate NOT expired according with crl")
	}
	return nil
}
func GetTrustedAnchors(pem *string) (*x509.CertPool, error) {
	trustedAnchors := x509.NewCertPool()
	if pem != nil {
		file, err := ioutil.ReadFile(*pem)
		if err != nil {
			return nil, err
		}
		ok := trustedAnchors.AppendCertsFromPEM(file)
		if !ok {
			return trustedAnchors, errors.New("error parsing cert pool from pem file")
		}
	} else {
		trustedAnchors, err := trustlists.EUCertPool(trustlists.Options{})
		if err != nil {
			return trustedAnchors, err
		}
	}
	return trustedAnchors, nil
}
func getCertificate(certpath string) (*x509.Certificate, error) {
	var cert *x509.Certificate
	rootCaCertBytes, err := ioutil.ReadFile(certpath)
	if err != nil {
		return cert, err
	}
	cert, err = x509.ParseCertificate(rootCaCertBytes)
	if err != nil {
		return cert, err
	}
	return cert, nil
}