[dns-operations] calculating DNSSEC keytags in awk
Lutz Donnerhacke
lutz at iks-jena.de
Fri Dec 16 23:19:43 UTC 2011
In iks.lists.dns-operations, you wrote:
> I realise I'm probably the only person in the world who would ever
> want to do such a thing
No, you are not that alone.
> It seems to generate the right keytags for the zones I have been
> playing with.
Fine!
#! /usr/bin/perl
package dnskey2ds;
use strict;
use warnings;
use Digest;
use MIME::Base64;
BEGIN {
use Exporter ();
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
$VERSION = 1.00;
@ISA = qw(Exporter);
@EXPORT = qw(&generate_ds);
%EXPORT_TAGS = ( ); # eg: TAG => [ qw!name1 name2! ],
# your exported package globals go here,
# as well as any optionally exported functions
@EXPORT_OK = qw(&generate_ds);
}
use vars @EXPORT_OK;
my $sha1 = Digest->new("SHA-1");
sub generate_ds($$) {
my $fqdn = shift;
my ($flags, $prot, $algo, $key) = split(/\s+/, shift, 4);
my $rdata = join("", map {decode_base64 $_} (split /\s+/, $key));
local $_;
$sha1->reset();
$fqdn =~ s/\.$//;
foreach (split (/\./,$fqdn)) { $sha1->add(pack("c/a*",$_)); }
$sha1->add(pack("c/a*",""));
my $wire = pack("ncc", $flags, 3, $algo) . $rdata;
$sha1->add($wire);
my $keytag;
if($algo == 1) {
$keytag = 0xffff & unpack("n", substr($wire,-3,2)) ;
} else {
my ($sum, $i);
for($sum = $i = 0; $i < length $wire; $i++) {
$_ = unpack("C", substr($wire,$i,1));
$sum += ($i & 1) ? $_ : $_ << 8;
}
$keytag = 0xffff & ($sum + ($sum >> 16));
}
my $comment = "";
if($algo == 3) {
$_ = $rdata;
my $len = 8*(64 + 8*unpack("C", substr($_,0,1)));
$comment = "; Modulus = $len bit";
} elsif($algo == 5 || $algo == 1) {
$_ = $rdata;
my ($len, $exponent);
$len = unpack("C", substr($_,0,1));
$_ = substr($_,1);
unless($len) {
$len = unpack("n", substr($_,0,2));
$_ = substr($_,2);
}
if($len == 1) {
$exponent = unpack("C", substr($_,0,1));
} elsif($len == 2) {
$exponent = unpack("n", substr($_,0,2));
} elsif($len == 3) {
$exponent = unpack("n", substr($_,0,2)) * 256
+ unpack("C", substr($_,2,1));
} elsif($len == 4) {
$exponent = unpack("N", substr($_,0,4));
} elsif($len == 5) {
$exponent = unpack("N", substr($_,0,4)) * 256
+ unpack("C", substr($_,4,1));
}
$_ = substr($_,$len);
$_ = 8*(length $_);
$comment = "; Modulus = $_ bit";
if($exponent) {
$comment .= ", Exponent = $exponent";
} else {
$comment .= ", Exponent = $len byte";
}
}
return "$keytag $algo 1 ${\$sha1->hexdigest()} $comment";
}
1;
More information about the dns-operations
mailing list