Export SignedData in cms. Fixes #89

This commit is contained in:
Florent CHAUVEAU 2022-06-24 13:02:15 +02:00
Родитель 3564e86011
Коммит d66840f9a5
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B3D359E40653E07F
7 изменённых файлов: 42 добавлений и 42 удалений

Просмотреть файл

@ -45,5 +45,5 @@ func SignDetached(data []byte, chain []*x509.Certificate, signer crypto.Signer)
// leaf certificate associated with the signer. Any additional intermediates // leaf certificate associated with the signer. Any additional intermediates
// will also be added to the SignedData. // will also be added to the SignedData.
func (sd *SignedData) Sign(chain []*x509.Certificate, signer crypto.Signer) error { func (sd *SignedData) Sign(chain []*x509.Certificate, signer crypto.Signer) error {
return sd.psd.AddSignerInfo(chain, signer) return sd.AddSignerInfo(chain, signer)
} }

Просмотреть файл

@ -33,7 +33,7 @@ func TestSign(t *testing.T) {
} }
// test that we're including whole chain in sd // test that we're including whole chain in sd
sdCerts, err := sd2.psd.X509Certificates() sdCerts, err := sd2.X509Certificates()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -53,7 +53,7 @@ func TestSign(t *testing.T) {
} }
// check that we're including signing time attribute // check that we're including signing time attribute
st, err := sd2.psd.SignerInfos[0].GetSigningTimeAttribute() st, err := sd2.SignerInfos[0].GetSigningTimeAttribute()
if st.After(time.Now().Add(time.Second)) || st.Before(time.Now().Add(-time.Second)) { if st.After(time.Now().Add(time.Second)) || st.Before(time.Now().Add(-time.Second)) {
t.Fatal("expected SigningTime to be now. Difference was", st.Sub(time.Now())) t.Fatal("expected SigningTime to be now. Difference was", st.Sub(time.Now()))
} }
@ -77,7 +77,7 @@ func TestSignDetached(t *testing.T) {
} }
// test that we're including whole chain in sd // test that we're including whole chain in sd
sdCerts, err := sd2.psd.X509Certificates() sdCerts, err := sd2.X509Certificates()
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -97,7 +97,7 @@ func TestSignDetached(t *testing.T) {
} }
// check that we're including signing time attribute // check that we're including signing time attribute
st, err := sd2.psd.SignerInfos[0].GetSigningTimeAttribute() st, err := sd2.SignerInfos[0].GetSigningTimeAttribute()
if st.After(time.Now().Add(time.Second)) || st.Before(time.Now().Add(-time.Second)) { if st.After(time.Now().Add(time.Second)) || st.Before(time.Now().Add(-time.Second)) {
t.Fatal("expected SigningTime to be now. Difference was", st.Sub(time.Now())) t.Fatal("expected SigningTime to be now. Difference was", st.Sub(time.Now()))
} }

Просмотреть файл

