Creation of chain, add chain to signing, fetch OCSP/CRL for chain
This commit is contained in:
30
sign.go
30
sign.go
@@ -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",
|
||||||
},
|
},
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
Reference in New Issue
Block a user