#!/usr/bin/perl

use 5.008;
use strict;
use warnings;

use Digest::SHA qw[];
use MIME::Base64 qw[];
use Net::DNS qw[];
use URI qw[];

my $webid  = URI->new(shift @ARGV or die "Please provide a URI.\n");
my $proxy  = join '.', Digest::SHA::sha1_hex("$webid"), $webid->host;
my $dns    = Net::DNS::Resolver->new;
my $query  = $dns->query($proxy, 'TXT');

my (%data, $source);
if ($query)
{
   foreach my $rr ($query->answer)
   {
      next unless $rr->type eq 'TXT';  # double-check
      next unless $rr->name eq $proxy; # double-check
      
      my ($txt) = ($rr->rdatastr =~ /^"(.+)"$/);
      
      # Allow the proxy record to contain non-WebID TXT data too!
      next unless $txt =~ /^webid\s/;
      
      foreach my $part (split /\s+/, $txt)
      {
         my ($key, $value) = split /=/, $part, 2; # split on first '='
         $data{$key} = $value;
      }
   }
   
   # RFC 4501 URI
   $source = sprintf("dns://%s/%s?TYPE=TXT", $query->answerfrom, $proxy);
}

if (exists $data{webid} && exists $data{e} && exists $data{n})
{
   use bytes; # i.e. treat strings as octet sequences

   my %hex;
   foreach my $number (qw(e n))
   {
      my $bin = MIME::Base64::decode_base64( $data{$number} );
      $hex{$number} = '';
      while (length $bin)
      {
         $hex{$number} .= sprintf('%02X', ord($bin));
         $bin = substr($bin, 1);
      }
   }
   
    printf(<<'TURTLE', $webid, $hex{'e'}, $hex{'n'}, $source);
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix cert: <http://www.w3.org/ns/auth/cert#> .
@prefix rsa:  <http://www.w3.org/ns/auth/rsa#> .

[]
   a rsa:RSAPublicKey ;
   cert:identity <%1$s> ;
   rsa:public_exponent "%2$s"^^cert:hex ;
   rsa:modulus "%3$s"^^cert:hex .

<%1$s>
   a foaf:Agent ;
   foaf:page <%4$s> .
TURTLE
}

else
{
   die "Could not process WebID <$webid> via DNS\n";
}