CC: | Dmitry Belyavsky <beldmit [...] tcinet.ru> |
Subject: | Digest::GOST and CryptoProParamSet |
Date: | Tue, 25 Sep 2012 16:08:08 +0400 |
To: | bug-Digest-GOST [...] rt.cpan.org |
From: | Nikolay Shaplov <dhyan [...] nataraj.su> |
Hi!
I am trying to use Digest::GOST to calculate DS record in DNSSEC. Calculating
DS record using GOST is covered by https://tools.ietf.org/html/rfc5933
I take a calculating subroutine from Net::DNS::Sec, as it does calculation for
other types of digest and applied it to the example in 4.1. if RFC 5933. See
attached code.
The code gives wrong result. This happens because of RFC 5933 in section 4
tells to use CryptoProParamSet GOST param set to calculate hash, and
Digest::GOST seems to use TestParamSet.
I applied a small hack-patch to src/gost.c: I've added ctx->cryptpro = 1; to
the gost_init function:
void gost_init(gost_ctx *ctx)
{
memset(ctx, 0, sizeof(gost_ctx));
ctx->cryptpro = 1;
}
After building Digest::GOST with this patch an example script from the
attachment gives the same result as shown in RFC example.
So access to CryptoProParamSet is really needed in Digest::GOST: at least for
patching Net::DNS::Sec to support GOST hashes out of box.
The question is what is the best way to do it. If you use TestParamSet by
mistake, then may be if would be better not to use it. If you intentionally
used TestParamSet for some reason (you may have one), then it would be very
good to add support for both ParamSets in Digest::GOST. I can write and offer a
patch for this, if you give me general recommendations about the
implementation you expect to have.
Would be glad to here from you soon. :-) We are currently using custom built
module, with the hack above, to calculating DS. It would be great to replace
it with a standard module asap :-))))) This will give me a chance to send a
GOST patch Net::DNS::Sec as well :-)
#!/usr/bin/perl
use strict;
use warnings;
use utf8;
use lib ".";
use MIME::Base64;
use Digest::GOST::CryptoPro qw(gost gost_hex gost_base64);
use Data::Dumper;
use Net::DNS::RR;
use Net::DNS::RR::DS;
=pod
An example from RFC 5933
example.net. 86400 DNSKEY 257 3 12 (
LMgXRHzSbIJGn6i16K+sDjaDf/k1o9DbxScO
gEYqYS/rlh2Mf+BRAY3QHPbwoPh2fkDKBroF
SRGR7ZYcx+YIQw==
) ; key id = 40692
The DS RR will be
example.net. 3600 IN DS 40692 12 3 (
22261A8B0E0D799183E35E24E2AD6BB58533CBA7E3B14D659E9CA09B
2071398F )
=cut
my $record =
" example.net. 86400 DNSKEY 257 3 12 (
LMgXRHzSbIJGn6i16K+sDjaDf/k1o9DbxScO
gEYqYS/rlh2Mf+BRAY3QHPbwoPh2fkDKBroF
SRGR7ZYcx+YIQw==
) ; key id = 40692
";
my $keyrr = Net::DNS::RR->new_from_string($record);
my $data = $keyrr->_name2wire ($keyrr->name) . $keyrr->_canonicalRdata; # this is a part of Net::DNS::Sec that creates binary on whitch digest is calculated
print uc(gost_hex($data));