{"id":52,"date":"2005-04-09T14:35:34","date_gmt":"2005-04-09T19:35:34","guid":{"rendered":"http:\/\/crschmidt.net\/blog\/?p=52"},"modified":"2005-04-09T14:35:34","modified_gmt":"2005-04-09T19:35:34","slug":"rdf-gpg","status":"publish","type":"post","link":"https:\/\/crschmidt.net\/blog\/archives\/52\/rdf-gpg\/","title":{"rendered":"RDF + GPG"},"content":{"rendered":"<p>One of my eventual goals is to have julie replace all the features of wh4 (libby&#8217;s query bot) and foafbot (edd&#8217;s community IRC bot). One thing that edd&#8217;s bot did that julie doesn&#8217;t is to verify data based on signed documents, and to use this information as a &#8220;provenance&#8221; for the data: not just &#8220;where was it said&#8221;, but actually verifying &#8220;who said it&#8221;. <\/p>\n<p>Dealing with GPG is not nearly as easy as I really think it should be. Take Redland as an example: You can interact with the library at all kinds of levels, from the base swig wrapper to the hand-written RDF.py module wrapped around it, and you can do just about anything the base library does from within Python.<\/p>\n<p>GPG, on the other hand, is very hard to work with from a library level. There is a Python module for working with GPG, but it equates to simply using the command line tool in the end. You can&#8217;t tell it &#8220;Check this document&#8221;: you basically just have tools to create a pipe to GPG, and pass the options in the same way you would on the command line. Add to that that it&#8217;s Yet Another Dependancy which is somewhat of a pain to resolve in Python, and you can see why it&#8217;s slightly annoying for people who might want to use GPG.<\/p>\n<p>Wondering what edd had done for <a href=\"http:\/\/usefulinc.com\/foaf\/foafbot\">FOAFbot<\/a> back when it was running, I decided to grab his code and play with it. Turns out he just opened a pipe to gpg using the <a href=\"http:\/\/docs.python.org\/lib\/module-commands.html\">commands module<\/a> in Python. This seemed simple enough to me, so I ripped out some of his code and turned it into a little script.<\/p>\n<p>With that, I announce the release of <a href=\"http:\/\/crschmidt.net\/semweb\/rdfgpg\/\">rdfgpg<\/a>, a tool for verifying the signature described by an RDF document. It uses the Redland Python bindings, and the usage is:<\/p>\n<p><tt>python rdfgpg.py http:\/\/example.org\/urlof.rdf<\/tt><\/p>\n<p>Optionally, you can add a second argument, to set the <code>debug<\/code> argument, which will show more information about what&#8217;s going on in the background, which may help if something that you expect to work isn&#8217;t. Additionally, you can easily import the module and use the function rdfgpg.verify_url(url), which returns a list of email addresses on the signing key.<\/p>\n<p>The code is released under a GPL 2.0 license, and is stolen in large part from the FOAFbot code released by Ed Dumbill. Feature requests via comments or  <a href=\"crschmidt&#64;crschmidt.net\">email<\/a>.<\/p>\n<p>Hopefully with this, I&#8217;ll start to actually use it in my tools, to verify provenance when possible, and to start convincing people to sign their files. I hate to think what would happen to the semantic web if people suddenly started creating lots of false documents&#8230; but hopefully it&#8217;s not quite that popular yet.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of my eventual goals is to have julie replace all the features of wh4 (libby&#8217;s query bot) and foafbot (edd&#8217;s community IRC bot). One thing that edd&#8217;s bot did that julie doesn&#8217;t is to verify data based on signed documents, and to use this information as a &#8220;provenance&#8221; for the data: not just &#8220;where [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8,4,2],"tags":[],"class_list":["post-52","post","type-post","status-publish","format-standard","hentry","category-rdfcat","category-redland-rdf-application-framework","category-semantic-web"],"_links":{"self":[{"href":"https:\/\/crschmidt.net\/blog\/wp-json\/wp\/v2\/posts\/52","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/crschmidt.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/crschmidt.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/crschmidt.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/crschmidt.net\/blog\/wp-json\/wp\/v2\/comments?post=52"}],"version-history":[{"count":0,"href":"https:\/\/crschmidt.net\/blog\/wp-json\/wp\/v2\/posts\/52\/revisions"}],"wp:attachment":[{"href":"https:\/\/crschmidt.net\/blog\/wp-json\/wp\/v2\/media?parent=52"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/crschmidt.net\/blog\/wp-json\/wp\/v2\/categories?post=52"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/crschmidt.net\/blog\/wp-json\/wp\/v2\/tags?post=52"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}