ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/AnyEvent-MP/MP/Transport.pm
(Generate patch)

Comparing AnyEvent-MP/MP/Transport.pm (file contents):
Revision 1.84 by root, Sun Mar 25 20:50:49 2012 UTC vs.
Revision 1.85 by root, Sun Aug 28 08:13:43 2016 UTC

27use Scalar::Util (); 27use Scalar::Util ();
28use List::Util (); 28use List::Util ();
29use MIME::Base64 (); 29use MIME::Base64 ();
30 30
31use JSON::XS (); 31use JSON::XS ();
32use Digest::MD6 (); 32use Digest::SHA3 ();
33use Digest::HMAC_MD6 (); 33use Digest::HMAC ();
34 34
35use AnyEvent (); 35use AnyEvent ();
36use AnyEvent::Socket (); 36use AnyEvent::Socket ();
37use AnyEvent::Handle 4.92 (); 37use AnyEvent::Handle 4.92 ();
38 38
118 tls_ctx => AnyEvent::TLS, 118 tls_ctx => AnyEvent::TLS,
119 peername => $peername, # for verification 119 peername => $peername, # for verification
120 ; 120 ;
121 121
122=cut 122=cut
123
124sub hmac_sha3_512_hex($$) {
125 Digest::HMAC::hmac_hex $_[1], $_[0], \&Digest::SHA3::sha3_512, 72
126}
123 127
124sub new { 128sub new {
125 my ($class, %arg) = @_; 129 my ($class, %arg) = @_;
126 130
127 my $self = bless \%arg, $class; 131 my $self = bless \%arg, $class;
254 } 258 }
255 259
256 defined $s_framing 260 defined $s_framing
257 or return $self->error ("$framings: no common framing method supported"); 261 or return $self->error ("$framings: no common framing method supported");
258 262
259 my $key;
260 my $lauth; 263 my $lauth;
261 264
262 if ($tls) { 265 if ($tls) {
263 $self->{tls} = $lgreeting2 lt $rgreeting2 ? "connect" : "accept"; 266 $self->{tls} = $lgreeting2 lt $rgreeting2 ? "connect" : "accept";
264 $self->{hdl}->starttls ($self->{tls}, $self->{tls_ctx}); 267 $self->{hdl}->starttls ($self->{tls}, $self->{tls_ctx});
265 return unless $self->{hdl}; # starttls might destruct us 268 return unless $self->{hdl}; # starttls might destruct us
266 269
267 $lauth = 270 $lauth =
268 $s_auth eq "tls_anon" ? "" 271 $s_auth eq "tls_anon" ? ""
269 : $s_auth eq "tls_md6_64_256" ? Digest::MD6::md6_hex "$lgreeting1\012$lgreeting2\012$rgreeting1\012$rgreeting2\012" 272 : $s_auth eq "tls_sha3_512" ? Digest::SHA3::sha3_512_hex "$lgreeting1\012$lgreeting2\012$rgreeting1\012$rgreeting2\012"
270 : return $self->error ("$s_auth: fatal, selected unsupported snd auth method"); 273 : return $self->error ("$s_auth: fatal, selected unsupported snd auth method");
271 274
272 } elsif (length $secret) { 275 } elsif (length $secret) {
273 return $self->error ("$s_auth: fatal, selected unsupported snd auth method") 276 return $self->error ("$s_auth: fatal, selected unsupported snd auth method")
274 unless $s_auth eq "hmac_md6_64_256"; # hardcoded atm. 277 unless $s_auth eq "hmac_sha3_512"; # hardcoded atm.
275 278
276 $key = Digest::MD6::md6 $secret;
277 # we currently only support hmac_md6_64_256
278 $lauth = Digest::HMAC_MD6::hmac_md6_hex $key, "$lgreeting1\012$lgreeting2\012$rgreeting1\012$rgreeting2\012", 64, 256; 279 $lauth = hmac_sha3_512_hex $secret, "$lgreeting1\012$lgreeting2\012$rgreeting1\012$rgreeting2\012";
279 280
280 } else { 281 } else {
281 return $self->error ("unable to handshake TLS and no shared secret configured"); 282 return $self->error ("unable to handshake TLS and no shared secret configured");
282 } 283 }
283 284
289 my ($hdl, $rline) = @_; 290 my ($hdl, $rline) = @_;
290 291
291 my ($auth_method, $rauth2, $r_framing) = split /;/, $rline; 292 my ($auth_method, $rauth2, $r_framing) = split /;/, $rline;
292 293
293 my $rauth = 294 my $rauth =
294 $auth_method eq "hmac_md6_64_256" ? Digest::HMAC_MD6::hmac_md6_hex $key, "$rgreeting1\012$rgreeting2\012$lgreeting1\012$lgreeting2\012", 64, 256 295 $auth_method eq "hmac_sha3_512" ? hmac_sha3_512_hex $secret, "$rgreeting1\012$rgreeting2\012$lgreeting1\012$lgreeting2\012"
295 : $auth_method eq "cleartext" ? unpack "H*", $secret 296 : $auth_method eq "cleartext" ? unpack "H*", $secret
296 : $auth_method eq "tls_anon" ? ($tls ? "" : "\012\012") # \012\012 never matches 297 : $auth_method eq "tls_anon" ? ($tls ? "" : "\012\012") # \012\012 never matches
297 : $auth_method eq "tls_md6_64_256" ? ($tls ? Digest::MD6::md6_hex "$rgreeting1\012$rgreeting2\012$lgreeting1\012$lgreeting2\012" : "\012\012") 298 : $auth_method eq "tls_sha3_512" ? ($tls ? Digest::SHA3::sha3_512_hex "$rgreeting1\012$rgreeting2\012$lgreeting1\012$lgreeting2\012" : "\012\012")
298 : return $self->error ("$auth_method: fatal, selected unsupported rcv auth method"); 299 : return $self->error ("$auth_method: fatal, selected unsupported rcv auth method");
299 300
300 if ($rauth2 ne $rauth) { 301 if ($rauth2 ne $rauth) {
301 return $self->error ("authentication failure/shared secret mismatch"); 302 return $self->error ("authentication failure/shared secret mismatch");
302 } 303 }
612This is simply the shared secret, lowercase-hex-encoded. This method is of 613This is simply the shared secret, lowercase-hex-encoded. This method is of
613course very insecure if TLS is not used (and not completely secure even 614course very insecure if TLS is not used (and not completely secure even
614if TLS is used), which is why this module will accept, but not generate, 615if TLS is used), which is why this module will accept, but not generate,
615cleartext auth replies. 616cleartext auth replies.
616 617
617=item hmac_md6_64_256 618=item hmac_sha3_512
618 619
619This method uses an MD6 HMAC with 64 bit blocksize and 256 bit hash, and 620This method uses a SHA-3/512 HMAC with 576 bit blocksize and 512 bit hash,
620requires a shared secret. It is the preferred auth method when a shared 621and requires a shared secret. It is the preferred auth method when a
621secret is available. 622shared secret is available.
622 623
623First, the shared secret is hashed with MD6:
624
625 key = MD6 (secret)
626
627This secret is then used to generate the "local auth reply", by taking 624The secret is used to generate the "local auth reply", by taking the
628the two local greeting lines and the two remote greeting lines (without 625two local greeting lines and the two remote greeting lines (without
629line endings), appending \012 to all of them, concatenating them and 626line endings), appending \012 to all of them, concatenating them and
630calculating the MD6 HMAC with the key: 627calculating the HMAC with the key:
631 628
632 lauth = HMAC_MD6 key, "lgreeting1\012lgreeting2\012rgreeting1\012rgreeting2\012" 629 lauth = HMAC_SHA3_512 key, "lgreeting1\012lgreeting2\012rgreeting1\012rgreeting2\012"
633 630
634This authentication token is then lowercase-hex-encoded and sent to the 631This authentication token is then lowercase-hex-encoded and sent to the
635other side. 632other side.
636 633
637Then the remote auth reply is generated using the same method, but local 634Then the remote auth reply is generated using the same method, but local
638and remote greeting lines swapped: 635and remote greeting lines swapped:
639 636
640 rauth = HMAC_MD6 key, "rgreeting1\012rgreeting2\012lgreeting1\012lgreeting2\012" 637 rauth = HMAC_SHA3_512 key, "rgreeting1\012rgreeting2\012lgreeting1\012lgreeting2\012"
641 638
642This is the token that is expected from the other side. 639This is the token that is expected from the other side.
640
641=item hmac_md6_64_256 [obsolete, not supported]
642
643This method uses an MD6 HMAC with 64 bit blocksize and 256 bit hash, and
644requires a shared secret. It is similar to C<hmac_sha3_512>, but uses
645MD6 instead of SHA-3 and instead of using the secret directly, it uses
646MD6(secret) as HMAC key.
643 647
644=item tls_anon 648=item tls_anon
645 649
646This type is only valid I<iff> TLS was enabled and the TLS handshake 650This type is only valid I<iff> TLS was enabled and the TLS handshake
647was successful. It has no authentication data, as the server/client 651was successful. It has no authentication data, as the server/client
653exploits this in a way that is worse than just denying the service. 657exploits this in a way that is worse than just denying the service.
654 658
655By default, this implementation accepts but never generates this auth 659By default, this implementation accepts but never generates this auth
656reply. 660reply.
657 661
658=item tls_md6_64_256 662=item tls_sha3_512
659 663
660This type is only valid I<iff> TLS was enabled and the TLS handshake was 664This type is only valid I<iff> TLS was enabled and the TLS handshake was
661successful. 665successful.
662 666
663This authentication type simply calculates: 667This authentication type simply calculates:
664 668
665 lauth = MD6 "rgreeting1\012rgreeting2\012lgreeting1\012lgreeting2\012" 669 lauth = SHA3_512 "rgreeting1\012rgreeting2\012lgreeting1\012lgreeting2\012"
666 670
667and lowercase-hex encodes the result and sends it as authentication 671and lowercase-hex encodes the result and sends it as authentication
668data. No shared secret is required (authentication is done by TLS). The 672data. No shared secret is required (authentication is done by TLS). The
669checksum exists only to make tinkering with the greeting hard. 673checksum exists only to make tinkering with the greeting hard.
674
675=item tls_md6_64_256 [deprecated, unsupported]
676
677Same as C<tls_sha3_512>, except MD6 is used.
670 678
671=back 679=back
672 680
673=item the authentication data 681=item the authentication data
674 682
726check the authenticity of the other side and use cleartext authentication 734check the authenticity of the other side and use cleartext authentication
727yourself. The the handshake is as simple as sending three lines of text, 735yourself. The the handshake is as simple as sending three lines of text,
728reading three lines of text, and then you can exchange JSON-formatted 736reading three lines of text, and then you can exchange JSON-formatted
729messages: 737messages:
730 738
731 aemp;1;<nodename>;hmac_md6_64_256;json 739 aemp;1;<nodename>;hmac_sha3_512;json
732 <nonce> 740 <nonce>
733 cleartext;<hexencoded secret>;json 741 cleartext;<hexencoded secret>;json
734 742
735The nodename should be unique within the network, preferably unique with 743The nodename should be unique within the network, preferably unique with
736every connection, the <nonce> could be empty or some random data, and the 744every connection, the <nonce> could be empty or some random data, and the

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines