allow intermediates to be added in addition to leaf cert

This commit is contained in:
Ben Toews 2017-11-27 16:22:30 -07:00
Родитель 737ea9eaba
Коммит 196d48671f
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E9C423BE17EFEE70
4 изменённых файлов: 49 добавлений и 18 удалений

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

@ -623,7 +623,32 @@ func NewSignedData(data []byte) (*SignedData, error) {
}
// AddSignerInfo adds a SignerInfo to the SignedData.
func (sd *SignedData) AddSignerInfo(cert *x509.Certificate, signer crypto.Signer) error {
func (sd *SignedData) AddSignerInfo(chain []*x509.Certificate, signer crypto.Signer) error {
// figure out which certificate is associated with signer.
pub, err := x509.MarshalPKIXPublicKey(signer.Public())
if err != nil {
return err
}
var cert *x509.Certificate
for _, c := range chain {
if err := sd.addCertificate(c); err != nil {
return err
}
certPub, err := x509.MarshalPKIXPublicKey(c.PublicKey)
if err != nil {
return err
}
if bytes.Equal(pub, certPub) {
cert = c
}
}
if cert == nil {
return errors.New("No certificate matching signer's public key")
}
sid, err := NewIssuerAndSerialNumber(cert)
if err != nil {
return err
@ -695,10 +720,6 @@ func (sd *SignedData) AddSignerInfo(cert *x509.Certificate, signer crypto.Signer
return err
}
if err := sd.addCertificate(cert); err != nil {
return err
}
sd.addDigestAlgorithm(si.DigestAlgorithm)
sd.SignerInfos = append(sd.SignerInfos, si)

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

@ -27,7 +27,8 @@ func TestSignerInfo(t *testing.T) {
t.Fatal(err)
}
if err = sd.AddSignerInfo(cert, priv.(*ecdsa.PrivateKey)); err != nil {
chain := []*x509.Certificate{cert}
if err = sd.AddSignerInfo(chain, priv.(*ecdsa.PrivateKey)); err != nil {
t.Fatal(err)
}

26
sign.go
Просмотреть файл

@ -5,15 +5,17 @@ import (
"crypto/x509"
)
// Sign creates a CMS SignedData from the content and signs it with the
// certificate and signer. The DER encoded CMS message is returned.
func Sign(data []byte, cert *x509.Certificate, signer crypto.Signer) ([]byte, error) {
// Sign creates a CMS SignedData from the content and signs it with signer. At
// minimum, chain must contain the leaf certificate associated with the signer.
// Any additional intermediates will also be added to the SignedData. The DER
// encoded CMS message is returned.
func Sign(data []byte, chain []*x509.Certificate, signer crypto.Signer) ([]byte, error) {
sd, err := NewSignedData(data)
if err != nil {
return nil, err
}
if err = sd.Sign(cert, signer); err != nil {
if err = sd.Sign(chain, signer); err != nil {
return nil, err
}
@ -21,14 +23,16 @@ func Sign(data []byte, cert *x509.Certificate, signer crypto.Signer) ([]byte, er
}
// SignDetached creates a detached CMS SignedData from the content and signs it
// with the certificate and signer. The DER encoded CMS message is returned.
func SignDetached(data []byte, cert *x509.Certificate, signer crypto.Signer) ([]byte, error) {
// with signer. At minimum, chain must contain the leaf certificate associated
// with the signer. Any additional intermediates will also be added to the
// SignedData. The DER encoded CMS message is returned.
func SignDetached(data []byte, chain []*x509.Certificate, signer crypto.Signer) ([]byte, error) {
sd, err := NewSignedData(data)
if err != nil {
return nil, err
}
if err = sd.Sign(cert, signer); err != nil {
if err = sd.Sign(chain, signer); err != nil {
return nil, err
}
@ -37,7 +41,9 @@ func SignDetached(data []byte, cert *x509.Certificate, signer crypto.Signer) ([]
return sd.ToDER()
}
// Sign adds a signature to the SignedData.
func (sd *SignedData) Sign(cert *x509.Certificate, signer crypto.Signer) error {
return sd.psd.AddSignerInfo(cert, signer)
// Sign adds a signature to the SignedData.At minimum, chain must contain the
// 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)
}

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

@ -2,6 +2,7 @@ package cms
import (
"crypto/ecdsa"
"crypto/x509"
"testing"
"golang.org/x/crypto/pkcs12"
@ -12,10 +13,11 @@ func TestSign(t *testing.T) {
if err != nil {
t.Fatal(err)
}
chain := []*x509.Certificate{cert}
data := []byte("hello, world!")
ci, err := Sign(data, cert, priv.(*ecdsa.PrivateKey))
ci, err := Sign(data, chain, priv.(*ecdsa.PrivateKey))
if err != nil {
t.Fatal(err)
}
@ -35,10 +37,11 @@ func TestSignDetached(t *testing.T) {
if err != nil {
t.Fatal(err)
}
chain := []*x509.Certificate{cert}
data := []byte("hello, world!")
ci, err := SignDetached(data, cert, priv.(*ecdsa.PrivateKey))
ci, err := SignDetached(data, chain, priv.(*ecdsa.PrivateKey))
if err != nil {
t.Fatal(err)
}