Fix TSA
This commit is contained in:
2
sign.go
2
sign.go
@@ -106,6 +106,8 @@ func main() {
|
|||||||
certificate_pool.AppendCertsFromPEM(chain_data)
|
certificate_pool.AppendCertsFromPEM(chain_data)
|
||||||
certificate_chains, err = cert.Verify(x509.VerifyOptions{
|
certificate_chains, err = cert.Verify(x509.VerifyOptions{
|
||||||
Intermediates: certificate_pool,
|
Intermediates: certificate_pool,
|
||||||
|
CurrentTime: cert.NotBefore,
|
||||||
|
KeyUsages: []x509.ExtKeyUsage{x509.ExtKeyUsageAny},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@@ -111,52 +111,6 @@ func (context *SignContext) createSignature() ([]byte, error) {
|
|||||||
|
|
||||||
TSATokenChain := make([][]*x509.Certificate, 0)
|
TSATokenChain := make([][]*x509.Certificate, 0)
|
||||||
|
|
||||||
if context.SignData.TSA.URL != "" {
|
|
||||||
timestamp_response, err := context.GetTSA(sign_content)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var rest []byte
|
|
||||||
var resp TSAResponse
|
|
||||||
if rest, err = asn1.Unmarshal(timestamp_response, &resp); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if len(rest) > 0 {
|
|
||||||
return nil, errors.New("trailing data in Time-Stamp response")
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.Status.Status > 0 {
|
|
||||||
return nil, errors.New(fmt.Sprintf("%s: %s", timestamp.FailureInfo(resp.Status.FailInfo).String(), resp.Status.StatusString))
|
|
||||||
}
|
|
||||||
|
|
||||||
timestamp_p7, err := pkcs7.Parse(resp.TimeStampToken.FullBytes)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(resp.TimeStampToken.Bytes) == 0 {
|
|
||||||
return nil, errors.New("no pkcs7 data in Time-Stamp response")
|
|
||||||
}
|
|
||||||
|
|
||||||
timestamp_attribute := pkcs7.Attribute{
|
|
||||||
Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 2, 14},
|
|
||||||
Value: resp.TimeStampToken,
|
|
||||||
}
|
|
||||||
signer_config.ExtraUnsignedAttributes = append(signer_config.ExtraUnsignedAttributes, timestamp_attribute)
|
|
||||||
|
|
||||||
tsa_certificate_pool := x509.NewCertPool()
|
|
||||||
for _, certificate := range timestamp_p7.Certificates {
|
|
||||||
tsa_certificate_pool.AddCert(certificate)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(timestamp_p7.Certificates) > 0 {
|
|
||||||
TSATokenChain, err = timestamp_p7.Certificates[len(timestamp_p7.Certificates)-1].Verify(x509.VerifyOptions{
|
|
||||||
Intermediates: tsa_certificate_pool,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if context.SignData.RevocationFunction != nil {
|
if context.SignData.RevocationFunction != nil {
|
||||||
if context.SignData.CertificateChains != nil && (len(context.SignData.CertificateChains) > 0) {
|
if context.SignData.CertificateChains != nil && (len(context.SignData.CertificateChains) > 0) {
|
||||||
certificate_chain := context.SignData.CertificateChains[0]
|
certificate_chain := context.SignData.CertificateChains[0]
|
||||||
@@ -217,6 +171,43 @@ func (context *SignContext) createSignature() ([]byte, error) {
|
|||||||
// PDF needs a detached signature, meaning the content isn't included.
|
// PDF needs a detached signature, meaning the content isn't included.
|
||||||
signed_data.Detach()
|
signed_data.Detach()
|
||||||
|
|
||||||
|
if context.SignData.TSA.URL != "" {
|
||||||
|
signature_data := signed_data.GetSignedData()
|
||||||
|
|
||||||
|
timestamp_response, err := context.GetTSA(signature_data.SignerInfos[0].EncryptedDigest)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var rest []byte
|
||||||
|
var resp TSAResponse
|
||||||
|
if rest, err = asn1.Unmarshal(timestamp_response, &resp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if len(rest) > 0 {
|
||||||
|
return nil, errors.New("trailing data in Time-Stamp response")
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.Status.Status > 0 {
|
||||||
|
return nil, errors.New(fmt.Sprintf("%s: %s", timestamp.FailureInfo(resp.Status.FailInfo).String(), resp.Status.StatusString))
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = pkcs7.Parse(resp.TimeStampToken.FullBytes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(resp.TimeStampToken.Bytes) == 0 {
|
||||||
|
return nil, errors.New("no pkcs7 data in Time-Stamp response")
|
||||||
|
}
|
||||||
|
|
||||||
|
timestamp_attribute := pkcs7.Attribute{
|
||||||
|
Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 2, 14},
|
||||||
|
Value: resp.TimeStampToken,
|
||||||
|
}
|
||||||
|
signature_data.SignerInfos[0].SetUnauthenticatedAttributes([]pkcs7.Attribute{timestamp_attribute})
|
||||||
|
}
|
||||||
|
|
||||||
return signed_data.Finish()
|
return signed_data.Finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,6 +16,7 @@ import (
|
|||||||
"github.com/digitorus/timestamp"
|
"github.com/digitorus/timestamp"
|
||||||
"log"
|
"log"
|
||||||
"golang.org/x/crypto/ocsp"
|
"golang.org/x/crypto/ocsp"
|
||||||
|
"crypto"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Response struct {
|
type Response struct {
|
||||||
@@ -147,6 +148,22 @@ func Verify(file *os.File) (apiResp *Response, err error) {
|
|||||||
apiResp.Error = fmt.Sprintln("Failed to parse timestamp", err)
|
apiResp.Error = fmt.Sprintln("Failed to parse timestamp", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r := bytes.NewReader(s.EncryptedDigest)
|
||||||
|
h := crypto.SHA256.New()
|
||||||
|
b := make([]byte, 32)
|
||||||
|
for {
|
||||||
|
n, err := r.Read(b)
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
h.Write(b[:n])
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(h.Sum(nil), signer.TimeStamp.HashedMessage) {
|
||||||
|
apiResp.Error = fmt.Sprintln("Hash in timestamp is different from pkcs7")
|
||||||
|
}
|
||||||
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,7 +234,7 @@ func Verify(file *os.File) (apiResp *Response, err error) {
|
|||||||
signer.RevokedCertificate = true
|
signer.RevokedCertificate = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(chain) > 1 && len(chain[0]) > 1 {
|
if len(chain) > 0 && len(chain[0]) > 1 {
|
||||||
issuer := chain[0][1]
|
issuer := chain[0][1]
|
||||||
if resp.Certificate != nil {
|
if resp.Certificate != nil {
|
||||||
err = resp.Certificate.CheckSignatureFrom(issuer)
|
err = resp.Certificate.CheckSignatureFrom(issuer)
|
||||||
|
Reference in New Issue
Block a user