HOWTO: Create a Warrant Canary, or NSL Dead Man’s Switch



Monday, September 9th, 2013 at 8:52 am | 3,035 views | trackback url

Thanks Slashdot for carrying your users over to my blog this morning!

The rsync team has been doing this for quite awhile, and I had an idea. Why not share this more broadly?

So I created a quick little script to generate my own “warrant canary”. Instructions follow below.

Note: Based on the direct emails from Slashdot users, I’ll update this post with more information in the coming days/weeks to keep this current.

#!/usr/bin/perl

use warnings;
use strict;
use LWP::Simple;   # Fetch the remote feed via HTTP
use XML::RSS;      # Parse the RSS feed into tree and DOM elements
use HTML::Strip;   # Clean up bad tags, HTML, CDATA in RSS feeds
use File::Slurp;   # Easily read/write files to the filesystem
use Crypt::GPG;    # Call out to gpg for signing the canary

# Pick an RSS news source that is current, updated, and neutral if possible:
my $url           = "http://www.npr.org/rss/rss.php?id=1001";
# my $url         = 'http://feeds.bbci.co.uk/news/world/rss.xml';

binmode(STDOUT, ":utf8");

my $hs            = HTML::Strip->new();
my $gpg           = new Crypt::GPG;
my @newscanary = '';

my $rss           = XML::RSS->new();
my $data          = get($url);
$rss->parse($data);

my $channel       = $rss->{channel};

foreach my $item (@{ $rss->{items}}) {
	my $title = $item->{title};
	my $date  = $item->{pubDate};
	my $desc  = $hs->parse($item->{description});

	# Word wrap the output at 70 characters
	$desc =~ s/(.{70}[^\s]*)\s+/$1\n/xg;

	push @newscanary, "$title\n$date\n" . "-"x70 . "\n$desc\n\n\n";
}

write_file('canary.txt', @newscanary) ;

my $boilerplate = read_file('boilerplate.txt', {binmode => ':raw'});
my $newscanary = read_file('canary.txt', {binmode => ':raw'});

print $boilerplate, $newscanary;

$hs->eof;

Now you create a file called ‘boilerplate.txt’, which includes the header you want to show up at the top of your canary, such as this example (nicked and modified from the rsync canary):

Existing and proposed laws, especially as relate to the US Patriot Act,
etc., provide for secret warrants, searches and seizures of data, such as
library records.

Some such laws provide for criminal penalties for revealing the warrant,
search or seizure, disallowing the disclosure of events that would
materially affect the users of a service such as those provided by
YOUR_COMPANY and subsidiary domains and services.

YOUR_COMPANY and its principals and employees will in fact comply with
such warrants and their provisions for secrecy as legally prescribed by US
law.

YOUR_COMPANY will also make available, hourly, a "warrant canary" in
the form of a cryptographically signed message containing the following:

	- a declaration that, up to that point, no warrants have been
	  served, nor have any searches or seizures taken place

	- a cut and paste headline from a major news source, establishing
	  date

Special note should be taken if these messages ever cease being updated, or
are removed from this page.
The current message is here:

I’ll leave it as an exercise to the reader how to sign the output of that with GNU Privacy Guard (hint: gpg –clearsign), and how to protect that key and copy the completed canary.txt over to your webserver (hint: use rsync).

Set that up in an hourly cron job, and you should be all set.

Last Modified: Tuesday, September 10th, 2013 @ 09:44

Leave a Reply

You must be logged in to post a comment.

Bad Behavior has blocked 1284 access attempts in the last 7 days.