@ -9,7 +9,7 @@ import (
// SignedData represents a signed message or detached signature. // SignedData represents a signed message or detached signature.
type SignedData struct { type SignedData struct {
psd *protocol.SignedData *protocol.SignedData
} }
// NewSignedData creates a new SignedData from the given data. // NewSignedData creates a new SignedData from the given data.
@ -19,12 +19,12 @@ func NewSignedData(data []byte) (*SignedData, error) {
return nil, err return nil, err
} }
psd, err := protocol.NewSignedData(eci) sd, err := protocol.NewSignedData(eci)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &SignedData{psd}, nil return &SignedData{sd}, nil
} }
// ParseSignedData parses a SignedData from BER encoded data. // ParseSignedData parses a SignedData from BER encoded data.
@ -34,32 +34,32 @@ func ParseSignedData(ber []byte) (*SignedData, error) {
return nil, err return nil, err
} }
psd, err := ci.SignedDataContent() sd, err := ci.SignedDataContent()
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &SignedData{psd}, nil return &SignedData{sd}, nil
} }
// GetData gets the encapsulated data from the SignedData. Nil will be returned // GetData gets the encapsulated data from the SignedData. Nil will be returned
// if this is a detached signature. A protocol.ErrWrongType will be returned if // if this is a detached signature. A protocol.ErrWrongType will be returned if
// the SignedData encapsulates something other than data (1.2.840.113549.1.7.1). // the SignedData encapsulates something other than data (1.2.840.113549.1.7.1).
func (sd *SignedData) GetData() ([]byte, error) { func (sd *SignedData) GetData() ([]byte, error) {
return sd.psd.EncapContentInfo.DataEContent() return sd.EncapContentInfo.DataEContent()
} }
// GetCertificates gets all the certificates stored in the SignedData. // GetCertificates gets all the certificates stored in the SignedData.
func (sd *SignedData) GetCertificates() ([]*x509.Certificate, error) { func (sd *SignedData) GetCertificates() ([]*x509.Certificate, error) {
return sd.psd.X509Certificates() return sd.X509Certificates()
} }
// SetCertificates replaces the certificates stored in the SignedData with new // SetCertificates replaces the certificates stored in the SignedData with new
// ones. // ones.
func (sd *SignedData) SetCertificates(certs []*x509.Certificate) error { func (sd *SignedData) SetCertificates(certs []*x509.Certificate) error {
sd.psd.ClearCertificates() sd.ClearCertificates()
for _, cert := range certs { for _, cert := range certs {
if err := sd.psd.AddCertificate(cert); err != nil { if err := sd.AddCertificate(cert); err != nil {
return err return err
} }
} }
@ -69,15 +69,15 @@ func (sd *SignedData) SetCertificates(certs []*x509.Certificate) error {
// Detached removes the data content from this SignedData. No more signatures // Detached removes the data content from this SignedData. No more signatures
// can be added after this method has been called. // can be added after this method has been called.
func (sd *SignedData) Detached() { func (sd *SignedData) Detached() {
sd.psd.EncapContentInfo.EContent = asn1.RawValue{} sd.EncapContentInfo.EContent = asn1.RawValue{}
} }
// IsDetached checks if this SignedData has data content. // IsDetached checks if this SignedData has data content.
func (sd *SignedData) IsDetached() bool { func (sd *SignedData) IsDetached() bool {
return sd.psd.EncapContentInfo.EContent.Bytes == nil return sd.EncapContentInfo.EContent.Bytes == nil
} }
// ToDER encodes this SignedData message using DER. // ToDER encodes this SignedData message using DER.
func (sd *SignedData) ToDER() ([]byte, error) { func (sd *SignedData) ToDER() ([]byte, error) {
return sd.psd.ContentInfoDER() return sd.ContentInfoDER()
} }

Просмотреть файл

@ -16,20 +16,20 @@ import (
// in old messages signed with revoked keys. // in old messages signed with revoked keys.
func (sd *SignedData) AddTimestamps(url string) error { func (sd *SignedData) AddTimestamps(url string) error {
var ( var (
attrs = make([]protocol.Attribute, len(sd.psd.SignerInfos)) attrs = make([]protocol.Attribute, len(sd.SignerInfos))
err error err error
) )
// Fetch all timestamp tokens before adding any to sd. This avoids a partial // Fetch all timestamp tokens before adding any to sd. This avoids a partial
// failure. // failure.
for i := range attrs { for i := range attrs {
if attrs[i], err = fetchTS(url, sd.psd.SignerInfos[i]); err != nil { if attrs[i], err = fetchTS(url, sd.SignerInfos[i]); err != nil {
return err return err
} }
} }
for i := range attrs { for i := range attrs {
sd.psd.SignerInfos[i].UnsignedAttrs = append(sd.psd.SignerInfos[i].UnsignedAttrs, attrs[i]) sd.SignerInfos[i].UnsignedAttrs = append(sd.SignerInfos[i].UnsignedAttrs, attrs[i])
} }
return nil return nil
@ -88,7 +88,7 @@ func getTimestamp(si protocol.SignerInfo, opts x509.VerifyOptions) (timestamp.In
return timestamp.Info{}, err return timestamp.Info{}, err
} }
tsti, err := timestamp.ParseInfo(tst.psd.EncapContentInfo) tsti, err := timestamp.ParseInfo(tst.EncapContentInfo)
if err != nil { if err != nil {
return timestamp.Info{}, err return timestamp.Info{}, err
} }

Просмотреть файл

@ -24,7 +24,7 @@ func TestAddTimestamps(t *testing.T) {
if _, err := sd.Verify(intermediateOpts); err != nil { if _, err := sd.Verify(intermediateOpts); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err != nil { if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -68,17 +68,17 @@ func TestTimestampsVerifications(t *testing.T) {
getTimestampedSignedData := func() *SignedData { getTimestampedSignedData := func() *SignedData {
sd, _ := NewSignedData([]byte("hi")) sd, _ := NewSignedData([]byte("hi"))
sd.Sign(leaf.Chain(), leaf.PrivateKey) sd.Sign(leaf.Chain(), leaf.PrivateKey)
tsReq, _ := tsRequest(sd.psd.SignerInfos[0]) tsReq, _ := tsRequest(sd.SignerInfos[0])
tsResp, _ := tsa.Do(tsReq) tsResp, _ := tsa.Do(tsReq)
tsAttr, _ := protocol.NewAttribute(oid.AttributeTimeStampToken, tsResp.TimeStampToken) tsAttr, _ := protocol.NewAttribute(oid.AttributeTimeStampToken, tsResp.TimeStampToken)
sd.psd.SignerInfos[0].UnsignedAttrs = append(sd.psd.SignerInfos[0].UnsignedAttrs, tsAttr) sd.SignerInfos[0].UnsignedAttrs = append(sd.SignerInfos[0].UnsignedAttrs, tsAttr)
return sd return sd
} }
// Good timestamp // Good timestamp
tsa.Clear() tsa.Clear()
sd := getTimestampedSignedData() sd := getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err != nil { if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := sd.Verify(intermediateOpts); err != nil { if _, err := sd.Verify(intermediateOpts); err != nil {
@ -97,7 +97,7 @@ func TestTimestampsVerifications(t *testing.T) {
return info return info
}) })
sd = getTimestampedSignedData() sd = getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err != nil { if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := sd.Verify(intermediateOpts); err == nil || !strings.HasPrefix(err.Error(), "x509: certificate has expired") { if _, err := sd.Verify(intermediateOpts); err == nil || !strings.HasPrefix(err.Error(), "x509: certificate has expired") {
@ -116,7 +116,7 @@ func TestTimestampsVerifications(t *testing.T) {
return info return info
}) })
sd = getTimestampedSignedData() sd = getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err != nil { if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := sd.Verify(intermediateOpts); err != nil { if _, err := sd.Verify(intermediateOpts); err != nil {
@ -135,7 +135,7 @@ func TestTimestampsVerifications(t *testing.T) {
return info return info
}) })
sd = getTimestampedSignedData() sd = getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err != nil { if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := sd.Verify(intermediateOpts); err == nil || !strings.HasPrefix(err.Error(), "x509: certificate has expired") { if _, err := sd.Verify(intermediateOpts); err == nil || !strings.HasPrefix(err.Error(), "x509: certificate has expired") {
@ -154,7 +154,7 @@ func TestTimestampsVerifications(t *testing.T) {
return info return info
}) })
sd = getTimestampedSignedData() sd = getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err != nil { if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if _, err := sd.Verify(intermediateOpts); err != nil { if _, err := sd.Verify(intermediateOpts); err != nil {
@ -167,7 +167,7 @@ func TestTimestampsVerifications(t *testing.T) {
return info return info
}) })
sd = getTimestampedSignedData() sd = getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err == nil || err.Error() != "invalid message imprint" { if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err == nil || err.Error() != "invalid message imprint" {
t.Fatalf("expected 'invalid message imprint', got %v", err) t.Fatalf("expected 'invalid message imprint', got %v", err)
} }
@ -179,7 +179,7 @@ func TestTimestampsVerifications(t *testing.T) {
return tst return tst
}) })
sd = getTimestampedSignedData() sd = getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err == nil { if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err == nil {
t.Fatal("expected error") t.Fatal("expected error")
} else if _, ok := err.(x509.UnknownAuthorityError); !ok { } else if _, ok := err.(x509.UnknownAuthorityError); !ok {
t.Fatalf("expected x509.UnknownAuthorityError, got %v", err) t.Fatalf("expected x509.UnknownAuthorityError, got %v", err)
@ -191,7 +191,7 @@ func TestTimestampsVerifications(t *testing.T) {
return tst return tst
}) })
sd = getTimestampedSignedData() sd = getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err != rsa.ErrVerification { if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err != rsa.ErrVerification {
t.Fatalf("expected %v, got %v", rsa.ErrVerification, err) t.Fatalf("expected %v, got %v", rsa.ErrVerification, err)
} }
} }

Просмотреть файл

@ -16,7 +16,7 @@ import (
// //
// WARNING: this function doesn't do any revocation checking. // WARNING: this function doesn't do any revocation checking.
func (sd *SignedData) Verify(opts x509.VerifyOptions) ([][][]*x509.Certificate, error) { func (sd *SignedData) Verify(opts x509.VerifyOptions) ([][][]*x509.Certificate, error) {
econtent, err := sd.psd.EncapContentInfo.EContentValue() econtent, err := sd.EncapContentInfo.EContentValue()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -35,18 +35,18 @@ func (sd *SignedData) Verify(opts x509.VerifyOptions) ([][][]*x509.Certificate,
// //
// WARNING: this function doesn't do any revocation checking. // WARNING: this function doesn't do any revocation checking.
func (sd *SignedData) VerifyDetached(message []byte, opts x509.VerifyOptions) ([][][]*x509.Certificate, error) { func (sd *SignedData) VerifyDetached(message []byte, opts x509.VerifyOptions) ([][][]*x509.Certificate, error) {
if sd.psd.EncapContentInfo.EContent.Bytes != nil { if sd.EncapContentInfo.EContent.Bytes != nil {
return nil, errors.New("signature not detached") return nil, errors.New("signature not detached")
} }
return sd.verify(message, opts) return sd.verify(message, opts)
} }
func (sd *SignedData) verify(econtent []byte, opts x509.VerifyOptions) ([][][]*x509.Certificate, error) { func (sd *SignedData) verify(econtent []byte, opts x509.VerifyOptions) ([][][]*x509.Certificate, error) {
if len(sd.psd.SignerInfos) == 0 { if len(sd.SignerInfos) == 0 {
return nil, protocol.ASN1Error{Message: "no signatures found"} return nil, protocol.ASN1Error{Message: "no signatures found"}
} }
certs, err := sd.psd.X509Certificates() certs, err := sd.X509Certificates()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -64,16 +64,16 @@ func (sd *SignedData) verify(econtent []byte, opts x509.VerifyOptions) ([][][]*x
tsOpts := opts tsOpts := opts
tsOpts.KeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageTimeStamping} tsOpts.KeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageTimeStamping}
chains := make([][][]*x509.Certificate, 0, len(sd.psd.SignerInfos)) chains := make([][][]*x509.Certificate, 0, len(sd.SignerInfos))
for _, si := range sd.psd.SignerInfos { for _, si := range sd.SignerInfos {
var signedMessage []byte var signedMessage []byte
// SignedAttrs is optional if EncapContentInfo eContentType isn't id-data. // SignedAttrs is optional if EncapContentInfo eContentType isn't id-data.
if si.SignedAttrs == nil { if si.SignedAttrs == nil {
// SignedAttrs may only be absent if EncapContentInfo eContentType is // SignedAttrs may only be absent if EncapContentInfo eContentType is
// id-data. // id-data.
if !sd.psd.EncapContentInfo.IsTypeData() { if !sd.EncapContentInfo.IsTypeData() {
return nil, protocol.ASN1Error{Message: "missing SignedAttrs"} return nil, protocol.ASN1Error{Message: "missing SignedAttrs"}
} }
@ -87,7 +87,7 @@ func (sd *SignedData) verify(econtent []byte, opts x509.VerifyOptions) ([][][]*x
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !siContentType.Equal(sd.psd.EncapContentInfo.EContentType) { if !siContentType.Equal(sd.EncapContentInfo.EContentType) {
return nil, protocol.ASN1Error{Message: "invalid SignerInfo ContentType attribute"} return nil, protocol.ASN1Error{Message: "invalid SignerInfo ContentType attribute"}
} }

Просмотреть файл

@ -36,7 +36,7 @@ func ExampleSignedData() {
func verifyOptionsForSignedData(sd *SignedData) (opts x509.VerifyOptions) { func verifyOptionsForSignedData(sd *SignedData) (opts x509.VerifyOptions) {
// add self-signed cert as trusted root // add self-signed cert as trusted root
certs, err := sd.psd.X509Certificates() certs, err := sd.X509Certificates()
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -46,7 +46,7 @@ func verifyOptionsForSignedData(sd *SignedData) (opts x509.VerifyOptions) {
} }
// trust signing time // trust signing time
signingTime, err := sd.psd.SignerInfos[0].GetSigningTimeAttribute() signingTime, err := sd.SignerInfos[0].GetSigningTimeAttribute()
if err != nil { if err != nil {
panic(err) panic(err)
} }