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
// will also be added to the SignedData.
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
sdCerts, err := sd2.psd.X509Certificates()
sdCerts, err := sd2.X509Certificates()
if err != nil {
t.Fatal(err)
}
@ -53,7 +53,7 @@ func TestSign(t *testing.T) {
}
// 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)) {
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
sdCerts, err := sd2.psd.X509Certificates()
sdCerts, err := sd2.X509Certificates()
if err != nil {
t.Fatal(err)
}
@ -97,7 +97,7 @@ func TestSignDetached(t *testing.T) {
}
// 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)) {
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.
type SignedData struct {
psd *protocol.SignedData
*protocol.SignedData
}
// NewSignedData creates a new SignedData from the given data.
@ -19,12 +19,12 @@ func NewSignedData(data []byte) (*SignedData, error) {
return nil, err
}
psd, err := protocol.NewSignedData(eci)
sd, err := protocol.NewSignedData(eci)
if err != nil {
return nil, err
}
return &SignedData{psd}, nil
return &SignedData{sd}, nil
}
// ParseSignedData parses a SignedData from BER encoded data.
@ -34,32 +34,32 @@ func ParseSignedData(ber []byte) (*SignedData, error) {
return nil, err
}
psd, err := ci.SignedDataContent()
sd, err := ci.SignedDataContent()
if err != nil {
return nil, err
}
return &SignedData{psd}, nil
return &SignedData{sd}, nil
}
// 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
// the SignedData encapsulates something other than data (1.2.840.113549.1.7.1).
func (sd *SignedData) GetData() ([]byte, error) {
return sd.psd.EncapContentInfo.DataEContent()
return sd.EncapContentInfo.DataEContent()
}
// GetCertificates gets all the certificates stored in the SignedData.
func (sd *SignedData) GetCertificates() ([]*x509.Certificate, error) {
return sd.psd.X509Certificates()
return sd.X509Certificates()
}
// SetCertificates replaces the certificates stored in the SignedData with new
// ones.
func (sd *SignedData) SetCertificates(certs []*x509.Certificate) error {
sd.psd.ClearCertificates()
sd.ClearCertificates()
for _, cert := range certs {
if err := sd.psd.AddCertificate(cert); err != nil {
if err := sd.AddCertificate(cert); err != nil {
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
// can be added after this method has been called.
func (sd *SignedData) Detached() {
sd.psd.EncapContentInfo.EContent = asn1.RawValue{}
sd.EncapContentInfo.EContent = asn1.RawValue{}
}
// IsDetached checks if this SignedData has data content.
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.
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.
func (sd *SignedData) AddTimestamps(url string) error {
var (
attrs = make([]protocol.Attribute, len(sd.psd.SignerInfos))
attrs = make([]protocol.Attribute, len(sd.SignerInfos))
err error
)
// Fetch all timestamp tokens before adding any to sd. This avoids a partial
// failure.
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
}
}
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
@ -88,7 +88,7 @@ func getTimestamp(si protocol.SignerInfo, opts x509.VerifyOptions) (timestamp.In
return timestamp.Info{}, err
}
tsti, err := timestamp.ParseInfo(tst.psd.EncapContentInfo)
tsti, err := timestamp.ParseInfo(tst.EncapContentInfo)
if err != nil {
return timestamp.Info{}, err
}

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

@ -24,7 +24,7 @@ func TestAddTimestamps(t *testing.T) {
if _, err := sd.Verify(intermediateOpts); err != nil {
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)
}
@ -68,17 +68,17 @@ func TestTimestampsVerifications(t *testing.T) {
getTimestampedSignedData := func() *SignedData {
sd, _ := NewSignedData([]byte("hi"))
sd.Sign(leaf.Chain(), leaf.PrivateKey)
tsReq, _ := tsRequest(sd.psd.SignerInfos[0])
tsReq, _ := tsRequest(sd.SignerInfos[0])
tsResp, _ := tsa.Do(tsReq)
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
}
// Good timestamp
tsa.Clear()
sd := getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err != nil {
if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err != nil {
t.Fatal(err)
}
if _, err := sd.Verify(intermediateOpts); err != nil {
@ -97,7 +97,7 @@ func TestTimestampsVerifications(t *testing.T) {
return info
})
sd = getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err != nil {
if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err != nil {
t.Fatal(err)
}
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
})
sd = getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err != nil {
if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err != nil {
t.Fatal(err)
}
if _, err := sd.Verify(intermediateOpts); err != nil {
@ -135,7 +135,7 @@ func TestTimestampsVerifications(t *testing.T) {
return info
})
sd = getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err != nil {
if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err != nil {
t.Fatal(err)
}
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
})
sd = getTimestampedSignedData()
if _, err := getTimestamp(sd.psd.SignerInfos[0], intermediateOpts); err != nil {
if _, err := getTimestamp(sd.SignerInfos[0], intermediateOpts); err != nil {
t.Fatal(err)
}
if _, err := sd.Verify(intermediateOpts); err != nil {
@ -167,7 +167,7 @@ func TestTimestampsVerifications(t *testing.T) {
return info
})
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)
}
@ -179,7 +179,7 @@ func TestTimestampsVerifications(t *testing.T) {
return tst
})
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")
} else if _, ok := err.(x509.UnknownAuthorityError); !ok {
t.Fatalf("expected x509.UnknownAuthorityError, got %v", err)
@ -191,7 +191,7 @@ func TestTimestampsVerifications(t *testing.T) {
return tst
})
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)
}
}

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

@ -16,7 +16,7 @@ import (
//
// WARNING: this function doesn't do any revocation checking.
func (sd *SignedData) Verify(opts x509.VerifyOptions) ([][][]*x509.Certificate, error) {
econtent, err := sd.psd.EncapContentInfo.EContentValue()
econtent, err := sd.EncapContentInfo.EContentValue()
if err != nil {
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.
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 sd.verify(message, opts)
}
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"}
}
certs, err := sd.psd.X509Certificates()
certs, err := sd.X509Certificates()
if err != nil {
return nil, err
}
@ -64,16 +64,16 @@ func (sd *SignedData) verify(econtent []byte, opts x509.VerifyOptions) ([][][]*x
tsOpts := opts
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
// SignedAttrs is optional if EncapContentInfo eContentType isn't id-data.
if si.SignedAttrs == nil {
// SignedAttrs may only be absent if EncapContentInfo eContentType is
// id-data.
if !sd.psd.EncapContentInfo.IsTypeData() {
if !sd.EncapContentInfo.IsTypeData() {
return nil, protocol.ASN1Error{Message: "missing SignedAttrs"}
}
@ -87,7 +87,7 @@ func (sd *SignedData) verify(econtent []byte, opts x509.VerifyOptions) ([][][]*x
if err != nil {
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"}
}

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

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