wtf snippets

How to sign XML documents using XMLDSig (XML Signature)

Tagged xmldsig, xml, signature, wtf, hl7fi, kanta, xmlsec1  Languages bash, xml

Install xmlsec1

sudo apt-get install xmlsec1

Create document

<?xml version="1.0" encoding="UTF-8"?>
<document>
  <hello>All XML is doomed to fail.</hello>
  <!-- Signature contains the signature definition -->
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
      <Reference>
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
          <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
        <DigestValue />
      </Reference>
      </SignedInfo>
    <SignatureValue />
    <KeyInfo>
      <X509Data />
    </KeyInfo>
  </Signature>
</document>

Sign document

xmlsec1 --sign --privkey-pem xxx.com.key,xxx.com.cer --output signed.xml tosign.xml

This example uses test certificates issued by VRK.

Verify document

xmlsec1 --verify --trusted-pem vrkthsp.pem --trusted-pem vrktestc.pem signed.xml

Note that a concatenated PEM file, i.e. cat vrkthsp.pem vrktestc.pem > concat.pem, does not work with xmlsec1.

How to specify which elements to sign with ds:Reference

Add one or more ds:Reference elements to specify which elements should be signed. Each element should have a unique ID in the URI attribute. The ID should be prefixed with a hash, e.g., #your-id:

<ds:Reference URI="#secret-xml-sauce">

Make sure your document contains an element having the exact ID without the hash prefix:

<Dog ID="secret-xml-sauce" name="Christian" />

Next, use the “—id-attr” switch to specify the element and attribute name:

xmlsec1 --sign --privkey-pem signing.key,signing.pem --id-attr:ID Dog --id-attr:ID structuredBody --output signed.xml tosign.xml

Note that “id” is the default attribute name. You only need —id-attr switch if you have the ID in an attribute having a different name.

How to sign multiple elements

Just add another “—id-attr: ” switch:

xmlsec1 --sign --privkey-pem signing.key,signing.pem --id-attr:ID signatureTimestamp --id-attr:ID structuredBody --output signed.xml tosign.xml

Then add another element having the given ID.

Troubleshooting

  • This error means you don’t have the correct trusted pem
certificate issuer check failed:err=2;msg=unable to get issuer certificate;issuer=/C=FI/ST=Finland/O=Vaestorekisterikeskus TEST/OU=Certification Authority Services/OU=Varmennepalvelut/CN=VRK TEST Root CA

To fix the error, take a hard look at the Issuer and Subject of all certificates in the certificate chain. For example:

openssl x509 -inform DER -in vrktestc.crt -text | grep "Issuer\|Subject"
  • xmlsec1 fails to find element containing ID
func=xmlSecXPathDataExecute:file=xpath.c:line=273:obj=unknown:subj=xmlXPtrEval:error=5:libxml2 library function failed:expr=xpointer(id('ID_OF_ELEMENT_TO_SIGN'))

Note that the XPATH queries are case sensitive. This means you might have to specify both the name of the element and the name of the ID attribute like this:

xmlsec1 sign --id-attr:ID elementThatYouWantToSign ...

For more solutions to issues, see sgros.blogspot.com: http://sgros.blogspot.com/2013/01/signing-xml-document-using-xmlsec1.html

"ERROR: permission denied for schema public" WTF

Tagged postgresql, wtf, grant  Languages sql

If you get this error:

ERROR:  permission denied for schema history

And, you’re running a query such as, for example, this one:

SELECT 1 FROM ONLY "history"."dummytafvel" x WHERE "id" OPERATOR(pg_catalog.=) $1 FOR KEY SHARE OF x;

And, your user has been granted access to the schema:

GRANT ALL ON history TO myself_and_i;

Then, you might have been hit over the head by the “permission denied for schema even as superuser” feature in PostgreSQL:

That’s a foreign key checking query.FK checks are done as the owner of the target table, not as the user who did the original query. So your problem is that the owner of the table lacks permissions to access the other table (or more specifically, the schema it’s in).

The solution is to grant access to the owner of the foreign keys to the schema in question.

References

https://sharingtechknowledge.blogspot.com/2012/03/postgresql-foreign-key-checking.html

How to dump Postgres extensions and all schemas with Rails

Tagged wtf, lol, migration, rails  Languages bash, ruby

When running rake db:reset you might get one of the following informative errors:

  function public.gen_random_uuid() does not exist
  db/structure.sql:22: ERROR:  schema "public" already exists

To fix them tell Ruby to dump everything by editing config/application.rb:

module XXX
  class Application < Rails::Application
    config.active_record.dump_schemas = :all

Tested with Rails 6.

References: https://github.com/rails/rails/issues/17157#issuecomment-77400517