Skip to content

Commit

Permalink
Support x509 certificate chains
Browse files Browse the repository at this point in the history
  • Loading branch information
apilloud committed Dec 1, 2017
1 parent b7efc62 commit e2d4c9c
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 6 deletions.
4 changes: 4 additions & 0 deletions keystore.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ type X509KeyStore interface {
GetKeyPair() (privateKey *rsa.PrivateKey, cert []byte, err error)
}

type X509ChainStore interface {
GetChain() (certs [][]byte, err error)
}

type X509CertificateStore interface {
Certificates() (roots []*x509.Certificate, err error)
}
Expand Down
14 changes: 12 additions & 2 deletions sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,14 @@ func (ctx *SigningContext) ConstructSignature(el *etree.Element, enveloped bool)
return nil, err
}

certs := [][]byte{cert}
if cs, ok := ctx.KeyStore.(X509ChainStore); ok {
certs, err = cs.GetChain()
if err != nil {
return nil, err
}
}

rawSignature, err := rsa.SignPKCS1v15(rand.Reader, key, ctx.Hash, digest)
if err != nil {
return nil, err
Expand All @@ -186,8 +194,10 @@ func (ctx *SigningContext) ConstructSignature(el *etree.Element, enveloped bool)

keyInfo := ctx.createNamespacedElement(sig, KeyInfoTag)
x509Data := ctx.createNamespacedElement(keyInfo, X509DataTag)
x509Certificate := ctx.createNamespacedElement(x509Data, X509CertificateTag)
x509Certificate.SetText(base64.StdEncoding.EncodeToString(cert))
for _, cert := range certs {
x509Certificate := ctx.createNamespacedElement(x509Data, X509CertificateTag)
x509Certificate.SetText(base64.StdEncoding.EncodeToString(cert))
}

return sig, nil
}
Expand Down
5 changes: 5 additions & 0 deletions tls_keystore.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,8 @@ func (d TLSCertKeyStore) GetKeyPair() (*rsa.PrivateKey, []byte, error) {

return pk, crt, nil
}

//GetChain impliments X509ChainStore using the underlying tls.Certificate
func (d TLSCertKeyStore) GetChain() ([][]byte, error) {
return d.Certificate, nil
}
4 changes: 2 additions & 2 deletions types/signature.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ type KeyInfo struct {
}

type X509Data struct {
XMLName xml.Name `xml:"http://www.w3.org/2000/09/xmldsig# X509Data"`
X509Certificate X509Certificate `xml:"X509Certificate"`
XMLName xml.Name `xml:"http://www.w3.org/2000/09/xmldsig# X509Data"`
X509Certificates []X509Certificate `xml:"X509Certificate"`
}

type X509Certificate struct {
Expand Down
4 changes: 2 additions & 2 deletions validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,12 +364,12 @@ func (ctx *ValidationContext) verifyCertificate(sig *types.Signature) (*x509.Cer

if sig.KeyInfo != nil {
// If the Signature includes KeyInfo, extract the certificate from there
if sig.KeyInfo.X509Data.X509Certificate.Data == "" {
if len(sig.KeyInfo.X509Data.X509Certificates) == 0 || sig.KeyInfo.X509Data.X509Certificates[0].Data == "" {
return nil, errors.New("missing X509Certificate within KeyInfo")
}

certData, err := base64.StdEncoding.DecodeString(
whiteSpace.ReplaceAllString(sig.KeyInfo.X509Data.X509Certificate.Data, ""))
whiteSpace.ReplaceAllString(sig.KeyInfo.X509Data.X509Certificates[0].Data, ""))
if err != nil {
return nil, errors.New("Failed to parse certificate")
}
Expand Down

0 comments on commit e2d4c9c

Please sign in to comment.