moov-io / signedxml

pure go library for processing signed XML documents
MIT License
52 stars 44 forks source link

How to sign an XML choose some settings? #52

Closed faelp22 closed 3 months ago

faelp22 commented 5 months ago

Hello everyone, could anyone create an example of how to sign an XML using the following settings?

Hash http://www.w3.org/2000/09/xmldsig#sha1

Signature http://www.w3.org/2000/09/xmldsig#rsa-sha1

Canonicalization Methods/Transforms http://www.w3.org/TR/2001/REC-xml-c14n-20010315

I've tried to do it, but I can't understand it.

adamdecaf commented 4 months ago

Your Signature element would have those settings included. The XML specifications have all of the values, but they're in code as well

Then you'll marshal and sign the xml. See tests in this repository for examples.

jsdaniell commented 3 months ago

I couldn't find any example on the tests folder :/

adamdecaf commented 3 months ago

You can specify those in the xml - https://github.com/moov-io/signedxml/blob/master/tests/testdata/issue55.xml

Then create a Signer and call .Sign - https://github.com/moov-io/signedxml/blob/master/tests/issue55_test.go#L22

jsdaniell commented 3 months ago

Can you help me to do this using the Signature struct that I created? @adamdecaf Here's my code:

func SignXML(xpath, canonicalizationAlgorithm, certificate, digestAlgorithm, publicKey, privateKey, xmlString string, transforms []string) error {
    if digestAlgorithm == "" {
        digestAlgorithm = "http://www.w3.org/2000/09/xmldsig#sha1"
    }

    if len(transforms) == 0 {
        transforms = []string{
            "http://www.w3.org/2000/09/xmldsig#enveloped-signature",
            "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments",
        }
    }

    if certificate == "" {
        certificate = models.GetX509Cert(publicKey)
    }

    if canonicalizationAlgorithm == "" {
        canonicalizationAlgorithm = dsig.CanonicalXML10WithCommentsAlgorithmId.String()
    }

    if publicKey == "" {
        p, err := GetPublicKeyFromFile()
        if err != nil {
            return err
        }

        publicKey = p
    }

    if privateKey == "" {
        p, err := GetPrivateKeyFromFile()
        if err != nil {
            return err
        }

        privateKey = p
    }

    if xpath == "" {
        return errors.New("xpath is required")
    }

    transformsTypes := xmldsig.TransformsType{Transform: make([]xmldsig.TransformType, len(transforms))}

    for i, t := range transforms {
        transformsTypes.Transform[i] = xmldsig.TransformType{
            Algorithm: t,
            XPath:     []*string{&xpath},
        }
    }

    sig := xmldsig.Signature{
        KeyInfo: &xmldsig.KeyInfoType{
            X509Data: []*xmldsig.X509DataType{
                {
                    X509Certificate: &certificate,
                },
            },
        },
        SignedInfo: xmldsig.SignedInfoType{
            CanonicalizationMethod: xmldsig.CanonicalizationMethodType{
                Algorithm: canonicalizationAlgorithm,
            },
            Reference: []xmldsig.ReferenceType{
                {
                    Transforms: &transformsTypes,
                    DigestMethod: xmldsig.DigestMethodType{
                        Algorithm: digestAlgorithm,
                    },
                },
            },
        },
    }

    spew.Dump(sig)
    return nil
}
adamdecaf commented 3 months ago

What error are you getting?