func ExampleSignature_Sign() { xmlsec.Init() defer xmlsec.Shutdown() p := parser.New(parser.XMLParseDTDLoad | parser.XMLParseDTDAttr | parser.XMLParseNoEnt) doc, err := p.ParseString(`<?xml version="1.0" encoding="UTF-8"?> <Message><Data>Hello, World!</Data></Message>`) n, err := doc.DocumentElement() if err != nil { log.Printf("DocumentElement failed: %s", err) return } // n is the node where you want your signature to be // generated under sig, err := dsig.NewSignature(n, dsig.ExclC14N, dsig.RsaSha1, "") if err != nil { log.Printf("failed to create signature: %s", err) return } sig.AddReference(dsig.Sha1, "", "", "") sig.AddTransform(dsig.Enveloped) privkey, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { log.Printf("failed to generate key: %s", err) return } key, err := crypto.LoadKeyFromRSAPrivateKey(privkey) if err := sig.Sign(key); err != nil { log.Printf("failed to sign: %s", err) return } log.Printf("%s", doc.Dump(true)) }
func TestSignature(t *testing.T) { xmlsec.Init() defer xmlsec.Shutdown() doc := dom.CreateDocument() defer doc.Free() message, err := doc.CreateElement("Message") if !assert.NoError(t, err, "CreateElement succeeds") { return } doc.SetDocumentElement(message) data, err := doc.CreateElement("Data") if !assert.NoError(t, err, "CreateElement succeeds") { return } message.AddChild(data) data.AppendText("Hello, World!") sig, err := dsig.NewSignature(message, dsig.ExclC14N, dsig.RsaSha1, "") if !assert.NoError(t, err, "NewSignature succeeds") { return } if !assert.NoError(t, sig.AddReference(dsig.Sha1, "", "", ""), "AddReference succeeds") { return } if !assert.NoError(t, sig.AddTransform(dsig.Enveloped), "AddTransform succeeds") { return } if !assert.NoError(t, sig.AddKeyValue(), "AddKeyValue succeeds") { return } if !assert.NoError(t, sig.AddX509Data(), "AddX509Data succeeds") { return } keyfile := filepath.Join("test", "key.pem") certfile := filepath.Join("test", "cert.pem") key, err := crypto.LoadKeyFromFile(keyfile, crypto.KeyDataFormatPem) if !assert.NoError(t, err, "Load key from file succeeds") { return } key.LoadCertFromFile(certfile, crypto.KeyDataFormatPem) if !assert.NoError(t, sig.Sign(key), "Sign succeeds") { return } t.Logf("%s", doc.Dump(true)) verify, err := dsig.NewSignatureVerify() if !assert.NoError(t, err, "NewSignatureVerify succeeds") { return } if !assert.NoError(t, verify.VerifyString(doc.Dump(false)), "VerifyString succeeds") { return } }
func encode(s serializer, key *crypto.Key, compress bool) ([]byte, error) { xmlstr, err := s.Serialize() if err != nil { return nil, err } if pdebug.Enabled { pdebug.Printf("Generated %d bytes of XML", len(xmlstr)) } if key != nil { p := parser.New(parser.XMLParseDTDLoad | parser.XMLParseDTDAttr | parser.XMLParseNoEnt) doc, err := p.ParseString(xmlstr) if err != nil { return nil, err } root, err := doc.DocumentElement() if err != nil { return nil, err } // Create a new signature section. sig, err := dsig.NewSignature(root, dsig.ExclC14N, dsig.RsaSha1, "") if err := sig.AddReference(dsig.Sha1, "", "", ""); err != nil { return nil, err } if err := sig.AddTransform(dsig.Enveloped); err != nil { return nil, err } if key.HasRsaKey() == nil || key.HasDsaKey() == nil || key.HasEcdsaKey() == nil { if err := sig.AddKeyValue(); err != nil { return nil, err } } // If the key is setup using X509, add that node if key.HasX509() == nil { if err := sig.AddX509Data(); err != nil { return nil, err } } if pdebug.Enabled { pdebug.Printf("Signing using key %p", key) } if err := sig.Sign(key); err != nil { return nil, err } xmlstr = doc.Dump(false) if err != nil { return nil, err } } if !compress { return []byte(xmlstr), nil } buf := bytes.Buffer{} w := getFlateWriter() defer releaseFlateWriter(w) w.Reset(&buf) if _, err := io.WriteString(w, xmlstr); err != nil { return nil, err } if err := w.Close(); err != nil { return nil, err } if pdebug.Enabled { pdebug.Printf("Compressed to %d bytes", buf.Len()) } ret := make([]byte, b64enc.EncodedLen(buf.Len())) b64enc.Encode(ret, buf.Bytes()) if pdebug.Enabled { pdebug.Printf("Encoded into %d bytes of base64", len(ret)) } return ret, nil }
func TestAuthnRequest(t *testing.T) { xmlsec.Init() defer xmlsec.Shutdown() ar := NewAuthnRequest() ar.ID = "809707f0030a5d00620c9d9df97f627afe9dcc24" ar.Version = "2.0" ar.IssueInstant = time.Now() ar.Issuer = "http://sp.example.com/metadata" ar.Destination = "http://idp.example.com/sso" ar.ProviderName = "FooProvider" ar.ProtocolBinding = binding.HTTPPost ar.AssertionConsumerServiceURL = "http://sp.example.com/acs" ar.NameIDPolicy = NewNameIDPolicy(nameid.EmailAddress, true) ar.RequestedAuthnContext = NewRequestedAuthnContext( "exact", "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport", ) xmlstr, err := ar.Serialize() if !assert.NoError(t, err, "Serialize() succeeds") { return } p := parser.New(parser.XMLParseDTDLoad | parser.XMLParseDTDAttr | parser.XMLParseNoEnt) c14ndoc, err := p.ParseString(xmlstr) if !assert.NoError(t, err, "Parse C14N XML doc succeeds") { return } defer c14ndoc.Free() root, err := c14ndoc.DocumentElement() if !assert.NoError(t, err, "DocumentElement succeeds") { return } privkey, err := rsa.GenerateKey(rand.Reader, 2048) if !assert.NoError(t, err, "GenerateKey succeeds") { return } signer, err := dsig.NewSignature(root, dsig.ExclC14N, dsig.RsaSha1, "urn:oasis:names:tc:SAML:2.0:protocol:AuthnRequest") if !assert.NoError(t, err, "dsig.NewSignature succeeds") { return } if !assert.NoError(t, signer.AddReference(dsig.Sha1, "", "", ""), "AddReference succeeds") { return } if !assert.NoError(t, signer.AddTransform(dsig.Enveloped), "AddTransform succeeds") { return } if !assert.NoError(t, signer.AddKeyValue(), "AddKeyValue succeeds") { return } key, err := crypto.LoadKeyFromRSAPrivateKey(privkey) if !assert.NoError(t, err, "Load key from RSA private key succeeds") { return } if !assert.NoError(t, signer.Sign(key), "Sign succeeds") { return } t.Logf("%s", c14ndoc.Dump(true)) }
func TestResponse(t *testing.T) { xmlsec.Init() defer xmlsec.Shutdown() res := NewResponse() res.Issuer = "http://idp.example.com/metadata" res.Destination = "http://sp.example.com/sso" // Run serialize once so we can check for empty assertion xmlstr, err := res.Serialize() if !assert.NoError(t, err, "Serialize() succeeds") { return } if !assert.NotContains(t, xmlstr, "<Assertion", "Should not contain assertion") { return } res.Assertion = NewAssertion() res.Assertion.Conditions.AddAudience("sp.example.com/sso") xmlstr, err = res.Serialize() if !assert.NoError(t, err, "Serialize() succeeds") { return } if !assert.Contains(t, xmlstr, "<saml:Audience>sp.example.com/sso", "<saml:Audience> exists") { return } p := parser.New(parser.XMLParseDTDLoad | parser.XMLParseDTDAttr | parser.XMLParseNoEnt) doc, err := p.ParseString(xmlstr) if !assert.NoError(t, err, "Parse XML doc succeeds") { return } defer doc.Free() c14nxml, err := dom.C14NSerialize{Mode: dom.C14NExclusive1_0}.Serialize(doc) if !assert.NoError(t, err, "C14NSerialize.Serialize succeeds") { return } c14ndoc, err := p.ParseString(c14nxml) if !assert.NoError(t, err, "Parse C14N doc succeeds") { return } defer c14ndoc.Free() root, err := c14ndoc.DocumentElement() if !assert.NoError(t, err, "DocumentElement succeeds") { return } privkey, err := rsa.GenerateKey(rand.Reader, 2048) if !assert.NoError(t, err, "GenerateKey succeeds") { return } signer, err := dsig.NewSignature(root, dsig.ExclC14N, dsig.RsaSha1, "urn:oasis:names:tc:SAML:2.0:protocol:Response") if !assert.NoError(t, err, "dsig.NewSignature succeeds") { return } if !assert.NoError(t, signer.AddReference(dsig.Sha1, "", "", ""), "AddReference succeeds") { return } if !assert.NoError(t, signer.AddTransform(dsig.Enveloped), "AddTransform succeeds") { return } if !assert.NoError(t, signer.AddKeyValue(), "AddKeyValue succeeds") { return } key, err := crypto.LoadKeyFromRSAPrivateKey(privkey) if !assert.NoError(t, err, "Load key from RSA private key succeeds") { return } if !assert.NoError(t, signer.Sign(key), "Sign succeeds") { t.Logf("%s", c14ndoc.Dump(true)) return } t.Logf("%s", c14ndoc.Dump(true)) }