DigestAlgorithm & SigningCertificate attribute
This commit is contained in:
@@ -71,8 +71,9 @@ err = sign.Sign(input_file, output_file, rdr, size, sign.SignData{
|
|||||||
CertType: sign.CertificationSignature,
|
CertType: sign.CertificationSignature,
|
||||||
DocMDPPerm: sign.AllowFillingExistingFormFieldsAndSignaturesPerms,
|
DocMDPPerm: sign.AllowFillingExistingFormFieldsAndSignaturesPerms,
|
||||||
},
|
},
|
||||||
Signer: privateKey, // crypto.Signer
|
Signer: privateKey, // crypto.Signer
|
||||||
Certificate: certificate, // x509.Certificate
|
DigestAlgorithm: crypto.SHA256, // hash algorithm for the digest creation
|
||||||
|
Certificate: certificate, // x509.Certificate
|
||||||
CertificateChains: certificate_chains, // x509.Certificate.Verify()
|
CertificateChains: certificate_chains, // x509.Certificate.Verify()
|
||||||
TSA: sign.TSA{
|
TSA: sign.TSA{
|
||||||
URL: "https://freetsa.org/tsr",
|
URL: "https://freetsa.org/tsr",
|
||||||
|
2
sign.go
2
sign.go
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
@@ -142,6 +143,7 @@ func main() {
|
|||||||
DocMDPPerm: sign.AllowFillingExistingFormFieldsAndSignaturesPerms,
|
DocMDPPerm: sign.AllowFillingExistingFormFieldsAndSignaturesPerms,
|
||||||
},
|
},
|
||||||
Signer: pkey,
|
Signer: pkey,
|
||||||
|
DigestAlgorithm: crypto.SHA256,
|
||||||
Certificate: cert,
|
Certificate: cert,
|
||||||
CertificateChains: certificate_chains,
|
CertificateChains: certificate_chains,
|
||||||
TSA: sign.TSA{
|
TSA: sign.TSA{
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
package sign
|
package sign
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto"
|
||||||
|
"encoding/asn1"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -140,3 +142,28 @@ func writePartFromSourceFileToTargetFile(input_file io.ReadSeeker, output_file i
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var hashOIDs = map[crypto.Hash]asn1.ObjectIdentifier{
|
||||||
|
crypto.SHA1: asn1.ObjectIdentifier([]int{1, 3, 14, 3, 2, 26}),
|
||||||
|
crypto.SHA256: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 1}),
|
||||||
|
crypto.SHA384: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 2}),
|
||||||
|
crypto.SHA512: asn1.ObjectIdentifier([]int{2, 16, 840, 1, 101, 3, 4, 2, 3}),
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHashAlgorithmFromOID(target asn1.ObjectIdentifier) crypto.Hash {
|
||||||
|
for hash, oid := range hashOIDs {
|
||||||
|
if oid.Equal(target) {
|
||||||
|
return hash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return crypto.Hash(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOIDFromHashAlgorithm(target crypto.Hash) asn1.ObjectIdentifier {
|
||||||
|
for hash, oid := range hashOIDs {
|
||||||
|
if hash == target {
|
||||||
|
return oid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package sign
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/asn1"
|
"encoding/asn1"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
@@ -13,6 +14,8 @@ import (
|
|||||||
|
|
||||||
"github.com/digitorus/pkcs7"
|
"github.com/digitorus/pkcs7"
|
||||||
"github.com/digitorus/timestamp"
|
"github.com/digitorus/timestamp"
|
||||||
|
"golang.org/x/crypto/cryptobyte"
|
||||||
|
cryptobyte_asn1 "golang.org/x/crypto/cryptobyte/asn1"
|
||||||
)
|
)
|
||||||
|
|
||||||
const signatureByteRangePlaceholder = "/ByteRange[0 ********** ********** **********]"
|
const signatureByteRangePlaceholder = "/ByteRange[0 ********** ********** **********]"
|
||||||
@@ -121,6 +124,39 @@ func (context *SignContext) fetchRevocationData() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (context *SignContext) createSigningCertificateAttribute() (*pkcs7.Attribute, error) {
|
||||||
|
hash := context.SignData.DigestAlgorithm.New()
|
||||||
|
hash.Write(context.SignData.Certificate.Raw)
|
||||||
|
|
||||||
|
var b cryptobyte.Builder
|
||||||
|
b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) { // SigningCertificate
|
||||||
|
b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) { // []ESSCertID, []ESSCertIDv2
|
||||||
|
b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) { // ESSCertID, ESSCertIDv2
|
||||||
|
if context.SignData.DigestAlgorithm.HashFunc() != crypto.SHA1 &&
|
||||||
|
context.SignData.DigestAlgorithm.HashFunc() != crypto.SHA256 { // default SHA-256
|
||||||
|
b.AddASN1(cryptobyte_asn1.SEQUENCE, func(b *cryptobyte.Builder) { // AlgorithmIdentifier
|
||||||
|
b.AddASN1ObjectIdentifier(getOIDFromHashAlgorithm(context.SignData.DigestAlgorithm))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
b.AddASN1OctetString(hash.Sum(nil)) // certHash
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
sse, err := b.Bytes()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
signingCertificate := pkcs7.Attribute{
|
||||||
|
Type: asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 2, 47}, // SigningCertificateV2
|
||||||
|
Value: asn1.RawValue{FullBytes: sse},
|
||||||
|
}
|
||||||
|
if context.SignData.DigestAlgorithm.HashFunc() == crypto.SHA1 {
|
||||||
|
signingCertificate.Type = asn1.ObjectIdentifier{1, 2, 840, 113549, 1, 9, 16, 2, 12} // SigningCertificate
|
||||||
|
}
|
||||||
|
return &signingCertificate, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (context *SignContext) createSignature() ([]byte, error) {
|
func (context *SignContext) createSignature() ([]byte, error) {
|
||||||
if _, err := context.OutputBuffer.Seek(0, 0); err != nil {
|
if _, err := context.OutputBuffer.Seek(0, 0); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -140,12 +176,19 @@ func (context *SignContext) createSignature() ([]byte, error) {
|
|||||||
return nil, fmt.Errorf("new signed data: %w", err)
|
return nil, fmt.Errorf("new signed data: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signed_data.SetDigestAlgorithm(getOIDFromHashAlgorithm(context.SignData.DigestAlgorithm))
|
||||||
|
signingCertificate, err := context.createSigningCertificateAttribute()
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("new signed data: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
signer_config := pkcs7.SignerInfoConfig{
|
signer_config := pkcs7.SignerInfoConfig{
|
||||||
ExtraSignedAttributes: []pkcs7.Attribute{
|
ExtraSignedAttributes: []pkcs7.Attribute{
|
||||||
{
|
{
|
||||||
Type: asn1.ObjectIdentifier{1, 2, 840, 113583, 1, 1, 8},
|
Type: asn1.ObjectIdentifier{1, 2, 840, 113583, 1, 1, 8},
|
||||||
Value: context.SignData.RevocationData,
|
Value: context.SignData.RevocationData,
|
||||||
},
|
},
|
||||||
|
*signingCertificate,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -34,6 +34,7 @@ type SignData struct {
|
|||||||
ObjectId uint32
|
ObjectId uint32
|
||||||
Signature SignDataSignature
|
Signature SignDataSignature
|
||||||
Signer crypto.Signer
|
Signer crypto.Signer
|
||||||
|
DigestAlgorithm crypto.Hash
|
||||||
Certificate *x509.Certificate
|
Certificate *x509.Certificate
|
||||||
CertificateChains [][]*x509.Certificate
|
CertificateChains [][]*x509.Certificate
|
||||||
TSA TSA
|
TSA TSA
|
||||||
|
Reference in New Issue
Block a user