Creation of chain, add chain to signing, fetch OCSP/CRL for chain

This commit is contained in:
Jeroen Bobbeldijk
2017-07-13 21:55:35 +02:00
parent c8e53c9bcf
commit 3928b7d813
4 changed files with 57 additions and 15 deletions

30
sign.go
View File

@@ -17,7 +17,7 @@ import (
) )
func usage() { func usage() {
log.Fatal("Usage: sign input.pdf output.pdf certificate.crt private_key.key OR verify input.pdf") log.Fatal("Usage: sign input.pdf output.pdf certificate.crt private_key.key [chain.crt] OR verify input.pdf")
} }
func main() { func main() {
@@ -90,6 +90,33 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
certificate_chains := make([][]*x509.Certificate, 0)
if flag.Arg(5) != "" {
certificate_pool := x509.NewCertPool()
if err != nil {
log.Fatal(err)
}
chain_data, err := ioutil.ReadFile(flag.Arg(5))
if err != nil {
log.Fatal(err)
}
certificate_pool.AppendCertsFromPEM(chain_data)
certificate_chains, err = cert.Verify(x509.VerifyOptions{
Intermediates: certificate_pool,
})
if err != nil {
log.Fatal(err)
}
chain_data_block, _ := pem.Decode(chain_data)
if chain_data_block == nil {
log.Fatal(errors.New("failed to parse PEM block containing the chain"))
}
}
err = sign.SignFile(input, output, sign.SignData{ err = sign.SignFile(input, output, sign.SignData{
Signature: sign.SignDataSignature{ Signature: sign.SignDataSignature{
Info: sign.SignDataSignatureInfo{ Info: sign.SignDataSignatureInfo{
@@ -104,6 +131,7 @@ func main() {
}, },
Signer: pkey, Signer: pkey,
Certificate: cert, Certificate: cert,
CertificateChains: certificate_chains,
TSA: sign.TSA{ TSA: sign.TSA{
URL: "http://aatl-timestamp.globalsign.com/tsa/aohfewat2389535fnasgnlg5m23", URL: "http://aatl-timestamp.globalsign.com/tsa/aohfewat2389535fnasgnlg5m23",
}, },

View File

@@ -14,6 +14,7 @@ import (
"github.com/digitorus/pkcs7" "github.com/digitorus/pkcs7"
"github.com/digitorus/timestamp" "github.com/digitorus/timestamp"
"crypto/x509"
) )
type pkiStatusInfo struct { type pkiStatusInfo struct {
@@ -28,7 +29,7 @@ type TSAResponse struct {
TimeStampToken asn1.RawValue TimeStampToken asn1.RawValue
} }
var signatureMaxLength = uint32(11742) var signatureMaxLength = uint32(1000000)
var signatureByteRangePlaceholder = "/ByteRange[0 ********** ********** **********]" var signatureByteRangePlaceholder = "/ByteRange[0 ********** ********** **********]"
func (context *SignContext) createSignaturePlaceholder() (signature string, byte_range_start_byte int64, signature_contents_start_byte int64) { func (context *SignContext) createSignaturePlaceholder() (signature string, byte_range_start_byte int64, signature_contents_start_byte int64) {
@@ -139,16 +140,21 @@ func (context *SignContext) createSignature() ([]byte, error) {
} }
if context.SignData.RevocationFunction != nil { if context.SignData.RevocationFunction != nil {
err = context.SignData.RevocationFunction(context.SignData.Certificate, nil, &context.SignData.RevocationData) if (len(context.SignData.CertificateChains) > 0) {
if err != nil { certificate_chain := context.SignData.CertificateChains[0]
return nil, err if (len(certificate_chain) > 0) {
} for i, certificate := range certificate_chain {
if i < len(certificate_chain)-1 {
if context.SignData.CertificateChain != nil && len(context.SignData.CertificateChain) > 0 { err = context.SignData.RevocationFunction(certificate, certificate_chain[i + 1], &context.SignData.RevocationData)
for _, cert := range context.SignData.CertificateChain { if err != nil {
err = context.SignData.RevocationFunction(cert, nil, &context.SignData.RevocationData) return nil, err
if err != nil { }
return nil, err } else {
err = context.SignData.RevocationFunction(certificate, nil, &context.SignData.RevocationData)
if err != nil {
return nil, err
}
}
} }
} }
} }
@@ -160,8 +166,14 @@ func (context *SignContext) createSignature() ([]byte, error) {
signer_config.ExtraSignedAttributes = append(signer_config.ExtraSignedAttributes, revocation_attribute) signer_config.ExtraSignedAttributes = append(signer_config.ExtraSignedAttributes, revocation_attribute)
} }
// Add the first certificate chain without our own certificate.
var certificate_chain []*x509.Certificate
if (len(context.SignData.CertificateChains) > 0 && len(context.SignData.CertificateChains[0]) > 1) {
certificate_chain = context.SignData.CertificateChains[0][1:]
}
// Add the signer and sign the data. // Add the signer and sign the data.
if err := signed_data.AddSignerChain(context.SignData.Certificate, context.SignData.Signer, context.SignData.CertificateChain, signer_config); err != nil { if err := signed_data.AddSignerChain(context.SignData.Certificate, context.SignData.Signer, certificate_chain, signer_config); err != nil {
return nil, err return nil, err
} }

View File

@@ -21,6 +21,7 @@ func embedOCSPRevocationStatus(cert, issuer *x509.Certificate, i *revocation.Inf
ocspUrl := fmt.Sprintf("%s/%s", strings.TrimRight(cert.OCSPServer[0], "/"), ocspUrl := fmt.Sprintf("%s/%s", strings.TrimRight(cert.OCSPServer[0], "/"),
base64.StdEncoding.EncodeToString(req)) base64.StdEncoding.EncodeToString(req))
resp, err := http.Get(ocspUrl) resp, err := http.Get(ocspUrl)
if err != nil { if err != nil {
return err return err
@@ -70,7 +71,8 @@ func DefaultEmbedRevocationStatusFunction(cert, issuer *x509.Certificate, i *rev
// TODO: Implement revocation status caching (required for higher volume signing) // TODO: Implement revocation status caching (required for higher volume signing)
// using an OCSP server // using an OCSP server
if len(cert.OCSPServer) > 0 { // OCSP requires issuer certificate.
if issuer != nil && len(cert.OCSPServer) > 0 {
err := embedOCSPRevocationStatus(cert, issuer, i) err := embedOCSPRevocationStatus(cert, issuer, i)
if err != nil { if err != nil {
return err return err

View File

@@ -30,7 +30,7 @@ type SignData struct {
Signature SignDataSignature Signature SignDataSignature
Signer crypto.Signer Signer crypto.Signer
Certificate *x509.Certificate Certificate *x509.Certificate
CertificateChain []*x509.Certificate CertificateChains [][]*x509.Certificate
TSA TSA TSA TSA
RevocationData revocation.InfoArchival RevocationData revocation.InfoArchival
RevocationFunction RevocationFunction RevocationFunction RevocationFunction