### Install goxmldsig via Go Get Source: https://github.com/russellhaering/goxmldsig/blob/main/README.md Command to install the goxmldsig package into your Go workspace. ```bash go get github.com/russellhaering/goxmldsig ``` -------------------------------- ### Create Custom Signing Context with ECDSA in Go Source: https://context7.com/russellhaering/goxmldsig/llms.txt Illustrates creating a flexible signing context using any crypto.Signer implementation, such as ECDSA. This example generates an ECDSA key pair, creates a self-signed certificate, and configures the signing context with ECDSA-SHA256. It then signs an XML element. ```go package main import ( "crypto" "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/x509" "crypto/x509/pkix" "fmt" "math/big" "time" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { // Generate an ECDSA key pair privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { panic(err) } // Create a self-signed certificate template := &x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{CommonName: "Example"}, NotBefore: time.Now(), NotAfter: time.Now().Add(365 * 24 * time.Hour), KeyUsage: x509.KeyUsageDigitalSignature, } certDER, err := x509.CreateCertificate(rand.Reader, template, template, &privateKey.PublicKey, privateKey) if err != nil { panic(err) } // Create signing context with ECDSA signer // The signer interface allows HSM or other key management solutions ctx, err := dsig.NewSigningContext(privateKey, [][]byte{certDER}) if err != nil { panic(err) } // Set signature method for ECDSA-SHA256 err = ctx.SetSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256") if err != nil { panic(err) } // Create and sign an element element := &etree.Element{Tag: "Document"} element.CreateAttr("ID", "doc-001") element.CreateElement("Content").SetText("Signed content") signedElement, err := ctx.SignEnveloped(element) if err != nil { panic(err) } doc := etree.NewDocument() doc.SetRoot(signedElement) xmlStr, _ := doc.WriteToString() fmt.Println(xmlStr) } ``` -------------------------------- ### Sign and Validate SAML Assertion in Go Source: https://context7.com/russellhaering/goxmldsig/llms.txt This example demonstrates the complete lifecycle of a SAML assertion: generating an RSA key pair, signing an XML assertion using an enveloped signature, and validating the signature against a trusted certificate. It utilizes the etree library for XML manipulation and goxmldsig for cryptographic operations. ```go package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "fmt" "math/big" "time" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { idpKey, _ := rsa.GenerateKey(rand.Reader, 2048) idpTemplate := &x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{CommonName: "Identity Provider"}, NotBefore: time.Now().Add(-1 * time.Hour), NotAfter: time.Now().Add(365 * 24 * time.Hour), KeyUsage: x509.KeyUsageDigitalSignature, } idpCertDER, _ := x509.CreateCertificate(rand.Reader, idpTemplate, idpTemplate, &idpKey.PublicKey, idpKey) idpCert, _ := x509.ParseCertificate(idpCertDER) keyStore := &MemoryKeyStore{key: idpKey, cert: idpCertDER} signingCtx := dsig.NewDefaultSigningContext(keyStore) assertion := etree.NewElement("saml:Assertion") assertion.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion") assertion.CreateAttr("ID", "_assertion_"+fmt.Sprintf("%d", time.Now().UnixNano())) assertion.CreateAttr("Version", "2.0") assertion.CreateAttr("IssueInstant", time.Now().UTC().Format(time.RFC3339)) issuer := assertion.CreateElement("saml:Issuer") issuer.SetText("https://idp.example.com") signedAssertion, err := signingCtx.SignEnveloped(assertion) if err != nil { panic(err) } doc := etree.NewDocument() doc.SetRoot(signedAssertion) xmlBytes, _ := doc.WriteToBytes() validationCtx := dsig.NewDefaultValidationContext(&dsig.MemoryX509CertificateStore{ Roots: []*x509.Certificate{idpCert}, }) receivedDoc := etree.NewDocument() receivedDoc.ReadFromBytes(xmlBytes) validated, err := validationCtx.Validate(receivedDoc.Root()) if err != nil { fmt.Println("Validation failed:", err) return } fmt.Println("Validation Successful") } type MemoryKeyStore struct { key *rsa.PrivateKey cert []byte } func (ks *MemoryKeyStore) GetKeyPair() (*rsa.PrivateKey, []byte, error) { return ks.key, ks.cert, nil } ``` -------------------------------- ### Create Canonical XML 1.0 (REC) Canonicalizer in Go Source: https://context7.com/russellhaering/goxmldsig/llms.txt Demonstrates how to create and use the Canonical XML 1.0 (REC) and Canonical XML 1.0 (REC) With Comments canonicalizers. These are used for preparing XML documents for signing by ensuring a consistent representation, with one variant preserving comments and the other removing them. It shows how to get the algorithm URI and canonicalize an XML element. ```go package main import ( "fmt" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { // Canonical XML 1.0 (Recommendation) canonicalizer := dsig.MakeC14N10RecCanonicalizer() fmt.Println("Algorithm:", canonicalizer.Algorithm()) // Output: http://www.w3.org/TR/2001/REC-xml-c14n-20010315 // With comments variant withComments := dsig.MakeC14N10WithCommentsCanonicalizer() fmt.Println("With Comments:", withComments.Algorithm()) // Output: http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments // Example usage doc := etree.NewDocument() doc.ReadFromString(``) // Without comments - removes XML comments noCommentCanon, _ := canonicalizer.Canonicalize(doc.Root()) fmt.Println("No comments:", string(noCommentCanon)) // With comments - preserves XML comments withCommentCanon, _ := withComments.Canonicalize(doc.Root()) fmt.Println("With comments:", string(withCommentCanon)) } ``` -------------------------------- ### Embed XML Signature Type in Go Structs Source: https://context7.com/russellhaering/goxmldsig/llms.txt Shows how to define a Go struct (SAMLResponse) that embeds the `sigtypes.Signature` type for XML marshaling and unmarshaling. This allows applications to easily include and parse XML digital signatures within their data structures, such as SAML responses. The example demonstrates unmarshaling XML data into the struct and accessing signature details. ```go package main import ( "encoding/xml" "fmt" sigtypes "github.com/russellhaering/goxmldsig/types" ) // SAML Response structure with embedded signature type SAMLResponse struct { XMLName xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:protocol Response" ID string `xml:"ID,attr" Version string `xml:"Version,attr" IssueInstant string `xml:"IssueInstant,attr" Destination string `xml:"Destination,attr,omitempty" Issuer string `xml:"urn:oasis:names:tc:SAML:2.0:assertion Issuer" Signature *sigtypes.Signature `xml:"Signature" Status Status `xml:"Status" } type Status struct { StatusCode StatusCode `xml:"StatusCode" } type StatusCode struct { Value string `xml:"Value,attr" } func main() { xmlData := ` https://idp.example.com ... ... ` var response SAMLResponse err := xml.Unmarshal([]byte(xmlData), &response) if err != nil { panic(err) } if response.Signature != nil { fmt.Println("Signature found!") fmt.Println("Signature Method:", response.Signature.SignedInfo.SignatureMethod.Algorithm) fmt.Println("Canonicalization:", response.Signature.SignedInfo.CanonicalizationMethod.Algorithm) } } ``` -------------------------------- ### Implement Custom X509KeyStore in Go Source: https://context7.com/russellhaering/goxmldsig/llms.txt Shows how to implement the X509KeyStore interface to provide custom key management for signing XML documents. This is useful for integrating with existing key management systems or hardware security modules. ```go package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "crypto/x509/pkix" "math/big" "time" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) type CustomKeyStore struct { key *rsa.PrivateKey cert []byte } func (ks *CustomKeyStore) GetKeyPair() (*rsa.PrivateKey, []byte, error) { return ks.key, ks.cert, nil } func main() { privateKey, _ := rsa.GenerateKey(rand.Reader, 2048) template := &x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{CommonName: "My Service"}, NotBefore: time.Now(), NotAfter: time.Now().Add(365 * 24 * time.Hour), KeyUsage: x509.KeyUsageDigitalSignature, } certDER, _ := x509.CreateCertificate(rand.Reader, template, template, &privateKey.PublicKey, privateKey) keyStore := &CustomKeyStore{ key: privateKey, cert: certDER, } ctx := dsig.NewDefaultSigningContext(keyStore) element := etree.NewElement("Message") element.CreateAttr("ID", "msg1") signed, _ := ctx.SignEnveloped(element) doc := etree.NewDocument() doc.SetRoot(signed) xmlStr, _ := doc.WriteToString() println(xmlStr) } ``` -------------------------------- ### Create Default Signing Context in Go Source: https://context7.com/russellhaering/goxmldsig/llms.txt Demonstrates creating a new signing context with default settings using an X509 key store. The context is pre-configured with SHA256 hashing, 'ID' attribute for identification, 'ds' namespace prefix, and C14N11 canonicalization. It then signs an XML element using an enveloped signature. ```go package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "fmt" "math/big" "time" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { // Create a key store with your certificate and private key keyStore := dsig.RandomKeyStoreForTest() // Create a signing context with default settings: // - Hash: SHA256 // - IdAttribute: "ID" // - Prefix: "ds" // - Canonicalizer: C14N11 ctx := dsig.NewDefaultSigningContext(keyStore) // Create an XML element to sign doc := etree.NewDocument() doc.ReadFromString(` https://idp.example.com `) // Sign the element with an enveloped signature signedElement, err := ctx.SignEnveloped(doc.Root()) if err != nil { panic(err) } // Output the signed XML signedDoc := etree.NewDocument() signedDoc.SetRoot(signedElement) xmlStr, _ := signedDoc.WriteToString() fmt.Println(xmlStr) } ``` -------------------------------- ### Sign XML with TLSCertKeyStore Source: https://context7.com/russellhaering/goxmldsig/llms.txt Demonstrates how to wrap a standard library tls.Certificate into a dsig.TLSCertKeyStore to sign XML elements. This is essential for SAML requests where private key access is required. ```go package main import ( "crypto/tls" "fmt" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { tlsCert, err := tls.LoadX509KeyPair("cert.pem", "key.pem") if err != nil { panic(err) } keyStore := dsig.TLSCertKeyStore(tlsCert) ctx := dsig.NewDefaultSigningContext(keyStore) element := etree.NewElement("AuthnRequest") element.CreateAttr("xmlns", "urn:oasis:names:tc:SAML:2.0:protocol") element.CreateAttr("ID", "_request123") signedElement, err := ctx.SignEnveloped(element) if err != nil { panic(err) } doc := etree.NewDocument() doc.SetRoot(signedElement) xmlStr, _ := doc.WriteToString() fmt.Println(xmlStr) } ``` -------------------------------- ### Validate Signatures with MemoryX509CertificateStore Source: https://context7.com/russellhaering/goxmldsig/llms.txt Shows how to initialize a MemoryX509CertificateStore with multiple trusted root certificates. This store is used by the validation context to verify incoming XML signatures against known trusted IdPs. ```go package main import ( "crypto/x509" "encoding/pem" "os" dsig "github.com/russellhaering/goxmldsig" ) func main() { certFiles := []string{"idp1.pem", "idp2.pem", "idp3.pem"} var roots []*x509.Certificate for _, file := range certFiles { pemData, err := os.ReadFile(file) if err != nil { continue } block, _ := pem.Decode(pemData) if block == nil { continue } cert, err := x509.ParseCertificate(block.Bytes) if err != nil { continue } roots = append(roots, cert) } certStore := &dsig.MemoryX509CertificateStore{ Roots: roots, } ctx := dsig.NewDefaultValidationContext(certStore) _ = ctx } ``` -------------------------------- ### Integrate Signature Struct in Go Source: https://github.com/russellhaering/goxmldsig/blob/main/README.md Demonstrates how to include the Signature struct within your application's data structures. ```go import ( sigtypes "github.com/russellhaering/goxmldsig/types" ) type AppHdr struct { ... Signature *sigtypes.Signature } ``` -------------------------------- ### Sign XML Elements with goxmldsig Source: https://github.com/russellhaering/goxmldsig/blob/main/README.md Shows how to initialize a signing context and sign an etree element. Note that modifying the element after signing will invalidate the signature. ```go package main import ( "github.com/beevik/etree" "github.com/russellhaering/goxmldsig" ) func main() { randomKeyStore := dsig.RandomKeyStoreForTest() ctx := dsig.NewDefaultSigningContext(randomKeyStore) elementToSign := &etree.Element{ Tag: "ExampleElement", } elementToSign.CreateAttr("ID", "id1234") signedElement, err := ctx.SignEnveloped(elementToSign) if err != nil { panic(err) } doc := etree.NewDocument() doc.SetRoot(signedElement) str, err := doc.WriteToString() if err != nil { panic(err) } println(str) } ``` -------------------------------- ### Configure Signature Algorithm in goxmldsig Source: https://context7.com/russellhaering/goxmldsig/llms.txt Demonstrates how to set the signature method for a signing context. It supports various RSA and ECDSA algorithms and retrieves the configured identifiers. ```go package main import ( dsig "github.com/russellhaering/goxmldsig" ) func main() { keyStore := dsig.RandomKeyStoreForTest() ctx := dsig.NewDefaultSigningContext(keyStore) err := ctx.SetSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512") if err != nil { panic(err) } sigMethod := ctx.GetSignatureMethodIdentifier() digestAlgo := ctx.GetDigestAlgorithmIdentifier() println("Signature Method:", sigMethod) println("Digest Algorithm:", digestAlgo) } ``` -------------------------------- ### Create Validation Context with Trusted Roots (Go) Source: https://context7.com/russellhaering/goxmldsig/llms.txt Creates a validation context for XML signature verification by initializing a certificate store with trusted root certificates. It parses a PEM-encoded certificate, adds it to a memory-based certificate store, and then uses this store to create a default validation context. This context is then used to validate a signed XML document. Dependencies include standard Go crypto libraries, PEM decoding, and the goxmldsig and etree libraries for XML parsing and validation. ```Go package main import ( "crypto/x509" "encoding/pem" "fmt" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { // Parse your trusted root certificate(s) certPEM := []byte(`-----BEGIN CERTIFICATE----- MIIBkTCB+wIJAKHBfpeg... -----END CERTIFICATE-----`) block, _ := pem.Decode(certPEM) cert, err := x509.ParseCertificate(block.Bytes) if err != nil { panic(err) } // Create a certificate store with trusted roots certStore := &dsig.MemoryX509CertificateStore{ Roots: []*x509.Certificate{cert}, } // Create validation context ctx := dsig.NewDefaultValidationContext(certStore) // Parse the signed XML document doc := etree.NewDocument() err = doc.ReadFromFile("signed-assertion.xml") if err != nil { panic(err) } // Validate returns ONLY the verified content // Always use the returned element, not the original validatedElement, err := ctx.Validate(doc.Root()) if err != nil { fmt.Println("Signature validation failed:", err) return } fmt.Println("Signature is valid!") // Use validatedElement for further processing outputDoc := etree.NewDocument() outputDoc.SetRoot(validatedElement) xmlStr, _ := outputDoc.WriteToString() fmt.Println(xmlStr) } ``` -------------------------------- ### Sign Raw String for HTTP-Redirect Binding (Go) Source: https://context7.com/russellhaering/goxmldsig/llms.txt Signs a raw string, typically a SAML request or response, for use with the HTTP-Redirect binding. It constructs the string to sign by encoding parameters like SAMLRequest, RelayState, and SigAlg, then signs it using a provided signing context and returns the base64-encoded signature. Dependencies include standard Go libraries for encoding, formatting, and URL manipulation, as well as the goxmldsig library. ```Go package main import ( "encoding/base64" "fmt" "net/url" dsig "github.com/russellhaering/goxmldsig" ) func main() { keyStore := dsig.RandomKeyStoreForTest() ctx := dsig.NewDefaultSigningContext(keyStore) // Construct the query string to sign (per SAML HTTP-Redirect binding) // SAMLRequest or SAMLResponse + RelayState + SigAlg samlRequest := "base64EncodedDeflatedRequest" relayState := "someState" sigAlg := ctx.GetSignatureMethodIdentifier() // Build the string to sign params := url.Values{} params.Set("SAMLRequest", samlRequest) params.Set("RelayState", relayState) params.Set("SigAlg", sigAlg) stringToSign := params.Encode() // Sign the string signatureBytes, err := ctx.SignString(stringToSign) if err != nil { panic(err) } // Base64 encode the signature for the URL signature := base64.StdEncoding.EncodeToString(signatureBytes) // Add signature to the redirect URL params.Set("Signature", signature) redirectURL := "https://sp.example.com/sso?" + params.Encode() fmt.Println(redirectURL) } ``` -------------------------------- ### Simulate Time for Certificate Validation using NewFakeClockAt Source: https://context7.com/russellhaering/goxmldsig/llms.txt This snippet demonstrates how to instantiate a validation context and inject a fake clock. By setting the Clock property, developers can force the validation logic to treat a specific timestamp as the current time, facilitating deterministic testing of certificate validity periods. ```go package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "fmt" "math/big" "time" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { key, _ := rsa.GenerateKey(rand.Reader, 2048) template := &x509.Certificate{ SerialNumber: big.NewInt(1), NotBefore: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC), NotAfter: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC), KeyUsage: x509.KeyUsageDigitalSignature, } certDER, _ := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key) cert, _ := x509.ParseCertificate(certDER) ctx := dsig.NewDefaultValidationContext(&dsig.MemoryX509CertificateStore{ Roots: []*x509.Certificate{cert}, }) ctx.Clock = dsig.NewFakeClockAt(time.Date(2024, 6, 15, 12, 0, 0, 0, time.UTC)) productionCtx := dsig.NewDefaultValidationContext(&dsig.MemoryX509CertificateStore{ Roots: []*x509.Certificate{cert}, }) productionCtx.Clock = dsig.NewRealClock() fmt.Println("Test clock set to:", ctx.Clock.Now()) } ``` -------------------------------- ### Validate XML Signatures Source: https://github.com/russellhaering/goxmldsig/blob/main/README.md Demonstrates how to validate an XML element against a root certificate using a validation context. ```go func validate(root *x509.Certificate, el *etree.Element) { ctx := dsig.NewDefaultValidationContext(&dsig.MemoryX509CertificateStore{ Roots: []*x509.Certificate{root}, }) validated, err := ctx.Validate(el) if err != nil { panic(err) } doc := etree.NewDocument() doc.SetRoot(validated) str, err := doc.WriteToString() if err != nil { panic(err) } println(str) } ``` -------------------------------- ### Canonicalize XML with C14N11 Source: https://context7.com/russellhaering/goxmldsig/llms.txt Illustrates the use of the C14N11 canonicalizer to normalize XML documents. This ensures consistent output by sorting attributes and handling namespaces, which is critical for signature integrity. ```go package main import ( "fmt" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { canonicalizer := dsig.MakeC14N11Canonicalizer() fmt.Println("Algorithm:", canonicalizer.Algorithm()) doc := etree.NewDocument() doc.ReadFromString(` `) canonical, err := canonicalizer.Canonicalize(doc.Root()) if err != nil { panic(err) } fmt.Println(string(canonical)) } ``` -------------------------------- ### Canonicalize XML with Exclusive C14N 1.0 Source: https://context7.com/russellhaering/goxmldsig/llms.txt Demonstrates the use of Exclusive XML Canonicalization 1.0 with a prefix list. This is a common requirement for SAML assertions to ensure specific namespace prefixes are preserved during canonicalization. ```go package main import ( "fmt" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { canonicalizerWithPrefixes := dsig.MakeC14N10ExclusiveCanonicalizerWithPrefixList("xs xsi") doc := etree.NewDocument() doc.ReadFromString(` https://idp.example.com `) canonical, err := canonicalizerWithPrefixes.Canonicalize(doc.Root()) if err != nil { panic(err) } fmt.Println(string(canonical)) } ``` -------------------------------- ### Create Enveloped XML Signature Source: https://context7.com/russellhaering/goxmldsig/llms.txt Shows how to sign an XML element using an enveloped signature. The signature is embedded as a child of the signed element, creating a copy of the original data. ```go package main import ( "fmt" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { keyStore := dsig.RandomKeyStoreForTest() ctx := dsig.NewDefaultSigningContext(keyStore) assertion := etree.NewElement("saml:Assertion") assertion.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion") assertion.CreateAttr("ID", "_abc123") signedAssertion, err := ctx.SignEnveloped(assertion) if err != nil { panic(err) } doc := etree.NewDocument() doc.SetRoot(signedAssertion) xmlBytes, _ := doc.WriteToBytes() fmt.Println(string(xmlBytes)) } ``` -------------------------------- ### Validate Enveloped XML Signatures in Go Source: https://context7.com/russellhaering/goxmldsig/llms.txt Demonstrates how to validate an XML element containing an enveloped signature using a trusted certificate store. It emphasizes using the returned validated element for subsequent processing to ensure security. ```go package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "fmt" "math/big" "time" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { key, _ := rsa.GenerateKey(rand.Reader, 2048) template := &x509.Certificate{ SerialNumber: big.NewInt(1), NotBefore: time.Now().Add(-1 * time.Hour), NotAfter: time.Now().Add(24 * time.Hour), KeyUsage: x509.KeyUsageDigitalSignature, } certDER, _ := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key) cert, _ := x509.ParseCertificate(certDER) signingCtx := dsig.NewDefaultSigningContext(dsig.RandomKeyStoreForTest()) element := etree.NewElement("Document") element.CreateAttr("ID", "doc1") element.CreateElement("Data").SetText("Test content") signedElement, _ := signingCtx.SignEnveloped(element) validationCtx := dsig.NewDefaultValidationContext(&dsig.MemoryX509CertificateStore{ Roots: []*x509.Certificate{cert}, }) validated, err := validationCtx.Validate(signedElement) if err != nil { switch err { case dsig.ErrMissingSignature: fmt.Println("No signature found referencing the element") case dsig.ErrInvalidSignature: fmt.Println("Signature structure is invalid") default: fmt.Println("Validation error:", err) } return } data := validated.FindElement("//Data") if data != nil { fmt.Println("Validated data:", data.Text()) } } ``` -------------------------------- ### Construct Detached XML Signature Source: https://context7.com/russellhaering/goxmldsig/llms.txt Illustrates how to create a detached signature element. This allows for placing the signature outside the signed element, useful for custom XML document structures. ```go package main import ( "fmt" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { keyStore := dsig.RandomKeyStoreForTest() ctx := dsig.NewDefaultSigningContext(keyStore) data := etree.NewElement("Data") data.CreateAttr("ID", "data-001") signature, err := ctx.ConstructSignature(data, false) if err != nil { panic(err) } wrapper := etree.NewElement("SignedDocument") wrapper.AddChild(data.Copy()) wrapper.AddChild(signature) doc := etree.NewDocument() doc.SetRoot(wrapper) xmlStr, _ := doc.WriteToString() fmt.Println(xmlStr) } ``` -------------------------------- ### SetSignatureMethod Source: https://context7.com/russellhaering/goxmldsig/llms.txt Configures the signature algorithm for the signing context. Supported algorithms include RSA-SHA1/256/384/512 and ECDSA-SHA1/256/384/512. ```APIDOC ## SetSignatureMethod ### Description Configures the signature algorithm for the signing context. Supported algorithms include RSA-SHA1/256/384/512 and ECDSA-SHA1/256/384/512. ### Method This is a method call within the goxmldsig library, not a direct HTTP API endpoint. ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```go package main import ( dsig "github.com/russellhaering/goxmldsig" ) func main() { keyStore := dsig.RandomKeyStoreForTest() ctx := dsig.NewDefaultSigningContext(keyStore) // Set RSA-SHA512 signature method err := ctx.SetSignatureMethod("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512") if err != nil { panic(err) } sigMethod := ctx.GetSignatureMethodIdentifier() digestAlgo := ctx.GetDigestAlgorithmIdentifier() println("Signature Method:", sigMethod) println("Digest Algorithm:", digestAlgo) } ``` ### Response #### Success Response (200) N/A (This is a configuration method, not an API endpoint returning a response) #### Response Example N/A ``` -------------------------------- ### MakeC14N10RecCanonicalizer Source: https://context7.com/russellhaering/goxmldsig/llms.txt Initializes a Canonical XML 1.0 (REC) canonicalizer for XML processing. ```APIDOC ## FUNCTION MakeC14N10RecCanonicalizer ### Description Creates a Canonical XML 1.0 (REC) canonicalizer instance. This is used to normalize XML documents for consistent signature verification. ### Method Go Function ### Parameters None ### Request Example canonicalizer := dsig.MakeC14N10RecCanonicalizer() ### Response - **canonicalizer** (Canonicalizer) - An object implementing the Canonicalize method. ``` -------------------------------- ### types.Signature Source: https://context7.com/russellhaering/goxmldsig/llms.txt Defines the structure for XML Digital Signature elements for use in Go structs. ```APIDOC ## STRUCT types.Signature ### Description The Signature struct represents an XML Digital Signature element. It is designed to be embedded in application message structures (like SAML) to facilitate XML marshaling and unmarshaling. ### Method Go Struct ### Parameters - **SignedInfo** (struct) - Contains the canonicalization method, signature method, and references. - **SignatureValue** (string) - The base64 encoded signature value. ### Request Example type SAMLResponse struct { Signature *sigtypes.Signature `xml:"Signature"` } ### Response - **Signature** (Pointer) - A pointer to the Signature struct populated during XML unmarshaling. ``` -------------------------------- ### ConstructSignature Source: https://context7.com/russellhaering/goxmldsig/llms.txt Creates a detached signature element for an XML element without embedding it. Useful when you need to place the signature in a specific location. ```APIDOC ## ConstructSignature ### Description Creates a detached signature element for an XML element without embedding it. Useful when you need to place the signature in a specific location. ### Method This is a method call within the goxmldsig library, not a direct HTTP API endpoint. ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```go package main import ( "fmt" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { keyStore := dsig.RandomKeyStoreForTest() ctx := dsig.NewDefaultSigningContext(keyStore) // Element to sign data := etree.NewElement("Data") data.CreateAttr("ID", "data-001") data.CreateElement("Value").SetText("Important data") // Construct a detached signature (enveloped=false) signature, err := ctx.ConstructSignature(data, false) if err != nil { panic(err) } // Create a wrapper document with data and signature as siblings wrapper := etree.NewElement("SignedDocument") wrapper.AddChild(data.Copy()) wrapper.AddChild(signature) doc := etree.NewDocument() doc.SetRoot(wrapper) xmlStr, _ := doc.WriteToString() fmt.Println(xmlStr) } ``` ### Response #### Success Response (200) - **signature** (*etree.Element) - A detached XMLDSig signature element. #### Response Example ```xml Important data ... ... ... ``` ``` -------------------------------- ### SignEnveloped Source: https://context7.com/russellhaering/goxmldsig/llms.txt Signs an XML element using an enveloped signature, embedding the signature as a child of the signed element. The returned element is a copy with the signature attached. ```APIDOC ## SignEnveloped ### Description Signs an XML element using an enveloped signature, embedding the signature as a child of the signed element. The returned element is a copy with the signature attached. ### Method This is a method call within the goxmldsig library, not a direct HTTP API endpoint. ### Endpoint N/A ### Parameters #### Path Parameters N/A #### Query Parameters N/A #### Request Body N/A ### Request Example ```go package main import ( "fmt" "github.com/beevik/etree" dsig "github.com/russellhaering/goxmldsig" ) func main() { keyStore := dsig.RandomKeyStoreForTest() ctx := dsig.NewDefaultSigningContext(keyStore) // Create a SAML assertion to sign assertion := etree.NewElement("saml:Assertion") assertion.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion") assertion.CreateAttr("ID", "_abc123") assertion.CreateAttr("Version", "2.0") assertion.CreateAttr("IssueInstant", "2024-01-01T00:00:00Z") issuer := assertion.CreateElement("saml:Issuer") issuer.SetText("https://idp.example.com") subject := assertion.CreateElement("saml:Subject") nameID := subject.CreateElement("saml:NameID") nameID.SetText("user@example.com") // Sign the assertion - creates a copy with enveloped signature signedAssertion, err := ctx.SignEnveloped(assertion) if err != nil { panic(err) } doc := etree.NewDocument() doc.SetRoot(signedAssertion) xmlBytes, err := doc.WriteToBytes() if err != nil { panic(err) } fmt.Println(string(xmlBytes)) } ``` ### Response #### Success Response (200) - **signedAssertion** (*etree.Element) - A new XML element representing the original element with an embedded XMLDSig signature. #### Response Example ```xml https://idp.example.com user@example.com ... ... ... ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.