Changeset 175 for trunk/lib/Vote/DB/Poll.pm
- Timestamp:
- 04/08/09 04:07:58 (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/lib/Vote/DB/Poll.pm
r173 r175 8 8 use Mail::Mailer; 9 9 use Crypt::RSA; 10 use Crypt::RSA::Key::Public::SSH; 11 use Crypt::RSA::Key::Private::SSH; 10 12 use Crypt::CBC; 11 13 use XML::Simple; … … 37 39 38 40 sub voteid { $_[0]->{voteid} } 41 42 sub setup { 43 my ($self) = @_; 44 $self->param( 45 free_choice => 0, 46 choice_count => 1, 47 ); 48 } 39 49 40 50 sub param { … … 294 304 my ($self, $choice, $fchoice) = @_; 295 305 306 my $uid = ($self->is_crypted 307 ? $self->_register_ballot_crypted($choice, $fchoice) 308 : $self->_register_ballot_clear($choice, $fchoice)) 309 or do { 310 self->db->rollback; 311 return; 312 }; 313 314 $uid 315 } 316 317 sub _register_ballot_clear { 318 my ($self, $choice, $fchoice, $uid) = @_; 319 296 320 my $addb = $self->db->prepare_cached( 297 321 q{ … … 299 323 } 300 324 ); 301 my $uid= Vote::DB::common::gen_uid();325 $uid ||= Vote::DB::common::gen_uid(); 302 326 $addb->execute($uid, $self->voteid, scalar(@{$fchoice || []}) ? undef : 'f') or do { 303 327 self->db->rollback; … … 336 360 337 361 $uid; 362 } 363 364 sub _register_ballot_crypted { 365 my ($self, $choice, $fchoice) = @_; 366 my $xml = XML::Simple->new(ForceArray => 1, RootName => 'ballot'); 367 my $symkey = map{ chr(rand(256)) } (1 .. (256 / 8)); 368 my $cipher = new Crypt::CBC($symkey, 'DES'); 369 my $ballotuid = Vote::DB::common::gen_uid(); 370 my $encryptedballot = $cipher->encrypt_hex( 371 $xml->XMLout({ 372 id => $ballotuid, 373 sbal => $choice, 374 fsbal => $fchoice 375 }) 376 ); 377 my $encsymkey = $self->rsa->encrypt ( 378 Message => $symkey, 379 Key => $self->public_key, 380 Armour => 1, 381 ) || die $self->rsa->errstr(); 382 383 my $addenc = $self->db->prepare_cached( 384 q{insert into ballot_enc (id, data, enckey, poll) values (?,?,?,?)} 385 ); 386 387 my $uid = Vote::DB::common::gen_uid(); 388 $addenc->execute($uid, $encryptedballot, $encsymkey, $self->voteid); 389 $ballotuid; 390 } 391 392 sub _decrypted_ballot { 393 my ($self, $ballotid, $privkey) = @_; 394 my $sth = $self->db->prepare_cached( 395 q{select * from ballot_enc where id = ? for update} 396 ); 397 $sth->execute($ballotid); 398 my $ballot = $sth->fetchrow_hashref; 399 $sth->finish; 400 my $encsymkey = $ballot->{enckey}; 401 my $data = $ballot->{data}; 402 my $symkey = $self->rsa->decrypt ( 403 Cyphertext => $encsymkey, 404 Key => $privkey, 405 Armour => 1, 406 ) || die $self->rsa->errstr(); 407 my $cipher = new Crypt::CBC($symkey, 'DES'); 408 my $xmldata = XMLin($cipher->decrypt_hex($data), ForceArray => 1); 409 $self->_register_ballot_clear($xmldata->{sbal}, $xmldata->{fsbal}, $xmldata->{id}); 410 my $upd = $self->db->prepare_cached(q{update ballot_enc set decrypted = true where id = ?}); 411 if ($upd->execute($ballotid)) { 412 $self->db->commit; 413 return; 414 } else { 415 $self->db->rollback; 416 return 1; 417 } 418 } 419 420 sub decrypted_ballots { 421 my ($self, $password) = @_; 422 my $privkey = $self->private_key($password); 423 foreach ($self->list_ballot_need_dec) { 424 $self->_decrypted_ballot($_, $privkey); 425 } 338 426 } 339 427 … … 422 510 } 423 511 512 sub is_crypted { 513 my ($self) = @_; 514 return $self->info->{public_key} ? 1 : 0; 515 } 516 424 517 sub ballot_count { 425 518 my ($self) = @_; 426 427 my $sth = $self->db->prepare_cached( 428 q{ 429 select count(*) from ballot where poll = ? 430 } 519 return $self->is_crypted 520 ? $self->ballot_count_crypt 521 : $self->ballot_count_clear; 522 } 523 524 sub ballot_count_clear { 525 my ($self) = @_; 526 527 my $sth = $self->db->prepare_cached( 528 q{select count(*) from ballot where poll = ?} 529 ); 530 531 $sth->execute($self->voteid); 532 my $res = $sth->fetchrow_hashref; 533 $sth->finish; 534 $res->{count} 535 } 536 537 sub ballot_count_crypt { 538 my ($self) = @_; 539 540 my $sth = $self->db->prepare_cached( 541 q{select count(*) from ballot_enc where poll = ?} 431 542 ); 432 543 … … 565 676 q{ 566 677 select id from ballot where poll = ? 678 order by id 679 } 680 ); 681 $sth->execute($self->voteid); 682 my @ids; 683 while (my $res = $sth->fetchrow_hashref) { 684 push(@ids, $res->{id}); 685 } 686 @ids 687 } 688 689 sub list_ballot_enc { 690 my ($self) = @_; 691 692 my $sth = $self->db->prepare_cached( 693 q{ 694 select id from ballot_enc where poll = ? 695 order by id 696 } 697 ); 698 $sth->execute($self->voteid); 699 my @ids; 700 while (my $res = $sth->fetchrow_hashref) { 701 push(@ids, $res->{id}); 702 } 703 @ids 704 } 705 706 sub list_ballot_need_dec { 707 my ($self) = @_; 708 709 my $sth = $self->db->prepare_cached( 710 q{ 711 select id from ballot_enc where poll = ? and decrypted = 'false' 567 712 order by id 568 713 } … … 715 860 716 861 sub gen_poll_keys { 717 my ($self ) = @_;862 my ($self, $password) = @_; 718 863 my ($public, $private) = $self->rsa->keygen ( 719 864 Identity => 'Epoll Vote ' . $self->voteid, 720 865 Size => 768, 721 Password => undef,866 Password => $password, 722 867 Verbosity => 0, 723 868 KF=>'SSH', … … 732 877 my ($self) = @_; 733 878 my $serialize = $self->info->{public_key} or return; 734 my $pubkey = Crypt::RSA::Key::Public->new; 735 $pubkey->deserialize($serialize); 736 879 my $pubkey = Crypt::RSA::Key::Public::SSH->new; 880 $pubkey->deserialize(String => [ $serialize ]); 737 881 $pubkey 738 882 } 739 883 884 sub private_key { 885 my ($self, $password) = @_; 886 my $serialize = $self->info->{private_key} or return; 887 my $privkey = Crypt::RSA::Key::Private::SSH->new; 888 $privkey->deserialize(String => [ decode_base64($serialize) ], Passphrase => $password); 889 $privkey 890 } 740 891 =head1 AUTHOR 741 892
Note: See TracChangeset
for help on using the changeset viewer.