#!/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";
}