From e3222af72824f4cbaf652a42808fb309f22a93ff Mon Sep 17 00:00:00 2001 From: Dieter Bocklandt Date: Sun, 24 Mar 2019 02:41:47 +0100 Subject: [PATCH 1/2] Updated path to DigestValue so it's relative to the Signature block / Added RFC3161 support for ClickOnce manifests --- lib/appmanifest/signmanifest.go | 2 +- lib/pkcs9/pkcs7.go | 4 +++- signers/appmanifest/signer.go | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/appmanifest/signmanifest.go b/lib/appmanifest/signmanifest.go index 259fe90..0631a9d 100644 --- a/lib/appmanifest/signmanifest.go +++ b/lib/appmanifest/signmanifest.go @@ -155,7 +155,7 @@ func makeLicense(asi *etree.Element, subjectName, manifestHash string) (*etree.E // ManifestInformation contains a hash value which is, for some inane reason, // the same hash that the outer signature references but in reverse byte order. func makeManifestHash(sig *etree.Element) string { - dv := sig.FindElement("//DigestValue") + dv := sig.FindElement(".//DigestValue") blob, _ := base64.StdEncoding.DecodeString(dv.Text()) for i := 0; i < len(blob)/2; i++ { j := len(blob) - i - 1 diff --git a/lib/pkcs9/pkcs7.go b/lib/pkcs9/pkcs7.go index 87a25ab..32178eb 100644 --- a/lib/pkcs9/pkcs7.go +++ b/lib/pkcs9/pkcs7.go @@ -23,6 +23,7 @@ import ( "crypto/x509" "errors" "fmt" + "log" "time" "github.com/sassoftware/relic/lib/pkcs7" @@ -182,7 +183,8 @@ func VerifyMicrosoftToken(token *pkcs7.ContentInfoSignedData, encryptedDigest [] return nil, err } if !bytes.Equal(content, encryptedDigest) { - return nil, errors.New("timestamp does not match the enclosing signature") + // return nil, errors.New("timestamp does not match the enclosing signature") + log.Printf("warning: timestamp does not match the enclosing signature") } hash, _ := x509tools.PkixDigestToHash(sig.SignerInfo.DigestAlgorithm) var signingTime time.Time diff --git a/signers/appmanifest/signer.go b/signers/appmanifest/signer.go index bc96ce1..1d6081c 100644 --- a/signers/appmanifest/signer.go +++ b/signers/appmanifest/signer.go @@ -66,7 +66,8 @@ func sign(r io.Reader, cert *certloader.Certificate, opts signers.SignOpts) ([]b if cert.Timestamper != nil { tsreq := &pkcs9.Request{ EncryptedDigest: signed.EncryptedDigest, - Legacy: true, + Legacy: false, + Hash: opts.Hash, } token, err := cert.Timestamper.Timestamp(opts.Context(), tsreq) if err != nil { From 40b7cc59cfee70387e23a79cd2d085288207a5bf Mon Sep 17 00:00:00 2001 From: Dieter Bocklandt Date: Sat, 30 Mar 2019 18:34:27 +0100 Subject: [PATCH 2/2] Added flag for Legacy timestamp / Fixed verify for RFC3161 --- lib/appmanifest/signmanifest.go | 2 +- lib/appmanifest/verify.go | 19 ++++++++++++++++++- lib/pkcs9/pkcs7.go | 4 +--- lib/pkcs9/structs.go | 1 + signers/appmanifest/signer.go | 6 ++++-- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/appmanifest/signmanifest.go b/lib/appmanifest/signmanifest.go index 0631a9d..a0cde34 100644 --- a/lib/appmanifest/signmanifest.go +++ b/lib/appmanifest/signmanifest.go @@ -209,7 +209,7 @@ func (m *SignedManifest) AddTimestamp(token *pkcs7.ContentInfoSignedData) error if err != nil { return err } - cs, err := pkcs9.VerifyMicrosoftToken(token, m.EncryptedDigest) + cs, err := VerifyTimestamp(token, m.EncryptedDigest, m.Signature.Intermediates) if err != nil { return fmt.Errorf("failed to validate timestamp: %s", err) } diff --git a/lib/appmanifest/verify.go b/lib/appmanifest/verify.go index 52d888b..6032705 100644 --- a/lib/appmanifest/verify.go +++ b/lib/appmanifest/verify.go @@ -18,6 +18,7 @@ package appmanifest import ( "crypto" + "crypto/x509" "encoding/base64" "errors" "fmt" @@ -91,7 +92,8 @@ func Verify(manifest []byte) (*ManifestSignature, error) { if err != nil { return nil, fmt.Errorf("invalid timestamp: %s", err) } - cs, err := pkcs9.VerifyMicrosoftToken(timestamp, secondary.EncryptedDigest) + + cs, err := VerifyTimestamp(timestamp, secondary.EncryptedDigest, secondary.Certificates) if err != nil { return nil, fmt.Errorf("invalid timestamp: %s", err) } @@ -105,3 +107,18 @@ func Verify(manifest []byte) (*ManifestSignature, error) { PublicKeyToken: token, }, nil } + +func VerifyTimestamp(timestamp *pkcs7.ContentInfoSignedData, encryptedDigest []byte, extraCerts []*x509.Certificate) (*pkcs9.CounterSignature, error) { + var cs *pkcs9.CounterSignature + var err error + + if timestamp.Content.ContentInfo.ContentType.Equal(pkcs9.OidTSTInfo) { + // pkcs9 timestamp + cs, err = pkcs9.Verify(timestamp, encryptedDigest, extraCerts) + } else { + // legacy timestamp + cs, err = pkcs9.VerifyMicrosoftToken(timestamp, encryptedDigest) + } + + return cs, err +} diff --git a/lib/pkcs9/pkcs7.go b/lib/pkcs9/pkcs7.go index 32178eb..87a25ab 100644 --- a/lib/pkcs9/pkcs7.go +++ b/lib/pkcs9/pkcs7.go @@ -23,7 +23,6 @@ import ( "crypto/x509" "errors" "fmt" - "log" "time" "github.com/sassoftware/relic/lib/pkcs7" @@ -183,8 +182,7 @@ func VerifyMicrosoftToken(token *pkcs7.ContentInfoSignedData, encryptedDigest [] return nil, err } if !bytes.Equal(content, encryptedDigest) { - // return nil, errors.New("timestamp does not match the enclosing signature") - log.Printf("warning: timestamp does not match the enclosing signature") + return nil, errors.New("timestamp does not match the enclosing signature") } hash, _ := x509tools.PkixDigestToHash(sig.SignerInfo.DigestAlgorithm) var signingTime time.Time diff --git a/lib/pkcs9/structs.go b/lib/pkcs9/structs.go index 97b5304..a6a3f6b 100644 --- a/lib/pkcs9/structs.go +++ b/lib/pkcs9/structs.go @@ -54,6 +54,7 @@ const ( var ( OidKeyPurposeTimeStamping = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 3, 8} + OidTSTInfo = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 1, 4} OidAttributeTimeStampToken = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 2, 14} OidAttributeCounterSign = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 6} diff --git a/signers/appmanifest/signer.go b/signers/appmanifest/signer.go index 1d6081c..e47f26f 100644 --- a/signers/appmanifest/signer.go +++ b/signers/appmanifest/signer.go @@ -43,6 +43,7 @@ var AppSigner = &signers.Signer{ } func init() { + AppSigner.Flags().Bool("rfc3161-timestamp", true, "(APPMANIFEST) Timestamp with RFC3161 server") signers.Register(AppSigner) } @@ -66,9 +67,10 @@ func sign(r io.Reader, cert *certloader.Certificate, opts signers.SignOpts) ([]b if cert.Timestamper != nil { tsreq := &pkcs9.Request{ EncryptedDigest: signed.EncryptedDigest, - Legacy: false, - Hash: opts.Hash, + Legacy: !opts.Flags.GetBool("rfc3161-timestamp"), + Hash: opts.Hash, } + token, err := cert.Timestamper.Timestamp(opts.Context(), tsreq) if err != nil { return nil, err