Example #1
0
func TestXmlSecDSigCtx(t *testing.T) {
	xmlsec.Init()
	defer xmlsec.Shutdown()

	privkey, err := rsa.GenerateKey(rand.Reader, 2048)
	if !assert.NoError(t, err, "Generating private key should succeed") {
		return
	}

	privfile, err := writePrivateKey(privkey)
	if !assert.NoError(t, err, "Writing private key should succeed") {
		return
	}
	defer os.Remove(privfile)

	pubfile, err := writePublicKey(&privkey.PublicKey)
	if !assert.NoError(t, err, "Writing public key should succeed") {
		return
	}
	defer os.Remove(pubfile)

	src := `<?xml version="1.0" encoding="UTF-8"?>
<!-- XML Security Library example: Simple signature template file for sign1 example.  -->
<Envelope xmlns="urn:envelope">
  <Data>
	Hello, World!
  </Data>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue></DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue/>
    <KeyInfo>
      <KeyName/>
    </KeyInfo>
  </Signature>
</Envelope>`

	p := parser.New(parser.XMLParseDTDLoad | parser.XMLParseDTDAttr | parser.XMLParseNoEnt)
	doc, err := p.ParseString(src)

	if !assert.NoError(t, err, "Parsing template should succeed") {
		return
	}
	defer doc.Free()

	{
		ctx, err := dsig.NewCtx(nil)
		if !assert.NoError(t, err, "dsig.NewCtx should succeed") {
			return
		}
		defer ctx.Free()

		key, err := crypto.LoadKeyFromFile(privfile, crypto.KeyDataFormatPem)
		if !assert.NoError(t, err, "Loading private key '%s' should succeed", privfile) {
			return
		}
		ctx.SetKey(key)

		if !assert.NoError(t, ctx.Sign(doc), "Sign should succeed") {
			return
		}
	}

	signed := doc.String()
	t.Logf("%s", signed)

	{
		ctx, err := dsig.NewCtx(nil)
		if !assert.NoError(t, err, "dsig.NewCtx should succeed") {
			return
		}
		defer ctx.Free()

		key, err := crypto.LoadKeyFromFile(pubfile, crypto.KeyDataFormatPem)
		if !assert.NoError(t, err, "Loading public key '%s' should succeed", pubfile) {
			return
		}
		ctx.SetKey(key)

		if !assert.NoError(t, ctx.Verify(doc), "Verify should succeed") {
			return
		}
	}

	{
		verify, err := dsig.NewSignatureVerify()
		if !assert.NoError(t, err, "NewSignatureVerify succeeds") {
			return
		}

		if !assert.NoError(t, verify.LoadKeyFromFile(pubfile, crypto.KeyDataFormatPem), "LoadKeyFromFile succeeds") {
			return
		}

		if !assert.NoError(t, verify.VerifyString(signed), "VerifyString succeeds") {
			return
		}
		if !assert.NoError(t, verify.Verify([]byte(signed)), "Verify succeeds") {
			return
		}
	}
}
func ExampleDSigCtx_Sign() {
	xmlsec.Init()
	defer xmlsec.Shutdown()

	ctx, err := dsig.NewCtx(nil)
	if err != nil {
		log.Printf("Failed to create signature context: %s", err)
		return
	}
	defer ctx.Free()

	// This stuff isn't necessary if you already have a key file
	privkey, err := rsa.GenerateKey(rand.Reader, 2048)
	if err != nil {
		log.Printf("Failed to generate private key: %s", err)
		return
	}
	var pemkey = &pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: x509.MarshalPKCS1PrivateKey(privkey),
	}

	pemfile, err := ioutil.TempFile("", "xmlsec-test-")
	if err != nil {
		log.Printf("Failed to create temporary pemfile")
		return
	}
	defer os.Remove(pemfile.Name())
	defer pemfile.Close()

	if err := pem.Encode(pemfile, pemkey); err != nil {
		log.Printf("Failed to write to pemfile: %s", err)
		return
	}

	if err := pemfile.Sync(); err != nil {
		log.Printf("Failed to sync pemfile: %s", err)
		return
	}

	key, err := crypto.LoadKeyFromFile(pemfile.Name(), crypto.KeyDataFormatPem)
	if err != nil {
		log.Printf("Faild to load key: %s", err)
		return
	}
	ctx.SetKey(key)

	p := parser.New(parser.XMLParseDTDLoad | parser.XMLParseDTDAttr | parser.XMLParseNoEnt)
	doc, err := p.ParseString(`<?xml version="1.0" encoding="UTF-8"?>
<!-- XML Security Library example: Simple signature template file for sign1 example.  -->
<Envelope xmlns="urn:envelope">
  <Data>
	Hello, World!
  </Data>
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue></DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue/>
    <KeyInfo>
      <KeyName/>
    </KeyInfo>
  </Signature>
</Envelope>`)

	if err != nil {
		log.Printf("Failed to parse source XML: %s", err)
		return
	}
	defer doc.Free()

	if err := ctx.Sign(doc); err != nil {
		log.Printf("Failed to sign document: %s", err)
		return
	}

	log.Printf("%s", doc.Dump(true))
}