Repository: vvk-ehk/ivxv Branch: published Commit: 2785872f84df Files: 1403 Total size: 5.0 MB Directory structure: gitextract_eag_ui9l/ ├── .editorconfig ├── .gitignore ├── .gitmodules ├── Documentation/ │ ├── .gitignore │ ├── Makefile │ ├── _static/ │ │ └── custom.css │ ├── common/ │ │ ├── examples/ │ │ │ ├── id.rpc.vote.query.json │ │ │ ├── id.rpc.vote.response.json │ │ │ ├── id.rpc.voterchoices.query.json │ │ │ ├── id.rpc.voterchoices.response.json │ │ │ ├── json.rpc.method.query.json │ │ │ ├── json.rpc.method.response.json │ │ │ ├── mid.rpc.authenticate.query.json │ │ │ ├── mid.rpc.authenticate.response.json │ │ │ ├── mid.rpc.authenticatestatus.query.json │ │ │ ├── mid.rpc.authenticatestatus.response.json │ │ │ ├── mid.rpc.authenticatestatus2.query.json │ │ │ ├── mid.rpc.authenticatestatus2.response.json │ │ │ ├── mid.rpc.getcertificate.query.json │ │ │ ├── mid.rpc.getcertificate.response.json │ │ │ ├── mid.rpc.sign.query.json │ │ │ ├── mid.rpc.sign.response.json │ │ │ ├── mid.rpc.signstatus.query.json │ │ │ ├── mid.rpc.signstatus.response.json │ │ │ ├── mid.rpc.signstatus2.query.json │ │ │ ├── mid.rpc.signstatus2.response.json │ │ │ ├── mid.rpc.vote.query.json │ │ │ ├── mid.rpc.vote.response.json │ │ │ ├── mid.rpc.voterchoices.query.json │ │ │ ├── mid.rpc.voterchoices.response.json │ │ │ ├── smartid.rpc.authenticate.query.json │ │ │ ├── smartid.rpc.authenticate.response.json │ │ │ ├── smartid.rpc.authenticatestatus.query.json │ │ │ ├── smartid.rpc.authenticatestatus.response.json │ │ │ ├── smartid.rpc.authenticatestatus2.query.json │ │ │ ├── smartid.rpc.authenticatestatus2.response.json │ │ │ ├── smartid.rpc.challenge.query.json │ │ │ ├── smartid.rpc.challenge.response.json │ │ │ ├── smartid.rpc.getcertificatechoice.query.json │ │ │ ├── smartid.rpc.getcertificatechoice.response.json │ │ │ ├── smartid.rpc.getcertificatechoicestatus.query.json │ │ │ ├── smartid.rpc.getcertificatechoicestatus.response.json │ │ │ ├── smartid.rpc.getcertificatechoicestatus2.response.json │ │ │ ├── smartid.rpc.sign.query.json │ │ │ ├── smartid.rpc.sign.response.json │ │ │ ├── smartid.rpc.signstatus.query.json │ │ │ ├── smartid.rpc.signstatus.response.json │ │ │ ├── smartid.rpc.signstatus2.query.json │ │ │ ├── smartid.rpc.signstatus2.response.json │ │ │ ├── smartid.rpc.vote.query.json │ │ │ ├── smartid.rpc.vote.response.json │ │ │ ├── smartid.rpc.voterchoices.query.json │ │ │ ├── smartid.rpc.voterchoices.response.json │ │ │ ├── ver.rpc.verify.query.json │ │ │ ├── ver.rpc.verify.response.json │ │ │ ├── votesorder.rpc.votes.query.json │ │ │ ├── votesorder.rpc.votes.response.json │ │ │ ├── votesorder.rpc.votesseqno.query.json │ │ │ ├── votesorder.rpc.votesseqno.response.json │ │ │ ├── webeid.rpc.challenge.query.json │ │ │ ├── webeid.rpc.challenge.response.json │ │ │ ├── webeid.rpc.token.query.json │ │ │ ├── webeid.rpc.token.response.json │ │ │ ├── webeid.rpc.vote.query.json │ │ │ ├── webeid.rpc.vote.response.json │ │ │ ├── webeid.rpc.voterchoices.query.json │ │ │ └── webeid.rpc.voterchoices.response.json │ │ ├── schema/ │ │ │ ├── Makefile │ │ │ ├── ivxv.anon-bb.schema │ │ │ ├── ivxv.anon-bb.schema.example │ │ │ ├── ivxv.choices.schema │ │ │ ├── ivxv.choices.schema.example │ │ │ ├── ivxv.districts.schema │ │ │ ├── ivxv.districts.schema.example │ │ │ ├── ivxv.result.schema │ │ │ ├── ivxv.result.schema.example │ │ │ ├── ivxv.revoke.schema │ │ │ ├── ivxv.revoke.schema.example │ │ │ ├── ivxv.voterlist.schema │ │ │ ├── ivxv.voterlist.schema.example │ │ │ └── validate_schema.py │ │ └── xmltemplates/ │ │ ├── si.template │ │ ├── sig.template │ │ ├── sp.template │ │ └── sv.template │ ├── common-model.mk │ ├── common.mk │ ├── conf.py │ ├── differ.sh │ ├── documents.py │ ├── en/ │ │ └── backendlogs/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── create_rst.py │ │ └── introduction.inc │ ├── et/ │ │ ├── audiitor/ │ │ │ ├── Makefile │ │ │ ├── annotatsioon.rst │ │ │ ├── audit.rst │ │ │ ├── history.rst │ │ │ ├── history.txt │ │ │ ├── index.rst │ │ │ ├── spelling_wordlist.txt │ │ │ └── ylevaade.rst │ │ ├── example-config/ │ │ │ ├── DEMO_auditor/ │ │ │ │ └── DEMO_auditor.yaml │ │ │ ├── DEMO_election/ │ │ │ │ ├── DEMO.election.yaml │ │ │ │ ├── DEMO_valijate_nimekiri.pem │ │ │ │ ├── EE-GovCA2018.pem.crt │ │ │ │ ├── EE_Certification_Centre_Root_CA.pem.crt │ │ │ │ ├── ESTEID-SK_2015.pem.crt │ │ │ │ ├── SK_OCSP_RESPONDER_2011.pem.cer │ │ │ │ ├── SK_TIMESTAMPING_AUTHORITY.pem.cer │ │ │ │ └── esteid2018.pem.crt │ │ │ ├── DEMO_ivxv/ │ │ │ │ ├── EE-GovCA2018.pem.crt │ │ │ │ ├── ESTEID-SK_2015.pem.crt │ │ │ │ ├── ESTEID2018.pem.crt │ │ │ │ ├── SK_OCSP_RESPONDER_2011.pem.crt │ │ │ │ ├── SK_TIMESTAMPING_AUTHORITY_2019.pem.crt │ │ │ │ ├── SK_TIMESTAMPING_AUTHORITY_2020.pem.crt │ │ │ │ ├── SK_TIMESTAMPING_AUTHORITY_2021.pem.crt │ │ │ │ └── ivxv.properties │ │ │ ├── DEMO_key.decrypt_f/ │ │ │ │ └── DEMO_key.decrypt_f.yaml │ │ │ ├── DEMO_key.decrypt_t/ │ │ │ │ └── DEMO_key.decrypt_t.yaml │ │ │ ├── DEMO_key.groupgen/ │ │ │ │ └── key.groupgen.yaml │ │ │ ├── DEMO_key.init/ │ │ │ │ └── key.init.yaml │ │ │ ├── DEMO_processor_TS/ │ │ │ │ └── DEMO_processor_TS.yaml │ │ │ ├── DEMO_technical/ │ │ │ │ ├── ca.pem │ │ │ │ └── technical.yaml │ │ │ └── DEMO_trust/ │ │ │ ├── DEMO.trust.yaml │ │ │ ├── EE-GovCA2018.pem.crt │ │ │ ├── EE_Certification_Centre_Root_CA.pem.crt │ │ │ ├── ESTEID-SK_2015.pem.crt │ │ │ ├── SK_OCSP_RESPONDER_2011.pem.cer │ │ │ ├── SK_TIMESTAMPING_AUTHORITY.pem.cer │ │ │ └── esteid2018.pem.crt │ │ ├── haldusteenus/ │ │ │ ├── Makefile │ │ │ ├── allalaadimised.rst │ │ │ ├── annotatsioon.rst │ │ │ ├── index.rst │ │ │ ├── kasutajad.rst │ │ │ ├── logi.rst │ │ │ ├── nimekirjad.rst │ │ │ ├── seadistused.rst │ │ │ ├── spelling_wordlist.txt │ │ │ ├── statistika.rst │ │ │ ├── teenused.rst │ │ │ ├── yldseisund.rst │ │ │ └── ylevaade.rst │ │ ├── kasutusmall/ │ │ │ ├── Makefile │ │ │ ├── index.rst │ │ │ ├── kasutusmallid.rst │ │ │ ├── sissejuhatus.rst │ │ │ └── tegijad.rst │ │ ├── kogumisteenuse_haldusjuhend/ │ │ │ ├── Makefile │ │ │ ├── algseadistamine.rst │ │ │ ├── annotatsioon.rst │ │ │ ├── genereeritud-failid/ │ │ │ │ ├── e-valimiskasti_koostamine.inc │ │ │ │ ├── haldusteenus-laadi_kogumisteenuse_tehnilised_seadistused.inc │ │ │ │ ├── haldusteenus-laadi_ringkondade_nimekiri.inc │ │ │ │ ├── haldusteenus-laadi_usaldusjuure_seadistused.inc │ │ │ │ ├── haldusteenus-laadi_valijate_nimekiri.inc │ │ │ │ ├── haldusteenus-laadi_valikute_nimekiri.inc │ │ │ │ ├── haldusteenus-laadi_valimiste_seadistused.inc │ │ │ │ ├── haldusteenuse_paigaldamine.inc │ │ │ │ ├── haldusteenuse_soltuvuste_paigaldamine.inc │ │ │ │ ├── kasutaja_lisamine.inc │ │ │ │ ├── mikroteenuse_kaivitamine.inc │ │ │ │ ├── mikroteenuse_seiskamine.inc │ │ │ │ ├── mikroteenuse_seisundi_tuvastamine.inc │ │ │ │ └── töötlemisrakenduse_sisendi_koostamine.inc │ │ │ ├── haldusteenus.rst │ │ │ ├── haldustoimingud.rst │ │ │ ├── index.rst │ │ │ ├── krahhitaaste.rst │ │ │ ├── lisad.rst │ │ │ ├── protseduurid.rst │ │ │ ├── recovery/ │ │ │ │ ├── recovery_backupservice.inc │ │ │ │ ├── recovery_fullstorage.inc │ │ │ │ ├── recovery_logcollection.inc │ │ │ │ ├── recovery_stateless.inc │ │ │ │ └── recovery_storageservice.inc │ │ │ ├── seadistused.rst │ │ │ ├── spelling_wordlist.txt │ │ │ ├── utiliitide-abiteave/ │ │ │ │ ├── ivxv-admin-helper.inc │ │ │ │ ├── ivxv-admin-sudo.inc │ │ │ │ ├── ivxv-agent-daemon.inc │ │ │ │ ├── ivxv-backup-crontab.inc │ │ │ │ ├── ivxv-backup.inc │ │ │ │ ├── ivxv-cmd-load.inc │ │ │ │ ├── ivxv-collector-init.inc │ │ │ │ ├── ivxv-config-apply.inc │ │ │ │ ├── ivxv-config-validate.inc │ │ │ │ ├── ivxv-copy-log-to-logmon.inc │ │ │ │ ├── ivxv-create-data-dirs.inc │ │ │ │ ├── ivxv-db-dump.inc │ │ │ │ ├── ivxv-db-reset.inc │ │ │ │ ├── ivxv-eventlog-dump.inc │ │ │ │ ├── ivxv-export-votes.inc │ │ │ │ ├── ivxv-generate-processor-input.inc │ │ │ │ ├── ivxv-secret-load.inc │ │ │ │ ├── ivxv-service.inc │ │ │ │ ├── ivxv-status.inc │ │ │ │ ├── ivxv-update-packages.inc │ │ │ │ ├── ivxv-users-list.inc │ │ │ │ ├── ivxv-voter-list-download.inc │ │ │ │ ├── ivxv-voterstats.inc │ │ │ │ └── ivxv-voting-sessions.inc │ │ │ └── ylevaade.rst │ │ ├── seadistuste_koostejuhend/ │ │ │ ├── Makefile │ │ │ ├── annotatsioon.rst │ │ │ ├── auditirakendus.rst │ │ │ ├── config-examples/ │ │ │ │ ├── DEMO_SK_TIMESTAMPING_AUTHORITY_2020.pem │ │ │ │ ├── Stats_Server_Certificate.pem │ │ │ │ ├── TEST_of_EE_Certification_Centre_Root_CA.pem │ │ │ │ ├── TEST_of_ESTEID-SK_2015.pem │ │ │ │ ├── TEST_of_SK_OCSP_RESPONDER_2020.pem │ │ │ │ ├── android-ios-config.json │ │ │ │ ├── auditor.convert.yaml │ │ │ │ ├── auditor.decrypt.yaml │ │ │ │ ├── auditor.integrity.yaml │ │ │ │ ├── auditor.mixer.yaml │ │ │ │ ├── etcd_CA.pem │ │ │ │ ├── example.election.yaml │ │ │ │ ├── example.technical.yaml │ │ │ │ ├── example.trust.yaml │ │ │ │ ├── example.voters.skip.yaml │ │ │ │ ├── ivxv.properties.real │ │ │ │ ├── key.decrypt.yaml │ │ │ │ ├── key.groupgen.yaml │ │ │ │ ├── key.init.original.yaml │ │ │ │ ├── key.init.yaml │ │ │ │ ├── key.testkey.yaml │ │ │ │ ├── key.util.yaml │ │ │ │ ├── processor.anonymize.yaml │ │ │ │ ├── processor.check.yaml │ │ │ │ ├── processor.checkAndSquash.yaml │ │ │ │ ├── processor.export.yaml │ │ │ │ ├── processor.revoke.yaml │ │ │ │ ├── processor.revokeAndAnonymize.yaml │ │ │ │ ├── processor.squash.yaml │ │ │ │ ├── processor.stats.yaml │ │ │ │ ├── processor.statsdiff.yaml │ │ │ │ ├── processor.verify.yaml │ │ │ │ ├── rnd.groupgen.yaml │ │ │ │ ├── rnd.init.yaml │ │ │ │ ├── rr_pub.key │ │ │ │ ├── vote_enc_pkey.pem │ │ │ │ └── xroadservice_ca.pem │ │ │ ├── genparam.py │ │ │ ├── index.rst │ │ │ ├── kogumisteenus.rst │ │ │ ├── kontrollrakendus.rst │ │ │ ├── kt-krypto.inc │ │ │ ├── kt-tehniline.inc │ │ │ ├── kt-usaldusjuur.inc │ │ │ ├── kt-valijate-nimekirja-vahelejätmine.inc │ │ │ ├── kt-valimised.inc │ │ │ ├── kt-volitused.inc │ │ │ ├── kt-ylevaade.inc │ │ │ ├── mixnet.rst │ │ │ ├── rakendused.rst │ │ │ ├── spelling_wordlist.txt │ │ │ ├── tootlemisrakendus.rst │ │ │ ├── valijarakendus.rst │ │ │ ├── votmerakendus.rst │ │ │ └── ylevaade.rst │ │ ├── votmerakendus/ │ │ │ ├── Makefile │ │ │ ├── index.rst │ │ │ ├── sissejuhatus.rst │ │ │ ├── viited.rst │ │ │ └── votmeosakute_protokollid.rst │ │ └── xteeteenus/ │ │ ├── Makefile │ │ ├── index.rst │ │ ├── jooksevnimekiri.rst │ │ ├── model/ │ │ │ ├── Makefile │ │ │ ├── xteeivxv.pu │ │ │ └── xteevotesorder.pu │ │ ├── seadistamine.rst │ │ └── sissejuhatus.rst │ ├── ivxv-technical/ │ │ ├── ivxv-common.cls │ │ ├── ivxv-technical.cls │ │ └── pandoc-extras.sty │ ├── podl/ │ │ ├── .gitignore │ │ ├── podl.py │ │ ├── requirements.in │ │ └── requirements.txt │ ├── public/ │ │ ├── arhitektuur/ │ │ │ ├── Makefile │ │ │ ├── etcd.rst │ │ │ ├── index.rst │ │ │ ├── kogumisteenus.rst │ │ │ ├── locales/ │ │ │ │ └── en/ │ │ │ │ └── LC_MESSAGES/ │ │ │ │ ├── etcd.po │ │ │ │ ├── index.po │ │ │ │ ├── kogumisteenus.po │ │ │ │ ├── tehnoloogiad.po │ │ │ │ ├── vallasrezhiim.po │ │ │ │ ├── viited.po │ │ │ │ └── yldpohimotted.po │ │ │ ├── model/ │ │ │ │ ├── Makefile │ │ │ │ ├── actors.pu │ │ │ │ ├── collector-if.pu │ │ │ │ ├── collector-in.pu │ │ │ │ ├── development.pu │ │ │ │ ├── elec-vote.pu │ │ │ │ ├── election.pu │ │ │ │ ├── en/ │ │ │ │ │ └── lang.pu │ │ │ │ ├── et/ │ │ │ │ │ └── lang.pu │ │ │ │ ├── example.pu │ │ │ │ ├── general.pu │ │ │ │ ├── ms-collector-status.pu │ │ │ │ ├── ms-management-service-components.en.pu │ │ │ │ ├── ms-management-service-components.et.pu │ │ │ │ ├── ms-service-status-changes.en.pu │ │ │ │ ├── ms-service-status-changes.et.pu │ │ │ │ ├── ms-service-status.en.pu │ │ │ │ ├── ms-service-status.et.pu │ │ │ │ ├── ms-upload-command.en.pu │ │ │ │ ├── ms-upload-command.et.pu │ │ │ │ ├── ms-voter-list-status.en.pu │ │ │ │ ├── ms-voter-list-status.et.pu │ │ │ │ ├── skin.inc │ │ │ │ ├── uc-audit.pu │ │ │ │ ├── uc-offline.pu │ │ │ │ ├── uc-online.pu │ │ │ │ ├── uc-prep.pu │ │ │ │ ├── uc-tootleja.pu │ │ │ │ └── uc-votmerakendus.pu │ │ │ ├── spelling_wordlist.txt │ │ │ ├── tehnoloogiad.rst │ │ │ ├── vallasrezhiim.rst │ │ │ ├── viited.rst │ │ │ └── yldpohimotted.rst │ │ ├── liidesed/ │ │ │ ├── Makefile │ │ │ ├── examples.rst │ │ │ ├── index.rst │ │ │ ├── locales/ │ │ │ │ ├── en/ │ │ │ │ │ └── LC_MESSAGES/ │ │ │ │ │ ├── VIS3-EHS/ │ │ │ │ │ │ ├── 1_Valimisringkondade_nimekiri/ │ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ │ ├── 2_Valikute_nimekiri/ │ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ │ ├── 3_Valijate_nimekiri/ │ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ │ ├── 4_e_haaletanute_nimekiri/ │ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ │ ├── 5_Tyhistusnimekiri/ │ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ │ ├── 6_e_haaletamise_tulemus/ │ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ │ ├── 7_e_haaletamise_yldstatistika/ │ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ │ ├── 8_e_haaletamise_detailstatistika/ │ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ │ ├── 9_e_haaletamiste_nimekiri/ │ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ │ ├── README.po │ │ │ │ │ │ ├── Taustateave/ │ │ │ │ │ │ │ └── README.po │ │ │ │ │ │ └── valimissündmuse_identifikaator.po │ │ │ │ │ ├── examples.po │ │ │ │ │ └── index.po │ │ │ │ └── et/ │ │ │ │ └── LC_MESSAGES/ │ │ │ │ ├── VIS3-EHS/ │ │ │ │ │ ├── 1_Valimisringkondade_nimekiri/ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ ├── 2_Valikute_nimekiri/ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ ├── 3_Valijate_nimekiri/ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ ├── 4_e_haaletanute_nimekiri/ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ ├── 5_Tyhistusnimekiri/ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ ├── 6_e_haaletamise_tulemus/ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ ├── 7_e_haaletamise_yldstatistika/ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ ├── 8_e_haaletamise_detailstatistika/ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ ├── 9_e_haaletamiste_nimekiri/ │ │ │ │ │ │ └── SPEC.po │ │ │ │ │ ├── README.po │ │ │ │ │ ├── Taustateave/ │ │ │ │ │ │ └── README.po │ │ │ │ │ └── valimissündmuse_identifikaator.po │ │ │ │ ├── examples.po │ │ │ │ └── index.po │ │ │ └── spelling_wordlist.txt │ │ ├── protokollid/ │ │ │ ├── 01-annotatsioon.rst │ │ │ ├── 02-ylevaade.rst │ │ │ ├── 04-seadistus.rst │ │ │ ├── 05-ehaal.rst │ │ │ ├── 06-talletamine.rst │ │ │ ├── 06a-regteenus.rst │ │ │ ├── 07-kontrollimine.rst │ │ │ ├── 08-haaletamine.rst │ │ │ ├── 09-tootlemine.rst │ │ │ ├── 11-audit.rst │ │ │ ├── 12-lisad.rst │ │ │ ├── Makefile │ │ │ ├── index.rst │ │ │ ├── ivxv-elgamal-ecc.asn1 │ │ │ ├── ivxv-elgamal-general.asn1 │ │ │ ├── ivxv-elgamal-modp.asn1 │ │ │ ├── locales/ │ │ │ │ └── en/ │ │ │ │ └── LC_MESSAGES/ │ │ │ │ ├── 01-annotatsioon.po │ │ │ │ ├── 02-ylevaade.po │ │ │ │ ├── 04-seadistus.po │ │ │ │ ├── 05-ehaal.po │ │ │ │ ├── 06-talletamine.po │ │ │ │ ├── 06a-regteenus.po │ │ │ │ ├── 07-kontrollimine.po │ │ │ │ ├── 08-haaletamine.po │ │ │ │ ├── 09-tootlemine.po │ │ │ │ ├── 11-audit.po │ │ │ │ ├── 12-lisad.po │ │ │ │ └── index.po │ │ │ ├── model/ │ │ │ │ ├── Makefile │ │ │ │ ├── en/ │ │ │ │ │ └── lang.pu │ │ │ │ ├── et/ │ │ │ │ │ └── lang.pu │ │ │ │ └── sequence.pu │ │ │ ├── paragraph.txt │ │ │ └── spelling_wordlist.txt │ │ └── uldsisukord/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── annotatsioon.rst │ │ ├── index.rst │ │ ├── locales/ │ │ │ └── en/ │ │ │ └── LC_MESSAGES/ │ │ │ ├── annotatsioon.po │ │ │ ├── index.po │ │ │ ├── nimekiri.po │ │ │ └── tarned.po │ │ ├── spelling_wordlist.txt │ │ └── tarned.rst │ └── spelling_wordlist.txt ├── LICENSE ├── Makefile ├── README.md ├── README.rst ├── auditor/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ ├── build.gradle │ ├── settings.gradle │ └── src/ │ └── main/ │ └── java/ │ └── ee/ │ └── ivxv/ │ └── audit/ │ ├── Audit.java │ ├── AuditApp.java │ ├── AuditContext.java │ ├── Msg.java │ ├── model/ │ │ ├── PlainBallotBox.java │ │ └── Tally.java │ ├── shuffle/ │ │ ├── ByteTree.java │ │ ├── DataParser.java │ │ ├── PRNG.java │ │ ├── ProtocolInformation.java │ │ ├── RO.java │ │ ├── ShuffleConsole.java │ │ ├── ShuffleException.java │ │ ├── ShuffleParameters.java │ │ ├── ShuffleProof.java │ │ ├── ThreadedVerifier.java │ │ └── Verifier.java │ ├── tools/ │ │ ├── ConvertTool.java │ │ ├── DecryptTool.java │ │ ├── IntegrityTool.java │ │ └── MixerTool.java │ └── util/ │ ├── DiscardedBallot.java │ ├── InvalidDecProofs.java │ └── RawBallotWithDigest.java ├── choices/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ ├── cmd/ │ │ ├── choiceimp/ │ │ │ ├── log_desc.go │ │ │ └── main.go │ │ ├── districtimp/ │ │ │ ├── district_test.go │ │ │ ├── log_desc.go │ │ │ └── main.go │ │ └── voterimp/ │ │ ├── container.go │ │ ├── log_desc.go │ │ ├── main.go │ │ └── voterimp_test.go │ ├── go.mod │ ├── go.sum │ ├── internal/ │ │ └── client/ │ │ └── sessionstatus/ │ │ └── rpc/ │ │ ├── client.go │ │ └── log_desc.go │ └── service/ │ └── choices/ │ ├── log_desc.go │ └── main.go ├── collector-admin/ │ ├── Makefile │ ├── README.rst │ ├── config/ │ │ ├── ivxv-admin-ui.conf │ │ └── rsyslog.conf │ ├── ivxv-collector-admin.conf │ ├── ivxv_admin/ │ │ ├── __init__.py │ │ ├── agent_daemon.py │ │ ├── cli_utils/ │ │ │ ├── __init__.py │ │ │ ├── admin_storage_utils.py │ │ │ ├── backup_utils.py │ │ │ ├── config_utils/ │ │ │ │ ├── __init__.py │ │ │ │ ├── command_load.py │ │ │ │ ├── config_apply.py │ │ │ │ ├── config_validate.py │ │ │ │ ├── load_secret_data_file.py │ │ │ │ └── voter_list_download.py │ │ │ ├── service_utils.py │ │ │ └── status_utils.py │ │ ├── collector_state.py │ │ ├── command_file.py │ │ ├── config.py │ │ ├── config_validator/ │ │ │ ├── __init__.py │ │ │ ├── choices_list.py │ │ │ ├── districts_list.py │ │ │ ├── election_conf.py │ │ │ ├── fields.py │ │ │ ├── schemas.py │ │ │ ├── tech_conf.py │ │ │ ├── trust_conf.py │ │ │ ├── user_management.py │ │ │ ├── validator_util.py │ │ │ └── voters_list.py │ │ ├── db.py │ │ ├── event_log.py │ │ ├── http_daemon.py │ │ ├── lib/ │ │ │ ├── __init__.py │ │ │ └── lockfile.py │ │ ├── service/ │ │ │ ├── __init__.py │ │ │ ├── backup_service.py │ │ │ ├── logging.py │ │ │ ├── remote_exec.py │ │ │ └── service.py │ │ ├── templates/ │ │ │ ├── ivxv_backup_crontab.jinja │ │ │ ├── ivxv_detail_stats_crontab.jinja │ │ │ ├── ivxv_service_rsyslog_conf.jinja │ │ │ ├── ivxv_status.jinja │ │ │ ├── ivxv_voting_facts_crontab.jinja │ │ │ └── stats.json │ │ └── wsgi.py │ ├── site/ │ │ ├── cgi/ │ │ │ └── ivxv-admin.wsgi │ │ ├── index.html │ │ ├── ivxv/ │ │ │ ├── about.html │ │ │ ├── config.html │ │ │ ├── downloads.html │ │ │ ├── index.html │ │ │ ├── lists.html │ │ │ ├── log.html │ │ │ ├── services.html │ │ │ ├── stats.html │ │ │ └── users.html │ │ └── js/ │ │ ├── config.js │ │ ├── downloads.js │ │ ├── index.js │ │ ├── ivxv.js │ │ ├── lists.js │ │ ├── log.js │ │ ├── services.js │ │ ├── stats.js │ │ └── users.js │ └── sk-certs/ │ ├── EE-GovCA2018.pem.crt │ └── esteid2018.pem.crt ├── common/ │ ├── README.rst │ ├── collector/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── README.md │ │ ├── age/ │ │ │ ├── age.go │ │ │ ├── age_test.go │ │ │ └── log_desc.go │ │ ├── auth/ │ │ │ ├── auth.go │ │ │ ├── dummy/ │ │ │ │ ├── dummy.go │ │ │ │ └── dummy_test.go │ │ │ ├── log_desc.go │ │ │ ├── ticket/ │ │ │ │ ├── log_desc.go │ │ │ │ └── ticket.go │ │ │ └── tls/ │ │ │ ├── log_desc.go │ │ │ └── tls.go │ │ ├── cmd/ │ │ │ └── verifier/ │ │ │ └── main.go │ │ ├── command/ │ │ │ ├── command.go │ │ │ ├── exit/ │ │ │ │ └── exit.go │ │ │ ├── log_desc.go │ │ │ └── status/ │ │ │ ├── isatty_linux.go │ │ │ ├── isatty_other.go │ │ │ └── status.go │ │ ├── conf/ │ │ │ ├── conf.go │ │ │ ├── conf_test.go │ │ │ ├── log_desc.go │ │ │ ├── testdata/ │ │ │ │ ├── election.dummy │ │ │ │ ├── prefix.trust.dummy │ │ │ │ ├── technical.dummy │ │ │ │ └── trust.dummy │ │ │ └── version/ │ │ │ ├── log_desc.go │ │ │ └── version.go │ │ ├── config/ │ │ │ ├── Makefile │ │ │ ├── rsyslog-ivxv-templates.conf │ │ │ ├── rsyslog-logcollector.conf │ │ │ └── sudoers │ │ ├── container/ │ │ │ ├── bdoc/ │ │ │ │ ├── asice.go │ │ │ │ ├── asice_test.go │ │ │ │ ├── bdoc.go │ │ │ │ ├── bdoc_test.go │ │ │ │ ├── c14n.go │ │ │ │ ├── c14n_test.go │ │ │ │ ├── log_desc.go │ │ │ │ ├── mapstack.go │ │ │ │ ├── pool.go │ │ │ │ ├── reader.go │ │ │ │ ├── reader_test.go │ │ │ │ ├── testdata/ │ │ │ │ │ ├── canonicalSignedInfoCompact │ │ │ │ │ ├── canonicalSignedInfoEID │ │ │ │ │ ├── canonicalSignedInfoMID │ │ │ │ │ ├── confNoCheckTM.yaml │ │ │ │ │ ├── signatures0Compact.xml │ │ │ │ │ ├── signatures0EID.xml │ │ │ │ │ ├── signatures0MID.xml │ │ │ │ │ ├── testEIDBES.bdoc │ │ │ │ │ ├── testEIDTM.bdoc │ │ │ │ │ ├── testEIDTS.bdoc │ │ │ │ │ ├── testMIDTM.bdoc │ │ │ │ │ ├── testMIDTS.bdoc │ │ │ │ │ ├── testMultipleFiles.bdoc │ │ │ │ │ ├── testMultipleSigners.bdoc │ │ │ │ │ ├── testNoFiles.bdoc │ │ │ │ │ ├── testNoManifest.bdoc │ │ │ │ │ ├── testNoSignatures.bdoc │ │ │ │ │ ├── testOCSPDelayed.bdoc │ │ │ │ │ ├── testOCSPOld.bdoc │ │ │ │ │ ├── trustBES.yaml │ │ │ │ │ ├── trustTM.yaml │ │ │ │ │ └── trustTS.yaml │ │ │ │ ├── xades.go │ │ │ │ ├── xml.go │ │ │ │ └── xml_test.go │ │ │ ├── container.go │ │ │ ├── dummy/ │ │ │ │ ├── dummy.go │ │ │ │ └── dummy_test.go │ │ │ ├── log_desc.go │ │ │ └── registry.go │ │ ├── cookie/ │ │ │ ├── cookie.go │ │ │ ├── cookie_test.go │ │ │ └── log_desc.go │ │ ├── crypto/ │ │ │ └── elgamal/ │ │ │ ├── ciphertext.go │ │ │ ├── ciphertext_test.go │ │ │ ├── elgamal.go │ │ │ ├── log_desc.go │ │ │ ├── x509.go │ │ │ └── x509_test.go │ │ ├── cryptoutil/ │ │ │ ├── cryptoutil.go │ │ │ ├── cryptoutil_test.go │ │ │ ├── log_desc.go │ │ │ ├── rdn.go │ │ │ ├── rdn_test.go │ │ │ └── testdata/ │ │ │ ├── certificate-trailing-data.pem │ │ │ ├── certificate-with-header.pem │ │ │ ├── certificate-wrong-type.pem │ │ │ ├── certificate.der │ │ │ └── certificate.pem │ │ ├── errors/ │ │ │ ├── errors.go │ │ │ └── errors_test.go │ │ ├── go.mod │ │ ├── go.sum │ │ ├── identity/ │ │ │ ├── identity.go │ │ │ └── log_desc.go │ │ ├── log/ │ │ │ ├── log.go │ │ │ ├── log_test.go │ │ │ └── testdata/ │ │ │ └── certificate.der │ │ ├── mid/ │ │ │ ├── authenticate.go │ │ │ ├── certificate.go │ │ │ ├── http.go │ │ │ ├── log_desc.go │ │ │ ├── mid.go │ │ │ ├── mid_test.go │ │ │ ├── session.go │ │ │ ├── sign.go │ │ │ └── testdata/ │ │ │ ├── TEST_of_EE_Certification_Centre_Root_CA.pem │ │ │ ├── TEST_of_ESTEID-SK_2015.pem │ │ │ ├── TEST_of_SK_OCSP_RESPONDER_2020.pem │ │ │ └── signer.pem │ │ ├── ocsp/ │ │ │ ├── log_desc.go │ │ │ ├── ocsp.go │ │ │ ├── ocsp_test.go │ │ │ ├── testdata/ │ │ │ │ ├── DEMO_of_KLASS3-SK_2016_SSL_OCSP_RESPONDER_2018.pem │ │ │ │ ├── ESTEID-SK_2011.pem │ │ │ │ ├── ESTEID-SK_2015.pem │ │ │ │ ├── ID-PNOEE-39605244244.pem │ │ │ │ ├── ID-PNOEE-41602290078.pem │ │ │ │ ├── MID-PNOEE-60001018800.pem │ │ │ │ ├── TEST_of_ESTEID-SK_2015.pem │ │ │ │ ├── TEST_of_KLASS3-SK_2016.pem │ │ │ │ ├── TEST_of_SK_OCSP_RESPONDER_2020.pem │ │ │ │ ├── demo-of-klass3-sk-2016-ssl-ocsp-responder-2018.pem │ │ │ │ ├── esteid2018.pem │ │ │ │ ├── good.pem │ │ │ │ ├── revoked.pem │ │ │ │ ├── test_nonce │ │ │ │ ├── test_response │ │ │ │ ├── test_response_old │ │ │ │ └── unknown.pem │ │ │ └── types.go │ │ ├── q11n/ │ │ │ ├── log_desc.go │ │ │ ├── ocsp/ │ │ │ │ ├── log_desc.go │ │ │ │ └── ocsp.go │ │ │ ├── q11n.go │ │ │ └── tsp/ │ │ │ ├── log_desc.go │ │ │ └── tsp.go │ │ ├── safereader/ │ │ │ ├── example_test.go │ │ │ ├── log_desc.go │ │ │ ├── reader.go │ │ │ └── reader_test.go │ │ ├── scripts/ │ │ │ ├── Makefile │ │ │ ├── ivxv-admin-helper.sh │ │ │ └── ivxv-admin-sudo.sh │ │ ├── server/ │ │ │ ├── .gitignore │ │ │ ├── codec.go │ │ │ ├── codec_test.go │ │ │ ├── context.go │ │ │ ├── controller.go │ │ │ ├── errors.go │ │ │ ├── filter.go │ │ │ ├── log_desc.go │ │ │ ├── proxy.go │ │ │ ├── server.go │ │ │ ├── status.go │ │ │ ├── tlsciphersuites │ │ │ ├── util.go │ │ │ ├── util_test.go │ │ │ └── wait.go │ │ ├── smartid/ │ │ │ ├── authenticate.go │ │ │ ├── certificate.go │ │ │ ├── http.go │ │ │ ├── log_desc.go │ │ │ ├── session.go │ │ │ ├── sign.go │ │ │ ├── smartid.go │ │ │ ├── smartid_test.go │ │ │ └── testdata/ │ │ │ ├── TEST_of_EE_Certification_Centre_Root_CA.pem │ │ │ ├── TEST_of_EID-SK_2016.pem │ │ │ └── TEST_of_SK_OCSP_RESPONDER_2020.pem │ │ ├── status/ │ │ │ ├── client/ │ │ │ │ ├── client.go │ │ │ │ └── rpc/ │ │ │ │ ├── builder.go │ │ │ │ ├── builder_test.go │ │ │ │ ├── client.go │ │ │ │ ├── dto.go │ │ │ │ ├── log_desc.go │ │ │ │ ├── util.go │ │ │ │ └── util_test.go │ │ │ ├── conf.go │ │ │ └── status.go │ │ ├── storage/ │ │ │ ├── batch.go │ │ │ ├── etcd/ │ │ │ │ ├── etcd.go │ │ │ │ ├── log_desc.go │ │ │ │ ├── logger.go │ │ │ │ ├── status.go │ │ │ │ └── txn.go │ │ │ ├── file/ │ │ │ │ └── file.go │ │ │ ├── log_desc.go │ │ │ ├── memory/ │ │ │ │ └── memory.go │ │ │ ├── registry.go │ │ │ ├── status.go │ │ │ ├── storage.go │ │ │ ├── storage_dev.go │ │ │ └── txn.go │ │ ├── token/ │ │ │ ├── custom/ │ │ │ │ ├── bearer_test.go │ │ │ │ ├── empty_bearer.go │ │ │ │ ├── empty_bearer_test.go │ │ │ │ ├── empty_builder.go │ │ │ │ ├── existing_bearer.go │ │ │ │ ├── existing_builder.go │ │ │ │ ├── log_desc.go │ │ │ │ ├── raw_bearer.go │ │ │ │ ├── raw_bearer_test.go │ │ │ │ ├── raw_builder.go │ │ │ │ ├── util.go │ │ │ │ └── util_test.go │ │ │ ├── token.go │ │ │ └── webeid/ │ │ │ ├── log_desc.go │ │ │ ├── raw_builder.go │ │ │ ├── raw_webeid.go │ │ │ ├── raw_webeid_test.go │ │ │ ├── testdata/ │ │ │ │ ├── token.example.json │ │ │ │ ├── voter.auth.key │ │ │ │ └── voter.auth.pem │ │ │ ├── testdata.go │ │ │ ├── util.go │ │ │ ├── util_test.go │ │ │ └── webeid_test.go │ │ ├── tsp/ │ │ │ ├── cms.go │ │ │ ├── log_desc.go │ │ │ ├── testdata/ │ │ │ │ ├── DEMO_SK_TIMESTAMPING_AUTHORITY_2020.pem │ │ │ │ ├── demo_tsu_ecc_2023.pem.crt │ │ │ │ ├── test_response │ │ │ │ └── test_response_08-11-2023 │ │ │ ├── tsp.go │ │ │ ├── tsp_test.go │ │ │ └── types.go │ │ ├── yaml/ │ │ │ ├── ast.go │ │ │ ├── ast_test.go │ │ │ ├── doc.go │ │ │ ├── lexer.go │ │ │ ├── lexer_test.go │ │ │ ├── log_desc.go │ │ │ ├── parser.go │ │ │ ├── parser_test.go │ │ │ ├── testdata/ │ │ │ │ └── unmarshal.yaml │ │ │ ├── unmarshal.go │ │ │ └── unmarshal_test.go │ │ └── zip/ │ │ ├── testdata/ │ │ │ ├── container1.asice │ │ │ ├── container2.asice │ │ │ ├── container3_general_purpose_bit3.bdoc │ │ │ ├── mid1.bdoc │ │ │ ├── mid2.bdoc │ │ │ ├── smartid1.bdoc │ │ │ └── smartid2.bdoc │ │ ├── zip.go │ │ └── zip_test.go │ ├── external/ │ │ └── .gitignore │ ├── go/ │ │ ├── common.mk │ │ ├── golangci-lint.yaml │ │ └── govar.mk │ ├── java/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── build.gradle │ │ ├── common-build.gradle │ │ ├── common-buildscript.gradle │ │ ├── common.mk │ │ ├── javavar.mk │ │ ├── settings.gradle │ │ ├── src/ │ │ │ ├── integration-test/ │ │ │ │ └── java/ │ │ │ │ └── ee/ │ │ │ │ └── ivxv/ │ │ │ │ └── common/ │ │ │ │ ├── cli/ │ │ │ │ │ └── TestContextFactory.java │ │ │ │ └── service/ │ │ │ │ └── smartcard/ │ │ │ │ └── dummy/ │ │ │ │ ├── DummyCardService.java │ │ │ │ └── DummyPKCS15Card.java │ │ │ └── main/ │ │ │ ├── java/ │ │ │ │ └── ee/ │ │ │ │ └── ivxv/ │ │ │ │ └── common/ │ │ │ │ ├── M.java │ │ │ │ ├── asn1/ │ │ │ │ │ ├── ASN1Decodable.java │ │ │ │ │ ├── ASN1DecodingException.java │ │ │ │ │ ├── ASN1Encodable.java │ │ │ │ │ ├── Ciphertext.java │ │ │ │ │ ├── Field.java │ │ │ │ │ ├── PKCS8PrivateKey.java │ │ │ │ │ ├── RSAParams.java │ │ │ │ │ ├── Sequence.java │ │ │ │ │ └── X509PublicKey.java │ │ │ │ ├── cli/ │ │ │ │ │ ├── App.java │ │ │ │ │ ├── AppContext.java │ │ │ │ │ ├── AppHelper.java │ │ │ │ │ ├── AppRunner.java │ │ │ │ │ ├── Arg.java │ │ │ │ │ ├── Args.java │ │ │ │ │ ├── CommandLine.java │ │ │ │ │ ├── CommonArgs.java │ │ │ │ │ ├── ContextFactory.java │ │ │ │ │ ├── InitialContext.java │ │ │ │ │ ├── Msg.java │ │ │ │ │ ├── Option.java │ │ │ │ │ ├── ParseException.java │ │ │ │ │ ├── Tool.java │ │ │ │ │ ├── ValidationResult.java │ │ │ │ │ ├── VerifyTool.java │ │ │ │ │ ├── YamlData.java │ │ │ │ │ └── YamlDataExtension.java │ │ │ │ ├── conf/ │ │ │ │ │ ├── Conf.java │ │ │ │ │ ├── ConfBuilder.java │ │ │ │ │ ├── ConfLoader.java │ │ │ │ │ ├── ConfVerifier.java │ │ │ │ │ ├── LocaleConf.java │ │ │ │ │ ├── LocaleConfLoader.java │ │ │ │ │ └── Msg.java │ │ │ │ ├── crypto/ │ │ │ │ │ ├── CorrectnessUtil.java │ │ │ │ │ ├── CryptoUtil.java │ │ │ │ │ ├── Plaintext.java │ │ │ │ │ ├── SignatureUtil.java │ │ │ │ │ ├── elgamal/ │ │ │ │ │ │ ├── ElGamalCiphertext.java │ │ │ │ │ │ ├── ElGamalDecryptionProof.java │ │ │ │ │ │ ├── ElGamalParameters.java │ │ │ │ │ │ ├── ElGamalPrivateKey.java │ │ │ │ │ │ └── ElGamalPublicKey.java │ │ │ │ │ ├── hash/ │ │ │ │ │ │ ├── HashFunction.java │ │ │ │ │ │ ├── HashType.java │ │ │ │ │ │ └── Sha256.java │ │ │ │ │ └── rnd/ │ │ │ │ │ ├── CombineRnd.java │ │ │ │ │ ├── DPRNG.java │ │ │ │ │ ├── FileRnd.java │ │ │ │ │ ├── NativeRnd.java │ │ │ │ │ ├── Rnd.java │ │ │ │ │ └── UserRnd.java │ │ │ │ ├── math/ │ │ │ │ │ ├── ECGroup.java │ │ │ │ │ ├── ECGroupElement.java │ │ │ │ │ ├── Group.java │ │ │ │ │ ├── GroupElement.java │ │ │ │ │ ├── IntegerConstructor.java │ │ │ │ │ ├── LagrangeInterpolation.java │ │ │ │ │ ├── MathException.java │ │ │ │ │ ├── MathUtil.java │ │ │ │ │ ├── ModPGroup.java │ │ │ │ │ ├── ModPGroupElement.java │ │ │ │ │ ├── Polynomial.java │ │ │ │ │ ├── ProductGroup.java │ │ │ │ │ └── ProductGroupElement.java │ │ │ │ ├── model/ │ │ │ │ │ ├── AnonymousBallotBox.java │ │ │ │ │ ├── Ballot.java │ │ │ │ │ ├── BallotBox.java │ │ │ │ │ ├── CandidateList.java │ │ │ │ │ ├── District.java │ │ │ │ │ ├── DistrictList.java │ │ │ │ │ ├── IBallotBox.java │ │ │ │ │ ├── LName.java │ │ │ │ │ ├── Proof.java │ │ │ │ │ ├── Region.java │ │ │ │ │ ├── RevocationList.java │ │ │ │ │ ├── SkipCommand.java │ │ │ │ │ ├── Voter.java │ │ │ │ │ ├── VoterBallots.java │ │ │ │ │ └── VoterList.java │ │ │ │ ├── service/ │ │ │ │ │ ├── bbox/ │ │ │ │ │ │ ├── BboxHelper.java │ │ │ │ │ │ ├── InvalidBboxException.java │ │ │ │ │ │ ├── Ref.java │ │ │ │ │ │ ├── Result.java │ │ │ │ │ │ └── impl/ │ │ │ │ │ │ ├── AbstractStage.java │ │ │ │ │ │ ├── BboxHelperImpl.java │ │ │ │ │ │ ├── FileName.java │ │ │ │ │ │ ├── FileSource.java │ │ │ │ │ │ ├── IvxvBboxLoader.java │ │ │ │ │ │ ├── IvxvRegDataLoader.java │ │ │ │ │ │ ├── LoaderHelper.java │ │ │ │ │ │ ├── Profile.java │ │ │ │ │ │ ├── Record.java │ │ │ │ │ │ ├── ResultException.java │ │ │ │ │ │ ├── TspProfile.java │ │ │ │ │ │ ├── ZipSource.java │ │ │ │ │ │ ├── ZipSourceRaw.java │ │ │ │ │ │ └── verify/ │ │ │ │ │ │ ├── TsSignature.java │ │ │ │ │ │ └── TsVerifier.java │ │ │ │ │ ├── console/ │ │ │ │ │ │ ├── BlockingQueueConsole.java │ │ │ │ │ │ ├── Console.java │ │ │ │ │ │ ├── InfiniteProgressImpl.java │ │ │ │ │ │ ├── Progress.java │ │ │ │ │ │ ├── ProgressImpl.java │ │ │ │ │ │ └── TextFormatter.java │ │ │ │ │ ├── container/ │ │ │ │ │ │ ├── Container.java │ │ │ │ │ │ ├── ContainerReader.java │ │ │ │ │ │ ├── DataFile.java │ │ │ │ │ │ ├── InvalidContainerException.java │ │ │ │ │ │ ├── Signature.java │ │ │ │ │ │ ├── Subject.java │ │ │ │ │ │ └── bdoc/ │ │ │ │ │ │ ├── BdocContainerReader.java │ │ │ │ │ │ └── DataConverter.java │ │ │ │ │ ├── i18n/ │ │ │ │ │ │ ├── Cal10nI18nImpl.java │ │ │ │ │ │ ├── DefaultI18n.java │ │ │ │ │ │ ├── I18n.java │ │ │ │ │ │ ├── Message.java │ │ │ │ │ │ ├── MessageException.java │ │ │ │ │ │ └── Translatable.java │ │ │ │ │ ├── report/ │ │ │ │ │ │ ├── CsvReporterImpl.java │ │ │ │ │ │ ├── DefaultReporter.java │ │ │ │ │ │ └── Reporter.java │ │ │ │ │ └── smartcard/ │ │ │ │ │ ├── Apdu.java │ │ │ │ │ ├── Card.java │ │ │ │ │ ├── CardInfo.java │ │ │ │ │ ├── CardService.java │ │ │ │ │ ├── Cards.java │ │ │ │ │ ├── IndexedBlob.java │ │ │ │ │ ├── Msg.java │ │ │ │ │ ├── SmartCardException.java │ │ │ │ │ ├── TerminalUtil.java │ │ │ │ │ └── pkcs15/ │ │ │ │ │ ├── PKCS15Card.java │ │ │ │ │ ├── PKCS15CardService.java │ │ │ │ │ ├── PKCS15Exception.java │ │ │ │ │ └── PKCS15IndexedBlob.java │ │ │ │ ├── util/ │ │ │ │ │ ├── ByteArrayWrapper.java │ │ │ │ │ ├── CandidatesUtil.java │ │ │ │ │ ├── ContainerHelper.java │ │ │ │ │ ├── DistrictsUtil.java │ │ │ │ │ ├── I18nConsole.java │ │ │ │ │ ├── Json.java │ │ │ │ │ ├── NameHolder.java │ │ │ │ │ ├── PdfDoc.java │ │ │ │ │ ├── SkipCommandUtil.java │ │ │ │ │ ├── ToolHelper.java │ │ │ │ │ ├── Util.java │ │ │ │ │ └── log/ │ │ │ │ │ ├── LogJsonFormatter.java │ │ │ │ │ └── PerformanceLog.java │ │ │ │ └── zip/ │ │ │ │ ├── Zip.java │ │ │ │ └── ZipFileCommentException.java │ │ │ └── resources/ │ │ │ ├── bootstrap-i18n/ │ │ │ │ └── common-conf-localeconfloader-msg_et.properties │ │ │ ├── log4j.properties │ │ │ └── logback.xml │ │ └── translations/ │ │ ├── i18n/ │ │ │ ├── audit-msg_et.properties │ │ │ ├── common-cli-msg_et.properties │ │ │ ├── common-conf-msg_et.properties │ │ │ ├── common-model-bb-type_et.properties │ │ │ ├── common-msg_et.properties │ │ │ ├── common-smartcard-msg_et.properties │ │ │ ├── key-msg_et.properties │ │ │ └── processor-msg_et.properties │ │ └── lang.properties │ └── tools/ │ ├── go/ │ │ ├── .gitignore │ │ ├── Makefile │ │ ├── cmd/ │ │ │ └── gen/ │ │ │ ├── .gitignore │ │ │ ├── description.go │ │ │ ├── gen.tmpl │ │ │ ├── gen_test.go │ │ │ ├── generate.go │ │ │ ├── gentmpl.sh │ │ │ ├── main.go │ │ │ ├── resolve.go │ │ │ ├── testdata/ │ │ │ │ ├── declared/ │ │ │ │ │ └── declared.go │ │ │ │ ├── duplicate/ │ │ │ │ │ └── duplicate.go │ │ │ │ ├── empty/ │ │ │ │ │ └── empty.go │ │ │ │ ├── local/ │ │ │ │ │ └── local.go │ │ │ │ ├── nodescription/ │ │ │ │ │ └── nodescription.go │ │ │ │ ├── nodescriptionempty/ │ │ │ │ │ └── nodescriptionempty.go │ │ │ │ ├── nokeys/ │ │ │ │ │ └── nokeys.go │ │ │ │ ├── single/ │ │ │ │ │ └── single.go │ │ │ │ ├── unexportedkeys/ │ │ │ │ │ └── unexportedkeys.go │ │ │ │ └── withtests/ │ │ │ │ ├── withtests.go │ │ │ │ └── withtests_test.go │ │ │ └── walk.go │ │ └── go.mod │ ├── pylintrc │ ├── update_project_version.py │ └── win32/ │ └── entropy/ │ ├── Aggregator.cpp │ ├── Aggregator.h │ ├── Counter.cpp │ ├── Counter.h │ ├── CounterManager.cpp │ ├── CounterManager.h │ ├── Error.cpp │ ├── Error.h │ ├── Makefile │ ├── Network.cpp │ ├── Protocol.cpp │ ├── Protocol.h │ ├── Slotter.cpp │ ├── Slotter.h │ ├── astylerc │ ├── client.c │ ├── resources.rc │ └── server.cpp ├── core/ │ ├── .editorconfig │ ├── .gitignore │ ├── .golangci.yml │ ├── Makefile │ ├── README.md │ ├── cmd/ │ │ ├── cms/ │ │ │ └── main.go │ │ ├── errorgen/ │ │ │ ├── .gitignore │ │ │ ├── Makefile │ │ │ ├── gen.tmpl │ │ │ ├── gen_test.go │ │ │ ├── generate.go │ │ │ ├── gentmpl.sh │ │ │ ├── main.go │ │ │ ├── resolve.go │ │ │ ├── testdata/ │ │ │ │ ├── declared/ │ │ │ │ │ └── declared.go │ │ │ │ ├── duplicate/ │ │ │ │ │ └── duplicate.go │ │ │ │ ├── empty/ │ │ │ │ │ └── empty.go │ │ │ │ ├── exists/ │ │ │ │ │ └── exists.go │ │ │ │ ├── local/ │ │ │ │ │ └── local.go │ │ │ │ ├── nokeys/ │ │ │ │ │ └── nokeys.go │ │ │ │ ├── single/ │ │ │ │ │ └── single.go │ │ │ │ ├── unexportedkeys/ │ │ │ │ │ └── unexportedkeys.go │ │ │ │ └── withtests/ │ │ │ │ ├── withtests.go │ │ │ │ └── withtests_test.go │ │ │ └── walk.go │ │ └── ts/ │ │ └── main.go │ ├── common/ │ │ ├── files/ │ │ │ └── files.go │ │ └── tar/ │ │ ├── tar.go │ │ └── tar_test.go │ ├── crypto/ │ │ ├── asn1/ │ │ │ └── asn1.go │ │ ├── cades/ │ │ │ ├── cades-b.go │ │ │ ├── cades-t.go │ │ │ ├── cades_test.go │ │ │ └── testdata/ │ │ │ ├── demo-ca-cert.pem │ │ │ ├── demo-user-cert.pem │ │ │ ├── plain-signed-attr.cms │ │ │ └── plain-unsigned.txt │ │ ├── cms/ │ │ │ ├── cms.go │ │ │ ├── cms_test.go │ │ │ ├── conf.go │ │ │ └── testdata/ │ │ │ ├── nottrusted.pem │ │ │ ├── test1.txt │ │ │ ├── test1.txt.pk7 │ │ │ ├── test2.txt.pk7 │ │ │ └── trusted.pem │ │ ├── crypto.go │ │ ├── ecdsa/ │ │ │ ├── ecdsa.go │ │ │ └── ecdsa_test.go │ │ ├── elgamal/ │ │ │ ├── ciphertext.go │ │ │ ├── decryption.go │ │ │ ├── distributed/ │ │ │ │ ├── distributed.go │ │ │ │ ├── distributed_test.go │ │ │ │ ├── parameters.go │ │ │ │ └── x509/ │ │ │ │ ├── pkcs8.go │ │ │ │ └── x509.go │ │ │ ├── elgamal.go │ │ │ ├── elgamal_test.go │ │ │ ├── homomorphic/ │ │ │ │ ├── homomorphic.go │ │ │ │ └── homomorphic_test.go │ │ │ ├── internal/ │ │ │ │ └── x509/ │ │ │ │ └── x509.go │ │ │ ├── nizkp/ │ │ │ │ ├── ciphertext/ │ │ │ │ │ └── ciphertext.go │ │ │ │ ├── key/ │ │ │ │ │ └── key.go │ │ │ │ └── nizkp.go │ │ │ ├── parameters.go │ │ │ ├── proof.go │ │ │ ├── shamir/ │ │ │ │ └── doc.go │ │ │ └── x509/ │ │ │ ├── pkcs8.go │ │ │ └── x509.go │ │ ├── ocsp/ │ │ │ ├── conf.go │ │ │ ├── ocsp.go │ │ │ ├── ocsp_test.go │ │ │ └── testdata/ │ │ │ ├── TESTCERT_GOOD_12345678901-sign.pem │ │ │ ├── TESTCERT_REVOKED_12345678902-sign.pem │ │ │ ├── TESTCERT_UNKNOWN_12345678903-sign.pem │ │ │ ├── TEST_of_SK_OCSP_RESPONDER_2020.pem │ │ │ ├── intermediate.pem │ │ │ ├── response-good.der │ │ │ ├── response-revoked.der │ │ │ └── response-unknown.der │ │ ├── timestamp/ │ │ │ ├── conf.go │ │ │ ├── testdata/ │ │ │ │ ├── DEMO_SK_TIMESTAMPING_AUTHORITY_2020.pem │ │ │ │ ├── response_1_test │ │ │ │ ├── response_2_test │ │ │ │ ├── response_3_test │ │ │ │ ├── response_4_test │ │ │ │ ├── response_5_test │ │ │ │ ├── test_file_1 │ │ │ │ ├── test_file_2 │ │ │ │ ├── test_file_3 │ │ │ │ ├── test_file_4 │ │ │ │ └── test_file_5 │ │ │ ├── timestamp.go │ │ │ └── timestamp_test.go │ │ ├── util/ │ │ │ └── util.go │ │ └── x509/ │ │ ├── encrypted_pkcs8.go │ │ ├── internal/ │ │ │ ├── internal.go │ │ │ ├── pem.go │ │ │ └── pki.go │ │ ├── marshal/ │ │ │ └── marshal.go │ │ ├── pkcs8.go │ │ ├── x509.go │ │ └── x509_test.go │ ├── encoding/ │ │ └── asn1/ │ │ └── asn1.go │ ├── go.mod │ ├── go.sum │ ├── govar.mk │ ├── math/ │ │ ├── group/ │ │ │ ├── all/ │ │ │ │ └── all.go │ │ │ ├── ecqp/ │ │ │ │ ├── ecqp.go │ │ │ │ ├── element.go │ │ │ │ ├── element_test.go │ │ │ │ ├── group.go │ │ │ │ ├── group_encode_p384_7_test.go │ │ │ │ ├── group_pad_byte_p384_7_test.go │ │ │ │ ├── group_test.go │ │ │ │ └── wellknown.go │ │ │ ├── edwards25519/ │ │ │ │ └── edwards25519.go │ │ │ ├── group.go │ │ │ ├── group_test.go │ │ │ ├── internal/ │ │ │ │ ├── errors.go │ │ │ │ └── internal.go │ │ │ ├── modqp/ │ │ │ │ ├── element.go │ │ │ │ ├── group.go │ │ │ │ ├── group_test.go │ │ │ │ ├── modqp.go │ │ │ │ └── wellknown.go │ │ │ ├── padding.go │ │ │ ├── registry.go │ │ │ ├── scalar.go │ │ │ └── scalar_test.go │ │ ├── math.go │ │ ├── math_test.go │ │ └── polynomial/ │ │ ├── polynomial.go │ │ └── polynomial_test.go │ ├── test/ │ │ └── fixtures/ │ │ └── fixtures.go │ ├── version.go │ └── voterlist/ │ ├── persistence/ │ │ ├── bitcask.go │ │ ├── bolt.go │ │ └── factory.go │ └── voterlist.go ├── debian/ │ ├── .gitignore │ ├── changelog │ ├── control │ ├── copyright │ ├── ivxv-admin.cron.d │ ├── ivxv-admin.install │ ├── ivxv-admin.ivxv-admin-agent.service │ ├── ivxv-admin.lintian-overrides │ ├── ivxv-admin.postinst │ ├── ivxv-admin.postrm │ ├── ivxv-admin.service │ ├── ivxv-backup.install │ ├── ivxv-backup.lintian-overrides │ ├── ivxv-backup.postinst │ ├── ivxv-backup.postrm │ ├── ivxv-choices.install │ ├── ivxv-choices.lintian-overrides │ ├── ivxv-choices.postinst │ ├── ivxv-choices.postrm │ ├── ivxv-common.install │ ├── ivxv-common.lintian-overrides │ ├── ivxv-common.postinst │ ├── ivxv-common.postrm │ ├── ivxv-log.install │ ├── ivxv-log.postinst │ ├── ivxv-log.postrm │ ├── ivxv-mid.install │ ├── ivxv-mid.lintian-overrides │ ├── ivxv-mid.postinst │ ├── ivxv-mid.postrm │ ├── ivxv-proxy.install │ ├── ivxv-proxy.lintian-overrides │ ├── ivxv-proxy.postinst │ ├── ivxv-proxy.postrm │ ├── ivxv-sessionstatus.install │ ├── ivxv-sessionstatus.lintian-overrides │ ├── ivxv-sessionstatus.postinst │ ├── ivxv-sessionstatus.postrm │ ├── ivxv-smartid.install │ ├── ivxv-smartid.lintian-overrides │ ├── ivxv-smartid.postinst │ ├── ivxv-smartid.postrm │ ├── ivxv-storage.install │ ├── ivxv-storage.lintian-overrides │ ├── ivxv-storage.postinst │ ├── ivxv-storage.postrm │ ├── ivxv-verification.install │ ├── ivxv-verification.lintian-overrides │ ├── ivxv-verification.postinst │ ├── ivxv-verification.postrm │ ├── ivxv-votesorder.install │ ├── ivxv-votesorder.lintian-overrides │ ├── ivxv-votesorder.postinst │ ├── ivxv-votesorder.postrm │ ├── ivxv-voting.install │ ├── ivxv-voting.lintian-overrides │ ├── ivxv-voting.postinst │ ├── ivxv-voting.postrm │ ├── ivxv-webeid.install │ ├── ivxv-webeid.lintian-overrides │ ├── ivxv-webeid.postinst │ ├── ivxv-webeid.postrm │ ├── python3-ivxv-common.install │ ├── python3-ivxv-common.postinst │ ├── python3-ivxv-common.prerm │ └── rules ├── key/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ ├── build.gradle │ ├── settings.gradle │ ├── src/ │ │ └── main/ │ │ └── java/ │ │ └── ee/ │ │ └── ivxv/ │ │ └── key/ │ │ ├── Key.java │ │ ├── KeyApp.java │ │ ├── KeyContext.java │ │ ├── Msg.java │ │ ├── RandomSourceArg.java │ │ ├── model/ │ │ │ ├── Invalid.java │ │ │ ├── PlainBallotBox.java │ │ │ ├── Tally.java │ │ │ └── Vote.java │ │ ├── protocol/ │ │ │ ├── DecryptionProtocol.java │ │ │ ├── GenerationProtocol.java │ │ │ ├── ProtocolException.java │ │ │ ├── ProtocolUtil.java │ │ │ ├── SigningProtocol.java │ │ │ ├── ThresholdParameters.java │ │ │ ├── decryption/ │ │ │ │ ├── desmedt/ │ │ │ │ │ └── DesmedtDecryption.java │ │ │ │ └── recover/ │ │ │ │ └── RecoverDecryption.java │ │ │ ├── generation/ │ │ │ │ ├── desmedt/ │ │ │ │ │ └── DesmedtGeneration.java │ │ │ │ ├── pedersen/ │ │ │ │ │ └── NOTIMPLEMENTED │ │ │ │ └── shoup/ │ │ │ │ └── ShoupGeneration.java │ │ │ └── signing/ │ │ │ └── shoup/ │ │ │ └── ShoupSigning.java │ │ ├── tool/ │ │ │ ├── DecryptTool.java │ │ │ ├── GroupGenTool.java │ │ │ ├── InitTool.java │ │ │ ├── TestKeyTool.java │ │ │ └── UtilTool.java │ │ └── util/ │ │ ├── ElectionResult.java │ │ └── QuorumUtil.java │ └── tools/ │ └── pkcs15_initialization/ │ ├── README.rst │ ├── card_options.conf │ ├── erase_and_install.sh │ └── erase_pkcs15.sh ├── mid/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ ├── go.mod │ ├── go.sum │ ├── internal/ │ │ └── sessionstatus/ │ │ └── rpc/ │ │ ├── client.go │ │ └── log_desc.go │ └── service/ │ └── mid/ │ ├── log_desc.go │ └── main.go ├── processor/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ ├── build.gradle │ ├── settings.gradle │ └── src/ │ └── main/ │ └── java/ │ └── ee/ │ └── ivxv/ │ └── processor/ │ ├── Msg.java │ ├── Processor.java │ ├── ProcessorApp.java │ ├── ProcessorContext.java │ ├── tool/ │ │ ├── AnonymizeTool.java │ │ ├── CheckAndSquashTool.java │ │ ├── CheckTool.java │ │ ├── ExportTool.java │ │ ├── RevokeAndAnonymizeTool.java │ │ ├── RevokeTool.java │ │ ├── SquashTool.java │ │ ├── StatsDiffTool.java │ │ └── StatsTool.java │ └── util/ │ ├── DistrictsMapper.java │ ├── ReportHelper.java │ ├── Statistics.java │ └── VotersUtil.java ├── proxy/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ ├── go.mod │ └── service/ │ └── proxy/ │ ├── haproxy-rsyslog.conf │ ├── haproxy.cfg.tmpl │ ├── haproxy.go │ ├── log_desc.go │ └── main.go ├── scripts/ │ └── goimports.sh ├── sessionstatus/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ ├── api/ │ │ ├── Makefile │ │ ├── README.rst │ │ ├── go.mod │ │ ├── go.sum │ │ └── rpc/ │ │ ├── builder.go │ │ ├── builder_test.go │ │ ├── client.go │ │ ├── dto.go │ │ ├── endpoints.go │ │ ├── log_desc.go │ │ ├── rpc.go │ │ ├── util.go │ │ └── util_test.go │ ├── go.mod │ ├── go.sum │ ├── internal/ │ │ └── rpc/ │ │ ├── log_desc.go │ │ ├── repository.go │ │ ├── server.go │ │ ├── util.go │ │ └── util_test.go │ └── service/ │ └── sessionstatus/ │ ├── log_desc.go │ └── main.go ├── setup.cfg ├── setup.py ├── smartid/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ ├── go.mod │ ├── go.sum │ ├── internal/ │ │ └── sessionstatus/ │ │ └── rpc/ │ │ ├── client.go │ │ └── log_desc.go │ └── service/ │ └── smartid/ │ ├── log_desc.go │ └── main.go ├── storage/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ ├── cmd/ │ │ ├── storageidx/ │ │ │ ├── log_desc.go │ │ │ └── main.go │ │ └── storageorder/ │ │ ├── log_desc.go │ │ └── main.go │ ├── go.mod │ ├── go.sum │ └── service/ │ └── storage/ │ ├── cluster.go │ ├── log_desc.go │ ├── logger.go │ └── main.go ├── systemd/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ └── ivxv-$service@.service.in ├── verification/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ ├── go.mod │ ├── go.sum │ ├── internal/ │ │ └── sessionstatus/ │ │ └── rpc/ │ │ ├── client.go │ │ └── log_desc.go │ └── service/ │ └── verification/ │ ├── log_desc.go │ └── main.go ├── votesorder/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ ├── go.mod │ ├── go.sum │ └── service/ │ └── votesorder/ │ ├── log_desc.go │ └── main.go ├── voting/ │ ├── .gitignore │ ├── Makefile │ ├── README.rst │ ├── cmd/ │ │ ├── voteexp/ │ │ │ ├── log_desc.go │ │ │ └── main.go │ │ ├── voterstats/ │ │ │ ├── log_desc.go │ │ │ ├── main.go │ │ │ ├── period.go │ │ │ └── period_test.go │ │ └── voteunion/ │ │ ├── main.go │ │ └── union_test.go │ ├── go.mod │ ├── go.sum │ ├── internal/ │ │ ├── ciphertext.go │ │ └── sessionstatus/ │ │ └── rpc/ │ │ ├── client.go │ │ └── log_desc.go │ └── service/ │ └── voting/ │ ├── log_desc.go │ ├── main.go │ ├── testdata/ │ │ ├── eligible.pem │ │ └── ineligible.pem │ └── voting_test.go ├── webeid/ │ ├── .gitignore │ ├── Makefile │ ├── go.mod │ ├── go.sum │ ├── internal/ │ │ └── sessionstatus/ │ │ └── rpc/ │ │ ├── client.go │ │ └── log_desc.go │ └── service/ │ └── webeid/ │ ├── handler.go │ ├── log_desc.go │ ├── main.go │ └── util.go └── xroad-service/ ├── .gitignore ├── .goreleaser.yml ├── Makefile ├── README.rst ├── cmd/ │ └── main.go ├── go.mod ├── go.sum ├── init/ │ └── systemd/ │ └── xroad-service.service ├── openapi/ │ └── ehs-xroad-api.yaml ├── pkg/ │ ├── conf/ │ │ └── conf.go │ ├── configs/ │ │ └── xroad-service.json │ ├── errors/ │ │ ├── errors.go │ │ └── errors_test.go │ ├── server/ │ │ └── handler.go │ └── service/ │ └── service.go └── scripts/ ├── postinstall.sh ├── postremove.sh └── preremove.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .editorconfig ================================================ # http://editorconfig.org root = true [*] trim_trailing_whitespace = true insert_final_newline = true charset = utf-8 end_of_line = lf [*.{conf,html,ini,jinja,sql,py}] indent_style = space indent_size = 4 [*.{json,schema,schema.example}] indent_style = space indent_size = 4 insert_final_newline = false [*.{css,feature,js,pu,sh,yaml,yml}] indent_style = space indent_size = 2 [*.{inc,rst}] indent_style = space indent_size = 3 [Makefile] indent_style = tab [*.mk] indent_style = tab [debian/*{preinst,postinst,prerm,postrm}] indent_style = space indent_size = 4 [debian/changelog] indent_style = space indent_size = 2 ================================================ FILE: .gitignore ================================================ *.swp *.pyc gen_types.go gen_types_test.go gen_import.go gen_import_dev.go __pycache__ .idea # ivxv-admin /build /dist /.pybuild /collector-admin/IVXVCollectorAdminDaemon.egg-info ================================================ FILE: .gitmodules ================================================ [submodule "Documentation/public/liidesed/VIS3-EHS"] path = Documentation/public/liidesed/VIS3-EHS url = https://github.com/e-gov/VIS3-EHS.git branch = feature/tervikdokument ================================================ FILE: Documentation/.gitignore ================================================ _build _master *.mo ================================================ FILE: Documentation/Makefile ================================================ # This Makefile supports two different invocation "modes". # # The default mode, invoked via "all", "pdf", or "html", builds all of the # documentation with a few exceptions, putting PDF files into $(DESTDIR)/pdf # (_build/pdf by default) and HTML files into $(DESTDIR)/html (_build/html by # default, "all" builds html only in development mode). # # Release mode, invoked via "release", builds only the release documents and # puts the PDF files, examples, and PDF diffs into a release hierarchy created # at $(DESTDIR) (_build/release by default). # Can be overridden from the command line. DESTDIR = _build # Build all Estonian and English documentation with a few exceptions. DOCS := $(wildcard internal/* public/* et/*) DOCS := $(filter-out et/example-config,$(DOCS)) # Does not contain reST. DOCS := $(filter-out internal/formal,$(DOCS)) # Does not contain reST. DOCS := $(filter-out internal/ivxv-pyapi,$(DOCS)) # Too many Python dependencies. DOCS := $(filter-out internal/entroopia,$(DOCS)) # Does not have a Makefile? DOCS := $(filter-out internal/stresstesting,$(DOCS)) # Does not have a Makefile? PDFDOCS := $(DOCS:%=pdf-%) DIFFDOCS := $(DOCS:%=diff-%) HTMLDOCS := $(DOCS:%=html-%) .PHONY: all all: release .PHONY: pdf pdf: $(PDFDOCS) $(MAKE) -C public/arhitektuur install-en-pdf DESTDIR=$(abspath $(DESTDIR)/pdf) $(MAKE) -C public/liidesed install-en-pdf DESTDIR=$(abspath $(DESTDIR)/pdf) $(MAKE) -C public/protokollid install-en-pdf DESTDIR=$(abspath $(DESTDIR)/pdf) .PHONY: $(PDFDOCS) $(PDFDOCS): pdf-%: mkdir -p $(DESTDIR)/pdf $(MAKE) -C $* install-pdf DESTDIR=$(abspath $(DESTDIR)/pdf) .PHONY: diff diff: $(DIFFDOCS) .PHONY: $(DIFFDOCS) $(DIFFDOCS): diff-%: mkdir -p $(DESTDIR)/diff $(MAKE) -C $* install-diff DESTDIR=$(abspath $(DESTDIR)/diff) .PHONY: html html: $(HTMLDOCS) .PHONY: $(HTMLDOCS) $(HTMLDOCS): html-%: mkdir -p $(DESTDIR)/html/$(notdir $*) # Drop language prefix. $(MAKE) -C $* install-html DESTDIR=$(abspath $(DESTDIR)/html/$(notdir $*)) # Rules for generating release documentation. RELEASE1 = "$(abspath $(DESTDIR))/1. Ülddokumendid" DOCS1ET := public/uldsisukord RELEASE2 = "$(abspath $(DESTDIR))/2. Spetsifikatsioonid" DOCS2ET := \ public/arhitektuur \ public/liidesed \ et/kasutusmall \ public/protokollid \ et/xteeteenus \ et/votmerakendus DOCS2EN := \ public/arhitektuur \ public/liidesed \ public/protokollid \ en/backendlogs RELEASE3 = "$(abspath $(DESTDIR))/3. Juhendid" DOCS3ET := \ et/haldusteenus \ et/kogumisteenuse_haldusjuhend \ et/seadistuste_koostejuhend \ et/audiitor RELEASE4 = "$(abspath $(DESTDIR))/4. Näited" DOCS4ET := \ et/example-config \ et/seadistuste_koostejuhend/config-examples/android-ios-config.json RELEASE5 = "$(abspath $(DESTDIR))/5. Muudatused" RELEASEDOCSET := $(patsubst %,release-et-%,$(DOCS1ET) $(DOCS2ET) $(DOCS3ET) $(DOCS4ET)) RELEASEDOCSEN := $(patsubst %,release-en-%,$(DOCS1EN) $(DOCS2EN)) # If releasing locally (i.e., no explicit DESTDIR is given), then use # _build/release. RELEASE[1-5] must be recursively expanded for this to work. $(RELEASEDOCSET): DESTDIR := $(DESTDIR)/release $(RELEASEDOCSEN): DESTDIR := $(DESTDIR)/release .PHONY: release release: $(RELEASEDOCSET) $(RELEASEDOCSEN) .PHONY: $(RELEASEDOCSET) $(DOCS1ET:%=release-et-%): release-et-%: mkdir -p $(RELEASE1) $(MAKE) -C $* install-pdf DESTDIR=$(RELEASE1) mkdir -p $(RELEASE5) $(MAKE) -C $* install-diff DESTDIR=$(RELEASE5) $(DOCS2ET:%=release-et-%): release-et-%: mkdir -p $(RELEASE2) $(MAKE) -C $* install-pdf DESTDIR=$(RELEASE2) mkdir -p $(RELEASE5) $(MAKE) -C $* install-diff DESTDIR=$(RELEASE5) $(DOCS3ET:%=release-et-%): release-et-%: mkdir -p $(RELEASE3) $(MAKE) -C $* install-pdf DESTDIR=$(RELEASE3) mkdir -p $(RELEASE5) $(MAKE) -C $* install-diff DESTDIR=$(RELEASE5) $(DOCS4ET:%=release-et-%): release-et-%: mkdir -p $(RELEASE4) cp --recursive --update $* $(RELEASE4) .PHONY: $(RELEASEDOCSEN) $(DOCS2EN:%=release-en-%): release-en-%: mkdir -p $(RELEASE2) $(MAKE) -C $* install-en-pdf DESTDIR=$(RELEASE2) # Cleanup. # DOCS already contains DOCS[1-3]. CLEANDOCS := $(DOCS:%=clean-%) .PHONY: clean clean: $(CLEANDOCS) -git worktree remove --force _master rm -rf $(DESTDIR) _master py3clean . .PHONY: $(CLEANDOCS) $(CLEANDOCS): clean-%: $(MAKE) -C $* clean ================================================ FILE: Documentation/_static/custom.css ================================================ /* * IVXV Internet voting framework * * Sphinx stylesheet for HTML documentation */ .figure { background-color: rgba(128, 128, 128, 0.1); border: thin dotted gray; } .caption { border-bottom: thin solid gray; } /* Highlight target section */ .section:target { background-color: rgba(220, 220, 255, 0.2); box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2); padding: 10px 5px 5px 5px; } /* * vim:foldmethod=syntax: */ ================================================ FILE: Documentation/common/examples/id.rpc.vote.query.json ================================================ { "id": 0.0, "method": "RPC.Vote", "params": [ { "AuthMethod": "tls", "Choices": "0140.1", "SessionID": "ec3a0cab353d552952289f2c7ad52e27", "OS": "Operating System,2,0", "Type": "bdoc", "Vote": "UEsDBAoABgAAAAIAAAAbWltZXR5cGVhcHBsaWNhdGlv\nbi92bmQuZX..." } ] } ================================================ FILE: Documentation/common/examples/id.rpc.vote.response.json ================================================ { "error": null, "id": 0.0, "result": { "Qualification": { "ocsp": "MIIFTAoBAKCCBUUwggVBBgkrBgEFBQcwAQEEggUyMIIFLjCB5qFMME...", "tspreg": "MIIDsAYJKoZIhvcNAQcCoIIDoTCCA50CAQMxCzAJBgUrDgMCGgQS..." }, "SessionID": "ec3a0cab353d552952289f2c7ad52e27", "TestVote": true, "VoteID": "VM/cUIU4n7VjxpUx1fC00Q==" } } ================================================ FILE: Documentation/common/examples/id.rpc.voterchoices.query.json ================================================ { "id": 0.0, "method": "RPC.VoterChoices", "params": [ { "AuthMethod": "tls", "OS": "Operating System,2,0" } ] } ================================================ FILE: Documentation/common/examples/id.rpc.voterchoices.response.json ================================================ { "error": null, "id": 0.0, "result": { "Choices": "0140.1", "List": "ew0KICAgICAgICAgICAgIkVyYWtvbmQgMSI6IHsNCiAgICAgICAgICAgIC...", "SessionID": "ec3a0cab353d552952289f2c7ad52e27", "Voted": true } } ================================================ FILE: Documentation/common/examples/json.rpc.method.query.json ================================================ { "id": 0.0, "method": "RPC.Method", "params": [ { "MethodParam": "value", "SessionID": "ec3a0cab353d552952289f2c7ad52e27" } ] } ================================================ FILE: Documentation/common/examples/json.rpc.method.response.json ================================================ { "error": null, "id": 0.0, "result": { "ResultParam": "value", "SessionID": "ec3a0cab353d552952289f2c7ad52e27" } } ================================================ FILE: Documentation/common/examples/mid.rpc.authenticate.query.json ================================================ { "id": 0.0, "method": "RPC.Authenticate", "params": [ { "OS": "Operating System,2,0", "IDCode": "60001019906", "PhoneNo": "+37200000766" } ] } ================================================ FILE: Documentation/common/examples/mid.rpc.authenticate.response.json ================================================ { "error": null, "id": 0.0, "result": { "Challenge": "EtsTur4XV7xEGS9LBjHSfF9Cc5PQxtYW+YAOysRIt2r...", "SessionCode": "2127729011", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "DataToken": "G1GTSqBSBKrzqReuKYrmFUFXWFPkisjJjdiZi6zqAnaK3OvrT2Qu6..." } } ================================================ FILE: Documentation/common/examples/mid.rpc.authenticatestatus.query.json ================================================ { "id": 0.0, "method": "RPC.AuthenticateStatus", "params": [ { "OS": "Operating System,2,0", "SessionCode": "2127729011", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/mid.rpc.authenticatestatus.response.json ================================================ { "error": null, "id": 0.0, "result": { "AuthToken": null, "GivenName": "", "PersonalCode": "", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Status": "POLL", "Surname": "" } } ================================================ FILE: Documentation/common/examples/mid.rpc.authenticatestatus2.query.json ================================================ { "id": 0.0, "method": "RPC.AuthenticateStatus", "params": [ { "OS": "Operating System,2,0", "SessionCode": "2127729011", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/mid.rpc.authenticatestatus2.response.json ================================================ { "error": null, "id": 0.0, "result": { "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT2Qu6...", "GivenName": "MARY \u00c4NN", "PersonalCode": "60001019906", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Status": "OK", "Surname": "O\u2019CONNE\u017d-\u0160USLIK" } } ================================================ FILE: Documentation/common/examples/mid.rpc.getcertificate.query.json ================================================ { "id": 0.0, "method": "RPC.GetCertificate", "params": [ { "AuthMethod": "ticket", "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT...", "DataToken": "G1GTSqBSBKrzqReuKYrmFUFXWFPkisjJjdiZi6zqAnaK3OvrT2Qu6...", "OS": "Operating System,2,0", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/mid.rpc.getcertificate.response.json ================================================ { "error": null, "id": 0.0, "result": { "Certificate": "MIIEVjCCAz6gAwIBAgIQRfmbsIcpkQ9UhxScCwG6VDANBgkqhki...", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } } ================================================ FILE: Documentation/common/examples/mid.rpc.sign.query.json ================================================ { "id": 0.0, "method": "RPC.Sign", "params": [ { "AuthMethod": "ticket", "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT...", "DataToken": "G1GTSqBSBKrzqReuKYrmFUFXWFPkisjJjdiZi6zqAnaK3OvrT2Qu6...", "Hash": "9IBrA05ylt2StdjxKkSTYMW/rQXY3Vub4upzShdfEzo=", "HashType": "SHA256", "OS": "Operating System,2,0", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/mid.rpc.sign.response.json ================================================ { "error": null, "id": 0.0, "result": { "SessionCode": "E663A711BB9447EAD82491F9372F4CA", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } } ================================================ FILE: Documentation/common/examples/mid.rpc.signstatus.query.json ================================================ { "id": 0.0, "method": "RPC.SignStatus", "params": [ { "OS": "Operating System,2,0", "SessionCode": "E663A711BB9447EAD82491F9372F4CA", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/mid.rpc.signstatus.response.json ================================================ { "error": null, "id": 0.0, "result": { "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Signature": null, "Status": "POLL" } } ================================================ FILE: Documentation/common/examples/mid.rpc.signstatus2.query.json ================================================ { "id": 0.0, "method": "RPC.SignStatus", "params": [ { "OS": "Operating System,2,0", "SessionCode": "E663A711BB9447EAD82491F9372F4CA", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/mid.rpc.signstatus2.response.json ================================================ { "error": null, "id": 0.0, "result": { "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Signature": "MOj+8xQ9DmZPr/ItHlm0tHNMCuTgn6dT9jcXjPLf0+2sVjsS11jRI...", "Algorithm": "SHA256WithECEncryption", "Status": "OK" } } ================================================ FILE: Documentation/common/examples/mid.rpc.vote.query.json ================================================ { "id": 0.0, "method": "RPC.Vote", "params": [ { "AuthMethod": "ticket", "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT...", "Choices": "0919.1", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "OS": "Operating System,2,0", "Type": "bdoc", "Vote": "UEsDBAoAAAAAAAAAAACKIflFHwAAAB8AAAAIAAAAbWltZXR5cGVhcHB..." } ] } ================================================ FILE: Documentation/common/examples/mid.rpc.vote.response.json ================================================ { "error": null, "id": 0.0, "result": { "Qualification": { "ocsp": "MIIG7QoBAKCCBuYwggbiBgkrBgEFBQcwAQEEggbTMIIGzzCCASGhgY...", "tspreg": "MIIE0QYJKoZIhvcNAQcCoIIEwjCCBL4CAQMxDzANBglghkgBZQMEA..." }, "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "TestVote": true, "VoteID": "dWf/HUQVqXili7BeX2JAZQ==" } } ================================================ FILE: Documentation/common/examples/mid.rpc.voterchoices.query.json ================================================ { "id": 0.0, "method": "RPC.VoterChoices", "params": [ { "AuthMethod": "ticket", "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT...", "OS": "Operating System,2,0", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/mid.rpc.voterchoices.response.json ================================================ { "error": null, "id": 0.0, "result": { "Choices": "0919.1", "List": "ew0KICAgICAgICAgICAgIsOca3Npa2thbmRpZGFhZGlkIjogew0KICAgIC...", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Voted": true } } ================================================ FILE: Documentation/common/examples/smartid.rpc.authenticate.query.json ================================================ { "id": 0.0, "method": "RPC.Authenticate", "params": [ { "OS": "Operating System,2,0", "XSmartIDAuth": "4wesTurtYW+66BjHSfF9CcAQEB56It2rW+11112018Reji==...", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Identifier": "60001019906" } ] } ================================================ FILE: Documentation/common/examples/smartid.rpc.authenticate.response.json ================================================ { "error": null, "id": 0.0, "result": { "XSmartIDAuth": "4wesTurtYW+66BjHSfF9CcAQEB56It2rW+11112018Reji==...", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "SessionCode": "2127729011", } } ================================================ FILE: Documentation/common/examples/smartid.rpc.authenticatestatus.query.json ================================================ { "id": 0.0, "method": "RPC.AuthenticateStatus", "params": [ { "OS": "Operating System,2,0", "SessionCode": "2127729011", "XSmartIDAuth": "4wesTurtYW+66BjHSfF9CcAQEB56It2rW+11112018Reji==...", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/smartid.rpc.authenticatestatus.response.json ================================================ { "error": null, "id": 0.0, "result": { "AuthToken": null, "DataToken": null, "GivenName": "", "PersonalCode": "", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "XSmartIDAuth": "4wesTurtYW+66BjHSfF9CcAQEB56It2rW+11112018Reji==...", "Status": "POLL", "Surname": "" } } ================================================ FILE: Documentation/common/examples/smartid.rpc.authenticatestatus2.query.json ================================================ { "id": 0.0, "method": "RPC.AuthenticateStatus", "params": [ { "OS": "Operating System,2,0", "SessionCode": "2127729011", "XSmartIDAuth": "4wesTurtYW+66BjHSfF9CcAQEB56It2rW+11112018Reji==...", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/smartid.rpc.authenticatestatus2.response.json ================================================ { "error": null, "id": 0.0, "result": { "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT2Qu6...", "DataToken": "G1RTZqBSBKrzqReuKYrmFUFXWkajsdhaiuhdaksdj62vrT2Qu6...", "GivenName": "MARY \u00c4NN", "PersonalCode": "60001019906", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Status": "OK", "Surname": "O\u2019CONNE\u017d-\u0160USLIK" } } ================================================ FILE: Documentation/common/examples/smartid.rpc.challenge.query.json ================================================ { "id": 0.0, "method": "RPC.Challenge", "params": [ { "OS": "Operating System,2,0", } ] } ================================================ FILE: Documentation/common/examples/smartid.rpc.challenge.response.json ================================================ { "error": null, "id": 0.0, "result": { "Challenge": "EtsTur4XV7xEGS9LBjHSfF9Cc5PQxtYW+YAOysRIt2r...", "XSmartIDAuth": "4wesTurtYW+66BjHSfF9CcAQEB56It2rW+11112018Reji==...", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } } ================================================ FILE: Documentation/common/examples/smartid.rpc.getcertificatechoice.query.json ================================================ { "id": 0.0, "method": "RPC.GetCertificateChoice", "params": [ { "AuthMethod": "ticket", "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT...", "DataToken": "G1RTZqBSBKrzqReuKYrmFUFXWkajsdhaiuhdaksdj62vrT2Qu6...", "OS": "Operating System,2,0", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/smartid.rpc.getcertificatechoice.response.json ================================================ { "error": null, "id": 0.0, "result": { "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "SessionCode": "2127729011" } } ================================================ FILE: Documentation/common/examples/smartid.rpc.getcertificatechoicestatus.query.json ================================================ { "id": 0.0, "method": "RPC.GetCertificateChoiceStatus", "params": [ { "SessionCode": "2127729011", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "OS": "Operating System,2,0" } ] } ================================================ FILE: Documentation/common/examples/smartid.rpc.getcertificatechoicestatus.response.json ================================================ { "error": null, "id": 0.0, "result": { "Certificate": null, "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Status": "POLL" } } ================================================ FILE: Documentation/common/examples/smartid.rpc.getcertificatechoicestatus2.response.json ================================================ { "error": null, "id": 0.0, "result": { "Certificate": "MIIEVjCCAz6gAwIBAgIQRfmbsIcpkQ9UhxScCwG6VDANBgkqhki...", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Status": "OK" } } ================================================ FILE: Documentation/common/examples/smartid.rpc.sign.query.json ================================================ { "id": 0.0, "method": "RPC.Sign", "params": [ { "AuthMethod": "ticket", "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT...", "DataToken": "G1RTZqBSBKrzqReuKYrmFUFXWkajsdhaiuhdaksdj62vrT2Qu6...", "Hash": "9IBrA05ylt2StdjxKkSTYMW/rQXY3Vub4upzShdfEzo=", "HashType": "SHA256", "OS": "Operating System,2,0", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/smartid.rpc.sign.response.json ================================================ { "error": null, "id": 0.0, "result": { "SessionCode": "E663A711BB9447EAD82491F9372F4CA", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } } ================================================ FILE: Documentation/common/examples/smartid.rpc.signstatus.query.json ================================================ { "id": 0.0, "method": "RPC.SignStatus", "params": [ { "OS": "Operating System,2,0", "SessionCode": "E663A711BB9447EAD82491F9372F4CA", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/smartid.rpc.signstatus.response.json ================================================ { "error": null, "id": 0.0, "result": { "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Signature": null, "Status": "POLL" } } ================================================ FILE: Documentation/common/examples/smartid.rpc.signstatus2.query.json ================================================ { "id": 0.0, "method": "RPC.SignStatus", "params": [ { "OS": "Operating System,2,0", "SessionCode": "E663A711BB9447EAD82491F9372F4CA", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/smartid.rpc.signstatus2.response.json ================================================ { "error": null, "id": 0.0, "result": { "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Signature": "MOj+8xQ9DmZPr/ItHlm0tHNMCuTgn6dT9jcXjPLf0+2sVjsS11jRI...", "Algorithm": "sha256WithRSAEncryption", "Status": "OK" } } ================================================ FILE: Documentation/common/examples/smartid.rpc.vote.query.json ================================================ { "id": 0.0, "method": "RPC.Vote", "params": [ { "AuthMethod": "ticket", "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT...", "Choices": "0919.1", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "OS": "Operating System,2,0", "Type": "bdoc", "Vote": "UEsDBAoAAAAAAAAAAACKIflFHwAAAB8AAAAIAAAAbWltZXR5cGVhcHB..." } ] } ================================================ FILE: Documentation/common/examples/smartid.rpc.vote.response.json ================================================ { "error": null, "id": 0.0, "result": { "Qualification": { "ocsp": "MIIG7QoBAKCCBuYwggbiBgkrBgEFBQcwAQEEggbTMIIGzzCCASGhgY...", "tspreg": "MIIE0QYJKoZIhvcNAQcCoIIEwjCCBL4CAQMxDzANBglghkgBZQMEA..." }, "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "TestVote": true, "VoteID": "dWf/HUQVqXili7BeX2JAZQ==" } } ================================================ FILE: Documentation/common/examples/smartid.rpc.voterchoices.query.json ================================================ { "id": 0.0, "method": "RPC.VoterChoices", "params": [ { "AuthMethod": "ticket", "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT...", "OS": "Operating System,2,0", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/smartid.rpc.voterchoices.response.json ================================================ { "error": null, "id": 0.0, "result": { "Choices": "0919.1", "List": "ew0KICAgICAgICAgICAgIsOca3Npa2thbmRpZGFhZGlkIjogew0KICAgIC...", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Voted": true } } ================================================ FILE: Documentation/common/examples/ver.rpc.verify.query.json ================================================ { "id": 1, "method": "RPC.Verify", "params": [ { "OS": "Operating System,2,0", "SessionID": "ec3a0cab353d552952289f2c7ad52e27", "VoteID": "VM/cUIU4n7VjxpUx1fC00Q==" } ] } ================================================ FILE: Documentation/common/examples/ver.rpc.verify.response.json ================================================ { "error": null, "id": 1, "result": { "Qualification": { "ocsp": "MIIG8woBAKCCBuwwggboBgkrBgEFBQcwAQEEggbZMIIG1TCCASehgY...", "tspreg": "MIIE0QYJKoZIhvcNAQcCoIIEwjCCBL4CAQMxDzANBglghkgBDQEJE..." }, "SessionID": "027ab451969d9d3f044ea2cb2675b503", "Type": "bdoc", "Vote": "UEsDBAoAAAAAAAAAAACKIflFHwAAAB8AAAAIAAAAbWltZXR5cGVhcHB...", "ChoicesList": "ew0KICAgICAgICAgICAgIkVyYWtvbmQgMSI6IHsNCiAgICAgICAgICAgIC..." } } ================================================ FILE: Documentation/common/examples/votesorder.rpc.votes.query.json ================================================ { "id": 0.0, "method": "RPC.Votes", "params": [ { "VotesFrom": 1, "BatchMaxSize": 1000 } ] } ================================================ FILE: Documentation/common/examples/votesorder.rpc.votes.response.json ================================================ { "error": null, "id": 0.0, "result": { "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "batchRecords": [ { "seqNo": 1, "idCode": "37123097845", "voterName": "NIMI NIMESTE1", "kovCode": "0123", "electoralDistrictNo": 1 }, { "seqNo": 2, "idCode": "37123097653", "voterName": "NIMI NIMESTE2", "kovCode": "0444", "electoralDistrictNo": 1 } ] } } ================================================ FILE: Documentation/common/examples/votesorder.rpc.votesseqno.query.json ================================================ { "id": 0.0, "method": "RPC.VotesSeqNo", "params": [ { } ] } ================================================ FILE: Documentation/common/examples/votesorder.rpc.votesseqno.response.json ================================================ { "error": null, "id": 0.0, "result": { "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "SeqNo": 10 } } ================================================ FILE: Documentation/common/examples/webeid.rpc.challenge.query.json ================================================ { "id": 0.0, "method": "RPC.Challenge", "params": [ { "OS": "Operating System,2,0" } ] } ================================================ FILE: Documentation/common/examples/webeid.rpc.challenge.response.json ================================================ { "error": null, "id": 0.0, "result": { "Challenge": "EtsTur4XV7xEGS9LBjHSfF9Cc5PQxtYW+YAOysRIt2r...", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Bearer": "xtYW+YAOyXV7xEGS9YWxtYW+YAOtsTur4XV7xEGS9LB1..." } } ================================================ FILE: Documentation/common/examples/webeid.rpc.token.query.json ================================================ { "id": 0.0, "method": "RPC.Token", "params": [ { "OS": "Operating System,2,0", "Token": "{\"unverifiedCertificate":"MIICnDCCA...", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Bearer": "xtYW+YAOyXV7xEGS9YWxtYW+YAOtsTur4XV7xEGS9LB1..." } ] } ================================================ FILE: Documentation/common/examples/webeid.rpc.token.response.json ================================================ { "error": null, "id": 0.0, "result": { "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT2Qu6...", "GivenName": "MARY \u00c4NN", "PersonalCode": "60001019906", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Status": "OK", "Surname": "O\u2019CONNE\u017d-\u0160USLIK" } } ================================================ FILE: Documentation/common/examples/webeid.rpc.vote.query.json ================================================ { "id": 0.0, "method": "RPC.Vote", "params": [ { "AuthMethod": "ticket", "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT...", "Choices": "0919.1", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "OS": "Operating System,2,0", "Type": "bdoc", "Vote": "UEsDBAoAAAAAAAAAAACKIflFHwAAAB8AAAAIAAAAbWltZXR5cGVhcHB..." } ] } ================================================ FILE: Documentation/common/examples/webeid.rpc.vote.response.json ================================================ { "error": null, "id": 0.0, "result": { "Qualification": { "ocsp": "MIIG7QoBAKCCBuYwggbiBgkrBgEFBQcwAQEEggbTMIIGzzCCASGhgY...", "tspreg": "MIIE0QYJKoZIhvcNAQcCoIIEwjCCBL4CAQMxDzANBglghkgBZQMEA..." }, "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "TestVote": true, "VoteID": "dWf/HUQVqXili7BeX2JAZQ==" } } ================================================ FILE: Documentation/common/examples/webeid.rpc.voterchoices.query.json ================================================ { "id": 0.0, "method": "RPC.VoterChoices", "params": [ { "AuthMethod": "ticket", "AuthToken": "G1RTZqBSBKrzqReuKYrmFUFXWFPvaxhJjdiZi6zqAnaK3OvrT...", "OS": "Operating System,2,0", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b" } ] } ================================================ FILE: Documentation/common/examples/webeid.rpc.voterchoices.response.json ================================================ { "error": null, "id": 0.0, "result": { "Choices": "0919.1", "List": "ew0KICAgICAgICAgICAgIsOca3Npa2thbmRpZGFhZGlkIjogew0KICAgIC...", "SessionID": "057229fdfa2df7d3c7f4ced81b02760b", "Voted": true } } ================================================ FILE: Documentation/common/schema/Makefile ================================================ .PHONY: validate validate: python3 validate_schema.py ================================================ FILE: Documentation/common/schema/ivxv.anon-bb.schema ================================================ { "$schema": "http://json-schema.org/draft-04/schema#", "definitions": { "results": { "type": "array", "items": { "type": "string" }, "additionalItems": false }, "questions": { "type": "object", "additionalProperties": { "$ref": "#/definitions/results" }, "minProperties": 1 }, "parish": { "type": "object", "patternProperties": { "^[0-9]{4}$|^(FOREIGN)$": { "$ref": "#/definitions/questions" } }, "additionalProperties": false, "minProperties": 1 }, "districts": { "type": "object", "patternProperties": { "^[0-9]{4}\\.[0-9]{1,2}$": { "$ref": "#/definitions/parish" } }, "additionalProperties": false, "minProperties": 1 } }, "type": "object", "properties": { "election": { "type": "string" }, "districts": { "$ref": "#/definitions/districts" } }, "required": [ "election", "districts" ], "additionalProperties": false } ================================================ FILE: Documentation/common/schema/ivxv.anon-bb.schema.example ================================================ { "election": "TESTKOV", "districts": { "0164.1": { "0164": { "TESTKOV.1": [ "MDkxOS4xMDUK", "MDkxOS4xMDQK", "MDkxOS4xMDEK", "MDkxOS4xMDMK" ] } }, "0296.1": { "0296": { "TESTKOV.1": [ "MDkxOS4xMDQK", "MDkxOS4xMDQK" ] } } } } ================================================ FILE: Documentation/common/schema/ivxv.choices.schema ================================================ { "$schema": "http://json-schema.org/draft-04/schema#", "definitions": { "choice": { "type": "string", "description": "Candidate's name in case of RK, EP, KOV. Possible answer in case of RH" }, "list_choices": { "type": "object", "patternProperties": { "^[0-9]{4}\\.[0-9]{3,4}$": { "$ref": "#/definitions/choice" } }, "additionalProperties": false, "minProperties": 1 }, "district_choices": { "type": "object", "additionalProperties": { "$ref": "#/definitions/list_choices" }, "minProperties": 1, "description": "Political unions and independent candidates in district, in case of RH - question" }, "district_dict": { "type": "object", "patternProperties": { "^[0-9]{4}\\.[0-9]{1,2}$": { "$ref": "#/definitions/district_choices" } }, "additionalProperties": false, "minProperties": 1 } }, "type": "object", "properties": { "election": { "type": "string", "pattern": "^[ \\-,\\+\\.:;=!?&%#<>_/\\'\\*()\\[\\]{}|^A-Za-z0-9]{1,28}$" }, "choices": { "$ref": "#/definitions/district_dict" } }, "required": [ "election", "choices" ], "additionalProperties": false } ================================================ FILE: Documentation/common/schema/ivxv.choices.schema.example ================================================ { "choices": { "0164.1": { "Nimi Valimisliit": { "0164.126": "Nimi Kandidaat", "0164.127": "Nimi Kandidaat" } }, "0296.1": { "Nimi Erakond": { "0296.198": "Nimi Kandidaat", "0296.199": "Nimi Kandidaat", "0296.200": "Nimi Kandidaat" }, "Nimi Valimisliit": { "0296.115": "Nimi Kandidaat", "0296.116": "Nimi Kandidaat", "0296.117": "Nimi Kandidaat" }, "Üksikkandidaadid": { "0296.101": "Nimi Kandidaat", "0296.102": "Nimi Kandidaat" } } }, "election": "TESTKOV" } ================================================ FILE: Documentation/common/schema/ivxv.districts.schema ================================================ { "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "region": { "type": "object", "properties": { "state": { "type": "string" }, "county": { "type": "string" }, "parish": { "type": "string" } }, "additionalProperties": false, "minProperties": 1, "description": "Value - parish - is absent in case of Tallinn and Tartu cities as they are marked as counties. Parish represents city district in case of Tallinn. Parish and county are absent in case of Välisriik and RK, EP and RH elections" }, "region_dict": { "type": "object", "patternProperties": { "^[0-9]{4}$": { "$ref": "#/definitions/region" } }, "additionalProperties": false, "minProperties": 1, "description": "Parishes EHAK code; city district code in case of Tallinn; 0000 for foreign state in case of RK, EP and RH elections" }, "parish": { "type": "string", "pattern": "^[0-9]{4}$", "description": "Parishes in election district of county. 0000 value in represents foreign state in case of RK, EP and RH elections for each election district in districts block" }, "district": { "type": "object", "properties": { "name": { "type": "string" }, "parish": { "type": "array", "items": { "$ref": "#/definitions/parish" } } }, "required": [ "parish" ], "description": "Object includes parishes or city districts that belong to this election district" }, "district_dict": { "type": "object", "patternProperties": { "^[0-9]{4}.[0-9]{1,2}$": { "$ref": "#/definitions/district" } }, "additionalProperties": false, "minProperties": 1 }, "counties": { "type": "array", "items": { "$ref": "#/definitions/parish" }, "description": "Object includes parishes or city districts that belong into this election district", "additionalProperties": false, "minProperties": 1 }, "county_dict": { "type": "object", "patternProperties": { "^[0-9]{4}$": { "$ref": "#/definitions/counties" } }, "description": "Object contains parishes or city districts inside county. Tallinn is defined as county and contains city districts, Tartu linn is both county and parish", "additionalProperties": false, "minProperties": 1 } }, "type": "object", "properties": { "election": { "type": "string", "pattern": "^[ \\-,\\+\\.:;=!?&%#<>_/\\'\\*()\\[\\]{}|^A-Za-z0-9]{1,28}$" }, "districts": { "$ref": "#/definitions/district_dict" }, "regions": { "$ref": "#/definitions/region_dict" }, "counties": { "$ref": "#/definitions/county_dict" } }, "required": [ "districts", "regions", "counties", "election" ], "additionalProperties": false } ================================================ FILE: Documentation/common/schema/ivxv.districts.schema.example ================================================ { "election": "KOV2034", "regions": { "0809": { "parish": "Tori vald", "county": "Pärnu maakond", "state": "Eesti Vabariik" }, "0624": { "parish": "Pärnu linn", "county": "Pärnu maakond", "state": "Eesti Vabariik" }, "0524": { "parish": "Nõmme linnaosa", "county": "Tallinn", "state": "Eesti Vabariik" }, "0784": { "county": "Tallinn", "state": "Eesti Vabariik" }, "0796": { "parish": "Tartu vald", "county": "Tartu maakond", "state": "Eesti Vabariik" }, "0793": { "county": "Tartu linn", "state": "Eesti Vabariik" } }, "districts": { "0809.1": { "name": "Valimisringkond nr. 1", "parish": [ "0809" ] }, "0809.2": { "name": "Valimisringkond nr. 2", "parish": [ "0809" ] }, "0624.1": { "name": "Valimisringkond nr. 1", "parish": [ "0624" ] }, "0784.6": { "name": "Valimisringkond nr. 6", "parish": [ "0524" ] }, "0796.1": { "name": "Valimisringkond nr. 1", "parish": [ "0796" ] }, "0793.1": { "name": "Valimisringkond nr. 1", "parish": [ "0793" ] } }, "counties": { "0068": [ "0809", "0624" ], "0784": [ "0524" ], "0079": [ "0796" ], "0793": [ "0793" ] } } ================================================ FILE: Documentation/common/schema/ivxv.result.schema ================================================ { "$schema": "http://json-schema.org/draft-04/schema#", "definitions": { "results": { "type": "object", "properties": { "invalid": { "type": "integer", "description": "Number of invalid votes" } }, "patternProperties": { "^[0-9]{4}\\.[0-9]{3,4}$": { "type": "integer" } }, "additionalProperties": false, "required": [ "invalid" ] }, "parish": { "type": "object", "patternProperties": { "^[0-9]{4}$": { "$ref": "#/definitions/results" } }, "additionalProperties": false, "minProperties": 1 }, "district_dict": { "type": "object", "patternProperties": { "^[0-9]{4}\\.[0-9]{1,2}$": { "$ref": "#/definitions/results" } }, "additionalProperties": false, "minProperties": 1 }, "parish_dict": { "type": "object", "patternProperties": { "^[0-9]{4}\\.[0-9]{1,2}$": { "$ref": "#/definitions/parish" } }, "additionalProperties": false, "minProperties": 1 } }, "type": "object", "properties": { "election": { "type": "string", "pattern": "^[ \\-,\\+\\.:;=!?&%#<>_/\\'\\*()\\[\\]{}|^A-Za-z0-9]{1,28}$" }, "bydistrict": { "$ref": "#/definitions/district_dict" }, "byparish": { "$ref": "#/definitions/parish_dict" } }, "required": ["election", "bydistrict", "byparish"], "additionalProperties": false } ================================================ FILE: Documentation/common/schema/ivxv.result.schema.example ================================================ { "bydistrict": { "0164.1": { "0164.126": 0, "0164.127": 0, "invalid": 0 }, "0296.1": { "0296.101": 0, "0296.102": 0, "0296.115": 0, "0296.116": 0, "0296.117": 0, "0296.198": 0, "0296.199": 0, "0296.200": 0, "invalid": 0 } }, "byparish": { "0164.1": { "0164": { "0164.126": 0, "0164.127": 0, "invalid": 0 } }, "0296.1": { "0296": { "0296.101": 0, "0296.102": 0, "0296.115": 0, "0296.116": 0, "0296.117": 0, "0296.198": 0, "0296.199": 0, "0296.200": 0, "invalid": 0 }, "0296": { "0296.101": 0, "0296.102": 0, "0296.115": 0, "0296.116": 0, "0296.117": 0, "0296.198": 0, "0296.199": 0, "0296.200": 0, "invalid": 0 } } }, "election": "TESTKOV" } ================================================ FILE: Documentation/common/schema/ivxv.revoke.schema ================================================ { "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { "rev_entry": { "type": "string", "pattern": "^[0-9]{11}$", "description": "Personal code of onlinevoter to be revoked" } }, "type": "object", "properties": { "election": { "type": "string", "pattern": "^[ \\-,\\+\\.:;=!?&%#<>_/\\'\\*()\\[\\]{}|^A-Za-z0-9]{1,28}$" }, "type": {"enum": ["revoke", "restore"]}, "persons": { "type": "array", "items": { "$ref": "#/definitions/rev_entry" } } }, "required": [ "election", "persons", "type" ], "additionalProperties": false } ================================================ FILE: Documentation/common/schema/ivxv.revoke.schema.example ================================================ { "election": "TESTKOV", "persons": [ "11412090004", "11412090005", "11412090006" ], "type": "revoke" } ================================================ FILE: Documentation/common/schema/ivxv.voterlist.schema ================================================ { "$schema": "http://json-schema.org/draft-04/schema#", "definitions": { "onlinevoters_entry": { "type": "string", "pattern": "^[0-9]{11}$", "additionalItems": false }, "onlinevoters": { "type": "array", "items": { "$ref": "#/definitions/onlinevoters_entry" }, "additionalItems": false }, "parish": { "type": "object", "patternProperties": { "^[0-9]{4}$": { "$ref": "#/definitions/onlinevoters" } }, "additionalProperties": false, "minProperties": 1 }, "districts": { "type": "object", "patternProperties": { "^[0-9]{4}\\.[0-9]{1,2}$": { "$ref": "#/definitions/parish" } }, "additionalProperties": false, "minProperties": 1 } }, "type": "object", "properties": { "election": { "type": "string", "pattern": "^[ \\-,\\+\\.:;=!?&%#<>_/\\'\\*()\\[\\]{}|^A-Za-z0-9]{1,28}$" }, "onlinevoters": { "$ref": "#/definitions/districts" } }, "required": [ "election", "onlinevoters" ], "additionalProperties": false } ================================================ FILE: Documentation/common/schema/ivxv.voterlist.schema.example ================================================ { "election": "RK2030", "onlinevoters": { "0000.1": { "0176": [ "11412090001" ], "0339": [ "11412090002", "11412090003" ], "0614": [ "11412090004" ], "0000": [ "11412090005" ] }, "0000.10": { "0793": [ "11412090006", "11412090007", "11412090008" ], "0000": [ "11412090009" ] } } } ================================================ FILE: Documentation/common/schema/validate_schema.py ================================================ # IVXV Internet voting framework """Validate jsonschema example files.""" import json import logging import os import sys import jsonschema log = logging.getLogger() logging.basicConfig(level=logging.INFO) def main(): """Main routine.""" for schema_filename in sorted(os.listdir(".")): if schema_filename.endswith(".schema"): log.info("Loading schema %s", schema_filename) with open(schema_filename) as fd: schema = json.load(fd) log.info("Schema file %s is valid", schema_filename) example_filename = f"{schema_filename}.example" log.info("Validating file %s", example_filename) with open(example_filename) as fd: example = json.load(fd) try: jsonschema.validate(instance=example, schema=schema) except jsonschema.exceptions.ValidationError as err: log.error( "Schema validation error while validating %r: %s", example_filename, err, ) return 1 log.info("File %s is valid", example_filename) return 0 if __name__ == "__main__": sys.exit(main()) ================================================ FILE: Documentation/common/xmltemplates/si.template ================================================ %VOTE_DIGEST% %SP_DIGEST% ================================================ FILE: Documentation/common/xmltemplates/sig.template ================================================ %SI_XML% %SV_XML% %X509_CERT% %SP_XML% ================================================ FILE: Documentation/common/xmltemplates/sp.template ================================================ %SIGNING_TIME% %CERT_DIGEST% %ISSUER_NAME% %ISSUER_SERIAL% application/octet-stream ================================================ FILE: Documentation/common/xmltemplates/sv.template ================================================ %SIG_VALUE% ================================================ FILE: Documentation/common-model.mk ================================================ PLANTUML=env -u DISPLAY plantuml PLANTUML_EN=env -u DISPLAY plantuml -I./en/lang.pu PLANTUML_ET=env -u DISPLAY plantuml -I./et/lang.pu LANGUAGES=et en DIAGRAMS=$(SRC_DIAG) $(SUB_DIAG) # We process each diagram in all languages, so that the variables are set properly TARGETS=$(foreach DIAGRAM,$(DIAGRAMS),$(patsubst %, img/$(DIAGRAM).%.png, $(LANGUAGES))) all: @echo "Dry run, make model to apply changes" $(MAKE) -n model model: $(TARGETS) # Process manually translated diagrams img/%.png: %.pu $(PLANTUML) $< mv $*.png $@ # Process source diagrams img/%.et.png: %.pu $(PLANTUML_ET) $< mv $*.png $@ img/%.en.png: %.pu $(PLANTUML_EN) $< mv $*.png $@ # Process sub-diagrams of major diagram img/%.et.png: $(PARENT).pu %.env $(PLANTUML_ET) $(DIAGRAM_DEF) $< mv $(PARENT).png $@ img/%.en.png: $(PARENT).pu %.env $(PLANTUML_EN) $(DIAGRAM_DEF) $< mv $(PARENT).png $@ ================================================ FILE: Documentation/common.mk ================================================ # common.mk: Common recipes for Documentation. # # Defines a catch-all recipe which routes unknown targets to Sphinx in "make # mode". If $(DEPENDENCIES) is defined, then it will be set as a prerequisite # of the catch-all and removed on clean. In addition, if the source directory # contains a "model" subdirectory, then it invokes make in it to build and # clean that too. # # Defines a "diff" recipe which generates a PDF that highlights differences # between the current and latest released version of the document. If there are # no differences, then no PDF is produced. # # Defines "install-pdf", "install-html", and "install-diff" recipes which build # the specified type of documentation and install it to $(DESTDIR). common.mk := $(lastword $(MAKEFILE_LIST)) Makefile := $(lastword $(filter-out $(common.mk),$(MAKEFILE_LIST))) # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= -c $(dir $(common.mk)) SPHINXBUILD ?= sphinx-build SOURCEDIR = $(dir $(Makefile)) BUILDDIR = $(SOURCEDIR)_build SPHINXINTL ?= sphinx-intl # Set IVXV_DOCUMENT to the name of the source directory. This will be used as # the key to look up configuration from documents.py. export IVXV_DOCUMENT := $(notdir $(patsubst %/,%,$(abspath $(SOURCEDIR)))) # Special case the help target: set as default and skip prerequisites. .DEFAULT_GOAL := help .PHONY: help help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) translation-et: @$(SPHINXBUILD) -M gettext "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) @$(SPHINXINTL) update -p _build/gettext -l et translation: @$(SPHINXBUILD) -M gettext "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) @$(SPHINXINTL) update -p _build/gettext -l en spelling: @$(SPHINXBUILD) -M spelling "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) english: clean $(DEPENDENCIES) export SPHINXOPTS="-D language='en'" && $(SPHINXBUILD) -M latexpdf "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) estonian: clean $(DEPENDENCIES) @$(SPHINXBUILD) -M latexpdf "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) # Special case the clean target: skip prerequisites and perform extra steps. .PHONY: clean clean: #if [ -d "model" ]; then $(MAKE) -C model clean; fi @$(SPHINXBUILD) -M clean "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) rm -rf $(BUILDDIR) $(DEPENDENCIES) # Do not regenerate the Makefiles. $(common.mk) $(Makefile): ; # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: $(DEPENDENCIES) if [ -d "model" ]; then $(MAKE) -C model; fi $(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) # Variables and rules for diffing. differ.sh := $(dir $(common.mk))differ.sh master := $(dir $(common.mk))_master/ gitdir := $(patsubst $(shell git rev-parse --show-toplevel)%,%,$(abspath $(SOURCEDIR))) olddir := $(master)$(gitdir) ifeq ("$(olddir)", "../../_master//Documentation/public/protokollid") olddir := "../../_master//Documentation/et/protokollid" endif ifeq ("$(olddir)", "../../_master//Documentation/public/uldsisukord") olddir := "../../_master//Documentation/et/uldsisukord" endif ifeq ("$(olddir)", "../../_master//Documentation/public/arhitektuur") olddir := "../../_master//Documentation/et/arhitektuur" endif .PHONY: diff diff: latex master-latex # latexmk attempts to proceed even though errors may be present # pdflatex attempts to proceed with errors and is silent (batchmode) LATEXMKOPTS="-f -interaction=batchmode" $(differ.sh) $(BUILDDIR)/master $(BUILDDIR) .PHONY: master-latex master-latex: $(master) if [ -d $(olddir) ]; then \ $(MAKE) -C $(olddir) BUILDDIR=$(abspath $(BUILDDIR))/master latex; \ fi $(master): git worktree add $@ 1.9.10 # Installation rules. .PHONY: install-pdf install-pdf: estonian cp --update $(filter-out %-diff.pdf,$(wildcard $(BUILDDIR)/latex/*.pdf)) "$(DESTDIR)" .PHONY: install-en-pdf install-en-pdf: english cp --update $(filter-out %-diff.pdf,$(wildcard $(BUILDDIR)/latex/*.pdf)) "$(DESTDIR)" .PHONY: install-html install-html: html cp --recursive --update $(BUILDDIR)/html/** "$(DESTDIR)" .PHONY: install-diff install-diff: diff $(eval diff.pdf = $(wildcard $(BUILDDIR)/latex/*-diff.pdf)) $(if $(diff.pdf),cp --update $(diff.pdf) "$(DESTDIR)") ================================================ FILE: Documentation/conf.py ================================================ # Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # import os import sys sys.path.insert(0, os.path.abspath('.')) import documents # -- Project information ----------------------------------------------------- def detect_language(): opts = os.environ.get('SPHINXOPTS') # expecting "-D language='en'" if opts is not None and 'en' in opts: return 'en' return 'et' language = detect_language() project = documents.project copyright = documents.copyright author = documents.author release = documents.release document = os.environ['IVXV_DOCUMENT'] version = documents.get(document, 'version', language) today = documents.get(document, 'changed', language) document_prefix = documents.get(document, 'document_prefix', language) document_type = documents.get(document, 'document_type', language) document_title = documents.get(document, 'document_title', language) document_target_name = documents.get(document, 'document_target_name', language) document_number = f'{document_prefix}-{version}' today_fmt = "%d.%m.%Y" numfig = True numfig_format = { 'section': '{name} (ptk. {number})' } # sphinx-intl locale_dirs = ['locales/'] gettext_compact = False # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.autosummary', 'sphinx.ext.imgmath', 'sphinx.ext.todo', 'sphinx_rtd_theme', 'sphinxcontrib.spelling', 'myst_parser', ] spelling_lang='et_EE' spelling_word_list_filename = ['../../spelling_wordlist.txt', 'spelling_wordlist.txt'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = { '.rst': 'restructuredtext', '.md': 'markdown', } # The master toctree document. master_doc = 'index' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'sphinx_rtd_theme' # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = [] # The name for this set of Sphinx documents. # " v documentation" by default. # html_title = f'{document_title} v{release}' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # List of CSS files. html_css_files = ['custom.css'] # HTML logo image. html_logo = '_static/ivxv.png' # -- Options for LaTeX output ------------------------------------------------ latex_preamble_lines = [ '\\makeatletter', '\\IVXVDefineDocumentVersion{%s}' % version, '\\IVXVDefineDocumentNumber{%s}' % document_number, '\\IVXVDefineDocumentType{%s}' % document_type, '\\IVXVDefineDocumentSecurity{}', '\\pagestyle{IVXVFancy}', '\\makeatother', '\\newcommand{\\tablecontinued}{\\sphinxtablecontinued}', ] latex_elements = { # The paper size ('letterpaper' or 'a4paper'). 'papersize': 'a4paper', 'preamble': ''.join(latex_preamble_lines), # The font size ('10pt', '11pt' or '12pt'). 'pointsize': '12pt', # Additional stuff for the LaTeX preamble. # 'preamble': '', # Latex figure (float) alignment # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, f'{document_target_name}.tex', document_title, author, 'ivxv-technical'), ] latex_additional_files = [ 'ivxv-technical/ivxv-common.cls', 'ivxv-technical/ivxv-technical.cls' ] # The name of an image file (relative to this directory) to place at the top of # the title page. # latex_logo = html_logo # If true, show page references after internal links. # latex_show_pagerefs = False # If true, show URL addresses after external links. # latex_show_urls = 'footnote' # -- Options for Texinfo output ---------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, document_target_name, document_title, author, document_target_name, 'One line description of project.', 'Miscellaneous'), ] ================================================ FILE: Documentation/differ.sh ================================================ #!/bin/bash # differ.sh: Generate LaTeX differences between two Sphinx build directories. set -eu old="$1/latex/" new="$2/latex/" shopt -s nullglob for oldfile in ${old}*.tex; do basename="$(basename "${oldfile}" .tex)" newfile="${new}${basename}.tex" difffile="${new}${basename}-diff.tex" if [[ "${basename}" != "*-diff" && -f "${newfile}" ]]; then latexdiff --replace-context2cmd="none" --config VERBATIMENV=sphinxVerbatim "${oldfile}" "${newfile}" > "${difffile}" # Only generate the -diff.pdf if there are any actual differences. if grep --invert-match "%DIF PREAMBLE" "${difffile}" | grep --quiet '\\DIF'; then # latexdiff can mess up latex sometimes, but output is still visually fine make --directory "${new}" "${basename}-diff.pdf" || true else # Remove any existing -diff.pdf to signal that there were no changes. rm --force "${new}${basename}-diff.pdf" fi fi done exit 0 ================================================ FILE: Documentation/documents.py ================================================ #!/usr/bin/python3 """ IVXV documents """ project = 'Elektroonilise hääletamise infosüsteem' copyright = '2016-2025, Cybernetica AS' author = 'Cybernetica AS' release = '1.10' META = { 'audiitor': { 'et':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-JAJ', 'document_type': 'Juhend', 'document_title': 'IVXV audiitori juhend', 'document_target_name': 'IVXV-audiitor' } }, 'arhitektuur': { 'et':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-AR', 'document_type': 'Arhitektuuridokument', 'document_title': 'IVXV arhitektuur', 'document_target_name': 'IVXV-arhitektuur' }, 'en':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-AR-EN', 'document_type': 'Architecture document', 'document_title': 'IVXV architecture', 'document_target_name': 'IVXV-architecture' } }, 'protokollid': { 'et':{ 'lang': 'et', 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-PR', 'document_type': 'Spetsifikatsioon', 'document_title': 'IVXV protokollide kirjeldus', 'document_target_name': 'IVXV-protokollid' }, 'en':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-PR-EN', 'document_type': 'Specification', 'document_title': 'IVXV protocols', 'document_target_name': 'IVXV-protocols' } }, 'haldusteenus': { 'et':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-JHT', 'document_type': 'Juhend', 'document_title': 'IVXV haldusteenuse kasutusjuhend', 'document_target_name': 'IVXV-haldusteenuse-juhend' } }, 'kasutusmall': { 'et':{ 'version': '1.8.1', 'changed': "16.12.2022", 'document_prefix': 'IVXV-KM', 'document_type': 'Analüüsidokument', 'document_title': 'IVXV kasutusmallid', 'document_target_name': 'IVXV-kasutusmallid' } }, 'votmerakendus': { 'et':{ 'version': '1.8.0', 'changed': "01.12.2022", 'document_prefix': 'IVXV-SVR', 'document_type': 'Spetsifikatsioon', 'document_title': 'IVXV võtmerakendus', 'document_target_name': 'IVXV-votmerakendus' } }, 'ivxvapi': { 'et':{ 'version': '1.8.0', 'changed': "01.12.2022", 'document_prefix': 'IVXV-API', 'document_type': 'API-dokument', 'document_title': 'IVXV API', 'document_target_name': 'IVXV-API' } }, 'seadistuste_koostejuhend': { 'et':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-JSK', 'document_type': 'Juhend', 'document_title': 'IVXV seadistuste koostamise juhend', 'document_target_name': 'IVXV-seadistuste-koostejuhend' } }, 'kogumisteenuse_haldusjuhend': { 'et':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-JSH', 'document_type': 'Juhend', 'document_title': 'IVXV kogumisteenuse haldusjuhend', 'document_target_name': 'IVXV-kogumisteenuse-haldusjuhend' } }, 'uldsisukord': { 'et':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-YS', 'document_type': '', 'document_title': 'IVXV dokumentatsiooni üldsisukord', 'document_target_name': 'IVXV-dokumentatsiooni-uldsisukord' }, 'en':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-YS-EN', 'document_type': '', 'document_title': 'IVXV documentation overview', 'document_target_name': 'IVXV-documentation-overview' } }, 'valijarakendus': { 'et':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-JVR', 'document_type': 'Juhend', 'document_title': 'IVXV valijarakendus', 'document_target_name': 'IVXV-valijarakendus' } }, 'valijarakenduse_pakendamine': { 'et':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-JVP', 'document_type': 'Juhend', 'document_title': 'IVXV valijarakenduse pakendamine', 'document_target_name': 'IVXV-valijarakenduse-pakendamine' } }, 'tarne': { 'et':{ 'version': '1.8.0', 'changed': "01.12.2022", 'document_prefix': 'IVXV-T', 'document_type': 'Juhend', 'document_title': 'IVXV tarnejuhend', 'document_target_name': 'IVXV-tarnejuhend' } }, 'eriomadused': { 'et':{ 'version': '1.8.0', 'changed': "01.12.2022", 'document_prefix': 'IVXV-EO', 'document_type': 'Analüüsidokument', 'document_title': 'IVXV eriomadused', 'document_target_name': 'IVXV-eriomadused' } }, 'testimisplaan': { 'et':{ 'version': '1.8.0', 'changed': "01.12.2022", 'document_prefix': 'IVXV-TP', 'document_type': 'Testimisplaan', 'document_title': 'IVXV testimisplaan', 'document_target_name': 'IVXV-testimisplaan' } }, 'regteenus': { 'et':{ 'version': '1.8.0', 'changed': "01.12.2022", 'document_prefix': 'IVXV-SRT', 'document_type': 'Spetsifikatsioon', 'document_title': 'IVXV registreerimisteenuse kirjeldus', 'document_target_name': 'IVXV-registreerimisteenus' } }, 'liidesed': { 'et': { 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-VIS-EHS', 'document_type': 'Spetsifikatsioon', 'document_title': 'VIS3-EHS liidesed', 'document_target_name': 'IVXV-liidesed' }, 'en': { 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-VIS-EHS-EN', 'document_type': 'Specification', 'document_title': 'VIS3-EHS interfaces', 'document_target_name': 'IVXV-interfaces' } }, 'xteeteenus': { 'et':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-XTEE', 'document_type': 'Spetsifikatsioon', 'document_title': 'IVXV X-tee teenuse kirjeldus', 'document_target_name': 'IVXV-xteeteenus' } }, 'ivxv-pyapi': { 'et':{ 'version': '1.8.0', 'changed': "01.12.2022", 'document_prefix': 'IVXV-PYAPI', 'document_type': 'API-dokument', 'document_title': 'IVXV Python API', 'document_target_name': 'IVXV-python-api' } }, 'backendlogs': { 'en':{ 'version': '1.10', 'changed': "25.09.2025", 'document_prefix': 'IVXV-LOGS-EN', 'document_type': 'Technical documentation', 'document_title': 'IVXV Backend Log Messages', 'document_target_name': 'IVXV-backend-log-messages' } } } def get(doc, meta, language): return META[doc][language][meta] def print_table_header(): print("") print(".. list-table::") print(" :widths: 47 20 13 15") print(" :header-rows: 1") print("") print(" * - Nimi") print(" - ID") print(" - Versioon") print(" - Kuupäev") print("") def print_document(doc, lang='et'): title = get(doc, 'document_title', lang) prefix = get(doc, 'document_prefix', lang) version = get(doc, 'version', lang) changed = get(doc, 'changed', lang) print(f" * - {title}") print(f" - {prefix}-{version}") print(f" - {version}") print(f" - {changed}") print("") if __name__ == "__main__": print(".. IVXV dokumentatsiooni üldsisukord") print("") print("Dokumendid") print("==========") print("") print("Ülddokumendid") print("-------------") print("") print_table_header() print_document('uldsisukord') print("Spetsifikatsioonid") print("------------------") print("") print_table_header() print_document('kasutusmall') print_document('protokollid') print_document('arhitektuur') print_document('votmerakendus') print("Ingliskeelsed dokumendid") print("------------------------") print("") print_table_header() print_document('protokollid', 'en') print_document('arhitektuur', 'en') print_document('liidesed', 'en') print_document('backendlogs', 'en') print("Juhendid") print("--------") print("") print_table_header() print_document('seadistuste_koostejuhend') print_document('kogumisteenuse_haldusjuhend') print_document('haldusteenus') print_document('ivxvapi') print_document('audiitor') print_document('valijarakendus') print_document('valijarakenduse_pakendamine') ================================================ FILE: Documentation/en/backendlogs/.gitignore ================================================ index.rst ================================================ FILE: Documentation/en/backendlogs/Makefile ================================================ DEPENDENCIES := index.rst include ../../common.mk index.rst: ./create_rst.py ================================================ FILE: Documentation/en/backendlogs/create_rst.py ================================================ #!/usr/bin/env python3 """ Generate log-event reference doc from source code """ import os import re from rstcloth import RstCloth def rstescape(txt): """ Escape RST formatting symbols from text """ return txt.replace("*", r"\*") def parse_structs(file_content): """ Parse information about a particular struct in the generated file """ pattern = re.compile( r"// BEGIN (\w+)\n\n" # Match typename r"// auto-generated.*\n" # Match warning r"//\s*([\w./]+)\.\1\s*\n" # Match package r"((?:\s*//.*\n)+)" # Match comments r"(type\s+\1\s+struct\s*{(?:.|\n)+?})\s*" # Match typedef r"// END \1", # Match end re.MULTILINE, ) structs = [] for match in pattern.finditer(file_content): typename = match.group(1) packagename = match.group(2) comments = match.group(3).replace("//", "").strip() typedef = match.group(4).strip() struct_info = { "typename": typename, "packagename": packagename, "fullcomment": comments, "typedef": typedef, } structs.append(struct_info) return structs def output_section_common(common_modules, rst, h2_common, h3_common, text): """ Output section with common modules """ rst.h2(h2_common) sorted_modules = sorted(common_modules.keys()) for module in sorted_modules: rst.h3(f"{h3_common} {module.replace('ivxv.ee/', '')}") sorted_events = sorted(common_modules[module].keys()) for event in sorted_events: data = common_modules[module][event] rst.definition(event, text) _, val = next(iter(data.items())) rst.codeblock(val["typedef"], indent=3) rst.newline() for mod in data: rst.li(rstescape(f"{mod}.{event}: {data[mod]['fullcomment']}")) rst.newline() def output_section_unique(unique_modules, rst, h2_unique, h3_unique): """ Output section with unique models """ rst.h2(h2_unique) sorted_modules = sorted(unique_modules.keys()) for module in sorted_modules: rst.h3(f"{h3_unique} {module.replace('ivxv.ee/', '')}") sorted_events = sorted(unique_modules[module].keys()) for event in sorted_events: data = unique_modules[module][event] rst.definition( f"{data['packagename']}.{event}", rstescape(data["fullcomment"]) ) rst.codeblock(data["typedef"], indent=3) rst.newline() def output_intro(rst, h1, content_file): """ Output introduction """ rst.h1(h1) with open(content_file, "r", encoding="ascii") as inf: for line in inf.readlines(): if line.startswith("*"): rst.li(line.replace("* ", "")) else: rst.content(line) rst.newline() def categorize_event(pkg, evt, item, exclusions, events_dicts): """ Analyze each event to a category """ if exclusions and pkg in exclusions: return if "/cmd/" in pkg: events_dicts["cmd_events"].setdefault(pkg, {})[evt] = item elif "/service/" in pkg: events_dicts["srv_events"].setdefault(pkg, {})[evt] = item elif "/internal/" in pkg: events_dicts["int_events"].setdefault(pkg, {})[evt] = item else: events_dicts["events"].setdefault(pkg, {})[evt] = item def analyze_src(src_dir, target_file, exclusions=None): """ Walk the source tree and analyze generated code """ events_dicts = {"events": {}, "cmd_events": {}, "int_events": {}, "srv_events": {}} for dirpath, _, filenames in os.walk(src_dir): if target_file in filenames: full_path = os.path.join(dirpath, target_file) with open(full_path, "r", encoding="utf8") as file: parsed_structs = parse_structs(file.read()) for item in parsed_structs: categorize_event( item["packagename"], item["typename"], item, exclusions, events_dicts, ) return tuple( events_dicts[key] for key in ["events", "cmd_events", "int_events", "srv_events"] ) def remove_common(events): """ Remove common events from unique set """ common_events = {} unique_events = {} all_events = {} for module, mod_events in events.items(): for event in mod_events: all_events.setdefault(event, set([])) all_events[event].add(module) for event, modules in all_events.items(): if len(modules) > 1: by_types = {} for mod in modules: typedef = events[mod][event]["typedef"] by_types.setdefault(typedef, set([])) by_types[typedef].add(mod) if len(by_types) > 1: pass # This should not happen often. This means that same identifiers # do not have equal typedefs and we may even have several different # clusters with same identifier # TODO # print(event,file=sys.stderr) # print(by_types, file=sys.stderr) for _, val in by_types.items(): if len(val) > 1: printable = "" for mod in sorted(val): printable += mod printable += ", " printable = printable[:-2] common_events.setdefault(printable, {}) common_events[printable][event] = {} for mod in sorted(val): common_events[printable][event][mod] = events[mod][event] else: mod = next(iter(val)) unique_events.setdefault(mod, {}) unique_events[mod][event] = events[mod][event] else: mod = next(iter(modules)) unique_events.setdefault(mod, {}) unique_events[mod][event] = events[mod][event] return common_events, unique_events if __name__ == "__main__": SRC_DIR = os.path.abspath("../../../") print(SRC_DIR) TARGET_FILE = "gen_types.go" OUT_FILE = "index.rst" EXCLUSIONS = set( [ "ivxv.ee/common/collector/auth/dummy", "ivxv.ee/common/collector/container/dummy", "ivxv.ee/common/collector/storage/file", "ivxv.ee/common/collector/storage/memory", ] ) MOD_EVENTS, CMD_EVENTS, INT_EVENTS, SRV_EVENTS = analyze_src( SRC_DIR, TARGET_FILE, EXCLUSIONS ) with open(OUT_FILE, "w") as output_file: RST = RstCloth(output_file) RST.title("IVXV Backend Log Messages") RST.newline() RST.content(".. raw:: html") RST.newline() RST.content('

') RST.content(" NB!") RST.content(" See on HTML-versioon dokumendist.") RST.content(" Tellijale antakse üle PDF-versioon.") RST.content("

") RST.newline() RST.content(".. toctree::") RST.content(" :maxdepth: 4") RST.newline() output_intro(RST, "Overview", "introduction.inc") CMD_COMMON, CMD_UNIQUE = remove_common(CMD_EVENTS) SRV_COMMON, SRV_UNIQUE = remove_common(SRV_EVENTS) MOD_COMMON, MOD_UNIQUE = remove_common(MOD_EVENTS) INT_COMMON, INT_UNIQUE = remove_common(INT_EVENTS) RST.h1("Commands") output_section_common( CMD_COMMON, RST, "Common events", "Commands", "Typedef for common event" ) output_section_unique(CMD_UNIQUE, RST, "Specific events", "Command") RST.h1("Services") output_section_common( SRV_COMMON, RST, "Common events", "Services", "Typedef for common event" ) output_section_unique(SRV_UNIQUE, RST, "Specific events", "Service") RST.h1("Modules") output_section_common( MOD_COMMON, RST, "Common events", "Modules", "Typedef for common event" ) output_section_unique(MOD_UNIQUE, RST, "Specific events", "Module") RST.h1("Internal modules") output_section_common( INT_COMMON, RST, "Common events", "Modules", "Typedef for common event" ) output_section_unique(INT_UNIQUE, RST, "Specific events", "Module") ================================================ FILE: Documentation/en/backendlogs/introduction.inc ================================================ The purpose of this document is to provide a reference to all possible log messages in the IVXV backend. This document is partially auto-generated from the comments in the source code. This is necessary to keep the document up to date through the evolution of the software. The document is written in english, since the source code is written in english for improved readability and availability to wider audiences. IVXV systematically logs based on the protocol description and the service status diagram. We describe general principles that are followed. At a minimum, the following should be logged: * The fact of receiving each request and the start of processing * The handover of processing to an external component * The return of the processing sequence to the component * The end of the request processing and the result * Additionally, passing through significant stages in the process state model together with important facts about the process General Principles: * The rsyslog service is used for logging, which records the timestamp of the log message with millisecond precision. * At the start of each session, the system generates a unique identifier, which the client application uses in its requests to the central system. * All log entries belonging to a single session contain the same session identifier. Validity of the session identifier is checked, requests with unknown, invalid or expired session identifiers are not served. * Each log entry must be uniquely identifiable. * For each log message, it must be possible to unambiguously identify the location in the source code where the message originated. To ensure this, each logged message must have a unique phrasing or contain a unique identifier. In IVXV all event identifiers and corresponding data structures are generated before the compilation. This makes it easier to follow unified pattern. * The log entry should preferably be in JSON format, where machine readability is primary and human readability is secondary for automated monitoring. * The log entries may be stacked, to include information from more technical contexts. * If in doubt - log, one can filter unnecessary information, but cannot regenerate missing information. Requirements: * The information logged must be sanitized (e.g., URL encoding) and subject to length restrictions (both overall and per parameter). * Information originating from outside the system perimeter must only be logged in a sanitized form and within a predefined length. * Certificates and the agreed cipher used during TLS handshake must be logged. * Sensitive data must not be logged Directly, it must be protected by e.g. hashing. ================================================ FILE: Documentation/et/audiitor/Makefile ================================================ include ../../common.mk ================================================ FILE: Documentation/et/audiitor/annotatsioon.rst ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus Annotatsioon ------------ Juhend annab suunised IVXV andmeauditi teostamiseks Ubuntu 20.04 platvormil. Kasulik on tutvuda järgmiste dokumentidega. * https://www.valimised.ee/sites/default/files/uploads/eh/IVXV_raamistiku_yldkirjeldus_29052017.pdf * https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-seadistuste-koostejuhend.pdf * https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-protokollid.pdf Juhendiga kaasneb näidisandmekomplekt ning vabas vormis `history` fail. ================================================ FILE: Documentation/et/audiitor/audit.rst ================================================ ================================================================================ IVXV juhend audiitorile ================================================================================ Rakenduste kompileerimine ================================================================================ EELDUSED -------------------------------------------------------------------------------- Kõik tegevused viime läbi tavakasutaja -- näidetes `ubuntu` -- õigustes, kasutades vajadusel käsklust `sudo`. Üldjuhul viime kõik tegevused läbi kasutaja kodukaustas:: cd $HOME Paigaldame tarkvara, mis on vajalik audiitori tööriistade ehitamiseks:: sudo apt-get install --no-install-recommends -y autoconf automake build-essential libgmp-dev libtool git openjdk-11-jdk-headless python unzip zip wget make INTCHECK -------------------------------------------------------------------------------- Verificatum miksneti tervikluskontroll toimub rakendusega `intcheck`:: wget https://github.com/vvk-ehk/intcheck/archive/master.zip unzip master.zip rm master.zip mv intcheck-master intcheck chmod +x intcheck/src/intcheck.py Veendume et rakendus on paigaldatud korrektselt:: ./intcheck/src/intcheck.py -h JAVA RAKENDUSED -------------------------------------------------------------------------------- Andmeauditi läbiviimiseks läheb vaja rakendust `auditor`, mille lähtekood on avalikustatud IVXV repositooriumis:: wget https://github.com/vvk-ehk/ivxv/archive/master.zip unzip master.zip rm master.zip mv ivxv-master ivxv Paigaldame Java sõltuvuspaketid:: cd $HOME/ivxv/common/external wget -O gradle-8.11.zip https://services.gradle.org/distributions/gradle-8.11-bin.zip unzip gradle-8.11.zip rm gradle-8.11.zip cd $HOME/ivxv/common/java make sync Veendume, et ettevalmistused on tehtud korrektselt:: cd $HOME/ivxv make clean-java Ehitame Java rakendused:: make java RVT'le tarnitavad rakendused:: $HOME/ivxv/auditor/build/distributions/auditor-1.10.3.zip $HOME/ivxv/key/build/distributions/key-1.10.3.zip $HOME/ivxv/processor/build/distributions/processor-1.10.3.zip Käivitatavad failid:: $HOME/ivxv/auditor/build/install/auditor/bin/auditor $HOME/ivxv/key/build/install/key/bin/key $HOME/ivxv/processor/build/install/processor/bin/processor VERIFICATUM -------------------------------------------------------------------------------- Verificatum miksneti adapter on vajalik miksimistõendi kontrolliks:: cd $HOME wget https://github.com/vvk-ehk/ivxv-mixnet-adapter/archive/master.zip unzip master.zip rm master.zip mv ivxv-mixnet-adapter-master ivxv-verificatum Verificatum tarkvara allalaadmine:: git clone https://github.com/verificatum/verificatum-gmpmee gmpmee git clone https://github.com/verificatum/vmgj git clone https://github.com/verificatum/vcr git clone https://github.com/verificatum/vmn Tarkvara täpse versiooni hankimine ning tervikluse kontroll:: cd gmpmee git checkout 4aafc31 rm -rf .git/ cd .. ./intcheck/src/intcheck.py verify gmpmee ivxv-verificatum/doc/gmpmee.dirsha256sum cd vmgj git checkout 8d7d412 rm -rf .git/ cd .. ./intcheck/src/intcheck.py verify vmgj ivxv-verificatum/doc/vmgj.dirsha256sum cd vcr git checkout af9fd82 rm -rf .git/ cd .. ./intcheck/src/intcheck.py verify vcr ivxv-verificatum/doc/vcr.dirsha256sum cd vmn git checkout bb00543 rm -rf .git/ cd .. ./intcheck/src/intcheck.py verify vmn ivxv-verificatum/doc/vmn.dirsha256sum Verificatumi adapteri ehitamine:: cd $HOME/ivxv-verificatum make zipext Juhuarvugeneraatori initsialiseerimine Verificatumi jaoks:: cd $HOME ./vcr/bin/vog -rndinit RandomDevice /dev/urandom Auditeerimine ================================================================================ Siit edasi eeldame, et lugeja on tuttav dokumendiga "IVXV seadistuste koostamise juhend" järgmises ulatuses: * Ptk. 2, IVXV seadistused valimise korraldamise protsessis * Ptk. 3, IVXV rakendused * Ptk. 6, Auditirakendus * Ptk. 10, E-häälte miksimine Olgu samuti paigaldatud pakk `audit-examples.tar`, millel on järgmine struktuur:: audit-conv |-- auditor.yaml -- konfinäide |-- inputs | |-- |-- process | |-- | audit-mix |-- auditor.yaml -- konfinäide |-- inputs | |-- |-- process | |-- | audit-mixver |-- inputs | |-- | audit-pdec |-- auditor.yaml -- konfinäide |-- inputs | |-- |-- process | |-- | audit-vertally |-- inputs | |-- | processor |-- Tegutsemine on üldjuhul järgmine: * Tutvuge konfinäitega * Veenduge, et on olemas vajalik RVT sisend * Tehke kausta `process` konfinäitest lähtuv failistruktuur * Käivitage kaustas `process` rakendus ja tööriist (eelvalmendatud seadistused on seal juba ees) Täpsemad juhised järgnevad. Genereeritud avalike võtmete kooskõlalisuse kontroll -------------------------------------------------------------------------------- Võtmete genereerimise ajal tekib kaks võtit - tulemusfaili signeerimisvõti ja häälte salastamise võti. Tulemusfaili signeerimisvõti on kodeeritud X509 sertifikaadina failis `RK2051-sign.pem`. Häälte salastamise võti on antud kolmes kodeeringus: * X509 sertifikaadina failis `RK2051-enc.pem` * DER-kodeeritud avaliku võtmena failis `RK2051-pub.der` * PEM-kodeeritud avaliku võtmena failis `RK2051-pub.pem` On võimalik kontrollida, et sertifikaat, mis sisaldab tulemusfaili signeerimisvõtit, on korrektselt isesigneeritud. Seda saab teha järgnevalt:: openssl verify -CAfile RK2051-sign.pem -check_ss_sig RK2051-sign.pem Korrektse sertifikaadi korral on väljund:: RK2051-sign.pem: OK On võimalik kontrollida, et sertifikaat, mis sisaldab häälte salastamise võtit, on korrektselt signeeritud tulemusfaili signeerimisvõtmega. Seda saab teha järgnevalt:: openssl verify -CAfile RK2051-sign.pem -check_ss_sig RK2051-enc.pem Korrektselt allkirjastatud sertifikaadi korral on väljund:: RK2051-enc.pem: OK .. note:: Teadaoleva OpenSSL vea tõttu ei suuda OpenSSL versioonist `1.1.1b` vanemad versioonid sertifikaadi usaldusahelat kontrollida. Eelneva kontrolli õnnestumise jaoks on eelduseks vähemalt OpenSSL versioon `1.1.1b`. Lisaks on võimalik kontrollida, et häälte salastamise võtme eri kodeeringud vastavad üksteisele. Me kontrollime, et X509 sertifikaadis olev võti vastab DER-kodeeritud võtmele ning lisaks, et PEM-kodeeritud võti vastab DER-kodeeritud võtmele. Transitiivsuse tõttu on seega kõik kolm kodeeringut kooskõlalised. Esiteks tuleb eraldada häälte salastamise võti vastavast sertifikaadist. Kuna OpenSSL ei toeta kasutatavad ElGamali krüptoskeemi, siis tuleb avaliku võtme eksportimiseks kasutada OpenSSL `asn1parse` tööriista. Kõigepealt tuleb leida avaliku võtme nihe sertifikaadis:: openssl asn1parse -in RK2051-enc.pem Avalik võti on vastavas `SubjectPublicKeyInfo` väljal:: 156:d=2 hl=4 l= 816 cons: SEQUENCE 160:d=3 hl=4 l= 415 cons: SEQUENCE 164:d=4 hl=2 l= 9 prim: OBJECT :1.3.6.1.4.1.3029.2.1 175:d=4 hl=4 l= 400 cons: SEQUENCE 179:d=5 hl=4 l= 385 prim: INTEGER :FFFFFFFFFFFFFFFFC90FDA A22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08 798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B5 76625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24 117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163F A8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C35 4E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783 A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D226 1898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB85 0458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94 E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B 18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5B FCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF 568:d=5 hl=2 l= 1 prim: INTEGER :02 571:d=5 hl=2 l= 6 prim: GENERALSTRING 579:d=3 hl=4 l= 393 prim: BIT STRING Näeme, et `SubjectPublicKeyInfo` välja nihe on 156 baiti. Eraldame avaliku võtme ja kontrollime vastavust väljastatud avaliku võtmega:: openssl asn1parse -in RK2051-enc.pem -strparse 156 -noout -out extracted.der diff -s extracted.der RK2051-pub.der Samaväärsete võtmete korral on väljundiks:: Files extracted.der and RK2051-pub.der are identical Teiseks kontrollime DER-kodeeritud võtme vastavust PEM-kodeeritud võtmele. Selleks teisendame PEM-kodeeritud võtme DER-kodeeringusse ja võrdleme:: openssl asn1parse -in RK2051-pub.pem -noout -out converted.der diff -s converted.der RK2051-pub.der Samaväärsete võtme korral on väljundiks:: Files converted.der and RK2051-pub.der are identical Hääletamistulemuse allkirja verifitseerimine -------------------------------------------------------------------------------- Nii tavalise dekrüpteerimise kui tõestatava dekrüpteerimise käigus tekib kaks faili: * Tulemusfail `RK2051.1.tally` * Signatuurifail `RK2051.1.tally.signature` Koos häälte salastamise võtmega genereeritakse tulemusfaili signeerimisvõti ja vastav sertifikaat (`RK2051-sign.pem`). Dekrüpteeritud tulemusele antakse selle võtmega signatuur, mida tuleb kontrollida. Eraldame signeerimisvõtme sertifikaadist avaliku võtme:: openssl x509 -in RK2051-sign.pem -noout -pubkey > sign.pub Kasutame avalikku võtit tulemusfaili allkirja kontrollimiseks:: openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 -sigopt rsa_mgf1_md:sha256 -verify sign.pub -signature RK2051.1.tally.signature RK2051.1.tally NB! Tavalise dekrüpteerimise ja tõestatava dekrüpteerimise käigus tekkivad tulemusfailid peavad olema identsed. Kontrollimiseks UNIXi tööriist `diff`:: diff decout/RK2051.1.tally pdecout/RK2051.1.tally Näitefailid on pakis:: cd $HOME/audit-examples/audit-vertally IVXV <-> Verificatum teisenduste korrektsuse kontroll -------------------------------------------------------------------------------- Teisenduste korrektsuse kontroll toimub tööriistaga `convert`. NB! Kaust `process` tuleb `auditor.yaml` põhjal sisenditest ettevalmistada:: cd $HOME/audit-examples/audit-conv/process $HOME/ivxv/auditor/build/install/auditor/bin/auditor convert -c conf.bdoc -p auditor.yaml.bdoc Miksimistõendi kontroll tööriistaga `auditor` -------------------------------------------------------------------------------- Miksimistõendi kontroll toimub tööriistaga `mixer`. NB! Kaust `process` tuleb `auditor.yaml` põhjal sisenditest ettevalmistada:: cd $HOME/audit-examples/audit-mix/process $HOME/ivxv/auditor/build/install/auditor/bin/auditor mixer -c conf.bdoc -p auditor.yaml.bdoc Lugemistõendi kontroll -------------------------------------------------------------------------------- Lugemistõendi kontroll toimub tööriistaga `decrypt`. NB! Kaust `process` tuleb `auditor.yaml` põhjal sisenditest ettevalmistada:: cd $HOME/audit-examples/audit-pdec/process $HOME/ivxv/auditor/build/install/auditor/bin/auditor decrypt -c conf.bdoc -p auditor.yaml.bdoc Miksimistõendi kontroll Verificatumi originaaltööriistaga -------------------------------------------------------------------------------- Miksimistõendi kontroll Verificatumi abil:: cd $HOME/audit-examples/audit-mixver $HOME/ivxv-verificatum/release/mixer/bin/mix.py verify --proof-zipfile shuffle_proof.zip Töötlemise audit -------------------------------------------------------------------------------- Täiendavalt on lisatud pakki kõik töötlemisrakenduse sisendid ja väljundid lihtsustamaks töötlemisprotsessi auditit. Täiendavad auditeerimistööriistad, nt. `integrity` on kirjeldatud dokumendis "IVXV seadistuste koostamise juhend". ================================================ FILE: Documentation/et/audiitor/history.rst ================================================ `.history` --------------- .. literalinclude:: history.txt :linenos: ================================================ FILE: Documentation/et/audiitor/history.txt ================================================ sudo apt update sudo apt upgrade tar xvf audit-examples.tar sudo apt-get install --no-install-recommends -y autoconf automake build-essential libgmp-dev libtool git openjdk-11-jdk-headless python unzip zip wget make java -version javac -version sudo apt install openjdk-11-jre-headless sudo update-alternatives --config java java -version javac -version wget https://github.com/vvk-ehk/intcheck/archive/master.zip unzip master.zip rm master.zip mv intcheck-master/ intcheck chmod +x intcheck/src/intcheck.py ./intcheck/src/intcheck.py -h ./intcheck/src/intcheck.py verify -h wget https://github.com/vvk-ehk/ivxv/archive/master.zip unzip master.zip rm master.zip mv ivxv-master/ ivxv cd ivxv/common/external/ wget -O gradle-8.11.zip https://services.gradle.org/distributions/gradle-8.11-bin.zip unzip gradle-8.11.zip rm gradle-8.11.zip cd .. cd java/ make sync ls ../external/ cd .. cd .. make clean-java make java auditor/build/install/auditor/bin/auditor -h ls auditor/build/distributions/*.zip ls key/build/distributions/*.zip ls processor/build/distributions/*.zip ls processor/build/install/processor/bin/processor ls key/build/install/key/bin/key ls auditor/build/install/auditor/bin/auditor cd .. wget https://github.com/vvk-ehk/ivxv-mixnet-adapter/archive/master.zip unzip master.zip rm master.zip mv ivxv-mixnet-adapter-master ivxv-verificatum git clone https://github.com/verificatum/verificatum-gmpmee gmpmee git clone https://github.com/verificatum/vmgj git clone https://github.com/verificatum/vcr git clone https://github.com/verificatum/vmn cd gmpmee/ git checkout 4aafc31 rm -rf .git/ cd .. ./intcheck/src/intcheck.py verify gmpmee ivxv-verificatum/doc/gmpmee.dirsha256sum cd vmgj/ git checkout 8d7d412 rm -rf .git/ cd .. ./intcheck/src/intcheck.py verify vmgj ivxv-verificatum/doc/vmgj.dirsha256sum cd vcr/ git checkout af9fd82 rm -rf .git/ cd .. ./intcheck/src/intcheck.py verify vcr ivxv-verificatum/doc/vcr.dirsha256sum cd vmn/ git checkout bb00543 rm -rf .git cd .. ./intcheck/src/intcheck.py verify vmn ivxv-verificatum/doc/vmn.dirsha256sum cd ivxv-verificatum/ make zipext cd .. ./vcr/bin/vog -rndinit RandomDevice /dev/urandom openssl verify -CAfile initout/RK2051-sign.pem -check_ss_sig initout/RK2051-sign.pem openssl verify -CAfile initout/RK2051-sign.pem -check_ss_sig initout/RK2051-enc.pem openssl asn1parse -in initout/RK2051-enc.pem openssl asn1parse -in initout/RK2051-enc.pem -strparse 156 -noout -out extracted.der diff -s extracted.der initout/RK2051-pub.der openssl asn1parse -in initout/RK2051-pub.pem -noout -out converted.der diff -s converted.der initout/RK2051-pub.der diff decout/RK2051.1.tally pdecout/RK2051.1.tally openssl x509 -in initout/RK2051-sign.pem -noout -pubkey > sign.pub openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 -sigopt rsa_mgf1_md:sha256 -verify sign.pub -signature decout/RK2051.1.tally.signature decout/RK2051.1.tally cd $HOME/audit-examples/audit-conv cd process $HOME/ivxv/auditor/build/install/auditor/bin/auditor $HOME/ivxv/auditor/build/install/auditor/bin/auditor convert -c conf.bdoc -p auditor.yaml.bdoc cat ../auditor.yaml cp ../inputs/bb-4.json* . mkdir initout cp ../inputs/RK2051-pub.pem initout/ cp ../inputs/shuffled.json . $HOME/ivxv/auditor/build/install/auditor/bin/auditor convert -c conf.bdoc -p auditor.yaml.bdoc unzip -l ../inputs/shuffle_proof.zip cd .. unzip inputs/shuffle_proof.zip cd process/ $HOME/ivxv/auditor/build/install/auditor/bin/auditor convert -c conf.bdoc -p auditor.yaml.bdoc $HOME/ivxv/auditor/build/install/auditor/bin/auditor mixer -c conf.bdoc -p auditor.yaml.bdoc $HOME/ivxv/auditor/build/install/auditor/bin/auditor decrypt -c conf.bdoc -p auditor.yaml.bdoc $HOME/ivxv-verificatum/release/mixer/bin/mix.py verify --proof-zipfile shuffle_proof.zip $HOME/ivxv/processor/build/install/processor/bin/processor ================================================ FILE: Documentation/et/audiitor/index.rst ================================================ .. IVXV seadistuste koostamise juhend IVXV audiitori juhend ========================================================================== .. raw:: html

NB! See on HTML-versioon dokumendist. Tellijale antakse üle PDF-versioon.

.. toctree:: :maxdepth: 2 :numbered: ylevaade annotatsioon audit history ================================================ FILE: Documentation/et/audiitor/spelling_wordlist.txt ================================================ PEM RVT'le konfinäitega konfinäitest ubuntu ================================================ FILE: Documentation/et/audiitor/ylevaade.rst ================================================ Miksimistõendi ülevaade ======================= Ilma juhuslikkust kasutamata oleks iga krüpteerimise algoritm deterministlik, st. valija valiku krüpteerimisel oleks tulemuseks alati sama väljund. See lubaks ründajal tuvastada esialgse valiku, kui ta krüpteeriks kõikvõimalikud valikud ja võrdleks seda nimekirja nähtud krüpteeritud valikuga. Seega, krüpteerimine peab kasutama juhuslikkust. Juhuslikkuse kasutamine teeb krüptogrammid unikaalseks - isegi kui kaks korda on krüpteeritud sama valik, siis krüptogrammid on erinevad. See tähendab, et kui ründaja on võimeline mingil ajahetkel seostama krüptogrammi ja selle krüpteerinud isikut, siis on tal võimalik hiljem ainult krüptogrammi nähes tuletada seda andnud isik. Kuna sobivate parameetrite kasutamisel on ElGamali avaliku võtme krüptosüsteem pikaajaliselt turvaline, siis see ei ole otseselt probleemiks. Probleem tekib siis, kui on tarvis tõestada, et krüptogramm on korrektselt dekrüpteeritud. Kui kasutatav valikute agregeerimise algoritm töötab avateksti kujul sõnede peal (nagu see IVXVs on), siis iga krüptogrammi kohta tekib üks dekrüpteeritud avatekst. Korrektse dekrüpteerimise tõestus peab nii krüptogrammi kui dekrüpteeritud avateksti siduma. Seega on võimalik ründajal tekitada seos isiku ja krüptogrammi, ning krüptogrammi ja vastava avateksti vahel, st. ta saab teada, mis valiku isik tegi. Et seda seost eemaldada, kasutatakse IVXVs krüptogrammide segamist (miksnet). Miksnet teeb korraga kahte operatsiooni -- järjestab sisendkrüptogrammid ümber (permuteerib) ja uuendab krüptogrammis olevad juhuslikkust (rerandomiseerib). See tähendab, et krüptogrammid, mis lähevad miksneti sisse on väliselt täiesti sõltumatud krüptogrammidest, mis tulevad miksnetist välja. Kuna välise sõltumatuse tõttu võiks teoreetiliselt miksnet krüptogramme asendada, siis on tarvis lisada miksimistõend, mis tõestab krüptograafiliselt, et operatsioonid on tehtud korrektselt ja ühtegi täiendavat operatsiooni pole tehtud. Kontrollides miksimistõendit, on võimalik garanteerida, et miksnet on töötanud korrektselt. Väikeste parameetritega kirjutatud näide ---------------------------------------- IVXV kasutab valikute krüpteerimiseks ElGamali avaliku võtme krüptosüsteemi. ElGamali krüptosüsteemi korral on fikseeritud algebralise rühma parameetrid koos generaatoriga :math:`g`. Salajane võti :math:`x` valitakse vahemikus :math:`[0, q-1]` ühtlase jaotusega, kus :math:`q` on rühma multiplikatiivse alamrühma järk. Salajasele võtmele avalik võti on defineeritud: .. math:: pk = (g, g^x) = (g, y). Krüpteerimaks sõne kujul valikut `V`, tuleb see kõigepealt kodeerida rühma elemendiks .. math:: m = encode(V) ja seejärel arvutatakse krüptogramm kasutades ühekordset juhuarvu :math:`0<=r NB! See on HTML-versioon dokumendist. Tellijale antakse üle PDF-versioon.

.. toctree:: :maxdepth: 2 annotatsioon ylevaade yldseisund nimekirjad statistika kasutajad teenused allalaadimised seadistused logi ================================================ FILE: Documentation/et/haldusteenus/kasutajad.rst ================================================ .. IVXV kogumisteenuse haldusliidese kasutusjuhend Kasutajate haldus ================= Kasutajate halduse leht avaneb menüüvalikust ``Kasutajad``. Kasutajate nimekiri ------------------- Kasutajate nimekirjas kuvatakse kõigi haldusteenuses registreeritud kasutajate andmeid sordituna kasutaja ID-kaardi üldnime (CN - *Common Name*) järgi: #. Järjekorranumber nimekirjas; #. Üldnimi; #. Kasutaja rollid. Kasutaja volituste laadimise vorm --------------------------------- Kasutaja volituste laadimiseks kogumisteenusesse on lehe allosas laadimisvorm. Laadida on lubatud ainult volitatud kasutajate poolt digitaalselt signeeritud volitusi. ================================================ FILE: Documentation/et/haldusteenus/logi.rst ================================================ .. IVXV kogumisteenuse haldusliidese kasutusjuhend Haldussündmuste logi jälgimine ============================== Kogumisteenuse sündmuste logi sirvimise leht avaneb menüüvalikust ``Logiraamat``. Logis on järgmised väljad: #. ``Aeg`` - sündmuse registreerimise aeg; #. ``Teenus`` - teenuse identifikaator; #. ``Tase`` - logisündmuse tase (``INFO`` või ``ERROR``); #. ``Sündmus`` - sündmuse liigi identifikaator; #. ``Kirjeldus`` - sündmuse tekstiline kirjeldus. Logi on võimalik filtreerida ja välja väärtuse järgi sortida. Logisündmused ------------- Kogumisteenuse olekud: :COLLECTOR_INIT: Kogumisteenuse lähtestamine (käsuga :command:`ivxv-collector-init`); :COLLECTOR_RESET: Kogumisteenuse seadistuste lähtestamine (usaldusjuure laadimine); :COLLECTOR_STATE_CHANGE: Kogumisteenuse olekumuutus; Korralduste laadimine: :CMD_LOAD: Korraldusfaili haldusteenusesse laadimine; :CMD_LOADED: Edukalt laaditud korraldusfaili registreerimine haldusteenuses; :CMD_REMOVED: Korraldusfaili eemaldamine haldusteenusest; :VOTER_LIST_DOWNLOADED: Valijate muudatusnimekirja allalaadimine; :VOTER_LIST_DOWNLOAD_FAILED: Valijate muudatusnimekirja nurjunud allalaadimine; :VOTER_LIST_NOT_FOUND: Valijate järgmist muudatusnimekirja ei leitud Valimiste Infosüsteemis; Kasutajaõiguste muutused: :PERMISSION_SET: Kasutajale õiguse määramine; :PERMISSION_RESET: Kasutaja õiguste lähtestamine; Hääletusperioodi registreerimine: :SET_ELECTION_TIME: Hääletusperioodi algus- ja lõpuaegade registreerimine; Mikroteenuste haldus: :SERVICE_REGISTER: Teenuse registreerimine haldusteenuses; :SERVICE_CONFIG_APPLY: Seadistuse rakendamine teenusele; :SERVICE_STATE_CHANGE: Teenuse olekumuutus; :SECRET_INSTALL: Saladuse laadimine teenusele. ================================================ FILE: Documentation/et/haldusteenus/nimekirjad.rst ================================================ .. IVXV kogumisteenuse haldusliidese kasutusjuhend Nimekirjade haldamine ===================== Nimekirjade haldamise leht avaneb menüüvalikust ``Nimekirjad``. Valikute nimekiri ----------------- Valikute nimekirja kohta kuvatakse nimekirja seisundit ja laaditud nimekirja korral selle versiooni (nimekirja signeerija andmed koos digiallkirja ajatempliga). Nimekirja võimalikud seisundid on: #. Laadimata; #. Laaditud haldusteenusesse; #. Rakendatud kogumisteenusele. Valijate nimekirjad ------------------- Valijate nimekirjade kohta kuvatakse nimekirjade koguarvu, nimekirjade arvu seisundi kaupa ning loetelu kõigi kogumisteenuses registreeritud nimekirjade kohta (versioon ja seisund). Valijate algnimekirja korral on nimekirja versioon nimekirja signeerija andmed koos digiallkirja ajatempliga; muudatusnimekirja korral nimekirja allalaadimise URL koos allalaadimise hetke ajatempliga. Nimekirja võimalikud seisundid on: #. Rakendamise ootel; #. Rakendatud kogumisteenusele; #. Vigane; #. Vahele jäetud. Ringkondade nimekiri -------------------- Ringkondade nimekirja kohta kuvatakse nimekirja seisundit ja laaditud nimekirja korral selle versiooni (nimekirja signeerija andmed koos digiallkirja ajatempliga). Nimekirja võimalikud seisundid on: #. Laadimata; #. Laaditud haldusteenusesse; #. Rakendatud kogumisteenusele. Nimekirjade laadimine kogumisteenusesse --------------------------------------- Nimekirjade laadimiseks kogumisteenusesse on lehe allosas laadimisvorm. Laadida on lubatud ainult volitatud kasutajate poolt digitaalselt signeeritud nimekirju. .. note:: Nimekirjade laadimise järjekord ei ole oluline. Enne nimekirjade laadimist tuleb laadida valimiste seadistused. .. important:: Valikute nimekirja on võimalik kogumisteenusele rakendada ainult üks kord! ================================================ FILE: Documentation/et/haldusteenus/seadistused.rst ================================================ .. IVXV kogumisteenuse haldusliidese kasutusjuhend Seadistuste rakendamise seisundid ================================= Seadistuste seisundite jälgimise leht avaneb menüüvalikust ``Seadistused``. Seisundit kuvatakse järgmiste seadistuste kohta: * Usaldusjuure seadistused; * Tehniline seadistus; * Valimiste seadistus; * Valikute nimekiri; * Ringkondade nimekiri; * Valijate nimekirjad. Seisundit ei kuvata järgmiste seadistuste kohta: * Kasutaja volitused (on laadimisel kohe rakendatud). Haldusteenusesse laaditud seadistuste kohta kuvatakse: * Seadistuse rakendamise seisundit; * Aktiivse seadistuse versiooni; * Seadistuste rakendamise katsete arvu; * Rakendamisele saadetud seadistuse kohta ka rakendamise logi. Seadistuste laadimine kogumisteenusesse --------------------------------------- Tehnilise seadistuse ja valimiste seadistuste laadimiseks kogumisteenusesse on lehe allosas laadimisvorm. Laadida on lubatud ainult volitatud kasutajate poolt digitaalselt signeeritud seadistuspakke. Seadistuste laadimise järjekord ei ole oluline. Valimiste seadistuse laadimine on eelduseks valimiste nimekirjade laadimisele. .. note:: Usaldusjuure seadistuse laadib kogumisteenuse haldur käsurealt. Enne usaldusjuure laadimist pole kogumisteenuse haldusliidest võimalik kasutada. ================================================ FILE: Documentation/et/haldusteenus/spelling_wordlist.txt ================================================ ================================================ FILE: Documentation/et/haldusteenus/statistika.rst ================================================ .. IVXV kogumisteenuse haldusliidese kasutusjuhend Statistika jälgimine ==================== Statistika jälgimise leht avaneb menüüvalikust ``Statistika``. Hääletamise detailstatistika allalaadimine on kirjeldatud lõigus :ref:`allalaadimised`. Statistika genereerimine ------------------------ Statistika vaates kuvatavad andmed genereeritakse ja uuendatakse korrapäraselt logimonitoris ning laaditakse automaatselt haldusliidesesse. Haldusliideses kuvatav statistika kajastab kogumisteenuse seisundit mõningase viivitusega (harilikult kuni 10 minutit). Statistika sisu --------------- Kuvatavad andmed on järgmised: #. Kogutud häälte arv; #. Hääletajate arv; #. Kontrollitud häälte arv; #. Hääle kontrollijate arv; #. Hääletajate jaotumine: #. Sugude kaupa; #. Vanusegruppide kaupa; #. Autentimisvahendite kaupa; #. Operatsioonisüsteemide kaupa; #. Riikide kaupa (vastavalt hääletaja IP-aadressile). #. Korduvhääletamiste statistika. Statistikat on võimalik filtreerida ringkondade ja jaoskondade kaupa (juhul, kui ringkondade nimekiri on laaditud haldusteenusesse). ================================================ FILE: Documentation/et/haldusteenus/teenused.rst ================================================ .. IVXV kogumisteenuse haldusliidese kasutusjuhend Teenuste haldus =============== Teenuste haldamise leht avaneb menüüvalikust ``Teenused``. Teenuste kokkuvõte ------------------ Teenuste kokkuvõttes kuvatakse kõikide registreeritud teenuste ülevaadet seisundi kaupa. Iga seisundi järel kuvatakse selles seisundis olevate teenuste arvu: #. Paigaldamata – teenus pole paigaldatud; #. Paigaldatud – teenus on paigaldatud ja sellele on rakendatud usaldusjuure seadistus, kogumisteenuse tehniline seadistus. Valimiste seadistus on teenusele rakendamata; #. Seadistatud – teenusele on rakendatud kõik seadistused ja teenus on töökorras; #. Tõrge – teenuse toimimises on avastatud tõrge; #. Eemaldatud – teenuse on kogumisteenuse koosseisust eemaldatud. Teenuste nimekiri ----------------- Teenuste nimekirjas kuvatakse kõiki haldusteenuses registreeritud teenuseid. Iga teenuse kohta kuvatakse: Teenuste halduse vaates kuvatakse alamteenuste nimekirja, mis on sorditud teenuse identifikaatori järgi: #. Teenuse identifikaator; #. Teenuse alamvõrk; #. Teenuse liik; #. Teenuse seisund; Kui haldusteenus on alamteenuse kohta tuvastanud seadistuste puudumise või veaolukorra, siis vastav teave kuvatakse teenuse all. Iga teenuse kohta kuvatakse korraga vaid ühte teadet. Nimekirjas teenuse kirjel klõpsates avaneb kirje all tabel täpsema infoga: #. Teenuse korrasoleku kontrolli poolt tuvastatud järjestikune vigade arv (ainult teenustel, mis on olekus ``seadistatud`` või ``tõrge``); #. Teenuse korrasoleku kontrolli viimase läbiviimise aeg (ainult teenustel, mis on olekus ``seadistatud`` või ``tõrge``); #. Teenusele rakendadud tehnilise seadistuse versioon; #. Teenusele rakendadud valimiste seadistuse versioon; #. Teenuse IP-aadress ja port; #. Teenuse TLS-sertifikaadi kontrollsumma (SHA256); #. Teenuse TLS-sertifikaadile vastava võtme kontrollsumma (SHA256); #. Mobiil-ID/Smart-ID/Web eID tugiteenuste jagatud krüptimissaladuse kontrollsumma (SHA256); ================================================ FILE: Documentation/et/haldusteenus/yldseisund.rst ================================================ .. IVXV kogumisteenuse haldusliidese kasutusjuhend Üldseisund ========== Üldseisundi leht avaneb menüüvalikust ``Üldseisund``. Kogumisteenuse üldseisund ------------------------- Kogumisteenuse üldseisundi vaates kuvatakse järgnevaid andmeid: #. Valimiste identifikaator; #. Kogumisteenuse seisund; #. Käimasolev hääletusetapp; #. Kogumisteenusele rakendatud seadistuste ja nimekirjade versioonid; #. Mikroteenuste seisundite kokkuvõte; #. Kogumisteenuse tarkvarapakkide seisund; #. Kogumisteenuses registreeritud kasutajate arv; #. Kogumisteenusesse laaditud korralduste arv. Kogumisteenuse üldseisundi tuvastamiseks kogub haldusteenus korrapäraselt alamteenustelt nende seisundi kohta andmeid ja peab selle üle arvestust. .. note:: Kogumisteenusesse laaditud korraldused jagunevad aktiivseteks ja arhiveeritud korraldusteks. Aktiivsed korraldused on hetkel teenusele rakendatud. Arhiveeritud korraldused on süsteemi laaditud, kuid pole rakendatud - näiteks uuema versiooniga asendatud korraldused. ================================================ FILE: Documentation/et/haldusteenus/ylevaade.rst ================================================ .. IVXV kogumisteenuse haldusliidese kasutusjuhend Ülevaade ======== Haldusliidese funktsionaalsus ----------------------------- Haldusliides on kogumisteenuse haldamise teenuse veebipõhine kasutajaliides ja sellel on järgmised funktsioonid: * Kogumisteenuse seisundi ja ajaloo kohta ülevaate esitamine: * Koondülevaade; * Teenuste seisund; * Valmisnimekirjade seisund; * Üldstatistika; * Kogumisteenuse haldussündmuste logi; * Korralduste laadimine kogumisteenusesse; * Kasutajate haldamine; * Väljavõtete allalaadimine: * Hääletamise detailstatistika allalaadimine; * Hääletamisseansside nimekirja allalaadimine; * E-valimiskasti allalaadimine. Ligipääse haldusliidesele ------------------------- Kogumisteenuse haldusliides on kasutatav veebisirviku abil. Haldusliidesele ligipääsuks vajaliku ``URL-i`` annab kasutajatele IVXV süsteemihaldur. Haldusliidesele pääsevad ligi ainult volitatud kasutajad, kes on ennast autentinud ID-kaardiga. Kasutajale pakutavate funktsioonide hulk sõltub kasutaja volitustest. Kasutajaliidese ülevaade ------------------------ Lehe ülaosas asub lehe päis, kus on kirjas haldusliidese nimi ja ikoon sisselogitud kasutaja andmete vaatamiseks. Lehe vasakus servas asub menüüriba, mille abil saab navigeerida alamlehtede vahel. .. note:: Kasutajaliides skaleerub ka madala resolutsiooniga ekraanidele, siis peidetakse menüüosa vaikimisi vaatest ja see on avatav lehe päisest. Seadistuste, nimekirjade ja volituste koostamine ning laadimine --------------------------------------------------------------- Kasutajaliides kaudu on võimalik süsteemi laadida kogumisteenuse seadistusi, valikute- ja valijate nimekirju ning kasutajate volitusi. Nende andmete peavad olema vormistatud digitaalselt signeeritud korraldusena. Seadistuspakkide ettevalmistamine on kirjeldatud dokumendis ``IVXV seadistuste koostamise juhend``. Süsteemi laaditud seadistuspakke on võimalik alla laadida, kui klõpsata kasutajaliideses seadistuspaki versiooniandmetel. ================================================ FILE: Documentation/et/kasutusmall/Makefile ================================================ include ../../common.mk ================================================ FILE: Documentation/et/kasutusmall/index.rst ================================================ .. IVXV kasutusmallid IVXV kasutusmallid ========================================================== .. raw:: html

NB! See on HTML-versioon dokumendist. Tellijale antakse üle PDF-versioon.

.. toctree:: :maxdepth: 3 :numbered: sissejuhatus tegijad kasutusmallid ================================================ FILE: Documentation/et/kasutusmall/kasutusmallid.rst ================================================ .. IVXV kasutusmallid Kasutusmallid ============= Hääletamiseelne etapp --------------------- Korraldaja - Valimise defineerimine ``````````````````````````````````` Kirjeldus ''''''''' Rangelt võttes ei ole tegemist elektroonilise hääletamise infosüsteemi kasutusmalliga, kuid see on elektroonilise hääletamise alguspunkt - Korraldaja kirjeldab valimise, küsimused, ringkonnad, valijad ning erinevate rollide täitjad e-hääletamise põhiprotsessides - Lugeja, Koguja, Töötleja jt. Lugeja - Häälte salastamise ja avamise võtme genereerimine `````````````````````````````````````````````````````````` Kirjeldus ''''''''' Lugeja genereerib võtmepaari e-häälte salastamiseks ja avamiseks. Avamisvõtme osakud jagatakse Võtmehaldurite vahel. Eeltingimus ''''''''''' #. Lugejal on olemas Võtmerakendus. #. Läviskeemi tehniline seadistus on olemas. #. Leidub Läviskeemi rakendamiseks vajalik hulk Võtmehaldureid ning võtmekandjaid. Päästik ''''''' Lugeja algatab võtmepaari genereerimise Võtmerakenduses. Põhiprotsess '''''''''''' #. Võtmerakendus verifitseerib konfiguratsiooni digitaalallkirja. #. Võtmerakendus genereerib võtmeosakud vastavalt läviskeemi spetsifikatsioonile. #. Võtmerakendus küsib Lugejalt võtmekandjaid osakute talletamiseks. #. Võtmerakendus talletab osakud võtmekandjatele. #. Võtmerakendus kasutab häälte salastamise võtit sõnumi krüpteerimiseks. #. Võtmerakendus testib võtmekandjaid ning taastab 2 erineva kvoorumiga võtme sõnumi dekrüpteerimiseks. #. Võtmerakendus allkirjastab krüpteerimisvõtme allkirjastamisvõtmega. Laiendid '''''''' - Tehniliste vigade tekkimisel kõigis põhivoo sammudes logitakse sündmus tehniliste vigade logisse. Kasutajale väljastatakse teade veasituatsiooni kohta.. Järeltingimus ''''''''''''' Häälte salastamise ja avamise võtmepaar on edukalt genereeritud, avamise võti on talletatud osakutena võtmekandjatel. Korraldaja - Valijarakenduse seadistuse loomine ``````````````````````````````````````````````` Kirjeldus ''''''''' Korraldaja konfigureerib Valijarakenduse poolt kasutatavad tekstid, sertifikaadid, ikoonid ja valimise parameetrid. Eeltingimus ''''''''''' Seadistamiseks on täidetud järgmised tingimused: - Korraldaja on Valijarakenduse tekstid ette valmistanud - Korraldaja on valimise parameetrid ette valmistanud - Häälte salastamise võti on olemas. Põhiprotsess '''''''''''' #. Korraldaja käivitab Seadistamisrakenduse. #. Korraldaja sisestab valimise ja küsimuste identifikaatorid ning tüübid. #. Korraldaja sisestab valimise küsimused. #. Korraldaja laadib häälte salastamise võtme. #. Korraldaja konfigureerib Valijarakenduse kasutajaliidese – tekstid, fondid, värvid, ikoonid. #. Korraldaja kontrollib kõigi Valijarakenduse vaadete vastavust soovitule. #. Korraldaja salvestab loodud konfiguratsiooni. Laiendid '''''''' Järeltingimus ''''''''''''' Seadistamise lõpuks on olemas Valijarakenduse konfiguratsioon, millest on puudu Kogumisteenuse tehniline info. Korraldaja - Kontrollrakenduse seadistuse loomine ````````````````````````````````````````````````` Eeltingimus ''''''''''' Korraldajal on olemas #. Hääletaja allkirja kontrolliks vajalikud sertifikaadid #. Registreerimisteenuse kinnituse kontrolliks vajalikud sertifikaadid #. Kogumisteenuse allkirja kontrolliks vajalikud sertifikaadid #. Käimasoleval valimisel häälte krüpteerimiseks kasutatav avalik võti #. Kontrollrakenduse tekstid HTML kujul #. Kontrollrakenduse fondid #. Kontrollrakenduse värvid #. Käimasoleva valimise identifikaator ja küsimused Põhiprotsess '''''''''''' 1. Korraldaja loob Kontrollrakenduse seadistuse 2. Korraldaja veendub seadistamise õnnestumises vaadates läbi rakenduse vaated Laiendid '''''''' 1. Vaadete mittesobivuse korral muudab Korraldaja seadistusi ning alustab põhiprotsessi algusest. Koguja - Kogumisteenuse seadistamine ```````````````````````````````````` Kirjeldus ''''''''' Koguja valmistab Kogumisteenuse valimiseks ette. Eeltingimus ''''''''''' #. Kogumisteenuse operatsioonisüsteem on paigaldatud #. Kogumisteenuse tarkvarapakid on paigaldatud. Päästik ''''''' Kasutusmall algab kui Koguja logib enne hääletamisperioodi algust Kogumisteenusesse. Põhiprotsess '''''''''''' 1. Koguja viib läbi alljärgnevad sammud: a. Laeb konfiguratsioonipakkide verifitseerimiseks vajaliku sertifikaatide konfiguratsiooni. b. Laeb Tuvastusteenuse konfiguratsiooni. c. Laeb Allkirjastamisteenuse konfiguratsiooni. d. Laeb Registreerimisteenuse konfiguratsiooni. e. Laeb mikroteenuste võrgukonfiguratsiooni. f. Laeb talletustehnoloogia konfiguratsiooni. g. Laeb volitatud nimekirjade laadijate konfiguratsiooni. h. Laeb digitaalselt allkirjastatud jaoskondade/ringkondade nimekirja. i. Laeb digitaalselt allkirjastatud valikute nimekirja. j. Laeb signeeritud valijate nimekirja. k. Kogumisteenus kontrollib digitaalallkirju konfiguratsioonipakkidel ja nimekirjadel (tehniline kasutusmall Digitaalallkirja kehtivuse kontroll Kogumisteenuses). l. Kogumisteenus kontrollib tuvastatud allkirjastaja volitusi süsteemis. m. Kogumisteenus kontrollib konfiguratsiooni vormilist ja sisulist kooskõlalisust ning initsialiseerib sisemised andmestruktuurid. Laiendid '''''''' - Kui põhiprotsessi sammus 1.k ei tuvastata digitaalallkirja kehtivust, siis väljastatakse veateade, sündmus logitakse vigade logisse, ühtegi muudatust ei rakendata. - Kui põhiprotsessi sammus 1.l ei tuvastata digitaalallkirjastaja vastavat volitust volitatud isikute nimekirjast, siis väljastatakse veateade, sündmus logitakse vigade logisse, ühtegi muudatust ei rakendata. - Kui põhivoo sammus 1.m tuvastatakse vorminguprobleemid, siis väljastatakse veateade, sündmus logitakse vigade logisse, ühtegi muudatust ei rakendata. - Kui põhivoo sammus 1.m tuvastatakse ebakooskõla konfiguratsioonis – valed valimised, korduv jaoskond, korduv ringkond, jaoskond olematus ringkonnas, korduv kandidaat, olematu ringkonnaga kandidaat, korduv valija, olematu jaoskonnaga Hääletaja vms. – siis väljastatakse veateade, sündmus logitakse vigade logisse, ühtegi muudatust ei rakendata. - Tehniliste vigade tekkimisel kõigis põhivoo sammudes logitakse sündmus tehniliste vigade logisse. Kasutajale väljastatakse teade veasituatsiooni kohta.. Järeltingimus ''''''''''''' Kogumisteenus on kooskõlaliselt seadistatud ning seda on võimalik viia hääletamisetappi. Koguja - Valijarakenduse valmendamine ````````````````````````````````````` Kirjeldus ''''''''' Koguja valmendab Valijarakenduse. Eeltingimus ''''''''''' Valmendamiseks on täidetud järgmised tingimused: - Korraldaja on loonud omapoolse Valijarakenduse konfiguratsioonifaili - Valijarakendus on kompileeritud kõigi toetatavate platvormide jaoks. - Valijarakendus on seadistamata. - Kogumisteenuse TLS-sertifikaadi usaldamiseks vajalikud sertifikaadid on olemas. - Kogumisteenuse URI on teada. Põhiprotsess '''''''''''' #. Koguja käivitab Seadistamisrakenduse. #. Koguja laadib Korraldaja loodud Valijarakenduse konfiguratsioonifaili. #. Koguja laadib Kogumisteenuse TLS-sertifikaadi usaldamiseks vajalikud sertifikaadid. #. Koguja rakendab loodud seadistuse Valijarakendusele. #. Koguja kontrollib kõigi Valijarakenduse vaadete vastavust soovitule. Laiendid '''''''' Mõne vajaliku ressurssi puudumisel seadistamine katkestatakse ning protsessi alustatakse uuesti kui kõik eeltingimused on täidetud. Järeltingimus ''''''''''''' Seadistamise lõpuks Valijarakendus käivitub ning kasutab seadistatud ressursse. Koguja - Kontrollrakenduse valmendamine ``````````````````````````````````````` Eeltingimus ''''''''''' Kogujal on olemas 1. Kompileeritud Kontrollrakendus 2. Kontrollrakenduse allkirjastamiseks sobiv võtmepaar 3. Kogumisteenuse võrguaadress 4. Kogumisteenuse sertifikaadi verifitseerimiseks vajalikud sertifikaadid Põhiprotsess '''''''''''' 1. Koguja seadistab Kontrollrakenduse Kogumisteenuse võrguaadressi ja vastavate sertifikaatidega. 2. Koguja pakendab rakenduse 3. Koguja allkirjastab pakendatud rakenduse Korraldaja - Proovihääletamine `````````````````````````````` Kirjeldus ''''''''' Korraldaja koostöös Koguja, Töötleja, Lugeja ning Võtmehalduritega veendub Kogumisteenuse valmisolekus elektrooniliseks hääletamiseks ning kõigi komponentide kooskõlalises seadistatuses. Eeltingimus ''''''''''' #. e-häälte salastamise võti on loodud ja testitud #. Kogumisteenus on seadistatud #. Valijarakendus on seadistatud #. Kontrollrakendus on seadistatud Põhiprotsess '''''''''''' 1. Korraldaja viib läbi testhääletamise #. Koguja viib Kogumisteenuse hääletamisetappi #. Korraldaja annab Valijarakenduse abil ühe või mitu häält #. Korraldaja kontrollib Kontrollrakenduse abil hääli #. Koguja peatab Kogumisteenuse ja väljastab e-valimiskasti #. Töötleja genereerib e-hääletanute nimekirja #. Töötleja loob lugemisele minevate anonüümistatud e-häälte nimekirja #. Lugeja koos Võtmehalduritega aktiveerib Võtmerakenduse ja häälte avamise võtme #. Lugeja dekrüpteerib anonüümistatud hääled ja väljastab hääletamistulemuse 2. Koguja lõpetab testhääletamise ning viib Kogumisteenuse algsesse olekusse, kus talletatud häälte andmebaas on tühi. Laiendid '''''''' - Testhääletamine võib sisaldada ka miksimise ja auditeerimise töövooge. Järeltingimus ''''''''''''' Elektroonilise hääletamise süsteemi komponendid on kontrollitult kooskõlaliselt seadistatud. Hääletamisetapp --------------- Korraldaja - Hääletamise alustamine ``````````````````````````````````` Kirjeldus ''''''''' Hääletamise alustamine viib Kogumisteenuse hääletamisetappi - algab valikute nimekirjade väljastamine, häälte talletamine ja kontrollpäringutele vastamine. Päästik ''''''' #. Valimise seadistustes näidatud hääletamise algusaeg jõuab kätte. #. Korraldaja edastab Haldusteenuse vahendusel digitaalallkirjastatud korralduse hääletamise alustamiseks. Põhiprotsess '''''''''''' 1. Kogumisteenus alustab valikute nimekirjade väljastamist, häälte talletamist ja kontrollpäringutele vastamist. Järeltingimus ''''''''''''' Kogumisteenus väljastab valikute nimekirju, talletab hääli ning vastab kontrollpäringutele. Hääletaja - Elektrooniline hääletamine Valijarakendusega ```````````````````````````````````````````````````````` Kirjeldus ''''''''' Hääletaja kasutab Valijarakendust elektroonilise hääle andmiseks käimasoleval valimisel, mille valijate nimekirja ta kuulub. Eeltingimus ''''''''''' Hääletaja on laadinud oma arvutisse käimasoleva valimise jaoks seadistatud Valijarakenduse. Päästik ''''''' Kasutusmall käivitub kui Hääletaja on käivitanud Valijarakenduse. Põhiprotsess '''''''''''' #. Hääletaja autendib ennast elektroonilise isikutunnistusega (tehniline kasutusmall Autentimine Valijarakenduses) Kogumisteenusele. #. Kogumisteenus saadab isikukoodi alusel Valijarakendusele (tehniline kasutusmall Valikute nimekirjade väljastamine Valijarakendusele): - Hääletaja elukohajärgse valimisringkonna küsimuste ja valikute nimekirja valimisel, - teavituse varasema hääletamise kohta, kui sellel valimisel on sama isikukoodi kohta juba talletatud elektrooniline hääl. 3. Valijarakendus esitab Hääletaja isikuandmed, käimasoleva valimise kirjelduse ning küsimused. #. Valijarakendus esitab Hääletaja elukohajärgse valimisringkonna valikute nimekirja. #. Hääletaja teeb kõigi küsimuste kontekstis kuvatud valikute hulgast valiku. #. Valijarakendus esitab Hääletajale tehtud valikute andmed (valiku nimi, valiku number, teatud valimistel ka valimisnimekirja nimi või üksikkandidaat) ning küsib kinnitust valikutele. #. Hääletaja kinnitab tehtud valikud. #. Valijarakendus krüpteerib Hääletaja valikud valimise avaliku võtmega ning algatab hääle digitaalse allkirjastamise (tehniline kasutusmall Digitaalne allkirjastamine Valijarakenduses) Hääletaja elektroonilise isikutunnistusega. Valijarakendus saadab digitaalselt allkirjastatud hääle Kogumisteenusele talletamiseks (tehniline kasutusmall Hääle talletamine Kogumisteenuses). #. Valijarakendus verifitseerib Kogumisteenuse poolt vastusena saadetud Registreerimiskinnitust, kuvab Hääletajale teate hääle edukast talletamisest ning hääle kontrollimiseks vajaliku kontrollkoodi. Laiendid '''''''' - Hääletaja võib põhiprotsessi läbiviimisel kasutada ligipääsetavustehnoloogiaid (nt. ekraanilugerid). - Põhiprotsessi mis tahes etapis asetleidvad vead on fataalsed ning toovad kaasa hääletamisprotsessi katkestamise. Vea põhjuse kõrvaldamise korral tuleb kasutusmall uuesti käivitada. Olulisimad vead: - Elektroonilise isikutunnistuse kasutamine ebaõnnestus - Sidehäire Valijarakenduse ja Kogumisteenuse vahel - Autentimine ebaõnnestus - Hääletajal ei ole hääleõigust käimasoleval valimisel - Digitaalne allkirjastamine ebaõnnestus - Tehnilised vead Järeltingimus ''''''''''''' Õnnestunud elektroonilise hääletamise korral kuvatakse Hääletajale kontrollkood, mille alusel on võimalik kontrollida elektroonilise hääle jõudmist Kogumisteenusesse ning vastavust Hääletaja tahtele. Kasutusmalli katkestamine enne elektroonilise hääle digitaalset allkirjastamist ei mõjuta Hääletaja Kogumisteenuses eelnevalt talletatud häält. Hääletaja - Elektroonilise hääle kontrollimine Kontrollrakendusega `````````````````````````````````````````````````````````````````` Kirjeldus ''''''''' Hääletaja kasutab vahetult peale hääletamist Valijarakendusega Kontrollrakendust elektroonilise hääle korrektse jõudmise Kogumisteenusesse kontrollimiseks. Eeltingimus ''''''''''' #. Hääletaja valduses on Kontrollrakendusega mobiilseade. #. Hääletaja on kasutanud Valijarakendust hääletamiseks. #. Hääle kontrollimise ajaaken ei ole veel möödunud. #. Valijarakenduse viimane vaade on ekraanil avatud ning kuvab kontrollimiseks vajalikku infot sisaldavat QR-koodi. Päästik ''''''' Kasutusmall käivitub kui Hääletaja on käivitanud Kontrollrakenduse. Põhiprotsess '''''''''''' Põhiprotsess on ühesuunaline, tagasi liikumised protsessis eeldavad Kontrollrakenduse töö lõpetamist. #. Kontrollrakendus laadib Kogumisteenusest seadistused. #. Kontrollrakendus kuvab tervitusteksti. #. Hääletaja suunab mobiilseadme kaamera Valijarakenduses kuvatavale QR-koodile. #. Kontrollrakendus analüüsib QR-koodi ning tuvastab sealt hääle krüpteerimiseks kasutatud juhuarvu ning häält Kogumisteenuses identifitseeriva sessiooniidentifikaatori. #. Kontrollrakendus pöördub sessiooniidentifikaatoriga Kogumisteenuse poole. #. Kontrollrakendus verifitseerib Kogumisteenuse sertifikaadi ning kuvab Hääletajale info verifitseerimise õnnestumise kohta. #. Kontrollrakendus laadib Kogumisteenusest alla Kogumisteenuse allkirjastatud hääle, Registreerimisteenuse kinnituse ja häälega seotud valikute nimekirjad (tehniline kasutusmall Hääle väljastamine kontrollimiseks Kogumisteenusest). #. Kontrollrakendus veendub, et hääl vastab kontrollprotokolli nõuetele. Kontrollrakendus verifitseerib Registreerimisteenuse kinnitust ning Hääletaja allkirja. Kontrollrakendus kuvab Hääletajale info verifitseerimiste õnnestumise kohta, hääle allkirjastanud Hääletaja andmed ning küsimused, mille kohta antud hääles leidub krüpteeritud tahteavaldus. #. Hääletaja käivitab kontrollalgoritmi. #. Kontrollrakendus puhastab vaate hääle allkirjastanud Hääletaja andmetest. #. Kontrollrakendus tuvastab krüpteeritud tahteavalduse sisu kasutades kontrollalgoritmi ja QR-koodist saadud juhuarvu. #. Kontrollrakendus kuvab iga krüpteeritud tahteavalduse kohta Hääletajale küsimuse identifikaatorit ja tuvastatud valikut. Laiendid '''''''' #. Kui Kontrollrakendus tuvastab võrguühenduse puudumise, siis suunatakse Hääletaja võrguühendust aktiveerima. #. Kui Kontrollrakendus tuvastab vea Kogumisteenuse sertifikaadis, siis lõpetatakse rakenduse töö veateatega. #. Kui Kogumisteenusest ei saadud häält või Registreerimisteenuse kinnitust, siis juhendatakse Hääletajat Kliendituge informeerima ja lõpetatakse rakenduse töö veateatega. #. Kui Kogumisteenusest tuleb teade, et konkreetse hääle kontrollimine ei ole enam võimalik (aeg või korrad ületatud), siis lõpetatakse rakenduse töö vastavasisulise teatega. #. Kui Kogumisteenusest saadud hääl ei vasta nõuetele, siis lõpetatakse rakenduse töö veateatega. #. Kui Hääletaja allkirja verifitseerimine ebaõnnestub, siis lõpetatakse rakenduse töö veateatega. #. Kui Registreerimisteenuse kinnituse verifitseerimine ebaõnnestub, siis lõpetatakse rakenduse töö veateatega. #. Kui kontrollalgoritm ei leia kandidaatide nimekirjast sobivat valikut, siis kuvatakse konkreetse valimise ja küsimuse identifikaatori järel veateade. #. Kui QR koodis sisaldub rohkem kui ühe küsimuse kontrollkood, siis teostatakse kontroll kõigi viidatud küsimuste jaoks. #. Kui Kogumisteenusest saadetud allkirjastatud hääles on krüpteeritud hääli, mille kohta puudub kontrollkood, siis esitab Kontrollrakendus Hääletajale nende valimiste/küsimuste identifikaatorid ning vastavasisulise hoiatuse. Ülejäänud hääled kontrollitakse. #. Kui Kogumisteenusest saadetud allkirjastatud hääles ei ole kõiki hääli, mille kohta on kontrollkood, siis esitab Kontrollrakendus Hääletajale nende valimiste/küsimuste identifikaatorid ning vastavasisulise hoiatuse. Ülejäänud hääled kontrollitakse. #. Kui kontrollalgoritm lõpetab veateatega, siis juhendatakse Hääletajat Kliendituge informeerima. Järeltingimus ''''''''''''' Kui hääle kontrollimisega ületatakse lubatud kontrollimiste limiit, siis Kogumisteenus rohkem häält kontrollida ei võimalda. Kogumisteenuse Haldur - Kogumisteenuse seisundi kuvamine ```````````````````````````````````````````````````````` Päästik ''''''' Kogumisteenuse Haldur siseneb Kogumisteenuse Haldusteenusesse. Põhiprotsess '''''''''''' #. Haldusteenus autendib kasutaja ning tuvastab autenditud kasutaja volitused Haldusteenuses #. Vastavalt volituste määrale kuvab Kogumisteenus alamhulka järgmisest informatsioonist: #. Valimise identifikaator, küsimused, hääletusetapp #. Töötavad teenusserverid #. Laetud nimekirjad - ringkonnad, valijad, valikud #. Hääletamise statistika #. Kogumisteenuse volitatud kasutajad #. Kogumisteenuse tehniline logi Korraldaja - Hääletamise lõpetamine ``````````````````````````````````` Kirjeldus ''''''''' Hääletamise lõpetamine lõpetab häälte vastuvõtmise Kogumisteenuse poolt. Hääletamise lõpetamine toimub järk-järgult – Hääletajad, kes on saanud kandidaatide nimekirja enne hääletamise ametlikku lõppu, peavad saama mõistliku aja jooksul hääletada. Päästik ''''''' #. Valimise seadistustes näidatud hääletamise lõpetamise aeg jõuab kätte. #. Korraldaja edastab Haldusteenuse vahendusel digitaalallkirjastatud korralduse hääletamise lõpetamiseks. Põhiprotsess '''''''''''' 1. Kogumisteenus vastab kõigile kandidaatide nimekirjade päringutele veateatega, kuid jätkab häälte talletamispäringute teenindamist. 2. Kogumisteenus lõpetab korralduses/konfiguratsioonis näidatud aja möödudes häälte vastuvõtmise. 3. Kogumisteenus vastab kõigile Valijarakendustelt tulevatele päringutele veateatega. Järeltingimus ''''''''''''' Kogumisteenus ei võta enam uusi hääli vastu. Töötlusetapp ------------ Koguja - E-valimiskasti väljastamine ```````````````````````````````````` Kirjeldus ''''''''' Koguja ekspordib e-valimiskasti Kogumisteenuse andmebaasist. Eeltingimus ''''''''''' Elektrooniline hääletamine on lõpetatud. Päästik ''''''' Koguja valib Haldusteenusest e-valimiskasti eksportimise funktsionaalsuse. Põhiprotsess '''''''''''' #. Kogumisteenus teeb häälte andmebaasist väljavõtte, mis sisaldab kogu talletamisteenuses sisalduvat häältega seotud infot. Järeltingimus ''''''''''''' E-valimiskast on eksporditud. Töötleja - E-valimiskasti verifitseerimine `````````````````````````````````````````` Kirjeldus ''''''''' Töötleja verifitseerib Kogujalt saadud e-valimiskasti kooskõlalisust ning selle vastavust Registreerimisteenuselt saadud informatsioonile. Eeltingimus ''''''''''' - E-valimiskast on väljastatud - Registreerimiskinnitused on väljastatud Päästik ''''''' Töötleja käivitab vastava funktsionaalsuse Töötlemisrakenduse kasutajaliideses. Põhiprotsess '''''''''''' #. Töötlemisrakendus laadib seadistused #. Töötlemisrakendus kontrollib seadistuste digitaalallkirja #. Töötlamisrakendus kontrollib seadistuste kooskõlalisust #. Töötlemisrakendus laadib e-valimiskasti #. Töötlemisrakendus kontrollib e-häälte digitaalallkirja #. Töötlemisrakendus laadib registreerimiskinnitused #. Töötlemisrakendus verifitseerib registreerimiskinnitused #. Töötlemisrakendus kontrollib e-valimiskasti ja registreerimiskinnituste kooskõlalisust Laiendid '''''''' - Tehniliste vigade tekkimisel kõigis põhiprotsessi sammudes logitakse sündmus tehniliste vigade logisse. Kasutajale väljastatakse teade veasituatsiooni kohta ning protsess peatatakse. - Kasutajal on võimalus viia protsess läbi selliselt et vigadega seotud Hääletajad eraldatakse muust e-valimiskastist. Tulemuseks on probleemsete häälte raport ja puhastatud e-valimiskast. Järeltingimus ''''''''''''' E-valimiskasti verifitseerimise raport identifitseerib üheselt korrektsed ja probleemsed hääled. Töötleja - Elektrooniliselt hääletanute nimekirja koostamine ```````````````````````````````````````````````````````````` Kirjeldus ''''''''' Peale hääletamisperioodi lõppu koostab Töötleja valimisjaoskondade kaupa nimekirjad elektrooniliselt hääletanud isikutest. Nimekirjad on nii inim- kui masinloetavad. Eeltingimus ''''''''''' E-valimiskast on edukalt verifitseeritud. Päästik ''''''' Töötleja käivitab vastava funktsionaalsuse Töötlemisrakenduse kasutajaliideses. Põhiprotsess '''''''''''' 1. Töötlemisrakendus tühistab korduvad hääled, jättes iga Hääletaja kohta alles ajaliselt kõige viimasena antud hääle. 2. Töötlemisrakendus sorteerib kehtivad hääled valimisjaoskondade kaupa. 3. Töötlemisrakendus loob elektrooniliselt hääletanute nimekirjade faili. 1. Iga kehtiva hääle kohta lisab Töötlemisrakendus faili ühe kirje, kus sisaldub isikukood, nimi, valimisjaoskonna number ja rea number valimisringkonna nimekirjas. Andmed võetakse valijate nimekirjast. 4. Töötlemisrakendus esitab vastuvõetud häälte koguarvu ning elektrooniliselt hääletanute arvu. 5. Töötleja salvestab nimekirja välisele andmekandjale. Laiendid '''''''' Kui põhiprotsessi sammus 3 ei tuvastata isikukoodi valijate nimekirjast, siis logitakse vastavasisuline informatsioon ning jätkatakse põhiprotsessiga. Järeltingimus ''''''''''''' Kehtivad hääled on kantud e-hääletanute nimekirja. Korduvad hääled on tühistatud. Töötleja - Miksimisele/Lugemisele minevate e-häälte anonümiseerimine ```````````````````````````````````````````````````````````````````` Kirjeldus ''''''''' Töötleja rakendab tühistus- ja ennistusnimekirju ning loob lugemisele minevate e-häälte anonümiseeritud hulga. Eeltingimus ''''''''''' E-valimiskast on edukalt verifitseeritud ning elektrooniliselt hääletanute nimekiri koostatud. Päästik ''''''' Töötleja käivitab vastava funktsionaalsuse Töötlemisrakenduse kasutajaliideses. Põhiprotsess '''''''''''' Töötlemisrakendus verifitseerib tühistus- ja ennistusnimekirjade digitaalallkirjad. Töötlemisrakendus kontrollib tühistus- ja ennistusnimekirjade kooskõlalisust järjekorras. Töötlemisrakendus rakendab tühistus- ja ennistusnimekirju järjekorras. Töötlemisrakendus koostab miksimisele/lugemisele minevate häälte nimekirja eraldades krüptogrammid digitaalallkirjadest. Töötlemisrakendus väljastab lõpliku elektrooniliselt hääletanute nimekirja masinloetavas vormingus. Laiendid '''''''' - Kui põhiprotsessi sammus 1 Korraldaja allkirja verifitseerimine või volituse kontroll ebaõnnestuvad, siis väljastatakse veateade Ühtegi muudatust ei rakendata. Järeltingimus ''''''''''''' Miksimisele/lugemisele minevate häälte hulk on koostatud, elektrooniliselt hääletanute nimekiri on väljastatud. Miksija - Miksimine ``````````````````` Kirjeldus ''''''''' Eeltingimus ''''''''''' Päästik ''''''' Põhiprotsess '''''''''''' #. Miksija käivitab Miksimisrakenduse ning laadib anonüümistatud e-hääled #. Miksimisrakendus rerandomiseerib ning permuteerib e-hääled, tulemuseks on uued e-hääled #. Miksimisrakendus genereerib tõestuse, et uued e-hääled on algsete e-häältega sisuliselt samaväärsed #. Miksimisrakendus väljastab nii miksitud hääled kui Miksimistõendi Laiendid '''''''' Järeltingimus ''''''''''''' Algsete häältega tõestatavalt samaväärsed, miksitud hääled on väljastatud. Lugemisetapp ------------ Lugeja - Elektroonilise hääletamise tulemuse kindlaks tegemine `````````````````````````````````````````````````````````````` Kirjeldus ''''''''' Tühistusperioodi lõppedes sorteeritakse ümbrikud valimisringkondade kaupa. Välised ümbrikud avatakse. s.t. digitaalallkirjad eemaldatakse, järgi jäävad häälte salastamise võtmega krüpteeritud hääled, mis dekrüpteeritakse Võtmerakendusega. Põhiprotsess '''''''''''' #. Lugeja algatab häälte kokku lugemise Võtmerakendusega. #. Võtmehaldurid aktiveerivad vastavalt võtmehalduse protseduuridele häälte avamise võtme. #. Võtmerakendus loeb krüpteeritud hääled väliselt andmekandjalt. #. Võtmerakendus teostab häältefaili tehnilise kontrolli ning algatab häälte krüpteerimise. #. Võtmerakendus kontrollib dekrüpteeritud hääle vastavust avakujul hääle vormingule. #. Võtmerakendus kontrollib hääle kehtivust, veendudes et dekrüpteerimisel selgunud kandidaat kuulus antud ringkonnas valikute hulka. #. Võtmerakendus summeerib arvesse minevad hääled jaoskondade, ringkondade ja kandidaatide kaupa. #. Võtmerakendus kannab hääletamistulemuse andmekandjale. #. Hääletamistulemus imporditakse valimiste infosüsteemi. Laiendid '''''''' - Tehniliste vigade tekkimisel kõigis põhiprotsessi sammudes logitakse sündmus tehniliste vigade logisse. Kasutajale väljastatakse teade veasituatsiooni kohta ning protsess peatatakse. - Põhiprotsessi sammudes 4 ja 5 tehtavate kontrollide ebaõnnestumise korral loetakse antud hääl kehtetuks ning protsessi jätkatakse järgmise krüpteeritud hääle juurest. Järeltingimus ''''''''''''' Hääletamistulemus on sisestatud valimiste infosüsteemi. Auditeerimisetapp ----------------- Audiitor - Auditeerimine ```````````````````````` Kirjeldus ''''''''' Peale hääletamistulemuse väljaselgitamist on Audiitoril võimalik kontrollida Miksimistõendit ja Lugemistõendit. Eeltingimus ''''''''''' - Hääletamistulemus, krüptogrammid ning lugemistõend on olemas - Miksimiseelsed krüptogrammid, miksimisjärgsed krüptogrammid ning miksimistõend on olemas Põhiprotsess '''''''''''' 1. Audiitor kasutab Auditirakendust Lugemistõendi kontrollimiseks 2. Audiitor kasutab Auditirakendust Miksimistõendi kontrollimiseks Laiendid '''''''' Järeltingimus ''''''''''''' Lugemistõend ja Miksimistõend on kontrollitud. Tehnilised kasutusmallid ------------------------ Autentimine Valijarakenduses ```````````````````````````` Kirjeldus ''''''''' Valijarakenduse vahendusel ja elektroonilise isikutunnistuse abil tuvastab Kogumisteenus Hääletaja isiku. Päästik ''''''' Kasutusmall käivitatakse kui Hääletaja käivitab Valijarakenduse ning suundub hääletama. Põhiprotsess – ID kaart ''''''''''''''''''''''' 1. Hääletaja sisestab ID-kaardi lugejasse. 2. Valijarakendus pöördub Kogumisteenuse poole protokolli algatamiseks. 3. Kogumisteenus saadab Valijarakendusele oma sertifikaadi. 4. Valijarakendus kontrollib Kogumisteenuse sertifikaati. 5. Kogumisteenus nõuab Hääletaja autentimist TLS-protokolli kohaselt. 6. Valijarakendus küsib valijalt ID-kaardi autentimisvõtme kasutamiseks PIN1 koodi. 7. Hääletaja sisestab PIN1 koodi. 8. Valijarakendus ja Kogumisteenus viivad läbi TLS-protokolli, Kogumisteenuse saadetakse Hääletaja sertifikaat. 9. Kogumisteenus kontrollib Hääletaja sertifikaati. 10. Kogumisteenus tuvastab Hääletaja isikukoodi. Põhiprotsess – Mobiil-ID '''''''''''''''''''''''' 1. Hääletaja sisestab Valijarakendusse oma Mobiil-ID SIM kaarti sisaldava mobiiltelefoni numbri. 2. Valijarakendus pöördub Kogumisteenuse poole protokolli algatamiseks. 3. Kogumisteenus saadab Valijarakendusele oma sertifikaadi. 4. Valijarakendus kontrollib Kogumisteenuse sertifikaati. 5. Valijarakendus saadab telefoninumbri Kogumisteenusele. 6. Kogumisteenus algatab autentimise Mobiil-ID teenuse kaudu. 7. Kogumisteenus saadab Mobiil-ID kontrollkoodi Valijarakendusele, mis kuvab seda valijale. 8. Hääletaja saab mobiiltelefonile autentimissõnumi. 9. Hääletaja võrdleb autentimissõnumi kontrollkoodi Valijarakenduses kuvatavaga. 10. Hääletaja sisestab autentimisvõtme kasutamiseks PIN1 koodi. 11. Kogumisteenus ja Mobiil-ID teenus viivad läbi autentimise, Kogumisteenuse saadetakse Hääletaja sertifikaat. 12. Kogumisteenus kontrollib Hääletaja sertifikaati. 13. Kogumisteenus tuvastab Hääletaja isikukoodi. 14. Valijarakendus küsib regulaarselt, kas autentimine on toimunud, Kogumisteenus vastab. Laiendid '''''''' - Kui ID-kaarti ei ole lugejas, siis katkestab Valijarakendus töö veateatega (ID-kaart). - Kui Kogumisteenus ei ole kättesaadav, siis katkestab Valijarakendus töö veateatega. - Kui Kogumisteenuse sertifikaadi kehtivust ei õnnestu kontrollida või kui sertifikaat ei vasta Kogumisteenuse nimele, siis katkestab Valijarakendus töö veateatega. - Kui ID-kaardi kasutamine ebaõnnestub, siis katkestab Valijarakendus töö veateatega. (ID-kaart) - Kui Kogumisteenuses annab Hääletaja sertifikaadi kontroll negatiivse tulemuse, siis saadetakse Valijarakendusele veateade ning autentimine katkestatakse. - Kui Mobiil-ID protokolli läbiviimine ebaõnnestub, siis vastab Kogumisteenus Valijarakenduse päringule veateatega ning autentimine katkestatakse. (Mobiil-ID) Järeltingimus ''''''''''''' Kogumisteenus teab Hääletaja sertifikaati ning on tuvastanud sellest isikukoodi. Digitaalne allkirjastamine Valijarakenduses ``````````````````````````````````````````` Kirjeldus ''''''''' Valijarakenduse abil antakse digitaalallkirja vahendi abil krüpteeritud häälele digitaalallkiri. Eeltingimus ''''''''''' Hääletaja on teinud oma valikud ja kinnitanud need. Valijarakendus on valikud krüpteerinud Kogumisteenuse avaliku võtmega. Mobiil-ID korral teab Kogumisteenus juba Hääletaja Mobiil-ID SIM kaardiga mobiiltelefoninumbrit, kuna autentimine on edukalt toimunud. Päästik ''''''' Hääletaja on valinud Valijarakenduses hääletamise funktsionaalsuse, kõik valikud on krüpteeritud Kogumisteenuse avaliku võtmega. Põhiprotsess – ID-kaart ''''''''''''''''''''''' 1. Valijarakendus moodustab BES vormingus BDOC konteineri. 2. Valijarakendus lisab konteinerisse andmefailidena krüpteeritud valikud. 3. Valijarakendus moodustab allkirjastatava räsi BDOC standardi kohaselt. 4. Valijarakendus algatab räsi signeerimise ID-kaardiga. 5. Hääletaja sisestab PIN2 koodi allkirjastamisvõtme kasutamiseks. 6. Valijarakendus lisab Hääletaja signatuuri ja allkirjastamissertifikaadi BDOC konteinerile. Põhiprotsess – Mobiil-ID '''''''''''''''''''''''' 1. Valijarakendus moodustab BES vormingus BDOC konteineri. 2. Valijarakendus lisab konteinerisse andmefailidena krüpteeritud valikud. 3. Valijarakendus saadab konteineri Kogumisteenusele. 4. Kogumisteenus moodustab allkirjastatava räsi BDOC standardi kohaselt. 5. Kogumisteenus algatab räsi signeerimise Mobiil-ID teenusega. 6. Kogumisteenus saadab Mobiil-ID kontrollkoodi Valijarakendusele, mis kuvab seda valijale. 7. Hääletaja saab mobiiltelefonile allkirjastamissõnumi. 8. Hääletaja võrdleb allkirjastamissõnumi kontrollkoodi Valijarakenduses kuvatavaga. 9. Hääletaja sisestab allkirjastamisvõtme kasutamiseks PIN2 koodi. 10. Kogumisteenus ja Mobiil-ID teenus viivad läbi allkirjastamise, Kogumisteenuse saadetakse digitaalselt allkirjastatud ja kehtivuskinnitusega TS vormingus BDOC konteiner. 11. Valijarakendus küsib regulaarselt, kas allkirjastamine on toimunud, Kogumisteenus vastab. 12. TS vormingus BDOC konteiner edastatakse Valijarakendusele verifitseerimiseks. Laiendid '''''''' - Kui ID-kaarti ei ole lugejas, siis katkestab Valijarakendus töö veateatega (ID-kaart). - Kui Kogumisteenus ei ole kättesaadav, siis katkestab Valijarakendus töö veateatega. - Kui ID-kaardi kasutamine ebaõnnestub, siis katkestab Valijarakendus töö veateatega. (ID-kaart) - Kui Mobiil-ID protokolli läbiviimine ebaõnnestub, siis vastab Kogumisteenus Valijarakenduse päringule veateatega ning allkirjastamine katkestatakse. (Mobiil-ID) Järeltingimus ''''''''''''' Hääletaja hääl on digitaalselt allkirjastatud. Digitaalallkirja kehtivuse kontroll Kogumisteenuses ``````````````````````````````````````````````````` Kirjeldus ''''''''' Kogumisteenus kontrollib digitaalallkirju ID-kaardi ja Mobiil-ID'ga allkirjastatud e-häältel ning seadistamisel ja tühistamisel kasutatavatel sisendfailidel. Eeltingimus ''''''''''' Kogumisteenusede sertifikaatide konfiguratsioon on tehtud. Kogumisteenuse kehtivuskinnitusteenuse konfiguratsioon on tehtud. Päästik ''''''' Kogumisteenus algatab digitaalallkirja kehtivuse kontrolli. Põhiprotsess '''''''''''' 1. Kogumisteenus tuvastab profiili, millest lähtudes kontroll läbi viia: 1. ID-kaardiga allkirjastatud hääl võib olla BES või TS vormingus, tohib sisaldada mitut andmefaili ja täpselt ühte allkirja. 2. Mobiil-ID'ga allkirjastatud hääl peab olema TS vormingus, tohib sisaldada mitut andmefaili ja täpselt ühte allkirja. 3. Muud failid peavad olema TS vormingus, tohivad sisaldada täpselt ühte andmefaili ja täpselt ühte allkirja. 2. Kogumisteenus veendub allkirja vastavuses nõutud profiilile. 3. Kui allkiri on BES vormingus, siis pöördub Kogumisteenus kehtivuskinnitusteenuse poole sertifikaadi kehtivuse kontrolliks. Kogumisteenus liidab kehtivuskinnituse digitaalallkirjale, tulemuseks on TS vormingus allkiri. 4. Kogumisteenus kontrollib TS vormingus allkirja: 1. Signatuuri. 2. Sertifikaadi kehtivuskinnitust. Laiendid '''''''' - Tehniliste vigade tekkimisel kõigis põhiprotsessi sammudes logitakse sündmus tehniliste vigade logisse. Välja kutsuvale protsessile väljastatakse teade veasituatsiooni kohta. - Kehtivuskinnituse laadimise ebaõnnestumisel põhiprotsessi sammus 3 logitakse sündmus tehniliste vigade logisse. Välja kutsuvale protsessile väljastatakse teade veasituatsiooni kohta. - Kontrollide ebaõnnestumisel põhiprotsessi sammus 4 logitakse sündmus tehniliste vigade logisse. Välja kutsuvale protsessile väljastatakse teade veasituatsiooni kohta. Valikute nimekirjade väljastamine Valijarakendusele ``````````````````````````````````````````````````` Kirjeldus ''''''''' Kogumisteenus väljastab Valijarakendusele valikute nimekirja. Eeltingimus ''''''''''' Hääletaja autentimine on õnnestunult toimunud. Päästik ''''''' Valijarakendus on pöördunud Kogumisteenuse poole valikute nimekirja alla laadimiseks. Põhiprotsess '''''''''''' 1. Kogumisteenus kontrollib isikukoodi kasutades, millisesse valimisringkonda Hääletaja kuulub. 2. Kogumisteenus kontrollib, kas Hääletaja kohta on juba mõni hääl talletatud. 3. Kogumisteenus saadab Valijarakendusele ringkonnakohase kandidaatide nimekirja kõigi valimise kohta, kus isikukood on nimekirja kantud ning informatsiooni võimaliku korduvhääletamise kohta. Laiendid '''''''' - Tehniliste vigade tekkimisel kõigis põhiprotsessi sammudes logitakse sündmus tehniliste vigade logisse. Valijarakendust teavitatakse protsessi ebaõnnestumisest. - Kui põhiprotsessi sammus 2 on selge, et Hääletaja ei kuulu käimasoleva valimise valijate nimekirja, siis saadetakse Valijarakendusele vastavasisuline veateade. Hääle talletamine Kogumisteenuses ````````````````````````````````` Kirjeldus ''''''''' Kogumisteenus talletab Hääletaja hääle. Eeltingimus ''''''''''' Hääle digitaalne allkirjastamine Valijarakenduses on edukalt toimunud. Päästik ''''''' Valijarakendus on saatnud hääle talletamisele. Põhiprotsess '''''''''''' 1. Kogumisteenus kontrollib hääle digitaalallkirja (tehniline kasutusmall Digitaalallkirja kehtivuse kontroll Kogumisteenuses). Kontrolli käigus tagatakse muu hulgas kehtivuskinnituse lisamine allkirjale. 2. Kogumisteenus kontrollib hääle allkirjastanud ja valikute nimekirja laadimisel TLS protokollis autenditud isikukoodide samasust. 3. Kogumisteenus registreerib hääle vastuvõtmise Registreerimisteenuses. 4. Kogumisteenus genereerib häälega seostatud unikaalse identifikaatori. 5. Kogumisteenus salvestab hääle koos unikaalse identifikaatoriga. 6. Kogumisteenus tagastab Valijarakendusele õnnestumise teate koos häälele viitava unikaalse identifikaatoriga ja Registreerimisteenuse kinnitusega Laiendid '''''''' - Tehniliste vigade tekkimisel kõigis põhiprotsessi sammudes logitakse sündmus tehniliste vigade logisse. Valijarakendust teavitatakse protsessi ebaõnnestumisest. Häält ei talletata. - Kui põhiprotsessi sammus 1 digitaalallkirja kontroll ebaõnnestub, siis logitakse sündmus tehniliste vigade logisse. Valijarakendust teavitatakse protsessi ebaõnnestumisest. Häält ei talletata. - Kui põhiprotsessi sammus 2 isikukoodid erinevad, siis logitakse sündmus tehniliste vigade logisse. Valijarakendust teavitatakse protsessi ebaõnnestumisest. Häält ei talletata. Järeltingimus ''''''''''''' Digitaalselt allkirjastatud hääl on varustatud kehtivuskinnitusega, Kogumisteenuse poolse kinnitusega ning talletatud Kogumisteenuses seostatuna unikaalse identifikaatoriga. Hääle väljastamine kontrollimiseks Kogumisteenusest ``````````````````````````````````````````````````` Kirjeldus ''''''''' Kogumisteenus väljastab Kontrollrakendusele kontrollimiseks allkirjastatud hääle ja registreerimiskinnituse. Päästik ''''''' Kontrollrakendus on esitanud Kogumisteenusele unikaalse identifikaatoriga hääle kontrollimise päringu. Põhiprotsess '''''''''''' 1. Kogumisteenus kontrollib, kas unikaalsele identifikaatorile vastab elektrooniline hääl. 2. Kogumisteenus kontrollib, kas unikaalsele identifikaatorile vastava hääle kontrollimine on veel võimalik vastavalt aja ja kordade tingimustele. 3. Kogumisteenus suurendab konkreetse hääle kontrollimise kordade loendurit. 4. Kogumisteenus väljastab Kontrollrakendusele unikaalse identifikaatori poolt viidatud hääle koos ringkonna valikute nimekirjaga ning häälele vastava registreerimiskinnitusega. Laiendid '''''''' - Tehniliste vigade tekkimisel kõigis põhiprotsessi sammudes logitakse sündmus tehniliste vigade logisse. Kontrollrakendust teavitatakse protsessi ebaõnnestumisest. Häält ei väljastata. - Kui põhiprotsessi sammus 1 ei leita unikaalsele identifikaatorile vastavat häält, siis logitakse sündmus tehniliste vigade logisse. Kontrollrakendust teavitatakse protsessi ebaõnnestumisest. Häält ei väljastata. - Kui põhiprotsessi sammus 2 tehtavad kontrollid annavad negatiivse tulemuse, siis logitakse sündmus tehniliste vigade logisse. Kontrollrakendust teavitatakse protsessi ebaõnnestumisest. Häält ei väljastata. Elektrooniliste häälte avalduse alusel tühistamine/ennistamine `````````````````````````````````````````````````````````````` Kirjeldus ''''''''' Korraldaja poolt kinnitatud digitaalallkirjastatud tühistus-/ennistuskannete faili import Töötleja poolt. Töötlemisrakendus teostab tühistused/ennistused, logides tegevused. Töötlejale kuvatakse tühistamise/ennistamise tulem – aruanne tühistustest/ennistustest koos tulemusega. Päästik ''''''' Töötlemisrakendus käivitab vastava funktsionaalsuse. Põhiprotsess '''''''''''' #. Töötlemisrakendus verifitseerib avalduse digitaalallkirja. #. Töötlemisrakendus kontrollib, et avaldus oleks allkirjastatud volitatud kasutaja poolt. #. Töötlemisrakendus loeb failist kandeid ning viib operatsioonid täide märkides hääle kas tühistatuks või ennistatuks. #. Kogumisteenus kuvab avalduse rakendamise tulemusi. Laiendid '''''''' - Kui põhiprotsessi sammus 1 tuvastatakse digitaalallkirja mittekehtivus, siis logitakse tehniliste vigade logisse vastav kanne ning protsess peatatakse. - Kui põhiprotsessi sammus 2 tuvastatakse, et avalduse allkirjastajal ei ole vastavaid volitusi, siis logitakse tehniliste vigade logisse vastav kanne ning protsess peatatakse. - Kui põhiprotsessi sammus 3 tuvastatakse, et isikukoodiga identifitseeritud Hääletaja hääl on mittesobivas olekus või Hääletaja ei ole hääletanud, siis logitakse aruandesse vastav kanne ning protsessi jätkatakse järgmise kandega. - Tehniliste vigade tekkimisel kõigis põhivoo sammudes logitakse sündmus tehniliste vigade logisse. Kasutajale väljastatakse teade veasituatsiooni kohta ning protsess peatatakse. Järeltingimus ''''''''''''' Tühistatud hääled ei lähe lugemisele, ennistatud hääled lähevad lugemisele. ================================================ FILE: Documentation/et/kasutusmall/sissejuhatus.rst ================================================ .. IVXV kasutusmallid Sissejuhatus ============ Dokument kirjeldab elektroonilise hääletamise süsteemi kasutusmallimudeli. Dokument on jaotatud kaheks osaks: tegijad ja kasutusmallid. Esimeses osas on kirjeldatud kasutusmallimudeli tegijad. Teises osas on kirjeldatud elektroonilise hääletamise süsteemi kasutusmallid. Viited ------ 1. [UML] – UMLi kontsentraat. Objektmodelleerimise standardkeele UML 2.0 lühijuhend. Martin Fowler. Cybernetica AS. Kasutatud metoodika ------------------- Kasutusmallimudel ````````````````` Kasutusmallid on abivahend, mis aitab aru saada süsteemi talitlusnõuetest. Kasutusmallid esitavad süsteemi välisvaate kirjeldades süsteemi kasutajate ja süsteemi vahelisi interaktsioone kasutajate eesmärkide täitmiseks. Kasutusmallimudel koondab endas kõik analüüsitava süsteemi olulised kasutusmallid [UML]. Tegija `````` Tegija on roll, mida kasutaja mängib süsteemi suhtes. Tegija ei pea olema inimene. Kui modelleeritav süsteem annab mingit teenust teisele arvutisüsteemile, on see teine süsteem tegija. Kasutusmall ``````````` Kirjeldus ''''''''' Kasutusmall on kogum stsenaariume, mida omavahel ühendab ühine kasutaja eesmärk. Iga stsenaarium on süsteemis tehtavate toimingute jada, mis annab tegijale nähtava ja kasuliku tulemuse. Eeltingimus ''''''''''' Eeltingimus kirjeldab tingimusi, mille täidetuse peab süsteem tagama, enne kui ta laseb alustada kasutusmalli täitmist. Päästik ''''''' Päästik spetsifitseerib sündmuse, mis käivitab kasutusmalli. Põhiprotsess '''''''''''' Põhiprotsess kirjeldab kasutusmalli peastsenaariumi. Laiendid '''''''' Laiend kasutusmallis nimetab oleku, mis tuleneb teistsugustest interaktsioonidest kui need, mis on kirjeldatud õnnestumise peastsenaariumis, ja ütleb, millised on need erinevused. Järeltingimus ''''''''''''' Järeltingimuse täidetus garanteeritakse süsteemi poolt kasutusmalli täitmise lõpus. E-hääletamise etapid -------------------- E-hääletamine jaguneb korralduslikult viieks etapiks: - hääletamiseelne etapp - hääletamisetapp - töötlusetapp - lugemisetapp - auditeerimisetapp Mõisted ------- Mõiste *isik* võib tähistada nii füüsilist kui juriidilist isikut. Eeldame, et konkreetsete toimingute läbiviija on alati üheselt indentifitseeritav füüsiline isik, kes võib tegutseda juriidilise isiku volitatud esindajana. Mõiste *serverisüsteem* tähistab terviklikku kogumit tarkvaralisi ja riistvaralisi komponente, mis koostoimes realiseerivad konkreetset protokolli ning osutavad pikema aja vältel teenust paljudele kasutajatele. Mõiste *liides* tähistab selgelt spetsifitseeritud kokkupuutepunkti süsteemi komponentide vahel, mis võimaldab komponentide vahelist infovahetust. Mõiste *rakendus* tähistab tarkvaralist komponenti, mida käivitatakse konkreetsel ajahetkel ühel riistvaralisel komponendil ühe kasutaja poolt. Rakendus võib oma ülesande täitmiseks suhelda servrisüsteemiga. Mõiste *teenus* tähistab süsteemivälist komponenti, millega süsteem oma ülesannete täitmiseks konkreetsete liideste kaudu andmeid vahetab. ================================================ FILE: Documentation/et/kasutusmall/tegijad.rst ================================================ .. IVXV kasutusmallid Tegijad ======= Korraldaja ---------- *Korraldaja* on isik, kes korraldab valimisi mille raamides elektroonilise hääletamise süsteemi kasutatakse. Korraldaja määrab elektroonilise hääletamise seadistuse, sealhulgas kõik ülejäänud rollitäitjad. Korraldaja haldab Kogumisteenust sisuliselt. Korraldaja tegeleb hääletamiseelsel etapil valijate, valimisjaoskondade, ringkondade ja valikute- kandidaatide (valimistel) või vastusevariantide (rahvahääletusel) nimekirja koostamise ja/või kinnitamisega. Korraldaja loob ja/või kinnitab Valimisrakenduse ning Kontrollrakenduse seadistused. Korraladaja tegeleb hääletamisetapil valijate nimekirjade täiendamise ja/või täienduste kinnitamisega. Korraldaja tegeleb töötlusetapil e-häälte tühistamis- ja ennistamisavalduste koostamise ja/või kinnitamisega. Korraldaja võib täita ka elektroonilise hääletamise põhiprotsesside toimimisega seotud konkreetseid rolle. Näiteks hoiab Korraldaja tavajuhtumitel ka e-hääletamise süsteemi põhisaladust – häälte avamise võtit ning seega täidab ta ka häälte avaja ja summeerija ehk Lugeja rolli. Hääletaja --------- *Hääletaja* on isik, kes kasutab elektroonilise hääletamise süsteemi hääletamisetapil - hääletamiseks Valijarakendusega, - hääle kontrollimiseks Kontrollrakendusega. Hääletajal on elektrooniline isikutunnistus – ID-kaart, Mobiil-ID, Smart-ID või Web eID. Koguja ------ *Koguja* on isik, kes haldab Kogumisteenust, Valijarakendust ja Kontrollrakendust tehniliselt. *Kogumisteenus* on serverisüsteem, mis tuvastab hääleõiguslikkust Tuvastusteenuse abil, väljstab kandidaatide nimekirja, aitab Valijarakendusel Allkirjastamisteenuse abil e-häält moodustada, talletab hääli e-valimiskasti ning registreerib neid Registreerimisteenuses. Kogumisteenus vastab Kontrollrakenduse poolt tehtud hääle tervikluse kontrollpäringutele. *Kogumisteenuse Haldur* on kas Korraldaja, Koguja või Klienditugi. Koguja on Kogumisteenuse tehniline haldur. Kogumisteenuse sisuline haldur on Korraldaja. Kogumisteenus pakub informatiivset liidest Klienditoele. *Haldusteenus* on teenus, mida Kogumisteenuse Haldur kasutab Kogumisteenuselt informatsiooni saamiseks või Kogumisteenusele korralduste edastamiseks. *Valijarakendus* on rakendus, mida Hääletaja kasutab e-hääle andmiseks käimasolevatel valimistel. Valijarakendus suhtleb Kogumisteenusega ning võimaldab Hääletajal teha valikut, seda krüpteerida ja digitaalselt allkirjastada. Valijarakendus kuvab QR-koodi, mille alusel saab Hääletaja Kontrollrakendusega kontrollida e-hääle korrektset jõudmist Kogumisteenusesse. Koguja valmistab kompileeritud valijarakendusest ette seadistatud valijarakenduse, mis allkirjastatakse ja levitatakse valijateni. *Kontrollrakendus* on rakendus, mis võimaldab Hääletajal arvutist erineval nutiseadme platvormil veenduda, et tema e-hääl jõudis Kogumisteenusesse ja Registreermisteenusesse ning väljendas tema tahet korrektselt. Koguja seadistab kontrollrakenduse selliselt, et too on võimeline võrgust tegelikke seadistusi laadima ning allkirjastab kontrollrakenduse. Koguja on Valijarakenduse ja Kontrollrakenduse tehniline haldur, sisuline haldur on Korraldaja. Koguja poolt täidetavad põhiprotsessid leiavad aset hääletamisetapil, alustavad ning lõpetavad tegevused toimuvad nii hääletamiseelsel kui töötlusetapil. Koguja digiallkirjastab hääletamisperioodi lõpul Töötlejale üle antavad andmed (e-hääled ja logid). Töötleja -------- *Töötleja* on isik, kes kasutades Töötlemisrakendust töötleb töötlusetapil hääletamisperioodil kogutud e-hääli: - kontrollib digitaalallkirju ja Kogujalt saadud andmete täielikkust, - tühistab korduvad e-hääled ning paralleelhääletamise kasutamisel ka nende Hääletajate e-hääled, kes hääletasid jaoskonnas eelhääletamise ajal, - anonüümistab e-hääled, eemaldades nendelt isikulised digitaalallkirjad, olles eelnevalt need sorteerinud ringkondade kaupa Töötleja võib e-hääli täiendavalt krüptograafiliselt anonüümistada kasutades Miksimisrakendust. *Töötlemisrakendus* on rakendus, mille abil kontrollitakse häälte individuaalset terviklust ja e-valimiskasti terviklust, tühistatakse hääli, väljastatakse hääletanute nimekirju ning ringkondade kaupa rühmitatud anonüümistatud hääli. Töötlemisrakenduse sisendi annavad Koguja, Registreerimisteenus ja Korraldaja. Töötlemisrakendust võib käitada ka Audiitor Töötleja töötulemuste kontrollimiseks. Miksija ------- *Miksija* on isik, kes töötlusetapil anonüümistab e-hääled krüptograafiliselt kasutades Miksimisrakendust. *Miksimisrakendus* on rakendus, mille sisendiks on ringkondade kaupa rühmitatud anonüümistatud krüpteeritud hääled ning mis väljastab krüptograafiliselt segatud hääled selliselt, et neid ei ole võimalik sisendiga vastavusse viia. Miksimine toimub sellisel moel, et nii sisend- kui ka väljundhäälte dekrüpteerimine ja tulemi summeerimine annab sama resultaadi. Miksimirakendus väljastab lisaks segatud häältele miksimistõendi, mis kinnitab sisend- ja väljundhäälte semantilist samaväärsust. Lugeja ------ *Lugeja* on isik, kes kasutades Võtmerakendust - hääletamiseelsel etapil genereerib häälte salastamise ja avamise võtme, - lugemisetapil avab krüpteeritud hääled ning summeerib need e-hääletamise tulemusteks. Lugeja võib toimetada ainuisikuliselt, üldjuhul kaitstakse e-hääletamise salastamise võti läviskeemiga, kus ühe tervikvõtme asemel luuakse mitu võtmeosakut ning võtmeoperatsioonid on teostatavad ainult teatud kvoorumi võtmeosakute osavõtul. Sellisel juhul assisteerivad Lugejat Võtmehaldurid. *Võtmehaldur* on isik, kelle ülesandeks on talle usaldatud võtmeosaku alalhoidmine ning selle andmine Lugeja käsutusse ainult siis kui selleks on seaduslik alus. *Võtmerakendus* on rakendus, millega genereeritakse iga hääletamise jaoks häälte salastamise ja häälte avamise võti. Võtmerakenduse abil toimub ka häälte lugemine ja tulemuse väljastamine. Audiitor -------- *Audiitor* on isik, kes auditeerimisetapil kontrollib süsteemi kirjelduse ja Korraldaja poolt avaldatud süsteemi kesksete osapoolte vahel liikunud andmete põhjal andmete terviklust ning kooskõlalisust. Audiitor kasutab oma töös Auditirakendust. Kui Audiitor kontrollib ka Töötleja toimimise korrektsust, siis kasutab Audiitor ka Töötlemisrakendust. *Auditirakendus* on rakendus mis võimaldab kontrollida Lugeja ja Miksija töö korrektsust. Lugeja töö korrektsust on võimalik kontrollida ka avalikult. Klienditugi ----------- *Klienditugi* on isik, kelle poole Hääletaja hääletamisetapil probleemide korral pöördub. Klienditugi abistab Kogumisteenusest saadud info abil Hääletajat probleemide lahendamisel. Tuvastusteenus -------------- *Tuvastusteenus* on teenus, mida kasutatakse vajadusel hääletaja identiteedi tuvastamiseks. Allkirjastamisteenus -------------------- *Allkirjastamisteenus* on teenus, mida kasutatakse vajadusel hääle allkirjastamisel ja sellele kehtivuskinnituse saamisel. Vajadus Allkirjastamisteenuse järele sõltub allkirja andmise vahendist - Mobiil-ID, Smart-ID, Web eID ja ID-kaardi korral on nende teenuste ülesehitus erinev. Registreerimisteenus -------------------- *Registreerimisteenus* on teenus, mille abil Kogumisteenus peab registreerima kõik Valijarakendustelt saadud hääled. Pärast hääletamisperioodi lõppu edastab teenuseosutaja info registreeritud häälte kohta Töötlejale. ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/Makefile ================================================ include ../../common.mk ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/algseadistamine.rst ================================================ .. IVXV kogumisteenuse haldusjuhend Süsteemi algseadistamine ======================== Süsteemi algseadistamine tähendab süsteemi paigaldamist ning seadistamist läbiviidavate valimiste tarbeks. .. _nouded-platvormile: Nõuded kasutatavale platvormile ------------------------------- Kogumisteenus töötab platvormil ``Ubuntu 20.04 LTS (Focal Fossa)``. Väliste teenuste kaardistamine ------------------------------ Kogumisteenuse poolt toetatavate ja läbiviidavas hääletamises kasutatavate väliste teenuste (Mobiil-ID, Smart-ID, OCSP jms) kaardistamise käigus koostatakse nimekiri välistest teenustest ja nendega andmevahetuseks vajalikest andmetest (võrguaadress, port jms). Väliste teenuste andmed on sisendiks kogumisteenuse tehnilise seadistuse koostamisel (:ref:`seadistuste_koostamine`). Väliste teenuste kaardistamise tulemusena on kogumisteenuse osutajal olemas nimekiri kogumisteenuse poolt kasutatavatest välistest teenustest koos teenuste kasutamiseks vajalike parameetritega. Tugiteenuste ettevalmistamine ----------------------------- Kogumisteenuse tugiteenusteks on: #. Tehnilise seire teenus; #. Logiseire teenus; #. Varundusteenus. Tehnilise seire ettevalmistamine ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. important:: Kogumisteenuse osutaja peab kogumisteenuse töötamiseks eraldatud riistvara jälgimiseks läbi viima riistvara tehnilist seiret. Tehnilise seire teenus on `Zabbix `_ tarkvaral põhinev seire- ja teavitussüsteem. Zabbix serveri paigaldab ja seadistab kogumisteenuse osutaja iseseisvalt. Tehnilisse seiresse võib hõlmata ka kogumisteenuse tarkvaralisi komponente nagu kirjeldatud lõigus ":ref:`etcd-zabbix`". Seire toimimiseks on tarvis määrata seire eest vastutavad isikud ning tagada nende vahetu teavitamine seireprogrammi poolt avastatud kõrvalekalletest. Lisaks standardsele tehnilisele seirele (teenusmasinate protsessori-/kettakasutus jms.) viib kogumisteenuse haldusteenus läbi alamteenuste seiret ja teavitab tehnilise seire serverit avastatud kõrvalekalletest. .. todo:: Lisada haldusteenusele tehnilise seire teavituste tugi! Tehnilise seire ettevalmistamise tulemusena on kogumisteenuse osutajal olemas tehnilise seire server, kuhu on paigaldatud seiretarkvara ning kus on kirjeldatud tehnilise seire eest vastutavad isikud ja nende teavitamise meetodid. Logiseire ettevalmistamine ^^^^^^^^^^^^^^^^^^^^^^^^^^ Logiseire teenus koosneb rsyslog logiserverist koos analüüsi- ja visualiseerimistarkvaraga (Log Monitor, `Grafana `_). Logiseire ettevalmistamine ja integreerimine kogumisteenusega on kirjeldatud dokumendis ``IVXV tegevuslogi seirelahendus``. Logiseire ettevalmistamise tulemusena on kogumisteenuse osutajal olemas logiseire server, kuhu on paigaldatud logiseire tarkvara ning kus on kirjeldatud logiseire andmetele ligipääsevad isikud. Varunduse ettevalmistamine ^^^^^^^^^^^^^^^^^^^^^^^^^^ Varundusteenus on kogumisteenuse osutaja poolt paigaldatud ja seadistatud varundusserver, mis vastutab kogumisteenuse sisemises varundusserveris koostatud varukoopiate säilimise eest. Varunduse ettevalmistamise tulemusena on kogumisteenuse osutajal olemas varundusserver, mis on suuteline kogumisteenuse varundusliidese kaudu andmeid varundama. .. _seadistuste_koostamine: Kogumisteenuse seadistuste koostamine ------------------------------------- Kogumisteenuse seadistused koosnevad kolmest eraldiseisvast osast: #. **Usaldusjuure seadistus** sisaldab andmed seadistuste (kaasa arvatud usaldusjuure enda) allkirjade kontrollimiseks ja nimekirja kogumisteenuse haldurite volitustest. #. **Kogumisteenuse tehniline seadistus** määrab kogumisteenuse tehnilised parameetrid, hääletuse läbiviimiseks kasutatavad teenused, samuti ka kogumisteenuse koosseisu kuulvad alamteenused. #. **Valimiste seadistus** määrab ühe valimise seadistuse. Seadistuste koostamine on kirjeldatud dokumendis IVXV-JSK-\* "Elektroonilise hääletamise infosüsteemi IVXV seadistuste koostamise juhend". Kogumisteenusele rakendatavad seadistused peavad olema pakendatud ASiC-E konteinerisse ja olema signeeritud volitatud kasutaja poolt. Kogumisteenuse seadistuste koostamise tulemusena on kogumisteenuse osutajal olemas kogumisteenuse seadistamiseks vajalikud seadistuspakid. Kõik seadistused on signeeritud isiku(te) poolt, kelle volitused on kirjeldatud usaldusjuure seadistustes või kelle volitused on määratud eraldiseisvate korralduste abil. .. _taristu-paigaldamine: Kogumisteenuse taristu paigaldamine ----------------------------------- Kogumisteenuse taristu eraldatakse teenuse osutamiseks vastavalt koostatud seadistustele (:ref:`seadistuste_koostamine`). Igas teenusmasinas: #. peab olema seadistatud hostinimi (fail :file:`/etc/hostname`); #. peab olema paigaldatud SSH teenus (tarkvarapakk ``openssh-server``); #. peab olema paigaldatud tehnilise seire teenuse agent (tarkvarapakk ``zabbix-agent``); #. peab olema tagatud õige kellaaeg (näiteks õige kellaaja teenuse ``ntp`` abil). #. peab olema seadistatud nimelahendus, mis võimaldab kõikide teenusmasinate aadresse lahendada; #. peab olema seadistatud Eesti lokaat koos UTF-8 kooditabeli toega ``et_EE.UTF-8`` (kas tarkvarapakk ``locales`` koos nimetatud lokaadi seadistamisega või tarkvarapakk ``locales-all``, mis paigaldab kõik toetatud lokaadid). .. note:: Iga teenusmasina poolt kasutatav nimelahendus peab tagama, et suhtluseks kasutatavate hostide nimed lahenduvad korrektselt. Vältima peab olukordi, kus hostinimi lahendub mitmeks aadressiks või teistele hostidele kättesaamatuks aadressiks. Järgnev näide kirjeldab võimalikku olukorda failis :file:`/etc/hosts`, kus operatsioonisüsteemi paigalduse järel on hostinimi ``ivxv123`` määratud kahele liidesele. Sellise seadistuse puhul võib tekkida olukord, kus aadressile ``ivxv123`` ühendusi vastu võtma seadistatud teenus hakkab kuulama kohalikul liidesel ``127.0.0.1`` ja pole avaliku liidese ``192.168.10.1`` kaudu teistele teenustele kättesaadav. .. code-block:: text # /etc/hosts 127.0.0.1 ivxv123 192.168.10.1 ivxv123 Kogumisteenuse taristu jaoks eraldatud hostidest tuleb koostada nimekiri, kus on kirjas hosti asukohaks olev alamvõrk, hosti nimi, IP-aadress, SSH-serveri avalik võti ja hostile plaanitud teenused. Kogumisteenuse taristu nimekirja näide: .. code-block:: text Valimiste infrastruktuuri andmed Alamvõrk: zone1 IP-aadress: 172.16.238.10 Hostinimi: admin SSH-serveri avalik võti: ecdsa-sha2-nistp256 AAAAE2VjZHNhLX...SgtbbE= root@admin IP-aadress: 172.16.238.41 Hostinimi: ivxv1 SSH-serveri avalik võti: ecdsa-sha2-nistp256 AAAAE2VjZHNhLX...mN8ul0= root@ivxv1 Alamvõrk: zone2 IP-aadress: 172.16.100.63 Hostinimi: ivxv2 SSH-serveri avalik võti: ecdsa-sha2-nistp256 AAAE2VjZHNhLXN...rtWT7A= root@ivxv2 Kogumisteenuse taristusse kuuluvad hostid tuleb lisada tehnilisse seiresse. Kogumisteenuse taristu paigaldamise tulemusena on kogumisteenuse osutajal olemas dokumenteeritud platvorm kogumisteenuse paigaldamiseks ettenähtud konfiguratsiooniga. Kõik taristusse kuuluvad (virtuaal)masinad on tehnilise seire teenuse poolt kättesaadavad ja nende seisundis pole tuvastatud probleeme. Võrgupääsude loomine -------------------- Kogumisteenuse paigaldamiseks ja seadistamiseks on vajalik seadustustele vastavate võrgupääsude olemasolu. Süsteemiülemad ja kasutajad ^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. Kogumisteenuse süsteemiülemate arvutitest haldusteenusesse (protokoll SSH, port 22); #. Haldusteenuse kasutajate arvutitest haldusteenusesse (protokoll HTTPS, port 443); #. Kogumisteenuse süsteemiülemate arvutitest logiseire teenusesse (protokoll SSH, port 22); #. Logiseire kasutajate arvutitest logiseire teenusesse (protokoll HTTPS, port 443). Teenuste omavaheline suhtlus ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. Haldusteenusest kõikidesse mikroteenustesse (protokoll SSH, port 22); #. Haldusteenusest logiseire teenusesse (protokoll SSH, port 22); #. Kõigist mikroteenuste hostidest kõikidesse logikogumisteenustesse (protokoll RELP, port 20514); #. Kõigist mikroteenuste hostidest kõikidesse välistesse logikogumisteenustesse (sh, ka logiseire teenusesse) (protokoll RELP, port 20514); #. Kõigist mikroteenuste hostidest logiseire teenusesse (protokoll SSH, port 22); #. Kõigist logikogumisteenuste hostidest logiseire teenusesse (protokoll SSH, port 22); #. Vahendusteenusest teistesse mikroteenustesse peale talletusteenuse (protokoll TLS, port vastavalt tehnilisele seadistusele); #. Nimekirjateenusest talletusteenustesse (protokoll TLS, port vastavalt tehnilisele seadistusele); #. Hääletamisteenusest talletusteenustesse (protokoll TLS, port vastavalt tehnilisele seadistusele); #. Kontrolliteenusest talletusteenustesse (protokoll TLS, port vastavalt tehnilisele seadistusele); #. Talletusteenusest teistesse talletusteenustesse (protokoll TLS, port vastavalt tehnilisele seadistusele); #. Mobiil-ID tugiteenusest välisesse Mobiil-ID teenusesse (protokoll HTTP(S), port vastavalt tehnilisele seadistusele); #. Smart-ID tugiteenusest välisesse Smart-ID teenusesse (protokoll HTTP(S), port vastavalt tehnilisele seadistusele); #. Teistest mikroteenustest Session status tugiteenusesse (protokoll RPC, port vastavalt tehnilisele seadistusele); #. Hääletamisteenusest välisesse kvalifitseerimisteenusesse (protokoll HTTP(S), port vastavalt tehnilisele seadistusele); #. Varundusteenusest haldusteenusesse (protokoll SSH, port 22); #. Varundusteenusest logikogumisteenustesse (protokoll SSH, port 22); #. Varundusteenusest talletusteenustesse (protokoll SSH, port 22); Hääletaja ^^^^^^^^^ #. Hääletaja kasutatavast seadmest vahendusteenusesse (protokoll TLS, port vastavalt tehnilisele seadistusele, eeldatavalt 443). Haldusteenuse paigaldamine -------------------------- Haldusteenuse paigaldamine toimub haldusteenuse hostil. Haldusteenuse paigaldamiseks tuleb kopeerida **kõik** kogumisteenuse tarkvarapakid haldusteenuse masina kataloogi :file:`/etc/ivxv/debs/`. Nendest pakkidest paigaldatakse haldusteenus, samuti kasutab haldusteenus neid pakke alamteenuste paigaldamiseks. Haldusteenuse sõltuvuste paigaldamine: .. include:: genereeritud-failid/haldusteenuse_soltuvuste_paigaldamine.inc Haldusteenuse paigaldamine: .. include:: genereeritud-failid/haldusteenuse_paigaldamine.inc .. important:: Haldusteenuse edasine kasutamine toimub haldusteenuse konto alt. Selleks tuleb halduril luua SSH-ligipääs haldusteenuse kontole ``ivxv-admin``. Soovitav on autentimine teha ID-kaardi põhiseks (vaata :ref:`configure-ssh-idcard-auth`). Haldusteenuse paigaldamise tulemusena on kogumisteenuse osutajal teenuse haldamiseks vajalik liides. Haldusteenuse seadistamine ^^^^^^^^^^^^^^^^^^^^^^^^^^ Osad haldusteenuse protsessid käivitatakse korrapärase intervalliga cron teenuse abil. Nende protsesside puhul väljastatakse võimalik tõrkeinfo standardväljunditesse ja cron edastab selle e-posti teel käivitaja konto aadressile. Seetõttu tuleb haldusteenuse masinasse paigaldada meiliserver ja seadistada see nii, et kõigile masinas asuvatele kontodele (nt. ``root@localhost``) saadetavad sõnumid edastatakse teenuse halduritele. Kogumisteenuse taristu hõlmamine haldusesse ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Haldusteenus kasutab kogumisteenuse haldamiseks SSH protokolli. Selleks, et haldusteenusel oleks võimalik teisi teenushoste usaldada, tuleb haldusteenusesse lisada hallatavate teenushostide SSH-serveri võtmed. Näide hosti ``ivxv1`` SSH-võtmete lisamisest haldusteenuse usaldatavate hostide hulka:: ivxv-admin@admin $ ssh-keyscan ivxv1 >> ~/.ssh/known_hosts # ivxv1:22 SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.2 # ivxv1:22 SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.2 # ivxv1:22 SSH-2.0-OpenSSH_8.2p1 Ubuntu-4ubuntu0.2 Selleks, et haldusteenusel oleks võimalik teenushostidesse tarkvara paigaldada, tuleb haldusteenuse kontole ``ivxv-admin`` luua SSH-ligipääs teenushostide juurkasutaja kontole. .. note:: Haldusteenus vajab juurkasutaja ligipääsu alamteenuse tarkvara paigaldamiseks. Pärast edukat paigaldamist ühel hostil eemaldab haldusteenus ligipääsu selle hosti juurkasutaja kontole. Haldusteenuse konto SSH-võtmepaari avalik võti asub kasutaja ``ivxv-admin`` kodukataloogi all failis :file:`.ssh/id_ed25519.pub` ja see on genereeritud haldusteenuse paigaldamise käigus. Vajadusel võib haldur selle võtme asendada (kuid see peab toimuma enne, kui võti on üle kantud hallatavatesse teenusmasinatesse). Teenusmasinas tuleb haldusteenuse konto SSH avalik võti panna faili :file:`/root/.ssh/authorized_keys`. See fail peab kuuluma juurkasutajale ja olema loetav ainult juurkasutaja poolt (faili pääsuõigused ``0600``). Kogumisteenuse taristu haldusesse hõlmamise tulemusena on haldusteenusel usaldusväärne ligipääs kogumisteenuse taristusse kuuluvatele teenusmasinate juurkasutaja kontodele. Logiseire lahenduse ühendamine haldusteenusega ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Logiseire lahenduse kasutamise korral peab haldusteenusel olema ligipääs logiseire lahendusele, et sealt kogutud statistikat alla laadida ja vajadusel värskendada logiseire poolt analüüsitavaid logisid. Selleks, et haldusteenusel oleks usaldus logiseire teenuse vastu, tuleb haldusteenusesse lisada logiseire teenuse hosti (käesolevas näites nimega ``logmonitor``) SSH-serveri võtmed:: ivxv-admin@admin $ ssh-keyscan -t ecdsa logmonitor >> ~/.ssh/known_hosts Selleks, et haldusteenus pääseks logiseire kontole ligi, tuleb haldusteenuse konto SSH avalik võti panna logiseire konto ``logmon`` volitatud võtmete faili :file:`~logmon/.ssh/authorized_keys`. See fail peab kuuluma logimonitori kasutajale ja olema loetav ainult selle kasutaja poolt (faili pääsuõigused ``0600``). Logiseire lahenduse haldusteenusega ühendamise tulemusena on tegevuslogi seirelahendus haldusteenusele kättesaadav ning haldusteenusel on võimalik seirelahendusest statistikaandmeid laadida ning seirelahenduse andmehoidlasse ajakohaseid logiandmeid üle kanda. Haldusteenuse veebiliidese vaikimisi TLS-sertifikaadi asendamine ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Haldusteenuse paigalduse käigus genereeritakse kasutajaliidese veebiserveri TLS-sertifikaat koos krüptovõtmega ja tugeva Diffie-Hellman grupifailiga (vaata https://weakdh.org/). Vajadusel on halduril võimalik need asendada. Failide asukohad: * Veebiserveri TLS-sertifikaadi võti: :file:`/etc/ssl/private/ivxv-admin-default.key` * Veebiserveri TLS-sertifikaat: :file:`/etc/ssl/certs/ivxv-admin-default.crt` * Diffie-Hellmani grupifail: :file:`/etc/ssl/dhparams.pem` Asendatud failide rakendamiseks tuleb veebiserver taaskäivitada käsuga :command:`service apache2 restart` ja veenduda, et veebiliides töötab. Haldusteenuse veebiliidese vaikimisi TLS-sertifikaadi asendamise tulemusena kasutab haldusteenuse veebiliides turvalist sertifikaati. Haldusteenuse vaikimisi autentimissertifikaadi asendamine ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Haldusteenuse paigalduse käigus genereeritakse haldusteenuse autentimissertifikaat koos krüptovõtmega (haldusteenus kasutab seda Valimiste Infosüsteemiga infovahetusel autentimiseks). Vajadusel on halduril võimalik need asendada. Failide asukohad: * Autentimissertifikaadi võti: :file:`/etc/ssl/private/ivxv-admin-client.key` * Autentimissertifikaat: :file:`/etc/ssl/certs/ivxv-admin-client.crt` Haldusteenuse vaikimisi autentimissertifikaadi asendamise tulemusena kasutab haldusteenus Valimiste Infosüsteemi autentimiseks turvalist sertifikaati. Autentimissertifikaadi testimine: .. code-block:: shell-session $ openssl s_client -connect vis-address:443 \ -cert /etc/ssl/certs/ivxv-admin-client.crt \ -key /etc/ssl/private/ivxv-admin-client.key Haldusteenuse lähtestamine -------------------------- Haldusteenuse lähtestamine toimub käsuga :ref:`ivxv-collector-init`. Selle käigus puhastatakse haldusteenuse andmekataloogid ja lähtestatakse andmebaas. Seadistuste ja valimisnimekirjade rakendamine kogumisteenusele -------------------------------------------------------------- .. note:: Käesolevas lõigus ja alamlõikudes tähendab "seadistuspakk" nii seadistusi sisaldavat faili kui valimisnimekirja faili, mis on signeeritud volitatud isiku poolt. Kogumisteenusele tuleb rakendada järgmised seadistuspakid: #. Usaldusjuur – laaditakse alati esimesena; #. Kogumisteenuse tehniline seadistus – laaditakse enne valimiste seadistust; #. Valimiste seadistus – laaditakse enne nimekirju; #. Valikute nimekiri; #. Ringkondade nimekiri; #. Valijate algnimekiri. Ettevalmistatud seadistuspakkide rakendamiseks tuleb läbi viia järgmised tegevused: #. Ülekandmine haldusteenuse masinasse; #. Laadimine haldusteenusesse; #. Rakendamine alamteenustele. .. hint:: Seadistuspakkide ettevalmistamine on kirjeldatud lõigus ":ref:`seadistuste_koostamine`". .. attention:: Usaldusjuure seadistuse laadimisega kaasneb alati ka kogumisteenuse haldusteenuse andmebaasi lähtestamine! Seadistuste ja valimisnimekirjade kogumisteenusele rakendamise tulemusena on kogumisteenus seadistatud ettenähtud perioodil osutama nõuetekohast häälte kogumise teenust. Seadistuspaki ülekandmine haldusteenuse masinasse ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Seadistuspaki ülekandmine haldusteenuse masinasse toimub üle `SCP `_ protokolli. Seadistuspakk peab olema kättesaadav haldusteenuse kasutajakontole ``ivxv-admin``. Näide:: $ scp seadistus.asice ivxv-admin@admin: seadistus.asice 100% 15KB 79.5KB/s 00:00 .. note:: Kogumisteenus osutaja võib seadistuspakkide ülekandmiseks kasutada ka muid meetodeid, näiteks irdmeediat. Seadistuspaki ülekandmise tulemusena on seadistuspakk haldusteenuse poolt ligipääsetaval andmekandjal. Seadistuspaki laadimine haldusteenusesse ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Seadistuspakk laaditakse haldusteenusesse käsuga :ref:`ivxv-cmd-load`. Selle käigus kontrollib haldusteenus seadistuspaki signeerinud isiku volitusi ja valideerib seadistuste sisu ning kooskõlalisust. Laadimise tulemusena on seadistuspakk valmis rakendamiseks hallatavatele teenustele. Näide: Usaldusjuure laadimine haldusteenusesse: .. include:: genereeritud-failid/haldusteenus-laadi_usaldusjuure_seadistused.inc Seadistuspaki haldusteenusesse laadimise tulemusena on haldusteenus valmis rakendama seadistuspakki alamteenustele. Seadistuspaki versiooni kuvatakse haldusteenuse olekuandmetes. .. seealso:: * :ref:`korralduste-valideerimine` Seadistuste rakendamine alamteenustele ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Haldusteenusesse laaditud seadistuspakid rakendatakse hallatavatele teenustele käsuga :ref:`ivxv-config-apply`. Rakendamine on võimalik tehniliste seadistuse laadimise järel, kuna tehnilise seadistusega tekivad haldusteenusesse andmed hallatavate teenuste kohta. Seadistuste rakendamise käigus haldusteenus: * Paigaldab seadistatava teenuse tarkvara (tehnilise seadistuse laadimisel, kui pole eelnevalt paigaldatud); * Kannab seadistuspaki üle hallatava teenuse hosti failisüsteemi; * Valimiste seadistuse laadimisel lubab ja käivitab seadistatava teenuse. .. note:: Seadistuste rakendamise järjekord on kirjeldatud utiliidi ivxv-config-apply abiteabe lõigus (vaata :ref:`ivxv-config-apply`). Näide: Haldusteenusesse laaditud seadistuste rakendamine hallatavatele teenusele:: ivxv-admin@admin $ ivxv-config-apply INFO: Technical config is signed by ÕIGE,VALIK,44444444444 2017-06-07T12:05:44Z INFO: Service choices@choices1.ivxv.ee: Applying technical config SERVICE choices@choices1.ivxv.ee: Installing service to host "ivxv1" SERVICE choices@choices1.ivxv.ee: Querying state of the service software package "ivxv-choices" SERVICE choices@choices1.ivxv.ee: Copying software package files to service host SERVICE choices@choices1.ivxv.ee: Checking state of dpkg database in service host SERVICE choices@choices1.ivxv.ee: Installing dependencies for package "ivxv-common" Reading package lists... Building dependency tree... Reading state information... ... SERVICE voting@voting3.ivxv.ee: Set trust config file permissions in service host SERVICE voting@voting3.ivxv.ee: Trust root config successfully applied to service SERVICE voting@voting3.ivxv.ee: Applying technical config to service SERVICE voting@voting3.ivxv.ee: Copying technical config to service host SERVICE voting@voting3.ivxv.ee: Set technical config file permissions in service host SERVICE voting@voting3.ivxv.ee: Technical config successfully applied to service SERVICE voting@voting3.ivxv.ee: Registering technical config version "ÕIGE,VALIK,44444444444 2017-06-07T12:05:44Z" in management database SERVICE voting@voting3.ivxv.ee: Registering service state as "INSTALLED" in management database INFO: Service voting@voting3.ivxv.ee: technical config config applied successfully INFO: 15 configuration packages successfully applied Seadistuste alamteenustele rakendamise tulemusena on hallatavad teenused seadistatud ja nende seisund on haldusteenusest jälgitav. .. seealso:: * :ref:`korralduste-laadimine-rakendamine` Kogumisteenuse krüptovõtmete rakendamine ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ **Teenuste krüptovõtmete ja TLS-sertifikaatide** rakendamine toimub käsuga :ref:`ivxv-secret-load`. .. hint:: Teenuse krüptovõtmete seisundit on võimalik väljastada käsuga :command:`ivxv-status --service=` (vaata :ref:`ivxv-status`) Võtme laadimine teenusele: .. code-block:: shell-session $ ivxv-secret-load --service= tls-key tls.key Sertifikaadi laadimine teenusele: .. code-block:: shell-session $ ivxv-secret-load --service= tls-cert tls.pem .. important:: Igale teenuse isendile tuleb rakendada selle isendi jaoks genereeritud võti ja sertifikaat! **Hääletamisteenuse ajatemplipäringute signeerimisvõtme** rakendamine toimub käsuga :ref:`ivxv-secret-load`: .. code-block:: shell-session $ ivxv-secret-load tsp-regkey tspreg.key .. note:: Hääletamisteenuse ajatemplipäringute signeerimisvõti on vaja rakendada vaid juhul, kui ajatempliteenust kasutatakse registreerimisteenuseks (valimiste seadistuses on ``qualification/protocol`` välja väärtuseks ``tspreg``). **Mobiil-ID/Smart-ID/Web eID identsustõendi võtme** rakendamine toimub käsuga :ref:`ivxv-secret-load`: .. code-block:: shell-session $ ivxv-secret-load mid-token-key mobid-shared-secret.key .. note:: Mobiil-ID/Smart-ID/Web eID identsustõendi võti on vaja rakendada vaid juhul, kui Mobiil-ID/Smart-ID/Web eID tugiteenus on kasutusel (valimiste seadistuses on olemas plokk ``auth.ticket``). Kogumisteenuse krüptovõtmete rakendamise tulemusena on hallatavate teenuste suhtluskanalid varustatud kanali turvamiseks vajalike krüptovõtmetega, samuti on teenustel olemas krüptovõtmed muude oluliste operatsioonide jaoks. Algseadistamise tulemuse kontrollimine -------------------------------------- Algseadistamise tegevuste tulemusena on kogumisteenus eeldatavalt valmis hääletuse läbiviimiseks. Tulemust on võimalik kontrollida kogumisteenuse oleku jälgimisega, mis on kirjeldatud süsteemi haldustoimingute lõigus (:ref:`kogumisteenuse-oleku-jälgimine`). Hääletuse läbiviimiseks seadistatud kogumisteenuse olek on "Seadistatud" (CONFIGURED). Oleku "Paigaldatud" puhul tuleb kontrollida mikroteenuste seisundit ja seisundi taustainfot. ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/annotatsioon.rst ================================================ .. IVXV kogumisteenuse haldusjuhend Annotatsioon ------------ Käesolev juhend käsitleb tööd elektroonilise hääletamise raamistiku IVXV kogumisteenuse tarkvaraga süsteemiülema vaatepunktist ning kirjeldab tarkvara kõiki võimalusi kogu e-hääletusprotsessi ulatuses. Süsteemiülemalt eeldatakse e-hääletuse põhiterminoloogia tundmist. ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/e-valimiskasti_koostamine.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Valimiste kokkuvõtete tegemine features/end-to-end-10-collector-ha-setup.feature:892 Step: Haldur ekspordib haldusteenusest kogutud hääled features/end-to-end-10-collector-ha-setup.feature:970 .. code-block:: text ivxv-admin@admin $ ivxv-export-votes /output/voting/HA-SETUP/exported-votes.zip INFO: Creating backup copy from current ballot box SERVICE backup@backup.ivxv.ee: Copying list of known SSH hosts to service host # Preparing ballot box backup file in voting service voting@voting1.ivxv.ee # Creating ballot box backup file ballot-box-20211228_1155.zip Exporting votes: 0 Exporting votes: 1 Exporting votes: 2 Exporting votes: 3 Exporting votes: 4 Exporting votes: 5 Exporting votes: 6 Exporting votes: 7 Exporting votes: 8 # Copying backup file ballot-box-20211228_1155.zip to backup service # Removing backup file ballot-box-20211228_1155.zip from voting service INFO: Copying ballot box to management service SERVICE backup@backup.ivxv.ee: Copying ballot box from service host INFO: Collected votes archive is written to '/output/voting/HA-SETUP/exported-votes.zip' ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/haldusteenus-laadi_kogumisteenuse_tehnilised_seadistused.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Kogumisteenuse tehniliste seadistuste rakendamine features/end-to-end-10-collector-ha-setup.feature:404 Step: Haldur laadib haldusteenusesse kogumisteenuse tehnilised seadistused features/end-to-end-10-collector-ha-setup.feature:438 .. code-block:: text ivxv-admin@admin $ ivxv-cmd-load technical /output/voting/HA-SETUP/config/HA-SETUP.technical.asice INFO: Config file is signed by: ROPKA,KIVIVALVUR,32608320001 2021-12-28T11:38:40Z INFO: User ROPKA,KIVIVALVUR,32608320001 with role 'admin' is authorized to execute 'technical' commands INFO: Using signature 'ROPKA,KIVIVALVUR,32608320001 2021-12-28T11:38:40Z' as config file version INFO: Config file version is 'ROPKA,KIVIVALVUR,32608320001 2021-12-28T11:38:40Z' INFO: Loading command 'collectors technical configuration' from file '/output/voting/HA-SETUP/config/HA-SETUP.technical.asice' command_file:INFO: Loading command file '/output/voting/HA-SETUP/config/HA-SETUP.technical.asice' (collectors technical configuration) command_file:INFO: Validating collectors technical configuration command_file:INFO: Files in collectors technical configuration package are valid INFO: Collectors technical configuration file loaded successfully INFO: Collectors technical configuration file is registered in management service ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/haldusteenus-laadi_ringkondade_nimekiri.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Ringkondade nimekirja rakendamine features/end-to-end-10-collector-ha-setup.feature:586 Step: Nimekirjade haldur laadib ringkondade nimekirja haldusteenusesse features/end-to-end-10-collector-ha-setup.feature:630 .. code-block:: text ivxv-admin@admin $ ivxv-cmd-load districts /output/voting/HA-SETUP/config/districts.asice INFO: Config file is signed by: NÕID,VÄIKE,33333333333 2021-12-28T11:49:17Z INFO: User NÕID,VÄIKE,33333333333 with role 'election-conf-manager' is authorized to execute 'districts' commands INFO: Using signature 'NÕID,VÄIKE,33333333333 2021-12-28T11:49:17Z' as config file version INFO: Config file version is 'NÕID,VÄIKE,33333333333 2021-12-28T11:49:17Z' INFO: Loading command 'districts list' from file '/output/voting/HA-SETUP/config/districts.asice' command_file:INFO: Loading command file '/output/voting/HA-SETUP/config/districts.asice' (districts list) command_file:INFO: Validating districts list command_file:INFO: Files in districts list package are valid INFO: Some voting lists are already loaded, executing consistency checks: ivxv-config-validate --election=/etc/ivxv/election.bdoc --choices=/etc/ivxv/choices.bdoc --districts=/output/voting/HA-SETUP/config/districts.asice INFO: Validating elections configuration file '/etc/ivxv/election.bdoc' ... command_file:INFO: Files in districts list package are valid INFO: Config files are valid INFO: Detected election ID 'HA-SETUP' from election config INFO: Election ID consistency check succeeded INFO: Checking districts and choices lists consistency INFO: Voting lists consistency check succeeded INFO: Writing simplified district list to '/var/lib/ivxv/admin-ui-data/districts.json' INFO: Districts list file loaded successfully INFO: Districts list file is registered in management service ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/haldusteenus-laadi_usaldusjuure_seadistused.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Kogumisteenuse tehniliste seadistuste rakendamine features/end-to-end-10-collector-ha-setup.feature:404 Step: Haldur laadib haldusteenusesse usaldusjuure seadistused features/end-to-end-10-collector-ha-setup.feature:412 .. code-block:: text ivxv-admin@admin $ ivxv-cmd-load trust /output/voting/HA-SETUP/config/HA-SETUP.trust.asice command_file:INFO: Loading command file '/output/voting/HA-SETUP/config/HA-SETUP.trust.asice' (trust root configuration) command_file:INFO: Validating trust root configuration command_file:INFO: Files in trust root configuration package are valid INFO: Config file is signed by: ORAV,IVAN,30809010001 2021-12-28T11:38:37Z INFO: User ORAV,IVAN,30809010001 with role 'admin' is authorized to execute 'trust' commands INFO: Using signature 'ORAV,IVAN,30809010001 2021-12-28T11:38:37Z' as config file version INFO: Config file version is 'ORAV,IVAN,30809010001 2021-12-28T11:38:37Z' INFO: Loading command 'trust root configuration' from file '/output/voting/HA-SETUP/config/HA-SETUP.trust.asice' command_file:INFO: Loading command file '/output/voting/HA-SETUP/config/HA-SETUP.trust.asice' (trust root configuration) command_file:INFO: Validating trust root configuration command_file:INFO: Files in trust root configuration package are valid INFO: Resetting collector management database db:INFO: Initializing management database '/var/lib/ivxv/db/ivxv-management.db' Removing crontab (if exist) no crontab for ivxv-admin INFO: Trust root configuration file loaded successfully INFO: Resetting user permissions INFO: Trust root configuration file is registered in management service ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/haldusteenus-laadi_valijate_nimekiri.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Valijate algnimekirja rakendamine features/end-to-end-10-collector-ha-setup.feature:642 Step: Nimekirjade haldur laadib valijate algnimekirja haldusteenusesse features/end-to-end-10-collector-ha-setup.feature:666 .. code-block:: text ivxv-admin@admin $ ivxv-cmd-load voters /output/voting/HA-SETUP/config/voters-0.asice INFO: Config file is signed by: NÕID,VÄIKE,33333333333 2021-12-28T11:49:37Z INFO: User NÕID,VÄIKE,33333333333 with role 'election-conf-manager' is authorized to execute 'voters' commands INFO: Using signature 'NÕID,VÄIKE,33333333333 2021-12-28T11:49:37Z' as config file version INFO: Config file version is 'NÕID,VÄIKE,33333333333 2021-12-28T11:49:37Z' INFO: Loading command 'voters list' from file '/output/voting/HA-SETUP/config/voters-0.asice' command_file:INFO: Loading command file '/output/voting/HA-SETUP/config/voters-0.asice' (voters list) command_file:INFO: Validating voters list command_file:INFO: Files in voters list package are valid INFO: Some voting lists are already loaded, executing consistency checks: ivxv-config-validate --election=/etc/ivxv/election.bdoc --choices=/etc/ivxv/choices.bdoc --districts=/etc/ivxv/districts.bdoc --voters=/output/voting/HA-SETUP/config/voters-0.asice INFO: Validating elections configuration file '/etc/ivxv/election.bdoc' ... command_file:INFO: Files in voters list package are valid INFO: Config files are valid INFO: Detected election ID 'HA-SETUP' from election config INFO: Election ID consistency check succeeded INFO: Checking districts and choices lists consistency INFO: Checking districts and voter list changeset #0 consistency INFO: Voting lists consistency check succeeded INFO: Voters list file loaded successfully INFO: Voters list file is registered in management service ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/haldusteenus-laadi_valikute_nimekiri.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Valikute nimekirja rakendamine features/end-to-end-10-collector-ha-setup.feature:528 Step: Nimekirjade haldur laadib valikute nimekirja haldusteenusesse features/end-to-end-10-collector-ha-setup.feature:574 .. code-block:: text ivxv-admin@admin $ ivxv-cmd-load choices /output/voting/HA-SETUP/config/choices.asice INFO: Config file is signed by: NÕID,VÄIKE,33333333333 2021-12-28T11:49:03Z INFO: User NÕID,VÄIKE,33333333333 with role 'election-conf-manager' is authorized to execute 'choices' commands INFO: Using signature 'NÕID,VÄIKE,33333333333 2021-12-28T11:49:03Z' as config file version INFO: Config file version is 'NÕID,VÄIKE,33333333333 2021-12-28T11:49:03Z' INFO: Loading command 'choices list' from file '/output/voting/HA-SETUP/config/choices.asice' command_file:INFO: Loading command file '/output/voting/HA-SETUP/config/choices.asice' (choices list) command_file:INFO: Validating choices list command_file:INFO: Files in choices list package are valid INFO: Choices list file loaded successfully INFO: Choices list file is registered in management service ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/haldusteenus-laadi_valimiste_seadistused.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Lugemisperioodi alustamine features/end-to-end-10-collector-ha-setup.feature:885 Step: Haldur määrab kogumisteenuse uueks perioodiks "lõpetatud" features/end-to-end-10-collector-ha-setup.feature:888 .. code-block:: text ivxv-admin@admin $ ivxv-cmd-load election /output/voting/HA-SETUP/config/HA-SETUP.election.asice INFO: Config file is signed by: NÕID,VÄIKE,33333333333 2021-12-28T11:54:10Z INFO: User NÕID,VÄIKE,33333333333 with role 'election-conf-manager' is authorized to execute 'election' commands INFO: Using signature 'NÕID,VÄIKE,33333333333 2021-12-28T11:54:10Z' as config file version INFO: Config file version is 'NÕID,VÄIKE,33333333333 2021-12-28T11:54:10Z' INFO: Loading command 'elections configuration' from file '/output/voting/HA-SETUP/config/HA-SETUP.election.asice' command_file:INFO: Loading command file '/output/voting/HA-SETUP/config/HA-SETUP.election.asice' (elections configuration) command_file:INFO: Validating elections configuration command_file:INFO: Files in elections configuration package are valid INFO: Elections configuration file loaded successfully command_file:INFO: Loading command file '/output/voting/HA-SETUP/config/HA-SETUP.election.asice' (elections configuration) INFO: Elections configuration file is registered in management service ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/haldusteenuse_paigaldamine.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Kogumisteenuse haldusteenuse paigaldus features/end-to-end-10-collector-ha-setup.feature:370 Step: Haldur paigaldab haldusteenuse features/end-to-end-10-collector-ha-setup.feature:376 .. code-block:: text root@admin # dpkg -i /etc/ivxv/debs/ivxv-common_1.7.8_all.deb /etc/ivxv/debs/ivxv-admin_1.7.8_amd64.deb Selecting previously unselected package ivxv-common. (Andmebaasi lugemine ... 13710 files and directories currently installed.) Preparing to unpack .../debs/ivxv-common_1.7.8_all.deb ... Unpacking ivxv-common (1.7.8) ... Selecting previously unselected package ivxv-admin. Preparing to unpack .../ivxv-admin_1.7.8_amd64.deb ... Unpacking ivxv-admin (1.7.8) ... Paki ivxv-common (1.7.8) paikasättimine ... # Adding user group 'ivxv' Adding group `ivxv' (GID 109) ... ... systemctl restart apache2 # Starting Apache web server # Restarting rsyslog log server Created symlink /etc/systemd/system/multi-user.target.wants/ivxv-admin.service → /lib/systemd/system/ivxv-admin.service. Created symlink /etc/systemd/system/multi-user.target.wants/ivxv-admin-agent.service → /lib/systemd/system/ivxv-admin-agent.service. /usr/lib/python3/dist-packages/schematics/validate.py:121: SyntaxWarning: "is" with a literal. Did you mean "=="? if not kwargs or kwargs.pop('context', 0) is 0: Processing triggers for rsyslog (8.2001.0-1ubuntu1.1) ... invoke-rc.d: WARNING: No init system and policy-rc.d missing! Defaulting to block. ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/haldusteenuse_soltuvuste_paigaldamine.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Kogumisteenuse haldusteenuse paigaldus features/end-to-end-10-collector-ha-setup.feature:370 Step: Haldur paigaldab haldusteenuse features/end-to-end-10-collector-ha-setup.feature:376 .. code-block:: text root@admin # apt-get install --yes --quiet adduser openssh-server openssl rsync rsyslog rsyslog-relp sudo tzdata locales libc6 python3-bottle python3-dateutil python3-debian python3-docopt python3-fasteners python3-jinja2 python3-jsonschema python3-openssl python3-pkg-resources python3-yaml python3:any apache2 cron fonts-font-awesome javascript-common language-pack-et libapache2-mod-wsgi-py3 libjs-bootstrap libjs-jquery libjs-jquery-datatables libjs-jquery-datatables-extensions python3-gdbm python3-requests ssl-cert Reading package lists... Building dependency tree... Reading state information... adduser is already the newest version (3.118ubuntu2). cron is already the newest version (3.0pl1-136ubuntu1). fonts-font-awesome is already the newest version (5.0.10+really4.7.0~dfsg-1). javascript-common is already the newest version (11). libapache2-mod-wsgi-py3 is already the newest version (4.6.8-1ubuntu3). libjs-jquery is already the newest version (3.3.1~dfsg-3). libjs-jquery on määratud käsitsi paigaldatuks. ... Paki apache2-data (2.4.41-4ubuntu3.8) paikasättimine ... Paki openssl (1.1.1f-1ubuntu2.10) paikasättimine ... Paki rsync (3.1.3-8ubuntu0.1) paikasättimine ... invoke-rc.d: WARNING: No init system and policy-rc.d missing! Defaulting to block. Paki apache2-utils (2.4.41-4ubuntu3.8) paikasättimine ... Paki apache2 (2.4.41-4ubuntu3.8) paikasättimine ... invoke-rc.d: WARNING: No init system and policy-rc.d missing! Defaulting to block. invoke-rc.d: WARNING: No init system and policy-rc.d missing! Defaulting to block. Processing triggers for systemd (245.4-4ubuntu3.13) ... ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/kasutaja_lisamine.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Kogumisteenuse tehniliste seadistuste rakendamine features/end-to-end-10-collector-ha-setup.feature:404 Step: Haldur määrab haldusteenuses kasutajale "NÕID,VÄIKE,33333333333" rolli "election-conf-manager" features/end-to-end-10-collector-ha-setup.feature:471 .. code-block:: text ivxv-admin@admin $ ivxv-cmd-load user /output/voting/HA-SETUP/config/user-NÕID,VÄIKE,33333333333-election-conf-manager.asice INFO: Config file is signed by: ORAV,IVAN,30809010001 2021-12-28T11:46:31Z INFO: User ORAV,IVAN,30809010001 with role 'admin' is authorized to execute 'user' commands INFO: Using signature 'ORAV,IVAN,30809010001 2021-12-28T11:46:31Z' as config file version INFO: Config file version is 'ORAV,IVAN,30809010001 2021-12-28T11:46:31Z' INFO: Loading command 'user permissions configuration' from file '/output/voting/HA-SETUP/config/user-NÕID,VÄIKE,33333333333-election-conf-manager.asice' command_file:INFO: Loading command file '/output/voting/HA-SETUP/config/user-NÕID,VÄIKE,33333333333-election-conf-manager.asice' (user permissions configuration) command_file:INFO: Validating user permissions configuration command_file:INFO: Files in user permissions configuration package are valid INFO: User permissions configuration file loaded successfully INFO: Resetting user 'NÕID,VÄIKE,33333333333' permissions ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/mikroteenuse_kaivitamine.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Mikroteenuse seiskamine ja käivitamine features/end-to-end-10-collector-ha-setup.feature:512 Step: Haldur käivitab teenuse "voting@voting2.ivxv.ee" features/end-to-end-10-collector-ha-setup.feature:518 .. code-block:: text ivxv-admin@admin $ ivxv-service restart voting@voting2.ivxv.ee INFO: Restarting service voting@voting2.ivxv.ee SERVICE voting@voting2.ivxv.ee: Restarting service SERVICE voting@voting2.ivxv.ee: Registering service state as 'CONFIGURED' in management database (last state: 'FAILURE') SERVICE voting@voting2.ivxv.ee: Service restarted successfully INFO: Service voting@voting2.ivxv.ee restarted ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/mikroteenuse_seiskamine.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Mikroteenuse seiskamine ja käivitamine features/end-to-end-10-collector-ha-setup.feature:512 Step: Haldur seiskab teenuse "voting@voting2.ivxv.ee" features/end-to-end-10-collector-ha-setup.feature:515 .. code-block:: text ivxv-admin@admin $ ivxv-service stop voting@voting2.ivxv.ee INFO: Stopping service voting@voting2.ivxv.ee SERVICE voting@voting2.ivxv.ee: Stopping service SERVICE voting@voting2.ivxv.ee: Service stopped successfully INFO: Service voting@voting2.ivxv.ee stopped ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/mikroteenuse_seisundi_tuvastamine.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Mikroteenuse seiskamine ja käivitamine features/end-to-end-10-collector-ha-setup.feature:512 Step: Haldur tuvastab teenuse "voting@voting2.ivxv.ee" seisundi features/end-to-end-10-collector-ha-setup.feature:516 .. code-block:: text ivxv-admin@admin $ ivxv-service ping voting@voting2.ivxv.ee INFO: Pinging service voting@voting2.ivxv.ee SERVICE voting@voting2.ivxv.ee: Registering background info: Ping error: * ivxv-voting@voting@voting2.ivxv.ee.service - IVXV voting service SERVICE voting@voting2.ivxv.ee: ERROR: Pinging service failed ERROR: Failed to query service voting@voting2.ivxv.ee status ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/genereeritud-failid/töötlemisrakenduse_sisendi_koostamine.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * steps/test_util/report.py .. Feature: Kogumisteenuse käivitamine kõrgkäideldava konfiguratsiooniga features/end-to-end-10-collector-ha-setup.feature:7 Scenario: Valimiste kokkuvõtete tegemine features/end-to-end-10-collector-ha-setup.feature:892 Step: Haldur genereerib haldusteenuses töötlemisrakenduse sisendi aluse features/end-to-end-10-collector-ha-setup.feature:973 .. code-block:: text ivxv-admin@admin $ ivxv-generate-processor-input /output/voting/HA-SETUP/processor.cfg.zip INFO: Generating processor application config command_file:INFO: Loading command file '/etc/ivxv/election.bdoc' (elections configuration) INFO: Creating input file for processor application INFO: Preparing container structure in directory '/tmp/tmp6jswwi8i' INFO: Copying district list 'HA-SETUP.districts.json.bdoc' INFO: Copying voter list signing key 'voterfile.pub.key' INFO: Copying voter list #0 content '00.HA-SETUP.voters.utf' INFO: Copying voter list #0 signature '00.HA-SETUP.voters.sig' INFO: Copying voter list #1 content '01.HA-SETUP.voters.utf' INFO: Copying voter list #1 signature '01.HA-SETUP.voters.sig' ... INFO: Adding '02.HA-SETUP.voters.sig' to ZIP container INFO: Adding '02.HA-SETUP.voters.utf' to ZIP container INFO: Adding '03.HA-SETUP.voters.sig' to ZIP container INFO: Adding '03.HA-SETUP.voters.utf' to ZIP container INFO: Adding 'HA-SETUP.districts.json.bdoc' to ZIP container INFO: Adding 'HA-SETUP.processor.yaml' to ZIP container INFO: Adding 'ts.key' to ZIP container INFO: Adding 'voterfile.pub.key' to ZIP container INFO: Processor input is written to '/output/voting/HA-SETUP/processor.cfg.zip' ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/haldusteenus.rst ================================================ .. IVXV kogumisteenuse haldusjuhend .. _haldusteenus: Haldusteenus ============ Haldusteenus on kogumisteenuse haldamiseks mõeldud lahendus. Haldusteenus paigaldatakse eraldiseisvasse masinasse ja selle kaudu toimub kogumisteenuse juhtimine paigaldusest kuni seiskamiseni. Haldusteenuse funktsioonid on: #. Kogumisteenuse alamteenuste haldamine: #. Seadistuste ja valimisnimekirjade laadimine; #. Alamteenuste paigaldus selleks ettevalmistatud masinatesse; #. Alamteenustele seadistuste ja nimekirjade rakendamine; #. Valijate nimekirjade uuenduste hankimine Valimiste Infosüsteemist; #. E-valimiskasti koostamine töötlemiseks; #. Valimiste üldstatistika jälgimine; #. Valijate statistika allalaadimine; #. E-valimiskasti ja logide korrapärane varundamine; #. Kogumisteenuse seisundi seire; Haldusteenus suhtleb hallatavate teenustega üle `SSH `_-kanali. Suhtluse algatab alati haldusteenus. Usaldus teenusmasinate vastu luuakse süsteemihalduri abiga pärast teenuseid majutavate masinate paigaldamist. Teenust majutava masina paigaldamise järel loob haldur haldusteenusele ligipääsu teenusmasina juurkontole, et haldusteenusel oleks võimalik teenuse tarkvara paigaldada. Pärast viimase teenuse paigaldamist teenuseid majutavasse masinasse eemaldab haldusteenus ligipääsu juurkontole. Haldusteenuse koosseis ---------------------- Haldusteenuse kasutajaliides koosneb kahest osast: #. Haldamise põhifunktsionaalsus on teostatud :ref:`käsureautiliitide ` abil; #. Graafiline kasutajaliides on veebipõhine liides, mille funktsionaalsuse tagavad käsureautiliidid. .. seealso:: Graafilise kasutajaliidese kasutusjuhend asub dokumendis ``IVXV kogumisteenuse haldusliidese kasutusjuhend``. Lisaks töötavad deemonprotsessid: #. Veebiserver graafilise kasutajaliidese jaoks; #. Haldusdeemon veebiserveri poolt vahendatud päringute käivitamiseks; #. Agentdeemon teenuste seisundi jälgimiseks. ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/haldustoimingud.rst ================================================ .. IVXV kogumisteenuse haldusjuhend Süsteemi haldustoimingud ======================== .. _kogumisteenuse-oleku-jälgimine: Kogumisteenuse oleku jälgimine ------------------------------ Kogumisteenuse olekuandmed registreeritakse haldusteenuse andmebaasis. Oleku kuvamiseks on utiliit :ref:`ivxv-status`. Olekus kuvatakse järgmisi andmeid: * Valimise ID, faas, algus- ja lõpuaeg; * Haldusteenusesse laaditud konfiguratsioon: * Seadistuspakkide versioonid; * Valikute nimekirja ja ringkondade nimekirja versioonid; * Valijate nimekirjade versioonid ja olekud; * Teenuste nimekiri koos rakendatud seadistuste versioonidega, teenuse seisundi ja selle viimase tuvastamise ajaga; * Väliste teenuste seisundid; * Haldusteenuse andmehoidla statistika. Sõltuvalt kogumisteenuse seisundist võib oleku kuvamise utiliit jätta mõned andmeblokid kuvamata (kui need pole jooksva seisundi puhul olulised). Täieliku andmestiku väljastamiseks vaata utiliidi :ref:`ivxv-status` abiteavet. Mikroteenuste oleku jälgimise ning oleku ja võimaliku veainfo registreerimisega haldusteenuse andmebaasis tegeleb haldusteenuse :ref:`agentdeemon `. Valijate muudatusnimekirjade hankimine Valimiste Infosüsteemist toimub utiliidiga :ref:`ivxv-voter-list-download`, mis käivitatakse teenuse `cron` poolt veerandtunnise intervalliga. Kogumisteenuse haldusteenuse sündmuste logi kuvamiseks on utiliit :ref:`ivxv-eventlog-dump`. .. important:: Haldusteenus tagab kogumisteenuse alamteenuste olekuandmetes vajaliku teabe teenuse töökorda seadmiseks. See võib olla järgmine: #. Teave puuduvate seadistuste kohta (seadistusfailid, võtmed jms). Seda kuvatakse kuni teenus on varustatud kõigi käivitamiseks vajalike seadistustega. #. Veateade - alamteenuse haldusvahendite (seadistuste kontrollivahend, teenuse haldusvahend) veaväljund mittetöötava teenuse kohta. .. _korralduste-valideerimine: Korralduste valideerimine ------------------------- Korraldusfailide valideerimine võimaldab veenduda korralduste vastavuses vormistusnõuetele ning tuvastada vigased või mittekooskõlalised korraldused. Valideerimine toimub käsuga :ref:`ivxv-config-validate`. Valimise seadistuse valideerimise näide:: $ ivxv-config-validate --election=valimise-seadistus-TEST2017.asice Korralduste kooskõlalisuse valideerimine ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Kooskõla valideerimine viiakse läbi kahel juhul: #. Kui valideerimise käsule antakse korraga valideerimiseks mitu korraldust; #. Korralduse laadimisel juhul, kui laaditava korraldusega kooskõla nõudev oluline korraldus juba haldusteenusesse laaditud. Korralduste kooskõla valideerimise kontrollid: #. Korraga valimiste seadistust ja/või nimekirju (valikute, ringkondade või valijate) valideerides kontrollitakse valimiste identifikaatori kooskõla. #. Korraga mitut valijate nimekirja valideerides viiakse läbi järgnevad kontrollid: * Nimekirjade korrektne järjestus; * Muudatusnimekirjas kontrollitakse: #. Valija topeltlisamist ja -eemaldamist; #. Valija eemaldamist pärast tema lisamist sama muudatusnimekirjaga. #. Valija eemaldamist ringkonnast, kuhu teda pole lisatud; #. Korraga ringkondade ja valikute nimekirja valideerides viiakse läbi järgnevad kontrollid: * Igas valimisringkonnas peab olema kirjeldatud vähemalt üks valik; * Iga valik peab olema seotud olemasoleva valimisringkonnaga. #. Korraga ringkondade nimekirja ja valijate nimekirju valideerides viiakse läbi järgnevad kontrollid: * Igas valimisjaoskonnas peab olema vähemalt üks valija; * Iga valimisnimekirja kantud isik peab olema seotud olemasoleva ringkonnaga; #. Valijate nimekirja(de) ja ringkondade nimekirja valideerimisel kontrollitakse valijale määratud ringkonna olemasolu ringkondade nimekirjas. Kui valimiste seadistuses on määratud välisriigis asuvale valijale määratav ringkonna haldusüksuse EHAK-kood (parameeter ``voterforeignehak``), peab valikute, valijate ja ringkondade nimekirjade vastavuse valideerimisel olema kaasatud ka valimiste seadistus ja seadistuste valideerimisel tehakse täiendavad kontrollid: #. Valijate nimekirja ja ringkondade nimekirja kooskõla valideerides kontrollitakse, et ringkondade nimekirjas on parameetriga määratud haldusüksuses olemas valijale määratud ringkond. .. _korralduste-laadimine-rakendamine: Korralduste laadimine ja rakendamine ------------------------------------ Kogumisteenuse korraldused koostatakse signeeritud korralduspakkidena, millega kirjeldatakse kasutaja identifikaator (*Common Name* ehk CN väli ID-kaardilt) ja rollide nimekiri. Sõltuvalt korraldusest tuleb rakendamiseks kasutada ühte või kahte käsku. Haldusteenust puudutavad korralduste rakendamiseks piisab nende laadimisest haldusteenusesse. Alamteenuseid puudutavad korraldused (näiteks seadistuspakid) tuleb pärast haldusteenusesse laadimist rakendada ka hallatavatele teenustele. Korralduste laadimine haldusteenusesse toimub käsuga :ref:`ivxv-cmd-load`. Laadimise käigus viiakse läbi ka :ref:`korralduse valideerimine `, vigane või mittekooskõlaline korraldus jäetakse laadimata. Valikute nimekirja korralduse rakendamise näide: .. include:: genereeritud-failid/haldusteenus-laadi_valikute_nimekiri.inc .. seealso:: * Käsu :ref:`ivxv-cmd-load` abiteave; * Korralduste rollide kirjeldus ja korralduste koostamise juhend asuvad dokumendis ``IVXV seadistuste koostamise juhend``. Teenuse isendi seisundi tuvastamine ----------------------------------- Mikroteenuse isendi seisundi tuvastamiseks on utiliit :ref:`ivxv-service`, millega on võimalik teenuse seisundit vahetult küsida (utiliit :ref:`ivxv-status` kuvab andmebaasis puhverdatavat seisundit). Teenuse seisundi päringu näide: .. include:: genereeritud-failid/mikroteenuse_seisundi_tuvastamine.inc .. _teenuse-taaskäivitamine: Teenuse (taas)käivitamine ------------------------- Mikroteenuste käivitamiseks ja taaskäivitamiseks on utiliit :ref:`ivxv-service`. Teenuse taaskäivitamise näide: .. include:: genereeritud-failid/mikroteenuse_kaivitamine.inc .. note:: Protseduuri nimetamine käivitamiseks või taaskäivitamiseks sõltub teenuse protsessi seisundist. Tehniliselt on tegemist sarnaste protseduuridega, kus esmalt veendutakse, et teenus seisab (vajadusel jäetakse see seisma) ja siis püütakse käivitada hetkel kehtivate seadistustega. .. _teenuse-seiskamine: Teenuse seiskamine ------------------ Mikroteenuste seiskamiseks on utiliit :ref:`ivxv-service`. Teenuse seiskamise näide: .. include:: genereeritud-failid/mikroteenuse_seiskamine.inc .. _teenuse-asendamine: Teenuse isendi asendamine ------------------------- Teenuse isendi asendamine koosneb ühe mikroteenuse isendi eemaldamisest (vt. :ref:`teenuse-eemaldamine`) ja teise sama funktsiooniga mikroteenuse isendi lisamisest (vt. :ref:`teenuse-lisamine`). .. _teenuse-lisamine: Teenuse isendi lisamine ----------------------- Teenuse isendi lisamiseks tuleb vajadusel teenust hostiv server ette valmistada (vt. :ref:`taristu-paigaldamine`) ning rakendada uus tehniline seadistus, mis sisaldab lisatavat teenuse isendit. .. important:: Lisatava isendi identifikaator ei tohi kattuda ühegi teise, ka minevikus eemaldatud isendi identifikaatoriga. .. _teenuse-eemaldamine: Teenuse isendi eemaldamine -------------------------- Teenuse isendi eemaldamiseks tuleb: #. Teenuse isend seisma jätta (vt. :ref:`teenuse-seiskamine`); #. Keelata teenuse isendi uuesti käivitamine (vt. allpool); #. Rakendada uus tehniline seadistus, mis eemaldatavat isendit enam ei sisalda. .. important:: Teenuse isendi eemaldamisel kogumisteenuse koosseisust on oluline eemaldatava isendi täielik elimineerimine. Teenuste isendid kasutavad üksteisele usalduse tõestamiseks kindla sertifitseerimiskeskuse (CA) poolt välja antud sertifikaate, kuid ei kasuta sama meetodit eemaldatud isendi usalduse tühistamiseks (vastava protseduuri rakendamise liigse keerukuse tõttu). Seetõttu on oluline veenduda, et kogumisteenusest eemaldatud teenuse isend on enne uue seadistuse rakendamist täielikult süsteemist eemaldatud. Vastasel juhul tekib oht, et eemaldatav isend jätkab tegutsemist ja häirib kogumisteenuse tööd. Teenuse isendi käivitamise keelamiseks teenuse eemaldamisel tuleb eemaldada vastava teenuse tarkvarapakk teenuse hostist: * Nimekirjateenuse paki eemaldamine: .. code-block:: text $ apt purge ivxv-choices * Mobiil-ID tugiteenuse paki eemaldamine: .. code-block:: shell-session $ apt purge ivxv-mid * Smart-ID tugiteenuse paki eemaldamine: .. code-block:: shell-session $ apt purge ivxv-smartid * Web eID tugiteenuse paki eemaldamine: .. code-block:: shell-session $ apt purge ivxv-webeid * Session status tugiteenuse paki eemaldamine: .. code-block:: shell-session $ apt purge ivxv-sessionstatus * Vahendusteenuse paki eemaldamine: .. code-block:: shell-session $ apt purge haproxy * Talletusteenuse paki eemaldamine: .. code-block:: shell-session $ apt purge etcd-server * Kontrolliteenuse paki eemaldamine: .. code-block:: shell-session $ apt purge ivxv-verification * Hääletamisteenuse paki eemaldamine: .. code-block:: shell-session $ apt purge ivxv-voting Kasutajate haldus ----------------- Kasutajate algsed kirjeldused määratakse usaldusjuure seadistuses, hilisem haldus toimub vastavate korralduste abil. Kasutajate halduse korraldused rakendatakse käsuga :ref:`ivxv-cmd-load` (vaata :ref:`korralduste-laadimine-rakendamine`). Kasutajaõiguste määramise korralduse rakendamise näide: .. include:: genereeritud-failid/kasutaja_lisamine.inc .. attention:: Juba lisatud kasutajate eemaldamine süsteemist pole võimalik. Kasutaja eemaldamise asemel tuleb kasutaja rolliks määrata "õigusteta kasutaja". .. seealso:: * Kasutajate rollide kirjeldus ja volituste korralduste koostamise juhend asuvad dokumendis ``IVXV seadistuste koostamise juhend``. * Korralduste rakendamine on kirjeldatud lõigus :ref:`korralduste-laadimine-rakendamine`. Tarkvarauuenduste rakendamine ----------------------------- Tarkvarauuendused jagunevad kogumisteenuse vaatepunktist kaheks: operatsioonisüsteemi uuendused ja kogumisteenuse uuendused. Operatsioonisüsteemi tarkvarapakkide uute versioonide paigaldamine pole kogumisteenuse dokumentatsioonis käsitletud. Süsteemiülem peab tagama ajakohaste turvauuenduste rakendamise kogumisteenuses kasutatavate operatsioonisüsteemidele; Kogumisteenuse tarkvarapakkide uute versioonide paigaldamine toimub järgnevalt: #. Uuenenud tarkvarapakid kopeeritakse haldusteenuse kataloogi :file:`/etc/ivxv/debs` (soovitavalt juurkasutaja õigustes); #. Haldusteenuse tarkvara uuendatakse juurkasutaja õigustes käsuga :command:`dpkg -i /etc/ivxv/debs/ivxv-common_1.0_all.deb /etv/ivxv/debs/ivxv-admin_1.0_amd64.deb` (tegelik versiooninumber erineb käesolevas näites kasutatud versioonist); #. Hallatavate teenuste tarkvara uuendamine toimub haldusteenuse kasutaja ``ivxv-admin`` õigustes käsuga :ref:`ivxv-update-packages`. Varundamine ----------- Varundamine hõlmab kolme liiki andmeid: #. Haldusteenuse seadistused; #. Kogumisteenuse e-valimiskast; #. Kogutud logid. Varukoopia loomine toimub haldusteenuse masinas utiliidi :ref:`ivxv-backup` abil, varukoopiad talletatakse varundusserveri kataloogis :file:`/var/backups/ivxv`. Haldusteenus seadistuste varundamine ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Haldusteenuse seadistustest varundatakse järgmised andmed: #. :file:`etc/` - haldusteenusesse laaditud tarkvarapakid ja hetkel kehtivad seadistusfailid; #. :file:`admin-ui-permissions/` - haldusteenuse kasutajaliidese pääsuõigused; #. :file:`commands/` - kõik haldusteenusese laaditud korraldusfailid. Haldusteenuse varundamist viiakse läbi haldusteenuses, varundatavad andmed kopeeritakse varundusserverisse. .. hint:: Haldusteenuse andmete tõhusamaks varundamiseks ja taasteks on soovitav kasutada haldusteenuse virtuaalmasina dünaamilist tõmmist (*snapshot dump*). Haldusteenuse seadistuste varukoopiast taastamise protseduuri pole kogumisteenuses ette nähtud. Haldusteenuse seadistusete varukoopia loomise näide:: $ ivxv-backup management-conf Kogumisteenuse e-valimiskasti varundamine ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Kogumisteenuse e-valimiskasti varundamine toimub talletusteenuses kogutud häältest e-valimiskasti loomisega ja selle kopeerimisega varundusteenusesse. Varundatud andmete taastamine toimub hääletuse järel e-valimiskasti väljastamise käigus, kus talletusteenuses olevatest häältest ja varukoopiatesse salvestatud häältest pannakse kokku töötlemisele minev e-valimiskast. E-valimiskasti varundamist viib läbi haldusteenus. Varukoopia loomine toimub talletusteenuses ja see kopeeritakse varundusserverisse. Varukoopia on sama vorminguga, nagu kogumisteenuse poolt väljastatav e-valimiskast (ZIP64). Varundamise andmemahtu saab arvutada järgmise meetodiga: ``häälte arv * 12,1 kB * pakkimistegur``. Näiteks saja tuhande hääle suurus, kus pakkimistegur on 0,4 = 472 MB. E-valimiskasti varukoopia loomise näide:: $ ivxv-backup ballot-box Logide varundamine ^^^^^^^^^^^^^^^^^^ Logikogumisteenustes kogutud logifailide varundamine toimub logifailide :file:`/var/log/ivxv/ivxv-YYYY-MM-DD-HH.log` kopeerimisega varundusserverisse. Logide varundamist viib läbi haldusteenus. Logide varukoopiast taastamise protseduuri pole kogumisteenuses ette nähtud. Logikogumisteenusesse kogutud logist varukoopia loomise näide:: $ ivxv-backup log .. _konsolideeritud-e-valimiskasti-koostamine: Konsolideeritud e-valimiskasti koostamine ----------------------------------------- Konsolideeritud e-valimiskast koostatakse talletusteenusesse kogutud häältest ja varundusteenusesse varundatud e-valimiskastidest. Konsolideerimise protsess koosneb järgmistest sammudest: #. Talletusteenusesse kogutud hääled varundatakse varundusteenusesse. Selle tulemusena on varundusteenusesse salvestatud kõik kogutud e-valimiskastid; #. Varundusteenuses koostatakse konsolideeritud e-valimiskast; #. Konsolideeritud e-valimiskast kopeeritakse haldusteenusesse. Konsolideeritud e-valimiskasti koostamise näide: .. include:: genereeritud-failid/e-valimiskasti_koostamine.inc Töötlemisrakenduse sisendi aluse koostamine ------------------------------------------- Töötlemisrakenduse sisendi alus on häälte töötlemiseks vajalike sisendfailide komplekt, mis genereeritakse kogumisteenuses salvestatud andmete põhjal. Komplekti koosseis on järgmine: #. Ringkondade nimekiri; #. Valijate nimekirjad; #. E-valimiskast kogutud häältega; #. Häälte registreerimispäringute valideerimisandmed; #. Töötlemisrakenduse seadistused. Väljund on ZIP-konteiner, mis sisaldab järgmisi faile: #. Ringkondade nimekiri digitaalselt signeerituna :file:`.districts.json.asice`; #. Valijate nimekirjade signeerimisvõtme avalik võti :file:`voterfile.pub.key`; #. Valijate nimekirjad :file:`..voters.utf`; #. Valijate nimekirjade signatuurid :file:`..voters.sig`; #. Valijate nimekirja vahelejätmise korraldused :file:`..voters-skip.yaml.asice`; #. Registreerimispäringute verifitseerimise avalik võti :file:`ts.key`; #. Töötlemisrakenduse seadistuste mall e-valimiskasti verifitseerimiseks :file:`.processor.yaml`. Töötlemisrakenduse sisendi alus koostatakse utiliidi :ref:`ivxv-generate-processor-input` abil. Näide: .. include:: genereeritud-failid/töötlemisrakenduse_sisendi_koostamine.inc Hääletamise statistika eksportimine ----------------------------------- Häälestamise statistika koostatakse hääletusteenuses ja see koosneb kahest osast: üldstatistika (hääletajate koguarv) ja detailstatistika. Üldstatistika kopeeritakse haldusteenusesse ja eksporditakse Valimiste Infosüsteemi 15 minutilise intervalliga. Detailstatistika koostatakse ja eksporditakse Valimiste Infosüsteemi käsitsi. Häälestamise statistika importimine ja eksportimine toimub haldusteenuse masinas utiliidi :ref:`ivxv-voterstats` abil. Üldstatistika importimise ja eksportimise automaatika on teostatud cron-teenuse abil ja kirjeldatud failis :file:`/etc/cron.d/ivxv-admin`. Hääletamise seansside väljavõtte koostamine ------------------------------------------- Hääletamise ja hääle kontrollimise seansside väljavõte on CSV-vormingus ja see koostatakse logiseire teenuses. Väljavõtet on võimalik koostada anonüümistatud kujul, kus kasutajate isikukoodid ja IP-aadressid on asendatud anonüümsete väärtustega. Võimalik on valida, kas väljastada kõik hääletamise seansid või ainult hääle kontrollimisega seansid. :ref:`ivxv-voting-sessions` ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/index.rst ================================================ .. IVXV kogumisteenuse haldusjuhend IVXV kogumisteenuse haldusjuhend ======================================================================== .. raw:: html

NB! See on HTML-versioon dokumendist. Tellijale antakse üle PDF-versioon.

.. toctree:: :maxdepth: 2 annotatsioon ylevaade haldusteenus algseadistamine haldustoimingud krahhitaaste seadistused protseduurid lisad ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/krahhitaaste.rst ================================================ .. IVXV kogumisteenuse haldusjuhend Krahhitaaste ============ Kogumisteenus on projekteeritud nii, et teenuse või selle osade krahhimise tagajärjel ei tekiks andmekadu või oleks see minimaalne. Eeldused edukaks krahhitaasteks ------------------------------- Kõrgkäideldav seadistus ^^^^^^^^^^^^^^^^^^^^^^^ Peamine eeldus edukaks krahhitaasteks on kogumisteenuse paigaldamine kõrgkäideldava seadistusega, mis määrab vähemalt kolme talletusteenuse isendi kasutamise. Lisaks on krahhiolukorra kiiremaks lahendamiseks kasulik eraldada mikroteenustele ühe lisaisendite komplekti paigalduseks vajalik taristu. Logikoguja kasutamine ^^^^^^^^^^^^^^^^^^^^^ Kogumisteenuse seadistus peab kirjeldama logikogumisteenuse, et mikroteenuste poolt toodetavad logisid oleks võimalik lihtsal moel kokku koguda. Soovitav on kasutada mitut logikogujat erinevas füüsilises lokatsioonis, et minimeerida logikirjete kaotsimineku võimalust. Varundusteenuse kasutamine ^^^^^^^^^^^^^^^^^^^^^^^^^^ Kogumisteenuse seadistus peab kirjeldama varundusteenuse ning automaatse varundamise ajad piisava sagedusega. Samuti on soovitav teha varukoopiad ka varundusteenusest. Automaatne varundamine tagab e-valimiskasti koopia säilimise :ref:`talletusteenuse täieliku krahhi ` korral. .. note:: Varundusteenus on soovitav paigaldada teistest kogumisteenuse isenditest füüsiliselt eraldi, et võimalikud eriolukorrad (näiteks tulekahju) ei mõjutaks korraga nii varundusteenust kui teisi teenuseid. Varundusteenus on projekteeritud kogumisteenuse andmetest automaatsete varukoopiate loomiseks ühte kohta ning nende kättesaadavaks tegemiseks operatsioonidele, mis varukoopiaid kasutavad (näiteks häälte kokkulugemine). .. note:: Kogumisteenuse osutaja peaks kaaluma võimalust teha varundusteenusest täiendavaid varukoopiaid, et tagada varundatud andmete säilimine ka varundusteenuse krahhi korral. Valmisolek krahhiks ^^^^^^^^^^^^^^^^^^^ Kogumisteenuse krahh mõjutab kõiki e-hääletamise komponente, erilist tähelepanu tuleb pöörata valijarakenduste ja kontrollrakenduste nimelahendusele ning TLS ühenduste usaldamiseks vajalikele sertifikaatidele. Hääletamise edukaks läbiviimiseks tuleb tagada, et nimeserverid sisaldaks kogu hääletusperioodi vältel ajakohast infot hääletamissüsteemi sisendpunktide kohta - siis suudavad valijarakendused ja kontrollrakendused vastavalt muutuvatele oludele nimesid korrektselt lahendada. #. Krahhimise tuvastamisel tuleb esimeste tegevuste hulgas eemaldada nimelahendusest krahhinud teenus, et rakendused enam selle poole pöörduda ei saaks. #. Kui teenused pärast krahhi uuesti töökorda saadakse, tuleb viimase sammuna nimelahenduses panna uute teenuste aadressid lahenduma vastavalt rakendustes defineeritule. Kui kogumisteenusesse lisatakse uusi mikroteenuseid (eeldatavalt pärast krahhimist), siis on tarvis tagada lisatud teenuste usaldusväärsus rakendustes. Teenuse plaanimisel tuleb luua serdid/võtmed ka võimalike asendusteenuste jaoks (choices, mid, voting). Need võtmed tuleb pakendada valijarakendusse, et pärast krahhi poleks tarvis hakata uut rakendust levitama. Kui sertifikaadid luuakse ühe CA alt, siis piisab valijarakendusse vastava CA sertifikaadi pakendamisest. Kontrollrakenduste jaoks tuleb seadistustes alati näidata konkreetsed teenussertifikaadid, kuid kontrollrakenduste seadistuste muutmine ei eelda kontrollrakenduste uuesti levitamist. Teenuste taastamine krahhist ---------------------------- Mikroteenuse isendi krahh ilma andmekaota ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Mikroteenuse isendi krahh ilma andmekaota võib esineda teenuste puhul, mis ei tegele andmete säilitamisega (nimekirjateenus, hääletusteenus, kontrolliteenus või mobiil-id tugiteenus). Sellises olukorras piisab teenuse isendi taastamiseks kas teenuse taaskäivitamisest (kui see on võimalik) või teenuse isendi asendamisest uuega. .. seealso:: * :ref:`teenuse-taaskäivitamine` * :ref:`teenuse-asendamine` * :ref:`recovery-stateless` Logikogumisteenuse isendi krahh ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Logikogumisteenuse krahh võib esineda nii logiandmete riknemisega kui ka ilma. Ilma logiandmete riknemiseta krahh tähendab olukorda, kus rsyslog teenus seisab ja ei võta seetõtte teenustelt logikirjeid vastu ning salvestatud logifailid ei ole rikutud. Sellises olukorras piisab teenuse isendi töökorda seadmiseks selle taaskäivitamisest. Logikogumisteenuse krahh koos logiandmete riknemisega nõuab teenuse isendi asendamist uuega. Kui logiandmete riknemisega kaasneb alati logiandmete kadu, siis ilma riknemiseta krahhi puhul tuleb samuti selle võimalusega arvestada. Logisid edastatakse üle RELP-protokolli, mis on küllalt töökindel, kuid vaatamata sellele võib logiedastus katkeda olukorras, kus logi genereeriva teenuse hostil on rsyslogi isendit taaskäivitatud ajal, mil logikoguja rsyslog isend ei töötanud. .. seealso:: * :ref:`teenuse-taaskäivitamine` * :ref:`teenuse-asendamine` * `RELP - The Reliable Event Logging Protocol `_ * :ref:`recovery-logcollection` Varundusteenuse isendi krahh ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Varundusteenuse isendi krahh tähendab varundusteenusesse varundatud andmete riknemist. Teenuse taastamiseks tuleb varundusteenus uuesti paigaldada ja varundatud andmed taastada. Andmete taastamine varundusserverisse võib toimuda ka pärast häälte kogumise lõppemist, kuid enne häälte kokkulugemist. .. note:: Varundusprotseduuride käivitamist juhitakse haldusteenusest ja seetõttu pole varundusteenust võimalik käivitada ega seisma jätta. .. seealso:: * :ref:`recovery-backupservice` Talletusteenuse isendi krahh ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Talletusteenuse ühe isendi krahhimisel piisab isendi asendamisest uuega. Talletusteenuseid saab lisada ja eemaldada ainult siis, kui klastris on vähemalt kvoorumi jagu töökorras talletusteenuse isendeid. Kvoorumi suurus on N/2+1 ümardatud alla, kus N on seadistatud isendite arv (näiteks kolme seadistatud isendi korral on kvoorumi suurus kaks). Kui talletusteenuse isendeid jääb alles vähem kui kvoorumi jagu, siis tuleb teha kõigile isenditele uus paigaldus (vt. :ref:`talletusteenuste-täielik-krahh`). Talletusteenuse kvoorumist tingitud piirangud: #. Talletusteenuse isendite arvu ei ole kunagi võimalik vähendada ühele; #. Talletusteenuste isendite eemaldamisel peab arvestama kvoorumi säilimisega. Näide: kui on seadistatud 6 talletusteenuse isendit (kvoorum=4), siis sealt ei saa korraga eemaldada kolme isendit (jääks järgi kolm isendit, kvoorum=2), kuna seadistatud isendite hulk oleks siis väiksem kui algne kvoorum. Kõigepealt tuleb eemaldada üks (jääb järgi 5 isendit, kvoorum=3) isend ja alles pärast seda saab eemaldada ülejäänud kaks. .. seealso:: * :ref:`teenuse-taaskäivitamine` * :ref:`teenuse-asendamine` * :ref:`recovery-storageservice` .. _talletusteenuste-täielik-krahh: Talletusteenuste täielik krahh ehk kogumisteenuse täielik asendamine ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Talletusteenuste täielikul asendamisel tuleb koostada uus tehniline seadistus, mis vastab järgmistele tingimustele: * ei sisalda ühtegi vana talletusteenust; * kõik uued talletusteenused on loetletud parameetri ``storage.conf.bootstrap`` nimekirjas. .. important:: Talletusteenuste täielikul asendamisel tuleb arvestada järgnevada: * enne asendamist kogutud hääled säilivad varundusserveritesse tehtud varukoopiates; * varukoopia loomise ja krahhi vahel kogutud hääled lähevad kaotsi; * valikute, ringkondade ja valijate nimekirjad tuleb teenustele uuesti rakendada. .. seealso:: * :ref:`recovery-fullstorage` ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/lisad.rst ================================================ .. IVXV kogumisteenuse haldusjuhend Lisad ===== .. _utiliidid: Utiliidid --------- Kogumisteenuse haldamise käsureautiliitide ülevaade ja abiteave. .. contents:: . :local: :depth: 1 Andmehoidla utiliidid ^^^^^^^^^^^^^^^^^^^^^ .. include:: utiliitide-abiteave/ivxv-create-data-dirs.inc .. include:: utiliitide-abiteave/ivxv-db-reset.inc .. include:: utiliitide-abiteave/ivxv-db-dump.inc Teenuse seisundi utiliidid ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. include:: utiliitide-abiteave/ivxv-status.inc .. include:: utiliitide-abiteave/ivxv-service.inc Sündmuste logi utiliidid ^^^^^^^^^^^^^^^^^^^^^^^^ .. include:: utiliitide-abiteave/ivxv-eventlog-dump.inc Kasutajate halduse utiliidid ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. include:: utiliitide-abiteave/ivxv-users-list.inc Seadistusutiliidid ^^^^^^^^^^^^^^^^^^ .. include:: utiliitide-abiteave/ivxv-collector-init.inc .. include:: utiliitide-abiteave/ivxv-cmd-load.inc .. include:: utiliitide-abiteave/ivxv-config-validate.inc .. include:: utiliitide-abiteave/ivxv-config-apply.inc Seadistuste rakendamine hallatavatele teenustele on võimalik siis, kui haldusteenusesse on laaditud kogumisteenuse tehnilised seadistused. Seadistuste rakendamise järjekord: #. Tehnilised seadistused koos usaldusjuure seadistustega. #. Teenuse tarkvara paigaldamine; #. Haldusteenuse ligipääsu loomine hallatava teenuse kontole; #. Teenuse logimisseadistuste rakendamine; #. Haldusteenuse ligipääsu eemaldamine teenuse hosti juurkasutaja kontole (ainult juhul, kui teenusmasinas pole rohkem seadistamata teenuseid); #. Usaldusjuure rakendamine teenusele; #. Tehniliste seadistuste rakendamine teenusele; #. Valikute nimekiri; #. Ringkondade nimekiri; #. Valijate nimekirjad; Logikogumisteenus erineb teistest hallatavatest teenustest: #. Logikogumisteenus seadistatakse enne teisi teenuseid, et tagada võimalikult varajane logi kogumine. #. Logikogumisteenustele ei rakendata muid seadistusi peale logikogumisteenuse seadistuste (usaldusjuure seadistusi, kogumisteenuse tehnilised seadistusi ja valimiste seadistusi logikogumisteenus ei vaja). Valimisnimekirjade (valikute ja valijate nimekirjad) rakendamine tähendab nimekirja ülekandmist talletusteenusesse vastavat nimekirja teenindava teenuse kaudu. Näiteks valikute nimekiri rakendatakse vaid ühele (juhuslikult valitud) nimekirjateenusele, mis kannab nimekirja talletusteenusesse. Talletusteenuse kaudu on nimekiri kättesaadav kõigile teistele nimekirjateenustele. .. include:: utiliitide-abiteave/ivxv-voter-list-download.inc .. include:: utiliitide-abiteave/ivxv-secret-load.inc .. include:: utiliitide-abiteave/ivxv-copy-log-to-logmon.inc .. include:: utiliitide-abiteave/ivxv-update-packages.inc .. include:: utiliitide-abiteave/ivxv-backup-crontab.inc Andmete eksportimise ja varundamise utiliidid ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. include:: utiliitide-abiteave/ivxv-export-votes.inc .. include:: utiliitide-abiteave/ivxv-backup.inc .. include:: utiliitide-abiteave/ivxv-generate-processor-input.inc .. include:: utiliitide-abiteave/ivxv-voterstats.inc .. include:: utiliitide-abiteave/ivxv-voting-sessions.inc Deemonid ^^^^^^^^ .. include:: utiliitide-abiteave/ivxv-agent-daemon.inc Sisemised utiliidid ^^^^^^^^^^^^^^^^^^^ .. attention:: Sisemised utiliidid on kasutusel haldusdeemoni poolt alamteenuste haldamiseks ja neid ei ole reeglina tarvis eraldi käivitada. .. include:: utiliitide-abiteave/ivxv-admin-helper.inc .. include:: utiliitide-abiteave/ivxv-admin-sudo.inc Seadistusfailid --------------- .. _ivxv-logcollector.conf: Logikogumisteenuse seadistusfail ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. literalinclude:: ../../../common/collector/config/rsyslog-logcollector.conf :name: /etc/rsyslog.d/ivxv-logcollector.conf :language: text :linenos: Lisaseadistused --------------- .. _configure-ssh-idcard-auth: SSH kasutajate autentimine ID-kaardi abil ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SSH-teenusesse on võimalik autentida ID-kaardi avaliku võtmega abil, kasutades selleks PKCS#11 toega SSH-klienti ``kitty.exe`` (http://kitty.9bis.net/). Turvakaalutustel tuleks keelata haldusliidese SSH-teenusesse parooliga autentimine. Parooliga autentimise keelamiseks tuleb seadistusfailis :file:`/etc/ssh/sshd_config` määrata parameetri ``PasswordAuthentication`` väärtuseks ``no``:: # To disable tunneled clear text passwords, change to no here! PasswordAuthentication no Volitatud kasutajate faili asukoht (:file:`/etc/ssh/kasutajad`) tuleb failis :file:`/etc/ssh/sshd_config` määrata parameetriga ``AuthorizedKeysFile``: ``AuthorizedKeysFile /etc/ssh/kasutajad`` .. important:: Seadistusfailis ``/etc/ssh/sshd_config`` tehtud muutuse rakendamiseks tuleb SSH teenus taaskäivitada:: # service ssh restart [ ok ] Restarting OpenBSD Secure Shell server: sshd. ID-kaardi isikutuvastamise sertifikaadiga autenditava kasutaja ülesseadmine käib järgmiselt: #. Kasutajale konto loomine: .. code-block:: shell-session # adduser --disabled-password kasutajanimi # usermod -a -G www-data kasutajanimi #. Kasutaja ID-kaardi isikutuvastamise sertifikaadi salvestamine PEM-vormingus faili :file:`usercert.cer` (ID-kaardi haldusvahendi abil); #. Sertifikaadist kasutaja avaliku võtme eraldamine ja salvestamine faili :file:`userpubkey.pem`: .. code-block:: shell-session # openssl x509 -in usercert.cer -pubkey -noout > userpubkey.pem #. Avaliku võtme teisendamine PKCS#8 vormingusse, kasutaja tunnusega varustamine ja salvestamine SSH volitatud kasutajate faili :file:`/etc/ssh/kasutajad`: .. code-block:: shell-session # KEY=$(ssh-keygen -i -m PKCS8 -f userpubkey.pem) # echo "$KEY kasutaja@eesti.ee" >> /etc/ssh/kasutajad #. Kontrollimine, kas lisatud kirje on kujul ``ssh-rsa PKCS8-võti`` kasutajatunnus: .. code-block:: shell-session # tail -1 /etc/ssh/kasutajad ssh-rsa AAAAB3NzaC1yc2EAAAAELGuiTwAAAIEAxZf/TuSrGJEU1PlfkY9jJ33VOYVZ9Vao0Uiytlf8 7HJu/78fCIB7m05J7ibpMhsZoZ4DElU7ve0VwbvdDS3srh1OhiQcUjpznTlx4rIM1vkHwadrHtmF+BNi DwbLbbdD5y3puGcLH+sLuwba6Vuc3aU0QuqzenYmY9pV7w9y0wc= kasutaja@eesti.ee Andmehoidla ----------- Haldusteenuse andmeid hoitakse failisüsteemis ja andmebaasis. Failisüsteemis hoitakse andmeid, mis on pärit välistest süsteemidest ja on haldusteenusesse üle kantud faili kujul. Andmebaasis hoitakse andmeid, mis on genereeritud haldusteenuse töö käigus. Failisüsteemis hoitavad andmed ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * :file:`/etc/ivxv/` -- kogumisteenusele rakendatud ja hetkel kehtivad seadistus- ja nimekirjafailid; * :file:`/var/lib/ivxv/` -- kogumisteenuse haldusteenuse andmefailid; * :file:`/var/lib/ivxv/admin-ui-data/` -- haldusteenuse veebiliidese jaoks serveeritavad JSON-failid; * :file:`/var/lib/ivxv/admin-ui-data/status.json` -- kogumisteenuse seisundi koondandmed; * :file:`/var/lib/ivxv/admin-ui-permissions/` -- haldusteenuse veebiliidese kasutajaõigused (Apache veebiserveri jaoks); * :file:`/var/lib/ivxv/ballot-box/` -- allalaaditava e-valimiskasti salvestamise kataloog; * :file:`/var/lib/ivxv/commands/` -- kogumisteenuse juhtimiseks rakendatud korraldusfailide ajalugu; * :file:`/var/lib/ivxv/commands/-.bdoc` -- digitaalselt allkirjastatud korraldus ``ASiC-E`` vormingus. * :file:`/var/lib/ivxv/commands/-.json` -- korralduse olekufail JSON-vormingus. * :file:`/var/lib/ivxv/db/` -- haldusteenuse andmebaasi kataloog; * :file:`/var/lib/ivxv/db/ivxv-management.db` -- haldusteenuse andmebaasi fail; * :file:`/var/lib/ivxv/ivxv-management-events.log` -- haldusteenuse sündmuste logi; * :file:`/var/lib/ivxv/service/` -- muud teenusespetsiifilised failid (nt. registreerimisvõtmest eraldatud avalik võti); * :file:`/var/lib/ivxv/upload/` -- kogumisteenusesse veebiliidese kaudu laaditud failid; Andmebaasis hoitavad andmed ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Andmevälja nimi ja kirjeldus: * ``collector/state`` -- kogumisteenuse olek; * ``config/election`` -- kogumisteenuses rakendatud valimiste seadistusele digiallkirja andnud volitatud kasutaja andmed kujul `` ``; * ``config/technical`` -- kogumisteenuses rakendatud tehnilisele seadistusele digiallkirja andnud volitatud kasutaja andmed kujul `` ``; * ``config/trust`` -- kogumisteenuses rakendatud usaldusjuure seadistusele digiallkirja andnud volitatud kasutaja andmed kujul `` ``; * ``election/election-id`` -- valimiste identifikaator; * ``election/electionstart`` -- valimiste algusaeg; * ``election/electionstop`` -- valimiste lõpuaeg; * ``election/servicestart`` -- kogumisteenuse käivitamise aeg; * ``election/servicestop`` -- kogumisteenuse seiskamise aeg; * ``host//state`` -- teenushosti seisund; * ``list/choices`` -- haldusteenusesse laaditud valikute nimekirjale digiallkirja andnud volitatud kasutaja andmed kujul `` ``; * ``list/choices-loaded`` -- nimekirjateenustesse laaditud valikute nimekirjale digiallkirja andnud volitatud kasutaja andmed kujul `` ``; * ``list/districts`` -- nimekirjateenustesse laaditud ringkondade nimekirjale digiallkirja andnud volitatud kasutaja andmed kujul `` ``; * ``list/districts-loaded`` -- nimekirjateenustesse laaditud ringkondade nimekirjale digiallkirja andnud volitatud kasutaja andmed kujul `` ``; * ``list/voters0000`` -- haldusteenusesse laaditud valijate algnimekirjale digiallkirja andnud volitatud kasutaja andmed kujul `` ``; * ``list/voters`` (``list-number >= 01``) -- haldusteenusesse laaditud valijate muudatusnimekirja allalaadimise hetke ajatempel; * ``list/voters-state`` -- nimekirjateenustesse laaditud valijate nimekirja olek. Võimalikud väärtused: 1. ``PENDING`` - laaditud haldusteenusesse; 2. ``APPLIED`` - rakendatud nimekirjateenusele; 3. ``INVALID`` - nimekiri on märgitud vigaseks ja ootab halduri otsust vahelejätmise kohta (ainult muudatusnimekirja korral); 4. ``SKIPPED`` - nimekiri on vahele jäetud (ainult muudatusnimekirja korral). * ``logmonitor/address`` -- seireteenuse aadress või võrgunimi; * ``logmonitor/last-data`` -- viimase seireteenusest statistikafaili hankimise aeg; * ``user/`` -- haldusteenuse kasutaja nimi ja rollid kujul `` [,]``; * ``service//service-type`` -- Teenuse liik; * ``service//technical-conf-version`` -- Teenusele rakendatud tehnilise seadistuse versioon; * ``service//election-conf-version`` -- Teenusele rakendatud valimiste seadistuse versioon; * ``service//network`` -- Teenusele alamvõrgu nimi; * ``service//state`` -- Teenuse olek; * ``service//ping-errors`` -- Teenuse elusoleku kontrollimise järjestikuste vigade arv; * ``service//last-data`` -- Teenuse viimase oleku hankimise aeg; * ``service//ip-address`` -- Teenuse IP-aadress; * ``service//bg_info`` -- Teenuse taustainfo stringina (näiteks elusoleku kontrolli käigus genereeritud veateade); * ``service//backup-times`` -- Varundusteenuse automaatvarunduse kellaajad; * ``service//mid-token-key`` -- Mobiil-ID/Smart-ID/Web eID tugiteenuse identsustõendi võtmefaili kontrollsumma (SHA256); * ``service//tls-cert`` -- Teenuse TLS-sertifikaadi faili kontrollsumma (SHA256); * ``service//tls-key`` -- Teenuse TLS-sertifikaadi võtmefaili kontrollsumma (SHA256); * ``service//tspreg-key`` -- Hääletamisteenuse ajatempliteenuse signeerimisvõtme faili kontrollsumma (SHA256); Kasutatud tähised: * ```` -- korralduse liik: #. ``trust`` -- usaldusjuure seadistused; #. ``technical`` kogumisteenuse seadistused; #. ``election`` valimiste seadistused; * ```` -- ID-kaardi CN väli kujul ``PEREKONNANIMI,EESNIMI,ISIKUKOOD``; * ```` on seadistuse liik. Usaldusjuure seadistus on ``trust``, valimiste seadistus on ``election`` ja kogumisteenuse tehniline seadistus on ``tech``; * ```` teenushosti nimi; * ```` valimisnimekirja kahekohaline järjekorranumber, esimene nimekiri kannab numbrit 01. * ```` teenuse identifikaator kogumisteenuse seadistustest; * ```` on ajatempel ISO-8601 vormingus. .. _etcd-zabbix: Klastri seisundi monitoorimine Zabbixiga ---------------------------------------- Etcd klaster tagab süsteemi toimimise ka olukorras, kus mõni klastriliige kaotab töövõime (krahh, võrguühenduse kadumine jms.). Siiski on oluline selliseid sündmuseid monitoorida ning nende algpõhjus tuvastada. Etcd krahhimise tuvastamiseks tuleb talletusteenuste logidest (``ivxv-YYYY-MM-DD-HH.log``) monitoorida ``ivxv.ee/service/storage.EtcdTerminatedError`` kirjet. Täiendavalt saab etcd käsureakliendiga küsida klastri liikmete olekut. Kuna IVXV klastris on kõik klient-päringud autenditud, siis tuleb korraldus käivitada mõnes ``ivxv-storage`` teenuse masinas kasutajakonto ``ivxv-storage`` (või juurkasutaja) õigustes: .. code-block:: shell-session # ivxv-storage@ivxv1:~$ env ETCDCTL_API=3 etcdctl \ --cacert /var/lib/ivxv/service/storage@storage1.ivxv.ee/ca.pem \ --cert /var/lib/ivxv/service/storage@storage1.ivxv.ee/tls.pem \ --key /var/lib/ivxv/service/storage@storage1.ivxv.ee/tls.key \ --endpoints ivxv1:2379,ivxv2:2379,ivxv3:2379 \ endpoint status ivxv1:2379, 2d0df029f29770a4, 3.2.17, 25 kB, true, 12, 15 ivxv2:2379, d4a9ae16c8557764, 3.2.17, 25 kB, false, 12, 15 ivxv3:2379, e8914f4e0b89b80f, 3.2.17, 25 kB, false, 12, 15 Vastuses on veergude tähendused järgmised: #. klastri liige; #. klastri liikme identifikaator; #. etcd versioon; #. baasi suurus (max 8GB ehk 8589934592); #. kas konkreetne klastri liige on hetkel juht; #. RAFT ametiaeg (sisuliselt toimunud juhi-valimiste arv); #. RAFT indeks - etcd kirjutamisoperatsioonide arv (sh. konfiguratsiooni muutused). Monitooringule on oluline parameeter RAFT ametiaeg. Selle väärtuse muutumine tähendab juhivahetust, mis üldjuhul on seotud probleemidega klastri töös - olemasolev juht ei vasta piisavalt kiiresti klastri liikmete päringutele. Käsurea seletus: * ``env ETCDCTL_API=3``: kasutame etcd API versiooni 3 (Ubuntu versioonis 20.04 LTS on ``etcdctl`` API vaikeversioon veel 2); * ``--cacert``: usaldame ainult servereid, mille sertifikaat on antud selle CA poolt; * ``--cert`` ja ``--key``: kasutame klient-autentimiseks ivxv1 talletusteenuse sertifikaati ja võtit; * ``--endpoints``: millistele serveritele päring saata. Siin võib kõigi kolme asemel ka ainult ühe loetleda: sellisel juhul on väljundis vaid üks rida. Kasulik nt kui Zabbix tahab igas talletusteenuses küsida ainult selle isendi kohta; * ``endpoint status``: küsime loetletud serverite olekut. Väljundit on võimalik küsida ka masinloetavas JSON-vormingus (parameeter ``-w json``): .. code-block:: shell-session ivxv-storage@ivxv1:~$ env ETCDCTL_API=3 etcdctl \ --cacert /var/lib/ivxv/service/storage@storage1.ivxv.ee/ca.pem \ --cert /var/lib/ivxv/service/storage@storage1.ivxv.ee/tls.pem \ --key /var/lib/ivxv/service/storage@storage1.ivxv.ee/tls.key \ --endpoints ivxv1:2379,ivxv2:2379,ivxv3:2379 \ endpoint status -w json [{"Endpoint":"ivxv1:2379","Status":{"header":{"cluster_id":1867986262344190226,"member_id":3246514969358332068,"revision":1,"raft_term":12},"version":"3.2.17","dbSize":24576,"leader":3246514969358332068,"raftIndex":15,"raftTerm":12}}, {"Endpoint":"ivxv2:2379","Status":{"header":{"cluster_id":1867986262344190226,"member_id":15323970619978381156,"revision":1,"raft_term":12},"version":"3.2.17","dbSize":24576,"leader":3246514969358332068,"raftIndex":15,"raftTerm":12}}, {"Endpoint":"ivxv3:2379","Status":{"header":{"cluster_id":1867986262344190226,"member_id":16758262885041944591,"revision":1,"raft_term":12},"version":"3.2.17","dbSize":24576,"leader":3246514969358332068,"raftIndex":15,"raftTerm":12}}] ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/protseduurid.rst ================================================ .. IVXV kogumisteenuse haldusjuhend Protseduurid ============ .. _recovery-stateless: Juhend: olekuvaba mikroteenuse isendi taastamine krahhist --------------------------------------------------------- .. include:: recovery/recovery_stateless.inc .. _recovery-logcollection: Juhend: logikogumisteenuse isendi taastamine krahhist ----------------------------------------------------- .. include:: recovery/recovery_logcollection.inc .. _recovery-backupservice: Juhend: varundusteenuse isendi taastamine krahhist -------------------------------------------------- .. include:: recovery/recovery_backupservice.inc .. _recovery-storageservice: Juhend: talletusteenuse isendi taastamine krahhist -------------------------------------------------- .. include:: recovery/recovery_storageservice.inc .. _recovery-fullstorage: Juhend: talletusteenuse taastamine täielikust krahhist ------------------------------------------------------ .. include:: recovery/recovery_fullstorage.inc ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/recovery/recovery_backupservice.inc ================================================ Krahhi toimumise indikaatorid ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Haldusveebiliides. Vali **Teenused** vasakult menüüst. Kui varundusteenus on krahhinud, siis tema **Seisund** on **Tõrge**. Halduskäsurealiides. Logi sisse **ivxv-admin** kasutajana ja päri teenuste statistikat:: $ sudo su - ivxv-admin $ ivxv-status Kui varundusteenus on krahhinud, siis tema **State** on **FAILURE**. Krahhist taastumise eeldused ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Krahhist taastumine on alati võimalik. Krahhi võimalik mõju hääletamistulemusele ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Varundusteenuse krahh mõjutab hääletamistulemust (andmekadu), kui täiendavalt krahhib ka talletusteenus. Krahhist taastumise sammud ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. seealso:: * Kasuta :ref:`recovery-stateless` juhendis oleva **Teenuse masin on krahhinud, v.a vahendus- ja x-tee teenused** peatükki, v.a sammud 8, 10, 12-16. .. note:: Punktis 10 tuleb välja vahetada ainult varundusteenuse **id** ja **address** väljad: .. code-block:: yaml - id: zone0 services: log: - id: backup@backup1.ivxv.ee address: backup1 uute vastu: .. code-block:: yaml - id: zone0 services: log: - id: backup@backup2.ivxv.ee address: backup2 SSH logi sisse haldusmasinasse **ivxv-admin** kasutajana:: $ sudo su - ivxv-admin Seadista SSH ühenduse loomiseks *prompt* sõnumi *Are you sure you want to continue connecting (yes/no)? yes* kinnitamist vältida, näiteks, kui varundusteenuse masina DNS **address** on *backup2*:: $ ssh backup2 $ echo "StrictHostKeyChecking no" >> /var/lib/ivxv/user/ivxv-admin/.ssh/config ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/recovery/recovery_fullstorage.inc ================================================ Krahhi toimumise indikaatorid ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Haldusveebiliides. Vali **Teenused** vasakult menüüst. Kui talletusteenused on krahhinud, siis tema **Seisund** on **Tõrge**. Halduskäsurealiides. Logi sisse **ivxv-admin** kasutajana ja päri teenuste statistikat:: $ sudo su - ivxv-admin $ ivxv-status Kui talletusteenused on krahhinud, siis tema **State** on **FAILURE**. Krahhist taastumise eeldused ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Krahhi taastumiseks piisab kui teenuste CA TLS privaatvõti ja sertifikaat on alles, mida saab kasutada teenuse varuvõtmete ja -sertifikaatide genereerimiseks. Samas, saab ka enne valimisi teenuse varuvõtmed ja -sertifikaadid ette genereerida. Kui kõikide teenuste CA on sama, siis tasub valija- ja kontrollrakenduste seadistusse panna hoopis CA TLS sertifikaadi. Juhul kui CA on teenustel erinev, siis peab panema kõik teenuste TLS sertifikaadid rakenduste seadistusse vahetult enne valimisi. Krahhi võimalik mõju hääletamistulemusele ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Kui krahhib talletusteenuse klaster, siis kindlasti tegu on andmekaoga. Andmekao suurus sõltub varundusteenusest ehk kui tihti e-urni varundati. Lisaks, juba hääletanud valijal võivad tekkida segadus, kui teist korda hääletades, kuvatakse valijarakenduses "Teie pole veel hääletanud" tervitustekst. Krahhist taastumise sammud ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. seealso:: * Tee :ref:`recovery-storageservice` juhendis oleva **Teenuse andmed (võti, sertifikaat jne) on rikutud või masina krahh** peatükki protseduurid läbi iga uue koguja masina jaoks. .. note:: Punktis 10 tuleb välja vahetada kõik vanad **id** ja **address** kirjed uute vastu, lisaks tuleb muuta ka talletusteenuse **bootstrap** seadistust: .. code-block:: yaml bootstrap: - storage@storage1.ivxv.ee - storage@storage2.ivxv.ee - storage@storage3.ivxv.ee selliselt: .. code-block:: yaml bootstrap: - storage@storage4.ivxv.ee - storage@storage5.ivxv.ee - storage@storage6.ivxv.ee Nüüd tuleb taastada koguja krahhieelne seisund, v.a kaotsi läinud hääled: #. SSH logi sisse haldusmasinasse **ivxv-admin** kasutajana:: $ sudo su - ivxv-admin #. Laadi ringkondade nimekiri:: $ ivxv-config-apply --type=districts #. Laadi valikute nimekiri:: $ ivxv-config-apply --type=choices #. Laadi nii valijate alg-, kui ka kõik vahepealsed muudatusnimekirjad:: $ ivxv-config-apply --type=voters .. warning:: Ära unusta, et valimiste lõpus tuleb hääli alla laadida koos varundatud häältega, et vähemalt mingis ulatuses tagada e-urni terviklikkus:: $ ivxv-export-votes --consolidate ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/recovery/recovery_logcollection.inc ================================================ Krahhi toimumise indikaatorid ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Haldusveebiliides. Vali **Teenused** vasakult menüüst. Kui logikogumisteenus on krahhinud, siis tema **Seisund** on **Tõrge**. Halduskäsurealiides. Logi sisse **ivxv-admin** kasutajana ja päri teenuste statistikat:: $ sudo su - ivxv-admin $ ivxv-status Kui logikogumisteenus on krahhinud, siis tema **State** on **FAILURE**. Krahhist taastumise eeldused ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Krahhist taastumine on alati võimalik. Krahhi võimalik mõju hääletamistulemusele ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Hääletamistulemusele mõju puudub, küll aga krahhinud logikogumisteenusega kaob ka osa varundatud logidest, mida enam taastada ei ole võimalik. Samas, need logid on ikkagi endiselt alles koguja masinates, ning ka logimonitori masinas. Ainus koht kus avaldub logikogumisteenuse krahh on varundusteenuse masin, kus jääbki puudu osa varundatud logidest. Krahhist taastumise sammud ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. seealso:: * Kasuta :ref:`recovery-stateless` juhendis oleva **Teenuse masin on krahhinud, v.a vahendus- ja x-tee teenused** peatükki, v.a sammud 10, 12-16. .. note:: Punktis 10 tuleb välja vahetada ainult logikogumisteenuse **id** ja **address** väljad: .. code-block:: yaml - id: zone0 services: log: - id: log@log1.ivxv.ee address: log1:20514 uute vastu: .. code-block:: yaml - id: zone0 services: log: - id: log@log2.ivxv.ee address: log2:20514 ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/recovery/recovery_stateless.inc ================================================ Krahhi toimumise indikaatorid ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Haldusveebiliides. Vali **Teenused** vasakult menüüst. Kui teenus on krahhinud, siis tema **Seisund** on **Tõrge**. Halduskäsurealiides. Logi sisse **ivxv-admin** kasutajana ja päri teenuste statistikat:: $ sudo su - ivxv-admin $ ivxv-status Kui teenus on krahhinud, siis tema **State** on **FAILURE**. Krahhist taastumise eeldused ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Krahhist taastumiseks piisab kui teenuste CA TLS privaatvõti ja sertifikaat on alles, mida saab kasutada teenuse varuvõtmete ja -sertifikaatide genereerimiseks. Samas, saab ka enne valimisi teenuse varuvõtmed ja -sertifikaadid ette genereerida. Kui kõikide teenuste CA on sama, siis tasub valija- ja kontrollrakenduste seadistusse panna hoopis CA sertifikaat. Juhul kui CA on teenustel erinev, siis peab panema kõik teenuste TLS sertifikaadid rakenduste seadistusse vahetult enne valimisi. Krahhi võimalik mõju hääletamistulemusele ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Sõltuvalt teenusest võivad tagajärjed olla järgmised: * kui krahhivad nimekirja-, Mobiil-ID, vahendus-, seansi-, Smart-ID, hääletamis-, Web-eID teenused, siis valijal ei õnnestu hääletada * kui krahhivad järjekorra- ja x-tee teenused, siis VIS ei saa pärida andmeid x-tee kaudu * kui krahhib verifitseerimisteenus, siis valijal ei õnnestu oma häält verifitseerida Krahhist taastumise sammud ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. seealso:: * Talletusteenust antud juhendis ei käsitleta, selleks on eraldi juhend :ref:`recovery-storageservice` Krahhi saab liigitada järgmiselt: #. Teenus on terve, ning vajab ainult taaskäivitamist, v.a x-tee teenus #. Teenuse andmed (TLS privaatvõti, sertifikaat jne) on rikutud, v.a vahendus- ja x-tee teenused #. Teenuse lähtekoodis on viga, v.a x-tee teenus #. X-tee teenuse taastumine, sh. krahh ja lähtekoodi viga #. Teenuse masin on krahhinud, v.a vahendus- ja x-tee teenused #. Vahendusteenuse masin on krahhinud Teenus on terve, ning vajab ainult taaskäivitamist, v.a x-tee teenus ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. SSH logi sisse haldus masinasse **ivxv-admin** kasutajana:: $ sudo su - ivxv-admin #. Taaskäivita teenus, näiteks nimekirjateenust:: $ ivxv-service restart choices@choices1.ivxv.ee Teenuse andmed (TLS privaatvõti, sertifikaat jne) on rikutud, v.a vahendus- ja x-tee teenused ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. Vaheta välja krahhinud teenuse **id** tehnilises seadistuses varuteenuse **id** vastu, mille TLS privaatvõti ja sertifikaat on genereeritud #. Allkirjasta tehniline seadistus #. Laadi seadistus läbi haldusveebiliidese **Seadistused** #. SSH logi sisse haldusmasinasse **ivxv-admin** kasutajana:: $ sudo su - ivxv-admin #. Laadi TLS privaatvõti ja sertifikaat, näiteks nimekirjateenus:: $ ivxv-secret-load --service=choices@choices4.ivxv.ee tls-key /opt/ivxv-install/service_definition/choices@choices4.ivxv.ee.key $ ivxv-secret-load --service=choices@choices4.ivxv.ee tls-cert /opt/ivxv-install/service_definition/choices@choices4.ivxv.ee.pem #. Kui tegu on nimekirja-, Mobiil-ID, Smart-ID, hääletamis-, Web-eID või verifitseerimisteenusega siis tuleb üles laadida ka küpsiste allkirjatamiseks privaatvõti:: $ ivxv-secret-load mid-token-key /opt/ivxv-install/service_definition/ticket.key #. Kui tegu on hääletamisteenusega siis tuleb üles laadida TSP vastuse räsi allkirjastamiseks privaatvõti:: $ ivxv-secret-load tsp-regkey /opt/ivxv-install/service_definition/tspreg.key #. Käivita teenused:: $ ivxv-config-apply --type=election Teenuse lähtekoodis on viga, v.a x-tee teenus ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. Kopeeri uus *.deb* pakk haldusmasinasse #. SSH logi sisse haldusmasinasse **sudo** kasutajana:: $ sudo su #. Kopeeri *.deb* pakk */etc/ivxv/debs/* kausta #. Logi **sudo** kasutajalt välja:: $ exit #. SSH logi sisse haldusmasinasse **ivxv-admin** kasutajana:: $ sudo su - ivxv-admin #. Uuenda teenuse *.deb* pakki kõikides masinates, näiteks nimekirjateenus:: $ ivxv-update-packages --service=choices --package=/etc/ivxv/debs/ivxv-choices_1.9.12~dev_amd64.deb #. Taaskäivita teenus igal hostil, näiteks taaskäivitame nimekirjateenuse kolmeõlgse seadistuse korral:: $ ivxv-service restart choices@choices1.ivxv.ee $ ivxv-service restart choices@choices2.ivxv.ee $ ivxv-service restart choices@choices3.ivxv.ee X-tee teenuse taastumine, sh. krahh ja lähtekoodi viga ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. Esmalt tasub proovida taaskäivitada systemd x-tee teenust:: $ sudo systemctl restart xroad-service #. Ebaõnnestumise korral tuleb tarnida uus *.deb* pakk, ning vana pakk eemaldada:: $ sudo apt purge xroad-service #. Kui uus *.deb* pakk on masinasse kopeeritud, tuleb see paigaldada:: $ sudo apt install ./xroad-service_*.deb #. Kasuta x-tee teenuse juhendit, et paigaldada TLS sertifikaadid õigesse kaustadesse #. Käivita systemd x-tee teenus:: $ sudo systemctl start xroad-service Teenuse masin on krahhinud, v.a vahendus- ja x-tee teenused ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. Paigalda värske Ubuntu masin .. important:: Palun täpsusta üle, millist Ubuntu versiooni parasjagu kasutatakse #. Paigalda teenuse masinasse baastarkvara pakid APT pakihoidlast:: $ sudo apt-get install acl locales unzip zstd --yes #. Nüüd tuleb haldus-, koguja-, varundus-, logi-, vahendus-, logi monitooringu masinate **ip** ja DNS **nimi** lisada uue teenuse masina */etc/hosts* faili #. Seejärel tuleb haldus-, koguja-, varundus-, logi-, vahendus masinates kustutada krahhinud teenuse masina **ip** ja DNS **nimi** ning lisada uus .. attention:: See on kõige olulisem samm, kuna siin peab valima sellise DNS **nime**, mille tulevikus lisame tehnilistesse seadistustesse. Reegel on lihtne, et iga uue teenuse masina DNS **nimi** peab olema unikaalne ja ei tohi olla sama, mis krahhinud teenuste masinatele olid varem omistatud. Haldusteenuse andmebaasis on registreeritud kõigi süsteemis leiduvate masinate DNS **nimed**, isegi krahhinud isendite omad. Haldusteenuse eripära seisneb selles, et see ei paigalda tarkvara masinatele, mille DNS **nimi** on juba haldusteenuse andmebaasis registreeritud. #. SSH logi sisse haldusmasinasse **ivxv-admin** kasutajana:: $ sudo su - ivxv-admin #. Kuna haldusteenus paigaldab vajaliku taristu kõikidele süsteemi masinatele automaatselt, siis on vaja vältida SSH ühenduse loomisel *prompt* sõnumi *Are you sure you want to continue connecting (yes/no)? yes* kinnitamist. Kustuta vana teenusmasina SSH avalik võti */etc/ssh/ssh_known_hosts* failist, ning lisa uus, näiteks, kui uue teenuse masina DNS **nimi** on *ivxv4*:: $ ssh-keyscan -t ecdsa ivxv4 | grep -v ^# >> /etc/ssh/ssh_known_hosts #. SSH logi sisse uue teenuse masinasse **root** kasutajana:: $ sudo su #. Kuna haldusteenus edastab teenuse logid logimonitori, lisaks *syslog* *RELP* protokollile, ka üle SSH protokolli, siis on vaja samuti vältida SSH ühenduse loomisel *prompt* sõnumi kinnitamist, näiteks, monitooringu masina *logmonitor* DNS **address** korral:: $ ssh-keyscan -t ecdsa logmonitor | grep -v ^# >> /etc/ssh/ssh_known_hosts #. Kuna haldusteenus peab paigaldama tarkvara APT pakihoidlast, mis on võimatu juurkasutaja õiguseid omandamata, pead kopeerima haldusmasina SSH avaliku võtme, mis asub */var/lib/ivxv/user/ivxv-admin/.ssh/id_ed25519.pub* failis, ning lisama selle uue teenuse masina */root/.ssh/authorized_keys* faili #. Nüüd tuleb tehnilistes seadistustes välja vahetada teenuste **id** ja **nimed** (**address**), näiteks: .. code-block:: yaml - id: zone1 services: mid: - id: mid@mid1.ivxv.ee address: ivxv1:4441 choices: - id: choices@choices1.ivxv.ee address: ivxv1:4442 voting: - id: voting@voting1.ivxv.ee address: ivxv1:4443 verification: - id: verification@verification1.ivxv.ee address: ivxv1:4444 smartid: - id: smartid@smartid1.ivxv.ee address: ivxv1:4445 votesorder: - id: votesorder@votesorder1.ivxv.ee address: ivxv1:4446 webeid: - id: webeid@webeid1.ivxv.ee address: ivxv1:4447 origin: https://ivxv1.test.ivxv.ee:443 sessionstatus: - id: sessionstatus@sessionstatus1.ivxv.ee address: ivxv1:4448 uute **id** ja **address** vastu: .. code-block:: yaml - id: zone1 services: mid: - id: mid@mid4.ivxv.ee address: ivxv4:4441 choices: - id: choices@choices4.ivxv.ee address: ivxv4:4442 voting: - id: voting@voting4.ivxv.ee address: ivxv4:4443 verification: - id: verification@verification4.ivxv.ee address: ivxv4:4444 smartid: - id: smartid@smartid4.ivxv.ee address: ivxv4:4445 votesorder: - id: votesorder@votesorder4.ivxv.ee address: ivxv4:4446 webeid: - id: webeid@webeid4.ivxv.ee address: ivxv4:4447 origin: https://ivxv4.test.ivxv.ee:443 sessionstatus: - id: sessionstatus@sessionstatus4.ivxv.ee address: ivxv4:4448 .. attention:: Pane tähele, et on muutunud nii **id** kui ka **address**. Vahendus- ja talletusteenuste **id** ja **address** jäävad samaks **siis ja ainult siis**, kui need teenused ei olnud krahhinud masina koosseisus, vastasel juhul tuleb sarnaselt muuta ka nende teenuste **id** ja **address**. #. Allkirjasta uus tehniline seadistus. Laadi see läbi haldusveebiliidese, vasakult valides **Seadusted**. #. SSH logi sisse haldusmasinasse **ivxv-admin** kasutajana:: $ sudo su - ivxv-admin #. Laadi kõik teenuste TLS privaatvõtmed ja sertifikaadid, näiteks:: $ ivxv-secret-load --service=choices@choices4.ivxv.ee tls-key /opt/ivxv-install/service_definition/choices@choices4.ivxv.ee.key $ ivxv-secret-load --service=voting@voting4.ivxv.ee tls-key /opt/ivxv-install/service_definition/voting@voting4.ivxv.ee.key $ ivxv-secret-load --service=mid@mid4.ivxv.ee tls-key /opt/ivxv-install/service_definition/mid@mid4.ivxv.ee.key $ ivxv-secret-load --service=smartid@smartid4.ivxv.ee tls-key /opt/ivxv-install/service_definition/smartid@smartid4.ivxv.ee.key $ ivxv-secret-load --service=sessionstatus@sessionstatus4.ivxv.ee tls-key /opt/ivxv-install/service_definition/sessionstatus@sessionstatus4.ivxv.ee.key $ ivxv-secret-load --service=verification@verification4.ivxv.ee tls-key /opt/ivxv-install/service_definition/verification@verification4.ivxv.ee.key $ ivxv-secret-load --service=votesorder@votesorder4.ivxv.ee tls-key /opt/ivxv-install/service_definition/votesorder@votesorder4.ivxv.ee.key $ ivxv-secret-load --service=webeid@webeid4.ivxv.ee tls-key /opt/ivxv-install/service_definition/webeid@webeid4.ivxv.ee.key $ ivxv-secret-load --service=choices@choices4.ivxv.ee tls-cert /opt/ivxv-install/service_definition/choices@choices4.ivxv.ee.pem $ ivxv-secret-load --service=voting@voting4.ivxv.ee tls-cert /opt/ivxv-install/service_definition/voting@voting4.ivxv.ee.pem $ ivxv-secret-load --service=mid@mid4.ivxv.ee tls-cert /opt/ivxv-install/service_definition/mid@mid4.ivxv.ee.pem $ ivxv-secret-load --service=smartid@smartid4.ivxv.ee tls-cert /opt/ivxv-install/service_definition/smartid@smartid4.ivxv.ee.pem $ ivxv-secret-load --service=sessionstatus@sessionstatus4.ivxv.ee tls-cert /opt/ivxv-install/service_definition/sessionstatus@sessionstatus4.ivxv.ee.pem $ ivxv-secret-load --service=verification@verification4.ivxv.ee tls-cert /opt/ivxv-install/service_definition/verification@verification4.ivxv.ee.pem $ ivxv-secret-load --service=votesorder@votesorder4.ivxv.ee tls-cert /opt/ivxv-install/service_definition/votesorder@votesorder4.ivxv.ee.pem $ ivxv-secret-load --service=webeid@webeid4.ivxv.ee tls-cert /opt/ivxv-install/service_definition/webeid@webeid4.ivxv.ee.pem #. Lisa küpsiste signeerimisvõti:: $ ivxv-secret-load mid-token-key /opt/ivxv-install/service_definition/ticket.key #. Lisa hääletamisteenuse TSP räsi signeerimisvõti:: $ ivxv-secret-load tsp-regkey /opt/ivxv-install/service_definition/tspreg.key #. Käivita teenused:: $ ivxv-config-apply --type=election Vahendusteenuse masin on krahhinud ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. seealso:: * Kasuta käesoleva juhendi **Teenuste masin on krahhinud, v.a vahendus- ja x-tee teenused** peatükki, v.a punktid 6, 10-12. .. note:: Punktis 8 tuleb ainult asendada vana vahendusteenuse **id** ja **address**: .. code-block:: yaml - id: zone1 services: proxy: - id: proxy@proxy1.ivxv.ee address: proxy1:443 uute vastu: .. code-block:: yaml - id: zone1 services: proxy: - id: proxy@proxy4.ivxv.ee address: proxy4:443 ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/recovery/recovery_storageservice.inc ================================================ Krahhi toimumise indikaatorid ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Haldusveebiliides. Vali **Teenused** vasakult menüüst. Kui talletusteenus on krahhinud, siis tema **Seisund** on **Tõrge**. Halduskäsurealiides. Logi sisse **ivxv-admin** kasutajana ja päri teenuste statistikat:: $ sudo su - ivxv-admin $ ivxv-status Kui talletusteenus on krahhinud, siis tema **State** on **FAILURE**. Krahhist taastumise eeldused ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Krahhi taastumiseks piisab kui teenuste CA TLS privaatvõti ja sertifikaat on alles, mida saab kasutada teenuse varuvõtmete ja -sertifikaatide genereerimiseks. Samas, saab ka enne valimisi teenuse varuvõtmed ja -sertifikaadid ette genereerida. Kui kõikide teenuste CA on sama, siis tasub valija- ja kontrollrakenduste seadistusse panna hoopis CA TLS sertifikaadi. Juhul kui CA on teenustel erinev, siis peab panema kõik teenuste TLS sertifikaadid rakenduste seadistusse vahetult enne valimisi. Krahhi võimalik mõju hääletamistulemusele ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Kõik päringud mis saadetakse vastu krahhinud talletusteenuse masinat ebaõnnestuvad. Valija ei saa autentida, ega hääletada. Krahhist taastumise sammud ^^^^^^^^^^^^^^^^^^^^^^^^^^ Krahhi saab liigitada järgmiselt: #. Talletusteenus on terve, ning vajab ainult taaskäivitamist #. Talletusteenuse andmed (võti, sertifikaat jne) on rikutud või masina krahh #. Talletusteenuse lähtekoodis on viga Talletusteenus on terve, ning vajab ainult taaskäivitamist ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. seealso:: * Kasuta :ref:`recovery-stateless` juhendis oleva **Teenus on terve, ning vajab ainult taaskäivitamist, v.a x-tee teenus** peatükki Talletusteenuse andmed (võti, sertifikaat jne) on rikutud või masina krahh ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. seealso:: * Kasuta :ref:`recovery-stateless` juhendis oleva **Teenuse masin on krahhinud, v.a vahendus- ja x-tee teenused** peatükki .. note:: Punktis 10 tuleb asendada vana talletusteenuse **id** ja **address** väljad: .. code-block:: yaml - id: zone1 services: storage: - id: storage@storage1.ivxv.ee address: ivxv1:2379 peeraddress: ivxv1:2380 uute vastu: .. code-block:: yaml - id: zone1 services: storage: - id: storage@storage4.ivxv.ee address: ivxv4:2379 peeraddress: ivxv4:2380 Punktis 12 tuleb uuendada ka talletusteenuse TLS privaatvõti:: $ ivxv-secret-load --service=storage@storage4.ivxv.ee tls-key /opt/ivxv-install/service_definition/storage@storage4.ivxv.ee.key ja sertifikaat::: $ ivxv-secret-load --service=storage@storage4.ivxv.ee tls-cert /opt/ivxv-install/service_definition/storage@storage4.ivxv.ee.pem Veendu, et asendamine läks sujuvalt läbi: #. SSH logi uue koguja masinasse *root* kasutajana:: $ sudo su #. Päri andmebaasi klastri seisu, näiteks, kui klaster koosneb *ivxv4*, *ivxv2*, *ivxv3* masinatest:: $ cd /var/lib/ivxv/service/storage@storage4.ivxv.ee $ env ETCDCTL_API=3 etcdctl --endpoints=ivxv4:2379,ivxv2:2379,ivxv3:2379 --cert tls.pem --key tls.key --cacert ca.pem endpoint status -w table Talletusteenuse lähtekoodis on viga ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Kui talletusteenuse lähtekoodis on viga, siis seda saab asendada uuema versiooniga, olemasoleva andmebaasi klastrit rikumata. .. seealso:: * Kasuta :ref:`recovery-stateless` juhendis oleva **Teenuse lähtekoodis on viga, v.a x-tee teenus** peatükki ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/seadistused.rst ================================================ .. IVXV kogumisteenuse haldusjuhend Kogumisteenuse seadistused ========================== Logimise seadistused -------------------- Kogumisteenuse logi hoitakse logi tekkimise asukohas ja dubleeritakse logiserveritesse. Logide kogumiseks ja edastamiseks kasutatakse vaikimisi *syslog*-teenust ``rsyslog``. Kogumisteenus toetab kahte liiki logiservereid, mis kirjeldatakse kogumisteenuse tehnilises seadistuses. #. Kogumisteenuse logikogumisteenus on kogumisteenuse sisemine teenus ja seda võib süsteemis olla mitu isendit. #. Tegevusmonitooringu server on kogumisteenuse jaoks väline teenus ja seda võib olla ainult üks isend. Kogumisteenusele tehniliste seadistuse rakendamisel paigaldab haldusteenus logikogumisteenuse enne teise teenuseid, et teenuste poolt toodetav logi saaks võimalikult varakult ka logikogumisteenusesse kogutud. .. note:: Kogumisteenuse logiteated tekivad pärast valimiste seadistuse esmakordset laadimist, kuna teenused käivitatakse selle seadistuse laadimise järel. Logi tootva teenuse logimise korraldus ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Logi tootva teenuse logimise seadistuse genereerib haldusteenus vastavalt tehnilistele seadistustele. #. Iga teenus logib kohalikku *syslog*-teenusesse; #. Kõigi teenusmasinate *syslog*-teenused on seadistatud kogumisteenuse logi salvestama kohalikku failisüsteemi (:file:`/var/log/ivxv/ivxv-YYYY-MM-DD-HH.log`); #. Kõigi teenusmasinate (peale logikogumisteenuse) *syslog*-teenused on seadistatud edastama üle võrgu: #. Kõiki logikirjeid logikogumisteenusesse (protokoll: RELP); #. Kogumisteenuse logikirjeid tegevuslogi monitooringu serverisse (protokoll: RELP); Logikogumisteenuse korraldus ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Logikogumisteenuse seadistusfail tuleb teenuse tarkvarapakist (:ref:`ivxv-logcollector.conf `). #. Logikogumisteenus võtab logikirjeid vastu RELP-protokolli kaudu; #. Kogumisteenuse logikirjeid kirjutatakse JSON-vormingus faili :file:`/var/log/ivxv/ivxv-YYYY-MM-DD-HH.log` (välja arvatud päringu- ja silumislogi); #. Kogumisteenuse päringulogi kirjutatakse rsyslogi standardvormingus faili :file:`/var/log/ivxv/ivxv-request-YYYY-MM-DD-HH.log`; #. Kogumisteenuse silumislogi ja teiste oluliste teenuste (haproxy, etcd, rsyslog, sshd) logi kirjutatakse rsyslogi standardvormingus faili :file:`/var/log/ivxv/ivxv-debug-YYYY-MM-DD-HH.log`. Talletamisteenuse seadistused ----------------------------- Hetkel ainus talletamisteenuse teostus kasutab hajusat võti-väärtus andmebaasi ``etcd``. Korraga käivitatakse mitu ``etcd`` isendit, mis saavutavad omavahel konsensuse talletatud andmete osas. Talletusteenuse sujuvaks tööks võib olla vajalik osade ``etcd`` parameetrite häälestamine konkreetse evituskeskkonna jaoks. Selleks tuleb teenuse masinas luua fail :file:`/etc/default/ivxv` ning sinna lisada järgmistes jaotistes kirjeldatud read. Pärast faili loomist või selle sisu muutmist tuleb uute väärtuste rakendamiseks talletusteenus taaskäivitada. Parameetri puudumise korral kasutatakse vaikeväärtust. Seadistuste väärtuste valimisel on abiks ``etcd`` dokumentatsioon aadressil https://coreos.com/etcd/docs/latest/tuning.html. Ajaparameetrid ^^^^^^^^^^^^^^ ``etcd`` klaster valib ühe liikmetest juhiks, mis koordineerib kõiki andmemuudatusi. Lisaks pingib juht perioodiliselt kõiki ülejäänud klastri liikmeid aitamaks tuvastada olukorda, kus ühendus juhiga on katkenud: kui mõni klastri liikmetest pole piisavalt kaua ühtegi pingi saanud, algatab see uue juhi valimise. Suurema võrgu- või kettalatentsuse tagajärjel võib juhi ping liialt viibida ning põhjustada uue juhi valimise. Tõrgete korral on juhivahetus süsteemi loomulik osa, ent töötava süsteemi puhul tarbetu koormus. Seetõttu tuleks seadistada juhi pingimise tihedust ``ETCD_HEARTBEAT_INTERVAL`` ning teiste liikmete ooteaega ``ETCD_ELECTION_TIMEOUT`` vastavalt evituskeskkonna latentsusele:: ETCD_HEARTBEAT_INTERVAL=100 ETCD_ELECTION_TIMEOUT=1000 Mõlemad väärtused on millisekundites ning vaikimisi vastavalt 100ms ja 1000ms. .. important:: Ühes klastris peavad kõigil talletamisteenuse isenditel olema samad ajaparameetrid. Vastasel korral võib esineda stabiilsusprobleeme erinevate pingi ootuste tõttu. Hetkvõtete parameetrid ^^^^^^^^^^^^^^^^^^^^^^ ``etcd`` peab logi kõigist andmemuudatustest. Vältimaks logi liiga suureks kasvamist tehakse andmebaasi seisust perioodiliselt hetkvõtteid ning eelnev logi kustutatakse. Kui talletamisteenus kasutab liiga palju mälu või kettaruumi, siis võib aidata tihedam hetkvõtete tegemine. Uus hetkvõte tehakse iga ``ETCD_SNAPSHOT_COUNT`` andmemuudatuse järel, seega madalam väärtus toob kaasa tihedamad hetkvõtted ning väiksema logi suuruse:: ETCD_SNAPSHOT_COUNT=10000 Vaikimisi tehakse hetkvõte iga 10000 muudatuse järel. ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/spelling_wordlist.txt ================================================ id x apache cron etcd haproxy rsyslog rsyslogi sshd systemd ubuntu zabbix zabbixiga ivxv voter list download db reset collector init cmd load copy log to logmon update packages backup crontab config validate apply secret export votes create data dirs dump generate processor input choices voting eventlog users voterstats daemon helper CSV ASiC IP PEM SSH esmakordset hosti hostid hostide hostidel hostidele hostidest hostil hostile hostinimi hostist hostiv krahhib krahhimise krahhinud pingib pingimise Diffie Hellmani ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-admin-helper.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-admin-helper kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-admin-helper: ivxv-admin-helper ````````````````` :command:`ivxv-admin-helper --help`: .. code-block:: text Usage: ivxv-admin-helper check-service-config Check service configuration ivxv-admin-helper copy-logs-to-logmon Copy IVXV service log files to Log Monitor ivxv-admin-helper restart-service Restart service ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-admin-sudo.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-admin-sudo kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-admin-sudo: ivxv-admin-sudo ``````````````` :command:`ivxv-admin-sudo --help`: .. code-block:: text Usage: ivxv-admin-sudo backup-ballot-box Backup ballot box (in backup service) ivxv-admin-sudo backup-log Backup log file (in backup service) ivxv-admin-sudo create-ssh-access Create management service access to account in service host ivxv-admin-sudo init-host Initialize service host ivxv-admin-sudo init-service Initialize service data directory. Value 'backup' is used for all backup services ivxv-admin-sudo install-pkg Install IVXV package with dependencies ivxv-admin-sudo prepare-ballot-box-backup Prepare votes backup file in voting service ivxv-admin-sudo remove-admin-root-access Remove management service access to service host root account ivxv-admin-sudo rsyslog-config-apply Apply rsyslog config file for IVXV logging ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-agent-daemon.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-agent-daemon kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-agent-daemon: ivxv-agent-daemon ````````````````` :command:`ivxv-agent-daemon --help`: .. code-block:: text IVXV Collector Management Service agent daemon. Usage: ivxv-agent-daemon [--get-stats] [--register-status] Options: --get-stats Copy statistics from Log Monitor to Management Service without daemonizing. --register-status Register collector state (if not registered). ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-backup-crontab.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-backup-crontab kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-backup-crontab: ivxv-backup-crontab ``````````````````` :command:`ivxv-backup-crontab --help`: .. code-block:: text Generate crontab for IVXV backup automation. This utility must be called as editor by crontab utility: $ env VISUAL=ivxv-backup-crontab crontab -e Usage: ivxv-backup-crontab ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-backup.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-backup kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-backup: ivxv-backup ``````````` :command:`ivxv-backup --help`: .. code-block:: text Backup IVXV collector data. Usage: ivxv-backup management-conf ivxv-backup ballot-box [] ivxv-backup log ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-cmd-load.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-cmd-load kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-cmd-load: ivxv-cmd-load ````````````` :command:`ivxv-cmd-load --help`: .. code-block:: text Load command to IVXV Collector Management Service. Usage: ivxv-cmd-load [--autoapply] [--show-version] FILE Options: Command type. Possible values are: - election: election config - technical: collector technical config - trust: trust root config - choices: choices list - districts: districts list - voters: voters list or voters list skipping - user: user account and role(s) --autoapply Apply command file automatically (by Agent Daemon). --show-version Output config file version and exit. ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-collector-init.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-collector-init kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-collector-init: ivxv-collector-init ``````````````````` :command:`ivxv-collector-init --help`: .. code-block:: text Initialize IVXV Collector. Usage: ivxv-collector-init [--force] Options: --force Don't ask user confirmation ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-config-apply.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-config-apply kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-config-apply: ivxv-config-apply ````````````````` :command:`ivxv-config-apply --help`: .. code-block:: text Apply loaded IVXV Collector config to services. Usage: ivxv-config-apply [--type=] ... [] ... Options: --type= Config type. Possible values are: - election: election config file - technical: collector technical config file - choices: choices list - districts: districts list - voters: voters list ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-config-validate.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-config-validate kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-config-validate: ivxv-config-validate ```````````````````` :command:`ivxv-config-validate --help`: .. code-block:: text Validate IVXV collector config files. Validate single config files. Also validate voting lists consistency if multiple lists are provided. Usage: ivxv-config-validate [--plain] [--trust=] [--technical=] [--election=] [--choices=] [--districts=] [--voters= ...] Options: --plain Validate plain config file (Default: BDOC container) ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-copy-log-to-logmon.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-copy-log-to-logmon kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-copy-log-to-logmon: ivxv-copy-log-to-logmon ``````````````````````` :command:`ivxv-copy-log-to-logmon --help`: .. code-block:: text Copy IVXV log files from service hosts to Log Monitor. This utility transports collected IVXV log files from IVXV services (including Log Collector Service) to Log Monitor. Usage: ivxv-copy-log-to-logmon [--log-level=] [ ...] Options: Service host name. --log-level= Logging level [Default: INFO]. ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-create-data-dirs.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-create-data-dirs kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-create-data-dirs: ivxv-create-data-dirs ````````````````````` :command:`ivxv-create-data-dirs --help`: .. code-block:: text Create IVXV Collector Management Service data directories. NOTE: Directory owners and permissions are not set by this utility! Usage: ivxv-create-data-dirs ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-db-dump.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-db-dump kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-db-dump: ivxv-db-dump ```````````` :command:`ivxv-db-dump --help`: .. code-block:: text Dump IVXV Collector Management Service database. Usage: ivxv-db-dump [] ... ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-db-reset.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-db-reset kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-db-reset: ivxv-db-reset ````````````` :command:`ivxv-db-reset --help`: .. code-block:: text Reset IVXV Collector Management Service database. Usage: ivxv-db-reset [--force] Options: --force Don't ask user confirmation ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-eventlog-dump.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-eventlog-dump kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-eventlog-dump: ivxv-eventlog-dump `````````````````` :command:`ivxv-eventlog-dump --help`: .. code-block:: text Dump IVXV Collector Management event log in human readable format. Usage: ivxv-eventlog-dump ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-export-votes.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-export-votes kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-export-votes: ivxv-export-votes ````````````````` :command:`ivxv-export-votes --help`: .. code-block:: text Export collected votes. This utility copies current ballot box from voting service to backup service and outputs ballot box content. Usage: ivxv-export-votes [--consolidate] Options: --consolidate Consolidate all collected votes ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-generate-processor-input.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-generate-processor-input kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-generate-processor-input: ivxv-generate-processor-input ````````````````````````````` :command:`ivxv-generate-processor-input --help`: .. code-block:: text Generate input for processor application. This utility generates ZIP container with data files for processor application to validate ballot box: 1. District list; 2. Voter lists; 3. Validation key for vote registration requests; 4. Configuration for processor application. Usage: ivxv-generate-processor-input ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-secret-load.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-secret-load kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-secret-load: ivxv-secret-load ```````````````` :command:`ivxv-secret-load --help`: .. code-block:: text Load secret data to IVXV services. This utility loads file that contains secret data to services. Supported secret types are: tls-cert - TLS certificate for service. Certificate (and key) is used for securing communication between services and service instances. tls-key - TLS key for service. Key is used together with service certificate. tsp-regkey - PKIX TSP registration key for voting services. Key is used for signing Time Stamp Protocol requests. Key file must be in PEM format and must be not password protected. mid-token-key - Mobile ID identity token for choices, mobile-id and voting services. Key file must be 32 bytes long. Usage: ivxv-secret-load [--service=] ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-service.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-service kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-service: ivxv-service ```````````` :command:`ivxv-service --help`: .. code-block:: text Manage IVXV services. Usage: ivxv-service ... Options: Management action: start, stop, restart, ping ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-status.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-status kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-status: ivxv-status ``````````` :command:`ivxv-status --help`: .. code-block:: text Output IVXV Collector state. Usage: ivxv-status [--json] [--service= ...] [ ...] Options: --json Output full data in JSON format. Note: filters have no effect in JSON output. --service= Filter output by service ID. Note: This filter conflicts other section filters than "smart" or "service". Filter output by section. Possible values are: * collector - collector state; * election - election data; * config - versions of loaded config; * list - versions of loades lists; * service - service information; * ext - external service information; * storage - storage information; * smart - output only relevant data; * all - output all data; [Default: smart]. ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-update-packages.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-update-packages kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-update-packages: ivxv-update-packages ```````````````````` :command:`ivxv-update-packages --help`: .. code-block:: text Update service packages in IVXV service hosts. This utility checks versions of software packages in service hosts and installs new versions if required. Usage: ivxv-update-packages [--force] Options: --force Update even package version does not require update ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-users-list.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-users-list kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-users-list: ivxv-users-list ``````````````` :command:`ivxv-users-list --help`: .. code-block:: text List IVXV Collector Management Service registered users. Usage: ivxv-users-list ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-voter-list-download.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-voter-list-download kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-voter-list-download: ivxv-voter-list-download ```````````````````````` :command:`ivxv-voter-list-download --help`: .. code-block:: text Download next available voter list changeset from VIS to IVXV Collector Management Service. Usage: ivxv-voter-list-download [--output-report=] [--log-level=] Options: --output-report= Write JSON report about HTTP request to VIS. --log-level= Logging level [Default: INFO]. ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-voterstats.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-voterstats kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-voterstats: ivxv-voterstats ``````````````` :command:`ivxv-voterstats --help`: .. code-block:: text Import voter stats from voting service and export common stats to VIS. Usage: ivxv-voterstats [--action=] [--file=] [--service-id=] [--log-level=] Options: Stats type "common" or "detail". --action= Limit actions for "common" stats type. Possible values are "import" and "export". [Default: all] --file= Path to stats file. --service-id= Voting service ID [Default: random]. --log-level= Logging level [Default: INFO]. ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/utiliitide-abiteave/ivxv-voting-sessions.inc ================================================ .. Elektroonilise hääletamise infosüsteem IVXV .. Käsureautiliidi ivxv-voting-sessions kasutusjuhend .. SEE FAIL ON GENEREERITUD AUTOMAATTESTI POOLT: .. * features/steps/autodoc.py .. * features/autodoc-utilities.feature .. _ivxv-voting-sessions: ivxv-voting-sessions ```````````````````` :command:`ivxv-voting-sessions --help`: .. code-block:: text Import list of voting sessions from Log Monitor. Session data is in CSV format. Usage: ivxv-voting-sessions (vote | verify) [--anonymize] [--log-level=] Options: Write sessions to file. --anonymize Anonymize session data (IP addresses and ID codes). --log-level= Logging level [Default: INFO]. ================================================ FILE: Documentation/et/kogumisteenuse_haldusjuhend/ylevaade.rst ================================================ .. IVXV kogumisteenuse haldusjuhend Ülevaade ======== Kogumisteenuse ülevaade ----------------------- IVXV kogumisteenus on elektroonilise hääletuse käigus hääletajate teenindamiseks ja häälte kogumiseks mõeldud tarkvara. Kogumisteenus koosneb mikroteenustest ja nende haldamiseks mõeldud haldusteenusest. Haldusteenuse kasutamine on käsureapõhine. Osade funktsioonide kasutamist on laiendatud veebipõhise liidesega, mida on kirjeldatud dokumendis ``IVXV kogumisteenuse haldusliidese kasutusjuhend``. .. attention:: Kogumisteenus paigaldatakse ja seadistatakse eraldi iga hääletuse läbiviimiseks. Ühe kogumisteenusega on korraga võimalik teenindada ainult ühte hääletust. Lisamaterjalid -------------- Käesolevas dokumendis kasutatakse mõisteid ja definitsioone, mis on kirjeldatud dokumendis ``IVXV-ÜK-0.95 Elektroonilise hääletamise üldraamistik ja selle kasutamine Eesti riiklikel valimistel``: * E-hääletamise etapid; * Süsteemi osapooled ja komponendid. Kogumisteenuse kasutajate rollid -------------------------------- Kogumisteenuses on kasutusel järgnevad rollid: #. **Kogumisteenuse haldur** tegeleb kogumisteenuse tehnilise haldamisega; #. **Valimiste haldur** tegeleb valimiste seadistuste kehtestamisega; #. **Vaataja** pääseb ligi haldusteenuse kaudu väljastatavatele seisundi- ja statistikaandmetele; Rollide täpsem kirjeldus asub dokumendis ``Elektroonilise hääletamise infosüsteemi IVXV seadistuste koostamise juhend``. Süsteemi komponendid -------------------- Kogumisteenus ^^^^^^^^^^^^^ **Haldusteenus** on kogumisteenuse haldamise teenus. Haldusteenuse kaudu juhitakse ja jälgitakse kogumisteenust alates paigaldusest kuni mahavõtmiseni. Vaata lähemalt lõigus :ref:`haldusteenus`. **Logikoguja** on kogumisteenuse sisemine logiserver, mis kogub ja säilitab kõigi kogumisteenuste alamteenuste logisid. Logikogujasse kogutud logid antakse valimiste lõppedes üle korraldajale. **Sisemine varundus** on kogumisteenuse varundusteenus, mis varundab kõigi alamteenuste andmeid ja teeb need lihtsa liidese (failisüsteemi kataloog) kaudu kättesaadavaks välisele varundusteenusele. **Alamteenused** on kogumisteenuse eri lõikude eest vastutavad teenused. .. _tugiteenused: Tugiteenused ^^^^^^^^^^^^ **Logiseire** on kogumisteenuse logide analüüsiks ja jälgimiseks mõeldud seireprogramm. **Tehniline seire** on kogumisteenuse tehnilise toimimise jälgimiseks mõeldud seireprogramm. **Väline varundus** on kogumisteenuse sisemisest varunduse poolt varundatud andmete säilitamiseks mõeldud väline varundusteenus. .. _välisteenused: Välised teenused ^^^^^^^^^^^^^^^^ Välised teenused on läbiviidavatele valimistele kehtestatud nõuetest sõltuvad teenused, millega kogumisteenus on võimeline liidestuma. Väliste teenuste hulka kuuluvad Registreerimisteenus, Ajatempliteenus, Mobiil-ID teenus, Smart-ID teenus, OCSP teenus vms. Ülevaade toimingutest --------------------- * Hääletamiseelsel etapil: * Kirjeldatakse kogumisteenuse poolt kasutatavad :ref:`välised teenused `; * Valmistatakse ette kogumisteenuse :ref:`tugiteenused `; * Koostatakse kogumisteenuse seadistused (usaldusjuur, tehnilised seadistused ja valimiste seadistused); * Genereeritakse teenuse toimimiseks vajalikud krüptovõtmed ja sertifikaadid; * Valmistatakse ette kogumisteenuse käitamiseks vajalik taristu; * Paigaldatakse haldusteenus; * Rakendatakse seadistused haldusteenusele, mille põhjal haldusteenus paigaldab ja seadistab kogumisteenuse alamteenused. * Hääletamisetapil * Jälgitakse teenuse toimimist; * Luuakse e-valimiskastist varukoopiaid. * Töötlusetapil * Eksporditakse kogumisteenusesse kogutud andmed: #. konsolideeritud e-valimiskast kogutud häältega. * Lugemisetapil * Lugemisetapil kogumisteenust ei kasutata; ================================================ FILE: Documentation/et/seadistuste_koostejuhend/Makefile ================================================ include ../../common.mk ================================================ FILE: Documentation/et/seadistuste_koostejuhend/annotatsioon.rst ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus Annotatsioon ------------ Käesolev dokument sisaldab elektroonilise hääletamise infosüsteemi IVXV rakenduste ja kogumisteenuse seadistuste ülevaadet ja koostamise juhendit. ================================================ FILE: Documentation/et/seadistuste_koostejuhend/auditirakendus.rst ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus .. _app-auditor: Auditirakendus ============== IVXV võtmerakendus võimaldab kasutada tõestatavat dekrüpteerimist - koos tulemusega väljastatakse lugemistõend e-häälte korrektse avamise kohta. Vältimaks häälte salajasuse rikkumist lugemistõendi kontrollil võimaldab IVXV kasutada häälte miksimist, mis säilitab häälte sisu kuid eemaldab krüptograafiliselt seose konkreetse hääle ja selle hääle andnud isiku vahel. IVXV kasutab e-häälte miksimiseks tarkvara Verificatum, mis võtab sisendiks krüpteeritud hääled ning annab väljundiks miksitud krüpteeritud hääled ja miksimistõendi. Miksimistõendi ja lugemistõendi kontroll toimub auditirakenduse tööriistadega *convert*, *mixer* ja *decrypt*. Töötlemisrakenduse toimingute kontroll toimub auditirakenduse tööriistaga *integrity*. #. Tööriist *convert* kontrollib, teisenduste korrektsust IVXV andmevormingute ja Verificatumi andmevormingute vahel. #. Tööriist *mixer* kontrollib miksimistõendi korrektsust. #. Tööriist *decrypt* kontrollib lugemistõendi korrektsust. #. Tööriist *integrity* kontrollib töötlemisrakenduse logide korrektsust. E-häälte korrektse kokkulugemise kontrolliks on vajalik ja piisav kasutada kõiki nelja auditirakenduse tööriista. Kõigi tööriistade kasutamine eeldab allkirjastatud usaldusjuure ja konkreetse tööriista seadistuste olemasolu. Alljärgnevalt kirjeldame konkreetsete tööriistade seadistusi. .. _auditor-convert: E-häälte korrektse teisendamise kontroll ---------------------------------------- Verificatumi poolt koostatud miksimistõendi formaat on erinev IVXV raamistikus kasutatavast formaadist, samuti erinevad IVXV ning Verificatumi krüpteeritud häälte formaadid. IVXV raamistikku on pakendatud adapterid formaaditeisendusteks, auditirakendus pakub võimalust nende teisenduste korrektsuse kontrolliks. Tööriist *convert* kontrollib, et Verificatumi poolt väljastatud miksimistõend vastab failidele IVXV raamistikus. :convert.input_bb: IVXV miksimiseelse e-valimiskasti asukoht. :convert.output_bb: IVXV miksimisjärgse e-valimiskasti asukoht. :convert.pub: IVXV avaliku võtme asukoht. :convert.protinfo: Verificatumi miksimise protokollifaili asukoht. :convert.proofdir: Verificatumi miksimistõendi asukoht. :file: `auditor.convert.yaml`: .. literalinclude:: config-examples/auditor.convert.yaml :language: yaml :linenos: .. _auditor-mix: E-häälte miksimistõendi kontroll -------------------------------- Tööriist *mixer* kontrollib Verificatumi miksimistõendi korrektsust. :mixer.protinfo: Verificatumi miksimistõendi protokollifaili asukoht. :mixer.proofdir: Verificatumi miksimistõendi asukoht. :mixer.threaded: Kasuta mitmelõimelist implementatsiooni. Vaikimisi väärtus on väär. Kasutatavate lõimede arv sõltub käsurea-argumentidest. Käsurea-argumentide puudumise korral valitakse optimaalne lõimede arv lähtudes tuvastatud tuumade arvust. :file:`auditor.mixer.yaml`: .. literalinclude:: config-examples/auditor.mixer.yaml :language: yaml :linenos: .. _auditor-decrypt: E-häälte lugemistõendi kontroll ------------------------------- Tööriist *decrypt* kontrollib lugemistõendi korrektsust. :decrypt.proofs: Kehtivate sedelite lugemistõendi asukoht. :decrypt.pub: Dekrüpteerimiseks kasutatud salajasele võtmele vastava avaliku võtme asukoht. :decrypt.discarded: Loend kehtetutest sedelitest. :decrypt.anon_bb: Töötlemisrakenduse või miksimisrakenduse poolt loodud e-valimiskast anonüümistatud häältega. :decrypt.plain_bb: Dekrüpteeritud valimiskast. :decrypt.tally: Elektroonilise hääletamise tulemus. :decrypt.candidates: Valimise valikute nimekiri allkirjastatud kujul. :decrypt.districts: Valimise ringkondade nimekiri allkirjastatud kujul. :decrypt.out: Lugemistõendi kontrolli tulemuste asukoht. Tegemist on kataloogiga kuhu salvestatakse sedelid, mille lugemistõend oli kehtetu. :decrypt.invalidity_proofs: Valikuline kehtetute sedelite lugemistõendi asukoht. :decrypt.abort_early: Valikuline auditirakenduse peatamine esimese läbikukutud kontrolli korral. Vaikimisi väärtus on tõene. :file:`auditor.decrypt.yaml`: .. literalinclude:: config-examples/auditor.decrypt.yaml :language: yaml :linenos: .. _auditor-integrity: Töötlemisrakenduse logide kontroll ---------------------------------- Tööriist *integrity* kontrollib, et töötlemisrakenduse poolt väljastatud logid ühendavad e-valimiskasti anonüümitud e-valimiskastiga. :integrity.ballotbox: Kogumisteenusest väljastatud e-valimiskast. :integrity.anon_bb: Töötlemisrakenduse poolt loodud e-valimiskast anonüümistatud häältega. :integrity.log_accepted: Vastuvõetud häälte *log1* fail. :integrity.log_squashed: Tühistatud korduvhäälte häälte *log2* fail. :integrity.log_revoked: Jaoskonnainfo põhjal tühistatud ja ennistatud häälte *log2* fail. :integrity.log_anonymised: Lugemisele läinud häälte *log3* fail. :integrity.bb_errors: E-valimiskasti töötlemisvigade raport. :integrity.abort_early: Valikuline auditirakenduse peatamine esimese läbikukutud kontrolli korral. Vaikimisi väärtus on tõene. :file: `auditor.integrity.yaml`: .. literalinclude:: config-examples/auditor.integrity.yaml :language: yaml :linenos: ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/DEMO_SK_TIMESTAMPING_AUTHORITY_2020.pem ================================================ -----BEGIN CERTIFICATE----- MIIEgzCCA2ugAwIBAgIQcGzJsYR4QLlft+S73s/WfTANBgkqhkiG9w0BAQsFADB9 MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 czEwMC4GA1UEAwwnVEVTVCBvZiBFRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290 IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwHhcNMjAxMTMwMjEwMDAwWhcN MjUxMTMwMjEwMDAwWjB/MSwwKgYDVQQDDCNERU1PIFNLIFRJTUVTVEFNUElORyBB VVRIT1JJVFkgMjAyMDEXMBUGA1UEYQwOTlRSRUUtMTA3NDcwMTMxDDAKBgNVBAsM A1RTQTEbMBkGA1UECgwSU0sgSUQgU29sdXRpb25zIEFTMQswCQYDVQQGEwJFRTCC ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMz8yTHQyp8gzyPnKt/CQg+0 7c/ogDl4V1SmyFGPT+lQaYZvXIKNNZyJlzII+vNnsok6hIRvAX5ffDZs8dkeNdo8 QOuQ81QbLn5JJT2VuSppvpnqpFCiL+uWY0/nnwNmyiDueMkUDDJavbSPCkWwmW+a QZCNGd+krSTL/zNHCfOt7cAVDQAL9C4Ue7olufIZoDCTqRA00S8bGbTQPyTS8uUM EuwWc4JYZqEu4c24bIGhbKoCOSR60WrD6cBoZXLlqwDbWdkX5SLjJ9dTCxGW+pLp nAWx+KqJY3HkDiSZCT46JXOaoVzmcFx3l7eqQfqWgkzRZs9TJvqQSLQ+vgSAOREC AwEAAaOB/DCB+TAOBgNVHQ8BAf8EBAMCBsAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH AwgwHQYDVR0OBBYEFJ8v3/rNs6jK0l3BxyVSixDYEOJHMB8GA1UdIwQYMBaAFLU0 Cp2lLxDF5yEOvsSxZUcbA3b+MIGOBggrBgEFBQcBAQSBgTB/MCEGCCsGAQUFBzAB hhVodHRwOi8vZGVtby5zay5lZS9haWEwWgYIKwYBBQUHMAKGTmh0dHBzOi8vd3d3 LnNrLmVlL3VwbG9hZC9maWxlcy9URVNUX29mX0VFX0NlcnRpZmljYXRpb25fQ2Vu dHJlX1Jvb3RfQ0EuZGVyLmNydDANBgkqhkiG9w0BAQsFAAOCAQEAWWkQKAbEAT77 n8L42gw5ql7BO1fdmUgRJRRwWL9Vo9l1c50lqieR8MUToF4wpF6D0PJUx9FDcKL0 fbURFTRuETCgGekYmCjMbVQCiv6W38vMsIdJLBWjo2oT2AjtJ2VakwkrzzSxOSBr F5u0hPsAkP0VkBhmW1E0DHfm1Bti2xk5t9OsJMJqfTTl8v1HXktlnxi6WdUzLBcS dknFePDnSYoT3xOfOz1IlB3Ta729bgglAjVBEoWyrKX4kTjZPChxseMntXaW/pN+ Agm3Xa9hniXdK4KamzX8d8LJ+qObxmc9TXmksbWZVup0ktfJYWIHCwZjmQukAed/ pIX8UV3N9w== -----END CERTIFICATE----- ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/Stats_Server_Certificate.pem ================================================ -----BEGIN CERTIFICATE----- MIIDbDCCAlQCCQCc0vA55LL2hDANBgkqhkiG9w0BAQsFADB4MRwwGgYDVQQDDBNp dnh2LWFkbWluLWRlbW9jZXJ0MSUwIwYDVQQKDBxJVlhWIGNvbGxlY3RvciBhZG1p bmlzdHJhdG9yMRIwEAYDVQQLDAlCREQgdGVzdHMxEDAOBgNVBAcMB1Rlc3RFbnYx CzAJBgNVBAYTAkVFMB4XDTE2MTIwOTIxMTMzN1oXDTI2MTIwNzIxMTMzN1oweDEc MBoGA1UEAwwTaXZ4di1hZG1pbi1kZW1vY2VydDElMCMGA1UECgwcSVZYViBjb2xs ZWN0b3IgYWRtaW5pc3RyYXRvcjESMBAGA1UECwwJQkREIHRlc3RzMRAwDgYDVQQH DAdUZXN0RW52MQswCQYDVQQGEwJFRTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC AQoCggEBANqBKqPiPEv4TE3UnO6pym8ejzsY6WaTSnqJE2mSoXBKquc/tK3eLon4 XdkgJI6wz/x2ZkPbUUuQW1NBhHGXY7W5Yu5OQ1lIKi/UAirPoQg4qsyyXkti51+R HeepaKB8ll7+ALXBTDLvNbIn9NN2pPp3Lf+j0vJDvgL2aQYfcUMKe0E6Vdr0r2fY DShCrLssNNlkY9wHPxBPKY2MPeIQxrCSI8OAjH5vGXoU0QLUAxTh6kFowU438tGp 3Hxa4IbaaACNhghRudxcRi8SYCRAgc3zuzOFtkU2k3aetZT60Zcpuds+ZlPQl8Sd RJ6ToGQ7dO/Pvwpc+D8MEmwFSgHJb7ECAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA IaOkADkkoJo+zFhKL4EYJpnq22nCB2FHYjuHQDzyyjfHU9r2J11s66ol4tWj/k9u FnQq9xE19L+QI3DsDA/q8XlRlhMKYRE8Pm5zpoC99+6QS34qbOvNR65pq3WH6J3m hWLulbJhEjgR5KXZSIzPWxt781sx1n9BEQCWsm3aCPGQofuEOcjTlZYuHSymSF5I 5q9FAcI0jsquZVdlWsIg3QucSlS+wZVM/1GjTWorAekXTAhrLhIrTdpvNwo+fysy AJXROOJbkLUlVaAJFFT+CAUl1qWd9M1CmTYc91RFrlKN/hVItIJeIRGunE5N9dl4 2/RTqnxfqfwSZuQ3DcRKSw== -----END CERTIFICATE----- ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/TEST_of_EE_Certification_Centre_Root_CA.pem ================================================ -----BEGIN CERTIFICATE----- MIIEEzCCAvugAwIBAgIQc/jtqiMEFERMtVvsSsH7sjANBgkqhkiG9w0BAQUFADB9 MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 czEwMC4GA1UEAwwnVEVTVCBvZiBFRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290 IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwIhgPMjAxMDEwMDcxMjM0NTZa GA8yMDMwMTIxNzIzNTk1OVowfTELMAkGA1UEBhMCRUUxIjAgBgNVBAoMGUFTIFNl cnRpZml0c2VlcmltaXNrZXNrdXMxMDAuBgNVBAMMJ1RFU1Qgb2YgRUUgQ2VydGlm aWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVl MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1gGpqCtDmNNEHUjC8LXq xRdC1kpjDgkzOTxQynzDxw/xCjy5hhyG3xX4RPrW9Z6k5ZNTNS+xzrZgQ9m5U6uM ywYpx3F3DVgbdQLd8DsLmuVOz02k/TwoRt1uP6xtV9qG0HsGvN81q3HvPR/zKtA7 MmNZuwuDFQwsguKgDR2Jfk44eKmLfyzvh+Xe6Cr5+zRnsVYwMA9bgBaOZMv1TwTT VNi9H1ltK32Z+IhUX8W5f2qVP33R1wWCKapK1qTX/baXFsBJj++F8I8R6+gSyC3D kV5N/pOlWPzZYx+kHRkRe/oddURA9InJwojbnsH+zJOa2VrNKakNv2HnuYCIonzu pwIDAQABo4GKMIGHMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G A1UdDgQWBBS1NAqdpS8QxechDr7EsWVHGwN2/jBFBgNVHSUEPjA8BggrBgEFBQcD AgYIKwYBBQUHAwEGCCsGAQUFBwMDBggrBgEFBQcDBAYIKwYBBQUHAwgGCCsGAQUF BwMJMA0GCSqGSIb3DQEBBQUAA4IBAQAj72VtxIw6p5lqeNmWoQ48j8HnUBM+6mI0 I+VkQr0EfQhfmQ5KFaZwnIqxWrEPaxRjYwV0xKa1AixVpFOb1j+XuVmgf7khxXTy Bmd8JRLwl7teCkD1SDnU/yHmwY7MV9FbFBd+5XK4teHVvEVRsJ1oFwgcxVhyoviR SnbIPaOvk+0nxKClrlS6NW5TWZ+yG55z8OCESHaL6JcimkLFjRjSsQDWIEtDvP4S tH3vIMUPPiKdiNkGjVLSdChwkW3z+m0EvAjyD9rnGCmjeEm5diLFu7VMNVqupsbZ SfDzzBLc5+6TqgQTOG7GaZk2diMkn03iLdHGFrh8ML+mXG9SjEPI -----END CERTIFICATE----- ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/TEST_of_ESTEID-SK_2015.pem ================================================ -----BEGIN CERTIFICATE----- MIIGgzCCBWugAwIBAgIQEDb9gCZi4PdWc7IoNVIbsTANBgkqhkiG9w0BAQwFADB9 MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 czEwMC4GA1UEAwwnVEVTVCBvZiBFRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290 IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwIBcNMTUxMjE4MDcxMzQ0WhgP MjAzMDEyMTcyMzU5NTlaMGsxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0 aWZpdHNlZXJpbWlza2Vza3VzMRcwFQYDVQRhDA5OVFJFRS0xMDc0NzAxMzEfMB0G A1UEAwwWVEVTVCBvZiBFU1RFSUQtU0sgMjAxNTCCAiIwDQYJKoZIhvcNAQEBBQAD ggIPADCCAgoCggIBAMTeAFvLxmAeaOsRKaf+hlkOhW+CdEilmUIKWs+qCWVq+w8E 8PA/TohAZdUcO4KFXothmPDmfOCb0ExXcnOPCr2NndavzB39htlyYKYxkOkZi3pL z8bZg/HvpBoy8KIg0sYdbhVPYHf6i7fuJjDac4zN1vKdVQXA6Tv5wS/e90/ZyF95 5vycxdNLticdozm5yCDMNgsEji6QNA1zIi3+C2YmnDXx6VyxhuC2R3q0xNkwtJ4e zs1RZGxWokTNPzQc3ilGhEJlVsS8vP624hUHwufQnwrKWpc3+D+plMIO0j3E+hmh 46gIadDRweFR/dzb+CIBHRaFh0LEBjd/cDFQlBI+E8vpkhqeWp6rp1xwnhCL201M 3E1E1Mw+51Xqj7WOfY0TzjOmQJy8WJPEwU2m44KxW1SnpeEBVkgb4XYFeQHAllc7 J7JDv50BoIPpecgaqn1vKR7l//wDsL0MN1tDlBhl3x7TJ/fwMnwB1E3zVZR74TUZ h5J49CAcFrfM4RmP/0hcDW8+4wNWMg2Qgst2qmPZmHCI/OJt5yMt0Ud5yPF8AWxV ot3TxOBGjMiM8m6WsksFsQxp5WtA0DANGXIIfydTaTV16Mg+KpYVqFKxkvFBmfVp 6xApMaFl3dY/m56O9JHEqFpBDF+uDQIMjFJxJ4Pt7Mdk40zfL4PSw9Qco2T3AgMB AAGjggINMIICCTAfBgNVHSMEGDAWgBS1NAqdpS8QxechDr7EsWVHGwN2/jAdBgNV HQ4EFgQUScDyRDll1ZtGOw04YIOx1i0ohqYwDgYDVR0PAQH/BAQDAgEGMGYGA1Ud IARfMF0wMQYKKwYBBAHOHwMBATAjMCEGCCsGAQUFBwIBFhVodHRwczovL3d3dy5z ay5lZS9DUFMwDAYKKwYBBAHOHwMBAjAMBgorBgEEAc4fAwEDMAwGCisGAQQBzh8D AQQwEgYDVR0TAQH/BAgwBgEB/wIBADBBBgNVHR4EOjA4oTYwBIICIiIwCocIAAAA AAAAAAAwIocgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwJwYDVR0l BCAwHgYIKwYBBQUHAwkGCCsGAQUFBwMCBggrBgEFBQcDBDCBiQYIKwYBBQUHAQEE fTB7MCUGCCsGAQUFBzABhhlodHRwOi8vZGVtby5zay5lZS9jYV9vY3NwMFIGCCsG AQUFBzAChkZodHRwOi8vd3d3LnNrLmVlL2NlcnRzL1RFU1Rfb2ZfRUVfQ2VydGlm aWNhdGlvbl9DZW50cmVfUm9vdF9DQS5kZXIuY3J0MEMGA1UdHwQ8MDowOKA2oDSG Mmh0dHBzOi8vd3d3LnNrLmVlL3JlcG9zaXRvcnkvY3Jscy90ZXN0X2VlY2NyY2Eu Y3JsMA0GCSqGSIb3DQEBDAUAA4IBAQDBOYTpbbQuoJKAmtDPpAomDd9mKZCarIPx AH8UXphSndMqOmIUA4oQMrLcZ6a0rMyCFR8x4NX7abc8T81cvgUAWjfNFn8+bi6+ DgbjhYY+wZ010MHHdUo2xPajfog8cDWJPkmz+9PAdyjzhb1eYoEnm5D6o4hZQCiR yPnOKp7LZcpsVz1IFXsqP7M5WgHk0SqY1vs+Yhu7zWPSNYFIzNNXGoUtfKhhkHiR WFX/wdzr3fqeaQ3gs/PyD53YuJXRzFrktgJJoJWnHEYIhEwbai9+OeKr4L4kTkxv PKTyjjpLKcjUk0Y0cxg7BuzwevonyBtL72b/FVs6XsXJJqCa3W4T -----END CERTIFICATE----- ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/TEST_of_SK_OCSP_RESPONDER_2020.pem ================================================ -----BEGIN CERTIFICATE----- MIIEzjCCA7agAwIBAgIQa7w4iGoiIOtfrn0fG/hc1zANBgkqhkiG9w0BAQUFADB9 MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1 czEwMC4GA1UEAwwnVEVTVCBvZiBFRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBSb290 IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwHhcNMjAxMTEzMTIzMzM1WhcN MjQwNjEzMTEzMzM1WjCBgzELMAkGA1UEBhMCRUUxIjAgBgNVBAoMGUFTIFNlcnRp Zml0c2VlcmltaXNrZXNrdXMxDTALBgNVBAsMBE9DU1AxJzAlBgNVBAMMHlRFU1Qg b2YgU0sgT0NTUCBSRVNQT05ERVIgMjAyMDEYMBYGCSqGSIb3DQEJARYJcGtpQHNr LmVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz6U1uMvi5P6bycik gOFp1QdIdt2R/x/+WbRVNLNjDTMS0t70BVl6+Z7c5jqZUNIBZ5qlr3K8v5bIv0rd r1H/By0wFMWsWksZnQLIsb/lU+HeuSIDY2ESs0YzvZW4AB3tDrMFOrtuImmsUxhs z00KcRt9o+/o0RD9v5qxhJaqj6+Pr/8fZJK67Wuiqli2vVtuStaTb5zpjA1MJtu9 OM4jk/FaL1FaST72XPTzpMVNJR/Rk63t0wL4l4f4s3y0ZI+JPzXu3jyeH+g3ZVLb wB2ccwgqfDPKXoxfNtcDxjUZz16OQQp2Rp14h/n8If0jyHfiNHHCDKaSPFyyJJMg RrQkiwIDAQABo4IBQTCCAT0wEwYDVR0lBAwwCgYIKwYBBQUHAwkwHQYDVR0OBBYE FIGteMcJzpGYrEl+MRkb+QpBx6XFMIGgBgNVHSAEgZgwgZUwgZIGCisGAQQBzh8D AQEwgYMwWAYIKwYBBQUHAgIwTB5KAEEAaQBuAHUAbAB0ACAAdABlAHMAdABpAG0A aQBzAGUAawBzAC4AIABPAG4AbAB5ACAAZgBvAHIAIAB0AGUAcwB0AGkAbgBnAC4w JwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuc2suZWUvYWphdGVtcGVsLzAfBgNVHSME GDAWgBS1NAqdpS8QxechDr7EsWVHGwN2/jBDBgNVHR8EPDA6MDigNqA0hjJodHRw czovL3d3dy5zay5lZS9yZXBvc2l0b3J5L2NybHMvdGVzdF9lZWNjcmNhLmNybDAN BgkqhkiG9w0BAQUFAAOCAQEAKR+ssgVTDDkGl+sLwz5OwaBMUOPEscr7DcCXmjmR aC+KjTe8kCuXZwnMH7tMf0mDyF22USJ/o2m0MFW1k8zjH1yr1/2JghttRfi5mCvo MHNXVM/ST1C/6rrymaYA27RxIj201USwTQp35YvhUUIZO3Xby/60yXZyt7wCS7xA nH65U/0LnkT5w5DLC8EdXlH3QF600Z74fm8z54lY80IoSgIEPmFZlLe4YR822G24 mawGRQKIbhPK2DO6sGtLZDAfee4B6TGmPcunztsYaUoc1spfCKrx5EBthieSgAp0 dh0kMBAR/AGh7fSwl5zyASFgYmtVP4FZS6w6ETlXU7Bg3g== -----END CERTIFICATE----- ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/android-ios-config.json ================================================ { "appConfig": { "colors": { "btn_background": "#F0F0F0", "btn_background_focused": "#CFCFCF", "btn_close_view_focused": "#1995B4", "btn_foreground": "#727272", "btn_verify_background_center": "#1AABE1", "btn_verify_background_end": "#00A1DC", "btn_verify_background_focused": "#1693C0", "btn_verify_background_start": "#30B4E5", "btn_verify_foreground": "#FFFFFF", "error_window": "#FF0000", "error_window_close_btn_focused": "#B60010", "error_window_foreground": "#FFFFFF", "error_window_shadow": "#770000", "frame_background": "#AA444444", "lbl_background": "#33B5E5", "lbl_close_timeout_background_center": "#F9D303", "lbl_close_timeout_background_end": "#F7C804", "lbl_close_timeout_background_start": "#FEEC00", "lbl_close_timeout_foreground": "#454444", "lbl_close_timeout_shadow": "#C6A002", "lbl_foreground": "#FFFFFF", "lbl_inner_container_background": "#FFFFFF", "lbl_inner_container_foreground": "#404040", "lbl_outer_container_background": "#EAEAEA", "lbl_outer_container_foreground": "#404040", "lbl_outer_inner_container_divider": "#595959", "lbl_shadow": "#008EC2", "loading_window_background": "#33B5E5", "loading_window_foreground": "#FFFFFF", "main_window": "#33B5E5", "main_window_foreground": "#FFFFFF", "main_window_shadow": "#005777" }, "elections": { "question-1": "Prototüübi test" }, "errors": { "bad_config_message": "Seadistuse viga", "bad_device_message": "Seadmel puudub kaamera, verifitseerimist ei ole võimalik läbi viia", "bad_server_response_message": "Tehniline viga, palun teavita valimiste korraldajat abi@valimised.ee", "bad_verification_message": "Valiku tuvastamine ebaõnnestus", "bad_version_message": "Rakenduse versioon ei ole ajakohane, palun uuenda oma rakendust", "camera_permission_required_message": "Rakenduse kasutamiseks peab olema kaamera kasutamine lubatud", "error_title_bad_version": "Rakenduse versiooni viga", "error_title_default": "Viga", "error_title_network": "Internetiühendus puudub", "get_config_message": "Seadistuse laadimine ebaõnnestus", "no_network_message": "Palun veendu, et nutiseadme internetiühendus on aktiivne", "problem_qrcode_message": "QR-koodi ei õnnestunud tuvastada", "send_server_request_message": "Serveriga ühendumine ebaõnnestus, kontrolli internetiühendust või teavita valimiste korraldajat abi@valimised.ee" }, "params": { "close_interval": 1000, "close_timeout": 30000, "con_timeout_1": 3000, "con_timeout_2": 15000, "help_url": "https://www.valimised.ee/verify/help/index.html", "ocsp_service_cert": [], "public_key": "", "tspreg_client_cert": "", "tspreg_service_cert": "", "verification_sni": "verification.ivxv.valimised.ee", "verification_tls": [ "", "", "" ], "verification_url": [ "collector1:port", "collector2:port", "collector3:port" ] }, "texts": { "a11y_qr_view_opened": "Alusta QR-koodi skaneerimist", "btn_close": "Sulge", "btn_more": "Abi", "btn_next": "Edasi", "btn_ok": "Ok", "btn_packet_data": "Andmeside", "btn_update": "Värskenda", "btn_verify": "Kuva minu valik", "btn_wifi": "Wifi", "lbl_choice": "Tuvastatud valik", "lbl_close_timeout": "Rakendus suletakse XX sekundi pärast!", "lbl_no_choice": "Valikut ei tehtud", "lbl_vote": "Hääle kontrollimine", "lbl_vote_signer": "E-hääle allkirjastaja: ", "lbl_vote_txt": "Sinu QR-koodile vastav hääl on talletatud valimiste serveris", "loading": "Laadin...", "notification_message": "Kontrollimine lõpetatud", "notification_title": "Riigi valimisteenistus", "welcome_message": "Hääle kontrollimiseks suuna nutiseadme kaamera arvuti ekraanil kuvatavale QR-koodile" }, "versions": { "android_version_code": 42, "ios_bundle_version": "2.1.19" } } } ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/auditor.convert.yaml ================================================ convert: input_bb: TESTCONF-bb-4.json output_bb: TESTCONF-shuffled.json pub: TESTCONF-pub.pem protinfo: prot.xml proofdir: mixnet/ ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/auditor.decrypt.yaml ================================================ decrypt: proofs: decout/TESTCONF-proof pub: initout/TESTCONF-pub.pem discarded: decout/TESTCONF-invalid anon_bb: TESTCONF-shuffled.json plain_bb: decout/TESTCONF.TESTQUESTION.plain tally: decout/TESTCONF.TESTQUESTION.tally candidates: TESTCONF.choices.bdoc districts: TESTCONF.districts.bdoc out: auditout invalidity_proofs: decout/TESTCONF-proof-invalid ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/auditor.integrity.yaml ================================================ integrity: ballotbox: TESTCONF.votes.zip anon_bb: TESTCONF-bb-4.json log_accepted: out-1/TESTCONF.TESTQUESTION.check.log1 log_squashed: out-2/TESTCONF.TESTQUESTION.squash.log2 log_revoked: out-3/TESTCONF.TESTQUESTION.revoke.log2 log_anonymised: out-4/TESTCONF.TESTQUESTION.anonymize.log3 bb_errors: out-1/ballotbox_errors.txt ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/auditor.mixer.yaml ================================================ mixer: protinfo: prot.xml proofdir: mixnet/ threaded: true ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/etcd_CA.pem ================================================ -----BEGIN CERTIFICATE----- MIIDgDCCAmigAwIBAgIJAN8HvtqlwnNYMA0GCSqGSIb3DQEBCwUAMFQxCzAJBgNV BAYTAkVFMRIwEAYDVQQKDAlTQ0NFSVYgT1kxHzAdBgNVBAsMFklWWFYgVGVzdCBD ZXJ0aWZpY2F0ZXMxEDAOBgNVBAMMB2V0Y2QgQ0EwIBcNMTcwNzI3MTIyMjIwWhgP MjExNzA3MDMxMjIyMjBaMFQxCzAJBgNVBAYTAkVFMRIwEAYDVQQKDAlTQ0NFSVYg T1kxHzAdBgNVBAsMFklWWFYgVGVzdCBDZXJ0aWZpY2F0ZXMxEDAOBgNVBAMMB2V0 Y2QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8xktrfvOSwiKg sd2CfOQ2PobheaMqhbd+zHyj+Vmw0KIc+LwRoPK6FiGVmeIJXp7bN3QbbZdbpTfh ap1xJr/wYu5JJO8DEy5i+Ea5IBGf6fZ6RTVngtbigln0FCFyRqumvD5yuZRbOnV6 w1Roe1GmhtrrW3QTHR5OSc8FjLcw21RkjrKbc0VtLoaGTU0CB7gSLUoHgXdOb3n5 n5pLa/N/4VjfIEqL7U4Pi9eFRl1tcKnj3+AwHp5HAHZgN937YDqXAtbWL7BwAToR CcW5ESm2xq6i46wg/OLhNU4bA8kfxqVCuCk/QDX3tvo4pkavC5bXMybc+3LfRfjO k7KKr+2XAgMBAAGjUzBRMB0GA1UdDgQWBBRWhI+0eFROcX+wY8h8jCU9SuXlHDAf BgNVHSMEGDAWgBRWhI+0eFROcX+wY8h8jCU9SuXlHDAPBgNVHRMBAf8EBTADAQH/ MA0GCSqGSIb3DQEBCwUAA4IBAQBOs9gwX28/Q2dvU9zFxHxVZ0x3jv2DAjAqBGHp I5ZbVjoWdjxurMwid9X6CF0nwqtHZQieGfKKt3wRv7G05yKZNlWkxSBfBiQwTwSs Mp2rj5zXDdQdkPWMD/08cDLj1jcynM8GMgUKzldcUKpWvwaL1MFaNda/pZAwd3DH r/s+XHnGKNafNalkCd+n/bWXUkJvVlE3Aakx2hfuNiT2WQ9rb6J7LkPhrWN4X1E4 1a++vt53qgMYH+jvYJkiKi9mDa+XVZR7XA9tD2xLGC5l0zt7Aaz4xUG9YVxc8/sW wP7zi1j187I4XZ9FIhO4+dmbpy+vg4e51xvQfC9/5T5vmfWR -----END CERTIFICATE----- ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/example.election.yaml ================================================ # Valimiste seadistuse näide identifier: TESTCONF questions: - TESTQUESTION period: servicestart: 2017-01-16T08:50:00+02:00 electionstart: 2017-01-16T09:00:00+02:00 electionstop: 2017-01-18T19:00:00+02:00 servicestop: 2017-01-18T19:15:00+02:00 verificationstop: 2017-01-18T19:20:00+02:00 voting: ratelimitstart: 50 ratelimitminutes: 5 verification: count: 3 minutes: 30 latestonly: false voterlist: key: !container rr_pub.key vis: url: https://vis-mock.local/vis3/ ca: - | -----BEGIN CERTIFICATE----- MIIDmzCCAoOgAwIBAgIDOBFTMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYTAkVF MRIwEAYDVQQKDAlTQ0NFSVYgT1kxHzAdBgNVBAsMFklWWFYgVGVzdCBDZXJ0aWZp Y2F0ZXMxEzARBgNVBAMMClNlcnZpY2UgQ0EwIBcNMjEwNjE3MTIwNTI0WhgPMjEy MTA1MjQxMjA1MjRaMFsxCzAJBgNVBAYTAkVFMRIwEAYDVQQKDAlTQ0NFSVYgT1kx HzAdBgNVBAsMFklWWFYgVGVzdCBDZXJ0aWZpY2F0ZXMxFzAVBgNVBAMMDnZpcy1t b2NrLmxvY2FsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzZW7yXGO SEt4qavm/vNJj9otKf9j8runLJcmoTGR61A5As2gluRnj3z6/U8An/VsX1dUG2qL sJecEXUkvXBSTw2IIyfA6lJNtaov44ytRB4fKpuFx+lb00WmuRf99uC0Tpp5K0Of 7D5NO5dgtMXLrdpzuyJD6NP2xrp8Dio5a1TosHcQEVWJvR/dwCr02TmcQjvILOVN vJFr038Dg77NQKojOsag60KRrHcKc1WukgUPu4AJ2VFCmn67rCfp39tusbcndsNs EX7zGNghOk85CMoGWlYfnJm94oAoKUsYtpF1hinfBN/EikXZwJbsVFoSg4mo/te2 MfwzK7E5j17JWwIDAQABo2owaDAdBgNVHQ4EFgQUI2yfomatZq3HLyL+DpqeBYO9 /1EwHwYDVR0jBBgwFoAUbyNWl77jkIGrjVtW7Eu4+qpDXxYwDgYDVR0PAQH/BAQD AgOoMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQCA RsgmPcL4NaHxQGRxPS2agw2ihLPgkmZcUJhJ0ObnmVYBjCCpYxaNd0vCWBYejChj Q2cblFAuKUtc+pwSC2WDPV9rRwLNOQn/PR2dzeNRP7L0UmNyPcH5pwmltAJLFQqW OdnlXL8ehXSLeIdzlBkqNYZCrj4Ulv4W8cLosjCrmwTZ8OW2E/GSTY7YljsPZZt0 uI5Sxz8VtlMJsVh0HWCQ4oAawp6BOgUAGdE9PIo2UlDHyUHBSDXDuZKTGut+yv1T NOq+xK3YM/CRFf/ujIuc1zx+dzkM9l72VJT2BQ6+LKeS5qzduJTG/8dJJFzgNB9p vo7reW+FURRS+CQI633D -----END CERTIFICATE----- min: 15 xroad: ca: !container xroadservice_ca.pem ballot: # This group must be the one used for voter ballot encryption public key # generation, check documentation for all available groups to use encpkeygroup: RFC3526ModPGroup3072 encpkey: !container vote_enc_pkey.pem auth: ticket: tls: roots: - !container TEST_of_EE_Certification_Centre_Root_CA.pem intermediates: - !container TEST_of_ESTEID-SK_2015.pem ocsp: url: http://demo.sk.ee/ocsp responders: - !container TEST_of_SK_OCSP_RESPONDER_2020.pem retry: 2 identity: pnoee age: method: estpic timezone: Europe/Tallinn limit: 18 vote: bdoc: filecount: 4 bdocsize: 32768 # 32 KiB filesize: 32768 # 32 KiB roots: - !container TEST_of_EE_Certification_Centre_Root_CA.pem intermediates: - !container TEST_of_ESTEID-SK_2015.pem profile: BES mid: url: https://tsp.demo.sk.ee/mid-api/ relyingpartyuuid: 00000000-0000-0000-0000-000000000000 relyingpartyname: DEMO language: EST authmessage: Mobiil-ID autentimise testimine. signmessage: Mobiil-ID allkirjastamise testimine. messageformat: GSM-7 authchallengesize: 64 statustimeoutms: 5000 roots: - !container TEST_of_EE_Certification_Centre_Root_CA.pem intermediates: - !container TEST_of_ESTEID-SK_2015.pem ocsp: url: http://demo.sk.ee/ocsp responders: - !container TEST_of_SK_OCSP_RESPONDER_2020.pem smartid: url: https://sid.demo.sk.ee/smart-id-rp/v2/ relyingpartyuuid: 00000000-0000-0000-0000-000000000000 relyingpartyname: DEMO certificatelevel: QUALIFIED authinteractionsorder: - type: verificationCodeChoice displayText60: authenticating - type: displayTextAndPIN displayText60: authenticating signinteractionsorder: - type: verificationCodeChoice displayText60: signing - type: displayTextAndPIN displayText60: signing authchallengesize: 64 statustimeoutms: 5000 roots: - !container TEST_of_EE_Certification_Centre_Root_CA.pem intermediates: - !container TEST_of_ESTEID-SK_2015.pem ocsp: url: http://demo.sk.ee/ocsp responders: - !container TEST_of_SK_OCSP_RESPONDER_2020.pem qualification: - protocol: tspreg conf: url: http://demo.sk.ee/tsa signers: - !container DEMO_SK_TIMESTAMPING_AUTHORITY_2020.pem delaytime: 1 retry: 2 - protocol: ocsp conf: url: http://demo.sk.ee/ocsp responders: - !container TEST_of_SK_OCSP_RESPONDER_2020.pem retry: 2 # this block defines any statistics that EHS shares with any other third-party stats: # this block defines detail statistics that EHS shares with VIS, # you can add 'common' here if implemented, or any other kind detail: # this block defines an automation (scheduler) for detail statistics sharing scheduler: # cron is a scheduler, you can add 'systemd-timer' here if implemented, # only crontab syntax supported for cron: section cron: min: "*/15" # minutes of a hour: 00, 15, 30, 45 hour: "*" # each hour day: "*" # each day month: "*" # each month weekday: "*" # each week day ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/example.technical.yaml ================================================ # Tehnilise seadistuse näide debug: true snidomain: inttest.ivxv.ee filter: tls: handshaketimeout: 20 ciphersuites: - TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 # Vanemate nutiseadmete tugi. - TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA codec: rwtimeout: 10 requestsize: 16384 # 16 KiB logrequests: true network: - id: default services: proxy: - id: proxy@proxy1.ivxv.ee address: proxy1.ivxv.ee:443 mid: - id: mid@mid1.ivxv.ee address: mid1.ivxv.ee:443 smartid: - id: smartid@smartid1.ivxv.ee address: smartid1.ivxv.ee:443 webeid: - id: webeid@webeid1.ivxv.ee address: webeid1.ivxv.ee:443 origin: https://ivxv1.mydomain.ivxv.ee:443 # address that client sees choices: - id: choices@choices1.ivxv.ee address: choices1.ivxv.ee:443 voting: - id: voting@voting1.ivxv.ee address: voting1.ivxv.ee:443 verification: - id: verification@verification1.ivxv.ee address: verification1.ivxv.ee:443 sessionstatus: - id: sessionstatus@sessionstatus1.ivxv.ee address: sessionstatus1.ivxv.ee:443 storage: - id: storage@storage1.ivxv.ee address: storage1.ivxv.ee:2379 peeraddress: storage1.ivxv.ee:2380 status: session: name: session servername: session.status.inttest.ivxv.ee authttl: 60 # ttl in seconds! choicettl: 90 votettl: 60 verifyttl: 60 logging: - address: logserver1.ivxv.ee port: 20514 - address: logserver2.ivxv.ee port: 514 storage: protocol: etcd conf: ca: !container etcd_CA.pem conntimeout: 5 optimeout: 10 size: 2147483648 # bytes snapshotcount: 10000 # etcd revisions heartbeattimeout: 100 # ms electiontimeout: 1000 # ms bootstrap: - storage@storage1.ivxv.ee ordertimeout: 10 backup: ["03:00", "09:00", "15:00", "21:00"] ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/example.trust.yaml ================================================ # Usaldusjuure seadistuse näide container: bdoc: filecount: 50 bdocsize: 104857600 # 100 MiB filesize: 104857600 # 100 MiB roots: - !container TEST_of_EE_Certification_Centre_Root_CA.pem intermediates: - !container TEST_of_ESTEID-SK_2015.pem profile: TS ocsp: responders: - !container TEST_of_SK_OCSP_RESPONDER_2020.pem tsp: signers: - !container DEMO_SK_TIMESTAMPING_AUTHORITY_2020.pem delaytime: 1 tsdelaytime: 60 authorizations: - ORAV,IVAN,30809010001 - ROPKA,KIVIVALVUR,32608320001 ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/example.voters.skip.yaml ================================================ # Valijate muudatusnimekirja nr. 15 vahelejätmise korralduse näide election: TESTCONF skip_voter_list: "https://vis-ehs-api.ria.ee/ehs-election-voters-changeset 2021-07-22T10:12:49Z" changeset: 15 ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/ivxv.properties.real ================================================ ca = EE-GovCA2018.pem.crt, ESTEID2018.pem.crt, ESTEID-SK_2015.pem.crt ocsp = SK_OCSP_RESPONDER_2011.pem.crt tsa = SK_TIMESTAMPING_AUTHORITY_2023.pem.crt ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/key.decrypt.yaml ================================================ decrypt: identifier: TESTCONF protocol: recover: threshold: 2 parties: 3 anonballotbox: TESTCONF-bb-4.json anonballotbox_checksum: TESTCONF-bb-4.json.sha256sum.bdoc candidates: TESTCONF.choices.bdoc districts: TESTCONF.districts.bdoc provable: true prove_invalid: true check_decodable: false out: decout ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/key.groupgen.yaml ================================================ groupgen: paramtype: mod length: 3072 init_template: key.init.template.yaml random_source: - random_source_type: DPRNG random_source_path: public_seed_file ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/key.init.original.yaml ================================================ init: identifier: TESTCONF paramtype: mod: p: 5809605995369958062791915965639201402176612226902900533702900882779736177890990861472094774477339581147373410185646378328043729800750470098210924487866935059164371588168047540943981644516632755067501626434556398193186628990071248660819361205119793693985433297036118232914410171876807536457391277857011849897410207519105333355801121109356897459426271845471397952675959440793493071628394122780510124618488232602464649876850458861245784240929258426287699705312584509625419513463605155428017165714465363094021609290561084025893662561222573202082865797821865270991145082200656978177192827024538990239969175546190770645685893438011714430426409338676314743571154537142031573004276428701433036381801705308659830751190352946025482059931306571004727362479688415574702596946457770284148435989129632853918392117997472632693078113129886487399347796982772784615865232621289656944284216824611318709764535152507354116344703769998514148343807 g: 2 out: initout skiptest: true fastmode: true signaturekeylen: 3072 signcn: SIGNATURE signsn: 1 enccn: ENCRYPTION encsn: 2 required_randomness: 128 random_source: - random_source_type: file random_source_path: randomness_file - random_source_type: system - random_source_type: DPRNG random_source_path: seed_file - random_source_type: stream random_source_path: /dev/urandom - random_source_type: user random_source_path: user_entropy.exe genprotocol: desmedt: threshold: 2 parties: 3 ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/key.init.yaml ================================================ init: identifier: TESTCONF paramtype: mod: p: 58096059953699580627919159656392014021766122269029005337.. g: 2 out: initout skiptest: true fastmode: true signaturekeylen: 3072 signcn: SIGNATURE signsn: 1 enccn: ENCRYPTION encsn: 2 required_randomness: 128 random_source: - random_source_type: file random_source_path: randomness_file - random_source_type: system - random_source_type: DPRNG random_source_path: seed_file - random_source_type: stream random_source_path: /dev/urandom - random_source_type: user random_source_path: user_entropy.exe genprotocol: desmedt: threshold: 2 parties: 3 ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/key.testkey.yaml ================================================ testkey: identifier: TESTCONF out: initout threshold: 2 parties: 3 fastmode: false ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/key.util.yaml ================================================ util: listreaders: true ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/processor.anonymize.yaml ================================================ anonymize: ballotbox: out-3/TESTCONF-bb-3.json ballotbox_checksum: out-3/TESTCONF-bb-3.json.sha256sum.bdoc out: out-4 ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/processor.check.yaml ================================================ check: ballotbox: TESTCONF.votes.zip ballotbox_checksum: TESTCONF.votes.zip.sha256sum.bdoc signed_ballot_max_size_bytes: 32768 districts: TESTCONF.districts.bdoc registrationlist: TESTCONF.registration.zip registrationlist_checksum: TESTCONF.registration.zip.sha256sum.bdoc tskey: TESTCONF.ts.key vlkey: TESTCONF.voterfile.pub.key voterlists_dir: TESTCONF.voterlists voterlists: - path: TESTCONF.voters_1 signature: TESTCONF.voters_1.signature - path: TESTCONF.voters_2 signature: TESTCONF.voters_2.signature election_start: 2017-05-01T12:00:00+03:00 out: out-1 ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/processor.checkAndSquash.yaml ================================================ checkAndSquash: ballotbox: TESTCONF.votes.zip ballotbox_checksum: TESTCONF.votes.zip.sha256sum.bdoc signed_ballot_max_size_bytes: 32768 districts: TESTCONF.districts.bdoc registrationlist: TESTCONF.registration.zip registrationlist_checksum: TESTCONF.registration.zip.sha256sum.bdoc tskey: TESTCONF.ts.key vlkey: TESTCONF.voterfile.pub.key voterlists_dir: TESTCONF.voterlists voterlists: - path: TESTCONF.voters_1 signature: TESTCONF.voters_1.signature - path: TESTCONF.voters_2 signature: TESTCONF.voters_2.signature enckey: TESTCONF-enc.pub.key election_start: 2017-05-01T12:00:00+03:00 out: out-2 ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/processor.export.yaml ================================================ export: ballotbox: TESTCONF.votes.zip ballotbox_checksum: TESTCONF.votes.zip.sha256sum.bdoc signed_ballot_max_size_bytes: 32768 out: out-export ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/processor.revoke.yaml ================================================ revoke: ballotbox: out-2/TESTCONF-bb-2.json ballotbox_checksum: out-2/TESTCONF-bb-2.json.sha256sum.bdoc districts: TESTCONF.districts.bdoc revocationlists: - TESTCONF.revoke_1.bdoc - TESTCONF.revoke_2.bdoc out: out-3 ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/processor.revokeAndAnonymize.yaml ================================================ revokeAndAnonymize: ballotbox: out-2/TESTCONF-bb-2.json ballotbox_checksum: out-2/TESTCONF-bb-2.json.sha256sum.bdoc districts: TESTCONF.districts.bdoc revocationlists: - TESTCONF.revoke_1.bdoc - TESTCONF.revoke_2.bdoc out: out-4 ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/processor.squash.yaml ================================================ squash: ballotbox: out-1/TESTCONF-bb-1.json ballotbox_checksum: out-1/TESTCONF-bb-1.json.sha256sum.bdoc districts: TESTCONF.districts.bdoc enckey: TESTCONF-enc.pub.key out: out-2 ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/processor.stats.yaml ================================================ stats: ballotbox: TESTCONF.votes.zip signed_ballot_max_size_bytes: 32768 election_day: 2018-11-11 period_start: 2018-11-01T10:00:00+03:00 period_end: 2018-11-07T22:00:00+03:00 districts: TESTCONF.districts.bdoc vlkey: TESTCONF.voterfile.pub.key voterlists: - path: TESTCONF.voters_1 signature: TESTCONF.voters_1.signature - path: TESTCONF.voters_2 signature: TESTCONF.voters_2.signature out: out-stats ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/processor.statsdiff.yaml ================================================ statsdiff: compare: out-stats/TESTCONF-stats.json to: TESTCONF-voting-stats.json diff: TESTCONF-stats-diff.json ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/processor.verify.yaml ================================================ verify: file: processor.yaml.bdoc ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/rnd.groupgen.yaml ================================================ groupgen: [...] random_source: - random_source_type: DPRNG random_source_path: public_seed_file ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/rnd.init.yaml ================================================ init: [...] required_randomness: 128 random_source: - random_source_type: system - random_source_type: user random_source_path: server.exe ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/rr_pub.key ================================================ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxOJOUqfOxVHHGplNmSSt LYXfpjyRlJrONLu74b85rBjTmr1bBwLRz+LemN9QWJJySKMaB0kShUhYoBDCAnpr gChxvnMzh2fsX9eK//dBWj+xbWFtzr2rrKLR8BnbB8SFDH18p1c4Pk3fDZGTME0D gmceUhAS83kZb/sZeRBf3ODDf9eWgFZupOOLGMIzwUYlMbYGGDV8dR8tNHKyNgj7 yWWPlCrqh1vrBqYSDcTZv0B5Rd+aaBwwvTFLc3cqeE2Xy59Rh7bJvTf8IHlPBPRY eqDqGvpQ/1rQcuqzfqqB6zc1qHUu09nViLc6qJJ3jQ5jQjJ1OREz9u05whEpD8Y1 9QIDAQAB -----END PUBLIC KEY----- ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/vote_enc_pkey.pem ================================================ -----BEGIN PUBLIC KEY----- MIIDMzCCAaEGCSsGAQQBl1UCATCCAZICggGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiK Z8x0Agu+pjsTmyJRSgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY3 7WsL/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7ORbPcIAfLihY78FmNpINhxV05ppFj+o/STP X4NlXSPco62WHGLzViCFUrue1SkHcJaWbWcMNU5KvJgE8XRsCMoYIXwykF5GLjbOO+OedywYDoYD myeDouwHoo+1xV3wb0xSyd4ry/aVWBcYOZVJfOqVauUV0iYYmPoFEBVyjlqKqsQtrTMXDQRQejOo VSGr3xy6ZOz7hQRY2+8KiupxV10GDH2zlw+FpuHkx6v1rozbCTPXHoyU4EolYZ3O49ImGtLua/Ev +gbZighk2HYCcz7IamRSHysYF3sgDLvhF1d6YV1sdwmIwLrZRuII4k+gdOWrMUPbW/zg/RCOS4LR IKk60sr//////////wIBAhsISEEtU0VUVVADggGKADCCAYUCggGBANr8jgmDq2SRdr85JlmKb+J4 OuqinXnSyJ/p/S0qqyde8VCzaBe2G7xj/l0zSVf1dj6JJeGzaN2G9DbrchOrix33ctjKNjnsp/kN Rro3xr/hPcnX3xdnywSvJIR8FEx2p1b3EU2AMEnmY8YDJeLYb7M/YqtLAfWd5qFCYsnzapMIgWj6 WfKvx8+h8STzI2Kc3xtHTW6KQrSRdb8yIJUIv5Tt+3Lgyng50twN4n1tynLjkpa5UG0sMIQWHjZV eEUWasqOUKfWugUEswUe7vi8AAL6q8EVxeh0C1VCwbkTdV/GwlI5zuvXdXZtFn9IOMgp3cHZjYNQ eEBFCVGzwzoBr9S3b75A7WAkGV596B7jHTJuBP02nJw4kU+TDr7tpVM2WK4tcZKrW3YNhOBofAt7 e1F2U7gyvwEECkEIc8PnYmh5twwUQv+AF2ABJOnoDR3cBbzqzyBzNSwnyu6kdegyXk8tBJLQ6ddu GZ6R0YR8V4xT7bCMVDMIM0fi7EmIkicJlQ== -----END PUBLIC KEY----- ================================================ FILE: Documentation/et/seadistuste_koostejuhend/config-examples/xroadservice_ca.pem ================================================ -----BEGIN CERTIFICATE----- MIIDfzCCAmegAwIBAgIUdYaa1OjZYFHPG7Ku7/Res9nou2AwDQYJKoZIhvcNAQEL BQAwTzELMAkGA1UEBhMCRUUxDjAMBgNVBAgMBVRhcnR1MQ8wDQYDVQQKDAZTQ0NF SVYxHzAdBgNVBAMMFnhzZXJ2aWNlLmRldmVsLml2eHYuZWUwHhcNMjIxMTMwMTY0 OTE2WhcNMjMxMTMwMTY0OTE2WjBPMQswCQYDVQQGEwJFRTEOMAwGA1UECAwFVGFy dHUxDzANBgNVBAoMBlNDQ0VJVjEfMB0GA1UEAwwWeHNlcnZpY2UuZGV2ZWwuaXZ4 di5lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMO3JO230yexwypu YHfBUgGiTvXTIBScpP1HwiLvBSr9FylD+iaZ890TpGLGMSH83FWgznu4NJmbqhHF dlrZICnivng9C7w+/egE0coqExRuR0ECWSLXAkfNVQ82YKPedhdZ3gw88YByFwvy EhjD17Fiv5CHZ3Iu3Fa4Lb0U95/0AI45GGgLA2DWB914Lqloc28lyCXb2cQ3OUoM CZkjGmsC9BLSXbsiqhU2TqQ1R1vh9/ru4cYR37JtWrU/H7tGwNB/8/AFQ161zZOz DXIBv5wEmZ4Rco+pXiQY5Tp3wucagwGdYFFqzxPeiPxRa56Qk5F7zBQyifEZ/ypK MCSRO9UCAwEAAaNTMFEwHQYDVR0OBBYEFLdlusaUnlQmzLPFo+fLNewQcPzwMB8G A1UdIwQYMBaAFLdlusaUnlQmzLPFo+fLNewQcPzwMA8GA1UdEwEB/wQFMAMBAf8w DQYJKoZIhvcNAQELBQADggEBAKTbKmS8Wy5vSiaqlEo+Cs6bl1/RMRjzjc7k51Jk 0l1uvPBEA2/3ETZAkErqpApfwOD+CGNLPAgoLMH7dSpzyb7Z7i6bjZUcH8CeKT/D XZNHun2eBIuEP+sRXdzs+UAwL5Axj5ncemNEjfHLgZaKA4cr/QNkrdxViqzUbsFY ACjTr5UhqSLZpjRRmT7UNtGB5wdk+F76DIEdjGCAWzpufPTwPDemx301P4qg4R1m nS0ErClDR+AiQLTkLB/uzCQmWMhgq/++boyw8Ny2A8I/OphEghsl//NYBlQ+Uz2K htQmzR3L3Q0NE+9vXh8PFuFLv1qtyOpuhEn0/HuU/NzGMcU= -----END CERTIFICATE----- ================================================ FILE: Documentation/et/seadistuste_koostejuhend/genparam.py ================================================ #!/usr/bin/env sage from sage.all import * n = 3072 p_found = False c = 0 while not(p_found): if (Mod(c,10000) == 0): print("c is: ", c) p = 2**n - 2**(n-64) - 1 + 2**64*(floor(2**(n-130)*pi.n(prec=10000))+c) if is_pseudoprime(p): print(p, " is prime") q = (p-1)/2 if is_pseudoprime(q): print(p, " is safe prime") p_found = True c = c + 1 ================================================ FILE: Documentation/et/seadistuste_koostejuhend/index.rst ================================================ .. IVXV seadistuste koostamise juhend IVXV seadistuste koostamise juhend ========================================================================== .. raw:: html

NB! See on HTML-versioon dokumendist. Tellijale antakse üle PDF-versioon.

.. toctree:: :maxdepth: 2 :numbered: annotatsioon ylevaade rakendused votmerakendus tootlemisrakendus auditirakendus kogumisteenus valijarakendus kontrollrakendus mixnet ================================================ FILE: Documentation/et/seadistuste_koostejuhend/kogumisteenus.rst ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus .. _kogumisteenus: Kogumisteenus ============= .. include:: kt-ylevaade.inc .. include:: kt-usaldusjuur.inc .. include:: kt-tehniline.inc .. include:: kt-valimised.inc .. include:: kt-valijate-nimekirja-vahelejätmine.inc .. include:: kt-volitused.inc .. include:: kt-krypto.inc ================================================ FILE: Documentation/et/seadistuste_koostejuhend/kontrollrakendus.rst ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus .. _kontroll: Kontrollrakenduse seadistamine ============================== Kontrollrakenduste seadistus on JSON formaadis. Reaalne sisu võib kahel seadistusel olla samasugune ka siis kui võimalike erinevuste tekkimise jaoks kasutatakse ennetavalt erinevaid URLe. Varasemalt on erinevate URLide kasutamist õigustanud nt. iOS rakenduste pikem tarnetsükkel, mis nõuab testseadistuste avalikustamist. Seadistus koosneb viiest peamisest rühmast * :token:`versions` - Rakenduse nõutud versioon * :token:`texts` - Kasutajaliideses kasutatavad tekstid * :token:`errors` - Kasutajaliideses kasutatavad veateated * :token:`colors` - Kasutajaliidese värvide koodid * :token:`params` - Rakenduse tööks vajalikud parameetrid * :token:`elections` - Igale küsimuse identifikaatorile vastav tekst kasutajaliideses Kõiki seadistatavaid väärtusi näeb näidisseadistusest. Kõik väärtused on kohustuslikud. Versioonide seadistamine ------------------------ Kontrollrakenduse versioon peab olema suurem või võrdne seadistuses määratud versiooniga. Versioonid kuuluvad rühma :token:`versions`: * :token:`android_version_code` - Android-rakenduse minimaalne versioonikood. Väärtus peab olema positiivne JSON täisarv. * :token:`ios_bundle_version` - iOS-rakenduse minimaalne versioonisõne. Väärtus peab olema JSON sõne, mis koosneb punktidega eraldatud positiivsetest täisarvudest. Parameetrite seadistamine ------------------------- Rakenduse tööks vajalikud parameetrid kuuluvad rühma :token:`params`: * :token:`verification_url` - Nimekiri kogumisteenuse hostinimedest või IP-aadressidest koos pordiga. Järjekord pole oluline. Väärtus peab olema JSON loend ka ühe URLi puhul. * :token:`verification_tls` - Nimekiri kogumisteenuse TLS sertifikaatidest PEM vormingus. Järjekord pole oluline. Väärtus peab olema JSON loend ka ühe sertifikaadi puhul. * :token:`help_url` - Abiinfo vaate URL * :token:`close_timeout` - Ajaaken, mil on kasutajal võimalik oma valikut näha enne rakenduse sulgumist. Millisekundites. * :token:`close_interval` - Intervall, millega uuendatakse :token:`close_timeout` väärtust kasutajaliideses. Millisekundites. * :token:`con_timeout_1` - Kogumisteenusega ühenduse saamise esimese katse ajapiirang. Millisekundites. * :token:`con_timeout_2` - Kui esimese ringiga ei saadud ühendust ühegi kogumisteenuse instantsiga, proovitakse uuesti selle ajapiiranguga. Millisekundites. * :token:`public_key` - Valimiste avalik võti, millega krüpteeritakse valijate hääli. PEM vormingus. * :token:`tspreg_service_cert` - Ajatembeldusteenuse sertifikaat PEM vormingus. * :token:`ocsp_service_cert` - OCSP-teenuse sertifikaadid PEM vormingus. Järjekord pole oluline. Väärtus peab olema JSON loend ka ühe väärtuse puhul. Kui väli on tühi, siis tuvastatakse OCSP responderi sertifikaat automaatselt. * :token:`tspreg_client_cert` - Kogumisteenuse sertifikaat registreerimispäringute tegemiseks PEM vormingus. Tekstide seadistamine --------------------- Kasutajaliideses kasutatavad tekstid kuuluvad rühma :token:`texts`. Järgmised tekstid on parametriseeritavad: * :token:`lbl_close_timeout` - Kontrollrakenduse sulgemisteade koos loenduriga. Tekst peab sisaldama märgendit XX, mis asendatakse automaatselt rakenduse sulgemiseni jäänud ajaga sekundites. Näide ----- .. literalinclude:: config-examples/android-ios-config.json :language: json ================================================ FILE: Documentation/et/seadistuste_koostejuhend/kt-krypto.inc ================================================ .. IVXV seadistuste koostamise juhend .. _kt-krypto: Kogumisteenuse krüptovõtmed --------------------------- Kogumisteenuse andmevahetuse turvamiseks on tarvis luua komplekt krüptograafilisi võtmeid. Komplekti koosseis sõltub kogumisteenuse tehnilistest seadistustest. #. Teenuse krüptovõti ja TLS-sertifikaat - kasutatakse teenuste omavahelise suhtluse turvamiseks kõigi teenuste puhul peale vahendusteenuse; #. Hääletamisteenuse ajatemplipäringute signeerimisvõti - kasutatakse ajatemplipäringute signeerimiseks juhul, kui ajatempliteenus on registreerimisteenuseks; #. Mobiil-ID/Smart-ID/Web eID tugiteenuse jagatud krüptimissaladus – kasutatakse sümmeetrilise AES-256 krüptimise jaoks. Krüptimissaladusega krüptib Mobiil-ID tugiteenus hääletajale väljastatava identsustõendi, mille abil hääletaja enda identiteeti teistele teenustele tõendab. Teenuse krüptovõtme ja TLS-sertifikaadi genereerimine ***************************************************** Teenuse krüptovõti ja TLS-sertifikaat genereeritakse kõigile teenustele peale vahendusteenuse. Kõikide teenuste sertifikaadid peavad olema välja antud sama sertifitseerimiskeskuse (CA – *Certificate Authority*) poolt. CA sertifikaadi genereerimine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Sertifitseerimiskeskuse krüptovõtme ja sertifikaadi genereerimine toimub järgneva käsuga: .. code-block:: shell-session $ openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -x509 -nodes -days 365 -out ca.pem -keyout ca.key -utf8 -subj "/C=EE/O=Example/OU=IVXV Test Certificates/CN=Service CA" Käsu väljundiks on failid :file:`ca.key` (võti) ja :file:`ca.pem` (sertifikaat). Teenuse isendi krüptovõtme ja TLS-sertifikaadi genereerimine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Teenuse isendi krüptovõtme ja sertifikaadipäringu genereerimine toimub järgneva käsuga: .. code-block:: shell-session $ openssl req -newkey ec -pkeyopt ec_paramgen_curve:P-256 -nodes -out -tls.csr -keyout -tls.key -utf8 -subj "/C=EE/O=Example/OU=IVXV Test Certificates/CN=" Käsu väljundiks on failid :file:`-tls.key` (võti) ja :file:`-tls.csr` (sertifikaadipäring). .. attention:: Talletusteenuse puhul peab sertifikaadipäringus olema CN väärtuseks teenuse identifikaatori asemel hostinimi: erinevalt teistest teenustest ei kasutata talletusteenuse puhul alternatiivset TLS nime. Teenuse isendi TLS-sertifikaadi genereerimine toimub järgneva käsuga: .. code-block:: shell-session $ openssl x509 -req -days 365 -CA ca.pem -CAkey ca.key -set_serial 1 -extfile service-cert-openssl.cnf -extensions ext_ -in -tls.csr -out -tls.pem Käsu väljundiks on fail :file:`-tls.pem`. Sertifikaadi genereerimiseks peab failisüsteemis olema seadistusfail :file:`service-cert-openssl.cnf`. .. literalinclude:: ../../../tests/testdata/testca/service/service-cert-openssl.cnf :caption: Fail ``service-cert-openssl.cnf`` :language: ini Hääletamisteenuse ajatemplipäringute signeerimisvõtme ja sertifikaadi genereerimine *********************************************************************************** Hääletamisteenuse registreerimispäringute tegemise võti genereeritakse järgneva käsuga: .. code-block:: shell-session $ openssl genrsa -out tspreg.key 2048 Käsu väljundiks on fail :file:`tspreg.key`. Hääletamisteenuse registreerimispäringute tegemise võtme sertifikaat genereeritakse järgneva käsuga: .. code-block:: shell-session $ openssl req -x509 -nodes -days 365 -out tspreg.pem -key tspreg.key -utf8 -subj "/C=EE/O=Example/OU=IVXV Test Certificates/CN=Collector Registration" Käsu väljundiks on fail :file:`tspreg.pem`. .. note:: Hääletamisteenuse ajatemplipäringute signeerimisvõti on vaja genereerida vaid juhul, kui ajatempliteenust kasutatakse registreerimisteenuseks. Mobiil-ID/Smart-ID/Web eID tugiteenusele jagatud krüptimissaladuse genereerimine ******************************************************************************** Jagatud krüptimissaladus genereeritakse järgneva käsuga: .. code-block:: shell-session $ openssl rand -out mobid-shared-secret.key 32 Käsu väljundiks on 32 baidi suurune fail :file:`mobid-shared-secret.key`, mida Mobiil-ID, Smart-ID ja Web eID teenus hakkab kasutama sümmeetrilise AES-256 krüptimise jaoks. .. note:: Mobiil-ID/Smart-ID/Web eID tugiteenuse jagatud krüptimissaladus on vaja genereerida vaid juhul, kui Mobiil-ID, Smart-ID või Web eID tugiteenus on kasutusel. .. vim:syntax=rst: ================================================ FILE: Documentation/et/seadistuste_koostejuhend/kt-tehniline.inc ================================================ .. IVXV seadistuste koostamise juhend .. _kt-technical: Kogumisteenuse tehnilise seadistuse koostamine ---------------------------------------------- Tehniline seadistus määrab kogumisteenuse tehnilised parameetrid. Sama tehnilist seadistust peaks olema võimalik kasutada erinevate valimiste seadistustega [#]_. .. [#] Aga mitte samaaegselt: kogumisteenus toetab ainult ühte valimist. Tehnilise seadistuse koostab kogumisteenuse osutaja. Seadistusfaili nimi peab alati lõppema stringiga :file:`technical.yaml`. Failinime võimalik eesliide peab alati lõppema punktiga. :debug: Tõeväärtus, kas logidesse kirjutatakse silumisteateid. :snidomain: Kohustuslik väli. Domeen, mida kasutatakse teenuste SNI väärtuse seadistamiseks. Varasemalt on kasutusel olnud väärtus `ivxv.invalid` võib kasutada ka reaalseid domeene, mille nimehaldus on korraldaja kontrolli all nagu nt. `ivxv.ee` ---- :filter: Kohustuslik väli. Alamblokk, mis sisaldab ühenduste filtrite seadistusi. :filter.tls: Kohustuslik väli. Alamblokk, mis sisaldab ühenduste TLS-filtri seadistusi. :filter.tls.handshaketimeout: Kohustuslik väli. Maksimaalne aeg sekundites TLS-kätluse läbiviimiseks. :filter.tls.ciphersuites: Kohustuslik väli. TLS-protokolli versioonis 1.2 rakendamiseks lubatud šifrikomplektid. Hetkel toetatud valikud on:: TLS_RSA_WITH_AES_128_CBC_SHA TLS_RSA_WITH_AES_256_CBC_SHA TLS_RSA_WITH_AES_128_GCM_SHA256 TLS_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 Kui TLS-kätluse käigus lepitakse kokku TLS-protokolli versioonis 1.3, siis šifrikomplekti seadistada ei saa ning kõik serveri poolt toetatud turvalised šifrid on lubatud. Hetkel on nendeks:: TLS_AES_128_GCM_SHA256 TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 :filter.codec: Kohustuslik väli. Alamblokk, mis sisaldab ühenduste koodekfiltri seadistusi. :filter.codec.rwtimeout: Kohustuslik väli. Maksimaalne aeg sekundites valijalt tervikliku päringu lugemiseks. Maksimaalne aeg sekundites valijale tervikliku päringu kirjutamiseks. :filter.codec.requestsize: Päringu maksimaalne suurus baitides. Välja puudumise või väärtuse 0 korral päringu suurust ei piirata. :filter.codec.logrequests: Tõeväärtus, kas logidesse kirjutatakse kõik sissetulnud päringud algkujul. Päringu logi talletatakse tavalogist eraldi. ---- :network: Kohustuslik väli. Loetelu kogumisteenuse võrgusegmentidest. Kõik kogumisteenuse võrgusegmentide parameetrid määrab kogumisteenuse osutaja. :network.*.id: Kohustuslik väli. Võrgusegmendi identifikaator. :network.*.services: Kohustuslik väli. Alamblokk, mis sisaldab kogumisteenuse selle võrgusegmendi mikroteenuste seadistust. .. todo:: Kuigi kõik selle bloki parameetrid määrab Koguja, kas Korraldaja peaks vähemalt vahendusteenuste väliseid aadresse kinnitama, kuna need on otspunktid, kuhu valija- ja kontrollrakendus peavad ühendama hakkama? :network.*.services.proxy: Loetelu, mis sisaldab vahendusteenuste isendite seadistust. :network.*.services.mid: Loetelu, mis sisaldab Mobiil-ID toeteenuste isendite seadistust. :network.*.services.smartid: Loetelu, mis sisaldab Smart-ID toeteenuste isendite seadistust. :network.*.services.webeid: Loetelu, mis sisaldab Web eID toeteenuste isendite seadistust. :network.*.services.sessionstatus: Loetelu, mis sisaldab Session status toeteenuste isendite seadistust. :network.*.services.choices: Loetelu, mis sisaldab nimekirjateenuste isendite seadistust. :network.*.services.voting: Loetelu, mis sisaldab hääletamisteenuste isendite seadistust. :network.*.services.verification: Loetelu, mis sisaldab kontrollteenuste isendite seadistust. :network.*.services.storage: Loetelu, mis sisaldab talletusteenuste isendite seadistust. :network.*.services.log: Loetelu, mis sisaldab logikogumisteenuste isendite seadistust. :network.*.services.backup: Varundusteenuse isendi seadistus. :network.*.services.*.id: Kohustuslik väli. Mikroteenuse isendi identifikaator. :network.*.services.*.address: Kohustuslik väli. Mikroteenuse isendi võrguaadress ja -port. .. todo:: Sama parameetrit kasutatakse kirjeldamaks seda, millisel aadressil teenus peab kuulama hakkama ning milliselt aadressilt saavad haldusteenus ja vahendusteenus teenusele ligi. Kui sisemine ja välimine aadress hakkavad erinema, siis tuleb see parameeter lüüa kaheks. :network.*.services.*.peeraddress: Mikroteenuse isenditevahelise suhtluse võrguaadress ja -port. Kasutatakse ainult juhul, kui sama teenust pakkuvad isendid peavad omavahel suhtlema (nt talletusteenus). .. todo:: Sama parameetrit kasutatakse kirjeldamaks seda, millisel aadressil teenus peab kuulama hakkama ning milliselt aadressilt saavad teised isendid teenusele ligi. Kui sisemine ja välimine aadress hakkavad erinema, siis tuleb see parameeter lüüa kaheks. :network.*.services.*.origin: Kohustuslik väli. Mikroteenuse isendi täielik domeeninimi ja -port. ---- :status: Kohustuslik väli. Alamblokk, mis sisaldab loetelu staatust raporteeriva serveritest. :status.name: Kohustuslik väli. Hetkel toetatud ainult ``session``. Staatust raporteeriva serveri nimi. :status.servername: Kohustuslik väli. Staatust raporteeriva serveri SNI. :status.authttl: Kohustuslik väli. Aeg sekundites. Vaikeväärtus 0. Maksimaalne aeg autentimiseks. :status.choicettl: Kohustuslik väli. Aeg sekundites. Vaikeväärtus 0. Maksimaalne aeg valiku tegemiseks. :status.votettl: Kohustuslik väli. Aeg sekundites. Vaikeväärtus 0. Maksimaalne aeg hääle andmiseks. :status.verifyttl: Kohustuslik väli. Aeg sekundites. Vaikeväärtus 0. Maksimaalne aeg hääle verifitseerimiseks. ---- :logging: Alamblokk, mis sisaldab loetelu mikroteenuste kauglogimise serveritest. Siin blokis kirjeldatakse: * Logiseire teenus. Alati loetelus esimene. Teenusele saadetakse IVXV logi alates tasemest INFO; * Vajadusel ka täiendavad välised logikogujad, kuhu saadetakse täielik logi alates tasemest DEBUG. Logimine toimub üle RELP protokolli. Kõik logiserverite parameetrid määrab kogumisteenuse osutaja. :logging.address: Kohustuslik väli. Logiserveri aadress (IP-aadress või hostinimi). :logging.port: Logiserveri port (täisarv, vaikimisi *20514*). ---- :storage: Kohustuslik väli. Alamblokk, mis sisaldab talletusprotokolli seadistust. Kõik talletusprotokolli parameetrid määrab kogumisteenuse osutaja. :storage.protocol: Kohustuslik väli. Kogumisteenuse talletusprotokoll. Hetkel toetatud ainult ``etcd``. :storage.conf: Kohustuslik väli. Talletusprotokolli seadistus. Sisu sõltub ``storage.protocol`` parameetri väärtusest. :storage.conf.ca: Kohustuslik väli. Kasutatakse ainult juhul kui ``storage.protocol`` on ``etcd``. Talletusteenuste TLS sertifikaatide väljastaja sertifikaat. :storage.conf.conntimeout: Kohustuslik väli. Kasutatakse ainult juhul kui ``storage.protocol`` on ``etcd``. Maksimaalne aeg sekundites etcd serveriga ühenduse loomiseks. :storage.conf.optimeout: Kohustuslik väli. Kasutatakse ainult juhul kui ``storage.protocol`` on ``etcd``. Maksimaalne aeg sekundites ühe talletusoperatsiooni teostamiseks. :storage.conf.size: Valikuline väli. Kasutatakse ainult juhul kui ``storage.protocol`` on ``etcd``. Andmebaasi suurus baitides. :storage.conf.electiontimeout: Valikuline väli. Kasutatakse ainult juhul kui ``storage.protocol`` on ``etcd``. Aeg millisekundites, mida kasutatakse liidri kättesaadavuse kontrollimiseks. :storage.conf.heartbeattimeout: Valikuline väli. Kasutatakse ainult juhul kui ``storage.protocol`` on ``etcd``. Aeg millisekundites, mida kasutatakse andmebaasi hosti kättesaadavuse kontrollimiseks. :storage.conf.snapshotcount: Valikuline väli. Kasutatakse ainult juhul kui ``storage.protocol`` on ``etcd``. Andmebaasi talletamispäringute arv, mille täitumise korral andmebaasi seis varundatakse. :storage.conf.bootstrap: Kohustuslik väli. Kasutatakse ainult juhul kui ``storage.protocol`` on ``etcd``. Loetelu nende talletusteenuste identifikaatoritest, mis on osa algsest etcd klastrist. Vajalik, et talletusteenuse isend teaks esmasel käivitumisel, kas see loob uut klastrit või liitub olemasolevaga. Esmases tehnilises seadistuses peab loetelu kattuma ``network`` blokis loetletud talletusteenuste identifikaatoritega. Hiljem teenuseid lisades või eemaldades ei tohi ``storage.conf.bootstrap`` väärtust uuendada. :storage.ordertimeout: Aeg sekundites. Vaikeväärtus 5. Maksimaalne aeg hääle kirjutamiseks häälte järjekorra tabelisse. ---- :backup: Varunduse parameetrid. Loetelu varundamise kellaaegadest vormingus HH:MM. :file:`example.technical.yaml`: .. literalinclude:: config-examples/example.technical.yaml :language: yaml :linenos: .. vim:syntax=rst: ================================================ FILE: Documentation/et/seadistuste_koostejuhend/kt-usaldusjuur.inc ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus .. _kt-trust: Kogumisteenuse usaldusjuure seadistamine ---------------------------------------- Kogumisteenuse usaldusjuur sisaldab andmeid seadistuste (kaasa arvatud usaldusjuure enda) allkirjade kontrollimiseks ja nimekirja süsteemi esmastest volitustest. Usaldusjuure seadistuse koostab valimiste korraldaja. Seadistusfaili nimi peab alati lõppema stringiga :file:`trust.yaml`. Failinime võimalik eesliide peab alati lõppema punktiga. .. attention:: Usaldusjuure seadistuste laadimine lähtestab kogumisteenuse. Seetõttu pole juba seadistatud kogumisteenuse usaldusahela muutmine võimalik. Volituste muutmine on võimalik vastavate korralduste abil. :container: Kohustuslik väli. Alamblokk, mis sisaldab seadistusfailide allkirjade kontrollimise seadistust. :container.bdoc: Alamblokk, mis sisaldab seadistusfailide BDOC-allkirjade kontrollimise seadistust. :container.bdoc.filecount: Kohustuslik väli. Maksimaalne lubatud failide arv ZIP konteineris, ning kuna tegu on BDOC konteineriga, siis sellele väärtusele tuleb alati liita 3, sest BDOC konteineris on lisaks sisufailidele veel ``signatures0.xml``, ``manifest.xml`` ja ``mimetype`` failid. :container.bdoc.bdocsize: Kohustuslik väli. BDOC konteineri maksimaalne lubatud suurus baitides. :container.bdoc.filesize: Kohustuslik väli. BDOC konteineris olevate failide maksimaalne lubatud hõrendatud suurus baitides. :container.bdoc.roots: Kohustuslik väli. Seadistuste allkirjastajate sertifikaatide usaldusjuured. :container.bdoc.intermediates: Seadistuste allkirjastajate sertifikaatide vahesertifikaadid. Usalduse saavutamiseks peab nende sertifikaatide abil olema võimalik luua ahel allkirjastaja sertifikaadist usaldusjuureni. :container.bdoc.profile: Kohustuslik väli. Seadistuste allkirjadelt nõutav BDOC profiil. Toetatud valikud on ``BES`` (põhiprofiil kirjeldatud BDOC spetsifikatsiooni jaotises 5), ``TS`` (ajatemplitega profiil kirjeldatud BDOC spetsifikatsiooni jaotises 6.2). :container.bdoc.ocsp.responders: Kasutatakse ainult juhul kui ``container.bdoc.profile`` on ``TS``. Kehtivuskinnitusi väljastanud OCSP responderi sertifikaadid. Kui nende hulgast responderi sertifikaati ei leita, siis otsitakse OCSP vastuses olevate sertifikaatide hulgast selline, mis on antud välja sama väljastaja poolt, mis seadistuste allkirjastaja sertifikaat, ning on lubatud OCSP vastuste signeerimiseks. AIA loogika kasutamise korral võib väli olla tühi. :container.bdoc.tsp.signers: Kohustuslik väli. Kasutatakse ainult juhul kui ``container.bdoc.profile`` on ``TS``. Ajatempliteenuse vastuse allkirjastamise sertifikaadid. :container.bdoc.tsp.delaytime: Kohustuslik väli. Kasutatakse ainult juhul kui ``container.bdoc.profile`` on ``TS``. Maksimaalne ajanihe ajatempli loomise ja allkirjastamise vahel sekundites. :container.bdoc.tsdelaytime: Kasutatakse ainult juhul kui ``container.bdoc.profile`` on ``TS``. Maksimaalne ajanihe ajatempli ja kehtivuskinnituse loomise vahel sekundites. Välja puudumise või väärtuse 0 korral peavad mõlemad olema loodud samal sekundil. :authorizations: Kohustuslik väli. Esmane nimekiri kogumisteenuse halduri volitustega isikutest (vt. :ref:`rollid`), mis rakendatakse süsteemile usaldusjuure laadimisel. Iga isiku kohta on kirje tema ID-kaardi välja ``Common Name`` (CN) väärtusega. Minimaalselt peab sisaldama usaldusjuure signeerinud isiku andmeid. Näide ***** :file:`example.trust.yaml`: .. literalinclude:: config-examples/example.trust.yaml :language: yaml :linenos: ================================================ FILE: Documentation/et/seadistuste_koostejuhend/kt-valijate-nimekirja-vahelejätmine.inc ================================================ .. IVXV seadistuste koostamise juhend .. _kt-voter-list-skip: Valijate nimekirja vahelejätmine -------------------------------- Valijate nimekirja vahelejätmine tähendab haldusteenuses registreerinud vigase valijate nimekirja asendamist tühja nimekirjaga. Protseduur on vajalik olukorras, kus haldusteenus on Valimiste Infosüsteemist alla laadinud ja haldusteenuses registreerinud valijate muudatusnimekirja, mida pole võimalik kogumisteenusele rakendada (nimekiri on vigane või pole kooskõlas teiste kogumisteenuste seadistustega). Valijate nimekirja vahelejätmine korralduse koostab valimiste korraldaja. Seadistusfaili nimi peab alati lõppema stringiga :file:`.skip.yaml`. :election: Kohustuslik väli. Valimise unikaalne identifikaator. :skip_voter_list: Kohustuslik väli. Vahele jäetava valijate muudatusnimekirja versioon. :changeset: Kohustuslik väli. Vahele jäetava valijate muudatusnimekirja järjekorranumber. Näide ***** :file:`example.voters.skip.yaml`: .. literalinclude:: config-examples/example.voters.skip.yaml :language: yaml :linenos: .. vim:syntax=rst: ================================================ FILE: Documentation/et/seadistuste_koostejuhend/kt-valimised.inc ================================================ .. IVXV seadistuste koostamise juhend .. _kt-election: Kogumisteenusele valimise seadistuse koostamine ----------------------------------------------- Valimise seadistus määrab ühe valimise seadistuse. Valimise seadistuse koostab valimiste korraldaja. Seadistusfaili nimi peab alati lõppema stringiga :file:`election.yaml`. Failinime võimalik eesliide peab alati lõppema punktiga. :identifier: Kohustuslik väli. Valimise unikaalne identifikaator. :questions: Loetelu, mis sisaldab ühe või enama valimise küsimuse unikaalset identifikaatorit. Unikaalsus peab olema tagatud ainult konkreetse valimise küsimuste hulgas. Kohustuslik väli. ---- :period: Kohustuslik väli. E-hääletuse perioodi andmete alamblokk. :period.servicestart: Kohustuslik väli. Kogumisteenuses häälte vastuvõtmise algusaeg. Sellest hetkest alates hakkab kogumisteenus ühendusi teenindama. See aeg peab eelnema valimise algusajale ning on mõeldud enne valimise algust proovihääle andmiseks. Enne ``electionstart`` parameetriga määratud aega vastu võetud häälte puhul tagastatakse valijarakendusele hääle esitamise lõpus vastav veateade (hääl jõudis kohale enne valimise algust). Sellised hääled tühistatakse automaatselt töötlemise käigus. :period.electionstart: Kohustuslik väli. E-hääletuse algusaeg. Sellest hetkest alates antud hääled lähevad häälte lugemisel arvesse. :period.electionstop: Kohustuslik väli. E-hääletuse lõpuaeg. Sellest hetkest lõpetatakse valikute nimekirjade väljastamine. :period.servicestop: Kohustuslik väli. E-hääletuse lõppemisaeg. Sellest hetkest lõpetatakse häälte vastuvõtmine ning teenused lõpetavad töö. ---- :voting: Hääle esitamise parameetrite alamblokk. :voting.ratelimitstart: Valija poolt esitatud häälte kogus, mille järel rakendub talle hääletamissageduse piirang. Arvesse lähevad ka vigased hääled, kuna muidu saaks nendega süsteemi koormata piirangust hoolimata. Välja puudumise või väärtuse 0 korral rakendub piirang alates esimesest häälest. :voting.ratelimitminutes: Aeg minutites, mis peab jääma kahe hääle esitamise vahele, kui valijale on rakendatud hääletamissageduse piirang. Välja puudumise või väärtuse 0 korral on hääletamissageduse piirangud välja lülitatud. ---- :verification: Kohustuslik väli. Hääle kontrollimise parameetrite alamblokk. :verification.count: Kohustuslik väli. Suurim ühe hääle lubatud kontrollimiste arv. :verification.minutes: Kohustuslik väli. Hääle kontrollimise perioodi kestus minutites. Pärast hääle andmist on selle perioodi vältel võimalik häält kontrollida. :verification.latestonly: Tõeväärtus, kas kontrollida saab ainult valija viimati antud häält. Kui väärtus on väär või puudu, siis saab kontrollida kõiki valija hääli (teiste piirangute raames). ---- :voterforeignehak: Alaliselt välisriigis elavate valijate ringkonnakuuluvuse tuvastamiseks kasutatav EHAK-kood. Kui parameeter on määratud, siis alaliselt välisriigis elavad valijad kuuluvad ringkondadesse, kuhu kuulub ka parameetris määratud EHAK-koodile vastav haldusüksus. Täiendavalt peab ringkondade nimekiri sisaldama sellise EHAK-koodiga haldusüksust. Kui parameeter on määramata, siis kasutatakse EHAK-koodi "0000". Kui parameeter on määramata ning ringkondade nimekiri ei sisalda vaikekoodile vastavat haldusüksust, siis valijate nimekiri ei tohi sisaldada alaliselt välisriigis elavaid valijaid. :ignorevoterlist: Ringkonna identifikaator, mille valikud esitada kõigile valijatele. Kui see väärtus ei ole tühi, siis kogumisteenus ei kasuta valijate nimekirja ning esitab kõigile valijatele väärtusega määratud ringkonna valikud ja lubab hääletada kõigil, kellel õnnestub isikutuvastus ning hääle allkirja kontrollimine. ---- :voterlist: Kohustuslik väli. Valijate nimekirjade kontrollimise parameetrid. :voterlist.key: Kohustuslik väli. ECDSA-võtmepaari avalik võti valijate nimekirjade allkirja kontrollimiseks. :vis: Alamblokk, mis sisaldab Valimiste Infosüsteemi seadistust. :vis.url: Kohustuslik väli. Valimiste Infosüsteemi URL. :vis.ca: Valimiste Infosüsteemi TLS-sertifikaadi usaldusahel. :vis.min: Valimiste Infosüsteemi valijate nimekirja hankimise sagedus minutites (vaikeväärtus on 15). :xroad: Alamblokk, mis sisaldab X-teega ühenduva teenuse seadistust. :xroad.ca: X-teega teenuse TLS-sertifikaadi usaldusahel. ---- :ballot: Alamblokk, mis sisaldab sedeli verifitseerimise seadistust. :ballot.encpkeygroup: Kohustuslik väli. Abstraktne rühm, millele kuulub Võtmerakenduses genereeritud avalik võti häälte krüpteerimiseks. Võimalikud väärtused ``RFC3526ModPGroup2048`` (võtme pikkus on 2048 bitti ehk 256 baiti), ``RFC3526ModPGroup3072``, ``RFC3526ModPGroup4096``, ``RFC3526ModPGroup8192``, ``NIST-P256``, ``NIST-P384``, ``NIST-P521`` ja ``Edwards25519``. NB! Palun veendu, et valitud rühm loetelust oli ka kasutusel avaliku võtme genereerimisel Võtmerakenduses (vt Võtmerakenduse konfiguratsiooni faili). Antud rühma kasutatakse krüpteeritud häälte korrektsuse verifitseerimiseks. Antud väli on ignoreeritud kui `encpkey` on määratud. :ballot.encpkey: Avalik võti häälte krüpteerimiseks valijarakenduses. Võtme rühma kasutatakse krüpteeritud häälte korrektsuse verifitseerimiseks. ---- :auth: Kohustuslik väli. Alamblokk, mis sisaldab valija tuvastamise seadistust. :auth.ticket: Alamblokk, mis sisaldab piletipõhise valija tuvastamise seadistust. Piletipõhist valija tuvastamist kasutatakse Mobiil-ID/Smart-ID/Web eID puhul, kus ``mid``/``smartid``/``webeid`` teenus tuvastab valija ning väljastab talle pileti, millega teistele teenustele ennast tuvastada. See alamblokk on tühi, aga tema olemasolu või puudumine määrab, kas piletipõhine valija tuvastus on lubatud või ei. :auth.tls: Alamblokk, mis sisaldab TLS-põhise valija tuvastamise seadistust. TLS-põhist valijatuvastust kasutatakse ID-kaardi puhul. :auth.tls.roots: Kohustuslik väli. Valija TLS-klientsertifikaatide usaldusjuured. :auth.tls.intermediates: Valija TLS-klientsertifikaatide vahesertifikaadid. TLS-autentimiseks peab nende sertifikaatide abil olema võimalik luua ahel valija klientsertifikaadist usaldusjuureni. :auth.tls.ocsp: Alamblokk, mis sisaldab valija TLS-klientsertifikaatide oleku kontrollimise seadistust. Selle bloki puudumisel valija sertifikaatide kehtivust ei kontrollita välisest kehtivuskinnitusteenusest. :auth.tls.ocsp.url: Valija TLS-klientsertifikaatide kehtivuskinnitusteenuse aadress. Kui pole seadistatud, siis kasutatakse kehtivuskinnitusteenuse aadressi otse TLS-klientsertifikaadist. :auth.tls.ocsp.responders: Valija TLS-klientsertifikaatide kehtivuskinnitusteenuse responderi sertifikaadid. Kui nende hulgast responderi sertifikaati ei leita, siis otsitakse vastuses olevate sertifikaatide hulgast selline, mis on antud välja sama väljastaja poolt, mis kontrollitav sertifikaat, ning on lubatud OCSP vastuste signeerimiseks. :auth.tls.ocsp.retry: Valija TLS-klientsertifikaatide oleku kontrolli korduvkatsete arv. Juhul kui sertifikaadi oleku kontroll ebaõnnestub võrgu- või serverivea tõttu, saab seda automaatselt korrata. Välja väärtus määrab katsete arvu, mis tehakse lisaks algsele päringule. Seega kui väärtus on 1, siis tehakse kokku maksimaalselt kaks päringut. Välja puudumise või väärtuse 0 korral automaatseid korduvkatseid ei sooritata. ---- :identity: Tuvastatud valija X.500 eraldusnimest unikaalse identifikaatori tuletamise meetod. Hetkel toetatud valikud ``commonname``, ``serialnumber`` ja ``pnoee``. Eesti elektrooniliste isikut tõendavate dokumentide korral on ``commonname`` puhul identifikaator kujul "PERENIMI,EESNIMI,ISIKUKOOD" ning teiste valikute teise puhul "ISIKUKOOD". Kui ``serialnumber`` tagastab eraldusnimest ``serialNumber`` välja muutmata kujul, siis ``pnoee`` eemaldab sellelt enne mittekohustusliku "PNOEE-" eesliite. Viimane on vastavuses standardi ETSI EN 319 412-1 jaotisega 5.1.3 Eesti isikukoodide jaoks, kuid lubab ka standardile mittevastavaid seerianumbreid. ---- :age: Alamblokk, mis sisaldab valija vanuse kontrolli seadistust. Kui see blokk puudub, siis valija vanust ei kontrollita. :age.method: Kohustuslik väli. Valija sünniaja tuvastamiseks kasutatav meetod. Hetkel toetatud ainult ``estpic``, mis eeldab, et valija unikaalne identifikaator on Eesti isikukood ning eraldab sealt sünniaja. :age.timezone: Kohustuslik väli. IANA ajavööndi nimi, milles valija vanus arvutatakse ehk millises ajavööndis peab valija olema valimisealine. :age.limit: Kohustuslik väli. Valija peab olema vähemalt nii vana, et hääletada. Kui väärtus on 0, siis valija vanust ei kontrollita. ---- :vote: Kohustuslik väli. Alamblokk, mis sisaldab häälte allkirjade kontrollimise seadistust. :vote.bdoc: Alamblokk, mis sisaldab häälte BDOC-allkirjade kontrollimise seadistust. :vote.bdoc.filecount: Kohustuslik väli. Maksimaalne lubatud failide arv ZIP konteineris, ning kuna tegu on BDOC konteineriga, siis sellele väärtusele tuleb alati liita 3, sest BDOC konteineris on lisaks sisufailidele veel ``signatures0.xml``, ``manifest.xml`` ja ``mimetype`` failid. Antud parameetri väärtuseks sobib 4 (hääl + 3 lisafaili). :vote.bdoc.bdocsize: Kohustuslik väli. BDOC konteineri maksimaalne lubatud suurus baitides. :vote.bdoc.filesize: Kohustuslik väli. BDOC konteineris olevate failide maksimaalne lubatud hõrendatud suurus baitides. :vote.bdoc.roots: Kohustuslik väli. Häälte allkirjastajate sertifikaatide usaldusjuured. :vote.bdoc.intermediates: Häälte allkirjastajate sertifikaatide vahesertifikaadid. Hääle arvesseminekuks peab nende sertifikaatide abil olema võimalik luua ahel allkirjastaja sertifikaadist usaldusjuureni. :vote.bdoc.profile: Kohustuslik väli. Häälte allkirjadelt nõutav BDOC profiil. Toetatud valikud on ``BES`` (põhiprofiil kirjeldatud BDOC spetsifikatsiooni jaotises 5) ja ``TS`` (ajatemplitega profiil kirjeldatud BDOC spetsifikatsiooni jaotises 6.2). See peaks olema ``BES``, kuna kõikide allkirjastamisvahendite puhul ei ole sissetulev hääl kvalifitseeritud (nt Eesti ID-kaart). Kogumisteenus kvalifitseerib häältel olevad allkirjad ise (vt ``qualification``). ---- :mid: Alamblokk, mis sisaldab Mobiil-ID teenusepakkuja seadistust. :mid.url: Kohustuslik väli. Mobiil-ID teenusepakkuja asukoht. :mid.relyingpartyuuid: Kohustuslik väli. Mobiil-ID teenusepakkujaga kokkulepitud kliendi identifikaator. :mid.relyingpartyname: Kohustuslik väli. Mobiil-ID teenusepakkujaga kokkulepitud kliendi nimi. :mid.language: Kohustuslik väli. Mobiil-ID kasutajale kuvatavate sõnumite keel. Võimalikud väärtused ``EST``, ``ENG``, ``RUS`` ja ``LIT``. :mid.authmessage: Kohustuslik väli. Sõnum, mida Mobiil-ID kasutajale kuvada autentimise käigus. :mid.signmessage: Kohustuslik väli. Sõnum, mida Mobiil-ID kasutajale kuvada allkirjastamise käigus. :mid.messageformat: Autentimise ning allkirjastamise käigus kasutajale kuvatava sõnumi vorming. Võimalikud väärtused ``GSM-7`` (Mobiil-ID poolt kasutatav vaikeväärtus) ja ``UCS-2``. :mid.authchallengesize: Autentimise käigus Mobiil-ID teenusele saadetava pretensiooni pikkus. Võimalikud väärtused ``32`` (vaikeväärtus), ``48`` ja ``64``. :mid.statustimeoutms: Parameeter, mis edastatakse autentimise ja allkirjastamise staatuse päringu korral Mobiil-ID teenusele ning millega saab kontrollida, kui kaua ootab Mobiil-ID teenus kasutaja poolse tegevuse lõpptulemust, enne kui vastab, et tegevus on pooleli. Väärtuse puudumisel oodatakse võimalikult vähe: täpne aeg sõltub Mobiil-ID teenusest. Antud parameetri abil saab vähendada ühe autentimise või allkirjastamise käigus Mobiil-ID teenusele saadetavate päringute arvu. :mid.roots: Kohustuslik väli. Mobiil-ID sertifikaatide usaldusjuured. :mid.intermediates: Mobiil-ID sertifikaatide vahesertifikaadid. Mobiil-ID autentimiseks peab nende sertifikaatide abil olema võimalik luua ahel Mobiil-ID sertifikaadist usaldusjuureni. :mid.ocsp: Alamblokk, mis sisaldab valija Mobiil-ID sertifikaatide oleku kontrollimise seadistust. :mid.ocsp.url: Valija Mobiil-ID sertifikaatide kehtivuskinnitusteenuse aadress. Kui pole seadistatud, siis kasutatakse kehtivuskinnitusteenuse aadressi otse Mobiil-ID klientsertifikaadist. :mid.ocsp.responders: Mobiil-ID sertifikaatide OCSP responderi sertifikaadid. Kui nende hulgast responderi sertifikaati ei leita, siis otsitakse vastuses olevate sertifikaatide hulgast selline, mis on antud välja sama väljastaja poolt, mis kontrollitav sertifikaat, ning on lubatud OCSP vastuste signeerimiseks. ---- :smartid: Alamblokk, mis sisaldab Smart-ID teenusepakkuja seadistust. :smartid.url: Kohustuslik väli. Smart-ID teenusepakkuja asukoht. :smartid.relyingpartyuuid: Kohustuslik väli. Smart-ID teenusepakkujaga kokkulepitud kliendi identifikaator. :smartid.relyingpartyname: Kohustuslik väli. Smart-ID teenusepakkujaga kokkulepitud kliendi nimi. :smartid.authinteractionsorder: Kohustuslik väli. Autentimise käigus Smart-ID kasutajale kuvatavate interaktsioonide järjekord. Järjekorrast valitakse esimene interaktsioon, mida rakendus toetab. Võimalikud väärtused: ``displayTextAndPIN`` koos ``displayText60``, ``verificationCodeChoice`` koos ``displayText60``, ``confirmationMessage`` koos ``displayText200`` või ``confirmationMessageAndVerificationCodeChoice`` koos ``displayText200``. :smartid.signinteractionsorder: Kohustuslik väli. Allkirjastamise käigus Smart-ID kasutajale kuvatavate interaktsioonide järjekord. Järjekorrast valitakse esimene interaktsioon, mida rakendus toetab. Võimalikud väärtused: ``displayTextAndPIN`` koos ``displayText60``, ``verificationCodeChoice`` koos ``displayText60``, ``confirmationMessage`` koos ``displayText200`` või ``confirmationMessageAndVerificationCodeChoice`` koos ``displayText200``. :smartid.authchallengesize: Autentimise käigus Smart-ID teenusele saadetava pretensiooni pikkus. Võimalikud väärtused ``32`` (vaikeväärtus), ``48`` ja ``64``. :smartid.statustimeoutms: Autentimise ja allkirjastamise staatuse päringu korral Smart-ID teenusele edastatav parameeter, millega saab kontrollida, kui kaua Smart-ID teenus ootab kasutajapoolse tegevuse lõpptulemust, enne kui vastab, et tegevus on pooleli. Väärtuse puudumisel oodatakse võimalikult vähe: täpne aeg sõltub Smart-ID teenusest. Parameeter aitab vähendada autentimise või allkirjastamise käigus Smart-ID teenusele saadetavate päringute arvu. :smartid.roots: Kohustuslik väli. Smart-ID sertifikaatide usaldusjuured. :smartid.intermediates: Smart-ID sertifikaatide vahesertifikaadid. Smart-ID autentimiseks peab nende sertifikaatide abil olema võimalik luua ahel Smart-ID sertifikaadist usaldusjuureni. :smartid.ocsp: Alamblokk, mis sisaldab valija Smart-ID sertifikaatide oleku kontrollimise seadistust. :smartid.ocsp.url: Valija Smart-ID sertifikaatide kehtivuskinnitusteenuse aadress. Kui pole seadistatud, siis kasutatakse kehtivuskinnitusteenuse aadressi otse Smart-ID klientsertifikaadist. :smartid.ocsp.responders: Smart-ID sertifikaatide OCSP responderi sertifikaadid. Kui nende hulgast responderi sertifikaati ei leita, siis otsitakse vastuses olevate sertifikaatide hulgast selline, mis on 1) välja antud sama väljastaja poolt, mis kontrollitav sertifikaat; ja 2) lubatud OCSP vastuste signeerimiseks. ---- :qualification: Loetelu välistest kvalifitseerivatest päringutest, mis tehakse iga hääle kohta, koos seadistustega. Siin on kasutatud loetelu protokoll ja seadistus blokkidest selle asemel, et anda igale protokollile oma blokk, kuna kvalifitseerivate päringute järjekord on oluline ning seadistatav. :qualification.*.protocol: Kohustuslik väli. Kvalifitseeriva päringu protokoll. Hetkel toetatud ``ocsp`` (harilik OCSP), ``tsp`` (PKIX ajatempel) ja ``tspreg`` (PKIX ajatempel registreerimistõendina). :qualification.*.conf: Kohustuslik väli. Kvalifitseeriva päringu protokolli seadistus. Sisu sõltub ``qualification.*.protocol`` parameetri väärtusest. :qualification.*.conf.url: Valikuline väli ainult ``ocsp`` puhul, sest kui pole seadistatud, kasutatakse kehtivuskinnitusteenuse aadressi otse klientsertifikaadist. Aadress, kuhu kvalifitseeriv päring tehakse. :qualification.*.conf.responders: Kasutatakse ainult juhul kui ``qualification.*.protocol`` on ``ocsp``. OCSP responderi sertifikaadid. Kui nende hulgast responderi sertifikaati ei leita, siis otsitakse vastuses olevate sertifikaatide hulgast selline, mis on antud välja sama väljastaja poolt, mis kontrollitav sertifikaat, ning on lubatud OCSP vastuste signeerimiseks. AIA loogika kasutamise korral võib väli jääda tühjaks. :qualification.*.conf.signers: Kohustuslik väli. Kasutatakse ainult juhul kui ``qualification.*.protocol`` on ``tsp`` või ``tspreg``. Ajatempliteenuse vastuse allkirjastamise sertifikaadid. :qualification.*.conf.delaytime: Kohustuslik väli. Kasutatakse ainult juhul kui ``qualification.*.protocol`` on ``tsp`` või ``tspreg``. Maksimaalne ajanihe ajatempli loomise ja allkirjastamise vahel sekundites. :qualification.*.conf.retry: Kvalifitseeriva päringu korduvkatsete arv. Juhul kui päring ebaõnnestub võrgu- või serverivea tõttu, saab seda automaatselt korrata. Välja väärtus määrab katsete arvu, mis tehakse lisaks algsele päringule. Seega kui väärtus on 1, siis tehakse kokku maksimaalselt kaks päringut. Välja puudumise või väärtuse 0 korral automaatseid korduvkatseid ei sooritata. Näide ***** :file:`example.election.yaml`: .. literalinclude:: config-examples/example.election.yaml :language: yaml :linenos: .. vim:syntax=rst: ================================================ FILE: Documentation/et/seadistuste_koostejuhend/kt-volitused.inc ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus .. _kt-management: Kogumisteenuse volituste kirjeldamine ------------------------------------- Kasutajatele volituste määramine käib süsteemis kirjeldatud rollide kaudu. Igale rollile on määratud komplekt õigusi ja kasutajal on kõik volitused, mis talle seotud rollide kaudu on määratud. Volituste määramise korraldus määrab ühele kasutajale tema rollid süsteemis. Volitused koostatakse JSON-vormingus failina, millega määratakse: #. Korralduse sisu (``action=user-permissions``); #. Volitatud kasutaja *Common Name* väli tema ID-kaardilt (väli ``cn``); #. Kasutaja rollide nimekiri komadega eraldatud nimekirjana (väli ``roles``). Faili vorming: .. code-block:: JavaScript { "action": "user-permissions", "cn": ", "roles": "roll1[,roll2]" } .. _rollid: Rollid ****** Kogumisteenuses on järgnevad rollid: #. **Kogumisteenuse haldur** (``admin``) on ette nähtud kogumisteenuse tehniliseks haldamiseks; #. **Valimiste haldur** (``election-conf-manager``) on ette nähtud valimiste seadistuste kehtestamiseks; #. **Vaataja** (``viewer``) on ette nähtud haldusteenuse kaudu väljastatavate andmete vaatamiseks; #. **Õigusteta kasutaja** (``none``). See roll on ette nähtud kasutajakonto kirje hoidmiseks olukorras, kus kasutajale pole ühtegi teist rolli määratud (näiteks pärast lisamist või pärast kõigist teistest rollidest eemaldamist). .. list-table:: Rollide ja volituste maatriks :header-rows: 1 * - - ``admin`` - ``election-`` ``conf-`` ``manager`` - ``viewer`` - ``none`` * - Üldseisundi ja statistika vaatamine - ✓ - ✓ - ✓ - `-` * - Valimiste seadistuste rakendamine - ✓ - ✓ - `-` - `-` * - E-valimiskasti allalaadimine - ✓ - ✓ - `-` - `-` * - Kasutajate haldus - ✓ - `-` - `-` - `-` * - Tehnilise seadistuse rakendamine - ✓ - `-` - `-` - `-` * - Logide vaatamine - ✓ - `-` - `-` - `-` Volituste reeglid ***************** * Kasutaja võib olla mitmes rollis korraga; * Roll annab kasutajale rolliga seotud õigused, ükski roll õigusi ära ei võta. .. vim:syntax=rst: ================================================ FILE: Documentation/et/seadistuste_koostejuhend/kt-ylevaade.inc ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus Ülevaade -------- Kogumisteenuse juhtimine toimub signeeritud korralduste abil. Korraldused koostatakse operaatori poolt tekstiredaktori abil või imporditakse Valimiste Infosüsteemist. Korraldused signeeritakse ID-kaardiga. Nimekiri kogumisteenuse haldamise korraldustest: #. Usaldusjuure seadistus; #. Tehniline seadistus; #. Valimiste seadistus; #. Valikute nimekiri; #. Ringkondade nimekiri; #. Valijate nimekiri; #. Valijate nimekirja vahelejätmine; #. Kasutajate volituste määramine. Lisaks korraldustele tuleb kogumisteenusele genereerida ka komplekt krüptovõtmeid. Korralduste vorming ******************* Kogumisteenuse korralduste vorming on enamasti YAML või JSON, valijate nimekirja puhul kasutatakse spetsiifilist vormingut. YAML-vormingus korraldused: #. Usaldusjuure seadistus; #. Tehniline seadistus; #. Valimiste seadistus. JSON-vormingus korraldused: #. Valikute nimekiri; #. Kasutajate volituste määramine. Kohandatud vormingus korraldused: #. Valijate nimekiri. YAML-vormingus korraldused ~~~~~~~~~~~~~~~~~~~~~~~~~~ YAML-vormingus seadistustesse on võimalik kaasata väliseid faile. Selleks kasutatakse silti ``!container``. Näide: .. code-block:: yaml # välja "ext_file" väärtus loetakse failist "certificate-file.pem" ext_file: !container certificate-file.pem .. caution:: Väliste failide kaasamisel tuleb arvestada sellega, et seadistused laaditakse süsteemi BDOC-vormingus konteinerites (vt. lõiku :ref:`korralduspaki-vorming`). See seab väliste failide kaasamisele järgmised nõuded: * Kasutatavad välised failid peavad olema pakendatud seadistusfailiga samasse konteinerisse; * Välised failid peavad asuma seadistusfailiga samas kataloogis. .. _korralduspaki-vorming: Korralduspaki vorming ********************* Korralduspakk on BDOC-vormingus konteiner, milles on korraldusfail ja signatuurid. Üks korralduspakk tohib sisaldada ainult ühte korraldust. YAML-vormingus seadistuse (usaldusjuure seadistus, tehniline seadistus ja valimiste seadistus) korral võivad failis olla ka seadistusfaili poolt kasutatavad välised failid. .. vim:syntax=rst: ================================================ FILE: Documentation/et/seadistuste_koostejuhend/mixnet.rst ================================================ .. IVXV juhend Verificatumi miksneti ettevalmistamiseks ning kasutamiseks E-häälte miksimine ==================================================== .. _mix-install: Miksneti Verificatum paigaldamine --------------------------------- Eeldused ^^^^^^^^ Juhend on kasutamiseks distributsiooniga Ubuntu 20.04 LTS (Bionic Beaver) ja see eeldab, et käske käivitatakse lihtkasutaja õigustest, kellel on õigus privileegide eskaleerimiseks `sudo` käsu abil. Lisaks on eeldatud järgmiste failide olemasolu kasutaja kodukaustas: Github repositooriumist (https://github.com/vvk-ehk/intcheck): * :file:`intcheck.py` - tööriist kataloogide täielikkuse kontrolliks IVXV tarnefailist: * :file:`gmpmee.dirsha256sum` - ``gmpmee`` kataloogi räsi; * :file:`vmgj.dirsha256sum` - ``vmgj`` kataloogi räsi; * :file:`vcr.dirsha256sum` - ``vcr`` kataloogi räsi; * :file:`vmn.dirsha256sum` - ``vmn`` kataloogi räsi; * :file:`ivxv-verificatum-1.10.3-runner.zip` - IVXV adapter Verificatumi kasutamiseks. Valimise korraldaja käest: * :file:`data/bb-4.json` - anonüümitud e-valimiskast; * :file:`data/pub.pem` - häälte krüpteerimiseks kasutatud võti. Kataloogis :file:`data/` ei tohi olla ühtegi teist faili. Pärast protsessi lõppu on kataloogis :file:`data/` vajalikud järgnevad failid: * :file:`shuffled.json` - miksitud e-valimiskast; * :file:`proof.zip` - korrektse miksimise tõend. Verificatumi ehitamine ^^^^^^^^^^^^^^^^^^^^^^ Ehitamiseks vajalike pakkide paigaldamine:: sudo apt-get install --no-install-recommends -y autoconf autoconf automake \ build-essential libgmp-dev libtool git openjdk-11-jdk-headless \ python unzip wget Verificatumi lähtekoodi allalaadimine:: git clone https://github.com/verificatum/verificatum-gmpmee gmpmee git clone https://github.com/verificatum/vmgj git clone https://github.com/verificatum/vcr git clone https://github.com/verificatum/vmn Lähtekoodist puhaste arhiivide loomine täielikkuse kontrolliks:: cd gmpmee git checkout 4aafc31 rm -rf .git/ cd ../vmgj git checkout 8d7d412 rm -rf .git/ cd ../vcr git checkout af9fd82 rm -rf .git/ cd ../vmn git checkout bb00543 rm -rf .git/ cd .. Verificatumi lähtekoodi täielikkuse kontrollimine:: chmod +x ./intcheck.py ./intcheck.py verify gmpmee gmpmee.dirsha256sum ./intcheck.py verify vmgj vmgj.dirsha256sum ./intcheck.py verify vcr vcr.dirsha256sum ./intcheck.py verify vmn vmn.dirsha256sum `gmpmee` ehitamine:: cd gmpmee/ make -f Makefile.build ./configure make sudo make install `vmgj` ehitamine:: cd ../vmgj/ make -f Makefile.build ./configure make sudo make install `vcr` ehitamine:: cd ../vcr/ make -f Makefile.build ./configure --enable-vmgj make sudo make install `vmn` ehitamine:: cd ../vmn/ make -f Makefile.build ./configure make sudo make install IVXV Verificatumi adapteri ja käivitusskripti lahtipakkimine:: cd .. unzip ivxv-verificatum-1.10.3-runner.zip Verificatumi teekide kopeerimine adapteri väliste teekide kataloogi:: cp /usr/local/share/java/verificatum-vmgj-1.2.2.jar mixer/lib/verificatum-vmgj.jar cp /usr/local/share/java/verificatum-vcr-vmgj-3.0.4.jar mixer/lib/verificatum-vcr-vmgj.jar cp /usr/local/share/java/verificatum-vmn-3.0.4.jar mixer/lib/verificatum-vmn.jar cp /usr/local/lib/libgmpmee.so.0.0.0 mixer/lib/libgmpmee.so.0 cp /usr/local/lib/libvmgj-1.2.2.so mixer/lib/libvmgj-1.2.2.so .. _mix-mix: E-häälte miksimine ---------------------------------------- Verificatumi miksneti käivitamine:: cd data ../mixer/bin/mix.py --pubkey pub.pem --ballotbox bb-4.json \ --shuffled shuffled.json --proof-zipfile proof.zip shuffle Verificatumi miksneti käivitamine koos entroopiaallika eelneva tühjendamisega:: cd data ../mixer/bin/mix.py --pubkey pub.pem --ballotbox bb-4.json \ --shuffled shuffled.json --proof-zipfile proof.zip --empty-entropy-pool \ shuffle .. _mix-verify: Miksimistõendi verifitseerimine ------------------------------- Verificatumi adapteri abil saab miksimistõendit ka verifitseerida:: cd .. mkdir verify cp data/proof.zip verify cd verify ../mixer/bin/mix.py verify --proof-zipfile proof.zip ================================================ FILE: Documentation/et/seadistuste_koostejuhend/rakendused.rst ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus .. _ivxv-rakendused: IVXV rakendused =============== .. _app-install: Rakenduste paigaldamine -------------------------------------------------------------------------------- IVXV rakendused on: * võtmerakendus `key` (:numref:`app-key`), * töötlemisrakendus `processor` (:numref:`app-processor`), * auditirakendus `auditor` (:numref:`app-auditor`). IVXV rakendused on arendatud programmeerimiskeeles Java, kasutusel on Java 21. Rakendused on testitud Windows 11 ja Ubuntu 22.04 platvormil kasutades OpenJDK'd või Oracle Javat. Rakendused tarnitakse ZIP-vormingus failidena:: -.zip Peale ZIP-faili lahti pakkimist tekib kataloogipuu:: - |-- bin | |-- | |-- |-- lib | |-- *.jar Kui kataloogitee `-/bin` panna keskkonnamuutujasse `PATH`, saab rakendust edaspidi käivitada käsurealt:: $ Rakendusi paigaldades tuleb arvestada, et kesksüsteemi protokollides kirjeldatud raportid kasutavad ilma ajavööndita aja vormingut (`yyyymmddhhmmss`). Ajavööndiga ajamärgendi (näiteks hääletamise aeg kogumisteenuselt saadud e-valimiskastis) esitamiseks raportis teisendavad Java rakendused ajamärgendi esmalt operatsioonisüsteemi ajavööndisse ning seejärel eemaldavad ajavööndi info. Seetõttu tuleb rakendusi käivitavates masinates seadistada ajavöönd selliseks, millise kohalikus ajas soovitakse ajamärgendeid näha. .. _app-trust: Rakenduste usaldusjuure kirjeldamine ------------------------------------ Rakenduste kasutamine eeldab digitaalselt allkirjastatud seadistuste kasutamist. Allkirjade verifitseerimiseks vajalikud sertifikaadid tuleb rakendusele ette anda usaldusjuure koosseisus. Usaldusjuur on samuti digitaalselt allkirjastatud. Usaldusjuure seadistuse koostab valimiste korraldaja. :ca: Komadega eraldatud loetelu konteineris sisalduvatest CA sertifikaatidest ja vahesertifikaatidest. :ocsp: Komadega eraldatud loetelu konteineris sisalduvatest OCSP sertifikaatidest. :tsa: Komadega eraldatud loetelu konteineris sisalduvatest ATO sertifikaatidest. Kõik sertifikaadid antakse PEM vormingus. Rakendusele esitatakse usaldusjuur BDOC konteineris, kus usaldusjuure spetsifikatsioon on kirjeldatud failis `ivxv.properties` ning kõik juure elemendid on konteinerisse laaditud. Näide ***** :file:`ivxv.properties`: .. literalinclude:: config-examples/ivxv.properties.real :linenos: Rakenduste käivitamine -------------------------------------------- Rakendusi käivitatakse käsurealt, nende toimimist juhitakse käsureaparameetrite ja digitaalselt allkirjastatud seadistustega. Kõik rakendused väljastavad vajadusel abiinfot:: $ --help Rakendus 'rakendus' - Rakendus Kasutamine: --conf [--params ] [--force ] [--quiet ] [--lang ] [--container_threads ] [--threads ] -h | --help -h | --help Tööriistad: tool_foo - Tegevuse FOO teostamine tool_bar - Tegevuse BAR teostamine Käsurea argumendid: -h --help - Abi -c --conf (*) - Konfiguratsioon -p --params - Tööriista parameetrid -f --force - Ära küsi kasutajalt kinnitust -q --quiet - Vaikne käivitusrežiim --lang - Keel -ct --container_threads - Allkirjastatud konteinerite teegi poolt kasutatav lõimede arv (<= 0 korral dünaamiline) -t --threads - Rakenduse poolt paralleeltöötluse korral kasutatav lõimede arv (<= 0 korral dünaamiline) Rakendus lõpetas töö ilma vigadeta Rakenduste kasutamisel tuleb määrata konkreetne tööriist, usaldusjuur ning seadistusfail:: $ tool_foo --conf usaldusjuur.asice --params tool_foo.conf.asice Konfiguratsiooni laadimine failist usaldusjuur.asice Konfiguratsiooni allkirja kontrollimine Konfiguratsiooni allkirja on andnud NIMI NIMESTE Konfiguratsiooni allkirja andmise aeg on 24.12.2018 18:00 Konfiguratsiooni allkiri on korrektne ja kehtiv FOO! Rakendus lõpetas töö ilma vigadeta Juhised rakenduste tööriistade ning nende seadistusfailide koostamise kohta antakse järgmistes peatükkides. Käsureaargumendid on kõigil rakendustel samad: :-h --help: Abiinfo kuvamine kas rakenduse või konkreetse tööriista kohta. :-c --conf (*): Digitaalselt allkirjastatud fail usaldusjuurega. Kohustuslik parameeter. :-p --params: Digitaalselt allkirjastatud tööriista parameetrid. :-f --force: Ära küsi kasutajalt kinnitust. :-q --quiet: Vaikne käivitusrežiim. :--lang: Juhul kui rakendus on kompileeritud mitmekeelsena, siis keele valik. Vaikimisi on rakendustes võimaldatud ainult eesti keel. :-ct --container_threads: Allkirjastatud konteinerite teegi poolt kasutatav lõimede arv. Vaikimisi valitakse lõimede arv teegi poolt dünaamiliselt lähtudes saadaolevate tuumade arvust. :-t --threads: Rakenduse poolt paralleeltöötluse korral kasutatav lõimede arv. Vaikimisi valitakse lõimede arv rakenduse poolt dünaamiliselt lähtudes saadaolevate tuumade arvust. Rakendustest eksisteerivad nii tooteversioonid kui testversioonid. Testrakendused on kohaldatud protseduuride efektiivseks testimiseks, kuid ei sobi valimiste tegelikuks läbiviimiseks. Näiteks ei võimalda võtmerakenduse testversioon kasutada kiipkaarte. Testversioonid rakendustest kuvavad käivitamisel hoiatuse:: ******************************************************************** * !!! HOIATUS !!! * * * * Rakendus on käivitatud arendusrežiimis ning rakenduse käitumine * * võib erineda tavarežiimist. * * Rakenduse käivitamiseks tavarežiimis tuleb rakendus ümber * * kompileerida. * ******************************************************************** Rakenduste käivituskeskkonna parameetrid ---------------------------------------- Suure e-valimiskasti auditeerimisel, töötlemisel või dekrüpteerimisel, võib olla tarvilik suurendada protsessi mälupiirangut. Seda saab teha kasutades rakendusespetsiifilist keskkonnamuutujat ``{RAKENDUS}_OPTS``, mis defineerib täiendavad argumendid Java virtuaalmasinale. ``{RAKENDUS}`` on üks kolmest ``AUDITOR``, ``KEY`` või ``PROCESSOR``. Protsessi mälupiirangu suurendamiseks tuleb kasutada argumenti ``-Xmx{N}G``, kus ``{N}`` on mälupiirangu suurus gigabaitides. Näiteks 10 gigabaidi mälu eraldamiseks töötlemisrakendusele tuleb seada ``PROCESSOR_OPTS=-Xmx10G``. .. list-table:: Rakenduste mälupiirangu parameetrid :header-rows: 1 * - Rakendus - Vaikimisi mälupiirang - Keskkonnamuutuja * - Auditirakendus - 8GB - ``AUDITOR_OPTS`` * - Töötlemisrakendus - 8GB - ``PROCESSOR_OPTS`` * - Võtmerakendus - Puudub - ``KEY_OPTS`` Rakendused töötavad nii 32-bitise kui 64-bitise Java andmemudeliga, samas efektiivseimaks toimimiseks tuleb rakendusi kasutada 64-bitisel platvormil 64-bitise Java andmemudeliga. Juhul kui rakendus ei suuda käivitamisel 64-bitist mudelit tuvastada kuvatakse hoiatus:: ******************************************************************** * !!! HOIATUS !!! * * * * 64-bitise Java andmemudeli tuvastamine ebaõnnestus. Rakendus on * * vähemefektiivsem. Rakenduse jõudluse suurendamiseks tuleb * * kasutada 64-bitise andmemudeliga Java keskkonda. * ******************************************************************** Juhul kui rakenduse mälupiirang on 4GB või rohkem, ei ole 32-bitise andmemudeliga Java võimeline rakendust käivitama. Kuvatakse järgmine veateade:: Invalid maximum heap size: -Xmx4G The specified size exceeds the maximum representable size. Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit. ================================================ FILE: Documentation/et/seadistuste_koostejuhend/spelling_wordlist.txt ================================================ Beaver Bionic Github iOS Javat Oracle Ubuntu hosti hostinimedest hostinimi etcd xml CSV IP PDF URL Bertoni Daemen Peeters Van Assche Sponge Based Pseudo Random Number Generators Kivinen Kojo More Modular Exponential Diffie Hellman groups for Internet Key Exchange Desmedt ================================================ FILE: Documentation/et/seadistuste_koostejuhend/tootlemisrakendus.rst ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus .. _app-processor: Töötlemisrakendus ================= Töötlemisrakendus on käsurearakendus e-valimiskasti kontrollimiseks ja edasiseks töötlemiseks peale e-hääletamise lõppu. Töötlemisrakenduse põhilised tööriistad on *check*, *squash*, *revoke* ja *anonymize*, mis käivitatakse loetletud järjekorras vastavalt ette nähtud valimisprotseduuridele. Põhitööriistade sisendi hulgas on alati kas kogumisteenuse või eelmise tööriista poolt väljastatud e-valimiskast ja e-valimiskasti digitaalselt allkirjastatud räsi. Väljundi hulgas on töötlemisetapi tulemuseks olev e-valimiskast koos allkirjastamata räsiga. Kuna rakendused käivitatakse internetiühenduseta arvutis, tuleb räsifailid tõsta digitaalseks allkirjastamiseks välisesse seadmesse. E-valimiskasti räsi arvutatakse funktsiooniga ``hex(sha256())``. Lisaks põhitööriistadele on rakendusel veel neli täiendavat tööriista: *export*, *verify*, *stats* ja *statsdiff*. Kõigi tööriistade kasutamine eeldab allkirjastatud usaldusjuure ja konkreetse tööriista seadistuste olemasolu. Faile väljastavatel tööriistadel tuleb seadistustes määrata väljundkausta asukoht. Väljundkausta ei tohi käivitamise ajal olemas olla, selle loob rakendus. Alljärgnevalt on kirjeldatud tööriistade seadistusi. .. _processor-check: E-valimiskasti töötlemine - verifitseerimine -------------------------------------------- Kogumisteenusest väljastatud e-valimiskasti verifitseerimiseks kasutatakse tööriista *check*. valimiskasti verifitseeritakse usaldusjuure, valijate nimekirjade, ringkondade nimekirja ja registreerimisteenuse väljundi vastu. Verifitseerimise käigus kontrollitakse järgmiseid põhilisi omadusi: * Ringkondade nimekirja ja valijate nimekirjade andmeterviklus ja kooskõlalisus; * E-valimiskasti andmeterviklus; * E-hääletajate valimisõigus e. kuuluvus valijate nimekirja (kontrollitakse juhul kui valijate nimekirjad on seadistustes kirjeldatud); * E-valimiskastis sisalduvate häälte vastavus digiallkirja vormingule; * Registreerimisandmete andmeterviklus; * E-valimiskastis sisalduvate häälte vastavus registreerimisandmetega. E-valimiskasti verifitseerimine on töömahukas protsess. 4-tuumalise *i7* protsessoriga arvuti suudab ühe sekundi jooksul töödelda umbes 200 häält. Töötlemise jooksul kuvatakse kasutajale edenemisriba, mille alusel on võimalik ennustada töötlemisele kuluvat aega. :check.ballotbox: Kogumisteenusest väljastatud e-valimiskast. :check.ballotbox_checksum: Kogumisteenusest väljastatud e-valimiskasti digitaalselt allkirjastatud räsi. Kui määramata, siis ei väljastata korrastatud e-valimiskasti järgmisteks etappideks. Kasulik mitte-lõpliku e-valimiskasti valimisaegseks kontrolliks. :check.signed_ballot_max_size_bytes: Kogumisteenusest väljastatud e-valimiskasti üksiku allkirjastatud hääle maksimaalne lubatud pikkus baitides. Kui määramata, siis vaikimisi kasutatakse 32768 baiti. :check.districts: Digitaalselt allkirjastatud ringkondade nimekiri. :check.registrationlist: Registreerimisteenusest pärit registreerimisandmed. Kui määramata, siis ei kontrollita e-valimiskastis sisalduvate häälte vastavust registreerimisandmetega. :check.registrationlist_checksum: Registreerimisandmete digitaalselt allkirjastatud räsi. Võib puududa, kui ``registrationlist`` puudub. :check.tskey: Registreerimispäringute verifitseerimiseks kasutatav kogumisteenuse avalik võti registreerimispäringute tegemise sertifikaadist. :check.vlkey: Valijate nimekirjade verifitseerimiseks kasutatav avalik võti. Argument on kohustuslik, kui valijate nimekirjad on antud. :check.voterlists_dir: Valijate nimekirjade loendi kaust. Kui on määramata, siis e-hääletanute hääleõigust ei kontrollita. :check.voterlists: Valijate nimekirjade loend. Kui on määramata, siis e-hääletanute hääleõigust ei kontrollita. :check.voterlists.path: Valijate nimekirja fail. :check.voterlists.signature: Valijate nimekirja allkiri, mis on antud algoritmiga ``ecdsa-with-SHA256``. :check.districts_mapping: Valijate nimekirjas oleva ringkonna ja jaoskonna teisendusfail (valikuline). :check.election_start: Hääletamise algusaeg. Sellest varasema hääletusajaga hääli käsitletakse proovihäältena ning need lugemisele ei lähe. :check.voterforeignehak: Alaliselt välisriigis elavate valijate ringkonnakuuluvuse tuvastamiseks kasutatav EHAK-kood. Vaikeväärtus "0000". :check.out: Tööriista väljundkaust. Sellesse kausta tekivad: #. Tervikluskontrolliga korrastatud e-valimiskast :file:`-bb-1.json`; #. Tervikluskontrolliga korrastatud e-valimiskasti räsi :file:`-bb-1.json.sha256sum`; #. E-valimiskasti töötlemisvigade raport :file:`ballotbox_errors.txt`; #. Valijate nimekirjade töötlemisvigade raport :file:`voterlist_errors.txt`; #. *Log1* fail ehk vastuvõetud hääled :file:`..check.log1`. :file:`processor.check.yaml`: .. literalinclude:: config-examples/processor.check.yaml :language: yaml :linenos: .. _processor-squash: E-valimiskasti töötlemine - korduvhäälte tühistamine ---------------------------------------------------- Korduvate e-häälte tühistamiseks kasutatakse tööriista *squash*. Tööriista sisendiks on tööriista *check* poolt koostatud e-valimiskast. Korduvhäälte tühistamisel jäetakse alles iga hääletaja kõige hilisema hääl ja eemaldatakse kõik varasemad hääled. :squash.ballotbox: Tervikluskontrolliga korrastatud e-valimiskast. :squash.ballotbox_checksum: Tervikluskontrolliga korrastatud e-valimiskasti digitaalselt allkirjastatud räsi. :squash.districts: Digitaalselt allkirjastatud ringkondade nimekiri. :squash.enckey: Krüpteerimise avaliku võtme faili asukoht (võtmerakenduse väljund). Võtit kasutatakse krüpteeritud häälte eelkontrolliks, eristamaks päriselt krüpteeritud hääli suvalisest binaarsest prügist. :squash.out: Tööriista väljundkaust. Sellesse kausta luuakse: #. Korduvhäältest puhastatud e-valimiskast :file:`-bb-2.json`; #. Korduvhäältest puhastatud e-valimiskasti räsi :file:`-bb-2.json.sha256sum`; #. E-hääletanute nimekiri JSON-vormingus :file:`-ivoterlist.json`; #. E-hääletanute nimekiri PDF-vormingus :file:`-ivoterlist.pdf`; #. Tühistamiste ja ennistamiste aruanne :file:`-revocation-report.csv`; #. Tühistamiste ja ennistamiste aruanne ilma isikuandmeteta :file:`-revocation-report.csv.anonymous`; #. *Log2* fail ehk tühistatud hääled :file:`..squash.log2`. :file:`processor.squash.yaml`: .. literalinclude:: config-examples/processor.squash.yaml :language: yaml :linenos: .. _processor-revoke: E-valimiskasti töötlemine - häälte tühistamine ja ennistamine jaoskonnainfo põhjal ---------------------------------------------------------------------------------- Häälte tühistamiseks ja ennistamiseks jaoskonnainfo põhjal kasutatakse tööriista *revoke*. Tööriist saab sisendiks tööriista *squash* poolt koostatud e-valimiskasti ning rakendab sellele sisendiks antud tühistus- ja ennistusnimekirjad. :revoke.ballotbox: Korduvhäältest puhastatud e-valimiskast. :revoke.ballotbox_checksum: Korduvhäältest puhastatud e-valimiskasti digitaalselt allkirjastatud räsi. :revoke.districts: Digitaalselt allkirjastatud ringkondade nimekiri. :revoke.revocationlists: Tühistus- ja ennistusnimekirjade loend. Võib olla tühi. :revoke.out: Tööriista väljundkaust. Sellesse kausta tekivad: #. Korduvhääletajate häältest puhastatud e-valimiskast :file:`-bb-3.json`; #. Korduvhääletajate häältest puhastatud e-valimiskasti räsi :file:`-bb-3.json.sha256sum`; #. Tühistamiste ja ennistamiste aruanne :file:`-revocation-report.csv`; #. Tühistamiste ja ennistamiste aruanne ilma isikuandmeteta :file:`-revocation-report.csv.anonymous`; #. E-hääletanute nimekiri JSON-vormingus :file:`-ivoterlist.json``; #. *Log2* fail e. tühistatud hääled :file:`..revoke.log2`. :file:`processor.revoke.yaml`: .. literalinclude:: config-examples/processor.revoke.yaml :language: yaml :linenos: .. _processor-anonymize: E-valimiskasti töötlemine - anonüümimine ---------------------------------------- E-valimiskasti anonüümimiseks kasutatakse tööriista *anonymize*. Tööriist saab sisendiks tööriista *revoke* poolt koostatud e-valimiskasti ning eemaldab sellest valijate info. :anonymize.ballotbox: Korduvhääletajate häältest puhastatud e-valimiskast. :anonymize.ballotbox_checksum: Korduvhääletajate häältest puhastatud e-valimiskasti digitaalselt allkirjastatud räsi. :anonymize.out: Tööriista väljundkaust. Sellesse kausta luuakse: #. Hääletajate isikuandmetest puhastatud e-valimiskast :file:`-bb-4.json`; #. Hääletajate isikuandmetest puhastatud e-valimiskasti räsi :file:`-bb-4.json.sha256sum`; #. *Log3* fail e. lugemisele läinud hääled :file:`..anonymize.log3`. :file:`processor.anonymize.yaml`: .. literalinclude:: config-examples/processor.anonymize.yaml :language: yaml :linenos: Töötlemisrakenduse täiendavad tööriistad ---------------------------------------- Tööriist *verify* ***************** *Verify* on lisavahend, millega saab verifitseerida digitaalselt allkirjastatud konteineri allkirja ning kuvada konteineri andmed. :verify.file: Verifitseeritav fail. :file:`processor.verify.yaml`: .. literalinclude:: config-examples/processor.verify.yaml :language: yaml :linenos: Tööriist *export* ***************** *Export* on lisavahend, millega saab eksportida kogumisteenusest väljastatud e-valimiskasti seest täielikke digitaalselt allkirjastatud hääle konteinereid. On võimalik eksportida nii kõiki hääli korraga, kui konkreetse valija hääli. :export.ballotbox: Kogumisteenusest väljastatud e-valimiskast. :export.ballotbox_checksum: Kogumisteenusest väljastatud e-valimiskasti digitaalselt allkirjastatud räsi. :export.signed_ballot_max_size_bytes: Kogumisteenusest väljastatud e-valimiskasti üksiku allkirjastatud hääle maksimaalne lubatud pikkus baitides. Kui määramata, siis vaikimisi kasutatakse 32768 baiti. :export.voter_id: Valija identifikaator (valikuline). :export.out: Tööriista väljundkaust. Sellesse kausta tekivad: #. E-valimiskasti töötlemisvigade raport :file:`ballotbox_errors.txt` (valikuline); #. E-valimiskastist eksporditud häälte digitaalselt allkirjastatud konteinerid. :file:`processor.export.yaml`: .. literalinclude:: config-examples/processor.export.yaml :language: yaml :linenos: Tööriist *stats* **************** *Stats* on lisavahend, millega saab arvutada häälte ja hääletajate statistikat e-valimiskasti põhjal. Statistikat on võimalik piiritleda ajavahemikuga ning väljundit on võimalik piiritleda koondandmetega kui ka ringkondade kaupa. NB! Tööriist ei kontrolli digitaalallkirju, häälte töötlemiseks tuleb kasutada *check*, *squash*, *revoke*, *anonymize* töövoogu. :stats.ballotbox: E-valimiskast, mille põhjal statistika koostada. Kui faili laiendiks on ``.json``, siis peab see olema olema töödeldud e-valimiskast. Vastasel juhul peab see olema kogumisteenusest väljastatud e-valimiskast. :stats.signed_ballot_max_size_bytes: Kogumisteenusest väljastatud e-valimiskasti üksiku allkirjastatud hääle maksimaalne lubatud pikkus baitides. Kui määramata, siis vaikimisi kasutatakse 32768 baiti. :stats.election_day: Valimispäev. Kõikide e-hääletanute vanused arvutatakse statistika tarbeks selle kuupäeva suhtes. :stats.period_start: Statistikaperioodi algusaeg (valikuline). Sellest varasema hääletusajaga hääli statistikasse ei kaasata. :stats.period_end: Statistikaperioodi lõppaeg (valikuline). Sellest hilisema hääletusajaga hääli statistikasse ei kaasata. :stats.districts: Digitaalselt allkirjastatud ringkondade nimekiri. Vajalik ringkondade kaupa statistika väljastamiseks. Kui on määramata, siis väljastatakse ainult koondstatistika. :stats.vlkey: Valijate nimekirjade verifitseerimiseks kasutatav avalik võti. Argument on kohustuslik valijate nimekirjade kasutamise korral. :stats.voterlists: Valijate nimekirjade loend. Vajalik kogumisteenusest väljastatud e-valimiskastist valija ringkonna tuvastamiseks. Argument on kohustuslik, kui e-valimiskast on väljastatud kogumisteenusest ja statistikat väljastatakse ringkondade kaupa. :stats.voterlists.path: Valijate nimekirja fail. :stats.voterlists.signature: Valijate nimekirja allkiri, mis on antud algoritmiga ``ecdsa-with-SHA256``. :check.voterforeignehak: Alaliselt välisriigis elavate valijate ringkonnakuuluvuse tuvastamiseks kasutatav EHAK-kood. Vaikeväärtus "0000". :stats.out: Tööriista väljundkaust. Sellesse kausta tekivad: #. E-valimiskasti statistika JSON-vormingus :file:`-stats.json` (:file:`ELECTION-stats.json` kui valimist ei suudeta tuvastada); #. E-valimiskasti statistika CSV-vormingus :file:`-stats.csv` (:file:`ELECTION-stats.csv` kui valimist ei suudeta tuvastada); #. E-valimiskasti töötlemisvigade raport :file:`ballotbox_errors.txt` (tekib vigade korral); #. Valijate nimekirjade töötlemisvigade raport :file:`voterlist_errors.txt` (tekib vigade korral). :file:`processor.stats.yaml`: .. literalinclude:: config-examples/processor.stats.yaml :language: yaml :linenos: Tööriist *statsdiff* ******************** *Statsdiff* on lisavahend, millega saab arvutada kahe statistikafaili vahet. Tulemuseks on kolmas statistikafail, mille kõik väärtused on pärit alusfailist, kust on lahutatud võrreldava faili väärtused. :statsdiff.compare: Statistika võrdluse alusfail JSON-vormingus. :statsdiff.to: Võrreldav statistika fail JSON-vormingus. Võrreldav statistika fail on pärit IVXV logimonitorist. Selleks et kasutada *statsdiff* utiliidi tuleb antud failist eemaldada **time:** ja **meta:** JSON kirjed. Need kirjed ei oma tähtsust statistika võrdlemisel ja on lihtsalt statistika faili genereerimise ajatempel, mis on alati erinev **statsdiff.compare** ja **statsdiff.to** failides. :statsdiff.diff: Tööriista väljundfail. Sellesse faili salvestatakse statistikate vahe JSON-vormingus. :file:`processor.statsdiff.yaml`: .. literalinclude:: config-examples/processor.statsdiff.yaml :language: yaml :linenos: .. _processor-checkAndSquash: E-valimiskasti töötlemine - verifitseerimine ja korduvhäälte tühistamine ------------------------------------------------------------------------ Antud tööriist teostab nii verifitseerimist, kui ka korduvhäälte tühistamist. Rohkem infot teostavate operatsioonide kohta leidub alapeatükkides: * *E-valimiskasti töötlemine - verifitseerimine* * *E-valimiskasti töötlemine - korduvhäälte tühistamine* :checkAndSquash.ballotbox: Kogumisteenusest väljastatud e-valimiskast. :checkAndSquash.ballotbox_checksum: Kogumisteenusest väljastatud e-valimiskasti digitaalselt allkirjastatud räsi. Kui määramata, siis ei väljastata korrastatud e-valimiskasti järgmisteks etappideks. Kasulik mitte-lõpliku e-valimiskasti valimisaegseks kontrolliks. :checkAndSquash.signed_ballot_max_size_bytes: Kogumisteenusest väljastatud e-valimiskasti üksiku allkirjastatud hääle maksimaalne lubatud pikkus baitides. Kui määramata, siis vaikimisi kasutatakse 32768 baiti. :checkAndSquash.districts: Digitaalselt allkirjastatud ringkondade nimekiri. :checkAndSquash.registrationlist: Registreerimisteenusest pärit registreerimisandmed. Kui määramata, siis ei kontrollita e-valimiskastis sisalduvate häälte vastavust registreerimisandmetega. :checkAndSquash.registrationlist_checksum: Registreerimisandmete digitaalselt allkirjastatud räsi. Võib puududa, kui ``registrationlist`` puudub. :checkAndSquash.tskey: Registreerimispäringute verifitseerimiseks kasutatav kogumisteenuse avalik võti registreerimispäringute tegemise sertifikaadist. :checkAndSquash.vlkey: Valijate nimekirjade verifitseerimiseks kasutatav avalik võti. Argument on kohustuslik, kui valijate nimekirjad on antud. :checkAndSquash.voterlists_dir: Valijate nimekirjade loendi kaust. Kui on määramata, siis e-hääletanute hääleõigust ei kontrollita. :checkAndSquash.voterlists: Valijate nimekirjade loend. Kui on määramata, siis e-hääletanute hääleõigust ei kontrollita. :checkAndSquash.voterlists.path: Valijate nimekirja fail. :checkAndSquash.voterlists.signature: Valijate nimekirja allkiri, mis on antud algoritmiga ``ecdsa-with-SHA256``. :checkAndSquash.districts_mapping: Valijate nimekirjas oleva ringkonna ja jaoskonna teisendusfail (valikuline). :checkAndSquash.election_start: Hääletamise algusaeg. Sellest varasema hääletusajaga hääli käsitletakse proovihäältena ning need lugemisele ei lähe. :checkAndSquash.voterforeignehak: Alaliselt välisriigis elavate valijate ringkonnakuuluvuse tuvastamiseks kasutatav EHAK-kood. Vaikeväärtus "0000". :checkAndSquash.enckey: Krüpteerimise avaliku võtme faili asukoht (võtmerakenduse väljund). Võtit kasutatakse krüpteeritud häälte eelkontrolliks, eristamaks päriselt krüpteeritud hääli suvalisest binaarsest prügist. :checkAndSquash.out: Tööriista väljundkaust. Sellesse kausta tekivad: #. Korduvhäältest puhastatud e-valimiskast :file:`-bb-2.json`; #. Korduvhäältest puhastatud e-valimiskasti räsi :file:`-bb-2.json.sha256sum`; #. E-hääletanute nimekiri JSON-vormingus :file:`-ivoterlist.json`; #. E-hääletanute nimekiri PDF-vormingus :file:`-ivoterlist.pdf`; #. Tühistamiste ja ennistamiste aruanne :file:`-revocation-report.csv`; #. Tühistamiste ja ennistamiste aruanne ilma isikuandmeteta :file:`-revocation-report.csv.anonymous`; #. *Log1* fail ehk vastuvõetud hääled :file:`..log1`. #. *Log2* fail ehk tühistatud hääled :file:`..log2`. #. E-valimiskasti töötlemisvigade raport :file:`ballotbox_errors.txt` (valikuline); #. Valijate nimekirjade töötlemisvigade raport :file:`voterlist_errors.txt` (valikuline); :file:`processor.checkAndSquash.yaml`: .. literalinclude:: config-examples/processor.checkAndSquash.yaml :language: yaml :linenos: .. _processor-revokeAndAnonymize: E-valimiskasti töötlemine - häälte tühistamine, ennistamine jaoskonnainfo põhjal ja anonüümimine --------------------------------------------------------------------------------------------------- Häälte tühistamiseks, ennistamiseks jaoskonnainfo põhjal ning anonüümimiseks kasutatakse tööriista *revokeAndAnonymize*. Tööriist saab sisendiks tööriista *squash* või *checkAndSquash* poolt koostatud e-valimiskasti ning rakendab sellele sisendiks antud tühistus- ja ennistusnimekirjad. :revokeAndAnonymize.ballotbox: Korduvhäältest puhastatud e-valimiskast. :revokeAndAnonymize.ballotbox_checksum: Korduvhäältest puhastatud e-valimiskasti digitaalselt allkirjastatud räsi. :revokeAndAnonymize.districts: Digitaalselt allkirjastatud ringkondade nimekiri. :revokeAndAnonymize.revocationlists: Tühistus- ja ennistusnimekirjade loend. Võib olla tühi. :revokeAndAnonymize.out: Tööriista väljundkaust. Sellesse kausta tekivad: #. Korduvhääletajate häältest puhastatud ning anonüümitud e-valimiskast :file:`-bb-4.json`; #. Korduvhääletajate häältest puhastatud ning anonüümitud e-valimiskasti räsi :file:`-bb-4.json.sha256sum`; #. Tühistamiste ja ennistamiste aruanne :file:`-revocation-report.csv`; #. Tühistamiste ja ennistamiste aruanne ilma isikuandmeteta :file:`-revocation-report.csv.anonymous`; #. E-hääletanute nimekiri JSON-vormingus :file:`-ivoterlist.json``; #. *Log2* fail e. tühistatud hääled :file:`..log2`. #. *Log3* fail e. lugemisele läinud hääled :file:`..log3`. :file:`processor.revokeAndAnonymize.yaml`: .. literalinclude:: config-examples/processor.revokeAndAnonymize.yaml :language: yaml :linenos: ================================================ FILE: Documentation/et/seadistuste_koostejuhend/valijarakendus.rst ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus .. _valijarakendus: Valijarakenduse seadistamine ============================ Valijarakenduse seadistamist ning pakendamist käsitleb eraldi dokument. ================================================ FILE: Documentation/et/seadistuste_koostejuhend/votmerakendus.rst ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus .. _app-key: Võtmerakendus ============= Võtmerakendus `key` koosneb tööriistadest *groupgen*, *init*, *testkey*, *decrypt* ja *util*. Kõigi tööriistade kasutamine eeldab allkirjastatud usaldusjuure ja konkreetse tööriista seadistuste olemasolu. Alljärgnevalt kirjeldame konkreetsete tööriistade seadistusi. .. _key-groupgen: Häälte salastamise võtme spetsifikatsiooni valimine -------------------------------------------------------------------------------- Kasutamaks ElGamali krüptosüsteemi häälte krüpteerimiseks, on oluline häälte salastamise võtme spetsifikatsiooni valimine ehk kasutatavate rühma parameetrite valimine, milles tehakse matemaatilisi operatsioone. Oluline on, et antud parameetrid oleksid valitud läbipaistvalt, vältimaks tagauste olemasolu, mille abil oleks võimalik ilma salajast võtit omamata krüpteeritud hääli avada. Kuna turvalisuse jaoks peavad rühma parameetrid vastama teatud tingimustele, siis nende valimiseks pole kiiret meetodit. Sobivate rühmaparameetrite leidmiseks tuleb juhuslikult valida mingid parameetrid ja kontrollida, kas need vastavad antud tingimustele. Rühma parameetrite genereerimise protsessi on võimalik läbipaistvalt läbi viia kahel viisil: #. Kasutades teadaolevaid defineeritud parameetreid #. Parameetreid avaliku algoritmi alusel deterministlikult genereerides Teadaolevate parameetrite kasutamine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Mitmed standardid ja rakendused on juba defineerinud parameetrid, mida on sobiv kasutada ElGamal krüptosüsteemis. Kasutades laialt levinud parameetreid on suurem tõenäosus, et neid on sõltumatult kontrollitud. Üheks selliseks standardiks on [RFC3526]_, mis kasutab samuti deterministlikku parameetrite genereerimist. Antud standardi korral saab kontrollida defineeritud parameetrite korrektsust järgneva Sage skriptiga: .. literalinclude:: genparam.py :language: python :linenos: Uute parameetrite deterministlik ja kontrollitav genereerimine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ElGamal krüptosüsteemi jaoks sobilikke parameetreid saab genereerida kasutades tööriista *groupgen*. Võtmespetsifikatsiooni genereerimine on ajaliselt mahukas tegevus, mis võib olenevalt riistvarast kesta tunde. Ühekordselt genereeritud rühm on kasutatav mitmetel valimistel. :groupgen.paramtype: ElGamal'i krüptosüsteemi töö aluseks oleva rühma tüüp. Toetatud väärtused: #. ``mod`` - jäägiklassiring ``Zp`` :groupgen.length: ElGamal'i krüptosüsteemi töö aluseks olevat rühma iseloomustav turvaparameeter. Jäägiklassiringide korral on sobiv väärtus 3072. :groupgen.init_template: Asukoht, kuhu kirjutatakse rühma parameetrid. Väljund sobib kasutamiseks võtme genereerimise seadistuse koostamisel. :groupgen.random_source: Juhuarvugeneraatori sisendiks kasutatavate allikate loetelu. Vaata ka :numref:`random-gen`. Elliptkõveraid kasutades on toetatud kõver P-384, mille parameetrite genereerimine ei ole vajalik. Kasutades juhuslike parameetrite leidmiseks juhuarvugeneraatorit, mille algväärtus on üheselt defineeritav ning avalikustatud, võivad kolmandad osapooled kontrollida, et avaldatud rühma parameetrid on esimesed sellised leitud parameetrid, mis vastavad tingimustele. Näitekonfiguratsioon kasutab DPRNG'd avaliku seemnefailiga. Vaata ka :numref:`random-gen`. :file:`key.groupgen.yaml`: .. literalinclude:: config-examples/key.groupgen.yaml :language: yaml :linenos: Sellise seadistuse korral loetakse juhuarvugeneraatori algväärtus failist ``public_seed_file``. Oluline on, et sellisel juhul käivitatakse võtmerakendus ühelõimelisena:: $ key groupgen --conf usaldusjuur.asice --params key.groupgen.asice --threads 1 .. _key-init: Häälte salastamise võtme genereerimine -------------------------------------- Häälte salastamise võtme genereerimiseks kasutatakse võtmerakenduse tööriista *init*. Võti genereeritakse seadistustes näidatud läviskeemiga ``MofN``, mis tähendab, et N võtmehaldurist peavad häälte dekrüpteerimisel osalema vähemalt M haldurit, vastasel juhul ei ole dekrüpteerimine võimalik. :init.identifier: Valimise unikaalne identifikaator. :init.out: Võtmerakenduse tööriista *init* väljundkataloog. Sellesse kataloogi tekivad #. PEM vormingus allkirjavõtme sertifikaat (``sign.pem``) #. PEM vormingus krüpteerimisvõtme sertifikaat (``enc.pem``) #. PEM vormingus krüpteerimisvõti (``pub.pem``) #. DER vormingus krüpteerimisvõti (``pub.der``) :init.skiptest: Võtmeosakute kontrolltestide vahelejätmine. :init.fastmode: Kaartidele automaatne terminalide määramine. Vaikimise väärtus on tõene. ---- :init.paramtype: ElGamal krüptosüsteemi aluseks oleva rühma parameetrid, mis ühtlasi määravad võtme turvataseme. Korraga saab olla kasutusel vaid ühe rühma spetsifikatsioon - kas jäägiklassiring või elliptkõver :init.paramtype.ec: Elliptkõverat määravad parameetrid. :init.paramtype.ec.name: Kasutatava kõvera nimi, hetkel P-384. :init.paramtype.mod: Jäägiklassiringi määravad parameetrid kümnendesituses. Parameetrid võib luua võtmerakenduse tööriista *groupgen* kasutades. :init.paramtype.mod.p: Jäägiklassiringi moodul. :init.paramtype.mod.g: Jäägiklassiringi generaator. ---- :init.signaturekeylen: Võtmerakenduse poolt genereeritava allkirjastamise võtme pikkus. :init.signcn: Võtmerakenduse poolt loodava allkirjastamise sertifikaadi subjekti nimi (väli *CN*). :init.signsn: Võtmerakenduse poolt loodava allkirjastamise sertifikaadi järjekorranumber. :init.enccn: Võtmerakenduse poolt loodava krüpteerimise sertifikaadi subjekti nimi (väli *CN*). :init.encsn: Võtmerakenduse poolt loodava krüpteerimise sertifikaadi järjekorranumber. ---- :init.required_randomness: Juhuslikkuse allikatest loetava entroopia kohustuslik hulk baitides. :init.random_source: Juhuarvugeneraatori sisendiks kasutatavate allikate loetelu. Vaata ka :numref:`random-gen`. ---- :init.genprotocol: Võtme genereerimiseks kasutatava algoritmi ja läviskeemi spetsifikatsioon. :init.genprotocol.desmedt: Algoritmi Desmedt korral genereeritakse võti usaldatava osakujagaja poolt ehk võtmerakenduse mälus. Privaatvõtme osakud talletatakse kiipkaartidel. Täiendavalt tuleb määrata läviskeemi osaliste arv ja minimaalne kvoorum. Kaartide arv 7 - võimalikud kvoorumid 1,2,3,4 - soovitatav kvoorum 4 Kaartide arv 8 - võimalikud kvoorumid 1,2,3,4 - soovitatav kvoorum 4 Kaartide arv 9 - võimalikud kvoorumid 1,2,3,4,5 - soovitatav kvoorum 5 :init.genprotocol.desmedt.threshold: Läviskeemi M väärtus - kvoorum. :init.genprotocol.desmedt.parties: Läviskeemi N väärtus. :file:`key.init.yaml`: .. literalinclude:: config-examples/key.init.yaml :language: yaml :linenos: .. _key-testkey: Häälte salastamise võtme testimine ---------------------------------- Häälte salastamise võtme testimine kontrollib võtme rekonstrueerimise võimekust selliselt, et iga osak osaleb vähemalt kahes kvoorumis. Testimiseks on vajalik kõigi osakute osalemine. :testkey.identifier: Valimise unikaalne identifikaator. :testkey.out: Krüpteerimise avaliku võtme asukoha kataloog. :testkey.threshold: Testimiseks kasutatav lävi, sama mis võtme loomisel spetsifitseeritud. :testkey.parties: Testimiseks kasutatav osapoolte arv, sama mis võtme loomisel spetsifitseeritud. :testkey.fastmode: Kaartidele automaatne terminalide määramine. Vaikimise väärtus on tõene. :file:`key.testkey.yaml`: .. literalinclude:: config-examples/key.testkey.yaml :language: yaml :linenos: .. _key-decrypt: E-häälte dekrüpteerimine -------------------------------------- Elektrooniliste häälte dekrüpteerimiseks kasutatakse võtmerakenduse tööriista *decrypt*. Dekrüpteerimise õnnestumiseks peab osalema läviskeemi poolt määratud kvoorumi jagu võtmehaldureid. Kui rakendati skeemi ``5of9``, siis osaleb dekrüpteerimisel täpselt 5 võtmehaldurit. Vähema arvu haldurite korral ei ole dekrüpteerimine võimalik. :decrypt.identifier: Valimise unikaalne identifikaator. ---- :decrypt.protocol: :decrypt.protocol.recover: Algoritmi Desmedt korral genereeritakse võti usaldatava osakujagaja poolt ehk võtmerakenduse mälus. Privaatvõtme osakud talletatakse kiipkaartidel. :decrypt.protocol.recover.threshold: Läviskeemi M väärtus - kvoorum, mis spetsifitseeriti võtme loomisel. :decrypt.protocol.recover.parties: Läviskeemi N väärtus, mis spetsifitseeriti võtme loomisel. ---- :decrypt.anonballotbox: Töötlemisrakenduse või miksimisrakenduse poolt loodud e-valimiskast anonüümistatud häältega. :decrypt.anonballotbox_checksum: Anonüümistatud häältega e-valimiskasti allkirjastatud SHA256 kontrollsummafail. :decrypt.questioncount: Küsimuste arv anonüümistatud e-valimiskastis. Vaikimisi väärtus on 1. :decrypt.candidates: Valimise valikute nimekiri allkirjastatud kujul. :decrypt.districts: Valimise ringkondade nimekiri allkirjastatud kujul. :decrypt.provable: Valikuline korrektse dekrüpteerimise tõestuse väljastamine. Vaikimisi väärtus on tõene. :decrypt.prove_invalid: Valikuline korrektse dekrüpteerimise tõestuse väljastamine ka ebakorrektsete sedelite kohta. Eeldab dekrüpteerimise tõestuse väljastamist. Vaikimisi väärtus on väär. :decrypt.check_decodable: Krüptogrammide korrektsuse kontrollimine enne dekrüpteerimist. Juhul kui krüptogrammide sisend ei tule usaldatud allikast, siis tuleb kontrollida krüptogrammide korrektsust. Usaldatud allikad on töötlemisrakendus ning miksija. Vaikimisi väärus on väär. :decrypt.out: Võtmerakenduse tööriista *decrypt* väljundkataloog. Eduka dekrüpteerimise korral tekivad siia kausta: #. Elektroonilise hääletamise tulemus #. Elektroonilise hääletamise tulemuse signatuur #. Dekrüpteeritud valimiskast #. Dekrüpteeritud valimiskasti signatuur #. Loend kehtetutest sedelitest #. Kehtivate sedelite lugemistõend #. Kehtetute sedelite lugemistõend (valikuline) Dekrüpteeritud valimiskast tundlikke andmeid ei sisalda. :file:`key.decrypt.yaml`: .. literalinclude:: config-examples/key.decrypt.yaml :language: yaml :linenos: Pärast dekrüpteerimist on võimalik kontrollida väljastatud elektroonilise hääletamise tulemuse signatuuri korrektsust. Selleks tuleb teha järgnevad sammud: 1. Eraldada allkirja kontrollimise võti allkirjastamise sertifikaadist:: openssl x509 -in initout/sign.pem -noout -pubkey > sign.pub 2. Kontrollida hääletamise tulemuse allkirja:: openssl dgst -sha256 -sigopt rsa_padding_mode:pss -sigopt \ rsa_pss_saltlen:32 -sigopt rsa_mgf1_md:sha256 -verify sign.pub \ -signature decout/TESTCONF.tally.signature decout/TESTCONF.tally Korrektse allkirja korral kuvatakse väärtust `Verified OK`. Sarnaste sammudega on võimalik kontrollida ka väljastatud dekrüpteeritud valimiskasti signatuuri korrektsust. Võtmerakenduse täiendavad tööriistad ------------------------------------ :util.listreaders: Loetle ühendatud kaardilugejad. :file:`key.util.yaml`: .. literalinclude:: config-examples/key.util.yaml :language: yaml :linenos: .. _random-gen: Juhuarvude genereerimine võtmerakenduses ---------------------------------------- Võtmerakenduse tööriistad *groupgen* ja *init* vajavad oma tööks juhuarve, mille genereerimiseks on võimalik kasutada erinevaid entroopiaallikaid, mis võtmerakenduse poolt üheks allikaks kombineeritakse. Kombineerimisel on oluline, et säiliks sisendite sõltumatus, st. kombineeritud väljund ei tohi olla kehvem ühestki sisendist. IVXV raamistikus toimub entroopia kombineerimine SHAKE-256 muutuva väljundipikkusega räsifunktsiooni abil (XOF), kasutades skeemi nagu on kirjeldatud [BDPA10]_. Lõpliku pikkusega entroopiaallika kasutamisel loetakse kogu väärtus ning antakse see SHAKE-256 sisendiks. Piiramata pikkusega allika lisamisel salvestatakse selle viide kombineerija mällu. Pärides kombineerijast töödeldud juhuslikkust, loetakse kõigepealt igast salvestatud entroopia allikast sama palju baite ning antakse see SHAKE-256 sisendiks. Seejärel kopeeritakse SHAKE-256 isend, muudetakse kopeeritud SHAKE-256 režiim lugemisele ning loetakse nõutud baitide jagu väljundit. :random_source: Juhuarvugeneraatori sisendiks kasutatavate allikate loetelu. :random_source.random_source_type: Juhuarvugeneraatori allika tüüp. :random_source.random_source_path: Juhuarvugeneraatori allika seadistatav asukoht. Argument on valikuline sõltuvalt allika tüübist. ---- :random_source_type\: file: Entroopia lugemine failist. :random_source_path\: `randomness_file`: Kasutatav fail. ---- :random_source_type\: system: Operatsioonisüsteemi poolt pakutav entroopiaallikas (Linuxil `/dev/urandom`). ---- :random_source_type\: DPRNG: Deterministlik pseudojuhuslik generaator (DPRNG) on mõeldud baidijadade genereerimiseks, kasutades etteantud seemneväärtust. Sama seemneväärtuse korral genereerib meetod alati sama jada. :random_source_path\: `seed_file`: DPRNG seemneväärtus saadakse viidatud faili SHA256 räsides. ---- :random_source_type\: stream: Entroopia lugemine voogseadmelt. :random_source_path\: `/dev/urandom`: Kasutatav seade. ---- :random_source_type\: user: Välise programmi käest üle sokli juhuslikkust hankiv entroopiaallikas. Kasutusel on IVXV-spetsiifiline protokoll. :random_source_path\: `user_entropy.exe`: Tee programmini, mis tuleb juhuslikkuse hankimiseks käivitada. Entroopiaallikate kombineerimine kirjeldatud viisil võimaldab realiseerida erinevaid juhuarvude genereerimise stsenaariumeid. Näiteks häälte salastamise võtme genereerimise korral on vaja tagada võtme konfidentsiaalsus ning olla kindel, et genereerimisprotsess ei ole hiljem korratav. Näitekonfiguratsioon kasutab välist programmi kasutaja sisendi lugemiseks ning süsteemset juhuarvugeneraatorit: :file:`rnd.init.yaml`: .. literalinclude:: config-examples/rnd.init.yaml :language: yaml :linenos: Rakendus käivitatakse mitmelõimelisena:: $ key init --conf usaldusjuur.asice --params rnd.init.asice Häälte salastamise võtme spetsifikatsioon on erinevalt häälte salastamise võtmest avalik ning selle genereerimisel kasutatud juhuslikkuse võib samuti teha avalikuks. Näitekonfiguratsioon kasutab DPRNG'd avaliku seemnefailiga. :file:`rnd.groupgen.yaml`: .. literalinclude:: config-examples/rnd.groupgen.yaml :language: yaml :linenos: Kui eesmärk on genereerimisprotsessi korratavus, tuleb rakendus käivitada ühelõimelisena:: $ key groupgen --conf usaldusjuur.asice --params rnd.groupgen.asice --threads 1 .. [BDPA10] G. Bertoni, J. Daemen, M. Peeters, G. Van Assche: Sponge-Based Pseudo-Random Number Generators. CHES 2010: 33-47 .. [RFC3526] T. Kivinen, M. Kojo: More Modular Exponential (MODP) Diffie-Hellman groups for Internet Key Exchange (IKE). IETF RFC3526, 2003 ================================================ FILE: Documentation/et/seadistuste_koostejuhend/ylevaade.rst ================================================ .. IVXV kogumisteenuse haldusteenuse kirjeldus IVXV seadistused valimise korraldamise protsessis ------------------------------------------------- IVXV kasutamiseks valimise kontekstis tuleb süsteem ja sellega seotud rakendused seadistada nii, et on võimalik valijatelt häälte vastuvõtmine ning nende käitlemine vastavalt süsteemile seatud terviklus-, konfidentsiaalsus ja käideldavusnõuetele. Käesolev tehniline dokument annab ülevaate olulisimatest seadistustoimingutest ning on mõeldud täiendama elektroonilise hääletamise käsiraamatu poolt kirjeldatud protseduurireeglite täitmist. Seadistuste koostamiseks vajalikud andmed ***************************************** Valimise üldparameetrid Valimise üldparameetrid määravad valimise unikaalse identifikaatori kasutamiseks kõigi seotud komponentide poolt, küsimuste arvu ning identifikaatorid, hääletamisperioodi alguse- ja lõpuaja ning hääle kontrollimise seadistuse. Valimise üldparameetrite spetsifikatsiooni käsitletakse käesolevas dokumendis. Algne valijate nimekiri Algne valijate nimekiri on kohandatud vormingus fail, mille vorming ning seotud protokollid on defineeritud dokumendis "IVXV protokollid". Eesti riiklike valimiste korral tuleb algne valijate nimekiri Rahvastikuregistrist. Valikute nimekiri Valikute nimekiri on JSON vormingus fail, mille vorming ning seotud protokollid on defineeritud dokumendis "IVXV protokollid". Eesti riiklike valimiste korral tuleb valikute nimekiri valimiste infosüsteemist. Ringkondade nimekiri Ringkondade nimekiri on JSON vormingus fail, mille vorming ning seotud protokollid on defineeritud dokumendis "IVXV protokollid". Eesti riiklike valimiste korral tuleb ringkondade nimekiri valimiste infosüsteemist. Rakenduste usaldusjuur Rakenduste usaldusjuur defineerib sertifitseerimishierarhiad, mille alusel IVXV rakendused verifitseerivad digitaalallkirju. Eesti riiklike valimiste korral määrab usaldusjuure koosseisu Riigi Valimisteenistus. Rakenduste usaldusjuure vormingut käsitletakse peatükis :numref:`ivxv-rakendused`. Kogumisteenuse usaldusjuur Kogumisteenuse usaldusjuur defineerib sertifitseerimishierarhiad, mille alusel IVXV kogumisteenuse komponendid verifitseerivad digitaalallkirju. Eesti riiklike valimiste korral määrab usaldusjuure koosseisu Riigi Valimisteenistus. Kogumisteenuse usaldusjuure vormingut ning seotud protokolle käsitletakse peatükis :numref:`kogumisteenus`. Kogumisteenuse tehniline seadistus Kogumisteenuse tehniline seadistus kirjeldab IVXV mikroteenuste seadistuse ning isendite jaotumise. Eesti riiklike valimiste korral leiab kogumisteenuse osutaja Riigi Valimisteenistus. Tehniline seadistus kooskõlastatakse valimiste omaniku ja kogumisteenuse osutaja vahel. Tehnilist seadistust käsitletakse peatükis :numref:`kt-technical`. Kogumisteenuse võtmed ja sertifikaadid Kogumisteenuse mikroteenused suhtlevad omavahel TLS protokolli vahendusel. Vastavad sertifikaadid tuleb eksportida Valijarakendusse ja Kontrollrakendusse. Kogumisteenusega seotud võtmete loomist käsitletakse peatükis :numref:`kt-krypto`. Häälte salastamise võtme spetsifikatsioon Häälte salastamise võtme jaoks kasutatav algoritm ning seotud tehnilised parameetrid fikseeritakse enne häälte salastamise võtme genereerimist. Võtme spetsifikatsiooni käsitletakse peatükis :numref:`key-groupgen`. Hääletamisperioodile eelnevad tegevused *************************************** Enne hääletamisperioodi algust teostatakse lähtuvalt eelnevatest andmetest järgmised tegevused: #. :numref:`app-install` #. :numref:`app-trust` #. :numref:`key-groupgen` #. :numref:`key-init` #. :numref:`key-testkey` #. :numref:`kt-trust` #. :numref:`kt-technical` #. :numref:`kt-election` #. Ringkondade nimekirja laadimine Kogumisteenusesse #. Valikute nimekirja laadimine Kogumisteenusesse #. Valijate nimekirja (algne) laadimine Kogumisteenusesse #. :numref:`kt-management` #. :numref:`valijarakendus` #. :numref:`kontroll` Hääletamisperioodi tegevused **************************** #. Valijate nimekirjade (muudatused) laadimine Kogumisteenusesse Hääletamisperioodile järgnevad tegevused **************************************** E-valimiskasti töötlemine ^^^^^^^^^^^^^^^^^^^^^^^^^ #. :numref:`processor-check` #. :numref:`processor-squash` #. :numref:`processor-revoke` #. :numref:`processor-anonymize` Häälte miksimine ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. :numref:`mix-install` #. :numref:`mix-mix` #. :numref:`mix-verify` Hääletamistulemuse väljaselgitamine ja andmeaudit ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #. :numref:`key-decrypt` #. :numref:`auditor-convert` #. :numref:`auditor-mix` #. :numref:`auditor-decrypt` ================================================ FILE: Documentation/et/votmerakendus/Makefile ================================================ include ../../common.mk ================================================ FILE: Documentation/et/votmerakendus/index.rst ================================================ .. IVXV tehniline dokumentatsioon ====================================================================== IVXV tehniline dokumentatsioon ====================================================================== ------------- Võtmerakendus ------------- .. raw:: html

NB! See on HTML-versioon dokumendist. Tellijale antakse üle PDF-versioon.

.. toctree:: :maxdepth: 3 :numbered: sissejuhatus votmeosakute_protokollid viited ================================================ FILE: Documentation/et/votmerakendus/sissejuhatus.rst ================================================ .. IVXV tehniline dokumentatsioon Sissejuhatus ============ Võtmerakendus on Korraldaja põhitööriist, millega genereeritakse iga hääletamise jaoks häälte salastamise ja häälte avamise võti. Võtmerakenduse abil toimub ka häälte lugemine ja tulemuse väljastamine. Dokumendis spetsifitseeritakse võtmerakenduse tehnilised detailid. ================================================ FILE: Documentation/et/votmerakendus/viited.rst ================================================ .. IVXV tehniline dokumentatsioon Viited ====== .. [DF89] Desmedt, Y. & Frankel, Y. Brassard, G. (Ed.). Threshold Cryptosystems. Advances in Cryptology - CRYPTO '89, 9th Annual International Cryptology Conference, Santa Barbara, California, USA, August 20-24, 1989, Proceedings, Springer, 1989, 435, 307-315 .. [Shoup00] Shoup, V. Practical Threshold Signatures Advances in Cryptology - EUROCRYPT 2000, International Conference on the Theory and Application of Cryptographic Techniques, Bruges, Belgium, May 14-18, 2000, Proceeding, 2000, 207-220 .. [RFC8017] PKCS #1: RSA Cryptography Specifications Version 2.2. https://tools.ietf.org/html/rfc8017 ================================================ FILE: Documentation/et/votmerakendus/votmeosakute_protokollid.rst ================================================ .. IVXV tehniline dokumentatsioon Eritüübiliste võtmeosakute protokollide liidestamine ==================================================== Võtmeosakute genereerimise protokolli liides -------------------------------------------- Klass `ee.ivxv.key.protocol.GenerationProtocol` defineerib liidese, mida ElGamali või RSA võtmeosakute genereerimise protokoll peab täitma. Liides on järgnev:: public interface GenerationProtocol { byte[] generateKey() throws ProtocolException; } Eritüübiliste võtmeosakute genereerimiseks peab implementeerima `generateKey()` meetodi, mis tagastab kodeeritud avaliku võtme X.509 sertifikaadina DER formaadis. Protokolli klass peab olema paki `ee.ivxv.key.protocol.generation` alampakis. Protokolli parameetrid tuleb määrata protokolli klassiinstantsi initsialiseerimise ajal. Dekrüpteerimise protokolli liides --------------------------------- Dekrüpteerimise ja võtmeosakute genereerimise protokoll ei pea olema üksüheses seoses, st. võtmeosakute genereerimise protokollile võib vastata mitu dekrüpteerimise protokolli. Seega on dekrüpteerimise protokolli liides defineeritud sõltumatult võtmeosakute genereerimise liidesest. Protokoll peab implementeerima `ee.ivxv.key.protocol.DecryptionProtocol` liidese:: public interface DecryptionProtocol { ElGamalDecryptionProof decryptMessage(byte[] msg) throws ProtocolException; } Meetod `decryptMessage()` võtab sisendina krüptogrammi DER formaadis ning väljastab `ElGamalDecryptionProof` instantsi. Juhul kui protokoll ei toeta lugemistõendi väljastamist, siis on vastavad väljad väärtustatud tühiväärtusega (`null`). Analoogselt võtmeosakute genereerimise protokollile tuleb protokolli parameetrid määrata klassiinstantsi initsialiseerimise ajal. Allkirjastamise protokolli liides --------------------------------- Lisaks dekrüpteerimise protokollile saab implementeerida ka allkirjastamise protokolli. Sarnaselt dekrüpteerimisprotokollile võib ühele võtmegenereerimise meetodile vastata mitu allkirjastamise protokolli. Protokoll peab implementeerima `ee.ivxv.key.protocol.SigningProtocol` liidese:: public interface SigningProtocol { byte[] sign(byte[] msg) throws ProtocolException; } Meetod `sign()` võtab sisendina sõnumi, mida soovitakse allkirjastada, ja väljastab RSA-PSS allkirja järgnevate parameetritega: .. _RSA-PSS parameetrid: - sõnumi räsifunktsioon: SHA2-256 - maski genereerimise funktsioon: MGF1, maski räsifunktsioon SHA2-256 ja maski pikkus 32 baiti - soola pikkus: 32 baiti - sababait: `0xbc` Analoogselt võtmeosakute genereerimise protokollile tuleb protokolli parameetrid määrata klassiinstantsi initsialiseerimise ajal. Toetatud protokollid -------------------- Hetkel on teostatud järgnevad võtmeosakute genereerimise protokollid: * `ee.ivxv.key.protocol.generation.desmedt.DesmedtGeneration`: Võtmeosakud on sellised, et oleks võimalik kasutada [DF89]_ hajutatud dekrüpteerimisprotokolli. Võtmeosakud salvestatakse otse PKCS15 liidest toetavale pääsmikule. Klassiinstantsi initsialiseerimise ajal saab anda järgnevaid argumente: + `PKCS15Card[] cards`: järjend objektides mis implementeerivad PKCS15Card liidest (nt. kiipkaardid või tarkvaralised pääsmikud). + `ElGamalParameters params`: ElGamali krüptosüsteemi parameetrid. + `ThresholdParameters tparams`: läviskeemi parameetrid. + `Rnd rnd`: juhuslikkuse sisend võtmeosakute genereerimisel + `byte[] cardShareAID`: võtmeosaku ligipääsuidentifikaator PKCS15 pääsmikul. Defineerib, millise ligipääsutunnusega pääseb võtmeosakule ligi. + `byte[] cardShareName`: võtmeosaku identifikaator PKCS15 pääsmikul. * `ee.ivxv.key.protocol.generation.shoup.ShoupGeneration`: Võtmeosakud on sellised, et oleks võimalik kasutada [Shoup00]_ põhinevat hajutatud allkirjastamisprotokolli. Võtmeosakud salvestatakse otse PKCS15 liidest toetavale pääsmikule. Klassiinstantsi initsialiseerimise ajal saab anda järgnevaid argumente: + `PKCS15Card[] cards`: järjend objektidest, mis implementeerivad PKCS15Card liidest (nt. kiipkaardid või tarkvaralised pääsmikud). + `int modLen`: RSA võtme pikkus bittides + `ThresholdParameters tparams`: läviskeemi parameetrid. + `Rnd rnd`: juhuslikkuse sisend võtmeosakute genereerimisel + `byte[] cardShareAID`: võtmeosaku ligipääsuidentifikaator PKCS15 pääsmikul. Defineerib, millise ligipääsutunnusega pääseb võtmeosakule ligi. + `byte[] cardShareName`: võtmeosaku identifikaator PKCS15 pääsmikul. On teostatud järgnevad dekrüpteerimise protokollid: * `ee.ivxv.key.protocol.decryption.recover.RecoverDecryption`: Loetakse PKCS15 liidest toetavatelt pääsmikelt võtmeosakud, rekonstrueeritakse nende abil operatiivmälus salajane võti ning teostatakse dekrüpteerimine lugemistõendiga. Klassiinstantsi initsialiseerimise ajal saab anda järgnevaid argumente: + `PKCS15Card[] cards`: järjend objektides mis implementeerivad PKCS15Card liidest (nt. kiipkaardid või tarkvaralised pääsmikud). + `ThresholdParameters tparams`: läviskeemi parameetrid. + `byte[] cardShareAID`: võtmeosaku ligipääsuidentifikaator PKCS15 pääsmikul. Defineerib, millise ligipääsutunnusega pääseb võtmeosakule ligi. + `byte[] cardShareName`: võtmeosaku identifikaator PKCS15 pääsmikul. On teostatud järgnevad allkirjastamise protokollid: * `ee.ivxv.key.protocol.signing.shoup.ShoupSigning`: Loetakse PKCS15 liidest toetavatelt pääsmikelt võtmeosakud, konstrueeritakse mälus allkirjastamise osakud ilma võtit rekonstrueerimata ning kombineeritakse allkirjastamise osakud RSA-PSS allkirjaks. Klassiinstantsi initsialiseerimise ajal saab anda järgnevaid argumente: + `PKCS15Card[] cards`: järjend objektides mis implementeerivad PKCS15Card liidest (nt. kiipkaardid või tarkvaralised pääsmikud). + `ThresholdParameters tparams`: läviskeemi parameetrid. + `Rnd rnd`: juhuslikkuse sisend RSA-PSS allkirja soola genereerimisel. + `byte[] cardShareAID`: võtmeosaku ligipääsuidentifikaator PKCS15 pääsmikul. Defineerib, millise ligipääsutunnusega pääseb võtmeosakule ligi. + `byte[] cardShareName`: võtmeosaku identifikaator PKCS15 pääsmikul. Protokollide võtmerakendusega liidestamine ------------------------------------------ Järgnev kirjeldus käib nii võtmeosakute genereerimise ja dekrüpteerimise protokollide kohta. .. note:: Praegune kirjeldus on üldine. Kui konfi- ja argumentide parsimine on lõplikult välja töötatud ning protokollid võtmerakendusega liidestatud, siis tuleks järgnevat lõiku täiendada. Liidestamaks uut protokolli võtmerakendusega, tuleb kõigepealt teostada vastava protokolli liidest täitev klass. Võtmerakendus peab töö alguses seadistuse töötlemise käigus aru saama kas käsureaargumentidest või seadistusfailist, millist protokolli soovitakse kasutada. Seejärel tuleb vastava klassi staatilise meetodi abil ülejäänud käsureaargumentide või seadistusfaili abil initsialiseerida uus protokolliklassi instants. Seejärel tuleb genereerida võti või dekrüpteerida sõnum. Toetatud protokollide kirjeldused --------------------------------- Shamiri saladuse jagamise skeem ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Olgu meil salajane väärtus :math:`s = a_0` ja soovime seda jagada :math:`n` osapoole vahel selliselt, et vähemalt :math:`t` osapoolt saaksid selle saladuse rekonstrueerida. Selleks valime koefitsiendid :math:`a_1` kuni :math:`a_{t-1}` ning vaatame polünoomi muutuja :math:`x` suhtes: .. math:: P(x) = a_{t-1} x^{t-1} + .. + a_1 x + a_0 Olgu :math:`x_1` kuni :math:`x_n` nullist erinevad unikaalsed väärtused (üldiselt :math:`1` kuni :math:`n`), sellisel juhul saame osakud :math:`s_i = P(x_i)` ning salajase väärtuse :math:`s = P(0)`. Geomeetriliselt vaadates on :math:`P(x)` polünoom ning osakud punktid sellel polünoomil. Põhikoolimatemaatikast teame, et :math:`t-1` järku polünoomi joonistamiseks piisab meile :math:`t` punktist (sirge jaoks kaks punkti, parabooli jaoks kolm punkti jne.). Salajane väärtus on selle polünoomi väärtus y-telje lõikepunktis. Vaadates rekonstrueerimist arvuliselt, mitte geomeetriliselt, saame kasutades Lagrange interpoleerimise meetodit. Tähist :math:`\prod` kasutame me mitme liikmega korrutise tähistamiseks ja tähist :math:`\sum` kasutame me mitme liikmega summa tähistamiseks. Nüüd, tähistame lisaks :math:`t` osapoolt, kes osalevad salajase väärtuse rekonstrueerimisel tähisega :math:`U`. Lagrange interpoleerimise valem ütleb: .. math:: \overline{P}(x) = \sum\limits_{j \in U} s_j \frac{\prod\limits_{i \in U, j \neq i}x-x_i}{\prod\limits_{i \in U, j \neq i}x_j-x_i} Tõepoolest: fikseerime :math:`j` - paneme tähele, et kui :math:`x = x_j`, siis murru väärtus on :math:`1` (kuna lugejas ja nimetajas olevad kordajad taandavad üksteist) ja kui :math:`x \neq x_j`, kuid :math:`x = x_k`, mingi muu :math:`k \in U` korral, siis murd on :math:`0` (kuna lugejas on :math:`x_k - x_i = 0` mingi :math:`i \in U` korral). Seega: .. math:: \overline{P}(x_j) = s_j + 0 \sum_{i \in U, i \neq j} s_i = s_j = P(x_j) Kuna osapooled teavad väärtuseid :math:`s_i = P(x_i)` (osakud), siis kombineerides ning korrutades need läbi baaspolünoomiga .. math:: L(U,x,j) = \frac{\prod\limits_{i \in U, j \neq i}x - x_i}{\prod\limits_{i \in U, j \neq i}x_j - x_i} ja fikseerides :math:`x = 0`, saame jagatud saladuse. `ee.ivxv.key.protocol.generation.desmedt.DesmedtGeneration` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Arvestades, et ElGamali võtmeparameetriks on rühm :math:`G` koos generaatoriga :math:`g`, siis salajaseks võtmeks valitakse :math:`x`, mis on ülimalt :math:`ord(g)`, st. :math:`g` multiplikatiivne järk rühmas :math:`G`. Vastavaks avalikuks võtmeks võetakse väärtus :math:`y = g^x`. Salajase võtme komplektiks saab väärtus :math:`(G, g, x)` ja avaliku võtme komplektiks väärtus :math:`(G, g, y)`. Rühm :math:`G` valitakse selliselt, et tema järk on mingi algarv :math:`p` selliselt, et kehtib :math:`p = 2 q + 1`, kus :math:`q` on samuti algarv. Selliselt juhul kirjeldab :math:`G` väärtust algarv :math:`p`. Algebrast teame, et kui :math:`G` järk on :math:`2q + 1`, siis iga selle rühma elemendi järk on kas :math:`1`, :math:`2`, :math:`q` või :math:`2q`. Me oleme huvitatud selliselt generaatorist, mille järk on :math:`q` ja mis on ruutjääk, kuna see genereerib piisavalt suure alamrühma, mille kõik elemendid on ruutjäägid. Vastasel juhul võib toimuda ühe biti lekkimine krüpteeritud sõnumi kohta. Sellise generaatori leidmiseks vaatame me rühma suvalisi elemente ning kontrollime tema järku ning ruutjäägilisust kuni leiame sobiva elemendi. Sellise elemendi määrame generaatoriks. Instants genereerib juhusliku :math:`0 NB! See on HTML-versioon dokumendist. Tellijale antakse üle PDF-versioon.

.. toctree:: :maxdepth: 3 :numbered: sissejuhatus jooksevnimekiri seadistamine ================================================ FILE: Documentation/et/xteeteenus/jooksevnimekiri.rst ================================================ .. IVXV tehniline dokumentatsioon E-hääletamiste jooksev nimekiri =============================== Teenus vahendab jooksvat nimekirja EHS-ist X-tee-le. .. figure:: model/xteevotesorder.png X-tee turvaserveri suhtlus EHS-iga Teenuses konfigureeritakse valimissündmused, mille nimekirja on võimalik küsida. Teenus pakub kolme otspunkti: 1. ``Valimissündmuste loetelu`` - väljastab aktiivsete valimissündmuste loetelu 2. ``Viimane järjenumber`` - väljastab konkreetse valimissündmuse viimase EHS-s registreeritud e-hääletamise järjenumbri. 3. ``e-hääletamiste pakk`` - väljastab EHS-lt valimissündmuse e-hääletamiste paki, alatest e-hääletamisest järjenumbriga. ================================================ FILE: Documentation/et/xteeteenus/model/Makefile ================================================ PLANTUML=env -u DISPLAY plantuml all: xteeivxv.png xteevotesorder.png %.png: %.pu $(PLANTUML) $< ================================================ FILE: Documentation/et/xteeteenus/model/xteeivxv.pu ================================================ @startuml left to right direction [X-tee teenus(xroad-service)] as xservice [X-tee turvaserver] as xsec [IVXV1] as ivxv1 [IVXV2] as ivxv2 [IVXV3] as ivxv3 xsec --> xservice xservice--> ivxv1 xservice--> ivxv2 xservice--> ivxv3 @enduml ================================================ FILE: Documentation/et/xteeteenus/model/xteevotesorder.pu ================================================ @startuml left to right direction package "IVXV" { [Järjekorrateenus] as votesorder } [X-tee teenus(xroad-service)] as xservice [X-tee turvaserver] as xsec xsec --> xservice xservice--> votesorder @enduml ================================================ FILE: Documentation/et/xteeteenus/seadistamine.rst ================================================ .. IVXV tehniline dokumentatsioon Seadistamine ============ Teenuse konfigureerimiseks kasutatakse ``xroad-service.json`` faili. ``server.address`` - Serveri port ``server.batchmaxsize`` - Paki suurus, soovitatud suurus 1000 ``server.openapipath`` - OpenAPI faili asukoht. Serveeritakse https://host/openapi. ``server.tls`` - Serveri TLS konfiguratsioon ``xroad.certificate`` - X-tee turvaserveri sertifikaat ``elections``- Valimissündmuste list ``elections.name``- Valimissündmuse nimi ``elections.address`` - IVXV serveri aadress ``elections.servername`` - Järjekorrateenuse SNI ``elections.rootca`` - IVXV CA sertifikaat ``elections.clientcert`` - Kliendi sertifikaat, kliendi CA tuleb lisada IVXV konfiguratsiooni ``elections.clientkey`` - Kliendi võti Käivitamine =========== Teenus ei lähe iseseisvalt püsti, ning kui "Seadistamine" on tehtud, tuleb juurkasutajalt käivitada `systemctl start xroad-service`. Seiskamine ========== Kui teenus läheb maha erinevatel põhjustel (masina taaskäivitamine, veaolukorrad, manuaalne seiskamine `systemctl stop xroad-service` abil), siis tuleb korrata "Käivitamine" protseduuri et teenust taas püsti ajada. ================================================ FILE: Documentation/et/xteeteenus/sissejuhatus.rst ================================================ .. IVXV tehniline dokumentatsioon Sissejuhatus ============ X-tee teenus on vahendamaks päringuid EHS-i(de) ja X-tee turvaserveri vahel. .. figure:: model/xteeivxv.png X-tee teenus turvaserveri ja EHS-ide vahel Dokumendis spetsifitseeritakse teenuse tehnilised detailid. ================================================ FILE: Documentation/ivxv-technical/ivxv-common.cls ================================================ % ivxv-common.cls % Class definition \ProvidesClass{ivxv-common} % Class options for handling documents in different languages \newcommand{\@IVXVStringConfidential}{Konfidentsiaalne} \newcommand{\@IVXVStringDate}{Kuup\"aev:} \newcommand{\@IVXVStringDocumentType}{Tehniline dokument} \newcommand{\@IVXVStringVersion}{Versioon} \newcommand{\@IVXVStringPages}{lk} \newcommand{\@IVXVStringDocument}{Dok} \newcommand{\@IVXVStringBackofTitlePage}{\copyright\ RVT, \the\year} \newcommand{\@IVXVStringCopyrightFooter}{\copyright\ RVT, \the\year} \DeclareOption{estonian}{% \renewcommand{\@IVXVStringConfidential}{Konfidentsiaalne}% \renewcommand{\@IVXVStringDate}{Kuup\"aev:}% \renewcommand{\@IVXVStringDocumentType}{Tehniline dokument}% \renewcommand{\@IVXVStringVersion}{Versioon}% \renewcommand{\@IVXVStringPages}{lk}% \renewcommand{\@IVXVStringDocument}{Dok}% } \DeclareOption{english}{% \renewcommand{\@IVXVStringConfidential}{Confidential}% \renewcommand{\@IVXVStringDate}{Date:}% \renewcommand{\@IVXVStringDocumentType}{Technical document}% \renewcommand{\@IVXVStringVersion}{Version}% \renewcommand{\@IVXVStringPages}{pages}% \renewcommand{\@IVXVStringDocument}{Doc.}% } \ProcessOptions\relax % Base class, which we will modify % Add oldfontcommands for newer versions of memoir. %\LoadClass[a4paper, twoside, 12pt, article]{memoir} \LoadClass[a4paper, twoside, 12pt, article, oldfontcommands]{memoir} \usepackage{cmap} % Make the figure and table captions separated by full stops rather than colons. \usepackage{caption} \captionsetup[table]{labelsep=period} \captionsetup[figure]{labelsep=period} % margins \usepackage[top=1in,bottom=1in,left=1in,right=1in,pdftex]{geometry} % For figuring out, how many pages there is in the document \usepackage{lastpage} % We want to do later MakeUppercase for the section heads and when \label{} is included in the section head, then it will break everything. % Textcase package provides more intelligent MakeUppercase command \usepackage[overload]{textcase} % utf8 fileformat \usepackage[utf8]{inputenc} \usepackage[T1]{fontenc} % Times New Roman font for body text % Arial font for section headlines. The font can be installed % with ftp://tug.org/tex/getnonfreefonts/install-getnonfreefonts utility %\usepackage[scaled]{uarial} \renewcommand*{\familydefault}{\sfdefault} \newcommand{\IVXVArial}{\fontfamily{phv} \selectfont} % Commands for setting the document type, number, version, etc. \newcommand{\IVXVDefineDocumentType}[1]{\def\@IVXVStringDocumentType{#1}} \newcommand{\IVXVDefineDocumentNumber}[1]{\def\@IVXVDocumentNumber{#1}} \newcommand{\IVXVDefineDocumentVersion}[1]{\def\@IVXVDocumentVersion{#1}} \newcommand{\IVXVDefineDocumentSecurity}[1]{\renewcommand{\@IVXVStringConfidential}{#1}} \newcommand{\IVXVDefineAcknowledgement}[1]{\def\@IVXVAcknowledgement{#1}} \newcommand{\IVXVDefineCopyrightFooter}[1]{\renewcommand{\@IVXVStringCopyrightFooter}{#1}} \newcommand{\IVXVDefineBackofTitlePage}[1]{\renewcommand{\@IVXVStringBackofTitlePage}{#1}} % .. and initialize them to empty \IVXVDefineDocumentNumber{} \global\let\@IVXVDocumentNumber\@empty \IVXVDefineDocumentVersion{} \global\let\@IVXVDocumentVersion\@empty \IVXVDefineAcknowledgement{} \global\let\@IVXVAcknowledgement\@empty % Pagestyle with headers and footers \setlength{\headwidth}{\textwidth} \makepagestyle{IVXVFancy} \makerunningwidth{IVXVFancy}{\headwidth} % No indent of paragraphs \setlength{\parindent}{0pt} \setlength{\parskip}{1.5ex} % TODO: Single command for this? \makeoddhead{IVXVFancy}{}{}{ \IVXVArial \tiny \@IVXVStringConfidential} \makeevenhead{IVXVFancy}{}{}{ \IVXVArial \tiny \@IVXVStringConfidential} \makeoddfoot{IVXVFancy}{ \IVXVArial {\tiny {\bfseries \hspace{-0.75em}\@title} \\ \@date}} {} { \IVXVArial {\tiny \@IVXVDocumentVersion \\ \thepage\ / \pageref{LastPage}}} \makeevenfoot{IVXVFancy}{ \IVXVArial {\tiny {\bfseries \hspace{-0.75em}\@title} \\ \@date}} {} { \IVXVArial {\tiny \@IVXVDocumentVersion \\ \thepage\ / \pageref{LastPage}}} \makefootrule{IVXVFancy}{\headwidth}{\normalrulethickness}{0pt} % We have multiline headers, therefore less space is available % for text. \addtolength{\footskip}{2mm} % Enforce pagestyle for pages with new chapters as well \aliaspagestyle{chapter}{IVXVFancy} % Set the new style as the default \pagestyle{IVXVFancy} % Titlepage style with headings \makepagestyle{IVXVTitle} \makerunningwidth{IVXVTitle}{\headwidth} \makeoddhead{IVXVTitle}{ \begin{minipage}[t]{0.5\textwidth} \hspace{-7mm} \end{minipage} }{}{ \raisebox{2.5mm}{\IVXVArial \scriptsize \bfseries \@IVXVStringConfidential} } % Chapter and section headline style \renewcommand{\printchapternum}{\LARGE \bfseries \IVXVArial \thechapter} \renewcommand{\printchaptertitle}[1]{\LARGE \bfseries \IVXVArial #1} \setlength{\beforechapskip}{60pt} \setlength{\afterchapskip}{40pt} \let\stdchapter\chapter \renewcommand\chapter{\clearpage\ \stdchapter} \setsecheadstyle{\normalsize \bfseries \IVXVArial} \setsubsecheadstyle{\normalsize \bfseries \IVXVArial} \setsubsubsecheadstyle{\IVXVArial} \usepackage{graphicx} % title page \makeatletter \renewcommand{\maketitle}{% \thispagestyle{IVXVTitle} % \vspace{2cm} \begin{minipage}[t]{0.5\textwidth} %\vspace{-6.5mm} %\hfill \vspace{31mm} \end{minipage} \vspace{4cm} \begin{flushleft} \IVXVArial {\LARGE \bfseries \@title} \vfill {\Large \bfseries \@IVXVStringDocumentType \ifx\@IVXVDocumentVersion\@empty Dok. versiooninumber defineerimata. Kasuta IVXVDefineDocumentVersion käsku või IVXV-Document-Version stiili. \else \@IVXVStringVersion~\@IVXVDocumentVersion \fi \@date \pageref{LastPage} \@IVXVStringPages\\[1.5ex] \ifx\@IVXVDocumentNumber\@empty Dok. hoidla ning järjenumber defineerimata. Kasuta IVXVDefineDocumentNumber käsku või IVXV-Document-Number stiili. \else \@IVXVStringDocument~\@IVXVDocumentNumber \fi }\par \vspace{2cm} {\scriptsize \@IVXVAcknowledgement} \end{flushleft} \pagebreak % \thispagestyle{empty} % \@IVXVStringBackofTitlePage % \cleardoublepage } \makeatother % Make dots appear in the table of contents also for chapters \renewcommand{\cftchapterdotsep}{\cftdotsep} % URL formating, URL breaking and linked entries in the PDF \usepackage{url} %%% XXX remove breakurl % \usepackage{breakurl} %%% XXX \usepackage[pdfborder={0 0 0}, pdftex, pdfpagelayout=TwoPageRight]{hyperref} % hyperref and memoir is incompatible, this fixes the problems \usepackage{memhfixc} % make enumerate and itemize lists tighter \firmlists % and change the numbering for nested lists \renewcommand{\labelenumi}{\arabic{enumi}.} \renewcommand{\labelenumii}{\arabic{enumi}.\arabic{enumii}} \renewcommand{\labelenumiii}{\arabic{enumi}.\arabic{enumii}.\arabic{enumiii}} \renewcommand{\labelenumiv}{\arabic{enumi}.\arabic{enumii}.\arabic{enumiii}.\arabic{enumiii}.\arabic{enumiv}} % make LaTeX observe right margins at all costs: \sloppy ================================================ FILE: Documentation/ivxv-technical/ivxv-technical.cls ================================================ % ivxv-technical.cls \ProvidesClass{ivxv-technical} \DeclareOption*{\PassOptionsToClass{\CurrentOption}{ivxv-common}} \ProcessOptions\relax \LoadClass{ivxv-common} ================================================ FILE: Documentation/ivxv-technical/pandoc-extras.sty ================================================ % Style for pandoc generated latex output, related with docbook format. % It's needed for special formatting and may be only needed for docbook, % so probably you don't need this (e.g. for markdown -> latex conversion). % Highlighting \usepackage{framed} \usepackage{color} \usepackage{fancyvrb} \newcommand{\VerbBar}{|} \newcommand{\VERB}{\Verb[commandchars=\\\{\}]} \DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}} \newenvironment{Shaded}{\begin{shaded}}{\end{shaded}} \definecolor{shadecolor}{gray}{0.9} \newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}} \newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}} \newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} \newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} \newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}} \newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{{#1}}} \newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} \newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} \newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} \newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}} \newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{{#1}}} \newcommand{\ImportTok}[1]{{#1}} \newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}} \newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{{#1}}}} \newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}} \newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}} \newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}} \newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}} \newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{{#1}}} \newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}} \newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{{#1}}} \newcommand{\BuiltInTok}[1]{{#1}} \newcommand{\ExtensionTok}[1]{{#1}} \newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{{#1}}} \newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{{#1}}} \newcommand{\RegionMarkerTok}[1]{{#1}} \newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}} \newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}} \newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} \newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}} \newcommand{\NormalTok}[1]{{#1}} ================================================ FILE: Documentation/podl/.gitignore ================================================ venv/ ================================================ FILE: Documentation/podl/podl.py ================================================ #!/usr/bin/env python3 # IVXV Internet voting framework """PO translator with Deepl Translate PO files with Deepl Usage: podl --input --api [options] podl -h | --help podl -v | --version Options: -h --help Request for help -v --version Show version information -i --input Input file or directory -s --source Source language [default: ET] -t --target Target language [default: EN-GB] -f --force Actually use API --fuzzy Override fuzzy translations [default: False] -a --api Deepl API token """ import os import deepl import polib from docopt import docopt from schema import Or, Schema, SchemaError class Translator: def __init__(self, api, source, target, force): self.__translator = deepl.Translator(api) self.__source_lang = source self.__target_lang = target self.__force = force def translate(self, source_msg): if self.__force: return str(self.__translator.translate_text( source_msg, source_lang = self.__source_lang, target_lang = self.__target_lang )) return None def process_file(filename, translator, fuzzy): po = polib.pofile(filename) print(f"File {filename} is {po.percent_translated()}% translated") for entry in po.untranslated_entries(): if not entry.msgstr: newmsg = translator.translate(entry.msgid) if newmsg is not None: entry.msgstr = newmsg po.save(filename) if fuzzy: for entry in po.fuzzy_entries(): newmsg = translator.translate(entry.msgid) if newmsg is not None: entry.msgstr = newmsg po.save(filename) po.save(filename) if __name__ == '__main__': ARGS = docopt(__doc__, version='Deepl PO translator 1.0') SCHEMA = Schema({ '--input': Or(os.path.isdir, os.path.isfile), '--source': str, '--target': str, '--api': str, '--force': bool, '--fuzzy': bool, '--help': Or(False), '--version': Or(False) }) try: ARGS = SCHEMA.validate(ARGS) except SchemaError as err: exit(err) INPUT = ARGS['--input'] DEEPL = Translator( ARGS['--api'], ARGS['--source'], ARGS['--target'], ARGS['--force']) if os.path.isfile(INPUT): process_file(INPUT, DEEPL, ARGS['--fuzzy']) elif os.path.isdir(INPUT): for root, dirs, files in os.walk(INPUT): for file in files: if file.endswith(".po"): file_path = os.path.join(root, file) process_file(file_path, DEEPL, ARGS['--fuzzy']) else: pass ================================================ FILE: Documentation/podl/requirements.in ================================================ # We depend on pip-tools being installed to venv. # # Add dependencies to this file # pip-compile to update requirements.txt # pip-sync to update venv docopt==0.6.2 schema==0.7.7 polib==1.2.0 deepl==1.19.1 ================================================ FILE: Documentation/podl/requirements.txt ================================================ # # This file is autogenerated by pip-compile with Python 3.10 # by the following command: # # pip-compile requirements.in # certifi==2024.8.30 # via requests charset-normalizer==3.4.0 # via requests deepl==1.19.1 # via -r requirements.in docopt==0.6.2 # via -r requirements.in idna==3.10 # via requests polib==1.2.0 # via -r requirements.in requests==2.32.3 # via deepl schema==0.7.7 # via -r requirements.in urllib3==2.2.3 # via requests ================================================ FILE: Documentation/public/arhitektuur/Makefile ================================================ include ../../common.mk ================================================ FILE: Documentation/public/arhitektuur/etcd.rst ================================================ .. IVXV arhitektuur Lisa - ETCD Andmemudel ====================== ETCD on võti-väärtus andmebaas, kus talletatakse e-hääletamise sisendnimekirju, e-hääli ning statistikat. Ringkondade nimekiri -------------------- .. table:: Ringkondade nimekiri :widths: 30 35 35 +----------------------------+---------------------------+-----------------------+ | **Võti** | **Väärtus** | **Näide** | +============================+===========================+=======================+ | /districts | Juurvõti | | +----------------------------+---------------------------+-----------------------+ | /districts/ | Seab valija | /districts/05241 | | | EHAK-ringkond paarile | | | | vastavusse | 0000.1 | | | ringkonnaidentifikaatori, | | | | mis viitab /choices | | | | harusse | | +----------------------------+---------------------------+-----------------------+ | /districts/counties | Väli counties | { | | | ringkondade | | | | nimekirjast | "0068": [ | | | | | | | | "0809", | | | | | | | | "0624" | | | | | | | | ], | | | | | | | | "0784": [ | | | | | | | | "0524" | | | | | | | | ], | | | | | | | | "0079": [ | | | | | | | | "0796" | | | | | | | | ], | | | | | | | | "0793": [ | | | | | | | | "0793" | | | | | | | | ] | | | | | | | | } | +----------------------------+---------------------------+-----------------------+ | /districts/version | Nimekirja | ["NIMESTE,NIMI,123456 | | | allkirjastajad | 78912 | | | | 2019-02-22T13:58:48Z" | | | | ] | +----------------------------+---------------------------+-----------------------+ Valikute nimekiri ----------------- .. table:: Valikute nimekiri :widths: 30 35 35 +------------------------+-----------------------+-----------------------+ | **Võti** | **Väärtus** | **Näide** | +========================+=======================+=======================+ | /choices | Juurvõti | | +------------------------+-----------------------+-----------------------+ | /choices/ | Ringkonnale | /choices/0000.1 | | | district-id vastav | | | | valikute nimekiri. | { | | | | | | | | "Erakond 1":{ | | | | | | | | "0000.101":"Nimi | | | | Nimeste1", | | | | | | | | "0000.102":"Nimi | | | | Nimeste2", | | | | | | | | "0000.103":"Nimi | | | | Nimeste3" | | | | | | | | }, | | | | | | | | "Erakond 2":{ | | | | | | | | "0000.104":"Nimi | | | | Nimeste4", | | | | | | | | "0000.105":"Nimi | | | | Nimeste5" | | | | | | | | }, | | | | | | | | "Üksikkandidaadid":{ | | | | | | | | "0000.106":"Nimi | | | | Nimeste6" | | | | | | | | } | | | | | | | | } | +------------------------+-----------------------+-----------------------+ | /choices/version | Nimekirja | ["NIMESTE,NIMI,123456 | | | allkirjastajad | 78912 | | | | 2019-02-22T13:58:59Z" | | | | ] | +------------------------+-----------------------+-----------------------+ Valijate nimekiri ----------------- .. table:: Valijate nimekiri :widths: 30 35 35 +---------------------------------+-----------------------+-----------------------+ | **Võti** | **Väärtus** | **Näide** | +=================================+=======================+=======================+ | /voters | Juurvõti | | +---------------------------------+-----------------------+-----------------------+ | /voters/ | Valijanimekirja | /voters/1 | | | versiooni juurvõti | | +---------------------------------+-----------------------+-----------------------+ | /voters// | Valija | /voters/1/12345678912 | | | antud | | | | nimekirjas | 05241 | +---------------------------------+-----------------------+-----------------------+ | /voters//version | Valijatenimekirja | ["NIMESTE,NIMI,123456 | | | versioon | 78912 | | | | 2019-02-22T13:58:59Z" | | | | ] | +---------------------------------+-----------------------+-----------------------+ | /voters/version | Aktuaalse | 1 | | | valijatenimekirja | | | | versiooni ID | | +---------------------------------+-----------------------+-----------------------+ | /voters/previous | Eelmise | 0 | | | valijanimekirja | | | | versiooni ID | | +---------------------------------+-----------------------+-----------------------+ Talletatud e-hääl ----------------- .. table:: Talletatud e-hääl :widths: 30 35 35 +-------------------------+------------------------+-----------------------+ | **Võti** | **Väärtus** | **Näide** | +=========================+========================+=======================+ | /vote | Juurvõti | | +-------------------------+------------------------+-----------------------+ | /vote/ | Hääle juurvõti, | 16 baiti binaarandmed | | | unikaalne | | | | identifikaator | | +-------------------------+------------------------+-----------------------+ | /vote//count | Hääle kontrollimise | 0 | | | loendur | | +-------------------------+------------------------+-----------------------+ | /vote//ocsp | Kehtivuskinnitus | DER kodeeringus OCSP | | | | vastus | +-------------------------+------------------------+-----------------------+ | /vote//time | Hääle talletamise | 2019-03-03T10:56:28.8 | | | kellaaeg | 99925926Z | +-------------------------+------------------------+-----------------------+ | /vote//tspreg | Registreerimiskinnitus | DER kodeeringus PKIX | | | | ajatempel | +-------------------------+------------------------+-----------------------+ | /vote//type | Allkirjastatud hääle | BDOC | | | konteineri tüüp | | +-------------------------+------------------------+-----------------------+ | /vote//version | Hääle andmisel | 0 | | | kehtinud valijate | | | | nimekirja versiooni | | | | ID | | +-------------------------+------------------------+-----------------------+ | /vote//vote | E-hääl allkirjastatud | BDOC vormingus | | | konteineris | allkirjastatud hääl | +-------------------------+------------------------+-----------------------+ | /vote//voter | Valija isikukood | 12345678912 | +-------------------------+------------------------+-----------------------+ Statistikaliidesed ------------------ .. table:: Statistikaliidesed :widths: 30 35 35 +-------------------------------+-----------------------+-----------------------+ | **Võti** | **Väärtus** | **Näide** | +===============================+=======================+=======================+ | /votes | Juurvõti | | +-------------------------------+-----------------------+-----------------------+ | /votes/order | Hääletamisfaktide | | | | järjestuse juurvõti | | +-------------------------------+-----------------------+-----------------------+ | /votes/order/ | Konkreetse | /votes/order/1 | | | hääletamisfakti | | | | juurvõti | | +-------------------------------+-----------------------+-----------------------+ | /votes/order//admincode | Hääletamisfaktiga | 0796 | | | seotud EHAK | | +-------------------------------+-----------------------+-----------------------+ | /votes/order//district | Hääletamisfaktiga | 10 | | | seotud ringkonna | | | | number | | +-------------------------------+-----------------------+-----------------------+ | /votes/order//voterid | Hääletaja isikukood | 12345678901 | | | | | +-------------------------------+-----------------------+-----------------------+ | /votes/order//votername | Hääletaja nimi | NIMI NIMESTE | | | | | +-------------------------------+-----------------------+-----------------------+ | /votes/stats | Viimase | 12 | | | hääletamisfakti | | | | järjekorranumber | | +-------------------------------+-----------------------+-----------------------+ | /voted | Juurvõti | | +-------------------------------+-----------------------+-----------------------+ | /voted/latest | Viimati antud häälte | | | | indeksi juurvõti | | +-------------------------------+-----------------------+-----------------------+ | /voted/latest/ | Hääletaja poolt | /voted/latest/1234567 | | | viimati antud hääle | 8901 | | | aeg ja identifikaator | | | | binaarkujul | <2019-03-03T12:15:59Z | | | | > | +-------------------------------+-----------------------+-----------------------+ | /voted/stats | Jaoskonnapõhise | | | | statistika indeksi | | | | juurvõti | | +-------------------------------+-----------------------+-----------------------+ | /voted/stats/ | Hääle andmise | /voted/stats/12345678 | | | kellaaeg koos | 901 | | | jaoskonnainfoga | | | | | <0796><2019-02-22T14: | | | | 17:23Z> | +-------------------------------+-----------------------+-----------------------+ | /votes/voter/stats/ | Tühi baitide massiiv | /votes/voter/stats/ | | | (kasutatakse väärtuse | 394091044211 | | | versiooni, ning mitte | | | | väärtust ennast) | | +-------------------------------+-----------------------+-----------------------+ Hääletamisseansid ----------------- .. table:: Hääletamisseansid :widths: 30 35 35 +-----------------------+-----------------------+---------------------------+ | **Võti** | **Väärtus** | **Näide** | +=======================+=======================+===========================+ | /session | Juurvõti | | +-----------------------+-----------------------+---------------------------+ | /session/ | RPC meetod, mis | ``/session/0149468d2866`` | | | kutsus antud | ``6fced7d73b32cc16225d`` | | | funktsiooni välja + | | | | ``x1F`` + kasutaja | | | | autentimismeetod | | +-----------------------+-----------------------+---------------------------+ ================================================ FILE: Documentation/public/arhitektuur/index.rst ================================================ .. IVXV arhitektuur IVXV arhitektuur ======================================================== .. raw:: html

NB! See on HTML-versioon dokumendist. Tellijale antakse üle PDF-versioon.

.. toctree:: :maxdepth: 3 :numbered: yldpohimotted kogumisteenus vallasrezhiim tehnoloogiad etcd viited ================================================ FILE: Documentation/public/arhitektuur/kogumisteenus.rst ================================================ .. IVXV arhitektuur Kogumisteenus ============= Üldkirjelduse [ÜK2016]_ põhjal on Kogumisteenus: .. epigraph:: Süsteemi keskne komponent, mida käitab Koguja. Teenus abistab Hääletajat e-hääle koostamisel ning registreerib selle enne salvestamist e-valimiskasti. Kogumisteenus kasutab väliseid teenuseid (tuvastamine, allkirjastamine, registreerimine). Kogumisteenusel on peale Koguja enda teisigi haldureid (Korraldaja, Klienditugi), kelle jaoks on Kogumisteenusel eraldi haldusliidesed. Kogumisteenus töötab sidusrežiimis ning vähemalt valija- ja kontrollrakenduse suunalised liidesed on avatud internetile. Seega töötleb Kogumisteenus potentsiaalselt ebausaldusväärsest allikast pärit päringuid. Tulenevalt tarkvarale seatavast turvatasemest, kõrgkäideldavuse, skaleeritavuse, kihilise evitatavuse ning laiendatavuse nõuetest on kogumisteenus omakorda liigendatud ühte konkreetset teenust osutavateks mikroteenusteks, mida on võimalik paindlikult evitada. Kõik kogumisteenuse komponendid programmeeritakse keeles `Go `_. Keelel Go on: - staatiline tüüpimine, mis võimaldab tüübivigade avastamist enne programmi käivitamist; - automaatne mäluhaldus, mis välistab rakenduse vigasest mäluhaldusest tulenevad turvaaugud; - kompilaator avatud lähtekoodiga; - ribastamine/rööprapse, mis võimaldab kasutada paralleelsust mitmetuumalistes süsteemides. Kogumisteenuse andmeedastuseks kasutatakse üldjuhul JSON-vormingut, välja arvatud olukordades, kus välised asjaolud tingivad mõne muu andmevormingu kasutamist (näiteks BDOC-vorming põhineb XML'il). Kogumisteenus toetab Riigikogu valimisi, kohaliku omavalitsuse volikogu valimisi, Euroopa parlamendi valimisi ning rahvahääletusi. Kogumisteenuse komponendid arvestavad virtualiseerimistehnoloogiate kasutamisega ning kogumisteenust on võimalik evitada nii ühel virtuaalriistvara instantsil, kui ka mikroteenuste kaupa erinevatel instantsidel. Kogumisteenuse komponendid on evitatavad Ubuntu 22.04 LTS (Jammy Jellyfish) operatsioonisüsteemil 64-bitisel arhitektuuril. Andmesäilitus on teostatud kasutades võti-väärtus andmebaasi (etcd). Testotstarbel on teostatud ka andmesäilitus failisüsteemi ning mällu, kuid neid ei ole soovituslik kasutada tootekeskkonnas. Lisaks on kogumisteenusel olemas liides uute talletusprotokollide lisamiseks. Lõplik otsus kasutatava lahenduse kohta tehakse kogumisteenuse haldurite poolt teenust seadistades. Mikroteenused ------------- .. figure:: model/img/collector_microservices.png Kogumisteenuse jaotus mikroteenusteks Kogumisteenus on jaotatud põhiteenusteks ja abiteenusteks. Põhiteenused - vahendusteenus, nimekirjateenus, hääletamisteenus, kontrollteenus ning talletamisteenus - on arhitektuuri tehnilise lihtsuse mõttes piiritletud ühe valimisega, kuid ühel riistvaral, ühe operatsioonisüsteemi kontekstis võivad käia mitme valimise mikroteenused. Täiendavalt võib kogumisteenuse juures kasutada abiteenuseid - tuvastusteenust hääletaja isiku tuvastamiseks ning allkirjateenust valijarakenduse poolt hääle allkirjastamise hõlbustamiseks. Teenuseid on võimalik evitada nii eraldatult kui koos erinevates konfiguratsioonides, mis teeb võimalikuks kihilise arhitektuuri. Lähtudes funktsioonist on otstarbekas hoida Vahendus- ning Talletamisteenused teistest eraldi. Teenused kasutavad transpordiprotokollina TLS'i, ühendused on vähemalt serveripoolselt autenditud. Rakenduskihi protokoll on JSON-RPC. Kõik teenused tekitavad tegevuslogi, mida säilitatakse nii lokaalselt kui logitakse syslog protokolli vahendusel kesksesse logikogujasse. Vahendusteenuse funktsioon ja tehniline liides `````````````````````````````````````````````` Vahendusteenuse põhifunktsioon on ühe sisenemispunkti (port 443) pakkumine Valijarakendusele ja Kontrollrakendusele. Vahendusteenus on dispetšerteenus teiste komponentide vahel, mis võimaldab sisemiselt evitada kogumisteenust mikroteenustena, ent omada süsteemil ainult ühte sisenemispunkti. Lisaks suudab see dubleeritud evituse puhul täita koormusjaoturi ülesannet. Vahendusteenus ei termineeri TLS-ühendust vaid kasutab sihtpunkti tuvastamiseks TLS'i *Server Name Indication* (SNI) laiendust. Kliendid panevad TLS ``ClientHello`` sõnumisse SNI-laiendi, kus avatekstis määravad, millise teenusega soovivad suhelda: vahendusteenus näeb seda, võtab ühendust vastavat teenust pakkuva isendiga ja hakkab kliendi ning teenuse vahelisi sõnumeid vahendama. Vahendusteenus EI termineeri TLS'i ning ei näe sõnumite sisu. Vahendusteenusel on andmed kõigi teiste teenuste asukohtadest (aadress:port) ning teenus vahendab sõnumivahetust kõigi osapoolte vahel. Vahendusteenus on olekuvaba komponent, mida on võimalik horisontaalselt skaleerida. Vahendusteenuse teostus ''''''''''''''''''''''' Vahendusteenuse teostus kasutab vabavaralist HAProxy serverit, mis on üldlevinud tarkvaraline koormusjaotur ja proksi. Kuna Vahendusteenus on esimene puutepunkt avalikust internetist tulevate ühenduste jaoks, siis on mõistlik kasutada tarkvara, mille töökindlus on juba tõestatud. Kuigi HAProxyt kasutatakse tihti HTTP-režiimis, kus see analüüsib liiklust, siis vahendusteenuse rollis on see TCP-režiimis ning ei näe vahendatava krüpteeritud TLS-kanali sisse. IVXV seadistusest genereeritakse HAProxy seadistusfail, mis sisaldab teiste teenuste asukohti, ning ühenduste vahendamise ülesanne jääb viimase kanda. Lisaks on võimalik HAProxyt ka seadistada ühenduste sagedusi piirama lähteaadressi või mõne muu nimetaja põhjal. See aga jääb süsteemihalduri ülesandeks. Kuigi HAProxy on võimeline ise teostama koormusjaoturi ülesannet, on seda võimalik evitada ka teiste, potentsiaalselt riistvaraliste koormusjaoturite taha, kus see jääb täitma ainult SNI põhjal vahendamise ülesannet. HAProxy lähtekood on avalik ja sobiva litsentsiga ning pakendatud kogumisteenuse alusplatvormi ametlikus hoidlas (vt. :ref:`tehnoloogiad`). Nimekirjateenuse funktsioon ja tehniline liides ``````````````````````````````````````````````` Nimekirjateenuse põhifunktsioon on valikute nimekirjade vahendamine Valijarakendusele. Nimekirjateenusesse jõuab informatsioon tuvastatud valija kohta ning Nimekirjateenus väljastab valija ringkonnale vastava valikute nimekirja Talletamisteenusest Valijarakendusse. Nimekirjateenus on olekuvaba komponent, mida on võimalik horisontaalselt skaleerida. Kontrollteenuse funktsioon ja tehniline liides `````````````````````````````````````````````` Kontrollteenuse põhifunktsioon on kontrollpäringute töötlemine ning kontrollitava hääle väljastamine Talletamisteenusest Kontrollrakendusse. Kontrollteenus on olekuvaba komponent, mida on võimalik horisontaalselt skaleerida. Hääletamisteenuse funktsioon ja tehniline liides ```````````````````````````````````````````````` Hääletamisteenuse põhifunktsioon on hääletamispäringute töötlemine. Hääletamisteenus verifitseerib sissetuleva hääle, registreerib selle Registreerimisteenuses ning talletab Talletamisteenusesse. Hääletamisteenus on olekuvaba komponent, mida on võimalik horisontaalselt skaleerida. Talletamisteenuse funktsioon ja tehniline liides ````````````````````````````````````````````````` Talletamisteenuse põhifunktsioon on valikute ja valijanimekirjade ning häälte pikaajaline talletamine. Talletamisteenuse horisontaalseks skaleerimiseks kasutatakse hajustalletamist võimaldavat säilitustehnoloogiat. Talletamisteenuse teostus ''''''''''''''''''''''''' Talletamisteenus ei ole teadlik IVXV protokollist ega talletatavate andmete spetsiifikast, vaid on üldkasutatav võti-väärtus andmebaas binaarandmete säilitamiseks. Kogu teadmus talletatavate andmete struktuurist ja võtmete hierarhiast on teistes, Talletamisteenust kasutatavates teenustes, mis käituvad nii-öelda "tarkade" klientidena. Selline lähenemine lubab ilma suurema vaevata kasutada Talletamisteenusena ükskõik millist üldlevinud võti-väärtus andmebaasi: ainsateks ülesanneteks on IVXV seadistuse teisendamine andmebaasi jaoks sobilikku vormingusse ning teenuse käivitamine. Andmebaasi tarkvara peab võimaldama vaid võtme järgi talletamist ja lugemist, võtmete prefiksi järgi loetlemist ning atomaarset võrdle-ja-vaheta (*compare-and-swap*) operatsiooni. Talletamisteenus on kogumisteenuse töökiiruse oluliseks määrajaks, mistõttu mõjutab seda teenust pakkuv riistvara kogu süsteemi jõudlust ning see tuleks vastavalt kasutatavale andmebaasile dimensioneerida. Hetkel ainus tooteks mõeldud Talletamisteenuse teostus kasutab hajusat võti-väärtus andmebaasi etcd. Selle puhul tuleks järgida etcd autorite `riistvara soovitusi `_. Tuvastusteenuse funktsioon ja tehniline liides `````````````````````````````````````````````` Tuvastusteenuse põhifunktsioon on valija identiteedi tuvastamine. Tuvastusteenus on vajalik näiteks Mobiil-ID autentimise korral. Web-eID abiteenuse teostus '''''''''''''''''''''''''' IVXV koosseisu kuulub Web-eID abiteenus, mis realiseerib Tuvastusteenuse ID-kaardi kasutamiseks Web-eID raamistikus. Eduka Web-eID isikutuvastuse korral väljastab abiteenus Valijarakendusele pileti, mille abil on võimalik teistele teenustele valija identiteeti kinnitada. Iga piletiga saab hääletada ainult ühe korra. Web-eID ei paku allkirjateenust, hääle allkirjastamine toimub Valija seadmes lokaalselt analoogselt klassikalisele ID-kaardiga autentimisele/allkirjastamisele. Web-eID abiteenus on olekuvaba komponent. Tänu sellele on võimalik Web-eID abiteenust horisontaalselt skaleerida. Allkirjateenuse funktsioon ja tehniline liides `````````````````````````````````````````````` Allkirjateenuse funktsioon on Valijarakenduse toetamine hääle allkirjastamisel. Allkirjateenus on vajalik näiteks Mobiil-ID allkirjastamise korral. Mobiil-ID abiteenuse teostus '''''''''''''''''''''''''''' IVXV koosseisu kuulub Mobiil-ID abiteenus, mis käitub Mobiil-ID jaoks nii Tuvastusteenusena kui ka Allkirjateenusena. Valijarakendus esitab IVXV päringud Mobiil-ID abiteenusele, mis teisendab need Mobiil-ID päringuteks ning edastab Mobiil-ID teenusepakkujale. Eduka Mobiil-ID isikutuvastuse korral väljastab abiteenus Valijarakendusele pileti, mille abil on võimalik teistele teenustele valija identiteeti kinnitada. Iga piletiga saab hääletada ainult ühe korra. Allkirjastamise korral saadab Valijarakendus Mobiil-ID abiteenusele vaid allkirjastatava hääle räsi ning kasutab vastuseks saadud signatuuri samamoodi kui ID-kaardiga loodud signatuuri. Mobiil-ID abiteenus sisaldab küll olekut pooleliolevate tuvastusseansside kohta, aga muus osas on tegu olekuvaba komponendiga. Tänu sellele on võimalik Mobiil-ID abiteenust horisontaalselt skaleerida. Smart-ID abiteenuse teostus ''''''''''''''''''''''''''' IVXV koosseisu kuulub Smart-ID abiteenus, mis käitub Smart-ID jaoks nii Tuvastusteenusena kui ka Allkirjateenusena. Valijarakendus esitab IVXV päringud Smart-ID abiteenusele, mis teisendab need Smart-ID päringuteks ning edastab Smart-ID teenusepakkujale. Eduka Smart-ID isikutuvastuse korral väljastab abiteenus Valijarakendusele pileti, mille abil on võimalik teistele teenustele valija identiteeti kinnitada. Iga piletiga saab hääletada ainult ühe korra. Allkirjastamise korral saadab Valijarakendus Smart-ID abiteenusele vaid allkirjastatava hääle räsi ning kasutab vastuseks saadud signatuuri samamoodi kui ID-kaardiga loodud signatuuri. Smart-ID abiteenus sisaldab küll olekut pooleliolevate tuvastusseansside kohta, aga muus osas on tegu olekuvaba komponendiga. Tänu sellele on võimalik Smart-ID abiteenust horisontaalselt skaleerida. Hääletamisfaktide järjekorrateenus `````````````````````````````````` Hääletamisfaktide järjekorrateenuse põhifunktsiooniks on hääletamisfaktide edastamine Valimiste Infosüsteemile X-tee abiteenuse vahendusel. Kogumisteenuse mikroteenuste evitamine `````````````````````````````````````` Kogumisteenuse mikroteenused sõltuvad välistest pakkidest minimaalselt. Vajalikud sõltuvused on: #. SSH-server haldustegevuste läbiviimiseks (seda kasutab mikroteenuste haldamiseks haldusteenus). #. rsyslog logide kogumiseks logikogumisteenustesse. Kogumisteenuse mikroteenused pakendatakse deb-vormingus, neid on võimalik evitada ka docker'i-laadsete konteineritena. Välised teenused ja laiendatavus -------------------------------- .. figure:: model/img/collector_extension.png Kogumisteenuse laiendusmoodulid ja välised teenused Kogumisteenuse mikroteenused kasutavad laiendusmooduleid teostamaks erinevaid mehhanisme valija tuvastamiseks, digiallkirjade verifitseerimiseks ja täiendamiseks, sealhulgas hääle registreerimiseks. Laiendusmoodulid võivad teostuse võimaldamiseks kasutada väliseid teenuseid. Mikroteenuste laiendatavuse huvides on defineeritud Go API, mille alusel saab teostada ka täiendavaid mooduleid. Hetkel on teostatud järgmised moodulid: - Autentimine TLS-sertifikaadiga (ID-kaart); - Autentimine Tuvastusteenuse piletiga (Mobiil-ID, Smart-ID, Web-eID); - BDOC verifitseerimine; - Kehtivuskinnitusteenus OCSP; - Ajatempliteenus RFC 3161; - Registreerimisteenus OCSP; - Registreerimisteenus RFC 3161. IVXV krüptograafilises protokollis on kesksel kohal Registreerimisteenus, mis osaleb samuti häälte pikaajalisel talletamisel. Registreerimisteenuse funktsioon ```````````````````````````````` Registreerimisteenuse põhifunktsioon on võtta Hääletamisteenuselt vastu allkirjastatud registreerimispäringuid, kinnitada need omapoolse allkirjastatud vastusega ning säilitada hilisemaks auditeerimiseks vähemalt hääletamisperioodi lõpuni. Auditeerimisel tekkivate võimalike erisuste lahendamiseks on oluline, et - Registreerimisteenus on võimeline tõestama, et igale tema poolt väljastatud kinnitusele eelnes Talletamisteenuse poolne registreerimispäring; - Talletamisteenus on võimeline tõestama, et iga tema poolt talletatud hääle kohta on olemas Registreerimisteenuse kinnitus. Piisav protokoll sellise tõendamistaseme saavutamiseks on, kus mõlemal osapoolel on olemas võtmepaar allkirjastamiseks, päringud ja vastused on allkirjastatud ning kumbki pool peab registrit teise poole teadete üle. Selline protokoll on realiseeritav näiteks OCSP-põhise Registreerimisteenuse korral. Samas võib esineda juhtumeid, kus näiteks registreerimispäringute allkirjastamine ei ole standardsete vahenditega võimalik (RFC 3161 põhine registreerimine). Sellisel juhul tuleb registreerimisteenusele vajalik tõendusmaterjal anda muude organisatsioonilis-tehniliste vahenditega. Registreerimisteenusel on praegu kaks erinevat teostust: #. OCSP-liides eeldab Eestis rakendatava OCSP-põhise ajamärgendamisteenuse kasutamist, kus allkirjastatud OCSP-päringu nonsiks on Hääletamisteenuse poolt pandud hääle räsi. Päring on allkirjastatud standardsete OCSP vahenditega; #. RFC 3161 liides, mille korral ebastandardse lahendusena pannakse ajatemplipäringu nonsiks Hääletamisteenuse poolt allkirjastatud hääle räsi. Kogumisteenuse laiendusmoodulite lisamine ````````````````````````````````````````` Kogumisteenuse API defineerib kuute tüüpi laiendusmooduleid: #. isikutuvastus (Go pakk ``ivxv.ee/auth``, näiteks ``tls``); #. tuvastatud isiku sertifikaadist valija identifikaatori tuletamine (Go pakk ``ivxv.ee/identity``, näiteks ``serialnumber``); #. valija identifikaatorist vanuse tuletamine (Go pakk ``ivxv.ee/age``, näiteks ``estpic``); #. allkirjastatud konteineri verifitseerimine (Go pakk ``ivxv.ee/container``, näiteks ``bdoc``); #. allkirja kvalifitseerimine (Go pakk ``ivxv.ee/q11n``, näiteks ``tspreg``); #. andmetalletusprotokoll (Go pakk ``ivxv.ee/storage``, näiteks ``etcd``). Uue mooduli lisamiseks tuleb moodulpakki lisada mooduli identifikaator ning mooduli teostusega alampakk. Alampaki alglaadimisel tuleb mooduli registreerimiseks kutsuda välja moodulpaki ``Register`` funktsioon. Uue mooduli kasutamiseks tuleb selle identifikaator lisada seadistusse vastava moodulitüübi seadistuse juurde koos alammooduli seadistusega. Laiendusmoodulile antakse ette tema identifikaatoriga viidatud seadistusblokk, mida see mooduli-siseselt edasi töötleb. Moodulpakid ja nende moodulitelt nõutavad liidesed on täpsemalt kirjeldatud vastavates lähtekoodifailides. Samuti on iga mooduli kohta olemas vähemalt üks teostus, mida saab kasutada eeskujuna. Monitooring ----------- .. figure:: model/img/monitoring.png Monitooringulahendus Logimine ```````` Iga mikroteenuse poolt genereeritav logi defineeritakse süstemaatiliselt, lähtudes protokollikirjeldusest ning teenuse osutamise olekudiagrammist. Logitakse minimaalselt: * iga päringu kättesaamise fakt ning töötlemise algus; * töötlemise üleandmine välisele komponendile; * töötlemisjärje naasmine komponenti; * päringu töötlemise lõpp ning tulemus; * täiendavalt oluliste etappide läbimine protsessi olekumudelis. Logimisel järgitakse järgmisi põhimõtteid: * Logimiseks kasutatakse rsyslog teenust, mis registreerib logiteate kirjutamise hetke millisekundi täpsusega; * Iga seansi alustamisel genereerib süsteem unikaalse identifikaatori, mida klientrakendus kasutab oma päringutel kesksüsteemi poole pöördumiseks; * Kõik ühe seansi alla kuuluvad logikirjed sisaldavad sama seansiidentifikaatorit; * Logikirje on unikaalselt identifitseeritav; * Iga logitava teate juures on võimalik unikaalse tunnuse abil üksüheselt tuvastada teate tekkimise koht monitooritavas süsteemis; * Logikirje on JSON vormingus, automaatse monitooringu jaoks on masinloetavus primaarne ning inimloetavus sekundaarne; * Logisse minev info saneeritakse (urlencode) ja sellele rakendatakse pikkuse piirangut (piirang terve logiteate ja samuti parameetri kaupa); * Süsteemiperimeetrist väljastpoolt pärinevat infot logitakse ainult saneerituna ja ainult etteantud pikkuses. Kuna logimine toimub rsyslog vahendusel, on võimalik Guardtime mooduli kasutamine logide tervikluse tagamiseks. Üldstatistika ````````````` Järgmise statistika jälgimiseks kasutatakse staatilist veebiliidest: * edukalt kogutud hääled/hääletajate hulk; * hääletajate jagunemine sugude, vanusegruppide, operatsioonisüsteemide ning autentimisvahendite kaupa; * edukalt kontrollitud häälte/hääletajate hulk; * korduvhääletamiste statistika; * hääletajate jagunemine riigiti IP-aadressi põhjal. Detailstatistika ```````````````` Detailstatistika agregeeritakse logide põhjal kasutades SCCEIV logianalüsaatorit, mis analüüsib rakenduste tegevuslogi eeldefineeritud profiili suhtes ning võimaldab seansi-/veatüübipõhist analüüsi. Detailstatistika on kättesaadav üle HTTPS-liidese. .. _kogumisteenuse-haldus: Haldus ------ Kogumisteenuse haldamine toimub digitaalallkirjastatud seadistuspakkide abil. Kogumisteenus pakub seadistuspakkide laadimiseks kahte liidest: * Käsurealiides – rakendus verifitseerib allkirja, valideerib korralduste vormingut, kooskõlalisust ja sobivust kogumisteenuse seisundi suhtes. Korralduse rakendamine toimub eraldi utiliidi abil. * Veebiliides – veebiliides vahendab seadistuspaki käsurealiidesele ja tagastab kasutajale info laadimise tulemuse kohta. Eduka laadimise korral toimub automaatselt ja samadel põhimõtetel ka seadistuspaki rakendamine. Veebiliidese funktsioonideks on: * Kogumisteenuse mikroteenuste seisundi jälgimine; * Valimiste nimekirjade haldus; * Statistika kuvamine e-hääletamise kulgemise kohta; * Haldusteenuse kasutajate haldus; * Kogumisteenuse halduse logi kuvamine. Kõik rakendusele antud korraldused säilitatakse - ka need mida ei rakendatud. Vigaseid (mittevalideeruvaid) korraldusi ei säilitata. Kogumisteenuse haldusteenus sooritab järgmisi tegevusi automaatselt: #. Valijate nimekirjade muudatuste laadimine Valimiste Infosüsteemist; #. Hääletamise statistika kogumine hääletusteenusest ja eksportimine Valimiste Infosüsteemi; #. Talletatud häälte, logide ning seadistuste varundamine varundusteenusesse. Haldusteenuse komponendid ````````````````````````` .. figure:: model/img/ms-management-service-components.png Kogumisteenuse haldusteenuse komponendid #. **Halduse veebiserver** on süsteemse kasutaja ``www-data`` õigustes töötav Apache server, mille ülesanded on: #. Kasutajatelt tulevate HTTPS-päringute esmane teenindamine: #. Haldusteenuse usaldusväärsuse tõestamine (TLS-sertifikaat); #. Kasutajate autentimine; #. Valmisgenereeritud veebilehtede ja andmefailide serveerimine andmehoidlast. #. Üldiste taustaandmete päringu vastuse varustamine sisseloginud kasutaja andmetega (WSGI). #. Üleslaaditavate korralduste esmane valideerimine ja vahendamine haldusdeemonile ning haldusdeemoni sellekohaste vastuste vahendamine kliendile (WSGI). #. **Haldusdeemon** on kasutajakonto ``ivxv-admin`` õigustes töötav ja kohalikul (``localhost``) liidesel kuulav veebiserver mille ülesanded on: #. Üleslaaditavate korralduste valideerimine; #. Üleslaaditavate korralduste vahetu rakendamine (kasutajate haldus); #. Üleslaaditavate korralduste salvestamine hilisemaks rakendamiseks (seadistuse ja valimisnimekirjade rakendamiseks teenusele); #. E-valimiskasti allalaadimise vahendamine. #. **Agentdeemon** on kasutajakonto ``ivxv-admin`` õigustes töötav deemon, mille ülesanded on: #. Andmete kogumine ja registreerimine: #. Teadaolevate mikroteenuste seisund; #. Tegevusmonitooringu statistika allalaadimine; #. **Andmehoidla** on failisüsteemis asuv kataloog, kuhu haldusteenuse komponendid hoiavad kogutud ja genereeritud andmeid (vaata üksikasjalist kirjeldust ``IVXV kogumisteenuse haldusjuhendi`` lisadest); Välised komponendid, millega haldusteenus kokku puutub: #. **Kogumisteenuse alamteenused** - paigaldamine, seadistamine ja seisundi andmete kogumine toimub agentdeemoni kaudu (SSH-ühendus teenuse masinasse); #. **Seireserver** - üldstatistika andmete allalaadimine haldusteenuses kuvamiseks; .. figure:: model/img/ms-upload-command.png Korralduste laadimine haldusteenusesse Kogumisteenuse seisundid ------------------------ Kogumisteenuse seisund kajastab teenuse kõigi alamteenuste seisundit, kasutuselolevate väliste teenuste seisundit ja eelneva põhjal tuletatud üldseisundit. Kogumisteenuse üldseisundi tuvastamisega tegeleb haldusteenus. Üldseisundi olekud on: #. **Paigaldamata** - alates haldusteenuse paigaldamisest kuni kõigi alamteenuste paigaldamiseni; #. **Paigaldatud** - kõik alamteenused on paigaldatud, neile on rakendatud tehnilised seadistused ja teenuse toimimiseks vajalikud krüptovõtmed. Valimiste seadistust pole rakendatud (kuid see võib olla laaditud haldusteenusesse); #. **Seadistatud** - kogumisteenus on seadistatud ja töökorras, sellega on võimalik häälte kogumist läbi viia ja e-valimiskasti väljastada. #. **Osaline tõrge** - kogumisteenus on seadistatud ja osaliselt töökorras, mõned alamteenused pole töökorras, kuid see ei takista kogumisteenuse toimimist. #. **Tõrge** - kogumisteenuse oluline sõlm pole töökorras, teenuse nõuetekohane osutamine pole võimalik. .. figure:: model/img/ms-collector-status.png :scale: 50% Kogumisteenuse olekudiagramm. Olekud vastavalt värvusele: kollane - seadistamisel, punane - viga, roheline - töökorras. Kogumisteenuse alamteenuste seisundid ````````````````````````````````````` .. figure:: model/img/ms-service-status.png :scale: 50% Haldusteenuse poolt registreeritud alamteenuse olekudiagramm. Olekud vastavalt värvusele: kollane - seadistamisel, punane - viga, roheline - töökorras. Kogumisteenuse seisundi muutused ```````````````````````````````` Kogumisteenuse seisund on jälgitav alates haldusteenuse edukast paigaldamisest, algne seisund on **Paigaldamata**. Paigaldamata '''''''''''' Toimub usaldusjuure ja tehnilise seadistuse rakendamine kogumisteenusele: #. Seadistuste laadimine kogumisteenusesse; #. Tehnilises seadistuses kirjeldatud alamteenuste paigaldus; #. Usaldusjuure ja tehniliste seadistuste rakendamine alamteenustele; Seadistuste eduka rakendamise tulemusena saab süsteemi uueks seisundiks **Paigaldatud**. Paigaldatud ''''''''''' Kogumisteenuse seadistused on rakendatud kõigile alamteenustele, valimiste seadistused pole rakendatud. Toimub valimiste seadistuse laadimine haldusteenusesse ja rakendamine alamteenustele. Valimiste seadistuse eduka rakendamise korral saab süsteemi uueks seisundiks **Seadistatud**. Seadistatud ''''''''''' Kõik kogumisteenuse alamteenused on seadistatud ja töökorras. Haldusteenusel on kõikidest alamteenustest värsked seisundiraportid. Süsteemiga on võimalik hääletust läbi viia ja e-valimiskasti väljastada. Kui süsteemis tuvastatakse tõrge, saab süsteemi uueks **Osaline tõrge**. **Seadistatud** olekust ei pöörduta enam kunagi tagasi olekutesse **paigaldamata** või **paigaldatud**, kuigi uute alamteenuste lisamisel (kuni need on olekus **paigaldamata/paigaldatud**) oleks vastavad tingimused täidetud. Osaline tõrge ''''''''''''' Süsteem on seadistatud ja osaliselt töökorras, mõned süsteemi dubleeritud osad pole töökorras, kuid see ei takista süsteemil toimimast. Rikke süvenemisel piirini, kus süsteem pole võimeline teenust osutama, saab süsteemi uueks olekuks **Tõrge**. Kõigi rikete kõrvaldamise järel saab süsteemi uueks olekuks **Seadistatud**. Tõrge ''''' Seadistatud süsteemil on tuvastatud rike, mis takistab teenuse osutamist. Rikete kõrvaldamisel olukorrani, kus süsteemiga on võimalik teenust osutada, saab süsteemi uueks olekuks **Osaline tõrge**. Eemaldatud '''''''''' Teenus on konfiguratsioonist eemaldatud. Valijate nimekirjade olekud haldusteenuses ------------------------------------------ Valijate nimekirja olek võib olla: #. **Rakendamise ootel** - nimekiri on laaditud haldusteenusesse; #. **Rakendatud** - nimekiri on rakendatud kogumisteenusele; #. **Vigane** - nimekiri on märgitud vigaseks, haldusteenus uusi valijate nimekirjade muudatusi ei laadi; #. **Vahele jäetud** - vigane nimekiri on märgitud vahelejätmiseks. .. figure:: model/img/ms-voter-list-status.png Valijate nimekirja olekudiagramm Siirdeprotsessid: #. Nimekirja laadimine haldusteenusesse: Algnimekirja laadib kogumisteenuse operaator, nimekirja olekuks saab **Rakendamise ootel**; Muudatusnimekirja laadib haldusteenus. Vastavalt valideerimise tulemusele saab nimekirja olekuks kas **Rakendamise ootel** või **Vigane**; #. **Rakendamine kogumisteenusele**: viib läbi haldusteenus **rakendamise ootel** olekus nimekirjaga. Õnnestumisel määratakse nimekirja olekuks **Rakendatud**, vea korral **Vigane**; #. **Vahelejätmine**: operaator määrab olekuga **Vigane** nimekirjale oleku **Vahele jäetud**. ================================================ FILE: Documentation/public/arhitektuur/locales/en/LC_MESSAGES/etcd.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 15:28+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../etcd.rst:4 msgid "Lisa - ETCD Andmemudel" msgstr "Appendix - ETCD datamodel" #: ../../etcd.rst:6 msgid "" "ETCD on võti-väärtus andmebaas, kus talletatakse e-hääletamise " "sisendnimekirju, e-hääli ning statistikat." msgstr "" "ETCD is key-value database used for storing input lists, votes and " "statistics of online voting" #: ../../etcd.rst:10 ../../etcd.rst:12 msgid "Ringkondade nimekiri" msgstr "List of districts" #: ../../etcd.rst:16 ../../etcd.rst:70 ../../etcd.rst:123 ../../etcd.rst:155 #: ../../etcd.rst:196 ../../etcd.rst:258 msgid "**Võti**" msgstr "**Key**" #: ../../etcd.rst:16 ../../etcd.rst:70 ../../etcd.rst:123 ../../etcd.rst:155 #: ../../etcd.rst:196 ../../etcd.rst:258 msgid "**Väärtus**" msgstr "**Value**" #: ../../etcd.rst:16 ../../etcd.rst:70 ../../etcd.rst:123 ../../etcd.rst:155 #: ../../etcd.rst:196 ../../etcd.rst:258 msgid "**Näide**" msgstr "**Example**" #: ../../etcd.rst:18 msgid "/districts" msgstr "/districts" #: ../../etcd.rst:18 ../../etcd.rst:72 ../../etcd.rst:125 ../../etcd.rst:157 #: ../../etcd.rst:198 ../../etcd.rst:224 ../../etcd.rst:260 msgid "Juurvõti" msgstr "Rootkey" #: ../../etcd.rst:20 msgid "/districts/" msgstr "/districts/" #: ../../etcd.rst:20 msgid "" "Seab valija EHAK-ringkond paarile vastavusse ringkonnaidentifikaatori, " "mis viitab /choices harusse" msgstr "" "Connects voter's EHAK-district pair with district identifier referring to" " the /choices branch" #: ../../etcd.rst:20 msgid "/districts/05241" msgstr "/districts/05241" #: ../../etcd.rst:22 msgid "0000.1" msgstr "0000.1" #: ../../etcd.rst:27 msgid "/districts/counties" msgstr "/districts/counties" #: ../../etcd.rst:27 msgid "Väli counties ringkondade nimekirjast" msgstr "Field counties from the district list" #: ../../etcd.rst:27 ../../etcd.rst:76 msgid "{" msgstr "{" #: ../../etcd.rst:29 msgid "\"0068\": [" msgstr "\"0068\": [" #: ../../etcd.rst:31 msgid "\"0809\"," msgstr "\"0809\"," #: ../../etcd.rst:33 msgid "\"0624\"" msgstr "\"0624\"" #: ../../etcd.rst:35 ../../etcd.rst:41 ../../etcd.rst:47 msgid "]," msgstr "]," #: ../../etcd.rst:37 msgid "\"0784\": [" msgstr "\"0784\": [" #: ../../etcd.rst:39 msgid "\"0524\"" msgstr "\"0524\"" #: ../../etcd.rst:43 msgid "\"0079\": [" msgstr "\"0079\": [" #: ../../etcd.rst:45 msgid "\"0796\"" msgstr "\"0796\"" #: ../../etcd.rst:49 msgid "\"0793\": [" msgstr "\"0793\": [" #: ../../etcd.rst:51 msgid "\"0793\"" msgstr "\"0793\"" #: ../../etcd.rst:53 msgid "]" msgstr "]" #: ../../etcd.rst:55 ../../etcd.rst:106 ../../etcd.rst:108 msgid "}" msgstr "}" #: ../../etcd.rst:57 msgid "/districts/version" msgstr "/districts/version" #: ../../etcd.rst:57 ../../etcd.rst:110 msgid "Nimekirja allkirjastajad" msgstr "Signers of lists" #: ../../etcd.rst:57 msgid "[\"NIMESTE,NIMI,123456 78912 2019-02-22T13:58:48Z\" ]" msgstr "[\"NIMESTE,NIMI,123456 78912 2019-02-22T13:58:48Z\" ]" #: ../../etcd.rst:64 ../../etcd.rst:66 msgid "Valikute nimekiri" msgstr "Choices list" #: ../../etcd.rst:72 msgid "/choices" msgstr "/choices" #: ../../etcd.rst:74 msgid "/choices/" msgstr "/choices/" #: ../../etcd.rst:74 msgid "Ringkonnale district-id vastav valikute nimekiri." msgstr "Choices list corresponding to district-id" #: ../../etcd.rst:74 msgid "/choices/0000.1" msgstr "/choices/0000.1" #: ../../etcd.rst:78 msgid "\"Erakond 1\":{" msgstr "\"Party 1\":{" #: ../../etcd.rst:80 msgid "\"0000.101\":\"Nimi Nimeste1\"," msgstr "\"0000.101\":\"Nimi Nimeste1\"," #: ../../etcd.rst:83 msgid "\"0000.102\":\"Nimi Nimeste2\"," msgstr "\"0000.102\":\"Nimi Nimeste2\"," #: ../../etcd.rst:86 msgid "\"0000.103\":\"Nimi Nimeste3\"" msgstr "\"0000.103\":\"Nimi Nimeste3\"" #: ../../etcd.rst:89 ../../etcd.rst:99 msgid "}," msgstr "}," #: ../../etcd.rst:91 msgid "\"Erakond 2\":{" msgstr "\"Party 2\":{" #: ../../etcd.rst:93 msgid "\"0000.104\":\"Nimi Nimeste4\"," msgstr "\"0000.104\":\"Nimi Nimeste4\"," #: ../../etcd.rst:96 msgid "\"0000.105\":\"Nimi Nimeste5\"" msgstr "\"0000.105\":\"Nimi Nimeste5\"" #: ../../etcd.rst:101 msgid "\"Üksikkandidaadid\":{" msgstr "\"Independent candidates\":{" #: ../../etcd.rst:103 msgid "\"0000.106\":\"Nimi Nimeste6\"" msgstr "\"0000.106\":\"Nimi Nimeste6\"" #: ../../etcd.rst:110 msgid "/choices/version" msgstr "/choices/version" #: ../../etcd.rst:110 ../../etcd.rst:134 msgid "[\"NIMESTE,NIMI,123456 78912 2019-02-22T13:58:59Z\" ]" msgstr "[\"NIMESTE,NIMI,123456 78912 2019-02-22T13:58:59Z\" ]" #: ../../etcd.rst:117 ../../etcd.rst:119 msgid "Valijate nimekiri" msgstr "Voterlist" #: ../../etcd.rst:125 msgid "/voters" msgstr "/voters" #: ../../etcd.rst:127 msgid "/voters/" msgstr "/voters/" #: ../../etcd.rst:127 msgid "Valijanimekirja versiooni juurvõti" msgstr "Rootkey of voterlist version" #: ../../etcd.rst:127 msgid "/voters/1" msgstr "/voters/1" #: ../../etcd.rst:130 msgid "/voters//" msgstr "/voters//" #: ../../etcd.rst:130 msgid "Valija antud nimekirjas" msgstr "Voter in the list" #: ../../etcd.rst:130 msgid "/voters/1/12345678912" msgstr "/voters/1/12345678912" #: ../../etcd.rst:132 msgid "05241" msgstr "05241" #: ../../etcd.rst:134 msgid "/voters//version" msgstr "/voters//version" #: ../../etcd.rst:134 msgid "Valijatenimekirja versioon" msgstr "Voterlist version" #: ../../etcd.rst:139 msgid "/voters/version" msgstr "/voters/version" #: ../../etcd.rst:139 msgid "Aktuaalse valijatenimekirja versiooni ID" msgstr "ID of latest voterlist" #: ../../etcd.rst:139 msgid "1" msgstr "1" #: ../../etcd.rst:143 msgid "/voters/previous" msgstr "/voters/previous" #: ../../etcd.rst:143 msgid "Eelmise valijanimekirja versiooni ID" msgstr "ID of previous voterlist" #: ../../etcd.rst:143 ../../etcd.rst:163 ../../etcd.rst:178 msgid "0" msgstr "0" #: ../../etcd.rst:149 ../../etcd.rst:151 msgid "Talletatud e-hääl" msgstr "Stored i-vote" #: ../../etcd.rst:157 msgid "/vote" msgstr "/vote" #: ../../etcd.rst:159 msgid "/vote/" msgstr "/vote/" #: ../../etcd.rst:159 msgid "Hääle juurvõti, unikaalne identifikaator" msgstr "Rootkey of a vote, unique identifier" #: ../../etcd.rst:159 msgid "16 baiti binaarandmed" msgstr "16 bytes binary" #: ../../etcd.rst:163 msgid "/vote//count" msgstr "/vote//count" #: ../../etcd.rst:163 msgid "Hääle kontrollimise loendur" msgstr "Vote verification counter" #: ../../etcd.rst:166 msgid "/vote//ocsp" msgstr "/vote//ocsp" #: ../../etcd.rst:166 msgid "Kehtivuskinnitus" msgstr "Proof-of-validity" #: ../../etcd.rst:166 msgid "DER kodeeringus OCSP vastus" msgstr "DER encoded OCSP response" #: ../../etcd.rst:169 msgid "/vote//time" msgstr "/vote//time" #: ../../etcd.rst:169 msgid "Hääle talletamise kellaaeg" msgstr "Time of the vote storage" #: ../../etcd.rst:169 msgid "2019-03-03T10:56:28.8 99925926Z" msgstr "2019-03-03T10:56:28.8 99925926Z" #: ../../etcd.rst:172 msgid "/vote//tspreg" msgstr "/vote//tspreg" #: ../../etcd.rst:172 msgid "Registreerimiskinnitus" msgstr "Registration confirmation" #: ../../etcd.rst:172 msgid "DER kodeeringus PKIX ajatempel" msgstr "DER encoded PKIX timestamp" #: ../../etcd.rst:175 msgid "/vote//type" msgstr "/vote//type" #: ../../etcd.rst:175 msgid "Allkirjastatud hääle konteineri tüüp" msgstr "Type of signed container" #: ../../etcd.rst:175 msgid "BDOC" msgstr "BDOC" #: ../../etcd.rst:178 msgid "/vote//version" msgstr "/vote//version" #: ../../etcd.rst:178 msgid "Hääle andmisel kehtinud valijate nimekirja versiooni ID" msgstr "ID of the voterlist valid at the time of voting" #: ../../etcd.rst:183 msgid "/vote//vote" msgstr "/vote//vote" #: ../../etcd.rst:183 msgid "E-hääl allkirjastatud konteineris" msgstr "I-vote in signed container" #: ../../etcd.rst:183 msgid "BDOC vormingus allkirjastatud hääl" msgstr "Vote in BDOC format" #: ../../etcd.rst:186 msgid "/vote//voter" msgstr "/vote//voter" #: ../../etcd.rst:186 msgid "Valija isikukood" msgstr "Voter personal code" #: ../../etcd.rst:186 msgid "12345678912" msgstr "12345678912" #: ../../etcd.rst:190 ../../etcd.rst:192 msgid "Statistikaliidesed" msgstr "Statisticinterfaces" #: ../../etcd.rst:198 msgid "/votes" msgstr "/votes" #: ../../etcd.rst:200 msgid "/votes/order" msgstr "/votes/order" #: ../../etcd.rst:200 msgid "Hääletamisfaktide järjestuse juurvõti" msgstr "Rootkey of votesorder" #: ../../etcd.rst:203 msgid "/votes/order/" msgstr "/votes/order/" #: ../../etcd.rst:203 msgid "Konkreetse hääletamisfakti juurvõti" msgstr "Rootkey of specific vote" #: ../../etcd.rst:203 msgid "/votes/order/1" msgstr "/votes/order/1" #: ../../etcd.rst:207 msgid "/votes/order//admincode" msgstr "/votes/order//admincode" #: ../../etcd.rst:207 msgid "Hääletamisfaktiga seotud EHAK" msgstr "EHAK associated with vote" #: ../../etcd.rst:207 msgid "0796" msgstr "0796" #: ../../etcd.rst:210 msgid "/votes/order//district" msgstr "/votes/order//district" #: ../../etcd.rst:210 msgid "Hääletamisfaktiga seotud ringkonna number" msgstr "District associated with vote" #: ../../etcd.rst:210 msgid "10" msgstr "10" #: ../../etcd.rst:214 msgid "/votes/order//voterid" msgstr "/votes/order//voterid" #: ../../etcd.rst:214 msgid "Hääletaja isikukood" msgstr "Personal code" #: ../../etcd.rst:214 msgid "12345678901" msgstr "12345678901" #: ../../etcd.rst:217 msgid "/votes/order//votername" msgstr "/votes/order//votername" #: ../../etcd.rst:217 msgid "Hääletaja nimi" msgstr "Voter name" #: ../../etcd.rst:217 msgid "NIMI NIMESTE" msgstr "NIMI NIMESTE" #: ../../etcd.rst:220 msgid "/votes/stats" msgstr "/votes/stats" #: ../../etcd.rst:220 msgid "Viimase hääletamisfakti järjekorranumber" msgstr "Sequence number of last vote" #: ../../etcd.rst:220 msgid "12" msgstr "12" #: ../../etcd.rst:224 msgid "/voted" msgstr "/voted" #: ../../etcd.rst:226 msgid "/voted/latest" msgstr "/voted/latest" #: ../../etcd.rst:226 msgid "Viimati antud häälte indeksi juurvõti" msgstr "Rootkey of last vote index" #: ../../etcd.rst:229 msgid "/voted/latest/" msgstr "/voted/latest/" #: ../../etcd.rst:229 msgid "Hääletaja poolt viimati antud hääle aeg ja identifikaator binaarkujul" msgstr "The time and identifier of the last vote in binary" #: ../../etcd.rst:229 msgid "/voted/latest/1234567 8901" msgstr "/voted/latest/1234567 8901" #: ../../etcd.rst:232 msgid "<2019-03-03T12:15:59Z >" msgstr "<2019-03-03T12:15:59Z >" #: ../../etcd.rst:235 msgid "/voted/stats" msgstr "/voted/stats" #: ../../etcd.rst:235 msgid "Jaoskonnapõhise statistika indeksi juurvõti" msgstr "Station statistics rootkey" #: ../../etcd.rst:239 msgid "/voted/stats/" msgstr "/voted/stats/" #: ../../etcd.rst:239 msgid "Hääle andmise kellaaeg koos jaoskonnainfoga" msgstr "Time of voting with station info" #: ../../etcd.rst:239 msgid "/voted/stats/12345678 901" msgstr "/voted/stats/12345678 901" #: ../../etcd.rst:242 msgid "<0796><2019-02-22T14: 17:23Z>" msgstr "<0796><2019-02-22T14: 17:23Z>" #: ../../etcd.rst:245 msgid "/votes/voter/stats/" msgstr "/votes/voter/stats/" #: ../../etcd.rst:245 msgid "" "Tühi baitide massiiv (kasutatakse väärtuse versiooni, ning mitte väärtust" " ennast)" msgstr "Empty array - we use the version of the value, not value itself" #: ../../etcd.rst:245 msgid "/votes/voter/stats/ 394091044211" msgstr "/votes/voter/stats/ 394091044211" #: ../../etcd.rst:252 ../../etcd.rst:254 msgid "Hääletamisseansid" msgstr "Voting sessions" #: ../../etcd.rst:260 msgid "/session" msgstr "/session" #: ../../etcd.rst:262 msgid "/session/" msgstr "/session/" #: ../../etcd.rst:262 msgid "" "RPC meetod, mis kutsus antud funktsiooni välja + ``x1F`` + kasutaja " "autentimismeetod" msgstr "RPC method called + ``x1F`` + authentication method" #: ../../etcd.rst:262 msgid "``/session/0149468d2866`` ``6fced7d73b32cc16225d``" msgstr "``/session/0149468d2866`` ``6fced7d73b32cc16225d``" ================================================ FILE: Documentation/public/arhitektuur/locales/en/LC_MESSAGES/index.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:35+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" #: ../../index.rst:4 msgid "IVXV arhitektuur" msgstr "IVXV architecture" ================================================ FILE: Documentation/public/arhitektuur/locales/en/LC_MESSAGES/kogumisteenus.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 15:28+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../kogumisteenus.rst:4 msgid "Kogumisteenus" msgstr "Collection service" #: ../../kogumisteenus.rst:6 msgid "Üldkirjelduse [ÜK2016]_ põhjal on Kogumisteenus:" msgstr "Based on the general description [ÜK2016]_, the Collection Service is:" #: ../../kogumisteenus.rst:10 msgid "" "Süsteemi keskne komponent, mida käitab Koguja. Teenus abistab Hääletajat " "e-hääle koostamisel ning registreerib selle enne salvestamist " "e-valimiskasti. Kogumisteenus kasutab väliseid teenuseid (tuvastamine, " "allkirjastamine, registreerimine). Kogumisteenusel on peale Koguja enda " "teisigi haldureid (Korraldaja, Klienditugi), kelle jaoks on " "Kogumisteenusel eraldi haldusliidesed." msgstr "" "The central component of the system, operated by the Collector. The " "service assists the Voter in compiling the e-Vote and registers the vote before" " storing it in the digital ballotbox. The Collection Service makes use of" " external services (authentication, signing, registration). In addition " "to the Collector, the Collection Service has other administrators " "(Organiser, Customer Support) for which the Collection Service has " "separate administrative interfaces." #: ../../kogumisteenus.rst:17 msgid "" "Kogumisteenus töötab sidusrežiimis ning vähemalt valija- ja " "kontrollrakenduse suunalised liidesed on avatud internetile. Seega " "töötleb Kogumisteenus potentsiaalselt ebausaldusväärsest allikast pärit " "päringuid. Tulenevalt tarkvarale seatavast turvatasemest, " "kõrgkäideldavuse, skaleeritavuse, kihilise evitatavuse ning laiendatavuse" " nõuetest on kogumisteenus omakorda liigendatud ühte konkreetset teenust " "osutavateks mikroteenusteks, mida on võimalik paindlikult evitada." msgstr "" "The collection service works in online mode and at least the interfaces " "to the voter and the verification application are open to the internet. " "Thus, the Collection Service processes queries from potentially " "unreliable sources. In turn, due to the security level, high " "availability, scalability, deployment and extensibility requirements of " "the software, the Collection Service is broken down into microservices " "providing one specific service, which can be flexibly extensible." #: ../../kogumisteenus.rst:25 msgid "" "Kõik kogumisteenuse komponendid programmeeritakse keeles `Go " "`_. Keelel Go on:" msgstr "" "All collection service components are programmed in `Go " "`_. The language Go is:" #: ../../kogumisteenus.rst:28 msgid "" "staatiline tüüpimine, mis võimaldab tüübivigade avastamist enne programmi" " käivitamist;" msgstr "" "static typing, which allows typing errors to be detected before the " "program is run;" #: ../../kogumisteenus.rst:31 msgid "" "automaatne mäluhaldus, mis välistab rakenduse vigasest mäluhaldusest " "tulenevad turvaaugud;" msgstr "" "automatic memory management, which eliminates security holes caused by " "incorrect memory management in the application;" #: ../../kogumisteenus.rst:34 msgid "kompilaator avatud lähtekoodiga;" msgstr "open source compiler;" #: ../../kogumisteenus.rst:36 msgid "" "ribastamine/rööprapse, mis võimaldab kasutada paralleelsust " "mitmetuumalistes süsteemides." msgstr "goroutines, allowing parallelism to be used in multi-CPU systems." #: ../../kogumisteenus.rst:39 msgid "" "Kogumisteenuse andmeedastuseks kasutatakse üldjuhul JSON-vormingut, välja" " arvatud olukordades, kus välised asjaolud tingivad mõne muu " "andmevormingu kasutamist (näiteks BDOC-vorming põhineb XML'il)." msgstr "" "The JSON format will generally be used for the data transmission of the " "collection service, except in situations where external circumstances " "dictate the use of another data format (for example, the BDOC format is " "based on XML)." #: ../../kogumisteenus.rst:43 msgid "" "Kogumisteenus toetab Riigikogu valimisi, kohaliku omavalitsuse volikogu " "valimisi, Euroopa parlamendi valimisi ning rahvahääletusi." msgstr "" "The collection service supports elections to the Riigikogu, local council" " elections, European Parliament elections and referendums." #: ../../kogumisteenus.rst:46 msgid "" "Kogumisteenuse komponendid arvestavad virtualiseerimistehnoloogiate " "kasutamisega ning kogumisteenust on võimalik evitada nii ühel " "virtuaalriistvara instantsil, kui ka mikroteenuste kaupa erinevatel " "instantsidel. Kogumisteenuse komponendid on evitatavad Ubuntu 22.04 LTS " "(Jammy Jellyfish) operatsioonisüsteemil 64-bitisel arhitektuuril." msgstr "" "The collection service components take into account the use of " "virtualisation technologies and the collection service can be hosted on a" " single virtual hardware instance or on a microservice-by-microservice " "basis on different instances. The collection service components are " "executable on Ubuntu 22.04 LTS (Jammy Jellyfish) operating system on " "64-bit architecture." #: ../../kogumisteenus.rst:52 msgid "" "Andmesäilitus on teostatud kasutades võti-väärtus andmebaasi (etcd). " "Testotstarbel on teostatud ka andmesäilitus failisüsteemi ning mällu, " "kuid neid ei ole soovituslik kasutada tootekeskkonnas. Lisaks on " "kogumisteenusel olemas liides uute talletusprotokollide lisamiseks. " "Lõplik otsus kasutatava lahenduse kohta tehakse kogumisteenuse haldurite " "poolt teenust seadistades." msgstr "" "Data storage is performed using a key-value database (etcd). For testing " "purposes, data storage on the file system and in memory has also been " "implemented, but is not recommended for use in the production " "environment. In addition, the collection service has an interface for " "adding new storage protocols. The final decision on the solution to be " "used will be made by the collection administrators when configuring the " "service." #: ../../kogumisteenus.rst:59 msgid "Mikroteenused" msgstr "Microservices" #: ../../kogumisteenus.rst:63 msgid "Kogumisteenuse jaotus mikroteenusteks" msgstr "Breakdown of collection service into microservices" #: ../../kogumisteenus.rst:65 msgid "" "Kogumisteenus on jaotatud põhiteenusteks ja abiteenusteks. Põhiteenused -" " vahendusteenus, nimekirjateenus, hääletamisteenus, kontrollteenus ning " "talletamisteenus - on arhitektuuri tehnilise lihtsuse mõttes piiritletud " "ühe valimisega, kuid ühel riistvaral, ühe operatsioonisüsteemi kontekstis" " võivad käia mitme valimise mikroteenused. Täiendavalt võib " "kogumisteenuse juures kasutada abiteenuseid - tuvastusteenust hääletaja " "isiku tuvastamiseks ning allkirjateenust valijarakenduse poolt hääle " "allkirjastamise hõlbustamiseks." msgstr "" "The collection service is broken down into basic and helper services. The" " basic services - dispatcher, choice-list, voting, verification and " "storage - are limited to a single election for the sake of technical " "simplicity of the architecture, but multiple election microservices can " "run on a single hardware, in the context of a single operating system. In" " addition, the collection service may use helper services - an " "authentication service to authenticate the voter, and a signature service" " to facilitate the signing of the vote by the voting application." #: ../../kogumisteenus.rst:73 msgid "" "Teenuseid on võimalik evitada nii eraldatult kui koos erinevates " "konfiguratsioonides, mis teeb võimalikuks kihilise arhitektuuri. Lähtudes" " funktsioonist on otstarbekas hoida Vahendus- ning Talletamisteenused " "teistest eraldi." msgstr "" "Services can be provided both separately and together in different " "configurations, enabling a layered architecture. Based on the function, " "it makes sense to keep the dispatcher and storage services separate from " "each other." #: ../../kogumisteenus.rst:78 msgid "" "Teenused kasutavad transpordiprotokollina TLS'i, ühendused on vähemalt " "serveripoolselt autenditud. Rakenduskihi protokoll on JSON-RPC." msgstr "" "The services use TLS as transport protocol, all connections are at least " "server-side authenticated. The application layer protocol is JSON-RPC." #: ../../kogumisteenus.rst:81 msgid "" "Kõik teenused tekitavad tegevuslogi, mida säilitatakse nii lokaalselt kui" " logitakse syslog protokolli vahendusel kesksesse logikogujasse." msgstr "" "All services generate an activity log, which is both stored locally and " "logged via the syslog protocol to a central log collector." #: ../../kogumisteenus.rst:85 msgid "Vahendusteenuse funktsioon ja tehniline liides" msgstr "Dispatcher service function and technical interface" #: ../../kogumisteenus.rst:87 msgid "" "Vahendusteenuse põhifunktsioon on ühe sisenemispunkti (port 443) " "pakkumine Valijarakendusele ja Kontrollrakendusele. Vahendusteenus on " "dispetšerteenus teiste komponentide vahel, mis võimaldab sisemiselt " "evitada kogumisteenust mikroteenustena, ent omada süsteemil ainult ühte " "sisenemispunkti. Lisaks suudab see dubleeritud evituse puhul täita " "koormusjaoturi ülesannet." msgstr "" "The main function of the Dispatcher Service is to provide a single entry " "point (port 443) to the Voting Application and the Verification " "Application. The Dispatcher Service is dispatching between other " "components, allowing the collection service to be provided internally as " "microservices, but with only one entry point on the system. In addition, " "it is able to act as a load balancer in the case of distributed " "deployment." #: ../../kogumisteenus.rst:93 msgid "" "Vahendusteenus ei termineeri TLS-ühendust vaid kasutab sihtpunkti " "tuvastamiseks TLS'i *Server Name Indication* (SNI) laiendust. Kliendid " "panevad TLS ``ClientHello`` sõnumisse SNI-laiendi, kus avatekstis " "määravad, millise teenusega soovivad suhelda: vahendusteenus näeb seda, " "võtab ühendust vastavat teenust pakkuva isendiga ja hakkab kliendi ning " "teenuse vahelisi sõnumeid vahendama. Vahendusteenus EI termineeri TLS'i " "ning ei näe sõnumite sisu. Vahendusteenusel on andmed kõigi teiste " "teenuste asukohtadest (aadress:port) ning teenus vahendab sõnumivahetust " "kõigi osapoolte vahel." msgstr "" "The dispatcher service does not terminate the TLS connection but uses the" " TLS *Server Name Indication* (SNI) extension to identify the " "destination. Clients put an SNI extension in the TLS ``ClientHello`` " "message, where they specify in the plain text which service they wish to " "communicate with: the dispatcher service sees this, contacts the host " "providing the corresponding service and starts dispatching messages " "between the client and the service. The dispatcher service does NOT " "terminate the TLS and does not see the content of the messages. The " "dispatcher service has information about the locations of all other " "services (address:port) and mediates the messaging between all parties." #: ../../kogumisteenus.rst:102 msgid "" "Vahendusteenus on olekuvaba komponent, mida on võimalik horisontaalselt " "skaleerida." msgstr "" "The dispatcher service is a stateless component that can be scaled " "horizontally." #: ../../kogumisteenus.rst:106 msgid "Vahendusteenuse teostus" msgstr "Implementation of the dispatcher service" #: ../../kogumisteenus.rst:108 msgid "" "Vahendusteenuse teostus kasutab vabavaralist HAProxy serverit, mis on " "üldlevinud tarkvaraline koormusjaotur ja proksi. Kuna Vahendusteenus on " "esimene puutepunkt avalikust internetist tulevate ühenduste jaoks, siis " "on mõistlik kasutada tarkvara, mille töökindlus on juba tõestatud." msgstr "" "The dispatcher service is implemented using the freeware HAProxy server, " "which is a ubiquitous software load balancer and proxy. As the Dispatcher" " Service is the first point of contact for connections from the public " "Internet, it makes sense to use software that is already proven to be " "reliable." #: ../../kogumisteenus.rst:113 msgid "" "Kuigi HAProxyt kasutatakse tihti HTTP-režiimis, kus see analüüsib " "liiklust, siis vahendusteenuse rollis on see TCP-režiimis ning ei näe " "vahendatava krüpteeritud TLS-kanali sisse." msgstr "" "While HAProxy is often used in HTTP mode, where it analyses traffic, in " "the role of a proxy service it is in TCP mode and does not see into the " "encrypted TLS channel being proxied." #: ../../kogumisteenus.rst:117 msgid "" "IVXV seadistusest genereeritakse HAProxy seadistusfail, mis sisaldab " "teiste teenuste asukohti, ning ühenduste vahendamise ülesanne jääb " "viimase kanda. Lisaks on võimalik HAProxyt ka seadistada ühenduste " "sagedusi piirama lähteaadressi või mõne muu nimetaja põhjal. See aga jääb" " süsteemihalduri ülesandeks." msgstr "" "The IVXV configuration generates a HAProxy configuration file containing " "the locations of the other services, and leaves the connection brokering " "to the latter. In addition, it is also possible to configure HAProxy to " "limit connections based on the source address or some other denominator. " "This, however, is left to the system administrator." #: ../../kogumisteenus.rst:123 msgid "" "Kuigi HAProxy on võimeline ise teostama koormusjaoturi ülesannet, on seda" " võimalik evitada ka teiste, potentsiaalselt riistvaraliste " "koormusjaoturite taha, kus see jääb täitma ainult SNI põhjal vahendamise " "ülesannet." msgstr "" "Although HAProxy is capable of performing the load balancer task itself, " "it can also be exported behind other, potentially hardware load " "balancers, where it remains to perform only the task of dispatching on " "the basis of SNI." #: ../../kogumisteenus.rst:127 msgid "" "HAProxy lähtekood on avalik ja sobiva litsentsiga ning pakendatud " "kogumisteenuse alusplatvormi ametlikus hoidlas (vt. :ref:`tehnoloogiad`)." msgstr "" "The HAProxy source code is public and suitably licensed and packaged in " "the official repository of the underlying collection service platform " "(see :ref:`tehnoloogiad`)." #: ../../kogumisteenus.rst:131 msgid "Nimekirjateenuse funktsioon ja tehniline liides" msgstr "Functionality and technical interface of the choice-list service" #: ../../kogumisteenus.rst:133 msgid "" "Nimekirjateenuse põhifunktsioon on valikute nimekirjade vahendamine " "Valijarakendusele. Nimekirjateenusesse jõuab informatsioon tuvastatud " "valija kohta ning Nimekirjateenus väljastab valija ringkonnale vastava " "valikute nimekirja Talletamisteenusest Valijarakendusse." msgstr "" "The main function of the choice-list service is to provide choice list to" " the Voting application. The Choice List Service receives information " "about the authenticated voter and issues the corresponding list of " "choices to the voter's precinct to the Voting Application." #: ../../kogumisteenus.rst:138 msgid "" "Nimekirjateenus on olekuvaba komponent, mida on võimalik horisontaalselt " "skaleerida." msgstr "" "The choice-list service is a stateless component that can be scaled " "horizontally." #: ../../kogumisteenus.rst:142 msgid "Kontrollteenuse funktsioon ja tehniline liides" msgstr "Verification service functionality and technical interface" #: ../../kogumisteenus.rst:144 msgid "" "Kontrollteenuse põhifunktsioon on kontrollpäringute töötlemine ning " "kontrollitava hääle väljastamine Talletamisteenusest Kontrollrakendusse." msgstr "" "The main function of the Verification Service is to process verification " "requests and output the vote to be verified from the Storage Service to " "the Verification Application." #: ../../kogumisteenus.rst:147 msgid "" "Kontrollteenus on olekuvaba komponent, mida on võimalik horisontaalselt " "skaleerida." msgstr "" "The verification service is a stateless component that can be scaled " "horizontally." #: ../../kogumisteenus.rst:151 msgid "Hääletamisteenuse funktsioon ja tehniline liides" msgstr "Voting service function and technical interface" #: ../../kogumisteenus.rst:153 msgid "" "Hääletamisteenuse põhifunktsioon on hääletamispäringute töötlemine. " "Hääletamisteenus verifitseerib sissetuleva hääle, registreerib selle " "Registreerimisteenuses ning talletab Talletamisteenusesse." msgstr "" "The main function of the voting service is the processing of voting " "requests. The Voting Service verifies the incoming vote, registers it in " "the Registration Service and stores it in the Storage Service." #: ../../kogumisteenus.rst:157 msgid "" "Hääletamisteenus on olekuvaba komponent, mida on võimalik horisontaalselt" " skaleerida." msgstr "" "The voting service is a stateless component that can be scaled " "horizontally." #: ../../kogumisteenus.rst:161 msgid "Talletamisteenuse funktsioon ja tehniline liides" msgstr "Functionality and technical interface of the storage service" #: ../../kogumisteenus.rst:163 msgid "" "Talletamisteenuse põhifunktsioon on valikute ja valijanimekirjade ning " "häälte pikaajaline talletamine." msgstr "" "The main function of the storage service is the long-term storage of " "lists of choices, lists of voters and votes." #: ../../kogumisteenus.rst:166 msgid "" "Talletamisteenuse horisontaalseks skaleerimiseks kasutatakse " "hajustalletamist võimaldavat säilitustehnoloogiat." msgstr "" "Storage technology that enables distributed storage is used for " "horizontal scaling of the storage service." #: ../../kogumisteenus.rst:170 msgid "Talletamisteenuse teostus" msgstr "Implementation of storage service" #: ../../kogumisteenus.rst:172 msgid "" "Talletamisteenus ei ole teadlik IVXV protokollist ega talletatavate " "andmete spetsiifikast, vaid on üldkasutatav võti-väärtus andmebaas " "binaarandmete säilitamiseks. Kogu teadmus talletatavate andmete " "struktuurist ja võtmete hierarhiast on teistes, Talletamisteenust " "kasutatavates teenustes, mis käituvad nii-öelda \"tarkade\" klientidena." msgstr "" "The storage service is not aware of the IVXV protocol or the specifics of" " the data being stored, but is a public key-value database for storing " "binary data. All the knowledge about the structure of the stored data and" " the hierarchy of keys is in the other services using the Storage " "Service, which behave as \"smart\" clients." #: ../../kogumisteenus.rst:178 msgid "" "Selline lähenemine lubab ilma suurema vaevata kasutada " "Talletamisteenusena ükskõik millist üldlevinud võti-väärtus andmebaasi: " "ainsateks ülesanneteks on IVXV seadistuse teisendamine andmebaasi jaoks " "sobilikku vormingusse ning teenuse käivitamine. Andmebaasi tarkvara peab " "võimaldama vaid võtme järgi talletamist ja lugemist, võtmete prefiksi " "järgi loetlemist ning atomaarset võrdle-ja-vaheta (*compare-and-swap*) " "operatsiooni." msgstr "" "This approach allows any common key-value database to be used as a " "Storage Service without much effort: the only tasks are to convert the " "IVXV configuration into a database-appropriate format and to start the " "service. The database software only needs to support key-by-key storage " "and read, key-by-prefix read, and atomic *compare-and-swap* operation." #: ../../kogumisteenus.rst:185 msgid "" "Talletamisteenus on kogumisteenuse töökiiruse oluliseks määrajaks, " "mistõttu mõjutab seda teenust pakkuv riistvara kogu süsteemi jõudlust " "ning see tuleks vastavalt kasutatavale andmebaasile dimensioneerida." msgstr "" "The storage service is an important determinant of the performance of the" " collection service, so the hardware that provides this service affects " "the performance of the whole system and should be dimensioned according " "to the database used." #: ../../kogumisteenus.rst:189 msgid "" "Hetkel ainus tooteks mõeldud Talletamisteenuse teostus kasutab hajusat " "võti-väärtus andmebaasi etcd. Selle puhul tuleks järgida etcd autorite " "`riistvara soovitusi `_." msgstr "" "Currently, the only Storage Service implementation for the production " "uses a distributed key-value database etcd. For this, the `hardware " "recommendations `_ of the etcd authors should be followed." #: ../../kogumisteenus.rst:195 msgid "Tuvastusteenuse funktsioon ja tehniline liides" msgstr "Authentication service function and technical interface" #: ../../kogumisteenus.rst:197 msgid "" "Tuvastusteenuse põhifunktsioon on valija identiteedi tuvastamine. " "Tuvastusteenus on vajalik näiteks Mobiil-ID autentimise korral." msgstr "" "The main function of the authentication service is to identify and " "authenticate the voter. For example, the authentication service must be " "implemented for Mobile-ID authentication." #: ../../kogumisteenus.rst:201 msgid "Web-eID abiteenuse teostus" msgstr "Implementation of the Web-eID authentication service" #: ../../kogumisteenus.rst:203 msgid "" "IVXV koosseisu kuulub Web-eID abiteenus, mis realiseerib Tuvastusteenuse " "ID-kaardi kasutamiseks Web-eID raamistikus." msgstr "" "IVXV includes Web-eID authentication service for using ID-card in the " "Web-eID framework" #: ../../kogumisteenus.rst:206 msgid "" "Eduka Web-eID isikutuvastuse korral väljastab abiteenus Valijarakendusele" " pileti, mille abil on võimalik teistele teenustele valija identiteeti " "kinnitada. Iga piletiga saab hääletada ainult ühe korra." msgstr "" "In case of a successful Web-eID authentication, the service issues a " "ticket to the Voting Application, which can be used to confirm the " "voter's identity to other services. Each ticket can be used to vote only " "once." #: ../../kogumisteenus.rst:210 msgid "" "Web-eID ei paku allkirjateenust, hääle allkirjastamine toimub Valija " "seadmes lokaalselt analoogselt klassikalisele ID-kaardiga " "autentimisele/allkirjastamisele." msgstr "" "Web-eID does not provide signature service. The signing of the vote takes" " place in the Voting Application in the same way as with ID-card." #: ../../kogumisteenus.rst:214 msgid "" "Web-eID abiteenus on olekuvaba komponent. Tänu sellele on võimalik Web-" "eID abiteenust horisontaalselt skaleerida." msgstr "" "The Web-eID service is a stateless component that can be scaled " "horizontally." #: ../../kogumisteenus.rst:219 msgid "Allkirjateenuse funktsioon ja tehniline liides" msgstr "Signature service functionality and technical interface" #: ../../kogumisteenus.rst:221 msgid "" "Allkirjateenuse funktsioon on Valijarakenduse toetamine hääle " "allkirjastamisel. Allkirjateenus on vajalik näiteks Mobiil-ID " "allkirjastamise korral." msgstr "" "The function of the Signature Service is to support the Voting " "Application in signing a vote. For example, the signature service is " "required for Mobile-ID signing." #: ../../kogumisteenus.rst:226 msgid "Mobiil-ID abiteenuse teostus" msgstr "Implementation of the Mobile-ID service" #: ../../kogumisteenus.rst:228 msgid "" "IVXV koosseisu kuulub Mobiil-ID abiteenus, mis käitub Mobiil-ID jaoks nii" " Tuvastusteenusena kui ka Allkirjateenusena. Valijarakendus esitab IVXV " "päringud Mobiil-ID abiteenusele, mis teisendab need Mobiil-ID päringuteks" " ning edastab Mobiil-ID teenusepakkujale." msgstr "" "IVXV includes the Mobile-ID Service, which acts as both an Authentication" " Service and a Signature Service for Mobile-ID. The Voting Application " "submits the IVXV requests to the Mobile-ID Service, which converts them " "into Mobile-ID requests and forwards them to the Mobile-ID Service " "Provider." #: ../../kogumisteenus.rst:233 msgid "" "Eduka Mobiil-ID isikutuvastuse korral väljastab abiteenus " "Valijarakendusele pileti, mille abil on võimalik teistele teenustele " "valija identiteeti kinnitada. Iga piletiga saab hääletada ainult ühe " "korra." msgstr "" "In case of a successful Mobile-ID authentication, the help service issues" " a ticket to the Voting Application, which can be used to confirm the " "voter's identity to other services. Each ticket can be used to vote only " "once." #: ../../kogumisteenus.rst:237 msgid "" "Allkirjastamise korral saadab Valijarakendus Mobiil-ID abiteenusele vaid " "allkirjastatava hääle räsi ning kasutab vastuseks saadud signatuuri " "samamoodi kui ID-kaardiga loodud signatuuri." msgstr "" "In the case of a signature, the Voting Application sends only the hash of" " the vote to be signed to the Mobile ID Service and uses the signature " "received in response in the same way as the signature created with an ID-" "card." #: ../../kogumisteenus.rst:241 msgid "" "Mobiil-ID abiteenus sisaldab küll olekut pooleliolevate tuvastusseansside" " kohta, aga muus osas on tegu olekuvaba komponendiga. Tänu sellele on " "võimalik Mobiil-ID abiteenust horisontaalselt skaleerida." msgstr "" "The Mobile-ID service does contain a status for pending authentication " "sessions, but otherwise it is a stateless component. This makes it " "possible to horizontally scale the Mobile-ID Service." #: ../../kogumisteenus.rst:246 msgid "Smart-ID abiteenuse teostus" msgstr "Implementation of Smart-ID service" #: ../../kogumisteenus.rst:248 msgid "" "IVXV koosseisu kuulub Smart-ID abiteenus, mis käitub Smart-ID jaoks nii " "Tuvastusteenusena kui ka Allkirjateenusena. Valijarakendus esitab IVXV " "päringud Smart-ID abiteenusele, mis teisendab need Smart-ID päringuteks " "ning edastab Smart-ID teenusepakkujale." msgstr "" "IVXV includes the Smart-ID Service, which acts as both an Authentication " "Service and a Signature Service for Smart-ID. The Voting Application " "submits the IVXV requests to the Smart-ID Service, which converts them " "into Smart-ID requests and forwards them to the Smart-ID Service " "Provider." #: ../../kogumisteenus.rst:253 msgid "" "Eduka Smart-ID isikutuvastuse korral väljastab abiteenus " "Valijarakendusele pileti, mille abil on võimalik teistele teenustele " "valija identiteeti kinnitada. Iga piletiga saab hääletada ainult ühe " "korra." msgstr "" "In case of a successful Smart-ID authentication, the help service issues " "a ticket to the Voting Application, which can be used to confirm the " "voter's identity to other services. Each ticket can be used to vote only " "once." #: ../../kogumisteenus.rst:257 msgid "" "Allkirjastamise korral saadab Valijarakendus Smart-ID abiteenusele vaid " "allkirjastatava hääle räsi ning kasutab vastuseks saadud signatuuri " "samamoodi kui ID-kaardiga loodud signatuuri." msgstr "" "In the case of signing, the Voting App sends only the hash of the vote to" " be signed to the Smart-ID Service and uses the signature received in " "response in the same way as the signature created with an ID-card." #: ../../kogumisteenus.rst:261 msgid "" "Smart-ID abiteenus sisaldab küll olekut pooleliolevate tuvastusseansside " "kohta, aga muus osas on tegu olekuvaba komponendiga. Tänu sellele on " "võimalik Smart-ID abiteenust horisontaalselt skaleerida." msgstr "" "The Smart-ID service does contain a status for pending authentication " "sessions, but otherwise it is a stateless component. This makes it " "possible to horizontally scale the Smart-ID Service." #: ../../kogumisteenus.rst:267 msgid "Hääletamisfaktide järjekorrateenus" msgstr "Votesorder service" #: ../../kogumisteenus.rst:269 msgid "" "Hääletamisfaktide järjekorrateenuse põhifunktsiooniks on " "hääletamisfaktide edastamine Valimiste Infosüsteemile X-tee abiteenuse " "vahendusel." msgstr "" "Main function of the votesorder service is to provide information about " "votes received to the Election Management System over X-road service" #: ../../kogumisteenus.rst:273 msgid "Kogumisteenuse mikroteenuste evitamine" msgstr "Deployment of collection microservices" #: ../../kogumisteenus.rst:275 msgid "" "Kogumisteenuse mikroteenused sõltuvad välistest pakkidest minimaalselt. " "Vajalikud sõltuvused on:" msgstr "" "Collection microservices rely minimally on external packages. The " "necessary dependencies are:" #: ../../kogumisteenus.rst:278 msgid "" "SSH-server haldustegevuste läbiviimiseks (seda kasutab mikroteenuste " "haldamiseks haldusteenus)." msgstr "" "SSH server for administrative activities (used by the management service " "for microservices)." #: ../../kogumisteenus.rst:281 msgid "rsyslog logide kogumiseks logikogumisteenustesse." msgstr "rsyslog for log collection services." #: ../../kogumisteenus.rst:283 msgid "" "Kogumisteenuse mikroteenused pakendatakse deb-vormingus, neid on võimalik" " evitada ka docker'i-laadsete konteineritena." msgstr "" "The collection microservices are packaged in deb format and can also be " "delivered in docker-like containers." #: ../../kogumisteenus.rst:287 msgid "Välised teenused ja laiendatavus" msgstr "External services and scalability" #: ../../kogumisteenus.rst:291 msgid "Kogumisteenuse laiendusmoodulid ja välised teenused" msgstr "Collection Service Extensions and External Services" #: ../../kogumisteenus.rst:293 msgid "" "Kogumisteenuse mikroteenused kasutavad laiendusmooduleid teostamaks " "erinevaid mehhanisme valija tuvastamiseks, digiallkirjade " "verifitseerimiseks ja täiendamiseks, sealhulgas hääle registreerimiseks. " "Laiendusmoodulid võivad teostuse võimaldamiseks kasutada väliseid " "teenuseid. Mikroteenuste laiendatavuse huvides on defineeritud Go API, " "mille alusel saab teostada ka täiendavaid mooduleid. Hetkel on teostatud " "järgmised moodulid:" msgstr "" "Collection microservices use plug-ins to perform various mechanisms for " "voter authentication, digital signature verification and qualification, " "including vote registration. The extension modules may use external " "services to enable the implementation. For the extensibility of the " "microservices, a Go API has been defined to allow the execution of " "additional modules. The following modules are currently implemented:" #: ../../kogumisteenus.rst:300 msgid "Autentimine TLS-sertifikaadiga (ID-kaart);" msgstr "Authentication with TLS certificate (ID card);" #: ../../kogumisteenus.rst:302 msgid "Autentimine Tuvastusteenuse piletiga (Mobiil-ID, Smart-ID, Web-eID);" msgstr "" "Authentication with an Authentication Service Ticket (Mobile-ID, Smart-" "ID, Web-eID);" #: ../../kogumisteenus.rst:304 msgid "BDOC verifitseerimine;" msgstr "BDOC verification;" #: ../../kogumisteenus.rst:306 msgid "Kehtivuskinnitusteenus OCSP;" msgstr "Certificate validity service OCSP;" #: ../../kogumisteenus.rst:308 msgid "Ajatempliteenus RFC 3161;" msgstr "Timestamp Service RFC 3161;" #: ../../kogumisteenus.rst:310 msgid "Registreerimisteenus OCSP;" msgstr "Registration service OCSP;" #: ../../kogumisteenus.rst:312 msgid "Registreerimisteenus RFC 3161." msgstr "Registration service RFC 3161." #: ../../kogumisteenus.rst:314 msgid "" "IVXV krüptograafilises protokollis on kesksel kohal Registreerimisteenus," " mis osaleb samuti häälte pikaajalisel talletamisel." msgstr "" "Central to the IVXV cryptographic protocol is the Registration Service, " "which is also involved in the long-term storage of votes." #: ../../kogumisteenus.rst:318 msgid "Registreerimisteenuse funktsioon" msgstr "Registration service function" #: ../../kogumisteenus.rst:320 msgid "" "Registreerimisteenuse põhifunktsioon on võtta Hääletamisteenuselt vastu " "allkirjastatud registreerimispäringuid, kinnitada need omapoolse " "allkirjastatud vastusega ning säilitada hilisemaks auditeerimiseks " "vähemalt hääletamisperioodi lõpuni." msgstr "" "The main function of the Registration Service is to receive signed " "registration requests from the Voting Service, validate them with a " "signed response from the Voting Service, and store them for later audit " "at least until the end of the voting period." #: ../../kogumisteenus.rst:325 msgid "Auditeerimisel tekkivate võimalike erisuste lahendamiseks on oluline, et" msgstr "" "In order to address possible differences in auditing, it is important " "that." #: ../../kogumisteenus.rst:327 msgid "" "Registreerimisteenus on võimeline tõestama, et igale tema poolt " "väljastatud kinnitusele eelnes Talletamisteenuse poolne " "registreerimispäring;" msgstr "" "The Registration service is able to prove that each confirmation issued " "by it was preceded by a registration request from the Storage;" #: ../../kogumisteenus.rst:330 msgid "" "Talletamisteenus on võimeline tõestama, et iga tema poolt talletatud " "hääle kohta on olemas Registreerimisteenuse kinnitus." msgstr "" "The Storage is able to prove that there is a confirmation from the " "Registration Service for each vote it has stored." #: ../../kogumisteenus.rst:333 msgid "" "Piisav protokoll sellise tõendamistaseme saavutamiseks on, kus mõlemal " "osapoolel on olemas võtmepaar allkirjastamiseks, päringud ja vastused on " "allkirjastatud ning kumbki pool peab registrit teise poole teadete üle. " "Selline protokoll on realiseeritav näiteks OCSP-põhise " "Registreerimisteenuse korral. Samas võib esineda juhtumeid, kus näiteks " "registreerimispäringute allkirjastamine ei ole standardsete vahenditega " "võimalik (RFC 3161 põhine registreerimine). Sellisel juhul tuleb " "registreerimisteenusele vajalik tõendusmaterjal anda muude " "organisatsioonilis-tehniliste vahenditega." msgstr "" "A sufficient protocol to achieve this level of confirmation is where both" " parties have a key pair to sign, queries and responses are signed, and " "each party keeps a record of the other party's messages. Such a protocol " "is feasible, for example, in the case of an OCSP-based Registration " "Service. However, there may be cases where, for example, signing of " "registration requests is not possible by standard means (RFC 3161-based " "registration). In such cases, the necessary evidence for the Registration" " Service must be provided by other organisational/technical means." #: ../../kogumisteenus.rst:342 msgid "Registreerimisteenusel on praegu kaks erinevat teostust:" msgstr "The registration service currently has two different implementations:" #: ../../kogumisteenus.rst:344 msgid "" "OCSP-liides eeldab Eestis rakendatava OCSP-põhise ajamärgendamisteenuse " "kasutamist, kus allkirjastatud OCSP-päringu nonsiks on Hääletamisteenuse " "poolt pandud hääle räsi. Päring on allkirjastatud standardsete OCSP " "vahenditega;" msgstr "" "The OCSP interface requires the use of the OCSP-based timemarking service" " implemented in Estonia, where the nonce of a signed OCSP request is the " "hash of the vote cast by the Voting Service. The query is signed using " "standard OCSP tools;" #: ../../kogumisteenus.rst:349 msgid "" "RFC 3161 liides, mille korral ebastandardse lahendusena pannakse " "ajatemplipäringu nonsiks Hääletamisteenuse poolt allkirjastatud hääle " "räsi." msgstr "" "RFC 3161 interface, where as a non-standard solution the nonce of a " "timestamp request is set to a hash of the vote signed by the Vote " "Service." #: ../../kogumisteenus.rst:354 msgid "Kogumisteenuse laiendusmoodulite lisamine" msgstr "Adding collection service extension modules" #: ../../kogumisteenus.rst:356 msgid "Kogumisteenuse API defineerib kuute tüüpi laiendusmooduleid:" msgstr "The Collection API defines six types of extension modules:" #: ../../kogumisteenus.rst:358 msgid "isikutuvastus (Go pakk ``ivxv.ee/auth``, näiteks ``tls``);" msgstr "authentication (Go package ``ivxv.ee/auth``, for example ``tls``);" #: ../../kogumisteenus.rst:360 msgid "" "tuvastatud isiku sertifikaadist valija identifikaatori tuletamine (Go " "pakk ``ivxv.ee/identity``, näiteks ``serialnumber``);" msgstr "" "derivation of the voter identifier from the certificate of the " "authenticated person (Go package ``ivxv.ee/identity``, for example " "``serialnumber``);" #: ../../kogumisteenus.rst:363 msgid "" "valija identifikaatorist vanuse tuletamine (Go pakk ``ivxv.ee/age``, " "näiteks ``estpic``);" msgstr "" "deriving the age of a voter from the voter's identifier (Go package " "``ivxv.ee/age``, for example ``estpic``);" #: ../../kogumisteenus.rst:366 msgid "" "allkirjastatud konteineri verifitseerimine (Go pakk " "``ivxv.ee/container``, näiteks ``bdoc``);" msgstr "" "verification of a signed container (Go package ``ivxv.ee/container``, for" " example ``bdoc``);" #: ../../kogumisteenus.rst:369 msgid "allkirja kvalifitseerimine (Go pakk ``ivxv.ee/q11n``, näiteks ``tspreg``);" msgstr "" "signature qualification (Go package ``ivxv.ee/q11n``, for example " "``tspreg``);" #: ../../kogumisteenus.rst:371 msgid "andmetalletusprotokoll (Go pakk ``ivxv.ee/storage``, näiteks ``etcd``)." msgstr "storage protocol (Go package ``ivxv.ee/storage``, for example ``etcd``)." #: ../../kogumisteenus.rst:373 msgid "" "Uue mooduli lisamiseks tuleb moodulpakki lisada mooduli identifikaator " "ning mooduli teostusega alampakk. Alampaki alglaadimisel tuleb mooduli " "registreerimiseks kutsuda välja moodulpaki ``Register`` funktsioon." msgstr "" "In order to add a new module, the module identifier and the sub-package " "with the module implementation must be added to the module package. The " "``Register`` function of the module package must be called to register " "the module when the sub-package is initially loaded." #: ../../kogumisteenus.rst:377 msgid "" "Uue mooduli kasutamiseks tuleb selle identifikaator lisada seadistusse " "vastava moodulitüübi seadistuse juurde koos alammooduli seadistusega. " "Laiendusmoodulile antakse ette tema identifikaatoriga viidatud " "seadistusblokk, mida see mooduli-siseselt edasi töötleb." msgstr "" "In order to use a new module, its identifier must be added to the " "configuration of the corresponding module type, together with the " "configuration of the sub-module. The extension module shall be provided " "with a configuration block referenced by its identifier, which it shall " "further process within the module." #: ../../kogumisteenus.rst:382 msgid "" "Moodulpakid ja nende moodulitelt nõutavad liidesed on täpsemalt " "kirjeldatud vastavates lähtekoodifailides. Samuti on iga mooduli kohta " "olemas vähemalt üks teostus, mida saab kasutada eeskujuna." msgstr "" "The module packages and the interfaces required from these modules are " "described in more detail in the source code. There is also at least one " "implementation of each module that can be used as an example." #: ../../kogumisteenus.rst:388 msgid "Monitooring" msgstr "Monitoring" #: ../../kogumisteenus.rst:392 msgid "Monitooringulahendus" msgstr "Monitoring solution" #: ../../kogumisteenus.rst:395 msgid "Logimine" msgstr "Logging" #: ../../kogumisteenus.rst:397 msgid "" "Iga mikroteenuse poolt genereeritav logi defineeritakse süstemaatiliselt," " lähtudes protokollikirjeldusest ning teenuse osutamise olekudiagrammist." " Logitakse minimaalselt:" msgstr "" "Each log generated by a microservice is systematically defined based on " "the protocol description and the service provision status diagram. Logs " "shall be kept to a minimum:" #: ../../kogumisteenus.rst:401 msgid "iga päringu kättesaamise fakt ning töötlemise algus;" msgstr "the fact of receipt of each request and the start of processing;" #: ../../kogumisteenus.rst:403 msgid "töötlemise üleandmine välisele komponendile;" msgstr "transfer of processing to an external component;" #: ../../kogumisteenus.rst:405 msgid "töötlemisjärje naasmine komponenti;" msgstr "the processing stage return component;" #: ../../kogumisteenus.rst:407 msgid "päringu töötlemise lõpp ning tulemus;" msgstr "the end of query processing and the result;" #: ../../kogumisteenus.rst:409 msgid "täiendavalt oluliste etappide läbimine protsessi olekumudelis." msgstr "additional key steps in the process status model." #: ../../kogumisteenus.rst:411 msgid "Logimisel järgitakse järgmisi põhimõtteid:" msgstr "Logging is based on the following principles:" #: ../../kogumisteenus.rst:413 msgid "" "Logimiseks kasutatakse rsyslog teenust, mis registreerib logiteate " "kirjutamise hetke millisekundi täpsusega;" msgstr "" "Logging is done using the rsyslog service, which records the time of " "writing a log message to the nearest millisecond;" #: ../../kogumisteenus.rst:416 msgid "" "Iga seansi alustamisel genereerib süsteem unikaalse identifikaatori, mida" " klientrakendus kasutab oma päringutel kesksüsteemi poole pöördumiseks;" msgstr "" "At the start of each session, the system generates a unique identifier " "that the client application uses in its queries to access the central " "system;" #: ../../kogumisteenus.rst:419 msgid "" "Kõik ühe seansi alla kuuluvad logikirjed sisaldavad sama " "seansiidentifikaatorit;" msgstr "All the logs belonging to one session contain the same session identifier;" #: ../../kogumisteenus.rst:422 msgid "Logikirje on unikaalselt identifitseeritav;" msgstr "The log record is uniquely identifiable;" #: ../../kogumisteenus.rst:424 msgid "" "Iga logitava teate juures on võimalik unikaalse tunnuse abil üksüheselt " "tuvastada teate tekkimise koht monitooritavas süsteemis;" msgstr "" "For each logged message it is possible to uniquely identify, by means of " "a unique identifier, where the message originated in the monitored " "system;" #: ../../kogumisteenus.rst:427 msgid "" "Logikirje on JSON vormingus, automaatse monitooringu jaoks on " "masinloetavus primaarne ning inimloetavus sekundaarne;" msgstr "" "The log record is in JSON format, with machine readability primary and " "human readability secondary for automatic monitoring;" #: ../../kogumisteenus.rst:430 msgid "" "Logisse minev info saneeritakse (urlencode) ja sellele rakendatakse " "pikkuse piirangut (piirang terve logiteate ja samuti parameetri kaupa);" msgstr "" "The information that goes into the log is sanitized (urlencode) and a " "length limit is applied (limit per whole log message and also per " "parameter);" #: ../../kogumisteenus.rst:433 msgid "" "Süsteemiperimeetrist väljastpoolt pärinevat infot logitakse ainult " "saneerituna ja ainult etteantud pikkuses." msgstr "" "Information coming from outside the system perimeter is logged only as " "redundant and only at a predefined length." #: ../../kogumisteenus.rst:436 msgid "" "Kuna logimine toimub rsyslog vahendusel, on võimalik Guardtime mooduli " "kasutamine logide tervikluse tagamiseks." msgstr "" "Since logging is done via rsyslog, it is possible to use the Guardtime " "module to ensure log integrity." #: ../../kogumisteenus.rst:441 msgid "Üldstatistika" msgstr "General statistics" #: ../../kogumisteenus.rst:443 msgid "Järgmise statistika jälgimiseks kasutatakse staatilist veebiliidest:" msgstr "A static web interface is used to monitor the following statistics:" #: ../../kogumisteenus.rst:445 msgid "edukalt kogutud hääled/hääletajate hulk;" msgstr "number of votes successfully collected/votes cast;" #: ../../kogumisteenus.rst:447 msgid "" "hääletajate jagunemine sugude, vanusegruppide, operatsioonisüsteemide " "ning autentimisvahendite kaupa;" msgstr "" "breakdown of voters by gender, age group, operating system and " "authentication means;" #: ../../kogumisteenus.rst:450 msgid "edukalt kontrollitud häälte/hääletajate hulk;" msgstr "the number of successfully verified votes/votes;" #: ../../kogumisteenus.rst:452 msgid "korduvhääletamiste statistika;" msgstr "statistics on re-votes;" #: ../../kogumisteenus.rst:454 msgid "hääletajate jagunemine riigiti IP-aadressi põhjal." msgstr "breakdown of voters by country, based on IP address." #: ../../kogumisteenus.rst:458 msgid "Detailstatistika" msgstr "Detailed statistics" #: ../../kogumisteenus.rst:460 msgid "" "Detailstatistika agregeeritakse logide põhjal kasutades SCCEIV " "logianalüsaatorit, mis analüüsib rakenduste tegevuslogi eeldefineeritud " "profiili suhtes ning võimaldab seansi-/veatüübipõhist analüüsi." msgstr "" "Detailed statistics are aggregated from logs using the SCCEIV log " "analyser, which analyses the activity logs of applications against a " "predefined profile and allows for a session/vehicle type analysis." #: ../../kogumisteenus.rst:464 msgid "Detailstatistika on kättesaadav üle HTTPS-liidese." msgstr "Detailed statistics are available over HTTPS." #: ../../kogumisteenus.rst:470 msgid "Haldus" msgstr "Administration" #: ../../kogumisteenus.rst:472 msgid "" "Kogumisteenuse haldamine toimub digitaalallkirjastatud seadistuspakkide " "abil." msgstr "" "The collection service is managed by means of digitally signed " "configuration packs." #: ../../kogumisteenus.rst:474 msgid "Kogumisteenus pakub seadistuspakkide laadimiseks kahte liidest:" msgstr "" "The collection service provides two interfaces for loading configuration " "packages:" #: ../../kogumisteenus.rst:476 msgid "" "Käsurealiides – rakendus verifitseerib allkirja, valideerib korralduste " "vormingut, kooskõlalisust ja sobivust kogumisteenuse seisundi suhtes. " "Korralduse rakendamine toimub eraldi utiliidi abil." msgstr "" "Command line interface - the application verifies the signature, " "validates the format, consistency and appropriateness of the orders " "against the status of the collection service. The execution of the order " "is done through a separate utility." #: ../../kogumisteenus.rst:480 msgid "" "Veebiliides – veebiliides vahendab seadistuspaki käsurealiidesele ja " "tagastab kasutajale info laadimise tulemuse kohta. Eduka laadimise korral" " toimub automaatselt ja samadel põhimõtetel ka seadistuspaki rakendamine." msgstr "" "Web interface - the web interface passes the configuration package to the" " command line interface and returns information about the result of the " "loading to the user. In case of a successful load, the implementation of " "the configuration package is automatic and follows the same principles." #: ../../kogumisteenus.rst:484 msgid "Veebiliidese funktsioonideks on:" msgstr "The features of the web interface are:" #: ../../kogumisteenus.rst:486 msgid "Kogumisteenuse mikroteenuste seisundi jälgimine;" msgstr "Monitoring the status of collection microservices;" #: ../../kogumisteenus.rst:488 msgid "Valimiste nimekirjade haldus;" msgstr "Management of voter lists;" #: ../../kogumisteenus.rst:490 msgid "Statistika kuvamine e-hääletamise kulgemise kohta;" msgstr "Displaying statistics on the progress of e-voting;" #: ../../kogumisteenus.rst:492 msgid "Haldusteenuse kasutajate haldus;" msgstr "Management of users of the management service;" #: ../../kogumisteenus.rst:494 msgid "Kogumisteenuse halduse logi kuvamine." msgstr "Display the collection service management log." #: ../../kogumisteenus.rst:496 msgid "" "Kõik rakendusele antud korraldused säilitatakse - ka need mida ei " "rakendatud. Vigaseid (mittevalideeruvaid) korraldusi ei säilitata." msgstr "" "All orders given to the application are kept - even those that were not " "applied. Incorrect (non-validated) orders are not retained." #: ../../kogumisteenus.rst:499 msgid "Kogumisteenuse haldusteenus sooritab järgmisi tegevusi automaatselt:" msgstr "" "The collection management service automatically performs the following " "actions:" #: ../../kogumisteenus.rst:501 msgid "Valijate nimekirjade muudatuste laadimine Valimiste Infosüsteemist;" msgstr "" "Downloading changes to electoral rolls from the Election Information " "System;" #: ../../kogumisteenus.rst:503 msgid "" "Hääletamise statistika kogumine hääletusteenusest ja eksportimine " "Valimiste Infosüsteemi;" msgstr "" "Collection of voting statistics from the voting service and export to the" " Election Information System;" #: ../../kogumisteenus.rst:506 msgid "Talletatud häälte, logide ning seadistuste varundamine varundusteenusesse." msgstr "Backing up saved voices, logs and settings to a backup service." #: ../../kogumisteenus.rst:510 msgid "Haldusteenuse komponendid" msgstr "Components of a management service" #: ../../kogumisteenus.rst:514 msgid "Kogumisteenuse haldusteenuse komponendid" msgstr "Components of a collection management service" #: ../../kogumisteenus.rst:516 msgid "" "**Halduse veebiserver** on süsteemse kasutaja ``www-data`` õigustes " "töötav Apache server, mille ülesanded on:" msgstr "" "The **Administrative Web Server** is an Apache server running as ``www-" "data`` for the system user, whose functions are:" #: ../../kogumisteenus.rst:519 msgid "Kasutajatelt tulevate HTTPS-päringute esmane teenindamine:" msgstr "Serving HTTPS requests from users on a first-come, first-served basis:" #: ../../kogumisteenus.rst:521 msgid "Haldusteenuse usaldusväärsuse tõestamine (TLS-sertifikaat);" msgstr "Proof of trustworthiness of the management service (TLS certificate);" #: ../../kogumisteenus.rst:523 msgid "Kasutajate autentimine;" msgstr "User authentication;" #: ../../kogumisteenus.rst:525 msgid "" "Valmisgenereeritud veebilehtede ja andmefailide serveerimine " "andmehoidlast." msgstr "Serving pre-built web pages and data files from the repository." #: ../../kogumisteenus.rst:528 msgid "" "Üldiste taustaandmete päringu vastuse varustamine sisseloginud kasutaja " "andmetega (WSGI)." msgstr "" "Supplying the response to a general background query with the logged-in " "user's data (WSGI)." #: ../../kogumisteenus.rst:531 msgid "" "Üleslaaditavate korralduste esmane valideerimine ja vahendamine " "haldusdeemonile ning haldusdeemoni sellekohaste vastuste vahendamine " "kliendile (WSGI)." msgstr "" "Initial validation and transmission of uploaded instructions to the " "management daemon and transmission of the management daemon's responses " "to the client (WSGI)." #: ../../kogumisteenus.rst:535 msgid "" "**Haldusdeemon** on kasutajakonto ``ivxv-admin`` õigustes töötav ja " "kohalikul (``localhost``) liidesel kuulav veebiserver mille ülesanded on:" msgstr "" "The **administrative daemon** is a web server running under ``ivxv-" "admin`` privileges and listening on the local (``localhost``) interface " "with the following tasks:" #: ../../kogumisteenus.rst:538 msgid "Üleslaaditavate korralduste valideerimine;" msgstr "Validation of downloadable orders;" #: ../../kogumisteenus.rst:540 msgid "Üleslaaditavate korralduste vahetu rakendamine (kasutajate haldus);" msgstr "Immediate implementation of uploading instructions (user management);" #: ../../kogumisteenus.rst:542 msgid "" "Üleslaaditavate korralduste salvestamine hilisemaks rakendamiseks " "(seadistuse ja valimisnimekirjade rakendamiseks teenusele);" msgstr "" "Saving of uploaded orders for later implementation (application of configurations and " "voter lists for the service);" #: ../../kogumisteenus.rst:545 msgid "E-valimiskasti allalaadimise vahendamine." msgstr "Facilitating the downloading of the digital ballot box." #: ../../kogumisteenus.rst:547 msgid "" "**Agentdeemon** on kasutajakonto ``ivxv-admin`` õigustes töötav deemon, " "mille ülesanded on:" msgstr "" "The **Agentdeemon** is a daemon with ``ivxv-admin`` privileges, whose " "tasks are:" #: ../../kogumisteenus.rst:550 msgid "Andmete kogumine ja registreerimine:" msgstr "Data collection and recording:" #: ../../kogumisteenus.rst:552 msgid "Teadaolevate mikroteenuste seisund;" msgstr "Status of known microservices;" #: ../../kogumisteenus.rst:554 msgid "Tegevusmonitooringu statistika allalaadimine;" msgstr "Download statistics of activity;" #: ../../kogumisteenus.rst:556 msgid "" "**Andmehoidla** on failisüsteemis asuv kataloog, kuhu haldusteenuse " "komponendid hoiavad kogutud ja genereeritud andmeid (vaata üksikasjalist " "kirjeldust ``IVXV kogumisteenuse haldusjuhendi`` lisadest);" msgstr "" "**Remote repository** is the directory in the file system where the " "components of the management service store the collected and generated " "data (see detailed description in the annexes of the ``IVXV Collection " "Management Guide``);" #: ../../kogumisteenus.rst:560 msgid "Välised komponendid, millega haldusteenus kokku puutub:" msgstr "External components with which the management service comes into contact:" #: ../../kogumisteenus.rst:562 msgid "" "**Kogumisteenuse alamteenused** - paigaldamine, seadistamine ja seisundi " "andmete kogumine toimub agentdeemoni kaudu (SSH-ühendus teenuse " "masinasse);" msgstr "" "**Collection Service Subservices** - installation, configuration and " "status data collection is done via agent daemon (SSH connection to the " "service machine);" #: ../../kogumisteenus.rst:565 msgid "" "**Seireserver** - üldstatistika andmete allalaadimine haldusteenuses " "kuvamiseks;" msgstr "" "**Monitoring** - download of general statistics data for display in the " "administrative service;" #: ../../kogumisteenus.rst:570 msgid "Korralduste laadimine haldusteenusesse" msgstr "Uploading orders to the management service" #: ../../kogumisteenus.rst:574 msgid "Kogumisteenuse seisundid" msgstr "Collection service conditions" #: ../../kogumisteenus.rst:576 msgid "" "Kogumisteenuse seisund kajastab teenuse kõigi alamteenuste seisundit, " "kasutuselolevate väliste teenuste seisundit ja eelneva põhjal tuletatud " "üldseisundit. Kogumisteenuse üldseisundi tuvastamisega tegeleb " "haldusteenus." msgstr "" "The state of the collection service reflects the state of all sub-" "services of the service, the state of the external services in use and " "the overall state derived from the previous buffer. The identification of" " the overall status of the collection service is handled by the " "management service." #: ../../kogumisteenus.rst:580 msgid "Üldseisundi olekud on:" msgstr "The overall status is:" #: ../../kogumisteenus.rst:582 msgid "" "**Paigaldamata** - alates haldusteenuse paigaldamisest kuni kõigi " "alamteenuste paigaldamiseni;" msgstr "" "**Uninstalled** - from the installation of the management service to the " "installation of all sub-services;" #: ../../kogumisteenus.rst:585 msgid "" "**Paigaldatud** - kõik alamteenused on paigaldatud, neile on rakendatud " "tehnilised seadistused ja teenuse toimimiseks vajalikud krüptovõtmed. " "Valimiste seadistust pole rakendatud (kuid see võib olla laaditud " "haldusteenusesse);" msgstr "" "**Installed** - all sub-services have been installed, with the technical " "settings and cryptographic keys necessary for the service to work. The " "configuration for elections has not been applied (but may be loaded into " "the management service);" #: ../../kogumisteenus.rst:590 msgid "" "**Seadistatud** - kogumisteenus on seadistatud ja töökorras, sellega on " "võimalik häälte kogumist läbi viia ja e-valimiskasti väljastada." msgstr "" "**Set up** - the collection service is set up and operational, it is able" " to vote and issue digital ballot box." #: ../../kogumisteenus.rst:593 msgid "" "**Osaline tõrge** - kogumisteenus on seadistatud ja osaliselt töökorras, " "mõned alamteenused pole töökorras, kuid see ei takista kogumisteenuse " "toimimist." msgstr "" "**Partial failure** - the collection service is configured and partially " "operational, some of the sub-services are not operational but this does " "not prevent the collection service from working." #: ../../kogumisteenus.rst:597 msgid "" "**Tõrge** - kogumisteenuse oluline sõlm pole töökorras, teenuse " "nõuetekohane osutamine pole võimalik." msgstr "" "**Failure** - an essential node of the collection service is not in " "working order, the proper provision of the service is not possible." #: ../../kogumisteenus.rst:603 msgid "" "Kogumisteenuse olekudiagramm. Olekud vastavalt värvusele: kollane - " "seadistamisel, punane - viga, roheline - töökorras." msgstr "" "Collection service status diagram. LEDs according to colour: yellow - in " "configuration, red - error, green - operational." #: ../../kogumisteenus.rst:608 msgid "Kogumisteenuse alamteenuste seisundid" msgstr "Collection sub-service statuses" #: ../../kogumisteenus.rst:613 msgid "" "Haldusteenuse poolt registreeritud alamteenuse olekudiagramm. Olekud " "vastavalt värvusele: kollane - seadistamisel, punane - viga, roheline - " "töökorras." msgstr "" "Status diagram of a sub-service registered by the management service. " "LEDs according to colour: yellow - in configuration, red - error, green -" " operational." #: ../../kogumisteenus.rst:619 msgid "Kogumisteenuse seisundi muutused" msgstr "Changes in the status of the collection service" #: ../../kogumisteenus.rst:621 msgid "" "Kogumisteenuse seisund on jälgitav alates haldusteenuse edukast " "paigaldamisest, algne seisund on **Paigaldamata**." msgstr "" "The status of the collection service is traceable from the successful " "installation of the management service, the initial status is " "**Uninstalled**." #: ../../kogumisteenus.rst:626 msgid "Paigaldamata" msgstr "Not yet installed" #: ../../kogumisteenus.rst:628 msgid "Toimub usaldusjuure ja tehnilise seadistuse rakendamine kogumisteenusele:" msgstr "" "Implementation of the trust root and technical setup for the collection " "service:" #: ../../kogumisteenus.rst:630 msgid "Seadistuste laadimine kogumisteenusesse;" msgstr "Uploading settings to the collection service;" #: ../../kogumisteenus.rst:632 msgid "Tehnilises seadistuses kirjeldatud alamteenuste paigaldus;" msgstr "Installation of the sub-services described in the technical configuration;" #: ../../kogumisteenus.rst:634 msgid "Usaldusjuure ja tehniliste seadistuste rakendamine alamteenustele;" msgstr "Implementation of trust root and technical settings for sub-services;" #: ../../kogumisteenus.rst:636 msgid "" "Seadistuste eduka rakendamise tulemusena saab süsteemi uueks seisundiks " "**Paigaldatud**." msgstr "" "Successful implementation of the settings will result in a new system " "status of **Installed**." #: ../../kogumisteenus.rst:641 msgid "Paigaldatud" msgstr "Installed" #: ../../kogumisteenus.rst:643 msgid "" "Kogumisteenuse seadistused on rakendatud kõigile alamteenustele, " "valimiste seadistused pole rakendatud. Toimub valimiste seadistuse " "laadimine haldusteenusesse ja rakendamine alamteenustele." msgstr "" "Collection service settings are applied to all sub-services, election " "settings are not applied. Election settings are being loaded into the " "management service and applied to sub-services." #: ../../kogumisteenus.rst:647 msgid "" "Valimiste seadistuse eduka rakendamise korral saab süsteemi uueks " "seisundiks **Seadistatud**." msgstr "" "If the configuration is successfully implemented, the system will have a " "new status of **Set up**." #: ../../kogumisteenus.rst:652 msgid "Seadistatud" msgstr "Set up" #: ../../kogumisteenus.rst:654 msgid "" "Kõik kogumisteenuse alamteenused on seadistatud ja töökorras. " "Haldusteenusel on kõikidest alamteenustest värsked seisundiraportid. " "Süsteemiga on võimalik hääletust läbi viia ja e-valimiskasti väljastada." msgstr "" "All sub-services of the collection service are configured and " "operational. The management service has up-to-date status reports for all" " sub-services. The system is able to conduct voting and issue digital " "ballot box." #: ../../kogumisteenus.rst:658 msgid "Kui süsteemis tuvastatakse tõrge, saab süsteemi uueks **Osaline tõrge**." msgstr "" "If a fault is detected in the system, the system will be reset to " "**Partial fault**." #: ../../kogumisteenus.rst:660 msgid "" "**Seadistatud** olekust ei pöörduta enam kunagi tagasi olekutesse " "**paigaldamata** või **paigaldatud**, kuigi uute alamteenuste lisamisel " "(kuni need on olekus **paigaldamata/paigaldatud**) oleks vastavad " "tingimused täidetud." msgstr "" "The **Set-up** state will never return to the **Uninstalled** or " "**Installed** states, even if new sub-services are added (as long as they" " are in the **Uninstalled/Installed** state)." #: ../../kogumisteenus.rst:667 msgid "Osaline tõrge" msgstr "Partial failure" #: ../../kogumisteenus.rst:669 msgid "" "Süsteem on seadistatud ja osaliselt töökorras, mõned süsteemi dubleeritud" " osad pole töökorras, kuid see ei takista süsteemil toimimast." msgstr "" "The system is configured and partially operational, some duplicated parts" " of the system are not operational, but this does not prevent the system " "from working." #: ../../kogumisteenus.rst:672 msgid "" "Rikke süvenemisel piirini, kus süsteem pole võimeline teenust osutama, " "saab süsteemi uueks olekuks **Tõrge**. Kõigi rikete kõrvaldamise järel " "saab süsteemi uueks olekuks **Seadistatud**." msgstr "" "If the failure reaches the point where the system is unable to provide " "service, the system will be set to a new status of **Failure**. When all " "faults have been cleared, the system will be set to **Set up**." #: ../../kogumisteenus.rst:678 msgid "Tõrge" msgstr "Failure" #: ../../kogumisteenus.rst:680 msgid "Seadistatud süsteemil on tuvastatud rike, mis takistab teenuse osutamist." msgstr "" "A fault has been detected in the configured system, preventing the " "service from being provided." #: ../../kogumisteenus.rst:682 msgid "" "Rikete kõrvaldamisel olukorrani, kus süsteemiga on võimalik teenust " "osutada, saab süsteemi uueks olekuks **Osaline tõrge**." msgstr "" "When the fault is rectified to a state where the system can provide " "service, the system will be set to a new status of **Partial failure**." #: ../../kogumisteenus.rst:687 msgid "Eemaldatud" msgstr "Removed" #: ../../kogumisteenus.rst:689 msgid "Teenus on konfiguratsioonist eemaldatud." msgstr "The service has been removed from the configuration." #: ../../kogumisteenus.rst:693 msgid "Valijate nimekirjade olekud haldusteenuses" msgstr "Statuses of electoral rolls in the administrative service" #: ../../kogumisteenus.rst:695 msgid "Valijate nimekirja olek võib olla:" msgstr "The status of the voters list may be:" #: ../../kogumisteenus.rst:697 msgid "**Rakendamise ootel** - nimekiri on laaditud haldusteenusesse;" msgstr "**Pending** - the list has been uploaded to the management service;" #: ../../kogumisteenus.rst:699 msgid "**Rakendatud** - nimekiri on rakendatud kogumisteenusele;" msgstr "**Applied** - the list is applied to the collection service;" #: ../../kogumisteenus.rst:701 msgid "" "**Vigane** - nimekiri on märgitud vigaseks, haldusteenus uusi valijate " "nimekirjade muudatusi ei laadi;" msgstr "" "**Invalid** - the list is marked as invalid, the administrative service " "does not create new voter list changes;" #: ../../kogumisteenus.rst:704 msgid "**Vahele jäetud** - vigane nimekiri on märgitud vahelejätmiseks." msgstr "**Skipped** - an invalid list is marked for skipping." #: ../../kogumisteenus.rst:708 msgid "Valijate nimekirja olekudiagramm" msgstr "Voters list status diagram" #: ../../kogumisteenus.rst:710 msgid "Siirdeprotsessid:" msgstr "Transition processes:" #: ../../kogumisteenus.rst:712 msgid "Nimekirja laadimine haldusteenusesse:" msgstr "Uploading the list to the management service:" #: ../../kogumisteenus.rst:714 msgid "" "Algnimekirja laadib kogumisteenuse operaator, nimekirja olekuks saab " "**Rakendamise ootel**;" msgstr "" "The initial list will be loaded by the collection service operator, the " "status of the list will be **Pending**;" #: ../../kogumisteenus.rst:717 msgid "" "Muudatusnimekirja laadib haldusteenus. Vastavalt valideerimise tulemusele" " saab nimekirja olekuks kas **Rakendamise ootel** või **Vigane**;" msgstr "" "The change list is loaded by the management service. Depending on the " "result of the validation, the status of the list will be either " "**Pending** or **Viable**;" #: ../../kogumisteenus.rst:720 msgid "" "**Rakendamine kogumisteenusele**: viib läbi haldusteenus **rakendamise " "ootel** olekus nimekirjaga. Õnnestumisel määratakse nimekirja olekuks " "**Rakendatud**, vea korral **Vigane**;" msgstr "" "**Upgrading to collection service**: carries out a management service " "with a list in the **pending** state. If successful, the status of the " "list is set to **Applied**, if not successful, the status is set to " "**Invalid**;" #: ../../kogumisteenus.rst:724 msgid "" "**Vahelejätmine**: operaator määrab olekuga **Vigane** nimekirjale oleku " "**Vahele jäetud**." msgstr "" "**Skip**: the operator assigns the status **Invalid** to the list with " "the status **Skipped**." ================================================ FILE: Documentation/public/arhitektuur/locales/en/LC_MESSAGES/tehnoloogiad.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 15:28+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../tehnoloogiad.rst:6 msgid "Kasutatavad tehnoloogiad" msgstr "Technologies used" #: ../../tehnoloogiad.rst:9 msgid "Kogumisteenuse programmeerimiskeel" msgstr "Collection service programming language" #: ../../tehnoloogiad.rst:11 msgid "" "Kogumisteenuse tuumikfunktsionaalsus on programmeeritud keeles Go, mis " "vastab järgmistele hanke nõuetele:" msgstr "" "The core functionality of the collection service is programmed in the Go " "language, which meets the following procurement requirements:" #: ../../tehnoloogiad.rst:14 msgid "Staatiline tüüpimine;" msgstr "Static typing;" #: ../../tehnoloogiad.rst:16 msgid "Automaatne mäluhaldus;" msgstr "Automatic memory management;" #: ../../tehnoloogiad.rst:18 msgid "Kompilaator avatud lähtekoodiga;" msgstr "Open source compiler;" #: ../../tehnoloogiad.rst:20 msgid "Ribastamine (rööprapse)." msgstr "Parallel processing (co-routines)." #: ../../tehnoloogiad.rst:22 msgid "Kogumisteenuse haldusteenus on programmeeritud keeles Python." msgstr "The collection management service is programmed in Python." #: ../../tehnoloogiad.rst:26 msgid "Rakenduste programmeerimiskeel" msgstr "Programming language for applications" #: ../../tehnoloogiad.rst:28 msgid "" "Rakendused on programmeeritud keeles Java, mis vastab hanke nõuetele " "keele laia leviku ja jätkusuutlikkuse kohta." msgstr "" "The applications are programmed in Java, which fulfils the requirements " "of the call for tender for the wide distribution and sustainability of " "the language." #: ../../tehnoloogiad.rst:33 msgid "Projekti sõltuvused" msgstr "Project dependencies" #: ../../tehnoloogiad.rst:35 msgid "" "Projektis kasutatavad kolmandate osapoolte komponendid koos nende " "motiveeritud kasutamisvajadusega on üles loetletud järgnevates tabelites." " Eraldi tabelid on raamistiku pakendamiseks ja töötamiseks ning " "raamistiku arenduseks ja testimiseks." msgstr "" "The third-party components used in the project, together with their " "motivated use, are listed in the tables below. Separate tables are " "provided for the packaging and operation of the framework and for the " "development and testing of the framework." #: ../../tehnoloogiad.rst:40 msgid "" "Kõik IVXV projektis kasutatavad välised teegid asuvad ``ivxv-" "external.git`` hoidlas või on saadaval platvormil, kus rakendus tööle " "hakkab." msgstr "" "All external teegs used in the IVXV project are located in the ``ivxv-" "external.git`` repository or are available on the platform where the " "application will run." #: ../../tehnoloogiad.rst:43 msgid "Kõik kogumisteenuses kasutatavad komponendid on avatud lähtekoodiga." msgstr "All components used in the collection service are open source." #: ../../tehnoloogiad.rst:46 msgid "IVXV raamistiku tööks kasutatavad kolmandate osapoolte komponendid" msgstr "Third party components used for the operation of the IVXV framework" #: ../../tehnoloogiad.rst:50 ../../tehnoloogiad.rst:222 #: ../../tehnoloogiad.rst:268 msgid "Nimi" msgstr "Name" #: ../../tehnoloogiad.rst:51 ../../tehnoloogiad.rst:223 #: ../../tehnoloogiad.rst:269 msgid "Versioon" msgstr "Version" #: ../../tehnoloogiad.rst:52 ../../tehnoloogiad.rst:224 #: ../../tehnoloogiad.rst:270 msgid "Litsents (SPDX)" msgstr "Licence" #: ../../tehnoloogiad.rst:53 ../../tehnoloogiad.rst:225 #: ../../tehnoloogiad.rst:271 msgid "Kasutusvajadus" msgstr "Requirement" #: ../../tehnoloogiad.rst:55 msgid "`Bootstrap `_" msgstr "`Bootstrap `_" #: ../../tehnoloogiad.rst:56 msgid "3.4.1, JavaScript" msgstr "" #: ../../tehnoloogiad.rst:57 ../../tehnoloogiad.rst:62 #: ../../tehnoloogiad.rst:67 ../../tehnoloogiad.rst:72 #: ../../tehnoloogiad.rst:87 ../../tehnoloogiad.rst:97 #: ../../tehnoloogiad.rst:132 ../../tehnoloogiad.rst:137 #: ../../tehnoloogiad.rst:153 ../../tehnoloogiad.rst:158 #: ../../tehnoloogiad.rst:163 ../../tehnoloogiad.rst:168 #: ../../tehnoloogiad.rst:178 ../../tehnoloogiad.rst:213 #: ../../tehnoloogiad.rst:244 ../../tehnoloogiad.rst:254 msgid "MIT" msgstr "MIT" #: ../../tehnoloogiad.rst:58 ../../tehnoloogiad.rst:214 msgid "Kogumisteenuse haldusteenuse kasutajaliidese kujundus" msgstr "Collection management service interface design" #: ../../tehnoloogiad.rst:60 msgid "Bouncy Castle" msgstr "Bouncy Castle" #: ../../tehnoloogiad.rst:61 msgid "1.78.1, Java" msgstr "" #: ../../tehnoloogiad.rst:63 msgid "ASN1 käsitlemine, andmetüübi BigInteger abifunktsioonid" msgstr "ASN1 handling, BigInteger data type support functions" #: ../../tehnoloogiad.rst:65 msgid "`Bottle `_" msgstr "`Bottle `_" #: ../../tehnoloogiad.rst:66 msgid "0.13.2, Python" msgstr "" #: ../../tehnoloogiad.rst:68 msgid "Raamistik kogumisteenuse haldusteenuse veebiliidese teostamiseks" msgstr "" "Framework for the implementation of the web interface for the collection " "management service" #: ../../tehnoloogiad.rst:70 msgid "CAL10N" msgstr "CAL10N" #: ../../tehnoloogiad.rst:71 msgid "0.8.1, Java" msgstr "" #: ../../tehnoloogiad.rst:73 msgid "Mitmekeelsuse tugi, tõlkefailide valideerimine" msgstr "Multilingual support, validation of translation files" #: ../../tehnoloogiad.rst:75 msgid "Digidoc 4j" msgstr "Digidoc 4j" #: ../../tehnoloogiad.rst:76 msgid "5.3.1, Java" msgstr "" #: ../../tehnoloogiad.rst:77 msgid "LGPL-2.1-only" msgstr "LGPL-2.1-only" #: ../../tehnoloogiad.rst:78 msgid "BDoc konteinerite käsitlemine" msgstr "BDoc container handling" #: ../../tehnoloogiad.rst:80 msgid "Apache Commons (collections4 4.4)" msgstr "Apache Commons (collections4 4.4)" #: ../../tehnoloogiad.rst:81 msgid "Java" msgstr "" #: ../../tehnoloogiad.rst:82 ../../tehnoloogiad.rst:92 #: ../../tehnoloogiad.rst:102 ../../tehnoloogiad.rst:112 #: ../../tehnoloogiad.rst:122 ../../tehnoloogiad.rst:173 #: ../../tehnoloogiad.rst:208 ../../tehnoloogiad.rst:239 #: ../../tehnoloogiad.rst:280 msgid "Apache-2.0" msgstr "Apache 2.0" #: ../../tehnoloogiad.rst:83 msgid "Digidoc 4j ja PDFBox sõltuvused" msgstr "Digidoc 4j and PDFBox dependencies" #: ../../tehnoloogiad.rst:85 msgid "`Docopt `_" msgstr "`Docopt `_" #: ../../tehnoloogiad.rst:86 msgid "0.6.2, Python" msgstr "" #: ../../tehnoloogiad.rst:88 msgid "Kogumisteenuse haldusutiliitide käsurealiidese teostus" msgstr "" "Command line interface for collection service management tool" #: ../../tehnoloogiad.rst:90 msgid "`Fasteners `_" msgstr "`Fasteners `_" #: ../../tehnoloogiad.rst:91 msgid "0.19, Python" msgstr "" #: ../../tehnoloogiad.rst:93 msgid "Kogumisteenuse haldusteenuse protsesside lukustus" msgstr "Locking processes for the collection management service" #: ../../tehnoloogiad.rst:95 msgid "`gin-gonic `_" msgstr "`gin-gonic `_" #: ../../tehnoloogiad.rst:96 msgid "1.9.1, Go" msgstr "" #: ../../tehnoloogiad.rst:98 msgid "Veebiraamistik x-tee liidese jaoks" msgstr "Web-framework for X-road service interface" #: ../../tehnoloogiad.rst:100 msgid "`etcd `_" msgstr "`etcd `_" #: ../../tehnoloogiad.rst:101 msgid "3.5.9, Go" msgstr "" #: ../../tehnoloogiad.rst:103 msgid "Talletusteenusena kasutatav hajus võti-väärtus andmebaas" msgstr "Distributed key-value database used as a storage service" #: ../../tehnoloogiad.rst:105 msgid "Glassfish JAXB" msgstr "Glassfish JAXB" #: ../../tehnoloogiad.rst:106 msgid "4.0.5, Java" msgstr "" #: ../../tehnoloogiad.rst:107 ../../tehnoloogiad.rst:203 #: ../../tehnoloogiad.rst:229 msgid "BSD-3-Clause" msgstr "BSD 3 Clause" #: ../../tehnoloogiad.rst:108 msgid "Java XML teek" msgstr "Java XML library" #: ../../tehnoloogiad.rst:110 msgid "Gradle" msgstr "Gradle" #: ../../tehnoloogiad.rst:111 msgid "8.11, Java" msgstr "" #: ../../tehnoloogiad.rst:113 msgid "Java rakenduste ehitamise raamistik" msgstr "Framework for building Java applications" #: ../../tehnoloogiad.rst:115 msgid "`HAProxy `_" msgstr "`HAProxy `_" #: ../../tehnoloogiad.rst:116 msgid "2.4.24" msgstr "2.4.24" #: ../../tehnoloogiad.rst:117 msgid "GPL-2.0-or-later" msgstr "GPL-2.0-or-later" #: ../../tehnoloogiad.rst:118 msgid "Vahendusteenusena kasutatav TCP-proksi" msgstr "TCP proxy used as an intermediary service" #: ../../tehnoloogiad.rst:120 msgid "Jackson" msgstr "Jackson" #: ../../tehnoloogiad.rst:121 msgid "2.18.1, Java" msgstr "" #: ../../tehnoloogiad.rst:123 msgid "JSON vormingus failide lugemine ja kirjutamine" msgstr "Read and write JSON format files" #: ../../tehnoloogiad.rst:125 msgid "Jinja2" msgstr "Jinja2" #: ../../tehnoloogiad.rst:126 msgid "3.1.4, Python" msgstr "" #: ../../tehnoloogiad.rst:127 ../../tehnoloogiad.rst:188 #: ../../tehnoloogiad.rst:285 msgid "BSD" msgstr "BSD" #: ../../tehnoloogiad.rst:128 msgid "Jinja mallide kasutamine haldusteenuses" msgstr "Using Jinja templates in collection management service" #: ../../tehnoloogiad.rst:130 msgid "`jQuery `_" msgstr "`jQuery `_" #: ../../tehnoloogiad.rst:131 msgid "3.7.1, JavaScript" msgstr "" #: ../../tehnoloogiad.rst:133 ../../tehnoloogiad.rst:159 #: ../../tehnoloogiad.rst:164 ../../tehnoloogiad.rst:169 msgid "Kogumisteenuse haldusteenuse kasutajaliides" msgstr "Collection management service interface" #: ../../tehnoloogiad.rst:135 msgid "jsonschema" msgstr "jsonschema" #: ../../tehnoloogiad.rst:136 msgid "4.23.0, Python" msgstr "" #: ../../tehnoloogiad.rst:138 msgid "JSON valideerimine haldusteenuses" msgstr "JSON validation in collection management service" #: ../../tehnoloogiad.rst:140 msgid "Logback" msgstr "Logback" #: ../../tehnoloogiad.rst:141 msgid "1.5.12, Java" msgstr "" #: ../../tehnoloogiad.rst:142 ../../tehnoloogiad.rst:147 msgid "EPL-1.0 or LGPL-v2.1-only" msgstr "EPL-1.0 or LGPL-v2.1-only" #: ../../tehnoloogiad.rst:143 msgid "Logimise API teostus" msgstr "Implementation of logging API" #: ../../tehnoloogiad.rst:145 msgid "Logback JSON" msgstr "Logback JSON" #: ../../tehnoloogiad.rst:146 msgid "0.1.5, Java" msgstr "" #: ../../tehnoloogiad.rst:148 msgid "" "Logback logija laiendus JSON vormingus logikirjete koostamiseks Jackson " "teegi abil" msgstr "" "Logback logger extension for generating JSON format log entries using " "Jackson library." #: ../../tehnoloogiad.rst:151 msgid "`Logrus `_" msgstr "`Logrus `_" #: ../../tehnoloogiad.rst:152 msgid "1.9.3, Go" msgstr "" #: ../../tehnoloogiad.rst:154 msgid "Logimisraamistik x-tee liidese jaoks" msgstr "Logframework for X-road service interface" #: ../../tehnoloogiad.rst:156 msgid "`metisMenu `_" msgstr "`metisMenu `_" #: ../../tehnoloogiad.rst:157 msgid "1.1.3, JavaScript" msgstr "" #: ../../tehnoloogiad.rst:161 msgid "`FontAwesome `_" msgstr "`FontAwesome `_" #: ../../tehnoloogiad.rst:162 msgid "6.7.2, JavaScript" msgstr "" #: ../../tehnoloogiad.rst:166 msgid "`DataTables `_" msgstr "`DataTables `_" #: ../../tehnoloogiad.rst:167 msgid "2.3.2, JavaScript" msgstr "" #: ../../tehnoloogiad.rst:171 msgid "PDFBox" msgstr "PDFBox" #: ../../tehnoloogiad.rst:172 msgid "3.0.3, Java" msgstr "" #: ../../tehnoloogiad.rst:174 msgid "PDF vormingus raportite genereerimise tugi Java rakendustele" msgstr "Support for generating PDF reports for Java applications" #: ../../tehnoloogiad.rst:176 msgid "`PyYAML `_" msgstr "`PyYAML `_" #: ../../tehnoloogiad.rst:177 msgid "6.0.2, Python" msgstr "" #: ../../tehnoloogiad.rst:179 msgid "Kogumisteenuse seadistusfailide töötlemise tugi haldusteenusele" msgstr "" "Support for processing configuration files for the collection service to " "the management service" #: ../../tehnoloogiad.rst:181 msgid "python-crontab" msgstr "" #: ../../tehnoloogiad.rst:182 msgid "3.3.0, Python" msgstr "" #: ../../tehnoloogiad.rst:183 msgid "LGPLv3" msgstr "LGPLv3" #: ../../tehnoloogiad.rst:184 msgid "Crontab haldusteenuses" msgstr "Crontab in collection management service" #: ../../tehnoloogiad.rst:186 msgid "python-dateutil" msgstr "python-dateutil" #: ../../tehnoloogiad.rst:187 msgid "2.9.0, Python" msgstr "" #: ../../tehnoloogiad.rst:189 msgid "Kuupäevad ja kellaajad haldusteenuses" msgstr "Dates and times in collection management service" #: ../../tehnoloogiad.rst:191 msgid "python-debian" msgstr "python-debian" #: ../../tehnoloogiad.rst:192 msgid "0.1.49, Python" msgstr "" #: ../../tehnoloogiad.rst:193 msgid "GPLv2" msgstr "GPLv2" #: ../../tehnoloogiad.rst:194 msgid "Debian pakkide lugemine haldusteenuses" msgstr "Managing DEB files in collection management service" #: ../../tehnoloogiad.rst:196 msgid "pyopenssl" msgstr "pyopenssl" #: ../../tehnoloogiad.rst:197 msgid "24.2.1, Python" msgstr "" #: ../../tehnoloogiad.rst:198 msgid "Apache" msgstr "Apache" #: ../../tehnoloogiad.rst:199 msgid "OpenSSL kasutus haldusteenuses" msgstr "OpenSSL in collection management service" #: ../../tehnoloogiad.rst:201 msgid "`Schematics `_" msgstr "`Schematics `_" #: ../../tehnoloogiad.rst:202 msgid "2.1.1, Python" msgstr "" #: ../../tehnoloogiad.rst:204 msgid "Kogumisteenuse seadistusfailide valideerimise tugi haldusteenusele" msgstr "" "Support for validation of collection service configuration files for the " "management service" #: ../../tehnoloogiad.rst:206 msgid "SnakeYAML" msgstr "SnakeYAML" #: ../../tehnoloogiad.rst:207 msgid "2.3, Java" msgstr "" #: ../../tehnoloogiad.rst:209 msgid "YAML vormingus andmete lugemine" msgstr "Reading data in YAML format" #: ../../tehnoloogiad.rst:211 msgid "" "`SB Admin 2 `_" msgstr "" "`SB Admin 2 `_" #: ../../tehnoloogiad.rst:212 msgid "3.3.7+1, JavaScript" msgstr "" #: ../../tehnoloogiad.rst:217 msgid "IVXV raamistiku testide kasutatavad kolmandate osapoolte komponendid" msgstr "Third-party components to be used for IVXV Framework tests" #: ../../tehnoloogiad.rst:227 msgid "Hamcrest" msgstr "Hamcrest" #: ../../tehnoloogiad.rst:228 msgid "3.0, Java" msgstr "" #: ../../tehnoloogiad.rst:230 msgid "Loetavam assert-meetodite kasutamine Java üksuste testides" msgstr "More readable use of assert methods in Java unit tests" #: ../../tehnoloogiad.rst:232 msgid "JUnit" msgstr "JUnit" #: ../../tehnoloogiad.rst:233 msgid "5.10.0, Java" msgstr "" #: ../../tehnoloogiad.rst:234 msgid "EPL-1.0" msgstr "EPL-1.0" #: ../../tehnoloogiad.rst:235 msgid "Java testimisraamistik" msgstr "Java testing framework" #: ../../tehnoloogiad.rst:237 msgid "JUnitParams" msgstr "JUnitParams" #: ../../tehnoloogiad.rst:238 msgid "1.1.1, Java" msgstr "" #: ../../tehnoloogiad.rst:240 msgid "Testide parametriseerimise tugi" msgstr "Test parameterisation support" #: ../../tehnoloogiad.rst:242 msgid "Mockito" msgstr "Mockito" #: ../../tehnoloogiad.rst:243 msgid "5.14.2, Java" msgstr "" #: ../../tehnoloogiad.rst:245 msgid "Testitava koodi sõltuvuste mockimise tugi" msgstr "Support for mocking dependencies in code under test" #: ../../tehnoloogiad.rst:247 msgid "libdigidocpp-tools" msgstr "libdigidocpp-tools" #: ../../tehnoloogiad.rst:248 msgid "3.14.5 .1404" msgstr "3.14.5 .1404" #: ../../tehnoloogiad.rst:249 msgid "LGPL-2.1-or-later" msgstr "LGPL-2.1-or-later" #: ../../tehnoloogiad.rst:250 msgid "Testandmete genereerimine" msgstr "Test data generation" #: ../../tehnoloogiad.rst:252 msgid "PyTest" msgstr "PyTest" #: ../../tehnoloogiad.rst:253 msgid "7.4.2, Python" msgstr "" #: ../../tehnoloogiad.rst:255 msgid "Üksuste testimise tugi Pythonile" msgstr "Unit testing support for Python" #: ../../tehnoloogiad.rst:257 msgid "Requests" msgstr "Requests" #: ../../tehnoloogiad.rst:258 msgid "2.32.3, Python" msgstr "" #: ../../tehnoloogiad.rst:259 msgid "Apache 2.0" msgstr "Apache 2.0" #: ../../tehnoloogiad.rst:260 msgid "HTTP päringute moodul Pythoni testidele" msgstr "HTTP request module for Python tests" #: ../../tehnoloogiad.rst:263 msgid "" "IVXV raamistiku arendamiseks ja/või testimiseks kasutatavad kolmandate " "osapoolte tööriistad" msgstr "Third-party tools used to develop and/or test the IVXV framework" #: ../../tehnoloogiad.rst:273 msgid "`Behave `_" msgstr "`Behave `_" #: ../../tehnoloogiad.rst:274 msgid "1.2.6, Python" msgstr "" #: ../../tehnoloogiad.rst:275 msgid "BSD-2-Clause" msgstr "BSD 2 Clause" #: ../../tehnoloogiad.rst:276 msgid "Regressioonitestide käivitaja (*Behavior-driven development*)" msgstr "Regression test trigger (*Behavior-driven development*)" #: ../../tehnoloogiad.rst:278 msgid "`Docker `_" msgstr "`Docker `_" #: ../../tehnoloogiad.rst:279 msgid "18.06 (või uuem)" msgstr "18.06 (or newer)" #: ../../tehnoloogiad.rst:281 msgid "Regressioonitestide läbiviimise keskkond - tarkvarakonteinerid" msgstr "Regression testing environment - software containers" #: ../../tehnoloogiad.rst:283 msgid "`Sphinx `_" msgstr "`Sphinx `_" #: ../../tehnoloogiad.rst:284 msgid "7.2.5, Python" msgstr "" #: ../../tehnoloogiad.rst:286 msgid "Dokumentatsiooni genereerimine" msgstr "Generating documentation" ================================================ FILE: Documentation/public/arhitektuur/locales/en/LC_MESSAGES/vallasrezhiim.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 19:48+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../vallasrezhiim.rst:4 msgid "Rakendused" msgstr "Applications" #: ../../vallasrezhiim.rst:8 msgid "Üldpõhimõtted" msgstr "General principles" #: ../../vallasrezhiim.rst:10 msgid "" "Kõik rakendused on käsurealiidesega rakendused, mis on pakendatud töötama" " operatsioonisüsteemi Windows 10 (või uuem) keskkonnas. Komponentide " "kasutajaliidesed on ühekeelsed. Komponendid tarnitakse eestikeelsetena, " "nende tõlkimine on võimalik tõlkefaili abil." msgstr "" "All applications are command-line applications, packaged to work in " "Windows 10 (or later) operating system environment. Component user " "interfaces are monolingual. The components are delivered in Estonian, and" " can be translated using a translation file." #: ../../vallasrezhiim.rst:15 msgid "Rakendused on programmeeritud Java keeles." msgstr "The applications are developed in Java programming language." #: ../../vallasrezhiim.rst:17 msgid "" "Väliste infosüsteemidega suhtlevad rakendused kasutavad maksimaalselt " "olemasolevaid liideseid/andmestruktuure." msgstr "" "Applications interacting with external information systems make maximum " "use of existing interfaces/data structures." #: ../../vallasrezhiim.rst:20 msgid "" "Rakendused saavad oma sisendi rakenduste seadistustest ja seadistustes " "näidatud failidest failisüsteemis ning salvestavad oma väljundi kasutaja " "näidatud kausta failisüsteemis. Failid võivad paikneda ka operatiiv-" "mälukettal." msgstr "" "Applications get their input from the application settings and the files " "in the file system indicated in the settings, and store their output in " "the folder in the file system indicated by the user. Files may also be " "located on the memory-disk." #: ../../vallasrezhiim.rst:24 msgid "" "Relevantsed rakendused toetavad ElGamal krüptosüsteemi " "täisarvujäägikorpustel ning P-384 elliptkõveral. Lugemistõend on " "realiseeritud Schnorri nullteadmustõestusel põhineval protokollil." msgstr "" "Relevant applications support the ElGamal cryptosystem on prime order " "fields and the P-384 elliptic curve. The decryption proof is implemented " "using the Schnorr zero-knowledge protocol." #: ../../vallasrezhiim.rst:30 msgid "Rakenduste abimoodulid" msgstr "Applications support modules" #: ../../vallasrezhiim.rst:32 msgid "" "Valimise liides on rakenduste jaoks unifitseeritud, see võimaldab " "erinevate valimistüüpide realiseerimist moodulitena. Digiallkirja " "verifitseerimise funktsionaalsus on loodud `digidoc4j `_ teegi abil. Abimoodulite kasutamist alljärgnevatel" " skeemidel eraldi välja ei tooda." msgstr "" "The election interface is unified for applications, allowing different " "types of elections to be implemented as modules. The digital signature " "verification functionality has been created using the `digidoc4j " "`_ library. The use of the " "auxiliary modules is not explicitly described in the following diagrams." #: ../../vallasrezhiim.rst:39 msgid "Rakenduste seadistamine" msgstr "Setting up applications" #: ../../vallasrezhiim.rst:41 msgid "" "Rakendused seadistatakse kas digitaalallkirjastatud " "konfiguratsioonipakiga või käsureavõtmetega. Käsureavõtmed ei toeta " "hierarhilise struktuuriga seadistuste sisestamist. Seadistused " "konfiguratsioonipakis kirjeldatakse YAML-keeles:" msgstr "" "The applications are configured either with a digitally signed " "configuration package or with command line parameters. The latter do not " "support the entry of hierarchically structured configurations. The " "settings in the configuration package shall be described in YAML:" #: ../../vallasrezhiim.rst:88 msgid "Sisendite kooskõlalisuse kontroll" msgstr "Input consistency check" #: ../../vallasrezhiim.rst:90 msgid "" "Kõik rakendused teostavad konfiguratsioonile sisendite kooskõlalisuse " "kontrolli vastavalt nende poolt kasutatavale konfiguratsioonile:" msgstr "" "All applications perform configuration consistency checks on the inputs " "according to the configuration they use:" #: ../../vallasrezhiim.rst:93 msgid "sertifikaatide konfiguratsiooni laadimine;" msgstr "loading certificate configuration;" #: ../../vallasrezhiim.rst:95 msgid "konfiguratsiooni digiallkirja verifitseerimine;" msgstr "Digital signature verification of the configuration;" #: ../../vallasrezhiim.rst:97 msgid "ringkondade nimekirja verifitseerimine;" msgstr "verification of the list of districts;" #: ../../vallasrezhiim.rst:99 msgid "ringkondade nimekirja kooskõlalisuse kontroll;" msgstr "checking the consistency of the list of districts;" #: ../../vallasrezhiim.rst:101 msgid "ringkondade nimekirja laadimine;" msgstr "loading the list of districts;" #: ../../vallasrezhiim.rst:103 msgid "valikute nimekirja verifitseerimine;" msgstr "verification of the list of choices;" #: ../../vallasrezhiim.rst:105 msgid "valikute nimekirja kooskõlalisuse kontroll;" msgstr "checking the consistency of the list of choices;" #: ../../vallasrezhiim.rst:107 msgid "valikute nimekirja laadimine;" msgstr "loading the list of choices;" #: ../../vallasrezhiim.rst:109 msgid "valijate nimekirjade verifitseerimine;" msgstr "verification of voter lists;" #: ../../vallasrezhiim.rst:111 msgid "valijate nimekirjade kooskõlalisus kontroll;" msgstr "a check on the consistency of voter lists;" #: ../../vallasrezhiim.rst:113 msgid "valijate nimekirjade laadimine." msgstr "loading the voter lists." #: ../../vallasrezhiim.rst:117 msgid "Võtmerakendus" msgstr "Key application" #: ../../vallasrezhiim.rst:121 msgid "Võtmerakenduse liidesed" msgstr "Key application interfaces" #: ../../vallasrezhiim.rst:123 msgid "" "Võtmerakendusega genereeritakse iga hääletamise jaoks häälte salastamise " "ja häälte avamise võti, samuti toimub selle abil häälte lugemine ja " "tulemuse väljastamine." msgstr "" "The key application generates a key for encrypting and decrypting votes, " "as well as counting votes and issuing the result." #: ../../vallasrezhiim.rst:127 msgid "" "Võtmerakendus kasutab [DesmedtF89]_ läviskeemi, mis põhineb usaldataval " "osakujagajal ning rakendab Shamiri osakujagamist, mis on " "informatsiooniteoreetiliselt turvaline :math:`t < M` osapoole korral, kus" " M on lävipiir." msgstr "" "The key application uses the [DesmedtF89]_ threshold scheme based on a " "trusted dealer and implements Shamir secret-sharing, which is " "information-theoretically secure for :math:`t < M`, where M is the " "threshold." #: ../../vallasrezhiim.rst:132 msgid "" "Võtmeosakud genereeritakse operatiivmälus ning talletatakse " "PKCS15-liidese vahendusel kiipkaardile." msgstr "" "The key shares are generated in the operational memory and stored on the " "smart card via the PKCS15 interface." #: ../../vallasrezhiim.rst:135 msgid "Võtmerakenduse sisend võtme genereerimisel on:" msgstr "The input to the key application when generating a key is:" #: ../../vallasrezhiim.rst:137 ../../vallasrezhiim.rst:161 msgid "Võtmepaari identifikaator;" msgstr "Key pair identifier;" #: ../../vallasrezhiim.rst:139 msgid "" "Krüptosüsteemi ElGamal spetsifikatsioon – täisarvujäägikorpus või P-384 " "elliptkõver ning võtmepikkus;" msgstr "" "Specification of the ElGamal cryptosystem - prime order field or P-384 " "elliptic curve and key length;" #: ../../vallasrezhiim.rst:142 msgid "" "M-N läviskeemi spetsifikatsioon, mis peab vastama reeglile :math:`N >= 2 " "* M - 1`;" msgstr "" "Specification of the M-N threshold scheme, which must satisfy the rule " ":math:`N >= 2 * M - 1`;" #: ../../vallasrezhiim.rst:145 msgid "N PKCS15-ühilduvat kiipkaarti;" msgstr "N PKCS15-compatible smart card;" #: ../../vallasrezhiim.rst:147 msgid "Võtmerakenduse väljund võtme genereerimisel on:" msgstr "The output of the key application when generating a key is:" #: ../../vallasrezhiim.rst:149 msgid "Isesigneeritud sertifikaat;" msgstr "Self-signed certificate;" #: ../../vallasrezhiim.rst:151 msgid "N võtmeosakut talletatuna kiipkaartidel;" msgstr "N key shares stored on smart cards;" #: ../../vallasrezhiim.rst:153 ../../vallasrezhiim.rst:174 msgid "Rakenduse detailne tegevuslogi;" msgstr "Detailed activity log of the application;" #: ../../vallasrezhiim.rst:155 ../../vallasrezhiim.rst:176 msgid "Rakenduse detailne vealogi." msgstr "A detailed error log for the application." #: ../../vallasrezhiim.rst:157 msgid "Võtmerakenduse sisend häälte lugemisel on:" msgstr "The key application input for vote counting is:" #: ../../vallasrezhiim.rst:159 msgid "Miksitud hääled;" msgstr "Mixed ballots;" #: ../../vallasrezhiim.rst:163 msgid "M võtmeosakut vastavalt läviskeemi spetsifikatsioonile." msgstr "M key shares according to the threshold scheme specification." #: ../../vallasrezhiim.rst:165 msgid "Võtmerakenduse väljund häälte lugemisel on:" msgstr "The output of the key application for counting votes is:" #: ../../vallasrezhiim.rst:167 msgid "Signeeritud hääletamistulemus;" msgstr "Signed results;" #: ../../vallasrezhiim.rst:169 msgid "Kehtetute häälte loend;" msgstr "List of invalid votes;" #: ../../vallasrezhiim.rst:171 msgid "" "Lugemistõend (Schnorri nullteadmustõestusel põhinev protokoll vastavalt " "hankedokumentides viidatule);" msgstr "" "Decryption proof (Schnorr's zero knowledge protocol as referred to in the" " contract documents);" #: ../../vallasrezhiim.rst:179 msgid "Töötlemisrakendus" msgstr "Processing application" #: ../../vallasrezhiim.rst:181 msgid "" "Töötlemisrakendusega verifitseeritakse, tühistatakse ning anonüümitakse " "hääletamisperioodil kogutud hääli vastavalt Üldkirjelduse jaotisele 7.6." msgstr "" "The processing application verifies, revokes and anonymises the votes " "collected during the voting period in accordance with Section 7.6 of the " "General Description." #: ../../vallasrezhiim.rst:184 msgid "Töötlemisrakenduse sisendid on:" msgstr "The inputs to the processing application are:" #: ../../vallasrezhiim.rst:186 msgid "kogumisteenuse poolt talletatud elektroonilised hääled;" msgstr "electronic votes recorded by the collection service;" #: ../../vallasrezhiim.rst:188 msgid "registreerimisteenuse poolt väljastatud ajamärgendid;" msgstr "time stamps issued by the registration service;" #: ../../vallasrezhiim.rst:190 msgid "valijate nimekirjad;" msgstr "voter lists;" #: ../../vallasrezhiim.rst:192 msgid "ringkondade nimekiri;" msgstr "list of districts;" #: ../../vallasrezhiim.rst:194 msgid "tühistusnimekirjad;" msgstr "revocation lists;" #: ../../vallasrezhiim.rst:196 msgid "ennistusnimekirjad." msgstr "restoration lists." #: ../../vallasrezhiim.rst:198 msgid "Töötlemisrakenduse väljundid on:" msgstr "The outputs of the processing application are:" #: ../../vallasrezhiim.rst:200 msgid "rakenduse detailne tegevuslogi;" msgstr "detailed activity log of the application;" #: ../../vallasrezhiim.rst:202 msgid "rakenduse detailne vealogi;" msgstr "detailed error log of the application;" #: ../../vallasrezhiim.rst:204 msgid "e-hääletanute nimekiri PDF-vormingus, vastavalt töötlemise etapile;" msgstr "the list of e-voters in PDF format, according to the stage of processing;" #: ../../vallasrezhiim.rst:206 msgid "" "e-hääletanute nimekiri masintöödeldaval kujul, vastavalt töötlemise " "etapile;" msgstr "" "the list of e-voters in a machine-processable format, according to the " "stage of processing;" #: ../../vallasrezhiim.rst:208 msgid "anonüümitud hääled." msgstr "anonymised ballots." #: ../../vallasrezhiim.rst:210 msgid "" "Lisaks varem defineeritud liidestele ja sõltuvustele kasutab " "töötlemisrakendus kolmanda osapoole teeki PDF'ide väljastamise " "funktsionaalsuse teostamiseks." msgstr "" "In addition to the interfaces and dependencies defined earlier, the " "processing application uses a third-party library to perform PDF output " "functionality." #: ../../vallasrezhiim.rst:215 msgid "Töötlemisrakenduse liidesed" msgstr "Processing application interfaces" #: ../../vallasrezhiim.rst:218 msgid "Elektrooniliste häälte täielik töötlemine" msgstr "Complete processing of electronic voices" #: ../../vallasrezhiim.rst:220 msgid "" "Elektrooniliste häälte täielik töötlemine on tegevus, mille käigus " "töötlemisrakendus võrdleb Kogumisteenuse poolt talletatud häälte hulka " "registreerimisteenuse poolt talletatud häälte hulgaga, kontrollib " "talletatud häälte vastavust valimiste konfiguratsioonile, tuvastab " "loendamisele minevad hääled ning anonüümib need Võtmerakendusele üle " "andmiseks." msgstr "" "Complete processing of electronic ballots is the process whereby the " "processing application compares the number of ballots stored by the " "Collection Service with the number of ballots stored by the Registration " "Service, verifies that the stored ballots match the election " "configuration, identifies the ballots to be counted and anonymizes them " "for delivery to the Key Application." #: ../../vallasrezhiim.rst:226 ../../vallasrezhiim.rst:254 msgid "rakenduse seadistuste laadimine;" msgstr "loading app settings;" #: ../../vallasrezhiim.rst:228 ../../vallasrezhiim.rst:256 msgid "elektrooniliste häälte digitaalallkirjade verifitseerimine;" msgstr "verification of digital signatures of electronic votes;" #: ../../vallasrezhiim.rst:230 msgid "registreerimisteenuse kinnituste verifitseerimine;" msgstr "verification of registration service confirmations;" #: ../../vallasrezhiim.rst:232 msgid "ajatemplite verifitseerimine;" msgstr "verification of time stamps;" #: ../../vallasrezhiim.rst:234 msgid "iga valija kohta viimase kehtiva hääle tuvastamine;" msgstr "identifying the last valid vote for each voter;" #: ../../vallasrezhiim.rst:236 msgid "algse elektrooniliselt hääletanute nimekirja väljastamine PDF-vormingus;" msgstr "issuing the original list of electronic voters in PDF format;" #: ../../vallasrezhiim.rst:238 msgid "tühistus- ja ennistusnimekirjade verifitseerimine;" msgstr "verification of revocation and restoration lists;" #: ../../vallasrezhiim.rst:240 msgid "tühistus- ja ennistusnimekirjade kooskõlalisuse kontroll;" msgstr "checking the consistency of cancellation and reinstatement lists;" #: ../../vallasrezhiim.rst:242 msgid "tühistus- ja ennistusnimekirjade rakendamine;" msgstr "the implementation of revocation and restoration lists;" #: ../../vallasrezhiim.rst:244 msgid "" "miksimisele minevate häälte nimekirja koostamine, krüptogrammide " "eraldamine digitaalallkirjadest;" msgstr "" "drawing up a list of votes to be mixed, separating ciphertexts from " "digital signatures;" #: ../../vallasrezhiim.rst:247 msgid "" "lõpliku elektrooniliselt hääletanute nimekirja väljastamine masinloetavas" " vormingus." msgstr "issuing the final list of electronic voters in machine-readable format." #: ../../vallasrezhiim.rst:252 msgid "Elektrooniliselt hääletanute nimekirja genereerimine" msgstr "Generating a list of voters electronically" #: ../../vallasrezhiim.rst:258 msgid "algse elektrooniliselt hääletanute nimekirja väljastamine PDF-vormingus." msgstr "issuing the original list of electronic voters in PDF format." #: ../../vallasrezhiim.rst:262 msgid "Auditirakendus" msgstr "Audit application" #: ../../vallasrezhiim.rst:266 msgid "Auditirakenduse liidesed" msgstr "Audit application interfaces" #: ../../vallasrezhiim.rst:268 msgid "" "Auditirakendusega (joonis 9) verifitseeritakse matemaatiliselt häälte " "kokkulugemise korrektsust ning miksimise kasutamisel ka miksimise " "korrektsust." msgstr "" "The audit application (Figure 9) mathematically verifies the correctness " "of the voice aggregation and, when mixing is used, the correctness of the" " mixing." #: ../../vallasrezhiim.rst:271 msgid "Auditirakenduse sisendid on;" msgstr "The inputs to the audit application are;" #: ../../vallasrezhiim.rst:273 msgid "anonüümitud hääled;" msgstr "anonymised ballots;" #: ../../vallasrezhiim.rst:275 msgid "miksitud hääled;" msgstr "mixed ballots;" #: ../../vallasrezhiim.rst:277 msgid "Verificatumi miksimistõend;" msgstr "Verificatum mixing proof;" #: ../../vallasrezhiim.rst:279 msgid "hääletamistulemus." msgstr "the tally." #: ../../vallasrezhiim.rst:281 msgid "" "Auditirakenduse väljund on rakenduse detailne tegevuslogi, mis sisaldab " "ka hinnangut auditi tervikliku õnnestumise kohta. Vajadusel väljastatakse" " ka rakenduse detailne vealogi." msgstr "" "The output of the audit application is a detailed log of the " "application's activities, including an assessment of the overall success " "of the audit. If required, a detailed error log of the application is " "also output." ================================================ FILE: Documentation/public/arhitektuur/locales/en/LC_MESSAGES/viited.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 18:28+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../viited.rst:4 msgid "" "Desmedt, Y. & Frankel, Y. Brassard, G. (Ed.) Threshold Cryptosystems " "Advances in Cryptology - CRYPTO '89, 9th Annual International Cryptology " "Conference, Santa Barbara, California, USA, August 20-24, 1989, " "Proceedings, Springer, 1989, 435, 307-315." msgstr "" "Desmedt, Y. & Frankel, Y. Brassard, G. (Ed.) Threshold Cryptosystems " "Advances in Cryptology - CRYPTO '89, 9th Annual International Cryptology " "Conference, Santa Barbara, California, USA, August 20-24, 1989, " "Proceedings, Springer, 1989, 435, 307-315." #: ../../viited.rst:9 msgid "" "Sven Heiberg, Tarvi Martens, Priit Vinkel, Jan Willemson, Improving the " "verifiability of the Estonian Internet Voting scheme. In Robert Krimmer, " "Melanie Volkamer, Jordi Barrat, Josh Benaloh, Nicole Goodman, Peter Y.A. " "Ryan, Oliver Spycher, Vanessa Teague, Gregor Wenda (Eds.), The " "International Conference on Electronic Voting E-Vote-ID 2016, 18-21 " "October 2016, Lochau/Bregenz, Austria, TUT Press, pp. 213-229, ISBN " "978-9949-83-022-0" msgstr "" "Sven Heiberg, Tarvi Martens, Priit Vinkel, Jan Willemson, Improving the " "verifiability of the Estonian Internet Voting scheme. In Robert Krimmer, " "Melanie Volkamer, Jordi Barrat, Josh Benaloh, Nicole Goodman, Peter Y.A. " "Ryan, Oliver Spycher, Vanessa Teague, Gregor Wenda (Eds.), The " "International Conference on Electronic Voting E-Vote-ID 2016, 18-21 " "October 2016, Lochau/Bregenz, Austria, TUT Press, pp. 213-229, ISBN " "978-9949-83-022-0" #: ../../viited.rst:16 msgid "" "Tehniline kirjeldus. Elektroonilise hääletamise infosüsteemi arenduse " "hange, Vabariigi Valimiskomisjon, 2016" msgstr "" "Technical description. Tender for the development of an electronic voting" " information system, National Electoral Committee, 2016" #: ../../viited.rst:19 msgid "" "Elektroonilise hääletamise üldraamistik ja selle kasutamine Eesti " "riiklikel valimistel. Elektroonilise Hääletamise Komisjon, Tallinn 2016" msgstr "" "General framework for electronic voting and its use in Estonian national " "elections. Electronic Voting Commission, Tallinn 2016" ================================================ FILE: Documentation/public/arhitektuur/locales/en/LC_MESSAGES/yldpohimotted.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 15:28+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../yldpohimotted.rst:4 msgid "Sissejuhatus" msgstr "Introduction" #: ../../yldpohimotted.rst:6 msgid "" "Elektroonilise hääletamise infosüsteem IVXV on loodud lähtuvalt " "e-hääletamise raamistikust [ÜK2016]_ ja riigihanke 171780 tehnilisest " "kirjeldusest [TK2016]_. Käesolevas dokumendis kirjeldatakse IVXV " "arhitektuurset lahendust. Elektroonilise hääletamise infosüsteem koosneb " "vallasrežiimirakendustest ning sidusrežiimikomponentidest. Täiendavalt " "sõltub infosüsteem välistest infosüsteemidest ning mõjutab vahetult " "elektrooniliseks hääletamiseks ja hääle kontrollimiseks kasutatavaid " "komponente." msgstr "" "The IVXV electronic voting information system has been developed on the " "basis of the e-voting framework [ÜK2016]_ and the technical specification" " of public procurement 171780 [TK2016]_. This document describes the " "architectural design of IVXV. The eVoting Information System consists of " "the offline applications and the online components. In addition, the " "information system depends on external information systems and directly " "affects the components used for electronic voting and vote verification." #: ../../yldpohimotted.rst:14 msgid "" "Arhitektuuridokument kirjeldab IVXV komponente, nende omavahelisi " "liideseid ja liideseid väliste süsteemidega ning komponentide poolt " "realiseeritavaid protokolle." msgstr "" "The architecture document describes the IVXV components, their interfaces" " with each other and with external systems, and the protocols implemented" " by the components." #: ../../yldpohimotted.rst:18 msgid "IVXV kontseptsioon" msgstr "IVXV Concept" #: ../../yldpohimotted.rst:20 msgid "" "Üldine, kuid terviklik ülevaade elektroonilise hääletamise raamistiku " "(\"IVXV\") tehnilisest ja organisatsioonilisest poolest ning selle " "rakendamisest Eesti riiklikel valimistel on antud e-hääletamise " "raamistiku üldkirjelduses [ÜK2016]_." msgstr "" "A general but comprehensive overview of the technical and organisational " "aspects of the electronic voting framework (\"IVXV\") and its " "implementation in Estonian national elections is given in the general " "description of the e-voting framework [ÜK2016]_." #: ../../yldpohimotted.rst:25 msgid "" "IVXV infosüsteemina teostab \"ümbrikuskeemil\" põhinevat e-hääletamise " "protokolli. IVXV toimib hääletamiseelsel etapil, hääletamisetapil, " "töötlusetapil ning lugemisetapil ja pakub vahendeid elektroonilise " "hääletamise protsessis osalemiseks Korraldajale, Lugejale, Hääletajale, " "Kogujale, Töötlejale, Miksijale, Audiitorile, Klienditoele, Valijate " "nimekirja koostajale ja täiendajale." msgstr "" "As an information system, IVXV implements an e-voting protocol based on " "an \"double-envelope scheme\". IVXV operates at the pre-voting stage, the" " voting stage, the processing stage and the counting stage, and provides " "the tools for the participation in the electronic voting process of the " "Organiser, Tallier, Voter, Collector, Processor, Registrar, Auditor, " "Client Support and Voter List manager." #: ../../yldpohimotted.rst:32 msgid "" "Infosüsteemi komponendid on Kogumisteenus, Töötlemisrakendus, " "Võtmerakendus ning Auditirakendus. Infosüsteemiga on tihedalt seotud " "Valijarakendus, Kontrollrakendus ning Miksimisrakendus." msgstr "" "The components of the information system are the Collection Service, the " "Processing Application, the Key Application and the Audit Application. " "Closely linked to the Information System are the Voting Application, the " "Verification Application and the Mixing Application." #: ../../yldpohimotted.rst:36 msgid "" "Infosüsteem kasutab oma töös väliseid teenuseid - Tuvastusteenus, " "Allkirjastamisteenus, Registreerimisteenus, Valimiste Infosüsteem ning " "X-tee." msgstr "" "The information system uses external services - Authentication Service, " "Signature Service, Registration Service, Election Management System and " "X-Road." #: ../../yldpohimotted.rst:40 msgid "IVXV krüptograafiline protokoll" msgstr "IVXV Cryptographic Protocol" #: ../../yldpohimotted.rst:42 msgid "" "Elektroonilise hääletamise turvalisuse, verifitseeritavuse ning " "hääletamise salajasuse, hääletamise korrektsuse ja hääletaja sõltumatuse " "saavutamiseks on rangelt kirjeldatud elektroonilise hääletamise " "krüptograafiline protokoll [HMVW16]_. Protokoll annab vajaliku ja piisava" " ülevaate IVXV ülesehitusest ning selle turvaaspektidest. IVXV " "komponendid realiseerivad krüptograafilise protokolli alamosi." msgstr "" "In order to achieve the security, verifiability and secrecy of electronic" " voting, the correctness of the voting and the independence of the voter," " the cryptographic protocol for electronic voting [HMVW16]_ is strictly " "described. The protocol provides a necessary and sufficient overview of " "the IVXV architecture and its security aspects. The components of IVXV " "implement sub-components of the cryptographic protocol." #: ../../yldpohimotted.rst:50 msgid "Notatsioon" msgstr "Notation" #: ../../yldpohimotted.rst:52 msgid "" "Arhitektuurse lahenduse visandi illustreerimiseks kasutatakse dokumendis " "UML-skeeme, kus eristame värvide ja märgenditega ``<<>>`` kodeeritult " "olemite – tegijad, liidesed, komponendid – järgmisi aspekte:" msgstr "" "To illustrate a sketch of the architectural solution, the document uses " "UML diagrams, where we distinguish the following aspects of entities - " "actors, interfaces, components - coded with colours and ``<<>>``:" #: ../../yldpohimotted.rst:56 msgid "" "Märgend ``<>`` (Kollane) – infosüsteemi liides või komponent " "defineeritakse/realiseeritakse konkreetse pakkumuse raames tehtavate " "tööde käigus" msgstr "" "Mark ``<>`` (Yellow) - The information system interface or " "component will be defined/realised during the works of a specific tender." #: ../../yldpohimotted.rst:60 msgid "" "Märgend ``<>`` (Punane) – infosüsteem sõltub mingi " "funktsionaalsuse realiseerimisel kolmanda osapoole komponendist või " "olemasolevast liidesest, mille ümberdefineerimine eeldab ka kolmandate " "osapoolte tööd." msgstr "" "``<<>`` (Red) - The information system depends on a third-party" " component or an existing interface for the implementation of some " "functionality, the redefinition of which also requires third-party work." #: ../../yldpohimotted.rst:64 msgid "" "Märgend ``<>`` (Pruun) – sarnane eelmisele, kuid liidese/komponendi " "omanikuks on VVK." msgstr "" "Flag ``<<>`` (Brown) - similar to the previous one, but the " "interface/component is owned by NEC." #: ../../yldpohimotted.rst:67 msgid "" "Märgend ``<>`` (Must) – infosüsteemi jaoks oluline liides " "on määratlemata." msgstr "" "Flag ``<>`` (Black) - Interface relevant to the information " "system is undefined." #: ../../yldpohimotted.rst:72 msgid "Näiteskeem" msgstr "Example scheme" ================================================ FILE: Documentation/public/arhitektuur/model/Makefile ================================================ # Source diagrams are all in different .pu files SRC_DIAG=example ms-collector-status ms-management-service-components \ ms-service-status-changes ms-service-status ms-upload-command \ ms-voter-list-status PARENT=development # Sub-diagrams are generated from $(PARENT).pu SUB_DIAG=processing collector_microservices collector_extension monitoring \ app_modules key audit include ../../../common-model.mk # Set environment variables for subdiagrams collector_extension.env: $(eval DIAGRAM_DEF=-DCOLLECTOR_EXTENSION) collector_microservices.env: $(eval DIAGRAM_DEF=-DCOLLECTOR_MICROSERVICES) processing.env: $(eval DIAGRAM_DEF=-DPROCESSING_APPLICATION) key.env: $(eval DIAGRAM_DEF=-DKEY_APPLICATION) audit.env: $(eval DIAGRAM_DEF=-DAUDIT_APPLICATION) monitoring.env: $(eval DIAGRAM_DEF=-DMONITORING) app_modules.env: $(eval DIAGRAM_DEF=-DAPP_MODULES) ================================================ FILE: Documentation/public/arhitektuur/model/actors.pu ================================================ @startuml :Omanik: as Omanik <> actor Hääletaja <> actor Töötleja <> actor Andmeaudiitor <> actor Klienditugi <> actor Kogumisteenus <> actor Registreerimisteenus <> actor Autentimisteenus <> actor Allkirjateenus <> @enduml ================================================ FILE: Documentation/public/arhitektuur/model/collector-if.pu ================================================ @startuml left to right direction [Kogumisteenus] as collector package "Keskkonnateenused" { [Registreerimisteenus] as tsa [Autentimisteenus] as auth [Allkirjateenus] as sign } [Nimekirjad] as voterlist [Varundamine] as backup actor Omanik as owner actor Töötleja as offline actor Klienditeenindaja as helpdesk actor Hääletaja as voter actor :Kogumisteenuse admin: as admin actor :Kogumisteenuse kaugadmin: as radmin interface "Valimise defineerimine" as i_define interface "Ümbrikute väljastamine" as i_export interface "Hääletamine" as i_vote interface "Kontrollimine" as i_verify interface "Valikute nimekiri" as i_cls interface "Käsurida" as i_localadmin interface "Kaughaldus" as i_remoteadmin interface "Monitooring" as i_monitor interface "Helpdesk" as i_helpdesk interface "Varundamine" as i_backup interface "Nimekirjade uuendused" as i_voterlist collector -down- i_cls collector -down- i_vote collector -down- i_verify voter -up-> i_vote voter -up-> i_verify voter -up-> i_cls collector -up- i_localadmin collector -up- i_helpdesk collector -up- i_monitor collector -up- i_remoteadmin admin -down-> i_localadmin helpdesk -down-> i_helpdesk radmin -down-> i_monitor radmin -left-> i_remoteadmin collector -right- i_define collector -right- i_export owner -left-> i_define offline -left-> i_export owner -up-> i_remoteadmin voterlist -right- i_voterlist backup -right- i_backup collector .left.> i_backup collector .left.> i_voterlist @enduml ================================================ FILE: Documentation/public/arhitektuur/model/collector-in.pu ================================================ @startuml left to right direction package "Kogumisteenus" { [Storage] as collector [Log] as log [Eligibility] as elig [Verification] as verif [Admin] as adminc interface "Valimise defineerimine" as i_define interface "Ümbrikute väljastamine" as i_export interface "Hääletamine" as i_vote interface "Kontrollimine" as i_verify interface "Valikute nimekiri" as i_cls interface "Käsurida" as i_localadmin interface "Kaughaldus" as i_remoteadmin interface "Monitooring" as i_monitor interface "Helpdesk" as i_helpdesk } elig -- collector verif -- collector verif ..> log elig ..> log collector ..> log package "Keskkonnateenused" { [Registreerimisteenus] as tsa [Autentimisteenus] as auth [Allkirjateenus] as sign } [Nimekirjad] as voterlist [Varundamine] as backup collector ..> tsa i_vote ..> sign i_cls ..> auth interface "Varundamine" as i_backup interface "Nimekirjade uuendused" as i_voterlist elig -up- i_cls elig -up- i_vote verif -up- i_verify collector -down- i_localadmin log -down- i_helpdesk log -down- i_monitor adminc -down- i_remoteadmin adminc -down- i_define adminc -down- i_export voterlist -right- i_voterlist backup -right- i_backup collector .left.> i_backup elig .left.> i_voterlist @enduml ================================================ FILE: Documentation/public/arhitektuur/model/development.pu ================================================ @startuml !ifdef MONITORING !define COLLECTOR !define OWNER !endif !ifdef KEY_APPLICATION !define OWNER !define GENERIC_APP !endif !ifdef AUDIT_APPLICATION !define EXTERNAL_MODULES !define GENERIC_APP !endif !ifdef PROCESSING_APPLICATION !define GENERIC_APP !define EXTERNAL_MODULES !endif !ifdef APP_MODULES !define EXTERNAL_MODULES !define HELPER_MODULES !endif !ifdef COLLECTOR_MICROSERVICES !define COLLECTOR !define SERVICES !define VOTER !endif !ifdef COLLECTOR_EXTENSION !define COLLECTOR !define EXTENSION_MODULES !define EXTERNAL_INTERFACES !endif !include skin.inc !ifdef GENERIC_APP interface "TR_APP_LOG()" <> as i_app_log !endif !ifdef PROCESSING_APPLICATION interface "TR_IVOTERS_PDF()" <> as i_ivoters_pdf !define ENCRYPTED_VOTES !endif !ifdef KEY_APPLICATION interface "TR_KEY_SHARE()" <> as i_key_share interface "TR_INVALID_VOTES()" <> as i_invalid_votes interface "TR_CERTIFICATE()" <> as i_certificate !define AUDITABLE !endif !ifdef AUDIT_APPLICATION interface "TR_MIXING_PROOF()" <> as i_mixing_proof !define AUDITABLE !endif !ifdef AUDITABLE interface "TR_DECRYPTION_PROOF()" <> as i_decryption_proof interface "TR_VOTING_RESULT()" <> as i_voting_result interface "TR_MIXED_VOTES()" <> as i_mixed_votes !define ENCRYPTED_VOTES !endif !ifdef ENCRYPTED_VOTES interface "TR_ENCRYPTED_VOTES()" <> as i_encrypted_votes !endif 'interface "TR_CONF_BUNDLE()" <> as i_conf_bundle /' ' ' ACTORS ' '/ !ifdef OWNER actor "TR_A_OWNER()" <> as a_owner !endif !ifdef MONITORING actor "TR_A_HELPDESK()" <> as a_helpdesk actor "TR_A_SYSADMIN()" <> as a_sysadmin !endif !ifdef KEY_APPLICATION actor "TR_A_KEYMANAGER()" <> as a_keymanager a_keymanager ..> i_key_share !endif !ifdef PROCESSING_APPLICATION actor "TR_A_OFFLINE_PROCESSOR()" <> as a_offline_processor !endif !ifdef AUDIT_APPLICATION actor "TR_A_AUDITOR()" <> as a_auditor !endif /' ' ' EXTERNAL SERVICES ' '/ !ifdef EXTERNAL_INTERFACES interface "TR_SK_OCSP()" <> as i_sk_ocsp interface "TR_SK_AUTH()" <> as i_sk_auth interface "TR_RFC_3161()" <> as i_rfc_3161 interface "TR_MID()" <> as i_mid !endif !ifdef PROCESSING_APPLICATION interface "TR_REGISTERED_VOTES()" <> as i_registered_votes !endif !ifdef EXTERNAL_SERVICES [TR_SK_OCSP()] <> as sk_ocsp sk_ocsp -up- i_sk_ocsp sk_ocsp -down- i_registered_votes [TR_RFC_3161()] <> as rfc_3161 rfc_3161 -up- i_rfc_3161 rfc_3161 -down- i_registered_votes [TR_DDOC_SERVICE()] <> as ddoc_service ddoc_service -up- i_mid !endif !ifdef MONITORING [TR_ELECTION_WWW()] <> as election_www [TR_ZABBIX_EXT()] <> as zabbix_ext '[TR_MESSENTE()] <> as messente 'interface "TR_MESSENTE()" <> as i_messente interface "TR_MONITOR()" <> as i_monitor interface "TR_HELPDESK()" <> as i_helpdesk 'messente -up- i_messente !endif !ifdef PROCESSING_APPLICATION interface "TR_VIS_VOTERS()" <> as i_vis_voters interface "TR_VIS_REVOKE()" <> as i_vis_revoke interface "TR_POP_VOTERS()" <> as i_pop_voters interface "TR_VIS_DIST()" <> as i_vis_dist !endif '[TR_VIS()] <> as vis 'interface "TR_VIS_RESULTS()" <> as i_vis_results 'vis -up- i_vis_results 'interface "TR_VIS_CANDS()" <> as i_vis_cands 'vis - i_vis_cands 'vis -up- i_vis_dist !ifdef VIS vis -up- i_vis_voters vis -up- i_vis_revoke [TR_POP()] <> as pop pop -up- i_pop_voters !endif !ifdef EXTERNAL_MODULES [TR_JDIGIDOC()] <> as jdigidoc interface "TR_JAVA()" <> as i_java i_java -right- jdigidoc !endif !ifdef HELPER_MODULES package "TR_P_HELPERS()" as p_helpers { interface "TR_ELEC()" <> as elec [TR_RK_ELEC()] <> as rk_elec [TR_RH_ELEC()] <> as rh_elec [TR_EP_ELEC()] <> as ep_elec [TR_KOV_ELEC()] <> as kov_elec rk_elec -up- elec rh_elec -up- elec ep_elec -up- elec kov_elec -up- elec } !endif !ifdef PROCESSING_APPLICATION interface "TR_EXPORT_VOTES()" <> as i_export_votes !endif !ifdef COLLECTOR package "TR_P_COLLECTOR()" as p_collector { !ifdef SUPPORT [TR_ADMIN_APP()] <> as admin_app ' admin_app - i_export_votes interface "TR_LOCALADMIN()" <> as i_localadmin interface "TR_REMOTEADMIN()" <> as i_remoteadmin admin_app -up- i_localadmin admin_app -left- i_remoteadmin [TR_BACKUP()] <> as backup interface "TR_BACKUP()" <> as i_backup backup - i_backup !endif !ifdef MONITORING interface "TR_LOG_INT()" <> as i_log_int interface "TR_ZABBIX()" <> as i_zabbix rectangle "TR_R_MONITORING()" as r_monitoring { [TR_IVXV_MONITOR()] <> as ivxv_monitor database "TR_MONITOR_DB()" as monitor_db { } interface "TR_LOG_EXT()" <> as i_log_ext ' interface "TR_LOG_SMTP()" <> as i_log_smtp ' interface "TR_LOG_SMS()" <> as i_log_sms ivxv_monitor -down- i_log_int ' ivxv_monitor -down- i_log_smtp ' ivxv_monitor -down- i_log_sms ivxv_monitor -up- i_log_ext ivxv_monitor -up- i_zabbix ivxv_monitor -left-> monitor_db zabbix_ext <-left- i_monitor zabbix_ext <-left- i_helpdesk ' i_log_sms -> i_messente } a_helpdesk -down-> i_helpdesk a_owner -down-> i_monitor a_sysadmin -down-> i_monitor election_www --> i_log_ext zabbix_ext --> i_zabbix !endif !ifdef EXTENSION_MODULES interface "TR_API_INT()" <> as i_api_int rectangle "TR_R_MID_AUTH()" as r_mid_auth { [TR_MID_AUTH()] <> as mid_auth [TR_MID_SIGN()] <> as mid_sign interface "TR_MID()" <> as i_mid mid_auth -up- i_mid mid_sign -up- i_mid mid_auth -down-> i_mid mid_sign -down-> i_mid } rectangle "TR_R_EXTENSION()" as r_extension { [TR_TLS()] <> as tls [TR_TICKET()] <> as ticket [TR_BDOC()] <> as bdoc [TR_OCSP()] <> as ocsp [TR_TSP()] <> as tsp [TR_REG()] <> as reg interface "TR_AUTH()" <> as i_auth interface "TR_VERIFY()" <> as i_verify interface "TR_Q11N()" <> as i_q11n tls -up- i_auth ticket -up- i_auth bdoc -up- i_verify ocsp -up- i_q11n tsp -up- i_q11n reg -up- i_q11n tls -down-> i_sk_auth ocsp -down-> i_sk_ocsp tsp -down-> i_rfc_3161 reg -down-> i_sk_ocsp reg -down-> i_rfc_3161 } i_api_int -down-> i_mid i_api_int -down-> i_auth i_api_int -down-> i_verify i_api_int -down-> i_q11n !endif !ifdef SERVICES rectangle "TR_R_STORAGE()" as r_storage { [TR_STORAGE()] <> as storage database "TR_STORAGE_DB()" as storage_db { } database "TR_CONF_DB_STORAGE()" as conf_db_storage { } storage -> storage_db interface "TR_TLS_STORAGE()" <> as i_tls_storage i_tls_storage -- storage } rectangle "TR_R_CLS()" as r_cls { interface "TR_TLS_CLS()" <> as i_tls_cls [TR_CLS()] <> as cls database "TR_CONF_DB_CLS()" as conf_db_cls { } cls --> i_tls_storage cls -up- i_tls_cls } rectangle "TR_R_VERIFY()" as r_verify { interface "TR_TLS_VERIFY()" <> as i_tls_verify [TR_VERIFY()] <> as verify database "TR_CONF_DB_VERIFY()" as conf_db_verify { } verify --> i_tls_storage verify -up- i_tls_verify } rectangle "TR_R_VOTING()" as r_voting { interface "TR_TLS_VOTE()" <> as i_tls_vote [TR_VOTE()] <> as vote database "TR_CONF_DB_VOTE()" as conf_db_vote { } vote --> i_tls_storage vote -up- i_tls_vote } rectangle "TR_R_DISPATCH()" as r_dispatch { interface "TR_HTTPS_EXT()" <> as i_https_ext interface "TR_TLS_INT()" <> as i_tls_int [TR_FORWARDER()] <> as forwarder database "TR_CONF_DB_FORWARDER()" as conf_db_forwarder { } i_tls_int --> i_tls_cls i_tls_int --> i_tls_vote i_tls_int --> i_tls_verify forwarder -up- i_https_ext forwarder -down-> i_tls_int } !endif } !endif /' ' ' VÕTMERAKENDUS ' '/ !ifdef KEY_APPLICATION package "TR_P_KEY()" as p_key { [TR_KEY_APP()] <> as key_app interface "TR_KEY_IN()" <> as i_key_in interface "TR_KEY_OUT()" <> as i_key_out interface "TR_PKCS15()" <> as i_pkcs15 interface "TR_KEY_GUI()" <> as i_key_gui key_app -down-> i_pkcs15 key_app -left-> i_key_in key_app -up-> i_key_out key_app -right-> i_key_gui i_pkcs15 -- i_key_share i_key_in ..> i_mixed_votes i_key_out .up.> i_voting_result i_key_out .up.> i_decryption_proof i_key_out .up.> i_app_log i_key_out .up.> i_certificate i_key_out .up.> i_invalid_votes } a_owner -> i_key_gui !endif /' ' ' TÖÖTLEMISRAKENDUS ' '/ !ifdef PROCESSING_APPLICATION package "TR_P_PROCESSOR()" as p_processor { [TR_OFFLINE_PROCESSOR()] <> as offline_processor [TR_PDF_API()] <> as pdf_api offline_processor -> pdf_api interface "TR_PROCESSOR_IN()" <> as i_processor_in interface "TR_PROCESSOR_OUT()" <> as i_processor_out interface "TR_PROCESSOR_GUI()" <> as i_processor_gui offline_processor -down-> i_processor_in offline_processor -left- i_processor_gui offline_processor -up-> i_processor_out offline_processor -right-> i_java i_processor_in ..> i_registered_votes i_processor_in ..> i_vis_revoke i_processor_in ..> i_vis_dist i_processor_in ..> i_pop_voters i_processor_in ..> i_export_votes i_processor_out .up.> i_vis_voters i_processor_out .up.> i_ivoters_pdf i_processor_out .up.> i_encrypted_votes i_processor_out .up.> i_app_log } a_offline_processor -> i_processor_gui !endif /' ' ' AUDITIRAKENDUS ' '/ !ifdef AUDIT_APPLICATION package "TR_P_AUDIT()" as p_audit { [TR_OFFLINE_AUDIT()] <> as offline_audit [TR_DECRYPTION_VERIFIER()] <> as decryption_verifier interface "TR_MIXING_VERIFIER()" <> as i_mixing_verifier interface "TR_AUDIT_IN()" <> as i_audit_in interface "TR_AUDIT_OUT()" <> as i_audit_out interface "TR_AUDIT_GUI()" <> as i_audit_gui offline_audit --> decryption_verifier offline_audit --> i_mixing_verifier offline_audit -down-> i_audit_in offline_audit -left- i_audit_gui offline_audit -up-> i_audit_out offline_audit -right-> i_java i_audit_in ..> i_encrypted_votes i_audit_in ..> i_mixed_votes i_audit_in ..> i_decryption_proof i_audit_in ..> i_mixing_proof i_audit_in ..> i_voting_result i_audit_out ..> i_app_log } a_auditor -> i_audit_gui !endif /' ' ' SEADISTUSRAKENDUS ' '/ !ifdef CONFIG_APPLICATION package "TR_P_CONFIG()" as p_config { [TR_CONF_APP()] <> as conf_app database "TR_CONF_DB()" as conf_db { } conf_app -> conf_db interface "TR_CONF_IN()" <> as i_conf_in interface "TR_CONF_OUT()" <> as i_conf_out interface "TR_SMTP()" <> as i_smtp interface "TR_CONF_GUI()" <> as i_conf_gui conf_app -up- i_smtp conf_app -down- i_conf_in conf_app -down- i_conf_out conf_app -down- i_conf_gui i_conf_out --> i_conf_bundle i_conf_out --> i_app_log i_conf_in --> i_vis_dist i_conf_in --> i_vis_cands i_conf_in --> i_pop_voters } a_owner --> i_conf_gui !endif /' actor "TR_A_ADMIN()" <> as admin owner -left-> i_remoteadmin admin -down-> i_localadmin admin -down-> i_backup '/ !ifdef VOTER actor "TR_A_VOTER()" <> as voter interface "TR_VOTE()" <> as i_vote interface "TR_INDVERIFY()" <> as i_indverify i_https_ext -up- i_vote i_https_ext -up- i_indverify voter -down-> i_vote voter -down-> i_indverify !endif @enduml ================================================ FILE: Documentation/public/arhitektuur/model/elec-vote.pu ================================================ @startuml title "Hääletamisfaas" actor Valija as Voter participant VER participant VA participant Auth participant Sign participant CAVA participant TSA box "Collector Service" participant AuthProxy participant SignProxy participant VerProxy participant CLS participant VSS end box == Hääletamine == VA -> CLS: Valija identifikaator, id alt Võimalik autentimine CLS --> VA VA --> AuthProxy AuthProxy --> Auth Auth --> Voter AuthProxy --> VA VA --> CLS: AUTH(id) end CLS -> VA: Valikute nimekiri, C_id VA -> Voter: Valikute kuvamine, C_id Voter -> VA: Valiku tegemine, choice_id VA -> VA: r = GEN() VA -> VA: ballot_id = ENC(choice_id;r) alt Allkirjastamine lokaalselt VA --> VA: vote_id = SIGN(ballot_id, id) else Allkirjastamine läbi proksi VA --> SignProxy SignProxy --> Sign Sign --> Voter SignProxy --> VA: vote_id = SIGN(ballot_id, id) end VA -> VSS: vote_id VSS -> CAVA: id CAVA -> VSS: val_id = Valid(id) VSS -> TSA: vote_id TSA -> VSS: tok_id = Timestamp(vote_id) VSS -> VSS: vote_ref = Store(vote_id, val_id, tok_id) VSS -> VA: tok_id, vote_ref VA -> VA: VerTimestamp(tok_id) VA -> Voter: vote_ref, r == Hääle kontroll == Voter -> VER: vote_ref, r VER -> VerProxy: vote_ref VerProxy -> VSS: vote_ref VSS -> VerProxy: vote_id, tok_id, val_id VerProxy -> VER: vote_id, tok_id, val_id VER -> VER: id, choice = VerifyVote(vote_id, tok_id, val_id) VER -> Voter: id, choice @enduml ================================================ FILE: Documentation/public/arhitektuur/model/election.pu ================================================ @startuml actor Voter participant VER participant VA participant Auth participant Sign box "Collector Service" participant AuthProxy participant SignProxy participant CLS participant VSS end box participant CAVA participant TSA participant CONF participant WORKER participant MIX participant DECRYPT actor Owner actor Auditor == Setup phase == == Voting phase == VA -> CLS: Valija identifikaator, id alt Võimalik autentimine CLS --> VA VA --> AuthProxy AuthProxy --> Auth Auth --> Voter Voter --> Auth Auth --> AuthProxy AuthProxy --> VA VA --> CLS: AUTH(id) end CLS -> VA: Valikute nimekiri, C_id VA -> Voter: Valikute kuvamine, C_id Voter -> VA: Valiku tegemine, choice_id VA -> VA: r = GEN() VA -> VA: ballot_id = ENC(choice_id;r) alt Allkirjastamine lokaalselt VA --> VA: vote_id = SIGN(ballot_id, id) else Allkirjastamine läbi proksi VA --> SignProxy SignProxy --> Sign Sign --> Voter Voter --> Sign Sign --> SignProxy SignProxy --> VA: vote_id = SIGN(ballot_id, id) end VA -> VSS: vote_id VSS -> CAVA: id CAVA -> VSS: val_id = Valid(id) VSS -> TSA: vote_id TSA -> VSS: tok_id = Timestamp(vote_id) VSS -> VSS: vote_ref = Store(vote_id, val_id, tok_id) VSS -> VA: tok_id, vote_ref == Tallying phase == == Auditing phase == @enduml ================================================ FILE: Documentation/public/arhitektuur/model/en/lang.pu ================================================ ' SKIN.INC !define TR_EXTERNAL() External !define TR_UNSPECIFIED() Unspecified !define TR_NEC() NEC !define TR_IVXV() IVXV ' EXAMPLE.PU !define TR_STAKEHOLDER() Stakeholder !define TR_APPLICATION() Application !define TR_SERVICE() Service !define TR_INTERFACE() Interface !define TR_UNSPECIFIED_INTERFACE() Unspecified interface !define TR_COMPONENT() Component !define TR_IVXV_COMPONENT() IVXV Component !define TR_EXTERNAL_COMPONENT() External component !define TR_DATABASE() Database ' DEVELOPMENT.PU !define TR_MONITOR_DB() Logs !define TR_STORAGE_DB() Lists and votes !define TR_CONF_DB_CLS() Settings !define TR_CONF_DB_FORWARDER() Settings !define TR_CONF_DB_STORAGE() Settings !define TR_CONF_DB_VERIFY() Settings !define TR_CONF_DB_VOTE() Settings !define TR_CONF_DB() Settings !define TR_P_HELPERS() Helper modules !define TR_P_AUDIT() Audit application !define TR_P_COLLECTOR() Collection service !define TR_P_CONFIG() Configuration application !define TR_P_PROCESSOR() Processor !define TR_P_KEY() Key application !define TR_R_VOTING() Voting service !define TR_R_VERIFY() Verification service !define TR_R_EXTENSION() Extension modules !define TR_R_MID_AUTH() Mobiil-ID helper service !define TR_R_MONITORING() Monitoring !define TR_R_CLS() Choicelist service !define TR_R_STORAGE() Storage !define TR_R_DISPATCH() Dispatcher !define TR_ADMIN_APP() Management !define TR_BACKUP() Backup !define TR_BDOC() BDOC !define TR_CLS() Choicelist service !define TR_CONF_APP() Configuration app !define TR_DDOC_SERVICE() Mobile ID Service !define TR_DECRYPTION_VERIFIER() Decryption proof verifier !define TR_ELECTION_WWW() Election WWW !define TR_EP_ELEC() Europarliament !define TR_FORWARDER() Dispatcher !define TR_IVXV_MONITOR() Logmonitor !define TR_JDIGIDOC() DigiDoc4J !define TR_KEY_APP() Key app !define TR_KOV_ELEC() Local government !define TR_MESSENTE() Messente SMS !define TR_MID_AUTH() Authentication !define TR_MID_SIGN() Signing !define TR_OCSP() OCSP !define TR_OFFLINE_AUDIT() Audit !define TR_OFFLINE_PROCESSOR() Processor !define TR_PDF_API() PDF API !define TR_POP() Population register !define TR_REG() Registering service !define TR_RFC_3161() RFC3161 Registering service !define TR_RH_ELEC() Referendum !define TR_RK_ELEC() Riigikogu !define TR_SK_OCSP() OCSP Registering service !define TR_STORAGE() Storage !define TR_TICKET() Authentication, ticket !define TR_TLS() Authentication, TLS !define TR_TSP() Timestamp !define TR_VERIFY() Verification service !define TR_VIS() VIS !define TR_VOTE() Voting !define TR_ZABBIX_EXT() External monitoring !define TR_A_ADMIN() Local admin !define TR_A_AUDITOR() Auditor !define TR_A_HELPDESK() Helpdesk !define TR_A_KEYMANAGER() Keymanager !define TR_A_OFFLINE_PROCESSOR() Processor !define TR_A_OWNER() Election owner !define TR_A_SYSADMIN() System admin !define TR_A_VOTER() Voter !define TR_API_INT() IVXV API !define TR_APP_LOG() Application log !define TR_AUDIT_GUI() GUI !define TR_AUDIT_IN() FS Import !define TR_AUDIT_OUT() FS Export !define TR_AUTH() Authentication !define TR_BACKUP() Backup !define TR_CERTIFICATE() Certificate !define TR_CONF_BUNDLE() Configuration bundle !define TR_CONF_GUI() GUI !define TR_CONF_IN() FS Import !define TR_CONF_OUT() FS Export !define TR_DECRYPTION_PROOF() Decryption proof !define TR_ELEC() Election interface !define TR_ENCRYPTED_VOTES() Anonymized votes !define TR_EXPORT_VOTES() Votes export !define TR_HELPDESK() Helpdesk !define TR_HTTPS_EXT() HTTPS !define TR_INDVERIFY() Verification application !define TR_INVALID_VOTES() List of invalid votes !define TR_IVOTERS_PDF() List of i-voters, PDF !define TR_JAVA() DigiDoc4J !define TR_KEY_GUI() GUI !define TR_KEY_IN() FS Import !define TR_KEY_OUT() FS Export !define TR_KEY_SHARE() Key share !define TR_LOCALADMIN() Command line administration !define TR_LOG_EXT() HTTPS !define TR_LOG_INT() RELP-JSON !define TR_LOG_SMS() SMS !define TR_LOG_SMTP() SMTP !define TR_MESSENTE() Messente !define TR_MID() Mobile ID Service !define TR_MIXED_VOTES() Shuffled ballots !define TR_MIXING_PROOF() Proof of shuffle !define TR_MIXING_VERIFIER() Shuffle verifier !define TR_MONITOR() Monitoring !define TR_PKCS15() PKCS15 !define TR_POP_VOTERS() Voterlist !define TR_PROCESSOR_GUI() GUI !define TR_PROCESSOR_IN() FS Import !define TR_PROCESSOR_OUT() FS Export !define TR_Q11N() Qualification !define TR_REGISTERED_VOTES() Registered votes !define TR_REMOTEADMIN() Remote administration !define TR_RFC_3161() RFC3161 !define TR_SK_AUTH() Authentication OCSP !define TR_SK_OCSP() OCSP !define TR_SMTP() Urgent command (SMTP) !define TR_TLS_CLS() Choices !define TR_TLS_INT() TLS-SNI !define TR_TLS_STORAGE() TLS !define TR_TLS_VERIFY() Verification !define TR_TLS_VOTE() Voting !define TR_VERIFY() Verification !define TR_VIS_CANDS() List of choices !define TR_VIS_DIST() List of districts !define TR_VIS_RESULTS() Tally import !define TR_VIS_REVOKE() Revokation/restoration list !define TR_VIS_VOTERS() List of i-voters !define TR_VOTE() Voting application !define TR_VOTING_RESULT() Voting result !define TR_ZABBIX() Zabbix ' MS !define TR_MS_STATE_TITLE() Collection service states !define TR_MS_S_UNINSTALLED() Uninstalled !define TR_MS_S_INSTALLED() Installed !define TR_MS_S_SETUP() Set up !define TR_MS_S_FAILURE() Failure !define TR_MS_S_PARTIAL_FAILURE() Partial failure !define TR_MS_S_UNINSTALLED_TXT() - Management service is installed, \ \n- Collector services are uninstalled. !define TR_MS_S_INSTALLED_TXT() All collector services are installed \ \nand technical configuration applied. \ \nElection configuration has not been applied. !define TR_MS_S_SETUP_TXT() Election configuration has been applied \ \nto the Collection service \ \nit is possible to vote \ \nand export digital ballot box !define TR_MS_S_FAILURE_TXT() At least one collector service has failed. \ \nCollection service is unfunctional !define TR_MS_S_PARTIAL_FAILURE_TXT() At least one replicated collector service \ \nhas failed, Collection service is functional. !define TR_MS_TRANS_INSTALL() Installation of services !define TR_MS_TRANS_SETUP() Application of election configuration !define TR_MS_TRANS_FAIL() Failure detection !define TR_MS_TRANS_RECOVERY() Recovery detection ================================================ FILE: Documentation/public/arhitektuur/model/et/lang.pu ================================================ ' SKIN.INC !define TR_EXTERNAL() Väline !define TR_UNSPECIFIED() Määratlemata !define TR_NEC() VVK !define TR_IVXV() IVXV ' EXAMPLE.PU !define TR_STAKEHOLDER() Osapool !define TR_APPLICATION() Rakendus !define TR_SERVICE() Teenus !define TR_INTERFACE() Liides !define TR_UNSPECIFIED_INTERFACE() Määratlemata liides !define TR_COMPONENT() Komponent !define TR_IVXV_COMPONENT() IVXV komponent !define TR_EXTERNAL_COMPONENT() Väline komponent !define TR_DATABASE() Andmebaas ' DEVELOPMENT.PU !define TR_MONITOR_DB() Logid !define TR_STORAGE_DB() Nimekirjad ja hääled !define TR_CONF_DB_CLS() Seaded !define TR_CONF_DB_FORWARDER() Seaded !define TR_CONF_DB_STORAGE() Seaded !define TR_CONF_DB_VERIFY() Seaded !define TR_CONF_DB_VOTE() Seaded !define TR_CONF_DB() Seadistused !define TR_P_HELPERS() Abimoodulid !define TR_P_AUDIT() Auditirakendus !define TR_P_COLLECTOR() Kogumisteenus !define TR_P_CONFIG() Seadistusrakendus !define TR_P_PROCESSOR() Töötlemisrakendus !define TR_P_KEY() Võtmerakendus !define TR_R_VOTING() Hääletamisteenus !define TR_R_VERIFY() Kontrollteenus !define TR_R_EXTENSION() Laiendusmoodulid !define TR_R_MID_AUTH() Mobiil-ID abiteenus !define TR_R_MONITORING() Monitooring !define TR_R_CLS() Nimekirjateenus !define TR_R_STORAGE() Talletamisteenus !define TR_R_DISPATCH() Vahendusteenus !define TR_ADMIN_APP() Haldus !define TR_BACKUP() Varundamine !define TR_BDOC() BDOC !define TR_CLS() Nimekirjateenus !define TR_CONF_APP() Seadistusrakendus !define TR_DDOC_SERVICE() Mobile ID Service !define TR_DECRYPTION_VERIFIER() Lugemistõendi kontroll !define TR_ELECTION_WWW() Valimiste veebiserver !define TR_EP_ELEC() Europarlament !define TR_FORWARDER() Vahendusteenus !define TR_IVXV_MONITOR() Logianalüsaator !define TR_JDIGIDOC() DigiDoc4J !define TR_KEY_APP() Võtmerakendus !define TR_KOV_ELEC() Kohaliku omavalitsuse volikogu !define TR_MESSENTE() Messente SMS !define TR_MID_AUTH() Autentimine !define TR_MID_SIGN() Allkirjastamine !define TR_OCSP() Kehtivuskinnitus !define TR_OFFLINE_AUDIT() Audit !define TR_OFFLINE_PROCESSOR() Töötlemisrakendus !define TR_PDF_API() PDF API !define TR_POP() Rahvastikuregister !define TR_REG() Registreerimine !define TR_RFC_3161() RFC3161 Registreerimisteenus !define TR_RH_ELEC() Rahvahääletus !define TR_RK_ELEC() Riigikogu !define TR_SK_OCSP() OCSP Registreerimisteenus !define TR_STORAGE() Talletamisteenus !define TR_TICKET() Autentimine, pilet !define TR_TLS() Autentimine, TLS !define TR_TSP() Ajatempel !define TR_VERIFY() Kontrollteenus !define TR_VIS() VIS !define TR_VOTE() Hääletamisteenus !define TR_ZABBIX_EXT() Väline monitooringuserver !define TR_A_ADMIN() Admin !define TR_A_AUDITOR() Audiitor !define TR_A_HELPDESK() Klienditugi !define TR_A_KEYMANAGER() Võtmehaldur !define TR_A_OFFLINE_PROCESSOR() Töötleja !define TR_A_OWNER() Korraldaja !define TR_A_SYSADMIN() Süs.admin !define TR_A_VOTER() Valija !define TR_API_INT() IVXV API !define TR_APP_LOG() Rakenduse logi !define TR_AUDIT_GUI() GUI !define TR_AUDIT_IN() FS Import !define TR_AUDIT_OUT() FS Export !define TR_AUTH() Tuvastamine !define TR_BACKUP() Varundamine !define TR_CERTIFICATE() Sertifikaat !define TR_CONF_BUNDLE() Konfiguratsioonifail !define TR_CONF_GUI() GUI !define TR_CONF_IN() FS Import !define TR_CONF_OUT() FS Export !define TR_DECRYPTION_PROOF() Lugemistõend !define TR_ELEC() Valimise liides !define TR_ENCRYPTED_VOTES() Anonüümitud hääled !define TR_EXPORT_VOTES() Häälte eksport !define TR_HELPDESK() Helpdesk !define TR_HTTPS_EXT() HTTPS !define TR_INDVERIFY() Kontrollrakendus !define TR_INVALID_VOTES() Kehtetute häälte loend !define TR_IVOTERS_PDF() E-hääletanute nimekiri PDF !define TR_JAVA() DigiDoc4J !define TR_KEY_GUI() GUI !define TR_KEY_IN() FS Import !define TR_KEY_OUT() FS Export !define TR_KEY_SHARE() Võtmeosak !define TR_LOCALADMIN() Käsurida !define TR_LOG_EXT() HTTPS !define TR_LOG_INT() RELP-JSON !define TR_LOG_SMS() SMS !define TR_LOG_SMTP() SMTP !define TR_MESSENTE() Messente !define TR_MID() Mobiil-ID abiteenus !define TR_MIXED_VOTES() Miksitud hääled !define TR_MIXING_PROOF() Miksimistõend !define TR_MIXING_VERIFIER() Miksimistõendi kontroll !define TR_MONITOR() Monitooring !define TR_PKCS15() PKCS15 !define TR_POP_VOTERS() Valijate nimekiri !define TR_PROCESSOR_GUI() GUI !define TR_PROCESSOR_IN() FS Import !define TR_PROCESSOR_OUT() FS Export !define TR_Q11N() Täiendamine !define TR_REGISTERED_VOTES() Registreeritud hääled !define TR_REMOTEADMIN() Kaughaldus !define TR_RFC_3161() RFC3161 !define TR_SK_AUTH() Autentimise OCSP !define TR_SK_OCSP() OCSP !define TR_SMTP() Kiirkorraldus (SMTP) !define TR_TLS_CLS() Valikud !define TR_TLS_INT() TLS-SNI !define TR_TLS_STORAGE() TLS !define TR_TLS_VERIFY() Kontrollimine !define TR_TLS_VOTE() Hääletamine !define TR_VERIFY() Verifitseerimine !define TR_VIS_CANDS() Kandidaatide nimekiri !define TR_VIS_DIST() Ringkondade nimekiri !define TR_VIS_RESULTS() Tulemuste sisestamine !define TR_VIS_REVOKE() Tühistus-ennistusnimekiri !define TR_VIS_VOTERS() E-hääletanute nimekiri !define TR_VOTE() Valijarakendus !define TR_VOTING_RESULT() Hääletamistulemus !define TR_ZABBIX() Zabbix 'MS !define TR_MS_STATE_TITLE() Kogumisteenuse olek !define TR_MS_S_UNINSTALLED() Paigaldamata !define TR_MS_S_INSTALLED() Paigaldatud !define TR_MS_S_SETUP() Seadistatud !define TR_MS_S_FAILURE() Tõrge !define TR_MS_S_PARTIAL_FAILURE() Osaline tõrge !define TR_MS_S_UNINSTALLED_TXT() - Haldusteenus on paigaldatud, \ \n- Alamteenused on paigaldamata. !define TR_MS_S_INSTALLED_TXT() Kõik alamteenused on paigaldatud \ \nja tehniliselt seadistatud. \ \nValimiste seadistust pole rakendatud. !define TR_MS_S_SETUP_TXT() Kogumisteenusele on rakendatud \ \nvalimiste seadistused, teenusega \ \non võimalik hääletust läbi viia \ \nja e-valimiskasti väljastada. !define TR_MS_S_FAILURE_TXT() Üks või mitu alamteenust ei tööta, \ \nkogumisteenuse oluline sõlm \ \npole töökorras. !define TR_MS_S_PARTIAL_FAILURE_TXT() Üks või mitu dubleeritud \ \nalamteenust ei tööta, \ \nkogumisteenus töötab. !define TR_MS_TRANS_INSTALL() Teenuste \n paigaldamine !define TR_MS_TRANS_SETUP() Valimiste \n seadistuse \n rakendamine \n teenustele !define TR_MS_TRANS_FAIL() Teenuse \n tõrkeoleku \n tuvastamine !define TR_MS_TRANS_RECOVERY() Kõikide \n teenuste \n korrasoleku \n tuvastamine ================================================ FILE: Documentation/public/arhitektuur/model/example.pu ================================================ @startuml !include skin.inc actor "TR_STAKEHOLDER()" <> as a_owner package TR_APPLICATION() { interface "TR_INTERFACE()" <> as liides_1 interface "TR_UNSPECIFIED_INTERFACE()" <> as liides_3 [TR_COMPONENT()] <> as komponent_1 komponent_1 - liides_1 komponent_1 -up- liides_3 } a_owner --> liides_3 package TR_SERVICE() { interface "TR_INTERFACE()" <> as liides_2 [TR_IVXV_COMPONENT()] <> as komponent_2 [TR_EXTERNAL_COMPONENT()] <> as komponent_3 komponent_2 --> komponent_3 komponent_2 - liides_2 database "TR_DATABASE()" as andmebaas { } komponent_2 --> andmebaas } liides_1 --> liides_2 @enduml ================================================ FILE: Documentation/public/arhitektuur/model/general.pu ================================================ Osapooled Omanik Hääletaja Töötleja Audiitor Klienditugi Collector ATO VA-STO Auth Sign ================================================ FILE: Documentation/public/arhitektuur/model/ms-collector-status.pu ================================================ @startuml Title TR_MS_STATE_TITLE() skinparam state { BackgroundColor<> LightGreen BackgroundColor<> LightCoral } state "TR_MS_S_UNINSTALLED()" as s_uninstalled s_uninstalled : TR_MS_S_UNINSTALLED_TXT() state "TR_MS_S_INSTALLED()" as s_installed <> s_installed : TR_MS_S_INSTALLED_TXT() state "TR_MS_S_SETUP()" as s_setup <> s_setup : TR_MS_S_SETUP_TXT() state "TR_MS_S_FAILURE()" as s_failure <> s_failure : TR_MS_S_FAILURE_TXT() state "TR_MS_S_PARTIAL_FAILURE()" as s_partial_failure s_partial_failure : TR_MS_S_PARTIAL_FAILURE_TXT() [*] --> s_uninstalled s_uninstalled --> s_installed : TR_MS_TRANS_INSTALL() s_installed --> s_setup : TR_MS_TRANS_SETUP() s_setup --> s_partial_failure : TR_MS_TRANS_FAIL() s_setup --> [*] s_partial_failure --> s_setup : TR_MS_TRANS_RECOVERY() s_partial_failure --> s_failure s_partial_failure --> [*] s_failure --> s_partial_failure s_failure --> [*] @enduml ================================================ FILE: Documentation/public/arhitektuur/model/ms-management-service-components.en.pu ================================================ @startuml !include skin.inc Title Components of the Collection Service Management Service [User Web Browser] as User frame IVXV { [Statistics Server] interface "HTTP" as StatisticsHTTP [Statistics Server] -down- StatisticsHTTP frame "Collection Service" { node "Management Service" { [Utilities] [Web Server \n (Apache)] as WebServer interface HTTPS WebServer -u- HTTPS [User] -> HTTPS [Management Daemon] interface "HTTP" as ManagementDaemonHTTP ManagementDaemonHTTP -- [Management Daemon] [Agent Daemon] database "Data Catalog" { [Service \n data files] as DataFiles } } [Microservice] interface "SSH" as ServiceSSH [Microservice] -l- ServiceSSH } } /' External Sources '/ StatisticsHTTP -> [Agent Daemon] /' Management Service '/ [Agent Daemon] --> [Data Files] : Writing \n collected \n data [Management Daemon] --> [Data Files] : 1. Adding and \n modifying users \n 2. Saving digital \n ballot-box [Data Files] --> [Web Server] : Reading \n generated \n data [Web Server] --> [Data Files] : Loading commands [Web Server] --> ManagementDaemonHTTP : Implementing \n commands [Data Files] --> [Web Server] : Loading digital \n ballot-box /' Service Servers '/ ServiceSSH --> [Management Daemon] : Loading digital \n ballot-box \n from storage service [Utilities] --> ServiceSSH : 1. Installing service \n 2. Configuring service \n 3. Applying list [Agent Daemon] --> ServiceSSH : Service monitoring @enduml ================================================ FILE: Documentation/public/arhitektuur/model/ms-management-service-components.et.pu ================================================ @startuml !include skin.inc Title Kogumisteenuse haldusteenuse komponendid [Kasutaja veebisirvija] as Kasutaja frame IVXV { [Statistikaserver] interface "HTTP" as StatistikaHTTP [Statistikaserver] -down- StatistikaHTTP frame Kogumisteenus { node "Haldusteenus" { [Utiliidid] [Veebiserver \n (Apache)] as Veebiserver interface HTTPS Veebiserver -u- HTTPS [Kasutaja] -> HTTPS [Haldusdeemon] interface "HTTP" as HaldusdeemonHTTP HaldusdeemonHTTP -- [Haldusdeemon] [Agentdeemon] database "Andmekataloog" { [Haldusteenuse \n andmefailid] as Andmefailid } } [Mikroteenus] interface "SSH" as TeenusSSH [Mikroteenus] -l- TeenusSSH } } /' Välised allikad '/ StatistikaHTTP -> [Agentdeemon] /' Haldusteenus '/ [Agentdeemon] --> [Andmefailid] : Kogutud \n andmete \n kirjutamine [Haldusdeemon] --> [Andmefailid] : 1. Kasutaja \n lisamine ja \n muutmine \n 2. e-valimiskasti \n salvestamine [Andmefailid] --> [Veebiserver] : Genereeritud \n andmete \n lugemine [Veebiserver] --> [Andmefailid] : Korralduste \n laadimine [Veebiserver] --> HaldusdeemonHTTP : Korralduste \n rakendamine [Andmefailid] --> [Veebiserver] : E-valimiskasti \n laadimine /' Teenusserverid '/ TeenusSSH --> [Haldusdeemon] : E-valimiskasti \n laadimine \n talletusteenusest [Utiliidid] --> TeenusSSH : 1. Teenuse paigaldus \n 2. Teenuse seadistamine \n 3. Nimekirja rakendamine [Agentdeemon] --> TeenusSSH : Teenuse seire @enduml ================================================ FILE: Documentation/public/arhitektuur/model/ms-service-status-changes.en.pu ================================================ @startuml Title Collector Service Component State Change on Management Server partition Installation { :NEW; while (Can the service state be queried under the service account?) is (no) if (Can the service package state be queried under the root account of the service machine?) then (yes) :Install the service package; :Create access to the service account; else (no) :Set new state to FAULTY; stop endif endwhile (yes) while (Can access be granted to the root account of the service machine?) is (yes) :Remove access to the root account of the service machine; endwhile (no) } partition Configuration { :INSTALLED; while (Are the latest configurations applied to the service?) is (no) :Load configurations into the service machine; :Apply configurations to the service; endwhile (yes) } partition Execution { :CONFIGURED; while (Is it possible to query the service state?) is (yes) :Load the latest data into the management service; :Wait; if (Is the service disabled by the administrator?) then (yes) :Set new state to DISABLED; stop else (no) endif endwhile (no) } :FAULTY; @enduml ================================================ FILE: Documentation/public/arhitektuur/model/ms-service-status-changes.et.pu ================================================ @startuml Title Koguja teenusekomponendi olekumuutus haldusserveris partition Paigaldamine { :UUS; while (Kas teenuse konto alt õnnestub teenuse olekut küsida?) is (ei) if (Kas teenusmasina juurkonto alt \n õnnestub teenuspaki olekut küsida?) then (jah) :Paigalda teenuse pakk; :Loo ligipääs teenuse kontole; else (ei) :Määra uus olek VIGANE; stop endif endwhile (jah) while (Kas teenusmasina juurkontole õnnestub ligi pääseda?) is (jah) :eemalda ligipääs teenusmasina juurkontole; endwhile (ei) } partition Seadistamine { :PAIGALDATUD; while (Kas teenusele on rakendatud värskeimad seadistused?) is (ei) :Laadi seadistused teenusmasinasse; :Rakenda seadistused teenusele; endwhile (jah) } partition Käitamine { :SEADISTATUD; while (Kas teenuse oleku küsimine õnnestub) is (jah) :Laadi haldusteenusesse teenuse viimased andmed; :Oota; if (Kui haldur keelab teenuse?) then (jah) :Määra uus olek KEELATUD; stop else (ei) endif endwhile (ei) } :VIGANE; @enduml ================================================ FILE: Documentation/public/arhitektuur/model/ms-service-status.en.pu ================================================ @startuml Title Subservice State Diagram of the Collection Service skinparam state { BackgroundColor<> LightGreen BackgroundColor<> LightCoral } state NotInstalled state Installed state Configured <> state Error <> state Removed NotInstalled: Service described in technical settings, NotInstalled: but the service software is not installed or NotInstalled: no technical settings have been applied to the service. Installed : Service software is installed and the status of applied configurations is: Installed : - root certificates are applied; Installed : - technical settings are applied; Installed : - election settings are not applied. Configured : Service is operational Error : Service is not operational Removed : Service has been removed from the collection service Removed : composition [*] --> NotInstalled NotInstalled --> Installed : Management service installs \n service software and \n applies root and \n technical settings Installed --> Configured : Management service applies \n election settings to the service Installed --> Removed : Service is removed \n from the collection service Configured --> Error : Management service \n loses connection \n to the service Configured --> Removed : Service is removed \n from the collection service Error --> Configured : Error in the \n configured service \n is resolved Error --> Removed : Service is removed \n from the collection service Error --> [*] : Voting period \n ends Configured --> [*] : Voting period \n ends Removed --> [*] @enduml ================================================ FILE: Documentation/public/arhitektuur/model/ms-service-status.et.pu ================================================ @startuml Title Kogumisteenuse alamteenuse olekudiagramm skinparam state { BackgroundColor<> LightGreen BackgroundColor<> LightCoral } state Paigaldamata state Paigaldatud state Seadistatud <> state Tõrge <> state Eemaldatud Paigaldamata: Teenus kirjeldatud tehnilistes seadistustes, Paigaldamata: kuid teenuse tarkvara on paigaldamata või Paigaldamata: pole teenusele tehnilisi seadistusi rakendatud. Paigaldatud : Teenuse tarkvara on paigaldatud ja teenusele Paigaldatud : rakendatud seadistuste seisund on: Paigaldatud : - usaldusjuure seadistused on rakendatud; Paigaldatud : - tehnilised seadistused on rakendatud; Paigaldatud : - valimiste seadistused on rakendamata. Seadistatud : Teenus on töökorras Tõrge : Teenus pole töökorras Eemaldatud : Teenus on kogumisteenuse Eemaldatud : koosseisust eemaldatud [*] --> Paigaldamata Paigaldamata --> Paigaldatud : Haldusteenus paigaldab \n teenuse tarkvara ning \n rakendab usaldusjuure ja \n tehnilised seadistused Paigaldatud --> Seadistatud : Haldusteenus rakendab \n teenusele \n valimiste seadistused Paigaldatud --> Eemaldatud : Teenus eemaldatakse \n kogumisteenusest Seadistatud --> Tõrge : Haldusteenusel \n kaob ühendus \n teenusega Seadistatud --> Eemaldatud : Teenus eemaldatakse \n kogumisteenusest Tõrge --> Seadistatud : Seadistatud \n teenuse \n tõrge \n kõrvaldatakse Tõrge --> Eemaldatud : Teenus eemaldatakse \n kogumisteenusest Tõrge --> [*] : Hääletusperiood \n lõppeb Seadistatud --> [*] : Hääletusperiood \n lõppeb Eemaldatud --> [*] @enduml ================================================ FILE: Documentation/public/arhitektuur/model/ms-upload-command.en.pu ================================================ @startuml Title Execution of Commands in the Management Service Actor "User (Browser)" as Browser participant "Web Server \n (Apache)" as WSGI participant "Daemon \n (HTTP)" as Daemon_HTTP participant "Management \n Library" as Util Database "File System" as FS participant Service Browser -> WSGI : Uploading \n command Activate Browser Activate WSGI WSGI -> FS : Saving command alt Command is valid WSGI -> Daemon_HTTP : Request to \n apply command Activate Daemon_HTTP Daemon_HTTP -> Util : Request to apply \n command Activate Util Util <- FS : Reading command Util -> Util : Validating command alt Immediate application Util -> Service : Applying command else Issuing digital ballot-box Service -> Util : Loading digital ballot-box end Util -> Daemon_HTTP : Response to apply \n command Deactivate Util Daemon_HTTP -> WSGI : Sending response Deactivate Daemon_HTTP end WSGI -> Browser : Sending response Deactivate WSGI Deactivate Browser @enduml ================================================ FILE: Documentation/public/arhitektuur/model/ms-upload-command.et.pu ================================================ @startuml Title Korralduste täitmine haldusteenuses Actor "Kasutaja (Brauser)" as Brauser participant "Veebiserver \n (Apache)" as WSGI participant "Deemon \n (HTTP)" as Deemon_HTTP participant "Halduse \n teek" as Util Database "Failisüsteem" as FS participant Teenus Brauser -> WSGI : Korralduse \n üleslaadimine Activate Brauser Activate WSGI WSGI -> FS : Korralduse salvestamine alt Korraldus on valiidne WSGI -> Deemon_HTTP : Korralduse \n rakendamise \n päring Activate Deemon_HTTP Deemon_HTTP -> Util : Korralduse \n rakendamise päring Activate Util Util <- FS : Korralduse lugemine Util -> Util : Korralduse valideerimine alt Vahetu rakendamine Util -> Teenus : Korralduse rakendamine else E-valimiskasti väljastamine Teenus -> Util : E-valimiskasti laadimine end Util -> Deemon_HTTP : Korralduse \n rakendamise vastus Deactivate Util Deemon_HTTP -> WSGI : Vastuse \n edastamine Deactivate Deemon_HTTP end WSGI -> Brauser : Vastuse \n edastamine Deactivate WSGI Deactivate Brauser @enduml ================================================ FILE: Documentation/public/arhitektuur/model/ms-voter-list-status.en.pu ================================================ @startuml title Voter List State Diagram skinparam state { BackgroundColor<> LightGray BackgroundColor<> LightGreen BackgroundColor<> LightCoral } state "Available" as AVAILABLE <> state "Pending Application" as PENDING state "Applied" as APPLIED <> state "Invalid" as INVALID <> state "Skipped" as SKIPPED <> note right of AVAILABLE External system state not registered in the management service database end note [*] --> AVAILABLE : Detection of list availability AVAILABLE : List is available in the Voting Information System AVAILABLE --> PENDING : Loading of correct list \n into the management service PENDING : List is Loaded into the management service AVAILABLE --> INVALID : Loading of \n invalid list \n into the management service PENDING --> INVALID : Failed application of \n the change list \n to the list service INVALID : List is marked as invalid PENDING --> APPLIED : Application of the list \n to the list service APPLIED : List is applied to the collection service INVALID --> SKIPPED : Marking the list as skipped SKIPPED : List is marked as skipped SKIPPED --> [*] APPLIED --> [*] @enduml ================================================ FILE: Documentation/public/arhitektuur/model/ms-voter-list-status.et.pu ================================================ @startuml title Valijate nimekirja olekudiagramm skinparam state { BackgroundColor<> LightGray BackgroundColor<> LightGreen BackgroundColor<> LightCoral } state "Saadaval" as AVAILABLE <> state "Rakendamise ootel" as PENDING state "Rakendatud" as APPLIED <> state "Vigane" as INVALID <> state "Vahele jäetud" as SKIPPED <> note right of AVAILABLE Süsteemiväline seisund, mida haldusteenuse andmebaasis ei registreerita end note [*] --> AVAILABLE : Nimekirja saadavaloleku tuvastamine AVAILABLE : Nimekiri on saadaval Valimiste Infosüsteemis AVAILABLE --> PENDING : Korrektse nimekirja \n laadimine \n haldusteenusesse PENDING : Nimekiri on Laaditud haldusteenusesse AVAILABLE --> INVALID : Vigase \n muudatusnimekirja \n laadimine \n haldusteenusesse PENDING --> INVALID : Muudatusnimekirja \n nurjunud rakendamine \n nimekirjateenusele INVALID : Nimekiri on märgitud vigaseks PENDING --> APPLIED : Nimekirja \n rakendamine \n nimekirjateenusele APPLIED : Nimekiri on rakendatud kogumisteenusele INVALID --> SKIPPED : Nimekirja \n märkimine \n vahelejätmiseks SKIPPED : Nimekirja on märgitud vahelejätmiseks SKIPPED --> [*] APPLIED --> [*] @enduml ================================================ FILE: Documentation/public/arhitektuur/model/skin.inc ================================================ skinparam interface { backgroundColor<> Gold backgroundColor<> LightSalmon backgroundColor<> DarkGoldenRod backgroundColor<> Black } skinparam actor { backgroundColor<> Gold backgroundColor<> LightSalmon backgroundColor<> DarkGoldenRod backgroundColor<> Black } skinparam component { backgroundColor<> Gold backgroundColor<> DarkGoldenRod backgroundColor<> LightSalmon backgroundColor<> Black } ================================================ FILE: Documentation/public/arhitektuur/model/uc-audit.pu ================================================ @startuml title "Auditirakendus - offline" usecase (Kogumisteenuse auditimaterjali import) usecase (Lugemisteenuse auditimaterjali import) usecase (Miksimisteenuse auditimaterjali import) usecase (Ajatembeldusteenuse auditimaterjali import) usecase (Auditi läbiviimine) @enduml ================================================ FILE: Documentation/public/arhitektuur/model/uc-offline.pu ================================================ @startuml title "Lugemisfaas - offline" package "Töötleja" { usecase (Allkirjastatud häälte import) usecase (Ajamärgendite import) usecase (Kontrollimine - ver, ATO) usecase (Korduvate häälte tühistamine) usecase (E-hääletanute nimekiri jaoskondade kaupa) usecase (Tühistusavalduste import) usecase (Tühistamise ennistusavalduste import) usecase (Anonümiseerimine) usecase (Anonüümsete häälte eksport) usecase (Lugemisele läinud E-hääletanute nimekiri jaoskondade kaupa) } package "Miksimine" { usecase (Auditeeritud random) usecase (Anonüümsete häälte import) usecase (Häälte miksimine) usecase (Miksitud häälte eksport) usecase (Miksimistõestuse eksport) } package "Lugemine" { usecase (Krüpteeritud häälte import) usecase (E-häälte kokkulugemine) usecase (E-hääletamise tulemuste eksport) usecase (Dekrüptimistõestuse eksport) } package "Võtmehaldus" { usecase (Privaatvõtme aktiveerimine) } package "Audit" { usecase (Kogumisteenuse auditimaterjali import) usecase (Lugemisteenuse auditimaterjali import) usecase (Ajatembeldusteenuse auditimaterjali import) usecase (Auditi läbiviimine) } package "Valimise lõpetamine" { usecase (Arhiveerimine) usecase (Privaatvõtme ja koopiate hävitamine) } @enduml ================================================ FILE: Documentation/public/arhitektuur/model/uc-online.pu ================================================ @startuml title "Hääletamisfaas hostingus" usecase (*) as UC0 note left of UC0 * Ainult talletamiskomponent ja ajatembeldus säilitavad olekut * Muud komponendid on stateless - loadbalancing on võimalik * Talletamiskomponendi veakindlus - HadoopFSi või byzantine? * On-line komponentide väliste liideste definitsioon ja valideerimine * Nõue TLSi kasutamiseks ja 443 pordiga piirdumiskes * HTTP ei ole hädavajalik kuid võib aidata endnote package "Support" { usecase (Varundamine hääletamisperioodi peatamata) usecase (Taastamine puhtale süsteemile) usecase (Logimine monitooringusüsteemi) usecase (Süsteemi seisundi kaugvaatlus) usecase (Süsteemi seisundi vaatlus käsurealt) as UC1.5 note left of UC1.5 * pseudograafika asemel git laadne käsustik * võimalusel süsteemsete lahenduste kasutamine iseleiutamise asemel endnote } package "Hääletamisperioodi eelne" { usecase (Proovihääletamine ühenduste testimiseks) usecase (Hääletamisperioodi kaugkäivitamine) } package "Hääletamisperiood" { usecase (Valijate nimekirja perioodiline uuendamine) usecase (Häälte talletamine) as UC2.2 usecase (Kontrollpäringutele vastamine) usecase (Vaheaudit) usecase (Serverite ühtsuse kontroll) usecase (Hääletamisperioodi järkjärguline kaugpeatamine) note left of UC2.2 * isikute autentimine * valimisõigus(t)e tuvastamine * valikute väljastamine * häälte vastu võtmine ja talletamine * kontrollidentifikaatorite väljastamine endnote } ' osa vähemalt häältest eesti pinnal vähemalt 1 kord päevas, võib ka logiandmed ' eesti pinnal olev backup peab olema loetav package "Hääletamisperioodi järgne" { usecase (E-hääletanute nimekirja koostamine valimisjaoskondade kaupa) usecase (Häälte eksport kogumisteenusest) usecase (Auditimaterjali eksport kogumisteenusest) ' usecase (Auditimaterjali eksport ajatempliteenusest) usecase (Logi eksport kogumisteenusest) } package "Valija tegevused" { usecase (Valijarakenduse paigaldamine autentsest allikast) usecase (Kontrollrakenduse paigaldamine autentsest allikast) usecase (E-hääletamine) usecase (E-hääle kontrollimine) } @enduml ================================================ FILE: Documentation/public/arhitektuur/model/uc-prep.pu ================================================ @startuml title "Ettevalmistusfaas kontoris" usecase (*) as UC0 note left of UC0 Mujal menetlemata nüansid * Võimekus mitme samaaegse eritüübilise valimise korraldamiseks * Võimekus null-autentimismeetodite ja nimekirjade kasutamiseks * Andmevormingute spetsifikatsioon * Väliste liideste ja sõltuvuste spetsifikatsioon end note actor Omanik actor Hääletaja actor Koguja actor Töötleja actor Audiitor actor IDP actor ATO actor STO actor Klienditugi package "Konfiguratsiooni haldamine" { usecase (Tekstide haldus) as UC1.5 usecase (Valimisinfo laadimine) as UC1.1 usecase (Tehniliste parameetrite haldus) as UC1.4 usecase (Autentimisteenuse seadistamine) as UC1.6 usecase (Kehtivuskinnitusteenuse seadistamine) as UC1.7 usecase (Ajatempliteenuse seadistamine) as UC1.8 usecase (Konfiguratsiooni valideerimine) as UC1.9 usecase (Konfiguratsiooni allkirjastamine) as UC1.10 usecase (Konfiguratsiooni eksport) as UC1.11 usecase (Allkirja moodustamine, ajatempli saamine, kehtivuses veendumine meetodite määramine) usecase (Algoritmi ja votme määramine) note bottom of UC1.11 Komponentide põhiste allkirjastatud konfipakkide loomine endnote note bottom of UC1.1 * Valimine * Reeglid * Valijad * Valikud * Jaoskonnad endnote } Omanik -> UC1.10 Koguja -> UC1.5 note left of UC1.9 * Olemasolu kontroll * Vormingu kontroll * Kooskõlalisuse kontroll endnote note top of UC1.5 * Kontrollrakendus * Valijarakendus endnote package "Võtmehaldus" { usecase (Võtmepaari ja PIN-ide genereerimine) as UC2.1 usecase (Võtmepaari varukoopia loomine) as UC2.2 usecase (Avaliku komponendi transport valijarakendusele) as UC2.3 usecase (Valijarakenduse ettevalmistamine) as UC2.4 ' osad pinniga osad mitte note left of UC2.1 * MofN * kiipkaart vs. HSM endnote } package "Keskkonna ettevalmistamine" { usecase (Paigalduspakkide haldamine) as UC3.1 usecase (Süsteemi paigaldamine) as UC3.2 usecase (Usaldusnimekiri) as UC3.3 usecase (Volitatud isikute sertifikaatide haldus) usecase (Konfiguratsiooni laadmine) as UC3.4 } package "Laua peal testimine" { usecase (Võtmepaari kontroll, testhääletamine) as UC4.1 } @enduml ================================================ FILE: Documentation/public/arhitektuur/model/uc-tootleja.pu ================================================ @startuml title "Töötleja" usecase (Töötleja usaldusjuurte laadimine) usecase (Töötleja seadistuse import) usecase (Allkirjastatud häälte import) usecase (Ajamärgendite import) usecase (Kontrollimine - ver, ATO) usecase (Korduvate häälte tühistamine) usecase (E-hääletanute nimekiri jaoskondade kaupa) usecase (Tühistusavalduste import) usecase (Tühistamise ennistusavalduste import) usecase (Anonümiseerimine) usecase (Anonüümsete häälte eksport) usecase (Lugemisele läinud E-hääletanute nimekiri jaoskondade kaupa) usecase (Tegevuslogi) usecase (Tulemuslogi) usecase (Hääle olekulogi) usecase (Korrektse korduvhääle tühistamise tõestamine) usecase (Korrektse hääle tühistamise tõestamine p-hääle tõttu) usecase (Miksimissisendi autentsuse tõestamine) @enduml ================================================ FILE: Documentation/public/arhitektuur/model/uc-votmerakendus.pu ================================================ @startuml title "Võtmerakendus" usecase (Verifitseerimiskonfiguratsiooni import) usecase (Kandidaatide ja ringkondade nimekirja import) usecase (Krüpteeritud häälte import) usecase (E-häälte dekrüpteerimine) usecase (E-häälte kokkulugemine) usecase (Sisendinfo verifitseerimine) usecase (Väljundinfo signeerimine) usecase (E-hääletamise tulemuste eksport) usecase (Kehtetute sedelite loendi eksport) usecase (Dekrüptimistõestuse eksport) usecase (Tegevuslogi eksport) usecase (Hääle olekulogi) usecase (Võtmepaari genereerimine) usecase (Juhuslikkuse lisamine) usecase (Juhuslikkuse mõõtmine) usecase (Sertifikaadi allkirjastamine) usecase (Privaatvõtme aktiveerimine) usecase (Privaatvõtme ja koopiate hävitamine) @enduml ' Rakenduse konfigureerimine ' Võtme genereerimine ' Sertifikaadi väljastamine ' Hääletamistulemuse väljastamine ================================================ FILE: Documentation/public/arhitektuur/spelling_wordlist.txt ================================================ Advances Annual Cryptosystems Improving October pp th Threshold PDF'ide Bouncy Castle IP XML'il TLS'i SSH SNI TCP apache BDoc clause crontab deb debian digidoc docker'i etcd go jammy jellyfish jinja libdigidocpp logback python rsyslog ubuntu urlencode Guardtime Gradle Jackson admincode cc choices count counties district districts id EHAK Nimeste ocsp previous seq stats time tspreg type version vote voted voter votername voters votes Sven Heiberg Tarvi Martens Priit Vinkel Jan Willemson Oliver Spycher Vanessa Teague Gregor Wenda Melanie Volkamer Jordi Barrat Josh Benaloh Nicole Goodman Peter Ryan International Conference Electronic Voting Cryptology Santa Barbara California USA Desmedt Frankel Brassard ed eds the of in or pdf verifiability Estonian Internet Voting scheme Robert Krimmer Austria Bregenz Lochau Proceedings Springer Schnorri Shamir Shamiri assert collections commons dateutil glassfish hamcrest JUnit later mockimise Mockito pyopenssl pythoni pythonile requests tools x parametriseerimise haldusutiliitide vallasrežiimis ================================================ FILE: Documentation/public/arhitektuur/tehnoloogiad.rst ================================================ .. IVXV arhitektuur .. _tehnoloogiad: Kasutatavad tehnoloogiad ======================== Kogumisteenuse programmeerimiskeel ---------------------------------- Kogumisteenuse tuumikfunktsionaalsus on programmeeritud keeles Go, mis vastab järgmistele hanke nõuetele: * Staatiline tüüpimine; * Automaatne mäluhaldus; * Kompilaator avatud lähtekoodiga; * Ribastamine (rööprapse). Kogumisteenuse haldusteenus on programmeeritud keeles Python. Rakenduste programmeerimiskeel ------------------------------ Rakendused on programmeeritud keeles Java, mis vastab hanke nõuetele keele laia leviku ja jätkusuutlikkuse kohta. Projekti sõltuvused ------------------- Projektis kasutatavad kolmandate osapoolte komponendid koos nende motiveeritud kasutamisvajadusega on üles loetletud järgnevates tabelites. Eraldi tabelid on raamistiku pakendamiseks ja töötamiseks ning raamistiku arenduseks ja testimiseks. Kõik IVXV projektis kasutatavad välised teegid asuvad ``ivxv-external.git`` hoidlas või on saadaval platvormil, kus rakendus tööle hakkab. Kõik kogumisteenuses kasutatavad komponendid on avatud lähtekoodiga. .. tabularcolumns:: |p{0.2\linewidth}|p{0.1\linewidth}|p{0.15\linewidth}|p{0.55\linewidth}| .. list-table:: IVXV raamistiku tööks kasutatavad kolmandate osapoolte komponendid :header-rows: 1 * - Nimi - Versioon - Litsents (SPDX) - Kasutusvajadus * - `Bootstrap `_ - 3.4.1, JavaScript - MIT - Kogumisteenuse haldusteenuse kasutajaliidese kujundus * - Bouncy Castle - 1.78.1, Java - MIT - ASN1 käsitlemine, andmetüübi BigInteger abifunktsioonid * - `Bottle `_ - 0.13.2, Python - MIT - Raamistik kogumisteenuse haldusteenuse veebiliidese teostamiseks * - CAL10N - 0.8.1, Java - MIT - Mitmekeelsuse tugi, tõlkefailide valideerimine * - Digidoc 4j - 5.3.1, Java - LGPL-2.1-only - BDoc konteinerite käsitlemine * - Apache Commons (collections4 4.4) - Java - Apache-2.0 - Digidoc 4j ja PDFBox sõltuvused * - `Docopt `_ - 0.6.2, Python - MIT - Kogumisteenuse haldusutiliitide käsurealiidese teostus * - `Fasteners `_ - 0.19, Python - Apache-2.0 - Kogumisteenuse haldusteenuse protsesside lukustus * - `gin-gonic `_ - 1.9.1, Go - MIT - Veebiraamistik x-tee liidese jaoks * - `etcd `_ - 3.5.9, Go - Apache-2.0 - Talletusteenusena kasutatav hajus võti-väärtus andmebaas * - Glassfish JAXB - 4.0.5, Java - BSD-3-Clause - Java XML teek * - Gradle - 8.11, Java - Apache-2.0 - Java rakenduste ehitamise raamistik * - `HAProxy `_ - 2.4.24 - GPL-2.0-or-later - Vahendusteenusena kasutatav TCP-proksi * - Jackson - 2.18.1, Java - Apache-2.0 - JSON vormingus failide lugemine ja kirjutamine * - Jinja2 - 3.1.4, Python - BSD - Jinja mallide kasutamine haldusteenuses * - `jQuery `_ - 3.7.1, JavaScript - MIT - Kogumisteenuse haldusteenuse kasutajaliides * - jsonschema - 4.23.0, Python - MIT - JSON valideerimine haldusteenuses * - Logback - 1.5.12, Java - EPL-1.0 or LGPL-v2.1-only - Logimise API teostus * - Logback JSON - 0.1.5, Java - EPL-1.0 or LGPL-v2.1-only - Logback logija laiendus JSON vormingus logikirjete koostamiseks Jackson teegi abil * - `Logrus `_ - 1.9.3, Go - MIT - Logimisraamistik x-tee liidese jaoks * - `metisMenu `_ - 1.1.3, JavaScript - MIT - Kogumisteenuse haldusteenuse kasutajaliides * - `FontAwesome `_ - 6.7.2, JavaScript - MIT - Kogumisteenuse haldusteenuse kasutajaliides * - `DataTables `_ - 2.3.2, JavaScript - MIT - Kogumisteenuse haldusteenuse kasutajaliides * - PDFBox - 3.0.3, Java - Apache-2.0 - PDF vormingus raportite genereerimise tugi Java rakendustele * - `PyYAML `_ - 6.0.2, Python - MIT - Kogumisteenuse seadistusfailide töötlemise tugi haldusteenusele * - python-crontab - 3.3.0, Python - LGPLv3 - Crontab haldusteenuses * - python-dateutil - 2.9.0, Python - BSD - Kuupäevad ja kellaajad haldusteenuses * - python-debian - 0.1.49, Python - GPLv2 - Debian pakkide lugemine haldusteenuses * - pyopenssl - 24.2.1, Python - Apache - OpenSSL kasutus haldusteenuses * - `Schematics `_ - 2.1.1, Python - BSD-3-Clause - Kogumisteenuse seadistusfailide valideerimise tugi haldusteenusele * - SnakeYAML - 2.3, Java - Apache-2.0 - YAML vormingus andmete lugemine * - `SB Admin 2 `_ - 3.3.7+1, JavaScript - MIT - Kogumisteenuse haldusteenuse kasutajaliidese kujundus .. tabularcolumns:: |p{0.2\linewidth}|p{0.1\linewidth}|p{0.15\linewidth}|p{0.55\linewidth}| .. list-table:: IVXV raamistiku testide kasutatavad kolmandate osapoolte komponendid :header-rows: 1 * - Nimi - Versioon - Litsents (SPDX) - Kasutusvajadus * - Hamcrest - 3.0, Java - BSD-3-Clause - Loetavam assert-meetodite kasutamine Java üksuste testides * - JUnit - 5.10.0, Java - EPL-1.0 - Java testimisraamistik * - JUnitParams - 1.1.1, Java - Apache-2.0 - Testide parametriseerimise tugi * - Mockito - 5.14.2, Java - MIT - Testitava koodi sõltuvuste mockimise tugi * - libdigidocpp-tools - 3.14.5 .1404 - LGPL-2.1-or-later - Testandmete genereerimine * - PyTest - 7.4.2, Python - MIT - Üksuste testimise tugi Pythonile * - Requests - 2.32.3, Python - Apache 2.0 - HTTP päringute moodul Pythoni testidele .. tabularcolumns:: |p{0.2\linewidth}|p{0.1\linewidth}|p{0.15\linewidth}|p{0.55\linewidth}| .. list-table:: IVXV raamistiku arendamiseks ja/või testimiseks kasutatavad kolmandate osapoolte tööriistad :header-rows: 1 * - Nimi - Versioon - Litsents (SPDX) - Kasutusvajadus * - `Behave `_ - 1.2.6, Python - BSD-2-Clause - Regressioonitestide käivitaja (*Behavior-driven development*) * - `Docker `_ - 18.06 (või uuem) - Apache-2.0 - Regressioonitestide läbiviimise keskkond - tarkvarakonteinerid * - `Sphinx `_ - 7.2.5, Python - BSD - Dokumentatsiooni genereerimine ================================================ FILE: Documentation/public/arhitektuur/vallasrezhiim.rst ================================================ .. IVXV arhitektuur Rakendused ========== Üldpõhimõtted ------------- Kõik rakendused on käsurealiidesega rakendused, mis on pakendatud töötama operatsioonisüsteemi Windows 10 (või uuem) keskkonnas. Komponentide kasutajaliidesed on ühekeelsed. Komponendid tarnitakse eestikeelsetena, nende tõlkimine on võimalik tõlkefaili abil. Rakendused on programmeeritud Java keeles. Väliste infosüsteemidega suhtlevad rakendused kasutavad maksimaalselt olemasolevaid liideseid/andmestruktuure. Rakendused saavad oma sisendi rakenduste seadistustest ja seadistustes näidatud failidest failisüsteemis ning salvestavad oma väljundi kasutaja näidatud kausta failisüsteemis. Failid võivad paikneda ka operatiiv-mälukettal. Relevantsed rakendused toetavad ElGamal krüptosüsteemi täisarvujäägikorpustel ning P-384 elliptkõveral. Lugemistõend on realiseeritud Schnorri nullteadmustõestusel põhineval protokollil. .. figure:: model/img/app_modules.png Rakenduste abimoodulid Valimise liides on rakenduste jaoks unifitseeritud, see võimaldab erinevate valimistüüpide realiseerimist moodulitena. Digiallkirja verifitseerimise funktsionaalsus on loodud `digidoc4j `_ teegi abil. Abimoodulite kasutamist alljärgnevatel skeemidel eraldi välja ei tooda. Rakenduste seadistamine ``````````````````````` Rakendused seadistatakse kas digitaalallkirjastatud konfiguratsioonipakiga või käsureavõtmetega. Käsureavõtmed ei toeta hierarhilise struktuuriga seadistuste sisestamist. Seadistused konfiguratsioonipakis kirjeldatakse YAML-keeles: .. code-block:: yaml check: ballotbox: votes.zip ballotbox_checksum: votes.zip.sha256sum.bdoc districts: TESTKOV2017.districts.json registrationlist: register.zip registrationlist_checksum: register.zip.sha256sum.bdoc tskey: ts.pub.key vlkey: test.gen.pub.key voterlists: - path: 00.TESTKOV2017.gen.voters signature: 00.TESTKOV2017.gen.voters.signature - path: 03.TESTKOV2017.gen.voters signature: 03.TESTKOV2017.gen.voters.signature - path: 06.TESTKOV2017.gen.voters signature: 06.TESTKOV2017.gen.voters.signature - path: 09.TESTKOV2017.gen.voters signature: 09.TESTKOV2017.gen.voters.signature election_start: 2017-05-01T12:00:00+03:00 out: out-1 squash: ballotbox: out-1/bb-1.json ballotbox_checksum: out-1/bb-1.json.sha256sum.bdoc districts: TESTKOV2017.districts.json out: out-2 revoke: ballotbox: out-2/bb-2.json ballotbox_checksum: out-2/bb-2.json.sha256sum.bdoc districts: TESTKOV2017.districts.json revocationlists: - 12.TESTKOV2017.gen.revoke.json - 13.TESTKOV2017.gen.revoke.json - 14.TESTKOV2017.gen.revoke.json - 15.TESTKOV2017.gen.revoke.json out: out-3 Sisendite kooskõlalisuse kontroll ````````````````````````````````` Kõik rakendused teostavad konfiguratsioonile sisendite kooskõlalisuse kontrolli vastavalt nende poolt kasutatavale konfiguratsioonile: #. sertifikaatide konfiguratsiooni laadimine; #. konfiguratsiooni digiallkirja verifitseerimine; #. ringkondade nimekirja verifitseerimine; #. ringkondade nimekirja kooskõlalisuse kontroll; #. ringkondade nimekirja laadimine; #. valikute nimekirja verifitseerimine; #. valikute nimekirja kooskõlalisuse kontroll; #. valikute nimekirja laadimine; #. valijate nimekirjade verifitseerimine; #. valijate nimekirjade kooskõlalisus kontroll; #. valijate nimekirjade laadimine. Võtmerakendus ------------- .. figure:: model/img/key.png Võtmerakenduse liidesed Võtmerakendusega genereeritakse iga hääletamise jaoks häälte salastamise ja häälte avamise võti, samuti toimub selle abil häälte lugemine ja tulemuse väljastamine. Võtmerakendus kasutab [DesmedtF89]_ läviskeemi, mis põhineb usaldataval osakujagajal ning rakendab Shamiri osakujagamist, mis on informatsiooniteoreetiliselt turvaline :math:`t < M` osapoole korral, kus M on lävipiir. Võtmeosakud genereeritakse operatiivmälus ning talletatakse PKCS15-liidese vahendusel kiipkaardile. Võtmerakenduse sisend võtme genereerimisel on: - Võtmepaari identifikaator; - Krüptosüsteemi ElGamal spetsifikatsioon – täisarvujäägikorpus või P-384 elliptkõver ning võtmepikkus; - M-N läviskeemi spetsifikatsioon, mis peab vastama reeglile :math:`N >= 2 * M - 1`; - N PKCS15-ühilduvat kiipkaarti; Võtmerakenduse väljund võtme genereerimisel on: - Isesigneeritud sertifikaat; - N võtmeosakut talletatuna kiipkaartidel; - Rakenduse detailne tegevuslogi; - Rakenduse detailne vealogi. Võtmerakenduse sisend häälte lugemisel on: - Miksitud hääled; - Võtmepaari identifikaator; - M võtmeosakut vastavalt läviskeemi spetsifikatsioonile. Võtmerakenduse väljund häälte lugemisel on: - Signeeritud hääletamistulemus; - Kehtetute häälte loend; - Lugemistõend (Schnorri nullteadmustõestusel põhinev protokoll vastavalt hankedokumentides viidatule); - Rakenduse detailne tegevuslogi; - Rakenduse detailne vealogi. Töötlemisrakendus ----------------- Töötlemisrakendusega verifitseeritakse, tühistatakse ning anonüümitakse hääletamisperioodil kogutud hääli vastavalt Üldkirjelduse jaotisele 7.6. Töötlemisrakenduse sisendid on: - kogumisteenuse poolt talletatud elektroonilised hääled; - registreerimisteenuse poolt väljastatud ajamärgendid; - valijate nimekirjad; - ringkondade nimekiri; - tühistusnimekirjad; - ennistusnimekirjad. Töötlemisrakenduse väljundid on: - rakenduse detailne tegevuslogi; - rakenduse detailne vealogi; - e-hääletanute nimekiri PDF-vormingus, vastavalt töötlemise etapile; - e-hääletanute nimekiri masintöödeldaval kujul, vastavalt töötlemise etapile; - anonüümitud hääled. Lisaks varem defineeritud liidestele ja sõltuvustele kasutab töötlemisrakendus kolmanda osapoole teeki PDF'ide väljastamise funktsionaalsuse teostamiseks. .. figure:: model/img/processing.png Töötlemisrakenduse liidesed Elektrooniliste häälte täielik töötlemine ````````````````````````````````````````` Elektrooniliste häälte täielik töötlemine on tegevus, mille käigus töötlemisrakendus võrdleb Kogumisteenuse poolt talletatud häälte hulka registreerimisteenuse poolt talletatud häälte hulgaga, kontrollib talletatud häälte vastavust valimiste konfiguratsioonile, tuvastab loendamisele minevad hääled ning anonüümib need Võtmerakendusele üle andmiseks. #. rakenduse seadistuste laadimine; #. elektrooniliste häälte digitaalallkirjade verifitseerimine; #. registreerimisteenuse kinnituste verifitseerimine; #. ajatemplite verifitseerimine; #. iga valija kohta viimase kehtiva hääle tuvastamine; #. algse elektrooniliselt hääletanute nimekirja väljastamine PDF-vormingus; #. tühistus- ja ennistusnimekirjade verifitseerimine; #. tühistus- ja ennistusnimekirjade kooskõlalisuse kontroll; #. tühistus- ja ennistusnimekirjade rakendamine; #. miksimisele minevate häälte nimekirja koostamine, krüptogrammide eraldamine digitaalallkirjadest; #. lõpliku elektrooniliselt hääletanute nimekirja väljastamine masinloetavas vormingus. Elektrooniliselt hääletanute nimekirja genereerimine ```````````````````````````````````````````````````` #. rakenduse seadistuste laadimine; #. elektrooniliste häälte digitaalallkirjade verifitseerimine; #. algse elektrooniliselt hääletanute nimekirja väljastamine PDF-vormingus. Auditirakendus -------------- .. figure:: model/img/audit.png Auditirakenduse liidesed Auditirakendusega (joonis 9) verifitseeritakse matemaatiliselt häälte kokkulugemise korrektsust ning miksimise kasutamisel ka miksimise korrektsust. Auditirakenduse sisendid on; - anonüümitud hääled; - miksitud hääled; - Verificatumi miksimistõend; - hääletamistulemus. Auditirakenduse väljund on rakenduse detailne tegevuslogi, mis sisaldab ka hinnangut auditi tervikliku õnnestumise kohta. Vajadusel väljastatakse ka rakenduse detailne vealogi. ================================================ FILE: Documentation/public/arhitektuur/viited.rst ================================================ .. IVXV arhitektuur .. [DesmedtF89] Desmedt, Y. & Frankel, Y. Brassard, G. (Ed.) Threshold Cryptosystems Advances in Cryptology - CRYPTO '89, 9th Annual International Cryptology Conference, Santa Barbara, California, USA, August 20-24, 1989, Proceedings, Springer, 1989, 435, 307-315. .. [HMVW16] Sven Heiberg, Tarvi Martens, Priit Vinkel, Jan Willemson, Improving the verifiability of the Estonian Internet Voting scheme. In Robert Krimmer, Melanie Volkamer, Jordi Barrat, Josh Benaloh, Nicole Goodman, Peter Y.A. Ryan, Oliver Spycher, Vanessa Teague, Gregor Wenda (Eds.), The International Conference on Electronic Voting E-Vote-ID 2016, 18-21 October 2016, Lochau/Bregenz, Austria, TUT Press, pp. 213-229, ISBN 978-9949-83-022-0 .. [TK2016] Tehniline kirjeldus. Elektroonilise hääletamise infosüsteemi arenduse hange, Vabariigi Valimiskomisjon, 2016 .. [ÜK2016] Elektroonilise hääletamise üldraamistik ja selle kasutamine Eesti riiklikel valimistel. Elektroonilise Hääletamise Komisjon, Tallinn 2016 ================================================ FILE: Documentation/public/arhitektuur/yldpohimotted.rst ================================================ .. IVXV arhitektuur Sissejuhatus ============ Elektroonilise hääletamise infosüsteem IVXV on loodud lähtuvalt e-hääletamise raamistikust [ÜK2016]_ ja riigihanke 171780 tehnilisest kirjeldusest [TK2016]_. Käesolevas dokumendis kirjeldatakse IVXV arhitektuurset lahendust. Elektroonilise hääletamise infosüsteem koosneb vallasrežiimirakendustest ning sidusrežiimikomponentidest. Täiendavalt sõltub infosüsteem välistest infosüsteemidest ning mõjutab vahetult elektrooniliseks hääletamiseks ja hääle kontrollimiseks kasutatavaid komponente. Arhitektuuridokument kirjeldab IVXV komponente, nende omavahelisi liideseid ja liideseid väliste süsteemidega ning komponentide poolt realiseeritavaid protokolle. IVXV kontseptsioon ------------------ Üldine, kuid terviklik ülevaade elektroonilise hääletamise raamistiku ("IVXV") tehnilisest ja organisatsioonilisest poolest ning selle rakendamisest Eesti riiklikel valimistel on antud e-hääletamise raamistiku üldkirjelduses [ÜK2016]_. IVXV infosüsteemina teostab "ümbrikuskeemil" põhinevat e-hääletamise protokolli. IVXV toimib hääletamiseelsel etapil, hääletamisetapil, töötlusetapil ning lugemisetapil ja pakub vahendeid elektroonilise hääletamise protsessis osalemiseks Korraldajale, Lugejale, Hääletajale, Kogujale, Töötlejale, Miksijale, Audiitorile, Klienditoele, Valijate nimekirja koostajale ja täiendajale. Infosüsteemi komponendid on Kogumisteenus, Töötlemisrakendus, Võtmerakendus ning Auditirakendus. Infosüsteemiga on tihedalt seotud Valijarakendus, Kontrollrakendus ning Miksimisrakendus. Infosüsteem kasutab oma töös väliseid teenuseid - Tuvastusteenus, Allkirjastamisteenus, Registreerimisteenus, Valimiste Infosüsteem ning X-tee. IVXV krüptograafiline protokoll ------------------------------- Elektroonilise hääletamise turvalisuse, verifitseeritavuse ning hääletamise salajasuse, hääletamise korrektsuse ja hääletaja sõltumatuse saavutamiseks on rangelt kirjeldatud elektroonilise hääletamise krüptograafiline protokoll [HMVW16]_. Protokoll annab vajaliku ja piisava ülevaate IVXV ülesehitusest ning selle turvaaspektidest. IVXV komponendid realiseerivad krüptograafilise protokolli alamosi. Notatsioon ---------- Arhitektuurse lahenduse visandi illustreerimiseks kasutatakse dokumendis UML-skeeme, kus eristame värvide ja märgenditega ``<<>>`` kodeeritult olemite – tegijad, liidesed, komponendid – järgmisi aspekte: * Märgend ``<>`` (Kollane) – infosüsteemi liides või komponent defineeritakse/realiseeritakse konkreetse pakkumuse raames tehtavate tööde käigus * Märgend ``<>`` (Punane) – infosüsteem sõltub mingi funktsionaalsuse realiseerimisel kolmanda osapoole komponendist või olemasolevast liidesest, mille ümberdefineerimine eeldab ka kolmandate osapoolte tööd. * Märgend ``<>`` (Pruun) – sarnane eelmisele, kuid liidese/komponendi omanikuks on VVK. * Märgend ``<>`` (Must) – infosüsteemi jaoks oluline liides on määratlemata. .. figure:: model/img/example.png Näiteskeem ================================================ FILE: Documentation/public/liidesed/Makefile ================================================ include ../../common.mk ================================================ FILE: Documentation/public/liidesed/examples.rst ================================================ Skeemid ja näited ================= --------------------------- Valimisringkondade nimekiri --------------------------- Skeem ----- .. literalinclude:: VIS3-EHS/1_Valimisringkondade_nimekiri/districts.schema :language: json :linenos: Näide: KOV ---------- .. literalinclude:: VIS3-EHS/1_Valimisringkondade_nimekiri/district_KOV.json :language: json :linenos: Näide: EP --------- .. literalinclude:: VIS3-EHS/1_Valimisringkondade_nimekiri/districts_EP.json :language: json :linenos: Näide: RH --------- .. literalinclude:: VIS3-EHS/1_Valimisringkondade_nimekiri/districts_RH.json :language: json :linenos: Näide: RK --------- .. literalinclude:: VIS3-EHS/1_Valimisringkondade_nimekiri/districts_RK.json :language: json :linenos: ----------------- Valikute nimekiri ----------------- Skeem ----- .. literalinclude:: VIS3-EHS/2_Valikute_nimekiri/choices.schema :language: json :linenos: Näide: EP --------- .. literalinclude:: VIS3-EHS/2_Valikute_nimekiri/choices_EP.json :language: json :linenos: Näide: KOV ---------- .. literalinclude:: VIS3-EHS/2_Valikute_nimekiri/choices_KOV.json :language: json :linenos: Näide: RH --------- .. literalinclude:: VIS3-EHS/2_Valikute_nimekiri/choices_RH.json :language: json :linenos: Näide: RK --------- .. literalinclude:: VIS3-EHS/2_Valikute_nimekiri/choices_RK.json :language: json :linenos: ---------------------- E-hääletanute nimekiri ---------------------- Skeem ----- .. literalinclude:: VIS3-EHS/4_e_haaletanute_nimekiri/onlinevoters.schema :language: json :linenos: Näide: EP --------- .. literalinclude:: VIS3-EHS/4_e_haaletanute_nimekiri/onlinevoters_EP.json :language: json :linenos: Näide: KOV ---------- .. literalinclude:: VIS3-EHS/4_e_haaletanute_nimekiri/onlinevoters_KOV.json :language: json :linenos: Näide: RH --------- .. literalinclude:: VIS3-EHS/4_e_haaletanute_nimekiri/onlinevoters_RH.json :language: json :linenos: Näide: RK --------- .. literalinclude:: VIS3-EHS/4_e_haaletanute_nimekiri/onlinevoters_RK.json :language: json :linenos: ---------------- Tühistusnimekiri ---------------- Skeem ----- .. literalinclude:: VIS3-EHS/5_Tyhistusnimekiri/revoke.schema :language: json :linenos: Näide: EP --------- .. literalinclude:: VIS3-EHS/5_Tyhistusnimekiri/revoke_EP.json :language: json :linenos: Näide: KOV ---------- .. literalinclude:: VIS3-EHS/5_Tyhistusnimekiri/revoke_KOV.json :language: json :linenos: Näide: RH --------- .. literalinclude:: VIS3-EHS/5_Tyhistusnimekiri/revoke_RH.json :language: json :linenos: Näide: RK --------- .. literalinclude:: VIS3-EHS/5_Tyhistusnimekiri/revoke_RK.json :language: json :linenos: --------------------- E-hääletamise tulemus --------------------- Skeem ----- .. literalinclude:: VIS3-EHS/6_e_haaletamise_tulemus/results.schema :language: json :linenos: Näide: EP --------- .. literalinclude:: VIS3-EHS/6_e_haaletamise_tulemus/results_EP.json :language: json :linenos: Näide: KOV ---------- .. literalinclude:: VIS3-EHS/6_e_haaletamise_tulemus/results_KOV.json :language: json :linenos: Näide: RH --------- .. literalinclude:: VIS3-EHS/6_e_haaletamise_tulemus/results_RH.json :language: json :linenos: Näide: RK --------- .. literalinclude:: VIS3-EHS/6_e_haaletamise_tulemus/results_RK.json :language: json :linenos: --------------------------- E-hääletamise üldstatistika --------------------------- Skeem ----- .. literalinclude:: VIS3-EHS/7_e_haaletamise_yldstatistika/online-voters-total.schema :language: json :linenos: Näide ----- .. literalinclude:: VIS3-EHS/7_e_haaletamise_yldstatistika/online-voters-total.json :language: json :linenos: ------------------------------ E-hääletamise detailstatistika ------------------------------ Skeem ----- .. literalinclude:: VIS3-EHS/8_e_haaletamise_detailstatistika/online-voters-counties.schema :language: json :linenos: ----------------------- E-hääletamiste nimekiri ----------------------- Skeem ----- .. literalinclude:: VIS3-EHS/9_e_haaletamiste_nimekiri/ehs-xroad-api.yaml :language: yaml :linenos: ================================================ FILE: Documentation/public/liidesed/index.rst ================================================ .. IVXV registreerimisteenus IVXV registreerimisteenus ================================================================= .. raw:: html

NB! See on HTML-versioon dokumendist. Tellijale antakse üle PDF-versioon.

.. toctree:: :maxdepth: 3 :numbered: VIS3-EHS/README.md VIS3-EHS/valimissündmuse_identifikaator VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md VIS3-EHS/2_Valikute_nimekiri/SPEC.md VIS3-EHS/3_Valijate_nimekiri/SPEC.md VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md VIS3-EHS/5_Tyhistusnimekiri/SPEC.md VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md examples ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-03-02 12:43+0200\n" "PO-Revision-Date: 2024-03-02 13:31+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:1 msgid "1 Valimisringkondade nimekiri" msgstr "List of constituencies" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:3 msgid "Protseduur" msgstr "Procedure" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:5 msgid "VIS3 edastab EHS-le teabe valimisringkondade kohta." msgstr "VIS3 transmits constituency information to EHS." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:7 msgid "Andmed edastatakse inim-masin-protseduuriga:" msgstr "The data are transmitted by human-machine procedure:" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:9 msgid "VIS peakasutaja laeb JSON faili VIS3-st alla;" msgstr "The VIS head user downloads the JSON file from VIS3;" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:11 msgid "" "VIS peakasutaja allkirjastab faili digitaalselt väljaspool VIS-i ja annab " "selle EHS operaatorile;" msgstr "" "The VIS head user digitally signs the file outside the VIS and gives it to " "the EHS operator;" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:13 msgid "EHS operaator laeb digiallkirjastatud faili EHS-i." msgstr "The EHS operator uploads the digitally signed file to the EHS." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:15 msgid "Fail on JSON-formaadis. Faili ei allkirjastata." msgstr "The file is in JSON format. The file will not be signed." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:17 msgid "" "Faili struktuur on kirjeldatud JSON schema-ga. Kirjeldus on kooskõlastatud " "EHS omanikuga." msgstr "" "The file structure is described by a JSON schema. The description has been " "agreed with the EHS owner." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:19 msgid "" "EHS senine liides VIS2-ga on spetsifitseeritud dokumendis \"IVXV " "protokollide kirjeldus\" (v 1.5.0, IVXV-PR-1.5.0, 20.04.2019), [https://www." "valimised.ee/sites/default/files/uploads/eh/IVXV-protokollid.pdf](https://" "www.valimised.ee/sites/default/files/uploads/eh/IVXV-protokollid.pdf), " "jaotises 3.2 \"Valimisjaoskondade ja -ringkondade nimekiri\"." msgstr "" "The current interface of the EHS with VIS2 is specified in the document " "\"Description of the IVXV protocols\" (v 1.5.0, IVXV-PR-1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-protokollid." "pdf](https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf), section 3.2 \"List of polling stations and " "constituencies\"." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:21 msgid "" "Valimistel, kus saavad osaleda alaliselt välisriigis elavad valijad " "kantakse nad valijate nimekirja tunnusega `FOREIGN`. Sellisel juhul peab " "valimisringkondade nimekiri sisaldama regiooni nende valijate jaoks ning " "iga ringkond peab sisaldama eraldi jaoskonda, kus nende häälte üle " "arvestust peetakse. Nii selle regiooni kui jaoskondade tunnuseks on " "fiktiivne EHAK: `0000`. Näitefailis [districts_RK.json](districts_RK.json) " "on näha nii regiooni korrektne lisamine kui ka välishääletajate jaoskonna " "korrektne lisamine igasse ringkonda." msgstr "" "In elections where voters permanently resident abroad are eligible, they " "are entered on the electoral roll with the symbol `FOREIGN`. In this case, " "the list of constituencies must include the region for these voters and " "each constituency must include a separate polling station where their votes " "are counted. Both this region and the precincts shall be identified by the " "fictitious EHAK: `0000'. The example file [districts_RK.json](districts_RK." "json) shows both the correct inclusion of a region and the correct " "inclusion of an out-of-town voter precinct in each district." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:25 msgid "Edastatav fail" msgstr "Transmitted file" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:27 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" "The election event identifier must conform to the format [Election event " "identifier](../valimissündmuse_identifikaator.md)." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:29 msgid "Faili struktuur (JSON-skeem): [districts.schema](districts.schema)" msgstr "File structure (JSON schema): [districts.schema](districts.schema)" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:31 msgid "Näited (JSON):" msgstr "Examples (JSON):" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:33 msgid "[district_KOV.json](district_KOV.json)" msgstr "[district_KOV.json](district_KOV.json)" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:34 msgid "[districts_EP.json](districts_EP.json)" msgstr "[districts_EP.json](districts_EP.json)" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:35 msgid "[districts_RH.json](districts_RH.json)" msgstr "[districts_RH.json](districts_RH.json)" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:36 msgid "[districts_RK.json](districts_RK.json)" msgstr "[districts_RK.json](districts_RK.json)" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:38 msgid "Taustainfo" msgstr "Background information" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:40 msgid "" "Kandidaate on võimalik valimisele üles seada ainult konkreetses " "valimisringkonnas. Ringkondade järgi antakse valijatele hääletamise valikud:" msgstr "" "For any voter it is only possible to vote for candidates from a single " "constituency. Voters are given voting options by constituency:" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:42 msgid "Iga valija kuulub talle määratud valimisringkonda;" msgstr "Each voter belongs to the constituency assigned to him or her;" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:43 msgid "" "Kõigis ühe ringkonna jaoskondades saavad valijad teha valiku vaid selle " "ringkonna valikute vahel;" msgstr "" "In each of the polling station in a district, voters can only choose " "between the options for that district;" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:45 msgid "" "Eesti riiklikel valimistel eristatakse kohalike omavalitsuste volikogude " "(KOV) valimisi, Riigikogu valimisi, Euroopa Parlamendi valimisi ning " "rahvahääletusi." msgstr "" "In Estonian national elections, a distinction is made between local " "government elections, Riigikogu elections, European Parliament elections " "and referendums." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:47 msgid "" "KOV valimised korraldatakse vastavalt seadusele „Kohaliku omavalitsuse " "volikogu valimise seadus“. Valimine toimub kohaliku omavalitsuse tasandil, " "igal omavalitsusel on oma hääletamistulemus. Valimisringkonnad " "moodustatakse omavalitsuse tasemel vastavalt seaduses kirjeldatud " "reeglitele." msgstr "" "Local elections are organised in accordance with the law \"Law on the " "election of local government councils\". Elections are held at the level of " "the local municipality, each municipality has its own voting results. " "Constituencies are formed at the municipal level according to the rules " "described in the law." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:49 msgid "" "Riigikogu valimised korraldatakse vastavalt seadusele „Riigikogu valimise " "seadus“. Valimine toimub riigi tasandil. Riik jaguneb 12 " "valimisringkonnaks. Hääletamistulemus tehakse kindlaks iga valimisringkonna " "kohta." msgstr "" "Elections to the Riigikogu are organised in accordance with the Act on the " "Election of the Riigikogu. Elections are held at the national level. The " "country is divided into 12 constituencies. The result of the vote is " "determined for each constituency." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:51 msgid "" "Europarlamendi valimised korraldatakse vastavalt seadusele „Euroopa " "Parlamendi valimise seadus“. Valimine toimub riigi tasandil, " "hääletamistulemus on kõigile kohalikele omavalitsustele ühine. Terve riik " "on üks valimisringkond." msgstr "" "The elections to the European Parliament are organised in accordance with " "the law \"Law on the election of the European Parliament\". Elections are " "held at national level, with the result of the vote being common to all " "local authorities. The whole country is one constituency." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:53 msgid "" "Rahvahääletused korraldatakse vastavalt seadusele „Rahvahääletuse seadus“. " "Valimine toimub riigi tasandil, hääletamistulemus on kõigile kohalikele " "omavalitsustele ühine. Terve riik on üks valimisringkond." msgstr "" "Referendums are organised in accordance with the law \"Referendums Act\". " "Elections are held at the national level, and the result of the vote is " "common to all local authorities. The whole country is one constituency." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:55 msgid "" "Erinevad valimised ei erine elektroonilise hääletamise andmevormingute ja " "protseduuride poolest. Erinevad ringkondade jaotused hallatakse VIS3 poolt." msgstr "" "The different elections do not differ in terms of electronic voting data " "formats and procedures. The different constituency breakdowns are managed " "by VIS3." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:57 msgid "" "Kandidaate on võimalik valimisele üles seada ainult konkreetses " "valimisringkonnas. Valijad on jaotatud valimisringkondade vahel. Valija " "saab teha valiku ainult tema ringkonnas kandideerivate kandidaatide vahel." msgstr "" "It is only possible to stand as a candidate in a particular constituency. " "Voters are allocated between constituencies. Voters can only choose between " "candidates standing in their constituency." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:59 msgid "" "Kuna kohaliku omavalitsuse volikogude valimisel toimub valimine Eesti " "omavalitsuste (vallad, linnad) tasemel, siis kasutatakse elektroonilise " "hääletamise protokollistikus valimisringkondade kirjeldamisel ning valijate " "ja valikute ringkonnakuuluvuse näitamisel Eesti haldus- ja asustusjaotuse " "klassifikaatorit EHAK" msgstr "" "Since the election of local government councils is held at the level of " "Estonian local governments (municipalities, cities), the Estonian " "Administrative and Settlement Classification of Estonia (EHAK) is used in " "the electronic voting protocol to describe the electoral districts and to " "indicate the district coverage of voters and choices" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:61 msgid "" "Näiteks: • Tallinna linna Pirita linnaosa EHAK kood on 0596; • Anija valla " "EHAK kood on 0141." msgstr "" "For example: - the EHAK code of Pirita district of Tallinn is 0596; - the " "EHAK code of Anija municipality is 0141." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:65 msgid "" "Riigi tasemel toimuvatel valimistel pannakse ringkonna EHAK koodiks " "kokkuleppeliselt 0." msgstr "" "For national elections, the district EHAK code is set to 0 by convention." #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:67 msgid "" "Riigikogu ja europarlamendi valimistel ning rahvahääletusel moodustatakse " "nimekirjas igasse ringkonda fiktiivne üksus alaliselt välisriigis elavate " "valijate tarbeks. Selle üksuse number on 0 ning vastav EHAK kood on 0000." msgstr "" "In Riigikogu and European Parliament elections and in referendums, a " "fictitious unit is created in each district for voters permanently resident " "abroad. The number of this unit is 0 and the corresponding EHAK code is " "0000." ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/VIS3-EHS/2_Valikute_nimekiri/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-03-02 12:43+0200\n" "PO-Revision-Date: 2024-03-02 13:34+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:1 msgid "2 Valikute nimekiri (kandidaatide nimekiri)" msgstr "List of Candidates" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:3 msgid "Protseduur" msgstr "Procedure" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:5 msgid "" "VIS3 edastab EHS-le andmed registreeritud kandidaatide (valimistel) või " "vastusevariantide (rahvahääletusel) kohta." msgstr "" "VIS3 transmits to EHS data on registered candidates (in elections) or " "options (in referendums)." #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:7 msgid "Andmed edastatakse inim-masin-protseduuriga:" msgstr "The data are transmitted by human-machine procedure:" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:9 msgid "" "VIS peakasutaja laeb JSON faili VIS3-st alla; Kasutaja peab valima " "aktiivsete valimissündmuste seast soovitud sündmuse, mille kohta infot alla " "laadida. Valimissündmus on aktiivne, kui tema staatus pole `closed` ega " "`deleted`." msgstr "" "The VIS head user downloads a JSON file from VIS3; the user has to select " "the desired event to download information about from the list of active " "election events. An election event is active if its status is neither " "`closed` nor `deleted`." #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:10 msgid "" "VIS peakasutaja allkirjastab faili digitaalselt väljaspool VIS-i ja annab " "selle EHS operaatorile;" msgstr "" "The VIS head user digitally signs the file outside the VIS and gives it to " "the EHS operator;" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:11 msgid "EHS operaator laeb digiallkirjastatud faili EHS-i." msgstr "The EHS operator uploads the digitally signed file to the EHS." #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:13 msgid "" "Fail on JSON-formaadis (näidis lisatud tööülesandele). Faili ei " "allkirjastata." msgstr "" "The file is in JSON format (sample attached to the assignment). The file is " "not signed." #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:15 msgid "Edastatav fail" msgstr "Transmitted file" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:17 msgid "" "Aluseks on EHS senine liides VIS2-ga, mis on spetsifitseeritud dokumendis " "\"IVXV protokollide kirjeldus\" (v 1.5.0, IVXV-PR-1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-protokollid." "pdf](https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf), jaotises \"Valikute nimekiri\" (jaotis 3.4)." msgstr "" "It is based on the current interface of the EHS with VIS2, as specified in " "the document \"Description of the IVXV protocols\" (v 1.5.0, IVXV-PR-1.5.0, " "20.04.2019), [https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf](https://www.valimised.ee/sites/default/files/uploads/eh/" "IVXV-protokollid.pdf), section \"List of options\" (section 3.4)." #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:19 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" "The election event identifier must conform to the format [Election event " "identifier](../valimissündmuse_identifikaator.md)." #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:21 msgid "Faili struktuur (JSON-skeem): [choices.schema](choices.schema)" msgstr "File structure (JSON schema): [choices.schema](choices.schema)" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:23 msgid "Faili näited (JSON):" msgstr "File examples (JSON):" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:25 msgid "[choices_KOV.json](choices_KOV.json)" msgstr "[choices_KOV.json](choices_KOV.json)" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:26 msgid "[choices_EP.json](choices_EP.json)" msgstr "[choices_EP.json](choices_EP.json)" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:27 msgid "[choices_RK.json](choices_RK.json)" msgstr "[choices_RK.json](choices_RK.json)" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:29 msgid "Taustainfo" msgstr "Background information" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:31 msgid "" "Valikute nimekiri sisaldab andmeid kandidaatide (valimistel) või " "vastusevariantide (rahvahääletusel) kohta. Valimiste korral on lisaks " "kandidaadi andmetele nimekirjas ka tema erakonna või valimisliidu nimi, " "mille nimekirjas ta kandideerib." msgstr "" "The list of choices contains information on the candidates (in the " "election) or the options (in the referendum). In the case of an election, " "the list includes, in addition to the candidate's details, the name of the " "political party or electoral alliance on whose list he or she is standing." #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:34 msgid "" "Valijale elektroonilise hääletamise käigus nähtavaid valimiste vahelisi " "süsteemseid erinevusi on kaks:" msgstr "" "There are two systemic differences between elections that are visible to " "the voter when voting electronically:" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:36 msgid "" "Rahvahääletusel ei valita erakondadesse kuuluvate kandidaatide vahel vaid " "vastatakse „JAH“/“EI“ rahvahääletuse küsimusele;" msgstr "" "The referendum is not a choice between candidates belonging to political " "parties, but a \"YES\"/\"NO\" answer to a referendum question;" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:38 msgid "" "Riigikogu, KOV ja Euroopa Parlamendi valimistel antakse hääl ühele " "kandidaadile, kes võib, aga ei pruugi kuuluda poliitilise ühenduse " "nimekirja." msgstr "" "In the elections to the Riigikogu, Municipalities and the European " "Parliament, votes are cast for one candidate, who may or may not be on the " "list of a political association." #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:40 msgid "" "Protokollistik kodeerib valija võimalikud valikud ringkonnas kuni 11-" "kohalise arvväärtusena, mis valikute nimekirjas kodeeritakse koos ringkonna " "EHAK-koodiga. Valijale tohivad kättesaadavad olla ainult tema " "ringkonnakohased valikud. Valijarakendus peab seda omadust tagama ning " "hääletamistulemust arvutav rakendus kontrollima." msgstr "" "The protocol encodes the voter's possible choices in the district as a " "numeric value of up to 11 digits, which in the list of choices is encoded " "together with the district's EHAK code. A voter may only have options " "available for his/her district. The voter application must guarantee this " "property and the application calculating the vote result must check it." ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/VIS3-EHS/3_Valijate_nimekiri/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:04+0000\n" "PO-Revision-Date: 2024-03-02 13:43+0200\n" "Last-Translator: \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:1 msgid "3 Valijate nimekiri EHS-le" msgstr "Voters list for the EHS" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:3 msgid "1. Annotatsioon" msgstr "Annotation" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:5 msgid "" "Spetsifikatsioon määratleb Valimiste infosüsteemi (VIS3) ja e-hääletamise" " süsteemi (EHS) vahelise liidese, mille kaudu VIS3 edastab EHS-le " "valijate algnimekirja ja valijate nimekirja muudatusi ehk " "muudatusnimekirju." msgstr "" "The specification defines the interface between the Election Information " "System (VIS3) and the e-voting system (EHS), through which VIS3 transmits" " to EHS the initial voters' list and changes to the voters' list, or " "change lists." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:9 msgid "" "Spetsifikatsioon on avalik. Spetsifikatsioon ei käsitle VIS3 ega EHS " "konfidentsiaalset siseehitust ega liidese konfidentsiaalseid elemente." msgstr "" "The specification is public. The specification does not address the " "confidential internal architecture of VIS3 or EHS, nor the confidential " "elements of the interface." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:12 msgid "" "Käesolevat spetsifikatsiooni tuleb kasutada koos VIS3 EHS API OpenAPI " "spetsifikatsiooniga (asub käesolevas repos, failis `vis-ehs-api.yaml`)." msgstr "" "This specification should be used in conjunction with the VIS3 EHS API " "OpenAPI specification (located in this repo, in the file `vis-ehs-" "api.yaml`)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:14 msgid "2. Sõnumivahetus nimekirjade edastamiseks" msgstr "Exchange of messages for the transmission of lists" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:16 msgid "" "Valijate nimekirja põhjal tuvastab EHS isiku hääleõiguse ja " "ringkonnakuuluvuse. Valijate nimekiri võib hääletamisperioodi jooksul " "muutuda, sellest tulenevalt võib valija saada hääleõiguse, jääda oma " "hääleõigusest ilma või saada hääleõiguse senisest erinevas ringkonnas. " "EHS peab nende muutustega arvestama. Muudatused saab EHS VIS3 vahendusel " "muudatusnimekirjadena." msgstr "" "Based on the voters' list, the EHS determines a person's eligibility to " "vote and district eligibility. The electoral roll may change during the " "voting period, and as a result, a voter may become eligible to vote, be " "disenfranchised, or become eligible to vote in a different district. The " "EHS must take these changes into account. The changes can be obtained by " "EHS via VIS3 as change lists." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:22 msgid "" "Spetsifikatsioonis defineeritud liidese vahendusel suhtlevad vahetult EHS" " ja VIS3:" msgstr "" "EHS and VIS3 communicate directly via the interface defined in the " "specification:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:25 msgid "" "VIS3 liidestub Rahvastikuregistri andmekoguga ning hangib seal nii " "valijate algnimekirja kui ka muudatusnimekirjad." msgstr "" "VIS3 interfaces with the Population Register database and retrieves both " "the initial voters' list and the amended voters' lists." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:27 msgid "EHS esitab VIS3-le päringuid muudatusnimekirjade saamiseks." msgstr "The EHS will query VIS3 for change lists." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:29 msgid "Kaudselt on liidesega seotud:" msgstr "Indirectly linked to the interface:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:31 msgid "Rahvastikuregister, kus toimub nimekirjade haldamine;" msgstr "Population register, where the lists are managed;" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:32 msgid "" "VIS3 ja EHS operaatorid, kes vahetavad taustakanalis algnimekirja ning " "suhtlevad võimalike tõrgete lahendamisel;" msgstr "" "VIS3 and EHS operators exchanging the initial list in the background " "channel and communicating on possible glitches;" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:34 msgid "Audiitor, kes veendub et EHS on VIS3 poolt tarnitud nimekirjad rakendanud;" msgstr "" "An auditor who makes sure that EHS has implemented the lists delivered by" " VIS3;" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:35 msgid "" "EHS vallasrežiimis töötlemisrakendus, mis verifitseerib EHS sidusrežiimi " "komponentide poolt üle antud urni." msgstr "" "A processing application in EHS standalone mode that verifies the ballot " "box passed by the EHS online mode components." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:38 msgid "2.1 Ettevalmistused nimekirjade edastamiseks" msgstr "Preparations for the transmission of lists" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:40 msgid "![Joonis 1: Sõnumivahetuse ettevalmistamine](model/list_prepare.png)" msgstr "![Figure 1: Preparing a message exchange](model/list_prepare.png)" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:40 msgid "Joonis 1: Sõnumivahetuse ettevalmistamine" msgstr "Figure 1: Preparing the exchange of messages" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:42 msgid "" "Valijate alg- ja muudatusnimekirjade vahetamisele eelnevalt tuleb " "vahetada nimekirjadele juurdepääsuks ja nimekirjade autentsuse " "kontrolliks vajalikud võtmed ja sertifikaadid (sammud 1-5)" msgstr "" "Prior to the exchange of the voters' initial and amended lists, the keys " "and certificates needed to access the lists and to verify their " "authenticity must be exchanged (steps 1-5)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:46 msgid "2.2 Valijate algnimekirja edastamine" msgstr "Transmission of the initial list of voters" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:48 msgid "![Joonis 2: Algnimekirja edastamine](model/list_initial.png)" msgstr "![Figure 2: Transmitting the initial list](model/list_initial.png)" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:48 msgid "Joonis 2: Algnimekirja edastamine" msgstr "Figure 2: Transmission of the initial list" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:50 msgid "" "Valijate algnimekiri järjekorranumbriga 0 laetakse EHSi haldusliidese " "veebiliidesest. Valijate algnimekirja laadimine on eelduseks " "muudatusnimekirjade edasiseks automaatseks laadimiseks." msgstr "" "The initial list of voters with order number 0 is downloaded from the web" " interface of the EHS management interface. The loading of the initial " "list of voters is a prerequisite for further automatic loading of the " "modification lists." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:54 msgid "Valijate algnimekirja laadimine toimub järgmistes etappides:" msgstr "" "The loading of the initial list of voters will take place in the " "following steps:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:56 msgid "" "VIS3 kasutab Rahvastikuregistri X-tee teenust valijate algnimekirja " "laadimiseks (sammud 1-3)." msgstr "" "VIS3 uses the Population Register X-Road service to load the initial list" " of voters (steps 1-3)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:58 msgid "" "VIS3 peakasutaja pärib allkirjastatud algnimekirja VIS3 teenusest, ning " "allkirjastab algnimekirja täiendavalt ID-kaardiga (sammud 4-6)." msgstr "" "The VIS3 end-user inherits the signed initial list from the VIS3 service," " and additionally signs the initial list with an ID card (steps 4-6)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:60 msgid "" "VIS3 peakasutaja edastab allkirjastatud algnimekirja EHS operaatorile " "(samm 7)" msgstr "" "The VIS3 head user forwards the signed initial list to the EHS operator " "(step 7)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:62 msgid "" "EHS operaator laeb digitaalselt allkirjastatud algnimekirja EHSi, kus see" " rakendatakse (sammud 8-9)." msgstr "" "The EHS operator uploads the digitally signed initial list to the EHS " "where it is implemented (steps 8-9)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:65 msgid "2.3 Valijate muudatusnimekirja edastamine" msgstr "Transmission of the voters' change list" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:67 msgid "![Joonis 3: Muudatusnimekirja edastamine](model/list_changeset.png)" msgstr "![Figure 3: Forwarding a change list](model/list_changeset.png)" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:67 msgid "Joonis 3: Muudatusnimekirja edastamine" msgstr "Figure 3: Forwarding the revision list" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:69 msgid "" "Valijate nimekirja muudatusnimekirja laadimise algatab EHS. " "Muudatusnimekirjad on järjestatud, nii EHS kui ka VIS3 peavad arvet, " "milline on viimane loodud muudatusnimekiri." msgstr "" "The EHS initiates the loading of the voters' list. The changelists are " "ordered, both EHS and VIS3 keep a record of the last changelist created." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:73 msgid "" "EHS algatab uue muudatusnimekirja laadimise pöördudes uue " "järjekorranumbriga VIS3 vastava otspunkti poole. EHS võib varasemaid " "muudatusnimekirju uuesti pärida, kasutades varasemat järjekorranumbrit." msgstr "" "EHS initiates the loading of the new changelist by addressing the " "corresponding VIS3 endpoint with the new queue number. EHS may re-request" " previous changelists using the previous sequence number." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:77 msgid "" "VIS3 saab muudatused Rahvastikuregistri X-tee teenusest. VIS3 poolne " "muudatuste hankimine on EHSile muudatuste esitamisest sõltumatu " "paralleelprotsess. See tähendab, et üks EHSile minev muudatusnimekiri " "võib sisaldada mitut Rahvastikuregistrist tulnud muudatust." msgstr "" "The VIS3 will receive changes from the X-Road service of the Population " "Register. The retrieval of amendments by VIS3 is a parallel process " "independent of the submission of amendments to the EHS. This means that a" " single list of changes going to the EHS may contain several changes " "coming from the Population Register." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:82 msgid "Muudatusnimekirjade edastamine EHSi käib järgmiselt:" msgstr "The transmission of the changelists to the ETS takes place as follows:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:84 msgid "EHS esitab päringu muudatusnimekirja saamiseks (samm 1)" msgstr "EHS will submit a request for a change list (step 1)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:85 msgid "Kui muudatusi ei ole, siis ei ole ka muudatusnimekirja (samm 2)" msgstr "If there are no changes, there is no changelist (step 2)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:86 msgid "" "EHS kordab mingi aja möödudes päringut muudatusnimekirja saamiseks (samm " "3)" msgstr "EHS repeats the query after some time to get the changelist (step 3)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:87 msgid "" "VIS3 edastab vahepeal saabunud muudatused EHSile ning EHS rakendab need " "edukalt (sammud 4-5)" msgstr "" "VIS3 forwards the changes that have arrived in the meantime to EHS and " "EHS successfully implements them (steps 4-5)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:89 msgid "" "Nii VIS3 kui EHS suurendavad muudatusnimekirjade järjekorranumbrit ning " "mõne aja möödudes edastatakse uus muudatusnimekiri (sammud 6-8)" msgstr "" "Both VIS3 and EHS will increment the queue number of the changelists and " "after some time a new changelist will be transmitted (steps 6-8)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:92 #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:96 msgid "**Märkused**" msgstr "**Notes**" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:93 msgid "" "Kui järjekorras järgmise muudatusnimekirja pärimisel muudatuskirjed " "puuduvad vastatakse HTTP staatusega `404` (not found)." msgstr "" "If the next in the queue of changelists is queried and no changelists are" " found, the HTTP status `404` (not found) is returned." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:97 msgid "" "Kui päritakse muudatusnimekirja suurema järjenumbriga, kui tegelik " "järgmise muudatusnimekirja järjenumber, vastatakse HTTP staatusega `409` " "(conflict)." msgstr "" "If a changelist with a higher sequence number than the actual sequence " "number of the next changelist is received, HTTP status `409` (conflict) " "is returned." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:100 msgid "2.4 Veajuhtumite lahendamine" msgstr "Troubleshooting situations" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:102 msgid "![Joonis 4: Veajuhtumite lahendamine](model/list_errors.png)" msgstr "![Figure 4: Error handling](model/list_errors.png)" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:102 msgid "Joonis 4: Veajuhtumite lahendamine" msgstr "Figure 4: Error handling" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:104 msgid "" "Muudatusnimekirjade edastamisel ei saa välistada vigu. Olenevalt vea " "iseloomust on võimalik taaste, keerulisematel juhtudel tuleb mõni " "vigaseks osutunud nimekiri vahele jätta. Veajuhtumi menetlemise ajal " "muudatusnimekirju ei edastata." msgstr "" "Errors cannot be excluded in the transmission of changelists. Depending " "on the nature of the error, it may be possible to revert, in more complex" " cases some lists that are found to contain errors should be skipped. No " "changelists will be forwarded during the processing of an error." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:109 msgid "Veajuhtumite lahendamine toimub järgmiselt:" msgstr "Error handling is as follows:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:111 msgid "" "EHS ja VIS3 käivitavad protokolli muudatusnimekirja edastamiseks (sammud " "1-3)." msgstr "" "EHS and VIS3 will trigger a protocol for the transmission of the " "changelist (steps 1-3)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:113 msgid "" "EHS tunnistab nimekirja vigaseks ning teavitab sellest operaatorit (samm " "4)." msgstr "EHS will declare the list as corrupt and inform the operator (step 4)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:114 msgid "" "Probleemi analüüsides tuvastatakse EHS-poolne tõrge, mida on võimalik " "lahendada. Tõrge lahendatakse ning EHS ja VIS3 kordavad edukalt " "protokolli (sammud 5-7)." msgstr "" "Analysis of the problem identifies an EHS failure that can be resolved. " "The fault is resolved and EHS and VIS3 successfully replicate the " "protocol (steps 5-7)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:117 msgid "" "EHS ja VIS3 käivitavad protokolli muudatusnimekirja edastamiseks (sammud " "8-10)." msgstr "" "EHS and VIS3 will trigger a protocol for the transmission of the " "changelist (steps 8-10)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:119 msgid "" "EHS tunnistab nimekirja vigaseks ning teavitab sellest operaatorit (samm " "11)." msgstr "EHS will declare the list as corrupt and inform the operator (step 11)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:121 msgid "" "Probleemi analüüsides tuvastatakse sisuline probleem nimekirjas. Vigast " "nimekirja ei muudeta, luuakse uus korrektne nimekiri. EHS operaator laeb " "digitaalselt allkirjastatud korralduse vigase nimekirja vahele jätmiseks " "(samm 12)" msgstr "" "Analysing the problem identifies a substantive problem with the list. The" " incorrect list is not modified, a new correct list is created. The EHS " "operator uploads a digitally signed order to skip the incorrect list " "(step 12)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:125 msgid "" "EHS ja VIS3 suurendavad järjekorranumbrit ning käivitavad protokolli " "muudatusnimekirja edastamiseks (sammud 13-15)." msgstr "" "EHS and VIS3 increment the queue number and start a protocol to transmit " "the changelist (steps 13-15)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:127 msgid "" "EHS ja VIS3 suurendavad järjekorranumbrit ning käivitavad protokolli " "muudatusnimekirja edastamiseks (sammud 16-17). VIS3 vastab HTTP " "staatusega 409 (conflict)." msgstr "" "EHS and VIS3 increment the queue number and start a protocol to transmit " "the changelist (steps 16-17). VIS3 responds with HTTP status 409 " "(conflict)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:130 msgid "" "EHS tuvastab vale järjenumbriga nimekirja laadimise ning teavitab sellest" " operaatorit (samm 18)." msgstr "" "The EHS detects the loading of a list with the wrong sequence number and " "informs the operator (step 18)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:132 msgid "" "Tõrge lahendatakse ning EHS ja VIS3 kordavad edukalt protokolli (sammud " "19-21)." msgstr "" "The failure is resolved and EHS and VIS3 successfully repeat the protocol" " (steps 19-21)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:134 msgid "2.5 Nimekirjade loendi edastamine" msgstr "Transmission of the list of lists" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:136 msgid "3. Nimekirja andmevorming" msgstr "Data format of the list" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:138 msgid "" "Nimekirja andmevorming on sama nii valijate algnimekirja kui " "muudatusnimekirjade jaoks." msgstr "" "The list data format is the same for both the initial list of voters and " "the amended lists." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:141 msgid "" "Nimekiri esitatakse UTF-8-NOBOM vormingus tekstifailina. " "Andmestruktuuride eraldajaks kasutatakse reavahetusmärki `LF` (ASCII-kood" " `0x0A`). Andmestruktuuride väljade eraldajaks kasutatakse tabeldusmärki " "`TAB` (ASCII-kood `0x09`)." msgstr "" "The list is presented as a UTF-8-NOBOM text file. The separator of the " "data structures shall be the space character `LF` (ASCII code `0x0A`). " "Fields of data structures shall be delimited by the tab delimiter `TAB` " "(ASCII code `0x09`)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:146 msgid "Nimekiri koosneb päiseridadest ja kirjetest." msgstr "The list consists of headers and entries." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:148 msgid "Päiseridade sisu on järgmine:" msgstr "The content of the headlines is as follows:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:150 msgid "" "`version` - andmestruktuuri versiooninumber, mille pikkus on piiratud 2 " "tähemärgiga. Spetsifikatsioonile vastava nimekirja korral on selle välja " "väärtus 2." msgstr "" "`version` - version number of the data structure, limited to 2 " "characters. For a specification conforming list, its field value is 2." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:153 msgid "" "`election_identifier` - valimissündmuse identifikaator, mille pikkus on " "piiratud 28 tähemärgiga ASCII kooditabelist. Nimekirja rakendamine toimub" " ainult vastava identifikaatoriga valimissündmuse kontekstis. " "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" "`election_identifier` - election event identifier, limited to 28 " "characters from the ASCII code table. The implementation of the " "enumeration shall only take place in the context of an election event " "with the corresponding identifier. The election event identifier must " "conform to the format [Election event " "identifier](../valimissündmuse_identifikaator.md)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:156 msgid "" "`changeset` - nimekirja järjekorranumber. Rangelt kasvav number (0, 1, 2," " ...), mis defineerib nimekirjade rakendamise järjekorra. Algnimekirja " "järjekorranumbriks on 0." msgstr "" "`changeset` - the sequence number of the list. An ordinal number (0, 1, " "2, ...) that defines the order in which lists are implemented. The queue " "number of the initial list is 0." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:159 msgid "" "`period` - nimekirjas kajastuvate muudatuste ajavahemik. Esimene väli " "sisaldab perioodi algust, teine lõppu. Algnimekirja puhul on perioodi " "algus ja lõpu väärtused võrdsed. Väli on informatiivne." msgstr "" "`period` - the period of time of the changes in the list. The first field" " contains the start of the period, the second the end. In the case of a " "sub-list, the start and end values of the period are equal. The field is " "informative." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:163 msgid "Kirje koosneb väljadest, mille sisu on järgmine:" msgstr "The record consists of fields, the content of which is as follows:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:165 msgid "" "`person_code` - isikukood on valija unikaalne identifikaator, mille " "alusel EHS tuvastab isiku hääleõiguse ja ringkonnakuuluvuse." msgstr "" "`person_code` - the person code is the unique identifier of the voter, " "which EHS uses to determine the person's eligibility to vote and to be " "elected." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:167 msgid "" "`voter_name` - valija nimi, informaalne väli, otsuste tegemisel ei " "kasutata." msgstr "" "`voter_name` - name of voter, informal field, not used for decision " "making." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:168 msgid "" "`action` - kirjega seotud tegevus. `lisamine` tähendab uue valija " "lisamist ja `kustutamine` olemasoleva valija eemaldamist." msgstr "" "`action` - action related to an item. An `add' action is an action to add" " a new selector and a `delete' action is an action to remove an existing " "voter." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:170 msgid "" "`kov_code` - haldusüksus, kuhu valija kuulub. Haldusüksuse " "identifitseerimiseks kasutatakse kohaliku omavalitsuse EHAK-koodi, " "Tallinna korral linnaosa EHAK-koodi, alaliselt välisriigis elava valija " "korral kasutatakse väärtust `FOREIGN`." msgstr "" "`kov_code` - the administrative unit to which the voter belongs. To " "identify the administrative unit, the EHAK code of the local municipality" " is used, in the case of Tallinn the EHAK code of the district, in the " "case of a voter permanently resident abroad the value `FOREIGN` is used." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:174 msgid "" "`electoral_district_id` - valimisringkonna number identifitseerib " "valimisringkonna, kus valija hääletab. KOV valimiste korral kehtib " "identifikaator haldusüksuse sees. RK, EP ja RH valimiste korral on " "identifikaator haldusüksuste ülene." msgstr "" "`electoral_district_id` - the electoral district number identifies the " "electoral district where the voter votes. In the case of local elections," " the identifier is valid within the municipality. In the case of CoR, EP " "and EPP elections, the identifier is supra-administrative." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:179 msgid "" "Välju `voter_name`, `kov_code` ja `electoral_district_id` kasutatakse " "ainult lisamiskirjes (`action` väärtus `lisamine`)." msgstr "" "The fields `voter_name`, `kov_code` and `electoral_district_id` are only " "used in the addition record (`action` value `add`)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:182 msgid "Andmevormingu formaalne kirjeldus Backus-Naur notatsioonis:" msgstr "Formal description of the data format in Backus-Naur notation:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:212 msgid "3.1 Nimekirja tõlgendamine" msgstr "Interpreting the list" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:214 msgid "Nimekirju töötlev rakendus lähtub järgmistest reeglitest:" msgstr "The application that processes the lists follows these rules:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:216 msgid "Nimekiri rakendatakse tervikuna." msgstr "The list will be implemented in its entirety." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:217 msgid "" "Nimekirja rakendamisele eelnevad vormingu ja kooskõlalisuse kontrollid, " "vigaseid nimekirju ei rakendata." msgstr "" "The implementation of the list is preceded by formatting and consistency " "checks, and incorrect lists are not implemented." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:219 msgid "Rakendus kontrollib nimekirja versiooni." msgstr "The application checks the version of the list." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:220 msgid "Rakendus kontrollib valimissündmuse identifikaatorit." msgstr "The application checks the election event identifier." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:221 msgid "Rakendus kontrollib nimekirja järjekorranumbrit." msgstr "The application checks the order number of the list." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:222 msgid "" "Rakendus kontrollib nimekirja kõigi kirjete kooskõlalisust oma " "andmebaasiga." msgstr "" "The application checks the consistency of all the entries in the list " "with its database." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:223 msgid "Kooskõlalisust kontrollitakse kirjete esinemisjärjekorras." msgstr "Coordination is checked in the order of occurrence of the records." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:224 msgid "" "Kui tegevus on `lisamine`, siis ei tohi vastava isikukoodiga kirjet " "rakenduse andmebaasis olla." msgstr "" "If the activity is an `addition', then there must be no record with the " "corresponding ID in the application database." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:226 msgid "" "Kui tegevus on `kustutamine`, siis rakendus kontrollib, kas vastava " "isikukoodiga kirje on rakenduse andmebaasis olemas. Kui ei ole, siis " "rakendus logib veateate ja jätkab järgmiste kirjete töötlust." msgstr "" "If the action is 'delete', the application will check if the " "corresponding record with the personal identification code exists in the " "application database. If not, the application logs an error message and " "continues processing the following records." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:229 msgid "" "Kui valijaga soetud andmeid on vaja muuta, näiteks valija liigub ühest " "haldusüksusest või valimisringkonnast teise, siis kantakse valijate " "nimekirja muudatuste hulka üks kustutamise kirje, millega valija oma " "eelmisest üksusest kustutatakse ja üks lisamise kirje, millega valija " "uues üksuses valijate nimekirja lisatakse. Ka kõik teised muudatused " "valija andmetes - näiteks nimemuutus - toimuvad läbi vana kirje " "kustutamise ja uue lisamise." msgstr "" "If it is necessary to modify the voter's record, for example, if the " "voter moves from one municipality or constituency to another, a deletion " "entry to delete the voter from his/her previous unit and an addition " "entry to add the voter to the voter list in the new unit are included in " "the changes to the voter list. All other changes to the voter's details -" " such as a name change - are also made by deleting the old record and " "adding the new one." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:236 msgid "" "Valijate algnimekirjas on ainult lisamiskirjed, iga valija kohta " "maksimaalselt üks kirje. Muudatusnimekirjas peavad ühe valija kohta " "käivad kirjed olema nimekirjas loogilises järjestuses ning liiasuseta. " "Ehk kustutamine enne lisamist ning maksimaalselt üks kustutamise-lisamise" " paar." msgstr "" "The initial list of voters contains only additions, with a maximum of one" " entry per voter. In the amendment list, the entries per voter must be in" " a logical order in the list and must not be redundant. Perhaps a " "deletion before an addition, and a maximum of one deletion-addition pair." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:241 msgid "" "On võimalik, et valimise ajal muutub valija isikukood. Sellisel juhul " "lisatakse nimekirja vana isikukoodiga kustutamise kirje ning uue " "isikukoodiga lisamise kirje. Täiendav korduvhääletamise kontroll ei ole " "selle liidese skoobis ja teostakse VIS3 poolt eraldi." msgstr "" "It is possible that the voter's personal identification number will " "change during the election. In such a case, a deletion entry with the old" " ID will be added to the list, and an addition entry with the new ID will" " be added. The additional re-vote check is not in the scope of this " "interface and is performed separately by VIS3." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:247 msgid "3.2 Näited nimekirjadest" msgstr "Examples of lists" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:249 msgid "Valijate algnimekiri, 0." msgstr "Initial list of voters, 0." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:267 msgid "Muudatusnimekiri, 1:" msgstr "List of changes, 1:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:269 msgid "Muutub valija 20000000002 haldusüksus." msgstr "Change the municipality of the voter 20000000002." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:270 msgid "Valija 30000000003 kaotab hääleõiguse." msgstr "The voter 30000000003 loses the right to vote." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:271 msgid "Valijale 11000000011 antakse hääleõigus." msgstr "The voter 11000000011 is given the right to vote." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:285 msgid "Muudatusnimekiri, 2:" msgstr "List of changes, 2:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:287 msgid "Muutub valija 20000000002 nimi." msgstr "The name of the website 20000000002 will change." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:288 msgid "Valija 60000000006 kaotab hääleõiguse." msgstr "The voter 60000000006 loses the right to vote." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:300 msgid "Muudatusnimekiri, 3:" msgstr "List of changes, 3:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:302 msgid "Muutub valija 20000000003->10000000003 isikukood koos nimega." msgstr "" "The voter's 20000000003->10000000003 personal identification number will " "be changed together with the name." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:303 msgid "Valija 60000000006 saab hääleõiguse." msgstr "The voter 60000000006 gets the right to vote." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:315 msgid "4. Nimekirja signeerimine" msgstr "Signing the list" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:317 msgid "" "Nii algnimekirjaga kui muudatusnimekirjadega kaasatakse allkirjafail " "(FIPS 186-4), mille moodustab andmeallikas, arvutades algsest valijate " "nimekirjast SHA256-räsi ning allkirjastades selle räsi ECDSA võtmega " "(kasutame P-256 kõverat). Andmeallika poolt genereeritud avalik võti " "tehakse taustakanalis kättesaadavaks EHSile ning selle võtme alusel " "kontrollitakse EHS komponentides valijate nimekirjade terviklust." msgstr "" "Both the initial list and the changelists are accompanied by a signature " "file (FIPS 186-4), which is formed by the data source by computing the " "SHA256 hash from the initial voter list and signing this hash with the " "ECDSA key (we use the P-256 curve). The public key generated by the data " "source is made available in the background channel to the EHS and is used" " by the EHS components to verify the integrity of the voter lists." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:324 msgid "" "Võtmete genereerimiseks, signeerimiseks ning verifitseerimiseks võib " "kasutada tööriista OpenSSL:" msgstr "The OpenSSL tool can be used to generate, sign and verify keys:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:327 msgid "" "Võtme genereerimine: `openssl ecparam -name prime256v1 -genkey -noout " "-out private.key.pem`" msgstr "" "Key generation: `openssl ecparam -name prime256v1 -genkey -noout -out " "private.key.pem`" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:329 msgid "" "Avaliku võtme eraldamine: `openssl ec -in private.key.pem -pubout -out " "public.key.pem`" msgstr "" "Public key extraction: `openssl ec -in private.key.pem -pubout -out " "public.key.pem`" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:331 msgid "" "Andmefaili signeerimine: `openssl dgst -sha256 -sign private.key.pem -out" " data.sig data.txt`" msgstr "" "Signing a data file: `openssl dgst -sha256 -sign private.key.pem -out " "data.sig data.txt`" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:333 msgid "" "Signatuuri verifitseerimine: `openssl dgst -sha256 -verify public.key.pem" " -signature data.sig data.txt`" msgstr "" "Signature verification: `openssl dgst -sha256 -verify public.key.pem " "-signature data.sig data.txt`" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:336 msgid "" "Näide antud meetodi kasutamiseks golang keeles on leitav repositooriumis " "[DigiSign](https://github.com/e-gov/DigiSign)" msgstr "" "An example of using this method in golang can be found in the repository " "[DigiSign](https://github.com/e-gov/DigiSign)." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:339 msgid "5. Transpordiprotokoll" msgstr "Transport protocol" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:341 msgid "VIS3-EHS käesolev masinliides koosneb kahest API otspunktist." msgstr "This VIS3-EHS machine interface consists of two API endpoints." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:343 msgid "" "API otspunkt `ehs-voters-changeset` konkreetse muudatusnimekirja " "laadimiseks VIS3-st" msgstr "" "API endpoint `ehs-voters-changeset` to load a specific changelist from " "VIS3." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:345 msgid "" "API otspunkt `ehs-list-election-changesets` ülevaate saamiseks " "avalikustatud nimekirjadest" msgstr "" "API endpoint `ehs-list-election-changesets` for an overview of published " "lists" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:348 msgid "" "Transpordiprotokoll on HTTPS, kuna volitamata ligipääs nimekirjadele " "tuleb tõkestada kasutatakse mõlemapoolselt autenditud TLS ühendusi." msgstr "" "The transport protocol is HTTPS, since unauthorised access to the lists " "must be blocked using mutually authenticated TLS connections." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:351 msgid "5.1 `ehs-voters-changeset`" msgstr "`ehs-voters-changeset`" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:353 msgid "" "HTTP meetod on GET. Päringu tegemisel tuleb kasutada kohustuslikke " "parameetreid `changeset` ja `election_identifier`, kus" msgstr "" "The HTTP method is GET. When making a query, you must use the mandatory " "parameters `changeset` and `election_identifier`, where" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:356 msgid "`changeset` on muudatusnimekirja `integer` tüüpi järjekorranumber." msgstr "`changeset` is the `integer` type sequence number of the changelist." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:357 #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:379 msgid "`election_identifier` on `string` tüüpi valimissündmuse identifikaator." msgstr "" "`election_identifier` is an identifier of type `string` for an election " "event." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:359 msgid "" "Kui EHS teeb API otspunkti GET päringu, siis juhul kui vastava " "identifikaatori ja järjekorranumbriga nimekiri eksisteerib, vastab VIS3 " "`application/octet-stream` tüüpi baidijadaga, mis esitab kahest failist " "koosnevat ZIP konteinerit:" msgstr "" "When the EHS makes an API endpoint GET request, if a list with the " "corresponding identifier and sequence number exists, VIS3 will respond " "with a `application/octet-stream` type byte string representing a ZIP " "container of two files:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:364 msgid "nimekirjafail nimega `-voters-.utf`" msgstr "listfile named `-voters-.utf`" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:366 msgid "signatuurifail nimega `election_identifier<>-voters-.sig`" msgstr "signature file named `election_identifier<>-voters-.sig`" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:369 #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:414 msgid "Sellise vastuse korral on HTTP status 200." msgstr "The HTTP status for this response is 200." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:371 msgid "" "Juhul kui vastava järjekorranumbriga muudatusnimekirja veel ei eksisteeri" " antakse vastuses HTTP status 404." msgstr "" "If the corresponding changelist with the corresponding queue number does " "not yet exist, the HTTP status 404 is returned." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:374 msgid "5.1 `ehs-list-election-changesets`" msgstr "`ehs-list-election-changesets`" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:376 msgid "" "HTTP meetod on GET. Päringu tegemisel tuleb kasutada kohustuslikku " "parameetrit `election_identifier`:" msgstr "" "The HTTP method is GET. When making a query, the mandatory " "`election_identifier` parameter must be used:" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:381 msgid "" "Kui EHS teeb API otspunkti, siis juhul kui vastava identifikaatoriga " "valimine eksisteerib, vastab VIS3 `application/json` tüüpi baidijadaga, " "mis sisaldab endas JSON vormingus viiteid kõigile väljastatud " "muudatusnimekirjadele." msgstr "" "When EHS makes an API endpoint, if a election with the corresponding " "identifier exists, VIS3 will respond with a `application/json` type byte " "string containing JSON format references to all issued changelists." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:385 msgid "" "MÄRKUS. Viidetes tarnitavad URL-id ei ole õiged ja seetõttu " "mittekasutatavad. EHS peab konkreetse muudatuste nimekirja poole " "pöördumise URL-i koostama vastavalt VIS3 EHS API OpenAPI vormingus " "spetsifikatsioonile (asub käesolevas repos, failis `vis3-ehs-api.yaml`). " "VIS3 edasisestes versioonides eemaldame viidetest URL-id. 20.07.2021." msgstr "" "NOTE. The URLs supplied in the references are not correct and therefore " "cannot be used. The URL to a specific changelist must be generated by EHS" " according to the VIS3 EHS API OpenAPI format specification (located in " "this repo, in the file `vis3-ehs-api.yaml`). In future versions of VIS3, " "we will remove URLs from the references. 20.07.2021." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:387 msgid "" "MÄRKUS. Viidetes tarnitavate URL-de käsitlust muudetud: elemendis `url` " "tarnitakse mitte täis-URL, vaid ainult _path_ ja -query_ osa." msgstr "" "NOTE. Changed the handling of URLs supplied in references: the `url` " "element does not supply the full URL, but only the _path_ and -query_ " "parts." #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:416 msgid "6. Näited" msgstr "Examples" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:418 msgid "7. Viited" msgstr "References" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:420 msgid "" "[\"DigiSign\" - lihtne protokoll edastatavate failide allkirjastamiseks, " "koos teostusnäitega](https://github.com/e-gov/DigiSign)" msgstr "" "[\"DigiSign\" - a simple protocol for signing files in transit, with " "examples](https://github.com/e-gov/DigiSign)" ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: 2024-03-02 13:44+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:1 msgid "E-hääletanute nimekiri" msgstr "List of e-voters" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:3 msgid "Protseduur" msgstr "Procedure" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:5 msgid "" "E-hääletanute nimekiri on pärast e-hääletamise lõppu EHS poolt genereeritav " "ja väljastatav nimekiri e-hääletanud isikutest. E-hääletanute nimekiri " "loetakse sisse VIS3-e (moodul NIM)." msgstr "" "The e-vote list is the list of e-voters generated and issued by EHS after " "the end of e-voting. The list of e-voters shall be read into VIS3 (module " "NIM)." #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:7 msgid "E-hääletanute nimekiri edastakse inim-masin-protseduuriga:" msgstr "The list of e-voters is transmitted by human-machine procedure:" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:9 msgid "EHS operaator laeb JSON-faili EHS-st alla;" msgstr "The EHS operator downloads the JSON file from the EHS;" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:11 msgid "" "EHS operaator allkirjastab faili digitaalselt väljaspool EHS-i ja annab " "selle VIS peakasutajale;" msgstr "" "The EHS operator digitally signs the file outside the EHS and gives it to " "the VIS head user;" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:13 msgid "VIS peakasutaja laeb digikonteinerist välja võetud faili VIS3-i." msgstr "" "The VIS head user uploads the file taken from the digital container to VIS3." #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:15 msgid "Fail on JSON-formaadis. Faili näidised on tööülesandes." msgstr "The file is in JSON format. File examples are in the appendix." #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:17 msgid "Faili struktuur on kirjeldatud JSON-skeemiga." msgstr "The file structure is described by a JSON schema." #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:19 msgid "Edastatav fail" msgstr "Transmitted file" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:21 msgid "" "Aluseks on EHS senine liides VIS2-ga, mis on spetsifitseeritud dokumendis " "\"IVXV protokollide kirjeldus\" (v 1.5.0, IVXV-PR-1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-protokollid." "pdf](https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf), jaotises \"E-hääletanute nimekiri\" (jaotis 9.2)." msgstr "" "It is based on the current interface of the EHS with VIS2, as specified in " "the document \"Description of the IVXV protocols\" (v 1.5.0, IVXV-PR-1.5.0, " "20.04.2019), [https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf](https://www.valimised.ee/sites/default/files/uploads/eh/" "IVXV-protokollid.pdf), section \"E-voting list\" (section 9.2)." #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:23 msgid "" "Faili struktuur (JSON-skeem): [onlinevoters.schema](onlinevoters.schema)" msgstr "" "File structure (JSON schema): [onlinevoters.schema](onlinevoters.schema)" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:25 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" "The election event identifier must conform to the format [Election event " "identifier](../valimissündmuse_identifikaator.md)." #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:27 msgid "Faili näited (JSON):" msgstr "File examples (JSON):" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:29 msgid "[onlinevoters_EP.json](onlinevoters_EP.json)" msgstr "[onlinevoters_EP.json](onlinevoters_EP.json)" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:30 msgid "[onlinevoters_KOV.json](onlinevoters_KOV.json)" msgstr "[onlinevoters_KOV.json](onlinevoters_KOV.json)" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:31 msgid "[onlinevoters_RH.json](onlinevoters_RH.json)" msgstr "[onlinevoters_RH.json](onlinevoters_RH.json)" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:32 msgid "[onlinevoters_RK.json](onlinevoters_RK.json)" msgstr "[onlinevoters_RK.json](onlinevoters_RK.json)" ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/VIS3-EHS/5_Tyhistusnimekiri/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: 2024-03-02 13:46+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:1 msgid "5 Tühistus- ja ennistusnimekiri" msgstr "5 Revokation and Restoration list" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:3 msgid "" "VIS3 edastab EHS-le tühistus- ja ennistusnimekirja (lühidalt - " "tühistusnimekiri)." msgstr "" "VIS3 transmits to the EHS the revocation and restoration list (in short - " "the revokation list)." #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:5 msgid "" "Tühistusnimekiri sisaldab andmeid isikute kohta, kelle e-hääl tuleb " "tühistada (on paberhääletanud ja sellest tulenevalt ei lähe e-hääl arvesse " "valimistulemuste kokkulugemisel) või ennistada (s.t. tühistatakse eelnev " "tühistamine ning häälte uuesti üle lugemisel võetakse ennistatud e-hääl " "arvesse)." msgstr "" "The revokation list contains the details of persons whose e-vote is to be " "cancelled (they have voted by paper ballot and therefore their e-vote will " "not be counted in the recount) or restored (i.e. the previous revokation is " "cancelled and the restored e-vote is counted in the tally)." #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:7 msgid "Fail on JSON-formaadis." msgstr "The file is in JSON format." #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:9 msgid "Protseduur" msgstr "Procedure" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:11 msgid "Tühistusnimekiri edastakse inim-masin-protseduuriga:" msgstr "The revokation list is transmitted by human-machine procedure:" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:13 msgid "EHS operaator laeb JSON-faili EHS-st alla;" msgstr "The EHS operator downloads the JSON file from the EHS;" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:15 msgid "" "EHS operaator allkirjastab faili digitaalselt väljaspool EHS-i ja annab " "selle VIS peakasutajale;" msgstr "" "The EHS operator digitally signs the file outside the EHS and gives it to " "the VIS head user;" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:17 msgid "VIS peakasutaja laeb digikonteinerist välja võetud faili VIS3-i." msgstr "" "The VIS head user uploads the file taken from the digital container to VIS3." #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:19 msgid "Edastatav fail" msgstr "Transmitted file" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:21 msgid "" "Aluseks on EHS senine liides VIS2-ga, mis on spetsifitseeritud dokumendis " "\"IVXV protokollide kirjeldus\" (v 1.5.0, IVXV-PR-1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-protokollid." "pdf](https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf), jaotises \"Tühistus- ja ennistusnimekiri\" (jaotis 9.1)." msgstr "" "It is based on the EHS current interface with VIS2, as specified in the " "document \"Description of the IVXV Protocols\" (v 1.5.0, IVXV-PR-1.5.0, " "20.04.2019), [https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf](https://www.valimised.ee/sites/default/files/uploads/eh/" "IVXV-protokollid.pdf), section \"Cancellation and Restoration " "List\" (section 9.1)." #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:23 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" "The election event identifier must conform to the format [Election event " "identifier](../valimissündmuse_identifikaator.md)." #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:25 msgid "Faili struktuur (JSON-skeem): [revoke.schema](revoke.schema)" msgstr "File structure (JSON schema): [revoke.schema](revoke.schema)" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:27 msgid "Faili näited (JSON):" msgstr "File examples (JSON):" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:29 msgid "[revoke_EP.json](revoke_EP.json)" msgstr "[revoke_EP.json](revoke_EP.json)" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:30 msgid "[revoke_KOV.json](revoke_KOV.json)" msgstr "[revoke_KOV.json](revoke_KOV.json)" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:31 msgid "[revoke_RH.json](revoke_RH.json)" msgstr "[revoke_RH.json](revoke_RH.json)" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:32 msgid "[revoke_RK.json](revoke_RK.json)" msgstr "[revoke_RK.json](revoke_RK.json)" ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/VIS3-EHS/6_e_haaletamise_tulemus/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: 2024-03-02 13:47+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:1 msgid "E-hääletamise tulemus" msgstr "Result of e-voting" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:3 msgid "" "E-hääletamise lõppedes genereerib EHS e-hääletamise tulemuste faili " "(hääletamistulemuse fail). Fail laetakse VIS3-e (valimistulemuse moodulisse " "TUL)." msgstr "" "At the end of the e-voting, the EHS generates an e-voting results file " "(voting result file). The file is uploaded to VIS3 (in the election result " "module TUL)." #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:5 msgid "Protseduur" msgstr "Procedure" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:7 msgid "Fail edastatakse inim-masin-protseduuriga:" msgstr "The file is transmitted by human-machine procedure:" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:9 msgid "EHS operaator laeb JSON-faili EHS-st alla;" msgstr "The EHS operator downloads the JSON file from the EHS;" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:11 msgid "" "EHS operaator allkirjastab faili digitaalselt väljaspool EHS-i ja annab " "selle VIS peakasutajale;" msgstr "" "The EHS operator digitally signs the file outside the EHS and gives it to " "the VIS head user;" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:13 msgid "VIS peakasutaja laeb digikonteinerist välja võetud faili VIS3-i." msgstr "" "The VIS head user uploads the file taken from the digital container to VIS3." #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:15 msgid "Fail on JSON-formaadis." msgstr "The file is in JSON format." #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:17 msgid "Edastatav fail" msgstr "Transmitted file" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:19 msgid "" "Aluseks on EHS senine liides VIS2-ga, mis on spetsifitseeritud dokumendis " "\"IVXV protokollide kirjeldus\" (v 1.5.0, IVXV-PR-1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-protokollid." "pdf](https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf), jaotises \"E-hääletamise tulemus\" (jaotis 9.3)." msgstr "" "It is based on the current interface of the EHS with VIS2, as specified in " "the document \"Description of the IVXV protocols\" (v 1.5.0, IVXV-PR-1.5.0, " "20.04.2019), [https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf](https://www.valimised.ee/sites/default/files/uploads/eh/" "IVXV-protokollid.pdf), section \"E-voting result\" (section 9.3)." #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:21 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" "The election event identifier must conform to the format [Election event " "identifier](../valimissündmuse_identifikaator.md)." #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:23 msgid "Faili struktuur (JSON-skeem): [results.schema](results.schema)" msgstr "File structure (JSON schema): [results.schema](results.schema)" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:25 msgid "Faili näited (JSON):" msgstr "File examples (JSON):" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:27 msgid "[results_EP.json](results_EP.json)" msgstr "[results_EP.json](results_EP.json)" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:28 msgid "[results_KOV.json](results_KOV.json)" msgstr "[results_KOV.json](results_KOV.json)" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:29 msgid "[results_RH.json](results_RH.json)" msgstr "[results_RH.json](results_RH.json)" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:30 msgid "[results_RK.json](results_RK.json)" msgstr "[results_RK.json](results_RK.json)" ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: 2024-03-02 13:48+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:1 msgid "7 E-hääletamisest osavõtu üldstatistika" msgstr "General statistics on participation in e-voting" #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:3 msgid "" "EHS annab lühikese perioodiga (nt 15 min) VIS3-le andmeid kui palju " "valijaid on e-hääletanud." msgstr "" "The EHS will provide VIS3 with information on how many voters have e-voted " "in a short period of time (e.g. 15 min)." #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:5 msgid "EHS teeb seda HTTPS päringutega VIS3 poolt pakutava otspunkti vastu." msgstr "" "EHS does this by HTTPS requests against the endpoint provided by VIS3." #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:7 msgid "Päringu vastuses tagastatav fail:" msgstr "The file to be returned in response to the query:" #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:9 msgid "JSON-skeem: [online-voters-total.schema](online-voters-total.schema)" msgstr "JSON schema: [online-voters-total.schema](online-voters-total.schema)" #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:11 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" "The election event identifier must conform to the format [Election event " "identifier](../valimissündmuse_identifikaator.md)." #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:13 msgid "Näide (JSON): [online-voters-total.json](online-voters-total.json)" msgstr "Example (JSON): [online-voters-total.json](online-voters-total.json)" ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: 2024-03-02 13:49+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:1 msgid "8 E-hääletamisest osavõtu detailne statistika" msgstr "Detailed statistics on participation in e-voting" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:3 msgid "" "E-hääletamise lõppedes annab EHS VIS3-le e-hääletamisest osavõtu detailse " "statistika." msgstr "" "At the end of e-voting, EHS will provide VIS3 with detailed statistics on " "e-voting participation." #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:5 msgid "" "E-hääletamisest osavõtu statistikat kuvatakse valimiste veebilehel, samuti " "edastatakse masintöödeldaval kujul meediaorganisatsioonidele ja lõpuks " "publitseeritakse avaandmetena." msgstr "" "The e-voting statistics will be displayed on the election website, as well " "as being provided in a machine-readable format to media organisations and " "eventually published as open data." #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:7 msgid "Protseduur" msgstr "Procedure" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:9 msgid "EHS operaator laeb faili alla." msgstr "The EHS operator downloads the file." #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:11 msgid "EHS operaator edastab faili VIS3 peakasutajale." msgstr "The EHS operator forwards the file to the VIS3 head user." #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:13 msgid "VIS3 peakasutaja laeb faili VIS3-e üles." msgstr "The VIS3 head user uploads the file to VIS3." #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:15 msgid "Faili edastatakse eelhääletamise ajal, kord päevas." msgstr "The file will be transmitted during the advance voting, once a day." #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:17 msgid "Edastatav fail" msgstr "Transmitted file" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:19 msgid "" "JSON-skeem: [online-voters-counties.schema](online-voters-counties.schema)" msgstr "" "JSON-skeem: [online-voters-counties.schema](online-voters-counties.schema)" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:21 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" "The polling event identifier must conform to the format [Polling event " "identifier](../polling_event_identifier.md)." #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:23 msgid "" "Näide (JSON): [online-voters-counties.json](online-voters-counties.json)" msgstr "" "Example (JSON): [online-voters-counties.json](online-voters-counties.json)" ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: 2024-03-02 13:55+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:1 msgid "E-hääletamiste nimekiri" msgstr "List of e-votes" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:3 msgid "kavand v0.4" msgstr "draft v0.4" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:5 msgid "Muutelugu" msgstr "Migration story" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:7 msgid "Eemaldatud sõna \"jooksev\" / Priit Parmakson, 23.11.2022" msgstr "Removed the word \"current\" / Priit Parmakson, 23.11.2022" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:8 msgid "" "Lisatud OpenAPI kirjelduse publitseerimise teave. / Priit Parmakson, " "13.12.2022" msgstr "" "Added information on the publication of the OpenAPI specification / Priit " "Parmakson, 13.12.2022" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:9 msgid "" "Täpsustatud e-hääletamiste väljanäitamist VIS3-s. / Priit Parmakson, " "15.11.2022" msgstr "" "The e-voting field in VIS3 has been specified. / Priit Parmakson, 15.11.2022" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:10 msgid "Lisatud jõudluskaalutlused. / Priit Parmakson, 01.11.2022" msgstr "Performance scales added / Priit Parmakson, 01.11.2022" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:11 msgid "" "Asendatud \"e-hääletanu\" -> \"e-hääletamine\". Põhjus: inimene võib e-" "hääletada mitu korda (ümberhääletamine); vastavalt korrigeeritud JSON " "väljanimesid \"evotersbatch\" -> \"evotingsbatch\". / Priit Parmakson, " "01.09.2022" msgstr "" "Replaced \"e-vote\" -> \"e-voting\". Reason: a person can e-vote multiple " "times (re-vote); corrected JSON field names \"evotersbatch\" -> " "\"evotingsbatch\" accordingly. / Priit Parmakson, 01.09.2022" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:12 msgid "" "Eemaldatud: hääletamise kuupäeva/aja edastamine. Põhjus: turvakaalutlus " "(häälemüügi takistamine). / Priit Parmakson, 01.09.2022 (Sven Heibergiga " "arutelu alusel)" msgstr "" "Removed: transmission of voting date/time. Reason: security considerations " "(to prevent the sale of votes) / Priit Parmakson, 01.09.2022 (in discussion " "with Sven Heiberg)." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:13 msgid "" "Lisatud: 1) ärivajaduse täpsustus; 2) e-hääletamise fakti aja edastamine; 3) " "edastuse kontroll ja vajadusel täiendamine või parandamine lõpliku faili " "abil. / Priit Parmakson, 04.05.2022" msgstr "" "Attached: 1) specification of the business need; 2) transmission of the e-" "voting fact time; 3) checking of the transmission and, if necessary, " "completion or correction by means of the final file / Priit Parmakson, " "04.05.2022" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:14 msgid "Arutelu - RVT ja RIA inimesed, 04.05.2022" msgstr "Debate - RVT and RIA people, 04.05.2022" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:15 msgid "" "\"E-hääletanute jooksev nimekiri\", kavand v0.2. / Priit Parmakson, 02.05.2022" msgstr "\"Rolling list of e-voters\", draft v0.2. / Priit Parmakson, 02.05.2022" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:16 msgid "Arutelu: X-tee kasutamine, JSON - Tarmo Hanga, Priit Parmakson, apr 2022" msgstr "Discussion: using X-tee, JSON - Tarmo Hanga, Priit Parmakson, Apr 2022" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:17 msgid "\"EHS- VIS3 liidestus\" (kavand) - Indrek Leesi, apr 2022" msgstr "\"EHS- VIS3 interface\" (draft) - Indrek Leesi, Apr 2022" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:19 msgid "Ülevaade" msgstr "Overview" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:21 msgid "" "Käesolev spetsifikatsioon määratleb protokolli e-hääletamiste nimekirja " "edastamiseks e-hääletamise süsteemist (edaspidi - EHS) Valimiste infosüsteemi " "(edaspidi - VIS3)." msgstr "" "This specification defines the protocol for the transfer of the list of e-" "votes from the e-voting system (hereinafter referred to as EHS) to the " "Election Information System (hereinafter referred to as VIS3)." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:23 msgid "" "Varasematel valimistel (k.a KOV 2021) on peale hääletamise lõppu, " "valimispäeval edastatud EHS-st VIS3-le e-hääletanute nimekiri (edaspidi - e-" "hääletanute lõplik nimekiri). See edastus on spetsifitseeritud: [E-" "hääletanute nimekiri](https://github.com/e-gov/VIS3-EHS/blob/" "main/4_e_haaletanute_nimekiri/SPEC.md)." msgstr "" "In previous elections (including Municipal elections 2021), the list of e-" "voters (hereafter referred to as the final list of e-voters) has been " "transmitted from the EHS to VIS3 after the end of voting on the day of the " "election. This transmission is specified in [e-vote list](https://github.com/" "e-gov/VIS3-EHS/blob/main/4_e_haaletanute_nimekiri/SPEC.md)." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:25 msgid "" "Siiski on vajadus VIS3-s saada teavet, kas valija on e-hääletanud, juba enne " "ülalnimetatud lõplikku edastust. Valija, kes on e-hääletanud, võib tulla " "eelhääletamise perioodil valimisjaoskonda ja soovida paberil hääletada. " "Valimisjaoskonna töötajal oleks hea omada võimalust VIS3-st vaadata, kas " "valija on e-hääletanud. Seda teavet saab muuhulgas kasutada valija " "hoiatamiseks, et paberhääletamisega tema e-hääletamine tühistub." msgstr "" "However, there is a need to obtain information in VIS3 on whether the voter " "has e-voted, even before the final transmission mentioned above. A voter who " "has e-voted may come to a polling station during the early voting period and " "wish to vote by paper ballot. It would be useful for the polling station " "staff to have the possibility to check in VIS3 whether the voter has e-voted. " "This information can be used, among other things, to warn the voter that his/" "her e-vote will be cancelled if he/she votes by paper ballot." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:27 msgid "E-hääletamiste nimekiri edastatakse EHS-st VIS3-e X-tee teenusega." msgstr "" "The list of e-votes will be transmitted from the EHS to VIS3 via the X-road " "service." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:29 msgid "" "Teenust pakub EHS. VIS3 pöördub regulaarselt teenuse poole. EHS edastab e-" "hääletamiste andmete paki. VIS3 saab paki ja salvestab andmed VIS3 andmebaasi." msgstr "" "The service is provided by EHS. VIS3 regularly calls on the service. EHS will " "transmit the e-voting data packet. VIS3 receives the packet and stores the " "data in the VIS3 database." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:31 msgid "Sünkroonimiseks kasutatakse e-hääletamiste nummerdamist." msgstr "Numbering of e-votes is used for synchronisation." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:33 msgid "Kaalutlused" msgstr "Reflections" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:35 msgid "" "Teenus on arendatud X-tee REST võimalusi kasutades, vastavalt X-tee REST " "sõnumiprotokollile ([X-Road: Message Protocol for REST](https://www.x-tee.ee/" "docs/live/xroad/pr-rest_x-road_message_protocol_for_rest.html)). Andmed " "väljastatakse JSON-vormingus." msgstr "" "The service has been developed using the REST capabilities of the X-Road, " "according to the X-Road REST message protocol ([X-Road: Message Protocol for " "REST](https://www.x-tee.ee/docs/live/xroad/pr-rest_x-" "road_message_protocol_for_rest.html)). The data is output in JSON format." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:37 msgid "" "X-teed on otstarbekas kasutada, sest kuigi VIS3 ja EHS võivad olla käitatud " "samas taristus, on ikkagi vaja tagada usaldus, logimine ja paindlikkus - " "omadused, mille tagamine X-tee kasutamisega kokkuvõttes tõenäoliselt ei saaks " "olema ei lihtsam ega odavam." msgstr "" "The X-road makes sense because, although VIS3 and EHS can be run on the same " "infrastructure, there is still a need to ensure trust, logging and " "flexibility - features that, in the end, using the X-road is unlikely to be " "easier or cheaper to provide." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:39 msgid "" "Protokollis on arvesse võetud Rahvastikuregistri ja VIS3 vaheliste X-tee " "teenuste kasutamise kogemust (REST sõnumiprotokoll, JSON, OpenAPI)." msgstr "" "The protocol takes into account the experience of using X-Road services " "between the Population Register and VIS3 (REST message protocol, JSON, " "OpenAPI)." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:41 msgid "" "Erilist tähelepanu on pööratud andmete re-sünkroonimise võimalusele tõrgete " "korral. Selleks on pakkide pärimine kavandatud idenmpotentsena." msgstr "" "Particular attention has been paid to the possibility of re-synchronising " "data in case of failures. For this purpose, packet inheritance is designed as " "an idempotent." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:43 msgid "" "E-hääletanute nimekirja \"peegeldamiseks\" EHS-st VIS3-e võiks " "põhimõtteliselt kasutada ka mõnda standardset sünkroonimisprotokolli (nt Git, " "Rsync vms, vt \\[1], \\[2], \\[3]). Kuna vajadus on suhteliselt lihtne, siis " "seda ei ole tehtud." msgstr "" "To \"mirror\" the list of e-voters from the EHS to VIS3, in principle a " "standard synchronisation protocol could also be used (e.g. Git, Rsync etc., " "see \\[1], \\[2], \\[3]). Since the need is relatively simple, this has not " "been done." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:45 msgid "" "Jõudluskaalutlused: E-hääletamise jooksvat nimekirja edastatakse e-" "hääletamise perioodil (6 päeva). E-hääletamise fakte edastatakse kokku u 300 " "000. E-hääletamise perioodi esimesel tunnil võib oodata u 5000 e-hääletamist; " "perioodi viimasel tunnil u 10 000 e-hääletamist." msgstr "" "Performance considerations: the e-voting rolling list will be made available " "during the e-voting period (6 days). The total number of e-voting files to be " "transmitted will be around 300 000. Approximately 5,000 e-votes can be " "expected in the first hour of the e-voting period; approximately 10,000 e-" "votes in the last hour of the period." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:47 msgid "E-hääletamiste järjenumbrid" msgstr "E-vote sequential numbers" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:49 msgid "" "Tagamaks, et e-hääletamiste nimekiri kantakse EHS-st VIS3-e õigeaegselt ja " "täielikult, kasutatakse järjenumbreid. EHS omistab igale e-hääletamisele " "järjenumbri (ingl Sequence Number)." msgstr "" "Sequential numbers will be used to ensure that the list of e-votes is " "transferred from the EHS to VIS3 in a timely and complete manner. The EHS " "assigns a Sequence Number to each e-vote." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:51 msgid "" "Järjenumber on naturaalarv, alates ühest. Väärtus `0` tähistab olukorda, kus " "e-hääletamisi veel ei ole toimunud." msgstr "" "The sequence number is a natural number, starting from one. The value `0` " "indicates a situation where no e-voting has yet taken place." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:53 msgid "Igas valimissündmuses on oma numeratsioon." msgstr "Each election event has its own numbering." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:55 msgid "Teenus" msgstr "Service" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:57 msgid "" "Teenuse vastutav töötleja on Riigi Valimisteenistus (RVT). Teenuse volitatud " "töötleja on Riigi Infosüsteemi Amet (RIA). Teenust osutav süsteem on EHS." msgstr "" "The controller of the service is the State Election Service (RVT). The " "authorised processor of the service is the State Information System Authority " "(RIA). The system providing the service is EHS." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:59 msgid "" "Teenust kasutav süsteem on VIS3. Teenust kasutava süsteemi vastutav töötleja " "on RIA." msgstr "" "The system using the service is VIS3. The system using the service is the RIA." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:61 msgid "" "Teenuse ärinimi on \"E-hääletamiste nimekiri\". Teenuse tehniline nimi (X-tee " "REST teenusekood, Service Code) on `e-votings-running-list`." msgstr "" "The business name of the service is \"E-voting list\". The technical name of " "the service (X-way REST Service Code) is `e-votings-running-list`." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:63 msgid "Teenus pakub järgmisi otspunkte:" msgstr "The service offers the following endpoints:" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:65 msgid "" "1 `GET /elections`. \"Valimissündmuste loetelu\" väljastab aktiivsete " "valimissündmuste loetelu. Aktiivne valimissündmus teenuse kontekstis on " "selline, mille kohta EHS on valmis väljastama e-hääletamiste nimekirja." msgstr "" "1 `GET /elections`. \"List of election events\" outputs a list of active " "election events. An active election event in the context of the service is " "one for which EHS is ready to issue a list of e-votes." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:67 msgid "" "2 `GET /elections/{electionId}/lastseqno`. \"Viimane järjenumber\" väljastab " "konkreetse valimissündmuse viimase EHS-s registreeritud e-hääletamise " "järjenumbri." msgstr "" "2 `GET /elections/{electionId}/lastseqno`. \"Last Sequence Number\" gives the " "last e-voting sequence number registered in the EHS for a particular election " "event." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:69 msgid "" "3 `GET /elections/{electionId}/evotingsbatchfrom/{fromseqno}`. \"e-" "hääletamiste pakk\". Selle päringuga pärib VIS3 EHS-lt valimissündmuse " "`{electionId}` e-hääletamiste paki, alatest e-hääletamisest järjenumbriga " "`{fromseqno}`." msgstr "" "3 `GET /elections/{electionId}/evotingsbatchfrom/{fromseqno}`. \"e-voting " "pack\". With this query, VIS3 shall inherit from EHS the e-voting batch for " "the election event `{electionId}`, starting from e-voting with the suffix " "`{fromseqno}`." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:71 msgid "" "Päringute ja vastuste andmestruktuuride ja samuti vastuskoodide " "spetsifikatsiooni vt OpenAPI spetsifikatsioonis: [ehs-xroad-api.yaml](ehs-" "xroad-api.yaml)." msgstr "" "For the specification of the query and response data structures and also the " "response codes, see the OpenAPI specification: [ehs-xroad-api.yaml](ehs-xroad-" "api.yaml)." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:73 msgid "" "Teenuse OpenAPI spetsifikatsioon publitseeritakse turvaserveris, vastavalt " "spetsifikatsioonile [https://www.x-tee.ee/docs/live/xroad/pr-mrest_x-" "road_service_metadata_protocol_for_rest.html#4-retrieving-list-of-services](X-" "Road: Service Metadata Protocol for REST), jaotis 5 \"Retrieving the OpenAPI " "description of a Service\"." msgstr "" "The OpenAPI specification of a Service is published in the Security Server, " "according to the specification [https://www.x-tee.ee/docs/live/xroad/pr-" "mrest_x-road_service_metadata_protocol_for_rest.html#4-retrieving-list-of-" "services](X-Road: Service Metadata Protocol for REST), section 5 \"Retrieving " "the OpenAPI description of a Service\"." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:75 msgid "Teenuse OpenAPI spetsifikatsioon näitepäring:" msgstr "OpenAPI service specification example request:" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:77 msgid "" "`curl -H \"accept: application/json\" -H \"X-Road-Client:ee-dev/COM//" "dev\" \"https://.../r1/ee-dev/COM//ehs/getOpenAPI?serviceCode=e-" "votings-running-list\"`" msgstr "" "`curl -H \"accept: application/json\" -H \"X-Road-Client:ee-dev/COM//" "dev\" \"https://.../r1/ee-dev/COM//ehs/getOpenAPI?serviceCode=e-" "votings-running-list\"`" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:79 msgid "Otspunkt \"Valimissündmuste loetelu\"" msgstr "Endpoint \"List of electoral events\"" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:81 #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:99 msgid "Näide." msgstr "Example." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:83 msgid "Päring: `GET /elections`" msgstr "Query: `GET /elections`" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:85 msgid "VIS3 pärib EHS-lt aktiivsete valimissündmuste loetelu." msgstr "VIS3 will query the list of active electoral events from EHS." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:87 #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:105 #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:128 msgid "Vastus:" msgstr "Answer:" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:93 msgid "EHS vastab, et aktiivseid valimissündmusi on üks - `RK_2023`." msgstr "EHS replies that there is one active election event - `RK_2023`." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:95 msgid "" "Kui aktiivseid valimissündmusi ei ole, siis EHS peab vastuses saatma tühja " "massiivi (JSON Array)." msgstr "" "If there are no active election events, EHS must send an empty array (JSON " "Array) in the response." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:97 msgid "Otspunkt \"Viimane järjenumber\"" msgstr "Endpoint \"Last serial\"" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:101 msgid "Päring: `GET /elections/RK_2023/lastseqno`" msgstr "Query: `GET /elections/RK_2023/lastseqno`" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:103 msgid "VIS3 pärib valimissündmuse `RK_2023` viimase e-hääletamise järjenumbrit." msgstr "" "VIS3 will query the last e-voting sequence number of the election event " "`RK_2023`." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:114 msgid "" "EHS vastab, et valimissündmuse `RK_2023` viimase e-hääletamise järjenumber on " "`54002`." msgstr "" "The EHS replies that the last e-voting sequence number for the election event " "`RK_2023` is `54002`." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:116 msgid "" "Kui valimissündmus on EHS-le tundmatu, siis EHS vastab HTTP vastuskoodiga " "`404 Not Found`." msgstr "" "If the election event is unknown to EHS, EHS will respond with the HTTP " "response code `404 Not Found`." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:118 msgid "" "Järjenumbrid algavad ühest (`1`). Kui valimisündmuses ei ole veel ükski " "valija e-hääletanud, siis vastab EHS `lastseqno` väärtusega `0`." msgstr "" "Sequential numbers start with one (`1`). If no voter has yet e-voted in the " "election event, the EHS will match `lastseqno` with a value of `0`." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:120 msgid "Otspunkt \"e-hääletanute pakk\"" msgstr "Endpoint \"e-vote pack\"" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:122 msgid "Näide 3." msgstr "Example 3." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:124 msgid "Päring: `G /elections/RK_2023/evotingsbatchfrom/54001`" msgstr "Query: `G /elections/RK_2023/evotingsbatchfrom/54001`" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:126 msgid "" "VIS3 pärib valimissündmuse `RK_2023` e-hääletamiste andmeid, alates " "järjenumbrist `54001`." msgstr "" "VIS3 will query the e-voting data for the election event 'RK_2023', starting " "with the sequence number '54001'." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:155 msgid "" "EHS vastab, et saadab valimissündmuse `RK_2023` e-hääletamiste andmeid, " "alates järjenumbrist `54001`, pakina, milles on kuni `100` kirjet. " "Konkreetses pakis on kaks kirjet, kuna paki moodustamise hetkel on viimase " "EHS-s registreeritud e-hääletamise järjenumber `54002`. Esimene kirje " "tähendab, et valija `LEO KASS`, isikukoodiga `38101010020` on valimistel " "`RK_2023` e-hääletanud. Kirjes on ka valija KOV EHAK-kood ja valimisringkonna " "number." msgstr "" "The EHS replies that it will send the e-voting data for the election event " "`RK_2023`, starting with the sequence number `54001`, as a packet with up to " "`100` records. There will be two records in a particular packet, as the last " "e-voting sequence number registered in the EHS at the time the packet is " "formed is '54002'. The first record means that the voter `LEO KASS`, with the " "personal identification number `38101010020` has e-voted in the election " "`RK_2023`. The record also contains the voter's Municipal Electoral " "Registration Number and the constituency number." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:157 msgid "" "E-hääletamise fakti kohta EHS e-hääletamise aega ei saada - turvakaalutlustel." msgstr "" "The fact of e-voting will not be reported to EHS at the time of e-voting - " "for security reasons." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:159 msgid "" "Paki maksimaalsuuruse `batchmaxsize` määrab EHS, arvestusega, et andmed " "saadetakse X-tee vastussõnumi kehas (mitte manuses). Vastussõnumi töötlemisel " "turvaserveris loetakse keha üheaegselt põhimällu. Seetõttu ei tohi " "vastusõnumi keha suurus ületada 10 MB (turvaserveri vaikeseadistus)." msgstr "" "The maximum batch size `batchmaxsize` is determined by the EHS, taking into " "account that the data is sent in the body of the X-road response message (not " "in the attachment). When processing the response message in the security " "server, the body is read simultaneously into the main memory. Therefore, the " "body size of the response message shall not exceed 10 MB (default setting of " "the security server)." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:161 msgid "" "Vastuses võib olla kuni `batchmaxsize` kirjet. Kui vastuses on kirjeid vähem " "kui `batchmaxsize`, siis see tähendab, et EHS-l ei ole vastuse koostamise " "hetkel rohkem andmeid e-hääletamiste kohta." msgstr "" "The response can contain up to `batchmaxsize` records. If there are fewer " "than `batchmaxsize` items in the response, this means that the EHS does not " "have any more data on e-voting at the time the response is generated." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:163 msgid "VIS3 peab suutma töödelda erineva `batchmaxsize` väärtusega vastuseid." msgstr "" "VIS3 must be able to handle responses with different `batchmaxsize` values." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:165 msgid "Töötluse ülevaade" msgstr "Overview of treatment" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:167 msgid "" "EHS registreerib e-hääletamise fakte. Igale e-hääletamisele omistab EHS " "järjenumbri. E-hääletamise fakte võib hoida nt järjenumbri järgi " "indekseeritud tabelis - siis on VIS3-i päringutele vastamine kiire ja " "efektiivne - kuid see on EHS siseasi. Paki maksimaalsuurus peaks olema EHS " "seadistuses määratav." msgstr "" "EHS records the facts of e-voting. EHS assigns a serial number to each e-" "vote. E-voting files could be kept in a table indexed by e.g. sequence number " "- then the response to VIS3 queries is fast and efficient - but this is an " "internal matter for EHS. The maximum packet size should be configurable in " "the EHS configuration." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:169 msgid "" "VIS3 saadab valimiste aktiivsel perioodil regulaarselt päringuid EHS-i X-tee " "teenuse otspunkti \"Viimane järjenumber\". EHS saadab vastuses viimase e-" "hääletamise järjenumbri." msgstr "" "During the active period of the elections, VIS3 will regularly send queries " "to the EHS X-Road service endpoint \"Last Sequence Number\". EHS will send " "the last e-voting sequential number in the response." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:171 msgid "" "Viimase järjenumbri alusel leiab VIS3, kas VIS3-e kantud e-hääletamiste " "andmed on EHS-iga sünkroonis. Kui viimane järjenumber osutab, et EHS-s on " "lisandunud kirjeid, mis vajavad VIS3-e kandmist, siis saadab VIS3 järjest " "päringud EHS X-tee teenuse otspunkti \"e-hääletamiste pakk\", alates " "esimesest järjenumbrist, mis on VIS3-s puudu; EHS saadab küsitud paki; VIS3 " "salvestab saadud andmed ja saadab järgmise paki päringu." msgstr "" "Based on the last sequential number, VIS3 will find out whether the e-voting " "data entered in VIS3 are in sync with EHS. If the last sequential number " "indicates that there are additional records in EHS that need to be entered in " "VIS3, VIS3 will send successive queries to the EHS X-Road service endpoint 'e-" "voting batch', starting from the first sequential number that is missing in " "VIS3; EHS will send the requested batch; VIS3 will store the received data " "and send the next batch query." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:173 msgid "" "Päringute \"e-hääletamiste pakk\" töötlusloogika EHS-i poolel peab võimaldama " "VIS3-l päringuid esitada mistahes järjekorras ja kuitahes palju kordi." msgstr "" "The processing logic of the 'e-voting packet' of queries on the EHS side must " "allow VIS3 to query in any order and as many times as necessary." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:175 msgid "" "Töötlus peab olema idempotentne (samajõuline) - selles mõttes, et VIS3 võib " "päritud andmeid igal ajal uuesti küsida. Uuesti pärimisega ei tohi tekkida " "duubelandmeid, tähendusnihkeid ega kinnijooksmisi." msgstr "" "The processing must be idempotent (concurrent) - in the sense that VIS3 can " "retrieve the requested data at any time. The re-query must not result in " "duplicates, semantic ambiguities, or stalls." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:177 msgid "" "Tehnilise taustateabena märgime, et EHS hoiab e-hääletamise fakte mitte " "relatsioonilises andmebaasis, vaid etcd mäluteenuses." msgstr "" "As a technical background, EHS stores e-voting facts not in a relational " "database but in the etcd storage service." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:179 msgid "Kohaletoimetamise garantii" msgstr "Delivery guarantee" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:180 msgid "" "Sõltuvalt e-hääletamise sagedusest ja EHS jõudlusest ning seadistusest võib " "EHS-s juhtuda, et e-hääletamise väga suure sageduse perioodil e-hääletamise " "faktile järjenumbri omistamine ajalõpu (ingl timeout) tõttu ebaõnnestub. " "Selline e-hääletamise fakt jääb e-hääletamiste nimekirjas VIS3-e edastamata." msgstr "" "Depending on the frequency of e-voting and the performance and configuration " "of the EHS, it is possible that during a period of very high frequency of e-" "voting, the assignment of a sequential number to the e-voting fact may fail " "due to a timeout. Such an e-voting fact will not be transmitted to VIS3 in " "the list of e-votes." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:182 msgid "" "Seega e-hääletamiste nimekiri ei anna kõigi e-hääletamiste VIS3-e jooksvalt " "kohaletoimetamise garantiid. VIS3-e kohaletoimetatud fakte tuleb käsitada " "informatiivsetena. E-hääletamise faktid toimetatakse VIS3-e kindlalt " "täielikus koosseisus e-hääletanute (lõplikus) nimekirjas, pärast e-" "hääletamise perioodi lõppu (eraldi liides EHS ja VIS3 vahel)." msgstr "" "Therefore, the list of e-votes does not guarantee the delivery of all e-votes " "VIS3s on a rolling basis. Facts delivered to the VIS3 must be considered as " "informative. The facts of an e-vote will be delivered to the VIS3 in the " "(final) list of e-voters in its definitive complete composition, after the " "end of the e-voting period (separate interface between EHS and VIS3)." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:184 msgid "Teenuse pakkumise ajaline ulatus" msgstr "Time scale for the provision of the service" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:186 msgid "" "Konkreetse valimissündmuse kohta pakub EHS e-hääletamiste nimekirja ainult " "piiratud perioodil. See periood hõlmab e-hääletamise perioodi (kehtiva õiguse " "kohaselt 6 päeva) koos lühikeste siirdeperioodidega enne ja pärast." msgstr "" "For a specific election event, the EHS only offers a list of e-votes for a " "limited period. This period includes the e-voting period (6 days under " "current law) with short transition periods before and after." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:188 msgid "" "Kui EHS valimissündmuse kohta e-hääletamiste nimekirja enam ei paku, siis " "päringud otspunktidesse \"Viimane järjenumber\" ja \"e-hääletanute pakk\" " "saavad HTTP vastuskoodi `410 Gone`." msgstr "" "If the EHS no longer provides a list of e-votes for an election event, " "queries to the endpoints \"Last Sequence Number\" and \"e-vote pack\" will " "receive the HTTP response code `410 Gone`." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:190 msgid "" "Valimissündmuste loetelu pakub EHS pidevalt (otspunkt \"Valimissündmuste " "loetelu\"). Loetelus on valimissündmused, mille kohta EHS on valmis e-" "hääletamiste nimekirja pakkuma." msgstr "" "A list of electoral events is provided by EHS on an ongoing basis (under " "\"List of electoral events\"). The list includes election events for which " "EHS is ready to provide a list of e-voting events." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:192 msgid "Kontroll ja veaolukordade käsitlemine" msgstr "Control and error handling" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:194 msgid "" "Eeldatakse, et EHS-i poolt VIS3-le väljastatav on korrektne ja muutumatu (e-" "hääletamiste nimekirja piires). Parandus- ja muutmiskirjeid käesolev " "protokoll ei sisalda." msgstr "" "It is assumed that the EHS output to VIS3 is correct and unchanged (within " "the limits of the list of e-votes). Letters of correction and amendment are " "not included in these minutes." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:196 msgid "" "Pärast e-hääletamise lõppu, valimispäeval, edastatakse EHS-st VIS3-le e-" "hääletanute lõplik nimekiri). See edastus on spetsifitseeritud: [E-" "hääletanute nimekiri](https://github.com/e-gov/VIS3-EHS/blob/" "main/4_e_haaletanute_nimekiri/SPEC.md)." msgstr "" "After the end of e-voting, on election day, the final list of e-voters is " "transmitted from the EHS to VIS3). This transmission is specific: [e-vote " "list](https://github.com/e-gov/VIS3-EHS/blob/main/4_e_haaletanute_nimekiri/" "SPEC.md)." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:198 msgid "VIS3 operaator laeb e-hääletanute lõpliku nimekirja VIS3-e." msgstr "The VIS3 operator uploads the final list of e-voters to VIS3." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:200 msgid "" "Jooksva nimekirja ja lõpliku nimekirja erinevuse korral loetakse \"tõe " "allikaks\" lõplik nimekiri. Seega: 1) kui lõplikus nimekirjas on isik, kes " "hääletamisperioodil edastatud nimekirjas puudub, siis loetakse isik e-" "hääletanuks; 2) kui hääletamisaegses nimekirjas on isik, kes lõplikus " "nimekirjas puudub, siis märge sellise isiku kohta VIS3-s küll säilitatakse, " "kuid töötluses ja toimingutes lähtutakse lõplikust nimekirjast, s.t loetakse, " "et isik ei ole e-hääletanud. VIS3 peab omama võimekust hääletamisaegse ja " "lõpliku nimekirja erinevust avastada ja operaatorile teada anda." msgstr "" "In the event of a discrepancy between the current list and the definitive " "list, the definitive list is considered to be the \"source of truth\". Thus: " "1) if the final list contains a person who is not on the list transmitted " "during the voting period, the person is considered to have e-voted; 2) if the " "voting period list contains a person who is not on the final list, the record " "of such person is kept in VIS3, but processing and operations are based on " "the final list, i.e. the person is considered not to have e-voted. The VIS3 " "shall have the capability to detect a discrepancy between the voting list and " "the final list and to inform the operator." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:203 msgid "" "EHS-st VIS3-e edastatud e-hääletamise faktid on VIS3 kasutajaliideses " "nähtavad valimiste korraldajale, vaates \"Valijaga seotud toimingute " "ajalugu\". Kui valija e-hääletas mitu korda, siis on valijaga seotud " "toimingute ajaloos esitatud kõik valija e-hääletamised. E-hääletamise juures " "on näha kuupäev ja kellaaeg, millal e-hääletamise fakt EHS-st VIS3-e edastati." msgstr "" "The e-voting facts transmitted from the EHS to VIS3 will be visible to the " "election organiser in the VIS3 interface, in the 'Voter History' view. If a " "voter has e-voted more than once, all e-votes of the voter are shown in the " "voter activity history. The date and time at which the fact of the e-vote was " "transmitted from the EHS to VIS3 is shown next to the e-vote." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:205 msgid "Kirjandus" msgstr "Literature" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:207 msgid "\\[1] Git. https://git-scm.com/." msgstr "\\[1] Git. https://git-scm.com/." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:209 msgid "" "\\[2] CouchDB Replication Protocol, https://guide.couchdb.org/draft/" "replication.html." msgstr "" "\\[2] CouchDB Replication Protocol, https://guide.couchdb.org/draft/" "replication.html." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:211 msgid "" "\\[3] Principle and application of Rsync algorithm. https://developpaper.com/" "principle-and-application-of-rsync-algorithm/." msgstr "" "\\[3] Principle and application of Rsync algorithm. https://developpaper.com/" "principle-and-application-of-rsync-algorithm/." ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/VIS3-EHS/README.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-05-13 21:04+0000\n" "PO-Revision-Date: 2024-03-02 13:27+0200\n" "Last-Translator: \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/README.md:1 msgid "VIS3-EHS liideste spetsifikatsioonid" msgstr "VIS3-EHS interface specifications" #: ../../VIS3-EHS/README.md:3 msgid "" "Eesti riiklikel valimistel toimub e-hääletamine Valimiste infosüsteemi " "(VIS3) ja e-hääletamise süsteemi (EHS) koostöös. EHS roll on " "elektroonilise hääletamise läbiviimine lähtudes valimise definitsioonist," " mis koostatakse valimise korraldaja poolt VIS3 abil. E-hääletamise ajal " "vahetavad EHS ja VIS3 informatsiooni - võivad muutuda valijate nimekirjad" " ning liigub info e-häälte laekumise kohta." msgstr "" "In Estonian national elections, e-voting takes place in cooperation " "between the Election Information System (VIS3) and the e-voting system " "(EHS). The role of the EHS is to carry out electronic voting based on the" " definition of an election, which is drawn up by the election organiser " "using VIS3. During e-voting, the EHS and VIS3 exchange information - " "voters' lists may change and information on the collection of e-votes is " "passed on." #: ../../VIS3-EHS/README.md:5 msgid "" "Dokument esitab VIS3 ja e-hääletamise süsteemi EHS vaheliste liideste " "spetsifikatsioonid." msgstr "" "The document sets out the specifications for the interfaces between VIS3 " "and the e-voting system EHS." #: ../../VIS3-EHS/README.md:7 msgid "" "Spetsifikatsioonid on avalikud. Spetsifikatsioonid ei käsitle VIS3 ega " "EHS konfidentsiaalset siseehitust ega liideste konfidentsiaalseid " "elemente." msgstr "" "The specifications are public. The specifications do not deal with the " "confidential internal architecture of VIS3 and EHS, nor with the " "confidential elements of the interfaces." #: ../../VIS3-EHS/README.md:10 msgid "Ülevaade" msgstr "Overview" #: ../../VIS3-EHS/README.md:12 msgid "![VIS3 ja EHS liidesed (ülevaade)](img/vis-ehs.png)" msgstr "![VIS3 and EHS interfaces (overview)](img/vis-ehs.png)" #: ../../VIS3-EHS/README.md:12 msgid "VIS3 ja EHS liidesed (ülevaade)" msgstr "VIS3 and EHS interfaces (overview)" #: ../../VIS3-EHS/README.md:14 msgid "Joonis 1. VIS3 ja EHS liidesed (ülevaade)." msgstr "Figure 1. VIS3 and EHS interfaces (overview)." #: ../../VIS3-EHS/README.md:16 msgid "Märkus: Joonise originaal vt VIS3 dok-s RIAs, fail \"EHS\"." msgstr "Note: For the original drawing, see VIS3 doc in RIA, file \"EHS\"." #: ../../VIS3-EHS/README.md:18 msgid "Vasakul on VIS3, mooduli täpsusega:" msgstr "On the left is VIS3, with module precision:" #: ../../VIS3-EHS/README.md:20 msgid "KAN - Kandidaadimoodul" msgstr "KAN - Candidate module" #: ../../VIS3-EHS/README.md:21 msgid "NIM - Nimekirjamoodul" msgstr "NIM - List module" #: ../../VIS3-EHS/README.md:22 msgid "TUL - Valimistulemuse moodul" msgstr "TUL - Election results module" #: ../../VIS3-EHS/README.md:23 msgid "VAL - Valimissündmuse moodul" msgstr "VAL - Election event module" #: ../../VIS3-EHS/README.md:24 msgid "VTA - Valimistulemuse avalikustamise moodul." msgstr "VTA - Election result publishing module." #: ../../VIS3-EHS/README.md:26 msgid "" "Andmed liiguvad noole suunas. HTTPS masinliidestes on teenust pakkuvad " "otspunktid VIS3 poolel. X-tee liideses on teenusepakkujaks EHS. Inim-" "masinliides tähendab seda, et ühe süsteemi operaator laeb faili " "süsteemist alla ja edastab teise süsteemi operaatorile, kes laeb faili " "teise süsteemi üles." msgstr "" "The data moves in the direction of the arrow. In HTTPS machine " "interfaces, the service-providing endpoints are on the VIS3 side. In an " "X-road interface, the service provider is EHS. A human machine interface " "means that an operator on one system downloads a file from one system and" " forwards it to an operator on another system, who uploads the file to " "the other system." #: ../../VIS3-EHS/README.md:29 msgid "Liidesed on täpsemalt kirjeldatud allpool." msgstr "The interfaces are described in more detail below." #: ../../VIS3-EHS/README.md:31 msgid "Spetsifikatsioonid" msgstr "Specifications" #: ../../VIS3-EHS/README.md:33 msgid "[1 Valimisringkondade nimekiri](1_Valimisringkondade_nimekiri/SPEC.md)" msgstr "[1 List of constituencies](1_Valimisringkondade_nimekiri/SPEC.md)" #: ../../VIS3-EHS/README.md:35 msgid "[2 Valikute nimekiri (kandidaatide nimekiri)](2_Valikute_nimekiri/SPEC.md)" msgstr "[2 List of candidates (list of candidates)](2_Valikute_nimekiri/SPEC.md)" #: ../../VIS3-EHS/README.md:37 msgid "[3 Valijate nimekiri EHS-le](3_Valijate_nimekiri/SPEC.md)" msgstr "[3 Voters list for EHS](3_Valijate_nimekiri/SPEC.md)" #: ../../VIS3-EHS/README.md:39 msgid "[4 E-hääletanute nimekiri](4_e_haaletanute_nimekiri/SPEC.md)" msgstr "[4 List of e-voters](4_e_haaletanute_nimekiri/SPEC.md)" #: ../../VIS3-EHS/README.md:41 msgid "[5 Tühistus- ja ennistusnimekiri](5_Tyhistusnimekiri/SPEC.md)" msgstr "[5 Revokation and Restoration List](5_Tyhistusnimekiri/SPEC.md)" #: ../../VIS3-EHS/README.md:43 msgid "[6 E-hääletamise tulemus](6_e_haaletamise_tulemus/SPEC.md)" msgstr "[6 Result of the e-voting](6_e_haaletamise_tulemus/SPEC.md)" #: ../../VIS3-EHS/README.md:45 msgid "" "[7 E-hääletamisest osavõtu " "üldstatistika](7_e_haaletamise_yldstatistika/SPEC.md)" msgstr "" "[7 General statistics on e-voting " "participation](7_e_haaletamise_uldstatistika/SPEC.md)" #: ../../VIS3-EHS/README.md:47 msgid "" "[8 E-hääletamisest osavõtu " "detailstatistika](8_e_haaletamise_detailstatistika/SPEC.md)" msgstr "" "[8 Detailed statistics on e-voting " "participation](8_e_haaletamise_detailstatistika/SPEC.md)" #: ../../VIS3-EHS/README.md:49 msgid "[9 E-hääletamiste nimekiri](9_e_haaletamiste_nimekiri/SPEC.md)" msgstr "[9 e-vote list](9_e_haaletamiste_nimekiri/SPEC.md)" #: ../../VIS3-EHS/README.md:51 msgid "" "Spetsifikatsioonides kasutatav valimissündmuse identifikaator peab " "vastama formaadile [Valimissündmuse " "identifikaator](valimissündmuse_identifikaator.md)." msgstr "" "The election event identifier used in the specifications must conform to " "the format [Election event " "identifier](valimissündmuse_identifikaator.md)." #: ../../VIS3-EHS/README.md:53 msgid "Usalduse loomine masinliidestes" msgstr "Building trust in machine interfaces" #: ../../VIS3-EHS/README.md:55 msgid "Masinliidesed kaitstakse HTTPS-ga ja TLS mõlemapoolse autentimisega." msgstr "Machine interfaces are protected by HTTPS and TLS two-way authentication." #: ../../VIS3-EHS/README.md:57 msgid "" "Lisaks piiratakse VIS3 seadistusega EHS pääs ainult EHS-le määratud " "otspunktidele (3b ja 7)." msgstr "" "In addition, the VIS3 setting restricts EHS access to the endpoints " "assigned to EHS only (3b and 7)." #: ../../VIS3-EHS/README.md:59 msgid "Veakäsitlus masinliidestes" msgstr "Error handling in machine interfaces" #: ../../VIS3-EHS/README.md:61 msgid "" "VIS3 peab andma HTTP standardi kohase vastuskoodi ja veateate, kui EHS " "saadetud päring on ebakorrektne või VIS3 ei suuda päringut teenendada." msgstr "" "The VIS3 must provide an HTTP standard response code and an error message" " if the request sent by the EHS is incorrect or if the VIS3 fails to " "serve the request." #: ../../VIS3-EHS/README.md:63 msgid "" "EHS peab arvestama VIS3 tõrke võimalusega. Standardne reaktsioon tõrkele " "on päringu uuestisaatmine." msgstr "" "EHS must take into account the possibility of a VIS3 failure. The " "standard response to a failure is to resend the request." #: ../../VIS3-EHS/README.md:65 msgid "Veakäsitlus faili inimese poolt edastamise liidestes" msgstr "Error handling in human file transfer interfaces" #: ../../VIS3-EHS/README.md:67 msgid "" "VIS3 peab kontrollima üleslaetud faili süntaksit ja kus võimalik, kas " "semantikat. Ebakorrektse faili kohta tuleb anda operaatorile teada. " "Ebakorrektse faili andmeid ei kanta VIS3 andmebaasi." msgstr "" "VIS3 must check the syntax and, where possible, the semantics of the " "uploaded file. An incorrect file must be reported to the operator. The " "data of an incorrect file shall not be entered into the VIS3 database." #: ../../VIS3-EHS/README.md:69 msgid "" "Korrektse, kuid eksitusena üleslaetud faili andmeid saab VIS3 " "andmebaasist kustutada ja õige fail uuesti üles laadida." msgstr "" "The data of a correct file uploaded in error can be deleted from the VIS3" " database and the correct file uploaded again." #: ../../VIS3-EHS/README.md:71 msgid "Muudatused võrreldes VIS2-EHS-ga" msgstr "Changes compared to VIS2-EHS" #: ../../VIS3-EHS/README.md:73 msgid "VIS3-EHS liideses on võrreldes VIS2-ga muudetud ja ajakohastatud:" msgstr "The VIS3-EHS interface has been modified and updated compared to VIS2:" #: ../../VIS3-EHS/README.md:75 msgid "" "osapoolte vahetumisest (valijate nimekirja hakkab EHS-le saame mitte RR" "/SMIT-ist, vaid RIA VIS3-st)" msgstr "" "change of parties (we will get the list of voters for EHS not from " "RR/SMIT but from RIA VIS3)." #: ../../VIS3-EHS/README.md:76 msgid "valimisõiguse muutumisest (jaoskondade tähenduse muutumine)" msgstr "changes to electoral law (changing the meaning of polling stations)" #: ../../VIS3-EHS/README.md:77 msgid "valijate nimekirja ja selle uuenduste edastamisest üle liidese." msgstr "the transmission of the electoral roll and its updates over the interface." #: ../../VIS3-EHS/README.md:79 msgid "" "VIS2 ja EHS omavahelisi liideseid spetsifitseerib \"IVXV protokollide " "kirjeldus\" (v 1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf](https://www.valimised.ee/sites/default/files/uploads/eh" "/IVXV-protokollid.pdf). \"Elektroonilise hääletamise protokollistik " "defineerib elektroonilise hääletamise süsteemi komponentide vahelise " "sõnumivahetuse, kasutatavad andmestruktuurid, algoritmid ning liidesed " "väliste süsteemidega.\" Spetsifitseeritud on:" msgstr "" "The interfaces between VIS2 and EHS are specified in the \"Specification " "of the IVXV Protocols\" (v 1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf](https://www.valimised.ee/sites/default/files/uploads/eh" "/IVXV-protokollid.pdf). \"The Electronic Voting Protocol Specification " "defines the messaging between the components of the electronic voting " "system, the data structures to be used, the algorithms, and the " "interfaces to external systems.\" Specified are:" #: ../../VIS3-EHS/README.md:81 msgid "liides \"Valimisringkondade nimekiri\" (jaotis 3.2)" msgstr "the interface \"List of constituencies\" (section 3.2)." #: ../../VIS3-EHS/README.md:82 msgid "liides \"Valikute nimekiri\" (jaotis 3.4)" msgstr "the \"List of choices\" interface (section 3.4)" #: ../../VIS3-EHS/README.md:83 msgid "liides \"Valijate nimekiri\" (jaotis 3.3)" msgstr "the \"Voters' list\" interface (section 3.3)" #: ../../VIS3-EHS/README.md:84 msgid "liides \"Tühistus- ja ennistusnimekiri\" (jaotis 9.1)" msgstr "the interface \"Revokation and Restoration List\" (section 9.1)." #: ../../VIS3-EHS/README.md:85 msgid "liides \"E-hääletanute nimekiri\" (jaotis 9.2)" msgstr "the interface \"E-vote list\" (section 9.2)." #: ../../VIS3-EHS/README.md:86 msgid "liides \"E-hääletamise tulemus\" (jaotis 9.3)" msgstr "the interface \"Result of e-voting\" (section 9.3)." #: ../../VIS3-EHS/README.md:88 msgid "" "Käesolevad spetsifikatsioonid tuginevad ülalnimetatud " "spetsifikatsioonidele. Täpsemalt vt konkreetsete spetsifikatsioonide " "juures." msgstr "" "These specifications are based on the above specifications. For more " "details, see the specific specifications." #: ../../VIS3-EHS/README.md:90 msgid "" "EHS lähtekood on kättesaadav: [https://github.com/vvk-" "ehk/ivxv](https://github.com/vvk-ehk/ivxv)." msgstr "" "The EHS source code is available at: " "[https://github.com/valimised/ivxv](https://github.com/valimised/ivxv)." ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/VIS3-EHS/Taustateave/README.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 22:58+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/Taustateave/README.md:1 msgid "" "Kaustas on spetsifikatsioonid X-tee teenustele, millega VIS3 pärib " "Rahvastikuregistrist valijate nimekirja ja nimekirja muudatused:" msgstr "" #: ../../VIS3-EHS/Taustateave/README.md:4 msgid "" "`RRValimisteAlgNimekiri_kirjeldus.pdf` - Rahvastikuregistri poolt " "osutatava Valimiste algnimekirja X-tee teenuse spetsifikatsioon." msgstr "" #: ../../VIS3-EHS/Taustateave/README.md:7 msgid "" "`RRValimisteNimekirjaMuudatused.pdf` - Rahvastikuregistri poolt osutatava" " Valimiste algnimekirja muudatuste X-tee teenuse spetsifikatsioon." msgstr "" #: ../../VIS3-EHS/Taustateave/README.md:10 msgid "" "Spetsifikatsioonid võivad aidata mõista VIS3 poolt EHS-le pakutavate " "andmete koosseisu ja tähendust." msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/VIS3-EHS/valimissündmuse_identifikaator.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-03-02 12:43+0200\n" "PO-Revision-Date: 2024-03-02 13:19+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:1 msgid "Valimissündmuse identifikaator" msgstr "Election event identifier" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:3 msgid "" "Üht valimist puudutav andmestik on seotud unikaalse valimissündmuse " "identifikaatori abil." msgstr "" "A set of data relating to a single election is linked by a unique election " "event identifier." #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:5 msgid "" "Valimissündmuse identifikaator on sõne, mis koosneb kahest kohustuslikust " "ja kahest valikulisest osast:" msgstr "" "The election event identifier is a string consisting of two mandatory and " "two optional parts:" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:6 msgid "valimissündmuse tüüp, vastavalt allolevale tabelile, nt `RK`." msgstr "the type of event, according to the table below, e.g. `RK'." #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:7 msgid "aastanumbrist (nt `2023`)" msgstr "from the year (e.g. `2023`)" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:8 msgid "valikulisest erakorraliste valimiste tunnusest `_E` ja" msgstr "the optional special election flag `_E` and" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:9 msgid "valikulisest järjenumbrist , nt `2`." msgstr "from an optional sequence number , e.g. `2`." #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:11 msgid "Ülalnimetatud osad eraldatakse üksteisest allkriipsudega `_`." msgstr "The above parts are separated by underscores `_'." #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:13 msgid "" "Järjenummerdatakse tüüpide kaupa. Seejuures aasta esimese samatüübilise " "valimissündmuse korral järjenumbrit ei näidata." msgstr "" "Sequence numbering by type. The sequence number is not shown for the first " "election event of the same type in the year." #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:15 msgid "Näited:" msgstr "Examples:" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:16 msgid "`KOV_2021`" msgstr "'KOV_2021" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:17 msgid "`RH_2021`" msgstr "'RH_2021" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:18 msgid "`RH_2021_2` (2021. a teine rahvahääletus)" msgstr "`RH_2021_2` (second referendum in 2021)" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:19 msgid "`RK_2023`" msgstr "'RK_2023" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:20 msgid "`RK_2023_E` (2023. a Riigikogu erakorralised valimised)" msgstr "`RK_2023_E` (2023 special elections to the Riigikogu)" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:21 msgid "`RK_2023_E_2` (2023. a Riigikogu teised erakorralised valimised)." msgstr "`RK_2023_E_2` (other special elections to the Riigikogu in 2023)." #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:23 msgid "" "EHSi jaoks on valimise identifikaator kuni 28 ASCII-tähemärgi pikkune sõne " "ning eelnevalt kirjeldatud struktuuri põhjal EHS otsuseid ei tee." msgstr "" "For the EHS, the election identifier is a string up to 28 ASCII characters " "long, and the EHS does not make decisions based on the structure described " "above." #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:25 msgid "Valimissündmuse tüüp" msgstr "Type of election event" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:27 msgid "Valimissündmuse tüüp esitatakse koodiga:" msgstr "The type of the election event is indicated by a code:" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:29 msgid "`KOV` - Kohaliku omavalitsuse volikogu valimised" msgstr "`KOV` - Local government council elections" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:30 msgid "`EP` - Euroopa Parlamendi valimised" msgstr "`EP` - European Parliament elections" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:31 msgid "`RK` - Riigikogu valimised" msgstr "`RK` - Riigikogu elections" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:32 msgid "`RH` - Rahvahääletus." msgstr "`RH` - Referendum." ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/examples.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-03-02 12:43+0200\n" "PO-Revision-Date: 2024-03-02 13:16+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../examples.rst:3 msgid "Skeemid ja näited" msgstr "Schemes and examples" #: ../../examples.rst:7 msgid "Valimisringkondade nimekiri" msgstr "List of constituencies" #: ../../examples.rst:10 ../../examples.rst:48 ../../examples.rst:84 #: ../../examples.rst:119 ../../examples.rst:154 ../../examples.rst:189 #: ../../examples.rst:206 ../../examples.rst:217 msgid "Skeem" msgstr "Scheme" #: ../../examples.rst:17 ../../examples.rst:61 ../../examples.rst:97 #: ../../examples.rst:132 ../../examples.rst:167 msgid "Näide: KOV" msgstr "Example: KOV" #: ../../examples.rst:24 ../../examples.rst:55 ../../examples.rst:91 #: ../../examples.rst:126 ../../examples.rst:161 msgid "Näide: EP" msgstr "Example: EP" #: ../../examples.rst:31 ../../examples.rst:68 ../../examples.rst:103 #: ../../examples.rst:138 ../../examples.rst:173 msgid "Näide: RH" msgstr "Example: RH" #: ../../examples.rst:38 ../../examples.rst:74 ../../examples.rst:109 #: ../../examples.rst:144 ../../examples.rst:179 msgid "Näide: RK" msgstr "Example: RK" #: ../../examples.rst:45 msgid "Valikute nimekiri" msgstr "List of choices" #: ../../examples.rst:81 msgid "E-hääletanute nimekiri" msgstr "List of e-voters" #: ../../examples.rst:116 msgid "Tühistusnimekiri" msgstr "Revokation list" #: ../../examples.rst:151 msgid "E-hääletamise tulemus" msgstr "Result of e-voting" #: ../../examples.rst:186 msgid "E-hääletamise üldstatistika" msgstr "General statistics on e-voting" #: ../../examples.rst:196 msgid "Näide" msgstr "Example" #: ../../examples.rst:203 msgid "E-hääletamise detailstatistika" msgstr "Detailed statistics on e-voting" #: ../../examples.rst:214 msgid "E-hääletamiste nimekiri" msgstr "List of e-votes" ================================================ FILE: Documentation/public/liidesed/locales/en/LC_MESSAGES/index.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.9.1\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" #: ../../index.rst:4 msgid "IVXV registreerimisteenus" msgstr "IVXV registration service" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:1 msgid "1 Valimisringkondade nimekiri" msgstr "Valimisringkondade nimekiri" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:3 msgid "Protseduur" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:5 msgid "VIS3 edastab EHS-le teabe valimisringkondade kohta." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:7 msgid "Andmed edastatakse inim-masin-protseduuriga:" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:9 msgid "VIS peakasutaja laeb JSON faili VIS3-st alla;" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:11 msgid "" "VIS peakasutaja allkirjastab faili digitaalselt väljaspool VIS-i ja annab" " selle EHS operaatorile;" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:13 msgid "EHS operaator laeb digiallkirjastatud faili EHS-i." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:15 msgid "Fail on JSON-formaadis. Faili ei allkirjastata." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:17 msgid "" "Faili struktuur on kirjeldatud JSON schema-ga. Kirjeldus on " "kooskõlastatud EHS omanikuga." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:19 msgid "" "EHS senine liides VIS2-ga on spetsifitseeritud dokumendis \"IVXV " "protokollide kirjeldus\" (v 1.5.0, IVXV-PR-1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf](https://www.valimised.ee/sites/default/files/uploads/eh" "/IVXV-protokollid.pdf), jaotises 3.2 \"Valimisjaoskondade ja -ringkondade" " nimekiri\"." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:21 msgid "" "Valimistel, kus saavad osaleda alaliselt välisriigis elavad valijad " "kantakse nad valijate nimekirja tunnusega `FOREIGN`. Sellisel juhul peab " "valimisringkondade nimekiri sisaldama regiooni nende valijate jaoks ning " "iga ringkond peab sisaldama eraldi jaoskonda, kus nende häälte üle " "arvestust peetakse. Nii selle regiooni kui jaoskondade tunnuseks on " "fiktiivne EHAK: `0000`. Näitefailis " "[districts_RK.json](districts_RK.json) on näha nii regiooni korrektne " "lisamine kui ka välishääletajate jaoskonna korrektne lisamine igasse " "ringkonda." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:25 msgid "Edastatav fail" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:27 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:29 msgid "Faili struktuur (JSON-skeem): [districts.schema](districts.schema)" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:31 msgid "Näited (JSON):" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:33 msgid "[district_KOV.json](district_KOV.json)" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:34 msgid "[districts_EP.json](districts_EP.json)" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:35 msgid "[districts_RH.json](districts_RH.json)" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:36 msgid "[districts_RK.json](districts_RK.json)" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:38 msgid "Taustainfo" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:40 msgid "" "Kandidaate on võimalik valimisele üles seada ainult konkreetses " "valimisringkonnas. Ringkondade järgi antakse valijatele hääletamise " "valikud:" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:42 msgid "Iga valija kuulub talle määratud valimisringkonda;" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:43 msgid "" "Kõigis ühe ringkonna jaoskondades saavad valijad teha valiku vaid selle " "ringkonna valikute vahel;" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:45 msgid "" "Eesti riiklikel valimistel eristatakse kohalike omavalitsuste volikogude " "(KOV) valimisi, Riigikogu valimisi, Euroopa Parlamendi valimisi ning " "rahvahääletusi." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:47 msgid "" "KOV valimised korraldatakse vastavalt seadusele „Kohaliku omavalitsuse " "volikogu valimise seadus“. Valimine toimub kohaliku omavalitsuse " "tasandil, igal omavalitsusel on oma hääletamistulemus. Valimisringkonnad " "moodustatakse omavalitsuse tasemel vastavalt seaduses kirjeldatud " "reeglitele." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:49 msgid "" "Riigikogu valimised korraldatakse vastavalt seadusele „Riigikogu valimise" " seadus“. Valimine toimub riigi tasandil. Riik jaguneb 12 " "valimisringkonnaks. Hääletamistulemus tehakse kindlaks iga " "valimisringkonna kohta." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:51 msgid "" "Europarlamendi valimised korraldatakse vastavalt seadusele „Euroopa " "Parlamendi valimise seadus“. Valimine toimub riigi tasandil, " "hääletamistulemus on kõigile kohalikele omavalitsustele ühine. Terve riik" " on üks valimisringkond." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:53 msgid "" "Rahvahääletused korraldatakse vastavalt seadusele „Rahvahääletuse " "seadus“. Valimine toimub riigi tasandil, hääletamistulemus on kõigile " "kohalikele omavalitsustele ühine. Terve riik on üks valimisringkond." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:55 msgid "" "Erinevad valimised ei erine elektroonilise hääletamise andmevormingute ja" " protseduuride poolest. Erinevad ringkondade jaotused hallatakse VIS3 " "poolt." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:57 msgid "" "Kandidaate on võimalik valimisele üles seada ainult konkreetses " "valimisringkonnas. Valijad on jaotatud valimisringkondade vahel. Valija " "saab teha valiku ainult tema ringkonnas kandideerivate kandidaatide " "vahel." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:59 msgid "" "Kuna kohaliku omavalitsuse volikogude valimisel toimub valimine Eesti " "omavalitsuste (vallad, linnad) tasemel, siis kasutatakse elektroonilise " "hääletamise protokollistikus valimisringkondade kirjeldamisel ning " "valijate ja valikute ringkonnakuuluvuse näitamisel Eesti haldus- ja " "asustusjaotuse klassifikaatorit EHAK" msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:61 msgid "" "Näiteks: • Tallinna linna Pirita linnaosa EHAK kood on 0596; • Anija " "valla EHAK kood on 0141." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:65 msgid "" "Riigi tasemel toimuvatel valimistel pannakse ringkonna EHAK koodiks " "kokkuleppeliselt 0." msgstr "" #: ../../VIS3-EHS/1_Valimisringkondade_nimekiri/SPEC.md:67 msgid "" "Riigikogu ja europarlamendi valimistel ning rahvahääletusel moodustatakse" " nimekirjas igasse ringkonda fiktiivne üksus alaliselt välisriigis " "elavate valijate tarbeks. Selle üksuse number on 0 ning vastav EHAK kood " "on 0000." msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/VIS3-EHS/2_Valikute_nimekiri/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:1 msgid "2 Valikute nimekiri (kandidaatide nimekiri)" msgstr "Valikute nimekiri (kandidaatide nimekiri)" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:3 msgid "Protseduur" msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:5 msgid "" "VIS3 edastab EHS-le andmed registreeritud kandidaatide (valimistel) või " "vastusevariantide (rahvahääletusel) kohta." msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:7 msgid "Andmed edastatakse inim-masin-protseduuriga:" msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:9 msgid "" "VIS peakasutaja laeb JSON faili VIS3-st alla; Kasutaja peab valima " "aktiivsete valimissündmuste seast soovitud sündmuse, mille kohta infot " "alla laadida. Valimissündmus on aktiivne, kui tema staatus pole `closed` " "ega `deleted`." msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:10 msgid "" "VIS peakasutaja allkirjastab faili digitaalselt väljaspool VIS-i ja annab" " selle EHS operaatorile;" msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:11 msgid "EHS operaator laeb digiallkirjastatud faili EHS-i." msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:13 msgid "" "Fail on JSON-formaadis (näidis lisatud tööülesandele). Faili ei " "allkirjastata." msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:15 msgid "Edastatav fail" msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:17 msgid "" "Aluseks on EHS senine liides VIS2-ga, mis on spetsifitseeritud dokumendis" " \"IVXV protokollide kirjeldus\" (v 1.5.0, IVXV-PR-1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf](https://www.valimised.ee/sites/default/files/uploads/eh" "/IVXV-protokollid.pdf), jaotises \"Valikute nimekiri\" (jaotis 3.4)." msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:19 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:21 msgid "Faili struktuur (JSON-skeem): [choices.schema](choices.schema)" msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:23 msgid "Faili näited (JSON):" msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:25 msgid "[choices_KOV.json](choices_KOV.json)" msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:26 msgid "[choices_EP.json](choices_EP.json)" msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:27 msgid "[choices_RK.json](choices_RK.json)" msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:29 msgid "Taustainfo" msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:31 msgid "" "Valikute nimekiri sisaldab andmeid kandidaatide (valimistel) või " "vastusevariantide (rahvahääletusel) kohta. Valimiste korral on lisaks " "kandidaadi andmetele nimekirjas ka tema erakonna või valimisliidu nimi, " "mille nimekirjas ta kandideerib." msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:34 msgid "" "Valijale elektroonilise hääletamise käigus nähtavaid valimiste vahelisi " "süsteemseid erinevusi on kaks:" msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:36 msgid "" "Rahvahääletusel ei valita erakondadesse kuuluvate kandidaatide vahel vaid" " vastatakse „JAH“/“EI“ rahvahääletuse küsimusele;" msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:38 msgid "" "Riigikogu, KOV ja Euroopa Parlamendi valimistel antakse hääl ühele " "kandidaadile, kes võib, aga ei pruugi kuuluda poliitilise ühenduse " "nimekirja." msgstr "" #: ../../VIS3-EHS/2_Valikute_nimekiri/SPEC.md:40 msgid "" "Protokollistik kodeerib valija võimalikud valikud ringkonnas kuni " "11-kohalise arvväärtusena, mis valikute nimekirjas kodeeritakse koos " "ringkonna EHAK-koodiga. Valijale tohivad kättesaadavad olla ainult tema " "ringkonnakohased valikud. Valijarakendus peab seda omadust tagama ning " "hääletamistulemust arvutav rakendus kontrollima." msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/VIS3-EHS/3_Valijate_nimekiri/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:1 msgid "3 Valijate nimekiri EHS-le" msgstr "Valijate nimekiri EHS-le" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:3 msgid "1. Annotatsioon" msgstr "Annotatsioon" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:5 msgid "" "Spetsifikatsioon määratleb Valimiste infosüsteemi (VIS3) ja e-hääletamise" " süsteemi (EHS) vahelise liidese, mille kaudu VIS3 edastab EHS-le " "valijate algnimekirja ja valijate nimekirja muudatusi ehk " "muudatusnimekirju." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:9 msgid "" "Spetsifikatsioon on avalik. Spetsifikatsioon ei käsitle VIS3 ega EHS " "konfidentsiaalset siseehitust ega liidese konfidentsiaalseid elemente." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:12 msgid "" "Käesolevat spetsifikatsiooni tuleb kasutada koos VIS3 EHS API OpenAPI " "spetsifikatsiooniga (asub käesolevas repos, failis `vis-ehs-api.yaml`)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:14 msgid "2. Sõnumivahetus nimekirjade edastamiseks" msgstr "Sõnumivahetus nimekirjade edastamiseks" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:16 msgid "" "Valijate nimekirja põhjal tuvastab EHS isiku hääleõiguse ja " "ringkonnakuuluvuse. Valijate nimekiri võib hääletamisperioodi jooksul " "muutuda, sellest tulenevalt võib valija saada hääleõiguse, jääda oma " "hääleõigusest ilma või saada hääleõiguse senisest erinevas ringkonnas. " "EHS peab nende muutustega arvestama. Muudatused saab EHS VIS3 vahendusel " "muudatusnimekirjadena." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:22 msgid "" "Spetsifikatsioonis defineeritud liidese vahendusel suhtlevad vahetult EHS" " ja VIS3:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:25 msgid "" "VIS3 liidestub Rahvastikuregistri andmekoguga ning hangib seal nii " "valijate algnimekirja kui ka muudatusnimekirjad." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:27 msgid "EHS esitab VIS3-le päringuid muudatusnimekirjade saamiseks." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:29 msgid "Kaudselt on liidesega seotud:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:31 msgid "Rahvastikuregister, kus toimub nimekirjade haldamine;" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:32 msgid "" "VIS3 ja EHS operaatorid, kes vahetavad taustakanalis algnimekirja ning " "suhtlevad võimalike tõrgete lahendamisel;" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:34 msgid "Audiitor, kes veendub et EHS on VIS3 poolt tarnitud nimekirjad rakendanud;" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:35 msgid "" "EHS vallasrežiimis töötlemisrakendus, mis verifitseerib EHS sidusrežiimi " "komponentide poolt üle antud urni." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:38 msgid "2.1 Ettevalmistused nimekirjade edastamiseks" msgstr "Ettevalmistused nimekirjade edastamiseks" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:40 msgid "![Joonis 1: Sõnumivahetuse ettevalmistamine](model/list_prepare.png)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:40 msgid "Joonis 1: Sõnumivahetuse ettevalmistamine" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:42 msgid "" "Valijate alg- ja muudatusnimekirjade vahetamisele eelnevalt tuleb " "vahetada nimekirjadele juurdepääsuks ja nimekirjade autentsuse " "kontrolliks vajalikud võtmed ja sertifikaadid (sammud 1-5)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:46 msgid "2.2 Valijate algnimekirja edastamine" msgstr "Valijate algnimekirja edastamine" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:48 msgid "![Joonis 2: Algnimekirja edastamine](model/list_initial.png)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:48 msgid "Joonis 2: Algnimekirja edastamine" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:50 msgid "" "Valijate algnimekiri järjekorranumbriga 0 laetakse EHSi haldusliidese " "veebiliidesest. Valijate algnimekirja laadimine on eelduseks " "muudatusnimekirjade edasiseks automaatseks laadimiseks." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:54 msgid "Valijate algnimekirja laadimine toimub järgmistes etappides:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:56 msgid "" "VIS3 kasutab Rahvastikuregistri X-tee teenust valijate algnimekirja " "laadimiseks (sammud 1-3)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:58 msgid "" "VIS3 peakasutaja pärib allkirjastatud algnimekirja VIS3 teenusest, ning " "allkirjastab algnimekirja täiendavalt ID-kaardiga (sammud 4-6)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:60 msgid "" "VIS3 peakasutaja edastab allkirjastatud algnimekirja EHS operaatorile " "(samm 7)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:62 msgid "" "EHS operaator laeb digitaalselt allkirjastatud algnimekirja EHSi, kus see" " rakendatakse (sammud 8-9)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:65 msgid "2.3 Valijate muudatusnimekirja edastamine" msgstr "Valijate muudatusnimekirja edastamine" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:67 msgid "![Joonis 3: Muudatusnimekirja edastamine](model/list_changeset.png)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:67 msgid "Joonis 3: Muudatusnimekirja edastamine" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:69 msgid "" "Valijate nimekirja muudatusnimekirja laadimise algatab EHS. " "Muudatusnimekirjad on järjestatud, nii EHS kui ka VIS3 peavad arvet, " "milline on viimane loodud muudatusnimekiri." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:73 msgid "" "EHS algatab uue muudatusnimekirja laadimise pöördudes uue " "järjekorranumbriga VIS3 vastava otspunkti poole. EHS võib varasemaid " "muudatusnimekirju uuesti pärida, kasutades varasemat järjekorranumbrit." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:77 msgid "" "VIS3 saab muudatused Rahvastikuregistri X-tee teenusest. VIS3 poolne " "muudatuste hankimine on EHSile muudatuste esitamisest sõltumatu " "paralleelprotsess. See tähendab, et üks EHSile minev muudatusnimekiri " "võib sisaldada mitut Rahvastikuregistrist tulnud muudatust." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:82 msgid "Muudatusnimekirjade edastamine EHSi käib järgmiselt:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:84 msgid "EHS esitab päringu muudatusnimekirja saamiseks (samm 1)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:85 msgid "Kui muudatusi ei ole, siis ei ole ka muudatusnimekirja (samm 2)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:86 msgid "" "EHS kordab mingi aja möödudes päringut muudatusnimekirja saamiseks (samm " "3)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:87 msgid "" "VIS3 edastab vahepeal saabunud muudatused EHSile ning EHS rakendab need " "edukalt (sammud 4-5)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:89 msgid "" "Nii VIS3 kui EHS suurendavad muudatusnimekirjade järjekorranumbrit ning " "mõne aja möödudes edastatakse uus muudatusnimekiri (sammud 6-8)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:92 #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:96 msgid "**Märkused**" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:93 msgid "" "Kui järjekorras järgmise muudatusnimekirja pärimisel muudatuskirjed " "puuduvad vastatakse HTTP staatusega `404` (not found)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:97 msgid "" "Kui päritakse muudatusnimekirja suurema järjenumbriga, kui tegelik " "järgmise muudatusnimekirja järjenumber, vastatakse HTTP staatusega `409` " "(conflict)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:100 msgid "2.4 Veajuhtumite lahendamine" msgstr "Veajuhtumite lahendamine" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:102 msgid "![Joonis 4: Veajuhtumite lahendamine](model/list_errors.png)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:102 msgid "Joonis 4: Veajuhtumite lahendamine" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:104 msgid "" "Muudatusnimekirjade edastamisel ei saa välistada vigu. Olenevalt vea " "iseloomust on võimalik taaste, keerulisematel juhtudel tuleb mõni " "vigaseks osutunud nimekiri vahele jätta. Veajuhtumi menetlemise ajal " "muudatusnimekirju ei edastata." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:109 msgid "Veajuhtumite lahendamine toimub järgmiselt:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:111 msgid "" "EHS ja VIS3 käivitavad protokolli muudatusnimekirja edastamiseks (sammud " "1-3)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:113 msgid "" "EHS tunnistab nimekirja vigaseks ning teavitab sellest operaatorit (samm " "4)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:114 msgid "" "Probleemi analüüsides tuvastatakse EHS-poolne tõrge, mida on võimalik " "lahendada. Tõrge lahendatakse ning EHS ja VIS3 kordavad edukalt " "protokolli (sammud 5-7)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:117 msgid "" "EHS ja VIS3 käivitavad protokolli muudatusnimekirja edastamiseks (sammud " "8-10)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:119 msgid "" "EHS tunnistab nimekirja vigaseks ning teavitab sellest operaatorit (samm " "11)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:121 msgid "" "Probleemi analüüsides tuvastatakse sisuline probleem nimekirjas. Vigast " "nimekirja ei muudeta, luuakse uus korrektne nimekiri. EHS operaator laeb " "digitaalselt allkirjastatud korralduse vigase nimekirja vahele jätmiseks " "(samm 12)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:125 msgid "" "EHS ja VIS3 suurendavad järjekorranumbrit ning käivitavad protokolli " "muudatusnimekirja edastamiseks (sammud 13-15)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:127 msgid "" "EHS ja VIS3 suurendavad järjekorranumbrit ning käivitavad protokolli " "muudatusnimekirja edastamiseks (sammud 16-17). VIS3 vastab HTTP " "staatusega 409 (conflict)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:130 msgid "" "EHS tuvastab vale järjenumbriga nimekirja laadimise ning teavitab sellest" " operaatorit (samm 18)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:132 msgid "" "Tõrge lahendatakse ning EHS ja VIS3 kordavad edukalt protokolli (sammud " "19-21)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:134 msgid "2.5 Nimekirjade loendi edastamine" msgstr "Nimekirjade loendi edastamine" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:136 msgid "3. Nimekirja andmevorming" msgstr "Nimekirja andmevorming" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:138 msgid "" "Nimekirja andmevorming on sama nii valijate algnimekirja kui " "muudatusnimekirjade jaoks." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:141 msgid "" "Nimekiri esitatakse UTF-8-NOBOM vormingus tekstifailina. " "Andmestruktuuride eraldajaks kasutatakse reavahetusmärki `LF` (ASCII-kood" " `0x0A`). Andmestruktuuride väljade eraldajaks kasutatakse tabeldusmärki " "`TAB` (ASCII-kood `0x09`)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:146 msgid "Nimekiri koosneb päiseridadest ja kirjetest." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:148 msgid "Päiseridade sisu on järgmine:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:150 msgid "" "`version` - andmestruktuuri versiooninumber, mille pikkus on piiratud 2 " "tähemärgiga. Spetsifikatsioonile vastava nimekirja korral on selle välja " "väärtus 2." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:153 msgid "" "`election_identifier` - valimissündmuse identifikaator, mille pikkus on " "piiratud 28 tähemärgiga ASCII kooditabelist. Nimekirja rakendamine toimub" " ainult vastava identifikaatoriga valimissündmuse kontekstis. " "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:156 msgid "" "`changeset` - nimekirja järjekorranumber. Rangelt kasvav number (0, 1, 2," " ...), mis defineerib nimekirjade rakendamise järjekorra. Algnimekirja " "järjekorranumbriks on 0." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:159 msgid "" "`period` - nimekirjas kajastuvate muudatuste ajavahemik. Esimene väli " "sisaldab perioodi algust, teine lõppu. Algnimekirja puhul on perioodi " "algus ja lõpu väärtused võrdsed. Väli on informatiivne." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:163 msgid "Kirje koosneb väljadest, mille sisu on järgmine:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:165 msgid "" "`person_code` - isikukood on valija unikaalne identifikaator, mille " "alusel EHS tuvastab isiku hääleõiguse ja ringkonnakuuluvuse." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:167 msgid "" "`voter_name` - valija nimi, informaalne väli, otsuste tegemisel ei " "kasutata." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:168 msgid "" "`action` - kirjega seotud tegevus. `lisamine` tähendab uue valija " "lisamist ja `kustutamine` olemasoleva valija eemaldamist." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:170 msgid "" "`kov_code` - haldusüksus, kuhu valija kuulub. Haldusüksuse " "identifitseerimiseks kasutatakse kohaliku omavalitsuse EHAK-koodi, " "Tallinna korral linnaosa EHAK-koodi, alaliselt välisriigis elava valija " "korral kasutatakse väärtust `FOREIGN`." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:174 msgid "" "`electoral_district_id` - valimisringkonna number identifitseerib " "valimisringkonna, kus valija hääletab. KOV valimiste korral kehtib " "identifikaator haldusüksuse sees. RK, EP ja RH valimiste korral on " "identifikaator haldusüksuste ülene." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:179 msgid "" "Välju `voter_name`, `kov_code` ja `electoral_district_id` kasutatakse " "ainult lisamiskirjes (`action` väärtus `lisamine`)." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:182 msgid "Andmevormingu formaalne kirjeldus Backus-Naur notatsioonis:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:212 msgid "3.1 Nimekirja tõlgendamine" msgstr "Nimekirja tõlgendamine" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:214 msgid "Nimekirju töötlev rakendus lähtub järgmistest reeglitest:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:216 msgid "Nimekiri rakendatakse tervikuna." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:217 msgid "" "Nimekirja rakendamisele eelnevad vormingu ja kooskõlalisuse kontrollid, " "vigaseid nimekirju ei rakendata." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:219 msgid "Rakendus kontrollib nimekirja versiooni." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:220 msgid "Rakendus kontrollib valimissündmuse identifikaatorit." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:221 msgid "Rakendus kontrollib nimekirja järjekorranumbrit." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:222 msgid "" "Rakendus kontrollib nimekirja kõigi kirjete kooskõlalisust oma " "andmebaasiga." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:223 msgid "Kooskõlalisust kontrollitakse kirjete esinemisjärjekorras." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:224 msgid "" "Kui tegevus on `lisamine`, siis ei tohi vastava isikukoodiga kirjet " "rakenduse andmebaasis olla." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:226 msgid "" "Kui tegevus on `kustutamine`, siis rakendus kontrollib, kas vastava " "isikukoodiga kirje on rakenduse andmebaasis olemas. Kui ei ole, siis " "rakendus logib veateate ja jätkab järgmiste kirjete töötlust." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:229 msgid "" "Kui valijaga soetud andmeid on vaja muuta, näiteks valija liigub ühest " "haldusüksusest või valimisringkonnast teise, siis kantakse valijate " "nimekirja muudatuste hulka üks kustutamise kirje, millega valija oma " "eelmisest üksusest kustutatakse ja üks lisamise kirje, millega valija " "uues üksuses valijate nimekirja lisatakse. Ka kõik teised muudatused " "valija andmetes - näiteks nimemuutus - toimuvad läbi vana kirje " "kustutamise ja uue lisamise." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:236 msgid "" "Valijate algnimekirjas on ainult lisamiskirjed, iga valija kohta " "maksimaalselt üks kirje. Muudatusnimekirjas peavad ühe valija kohta " "käivad kirjed olema nimekirjas loogilises järjestuses ning liiasuseta. " "Ehk kustutamine enne lisamist ning maksimaalselt üks kustutamise-lisamise" " paar." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:241 msgid "" "On võimalik, et valimise ajal muutub valija isikukood. Sellisel juhul " "lisatakse nimekirja vana isikukoodiga kustutamise kirje ning uue " "isikukoodiga lisamise kirje. Täiendav korduvhääletamise kontroll ei ole " "selle liidese skoobis ja teostakse VIS3 poolt eraldi." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:247 msgid "3.2 Näited nimekirjadest" msgstr "Näited nimekirjadest" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:249 msgid "Valijate algnimekiri, 0." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:267 msgid "Muudatusnimekiri, 1:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:269 msgid "Muutub valija 20000000002 haldusüksus." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:270 msgid "Valija 30000000003 kaotab hääleõiguse." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:271 msgid "Valijale 11000000011 antakse hääleõigus." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:285 msgid "Muudatusnimekiri, 2:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:287 msgid "Muutub valija 20000000002 nimi." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:288 msgid "Valija 60000000006 kaotab hääleõiguse." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:300 msgid "Muudatusnimekiri, 3:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:302 msgid "Muutub valija 20000000003->10000000003 isikukood koos nimega." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:303 msgid "Valija 60000000006 saab hääleõiguse." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:315 msgid "4. Nimekirja signeerimine" msgstr "Nimekirja signeerimine" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:317 msgid "" "Nii algnimekirjaga kui muudatusnimekirjadega kaasatakse allkirjafail " "(FIPS 186-4), mille moodustab andmeallikas, arvutades algsest valijate " "nimekirjast SHA256-räsi ning allkirjastades selle räsi ECDSA võtmega " "(kasutame P-256 kõverat). Andmeallika poolt genereeritud avalik võti " "tehakse taustakanalis kättesaadavaks EHSile ning selle võtme alusel " "kontrollitakse EHS komponentides valijate nimekirjade terviklust." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:324 msgid "" "Võtmete genereerimiseks, signeerimiseks ning verifitseerimiseks võib " "kasutada tööriista OpenSSL:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:327 msgid "" "Võtme genereerimine: `openssl ecparam -name prime256v1 -genkey -noout " "-out private.key.pem`" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:329 msgid "" "Avaliku võtme eraldamine: `openssl ec -in private.key.pem -pubout -out " "public.key.pem`" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:331 msgid "" "Andmefaili signeerimine: `openssl dgst -sha256 -sign private.key.pem -out" " data.sig data.txt`" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:333 msgid "" "Signatuuri verifitseerimine: `openssl dgst -sha256 -verify public.key.pem" " -signature data.sig data.txt`" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:336 msgid "" "Näide antud meetodi kasutamiseks golang keeles on leitav repositooriumis " "[DigiSign](https://github.com/e-gov/DigiSign)" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:339 msgid "5. Transpordiprotokoll" msgstr "Transpordiprotokoll" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:341 msgid "VIS3-EHS käesolev masinliides koosneb kahest API otspunktist." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:343 msgid "" "API otspunkt `ehs-voters-changeset` konkreetse muudatusnimekirja " "laadimiseks VIS3-st" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:345 msgid "" "API otspunkt `ehs-list-election-changesets` ülevaate saamiseks " "avalikustatud nimekirjadest" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:348 msgid "" "Transpordiprotokoll on HTTPS, kuna volitamata ligipääs nimekirjadele " "tuleb tõkestada kasutatakse mõlemapoolselt autenditud TLS ühendusi." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:351 msgid "5.1 `ehs-voters-changeset`" msgstr "`ehs-voters-changeset`" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:353 msgid "" "HTTP meetod on GET. Päringu tegemisel tuleb kasutada kohustuslikke " "parameetreid `changeset` ja `election_identifier`, kus" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:356 msgid "`changeset` on muudatusnimekirja `integer` tüüpi järjekorranumber." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:357 #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:379 msgid "`election_identifier` on `string` tüüpi valimissündmuse identifikaator." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:359 msgid "" "Kui EHS teeb API otspunkti GET päringu, siis juhul kui vastava " "identifikaatori ja järjekorranumbriga nimekiri eksisteerib, vastab VIS3 " "`application/octet-stream` tüüpi baidijadaga, mis esitab kahest failist " "koosnevat ZIP konteinerit:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:364 msgid "nimekirjafail nimega `-voters-.utf`" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:366 msgid "signatuurifail nimega `election_identifier<>-voters-.sig`" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:369 #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:414 msgid "Sellise vastuse korral on HTTP status 200." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:371 msgid "" "Juhul kui vastava järjekorranumbriga muudatusnimekirja veel ei eksisteeri" " antakse vastuses HTTP status 404." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:374 msgid "5.1 `ehs-list-election-changesets`" msgstr "`ehs-list-election-changesets`" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:376 msgid "" "HTTP meetod on GET. Päringu tegemisel tuleb kasutada kohustuslikku " "parameetrit `election_identifier`:" msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:381 msgid "" "Kui EHS teeb API otspunkti, siis juhul kui vastava identifikaatoriga " "valimine eksisteerib, vastab VIS3 `application/json` tüüpi baidijadaga, " "mis sisaldab endas JSON vormingus viiteid kõigile väljastatud " "muudatusnimekirjadele." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:385 msgid "" "MÄRKUS. Viidetes tarnitavad URL-id ei ole õiged ja seetõttu " "mittekasutatavad. EHS peab konkreetse muudatuste nimekirja poole " "pöördumise URL-i koostama vastavalt VIS3 EHS API OpenAPI vormingus " "spetsifikatsioonile (asub käesolevas repos, failis `vis3-ehs-api.yaml`). " "VIS3 edasisestes versioonides eemaldame viidetest URL-id. 20.07.2021." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:387 msgid "" "MÄRKUS. Viidetes tarnitavate URL-de käsitlust muudetud: elemendis `url` " "tarnitakse mitte täis-URL, vaid ainult _path_ ja -query_ osa." msgstr "" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:416 msgid "6. Näited" msgstr "Näited" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:418 msgid "7. Viited" msgstr "Viited" #: ../../VIS3-EHS/3_Valijate_nimekiri/SPEC.md:420 msgid "" "[\"DigiSign\" - lihtne protokoll edastatavate failide allkirjastamiseks, " "koos teostusnäitega](https://github.com/e-gov/DigiSign)" msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:1 msgid "E-hääletanute nimekiri" msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:3 msgid "Protseduur" msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:5 msgid "" "E-hääletanute nimekiri on pärast e-hääletamise lõppu EHS poolt " "genereeritav ja väljastatav nimekiri e-hääletanud isikutest. " "E-hääletanute nimekiri loetakse sisse VIS3-e (moodul NIM)." msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:7 msgid "E-hääletanute nimekiri edastakse inim-masin-protseduuriga:" msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:9 msgid "EHS operaator laeb JSON-faili EHS-st alla;" msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:11 msgid "" "EHS operaator allkirjastab faili digitaalselt väljaspool EHS-i ja annab " "selle VIS peakasutajale;" msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:13 msgid "VIS peakasutaja laeb digikonteinerist välja võetud faili VIS3-i." msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:15 msgid "Fail on JSON-formaadis. Faili näidised on tööülesandes." msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:17 msgid "Faili struktuur on kirjeldatud JSON-skeemiga." msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:19 msgid "Edastatav fail" msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:21 msgid "" "Aluseks on EHS senine liides VIS2-ga, mis on spetsifitseeritud dokumendis" " \"IVXV protokollide kirjeldus\" (v 1.5.0, IVXV-PR-1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf](https://www.valimised.ee/sites/default/files/uploads/eh" "/IVXV-protokollid.pdf), jaotises \"E-hääletanute nimekiri\" (jaotis 9.2)." msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:23 msgid "Faili struktuur (JSON-skeem): [onlinevoters.schema](onlinevoters.schema)" msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:25 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:27 msgid "Faili näited (JSON):" msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:29 msgid "[onlinevoters_EP.json](onlinevoters_EP.json)" msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:30 msgid "[onlinevoters_KOV.json](onlinevoters_KOV.json)" msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:31 msgid "[onlinevoters_RH.json](onlinevoters_RH.json)" msgstr "" #: ../../VIS3-EHS/4_e_haaletanute_nimekiri/SPEC.md:32 msgid "[onlinevoters_RK.json](onlinevoters_RK.json)" msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/VIS3-EHS/5_Tyhistusnimekiri/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:1 msgid "5 Tühistus- ja ennistusnimekiri" msgstr "Tühistus- ja ennistusnimekiri" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:3 msgid "" "VIS3 edastab EHS-le tühistus- ja ennistusnimekirja (lühidalt - " "tühistusnimekiri)." msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:5 msgid "" "Tühistusnimekiri sisaldab andmeid isikute kohta, kelle e-hääl tuleb " "tühistada (on paberhääletanud ja sellest tulenevalt ei lähe e-hääl " "arvesse valimistulemuste kokkulugemisel) või ennistada (s.t. tühistatakse" " eelnev tühistamine ning häälte uuesti üle lugemisel võetakse ennistatud " "e-hääl arvesse)." msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:7 msgid "Fail on JSON-formaadis." msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:9 msgid "Protseduur" msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:11 msgid "Tühistusnimekiri edastakse inim-masin-protseduuriga:" msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:13 msgid "EHS operaator laeb JSON-faili EHS-st alla;" msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:15 msgid "" "EHS operaator allkirjastab faili digitaalselt väljaspool EHS-i ja annab " "selle VIS peakasutajale;" msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:17 msgid "VIS peakasutaja laeb digikonteinerist välja võetud faili VIS3-i." msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:19 msgid "Edastatav fail" msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:21 msgid "" "Aluseks on EHS senine liides VIS2-ga, mis on spetsifitseeritud dokumendis" " \"IVXV protokollide kirjeldus\" (v 1.5.0, IVXV-PR-1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf](https://www.valimised.ee/sites/default/files/uploads/eh" "/IVXV-protokollid.pdf), jaotises \"Tühistus- ja ennistusnimekiri\" " "(jaotis 9.1)." msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:23 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:25 msgid "Faili struktuur (JSON-skeem): [revoke.schema](revoke.schema)" msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:27 msgid "Faili näited (JSON):" msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:29 msgid "[revoke_EP.json](revoke_EP.json)" msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:30 msgid "[revoke_KOV.json](revoke_KOV.json)" msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:31 msgid "[revoke_RH.json](revoke_RH.json)" msgstr "" #: ../../VIS3-EHS/5_Tyhistusnimekiri/SPEC.md:32 msgid "[revoke_RK.json](revoke_RK.json)" msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/VIS3-EHS/6_e_haaletamise_tulemus/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:1 msgid "E-hääletamise tulemus" msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:3 msgid "" "E-hääletamise lõppedes genereerib EHS e-hääletamise tulemuste faili " "(hääletamistulemuse fail). Fail laetakse VIS3-e (valimistulemuse " "moodulisse TUL)." msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:5 msgid "Protseduur" msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:7 msgid "Fail edastatakse inim-masin-protseduuriga:" msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:9 msgid "EHS operaator laeb JSON-faili EHS-st alla;" msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:11 msgid "" "EHS operaator allkirjastab faili digitaalselt väljaspool EHS-i ja annab " "selle VIS peakasutajale;" msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:13 msgid "VIS peakasutaja laeb digikonteinerist välja võetud faili VIS3-i." msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:15 msgid "Fail on JSON-formaadis." msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:17 msgid "Edastatav fail" msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:19 msgid "" "Aluseks on EHS senine liides VIS2-ga, mis on spetsifitseeritud dokumendis" " \"IVXV protokollide kirjeldus\" (v 1.5.0, IVXV-PR-1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf](https://www.valimised.ee/sites/default/files/uploads/eh" "/IVXV-protokollid.pdf), jaotises \"E-hääletamise tulemus\" (jaotis 9.3)." msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:21 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:23 msgid "Faili struktuur (JSON-skeem): [results.schema](results.schema)" msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:25 msgid "Faili näited (JSON):" msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:27 msgid "[results_EP.json](results_EP.json)" msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:28 msgid "[results_KOV.json](results_KOV.json)" msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:29 msgid "[results_RH.json](results_RH.json)" msgstr "" #: ../../VIS3-EHS/6_e_haaletamise_tulemus/SPEC.md:30 msgid "[results_RK.json](results_RK.json)" msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:1 msgid "7 E-hääletamisest osavõtu üldstatistika" msgstr "E-hääletamisest osavõtu üldstatistika" #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:3 msgid "" "EHS annab lühikese perioodiga (nt 15 min) VIS3-le andmeid kui palju " "valijaid on e-hääletanud." msgstr "" #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:5 msgid "EHS teeb seda HTTPS päringutega VIS3 poolt pakutava otspunkti vastu." msgstr "" #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:7 msgid "Päringu vastuses tagastatav fail:" msgstr "" #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:9 msgid "JSON-skeem: [online-voters-total.schema](online-voters-total.schema)" msgstr "" #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:11 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" #: ../../VIS3-EHS/7_e_haaletamise_yldstatistika/SPEC.md:13 msgid "Näide (JSON): [online-voters-total.json](online-voters-total.json)" msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:1 msgid "8 E-hääletamisest osavõtu detailne statistika" msgstr "E-hääletamisest osavõtu detailne statistika" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:3 msgid "" "E-hääletamise lõppedes annab EHS VIS3-le e-hääletamisest osavõtu detailse" " statistika." msgstr "" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:5 msgid "" "E-hääletamisest osavõtu statistikat kuvatakse valimiste veebilehel, " "samuti edastatakse masintöödeldaval kujul meediaorganisatsioonidele ja " "lõpuks publitseeritakse avaandmetena." msgstr "" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:7 msgid "Protseduur" msgstr "" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:9 msgid "EHS operaator laeb faili alla." msgstr "" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:11 msgid "EHS operaator edastab faili VIS3 peakasutajale." msgstr "" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:13 msgid "VIS3 peakasutaja laeb faili VIS3-e üles." msgstr "" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:15 msgid "Faili edastatakse eelhääletamise ajal, kord päevas." msgstr "" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:17 msgid "Edastatav fail" msgstr "" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:19 msgid "JSON-skeem: [online-voters-counties.schema](online-voters-counties.schema)" msgstr "" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:21 msgid "" "Valimissündmuse identifikaator peab vastama formaadile [Valimissündmuse " "identifikaator](../valimissündmuse_identifikaator.md)." msgstr "" #: ../../VIS3-EHS/8_e_haaletamise_detailstatistika/SPEC.md:23 msgid "Näide (JSON): [online-voters-counties.json](online-voters-counties.json)" msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:1 msgid "E-hääletamiste nimekiri" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:3 msgid "kavand v0.4" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:5 msgid "Muutelugu" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:7 msgid "Eemaldatud sõna \"jooksev\" / Priit Parmakson, 23.11.2022" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:8 msgid "" "Lisatud OpenAPI kirjelduse publitseerimise teave. / Priit Parmakson, " "13.12.2022" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:9 msgid "" "Täpsustatud e-hääletamiste väljanäitamist VIS3-s. / Priit Parmakson, " "15.11.2022" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:10 msgid "Lisatud jõudluskaalutlused. / Priit Parmakson, 01.11.2022" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:11 msgid "" "Asendatud \"e-hääletanu\" -> \"e-hääletamine\". Põhjus: inimene võib " "e-hääletada mitu korda (ümberhääletamine); vastavalt korrigeeritud JSON " "väljanimesid \"evotersbatch\" -> \"evotingsbatch\". / Priit Parmakson, " "01.09.2022" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:12 msgid "" "Eemaldatud: hääletamise kuupäeva/aja edastamine. Põhjus: turvakaalutlus " "(häälemüügi takistamine). / Priit Parmakson, 01.09.2022 (Sven Heibergiga " "arutelu alusel)" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:13 msgid "" "Lisatud: 1) ärivajaduse täpsustus; 2) e-hääletamise fakti aja edastamine;" " 3) edastuse kontroll ja vajadusel täiendamine või parandamine lõpliku " "faili abil. / Priit Parmakson, 04.05.2022" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:14 msgid "Arutelu - RVT ja RIA inimesed, 04.05.2022" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:15 msgid "" "\"E-hääletanute jooksev nimekiri\", kavand v0.2. / Priit Parmakson, " "02.05.2022" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:16 msgid "Arutelu: X-tee kasutamine, JSON - Tarmo Hanga, Priit Parmakson, apr 2022" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:17 msgid "\"EHS- VIS3 liidestus\" (kavand) - Indrek Leesi, apr 2022" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:19 msgid "Ülevaade" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:21 msgid "" "Käesolev spetsifikatsioon määratleb protokolli e-hääletamiste nimekirja " "edastamiseks e-hääletamise süsteemist (edaspidi - EHS) Valimiste " "infosüsteemi (edaspidi - VIS3)." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:23 msgid "" "Varasematel valimistel (k.a KOV 2021) on peale hääletamise lõppu, " "valimispäeval edastatud EHS-st VIS3-le e-hääletanute nimekiri (edaspidi -" " e-hääletanute lõplik nimekiri). See edastus on spetsifitseeritud: " "[E-hääletanute " "nimekiri](https://github.com/e-gov/VIS3-EHS/blob/main/4_e_haaletanute_nimekiri/SPEC.md)." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:25 msgid "" "Siiski on vajadus VIS3-s saada teavet, kas valija on e-hääletanud, juba " "enne ülalnimetatud lõplikku edastust. Valija, kes on e-hääletanud, võib " "tulla eelhääletamise perioodil valimisjaoskonda ja soovida paberil " "hääletada. Valimisjaoskonna töötajal oleks hea omada võimalust VIS3-st " "vaadata, kas valija on e-hääletanud. Seda teavet saab muuhulgas kasutada " "valija hoiatamiseks, et paberhääletamisega tema e-hääletamine tühistub." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:27 msgid "E-hääletamiste nimekiri edastatakse EHS-st VIS3-e X-tee teenusega." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:29 msgid "" "Teenust pakub EHS. VIS3 pöördub regulaarselt teenuse poole. EHS edastab " "e-hääletamiste andmete paki. VIS3 saab paki ja salvestab andmed VIS3 " "andmebaasi." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:31 msgid "Sünkroonimiseks kasutatakse e-hääletamiste nummerdamist." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:33 msgid "Kaalutlused" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:35 msgid "" "Teenus on arendatud X-tee REST võimalusi kasutades, vastavalt X-tee REST " "sõnumiprotokollile ([X-Road: Message Protocol for " "REST](https://www.x-tee.ee/docs/live/xroad/pr-rest_x-" "road_message_protocol_for_rest.html)). Andmed väljastatakse JSON-" "vormingus." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:37 msgid "" "X-teed on otstarbekas kasutada, sest kuigi VIS3 ja EHS võivad olla " "käitatud samas taristus, on ikkagi vaja tagada usaldus, logimine ja " "paindlikkus - omadused, mille tagamine X-tee kasutamisega kokkuvõttes " "tõenäoliselt ei saaks olema ei lihtsam ega odavam." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:39 msgid "" "Protokollis on arvesse võetud Rahvastikuregistri ja VIS3 vaheliste X-tee " "teenuste kasutamise kogemust (REST sõnumiprotokoll, JSON, OpenAPI)." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:41 msgid "" "Erilist tähelepanu on pööratud andmete re-sünkroonimise võimalusele " "tõrgete korral. Selleks on pakkide pärimine kavandatud idenmpotentsena." msgstr "" "Erilist tähelepanu on pööratud andmete re-sünkroonimise võimalusele " "tõrgete korral. Selleks on pakkide pärimine kavandatud idempotentsena." #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:43 msgid "" "E-hääletanute nimekirja \"peegeldamiseks\" EHS-st VIS3-e võiks " "põhimõtteliselt kasutada ka mõnda standardset sünkroonimisprotokolli (nt " "Git, Rsync vms, vt \\[1], \\[2], \\[3]). Kuna vajadus on suhteliselt " "lihtne, siis seda ei ole tehtud." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:45 msgid "" "Jõudluskaalutlused: E-hääletamise jooksvat nimekirja edastatakse " "e-hääletamise perioodil (6 päeva). E-hääletamise fakte edastatakse kokku " "u 300 000. E-hääletamise perioodi esimesel tunnil võib oodata u 5000 " "e-hääletamist; perioodi viimasel tunnil u 10 000 e-hääletamist." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:47 msgid "E-hääletamiste järjenumbrid" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:49 msgid "" "Tagamaks, et e-hääletamiste nimekiri kantakse EHS-st VIS3-e õigeaegselt " "ja täielikult, kasutatakse järjenumbreid. EHS omistab igale " "e-hääletamisele järjenumbri (ingl Sequence Number)." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:51 msgid "" "Järjenumber on naturaalarv, alates ühest. Väärtus `0` tähistab olukorda, " "kus e-hääletamisi veel ei ole toimunud." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:53 msgid "Igas valimissündmuses on oma numeratsioon." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:55 msgid "Teenus" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:57 msgid "" "Teenuse vastutav töötleja on Riigi Valimisteenistus (RVT). Teenuse " "volitatud töötleja on Riigi Infosüsteemi Amet (RIA). Teenust osutav " "süsteem on EHS." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:59 msgid "" "Teenust kasutav süsteem on VIS3. Teenust kasutava süsteemi vastutav " "töötleja on RIA." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:61 msgid "" "Teenuse ärinimi on \"E-hääletamiste nimekiri\". Teenuse tehniline nimi " "(X-tee REST teenusekood, Service Code) on `e-votings-running-list`." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:63 msgid "Teenus pakub järgmisi otspunkte:" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:65 msgid "" "1 `GET /elections`. \"Valimissündmuste loetelu\" väljastab aktiivsete " "valimissündmuste loetelu. Aktiivne valimissündmus teenuse kontekstis on " "selline, mille kohta EHS on valmis väljastama e-hääletamiste nimekirja." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:67 msgid "" "2 `GET /elections/{electionId}/lastseqno`. \"Viimane järjenumber\" " "väljastab konkreetse valimissündmuse viimase EHS-s registreeritud " "e-hääletamise järjenumbri." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:69 msgid "" "3 `GET /elections/{electionId}/evotingsbatchfrom/{fromseqno}`. " "\"e-hääletamiste pakk\". Selle päringuga pärib VIS3 EHS-lt " "valimissündmuse `{electionId}` e-hääletamiste paki, alatest " "e-hääletamisest järjenumbriga `{fromseqno}`." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:71 msgid "" "Päringute ja vastuste andmestruktuuride ja samuti vastuskoodide " "spetsifikatsiooni vt OpenAPI spetsifikatsioonis: [ehs-xroad-api.yaml" "](ehs-xroad-api.yaml)." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:73 msgid "" "Teenuse OpenAPI spetsifikatsioon publitseeritakse turvaserveris, " "vastavalt spetsifikatsioonile [https://www.x-tee.ee/docs/live/xroad/pr-" "mrest_x-road_service_metadata_protocol_for_rest.html#4-retrieving-list-" "of-services](X-Road: Service Metadata Protocol for REST), jaotis 5 " "\"Retrieving the OpenAPI description of a Service\"." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:75 msgid "Teenuse OpenAPI spetsifikatsioon näitepäring:" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:77 msgid "" "`curl -H \"accept: application/json\" -H \"X-Road-Client:ee-" "dev/COM//dev\" \"https://.../r1/ee-" "dev/COM//ehs/getOpenAPI?serviceCode=e-votings-running-list\"`" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:79 msgid "Otspunkt \"Valimissündmuste loetelu\"" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:81 #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:99 msgid "Näide." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:83 msgid "Päring: `GET /elections`" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:85 msgid "VIS3 pärib EHS-lt aktiivsete valimissündmuste loetelu." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:87 #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:105 #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:128 msgid "Vastus:" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:93 msgid "EHS vastab, et aktiivseid valimissündmusi on üks - `RK_2023`." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:95 msgid "" "Kui aktiivseid valimissündmusi ei ole, siis EHS peab vastuses saatma " "tühja massiivi (JSON Array)." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:97 msgid "Otspunkt \"Viimane järjenumber\"" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:101 msgid "Päring: `GET /elections/RK_2023/lastseqno`" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:103 msgid "VIS3 pärib valimissündmuse `RK_2023` viimase e-hääletamise järjenumbrit." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:114 msgid "" "EHS vastab, et valimissündmuse `RK_2023` viimase e-hääletamise " "järjenumber on `54002`." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:116 msgid "" "Kui valimissündmus on EHS-le tundmatu, siis EHS vastab HTTP vastuskoodiga" " `404 Not Found`." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:118 msgid "" "Järjenumbrid algavad ühest (`1`). Kui valimisündmuses ei ole veel ükski " "valija e-hääletanud, siis vastab EHS `lastseqno` väärtusega `0`." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:120 msgid "Otspunkt \"e-hääletanute pakk\"" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:122 msgid "Näide 3." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:124 msgid "Päring: `G /elections/RK_2023/evotingsbatchfrom/54001`" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:126 msgid "" "VIS3 pärib valimissündmuse `RK_2023` e-hääletamiste andmeid, alates " "järjenumbrist `54001`." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:155 msgid "" "EHS vastab, et saadab valimissündmuse `RK_2023` e-hääletamiste andmeid, " "alates järjenumbrist `54001`, pakina, milles on kuni `100` kirjet. " "Konkreetses pakis on kaks kirjet, kuna paki moodustamise hetkel on " "viimase EHS-s registreeritud e-hääletamise järjenumber `54002`. Esimene " "kirje tähendab, et valija `LEO KASS`, isikukoodiga `38101010020` on " "valimistel `RK_2023` e-hääletanud. Kirjes on ka valija KOV EHAK-kood ja " "valimisringkonna number." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:157 msgid "" "E-hääletamise fakti kohta EHS e-hääletamise aega ei saada - " "turvakaalutlustel." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:159 msgid "" "Paki maksimaalsuuruse `batchmaxsize` määrab EHS, arvestusega, et andmed " "saadetakse X-tee vastussõnumi kehas (mitte manuses). Vastussõnumi " "töötlemisel turvaserveris loetakse keha üheaegselt põhimällu. Seetõttu ei" " tohi vastusõnumi keha suurus ületada 10 MB (turvaserveri " "vaikeseadistus)." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:161 msgid "" "Vastuses võib olla kuni `batchmaxsize` kirjet. Kui vastuses on kirjeid " "vähem kui `batchmaxsize`, siis see tähendab, et EHS-l ei ole vastuse " "koostamise hetkel rohkem andmeid e-hääletamiste kohta." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:163 msgid "VIS3 peab suutma töödelda erineva `batchmaxsize` väärtusega vastuseid." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:165 msgid "Töötluse ülevaade" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:167 msgid "" "EHS registreerib e-hääletamise fakte. Igale e-hääletamisele omistab EHS " "järjenumbri. E-hääletamise fakte võib hoida nt järjenumbri järgi " "indekseeritud tabelis - siis on VIS3-i päringutele vastamine kiire ja " "efektiivne - kuid see on EHS siseasi. Paki maksimaalsuurus peaks olema " "EHS seadistuses määratav." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:169 msgid "" "VIS3 saadab valimiste aktiivsel perioodil regulaarselt päringuid EHS-i " "X-tee teenuse otspunkti \"Viimane järjenumber\". EHS saadab vastuses " "viimase e-hääletamise järjenumbri." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:171 msgid "" "Viimase järjenumbri alusel leiab VIS3, kas VIS3-e kantud e-hääletamiste " "andmed on EHS-iga sünkroonis. Kui viimane järjenumber osutab, et EHS-s on" " lisandunud kirjeid, mis vajavad VIS3-e kandmist, siis saadab VIS3 " "järjest päringud EHS X-tee teenuse otspunkti \"e-hääletamiste pakk\", " "alates esimesest järjenumbrist, mis on VIS3-s puudu; EHS saadab küsitud " "paki; VIS3 salvestab saadud andmed ja saadab järgmise paki päringu." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:173 msgid "" "Päringute \"e-hääletamiste pakk\" töötlusloogika EHS-i poolel peab " "võimaldama VIS3-l päringuid esitada mistahes järjekorras ja kuitahes " "palju kordi." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:175 msgid "" "Töötlus peab olema idempotentne (samajõuline) - selles mõttes, et VIS3 " "võib päritud andmeid igal ajal uuesti küsida. Uuesti pärimisega ei tohi " "tekkida duubelandmeid, tähendusnihkeid ega kinnijooksmisi." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:177 msgid "" "Tehnilise taustateabena märgime, et EHS hoiab e-hääletamise fakte mitte " "relatsioonilises andmebaasis, vaid etcd mäluteenuses." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:179 msgid "Kohaletoimetamise garantii" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:180 msgid "" "Sõltuvalt e-hääletamise sagedusest ja EHS jõudlusest ning seadistusest " "võib EHS-s juhtuda, et e-hääletamise väga suure sageduse perioodil " "e-hääletamise faktile järjenumbri omistamine ajalõpu (ingl timeout) tõttu" " ebaõnnestub. Selline e-hääletamise fakt jääb e-hääletamiste nimekirjas " "VIS3-e edastamata." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:182 msgid "" "Seega e-hääletamiste nimekiri ei anna kõigi e-hääletamiste VIS3-e " "jooksvalt kohaletoimetamise garantiid. VIS3-e kohaletoimetatud fakte " "tuleb käsitada informatiivsetena. E-hääletamise faktid toimetatakse " "VIS3-e kindlalt täielikus koosseisus e-hääletanute (lõplikus) nimekirjas," " pärast e-hääletamise perioodi lõppu (eraldi liides EHS ja VIS3 vahel)." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:184 msgid "Teenuse pakkumise ajaline ulatus" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:186 msgid "" "Konkreetse valimissündmuse kohta pakub EHS e-hääletamiste nimekirja " "ainult piiratud perioodil. See periood hõlmab e-hääletamise perioodi " "(kehtiva õiguse kohaselt 6 päeva) koos lühikeste siirdeperioodidega enne " "ja pärast." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:188 msgid "" "Kui EHS valimissündmuse kohta e-hääletamiste nimekirja enam ei paku, siis" " päringud otspunktidesse \"Viimane järjenumber\" ja \"e-hääletanute " "pakk\" saavad HTTP vastuskoodi `410 Gone`." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:190 msgid "" "Valimissündmuste loetelu pakub EHS pidevalt (otspunkt \"Valimissündmuste " "loetelu\"). Loetelus on valimissündmused, mille kohta EHS on valmis " "e-hääletamiste nimekirja pakkuma." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:192 msgid "Kontroll ja veaolukordade käsitlemine" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:194 msgid "" "Eeldatakse, et EHS-i poolt VIS3-le väljastatav on korrektne ja muutumatu " "(e-hääletamiste nimekirja piires). Parandus- ja muutmiskirjeid käesolev " "protokoll ei sisalda." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:196 msgid "" "Pärast e-hääletamise lõppu, valimispäeval, edastatakse EHS-st VIS3-le " "e-hääletanute lõplik nimekiri). See edastus on spetsifitseeritud: " "[E-hääletanute " "nimekiri](https://github.com/e-gov/VIS3-EHS/blob/main/4_e_haaletanute_nimekiri/SPEC.md)." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:198 msgid "VIS3 operaator laeb e-hääletanute lõpliku nimekirja VIS3-e." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:200 msgid "" "Jooksva nimekirja ja lõpliku nimekirja erinevuse korral loetakse \"tõe " "allikaks\" lõplik nimekiri. Seega: 1) kui lõplikus nimekirjas on isik, " "kes hääletamisperioodil edastatud nimekirjas puudub, siis loetakse isik " "e-hääletanuks; 2) kui hääletamisaegses nimekirjas on isik, kes lõplikus " "nimekirjas puudub, siis märge sellise isiku kohta VIS3-s küll " "säilitatakse, kuid töötluses ja toimingutes lähtutakse lõplikust " "nimekirjast, s.t loetakse, et isik ei ole e-hääletanud. VIS3 peab omama " "võimekust hääletamisaegse ja lõpliku nimekirja erinevust avastada ja " "operaatorile teada anda." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:203 msgid "" "EHS-st VIS3-e edastatud e-hääletamise faktid on VIS3 kasutajaliideses " "nähtavad valimiste korraldajale, vaates \"Valijaga seotud toimingute " "ajalugu\". Kui valija e-hääletas mitu korda, siis on valijaga seotud " "toimingute ajaloos esitatud kõik valija e-hääletamised. E-hääletamise " "juures on näha kuupäev ja kellaaeg, millal e-hääletamise fakt EHS-st " "VIS3-e edastati." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:205 msgid "Kirjandus" msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:207 msgid "\\[1] Git. https://git-scm.com/." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:209 msgid "" "\\[2] CouchDB Replication Protocol, " "https://guide.couchdb.org/draft/replication.html." msgstr "" #: ../../VIS3-EHS/9_e_haaletamiste_nimekiri/SPEC.md:211 msgid "" "\\[3] Principle and application of Rsync algorithm. " "https://developpaper.com/principle-and-application-of-rsync-algorithm/." msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/VIS3-EHS/README.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/README.md:1 msgid "VIS3-EHS liideste spetsifikatsioonid" msgstr "" #: ../../VIS3-EHS/README.md:3 msgid "" "Eesti riiklikel valimistel toimub e-hääletamine Valimiste infosüsteemi " "(VIS3) ja e-hääletamise süsteemi (EHS) koostöös. EHS roll on " "elektroonilise hääletamise läbiviimine lähtudes valimise definitsioonist," " mis koostatakse valimise korraldaja poolt VIS3 abil. E-hääletamise ajal " "vahetavad EHS ja VIS3 informatsiooni - võivad muutuda valijate nimekirjad" " ning liigub info e-häälte laekumise kohta." msgstr "" #: ../../VIS3-EHS/README.md:5 msgid "" "Dokument esitab VIS3 ja e-hääletamise süsteemi EHS vaheliste liideste " "spetsifikatsioonid." msgstr "" #: ../../VIS3-EHS/README.md:7 msgid "" "Spetsifikatsioonid on avalikud. Spetsifikatsioonid ei käsitle VIS3 ega " "EHS konfidentsiaalset siseehitust ega liideste konfidentsiaalseid " "elemente." msgstr "" #: ../../VIS3-EHS/README.md:10 msgid "Ülevaade" msgstr "" #: ../../VIS3-EHS/README.md:12 msgid "![VIS3 ja EHS liidesed (ülevaade)](img/vis-ehs.png)" msgstr "" #: ../../VIS3-EHS/README.md:12 msgid "VIS3 ja EHS liidesed (ülevaade)" msgstr "" #: ../../VIS3-EHS/README.md:14 msgid "Joonis 1. VIS3 ja EHS liidesed (ülevaade)." msgstr "" #: ../../VIS3-EHS/README.md:16 msgid "Märkus: Joonise originaal vt VIS3 dok-s RIAs, fail \"EHS\"." msgstr "" #: ../../VIS3-EHS/README.md:18 msgid "Vasakul on VIS3, mooduli täpsusega:" msgstr "" #: ../../VIS3-EHS/README.md:20 msgid "KAN - Kandidaadimoodul" msgstr "" #: ../../VIS3-EHS/README.md:21 msgid "NIM - Nimekirjamoodul" msgstr "" #: ../../VIS3-EHS/README.md:22 msgid "TUL - Valimistulemuse moodul" msgstr "" #: ../../VIS3-EHS/README.md:23 msgid "VAL - Valimissündmuse moodul" msgstr "" #: ../../VIS3-EHS/README.md:24 msgid "VTA - Valimistulemuse avalikustamise moodul." msgstr "" #: ../../VIS3-EHS/README.md:26 msgid "" "Andmed liiguvad noole suunas. HTTPS masinliidestes on teenust pakkuvad " "otspunktid VIS3 poolel. X-tee liideses on teenusepakkujaks EHS. Inim-" "masinliides tähendab seda, et ühe süsteemi operaator laeb faili " "süsteemist alla ja edastab teise süsteemi operaatorile, kes laeb faili " "teise süsteemi üles." msgstr "" #: ../../VIS3-EHS/README.md:29 msgid "Liidesed on täpsemalt kirjeldatud allpool." msgstr "" #: ../../VIS3-EHS/README.md:31 msgid "Spetsifikatsioonid" msgstr "" #: ../../VIS3-EHS/README.md:33 msgid "[1 Valimisringkondade nimekiri](1_Valimisringkondade_nimekiri/SPEC.md)" msgstr "" #: ../../VIS3-EHS/README.md:35 msgid "[2 Valikute nimekiri (kandidaatide nimekiri)](2_Valikute_nimekiri/SPEC.md)" msgstr "" #: ../../VIS3-EHS/README.md:37 msgid "[3 Valijate nimekiri EHS-le](3_Valijate_nimekiri/SPEC.md)" msgstr "" #: ../../VIS3-EHS/README.md:39 msgid "[4 E-hääletanute nimekiri](4_e_haaletanute_nimekiri/SPEC.md)" msgstr "" #: ../../VIS3-EHS/README.md:41 msgid "[5 Tühistus- ja ennistusnimekiri](5_Tyhistusnimekiri/SPEC.md)" msgstr "" #: ../../VIS3-EHS/README.md:43 msgid "[6 E-hääletamise tulemus](6_e_haaletamise_tulemus/SPEC.md)" msgstr "" #: ../../VIS3-EHS/README.md:45 msgid "" "[7 E-hääletamisest osavõtu " "üldstatistika](7_e_haaletamise_yldstatistika/SPEC.md)" msgstr "" #: ../../VIS3-EHS/README.md:47 msgid "" "[8 E-hääletamisest osavõtu " "detailstatistika](8_e_haaletamise_detailstatistika/SPEC.md)" msgstr "" #: ../../VIS3-EHS/README.md:49 msgid "[9 E-hääletamiste nimekiri](9_e_haaletamiste_nimekiri/SPEC.md)" msgstr "" #: ../../VIS3-EHS/README.md:51 msgid "" "Spetsifikatsioonides kasutatav valimissündmuse identifikaator peab " "vastama formaadile [Valimissündmuse " "identifikaator](valimissündmuse_identifikaator.md)." msgstr "" #: ../../VIS3-EHS/README.md:53 msgid "Usalduse loomine masinliidestes" msgstr "" #: ../../VIS3-EHS/README.md:55 msgid "Masinliidesed kaitstakse HTTPS-ga ja TLS mõlemapoolse autentimisega." msgstr "" #: ../../VIS3-EHS/README.md:57 msgid "" "Lisaks piiratakse VIS3 seadistusega EHS pääs ainult EHS-le määratud " "otspunktidele (3b ja 7)." msgstr "" #: ../../VIS3-EHS/README.md:59 msgid "Veakäsitlus masinliidestes" msgstr "" #: ../../VIS3-EHS/README.md:61 msgid "" "VIS3 peab andma HTTP standardi kohase vastuskoodi ja veateate, kui EHS " "saadetud päring on ebakorrektne või VIS3 ei suuda päringut teenendada." msgstr "" #: ../../VIS3-EHS/README.md:63 msgid "" "EHS peab arvestama VIS3 tõrke võimalusega. Standardne reaktsioon tõrkele " "on päringu uuestisaatmine." msgstr "" #: ../../VIS3-EHS/README.md:65 msgid "Veakäsitlus faili inimese poolt edastamise liidestes" msgstr "" #: ../../VIS3-EHS/README.md:67 msgid "" "VIS3 peab kontrollima üleslaetud faili süntaksit ja kus võimalik, kas " "semantikat. Ebakorrektse faili kohta tuleb anda operaatorile teada. " "Ebakorrektse faili andmeid ei kanta VIS3 andmebaasi." msgstr "" #: ../../VIS3-EHS/README.md:69 msgid "" "Korrektse, kuid eksitusena üleslaetud faili andmeid saab VIS3 " "andmebaasist kustutada ja õige fail uuesti üles laadida." msgstr "" #: ../../VIS3-EHS/README.md:71 msgid "Muudatused võrreldes VIS2-EHS-ga" msgstr "" #: ../../VIS3-EHS/README.md:73 msgid "VIS3-EHS liideses on võrreldes VIS2-ga muudetud ja ajakohastatud:" msgstr "" #: ../../VIS3-EHS/README.md:75 msgid "" "osapoolte vahetumisest (valijate nimekirja hakkab EHS-le saame mitte RR" "/SMIT-ist, vaid RIA VIS3-st)" msgstr "" #: ../../VIS3-EHS/README.md:76 msgid "valimisõiguse muutumisest (jaoskondade tähenduse muutumine)" msgstr "" #: ../../VIS3-EHS/README.md:77 msgid "valijate nimekirja ja selle uuenduste edastamisest üle liidese." msgstr "" #: ../../VIS3-EHS/README.md:79 msgid "" "VIS2 ja EHS omavahelisi liideseid spetsifitseerib \"IVXV protokollide " "kirjeldus\" (v 1.5.0, 20.04.2019), " "[https://www.valimised.ee/sites/default/files/uploads/eh/IVXV-" "protokollid.pdf](https://www.valimised.ee/sites/default/files/uploads/eh" "/IVXV-protokollid.pdf). \"Elektroonilise hääletamise protokollistik " "defineerib elektroonilise hääletamise süsteemi komponentide vahelise " "sõnumivahetuse, kasutatavad andmestruktuurid, algoritmid ning liidesed " "väliste süsteemidega.\" Spetsifitseeritud on:" msgstr "" #: ../../VIS3-EHS/README.md:81 msgid "liides \"Valimisringkondade nimekiri\" (jaotis 3.2)" msgstr "" #: ../../VIS3-EHS/README.md:82 msgid "liides \"Valikute nimekiri\" (jaotis 3.4)" msgstr "" #: ../../VIS3-EHS/README.md:83 msgid "liides \"Valijate nimekiri\" (jaotis 3.3)" msgstr "" #: ../../VIS3-EHS/README.md:84 msgid "liides \"Tühistus- ja ennistusnimekiri\" (jaotis 9.1)" msgstr "" #: ../../VIS3-EHS/README.md:85 msgid "liides \"E-hääletanute nimekiri\" (jaotis 9.2)" msgstr "" #: ../../VIS3-EHS/README.md:86 msgid "liides \"E-hääletamise tulemus\" (jaotis 9.3)" msgstr "" #: ../../VIS3-EHS/README.md:88 msgid "" "Käesolevad spetsifikatsioonid tuginevad ülalnimetatud " "spetsifikatsioonidele. Täpsemalt vt konkreetsete spetsifikatsioonide " "juures." msgstr "" #: ../../VIS3-EHS/README.md:90 msgid "" "EHS lähtekood on kättesaadav: [https://github.com/vvk-" "ehk/ivxv](https://github.com/vvk-ehk/ivxv)." msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/VIS3-EHS/Taustateave/README.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/Taustateave/README.md:1 msgid "" "Kaustas on spetsifikatsioonid X-tee teenustele, millega VIS3 pärib " "Rahvastikuregistrist valijate nimekirja ja nimekirja muudatused:" msgstr "" #: ../../VIS3-EHS/Taustateave/README.md:4 msgid "" "`RRValimisteAlgNimekiri_kirjeldus.pdf` - Rahvastikuregistri poolt " "osutatava Valimiste algnimekirja X-tee teenuse spetsifikatsioon." msgstr "" #: ../../VIS3-EHS/Taustateave/README.md:7 msgid "" "`RRValimisteNimekirjaMuudatused.pdf` - Rahvastikuregistri poolt osutatava" " Valimiste algnimekirja muudatuste X-tee teenuse spetsifikatsioon." msgstr "" #: ../../VIS3-EHS/Taustateave/README.md:10 msgid "" "Spetsifikatsioonid võivad aidata mõista VIS3 poolt EHS-le pakutavate " "andmete koosseisu ja tähendust." msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/VIS3-EHS/valimissündmuse_identifikaator.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:1 msgid "Valimissündmuse identifikaator" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:3 msgid "" "Üht valimist puudutav andmestik on seotud unikaalse valimissündmuse " "identifikaatori abil." msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:5 msgid "" "Valimissündmuse identifikaator on sõne, mis koosneb kahest kohustuslikust" " ja kahest valikulisest osast:" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:6 msgid "valimissündmuse tüüp, vastavalt allolevale tabelile, nt `RK`." msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:7 msgid "aastanumbrist (nt `2023`)" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:8 msgid "valikulisest erakorraliste valimiste tunnusest `_E` ja" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:9 msgid "valikulisest järjenumbrist , nt `2`." msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:11 msgid "Ülalnimetatud osad eraldatakse üksteisest allkriipsudega `_`." msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:13 msgid "" "Järjenummerdatakse tüüpide kaupa. Seejuures aasta esimese samatüübilise " "valimissündmuse korral järjenumbrit ei näidata." msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:15 msgid "Näited:" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:16 msgid "`KOV_2021`" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:17 msgid "`RH_2021`" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:18 msgid "`RH_2021_2` (2021. a teine rahvahääletus)" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:19 msgid "`RK_2023`" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:20 msgid "`RK_2023_E` (2023. a Riigikogu erakorralised valimised)" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:21 msgid "`RK_2023_E_2` (2023. a Riigikogu teised erakorralised valimised)." msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:23 msgid "" "EHSi jaoks on valimise identifikaator kuni 28 ASCII-tähemärgi pikkune " "sõne ning eelnevalt kirjeldatud struktuuri põhjal EHS otsuseid ei tee." msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:25 msgid "Valimissündmuse tüüp" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:27 msgid "Valimissündmuse tüüp esitatakse koodiga:" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:29 msgid "`KOV` - Kohaliku omavalitsuse volikogu valimised" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:30 msgid "`EP` - Euroopa Parlamendi valimised" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:31 msgid "`RK` - Riigikogu valimised" msgstr "" #: ../../VIS3-EHS/valimissündmuse_identifikaator.md:32 msgid "`RH` - Rahvahääletus." msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/examples.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../examples.rst:3 msgid "Skeemid ja näited" msgstr "" #: ../../examples.rst:7 msgid "Valimisringkondade nimekiri" msgstr "" #: ../../examples.rst:10 ../../examples.rst:48 ../../examples.rst:84 #: ../../examples.rst:119 ../../examples.rst:154 ../../examples.rst:189 #: ../../examples.rst:206 ../../examples.rst:217 msgid "Skeem" msgstr "" #: ../../examples.rst:17 ../../examples.rst:61 ../../examples.rst:97 #: ../../examples.rst:132 ../../examples.rst:167 msgid "Näide: KOV" msgstr "" #: ../../examples.rst:24 ../../examples.rst:55 ../../examples.rst:91 #: ../../examples.rst:126 ../../examples.rst:161 msgid "Näide: EP" msgstr "" #: ../../examples.rst:31 ../../examples.rst:68 ../../examples.rst:103 #: ../../examples.rst:138 ../../examples.rst:173 msgid "Näide: RH" msgstr "" #: ../../examples.rst:38 ../../examples.rst:74 ../../examples.rst:109 #: ../../examples.rst:144 ../../examples.rst:179 msgid "Näide: RK" msgstr "" #: ../../examples.rst:45 msgid "Valikute nimekiri" msgstr "" #: ../../examples.rst:81 msgid "E-hääletanute nimekiri" msgstr "" #: ../../examples.rst:116 msgid "Tühistusnimekiri" msgstr "" #: ../../examples.rst:151 msgid "E-hääletamise tulemus" msgstr "" #: ../../examples.rst:186 msgid "E-hääletamise üldstatistika" msgstr "" #: ../../examples.rst:196 msgid "Näide" msgstr "" #: ../../examples.rst:203 msgid "E-hääletamise detailstatistika" msgstr "" #: ../../examples.rst:214 msgid "E-hääletamiste nimekiri" msgstr "" ================================================ FILE: Documentation/public/liidesed/locales/et/LC_MESSAGES/index.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 23:20+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: et\n" "Language-Team: et \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../index.rst:4 msgid "IVXV registreerimisteenus" msgstr "" ================================================ FILE: Documentation/public/liidesed/spelling_wordlist.txt ================================================ com etcd git html https rsync scm www docs i b dok le ingl of ga lt edasisestes evotersbatch evotingsbatch edastakse liidestus id query tabeldusmärki digikonteinerist schema repos retrieving list array golang liidestub not found conflict duubelandmeid idempotentne informaalne sünkroonis sünkroonimisprotokolli teenendada tähelepanu EHS RR SMIT URL VIS live mrest timeout principle application draft replication developpaper algorithm x Road Service metadata protocol for REST Retrieving the OpenAPI description service services CouchDB Replication guide couchdb sequence code Anija Indrek Leesi Parmakson Tarmo Hanga Backus Naur Pirita Heibergiga ================================================ FILE: Documentation/public/protokollid/01-annotatsioon.rst ================================================ .. IVXV protokollid ================================================================================ Annotatsioon ================================================================================ Käesolev dokument kirjeldab elektroonilise hääletamise infosüsteemi IVXV protokollistikku. Dokument annab üldise ülevaate elektroonilise hääletamise süsteemi tehnilisest ülesehitusest ja kasutatavatest protokollidest. Dokumendis defineeritakse protokollides kasutatavad ühised mõisted ja andmestruktuurid. ================================================ FILE: Documentation/public/protokollid/02-ylevaade.rst ================================================ .. IVXV protokollid ================================================================================ Ülevaade ================================================================================ Elektroonilise hääletamise protokollistik (edaspidi protokollistik) defineerib elektroonilise hääletamise süsteemi komponentide vahelise sõnumivahetuse, kasutatavad andmestruktuurid, algoritmid ning liidesed väliste süsteemidega. Sõnumivahetus esitatakse UML suhtlusskeemidena, mis üheselt defineerivad sõnumite järgnevuse. Andmestruktuuride kirjeldused on varustatud BNF, ASN.1 või JSON-schema notatsioonis spetsifikatsioonidega. Algoritmid esitatakse pseudokoodina. NB! Kõigis protokollistiku andmestruktuuride väljades tuleb rangelt kinni pidada lubatud märkidest ning väljade minimaalsetest ja maksimaalsetest pikkustest. Täiendavate tühikute, tabulaatorite jms. kasutamine on keelatud ning spetsifikatsiooni realiseerivad rakendused peavad vorminguga mitte-vastavate andmete töötlemisest keelduma. Protokollistik defineerib elektroonilise hääletamise protokolli ning selle protokolli realiseerimiseks vajalikud tugistruktuurid. Elektroonilise hääletamise protokoll ==================================== Elektroonilise hääletamise protokoll spetsifitseerib: #. elektroonilise hääle vormingu, mis võimaldab üheselt määratleda valija tahte konkreetsel valimisel; #. elektroonilise hääle krüpteerimise hääle salajasuse tagamiseks; #. elektroonilise hääle digitaalse allkirjastamise tervikluse ja valija identifitseerimise tagamiseks; #. elektroonilise hääle kvalifitseerimise kogumisteenuse poolt, hääle vastuvõtmise tähistamiseks; Protokoll eeldab, et valimise korraldaja defineerib valimise ning genereerib häälte salastamise võtmepaari, mille avalik komponent tehakse valijarakendusele kättesaadavaks. Protokolli vahendusel liigub valija tahe kogumisteenuses talletatavasse e-valimiskasti ning võetakse tulemuse kujunemisel arvesse järgmist sündmusterida pidi: #. Valija kasutab valijarakendust oma tahteavalduse elektrooniliseks vormistamiseks: #. tahteavaldus vormistatakse elektroonilise häälena; #. vormistatud hääl krüpteeritakse; #. krüpteeritud hääl signeeritakse valija arvutis. #. Kogumisteenus talletab elektroonilise hääle, moodustades selle käigus häälele kvalifitseeritud digitaalallkirja: #. elektrooniline hääl registreeritakse välises registreerimisteenuses; #. elektroonilisele häälele võetakse digitaalne ajatempel; #. elektroonilisele häälele võetakse valija sertifikaadi kehtivuskinnitus; #. elektroonilist häält kvalifitseerivad elemendid tagastatakse mh. ka valijarakendusele kontrollimiseks ning valija informeerimiseks kvalifitseerimise tulemustest; #. valijale võimaldatakse kvalifitseeritud elektroonilise hääle kontrollimine kontrollrakenduse abil. .. note:: Elektroonilise hääle digitaalne allkirjastamine erineb tavapärasest dokumentide digitaalallkirjastamisest, kus kõik allkirja kvalifitseerimiseks vajalikud toimingud algatatakse vahetult allkirjastaja seadmes. Elektroonilise hääle kvalifitseerimise kohustus on kogumisteenusel, kelle ülesanne on veenduda vastuvõetavate häälte korrektses allkirjastatuses. Kuna e-hääletamise perioodil on koormus seotud teenustele kõrge, võimaldab kogumisteenuse poolt juhitud kvalifitseerimine tagada paremat teenuse kvaliteeti. #. Valija võib kasutada kontrollrakendust veendumaks oma hääle korrektses käitlemises kogumisteenuse poolt; #. Hääletamisperioodi lõppedes väljastab kogumisteenus valimise korraldajale e-valimiskasti ning registreerimisteenus väljavõtte kogumisteenuse poolt registreeritud häältest; #. e-valimiskasti koosseisus antakse valimise korraldajale üle: #. valija krüpteeritud tahteavaldus koos signatuuriga; #. registreerimisteenuse kinnitus hääle registreerimisest; #. ajatempliteenuse poolt väljastatud digitaalne ajatempel elektroonilisele häälele; #. kehtivuskinnitusteenuse poolt väljastatud kinnitus valija sertifikaadi kehtivuse kohta; #. registreerimisteenuse väljavõtte koosseisus antakse valimise korraldajale üle: #. kõik e-hääletamise perioodil kogumisteenuse poolt registreerimisteenusele saadetud päringud elektrooniliste häälte registreerimiseks. #. Valimise korraldaja arvutab hääletamistulemuse: #. kontrollitaks üle antud elektrooniliste häälte allkirjade kehtivust #. kontrollitakse, et kõik registreerimisteenuses registreeritud hääled on e-valimiskasti koosseisus üle antud; #. eraldatakse krüpteeritud hääled ja digitaalallkirjad; #. anonüümitakse krüpteeritud hääled krüptograafiliselt; #. dekrüpteeritakse krüpteeritud hääled; #. dekrüpteeritud häälte põhjal arvutatakse hääletamistulemus. Protokoll on analoogne paberil posti teel hääletamise protokolliga, kus valija tahe liigub valimiskomisjonini kahes ümbrikus – välimise ümbriku sees on sisemine ümbrik, mis omakorda sisaldab valija tahteavaldusega hääletussedelit. Välimine ümbrik kannab valijat identifitseerivat infot ning võimaldab mh. kontrollida valija õigust hääletada. Sisemine ümbrik on anonüümne ning kaitseb hääle salajasust. Enne häälte kokkulugemist eraldatakse sisemised ümbrikud välimistest. Elektroonilise hääletamise kontekstis on sisemine ümbrik vormistatud krüpteeritud häälena ning välimine ümbrik digitaalselt allkirjastatud dokumendina. ================================================ FILE: Documentation/public/protokollid/04-seadistus.rst ================================================ .. IVXV protokollid ================================================================================ Valimise definitsioon ================================================================================ Valimise defineerib valimise korraldaja. Eesti riiklikel valimistel jagunevad kõik hääleõiguslikud isikud ühte või mitmesse valimisringkonda. Valijal on võimalik hääletamisel valida ainult selle ringkonna kandidaatide vahel, kuhu ta kuulub. Valimise defineerimiseks tuleb määratleda vähemalt #. valimise unikaalne identifikaator ning küsimuste unikaalsed identifikaatorid; #. täielik loend valimisringkondadest ja -jaoskondadest; #. hääleõiguslike isikute nimekiri ja jagunemine valimisringkondadesse; #. kandidaatide nimekiri ja jagunemine valimisringkondadesse. Valimise sisendandmed koostatakse Valimise Infosüsteemis (VIS), vormingukirjeldused on spetsifitseeritud `VIS ja EHS ühisspetsifikatsioonis `_. ================================================ FILE: Documentation/public/protokollid/05-ehaal.rst ================================================ .. IVXV protokollid =================== Elektrooniline hääl =================== IVXV hääletamisprotokoll põhineb topeltümbrikuskeemil, mis tähendab, et valija avakujul tahteavaldus krüpteeritakse valimise korraldaja poolt levitatud avaliku võtmega. Krüpteeritud tahteavaldus allkirjastatakse digitaalselt valija käsutuses oleva allkirjastamisvahendiga ning edastatakse kogumisteenusesse mingis kokkulepitud konteinervormingus. Kogumisteenus võib valija poolt allkirjastatud häält täiendavalt kvalifitseerida, veendudes näiteks allkirjastamissertifikaadi kehtivuses. IVXV protokollistik näeb mh. ette kogumisteenuse poolt vastuvõetud häälte registreerimise välises registreerimisteenuses. Kogumisteenuse poolt talletamisele võetud hääl koos kvalifitseerivate elementidega tehakse kättesaadavaks nii valijarakendusele kui kontrollrakendusele, mis teostavad üksiku hääle peal samad kontrollid, mida hilisem valimise korraldaja töötlemisrakendus teostab kõigi häälte peal. Kvalifitseerivate elementide kontrollimise võimalus annab valijale kindluse, et tema häält on hilisemates protsessides korrektselt menetletud. Valija tahteavaldus avakujul ============================ Valija tahteavaldus avakujul eksisteerib valijarakenduses ning hiljem ka kontrollrakenduses ja häälte kokkulugemisel võtmerakenduses. Tahteavaldus sisaldab valiku koodi ringkonnas ja ringkonna EHAK-koodi. Eraldajana kasutatakse ASCII kooditabeli sümbolit `0x2E` ehk ".". Vormingus spetsifitseerimata sümbolite kasutamine ei ole lubatud, vormingule mittevastavad sedelid loetakse kehtetuks. .. code-block:: bnf ::= "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ::= ::= | ::= 0x2E ::= Järgmised tahteavaldused on vormistatud korrektselt: .. code-block:: bnf 0000.123 0321.1234 0000.1234 Järgmised tahteavaldused ei ole vormistatud korrektselt: .. code-block:: bnf 0000 . 123 (* vorming ei näe ette tühikute kasutamist *) 0000-123 (* vorming lubab eraldajana vaid sümbolit "." *) 123 (* mõlemad vormingukomponendid tuleb esitada *) 321.1234 (* EHAK kood on 4-kohaline identifikaator *) Krüpteeritud sedel ================== Valija tahteavaldus avakujul :token:`ballot` krüpteeritakse valijarakenduse poolt valimise korraldaja genereeritud avaliku võtmega. IVXV vajab krüpteerimiseks mitte-deterministlikku, homomorfset avaliku võtme krüptosüsteemi. Selliseks süsteemiks sobib ElGamal krüptosüsteem, mida täna rakendatakse IVXV kontekstis nii jäägiklassiringi `Zp` multiplikatiivsel rühmal `Zp*` (MODP tüüpi rühmad) kui ka elliptkõveratel (ECC tüüpi rühmad). ElGamal avalik võti kodeeritakse koos ElGamal krüptosüsteemi parameetritega ning konkreetset valimist iseloomustava identifikaatoriga. Krüptosüsteemi parameetrid on osaks algoritmi identifikaatori struktuurist, avalik võti on kodeeritud X509 standardis kirjeldatud :token:`SubjectPublicKeyInfo` struktuuri :token:`subjectPublicKey` välja. :: SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING } MODP tüüpi rühmade korral identifitseerib algoritmi identifikaator :token:`id-ivxv-modp-elgamal`. Parameetrid vastavad struktuurile :token:`IVXVModPElGamalParameters` ning avalik võti struktuurile :token:`IVXVModPElGamalPublicKey` (:ref:`asn-modp`). ECC tüüpi rühmade korral identifitseerib algoritmi identifikaator :token:`id-ivxv-ecc-elgamal`. Parameetrid vastavad struktuurile :token:`IVXVECCElGamalParameters` ning avalik võti struktuurile :token:`IVXVECCElGamalPublicKey` (:ref:`asn-ecc`). Valija tahteavalduse krüpteerimiseks võetakse UTF-8 kodeeringus struktuur :token:`ballot` ning teisendatakse see ElGamal parameetrite poolt kirjeldatud rühma elemendiks vastavalt MODP või ECC algoritmidele. Rühma elemendiks teisendatud tahteavaldus krüpteeritakse ElGamal algoritmiga ning kodeeritakse MODP korral struktuuri :token:`IVXVModPElGamalCiphertext` (:ref:`asn-modp`) ja ECC korral struktuuri :token:`IVXVECCElGamalCiphertext` (:ref:`asn-ecc`). Lõplik krüpteeritud tahteavaldus esitatakse struktuuris :token:`IVXVElGamalCiphertext` (:ref:`asn-general`), kus väli :token:`algorithm` viitab rühma tüübile ning väli :token:`ciphertext` rühmaspetsiifilisele krüptogrammile. Andmestruktuuri :token:`IVXVElGamalCiphertext` DER-kodeering on krüpteeritud sedel ehk sisemine ümbrik topeltümbriku skeemis. .. NB! Nende algoritmide spetsifikatsioonidele tuleb viidata. Tahteavalduse krüpteerimise käigus genereeritakse valijarakenduses juhuarv, mida ElGamal krüpteerimisel kasutab. Sama juhuarv avalikustatakse hiljem kontrollrakendusele. Tulenevalt ElGamal krüptosüsteemi eripärast funktsioneerib see juhuarv nö. teise võtmena ning võimaldab krüptogrammi dekodeerimist kontrollrakenduses. .. _signed-vote: Valija poolt allkirjastatud hääl ================================ Krüpteeritud sedel tuleb enne kogumisteenusesse talletamisele saatmist digitaalselt allkirjastada, milleks on võimalik kasutada kõiki Eesti Vabariigis kehtivaid digitaalallkirjavahendeid – ID-kaart, Digi-ID, Mobiil-ID, Smart-ID. ID-kaarti saab kasutada nii TLS-CCA kui Web-eID protokolliga. .. attention:: Loend digitaalallkirjavahenditest ja nendega seotud protokollidest on tehniliselt korrektne, kuid valimiste korraldajal on võimalus kasutada vaid mõnda alamhulka nimetatud vahenditest. Käesolev spetsifikatsioon näeb ette Eesti Vabariigi Standardikavandis [BDOC2.1] defineeritud BDOC allkirjavormingu kasutamise. BDOC allkirjavorming koosneb ETSI standardi TS 101 903 (XadES) profiilist ning OpenDocument konteineri vormingust. Olenevalt käimasoleval valimisel esitatud küsimuste arvust võib digitaalselt allkirjastatud hääl sisaldada ühte või mitut andmefaili MIME-tüübiga ``application/octet-stream``. Iga andmefaili sisuks on krüpteeritud sedel. Andmefaili ja teiste signeeritavate andmeobjektide räsimiseks enne allkirjastamist kasutatakse räsifunktsiooni SHA-256. Andmefaili nimi moodustatakse laiendist '``ballot``' ning valimise identifikaatorist ja küsimuse identifikaatorist. Kõik viidatud andmefailid peavad sisalduma allkirjakonteineris. Digitaalselt allkirjastatud hääl ei tohi sisaldada muid andmefaile kui neid, mis sisaldavad hääli mõne käimasoleva valimise kontekstis. Seadistusele mittevastavate häälte vastuvõtmisest, talletamisest ja töötlemisest peab kogumisteenus keelduma. .. attention:: Valimise identifikaator ja küsimuse identifikaator on defineeritud valimise korraldaja poolt loodud seadistustes ning töötlevad rakendused peavad lähtuma neist seadistustest otsustamaks, millised vormingule vastavad identifikaatorid on konkreetse sündmuse kontekstis lubatud ja millised mitte. .. code-block:: bnf ::= [ASCII] ::= 1..28 ::= 1..28 ::= "ballot" ::= 0x2E ::= Valija poolt valijarakenduses allkirjastatud hääl moodustatakse nii, et on võimalik selle edasine kvalifitseerimine kogumisteenuses. Käesolev spetsifikatsioon näeb ette hääle kvalifitseerimiseks nii PKIX ajatempli kui OCSP kehtivuskinnituse võtmise. Sellisena on lõplik kvalifitseeritud hääl vastav BDOC-TS profiilile. Kui hääl allkirjastatakse ID-kaardi või Digi-ID'ga, siis toimub algse allkirjastatud konteineri moodustamine valijarakenduses. Kui hääl allkirjastatakse Mobiil-ID või Smart-ID'ga, siis toimub konteineri moodustamine valijarakenduse ning kogumisteenuse poolt vahendatava Mobiil-ID/Smart-ID teenuse koostöös. Mobiil-ID/Smart-ID juhtumil kasutab kogumisteenus Mobiil-ID/Smart-ID teenust ainult signatuuri saamiseks krüpteeritud sedelile. Kõik hääle kvalifitseerimiseks vajalikud elemendid hangitakse vastavatelt teenustelt alles siis kui valijarakendus on saatnud signeeritud hääle talletamiseks. Kvalifitseeritud hääl esitatakse kogumisteenuse poolt valijarakendusele verifitseerimiseks, ainult kvalifitseeritud hääl peab vastama BDOC 2.1 standardi tingimustele -- valijarakenduse poolt moodustatud hääl on vaheetapp kvalifitseeritud hääleni jõudmiseks. Valijarakenduses signeeritud häälel peab olema üks ja ainult üks allkiri, mida hoitakse signatuurifailis :file:`META-INF/signature0.xml`. Häält ja allkirja sisaldav konteiner (edaspidi viidatud kui ``SignedVote``) moodustatakse BDOC 2.1 standardis kirjeldatud meetodit kasutades. Spetsifitseerime valijarakenduses allkirjastatud hääle vormingu ühe küsimuse korral. Räsialgoritmina ``DIGEST_ALG`` on kasutusel SHA-256 (http://www.w3.org/2001/04/xmlenc#sha256). XML kanoniseerimiseks (``CANON_ALG``) kasutatakse meetodit ``c14n11`` (http://www.w3.org/2006/12/xml-c14n11). ECC võtmete korral on allkirjastamismeetodiks http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256. RSA võtmeid enam ei kasutata. Identifikaatorite `VOTE_REF`, `SP_REF`, `SP_URI` ning `SV_URI` täpne väärtus ei ole fikseeritud. Element `SignedProperties` --------------------------- Element ``SignedProperties`` moodustatakse kooskõlas BDOC 2.1 standardiga. Kui kvalifitseerimisel kasutatakse ajatemplit, siis elementi ``SignaturePolicyIdentifier`` ei kasutata. Ühtegi mitte-kohustuslikku elementi ei kasutata. Allkirjastamise kellaaja fikseerib andmestruktuuri täitev arvuti ning valija X509-sertifikaat saadakse kas ID-kaardilt, Mobiil-ID, Smart-ID või Web eID teenuse vahendusel. .. literalinclude:: ../../common/xmltemplates/sp.template :language: xml :linenos: Element `SignedInfo` --------------------- Element ``SignedInfo`` moodustatakse kooskõlas BDOC 2.1 standardiga, viidates nii krüpteeritud sedelile (``VOTE_DIGEST``) kui elemendile ``SignedProperties`` (``SP_DIGEST``). .. literalinclude:: ../../common/xmltemplates/si.template :language: xml :linenos: Element `SignatureValue` ------------------------ Element ``SignatureValue`` moodustatakse kooskõlas BDOC 2.1 standardiga. Kanoniseeritud elemendist ``SignedInfo`` arvutatakse räsi, mis allkirjastatakse PKCS1-meetodiga. .. literalinclude:: ../../common/xmltemplates/sv.template :language: xml :linenos: Element `XAdESSignatures` ------------------------- Element ``XAdESSignatures`` sisaldab ühte ``Signature`` elementi, mis on koostatud lähtudes kõigist eelmistest elementidest ning valija X509 sertifikaadist. Elementi ``UnsignedProperties`` ei kasutata. .. literalinclude:: ../../common/xmltemplates/sig.template :language: xml :linenos: ================================================ FILE: Documentation/public/protokollid/06-talletamine.rst ================================================ .. IVXV protokollid ==================================================== Elektroonilise hääle kvalifitseerimine talletamiseks ==================================================== Kvalifitseeritud hääl ===================== Valijarakenduse töö tulemusena saadetakse kogumisteenusesse talletamiseks topeltümbrik, mis sisaldab endas valija tahteavaldust krüpteeritud kujul, valija allkirja krüpteeritud tahteavaldusel kooskõlastatud allkirja- ja konteinervormingus ning valija allkirjastamissertifikaati X509-vormingus. Hääle edukaks talletamiseks näeb IVXV protokoll ette hääle registreerimise välise registreerimisteenuse osutaja juures ning registreerimistõendi valijarakendusele kättesaadavaks tegemise. Valimise korraldaja võib hääle kvalifitseerimiseks näha ette täiendavaid samme lisaks registreerimisele -- näiteks kehtivuskinnituse hankimist hääle allkirjastanud sertifikaadi kohta. Kõik kogumisteenuse poolt hangitavad kvalifitseerivad elemendid, mis määravad hääle staatuse hilisemates töötlusetappides, tuleb esitada valijarakendusele ning nõudmise korral ka kontrollrakendusele tagamaks, et valija saab oma hääle korrektse menetlemise võimalikkusest õigeaegselt teada. OCSP kehtivuskinnitus --------------------- OCSP (*Online Certificate Status Protocol*) on standartne protokoll X509-sertifikaatide kehtivusinfo pärimiseks. Kogumisteenus võib seda protokolli kasutada hääle allkirjastanud sertifikaadi kehtivuse teadasaamiseks. OCSP vastus ütleb, et sertifikaat kehtis päringu tegemise ajahetkel, kuid ei seosta OCSP vastust konkreetse allkirjaga. RFC3161 ajatempel ----------------- RFC3161 ajatempli protokolliga saadakse usaldusteenuse pakkujalt kinnitus, et mingi andmekogum eksisteeris enne teatud ajahetke. BDOC-TS kontekstis ajatembeldatakse allkirja element ``SignatureValue`` kanoniseeritud kujul. Klassikaline OCSP vastus koos RFC 3161 vormingus ajatempliga kvalifitseerivad BDOC-TS allkirja. Talletamine ==================================================== Elektroonilise hääle talletamine kogumisteenuses tähendab: #. hääle vastuvõtmist valijarakenduselt ning hääletaja allkirja verifitseerimist; #. hääle võimalikku kvalifitseerimist -- näiteks sertifikaadi kehtivuse tõendamist hääle allkirjastamisele lähedasel ajahetkel; #. hääle registreerimist sõltumatus registreerimisteenuses; #. häält kvalifitseerivate elementide vahendamist valijarakendusele. Erinevad kombinatsioonid allkirjavormingust ning hääli kvalifitseerivatest teenustest võivad tekitada erinevaid IVXV-profiile. Konkreetse dokumendi raames on IVXV profiil: #. Allkirjastatud hääle vorming on BDOC-TS; #. Kehtivuskinnitusprotokolliks on standartne OCSP; #. BDOC-TS kvalifitseerimiseks kasutatav RFC3161 ajatempel on kasutusel ka registreerimistõendina. ================================================ FILE: Documentation/public/protokollid/06a-regteenus.rst ================================================ .. IVXV registreerimisteenus ==================================== Elektroonilise hääle registreerimine ==================================== Hääle edukaks talletamiseks näeb IVXV protokoll ette hääle registreerimise välise registreerimisteenuse osutaja juures ning registreerimistõendi valijarakendusele kättesaadavaks tegemise. Registreerimisteenus toimub RFC3161 ajatempli protokolli baasil. Protokolli on laiendatud selliselt, et kogumisteenus saab ajatempli päringule anda oma signatuuri, mis teeb võimalikuks hilisema võrdleva väljavõtte registreerimisteenusest. Sõltumatu registreerimisteenuse olemasolu vähendab häälte kogumisteenuse poolt "kaotamise" riski. Registreerimisteenus ==================== Registreerimisteenus on teenus, mille abil Kogumisteenus registreerib kõik Hääletajatelt saadud hääled. Pärast hääletamisperioodi lõppu edastab Kogumisteenus talletatud hääled Töötlejale ning Registreerimisteenus edastab registreeritud hääled Töötlejale. Registreerimisteenus aitab tagada e-valimiskasti terviklust. Eeldame et Kogumisteenusel puudub võimalus võltsida digitaalallkirja ning sellisel moel tekitada juurde hääli või muuta juba talletatud hääli. Riskina säilib võimalus, et Kogumisteenus ei anna kõiki talletatud hääli Töötlejale üle. Häälte valikulise üleandmise riski maandamiseks kasutab IVXV protokoll täiendavat Registreerimisteenust, kuhu Kogumisteenus iga talletatud hääle registreerib. Hääletajal on protokollikohaselt võimalus korrektses registreerimises veenduda -- Registreerimisteenuse digitaalselt allkirjastatud kinnitus konkreetse hääle registreerimise kohta esitatakse ka konkreetsele hääletajale. Registreerimisteenus protokollis -------------------------------- Kogumisteenus saadab Registreerimisteenusele enda poolt allkirjastatud registreerimiskorralduse (edaspidi KORRALDUS), mis sisaldab hääle identifikaatorit ja allkirjastatud hääle räsi:: KORRALDUS = Sign_K(V_id, Hash(VOTE)) Registreerimisteenus talletab KORRALDUSE hilisemaks väljastamiseks ning vastab Kogumisteenusele oma poolt allkirjastatud registreerimiskinnitusega (edaspidi KINNITUS), mis allkirjastab algset KORRALDUST ning KINNITUSE väljastamise aega:: KINNITUS = Sign_R(Hash(KORRALDUS), t) Kogumisteenus tagastab nii KINNITUSE kui KORRALDUSE valijarakendusele, Hääletaja saab teate hääle positiivsest talletamisest ainult KINNITUSE ja selle aluseks olnud KORRALDUSE edukal verifitseerimisel. Hääletamisperioodi lõppedes edastab Registreerimisteenus Kogumisteenuse poolt tehtud KORRALDUSED Töötlejale. Registreerimisteenus peab Töötlejale algselt andma üle vähemalt loendi:: (V_id, Hash(VOTE)) Kui Registreerimisteenus annab üle ainult ülalkirjeldatud loendi, siis peab ta hiljem oleme võimeline andma loendi nõutud elemendile vastava korralduse:: (V_id, Hash(VOTE)), Sign_K(V_id, Hash(VOTE)) .. figure:: model/img/phase1.png Registreerimisteenuse roll hääletamisel .. figure:: model/img/phase2.png Registreerimisteenuse roll hääle kontrollimisel .. figure:: model/img/phase3.png Registreerimisteenuse roll häälte üleandmisel Registreerimisteenuse liidesed ------------------------------ Registreerimisteenusel on kaks liidest #. KORRALDUSTE vastuvõtmise ja KINNITUSTE väljastamise liides; #. KORRALDUSE alusel väljastatud KINNITUSTE loetelu ja nende aluseks olnud KORRALDUSTE väljastamise liides. Registreerimisteenuse funktsionaalsuseks on Kogumisteenusele KINNITUSTE väljastamine, väljastatud KINNITUSTE ja neile aluseks olevate KORRALDUSTE säilitamine ja hilisem Töötlejale üleandmine. Kui Registreerimisteenus osutab teenust mitmele erinevale osapoolele, siis peab olema garanteeritud, et konkreetse valimisega seotud Kogumisteenuse KORRALDUSED ja neile vastavad KINNITUSED on Valijarakenduse ja Kontrollrakenduse poolt kontrollitavalt eristatavad teiste osapoolte KORRALDUSTEST ning neile vastavatest KINNITUSTEST. Vastasel juhul võib tekkida olukord, kus Kogumisteenus küll registreerib hääle, kuid info sellest ei jõua Töötlejani. Registreerimisteenus peab olema võimeline kõiki Kogumisteenuse poolt tulnud KORRALDUSI üle andma. Osapoolte nõuded registreerimisteenusele ---------------------------------------- Töötleja ```````` Töötleja ülesanne on muuhulgas tuvastada, #. millised Kogumisteenuse poolt üle antud hääled lähevad lugemisele ja #. kas Kogumisteenus on jätnud hääli üle andmata. Töötleja töö tulemusena selguvaid erisusi tuleb lahendada ning siin on järgmised 3 juhtumit: #. Kogumisteenus annab Töötlejale üle allkirjastatud hääle koos KINNITUSega, Registreerimisteenus annab Töötlejale üle Kogumisteenuse KORRALDUSE, mille alusel KINNITUS anti - vaidlust ei ole, kui konkreetne hääl oli antud Hääletaja jaoks viimane, siis suunatakse ta lugemisele. #. Kogumisteenus annab Töötlejale üle allkirjastatud hääle koos KINNITUSega, Registreerimisteenus ei anna Töötlejale selle hääle kohta midagi üle. Kuna KINNITUS on Registreerimisteenuse poolt allkirjastatud, siis on viga Registreerimisteenuse poolel. Kui konkreetne hääl oli antud Hääletaja jaoks viimane, siis suunatakse ta lugemisele. #. Registreerimisteenus annab Töötlejale üle Kogumisteenuse KORRALDUSE, Kogumisteenus ei anna Töötlejale vastava räsiga häält üle. Kuna KORRALDUS on Kogumisteenuse poolt allkirjastatud, siis on viga Kogumisteenuse poolel ning antud hääl tuleb üles otsida. Hääletaja ````````` Hääletaja jaoks on oht, et Kogumisteenus võib tema hääle 'unustada'. Nõuetekohase KINNITUSE nägemine annab Hääletajale kindluse, et väline osapool garanteerib tema hääle Töötlejani jõudmist. Kindluse jaoks on oluline: #. KINNITUS on Registreerimisteenuse poolt allkirjastatud; #. KINNITUSES sisalduv algne KORRALDUS on Kogumisteenuse poolt allkirjastatud; #. usaldus, et Registreerimisteenus on võimeline KINNITUSE andmise fakti meeles pidama; #. usaldus, et Registreerimisteenus on võimeline KINNITUSE andmise kohasust Töötlejale tõestama; #. usaldus, et Kogumisteenusel ei ole võimalik hankida alternatiivset valekinnitust, mis Valijarakenduses verifitseerub, kuid Töötlejani ei jõua. Kogumisteenus ````````````` Kogumisteenuse jaoks on oht, et Registreerimisteenuse poolt üleantud KINNITUSTE ja talletatud häälte vaated erinevad. Kogumisteenuse poolt KORRALDUSELE antud allkiri on Kogumisteenuse garantii, et Registreerimisteenuse poolt ei saa tekkida fiktiivseid KINNITUSI, mida Kogumisteenus tegelikult nõudnud pole. Kogumisteenus talletab kõiki Registreerimisteenuse vastuseid. Kuna need on allkirjastatud, siis on täiendav info oluline vaid siis kui Kogumisteenus väidab, et mingit KORRALDUST ei ole antud, kuigi Registreerimisteenus on ``(v_id, Hash(VOTE))`` esitanud. Sellisel juhul saab Registreerimisteenus esitada terve Kogumisteenuse KORRALDUSE (või vähemalt selle allkirjastatud komponendi) Registreerimisteenus ```````````````````` Registreerimisteenus on huvitatud, et vaidlusolukordades, kus Kogumisteenus jätab midagi üle andmata, oleks tal võimalik oma tegevuse korrektsust tõestada. Oluline on tagada: #. Kogumisteenuse poolt konkreetse valimise raames antavad KORRALDUSED on teiste klientide poolt esitatud KORRALDUSTEST kontrollitavalt eristatavad. #. Kogumisteenus ei saa juba esitatud KORRALDUSTE kohta väita, et ta neid ei esitanud. Registreerimisteenuse realiseerimine RFC 3161 protokolli raamistikus -------------------------------------------------------------------- PKIX on ajatembeldusprotokoll, kus usaldatav kolmas osapool (ajatempliteenuse osutaja ehk ATO) kinnitab oma allkirjaga andmete eksisteerimist konkreetsel ajahetkel. Protokoll koosneb ühest päringust ja vastusest. Ajatemplipäring:: TimeStampReq ::= SEQUENCE { version INTEGER { v1(1) }, messageImprint MessageImprint, --a hash algorithm OID and the hash value of the data to be --time-stamped reqPolicy TSAPolicyId OPTIONAL, nonce INTEGER OPTIONAL, certReq BOOLEAN DEFAULT FALSE, extensions [0] IMPLICIT Extensions OPTIONAL } Ajatembeldatavad andmed esitatakse teenusele ``messageImprint`` koosseisus räsina. ``TimeStampReq`` ei sisalda endas päringu esitaja allkirja. ATO vastus ajatemplipäringule:: TimeStampResp ::= SEQUENCE { status PKIStatusInfo, timeStampToken TimeStampToken OPTIONAL } TimeStampToken ::= ContentInfo -- contentType is id-signedData ([CMS]) -- content is SignedData ([CMS]) TSTInfo ::= SEQUENCE { version INTEGER { v1(1) }, policy TSAPolicyId, messageImprint MessageImprint, -- MUST have the same value as the similar field in -- TimeStampReq serialNumber INTEGER, -- Time-Stamping users MUST be ready to accommodate integers -- up to 160 bits. genTime GeneralizedTime, accuracy Accuracy OPTIONAL, ordering BOOLEAN DEFAULT FALSE, nonce INTEGER OPTIONAL, -- MUST be present if the similar field was present -- in TimeStampReq. In that case it MUST have the same value. tsa [0] GeneralName OPTIONAL, extensions [1] IMPLICIT Extensions OPTIONAL } ``TimeStampResp`` on ATO poolt digitaalselt allkirjastatud konteiner, mis sisaldab endas päringu koosseisus saadud välja ``messageImprint`` ning nonssi. Registreerimisteenuse huvides on, et Kogumisteenuse päring oleks signeeritud. Kuna RFC 3161 ei toeta allkirjastatud päringuid on alternatiiviks kasutada mõnda laiendust, mis võimaldab Kogumisteenuse signatuuri edastamist. See laiendus tuleks teenuse poolt ajatempli koosseisus ka tagasi saata. Kuna RFC 3161 ei sõnasta laienduste tagasipeegeldamise nõuet ühemõtteliselt on reaalne võimalus kasutada protokolli laiendamiseks ajatemplipäringu nonssi. Nonss on ASN.1 INTEGER andmetüüp kuhu saab kodeerida suvalise struktuuriga andmeid, mis teeb võimalikuks järgmise skeemi: Enne hääletamist: #. Kogumisteenus genereerib allkirjastamisvõtme ja sertifikaadi. #. Kogumisteenus annab sertifikaadi Korraldajale üle. #. Kogumisteenus seadistab ennast ATO'd kasutama. Hääletamise ajal: #. Valija saadab hääle talletamiseks. #. Kogumisteenus räsib hääle, allkirjastab räsi ning võtab räsile ajatempli, kasutades ajatemplipäringu TimeStampReq nonsina oma allkirja sellel räsil. #. ATO töötleb ajatemplipäringut kooskõlas RFC 3161 nõuetega ning väljastab allkirjastatud ajatempli. #. Kogumisteenus vahendab ajatempli Valijarakendusele, mis teostab järgmised kontrollid: a) ajatempel on ATO poolt allkirjastatud, b) ajatempel sisaldab nonssi, c) ajatempel sisaldab tema hääle räsi, d) nonss on Kogumisteenuse poolt allkirjastatud valija hääle räsi. Peale hääletamist: #. Korraldaja annab ATO'le ajavahemiku ja Kogumisteenuse sertifikaadi #. ATO otsib kõigi selle ajavahemiku ajatemplipäringute ja vastuste hulgast neid, millel a) on nonss, b) nonss dekodeerub kokkuleppeliseks andmestruktuuriks, c) andmestruktuur verifitseerub Kogumisteenuse sertifikaadiga. #. ATO annab üle kõik leitud ajatemplipäringud ja ajatemplid. #. Kogumisteenus annab üle kõik ajatemplipäringud, ajatemplid ja hääled. #. Töötleja analüüsib andmeid vastavalt protokollile #. KINNITUS on Registreerimisteenuse poolt allkirjastatud; #. KINNITUSES sisalduv algne KORRALDUS on Kogumisteenuse poolt allkirjastatud; #. Usaldus, et Registreerimisteenus on võimeline KINNITUSE andmise fakti meeles pidama; #. Usaldus, et Kogumisteenusel ei ole võimalik hankida alternatiivset valekinnitust, mis Valijarakenduses verifitseerub, kuid Töötlejani ei jõua #. Usaldus, et Registreerimisteenus on võimeline KINNITUSE andmise kohasust Töötlejale tõestama; #. Registreerimisteenuse poolt ei saa tekkida fiktiivseid KINNITUSI, mida Kogumisteenus tegelikult nõudnud pole #. Kogumisteenus ei saa juba esitatud KORRALDUSTE kohta väita, et ta neid ei esitanud Nonsi vorming:: Signature ::= SEQUENCE { signingAlgorithm AlgorithmIdentifier, signature ANY DEFINED BY signingAlgorithm } AlgorithmIdentifier ::= SEQUENCE { algorithm OBJECT IDENTIFIER, parameters ANY DEFINED BY algorithm OPTIONAL } Sõnumiks on TimeStampReq.messageImprint DER-kodeering:: MessageImprint ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier, hashedMessage OCTET STRING } RSA kasutamisel allkirjastamiseks. välja ``Signature.signingAlgorithm.algorithm`` väärtus sõltub sõnumi ``hashAlgorithm`` välja väärtusest:: pkcs-1 OBJECT IDENTIFIER ::= { iso(1) member-body(2) US(840) rsadsi(113549) pkcs(1) 1 } sha-1WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 5 } sha224WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 14 } sha256WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 11 } sha384WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 12 } sha512WithRSAEncryption OBJECT IDENTIFIER ::= { pkcs-1 13 } Väli ``Signature.signingAlgorithm.parameters`` puudub või on NULL. Väli ``Signature.signature`` on OCTET STRING, mis sisaldab RSA signatuuri sõnumil. ATO väljavõte ------------- ATO väljavõte Kogumisteenuse poolt esitatud TimeStampReq vormingus päringutest esitatakse ZIP failina, kus iga päring on salvestatud ühte faili, mis vastab järgmistele tingimustele: * Kaustastruktuur puudub, ükski fail ei paikne kaustas. * Failinimed on unikaalsed (failinimedele samas tähendust ei omistata). Üleantav andmekomplekt on: * Andmefail: `.zip` * Kontrollsummafail: `.zip.sha256sum.asice` Üherealise kontrollsummafaili sisu on HEX kodeeringus SHA256 räsi andmefailist. ================================================ FILE: Documentation/public/protokollid/07-kontrollimine.rst ================================================ .. IVXV protokollid ================================================================================ Elektroonilise hääle kontrollimine eraldi ja e-valimiskasti koosseisus ================================================================================ Elektroonilist häält kontrollitakse töötlemisrakenduses, kogumisteenuses, valijarakenduses ja kontrollrakenduses. Kõige põhjalikuma kontrolli läbib elektrooniline hääl e-valimiskasti koosseisus töötlemisrakenduses, kus otsustatakse konkreetse hääle lugemisele saatmine või mittesaatmine. Nende kontrollide käigus vaadeldakse e-häält nii eraldi kui ka suhtes kõigi teiste sama valija poolt antud häältega. Täiendavalt kõrvutatakse e-valimiskasti registreerimisteenuse väljavõttega. Iga üksiku hääle kohta läbitakse töötlemisrakendusega analoogsel tasemel kontroll valijarakenduses, kus veendutakse, et kogumisteenus on hääle kvalifitseerinud selliselt, et töötlemisrakenduses tehtavad kontrollid õnnestuvad. Valijarakenduse kontrollidega samaväärsed kontrollid viib läbi kontrollrakendus. Kogumisteenus on lisaks vastutav mitme hääle lõplikuks kvalifitseerumiseks vajaliku elemendi hankimise eest ning teostab ka nende hankimise järgselt kontrollid. Lõpliku elektroonilise hääle komponendid ---------------------------------------- Elemendid, mis on kättesaadavad otsustamise hetkel, kas hääl kvalifitseerub lugemisele saatmiseks või mitte: #. elektroonilist häält sisaldav konteiner - :ref:`entity-haale-konteiner`; #. krüpteeritud sedel - :ref:`entity-krypteeritud-sedel`; #. valija signatuur krüpteeritud sedelil - :ref:`entity-haale-signatuur`; #. valija allkiri krüpteeritud sedelil - :ref:`entity-haale-allkiri`; #. valija allkirjastamissertifikaat - :ref:`entity-valija-sertifikaat`; #. valija isikukood - :ref:`entity-valija-identiteet`; #. kvalifitseeriv element - valija sertifikaadi kehtivuskinnitus - :ref:`entity-kehtivuskinnitus`; #. kvalifitseeriv element - ajatempel allkirjastatud krüpteeritud sedelile - :ref:`entity-ajatempel`; #. kvalifitseeriv element - registreerimispäringu konteiner :ref:`entity-registreerimisparing-konteiner`; #. kvalifitseeriv element - registreerimispäring allkirjastatud krüpteeritud sedelile - :ref:`entity-registreerimisparing`; #. kvalifitseeriv element - registreerimistõend allkirjastatud krüpteeritud sedeli kohta - :ref:`entity-registreerimistoend`; #. valija ringkonnakuuluvuse tõend hääle andmise hetkel - :ref:`entity-nimekirjatunnus`. Elemendid, mis on kättesaadavad otsustamise hetkel, kuidas häält kokkulugemisel arvesse võtta: #. miksitud krüpteeritud sedel - :ref:`entity-miksitud-krypteeritud-sedel`; #. valija tahteavaldus avakujul - :ref:`entity-tahteavaldus`; #. ringkonnakuuluvuse tunnus - :ref:`entity-ringkonnatunnus`; #. ringkonnapõhine valikute nimekiri - :ref:`entity-ringkonna-valikutenimekiri`. Täiendavad elemendid: #. krüpteerimisel kasutatud juhuslikkus - :ref:`entity-juhuslikkus`; - luuakse valijarakenduses hääle krüpteerimisel ning vahendatakse ainult kontrollrakendusele. .. _entity-tahteavaldus: ```````````` TAHTEAVALDUS ```````````` Olem moodustatakse valijarakenduses ning tuvastatakse võtmerakenduses. Tegemist on EHS spetsiifilises vormingus UTF-8 kodeeringus baidijadaga. .. _check-tahteavaldus-correctness: TAHTEAVALDUS, vormingu korrektsus ````````````````````````````````` Tahteavalduse vormingu korrektsuse kontroll käesoleva spetsifikatsiooni suhtes. .. _check-tahteavaldus-ringkonnatunnus-valikutenimekiri-consistency: TAHTEAVALDUS, RINGKONNATUNNUS, RINGKONNA VALIKUTENIMEKIRI kooskõlalisus ``````````````````````````````````````````````````````````````````````` Tahteavalduses sisalduva valiku kontroll ringkonnatunnuse ja valikute nimekirja suhtes. Kontroll õnnestub, kui tuvastatud valik on kättesaadav antud ringkonnas. .. _check-tahteavaldus-ringkonna-valikutenimekiri-consistency: TAHTEAVALDUS, RINGKONNA VALIKUTENIMEKIRI, kooskõlalisus ``````````````````````````````````````````````````````` Tahteavalduses sisalduva valiku kontroll ringkonnapõhise valikute nimekirja suhtes. Kontroll õnnestub, kui tuvastatud valik on kättesaadav antud ringkonnas. .. _entity-juhuslikkus: ``````````` JUHUSLIKKUS ``````````` Olem moodustatakse valijarakenduses ning kasutatakse ka kontrollrakenduses. Olem esitatakse EHS spetsiifilises vormingus baidijadana ning peab olema ühilduv avaliku võtme parameetrite poolt määratud matemaatilise rühmaga. .. _check-juhuslikkus-correctness: JUHUSLIKKUS, vormingu korrektsus ```````````````````````````````` Juhuslikkuse vormingu korrektsuse kontroll käesoleva spetsifikatsiooni suhtes. .. _check-juhuslikkus-public-key-consistency: JUHUSLIKKUS, kooskõlalisus avaliku võtmega `````````````````````````````````````````` Juhuslikkuse kooskõlalisuse kontroll avaliku võtmega. Kontroll õnnestub kui juhuslikkus on kasutatav skalaarina arvutusteks avaliku võtme parameetrite poolt määratud matemaatilises rühmas. .. _entity-krypteeritud-sedel: `````````````````` KRÜPTEERITUD SEDEL `````````````````` Olem moodustatakse valijarakenduses. Tegemist on EHS spetsiifilises vormingus DER-kodeeritud andmestruktuuriga, mille kontrollimise aluseks on EHS avalik võti, mis muuhulgas määratleb krüpteerimisel kasutatud matemaatilise rühma. .. _check-krypteeritud-sedel-correctness: KRÜPTEERITUD SEDEL, vormingu korrektsus ``````````````````````````````````````` Krüpteeritud sedeli vormingu korrektsuse kontroll käesoleva spetsifikatsiooni suhtes. .. _check-krypteeritud-sedel-public-key-consistency: KRÜPTEERITUD SEDEL, kooskõlalisus avaliku võtmega ````````````````````````````````````````````````` Krüpteeritud sedeli kooskõlalisuse kontroll avaliku võtmega. Kontroll õnnestub kui krüpteeritud sedeli komponendid on kasutatavad rühma liikmetena arvutusteks avaliku võtme parameetrite poolt määratud matemaatilises rühmas. .. _check-krypteeritud-sedel-juhuslikkus-consistency: KRÜPTEERITUD SEDEL, JUHUSLIKKUS, kooskõlalisus `````````````````````````````````````````````` Krüpteeritud sedeli kooskõlalisuse kontroll juhuslikkusega lähtudes rühma parameetritest. Kontroll õnnestub kui õnnestub näidata, et antud juhuslikkust on kasutatud krüpteeritud sedeli komponendi `uBlind` arvutamiseks antud rühma parameetrite järgi. .. _entity-valija-sertifikaat: `````````````````` VALIJA SERTIFIKAAT `````````````````` Olem on valijale omistatud süsteemiväliselt. Tegemist on X.509 vormingus sertifikaadiga, mille kehtivuse kontrolli aluseks on samasse avaliku võtme infrastruktuuri kuuluvad juursertifikaadid ja kehtivuskinnitusteenuse osutaja. .. _check-valija-sertifikaat-correctness: VALIJA SERTIFIKAAT, vormingu korrektsus ``````````````````````````````````````` Valija sertifikaadi vormingu korrektsuse kontroll lähtudes X.509 spetsifikatsioonist. .. _check-valija-sertifikaat-consistency-protocol-settings: VALIJA SERTIFIKAAT, protokollikohane kooskõlalisus valimise seadistustega ````````````````````````````````````````````````````````````````````````` Valija sertifikaadi protokollikohase kooskõlalisuse kontroll valimise seadistustega. Kontroll õnnestub kui: #. Valija sertifikaat on kehtiv lähtudes sertifikaadis sisalduvast kehtivusajast; #. Valija sertifikaat kuulub mõnda valimise seadistustes kirjeldatud sertifitseerimishierarhiatest. .. _check-valija-sertifikaat-kehtivuskinnitus-consistency: VALIJA SERTIFIKAAT, KEHTIVUSKINNITUS, protokollikohane kooskõlalisus valimise seadistustega ``````````````````````````````````````````````````````````````````````````````````````````` Valija sertifikaadi ja kehtivuskinnituse protokollikohase kooskõlalisuse kontroll valimise seadistustega. Kontroll õnnestub kui: #. Kehtivuskinnitus on korrektselt allkirjastatud kehtivuskinnituse teenuse osutaja poolt, kellel on seadistuste kohaselt voli valija sertifikaadi kehtivust tõendada #. Kehtivuskinnitus on väljastatud valija sertifikaadi kohta; #. Kehtivuskinnitus näitab valija sertifikaadi OCSP olekuks 'Kehtiv'. .. _entity-valija-identiteet: ````````````````` VALIJA IDENTITEET ````````````````` Olem on valijale omistatud süsteemiväliselt. Tegemist on isikukoodiga, mille kontrollimise aluseks on VALIJA SERTIFIKAAT. .. _check-valija-identiteet-correctness: VALIJA IDENTITEET, vormingu korrektsus `````````````````````````````````````` Valija identiteedi vormingu korrektsuse kontroll lähtudes Eesti Vabariigi isikukoodi vormingust. .. _check-valija-identiteet-nimekirjatunnus-eligibility: VALIJA IDENTITEET, NIMEKIRJATUNNUS, hääleõigus `````````````````````````````````````````````` Hääleõiguse kontroll valija identiteedi ja nimekirjatunnuse alusel. Kontroll õnnestub, kui valija identiteet on kantud nimekirjatunnusele vastavasse valijate nimekirja. Sellisel juhul on identiteedile omistatud ka ringkonnatunnus, mis määrab ringkonnaspetsiifilise valikute nimekirja. .. _entity-haale-signatuur: ``````````````` HÄÄLE SIGNATUUR ``````````````` Olem arvutatakse allkirjastamise vahendi poolt lähtudes valijarakenduse poolt sisendiks antud KRÜPTEERITUD SEDELI räsist. .. _check-haale-signatuur-correctness: HÄÄLE SIGNATUUR, vormingu korrektsus ```````````````````````````````````` Hääle signatuuri vormingu korrektsuse kontroll lähtudes konkreetsest signeerimismeetodist. .. _check-haale-signatuur-krypteeritud-sedel-valija-sertifikaat-consistency: HÄÄLE SIGNATUUR, KRÜPTEERITUD SEDEL, VALIJA SERTIFIKAAT, kooskõlalisus `````````````````````````````````````````````````````````````````````` Kontroll, mis õnnestub siis ja ainult siis kui õnnestub verifitseerida, et hääle signatuur on arvutatud krüpteeritud sedeli räsist kasutades valija sertifikaadis leiduvale avalikule võtmele vastavat privaatvõtit. .. _entity-haale-allkiri: ````````````` HÄÄLE ALLKIRI ````````````` Olem moodustatakse valijarakenduses, talletades hääle signatuuri allkirja vormingusse. .. _check-haale-allkiri-correctness: HÄÄLE ALLKIRI, vormingu korrektsus `````````````````````````````````` Hääle allkirja vormingu korrektsuse kontroll käesoleva spetsifikatsiooni suhtes. .. _check-haale-allkiri-haale-signatuur-consistency: HÄÄLE ALLKIRI, HÄÄLE SIGNATUUR, kooskõlalisus ````````````````````````````````````````````` Hääle allkirja ja hääle signatuuri kooskõlalisuse kontroll. Kontroll õnnestub, kui antud allkiri sisaldab antud signatuuri. .. _entity-haale-konteiner: ``````````````` HÄÄLE KONTEINER ``````````````` Olem moodustatakse valijarakenduses, luues vormingukohane konteiner, mis sisaldab muuhulgas krüpteeritud sedelit, hääle allkirja ja valija sertifikaati. .. _check-haale-konteiner-correctness: HÄÄLE KONTEINER, vormingu korrektsus ```````````````````````````````````` Hääle konteineri vormingu korrektsuse kontroll käesoleva spetsifikatsiooni suhtes. .. _check-haale-konteiner-haale-allkiri-valija-sertifikaat-krypteeritud-sedel-consistency: HÄÄLE KONTEINER, HÄÄLE ALLKIRI, VALIJA SERTIFIKAAT, KRÜPTEERITUD SEDEL, kooskõlalisus ````````````````````````````````````````````````````````````````````````````````````` Hääle konteineri, hääle allkirja, valija sertifikaadi ja krüpteeritud sedeli kooskõlalisuse kontroll. Kontroll õnnestub kui antud konteiner sisaldab konkreetset hääle allkirja, valija sertifikaati ja krüpteeritud sedelit. .. _entity-kehtivuskinnitus: ```````````````` KEHTIVUSKINNITUS ```````````````` Olemi hankimise eest vastutab kogumisteenus. Tegemist on OCSP vormingus kinnitusega valija sertifikaadi oleku kohta. .. _check-kehtivuskinnitus-correctness: KEHTIVUSKINNITUS, vormingu korrektsus ````````````````````````````````````` Kehtivuskinnituse vormingu korrektsuse kontroll OCSP spetsifikatsiooni suhtes. .. _check-kehtivuskinnitus-ajatempel-order: KEHTIVUSKINNITUS, AJATEMPEL, ajaline järgnevus `````````````````````````````````````````````` Kehtivuskinnituse ja ajatempli ajalise järgnevuse kontroll. Kontroll õnnestub, kui #. ajatempel ei ole väljastatud hiljem kui kehtivuskinnitus; #. ajatempli ja kehtivuskinnituse väljastamise ajaline vahe on väiksem kui valimise seadistustes ette nähtud aeg. .. _entity-ajatempel: ````````` AJATEMPEL ````````` Olemi hankimise eest vastutab kogumisteenus. Tegemist on PKIX vormingus ajatempliga. .. _check-ajatempel-correctness: AJATEMPEL, vormingu korrektsus `````````````````````````````` Ajatempli vormingu korrektsuse kontroll PKIX spetsifikatsiooni suhtes. .. _check-ajatempel-consistency-protocol-settings: AJATEMPEL, HÄÄLE ALLKIRI, protokollikohane kooskõlalisus valimise seadistustega ``````````````````````````````````````````````````````````````````````````````` Ajatempli protokollikohase kooskõlalisuse kontroll valimise seadistustega. Kontroll õnnestub kui: #. ajatempel on korrektselt allkirjastatud valimise seadistuses volitatud ajatempliteenuse osutaja poolt; #. ajatempel on võetud hääle allkirjale. .. _entity-registreerimisparing: ```````````````````` REGISTREERIMISPÄRING ```````````````````` Olem moodustatakse kogumisteenuses. Olemi talletamise eest vastutab registreerimisteenuse osutaja. .. _check-registreerimisparing-correctness: REGISTREERIMISPÄRING, vormingu korrektsus ````````````````````````````````````````` Registreerimispäringu vormingu korrektsuse kontroll käesoleva spetsifikatsiooni suhtes. .. _check-registreerimisparing-haale-allkiri-consistency: REGISTREERIMISPÄRING, HÄÄLE ALLKIRI, protokollikohane kooskõlalisus valimise seadistustega `````````````````````````````````````````````````````````````````````````````````````````` Registreerimispäringu ja hääle allkirja protokollikohase kooskõlalisuse kontroll valimise seadistustega. Kontroll õnnestub kui: #. Registreerimispäring on koostatud hääle allkirjale; #. Registreerimispäring on korrektselt allkirjastatud valimise seadistuses viidatud kogumisteenuse poolt. .. _check-registreerimisparing-registreerimistoend-consistency: REGISTREERIMISPÄRING, REGISTREERIMISTÕEND, kooskõlalisus ``````````````````````````````````````````````````````````````````````` Registreerimispäringu ja registreerimistõendi protokollikohase kooskõlalisuse kontroll valimise seadistustega. Kontroll õnnestub kui: #. Registreerimispäring on korrektselt allkirjastatud valimise seadistuses viidatud kogumisteenuse poolt. #. Registreerimistõend on koostatud vastuseks samale registreerimispäringule; #. Registreerimistõend on korrektselt allkirjastatud valimise seadistuses viidatud registreerimisteenuse poolt. .. _entity-registreerimisparing-konteiner: ``````````````````````````````` REGISTREERIMISPÄRINGU KONTEINER ``````````````````````````````` Olem moodustatakse kogumisteenuses. Olemi talletamise eest vastutab registreerimisteenuse osutaja. .. _check-registreerimisparing-konteiner-correctness: REGISTREERIMISPÄRINGU KONTEINER, vormingu korrektsus ```````````````````````````````````````````````````` Registreerimispäringu konteineri vormingu korrektsuse kontroll käesoleva spetsifikatsiooni suhtes. .. _check-registreerimisparing-konteiner-registreerimispäring-consistency: REGISTREERIMISPÄRINGU KONTEINER, REGISTREERIMISPÄRING, protokollikohane kooskõlalisus valimise seadistustega ```````````````````````````````````````````````````````````````````````````````````````````````````````````` Registreerimispäringu konteineri ja registreerimispäringu protokollikohase kooskõlalisuse kontroll valimise seadistustega. Kontroll õnnestub kui: #. Registreerimispäringu konteiner sisaldab registreerimispäringut; #. Registreerimispäring on korrektselt allkirjastatud valimise seadistuses viidatud kogumisteenuse poolt. .. _entity-registreerimistoend: ``````````````````` REGISTREERIMISTÕEND ``````````````````` Olemi hankimise eest vastutab kogumisteenus, olemi moodustab registreerimisteenuse osutaja. .. _check-registreerimistoend-correctness: REGISTREERIMISTÕEND, vormingu korrektsus ```````````````````````````````````````` Registreerimistõendi vormingu korrektsuse kontroll käesoleva spetsifikatsiooni suhtes. .. _check-registreerimistoend-haale-allkiri-consistency: REGISTREERIMISTÕEND, HÄÄLE ALLKIRI, protokollikohane kooskõlalisus valimise seadistustega ````````````````````````````````````````````````````````````````````````````````````````` Registreerimistõendi ja hääle allkirja protokollikohase kooskõlalisuse kontroll valimise seadistustega. Kontroll õnnestub kui: #. Registreerimistõend on koostatud hääle allkirjale; #. Registreerimistõend sisaldab kogumisteenuse poolt korrektselt allkirjastatud registreerimispäringut; #. Registreerimistõend on korrektselt allkirjastatud valimise seadistuses viidatud registreerimisteenuse poolt. .. _entity-nimekirjatunnus: ``````````````` NIMEKIRJATUNNUS ``````````````` Olem moodustatakse kogumisteenuses ning identifitseerib ühe konkreetse versiooni valijate nimekirjast. .. _check-nimekirjatunnus-correctness: NIMEKIRJATUNNUS, vormingu korrektsus ```````````````````````````````````` Nimekirjatunnuse vormingu korrektsuse kontroll käesoleva spetsifikatsiooni suhtes. .. _check-nimekirjatunnus-consistency-protocol-settings: NIMEKIRJATUNNUS, protokollikohane kooskõlalisus valimise seadistusega ````````````````````````````````````````````````````````````````````` Nimekirjatunnuse protokollikohase kooskõlalisuse kontroll valimise seadistusega. Kontroll õnnestub kui valimise seadistuses sisalduvate muudatusnimekirjade alusel on võimalik koostada nimekirjatunnusele vastav nimekiri. .. _entity-miksitud-krypteeritud-sedel: ``````````````````````````` MIKSITUD KRÜPTEERITUD SEDEL ``````````````````````````` Olem moodustatakse miksimisrakenduses. Miksitud krüpteeritud sedel on sisuliselt krüpteeritud sedel ning rakenduvad samad kontrollid, mis krüpteeritud sedelilegi. .. _check-miksitud-krypteeritud-sedel-correctness: MIKSITUD KRÜPTEERITUD SEDEL, vormingu korrektsus ```````````````````````````````````````````````` Miksitud krüpteeritud sedeli vormingu korrektsuse kontroll käesoleva spetsifikatsiooni suhtes. .. _check-miksitud-krypteeritud-sedel-public-key-consistency: MIKSITUD KRÜPTEERITUD SEDEL, kooskõlalisus avaliku võtmega `````````````````````````````````````````````````````````` Miksitud krüpteeritud sedeli kooskõlalisuse kontroll avaliku võtmega. Kontroll õnnestub kui miksitud krüpteeritud sedeli komponendid on kasutatavad rühma liikmetena arvutusteks avaliku võtme parameetrite poolt määratud matemaatilises rühmas. .. _entity-ringkonnatunnus: ``````````````` RINGKONNATUNNUS ``````````````` Olem moodustatakse töötlemisrakenduses ning viitab ringkonnapõhisele valikute nimekirjale. .. _check-ringkonnatunnus-correctness: RINGKONNATUNNUS, vormingu korrektsus ```````````````````````````````````` Ringkonnatunnuse vormingu korrektsuse kontroll käesoleva spetsifikatsiooni suhtes. .. _entity-ringkonna-valikutenimekiri: ````````````````````````````````` RINGKONNAPÕHINE VALIKUTE NIMEKIRI ````````````````````````````````` Olem on valijale omistatud süsteemiväliselt. .. _check-ringkonna-valikutenimekiri-correctness: RINGKONNAPÕHINE VALIKUTE NIMEKIRI, vormingu korrektsus `````````````````````````````````````````````````````` Ringkonnapõhise valikute nimekirja vormingu korrektsuse kontroll VIS liideste spetsifikatsiooni suhtes. Kontrollid kogumisteenuses -------------------------- Kogumisteenus käsitleb talletatavat häält sõltumatult teistest häältest. Kogumisteenuse ülesandeks on hääle talletamine kogu hääletamisperioodi vältel ja häälele töötlemise käigus kvalifitseerumiseks vajalike elementide hankimine. Kogumisteenus saab valijarakenduselt järgmised olemid: #. :ref:`entity-krypteeritud-sedel` #. :ref:`entity-valija-sertifikaat` #. :ref:`entity-valija-identiteet` #. :ref:`entity-haale-signatuur` #. :ref:`entity-haale-allkiri` #. :ref:`entity-haale-konteiner` Kogumisteenus hangib hääle töötlemise käigus välistelt teenustelt järgmised olemid: #. :ref:`entity-kehtivuskinnitus` #. :ref:`entity-ajatempel` #. :ref:`entity-registreerimistoend` Kogumisteenus tuvastab / loob ise järgmised olemid: #. :ref:`entity-registreerimisparing` #. :ref:`entity-registreerimisparing-konteiner` #. :ref:`entity-nimekirjatunnus` #. :ref:`entity-ringkonnatunnus` #. :ref:`entity-ringkonna-valikutenimekiri` Kogumisteenus ei puutu vahetult kokku järgmiste olemitega: #. :ref:`entity-tahteavaldus` #. :ref:`entity-juhuslikkus` #. :ref:`entity-miksitud-krypteeritud-sedel` Kogumisteenus viib läbi järgmised tegevused ja teostab järgmised kontrollid: #. Hääle talletamise päringu vastuvõtmine valijarakenduselt #. :ref:`check-valija-sertifikaat-correctness` #. :ref:`check-valija-sertifikaat-consistency-protocol-settings` #. :ref:`check-valija-identiteet-correctness` #. :ref:`check-valija-identiteet-nimekirjatunnus-eligibility` #. :ref:`check-haale-signatuur-correctness` #. :ref:`check-haale-signatuur-krypteeritud-sedel-valija-sertifikaat-consistency` #. :ref:`check-haale-allkiri-correctness` #. :ref:`check-haale-allkiri-haale-signatuur-consistency` #. :ref:`check-haale-konteiner-correctness` #. :ref:`check-haale-konteiner-haale-allkiri-valija-sertifikaat-krypteeritud-sedel-consistency` #. :ref:`check-krypteeritud-sedel-correctness` #. :ref:`check-krypteeritud-sedel-public-key-consistency` #. Kehtivuskinnituse hankimine - :ref:`entity-kehtivuskinnitus` #. :ref:`check-kehtivuskinnitus-correctness` #. :ref:`check-valija-sertifikaat-kehtivuskinnitus-consistency` #. Ajatempli hankimine - :ref:`entity-ajatempel` #. :ref:`check-ajatempel-correctness` #. :ref:`check-ajatempel-consistency-protocol-settings` #. Registreerimispäringu loomine - :ref:`entity-registreerimisparing` #. Registreerimistõendi hankimine - :ref:`entity-registreerimistoend` #. :ref:`check-registreerimisparing-registreerimistoend-consistency` #. :ref:`check-registreerimistoend-correctness` #. :ref:`check-registreerimistoend-haale-allkiri-consistency` #. :ref:`check-kehtivuskinnitus-ajatempel-order` #. Hääle talletamine, kvalifitseerivate elementide ja unikaalse identifikaatori tagastamine valijarakendusele. Kontrollid valijarakenduses --------------------------- Valijarakendus moodustab valija avakujul tahteavalduse põhjal krüpteeritud sedeli ning allkirjastab selle valija allkirja andmise vahendiga. Valijarakenduse rolliks peale hääle allkirjastamist on veenduda, et kogumisteenus käitus häält kvalifitseerivate elementide võtmisel protokollikohaselt ning et hääl on talletatud selliselt, et ta saab töötlemisrakenduse poolt arvesse võetud. Valijarakendus viib läbi minimaalselt järgmised kontrollid: #. Kogumisteenus võttis kehtivuskinnituse valija sertifikaadile volitatud kehtivuskinnitusteenuselt. Valijarakendus kontrollib allkirja kehtivuskinnitusteenuse vastusel. #. Kogumisteenus registreeris valija poolt allkirjastatud hääle volitatud registreerimisteenuses. Valijarakendus kontrollib, et kogumisteenuse poolt moodustatud päring oli kogumisteenuse poolt signeeritud ning viitas korrektselt allkirjastatud häälele. Valijarakendus kontrollib, et registreerimisteenuse vastus on allkirjastatud õige registreerimisteenuse osutaja poolt ning sisaldab kogumisteenuse poolt allkirjastatud päringut. Kui hääle kvalifitseerimiseks vajalike elementide kontroll ei õnnestu, siis teavitab valijarakendus sellest kasutajat. Valijarakendus loob ise järgmised olemid: #. :ref:`entity-tahteavaldus` #. :ref:`entity-juhuslikkus` #. :ref:`entity-krypteeritud-sedel` #. :ref:`entity-haale-allkiri` #. :ref:`entity-haale-konteiner` Valijarakendus saab järgmised olemid teistelt osapooltelt: #. :ref:`entity-valija-sertifikaat` #. :ref:`entity-valija-identiteet` #. :ref:`entity-ringkonna-valikutenimekiri` #. :ref:`entity-haale-signatuur` #. :ref:`entity-kehtivuskinnitus` #. :ref:`entity-ajatempel` #. :ref:`entity-registreerimistoend` #. :ref:`entity-registreerimisparing` Valijarakendus ei puutu vahetult kokku järgmiste olemitega: #. :ref:`entity-registreerimisparing-konteiner` #. :ref:`entity-nimekirjatunnus` #. :ref:`entity-ringkonnatunnus` #. :ref:`entity-miksitud-krypteeritud-sedel` Valijarakendus viib läbi järgmised tegevused ja teostab järgmised kontrollid: #. eID vahendi aktiveerimine ja valija identiteedi tuvastamine #. :ref:`entity-valija-sertifikaat` #. :ref:`entity-valija-identiteet` #. :ref:`check-valija-sertifikaat-correctness` #. :ref:`check-valija-sertifikaat-consistency-protocol-settings` #. :ref:`check-valija-identiteet-correctness` #. Ringkonnapõhise valikutenimekirja tuvastamine - :ref:`entity-ringkonna-valikutenimekiri` #. Tahteavalduse moodustamine - :ref:`entity-tahteavaldus` #. Juhuarvu genereerimine - :ref:`entity-juhuslikkus` #. Sedeli krüpteerimine - :ref:`entity-krypteeritud-sedel` #. Krüpteeritud sedeli signeerimine - :ref:`entity-haale-signatuur` #. Allkirja moodustamine signatuurist - :ref:`entity-haale-allkiri` #. :ref:`check-haale-signatuur-correctness` #. :ref:`check-haale-signatuur-krypteeritud-sedel-valija-sertifikaat-consistency` #. Allkirjastatud konteineri moodustamine - :ref:`entity-haale-konteiner` #. Allkirjastatud konteineri edastamine kogumisteenusele. #. Kogumisteenuse vastuse kontrollimine #. :ref:`entity-kehtivuskinnitus` #. :ref:`entity-ajatempel` #. :ref:`entity-registreerimistoend` #. :ref:`entity-registreerimisparing` #. :ref:`check-kehtivuskinnitus-correctness` #. :ref:`check-valija-sertifikaat-kehtivuskinnitus-consistency` #. :ref:`check-ajatempel-correctness` #. :ref:`check-ajatempel-consistency-protocol-settings` #. :ref:`check-kehtivuskinnitus-ajatempel-order` #. :ref:`check-registreerimisparing-correctness` #. :ref:`check-registreerimisparing-haale-allkiri-consistency` #. :ref:`check-registreerimisparing-registreerimistoend-consistency` #. :ref:`check-registreerimistoend-correctness` #. :ref:`check-registreerimistoend-haale-allkiri-consistency` Kontrollid kontrollrakenduses ----------------------------- Sarnaselt valijarakendusele on kontrollrakenduse rolliks peale hääle allkirjastamist veenduda, et kogumisteenus käitus häält kvalifitseerivate elementide võtmisel protokollikohaselt ning et hääl on talletatud selliselt, et ta saab töötlemisrakenduse poolt arvesse võetud. Täiendavalt on kontrollrakenduse ülesandeks anda valijale tagasisidet, kas tema tahteavaldus sai valijarakenduse poolt korrektselt hääleks vormistatud. Kui hääle kvalifitseerimiseks vajalike elementide kontroll ei õnnestu, siis teavitab kontrollrakendus sellest kasutajat. Tahteavalduse korrektsuses peab valija ise veenduma. Kontrollrakendus tuvastab ise järgmised olemid: #. :ref:`entity-tahteavaldus` Kontrollrakendus saab järgmised olemid teistelt osapooltelt: #. :ref:`entity-juhuslikkus` #. :ref:`entity-krypteeritud-sedel` #. :ref:`entity-valija-sertifikaat` #. :ref:`entity-valija-identiteet` #. :ref:`entity-haale-signatuur` #. :ref:`entity-haale-allkiri` #. :ref:`entity-haale-konteiner` #. :ref:`entity-kehtivuskinnitus` #. :ref:`entity-ajatempel` #. :ref:`entity-registreerimistoend` #. :ref:`entity-registreerimisparing` #. :ref:`entity-ringkonna-valikutenimekiri` Kontrollrakendus ei puutu vahetult kokku järgmiste olemitega: #. :ref:`entity-registreerimisparing-konteiner` #. :ref:`entity-nimekirjatunnus` #. :ref:`entity-ringkonnatunnus` #. :ref:`entity-miksitud-krypteeritud-sedel` Kontrollrakendus viib läbi järgmised tegevused ja teostab järgmised kontrollid: #. :ref:`check-valija-sertifikaat-correctness` #. :ref:`check-valija-sertifikaat-consistency-protocol-settings` #. :ref:`check-valija-sertifikaat-kehtivuskinnitus-consistency` #. :ref:`check-valija-identiteet-correctness` #. :ref:`check-haale-signatuur-correctness` #. :ref:`check-haale-signatuur-krypteeritud-sedel-valija-sertifikaat-consistency` #. :ref:`check-haale-allkiri-correctness` #. :ref:`check-haale-allkiri-haale-signatuur-consistency` #. :ref:`check-haale-konteiner-correctness` #. :ref:`check-haale-konteiner-haale-allkiri-valija-sertifikaat-krypteeritud-sedel-consistency` #. :ref:`check-kehtivuskinnitus-correctness` #. :ref:`check-ajatempel-correctness` #. :ref:`check-ajatempel-consistency-protocol-settings` #. :ref:`check-kehtivuskinnitus-ajatempel-order` #. :ref:`check-registreerimisparing-correctness` #. :ref:`check-registreerimisparing-haale-allkiri-consistency` #. :ref:`check-registreerimisparing-registreerimistoend-consistency` #. :ref:`check-registreerimistoend-correctness` #. :ref:`check-registreerimistoend-haale-allkiri-consistency` #. :ref:`check-ringkonna-valikutenimekiri-correctness` #. :ref:`check-juhuslikkus-correctness` #. :ref:`check-juhuslikkus-public-key-consistency` #. :ref:`check-krypteeritud-sedel-correctness` #. :ref:`check-krypteeritud-sedel-public-key-consistency` #. :ref:`check-krypteeritud-sedel-juhuslikkus-consistency` #. :ref:`check-tahteavaldus-correctness` #. :ref:`check-tahteavaldus-ringkonna-valikutenimekiri-consistency` Kontrollid töötlemisrakenduses ------------------------------ Töötlemisrakenduse sisendiks on e-valimiskast ja registreerimisteenuse väljavõte registreerimispäringutest. Töötlemisrakendus kontrollib mõlema andmehulga elemente kõigepealt eraldi ning seejärel püüab luua vastavuse nende vahel. Töötlemisrakendus otsustab, milline valija häältest oli viimane ning liigub töötlemise järgmisesse etappi. S.t. üks häält kvalifitseerivatest elementidest täidab hääle talletamise aja fikseerimise rolli ning selle elemendi põhjal moodustatakse üksikute häälte ajaline järgnevus. Olenevalt IVXV profiilist võib see element olla kehtivuskinnituse koosseisus (BDOC-TM), eraldi ajatemplina (BDOC-TS) või registreerimistõendi koosseisus (BDOC-TS). Töötlemisrakendusele tehakse kättesaadavaks järgmised olemid: #. :ref:`entity-krypteeritud-sedel` #. :ref:`entity-valija-sertifikaat` #. :ref:`entity-valija-identiteet` #. :ref:`entity-haale-signatuur` #. :ref:`entity-haale-allkiri` #. :ref:`entity-haale-konteiner` #. :ref:`entity-kehtivuskinnitus` #. :ref:`entity-ajatempel` #. :ref:`entity-registreerimisparing` #. :ref:`entity-registreerimisparing-konteiner` #. :ref:`entity-registreerimistoend` #. :ref:`entity-nimekirjatunnus` #. :ref:`entity-ringkonna-valikutenimekiri` Töötlemisrakendus tuvastab/loob järgmised olemid: #. :ref:`entity-ringkonnatunnus` Töötlemisrakendus ei puutu vahetult kokku järgmiste olemitega: #. :ref:`entity-miksitud-krypteeritud-sedel` #. :ref:`entity-tahteavaldus` #. :ref:`entity-juhuslikkus` Töötlemisrakenduse töö jaguneb neljaks etapiks: #. Kontrollimine #. Korduvhäälte eemaldamine #. Tühistamine/-ennistamine #. Anonüümimine Töötlemisrakendus teostab kontrollimise etapis järgmised kontrollid: #. e-valimiskasti elementide kontrollid teostatakse kõigi hääle elementide kohta: #. :ref:`check-valija-sertifikaat-correctness` #. :ref:`check-valija-sertifikaat-consistency-protocol-settings` #. :ref:`check-valija-identiteet-correctness` #. :ref:`check-nimekirjatunnus-correctness` #. :ref:`check-nimekirjatunnus-consistency-protocol-settings` #. :ref:`check-valija-identiteet-nimekirjatunnus-eligibility` #. :ref:`check-ringkonnatunnus-correctness` #. :ref:`check-haale-signatuur-correctness` #. :ref:`check-haale-signatuur-krypteeritud-sedel-valija-sertifikaat-consistency` #. :ref:`check-haale-allkiri-correctness` #. :ref:`check-haale-allkiri-haale-signatuur-consistency` #. :ref:`check-haale-konteiner-correctness` #. :ref:`check-haale-konteiner-haale-allkiri-valija-sertifikaat-krypteeritud-sedel-consistency` #. :ref:`check-kehtivuskinnitus-correctness` #. :ref:`check-valija-sertifikaat-kehtivuskinnitus-consistency` #. :ref:`check-ajatempel-correctness` #. :ref:`check-ajatempel-consistency-protocol-settings` #. :ref:`check-kehtivuskinnitus-ajatempel-order` #. :ref:`check-registreerimistoend-correctness` #. :ref:`check-registreerimistoend-haale-allkiri-consistency` #. registreerimisteenuse väljavõtte kontrollid teostatakse iga registreerimispäringu kohta #. :ref:`check-registreerimisparing-correctness` #. :ref:`check-registreerimisparing-konteiner-correctness` #. :ref:`check-registreerimisparing-konteiner-registreerimispäring-consistency` #. Töötlemisrakendus loob vastavuse e-valimiskasti ja registreerimisteenuse väljavõtte vahel võttes aluseks olemi :ref:`entity-registreerimisparing-konteiner` registreerimisteenuse väljavõttest ning olemi :ref:`entity-registreerimistoend` e-valimiskastist. Ühendavaks lüliks kahe vaate vahel on :ref:`entity-registreerimisparing`. #. e-valimiskasti ja registreerimisteenuse väljavõtte vastavuskontrollid #. :ref:`check-registreerimisparing-haale-allkiri-consistency` #. :ref:`check-registreerimisparing-registreerimistoend-consistency` Töötlemisrakendus teostab korduvhäälte eemaldamise etapis järgmised kontrollid: #. Töötlemisrakendus tuvastab iga valija häälte hulgast ajaliselt viimase. #. Töötlemisrakendus viib läbi krüpteeritud sedeli korrektsuse kontrollid. #. :ref:`check-krypteeritud-sedel-correctness` #. :ref:`check-krypteeritud-sedel-public-key-consistency` Töötlemisrakenduse töö järgmistes etappides täiendavaid kontrolle ei teostata. Tühistamis-/ennistamisetapis eemaldatakse/taastatakse isikukoodile vastavaid hääli korduvhäältest puhastatud e-valimiskastist. Anonüümimisetapis eemaldatakse e-häältelt kvalifitseerivad elemendid ning saadud loend krüpteeritud sedelitest suunatakse miksimisrakendusse. Kontrollid miksimisrakenduses ----------------------------- Miksimisrakendusele tehakse kättesaadavaks järgmised olemid: #. :ref:`entity-krypteeritud-sedel` #. :ref:`entity-ringkonnatunnus` Miksimisrakendus loob järgmised olemid: #. :ref:`entity-miksitud-krypteeritud-sedel` Miksimisrakendus ei puutu vahetult kokku järgmiste olemitega: #. :ref:`entity-tahteavaldus` #. :ref:`entity-juhuslikkus` #. :ref:`entity-valija-sertifikaat` #. :ref:`entity-valija-identiteet` #. :ref:`entity-haale-signatuur` #. :ref:`entity-haale-allkiri` #. :ref:`entity-haale-konteiner` #. :ref:`entity-kehtivuskinnitus` #. :ref:`entity-ajatempel` #. :ref:`entity-registreerimisparing` #. :ref:`entity-registreerimisparing-konteiner` #. :ref:`entity-registreerimistoend` #. :ref:`entity-nimekirjatunnus` #. :ref:`entity-ringkonna-valikutenimekiri` Miksimisrakendus viib läbi järgmised tegevused ja kontrollid: #. :ref:`check-ringkonnatunnus-correctness` #. :ref:`check-krypteeritud-sedel-correctness` #. :ref:`check-krypteeritud-sedel-public-key-consistency` #. Miksimisrakendus grupeerib sisendiks antud krüpteeritud sedelid ringkonnatunnuste kaupa ning järjestab krüpteeritud sedelid ringkonnas ringi. #. Miksimisrakendus arvutab iga ümberjärjestatud krüpteeritud sedeli kohta uue miksitud krüpteeritud sedeli. #. Miksimisrakendus koostab nullteadmustõestused sedelite korrektse miksimise kohta. Kontrollid võtmerakenduses -------------------------- Võtmerakendusele tehakse kättesaadavaks järgmised olemid: #. :ref:`entity-miksitud-krypteeritud-sedel` #. :ref:`entity-ringkonnatunnus` #. :ref:`entity-ringkonna-valikutenimekiri` Võtmerakendus tuvastab järgmised olemid: #. :ref:`entity-tahteavaldus` Võtmerakendus ei puutu vahetult kokku järgmiste olemitega: #. :ref:`entity-juhuslikkus` #. :ref:`entity-krypteeritud-sedel` #. :ref:`entity-valija-sertifikaat` #. :ref:`entity-valija-identiteet` #. :ref:`entity-haale-signatuur` #. :ref:`entity-haale-allkiri` #. :ref:`entity-haale-konteiner` #. :ref:`entity-kehtivuskinnitus` #. :ref:`entity-ajatempel` #. :ref:`entity-registreerimisparing` #. :ref:`entity-registreerimisparing-konteiner` #. :ref:`entity-registreerimistoend` #. :ref:`entity-nimekirjatunnus` Võtmerakendus viib läbi järgmised tegevused ja kontrollid: #. :ref:`check-miksitud-krypteeritud-sedel-correctness` #. :ref:`check-miksitud-krypteeritud-sedel-public-key-consistency` #. Häälte dekrüpteerimine #. :ref:`check-ringkonnatunnus-correctness` #. :ref:`check-tahteavaldus-correctness` #. :ref:`check-tahteavaldus-ringkonnatunnus-valikutenimekiri-consistency` ================================================ FILE: Documentation/public/protokollid/08-haaletamine.rst ================================================ .. IVXV protokollid =================== Suhtlusprotokollid =================== Liides ------ Kogumisteenuse valijale suunatud mikroteenused suhtlevad valijarakendusega ja kontrollrakendusega JSON-RPC protokolli vahendusel. :id: JSON-RPC päringuidentifikaator :method: RPC-meetod :params: Konkreetse RPC-meetodi parameetrid .. literalinclude:: ../../common/examples/json.rpc.method.query.json :language: json :linenos: :error: Võimalik veainfo või ``null`` vea puudumisel :id: JSON-RPC päringuidentifikaator, peab ühtima päringus kasutatud id'ga :result: Meetodipõhine vastusandmestruktuur .. literalinclude:: ../../common/examples/json.rpc.method.response.json :language: json :linenos: Esimese päringuvahetuse käigus mõne IVXV mikroteenusega väljastatakse suhtlevale rakendusele HEX-kodeeritud unikaalne seansiidentifikaator (``result.SessionID``), mida rakendus kasutab edaspidi kõigis kogumisteenuse suunalistes päringutes (``params.SessionID``). Seansiidentifikaatori abil seostatakse hääletamisega seotud RPC-päringud üheks seansiks. Seostamine on informatiivne ning selle eesmärk on logianalüüsi lihtsustamine, hääle ringkonnakuuluvust jm. sisulisi aspekte puudutavad otsused tehakse digiallkirjastatud andmete põhjal. Transpordiprotokollina on kasutusel TLS. Krüpteeritud kanali termineerimine toimub konkreetses mikroteenuses. Võimaldamaks koormuse jaotamist ning mikroteenuste paindlikku evitamist kasutatakse TLS-SNI laiendust, mis lubab vahendusteenusel TLS voogu termineerimata õigesse mikroteenusinstantsi suunata. Vahendusteenus on tüüpiliselt kättesaadav kogumisteenuse välise liidese pordis 443. Valikute nimekirja hankimine ---------------------------- Valikute nimekirja hankimine tähendab valijarakenduse suhtlemist nimekirjateenusega (SNI ``choices.ivxv.invalid``). Valikute nimekirja hankimine eeldab valija autentimist ning tema ringkonnakuuluvuse tuvastamist. Valijarakendus teeb päringu ``RPC.VoterChoices`` nimekirjade hankimiseks. :params.AuthMethod: Toetatud valikud on meetodid ``tls`` ja ``ticket``. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. Päring ``RPC.VoterChoices`` ID-kaardiga autentimise korral - autentimine toimub TLS-protokolli tasemel päringu töötlemise ajal kasutades ID-kaardi autentimissertifikaati. .. literalinclude:: ../../common/examples/id.rpc.voterchoices.query.json :language: json :linenos: Päring ``RPC.VoterChoices`` Mobiil-ID'ga autentimise korral - päringu sooritamiseks tuleb eelnevalt kasutada Mobiil-ID vahendusteenuse (SNI ``mid.ivxv.invalid``) abi allkirjastatud autentimistõendi saamiseks. :params.AuthToken: Autentimisteenuse vahendusel allkirjastatud tõend, mis sisaldab endas valija unikaalset identifikaatorit. :params.SessionID: Kuna Mobiil-ID korral on nimekirja hankimisele eelnenud interaktsioon autentimistõendi saamiseks, on olemas seansiidentifikaator, mida tuleb kasutada. .. literalinclude:: ../../common/examples/mid.rpc.voterchoices.query.json :language: json :linenos: Päring ``RPC.VoterChoices`` Smart-ID'ga autentimise korral - päringu sooritamiseks tuleb eelnevalt kasutada Smart-ID vahendusteenuse (SNI ``smartid.ivxv.invalid``) abi allkirjastatud autentimistõendi saamiseks. :params.AuthToken: Autentimisteenuse vahendusel allkirjastatud tõend, mis sisaldab endas valija unikaalset identifikaatorit. :params.SessionID: Kuna Smart-ID korral on nimekirja hankimisele eelnenud interaktsioon autentimistõendi saamiseks, on olemas seansiidentifikaator, mida tuleb kasutada. .. literalinclude:: ../../common/examples/smartid.rpc.voterchoices.query.json :language: json :linenos: Päring ``RPC.VoterChoices`` Web eID'ga autentimise korral - päringu sooritamiseks tuleb eelnevalt kasutada Web eID vahendusteenuse (SNI ``webeid.ivxv.invalid``) abi allkirjastatud autentimistõendi saamiseks. :params.AuthToken: Autentimisteenuse vahendusel allkirjastatud tõend, mis sisaldab endas valija unikaalset identifikaatorit. :params.SessionID: Kuna Web eID korral on nimekirja hankimisele eelnenud interaktsioon autentimistõendi saamiseks, on olemas seansiidentifikaator, mida tuleb kasutada. .. literalinclude:: ../../common/examples/webeid.rpc.voterchoices.query.json :language: json :linenos: Nimekirjateenuse vastus päringule ``RPC.VoterChoices``. :result.Choices: Valija ringkonnakuuluvuse identifikaator ``VoterDistrict`` :result.List: BASE64-kodeeritud ringkonna valikute nimekiri ``DistrictChoices`` :result.Voted: Kui valija on juba hääletanud, siis ``true``, vastasel juhul seda välja vastuses ei ole. .. literalinclude:: ../../common/examples/id.rpc.voterchoices.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.VoterChoices`` korral. :BAD_CERTIFICATE: Viga valija isikutuvastussertifikaadiga. :BAD_REQUEST: Vigane päring. :INELIGIBLE_VOTER: Valijal pole õigust hääletada. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :UNAUTHENTICATED: Autentimata päring. :VOTER_TOO_YOUNG: Valija on liiga noor. :VOTING_END: Hääletusperiood on lõppenud. Allkirjastatud hääle saatmine talletamiseks ------------------------------------------- Allkirjastatud hääle saatmine talletamiseks tähendab valijarakenduse suhtlemist hääletamisteenusega (SNI ``voting.ivxv.invalid``). Valijarakendus teeb päringu ``RPC.Vote`` allkirjastatud hääle talletamiseks saatmiseks. :params.AuthMethod: Toetatud valikud on meetodid ``tls`` ja ``ticket``. :params.Choices: Valija ringkonnakuuluvuse identifikaator ``VoterDistrict`` mis kehtis valikute nimekirja hankimise ajal. Parameetri korrektne kasutamine võimaldab kogumisteenusel valijat hoiatada kui tema ringkonnakuuluvus on võrreldes hääletamise algushetkega muutunud. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. :params.Type: Allkirjastatud hääle vorming. Hetkel on ainus toetatud väärtus ``bdoc``. :params.Vote: BASE64-kodeeritud hääl ``SignedVote`` eelpoolmääratud vormingus (:ref:`signed-vote`). Päring ``RPC.Vote`` ID-kaardiga autentimise korral. .. literalinclude:: ../../common/examples/id.rpc.vote.query.json :language: json :linenos: Päring ``RPC.Vote`` Mobiil-ID'ga autentimise korral. .. literalinclude:: ../../common/examples/mid.rpc.vote.query.json :language: json :linenos: Päring ``RPC.Vote`` Smart-ID'ga autentimise korral. .. literalinclude:: ../../common/examples/smartid.rpc.vote.query.json :language: json :linenos: Päring ``RPC.Vote`` Web eID'ga autentimise korral. .. literalinclude:: ../../common/examples/webeid.rpc.vote.query.json :language: json :linenos: Hääletamisteenuse vastus päringule ``RPC.Vote``. :result.Qualification.ocsp: :result.Qualification.tspreg: Kogumisteenuse poolt hangitud täiendavad tõendid valijarakenduse poolt loodud hääle ``SignedVote`` (:ref:`signed-vote`) kvalifitseerimiseks ning korrektseks registreerimiseks. Vastuse koosseis sõltub kogumisteenuse konkreetsest seadistusest, antud juhul kasutatakse standardset OCSP protokolli valija allkirjasertifikaadi kehtivuse kontrolliks ning PKIX ajatempliprotokolli põhist registreerimisteenust nii hääle andmise aja fikseerimiseks kui elektroonilise hääle registreerimiseks välises sõltumatus teenuses. Valijarakendusele kontrollimiseks edastatakse nii OCSP vastus kui PKIX vormingus ajatempel koos registreerimisteenusele vajalike täiendustega. :result.TestVote: Kui hääl esitati enne hääletamise algust ning läks arvesse proovihäälena, siis ``true``, vastasel juhul seda välja vastuses ei ole. Valijarakendus kuvab valijale proovihääle korral sellekohase hoiatuse. :result.VoteID: Hääle identifikaator talletusteenuses, mille alusel on kontrollrakendusel võimalik häält hilisemaks analüüsiks välja nõuda. .. literalinclude:: ../../common/examples/id.rpc.vote.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.Vote`` korral. :BAD_CERTIFICATE: Viga valija isikutuvastus- või allkirjastamissertifikaadiga. :BAD_REQUEST: Vigane päring. :IDENTITY_MISMATCH: Isikutuvastus- ning allkirjastamissertifikaadi isikukoodid ei kattu. :INELIGIBLE_VOTER: Valijal pole õigust hääletada. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :OUTDATED_CHOICES: Valija ringkonnakuuluvus on nimekirja hankimisest muutunud. :UNAUTHENTICATED: Autentimata päring. :VOTER_TOO_YOUNG: Valija on liiga noor. :VOTING_END: Hääletusperiood on lõppenud. Hääletamine Mobiil-ID'ga ------------------------ Mobiil-ID kasutamine allkirjastamis- ning autentimisvahendina tingib Mobiil-ID teenusega liidestuva abiteenuse (SNI ``mid.ivxv.invalid``) kasutamise autentimistõendi hankimiseks enne valikute nimekirja hankimist ning hääle allkirjastamiseks enne talletamist. Autentimistõendi hankimine ************************** Valijarakendus teeb päringu ``RPC.Authenticate`` Mobiil-ID autentimise algatamiseks. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. :params.IDCode: Mobiil-ID kasutaja isikukood. :params.PhoneNo: Mobiil-ID kasutaja telefoninumber. .. literalinclude:: ../../common/examples/mid.rpc.authenticate.query.json :language: json :linenos: :result.Challenge: Räsi, millest arvutada Mobiil-ID kontrollkood valijarakenduses kuvamiseks :result.SessionCode: Mobiil-ID seansiidentifikaator edasiste poll-päringute jaoks .. literalinclude:: ../../common/examples/mid.rpc.authenticate.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.Authenticate`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :VOTING_END: Hääletusperiood on lõppenud. Valijarakendus teeb päringu ``RPC.AuthenticateStatus`` autentimisprotsessi oleku hindamiseks. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. :params.SessionCode: Autentimisseansi identifikaator .. literalinclude:: ../../common/examples/mid.rpc.authenticatestatus.query.json :language: json :linenos: :result.AuthToken: Autentimistõend teistele IVXV teenustele esitamiseks või ``null``, kui päringu töötlemine alles käib. :result.GivenName: Eduka autentimise korral valija eesnimi :result.PersonalCode: Eduka autentimise korral valija isikukood :result.Status: Päringu staatus - ``POLL`` viitab vajadusele päringut korrata, ``OK`` viitab edukale autentimisele. Vastuse muud väljad sisaldavad infot vaid siis kui väärtus on ``OK``. :result.Surname: Eduka autentimise korral valija perekonnanimi .. literalinclude:: ../../common/examples/mid.rpc.authenticatestatus.response.json :language: json :linenos: .. literalinclude:: ../../common/examples/mid.rpc.authenticatestatus2.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.AuthenticateStatus`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :MID_BAD_CERTIFICATE: Viga valija Mobiil-ID isikutuvastussertifikaadiga. :MID_NOT_USER: Telefoninumber ei kuulu Mobiil-ID kliendile. :MID_OPERATOR: Probleem valija mobiiltelefoni SIM kaardiga, mille lahendamiseks tuleb pöörduda mobiilioperaatori poole. :MID_ABSENT: Valija mobiiltelefon ei ole kättesaadav. :MID_CANCELED: Valija katkestas Mobiil-ID seansi. :MID_EXPIRED: Mobiil-ID seanss on aegunud. :MID_GENERAL: Viga Mobiil-ID teenuse töös. :VOTING_END: Hääletusperiood on lõppenud. Hääle allkirjastamine ********************* Valijarakendus teeb päringu ``RPC.GetCertificate`` allkirjastamissertifikaadi hankimiseks. :params.AuthMethod: Toetatud ainult autentimismeetod ``ticket``. :params.AuthToken: Mobiil-ID autentimistõend. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. :params.PhoneNo: Hääle allkirjastaja telefoninumber .. literalinclude:: ../../common/examples/mid.rpc.getcertificate.query.json :language: json :linenos: :result.Certificate: Allkirjastamissertifikaat X509-vormingus .. literalinclude:: ../../common/examples/mid.rpc.getcertificate.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.GetCertificate`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :MID_BAD_CERTIFICATE: Viga valija Mobiil-ID allkirjastamissertifikaadiga. :MID_GENERAL: Viga Mobiil-ID teenuse töös. :MID_NOT_USER: Telefoninumber ei kuulu Mobiil-ID kliendile. :VOTING_END: Hääletusperiood on lõppenud. Valijarakendus teeb päringu ``RPC.Sign`` hääle allkirjastamise algatamiseks. Mobiil-ID kontrollkoodi arvutab valijarakendus andmevälja ``Hash`` väärtusest. :params.AuthMethod: Toetatud ainult autentimismeetod ``ticket``. :params.AuthToken: Mobiil-ID autentimistõend. :params.Hash: BASE64-kodeeritud elektroonilise hääle räsi :params.HashType: Räsifunktsiooni nimi Mobiil-ID teenusele edastamiseks, kas ``SHA256``, ``SHA384`` või ``SHA512`` :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. :params.PhoneNo: Hääle allkirjastaja telefoninumber .. literalinclude:: ../../common/examples/mid.rpc.sign.query.json :language: json :linenos: :result.SessionCode: Mobiil-ID seansiidentifikaator edasiste poll-päringute jaoks. .. literalinclude:: ../../common/examples/mid.rpc.sign.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.Sign`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :VOTING_END: Hääletusperiood on lõppenud. Valijarakendus teeb päringu ``RPC.SignStatus`` allkirjastamisprotsessi seisundi hindamiseks. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. :params.SessionCode: Mobiil-ID seansiidentifikaator .. literalinclude:: ../../common/examples/mid.rpc.signstatus.query.json :language: json :linenos: :result.Signature: Juhul kui vastuse ``Status`` väli on ``OK``, BASE-64 kodeeritud PKCS1-vormingus signatuur, vastasel juhul ``null``. :result.Algorithm: Juhul kui vastuse ``Status`` väli on ``OK``, Mobiil-ID teenuse poolt tagastatud signatuuri algoritm. Võimalikud väärtused on ``SHA256WithECEncryption``, ``SHA256WithRSAEncryption``, ``SHA384WithECEncryption``, ``SHA384WithRSAEncryption``, ``SHA512WithECEncryption`` ja ``SHA512WithRSAEncryption``. :result.Status: Päringu staatus - ``POLL`` viitab vajadusele päringut korrata, ``OK`` viitab edukale allkirjastamisele. Vastuse muud väljad sisaldavad infot vaid siis kui väärtus on ``OK``. .. literalinclude:: ../../common/examples/mid.rpc.signstatus.response.json :language: json :linenos: .. literalinclude:: ../../common/examples/mid.rpc.signstatus2.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.SignStatus`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :MID_ABSENT: Valija mobiiltelefon ei ole kättesaadav. :MID_BAD_CERTIFICATE: Viga valija Mobiil-ID allkirjastamissertifikaadiga. :MID_OPERATOR: Probleem valija mobiiltelefoni SIM kaardiga, mille lahendamiseks tuleb pöörduda mobiilioperaatori poole. :MID_CANCELED: Valija katkestas Mobiil-ID seansi. :MID_EXPIRED: Mobiil-ID seanss on aegunud. :MID_GENERAL: Viga Mobiil-ID teenuse töös. :VOTING_END: Hääletusperiood on lõppenud. Hääletamine Smart-ID'ga ------------------------ Smart-ID kasutamine allkirjastamis- ning autentimisvahendina tingib Smart-ID teenusega liidestuva abiteenuse (SNI ``smartid.ivxv.invalid``) kasutamise autentimistõendi hankimiseks enne valikute nimekirja hankimist ning hääle allkirjastamiseks enne talletamist. Autentimistõendi hankimine ************************** Valijarakendus teeb päringu ``RPC.Challenge`` Smart-ID kontrollkoodi hankimiseks. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. .. literalinclude:: ../../common/examples/smartid.rpc.challenge.query.json :language: json :linenos: :result.Challenge: Räsi, millest arvutada Smart-ID kontrollkood valijarakenduses kuvamiseks :result.XSmartIDAuth: Päringu küpsis, kus talletatakse Smart-ID kontrollkoodi räsi, selle eluea ajatempel ja seansiidentifikaator .. literalinclude:: ../../common/examples/smartid.rpc.challenge.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.Authenticate`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :VOTING_END: Hääletusperiood on lõppenud. Valijarakendus teeb päringu ``RPC.Authenticate`` Smart-ID autentimise algatamiseks. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. :params.XSmartIDAuth: Päringu küpsis, kus talletatakse Smart-ID kontrollkoodi räsi, selle eluea ajatempel ja seansiidentifikaator :params.Identifier: Smart-ID kasutaja isikukood. .. literalinclude:: ../../common/examples/smartid.rpc.authenticate.query.json :language: json :linenos: :result.SessionCode: Smart-ID seansiidentifikaator edasiste poll-päringute jaoks .. literalinclude:: ../../common/examples/smartid.rpc.authenticate.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.Authenticate`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :VOTING_END: Hääletusperiood on lõppenud. Valijarakendus teeb päringu ``RPC.AuthenticateStatus`` autentimisprotsessi oleku hindamiseks. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. :params.XSmartIDAuth: Päringu küpsis, kus talletatakse Smart-ID kontrollkoodi räsi, selle eluea ajatempel ja seansiidentifikaator :params.SessionCode: Autentimisseansi identifikaator .. literalinclude:: ../../common/examples/smartid.rpc.authenticatestatus.query.json :language: json :linenos: :result.AuthToken: Autentimistõend teistele IVXV teenustele esitamiseks või ``null``, kui päringu töötlemine alles käib. :result.DataToken: Hääletaja Smart-ID dokumendi number või ``null``, kui päringu töötlemine alles käib. :result.GivenName: Eduka autentimise korral valija eesnimi :result.PersonalCode: Eduka autentimise korral valija isikukood :result.Status: Päringu staatus - ``POLL`` viitab vajadusele päringut korrata, ``OK`` viitab edukale autentimisele. Vastuse muud väljad sisaldavad infot vaid siis kui väärtus on ``OK``. :result.Surname: Eduka autentimise korral valija perekonnanimi .. literalinclude:: ../../common/examples/smartid.rpc.authenticatestatus.response.json :language: json :linenos: .. literalinclude:: ../../common/examples/smartid.rpc.authenticatestatus2.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.AuthenticateStatus`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :SMARTID_BAD_CERTIFICATE: Viga valija Smart-ID isikutuvastussertifikaadiga. :SMARTID_VERIFICATION: Valija valis vale verifitseerimiskoodi. :SMARTID_ACCOUNT: Viga valija Smart-ID kontos. :SMARTID_CANCELED: Valija katkestas Smart-ID seansi. :SMARTID_EXPIRED: Smart-ID seanss on aegunud. :SMARTID_GENERAL: Viga Smart-ID teenuse töös. :VOTING_END: Hääletusperiood on lõppenud. Hääle allkirjastamine ********************* Valijarakendus teeb päringu ``RPC.GetCertificateChoice`` allkirjastamissertifikaadi valikuks. :params.AuthMethod: Toetatud ainult autentimismeetod ``ticket``. :params.AuthToken: Smart-ID autentimistõend. :params.DataToken: Hääletaja Smart-ID dokumendi number. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. .. literalinclude:: ../../common/examples/smartid.rpc.getcertificatechoice.query.json :language: json :linenos: :result.SessionCode: Smart-ID seansiidentifikaator edasiste poll-päringute jaoks .. literalinclude:: ../../common/examples/smartid.rpc.getcertificatechoice.response.json :language: json :linenos: Valijarakendus teeb päringu ``RPC.GetCertificateChoiceStatus`` allkirjastamissertifikaadi oleku hindamiseks. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. :params.SessionCode: Autentimisseansi identifikaator .. literalinclude:: ../../common/examples/smartid.rpc.getcertificatechoicestatus.query.json :language: json :linenos: :result.Certificate: Allkirjastamissertifikaat X509-vormingus :result.Status: Päringu staatus - ``POLL`` viitab vajadusele päringut korrata, ``OK`` viitab edukale autentimisele. Vastuse muud väljad sisaldavad infot vaid siis kui väärtus on ``OK``. .. literalinclude:: ../../common/examples/smartid.rpc.getcertificatechoicestatus.response.json :language: json :linenos: .. literalinclude:: ../../common/examples/smartid.rpc.getcertificatechoicestatus2.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.GetCertificateChoiceStatus`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :SMARTID_BAD_CERTIFICATE: Viga valija Smart-ID allkirjastamissertifikaadiga. :SMARTID_GENERAL: Viga Smart-ID teenuse töös. :VOTING_END: Hääletusperiood on lõppenud. Valijarakendus teeb päringu ``RPC.Sign`` hääle allkirjastamise algatamiseks. Smart-ID kontrollkoodi arvutab valijarakendus andmevälja ``Hash`` väärtusest. :params.AuthMethod: Toetatud ainult autentimismeetod ``ticket``. :params.AuthToken: Smart-ID autentimistõend. :params.Hash: BASE64-kodeeritud elektroonilise hääle räsi :params.HashType: Räsifunktsiooni nimi Smart-ID teenusele edastamiseks, kas ``SHA256``, ``SHA384`` või ``SHA512`` :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. :params.DataToken: Hääletaja Smart-ID dokumendi number. .. literalinclude:: ../../common/examples/smartid.rpc.sign.query.json :language: json :linenos: :result.SessionCode: Smart-ID seansiidentifikaator edasiste poll-päringute jaoks. .. literalinclude:: ../../common/examples/smartid.rpc.sign.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.Sign`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :VOTING_END: Hääletusperiood on lõppenud. Valijarakendus teeb päringu ``RPC.SignStatus`` allkirjastamisprotsessi seisundi hindamiseks. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. :params.SessionCode: Smart-ID seansiidentifikaator .. literalinclude:: ../../common/examples/smartid.rpc.signstatus.query.json :language: json :linenos: :result.Signature: Juhul kui vastuse ``Status`` väli on ``OK``, BASE-64 kodeeritud signatuur, vastasel juhul ``null``. :result.Algorithm: Juhul kui vastuse ``Status`` väli on ``OK``, Smart-ID teenuse poolt tagastatud signatuuri algoritm. Võimalikud väärtused on ``sha256WithRSAEncryption``, ``sha384WithRSAEncryption``, ja ``sha512WithRSAEncryption``. :result.Status: Päringu staatus - ``POLL`` viitab vajadusele päringut korrata, ``OK`` viitab edukale allkirjastamisele. Vastuse muud väljad sisaldavad infot vaid siis kui väärtus on ``OK``. .. literalinclude:: ../../common/examples/smartid.rpc.signstatus.response.json :language: json :linenos: .. literalinclude:: ../../common/examples/smartid.rpc.signstatus2.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.SignStatus`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :SMARTID_BAD_CERTIFICATE: Viga valija Smart-ID isikutuvastussertifikaadiga. :SMARTID_VERIFICATION: Valija valis vale verifitseerimiskoodi. :SMARTID_ACCOUNT: Viga valija Smart-ID kontos. :SMARTID_CANCELED: Valija katkestas Smart-ID seansi. :SMARTID_EXPIRED: Smart-ID seanss on aegunud. :SMARTID_GENERAL: Viga Smart-ID teenuse töös. :VOTING_END: Hääletusperiood on lõppenud. Hääletamine Web eID'ga ------------------------ Web eID kasutamine autentimisvahendina tingib Web eID teenusega liidestuva abiteenuse (SNI ``webeid.ivxv.invalid``) kasutamise autentimistõendi hankimiseks enne valikute nimekirja hankimist. Autentimistõendi hankimine ************************** Valijarakendus teeb päringu ``RPC.Challenge`` Web eID autentimise algatamiseks. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. .. literalinclude:: ../../common/examples/webeid.rpc.challenge.query.json :language: json :linenos: :result.Challenge: Base64 kodeeritud räsi, mille dekodeeritud väärtust peab valijarakendus kasutama autentimistõendi allkirja loomiseks. :params.SessionID: Seansiidentifikaator. :params.Bearer: Küpsis, mida server kasutab räsi verifitseerimiseks. .. literalinclude:: ../../common/examples/webeid.rpc.challenge.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.Challenge`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :VOTING_END: Hääletusperiood on lõppenud. Valijarakendus teeb päringu ``RPC.Token`` autentimistõendi valideerimiseks. :params.OS: Operatsioonisüsteem, millel valijarakendust kasutatakse. :params.SessionID: Seansiidentifikaator. :params.Token: Web eID autentimistõend. :params.Bearer: Küpsis, mida server kasutab räsi verifitseerimiseks. .. literalinclude:: ../../common/examples/webeid.rpc.token.query.json :language: json :linenos: :result.AuthToken: Autentimistõend teistele IVXV teenustele esitamiseks :result.GivenName: Eduka autentimise korral valija eesnimi :result.PersonalCode: Eduka autentimise korral valija isikukood :result.Status: Päringu staatus - ``OK`` viitab edukale autentimisele. Vastuse muud väljad sisaldavad infot vaid siis kui väärtus on ``OK``. :result.Surname: Eduka autentimise korral valija perekonnanimi .. literalinclude:: ../../common/examples/webeid.rpc.token.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.Token`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :BAD_CERTIFICATE: Viga valija Web eID isikutuvastussertifikaadiga. :VOTING_END: Hääletusperiood on lõppenud. Hääle kontrollimine ------------------- Kontrollrakendus teeb päringu ``RPC.Verify`` allkirjastatud hääle ning häält kvalifitseerivate tõendite allalaadimiseks kogumisteenusest. :params.OS: Operatsioonisüsteem, millel kontrollrakendust kasutatakse. :params.VoteID: QR-koodi vahendusel valijarakendusest saadud hääle identifikaator talletusteenuses. .. literalinclude:: ../../common/examples/ver.rpc.verify.query.json :language: json :linenos: :result.Qualification.ocsp: :result.Qualification.tspreg: Vaata peatükki hääle verifitseerimisest :result.Type: Allkirjastatud hääle vorming. Hetkel on ainus toetatud väärtus ``bdoc``. :result.Vote: BASE64-kodeeritud hääl ``SignedVote`` eelpoolmääratud vormingus (:ref:`signed-vote`). :result.ChoicesList: JSON-vormingus ringkonnapõhine valikute nimekiri. .. literalinclude:: ../../common/examples/ver.rpc.verify.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.Verify`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :VOTING_END: Hääletusperiood on lõppenud. E-hääletamise jooksev nimekiri ------------------------------ X-tee teenusega(xroad-service) liidestuva abiteenuse (SNI ``votesorder.ivxv.invalid``) kasutatakse informatsiooni edastamiseks X-tee turvaserverile. Viimane järjenumber ******************* X-tee teenus(xroad-service) teeb päringu ``RPC.VotesSeqNo`` viimase järjenumbri saamiseks. .. literalinclude:: ../../common/examples/votesorder.rpc.votesseqno.query.json :language: json :linenos: :result.SeqNo: Viimane järjenumber. .. literalinclude:: ../../common/examples/votesorder.rpc.votesseqno.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.VotesSeqNo`` korral. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :VOTING_END: Hääletusperiood on lõppenud. E-hääletamiste pakk ******************* X-tee teenus(xroad-service) teeb päringu ``RPC.Votes`` e-hääletamise paki saamiseks. :params.VotesFrom: E-hääled alates sellest järjenumbrist. :params.BatchMaxSize: E-hääletamise paki suurus. .. literalinclude:: ../../common/examples/votesorder.rpc.votes.query.json :language: json :linenos: :result.batchRecords: E-häälte loend :result.batchRecords.seqNo: Hääle järjenumber :result.batchRecords.idCode: Hääletaja isikukood :result.batchRecords.voterName: Hääletaja nimi :result.batchRecords.kovCode: KOV EHAK kood :result.batchRecords.electoralDistrictNo: Valimisringkonna number .. literalinclude:: ../../common/examples/votesorder.rpc.votes.response.json :language: json :linenos: Võimalikud veateated päringu ``RPC.Votes`` korral. :BAD_REQUEST: Vigane päring. :INTERNAL_SERVER_ERROR: Viga serveri sisemises töös. :VOTING_END: Hääletusperiood on lõppenud. ================================================ FILE: Documentation/public/protokollid/09-tootlemine.rst ================================================ .. IVXV protokollid ============================================== E-valimiskasti töötlemisetapi andmestruktuurid ============================================== Tühistus- ja ennistusnimekiri ----------------------------- Tühistus- ja ennistusnimekiri sisaldab andmeid isikute kohta, kelle e-hääl tuleb tühistada (ei lähe arvesse valimistulemuste kokkulugemisel) või ennistada (s.t. tühistatakse eelnev tühistamine ning häälte uuesti üle lugemisel võetakse ennistatud e-hääl arvesse). Nimekiri laaditakse süsteemi digitaalselt allkirjastatud dokumendina, mille andmefaili vorming on järgmine: .. literalinclude:: ../../common/schema/ivxv.revoke.schema :language: json :linenos: Näide: .. literalinclude:: ../../common/schema/ivxv.revoke.schema.example :language: json E-hääletanute nimekiri ---------------------- E-hääletanute nimekiri on pärast e-hääletamise lõppu väljastatav nimekiri e-hääletanud isikutest, sordituna valimisjaoskondade kaupa. Dokument genereeritakse töötlemisrakenduse poolt. .. literalinclude:: ../../common/schema/ivxv.voterlist.schema :language: json :linenos: Näide: .. literalinclude:: ../../common/schema/ivxv.voterlist.schema.example :language: json Hääletamistulemus ----------------- Võtmerakenduse poolt dekrüpteeritud ning summeeritud hääled jagatud valimisringkondade ja jaoskondade kaupa. Hääletamistulemuste failis peavad iga jaoskonna kohta olema järgmised andmed. #. Rikutud ja kehtetute häälte arvu näitav kirje. Seda ka juhul, kui valimisjaoskonnas polnud ühtki rikutud või kehtetut häält: sellisel juhul on häälte arv null. #. Iga valiku poolt antud häälte arvu näitav kirje. Seda ka juhul, kui valimisjaoskonnas ei antud selle valiku poolt ühtki häält: sellisel juhul on häälte arv null. .. literalinclude:: ../../common/schema/ivxv.result.schema :language: json :linenos: Näide: .. literalinclude:: ../../common/schema/ivxv.result.schema.example :language: json E-valimiskast ------------- Fail sisaldab kogumisteenuse poolt vastu võetud hääli koos häälte juurde kuuluvate andmetega. Faili vorming on Zip64 konteiner. Valija-spetsiifilised kaustad asuvad vahetult juurkausta `votes` all. Faili sisu: * :file:`votes//` * :file:`.version` * :file:`.` * :file:`.*` kus: * ```` on valija identifikaator, Eesti puhul isikukood; * ```` on hääle esitamise kellaaeg vormingus ``yyyymmddhhmmssmmm±zzzz``; * see kellaaeg kajastab hetke, mil päring kogumisteenusesse tehti, ja on antud lihtsalt valimiskasti inimloetavuse parandamiseks; hääle tegelik ajamärk või -tempel on mõne kvalifitseeriva vastuse sees; * ```` on valikute konteineri tüüp, Eesti puhul BDOC; * kusjuures BDOC ise on lihtsalt põhiprofiiliga ja ei sisalda kvalifitseerivad parameetreid (kehtivuskinnitusi, ajamärgendeid, ajatempleid), * ```` on häält kvalifitseeriva protokolli tüüp, millest hetkel võimalikud on: * ``ocsp`` - *Online Certificate Status Protocol* (kehtivuskinnitus, `RFC 6960 `_) kinnitab valija allkirjastamissertifikaadi kehtivust hääle andmise hetkel, * ``tsp`` - *Time-Stamp Protocol* (ajatempel, `RFC 3161 `_) kinnitab, et päringu tegemise hetkeks oli hääl olemas, * ``tspreg`` - sama, mis ``tsp``, aga nonsiks pannakse kogumisteenuse allkiri päringu ``MessageImprint`` elemendil, et häält registreerida. * Iga hääle kohta esinevad failid on: * ``.version`` - hääle andmise ajal kehtinud valijate nimekirja versioon; * ``.`` - valikute konteiner, mille sees on valiku identifikaator kujul ``..ballot``. Eesti puhul BDOC-konteineris olev vastava nimega fail; * ``.`` - häält kvalifitseeriva protokolli päringu vastus; neid võib esineda mitu, aga iga protokolli kohta maksimaalselt üks. Anonüümistatud e-valimiskast ---------------------------- Valimisringkondade ja jaoskondade järgi grupeeritud krüpteeritud hääled. Anonüümistatud e-valimiskastis puudub informatsioon valijate kohta. Anonüümistatud e-valimiskast on töötlemisrakenduse väljund ning võtmerakenduse dekrüpteerimise tööriista sisend. .. literalinclude:: ../../common/schema/ivxv.anon-bb.schema :language: json :linenos: Näide: .. literalinclude:: ../../common/schema/ivxv.anon-bb.schema.example :language: json ================================================ FILE: Documentation/public/protokollid/11-audit.rst ================================================ .. IVXV protokollid ======================== Hääletamistulemuse audit ======================== Miksimistõendi kontroll ======================= Miksimistõendi kontrollimiseks kasutatakse algoritmi nagu on defineeritud `Verificatumi verifitseerija implementeerimise manuaalis `_. Märgime, et miksimistõendi koostamisel lisatakse krüptogrammile andmed valimiste, ringkonna, jaoskonna ja küsimuse identifikaatori kohta. Lisamiseks kodeeritakse vastav väli rühma elemendina, kasutades pimendamiseks juhuslikkust 0. Näitena, kui esialgu on krüptogramm :math:`c_0 = (c_{00}, c_{01})`, kasutades avalikku võtit :math:`pk = (g, y)`, siis Verificatumi sisendina kasutatakse laia krüptogrammi :math:`C = (c_{id}, c_d, c_s, c_q, c_0)`, kus: * valimiste identifikaatori pseudokrüptogramm on antud kujul :math:`c_{id} = (1, encode(id))`, kus funktsioon :math:`encode` kodeerib sõne vastava rühma elemendina ja `id` on valimiste identifikaatori sõne. * ringkonna identifikaatori pseudokrüptogramm on antud kujul :math:`c_d = (1, encode(d))`, kus `d` on ringkonna identifikaatori sõne. * jaoskonna identifikaatori pseudokrüptogramm on antud kujul :math:`c_s = (1, encode(s))`, kus `s` on jaoskonna identifikaatori sõne. * küsimuse identifikaatori pseudokrüptogramm on antud kujul :math:`c_q = (1, encode(q))`, kus `q` on küsimuse identifikaatori sõne. Sellisel juhul defineeritakse laia krüptogrammile vastava avaliku võtmena :math:`((g,1), (g,1), (g,1), (g,1), (g,y))`. Korrektse dekrüpteerimise tõendi kontroll ========================================= Olgu antud krüptogramm :math:`c = (c_0, c_1)`, mis dekrüpteeritakse väärtuseks :math:`d` antud avaliku võtmega :math:`pk` üle parameetrite :math:`(p,g)` ja dekrüpteerimistõendiga :math:`(a,b,s)`. Korrektse dekrüpteerimise kontrollimise jaoks on tarvis arvutada mitte-interaktiivne kontrollija väljakutse. Selle jaoks kodeeritakse :math:`"DECRYPTION" || pk || c || d || a || b` DER-kodeeringus. Baidijada kasutatakse deterministliku juhuarvugeneraatori initsialiseerimiseks ja selle väljundist loetakse rühma järgu pikkune täisarv :math:`k`. Dekrüpteerimistõendi kontrolliks tuleb veenduda, et :math:`c_0^s = a * (c_1/d)^k` ja :math:`g^s = b * y^k`. Korrektse teisendamise kontroll =============================== Kontrollimaks, et teisendus IVXV e-valimiskasti ja Verificatumi krüptogrammide vahel on tehtud korrektselt, tuleb korrata teisendust sõltumatult. Pärast sõltumatut teisendust tuleb võrrelda saadud väljundeid. Kuna teisendamine on deterministlik protseduur, siis garanteerib kordamine tegevuse õigsuse. ================================================ FILE: Documentation/public/protokollid/12-lisad.rst ================================================ .. IVXV protokollid ===== Lisad ===== Andmestruktuuride ASN.1 spetsifikatsioon ======================================== .. literalinclude:: ivxv-elgamal-general.asn1 :language: asn1 :name: asn-general :linenos: :caption: IVXV ElGamal üldised andmestruktuurid .. literalinclude:: ivxv-elgamal-modp.asn1 :language: asn1 :name: asn-modp :linenos: :caption: IVXV ElGamal ModP spetsiifilised andmestruktuurid .. literalinclude:: ivxv-elgamal-ecc.asn1 :language: asn1 :name: asn-ecc :linenos: :caption: IVXV ElGamal ECC spetsiifilised andmestruktuurid Elektroonilise hääle vormingu spetsifikatsioon ============================================== Käesoleva protokolliversiooniga kooskõlaline ettepanek VVK otsuseks hääletamissedeli ja elektroonilise hääle vormi kehtestamiseks. .. literalinclude:: paragraph.txt Vead töötlemisprotsessis ======================== Anname ülevaate veakoodidest töötlemisprotsessis. Veakoodid kirjeldavad vigu üksiku elemendi verifitseerimisel - hääl, registreerimistõend, registreerimispäring - ning häälte, registreerimistõendite ja registreerimispäringute vahelise vastavuse loomisel. Enamus veaolukordi on pigem hüpoteetilised (nt. `REG_NO_NONCE`), siiski on tegemist olukordadega, mis programselt võivad esineda ning seetõttu tuleb neid ka käsitleda. Veaolukord tähendab, et konkreetne element ei liigu edasi töötlemise järgmisesse faasi. .. list-table:: Töötlemisprotsessi veakoodid :widths: 40 60 :header-rows: 1 * - Veakood - Selgitus * - ``INVALID_FILE_NAME`` - Failinimi ei vasta oodatud mustrile. Viitab tundmatule failile urnis. * - ``MISSING_FILE`` - Mõni hääle koosseisuks vajalik fail puudub. Nt. ajatempel. * - ``REPEATED_FILE`` - Mõnda hääle koosseisuks vajalikku faili on mitu. Nt. kehtivuskinnitus. * - ``UNKNOWN_FILE_TYPE`` - Faili tüüp on tundmatu või mittetoetatud. * - ``INVALID_FILE_SIZE`` - Allkirjastatud hääle faili suurus ei vasta seadistustes nõutud kriteeriumitele. * - ``INVALID_BALLOT_SIGNATURE`` - Hääl on vigase allkirjaga. * - ``MISSING_VOTER_SIGNATURE`` - Hääl ei sisalda valija allkirja. * - ``VOTER_NOT_FOUND`` - Valija ei olnud hääletamise hetkel valijate nimekirjas. * - ``VOTERLIST_NOT_FOUND`` - Versioonile vastavat valijate nimekirja ei leitud. * - ``TIME_BEFORE_START`` - Hääl on antud enne hääletamisperioodi algust. Viitab testhäälele. * - ``REG_RESP_INVALID`` - Registreerimistõend/ajatempel on vigane. Viga ATOs või töötlejas. * - ``REG_REQ_INVALID`` - Registreerimispäring on vigane. Viga kogumisteenuses või töötlejas. * - ``REG_RESP_NOT_UNIQUE`` - Registreerimistõend ei ole unikaalne. Viga kogumisteenuses või töötlejas. * - ``REG_REQ_NOT_UNIQUE`` - Registreerimispäring ei ole unikaalne. Sama räsiga häält on esitatud korduvalt. * - ``REG_NO_NONCE`` - Registreerimistõendis puudub nonss. * - ``REG_NONCE_NOT_SIG`` - Esitatud nonss ei ole IVXV protokolli kohaselt allkirjastatud. * - ``REG_NONCE_ALG_MISMATCH`` - Nonssi allkirjastamisel kasutatud algoritm ei vasta oodatule. * - ``REG_NONCE_SIG_INVALID`` - Nonssi allkiri on vigane. * - ``UNKNOWN_FILE_IN_VOTE_CONTAINER`` - Hääle konteineris on tundmatu fail. * - ``TECHNICAL_ERROR`` - Töötlemise ajal tekkis tehniline viga. * - ``REG_RESP_REQ_UNMATCH`` - Registreerimistõendi andmed ei vasta registreerimispäringu andmetele. * - ``REG_REQ_WITHOUT_BALLOT`` - Esitatud on registreerimispäring, kuid hääl puudub urnist. Kogumisteenuse viga. * - ``BALLOT_WITHOUT_REG_REQ`` - Hääl on esitatud ilma vastava registreerimispäringuta. ATO viga. * - ``SAME_TIME_AS_LATEST`` - Kaks häält samalt valijalt võivad olla arvesse võetavad viimasena. * - ``INVALID_SIGNATURE_PROFILE`` - Hääle allkirjaprofiil on vigane. Töötlemise käigus tuvastatakse kehtetud sedelid sellisel määral, mil seda võimaldavad kontrollid avaliku võtmega. Kuigi kogumisteenus ei luba kehtetuid sedeleid talletada, peab töötlemisrakendus kontrolle siiski kordama tagamaks mh. võimalike tarkvaravigade vältimise. .. list-table:: Krüptogrammide kehtivuse kontrolli veakoodid :widths: 30 70 :header-rows: 1 * - Veakood - Selgitus * - ``INVALID_BYTES`` - Baidijada ei ole dekodeeritav ElGamalCiphertext'na * - ``INVALID_GROUP`` - Väärtus ei ole oodatud rühma element * - ``INVALID_RANGE`` - Väärtus on lubatud vahemikust väljas. * - ``INVALID_QR`` - Väärtus ei ole ruutjääk (MODP). * - ``INVALID_POINT`` - Väärtus ei ole kõvera punkt (ECC). * - ``INVALID`` - Vigane šifreeritud tekst. ================================================ FILE: Documentation/public/protokollid/Makefile ================================================ include ../../common.mk ================================================ FILE: Documentation/public/protokollid/index.rst ================================================ .. IVXV seadistuste koostamise juhend ======================================================== IVXV protokollid ======================================================== .. raw:: html

NB! See on HTML-versioon dokumendist. Tellijale antakse üle PDF-versioon.

.. toctree:: :maxdepth: 4 01-annotatsioon 02-ylevaade 04-seadistus 05-ehaal 06-talletamine 06a-regteenus 07-kontrollimine 08-haaletamine 09-tootlemine 11-audit 12-lisad ================================================ FILE: Documentation/public/protokollid/ivxv-elgamal-ecc.asn1 ================================================ id-ivxv-ecc-elgamal OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) 99999 1 } IVXVECCElGamalParameters ::= SEQUENCE { curve GeneralString, electionId GeneralString } IVXVECCElGamalPublicKey ::= SEQUENCE { pubY OCTET STRING } IVXVECCElGamalCiphertext ::= SEQUENCE { uBlind OCTET STRING, vBlindedMessage OCTET STRING } IVXVECCElGamalDecryptionProof ::= SEQUENCE { aMsgCommitment OCTET STRING, bKeyCommitment OCTET STRING, sResponse INTEGER } IVXVECCElGamalDecryptionChallenge ::= SEQUENCE { niProofDomain GeneralString, publicKey SubjectPublicKeyInfo, ciphertextInfo IVXVElGamalCiphertextInfo, encodedPlaintext OCTET STRING, aMsgCommitment OCTET STRING, bKeyCommitment OCTET STRING } ================================================ FILE: Documentation/public/protokollid/ivxv-elgamal-general.asn1 ================================================ IVXVElGamalCiphertextInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, ciphertext ANY DEFINED BY algorithm } ================================================ FILE: Documentation/public/protokollid/ivxv-elgamal-modp.asn1 ================================================ id-ivxv-modp-elgamal OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) internet(1) private(4) enterprise(1) cryptlib(3029) mechanism(2) 1 } IVXVModPElGamalParameters ::= SEQUENCE { modP INTEGER, gen INTEGER, electionId GeneralString } IVXVModPElGamalPublicKey ::= SEQUENCE { pubY INTEGER } IVXVModPElGamalCiphertext ::= SEQUENCE { uBlind INTEGER, vBlindedMessage INTEGER } IVXVModPElGamalDecryptionProof ::= SEQUENCE { aMsgCommitment INTEGER, bKeyCommitment INTEGER, sResponse INTEGER } IVXVModPElGamalDecryptionChallenge ::= SEQUENCE { niProofDomain GeneralString, publicKey SubjectPublicKeyInfo, ciphertextInfo IVXVElGamalCiphertextInfo, encodedPlaintext INTEGER, aMsgCommitment INTEGER, bKeyCommitment INTEGER } ================================================ FILE: Documentation/public/protokollid/locales/en/LC_MESSAGES/01-annotatsioon.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: 2024-02-29 16:35+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../01-annotatsioon.rst:6 msgid "Annotatsioon" msgstr "Annotation" #: ../../01-annotatsioon.rst:8 msgid "" "Käesolev dokument kirjeldab elektroonilise hääletamise infosüsteemi IVXV " "protokollistikku." msgstr "" "This document specifies the protocols of the online voting system IVXV." #: ../../01-annotatsioon.rst:11 msgid "" "Dokument annab üldise ülevaate elektroonilise hääletamise süsteemi " "tehnilisest ülesehitusest ja kasutatavatest protokollidest. Dokumendis " "defineeritakse protokollides kasutatavad ühised mõisted ja andmestruktuurid." msgstr "" "The document gives a general overview of the technical architecture of the " "online voting system and the protocols used. It defines common concepts and " "data structures used in the protocols." ================================================ FILE: Documentation/public/protokollid/locales/en/LC_MESSAGES/02-ylevaade.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 08:56+0000\n" "PO-Revision-Date: 2024-02-29 17:09+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.15.0\n" #: ../../02-ylevaade.rst:5 msgid "Ülevaade" msgstr "Overview" #: ../../02-ylevaade.rst:7 msgid "" "Elektroonilise hääletamise protokollistik (edaspidi protokollistik) " "defineerib elektroonilise hääletamise süsteemi komponentide vahelise " "sõnumivahetuse, kasutatavad andmestruktuurid, algoritmid ning liidesed " "väliste süsteemidega. Sõnumivahetus esitatakse UML suhtlusskeemidena, mis " "üheselt defineerivad sõnumite järgnevuse. Andmestruktuuride kirjeldused on " "varustatud BNF, ASN.1 või JSON-schema notatsioonis spetsifikatsioonidega. " "Algoritmid esitatakse pseudokoodina." msgstr "" "The online voting protocol suite (hereafter referred to as the protocol " "suite) defines the messaging between the components of an online voting " "system, the data structures used, the algorithms, and the interfaces to " "external systems. The message exchange is represented as UML interaction " "diagrams that unambiguously define the sequence of messages. Data structure " "descriptions are provided with specifications in Backus-Naur or JSON schema " "notation. Algorithms shall be presented in pseudo-code form." #: ../../02-ylevaade.rst:15 msgid "" "NB! Kõigis protokollistiku andmestruktuuride väljades tuleb rangelt kinni " "pidada lubatud märkidest ning väljade minimaalsetest ja maksimaalsetest " "pikkustest. Täiendavate tühikute, tabulaatorite jms. kasutamine on keelatud " "ning spetsifikatsiooni realiseerivad rakendused peavad vorminguga mitte-" "vastavate andmete töötlemisest keelduma." msgstr "" "NOTE: The allowed characters and the minimum and maximum lengths of the " "fields must be strictly respected in all fields of the protocol data " "structures. The use of additional spaces, tabs, etc. is prohibited, and " "applications implementing the specification must refuse to process data that" " does not conform to the format." #: ../../02-ylevaade.rst:21 msgid "" "Protokollistik defineerib elektroonilise hääletamise protokolli ning selle " "protokolli realiseerimiseks vajalikud tugistruktuurid." msgstr "" "The protocol suite defines the protocol for online voting and the support " "structures needed to implement this protocol." #: ../../02-ylevaade.rst:25 msgid "Elektroonilise hääletamise protokoll" msgstr "Online Voting Protocol" #: ../../02-ylevaade.rst:27 msgid "Elektroonilise hääletamise protokoll spetsifitseerib:" msgstr "The online voting protocol specifies:" #: ../../02-ylevaade.rst:29 msgid "" "elektroonilise hääle vormingu, mis võimaldab üheselt määratleda valija tahte" " konkreetsel valimisel;" msgstr "" "the electronic ballot format that allows defining the voter’s intent " "unambiguously at a specific election;" #: ../../02-ylevaade.rst:32 msgid "elektroonilise hääle krüpteerimise hääle salajasuse tagamiseks;" msgstr "electronic ballot encryption to ensure ballot secrecy;" #: ../../02-ylevaade.rst:34 msgid "" "elektroonilise hääle digitaalse allkirjastamise tervikluse ja valija " "identifitseerimise tagamiseks;" msgstr "" "the digital signing of an electronic vote to ensure integrity and voter " "identification;" #: ../../02-ylevaade.rst:37 msgid "" "elektroonilise hääle kvalifitseerimise kogumisteenuse poolt, hääle " "vastuvõtmise tähistamiseks;" msgstr "" "electronic vote qualification by the collection service, to mark the " "acceptance of a vote;" #: ../../02-ylevaade.rst:40 msgid "" "Protokoll eeldab, et valimise korraldaja defineerib valimise ning genereerib" " häälte salastamise võtmepaari, mille avalik komponent tehakse " "valijarakendusele kättesaadavaks." msgstr "" "The protocol assumes that the election organizer has defined the election " "and generated a key pair for vote encryption, the public component of which " "has been made available to the voting application." #: ../../02-ylevaade.rst:44 msgid "" "Protokolli vahendusel liigub valija tahe kogumisteenuses talletatavasse " "e-valimiskasti ning võetakse tulemuse kujunemisel arvesse järgmist " "sündmusterida pidi:" msgstr "" "Through the protocol, the voter's intent will be transferred to the digital " "ballot box stored in the collection service and will be taken into account " "in the following sequence of events:" #: ../../02-ylevaade.rst:47 msgid "" "Valija kasutab valijarakendust oma tahteavalduse elektrooniliseks " "vormistamiseks:" msgstr "The voter uses the voting application to vote online:" #: ../../02-ylevaade.rst:50 msgid "tahteavaldus vormistatakse elektroonilise häälena;" msgstr "voter's intent is encoded as an electronic ballot;" #: ../../02-ylevaade.rst:52 msgid "vormistatud hääl krüpteeritakse;" msgstr "the electronic ballot is encrypted;" #: ../../02-ylevaade.rst:54 msgid "krüpteeritud hääl signeeritakse valija arvutis." msgstr "the encrypted ballot is digitally signed." #: ../../02-ylevaade.rst:56 msgid "" "Kogumisteenus talletab elektroonilise hääle, moodustades selle käigus " "häälele kvalifitseeritud digitaalallkirja:" msgstr "" "The collection service stores the electronic vote, forming a qualified " "digital signature for the vote:" #: ../../02-ylevaade.rst:59 msgid "elektrooniline hääl registreeritakse välises registreerimisteenuses;" msgstr "" "an electronic vote is registered with an external registration service;" #: ../../02-ylevaade.rst:61 msgid "elektroonilisele häälele võetakse digitaalne ajatempel;" msgstr "a digital timestamp is applied to the electronic vote;" #: ../../02-ylevaade.rst:63 msgid "" "elektroonilisele häälele võetakse valija sertifikaadi kehtivuskinnitus;" msgstr "" "a digitally signed ballot will be accompanied by elements to confirm the " "validity of the voter's certificate;" #: ../../02-ylevaade.rst:66 msgid "" "elektroonilist häält kvalifitseerivad elemendid tagastatakse mh. ka " "valijarakendusele kontrollimiseks ning valija informeerimiseks " "kvalifitseerimise tulemustest;" msgstr "" "elements qualifying an electronic vote are also returned to the voting " "application for verification and to inform the voter of the qualification " "results;" #: ../../02-ylevaade.rst:70 msgid "" "valijale võimaldatakse kvalifitseeritud elektroonilise hääle kontrollimine " "kontrollrakenduse abil." msgstr "" "the voter is allowed to verify a qualified electronic vote by means of a " "verification application." #: ../../02-ylevaade.rst:75 msgid "" "Elektroonilise hääle digitaalne allkirjastamine erineb tavapärasest " "dokumentide digitaalallkirjastamisest, kus kõik allkirja kvalifitseerimiseks" " vajalikud toimingud algatatakse vahetult allkirjastaja seadmes. " "Elektroonilise hääle kvalifitseerimise kohustus on kogumisteenusel, kelle " "ülesanne on veenduda vastuvõetavate häälte korrektses allkirjastatuses. Kuna" " e-hääletamise perioodil on koormus seotud teenustele kõrge, võimaldab " "kogumisteenuse poolt juhitud kvalifitseerimine tagada paremat teenuse " "kvaliteeti." msgstr "" "Digital signing of electronic votes differs from traditional digital signing" " of documents, where all the operations necessary to qualify a signature are" " initiated directly on the signer's device. The onus of qualifying an " "electronic vote lies with the collection service, which is responsible for " "verifying that the votes received have been correctly signed. As the " "e-voting period is a period of high workload for the associated services, " "the qualification process managed by the collection service allows for a " "better quality of service." #: ../../02-ylevaade.rst:84 msgid "" "Valija võib kasutada kontrollrakendust veendumaks oma hääle korrektses " "käitlemises kogumisteenuse poolt;" msgstr "" "The voter can use the verification application to make sure their vote is " "handled correctly by the collection service;" #: ../../02-ylevaade.rst:87 msgid "" "Hääletamisperioodi lõppedes väljastab kogumisteenus valimise korraldajale " "e-valimiskasti ning registreerimisteenus väljavõtte kogumisteenuse poolt " "registreeritud häältest;" msgstr "" "At the end of the voting period, the collection service will issue a digital" " ballot box to the election organiser and the registration service will " "issue a list of the votes registered by the collection service;" #: ../../02-ylevaade.rst:91 msgid "e-valimiskasti koosseisus antakse valimise korraldajale üle:" msgstr "" "in the composition of the digital ballot-box following data will be handed " "over to the election organiser:" #: ../../02-ylevaade.rst:93 msgid "valija krüpteeritud tahteavaldus koos signatuuriga;" msgstr "the voter's encrypted intent with signature;" #: ../../02-ylevaade.rst:95 msgid "registreerimisteenuse kinnitus hääle registreerimisest;" msgstr "" "confirmation of the registration of the vote by the registration service;" #: ../../02-ylevaade.rst:97 msgid "" "ajatempliteenuse poolt väljastatud digitaalne ajatempel elektroonilisele " "häälele;" msgstr "" "a digital timestamp issued by a timestamp service for an electronic vote;" #: ../../02-ylevaade.rst:100 msgid "" "kehtivuskinnitusteenuse poolt väljastatud kinnitus valija sertifikaadi " "kehtivuse kohta;" msgstr "" "confirmation of the validity of the voter's certificate issued by a " "validation service;" #: ../../02-ylevaade.rst:103 msgid "" "registreerimisteenuse väljavõtte koosseisus antakse valimise korraldajale " "üle:" msgstr "" "in the form of a registration extract shall be handed over to the organiser " "of the election:" #: ../../02-ylevaade.rst:105 msgid "" "kõik e-hääletamise perioodil kogumisteenuse poolt registreerimisteenusele " "saadetud päringud elektrooniliste häälte registreerimiseks." msgstr "" "all enquiries sent by the collection service to the registration service " "during the e-voting period to register electronic votes." #: ../../02-ylevaade.rst:109 msgid "Valimise korraldaja arvutab hääletamistulemuse:" msgstr "The election organiser calculates the tally:" #: ../../02-ylevaade.rst:111 msgid "kontrollitaks üle antud elektrooniliste häälte allkirjade kehtivust" msgstr "verifying the validity of the electronic signatures of votes cast." #: ../../02-ylevaade.rst:113 msgid "" "kontrollitakse, et kõik registreerimisteenuses registreeritud hääled on " "e-valimiskasti koosseisus üle antud;" msgstr "" "making sure that all the votes registered in the registration service have " "been cast in the digital ballot box;" #: ../../02-ylevaade.rst:116 msgid "eraldatakse krüpteeritud hääled ja digitaalallkirjad;" msgstr "separating encrypted ballots and digital signatures;" #: ../../02-ylevaade.rst:118 msgid "anonüümitakse krüpteeritud hääled krüptograafiliselt;" msgstr "anonymizing encrypted ballots cryptographically;" #: ../../02-ylevaade.rst:120 msgid "dekrüpteeritakse krüpteeritud hääled;" msgstr "decrypting encrypted ballots;" #: ../../02-ylevaade.rst:122 msgid "dekrüpteeritud häälte põhjal arvutatakse hääletamistulemus." msgstr "calculating the tally based on the decrypted votes." #: ../../02-ylevaade.rst:124 msgid "" "Protokoll on analoogne paberil posti teel hääletamise protokolliga, kus " "valija tahe liigub valimiskomisjonini kahes ümbrikus – välimise ümbriku sees" " on sisemine ümbrik, mis omakorda sisaldab valija tahteavaldusega " "hääletussedelit. Välimine ümbrik kannab valijat identifitseerivat infot ning" " võimaldab mh. kontrollida valija õigust hääletada. Sisemine ümbrik on " "anonüümne ning kaitseb hääle salajasust. Enne häälte kokkulugemist " "eraldatakse sisemised ümbrikud välimistest." msgstr "" "The protocol is analogous to a postal voting protocol, where the voter's " "intent is sent to the electoral commission in two envelopes - the outer " "envelope contains the inner envelope, which in turn contains the ballot " "paper with the voter's intent. The outer envelope carries the voter's " "identifying information and allows, among other things, the voter's right to" " vote to be verified. The inner envelope is anonymous and protects the " "secrecy of the vote. The inner envelopes are separated from the outer " "envelopes before the votes are counted." #: ../../02-ylevaade.rst:132 msgid "" "Elektroonilise hääletamise kontekstis on sisemine ümbrik vormistatud " "krüpteeritud häälena ning välimine ümbrik digitaalselt allkirjastatud " "dokumendina." msgstr "" "In the context of online voting, the inner envelope is an encrypted ballot " "and the outer envelope is a digitally signed document." ================================================ FILE: Documentation/public/protokollid/locales/en/LC_MESSAGES/04-seadistus.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: 2024-02-29 17:21+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../04-seadistus.rst:5 msgid "Valimise definitsioon" msgstr "Election definition" #: ../../04-seadistus.rst:7 msgid "" "Valimise defineerib valimise korraldaja. Eesti riiklikel valimistel " "jagunevad kõik hääleõiguslikud isikud ühte või mitmesse valimisringkonda. " "Valijal on võimalik hääletamisel valida ainult selle ringkonna kandidaatide " "vahel, kuhu ta kuulub." msgstr "" "The election is defined by the election organiser. In national elections in " "Estonia, all eligible voters are divided into one or more constituencies / " "electoral districts. Voters can only vote for candidates in the constituency" " to which they belong." #: ../../04-seadistus.rst:12 msgid "Valimise defineerimiseks tuleb määratleda vähemalt" msgstr "To define an election, at least the following have to be defined" #: ../../04-seadistus.rst:14 msgid "" "valimise unikaalne identifikaator ning küsimuste unikaalsed " "identifikaatorid;" msgstr "" "a unique identifier for the election and unique identifiers for the " "questions;" #: ../../04-seadistus.rst:16 msgid "täielik loend valimisringkondadest ja -jaoskondadest;" msgstr "a full list of electoral districts and polling stations;" #: ../../04-seadistus.rst:18 msgid "hääleõiguslike isikute nimekiri ja jagunemine valimisringkondadesse;" msgstr "" "the list of persons entitled to vote and the division into electoral " "districts;" #: ../../04-seadistus.rst:20 msgid "kandidaatide nimekiri ja jagunemine valimisringkondadesse." msgstr "the list of candidates and the division into electoral districts." #: ../../04-seadistus.rst:22 msgid "" "Valimise sisendandmed koostatakse Valimise Infosüsteemis (VIS), " "vormingukirjeldused on spetsifitseeritud `VIS ja EHS ühisspetsifikatsioonis " "`_." msgstr "" "Election input data is compiled in the Election Information System (VIS), " "the format specifications are specified in the 'Common Specification for VIS" " and EHS `_." ================================================ FILE: Documentation/public/protokollid/locales/en/LC_MESSAGES/05-ehaal.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.8.2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 19:52+0000\n" "PO-Revision-Date: 2024-02-29 19:50+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.15.0\n" #: ../../05-ehaal.rst:5 msgid "Elektrooniline hääl" msgstr "Electronic vote" #: ../../05-ehaal.rst:7 msgid "" "IVXV hääletamisprotokoll põhineb topeltümbrikuskeemil, mis tähendab, et " "valija avakujul tahteavaldus krüpteeritakse valimise korraldaja poolt " "levitatud avaliku võtmega. Krüpteeritud tahteavaldus allkirjastatakse " "digitaalselt valija käsutuses oleva allkirjastamisvahendiga ning edastatakse" " kogumisteenusesse mingis kokkulepitud konteinervormingus. Kogumisteenus " "võib valija poolt allkirjastatud häält täiendavalt kvalifitseerida, " "veendudes näiteks allkirjastamissertifikaadi kehtivuses. IVXV protokollistik" " näeb mh. ette kogumisteenuse poolt vastuvõetud häälte registreerimise " "välises registreerimisteenuses." msgstr "" "The IVXV voting protocol is based on a double envelope scheme, which means " "that the voter's plaintext intent is encrypted with a public key distributed" " by the election organiser. The encrypted ballot is digitally signed using a" " signature device at the voter's disposal and is delivered to the collection" " service in an agreed container format. The collection service may further " "qualify the vote signed by the voter, for example by verifying the validity " "of the signature certificate. The IVXV protocol suite foresees, inter alia, " "the registration of votes received by the collection service in an external " "registration service." #: ../../05-ehaal.rst:17 msgid "" "Kogumisteenuse poolt talletamisele võetud hääl koos kvalifitseerivate " "elementidega tehakse kättesaadavaks nii valijarakendusele kui " "kontrollrakendusele, mis teostavad üksiku hääle peal samad kontrollid, mida " "hilisem valimise korraldaja töötlemisrakendus teostab kõigi häälte peal. " "Kvalifitseerivate elementide kontrollimise võimalus annab valijale kindluse," " et tema häält on hilisemates protsessides korrektselt menetletud." msgstr "" "The vote accepted to be stored by the collection service, together with the " "qualifying elements, is made available to both the voting application and " "the verification application, which perform the same checks on the " "individual vote as the subsequent election organiser's processing " "application performs on all votes. The ability to check the qualifying " "elements gives the voter confidence that their vote has been correctly " "processed in subsequent processes." #: ../../05-ehaal.rst:26 msgid "Valija tahteavaldus avakujul" msgstr "Voter's Plaintext Intent" #: ../../05-ehaal.rst:28 msgid "" "Valija tahteavaldus avakujul eksisteerib valijarakenduses ning hiljem ka " "kontrollrakenduses ja häälte kokkulugemisel võtmerakenduses. Tahteavaldus " "sisaldab valiku koodi ringkonnas ja ringkonna EHAK-koodi. Eraldajana " "kasutatakse ASCII kooditabeli sümbolit `0x2E` ehk \".\". Vormingus " "spetsifitseerimata sümbolite kasutamine ei ole lubatud, vormingule " "mittevastavad sedelid loetakse kehtetuks." msgstr "" "The voter's plaintext intent exists in the voting application and later in " "the verification application and in the key application when the votes are " "tallied. The declaration of intent includes the precinct code and the EHAK " "code of the precinct. The separator shall be the ASCII code table symbol " "`0x2E` or \".\". The use of symbols not specified in the format is not " "allowed, and non-compliant tags will be invalidated." #: ../../05-ehaal.rst:49 msgid "Järgmised tahteavaldused on vormistatud korrektselt:" msgstr "The following declarations of intent have been correctly drafted:" #: ../../05-ehaal.rst:57 msgid "Järgmised tahteavaldused ei ole vormistatud korrektselt:" msgstr "The following declarations of intent have not been properly drawn up:" #: ../../05-ehaal.rst:68 msgid "Krüpteeritud sedel" msgstr "Encrypted ballot" #: ../../05-ehaal.rst:70 msgid "" "Valija tahteavaldus avakujul :token:`ballot` krüpteeritakse valijarakenduse " "poolt valimise korraldaja genereeritud avaliku võtmega. IVXV vajab " "krüpteerimiseks mitte-deterministlikku, homomorfset avaliku võtme " "krüptosüsteemi. Selliseks süsteemiks sobib ElGamal krüptosüsteem, mida täna " "rakendatakse IVXV kontekstis nii jäägiklassiringi `Zp` multiplikatiivsel " "rühmal `Zp*` (MODP tüüpi rühmad) kui ka elliptkõveratel (ECC tüüpi rühmad)." msgstr "" "The voter's plaintext intent :token:`ballot` is encrypted by a public key " "generated by the election organizer by the voting application. IVXV requires" " a non-deterministic, homomorphic public key cryptosystem for encryption. " "Such a system is the ElGamal cryptosystem, which is today implemented in the" " context of IVXV both on the multiplicative group `Zp*` of the residue class" " ring `Zp` (MODP type groups) and on the elliptic curves (ECC type groups)." #: ../../05-ehaal.rst:77 msgid "" "ElGamal avalik võti kodeeritakse koos ElGamal krüptosüsteemi parameetritega " "ning konkreetset valimist iseloomustava identifikaatoriga. Krüptosüsteemi " "parameetrid on osaks algoritmi identifikaatori struktuurist, avalik võti on " "kodeeritud X509 standardis kirjeldatud :token:`SubjectPublicKeyInfo` " "struktuuri :token:`subjectPublicKey` välja." msgstr "" "The ElGamal public key is encoded with the ElGamal cryptosystem parameters " "and an identifier for the specific election. The cryptosystem parameters are" " part of the structure of the algorithm identifier, the public key is " "encoded in the :token:`SubjectPublicKeyInfo` structure of the " ":token:`subjectPublicKey` described in the X509 standard." #: ../../05-ehaal.rst:90 msgid "" "MODP tüüpi rühmade korral identifitseerib algoritmi identifikaator " ":token:`id-ivxv-modp-elgamal`. Parameetrid vastavad struktuurile " ":token:`IVXVModPElGamalParameters` ning avalik võti struktuurile " ":token:`IVXVModPElGamalPublicKey` (:ref:`asn-modp`)." msgstr "" "In the case of MODP type groups, the identifier :token:`id-ivxv-modp-" "elgamal` identifies the algorithm. The parameters correspond to the " "structure :token:`IVXVModPElGamalParameters` and the public key to the " "structure :token:`IVXVModPElGamalPublicKey` (:ref:`asn-modp`)." #: ../../05-ehaal.rst:95 msgid "" "ECC tüüpi rühmade korral identifitseerib algoritmi identifikaator " ":token:`id-ivxv-ecc-elgamal`. Parameetrid vastavad struktuurile " ":token:`IVXVECCElGamalParameters` ning avalik võti struktuurile " ":token:`IVXVECCElGamalPublicKey` (:ref:`asn-ecc`)." msgstr "" "In the case of ECC-type groups, the identifier :token:`id-ivxv-ecc-elgamal` " "identifies the algorithm. The parameters correspond to the structure " ":token:`IVXVECCElGamalParameters` and the public key to the structure " ":token:`IVXVECCElGamalPublicKey` (:ref:`asn-ecc`)." #: ../../05-ehaal.rst:100 msgid "" "Valija tahteavalduse krüpteerimiseks võetakse UTF-8 kodeeringus struktuur " ":token:`ballot` ning teisendatakse see ElGamal parameetrite poolt " "kirjeldatud rühma elemendiks vastavalt MODP või ECC algoritmidele. Rühma " "elemendiks teisendatud tahteavaldus krüpteeritakse ElGamal algoritmiga ning " "kodeeritakse MODP korral struktuuri :token:`IVXVModPElGamalCiphertext` " "(:ref:`asn-modp`) ja ECC korral struktuuri :token:`IVXVECCElGamalCiphertext`" " (:ref:`asn-ecc`). Lõplik krüpteeritud tahteavaldus esitatakse struktuuris " ":token:`IVXVElGamalCiphertext` (:ref:`asn-general`), kus väli " ":token:`algorithm` viitab rühma tüübile ning väli :token:`ciphertext` " "rühmaspetsiifilisele krüptogrammile. Andmestruktuuri " ":token:`IVXVElGamalCiphertext` DER-kodeering on krüpteeritud sedel ehk " "sisemine ümbrik topeltümbriku skeemis." msgstr "" "To encrypt a voter's intent statement, the UTF-8 encoding takes the " "structure :token:`ballot` and converts it to a group element described by " "the ElGamal parameters, according to the MODP or ECC algorithms. The intent " "statement converted to a group element is encrypted by the ElGamal algorithm" " and encoded in the structure :token:`IVXVModPElGamalCiphertext` (:ref:`asn-" "modp`) for MODP and :token:`IVXVECCElGamalCiphertext` (:ref:`asn-ecc`) for " "ECC. The final encrypted intent statement is represented in the structure " ":token:`IVXVElGamalCiphertext` (:ref:`asn-general`), where " ":token:`algorithm` refers to the group type and :token:`ciphertext` refers " "to the group specific ciphertext. The :token:`IVXVElGamalCiphertext` of the " "data structure is the DER encoding of the encrypted tuple, i.e. the inner " "envelope in a double envelope scheme." #: ../../05-ehaal.rst:116 msgid "" "Tahteavalduse krüpteerimise käigus genereeritakse valijarakenduses juhuarv, " "mida ElGamal krüpteerimisel kasutab. Sama juhuarv avalikustatakse hiljem " "kontrollrakendusele. Tulenevalt ElGamal krüptosüsteemi eripärast " "funktsioneerib see juhuarv nö. teise võtmena ning võimaldab krüptogrammi " "dekodeerimist kontrollrakenduses." msgstr "" "During the encryption process, a random number is generated in the voting " "application. This random number is used for encryption by the ElGamal " "method. The same random number is later exposed to the verification " "application. Due to the specificity of the ElGamal cryptosystem, this random" " number functions as a second key and allows the decryption of the " "ciphertext in the verification application." #: ../../05-ehaal.rst:125 msgid "Valija poolt allkirjastatud hääl" msgstr "Vote signed by the voter" #: ../../05-ehaal.rst:127 msgid "" "Krüpteeritud sedel tuleb enne kogumisteenusesse talletamisele saatmist " "digitaalselt allkirjastada, milleks on võimalik kasutada kõiki Eesti " "Vabariigis kehtivaid digitaalallkirjavahendeid – ID-kaart, Digi-ID, Mobiil-" "ID, Smart-ID. ID-kaarti saab kasutada nii TLS-CCA kui Web-eID protokolliga." msgstr "" "The encrypted ballot has to be digitally signed before it is sent to the " "collection service for storage, which can be done using any digital " "signature device valid in the Republic of Estonia - ID-card, Digi-ID, " "Mobile-ID, Smart-ID." #: ../../05-ehaal.rst:134 msgid "" "Loend digitaalallkirjavahenditest ja nendega seotud protokollidest on " "tehniliselt korrektne, kuid valimiste korraldajal on võimalus kasutada vaid " "mõnda alamhulka nimetatud vahenditest." msgstr "" "The list of digital signature devices and associated protocols is " "technically correct, but only a subset of these devices can be used by the " "election organiser." #: ../../05-ehaal.rst:138 msgid "" "Käesolev spetsifikatsioon näeb ette Eesti Vabariigi Standardikavandis " "[BDOC2.1] defineeritud BDOC allkirjavormingu kasutamise. BDOC " "allkirjavorming koosneb ETSI standardi TS 101 903 (XadES) profiilist ning " "OpenDocument konteineri vormingust." msgstr "" "This specification prescribes the use of the BDOC signature format defined " "in the draft Estonian Standard [BDOC2.1]. The BDOC signature format consists" " of the ETSI TS 101 903 (XadES) profile and the OpenDocument container " "format." #: ../../05-ehaal.rst:142 msgid "" "Olenevalt käimasoleval valimisel esitatud küsimuste arvust võib digitaalselt" " allkirjastatud hääl sisaldada ühte või mitut andmefaili MIME-tüübiga " "``application/octet-stream``. Iga andmefaili sisuks on krüpteeritud sedel. " "Andmefaili ja teiste signeeritavate andmeobjektide räsimiseks enne " "allkirjastamist kasutatakse räsifunktsiooni SHA-256. Andmefaili nimi " "moodustatakse laiendist '``ballot``' ning valimise identifikaatorist ja " "küsimuse identifikaatorist. Kõik viidatud andmefailid peavad sisalduma " "allkirjakonteineris. Digitaalselt allkirjastatud hääl ei tohi sisaldada muid" " andmefaile kui neid, mis sisaldavad hääli mõne käimasoleva valimise " "kontekstis. Seadistusele mittevastavate häälte vastuvõtmisest, talletamisest" " ja töötlemisest peab kogumisteenus keelduma." msgstr "" "Depending on the number of questions in the current ballot, the digitally " "signed ballot may contain one or more data files with the MIME type " "``application/octet-stream''. The content of each data file is an encrypted " "message. The SHA-256 hash function is used to hash the data file and other " "data objects to be signed before signing. The name of the data file is " "formed by the extension ``ballot`` and the election identifier and the " "question identifier. All referenced data files must be contained in the " "signature container. A digitally signed ballot must not contain any data " "files other than those containing votes in the context of an ongoing " "election. The collection service must refuse to accept, store and process " "votes that do not conform to the configuration." #: ../../05-ehaal.rst:156 msgid "" "Valimise identifikaator ja küsimuse identifikaator on defineeritud valimise " "korraldaja poolt loodud seadistustes ning töötlevad rakendused peavad " "lähtuma neist seadistustest otsustamaks, millised vormingule vastavad " "identifikaatorid on konkreetse sündmuse kontekstis lubatud ja millised " "mitte." msgstr "" "The choice identifier and the question identifier are defined in the " "settings created by the choice organiser, and processing applications must " "refer to these settings to decide which format identifiers are allowed and " "which are not in the context of a particular event." #: ../../05-ehaal.rst:178 msgid "" "Valija poolt valijarakenduses allkirjastatud hääl moodustatakse nii, et on " "võimalik selle edasine kvalifitseerimine kogumisteenuses. Käesolev " "spetsifikatsioon näeb ette hääle kvalifitseerimiseks nii PKIX ajatempli kui " "OCSP kehtivuskinnituse võtmise. Sellisena on lõplik kvalifitseeritud hääl " "vastav BDOC-TS profiilile." msgstr "" "The vote signed by the voter in the voter application is formed in such a " "way that it can be further qualified in the collection service. This " "specification provides for both a PKIX timestamp and an OCSP validity " "confirmation to be taken to qualify a vote. As such, the final qualified " "vote will conform to the BDOC-TS profile." #: ../../05-ehaal.rst:184 msgid "" "Kui hääl allkirjastatakse ID-kaardi või Digi-ID'ga, siis toimub algse " "allkirjastatud konteineri moodustamine valijarakenduses. Kui hääl " "allkirjastatakse Mobiil-ID või Smart-ID'ga, siis toimub konteineri " "moodustamine valijarakenduse ning kogumisteenuse poolt vahendatava Mobiil-" "ID/Smart-ID teenuse koostöös. Mobiil-ID/Smart-ID juhtumil kasutab " "kogumisteenus Mobiil-ID/Smart-ID teenust ainult signatuuri saamiseks " "krüpteeritud sedelile. Kõik hääle kvalifitseerimiseks vajalikud elemendid " "hangitakse vastavatelt teenustelt alles siis kui valijarakendus on saatnud " "signeeritud hääle talletamiseks. Kvalifitseeritud hääl esitatakse " "kogumisteenuse poolt valijarakendusele verifitseerimiseks, ainult " "kvalifitseeritud hääl peab vastama BDOC 2.1 standardi tingimustele -- " "valijarakenduse poolt moodustatud hääl on vaheetapp kvalifitseeritud hääleni" " jõudmiseks." msgstr "" "If the vote is signed with an ID-card or Digi-ID, the initial signed " "container will be formed in the voting application. If the vote is signed " "with a Mobile-ID or Smart-ID, the containerisation is done in cooperation " "between the voting application and the Mobile-ID/Smart-ID service mediated " "by the collection service. In the case of a Mobile-ID/Smart-ID, the " "collection service will only use the Mobile-ID/Smart-ID service to obtain a " "signature on an encrypted ballot. All the elements necessary to qualify the " "vote are only retrieved from the respective services once the voting " "application has sent the signed vote for storage. The qualified vote is " "submitted by the collection service to the voting application for " "verification, only the qualified vote must meet the requirements of the BDOC" " 2.1 standard -- the vote formed by the voting application is an " "intermediate step to a qualified vote." #: ../../05-ehaal.rst:197 msgid "" "Valijarakenduses signeeritud häälel peab olema üks ja ainult üks allkiri, " "mida hoitakse signatuurifailis :file:`META-INF/signature0.xml`. Häält ja " "allkirja sisaldav konteiner (edaspidi viidatud kui ``SignedVote``) " "moodustatakse BDOC 2.1 standardis kirjeldatud meetodit kasutades." msgstr "" "A vote signed in the voting application must have one and only one " "signature, which is stored in the signature file :file:`META-" "INF/signature0.xml`. The container containing the vote and the signature " "(hereafter referred to as ``SignedVote``) shall be created using the method " "described in BDOC 2.1." #: ../../05-ehaal.rst:202 msgid "" "Spetsifitseerime valijarakenduses allkirjastatud hääle vormingu ühe küsimuse" " korral." msgstr "" "We specify the format of a signed vote in the voting application for a " "single question." #: ../../05-ehaal.rst:205 msgid "" "Räsialgoritmina ``DIGEST_ALG`` on kasutusel SHA-256 " "(http://www.w3.org/2001/04/xmlenc#sha256). XML kanoniseerimiseks " "(``CANON_ALG``) kasutatakse meetodit ``c14n11`` " "(http://www.w3.org/2006/12/xml-c14n11)." msgstr "" "The ``DIGEST_ALG`` algorithm used is SHA-256 " "(http://www.w3.org/2001/04/xmlenc#sha256). XML canonicalisation " "(``CANON_ALG``) is performed using the ``c14n11`` method " "(http://www.w3.org/2006/12/xml-c14n11)." #: ../../05-ehaal.rst:210 msgid "" "ECC võtmete korral on allkirjastamismeetodiks " "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256. RSA võtmeid enam ei " "kasutata." msgstr "" "In case of ECC keys, the signature method is " "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256. RSA keys are no longer " "used." #: ../../05-ehaal.rst:214 msgid "" "Identifikaatorite `VOTE_REF`, `SP_REF`, `SP_URI` ning `SV_URI` täpne väärtus" " ei ole fikseeritud." msgstr "" "The exact value of the identifiers `VOTE_REF`, `SP_REF`, `SP_URI` and " "`SV_URI` is not fixed." #: ../../05-ehaal.rst:218 msgid "Element `SignedProperties`" msgstr "Element `SignedProperties`" #: ../../05-ehaal.rst:220 msgid "" "Element ``SignedProperties`` moodustatakse kooskõlas BDOC 2.1 standardiga. " "Kui kvalifitseerimisel kasutatakse ajatemplit, siis elementi " "``SignaturePolicyIdentifier`` ei kasutata. Ühtegi mitte-kohustuslikku " "elementi ei kasutata. Allkirjastamise kellaaja fikseerib andmestruktuuri " "täitev arvuti ning valija X509-sertifikaat saadakse kas ID-kaardilt, Mobiil-" "ID, Smart-ID või Web eID teenuse vahendusel." msgstr "" "The ``SignedProperties`` element is formed in accordance with the BDOC 2.1 " "standard. If a timestamp is used for qualification, the " "``SignaturePolicyIdentifier`` element shall not be used. No non-mandatory " "element shall be used. The time of signature is fixed by the computer " "executing the data structure and the X509 certificate of the voter is " "obtained either from the ID card, Mobile-ID, Smart-ID or Web eID service." #: ../../05-ehaal.rst:234 msgid "Element `SignedInfo`" msgstr "Element `SignedInfo`" #: ../../05-ehaal.rst:236 msgid "" "Element ``SignedInfo`` moodustatakse kooskõlas BDOC 2.1 standardiga, " "viidates nii krüpteeritud sedelile (``VOTE_DIGEST``) kui elemendile " "``SignedProperties`` (``SP_DIGEST``)." msgstr "" "The ``SignedInfo`` element is formed in accordance with the BDOC 2.1 " "standard, referring to both the encrypted ballot (``VOTE_DIGEST``) and the " "``SignedProperties`` element (``SP_DIGEST``)." #: ../../05-ehaal.rst:246 msgid "Element `SignatureValue`" msgstr "Element 'SignatureValue" #: ../../05-ehaal.rst:248 msgid "" "Element ``SignatureValue`` moodustatakse kooskõlas BDOC 2.1 standardiga. " "Kanoniseeritud elemendist ``SignedInfo`` arvutatakse räsi, mis " "allkirjastatakse PKCS1-meetodiga." msgstr "" "The ``SignatureValue`` element shall be formed in accordance with the BDOC " "2.1 standard. A hash of the canonicalised element ``SignedInfo`` shall be " "computed and signed using the PKCS1 method." #: ../../05-ehaal.rst:258 msgid "Element `XAdESSignatures`" msgstr "Element `XAdESSignatures`" #: ../../05-ehaal.rst:260 msgid "" "Element ``XAdESSignatures`` sisaldab ühte ``Signature`` elementi, mis on " "koostatud lähtudes kõigist eelmistest elementidest ning valija X509 " "sertifikaadist. Elementi ``UnsignedProperties`` ei kasutata." msgstr "" "The ``XAdESSignatures`` element contains a single ``Signature`` element " "which is constructed from all the previous elements and the X509 certificate" " of the voter. The ``UnsignedProperties`` element is not used." ================================================ FILE: Documentation/public/protokollid/locales/en/LC_MESSAGES/06-talletamine.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.8.2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: 2024-03-01 12:50+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" "X-Generator: Poedit 3.4.2\n" #: ../../06-talletamine.rst:5 msgid "Elektroonilise hääle kvalifitseerimine talletamiseks" msgstr "Qualifying an electronic vote for storage" #: ../../06-talletamine.rst:8 msgid "Kvalifitseeritud hääl" msgstr "Qualified vote" #: ../../06-talletamine.rst:10 msgid "" "Valijarakenduse töö tulemusena saadetakse kogumisteenusesse talletamiseks " "topeltümbrik, mis sisaldab endas valija tahteavaldust krüpteeritud kujul, " "valija allkirja krüpteeritud tahteavaldusel kooskõlastatud allkirja- ja " "konteinervormingus ning valija allkirjastamissertifikaati X509-vormingus." msgstr "" "As a result of the work of the voting application, a double envelope " "containing the voter's intent in encrypted form, the voter's signature on " "the encrypted ballot, and the voter's signature certificate in X509 format " "is sent to the collection service for storage." #: ../../06-talletamine.rst:15 msgid "" "Hääle edukaks talletamiseks näeb IVXV protokoll ette hääle registreerimise " "välise registreerimisteenuse osutaja juures ning registreerimistõendi " "valijarakendusele kättesaadavaks tegemise. Valimise korraldaja võib hääle " "kvalifitseerimiseks näha ette täiendavaid samme lisaks registreerimisele -- " "näiteks kehtivuskinnituse hankimist hääle allkirjastanud sertifikaadi kohta." msgstr "" "In order to ensure the successful storage of votes, IVXV protocol provides " "for the registration of votes with an external registration service provider" " and the availability of the registration confirmation in the voting " "application. In order to qualify a vote, the election organiser may provide " "for additional steps beyond registration -- for example, obtaining a " "validation certificate for the certificate that signed the vote." #: ../../06-talletamine.rst:21 msgid "" "Kõik kogumisteenuse poolt hangitavad kvalifitseerivad elemendid, mis " "määravad hääle staatuse hilisemates töötlusetappides, tuleb esitada " "valijarakendusele ning nõudmise korral ka kontrollrakendusele tagamaks, et " "valija saab oma hääle korrektse menetlemise võimalikkusest õigeaegselt " "teada." msgstr "" "All qualifying elements obtained by the collection service that determine " "the status of the vote at subsequent stages of processing must be provided " "to the voting application and, on request, to the verification application " "to ensure that the voter is informed in a timely manner of the possibility " "of their vote being processed correctly." #: ../../06-talletamine.rst:27 msgid "OCSP kehtivuskinnitus" msgstr "OCSP validity confirmation" #: ../../06-talletamine.rst:29 msgid "" "OCSP (*Online Certificate Status Protocol*) on standartne protokoll " "X509-sertifikaatide kehtivusinfo pärimiseks. Kogumisteenus võib seda " "protokolli kasutada hääle allkirjastanud sertifikaadi kehtivuse " "teadasaamiseks. OCSP vastus ütleb, et sertifikaat kehtis päringu tegemise " "ajahetkel, kuid ei seosta OCSP vastust konkreetse allkirjaga." msgstr "" "OCSP (*Online Certificate Status Protocol*) is a standard protocol for " "requesting validity information for X509 certificates. The collection " "service can use this protocol to know the validity of the certificate that " "signed the vote. The OCSP response indicates that the certificate was valid " "at the time of the request, but does not link the OCSP response to a " "specific signature." #: ../../06-talletamine.rst:36 msgid "RFC3161 ajatempel" msgstr "RFC3161 timestamp" #: ../../06-talletamine.rst:38 msgid "" "RFC3161 ajatempli protokolliga saadakse usaldusteenuse pakkujalt kinnitus, " "et mingi andmekogum eksisteeris enne teatud ajahetke. BDOC-TS kontekstis " "ajatembeldatakse allkirja element ``SignatureValue`` kanoniseeritud kujul. " "Klassikaline OCSP vastus koos RFC 3161 vormingus ajatempliga " "kvalifitseerivad BDOC-TS allkirja." msgstr "" "The RFC3161 timestamp protocol is used to obtain confirmation from a trust " "service provider that a dataset existed before a certain point in time. In " "the context of BDOC-TS, the signature element ``SignatureValue`` is " "timestamped in canonicalized form. A classical OCSP response with a " "timestamp in RFC 3161 format qualifies a BDOC-TS signature." #: ../../06-talletamine.rst:47 msgid "Talletamine" msgstr "Storage" #: ../../06-talletamine.rst:49 msgid "Elektroonilise hääle talletamine kogumisteenuses tähendab:" msgstr "Storing an electronic ballot in a collection service means:" #: ../../06-talletamine.rst:51 msgid "" "hääle vastuvõtmist valijarakenduselt ning hääletaja allkirja " "verifitseerimist;" msgstr "" "acceptance of the vote from the voting application and verification of the " "voter's signature;" #: ../../06-talletamine.rst:54 msgid "" "hääle võimalikku kvalifitseerimist -- näiteks sertifikaadi kehtivuse " "tõendamist hääle allkirjastamisele lähedasel ajahetkel;" msgstr "" "possible qualification of the vote -- for example, proof of the validity of " "the certificate at a point in time close to the time the vote was signed;" #: ../../06-talletamine.rst:57 msgid "hääle registreerimist sõltumatus registreerimisteenuses;" msgstr "registering the vote with an independent registration service;" #: ../../06-talletamine.rst:59 msgid "häält kvalifitseerivate elementide vahendamist valijarakendusele." msgstr "" "the transmission of vote qualifying elements to the voting application." #: ../../06-talletamine.rst:61 msgid "" "Erinevad kombinatsioonid allkirjavormingust ning hääli kvalifitseerivatest " "teenustest võivad tekitada erinevaid IVXV-profiile. Konkreetse dokumendi " "raames on IVXV profiil:" msgstr "" "Different combinations of signature format and vote qualifying services can " "produce different IVXV profiles. In the context of a specific document, an " "IVXV profile is:" #: ../../06-talletamine.rst:65 msgid "Allkirjastatud hääle vorming on BDOC-TS;" msgstr "The signed vote format is BDOC-TS;" #: ../../06-talletamine.rst:67 msgid "Kehtivuskinnitusprotokolliks on standartne OCSP;" msgstr "The validation protocol is the standard OCSP;" #: ../../06-talletamine.rst:69 msgid "" "BDOC-TS kvalifitseerimiseks kasutatav RFC3161 ajatempel on kasutusel ka " "registreerimistõendina." msgstr "" "The RFC3161 timestamp used for BDOC-TS qualification is also used as a " "confirmation of registration." ================================================ FILE: Documentation/public/protokollid/locales/en/LC_MESSAGES/06a-regteenus.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.8.2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 19:52+0000\n" "PO-Revision-Date: 2024-03-01 12:42+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.15.0\n" #: ../../06a-regteenus.rst:5 msgid "Elektroonilise hääle registreerimine" msgstr "Registration of Electronic Vote" #: ../../06a-regteenus.rst:7 msgid "" "Hääle edukaks talletamiseks näeb IVXV protokoll ette hääle registreerimise " "välise registreerimisteenuse osutaja juures ning registreerimistõendi " "valijarakendusele kättesaadavaks tegemise. Registreerimisteenus toimub " "RFC3161 ajatempli protokolli baasil. Protokolli on laiendatud selliselt, et " "kogumisteenus saab ajatempli päringule anda oma signatuuri, mis teeb " "võimalikuks hilisema võrdleva väljavõtte registreerimisteenusest. Sõltumatu " "registreerimisteenuse olemasolu vähendab häälte kogumisteenuse poolt " "\"kaotamise\" riski." msgstr "" "In order to ensure the successful storage of votes, IVXV protocol provides " "for the registration of votes with an external registration service provider" " and the availability of the registration confirmation in the voting " "application. The registration service is based on the RFC3161 timestamping " "protocol. The protocol has been extended in such a way that the collection " "service can provide its own signature to the timestamp request, which allows" " for a later comparative extraction from the registration service. The " "existence of an independent registration service reduces the risk of votes " "being 'lost' by the collection service." #: ../../06a-regteenus.rst:17 ../../06a-regteenus.rst:171 msgid "Registreerimisteenus" msgstr "Registration Service" #: ../../06a-regteenus.rst:19 msgid "" "Registreerimisteenus on teenus, mille abil Kogumisteenus registreerib kõik " "Hääletajatelt saadud hääled. Pärast hääletamisperioodi lõppu edastab " "Kogumisteenus talletatud hääled Töötlejale ning Registreerimisteenus edastab" " registreeritud hääled Töötlejale." msgstr "" "The Registration Service is the service through which the Collection Service" " registers all votes received from Voters. After the end of the voting " "period, the Collection Service shall transmit the stored votes to the " "Processor and the Registration Service shall transmit the registered votes " "to the Processor." #: ../../06a-regteenus.rst:24 msgid "" "Registreerimisteenus aitab tagada e-valimiskasti terviklust. Eeldame et " "Kogumisteenusel puudub võimalus võltsida digitaalallkirja ning sellisel moel" " tekitada juurde hääli või muuta juba talletatud hääli. Riskina säilib " "võimalus, et Kogumisteenus ei anna kõiki talletatud hääli Töötlejale üle. " "Häälte valikulise üleandmise riski maandamiseks kasutab IVXV protokoll " "täiendavat Registreerimisteenust, kuhu Kogumisteenus iga talletatud hääle " "registreerib. Hääletajal on protokollikohaselt võimalus korrektses " "registreerimises veenduda -- Registreerimisteenuse digitaalselt " "allkirjastatud kinnitus konkreetse hääle registreerimise kohta esitatakse ka" " konkreetsele hääletajale." msgstr "" "The registration service helps to ensure the integrity of the digital ballot" " box. We assume that the Collection Service has no possibility to forge a " "digital signature and thus generate additional votes or change votes already" " stored. As a risk, there remains the possibility that the Collection " "Service may not deliver all the stored votes to the Processor. In request to" " mitigate the risk of a selective transfer of votes, the IVXV protocol will " "use an additional Registration Service, where each stored vote will be " "registered by the Collection Service. The voter will have the opportunity " "to verify the correct registration according to the protocol -- a digitally " "signed confirmation of the registration of a specific vote by the " "Registration Service will also be provided to the specific voter." #: ../../06a-regteenus.rst:35 msgid "Registreerimisteenus protokollis" msgstr "Registration Service in the protocol" #: ../../06a-regteenus.rst:37 msgid "" "Kogumisteenus saadab Registreerimisteenusele enda poolt allkirjastatud " "registreerimiskorralduse (edaspidi KORRALDUS), mis sisaldab hääle " "identifikaatorit ja allkirjastatud hääle räsi::" msgstr "" "The Collection Service sends to the Registration Service a registration " "request (hereinafter the REQUEST) signed by the Collection Service and " "containing the vote identifier and the signed vote hash:" #: ../../06a-regteenus.rst:43 msgid "" "Registreerimisteenus talletab KORRALDUSE hilisemaks väljastamiseks ning " "vastab Kogumisteenusele oma poolt allkirjastatud registreerimiskinnitusega " "(edaspidi KINNITUS), mis allkirjastab algset KORRALDUST ning KINNITUSE " "väljastamise aega::" msgstr "" "The Registration Service stores the REQUEST for later issuance and responds " "to the Collection Service with a registration confirmation signed by the " "Registration Service (hereinafter the CONFIRMATION), signing the original " "REQUEST and the time of issuance of the CONFIRMATION:" #: ../../06a-regteenus.rst:49 msgid "" "Kogumisteenus tagastab nii KINNITUSE kui KORRALDUSE valijarakendusele, " "Hääletaja saab teate hääle positiivsest talletamisest ainult KINNITUSE ja " "selle aluseks olnud KORRALDUSE edukal verifitseerimisel." msgstr "" "The collection service returns both the CONFIRMATION and the REQUEST to the " "voting application, the Voter will receive notification of a positive vote " "deposit only upon successful verification of the CONFIRMATION and the " "underlying REQUEST." #: ../../06a-regteenus.rst:53 msgid "" "Hääletamisperioodi lõppedes edastab Registreerimisteenus Kogumisteenuse " "poolt tehtud KORRALDUSED Töötlejale." msgstr "" "At the end of the voting period, the REGISTRATION SERVICE forwards the " "REQUESTS made by the COLLECTION SERVICE to the Processor." #: ../../06a-regteenus.rst:56 msgid "" "Registreerimisteenus peab Töötlejale algselt andma üle vähemalt loendi::" msgstr "" "The registration service must initially provide the Processor with at least " "a list of:" #: ../../06a-regteenus.rst:60 msgid "" "Kui Registreerimisteenus annab üle ainult ülalkirjeldatud loendi, siis peab " "ta hiljem oleme võimeline andma loendi nõutud elemendile vastava " "korralduse::" msgstr "" "If the Registration Service delivers only the list described above, it must " "later be able to issue the corresponding request for the requested element " "of the list::" #: ../../06a-regteenus.rst:68 msgid "Registreerimisteenuse roll hääletamisel" msgstr "The role of the registration service in voting" #: ../../06a-regteenus.rst:73 msgid "Registreerimisteenuse roll hääle kontrollimisel" msgstr "The role of the registration service in verifying votes" #: ../../06a-regteenus.rst:78 msgid "Registreerimisteenuse roll häälte üleandmisel" msgstr "The role of the registration service in the transfer of votes" #: ../../06a-regteenus.rst:82 msgid "Registreerimisteenuse liidesed" msgstr "Registration service interfaces" #: ../../06a-regteenus.rst:84 msgid "Registreerimisteenusel on kaks liidest" msgstr "The registration service has two interfaces" #: ../../06a-regteenus.rst:86 msgid "KORRALDUSTE vastuvõtmise ja KINNITUSTE väljastamise liides;" msgstr "" "Interface for the reception of REQUESTS and the issue of CONFIRMATIONS;" #: ../../06a-regteenus.rst:88 msgid "" "KORRALDUSE alusel väljastatud KINNITUSTE loetelu ja nende aluseks olnud " "KORRALDUSTE väljastamise liides." msgstr "" "List of CONFIRMATIONS issued under the REQUEST and the interface for issuing" " the underlying REQUEST." #: ../../06a-regteenus.rst:91 msgid "" "Registreerimisteenuse funktsionaalsuseks on Kogumisteenusele KINNITUSTE " "väljastamine, väljastatud KINNITUSTE ja neile aluseks olevate KORRALDUSTE " "säilitamine ja hilisem Töötlejale üleandmine." msgstr "" "The functionality of the Registration Service is to issue CONFIRMATIONS to " "the Collection Service, to store the issued CONFIRMATIONS and the underlying" " REQUESTS and to later transfer them to the Processor." #: ../../06a-regteenus.rst:95 msgid "" "Kui Registreerimisteenus osutab teenust mitmele erinevale osapoolele, siis " "peab olema garanteeritud, et konkreetse valimisega seotud Kogumisteenuse " "KORRALDUSED ja neile vastavad KINNITUSED on Valijarakenduse ja " "Kontrollrakenduse poolt kontrollitavalt eristatavad teiste osapoolte " "KORRALDUSTEST ning neile vastavatest KINNITUSTEST. Vastasel juhul võib " "tekkida olukord, kus Kogumisteenus küll registreerib hääle, kuid info " "sellest ei jõua Töötlejani." msgstr "" "Where the Registration Service provides a service to several different " "parties, it must be guaranteed that the REQUESTS of the Collection Service " "relating to a particular election and the corresponding CONFIRMATIONS are " "verifiably distinguishable by the Voting Application and the Verification " "Application from the REQUESTS of the other parties and the corresponding " "CONFIRMATIONS. Otherwise, a situation may arise where the Collection Service" " registers a vote but the information does not reach the Processor." #: ../../06a-regteenus.rst:102 msgid "" "Registreerimisteenus peab olema võimeline kõiki Kogumisteenuse poolt tulnud " "KORRALDUSI üle andma." msgstr "" "The Registration Service must be able to deliver all the REQUESTS coming " "from the Collection Service." #: ../../06a-regteenus.rst:106 msgid "Osapoolte nõuded registreerimisteenusele" msgstr "Requirements of registration service" #: ../../06a-regteenus.rst:109 msgid "Töötleja" msgstr "Processor" #: ../../06a-regteenus.rst:111 msgid "Töötleja ülesanne on muuhulgas tuvastada," msgstr "The task of the Processor is, inter alia, to identify," #: ../../06a-regteenus.rst:113 msgid "millised Kogumisteenuse poolt üle antud hääled lähevad lugemisele ja" msgstr "" "which votes handed over by the Collection Service will be counted, and" #: ../../06a-regteenus.rst:115 msgid "kas Kogumisteenus on jätnud hääli üle andmata." msgstr "whether the Collection Service has failed to deliver the votes." #: ../../06a-regteenus.rst:117 msgid "" "Töötleja töö tulemusena selguvaid erisusi tuleb lahendada ning siin on " "järgmised 3 juhtumit:" msgstr "" "The differences that emerge as a result of the processor's work need to be " "resolved, and here are 3 cases:" #: ../../06a-regteenus.rst:120 msgid "" "Kogumisteenus annab Töötlejale üle allkirjastatud hääle koos KINNITUSega, " "Registreerimisteenus annab Töötlejale üle Kogumisteenuse KORRALDUSE, mille " "alusel KINNITUS anti - vaidlust ei ole, kui konkreetne hääl oli antud " "Hääletaja jaoks viimane, siis suunatakse ta lugemisele." msgstr "" "The Collection Service delivers to the Processor the signed vote together " "with the CONFIRMATION, the Registration Service delivers to the Processor " "the Collection Service's REQUEST on the basis of which the CONFIRMATION was " "given - there is no dispute, if the particular vote was the last one given " "for the Voter, it will be forwarded for counting." #: ../../06a-regteenus.rst:125 msgid "" "Kogumisteenus annab Töötlejale üle allkirjastatud hääle koos KINNITUSega, " "Registreerimisteenus ei anna Töötlejale selle hääle kohta midagi üle. Kuna " "KINNITUS on Registreerimisteenuse poolt allkirjastatud, siis on viga " "Registreerimisteenuse poolel. Kui konkreetne hääl oli antud Hääletaja jaoks " "viimane, siis suunatakse ta lugemisele." msgstr "" "The Collection Service will transfer the signed vote to the Processor " "together with the CONFIRMATION, the Registration Service will not transfer " "anything about the vote to the Processor. Since the CONFIRMATION is signed " "by the Registration Service, the error is on the side of the Registration " "Service. If the particular vote was the last one cast for the Voter, it will" " be forwarded for counting." #: ../../06a-regteenus.rst:131 msgid "" "Registreerimisteenus annab Töötlejale üle Kogumisteenuse KORRALDUSE, " "Kogumisteenus ei anna Töötlejale vastava räsiga häält üle. Kuna KORRALDUS on" " Kogumisteenuse poolt allkirjastatud, siis on viga Kogumisteenuse poolel " "ning antud hääl tuleb üles otsida." msgstr "" "The Registration Service will transfer to the Processor the Collection " "Service's REQUEST, the Collection Service will not transfer to the Processor" " the vote with the corresponding hash. As the REQUEST is signed by the " "Collection Service, the error is on the Collection Service's side and the " "vote cast must be retrieved." #: ../../06a-regteenus.rst:137 msgid "Hääletaja" msgstr "Voter" #: ../../06a-regteenus.rst:139 msgid "" "Hääletaja jaoks on oht, et Kogumisteenus võib tema hääle 'unustada'. " "Nõuetekohase KINNITUSE nägemine annab Hääletajale kindluse, et väline " "osapool garanteerib tema hääle Töötlejani jõudmist. Kindluse jaoks on " "oluline:" msgstr "" "For the voter, there is a risk that the Collection Service may 'forget' " "his/her vote. Seeing a proper CONFIRMATION gives the Voter the assurance " "that an external party will guarantee that their vote will reach the " "Processor. Following is important for the certainty:" #: ../../06a-regteenus.rst:143 ../../06a-regteenus.rst:289 msgid "KINNITUS on Registreerimisteenuse poolt allkirjastatud;" msgstr "The CONFIRMATION is signed by the Registration Service;" #: ../../06a-regteenus.rst:145 ../../06a-regteenus.rst:291 msgid "" "KINNITUSES sisalduv algne KORRALDUS on Kogumisteenuse poolt allkirjastatud;" msgstr "" "The original REQUEST contained in the CONFIRMATION is signed by the " "Collection Service;" #: ../../06a-regteenus.rst:147 msgid "" "usaldus, et Registreerimisteenus on võimeline KINNITUSE andmise fakti meeles" " pidama;" msgstr "" "confidence that the Registration Service is capable of remembering the fact " "of giving the CONFIRMATION;" #: ../../06a-regteenus.rst:150 msgid "" "usaldus, et Registreerimisteenus on võimeline KINNITUSE andmise kohasust " "Töötlejale tõestama;" msgstr "" "confidence that the Registration Service is able to prove the " "appropriateness of granting the CONFIRMATION to the Processor;" #: ../../06a-regteenus.rst:153 msgid "" "usaldus, et Kogumisteenusel ei ole võimalik hankida alternatiivset " "valekinnitust, mis Valijarakenduses verifitseerub, kuid Töötlejani ei jõua." msgstr "" "confidence that the Collection Service will not be able to obtain an " "alternative false positive CONFIRMATION that will be verified in the Voting " "Application but will not reach the Processor." #: ../../06a-regteenus.rst:157 msgid "Kogumisteenus" msgstr "Collection Service" #: ../../06a-regteenus.rst:159 msgid "" "Kogumisteenuse jaoks on oht, et Registreerimisteenuse poolt üleantud " "KINNITUSTE ja talletatud häälte vaated erinevad. Kogumisteenuse poolt " "KORRALDUSELE antud allkiri on Kogumisteenuse garantii, et " "Registreerimisteenuse poolt ei saa tekkida fiktiivseid KINNITUSI, mida " "Kogumisteenus tegelikult nõudnud pole." msgstr "" "There is a risk that, for the Collection Service, the views of the " "CONFIRMATIONS transferred by the Registration Service and the stored votes " "will differ. The signature given by the Collection Service to the REQUEST is" " the Collection Service's guarantee that no fictitious REQUESTS cannot be " "generated by the Registration Service that were not actually requested by " "the Collection Service." #: ../../06a-regteenus.rst:164 msgid "" "Kogumisteenus talletab kõiki Registreerimisteenuse vastuseid. Kuna need on " "allkirjastatud, siis on täiendav info oluline vaid siis kui Kogumisteenus " "väidab, et mingit KORRALDUST ei ole antud, kuigi Registreerimisteenus on " "``(v_id, Hash(VOTE))`` esitanud. Sellisel juhul saab Registreerimisteenus " "esitada terve Kogumisteenuse KORRALDUSE (või vähemalt selle allkirjastatud " "komponendi)" msgstr "" "The Collection Service stores all responses from the Registration Service. " "Since they are signed, the additional information is only relevant if the " "Collection Service claims that no REQUEST has been given, even though the " "Registration Service has provided ``(v_id, Hash(VOTE))``. In such a case, " "the Registration Service can provide the entire ORDER of the Collection " "Service (or at least a signed component of it)." #: ../../06a-regteenus.rst:173 msgid "" "Registreerimisteenus on huvitatud, et vaidlusolukordades, kus Kogumisteenus " "jätab midagi üle andmata, oleks tal võimalik oma tegevuse korrektsust " "tõestada. Oluline on tagada:" msgstr "" "The Registration Service is interested in being able to prove the " "correctness of its actions in the event of a dispute where the Collection " "Service fails to deliver something. It is important to ensure:" #: ../../06a-regteenus.rst:177 msgid "" "Kogumisteenuse poolt konkreetse valimise raames antavad KORRALDUSED on " "teiste klientide poolt esitatud KORRALDUSTEST kontrollitavalt eristatavad." msgstr "" "The REQUESTS provided by the collection service in the context of a specific" " election are verifiably distinguishable from the REQUESTS provided by other" " customers." #: ../../06a-regteenus.rst:180 msgid "" "Kogumisteenus ei saa juba esitatud KORRALDUSTE kohta väita, et ta neid ei " "esitanud." msgstr "" "The collection service cannot claim that it has not already submitted the " "REQUESTS." #: ../../06a-regteenus.rst:184 msgid "Registreerimisteenuse realiseerimine RFC 3161 protokolli raamistikus" msgstr "Registry service implementation in the RFC 3161 protocol framework" #: ../../06a-regteenus.rst:186 msgid "" "PKIX on ajatembeldusprotokoll, kus usaldatav kolmas osapool " "(ajatempliteenuse osutaja ehk ATO) kinnitab oma allkirjaga andmete " "eksisteerimist konkreetsel ajahetkel. Protokoll koosneb ühest päringust ja " "vastusest." msgstr "" "PKIX is a timestamping protocol, where a trusted third party (a timestamp " "authority or TSA) confirms the existence of data at a specific point in time" " with its signature. The protocol consists of a single request and response." #: ../../06a-regteenus.rst:190 msgid "Ajatemplipäring::" msgstr "Timestamp request::" #: ../../06a-regteenus.rst:202 msgid "" "Ajatembeldatavad andmed esitatakse teenusele ``messageImprint`` koosseisus " "räsina. ``TimeStampReq`` ei sisalda endas päringu esitaja allkirja." msgstr "" "The data to be timestamped shall be submitted to the ``messageImprint`` " "service as a raster. The ``TimeStampReq`` shall not include the signature of" " the requester." #: ../../06a-regteenus.rst:205 msgid "ATO vastus ajatemplipäringule::" msgstr "TSA response to timestamp request::" #: ../../06a-regteenus.rst:234 msgid "" "``TimeStampResp`` on ATO poolt digitaalselt allkirjastatud konteiner, mis " "sisaldab endas päringu koosseisus saadud välja ``messageImprint`` ning " "nonssi." msgstr "" "The ``TimeStampResp`` is a digitally signed container by the ATO containing " "the ``messageImprint`` field and the nonss received in the query " "configuration." #: ../../06a-regteenus.rst:237 msgid "" "Registreerimisteenuse huvides on, et Kogumisteenuse päring oleks " "signeeritud. Kuna RFC 3161 ei toeta allkirjastatud päringuid on " "alternatiiviks kasutada mõnda laiendust, mis võimaldab Kogumisteenuse " "signatuuri edastamist. See laiendus tuleks teenuse poolt ajatempli " "koosseisus ka tagasi saata. Kuna RFC 3161 ei sõnasta laienduste " "tagasipeegeldamise nõuet ühemõtteliselt on reaalne võimalus kasutada " "protokolli laiendamiseks ajatemplipäringu nonssi. Nonss on ASN.1 INTEGER " "andmetüüp kuhu saab kodeerida suvalise struktuuriga andmeid, mis teeb " "võimalikuks järgmise skeemi:" msgstr "" "It is in the interest of the registration service that the request by " "Collection Service is signed. Since RFC 3161 does not support signed " "requests, an alternative is to use an extension that allows the transmission" " of the Collection Service signature. This extension should also be returned" " by the service as part of the timestamp. Since RFC 3161 does not explicitly" " state the requirement for reflecting extensions, a real possibility is to " "use a timestamp request nonsign to extend the protocol. A nonss is an ASN.1 " "INTEGER data type into which data of arbitrary structure can be encoded, " "which makes the following scheme possible:" #: ../../06a-regteenus.rst:246 msgid "Enne hääletamist:" msgstr "Before the vote:" #: ../../06a-regteenus.rst:248 msgid "Kogumisteenus genereerib allkirjastamisvõtme ja sertifikaadi." msgstr "The Collection Service generates a signature key and a certificate." #: ../../06a-regteenus.rst:250 msgid "Kogumisteenus annab sertifikaadi Korraldajale üle." msgstr "The Collection Service will deliver the certificate to the Organiser." #: ../../06a-regteenus.rst:252 msgid "Kogumisteenus seadistab ennast ATO'd kasutama." msgstr "The Collection Service configures itself to use the TSA." #: ../../06a-regteenus.rst:254 msgid "Hääletamise ajal:" msgstr "During the voting:" #: ../../06a-regteenus.rst:256 msgid "Valija saadab hääle talletamiseks." msgstr "The voter sends the vote to be recorded." #: ../../06a-regteenus.rst:258 msgid "" "Kogumisteenus räsib hääle, allkirjastab räsi ning võtab räsile ajatempli, " "kasutades ajatemplipäringu TimeStampReq nonsina oma allkirja sellel räsil." msgstr "" "The Collection Service casts a vote, signs the hash and takes a timestamp on" " the hash, using your signature on the hash as a TimeStampReq noun." #: ../../06a-regteenus.rst:261 msgid "" "ATO töötleb ajatemplipäringut kooskõlas RFC 3161 nõuetega ning väljastab " "allkirjastatud ajatempli." msgstr "" "The TSA processes the timestamp request in accordance with RFC 3161 and " "issues a signed timestamp." #: ../../06a-regteenus.rst:264 msgid "" "Kogumisteenus vahendab ajatempli Valijarakendusele, mis teostab järgmised " "kontrollid:" msgstr "" "The Collection Service sends a timestamp to the Voting Application, which " "performs the following checks:" #: ../../06a-regteenus.rst:267 msgid "ajatempel on ATO poolt allkirjastatud," msgstr "the timestamp is signed by the TSA," #: ../../06a-regteenus.rst:268 msgid "ajatempel sisaldab nonssi," msgstr "the timestamp includes the nonce," #: ../../06a-regteenus.rst:269 msgid "ajatempel sisaldab tema hääle räsi," msgstr "The timestamp contains the hash of her vote," #: ../../06a-regteenus.rst:270 msgid "nonss on Kogumisteenuse poolt allkirjastatud valija hääle räsi." msgstr "" "nonce is a hash of voter's signed vote signed by the Collection Service." #: ../../06a-regteenus.rst:272 msgid "Peale hääletamist:" msgstr "After the vote:" #: ../../06a-regteenus.rst:274 msgid "Korraldaja annab ATO'le ajavahemiku ja Kogumisteenuse sertifikaadi" msgstr "" "The Organiser will provide the TSA with a time period and a Collection " "Service certificate" #: ../../06a-regteenus.rst:276 msgid "" "ATO otsib kõigi selle ajavahemiku ajatemplipäringute ja vastuste hulgast " "neid, millel" msgstr "" "The TSA will search for all timestamp requests and responses in this period " "for those that have" #: ../../06a-regteenus.rst:279 msgid "on nonss," msgstr "a nonce," #: ../../06a-regteenus.rst:280 msgid "nonss dekodeerub kokkuleppeliseks andmestruktuuriks," msgstr "the nonce is decodable into a specified data structure," #: ../../06a-regteenus.rst:281 msgid "andmestruktuur verifitseerub Kogumisteenuse sertifikaadiga." msgstr "the data structure is verifiable by a Collection Service certificate." #: ../../06a-regteenus.rst:283 msgid "ATO annab üle kõik leitud ajatemplipäringud ja ajatemplid." msgstr "The TSA will hand over all timestamp requests and timestamps found." #: ../../06a-regteenus.rst:285 msgid "Kogumisteenus annab üle kõik ajatemplipäringud, ajatemplid ja hääled." msgstr "" "The Collection Service will deliver all timestamp requests, timestamps and " "votes." #: ../../06a-regteenus.rst:287 msgid "Töötleja analüüsib andmeid vastavalt protokollile" msgstr "The Processor analyses the data according to the protocol" #: ../../06a-regteenus.rst:293 msgid "" "Usaldus, et Registreerimisteenus on võimeline KINNITUSE andmise fakti meeles" " pidama;" msgstr "" "Confirmation that the Registration Service is able to remember the fact of " "the CONFIRMATION;" #: ../../06a-regteenus.rst:296 msgid "" "Usaldus, et Kogumisteenusel ei ole võimalik hankida alternatiivset " "valekinnitust, mis Valijarakenduses verifitseerub, kuid Töötlejani ei jõua" msgstr "" "Confirmation that it is not possible for the Collection Service to obtain an" " alternative false positive that will be verified in the Voting Application " "but will not reach the Processor" #: ../../06a-regteenus.rst:299 msgid "" "Usaldus, et Registreerimisteenus on võimeline KINNITUSE andmise kohasust " "Töötlejale tõestama;" msgstr "" "Confirmation that the Registration Service is able to prove the " "appropriateness of granting the CONFIRMATION to the Processor;" #: ../../06a-regteenus.rst:302 msgid "" "Registreerimisteenuse poolt ei saa tekkida fiktiivseid KINNITUSI, mida " "Kogumisteenus tegelikult nõudnud pole" msgstr "" "No fictitious CONFIRMATIONS can be generated by the Registration Service " "which are not actually required by the Collection Service" #: ../../06a-regteenus.rst:305 msgid "" "Kogumisteenus ei saa juba esitatud KORRALDUSTE kohta väita, et ta neid ei " "esitanud" msgstr "" "The collection service cannot claim that it did not submit the REQUESTS " "already submitted" #: ../../06a-regteenus.rst:308 msgid "Nonsi vorming::" msgstr "Nonce format::" #: ../../06a-regteenus.rst:320 msgid "Sõnumiks on TimeStampReq.messageImprint DER-kodeering::" msgstr "The message is TimeStampReq.messageImprint DER encoding::" #: ../../06a-regteenus.rst:327 msgid "" "RSA kasutamisel allkirjastamiseks. välja " "``Signature.signingAlgorithm.algorithm`` väärtus sõltub sõnumi " "``hashAlgorithm`` välja väärtusest::" msgstr "" "When using RSA for signing. field ``Signature.signingAlgorithm.algorithm`` " "the value depends on the value of the ``hashAlgorithm`` field of the " "message::" #: ../../06a-regteenus.rst:339 msgid "Väli ``Signature.signingAlgorithm.parameters`` puudub või on NULL." msgstr "" "The ``Signature.signingAlgorithm.parameters`` field is missing or NULL." #: ../../06a-regteenus.rst:341 msgid "" "Väli ``Signature.signature`` on OCTET STRING, mis sisaldab RSA signatuuri " "sõnumil." msgstr "" "The ``Signature.signature`` field is an OCTET STRING containing the RSA " "signature on the message." #: ../../06a-regteenus.rst:344 msgid "ATO väljavõte" msgstr "TSA extract" #: ../../06a-regteenus.rst:346 msgid "" "ATO väljavõte Kogumisteenuse poolt esitatud TimeStampReq vormingus " "päringutest esitatakse ZIP failina, kus iga päring on salvestatud ühte " "faili, mis vastab järgmistele tingimustele:" msgstr "" "The TSA extract of the requests submitted by the Collection Service in " "TimeStampReq format will be presented as a ZIP file, where each request is " "stored in a single file that meets the following conditions:" #: ../../06a-regteenus.rst:350 msgid "Kaustastruktuur puudub, ükski fail ei paikne kaustas." msgstr "There is no folder structure, no files are located in a folder." #: ../../06a-regteenus.rst:351 msgid "Failinimed on unikaalsed (failinimedele samas tähendust ei omistata)." msgstr "" "File names are unique (file names are not given any meaning at the same " "time)." #: ../../06a-regteenus.rst:353 msgid "Üleantav andmekomplekt on:" msgstr "The data set to be transferred is:" #: ../../06a-regteenus.rst:355 msgid "Andmefail: `.zip`" msgstr "Data file: `.zip`" #: ../../06a-regteenus.rst:356 msgid "Kontrollsummafail: `.zip.sha256sum.asice`" msgstr "Checksum file: `.zip.sha256sum.asice`" #: ../../06a-regteenus.rst:358 msgid "" "Üherealise kontrollsummafaili sisu on HEX kodeeringus SHA256 räsi " "andmefailist." msgstr "" "The contents of the single line checksum file are HEX encoded from the " "SHA256 hash data file." ================================================ FILE: Documentation/public/protokollid/locales/en/LC_MESSAGES/07-kontrollimine.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.8.2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-05 11:29+0000\n" "PO-Revision-Date: 2024-03-01 17:59+0200\n" "Last-Translator: \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../07-kontrollimine.rst:5 msgid "Elektroonilise hääle kontrollimine eraldi ja e-valimiskasti koosseisus" msgstr "" "Verification of electronic votes separately and as part of a digital " "ballot box" #: ../../07-kontrollimine.rst:7 msgid "" "Elektroonilist häält kontrollitakse töötlemisrakenduses, kogumisteenuses," " valijarakenduses ja kontrollrakenduses." msgstr "" "The electronic vote is verified in the processing application, the " "collection service, the voting application and the verification " "application." #: ../../07-kontrollimine.rst:10 msgid "" "Kõige põhjalikuma kontrolli läbib elektrooniline hääl e-valimiskasti " "koosseisus töötlemisrakenduses, kus otsustatakse konkreetse hääle " "lugemisele saatmine või mittesaatmine. Nende kontrollide käigus " "vaadeldakse e-häält nii eraldi kui ka suhtes kõigi teiste sama valija " "poolt antud häältega. Täiendavalt kõrvutatakse e-valimiskasti " "registreerimisteenuse väljavõttega." msgstr "" "The most thorough check of an electronic vote takes place in the " "processing application within the e-voting box, where the decision to " "send or not to send a particular vote is made. During these checks, the " "e-vote is examined both individually and in relation to all other votes " "cast by the same voter. A further comparison is made with the e-voting " "box registration service extract." #: ../../07-kontrollimine.rst:16 msgid "" "Iga üksiku hääle kohta läbitakse töötlemisrakendusega analoogsel tasemel " "kontroll valijarakenduses, kus veendutakse, et kogumisteenus on hääle " "kvalifitseerinud selliselt, et töötlemisrakenduses tehtavad kontrollid " "õnnestuvad. Valijarakenduse kontrollidega samaväärsed kontrollid viib " "läbi kontrollrakendus." msgstr "" "For each individual vote, a check is performed in the voting application " "at a level analogous to that in the processing application, to ensure " "that the collection service has qualified the vote in such a way that the" " checks in the processing application are successful. Checks equivalent " "to those carried out in the Voting Application shall be carried out by " "the Verification Application." #: ../../07-kontrollimine.rst:22 msgid "" "Kogumisteenus on lisaks vastutav mitme hääle lõplikuks " "kvalifitseerumiseks vajaliku elemendi hankimise eest ning teostab ka " "nende hankimise järgselt kontrollid." msgstr "" "In addition, the collection service is responsible for the procurement of" " the elements necessary for the final qualification of several votes, and" " also carries out post-qualification checks." #: ../../07-kontrollimine.rst:27 msgid "Lõpliku elektroonilise hääle komponendid" msgstr "Components of the final electronic voice" #: ../../07-kontrollimine.rst:29 msgid "" "Elemendid, mis on kättesaadavad otsustamise hetkel, kas hääl " "kvalifitseerub lugemisele saatmiseks või mitte:" msgstr "" "Elements available at the moment of deciding whether or not a vote " "qualifies to be sent for counting:" #: ../../07-kontrollimine.rst:32 msgid "elektroonilist häält sisaldav konteiner - :ref:`entity-haale-konteiner`;" msgstr "container containing electronic voice - :ref:`entity-haale-konteiner`;" #: ../../07-kontrollimine.rst:34 msgid "krüpteeritud sedel - :ref:`entity-krypteeritud-sedel`;" msgstr "encrypted ballot - :ref:`entity-krypteeritud-sedel`;" #: ../../07-kontrollimine.rst:36 msgid "valija signatuur krüpteeritud sedelil - :ref:`entity-haale-signatuur`;" msgstr "voter signature on encrypted ballot - :ref:`entity-haale-signatuur`;" #: ../../07-kontrollimine.rst:38 msgid "valija allkiri krüpteeritud sedelil - :ref:`entity-haale-allkiri`;" msgstr "voter signature on encrypted ballot - :ref:`entity-haale-allkiri`;" #: ../../07-kontrollimine.rst:40 msgid "valija allkirjastamissertifikaat - :ref:`entity-valija-sertifikaat`;" msgstr "voter signing certificate - :ref:`entity-valija-sertifikaat`;" #: ../../07-kontrollimine.rst:42 msgid "valija isikukood - :ref:`entity-valija-identiteet`;" msgstr "voter identity code - :ref:`entity-valija-identiteet`;" #: ../../07-kontrollimine.rst:44 msgid "" "kvalifitseeriv element - valija sertifikaadi kehtivuskinnitus - :ref" ":`entity-kehtivuskinnitus`;" msgstr "" "qualifying element - confirmation of the validity of the voter's " "certificate - :ref:`entity-kehtivuskinnitus`;" #: ../../07-kontrollimine.rst:47 msgid "" "kvalifitseeriv element - ajatempel allkirjastatud krüpteeritud sedelile -" " :ref:`entity-ajatempel`;" msgstr "" "qualifying element - timestamp on a signed encrypted ballot - :ref" ":`entity-ajatempel`;" #: ../../07-kontrollimine.rst:50 msgid "" "kvalifitseeriv element - registreerimispäringu konteiner :ref:`entity-" "registreerimisparing-konteiner`;" msgstr "" "Creating a registration request - :ref:`entity-registreerimisparing-" "konteiner`" #: ../../07-kontrollimine.rst:53 msgid "" "kvalifitseeriv element - registreerimispäring allkirjastatud krüpteeritud" " sedelile - :ref:`entity-registreerimisparing`;" msgstr "" "qualifying element - registration certificate for signed and encrypted " "vote - :ref:`entity-registreerimisparing`;" #: ../../07-kontrollimine.rst:56 msgid "" "kvalifitseeriv element - registreerimistõend allkirjastatud krüpteeritud " "sedeli kohta - :ref:`entity-registreerimistoend`;" msgstr "" "qualifying element - registration certificate for signed and encrypted " "vote - :ref:`entity-registreerimistoend`;" #: ../../07-kontrollimine.rst:59 msgid "" "valija ringkonnakuuluvuse tõend hääle andmise hetkel - :ref:`entity-" "nimekirjatunnus`." msgstr "" "proof of the voter's district eligibility at the time of voting - :ref" ":`entity-nimekirjatunnus`." #: ../../07-kontrollimine.rst:63 msgid "" "Elemendid, mis on kättesaadavad otsustamise hetkel, kuidas häält " "kokkulugemisel arvesse võtta:" msgstr "" "The elements available at the moment of deciding how to take the vote " "into account in the count:" #: ../../07-kontrollimine.rst:66 msgid "miksitud krüpteeritud sedel - :ref:`entity-miksitud-krypteeritud-sedel`;" msgstr "mixed encrypted ballot - :ref:`entity-miksitud-krypteeritud-sedel`;" #: ../../07-kontrollimine.rst:68 msgid "valija tahteavaldus avakujul - :ref:`entity-tahteavaldus`;" msgstr "voter's plaintext intent - :ref:`entity-tahteavaldus`;" #: ../../07-kontrollimine.rst:70 msgid "ringkonnakuuluvuse tunnus - :ref:`entity-ringkonnatunnus`;" msgstr "district membership - :ref:`entity-ringkonnatunnus`;" #: ../../07-kontrollimine.rst:72 msgid "" "ringkonnapõhine valikute nimekiri - :ref:`entity-ringkonna-" "valikutenimekiri`." msgstr "district-based candidate list - :ref:`entity-ringkonna-valikutenimekiri`." #: ../../07-kontrollimine.rst:75 msgid "Täiendavad elemendid:" msgstr "Additional elements:" #: ../../07-kontrollimine.rst:77 msgid "" "krüpteerimisel kasutatud juhuslikkus - :ref:`entity-juhuslikkus`; - " "luuakse valijarakenduses hääle krüpteerimisel ning vahendatakse ainult " "kontrollrakendusele." msgstr "" "randomness used in encryption - :ref:`entity-juhuslikkus`; - is generated" " in the voter application when the vote is encrypted and is only " "transmitted to the verification application." #: ../../07-kontrollimine.rst:86 msgid "TAHTEAVALDUS" msgstr "INTENT" #: ../../07-kontrollimine.rst:88 msgid "" "Olem moodustatakse valijarakenduses ning tuvastatakse võtmerakenduses. " "Tegemist on EHS spetsiifilises vormingus UTF-8 kodeeringus baidijadaga." msgstr "" "The item is created in the voter application and identified in the key " "application. It is an EHS specific format UTF-8 encoded byte string." #: ../../07-kontrollimine.rst:94 msgid "TAHTEAVALDUS, vormingu korrektsus" msgstr "INTENT, correctness of the format" #: ../../07-kontrollimine.rst:96 msgid "" "Tahteavalduse vormingu korrektsuse kontroll käesoleva spetsifikatsiooni " "suhtes." msgstr "" "Verification of the correctness of the intent format against this " "specification." #: ../../07-kontrollimine.rst:102 msgid "TAHTEAVALDUS, RINGKONNATUNNUS, RINGKONNA VALIKUTENIMEKIRI kooskõlalisus" msgstr "INTENT, DISTRICT MEMBERSHIP, DISTRICT CHOICES consistency " #: ../../07-kontrollimine.rst:104 msgid "" "Tahteavalduses sisalduva valiku kontroll ringkonnatunnuse ja valikute " "nimekirja suhtes. Kontroll õnnestub, kui tuvastatud valik on kättesaadav " "antud ringkonnas." msgstr "" "Checking the choice identified by the intent against the district " "membership and the district choices. The check succeeds if the identified" " option is available in the given district." #: ../../07-kontrollimine.rst:111 msgid "TAHTEAVALDUS, RINGKONNA VALIKUTENIMEKIRI, kooskõlalisus" msgstr "INTENT, DISTRICT CHOICES, consistency" #: ../../07-kontrollimine.rst:113 msgid "" "Tahteavalduses sisalduva valiku kontroll ringkonnapõhise valikute " "nimekirja suhtes. Kontroll õnnestub, kui tuvastatud valik on kättesaadav " "antud ringkonnas." msgstr "" "Checking the choice identified by the intent against the list of " "district-based choices. The check succeeds if the identified option is " "available in the given district." #: ../../07-kontrollimine.rst:121 msgid "JUHUSLIKKUS" msgstr "RANDOMNESS" #: ../../07-kontrollimine.rst:123 msgid "" "Olem moodustatakse valijarakenduses ning kasutatakse ka " "kontrollrakenduses. Olem esitatakse EHS spetsiifilises vormingus " "baidijadana ning peab olema ühilduv avaliku võtme parameetrite poolt " "määratud matemaatilise rühmaga." msgstr "" "The item is created in the voter application and is also used in the " "verification application. The element shall be presented in an EHS " "specific format as a byte string and shall be compatible with the " "mathematical group specified by the public key parameters." #: ../../07-kontrollimine.rst:130 msgid "JUHUSLIKKUS, vormingu korrektsus" msgstr "RANDOMNESS, correctness of formatting" #: ../../07-kontrollimine.rst:132 msgid "" "Juhuslikkuse vormingu korrektsuse kontroll käesoleva spetsifikatsiooni " "suhtes." msgstr "Randomness format correctness check against this specification." #: ../../07-kontrollimine.rst:137 msgid "JUHUSLIKKUS, kooskõlalisus avaliku võtmega" msgstr "RANDOMNESS, consistency with the public key" #: ../../07-kontrollimine.rst:139 msgid "" "Juhuslikkuse kooskõlalisuse kontroll avaliku võtmega. Kontroll õnnestub " "kui juhuslikkus on kasutatav skalaarina arvutusteks avaliku võtme " "parameetrite poolt määratud matemaatilises rühmas." msgstr "" "Randomness consistency check with public key. The check succeeds if the " "randomness can be used as a scalar for calculations in the mathematical " "group specified by the parameters of the public key." #: ../../07-kontrollimine.rst:147 msgid "KRÜPTEERITUD SEDEL" msgstr "ENCRYPTED BALLOT" #: ../../07-kontrollimine.rst:149 msgid "" "Olem moodustatakse valijarakenduses. Tegemist on EHS spetsiifilises " "vormingus DER-kodeeritud andmestruktuuriga, mille kontrollimise aluseks " "on EHS avalik võti, mis muuhulgas määratleb krüpteerimisel kasutatud " "matemaatilise rühma." msgstr "" "The item is formed in the voting application. It is a DER encoded data " "structure in a specific format of the EHS, which is verified by the EHS " "public key, which, among other things, defines the mathematical group " "used for encryption." #: ../../07-kontrollimine.rst:156 msgid "KRÜPTEERITUD SEDEL, vormingu korrektsus" msgstr "ENCRYPTED BALLOT, format correctness" #: ../../07-kontrollimine.rst:158 msgid "" "Krüpteeritud sedeli vormingu korrektsuse kontroll käesoleva " "spetsifikatsiooni suhtes." msgstr "Verification of the encrypted ballot format against this specification." #: ../../07-kontrollimine.rst:164 msgid "KRÜPTEERITUD SEDEL, kooskõlalisus avaliku võtmega" msgstr "ENCRYPTED BALLOT, consistency with public key" #: ../../07-kontrollimine.rst:166 msgid "" "Krüpteeritud sedeli kooskõlalisuse kontroll avaliku võtmega. Kontroll " "õnnestub kui krüpteeritud sedeli komponendid on kasutatavad rühma " "liikmetena arvutusteks avaliku võtme parameetrite poolt määratud " "matemaatilises rühmas." msgstr "" "Checking the consistency of an encrypted ballot with a public key. The " "check succeeds if the components of the encrypted ballot are usable as " "members of a group for computations in the mathematical group specified " "by the public key parameters." #: ../../07-kontrollimine.rst:173 msgid "KRÜPTEERITUD SEDEL, JUHUSLIKKUS, kooskõlalisus" msgstr "ENCRYPTED BALLOT, RANDOMNESS, consistency" #: ../../07-kontrollimine.rst:175 msgid "" "Krüpteeritud sedeli kooskõlalisuse kontroll juhuslikkusega lähtudes rühma" " parameetritest. Kontroll õnnestub kui õnnestub näidata, et antud " "juhuslikkust on kasutatud krüpteeritud sedeli komponendi `uBlind` " "arvutamiseks antud rühma parameetrite järgi." msgstr "" "Checking the consistency of an encrypted ballot with randomness based on " "group parameters. A check succeeds if it can be shown that the given " "randomness has been used to compute the `uBlind` component of the " "ciphertext from the given group parameters." #: ../../07-kontrollimine.rst:185 msgid "VALIJA SERTIFIKAAT" msgstr "VOTER CERTIFICATE" #: ../../07-kontrollimine.rst:187 msgid "" "Olem on valijale omistatud süsteemiväliselt. Tegemist on X.509 vormingus " "sertifikaadiga, mille kehtivuse kontrolli aluseks on samasse avaliku " "võtme infrastruktuuri kuuluvad juursertifikaadid ja " "kehtivuskinnitusteenuse osutaja." msgstr "" "The item is assigned to the voter externally. It is an X.509 format " "certificate whose validity is checked by the root certificates and the " "validation service provider, which are part of the same public key " "infrastructure." #: ../../07-kontrollimine.rst:194 msgid "VALIJA SERTIFIKAAT, vormingu korrektsus" msgstr "VOTER CERTIFICATE, correct formatting" #: ../../07-kontrollimine.rst:196 msgid "" "Valija sertifikaadi vormingu korrektsuse kontroll lähtudes X.509 " "spetsifikatsioonist." msgstr "" "Verification of the correctness of the format of the voter certificate " "based on the X.509 specification." #: ../../07-kontrollimine.rst:201 msgid "VALIJA SERTIFIKAAT, protokollikohane kooskõlalisus valimise seadistustega" msgstr "VOTER CERTIFICATE, protocol consistency with election settings" #: ../../07-kontrollimine.rst:203 msgid "" "Valija sertifikaadi protokollikohase kooskõlalisuse kontroll valimise " "seadistustega. Kontroll õnnestub kui:" msgstr "" "Checking the conformance of the voter certificate with the election " "settings. The check succeeds if:" #: ../../07-kontrollimine.rst:206 msgid "" "Valija sertifikaat on kehtiv lähtudes sertifikaadis sisalduvast " "kehtivusajast;" msgstr "" "The voter's certificate is valid for the period of validity contained in " "the certificate;" #: ../../07-kontrollimine.rst:208 msgid "" "Valija sertifikaat kuulub mõnda valimise seadistustes kirjeldatud " "sertifitseerimishierarhiatest." msgstr "" "The voter certificate belongs to one of the certification hierarchies " "described in the election settings." #: ../../07-kontrollimine.rst:215 msgid "" "VALIJA SERTIFIKAAT, KEHTIVUSKINNITUS, protokollikohane kooskõlalisus " "valimise seadistustega" msgstr "" "VOTER CERTIFICATE, CERTIFICATE VALIDITY PROOF, protocol compliance with " "the election settings." #: ../../07-kontrollimine.rst:217 msgid "" "Valija sertifikaadi ja kehtivuskinnituse protokollikohase kooskõlalisuse " "kontroll valimise seadistustega. Kontroll õnnestub kui:" msgstr "" "Checking that the voter certificate and the certificate validity proof " "are in accordance with the protocol and in line with the election " "settings. The check succeeds if:" #: ../../07-kontrollimine.rst:220 msgid "" "Kehtivuskinnitus on korrektselt allkirjastatud kehtivuskinnituse teenuse " "osutaja poolt, kellel on seadistuste kohaselt voli valija sertifikaadi " "kehtivust tõendada" msgstr "" "A certificate validity proof is correctly signed by validation service " "provider who has the power, according to the settings, to verify the " "validity of the voter's certificate." #: ../../07-kontrollimine.rst:224 msgid "Kehtivuskinnitus on väljastatud valija sertifikaadi kohta;" msgstr "A validation certificate is issued for a voter certificate;" #: ../../07-kontrollimine.rst:226 msgid "Kehtivuskinnitus näitab valija sertifikaadi OCSP olekuks 'Kehtiv'." msgstr "" "The validity confirmation indicates the OCSP status of the voter's " "certificate as 'Valid'." #: ../../07-kontrollimine.rst:233 msgid "VALIJA IDENTITEET" msgstr "VOTER IDENTITY" #: ../../07-kontrollimine.rst:235 msgid "" "Olem on valijale omistatud süsteemiväliselt. Tegemist on isikukoodiga, " "mille kontrollimise aluseks on VALIJA SERTIFIKAAT." msgstr "" "The item is assigned to the voter externally. It is a personal " "identification code, which is verified by the VOTER CERTIFICATE." #: ../../07-kontrollimine.rst:241 msgid "VALIJA IDENTITEET, vormingu korrektsus" msgstr "VOTER IDENTITY, correctness of formatting" #: ../../07-kontrollimine.rst:243 msgid "" "Valija identiteedi vormingu korrektsuse kontroll lähtudes Eesti Vabariigi" " isikukoodi vormingust." msgstr "" "Verification of the correctness of the format of the voter's identity " "based on the format of the personal identity code of the Republic of " "Estonia." #: ../../07-kontrollimine.rst:249 msgid "VALIJA IDENTITEET, NIMEKIRJATUNNUS, hääleõigus" msgstr "VOTER IDENTITY, DISTRICT ID, eligibility" #: ../../07-kontrollimine.rst:251 msgid "" "Hääleõiguse kontroll valija identiteedi ja nimekirjatunnuse alusel. " "Kontroll õnnestub, kui valija identiteet on kantud nimekirjatunnusele " "vastavasse valijate nimekirja. Sellisel juhul on identiteedile omistatud " "ka ringkonnatunnus, mis määrab ringkonnaspetsiifilise valikute nimekirja." msgstr "" "Verification of the right to vote based on voter identity and district " "id. The check is successful if the voter's identity is entered in the " "electoral roll corresponding to the district id. In this case, the " "identity is also assigned a precinct identifier, which determines the " "precinct-specific list of choices." #: ../../07-kontrollimine.rst:260 msgid "HÄÄLE SIGNATUUR" msgstr "VOTE SIGNATURE" #: ../../07-kontrollimine.rst:262 msgid "" "Olem arvutatakse allkirjastamise vahendi poolt lähtudes valijarakenduse " "poolt sisendiks antud KRÜPTEERITUD SEDELI räsist." msgstr "" "The element is calculated by the signing tool on the basis of the " "ENCRYPTED BALLOT given as input by the voter application." #: ../../07-kontrollimine.rst:268 msgid "HÄÄLE SIGNATUUR, vormingu korrektsus" msgstr "VOTE SIGNATURE, correctness of the format" #: ../../07-kontrollimine.rst:270 msgid "" "Hääle signatuuri vormingu korrektsuse kontroll lähtudes konkreetsest " "signeerimismeetodist." msgstr "" "Verification of the correctness of the vote signature format based on a " "specific signing method." #: ../../07-kontrollimine.rst:276 msgid "HÄÄLE SIGNATUUR, KRÜPTEERITUD SEDEL, VALIJA SERTIFIKAAT, kooskõlalisus" msgstr "VOTE SIGNATURE, ENCRYPTED BALLOT, VOTER CERTIFICATE, consistency" #: ../../07-kontrollimine.rst:278 msgid "" "Kontroll, mis õnnestub siis ja ainult siis kui õnnestub verifitseerida, " "et hääle signatuur on arvutatud krüpteeritud sedeli räsist kasutades " "valija sertifikaadis leiduvale avalikule võtmele vastavat privaatvõtit." msgstr "" "A check that succeeds if and only if it can be verified that the " "signature of the vote is computed from a hash of the encrypted ciphertext" " using the private key corresponding to the public key in the voter's " "certificate." #: ../../07-kontrollimine.rst:286 msgid "HÄÄLE ALLKIRI" msgstr "SIGNED VOTE" #: ../../07-kontrollimine.rst:288 msgid "" "Olem moodustatakse valijarakenduses, talletades hääle signatuuri allkirja" " vormingusse." msgstr "" "An item is formed in the voter application by storing the signature of " "the vote in a signature format." #: ../../07-kontrollimine.rst:293 msgid "HÄÄLE ALLKIRI, vormingu korrektsus" msgstr "SIGNED VOTE, correct formatting" #: ../../07-kontrollimine.rst:295 msgid "" "Hääle allkirja vormingu korrektsuse kontroll käesoleva spetsifikatsiooni " "suhtes." msgstr "" "Verification of the correctness of the signed vote format against this " "specification." #: ../../07-kontrollimine.rst:300 msgid "HÄÄLE ALLKIRI, HÄÄLE SIGNATUUR, kooskõlalisus" msgstr "SIGNED VOTE, VOTE SIGNATURE, consistency" #: ../../07-kontrollimine.rst:302 msgid "" "Hääle allkirja ja hääle signatuuri kooskõlalisuse kontroll. Kontroll " "õnnestub, kui antud allkiri sisaldab antud signatuuri." msgstr "" "Verification of the consistency of the signed vote and the vote " "signature. The check succeeds if the signed vote contains the given " "signature." #: ../../07-kontrollimine.rst:309 msgid "HÄÄLE KONTEINER" msgstr "VOTE CONTAINER" #: ../../07-kontrollimine.rst:311 msgid "" "Olem moodustatakse valijarakenduses, luues vormingukohane konteiner, mis " "sisaldab muuhulgas krüpteeritud sedelit, hääle allkirja ja valija " "sertifikaati." msgstr "" "The item is formed in the voter application by creating a formatted " "container containing, among other things, the encrypted ballot, the " "voter's signature and the voter's certificate." #: ../../07-kontrollimine.rst:317 msgid "HÄÄLE KONTEINER, vormingu korrektsus" msgstr "VOTE CONTAINER, format correctness" #: ../../07-kontrollimine.rst:319 msgid "" "Hääle konteineri vormingu korrektsuse kontroll käesoleva " "spetsifikatsiooni suhtes." msgstr "" "Verification of the correctness of the vote container format with respect" " to this specification." #: ../../07-kontrollimine.rst:324 msgid "" "HÄÄLE KONTEINER, HÄÄLE ALLKIRI, VALIJA SERTIFIKAAT, KRÜPTEERITUD SEDEL, " "kooskõlalisus" msgstr "" "VOTE CONTAINER, SIGNED VOTE, VOTER CERTIFICATE, ENCRPYPTED BALLOT, " "consistency" #: ../../07-kontrollimine.rst:326 msgid "" "Hääle konteineri, hääle allkirja, valija sertifikaadi ja krüpteeritud " "sedeli kooskõlalisuse kontroll. Kontroll õnnestub kui antud konteiner " "sisaldab konkreetset hääle allkirja, valija sertifikaati ja krüpteeritud " "sedelit." msgstr "" "Verification of the consistency of the vote container, the signed vote, " "the voter certificate and the encrypted ballot. The check succeeds if the" " given container contains a specific vote signature, voter certificate " "and encrypted ballot." #: ../../07-kontrollimine.rst:334 msgid "KEHTIVUSKINNITUS" msgstr "CERTIFICATE VALIDITY PROOF" #: ../../07-kontrollimine.rst:336 msgid "" "Olemi hankimise eest vastutab kogumisteenus. Tegemist on OCSP vormingus " "kinnitusega valija sertifikaadi oleku kohta." msgstr "" "The collection service is responsible for the procurement of the item. " "This is a confirmation of the status of the voter's certificate in OCSP " "format." #: ../../07-kontrollimine.rst:342 msgid "KEHTIVUSKINNITUS, vormingu korrektsus" msgstr "CERTIFICATE VALIDITY PROOF, correctness of the format" #: ../../07-kontrollimine.rst:344 msgid "" "Kehtivuskinnituse vormingu korrektsuse kontroll OCSP spetsifikatsiooni " "suhtes." msgstr "" "Validation of the correctness of the validation format against the OCSP " "specification." #: ../../07-kontrollimine.rst:350 msgid "KEHTIVUSKINNITUS, AJATEMPEL, ajaline järgnevus" msgstr "CERTIFICATE VALIDITY PROOF, TIMESTAMP, chronological sequence" #: ../../07-kontrollimine.rst:352 msgid "" "Kehtivuskinnituse ja ajatempli ajalise järgnevuse kontroll. Kontroll " "õnnestub, kui" msgstr "" "Verification of the chronological sequence of the certificate validity " "proof and the timestamp. The check is successful if" #: ../../07-kontrollimine.rst:354 msgid "ajatempel ei ole väljastatud hiljem kui kehtivuskinnitus;" msgstr "" "the time stamp is issued no later than the date of validity of the " "certificate validity proof;" #: ../../07-kontrollimine.rst:356 msgid "" "ajatempli ja kehtivuskinnituse väljastamise ajaline vahe on väiksem kui " "valimise seadistustes ette nähtud aeg." msgstr "" "the time difference between the issue of the timestamp and the " "certificate validity proof is less than determined in election settings." #: ../../07-kontrollimine.rst:364 msgid "AJATEMPEL" msgstr "TIMESTAMP" #: ../../07-kontrollimine.rst:366 msgid "" "Olemi hankimise eest vastutab kogumisteenus. Tegemist on PKIX vormingus " "ajatempliga." msgstr "" "The collection service is responsible for the procurement of the item. " "This is a timestamp in PKIX format." #: ../../07-kontrollimine.rst:371 msgid "AJATEMPEL, vormingu korrektsus" msgstr "TIMESTAMP, correctness of formatting" #: ../../07-kontrollimine.rst:373 msgid "Ajatempli vormingu korrektsuse kontroll PKIX spetsifikatsiooni suhtes." msgstr "" "Checking the correctness of the timestamp format against the PKIX " "specification." #: ../../07-kontrollimine.rst:379 msgid "" "AJATEMPEL, HÄÄLE ALLKIRI, protokollikohane kooskõlalisus valimise " "seadistustega" msgstr "TIMESTAMP, VOTE SIGNATURE, protocol consistency with election settings" #: ../../07-kontrollimine.rst:381 msgid "" "Ajatempli protokollikohase kooskõlalisuse kontroll valimise " "seadistustega. Kontroll õnnestub kui:" msgstr "" "Checking the timestamp protocol consistency with the election settings. " "The check succeeds if:" #: ../../07-kontrollimine.rst:384 msgid "" "ajatempel on korrektselt allkirjastatud valimise seadistuses volitatud " "ajatempliteenuse osutaja poolt;" msgstr "" "the timestamp is correctly signed by the provider authorized in the " "election settings" #: ../../07-kontrollimine.rst:387 msgid "ajatempel on võetud hääle allkirjale." msgstr "The timestamp has been taken to the signature of the vote." #: ../../07-kontrollimine.rst:393 msgid "REGISTREERIMISPÄRING" msgstr "REGISTRATION REQUEST" #: ../../07-kontrollimine.rst:395 ../../07-kontrollimine.rst:443 msgid "" "Olem moodustatakse kogumisteenuses. Olemi talletamise eest vastutab " "registreerimisteenuse osutaja." msgstr "" "The item is formed in the collection service. The storage of the item is " "the responsibility of the registration service provider." #: ../../07-kontrollimine.rst:401 msgid "REGISTREERIMISPÄRING, vormingu korrektsus" msgstr "REGISTRATION REQUEST, correctness of format" #: ../../07-kontrollimine.rst:403 msgid "" "Registreerimispäringu vormingu korrektsuse kontroll käesoleva " "spetsifikatsiooni suhtes." msgstr "" "Verification of the correctness of the registration request format " "against this specification." #: ../../07-kontrollimine.rst:409 msgid "" "REGISTREERIMISPÄRING, HÄÄLE ALLKIRI, protokollikohane kooskõlalisus " "valimise seadistustega" msgstr "" "REGISTRATION REQUEST, VOTE SIGNATURE, protocol consistency with election " "settings" #: ../../07-kontrollimine.rst:411 msgid "" "Registreerimispäringu ja hääle allkirja protokollikohase kooskõlalisuse " "kontroll valimise seadistustega. Kontroll õnnestub kui:" msgstr "" "Verification of the consistency of the registration request and the vote " "signature with the protocol settings for the election. The check succeeds" " if:" #: ../../07-kontrollimine.rst:414 msgid "Registreerimispäring on koostatud hääle allkirjale;" msgstr "" "The registration request is drawn up on the basis of the signature of the" " vote;" #: ../../07-kontrollimine.rst:416 ../../07-kontrollimine.rst:428 #: ../../07-kontrollimine.rst:465 msgid "" "Registreerimispäring on korrektselt allkirjastatud valimise seadistuses " "viidatud kogumisteenuse poolt." msgstr "" "The registration request has been correctly signed by the collection " "service shown in the election settings." #: ../../07-kontrollimine.rst:423 msgid "REGISTREERIMISPÄRING, REGISTREERIMISTÕEND, kooskõlalisus" msgstr "REGISTRATION REQUEST, REGISTRATION CERTIFICATE, consistency" #: ../../07-kontrollimine.rst:425 msgid "" "Registreerimispäringu ja registreerimistõendi protokollikohase " "kooskõlalisuse kontroll valimise seadistustega. Kontroll õnnestub kui:" msgstr "" "Verification of the consistency of the registration request and the " "registration certificate with the protocol election settings. The check " "succeeds if:" #: ../../07-kontrollimine.rst:431 msgid "Registreerimistõend on koostatud vastuseks samale registreerimispäringule;" msgstr "" "The registration certificate is issued in response to the same " "registration request;" #: ../../07-kontrollimine.rst:433 ../../07-kontrollimine.rst:499 msgid "" "Registreerimistõend on korrektselt allkirjastatud valimise seadistuses " "viidatud registreerimisteenuse poolt." msgstr "" "The certificate of registration is correctly signed by the service " "provider defined in the election settings." #: ../../07-kontrollimine.rst:441 msgid "REGISTREERIMISPÄRINGU KONTEINER" msgstr "REGISTRATION REQUEST CONTAINER" #: ../../07-kontrollimine.rst:449 msgid "REGISTREERIMISPÄRINGU KONTEINER, vormingu korrektsus" msgstr "REGISTRATION REQUEST CONTAINER, correctness of format" #: ../../07-kontrollimine.rst:451 msgid "" "Registreerimispäringu konteineri vormingu korrektsuse kontroll käesoleva " "spetsifikatsiooni suhtes." msgstr "" "Verification of the correctness of the registration request container " "format with respect to this specification." #: ../../07-kontrollimine.rst:458 msgid "" "REGISTREERIMISPÄRINGU KONTEINER, REGISTREERIMISPÄRING, protokollikohane " "kooskõlalisus valimise seadistustega" msgstr "" "REGISTRATION REQUEST CONTAINER, REGISTRATION REQUEST, protocol " "consistency with election settings" #: ../../07-kontrollimine.rst:460 msgid "" "Registreerimispäringu konteineri ja registreerimispäringu " "protokollikohase kooskõlalisuse kontroll valimise seadistustega. Kontroll" " õnnestub kui:" msgstr "" "Check the consistency of the registration request container and the " "registration request protocol with the election settings. The check " "succeeds if:" #: ../../07-kontrollimine.rst:463 msgid "Registreerimispäringu konteiner sisaldab registreerimispäringut;" msgstr "The registration request container contains the registration request;" #: ../../07-kontrollimine.rst:473 msgid "REGISTREERIMISTÕEND" msgstr "REGISTRATION CERTIFICATE" #: ../../07-kontrollimine.rst:475 msgid "" "Olemi hankimise eest vastutab kogumisteenus, olemi moodustab " "registreerimisteenuse osutaja." msgstr "" "The collection service is responsible for the procurement of the item, " "the item is formed by the registration service provider." #: ../../07-kontrollimine.rst:481 msgid "REGISTREERIMISTÕEND, vormingu korrektsus" msgstr "REGISTRATION CERTIFICATE, correctness of format" #: ../../07-kontrollimine.rst:483 msgid "" "Registreerimistõendi vormingu korrektsuse kontroll käesoleva " "spetsifikatsiooni suhtes." msgstr "" "Verification of the correctness of the format of the registration " "certificate against this specification." #: ../../07-kontrollimine.rst:489 msgid "" "REGISTREERIMISTÕEND, HÄÄLE ALLKIRI, protokollikohane kooskõlalisus " "valimise seadistustega" msgstr "" "REGISTRATION CERTIFICATE, VOTE SIGNATURE, protocol consistency with " "election settings" #: ../../07-kontrollimine.rst:491 msgid "" "Registreerimistõendi ja hääle allkirja protokollikohase kooskõlalisuse " "kontroll valimise seadistustega. Kontroll õnnestub kui:" msgstr "" "Verification of the consistency of the certificate of registration and " "the signature of the vote with the protocol settings for the election. " "The check succeeds if:" #: ../../07-kontrollimine.rst:494 msgid "Registreerimistõend on koostatud hääle allkirjale;" msgstr "The registration certificate is drawn up on the signature of the vote;" #: ../../07-kontrollimine.rst:496 msgid "" "Registreerimistõend sisaldab kogumisteenuse poolt korrektselt " "allkirjastatud registreerimispäringut;" msgstr "" "The registration certificate shall contain the following information, " "duly completed by the collection service." #: ../../07-kontrollimine.rst:507 msgid "NIMEKIRJATUNNUS" msgstr "LIST IDENTIFIER" #: ../../07-kontrollimine.rst:509 msgid "" "Olem moodustatakse kogumisteenuses ning identifitseerib ühe konkreetse " "versiooni valijate nimekirjast." msgstr "" "An item is formed in the collection service and identifies one specific " "version of the voter list." #: ../../07-kontrollimine.rst:515 msgid "NIMEKIRJATUNNUS, vormingu korrektsus" msgstr "LIST IDENTIFIER, correctness of formatting" #: ../../07-kontrollimine.rst:517 msgid "" "Nimekirjatunnuse vormingu korrektsuse kontroll käesoleva " "spetsifikatsiooni suhtes." msgstr "" "Verification of the correctness of the list identifier format with " "respect to this specification." #: ../../07-kontrollimine.rst:522 msgid "NIMEKIRJATUNNUS, protokollikohane kooskõlalisus valimise seadistusega" msgstr "LIST IDENTIFIER, protocol consistency with the selection setting" #: ../../07-kontrollimine.rst:524 msgid "" "Nimekirjatunnuse protokollikohase kooskõlalisuse kontroll valimise " "seadistusega. Kontroll õnnestub kui valimise seadistuses sisalduvate " "muudatusnimekirjade alusel on võimalik koostada nimekirjatunnusele vastav" " nimekiri." msgstr "" "Checking the protocol consistency of the list identifier with the " "election setting. The check succeeds if the voter list updates contained " "in the election configuration can be used to generate a voterlist " "corresponding to the list identifier." #: ../../07-kontrollimine.rst:534 msgid "MIKSITUD KRÜPTEERITUD SEDEL" msgstr "MIXED ENCRYPTED BALLOT" #: ../../07-kontrollimine.rst:536 msgid "" "Olem moodustatakse miksimisrakenduses. Miksitud krüpteeritud sedel on " "sisuliselt krüpteeritud sedel ning rakenduvad samad kontrollid, mis " "krüpteeritud sedelilegi." msgstr "" "The element is formed in the mixing application. A mixed encrypted ballot" " is essentially an encrypted ballot and the same controls apply as for an" " encrypted ballot." #: ../../07-kontrollimine.rst:543 msgid "MIKSITUD KRÜPTEERITUD SEDEL, vormingu korrektsus" msgstr "MIXED ENCRYPTED BALLOT, format correctness" #: ../../07-kontrollimine.rst:545 msgid "" "Miksitud krüpteeritud sedeli vormingu korrektsuse kontroll käesoleva " "spetsifikatsiooni suhtes." msgstr "" "Verification of the correctness of the format of the mixed encrypted " "ballot with respect to this specification." #: ../../07-kontrollimine.rst:551 msgid "MIKSITUD KRÜPTEERITUD SEDEL, kooskõlalisus avaliku võtmega" msgstr "MIXED ENCRYPTED BALLOT, consistency with public key" #: ../../07-kontrollimine.rst:553 msgid "" "Miksitud krüpteeritud sedeli kooskõlalisuse kontroll avaliku võtmega. " "Kontroll õnnestub kui miksitud krüpteeritud sedeli komponendid on " "kasutatavad rühma liikmetena arvutusteks avaliku võtme parameetrite poolt" " määratud matemaatilises rühmas." msgstr "" "Checking the consistency of a mixed encrypted ballot with a public key. " "The check succeeds if the components of the mixed encrypted ballot are " "usable as members of a group for computations in the mathematical group " "specified by the public key parameters." #: ../../07-kontrollimine.rst:563 msgid "RINGKONNATUNNUS" msgstr "DISTRICT IDENTIFIER" #: ../../07-kontrollimine.rst:565 msgid "" "Olem moodustatakse töötlemisrakenduses ning viitab ringkonnapõhisele " "valikute nimekirjale." msgstr "" "The item is created in the processing application and refers to a " "district-based list of choices." #: ../../07-kontrollimine.rst:571 msgid "RINGKONNATUNNUS, vormingu korrektsus" msgstr "DISTRICT IDENTIFIER, correctness of formatting" #: ../../07-kontrollimine.rst:573 msgid "" "Ringkonnatunnuse vormingu korrektsuse kontroll käesoleva " "spetsifikatsiooni suhtes." msgstr "" "Verification of the correctness of the district identifier format with " "respect to this specification." #: ../../07-kontrollimine.rst:579 msgid "RINGKONNAPÕHINE VALIKUTE NIMEKIRI" msgstr "DISTRICT CHOICES" #: ../../07-kontrollimine.rst:581 msgid "Olem on valijale omistatud süsteemiväliselt." msgstr "The item is assigned to the voter externally." #: ../../07-kontrollimine.rst:586 msgid "RINGKONNAPÕHINE VALIKUTE NIMEKIRI, vormingu korrektsus" msgstr "DISTRICT CHOICES, format correctness" #: ../../07-kontrollimine.rst:588 msgid "" "Ringkonnapõhise valikute nimekirja vormingu korrektsuse kontroll VIS " "liideste spetsifikatsiooni suhtes." msgstr "" "Verification of the correctness of the format of the district-based list " "of choices against the VIS interface specification." #: ../../07-kontrollimine.rst:592 msgid "Kontrollid kogumisteenuses" msgstr "Checks in the Collection Service" #: ../../07-kontrollimine.rst:594 msgid "" "Kogumisteenus käsitleb talletatavat häält sõltumatult teistest häältest. " "Kogumisteenuse ülesandeks on hääle talletamine kogu hääletamisperioodi " "vältel ja häälele töötlemise käigus kvalifitseerumiseks vajalike " "elementide hankimine." msgstr "" "The collection service treats the vote to be stored independently of " "other votes. The role of the collection service is to store votes " "throughout the voting period and to obtain the elements necessary to " "qualify a vote during the processing." #: ../../07-kontrollimine.rst:598 msgid "Kogumisteenus saab valijarakenduselt järgmised olemid:" msgstr "A collection service receives following items from the voter application:" #: ../../07-kontrollimine.rst:600 ../../07-kontrollimine.rst:712 #: ../../07-kontrollimine.rst:819 ../../07-kontrollimine.rst:898 #: ../../07-kontrollimine.rst:1013 ../../07-kontrollimine.rst:1086 msgid ":ref:`entity-krypteeritud-sedel`" msgstr "" #: ../../07-kontrollimine.rst:602 ../../07-kontrollimine.rst:720 #: ../../07-kontrollimine.rst:750 ../../07-kontrollimine.rst:821 #: ../../07-kontrollimine.rst:900 ../../07-kontrollimine.rst:1027 #: ../../07-kontrollimine.rst:1088 msgid ":ref:`entity-valija-sertifikaat`" msgstr "" #: ../../07-kontrollimine.rst:604 ../../07-kontrollimine.rst:722 #: ../../07-kontrollimine.rst:751 ../../07-kontrollimine.rst:823 #: ../../07-kontrollimine.rst:902 ../../07-kontrollimine.rst:1029 #: ../../07-kontrollimine.rst:1090 msgid ":ref:`entity-valija-identiteet`" msgstr "" #: ../../07-kontrollimine.rst:606 ../../07-kontrollimine.rst:726 #: ../../07-kontrollimine.rst:825 ../../07-kontrollimine.rst:904 #: ../../07-kontrollimine.rst:1031 ../../07-kontrollimine.rst:1092 msgid ":ref:`entity-haale-signatuur`" msgstr "" #: ../../07-kontrollimine.rst:608 ../../07-kontrollimine.rst:714 #: ../../07-kontrollimine.rst:827 ../../07-kontrollimine.rst:906 #: ../../07-kontrollimine.rst:1033 ../../07-kontrollimine.rst:1094 msgid ":ref:`entity-haale-allkiri`" msgstr "" #: ../../07-kontrollimine.rst:610 ../../07-kontrollimine.rst:716 #: ../../07-kontrollimine.rst:829 ../../07-kontrollimine.rst:908 #: ../../07-kontrollimine.rst:1035 ../../07-kontrollimine.rst:1096 msgid ":ref:`entity-haale-konteiner`" msgstr "" #: ../../07-kontrollimine.rst:612 msgid "" "Kogumisteenus hangib hääle töötlemise käigus välistelt teenustelt " "järgmised olemid:" msgstr "" "In the course of vote processing, the Collection Service obtains the " "following entities from external services:" #: ../../07-kontrollimine.rst:614 ../../07-kontrollimine.rst:728 #: ../../07-kontrollimine.rst:779 ../../07-kontrollimine.rst:831 #: ../../07-kontrollimine.rst:910 ../../07-kontrollimine.rst:1037 #: ../../07-kontrollimine.rst:1098 msgid ":ref:`entity-kehtivuskinnitus`" msgstr "" #: ../../07-kontrollimine.rst:616 ../../07-kontrollimine.rst:730 #: ../../07-kontrollimine.rst:780 ../../07-kontrollimine.rst:833 #: ../../07-kontrollimine.rst:912 ../../07-kontrollimine.rst:1039 #: ../../07-kontrollimine.rst:1100 msgid ":ref:`entity-ajatempel`" msgstr "" #: ../../07-kontrollimine.rst:618 ../../07-kontrollimine.rst:732 #: ../../07-kontrollimine.rst:781 ../../07-kontrollimine.rst:835 #: ../../07-kontrollimine.rst:918 ../../07-kontrollimine.rst:1045 #: ../../07-kontrollimine.rst:1106 msgid ":ref:`entity-registreerimistoend`" msgstr "" #: ../../07-kontrollimine.rst:620 msgid "Kogumisteenus tuvastab / loob ise järgmised olemid:" msgstr "The collection service detects/creates the following entities:" #: ../../07-kontrollimine.rst:622 ../../07-kontrollimine.rst:734 #: ../../07-kontrollimine.rst:782 ../../07-kontrollimine.rst:837 #: ../../07-kontrollimine.rst:914 ../../07-kontrollimine.rst:1041 #: ../../07-kontrollimine.rst:1102 msgid ":ref:`entity-registreerimisparing`" msgstr "" #: ../../07-kontrollimine.rst:624 ../../07-kontrollimine.rst:738 #: ../../07-kontrollimine.rst:843 ../../07-kontrollimine.rst:916 #: ../../07-kontrollimine.rst:1043 ../../07-kontrollimine.rst:1104 msgid ":ref:`entity-registreerimisparing-konteiner`" msgstr "" #: ../../07-kontrollimine.rst:626 ../../07-kontrollimine.rst:740 #: ../../07-kontrollimine.rst:845 ../../07-kontrollimine.rst:920 #: ../../07-kontrollimine.rst:1047 ../../07-kontrollimine.rst:1108 msgid ":ref:`entity-nimekirjatunnus`" msgstr "" #: ../../07-kontrollimine.rst:628 ../../07-kontrollimine.rst:742 #: ../../07-kontrollimine.rst:847 ../../07-kontrollimine.rst:926 #: ../../07-kontrollimine.rst:1015 ../../07-kontrollimine.rst:1074 msgid ":ref:`entity-ringkonnatunnus`" msgstr "" #: ../../07-kontrollimine.rst:630 ../../07-kontrollimine.rst:724 #: ../../07-kontrollimine.rst:839 ../../07-kontrollimine.rst:922 #: ../../07-kontrollimine.rst:1049 ../../07-kontrollimine.rst:1076 msgid ":ref:`entity-ringkonna-valikutenimekiri`" msgstr "" #: ../../07-kontrollimine.rst:632 msgid "Kogumisteenus ei puutu vahetult kokku järgmiste olemitega:" msgstr "The collection service does not come into direct contact with:" #: ../../07-kontrollimine.rst:634 ../../07-kontrollimine.rst:708 #: ../../07-kontrollimine.rst:813 ../../07-kontrollimine.rst:933 #: ../../07-kontrollimine.rst:1023 ../../07-kontrollimine.rst:1080 msgid ":ref:`entity-tahteavaldus`" msgstr "" #: ../../07-kontrollimine.rst:636 ../../07-kontrollimine.rst:710 #: ../../07-kontrollimine.rst:817 ../../07-kontrollimine.rst:935 #: ../../07-kontrollimine.rst:1025 ../../07-kontrollimine.rst:1084 msgid ":ref:`entity-juhuslikkus`" msgstr "" #: ../../07-kontrollimine.rst:638 ../../07-kontrollimine.rst:744 #: ../../07-kontrollimine.rst:849 ../../07-kontrollimine.rst:931 #: ../../07-kontrollimine.rst:1019 ../../07-kontrollimine.rst:1072 msgid ":ref:`entity-miksitud-krypteeritud-sedel`" msgstr "" #: ../../07-kontrollimine.rst:640 msgid "" "Kogumisteenus viib läbi järgmised tegevused ja teostab järgmised " "kontrollid:" msgstr "The collection service will carry out the following activities and checks:" #: ../../07-kontrollimine.rst:642 msgid "Hääle talletamise päringu vastuvõtmine valijarakenduselt" msgstr "Receiving a vote storage request from a voter application" #: ../../07-kontrollimine.rst:644 ../../07-kontrollimine.rst:753 #: ../../07-kontrollimine.rst:853 ../../07-kontrollimine.rst:952 msgid ":ref:`check-valija-sertifikaat-correctness`" msgstr "" #: ../../07-kontrollimine.rst:645 ../../07-kontrollimine.rst:754 #: ../../07-kontrollimine.rst:854 ../../07-kontrollimine.rst:953 msgid ":ref:`check-valija-sertifikaat-consistency-protocol-settings`" msgstr "" #: ../../07-kontrollimine.rst:646 ../../07-kontrollimine.rst:755 #: ../../07-kontrollimine.rst:856 ../../07-kontrollimine.rst:954 msgid ":ref:`check-valija-identiteet-correctness`" msgstr "" #: ../../07-kontrollimine.rst:647 ../../07-kontrollimine.rst:957 msgid ":ref:`check-valija-identiteet-nimekirjatunnus-eligibility`" msgstr "" #: ../../07-kontrollimine.rst:648 ../../07-kontrollimine.rst:770 #: ../../07-kontrollimine.rst:857 ../../07-kontrollimine.rst:959 msgid ":ref:`check-haale-signatuur-correctness`" msgstr "" #: ../../07-kontrollimine.rst:649 ../../07-kontrollimine.rst:771 #: ../../07-kontrollimine.rst:858 ../../07-kontrollimine.rst:960 msgid "" ":ref:`check-haale-signatuur-krypteeritud-sedel-valija-sertifikaat-" "consistency`" msgstr "" #: ../../07-kontrollimine.rst:650 ../../07-kontrollimine.rst:859 #: ../../07-kontrollimine.rst:961 msgid ":ref:`check-haale-allkiri-correctness`" msgstr "" #: ../../07-kontrollimine.rst:651 ../../07-kontrollimine.rst:860 #: ../../07-kontrollimine.rst:962 msgid ":ref:`check-haale-allkiri-haale-signatuur-consistency`" msgstr "" #: ../../07-kontrollimine.rst:652 ../../07-kontrollimine.rst:861 #: ../../07-kontrollimine.rst:963 msgid ":ref:`check-haale-konteiner-correctness`" msgstr "" #: ../../07-kontrollimine.rst:653 ../../07-kontrollimine.rst:862 #: ../../07-kontrollimine.rst:964 msgid "" ":ref:`check-haale-konteiner-haale-allkiri-valija-sertifikaat-" "krypteeritud-sedel-consistency`" msgstr "" #: ../../07-kontrollimine.rst:654 ../../07-kontrollimine.rst:875 #: ../../07-kontrollimine.rst:998 ../../07-kontrollimine.rst:1055 msgid ":ref:`check-krypteeritud-sedel-correctness`" msgstr "" #: ../../07-kontrollimine.rst:655 ../../07-kontrollimine.rst:876 #: ../../07-kontrollimine.rst:999 ../../07-kontrollimine.rst:1056 msgid ":ref:`check-krypteeritud-sedel-public-key-consistency`" msgstr "" #: ../../07-kontrollimine.rst:657 msgid "Kehtivuskinnituse hankimine - :ref:`entity-kehtivuskinnitus`" msgstr "Obtaining certificate validation proof - :ref:`entity-kehtivuskinnitus`" #: ../../07-kontrollimine.rst:659 ../../07-kontrollimine.rst:784 #: ../../07-kontrollimine.rst:863 ../../07-kontrollimine.rst:965 msgid ":ref:`check-kehtivuskinnitus-correctness`" msgstr "" #: ../../07-kontrollimine.rst:660 ../../07-kontrollimine.rst:785 #: ../../07-kontrollimine.rst:855 ../../07-kontrollimine.rst:966 msgid ":ref:`check-valija-sertifikaat-kehtivuskinnitus-consistency`" msgstr "" #: ../../07-kontrollimine.rst:662 msgid "Ajatempli hankimine - :ref:`entity-ajatempel`" msgstr "Getting a timestamp - :ref:`entity-ajatempel`" #: ../../07-kontrollimine.rst:664 ../../07-kontrollimine.rst:786 #: ../../07-kontrollimine.rst:864 ../../07-kontrollimine.rst:967 msgid ":ref:`check-ajatempel-correctness`" msgstr "" #: ../../07-kontrollimine.rst:665 ../../07-kontrollimine.rst:787 #: ../../07-kontrollimine.rst:865 ../../07-kontrollimine.rst:968 msgid ":ref:`check-ajatempel-consistency-protocol-settings`" msgstr "" #: ../../07-kontrollimine.rst:667 msgid "Registreerimispäringu loomine - :ref:`entity-registreerimisparing`" msgstr "Creating a registration request - :ref:`entity-registreerimisparing`" #: ../../07-kontrollimine.rst:669 msgid "Registreerimistõendi hankimine - :ref:`entity-registreerimistoend`" msgstr "Obtaining a registration certificate - :ref:`entity-registreerimistoend`" #: ../../07-kontrollimine.rst:671 ../../07-kontrollimine.rst:792 #: ../../07-kontrollimine.rst:869 ../../07-kontrollimine.rst:990 msgid ":ref:`check-registreerimisparing-registreerimistoend-consistency`" msgstr "" #: ../../07-kontrollimine.rst:672 ../../07-kontrollimine.rst:793 #: ../../07-kontrollimine.rst:870 ../../07-kontrollimine.rst:970 msgid ":ref:`check-registreerimistoend-correctness`" msgstr "" #: ../../07-kontrollimine.rst:673 ../../07-kontrollimine.rst:794 #: ../../07-kontrollimine.rst:871 ../../07-kontrollimine.rst:971 msgid ":ref:`check-registreerimistoend-haale-allkiri-consistency`" msgstr "" #: ../../07-kontrollimine.rst:674 ../../07-kontrollimine.rst:788 #: ../../07-kontrollimine.rst:866 ../../07-kontrollimine.rst:969 msgid ":ref:`check-kehtivuskinnitus-ajatempel-order`" msgstr "" #: ../../07-kontrollimine.rst:676 msgid "" "Hääle talletamine, kvalifitseerivate elementide ja unikaalse " "identifikaatori tagastamine valijarakendusele." msgstr "" "Vote storage, return of qualifiers and unique identifiers to the voting " "application." #: ../../07-kontrollimine.rst:680 msgid "Kontrollid valijarakenduses" msgstr "Checks in the Voting Application" #: ../../07-kontrollimine.rst:682 msgid "" "Valijarakendus moodustab valija avakujul tahteavalduse põhjal " "krüpteeritud sedeli ning allkirjastab selle valija allkirja andmise " "vahendiga." msgstr "" "The voting application forms an encrypted ballot based on the voter's " "plaintext intent and signs it using the voter's signature device." #: ../../07-kontrollimine.rst:685 msgid "" "Valijarakenduse rolliks peale hääle allkirjastamist on veenduda, et " "kogumisteenus käitus häält kvalifitseerivate elementide võtmisel " "protokollikohaselt ning et hääl on talletatud selliselt, et ta saab " "töötlemisrakenduse poolt arvesse võetud." msgstr "" "The role of the voting application, after the vote has been signed, is to" " make sure that the collection service acted according to protocol in " "taking the elements that qualify the vote and that the vote has been " "stored in such a way that it can be taken into account by the processing " "application." #: ../../07-kontrollimine.rst:690 msgid "Valijarakendus viib läbi minimaalselt järgmised kontrollid:" msgstr "" "As a minimum, the following checks will be carried out by the voting " "application:" #: ../../07-kontrollimine.rst:692 msgid "" "Kogumisteenus võttis kehtivuskinnituse valija sertifikaadile volitatud " "kehtivuskinnitusteenuselt. Valijarakendus kontrollib allkirja " "kehtivuskinnitusteenuse vastusel." msgstr "" "The collection service validated the voter's certificate at the " "authorised validation service. The voting application verifies the " "signature in the validation service response." #: ../../07-kontrollimine.rst:696 msgid "" "Kogumisteenus registreeris valija poolt allkirjastatud hääle volitatud " "registreerimisteenuses. Valijarakendus kontrollib, et kogumisteenuse " "poolt moodustatud päring oli kogumisteenuse poolt signeeritud ning viitas" " korrektselt allkirjastatud häälele. Valijarakendus kontrollib, et " "registreerimisteenuse vastus on allkirjastatud õige registreerimisteenuse" " osutaja poolt ning sisaldab kogumisteenuse poolt allkirjastatud " "päringut." msgstr "" "The collection service registered the vote signed by the voter in the " "authorised registration service. The Voting Application verifies that the" " request generated by the Collection Service was signed by the Collection" " Service and referred to a correctly signed vote. The Voting Application " "checks that the confirmation from the registration service is signed by " "the correct registration service provider and includes the request signed" " by the collection service." #: ../../07-kontrollimine.rst:703 msgid "" "Kui hääle kvalifitseerimiseks vajalike elementide kontroll ei õnnestu, " "siis teavitab valijarakendus sellest kasutajat." msgstr "" "If the verification of the elements necessary to qualify a vote fails, " "the voting application will notify the user." #: ../../07-kontrollimine.rst:706 msgid "Valijarakendus loob ise järgmised olemid:" msgstr "The voting application itself creates the following entities:" #: ../../07-kontrollimine.rst:718 msgid "Valijarakendus saab järgmised olemid teistelt osapooltelt:" msgstr "The voting application receives the following entities from other parties:" #: ../../07-kontrollimine.rst:736 msgid "Valijarakendus ei puutu vahetult kokku järgmiste olemitega:" msgstr "The voting application does not come into direct contact with:" #: ../../07-kontrollimine.rst:746 msgid "" "Valijarakendus viib läbi järgmised tegevused ja teostab järgmised " "kontrollid:" msgstr "The voting application performs the following actions and checks:" #: ../../07-kontrollimine.rst:748 msgid "eID vahendi aktiveerimine ja valija identiteedi tuvastamine" msgstr "activation of the eID tool and identification of the voter's identity" #: ../../07-kontrollimine.rst:757 msgid "" "Ringkonnapõhise valikutenimekirja tuvastamine - :ref:`entity-ringkonna-" "valikutenimekiri`" msgstr "district-based candidate list - :ref:`entity-ringkonna-valikutenimekiri`." #: ../../07-kontrollimine.rst:760 msgid "Tahteavalduse moodustamine - :ref:`entity-tahteavaldus`" msgstr "Formation of an intent - :ref:`entity-tahteavaldus`" #: ../../07-kontrollimine.rst:762 msgid "Juhuarvu genereerimine - :ref:`entity-juhuslikkus`" msgstr "Random number generation - :ref:`entity-juhuslikkus`" #: ../../07-kontrollimine.rst:764 msgid "Sedeli krüpteerimine - :ref:`entity-krypteeritud-sedel`" msgstr "Encrypting ballot - :ref:`entity-krypteeritud-sedel`" #: ../../07-kontrollimine.rst:766 msgid "Krüpteeritud sedeli signeerimine - :ref:`entity-haale-signatuur`" msgstr "Signing an encrypted ballot - :ref:`entity-haale-signatuur`" #: ../../07-kontrollimine.rst:768 msgid "Allkirja moodustamine signatuurist - :ref:`entity-haale-allkiri`" msgstr "Forming a signed vote from a signature - :ref:`entity-haale-allkiri`" #: ../../07-kontrollimine.rst:773 msgid "Allkirjastatud konteineri moodustamine - :ref:`entity-haale-konteiner`" msgstr "Formation of a signed container - :ref:`entity-haale-konteiner`" #: ../../07-kontrollimine.rst:775 msgid "Allkirjastatud konteineri edastamine kogumisteenusele." msgstr "Forwarding the signed container to the collection service." #: ../../07-kontrollimine.rst:777 msgid "Kogumisteenuse vastuse kontrollimine" msgstr "Checking the collection service response" #: ../../07-kontrollimine.rst:790 ../../07-kontrollimine.rst:867 #: ../../07-kontrollimine.rst:976 msgid ":ref:`check-registreerimisparing-correctness`" msgstr "" #: ../../07-kontrollimine.rst:791 ../../07-kontrollimine.rst:868 #: ../../07-kontrollimine.rst:989 msgid ":ref:`check-registreerimisparing-haale-allkiri-consistency`" msgstr "" #: ../../07-kontrollimine.rst:797 msgid "Kontrollid kontrollrakenduses" msgstr "Checks in the Verification Application" #: ../../07-kontrollimine.rst:799 msgid "" "Sarnaselt valijarakendusele on kontrollrakenduse rolliks peale hääle " "allkirjastamist veenduda, et kogumisteenus käitus häält kvalifitseerivate" " elementide võtmisel protokollikohaselt ning et hääl on talletatud " "selliselt, et ta saab töötlemisrakenduse poolt arvesse võetud." msgstr "" "Similar to the voter application, the role of the verification " "application, once the vote has been signed, is to verify that the " "collection service acted in a protocol-compliant manner in capturing the " "elements that qualify the vote and that the vote has been stored in such " "a way that it can be taken into account by the processing application." #: ../../07-kontrollimine.rst:804 msgid "" "Täiendavalt on kontrollrakenduse ülesandeks anda valijale tagasisidet, " "kas tema tahteavaldus sai valijarakenduse poolt korrektselt hääleks " "vormistatud." msgstr "" "In addition, it is the responsibility of the verification application to " "provide feedback to the voter on whether their intent was correctly " "formatted as a vote by the voter application." #: ../../07-kontrollimine.rst:807 msgid "" "Kui hääle kvalifitseerimiseks vajalike elementide kontroll ei õnnestu, " "siis teavitab kontrollrakendus sellest kasutajat. Tahteavalduse " "korrektsuses peab valija ise veenduma." msgstr "" "If the verification of the elements necessary to qualify the vote fails, " "the verification application will inform the user. It is up to the voter " "to verify the correctness of the intent." #: ../../07-kontrollimine.rst:811 msgid "Kontrollrakendus tuvastab ise järgmised olemid:" msgstr "The verification application itself detects the following entities:" #: ../../07-kontrollimine.rst:815 msgid "Kontrollrakendus saab järgmised olemid teistelt osapooltelt:" msgstr "" "A verification application receives the following entities from other " "parties:" #: ../../07-kontrollimine.rst:841 msgid "Kontrollrakendus ei puutu vahetult kokku järgmiste olemitega:" msgstr "The verification application does not directly interact with:" #: ../../07-kontrollimine.rst:851 msgid "" "Kontrollrakendus viib läbi järgmised tegevused ja teostab järgmised " "kontrollid:" msgstr "" "The verification application will carry out the following activities and " "perform the following checks:" #: ../../07-kontrollimine.rst:872 msgid ":ref:`check-ringkonna-valikutenimekiri-correctness`" msgstr "" #: ../../07-kontrollimine.rst:873 msgid ":ref:`check-juhuslikkus-correctness`" msgstr "" #: ../../07-kontrollimine.rst:874 msgid ":ref:`check-juhuslikkus-public-key-consistency`" msgstr "" #: ../../07-kontrollimine.rst:877 msgid ":ref:`check-krypteeritud-sedel-juhuslikkus-consistency`" msgstr "" #: ../../07-kontrollimine.rst:878 ../../07-kontrollimine.rst:1117 msgid ":ref:`check-tahteavaldus-correctness`" msgstr "" #: ../../07-kontrollimine.rst:879 msgid ":ref:`check-tahteavaldus-ringkonna-valikutenimekiri-consistency`" msgstr "" #: ../../07-kontrollimine.rst:882 msgid "Kontrollid töötlemisrakenduses" msgstr "Checks in the Processing Application" #: ../../07-kontrollimine.rst:884 msgid "" "Töötlemisrakenduse sisendiks on e-valimiskast ja registreerimisteenuse " "väljavõte registreerimispäringutest. Töötlemisrakendus kontrollib mõlema " "andmehulga elemente kõigepealt eraldi ning seejärel püüab luua vastavuse " "nende vahel." msgstr "" "The input to the processing application is the e-voting box and the " "registration service extract of registration requests. The processing " "application first checks the elements of both data sets separately and " "then tries to establish a correspondence between them." #: ../../07-kontrollimine.rst:889 msgid "" "Töötlemisrakendus otsustab, milline valija häältest oli viimane ning " "liigub töötlemise järgmisesse etappi. S.t. üks häält kvalifitseerivatest " "elementidest täidab hääle talletamise aja fikseerimise rolli ning selle " "elemendi põhjal moodustatakse üksikute häälte ajaline järgnevus. " "Olenevalt IVXV profiilist võib see element olla kehtivuskinnituse " "koosseisus (BDOC-TM), eraldi ajatemplina (BDOC-TS) või " "registreerimistõendi koosseisus (BDOC-TS)." msgstr "" "The processing application decides which voter's vote was the last and " "moves to the next stage of processing. That is, one of the elements " "qualifying a vote performs the role of fixing the time at which the vote " "was recorded, and the temporal sequence of individual votes is formed " "based on this element. Depending on the IVXV profile, this element may be" " part of a validity confirmation (BDOC-TM), a separate time stamp (BDOC-" "TS) or a registration certificate (BDOC-TS)." #: ../../07-kontrollimine.rst:896 msgid "Töötlemisrakendusele tehakse kättesaadavaks järgmised olemid:" msgstr "" "The following entities will be made available to the processing " "application:" #: ../../07-kontrollimine.rst:924 msgid "Töötlemisrakendus tuvastab/loob järgmised olemid:" msgstr "The processing application detects/creates the following entities:" #: ../../07-kontrollimine.rst:929 msgid "Töötlemisrakendus ei puutu vahetult kokku järgmiste olemitega:" msgstr "The processing application does not come into direct contact with:" #: ../../07-kontrollimine.rst:937 msgid "Töötlemisrakenduse töö jaguneb neljaks etapiks:" msgstr "The work of the processing application is divided into four phases:" #: ../../07-kontrollimine.rst:939 msgid "Kontrollimine" msgstr "Check" #: ../../07-kontrollimine.rst:941 msgid "Korduvhäälte eemaldamine" msgstr "Removal of repeat votes" #: ../../07-kontrollimine.rst:943 msgid "Tühistamine/-ennistamine" msgstr "Revocation/restoration" #: ../../07-kontrollimine.rst:945 msgid "Anonüümimine" msgstr "Anonymization" #: ../../07-kontrollimine.rst:948 msgid "Töötlemisrakendus teostab kontrollimise etapis järgmised kontrollid:" msgstr "" "The processing application performs the following checks during the check" " phase:" #: ../../07-kontrollimine.rst:950 msgid "" "e-valimiskasti elementide kontrollid teostatakse kõigi hääle elementide " "kohta:" msgstr "" "checks on the elements of the digital ballot box are carried out for all " "elements of the vote:" #: ../../07-kontrollimine.rst:955 msgid ":ref:`check-nimekirjatunnus-correctness`" msgstr "" #: ../../07-kontrollimine.rst:956 msgid ":ref:`check-nimekirjatunnus-consistency-protocol-settings`" msgstr "" #: ../../07-kontrollimine.rst:958 ../../07-kontrollimine.rst:1054 #: ../../07-kontrollimine.rst:1116 msgid ":ref:`check-ringkonnatunnus-correctness`" msgstr "" #: ../../07-kontrollimine.rst:973 msgid "" "registreerimisteenuse väljavõtte kontrollid teostatakse iga " "registreerimispäringu kohta" msgstr "" "checks on the extract from the registration service are carried out for " "every registration request" #: ../../07-kontrollimine.rst:977 msgid ":ref:`check-registreerimisparing-konteiner-correctness`" msgstr "" #: ../../07-kontrollimine.rst:978 msgid "" ":ref:`check-registreerimisparing-konteiner-registreerimispäring-" "consistency`" msgstr "" #: ../../07-kontrollimine.rst:980 msgid "" "Töötlemisrakendus loob vastavuse e-valimiskasti ja registreerimisteenuse " "väljavõtte vahel võttes aluseks olemi :ref:`entity-registreerimisparing-" "konteiner` registreerimisteenuse väljavõttest ning olemi :ref:`entity-" "registreerimistoend` e-valimiskastist. Ühendavaks lüliks kahe vaate vahel" " on :ref:`entity-registreerimisparing`." msgstr "" "The processing application creates a match between the digital ballot box" " and the registration service extract based on the :ref:`entity-" "registreerimisparing-konteiner` from the registration service extract and" " the :ref:`entity-registreerimistoend` from the digital ballot box. The " "connecting link between the two views is :ref:`entity-" "registreerimisparing`." #: ../../07-kontrollimine.rst:987 msgid "e-valimiskasti ja registreerimisteenuse väljavõtte vastavuskontrollid" msgstr "digital ballot box and registration service extract compliance checks" #: ../../07-kontrollimine.rst:992 msgid "" "Töötlemisrakendus teostab korduvhäälte eemaldamise etapis järgmised " "kontrollid:" msgstr "" "The processing application performs the following checks during the " "squash phase:" #: ../../07-kontrollimine.rst:994 msgid "Töötlemisrakendus tuvastab iga valija häälte hulgast ajaliselt viimase." msgstr "" "The processing application identifies the last of each voter's votes in " "time." #: ../../07-kontrollimine.rst:996 msgid "Töötlemisrakendus viib läbi krüpteeritud sedeli korrektsuse kontrollid." msgstr "" "The processing application performs correctness checks on the encrypted " "sender." #: ../../07-kontrollimine.rst:1002 msgid "" "Töötlemisrakenduse töö järgmistes etappides täiendavaid kontrolle ei " "teostata. Tühistamis-/ennistamisetapis eemaldatakse/taastatakse " "isikukoodile vastavaid hääli korduvhäältest puhastatud e-valimiskastist. " "Anonüümimisetapis eemaldatakse e-häältelt kvalifitseerivad elemendid ning" " saadud loend krüpteeritud sedelitest suunatakse miksimisrakendusse." msgstr "" "No further checks will be carried out at subsequent stages of the " "processing application. In the cancellation/pre-cancelling phase, the " "votes corresponding to the personal identification code are " "removed/restored from the e-voting box cleaned of duplicate votes. In the" " anonymisation phase, the qualifying elements are removed from the " "e-votes and the resulting list of encrypted ballots is passed to the " "mixing application." #: ../../07-kontrollimine.rst:1009 msgid "Kontrollid miksimisrakenduses" msgstr "Controls in the mixing application" #: ../../07-kontrollimine.rst:1011 msgid "Miksimisrakendusele tehakse kättesaadavaks järgmised olemid:" msgstr "The following entities will be made available to the mixing application:" #: ../../07-kontrollimine.rst:1017 msgid "Miksimisrakendus loob järgmised olemid:" msgstr "The mixing application creates the following entities:" #: ../../07-kontrollimine.rst:1021 msgid "Miksimisrakendus ei puutu vahetult kokku järgmiste olemitega:" msgstr "The mixing application does not directly interact with:" #: ../../07-kontrollimine.rst:1052 msgid "Miksimisrakendus viib läbi järgmised tegevused ja kontrollid:" msgstr "The mixing application performs the following actions and checks:" #: ../../07-kontrollimine.rst:1058 msgid "" "Miksimisrakendus grupeerib sisendiks antud krüpteeritud sedelid " "ringkonnatunnuste kaupa ning järjestab krüpteeritud sedelid ringkonnas " "ringi." msgstr "" "The mixing application groups the encrypted ballots given as input by " "district identifiers and reorders the encrypted ballots within a " "district." #: ../../07-kontrollimine.rst:1062 msgid "" "Miksimisrakendus arvutab iga ümberjärjestatud krüpteeritud sedeli kohta " "uue miksitud krüpteeritud sedeli." msgstr "" "The mixing application for each reordered ciphertext calculates a new " "ciphertext." #: ../../07-kontrollimine.rst:1065 msgid "" "Miksimisrakendus koostab nullteadmustõestused sedelite korrektse " "miksimise kohta." msgstr "" "The mixing application generates zero-knowledge proofs of correct mixing " "of ballots." #: ../../07-kontrollimine.rst:1068 msgid "Kontrollid võtmerakenduses" msgstr "Checks in the key application" #: ../../07-kontrollimine.rst:1070 msgid "Võtmerakendusele tehakse kättesaadavaks järgmised olemid:" msgstr "The following entities will be made available to the key application:" #: ../../07-kontrollimine.rst:1078 msgid "Võtmerakendus tuvastab järgmised olemid:" msgstr "The key application identifies the following entities:" #: ../../07-kontrollimine.rst:1082 msgid "Võtmerakendus ei puutu vahetult kokku järgmiste olemitega:" msgstr "The key application does not directly interact with:" #: ../../07-kontrollimine.rst:1111 msgid "Võtmerakendus viib läbi järgmised tegevused ja kontrollid:" msgstr "The Key Application performs the following activities and checks:" #: ../../07-kontrollimine.rst:1113 msgid ":ref:`check-miksitud-krypteeritud-sedel-correctness`" msgstr "" #: ../../07-kontrollimine.rst:1114 msgid ":ref:`check-miksitud-krypteeritud-sedel-public-key-consistency`" msgstr "" #: ../../07-kontrollimine.rst:1115 msgid "Häälte dekrüpteerimine" msgstr "Decryption of votes" #: ../../07-kontrollimine.rst:1118 msgid ":ref:`check-tahteavaldus-ringkonnatunnus-valikutenimekiri-consistency`" msgstr "" ================================================ FILE: Documentation/public/protokollid/locales/en/LC_MESSAGES/08-haaletamine.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.8.2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-25 12:59+0000\n" "PO-Revision-Date: 2024-03-01 18:24+0200\n" "Last-Translator: \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../08-haaletamine.rst:5 msgid "Suhtlusprotokollid" msgstr "Communication protocols" #: ../../08-haaletamine.rst:8 msgid "Liides" msgstr "Interface" #: ../../08-haaletamine.rst:10 msgid "" "Kogumisteenuse valijale suunatud mikroteenused suhtlevad " "valijarakendusega ja kontrollrakendusega JSON-RPC protokolli vahendusel." msgstr "" "The micro-services at the collection service communicate with the voting " "application and the verification application via the JSON-RPC protocol." #: ../../08-haaletamine.rst msgid "id" msgstr "id" #: ../../08-haaletamine.rst:13 msgid "JSON-RPC päringuidentifikaator" msgstr "JSON-RPC query identifier" #: ../../08-haaletamine.rst msgid "method" msgstr "method" #: ../../08-haaletamine.rst:14 msgid "RPC-meetod" msgstr "RPC method" #: ../../08-haaletamine.rst msgid "params" msgstr "params" #: ../../08-haaletamine.rst:15 msgid "Konkreetse RPC-meetodi parameetrid" msgstr "Parameters of a specific RPC method" #: ../../08-haaletamine.rst msgid "error" msgstr "error" #: ../../08-haaletamine.rst:21 msgid "Võimalik veainfo või ``null`` vea puudumisel" msgstr "Possible error information or \"null\" in the absence of error" #: ../../08-haaletamine.rst:22 msgid "JSON-RPC päringuidentifikaator, peab ühtima päringus kasutatud id'ga" msgstr "JSON-RPC query identifier, must match the id used in the query." #: ../../08-haaletamine.rst msgid "result" msgstr "result" #: ../../08-haaletamine.rst:23 msgid "Meetodipõhine vastusandmestruktuur" msgstr "Method-dependent response data structure" #: ../../08-haaletamine.rst:29 msgid "" "Esimese päringuvahetuse käigus mõne IVXV mikroteenusega väljastatakse " "suhtlevale rakendusele HEX-kodeeritud unikaalne seansiidentifikaator " "(``result.SessionID``), mida rakendus kasutab edaspidi kõigis " "kogumisteenuse suunalistes päringutes (``params.SessionID``). " "Seansiidentifikaatori abil seostatakse hääletamisega seotud RPC-päringud " "üheks seansiks. Seostamine on informatiivne ning selle eesmärk on " "logianalüüsi lihtsustamine, hääle ringkonnakuuluvust jm. sisulisi aspekte" " puudutavad otsused tehakse digiallkirjastatud andmete põhjal." msgstr "" "During the first query exchange with one of the IVXV microservices, a " "HEX-encoded unique session identifier (``result.SessionID``) is issued to" " the communicating application, which is used by the application in all " "subsequent queries to the collection service (``params.SessionID``). The " "session identifier is used to associate RPC requests related to voting " "into a single session. The association is informative and is intended to " "simplify log analysis, vote circularity, etc. Decisions on substantive " "aspects are made on the basis of the digitally signed data." #: ../../08-haaletamine.rst:37 msgid "" "Transpordiprotokollina on kasutusel TLS. Krüpteeritud kanali " "termineerimine toimub konkreetses mikroteenuses. Võimaldamaks koormuse " "jaotamist ning mikroteenuste paindlikku evitamist kasutatakse TLS-SNI " "laiendust, mis lubab vahendusteenusel TLS voogu termineerimata õigesse " "mikroteenusinstantsi suunata. Vahendusteenus on tüüpiliselt kättesaadav " "kogumisteenuse välise liidese pordis 443." msgstr "" "TLS is used as the transport protocol. The termination of the encrypted " "channel takes place in a specific microservice. To enable load balancing " "and flexible provisioning of microservices, the TLS-SNI extension is " "used, which allows the proxy service to route the TLS stream to the " "correct microservice instance without termination. The broker service is " "typically available on port 443 of the external interface to the " "collection service." #: ../../08-haaletamine.rst:45 msgid "Valikute nimekirja hankimine" msgstr "Retrieving the List of Choices" #: ../../08-haaletamine.rst:47 msgid "" "Valikute nimekirja hankimine tähendab valijarakenduse suhtlemist " "nimekirjateenusega (SNI ``choices.ivxv.invalid``). Valikute nimekirja " "hankimine eeldab valija autentimist ning tema ringkonnakuuluvuse " "tuvastamist." msgstr "" "Retrieving the list of choices means the interaction of the voting " "application with the choices service (SNI ``choices.ivxv.invalid``). " "Getting a list of choices requires authentication of the voter and " "verification of the voter's electoral district." #: ../../08-haaletamine.rst:51 msgid "Valijarakendus teeb päringu ``RPC.VoterChoices`` nimekirjade hankimiseks." msgstr "The voting application will query ``RPC.VoterChoices`` to retrieve lists." #: ../../08-haaletamine.rst msgid "params.AuthMethod" msgstr "params.AuthMethod" #: ../../08-haaletamine.rst:53 ../../08-haaletamine.rst:140 msgid "Toetatud valikud on meetodid ``tls`` ja ``ticket``." msgstr "The supported options are methods ``tls`` and ``ticket``." #: ../../08-haaletamine.rst msgid "params.OS" msgstr "params.OS" #: ../../08-haaletamine.rst:54 ../../08-haaletamine.rst:146 #: ../../08-haaletamine.rst:230 ../../08-haaletamine.rst:256 #: ../../08-haaletamine.rst:305 ../../08-haaletamine.rst:337 #: ../../08-haaletamine.rst:361 ../../08-haaletamine.rst:415 #: ../../08-haaletamine.rst:439 ../../08-haaletamine.rst:464 #: ../../08-haaletamine.rst:516 ../../08-haaletamine.rst:533 #: ../../08-haaletamine.rst:570 ../../08-haaletamine.rst:594 #: ../../08-haaletamine.rst:645 ../../08-haaletamine.rst:668 msgid "Operatsioonisüsteem, millel valijarakendust kasutatakse." msgstr "The operating system on which the voting application is used." #: ../../08-haaletamine.rst:56 msgid "" "Päring ``RPC.VoterChoices`` ID-kaardiga autentimise korral - autentimine " "toimub TLS-protokolli tasemel päringu töötlemise ajal kasutades ID-kaardi" " autentimissertifikaati." msgstr "" "Query ``RPC.VoterChoices`` in case of ID-card authentication - " "authentication is performed at the TLS protocol level during query " "processing using the ID-card authentication certificate." #: ../../08-haaletamine.rst:64 msgid "" "Päring ``RPC.VoterChoices`` Mobiil-ID'ga autentimise korral - päringu " "sooritamiseks tuleb eelnevalt kasutada Mobiil-ID vahendusteenuse (SNI " "``mid.ivxv.invalid``) abi allkirjastatud autentimistõendi saamiseks." msgstr "" "Query ``RPC.VoterChoices`` in case of Mobile-ID authentication - to " "perform the query, the Mobile-ID Intermediary Service (SNI " "``mid.ivxv.invalid``) must be used in advance to obtain a signed " "authentication certificate." #: ../../08-haaletamine.rst msgid "params.AuthToken" msgstr "params.AuthToken" #: ../../08-haaletamine.rst:68 ../../08-haaletamine.rst:83 #: ../../08-haaletamine.rst:98 msgid "" "Autentimisteenuse vahendusel allkirjastatud tõend, mis sisaldab endas " "valija unikaalset identifikaatorit." msgstr "" "A certificate signed by an authentication service containing a unique " "identifier of the voter." #: ../../08-haaletamine.rst msgid "params.SessionID" msgstr "params.SessionID" #: ../../08-haaletamine.rst:71 msgid "" "Kuna Mobiil-ID korral on nimekirja hankimisele eelnenud interaktsioon " "autentimistõendi saamiseks, on olemas seansiidentifikaator, mida tuleb " "kasutada." msgstr "" "Since the Mobile ID has been preceded by an interaction to obtain an " "authentication certificate, there is a session identifier that must be " "used." #: ../../08-haaletamine.rst:79 msgid "" "Päring ``RPC.VoterChoices`` Smart-ID'ga autentimise korral - päringu " "sooritamiseks tuleb eelnevalt kasutada Smart-ID vahendusteenuse (SNI " "``smartid.ivxv.invalid``) abi allkirjastatud autentimistõendi saamiseks." msgstr "" "Query ``RPC.VoterChoices`` in case of authentication with Smart-ID - to " "perform the query, the Smart-ID Intermediary Service (SNI " "``smartid.ivxv.invalid``) must be used beforehand to obtain a signed " "authentication certificate." #: ../../08-haaletamine.rst:86 msgid "" "Kuna Smart-ID korral on nimekirja hankimisele eelnenud interaktsioon " "autentimistõendi saamiseks, on olemas seansiidentifikaator, mida tuleb " "kasutada." msgstr "" "Since the Smart-ID has an interaction to obtain an authentication proof " "prior to the list acquisition, there is a session identifier to be used." #: ../../08-haaletamine.rst:94 msgid "" "Päring ``RPC.VoterChoices`` Web eID'ga autentimise korral - päringu " "sooritamiseks tuleb eelnevalt kasutada Web eID vahendusteenuse (SNI " "``webeid.ivxv.invalid``) abi allkirjastatud autentimistõendi saamiseks." msgstr "" "Query ``RPC.VoterChoices`` in case of authentication with ID-card using " "Web eID protocol - to perform the query, the Web eID Intermediary Service" " (SNI ``webeid.ivxv.invalid``) must be used beforehand to obtain a signed" " authentication certificate." #: ../../08-haaletamine.rst:101 msgid "" "Kuna Web eID korral on nimekirja hankimisele eelnenud interaktsioon " "autentimistõendi saamiseks, on olemas seansiidentifikaator, mida tuleb " "kasutada." msgstr "" "Since in the case of a Web eID, the list acquisition is preceded by an " "interaction to obtain an authentication certificate, there is a session " "identifier that must be used." #: ../../08-haaletamine.rst:109 msgid "Nimekirjateenuse vastus päringule ``RPC.VoterChoices``." msgstr "Choices service response to ``RPC.VoterChoices``." #: ../../08-haaletamine.rst msgid "result.Choices" msgstr "result.Choices" #: ../../08-haaletamine.rst:111 msgid "Valija ringkonnakuuluvuse identifikaator ``VoterDistrict``" msgstr "Voter district identifier ``VoterDistrict``" #: ../../08-haaletamine.rst msgid "result.List" msgstr "result.List" #: ../../08-haaletamine.rst:112 msgid "BASE64-kodeeritud ringkonna valikute nimekiri ``DistrictChoices``" msgstr "List of BASE64 encoded district options ``DistrictChoices``" #: ../../08-haaletamine.rst msgid "result.Voted" msgstr "result.Voted" #: ../../08-haaletamine.rst:113 msgid "" "Kui valija on juba hääletanud, siis ``true``, vastasel juhul seda välja " "vastuses ei ole." msgstr "" "If the voter has already voted, then ``true``, otherwise it will not " "appear in the response." #: ../../08-haaletamine.rst:120 msgid "Võimalikud veateated päringu ``RPC.VoterChoices`` korral." msgstr "Possible error messages for the query ``RPC.VoterChoices``." #: ../../08-haaletamine.rst msgid "BAD_CERTIFICATE" msgstr "BAD_CERTIFICATE" #: ../../08-haaletamine.rst:122 msgid "Viga valija isikutuvastussertifikaadiga." msgstr "An error with the voter's identity certificate." #: ../../08-haaletamine.rst msgid "BAD_REQUEST" msgstr "BAD_REQUEST" #: ../../08-haaletamine.rst:123 ../../08-haaletamine.rst:204 #: ../../08-haaletamine.rst:249 ../../08-haaletamine.rst:284 #: ../../08-haaletamine.rst:321 ../../08-haaletamine.rst:353 #: ../../08-haaletamine.rst:389 ../../08-haaletamine.rst:432 #: ../../08-haaletamine.rst:457 ../../08-haaletamine.rst:496 #: ../../08-haaletamine.rst:555 ../../08-haaletamine.rst:586 #: ../../08-haaletamine.rst:621 ../../08-haaletamine.rst:662 #: ../../08-haaletamine.rst:692 ../../08-haaletamine.rst:728 #: ../../08-haaletamine.rst:790 msgid "Vigane päring." msgstr "Malformed query." #: ../../08-haaletamine.rst msgid "INELIGIBLE_VOTER" msgstr "INELIGIBLE_VOTER" #: ../../08-haaletamine.rst:124 ../../08-haaletamine.rst:207 msgid "Valijal pole õigust hääletada." msgstr "The voter has no right to vote." #: ../../08-haaletamine.rst msgid "INTERNAL_SERVER_ERROR" msgstr "INTERNAL_SERVER_ERROR" #: ../../08-haaletamine.rst:125 ../../08-haaletamine.rst:208 #: ../../08-haaletamine.rst:250 ../../08-haaletamine.rst:285 #: ../../08-haaletamine.rst:322 ../../08-haaletamine.rst:354 #: ../../08-haaletamine.rst:390 ../../08-haaletamine.rst:433 #: ../../08-haaletamine.rst:458 ../../08-haaletamine.rst:497 #: ../../08-haaletamine.rst:556 ../../08-haaletamine.rst:587 #: ../../08-haaletamine.rst:622 ../../08-haaletamine.rst:663 #: ../../08-haaletamine.rst:693 ../../08-haaletamine.rst:729 #: ../../08-haaletamine.rst:757 ../../08-haaletamine.rst:791 msgid "Viga serveri sisemises töös." msgstr "An error in the internal workings of the server." #: ../../08-haaletamine.rst msgid "UNAUTHENTICATED" msgstr "UNAUTHENTICATED" #: ../../08-haaletamine.rst:126 ../../08-haaletamine.rst:210 msgid "Autentimata päring." msgstr "Unauthenticated request." #: ../../08-haaletamine.rst msgid "VOTER_TOO_YOUNG" msgstr "VOTER_TOO_YOUNG" #: ../../08-haaletamine.rst:127 ../../08-haaletamine.rst:211 msgid "Valija on liiga noor." msgstr "The voter is too young." #: ../../08-haaletamine.rst msgid "VOTING_END" msgstr "VOTING_END" #: ../../08-haaletamine.rst:128 ../../08-haaletamine.rst:212 #: ../../08-haaletamine.rst:251 ../../08-haaletamine.rst:294 #: ../../08-haaletamine.rst:326 ../../08-haaletamine.rst:355 #: ../../08-haaletamine.rst:398 ../../08-haaletamine.rst:434 #: ../../08-haaletamine.rst:459 ../../08-haaletamine.rst:504 #: ../../08-haaletamine.rst:559 ../../08-haaletamine.rst:588 #: ../../08-haaletamine.rst:629 ../../08-haaletamine.rst:664 #: ../../08-haaletamine.rst:695 ../../08-haaletamine.rst:730 #: ../../08-haaletamine.rst:758 ../../08-haaletamine.rst:792 msgid "Hääletusperiood on lõppenud." msgstr "The voting period has ended." #: ../../08-haaletamine.rst:132 msgid "Allkirjastatud hääle saatmine talletamiseks" msgstr "Sending a signed vote for storage" #: ../../08-haaletamine.rst:134 msgid "" "Allkirjastatud hääle saatmine talletamiseks tähendab valijarakenduse " "suhtlemist hääletamisteenusega (SNI ``voting.ivxv.invalid``)." msgstr "" "Sending a signed vote to be stored implies the interaction of the voter " "application with the voting service (SNI ``voting.ivxv.invalid``)." #: ../../08-haaletamine.rst:137 msgid "" "Valijarakendus teeb päringu ``RPC.Vote`` allkirjastatud hääle " "talletamiseks saatmiseks." msgstr "" "The voting application will query ``RPC.Vote`` to send the signed vote " "for storage." #: ../../08-haaletamine.rst msgid "params.Choices" msgstr "params.Choices" #: ../../08-haaletamine.rst:141 msgid "" "Valija ringkonnakuuluvuse identifikaator ``VoterDistrict`` mis kehtis " "valikute nimekirja hankimise ajal. Parameetri korrektne kasutamine " "võimaldab kogumisteenusel valijat hoiatada kui tema ringkonnakuuluvus on " "võrreldes hääletamise algushetkega muutunud." msgstr "" "The voter's district identifier ``VoterDistrict`` that was in effect at " "the time the list of choices was obtained. Correct use of this parameter " "allows the collection service to alert the voter if his/her district " "affiliation has changed since the start of the voting process." #: ../../08-haaletamine.rst msgid "params.Type" msgstr "params.Type" #: ../../08-haaletamine.rst:147 ../../08-haaletamine.rst:716 msgid "Allkirjastatud hääle vorming. Hetkel on ainus toetatud väärtus ``bdoc``." msgstr "Signed ballot format. Currently the only supported value is ``bdoc``." #: ../../08-haaletamine.rst msgid "params.Vote" msgstr "params.Vote" #: ../../08-haaletamine.rst:149 ../../08-haaletamine.rst:718 msgid "" "BASE64-kodeeritud hääl ``SignedVote`` eelpoolmääratud vormingus (:ref" ":`signed-vote`)." msgstr "" "BASE64-encoded vote in ``SignedVote`` predefined format (:ref:`signed-" "vote`)." #: ../../08-haaletamine.rst:152 msgid "Päring ``RPC.Vote`` ID-kaardiga autentimise korral." msgstr "Query ``RPC.Vote`` in case of ID-card authentication." #: ../../08-haaletamine.rst:158 msgid "Päring ``RPC.Vote`` Mobiil-ID'ga autentimise korral." msgstr "Query ``RPC.Vote`` in case of authentication with Mobile-ID." #: ../../08-haaletamine.rst:164 msgid "Päring ``RPC.Vote`` Smart-ID'ga autentimise korral." msgstr "Query ``RPC.Vote`` for authentication with Smart-ID." #: ../../08-haaletamine.rst:170 msgid "Päring ``RPC.Vote`` Web eID'ga autentimise korral." msgstr "Query ``RPC.Vote`` for authentication with Web eID." #: ../../08-haaletamine.rst:176 msgid "Hääletamisteenuse vastus päringule ``RPC.Vote``." msgstr "Voting service response to the query ``RPC.Vote``." #: ../../08-haaletamine.rst msgid "result.Qualification.ocsp" msgstr "result.Qualification.ocsp" #: ../../08-haaletamine.rst msgid "result.Qualification.tspreg" msgstr "result.Qualification.tspreg" #: ../../08-haaletamine.rst:180 msgid "" "Kogumisteenuse poolt hangitud täiendavad tõendid valijarakenduse poolt " "loodud hääle ``SignedVote`` (:ref:`signed-vote`) kvalifitseerimiseks ning" " korrektseks registreerimiseks. Vastuse koosseis sõltub kogumisteenuse " "konkreetsest seadistusest, antud juhul kasutatakse standardset OCSP " "protokolli valija allkirjasertifikaadi kehtivuse kontrolliks ning PKIX " "ajatempliprotokolli põhist registreerimisteenust nii hääle andmise aja " "fikseerimiseks kui elektroonilise hääle registreerimiseks välises " "sõltumatus teenuses. Valijarakendusele kontrollimiseks edastatakse nii " "OCSP vastus kui PKIX vormingus ajatempel koos registreerimisteenusele " "vajalike täiendustega." msgstr "" "Additional evidence obtained by the collection service for the " "qualification and correct registration of the ``SignedVote`` (:ref" ":`signed-vote`) generated by the voting application. The composition of " "the response depends on the specific configuration of the collection " "service, in this case the standard OCSP protocol is used to verify the " "validity of the voter's signature certificate and the PKIX timestamp " "protocol based registration service is used both to record the time of " "casting the vote and to register the electronic vote in an external " "independent service. Both the OCSP response and the timestamp in PKIX " "format, with the necessary additions to the registration service, are " "transmitted to the voting application for verification." #: ../../08-haaletamine.rst msgid "result.TestVote" msgstr "result.TestVote" #: ../../08-haaletamine.rst:189 msgid "" "Kui hääl esitati enne hääletamise algust ning läks arvesse proovihäälena," " siis ``true``, vastasel juhul seda välja vastuses ei ole. Valijarakendus" " kuvab valijale proovihääle korral sellekohase hoiatuse." msgstr "" "If the vote was cast before voting started and counted as a test vote, " "then ``true``, otherwise it is not included in the response. The voting " "application will display a warning to the voter in the case of a test " "vote." #: ../../08-haaletamine.rst msgid "result.VoteID" msgstr "result.VoteID" #: ../../08-haaletamine.rst:193 msgid "" "Hääle identifikaator talletusteenuses, mille alusel on kontrollrakendusel" " võimalik häält hilisemaks analüüsiks välja nõuda." msgstr "" "The identifier of the ballot in the storage service, which allows the " "verification application to retrieve the ballot for later analysis." #: ../../08-haaletamine.rst:201 msgid "Võimalikud veateated päringu ``RPC.Vote`` korral." msgstr "Possible error messages in case of ``RPC.Vote`` query." #: ../../08-haaletamine.rst:203 msgid "Viga valija isikutuvastus- või allkirjastamissertifikaadiga." msgstr "An error with the voter's identification or signature certificate." #: ../../08-haaletamine.rst msgid "IDENTITY_MISMATCH" msgstr "IDENTITY_MISMATCH" #: ../../08-haaletamine.rst:205 msgid "Isikutuvastus- ning allkirjastamissertifikaadi isikukoodid ei kattu." msgstr "The ID codes of the ID and signature certificate do not match." #: ../../08-haaletamine.rst msgid "OUTDATED_CHOICES" msgstr "OUTDATED_CHOICES" #: ../../08-haaletamine.rst:209 msgid "Valija ringkonnakuuluvus on nimekirja hankimisest muutunud." msgstr "" "The district eligibility of a candidate has changed since the list was " "obtained." #: ../../08-haaletamine.rst:216 msgid "Hääletamine Mobiil-ID'ga" msgstr "Voting with Mobile-ID" #: ../../08-haaletamine.rst:218 msgid "" "Mobiil-ID kasutamine allkirjastamis- ning autentimisvahendina tingib " "Mobiil-ID teenusega liidestuva abiteenuse (SNI ``mid.ivxv.invalid``) " "kasutamise autentimistõendi hankimiseks enne valikute nimekirja hankimist" " ning hääle allkirjastamiseks enne talletamist." msgstr "" "The use of Mobile-ID as a signature and authentication tool implies the " "use of an auxiliary service (SNI ``mid.ivxv.invalid``) that interfaces " "with the Mobile-ID service to obtain an authentication certificate before" " retrieving the list of options and to sign the vote before storing it." #: ../../08-haaletamine.rst:225 ../../08-haaletamine.rst:411 #: ../../08-haaletamine.rst:640 msgid "Autentimistõendi hankimine" msgstr "Retrieving an Authentication Certificate" #: ../../08-haaletamine.rst:227 msgid "" "Valijarakendus teeb päringu ``RPC.Authenticate`` Mobiil-ID autentimise " "algatamiseks." msgstr "" "The voting application will make a request ``RPC.Authenticate`` to " "initiate Mobile ID authentication." #: ../../08-haaletamine.rst msgid "params.IDCode" msgstr "params.IDCode" #: ../../08-haaletamine.rst:231 msgid "Mobiil-ID kasutaja isikukood." msgstr "Mobile-ID user ID." #: ../../08-haaletamine.rst msgid "params.PhoneNo" msgstr "params.PhoneNo" #: ../../08-haaletamine.rst:232 msgid "Mobiil-ID kasutaja telefoninumber." msgstr "Mobile ID user's phone number." #: ../../08-haaletamine.rst msgid "result.Challenge" msgstr "result.Challenge" #: ../../08-haaletamine.rst:238 msgid "Räsi, millest arvutada Mobiil-ID kontrollkood valijarakenduses kuvamiseks" msgstr "" "Hash from which to calculate the Mobile ID verification code to display " "in the voting application" #: ../../08-haaletamine.rst msgid "result.SessionCode" msgstr "result.SessionCode" #: ../../08-haaletamine.rst:240 msgid "Mobiil-ID seansiidentifikaator edasiste poll-päringute jaoks" msgstr "Mobile-ID session identifier for further poll requests" #: ../../08-haaletamine.rst:247 ../../08-haaletamine.rst:430 #: ../../08-haaletamine.rst:455 msgid "Võimalikud veateated päringu ``RPC.Authenticate`` korral." msgstr "Possible error messages in case of ``RPC.Authenticate`` request." #: ../../08-haaletamine.rst:253 ../../08-haaletamine.rst:461 msgid "" "Valijarakendus teeb päringu ``RPC.AuthenticateStatus`` " "autentimisprotsessi oleku hindamiseks." msgstr "" "The voting application queries ``RPC.AuthenticateStatus`` to assess the " "status of the authentication process." #: ../../08-haaletamine.rst msgid "params.SessionCode" msgstr "params.SessionCode" #: ../../08-haaletamine.rst:257 ../../08-haaletamine.rst:467 #: ../../08-haaletamine.rst:534 msgid "Autentimisseansi identifikaator" msgstr "Authentication session identifier" #: ../../08-haaletamine.rst msgid "result.AuthToken" msgstr "result.AuthToken" #: ../../08-haaletamine.rst:264 ../../08-haaletamine.rst:474 msgid "" "Autentimistõend teistele IVXV teenustele esitamiseks või ``null``, kui " "päringu töötlemine alles käib." msgstr "" "Authentication certificate for submission to other IVXV services, or " "``null`` if the request is still being processed." #: ../../08-haaletamine.rst msgid "result.GivenName" msgstr "result.GivenName" #: ../../08-haaletamine.rst:266 ../../08-haaletamine.rst:478 #: ../../08-haaletamine.rst:678 msgid "Eduka autentimise korral valija eesnimi" msgstr "First name of voter in case of successful authentication" #: ../../08-haaletamine.rst msgid "result.PersonalCode" msgstr "result.PersonalCode" #: ../../08-haaletamine.rst:267 ../../08-haaletamine.rst:479 #: ../../08-haaletamine.rst:679 msgid "Eduka autentimise korral valija isikukood" msgstr "" "Voter's personal identification number in case of successful " "authentication" #: ../../08-haaletamine.rst msgid "result.Status" msgstr "result.Status" #: ../../08-haaletamine.rst:268 ../../08-haaletamine.rst:480 #: ../../08-haaletamine.rst:541 msgid "" "Päringu staatus - ``POLL`` viitab vajadusele päringut korrata, ``OK`` " "viitab edukale autentimisele. Vastuse muud väljad sisaldavad infot vaid " "siis kui väärtus on ``OK``." msgstr "" "Query status - ``POLL`` indicates the need to repeat the query, ``OK`` " "indicates successful authentication. The other fields in the response " "contain information only if the value is ``OK``." #: ../../08-haaletamine.rst msgid "result.Surname" msgstr "result.Surname" #: ../../08-haaletamine.rst:271 ../../08-haaletamine.rst:483 #: ../../08-haaletamine.rst:683 msgid "Eduka autentimise korral valija perekonnanimi" msgstr "In case of successful authentication, the voter's surname" #: ../../08-haaletamine.rst:282 ../../08-haaletamine.rst:494 msgid "Võimalikud veateated päringu ``RPC.AuthenticateStatus`` korral." msgstr "Possible error messages in case of ``RPC.AuthenticateStatus`` request." #: ../../08-haaletamine.rst msgid "MID_BAD_CERTIFICATE" msgstr "MID_BAD_CERTIFICATE" #: ../../08-haaletamine.rst:286 msgid "Viga valija Mobiil-ID isikutuvastussertifikaadiga." msgstr "An error with the voter's Mobile ID certificate." #: ../../08-haaletamine.rst msgid "MID_NOT_USER" msgstr "MID_NOT_USER" #: ../../08-haaletamine.rst:287 ../../08-haaletamine.rst:325 msgid "Telefoninumber ei kuulu Mobiil-ID kliendile." msgstr "The phone number does not belong to a Mobile ID customer." #: ../../08-haaletamine.rst msgid "MID_OPERATOR" msgstr "MID_OPERATOR" #: ../../08-haaletamine.rst:288 ../../08-haaletamine.rst:393 msgid "" "Probleem valija mobiiltelefoni SIM kaardiga, mille lahendamiseks tuleb " "pöörduda mobiilioperaatori poole." msgstr "" "A problem with the SIM card of the voter's mobile phone, which needs to " "be solved by contacting the mobile operator." #: ../../08-haaletamine.rst msgid "MID_ABSENT" msgstr "MID_ABSENT" #: ../../08-haaletamine.rst:290 ../../08-haaletamine.rst:391 msgid "Valija mobiiltelefon ei ole kättesaadav." msgstr "The voter's mobile phone is not available." #: ../../08-haaletamine.rst msgid "MID_CANCELED" msgstr "MID_CANCELED" #: ../../08-haaletamine.rst:291 ../../08-haaletamine.rst:395 msgid "Valija katkestas Mobiil-ID seansi." msgstr "The voter has cancelled the Mobile-ID session." #: ../../08-haaletamine.rst msgid "MID_EXPIRED" msgstr "MID_EXPIRED" #: ../../08-haaletamine.rst:292 ../../08-haaletamine.rst:396 msgid "Mobiil-ID seanss on aegunud." msgstr "The Mobile ID session has expired." #: ../../08-haaletamine.rst msgid "MID_GENERAL" msgstr "MID_GENERAL" #: ../../08-haaletamine.rst:293 ../../08-haaletamine.rst:324 #: ../../08-haaletamine.rst:397 msgid "Viga Mobiil-ID teenuse töös." msgstr "An error in the operation of the Mobile ID service." #: ../../08-haaletamine.rst:298 ../../08-haaletamine.rst:508 msgid "Hääle allkirjastamine" msgstr "Signing the vote" #: ../../08-haaletamine.rst:300 msgid "" "Valijarakendus teeb päringu ``RPC.GetCertificate`` " "allkirjastamissertifikaadi hankimiseks." msgstr "" "The voting application makes a query ``RPC.GetCertificate`` to retrieve " "the signing certificate." #: ../../08-haaletamine.rst:303 ../../08-haaletamine.rst:332 #: ../../08-haaletamine.rst:513 ../../08-haaletamine.rst:565 msgid "Toetatud ainult autentimismeetod ``ticket``." msgstr "Only the authentication method ``ticket`` is supported." #: ../../08-haaletamine.rst:304 ../../08-haaletamine.rst:333 msgid "Mobiil-ID autentimistõend." msgstr "Mobile-ID authentication certificate." #: ../../08-haaletamine.rst:306 ../../08-haaletamine.rst:338 msgid "Hääle allkirjastaja telefoninumber" msgstr "Telephone number of the person who signed the vote" #: ../../08-haaletamine.rst msgid "result.Certificate" msgstr "result.Certificate" #: ../../08-haaletamine.rst:313 ../../08-haaletamine.rst:540 msgid "Allkirjastamissertifikaat X509-vormingus" msgstr "Signature certificate in X509 format" #: ../../08-haaletamine.rst:319 msgid "Võimalikud veateated päringu ``RPC.GetCertificate`` korral." msgstr "Possible error messages for ``RPC.GetCertificate``." #: ../../08-haaletamine.rst:323 ../../08-haaletamine.rst:392 msgid "Viga valija Mobiil-ID allkirjastamissertifikaadiga." msgstr "Error with the voter's Mobile-ID signature certificate." #: ../../08-haaletamine.rst:329 msgid "" "Valijarakendus teeb päringu ``RPC.Sign`` hääle allkirjastamise " "algatamiseks. Mobiil-ID kontrollkoodi arvutab valijarakendus andmevälja " "``Hash`` väärtusest." msgstr "" "The voting application will make a query ``RPC.Sign`` to initiate the " "signing of the vote. The mobile ID verification code is calculated by the" " voter application from the value of the ``Hash`` field." #: ../../08-haaletamine.rst msgid "params.Hash" msgstr "params.hash" #: ../../08-haaletamine.rst:334 ../../08-haaletamine.rst:567 msgid "BASE64-kodeeritud elektroonilise hääle räsi" msgstr "BASE64-encoded hash of the ballot" #: ../../08-haaletamine.rst msgid "params.HashType" msgstr "params.HashType" #: ../../08-haaletamine.rst:335 msgid "" "Räsifunktsiooni nimi Mobiil-ID teenusele edastamiseks, kas ``SHA256``, " "``SHA384`` või ``SHA512``" msgstr "" "The name of the hash function to be forwarded to the Mobile-ID service, " "either ``SHA256``, ``SHA384`` or ``SHA512``" #: ../../08-haaletamine.rst:344 msgid "Mobiil-ID seansiidentifikaator edasiste poll-päringute jaoks." msgstr "Mobile ID session identifier for further poll requests." #: ../../08-haaletamine.rst:351 ../../08-haaletamine.rst:584 msgid "Võimalikud veateated päringu ``RPC.Sign`` korral." msgstr "Possible error messages in case of ``RPC.Sign`` query." #: ../../08-haaletamine.rst:358 ../../08-haaletamine.rst:591 msgid "" "Valijarakendus teeb päringu ``RPC.SignStatus`` allkirjastamisprotsessi " "seisundi hindamiseks." msgstr "" "The voting application queries ``RPC.SignStatus`` to assess the status of" " the signing process." #: ../../08-haaletamine.rst:362 msgid "Mobiil-ID seansiidentifikaator" msgstr "Mobile-ID session identifier" #: ../../08-haaletamine.rst msgid "result.Signature" msgstr "result.Signature" #: ../../08-haaletamine.rst:368 msgid "" "Juhul kui vastuse ``Status`` väli on ``OK``, BASE-64 kodeeritud " "PKCS1-vormingus signatuur, vastasel juhul ``null``." msgstr "" "If the ``Status`` field of the response is ``OK``, the BASE-64 encoded " "PKCS1 format signature, otherwise ``zero``." #: ../../08-haaletamine.rst msgid "result.Algorithm" msgstr "result.Algorithm" #: ../../08-haaletamine.rst:370 msgid "" "Juhul kui vastuse ``Status`` väli on ``OK``, Mobiil-ID teenuse poolt " "tagastatud signatuuri algoritm. Võimalikud väärtused on " "``SHA256WithECEncryption``, ``SHA256WithRSAEncryption``, " "``SHA384WithECEncryption``, ``SHA384WithRSAEncryption``, " "``SHA512WithECEncryption`` ja ``SHA512WithRSAEncryption``." msgstr "" "If the ``Status`` field of the response is ``OK``, the signature " "algorithm returned by the Mobile-ID service. The possible values are " "``SHA256WithECEncryption``, ``SHA256WithRSAEncryption``, " "``SHA384WithECEncryption``, ``SHA384WithRSAEncryption``, " "``SHA512WithECEncryption`` and ``SHA512WithRSAEncryption``." #: ../../08-haaletamine.rst:375 ../../08-haaletamine.rst:607 msgid "" "Päringu staatus - ``POLL`` viitab vajadusele päringut korrata, ``OK`` " "viitab edukale allkirjastamisele. Vastuse muud väljad sisaldavad infot " "vaid siis kui väärtus on ``OK``." msgstr "" "Query status - ``POLL`` indicates the need to repeat the query, ``OK`` " "indicates a successful signature. The other fields in the response " "contain information only if the value is ``OK``." #: ../../08-haaletamine.rst:387 ../../08-haaletamine.rst:619 msgid "Võimalikud veateated päringu ``RPC.SignStatus`` korral." msgstr "Possible error messages in case of ``RPC.SignStatus`` query." #: ../../08-haaletamine.rst:402 msgid "Hääletamine Smart-ID'ga" msgstr "Voting with Smart-ID" #: ../../08-haaletamine.rst:404 msgid "" "Smart-ID kasutamine allkirjastamis- ning autentimisvahendina tingib " "Smart-ID teenusega liidestuva abiteenuse (SNI ``smartid.ivxv.invalid``) " "kasutamise autentimistõendi hankimiseks enne valikute nimekirja hankimist" " ning hääle allkirjastamiseks enne talletamist." msgstr "" "The use of Smart-ID as a signature and authentication tool implies the " "use of an auxiliary service (SNI ``smartid.ivxv.invalid``) interfacing " "with the Smart-ID service to obtain an authentication certificate before " "retrieving the list of choices and to sign the vote before storing it." #: ../../08-haaletamine.rst:413 msgid "" "Valijarakendus teeb päringu ``RPC.Challenge`` Smart-ID kontrollkoodi " "hankimiseks." msgstr "" "The voter application will query ``RPC.Challenge`` to retrieve the Smart-" "ID verification code." #: ../../08-haaletamine.rst:421 msgid "Räsi, millest arvutada Smart-ID kontrollkood valijarakenduses kuvamiseks" msgstr "" "Hash from which to calculate the Smart-ID verification code to display in" " the voting application" #: ../../08-haaletamine.rst msgid "result.XSmartIDAuth" msgstr "result.XSmartIDAuth" #: ../../08-haaletamine.rst:423 ../../08-haaletamine.rst:440 #: ../../08-haaletamine.rst:465 msgid "" "Päringu küpsis, kus talletatakse Smart-ID kontrollkoodi räsi, selle eluea" " ajatempel ja seansiidentifikaator" msgstr "" "A query cookie storing a hash of the Smart-ID verification code, a " "timestamp of its lifetime and a session identifier." #: ../../08-haaletamine.rst:436 msgid "" "Valijarakendus teeb päringu ``RPC.Authenticate`` Smart-ID autentimise " "algatamiseks." msgstr "" "The voting application will query ``RPC.Authenticate`` to initiate Smart-" "ID authentication." #: ../../08-haaletamine.rst msgid "params.XSmartIDAuth" msgstr "params.XSmartIDAuth" #: ../../08-haaletamine.rst msgid "params.Identifier" msgstr "params.Identifier" #: ../../08-haaletamine.rst:442 msgid "Smart-ID kasutaja isikukood." msgstr "Smart-ID user ID." #: ../../08-haaletamine.rst:448 ../../08-haaletamine.rst:522 msgid "Smart-ID seansiidentifikaator edasiste poll-päringute jaoks" msgstr "Smart-ID session identifier for further poll requests" #: ../../08-haaletamine.rst msgid "result.DataToken" msgstr "" #: ../../08-haaletamine.rst:476 msgid "" "Hääletaja Smart-ID dokumendi number või ``null``, kui päringu töötlemine " "alles käib." msgstr "" "Voter's Smart-ID document number or ``null``, when the query is pending." #: ../../08-haaletamine.rst msgid "SMARTID_BAD_CERTIFICATE" msgstr "SMARTID_BAD_CERTIFICATE" #: ../../08-haaletamine.rst:498 ../../08-haaletamine.rst:623 msgid "Viga valija Smart-ID isikutuvastussertifikaadiga." msgstr "Error with the voter's Smart-ID identity certificate." #: ../../08-haaletamine.rst msgid "SMARTID_VERIFICATION" msgstr "SMARTID_VERIFICATION" #: ../../08-haaletamine.rst:499 ../../08-haaletamine.rst:624 msgid "Valija valis vale verifitseerimiskoodi." msgstr "The voter selected the wrong verification code." #: ../../08-haaletamine.rst msgid "SMARTID_ACCOUNT" msgstr "SMARTID_ACCOUNT" #: ../../08-haaletamine.rst:500 ../../08-haaletamine.rst:625 msgid "Viga valija Smart-ID kontos." msgstr "An error in the voter's Smart-ID account." #: ../../08-haaletamine.rst msgid "SMARTID_CANCELED" msgstr "SMARTID_CANCELED" #: ../../08-haaletamine.rst:501 ../../08-haaletamine.rst:626 msgid "Valija katkestas Smart-ID seansi." msgstr "The Smart-ID session has been interrupted by the voter." #: ../../08-haaletamine.rst msgid "SMARTID_EXPIRED" msgstr "SMARTID_EXPIRED" #: ../../08-haaletamine.rst:502 ../../08-haaletamine.rst:627 msgid "Smart-ID seanss on aegunud." msgstr "The Smart-ID session has expired." #: ../../08-haaletamine.rst msgid "SMARTID_GENERAL" msgstr "SMARTID_GENERAL" #: ../../08-haaletamine.rst:503 ../../08-haaletamine.rst:558 #: ../../08-haaletamine.rst:628 msgid "Viga Smart-ID teenuse töös." msgstr "Error in the Smart-ID service." #: ../../08-haaletamine.rst:510 msgid "" "Valijarakendus teeb päringu ``RPC.GetCertificateChoice`` " "allkirjastamissertifikaadi valikuks." msgstr "" "The voting application makes a query ``RPC.GetCertificateChoice`` to " "select the signing certificate." #: ../../08-haaletamine.rst:514 ../../08-haaletamine.rst:566 msgid "Smart-ID autentimistõend." msgstr "Smart-ID authentication certificate." #: ../../08-haaletamine.rst msgid "params.DataToken" msgstr "" #: ../../08-haaletamine.rst:515 ../../08-haaletamine.rst:571 msgid "Hääletaja Smart-ID dokumendi number." msgstr "Voter's Smart-ID documentnumber" #: ../../08-haaletamine.rst:529 msgid "" "Valijarakendus teeb päringu ``RPC.GetCertificateChoiceStatus`` " "allkirjastamissertifikaadi oleku hindamiseks." msgstr "" "The voting application makes a query ``RPC.GetCertificateChoiceStatus`` " "to evaluate the status of the signing certificate." #: ../../08-haaletamine.rst:553 msgid "Võimalikud veateated päringu ``RPC.GetCertificateChoiceStatus`` korral." msgstr "Possible error messages for the query ``RPC.GetCertificateChoiceStatus``." #: ../../08-haaletamine.rst:557 msgid "Viga valija Smart-ID allkirjastamissertifikaadiga." msgstr "Error with the voter's Smart-ID signature certificate." #: ../../08-haaletamine.rst:562 msgid "" "Valijarakendus teeb päringu ``RPC.Sign`` hääle allkirjastamise " "algatamiseks. Smart-ID kontrollkoodi arvutab valijarakendus andmevälja " "``Hash`` väärtusest." msgstr "" "The voting application will make a query ``RPC.Sign`` to initiate the " "signing of the vote. The Smart-ID verification code is calculated by the " "voter application from the value of the ``Hash`` field." #: ../../08-haaletamine.rst:568 msgid "" "Räsifunktsiooni nimi Smart-ID teenusele edastamiseks, kas ``SHA256``, " "``SHA384`` või ``SHA512``" msgstr "" "The name of the hash function to transmit to the Smart-ID service, either" " ``SHA256``, ``SHA384`` or ``SHA512``" #: ../../08-haaletamine.rst:577 msgid "Smart-ID seansiidentifikaator edasiste poll-päringute jaoks." msgstr "Smart-ID session identifier for further poll requests." #: ../../08-haaletamine.rst:595 msgid "Smart-ID seansiidentifikaator" msgstr "Smart-ID session identifier" #: ../../08-haaletamine.rst:601 msgid "" "Juhul kui vastuse ``Status`` väli on ``OK``, BASE-64 kodeeritud " "signatuur, vastasel juhul ``null``." msgstr "" "If the ``Status`` field of the response is ``OK``, BASE-64 encoded " "signature, otherwise ``null``." #: ../../08-haaletamine.rst:603 msgid "" "Juhul kui vastuse ``Status`` väli on ``OK``, Smart-ID teenuse poolt " "tagastatud signatuuri algoritm. Võimalikud väärtused on " "``sha256WithRSAEncryption``, ``sha384WithRSAEncryption``, ja " "``sha512WithRSAEncryption``." msgstr "" "If the ``Status`` field of the response is ``OK``, the signature " "algorithm returned by the Smart-ID service. Possible values are " "``sha256WithRSAEncryption``, ``sha384WithRSAEncryption``, and " "``sha512WithRSAEncryption``." #: ../../08-haaletamine.rst:632 msgid "Hääletamine Web eID'ga" msgstr "Voting with Web eID" #: ../../08-haaletamine.rst:634 msgid "" "Web eID kasutamine autentimisvahendina tingib Web eID teenusega " "liidestuva abiteenuse (SNI ``webeid.ivxv.invalid``) kasutamise " "autentimistõendi hankimiseks enne valikute nimekirja hankimist." msgstr "" "The use of Web eID as an authentication tool implies the use of an " "auxiliary service (SNI ``webeid.ivxv.invalid``) interfacing with the Web " "eID service to obtain an authentication certificate before retrieving the" " list of choices." #: ../../08-haaletamine.rst:642 msgid "" "Valijarakendus teeb päringu ``RPC.Challenge`` Web eID autentimise " "algatamiseks." msgstr "" "The voting application makes a request to ``RPC.Challenge`` to initiate " "Web eID authentication." #: ../../08-haaletamine.rst:651 msgid "" "Base64 kodeeritud räsi, mille dekodeeritud väärtust peab valijarakendus " "kasutama autentimistõendi allkirja loomiseks." msgstr "" "A Base64 encoded hash whose decoded value must be used by the voter " "application to generate the authentication proof signature." #: ../../08-haaletamine.rst:653 ../../08-haaletamine.rst:669 msgid "Seansiidentifikaator." msgstr "Session identifier." #: ../../08-haaletamine.rst msgid "params.Bearer" msgstr "params.Bearer" #: ../../08-haaletamine.rst:654 ../../08-haaletamine.rst:671 msgid "Küpsis, mida server kasutab räsi verifitseerimiseks." msgstr "A cookie used by the server to verify hashes." #: ../../08-haaletamine.rst:660 msgid "Võimalikud veateated päringu ``RPC.Challenge`` korral." msgstr "Possible error messages in case of ``RPC.Challenge`` query." #: ../../08-haaletamine.rst:666 msgid "" "Valijarakendus teeb päringu ``RPC.Token`` autentimistõendi " "valideerimiseks." msgstr "" "The voting application will query ``RPC.Token`` to validate the " "authentication token." #: ../../08-haaletamine.rst msgid "params.Token" msgstr "params.Token" #: ../../08-haaletamine.rst:670 msgid "Web eID autentimistõend." msgstr "Web eID authentication certificate." #: ../../08-haaletamine.rst:677 msgid "Autentimistõend teistele IVXV teenustele esitamiseks" msgstr "Proof of authentication for submission to other IVXV services" #: ../../08-haaletamine.rst:680 msgid "" "Päringu staatus - ``OK`` viitab edukale autentimisele. Vastuse muud " "väljad sisaldavad infot vaid siis kui väärtus on ``OK``." msgstr "" "Query status - ``OK`` indicates successful authentication. The other " "fields in the response contain information only if the value is ``OK``." #: ../../08-haaletamine.rst:690 msgid "Võimalikud veateated päringu ``RPC.Token`` korral." msgstr "Possible error messages in case of ``RPC.Token`` query." #: ../../08-haaletamine.rst:694 msgid "Viga valija Web eID isikutuvastussertifikaadiga." msgstr "Error with the voter's Web eID identity certificate." #: ../../08-haaletamine.rst:698 msgid "Hääle kontrollimine" msgstr "Vote verification" #: ../../08-haaletamine.rst:700 msgid "" "Kontrollrakendus teeb päringu ``RPC.Verify`` allkirjastatud hääle ning " "häält kvalifitseerivate tõendite allalaadimiseks kogumisteenusest." msgstr "" "The Verification Application will query ``RPC.Verify`` to download the " "signed vote and the evidence that qualifies the vote from the collection " "service." #: ../../08-haaletamine.rst:703 msgid "Operatsioonisüsteem, millel kontrollrakendust kasutatakse." msgstr "The operating system on which the verification application is used." #: ../../08-haaletamine.rst msgid "params.VoteID" msgstr "params.VoteID" #: ../../08-haaletamine.rst:704 msgid "" "QR-koodi vahendusel valijarakendusest saadud hääle identifikaator " "talletusteenuses." msgstr "" "The identifier of the vote received from the voting application via QR " "code in the storage service." #: ../../08-haaletamine.rst:713 msgid "Vaata peatükki hääle verifitseerimisest" msgstr "See chapter on vote verification" #: ../../08-haaletamine.rst msgid "result.Type" msgstr "result.Type" #: ../../08-haaletamine.rst msgid "result.Vote" msgstr "result.Vote" #: ../../08-haaletamine.rst msgid "result.ChoicesList" msgstr "result.ChoicesList" #: ../../08-haaletamine.rst:720 msgid "JSON-vormingus ringkonnapõhine valikute nimekiri." msgstr "A JSON-formatted list of district-based options." #: ../../08-haaletamine.rst:726 msgid "Võimalikud veateated päringu ``RPC.Verify`` korral." msgstr "Possible error messages in case of ``RPC.Verify`` request." #: ../../08-haaletamine.rst:734 msgid "E-hääletamise jooksev nimekiri" msgstr "List of e-votes" #: ../../08-haaletamine.rst:736 msgid "" "X-tee teenusega(xroad-service) liidestuva abiteenuse (SNI " "``votesorder.ivxv.invalid``) kasutatakse informatsiooni edastamiseks " "X-tee turvaserverile." msgstr "" "The auxiliary service (SNI ``votesorder.ivxv.invalid``), which interfaces" " with the X-road service (xroad-service), is used to send information to " "the X-road security server." #: ../../08-haaletamine.rst:741 msgid "Viimane järjenumber" msgstr "Last serial number" #: ../../08-haaletamine.rst:742 msgid "" "X-tee teenus(xroad-service) teeb päringu ``RPC.VotesSeqNo`` viimase " "järjenumbri saamiseks." msgstr "" "The X-road service (xroad-service) makes a query ``RPC.VotesSeqNo`` for " "the last sequence number." #: ../../08-haaletamine.rst msgid "result.SeqNo" msgstr "result.SeqNo" #: ../../08-haaletamine.rst:749 msgid "Viimane järjenumber." msgstr "Latest sequence number." #: ../../08-haaletamine.rst:755 msgid "Võimalikud veateated päringu ``RPC.VotesSeqNo`` korral." msgstr "Possible error messages in case of query ``RPC.VotesSeqNo``." #: ../../08-haaletamine.rst:761 msgid "E-hääletamiste pakk" msgstr "E-voting package" #: ../../08-haaletamine.rst:762 msgid "" "X-tee teenus(xroad-service) teeb päringu ``RPC.Votes`` e-hääletamise paki" " saamiseks." msgstr "" "The X-road service (xroad-service) makes a request for an ``RPC.Votes`` " "e-voting packet." #: ../../08-haaletamine.rst msgid "params.VotesFrom" msgstr "params.VotesFrom" #: ../../08-haaletamine.rst:764 msgid "E-hääled alates sellest järjenumbrist." msgstr "E-votes from this serial number." #: ../../08-haaletamine.rst msgid "params.BatchMaxSize" msgstr "params.BatchMaxSize" #: ../../08-haaletamine.rst:765 msgid "E-hääletamise paki suurus." msgstr "Size of e-voting package." #: ../../08-haaletamine.rst msgid "result.batchRecords" msgstr "result.batchRecords" #: ../../08-haaletamine.rst:772 msgid "E-häälte loend" msgstr "List of e-votes" #: ../../08-haaletamine.rst msgid "result.batchRecords.seqNo" msgstr "result.batchRecords.seqNo" #: ../../08-haaletamine.rst:774 msgid "Hääle järjenumber" msgstr "Voice of the sequel" #: ../../08-haaletamine.rst msgid "result.batchRecords.idCode" msgstr "result.batchRecords.idCode" #: ../../08-haaletamine.rst:776 msgid "Hääletaja isikukood" msgstr "Voter identification code" #: ../../08-haaletamine.rst msgid "result.batchRecords.voterName" msgstr "result.batchRecords.voterName" #: ../../08-haaletamine.rst:778 msgid "Hääletaja nimi" msgstr "Name of voter" #: ../../08-haaletamine.rst msgid "result.batchRecords.kovCode" msgstr "result.batchRecords.kovCode" #: ../../08-haaletamine.rst:780 msgid "KOV EHAK kood" msgstr "KOV EHAK code" #: ../../08-haaletamine.rst msgid "result.batchRecords.electoralDistrictNo" msgstr "result.batchRecords.electoralDistrictNo" #: ../../08-haaletamine.rst:782 msgid "Valimisringkonna number" msgstr "Constituency number" #: ../../08-haaletamine.rst:788 msgid "Võimalikud veateated päringu ``RPC.Votes`` korral." msgstr "Possible error messages in case of ``RPC.Votes`` query." #~ msgid "result.DocumentNo" #~ msgstr "result.DocumentNo" #~ msgid "params.DocumentNo" #~ msgstr "params.DocumentNo" #~ msgid "Hääle allkirjastaja Smart-ID dokumendi number." #~ msgstr "Smart ID document number of the person who signed the vote." ================================================ FILE: Documentation/public/protokollid/locales/en/LC_MESSAGES/09-tootlemine.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 08:56+0000\n" "PO-Revision-Date: 2024-03-01 18:35+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.15.0\n" #: ../../09-tootlemine.rst:5 msgid "E-valimiskasti töötlemisetapi andmestruktuurid" msgstr "Data structures for the digital ballot box processing phase" #: ../../09-tootlemine.rst:9 msgid "Tühistus- ja ennistusnimekiri" msgstr "Revocation and Restoration List" #: ../../09-tootlemine.rst:11 msgid "" "Tühistus- ja ennistusnimekiri sisaldab andmeid isikute kohta, kelle e-hääl " "tuleb tühistada (ei lähe arvesse valimistulemuste kokkulugemisel) või " "ennistada (s.t. tühistatakse eelnev tühistamine ning häälte uuesti üle " "lugemisel võetakse ennistatud e-hääl arvesse). Nimekiri laaditakse süsteemi " "digitaalselt allkirjastatud dokumendina, mille andmefaili vorming on " "järgmine:" msgstr "" "The revocation and restoration lists contain information on the persons " "whose e-vote is to be annulled (not counted in the count) or restored (i.e. " "the previous annulment is cancelled and the restored e-vote is counted in " "the recount). The list will be uploaded to the system as a digitally signed " "document with the following data file format:" #: ../../09-tootlemine.rst:17 ../../09-tootlemine.rst:35 #: ../../09-tootlemine.rst:61 ../../09-tootlemine.rst:146 msgid "Näide:" msgstr "Example:" #: ../../09-tootlemine.rst:24 msgid "E-hääletanute nimekiri" msgstr "List of e-voters" #: ../../09-tootlemine.rst:26 msgid "" "E-hääletanute nimekiri on pärast e-hääletamise lõppu väljastatav nimekiri " "e-hääletanud isikutest, sordituna valimisjaoskondade kaupa. Dokument " "genereeritakse töötlemisrakenduse poolt." msgstr "" "The list of e-voters is the list of e-voters issued after the end of " "e-voting, sorted by polling station. The document is generated by the " "processing application." #: ../../09-tootlemine.rst:42 msgid "Hääletamistulemus" msgstr "Voting results" #: ../../09-tootlemine.rst:44 msgid "" "Võtmerakenduse poolt dekrüpteeritud ning summeeritud hääled jagatud " "valimisringkondade ja jaoskondade kaupa." msgstr "" "Votes decrypted and summed by the key application, broken down by district " "and polling station." #: ../../09-tootlemine.rst:47 msgid "" "Hääletamistulemuste failis peavad iga jaoskonna kohta olema järgmised " "andmed." msgstr "" "The voting results file must contain the following information for each " "station." #: ../../09-tootlemine.rst:49 msgid "" "Rikutud ja kehtetute häälte arvu näitav kirje. Seda ka juhul, kui " "valimisjaoskonnas polnud ühtki rikutud või kehtetut häält: sellisel juhul on" " häälte arv null." msgstr "" "A record showing the number of spoilt and invalid votes. This is the case " "even if there were no spoilt or invalid votes in the polling station: in " "this case the number of votes is zero." #: ../../09-tootlemine.rst:53 msgid "" "Iga valiku poolt antud häälte arvu näitav kirje. Seda ka juhul, kui " "valimisjaoskonnas ei antud selle valiku poolt ühtki häält: sellisel juhul on" " häälte arv null." msgstr "" "A record showing the number of votes cast for each option. This is the case " "even if no votes were cast for that option in the polling station: in this " "case the number of votes is zero." #: ../../09-tootlemine.rst:69 msgid "E-valimiskast" msgstr "Ballot box" #: ../../09-tootlemine.rst:71 msgid "" "Fail sisaldab kogumisteenuse poolt vastu võetud hääli koos häälte juurde " "kuuluvate andmetega." msgstr "" "The file contains the votes received by the collection service, together " "with the data associated with the votes." #: ../../09-tootlemine.rst:74 msgid "Faili vorming on Zip64 konteiner." msgstr "The file format is Zip64 container." #: ../../09-tootlemine.rst:76 msgid "Valija-spetsiifilised kaustad asuvad vahetult juurkausta `votes` all." msgstr "" "The voter-specific folders are located just below the `votes` root folder." #: ../../09-tootlemine.rst:78 msgid "Faili sisu:" msgstr "File content:" #: ../../09-tootlemine.rst:80 msgid ":file:`votes//`" msgstr ":file:`votes//`" #: ../../09-tootlemine.rst:82 msgid ":file:`.version`" msgstr ":file:`.version`" #: ../../09-tootlemine.rst:84 msgid ":file:`.`" msgstr ":file:`.`" #: ../../09-tootlemine.rst:86 msgid ":file:`.*`" msgstr ":file:`.*`" #: ../../09-tootlemine.rst:88 msgid "kus:" msgstr "where:" #: ../../09-tootlemine.rst:90 msgid "```` on valija identifikaator, Eesti puhul isikukood;" msgstr "" "```` is the voter's identifier, which in Estonia is the voter's " "personal identification number;" #: ../../09-tootlemine.rst:92 msgid "" "```` on hääle esitamise kellaaeg vormingus " "``yyyymmddhhmmssmmm±zzzz``;" msgstr "" "```` is the time of day for the submission of the vote in the " "format ``yyymmddhhmmmmmmm±zzzz``;" #: ../../09-tootlemine.rst:95 msgid "" "see kellaaeg kajastab hetke, mil päring kogumisteenusesse tehti, ja on antud" " lihtsalt valimiskasti inimloetavuse parandamiseks; hääle tegelik ajamärk " "või -tempel on mõne kvalifitseeriva vastuse sees;" msgstr "" "this time reflects the moment when the query was made to the collection " "service and is given simply to improve the human readability of the ballot " "box; the actual time stamp or time stamp of the vote is inside some " "qualifying response;" #: ../../09-tootlemine.rst:99 msgid "```` on valikute konteineri tüüp, Eesti puhul BDOC;" msgstr "" "```` is the type of the ballot container, for Estonia BDOC;" #: ../../09-tootlemine.rst:101 msgid "" "kusjuures BDOC ise on lihtsalt põhiprofiiliga ja ei sisalda kvalifitseerivad" " parameetreid (kehtivuskinnitusi, ajamärgendeid, ajatempleid)," msgstr "" "whereas the BDOC itself is just a basic profile and does not contain any " "qualifying parameters (validations, timemarks, timestamps)," #: ../../09-tootlemine.rst:105 msgid "" "```` on häält kvalifitseeriva protokolli tüüp, millest hetkel " "võimalikud on:" msgstr "" "```` is the type of vote qualifying protocol currently possible:" #: ../../09-tootlemine.rst:108 msgid "" "``ocsp`` - *Online Certificate Status Protocol* (kehtivuskinnitus, `RFC 6960" " `_) kinnitab valija " "allkirjastamissertifikaadi kehtivust hääle andmise hetkel," msgstr "" "``ocsp`` - *Online Certificate Status Protocol* (`RFC 6960 " "`_) confirms the validity of the " "voter's signature certificate at the moment of casting the vote," #: ../../09-tootlemine.rst:112 msgid "" "``tsp`` - *Time-Stamp Protocol* (ajatempel, `RFC 3161 " "`_) kinnitab, et päringu tegemise " "hetkeks oli hääl olemas," msgstr "" "``tsp`` - *Time-Stamp Protocol* (timestamp, `RFC 3161 " "`_) confirms that a ballot was present " "at the time the request was made," #: ../../09-tootlemine.rst:116 msgid "" "``tspreg`` - sama, mis ``tsp``, aga nonsiks pannakse kogumisteenuse allkiri " "päringu ``MessageImprint`` elemendil, et häält registreerida." msgstr "" "``tspreg`` - the same as ``tsp``, but with the addition of the collection " "service signature on the ``MessageImprint`` element of the query to register" " the vote." #: ../../09-tootlemine.rst:119 msgid "Iga hääle kohta esinevad failid on:" msgstr "The files per vote are:" #: ../../09-tootlemine.rst:121 msgid "" "``.version`` - hääle andmise ajal kehtinud valijate nimekirja " "versioon;" msgstr "" "``.version`` - the version of the electoral roll in force at the " "time the vote was cast;" #: ../../09-tootlemine.rst:124 msgid "" "``.`` - valikute konteiner, mille sees on valiku " "identifikaator kujul ``..ballot``. Eesti puhul " "BDOC-konteineris olev vastava nimega fail;" msgstr "" "``.`` - a ballot container containing a ballot " "identifier of the form ``..ballot``. In the case of " "Estonia, the file with the corresponding name in the BDOC container;" #: ../../09-tootlemine.rst:128 msgid "" "``.`` - häält kvalifitseeriva protokolli päringu " "vastus; neid võib esineda mitu, aga iga protokolli kohta maksimaalselt üks." msgstr "" "``.`` - the response to the query of the protocol " "qualifying the vote; there may be more than one, but not more than one per " "protocol." #: ../../09-tootlemine.rst:134 msgid "Anonüümistatud e-valimiskast" msgstr "Anonymous ballot box" #: ../../09-tootlemine.rst:136 msgid "" "Valimisringkondade ja jaoskondade järgi grupeeritud krüpteeritud hääled. " "Anonüümistatud e-valimiskastis puudub informatsioon valijate kohta." msgstr "" "Encrypted votes grouped by districts and stations. No information on voters " "is available in the anonymised e-voting box." #: ../../09-tootlemine.rst:139 msgid "" "Anonüümistatud e-valimiskast on töötlemisrakenduse väljund ning " "võtmerakenduse dekrüpteerimise tööriista sisend." msgstr "" "The anonymised e-voting box is the output of the processing application and " "the input of the decryption tool of the key application." ================================================ FILE: Documentation/public/protokollid/locales/en/LC_MESSAGES/11-audit.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 19:52+0000\n" "PO-Revision-Date: 2024-03-01 18:43+0200\n" "Last-Translator: \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.15.0\n" #: ../../11-audit.rst:5 msgid "Hääletamistulemuse audit" msgstr "Audit of voting results" #: ../../11-audit.rst:8 msgid "Miksimistõendi kontroll" msgstr "Verification of Proof-of-Shuffle" #: ../../11-audit.rst:10 msgid "" "Miksimistõendi kontrollimiseks kasutatakse algoritmi nagu on defineeritud " "`Verificatumi verifitseerija implementeerimise manuaalis " "`_." msgstr "" "The verification of the proof-of-shuffle is done using the algorithm as " "defined in the `Verificatum Verifier Implementation Manual " "`_." #: ../../11-audit.rst:14 msgid "" "Märgime, et miksimistõendi koostamisel lisatakse krüptogrammile andmed " "valimiste, ringkonna, jaoskonna ja küsimuse identifikaatori kohta. " "Lisamiseks kodeeritakse vastav väli rühma elemendina, kasutades " "pimendamiseks juhuslikkust 0. Näitena, kui esialgu on krüptogramm :math:`c_0" " = (c_{00}, c_{01})`, kasutades avalikku võtit :math:`pk = (g, y)`, siis " "Verificatumi sisendina kasutatakse laia krüptogrammi :math:`C = (c_{id}, " "c_d, c_s, c_q, c_0)`, kus:" msgstr "" "Note that when the proof-of-shuffle is generated, the cryptogram is appended" " with the election, district, station and question identifier. For the " "purpose of insertion, the corresponding field is coded as a group element " "using randomness 0 for obfuscation. As an example, if the initial cryptogram" " is :math:`c_0 = (c_{00}, c_{01})` using the public key :math:`pk = (g, y)`," " then the input to Verificatum is a broad cryptogram :math:`C = (c_{id}, " "c_d, c_s, c_q, c_0)` where:" #: ../../11-audit.rst:21 msgid "" "valimiste identifikaatori pseudokrüptogramm on antud kujul :math:`c_{id} = " "(1, encode(id))`, kus funktsioon :math:`encode` kodeerib sõne vastava rühma " "elemendina ja `id` on valimiste identifikaatori sõne." msgstr "" "the pseudocryptogram of the election identifier is given by :math:`c_{id} = " "(1, encode(id))`, where :math:`encode` encodes the seed as an element of the" " corresponding group and `id` is the seed of the election identifier." #: ../../11-audit.rst:24 msgid "" "ringkonna identifikaatori pseudokrüptogramm on antud kujul :math:`c_d = (1, " "encode(d))`, kus `d` on ringkonna identifikaatori sõne." msgstr "" "the pseudocryptogram of the district identifier is given by :math:`c_d = (1," " encode(d))`, where `d` is the seed of the district identifier." #: ../../11-audit.rst:26 msgid "" "jaoskonna identifikaatori pseudokrüptogramm on antud kujul :math:`c_s = (1, " "encode(s))`, kus `s` on jaoskonna identifikaatori sõne." msgstr "" "the pseudocryptogram of the station identifier is given by :math:`c_s = (1, " "encode(s))`, where `s` is the seed of the station identifier." #: ../../11-audit.rst:28 msgid "" "küsimuse identifikaatori pseudokrüptogramm on antud kujul :math:`c_q = (1, " "encode(q))`, kus `q` on küsimuse identifikaatori sõne." msgstr "" "the pseudocryptogram of the question identifier is given by :math:`c_q = (1," " encode(q))`, where `q` is the seed of the question identifier." #: ../../11-audit.rst:31 msgid "" "Sellisel juhul defineeritakse laia krüptogrammile vastava avaliku võtmena " ":math:`((g,1), (g,1), (g,1), (g,1), (g,y))`." msgstr "" "In this case, the public key corresponding to the wide cryptogram is defined" " as :math:`((g,1), (g,1), (g,1), (g,1), (g,y))`." #: ../../11-audit.rst:35 msgid "Korrektse dekrüpteerimise tõendi kontroll" msgstr "Checking the Proof-of-Decryption" #: ../../11-audit.rst:37 msgid "" "Olgu antud krüptogramm :math:`c = (c_0, c_1)`, mis dekrüpteeritakse " "väärtuseks :math:`d` antud avaliku võtmega :math:`pk` üle parameetrite " ":math:`(p,g)` ja dekrüpteerimistõendiga :math:`(a,b,s)`." msgstr "" "Given a cryptogram :math:`c = (c_0, c_1)`, decrypted to the value :math:`d` " "with the given public key :math:`pk` over the parameters :math:`(p,g)` and " "the decryption key :math:`(a,b,s)`." #: ../../11-audit.rst:41 msgid "" "Korrektse dekrüpteerimise kontrollimise jaoks on tarvis arvutada mitte-" "interaktiivne kontrollija väljakutse. Selle jaoks kodeeritakse " ":math:`\"DECRYPTION\" || pk || c || d || a || b` DER-kodeeringus. Baidijada " "kasutatakse deterministliku juhuarvugeneraatori initsialiseerimiseks ja " "selle väljundist loetakse rühma järgu pikkune täisarv :math:`k`." msgstr "" "To verify the proof-of-decryption it is necessary to calculate the challenge" " for non-interactive verifier. For this purpose, :math:`\"DECRYPTION\" || pk" " || c || d || a || b` is encoded in DER encoding. The byte sequence is used " "to initialise a deterministic random number generator and its output is read" " as a group-order integer :math:`k`." #: ../../11-audit.rst:47 msgid "" "Dekrüpteerimistõendi kontrolliks tuleb veenduda, et :math:`c_0^s = a * " "(c_1/d)^k` ja :math:`g^s = b * y^k`." msgstr "" "To check the decryption proof, make sure that :math:`c_0^s = a * (c_1/d)^k` " "and :math:`g^s = b * y^k`." #: ../../11-audit.rst:51 msgid "Korrektse teisendamise kontroll" msgstr "Correct conversion check" #: ../../11-audit.rst:53 msgid "" "Kontrollimaks, et teisendus IVXV e-valimiskasti ja Verificatumi " "krüptogrammide vahel on tehtud korrektselt, tuleb korrata teisendust " "sõltumatult. Pärast sõltumatut teisendust tuleb võrrelda saadud väljundeid. " "Kuna teisendamine on deterministlik protseduur, siis garanteerib kordamine " "tegevuse õigsuse." msgstr "" "To verify that the conversion between the IVXV ballot Box and the " "Verificatum cryptograms has been done correctly, the conversion must be " "repeated independently. After the independent conversion, the resulting " "outputs must be compared. Since the conversion is a deterministic procedure," " the repetition guarantees the correctness of the operation." ================================================ FILE: Documentation/public/protokollid/locales/en/LC_MESSAGES/12-lisad.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.0\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-03 19:52+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.15.0\n" #: ../../12-lisad.rst:5 msgid "Lisad" msgstr "More" #: ../../12-lisad.rst:8 msgid "Andmestruktuuride ASN.1 spetsifikatsioon" msgstr "ASN.1 specification of data structures" #: ../../12-lisad.rst:10 msgid "IVXV ElGamal üldised andmestruktuurid" msgstr "IVXV ElGamal general data structures" #: ../../12-lisad.rst:16 msgid "IVXV ElGamal ModP spetsiifilised andmestruktuurid" msgstr "IVXV ElGamal ModP specific data structures" #: ../../12-lisad.rst:22 msgid "IVXV ElGamal ECC spetsiifilised andmestruktuurid" msgstr "IVXV ElGamal ECC specific data structures" #: ../../12-lisad.rst:31 msgid "Elektroonilise hääle vormingu spetsifikatsioon" msgstr "Specification for electronic voice formatting" #: ../../12-lisad.rst:33 msgid "" "Käesoleva protokolliversiooniga kooskõlaline ettepanek VVK otsuseks " "hääletamissedeli ja elektroonilise hääle vormi kehtestamiseks." msgstr "" "Proposal for a decision of the IGC establishing the voting form and the " "electronic voting form, in conformity with this version of the minutes." #: ../../12-lisad.rst:40 msgid "Vead töötlemisprotsessis" msgstr "Errors in the processing" #: ../../12-lisad.rst:42 msgid "" "Anname ülevaate veakoodidest töötlemisprotsessis. Veakoodid kirjeldavad vigu" " üksiku elemendi verifitseerimisel - hääl, registreerimistõend, " "registreerimispäring - ning häälte, registreerimistõendite ja " "registreerimispäringute vahelise vastavuse loomisel." msgstr "" "We give an overview of error codes in the processing process. Error codes " "describe errors in the verification of a single element - vote, registration" " certificate, registration request - and in the matching of votes, " "registration certificates and registration requests." #: ../../12-lisad.rst:47 msgid "" "Enamus veaolukordi on pigem hüpoteetilised (nt. `REG_NO_NONCE`), siiski on " "tegemist olukordadega, mis programselt võivad esineda ning seetõttu tuleb " "neid ka käsitleda." msgstr "" "Most of the error situations are rather hypothetical (e.g. `REG_NO_NONCE`), " "however, they are situations that can occur programmatically and therefore " "need to be addressed." #: ../../12-lisad.rst:51 msgid "" "Veaolukord tähendab, et konkreetne element ei liigu edasi töötlemise " "järgmisesse faasi." msgstr "" "An error condition means that a particular element does not move on to the " "next phase of processing." #: ../../12-lisad.rst:53 msgid "Töötlemisprotsessi veakoodid" msgstr "Error codes for the processing process" #: ../../12-lisad.rst:57 ../../12-lisad.rst:121 msgid "Veakood" msgstr "Error code" #: ../../12-lisad.rst:58 ../../12-lisad.rst:122 msgid "Selgitus" msgstr "Explanation" #: ../../12-lisad.rst:59 msgid "``INVALID_FILE_NAME``" msgstr "``INVALID_FILE_NAME``" #: ../../12-lisad.rst:60 msgid "Failinimi ei vasta oodatud mustrile. Viitab tundmatule failile urnis." msgstr "" "The file name does not match the expected pattern. Refers to an unknown file" " in the urn." #: ../../12-lisad.rst:61 msgid "``MISSING_FILE``" msgstr "``MISSING_FILE``" #: ../../12-lisad.rst:62 msgid "Mõni hääle koosseisuks vajalik fail puudub. Nt. ajatempel." msgstr "" "Some of the files needed to compose the votes are missing. E.g. timestamp." #: ../../12-lisad.rst:63 msgid "``REPEATED_FILE``" msgstr "``REPEATED_FILE``" #: ../../12-lisad.rst:64 msgid "Mõnda hääle koosseisuks vajalikku faili on mitu. Nt. kehtivuskinnitus." msgstr "" "There are several files needed to compose some votes. E.g. validity " "confirmation." #: ../../12-lisad.rst:65 msgid "``UNKNOWN_FILE_TYPE``" msgstr "``UNKNOWN_FILE_TYPE``" #: ../../12-lisad.rst:66 msgid "Faili tüüp on tundmatu või mittetoetatud." msgstr "The file type is unknown or unsupported." #: ../../12-lisad.rst:67 msgid "``INVALID_FILE_SIZE``" msgstr "``INVALID_FILE_SIZE``" #: ../../12-lisad.rst:68 msgid "" "Allkirjastatud hääle faili suurus ei vasta seadistustes nõutud " "kriteeriumitele." msgstr "" "The size of the signed vote file does not meet the criteria required in the " "settings." #: ../../12-lisad.rst:69 msgid "``INVALID_BALLOT_SIGNATURE``" msgstr "``INVALID_BALLOT_SIGNATURE``" #: ../../12-lisad.rst:70 msgid "Hääl on vigase allkirjaga." msgstr "The voice has an incorrect signature." #: ../../12-lisad.rst:71 msgid "``MISSING_VOTER_SIGNATURE``" msgstr "``MISSING_VOTER_SIGNATURE``" #: ../../12-lisad.rst:72 msgid "Hääl ei sisalda valija allkirja." msgstr "The vote does not include the voter's signature." #: ../../12-lisad.rst:73 msgid "``VOTER_NOT_FOUND``" msgstr "``VOTER_NOT_FOUND``" #: ../../12-lisad.rst:74 msgid "Valija ei olnud hääletamise hetkel valijate nimekirjas." msgstr "The voter was not on the electoral roll at the time of voting." #: ../../12-lisad.rst:75 msgid "``VOTERLIST_NOT_FOUND``" msgstr "``VOTERLIST_NOT_FOUND``" #: ../../12-lisad.rst:76 msgid "Versioonile vastavat valijate nimekirja ei leitud." msgstr "No voter list matching the version was found." #: ../../12-lisad.rst:77 msgid "``TIME_BEFORE_START``" msgstr "``TIME_BEFORE_START``" #: ../../12-lisad.rst:78 msgid "Hääl on antud enne hääletamisperioodi algust. Viitab testhäälele." msgstr "" "The vote is cast before the start of the voting period. Refers to a test " "vote." #: ../../12-lisad.rst:79 msgid "``REG_RESP_INVALID``" msgstr "``REG_RESP_INVALID``" #: ../../12-lisad.rst:80 msgid "Registreerimistõend/ajatempel on vigane. Viga ATOs või töötlejas." msgstr "" "The registration certificate/time stamp is invalid. Error in ATO or " "processor." #: ../../12-lisad.rst:81 msgid "``REG_REQ_INVALID``" msgstr "``REG_REQ_INVALID``" #: ../../12-lisad.rst:82 msgid "Registreerimispäring on vigane. Viga kogumisteenuses või töötlejas." msgstr "" "The registration request is invalid. Error in collection service or " "processor." #: ../../12-lisad.rst:83 msgid "``REG_RESP_NOT_UNIQUE``" msgstr "``REG_RESP_NOT_UNIQUE``" #: ../../12-lisad.rst:84 msgid "" "Registreerimistõend ei ole unikaalne. Viga kogumisteenuses või töötlejas." msgstr "" "The registration certificate is not unique. Error in collection service or " "processor." #: ../../12-lisad.rst:85 msgid "``REG_REQ_NOT_UNIQUE``" msgstr "``REG_REQ_NOT_UNIQUE``" #: ../../12-lisad.rst:86 msgid "" "Registreerimispäring ei ole unikaalne. Sama räsiga häält on esitatud " "korduvalt." msgstr "" "The registration request is not unique. The same ragged vote has been " "submitted multiple times." #: ../../12-lisad.rst:87 msgid "``REG_NO_NONCE``" msgstr "``REG_NO_NONCE``" #: ../../12-lisad.rst:88 msgid "Registreerimistõendis puudub nonss." msgstr "There is no nonss on the registration certificate." #: ../../12-lisad.rst:89 msgid "``REG_NONCE_NOT_SIG``" msgstr "``REG_NONCE_NOT_SIG``" #: ../../12-lisad.rst:90 msgid "Esitatud nonss ei ole IVXV protokolli kohaselt allkirjastatud." msgstr "" "The submitted nonss have not been signed in accordance with Protocol IVXV." #: ../../12-lisad.rst:91 msgid "``REG_NONCE_ALG_MISMATCH``" msgstr "``REG_NONCE_ALG_MISMATCH``" #: ../../12-lisad.rst:92 msgid "Nonssi allkirjastamisel kasutatud algoritm ei vasta oodatule." msgstr "" "The algorithm used to sign the nonsense does not match the expected one." #: ../../12-lisad.rst:93 msgid "``REG_NONCE_SIG_INVALID``" msgstr "``REG_NONCE_SIG_INVALID``" #: ../../12-lisad.rst:94 msgid "Nonssi allkiri on vigane." msgstr "Nonss's signature is incorrect." #: ../../12-lisad.rst:95 msgid "``UNKNOWN_FILE_IN_VOTE_CONTAINER``" msgstr "``UNKNOWN_FILE_IN_VOTE_CONTAINER``" #: ../../12-lisad.rst:96 msgid "Hääle konteineris on tundmatu fail." msgstr "There is an unknown file in the voice container." #: ../../12-lisad.rst:97 msgid "``TECHNICAL_ERROR``" msgstr "``TECHNICAL_ERROR``" #: ../../12-lisad.rst:98 msgid "Töötlemise ajal tekkis tehniline viga." msgstr "A technical error occurred during processing." #: ../../12-lisad.rst:99 msgid "``REG_RESP_REQ_UNMATCH``" msgstr "``REG_RESP_REQ_UNMATCH``" #: ../../12-lisad.rst:100 msgid "Registreerimistõendi andmed ei vasta registreerimispäringu andmetele." msgstr "" "The information on the registration certificate does not match the " "information on the registration request." #: ../../12-lisad.rst:101 msgid "``REG_REQ_WITHOUT_BALLOT``" msgstr "``REG_REQ_WITHOUT_BALLOT``" #: ../../12-lisad.rst:102 msgid "" "Esitatud on registreerimispäring, kuid hääl puudub urnist. Kogumisteenuse " "viga." msgstr "" "A registration request has been submitted, but there is no vote in the " "ballot box. Collection service error." #: ../../12-lisad.rst:103 msgid "``BALLOT_WITHOUT_REG_REQ``" msgstr "``BALLOT_WITHOUT_REG_REQ``" #: ../../12-lisad.rst:104 msgid "Hääl on esitatud ilma vastava registreerimispäringuta. ATO viga." msgstr "" "The vote is submitted without a corresponding registration request. ATO " "error." #: ../../12-lisad.rst:105 msgid "``SAME_TIME_AS_LATEST``" msgstr "``SAME_TIME_AS_LATEST``" #: ../../12-lisad.rst:106 msgid "Kaks häält samalt valijalt võivad olla arvesse võetavad viimasena." msgstr "Two votes from the same voter may be counted last." #: ../../12-lisad.rst:107 msgid "``INVALID_SIGNATURE_PROFILE``" msgstr "``INVALID_SIGNATURE_PROFILE``" #: ../../12-lisad.rst:108 msgid "Hääle allkirjaprofiil on vigane." msgstr "The signature profile of the vote is incorrect." #: ../../12-lisad.rst:111 msgid "" "Töötlemise käigus tuvastatakse kehtetud sedelid sellisel määral, mil seda " "võimaldavad kontrollid avaliku võtmega. Kuigi kogumisteenus ei luba " "kehtetuid sedeleid talletada, peab töötlemisrakendus kontrolle siiski " "kordama tagamaks mh. võimalike tarkvaravigade vältimise." msgstr "" "Invalid tags will be identified during the processing to the extent that " "public key checks allow. Although the collection service does not allow the " "storage of invalid tags, the processing application must still repeat the " "checks to ensure, inter alia, that possible software bugs are avoided." #: ../../12-lisad.rst:117 msgid "Krüptogrammide kehtivuse kontrolli veakoodid" msgstr "Cryptogram validity check error codes" #: ../../12-lisad.rst:123 msgid "``INVALID_BYTES``" msgstr "``INVALID_BYTES``" #: ../../12-lisad.rst:124 msgid "Baidijada ei ole dekodeeritav ElGamalCiphertext'na" msgstr "Baidijada is not decodable by ElGamalCiphertext" #: ../../12-lisad.rst:125 msgid "``INVALID_GROUP``" msgstr "``INVALID_GROUP``" #: ../../12-lisad.rst:126 msgid "Väärtus ei ole oodatud rühma element" msgstr "The value is not an expected group element" #: ../../12-lisad.rst:127 msgid "``INVALID_RANGE``" msgstr "``INVALID_RANGE``" #: ../../12-lisad.rst:128 msgid "Väärtus on lubatud vahemikust väljas." msgstr "The value is out of range." #: ../../12-lisad.rst:129 msgid "``INVALID_QR``" msgstr "``INVALID_QR```" #: ../../12-lisad.rst:130 msgid "Väärtus ei ole ruutjääk (MODP)." msgstr "The value is not a square residual (MODP)." #: ../../12-lisad.rst:131 msgid "``INVALID_POINT``" msgstr "``INVALID_POINT``" #: ../../12-lisad.rst:132 msgid "Väärtus ei ole kõvera punkt (ECC)." msgstr "The value is not the point of the curve (ECC)." #: ../../12-lisad.rst:133 msgid "``INVALID``" msgstr "``INVALID``" #: ../../12-lisad.rst:134 msgid "Vigane šifreeritud tekst." msgstr "Erroneous shifter text." #~ msgid "IVXV ElGamal ECC spetsifiilised andmestruktuurid" #~ msgstr "" ================================================ FILE: Documentation/public/protokollid/locales/en/LC_MESSAGES/index.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.8.2\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" #: ../../index.rst:5 msgid "IVXV protokollid" msgstr "IVXV Protocols" ================================================ FILE: Documentation/public/protokollid/model/Makefile ================================================ # Source diagrams are all in different .pu files SRC_DIAG= PARENT=sequence # Sub-diagrams are generated from $(PARENT).pu SUB_DIAG=phase1 phase2 phase3 include ../../../common-model.mk # Set environment variables for subdiagrams phase1.env: $(eval DIAGRAM_DEF=-DPHASE_1) phase2.env: $(eval DIAGRAM_DEF=-DPHASE_2) phase3.env: $(eval DIAGRAM_DEF=-DPHASE_3) ================================================ FILE: Documentation/public/protokollid/model/en/lang.pu ================================================ !define TR_A_VOTER() Voter !define TR_P_VOTA() Voting application !define TR_P_VERA() Verification app !define TR_BOX_COLLECT() Online (RIA) !define TR_P_COLLECT() Collection service !define TR_BOX_REG() Registration service (SK) !define TR_P_REG() Registration service !define TR_BOX_PROCESSOR() Offline (RVT) !define TR_P_PROCESSOR() Processor !define TR_PHASE1() Voter votes !define TR_PHASE2() Voter verifies the vote !define TR_PHASE3() Services hand over the data !define TR_PHASE4() Processor verifies consistency of the data ================================================ FILE: Documentation/public/protokollid/model/et/lang.pu ================================================ !define TR_A_VOTER() Hääletaja !define TR_P_VOTA() Valijarakendus !define TR_P_VERA() Kontrollrakendus !define TR_BOX_COLLECT() Online (RIA) !define TR_P_COLLECT() Kogumisteenus !define TR_BOX_REG() Registreerimisteenus (SK) !define TR_P_REG() Registreerimisteenus !define TR_BOX_PROCESSOR() Offline (RVT) !define TR_P_PROCESSOR() Töötlemisrakendus !define TR_PHASE1() Hääletaja hääletab !define TR_PHASE2() Hääletaja kontrollib häält !define TR_PHASE3() Teenused annavad andmed üle !define TR_PHASE4() Töötleja kontrollib teenuste vaateid ================================================ FILE: Documentation/public/protokollid/model/sequence.pu ================================================ @startuml !ifdef PHASE_1 !define PHASE_VOTE !define PHASE_VOTER !define PHASE_COLLECT !define PHASE_REG !endif !ifdef PHASE_2 !define PHASE_VERIFY !define PHASE_VOTER !define PHASE_COLLECT !endif !ifdef PHASE_3 !define PHASE_COLLECT !define PHASE_REG !define PHASE_PROC !endif !ifdef PHASE_VOTER actor "TR_A_VOTER()" as a_voter !endif !ifdef PHASE_VOTE participant "TR_P_VOTA()" as p_vota !endif !ifdef PHASE_VERIFY participant "TR_P_VERA()" as p_vera !endif !ifdef PHASE_COLLECT box "TR_BOX_COLLECT()" participant "TR_P_COLLECT()" as p_collect end box !endif !ifdef PHASE_REG box "TR_BOX_REG()" participant "TR_P_REG()" as p_reg end box !endif !ifdef PHASE_PROC box "TR_BOX_PROCESSOR()" participant "TR_P_PROCESSOR()" as p_processor end box !endif !ifdef PHASE_1 == TR_PHASE1() == a_voter --> p_vota: ballot_v, key_v p_vota -> p_collect: vote_v = Sign(key_v, Enc(ballot_v)) p_collect -> p_reg: reg_request_v = Sign(key_k, (v_id, Hash(vote_v))) p_reg -> p_reg: VerifyAndStore(reg_request_v, cert_k) p_reg -> p_collect: reg_confirmation_v = Sign(key_r, Hash(reg_request_v)) p_collect -> p_collect: VerifyAndStore(reg_confirmation_v, cert_r) p_collect -> p_vota: v_id, reg_request_v, reg_confirmation_v p_vota -> p_vota: Verify(reg_request_v, cert_k) p_vota -> p_vota: Verify(reg_confirmation_v, cert_r) p_vota -> p_vota: Verify(reg_confirmation_v, reg_request_v, vote_v) p_vota --> a_voter: v_id !endif !ifdef PHASE_2 == TR_PHASE2() == a_voter --> p_vera: v_id p_vera -> p_collect: v_id p_collect -> p_vera: vote_v, reg_request_v, reg_confirmation_v p_vera -> p_vera: Verify(reg_request_v, cert_k) p_vera -> p_vera: Verify(reg_confirmation_v, cert_r) p_vera -> p_vera: Verify(reg_confirmation_v, reg_request_v, vote_v) p_vera --> a_voter: ballot_v !endif !ifdef PHASE_3 == TR_PHASE3() == p_collect -> p_processor: (v_id, vote_i, reg_request_i, reg_confirmation_i) p_reg -> p_processor: (v_id, Hash(vote_i), reg_request_i) == TR_PHASE4() == !endif @enduml ================================================ FILE: Documentation/public/protokollid/paragraph.txt ================================================ 3. Kehtestada elektroonilise hääle vorm järgmiselt (skeem lisatud). 3.1. Valijarakenduses elektrooniliselt allkirjastatud elektrooniline hääl on digitaalselt allkirjastatud fail, mille nimi on teksti kujul e-hääletamise aeg (ajatempel). Faili sees asub punktis 3.2 nimetatud salastatud (krüpteeritud) elektrooniline hääl ja valija elektrooniline allkiri. Elektroonilise allkirja sertifikaatide kehtivuskinnitus ja ajatempel saadakse usaldusteenuse pakkujalt kogujasse eraldi ning valijarakenduse faili ennast ei muudeta, vaid kehtivuskinnitus ja ajatempel hoiustatakse valijarakenduses loodud allkirjastatud failist lahus. 3.2. Elektrooniline hääl on krüpteeritud Riigikogu valimiste seaduse §483 lõike 3 alusel hääletamiseks loodud elektrooniliste häälte salastamise võtmega andmefail. Faili nimi algab valimiste või rahvahääletuse identifikaatoriga ja lõpeb küsimuse identifikaatoriga. Faili laiend on .ballot. Faili sees on krüpteeritud kujul punktides 3.4, 3.5, 3.6 või 3.7 nimetatud andmeelemendid vastavalt sellele, kas tegemist on Euroopa Parlamendi, Riigikogu või kohaliku omavalitsuse volikogu valimiste või rahvahääletusega. 3.3. Avatud (dekrüpteeritud) elektrooniline hääl on elektrooniliste häälte avamise arvuti (võtmeprotseduurideks mõeldud arvuti) mälus olev andmehulk, mis koosneb kahest andmeelemendist ja neid eraldavatest märgenditest. 3.4. Euroopa Parlamendi valimiste andmeelementide ja märgendite järjekord on: 3.4.1. sõne 0000 ja märgend ASCII kuueteistkümnendkood 2E; 3.4.2. kandidaadi registreerimisnumber. 3.5. Riigikogu valimiste andmeelementide ja märgendite järjekord on: 3.5.1. sõne 0000 ja märgend ASCII kuueteistkümnendkood 2E; 3.5.2. kandidaadi registreerimisnumber. 3.6. Kohaliku omavalitsuse volikogu valimiste andmeelementide ja märgendite järjekord on: 3.6.1. kohaliku omavalitsuse üksuse EHAK kood ja märgend ASCII kuueteistkümnendkood 2E; 3.6.2. kandidaadi registreerimisnumber. 3.7. Rahvahääletuse andmeelementide ja märgendite järjekord on: 3.7.1. sõne 0000 ja märgend ASCII kuueteistkümnendkood 2E; 3.7.2. vastuse kood. ================================================ FILE: Documentation/public/protokollid/spelling_wordlist.txt ================================================ ================================================ FILE: Documentation/public/uldsisukord/.gitignore ================================================ nimekiri.rst ================================================ FILE: Documentation/public/uldsisukord/Makefile ================================================ DEPENDENCIES := nimekiri.rst include ../../common.mk nimekiri.rst: ../../documents.py > $@ ================================================ FILE: Documentation/public/uldsisukord/annotatsioon.rst ================================================ .. IVXV dokumentatsiooni üldsisukord Annotatsioon ------------ IVXV dokumentatsiooni üldsisukord, infosüsteemi dokumentide sisukorradokument. ================================================ FILE: Documentation/public/uldsisukord/index.rst ================================================ .. IVXV dokumentatsiooni üldsisukord IVXV dokumentatsiooni üldsisukord ========================================================================= .. raw:: html

NB! See on HTML-versioon dokumendist. Tellijale antakse üle PDF-versioon.

.. toctree:: :maxdepth: 2 annotatsioon nimekiri tarned ================================================ FILE: Documentation/public/uldsisukord/locales/en/LC_MESSAGES/annotatsioon.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" #: ../../annotatsioon.rst:4 msgid "Annotatsioon" msgstr "Annotation" #: ../../annotatsioon.rst:6 msgid "" "IVXV dokumentatsiooni üldsisukord, infosüsteemi dokumentide " "sisukorradokument." msgstr "" "Table of contents for the IVXV documentation." ================================================ FILE: Documentation/public/uldsisukord/locales/en/LC_MESSAGES/index.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-02-29 10:34+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: en \n" "Language: en\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "Generated-By: Babel 2.10.3\n" #: ../../index.rst:4 msgid "IVXV dokumentatsiooni üldsisukord" msgstr "IVXV documentation overview" ================================================ FILE: Documentation/public/uldsisukord/locales/en/LC_MESSAGES/nimekiri.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2025, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2025. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-25 13:00+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../nimekiri.rst:4 msgid "Dokumendid" msgstr "Documents" #: ../../nimekiri.rst:7 msgid "Ülddokumendid" msgstr "General documents" #: ../../nimekiri.rst:14 ../../nimekiri.rst:32 ../../nimekiri.rst:65 #: ../../nimekiri.rst:98 msgid "Nimi" msgstr "Name" #: ../../nimekiri.rst:15 ../../nimekiri.rst:33 ../../nimekiri.rst:66 #: ../../nimekiri.rst:99 msgid "ID" msgstr "ID" #: ../../nimekiri.rst:16 ../../nimekiri.rst:34 ../../nimekiri.rst:67 #: ../../nimekiri.rst:100 msgid "Versioon" msgstr "Version" #: ../../nimekiri.rst:17 ../../nimekiri.rst:35 ../../nimekiri.rst:68 #: ../../nimekiri.rst:101 msgid "Kuupäev" msgstr "Date" #: ../../nimekiri.rst:19 msgid "IVXV dokumentatsiooni üldsisukord" msgstr "" #: ../../nimekiri.rst:20 msgid "IVXV-YS-1.10" msgstr "" #: ../../nimekiri.rst:21 ../../nimekiri.rst:44 ../../nimekiri.rst:49 #: ../../nimekiri.rst:72 ../../nimekiri.rst:77 ../../nimekiri.rst:82 #: ../../nimekiri.rst:87 ../../nimekiri.rst:105 ../../nimekiri.rst:110 #: ../../nimekiri.rst:115 ../../nimekiri.rst:125 ../../nimekiri.rst:130 #: ../../nimekiri.rst:135 msgid "1.10" msgstr "" #: ../../nimekiri.rst:22 ../../nimekiri.rst:45 ../../nimekiri.rst:50 #: ../../nimekiri.rst:73 ../../nimekiri.rst:78 ../../nimekiri.rst:83 #: ../../nimekiri.rst:88 ../../nimekiri.rst:106 ../../nimekiri.rst:111 #: ../../nimekiri.rst:116 ../../nimekiri.rst:126 ../../nimekiri.rst:131 #: ../../nimekiri.rst:136 msgid "25.09.2025" msgstr "" #: ../../nimekiri.rst:25 msgid "Spetsifikatsioonid" msgstr "Specifications" #: ../../nimekiri.rst:37 msgid "IVXV kasutusmallid" msgstr "" #: ../../nimekiri.rst:38 msgid "IVXV-KM-1.8.1" msgstr "" #: ../../nimekiri.rst:39 msgid "1.8.1" msgstr "" #: ../../nimekiri.rst:40 msgid "16.12.2022" msgstr "" #: ../../nimekiri.rst:42 msgid "IVXV protokollide kirjeldus" msgstr "" #: ../../nimekiri.rst:43 msgid "IVXV-PR-1.10" msgstr "" #: ../../nimekiri.rst:47 msgid "IVXV arhitektuur" msgstr "" #: ../../nimekiri.rst:48 msgid "IVXV-AR-1.10" msgstr "" #: ../../nimekiri.rst:52 msgid "IVXV võtmerakendus" msgstr "" #: ../../nimekiri.rst:53 msgid "IVXV-SVR-1.8.0" msgstr "" #: ../../nimekiri.rst:54 ../../nimekiri.rst:120 msgid "1.8.0" msgstr "" #: ../../nimekiri.rst:55 ../../nimekiri.rst:121 msgid "01.12.2022" msgstr "" #: ../../nimekiri.rst:58 msgid "Ingliskeelsed dokumendid" msgstr "Documents in english" #: ../../nimekiri.rst:70 msgid "IVXV protocols" msgstr "" #: ../../nimekiri.rst:71 msgid "IVXV-PR-EN-1.10" msgstr "" #: ../../nimekiri.rst:75 msgid "IVXV architecture" msgstr "" #: ../../nimekiri.rst:76 msgid "IVXV-AR-EN-1.10" msgstr "" #: ../../nimekiri.rst:80 msgid "VIS3-EHS interfaces" msgstr "" #: ../../nimekiri.rst:81 msgid "IVXV-VIS-EHS-EN-1.10" msgstr "" #: ../../nimekiri.rst:85 msgid "IVXV Backend Log Messages" msgstr "" #: ../../nimekiri.rst:86 msgid "IVXV-LOGS-EN-1.10" msgstr "" #: ../../nimekiri.rst:91 msgid "Juhendid" msgstr "User guides" #: ../../nimekiri.rst:103 msgid "IVXV seadistuste koostamise juhend" msgstr "" #: ../../nimekiri.rst:104 msgid "IVXV-JSK-1.10" msgstr "" #: ../../nimekiri.rst:108 msgid "IVXV kogumisteenuse haldusjuhend" msgstr "" #: ../../nimekiri.rst:109 msgid "IVXV-JSH-1.10" msgstr "" #: ../../nimekiri.rst:113 msgid "IVXV haldusteenuse kasutusjuhend" msgstr "" #: ../../nimekiri.rst:114 msgid "IVXV-JHT-1.10" msgstr "" #: ../../nimekiri.rst:118 msgid "IVXV API" msgstr "" #: ../../nimekiri.rst:119 msgid "IVXV-API-1.8.0" msgstr "" #: ../../nimekiri.rst:123 msgid "IVXV audiitori juhend" msgstr "" #: ../../nimekiri.rst:124 msgid "IVXV-JAJ-1.10" msgstr "" #: ../../nimekiri.rst:128 msgid "IVXV valijarakendus" msgstr "" #: ../../nimekiri.rst:129 msgid "IVXV-JVR-1.10" msgstr "" #: ../../nimekiri.rst:133 msgid "IVXV valijarakenduse pakendamine" msgstr "" #: ../../nimekiri.rst:134 msgid "IVXV-JVP-1.10" msgstr "" ================================================ FILE: Documentation/public/uldsisukord/locales/en/LC_MESSAGES/tarned.po ================================================ # SOME DESCRIPTIVE TITLE. # Copyright (C) 2016-2024, Cybernetica AS # This file is distributed under the same license as the Elektroonilise # hääletamise infosüsteem package. # FIRST AUTHOR , 2024. # msgid "" msgstr "" "Project-Id-Version: Elektroonilise hääletamise infosüsteem 1.10.3\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2025-09-25 13:06+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: en\n" "Language-Team: en \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Generated-By: Babel 2.15.0\n" #: ../../tarned.rst:4 msgid "Tarned" msgstr "Deliveries" #: ../../tarned.rst:7 msgid "Muudatused tarne 1.10.4 koosseisus, erinevused võrreldes tarnega 1.10.3" msgstr "" "Changes in the composition of the delivery 1.10.4, differences compared " "to delivery 1.10.3." #: ../../tarned.rst:10 ../../tarned.rst:78 ../../tarned.rst:146 #: ../../tarned.rst:236 ../../tarned.rst:302 ../../tarned.rst:380 #: ../../tarned.rst:451 ../../tarned.rst:545 ../../tarned.rst:614 #: ../../tarned.rst:688 ../../tarned.rst:762 ../../tarned.rst:844 #: ../../tarned.rst:921 ../../tarned.rst:1003 ../../tarned.rst:1084 #: ../../tarned.rst:1174 ../../tarned.rst:1263 msgid "Kogumisteenus" msgstr "Collection service" #: ../../tarned.rst:12 ../../tarned.rst:80 ../../tarned.rst:148 #: ../../tarned.rst:238 ../../tarned.rst:304 ../../tarned.rst:382 #: ../../tarned.rst:453 ../../tarned.rst:547 ../../tarned.rst:616 #: ../../tarned.rst:690 ../../tarned.rst:764 ../../tarned.rst:846 #: ../../tarned.rst:923 ../../tarned.rst:1005 ../../tarned.rst:1086 #: ../../tarned.rst:1176 msgid "Üldised muutused" msgstr "General changes" #: ../../tarned.rst:14 msgid "Valijate nimekirjade muudatuste allalaadimise täpsustused" msgstr "Clarify the download process for voterlist changesets" #: ../../tarned.rst:17 ../../tarned.rst:85 ../../tarned.rst:160 #: ../../tarned.rst:243 ../../tarned.rst:311 ../../tarned.rst:387 #: ../../tarned.rst:470 ../../tarned.rst:555 ../../tarned.rst:625 #: ../../tarned.rst:703 ../../tarned.rst:779 ../../tarned.rst:860 #: ../../tarned.rst:938 ../../tarned.rst:1018 ../../tarned.rst:1102 #: ../../tarned.rst:1193 ../../tarned.rst:1295 msgid "Registreerimisteenus" msgstr "Registration service" #: ../../tarned.rst:19 ../../tarned.rst:26 ../../tarned.rst:30 #: ../../tarned.rst:35 ../../tarned.rst:42 ../../tarned.rst:46 #: ../../tarned.rst:50 ../../tarned.rst:54 ../../tarned.rst:59 #: ../../tarned.rst:71 ../../tarned.rst:82 ../../tarned.rst:87 #: ../../tarned.rst:94 ../../tarned.rst:98 ../../tarned.rst:103 #: ../../tarned.rst:110 ../../tarned.rst:114 ../../tarned.rst:118 #: ../../tarned.rst:122 ../../tarned.rst:127 ../../tarned.rst:139 #: ../../tarned.rst:162 ../../tarned.rst:186 ../../tarned.rst:245 #: ../../tarned.rst:261 ../../tarned.rst:268 ../../tarned.rst:272 #: ../../tarned.rst:276 ../../tarned.rst:280 ../../tarned.rst:285 #: ../../tarned.rst:290 ../../tarned.rst:313 ../../tarned.rst:389 #: ../../tarned.rst:407 ../../tarned.rst:414 ../../tarned.rst:427 #: ../../tarned.rst:472 ../../tarned.rst:491 msgid "Muudatused puuduvad" msgstr "No changes" #: ../../tarned.rst:22 ../../tarned.rst:90 ../../tarned.rst:165 #: ../../tarned.rst:248 ../../tarned.rst:316 ../../tarned.rst:392 #: ../../tarned.rst:475 ../../tarned.rst:560 ../../tarned.rst:630 #: ../../tarned.rst:708 ../../tarned.rst:784 ../../tarned.rst:865 #: ../../tarned.rst:943 ../../tarned.rst:1023 ../../tarned.rst:1106 #: ../../tarned.rst:1197 ../../tarned.rst:1299 msgid "Kontrollrakendused" msgstr "Verification applications" #: ../../tarned.rst:24 ../../tarned.rst:92 ../../tarned.rst:167 #: ../../tarned.rst:250 ../../tarned.rst:318 ../../tarned.rst:394 #: ../../tarned.rst:477 ../../tarned.rst:562 ../../tarned.rst:632 #: ../../tarned.rst:710 ../../tarned.rst:786 ../../tarned.rst:867 #: ../../tarned.rst:945 ../../tarned.rst:1025 ../../tarned.rst:1108 #: ../../tarned.rst:1199 ../../tarned.rst:1301 msgid "Android" msgstr "Android" #: ../../tarned.rst:28 ../../tarned.rst:96 ../../tarned.rst:175 #: ../../tarned.rst:254 ../../tarned.rst:324 ../../tarned.rst:399 #: ../../tarned.rst:483 ../../tarned.rst:567 ../../tarned.rst:638 #: ../../tarned.rst:714 ../../tarned.rst:791 ../../tarned.rst:871 #: ../../tarned.rst:949 ../../tarned.rst:1029 ../../tarned.rst:1114 #: ../../tarned.rst:1204 ../../tarned.rst:1305 msgid "iOS" msgstr "iOS" #: ../../tarned.rst:33 ../../tarned.rst:101 ../../tarned.rst:184 #: ../../tarned.rst:259 ../../tarned.rst:331 ../../tarned.rst:405 #: ../../tarned.rst:489 ../../tarned.rst:572 ../../tarned.rst:645 #: ../../tarned.rst:719 ../../tarned.rst:797 ../../tarned.rst:876 #: ../../tarned.rst:954 ../../tarned.rst:1034 ../../tarned.rst:1119 #: ../../tarned.rst:1211 ../../tarned.rst:1310 msgid "Miksnet" msgstr "Mixnet" #: ../../tarned.rst:38 ../../tarned.rst:106 ../../tarned.rst:189 #: ../../tarned.rst:264 ../../tarned.rst:336 ../../tarned.rst:410 #: ../../tarned.rst:494 ../../tarned.rst:577 ../../tarned.rst:650 #: ../../tarned.rst:724 ../../tarned.rst:802 ../../tarned.rst:882 #: ../../tarned.rst:959 ../../tarned.rst:1039 ../../tarned.rst:1124 #: ../../tarned.rst:1216 ../../tarned.rst:1314 msgid "Töötleja rakendused" msgstr "Processor applications" #: ../../tarned.rst:40 ../../tarned.rst:108 ../../tarned.rst:191 #: ../../tarned.rst:266 ../../tarned.rst:338 ../../tarned.rst:412 #: ../../tarned.rst:496 ../../tarned.rst:579 ../../tarned.rst:652 #: ../../tarned.rst:726 ../../tarned.rst:804 ../../tarned.rst:884 #: ../../tarned.rst:961 ../../tarned.rst:1041 ../../tarned.rst:1126 msgid "Üldised" msgstr "General" #: ../../tarned.rst:44 ../../tarned.rst:112 ../../tarned.rst:195 #: ../../tarned.rst:270 ../../tarned.rst:343 ../../tarned.rst:416 #: ../../tarned.rst:500 ../../tarned.rst:583 ../../tarned.rst:656 #: ../../tarned.rst:730 ../../tarned.rst:808 ../../tarned.rst:888 #: ../../tarned.rst:965 ../../tarned.rst:1045 ../../tarned.rst:1132 #: ../../tarned.rst:1218 ../../tarned.rst:1315 msgid "Võtmerakendus" msgstr "Key application" #: ../../tarned.rst:48 ../../tarned.rst:116 ../../tarned.rst:199 #: ../../tarned.rst:274 ../../tarned.rst:348 ../../tarned.rst:421 #: ../../tarned.rst:505 ../../tarned.rst:587 ../../tarned.rst:660 #: ../../tarned.rst:734 ../../tarned.rst:812 ../../tarned.rst:892 #: ../../tarned.rst:969 ../../tarned.rst:1052 ../../tarned.rst:1136 #: ../../tarned.rst:1222 ../../tarned.rst:1319 msgid "Töötlemisrakendus" msgstr "Processing application" #: ../../tarned.rst:52 ../../tarned.rst:120 ../../tarned.rst:203 #: ../../tarned.rst:278 ../../tarned.rst:353 ../../tarned.rst:425 #: ../../tarned.rst:510 ../../tarned.rst:591 ../../tarned.rst:664 #: ../../tarned.rst:738 ../../tarned.rst:816 ../../tarned.rst:896 #: ../../tarned.rst:973 ../../tarned.rst:1056 ../../tarned.rst:1140 #: ../../tarned.rst:1229 ../../tarned.rst:1323 msgid "Auditirakendus" msgstr "Audit application" #: ../../tarned.rst:57 ../../tarned.rst:125 ../../tarned.rst:208 #: ../../tarned.rst:283 ../../tarned.rst:359 ../../tarned.rst:430 #: ../../tarned.rst:516 ../../tarned.rst:596 ../../tarned.rst:669 #: ../../tarned.rst:743 ../../tarned.rst:821 ../../tarned.rst:901 #: ../../tarned.rst:979 ../../tarned.rst:1061 ../../tarned.rst:1145 #: ../../tarned.rst:1234 ../../tarned.rst:1328 msgid "Valijarakendused ja seadistusrakendus" msgstr "Voting applications and configuration app" #: ../../tarned.rst:62 ../../tarned.rst:130 ../../tarned.rst:217 #: ../../tarned.rst:288 ../../tarned.rst:365 ../../tarned.rst:435 #: ../../tarned.rst:528 ../../tarned.rst:601 ../../tarned.rst:675 #: ../../tarned.rst:748 ../../tarned.rst:828 ../../tarned.rst:906 #: ../../tarned.rst:985 ../../tarned.rst:1066 ../../tarned.rst:1157 #: ../../tarned.rst:1245 ../../tarned.rst:1338 msgid "Dokumentatsioon" msgstr "Documentation" #: ../../tarned.rst:64 msgid "Numeratsiooni läbivaatus" msgstr "" #: ../../tarned.rst:65 msgid "Võtmerakenduse seadistuste täpsustamine" msgstr "Clarify the configuration of key app" #: ../../tarned.rst:66 msgid "Smart-ID protokolli näidete täpsustamine" msgstr "Improved SmartID protocol examples" #: ../../tarned.rst:69 ../../tarned.rst:137 ../../tarned.rst:224 #: ../../tarned.rst:293 ../../tarned.rst:371 ../../tarned.rst:441 #: ../../tarned.rst:534 ../../tarned.rst:606 ../../tarned.rst:680 #: ../../tarned.rst:753 ../../tarned.rst:833 ../../tarned.rst:911 #: ../../tarned.rst:992 ../../tarned.rst:1076 ../../tarned.rst:1163 #: ../../tarned.rst:1251 ../../tarned.rst:1342 msgid "Logimonitor" msgstr "Logmonitor" #: ../../tarned.rst:75 msgid "Muudatused tarne 1.10.3 koosseisus, erinevused võrreldes tarnega 1.10.2" msgstr "" "Changes in the composition of the delivery 1.10.3, differences compared " "to delivery 1.10.2." #: ../../tarned.rst:132 ../../tarned.rst:219 msgid "Tõlgete läbivaatus" msgstr "" #: ../../tarned.rst:133 ../../tarned.rst:220 msgid "Õigekirja läbivaatus" msgstr "" #: ../../tarned.rst:134 ../../tarned.rst:221 msgid "Tarne 1.10.2 sisu dokumenteerimine" msgstr "" #: ../../tarned.rst:143 msgid "Muudatused tarne 1.10.2 koosseisus, erinevused võrreldes tarnega 1.10.1" msgstr "" "Changes in the composition of the delivery 1.10.2, differences compared " "to delivery 1.10.1." #: ../../tarned.rst:150 ../../tarned.rst:193 msgid "ZIP/BDOC failide käsitluse parendamine" msgstr "Improve handling of ZIP/BDOC files" #: ../../tarned.rst:151 msgid "Sõltuvuste uuendamine, JavaScript" msgstr "Update dependencies, JavaScript" #: ../../tarned.rst:152 msgid "eID vahendite testimine" msgstr "Test eID tools" #: ../../tarned.rst:153 msgid "Mälulekete parandamine" msgstr "Fix memory leaks" #: ../../tarned.rst:154 msgid "Smart-ID voogude uuendamine vastavalt protokollile" msgstr "Update Smart-ID flows according the protocol" #: ../../tarned.rst:155 msgid "Nimekirjade laadimise intervalli ja strateegia täpsustamine" msgstr "Update the logic and configuration of downloading voterlists" #: ../../tarned.rst:156 msgid "Arendus- ja testkeskkonna parendused" msgstr "Improvements to test and development tools" #: ../../tarned.rst:157 ../../tarned.rst:197 ../../tarned.rst:201 #: ../../tarned.rst:205 msgid "Pisiparandused" msgstr "Minor bug fixes" #: ../../tarned.rst:169 ../../tarned.rst:177 msgid "Rakenduse kolimine Riigikogu Kantselei poodi" msgstr "Move application to Riigikogu Kantselei store" #: ../../tarned.rst:170 msgid "TargetSDK uuendamine" msgstr "Update TargetSDK" #: ../../tarned.rst:171 ../../tarned.rst:178 msgid "Erinevad veaparandused kasutajaliideses" msgstr "Minor UX changes/improvements" #: ../../tarned.rst:172 msgid "Täiendav obfuskeerimine" msgstr "Improved obfuscation" #: ../../tarned.rst:173 ../../tarned.rst:181 msgid "Veateadete täiendamine" msgstr "Improve error messages" #: ../../tarned.rst:179 msgid "Täpsustused rakenduse varundamisele" msgstr "Update backup policy" #: ../../tarned.rst:180 msgid "Rakenduse elutsükli olekumasina täpsustused" msgstr "Improve app lifecycle state machine" #: ../../tarned.rst:210 msgid "Sõltuvuste uuendamine, OpenSSL, PCRE" msgstr "Update dependencies, OpenSSL, PCRE" #: ../../tarned.rst:211 msgid "Kasutajaliidese teegi FLTK uuendamine" msgstr "Update UX library FLTK" #: ../../tarned.rst:212 msgid "Smart-ID voo uuendamine" msgstr "Update of Smart-ID flows" #: ../../tarned.rst:213 msgid "Testimine uusima ID-kaardiga" msgstr "Test with most recent ID-card" #: ../../tarned.rst:214 msgid "Kompileerimiskeskkonna täpsustused" msgstr "Improvements to compilation process" #: ../../tarned.rst:226 msgid "Sõltuvuste uuendamine, Python, JavaScript" msgstr "Update dependencies, Python, JavaScript" #: ../../tarned.rst:227 msgid "Veebiliidese täiendused" msgstr "Updates to web-interface" #: ../../tarned.rst:228 msgid "Päringuvahendaja ``pgbouncer`` kasutuselevõtt" msgstr "Add ``pgbouncer``" #: ../../tarned.rst:229 msgid "Veebiserveri konfiguratsiooni läbivaatus turvatesti tulemustest lähtudes" msgstr "Web-server configuration accordig to security test feedback" #: ../../tarned.rst:233 msgid "Muudatused tarne 1.10.1 koosseisus, erinevused võrreldes tarnega 1.10.0" msgstr "" "Changes in the composition of the delivery 1.10.1, differences compared " "to delivery 1.10.0." #: ../../tarned.rst:240 msgid "Uuenenud SmartID serdiprofiili toetamine" msgstr "Support for updated SmartID certificate profile" #: ../../tarned.rst:252 ../../tarned.rst:256 ../../tarned.rst:322 #: ../../tarned.rst:328 ../../tarned.rst:397 ../../tarned.rst:402 msgid "Täpsustused hääle verifitseerimisel, äärejuhtumite läbivaatus" msgstr "Clarification of vote verification, corner cases" #: ../../tarned.rst:295 ../../tarned.rst:373 ../../tarned.rst:444 msgid "Pisiparandused vastavalt muutuste logile" msgstr "Minor changes/improvements according to `changelog` file" #: ../../tarned.rst:299 msgid "Muudatused tarne 1.10.0 koosseisus, erinevused võrreldes tarnega 1.9.10" msgstr "" "Changes in the composition of delivery 1.10.0, differences compared to " "delivery 1.9.10" #: ../../tarned.rst:306 msgid "Funktsionaalsus kehtetute sedelite eemaldamiseks kogumisteenuses" msgstr "Functionality to remove invalid ballots in the collection service" #: ../../tarned.rst:307 msgid "MODP ja elliptkõverate krüptograafia" msgstr "ModP and ECC cryptography" #: ../../tarned.rst:308 ../../tarned.rst:384 ../../tarned.rst:467 msgid "Erinevad pisiparandused vastavalt muutuste logile" msgstr "Minor changes/improvements according to `changelog` file" #: ../../tarned.rst:320 ../../tarned.rst:326 ../../tarned.rst:333 #: ../../tarned.rst:340 ../../tarned.rst:345 ../../tarned.rst:350 #: ../../tarned.rst:355 ../../tarned.rst:361 msgid "Elliptkõverate krüptograafia" msgstr "Elliptic curves" #: ../../tarned.rst:321 ../../tarned.rst:327 msgid "Ligipääsetavuse parandamine" msgstr "Accessibility improvements" #: ../../tarned.rst:341 ../../tarned.rst:346 ../../tarned.rst:351 #: ../../tarned.rst:356 msgid "Täpsustused urni verifitseerimisel, äärejuhtumite läbivaatus" msgstr "Clarifications of ballot box verification, corner cases" #: ../../tarned.rst:362 msgid "Proksikasutuse refaktoreerimine" msgstr "Refactor proxy usage" #: ../../tarned.rst:367 msgid "Protokollidokumendi täiendamine" msgstr "Improve protocol document" #: ../../tarned.rst:368 msgid "Logide dokumendi loomine" msgstr "Create documentation for log items" #: ../../tarned.rst:377 msgid "Muudatused tarne 1.9.10 koosseisus, erinevused võrreldes tarnega 1.9.4" msgstr "" "Changes in the composition of delivery 1.9.10, differences compared to " "delivery 1.9.4" #: ../../tarned.rst:396 msgid "FLAG_SECURE kasutuselevõtt" msgstr "Use FLAG_SECURE" #: ../../tarned.rst:401 msgid "Ligipääsetavuse parendamine" msgstr "Accessibility improvements" #: ../../tarned.rst:418 msgid "Krüptogrammi kehtetuks kuulutamise äärejuhtumite läbivaatus" msgstr "Corner cases for invalid ballot detection" #: ../../tarned.rst:423 msgid "Hääle kehtetuks kuulutamise äärejuhtumite läbivaatus" msgstr "Corner cases for invalid ballot detection" #: ../../tarned.rst:432 msgid "Windows, ligipääsetavuse veaparandused" msgstr "Improvement of accessibility under Windows" #: ../../tarned.rst:437 ../../tarned.rst:531 msgid "Eesti- ja ingliskeelse dokumentatsiooni ühtlustamine" msgstr "Unifying documentation in Estonian and in English" #: ../../tarned.rst:438 msgid "Arhitektuuridokumendi täiendamine" msgstr "Improve architecture document" #: ../../tarned.rst:443 msgid "Hääletamisfaktide edastamise ebaõnnestumise tuvastamine logist" msgstr "Detect unsucessful delivery of statistics from the logs" #: ../../tarned.rst:448 msgid "Muudatused tarne 1.9.4 koosseisus, erinevused võrreldes tarnega 1.8.2" msgstr "" "Changes in the composition of delivery 1.9.4, differences compared to " "delivery 1.8.2" #: ../../tarned.rst:455 ../../tarned.rst:536 msgid "Ubuntu 22.04 tugi" msgstr "Support for Ubuntu 22.04" #: ../../tarned.rst:456 msgid "Go versiooniuuendus" msgstr "Go version upgrade" #: ../../tarned.rst:457 msgid "etcd versiooniuuendus ja seadistamine" msgstr "etcd version upgrade and configuration" #: ../../tarned.rst:458 msgid "Sõltuvuste ajakohastamine" msgstr "Update of dependencies" #: ../../tarned.rst:459 msgid "Web eID autentimismeetodi lisamine" msgstr "Add Web eID authentication method" #: ../../tarned.rst:460 msgid "Session status mikroteenuse lisamine" msgstr "Adding a session status microservice" #: ../../tarned.rst:461 msgid "EHS statistikaliidese töökindluse tõstmine" msgstr "Improving the reliability of statistics interface" #: ../../tarned.rst:462 msgid "Valimiste järkjärguline lõpp" msgstr "Gradual stop of an event" #: ../../tarned.rst:463 msgid "Seansiidentifikaatori muutmine kohustuslikuks" msgstr "Mandatory SessionID" #: ../../tarned.rst:464 msgid "ASiCe vormingutäpsustus" msgstr "ASiCe format clarifications" #: ../../tarned.rst:465 msgid "VIS tugi detailstatistikale" msgstr "VIS detailed statistics" #: ../../tarned.rst:466 msgid "SmartID toe täpsustused" msgstr "Improved SmartID support" #: ../../tarned.rst:479 ../../tarned.rst:485 ../../tarned.rst:518 msgid "TLS 1.3" msgstr "TLS 1.3" #: ../../tarned.rst:480 msgid "Sertide pinnimisest loobumine" msgstr "Deprecating certificate pinning" #: ../../tarned.rst:481 ../../tarned.rst:486 msgid "Valikute nimekirja kontroll" msgstr "Verification of a choice list" #: ../../tarned.rst:498 msgid "Java 17" msgstr "Java 17" #: ../../tarned.rst:502 msgid "Kehtetute sedelite korrektse dekrüpteerimise tõestamine" msgstr "Proof of correct decryption of invalid ciphertexts" #: ../../tarned.rst:507 ../../tarned.rst:538 msgid "Statistika arvutuste täpsustamine" msgstr "Calculation of statistics" #: ../../tarned.rst:508 msgid "Töötlemisprotseduuride auditeerimise täpsustamine" msgstr "Clarification of auditing tools for processing steps" #: ../../tarned.rst:512 msgid "Kehtetute sedelite korrektse dekrüpteerimise kontrollimine" msgstr "Checking the correct decryption of invalid ciphertexts" #: ../../tarned.rst:513 msgid "Sedelite kontrolli täpsustused" msgstr "" #: ../../tarned.rst:519 msgid "Mitme PKCS11 tokeni tugi" msgstr "Support for multiple PKCS11 tokens" #: ../../tarned.rst:520 msgid "Windowsi serdituvastuse parendamine" msgstr "Improvement of cert handling under Windows" #: ../../tarned.rst:521 msgid "Aegunud sertide tuvastamine" msgstr "Detection of outdated certificates" #: ../../tarned.rst:522 msgid "DLL laadimisvigade parandamine" msgstr "Fix errors in DLL loading" #: ../../tarned.rst:523 msgid "Ligipääsetavus macOS platvormil" msgstr "Accessibility on macOS" #: ../../tarned.rst:524 msgid "Kasutajaliidese muudatused" msgstr "General GUI changes" #: ../../tarned.rst:525 msgid "Kuvatõmmiste automatiseerimine" msgstr "Automated screenshots in configuration app" #: ../../tarned.rst:530 msgid "Web eID autentimismeetodiga seotud dokumentatsiooni lisamine" msgstr "Adding documentation related to the Web eID authentication method" #: ../../tarned.rst:537 msgid "Grafana versiooni uuendamine" msgstr "Grafana version update" #: ../../tarned.rst:542 msgid "Muudatused tarne 1.8.2 koosseisus, erinevused võrreldes tarnega 1.8.1" msgstr "" "Changes in the composition of delivery 1.8.2, differences compared to " "delivery 1.8.1." #: ../../tarned.rst:549 ../../tarned.rst:581 msgid "Valijate nimekirjade vormingu muutus" msgstr "Change the voter list format" #: ../../tarned.rst:550 msgid "EHS/VIS X-tee liidese CI lisandumine" msgstr "Addition of CI to the EHS/VIS X-road interface" #: ../../tarned.rst:551 msgid "EHS/VIS X-tee liidese dokumentatsiooni täpsustumine" msgstr "Specification of EHS/VIS X-Road interface documentation" #: ../../tarned.rst:552 ../../tarned.rst:598 msgid "Väiksemad veaparandused" msgstr "Minor bug fixes" #: ../../tarned.rst:557 ../../tarned.rst:569 ../../tarned.rst:574 #: ../../tarned.rst:585 ../../tarned.rst:593 ../../tarned.rst:608 #: ../../tarned.rst:627 ../../tarned.rst:647 ../../tarned.rst:658 #: ../../tarned.rst:666 ../../tarned.rst:692 ../../tarned.rst:696 #: ../../tarned.rst:700 ../../tarned.rst:705 ../../tarned.rst:712 #: ../../tarned.rst:716 ../../tarned.rst:728 ../../tarned.rst:732 #: ../../tarned.rst:736 ../../tarned.rst:740 ../../tarned.rst:745 #: ../../tarned.rst:755 ../../tarned.rst:781 ../../tarned.rst:810 #: ../../tarned.rst:818 ../../tarned.rst:862 ../../tarned.rst:869 #: ../../tarned.rst:873 ../../tarned.rst:894 ../../tarned.rst:898 #: ../../tarned.rst:940 ../../tarned.rst:951 ../../tarned.rst:1020 #: ../../tarned.rst:1027 ../../tarned.rst:1031 ../../tarned.rst:1036 #: ../../tarned.rst:1043 ../../tarned.rst:1054 ../../tarned.rst:1058 #: ../../tarned.rst:1103 ../../tarned.rst:1116 ../../tarned.rst:1121 #: ../../tarned.rst:1142 ../../tarned.rst:1194 ../../tarned.rst:1220 #: ../../tarned.rst:1231 msgid "Muudatusi ei ole" msgstr "No changes" #: ../../tarned.rst:564 msgid "RSA eemaldamine" msgstr "RSA removal" #: ../../tarned.rst:565 msgid "Veaparandused" msgstr "Bug fixes" #: ../../tarned.rst:589 msgid "Töövoogude konsolideerimine" msgstr "Workflow consolidation" #: ../../tarned.rst:603 msgid "Täpsustused seoses muudatustega tarkvaras" msgstr "Clarifications due to software changes" #: ../../tarned.rst:611 msgid "Muudatused tarne 1.8.1 koosseisus, erinevused võrreldes tarnega 1.7.7" msgstr "" "Changes in the composition of delivery 1.8.1, differences compared to " "delivery 1.7.7" #: ../../tarned.rst:618 msgid "Smart-ID toe lisandumine" msgstr "Addition of Smart-ID support" #: ../../tarned.rst:619 msgid "EHS/VIS X-tee liidese lisandumine" msgstr "Addition of EHS/VIS X-road interface" #: ../../tarned.rst:620 msgid "Hääletamisfaktide järjestamine" msgstr "Ranking of voting facts" #: ../../tarned.rst:621 ../../tarned.rst:636 ../../tarned.rst:642 msgid "Seadistatav SNI" msgstr "Configurable SNI" #: ../../tarned.rst:634 ../../tarned.rst:640 ../../tarned.rst:654 msgid "Smart-ID" msgstr "Smart ID" #: ../../tarned.rst:635 ../../tarned.rst:641 msgid "Täpsustatud krüptogrammi kontroll" msgstr "Clarified ciphertext verification" #: ../../tarned.rst:662 msgid "Töövoogude konsolideerimine, täpsustused parameetrites" msgstr "Consolidation of workflows, refinement of parameters" #: ../../tarned.rst:671 ../../tarned.rst:682 msgid "SmartID" msgstr "SmartID" #: ../../tarned.rst:672 msgid "Uuendatud väljanägemine" msgstr "Updated look" #: ../../tarned.rst:677 msgid "Täpsustused seoses muudatustega tarkvaras - SmartID, jne." msgstr "Clarifications regarding changes in software - SmartID, etc." #: ../../tarned.rst:685 msgid "Muudatused tarne 1.7.7 koosseisus, erinevused võrreldes tarnega 1.7.6" msgstr "" "Changes in the composition of delivery 1.7.7, differences compared to " "delivery 1.7.6" #: ../../tarned.rst:694 ../../tarned.rst:770 ../../tarned.rst:851 #: ../../tarned.rst:929 ../../tarned.rst:1009 ../../tarned.rst:1093 #: ../../tarned.rst:1181 ../../tarned.rst:1265 msgid "Haldusteenus" msgstr "Management service" #: ../../tarned.rst:698 ../../tarned.rst:774 ../../tarned.rst:855 #: ../../tarned.rst:933 ../../tarned.rst:1013 ../../tarned.rst:1097 #: ../../tarned.rst:1186 ../../tarned.rst:1278 msgid "IVXV mikroteenused" msgstr "IVXV microservices" #: ../../tarned.rst:721 msgid "Muudatused seoses entroopia allika valikulise tühjendamisega" msgstr "Changes regarding selective emptying of the entropy source" #: ../../tarned.rst:750 msgid "Muudatused seoses miksneti muutustega" msgstr "Changes due to changes in the mixnet" #: ../../tarned.rst:759 msgid "Muudatused tarne 1.7.6 koosseisus, erinevused võrreldes tarnega 1.6.0" msgstr "" "Changes in the composition of delivery 1.7.6, differences compared to " "delivery 1.6.0." #: ../../tarned.rst:766 msgid "Muudatused seoses sisendnimekirjade haldamisega VIS3's" msgstr "Changes regarding the management of input lists in VIS3" #: ../../tarned.rst:767 ../../tarned.rst:799 msgid "Muudatused seoses Ubuntu 20.04 toetamisega" msgstr "Changes related to Ubuntu 20.04 support" #: ../../tarned.rst:768 ../../tarned.rst:772 ../../tarned.rst:776 #: ../../tarned.rst:849 ../../tarned.rst:853 ../../tarned.rst:857 #: ../../tarned.rst:927 ../../tarned.rst:931 ../../tarned.rst:935 #: ../../tarned.rst:1007 ../../tarned.rst:1011 ../../tarned.rst:1015 #: ../../tarned.rst:1078 ../../tarned.rst:1095 ../../tarned.rst:1099 #: ../../tarned.rst:1168 ../../tarned.rst:1184 ../../tarned.rst:1190 msgid "Väiksemad muutused/veaparandused vastavalt `changelog` failile" msgstr "Minor changes/improvements according to `changelog` file" #: ../../tarned.rst:788 msgid "Muudatused seoses API versioonile 28 liikumisega" msgstr "Changes related to the move to API version 28" #: ../../tarned.rst:789 ../../tarned.rst:794 ../../tarned.rst:825 msgid "Aegunud rakenduse tuvastamine" msgstr "Detection of outdated application" #: ../../tarned.rst:793 msgid "Muudatused seoses iOS versioonile 12 liikumisega" msgstr "Changes related to the move to iOS version 12" #: ../../tarned.rst:806 msgid "Muudatused seoses sisendnimekirjade haldamisega VIS3s" msgstr "Changes to the management of input lists in VIS3" #: ../../tarned.rst:814 msgid "Töötlemise töövoogude optimeerimine" msgstr "Optimising processing workflows" #: ../../tarned.rst:823 msgid "M1 protsessoritüübi toetamine macOS platvormil" msgstr "M1 processor support on macOS platform" #: ../../tarned.rst:824 msgid "FLTK, OpenSSL ja teiste alusteekide versiooniuuendused" msgstr "Updates to FLTK, OpenSSL and other libraries." #: ../../tarned.rst:830 msgid "Muudatused seoses muutustega seadistustes ning terminoloogias" msgstr "Changes due to configuration and terminology changes" #: ../../tarned.rst:835 msgid "Kaasatud tarnesse" msgstr "Included in delivery" #: ../../tarned.rst:841 msgid "Muudatused tarne 1.6.0 koosseisus, erinevused võrreldes tarnega 1.5.0" msgstr "" "Changes in the composition of delivery 1.6.0, differences compared to " "delivery 1.5.0" #: ../../tarned.rst:848 msgid "Mobiil-ID REST teenuse toetamine" msgstr "Support for Mobile-ID REST service" #: ../../tarned.rst:878 ../../tarned.rst:886 msgid "Java versiooni 11 kasutuselevõtt" msgstr "Java version 11 rollout" #: ../../tarned.rst:879 msgid "Verificatumi versiooniuuendus" msgstr "Verificatum upgrade" #: ../../tarned.rst:890 msgid "RSA võtmete serialiseerimise uus vorming" msgstr "New format for RSA key serialisation" #: ../../tarned.rst:903 ../../tarned.rst:908 msgid "Mobiil-ID REST teenuse tugi" msgstr "Mobile-ID REST service support" #: ../../tarned.rst:913 msgid "Eemaldatud tarnest seoses litsentsi lõppemisega" msgstr "Removed from delivery due to expiry of licence" #: ../../tarned.rst:918 msgid "Muudatused tarne 1.5.0 koosseisus, erinevused võrreldes tarnega 1.4.1" msgstr "" "Changes in the composition of delivery 1.5.0, differences compared to " "delivery 1.4.1." #: ../../tarned.rst:925 msgid "Kõigi päringute logimine" msgstr "Logging all requests" #: ../../tarned.rst:926 msgid "etcd Debian buster repositooriumist, uusima golang-google-rpc saamiseks" msgstr "" "etcd from the Debian buster repository, to get the latest golang-google-" "rpc." #: ../../tarned.rst:947 msgid "Muudatused seoses koodiläbivaatuse ja veatöötluse parendamisega" msgstr "Changes to improve code review and error handling" #: ../../tarned.rst:956 msgid "Muudatused seoses 300K hääle miksimisega" msgstr "Changes to the 300K vote mixing process" #: ../../tarned.rst:963 msgid "Valimise identifikaatori kasutamine läbiva prefiksina" msgstr "Use of a election identifier as a prefix" #: ../../tarned.rst:967 msgid "Muudatused seoses koodiläbivaatusega" msgstr "Changes related to code review" #: ../../tarned.rst:971 ../../tarned.rst:976 msgid "Muudatused seoses 300K hääle töötlemisega" msgstr "Changes regarding the processing of 300K votes" #: ../../tarned.rst:975 msgid "Edenemisriba" msgstr "Progressbar" #: ../../tarned.rst:981 ../../tarned.rst:1063 msgid "MSAA toe täpsustamine" msgstr "Specification of MSAA support" #: ../../tarned.rst:982 msgid "Süsteemsete PIN-dialoogide kasutamine Windows platvormil" msgstr "Using system PIN dialogues on the Windows platform" #: ../../tarned.rst:987 msgid "IVXV audiitori juhendi lisamine" msgstr "Addition of IVXV auditor's manual" #: ../../tarned.rst:988 msgid "Muudatusdokumentide lisamine tarnesse" msgstr "Inclusion of change documents in the delivery" #: ../../tarned.rst:994 msgid "Muutused/veaparandused vastavalt `changelog` failile" msgstr "Changes/improvements according to `changelog` file" #: ../../tarned.rst:1000 msgid "Muudatused tarne 1.4.1 koosseisus, erinevused võrreldes tarnega 1.4.0" msgstr "" "Changes in the composition of the delivery 1.4.1, differences compared to" " delivery 1.4.0." #: ../../tarned.rst:1047 msgid "Tööriista *init* väljundfailide muutus" msgstr "Tool *init* change in output files" #: ../../tarned.rst:1048 msgid "Tööriista *init* SN ja CN parameetrite muutus" msgstr "Change in tool *init* SN and CN parameters" #: ../../tarned.rst:1049 msgid "Tööriista *testkey* sisendparameetrite muutus" msgstr "Change in input parameters of *testkey* tool" #: ../../tarned.rst:1050 msgid "Tööriista *decrypt* kasutatud kaardinumbrite kuvamine" msgstr "Displaying the card numbers used by the *decrypt* toolbar" #: ../../tarned.rst:1068 msgid "IVXV protokollid - registreerimisprotokolli lisamine" msgstr "Protocols IVXV - Addition to the record of registrations" #: ../../tarned.rst:1069 msgid "" "IVXV seadistuste koostejuhend - läbivad täiendused ning käsiraamatuga " "ühtlustamine." msgstr "IVXV configuration manual - improvements and alignment with the procedure." #: ../../tarned.rst:1071 msgid "IVXV valijarakendus - läbivad täiendused." msgstr "IVXV voting application - improvements." #: ../../tarned.rst:1072 msgid "IVXV mixnet - dokument hõlmatud seadistuste koostejuhendisse, eemaldatud." msgstr "IVXV mixnet - document included in the configuration manual, removed." #: ../../tarned.rst:1073 msgid "" "IVXV registreerimisteenus - dokument hõlmatud protokollistikku, " "eemaldatud." msgstr "" "IVXV registration service - document included in the protocol document, " "removed." #: ../../tarned.rst:1081 msgid "Muudatused tarne 1.4.0 koosseisus, erinevused võrreldes tarnega 1.3.0" msgstr "" "Changes in the configuration of delivery 1.4.0, differences compared to " "delivery 1.3.0" #: ../../tarned.rst:1088 msgid "" "OCSP ja ajatemplipäringute automaatne kordamine vastavalt " "konfiguratsioonile" msgstr "Automatic repetition of OCSP and timestamp requests as configured" #: ../../tarned.rst:1090 msgid "BDOC-TS allkirjakonteinerite toetamine" msgstr "Support for BDOC-TS signature containers" #: ../../tarned.rst:1091 msgid "Tühjade valijanimekirjade tugi" msgstr "Support for empty voterlists" #: ../../tarned.rst:1110 msgid "TLS 1.2 toetamine API-versioonide < 19 korral" msgstr "TLS 1.2 support for API versions < 19" #: ../../tarned.rst:1111 msgid "Abiinfo vaate asendamine süsteemse brauseriga" msgstr "Replacing the help view with a system browser" #: ../../tarned.rst:1112 msgid "Kuvast väljuvate tekstide automaatne lühendamine nuppude korral" msgstr "Automatic abbreviation of texts in the image when buttons are pressed" #: ../../tarned.rst:1128 msgid "Jaoskonnanumbri unikaalsusnõuete täpsustamine" msgstr "Specifying the uniqueness requirements for the station number" #: ../../tarned.rst:1129 msgid "Tühja valijatenimekirja tugi" msgstr "Support for an empty voterlist" #: ../../tarned.rst:1130 msgid "Kodeeringuvigadega sertifikaatide toetamine rakendustes" msgstr "Support for certificates with coding errors in applications" #: ../../tarned.rst:1134 msgid "Eemaldatud LOG4 ja LOG5" msgstr "Removed LOG4 and LOG5" #: ../../tarned.rst:1138 msgid "Eemaldatud PDF vormingus valijate nimekiri faasist *revoke*" msgstr "Removed PDF voter list from *revoke* phase." #: ../../tarned.rst:1147 msgid "macOS 10.11 toetamine" msgstr "macOS 10.11 support" #: ../../tarned.rst:1148 msgid "32bit Linuxi toetamine" msgstr "32bit Linux support" #: ../../tarned.rst:1149 msgid "UPX versiooni uuendamine" msgstr "Upgrading UPX" #: ../../tarned.rst:1150 msgid "Pinpad kaardilugejate töökindluse tõstmine (Win)" msgstr "Improving the reliability of Pinpad card readers (Win)" #: ../../tarned.rst:1151 msgid "ID-kaardi suhtlusvigade parandamine (Win7/ECC)" msgstr "Fix ID card communication errors (Win7/ECC)" #: ../../tarned.rst:1152 msgid "Nii PEM kui DER vormingus andmete import (Seadistaja)" msgstr "Import data in both PEM and DER format (Configurator)" #: ../../tarned.rst:1153 msgid "Lisatud Seadistuste valideerimisvõimalus (Seadistaja)" msgstr "Added Configuration validation option (Configurator)" #: ../../tarned.rst:1154 msgid "Parandatud käitumine liigsuurte seadistuste korral (Seadistaja)" msgstr "Corrected behaviour in case of excessive settings (Configurator)" #: ../../tarned.rst:1159 msgid "" "Dokumentatsiooni uuendamine muudatuste kajastamiseks ning DEMO2018 " "tagasiside arvestamiseks" msgstr "Updating documentation to reflect changes and feedback from DEMO2018." #: ../../tarned.rst:1165 msgid "MTA sõltuvuse lisamine" msgstr "Adding MTA dependency" #: ../../tarned.rst:1166 msgid "CSV logiväljavõtte täpsustamine, algus- ja lõpuaja lisamine" msgstr "Specifying the CSV log field, adding start and end times" #: ../../tarned.rst:1167 msgid "Logianalüüsi optimeerimine mitmetuumalise riistvara jaoks" msgstr "Optimising log analysis for multi-core hardware" #: ../../tarned.rst:1171 msgid "Muudatused tarne 1.3.0 koosseisus, erinevused võrreldes tarnega 1.2.0" msgstr "" "Changes in the composition of delivery 1.3.0, differences compared to " "delivery 1.2.0" #: ../../tarned.rst:1178 ../../tarned.rst:1253 msgid "Ubuntu 18.04 LTS (Bionic Beaver) kasutuselevõtmine" msgstr "Support for Ubuntu 18.04 LTS (Bionic Beaver)" #: ../../tarned.rst:1179 msgid "Krahhitaaste protseduuride kirjeldamine" msgstr "Description of disaster recovery procedures" #: ../../tarned.rst:1183 msgid "Parandatud tööriistad teenuste seisundiinfo saamiseks" msgstr "Improved tools for getting service status information" #: ../../tarned.rst:1188 msgid "golang keeleversioon 1.9 kasutuselevõtmine" msgstr "golang language version 1.9 rollout" #: ../../tarned.rst:1189 msgid "Eesti ID-kaardi uuenenud profiili toetamine (PNOEE)" msgstr "Supporting the renewed profile of the Estonian ID card (PNOEE)" #: ../../tarned.rst:1201 ../../tarned.rst:1206 msgid "ESTEID2018 sertifikaatide toetamine" msgstr "Support for ESTEID2018 certificates" #: ../../tarned.rst:1202 msgid "Täpsustatud vigase ASN1-kodeeringuga avalike võtmete käitlemist" msgstr "Improved handling of public keys with corrupt ASN1 coding" #: ../../tarned.rst:1207 msgid "iPhone 10 X muudatused" msgstr "iPhone 10 X changes" #: ../../tarned.rst:1208 msgid "XCode 10 ja iOS 12 SDK kasutamine" msgstr "Using XCode 10 and iOS 12 SDK" #: ../../tarned.rst:1213 msgid "Verificatumi AGPL versiooni kasutuselevõtmine" msgstr "Deployment of the AGPL version of Verificatum" #: ../../tarned.rst:1224 msgid "Lisatud tööriist StatsTool valimiskastist statistikafaili genereerimiseks" msgstr "Added tool StatsTool to generate a statistics file from the ballot box." #: ../../tarned.rst:1225 msgid "Lisatud tööriist StatsDiffTool kahe statistikafaili võrdlemiseks" msgstr "Added tool StatsDiffTool to compare two statistics files" #: ../../tarned.rst:1226 ../../tarned.rst:1239 msgid "ESTEID2018 sertifikaatide ja profiili toetamine" msgstr "ESTEID2018 certificates and profile support" #: ../../tarned.rst:1227 msgid "digidoc4j 2.1.0 kasutamine" msgstr "digidoc4j 2.1.0 usage" #: ../../tarned.rst:1236 msgid "Valijarakenduses kandidaatide otsingu võimaldamine" msgstr "Enabling the search for candidates in the voter application" #: ../../tarned.rst:1237 msgid "Valijarakenduses erakondade ja kandidaatide kaustana kuvamine" msgstr "" "Displaying political parties and candidates as a folder in the voter " "application" #: ../../tarned.rst:1238 msgid "" "Valijarakenduse ja Seadistusrakenduse üleviimine JSON-vormingus " "seadistustele" msgstr "Migrating the Voting app and Configuration app to JSON format settings" #: ../../tarned.rst:1240 msgid "Win: IDEMIA minidraiveri toetamine" msgstr "Win: IDEMIA minidriver support" #: ../../tarned.rst:1241 msgid "Linux/macOS: IDEMIA PKCS11 draiveri toetamine" msgstr "Linux/macOS: IDEMIA PKCS11 driver support" #: ../../tarned.rst:1242 msgid "macOS 10.14 toetamine" msgstr "macOS 10.14 support" #: ../../tarned.rst:1247 msgid "Dokumentatsiooni uuendamine muudatuste kajastamiseks" msgstr "Updating documentation to reflect changes" #: ../../tarned.rst:1248 msgid "Ingliskeelse arhitektuuridokumendi ja protokollistiku lisamine" msgstr "Creation of an English-language architecture and protocol document" #: ../../tarned.rst:1254 msgid "Võetud kasutusele Grafana 5.3.4" msgstr "Introduced Grafana 5.3.4" #: ../../tarned.rst:1255 msgid "" "Parandatud vanusepõhise statistika genereerimine ja vanusegruppidesse " "jaotumine" msgstr "Generation of age-specific statistics and age group breakdowns" #: ../../tarned.rst:1257 msgid "CSV väljundi võtmine seanssidest" msgstr "Extracting CSV output from sessions" #: ../../tarned.rst:1260 msgid "" "Muudatused tarne 1.2.0 koosseisus, erinevused võrreldes KOV2017 " "valimistega." msgstr "" "Changes in the composition of the supply 1.2.0, differences compared to " "the KOV2017 elections." #: ../../tarned.rst:1267 msgid "Lisatud tööriist vigaste valijanimekirjade eemaldamiseks." msgstr "Added a tool to remove invalid voterlists." #: ../../tarned.rst:1268 msgid "Lisatud tööriist jaoskondade/ringkondade nimekirja lisamiseks." msgstr "Added a tool to add a list of wards/districts." #: ../../tarned.rst:1269 msgid "Lisatud ringkonnapõhine statistika." msgstr "Statistics by district are included." #: ../../tarned.rst:1270 msgid "Lisatud varundusteenus." msgstr "Added backup service." #: ../../tarned.rst:1271 msgid "Lisatud tööriist varundatud valimiskastide konsolideerimiseks." msgstr "Added tool to consolidate backed up ballot boxes." #: ../../tarned.rst:1272 msgid "Lisatud tööriist nimekirjade kooskõlalisuse kontrolliks." msgstr "Added a tool to check the consistency of lists." #: ../../tarned.rst:1273 msgid "" "Lisatud võimekus seadistusfailidele valimisspetsiifiliste prefiksite " "lisamiseks." msgstr "Added ability to add election specific prefixes to configuration files." #: ../../tarned.rst:1274 msgid "Täiendatud haldusliidese kasutajaliidest abiinfoga." msgstr "Enhanced the administrative interface with help." #: ../../tarned.rst:1275 msgid "Eemaldatud aegunud konfiguratsiooniparameeter “stats.*”" msgstr "Removed obsolete configuration parameter \"stats.*\"" #: ../../tarned.rst:1276 msgid "Parandatud sisendfailide vormingu kontrolli ja laadimist." msgstr "Improved input file format checking and loading." #: ../../tarned.rst:1280 msgid "Uuendatud etcd versioon." msgstr "Updated etcd version." #: ../../tarned.rst:1281 msgid "Lisatud võimekus etcd ajalõppude seadistamiseks keskkonnamuutujate kaudu." msgstr "Added ability to set etcd timeouts via environment variables." #: ../../tarned.rst:1282 msgid "Lisatud võimekus klastri modifitseerimiseks krahhitaaste eesmärgil." msgstr "Added capability to modify cluster for disaster recovery" #: ../../tarned.rst:1283 msgid "" "Parandatud klastri käitumist liidrivahetuse korral, pooleliolevate " "talletamiste kordamine." msgstr "Improved cluster behaviour in the event of a leader-change." #: ../../tarned.rst:1284 msgid "TLS šifrid muudetud seadistatavaks." msgstr "TLS ciphers made configurable." #: ../../tarned.rst:1285 msgid "Parandatud BDOC profiili identifitseeriva konfiguratsioonivälja nimi." msgstr "Name of the configuration field identifying the corrected BDOC profile." #: ../../tarned.rst:1286 msgid "" "Lisatud võimekus seadistada Mobiil-ID autentimist nõudma nii isikukoodi " "kui telefoninumbrit." msgstr "" "Added the ability to configure Mobile ID authentication to require both " "an ID and a phone number." #: ../../tarned.rst:1287 msgid "Lisatud võimekus piirata korduvhääletamise sagedust." msgstr "Added ability to limit the frequency of re-voting." #: ../../tarned.rst:1288 msgid "Lisatud võimekus toetada Windowsi reavahetusi konfifailides." msgstr "Added ability to support Windows line-breaks in configuration files." #: ../../tarned.rst:1289 msgid "Täiustatud BDOC XML kanoniseerimist ja parsimist." msgstr "Improved BDOC XML canonicalisation and parsing." #: ../../tarned.rst:1290 msgid "Karmistatud DDS päringute vormingukontrolle." msgstr "Tightened DDS query formatting controls." #: ../../tarned.rst:1291 msgid "Logimine viidud üle RELP protokollile." msgstr "Logging migrated to RELP protocol." #: ../../tarned.rst:1292 msgid "" "Muudetud seadistusfailide ülesehitust eristamaks Koguja ja Töötleja " "vastutusi." msgstr "" "Changed the structure of configuration files to distinguish between the " "responsibilities of the Collector and the Processor." #: ../../tarned.rst:1296 ../../tarned.rst:1307 ../../tarned.rst:1311 #: ../../tarned.rst:1317 ../../tarned.rst:1321 ../../tarned.rst:1325 msgid "Muudatusi ei ole." msgstr "There are no changes." #: ../../tarned.rst:1303 msgid "" "Lisatud juhised publitseeritud kontrollrakenduse ja avalikustatud " "lähtekoodi vastavuse kontrollimiseks." msgstr "" "Added guidance on how to check the consistency of a published control " "implementation with the published source code." #: ../../tarned.rst:1329 msgid "Linux ja Mac – platvormispetsiifilisi muudatusi ei ole." msgstr "Linux and Mac - There are no platform-specific changes." #: ../../tarned.rst:1330 msgid "" "Windows – parandatud liidestumist Minidraiveriga, mingw64 " "kasutuselevõtmine." msgstr "Windows - improved interfacing with Minidraiver, introducing mingw64." #: ../../tarned.rst:1331 msgid "Lisatud ID-kaardi ECC toetamine." msgstr "Added support for ID card ECC." #: ../../tarned.rst:1332 msgid "Seadistatud Mobiil-ID nõudma vajadusel isikukoodi ja telefoninumbrit." msgstr "Set up Mobile ID to ask for an ID and phone number when needed." #: ../../tarned.rst:1333 msgid "Täiendatud veakoode." msgstr "Updated error codes." #: ../../tarned.rst:1334 msgid "Kohandatud seadistusrakendus muudatustega vastavusse." msgstr "Adjusted the configuration app to reflect the changes." #: ../../tarned.rst:1335 msgid "Kohandatud BDOC XML mallid" msgstr "Customized BDOC XML templates" #: ../../tarned.rst:1339 msgid "Dokumentatsioon läbivalt kaasajastatud seoses muudatustega" msgstr "Documentation updated throughout in the light of the amendments" #: ../../tarned.rst:1343 msgid "Loobutud CrateDBst." msgstr "Rejected CrateDB" #: ../../tarned.rst:1344 msgid "Võetud läbivalt kasutusele PostgreSQL." msgstr "Adopted PostgreSQL." #: ../../tarned.rst:1345 msgid "Võetud kasutusele Grafana 5.0.1." msgstr "Grafana 5.0.1 has been introduced." #: ../../tarned.rst:1346 msgid "Seansside valideerimise parandused lähtudes KOV2017 logianalüüsist." msgstr "" "Improvements to the validation of the sessions based on the KOV2017 log " "analysis." #: ../../tarned.rst:1347 msgid "Lisatud statistika genereerimine ringkondade kaupa." msgstr "Generation of statistics by district." #~ msgid "Muudatused tarne 1.9.1 koosseisus, erinevused võrreldes tarnega 1.9.0" #~ msgstr "" #~ "Changes in the composition of delivery" #~ " 1.9.1, differences compared to delivery" #~ " 1.9.0" #~ msgid "???" #~ msgstr "???" #~ msgid "iOS versioonide täpsustamine" #~ msgstr "Update iOS versions" ================================================ FILE: Documentation/public/uldsisukord/spelling_wordlist.txt ================================================ protocols architecture interfaces API backend beaver bionic bit buster debian digidoc ECC etcd go golang google grafana iOS iPhone log mac macOS messages mingw mixnet pin pinpad python rpc stats ubuntu Win Windowsi XCode ingliskeelsed ================================================ FILE: Documentation/public/uldsisukord/tarned.rst ================================================ .. IVXV dokumentatsiooni üldsisukord Tarned ====== Muudatused tarne 1.10.4 koosseisus, erinevused võrreldes tarnega 1.10.3 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Valijate nimekirjade muudatuste allalaadimise täpsustused Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatused puuduvad Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * Muudatused puuduvad iOS * Muudatused puuduvad Miksnet ~~~~~~~ * Muudatused puuduvad Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Muudatused puuduvad Võtmerakendus * Muudatused puuduvad Töötlemisrakendus * Muudatused puuduvad Auditirakendus * Muudatused puuduvad Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Muudatused puuduvad Dokumentatsioon ~~~~~~~~~~~~~~~ * Numeratsiooni läbivaatus * Võtmerakenduse seadistuste täpsustamine * Smart-ID protokolli näidete täpsustamine Logimonitor ~~~~~~~~~~~ * Muudatused puuduvad Muudatused tarne 1.10.3 koosseisus, erinevused võrreldes tarnega 1.10.2 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Muudatused puuduvad Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatused puuduvad Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * Muudatused puuduvad iOS * Muudatused puuduvad Miksnet ~~~~~~~ * Muudatused puuduvad Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Muudatused puuduvad Võtmerakendus * Muudatused puuduvad Töötlemisrakendus * Muudatused puuduvad Auditirakendus * Muudatused puuduvad Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Muudatused puuduvad Dokumentatsioon ~~~~~~~~~~~~~~~ * Tõlgete läbivaatus * Õigekirja läbivaatus * Tarne 1.10.2 sisu dokumenteerimine Logimonitor ~~~~~~~~~~~ * Muudatused puuduvad Muudatused tarne 1.10.2 koosseisus, erinevused võrreldes tarnega 1.10.1 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * ZIP/BDOC failide käsitluse parendamine * Sõltuvuste uuendamine, JavaScript * eID vahendite testimine * Mälulekete parandamine * Smart-ID voogude uuendamine vastavalt protokollile * Nimekirjade laadimise intervalli ja strateegia täpsustamine * Arendus- ja testkeskkonna parendused * Pisiparandused Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatused puuduvad Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * Rakenduse kolimine Riigikogu Kantselei poodi * TargetSDK uuendamine * Erinevad veaparandused kasutajaliideses * Täiendav obfuskeerimine * Veateadete täiendamine iOS * Rakenduse kolimine Riigikogu Kantselei poodi * Erinevad veaparandused kasutajaliideses * Täpsustused rakenduse varundamisele * Rakenduse elutsükli olekumasina täpsustused * Veateadete täiendamine Miksnet ~~~~~~~ * Muudatused puuduvad Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * ZIP/BDOC failide käsitluse parendamine Võtmerakendus * Pisiparandused Töötlemisrakendus * Pisiparandused Auditirakendus * Pisiparandused Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Sõltuvuste uuendamine, OpenSSL, PCRE * Kasutajaliidese teegi FLTK uuendamine * Smart-ID voo uuendamine * Testimine uusima ID-kaardiga * Kompileerimiskeskkonna täpsustused Dokumentatsioon ~~~~~~~~~~~~~~~ * Tõlgete läbivaatus * Õigekirja läbivaatus * Tarne 1.10.2 sisu dokumenteerimine Logimonitor ~~~~~~~~~~~ * Sõltuvuste uuendamine, Python, JavaScript * Veebiliidese täiendused * Päringuvahendaja ``pgbouncer`` kasutuselevõtt * Veebiserveri konfiguratsiooni läbivaatus turvatesti tulemustest lähtudes Muudatused tarne 1.10.1 koosseisus, erinevused võrreldes tarnega 1.10.0 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Uuenenud SmartID serdiprofiili toetamine Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatused puuduvad Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * Täpsustused hääle verifitseerimisel, äärejuhtumite läbivaatus iOS * Täpsustused hääle verifitseerimisel, äärejuhtumite läbivaatus Miksnet ~~~~~~~ * Muudatused puuduvad Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Muudatused puuduvad Võtmerakendus * Muudatused puuduvad Töötlemisrakendus * Muudatused puuduvad Auditirakendus * Muudatused puuduvad Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Muudatused puuduvad Dokumentatsioon ~~~~~~~~~~~~~~~ * Muudatused puuduvad Logimonitor ~~~~~~~~~~~ * Pisiparandused vastavalt muutuste logile Muudatused tarne 1.10.0 koosseisus, erinevused võrreldes tarnega 1.9.10 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Funktsionaalsus kehtetute sedelite eemaldamiseks kogumisteenuses * MODP ja elliptkõverate krüptograafia * Erinevad pisiparandused vastavalt muutuste logile Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatused puuduvad Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * Elliptkõverate krüptograafia * Ligipääsetavuse parandamine * Täpsustused hääle verifitseerimisel, äärejuhtumite läbivaatus iOS * Elliptkõverate krüptograafia * Ligipääsetavuse parandamine * Täpsustused hääle verifitseerimisel, äärejuhtumite läbivaatus Miksnet ~~~~~~~ * Elliptkõverate krüptograafia Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Elliptkõverate krüptograafia * Täpsustused urni verifitseerimisel, äärejuhtumite läbivaatus Võtmerakendus * Elliptkõverate krüptograafia * Täpsustused urni verifitseerimisel, äärejuhtumite läbivaatus Töötlemisrakendus * Elliptkõverate krüptograafia * Täpsustused urni verifitseerimisel, äärejuhtumite läbivaatus Auditirakendus * Elliptkõverate krüptograafia * Täpsustused urni verifitseerimisel, äärejuhtumite läbivaatus Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Elliptkõverate krüptograafia * Proksikasutuse refaktoreerimine Dokumentatsioon ~~~~~~~~~~~~~~~ * Protokollidokumendi täiendamine * Logide dokumendi loomine Logimonitor ~~~~~~~~~~~ * Pisiparandused vastavalt muutuste logile Muudatused tarne 1.9.10 koosseisus, erinevused võrreldes tarnega 1.9.4 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Erinevad pisiparandused vastavalt muutuste logile Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatused puuduvad Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * FLAG_SECURE kasutuselevõtt * Täpsustused hääle verifitseerimisel, äärejuhtumite läbivaatus iOS * Ligipääsetavuse parendamine * Täpsustused hääle verifitseerimisel, äärejuhtumite läbivaatus Miksnet ~~~~~~~ * Muudatused puuduvad Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Muudatused puuduvad Võtmerakendus * Krüptogrammi kehtetuks kuulutamise äärejuhtumite läbivaatus Töötlemisrakendus * Hääle kehtetuks kuulutamise äärejuhtumite läbivaatus Auditirakendus * Muudatused puuduvad Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Windows, ligipääsetavuse veaparandused Dokumentatsioon ~~~~~~~~~~~~~~~ * Eesti- ja ingliskeelse dokumentatsiooni ühtlustamine * Arhitektuuridokumendi täiendamine Logimonitor ~~~~~~~~~~~ * Hääletamisfaktide edastamise ebaõnnestumise tuvastamine logist * Pisiparandused vastavalt muutuste logile Muudatused tarne 1.9.4 koosseisus, erinevused võrreldes tarnega 1.8.2 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Ubuntu 22.04 tugi * Go versiooniuuendus * etcd versiooniuuendus ja seadistamine * Sõltuvuste ajakohastamine * Web eID autentimismeetodi lisamine * Session status mikroteenuse lisamine * EHS statistikaliidese töökindluse tõstmine * Valimiste järkjärguline lõpp * Seansiidentifikaatori muutmine kohustuslikuks * ASiCe vormingutäpsustus * VIS tugi detailstatistikale * SmartID toe täpsustused * Erinevad pisiparandused vastavalt muutuste logile Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatused puuduvad Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * TLS 1.3 * Sertide pinnimisest loobumine * Valikute nimekirja kontroll iOS * TLS 1.3 * Valikute nimekirja kontroll Miksnet ~~~~~~~ * Muudatused puuduvad Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Java 17 Võtmerakendus * Kehtetute sedelite korrektse dekrüpteerimise tõestamine Töötlemisrakendus * Statistika arvutuste täpsustamine * Töötlemisprotseduuride auditeerimise täpsustamine Auditirakendus * Kehtetute sedelite korrektse dekrüpteerimise kontrollimine * Sedelite kontrolli täpsustused Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * TLS 1.3 * Mitme PKCS11 tokeni tugi * Windowsi serdituvastuse parendamine * Aegunud sertide tuvastamine * DLL laadimisvigade parandamine * Ligipääsetavus macOS platvormil * Kasutajaliidese muudatused * Kuvatõmmiste automatiseerimine Dokumentatsioon ~~~~~~~~~~~~~~~ * Web eID autentimismeetodiga seotud dokumentatsiooni lisamine * Eesti- ja ingliskeelse dokumentatsiooni ühtlustamine Logimonitor ~~~~~~~~~~~ * Ubuntu 22.04 tugi * Grafana versiooni uuendamine * Statistika arvutuste täpsustamine Muudatused tarne 1.8.2 koosseisus, erinevused võrreldes tarnega 1.8.1 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Valijate nimekirjade vormingu muutus * EHS/VIS X-tee liidese CI lisandumine * EHS/VIS X-tee liidese dokumentatsiooni täpsustumine * Väiksemad veaparandused Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatusi ei ole Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * RSA eemaldamine * Veaparandused iOS * Muudatusi ei ole Miksnet ~~~~~~~ * Muudatusi ei ole Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Valijate nimekirjade vormingu muutus Võtmerakendus * Muudatusi ei ole Töötlemisrakendus * Töövoogude konsolideerimine Auditirakendus * Muudatusi ei ole Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Väiksemad veaparandused Dokumentatsioon ~~~~~~~~~~~~~~~ * Täpsustused seoses muudatustega tarkvaras Logimonitor ~~~~~~~~~~~ * Muudatusi ei ole Muudatused tarne 1.8.1 koosseisus, erinevused võrreldes tarnega 1.7.7 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Smart-ID toe lisandumine * EHS/VIS X-tee liidese lisandumine * Hääletamisfaktide järjestamine * Seadistatav SNI Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatusi ei ole Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * Smart-ID * Täpsustatud krüptogrammi kontroll * Seadistatav SNI iOS * Smart-ID * Täpsustatud krüptogrammi kontroll * Seadistatav SNI Miksnet ~~~~~~~ * Muudatusi ei ole Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Smart-ID Võtmerakendus * Muudatusi ei ole Töötlemisrakendus * Töövoogude konsolideerimine, täpsustused parameetrites Auditirakendus * Muudatusi ei ole Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * SmartID * Uuendatud väljanägemine Dokumentatsioon ~~~~~~~~~~~~~~~ * Täpsustused seoses muudatustega tarkvaras - SmartID, jne. Logimonitor ~~~~~~~~~~~ * SmartID Muudatused tarne 1.7.7 koosseisus, erinevused võrreldes tarnega 1.7.6 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Muudatusi ei ole Haldusteenus * Muudatusi ei ole IVXV mikroteenused * Muudatusi ei ole Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatusi ei ole Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * Muudatusi ei ole iOS * Muudatusi ei ole Miksnet ~~~~~~~ * Muudatused seoses entroopia allika valikulise tühjendamisega Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Muudatusi ei ole Võtmerakendus * Muudatusi ei ole Töötlemisrakendus * Muudatusi ei ole Auditirakendus * Muudatusi ei ole Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Muudatusi ei ole Dokumentatsioon ~~~~~~~~~~~~~~~ * Muudatused seoses miksneti muutustega Logimonitor ~~~~~~~~~~~ * Muudatusi ei ole Muudatused tarne 1.7.6 koosseisus, erinevused võrreldes tarnega 1.6.0 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Muudatused seoses sisendnimekirjade haldamisega VIS3's * Muudatused seoses Ubuntu 20.04 toetamisega * Väiksemad muutused/veaparandused vastavalt `changelog` failile Haldusteenus * Väiksemad muutused/veaparandused vastavalt `changelog` failile IVXV mikroteenused * Väiksemad muutused/veaparandused vastavalt `changelog` failile Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatusi ei ole Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * Muudatused seoses API versioonile 28 liikumisega * Aegunud rakenduse tuvastamine iOS * Muudatused seoses iOS versioonile 12 liikumisega * Aegunud rakenduse tuvastamine Miksnet ~~~~~~~ * Muudatused seoses Ubuntu 20.04 toetamisega Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Muudatused seoses sisendnimekirjade haldamisega VIS3s Võtmerakendus * Muudatusi ei ole Töötlemisrakendus * Töötlemise töövoogude optimeerimine Auditirakendus * Muudatusi ei ole Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * M1 protsessoritüübi toetamine macOS platvormil * FLTK, OpenSSL ja teiste alusteekide versiooniuuendused * Aegunud rakenduse tuvastamine Dokumentatsioon ~~~~~~~~~~~~~~~ * Muudatused seoses muutustega seadistustes ning terminoloogias Logimonitor ~~~~~~~~~~~ * Kaasatud tarnesse Muudatused tarne 1.6.0 koosseisus, erinevused võrreldes tarnega 1.5.0 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Mobiil-ID REST teenuse toetamine * Väiksemad muutused/veaparandused vastavalt `changelog` failile Haldusteenus * Väiksemad muutused/veaparandused vastavalt `changelog` failile IVXV mikroteenused * Väiksemad muutused/veaparandused vastavalt `changelog` failile Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatusi ei ole Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * Muudatusi ei ole iOS * Muudatusi ei ole Miksnet ~~~~~~~ * Java versiooni 11 kasutuselevõtt * Verificatumi versiooniuuendus Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Java versiooni 11 kasutuselevõtt Võtmerakendus * RSA võtmete serialiseerimise uus vorming Töötlemisrakendus * Muudatusi ei ole Auditirakendus * Muudatusi ei ole Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Mobiil-ID REST teenuse tugi Dokumentatsioon ~~~~~~~~~~~~~~~ * Mobiil-ID REST teenuse tugi Logimonitor ~~~~~~~~~~~ * Eemaldatud tarnest seoses litsentsi lõppemisega Muudatused tarne 1.5.0 koosseisus, erinevused võrreldes tarnega 1.4.1 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Kõigi päringute logimine * etcd Debian buster repositooriumist, uusima golang-google-rpc saamiseks * Väiksemad muutused/veaparandused vastavalt `changelog` failile Haldusteenus * Väiksemad muutused/veaparandused vastavalt `changelog` failile IVXV mikroteenused * Väiksemad muutused/veaparandused vastavalt `changelog` failile Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatusi ei ole Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * Muudatused seoses koodiläbivaatuse ja veatöötluse parendamisega iOS * Muudatusi ei ole Miksnet ~~~~~~~ * Muudatused seoses 300K hääle miksimisega Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Valimise identifikaatori kasutamine läbiva prefiksina Võtmerakendus * Muudatused seoses koodiläbivaatusega Töötlemisrakendus * Muudatused seoses 300K hääle töötlemisega Auditirakendus * Edenemisriba * Muudatused seoses 300K hääle töötlemisega Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MSAA toe täpsustamine * Süsteemsete PIN-dialoogide kasutamine Windows platvormil Dokumentatsioon ~~~~~~~~~~~~~~~ * IVXV audiitori juhendi lisamine * Muudatusdokumentide lisamine tarnesse Logimonitor ~~~~~~~~~~~ * Muutused/veaparandused vastavalt `changelog` failile Muudatused tarne 1.4.1 koosseisus, erinevused võrreldes tarnega 1.4.0 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Väiksemad muutused/veaparandused vastavalt `changelog` failile Haldusteenus * Väiksemad muutused/veaparandused vastavalt `changelog` failile IVXV mikroteenused * Väiksemad muutused/veaparandused vastavalt `changelog` failile Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatusi ei ole Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * Muudatusi ei ole iOS * Muudatusi ei ole Miksnet ~~~~~~~ * Muudatusi ei ole Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Muudatusi ei ole Võtmerakendus * Tööriista *init* väljundfailide muutus * Tööriista *init* SN ja CN parameetrite muutus * Tööriista *testkey* sisendparameetrite muutus * Tööriista *decrypt* kasutatud kaardinumbrite kuvamine Töötlemisrakendus * Muudatusi ei ole Auditirakendus * Muudatusi ei ole Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * MSAA toe täpsustamine Dokumentatsioon ~~~~~~~~~~~~~~~ * IVXV protokollid - registreerimisprotokolli lisamine * IVXV seadistuste koostejuhend - läbivad täiendused ning käsiraamatuga ühtlustamine. * IVXV valijarakendus - läbivad täiendused. * IVXV mixnet - dokument hõlmatud seadistuste koostejuhendisse, eemaldatud. * IVXV registreerimisteenus - dokument hõlmatud protokollistikku, eemaldatud. Logimonitor ~~~~~~~~~~~ * Väiksemad muutused/veaparandused vastavalt `changelog` failile Muudatused tarne 1.4.0 koosseisus, erinevused võrreldes tarnega 1.3.0 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * OCSP ja ajatemplipäringute automaatne kordamine vastavalt konfiguratsioonile * BDOC-TS allkirjakonteinerite toetamine * Tühjade valijanimekirjade tugi Haldusteenus * Väiksemad muutused/veaparandused vastavalt `changelog` failile IVXV mikroteenused * Väiksemad muutused/veaparandused vastavalt `changelog` failile Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatusi ei ole Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * TLS 1.2 toetamine API-versioonide < 19 korral * Abiinfo vaate asendamine süsteemse brauseriga * Kuvast väljuvate tekstide automaatne lühendamine nuppude korral iOS * Muudatusi ei ole Miksnet ~~~~~~~ * Muudatusi ei ole Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Üldised * Jaoskonnanumbri unikaalsusnõuete täpsustamine * Tühja valijatenimekirja tugi * Kodeeringuvigadega sertifikaatide toetamine rakendustes Võtmerakendus * Eemaldatud LOG4 ja LOG5 Töötlemisrakendus * Eemaldatud PDF vormingus valijate nimekiri faasist *revoke* Auditirakendus * Muudatusi ei ole Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * macOS 10.11 toetamine * 32bit Linuxi toetamine * UPX versiooni uuendamine * Pinpad kaardilugejate töökindluse tõstmine (Win) * ID-kaardi suhtlusvigade parandamine (Win7/ECC) * Nii PEM kui DER vormingus andmete import (Seadistaja) * Lisatud Seadistuste valideerimisvõimalus (Seadistaja) * Parandatud käitumine liigsuurte seadistuste korral (Seadistaja) Dokumentatsioon ~~~~~~~~~~~~~~~ * Dokumentatsiooni uuendamine muudatuste kajastamiseks ning DEMO2018 tagasiside arvestamiseks Logimonitor ~~~~~~~~~~~ * MTA sõltuvuse lisamine * CSV logiväljavõtte täpsustamine, algus- ja lõpuaja lisamine * Logianalüüsi optimeerimine mitmetuumalise riistvara jaoks * Väiksemad muutused/veaparandused vastavalt `changelog` failile Muudatused tarne 1.3.0 koosseisus, erinevused võrreldes tarnega 1.2.0 -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Üldised muutused * Ubuntu 18.04 LTS (Bionic Beaver) kasutuselevõtmine * Krahhitaaste protseduuride kirjeldamine Haldusteenus * Parandatud tööriistad teenuste seisundiinfo saamiseks * Väiksemad muutused/veaparandused vastavalt `changelog` failile IVXV mikroteenused * golang keeleversioon 1.9 kasutuselevõtmine * Eesti ID-kaardi uuenenud profiili toetamine (PNOEE) * Väiksemad muutused/veaparandused vastavalt `changelog` failile Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatusi ei ole Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * ESTEID2018 sertifikaatide toetamine * Täpsustatud vigase ASN1-kodeeringuga avalike võtmete käitlemist iOS * ESTEID2018 sertifikaatide toetamine * iPhone 10 X muudatused * XCode 10 ja iOS 12 SDK kasutamine Miksnet ~~~~~~~ * Verificatumi AGPL versiooni kasutuselevõtmine Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Võtmerakendus * Muudatusi ei ole Töötlemisrakendus * Lisatud tööriist StatsTool valimiskastist statistikafaili genereerimiseks * Lisatud tööriist StatsDiffTool kahe statistikafaili võrdlemiseks * ESTEID2018 sertifikaatide ja profiili toetamine * digidoc4j 2.1.0 kasutamine Auditirakendus * Muudatusi ei ole Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Valijarakenduses kandidaatide otsingu võimaldamine * Valijarakenduses erakondade ja kandidaatide kaustana kuvamine * Valijarakenduse ja Seadistusrakenduse üleviimine JSON-vormingus seadistustele * ESTEID2018 sertifikaatide ja profiili toetamine * Win: IDEMIA minidraiveri toetamine * Linux/macOS: IDEMIA PKCS11 draiveri toetamine * macOS 10.14 toetamine Dokumentatsioon ~~~~~~~~~~~~~~~ * Dokumentatsiooni uuendamine muudatuste kajastamiseks * Ingliskeelse arhitektuuridokumendi ja protokollistiku lisamine Logimonitor ~~~~~~~~~~~ * Ubuntu 18.04 LTS (Bionic Beaver) kasutuselevõtmine * Võetud kasutusele Grafana 5.3.4 * Parandatud vanusepõhise statistika genereerimine ja vanusegruppidesse jaotumine * CSV väljundi võtmine seanssidest Muudatused tarne 1.2.0 koosseisus, erinevused võrreldes KOV2017 valimistega. -------------------------------------------------------------------------------- Kogumisteenus ~~~~~~~~~~~~~ Haldusteenus * Lisatud tööriist vigaste valijanimekirjade eemaldamiseks. * Lisatud tööriist jaoskondade/ringkondade nimekirja lisamiseks. * Lisatud ringkonnapõhine statistika. * Lisatud varundusteenus. * Lisatud tööriist varundatud valimiskastide konsolideerimiseks. * Lisatud tööriist nimekirjade kooskõlalisuse kontrolliks. * Lisatud võimekus seadistusfailidele valimisspetsiifiliste prefiksite lisamiseks. * Täiendatud haldusliidese kasutajaliidest abiinfoga. * Eemaldatud aegunud konfiguratsiooniparameeter “stats.*” * Parandatud sisendfailide vormingu kontrolli ja laadimist. IVXV mikroteenused * Uuendatud etcd versioon. * Lisatud võimekus etcd ajalõppude seadistamiseks keskkonnamuutujate kaudu. * Lisatud võimekus klastri modifitseerimiseks krahhitaaste eesmärgil. * Parandatud klastri käitumist liidrivahetuse korral, pooleliolevate talletamiste kordamine. * TLS šifrid muudetud seadistatavaks. * Parandatud BDOC profiili identifitseeriva konfiguratsioonivälja nimi. * Lisatud võimekus seadistada Mobiil-ID autentimist nõudma nii isikukoodi kui telefoninumbrit. * Lisatud võimekus piirata korduvhääletamise sagedust. * Lisatud võimekus toetada Windowsi reavahetusi konfifailides. * Täiustatud BDOC XML kanoniseerimist ja parsimist. * Karmistatud DDS päringute vormingukontrolle. * Logimine viidud üle RELP protokollile. * Muudetud seadistusfailide ülesehitust eristamaks Koguja ja Töötleja vastutusi. Registreerimisteenus ~~~~~~~~~~~~~~~~~~~~ * Muudatusi ei ole. Kontrollrakendused ~~~~~~~~~~~~~~~~~~ Android * Lisatud juhised publitseeritud kontrollrakenduse ja avalikustatud lähtekoodi vastavuse kontrollimiseks. iOS * Muudatusi ei ole. Miksnet ~~~~~~~ * Muudatusi ei ole. Töötleja rakendused ~~~~~~~~~~~~~~~~~~~ Võtmerakendus * Muudatusi ei ole. Töötlemisrakendus * Muudatusi ei ole. Auditirakendus * Muudatusi ei ole. Valijarakendused ja seadistusrakendus ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Linux ja Mac – platvormispetsiifilisi muudatusi ei ole. * Windows – parandatud liidestumist Minidraiveriga, mingw64 kasutuselevõtmine. * Lisatud ID-kaardi ECC toetamine. * Seadistatud Mobiil-ID nõudma vajadusel isikukoodi ja telefoninumbrit. * Täiendatud veakoode. * Kohandatud seadistusrakendus muudatustega vastavusse. * Kohandatud BDOC XML mallid Dokumentatsioon ~~~~~~~~~~~~~~~ * Dokumentatsioon läbivalt kaasajastatud seoses muudatustega Logimonitor ~~~~~~~~~~~ * Loobutud CrateDBst. * Võetud läbivalt kasutusele PostgreSQL. * Võetud kasutusele Grafana 5.0.1. * Seansside valideerimise parandused lähtudes KOV2017 logianalüüsist. * Lisatud statistika genereerimine ringkondade kaupa. ================================================ FILE: Documentation/spelling_wordlist.txt ================================================ agregeerimise agregeeritakse ajakohastamine andmeaudit andmeauditi anonüümib anonüümimine anonüümitakse anonüümitud arhitektuuridokumendi ATO'd ATO'le audit auditi auditit auditirakendus auditirakenduse auditirakendusega autentimismeetod autentimismeetodi autentimismeetodiga autentimisprotsessi autentimisseansi autentimissertifikaadi autentimissertifikaat autentimissertifikaati autentimisteenuse autentimistõend autentimistõendi autentimisvahendina autentimisvahendite automaatvarunduse Base bitise CSV dekodeerub dekrüpteeruvad DER Digi digiallkirjastatud digiallkirja digiallkirjade dimensioneerida eID eID'ga elliptkõver elliptkõverad elliptkõveraid elliptkõveral elliptkõverate elliptkõveratel eskaleerimiseks haldusutiliitide HEX homomorfset ID ID'ga id'ga identiteedi identiteedile identiteet identiteeti ingliskeelse IP kasutuselevõtmine kasutuselevõtt kodeeringud kodeeringus kodeeringut kodeeringuvigadega konfifailides koodekfiltri kooskõlastatakse krüpteerinud krüptib krüptimise kõrgkäideldav kõrgkäideldava kõrgkäideldavuse käideldavusnõuetele käimasolev käimasoleval käsureautiliidid käsureautiliitide kätluse liidestuma liidestumist liidestuva logiseire lähtestab lähtestamine lähtestatakse mh miksija miksijale miksimine miksimise miksimiseelse miksimisega miksimiseks miksimisele miksimisjärgse miksimisrakendus miksimisrakenduse miksimisrakendusele miksimisrakenduses miksimisrakendusse miksimist miksimistõend miksimistõendi miksimistõendit miksitud miksnet miksneti miksnetist minidraiveriga mitmelõimelist ModP monitoorida monitoorimine monitooring monitooringu monitooringulahendus monitooringule monitooritavas navigeerida nonsiks nonsina nonss nonsi nonssi notatsioon notatsioonis nö obfuskeerimine olemasolev olemasolu organisatsioonilis osak osakud parametriseerimise parametriseeritavad parendused permuteerib poll privaatvõti privaatvõtit privaatvõtme privaatvõtmed programselt protokollistikku pseudojuhuslik pseudokoodina pseudokrüptogramm puhverdatavat QR refaktoreerimine responderi riigiti road RPC räsiga räsil räsile seadistusutiliidid seire seirelahendus seirelahenduse seirelahendusest seirele seireprogramm seireprogrammi seiresse seiret seiretarkvara seireteenuse seireteenusest serdid serdiprofiili serdituvastuse serialiseerimise sertide service skaleerida skaleerimiseks skaleeritavuse skaleerub smart spetsifikatsioon spetsifikatsiooni standartne teadaoleva teadaolevaid teadaolevate teadasaamiseks teavitussüsteem teavituste teenushoste teenushosti teenushostide teenushostidesse tegevusmonitooringu tähelepanu TLS unikaalsusnõuete utiliidi utiliidid utiliidiga utiliit UML URL vallasrežiimis vallasrežiimirakendustest varundab varundama varundamine varundamise varundamisele varundamiseks varundamist varundatakse varundatavad varundati varundatud varundus varunduse varundusliidese varundusprotseduuride varundusserver varundusserveri varundusserveris varundusserverisse varundusserveritesse varundusteenus varundusteenuse varundusteenuses varundusteenusele varundusteenusesse varundusteenusest varundusteenust veebisirviku Verificatum Verificatumi verifitseerib verifitseerida verifitseerimine verifitseerimise verifitseerimiseks verifitseerimisel verifitseerimisest verifitseerimiskoodi verifitseerimist verifitseerimisteenus verifitseerimisteenusega verifitseeritakse verifitseeritav verifitseeritavuse verifitseerivad verifitseerub virtualiseerimistehnoloogiate visualiseerimistarkvaraga võtmeosakud võtmeosakut ülaosas web X xroad zip ================================================ FILE: LICENSE ================================================ Copyright: Vabariigi Valimisteenistus (Estonian State Electoral Office), www.valimised.ee Created in 2016-2025 by Cybernetica AS, www.cyber.ee This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/. ================================================ FILE: Makefile ================================================ JAVADIRS := common/java key processor auditor GODIRS := common/collector sessionstatus/api proxy mid smartid choices voting verification storage votesorder webeid sessionstatus OTHERDIRS := systemd Documentation TESTDIRS := $(patsubst %,test-%,$(JAVADIRS) $(GODIRS)) INSTALLDIRS := $(patsubst %,install-%,$(JAVADIRS) $(GODIRS) systemd) CLEANDIRS := $(patsubst %,clean-%,$(JAVADIRS) $(GODIRS) $(OTHERDIRS)) export ROOT_BUILD=true # Needed to include newlines in $(forach) loops. Must contain two empty lines. define NEWLINE endef .PHONY: help help: @echo "usage: make all Build all components" @echo " make test Run unit tests for all components" @echo " make install Install all collector components to \$$DESTDIR" @echo " make install-java Install all application components to \$$DESTDIR" @echo " make clean Clean the repository" @echo @echo " make Build the component (listed below)" @echo " make test- Run unit tests for the component" @echo " make install- Install the component to \$$DESTDIR" @echo " make clean- Clean the component" @echo @echo " make external Checkout common/external to the expected version" @echo " make update-external Checkout common/external to the latest version" @echo " make version Update version numbers in all known locations to" @echo " the last entry in debian/changelog" @echo @echo "Components:" $(foreach component,$(filter-out $(JAVADIRS) $(GODIRS),$(OTHERDIRS)),@echo " $(component)"$(NEWLINE)) @echo @echo " java (meta-component which includes all of the following)" $(foreach component,$(JAVADIRS),@echo " $(component)"$(NEWLINE)) @echo @echo " go (meta-component which includes all of the following)" $(foreach component,$(GODIRS),@echo " $(component)"$(NEWLINE)) @echo @echo "All rules can be suffixed with \"-dev\" to call them in development mode instead," @echo "e.g., make all-dev." @echo @echo "Read README.rst in both the repository root and specific component directories" @echo "for more details." .PHONY: all all: $(JAVADIRS) $(GODIRS) $(OTHERDIRS) .PHONY: java java: $(JAVADIRS) .PHONY: go go: $(GODIRS) .PHONY: $(GODIRS) $(GODIRS): --gotools $(MAKE) -C $@ goimports $(MAKE) -C $@ ONLINE=$(ONLINE) $(MAKE) -C $@ .PHONY: $(JAVADIRS) $(JAVADIRS): $(MAKE) -C $@ .PHONY: $(OTHERDIRS) $(OTHERDIRS): $(MAKE) -C $@ .PHONY: test test: $(TESTDIRS) .PHONY: test-java test-java: $(JAVADIRS:%=test-%) .PHONY: test-go test-go: $(GODIRS:%=test-%) .PHONY: test-python test-python: $(MAKE) -C tests unit-tests .PHONY: $(TESTDIRS) $(TESTDIRS): test-%: $(MAKE) -C $* test # Only install Go services and systemd unit files by default. .PHONY: install install: $(patsubst %,install-%,$(GODIRS) systemd) .PHONY: install-java install-java: $(JAVADIRS:%=install-%) .PHONY: $(INSTALLDIRS) $(INSTALLDIRS): install-%: $(MAKE) -C $* install .PHONY: clean clean: $(CLEANDIRS) $(MAKE) -C tests $@ $(MAKE) -C release $@ rm -rf build dist common/tools/go/bin .PHONY: clean-java clean-java: $(JAVADIRS:%=clean-%) .PHONY: release-doc release-doc: go $(MAKE) -C Documentation/common/schema validate $(MAKE) -C Documentation release .PHONY: clean-go clean-go: $(GODIRS:%=clean-%) .PHONY: $(CLEANDIRS) $(CLEANDIRS): clean-%: $(MAKE) -C $* clean .PHONY: external external: git submodule update --init .PHONY: update-external update-external: git submodule update --init --remote .PHONY: version version: python3 common/tools/update_project_version.py # We cannot mark this target as phony without listing all possible targets. %-dev: $(MAKE) $* DEVELOPMENT=1 # Target prefixed with "--" are not seen to the call `make [target]` .PHONY: --gotools --gotools: $(MAKE) -C common/collector gotools ================================================ FILE: README.md ================================================ IVXV online voting system ========================= The intention behind this repository is to make source code of the Estonian online voting system available for public review. The repository is not used for active development, but will be kept up to date, so the code that can be found here is the code that is used for election. As the voting system used for legally binding elections must strictly follow the legislation, the actual development of Estonian I-voting system and I-vote verification application is supervised by State Electoral Office of Estonia. Please refer to www.valimised.ee for further information. ================================================ FILE: README.rst ================================================ ============================== IVXV Internet voting framework ============================== ---------- Building ---------- Building the collector components requires Go 1.9 and the management applications require Java 11:: sudo apt-get install --no-install-recommends openjdk-11-jdk-headless golang-1.9-go The submodule for external dependencies uses Git LFS. This must be locally supported so make sure that it is installed:: sudo apt-get install --no-install-recommends git-lfs Next, external dependencies need to be acquired. If working off of an offline copy of the IVXV repository, then they are already included and this step can be skipped. Otherwise run :: make external to download the external dependecy repository. Finally, to build, test, and clean the entire codebase, just do :: make all make test make clean Individual components can be built, tested, and cleaned with :: make make test- make clean- where ```` is the name name of the components subdirectory. All components are built in release mode by default. To build in development mode, which enables dummy modules and other components not safe for release, the make variable ``DEVELOPMENT`` must be set either on the command line or in the environment. Every target of the root Makefile can be called with a ``-dev`` suffix, which sets this variable during the make. Debian packages can be built using ``dpkg-buildpackage`` (or ``debuild`` if preferred) as usual. ------------- Development ------------- Updating external dependencies ------------------------------ During development, if changes are pushed to the external dependencies repository, then the reference needs to be updated in this repository to link those changes to the current revision. This is done with :: make update-external git add common/external git commit git push After the reference update has been pulled by other developers, they will get an entry in their ``git status`` output, indicating that external has changed:: modified: common/external (new commits) To fetch the changes to their local working tree, developers need to rerun :: make external Setting GOPATH -------------- The IVXV project uses multiple GOPATH directories, one for each Go component. During ``make`` commands, the GOPATH will be automatically set, but if a developer (or their IDE) wishes to run some manual Go commands, then this can be tedious to specify. To help with this :: make gopath will print out the GOPATH used by the build system. So for example, when using Bash, :: export GOPATH="$(make gopath)" will set the correct GOPATH in the current shell. ---------- Releasing ---------- Release builds are made using test system. To make release build: * run ``dch --release`` to finalize the changelog for a release * run ``make release`` *Note!* This creates a new virtual environment for building the release, so if you have installed a custom binaries or libraries to the local machine (e.g., the patched Go standard library from ivxv-golang), then those will not be used. In this case, build the Debian packages manually. ================================================ FILE: auditor/.gitignore ================================================ .classpath .gradle/ .idea/ .project build/ /log/ /bin/ .settings/ ================================================ FILE: auditor/Makefile ================================================ include ../common/java/common.mk ================================================ FILE: auditor/README.rst ================================================ ================================ IVXV Internet voting framework ================================ --------------------- Auditor application --------------------- The auditor application is an application for verifying the correctness of operations of other tools. The application functionality is provided by the tools described below: * *convert* - tool for verifying that the proof of shuffle provided by Verificatum corresponds to the anonymized ballot boxes. The input ballot box is the anonymized ballot box output by the processor tool and the output ballot box is the anonymized ballot box output by the Verificatum prover application. The provided public key must be output by key generation tool. * *mixer* - tool for verifying the correctness of a proof of shuffle. The tool takes as input the protocol information file provided to Verificatum during shuffle and the proof directory output by it. * *decrypt* - tool for verifying the correctness of decryption. The tool uses public key and the proof of correct decryption output by the decryption tool. The tool also verifies whether the tally has been computed correctly and whether the files resulting from the decryption are consistent with one another. It outputs ciphertexts for which verification of the decryption proof failed. * *integrity* - tool for verifying the logs of the processing application. The tool uses the logs output by the processing application as well as the original and anonymised ballot boxes to verify the audit trail of the logs. Building -------- IVXV java applications have 2 levels of build systems: * *make* - the build system facade. Must be installed on the user's machine. * *gradle* - the implementation of the build system. Gradle is located under ``common/external/gradle-8.11``, with the executable ``bin/gradle(.bat)``. Building: * ``make`` or * ``make all`` or * ``gradle build installDist`` - build and test the application. * ``make clean`` or * ``gradle clean`` - clean build resources, i.e. the directory ``build``. Application executable is ``build/install/auditor/bin/auditor(.bat)``. Distributable application packages are provided under ``build/distributions/``. Sample executions ----------------- As the command-line arguments have to be defined precisely for correct operation, we strongly recommend using a parameters file. Refer to the configuration preparation documentation for the example configurations. * Verify the correctness of file format conversion:: auditor convert --conf app-conf.bdoc --params auditor-app-conf.bdoc * Verify the correcntess of the shuffle:: auditor mixer --conf app-conf.bdoc --params auditor-app-conf.bdoc * Verify the correctness of decryption:: auditor decrypt --conf app-conf.bdoc --params auditor-app-conf.bdoc * Verify the integrity of processing logs:: auditor integrity --conf app-conf.bdoc --params auditor-app-conf.bdoc Sample configuration -------------------- .. code-block:: yaml convert: input_bb: bb-4.json output_bb: bb-5.json pub: initout/pub.pem protinfo: mixnet/ProtocolInformation.xml proofdir: mixnet/ mixer: protinfo: mixnet/ProtocolInformation.xml proofdir: mixnet/ threaded: true decrypt: proofs: decout/proof pub: initout/pub.pem discarded: decout/invalid anon_bb: bb-4.json plain_bb: decout/TESTQUESTION.plain tally: decout/TESTQUESTION.tally candidates: choices.bdoc districts: districts.bdoc out: auditout/ invalidity_proofs: decout/proof-invalid integrity: ballotbox: votes.zip anon_bb: bb-4.json log_accepted: out-1/TESTQUESTION.check.log1 log_squashed: out-2/TESTQUESTION.squash.log2 log_revoked: out-3/TESTQUESTION.revoke.log2 log_anonymised: out-4/TESTQUESTION.anonymize.log3 bb_errors: out-1/ballotbox_errors.txt ================================================ FILE: auditor/build.gradle ================================================ buildscript { ext.base = '../' apply from: "${base}/common/java/common-buildscript.gradle", to: buildscript } apply from: "${base}/common/java/common-build.gradle" apply plugin: 'application' dependencies { implementation project(":common") testImplementation testFixtures(project(":common")) } application { mainClass = "ee.ivxv.audit.Audit" applicationDefaultJvmArgs = ["-Xmx8G"] } ================================================ FILE: auditor/settings.gradle ================================================ include "common" project(":common").projectDir = file("../common/java") ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/Audit.java ================================================ package ee.ivxv.audit; import ee.ivxv.common.cli.AppRunner; public class Audit { public static void main(String[] args) { AuditApp app = new AuditApp(); AppRunner runner = new AppRunner<>(app); if (!runner.run(args)) { System.exit(1); } } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/AuditApp.java ================================================ package ee.ivxv.audit; import ee.ivxv.audit.tools.ConvertTool; import ee.ivxv.audit.tools.ConvertTool.ConvertArgs; import ee.ivxv.audit.tools.DecryptTool; import ee.ivxv.audit.tools.DecryptTool.DecryptArgs; import ee.ivxv.audit.tools.IntegrityTool; import ee.ivxv.audit.tools.IntegrityTool.IntegrityArgs; import ee.ivxv.audit.tools.MixerTool; import ee.ivxv.audit.tools.MixerTool.MixerArgs; import ee.ivxv.common.cli.App; import ee.ivxv.common.cli.CommonArgs; import ee.ivxv.common.cli.InitialContext; import ee.ivxv.common.cli.Tool; import ee.ivxv.common.conf.Conf; import java.util.Arrays; import java.util.List; class AuditApp extends App { AuditApp() { super(Msg.app_audit, createTools()); } private static List> createTools() { return Arrays.asList( // new Tool<>(Msg.tool_convert, ConvertArgs::new, ConvertTool::new), new Tool<>(Msg.tool_mixer, MixerArgs::new, MixerTool::new), new Tool<>(Msg.tool_decrypt, DecryptArgs::new, DecryptTool::new), new Tool<>(Msg.tool_integrity, IntegrityArgs::new, IntegrityTool::new)); } @Override public AuditContext createContext(InitialContext ctx, Conf conf, CommonArgs args) { return new AuditContext(ctx, conf, args); } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/AuditContext.java ================================================ package ee.ivxv.audit; import ee.ivxv.common.cli.AppContext; import ee.ivxv.common.cli.CommonArgs; import ee.ivxv.common.cli.InitialContext; import ee.ivxv.common.conf.Conf; public class AuditContext extends AppContext { public AuditContext(InitialContext i, Conf conf, CommonArgs args) { super(i, conf, args); } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/Msg.java ================================================ package ee.ivxv.audit; import ch.qos.cal10n.BaseName; import ch.qos.cal10n.LocaleData; import ee.ivxv.common.util.NameHolder; @BaseName("i18n.audit-msg") @LocaleData(defaultCharset = "UTF-8", value = {}) public enum Msg implements NameHolder { /*- * The part of the enum name until the first '_' (including) is excluded from the getName(). * This is a means to provide multiple translations for the same tool or argument name. */ // App app_audit, // Error messages e_proof_verif_false, e_proof_verif_exception, e_file_missing, // Tools tool_decrypt, tool_mixer, tool_convert, tool_integrity, // Tool arguments arg_abort_early, // arg_proofs, arg_invalidity_proofs, arg_discarded, // arg_hash, arg_links("l"), arg_out("o"), arg_pbb("p"), arg_pub("p"), // arg_revoke("r"), arg_seed("s"), arg_storage("s"), arg_signaturepub, arg_threads("t"), // arg_input_bb, arg_output_bb, arg_protinfo, arg_proofdir, arg_threaded, // arg_ballotbox, arg_ballotbox_checksum, arg_anon_bb, arg_plain_bb, // arg_log_accepted, arg_log_squashed, arg_log_revoked, arg_log_anonymised, arg_bb_errors, // arg_tally, arg_candidates, arg_districts, arg_questioncount, // // Messages m_yes, m_no, // m_pub_loading, m_pub_loaded, m_failurecount, m_verify_start, m_verify_finish, // m_decrypt_bb_has_proofs, m_decrypt_bb_has_invalids, m_decrypt_one_per_file, // m_decrypt_verified_valid, m_decrypt_verified_invalid, // m_decrypt_consistent_valids_begin, // m_decrypt_consistent_valids, m_decrypt_consistent_invalids, m_decrypt_dec_consistent, // m_decrypt_success, m_decrypt_failure, // m_shuffle_proof_loading, m_shuffle_proof_failed_reason, m_shuffle_proof_succeeded, // m_shuffle_proof_failed, m_convert_publickey_failed, m_convert_publickey_succ, // m_convert_bb_to_bt_failed, m_convert_bb_to_bt_succ, m_convert_bt_to_bb_failed, // m_convert_bt_to_bb_succ, m_shuffle_step, m_shuffle_read, m_shuffle_read_prot_info, // m_shuffle_read_pubkey, m_shuffle_read_pc, m_shuffle_read_posc, m_shuffle_read_posr, // m_shuffle_read_ciphs, m_shuffle_read_shuffled, // m_shuffle_verify, m_shuffle_verify_params, m_shuffle_verify_ni, m_shuffle_verify_permutation, // m_shuffle_verify_rerandomisation, // m_plain_loading, m_plain_loaded, m_plain_count, // m_tally_loading, m_tally_loaded, m_tally_match, // m_discarded_loading, m_discarded_loaded, m_discarded_count, // m_bb_loading, m_bb_loaded, m_anon_loading, m_anon_loaded, // m_log_accepted, m_log_squashed, m_log_revoked, m_log_anonymised, m_bb_errors, // m_integrity_match_anon, m_integrity_match_anon_logs, // m_integrity_match_valid, m_integrity_match_logs, // m_integrity_bb_consistent, m_integrity_bb_inconsistent, m_integrity_recurring_ct, // m_tally_start, m_tally_done, m_out_tally, m_tally_read, // e_abb_invalid_question_count, // ; private final String shortName; Msg() { this(null); } Msg(String shortName) { this.shortName = shortName; } @Override public String getShortName() { return shortName; } @Override public String getName() { return extractName(name()); } @Override public Enum getKey() { return this; } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/model/PlainBallotBox.java ================================================ package ee.ivxv.audit.model; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.Map; import java.util.List; /** * JSON serializable structure for holding the decrypted ballot box. */ public record PlainBallotBox(String election, Map>> byParish, Map> byDistrict) { @JsonCreator public PlainBallotBox(@JsonProperty("election") String election, @JsonProperty("byparish") Map>> byParish, @JsonProperty("bydistrict") Map> byDistrict) { this.election = election; this.byParish = byParish; this.byDistrict = byDistrict; } public Map> computeByDistrict() { Map> res = new LinkedHashMap<>(); byParish().forEach((d, sMap) -> { List pList = res.computeIfAbsent(d, tmp -> new ArrayList<>()); sMap.forEach((s, plains) -> pList.addAll(plains)); }); return res; } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/model/Tally.java ================================================ package ee.ivxv.audit.model; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import ee.ivxv.common.model.CandidateList; import ee.ivxv.common.model.DistrictList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; /** * JSON serializable structure for holding the tally of the votes. */ public class Tally { public static final String INVALID_VOTE_ID = "invalid"; private final String election; private final Map>> byParish; private final Map> byDistrict; @JsonCreator Tally(@JsonProperty("election") String election, @JsonProperty("byparish") Map>> byParish, @JsonProperty("bydistrict") Map> byDistrict) { this.election = election; this.byParish = byParish; this.byDistrict = byDistrict; } /** * Get the election identifier. * * @return */ public String getElection() { return election; } /** * @return Returns a map from district id to a map from station id to a map from candidate id to * number of received votes. */ public Map>> getByParish() { return byParish; } /** * @return Returns a map from district id to a map from candidate id to number of received * votes. */ public Map> getByDistrict() { return byDistrict; } public Map> computeByDistrict() { Map> res = new LinkedHashMap<>(); getByParish().forEach((d, sMap) -> { Map ccMap = res.computeIfAbsent(d, tmp -> new LinkedHashMap<>()); sMap.forEach((s, cMap) -> cMap.forEach((c, count) -> { ccMap.compute(c, (cc, ccount) -> ccount == null ? count : ccount + count); })); }); return res; } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/shuffle/ByteTree.java ================================================ package ee.ivxv.audit.shuffle; import ee.ivxv.common.math.*; import ee.ivxv.common.util.Util; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.file.Path; import java.util.HexFormat; import java.util.Objects; import org.bouncycastle.math.ec.ECFieldElement; import org.bouncycastle.util.Arrays; /** * ByteTree decodes the ByteTree (BT) format as defined in Verificatum user manual. */ public class ByteTree { public int getLength() { return 0; } public int getEncodedLength() { return 0; } public byte[] getEncoded() { return null; } public void writeEncoded(OutputStream out) throws IOException { // Overridden } public boolean isLeaf() { return false; } public String getPrefix() { return ""; } public String toString(int indent) { return ""; } @Override public String toString() { return toString(0); } /** * Node is a recursive object in a ByteTree which consists of an array of nodes and leafs. */ public static class Node extends ByteTree { private final ByteTree[] nodes; public static final byte PREFIX = 0; /** * Initialize Node from an array of ByteTree objects. * * @param nodes Array of ByteTree objects. */ public Node(ByteTree[] nodes) { this.nodes = nodes; } /** * Initialize Node from an array of BigInteger objects. * * @param ints Array of BigInteger objects */ public Node(BigInteger[] ints) { nodes = new Leaf[ints.length]; for (int i = 0; i < nodes.length; i++) { nodes[i] = new Leaf(ints[i]); } } /** * Initialize Node from an array of GroupElements. * * @param elements Array of GroupElements */ public Node(GroupElement[] elements) { nodes = new ByteTree[elements.length]; for (int i = 0; i < nodes.length; i++) { if (elements[i] instanceof ProductGroupElement) { nodes[i] = new Node((ProductGroupElement) elements[i]); } else if (elements[i] instanceof ECGroupElement) { nodes[i] = new Node((ECGroupElement) elements[i]); } else if (elements[i] instanceof ModPGroupElement) { nodes[i] = new Leaf(elements[i]); } else { throw new IllegalArgumentException("Unknown element type: " + elements[i].getClass().getSimpleName()); } } } /** * Initialize Node from ProductGroupElement. * * @param element A ProductGroupElement element */ public Node(ProductGroupElement element) { nodes = new ByteTree[element.getElements().length]; for (int i = 0; i < nodes.length; i++) { GroupElement ge = element.getElements()[i]; if (ge instanceof ProductGroupElement) { nodes[i] = new Node((ProductGroupElement) ge); } else if (ge instanceof ECGroupElement) { nodes[i] = new Node((ECGroupElement) ge); } else if (ge instanceof ModPGroupElement) { nodes[i] = new Leaf(ge); } else { throw new IllegalArgumentException("Unknown element type: " + ge.getClass().getSimpleName()); } } } /** * Initialize Node from ECGroupElement. * * @param ec {@link ee.ivxv.common.math.ECGroupElement} instance */ public Node(ECGroupElement ec) { // Size is two, because coordinate point (X,Y) == (BigInteger, BigInteger) nodes = new Leaf[2]; ECFieldElement x = ec.getPoint().getXCoord(); ECFieldElement y = ec.getPoint().getYCoord(); int fieldSizeBytes = ec.getPoint().getCurve().getFieldSize(); nodes[0] = new Leaf(ecFieldElementToLeaf(fieldSizeBytes, x)); nodes[1] = new Leaf(ecFieldElementToLeaf(fieldSizeBytes, y)); } /** * Return the array of ByteTree objects. * * @return Array of ByteTree objects. */ public ByteTree[] getNodes() { return nodes; } /** * Get the number of elements in the ByteTree array. * * @return Length of array. */ @Override public int getLength() { return nodes.length; } /** * Get the byte-length of the Node. * * @return Byte-length of the Node. */ @Override public int getEncodedLength() { int sum = 5; for (ByteTree n : nodes) { sum += n.getEncodedLength(); } return sum; } /** * Encode the Node as bytes. * * @return Node encoded as bytes */ @Override public byte[] getEncoded() { byte[] ret = new byte[getEncodedLength()]; ret[0] = PREFIX; System.arraycopy(ByteTree.parse_from_int(getLength()), 0, ret, 1, 4); int pt = 5; for (int i = 0; i < getLength(); i++) { byte[] enc = getNodes()[i].getEncoded(); System.arraycopy(enc, 0, ret, pt, enc.length); pt += enc.length; } return ret; } /** * Encode the Node and write it to out. * * @param out Stream to write the ByteTree description of the Node. * @throws IOException When writing to out fails */ @Override public void writeEncoded(OutputStream out) throws IOException { out.write(PREFIX); out.write(ByteTree.parse_from_int(getLength())); for (int i = 0; i < getLength(); i++) { getNodes()[i].writeEncoded(out); } } /** * @return false */ @Override public boolean isLeaf() { return false; } /** * Parse an array of bytes into a node, starting at offset. * * @param b Array of bytes to be parsed. * @param offset The offset in the array to start parsing * @return A decoded Node instance. */ public static Node parse(byte[] b, int offset) { int len = parse_int_fullbytes(b, offset); ByteTree[] bts = new ByteTree[len]; int pt = 0; for (int i = 0; i < len; i++) { bts[i] = ByteTree.parse(b, offset + pt + 5); pt += bts[i].getEncodedLength(); } Node n = new Node(bts); return n; } /** * Parse a DataInputStream into a node. * * The given DataInputStream must be pointed to the beginning of a valid Node element. * * @param is DataInputStream to be used for reading a node, seeked to the beginning of Node * definition. * @return A decoded Node instance. * @throws IOException When reading from the stream fails. */ public static Node parse(DataInputStream is) throws IOException { int len = read_length(is); ByteTree[] bts = new ByteTree[len]; for (int i = 0; i < len; i++) { bts[i] = ByteTree.parse(is); } Node n = new Node(bts); return n; } /** * @return "NODE". */ @Override public String getPrefix() { return "NODE"; } /** * Human-friendly representation of the Node object, with starting indentation. * * @param indent The indentation level * @return String representation of instance */ @Override public String toString(int indent) { String spaces = new String(new char[indent]).replace("\0", " "); String header = String.format("%s%s %d", spaces, getPrefix(), getLength()); String[] subs = new String[getLength() + 1]; subs[0] = header; for (int i = 0; i < getLength(); i++) { subs[i + 1] = nodes[i].toString(indent + 1); } return String.join("\n", subs); } /** * Convert ECFieldElement to Leaf. * Mixnet Verificatum reference: * innerToByteArray * * @param fieldSize EC field size * @param ec EC field element * @return EC field element as Leaf */ private byte[] ecFieldElementToLeaf(final int fieldSize, final ECFieldElement ec) { // https://github.com/verificatum/verificatum-vcr/blob/97974cfc4ebbb323e49396222823e226cae2bebe/src/java/com/verificatum/arithm/ECqPGroupElement.magic#L538 int fieldSizeBytesPlusOne = MathUtil.toBytesLen(fieldSize) + 1; final byte[] leaf = new byte[fieldSizeBytesPlusOne]; // null means infinity point if (Objects.isNull(ec)) { java.util.Arrays.fill(leaf, (byte) 0xFF); } else { final byte[] ecBytes = ec.toBigInteger().toByteArray(); System.arraycopy(ecBytes, 0, leaf, leaf.length - ecBytes.length, ecBytes.length); } return leaf; } } /** * Leaf represents an abstract object. */ public static class Leaf extends ByteTree { private final byte[] value; public static final byte PREFIX = 1; /** * Initialize a leaf from an abstract byte array. * * @param value A byte array */ public Leaf(byte[] value) { this.value = value; } /** * Initialize a leaf from a String. * * @param value A string to initialize Leaf. */ public Leaf(String value) { byte[] encoded = null; try { encoded = value.getBytes("US-ASCII"); } catch (UnsupportedEncodingException e) { // this encoding is supported } this.value = encoded; } /** * Initialize a leaf from a BigInteger. * * @param value A BigInteger to initialize Leaf. */ public Leaf(BigInteger value) { this.value = value.toByteArray(); } /** * Initialize a leaf from a GroupElement. * * @param value A GroupElement to initialize Leaf. */ public Leaf(GroupElement value) { if (value instanceof ModPGroupElement) { this.value = getEncoded((ModPGroupElement) value); } else if (value instanceof ECGroupElement) { this.value = getEncoded((ECGroupElement) value); } else if (value instanceof ProductGroupElement) { throw new IllegalArgumentException("Use Node for ProductGroupElement"); } else { throw new IllegalArgumentException("Invalid group"); } } /** * Get the byte array used to initialize the Leaf. * * @return A byte array. */ public byte[] getValue() { return value; } /** * Return a String representation of the underlying byte array. * * @return String representing byte array. */ public String getString() { return Util.toString(getValue()); } /** * Return a BigInteger representation of the underlying byte array. * * @return BigInteger representing byte array. */ public BigInteger getBigInteger() { return new BigInteger(value); } /** * Get the length of the underlying byte array. * * @return Length of byte array. */ @Override public int getLength() { return value.length; } /** * Get the length of the whole Leaf object represented as byte array. * * @return Length of Leaf instance representation as byte array. */ @Override public int getEncodedLength() { return getLength() + 5; } /** * Get the value with corresponding headers. * * @return A byte array. */ @Override public byte[] getEncoded() { byte[] ret = new byte[getEncodedLength()]; ret[0] = PREFIX; System.arraycopy(ByteTree.parse_from_int(getLength()), 0, ret, 1, 4); System.arraycopy(getValue(), 0, ret, 5, getLength()); return ret; } /** * Encode the Leaf and write it to out. * * @param out Stream to write the ByteTree description of the Leaf. * @throws IOException When writing to out fails */ @Override public void writeEncoded(OutputStream out) throws IOException { out.write(PREFIX); out.write(ByteTree.parse_from_int(getLength())); out.write(getValue()); } private byte[] getEncoded(ModPGroupElement value) { // Verificatum verifier manual says that enough enough bytes are needed such that the // element fits in. In implementation, it uses BigInteger.toByteArray().length, which is // not always the same (it has a bit for magnitude). byte[] ret = new byte[((ModPGroup) value.getGroup()).getOrder().toByteArray().length]; byte[] bvalue = value.getValue().toByteArray(); System.arraycopy(bvalue, 0, ret, ret.length - bvalue.length, bvalue.length); return ret; } private byte[] getEncoded(ECGroupElement v) { return v.getBytes(); } /** * @return true */ @Override public boolean isLeaf() { return true; } /** * Parse an array of bytes into a leaf. * * @param b The array of bytes to parse. * @param offset Starting offset to start parsing from. * @return The Leaf constructed from bytes. */ public static Leaf parse(byte[] b, int offset) { int len = parse_int_fullbytes(b, offset); byte[] leafbytes = Arrays.copyOfRange(b, offset + 5, offset + 5 + len); return new Leaf(leafbytes); } /** * Parse a data stream into a leaf. * * Parses the given DataInputStream into the leaf. The given stream must be pointed to the * beginning of the definition (with length). * * @param is The given input stream, seeked to the beginning of the Leaf definition. * @return Leaf constructed from the input stream * @throws IOException When reading from the stream fails. */ public static Leaf parse(DataInputStream is) throws IOException { int len = read_length(is); byte[] leafbytes = new byte[len]; int read = is.read(leafbytes); if (read == -1) { throw new IOException("Unexpected end of stream"); } else if (read != len) { throw new IOException("Short read"); } return new Leaf(leafbytes); } /** * @return "LEAF" */ @Override public String getPrefix() { return "LEAF"; } /** * Return a human-friendly String representation of the Leaf with indentation. * * @param indent Indentation of the String. */ @Override public String toString(int indent) { String spaces = new String(new char[indent]).replace("\0", " "); return String.format("%s%s %d %s", spaces, getPrefix(), getLength(), HexFormat.of().formatHex(getValue()).toUpperCase()); } } /** * Parse an array of bytes into ByteTree instance. Internally, either Node or Leaf is * constructed depending on the prefix. * * @param b Byte array to be parsed. * @param offset Starting offset of the byte array to start parsing from. * @return A ByteTree representing the byte array. */ public static ByteTree parse(byte[] b, int offset) { if (offset < 0) { throw new IllegalArgumentException("Offset must be non-negatove"); } if (b == null || b.length <= offset + 5) { throw new IllegalArgumentException("Non-existing bytetree"); } if (b[offset] == Node.PREFIX) { return Node.parse(b, offset); } else if (b[offset] == Leaf.PREFIX) { return Leaf.parse(b, offset); } throw new IllegalArgumentException("Invalid bytetree value"); } /** * Parse an input stream into ByteTree instance. * * Depending on the prefix, either Node or Leaf instance is constructed. * * @param is Given input stream to construct the ByteTree instance from, seeked to the * beginning. * @return A ByteTree representing the byte array. * @throws IOException When reading from the stream fails or if the prefix is invalid. */ public static ByteTree parse(DataInputStream is) throws IOException { switch (is.read()) { case -1: throw new IOException("Unexpected end of stream"); case Node.PREFIX: return Node.parse(is); case Leaf.PREFIX: return Leaf.parse(is); default: throw new IOException("Unexpected token in input stream"); } } /** * Short-hand method for {@link #parse(byte[], int)} with {@literal offset} 0. * * @param b Byte array to be parsed * @return A ByteTree representing the byte array. */ public static ByteTree parse(byte[] b) { return parse(b, 0); } /** * Parse a file at a path into a ByteTree instance. * * Read a file from the given location into a ByteTree instance. In practice, depending on the * prefix, either Node or Leaf is constructed. This method is useful when the files are large * and do not fit into byte arrays. * * @param path Location of file * @return A ByteTree instance representing the byte array. * @throws IOException When the path is invalid, or the corresponding file is not valid ByteTree * representation. */ public static ByteTree parse(Path path) throws IOException { File file = path.toFile(); FileInputStream fis = new FileInputStream(file); DataInputStream dis = new DataInputStream(fis); return parse(dis); } /** * Parse value from the byte array into integer. * * @param b Byte array to be parsed. * @param offset Starting offset to start parsing at. * @return Integer representation of the byte array. */ private static int parse_int(byte[] b, int offset) { if (b.length < offset + 4) { throw new IllegalArgumentException("Bytetree int must be in four bytes"); } return ByteBuffer.wrap(b, offset, 4).order(ByteOrder.BIG_ENDIAN).getInt(); } private static int parse_int_fullbytes(byte[] b, int offset) { int len = parse_int(b, offset + 1); return len; } private static byte[] parse_from_int(int v) { return ByteBuffer.allocate(4).order(ByteOrder.BIG_ENDIAN).putInt(v).array(); } private static int read_length(DataInputStream is) throws IOException { return is.readInt(); } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/shuffle/DataParser.java ================================================ package ee.ivxv.audit.shuffle; import ee.ivxv.audit.shuffle.ByteTree.Leaf; import ee.ivxv.audit.shuffle.ByteTree.Node; import ee.ivxv.common.math.ECGroup; import ee.ivxv.common.math.ECGroupElement; import ee.ivxv.common.math.Group; import ee.ivxv.common.math.GroupElement; import ee.ivxv.common.math.ModPGroup; import ee.ivxv.common.math.ModPGroupElement; import ee.ivxv.common.math.ProductGroup; import ee.ivxv.common.math.ProductGroupElement; import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.HexFormat; /** * DataParser is a utility class for performing operations with ByteTree objects. */ public class DataParser { /** * Identifier for groups of integers modulo a value. */ public static final String VER_MODP = "com.verificatum.arithm.ModPGroup"; /** * Identifier for elliptic curve groups. */ public static final String VER_EC = "com.verificatum.arithm.ECqPGroup"; /** * Extract Verificatum group information node from Verificatum group description. *

* Returns list [{@literal description}, {@literal groupinfo}], where {@literal decription} is a * string description of the group and {@literal groupinfo} is group-specific ByteTree * description of the group. * * @param pgroup String group description * @return Array of ByteTree elements representing group * @throws ShuffleException When unmarshalling fails. */ public static ByteTree[] unmarshalGroup(String pgroup) throws ShuffleException { String[] split = pgroup.split("::"); if (split.length != 2) { throw new ShuffleException("Invalid pgroup description string"); } String groupdesc = split[1]; // in some cases, the pgroup description has newline in the end. omit it if (groupdesc.length() % 2 == 1 && groupdesc.charAt(groupdesc.length() - 1) == '\n') { groupdesc = groupdesc.substring(0, groupdesc.length() - 1); } byte[] groupdescb = HexFormat.of().parseHex(groupdesc); ByteTree G = ByteTree.parse(groupdescb); if (G.isLeaf()) { throw new ShuffleException("Invalid pgroup description bytetree"); } ByteTree.Node pginfo = (ByteTree.Node) G; if (pginfo.getLength() != 2) { throw new ShuffleException("Invalid marshalled pgroup description"); } return pginfo.getNodes(); } /** * Extract elliptic curve generator from Verificatum elliptic curve group description leaf. *

* Returns the base point corresponding to the elliptic curve. Description leaf should be a * string leaf containing curve name. * * @param groupRoot ByteTree representation of elliptic curve group * @return Elliptic curve base point * @throws ShuffleException When parsing fails. * @throws IllegalArgumentException When unknown elliptic curve group is defined. */ public static ECGroupElement parseECGroupGenerator(ByteTree groupRoot) throws ShuffleException, IllegalArgumentException { if (!groupRoot.isLeaf()) { throw new ShuffleException("Invalid Elliptic Curve Group description"); } Leaf ecgroupname = (Leaf) groupRoot; ECGroup parsed_group = new ECGroup(ecgroupname.getString()); ECGroupElement generator = parsed_group.getBasePoint(); return generator; } /** * Extract elliptic curve group from Verificatum elliptic curve group description node. *

* * @see #parseECGroupGenerator(ByteTree) for input node format. * * @param groupRoot ByteTree representation of elliptic curve group. * @return {@link ee.ivxv.common.math.ECGroup} instance representing the group. * @throws ShuffleException When failing to parse the node */ public static ECGroup parseECGroup(ByteTree groupRoot) throws ShuffleException, IllegalArgumentException { return (ECGroup) parseECGroupGenerator(groupRoot).getGroup(); } /** * Extract generator for group of integers modulo a safe prime from Verificatum group * description node. *

* Expect as input a node [{@literal p}, {@literal q}, {@literal g}], where p is the modulus of * the group, q the order of the group and g the generator of the group. * * @param groupRoot ByteTree representation of group of integers modulo a prime. * @return Group generator * @throws ShuffleException When failing to parse the node. */ public static ModPGroupElement parseModPGroupGenerator(ByteTree groupRoot) throws ShuffleException { if (groupRoot.isLeaf()) { throw new ShuffleException("Invalid ModPGroup description"); } ByteTree.Node marshalled = (ByteTree.Node) groupRoot; if (marshalled.getLength() != 4) { throw new ShuffleException("Invalid ModPGroup description length"); } ByteTree pnode = marshalled.getNodes()[0]; if (!pnode.isLeaf()) { throw new ShuffleException("Invalid modulus leaf"); } BigInteger p = ((Leaf) pnode).getBigInteger(); ByteTree gnode = marshalled.getNodes()[2]; if (!gnode.isLeaf()) { throw new ShuffleException("Invalid generator leaf"); } BigInteger g = ((Leaf) gnode).getBigInteger(); ModPGroup parsed_group = new ModPGroup(p); ModPGroupElement generator = new ModPGroupElement(parsed_group, g); return generator; } /** * Extract group of integers modulo a prime from Verificatum group description node. *

* * @see #parseModPGroupGenerator(ByteTree). * * @param groupRoot ByteTree representation of group of integers modulo a prime. * @return {@link ee.ivxv.common.math.ModPGroup} representing a group * @throws ShuffleException When failing to parse the node */ public static ModPGroup parseModPGroup(ByteTree groupRoot) throws ShuffleException { return (ModPGroup) parseModPGroupGenerator(groupRoot).getGroup(); } /** * Parse group generator from Verificatum group description node. *

* * @see #parseModPGroupGenerator(ByteTree) * @see #parseECGroupGenerator(ByteTree) * * @param pgroup ByteTree representation of group. * @return {@link ee.ivxv.common.math.GroupElement} representing the group generator. * @throws ShuffleException When failing to parse the node */ public static GroupElement parseGroupGenerator(String pgroup) throws ShuffleException { ByteTree[] nodes = unmarshalGroup(pgroup); if (!nodes[0].isLeaf()) { throw new ShuffleException("Invalid marshalled pgroup description string"); } Leaf descstring = (Leaf) nodes[0]; GroupElement generator = null; if (descstring.getString().equals(VER_MODP)) { generator = parseModPGroupGenerator(nodes[1]); } else if (descstring.getString().equals(VER_EC)) { generator = parseECGroupGenerator(nodes[1]); } else { throw new ShuffleException("Invalid group"); } return generator; } /** * Get the ByteTree node as a group element. *

* The Verificatum element representation node bt must be a correct representation of the group * element. See descriptions of specific group methods for more detailed structures. *

* * @see #getAsElement(ECGroup, ByteTree) * @see #getAsElement(ModPGroup, ByteTree) * @see #getAsElement(ProductGroup, ByteTree) * * @param group Group where the element belongs * @param bt Element representation in Verificatum ByteTree format * @return Group element instance * @throws IllegalArgumentException when parsing fails */ public static GroupElement getAsElement(Group group, ByteTree bt) throws IllegalArgumentException { if (group instanceof ModPGroup) { return getAsElement((ModPGroup) group, bt); } else if (group instanceof ECGroup) { return getAsElement((ECGroup) group, bt); } else if (group instanceof ProductGroup) { return getAsElement((ProductGroup) group, bt); } else { throw new IllegalArgumentException("Invalid group"); } } /** * Get the indexed node from the ByteTree nodes as a group element *

* Indexed version of {@link #getAsElement(Group, ByteTree)}. *

* * @see #getAsElement(Group, ByteTree). * * @param group Group where the element belongs * @param bt Elements node representation in Verificatum ByteTree format * @param index Element index * @return Group element instance * @throws IllegalArgumentException when parsing fails */ public static GroupElement getAsElement(Group group, ByteTree bt, int index) throws IllegalArgumentException { if (bt.isLeaf()) { throw new IllegalArgumentException("Expecting node"); } Node node = (Node) bt; return getAsElement(group, node.getNodes()[index]); } /** * Get the ByteTree leaf as ModPGroupElement *

* We assume that the leaf is an integer. It is represented as an element in group of modulo a * prime. * * @param group Group where the element belongs. * @param bt Integer leaf * @return {@link ee.ivxv.common.math.ModPGroupElement} instance * @throws IllegalArgumentException When parsing fails */ public static ModPGroupElement getAsElement(ModPGroup group, ByteTree bt) throws IllegalArgumentException { if (!bt.isLeaf()) { throw new IllegalArgumentException("Expecting leaf"); } Leaf leaf = (Leaf) bt; BigInteger val = leaf.getBigInteger(); return new ModPGroupElement(group, val); } /** * Get the ByteTree node as an ECGroupElement. * * @param group Group where the element belongs * @param bt Node node * @return {@link ee.ivxv.common.math.ECGroupElement} instance */ public static ECGroupElement getAsElement(ECGroup group, ByteTree bt) { Node point = (Node) bt; Leaf x = (Leaf) point.getNodes()[0]; Leaf y = (Leaf) point.getNodes()[1]; return new ECGroupElement(group, x.getBigInteger(), y.getBigInteger()); } /** * Get the ByteTree node as an ProductGroupElement. *

* We assume that the node is an array of group element nodes. Every node is parsed as a * suitable group element from the product group. * * @param group Product group instance where the element belongs * @param bt Node representing the element * @return {@link ee.ivxv.common.math.ProductGroupElement} instance. * @throws IllegalArgumentException When parsing fails. */ public static ProductGroupElement getAsElement(ProductGroup group, ByteTree bt) throws IllegalArgumentException { if (bt.isLeaf()) { throw new IllegalArgumentException("Expecting node"); } Group[] groups = ((ProductGroup) group).getGroups(); GroupElement[] el = new GroupElement[groups.length]; for (int i = 0; i < groups.length; i++) { el[i] = getAsElement(groups[i], bt, i); } return new ProductGroupElement(group, el); } /** * Get the ByteTree node as an array of group elements. *

* We assume that the node is an array of group element representations. See specific group * element getter methods for exact structures. *

* * @see #getAsElement(Group, ByteTree). * * @param group Group which the elements are part of. * @param bt Node which is an array of elements. * @return An array of {@link ee.ivxv.common.math.GroupElement} instances. * @throws IllegalArgumentException When parsing fails. */ public static GroupElement[] getAsElementArray(Group group, ByteTree bt) throws IllegalArgumentException { if (bt.isLeaf()) { throw new IllegalArgumentException("Expecting root node"); } if (group instanceof ProductGroup) { // handle special case return getAsElementArray((ProductGroup) group, bt); } Node rootnode = (Node) bt; ByteTree[] nodes = rootnode.getNodes(); GroupElement[] ret = new GroupElement[nodes.length]; for (int i = 0; i < nodes.length; i++) { ret[i] = getAsElement(group, nodes[i]); } return ret; } /** * Get the ByteTree node as an array of product group elements. *

* We assume that the node is an array of group element representations. See specific group * element getter methods for exact structures. *

* * @see #getAsElement(ProductGroup, ByteTree) * * @param group Group which the elements are part of. * @param bt Node which is an array of elements. * @return An array of {@link ee.ivxv.common.math.GroupElement} instances. * @throws IllegalArgumentException When parsing fails. */ public static GroupElement[] getAsElementArray(ProductGroup group, ByteTree bt) throws IllegalArgumentException { Node rootnode = (Node) bt; Group[] groups = group.getGroups(); GroupElement[][] sub = new GroupElement[groups.length][]; for (int i = 0; i < groups.length; i++) { sub[i] = getAsElementArray(groups[i], rootnode.getNodes()[i]); } GroupElement[] ret = new GroupElement[sub[0].length]; for (int i = 0; i < ret.length; i++) { GroupElement[] cons = new GroupElement[groups.length]; for (int j = 0; j < groups.length; j++) { cons[j] = sub[j][i]; } ret[i] = new ProductGroupElement(group, cons); } return ret; } /** * Get the indexed ByteTree node as an array of group elements. *

* Indexed version of {@link #getAsElementArray(Group, ByteTree)}. *

* * @see #getAsElementArray(Group, ByteTree) * * @param group Group which the elements are part of. * @param bt Node which is an array of elements. * @param index Index of the node to use. * @return An array of {@link ee.ivxv.common.math.GroupElement} instances. * @throws IllegalArgumentException When parsing fails. */ public static GroupElement[] getAsElementArray(Group group, ByteTree bt, int index) throws IllegalArgumentException { if (bt.isLeaf()) { throw new IllegalArgumentException("Expecting node"); } Node node = (Node) bt; return getAsElementArray(group, node.getNodes()[index]); } /** * Get the indexed ByteTree node as an integer. *

* The index element of the node must be an integer leaf. * * @param bt Node * @param index Index of the element * @return Integer value * @throws IllegalArgumentException When parsing fails. */ public static BigInteger getAsInteger(ByteTree bt, int index) throws IllegalArgumentException { if (bt.isLeaf()) { throw new IllegalArgumentException("Root should be node"); } ByteTree[] nodes = ((Node) bt).getNodes(); if (!nodes[index].isLeaf()) { throw new IllegalArgumentException("Should be leaf"); } Leaf leaf = (Leaf) nodes[index]; BigInteger res = leaf.getBigInteger(); return res; } /** * Get the indexed ByteTree node as an array of integers. *

* The index element of the node must be a node consisting of integer leafs. * * @param bt Node * @param index Index of the element. * @return Array of integer values. * @throws IllegalArgumentException When parsing fails. */ public static BigInteger[] getAsIntegerArray(ByteTree bt, int index) throws IllegalArgumentException { if (bt.isLeaf()) { throw new IllegalArgumentException("Root should be node"); } ByteTree[] nodes = ((Node) bt).getNodes(); if (nodes[index].isLeaf()) { throw new IllegalArgumentException("Should be node"); } ByteTree[] intnodes = ((Node) nodes[index]).getNodes(); BigInteger[] res = new BigInteger[intnodes.length]; for (int i = 0; i < intnodes.length; i++) { if (!intnodes[i].isLeaf()) { throw new IllegalArgumentException("Should be leaf"); } res[i] = ((Leaf) intnodes[i]).getBigInteger(); } return res; } /** * Get the indexed ByteTree node as a group scalar. *

* Indexed version of {@link #getAsScalar(Group, ByteTree, int)}. *

* * @see #getAsScalar(Group, ByteTree, int) * * @param group Group where the scalar belongs. * @param bt Scalar node representation in Verificatum ByteTree format. * @param index Index of the node to use. * @return An array of {@link BigInteger} instances. * @throws IllegalArgumentException When parsing fails. */ public static BigInteger[] getAsScalar(Group group, ByteTree bt, int index) throws IllegalArgumentException { if (bt.isLeaf()) { throw new IllegalArgumentException("Expecting node"); } if (group instanceof ProductGroup) { Node node = (Node) ((Node) bt).getNodes()[index]; Group[] groups = ((ProductGroup) group).getGroups(); BigInteger[] scalars = new BigInteger[groups.length]; for (int i = 0; i < groups.length; i++) { Leaf leaf = (Leaf) node.getNodes()[i]; scalars[i] = leaf.getBigInteger(); } return scalars; } else { throw new IllegalArgumentException("Invalid group"); } } /** * Get the hash corresponding to string representation. *

* The hash name is delegated to {@link java.security.MessageDigest}. * * @param hashname Hash name. * @return Hash instance. * @throws IllegalArgumentException When can not find hash with hashname. */ public static MessageDigest getHash(String hashname) throws IllegalArgumentException { MessageDigest md; try { md = MessageDigest.getInstance(hashname); } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException( String.format("Hash function %s not supported", hashname)); } return md; } /** * Convert GroupElement array to a ProductGroupElement instance. *

* Currently only ProductGroupElement instances are supported. * * @param elements * @return * @throws IllegalArgumentException When converting fails */ public static ProductGroupElement toArray(GroupElement[] elements) throws IllegalArgumentException { ProductGroupElement[] casted = new ProductGroupElement[elements.length]; for (int i = 0; i < casted.length; i++) { if (!(elements[i] instanceof ProductGroupElement)) { throw new IllegalArgumentException("Invalid group"); } casted[i] = (ProductGroupElement) elements[i]; } return toArray(casted); } /** * Convert ProductGroupElement array to a ProductGroupElement instance. *

* * @see #toArray(GroupElement[]). * * @param elements * @return */ public static ProductGroupElement toArray(ProductGroupElement[] elements) { ProductGroupElement r = toArray_first(elements[0], elements.length); for (int i = 0; i < elements.length; i++) { toArray_second(r, elements[i], i); } return r; } private static ProductGroupElement toArray_first(ProductGroupElement in, int N) { GroupElement[] gs = in.getElements(); GroupElement[] ret = new GroupElement[gs.length]; Group[] retgs = new Group[gs.length]; for (int i = 0; i < gs.length; i++) { if (gs[i] instanceof ProductGroupElement) { ret[i] = toArray_first((ProductGroupElement) gs[i], N); } else { ret[i] = new ProductGroupElement(new ProductGroup(gs[i].getGroup(), N)); } retgs[i] = ret[i].getGroup(); } return new ProductGroupElement(new ProductGroup(retgs), ret); } private static void toArray_second(ProductGroupElement out, ProductGroupElement in, int N) { GroupElement[] inel = in.getElements(); GroupElement[] outel = out.getElements(); for (int i = 0; i < inel.length; i++) { if (inel[i] instanceof ProductGroupElement) { toArray_second((ProductGroupElement) outel[i], (ProductGroupElement) inel[i], N); } else { ((ProductGroupElement) outel[i]).getElements()[N] = inel[i]; } } } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/shuffle/PRNG.java ================================================ package ee.ivxv.audit.shuffle; import ee.ivxv.common.util.Util; import java.security.MessageDigest; /** * Class PRNG implements pseudo-random number generator as defined in Verificatum independent * verifier implementation description. */ public class PRNG { private MessageDigest cleanhash; private byte[] buf; private int it; private int bufp; private int digestLen; /** * Initialize PRNG using a hash function and a seed. * * @param hashname Defined hash function. * @param seed Seed to initialize PRNG with. */ PRNG(String hashname, byte[] seed) { this.cleanhash = init_hash(hashname, seed); this.digestLen = cleanhash.getDigestLength(); this.buf = new byte[digestLen]; this.it = 0; this.bufp = digestLen; } /** * Fill the output buffer with bytes from the PRNG. * * @param out Output buffer to fill. */ public void read(byte[] out) { int read = 0; int to_read; int len = out.length; while (read < len) { refill(); to_read = Math.min(len - read, digestLen - bufp); System.arraycopy(buf, bufp, out, read, to_read); bufp = bufp + to_read; read += to_read; } } private void refill() { if (bufp < digestLen) { return; } MessageDigest h; try { h = (MessageDigest) cleanhash.clone(); } catch (CloneNotSupportedException e) { // already checked return; } buf = h.digest(Util.toBytes(it)); bufp = 0; it += 1; } static MessageDigest init_hash(String hashname, byte[] seed) { MessageDigest md = DataParser.getHash(hashname); try { md.clone(); } catch (CloneNotSupportedException e) { throw new IllegalArgumentException( String.format("Hash function %s support is incomplete", hashname)); } if (seed != null) { md.update(seed); } return md; } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/shuffle/ProtocolInformation.java ================================================ package ee.ivxv.audit.shuffle; import ee.ivxv.common.math.Group; import ee.ivxv.common.math.GroupElement; import java.io.IOException; import java.nio.file.Path; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * ProtocolInformation represents Verificatum protocol information file. */ public class ProtocolInformation { private String version, sid, name, pgroup, prg, rohash, auxsid, type; private int statdist, width, ebitlenro, vbitlenro, keywidth; private Group pgroup_parsed; private GroupElement generator_parsed; private static final String default_auxsid = "default"; private static final String default_type = "shuffling"; private static final int default_keywidth = 5; /** * Initialize ProtocolInformation from required values. * * @param version * @param sid * @param name * @param pgroup * @param keywidth * @param vbitlenro * @param ebitlenro * @param prg * @param rohash * @param width * @param statdist */ public ProtocolInformation(String version, String sid, String name, String pgroup, int keywidth, int vbitlenro, int ebitlenro, String prg, String rohash, int width, int statdist) { this.version = version; this.sid = sid; this.name = name; this.pgroup = pgroup; this.keywidth = keywidth; this.vbitlenro = vbitlenro; this.ebitlenro = ebitlenro; this.prg = prg; this.rohash = rohash; this.width = width; this.statdist = statdist; this.auxsid = default_auxsid; this.type = default_type; } /** * Initialize the ProtocolInformation from a file. * * @param protinfo Protocol information file * @throws ShuffleException When parsing fails */ public ProtocolInformation(Path protinfo) throws ShuffleException { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db; Document dom; try { db = dbf.newDocumentBuilder(); } catch (ParserConfigurationException e) { // there should be a default parser throw new RuntimeException("XML parser not configured", e); } try { dom = db.parse(protinfo.toFile()); } catch (SAXException e) { throw new IllegalArgumentException("Invalid Protocol Information file", e); } catch (IOException e) { throw new IllegalArgumentException("Error while reading Protocol Information file", e); } Element root = dom.getDocumentElement(); root.normalize(); if (!root.getNodeName().equals("protocol")) { throw new IllegalArgumentException("Root node must be 'protocol'"); } if (root.getNodeType() != Node.ELEMENT_NODE) { throw new IllegalArgumentException("Protocol node must be an element node"); } Element rootel = (Element) root; this.version = get_element(rootel, "version"); this.sid = get_element(rootel, "sid"); this.name = get_element(rootel, "name"); this.pgroup = get_element(rootel, "pgroup"); this.generator_parsed = DataParser.parseGroupGenerator(this.pgroup); this.pgroup_parsed = this.generator_parsed.getGroup(); this.keywidth = Integer.parseInt(get_element(rootel, "keywidth")); if (this.keywidth != default_keywidth) { throw new IllegalArgumentException("Invalid keywidth"); } this.vbitlenro = Integer.parseInt(get_element(rootel, "vbitlenro")); this.ebitlenro = Integer.parseInt(get_element(rootel, "ebitlenro")); this.prg = get_element(rootel, "prg"); this.rohash = get_element(rootel, "rohash"); this.width = Integer.parseInt(get_element(rootel, "width")); this.statdist = Integer.parseInt(get_element(rootel, "statdist")); this.auxsid = default_auxsid; this.type = default_type; String corr = get_element(rootel, "corr"); if (!corr.equals("noninteractive")) { throw new IllegalArgumentException("Only non-interactive protocol is supported"); } } private static String get_element(Element node, String name) { NodeList els = node.getElementsByTagName(name); String val = null; if (els.getLength() < 1) { throw new IllegalArgumentException(String.format("Element '%s' missing", name)); } if (els.getLength() > 1) { for (int i = 0; i < els.getLength(); i++) { if (els.item(i).getParentNode().equals(node)) { val = els.item(i).getTextContent(); } } if (val == null) { throw new IllegalArgumentException(String.format("Element '%s' not found", name)); } } else { val = els.item(0).getTextContent(); } return val; } public String get_version() { return version; } public String get_sid() { return sid; } public String get_auxsid() { return auxsid; } public String get_name() { return name; } public String get_pgroup() { return pgroup; } public Group get_parsed_pgroup() { return pgroup_parsed; } public GroupElement get_parsed_generator() { return generator_parsed; } public int get_keywidth() { return keywidth; } public int get_vbitlenro() { return vbitlenro; } public int get_ebitlenro() { return ebitlenro; } public String get_prg() { return prg; } public String get_rohash() { return rohash; } public int get_width() { return width; } public int get_statdist() { return statdist; } public String get_type() { return type; } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/shuffle/RO.java ================================================ package ee.ivxv.audit.shuffle; import ee.ivxv.common.util.Util; import java.io.IOException; import java.io.OutputStream; import java.security.MessageDigest; /** * Implements Random Oracle as defined in Verificatum manual for implementing independent verifier. */ public class RO extends OutputStream { private String hashname; private MessageDigest hash; private byte[] seed; private int amount; /** * Initialize RO using a hashname and a seed. * * @param hashname Hash function to use. * @param seed Seed bytes. */ public RO(String hashname, byte[] seed) { this.hashname = hashname; this.flush(); this.seed = seed.clone(); } /** * Initialize RO instance using hashname. * * In this mode, the user has to provide the amount to be read and the seed to seed this * instance separately. * * @param hashname Hash function to use. */ public RO(String hashname) { this.hashname = hashname; this.flush(); } /** * Reset the RO instance * */ public void flush() { this.hash = PRNG.init_hash(hashname, null); this.amount = 0; } /** * Set the expected amount to be read. * * As the amount is written to the digest instance, then it must be set before updating the RO * instance. * * @param amount */ public void setAmount(int amount) { this.amount = amount; hash.update(Util.toBytes(amount)); } private void readOut(byte[] out) { if ((this.amount + 7) / 8 != out.length) { throw new IllegalArgumentException( "Output buffer length does not correspond to requested read amount"); } PRNG p = new PRNG(hashname, hash.digest()); p.read(out); if (amount % 8 != 0) { out[0] &= (1 << (amount % 8)) - 1; } } /** * Fill the output buffer with bytes from the RO. * * If the amount field is 0, then it is assumed that it has been set by a call to * {@link #setAmount(int)}. If the seed was given during the initialization, then it is added to * the input. * * @param out Output buffer to fill. * @param amount Number of bits to fill */ public void read(byte[] out, int amount) { if (this.amount == 0) { setAmount(amount); } if (this.seed != null) { try { write(seed); } catch (IOException e) { // checked exception } } readOut(out); } /** * Update the RO with some input. * * The expected amount to be read must be set. * * @param b The data * @throws IOException When amount to be read is not set. */ @Override public void write(int b) throws IOException { write(new byte[] {(byte) b}); } /** * Update the RO with some input. * * The expected amount to be read must be set. * * @param b The data * @param off Offset of the data * @param len Length of the data * @throws IOException when amount to be read is not set. */ @Override public void write(byte[] b, int off, int len) throws IOException { if (amount == 0) { throw new IllegalArgumentException("Amount not set"); } hash.update(b, off, len); } /** * Update the RO with some input. * * The expected amount to be read must be set. * * @param in A byte array to seed into the RO instance. * @throws IOException when amount to be read is not set. */ @Override public void write(byte[] b) throws IOException { write(b, 0, b.length); } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/shuffle/ShuffleConsole.java ================================================ package ee.ivxv.audit.shuffle; import ee.ivxv.audit.Msg; import ee.ivxv.common.service.console.Progress; import ee.ivxv.common.service.i18n.Translatable; import ee.ivxv.common.util.I18nConsole; import java.util.ArrayList; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; public class ShuffleConsole { private final I18nConsole console; public ShuffleConsole(I18nConsole console) { this.console = console; } public void enter(ShuffleStep step) { int totalSteps = step.parent != null ? step.parent.subSteps.size() : 0; int thisStep = step.parent != null ? step.parent.nextSubStep() : 0; String stepstr = ""; if (totalSteps > 0) { stepstr = String.format("(%d/%d): ", thisStep, totalSteps); } if (step.i18msg != null) { console.println(Msg.m_shuffle_step, step.getDepth(), stepstr, step.i18msg); } else if (step.msg != null) { console.println(Msg.m_shuffle_step, step.getDepth(), stepstr, step.msg); } else { console.println(Msg.m_shuffle_step, step.getDepth(), stepstr, ""); } } public Progress enter(ShuffleStep step, long length) { enter(step); return console.startProgress(length, true); } public static enum ShuffleStep { READ(Msg.m_shuffle_read), // READ_PROT_INFO(READ, Msg.m_shuffle_read_prot_info), // READ_PUBKEY(READ, Msg.m_shuffle_read_pubkey), // READ_PC(READ, Msg.m_shuffle_read_pc), READ_POSC(READ, Msg.m_shuffle_read_posc), // READ_POSR(READ, Msg.m_shuffle_read_posr), // READ_CIPHS(READ, Msg.m_shuffle_read_ciphs), // READ_SHUFFLED(READ, Msg.m_shuffle_read_shuffled), VERIFY(Msg.m_shuffle_verify), // VERIFY_PARAMS(VERIFY, Msg.m_shuffle_verify_params), // VERIFY_NI(VERIFY, Msg.m_shuffle_verify_ni), // VERIFY_PERM(VERIFY, Msg.m_shuffle_verify_permutation), // VERIFY_RERAND(VERIFY, Msg.m_shuffle_verify_rerandomisation); final String msg; final Translatable i18msg; final ShuffleStep parent; final List subSteps = new ArrayList(); final AtomicInteger completed = new AtomicInteger(); ShuffleStep(Translatable msg) { this.msg = null; this.i18msg = msg; this.parent = null; } ShuffleStep(String msg) { this.msg = msg; this.i18msg = null; this.parent = null; } ShuffleStep(ShuffleStep parent, Translatable msg) { this.msg = null; this.i18msg = msg; this.parent = parent; parent.appendSubStep(this); } int getDepth() { int i = 0; ShuffleStep next = this.parent; while (next != null) { next = next.parent; i++; } return i; } void appendSubStep(ShuffleStep substep) { subSteps.add(substep); } int subStepCount() { return subSteps.size(); } int nextSubStep() { return this.completed.incrementAndGet(); } } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/shuffle/ShuffleException.java ================================================ package ee.ivxv.audit.shuffle; @SuppressWarnings("serial") public class ShuffleException extends Exception { public ShuffleException(Throwable t) { super(t); } public ShuffleException(String msg) { super(msg); } public ShuffleException(String msg, Throwable t) { super(msg, t); } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/shuffle/ShuffleParameters.java ================================================ package ee.ivxv.audit.shuffle; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.List; public class ShuffleParameters { private String version, auxsid, type; int width; /** * Initialize the shuffle parameters from values. * * @param version * @param auxsid * @param width * @param type */ ShuffleParameters(String version, String auxsid, int width, String type) { this.version = version; this.auxsid = auxsid; this.width = width; this.type = type; } /** * Initialize ShuffleParameters using a proof directory path. The corresponding files are * assumed to be at their default locations (stored by Verificatum). * * @param proofdir Proof directory * @throws IOException If reading parameter file fails */ ShuffleParameters(Path proofdir) throws IOException { Path versionpath = Paths.get(proofdir.toString(), "version"); Path auxsidpath = Paths.get(proofdir.toString(), "auxsid"); Path widthpath = Paths.get(proofdir.toString(), "width"); Path typepath = Paths.get(proofdir.toString(), "type"); this.version = read_parameters(versionpath); this.auxsid = read_parameters(auxsidpath); this.width = Integer.parseInt(read_parameters(widthpath)); this.type = read_parameters(typepath); } private static String read_parameters(Path loc) throws IOException { List l = Files.readAllLines(loc); if (l.size() != 1) { throw new IllegalArgumentException("Parameters file must have single line"); } return l.get(0); } public String get_version() { return version; } public String get_auxsid() { return auxsid; } public int get_width() { return width; } public String get_type() { return type; } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/shuffle/ShuffleProof.java ================================================ package ee.ivxv.audit.shuffle; import ee.ivxv.audit.shuffle.ShuffleConsole.ShuffleStep; import ee.ivxv.common.crypto.elgamal.ElGamalCiphertext; import ee.ivxv.common.crypto.elgamal.ElGamalPublicKey; import ee.ivxv.common.math.Group; import ee.ivxv.common.math.GroupElement; import ee.ivxv.common.math.ProductGroup; import ee.ivxv.common.math.ProductGroupElement; import java.io.IOException; import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; /** * Class for holding variables for non-interactive shuffle proof. */ public class ShuffleProof { private final ProtocolInformation prot; private final PermutationCommitment pc; private final PoSCommitment posc; private final PoSReply posr; private final GroupElement[] ciphs, shuffled; private final GroupElement pk; /** * Default filename of ciphertexts in Verificatum shuffle proof. */ public static final String CIPHERTEXTS_PATH = "Ciphertexts.bt"; /** * Default filename of shuffled ciphertexts in Verificatum shuffle proof. */ public static final String SHUFFLED_CIPHERTEXTS_PATH = "ShuffledCiphertexts.bt"; /** * Default filename of public key in Verificatum shuffle proof. */ public static final String PUBLICKEY_PATH = "FullPublicKey.bt"; /** * Default directory name for proofs in Verificatum shuffle proof. */ public static final String PROOFS_PATH = "proofs"; /** * Default filename of permutation commitment in Verificatum shuffle proof. */ public static final String PC_PATH = "PermutationCommitment01.bt"; /** * Default filename of shuffle commitment in Verificatum shuffle proof. */ public static final String POSC_PATH = "PoSCommitment01.bt"; /** * Default filename of shuffle proof reply in Verificatum shuffle proof. */ public static final String POSR_PATH = "PoSReply01.bt"; /** * Initialize the proof from components. Ciphertexts, shuffled ciphertexts and public key are * represented as corresponding group elements. * * @param prot * @param pc * @param posc * @param posr * @param ciphs * @param shuffled * @param pk */ public ShuffleProof(ProtocolInformation prot, PermutationCommitment pc, PoSCommitment posc, PoSReply posr, GroupElement[] ciphs, GroupElement[] shuffled, GroupElement pk) { this.prot = prot; this.pc = pc; this.posc = posc; this.posr = posr; this.ciphs = ciphs; this.shuffled = shuffled; this.pk = pk; } /** * Initialize the proof from components. * * @param prot * @param pc * @param posc * @param posr * @param ciphs * @param shuffled * @param pk */ public ShuffleProof(ProtocolInformation prot, PermutationCommitment pc, PoSCommitment posc, PoSReply posr, ElGamalCiphertext[] ciphs, ElGamalCiphertext[] shuffled, ElGamalPublicKey pk) { if (ciphs.length != shuffled.length) { throw new IllegalArgumentException("Ciphertext and shuffled length does not match"); } GroupElement[] cge = new GroupElement[ciphs.length]; GroupElement[] scge = new GroupElement[shuffled.length]; for (int i = 0; i < ciphs.length; i++) { cge[i] = ciphs[i].getAsProductGroupElement(); scge[i] = shuffled[i].getAsProductGroupElement(); } this.prot = prot; this.pc = pc; this.posc = posc; this.posr = posr; this.ciphs = cge; this.shuffled = scge; this.pk = pk.getAsProductGroupElement(); } /** * Initialize the proof from protocol information path and proof directory path. *

* Parses the files and constructs the components. * * @param protpath * @param proofdir * @throws IOException * @throws ShuffleException */ public ShuffleProof(Path protpath, Path proofdir, ShuffleConsole console) throws IOException, ShuffleException { console.enter(ShuffleStep.READ); console.enter(ShuffleStep.READ_PROT_INFO); prot = new ProtocolInformation(protpath); console.enter(ShuffleStep.READ_PC); Path pcpath = Paths.get(proofdir.toString(), PROOFS_PATH, PC_PATH); pc = new PermutationCommitment(prot, pcpath); console.enter(ShuffleStep.READ_POSC); Path poscpath = Paths.get(proofdir.toString(), PROOFS_PATH, POSC_PATH); posc = new PoSCommitment(prot, poscpath); console.enter(ShuffleStep.READ_POSR); Path posrpath = Paths.get(proofdir.toString(), PROOFS_PATH, POSR_PATH); posr = new PoSReply(prot, posrpath); console.enter(ShuffleStep.READ_PUBKEY); Path pkpath = Paths.get(proofdir.toString(), PUBLICKEY_PATH); ByteTree pkbt = ByteTree.parse(pkpath); Group group = prot.get_parsed_pgroup(); Group ciphgroup = get_ciphertext_group(prot, group); pk = DataParser.getAsElement(ciphgroup, pkbt); console.enter(ShuffleStep.READ_CIPHS); Path ciphspath = Paths.get(proofdir.toString(), CIPHERTEXTS_PATH); ByteTree ctsbt = ByteTree.parse(ciphspath); ciphs = DataParser.getAsElementArray(ciphgroup, ctsbt); console.enter(ShuffleStep.READ_SHUFFLED); Path shuffledpath = Paths.get(proofdir.toString(), SHUFFLED_CIPHERTEXTS_PATH); ByteTree sctsbt = ByteTree.parse(shuffledpath); shuffled = DataParser.getAsElementArray(ciphgroup, sctsbt); } public ProtocolInformation get_ProtocolInformation() { return prot; } public PermutationCommitment get_PermutationCommitment() { return pc; } public PoSCommitment get_PoSCommitment() { return posc; } public PoSReply get_PoSReply() { return posr; } public GroupElement[] get_ciphertexts() { return ciphs; } public GroupElement[] get_shuffled_ciphertexts() { return shuffled; } public GroupElement get_publickey() { return pk; } private static ProductGroup get_ciphertext_group(ProtocolInformation prot, Group group) { ProductGroup prodgroup = new ProductGroup(group, prot.get_keywidth()); ProductGroup ciphgroup = new ProductGroup(prodgroup, 2); return ciphgroup; } /** * Permutation commitment holder. */ public static class PermutationCommitment { private final GroupElement[] u; /** * Parse permutation commitment from a bytetree. * * @param bt */ PermutationCommitment(ProtocolInformation prot, byte[] bt) { ByteTree root = ByteTree.parse(bt); this.u = DataParser.getAsElementArray(prot.get_parsed_pgroup(), root); } /** * Initialize the permutation commitment from protocol information and permutation * commitment path. * * @param prot * @param path * @throws IOException */ PermutationCommitment(ProtocolInformation prot, Path path) throws IOException { this(prot, Files.readAllBytes(path)); } public GroupElement[] get_u() { return u; } } /** * Proof of shuffle commitment holder. */ public static class PoSCommitment { private GroupElement A_prim, C_prim, D_prim; private GroupElement[] B, B_prim; private ProductGroupElement F_prim; /** * Parse proof of shuffle commitment from bytetree. * * @param bt Byte array holding proof of shuffle commitment. */ PoSCommitment(ProtocolInformation prot, byte[] bt) { ByteTree root = ByteTree.parse(bt); Group group = prot.get_parsed_pgroup(); ProductGroup ciphgroup = get_ciphertext_group(prot, group); B = DataParser.getAsElementArray(group, root, 0); A_prim = DataParser.getAsElement(group, root, 1); B_prim = DataParser.getAsElementArray(group, root, 2); C_prim = DataParser.getAsElement(group, root, 3); D_prim = DataParser.getAsElement(group, root, 4); F_prim = (ProductGroupElement) DataParser.getAsElement(ciphgroup, root, 5); } /** * Initialize the shuffle commitment from protocol information and shuffle commitment path. * * @param prot * @param path * @throws IOException */ PoSCommitment(ProtocolInformation prot, Path path) throws IOException { this(prot, Files.readAllBytes(path)); } public GroupElement get_A_prim() { return A_prim; } public GroupElement get_C_prim() { return C_prim; } public GroupElement get_D_prim() { return D_prim; } public GroupElement[] get_B() { return B; } public GroupElement[] get_B_prim() { return B_prim; } public ProductGroupElement get_F_prim() { return F_prim; } } /** * Holder for proof of shuffle reply. */ public static class PoSReply { private BigInteger kA, kC, kD; private BigInteger[] kB, kE; private BigInteger[] kF; /** * Parse proof of shuffle reply from bytetree. * * @param bt Byte array holding proof of shuffle in bytetree format. */ PoSReply(ProtocolInformation prot, byte[] bt) { ByteTree root = ByteTree.parse(bt); Group group = prot.get_parsed_pgroup(); ProductGroup prodgroup = new ProductGroup(group, prot.get_keywidth()); kA = DataParser.getAsInteger(root, 0); kB = DataParser.getAsIntegerArray(root, 1); kC = DataParser.getAsInteger(root, 2); kD = DataParser.getAsInteger(root, 3); kE = DataParser.getAsIntegerArray(root, 4); kF = DataParser.getAsScalar(prodgroup, root, 5); } /** * Initialize the proof reply from protocol information and path to proof reply. * * @param prot * @param path * @throws IOException */ PoSReply(ProtocolInformation prot, Path path) throws IOException { this(prot, Files.readAllBytes(path)); } public BigInteger get_kA() { return kA; } public BigInteger get_kC() { return kC; } public BigInteger get_kD() { return kD; } public BigInteger[] get_kB() { return kB; } public BigInteger[] get_kE() { return kE; } public BigInteger[] get_kF() { return kF; } } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/shuffle/ThreadedVerifier.java ================================================ package ee.ivxv.audit.shuffle; import ee.ivxv.audit.shuffle.ShuffleConsole.ShuffleStep; import ee.ivxv.common.math.GroupElement; import ee.ivxv.common.math.MathException; import ee.ivxv.common.math.ModPGroupElement; import ee.ivxv.common.math.ProductGroup; import ee.ivxv.common.math.ProductGroupElement; import ee.ivxv.common.service.console.Progress; import java.math.BigInteger; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.FutureTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ThreadedVerifier extends Verifier { static final Logger log = LoggerFactory.getLogger(ThreadedVerifier.class); private int nothreads; private ExecutorService executor; public ThreadedVerifier(ShuffleConsole console, ShuffleProof proof, int nothreads) { super(console, proof); this.nothreads = nothreads; this.executor = Executors.newFixedThreadPool(nothreads); } public GroupElement compute_A_threaded(Progress progress, BigInteger[] e) throws MathException, InterruptedException, ExecutionException { return compute_A(progress, get_proof().get_PermutationCommitment().get_u(), e, nothreads, executor); } public GroupElement compute_F_threaded(Progress progress, BigInteger[] e) throws MathException, InterruptedException, ExecutionException { return compute_F(progress, get_proof().get_ciphertexts(), e, nothreads, executor); } public boolean verify_A_threaded(Progress progress, BigInteger v, GroupElement A, GroupElement[] h) throws MathException, InterruptedException, ExecutionException { return verify_A(progress, v, A, get_proof().get_PoSCommitment().get_A_prim(), get_proof().get_ProtocolInformation().get_parsed_generator(), h, get_proof().get_PoSReply().get_kA(), get_proof().get_PoSReply().get_kE(), nothreads, executor); } public boolean verify_B_threaded(Progress progress, BigInteger v, GroupElement[] h) throws MathException, InterruptedException, ExecutionException { return verify_B(progress, v, get_proof().get_PoSCommitment().get_B(), get_proof().get_PoSCommitment().get_B_prim(), get_proof().get_ProtocolInformation().get_parsed_generator(), get_proof().get_PoSReply().get_kB(), get_proof().get_PoSReply().get_kE(), h, nothreads, executor); } public boolean verify_F_threaded(Progress progress, BigInteger v, GroupElement F) throws MathException, InterruptedException, ExecutionException { return verify_F(progress, v, F, get_proof().get_PoSCommitment().get_F_prim(), get_proof().get_publickey(), get_proof().get_PoSReply().get_kE(), get_proof().get_PoSReply().get_kF(), get_proof().get_shuffled_ciphertexts(), nothreads, executor); } public boolean verify_all() throws ShuffleException, MathException { console.enter(ShuffleStep.VERIFY); console.enter(ShuffleStep.VERIFY_PARAMS); byte[] rho = compute_rho(); GroupElement[] h = compute_h(rho); console.enter(ShuffleStep.VERIFY_NI); byte[] s = compute_RO_seed(rho, h); BigInteger[] e = compute_e(s); BigInteger v = compute_v(rho, s); int N = get_proof().get_ciphertexts().length; Progress progress = console.enter(ShuffleStep.VERIFY_PERM, 5 * N + 10 + 3 * nothreads); GroupElement A; try { A = compute_A_threaded(progress, e); } catch (InterruptedException | ExecutionException ex) { executor.shutdown(); throw new ShuffleException(ex); } GroupElement C = compute_C(progress, h); GroupElement D = compute_D(progress, h, e); try { if (!verify_A_threaded(progress, v, A, h)) { throw new ShuffleException("A failed"); } } catch (InterruptedException | ExecutionException ex) { executor.shutdown(); throw new ShuffleException(ex); } try { if (!verify_B_threaded(progress, v, h)) { throw new ShuffleException("B failed"); } } catch (InterruptedException | ExecutionException ex) { executor.shutdown(); throw new ShuffleException(ex); } if (!verify_C(progress, v, C)) { throw new ShuffleException("C failed"); } if (!verify_D(progress, v, D)) { throw new ShuffleException("D failed"); } progress.finish(); progress = console.enter(ShuffleStep.VERIFY_RERAND, 2 * N + get_proof().get_PoSReply().get_kF().length + 3 + 2 * nothreads); GroupElement F; try { F = compute_F_threaded(progress, e); } catch (InterruptedException | ExecutionException ex) { executor.shutdown(); throw new ShuffleException(ex); } try { if (!verify_F_threaded(progress, v, F)) { throw new ShuffleException("F failed"); } } catch (InterruptedException | ExecutionException ex) { executor.shutdown(); throw new ShuffleException(ex); } executor.shutdown(); progress.finish(); return true; } private GroupElement compute_A(Progress progress, GroupElement[] u, BigInteger[] e, int nothreads, ExecutorService executor) throws MathException, InterruptedException, ExecutionException { // the number of computations differ in threaded and non-threaded case. In threaded case we // also aggregate the per-thread results. List> futures = new ArrayList<>(); for (int i = 0; i < nothreads; i++) { FutureTask ft = new FutureTask<>(get_compute_A_worker(progress, u, e, i, nothreads)); executor.submit(ft); futures.add(ft); } log.debug("Started all compute A workers"); GroupElement res = u[0].getGroup().getIdentity(); log.debug("Collecting compute A worker results"); for (Future ft : futures) { res = res.op(ft.get()); progress.increase(1); } log.debug("Collected all compute A worker results"); return res; } private static Callable get_compute_A_worker(Progress progress, GroupElement[] u, BigInteger[] e, int threadid, int nothreads) { return () -> { log.debug("Compute A worker [{}/{}] started", threadid, nothreads); GroupElement res = u[0].getGroup().getIdentity(); for (int i = 0; i < u.length; i++) { if (i % nothreads != threadid) continue; GroupElement exped = u[i].scale(e[i]); res = res.op(exped); progress.increase(1); } log.debug("Compute A worker [{}/{}] finished", threadid, nothreads); return res; }; } public GroupElement compute_F(Progress progress, GroupElement[] w, BigInteger[] e, int nothreads, ExecutorService executor) throws MathException, InterruptedException, ExecutionException { // the number of computations differ in threaded and non-threaded case. In threaded case we // also aggregate the per-thread results. List> futures = new ArrayList<>(); for (int i = 0; i < nothreads; i++) { FutureTask ft = new FutureTask<>(get_compute_F_worker(progress, w, e, i, nothreads)); executor.submit(ft); futures.add(ft); } log.debug("Started all compute F workers"); GroupElement res = w[0].getGroup().getIdentity(); log.debug("Collecting compute F worker results"); for (Future ft : futures) { res = res.op(ft.get()); progress.increase(1); } log.debug("Collected all compute F worker results"); return res; } private static Callable get_compute_F_worker(Progress progress, GroupElement[] w, BigInteger[] e, int threadid, int nothreads) throws MathException { return () -> { log.debug("Compute F [{}/{}] worker started", threadid, nothreads); GroupElement res = w[0].getGroup().getIdentity(); for (int i = 0; i < w.length; i++) { if (i % nothreads != threadid) continue; GroupElement exped = w[i].scale(e[i]); res = res.op(exped); progress.increase(1); } log.debug("Compute F worker [{}/{}] finished", threadid, nothreads); return res; }; } private boolean verify_A(Progress progress, BigInteger v, GroupElement A, GroupElement A_prim, GroupElement g, GroupElement[] h, BigInteger k_A, BigInteger[] k_E, int nothreads, ExecutorService executor) throws MathException, InterruptedException, ExecutionException { // the number of computations differ in threaded and non-threaded case. In threaded case we // also aggregate the per-thread results. List> futures = new ArrayList<>(); for (int i = 0; i < nothreads; i++) { FutureTask ft = new FutureTask<>(get_verify_A_worker(progress, h, k_E, i, nothreads)); executor.submit(ft); futures.add(ft); } log.debug("Started verify A workers"); GroupElement left = A.scale(v).op(A_prim); progress.increase(1); GroupElement right = h[0].getGroup().getIdentity(); log.debug("Collecting verify A worker results"); for (Future ft : futures) { right = right.op(ft.get()); progress.increase(1); log.debug("Collected verify A worker result"); } log.debug("Collected all verify A worker results"); right = right.op(g.scale(k_A)); progress.increase(1); return left.equals(right); } private static Callable get_verify_A_worker(Progress progress, GroupElement[] h, BigInteger[] k_E, int threadid, int nothreads) throws MathException { return () -> { log.debug("Verify A worker [{}/{}] started", threadid, nothreads); GroupElement right = h[0].getGroup().getIdentity(); for (int i = 0; i < h.length; i++) { if (i % nothreads != threadid) continue; right = right.op(h[i].scale(k_E[i])); progress.increase(1); } log.debug("Verify A worker [{}/{}] finished", threadid, nothreads); return right; }; } private boolean verify_B(Progress progress, BigInteger v, GroupElement[] B, GroupElement[] B_prim, GroupElement g, BigInteger[] k_B, BigInteger[] k_E, GroupElement[] h, int nothreads, ExecutorService executor) throws MathException, InterruptedException, ExecutionException { // the number of computations is different in threaded and non-threaded case. In threaded // case the thread which sees invalid proof stops and this is propagated to the controlling // thread. In non-threaded case, all values are computed and then checked one-by-one. GroupElement left = B[0].scale(v).op(B_prim[0]); GroupElement right = h[0].scale(k_E[0]).op(g.scale(k_B[0])); if (!left.equals(right)) { return false; } log.debug("Verified first B value"); List> futures = new ArrayList<>(); for (int i = 0; i < nothreads; i++) { FutureTask ft = new FutureTask<>( get_verify_B_worker(progress, v, B, B_prim, g, k_B, k_E, h, i, nothreads)); executor.submit(ft); futures.add(ft); } log.debug("Started verify B workers"); log.debug("Collecting verify B worker results"); for (Future ft : futures) { if (!ft.get()) { return false; } progress.increase(1); log.debug("Collected verify B worker result"); } log.debug("Collected all verify B worker results"); return true; } private static Callable get_verify_B_worker(Progress progress, BigInteger v, GroupElement[] B, GroupElement[] B_prim, GroupElement g, BigInteger[] k_B, BigInteger[] k_E, GroupElement[] h, int threadid, int nothreads) { return () -> { log.debug("Verify B worker [{}/{}] started", threadid, nothreads); GroupElement left, right; for (int i = 1; i < B.length; i++) { if (i % nothreads != threadid) continue; left = B[i].scale(v).op(B_prim[i]); right = B[i - 1].scale(k_E[i]); right = right.op(g.scale(k_B[i])); progress.increase(1); if (!left.equals(right)) { log.debug("Verify B worker [{}/{}] finished early", threadid, nothreads); return false; } } log.debug("Verify B worker [{}/{}] finished", threadid, nothreads); return true; }; } private boolean verify_F(Progress progress, BigInteger v, GroupElement F, GroupElement F_prim, GroupElement pk, BigInteger[] k_E, BigInteger[] k_F, GroupElement[] w_prim, int nothreads, ExecutorService executor) throws MathException, InterruptedException, ExecutionException { // the number of computations differ in threaded and non-threaded case. In threaded case we // also aggregate the per-thread results. List> futures = new ArrayList<>(); for (int i = 0; i < nothreads; i++) { FutureTask ft = new FutureTask<>(get_verify_F_worker(progress, k_E, w_prim, i, nothreads)); executor.submit(ft); futures.add(ft); } log.debug("Started verify F workers"); BigInteger[] factors = new BigInteger[k_F.length]; for (int i = 0; i < factors.length; i++) { factors[i] = k_F[i].negate(); progress.increase(1); } GroupElement left = F.scale(v).op(F_prim); GroupElement right = w_prim[0].getGroup().getIdentity(); log.debug("Collecting verify F worker results"); for (Future ft : futures) { right = right.op(ft.get()); progress.increase(1); log.debug("Collected verify F worker result"); } log.debug("Collected all verify F worker results"); ProductGroupElement pkl = (ProductGroupElement) ((ProductGroupElement) pk).getElements()[0]; ProductGroupElement pkr = (ProductGroupElement) ((ProductGroupElement) pk).getElements()[1]; ProductGroupElement tmpl = pkl.scale(factors); progress.increase(1); ProductGroupElement tmpr = pkr.scale(factors); progress.increase(1); ProductGroupElement tmp = new ProductGroupElement((ProductGroup) pk.getGroup(), tmpl, tmpr); right = right.op(tmp); progress.increase(1); return left.equals(right); } private static Callable get_verify_F_worker(Progress progress, BigInteger[] k_E, GroupElement[] w_prim, int threadid, int nothreads) { return () -> { log.debug("Verify F worker [{}/{}] started", threadid, nothreads); GroupElement right = w_prim[0].getGroup().getIdentity(); for (int i = 0; i < w_prim.length; i++) { if (i % nothreads != threadid) continue; right = right.op(w_prim[i].scale(k_E[i])); progress.increase(1); } log.debug("Verify F worker [{}/{}] finished", threadid, nothreads); return right; }; } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/shuffle/Verifier.java ================================================ package ee.ivxv.audit.shuffle; import ee.ivxv.audit.shuffle.ByteTree.Leaf; import ee.ivxv.audit.shuffle.ByteTree.Node; import ee.ivxv.audit.shuffle.ShuffleConsole.ShuffleStep; import ee.ivxv.common.math.*; import ee.ivxv.common.service.console.Progress; import ee.ivxv.common.util.Util; import java.io.IOException; import java.math.BigInteger; import java.util.function.Supplier; /** * Verificatum proof of a shuffle verifier. *

* See the Verificatum manual for implementing independent verifier for the explanation of the * variables used in the verifier. */ public class Verifier { protected final ShuffleProof proof; protected final ShuffleConsole console; /** * Initialize the verifier using proof of a shuffle. * * @param proof */ public Verifier(ShuffleProof proof) { this.console = null; this.proof = proof; } public Verifier(ShuffleConsole console, ShuffleProof proof) { this.console = console; this.proof = proof; } public ShuffleProof get_proof() { return proof; } /** * See: * globalPrefix * * @return */ public byte[] compute_rho() { ProtocolInformation p = proof.get_ProtocolInformation(); String fullsid = String.format("%s.%s", p.get_sid(), p.get_auxsid()); Node n = new Node(new ByteTree[]{ new Leaf(p.get_version()), new Leaf(fullsid), new Leaf(Util.toBytes(p.get_statdist())), new Leaf(Util.toBytes(p.get_vbitlenro())), new Leaf(Util.toBytes(p.get_ebitlenro())), new Leaf(p.get_prg()), new Leaf(p.get_pgroup()), new Leaf(p.get_rohash()) }); return DataParser.getHash(p.get_rohash()).digest(n.getEncoded()); } /** * See: * prgSeed * * @param rho * @param h * @return */ public byte[] compute_RO_seed(byte[] rho, GroupElement[] h) { ProductGroupElement publickey = (ProductGroupElement) get_proof().get_publickey(); ProtocolInformation p = proof.get_ProtocolInformation(); GroupElement generator = get_proof().get_ProtocolInformation().get_parsed_generator(); String pgroup = p.get_pgroup(); ByteTree[] nodes; ByteTree generatorNode; if (pgroup.contains("ECqPGroup")) { generatorNode = new Node((ECGroupElement) generator); } else { generatorNode = new Leaf(generator); } nodes = new ByteTree[]{ generatorNode, new Node(h), new Node(get_proof().get_PermutationCommitment().get_u()), new Node(publickey), new Node(DataParser.toArray(get_proof().get_ciphertexts()).getElements()), new Node(DataParser.toArray(get_proof().get_shuffled_ciphertexts()).getElements()) }; Node node = new Node(nodes); RO ro = new RO(get_proof().get_ProtocolInformation().get_rohash()); byte[] out = new byte[DataParser.getHash(get_proof().get_ProtocolInformation().get_prg()).getDigestLength()]; ro.setAmount(out.length * 8); try { ro.write(rho); node.writeEncoded(ro); } catch (IOException e) { // checked } ro.read(out, out.length * 8); return out; } /** * See: * e * * @param s * @return */ public BigInteger[] compute_e(byte[] s) { PRNG gen = new PRNG(get_proof().get_ProtocolInformation().get_prg(), s); int n_e = get_proof().get_ProtocolInformation().get_ebitlenro(); int N = get_proof().get_ciphertexts().length; BigInteger[] scalars = new BigInteger[N]; BigInteger mask = BigInteger.ONE.shiftLeft(n_e); for (int i = 0; i < N; i++) { byte[] ti = new byte[(n_e + 7) / 8]; gen.read(ti); scalars[i] = new BigInteger(1, ti).mod(mask); } return scalars; } /** * For ECGroup see: * ec * For ModpGroup see: * modp * * @param rho * @return */ public GroupElement[] compute_h(byte[] rho) { Group G_q = get_proof().get_ProtocolInformation().get_parsed_pgroup(); BigInteger p = get_proof().get_ProtocolInformation().get_parsed_pgroup().getOrder(); int n_r = get_proof().get_ProtocolInformation().get_statdist(); int n_p = p.bitLength(); int N = get_proof().get_ciphertexts().length; String prg = get_proof().get_ProtocolInformation().get_prg(); String rohash = get_proof().get_ProtocolInformation().get_rohash(); Leaf l = new Leaf("generators"); byte[] seed = new byte[rho.length + l.getEncodedLength()]; System.arraycopy(rho, 0, seed, 0, rho.length); System.arraycopy(l.getEncoded(), 0, seed, rho.length, l.getEncodedLength()); @SuppressWarnings("resource") RO ro = new RO(rohash, seed); byte[] out = new byte[DataParser.getHash(prg).getDigestLength()]; ro.read(out, out.length * 8); PRNG gen = new PRNG(prg, out); GroupElement[] elements = new GroupElement[N]; BigInteger mask = BigInteger.ONE.shiftLeft(n_p + n_r); if (G_q instanceof ECGroup) { // Each dprg.get() invocation produces new byte array Supplier dprg = () -> { byte[] rand = new byte[(n_p + n_r + 7) / 8]; gen.read(rand); return new BigInteger(1, rand).mod(mask).toByteArray(); }; elements = new ECGroup().pseudoRandomElements(N, dprg); } else { BigInteger TWO = BigInteger.valueOf(2); for (int i = 0; i < N; i++) { byte[] rand = new byte[(n_p + n_r + 7) / 8]; gen.read(rand); BigInteger value = new BigInteger(1, rand).mod(mask).modPow(TWO, p); elements[i] = new ModPGroupElement((ModPGroup) G_q, value); } } return elements; } /** * See: * v * * @param rho * @param s * @return */ public BigInteger compute_v(byte[] rho, byte[] s) { GroupElement A_prim = get_proof().get_PoSCommitment().get_A_prim(); GroupElement C_prim = get_proof().get_PoSCommitment().get_C_prim(); GroupElement D_prim = get_proof().get_PoSCommitment().get_D_prim(); int n_v = get_proof().get_ProtocolInformation().get_vbitlenro(); ByteTree aPrim, cPrim, dPrim; if (get_proof().get_ProtocolInformation().get_pgroup().contains("ECqPGroup")) { aPrim = new Node((ECGroupElement) A_prim); cPrim = new Node((ECGroupElement) C_prim); dPrim = new Node((ECGroupElement) D_prim); } else { aPrim = new Leaf(A_prim); cPrim = new Leaf(C_prim); dPrim = new Leaf(D_prim); } ByteTree[] nodes = new ByteTree[]{ new Node(get_proof().get_PoSCommitment().get_B()), aPrim, new Node(get_proof().get_PoSCommitment().get_B_prim()), cPrim, dPrim, new Node(get_proof().get_PoSCommitment().get_F_prim()) }; Node n = new Node(new ByteTree[]{new Leaf(s), new Node(nodes)}); byte[] seed = new byte[rho.length + n.getEncodedLength()]; System.arraycopy(rho, 0, seed, 0, rho.length); System.arraycopy(n.getEncoded(), 0, seed, rho.length, n.getEncodedLength()); @SuppressWarnings("resource") RO ro = new RO(get_proof().get_ProtocolInformation().get_rohash(), seed); byte[] out = new byte[(n_v + 7) / 8]; ro.read(out, n_v); return new BigInteger(1, out); } /** * See: * A * * @param progress * @param e * @return * @throws MathException */ public GroupElement compute_A(Progress progress, BigInteger[] e) throws MathException { GroupElement[] u = get_proof().get_PermutationCommitment().get_u(); GroupElement res = u[0].getGroup().getIdentity(); for (int i = 0; i < u.length; i++) { res = res.op(u[i].scale(e[i])); progress.increase(1); } return res; } /** * See: * C * * @param progress * @param h * @return * @throws MathException * @throws ShuffleException */ public GroupElement compute_C(Progress progress, GroupElement[] h) throws MathException, ShuffleException { GroupElement[] u = get_proof().get_PermutationCommitment().get_u(); if (u.length != h.length) { throw new ShuffleException("u and h length does not match"); } GroupElement up = u[0].getGroup().getIdentity(); GroupElement hp = h[0].getGroup().getIdentity(); for (int i = 0; i < u.length; i++) { up = u[i].op(up); hp = h[i].op(hp); progress.increase(1); } GroupElement hpi = hp.inverse(); GroupElement res = up.op(hpi); progress.increase(2); return res; } /** * See: * D * * @param progress * @param h * @param e * @return * @throws ShuffleException * @throws MathException */ public GroupElement compute_D(Progress progress, GroupElement[] h, BigInteger[] e) throws ShuffleException, MathException { BigInteger ep = BigInteger.ONE; BigInteger q; int N = get_proof().get_ciphertexts().length; if (h[0] instanceof ModPGroupElement) { ModPGroup group = (ModPGroup) h[0].getGroup(); q = MathUtil.safePrimeOrder(group.getOrder()); } else if (h[0] instanceof ECGroupElement) { q = h[0].getGroup().getOrder(); } else { throw new ShuffleException("Unknown element type: " + h[0].getClass().getSimpleName()); } for (BigInteger bigInteger : e) { ep = ep.multiply(bigInteger).mod(q); progress.increase(1); } GroupElement hp = h[0].scale(ep); hp = hp.inverse(); GroupElement ret = get_proof().get_PoSCommitment().get_B()[N - 1].op(hp); progress.increase(3); return ret; } /** * See: * F * * @param progress * @param e * @return * @throws MathException */ public GroupElement compute_F(Progress progress, BigInteger[] e) throws MathException { GroupElement[] w = get_proof().get_ciphertexts(); GroupElement res = w[0].getGroup().getIdentity(); for (int i = 0; i < w.length; i++) { GroupElement exped = w[i].scale(e[i]); res = res.op(exped); progress.increase(1); } return res; } /** * See: * verdictA * * @param progress * @param v * @param A * @param h * @param e * @return * @throws MathException */ public boolean verify_A(Progress progress, BigInteger v, GroupElement A, GroupElement[] h) throws MathException { GroupElement left = A.scale(v).op(get_proof().get_PoSCommitment().get_A_prim()); progress.increase(1); GroupElement right = h[0].getGroup().getIdentity(); for (int i = 0; i < h.length; i++) { right = right.op(h[i].scale(get_proof().get_PoSReply().get_kE()[i])); progress.increase(1); } right = get_proof().get_ProtocolInformation().get_parsed_generator() .scale(get_proof().get_PoSReply().get_kA()) .op(right); progress.increase(1); return left.equals(right); } /** * See: * verdictB * * @param progress * @param v * @param h * @return * @throws MathException */ public boolean verify_B(Progress progress, BigInteger v, GroupElement[] h) throws MathException { GroupElement[] B = get_proof().get_PoSCommitment().get_B(); GroupElement[] Bp = get_proof().get_PoSCommitment().get_B_prim(); BigInteger[] kB = get_proof().get_PoSReply().get_kB(); BigInteger[] kE = get_proof().get_PoSReply().get_kE(); GroupElement g = get_proof().get_ProtocolInformation().get_parsed_generator(); for (int i = 1; i < B.length; i++) { GroupElement left = B[i].scale(v).op(Bp[i]); GroupElement right = B[i - 1].scale(kE[i]).op(g.scale(kB[i])); if (!left.equals(right)) { return false; } progress.increase(1); } return true; } /** * See: * verdictC * * @param progress * @param v * @param C * @return * @throws MathException */ public boolean verify_C(Progress progress, BigInteger v, GroupElement C) throws MathException { GroupElement left = C.scale(v).op(get_proof().get_PoSCommitment().get_C_prim()); progress.increase(1); GroupElement right = get_proof().get_ProtocolInformation().get_parsed_generator() .scale(get_proof().get_PoSReply().get_kC()); progress.increase(1); return left.equals(right); } /** * See: * verdictD * * @param progress * @param v * @param D * @return * @throws MathException */ public boolean verify_D(Progress progress, BigInteger v, GroupElement D) throws MathException { GroupElement left = D.scale(v).op(get_proof().get_PoSCommitment().get_D_prim()); progress.increase(1); GroupElement right = get_proof().get_ProtocolInformation().get_parsed_generator() .scale(get_proof().get_PoSReply().get_kD()); progress.increase(1); return left.equals(right); } /** * See: * verdictF * * @param progress * @param v * @param F * @return * @throws MathException */ public boolean verify_F(Progress progress, BigInteger v, GroupElement F) throws MathException { // the number of computations differ in threaded and non-threaded case. In threaded case we // also aggregate the per-thread results. GroupElement pk = get_proof().get_publickey(); BigInteger[] kF = get_proof().get_PoSReply().get_kF(); GroupElement[] wp = get_proof().get_shuffled_ciphertexts(); BigInteger[] kE = get_proof().get_PoSReply().get_kE(); GroupElement Fp = get_proof().get_PoSCommitment().get_F_prim(); GroupElement left = F.scale(v).op(Fp); GroupElement right = wp[0].getGroup().getIdentity(); for (int i = 0; i < wp.length; i++) { right = right.op(wp[i].scale(kE[i])); progress.increase(1); } BigInteger[] factors = new BigInteger[kF.length]; for (int i = 0; i < factors.length; i++) { factors[i] = kF[i].negate(); progress.increase(1); } ProductGroupElement pkl = (ProductGroupElement) ((ProductGroupElement) pk).getElements()[0]; ProductGroupElement pkr = (ProductGroupElement) ((ProductGroupElement) pk).getElements()[1]; ProductGroupElement tmpl = pkl.scale(factors); progress.increase(1); ProductGroupElement tmpr = pkr.scale(factors); progress.increase(1); ProductGroupElement tmp = new ProductGroupElement((ProductGroup) pk.getGroup(), tmpl, tmpr); right = right.op(tmp); progress.increase(1); return left.equals(right); } /** * Verify the correctness of the shuffle. *

* Throws an exception specifying the reason for failed verification. * * @return Boolean True if the proof verifies. If not, then an exception is thrown. * @throws ShuffleException If the verification fails, denoting a reason. * @throws MathException If computation fails. */ public boolean verify_all() throws ShuffleException, MathException { console.enter(ShuffleStep.VERIFY); console.enter(ShuffleStep.VERIFY_PARAMS); byte[] rho = compute_rho(); GroupElement[] h = compute_h(rho); console.enter(ShuffleStep.VERIFY_NI); byte[] s = compute_RO_seed(rho, h); BigInteger[] e = compute_e(s); BigInteger v = compute_v(rho, s); int N = get_proof().get_ciphertexts().length; Progress progress = console.enter(ShuffleStep.VERIFY_PERM, 5 * N + 11); GroupElement A = compute_A(progress, e); GroupElement C = compute_C(progress, h); GroupElement D = compute_D(progress, h, e); if (!verify_A(progress, v, A, h)) { throw new ShuffleException("A failed"); } if (!verify_B(progress, v, h)) { throw new ShuffleException("B failed"); } if (!verify_C(progress, v, C)) { throw new ShuffleException("C failed"); } if (!verify_D(progress, v, D)) { throw new ShuffleException("D failed"); } progress.finish(); progress = console.enter(ShuffleStep.VERIFY_RERAND, 2 * N + get_proof().get_PoSReply().get_kF().length + 3); GroupElement F = compute_F(progress, e); if (!verify_F(progress, v, F)) { throw new ShuffleException("F failed"); } progress.finish(); return true; } /** * Verify the correctness of the shuffle. *

* If {@literal throwexception} is false, then now exceptions are thrown during computation and * verification. * * @param throwexception Boolean in * @return Boolean indicating the correctness of the shuffle. */ public boolean verify_all(boolean throwexception) { try { return verify_all(); } catch (ShuffleException | MathException e) { if (!throwexception) { return false; } } return true; } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/tools/ConvertTool.java ================================================ package ee.ivxv.audit.tools; import ee.ivxv.audit.AuditContext; import ee.ivxv.audit.Msg; import ee.ivxv.audit.shuffle.DataParser; import ee.ivxv.audit.shuffle.ShuffleConsole; import ee.ivxv.audit.shuffle.ShuffleProof; import ee.ivxv.audit.tools.ConvertTool.ConvertArgs; import ee.ivxv.common.cli.Arg; import ee.ivxv.common.cli.Args; import ee.ivxv.common.cli.Tool; import ee.ivxv.common.crypto.Plaintext; import ee.ivxv.common.crypto.elgamal.ElGamalCiphertext; import ee.ivxv.common.crypto.elgamal.ElGamalPublicKey; import ee.ivxv.common.math.Group; import ee.ivxv.common.math.GroupElement; import ee.ivxv.common.math.MathException; import ee.ivxv.common.math.ProductGroup; import ee.ivxv.common.math.ProductGroupElement; import ee.ivxv.common.model.AnonymousBallotBox; import ee.ivxv.common.util.I18nConsole; import ee.ivxv.common.util.Json; import java.nio.file.Path; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.helpers.NOPLogger; /** * ConvertTool verifies the correctness of file format conversions. */ public class ConvertTool implements Tool.Runner { public static class ConvertArgs extends Args { Arg inputBbox = Arg.aPath(Msg.arg_input_bb); Arg outputBbox = Arg.aPath(Msg.arg_output_bb); Arg pubPath = Arg.aPath(Msg.arg_pub); Arg protPath = Arg.aPath(Msg.arg_protinfo, true, false); Arg proofPath = Arg.aPath(Msg.arg_proofdir, true, true); public ConvertArgs() { super(); args.add(inputBbox); args.add(outputBbox); args.add(pubPath); args.add(protPath); args.add(proofPath); } } // we use static NOP logger to be able to run tests without logging // the logger is patched in non-test context private static Logger log = NOPLogger.NOP_LOGGER; private I18nConsole console; public ConvertTool(AuditContext ctx) { this.console = new I18nConsole(ctx.i.console, ctx.i.i18n); // patch the static logger. It is a single-instance class, so there are not any race // conditions. ConvertTool.log = LoggerFactory.getLogger(ConvertTool.class); } @Override public boolean run(ConvertArgs args) throws Exception { boolean ret = true; log.debug("Reading shuffle proof"); ShuffleConsole sc = new ShuffleConsole(this.console); ShuffleProof proof = new ShuffleProof(args.protPath.value(), args.proofPath.value(), sc); log.debug("Reading pre-shuffle ballot box"); AnonymousBallotBox bb = Json.read(args.inputBbox.value(), AnonymousBallotBox.class); log.debug("Reading post-shuffle ballot box"); AnonymousBallotBox sbb = Json.read(args.outputBbox.value(), AnonymousBallotBox.class); log.debug("Reading public key"); ElGamalPublicKey pk = new ElGamalPublicKey(args.pubPath.value()); if (!verifyPublickey(pk, proof)) { console.println(Msg.m_convert_publickey_failed); ret = false; } else { console.println(Msg.m_convert_publickey_succ); } if (!verifyBallotboxToBytetree(pk, bb, proof)) { console.println(Msg.m_convert_bb_to_bt_failed); ret = false; } else { console.println(Msg.m_convert_bb_to_bt_succ); } if (!verifyBytetreeToBallotbox(pk, proof, sbb)) { console.println(Msg.m_convert_bt_to_bb_failed); ret = false; } else { console.println(Msg.m_convert_bt_to_bb_succ); } return ret; } public static boolean verifyPublickey(ElGamalPublicKey pk, ShuffleProof proof) { log.debug("Verifying public key correct converting"); log.debug("Getting shuffle proof public key"); GroupElement btpk = proof.get_publickey(); log.debug("Converting public key to bytetree format"); GroupElement gppk = convertPublickeyToBytetree(pk); boolean res = btpk.equals(gppk); log.debug("Shuffle proof public key == converted public key: {}", res); return res; } public static boolean verifyBallotboxToBytetree(ElGamalPublicKey pk, AnonymousBallotBox bb, ShuffleProof proof) { log.debug("Verifying ballot box to bytetree converting"); log.debug("Getting shuffle ciphertext list"); GroupElement[] proofciphs = proof.get_ciphertexts(); log.debug("Converting ballot box to byte tree format"); GroupElement[] bbciphs; try { bbciphs = convertBallotboxToBytetree(pk, bb); } catch (IllegalArgumentException e) { log.debug("Converting ballot box to bytetree cipherexts failed: {}", e); return false; } if (bbciphs.length != proofciphs.length) { log.debug("Ballot box and shuffle ciphertext list size differ"); return false; } for (int i = 0; i < bbciphs.length; i++) { if (!bbciphs[i].equals(proofciphs[i])) { log.debug("Ballot box element and shuffle ciphertext item '{}' differ", i); return false; } } log.debug("Shuffle proof ciphertexts == ballot box: true"); return true; } public static boolean verifyBytetreeToBallotbox(ElGamalPublicKey pk, ShuffleProof proof, AnonymousBallotBox bb) { log.debug("Verifying bytetree to ballot box converting"); log.debug("Converting shuffle ciphertext list to ballot box"); AnonymousBallotBox proofbb; try { proofbb = convertBytetreeToBallotbox(pk, proof.get_shuffled_ciphertexts()); } catch (IllegalArgumentException e) { log.debug("Converting bytetree to ballot box failed: {}", e); return false; } if (!bb.getElection().equals(proofbb.getElection())) { log.debug("Converted ballot box and ballot box election identifier differ. " + "Expected '{}', got '{}'", bb.getElection(), proofbb.getElection()); return false; } Map>>> proofd = proofbb.getDistricts(); Map>>> bbd = bb.getDistricts(); if (!proofd.keySet().equals(bbd.keySet())) { log.debug("Converted ballot box and ballot box district identifier set differ"); return false; } for (String d : proofd.keySet()) { Map>> proofs = proofd.get(d); Map>> bbs = bbd.get(d); if (!proofs.keySet().equals(bbs.keySet())) { log.debug("Converted ballot box and ballot box station identifier set differ " + "for district '{}'", d); return false; } for (String s : proofs.keySet()) { Map> proofq = proofs.get(s); Map> bbq = bbs.get(s); if (!proofq.keySet().equals(bbq.keySet())) { log.debug("Converted ballot box and ballot box question identifier set differ " + "for district '{}' and station '{}'", d, s); return false; } for (String q : proofq.keySet()) { List proofc = proofq.get(q); List bbc = bbq.get(q); if (proofc.size() != bbc.size()) { log.debug( "Converted ballot box and ballot box ciphertext list differ " + "for district '{}', station '{}' and question '{}'", d, s, q); return false; } for (int i = 0; i < proofc.size(); i++) { if (!Arrays.equals(proofc.get(i), bbc.get(i))) { log.debug("Converted ballot box and ballot box ciphertext differ for " + "district '{}', station '{}', question '{}' and " + "index '{}'", d, s, q, i); return false; } } } } } return true; } private static GroupElement[] convertBallotboxToBytetree(ElGamalPublicKey pk, AnonymousBallotBox bb) throws IllegalArgumentException { List res = new ArrayList(); ProductGroupElement ege = convertStringToProductGroupElement(pk, bb.getElection()); bb.getDistricts().forEach((d, smap) -> { ProductGroupElement dge = convertStringToProductGroupElement(pk, d); smap.forEach((s, qmap) -> { ProductGroupElement sge = convertStringToProductGroupElement(pk, s); qmap.forEach((q, clist) -> { ProductGroupElement qge = convertStringToProductGroupElement(pk, q); clist.forEach(c -> { ElGamalCiphertext ct = new ElGamalCiphertext(pk.getParameters(), c); ProductGroupElement cge = ct.getAsProductGroupElement(); ProductGroupElement multict = DataParser .toArray(new ProductGroupElement[] {ege, dge, sge, qge, cge}); res.add(multict); }); }); }); }); return res.toArray(new ProductGroupElement[0]); } private static ProductGroupElement convertStringToProductGroupElement(ElGamalPublicKey pk, String msg) throws IllegalArgumentException { Group G = pk.getParameters().getGroup(); Plaintext padded = G.pad(new Plaintext(msg)); GroupElement ge; try { ge = G.encode(padded); } catch (MathException e) { throw new IllegalArgumentException("Encoding failed", e); } ProductGroup pG = new ProductGroup(G, 2); ProductGroupElement pge = new ProductGroupElement(pG, G.getIdentity(), ge); return pge; } private static AnonymousBallotBox convertBytetreeToBallotbox(ElGamalPublicKey pk, GroupElement[] cts) throws IllegalArgumentException { Map>>> res = new LinkedHashMap>>>(); String election = null; for (int i = 0; i < cts.length; i++) { if (!(cts[i] instanceof ProductGroupElement)) { throw new IllegalArgumentException( String.format("Ciphertext %d not ProductGroupElement", i)); } ProductGroupElement multict = (ProductGroupElement) cts[i]; if (multict.getElements().length != 2) { throw new IllegalArgumentException(String.format("Ciphertext %d length not 2", i)); } if (!(multict.getElements()[0] instanceof ProductGroupElement)) { throw new IllegalArgumentException( String.format("Ciphertext %d left side not PGE", i)); } if (((ProductGroupElement) multict.getElements()[0]).getElements().length != 5) { throw new IllegalArgumentException( String.format("Ciphertext %d left side length not 5", i)); } if (!(multict.getElements()[1] instanceof ProductGroupElement)) { throw new IllegalArgumentException( String.format("Ciphertext %d right side not PGE", i)); } if (((ProductGroupElement) multict.getElements()[1]).getElements().length != 5) { throw new IllegalArgumentException( String.format("Ciphertext %d right side length not 5", i)); } String thiselection = convertProductGroupElementToString(pk, multict, 0); if (election == null) { election = thiselection; } if (!election.equals(thiselection)) { throw new IllegalArgumentException(String .format("Ciphertext %d election differs. Expected '%s', got '%s'", i)); } String district = convertProductGroupElementToString(pk, multict, 1); String station = convertProductGroupElementToString(pk, multict, 2); String question = convertProductGroupElementToString(pk, multict, 3); GroupElement blind = ((ProductGroupElement) multict.getElements()[0]).getElements()[4]; GroupElement blindedMessage = ((ProductGroupElement) multict.getElements()[1]).getElements()[4]; ElGamalCiphertext cc = new ElGamalCiphertext(blind, blindedMessage, pk.getParameters().getOID()); res.computeIfAbsent(district, x -> new LinkedHashMap<>()) .computeIfAbsent(station, x -> new LinkedHashMap<>()) .computeIfAbsent(question, x -> new ArrayList()).add(cc.getBytes()); } AnonymousBallotBox bb = new AnonymousBallotBox(election, res); return bb; } private static String convertProductGroupElementToString(ElGamalPublicKey pk, ProductGroupElement pge, int index) throws IllegalArgumentException { GroupElement[] els = pge.getElements(); GroupElement msgenc = ((ProductGroupElement) els[1]).getElements()[index]; Plaintext padded = pk.getParameters().getGroup().decode(msgenc); Plaintext pt = pk.getParameters().getGroup().unpad(padded); String msg = pt.getUTF8DecodedMessage(); return msg; } private static GroupElement convertPublickeyToBytetree(ElGamalPublicKey pk) { ProductGroupElement pkpg = pk.getAsProductGroupElement(); ProductGroupElement gpg = new ProductGroupElement((ProductGroup) pkpg.getGroup(), pk.getParameters().getGenerator(), pk.getParameters().getGroup().getIdentity()); ProductGroupElement res = DataParser.toArray(new ProductGroupElement[] {gpg, gpg, gpg, gpg, pkpg}); return res; } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/tools/DecryptTool.java ================================================ package ee.ivxv.audit.tools; import ee.ivxv.audit.AuditContext; import ee.ivxv.audit.Msg; import ee.ivxv.audit.model.PlainBallotBox; import ee.ivxv.audit.model.Tally; import ee.ivxv.audit.tools.DecryptTool.DecryptArgs; import ee.ivxv.audit.util.DiscardedBallot; import ee.ivxv.audit.util.InvalidDecProofs; import ee.ivxv.common.M; import ee.ivxv.common.cli.Arg; import ee.ivxv.common.cli.Args; import ee.ivxv.common.cli.Tool; import ee.ivxv.common.crypto.Plaintext; import ee.ivxv.common.crypto.elgamal.ElGamalCiphertext; import ee.ivxv.common.crypto.elgamal.ElGamalDecryptionProof; import ee.ivxv.common.crypto.elgamal.ElGamalPublicKey; import ee.ivxv.common.math.Group; import ee.ivxv.common.math.GroupElement; import ee.ivxv.common.math.MathException; import ee.ivxv.common.model.AnonymousBallotBox; import ee.ivxv.common.model.CandidateList; import ee.ivxv.common.model.DistrictList; import ee.ivxv.common.model.Proof; import ee.ivxv.common.service.bbox.impl.BboxHelperImpl; import ee.ivxv.common.service.console.Progress; import ee.ivxv.common.util.I18nConsole; import ee.ivxv.common.util.Json; import ee.ivxv.common.util.ToolHelper; import ee.ivxv.common.util.Util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.commons.collections4.Bag; import org.apache.commons.collections4.bag.HashBag; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; import java.util.concurrent.*; import java.util.function.Consumer; import java.util.stream.Collectors; /** * Tool for verifying the correctness and consistency of ciphertext decryption. */ public class DecryptTool implements Tool.Runner { private final Logger log = LoggerFactory.getLogger(DecryptTool.class); private final AuditContext ctx; private final I18nConsole console; private final ToolHelper tool; public DecryptTool(AuditContext ctx) { this.ctx = ctx; this.console = new I18nConsole(ctx.i.console, ctx.i.i18n); tool = new ToolHelper(console, ctx.container, new BboxHelperImpl(ctx.conf, ctx.container)); } @Override public boolean run(DecryptArgs args) throws Exception { // Verify whether all provided files are found on the filesystem. boolean allFilesExist = verifyInputFiles(args); if (!allFilesExist) { console.println(); return false; } boolean abortEarly = args.abortEarly.value(); boolean verifyInvalid = Objects.nonNull(args.invalidInputPath.value()); boolean allChecksPassed = true; DistrictList districts = tool.readJsonDistricts(args.districts.value()); CandidateList candidates = tool.readJsonCandidates(args.candidates.value(), districts); console.println(); console.println(Msg.m_anon_loading, args.anonBoxPath.value()); // The anonymous ballot box will subsequently be mutated! AnonymousBallotBox anonBb = Json.read(args.anonBoxPath.value(), AnonymousBallotBox.class); console.println(Msg.m_anon_loaded); console.println(); console.println(Msg.m_pub_loading, args.pubPath.value()); ElGamalPublicKey pub = new ElGamalPublicKey(args.pubPath.value()); console.println(Msg.m_pub_loaded); // Use bags since it might be that there are multiple identical ciphertexts. // While these occurrences are suspicious and should be flagged, the flagging is done by // the integrity tool, not the decrypt tool. Bag vProofCiphers = new HashBag<>(); // from proofs of ballot validity Bag iProofCiphers = new HashBag<>(); // from proofs of ballot invalidity // For privacy reasons, these proofs might not exist: their generation is optional. if (verifyInvalid) { Proof proofs = tool.readJsonProofs(args.invalidInputPath.value()); // Cryptographically verify proofs and get the base64 encoded invalid ballots. boolean allCorrect = processVerification(proofs, pub, ctx.args.threads.value(), args.outputPath.value(), false, iProofCiphers); if (!allCorrect && abortEarly) { printFailure(); return true; } else allChecksPassed = allCorrect; // Verify invalidity: plaintexts are indeed invalid. // Verify consistency: all ciphertexts in the proof file have a counterpart in the anonymous BB. // If this step becomes a performance bottleneck, it could be combined with the previous check. // Currently, the checks are separate for implementation clarity. // Note! Mutates the anonymous ballot box: removes ciphertexts of invalid votes from it. boolean areConsistent = verifyPlaintexts(pub, anonBb, proofs, candidates, false); if (!areConsistent && abortEarly) { printFailure(); return true; } else allChecksPassed = allChecksPassed && areConsistent; } Proof proofs = tool.readJsonProofs(args.inputPath.value()); // Cryptographically verify proofs and get the base64 encoded valid ballots. boolean allCorrect = processVerification(proofs, pub, ctx.args.threads.value(), args.outputPath.value(), true, vProofCiphers); if (!allCorrect && abortEarly) { printFailure(); return true; } else allChecksPassed = allChecksPassed && allCorrect; // Verify validity: plaintexts are indeed valid. // Verify consistency: all ciphertexts in the proof file have a counterpart in the anonymous BB. // If this step becomes a performance bottleneck, it could be combined with the previous check. // Currently, the checks are separate for implementation clarity. // Note! Mutates the anonymous ballot box: removes ciphertexts of valid votes from it. boolean areConsistent = verifyPlaintexts(pub, anonBb, proofs, candidates, true); if (!areConsistent && abortEarly) { printFailure(); return true; } else allChecksPassed = allChecksPassed && areConsistent; // Get the ciphertexts deemed invalid. // The file must always be provided, even if there are none: the file then contains none. Bag discardedCiphers = getDiscardedCiphers(args.discardedInputPath.value()); if (verifyInvalid) { // Verify whether the invalidity proofs are consistent with the ciphertexts declared invalid: // - all ciphertexts in the proofs file must have a counterpart in the invalids file // - all ciphertexts in the invalids file must have a counterpart in the proofs file boolean consistentInvalids = verifyInvalidConsistency(discardedCiphers, iProofCiphers); console.println(Msg.m_decrypt_consistent_invalids, getYesNoMessage(consistentInvalids)); if (!consistentInvalids && abortEarly) { printFailure(); return true; } else allChecksPassed = allChecksPassed && consistentInvalids; } else { // If the invalidity proofs are not provided, verify whether all ciphertexts declared invalid // have a counterpart in the anonymous BB. This is already done if the proofs are provided. // Note! Mutates the anonymous ballot box: removes ciphertexts of invalid votes from it. boolean invalidsInBb = verifyCiphersInBb(anonBb, discardedCiphers); console.println(Msg.m_decrypt_bb_has_invalids, getYesNoMessage(invalidsInBb)); if (!invalidsInBb && abortEarly) { printFailure(); return true; } else allChecksPassed = allChecksPassed && invalidsInBb; } // Verify that no ciphertext is declared both valid and invalid. console.println(); boolean disjointOutputs = Collections.disjoint(vProofCiphers, discardedCiphers); console.println(Msg.m_decrypt_one_per_file, getYesNoMessage(disjointOutputs)); if (!disjointOutputs && abortEarly) { printFailure(); return true; } else allChecksPassed = allChecksPassed && disjointOutputs; // The anonymous BB should now be empty if it is consistent with the proof files: // all ciphertexts in the anonymous BB then have a counterpart in the proof files. // If only validity proofs were provided, the counterparts were checked through the invalid // ciphertexts file. // The converse consistency has already been verified, i.e. that all ciphertexts have a // counterpart in the anonymous BB. // In summary, if the following check passes, then: anon bb = valid ciphertexts + invalid ciphertexts boolean abbIsEmpty = isAnonBBEmpty(anonBb); console.println(Msg.m_decrypt_dec_consistent, getYesNoMessage(abbIsEmpty)); if (!abbIsEmpty && abortEarly) { printFailure(); return true; } else allChecksPassed = allChecksPassed && abbIsEmpty; // Get the plaintext ballot box. console.println(); console.println(Msg.m_plain_loading, args.plainBoxPath.value()); PlainBallotBox plainBb = Json.read(args.plainBoxPath.value(), PlainBallotBox.class); console.println(Msg.m_plain_loaded); // Verify whether the plaintext ballot box is consistent with the plaintexts in the proofs file: // - all plaintexts in the proofs file must have a counterpart in the plaintext ballot box // - all entries in the plaintext ballot box must have a counterpart in the proofs file // - the number of invalid votes should be consistent // If this step becomes a performance bottleneck, it should be somehow combined with the // validity proof verification stage. boolean consistentValids = verifyValidConsistency(pub, proofs, plainBb, discardedCiphers.size()); console.println(Msg.m_decrypt_consistent_valids, getYesNoMessage(consistentValids)); if (!consistentValids && abortEarly) { printFailure(); return true; } else allChecksPassed = allChecksPassed && consistentValids; console.println(); // Verify whether the plaintext ballot box matches with the computed tally. boolean tallyValid = verifyTally(plainBb, args.tallyPath.value()); console.println(Msg.m_tally_match, getYesNoMessage(tallyValid)); if (!tallyValid && abortEarly) { printFailure(); return true; } else allChecksPassed = allChecksPassed && tallyValid; console.println(); if (allChecksPassed) console.println(Msg.m_decrypt_success); else console.println(Msg.m_decrypt_failure); console.println(); return true; } private Msg getYesNoMessage(boolean success) { if (success) return Msg.m_yes; return Msg.m_no; } private void printFailure() { console.println(); console.println(Msg.m_decrypt_failure); console.println(); } private boolean isAnonBBEmpty(AnonymousBallotBox abb) { boolean isEmpty = true; for (Map>> smap : abb.getDistricts().values()) { for (Map> qmap : smap.values()) { for (List clist : qmap.values()) { if (clist.isEmpty()) continue; isEmpty = false; for (byte[] c : clist) { String b64ct = Base64.getEncoder().encodeToString(c); log.warn("Output files missing ballot: {}", b64ct); } } } } return isEmpty; } /** * Parses the file of discarded ciphertexts and extracts them. * * @param path the path of the file containing discarded ciphertexts * @return a bag of base64-encoded ciphertexts * @throws Exception If the file cannot be read or parsed */ private Bag getDiscardedCiphers(Path path) throws Exception { Bag discardedCTs = new HashBag<>(); console.println(); console.println(Msg.m_discarded_loading, path); DiscardedBallot discarded = Json.read(path, DiscardedBallot.class); console.println(Msg.m_discarded_loaded); console.println(Msg.m_discarded_count, discarded.getCount()); discarded.getDiscarded().forEach(vote -> discardedCTs.add(Base64.getEncoder().encodeToString(vote.getVote()))); return discardedCTs; } /** * Verifies the proofs of correct decryption. *

* Additionally, verifies whether the decrypted results indeed are valid or invalid, * thus confirming whether proofs are valid proofs of validity or invalidity. * Collects also the base64-encoded ciphertexts for subsequent audit operations. * * @param proofs the decryption proofs * @param pub the election public key * @param threadCount the number of threads to use for processing * @param outPath the directory where to output verification failures * @param validityProofs whether the proofs prove validity or invalidity of ballots * @param b64CTs the bag where to store base64-encoded ciphertexts * @return true if all proofs verify, false otherwise * @throws Exception If the verification process cannot complete */ private boolean processVerification(Proof proofs, ElGamalPublicKey pub, int threadCount, Path outPath, boolean validityProofs, Bag b64CTs) throws Exception { console.println(); console.println(Msg.m_verify_start); InvalidDecProofs invalid = verifyDecryption(proofs, pub, threadCount, b64CTs); console.println(Msg.m_verify_finish); console.println(Msg.m_failurecount, invalid.getCount()); if (invalid.getCount() == 0) return true; console.println(M.m_out_start, outPath); if (!Files.exists(outPath)) Files.createDirectory(outPath); if (validityProofs) invalid.outputFailedProofsOfValidity(outPath); else invalid.outputFailedProofsOfInvalidity(outPath); console.println(M.m_out_done, outPath); return false; } /** * Verifies whether plaintexts in a proof file really are valid/invalid. *

* Mutates the anonymous ballot box: removes ciphertexts for which it has * checked the plaintext. This speeds up subsequent verifications and keeps * track of the verification status. * * @param pub the election public key * @param abb the anonymous ballot box * @param proofs the proof file * @param candidates the list of accepted candidates * @param expectedValid whether the plaintexts should be valid or invalid * @return the result of the checks */ private boolean verifyPlaintexts(ElGamalPublicKey pub, AnonymousBallotBox abb, Proof proofs, CandidateList candidates, boolean expectedValid) { // Using a set is fine here even if there are repetitions since we have already verified the proofs: // inconsistent repetitions should no longer be possible. Map votes = new HashMap<>(); // However, we still need to keep track of how many duplications there are when we compare with the // ballot box later. Bag multiples = new HashBag<>(); // Get all ciphertext-message pairs. for (Proof.ProofJson proof : proofs.getProofs()) { String b64 = Base64.getEncoder().encodeToString(proof.getCiphertext()); GroupElement old = votes.put(b64, pub.getParameters().getGroup().getElement(proof.getMessage())); if (Objects.isNull(old)) continue; // not a duplicate if (!multiples.contains(b64)) multiples.add(b64, 2); // add two the first time else multiples.add(b64); } boolean allCorrect = true; for (Map.Entry>>> districtMap : abb.getDistricts().entrySet()) { for (Map> sMap : districtMap.getValue().values()) { for (List cList : sMap.values()) { Iterator i = cList.iterator(); while (i.hasNext()) { byte[] c = i.next(); String b64 = Base64.getEncoder().encodeToString(c); GroupElement decrypted = votes.remove(b64); multiples.remove(b64); if (Objects.isNull(decrypted)) continue; Group group = pub.getParameters().getGroup(); Plaintext decoded = group.decode(decrypted); Plaintext unpadded = group.unpad(decoded); boolean isValid = isValidChoice(unpadded, districtMap.getKey(), candidates); if (isValid != expectedValid) { log.warn("Plaintext is declared {} but is not: {}", expectedValid ? "valid" : "invalid", unpadded.getUTF8DecodedMessage()); } allCorrect = allCorrect && (isValid == expectedValid); i.remove(); } } } } // Verify whether all proof file entries were indeed in the anonymous ballot box. boolean allInBb = votes.isEmpty() && multiples.isEmpty(); if (!allInBb) { log.warn("There were {} ballots missing from the input ballot box:", votes.size() + multiples.size()); logMissingBallots(votes.keySet()); logMissingBallots(multiples); } if (expectedValid) console.println(Msg.m_decrypt_verified_valid, getYesNoMessage(allCorrect)); else console.println(Msg.m_decrypt_verified_invalid, getYesNoMessage(allCorrect)); console.println(Msg.m_decrypt_bb_has_proofs, getYesNoMessage(allInBb)); return allCorrect && allInBb; } private boolean verifyTally(PlainBallotBox pbb, Path tallyPath) throws Exception { console.println(Msg.m_tally_loading, tallyPath); Tally tally = Json.read(tallyPath, Tally.class); console.println(Msg.m_tally_loaded); boolean electionMatches = tally.getElection().equals(pbb.election()); if (!electionMatches) { log.warn("The tally is for election '{}' while the plaintext ballot box is for election '{}'", tally.getElection(), pbb.election()); return false; } boolean parishesMatch = tally.getByParish().keySet().equals(pbb.byParish().keySet()); if (!parishesMatch) { log.warn("Parishes do not match between the tally and the plaintext ballot box"); return false; } // This iteration is comprehensive since the parish sets must now be equal. for (Map.Entry>> parishMap : pbb.byParish().entrySet()) { String parishId = parishMap.getKey(); Map> districtVotes = parishMap.getValue(); Map> parishDistricts = tally.getByParish().get(parishId); boolean districtsMatch = parishDistricts.keySet().equals(districtVotes.keySet()); if (!districtsMatch) { log.warn("Districts do not match between the tally and the plaintext ballot box"); return false; } // This iteration is comprehensive since the district sets must now be equal. for (Map.Entry> votesMap : districtVotes.entrySet()) { // The plaintext votes for that district. List votes = votesMap.getValue(); // Counter the (choice, count) pairs from the plaintext BB entry. Map counts = votes.stream() .collect(Collectors.groupingBy(c -> c, Collectors.summingInt(c -> 1))); // The tallied (choice, count) pairs. Create a copy to avoid mutation. Map tallyCounts = new LinkedHashMap<>(parishDistricts.get(votesMap.getKey())); for (Map.Entry count : counts.entrySet()) { // The tally counts must match the count obtained from the plaintext BB. if (!tallyCounts.remove(count.getKey()).equals(count.getValue())) { log.warn("Plaintext ballot box and tally mismatch for the choice '{}'", count.getKey()); return false; } } // Whatever choice is present in the tally map should now have 0 votes. // The plaintext BB choices have already been checked for validity. for (Integer val : tallyCounts.values()) { if (val != 0) { log.warn("Vote count > 0 for a choice not present in the plaintext ballot box"); return false; } } } } // We have checked the byParish tally. The byDistrict tally must also be checked. // Since byParish is valid, simply check whether the byDistrict tally obtained // from the byParish tally matches with the byDistrict tally read form the tally. return tally.getByDistrict().equals(tally.computeByDistrict()); } private boolean isValidChoice(Plaintext pt, String district, CandidateList candidates) { String candidateCode; try { candidateCode = pt.getUTF8DecodedMessage(); } catch (IllegalArgumentException ignored) { return false; } // Get choices list Map>> ds = candidates.getCandidates(); // Ensure that vote district exists in a choices list if (!ds.containsKey(district)) { return false; } // Get choices for a specific district (district that vote belongs to) Map> ps = ds.get(district); // Ensure that there are choices per that district if (ps.isEmpty()) { return false; } // Loop over all choices per that district for (Map parties : ps.values()) { // Is there a candidate code that matches candidateCode if (parties.containsKey(candidateCode)) { return true; } } // Choice is not valid return false; } private InvalidDecProofs verifyDecryption(Proof input, ElGamalPublicKey pub, int threadCount, Bag b64CTs) throws Exception { InvalidDecProofs idp = new InvalidDecProofs(input.getElection()); ExecutorService ioExecutor = Executors.newFixedThreadPool(2); CompletionService CompService = new ExecutorCompletionService<>(ioExecutor); ExecutorService verifyExecutor; threadCount = threadCount > 0 ? threadCount : 1; verifyExecutor = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(threadCount * 2)); WorkManager manager = new WorkManager(input, getVerifyConsumer(pub, idp, b64CTs), verifyExecutor, idp); CompService.submit(manager); CompService.submit(idp.getResultWorker()); try { for (int done = 0; done < 2; done++) { CompService.take().get(); } } finally { ioExecutor.shutdown(); verifyExecutor.shutdown(); } return idp; } private Consumer getVerifyConsumer(ElGamalPublicKey pub, InvalidDecProofs out, Bag b64CTs) { return (proofJson) -> { GroupElement decrypted = pub.getParameters().getGroup().getElement(proofJson.getMessage()); ElGamalCiphertext ct = new ElGamalCiphertext(pub.getParameters(), proofJson.getCiphertext()); ElGamalDecryptionProof proof = new ElGamalDecryptionProof(ct, decrypted, pub, proofJson.getProof()); // Get the base64-encoded ballot for later comparison with the ballot box. b64CTs.add(Base64.getEncoder().encodeToString(proofJson.getCiphertext())); try { boolean res = proof.verifyProof(); if (!res) { log.warn("Proof verification failed: {}", proof); out.addInvalidProof(proof); } } catch (MathException e) { log.warn("Proof verification exception: {}, {}", proof, e); out.addInvalidProof(proof); } }; } /** * Verifies whether ciphertexts are part of the anonymous ballot box. * * @param abb the anonymous ballot box * @param b64CTs the base64-encoded ciphertexts to check inclusion for * @return true if all the ciphertexts are included, false otherwise */ private boolean verifyCiphersInBb(AnonymousBallotBox abb, Bag b64CTs) { // Do not mutate the ciphers. Bag b64copy = new HashBag<>(b64CTs); for (Map>> sMap : abb.getDistricts().values()) { for (Map> qMap : sMap.values()) { for (List cList : qMap.values()) { Iterator i = cList.iterator(); while (i.hasNext()) { byte[] c = i.next(); String b64ct = Base64.getEncoder().encodeToString(c); if (!b64copy.remove(b64ct, 1)) continue; i.remove(); } } } } // Verify whether all entries were indeed in the anonymous ballot box. boolean allInBb = b64copy.isEmpty(); if (!allInBb) { log.warn("There were {} ballots missing from the input ballot box:", b64copy.size()); logMissingBallots(b64copy); } return allInBb; } private boolean verifyInvalidConsistency(Bag discardedCiphers, Bag iProofCiphers) { if (iProofCiphers.equals(discardedCiphers)) return true; // Create copies to avoid mutating inputs. Bag iProofCopy = new HashBag<>(iProofCiphers); Bag discardedCopy = new HashBag<>(discardedCiphers); // Obtain the differences and log them. iProofCopy.removeAll(discardedCiphers); discardedCopy.removeAll(iProofCiphers); log.warn("There were {} ballots missing from the discarded votes file:", iProofCopy.size()); logMissingBallots(iProofCopy); log.warn("There were {} ballots missing from the invalid proofs:", discardedCopy.size()); logMissingBallots(discardedCopy); return false; } private void logMissingBallots(Collection b64CTs) { for (String b64ct : b64CTs) log.warn("Missing ballot: {}", b64ct); } /** * Verifies plaintext ballot box consistency with the validity proofs. *

* Carries out the verification solely based on the choice identifier, and not * on the complete plaintext vote. The full validation of plaintexts in the proofs * file must be carried out beforehand for stronger consistency guarantees. * * @param pub the election public key * @param proofs the validity proofs * @param pbb the plaintext ballot box * @param invalidCount the number of expected invalid votes * @return true if the verification succeeds, false otherwise */ private boolean verifyValidConsistency(ElGamalPublicKey pub, Proof proofs, PlainBallotBox pbb, int invalidCount) { Bag plainVotes = new HashBag<>(pbb.byDistrict().values().stream() .flatMap(Collection::stream).toList()); console.println(Msg.m_plain_count, plainVotes.size()); console.println(); console.println(Msg.m_decrypt_consistent_valids_begin); boolean noExtra = true; try { for (Proof.ProofJson proof : proofs.getProofs()) { GroupElement decrypted = pub.getParameters().getGroup().getElement(proof.getMessage()); Group group = decrypted.getGroup(); Plaintext decoded = group.decode(decrypted); // Note! Here we do not validate the full vote, meaning that the validation // should be done prior to calling this function. String voteCode = group.unpad(decoded).getUTF8DecodedMessage(); if (plainVotes.remove(voteCode, 1)) continue; noExtra = false; log.warn("A vote for {} is missing from the plaintext ballot box", voteCode); } } catch (Exception e) { // Barring software errors, this can happen only if // the proofs file is manipulated/corrupted. log.error(e.toString()); return false; } // There were proofs for votes not present in the plaintext BB. if (!noExtra) { log.warn("There were proofs for votes not present in the plaintext ballot box"); return false; } // We have checked the byDistrict votes. The byParish votes must also be checked. // Since byDistrict is valid, simply check whether the byDistrict votes obtained // from the byParish votes matches with the byDistrict votes read form the plaintext BB. boolean tallyConsistent = pbb.byDistrict().equals(pbb.computeByDistrict()); if (!tallyConsistent) { log.warn("byparish inconsistent with bydistrict in the plaintext ballot box"); return false; } return plainVotes.size() == invalidCount; } private boolean verifyInputFiles(DecryptArgs args) { List paths = new ArrayList<>(List.of( args.inputPath.value(), args.pubPath.value(), args.discardedInputPath.value(), args.anonBoxPath.value(), args.plainBoxPath.value(), args.tallyPath.value(), args.districts.value(), args.candidates.value())); if (Objects.nonNull(args.invalidInputPath.value())) paths.add(args.invalidInputPath.value()); for (Path path : paths) { if (Files.notExists(path)) { console.println(); console.println(Msg.e_file_missing, path); return false; } } return true; } public static class DecryptArgs extends Args { Arg inputPath = Arg.aPath(Msg.arg_proofs); Arg invalidInputPath = Arg.aPath(Msg.arg_invalidity_proofs).setOptional(); Arg pubPath = Arg.aPath(Msg.arg_pub); Arg anonBoxPath = Arg.aPath(Msg.arg_anon_bb); Arg plainBoxPath = Arg.aPath(Msg.arg_plain_bb); Arg tallyPath = Arg.aPath(Msg.arg_tally); Arg discardedInputPath = Arg.aPath(Msg.arg_discarded); Arg districts = Arg.aPath(Msg.arg_districts); Arg candidates = Arg.aPath(Msg.arg_candidates); Arg outputPath = Arg.aPath(Msg.arg_out, false, true); Arg abortEarly = Arg.aFlag(Msg.arg_abort_early).setDefault(true); public DecryptArgs() { super(); args.add(inputPath); args.add(pubPath); args.add(discardedInputPath); args.add(anonBoxPath); args.add(plainBoxPath); args.add(tallyPath); args.add(districts); args.add(candidates); args.add(outputPath); args.add(invalidInputPath); args.add(abortEarly); } } private class WorkManager implements Callable { private final Proof in; private final Consumer consumer; private final ExecutorService verifyExecutor; private final InvalidDecProofs idp; WorkManager(Proof in, Consumer consumer, ExecutorService verifyExecutor, InvalidDecProofs idp) { this.in = in; this.consumer = consumer; this.verifyExecutor = verifyExecutor; this.idp = idp; } @Override public Void call() throws Exception { Progress progress = console.startProgress(in.getCount()); in.getProofs().forEach(proof -> { boolean taskAdded = false; do { try { verifyExecutor.execute(() -> consumer.accept(proof)); taskAdded = true; } catch (RejectedExecutionException e) { try { Thread.sleep(20); } catch (InterruptedException e1) { log.warn("Unexpected interruption", e1); } } } while (!taskAdded); progress.increase(1); }); verifyExecutor.shutdown(); verifyExecutor.awaitTermination(1, TimeUnit.DAYS); idp.setEot(); progress.finish(); return null; } } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/tools/IntegrityTool.java ================================================ package ee.ivxv.audit.tools; import ee.ivxv.audit.AuditContext; import ee.ivxv.audit.Msg; import ee.ivxv.audit.tools.IntegrityTool.IntegrityArgs; import ee.ivxv.audit.util.RawBallotWithDigest; import ee.ivxv.common.cli.Arg; import ee.ivxv.common.cli.Args; import ee.ivxv.common.cli.Tool; import ee.ivxv.common.crypto.hash.HashType; import ee.ivxv.common.model.AnonymousBallotBox; import ee.ivxv.common.service.bbox.impl.FileSource; import ee.ivxv.common.service.bbox.impl.ZipSource; import ee.ivxv.common.service.bbox.impl.ZipSourceRaw; import ee.ivxv.common.service.console.Progress; import ee.ivxv.common.util.I18nConsole; import ee.ivxv.common.util.Json; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.commons.collections4.Bag; import org.apache.commons.collections4.bag.TreeBag; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.math.BigInteger; import java.nio.file.Files; import java.nio.file.Path; import java.util.*; public class IntegrityTool implements Tool.Runner { private static final String BDOC_EXTENSION = ".bdoc"; private static final String ASICE_EXTENSION = ".asice"; private static final String RAW_BALLOT_EXTENSION = ".ballot"; private static final Character DIR_SEP = '/'; private static final String EXPECTED_BALLOT_REF = "" + DIR_SEP + "+XXXX"; private static final String CSV_FIELD_SEPARATOR = "\t"; private static final int LOG_HASH_ENTRY_FIELDS = 5; private static final int BB_ERRORS_ENTRY_FIELDS = 3; private static final String BB_ERRORS_BALLOT_REGEX = "^\\d{11}/\\d+\\+\\d{4}$"; private final Logger log = LoggerFactory.getLogger(IntegrityTool.class); private final AuditContext ctx; private final I18nConsole console; public IntegrityTool(AuditContext ctx) { this.ctx = ctx; this.console = new I18nConsole(ctx.i.console, ctx.i.i18n); } @Override public boolean run(IntegrityArgs args) throws Exception { // Verify whether all provided files are found on the filesystem. boolean allFilesExist = verifyInputFiles(args); if (!allFilesExist) { console.println(); return false; } boolean abortEarly = args.abortEarly.value(); console.println(); console.println(Msg.m_bb_loading, args.bb.value()); List ballots = getBallots(args); console.println(Msg.m_bb_loaded); BigInteger checksumAll = sumBbHashes(ballots); console.println(); // Checksums of ballots in the processed ballot box. console.println(Msg.m_anon_loading, args.anonBoxPath.value()); AnonymousBallotBox anonBb = Json.read(args.anonBoxPath.value(), AnonymousBallotBox.class); AnonBbDigests anonDigests = getAnonBbDigests(anonBb); console.println(Msg.m_anon_loaded); console.println(); console.println(Msg.m_log_accepted, args.acceptedLogPath.value()); console.println(Msg.m_log_squashed, args.squashedLogPath.value()); console.println(Msg.m_log_revoked, args.revokedLogPath.value()); console.println(Msg.m_log_anonymised, args.anonLogPath.value()); console.println(Msg.m_bb_errors, args.bbErrorsPath.value()); console.println(); // Checksums of all accepted (valid received) ballots. List acceptedDigests = getBallotDigestsFromLog(args.acceptedLogPath.value()); BigInteger acceptedDigestsSum = sumHashes(acceptedDigests); Set erroredBallotNames = getErroredBallotsNames(args.bbErrorsPath.value()); BbDigests bbDigests = getValidInvalidSums(ballots, acceptedDigests, erroredBallotNames); if (bbDigests == null) { // This should happen only if ballots in the original ballot box appear in neither // the error log nor the accepted log. console.println(Msg.m_integrity_bb_consistent, getYesNoMessage(false)); if (abortEarly) { console.println(); return true; } } else { // This check should never fail but is here for clarity. // If true: accepted ballots in the original box are consistent with the log of accepted ballots. boolean validChecksumsMatch = bbDigests.validSum.equals(acceptedDigestsSum); // This check should never fail but is here for clarity. // If true: accepted ballots + refused ballots = original box. boolean sumIsConsistent = checksumAll.equals(bbDigests.invalidSum.add(bbDigests.validSum)); boolean bbIsConsistent = validChecksumsMatch && sumIsConsistent; console.println(Msg.m_integrity_bb_consistent, getYesNoMessage(bbIsConsistent)); if (!bbIsConsistent) { if (abortEarly) { console.println(); return true; } // Check if accepted ballots are included in the original box. // This provides more information on the inconsistency failure. boolean acceptedMatch = matchHashesToBb(acceptedDigests, ballots); console.println(Msg.m_integrity_match_valid, getYesNoMessage(acceptedMatch)); } } // Checksums of accepted ballots that were squashed. List squashedDigests = getBallotDigestsFromLog(args.squashedLogPath.value()); BigInteger squashedDigestsSum = sumHashes(squashedDigests); // Checksums of accepted ballots that were revoked. List revokedDigests = getBallotDigestsFromLog(args.revokedLogPath.value()); BigInteger revokedDigestsSum = sumHashes(revokedDigests); // Checksums of accepted ballots forwarded for tallying (remaining after squash + revoke). List anonLogDigests = getBallotDigestsFromLog(args.anonLogPath.value()); BigInteger anonLogDigestsSum = sumHashes(anonLogDigests); // If true: anon ballots are consistent with the log of anon ballots. boolean anonDigestMatches = anonDigests.checksumSum.equals(anonLogDigestsSum); console.println(Msg.m_integrity_match_anon_logs, getYesNoMessage(anonDigestMatches)); if (!anonDigestMatches && abortEarly) { console.println(); return true; } BigInteger postprocessDigestSum = squashedDigestsSum.add(revokedDigestsSum.add(anonLogDigestsSum)); // If true: anon + revoked + squashed = all accepted ballots. boolean acceptedDigestMatches = acceptedDigestsSum.equals(postprocessDigestSum); console.println(Msg.m_integrity_match_logs, getYesNoMessage(acceptedDigestMatches)); // If all checks succeed, the following audit trail is verified: // - anon BB matches with anon log // - invalid ballots (log) + valid ballots (log) = original BB // - anon ballots (log) + squashed ballots (log) + revoked ballots (log) = valid ballots (log) // Inferred: anon ballots are part of the original ballot box. console.println(); return true; } private Msg getYesNoMessage(boolean success) { if (success) return Msg.m_yes; return Msg.m_no; } private List getBallots(IntegrityArgs args) { List ballots = new ArrayList<>(); // Read ballot box FileSource zipContainer = new ZipSource(args.bb.value()); // Start progress, counting from 0 up to the amount of ballots in a ballot box int ballotCount = zipContainer.countFilesWithSuffix(Arrays.asList(BDOC_EXTENSION, ASICE_EXTENSION)); Progress progress = console.startProgress(ballotCount); // Read ballots from a ballot box one by one zipContainer.processFiles((fileName, fileContent) -> { // Only look for voter signed ballots if (fileName.contains(BDOC_EXTENSION) || fileName.contains(ASICE_EXTENSION)) { try { // Read voter signed container as byte stream FileSource signedContainer = new ZipSourceRaw(fileContent.readAllBytes()); // Signed container is a zip file, that contains files inside signedContainer.processFiles((ballotName, ballotContent) -> { // Only look for a ballot file if (ballotName.contains(RAW_BALLOT_EXTENSION)) { try { byte[] ballot = ballotContent.readAllBytes(); String ballotId = getBallotContainerId(fileName); ballots.add(new RawBallotWithDigest(ballot, ballotId)); } catch (Exception e) { throw new RuntimeException(e); } } }); } catch (IOException e) { throw new RuntimeException(e); } progress.increase(1); } }); progress.finish(); return ballots; } private static String getBallotContainerId(String fileName) throws Exception { // Getting the container path in the BB is necessary // for ballot identification through the error log. int i = fileName.lastIndexOf(DIR_SEP); if (i < 0) { // It's OK to throw since we can reasonably expect a valid ballot box. throw new Exception("Expected name " + EXPECTED_BALLOT_REF + " but got " + fileName); } int j = fileName.lastIndexOf(DIR_SEP, i - 1); int extensionLength = fileName.contains(BDOC_EXTENSION) ? BDOC_EXTENSION.length() : ASICE_EXTENSION.length(); String ballotContainerId = fileName.substring(j + 1, fileName.length() - extensionLength); if (!ballotContainerId.matches(BB_ERRORS_BALLOT_REGEX)) { throw new Exception("Expected name " + EXPECTED_BALLOT_REF + " but got " + fileName); } return ballotContainerId; } private BbDigests getValidInvalidSums(List bb, List acceptedDigests, Set invalidBallotIds) { BigInteger invalidBallotChecksumSum = BigInteger.ZERO; BigInteger validBallotChecksumSum = BigInteger.ZERO; // Use a tree bag since comparing arrays of bytes does not work in a regular bag. // We must use a bag instead of a set since it might happen (statistically unlikely unless intentional) // that there are ballots with the same ciphertext. Therefore, a set would not correctly represent the // state of the accepted ballots. // Use a tree bag since comparing arrays of bytes does not work in a regular bag. Bag digests = new TreeBag<>(Arrays::compare); digests.addAll(acceptedDigests); // Notify in case of multiple matching ciphertexts so that the occurrence(s) can be investigated further. int recurringCts = digests.size() - digests.uniqueSet().size(); if (recurringCts != 0) { console.println(Msg.m_integrity_recurring_ct); log.warn("There are {} ciphertext recurrences among the accepted ballots", recurringCts); Set recurringDigests = new HashSet<>(); for (byte[] c : digests) if (digests.getCount(c) != 1) recurringDigests.add(c); for (byte[] c : recurringDigests) log.warn("Recurring ballot: {}", Base64.getEncoder().encodeToString(c)); console.println(); } // Avoid mutating the input set. These are IDs so they must be unique. Set invalids = new HashSet<>(invalidBallotIds); boolean errored = false; for (RawBallotWithDigest ballot : bb) { // Make sure that each ballot is referenced in exactly one file. int seenCount = 0; if (invalids.remove(ballot.getId())) { invalidBallotChecksumSum = invalidBallotChecksumSum.add(new BigInteger(1, ballot.getRawDigest())); ++seenCount; } if (digests.remove(ballot.getRawDigest(), 1)) { validBallotChecksumSum = validBallotChecksumSum.add(new BigInteger(1, ballot.getRawDigest())); ++seenCount; } if (seenCount == 0) { log.warn("Ballot '{}' not found in the acceptance/rejection logs", ballot.getId()); errored = true; } if (seenCount > 1) { log.warn("Ballot '{}' present in both the acceptance and rejection logs", ballot.getId()); errored = true; } } if (errored) return null; // Make sure that there are not more log entries than there are ballots in the BB. if (!digests.isEmpty() || !invalids.isEmpty()) { for (String invalid : invalids) log.warn("Ballot '{}' is missing from the original ballot box", invalid); for (byte[] digest : digests) log.warn("Missing from the original ballot box: {}", Base64.getEncoder().encodeToString(digest)); return null; } return new BbDigests(invalidBallotChecksumSum, validBallotChecksumSum); } /** * Reads the digests from a processor logfile. * * @param path the logfile path * @return a list of digests extracted from the logfile * @throws Exception If the logfile does not exist or cannot be properly read */ private List getBallotDigestsFromLog(Path path) throws Exception { List hashes = new ArrayList<>(); BufferedReader br = new BufferedReader(new FileReader(path.toFile())); String line; while ((line = br.readLine()) != null) { String[] values = line.split(CSV_FIELD_SEPARATOR); if (values.length != LOG_HASH_ENTRY_FIELDS) continue; byte[] hash = Base64.getDecoder().decode(values[1]); hashes.add(hash); } return hashes; } /** * Reads ballot identifiers from the ballot validation error report. * * @param path the report path * @return a set of ballot identifiers extracted from the report * @throws Exception If the report cannot be found be read */ private Set getErroredBallotsNames(Path path) throws Exception { // Use a set since there may be multiple errors pertaining to the // same ballot in the log. Set erroredBallotNames = new HashSet<>(); BufferedReader br = new BufferedReader(new FileReader(path.toFile())); String line; while ((line = br.readLine()) != null) { String[] values = line.split(CSV_FIELD_SEPARATOR); if (values.length != BB_ERRORS_ENTRY_FIELDS) continue; if (!values[0].matches(BB_ERRORS_BALLOT_REGEX)) continue; erroredBallotNames.add(values[0]); } return erroredBallotNames; } private static BigInteger sumHashes(List hashes) { BigInteger sum = BigInteger.ZERO; for (byte[] hash : hashes) { sum = sum.add(new BigInteger(1, hash)); } return sum; } private static BigInteger sumBbHashes(List bb) { BigInteger sum = BigInteger.ZERO; for (RawBallotWithDigest ballot : bb) { sum = sum.add(new BigInteger(1, ballot.getRawDigest())); } return sum; } private AnonBbDigests getAnonBbDigests(AnonymousBallotBox bb) { // Also extract checksums in a list to avoid looping again later. List digests = new ArrayList<>(); BigInteger sum = BigInteger.ZERO; for (Map>> smap : bb.getDistricts().values()) { for (Map> qmap : smap.values()) { for (List clist : qmap.values()) { for (byte[] c : clist) { byte[] hash = HashType.SHA256.getFunction().digest(c); digests.add(hash); sum = sum.add(new BigInteger(1, hash)); } } } } return new AnonBbDigests(digests, sum); } /** * Verifies whether digests correspond to ballots in a ballot box. * * @param digests the digests of some set of ballots * @param bb the ballot box to match against * @return whether all ballots were present in the box */ private boolean matchHashesToBb(List digests, List bb) { boolean allOk = true; // Potential perf improvement: would it be faster to iterate over the full ballot box // and try to remove them from a set of digests? The return value is then whether // the set is empty. During normal execution this should never be invoked in any case. for (byte[] digest : digests) { boolean matches = bb.stream().anyMatch(b -> Arrays.equals(digest, b.getRawDigest())); if (!matches) { log.warn("Missing from the original ballot box: {}", Base64.getEncoder().encodeToString(digest)); allOk = false; } } return allOk; } record BbDigests(BigInteger invalidSum, BigInteger validSum) { } record AnonBbDigests(List digests, BigInteger checksumSum) { } private boolean verifyInputFiles(IntegrityArgs args) { List paths = new ArrayList<>(List.of( args.bb.value(), args.anonBoxPath.value(), args.acceptedLogPath.value(), args.squashedLogPath.value(), args.revokedLogPath.value(), args.anonLogPath.value(), args.bbErrorsPath.value())); for (Path path : paths) { if (Files.notExists(path)) { console.println(); console.println(Msg.e_file_missing, path); return false; } } return true; } public static class IntegrityArgs extends Args { Arg bb = Arg.aPath(Msg.arg_ballotbox, true, false); Arg anonBoxPath = Arg.aPath(Msg.arg_anon_bb); Arg acceptedLogPath = Arg.aPath(Msg.arg_log_accepted); Arg squashedLogPath = Arg.aPath(Msg.arg_log_squashed); Arg revokedLogPath = Arg.aPath(Msg.arg_log_revoked); Arg anonLogPath = Arg.aPath(Msg.arg_log_anonymised); Arg bbErrorsPath = Arg.aPath(Msg.arg_bb_errors); Arg abortEarly = Arg.aFlag(Msg.arg_abort_early).setDefault(true); public IntegrityArgs() { super(); args.add(bb); args.add(anonBoxPath); args.add(acceptedLogPath); args.add(squashedLogPath); args.add(revokedLogPath); args.add(anonLogPath); args.add(bbErrorsPath); args.add(abortEarly); } } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/tools/MixerTool.java ================================================ package ee.ivxv.audit.tools; import ee.ivxv.audit.AuditContext; import ee.ivxv.audit.Msg; import ee.ivxv.audit.shuffle.ShuffleConsole; import ee.ivxv.audit.shuffle.ShuffleException; import ee.ivxv.audit.shuffle.ShuffleProof; import ee.ivxv.audit.shuffle.ThreadedVerifier; import ee.ivxv.audit.shuffle.Verifier; import ee.ivxv.audit.tools.MixerTool.MixerArgs; import ee.ivxv.common.cli.Arg; import ee.ivxv.common.cli.Args; import ee.ivxv.common.cli.Tool; import ee.ivxv.common.util.I18nConsole; import java.nio.file.Path; /** * Tool for verifying the correctness of the shuffle. */ public class MixerTool implements Tool.Runner { private final I18nConsole console; private AuditContext ctx; public static class MixerArgs extends Args { Arg protPath = Arg.aPath(Msg.arg_protinfo, true, false); Arg proofPath = Arg.aPath(Msg.arg_proofdir, true, true); Arg threaded = Arg.aFlag(Msg.arg_threaded); public MixerArgs() { super(); args.add(protPath); args.add(proofPath); args.add(threaded); } } public MixerTool(AuditContext ctx) { this.ctx = ctx; this.console = new I18nConsole(ctx.i.console, ctx.i.i18n); } @Override public boolean run(MixerArgs args) throws Exception { console.println(); console.println(Msg.m_shuffle_proof_loading, args.protPath.value(), args.proofPath.value()); ShuffleConsole sc = new ShuffleConsole(console); ShuffleProof proof = new ShuffleProof(args.protPath.value(), args.proofPath.value(), sc); Verifier ver; if (args.threaded.value()) { ver = new ThreadedVerifier(sc, proof, ctx.args.threads.value()); } else { ver = new Verifier(sc, proof); } boolean res = false; try { res = ver.verify_all(); } catch (ShuffleException e) { console.println(Msg.m_shuffle_proof_failed_reason, e); res = false; } if (res) { console.println(Msg.m_shuffle_proof_succeeded); } else { console.println(Msg.m_shuffle_proof_failed); } return res; } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/util/DiscardedBallot.java ================================================ package ee.ivxv.audit.util; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class DiscardedBallot { private final String election; private final List discarded; @JsonCreator public DiscardedBallot( @JsonProperty("election") String election, @JsonProperty("invalid") List invalid) { this.election = election; this.discarded = invalid; } public List getDiscarded() { return discarded; } @JsonIgnore public int getCount() { return discarded.size(); } public static class VoteJson { private final String district; private final String station; private final String question; private final byte[] vote; @JsonCreator private VoteJson( @JsonProperty("district") String district, @JsonProperty("station") String station, @JsonProperty("question") String question, @JsonProperty("vote") byte[] vote) { this.district = district; this.station = station; this.question = question; this.vote = vote; } public byte[] getVote() { return vote; } } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/util/InvalidDecProofs.java ================================================ package ee.ivxv.audit.util; import ee.ivxv.common.crypto.elgamal.ElGamalDecryptionProof; import ee.ivxv.common.model.Proof; import ee.ivxv.common.util.*; import java.nio.file.Path; import java.nio.file.Paths; import java.util.concurrent.BlockingQueue; import java.util.concurrent.Callable; import java.util.concurrent.LinkedBlockingQueue; /** * Class for handling ciphertexts with invalid proofs. */ public class InvalidDecProofs { private static final Path FAILED_PROOF_VALID_PATH = Paths.get("failed-validity"); private static final Path FAILED_PROOF_INVALID_PATH = Paths.get("failed-invalidity"); private final BlockingQueue in = new LinkedBlockingQueue<>(); private final Proof invalidProofs; /** * Initialize using the election identifier. * * @param electionName */ public InvalidDecProofs(String electionName) { invalidProofs = new Proof(electionName); } /** * Get the worker for parsing all added proofs. * * @return */ public InvalidProofHandler getResultWorker() { return new InvalidProofHandler(); } /** * Set the terminator after last added invalid proof. */ public void setEot() { in.add(ee.ivxv.common.util.Util.EOT); } /** * Add invalid proof. * * @param proof */ public void addInvalidProof(ElGamalDecryptionProof proof) { in.add(proof); } /** * Get the total number of invalid proofs. * * @return */ public int getCount() { return invalidProofs.getCount(); } /** * Serialize the structure to directory. * * @param outDir * @throws Exception */ public void outputFailedProofsOfValidity(Path outDir) throws Exception { Json.write(invalidProofs, outDir.resolve(FAILED_PROOF_VALID_PATH)); } /** * Serialize the structure to directory. * * @param outDir * @throws Exception */ public void outputFailedProofsOfInvalidity(Path outDir) throws Exception { Json.write(invalidProofs, outDir.resolve(FAILED_PROOF_INVALID_PATH)); } private class InvalidProofHandler implements Callable { @Override public Void call() throws Exception { Object obj; while ((obj = in.take()) != ee.ivxv.common.util.Util.EOT) { if (obj instanceof ElGamalDecryptionProof) { invalidProofs.addProof((ElGamalDecryptionProof) obj); } else { throw new IllegalArgumentException( "Unexpected decryption result type: " + obj.getClass()); } } return null; } } } ================================================ FILE: auditor/src/main/java/ee/ivxv/audit/util/RawBallotWithDigest.java ================================================ package ee.ivxv.audit.util; import ee.ivxv.common.crypto.hash.HashType; public class RawBallotWithDigest { private final String id; private final byte[] ballot; private final byte[] rawDigest; public RawBallotWithDigest(byte[] ballot, String id) { this.id = id; this.ballot = ballot; this.rawDigest = HashType.SHA256.getFunction().digest(ballot); } public String getId() { return this.id; } public byte[] getBallot() { return this.ballot; } public byte[] getRawDigest() { return this.rawDigest; } } ================================================ FILE: choices/.gitignore ================================================ bin/ pkg/ ================================================ FILE: choices/Makefile ================================================ include ../common/go/common.mk ================================================ FILE: choices/README.rst ================================================ ================================ IVXV Internet voting framework ================================ ----------------- Choices service ----------------- ================================================ FILE: choices/cmd/choiceimp/log_desc.go ================================================ package main const ( _CHOICES_VERSION_FROM_DB = "Cannot fetch choices list version from a database" _CHOICES_LIST_BDOC_OPEN = "Failed to open choices list BDOC container" _CHOICES_LIST_BDOC_NO_SIG = "No signatures found in choices list BDOC container" _CHOICES_LIST_BDOC_SIG_INFO = "Choices list BDOC container signature info" _CHOICES_LIST_BDOC_SIG_TO_JSON = "Failed to JSON marshal choices list BDOC container signature" _CHOICES_LIST_BDOC_HAS_MANY_FILES = "Choices list BDOC container should only have 1 file" _CHOICES_LIST_READ = "Reading choices list" _CHOICES_LIST_TO_DB_UPLOAD = "Failed to upload choices list to database" _CHOICES_LIST_INVALID_JSON = "Choices list has an invalid JSON format" _CHOICES_LIST_ID_MISMATCH = "Choices list ID doesn't match the one used in election configuration file" _CHOICES_LIST_PREPARE_UPLOAD_TO_DB = "Choices list is ready to uploaded into database" _CHOICES_LIST_UPLOAD_TO_DB_FAIL = "Unable to upload choices list to database" ) ================================================ FILE: choices/cmd/choiceimp/main.go ================================================ /* The choiceimp application is used for loading choice lists into the storage service. */ package main import ( "context" "encoding/json" "flag" "fmt" "os" "ivxv.ee/common/collector/command" "ivxv.ee/common/collector/command/exit" "ivxv.ee/common/collector/command/status" "ivxv.ee/common/collector/conf" "ivxv.ee/common/collector/conf/version" "ivxv.ee/common/collector/errors" "ivxv.ee/common/collector/log" "ivxv.ee/common/collector/storage" //ivxv:modules common/collector/container //ivxv:modules common/collector/storage ) const usage = `choiceimp loads choice lists into the collector's storage service for use by other services. The choice list container must have an extension corresponding to the container type it is, e.g., choicelist.bdoc.` var ( qp = flag.Bool("q", false, "quiet, do not show progress") progress *status.Line ) func main() { // Call choiceimpmain in a separate function so that it can set up // defers and have them trigger before returning with a non-zero exit // code. os.Exit(choiceimpmain()) } func choiceimpmain() (code int) { c := command.New("ivxv-choiceimp", usage, "choice list container") defer func() { code = c.Cleanup(code) }() if !*qp { progress = status.New() } // Only check the version if it was the specific check requested. if c.Until == command.CheckVersion { version1, err := c.Storage.GetChoicesVersion(c.Ctx) if err != nil { if errors.CausedBy(err, new(storage.NotExistError)) == nil { return c.Error(exit.Unavailable, CheckVersionError{Err: err, Description: _CHOICES_VERSION_FROM_DB}, "failed to check imported list version:", err) } } else { fmt.Println(version1) } } if c.Until < command.CheckInput { return exit.OK } path := c.Args[0] // Open the choice list container file. cnt, err := c.Conf.Container.OpenFile(path) if err != nil { code = exit.DataErr if perr := errors.CausedBy(err, new(os.PathError)); perr != nil { if os.IsNotExist(perr) { code = exit.NoInput } } return c.Error(code, OpenContainerError{Container: path, Err: err, Description: _CHOICES_LIST_BDOC_OPEN}, "failed to open choice list container:", err) } defer cnt.Close() // Ensure that the container is signed and log the signatures. signatures := cnt.Signatures() if len(signatures) == 0 { return c.Error(exit.DataErr, UnsignedContainerError{Container: path, Description: _CHOICES_LIST_BDOC_NO_SIG}, "unsigned choice list container") } for _, s := range signatures { log.Log(c.Ctx, ContainerSignature{Signer: s.Signer, SigningTime: s.SigningTime, Description: _CHOICES_LIST_BDOC_SIG_INFO}) } // Get the version string of the container. version1, err := version.Container(cnt) if err != nil { return c.Error(exit.DataErr, ContainerVersionError{Container: path, Err: err, Description: _CHOICES_LIST_BDOC_SIG_TO_JSON}, "failed to format container version string:", err) } // Check that the container only has a single file. data := cnt.Data() if len(data) != 1 { return c.Error(exit.DataErr, DataCountError{Count: len(data), Description: _CHOICES_LIST_BDOC_HAS_MANY_FILES}, "choice list container has", len(data), "files, expected 1") } // Process the choice list. We do not know the key, so do a single cycle loop. for key, list := range data { log.Log(c.Ctx, ProcessingList{List: key, Description: _CHOICES_LIST_READ}) if err := choiceimp(c.Ctx, c.Until, c.Conf, c.Storage, version1, list); err != nil { return c.Error(exit.Unavailable, ImportChoicesError{Err: err, Description: _CHOICES_LIST_TO_DB_UPLOAD}, "failed to import choice list", key+":", err) } } return exit.OK } type choicelist struct { Election string Choices map[string]json.RawMessage } // choiceimp parses the list of choices and uploads them to the storage // service. func choiceimp(ctx context.Context, until int, c *conf.C, s *storage.Client, version string, list []byte) error { var l choicelist if err := json.Unmarshal(list, &l); err != nil { return JSONUnmarshalError{Err: err, Description: _CHOICES_LIST_INVALID_JSON} } // Ensure that the election identifier matches the configured one. if l.Election != c.Election.Identifier { return ElectionIDMismatchError{Conf: c.Election.Identifier, List: l.Election, Description: _CHOICES_LIST_ID_MISMATCH} } if until >= command.Execute { // Convert map[string]json.RawMessage to map[string][]byte. choices := make(map[string][]byte) for id, list := range l.Choices { choices[id] = list } log.Log(ctx, ImportingChoices{Count: len(choices), Description: _CHOICES_LIST_PREPARE_UPLOAD_TO_DB}) progress.Static(fmt.Sprintf("Importing %d choices:", len(choices))) addprogress := progress.Percent(uint64(len(choices)), true) progress.Redraw() defer progress.Keep() if err := s.PutChoices(ctx, version, choices, addprogress); err != nil { return PutChoicesError{Err: err, Description: _CHOICES_LIST_UPLOAD_TO_DB_FAIL} } } return nil } ================================================ FILE: choices/cmd/districtimp/district_test.go ================================================ package main import ( "testing" "ivxv.ee/common/collector/errors" "ivxv.ee/common/collector/storage" ) func testDistrictsLookupFormatError(t *testing.T, id string) { t.Helper() list := districtlist{Districts: map[string]district{id: {}}} _, err := districtsLookup(list) if errors.CausedBy(err, new(DistrictIDFormatError)) == nil { t.Error("unexpected success with malformed district code", id) } } func TestDistrictsLookupFormatError(t *testing.T) { testDistrictsLookupFormatError(t, "0000") testDistrictsLookupFormatError(t, "0000.") testDistrictsLookupFormatError(t, ".0000") testDistrictsLookupFormatError(t, "0000.0.0") } func TestDistrictsLookupMultipleCodes(t *testing.T) { list := districtlist{ Districts: map[string]district{ "0001.1": { Parish: []string{"1111"}, }, "0002.2": { Parish: []string{"1111"}, }, }, } _, err := districtsLookup(list) if errors.CausedBy(err, new(ParishWithMultipleDistrictCodesError)) == nil { t.Error("unexpected success with multiple district codes") } } func assertDistricts(t *testing.T, districts map[string][]byte, adminCode, districtNr, districtID string) { t.Helper() encoded := storage.EncodeAdminDistrict(adminCode, districtNr) id, ok := districts[string(encoded)] if !ok { t.Error("unexpected error: administrative unit code", adminCode, "and district number", districtNr, "not in districts") } if string(id) != districtID { t.Errorf("unexpected district identifier for %s and %s: got %s, want %s", adminCode, districtNr, id, districtID) } } func TestDistrictsLookup(t *testing.T) { list := districtlist{ Districts: map[string]district{ // One-to-one match. "0001.1": { Parish: []string{"1111"}, }, // District with multiple parishes. "0002.1": { Parish: []string{"2222", "3333"}, }, // Parish with multiple districts. "0004.1": { Parish: []string{"4444"}, }, "0004.2": { Parish: []string{"4444"}, }, }, } districts, err := districtsLookup(list) if err != nil { t.Fatal(err) } assertDistricts(t, districts, "1111", "1", "0001.1") assertDistricts(t, districts, "2222", "1", "0002.1") assertDistricts(t, districts, "3333", "1", "0002.1") assertDistricts(t, districts, "4444", "1", "0004.1") assertDistricts(t, districts, "4444", "2", "0004.2") } ================================================ FILE: choices/cmd/districtimp/log_desc.go ================================================ package main const ( _DISTRICTS_VERSION_FROM_DB = "Cannot fetch districts list version from a database" _DISTRICTS_LIST_BDOC_OPEN = "Failed to open district list BDOC container" _DISTRICTS_LIST_BDOC_NO_SIG = "No signatures found in districts list BDOC container" _DISTRICTS_LIST_BDOC_SIG_INFO = "Districts list BDOC container signature info" _DISTRICTS_LIST_BDOC_SIG_TO_JSON = "Failed to JSON marshal districts list BDOC container signature" _DISTRICTS_LIST_BDOC_HAS_MANY_FILES = "Districts list BDOC container should only have 1 file" _DISTRICTS_LIST_READ = "Reading districts list" _DISTRICTS_LIST_TO_DB_UPLOAD = "Failed to upload districts list to database" _DISTRICTS_LIST_INVALID_JSON = "Choices list has an invalid JSON format" _DISTRICTS_LIST_ID_MISMATCH = "Choices list ID doesn't match the one used in election configuration file" _DISTRICTS_LIST_INVALID_COUNTIES_JSON = "District list has an invalid 'counties' JSON" _DISTRICTS_LIST_PREPARE_UPLOAD_TO_DB = "Choices list is ready to uploaded into database" _DISTRICTS_LIST_UPLOAD_TO_DB_FAIL = "Unable to upload districts list to database" _DISTRICTS_LIST_INVALID_DISTRICT_ID = "District ID has an invalid format" _DISTRICTS_LIST_PARISH_CONTAINS_SAME_DISTRICT_CODES = "Only 1 district code is allowed per parish" ) ================================================ FILE: choices/cmd/districtimp/main.go ================================================ /* The districtimp application is used for loading district lists into the storage service. */ package main import ( "context" "encoding/json" "flag" "fmt" "os" "strings" "ivxv.ee/common/collector/command" "ivxv.ee/common/collector/command/exit" "ivxv.ee/common/collector/command/status" "ivxv.ee/common/collector/conf" "ivxv.ee/common/collector/conf/version" "ivxv.ee/common/collector/errors" "ivxv.ee/common/collector/log" "ivxv.ee/common/collector/storage" //ivxv:modules common/collector/container //ivxv:modules common/collector/storage ) const usage = `districtimp loads district lists into the collector's storage service for use by other services. The district list container must have an extension corresponding to the container type it is, e.g., choicelist.bdoc.` var ( qp = flag.Bool("q", false, "quiet, do not show progress") progress *status.Line ) func main() { // Call districtimpmain in a separate function so that it can set up // defers and have them trigger before returning with a non-zero exit // code. os.Exit(districtimpmain()) } func districtimpmain() (code int) { c := command.New("ivxv-districtimp", usage, "district list container") defer func() { code = c.Cleanup(code) }() if !*qp { progress = status.New() } // Only check the version if it was the specific check requested. if c.Until == command.CheckVersion { version1, err := c.Storage.GetDistrictsVersion(c.Ctx) if err != nil { if errors.CausedBy(err, new(storage.NotExistError)) == nil { return c.Error(exit.Unavailable, CheckVersionError{Err: err, Description: _DISTRICTS_VERSION_FROM_DB, }, "failed to check imported list version:", err) } } else { fmt.Println(version1) } } if c.Until < command.CheckInput { return exit.OK } path := c.Args[0] // Open the district list container file. cnt, err := c.Conf.Container.OpenFile(path) if err != nil { code = exit.DataErr if perr := errors.CausedBy(err, new(os.PathError)); perr != nil { if os.IsNotExist(perr) { code = exit.NoInput } } return c.Error(code, OpenContainerError{Container: path, Err: err, Description: _DISTRICTS_LIST_BDOC_OPEN}, "failed to open district list container:", err) } defer cnt.Close() // Ensure that the container is signed and log the signatures. signatures := cnt.Signatures() if len(signatures) == 0 { return c.Error(exit.DataErr, UnsignedContainerError{Container: path, Description: _DISTRICTS_LIST_BDOC_NO_SIG}, "unsigned districts list container") } for _, s := range signatures { log.Log(c.Ctx, ContainerSignature{Signer: s.Signer, SigningTime: s.SigningTime, Description: _DISTRICTS_LIST_BDOC_SIG_INFO}) } // Get the version string of the container. version1, err := version.Container(cnt) if err != nil { return c.Error(exit.DataErr, ContainerVersionError{Container: path, Err: err, Description: _DISTRICTS_LIST_BDOC_SIG_TO_JSON}, "failed to format container version string:", err) } // Check that the container only has a single file. data := cnt.Data() if len(data) != 1 { return c.Error(exit.DataErr, DataCountError{Count: len(data), Description: _DISTRICTS_LIST_BDOC_HAS_MANY_FILES}, "districts list container has", len(data), "files, expected 1") } // Process the district list. We do not know the key, so do a single cycle loop. for key, list := range data { log.Log(c.Ctx, ProcessingList{List: key, Description: _DISTRICTS_LIST_READ}) if err := districtimp(c.Ctx, c.Until, c.Conf, c.Storage, version1, list); err != nil { return c.Error(exit.Unavailable, ImportDistrictsError{Err: err, Description: _DISTRICTS_LIST_TO_DB_UPLOAD}, "failed to import district list", key+":", err) } } return exit.OK } type districtlist struct { Election string Districts map[string]district Counties json.RawMessage } type district struct { Name string Parish []string } // districtimp parses the districts list and uploads data from it to the // storage service. func districtimp(ctx context.Context, until int, c *conf.C, s *storage.Client, version string, list []byte) error { var l districtlist if err := json.Unmarshal(list, &l); err != nil { return JSONUnmarshalError{Err: err, Description: _DISTRICTS_LIST_INVALID_JSON} } // Ensure that the election identifier matches the configured one. if l.Election != c.Election.Identifier { return ElectionIDMismatchError{Conf: c.Election.Identifier, List: l.Election, Description: _DISTRICTS_LIST_ID_MISMATCH} } // Convert districts to lookup table where a administrative unit code // and district number map to the district identifier. districts, err := districtsLookup(l) if err != nil { return err } // Although Counties is stored as-is, ensure that it is of expected // type, i.e., a JSON object with string array values. var counties map[string][]string if err := json.Unmarshal(l.Counties, &counties); err != nil { return JSONUnmarshalCountiesError{Err: err, Description: _DISTRICTS_LIST_INVALID_COUNTIES_JSON} } if until >= command.Execute { log.Log(ctx, ImportingDistricts{Count: len(l.Districts), Description: _DISTRICTS_LIST_PREPARE_UPLOAD_TO_DB}) progress.Static(fmt.Sprintf("Importing %d districts:", len(l.Districts))) addprogress := progress.Percent(uint64(len(districts)), true) progress.Redraw() defer progress.Keep() err := s.PutDistricts(ctx, version, districts, l.Counties, addprogress) if err != nil { return PutDistrictsError{Err: err, Description: _DISTRICTS_LIST_UPLOAD_TO_DB_FAIL} } } return nil } // districtsLookup converts the districts from a district list to a lookup // table from an administrative unit code and district number to a district // identifier. func districtsLookup(list districtlist) (map[string][]byte, error) { districts := make(map[string][]byte) parishCodes := make(map[string]string) for id, district := range list.Districts { splits := strings.Split(id, ".") if len(splits) != 2 || len(splits[0]) == 0 || len(splits[1]) == 0 { // Must contain a single period, but not first or last. return nil, DistrictIDFormatError{District: id, Description: _DISTRICTS_LIST_INVALID_DISTRICT_ID} } code, nr := splits[0], splits[1] for _, parish := range district.Parish { if parishCode, ok := parishCodes[parish]; ok && code != parishCode { return nil, ParishWithMultipleDistrictCodesError{First: parishCode, Second: code, Description: _DISTRICTS_LIST_PARISH_CONTAINS_SAME_DISTRICT_CODES, } } districts[string(storage.EncodeAdminDistrict(parish, nr))] = []byte(id) parishCodes[parish] = code } } return districts, nil } ================================================ FILE: choices/cmd/voterimp/container.go ================================================ package main import ( "archive/zip" "encoding/json" "io" "path/filepath" "regexp" "ivxv.ee/common/collector/conf/version" "ivxv.ee/common/collector/container" "ivxv.ee/common/collector/errors" ) // openContainer attemps to open path as a trusted signed container using // opener, but if this fails because it is an unknown type, then it opens it as // an untrusted ZIP-archive mimicing the container interface. func openContainer(opener container.Opener, path string) ( cnt container.Container, trusted bool, err error) { cnt, err = opener.OpenFile(path) if errors.CausedBy(err, new(container.UnconfiguredTypeError)) == nil { return cnt, true, err } // OpenFile failed because it was an unknown type: check if it is ZIP. if filepath.Ext(path) != ".zip" { return nil, false, err // Return the UnconfiguredTypeError. } archive, err := zip.OpenReader(path) if err != nil { return nil, false, OpenZIPContainerError{Err: err, Description: _VOTERS_LIST_OPEN_ZIP_CONTAINER} } defer archive.Close() data := make(map[string][]byte, len(archive.File)) for _, file := range archive.File { rc, err := file.Open() if err != nil { return nil, false, OpenZIPFileError{File: file.Name, Err: err, Description: _VOTERS_LIST_OPEN_ZIPPED_FILE} } defer rc.Close() bytes, err := io.ReadAll(rc) if err != nil { return nil, false, ReadZIPFileError{File: file.Name, Err: err, Description: _VOTERS_LIST_READ_ZIPPED_FILE} } data[file.Name] = bytes } return zipContainer{ comment: archive.Comment, data: data, }, false, nil } type zipContainer struct { comment string data map[string][]byte } // Close does nothing, because there are no resources to manually free. func (z zipContainer) Close() error { return nil } // Signatures returns an empty slice since the container is not signed. func (z zipContainer) Signatures() []container.Signature { return nil } // Data returns the container data from the ZIP-archive. func (z zipContainer) Data() map[string][]byte { return z.data } var containerVersionRE = regexp.MustCompile("(?m)^Version: +(.+)$") // containerVersion returns a container's version string. If the container is a // trusted signed container, then it calls version.Container, otherwise it // parses version metadata from the ZIP-archive comments. func containerVersion(cnt container.Container) (string, error) { z, ok := cnt.(zipContainer) if !ok { return version.Container(cnt) } matches := containerVersionRE.FindAllStringSubmatch(z.comment, -1) if len(matches) == 0 { return "", MissingZIPVersionError{Description: _VOTERS_LIST_UNABLE_TO_EXTRACT_ZIP_VERSION} } versions := make([]string, len(matches)) for i, match := range matches { versions[i] = match[1] // The first submatch is the version string. } version, err := json.Marshal(versions) return string(version), err } ================================================ FILE: choices/cmd/voterimp/log_desc.go ================================================ package main const ( _VOTERS_LIST_OPEN_ZIP_CONTAINER = "Failed to open .zip container with .utf and .sig files" _VOTERS_LIST_OPEN_ZIPPED_FILE = "Cannot open a file from .zip container" _VOTERS_LIST_READ_ZIPPED_FILE = "Failed to read a file from .zip container" _VOTERS_LIST_UNABLE_TO_EXTRACT_ZIP_VERSION = ".zip container doesn't have a version" _VOTERS_LIST_VERSION_FROM_DB = "Cannot fetch voters list version from a database" _VOTERS_LIST_VERSION_TO_JSON = "Cannot JSON marshal voters list version" _VOTERS_LIST_BDOC_OPEN = "Failed to open voters list BDOC container" _VOTERS_LIST_BDOC_NO_SIG = "No signatures found in voters list BDOC container" _VOTERS_LIST_BDOC_SIG_INFO = "Districts list BDOC container signature info" _VOTERS_LIST_BDOC_SIG_TO_JSON = "Failed to JSON marshal voters list BDOC container signature" _VOTERS_LIST_BDOC_INVALID_DATA = "Voters list BDOC container has invalid data" _VOTERS_LIST_UTF_AND_SIG_VERIFY = ".sig signature doesn't correspond to .utf" _VOTERS_LIST_CURRENT_VERSION = "Fetched from a database current voters list version" _VOTERS_LIST_CREATE_MAP_OF_ALL_CHANGES = "Failed to construct a map of all voters list being used so far" _VOTERS_LIST_TO_DB_UPLOAD = "Uploading voters list to database" _VOTERS_LIST_TO_DB_UPLOAD_FAIL = "Failed to upload voters list to database" _VOTERS_LIST_BDOC_HAS_MORE_THAN_2_FILES = "Voters list BDOC container doesn't have exactly 2 files (.utf and .sig)" _VOTERS_LIST_NO_UTF_FILE = "Voters list BDOC container doesn't have a .utf file" _VOTERS_LIST_NO_SIG_FILE = "Voters list BDOC container doesn't have a .sig file" _VOTERS_LIST_PUB_KEY_INVALID_PEM = "Voters list public key is invalid PEM" _VOTERS_LIST_PUB_KEY_INVALID_PKIX = "Voters list public key, after PEM decoding, is invalid PKIX" _VOTERS_LIST_PUB_KEY_INVALID_ECDSA = "Voters list public key algorithm is not ECDSA" _VOTERS_LIST_ASN1_SIG_ASN1_UNMARSHAL = "Cannot ASN.1 unmarshal .sig content" _VOTERS_LIST_SIG_VERIFY_FAIL = "Failed to verify .sig content with voters list public key" _VOTERS_LIST_READ = "Reading voters list" _VOTERS_LIST_READ_CTX_CANCEL = "Context has been cancelled during voters list reading" _VOTERS_LIST_UTF_INVALID_COLUMNS_COUNT = ".utf has invalid columns count" _VOTERS_LIST_UTF_UNKNOWN_COLUMN = ".utf contains unknown column" _VOTERS_LIST_READING_ERRORS = "Report of all errors occurred during voters file reading" _VOTERS_LIST_READING_ERRORS_COUNT = "Report errors count during voters file reading" _VOTERS_LIST_READ_UTF_FORMAT_VERSION = "Failed to read .utf format version" _VOTERS_LIST_UTF_FORMAT_VERSION = "Invalid .utf format version" _VOTERS_LIST_READ_UTF_ELECTION_ID = "Failed to read .utf election ID" _VOTERS_LIST_UTF_ELECTION_ID = ".utf election ID doesn't match the one in election configuration file" _VOTERS_LIST_READ_UTF_VOTERS_LIST_VERSION = "Failed to read .utf voters list version" _VOTERS_LIST_UTF_VOTERS_LIST_VERSION = ".utf voters list version is not a base-10 integer" _VOTERS_LIST_UTF_VOTERS_LIST_VERSION_0 = "Current .utf voters list to be uploaded has a version of 0, however such version already exists" _VOTERS_LIST_INITIAL_NOT_UPLOADED_YET = "Voters list with version 0 (initial) hasn't been yet uploaded" _VOTERS_LIST_UPLOAD_OLD_VERSION = "Trying to upload old voters list version" _VOTERS_LIST_READ_ELECTION_FROM_PERIOD = "Failed to read .utf election 'from' period" _VOTERS_LIST_ELECTION_FROM_PERIOD = ".utf election 'from' value is not a RFC3339 timestamp" _VOTERS_LIST_READ_ELECTION_TO_PERIOD = "Failed to read .utf election 'to' period" _VOTERS_LIST_ELECTION_TO_PERIOD = ".utf election 'to' value is not a RFC3339 timestamp" _VOTERS_LIST_UTF_VOTER_ID_EMPTY = ".utf voters list contains empty voter ID" _VOTERS_LIST_UTF_INITIAL_ACTION = ".utf voters list initial action should be 'lisamine'" _VOTERS_LIST_UTF_ADMIN_CODE_EMPTY = ".utf voters list contains empty admin code" _VOTERS_LIST_UTF_DISTRICT_EMPTY = ".utf voters list contains empty district" _VOTERS_LIST_UTF_ADD_SAME_VOTER = ".utf voters list attempts to add ('lisamine' action) same voters multiple time" _VOTERS_LIST_MODIFY_WITH_PREVIOUS_ERRORS = "Trying to process next line of voters list, but previous line was rejected with errors" _VOTERS_LIST_GET_VOTER_FROM_DB = "Cannot fetch voter ID from database" _VOTERS_LIST_NON_EXISTING_VOTER = "Voter doesn't exist in a database" _VOTERS_LIST_DELETE_JUST_ADDED_VOTER = "Voters list has 'lisamine' and then 'kustutamine' action for the same voter" _VOTERS_LIST_UNKNOWN_ACTION = "Voters list contains unknown action type" _VOTERS_LIST_READ_FILE_PROGRESS = "Reading voters file progress info" _VOTERS_LIST_READ_LINE_ERROR = "Cannot read voters file line" _VOTERS_LIST_UTF_COLUMNS_COUNT = "Voters file has invalid columns count for a given row" ) ================================================ FILE: choices/cmd/voterimp/main.go ================================================ /* The voterimp application is used for loading voter lists into the storage service. The voter list is generated and signed by the Estonian Election Information System and contains Estonian strings, so the format is very specific to Estonia. voterimp checks the raw ECDSA signature with SHA-256 digest, parses the contents of the voter list, and adds a new version of voter information into the storage service. */ package main import ( "bytes" "context" "crypto/ecdsa" "crypto/sha256" "crypto/x509" "encoding/json" "flag" "fmt" "io" "os" "strconv" "strings" "time" "ivxv.ee/common/collector/command" "ivxv.ee/common/collector/command/exit" "ivxv.ee/common/collector/command/status" "ivxv.ee/common/collector/cryptoutil" "ivxv.ee/common/collector/errors" "ivxv.ee/common/collector/log" "ivxv.ee/common/collector/storage" //ivxv:modules common/collector/container //ivxv:modules common/collector/storage ) const usage = `voterimp loads voter lists into the collector's storage service for use by other services. The voter list container must contain exactly two files: the voter list and the voter list signature. The key for the voter list can be anything, but the key for the signature must be the list key with a ".signature" suffix. E.g., "voter.list" and "voter.list.signature". The voter list container must have an extension corresponding to the container type it is, e.g., voterlist.bdoc. voterimp additionally supports unsigned ZIP containers with metadata stored in the archive comment.` var ( qp = flag.Bool("q", false, "quiet, do not show progress") progress *status.Line ) func main() { // Call voterimpmain in a separate function so that it can set up // defers and have them trigger before returning with a non-zero exit // code. os.Exit(voterimpmain()) } func voterimpmain() (code int) { c := command.New("ivxv-voterimp", usage, "voter list container") defer func() { code = c.Cleanup(code) }() if !*qp { progress = status.New() } // Only check the version if it was the specific check requested. if c.Until == command.CheckVersion { version, err := c.Storage.GetVotersContainerVersions(c.Ctx) if err != nil { if errors.CausedBy(err, new(storage.NotExistError)) == nil { return c.Error(exit.Unavailable, CheckVersionError{Err: err, Description: _VOTERS_LIST_VERSION_FROM_DB}, "failed to check imported container versions:", err) } } else { // Convert from new-line separation to JSON array. var vers []json.RawMessage for _, ver := range strings.Split(strings.TrimSpace(version), "\n") { vers = append(vers, json.RawMessage(ver)) } if err := json.NewEncoder(os.Stdout).Encode(vers); err != nil { return c.Error(exit.Unavailable, ConvertVersionError{Err: err, Description: _VOTERS_LIST_VERSION_TO_JSON}, "failed to encode container versions:", err) } } } if c.Until < command.CheckInput { return exit.OK } path := c.Args[0] // Open the voter list container file. cnt, trusted, err := openContainer(c.Conf.Container, path) if err != nil { code = exit.DataErr if perr := errors.CausedBy(err, new(os.PathError)); perr != nil { if os.IsNotExist(perr) { code = exit.NoInput } } return c.Error(code, OpenContainerError{Container: path, Err: err, Description: _VOTERS_LIST_BDOC_OPEN}, "failed to open voter list container:", err) } defer cnt.Close() // Ensure that a trusted container is signed and log the signatures. signatures := cnt.Signatures() if trusted && len(signatures) == 0 { return c.Error(exit.DataErr, UnsignedContainerError{Container: path, Description: _VOTERS_LIST_BDOC_NO_SIG}, "unsigned voter list container") } for _, s := range signatures { log.Log(c.Ctx, ContainerSignature{ Signer: s.Signer, SigningTime: s.SigningTime, Description: _VOTERS_LIST_BDOC_SIG_INFO, }) } // Get the version string of the container. cversion, err := containerVersion(cnt) if err != nil { return c.Error(exit.DataErr, ContainerVersionError{Container: path, Err: err, Description: _VOTERS_LIST_BDOC_SIG_TO_JSON}, "failed to format container version string:", err) } // Get the contents of the container. list, sig, err := containerData(cnt.Data()) if err != nil { return c.Error(exit.DataErr, ContainerDataError{Err: err, Description: _VOTERS_LIST_BDOC_INVALID_DATA}, "failed to find expected data from container:", err) } // Check the signature. if err = verifyECDSA(c.Conf.Election.VoterList.Key, list, sig); err != nil { return c.Error(exit.DataErr, VerifySignatureError{Err: err, Description: _VOTERS_LIST_UTF_AND_SIG_VERIFY}, "failed to verify voter list signature:", err) } // Get the current voter list version. oldver, err := c.Storage.GetVotersListVersion(c.Ctx) switch { case err == nil: log.Log(c.Ctx, CurrentVoterListVersion{Version: oldver, Description: _VOTERS_LIST_CURRENT_VERSION}) case errors.CausedBy(err, new(storage.NotExistError)) != nil: oldver = "" // Do not rely on storage returning zero value on error. default: return c.Error(exit.Unavailable, CheckListVersionError{Err: err, Description: _VOTERS_LIST_VERSION_FROM_DB}, "failed to check current list version:", err) } // Parse the voter list and preprocess into a map of changes. voters, newver, err := preprocess(c.Ctx, list, oldver, c.Conf.Election.Identifier, c.Storage) if err != nil { return c.Error(exit.DataErr, PreprocessVotersError{Err: err, Description: _VOTERS_LIST_CREATE_MAP_OF_ALL_CHANGES}, "failed to preprocess voter list:", err) } // Store the new list. if c.Until >= command.Execute { log.Log(c.Ctx, ImportingVoters{Version: newver, Count: len(voters), Description: _VOTERS_LIST_TO_DB_UPLOAD}) progress.Static(fmt.Sprintf("Importing %d voters:", len(voters))) addprogress := progress.Percent(uint64(len(voters)), true) progress.Redraw() defer progress.Keep() if err := c.Storage.PutVoters(c.Ctx, cversion, voters, oldver, newver, addprogress); err != nil { return c.Error(exit.Unavailable, PutVotersError{Err: err, Description: _VOTERS_LIST_TO_DB_UPLOAD_FAIL}, "failed to import voter list:", err) } } return exit.OK } // containerData returns voter list and signature contents from container data. func containerData(data map[string][]byte) (list, signature []byte, err error) { // The container data should have exactly two keys: *.utf and *.sig. // Although the files are usually named more specifically // // -voters-.{utf,sig}, // // do not enforce this. const utf = ".utf" const sig = ".sig" if len(data) != 2 { return nil, nil, KeyCountError{Count: len(data), Description: _VOTERS_LIST_BDOC_HAS_MORE_THAN_2_FILES} } var utfKey, sigKey string for key, content := range data { if strings.HasSuffix(key, utf) { utfKey = key list = content sigKey = key[:len(key)-len(utf)] + sig break } } if len(utfKey) == 0 { return nil, nil, MissingUTFKeyError{ Description: _VOTERS_LIST_NO_UTF_FILE, } } signature, ok := data[sigKey] if !ok { return nil, nil, MissingSigKeyError{Expected: sigKey, Description: _VOTERS_LIST_NO_SIG_FILE} } return list, signature, nil } // verifyECDSA parses an ECDSA public key from a PEM-encoded X.509 structure // and verifies the signature sig on data. func verifyECDSA(pub string, data, sig []byte) error { der, err := cryptoutil.PEMDecode(pub, "PUBLIC KEY") if err != nil { return ECDSAPEMDecodeError{Err: err, Description: _VOTERS_LIST_PUB_KEY_INVALID_PEM} } parsed, err := x509.ParsePKIXPublicKey(der) if err != nil { return ECDSAParsePKIXError{Err: err, Description: _VOTERS_LIST_PUB_KEY_INVALID_PKIX} } key, ok := parsed.(*ecdsa.PublicKey) if !ok { return ECDSAPublicKeyNotECDSAError{Type: fmt.Sprintf("%T", parsed), Description: _VOTERS_LIST_PUB_KEY_INVALID_ECDSA} } hashed := sha256.Sum256(data) // Hardcoded regardless of key parameters. r, s, err := cryptoutil.ParseECDSAASN1Signature(sig) if err != nil { return ECDSAParseSignatureError{Err: err, Description: _VOTERS_LIST_ASN1_SIG_ASN1_UNMARSHAL} } if !ecdsa.Verify(key, hashed[:], r, s) { return ECDSASignatureVerificationError{Description: _VOTERS_LIST_SIG_VERIFY_FAIL} } return nil } const ( delim = '\n' sep = '\t' ) // linefunc is the type of functions used to process voter lines. Given a // voter, action, administrative unit code and district number, it reports any // problems or if there were none, adds an entry for voter into voters. // previousErrors indicates if there were previous lines with errors for this // voter. version is the currently applied voter list version. type linefunc func(ctx context.Context, voter, action, adminCode, district string, voters map[string][]byte, previousErrors bool, version string, s *storage.Client) ( errs []error) // preprocess parses the list and preprocesses the changes for storage. func preprocess(ctx context.Context, list []byte, version, election string, s *storage.Client) ( voters map[string][]byte, newver string, err error) { b := bytes.NewBuffer(list) // Parse the header to determine list version and type. newver, lf, err := header(b, election, version) if err != nil { return nil, "", err } // Loop over all list entries, calling lf for each. Report progress of // this process. log.Log(ctx, PreprocessingVoterList{Version: newver, Description: _VOTERS_LIST_READ}) progress.Static("Preprocessing voter list:") addcount := progress.Count(0, false) // Do not redraw every time. const countstep = 10000 // Redraw after each countstep. progress.Redraw() defer progress.Keep() voters = make(map[string][]byte) withErrors := make(map[string]struct{}) // Voters with previous errors. var errcount int line := 3 // Voter entries start after the third line. loop: for ; ; stepadd(ctx, addcount, 1, countstep) { // Check if preprocessing was cancelled. select { case <-ctx.Done(): return nil, "", PreprocessVoterListCanceled{ Err: ctx.Err(), Description: _VOTERS_LIST_READ_CTX_CANCEL} default: } // Read the next line. line++ action, voter, adminCode, district, err := next(b) switch { case err == nil: case err == io.EOF: break loop case errors.CausedBy(err, new(FieldCountError)) != nil: report(ctx, VoterEntryFormatError{Line: line, Err: err, Description: _VOTERS_LIST_UTF_INVALID_COLUMNS_COUNT}) errcount++ continue loop default: report(ctx, ReadVoterEntryError{Line: line, Err: err, Description: _VOTERS_LIST_UTF_UNKNOWN_COLUMN}) errcount++ break loop } // Call lf for the line. _, previous := withErrors[voter] errs := lf(ctx, voter, action, adminCode, district, voters, previous, version, s) if len(errs) > 0 { withErrors[voter] = struct{}{} } for _, err = range errs { report(ctx, PreprocessVoterEntryError{Line: line, Err: err, Description: _VOTERS_LIST_READING_ERRORS}) errcount++ } } // Report final count if not already done by stepadd. if addcount(0)%countstep > 0 { stepadd(ctx, addcount, 0, 0) } if errcount > 0 { return nil, "", PreprocessVoterListError{ ErrorCount: errcount, Description: _VOTERS_LIST_READING_ERRORS_COUNT} } return voters, newver, nil } func header(b *bytes.Buffer, election, oldver string) (newver string, lf linefunc, err error) { // First line is the format version number, which must be 2. fver, err := readString(b, delim) if err != nil { return "", nil, ReadFileVersionError{Err: err, Description: _VOTERS_LIST_UTF_FORMAT_VERSION} } if fver != "2" { return "", nil, FileVersionError{Version: fver, Description: _VOTERS_LIST_READ_UTF_FORMAT_VERSION} } // Second is the election identifier. Must match the one in the election // configuration. elid, err := readString(b, delim) if err != nil { return "", nil, ReadElectionIDError{Err: err, Description: _VOTERS_LIST_READ_UTF_ELECTION_ID} } if elid != election { return "", nil, ElectionIDMismatchError{Conf: election, List: elid, Description: _VOTERS_LIST_UTF_ELECTION_ID} } // Third is the list version number. newver, err = readString(b, delim) if err != nil { return "", nil, ReadListVersionError{Err: err, Description: _VOTERS_LIST_READ_UTF_VOTERS_LIST_VERSION} } newver64, err := strconv.ParseUint(newver, 10, 64) if err != nil { return "", nil, ParseListVersionError{Err: err, Description: _VOTERS_LIST_UTF_VOTERS_LIST_VERSION} } if newver64 == 0 { if len(oldver) > 0 { return "", nil, VoterListExistsError{Version: oldver, Description: _VOTERS_LIST_UTF_VOTERS_LIST_VERSION_0} } lf = initial } else { var oldver64 uint64 if len(oldver) == 0 { return "", nil, NoExistingVoterListError{ Description: _VOTERS_LIST_INITIAL_NOT_UPLOADED_YET} } else if oldver64, err = strconv.ParseUint(oldver, 10, 64); err != nil { return "", nil, ParseCurrentListVersionError{Err: err, Description: _VOTERS_LIST_UTF_VOTERS_LIST_VERSION} } else if oldver64 >= newver64 { return "", nil, UnexpectedListVersionError{ Current: oldver64, List: newver64, Description: _VOTERS_LIST_UPLOAD_OLD_VERSION, } } lf = changes } // Fourth are two timestamps representing the period. Not used by the // collector, but make sure that the format is valid. fromstr, err := readString(b, sep) if err != nil { return "", nil, ReadPeriodFromError{Err: err, Description: _VOTERS_LIST_READ_ELECTION_FROM_PERIOD} } if _, err = time.Parse(time.RFC3339, fromstr); err != nil { return "", nil, ParsePeriodFromError{Err: err, Description: _VOTERS_LIST_ELECTION_FROM_PERIOD} } tostr, err := readString(b, delim) if err != nil { return "", nil, ReadPeriodToError{Err: err, Description: _VOTERS_LIST_READ_ELECTION_TO_PERIOD} } if _, err = time.Parse(time.RFC3339, tostr); err != nil { return "", nil, ParsePeriodToError{Err: err, Description: _VOTERS_LIST_ELECTION_TO_PERIOD} } return newver, lf, nil } func initial(_ context.Context, voter, action, adminCode, district string, voters map[string][]byte, _ bool, _ string, _ *storage.Client) ( errs []error) { // Skip duplicate checking if there are relevant errors. We want to // check duplicates even if the voter had previous errors, so use a // flag separate from previousErrors. var skip bool if len(voter) == 0 { errs = append(errs, InitialEmptyVoterError{Description: _VOTERS_LIST_UTF_VOTER_ID_EMPTY}) skip = true } if action != "lisamine" { errs = append(errs, InitialNonAddActionError{Action: action, Description: _VOTERS_LIST_UTF_INITIAL_ACTION}) skip = true } if len(adminCode) == 0 { errs = append(errs, InitialEmptyAdminUnitCodeError{ Description: _VOTERS_LIST_UTF_ADMIN_CODE_EMPTY, }) } if len(district) == 0 { errs = append(errs, InitialEmptyDistrictNumberError{ Description: _VOTERS_LIST_UTF_DISTRICT_EMPTY, }) } if !skip { if _, ok := voters[voter]; ok { errs = append(errs, InitialAddDuplicateVoterError{Voter: voter, Description: _VOTERS_LIST_UTF_ADD_SAME_VOTER}) } // It is OK to add invalid entries (skip was not set for // adminCode or district errors) since then we will error // anyway and the map values are not used during preprocessing. voters[voter] = storage.EncodeAdminDistrict(adminCode, district) } return } func changes(ctx context.Context, voter, action, adminCode, district string, voters map[string][]byte, previousErrors bool, version string, s *storage.Client) ( errs []error) { if len(voter) == 0 { errs = append(errs, ChangesEmptyVoterError{ Description: _VOTERS_LIST_UTF_VOTER_ID_EMPTY, }) previousErrors = true } else if previousErrors { errs = append(errs, ChangesVoterWithPreviousErrorsError{Voter: voter, Description: _VOTERS_LIST_MODIFY_WITH_PREVIOUS_ERRORS}) } // Only perform consistency checks if there are no previous errors. var voterExists bool // Is this voter on the current voter list? var voterProcessed bool // Has this voter already been processed? if !previousErrors { // Check the current entry for the voter. Look at the in-memory // map first and only then storage. if entry, ok := voters[voter]; ok { voterExists = entry != nil voterProcessed = true } else { var err error _, _, err = s.GetVoter(ctx, version, voter) switch { case err == nil: voterExists = true case errors.CausedBy(err, new(storage.NotExistError)) != nil: default: errs = append(errs, GetOldVoterError{Voter: voter, Err: err, Description: _VOTERS_LIST_GET_VOTER_FROM_DB}) previousErrors = true } } } switch action { case "lisamine": if len(adminCode) == 0 { errs = append(errs, ChangesEmptyAdminUnitCodeError{ Description: _VOTERS_LIST_UTF_ADMIN_CODE_EMPTY, }) previousErrors = true } if len(district) == 0 { errs = append(errs, ChangesEmptyDistrictNumberError{ Description: _VOTERS_LIST_UTF_DISTRICT_EMPTY, }) previousErrors = true } if !previousErrors { if voterExists { errs = append(errs, ChangesAddDuplicateVoterError{Voter: voter, Description: _VOTERS_LIST_UTF_ADD_SAME_VOTER}) } voters[voter] = storage.EncodeAdminDistrict(adminCode, district) } case "kustutamine": if !previousErrors { switch { case !voterExists: errs = append(errs, ChangesRemoveNotExistingVoterError{ Voter: voter, Description: _VOTERS_LIST_NON_EXISTING_VOTER}) case voterProcessed: errs = append(errs, ChangesRemoveAddedVoterError{Voter: voter, Description: _VOTERS_LIST_DELETE_JUST_ADDED_VOTER}) } voters[voter] = nil // nil to distinguish from unchanged voters. } default: errs = append(errs, ChangesUnsupportedActionError{Action: action, Description: _VOTERS_LIST_UNKNOWN_ACTION}) } return } // stepadd calls add with count and, if step is zero or the new total modulo // step is zero, logs and redraws progress. func stepadd(ctx context.Context, add status.Add, count, step uint64) { if new1 := add(count); step == 0 || new1%step == 0 { log.Log(ctx, PreprocessProgress{Count: new1, Description: _VOTERS_LIST_READ_FILE_PROGRESS}) progress.Redraw() } } // next reads and parses the next voter line from b. func next(b *bytes.Buffer) (action, voter, adminCode, district string, err error) { line, err := readString(b, delim) if err != nil { if err != io.EOF || len(line) > 0 { err = ReadNextError{Line: line, Err: err, Description: _VOTERS_LIST_READ_LINE_ERROR} } return } // Split on tabs and expect five fields or two fields when 'kustutamine': // // 0. action, // 1. voter ID, // 2. voter name (ignored), // 3. administrative unit code, and // 4. district number. // // 0. action, // 1. voter ID, // // The choices identifier is formed from the administrative unit code // and district number. fields := strings.Split(line, string(sep)) switch len(fields) { case 2: return fields[0], fields[1], "", "", nil case 5: return fields[0], fields[1], fields[3], fields[4], nil default: err = FieldCountError{Fields: len(fields), Description: _VOTERS_LIST_UTF_COLUMNS_COUNT} return } } // report reports an error to both the log and standard output. func report(ctx context.Context, entry log.ErrorEntry) { log.Error(ctx, entry) progress.Hide() defer progress.Show() fmt.Fprintln(os.Stderr, "error:", entry) } // readString returns the result of b.ReadString(delim) with delim trimmed. func readString(b *bytes.Buffer, delim byte) (string, error) { line, err := b.ReadString(delim) if err == nil { line = line[:len(line)-1] // Trim the delimiter. } return line, err } ================================================ FILE: choices/cmd/voterimp/voterimp_test.go ================================================ package main import "testing" func TestZIPVersion(t *testing.T) { const comment = `Version: start of text Some commentary about the archive. Version: mid-text Some more commentary about the archive. Version: left-trim and Unicode ✔️ version: lowercase Version:no space Version: end of text` const expected = `["start of text","mid-text","left-trim and Unicode ✔️","end of text"]` version, err := containerVersion(zipContainer{comment: comment}) if err != nil { t.Fatal(err) } if version != expected { t.Errorf("unexpected ZIP version: got %s, want %s", version, expected) } } ================================================ FILE: choices/go.mod ================================================ module ivxv.ee/choices go 1.23 require ivxv.ee/common/collector v1.9.11 require ivxv.ee/sessionstatus/api v1.9.11 require ( github.com/coreos/go-semver v0.3.0 // indirect github.com/coreos/go-systemd/v22 v22.3.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect go.etcd.io/etcd/api/v3 v3.5.17 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.17 // indirect go.etcd.io/etcd/client/v3 v3.5.17 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.17.0 // indirect golang.org/x/net v0.29.0 // indirect golang.org/x/sys v0.25.0 // indirect golang.org/x/text v0.18.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect google.golang.org/grpc v1.68.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) replace ivxv.ee/common/collector => ../common/collector replace ivxv.ee/sessionstatus/api => ../sessionstatus/api ================================================ FILE: choices/go.sum ================================================ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.etcd.io/etcd/api/v3 v3.5.17 h1:cQB8eb8bxwuxOilBpMJAEo8fAONyrdXTHUNcMd8yT1w= go.etcd.io/etcd/api/v3 v3.5.17/go.mod h1:d1hvkRuXkts6PmaYk2Vrgqbv7H4ADfAKhyJqHNLJCB4= go.etcd.io/etcd/client/pkg/v3 v3.5.17 h1:XxnDXAWq2pnxqx76ljWwiQ9jylbpC4rvkAeRVOUKKVw= go.etcd.io/etcd/client/pkg/v3 v3.5.17/go.mod h1:4DqK1TKacp/86nJk4FLQqo6Mn2vvQFBmruW3pP14H/w= go.etcd.io/etcd/client/v3 v3.5.17 h1:o48sINNeWz5+pjy/Z0+HKpj/xSnBkuVhVvXkjEXbqZY= go.etcd.io/etcd/client/v3 v3.5.17/go.mod h1:j2d4eXTHWkT2ClBgnnEPm/Wuu7jsqku41v9DZ3OtjQo= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc= google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0= google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= ================================================ FILE: choices/internal/client/sessionstatus/rpc/client.go ================================================ package rpc import ( "strconv" "ivxv.ee/common/collector/auth" "ivxv.ee/common/collector/command" "ivxv.ee/common/collector/server" "ivxv.ee/common/collector/status/client" status "ivxv.ee/common/collector/status/client/rpc" api "ivxv.ee/sessionstatus/api/rpc" ) const ( // This should be a StatusReadResp.Caller value for ID card Empty = "" // This should be a StatusReadResp.Caller value for Mobile-ID/Smart-ID AuthenticateStatus = "RPC.AuthenticateStatus" // This should be a StatusReadResp.Caller value for Web eID Token = "RPC.Token" // This should be a StatusUpdateReq.Caller value for ID card/Mobile-ID/Smart-ID/Web eID VoterChoices = "RPC.VoterChoices" ) const exitCodeOK = 0 type RPC struct { choiceTTL int64 client client.TLSDialer } // NewClient initializes session status server client. func NewClient(c *command.C) (client.Verifier, int) { // Initialize RPC TLS session status client tlsDialer, errCode := api.NewClient(c) if errCode != exitCodeOK { return nil, errCode } return &RPC{ client: tlsDialer, choiceTTL: c.Conf.Technical.Status.Session.ChoiceTTL, }, exitCodeOK } func (r *RPC) Verify(dto interface{}) (bool, error) { // dto should cast to *status.VerifyReq verifyReq, err := status.CastAnyToVerifyReq(dto) if err != nil { return false, CastAnyToVerifyReqError{Err: err, Description: _SESSIONSTATUS_CAST_ANY_TO_VERIFYREQ} } // verifyReq.Request should cast to server.Header header, err := api.CastVerifyRequestToServerHeader(verifyReq) if err != nil { return false, CastVerifyRequestToServerHeaderError{Err: err, Description: _SESSIONSTATUS_CAST_VERIFYREQ_TO_SERVERHEADER} } // Send request to session status server and verify response ok, err := r.verifyAndUpdateSessionStatus(verifyReq.ServiceMethod, *header) if err != nil { return false, VerifyAndUpdateSessionStatusError{Err: err, Description: _SESSIONSTATUS_SEND_UPDATE_REQ_AND_VERIFY_IT} } return ok, nil } // verifyAndUpdateSessionStatus will first check h.Header.SessionID // record against the underlying storage, and if everything is correct, // then will update h.Header.SessionID record in the underlying storage // by marking session status Caller as serviceMethod. // // Note, that here serviceMethod is the RPC method that calls this function. func (r *RPC) verifyAndUpdateSessionStatus(serviceMethod string, h server.Header) (bool, error) { // Extract authentication method from a header.Ctx authFilter, err := server.AuthMethod(h.Ctx) if err != nil { return false, AuthMethodFromCtxError{Err: err, Description: _SESSIONSTATUS_AUTHMETHOD_FROM_CTX} } if authFilter == "" { return false, AuthMethodIsEmptyError{AuthFilter: authFilter, Description: _SESSIONSTATUS_AUTHMETHOD_EMPTY} } // Create new session read status request reqRead := api.NewSessionStatusReadReqBuilder(). WithHeader(h). Build() // Create new RPC request to status server, embeds session status request reqReadRPC := status.NewStatusReqBuilder(). WithServiceMethod(api.Endpoint.SessionStatusRead). WithRequest(reqRead). Build() // RPC call to .WithServiceMethod(...) respReadRaw, err := r.client.TLSDial(&reqReadRPC) if err != nil { return false, SessionReadReqTLSDialError{Err: err, Description: _SESSIONSTATUS_TLS_DIAL} } // Process raw RPC response, doesn't care about the embedded status type respReadRPC := status.NewStatusRespBuilder(). WithResponse(respReadRaw). Build() // Process session read status response respRead := api.NewSessionStatusReadRespBuilder(). WithResponse(respReadRPC.Response). Build() ttl := strconv.FormatInt(r.choiceTTL, 10) // Reset the LeaseID respRead.Lease = "" // NB! Most important part, that prevents any attack on SessionID ok, err := verifyStatusReadResp(&respRead, voterChoicesHandler) if err != nil || !ok { return false, VerifyStatusReadRespError{Err: err, Description: _SESSIONSTATUS_RESP_VERIFY} } // SessionID is valid, however there is one more possibility to tamper // a SessionID == to wait until SessionID TTL is expired and perform // RPC.VoterChoices query. This is the only edge case that could happen // since RPC.VoterChoices is the only endpoint which allows // empty Auth and Caller fields. // // This behaviour can be prevented if we know, how user exactly authenticated // in an authentication filter. For Mobile-ID/Smart-ID/Web eID it is auth.Ticket, // however for ID card it is auth.TLS if respRead.Auth == client.NoAuth && auth.Type(authFilter) != auth.TLS { // SessionID is attempted to tamper return false, EmptyAuthAndCallerForNonIDCardUserError{ Method: VoterChoices, Auth: respRead.Auth, Caller: respRead.Caller, AuthMethod: authFilter, Description: _SESSIONSTATUS_IDCARD, } } // Here is 100% clear, that user is ID card if respRead.Auth == client.NoAuth { respRead.Auth = client.IDcardAuth } // Create new session update status request reqUpdate := api.NewSessionStatusUpdateReqBuilder(). WithHeader(h). WithCaller(serviceMethod). WithAuth(respRead.Auth). WithLease(respRead.Lease). WithTTL(ttl). Build() // Create new RPC request to status server, embeds session status request reqUpdateRPC := status.NewStatusReqBuilder(). WithServiceMethod(api.Endpoint.SessionStatusUpdate). WithRequest(reqUpdate). Build() // RPC call to .WithServiceMethod(...) respUpdateRaw, err := r.client.TLSDial(&reqUpdateRPC) if err != nil { return false, SessionUpdateReqTLSDialError{Err: err, Description: _SESSIONSTATUS_TLS_DIAL} } // Process raw RPC response, doesn't care about the embedded status type respUpdateRPC := status.NewStatusRespBuilder(). WithResponse(respUpdateRaw). Build() // Process session update status response respUpdate := api.NewSessionStatusUpdateRespBuilder(). WithResponse(respUpdateRPC.Response). Build() // If true, then status has been successfully updated ok = respUpdate.Ok if !ok { return false, SessionStatusUpdateError{ Caller: reqUpdate.Caller, Auth: respRead.Auth, Description: _SESSIONSTATUS_UPDATE_FAIL, } } return true, nil } // verifyStatusReadResp r by applying an appropriate handler h. func verifyStatusReadResp(r *api.StatusReadResp, h func(*api.StatusReadResp) (bool, error)) (bool, error) { return h(r) } // voterChoicesHandler performs filter operation on StatusReadResp r to // detect invalid SessionID in a client RPC.VoterChoices request. func voterChoicesHandler(r *api.StatusReadResp) (bool, error) { // When authenticating with ID card, i.e. first interaction with IVXV idCardAuth := r.Caller == Empty && r.Auth == client.NoAuth // When authenticating with Mobile-ID, then IVXV requires that client // has previously interacted with IVXV using RPC.AuthenticateStatus method midAuth := r.Caller == AuthenticateStatus && r.Auth == client.MobileIDAuth // When authenticating with Smart-ID, then IVXV requires that client // has previously interacted with IVXV using RPC.AuthenticateStatus method sidAuth := r.Caller == AuthenticateStatus && r.Auth == client.SmartIDAuth // When authenticating with Web eID, then IVXV requires that client // has previously interacted with IVXV using RPC.Token method widAuth := r.Caller == Token && r.Auth == client.WebeIDAuth // All conditions must satisfy simultaneously! if !(idCardAuth) && !(midAuth) && !(sidAuth) && !(widAuth) { return false, VoterChoicesInvalidCallerOrAuthForSessionID{ Method: VoterChoices, Caller: r.Caller, Auth: r.Auth, Description: _SESSIONSTATUS_MALFORMED_SESSION_ID, } } return true, nil } ================================================ FILE: choices/internal/client/sessionstatus/rpc/log_desc.go ================================================ package rpc const ( _SESSIONSTATUS_CAST_ANY_TO_VERIFYREQ = "Cannot cast any to VerifyReq" _SESSIONSTATUS_CAST_VERIFYREQ_TO_SERVERHEADER = "Cannot cast VerifyReq to server.Header" _SESSIONSTATUS_SEND_UPDATE_REQ_AND_VERIFY_IT = "SessionID verification request that has been sent to sessionstatus service has been failed" _SESSIONSTATUS_AUTHMETHOD_FROM_CTX = "Unable to parse server.AuthMethod from context" _SESSIONSTATUS_AUTHMETHOD_EMPTY = "server.AuthMethod parsed from context is empty" _SESSIONSTATUS_TLS_DIAL = "TLS dial to sessionstatus service failed" _SESSIONSTATUS_RESP_VERIFY = "Sessionstatus service response verification failed" _SESSIONSTATUS_IDCARD = "Empty server.AuthMethod is only allowed for ID card users" _SESSIONSTATUS_UPDATE_FAIL = "Sessionstatus service hasn't updated the Session ID state" _SESSIONSTATUS_MALFORMED_SESSION_ID = "SessionID has been attempted to tamper" ) ================================================ FILE: choices/service/choices/log_desc.go ================================================ package main const ( _CHOICES_CHOICESREQ = "RPC.ChoicesReq" _CHOICES_ADMIN_CODE = "Unable to fetch admin code from database for this voter ID" _CHOICES_NO_FOR_VOTER = "No choices for this voter ID" _CHOICES_FROM_DB = "Unable to fetch choices for this voter ID from a database" _CHOICES_CHOICESRESP = "RPC.ChoicesResp" _CHOICES_VOTERCHOICESREQ = "RPC.VoterChoicesReq" _CHOICES_VOTER_NO_AUTH = "Voter has not been authenticated" _CHOICES_SESSION_ID = "Malformed SessionID" _CHOICES_SESSION_ID_EXPIRED = "SessionID has been expired" _CHOICES_NO_VOTER_IN_VOTERS_LIST = "No such voter ID in a voters list" _CHOICES_DB = "Successfully got choices for this voter ID from a database" _CHOICES_CHECK_VOTED = "Unable to get a response from database whether this voter ID has already voted or not" _CHOICES_VOTERCHOICESRESP = "RPC.VoterChoicesResp" _CHOICES_START = "Failed to transform service start time from election configuration file to RFC3339 format" _CHOICES_STOP = "Failed to transform service stop time from election configuration file to RFC3339 format" _CHOICES_AUTH = "Failed to parse authentication configuration for choices service" _CHOICES_SERVER = "Failed to parse server configuration for choices service" _CHOICES_SERVER_SERVE = "Failed to serve choices service to clients" ) ================================================ FILE: choices/service/choices/main.go ================================================ /* The choices service serves choice lists for voting and verification. */ package main import ( "os" "strings" "time" internal "ivxv.ee/choices/internal/client/sessionstatus/rpc" "ivxv.ee/common/collector/command" "ivxv.ee/common/collector/command/exit" "ivxv.ee/common/collector/conf" "ivxv.ee/common/collector/errors" "ivxv.ee/common/collector/log" "ivxv.ee/common/collector/server" "ivxv.ee/common/collector/status/client" status "ivxv.ee/common/collector/status/client/rpc" "ivxv.ee/common/collector/storage" //ivxv:modules common/collector/auth //ivxv:modules common/collector/container //ivxv:modules common/collector/storage ) // RPC is the handler for choices service calls. type RPC struct { status client.Verifier storage *storage.Client forceList string // If set, VoterChoices always returns this list. foreignCode string // Administrative unit code for foreign voters. } // ChoicesArgs are the arguments provided to a call of RPC.Choices. type ChoicesArgs struct { server.Header Choices string `size:"10"` // Identifier of the requested choice list. } // VoterArgs are the arguments provided to a call of RPC.VoterChoices. There // are none, because the identity of the voter will be extracted from the // authentication info. type VoterArgs struct { server.Header } // Response is the response returned by RPC.Choices and RPC.VoterChoices. type Response struct { server.Header Choices string // Identifier of the requested choices. List []byte // The requested choices. Voted bool `json:",omitempty"` // Has the voter voted already? } // Deprecated: Choices RPC endpoint is not used by IVXV backend anymore. // Choices is the remote procedure call performed by verification clients to // retrieve a specific choices list. func (r *RPC) Choices(args ChoicesArgs, resp *Response) (err error) { log.Log(args.Ctx, ChoicesReq{Choices: args.Choices, Description: _CHOICES_CHOICESREQ}) resp.Choices = args.Choices if resp.List, err = r.storage.GetChoices(args.Ctx, args.Choices); err != nil { if errors.CausedBy(err, new(storage.NotExistError)) != nil { log.Error(args.Ctx, BadChoicesError{Err: err, Description: _CHOICES_NO_FOR_VOTER}) return server.ErrBadRequest } log.Error(args.Ctx, GetChoicesError{Err: log.Alert(err), Description: _CHOICES_FROM_DB}) return server.ErrInternal } // The choices are not actually sensitive, but just really large. log.Log(args.Ctx, ChoicesResp{List: log.Sensitive(resp.List), Description: _CHOICES_CHOICESRESP}) return } // VoterChoices is the remote procedure call performed by voting clients to // retrieve the choices list for a voter. func (r *RPC) VoterChoices(args VoterArgs, resp *Response) (err error) { log.Log(args.Ctx, VoterChoicesReq{Description: _CHOICES_VOTERCHOICESREQ}) // Get the voter identifier associated with the RPC call. If empty, then the request // was not properly authenticated and error shall be logged voter := server.VoterIdentity(args.Ctx) if len(voter) == 0 { log.Error(args.Ctx, UnauthenticatedVoterChoicesError{Description: _CHOICES_VOTER_NO_AUTH}) return server.ErrUnauthenticated } // Build up VerifyReq for session status service verifyReq := status.NewVerifyReqBuilder(). WithServiceMethod(internal.VoterChoices). WithRequest(args.Header). Build() // SessionID security check ok, err := r.status.Verify(&verifyReq) if err != nil { // Error during SessionID check - database unreachable, service stalled, etc. log.Error(args.Ctx, VoterChoicesVerifySessionIDError{Err: err, Description: _CHOICES_SESSION_ID}) return server.ErrBadRequest } if !ok { // SessionID is unknown / has expired, we shall not further process the request log.Error(args.Ctx, VoterChoicesUpdateSessionIDError{Description: _CHOICES_SESSION_ID_EXPIRED}) return server.ErrBadRequest } if len(r.forceList) > 0 { resp.Choices = r.forceList } else { _, resp.Choices, err = r.storage.VoterChoices(args.Ctx, voter, r.foreignCode) if err != nil { if errors.CausedBy(err, new(storage.NotExistError)) != nil { // Voter successfully authenticated to the backend but // was not found in the current voterlist log.Error(args.Ctx, IneligibleVoterError{Err: err, Description: _CHOICES_NO_VOTER_IN_VOTERS_LIST}) return server.ErrIneligible } // Backend cannot fetch choices list from storage, database may be unreachable log.Error(args.Ctx, VoterChoicesError{Err: log.Alert(err), Description: _CHOICES_ADMIN_CODE}) return server.ErrInternal } } log.Log(args.Ctx, VoterChoices{Choices: resp.Choices, Description: _CHOICES_DB}) if resp.List, err = r.storage.GetChoices(args.Ctx, resp.Choices); err != nil { // Backend cannot fetch choices list from storage, database may be unreachable log.Error(args.Ctx, GetVoterChoicesError{Err: log.Alert(err), Description: _CHOICES_FROM_DB}) return server.ErrInternal } if resp.Voted, err = r.storage.CheckVoted(args.Ctx, voter); err != nil { // Backend cannot check whether voter has already voted or not, // database may be unreachable log.Error(args.Ctx, CheckVotedError{Err: log.Alert(err), Description: _CHOICES_CHECK_VOTED}) return server.ErrInternal } // The choices are not actually sensitive, but just really large. log.Log(args.Ctx, VoterChoicesResp{List: log.Sensitive(resp.List), Description: _CHOICES_VOTERCHOICESRESP}) return } func main() { // Call choicesmain in a separate function so that it can set up defers // and have them trigger before returning with a non-zero exit code. os.Exit(choicesmain()) } func choicesmain() (code int) { c := command.New("ivxv-choices", "") defer func() { code = c.Cleanup(code) }() // Configure session status client statusClient, errCode := internal.NewClient(c) if statusClient == nil || errCode != 0 { return errCode } // Create new RPC instance with storage and status clients rpc := &RPC{storage: c.Storage, status: statusClient} var start, stop time.Time var authConf server.AuthConf var err error if elec := c.Conf.Election; elec != nil { // Check election configuration time values. if start, err = elec.ServiceStartTime(); err != nil { return c.Error(exit.Config, StartTimeError{Err: err, Description: _CHOICES_START}, "bad service start time:", err) } if stop, err = elec.ElectionStopTime(); err != nil { return c.Error(exit.Config, StopTimeError{Err: err, Description: _CHOICES_STOP}, "bad election stop time:", err) } // Parse client-authentication configuration. if authConf, err = server.NewAuthConf( elec.Auth, elec.Identity, &elec.Age); err != nil { return c.Error(exit.Config, ServerAuthConfError{Err: err, Description: _CHOICES_AUTH}, "failed to configure client authentication:", err) } rpc.forceList = strings.TrimSpace(elec.IgnoreVoterList) rpc.foreignCode = strings.TrimSpace(elec.VoterForeignEHAKDefault()) } var s *server.S if c.Conf.Technical != nil { // Configure a new server with the service instance // configuration and the RPC handler instance. cert, key := conf.TLS(conf.Sensitive(c.Service.ID)) if s, err = server.New(&server.Conf{ CertPath: cert, KeyPath: key, Address: c.Service.Address, End: stop, Filter: &c.Conf.Technical.Filter, Version: &c.Conf.Version, }, rpc); err != nil { return c.Error(exit.Config, ServerConfError{Err: err, Description: _CHOICES_SERVER}, "failed to configure server:", err) } } // Start listening for incoming connections during the voting period. if c.Until >= command.Execute { if err = s.WithAuth(authConf).ServeAt(c.Ctx, start); err != nil { return c.Error(exit.Unavailable, ServeError{Err: err, Description: _CHOICES_SERVER_SERVE}, "failed to serve choices service:", err) } } return exit.OK } ================================================ FILE: collector-admin/Makefile ================================================ check: env PYTHONPATH=../common/external/schematics \ pylint3 --rcfile=../common/tools/pylintrc ivxv_admin ================================================ FILE: collector-admin/README.rst ================================================ ================================ IVXV Internet voting framework ================================ ----------------------------------- Collector administration interface ----------------------------------- ================================================ FILE: collector-admin/config/ivxv-admin-ui.conf ================================================ # IVXV Internet voting framework # Apache site configuration for Collector Management Service # /etc/apache2/sites-available/ivxv-admin-ui.conf # When Apache server responds to client, then 'Header:Server:' will be 'Apache', and not 'Apache/2.4.52 (Ubuntu)' ServerTokens Prod ServerName ivxv-admin AddDefaultCharset utf-8 ErrorLog ${APACHE_LOG_DIR}/error.log # Nobody can browse URLs that are outside the tags listed below in this configuration. # E.g. URLs like 'https://myhost.ee/ui/js' will be HTTP 403 Forbidden Options FollowSymLinks AllowOverride None Require all granted # Redirect all HTTP requests to HTTPS site RewriteEngine on RewriteCond %{HTTPS} !=on RewriteRule ^.* https://%{HTTP_HOST}/ [R=301,L] # Access log CustomLog ${APACHE_LOG_DIR}/access-http.log combined # The ServerName directive sets the request scheme, hostname and port that # the server uses to identify itself. This is used when creating # redirection URLs. In the context of virtual hosts, the ServerName # specifies what hostname must appear in the request's Host: header to # match this virtual host. For the default virtual host (this file) this # value is not decisive as it is used as a last resort host regardless. # However, you must set it for any further virtual host explicitly. ServerAdmin webmaster@localhost DocumentRoot /var/www/collector-admin/ # Available loglevels: trace8, ..., trace1, debug, info, notice, warn, # error, crit, alert, emerg. # It is also possible to configure the loglevel for particular # modules, e.g. #LogLevel info ssl:warn # Access log LogFormat "%a %l %u %t \"%r\" %>s %b %T \"%{Referer}i\" \"%{User-Agent}i\" \"%q\" \"%{SSL_CLIENT_S_DN_CN}e\"" ivxv-admin-https CustomLog ${APACHE_LOG_DIR}/access.log ivxv-admin-https # SSL {{{ # SSL Engine Switch SSLEngine on # Create the standard set of SSL related CGI/SSI environment variables SSLOptions StdEnvVars # A self-signed certificate can be created by installing # the ssl-cert package. # If both key and certificate are stored in the same file, only the # SSLCertificateFile directive is needed. SSLCertificateFile "/etc/ssl/certs/ivxv-admin-default.crt" SSLCertificateKeyFile "/etc/ssl/private/ivxv-admin-default.key" # Server Certificate Chain: # Point SSLCertificateChainFile at a file containing the # concatenation of PEM encoded CA certificates which form the # certificate chain for the server certificate. Alternatively # the referenced file can be the same as SSLCertificateFile # when the CA certificates are directly appended to the server # certificate for convinience. #SSLCertificateChainFile /etc/ssl/certs/KLASS3-SK_2010_EECCRCA_SHA384.pem.crt # Certificate Authority (CA): # Set the CA certificate verification path where to find CA # certificates for client authentication or alternatively one # huge file containing all of them (file must be PEM encoded) # Note: Inside SSLCACertificatePath you need hash symlinks # to point to the certificate files. Use the provided # Makefile to update the hash symlinks after changes. #SSLCACertificatePath /etc/ssl/certs/ SSLCACertificateFile /etc/ssl/certs/sk-juur.crt # Certificate Revocation Lists (CRL): # Set the CA revocation path where to find CA CRLs for client # authentication or alternatively one huge file containing all # of them (file must be PEM encoded) # Note: Inside SSLCARevocationPath you need hash symlinks # to point to the certificate files. Use the provided # Makefile to update the hash symlinks after changes. #SSLCARevocationPath /etc/apache2/ssl.crl/ #SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl # Client Authentication (Type): # Client certificate verification type and depth. Types are # none, optional, require and optional_no_ca. Depth is a # number which specifies how deeply to verify the certificate # issuer chain before deciding the certificate is not valid. SSLVerifyClient require SSLVerifyDepth 2 # Ref: https://www.id.ee/wp-content/uploads/2021/12/21.11-ubuntu-apache2-webserver-ssl-configuration.pdf # Accept only TLSv1.3 protocol in new connections. SSLProtocol -all +TLSv1.3 # Use the server's preference when choosing a cipher # during an TLSv1.3 handshake. SSLHonorCipherOrder on # Uncomment in case you want to check client certificate against OCSP # responder, parsed from certificate's 'Authority Information Access:' field # SSLOCSPEnable on # Ensures Perfect Forward Secrecy is not compromised if the server is not restarted regularly. SSLSessionTickets off # Specify Diffie-Hellman group (strong, 2048 bit) SSLOpenSSLConfCmd DHParameters "/etc/ssl/dhparams.pem" # SSL Protocol Adjustments: # The safe and default but still SSL/TLS standard compliant shutdown # approach is that mod_ssl sends the close notify alert but doesn't wait for # the close notify alert from client. When you need a different shutdown # approach you can use one of the following variables: # o ssl-unclean-shutdown: # This forces an unclean shutdown when the connection is closed, i.e. no # SSL close notify alert is send or allowed to received. This violates # the SSL/TLS standard but is needed for some brain-dead browsers. Use # this when you receive I/O errors because of the standard approach where # mod_ssl sends the close notify alert. # o ssl-accurate-shutdown: # This forces an accurate shutdown when the connection is closed, i.e. a # SSL close notify alert is send and mod_ssl waits for the close notify # alert of the client. This is 100% SSL/TLS standard compliant, but in # practice often causes hanging connections with brain-dead browsers. Use # this only for browsers where you know that their SSL implementation # works correctly. # Notice: Most problems of broken clients are also related to the HTTP # keep-alive facility, so you usually additionally want to disable # keep-alive for those clients, too. Use variable "nokeepalive" for this. # Similarly, one has to force some clients to use HTTP/1.0 to workaround # their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and # "force-response-1.0" for this. BrowserMatch "MSIE [2-6]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 # MSIE 7 and newer should be able to use keepalive BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown # }}} # /ivxv/data - data files for UI {{{ # Aliases for data files in file system # Access to files is defined in Alias "/ivxv/data/ballot-box" "/var/lib/ivxv/ballot-box/" Alias "/ivxv/data/commands" "/var/lib/ivxv/commands/" Alias "/ivxv/data/" "/var/lib/ivxv/admin-ui-data/" # }}} # /ivxv/cgi - CGI application for UI {{{ # Define CGI application alias WSGIScriptAlias "/ivxv/cgi" "/var/www/cgi/ivxv-admin.wsgi" # }}} # Main site Require all denied ExpiresActive on ExpiresDefault "access plus 1 minute" # Allow all roles to access main site Require all granted Require all granted Require all granted # Exported votes downloadable through user interface Require all denied ExpiresActive on ExpiresDefault "access plus 1 second" Require all granted Require all granted # Command files with command status files Require all denied ExpiresActive on ExpiresDefault "access plus 1 second" # All config command files (bdoc, zip) and command status files (json) for admin Require all granted # Voting list command files for election config manager Require all granted # Voter list update files for election config manager Require all granted # JSON data for user interface AllowOverride None Require all denied ExpiresActive on ExpiresDefault "access plus 1 second" # Districts list, stats and status for every role Require all granted Require all granted Require all granted # Uploading status files for every role Require all granted Require all granted Require all granted # vim:ft=apache foldmethod=marker: ================================================ FILE: collector-admin/config/rsyslog.conf ================================================ # IVXV Internet voting framework # Logging configuration # /etc/rsyslog.d/90-ivxv-admin.conf # Write audit log in JSON format if ($programname == 'ivxv_audit_log') then action( type="omfile" file="/var/log/ivxv/ivxv-audit.log" # template is defined by ivxv-common package template="ivxv-json" ) ================================================ FILE: collector-admin/ivxv-collector-admin.conf ================================================ # IVXV Internet voting framework # Config file for collector admin utilities # This file should normally installed at /etc/ivxv-admin-utils.conf [DEFAULT] # base directory for management service data files #ivxv_admin_data_path = /var/lib/ivxv # directory for admin UI static data files (used directly by web UI) #admin_ui_data_path = %(ivxv_admin_data_path)s/admin-ui-data # directory for admin UI permissions #permissions_path = %(ivxv_admin_data_path)s/admin-ui-permissions # directory for applied command files #command_files_path = %(ivxv_admin_data_path)s/commands # directory for collector config files #active_config_files_path = /etc/ivxv # directory for uploaded files #file_upload_path = %(ivxv_admin_data_path)s/upload # directory for exported votes #exported_votes_path = %(ivxv_admin_data_path)s/ballot-box # directory for ivxv debian packages #deb_pkg_path = /etc/ivxv/debs # directory for VIS related data files (voter lists) #vis_path = %(ivxv_admin_data_path)s/vis # directory for service specific files #service_files_path = %(ivxv_admin_data_path)s/service # management database directory #ivxv_db_path = %(ivxv_admin_data_path)s/db # management database file path #ivxv_db_file_path = %(ivxv_db_path)s/ivxv-management.db # ADMIN UTILS LOGGING # https://docs.python.org/3/howto/logging.html [loggers] keys=root, ivxv_admin.admin_util, ivxv_admin.command_file, ivxv_admin.db, ivxv_admin.http_daemon, ivxv_admin.lib, ivxv_admin.service [handlers] keys=null, console, stdout, stdout_service, syslog [formatters] keys=console, stdout, stdout_service, syslog # LOGGERS # root logger [logger_root] level=DEBUG # Send all log to syslog handlers=syslog # Admin utility logger [logger_ivxv_admin.admin_util] level=DEBUG qualname=ivxv_admin.admin_util handlers=stdout # Command file handling module logger [logger_ivxv_admin.command_file] level=DEBUG qualname=ivxv_admin.command_file handlers=console # Database layer logger [logger_ivxv_admin.db] level=INFO qualname=ivxv_admin.db handlers=console # Management daemon logger [logger_ivxv_admin.http_daemon] level=INFO qualname=ivxv_admin.http_daemon handlers=null # Lib module logger [logger_ivxv_admin.lib] level=DEBUG qualname=ivxv_admin.lib handlers=console # Service configurator logger [logger_ivxv_admin.service] level=DEBUG qualname=ivxv_admin.service handlers=stdout_service # LOG HANDLERS # Console handler - output log to stderr [handler_console] class=StreamHandler level=INFO formatter=console args=(sys.stderr,) # Stdout handler - output log to stdout [handler_stdout] class=StreamHandler level=INFO formatter=stdout args=(sys.stdout,) # Stdout handler for service module - output log to stdout [handler_stdout_service] class=StreamHandler level=INFO formatter=stdout_service args=(sys.stdout,) # Null handler - drop log messages [handler_null] class=NullHandler args=() # Syslog handler [handler_syslog] class=handlers.SysLogHandler level=DEBUG formatter=syslog args=('/dev/log', handlers.SysLogHandler.LOG_LOCAL4) # LOG FORMATTERS # console formatter [formatter_console] format=%(module)s:%(levelname)s: %(message)s # stdout formatter [formatter_stdout] format=%(levelname)s: %(message)s # stdout formatter for service module [formatter_stdout_service] format=%(message)s # syslog formatter [formatter_syslog] format=%(name)s %(message)s # vim:ft=dosini: ================================================ FILE: collector-admin/ivxv_admin/__init__.py ================================================ # IVXV Internet voting framework """Collector Management Service.""" __version__ = '1.10.3' DEB_PKG_VERSION = '1.10.3' #: Management daemon data MANAGEMENT_DAEMON_PORT = 8080 MANAGEMENT_DAEMON_URL = f"http://localhost:{MANAGEMENT_DAEMON_PORT}/" #: RFC3339 date format RFC3339_DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.%f' #: RFC3339 date format (without second fractions) RFC3339_DATE_FORMAT_WO_FRACT = '%Y-%m-%dT%H:%M:%SZ' #: User permissions PERMISSION_BALLOT_BOX_DOWNLOAD = 'download-ballot-box' PERMISSION_ELECTION_CONF = 'election-conf-admin' PERMISSION_LOG_VIEW = 'log-view' PERMISSION_STATS_VIEW = 'stats-view' PERMISSION_TECH_CONF = 'tech-conf-admin' PERMISSION_USERS_ADMIN = 'user-admin' #: User roles USER_ROLES = { 'admin': { 'description': 'Administrator', 'permissions': ( PERMISSION_BALLOT_BOX_DOWNLOAD, PERMISSION_ELECTION_CONF, PERMISSION_LOG_VIEW, PERMISSION_STATS_VIEW, PERMISSION_TECH_CONF, PERMISSION_USERS_ADMIN, ), }, 'election-conf-manager': { 'description': 'Election config manager', 'permissions': ( PERMISSION_BALLOT_BOX_DOWNLOAD, PERMISSION_ELECTION_CONF, PERMISSION_STATS_VIEW ), }, 'viewer': { 'description': 'Viewer', 'permissions': ( PERMISSION_STATS_VIEW, ), }, 'none': { 'description': 'No permissions', 'permissions': tuple(), }, } #: Config types CFG_TYPES = { 'trust': 'trust root configuration', 'election': 'elections configuration', 'technical': 'collectors technical configuration', } #: Voting list types VOTING_LIST_TYPES = { 'choices': 'choices list', 'districts': 'districts list', 'voters': 'voters list', } #: Command types CMD_TYPES = list(CFG_TYPES) + list(VOTING_LIST_TYPES) + ['user'] #: Command descriptions CMD_DESCR = {'user': 'user permissions configuration'} CMD_DESCR.update(CFG_TYPES) CMD_DESCR.update(VOTING_LIST_TYPES) #: Collector states COLLECTOR_STATE_NOT_INSTALLED = 'NOT INSTALLED' COLLECTOR_STATE_INSTALLED = 'INSTALLED' COLLECTOR_STATE_CONFIGURED = 'CONFIGURED' COLLECTOR_STATE_FAILURE = 'FAILURE' COLLECTOR_STATE_PARTIAL_FAILURE = 'PARTIAL FAILURE' COLLECTOR_STATES = [ COLLECTOR_STATE_NOT_INSTALLED, COLLECTOR_STATE_INSTALLED, COLLECTOR_STATE_CONFIGURED, COLLECTOR_STATE_FAILURE, COLLECTOR_STATE_PARTIAL_FAILURE, ] #: Service states SERVICE_STATE_NOT_INSTALLED = 'NOT INSTALLED' SERVICE_STATE_INSTALLED = 'INSTALLED' SERVICE_STATE_CONFIGURED = 'CONFIGURED' SERVICE_STATE_FAILURE = 'FAILURE' SERVICE_STATE_REMOVED = 'REMOVED' SERVICE_STATES = [ SERVICE_STATE_NOT_INSTALLED, SERVICE_STATE_INSTALLED, SERVICE_STATE_CONFIGURED, SERVICE_STATE_FAILURE, SERVICE_STATE_REMOVED, ] #: Service states included to status monitoring SERVICE_MONITORING_STATES = [SERVICE_STATE_CONFIGURED, SERVICE_STATE_FAILURE] #: Service type parameters. #: ``main_service`` - is service required to collect votes #: (*False* = support service); #: **require_config** - does service require election config package for #: operation; #: ``require_tls`` - does service require TLS certificate and key to #: ``tspreg`` - can communicate with TSP registration service #: ``mobile_id`` - can communicate with Mobile ID service #: communicate with other services; SERVICE_TYPE_PARAMS = { 'backup': { 'main_service': False, 'require_config': False, 'require_tls': False, 'tspreg': False, 'mobile_id': False, }, 'choices': { 'main_service': True, 'require_config': True, 'require_tls': True, 'tspreg': False, 'mobile_id': True, }, 'log': { 'main_service': False, 'require_config': False, 'require_tls': False, 'tspreg': False, 'mobile_id': False, }, 'mid': { 'main_service': True, 'require_config': True, 'require_tls': True, 'tspreg': False, 'mobile_id': True, }, 'votesorder': { 'main_service': True, 'require_config': True, 'require_tls': True, 'tspreg': False, 'mobile_id': False, }, 'proxy': { 'main_service': True, 'require_config': True, 'require_tls': False, 'tspreg': False, 'mobile_id': False, }, 'smartid': { 'main_service': True, 'require_config': True, 'require_tls': True, 'tspreg': False, 'mobile_id': True, }, 'webeid': { 'main_service': True, 'require_config': True, 'require_tls': True, 'tspreg': False, 'mobile_id': True, }, 'storage': { 'main_service': True, 'require_config': True, 'require_tls': True, 'tspreg': False, 'mobile_id': False, }, 'verification': { 'main_service': True, 'require_config': True, 'require_tls': True, 'tspreg': False, 'mobile_id': False, }, 'voting': { 'main_service': True, 'require_config': True, 'require_tls': True, 'tspreg': True, 'mobile_id': True, }, 'sessionstatus': { 'main_service': True, 'require_config': True, 'require_tls': True, 'tspreg': False, 'mobile_id': False, }, } #: Service secret types SERVICE_SECRET_TYPES = { 'tls-cert': { 'description': 'Service TLS certificate', 'db-key': 'tls-cert', 'target-path': '/var/lib/ivxv/service/{service_id}/tls.pem', 'shared': False, }, 'tls-key': { 'description': 'Service TLS key', 'db-key': 'tls-key', 'target-path': '/var/lib/ivxv/service/{service_id}/tls.key', 'shared': False, }, 'mid-token-key': { 'description': 'Mobile-ID/Smart-ID/Web eID identity token', 'db-key': 'mid-token-key', 'target-path': '/var/lib/ivxv/service/ticket.key', 'shared': True, }, 'tsp-regkey': { 'description': 'PKIX TSP registration key', 'db-key': 'tspreg-key', 'target-path': '/var/lib/ivxv/service/{service_id}/tspreg.key', 'shared': False, }, } #: Filenames of collector deb packages COLLECTOR_PKG_FILENAMES = { 'ivxv-admin': f'ivxv-admin_{DEB_PKG_VERSION}_amd64.deb', 'ivxv-backup': f'ivxv-backup_{DEB_PKG_VERSION}_amd64.deb', 'ivxv-choices': f'ivxv-choices_{DEB_PKG_VERSION}_amd64.deb', 'ivxv-common': f'ivxv-common_{DEB_PKG_VERSION}_all.deb', 'ivxv-log': f'ivxv-log_{DEB_PKG_VERSION}_all.deb', 'ivxv-mid': f'ivxv-mid_{DEB_PKG_VERSION}_amd64.deb', 'ivxv-votesorder': f'ivxv-votesorder_{DEB_PKG_VERSION}_amd64.deb', 'ivxv-smartid': f'ivxv-smartid_{DEB_PKG_VERSION}_amd64.deb', 'ivxv-webeid': f'ivxv-webeid_{DEB_PKG_VERSION}_amd64.deb', 'ivxv-proxy': f'ivxv-proxy_{DEB_PKG_VERSION}_amd64.deb', 'ivxv-storage': f'ivxv-storage_{DEB_PKG_VERSION}_amd64.deb', 'ivxv-verification': f'ivxv-verification_{DEB_PKG_VERSION}_amd64.deb', 'ivxv-voting': f'ivxv-voting_{DEB_PKG_VERSION}_amd64.deb', 'ivxv-sessionstatus': f'ivxv-sessionstatus_{DEB_PKG_VERSION}_amd64.deb', } #: Event log filename EVENT_LOG_FILENAME = 'ivxv-management-events.log' #: Event descriptions EVENTS = { # collector state events "COLLECTOR_INIT": "Initialize Collector", "COLLECTOR_RESET": f"Reset Collector (state: {COLLECTOR_STATE_NOT_INSTALLED!r})", "COLLECTOR_STATE_CHANGE": "Collector state changed from {last_state!r} to {state!r}", # command loading events "CMD_LOAD": "Load command {cmd_type!r} version {version!r}", "CMD_LOADED": "Command {cmd_type!r} is loaded, version {version!r}", "CMD_REMOVED": "Command {cmd_type!r} is removed, version {version!r}", # voter list downloading events "VOTER_LIST_DOWNLOADED": "Downloaded voter list changeset #{changeset_no}", "VOTER_LIST_DOWNLOAD_FAILED": "Failed to download voter list changeset #{changeset_no}", # user permission management events "PERMISSION_SET": "Add permission {permission!r} to user {user_cn!r}", "PERMISSION_RESET": "Reset user {user_cn!r} permissions", # election start/stop times registering "SET_ELECTION_TIME": "Election {period!r} timestamp set to {timestamp}", # service management events "SERVICE_REGISTER": f"Add {{service_type}} service (state: {SERVICE_STATE_NOT_INSTALLED!r})", "SERVICE_CONFIG_APPLY": 'Applied {cfg_descr} version {cfg_version!r}', "SERVICE_STATE_CHANGE": 'Service state changed from {last_state!r} to {state!r}', "SECRET_INSTALL": "{secret_descr} loaded to service", } ================================================ FILE: collector-admin/ivxv_admin/agent_daemon.py ================================================ # IVXV Internet voting framework """ Agent daemon for collector management service. This daemon is managed by systemd. * Systemd service file: :file:`/lib/systemd/system/ivxv-admin.service` * Query daemon status: :command:`systemctl status ivxv-admin` * Start daemon: :command:`systemctl stop ivxv-admin` * Stop daemon: :command:`systemctl status ivxv-admin` """ import datetime import json import logging import os import re import subprocess import time import typing import dateutil.parser from . import (CMD_DESCR, RFC3339_DATE_FORMAT, SERVICE_MONITORING_STATES, SERVICE_STATE_CONFIGURED, SERVICE_STATE_FAILURE, lib) from .cli_utils import init_cli_util from .config import cfg_path from .db import DB_FILE_PATH, IVXVManagerDb from .event_log import register_service_event from .lib.lockfile import PidLocker from .service.service import Service # create logger log = logging.getLogger(__name__) #: Service ping interval in seconds. PING_INTERVAL = 60 #: State file path. STATE_FILEPATH = cfg_path("admin_ui_data_path", "status.json") #: Stats file path. STATS_FILEPATH = cfg_path('admin_ui_data_path', 'stats.json') #: Maximum count of automatic attempts to apply config MAX_AUTO_ATTEMPTS = 3 #: Unix epoch timestamp UNIX_EPOCH_TIMESTAMP = '1970-01-01T00:00:00' def main_loop(): """Agent daemon main loop.""" args = init_cli_util(""" IVXV Collector Management Service agent daemon. Usage: ivxv-agent-daemon [--get-stats] [--register-status] Options: --get-stats Copy statistics from Log Monitor to Management Service without daemonizing. --register-status Register collector state (if not registered). """) # copy stats and finish process if args['--get-stats'] and args["--register-status"]: log.error('Conflicting options: --get-stats and --register-status') return 1 if args['--get-stats']: return generate_stats_data(force=True) if args["--register-status"]: with IVXVManagerDb(for_update=True) as db: register_collector_state(db) return 0 # daemon process log.info('Starting Collector Management Service agent daemon') check_management_db() jobs: typing.Set[subprocess.Popen] = set() while True: loop_start_time = datetime.datetime.now() # generate stats/state data state = None try: PidLocker.rm_stale_pidfile('ivxv-config-apply.pid') state = generate_state_data() generate_stats_data() except OSError as err: log.error(err) except Exception as err: # pylint: disable=broad-except log.error( 'Unknown error while generating stats/state data: %s', err) finally: for job in jobs: if job.poll() is not None: # job is not yet terminated if job.stdin is not None: job.stdin.close() if job.stdout is not None: job.stdout.close() if job.stderr is not None: job.stderr.close() job.kill() # send SIGKILL to terminated process, just in case jobs.remove(job) # start config applying if required if state and len(jobs) == 0: jobs = apply_cfg(state) # pause after loop duration = datetime.datetime.now() - loop_start_time if duration.seconds < 5: log.debug('Sleeping for 5 seconds') time.sleep(5) else: time.sleep(1) def generate_state_data(): """ Ping services, generate state data and write it to :file:`status.json`. """ # fetch services data services = get_collector_data() if services: # sort services list in order of last data services_sorted = sorted([ [service['last-data'], service_id] for service_id, service in services.items()]) # check services for last_data_timestamp, service_id in services_sorted: service_data = services[service_id] if service_data['state'] not in SERVICE_MONITORING_STATES: # log.debug('Service %s state is %s, skipping check', # service_id, service_data['state']) continue next_check_timestamp = ( dateutil.parser.parse(last_data_timestamp or UNIX_EPOCH_TIMESTAMP) + datetime.timedelta(seconds=PING_INTERVAL)) if next_check_timestamp > datetime.datetime.now(): log.debug('Service %s next check is in the future, ' 'skipping check', service_id) continue ping_service(service_id, service_data) time.sleep(1) # generate state data with IVXVManagerDb(for_update=True) as db: state = register_collector_state(db) # generate config applying state state['config-apply'] = {} for cfg_key in ['trust', 'technical', 'election', 'choices', 'districts']: get_cfg_applying_state(cfg_key, state) for changeset_no in range(10_000): if not get_cfg_applying_state(f"voters{changeset_no:04}", state): break # write state data to file state['meta'] = get_agent_metadata() with open(STATE_FILEPATH, "w") as fp: fp.write(json.dumps(state, indent=4, sort_keys=True)) return state def get_cfg_applying_state(cfg_key, state): """Get config applying state. :return: True if config file exist and state data is generated, False if config file does not exist. """ cfg_filepath = lib.get_loaded_cfg_file_path(cfg_key) if cfg_filepath is None: return False state_file_filepath = cfg_filepath.replace( os.path.splitext(cfg_filepath)[1], ".json" ) try: with open(state_file_filepath) as fp: apply_state = json.load(fp) state['config-apply'][cfg_key] = { 'version': apply_state['config_version'], 'attempts': apply_state['attempts'], 'completed': apply_state['completed'], 'state_file': os.path.basename(state_file_filepath), } except FileNotFoundError: state['config-apply'][cfg_key] = {} state['config-apply'][cfg_key]['cmd_file'] = os.path.basename(cfg_filepath) return True def get_agent_metadata(): """Generate agent metadata block.""" timestamp = datetime.datetime.utcnow() return dict(generator='IVXV Management Service Agent Daemon', time_generated=timestamp.strftime('%Y-%m-%dT%H:%M:%SZ')) def apply_cfg(state) -> typing.Set[subprocess.Popen]: """Apply config files.""" jobs: typing.Set[subprocess.Popen] = set() job = apply_cfg_for_services("technical", "technical", state) if job is not None and job is not False: jobs.add(job) if state['config']['technical']: for cfg_key in ["election", "choices", "districts"]: job = apply_cfg_for_services(cfg_key, cfg_key, state) if job is not None and job is not False: jobs.add(job) for changeset_no in range(10_000): job = apply_cfg_for_services("voters", f"voters{changeset_no:04}", state) if job is None: # voter list doesn't exist or currently being loaded break if job is False: # voter list has already been loaded continue jobs.add(job) return jobs def apply_cfg_for_services(cfg_type, cfg_key, state) -> subprocess.Popen | bool | None: """Apply config for services. :return: None if config file does not exist, True if config applying is started, False if config applying is not started. """ cfg_filepath = lib.get_loaded_cfg_file_path(cfg_key) if cfg_filepath is None: return None state_file_filepath = cfg_filepath.replace( os.path.splitext(cfg_filepath)[1], ".json" ) with open(state_file_filepath) as fp: state = json.load(fp) # check preconditions if (not state['autoapply'] or state['completed'] or state['attempts'] >= MAX_AUTO_ATTEMPTS): return False if PidLocker.pidfile_exists('ivxv-config-apply.pid'): log.info('Can\'t start automatic applying of %s, pidfile exists', CMD_DESCR[cfg_type]) return None # execute config applying command log.info('Automatically apply %s, attempt #%d', CMD_DESCR[cfg_type], state['attempts'] + 1) return subprocess.Popen( args=['ivxv-config-apply', f'--type={cfg_type}'], stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) def ping_service(service_id, service_data): """Ping service.""" with Service(service_id, service_data) as service: service_ok = service.ping() if not is_db_accessible(service.get_db_key("last-data")): return False # register result in database with IVXVManagerDb(for_update=True) as db: db.set_value( service.get_db_key('last-data'), datetime.datetime.now().strftime(RFC3339_DATE_FORMAT)) ping_errors_key = service.get_db_key('ping-errors') ping_errors_old = db.get_value(ping_errors_key) service_state_key = service.get_db_key('state') service_state_old = db.get_value(service_state_key) if service_state_old not in SERVICE_MONITORING_STATES: log.warning('Service has removed from monitoring') return False service_state_new = service_state_old if service_ok: log.debug('Service %s is alive', service_id) ping_errors_new = '0' service_state_new = SERVICE_STATE_CONFIGURED if ping_errors_old != '0': db.set_value(ping_errors_key, '0') else: ping_errors_new = str(int(ping_errors_old) + 1) if (int(ping_errors_new) >= 3 and service_state_old != SERVICE_STATE_FAILURE): log.warning('Status check failed three times, ' 'setting service state from %s to FAILURE', service_state_old) service_state_new = SERVICE_STATE_FAILURE else: log.warning('Status check for service %s failed (%s times). ' 'Service state is %s', service_id, ping_errors_new, service_state_old) if ping_errors_old != ping_errors_new: db.set_value(ping_errors_key, ping_errors_new) if service_state_old != service_state_new: db.set_value(service_state_key, service_state_new) register_collector_state(db) return service_ok def generate_stats_data(force=False): """Generate stats data and write it to :file:`stats.json`. :param force: Force check even the next check timestamp is in the future. :type force: bool """ # read existing stats file stats = {} try: with open(STATS_FILEPATH) as fp: stats = json.load(fp) except json.decoder.JSONDecodeError as err: log.error("Invalid JSON in existing stats file %r: %s", STATS_FILEPATH, err) except OSError as err: log.error("Cannot load existing stats JSON file %r: %s", STATS_FILEPATH, err) stats.setdefault('data', {}) # import stats file from Log Monitor logmon_address, last_data_timestamp = get_logmon_data() if logmon_address: next_check_timestamp = ( dateutil.parser.parse(last_data_timestamp) + datetime.timedelta(seconds=PING_INTERVAL)) if not force and next_check_timestamp > datetime.datetime.now(): log.debug('Log Monitor service next check is in the future, ' 'skipping check') else: stats_data = query_logmon_stats(logmon_address) if 'error' in stats_data: stats['error'] = stats_data['error'] else: normalize_stats(stats_data) stats['data'] = stats_data try: del stats['error'] except KeyError: pass else: stats = {'error': 'Log Monitor address is not defined'} log.error(stats['error']) # update metadata stats['meta'] = get_agent_metadata() # write stats data to file with open(STATS_FILEPATH, 'w') as fp: fp.write(json.dumps(stats, indent=4, sort_keys=True)) def normalize_stats(stats_data): """Normalize Log Monitor stats. Convert dictionaries to sorted lists. """ for district_id, district_stats in sorted(stats_data.items()): if district_id == 'time': continue for stats_key, stats_val in district_stats.items(): if isinstance(stats_val, dict): stats_data[district_id][stats_key] = sorted( [[item[0], item[1]] for item in stats_val.items()], reverse=True )[:10 if stats_key in [ 'voting-operating-systems', 'verify-operating-system'] else 100] # generate empty values for missing districts. # Log Monitor does not have district list and cannot generate stats for # districts that have no voter data. Generate empty data for such # districts. districts = [] districts_filename = cfg_path('admin_ui_data_path', 'districts.json') try: with open(districts_filename) as fp: districts = json.load(fp) except FileNotFoundError: log.debug('Missing districts list. ' 'Will not generate empty blocks for missing districts') empty_stats = dict( [key, (list() if isinstance(val, list) else 0)] for key, val in stats_data['TOTAL'].items()) for district_id, _ in districts: if district_id not in stats_data: stats_data[district_id] = empty_stats def query_logmon_stats(address): """Query stats file from Log Monitor service. Query stats file from Log Monitor service and register last query timestamp in the management database. :return: Stats data. Existing stats data is returned with error message in ``error`` value if query fails. :rtype: dict """ ssh_cmd = [ 'ssh', '-T', '-o', 'PreferredAuthentications=publickey', f"logmon@{address}", "cat", "/var/lib/ivxv/stats.json" ] log.debug('Querying stats from Log Monitor') proc = subprocess.run( ssh_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False ) stats = {} if proc.returncode: log.error( 'Querying stats from Log Monitor finished with error code %d', proc.returncode) stats['error'] = ( 'Error while transporting stats data from Log Monitor over SSH:' f"\n {proc.stderr.decode('utf-8')}" ) else: try: stats = json.loads(proc.stdout.decode('utf-8')) except json.JSONDecodeError as err: errmsg = f"{err.msg}: line {err.lineno} column {err.colno} (char {err.pos})" stats['error'] = f'Invalid JSON data from Log Monitor: {errmsg}' log.error('Error while parsing JSON stats from Log Monitor: %s', errmsg) if is_db_accessible("logmonitor/last-data"): with IVXVManagerDb(for_update=True) as db: db.set_value('logmonitor/last-data', datetime.datetime.now().strftime(RFC3339_DATE_FORMAT)) return stats def check_management_db(): """Check management database file. Wait if database file does not exist. """ # wait if database does not exist check_interval = 1 check_notif_interval = 60 check_counter = 0 while not os.path.exists(DB_FILE_PATH): if check_counter % check_notif_interval == 0: log.warning('Collector management database does not exist, ' 'waiting') check_counter += 1 time.sleep(check_interval) log.info('Collector management database is available') def get_collector_data(): """Read collector data from management database. :return: service data or None if election config is not loaded. :rtype: dict """ with IVXVManagerDb() as db: election_cfg_ver = db.get_value('config/election') if not election_cfg_ver: return None services = {} for key in db.keys(): if re.match(r'service/', key): service_id, field_name = key.split('/')[1:] services[service_id] = services.get(service_id, {}) services[service_id][field_name] = db.get_value(key) return services def get_logmon_data(): """Read logmonitor address from management database. :return: Log Monitor data: [address, last_data_timestamp]. :rtype: list """ with IVXVManagerDb() as db: address = db.get_value('logmonitor/address') last_data_timestamp = db.get_value('logmonitor/last-data') if not last_data_timestamp: last_data_timestamp = UNIX_EPOCH_TIMESTAMP return [address, last_data_timestamp] def register_collector_state(db): """Detect collector state and register state change in database.""" state = lib.generate_collector_state(db) last_state = state['collector']['state'] if state['collector_state'] != last_state: log.info('Registering new state for collector: %s', state['collector_state']) db.set_value('collector/state', state['collector_state']) register_service_event( 'COLLECTOR_STATE_CHANGE', params={ 'state': state['collector_state'], 'last_state': last_state }) return state def is_db_accessible(check_value): """Try to read field value from database before writing it. If this fails, then something is happened with database (e.g. database is recreated during service reset) and writing to database must be cancelled. """ with IVXVManagerDb() as db: try: db.get_value(check_value) except KeyError: log.warning("Cannot read value %r from database", check_value) return False return True ================================================ FILE: collector-admin/ivxv_admin/cli_utils/__init__.py ================================================ # IVXV Internet voting framework """CLI utilities.""" import logging import os import sys import textwrap from docopt import docopt from .. import __version__ from ..config import CONFIG assert CONFIG # logging is configured by config module log = logging.getLogger('ivxv_admin.admin_util') def init_cli_util(docstr, allow_root=False): """ Initialize command line utility. 1. Validate command line arguments 2. Set up logging Config file :file:`ivxv-collector-admin.conf` is searched from the following locations: * current directory * :file:`/etc/ivxv` * directory specified by environment variable :envvar:`IVXV_ADMIN_CONF` * file specified by environment variable :envvar:`IVXV_ADMIN_CONF` """ # validate CLI arguments cli_args = docopt(textwrap.dedent(docstr), version=__version__) # set log level log.setLevel(cli_args.get('--log-level', 'INFO')) # check user rights if not allow_root and not os.getuid(): log.error('IVXV collector admin utils cannot be run as root') sys.exit(1) return cli_args def ask_user_confirmation(question): """Ask user confirmation. :return: True if user answers "Yes" or False if not. """ while True: answer = input(question).upper() if answer in 'YN': return answer == 'Y' ================================================ FILE: collector-admin/ivxv_admin/cli_utils/admin_storage_utils.py ================================================ # IVXV Internet voting framework """CLI utilities for management service data storage.""" import os import re import shutil import sys from .service_utils import remove_ivxv_admin_crontab from ..config import CONFIG, cfg_path from ..db import IVXVManagerDb, check_db_dir from ..event_log import init_event_log from ..lib import IvxvError, clean_dir from . import ask_user_confirmation, init_cli_util, log #: Config value names for Management Service data directories MANAGEMENT_PATH_PARAM_NAMES = [ 'ivxv_admin_data_path', 'admin_ui_data_path', 'permissions_path', 'command_files_path', 'active_config_files_path', 'file_upload_path', 'exported_votes_path', 'deb_pkg_path', 'ivxv_db_path', 'vis_path', ] def ivxv_create_data_dirs_util(): """Create management service data directories.""" init_cli_util( """ Create IVXV Collector Management Service data directories. NOTE: Directory owners and permissions are not set by this utility! Usage: ivxv-create-data-dirs """, allow_root=True) # config parameter names for directories for cfg_var in MANAGEMENT_PATH_PARAM_NAMES: dirname = CONFIG[cfg_var] if os.path.exists(dirname): log.info("Path %r already exist", dirname) else: log.info("Creating data directory %r", dirname) os.mkdir(dirname) if not os.path.isdir(dirname): log.error("Path %r is not a directory", dirname) return 1 return 0 def ivxv_collector_init_util(): """Initialize IVXV Collector.""" args = init_cli_util(""" Initialize IVXV Collector. Usage: ivxv-collector-init [--force] Options: --force Don't ask user confirmation """) # ask confirmation if not args['--force']: if not ask_user_confirmation( 'Do You want to initialize IVXV Collector (Y=yes) ?'): return 1 # remove ivxv-admin crontab if exist remove_ivxv_admin_crontab() # initialize data directories try: init_data_directories() except IvxvError as err: log.error(err) return 1 # initialize management database init_management_database() init_event_log() return 0 def database_util(): """Management service database utility.""" args = init_cli_util(""" Add, remove or modify key/value pairs in IVXV Collector Management Service database. WARNING! Use this utility only for testing purposes! Never change database in production systems! Usage: ivxv-db ivxv-db --del """) # check database directory if not check_db_dir(): return 1 # process record with IVXVManagerDb(for_update=True) as db: if args['--del']: db.rm_value(args['']) log.info("Database value %r successfully removed", args[""]) else: db.set_value(args[''], args['']) log.info("Database value %r set to %r", args[""], args[""]) return 0 def database_dump_util(): """Dump management service database.""" args = init_cli_util(""" Dump IVXV Collector Management Service database. Usage: ivxv-db-dump [] ... """) log.info('Dumping IVXV management database') # check database directory if not check_db_dir(): return 1 with IVXVManagerDb() as db: db.dump(args['']) return 0 def database_reset_util(): """Reset management service database.""" args = init_cli_util(""" Reset IVXV Collector Management Service database. Usage: ivxv-db-reset [--force] Options: --force Don't ask user confirmation """) # check database directory db_file_path = check_db_dir() if not db_file_path: return 1 # ask confirmation if not args['--force']: if not ask_user_confirmation( 'Do You want to reset IVXV management database (Y=yes) ?'): return 1 # initialize database init_management_database() # initialize data files init_management_datafiles() # initialize data directories clean_dir(CONFIG['file_upload_path']) return 0 def init_data_directories(): """Initialize data directories.""" for cfg_var in MANAGEMENT_PATH_PARAM_NAMES: dirpath = CONFIG[cfg_var] if not os.path.exists(dirpath): log.info("Creating directory %r", dirpath) os.mkdir(dirpath) elif not os.path.isdir(dirpath): raise IvxvError(f"Path {dirpath!r} is not a directory") if cfg_var not in [ "ivxv_admin_data_path", "deb_pkg_path", "active_config_files_path", ]: clean_dir(dirpath) patterns = ( r"(choices|districts|election|technical|trust|voters0000)\.bdoc$", r"voters[0-9]{2}\.zip$", ) for filename in os.listdir(CONFIG["active_config_files_path"]): if any(re.match(pattern, filename) for pattern in patterns): os.unlink(cfg_path("active_config_files_path", filename)) init_management_datafiles() def init_management_database(): """Initialize management database.""" log.debug('Initializing IVXV management database') IVXVManagerDb.reset() log.info('New management database is created with default values') def init_management_datafiles(): """Initialize management data files.""" # install empty stats.json to admin UI data path module_path = os.path.dirname(sys.modules['ivxv_admin'].__file__) file_path = os.path.join(module_path, 'templates/stats.json') shutil.copy(file_path, CONFIG['admin_ui_data_path']) ================================================ FILE: collector-admin/ivxv_admin/cli_utils/backup_utils.py ================================================ # IVXV Internet voting framework """CLI utilities for backup service.""" import datetime import os import random import subprocess import sys import time from jinja2 import Environment, PackageLoader from .. import SERVICE_STATE_CONFIGURED from ..config import CONFIG from ..lib import get_services from ..service.service import Service from . import init_cli_util, log def insert_backup_crontab(data: str, crontab: str) -> str: """Wrap crontab in an ivxv_backup_crontab block and insert it to a data. :param data: any data :type data: str :param crontab: rendered ivxv_backup_crontab Jinja2 crontab template file :type crontab: str :return: data with an ivxv_backup_crontab block :rtype: str """ header = '### block ivxv_backup_crontab ###' tail = '### endblock ivxv_backup_crontab ###' return data + "\n\n" + header + "\n" + crontab + "\n" + tail + "\n" def __get_backup_crontab_block(data: str) -> (str, bool): """Get ivxv_backup_crontab block from a data. :param data: any data :type data: str :return: ivxv_backup_crontab block and True on success, otherwise data and False :rtype: str, bool :raise ValueError: if ivxv_backup_crontab block's header or tail is malformed, however though, if both header and tail are malformed then function assumes that ivxv_backup_crontab block doesn't exist in a data """ header = '### block ivxv_backup_crontab ###' tail = '### endblock ivxv_backup_crontab ###' # remove leading and trailing whitespaces/newlines data_stripped = data.strip() # get start index of a header header_start_index = data_stripped.find(header) # get start index of a tail tail_start_index = data_stripped.find(tail) # both header and tail aren't present in a data_stripped if header_start_index < 0 and tail_start_index < 0: return data, False # both header and tail present in a data_stripped elif header_start_index >= 0 and tail_start_index >= 0: # get end index of a tail tail_end_index = tail_start_index + len(tail) # extract ivxv_backup_crontab block from a data_stripped return data_stripped[header_start_index:tail_end_index], True else: if header_start_index < 0: raise ValueError("malformed ### block ivxv_backup_crontab ###") else: raise ValueError("malformed ### endblock ivxv_backup_crontab ###") def remove_backup_crontab(data: str) -> str: """Remove ivxv_backup_crontab block from a data. :param data: any data :type data: str :return: data without ivxv_backup_crontab block :rtype: str """ block, found = __get_backup_crontab_block(data=data) if not found: return data return data.replace(block, '').strip() def backup_crontab_generator_util(): """Generate crontab for backup automation.""" args = init_cli_util(""" Generate crontab for IVXV backup automation. This utility must be called as editor by crontab utility: $ env VISUAL=ivxv-backup-crontab crontab -e Usage: ivxv-backup-crontab """) filepath = args[''] crontab_tmp_file_content: str # check input file try: with open(filepath) as fp: crontab_tmp_file_content = fp.read() except OSError as err: log.error("Can't read file %r: %s", filepath, err.strerror) return 1 # load crontab template tmpl_env = Environment(loader=PackageLoader('ivxv_admin', 'templates')) template = tmpl_env.get_template('ivxv_backup_crontab.jinja') # detect service states template_params = {'backup_times': []} backup_services = get_services( include_types=['backup'], service_state=[SERVICE_STATE_CONFIGURED]) for service_val in backup_services.values(): if service_val['backup-times']: template_params['backup_times'] = sorted( [[int(timeval.split(':')[0]), int(timeval.split(':')[1])] for timeval in service_val['backup-times'].split(' ')]) template_params['configured_backup_services'] = backup_services template_params['configured_voting_services'] = sorted( get_services( include_types=['voting'], service_state=[SERVICE_STATE_CONFIGURED])) template_params['configured_log_collectors'] = sorted( get_services( include_types=['log'], service_state=[SERVICE_STATE_CONFIGURED], )) # render crontab backup_crontab = template.render( time_generated=datetime.datetime.now().strftime('%d.%M.%Y %H:%M:%S'), **template_params, ) # remove old block: # ### block ivxv_backup_crontab ### # ... # ### endblock ivxv_backup_crontab ### # from a crontab temporary file if any exists try: without_backup_crontab = remove_backup_crontab( data=crontab_tmp_file_content) except ValueError as err: msg = "Can't remove ivxv_backup_crontab block from a temporary file %r: %s" log.error(msg, filepath, err.__str__()) return 1 # add new block to a crontab temporary file crontab = insert_backup_crontab( data=without_backup_crontab, crontab=backup_crontab) # Pause for 1 second. Crontab checks mtime to detect file modifications. It # seems that crontab can't detect mtime change if changes happens too # quickly (tested in Ubuntu Xenial). time.sleep(1) # override crontab temporary file with a new content try: with open(filepath, 'w') as fp: fp.write(crontab) except OSError as err: log.error("Can't write file %r: %s", filepath, err.strerror) return 1 return 0 def backup_util(): """Backup collector data.""" args = init_cli_util(""" Backup IVXV collector data. Usage: ivxv-backup management-conf ivxv-backup ballot-box [] ivxv-backup log """) # execute ballot box and log backup command with ssh-agent wrapper if ((args['ballot-box'] or args['log']) and not os.environ.get('SSH_AUTH_SOCK') and not os.environ.get('SSH_AGENT_PID')): log.debug('Starting command with ssh-agent wrapper') os.execvp('ssh-agent', ['ssh-agent'] + sys.argv) services = get_services(include_types=['backup'], service_state=[SERVICE_STATE_CONFIGURED]) if not services: log.error('Backup service is not defined') return 1 # Only 1 'CONFIGURED' backup service is allowed at the same time assert len(services) == 1 with Service(*list(services.items())[0]) as backup_service: log.debug('Backup service: %s', backup_service.service_id) if backup_service.data['state'] != SERVICE_STATE_CONFIGURED: log.error("Backup service state is %r (expected state is %r)", backup_service.data['state'], SERVICE_STATE_CONFIGURED) return 1 if args['management-conf']: return backup_management_cfg(backup_service) # copy list of known SSH hosts to backup server backup_service.scp( os.path.expanduser('~/.ssh/known_hosts'), '~/.ssh/', 'list of known SSH hosts') backup_timestamp = datetime.datetime.now().strftime('%Y%m%d_%H%M') if args['ballot-box']: backup_target = datetime.datetime.now().strftime( f'ballot-box-{backup_timestamp}.zip') services = get_services( include_types=['voting'], service_state=[SERVICE_STATE_CONFIGURED], ) voting_service_id = ( args[''] or random.choice(list(services))) if args[''] and voting_service_id not in services: log.error('Unknown voting service ID: %s', voting_service_id) return 1 with Service(voting_service_id, services[voting_service_id]) as service: proc = backup_service.ssh( [ 'ivxv-admin-sudo', 'backup-ballot-box', service.hostname, voting_service_id, backup_target, ], fwd_auth_agent=True, ) else: assert args['log'] services = get_services( include_types=['log'], service_state=[SERVICE_STATE_CONFIGURED]) for log_collector_id in services: with Service(log_collector_id, services[log_collector_id]) as service: proc = backup_service.ssh( [ 'ivxv-admin-sudo', 'backup-log', service.hostname, backup_timestamp, ], fwd_auth_agent=True, ) if proc.returncode: break if proc.returncode: log.error('Command execution failed with error code %d', proc.returncode) return 1 return 0 def exec_backup_service_cmd(backup_service, *cmd): """Execute command in backup service. :raises OSError: if command fails """ proc = backup_service.ssh(list(cmd)) if proc.returncode: raise OSError( f"Command {' '.join(cmd)} failed in backup service " f"with exit code {proc.returncode}" ) def backup_management_cfg(backup_service): """Creating management config backup.""" log.info('Creating management config backup') backup_target = datetime.datetime.now().strftime('%Y%m%d_%H%M') backup_basedir = '/var/backups/ivxv/management-conf' backup_tmpdir = os.path.join(backup_basedir, f'tmp-{backup_target}') backup_tgt_path = os.path.join(backup_basedir, backup_target) dirs_to_backup = [ ['config', '/etc/ivxv', 'etc'], [ 'admin UI permissions', CONFIG['permissions_path'], 'admin-ui-permissions' ], ['command history', CONFIG['command_files_path'], 'commands'], ] try: exec_backup_service_cmd(backup_service, "rm", "-rfv", backup_tmpdir) exec_backup_service_cmd(backup_service, "mkdir", "-v", backup_tmpdir) for description, src_dir, tgt_dir in dirs_to_backup: log.info("Backing up %s directory %r", description, src_dir) subprocess.run( [ 'rsync', '-av', '--del', f"{src_dir}/", f'{backup_service.hostname}:{backup_tmpdir}/{tgt_dir}/', ], check=True, ) exec_backup_service_cmd(backup_service, "rm", "-rfv", backup_tgt_path) exec_backup_service_cmd( backup_service, "mv", "-v", backup_tmpdir, backup_tgt_path ) except (OSError, subprocess.CalledProcessError) as err: log.error(err) return 1 return 0 ================================================ FILE: collector-admin/ivxv_admin/cli_utils/config_utils/__init__.py ================================================ # IVXV Internet voting framework """CLI utilities for management service configuration.""" ================================================ FILE: collector-admin/ivxv_admin/cli_utils/config_utils/command_load.py ================================================ # IVXV Internet voting framework """CLI utilities for command loading.""" import json import os import re import shutil import subprocess from ...cli_utils.service_utils import ( create_voter_list_download_crontab, remove_ivxv_admin_crontab, generate_detail_stats_crontab, generate_voting_facts_crontab, install_detail_stats_crontab, install_voting_facts_crontab ) from ... import CFG_TYPES, CMD_DESCR, CMD_TYPES, VOTING_LIST_TYPES from ...command_file import ( check_cmd_signature, load_cfg_file_content, load_collector_cmd_file, ) from ...config import cfg_path from ...db import IVXVManagerDb from ...event_log import register_service_event from ...lib import ( IvxvError, get_current_voter_list_changeset_no, manage_db_mobileid_fields, manage_db_tsp_fields, populate_user_permissions, register_tech_cfg_items, ) from .. import init_cli_util, log def main(): """Load command to IVXV Collector Management Service.""" args = init_cli_util(""" Load command to IVXV Collector Management Service. Usage: ivxv-cmd-load [--autoapply] [--show-version] FILE Options: Command type. Possible values are: - election: election config - technical: collector technical config - trust: trust root config - choices: choices list - districts: districts list - voters: voters list or voters list skipping - user: user account and role(s) --autoapply Apply command file automatically (by Agent Daemon). --show-version Output config file version and exit. """) # validate CLI arguments cmd_type = args[''].lower() if cmd_type not in CMD_TYPES: log.error("Invalid command type %r. Possible values are: %s", cmd_type, ', '.join(CMD_TYPES)) return 1 cfg_filename = args['FILE'] # check command file signature and loading state try: check_cmd_loading_state(cmd_type) cfg_timestamp, cfg_version = check_signer_permissions( cmd_type, filename=args['FILE']) except IvxvError as err: log.error(str(err)) return 1 # output config version log.info("Config file version is %r", cfg_version) if args['--show-version']: return 0 # raise error if reloading current version if cmd_type in CFG_TYPES: with IVXVManagerDb() as db: if db.get_value(f'config/{cmd_type}') == cfg_version: log.error("%s version %r is already loaded", CFG_TYPES[cmd_type].capitalize(), cfg_version) return 1 # load config (includes config validation) log.info("Loading command %r from file %r", CMD_DESCR[cmd_type], cfg_filename) cfg_data = load_collector_cmd_file(cmd_type, args['FILE']) if cfg_data is None: return 1 # validate voting lists consistency if cmd_type in VOTING_LIST_TYPES: if not validate_lists_consistency(cmd_type, args['FILE']): return 1 register_service_event( 'CMD_LOAD', params={'cmd_type': cmd_type, 'version': cfg_version}) # reset database and remove crontab on trust root config loading if cmd_type == 'trust': log.info('Resetting collector management database') db = IVXVManagerDb() db.reset() remove_ivxv_admin_crontab() register_service_event('COLLECTOR_RESET') # register new and removed services on technical config loading elif cmd_type == 'technical': register_tech_cfg_items(cfg_data, cfg_version) # write districts JSON to web server data directory elif cmd_type == 'districts': districts_filename = cfg_path('admin_ui_data_path', 'districts.json') districts_list = sorted( [[dist_id, f'{dist_id} - {val["name"]}'] for dist_id, val in cfg_data['districts'].items()]) log.info("Writing simplified district list to %r", districts_filename) with open(districts_filename, 'w') as fp: json.dump(districts_list, fp) # generate detail stats crontab elif cmd_type == 'election': create_voter_list_download_crontab(cfg_data) generate_detail_stats_crontab(cfg_data) install_detail_stats_crontab() generate_voting_facts_crontab(cfg_data) install_voting_facts_crontab() # register loaded config cfg_state = None if cmd_type == "voters": cfg_state = "SKIPPED" if "skip_voter_list" in cfg_data else "PENDING" register_cfg( cmd_type, cfg_data, cfg_filename, cfg_timestamp, cfg_version, args["--autoapply"], state=cfg_state, ) register_service_event( 'CMD_LOADED', params={'cmd_type': cmd_type, 'version': cfg_version}) return 0 def register_cfg( cmd_type, cfg_data, cfg_filename, cfg_timestamp, cfg_version, autoapply, state ): """Register config version in database and file system.""" db_key = 'config' if cmd_type in CFG_TYPES else 'list' cfg_file_ext = "bdoc" # connect to management service database with IVXVManagerDb(for_update=True) as db: # detect order number for voters list if cmd_type == 'voters': if state == "SKIPPED": changeset_no = cfg_data["changeset"] else: changeset_no = get_current_voter_list_changeset_no(db) + 1 if changeset_no: cfg_file_ext = "zip" active_cfg_filename = f"voters{changeset_no:04}.{cfg_file_ext}" db_key += f"/voters{changeset_no:04}" else: active_cfg_filename = f'{cmd_type}.bdoc' db_key += f"/{cmd_type}" # write config file to admin ui data path cmd_filepath = cfg_path( "command_files_path", f"{cmd_type}-{cfg_timestamp}.{cfg_file_ext}" ) log.debug("Copying file %r to %r", cfg_filename, cmd_filepath) shutil.copy(cfg_filename, cmd_filepath) log.info('%s file loaded successfully', CMD_DESCR[cmd_type].capitalize()) # register config file version if cmd_type in CFG_TYPES or cmd_type in VOTING_LIST_TYPES: db.set_value(db_key, cfg_version) if cmd_type == 'voters': db.set_value(f"{db_key}-state", state) # register user permissions if cmd_type == 'trust': # initial permissions log.info('Resetting user permissions') for user_cn in db.get_all_values('user'): db.rm_value(f"user/{user_cn}") for user_cn in cfg_data['authorizations']: register_user_permissions(db, user_cn, ["admin"]) elif cmd_type == 'user': # permissions from user management command user_cn = cfg_data['cn'] log.info("Resetting user %r permissions", cfg_data['cn']) register_service_event( 'PERMISSION_RESET', params={'user_cn': user_cn}) for existing_user_cn in db.get_all_values('user'): if existing_user_cn == user_cn: db.rm_value(f"user/{user_cn}") register_user_permissions(db, user_cn, cfg_data["roles"]) elif cmd_type == 'election': # register election params cfg_data = load_cfg_file_content( cmd_type, re.compile(r'(.+\.)?{}.yaml'.format(cmd_type)), cfg_filename) db.set_value('election/election-id', cfg_data['identifier']) # start/stop times for key in [ 'servicestart', 'electionstart', 'electionstop', 'servicestop', 'verificationstop' ]: db.set_value(f"election/{key}", cfg_data["period"][key]) register_service_event( 'SET_ELECTION_TIME', params={ 'period': key, 'timestamp': cfg_data['period'][key]}) # authentication methods auth_in_db = set(db.get_all_values('election').get('auth', [])) auth_in_cfg = set(cfg_data.get('auth', []).keys()) for key in auth_in_db.difference(auth_in_cfg): db.rm_value(f'election/auth/{key}') for key in auth_in_cfg.difference(auth_in_db): db.set_value(f'election/auth/{key}', 'TRUE') # TSP qualification protocol for key in cfg_data.get('qualification', []): if key.get('protocol') == 'tspreg': db.set_value('election/tsp-qualification', 'TRUE') break else: try: db.rm_value('election/tsp-qualification') except KeyError: pass if cmd_type in ['technical', 'election']: manage_db_mobileid_fields(db) manage_db_tsp_fields(db) register_cfg_in_fs( cmd_type, cmd_filepath, active_cfg_filename, cfg_version, autoapply) def register_cfg_in_fs(cmd_type, src_path, tgt_filename, cfg_version, autoapply): """Register config in file system. - Create symlink to active config directory (e.g. /var/lib/ivxv/commands/.bdoc -> /etc/ivxv/cmd.bdoc) - Create state file for some command types (/var/lib/ivxv/commands/.json) """ if cmd_type not in CFG_TYPES and cmd_type not in VOTING_LIST_TYPES: return tgt_path = cfg_path('active_config_files_path', tgt_filename) state_path = os.path.splitext(src_path)[0] + '.json' # create symlink to active config directory try: os.remove(tgt_path) except FileNotFoundError: pass log.debug("Creating symlink for config file %r -> %r", src_path, tgt_path) os.symlink(src_path, tgt_path) # create state file for loaded command if cmd_type in ["technical", "election", "choices", "districts", "voters"]: try: os.remove(state_path) except FileNotFoundError: pass log.debug("Generating config state file %r", state_path) default_state_data = { # config data 'config_type': CMD_DESCR[cmd_type], 'config_file': os.path.basename(tgt_path), 'config_version': cfg_version, # applying data 'autoapply': autoapply, 'completed': False, 'attempts': 0, 'log': [], } with open(state_path, 'w') as fp: json.dump(default_state_data, fp, indent=4, sort_keys=True) log.info('%s file is registered in management service', CMD_DESCR[cmd_type].capitalize()) def check_cmd_loading_state(cmd_type): """Check command loading state. :raises IvxvError: on any known error """ # don't allow to load choices list more than once if cmd_type == 'choices': with IVXVManagerDb() as db: choices_list_version = db.get_value('list/choices') if choices_list_version: raise IvxvError( f"Choices list is already loaded (version: {choices_list_version})" ) # don't allow to load technical config if trust root config is not loaded elif cmd_type == 'technical': with IVXVManagerDb() as db: trust_cfg = db.get_value('config/trust') if not trust_cfg: raise IvxvError( 'Trust root must be loaded before technical configuration') # don't allow to load voters list if districts list is not loaded elif cmd_type == "voters": with IVXVManagerDb() as db: districts_cfg = db.get_value("list/districts") if not districts_cfg: raise IvxvError("Districts list must be loaded before voters list") def check_signer_permissions(cmd_type, filename): """Check command file signer permissions. Detect config file timestamp and version based on signature(s). :return: config timestamp, config version :rtype: list :raises IvxvError: on any known error """ # check config permissions try: cfg_signatures, all_signatures = check_cmd_signature( cmd_type, filename) except LookupError as err: raise IvxvError(f'Failed to verify config file signatures: {err}') except (OSError, subprocess.SubprocessError) as err: raise IvxvError(str(err)) for signature in all_signatures: log.info('Config file is signed by: %s', signature[2]) if not cfg_signatures: raise IvxvError('No signatures by authorized users') cfg_version, role = cfg_signatures[0] log.info("User %s with role %r is authorized to execute %r commands", cfg_version.split(' ')[0], role, cmd_type) log.info("Using signature %r as config file version", cfg_version) cfg_timestamp = cfg_version.split(' ')[1] return cfg_timestamp, cfg_version def register_user_permissions(db, user_cn, roles): """Register user permissions.""" roles = sorted(roles) register_service_event( 'PERMISSION_SET', params={'user_cn': user_cn, 'permission': ','.join(roles)}) db.set_value(f"user/{user_cn}", ",".join(roles)) populate_user_permissions(db) def validate_lists_consistency(cmd_type, cmd_filepath): """Validate voting lists consistency.""" # create list of existing voting lists list_files = {} with IVXVManagerDb() as db: for db_key, db_val in db.get_all_values('list').items(): if re.match(r"voters[0-9]{2}", db_key): if db_key.endswith("-state"): cli_key = db_key.replace("-state", "") if db_val in ["PENDING", "APPLIED"]: list_files[cli_key] = cfg_path( "active_config_files_path", "voters0000.bdoc" if cli_key == "voters0000" else f"{cli_key}.zip", ) elif db_val == "SKIPPED": list_files[cli_key] = cfg_path( "active_config_files_path", f"{cli_key}.bdoc", ) continue if db_key.endswith("-loaded") or not db_val: continue list_files[db_key] = cfg_path( 'active_config_files_path', f'{db_key}.bdoc') # add current list if cmd_type != 'voters': list_files[cmd_type] = cmd_filepath else: # change voters list key for proper ordering for _ in range(10_000): if f'voters{_:04d}' not in list_files: list_files[f'voters{_:04d}'] = cmd_filepath break # validate if len(list_files) > 1: election_cfg = cfg_path("active_config_files_path", "election.bdoc") cmd = ["ivxv-config-validate", f"--election={election_cfg}"] for cfg_type, filepath in sorted(list_files.items()): cfg_type = re.sub(r'[0-9]+', '', cfg_type) cmd.append(f'--{cfg_type}={filepath}') log.info( 'Some voting lists are already loaded, ' 'executing consistency checks: %s', ' '.join(cmd)) proc = subprocess.run(cmd, check=False) if proc.returncode != 0: log.error('Config validation command raised exception') return False return True ================================================ FILE: collector-admin/ivxv_admin/cli_utils/config_utils/config_apply.py ================================================ # IVXV Internet voting framework """CLI utilities for config applying.""" import json import os import shutil import sys from ... import (CFG_TYPES, CMD_TYPES, SERVICE_STATE_CONFIGURED, SERVICE_TYPE_PARAMS, lib) from ...command_file import load_collector_cmd_file from ...config import cfg_path from ...db import IVXVManagerDb from ...lib.lockfile import PidLocker from ...service import generate_service_list, get_service_cfg_state from ...service.service import Service from .. import init_cli_util, log #: config types in applying order CFG_TYPES_DEFAULT = ("technical", "election", "choices", "districts", "voters") def main(): """Apply loaded config to IVXV services.""" args = init_cli_util(""" Apply loaded IVXV Collector config to services. Usage: ivxv-config-apply [--type=] ... [] ... Options: --type= Config type. Possible values are: - election: election config file - technical: collector technical config file - choices: choices list - districts: districts list - voters: voters list """) # validate CLI arguments for cfg_type in args['--type']: if cfg_type not in CMD_TYPES or cfg_type == 'trust': log.error('Invalid config type specified: --type=%s', cfg_type) return 1 cfg_types = args['--type'] or list(CFG_TYPES_DEFAULT) service_ids = args[''] # load config data with IVXVManagerDb() as db: cfg_data = get_cfg_data(db) try: tech_cfg = load_tech_cfg( cfg_data['technical']['version'], cfg_data['election']['version'], 'election' in cfg_types) except lib.IvxvError as err: log.error(err) return 1 # remove choices/voters list version record from config data # if list is not loaded and also not specified in CLI args if not args['--type']: if not cfg_data.get('choices', {}).get('version'): cfg_types.remove('choices') if not cfg_data.get('districts', {}).get('version'): cfg_types.remove('districts') if not cfg_data.get('voters0000', {}).get('version'): cfg_types.remove('voters') # generate service list from tech config services = generate_service_list(tech_cfg['network'], service_ids) if services is None: return 1 services = prepare_service_list(services, service_ids) # create pidfile to avoid running of multiple instances pidfile_path = cfg_path('ivxv_admin_data_path', 'ivxv-config-apply.pid') log.debug("Creating pidfile %r", pidfile_path) try: PidLocker(pidfile_path, timeout=5) except IOError: log.error("Creating pidfile %r failed. Is another %s running?", pidfile_path, os.path.basename(sys.argv[0])) sys.exit(1) # apply config apply_result = apply_cfg( cfg_types=cfg_types, services=services, tech_cfg=tech_cfg, cfg_data=cfg_data) return int(not apply_result) def get_cfg_data(db): """Load config versions from database. :rtype: dict """ # get config versions cfg_data = { 'technical': { 'version': db.get_value('config/technical') or None }, 'election': { 'version': db.get_value('config/election') or None }, 'choices': { 'version': db.get_value('list/choices') or None }, 'districts': { 'version': db.get_value('list/districts') or None }, } if not cfg_data['choices']['version']: del cfg_data['choices'] if not cfg_data['districts']['version']: del cfg_data['districts'] try: for changeset_no in range(10_000): cfg_data[f"voters{changeset_no:04}"] = { "version": db.get_value(f"list/voters{changeset_no:04}") or None } except KeyError: pass # get config applying report filenames for cmd_type in cfg_data: cfg_filepath = lib.get_loaded_cfg_file_path(cmd_type) cfg_data[cmd_type]["state_file"] = ( cfg_filepath.replace(os.path.splitext(cfg_filepath)[1], ".json") if cfg_filepath else None ) return cfg_data def load_tech_cfg(tech_cfg_ver, election_cfg_ver, has_election_cfg): """Load technical config. * Load technical config * Log election config state * Generate database records for undefined services :return: technical config :rtype: dicts :raises IvxvError: if technical config cannot be loaded """ # load technical config if not tech_cfg_ver: raise lib.IvxvError( 'Technical config is not loaded to management service') log.info('Technical config is signed by %s', tech_cfg_ver) tech_cfg = load_collector_cmd_file( 'technical', cfg_path('active_config_files_path', 'technical.bdoc')) if tech_cfg is None: raise lib.IvxvError('Error while loading technical config') # log election config state if has_election_cfg: if election_cfg_ver: log.info('Election config is signed by %s', election_cfg_ver) else: log.info('Election config is not loaded to management service') return tech_cfg def prepare_service_list(services, service_ids): """Prepare service list for applying config to services. Return services that are in service_ids list. """ services = [[service_type, service_data] for service_type, service_data in services if not service_ids or service_data['id'] in service_ids] # reorder services to satisfy dependencies for service_block in services[:]: # move log service record to beginning of list # to configure log collector(s) before other services if service_block[0] == 'log': services.remove(service_block) services.insert(0, service_block) # move proxy service records to end of list to ensure proxied services # are started and initial health checks can succeed if service_block[0] == 'proxy': services.remove(service_block) services.append(service_block) return services def apply_cfg(cfg_types, services, tech_cfg, cfg_data): """Apply config to services.""" results = dict([i, {}] for i in cfg_types) for cfg_type in CFG_TYPES_DEFAULT: if cfg_type not in cfg_types: continue # disallow applying choices/districts/voters list # if required services aren't operational if cfg_type in ["choices", "districts", "voters"]: list_services = lib.get_services( include_types=['choices', 'storage'], service_state=[SERVICE_STATE_CONFIGURED]) if not list_services: log.error('Choices and/or storage services are not configured') return False result_by_service = apply_cfg_to_services( services=services, cfg_type=cfg_type, tech_cfg=tech_cfg, cfg_data=cfg_data, ) results[cfg_type] = result_by_service # update config state file if (cfg_type in CFG_TYPES and result_by_service and False not in result_by_service.values()): state_filepath = cfg_data[cfg_type]['state_file'] with open(state_filepath) as fp: cfg_state = json.load(fp) cfg_state['completed'] = True tmp_filepath = f'{state_filepath}.tmp' with open(tmp_filepath, 'x') as fp: json.dump(cfg_state, fp, indent=4, sort_keys=True) shutil.move(tmp_filepath, state_filepath) return aggregate_results(results) def apply_cfg_to_services(services, cfg_type, tech_cfg, cfg_data): """Helper to apply config to services. :param services: Service list :type services: list :param cfg_type: Config type to apply :type cfg_type: str :param tech_cfg: Technical configuration from config file :type tech_cfg: dict :param services: List of services, grouped by service type :type services: list :param cfg_data: Loaded config/list files data (version, filenames) :type cfg_data: dict :return: dict with results for every service """ # get list of registered services that require config update with IVXVManagerDb() as db: service_cfg_state = get_service_cfg_state(db, tech_cfg) hostnames = sorted( set( service_data['address'].split(':')[0] for _, service_data in services )) host_state = dict( [hostname, db.get_value(f'host/{hostname}/state')] for hostname in hostnames) # apply config to services def report_applying_result(): """Report process result.""" cfg_descr = '{} {}'.format( cfg_type, 'config' if cfg_type in CFG_TYPES else 'list') results[service_id] = cfg_success if cfg_success: log.info('Service %s: %s config applied successfully', service_id, cfg_descr) service.register_event( 'SERVICE_CONFIG_APPLY', params={'cfg_descr': cfg_descr, 'cfg_version': cfg_version}) else: log.error('Service %s: failed to apply %s', service_id, cfg_descr) # apply config results = {} applied_lists = [] attempt_no = 0 for service_type, service_data in services: service_id = service_data['id'] if not service_cfg_state[service_id][cfg_type]: continue service_data['service_type'] = service_type # used by Service() with Service(service_id, service_data) as service: # apply technical config if cfg_type == 'technical': # initialize service host if required if not host_state[service.hostname]: log.info("Initializing service host %r", service.hostname) success = service.init_service_host() if not success: results[service_id] = False continue with IVXVManagerDb(for_update=True) as db: db.set_value(f'host/{service.hostname}/state', 'REGISTERED') host_state[service.hostname] = 'REGISTERED' # apply config log.info('Service %s: Applying technical config', service_id) cfg_version = cfg_data[cfg_type]['version'] attempt_no = service.load_apply_state( cfg_data[cfg_type]['state_file'], attempt_no) cfg_success = service.apply_tech_cfg(cfg_version, tech_cfg) report_applying_result() service.update_apply_state() # apply election config elif (cfg_type == 'election' and SERVICE_TYPE_PARAMS[service_type]['require_config']): log.info('Service %s: Applying elections config', service_id) cfg_version = cfg_data[cfg_type]['version'] attempt_no = service.load_apply_state( cfg_data[cfg_type]['state_file'], attempt_no) cfg_success = service.apply_election_cfg(cfg_version) report_applying_result() service.update_apply_state() # apply choices/districts list elif (cfg_type in ["choices", "districts"] and service_type == "choices" and cfg_type not in applied_lists): log.info("Service %s: Applying %s list", service_id, cfg_type) cfg_version = cfg_data[cfg_type]['version'] attempt_no = service.load_apply_state( cfg_data[cfg_type]['state_file'], attempt_no) cfg_success = service.apply_list(cfg_type) report_applying_result() service.update_apply_state(completed=True) applied_lists.append(cfg_type) # apply voters lists elif (cfg_type == 'voters' and service_type == 'voting' and 'voters' not in applied_lists): for changeset_no in service_cfg_state[service_id]["voters"]: log.info( "Service %s: Applying voter list changeset #%d", service_id, changeset_no, ) voters_list_id = f"voters{changeset_no:04}" cfg_version = cfg_data[voters_list_id]['version'] attempt_no = service.load_apply_state( cfg_data[voters_list_id]['state_file']) cfg_success = service.apply_list(cfg_type, changeset_no) report_applying_result() service.update_apply_state(completed=True) applied_lists.append('voters') return results def aggregate_results(results): """Aggregate and output collector config applying results for services. :rtype: bool :return: True if no error detected """ results_summary = [] for cfg_type in CFG_TYPES_DEFAULT: if results.get(cfg_type): log.info('Results for %s:', lib.cfg_type_verbose(cfg_type)) for service_id, result in sorted(results[cfg_type].items()): log.info(' Service %s: %s', service_id, 'success' if result else 'FAILED') results_summary.append(result) log.info('%d configuration packages successfully applied', results_summary.count(True)) if False in results_summary: log.error('Failed to apply %d configuration packages', results_summary.count(False)) return False not in results_summary ================================================ FILE: collector-admin/ivxv_admin/cli_utils/config_utils/config_validate.py ================================================ # IVXV Internet voting framework """CLI utilities for collector config validation.""" import json from ... import CMD_DESCR, CMD_TYPES from ...command_file import load_collector_cmd_file from ...lib import IvxvError from .. import init_cli_util, log def main(): """Validate IVXV collector config.""" args = init_cli_util(""" Validate IVXV collector config files. Validate single config files. Also validate voting lists consistency if multiple lists are provided. Usage: ivxv-config-validate [--plain] [--trust=] [--technical=] [--election=] [--choices=] [--districts=] [--voters= ...] Options: --plain Validate plain config file (Default: BDOC container) """) plain = args['--plain'] # validate CLI arguments cfg_files = [] for cfg_type in CMD_TYPES: files = args.get(f'--{cfg_type}') if isinstance(files, list): cfg_files += [[cfg_type, filepath] for filepath in files] elif files: cfg_files.append([cfg_type, files]) if not cfg_files: log.error('Config file is not specified') return 1 # validate single files try: validated_cfg = validate_cfg_files(cfg_files, plain) except IvxvError: return 1 log.info('Config files are valid') if validate_cfg_consistency( validated_cfg, election=args["--election"], choices=args["--choices"], districts=args["--districts"], voters=args["--voters"], ): return 0 return 1 def validate_cfg_consistency( validated_cfg, election=None, choices=None, districts=None, voters=None, ): """Perform consistency checks for config files.""" # validate election ID consistency if not validate_cfg_election_id(validated_cfg): log.info("Election ID consistency check failed") return False log.info("Election ID consistency check succeeded") # validate multiple voters lists consistency if len(voters) > 1: if not validate_voters_lists_consistency(validated_cfg): log.info('Voters lists consistency check failed') return False log.info('Voters lists consistency check succeeded') # determine voterforeignehak, there are no consistency checks voterforeignehak = "0000" if election: for cfg_type, cfg in validated_cfg: if cfg_type == "election": voterforeignehak = cfg.get("voterforeignehak", voterforeignehak) break # validate districts and choices/voters lists consistency if districts and (choices or voters): if not validate_lists_consistency(validated_cfg, voterforeignehak): log.info('Voting lists consistency check failed') return False log.info('Voting lists consistency check succeeded') return True def validate_cfg_election_id(validated_cfg): """Validate election ID consistency in config files.""" # try to detect election ID election_id = None for cfg_type, cfg in validated_cfg: if cfg_type == "election": election_id = cfg["identifier"] log.info("Detected election ID %r from election config", election_id) break # validate election ID consistency for cfg_type, cfg in validated_cfg: if cfg_type in ["election", "technical", "trust"]: continue cfg_election_id = cfg["election"] if not election_id: election_id = cfg_election_id log.debug("Detected election ID %r from %s config", election_id, cfg_type) else: if election_id != cfg_election_id: log.error( "Election ID %r in %s config does not match with %r", cfg_election_id, cfg_type, election_id, ) return False return True def validate_cfg_files(cfg_files, plain): """Load and validate config files.""" cfg_array = [] for cfg_type, filepath in cfg_files: log.info("Validating %s file %r", CMD_DESCR[cfg_type], filepath) try: cfg = load_collector_cmd_file(cfg_type, filepath, plain) except json.decoder.JSONDecodeError: cfg = None if cfg is None: raise IvxvError cfg_array.append([cfg_type, cfg]) return cfg_array def validate_voters_lists_consistency(cfg_objects): """Validate voters lists consistency.""" check_failed = False voters_reg = None changeset = 0 errors = [] for cfg_type, cfg in cfg_objects: if cfg_type != 'voters': continue if changeset == 0: if int(cfg['changeset']) != 0: errors.append( f'Invalid changeset {cfg["changeset"]} for initial voter list' ) break voters_reg = dict( [voter[1], voter[3:5]] for voter in cfg['voters']) changeset = 1 continue if int(cfg['changeset']) < changeset: errors.append( f'Invalid changeset {cfg["changeset"]}, ' f'expected {changeset} or greater') break changeset = int(cfg['changeset']) # voter list skipping command acts as an empty changeset if cfg.get('skip_voter_list'): continue log.info("Checking voters list changeset #%d consistency", changeset) voters_in_patch = set() for rec_no, voter in enumerate(cfg['voters']): voter_id = voter[1] if voter[0] == 'lisamine': if (voter_id not in voters_reg and voter_id not in voters_in_patch): voters_reg[voter_id] = voter[3:5] else: errors.append( f'Record #{rec_no}: Adding voter ID {voter_id} ' 'that is already in voters list') voters_in_patch.add(voter_id) else: if voter_id in voters_in_patch: errors.append( f'Record #{rec_no}: Removing ID {voter_id} ' 'that is added with this patch') try: # just to test that voter id is valid before removing it voters_reg.pop(voter_id) except KeyError: errors.append( f'Record #{rec_no}: Removing voter ID {voter_id} ' 'that is not in voters list') if errors: break for error in errors: log.error(error) check_failed = check_failed or bool(errors) return not check_failed def validate_lists_consistency(cfg_objects, voterforeignehak): """Validate voting lists consistency.""" districts_cfg = ([ cfg for cfg_type, cfg in cfg_objects if cfg_type == 'districts' ][0]) districts = set(districts_cfg['districts']) check_failed = False changeset_no = 0 for cfg_type, cfg in cfg_objects: errors = [] if cfg_type == 'choices': log.info('Checking districts and choices lists consistency') errors = validate_choices_consistency(districts, cfg) check_failed = check_failed or bool(errors) elif cfg_type == 'voters': log.info( "Checking districts and voter list changeset #%d consistency", changeset_no, ) errors = validate_voters_consistency(districts_cfg, districts, cfg, voterforeignehak) check_failed = check_failed or bool(errors) changeset_no += 1 for error in errors: log.error(error) return not check_failed def validate_choices_consistency(districts, choices_cfg): """Validate districts and choices lists consistency.""" choices = set(choices_cfg['choices']) errors = [] # Each choice is in an existing district choices_wo_district = choices.difference(districts) if choices_wo_district: errors.append( 'The following choices have no matching district: {}' .format(','.join(sorted(choices_wo_district)))) # In each district there must be at least one choice districts_wo_choices = districts.difference(choices) if districts_wo_choices: errors.append( 'The following districts have no choice defined: {}' .format(','.join(sorted(districts_wo_choices)))) return errors def validate_voters_consistency( districts_cfg, districts, voters_cfg, voterforeignehak ): """Validate voting lists consistency.""" errors = [] if "skip_voter_list" in voters_cfg: return errors parish_to_district = {} for dist in districts_cfg["districts"]: for parish in districts_cfg["districts"][dist]["parish"]: if parish not in parish_to_district: parish_to_district[parish] = [] parish_to_district[parish].append(dist) # check consistency for voter in voters_cfg['voters']: # if action is "kustutamine" then don't check districts/parish if voter[0] == "kustutamine": continue # Voterlist contains voter EHAK and district no which must be # translated into full district identifier voter_district = None voter_id = voter[1] voter_ehak = voter[3] voter_district_no = voter[4] # Voterlist uses parish FOREIGN, other configs may use some other code if voter_ehak == "FOREIGN": voter_ehak = voterforeignehak # Search district by parish, single parish may be in several districts # in this case the district no's must be different and match with voter if voter_ehak in parish_to_district: for dist in parish_to_district[voter_ehak]: if dist.split(".")[1] == voter_district_no: voter_district = dist break else: errors.append(f'Parish {voter_ehak} not found in districts') # Voter must belong to an existing district if voter_district is None: errors.append( f'District for voter {voter_id} in EHAK {voter_ehak} / ' f'{voter_district_no} cannot be determined') elif voter_district not in districts: errors.append( f'District {voter_district} for voter {voter_id} not found') return errors ================================================ FILE: collector-admin/ivxv_admin/cli_utils/config_utils/load_secret_data_file.py ================================================ # IVXV Internet voting framework """CLI utilites for sercet loading.""" import hashlib import OpenSSL from ... import (COLLECTOR_STATE_CONFIGURED, COLLECTOR_STATE_FAILURE, COLLECTOR_STATE_INSTALLED, COLLECTOR_STATE_PARTIAL_FAILURE, SERVICE_SECRET_TYPES, SERVICE_STATE_CONFIGURED, SERVICE_STATE_FAILURE, SERVICE_STATE_INSTALLED, SERVICE_TYPE_PARAMS, lib) from ...event_log import register_service_event from ...lib import IvxvError from ...service.service import Service from .. import init_cli_util, log def main(): """Load secret data to IVXV services.""" # validate CLI arguments args = init_cli_util(""" Load secret data to IVXV services. This utility loads file that contains secret data to services. Supported secret types are: tls-cert - TLS certificate for service. Certificate (and key) is used for securing communication between services and service instances. tls-key - TLS key for service. Key is used together with service certificate. tsp-regkey - PKIX TSP registration key for voting services. Key is used for signing Time Stamp Protocol requests. Key file must be in PEM format and must be not password protected. mid-token-key - Mobile-ID/Smart-ID/Web eID identity token for choices, mobile-id and voting services. Key file must be 32 bytes long. Usage: ivxv-secret-load [--service=] """) secret_type = args[''].lower() filepath = args[''] if secret_type not in SERVICE_SECRET_TYPES: log.error("Invalid secret type %r", secret_type) log.info('Supported secret types are: %s', ', '.join(SERVICE_SECRET_TYPES)) return 1 secret_descr = SERVICE_SECRET_TYPES[secret_type]['description'] # load file log.debug('Loading %s file', secret_descr) try: with open(filepath, 'rb') as fp: file_content = fp.read() except (FileNotFoundError, PermissionError) as err: log.error("Unable to load file %r: %s", filepath, err.strerror) return 1 # validate file try: validate_secret_file(secret_type, file_content, args["--service"]) except IvxvError as err: log.error('Error while validating %s: %s', secret_descr, err) return 1 # calculate file checksum file_checksum = hashlib.sha256(file_content).hexdigest() # generate list of services that are in required state key_param = { 'tls-cert': 'require_tls', 'tls-key': 'require_tls', 'tsp-regkey': 'tspreg', 'mid-token-key': 'mobile_id', }[secret_type] service_types_affected = sorted( set( service_type for service_type, service_params in SERVICE_TYPE_PARAMS.items() if service_params[key_param] ) ) services = lib.get_services( include_types=service_types_affected, require_collector_state=[ COLLECTOR_STATE_INSTALLED, COLLECTOR_STATE_CONFIGURED, COLLECTOR_STATE_FAILURE, COLLECTOR_STATE_PARTIAL_FAILURE ], service_state=[ SERVICE_STATE_INSTALLED, SERVICE_STATE_CONFIGURED, SERVICE_STATE_FAILURE ]) if not services: return 1 # copy key to service hosts # FIXME avoid multiple copying of shared secret to single host services_updated = [] for service_id, service_data in sorted(services.items()): if args['--service'] and service_id != args['--service']: continue if (service_data.get(SERVICE_SECRET_TYPES[secret_type]['db-key']) == file_checksum): log.info('Service %s already contains specified %s', service_id, secret_descr) continue with Service(service_id, service_data) as service: if not service.load_secret_file(secret_type, filepath, file_checksum): return 1 register_service_event( 'SECRET_INSTALL', service=service_id, params={ 'secret_descr': secret_descr, }) services_updated.append(service_id) if args['--service'] and args['--service'] not in services_updated: log.error('%s was not loaded to service %s', secret_descr, args['--service']) return 1 if args['--service']: log.info('%s is loaded to service %s', secret_descr, args['--service']) else: log.info('%s is loaded to services', secret_descr) return 0 def validate_secret_file(secret_type, file_content, service_id): """Validate secret data file. :raises IvxvError: """ if secret_type in ('tls-cert', 'tls-key') and not service_id: raise IvxvError("Service ID is not specified") if secret_type == 'mid-token-key' and len(file_content) != 32: raise IvxvError( f'File is not 32 bytes long ' f'(actual size: {len(file_content)} bytes)') if secret_type == 'tsp-regkey': try: privkey = OpenSSL.crypto.load_privatekey( OpenSSL.crypto.FILETYPE_PEM, file_content ) except OpenSSL.crypto.Error as err: err_lib, err_func, err_reason = err.args[0][0] raise IvxvError( f'Error in {err_lib} library {err_func} ' f'function: {err_reason}') with open("/var/lib/ivxv/service/tspreg-pubkey.pem", "wb") as fd: fd.write( OpenSSL.crypto.dump_publickey(OpenSSL.crypto.FILETYPE_PEM, privkey) ) ================================================ FILE: collector-admin/ivxv_admin/cli_utils/config_utils/voter_list_download.py ================================================ # IVXV Internet voting framework """CLI utility to download voter list from VIS.""" import datetime import json import os import shutil import sys import zipfile import requests from ... import command_file from ...config import CONFIG, cfg_path from ...db import IVXVManagerDb from ...event_log import register_service_event from ...lib import get_current_voter_list_changeset_no from ...lib.lockfile import PidLocker from .. import init_cli_util, log from .command_load import register_cfg, validate_lists_consistency def main(): """Download voter list from VIS to IVXV Collector Management Service.""" args = init_cli_util( """ Download next available voter list changeset from VIS to IVXV Collector Management Service. Usage: ivxv-voter-list-download [--output-report=] [--log-level=] Options: --output-report= Write JSON report about HTTP request to VIS. --log-level= Logging level [Default: INFO]. """ ) # validate CLI arguments output_report_filepath = args["--output-report"] # suppress error if executed from crontab before loading election config if not os.path.exists("/etc/ivxv/election.bdoc") and not sys.stdout.isatty(): return 0 # check process lock to start voterlist download without interruption, otherwise # skip downloading until next time if PidLocker.pidfile_exists('ivxv-voter-list-download.pid'): log.info('Cannot start voterlist download, pidfile exists') return 0 # create process lock and start voterlist downloading pidfile_path = cfg_path('ivxv_admin_data_path', 'ivxv-voter-list-download.pid') log.debug("Creating pidfile %r", pidfile_path) try: PidLocker(pidfile_path, timeout=5) except IOError: log.error("Creating pidfile %r failed", pidfile_path) return 1 retries: int = 0 try: while True: retries += 1 # detect state of the last changeset with IVXVManagerDb() as db: changeset_no = get_current_voter_list_changeset_no(db) changeset_state = db.get_value(f"list/voters{changeset_no:04d}-state") # stop on INVALID changeset if changeset_state == "INVALID": log.info( "State of the last registered voter list changeset #%d is %s", changeset_no, changeset_state, ) log.info("Skipping download of the next voter list changeset") if output_report_filepath: with open(output_report_filepath, "w") as fd: json.dump( {"voter-list-changeset": {"status": "Skipped"}}, fd, indent=True ) return 0 changeset_no += 1 # get params from election config command_file.log.setLevel(args["--log-level"]) cfg = command_file.load_collector_cmd_file( "election", "/etc/ivxv/election.bdoc") if not cfg: return 1 election_id = cfg["identifier"] vis_base_url_template = f"{cfg['vis']['url']}{{endpoint}}" ca_certs_filepath = None if cfg["vis"].get("ca"): ca_certs_filepath = cfg_path("vis_path", "ca.pem") with open(ca_certs_filepath, "w") as fd: fd.write("\n".join(cfg["vis"]["ca"])) # download voter list output_filepath = f"{CONFIG.get('vis_path')}/voters{changeset_no:04d}.zip" url = vis_base_url_template.format(endpoint="ehs-election-voters-changeset") log.info("Query voter list update #%d from %r", changeset_no, url) request_params = {"electionCode": election_id, "changeset": changeset_no} resp = requests.get( url, verify=ca_certs_filepath, cert=( "/etc/ssl/certs/ivxv-admin-client.crt", "/etc/ssl/private/ivxv-admin-client.key", ), params=request_params, ) log.info( "VIS responded to voter list update #%d: %r %s", changeset_no, resp.status_code, resp.reason, ) timestamp = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%SZ") version = f"{url} {timestamp}" # write query report if output_report_filepath: report = { "voter-list-changeset": { "operation": f"Download voter list update #{changeset_no} from " + "VIS", "request": {"url": resp.url, "method": "GET", "params": request_params}, "response": { "status": "OK" if resp.ok else "ERROR", "status_code": resp.status_code, "reason": resp.reason, "time_elapsed": str(resp.elapsed), "retries": retries, "headers": dict([key, val] for key, val in resp.headers.items()), "content": resp.text, }, }, } with open(output_report_filepath, "w") as fd: json.dump(report, fd, indent=True) # register download event / handle download errors if resp.status_code == 404: log.info("Voter list changeset #%d is not available in VIS", changeset_no) return 0 if resp.status_code != 200: log.error("Server responded with status %d - %r", resp.status_code, resp.reason) register_service_event( "VOTER_LIST_DOWNLOAD_FAILED", level="INFO", service="admin", params={"changeset_no": changeset_no}, ) return 1 register_service_event( "VOTER_LIST_DOWNLOADED", level="INFO", service="admin", params={"changeset_no": changeset_no}, ) # write downloaded content to file write_voter_list_zip(resp.content, version, output_filepath) # register voter list if changeset_no: register_voter_list(output_filepath, timestamp, version) finally: try: log.debug("Releasing pidfile %r", pidfile_path) PidLocker.rm_stale_pidfile('ivxv-voter-list-download.pid') except FileNotFoundError: # pid file doesn't exist pass def write_voter_list_zip(content, version, output_filepath): """Write voter list ZIP file.""" # write list to temporary ZIP file tmp_filepath = f"{output_filepath}.tmp" with open(tmp_filepath, "bw") as fd: tmp_filepath = fd.name log.info("Writing VIS response to temporary file %r", tmp_filepath) fd.write(content) # add version to ZIP comment = f"Version: {version}" log.info("Adding comment %r to %r", comment, tmp_filepath) with zipfile.ZipFile(tmp_filepath, "a") as zip_file: zip_file.comment = bytes(comment, "ASCII") # move ZIP file to final place log.info("Moving temporary file %r to %r", tmp_filepath, output_filepath) shutil.move(tmp_filepath, output_filepath) def register_voter_list(filepath, timestamp, version): """Register voter list in management service.""" cfg_data = command_file.load_collector_cmd_file("voters", filepath) is_cfg_valid = cfg_data is not None if is_cfg_valid: is_cfg_valid = validate_lists_consistency("voters", filepath) register_service_event( "CMD_LOAD", params={"cmd_type": "voters", "version": version} ) register_cfg( cmd_type="voters", cfg_data=cfg_data, cfg_filename=filepath, cfg_timestamp=timestamp, cfg_version=version, autoapply=is_cfg_valid, state="PENDING" if is_cfg_valid else "INVALID", ) register_service_event( "CMD_LOADED", params={"cmd_type": "voters", "version": version} ) ================================================ FILE: collector-admin/ivxv_admin/cli_utils/service_utils.py ================================================ # IVXV Internet voting framework """CLI utilities for service management.""" import datetime import os import shutil import json import logging import random import subprocess import sys import tempfile import time import zipfile from collections import OrderedDict from crontab import CronTab from jinja2 import Environment, PackageLoader import fasteners import yaml import requests from .. import ( COLLECTOR_STATE_CONFIGURED, COLLECTOR_STATE_FAILURE, COLLECTOR_STATE_INSTALLED, COLLECTOR_STATE_NOT_INSTALLED, COLLECTOR_STATE_PARTIAL_FAILURE, SERVICE_STATE_CONFIGURED, SERVICE_STATE_FAILURE, SERVICE_STATE_INSTALLED, SERVICE_STATE_REMOVED, SERVICE_TYPE_PARAMS, __version__, command_file, ) from ..agent_daemon import get_collector_data, ping_service from ..config import cfg_path from ..db import IVXVManagerDb from ..lib import IvxvError, get_services from ..service import logging as service_logging from ..service.service import Service, exec_remote_cmd from . import init_cli_util, log #: JSON formatting options JSON_DUMP_ARGS = dict(indent=2, sort_keys=True) IVXV_ADMIN_CRON_USER = 'ivxv-admin' VOTER_LIST_DOWNLOAD_CRON_JOB = 'if [ -x /usr/bin/ivxv-voter-list-download ]; then /usr/bin/ivxv-voter-list-download --log-level=WARNING; fi' # noqa: E501 def export_votes_util(): """Export collected votes.""" args = init_cli_util(""" Export collected votes. This utility copies current ballot box from voting service to backup service and outputs ballot box content. Usage: ivxv-export-votes [--consolidate] Options: --consolidate Consolidate all collected votes """) try: export_votes(args["--consolidate"], args[""]) except IvxvError as err: log.error(err) return 1 return 0 def export_votes(must_consolidate, output_filename): """Export votes.""" # fail if output file already exist if os.path.exists(output_filename): raise IvxvError(f"Output file {output_filename!r} already exist") # create backup of current ballot box log.info('Creating backup copy from current ballot box') try: subprocess.run(['ivxv-backup', 'ballot-box'], check=True) except OSError as err: raise IvxvError(f"Creating ballot box backup failed: {err.strerror}") except subprocess.CalledProcessError as err: raise IvxvError(f"Creating ballot box backup failed: {err}") # create handler for backup service services = get_services(include_types=['backup']) if not services: raise IvxvError('Backup service is not defined') assert len(services) == 1 with Service(*list(services.items())[0]) as backup_service: log.debug('Backup service: %s', backup_service.service_id) ballot_box_filepath = datetime.datetime.now().strftime( '/var/lib/ivxv/ballot-box-consolidated-%Y%m%d_%H%M.zip') # run consolidation in backup service if must_consolidate: proc = backup_service.ssh([ 'ivxv-voteunion', ballot_box_filepath, '/var/backups/ivxv/ballot-box/ballot-box-????????_????.zip' ]) if proc.returncode: raise IvxvError('Consolidation command failed in backup service') else: # export without consolidation # detect last backup filename cmd = [ 'ls', '/var/backups/ivxv/ballot-box/ballot-box-????????_????.zip' ] proc = backup_service.ssh(cmd, stdout=subprocess.PIPE, check=True) ballot_box_filepath = proc.stdout.decode('UTF-8').strip().split( '\n')[-1] # copy consolidated ballot box from backup log.info('Copying ballot box to management service') if not backup_service.scp( output_filename, ballot_box_filepath, "consolidated ballot box" if must_consolidate else "ballot box", to_remote=False): raise IvxvError('Failed to copy ballot box to management service') if must_consolidate: log.info('Removing consolidated ballot box from backup service') backup_service.ssh(['rm', '-v', ballot_box_filepath]) log.info("Collected votes archive is written to %r", output_filename) def generate_processor_input_util(): """Generate input for processor application.""" args = init_cli_util( """ Generate input for processor application. This utility generates ZIP container with data files for processor application to validate ballot box: 1. District list; 2. Voter lists; 3. Validation key for vote registration requests; 4. Configuration for processor application. Usage: ivxv-generate-processor-input """ ) try: election_id, cfg = generate_processor_check_cfg() generate_processor_input(election_id, cfg, args[""]) except IvxvError as err: log.error(err) return 1 return 0 def generate_processor_check_cfg(): """Generate config file for processor application.""" log.info("Generating processor application config") processor_check_cfg = OrderedDict( districts=None, registrationlist="registrationlist.zip", registrationlist_checksum="registrationlist.zip.sha256sum.asice", vlkey=None, tskey="ts.key", voterlists=[], election_start=None, voterforeignehak=None, out=None, ) # read collector config from management database with IVXVManagerDb() as db: election_id = db.get_value("election/election-id") processor_check_cfg["election_start"] = db.get_value("election/electionstart") districts_version = db.get_value("list/districts") voter_list_states = [] for changeset_no in range(10_000): try: voter_list_state = db.get_value(f"list/voters{changeset_no:04d}-state") except KeyError: break if voter_list_state not in ["APPLIED", "SKIPPED"]: raise IvxvError( f"Voter list changeset #{changeset_no} " f"has unexpected state {voter_list_state!r}" ) voter_list_states.append(voter_list_state) if not election_id: raise IvxvError("Election is not configured") if not districts_version: raise IvxvError("District list is not loaded") if not voter_list_states: raise IvxvError("Initial voter list is not loaded") processor_check_cfg.update( { "districts": f"{election_id}.districts.json.bdoc", "out": f"{election_id}-out-1", } ) # read election config from command file try: election_cfg = command_file.load_cfg_file_content( "election", f"{election_id}.election.yaml", "/etc/ivxv/election.bdoc" ) except (IvxvError, OSError) as err: raise IvxvError(f"Error while loading config file: {err}") except UnicodeDecodeError as err: raise IvxvError(f"Error while decoding config file: {err}") # copy election config values if "voterforeignehak" in election_cfg: processor_check_cfg["voterforeignehak"] = election_cfg["voterforeignehak"] else: processor_check_cfg.pop("voterforeignehak") processor_check_cfg["vlkey"] = election_cfg["voterlist"]["key"] # generate voter list filenames for changeset_no, voter_list_state in enumerate(voter_list_states): voter_list_record = dict( path=f"{changeset_no:02d}.{election_id}.voters.utf", signature=f"{changeset_no:02d}.{election_id}.voters.sig", ) if voter_list_state == "SKIPPED": voter_list_record[ "skip_cmd" ] = f"{changeset_no:02d}.{election_id}.voters-skip.yaml.bdoc" processor_check_cfg["voterlists"].append(voter_list_record) return election_id, processor_check_cfg def generate_processor_input(election_id, processor_check_cfg, output_filename): """Generate input file for processor application.""" # fail if output file already exist if os.path.exists(output_filename): raise IvxvError(f"Output file {output_filename!r} already exist") log.info("Creating input file for processor application") with tempfile.TemporaryDirectory() as output_dir: log.info("Preparing container structure in directory %r", output_dir) # district list filename = processor_check_cfg["districts"] log.info("Copying district list %r", filename) shutil.copy( cfg_path("active_config_files_path", "districts.bdoc"), f"{output_dir}/{filename}", ) # key to verify voter list signer filename = "voterfile.pub.key" log.info("Copying voter list signing key %r", filename) with open(f"{output_dir}/{filename}", "w") as fd: fd.write(processor_check_cfg["vlkey"]) processor_check_cfg["vlkey"] = filename # voter lists for changeset_no, voter_list_files in enumerate( processor_check_cfg["voterlists"] ): input_filepath = cfg_path( "active_config_files_path", f"voters{changeset_no:04d}.zip" if changeset_no else "voters0000.bdoc", ) with zipfile.ZipFile(input_filepath) as input_zip: for description, key in [ ["content", "path"], ["signature", "signature"], ["skipping command", "skip_cmd"], ]: try: filename = voter_list_files[key] except KeyError: continue file_ext = os.path.splitext(filename)[-1] log.info( "Copying voter list #%d %s %r", changeset_no, description, filename, ) if key == "skip_cmd": shutil.copy( cfg_path( "active_config_files_path", f"voters{changeset_no:04d}.bdoc", ), f"{output_dir}/" f"{changeset_no:02d}.{election_id}.voters-skip.yaml.bdoc", ) else: with input_zip.open( f"{election_id}-voters-{changeset_no}{file_ext}" ) as zip_fd: with open(f"{output_dir}/{filename}", "wb") as fd: fd.write(zip_fd.read()) # key to verify registration requests filename = processor_check_cfg["tskey"] log.info("Copying registration requests verification key %r", filename) shutil.copy( "/var/lib/ivxv/service/tspreg-pubkey.pem", f"{output_dir}/{filename}", ) # setup YAML module to write OrderedDict def represent_dictionary_order(self, dict_data): return self.represent_mapping("tag:yaml.org,2002:map", dict_data.items()) def setup_yaml(): yaml.add_representer(OrderedDict, represent_dictionary_order) setup_yaml() # config file for processor application filename = f"{election_id}.processor.yaml" log.info("Writing processor application config %r", filename) with open(f"{output_dir}/{filename}", "w") as fd: fd.write( "# Automaatselt genereeritud fail " f"{datetime.datetime.now():%d.%m.%Y %R}\n\n" f"# Generaator: {__file__}\n\n" ) yaml.dump(dict(check=processor_check_cfg), fd, default_flow_style=False) fd.write('\n') fd.write(' # BALLOT BOX\n') fd.write(' #ballotbox: votes.zip\n') fd.write(' #ballotbox_checksum: votes.zip.sha256sum\n') # generate ZIP container filenames = sorted(os.listdir(output_dir)) output_filename_tmp = f"{output_filename}.tmp" log.info( "Generating ZIP container %r with %d files", output_filename_tmp, len(filenames), ) with zipfile.ZipFile(output_filename_tmp, "w", allowZip64=True) as zip_file: for filename in filenames: log.info("Adding %r to ZIP container", filename) zip_file.write(f"{output_dir}/{filename}", filename) shutil.move(output_filename_tmp, output_filename) log.info("Processor input is written to %r", output_filename) def copy_logs_to_logmon_util(): """Copy IVXV log files from service hosts to Log Monitor.""" # validate CLI arguments args = init_cli_util(""" Copy IVXV log files from service hosts to Log Monitor. This utility transports collected IVXV log files from IVXV services (including Log Collector Service) to Log Monitor. Usage: ivxv-copy-log-to-logmon [--log-level=] [ ...] Options: Service host name. --log-level= Logging level [Default: INFO]. """) # check collector state with IVXVManagerDb() as db: collector_state = db.get_value('collector/state') logmonitor_address = db.get_value('logmonitor/address') services = db.get_all_values('service') if collector_state == COLLECTOR_STATE_NOT_INSTALLED: if not sys.stdout.isatty(): # suppress warning if executed from crontab return 0 log.warning("Collector is not installed") return 1 # create service host list hostnames = args[''] if not hostnames: hostnames = [] for service in services.values(): is_main_service = ( SERVICE_TYPE_PARAMS[service['service-type']]['main_service']) if ((is_main_service or service['service-type'] == 'log') and service['state'] != SERVICE_STATE_REMOVED): hostnames.append(service['ip-address'].split(':')[0]) hostnames = list(set(hostnames)) # checking access to Log Monitor account if not logmonitor_address: log.error('Log monitor is not defined') return 1 log.info("Using address %r for log monitor", logmonitor_address) logmon_account = f'logmon@{logmonitor_address}' log.info('Checking SSH access to Log Monitor account %s', logmon_account) proc = exec_remote_cmd(['ssh', logmon_account, 'true']) if proc.returncode: log.error('Cannot access to Log Monitor (%s)', logmon_account) return 1 # copy log file from service hosts to Log Monitor exit_code = 0 for hostname in hostnames: remote_account = f'ivxv-admin@{hostname}' # check if service host have Log Monitor host key log.info("Checking if %r have Log Monitor host key", remote_account) proc = exec_remote_cmd( ['ssh', hostname, 'ssh-keygen', '-F', logmonitor_address], stdout=subprocess.PIPE) if proc.returncode: log.error( 'Failed to check Log Monitor host key for %s', remote_account) log.info('Installing Log Monitor host key for %s', remote_account) proc = subprocess.run( ['sh', '-c', f'ssh-keygen -F {logmonitor_address} | ' 'grep -v ^# | ' f'ssh {hostname} tee --append .ssh/known_hosts'], check=False, ) if proc.returncode: log.error('Failed to install Log Monitor host key for %s', remote_account) continue if not copy_logs_from_host_to_logmon(hostname, logmon_account): exit_code = 1 return exit_code def copy_logs_from_host_to_logmon(hostname, logmon_account): """Copy log files from service host to Log Monitor.""" # acquire process lock lockfile_path = cfg_path( 'ivxv_admin_data_path', f'service/copy-log-from-{hostname}-to-logmon.lock') lock = fasteners.InterProcessLock(lockfile_path) if not lock.acquire(blocking=False): log.warning('Lock exists for process "copy logs from host %s ' 'to Log Monitor"', hostname) return False # execute rsync command in host to copy log file to Log Monitor proc = None try: log.info( "Copying IVXV service log files from host %r to Log Monitor", hostname) transfer_cmd = [ 'ivxv-admin-helper', 'copy-logs-to-logmon', hostname, logmon_account ] cmd = ['ssh-agent', 'ssh', '-A', hostname] + transfer_cmd proc = subprocess.run(cmd, check=False) finally: lock.release() if not proc.returncode: return True log.error("Failed to copy log file from host %r to Log Monitor", hostname) return False def update_software_pkg_util(): """Update service packages in service hosts.""" # validate CLI arguments args = init_cli_util(""" Update service packages in IVXV service hosts. This utility checks versions of software packages in service hosts and installs new versions if required. Usage: ivxv-update-packages [--force] [--service=] [--package=] Options: --force Update even package version does not require update --service= Update only specific service package (e.g. ivxv-voting) --package= Path to the service package """) if (not args['--service'] and args['--package'] or args['--service'] and not args['--package']): log.error('--service and --package should be set at the same time') return 1 # generate list of voting services that are in required state services = get_services( require_collector_state=[ COLLECTOR_STATE_INSTALLED, COLLECTOR_STATE_CONFIGURED, COLLECTOR_STATE_FAILURE, COLLECTOR_STATE_PARTIAL_FAILURE, ], service_state=[ SERVICE_STATE_INSTALLED, SERVICE_STATE_CONFIGURED, SERVICE_STATE_FAILURE, ], include_types=[args['--service'] or []] ) if not services: return 1 host_versions = dict( [services[service_id]['ip-address'].split(':')[0], ''] for service_id in sorted(services)) update_res = dict(failure=[], install=[], skip=[]) def get_installed_pkg_ver(): """Get version string if installed package in service host.""" service.log.info('Detect %s package version', pkg_name) proc = service.ssh( f'dpkg --status {pkg_name} | grep ^Version: | cut -d: -f2', stdout=subprocess.PIPE, account='ivxv-admin') return proc.stdout.decode('UTF-8').strip() for service_id, service_data in sorted(services.items()): with Service(service_id, service_data) as service: # check ivxv-common version host_version = host_versions.get(service.hostname) pkg_name = 'ivxv-common' # if specific service is requested to update, then skip install_pkg = bool(args['--force']) or bool(args['--service']) if not install_pkg and host_version != __version__: host_versions[service.hostname] = get_installed_pkg_ver() install_pkg = host_versions[service.hostname] != __version__ # install ivxv-common if required, don't install if specific service # is requested if install_pkg and not bool(args['--service']): if not service.update_ivxv_common_pkg(): update_res['failure'].append([service_id, pkg_name]) continue update_res['install'].append([service_id, pkg_name]) host_versions[service.hostname] = __version__ else: update_res['skip'].append([service_id, pkg_name]) # check service package version and upgrade if required, # package will be upgraded if specific service requested pkg_name = service.deb_pkg_name install_pkg = (args['--force'] or get_installed_pkg_ver() != __version__ or args['--service']) # install package if required if install_pkg: if not service.install_service_pkg(is_update=True, package=args['--package']): update_res['failure'].append([service_id, pkg_name]) continue update_res['install'].append([service_id, pkg_name]) else: update_res['skip'].append([service_id, pkg_name]) # output result for service_id, pkg_name in update_res['install']: log.info('Successfully installed service %s package %s', service_id, pkg_name) for service_id, pkg_name in update_res['failure']: log.error('Failed to install service %s package %s', service_id, pkg_name) log.info('Service update stats: %d packages installed, ' '%d package installations failed, %s packages skipped', len(update_res['install']), len(update_res['failure']), len(update_res['skip'])) return 1 if update_res['failure'] else None def manage_service(): """Manage IVXV services.""" # validate CLI arguments args = init_cli_util(""" Manage IVXV services. Usage: ivxv-service ... Options: Management action: start, stop, restart, ping """) action = args[''] if action not in ['start', 'stop', 'restart', 'ping']: log.error('Invalid action: %s', action) return 1 services = get_collector_data() if services is None: log.error('Election data is not loaded') return 1 exit_code = 0 for service_id in args['']: if service_id not in services: log.error('Unknown service %s', service_id) exit_code = 1 continue if action == 'ping': log.info('Pinging service %s', service_id) if ping_service(service_id, services[service_id]): log.info('Service %s is alive', service_id) else: log.error('Failed to query service %s status', service_id) exit_code = 1 continue with Service(service_id, services[service_id]) as service: if action == 'stop': log.info('Stopping service %s', service_id) if service.stop_service(): log.info('Service %s stopped', service_id) else: log.error('Failed to stop service %s', service_id) exit_code = 1 continue # start, restart log.info('%sing service %s', action.capitalize(), service_id) with Service(service_id, services[service_id]) as service: if service.restart_service(): log.info('Service %s %sed', service_id, action) else: log.error('Failed to %s service %s', action, service_id) exit_code = 1 return exit_code def voterstats_util(): """Import voter stats from voting service and export to VIS.""" args = init_cli_util( """ Import voter stats from voting service and export common stats to VIS. Usage: ivxv-voterstats [--action=] [--file=] [--service-id=] [--log-level=] Options: Stats type "common" or "detail". --action= Limit actions for "common" stats type. Possible values are "import" and "export". [Default: all] --file= Path to stats file. --service-id= Voting service ID [Default: random]. --log-level= Logging level [Default: INFO]. """ ) stats_type = args[""] action = args["--action"] filepath = args["--file"] if not filepath: filepath = f"/var/lib/ivxv/admin-ui-data/voterstats-{stats_type}.json" service_id = args["--service-id"] # validate CLI args if stats_type not in ["common", "detail"]: log.error("Unexpected stats type %r", stats_type) return 1 # check collector config state try: with IVXVManagerDb() as db: if not db.get_value("list/districts"): raise IvxvError("District list is not loaded") services = get_services( db=db, service_state=["CONFIGURED"], include_types=["voting"] ) if not services: raise IvxvError("No configured voting service found") except IvxvError as err: if not sys.stdout.isatty(): # suppress warning if executed from crontab return 0 log.warning(err) return 1 # choose voting service if service_id == "random": service_id = random.choice(list(services.keys())) if service_id not in services: services = get_services(include_types=["voting"]) if service_id in services: log.error( "Voting service %r is not configured (current state: %s)", service_id, services[service_id]["state"], ) else: log.error("No voting service %r found", service_id) return 1 service_logging.log.setLevel(args["--log-level"]) with Service(service_id, services[service_id]) as service: # import stats try: if action in ["all", "import"]: import_voterstats(stats_type, service, filepath, args["--log-level"]) except IvxvError: log.error( "Failed to import %s stats from service %r", stats_type, service_id) return 1 # export stats to VIS only if requested command_file.log.setLevel(args["--log-level"]) try: if action in ["all", "export"]: export_voterstats(stats_type, filepath) except IvxvError: log.error("Failed to export %s stats to VIS", stats_type) return 1 return 0 def import_voterstats(stats_type, service, filepath, log_level): """Import voter stats from voting service.""" log.info("Generating %s stats in voting service %r", stats_type, service.service_id) cmd = ["ivxv-voterstats", "-instance", service.service_id] if stats_type == "detail": cmd.append("-detailed") if logging.getLevelName(log_level) >= 30: cmd.append("-q") remote_filepath = ( f"/var/lib/ivxv/user/ivxv-voting/ivxv-voterstats-{os.getpid()}.json" ) cmd.append(remote_filepath) proc = service.ssh(cmd) if proc.returncode: raise IvxvError( f"Failed to generate {stats_type} stats " f"in voting service {service.service_id}" ) log.info( "Importing %s stats from voting service %r", stats_type, service.service_id ) if not service.scp( filepath, remote_filepath, f"{stats_type} stats", to_remote=False ): raise IvxvError(f"Failed to {stats_type} stats to management service") def export_voterstats(stats_type, filepath): """Export voter stats to VIS.""" log.info("Exporting %s stats to VIS", stats_type) with open(filepath) as fd: stats = json.load(fd) # get params from election config cfg = command_file.load_collector_cmd_file("election", "/etc/ivxv/election.bdoc") if not cfg: raise IvxvError("Election config not found") ca_certs_filepath = None if cfg["vis"].get("ca"): ca_certs_filepath = cfg_path("vis_path", "ca.pem") with open(ca_certs_filepath, "w") as fd: fd.write("\n".join(cfg["vis"]["ca"])) # upload voter stats url = f"{cfg['vis']['url']}voters-by-county" log.info("Upload voter stats to %r", url) resp = requests.post( url, verify=ca_certs_filepath, cert=( "/etc/ssl/certs/ivxv-admin-client.crt", "/etc/ssl/private/ivxv-admin-client.key", ), json=stats, ) log.info( "VIS responded to voter stats upload: %r %s", resp.status_code, resp.reason ) if resp.status_code != 204: raise IvxvError( f"Server responded with status {resp.status_code} - {resp.reason}" ) def voting_sessions_util(): """Utility to import voting sessions from Log Monitor.""" args = init_cli_util( """ Import list of voting sessions from Log Monitor. Session data is in CSV format. Usage: ivxv-voting-sessions (vote | verify) [--anonymize] [--uniq] [--log-level=] Options: Write sessions to file. --anonymize Anonymize session data (IP addresses and ID codes). --uniq Consolidate session data. --log-level= Logging level [Default: INFO]. """ ) # check collector state with IVXVManagerDb() as db: collector_state = db.get_value("collector/state") logmonitor_address = db.get_value("logmonitor/address") if collector_state == COLLECTOR_STATE_NOT_INSTALLED: # emit warning only if attached to console # (suppress if executed from crontab) if sys.stdout.isatty(): log.warning("Collector is not installed") return 1 return 0 # checking access to Log Monitor account if not logmonitor_address: log.error("Log monitor is not defined") return 1 log.info("Using address %r for log monitor", logmonitor_address) logmon_account = f"logmon@{logmonitor_address}" log.info("Checking SSH access to Log Monitor account %s", logmon_account) proc = exec_remote_cmd(["ssh", logmon_account, "true"]) if proc.returncode: log.error("Cannot access to Log Monitor (%s)", logmon_account) return 1 try: import_voting_sessions( logmon_account, session_type="vote" if args["vote"] else "verify", anonymize=args["--anonymize"], uniq=args["--uniq"], output_filepath=args[""], log_level=args["--log-level"], ) except IvxvError as err: log.error(err) return 1 return 0 def import_voting_sessions( logmon_account, session_type, anonymize, uniq, output_filepath, log_level ): """Import voting sessions from Log Monitor.""" # generate CSV log.info("Generating voting sessions file in Log Monitor") remote_outfile = f"~logmon/voting-sessions-{session_type}-{os.getpid()}.json" remote_cmd = ["ivxv-export-voting-sessions", f"--log-level={log_level}"] if anonymize: remote_cmd.append("--anonymize") if uniq: remote_cmd.append("--uniq") remote_cmd += [session_type, remote_outfile] cmd = ["ssh", logmon_account] + remote_cmd try: subprocess.run(cmd, stdout=subprocess.PIPE, check=True) except subprocess.CalledProcessError as err: raise IvxvError("Failed to generate voting sessions") from err log.info("Voting sessions file successfully generated in Log Monitor") # import CSV log.info("Importing voting sessions file from Log Monitor") cmd = ["scp", f"{logmon_account}:{remote_outfile}", output_filepath] try: subprocess.run(cmd, stdout=subprocess.PIPE, check=True) except subprocess.CalledProcessError as err: raise IvxvError("Failed to import voting sessions") from err log.info("Voting sessions file successfully imported from Log Monitor") def remove_ivxv_admin_crontab(): """Remove ivxv-admin user crontab if exists.""" log.info('Removing ivxv-admin user crontab (if exists)') proc = subprocess.run(["crontab", "-r"], check=False) assert proc.returncode in [0, 1], 'Unexpected exit code for crontab command' def generate_detail_stats_crontab(cfg: dict): """Generate crontab for detailed statistics exchange with VIS. Generated file will be stored to db. :param cfg: content of configuration file :type cfg: dict """ # load Jinja2 crontab template for detailed statistics template_dir = Environment(loader=PackageLoader('ivxv_admin', 'templates')) template = template_dir.get_template('ivxv_detail_stats_crontab.jinja') # read `stats:` section from a configuration file, # use default values if configuration file doesn't have `stats:` section cron_cfg = cfg.get('stats', {}).get('detail', {}).get('scheduler', {}) crontab_params = { 'minute': cron_cfg.get('cron', {}).get('min', '*/15') or '*/15', 'hour': cron_cfg.get('cron', {}).get('hour', '*') or '*', 'day': cron_cfg.get('cron', {}).get('day', '*') or '*', 'month': cron_cfg.get('cron', {}).get('month', '*') or '*', 'weekday': cron_cfg.get('cron', {}).get('weekday', '*') or '*', } # render Jinja2 template rendered_template = template.render( time_generated=datetime.datetime.now().strftime('%d.%M.%Y %H:%M:%S'), **crontab_params, ) # override crontab rendered template in a db with IVXVManagerDb(for_update=True) as db: db.set_value('stats/detail/scheduler/cron', rendered_template) def detail_stats_crontab_editor() -> int: args = init_cli_util(""" Generate crontab for IVXV detail statistics export to VIS automation. This utility must be called as editor by crontab utility: $ env VISUAL=ivxv-detail-stats-crontab crontab -e Usage: ivxv-detail-stats-crontab """) filepath = args[''] # when you run `crontab -e`, cron generates temporary file at '/tmp/XYZ/crontab', # and that temporary file is passed here as args[''], i.e 'filepath' crontab_tmp_file_content: str # read crontab temporary file with open(filepath, 'r') as fp: try: crontab_tmp_file_content = fp.read() except Exception as err: msg = "Can't read crontab temporary file %r: %s" log.error(msg, filepath, err.__str__()) return 1 # get rendered Jinja2 crontab template for detail stats from a db with IVXVManagerDb() as db: # get from db detail_stats_crontab = db.get_value('stats/detail/scheduler/cron') # remove old block: # ### block ivxv_detail_stats_crontab ### # ... # ### endblock ivxv_detail_stats_crontab ### # from a crontab temporary file if any exists try: without_detail_stats_crontab = remove_detail_stats_crontab( data=crontab_tmp_file_content) except ValueError as err: msg = "Can't remove ivxv_detail_stats block from a temporary file %r: %s" log.error(msg, filepath, err.__str__()) return 1 # add new block to a crontab temporary file crontab = insert_detail_stats_crontab( data=without_detail_stats_crontab, crontab=detail_stats_crontab) # Pause for 1 second. Crontab checks mtime to detect file modifications. It # seems that crontab can't detect mtime change if changes happens too # quickly (tested in Ubuntu Xenial). time.sleep(1) # override crontab temporary file with a new content with open(filepath, "w") as fp: try: fp.write(crontab) except Exception as err: msg = "Can't write to a crontab temporary file %r: %s" log.error(msg, filepath, err.__str__()) return 1 def remove_detail_stats_crontab(data: str) -> str: """Remove ivxv_detail_stats_crontab block from a data. :param data: any data :type data: str :return: data without ivxv_detail_stats_crontab block :rtype: str """ block, found = __get_detail_stats_crontab_block(data=data) if not found: return data return data.replace(block, '').strip() def insert_detail_stats_crontab(data: str, crontab: str) -> str: """Wrap crontab in an ivxv_detail_stats_crontab block and insert it to a data. :param data: any data :type data: str :param crontab: rendered ivxv_detail_stats Jinja2 crontab template file :type crontab: str :return: data with an ivxv_detail_stats_crontab block :rtype: str """ header = '### block ivxv_detail_stats_crontab ###' tail = '### endblock ivxv_detail_stats_crontab ###' return data + "\n\n" + header + "\n" + crontab + "\n" + tail + "\n" def __get_detail_stats_crontab_block(data: str) -> (str, bool): """Get ivxv_detail_stats_crontab block from a data. :param data: any data :type data: str :return: ivxv_detail_stats_crontab block and True on success, otherwise data and False :rtype: str, bool :raise ValueError: if ivxv_detail_stats_crontab block's header/tail is malformed, however though, if both header and tail are malformed then function assumes that ivxv_detail_stats_crontab block doesn't exist in a data """ header = '### block ivxv_detail_stats_crontab ###' tail = '### endblock ivxv_detail_stats_crontab ###' # remove leading and trailing whitespaces/newlines data_stripped = data.strip() # get start index of a header header_start_index = data_stripped.find(header) # get start index of a tail tail_start_index = data_stripped.find(tail) # both header and tail aren't present in a data_stripped if header_start_index < 0 and tail_start_index < 0: return data, False # both header and tail present in a data_stripped elif header_start_index >= 0 and tail_start_index >= 0: # get end index of a tail tail_end_index = tail_start_index + len(tail) # extract ivxv_detail_stats_crontab block from a data_stripped return data_stripped[header_start_index:tail_end_index], True else: if header_start_index < 0: raise ValueError("malformed ### block ivxv_detail_stats_crontab ###") else: raise ValueError("malformed ### endblock ivxv_detail_stats_crontab ###") def install_detail_stats_crontab(): """Install crontab for detail stats export with VIS automation.""" subprocess.run( ["env", "VISUAL=ivxv-detail-stats-crontab", "crontab", "-e"], check=True) def generate_voting_facts_crontab(cfg: dict): """Generate crontab for ivxv-storageorder automation. Generated file will be stored to db. :param cfg: content of configuration file :type cfg: dict """ # load Jinja2 crontab template for voting facts template_dir = Environment(loader=PackageLoader('ivxv_admin', 'templates')) template = template_dir.get_template('ivxv_voting_facts_crontab.jinja') # read `stats:` section from a configuration file, # use default values if configuration file doesn't have `stats:` section cron_cfg = cfg.get('stats', {}).get('voting_facts', {}).get('scheduler', {}) crontab_params = { 'minute': cron_cfg.get('cron', {}).get('min', '*/15') or '*/15', 'hour': cron_cfg.get('cron', {}).get('hour', '*') or '*', 'day': cron_cfg.get('cron', {}).get('day', '*') or '*', 'month': cron_cfg.get('cron', {}).get('month', '*') or '*', 'weekday': cron_cfg.get('cron', {}).get('weekday', '*') or '*', } # render Jinja2 template rendered_template = template.render( time_generated=datetime.datetime.now().strftime('%d.%M.%Y %H:%M:%S'), **crontab_params, ) # override crontab rendered template in a db with IVXVManagerDb(for_update=True) as db: db.set_value('stats/voting_facts/scheduler/cron', rendered_template) def voting_facts_crontab_editor() -> int: args = init_cli_util(""" Generate crontab for ivxv-storageorder automation. This utility must be called as editor by crontab utility: $ env VISUAL=ivxv-voting-facts-crontab crontab -e Usage: ivxv-voting-facts-crontab """) filepath = args[''] # when you run `crontab -e`, cron generates temporary file at '/tmp/XYZ/crontab', # and that temporary file is passed here as args[''], i.e 'filepath' crontab_tmp_file_content: str # read crontab temporary file with open(filepath, 'r') as fp: try: crontab_tmp_file_content = fp.read() except Exception as err: msg = "Can't read crontab temporary file %r: %s" log.error(msg, filepath, err.__str__()) return 1 # get rendered Jinja2 crontab template for voting facts from a db with IVXVManagerDb() as db: # get from db voting_facts_crontab = db.get_value('stats/voting_facts/scheduler/cron') # remove old block: # ### block ivxv_voting_facts_crontab ### # ... # ### endblock ivxv_voting_facts_crontab ### # from a crontab temporary file if any exists try: without_voting_facts_crontab = remove_voting_facts_crontab( data=crontab_tmp_file_content) except ValueError as err: msg = "Can't remove ivxv_voting_facts_crontab block from a tmp file %r: %s" log.error(msg, filepath, err.__str__()) return 1 # add new block to a crontab temporary file crontab = insert_voting_facts_crontab( data=without_voting_facts_crontab, crontab=voting_facts_crontab) # Pause for 1 second. Crontab checks mtime to detect file modifications. It # seems that crontab can't detect mtime change if changes happens too # quickly (tested in Ubuntu Xenial). time.sleep(1) # override crontab temporary file with a new content with open(filepath, "w") as fp: try: fp.write(crontab) except Exception as err: msg = "Can't write to a crontab temporary file %r: %s" log.error(msg, filepath, err.__str__()) return 1 def remove_voting_facts_crontab(data: str) -> str: """Remove ivxv_voting_facts_crontab block from a data. :param data: any data :type data: str :return: data without ivxv_voting_facts_crontab block :rtype: str """ block, found = __get_voting_facts_crontab_block(data=data) if not found: return data return data.replace(block, '').strip() def insert_voting_facts_crontab(data: str, crontab: str) -> str: """Wrap crontab in an ivxv_voting_facts_crontab block and insert it to a data. :param data: any data :type data: str :param crontab: rendered ivxv_voting_facts_crontab Jinja2 crontab template file :type crontab: str :return: data with an ivxv_voting_facts_crontab block :rtype: str """ header = '### block ivxv_voting_facts_crontab ###' tail = '### endblock ivxv_voting_facts_crontab ###' return data + "\n\n" + header + "\n" + crontab + "\n" + tail + "\n" def __get_voting_facts_crontab_block(data: str) -> (str, bool): """Get ivxv_voting_facts_crontab block from a data. :param data: any data :type data: str :return: ivxv_voting_facts_crontab block and True on success, otherwise data and False :rtype: str, bool :raise ValueError: if ivxv_voting_facts_crontab block's header/tail is malformed, however though, if both header and tail are malformed then function assumes that ivxv_voting_facts_crontab block doesn't exist in a data """ header = '### block ivxv_voting_facts_crontab ###' tail = '### endblock ivxv_voting_facts_crontab ###' # remove leading and trailing whitespaces/newlines data_stripped = data.strip() # get start index of a header header_start_index = data_stripped.find(header) # get start index of a tail tail_start_index = data_stripped.find(tail) # both header and tail aren't present in a data_stripped if header_start_index < 0 and tail_start_index < 0: return data, False # both header and tail present in a data_stripped elif header_start_index >= 0 and tail_start_index >= 0: # get end index of a tail tail_end_index = tail_start_index + len(tail) # extract ivxv_voting_facts_crontab block from a data_stripped return data_stripped[header_start_index:tail_end_index], True else: if header_start_index < 0: raise ValueError("malformed ### block ivxv_voting_facts_crontab ###") else: raise ValueError("malformed ### endblock ivxv_voting_facts_crontab ###") def install_voting_facts_crontab(): """Install crontab for ivxv-storageorder automation.""" subprocess.run( ["env", "VISUAL=ivxv-voting-facts-crontab", "crontab", "-e"], check=True) def voting_facts_util(): """Launch log analyzer on IVXV Logmonitor to search for missing voting facts, then export these facts as .csv file and run 'ivxv-storageorder' on a first Collector host, where operation succeeds, in case of unsuccessful operation it will choose another Collector host, until succeeds, or returns an error.""" init_cli_util( """ Launch log analyzer on IVXV Logmonitor to search for missing voting facts, then export these facts as .csv file and then run 'ivxv-storageorder' on a first Collector host, where operation succeeds, in case of unsuccessful operation it will choose another Collector host, until succeeds, or returns an error. Usage: ivxv-voting-facts """ ) filename = f"votesorder-{time.time_ns()}.csv" with IVXVManagerDb() as db: collector_state = db.get_value("collector/state") services = db.get_all_values("service") logmon_host = db.get_value('logmonitor/address') if not logmon_host: log.error("Log monitor is not defined") return 1 if collector_state != COLLECTOR_STATE_CONFIGURED: if not sys.stdout.isatty(): # suppress warning if executed from crontab return 0 log.warning("Collector is not configured") return 1 votesorder_services = {} # Find all votesorder service host addresses for service_id, service in services.items(): service_type = service["service-type"] is_votesorder_service = service_type == "votesorder" if is_votesorder_service and service["state"] != SERVICE_STATE_REMOVED: votesorder_services[service_id] = service["ip-address"].split(":")[0] if len(votesorder_services.keys()) < 1: log.error("No votesorder services found") return 1 # Prepare missing voting facts .csv file on first succeeded Logmonitor host logmon_account = f"logmon@{logmon_host}" proc = exec_remote_cmd(['ssh', logmon_account, "ivxv-storageorder-prepare-csv.sh", "--filename", filename]) if proc.returncode: logmon_account = "" if proc.returncode == 2: log.info("No missing voting facts found") return 0 log.error( f"Error while preparing .csv: {proc}") if logmon_account == "": log.error(f"Logmonitor host is not active {proc}") return 1 # Copy .csv file from succeeded Log host to first active Collector host collector_account = "" for service_host in votesorder_services.values(): collector_account = f"ivxv-votesorder@{service_host}" proc = exec_remote_cmd( ["scp", f"{logmon_account}:{filename}", f"{collector_account}:{filename}"]) if proc.returncode: collector_account = "" log.error( f"Cannot copy .csv file from {logmon_account} to {collector_account} " f"due to an error: {proc}") continue if collector_account == "": log.error(f"No active Collector hosts among {votesorder_services.values()}") return 1 # Add missing voting facts using ivxv-storageorder for service_id, service_host in votesorder_services.items(): collector_account = f"ivxv-votesorder@{service_host}" proc = exec_remote_cmd( ["ssh", f"{collector_account}", "ivxv-storageorder", "-file", f"{filename}", "-instance", f"{service_id}"]) if proc.returncode: collector_account = "" log.error(f"Running ivxv-storageorder failed with error: {proc}") continue if collector_account == "": log.error(f"ivxv-storageorder failed on {votesorder_services.values()} hosts") return 1 return 0 def create_voter_list_download_crontab(cfg: dict): """ Creates a cron job for running CLI ivxv-voter-list-download every X minute as defined in configuration file vis:min: section, X defaults to 15 minutes. :param cfg: configuration file """ # read `vis:` section from a configuration file and parse 'min:' int value out minutes = cfg.get('vis', {}).get('min', 15) with CronTab(user=IVXV_ADMIN_CRON_USER) as cron: # remove old ivxv-voter-list-download job for job in cron: if job.command == VOTER_LIST_DOWNLOAD_CRON_JOB: cron.remove(job) # install new one cron.new(command=VOTER_LIST_DOWNLOAD_CRON_JOB).minute.every(minutes) ================================================ FILE: collector-admin/ivxv_admin/cli_utils/status_utils.py ================================================ # IVXV Internet voting framework """CLI utilities for management service state.""" import json import re from jinja2 import Environment, PackageLoader from .. import lib from ..db import IVXVManagerDb from . import init_cli_util, log def users_list_util(): """User listing utility for collector administrator interface.""" init_cli_util(""" List IVXV Collector Management Service registered users. Usage: ivxv-users-list """) # read users from database with IVXVManagerDb() as db: users = db.get_all_values('user') # output users user_no = 0 for user_cn, permissions in sorted(users.items()): user_no += 1 print(f"{user_no}. {user_cn} Permissions: {permissions}") if not user_no: print('No users defined') def status_util(): """Output collector state.""" args = init_cli_util(""" Output IVXV Collector state. Usage: ivxv-status [--json] [--service= ...] [ ...] Options: --json Output full data in JSON format. Note: filters have no effect in JSON output. --service= Filter output by service ID. Note: This filter conflicts other section filters than "smart" or "service". Filter output by section. Possible values are: * collector - collector state; * election - election data; * config - versions of loaded config; * list - versions of loades lists; * service - service information; * ext - external service information; * storage - storage information; * smart - output only relevant data; * all - output all data; [Default: smart]. """) filters = args[''] or ['smart'] # validate CLI args data_sections = [ 'collector', 'election', 'config', 'list', 'service', 'ext', 'storage'] for arg in filters: if arg not in data_sections + ['all', 'smart']: log.error('Invalid section: %s', arg) return 1 if 'all' in filters: filters = data_sections if args['--service']: if filters not in (['smart'], ['service']): log.error('Service ID can only used with ' '"smart" or "service" section filters') return 1 filters = ['service'] if 'smart' in filters: filters = ['smart', 'collector', 'storage'] # generate state data with IVXVManagerDb() as db: state = lib.generate_collector_state(db) # output JSON if args['--json']: print(json.dumps(state, indent=4, sort_keys=True)) return 0 # apply smart filtering if 'smart' in filters: cfg_state_filters(filters, state) # apply service ID filters if args['--service']: for service_id in args['--service']: if service_id not in state['service'].keys(): log.error("Unknown service ID %r", service_id) return 1 for network_id in list(state['network']): for service_id in list(state['network'][network_id]): if service_id not in args['--service']: del state['network'][network_id][service_id] if not state['network'][network_id]: del state['network'][network_id] # output plain text tmpl_env = Environment(loader=PackageLoader('ivxv_admin', 'templates')) template = tmpl_env.get_template('ivxv_status.jinja') output = template.render(state, sections=filters) output = re.sub(r'\n\n+', '\n\n', output) print(output.strip()) return 0 def cfg_state_filters(filters, state): """Reconfigure list of state filters depending on actual state.""" if (state['config']['trust'] or state['config']['technical'] or state['config']['election']): filters += ['config'] if state['config']['election']: filters += ['election'] if (state['list']['choices-loaded'] or state['list']['choices'] or state['list']['districts-loaded'] or state['list']['districts'] or state['list'].get('voters0000') or state['list'].get('voters0000-loaded')): filters += ['list'] if state.get('service'): filters += ['service'] ================================================ FILE: collector-admin/ivxv_admin/collector_state.py ================================================ # IVXV Internet voting framework """ Collector state for collector management service. """ import datetime import json import logging import os import dateutil.parser from . import (COLLECTOR_PKG_FILENAMES, COLLECTOR_STATE_CONFIGURED, COLLECTOR_STATE_FAILURE, COLLECTOR_STATE_INSTALLED, COLLECTOR_STATE_NOT_INSTALLED, COLLECTOR_STATE_PARTIAL_FAILURE, SERVICE_STATE_CONFIGURED, SERVICE_STATE_FAILURE, SERVICE_STATE_INSTALLED, SERVICE_STATE_NOT_INSTALLED, SERVICE_TYPE_PARAMS) from .config import CONFIG, cfg_path from .service import generate_service_hints # create logger log = logging.getLogger(__name__) def generate_collector_state(db): """Generate collector state data.""" state = db.get_all_values() # generate service data if state.get('service'): generate_service_hints(state['service']) # group services by network state['network'] = dict() for service_id, service_rec in state.get('service').items(): nw_name = service_rec.pop('network') state['network'].setdefault(nw_name, dict()) state['network'][nw_name][service_id] = service_rec # check package files assert 'storage' not in state state["storage"] = { "debs_exists": [], "debs_missing": [], "command_files_active": [], "command_files_inactive": [], } for pkg_filename in COLLECTOR_PKG_FILENAMES.values(): pkg_filepath = cfg_path('deb_pkg_path', pkg_filename) key = 'debs_exists' if os.path.exists(pkg_filepath) else 'debs_missing' state['storage'][key].append(pkg_filepath) # collect command files state command_filepaths = [ cfg_path("command_files_path", filename) for filename in os.listdir(CONFIG["command_files_path"]) if not filename.endswith(".json") ] for filename in os.listdir(CONFIG["active_config_files_path"]): filepath = os.path.join(CONFIG["active_config_files_path"], filename) if os.path.islink(filepath): try: command_filepaths.remove(os.readlink(filepath)) except ValueError: log.warning( "Unresolved config file link %r -> %r", filepath, os.readlink(filepath), ) state["storage"]["command_files_active"].append( os.path.basename(os.readlink(filepath)) ) state["storage"]["command_files_active"].sort() state["storage"]["command_files_inactive"] = sorted( os.path.basename(filename) for filename in command_filepaths ) # detect collector state state['collector_state'] = detect_collector_state(state) generate_voter_list_state(state) generate_election_state(state) return state def detect_collector_state(state): """Detect collector state. :param state: Collector state data. Probably values from Collector Management Database. :type state: dict """ service_states = [ val['state'] for val in state.get('service', {}).values() ] # NOT INSTALLED # Stay in NOT INSTALLED state while: # - some service is not installed if (state['collector']['state'] == COLLECTOR_STATE_NOT_INSTALLED and (not state['config']['technical'] or not service_states or SERVICE_STATE_NOT_INSTALLED in service_states)): return COLLECTOR_STATE_NOT_INSTALLED # INSTALLED # Stay in INSTALLED state until technical config is applied to all services if (state['collector']['state'] == COLLECTOR_STATE_INSTALLED and SERVICE_STATE_INSTALLED in service_states): return COLLECTOR_STATE_INSTALLED # CONFIGURED if SERVICE_STATE_FAILURE not in service_states: return COLLECTOR_STATE_CONFIGURED # collect service states by type service_state_by_type = {} for _, service_data in sorted(state['service'].items()): service_state_by_type[service_data['service-type']] = ( service_state_by_type.get(service_data['service-type'], [])) service_state_by_type[service_data['service-type']].append( service_data['state']) # FAILURE for service_type, service_params in SERVICE_TYPE_PARAMS.items(): if not service_params['main_service']: continue if (service_type in service_state_by_type and SERVICE_STATE_CONFIGURED not in service_state_by_type[service_type]): return COLLECTOR_STATE_FAILURE # PARTIAL FAILURE return COLLECTOR_STATE_PARTIAL_FAILURE def generate_voter_list_state(state): """Generate voter list block for collector state data.""" state["list"].update( { "voters-list-total": 0, "voters-list-available": 0, "voters-list-pending": 0, "voters-list-applied": 0, "voters-list-invalid": 0, "voters-list-skipped": 0, } ) for changeset_no in range(10_000): key = f"voters{changeset_no:04d}-state" if key not in state['list']: break list_state = state["list"][key].lower() state["list"][f"voters-list-{list_state}"] += 1 state["list"]["voters-list-total"] += 1 # compare with VIS changeset data vis_changesets_filepath = f"{CONFIG.get('vis_path')}/voters-changesets.json" if state["list"]["voters-list-total"] and os.path.exists(vis_changesets_filepath): with open(vis_changesets_filepath) as fd: changesets = json.load(fd) for changeset_no, changeset in enumerate(changesets["changesets"]): key = f"voters{changeset_no:04d}" if key not in state["list"]: state["list"]["voters-list-available"] += 1 state["list"].update( {key: "[version not registered]", f"{key}-state": "AVAILABLE"} ) def generate_election_state(state): """Generate election block for collector state data.""" state['election']['phase'] = None state['election']['phase-start'] = None state['election']['phase-end'] = None if not state['election']: return def get_ts(name): """ Get timestamp value as datetime.datetime object or None if value is not set. """ value = state['election'][name] return dateutil.parser.parse(value) if value else None electionstart = get_ts('electionstart') electionstop = get_ts('electionstop') servicestart = get_ts('servicestart') servicestop = get_ts('servicestop') verificationstop = get_ts('verificationstop') ts_format = '%Y-%m-%dT%H:%M %Z' phases = [ [not electionstart, 'PREPARING', None, None], [ servicestart and datetime.datetime.now(servicestart.tzinfo) < servicestart, 'WAITING FOR SERVICE START', None, servicestart ], [ electionstart and datetime.datetime.now(electionstart.tzinfo) < electionstart, 'WAITING FOR ELECTION START', servicestart, electionstart ], [ electionstop and datetime.datetime.now(electionstop.tzinfo) < electionstop, 'ELECTION', electionstart, electionstop ], [ servicestop and datetime.datetime.now(servicestop.tzinfo) < servicestop, 'WAITING FOR SERVICE STOP', electionstop, servicestop ], [ verificationstop and datetime.datetime.now(verificationstop.tzinfo) < verificationstop, 'WAITING FOR VERIFICATION SERVICE STOP', servicestop, verificationstop ], [True, 'FINISHED', verificationstop, None], ] for phase_active, name, start_time, stop_time in phases: if phase_active: state['election']['phase'] = name state['election']['phase-start'] = ( start_time.strftime(ts_format) if start_time else '-') state['election']['phase-end'] = ( stop_time.strftime(ts_format) if stop_time else '-') break ================================================ FILE: collector-admin/ivxv_admin/command_file.py ================================================ # IVXV Internet voting framework """ Command file loading module collector management service. """ import datetime import json import logging import os import re import subprocess import tempfile import zipfile import schematics.exceptions import yaml from . import (CFG_TYPES, CMD_DESCR, CMD_TYPES, PERMISSION_ELECTION_CONF, PERMISSION_TECH_CONF, PERMISSION_USERS_ADMIN, RFC3339_DATE_FORMAT_WO_FRACT, USER_ROLES, VOTING_LIST_TYPES) from .config import CONFIG from .config_validator.validator_util import validate_cfg from .db import IVXVManagerDb from .lib import IvxvError # create logger log = logging.getLogger(__name__) def load_collector_cmd_file(cmd_type, filename, plain=False): """Load and validate collector command file. :param plain: Load plain file or BDOC container. :type plain: bool :return: Config as data structure or None on error :rtype: dict """ assert cmd_type in CMD_TYPES, f"Invalid command type {cmd_type!r}" file_descr = CMD_DESCR[cmd_type] if plain: cmd_filename = filename filename = None elif cmd_type in CFG_TYPES: cmd_filename = re.compile(rf"(.+\.)?{cmd_type}.yaml$") elif cmd_type in VOTING_LIST_TYPES: cmd_filename = None else: assert cmd_type == 'user' cmd_filename = 'user.json' # load content from file cfg = None try: cfg = load_cfg_file_content(cmd_type, cmd_filename, filename) except (IvxvError, OSError) as err: log.error('Error while loading config file: %s', err) except UnicodeDecodeError as err: log.error('Error while decoding config file: %s', err) except json.decoder.JSONDecodeError as err: log.error('JSON error in config file: %s', err) if cfg is None: return None # validate config file log.info('Validating %s', file_descr) try: cfg = validate_cfg(cfg, cmd_type) except ValueError as err: log.error(err) return None except schematics.exceptions.DataError as data_error: log_cfg_validation_errors(data_error.errors) return None # validate election ID in config if cmd_type not in ['technical', 'trust', 'user']: with IVXVManagerDb() as db: election_id = db.get_value('election/election-id') if election_id: if cmd_type == 'election': cfg_election_id = cfg.get('identifier') elif cmd_type in ['choices', 'districts', 'voters']: cfg_election_id = cfg.get('election') else: raise NotImplementedError(f"Unknown config type {cmd_type}") if election_id != cfg_election_id: log.error( "Election ID %r in config file does not match " "with current election ID %r", cfg_election_id, election_id) return None if plain: log.info('%s is valid', file_descr.capitalize()) else: log.info('Files in %s package are valid', file_descr) return cfg def load_cfg_file_content(cmd_type, cfg_filename, cmd_filename): """Load config file content from command file container. :param cfg_filename: Config file name :type cfg_filename: str or regexp pattern :param cmd_filename: Container file name. Plain config file is used if None. :type cmd_filename: str :return: Config as data structure; string for voter list; or None on error :rtype: dict :raises UnicodeDecodeError: if config file is not in UTF-8 :raises OSError: if some file operation fails :raises json.decoder.JSONDecodeError: if JSON decoding fails :raises IvxvError: if some internal check fails """ file_descr = CMD_DESCR[cmd_type] # load plain config file if cmd_filename is None: return load_plain_cfg_file( cmd_type, os.path.dirname(cfg_filename), os.path.basename(cfg_filename)) # load BDOC command file log.info('Loading command file %r (%s)', cmd_filename, file_descr) try: cmd_file = zipfile.ZipFile(cmd_filename) except FileNotFoundError: raise IvxvError(f"File {cmd_filename!r} not found") except zipfile.BadZipFile: raise IvxvError(f"File {cmd_filename!r} is not a valid ZIP container") log.debug('Command file loaded') log.debug("Files in command file container: %r", cmd_file.namelist()) # parse contents of command file filenames_in_bdoc = cmd_file.namelist() for filename in filenames_in_bdoc[:]: if filename in [ 'META-INF/manifest.xml', 'META-INF/signatures0.xml', 'mimetype' ]: filenames_in_bdoc.remove(filename) if cfg_filename is None: cfg_filename = get_command_filename(cmd_type, filenames_in_bdoc) if cfg_filename is None: raise IvxvError("No command filename detected") log.debug("Detected command filename %r", cfg_filename) if isinstance(cfg_filename, str) and cfg_filename not in filenames_in_bdoc: raise IvxvError( f'Command file does not contain expected file {cfg_filename} ' f'for {file_descr}') if isinstance(cfg_filename, type(re.compile(''))): for filename in filenames_in_bdoc: if cfg_filename.match(filename): cfg_filename = filename break else: raise IvxvError( f'Command file does not contain expected ' f'file {cfg_filename.pattern} for {file_descr}') # create temporary directory to extract container with tempfile.TemporaryDirectory() as dirpath: log.debug("Extracting command file to directory %r", dirpath) cmd_file.extractall(dirpath) log.debug('Command file successfully extracted') cfg = load_plain_cfg_file(cmd_type, dirpath, cfg_filename) return cfg def ck_json_dict_key_uniqueness(args): """Json loader hook to check dict key uniqueness. Add strictness for json loader to detect JSON that violates dict key uniqueness. """ keys = [_[0] for _ in args] for key in keys: if keys.count(key) > 1: raise IvxvError(f"Duplicate key {key!r} in JSON object") return dict(args) def load_plain_cfg_file(cmd_type, dirpath, filename): """Load content from plain config file.""" log.debug("Reading file %r", os.path.join(dirpath, filename)) cwd = os.getcwd() if dirpath: os.chdir(dirpath) try: with open(filename, 'rb') as fp: # possible UnicodeDecodeError must be handled by caller file_content = fp.read().decode('utf-8') if cmd_type in CFG_TYPES: cfg = load_yaml_file(file_content) elif cmd_type in ('choices', 'districts', 'user'): cfg = json.loads( file_content, object_pairs_hook=ck_json_dict_key_uniqueness) else: assert cmd_type == 'voters' if filename.endswith(".skip.yaml"): cfg = load_yaml_file(file_content) else: cfg = file_content finally: if dirpath: os.chdir(cwd) return cfg def get_command_filename(cmd_type, filenames_in_bdoc): """Get command file name from list of filenames. Get command file for choice list, district list, voter list or voter list changeset skip command. :return: Command filename or None on error :rtype: str """ filename = None if cmd_type in ('choices', 'districts'): if len(filenames_in_bdoc) > 1: log.error( "Too many files in %s file: %r", CMD_DESCR[cmd_type], filenames_in_bdoc) elif not filenames_in_bdoc: log.error('Missing %s list in %s file', cmd_type, CMD_DESCR[cmd_type]) else: filename = filenames_in_bdoc[0] elif cmd_type == 'voters': if len(filenames_in_bdoc) > 2: log.error("Too many files in %s file: %r", CMD_DESCR[cmd_type], filenames_in_bdoc) elif ( len(filenames_in_bdoc) == 1 and filenames_in_bdoc[0].endswith(".skip.yaml") ): filename = filenames_in_bdoc[0] elif len(filenames_in_bdoc) < 2: log.error('Missing voters list or signature in %s file', CMD_DESCR[cmd_type]) else: sig_filename, utf_filename = sorted(filenames_in_bdoc) if (utf_filename.endswith('.utf') and sig_filename == utf_filename[:-4] + '.sig'): filename = utf_filename else: log.error('Voters list and signature file names do not ' 'match (filenames: %s)', ', '.join([utf_filename, sig_filename])) log.error('List file must have ".utf" extension and ' 'signature file the same base with ".sig" extension') else: raise NotImplementedError return filename def check_cmd_signature(cmd_type, filename): """ Check collector command file signature. :return: Two lists, first one contains signatures by authorized users, second one contains all signatures. :rtype: tuple :raises OSError: if reading command file fails or if :command:`ivxv-verify-container` command not found :raises subprocess.SubprocessError: on :command:`ivxv-verify-container` error :raises LookupError: on invalid signature line :raises IvxvError: on trust root config validation error """ log.debug("Checking command file %r (%s) signature", filename, cmd_type) # detect trust root file trust_container_filepath = ( filename if cmd_type == 'trust' else os.path.join(CONFIG['active_config_files_path'], 'trust.bdoc')) # execute verifier command proc = exec_container_verifier(trust_container_filepath, filename) # parse command output and create signatures list all_signatures = [] for line in proc.stdout.strip().split('\n'): if not re.match(r'.+,.+,[0-9]{11} ', line): raise LookupError(f"Invalid signature line: {line}") signer, timestamp_str = line.split(' ') timestamp = datetime.datetime.strptime( timestamp_str, RFC3339_DATE_FORMAT_WO_FRACT).timestamp() all_signatures.append([timestamp, signer, line]) all_signatures.sort() # check signers authorization for trust root config if cmd_type == 'trust': log.debug('Check signers authorization against trust root config') cfg = load_collector_cmd_file(cmd_type, filename) if cfg is None: raise IvxvError('Trust root file is not valid') trusted_signers = cfg.get('authorizations', []) authorized_signatures = [ [signature, 'admin'] for timestamp, signer, signature in all_signatures if signer in trusted_signers] return authorized_signatures, all_signatures # detect permission for command type if cmd_type == 'technical': permission = PERMISSION_TECH_CONF elif cmd_type in CFG_TYPES or cmd_type in VOTING_LIST_TYPES: permission = PERMISSION_ELECTION_CONF else: assert cmd_type == 'user' permission = PERMISSION_USERS_ADMIN # check signers authorization for other config files log.debug( 'Check signers authorization against collector management database') authorized_signatures = [] with IVXVManagerDb() as db: for timestamp, signer, signature in all_signatures: try: roles = db.get_value(f'user/{signer}') except KeyError: log.debug('No database record for signer %s', signer) continue authorized_signatures += [ [signature, role] for role in roles.split(',') if permission in USER_ROLES[role]['permissions'] ] return authorized_signatures, all_signatures def exec_container_verifier(trust_container_filepath, filepath): """Execute container verifier command.""" cmd = [ 'ivxv-verify-container', '-trust', trust_container_filepath, filepath ] log.debug("Executing command %r", " ".join(cmd)) try: proc = subprocess.run( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=False, universal_newlines=True, ) except OSError as err: err.strerror = ( f"Error while executing verifier command {' '.join(cmd)!r}: {err.strerror}" ) raise err if proc.returncode == 0: return proc verifier_errors = { 64: 'Command was used incorrectly', 65: 'Failed to open container', 66: 'Input file did not exist or was not readable', 74: 'Failed read trust root', } err_msg = verifier_errors.get(proc.returncode, 'Unhandled error') print('Container verifier output:') print(proc.stdout) print(proc.stderr) raise subprocess.SubprocessError( f'Failed to execute container verifier: {err_msg}') def log_cfg_validation_errors(items, prefix="/"): """Log validation errors.""" for field_name, val in items.items(): if isinstance(val, dict): log_cfg_validation_errors(val, f"{prefix}{field_name}/") else: log.error("Validation error for field %r: %s", prefix + field_name, val) def load_yaml_file(fp): """Load YAML file. :return: Content of loaded file :rtype: dict :raises OSError: if some file operation fails """ def container_constructor_handler(loader, node): """Handler for !container constructor.""" filename = loader.construct_scalar(node) if os.path.dirname(filename): raise OSError( f"Referenced file {filename!r} must be in the same " "directory with YAML file." ) with open(filename) as fp: content = (yaml.load(fp, yaml.Loader) if filename[-5:] == '.yaml' else fp.read(-1)) return content def timestamp_constructor(loader, node): """ Handler for timestamp fields. Returns string field instead of datetime. """ assert loader # unused variable return node.value yaml.add_constructor('tag:yaml.org,2002:timestamp', timestamp_constructor) yaml.add_constructor('!container', container_constructor_handler) return yaml.load(fp, yaml.Loader) ================================================ FILE: collector-admin/ivxv_admin/config.py ================================================ # IVXV Internet voting framework """ Config file loader for collectors management service. """ import configparser import logging import logging.config import os import sys #: Config file name. CFG_FILE_NAME = 'ivxv-collector-admin.conf' #: Default values for config. CFG_DEFAULTS = { # base directory for management service data files 'ivxv_admin_data_path': os.environ.get('IVXV_ADMIN_DATA_PATH', '/var/lib/ivxv'), # directory for admin UI static data files (used directly by web UI) 'admin_ui_data_path': '%(ivxv_admin_data_path)s/admin-ui-data', # directory for admin UI permissions 'permissions_path': '%(ivxv_admin_data_path)s/admin-ui-permissions', # directory for applied command files 'command_files_path': '%(ivxv_admin_data_path)s/commands', # directory for collector config files 'active_config_files_path': '/etc/ivxv', # directory for uploaded files 'file_upload_path': '%(ivxv_admin_data_path)s/upload', # directory for exported votes 'exported_votes_path': '%(ivxv_admin_data_path)s/ballot-box', # directory for ivxv debian packages 'deb_pkg_path': '/etc/ivxv/debs', # management database directory 'ivxv_db_path': '%(ivxv_admin_data_path)s/db', # management database file path 'ivxv_db_file_path': '%(ivxv_db_path)s/ivxv-management.db', # directory for other service related data files "service_path": "%(ivxv_admin_data_path)s/service", # directory for VIS related data files (used to download voter list # changesets) "vis_path": "%(ivxv_admin_data_path)s/vis", } CFG_PARSER = configparser.ConfigParser(defaults=CFG_DEFAULTS) CFG_FILES_USED = [] #: Config file paths. CFG_PATHS = [ os.path.join(os.curdir, CFG_FILE_NAME), os.path.join('/etc/ivxv', CFG_FILE_NAME) ] if os.environ.get('IVXV_ADMIN_CONF'): CFG_PATHS += [ os.environ.get('IVXV_ADMIN_CONF'), os.path.join(os.environ.get('IVXV_ADMIN_CONF'), CFG_FILE_NAME) ] for FILE_PATH in CFG_PATHS: if os.path.isfile(FILE_PATH): CFG_FILES_USED.append(FILE_PATH) logging.config.fileConfig(FILE_PATH) CFG_PARSER.read(FILE_PATH) # check config files read if not CFG_FILES_USED: log = logging.getLogger(__name__) log.error( "IVXV collector admin utils config file %r not found in the search paths %s", CFG_FILE_NAME, CFG_PATHS, ) CONFIG = CFG_PARSER['DEFAULT'] def cfg_path(cfg_path_name, filename): """Generate full path for specified file.""" return os.path.join(CONFIG[cfg_path_name], filename) if __name__ == '__main__': log = logging.getLogger(__name__) log.info('Loading config file(s) %s succeeded', ', '.join((CFG_FILES_USED))) sys.exit() ================================================ FILE: collector-admin/ivxv_admin/config_validator/__init__.py ================================================ # IVXV Internet voting framework """ Validator for collector config files and voting lists. """ ================================================ FILE: collector-admin/ivxv_admin/config_validator/choices_list.py ================================================ # IVXV Internet voting framework """ Choices list validator. """ from schematics.exceptions import DataError from schematics.models import Model from schematics.types import DictType, StringType from .fields import ElectionIdType class ChoicesListSchema(Model): """Validating schema for choices list.""" election = ElectionIdType(required=True) choices = DictType(DictType(DictType(StringType))) def validate(self, partial=False, convert=True, app_data=None, **kwargs): """Validate model.""" super().validate(partial, convert, app_data, **kwargs) choices = [] for district_choices in self.choices.values(): for choice in district_choices.values(): for choice_id in choice.keys(): if choice_id in choices: raise DataError( {'choices': f'Duplicate choice ID: {choice_id}'}) choices.append(choice_id) ================================================ FILE: collector-admin/ivxv_admin/config_validator/districts_list.py ================================================ # IVXV Internet voting framework """ Districts list validator. """ from schematics.models import Model from schematics.types import DictType, ListType, ModelType, StringType from .fields import ElectionIdType class DistrictsListSchema(Model): """Validating schema for districts list.""" class DistrictSchema(Model): """Validating schema for district record config.""" name = StringType(required=True) parish = ListType(StringType, required=True) class RegionSchema(Model): """Validating schema for region record config.""" state = StringType() county = StringType() parish = StringType() election = ElectionIdType(required=True) districts = DictType(ModelType(DistrictSchema)) regions = DictType(ModelType(RegionSchema)) counties = DictType(ListType(StringType)) ================================================ FILE: collector-admin/ivxv_admin/config_validator/election_conf.py ================================================ # IVXV Internet voting framework """ Election config validator. """ # pylint: disable=no-self-use from schematics.exceptions import ValidationError from schematics.models import Model from schematics.types import ( BooleanType, DateTimeType, IntType, ListType, ModelType, StringType, URLType, DictType, ) from .fields import CertificateType, ElectionIdType, PublicKeyType from .schemas import ContainerSchema, OCSPSchema, TSPSchema, protocol_cfg class ElectionConfigSchema(Model): """Validating schema for election config.""" identifier = ElectionIdType(required=True) questions = ListType(ElectionIdType, min_size=1, required=True) class ElectionVerificationSchema(Model): """Validating schema for election verification config.""" count = IntType(required=True, min_value=0) minutes = IntType(required=True, min_value=0) latestonly = BooleanType(default=False) verification = ModelType(ElectionVerificationSchema, required=True) class ElectionVotingSchema(Model): """Validating schema for election voting config.""" ratelimitstart = IntType(default=0, min_value=0) ratelimitminutes = IntType(default=0, min_value=0) def validate_ratelimitminutes(self, data, value): """Validate rate limit.""" try: if (data['ratelimitstart'] > 0 and data['ratelimitminutes'] == 0): raise ValidationError( 'ratelimitstart set, but rate limiting disabled') except KeyError: pass # error in data structure is catched later return value voting = ModelType(ElectionVotingSchema) class ElectionPeriodSchema(Model): """Validating schema for election period config.""" servicestart = DateTimeType(required=True) electionstart = DateTimeType(required=True) electionstop = DateTimeType(required=True) servicestop = DateTimeType(required=True) verificationstop = DateTimeType(required=True) period = ModelType(ElectionPeriodSchema, required=True) voterforeignehak = StringType(regex=r'^[0-9]{1,10}$') ignorevoterlist = StringType() class VoterListSchema(Model): """Validating schema for voter list updating service config.""" key = PublicKeyType(required=True) voterlist = ModelType(VoterListSchema, required=True) class VisSchema(Model): """Validating schema for VIS service config.""" url = URLType(required=True) ca = ListType(CertificateType) min = IntType(default=15) vis = ModelType(VisSchema, required=True) class XroadSchema(Model): """Validating schema for VIS service config.""" ca = CertificateType(required=True) xroad = ModelType(XroadSchema, required=True) class BallotSchema(Model): """Validating schema for voter ballot.""" encpkeygroup = StringType(required=True) # See available types in docs # PublicKeyType (OpenSSL library under the hood) no support for ElGamal encpkey = StringType(required=False) ballot = ModelType(BallotSchema, required=True) class AuthSchema(Model): """Validating schema for voter authentication config.""" # FIXME: If service.mid exists, auth.ticket field must exist class TicketAuthSchema(Model): """Validating schema for ticket authentication config.""" ticket = ModelType(TicketAuthSchema) class TLSAuthSchema(Model): """Validating schema for TLS authentication config.""" roots = ListType(CertificateType, required=True) intermediates = ListType(CertificateType) ocsp = ModelType(OCSPSchema) tls = ModelType(TLSAuthSchema) auth = ModelType(AuthSchema, required=True) identity = StringType( required=True, choices=['commonname', 'serialnumber', 'pnoee']) class AgeSchema(Model): """Validating schema for voters age check config.""" method = StringType(required=True, choices=['estpic']) timezone = StringType(required=True) limit = IntType(required=True, min_value=14) age = ModelType(AgeSchema) vote = ModelType(ContainerSchema, required=True) class MIDSchema(Model): """Validating schema for Mobile ID config.""" url = URLType(required=True) relyingpartyuuid = StringType(required=True) relyingpartyname = StringType(required=True) language = StringType( required=True, choices=['EST', 'ENG', 'RUS', 'LIT']) authmessage = StringType(required=True, max_length=40) signmessage = StringType(required=True, max_length=40) messageformat = StringType(default='GSM-7', choices=['GSM-7', 'UCS-2']) authchallengesize = IntType(default=32, choices=[32, 48, 64]) statustimeoutms = IntType() roots = ListType(CertificateType, required=True) intermediates = ListType(CertificateType) ocsp = ModelType(OCSPSchema) # pylint: disable=no-self-use def validate_phonerequired(self, data, value): """Validate phone/idcode required field.""" try: if not data['idcoderequired'] and not data['phonerequired']: raise ValidationError('Either idcoderequired or ' 'phonerequired must be true') except KeyError: pass # error in data structure is catched later return value mid = ModelType(MIDSchema) class SmartIDSchema(Model): """Validating schema for Smart ID config.""" url = URLType(required=True) relyingpartyuuid = StringType(required=True) relyingpartyname = StringType(required=True) certificatelevel = StringType( required=True, choices=["QUALIFIED", "ADVANCED", "QSCD"] ) authinteractionsorder = ListType(DictType(StringType), required=True) signinteractionsorder = ListType(DictType(StringType), required=True) authchallengesize = IntType() statustimeoutms = IntType() roots = ListType(CertificateType, required=True) intermediates = ListType(CertificateType) ocsp = ModelType(OCSPSchema) smartid = ModelType(SmartIDSchema) qualification = ListType( protocol_cfg({ "ocsp": OCSPSchema, "ocsptm": OCSPSchema, "tsp": TSPSchema, "tspreg": TSPSchema, })) class StatsSchema(Model): """Validating schema for stats config.""" class DetailStatsSchema(Model): class SchedulerSchema(Model): class CronSchema(Model): min = StringType(required=False) hour = StringType(required=False) day = StringType(required=False) month = StringType(required=False) weekday = StringType(required=False) cron = ModelType(CronSchema, required=False, default={}) scheduler = ModelType(SchedulerSchema, required=False, default={}) detail = ModelType(DetailStatsSchema, required=False, default={}) class VotingFactsSchema(Model): class SchedulerSchema(Model): class CronSchema(Model): min = StringType(required=False) hour = StringType(required=False) day = StringType(required=False) month = StringType(required=False) weekday = StringType(required=False) cron = ModelType(CronSchema, required=False, default={}) scheduler = ModelType(SchedulerSchema, required=False, default={}) voting_facts = ModelType(VotingFactsSchema, required=False, default={}) stats = ModelType(StatsSchema, required=False, default={}) # pylint: disable=unused-argument def validate_questions(self, data, value): """Validate question field.""" if value and len(value) > len(set(value)): raise ValidationError('Election questions must be unique') return value def validate_period(self, data, value): """Validate election period.""" try: if data['period']['servicestart'] >= data['period']['electionstart']: raise ValidationError("servicestart is >= than electionstart") if data['period']['electionstart'] >= data['period']['electionstop']: raise ValidationError("electionstart is >= than electionstop") if data['period']['electionstop'] > data['period']['servicestop']: raise ValidationError("electionstop is > than servicestop") if data['period']['servicestop'] > data['period']['verificationstop']: raise ValidationError("servicestop is > than verificationstop") except KeyError: pass # error in data structure is catched later return value ================================================ FILE: collector-admin/ivxv_admin/config_validator/fields.py ================================================ # IVXV Internet voting framework """ Common field validator classes. """ # pylint: disable=too-few-public-methods import string import OpenSSL from schematics.exceptions import ValidationError from schematics.types import StringType class ElectionIdType(StringType): """Election ID field validator.""" def validate(self, value, context=None): """Validate field.""" min_length = 1 max_length = 28 if len(value) < min_length or len(value) > max_length: raise ValidationError( f"Election ID length must be between {min_length} and {max_length}" ) if any(ws in value for ws in list(string.whitespace)): raise ValidationError('Election ID contains whitespace') return super().validate(value, context) class CertificateType(StringType): """A field that validates input as a PEM-encoded certificate.""" def validate(self, value, context=None): """Validate field.""" try: OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, value) except OpenSSL.crypto.Error as err: err_lib, err_func, err_reason = err.args[0][0] raise ValidationError( f"Error in {err_lib} library {err_func} function: {err_reason}" ) return super().validate(value, context) class PublicKeyType(StringType): """A field that validates input as a PEM-encoded public key.""" def validate(self, value, context=None): """Validate field.""" try: OpenSSL.crypto.load_publickey(OpenSSL.crypto.FILETYPE_PEM, value) except OpenSSL.crypto.Error as err: err_lib, err_func, err_reason = err.args[0][0] raise ValidationError( f"Error in {err_lib} library {err_func} function: {err_reason}" ) return super().validate(value, context) ================================================ FILE: collector-admin/ivxv_admin/config_validator/schemas.py ================================================ # IVXV Internet voting framework """ Common schema validator classes. """ from schematics.exceptions import ValidationError from schematics.models import Model from schematics.types import (IntType, ListType, ModelType, PolyModelType, StringType, URLType) from .fields import CertificateType # FIXME: constrainments on schemas passed to wrapper aren't enforced. # fields can be missing from the conf, type constrainments are ignored, # without raising any errors (e.g missing storage.conf.ca, # invalid URL in qualification.*.url) def protocol_cfg(mapping, **kwargs): """ Return an alternative protocol configuration type. Alternative protocol configurations allow only one from a selection of alternatives to be used. The model looks like this:: protocol: conf: schematics has PolyModelType which allows "conf" to be different models, but it must select the model to use based solely on the contents of "conf", which cannot be done with this construction. So create a new wrapper model for each protocol configuration model which also includes the "protocol" field and let PolyModelType choose from those. """ models = [] for protocol, model in mapping.items(): wrapper = type( f"{model.__name__}Wrapper", (Model, ), { "protocol": StringType(required=True, choices=[protocol]), "conf": ModelType(model, required=True), "ordertimeout": IntType(required=False, min_value=1) }) mapping[protocol] = wrapper models.append(wrapper) def _claim(_, data): return mapping.get(data.get("protocol")) return PolyModelType(models, claim_function=_claim, **kwargs) class DummySchema(Model): """Validating schema for Dummy container config.""" trusted = ListType(StringType) class OCSPSchema(Model): """Validating schema for OCSP config.""" url = URLType(required=True) responders = ListType(CertificateType) retry = IntType(default=0, min_value=0) maxSkew = IntType(default=300, min_value=0) # 300 milliseconds maxAge = IntType(default=1, min_value=0) # 1 minute maxAge = IntType(default=1, min_value=0) # 1 minute class OCSPSchemaNoURL(Model): """Validating schema for OCSP config.""" responders = ListType(CertificateType) maxSkew = IntType(default=300, min_value=0) # 300 milliseconds maxAge = IntType(default=1, min_value=0) # 1 minute class TSPSchema(Model): """Validating schema for timestamp protocol config.""" url = URLType(required=True) signers = ListType(CertificateType, required=True) delaytime = IntType(required=True, min_value=0) retry = IntType(default=0, min_value=0) maxSkew = IntType(default=2, min_value=0) # 2 seconds maxAge = IntType(default=1, min_value=0) # 1 minute class TSPSchemaNoURL(Model): """Validating schema for timestamp protocol config.""" signers = ListType(CertificateType, required=True) delaytime = IntType(required=True, min_value=0) maxSkew = IntType(default=2, min_value=0) # 2 seconds maxAge = IntType(default=1, min_value=0) # 1 minute class BDocSchema(Model): """Validating schema for BDoc config.""" filecount = IntType(required=True, min_value=1) bdocsize = IntType(required=True, min_value=1) filesize = IntType(required=True, min_value=1) roots = ListType(CertificateType, required=True) intermediates = ListType(CertificateType) profile = StringType(choices=['BES', 'TM', 'TS'], required=True) ocsp = ModelType(OCSPSchemaNoURL) tsp = ModelType(TSPSchemaNoURL) tsdelaytime = IntType(default=0, min_value=0) def validate_tsp(self, data, value): """Check that tsp exists if profile is TS.""" try: if (data['profile'] == 'TS' and not data['tsp']): raise ValidationError('TS profile requires a tsp block') except KeyError: pass # error in data structure is catched later return value class ContainerSchema(Model): """Validating schema for signed container config.""" bdoc = ModelType(BDocSchema) dummy = ModelType(DummySchema) ================================================ FILE: collector-admin/ivxv_admin/config_validator/tech_conf.py ================================================ # IVXV Internet voting framework """ Collector technical config validator. """ import re from schematics.exceptions import ValidationError from schematics.models import Model from schematics.types import (BooleanType, IntType, ListType, ModelType, StringType) from .fields import CertificateType from .schemas import protocol_cfg class ServicesSchema(Model): """Validating schema for subservices config.""" class BackupServiceSchema(Model): """Validating schema for backup subservice config.""" id = StringType(regex=r'.+@.+', required=True) address = StringType(required=True) class ServiceSchema(Model): """Validating schema for subservice config.""" id = StringType(regex=r'.+@.+', required=True) address = StringType(regex=r'.+:[0-9]+', required=True) peeraddress = StringType(regex=r'.+:[0-9]+') origin = StringType(regex=r'.+:[0-9]+') proxy = ListType(ModelType(ServiceSchema)) mid = ListType(ModelType(ServiceSchema)) smartid = ListType(ModelType(ServiceSchema)) webeid = ListType(ModelType(ServiceSchema)) votesorder = ListType(ModelType(ServiceSchema)) voting = ListType(ModelType(ServiceSchema)) choices = ListType(ModelType(ServiceSchema)) verification = ListType(ModelType(ServiceSchema)) sessionstatus = ListType(ModelType(ServiceSchema)) storage = ListType(ModelType(ServiceSchema)) log = ListType(ModelType(ServiceSchema)) backup = ListType(ModelType(BackupServiceSchema), max_size=1) class CollectorTechnicalConfigSchema(Model): """Validating schema for collector technical config.""" debug = BooleanType(default=False) snidomain = StringType(required=True) class FilterSchema(Model): """Validating schema for connection filter config.""" class TLSFilterSchema(Model): """Validating schema for TLS connection filter config.""" handshaketimeout = IntType(required=True, min_value=0) ciphersuites = ListType( StringType(choices=[ 'TLS_RSA_WITH_AES_128_CBC_SHA', 'TLS_RSA_WITH_AES_256_CBC_SHA', 'TLS_RSA_WITH_AES_128_GCM_SHA256', 'TLS_RSA_WITH_AES_256_GCM_SHA384', 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA', 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA', 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA', 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA', 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256', 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256', 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384', 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384', ]), required=True) tls = ModelType(TLSFilterSchema, required=True) class CodecFilterSchema(Model): """Validating schema for codec connection filter config.""" rwtimeout = IntType(required=True, min_value=0) requestsize = IntType(min_value=0) logrequests = BooleanType(default=False) codec = ModelType(CodecFilterSchema, required=True) filter = ModelType(FilterSchema, required=True) class SegmentSchema(Model): """Validating schema for network segment config.""" id = StringType(required=True) services = ModelType(ServicesSchema, required=True) network = ListType(ModelType(SegmentSchema), required=True) class LogServerSchema(Model): """Validating schema for log collecting server config.""" address = StringType(required=True) port = IntType(default=20514) logging = ListType(ModelType(LogServerSchema)) class StatusServerSchema(Model): """Validating schema for status servers config.""" class SessionServiceSchema(Model): name = StringType(required=True) servername = StringType(required=True) authttl = IntType(required=True) choicettl = IntType(required=True) votettl = IntType(required=True) verifyttl = IntType(required=True) session = ModelType(SessionServiceSchema) status = ModelType(StatusServerSchema, required=True) class FileStorageServiceSchema(Model): """Validating schema for file storage service config.""" wd = StringType(required=True) class EtcdStorageServiceSchema(Model): """Validating schema for etcd storage service config.""" ca = CertificateType(required=True) conntimeout = IntType(required=True, min_value=0) optimeout = IntType(required=True, min_value=0) # FIXME: Compare to network.#.services.storage.#.id on first load. bootstrap = ListType(StringType(regex=r'.+@.+')) size = IntType(required=False) snapshotcount = IntType(required=False) heartbeattimeout = IntType(required=False) electiontimeout = IntType(required=False) storage = protocol_cfg( { "file": FileStorageServiceSchema, "etcd": EtcdStorageServiceSchema, }, required=True) class BackupTimeType(StringType): """Field validator for backup time.""" def validate(self, value, context=None): if not re.match(r'[0-9]{2}:[0-9]{2}', value): raise ValidationError(f"Value must be in format HH:MM (not {value!r})") hour, minute = value.split(':') if int(hour) >= 24: raise ValidationError(f"Hour must be smaller than 24 (not {value!r})") if int(minute) >= 60: raise ValidationError(f"Minute must be smaller than 60 (not {value!r})") return super().validate(value, context) backup = ListType(BackupTimeType) ================================================ FILE: collector-admin/ivxv_admin/config_validator/trust_conf.py ================================================ # IVXV Internet voting framework """ Collector trust root config validator. """ from schematics.models import Model from schematics.types import ListType, ModelType, StringType from .schemas import ContainerSchema class TrustRootSchema(Model): """Validating schema for trust root config.""" container = ModelType(ContainerSchema, required=True) authorizations = ListType(StringType, required=True) ================================================ FILE: collector-admin/ivxv_admin/config_validator/user_management.py ================================================ # IVXV Internet voting framework """ Collector user management command validator. """ from schematics.exceptions import DataError from schematics.models import Model from schematics.types import ListType, StringType from .. import USER_ROLES class UserManagementCommandSchema(Model): """Validating schema for user management command.""" action = StringType(required=True, regex='user-permissions') cn = StringType(required=True, regex='.+,.+,[0-9]{11}') roles = ListType(StringType(), required=True) def validate(self, partial=False, convert=True, app_data=None, **kwargs): """Validate model.""" super().validate(partial, convert, app_data, **kwargs) # role list checks if not isinstance(self.roles, list): raise DataError({'roles': 'Value is not a list'}) # pylint: disable=not-an-iterable for role in self.roles: if role not in USER_ROLES: raise DataError({"roles": f"Unknown role {role!r}"}) if len(self.roles) != len(set(self.roles)): raise DataError({'roles': 'Duplicate roles'}) # pylint: disable=unsupported-membership-test if 'none' in self.roles and len(self.roles) > 1: raise DataError({ 'roles': 'Role "none" can\'t be used with other roles' }) ================================================ FILE: collector-admin/ivxv_admin/config_validator/validator_util.py ================================================ # IVXV Internet voting framework """Config validator utility for collector config files and voting lists.""" import json import os import jsonschema import pkg_resources from .choices_list import ChoicesListSchema from .districts_list import DistrictsListSchema from .election_conf import ElectionConfigSchema from .tech_conf import CollectorTechnicalConfigSchema from .trust_conf import TrustRootSchema from .user_management import UserManagementCommandSchema from .voters_list import VoterListChangesetSkipSchema, parse_voters_list def validate_cfg(cfg, schema_name): """Validate collector config. :param cfg: Configuration data structure :type cfg: dict :raises ValueError: :raises schematics.exceptions.DataError: """ # validate choices and districts list with jsonschema if schema_name in ['choices', 'districts']: jsonschema_src = pkg_resources.resource_string( 'ivxv_admin', os.path.join('jsonschema', f'ivxv.{schema_name}.schema')) schema = json.loads(jsonschema_src.decode('UTF-8')) try: jsonschema.validate(instance=cfg, schema=schema) except jsonschema.exceptions.ValidationError as err: raise ValueError(err) # validate voters list if schema_name == "voters" and isinstance(cfg, str): return parse_voters_list(cfg) if not isinstance(cfg, dict): raise ValueError('Configuration data is not dictionary') # detect config schema schemas = { 'trust': TrustRootSchema, 'technical': CollectorTechnicalConfigSchema, 'election': ElectionConfigSchema, 'choices': ChoicesListSchema, 'districts': DistrictsListSchema, 'user': UserManagementCommandSchema, "voters": VoterListChangesetSkipSchema, } validator = schemas[schema_name](cfg.copy()) validator.validate() return validator.to_primitive() ================================================ FILE: collector-admin/ivxv_admin/config_validator/voters_list.py ================================================ # IVXV Internet voting framework """Voters list validator.""" import re import dateutil.parser from schematics.models import Model from schematics.types import IntType, StringType from .fields import ElectionIdType ISOPARSER = dateutil.parser.isoparser("T") class VoterListChangesetSkipSchema(Model): """Validating schema for voter list changeset skipping command.""" election = ElectionIdType(required=True) skip_voter_list = StringType(regex=r"^[^ ]+ [^ ]+$", required=True) changeset = IntType(required=True) def parse_voters_list(list_content): """Parse voters list. :return: Voters list data :rtype: dict :raises ValueError: """ lines = list_content.split('\n') if len(lines) < 4: raise ValueError(f'Too few lines in voters list ({len(lines)})') # parse header data = dict(version=lines[0].rstrip('\r')) data['election'] = lines[1].rstrip('\r') try: data['election'].encode('ASCII') except UnicodeEncodeError: raise ValueError('Election ID contains non-ASCII characters') data['changeset'] = lines[2].rstrip('\r') data['period'] = lines[3].rstrip('\r') timestamps = data['period'].split('\t') if len(timestamps) != 2: raise ValueError('Period does not contain two tab-separated fields') data['period_from'] = timestamps[0] data['period_to'] = timestamps[1].rstrip('\r') # validate header # version-no = "2" if data["version"] != "2": raise ValueError( f"Invalid voters list version {data['version']!r} in line 1. " "Expected value: 2" ) ElectionIdType(required=True).validate(data['election']) # changeset = integer if not data['changeset'].isdigit(): raise ValueError( f"Unknown voters list changeset {data['changeset']!r} in line 3. " "Must be an integer" ) # period_from, period_to = RFC 3339 timestamp try: # FIXME: Accepts all ISO 8601 timestamps, not only RFC 3339. ISOPARSER.isoparse(data['period_from']) ISOPARSER.isoparse(data['period_to']) except ValueError as err: raise ValueError(f'Period contains invalid timestamp: {err.args[0]}') # parse list is_original_list = data['changeset'] == '0' data['voters'] = [] for line_no, line in enumerate(lines[:-1], 1): if '\r' in line: raise ValueError(f'Line #{line_no}: Invalid character ') if line_no < 5: continue fields = line.split('\t') try: validate_voter_record(fields, is_original_list) except ValueError as err: raise ValueError(f'Line #{line_no}: {err.args[0]}') data['voters'].append(fields) if lines[-1] != '': raise ValueError(f'Line #{len(lines)}: Must end with character') return data def validate_voter_record(fields, is_original_list): """Validate voter record in voters list.""" # field count if len(fields) == 5: action, voter_personalcode, voter_name, adminunit_code, no_district = fields if not voter_name: raise ValueError("voter-name is empty") if action != "lisamine": raise ValueError( f"Unknown action {action!r}. Must be 'lisamine' or 'kustutamine'" ) # voter-personalcode = 11DIGIT if not re.match(r"[0-9]{11}$", voter_personalcode): raise ValueError(f"Invalid voter-personalcode {voter_personalcode!r}") if len(voter_name) > 100: raise ValueError(f"voter-name lenght {len(voter_name)} exceeds 100 chars") # adminunit-code = 1*4UTF-8-CHAR | "FOREIGN" if not adminunit_code: raise ValueError("Missing adminunit-code") if len(adminunit_code) > 4 and adminunit_code != "FOREIGN": raise ValueError( f"adminunit-code {adminunit_code!r} is longer than 4 chars") # no-district = 1*10DIGIT if not re.match(r"[0-9]{1,10}$", no_district): raise ValueError(f"Invalid no-district {no_district!r}") elif len(fields) == 2: action, voter_personalcode = fields if action != "kustutamine": raise ValueError( f"Unknown action {action!r}. Must be 'lisamine' or 'kustutamine'" ) # voter-personalcode = 11DIGIT if not re.match(r"[0-9]{11}$", voter_personalcode): raise ValueError(f"Invalid voter-personalcode {voter_personalcode!r}") if is_original_list: raise ValueError(f"Action {action!r} is not allowed in initial list") else: raise ValueError(f"Invalid field count {len(fields)}, expected 2 or 5 fields") ================================================ FILE: collector-admin/ivxv_admin/db.py ================================================ # IVXV Internet voting framework """ Database abstraction layer for collector management service. """ import datetime import dbm.gnu import logging import os import re import time import dateutil.parser from . import (COLLECTOR_STATE_NOT_INSTALLED, COLLECTOR_STATES, RFC3339_DATE_FORMAT, SERVICE_STATE_NOT_INSTALLED, SERVICE_STATES) from .config import CONFIG #: Path to database file DB_FILE_PATH = CONFIG['ivxv_db_file_path'] #: Database keys with default values DB_KEYS = { # collector state 'collector/state': COLLECTOR_STATE_NOT_INSTALLED, # election config file version in management service 'config/election': '', # technical config file version in management service 'config/technical': '', # trust root config file version in management service 'config/trust': '', # logmonitor address 'logmonitor/address': '', # logmonitor timestamp of last fetch 'logmonitor/last-data': '', # choices list file version in management service 'list/choices': '', # choices list file version in choices service 'list/choices-loaded': '', # districts list file version in management service 'list/districts': '', # districts list file version in choices service 'list/districts-loaded': '', # election ID 'election/election-id': '', # election start time 'election/electionstart': '', # election stop time 'election/electionstop': '', # collector service start time 'election/servicestart': '', # collector service stop time 'election/servicestop': '', # verification service stop time 'election/verificationstop': '', } #: Database keys for service hosts with default values DB_HOST_SUBKEYS = { # host state 'state': '', } #: Database keys for services with default values DB_SERVICE_SUBKEYS = { # service type 'service-type': None, # technical config file version in service 'technical-conf-version': '', # election config file version in service 'election-conf-version': '', # service network ID 'network': None, # service state 'state': SERVICE_STATE_NOT_INSTALLED, # last data by service PING (timestamp) 'last-data': '', # count of ping errors 'ping-errors': '0', # service IP address 'ip-address': None, # registered background information (usually error message) 'bg_info': '', } #: Database keys for certain service types DB_SERVICE_CONDITIONAL_SUBKEYS = { # mobile ID identity token key file checksum (sha256) 'mid-token-key': '', # TLS certificate file checksum (sha256) 'tls-cert': '', # TLS key file checksum (sha256) 'tls-key': '', # TSP registration key file checksum (sha256) 'tspreg-key': '', # automatic backup times for backup service 'backup-times': '', } #: Full list of allowed database keys ALLOWED_SERVICE_KEYS = ( list(DB_SERVICE_SUBKEYS) + list(DB_SERVICE_CONDITIONAL_SUBKEYS)) # create logger log = logging.getLogger(__name__) class IVXVManagerDb: """ Management service database abstraction class. Based on :py:mod:`dbm.gnu` module. """ db = None #: Database object. read_only = None #: Database access mode. _retries = None #: Retry count for failed database open. _retry_delay = None #: Delay between retries. _db_mode = None #: Mode string for :py:func:`dbm.open`. def __init__(self, for_update=False, retries=30, retry_delay=0.1): """ Constructor. :param for_update: Open database for update :type for_update: bool :param retries: Retries before giving up :type retries: int :param retry_delay: Pause between retries (in seconds) :type retry_delay: float """ self.read_only = not for_update self._db_mode = 'ws' if for_update else 'r' self._retries = retries self._retry_delay = retry_delay def __enter__(self, mode=None): """Enter the runtime context, open database.""" mode = mode or self._db_mode log.debug("Opening management database %r (mode: %s)", DB_FILE_PATH, mode) retries = self._retries if mode != 'n' and not os.path.exists(DB_FILE_PATH): log.error("Database file %r not found", DB_FILE_PATH) raise FileNotFoundError() db_error = OSError() while retries > 0: try: self.db = dbm.gnu.open(DB_FILE_PATH, mode) break except OSError as err: if err.errno == 11: # database is locked log.debug('Database is locked, retrying') else: log.debug("Can't open database, retrying (%s)", err) db_error = err retries -= 1 time.sleep(self._retry_delay) else: log.error('Error while opening management database: %s', db_error) raise db_error return self def __exit__(self, *args): """Exit the runtime context, close database.""" log.debug('Closing management database') self.db.close() def get_value(self, key): """Get value from database.""" return self.db[key].decode('UTF-8') def set_value(self, key, value, safe=False): """Validate and set database value. :param key: Key name :type key: str :param value: Value to set :type value: str :param safe: Is operation safe or not. Safe operation will try to read old value before writing new one. :type safe: bool """ assert isinstance(key, str) # validate value if isinstance(value, datetime.datetime): value = value.strftime(RFC3339_DATE_FORMAT) assert isinstance(value, str), f"Invalid value type: {type(value)}" # set value if key in [ 'election/election-id', 'logmonitor/address', 'logmonitor/last-data', 'stats/detail/scheduler/cron', 'stats/voting_facts/scheduler/cron', ]: pass elif key == 'collector/state': assert value in COLLECTOR_STATES, f"Invalid value for {key!r}: {value!r}" elif re.match('election/(election|service|verification)(start|stop)$', key): assert not value or dateutil.parser.parse(value) elif (re.match('election/auth/.+$', key) or key == 'election/tsp-qualification'): assert value == 'TRUE' elif key in DB_KEYS or key == "list/voters0000": if value != '': assert value.count(" ") == 1, f"Invalid value {value!r}" cn, timestamp = value.split(' ') assert re.match(r'^(.+,){2}\d{11}$', cn) dateutil.parser.parse(timestamp) elif re.match(r"list/voters[0-9]{4}$", key): assert value assert value.count(" ") == 1, f"Invalid value {value!r}" url_or_signature, timestamp = value.split(" ") dateutil.parser.parse(timestamp) elif re.match(r"list/voters[0-9]{4}-state$", key): assert value in ["PENDING", "APPLIED", "INVALID", "SKIPPED"] elif re.match(r'host/.+/.+$', key): key_type = key.split('/')[2] assert key_type in DB_HOST_SUBKEYS, f"Invalid host key type {key_type}" elif re.match(r'service/.+/.+$', key): key_type = key.split('/')[2] assert ( key_type in ALLOWED_SERVICE_KEYS ), f"Invalid service key type {key_type}" if key_type == 'state': assert value in SERVICE_STATES, f"Invalid value for {key!r}: {value!r}" elif key_type == 'backup-times': assert value == "" or re.match( r"[0-9]{2}:[0-9]{2}( [0-9]{2}:[0-9]{2})*$", value ), f"Invalid value for {key!r}: {value!r}" elif re.match(r'user/.+$', key): assert re.match(r'user/(.+,){2}\d{11}$', key), ( f"Invalid user CN {key.split('/')[1]!r}") else: raise KeyError(f"Invalid database field name {key!r}") # Safe operation reads value before writing it. # This is to avoid unneeded values after database initialization (e.g. # agent daemon may try to update service data in background). if safe: self.db[key] log.debug("Setting value %r = %r", key, value) self.db[key] = value def rm_value(self, key): """Remove database record.""" assert isinstance(key, str) log.debug("Removing record %r", key) del self.db[key] def get_all_values(self, section=None): """ Get all database values as a dictionary. :param section: Config section to get :type section: string :return: dict """ values = {} for key in sorted(self.keys()): path = key.split('/') # len(path) == 4 is for stats/detail/scheduler/cron # or stats/voting_facts/scheduler/cron assert len(path) in (2, 3, 4) if path[0] not in values: values[path[0]] = {} if len(path) == 2: values[path[0]][path[1]] = self.get_value(key) or None else: if path[1] not in values[path[0]]: values[path[0]][path[1]] = {} values[path[0]][path[1]][path[2]] = self.get_value(key) or None return values.get(section, {}) if section else values @classmethod def reset(cls): """Reset database.""" log.info("Initializing management database %r", DB_FILE_PATH) db = cls() db.__enter__(mode='n') # write default values for key, value in sorted(DB_KEYS.items()): db.set_value(key, value) db.__exit__() def dump(self, filter_keys=None): """ Dump database to stdout. :param filter_keys: Limit dump with specified values :type filter_keys: list """ for key in self.keys(): if not filter_keys or key in filter_keys: print(f'{key}: {self.get_value(key)}') def keys(self): """Return all database keys in sorted order.""" return [key.decode('UTF-8') for key in sorted(self.db.keys())] def check_db_dir(): """ Check database directory exist or not. :return: Database file directory path or None if path does not exist. :rtype: str """ db_file_path = CONFIG['ivxv_db_file_path'] db_path = os.path.dirname(db_file_path) if os.path.exists(db_path): return db_file_path log.error('Database directory %r does not exist', db_path) return None ================================================ FILE: collector-admin/ivxv_admin/event_log.py ================================================ # IVXV Internet voting framework """Event logging for Collector Management service.""" import datetime import json import os from . import EVENT_LOG_FILENAME, EVENTS, RFC3339_DATE_FORMAT from .cli_utils import init_cli_util from .config import cfg_path EVENT_LOG_FILEPATH = cfg_path('ivxv_admin_data_path', EVENT_LOG_FILENAME) def init_event_log(): """Initialize Management Service event log.""" try: os.unlink(EVENT_LOG_FILEPATH) except FileNotFoundError: pass register_service_event('COLLECTOR_INIT') def register_service_event(event, level='INFO', service=None, params=None): """Register Management Service event in event log file.""" params = params or {} assert level in ['INFO', 'ERROR'] log_event = { 'event': event, 'level': level, 'message': EVENTS[event].format(**params), 'service': service or 'management', 'timestamp': datetime.datetime.now().strftime(RFC3339_DATE_FORMAT), } with open(EVENT_LOG_FILEPATH, 'a') as fp: json.dump(log_event, fp, sort_keys=True) fp.write('\n') def event_log_dump_util(): """Dump collector management event log.""" init_cli_util( """ Dump IVXV Collector Management event log in human readable format. Usage: ivxv-eventlog-dump """, allow_root=True) with open(EVENT_LOG_FILEPATH) as fp: while True: line = fp.readline() if not line: break event = json.loads(line) print( '{timestamp} {level} {service} {event} {message}' .format(**event)) ================================================ FILE: collector-admin/ivxv_admin/http_daemon.py ================================================ # IVXV Internet voting framework """ Management daemon for collector management service. This daemon is based on :py:mod:`bottle` module and listens as web service. """ import datetime import json import logging import os import subprocess from bottle import get, post, request, response, route, run from . import MANAGEMENT_DAEMON_PORT from .config import cfg_path # create logger log = logging.getLogger(__name__) @route('/') def index(): """ Index page method. :return: Service identification message. """ return 'This is a web server for IVXV Collector Management Service!' @post('/upload-command') def upload_cmd_file(): """Upload command file.""" filename = request.forms.get('filename') original_filename = request.forms.get('original_filename') cmd_type = request.forms.get('cmd_type') file_path = cfg_path('file_upload_path', filename) log.info("Uploading command file %r (type: %s)", filename, cmd_type) # execute command loading utility cmd = ['ivxv-cmd-load', '--autoapply', cmd_type, file_path] log.info('Executing command: %s', ' '.join(cmd)) proc = subprocess.run( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False ) log.info('Command finished with exit code %d', proc.returncode) # report upload result body = { 'success': bool(proc.returncode == 0), 'log': proc.stdout.decode('utf-8').split('\n'), } if proc.returncode: # error body["message"] = f"Viga faili {original_filename!r} üleslaadimisel" else: # command loaded body["message"] = f"Fail {original_filename!r} on edukalt üles laaditud" # start response response.content_type = 'application/json' return json.dumps(body) @get('/download-ballot-box') @get('/download-consolidated-ballot-box') def download_ballots(): """Export votes into ballot box folder.""" timestamp = '{:%Y.%m.%d_%H.%M}'.format(datetime.datetime.now()) # prepare command cmd = ['ivxv-export-votes'] if 'download-consolidated-ballot-box' in request.url: cmd.append('--consolidate') filename = f'exported-votes-consolidated-{timestamp}.zip' else: filename = f'exported-votes-{timestamp}.zip' path = cfg_path('exported_votes_path', filename) cmd.append(path) cmd_str = ' '.join(cmd) logfile_path = cfg_path( 'exported_votes_path', filename.replace('.zip', '.log')) cmd = [ 'sh', '-e', '-c', f'( {cmd_str} && chmod 664 {path} ) > {logfile_path}' ] subprocess.Popen(cmd) # start response response.content_type = 'application/json' return json.dumps('OK') @get("/download-voter-detail-stats") def download_voter_stats(): """Download voter stats.""" # import detail stats from Collector, don't export to VIS cmd = ["ivxv-voterstats", "detail", "--action=import"] log.info("Executing command: %s", " ".join(cmd)) proc = subprocess.run( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False ) log.info("Command finished with exit code %d", proc.returncode) # report result if proc.returncode: # error body = { "success": True, "log": proc.stdout.decode("utf-8").split("\n"), "message": "Viga statistika hankimisel", } else: # success with open("/var/lib/ivxv/admin-ui-data/voterstats-detail.json") as fd: body = json.load(fd) # start response response.content_type = 'application/json' return json.dumps(body) @get("/download-processor-input") def download_processor_input(): """Download processor input.""" timestamp = "{:%Y.%m.%d_%H.%M}".format(datetime.datetime.now()) filename = f"processor-cfg-{timestamp}.zip" output_filepath = f"/var/lib/ivxv/admin-ui-data/{filename}" try: os.unlink(output_filepath) except FileNotFoundError: pass cmd = ["ivxv-generate-processor-input", output_filepath] log.info("Executing command: %s", " ".join(cmd)) proc = subprocess.run( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False ) log.info("Command finished with exit code %d", proc.returncode) # report result if proc.returncode: # error body = { "success": True, "log": proc.stdout.decode("utf-8").split("\n"), "message": "Viga töötlemisrakenduse sisendi aluse genereerimisel", } response.content_type = 'application/json' return json.dumps(body) # success with open(output_filepath, "rb") as fd: body = fd.read() response.content_type = "application/zip" response.set_header("Content-Disposition", f'attachment; filename="{filename}"') return body @get("/download-voting-sessions") def download_voting_sessions(): """Download voting sessions.""" cmd = ["ivxv-voting-sessions"] filename = "voting-sessions" if request.forms.get("verifications"): cmd.append("verify") filename += "-with-verifications" else: cmd.append("vote") if request.forms.get("anonymize"): cmd.append("--anonymize") filename += "-anonymized" if request.forms.get("uniq"): cmd.append("--uniq") filename += "-uniq" filename += "-{:%Y.%m.%d_%H.%M}.csv".format(datetime.datetime.now()) # timestamp filepath = f"/var/lib/ivxv/admin-ui-data/{filename}" cmd.append(filepath) log.info("Executing command: %s", " ".join(cmd)) proc = subprocess.run( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False ) if proc.returncode: # error body = { "success": False, "log": proc.stdout.decode("utf-8").split("\n"), "message": "Viga hääletamise seansside hankimisel", } response.content_type = "application/json" return json.dumps(body) # success log.info("Command finished with exit code %d", proc.returncode) response.content_type = "text/csv" response.set_header("Content-Disposition", f'attachment; filename="{filename}"') with open(filepath) as fd: return fd.read() @get('/skip-voters-list') def skip_voters_lists(): """Remove loaded but unapplied voters lists""" cmd = ["ivxv-voter-list-skip"] log.info('Executing command: %s', ' '.join(cmd)) proc = subprocess.run( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=False ) log.info('Command finished with exit code %d', proc.returncode) # report result body = { 'success': bool(proc.returncode == 0), 'log': proc.stdout.decode('utf-8').split('\n'), } if proc.returncode: # error body["message"] = "Viga nimekirja märkimisel vahelejätmiseks" else: # command loaded body["message"] = "Nimekiri on märgitud vahelejätmiseks" # start response response.content_type = 'application/json' return json.dumps(body) def daemon(): """Daemon main loop.""" log.info('Starting Management daemon') run(host='localhost', port=MANAGEMENT_DAEMON_PORT) ================================================ FILE: collector-admin/ivxv_admin/lib/__init__.py ================================================ # IVXV Internet voting framework """Library for collector management service.""" import datetime import json import logging import os import shutil from .. import ( CFG_TYPES, RFC3339_DATE_FORMAT_WO_FRACT, SERVICE_STATE_REMOVED, SERVICE_TYPE_PARAMS, VOTING_LIST_TYPES, ) from ..collector_state import generate_collector_state from ..config import CONFIG, cfg_path from ..db import DB_SERVICE_SUBKEYS, IVXVManagerDb from ..event_log import register_service_event from ..service import generate_service_list from ..service.service import Service # create logger log = logging.getLogger('lib') class IvxvError(Exception): """IVXV exception class.""" def register_tech_cfg_items(cfg, cfg_version): """Register technical config items in management database. Create database records for service hosts and services if not created and register removed services. :param cfg: Technical config :param cfg_version: Config version """ with IVXVManagerDb(for_update=True) as db: register_removed_services(db, cfg, cfg_version) gen_service_record_defaults(db, cfg) gen_host_record_defaults(db, cfg) gen_logmon_data(db, cfg.get('logging')) def register_removed_services(db, cfg, cfg_version): """Mark removed services in database with REMOVED state. Change state of removed services to REMOVED. :param db: Database handler :param cfg: Technical config """ existing_services = get_services(db=db) services_from_cfg = generate_service_list(cfg['network']) # find removed services existing_service_ids = set(existing_services.keys()) new_service_ids = set( new_service_cfg[1]['id'] for new_service_cfg in services_from_cfg) removed_service_ids = existing_service_ids.difference(new_service_ids) if not removed_service_ids: return # change loading states for choices, districts and voters lists # if all existing storage services are removed storages_removed = set( service_id for service_id, service_data in existing_services.items() if service_data['service-type'] == 'storage' and service_data['state'] != SERVICE_STATE_REMOVED) storages_added = set( new_service_cfg['id'] for service_type, new_service_cfg in services_from_cfg if service_type == 'storage') if not storages_removed.intersection(storages_added): # all storages removed log_msg = ( f'All existing storage service instances are removed with ' f'technical config {cfg_version}') log.warning(log_msg) reset_list_loading_state(db, "choices", "choices list", log_msg) reset_list_loading_state(db, "districts", "districts list", log_msg) for changeset_no in range(get_current_voter_list_changeset_no(db), -1, -1): reset_list_loading_state( db, f"voters{changeset_no:04d}", f"voter list #{changeset_no:04d}", log_msg, ) # change removed service states db_values = db.get_all_values()['service'] for service_id in sorted(removed_service_ids): log.info('Changing service %s state to REMOVED', service_id) with Service(service_id, db_values[service_id]) as service: service.register_state( db, SERVICE_STATE_REMOVED, bg_info=f'Service removed with technical config: {cfg_version}', ) def reset_list_loading_state(db, list_type, list_descr, log_msg): """Reset choices, districts and voters list loading state.""" # check if list is loaded list_version = db.get_value(f'list/{list_type}') if not list_version: return log_msgs = [log_msg] timestamp = datetime.datetime.now().strftime(RFC3339_DATE_FORMAT_WO_FRACT) # load list metadata file filepath = get_loaded_cfg_file_path(list_type) assert filepath, f"Config file for {list_descr} {list_version!r} does not exist" filepath = filepath.replace(os.path.splitext(filepath)[1], ".json") with open(filepath) as fp: cfg_state = json.load(fp) # set list state in management database log_msg = "" if list_type.startswith("voters"): # APPLIED -> PENDING for voters db_key = f"list/{list_type}-state" list_state = db.get_value(db_key) if list_state == "APPLIED": log_msg = f"Setting {list_descr} state from APPLIED to PENDING" db.set_value(db_key, "PENDING") else: # PENDING for choices/districts db_key = f"list/{list_type}-loaded" if db.get_value(db_key): log_msg = f"Setting {list_descr} state to PENDING" db.set_value(db_key, "") if log_msg: log.info(log_msg) log_msgs.append(log_msg) # write config metadata file log_msgs = [f'{timestamp} {log_msg}' for log_msg in log_msgs] cfg_state["log"] += [log_msgs] cfg_state["attempts"] = 0 cfg_state["completed"] = False tmp_filepath = f'{filepath}.tmp' with open(tmp_filepath, 'w') as fp: json.dump(cfg_state, fp) shutil.move(tmp_filepath, filepath) def gen_service_record_defaults(db, cfg): """Add database records for services with default values. Parse the list of services from technical config and create missing database records for every defined service. :param db: Database handler :param cfg: Technical config """ assert 'network' in cfg # generate list of default values service_values = {} for network in cfg['network']: for service_type, services in sorted(network['services'].items()): for service in services or []: service_id = service['id'] service_values[service_id] = DB_SERVICE_SUBKEYS.copy() service_values[service_id].update({ 'service-type': service_type, 'network': network['id'], 'ip-address': service['address'], }) # set service default values for service_id, service_defaults in sorted(service_values.items()): db_key_prefix = f'service/{service_id}' try: db.get_value(f"{db_key_prefix}/service-type") continue except KeyError: log.info('Registering new service %s in management service', service_id) register_service_event( 'SERVICE_REGISTER', service=service_id, params={'service_type': service_defaults['service-type']}) for key, val in service_defaults.items(): db.set_value(f"{db_key_prefix}/{key}", val) set_tech_cfg_service_cond_values(db, cfg) def set_tech_cfg_service_cond_values(db, cfg): """Set/remove service conditional values related to technical config.""" for network in cfg['network']: for service_type, services in sorted(network['services'].items()): for service in services or []: # create 'tls-key' and 'tls-cert' for # choices/mid/storage/verification/voting services if SERVICE_TYPE_PARAMS[service_type]['require_tls']: manage_db_cond_value(db, service["id"], "tls-key", True) manage_db_cond_value(db, service["id"], "tls-cert", True) # create 'backup-times' for backup service elif service_type == 'backup': manage_db_cond_value( db, service['id'], 'backup-times', True, ' '.join(cfg.get('backup') or [])) def manage_db_cond_value(db, service_id, key, set_value, value=None): """Manage (create/remove) service conditional database value.""" key = f'service/{service_id}/{key}' if set_value: # create key try: db.get_value(key) except KeyError: db.set_value(key, value or '') else: # remove key try: db.rm_value(key) except KeyError: pass def manage_db_mobileid_fields(db): """Create/remove service Mobile-ID/Smart-ID/Web eID token keys in database. Check 'ticket' authentication method in election config and manage "mid-token-key" keys in management database for mid, choices and voting services. Keys will created or removed as 'ticket' authentication method is used or not. """ ticket_auth = 'ticket' in db.get_all_values('election').get('auth', {}) for service_id, service_data in db.get_all_values('service').items(): if service_data['service-type'] not in [ 'mid', 'smartid', 'webeid', 'choices', 'voting']: continue key = f'service/{service_id}/mid-token-key' if ticket_auth: if 'mid-token-key' not in service_data: db.set_value(key, '') elif 'mid-token-key' in service_data: db.rm_value(key) def manage_db_tsp_fields(db): """Create/remove service TSP registration keys in database. Check 'qualification' protocol in election config and manage "tspreg-key" keys in management database for voting services. Keys will created or removed as 'tspreg' protocol is used or not. """ tspreg = db.get_all_values('election').get('tspreg', '') for service_id, service_data in db.get_all_values('service').items(): if service_data['service-type'] not in ['voting']: continue key = f'service/{service_id}/tspreg-key' if tspreg: if 'tspreg-key' not in service_data: db.set_value(key, '') elif 'tspreg-key' in service_data: db.rm_value(key) def gen_host_record_defaults(db, cfg): """Add database records for service hosts with default values. Parse the list of services from technical config and create missing database records for service hosts. :param db: Database handler :param cfg: Technical config """ # generate list of default values hostnames = set() for network in cfg['network']: for services in network['services'].values(): for service in services or []: hostnames |= {service['address'].split(':')[0]} # set host default values for hostname in sorted(hostnames): db_key_prefix = f'host/{hostname}' try: db.get_value(f"{db_key_prefix}/state") continue except KeyError: log.info( 'Registering new service host %s in management service', hostname) db.set_value(f"{db_key_prefix}/state", "") def gen_logmon_data(db, logging_params): """Add database record for Log Monitor service. :param logging_params: Logging params from technical config. :type logging_params: list of dicts """ if logging_params: db.set_value('logmonitor/address', logging_params[0]['address']) def cfg_type_verbose(cfg_type): """Get config type as human readable string.""" try: return CFG_TYPES[cfg_type] except KeyError: return VOTING_LIST_TYPES[cfg_type] def get_services(db=None, require_collector_state=None, service_state=None, include_types=None, exclude_types=None): """Generate filtered list of services. :param require_collector_state: Require specified state for collector :type require_collector_state: list :param include_types: Include specified service types :type include_types: list :param exclude_types: Exclude specified service types :type exclude_types: list :return: dict of services (key is service ID and value is dict with service database values) or None if collector is not in expected state """ require_collector_state = require_collector_state or [] assert isinstance(require_collector_state, list) service_state = service_state or [] assert isinstance(service_state, list) include_types = include_types or [] exclude_types = exclude_types or [] assert isinstance(include_types, list) assert isinstance(exclude_types, list) assert not include_types or not exclude_types # get collector state if db: collector_state = generate_collector_state(db) else: with IVXVManagerDb() as _db: collector_state = generate_collector_state(_db) # check collector state if (require_collector_state and collector_state['collector_state'] not in require_collector_state): log.info('Collector service state is %s', collector_state['collector_state']) if len(require_collector_state) == 1: log.error('Collector state must be %s for this operation', require_collector_state[0]) else: log.error('Collector state must be %s or %s for this operation', ', '.join(require_collector_state[:-1]), require_collector_state[-1]) return None # create list of services services = {} for service_id, service_data in collector_state.get('service', {}).items(): if service_state and service_data.get('state') not in service_state: continue if include_types: if service_data['service-type'] in include_types: services[service_id] = service_data continue if exclude_types: if service_data['service-type'] not in exclude_types: services[service_id] = service_data continue services[service_id] = service_data return services def clean_dir(path): """Remove all files from directory.""" log.debug("Cleaning directory %r", path) for filename in os.listdir(path): role_filename = os.path.join(path, filename) os.unlink(role_filename) def populate_user_permissions(db): """Populate user permissions for Apache web server.""" permissions_path = CONFIG['permissions_path'] permissions_to_create = [] for user_cn, permissions in db.get_all_values('user').items(): for permission_name in permissions.split(','): permissions_to_create.append(f"{user_cn}-{permission_name}") # removing permission files for permission_name in os.listdir(permissions_path): if permission_name not in permissions_to_create: filepath = os.path.join(permissions_path, permission_name) log.info("Removing Apache Web Server user permission file %r", filepath) os.remove(filepath) # creating permission files for permission_name in permissions_to_create: filepath = os.path.join(permissions_path, permission_name) if not os.path.exists(filepath): log.info("Creating Apache Web Server user permission file %r", filepath) with open(filepath, 'x') as fp: fp.write(f"Created {datetime.datetime.now().strftime('%c')}") def get_current_voter_list_changeset_no(db): """Get changeset number from database for last loaded voter list. :return: changeset number or -1 if initial voter list is not loaded to database :rtype: int """ for changeset_no in range(10_000): try: db.get_value(f"list/voters{changeset_no:04d}") except KeyError: return changeset_no - 1 return 0 def get_loaded_cfg_file_path(cfg_type): """Get real file path for loaded config file. :return: File path or None if file does not exist :rtype: str """ ext = ( "zip" if cfg_type.startswith("voters") and cfg_type != "voters0000" else "bdoc" ) filepath = cfg_path("active_config_files_path", f"{cfg_type}.{ext}") if not os.path.exists(filepath): return None assert os.path.islink(filepath), ( f"Config file {filepath!r} is not a symbolic link" ) return os.path.realpath(filepath) ================================================ FILE: collector-admin/ivxv_admin/lib/lockfile.py ================================================ # IVXV Internet voting framework """Lockfile implementation for collector management service.""" import argparse import atexit import errno import fcntl import logging import os import signal import sys import time from ..config import cfg_path # create logger log = logging.getLogger( f"{__package__}.lockfile" if __name__ == "__main__" else __name__ ) class PidLocker: """Pidfile creator and locker. Create pidfile and keep it locked until program exit. Raise IOError on locking failure. >>> try: ... PidLocker("/path/to/pidfile", timeout = 5) ... except IOError: ... print('Locking failed even after waiting 5 seconds') ... exit(1) """ filepath = None #: Pidfile name fp = None #: Pidfile descriptor def __init__(self, pidfile_name, timeout=0): """Create and lock pidfile. :raises OSError: On locking failure """ self.fp = None self.filepath = pidfile_name atexit.register(self.rm_pid) self.fp = open(pidfile_name, "ab") self.acquire_lock_with_timeout(timeout) self.fp.write(bytes(f"{os.getpid()}\n", "ASCII")) self.fp.flush() def acquire_lock_with_timeout(self, to): def handler(signum, frame): raise OSError(errno.EACCES, f"Failed to lock {self.filepath} in {to} sec") signal.signal(signal.SIGALRM, handler) retry_interval = 0.1 try: signal.alarm(to) while True: try: fcntl.flock(self.fp, fcntl.LOCK_EX | fcntl.LOCK_NB) # Successfully acquired a lock break except Exception: # pylint: disable=broad-except if to == 0: raise OSError(errno.EACCES, f"Failed to lock {self.filepath} in {to} sec.") # Wait for another process to release the lock time.sleep(retry_interval) finally: signal.alarm(0) def rm_pid(self): """Remove pidfile.""" try: os.remove(self.filepath) if self.fp is not None: self.fp.close() except FileNotFoundError: log.warning("PID file %r already removed", self.filepath) @classmethod def get_pidfile_path(cls, pidfile_name): """Get pidfile path.""" pidfile_path = cfg_path("ivxv_admin_data_path", pidfile_name) return pidfile_path @classmethod def pidfile_exists(cls, pidfile_name): """Check if pidfile exist.""" pidfile_path = cls.get_pidfile_path(pidfile_name) return os.path.exists(pidfile_path) @classmethod def rm_stale_pidfile(cls, pidfile_name): """Remove stale or invalid pidfile.""" if not cls.pidfile_exists(pidfile_name): return pidfile_path = cls.get_pidfile_path(pidfile_name) with open(pidfile_path) as fp: pidline = fp.readline() reason = "" if pidline.strip() else "empty" if not reason: try: pid = int(pidline) except ValueError: reason = "invalid" if not reason and not os.path.exists(f"/proc/{pid}"): reason = "stale" if reason: log.error("Removing %s pidfile %r", reason, pidfile_path) os.remove(pidfile_path) def main(): """Lockfile testing utility.""" # parse CLI args parser = argparse.ArgumentParser( description=""" Create lock file and related process to hold it for a specified period. """ ) parser.add_argument("--file", required=True, type=str, help="Lock file name") parser.add_argument( "--time", required=True, type=int, help="Period to hold lock file (in seconds)" ) parser.add_argument( "--attempts", required=False, type=int, default=1, help="Attempts to acquire lock file", ) parser.add_argument( "--background", action="store_true", help="Fork process to background" ) args = parser.parse_args() assert args.time >= 0, "--time can't have negative value" assert args.attempts > 0, "--attempts must have positive value" filepath = PidLocker.get_pidfile_path(args.file) attempts_left = args.attempts proc_type = "background" if args.background else "foreground" # fork to background if requested if args.background: log.info("Forking to background") pid = os.fork() if pid: log.info("Forked child process %d, exiting foreground process", pid) return 0 # acquire lockfile PidLocker.rm_stale_pidfile(args.file) log.info("Creating lockfile %r for PID %d in %s", filepath, os.getpid(), proc_type) while attempts_left: attempts_left -= 1 try: PidLocker(filepath) except BlockingIOError as err: if not attempts_left: log.error("Failed to create lockfile (%s), no attempts left", err) return 1 log.warning( "Failed to create lockfile %r, waiting for 1 second (%d attempts left)", filepath, attempts_left, ) time.sleep(1) continue log.info("Lockfile %r successfully acquired", filepath) break # sleep log.info("Sleeping for %d seconds", args.time) time.sleep(args.time) # cleanup log.info("Removing lockfile %r for PID %d in %s", filepath, os.getpid(), proc_type) return 0 if __name__ == "__main__": sys.exit(main()) ================================================ FILE: collector-admin/ivxv_admin/service/__init__.py ================================================ # IVXV Internet voting framework """Microservice management module.""" from .. import SERVICE_STATE_REMOVED, SERVICE_TYPE_PARAMS from .logging import log #: Path to users SSH public key file. IVXV_ADMIN_SSH_PUBKEY_FILE = '~/.ssh/id_ed25519.pub' #: Path to rsyslog config filename. RSYSLOG_CFG_FILENAME = '/etc/rsyslog.d/ivxv-logging.conf' def get_service_cfg_state(db, cfg): """Get list of services that requires config update. Check technical config records against database and generate list of services that require config update. :param db: Database handler :param cfg: Technical config :return: Service list with config update params: .. code-block:: text { 'service-id': { 'technical': bool, 'election': bool, 'choices': bool, 'districts': bool, 'voters': [list-number, ...], }, ... } :rtype: dict """ assert 'network' in cfg # detect config versions tech_cfg_ver = db.get_value('config/technical') election_cfg_ver = db.get_value('config/election') # detect need for list updates update_choices_list = (db.get_value('list/choices') != db.get_value('list/choices-loaded')) update_districts_list = (db.get_value('list/districts') != db.get_value('list/districts-loaded')) update_voters_list = [] for changeset_no in range(10_000): try: if db.get_value(f"list/voters{changeset_no:04d}-state") == "PENDING": update_voters_list.append(changeset_no) except KeyError: break # create list of services service_list = {} for network in cfg['network']: for service_type, services in sorted(network['services'].items()): for service in services or []: db_key_prefix = f'service/{service["id"]}' service_tech_cfg_ver = db.get_value( f"{db_key_prefix}/technical-conf-version" ) service_election_cfg_ver = election_cfg_ver and db.get_value( f"{db_key_prefix}/election-conf-version" ) service_list[service['id']] = { 'technical': service_tech_cfg_ver != tech_cfg_ver, 'election': service_election_cfg_ver != election_cfg_ver, 'choices': service_type == 'choices' and update_choices_list, 'districts': service_type == 'choices' and update_districts_list, 'voters': update_voters_list, } if service_list[service['id']]['technical']: log.debug('Service %s have no latest version of ' 'technical config', service['id']) if service_list[service['id']]['election']: log.debug('Service %s have no latest version of ' 'election config', service['id']) return service_list def generate_service_list(service_networks, service_id_filter=None): """Generate service list from collector technical config. .. code-block:: text [ [, {param: value, ...}], ... ] :param service_networks: Service networks from collector technical config (section 'networks'). :type service_networks: dict :param service_id_filter: Service IDs to include. All services are included if None. :type service_id_filter: list :return: List of services or None if some of specified services not found. """ service_id_filter = service_id_filter or [] service_list = [] service_ids = service_id_filter[:] for network in service_networks: for service_type, services in sorted(network['services'].items()): for service_data in services or []: service_id = service_data['id'] if service_id_filter and service_id not in service_ids: log.debug('Skipping service %s', service_id) continue if service_ids: service_ids.remove(service_id) service_list.append([service_type, service_data]) if service_ids: log.error('Invalid service ID: %s', ', '.join(service_ids)) return None return service_list def generate_service_hints(services): """Generate configuration hints for services and inject it to service data. :param services: Service data :type services: dict """ for service_id, params in services.items(): if params['state'] == SERVICE_STATE_REMOVED: continue # ordered list of hints hints = [ ['Apply technical config', not params['technical-conf-version']], ] service_type_params = SERVICE_TYPE_PARAMS[params['service-type']] if service_type_params['require_tls']: hints += [ ['Install service TLS key', not params.get('tls-key', True)], ['Install service TLS certificate', not params.get('tls-cert', True)], ] if service_type_params['mobile_id']: hints.append( ['Install Mobile-ID/Smart-ID/Web eID identity token key', not params.get('mid-token-key', True)]) if service_type_params['tspreg']: hints.append( ['Install TSP registration key', not params.get('tspreg-key', True)]) if service_type_params['require_config']: hints.append( ['Apply election config', not params['election-conf-version']]) for hint, is_relevant in hints: if is_relevant: services[service_id]['bg_info'] = hint break ================================================ FILE: collector-admin/ivxv_admin/service/backup_service.py ================================================ # IVXV Internet voting framework """Backup service management helper.""" import subprocess def install_backup_crontab(): """Install crontab for backup automation.""" subprocess.run(["env", "VISUAL=ivxv-backup-crontab", "crontab", "-e"], check=True) ================================================ FILE: collector-admin/ivxv_admin/service/logging.py ================================================ # IVXV Internet voting framework """Logging helper for microservice management.""" import logging # create logger log = logging.getLogger('.'.join(__name__.split('.')[:-1])) class ServiceLogger(logging.LoggerAdapter): """Logger adapter for service object. Include service ID for logged messages. Include message level for levels other than INFO. """ def process(self, msg, kwargs): """ Process the logging message and keyword arguments passed in to a logging call to insert contextual information. """ return f"SERVICE {self.extra['service_id']}: {msg}", kwargs def log(self, level, msg, *args, **kwargs): """ Delegate a log call to the underlying logger, after adding contextual information from this adapter instance. """ if self.isEnabledFor(level): if level != logging.INFO: msg = f"{logging.getLevelName(level).upper()}: {msg}" msg, kwargs = self.process(msg, kwargs) self.logger.log(level, msg, *args, **kwargs) ================================================ FILE: collector-admin/ivxv_admin/service/remote_exec.py ================================================ # IVXV Internet voting framework """Remote execution helper for microservice management.""" import subprocess from .logging import log def exec_remote_cmd(cmd, **kw): """Perform remote operation in service host. Execute service management command in service host (over OpenSSH SSH client) or copy file to service host file system (over secure copy). :param cmd: Command for subprocess.run() :type cmd: list :param kw: Parameters for subprocess.run() :type kw: dict :return: subprocess.CompletedProcess """ assert cmd[0] in ('ssh', 'scp') # patch command if cmd[0] == 'ssh': cmd.insert(1, '-T') # disable pseudo-terminal allocation cmd.insert(1, '-o') # set preferred authentication method cmd.insert(2, 'PreferredAuthentications=publickey') # execute command log.debug('Executing command: %s', ' '.join(cmd)) try: check = kw.pop('check') except KeyError: check = False proc = subprocess.run(cmd, **kw, check=check) if proc.returncode: log.debug('Command finished with error code %d', proc.returncode) else: log.debug('Command successfully executed') return proc ================================================ FILE: collector-admin/ivxv_admin/service/service.py ================================================ # IVXV Internet voting framework """Microservice management helper.""" import datetime import json import os import re import shutil import subprocess import tempfile from logging.handlers import MemoryHandler from jinja2 import Environment, PackageLoader from debian import debfile from .. import ( COLLECTOR_PKG_FILENAMES, DEB_PKG_VERSION, RFC3339_DATE_FORMAT_WO_FRACT, SERVICE_SECRET_TYPES, SERVICE_STATE_CONFIGURED, SERVICE_STATE_INSTALLED, SERVICE_STATE_NOT_INSTALLED, SERVICE_TYPE_PARAMS, ) from ..config import CONFIG, cfg_path from ..db import IVXVManagerDb from ..event_log import register_service_event from . import IVXV_ADMIN_SSH_PUBKEY_FILE, RSYSLOG_CFG_FILENAME, generate_service_hints from .backup_service import install_backup_crontab from .logging import ServiceLogger, log from .remote_exec import exec_remote_cmd #: Path to service directory. SERVICE_DIR = cfg_path('ivxv_admin_data_path', 'service') class Service: """Service management for collector services.""" service_id = None #: Service ID (str) data = None #: Service data (dict) #: State report file name for currently applied config (str) cfg_state_filepath = None cfg_state = None #: State report for currently applied config (dict) def __init__(self, service_id, service_data): """Constructor.""" self.service_id = service_id # Service data from config file and the same data from # management service database are slithgtly different. # Convert service data to database format. if 'service_type' in service_data: service_data = { 'service-type': service_data.get('service_type'), 'ip-address': service_data.get('address'), } self.data = service_data self.log = ServiceLogger(log, {"service_id": service_id}) self.memory_log_handler = MemoryHandler(1000) #: Mem-handler for log buffering log.addHandler(self.memory_log_handler) def __enter__(self): return self def __exit__(self, *args): self.close() def __repr__(self): """Printable representation of an object.""" return f'' def close(self): self.memory_log_handler.close() log.removeHandler(self.memory_log_handler) @property def hostname(self): """Hostname (str).""" return self.data['ip-address'].split(':')[0] @property def service_type(self): """Service type (str).""" return self.data['service-type'] @property def service_account_name(self): """Service account name (str).""" if self.service_type in ['backup', 'log']: return 'ivxv-admin' if self.service_type == 'proxy': return 'haproxy' return f"ivxv-{self.service_type}" @property def service_systemctl_id(self): """Service ID to use with systemctl (str).""" return f'ivxv-{self.service_type}@{self.service_id}' @property def service_data_dir(self): """Path to service data directory (str).""" return os.path.join(SERVICE_DIR, self.service_id) @property def deb_pkg_name(self): """Debian package name (str).""" return f'ivxv-{self.service_type}' def get_db_key(self, name): """Get database key for this service.""" return f'service/{self.service_id}/{name}' def register_event(self, event, params, level='INFO'): """Register service event.""" register_service_event( event, level=level, service=self.service_id, params=params) def register_bg_info(self, bg_info): """Register service error message in database.""" if bg_info: self.log.info('Registering background info: %s', bg_info.split('\n')[0]) with IVXVManagerDb(for_update=True) as db: db.set_value(self.get_db_key('bg_info'), bg_info, safe=True) def remove_root_access(self): """Remove management service access to service host root account. :return: True on success, False on error. :rtype: bool """ # disable ivxv-admin key in authorized_keys file self.log.info( "Removing management service access to root account in service host %r", self.hostname, ) proc = self.ssh( 'sudo ivxv-admin-sudo remove-admin-root-access', account='root') # report result if proc.returncode: self.log.info('Failed to remove management service access ' 'to service host root account') return False self.log.info('Management service access to service host ' 'root account removed successfully') return True def install_service(self): """Install service in service host. :return: True on success, False on error. :rtype: bool """ self.log.info("Installing service to host %r", self.hostname) # initialize service on the first tech config with IVXVManagerDb() as db: current_cfg_ver = db.get_value( self.get_db_key('technical-conf-version')) if not current_cfg_ver: if not self.init_service(): return False # install service package error = not self.install_service_pkg() # create SSH access to service account if not error and self.service_account_name != 'ivxv-admin': self.log.info( "Creating access to the service account %r in service host", self.service_account_name, ) proc = self.ssh( 'sudo ivxv-admin-sudo create-ssh-access {}'.format( self.service_account_name), account='ivxv-admin') error = bool(proc.returncode) if error: self.log.error('Failed to create access ' 'to the service account in service host') # report result if error: self.log.error('Failed to install service') return False self.log.info('Service installed successfully') return True def install_service_pkg(self, is_update=False, package=None): """Install service package to service host. :return: True on success, False on error. :rtype: bool """ if not package: pkg_path = cfg_path( 'deb_pkg_path', COLLECTOR_PKG_FILENAMES[self.deb_pkg_name]) else: pkg_path = package # check package status in service host if not is_update and not package: self.log.info( 'Querying state of the service software package %r version %s', self.deb_pkg_name, DEB_PKG_VERSION) proc = self.ssh( f'dpkg --status {self.deb_pkg_name}', account='ivxv-admin', stdout=subprocess.PIPE) if proc.returncode == 0: for line in proc.stdout.decode('UTF-8').split('\n'): if line.find('Version:') == 0: pkg_version = line.split(':')[1].strip() if DEB_PKG_VERSION == pkg_version: self.log.info( "Package %r is already installed", self.deb_pkg_name, ) return True self.log.info( "Package %r is installed with wrong version %s", self.deb_pkg_name, pkg_version, ) break # copy packages to service host if not self.scp( local_path=pkg_path, remote_path=CONFIG['deb_pkg_path'], description='software package file', account='ivxv-admin'): return False # install service package self.log.info("Installing package %r", self.deb_pkg_name) proc = self.ssh( 'sudo ivxv-admin-sudo install-pkg {}'.format( pkg_path), account='ivxv-admin') if proc.returncode: self.log.error("Failed to install package %r", self.deb_pkg_name) return False self.log.info("Package %r is installed successfully", self.deb_pkg_name) return True def update_ivxv_common_pkg(self): """Update ivxv-common package in service host. :return: True on success, False on error. :rtype: bool """ # copy package file to service host pkg_name = 'ivxv-common' pkg_path = cfg_path('deb_pkg_path', COLLECTOR_PKG_FILENAMES[pkg_name]) if not self.scp( local_path=pkg_path, remote_path=CONFIG['deb_pkg_path'], description='ivxv-common package file', account='ivxv-admin'): return False # install ivxv-common package self.log.info('Installing ivxv-common package') proc = self.ssh( 'sudo ivxv-admin-sudo install-pkg {}'.format( COLLECTOR_PKG_FILENAMES[pkg_name]), account='ivxv-admin') if proc.returncode: self.log.info('Failed to install {} package', pkg_name) return False self.log.info("Package %r is installed successfully", pkg_name) return True def init_service(self): """Initialize service. :return: True on success, False on error. :rtype: bool """ # remove service package with all dependent packages if not self.remove_service_pkg(): return False # initialize service data self.log.info('Initializing service data directory in service host') service_id = ( 'backup' if self.service_type == 'backup' else self.service_id) proc = self.ssh( f'sudo ivxv-admin-sudo init-service {service_id}', account='ivxv-admin') if proc.returncode: self.log.error('Failed to initialize service data directory') return False self.log.info('Service data directory initialized successfully') return True def init_service_host(self): """Initialize service host. :return: True on success, False on error. :rtype: bool """ self.log.info('Initializing service host') # install ivxv-common package in service host if required self.log.info('Detect ivxv-common package status') proc = self.ssh('dpkg --list ivxv-common', account='ivxv-admin') if proc.returncode: self.log.info('Failed to detect ivxv-common package status') # detect ivxv-common package dependencies pkg_path = cfg_path( 'deb_pkg_path', COLLECTOR_PKG_FILENAMES['ivxv-common']) # copy package file to service host remote_path = os.path.join( '/root', COLLECTOR_PKG_FILENAMES['ivxv-common']) if not self.scp( local_path=pkg_path, remote_path=remote_path, description='ivxv-common package file', account='root'): return False # update package list self.log.info('Updating package list') cmd = [ 'env', 'TERM=dumb', 'DEBIAN_FRONTEND=noninteractive', 'apt-get', 'update' ] proc = self.ssh(cmd, account='root') if proc.returncode: self.log.info('Failed to update package list') return False # install ivxv-common package if not self.install_ivxv_common_pkg(pkg_path, remote_path): return False # create management service access to # service host ivxv-admin account self.log.info('Creating access to the management account ' '"ivxv-admin" in service host') cmd = [ 'tee', '--append', os.path.join( os.path.expanduser('~ivxv-admin'), '.ssh', 'authorized_keys') ] with open(os.path.expanduser(IVXV_ADMIN_SSH_PUBKEY_FILE), 'rb') as key_fp: proc = self.ssh(cmd, account='root', stdin=key_fp) if proc.returncode: self.log.error('Failed to remove create SSH access ' 'to management account in service host') return False # remove management service access to service host root account if not self.remove_root_access(): return False # initialize service host proc = self.ssh('sudo ivxv-admin-sudo init-host', account='ivxv-admin') if proc.returncode: self.log.error('Failed to initialize service host') return False self.log.info('Service host initialized successfully') return True def install_ivxv_common_pkg(self, pkg_path, remote_path): """Install ivxv-common package with dependent packages.""" # detect package dependencies deb = debfile.DebFile(pkg_path) deps = [] for field in 'Depends', 'Recommends': deps_str = deb.control.debcontrol().get(field) if deps_str is not None: deps += [dep.split(' ')[0] for dep in deps_str.split(', ')] # install package dependecies self.log.info('Installing ivxv-common package dependencies') cmd = [ 'env', 'TERM=dumb', 'DEBIAN_FRONTEND=noninteractive', 'apt-get', '--yes', 'install' ] + deps proc = self.ssh(cmd, account='root') if proc.returncode: self.log.info('Failed to install ivxv-common package dependencies') return False # install package self.log.info('Installing ivxv-common package') proc = self.ssh(f'dpkg --install {remote_path}', account='root') if proc.returncode: self.log.info('Failed to install ivxv-common package') return False return True def remove_service_pkg(self): """Remove service package with all dependent packages in service host. :return: True on success, False on error. :rtype: bool """ # check package state self.log.info("Checking package %r state in service host", self.deb_pkg_name) cmd = f'dpkg --list {self.deb_pkg_name}' proc = self.ssh(cmd, account='ivxv-admin', stdout=subprocess.PIPE) if proc.returncode: self.log.info( "Package %r is not installed in service host", self.deb_pkg_name, ) return True # detect packages to remove pkg_to_remove = [] for line in proc.stdout.decode().split('\n'): if line[:2] != 'un': for key in COLLECTOR_PKG_FILENAMES: if f' {key} ' in line: assert key != 'ivxv-common' pkg_to_remove.append(key) # remove packages self.log.info("Removing package %r in service host", self.deb_pkg_name) cmd = 'apt-get purge --yes {}'.format(' '.join(pkg_to_remove)) proc = self.ssh(cmd, account='root', stdout=subprocess.PIPE) if proc.returncode: self.log.info( "Failed to remove package %r in service host", self.deb_pkg_name, ) if proc.stdout: for line in proc.stdout.decode().split('\n'): self.log.info(line) if proc.stderr: for line in proc.stderr.decode().split('\n'): self.log.error(line) return False self.log.info( "Package %r in service host removed successfully", self.deb_pkg_name, ) return True def restart_service(self): """Restart service. :return: True on success, False on error. :rtype: bool """ # detect service state with IVXVManagerDb() as db: state = db.get_all_values('service') state[self.service_id]['bg_info'] = None generate_service_hints(state) # skip restarting of unconfigured service if state[self.service_id]['bg_info']: self.log.info( 'Skipping restart of unconfigured service: %s', state[self.service_id]['bg_info']) return True # restart service self.log.info('Restarting service') cmd = [ 'ivxv-admin-helper', 'restart-service', self.service_type, self.service_id, self.service_systemctl_id ] proc = self.ssh(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) error = bool(proc.returncode) if error: self.register_bg_info( 'Service restart error: {}' .format(proc.stderr.decode('UTF-8').strip())) self.log.error('Failed to restart service') return False with IVXVManagerDb(for_update=True) as db: self.register_state(db, SERVICE_STATE_CONFIGURED) self.log.info('Service restarted successfully') return True def stop_service(self): """Stop service. :return: True on success, False on error. :rtype: bool """ self.log.info('Stopping service') cmd = ['systemctl', 'stop', '--user', self.service_systemctl_id] proc = self.ssh(cmd) error = bool(proc.returncode) if error: self.log.error('Failed to stop service') return False self.log.info('Service stopped successfully') return True def configure_logging(self, tech_cfg): """Configure rsyslog logging in service host. :return: True on success, False on error. :rtype: bool """ self.log.info("Configuring syslog logging in service host %r", self.hostname) # prepare log collector services data log_collectors = [] for network in tech_cfg['network']: for service_type, services in network['services'].items(): if service_type == 'log' and services: for service in services: log_collectors.append({ 'id': service['id'], 'address': service['address'].split(':')[0], 'port': service['address'].split(':')[1], }) # prepare external log collectors data (first record is Log Monitor) ext_log_collectors = tech_cfg.get('logging', []) # load rsyslog config template tmpl_env = Environment(loader=PackageLoader('ivxv_admin', 'templates')) template = tmpl_env.get_template('ivxv_service_rsyslog_conf.jinja') # create rsyslog config content rsyslog_cfg = template.render( cfg_filepath=RSYSLOG_CFG_FILENAME, log_collectors=log_collectors, ext_log_collectors=ext_log_collectors) # read existing config file cmd = f"test -f {RSYSLOG_CFG_FILENAME} && cat {RSYSLOG_CFG_FILENAME}" proc = self.ssh(cmd, account='ivxv-admin', stdout=subprocess.PIPE) existing_rsyslog_cfg = proc.stdout.decode() # don't replace file if not required if rsyslog_cfg == existing_rsyslog_cfg: self.log.info( "Rsyslog config file %r already exist with required content", RSYSLOG_CFG_FILENAME, ) return True # write config file temp_file = tempfile.NamedTemporaryFile(delete=False) temp_file.write(bytes(rsyslog_cfg, 'UTF-8')) temp_file.close() if not self.scp( local_path=[temp_file.name], remote_path='/etc/ivxv/ivxv-logging.conf', description='logging configuration file', account='ivxv-admin'): return False os.unlink(temp_file.name) # restart rsyslog service proc = self.ssh( 'sudo ivxv-admin-sudo rsyslog-config-apply', account='ivxv-admin') if proc.returncode: self.log.info('Failed to restart rsyslog server in service host') return False self.log.info('Logging configuration for service created successfully') return True def load_apply_state(self, filepath, attempt_no=0): """Load config applying state from state file. :return: Attempt number :rtype: int """ self.cfg_state_filepath = filepath with open(filepath) as fp: self.cfg_state = json.load(fp) if not attempt_no: self.cfg_state['attempts'] += 1 self.cfg_state['log'].append([]) attempt_no = self.cfg_state['attempts'] assert attempt_no == self.cfg_state['attempts'] assert attempt_no <= len(self.cfg_state['log']) self.update_apply_state() return attempt_no def update_apply_state(self, **kw): """Update config applying state file.""" self.cfg_state.update(kw) self.cfg_state["log"][-1] = list(self.get_log_buffer()) tmp_filepath = f"{self.cfg_state_filepath}.tmp" with open(tmp_filepath, 'x') as fp: json.dump(self.cfg_state, fp, indent=4, sort_keys=True) shutil.move(tmp_filepath, self.cfg_state_filepath) def apply_tech_cfg(self, cfg_ver, tech_cfg): """Apply collector technical config to service. :return: True on success, False on error. :rtype: bool """ self.update_apply_state() # install service package to service host if not self.install_service(): return False self.update_apply_state() # configure service logging if self.service_type != 'log' and not self.configure_logging(tech_cfg): return False self.update_apply_state() # mark services that does not require config packages as CONFIGURED # after install if not SERVICE_TYPE_PARAMS[self.service_type]['require_config']: self.register_cfg_version( 'technical', cfg_ver, SERVICE_STATE_CONFIGURED) install_backup_crontab() return True # create data directory for service proc = self.ssh(f'mkdir --verbose --parents {self.service_data_dir}') if proc.returncode: self.log.error('Failed to generate service data directory') return False self.update_apply_state() # apply trust root config to service self.log.info('Applying trust root config to service') if not self.copy_cfg_to_service('trust'): self.log.error('Failed to apply trust root config to service') return False self.log.info('Trust root config successfully applied to service') self.update_apply_state() # apply technical config to service self.log.info('Applying technical config to service') if not self.copy_cfg_to_service('technical'): self.log.error('Failed to apply technical config to service') return False self.update_apply_state() # notify service about config change with IVXVManagerDb() as db: election_cfg_ver = db.get_value( self.get_db_key('election-conf-version')) if election_cfg_ver and not self.restart_service(): return False self.log.info('Technical config successfully applied to service') self.update_apply_state() # detect service current state with IVXVManagerDb() as db: service_old_state = db.get_value(self.get_db_key('state')) # register config version (and new service state for NOT INSTALLED # service) in management database self.register_cfg_version( 'technical', cfg_ver, SERVICE_STATE_INSTALLED if service_old_state == SERVICE_STATE_NOT_INSTALLED else None ) return True def apply_election_cfg(self, cfg_ver): """Apply elections config to service. :return: True on success, False on error. :rtype: bool """ # detect service state with IVXVManagerDb() as db: state = db.get_all_values('service') # service issues must be fixed before installing first election config if not state[self.service_id]['election-conf-version']: state = {self.service_id: state[self.service_id]} generate_service_hints(state) if state[self.service_id].get('bg_info') not in [ None, 'Apply election config' ]: self.log.error('Cannot apply election config: %s', state[self.service_id].get('bg_info')) return False del state self.log.info('Applying election config to service') if not self.copy_cfg_to_service('election'): return False self.update_apply_state() # enable service systemd unit if first config is loaded self.log.info('Enabling systemd unit') cmd = f'systemctl enable --user {self.service_systemctl_id}' proc = self.ssh(cmd) if proc.returncode: self.log.error('Failed to enable systemd unit') return False self.update_apply_state() # register config version and service state in management database self.register_cfg_version( 'election', cfg_ver, SERVICE_STATE_CONFIGURED) # notify service about config change if not self.restart_service(): return False self.update_apply_state() # install crontab for automatic backups if self.service_type == 'voting': install_backup_crontab() return True def apply_list(self, list_type, changeset_no=None): """Apply choices list to service. :param list_type: List type (choices, voters) :type list_type: str :param changeset_no: Changeset number for voter list :type changeset_no: int :return: True on success, False on error. :rtype: bool """ # apply list self.log.info('Applying %s list to service', list_type) if not self.copy_cfg_to_service(list_type, changeset_no): self.log.error('Failed to apply %s list to service', list_type) return False self.update_apply_state() # register list version with IVXVManagerDb(for_update=True) as db: if list_type in ["choices", "districts"]: cfg_ver = db.get_value(f"list/{list_type}") self.log.info( "Registering applied %s list version %r in management database", list_type, cfg_ver, ) db.set_value(f"list/{list_type}-loaded", cfg_ver) else: assert list_type == "voters" cfg_ver = db.get_value(f"list/voters{changeset_no:04}") self.log.info( "Registering applied voters list #%d " "version %r in management database", changeset_no, cfg_ver, ) db.set_value(f"list/voters{changeset_no:04}-state", "APPLIED") self.log.info('%s list applied successfully to service', list_type.capitalize()) return True def load_secret_file(self, secret_type, filepath, checksum): """Load secret key file to service and register file checksum. :param secret_type: Secret type :type secret_type: str :param filepath: Source file path :type filepath: str :param checksum: File checksum :type checksum: str :return: True on success, False on error. :rtype: bool """ secret_descr = SERVICE_SECRET_TYPES[secret_type]['description'] target_path = (SERVICE_SECRET_TYPES[secret_type]['target-path'] .format(service_id=self.service_id)) shared_sercet = SERVICE_SECRET_TYPES[secret_type]['shared'] file_mode = '0640' if shared_sercet else '0600' remote_account = ('ivxv-admin' if shared_sercet else self.service_account_name) # copy file to service host self.log.info('Loading %s to service', secret_descr) if not self.scp( local_path=[filepath], remote_path=target_path, account=remote_account, description=secret_descr): return False # set file permissions proc = self.ssh( f'chmod --changes {file_mode} {target_path}', account=remote_account) if proc.returncode: self.log.error('Failed to set %s file permissions ' 'in service host', secret_descr) return False # register key checksum with IVXVManagerDb(for_update=True) as db: self.log.info( 'Registering loaded %s checksum in management database', secret_descr) db.set_value( self.get_db_key(SERVICE_SECRET_TYPES[secret_type]['db-key']), checksum) self.log.info('%s loaded successfully to service', secret_descr) # restart service return self.restart_service() def copy_cfg_to_service(self, cfg_type, changeset_no=None): """Copy config to service host and reload service if needed. :param cfg_type: Config type (trust, technical, elections, choices, voters) :type cfg_type: str :param changeset_no: Changeset number for voter list :type changeset_no: int :return: True on success, False on error. :rtype: bool """ # copy config to host cfg_filename_suffix = f"{changeset_no:04}" if cfg_type == "voters" else "" cfg_filename_ext = "zip" if changeset_no else "bdoc" cfg_filename = f"{cfg_type}{cfg_filename_suffix}.{cfg_filename_ext}" cfg_filepath = cfg_path('active_config_files_path', cfg_filename) target_path = f'/etc/ivxv/{cfg_filename}' if not self.scp( local_path=[cfg_filepath], remote_path=target_path, account='ivxv-admin', description=f'{cfg_type} config'): return False # set config file permissions self.log.info('Set %s config file permissions in service host', cfg_type) cmd = ['chmod', '--changes', '0640', target_path] proc = self.ssh(cmd, account='ivxv-admin') if proc.returncode: self.log.error('Failed to set %s config file permissions ' 'in service host', cfg_type) return False # notify choices service about list change list_change_util = { 'choices': 'ivxv-choiceimp', 'districts': 'ivxv-districtimp', 'voters': 'ivxv-voterimp' }.get(cfg_type) if list_change_util: self.log.info('Notify service about %s list change', cfg_type) cmd = [list_change_util, '-instance', self.service_id, target_path] proc = self.ssh(cmd) if proc.returncode: self.log.info('Failed to notify service about %s list change', cfg_type) return False return True def register_cfg_version(self, cfg_type, cfg_ver, service_state): """Register config version and service state in database.""" with IVXVManagerDb(for_update=True) as db: self.log.info( "Registering %s config version %r in management database", cfg_type, cfg_ver, ) db.set_value( self.get_db_key(f"{cfg_type}-conf-version"), cfg_ver) if service_state is not None: self.register_state(db, service_state) def register_state(self, db, state, bg_info=None): """Register service state in database.""" last_state = db.get_value(self.get_db_key('state')) if state == last_state: self.log.info("Service state %r not changed", state) return # set background info if state in SERVICE_STATE_CONFIGURED: bg_info = '' if bg_info is not None: db.set_value(self.get_db_key('bg_info'), bg_info, safe=True) # set service state self.log.info( "Registering service state as %r " "in management database (last state: %r)", state, last_state, ) db.set_value(self.get_db_key('state'), state, safe=True) self.register_event( 'SERVICE_STATE_CHANGE', params={ 'state': state, 'last_state': last_state }) def ping(self): """Ping service. :return: True on success, False on error. :rtype: bool """ self.log.debug('Pinging service') # query service status cfg_check_enabled = False if self.service_type == 'backup': ping_cmd = 'true' elif self.service_type == 'log': ping_cmd = 'systemctl status rsyslog' else: ping_cmd = 'env LC_ALL=C systemctl status --user {}'.format( self.service_systemctl_id) cfg_check_enabled = True ping_proc = self.ssh( ping_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if not ping_proc.returncode: if cfg_check_enabled: try: self._verify_cfg_version() except LookupError as err: self.register_bg_info(str(err)) self.log.error('Failed to detect service status') return False self.register_bg_info('') self.log.debug('Service is alive') return True # return without config check cmd_err_output = ping_proc.stderr.decode('UTF-8').strip() if not cfg_check_enabled or cmd_err_output: self.register_bg_info( 'Ping error: {}'.format( cmd_err_output or ping_proc.stdout.decode('UTF-8').strip() or f"Command {' '.join(ping_cmd)!r} failed")) self.log.error('Pinging service failed') return False # check service config cfg_check_cmd = [ 'ivxv-admin-helper', 'check-service-config', self.service_type, self.service_id ] cfg_check_proc = self.ssh( cfg_check_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if cfg_check_proc.returncode == 0: # valid config self.register_bg_info( 'Ping error: {}'.format( ping_proc.stdout.decode('UTF-8').strip() or f"Command {' '.join(ping_cmd)!r} failed")) self.log.error('Pinging service failed') else: # invalid config self.register_bg_info( 'Ping error: Invalid config: {}'.format( cfg_check_proc.stderr.decode('UTF-8').strip() or cfg_check_proc.stdout.decode('UTF-8').strip())) self.log.error('Pinging service failed (invalid configuration)') return False def _get_cfg_versions_from_service(self): """Get config versions from service. Service version data is provided by commands: * ``systemctl show`` - trust, technical and election config * ``ivxv-choiceimp`` - choices list * ``ivxv-districtimp`` - districts list * ``ivxv-voterimp`` - voters lists :raises LookupError: if some internal check fails """ cfg_versions = { 'service_state': {}, 'choices_list_versions': [], 'districts_list_versions': [], 'voters_lists_versions': [], } # query status text for trust, technical and election config cmd = ('systemctl --user show --property StatusText ' f'{self.service_systemctl_id}') proc = self.ssh(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if proc.returncode: raise LookupError( 'Error while querying service status text: {}'.format( proc.stderr.decode('UTF-8'))) status_text = proc.stdout.decode('UTF-8') # parse status re_pattern = re.compile(r'StatusText=(.+)') if not re_pattern.match(status_text): raise LookupError(f'Invalid service state text: {status_text}') state_json = re_pattern.sub('\\1', status_text) try: cfg_versions['service_state'] = json.loads(state_json) except json.decoder.JSONDecodeError as err: raise LookupError( f'Error while decoding JSON data from service state: {err}. ' f'JSON: {state_json}') self.log.debug('Service internal status: %s', cfg_versions['service_state']['Status']) # query status text for choices and districts list if self.service_type == 'choices': for cfg_type in ["choices", "districts"]: utility = f"ivxv-{cfg_type[:-1]}imp" cmd = f"{utility} --check version --instance {self.service_id}" proc = self.ssh(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if proc.returncode: raise LookupError( f"Error while querying {cfg_type} list version: " f"{proc.stderr.decode('UTF-8')}" ) status_text = proc.stdout.decode("UTF-8") try: list_versions = json.loads(status_text) if status_text else [] assert isinstance(list_versions, list) except json.decoder.JSONDecodeError as err: raise LookupError( "Error while decoding JSON data from service state: " f"{err}. JSON: {status_text}" ) # query status text for voters lists elif self.service_type == 'voting': cmd = ( f'ivxv-voterimp --check version --instance {self.service_id}') proc = self.ssh( cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if proc.returncode: raise LookupError( 'Error while querying voters list versions: {}'.format( proc.stderr.decode('UTF-8'))) status_text = proc.stdout.decode('UTF-8') try: cfg_versions['voters_lists_versions'] = ( json.loads(status_text) if status_text else []) assert isinstance(cfg_versions['voters_lists_versions'], list) except json.decoder.JSONDecodeError as err: raise LookupError( 'Error while decoding JSON data from service state: ' f'{err}. JSON: {status_text}') return cfg_versions def _verify_cfg_version(self): """Verify config version. Compare config version data provided by service and version in management database. :return: Message to register in service background info :raises LookupError: if some internal check fails """ cfg_versions = self._get_cfg_versions_from_service() version_in_db = None with IVXVManagerDb() as db: for cfg_type in 'trust', 'technical', 'election': db_key = ( 'config/trust' if cfg_type == 'trust' else self.get_db_key(f'{cfg_type}-conf-version')) version_in_db = db.get_value(db_key) versions_in_service = cfg_versions['service_state']['Version'][ cfg_type.capitalize()] if version_in_db not in versions_in_service: raise LookupError( f"{cfg_type.capitalize()} config version " "in service status info " f"does not contain version {version_in_db!r} " "registered in management database. " f"Service status info: {versions_in_service}" ) for list_type in ["choices", "districts"]: versions_in_service = cfg_versions[f"{list_type}_list_versions"] if versions_in_service: version_in_db = db.get_value(f"list/{list_type}") if version_in_db not in versions_in_service: raise LookupError( f"{list_type.capitalize()} list version " "in service status info " f"does not contain version {version_in_db!r} " "as registered in management database. " "Choices list versions in services: " f"{versions_in_service}" ) version_lists_in_service = cfg_versions['voters_lists_versions'] if version_lists_in_service: for changeset_no in range(10_000): key = f"list/voters{changeset_no:04d}-loaded" try: version_in_db = db.get_value(key) except KeyError: break try: versions_in_service = version_lists_in_service[ changeset_no - 1] except IndexError: raise LookupError( "Service status info does not contain " "version info for voters list " f"#{changeset_no:04d}. " "Version for this list in management database " f"is {version_in_db!r}" ) if version_in_db not in versions_in_service: raise LookupError( f"Voters list #{changeset_no:04d} version " "in service status info " f"does not contain version {version_in_db!r} " "as registered in management database. " "Voters list versions in services: " f"{versions_in_service}" ) def scp(self, local_path, remote_path, description, account=None, to_remote=True): """Copy file using SCP protocol. :param local_path: Local file path(s) :type local_path: str or list of strings :param remote_path: Remote file path :type remote_path: str :param description: Description of files to copy (for logging) :type description: str :param account: Remote account name (None = default service account) :type account: str :param to_remote: Copy to remote host (True) or from remote host :type to_remote: bool :return: True on success, False on error. :rtype: bool """ if not isinstance(local_path, list): local_path = [local_path] assert to_remote or len(local_path) == 1 remote_path = '{}@{}:{}'.format(account or self.service_account_name, self.hostname, remote_path) direction_str = 'to' if to_remote else 'from' # prepare command cmd = ['scp'] + (local_path + [remote_path] if to_remote else [remote_path] + local_path) # execute command self.log.info('Copying %s %s service host', description, direction_str) proc = exec_remote_cmd(cmd) # return results if proc.returncode: self.log.error('Failed to copy %s %s service host', description, direction_str) return proc.returncode == 0 def ssh(self, cmd, account=None, fwd_auth_agent=False, **kw): """Execute command in remote host. :param cmd: Command to execute :type cmd: str or list :param account: Remote account name :type account: str :param fwd_auth_agent: Start ssh with authentication agent forwarding :type fwd_auth_agent: bool :param kw: Command arguments :return: subprocess.CompletedProcess """ if not isinstance(cmd, list): cmd = [cmd] ssh_cmd = ['ssh', '-A'] if fwd_auth_agent else ['ssh'] ssh_cmd.append( '{}@{}'.format( account or self.service_account_name, self.hostname)) return exec_remote_cmd(ssh_cmd + cmd, **kw) def get_log_buffer(self): """Get formatted log messages from log buffer.""" for rec in self.memory_log_handler.buffer: timestamp = datetime.datetime.fromtimestamp(rec.created).strftime( RFC3339_DATE_FORMAT_WO_FRACT ) msg = rec.getMessage() yield f"{timestamp} {msg}" ================================================ FILE: collector-admin/ivxv_admin/templates/ivxv_backup_crontab.jinja ================================================ {# IVXV Internet voting framework Template file for backup automation crontab. -#} # Crontab for IVXV Management Service backup automation # This file is managed by IVXV Management Service # Current version is generated @ {{ time_generated }} # This file is (re)generated automatically on the following events: # # - Backup service comes to configured state # - Any of voting service instances comes to configured state # - Any of log collectors comes to configured state # # This file is removed automatically on the following events: # # - Management database is initialized {% if not configured_backup_services %} # Backup service is NOT CONFIGURED {% else %} # Backup service is configured # Configured voting services: {{ configured_voting_services }} # Configured log collectors: {{ configured_log_collectors }} {% for hour, minute in backup_times -%} # @ {{ "%02d"|format(hour) }}:{{ "%02d"|format(minute) }} {%- if configured_backup_services %} {{ minute }} {{ hour }} * * * ivxv-backup management-conf {%- endif -%} {%- if configured_voting_services %} {{ minute }} {{ hour }} * * * ivxv-backup ballot-box {%- endif -%} {%- if configured_log_collectors %} {{ minute }} {{ hour }} * * * ivxv-backup log {%- endif %} {% endfor -%} {% endif %} {#- vim:ft=jinja: #} ================================================ FILE: collector-admin/ivxv_admin/templates/ivxv_detail_stats_crontab.jinja ================================================ {# IVXV Internet voting framework Crontab template file to automate detail statistics export to VIS. -#} # Crontab for IVXV Management Service detail statistics export to VIS automation # This file is managed by IVXV Management Service # Current version is generated @ {{ time_generated }} # This file is (re)generated automatically on the following events: # # - `ivxv-cmd-load election ` # # This file is removed automatically on the following events: # # - `ivxv-collector-init` # Import detail voting stats from voting service and export it to VIS {{ minute }} {{ hour }} {{ day }} {{ month }} {{ weekday }} if [ -x /usr/bin/ivxv-voterstats ]; then /usr/bin/ivxv-voterstats detail --log-level=WARNING; fi ================================================ FILE: collector-admin/ivxv_admin/templates/ivxv_service_rsyslog_conf.jinja ================================================ {# IVXV Internet voting framework Template file for rsyslog config in service host. -#} # IVXV Internet voting framework # Rsyslog logging configuration file # {{ cfg_filepath }} # This file is automatically generated # by collector management service! DO NOT CHANGE! # load RELP output module module(load="omrelp") # increase max message size global(maxMessageSize="32k") # LOCAL LOGGING # write IVXV log to file (up to level INFO) if ($programname startswith 'ivxv-') and ($syslogfacility-text == 'local0') and ($syslogseverity <= '6') then action( type="omfile" dynaFile="IVXV_DEFAULT_LOG_FILENAME" template="ivxv-json" ) # write IVXV request log to /var/log/ivxv/ivxv-request-YYYY-MM-DD-HH.log if ($programname startswith 'ivxv-') and ($syslogfacility-text == 'local1') then action( type="omfile" dynaFile="IVXV_REQUEST_LOG_FILENAME" ) # write IVXV debug log and log of related # services (haproxy, etcd, rsyslog, sshd) to /var/log/ivxv/ivxv-debug-YYYY-MM-DD-HH.log if ($programname startswith 'ivxv-') or ($programname startswith 'rsyslog') or ($programname == 'haproxy') or ($programname == 'sshd') or ($programname == 'etcd') then action( type="omfile" dynaFile="IVXV_DEBUG_LOG_FILENAME" ) # REMOTE LOGGING - log collector services {% for log_collector in log_collectors %} # forward log messages to log collector "{{ log_collector.id }}" using RELP protocol action( type="omrelp" target="{{ log_collector.address }}" port="{{ log_collector.port }}" ) {% else %} # --- no log collectors defined --- {% endfor %} # REMOTE LOGGING - Log Monitor and other external log collectors {% if ext_log_collectors %} {% for log_collector in ext_log_collectors -%} {% if loop.index == 1 %} # forward log messages to Log Monitor using RELP protocol if ($programname startswith 'ivxv-') and ($syslogfacility-text == 'local0') and ($syslogseverity <= '6') then {% else %} # forward log messages to external log collector using RELP protocol {% endif -%} action( type="omrelp" target="{{ log_collector.address }}" port="{{ log_collector.port }}" ) {% endfor %} {% else %} # --- no log montitors defined --- {% endif %} {#- vim:ft=jinja: #} ================================================ FILE: collector-admin/ivxv_admin/templates/ivxv_status.jinja ================================================ {# IVXV Internet voting framework Template file for ivxv-status utility output. -#} {# COLLECTOR #} {% if 'collector' in sections %} Collector state: {{ collector_state }} {% endif %} {# ELECTION #} {% if 'election' in sections %} Election ID: {{ election['election-id'] or '-' }} Voting period config: Service start: {{ election['servicestart'] or '-' }} Service end: {{ election['servicestop'] or '-' }} Verification end: {{ election['verificationstop'] or '-' }} Election start: {{ election['electionstart'] or '-' }} Election stop: {{ election['electionstop'] or '-' }} Voting phase: {{ election['phase'] or '-' }} Phase start: {{ election['phase-start'] or '-' }} Phase end: {{ election['phase-end'] or '-' }} {% endif %} {# CONFIG #} {% if 'config' in sections %} Config state: Trust root config: {{ config.trust or '-' }} Technical config: {{ config.technical or '-' }} Election config: {{ config.election or '-' }} {% endif %} {# LIST #} {% if 'list' in sections %} Lists state: Choices list: {{ list.choices or '-' }} {%- if list.choices %} Choices list state: {{ list.choices == list['choices-loaded'] and 'LOADED TO SERVICE' or 'PENDING' }} {% endif %} Districts list: {{ list.districts or '-' }} {%- if list.districts %} Districts list state: {{ list.districts == list['districts-loaded'] and 'LOADED TO SERVICE' or 'PENDING' }} {% endif %} Voters lists: {{ list['voters-list-total'] }} [ APPLIED {{ list['voters-list-applied'] }} ; PENDING {{ list['voters-list-pending'] }} ; INVALID {{ list['voters-list-invalid'] }} ; SKIPPED {{ list['voters-list-skipped'] }} ] {%- if not list['voters0000'] %} [No voter lists loaded] {% else %} {%- set ns = namespace(changeset_no=0) %} {%- for key in list if key.startswith('voters') and key.endswith('-state') %} {% set ns.changeset_no = ns.changeset_no + 1 -%} {% set prefix = key|replace('-state', '') -%} {{ ns.changeset_no }}. {{ "%-7s"|format(list[prefix + '-state']) }} {{ list[prefix] }} {%- endfor %} {%- endif %} {% endif %} {# SERVICE #} {% if 'service' in sections %} Services: {{ service|count }} services in {{ network|count }} network(s) {%- for network_name in network|sort %} Service network: {{ network_name }}, {{ network[network_name]|count }} service(s) {%- for service_id in network[network_name]|sort %} {% set service = network[network_name][service_id] %} Service ID: {{ service_id }} Type: {{ service['service-type'] }} State: {{ service['state'] }} Address: {{ service['ip-address'] }} Technical config: {{ service['technical-conf-version'] or '-' }} {%- if service['service-type'] not in ['backup', 'log'] %} Election config: {{ service['election-conf-version'] or '-' }} {%- endif %} {%- if service['service-type'] == 'backup' %} Automatic backup times: {{ service['backup-times'] or '-' }} {%- endif %} {%- if 'tls-key' in service %} Service TLS key: {{ service['tls-key'] or '-' }} Service TLS certificate: {{ service['tls-cert'] or '-' }} {%- endif %} {%- if 'mid-token-key' in service %} Mobile-ID/Smart-ID/Web eID identity token key: {{ service['mid-token-key'] or '-' }} {%- endif %} {%- if 'tspreg-key' in service %} PKIX TSP registration key: {{ service['tspreg-key'] or '-' }} {%- endif %} Last data received: {{ service['last-data'] or '-' }} Background info: {{ service['bg_info'] or '-' }} {% endfor %} {% endfor %} {% endif -%} {# STORAGE #} {% if 'storage' in sections %} Data storage: Software packages: {{ storage.debs_exists|count }} exists, {{ storage.debs_missing|count }} missing {%- if storage.debs_missing %} Missing packages: {%- for pkg in storage.debs_missing %} {{ pkg }} {%- endfor %} {%- endif %} Users count: {{ user|count }} Commands: {{ storage.command_files_active|count + storage.command_files_inactive|count }} loaded ({{ storage.command_files_active|count }} active, {{ storage.command_files_inactive|count }} inactive) Active commands: {%- for command_file in storage.command_files_active %} {{ loop.index }}. {{ command_file }} {%- endfor %} Inactive commands: {%- for command_file in storage.command_files_inactive %} {{ loop.index }}. {{ command_file }} {%- endfor %} {% endif %} {#- vim:ft=jinja: #} ================================================ FILE: collector-admin/ivxv_admin/templates/ivxv_voting_facts_crontab.jinja ================================================ {# IVXV Internet voting framework Crontab template file to automate ivxv-storageorder tool. -#} # Crontab for IVXV Management Service ivxv-storageorder automation # This file is managed by IVXV Management Service # Current version is generated @ {{ time_generated }} # This file is (re)generated automatically on the following events: # # - `ivxv-cmd-load election ` # # This file is removed automatically on the following events: # # - `ivxv-collector-init` # Generate .csv file from Logmonitor logs of failed voting facts and run ivxv-storageorder on first active Collector host {{ minute }} {{ hour }} {{ day }} {{ month }} {{ weekday }} if [ -x /usr/bin/ivxv-voting-facts ]; then /usr/bin/ivxv-voting-facts; fi ================================================ FILE: collector-admin/ivxv_admin/templates/stats.json ================================================ { "data": { "TOTAL": { "age_group_16-17": 0, "age_group_18-24": 0, "age_group_25-34": 0, "age_group_35-44": 0, "age_group_45-54": 0, "age_group_55-64": 0, "age_group_65-74": 0, "age_group_75plus": 0, "authentication-methods": [], "voting-operating-systems": [], "verify-operating-systems": [], "revoters-2-times": 0, "revoters-3-times": 0, "revoters-more-than-3-times": 0, "revoters-total": 0, "revotes-from-changed-ip": 0, "revotes-with-different-card": 0, "top-10-revoters": [], "total-checkers": 0, "total-voters": 0, "total-votes-checked": 0, "total-votes-collected": 0, "votes-by-country": [], "voters-females": 0, "voters-males": 0 } }, "meta": { "generator": "IVXV Management Service Agent Daemon", "time_generated": "2017-09-01T00:00:00" }, "error": "IVXV Agent Daemon has not generated statistics. This is a default placeholder stats file from IVXV Collector Management Service package" } ================================================ FILE: collector-admin/ivxv_admin/wsgi.py ================================================ # IVXV Internet voting framework """ WSGI application for collector management service. Default path for application is "/ivxv/cgi/" """ import datetime import json import logging import os import re import urllib import urllib.request import bottle from bottle import request, response from . import ( COLLECTOR_STATE_CONFIGURED, COLLECTOR_STATE_FAILURE, COLLECTOR_STATE_INSTALLED, COLLECTOR_STATE_NOT_INSTALLED, COLLECTOR_STATE_PARTIAL_FAILURE, EVENT_LOG_FILENAME, MANAGEMENT_DAEMON_URL, USER_ROLES, __version__, ) from .config import CONFIG, cfg_path FILE_UPLOAD_PATH = CONFIG['file_upload_path'] APP = bottle.Bottle() #: Default value for "Expires" header (don't allow to cache responses) EXPIRES_DEFAULT = datetime.datetime(1970, 1, 1) log = logging.getLogger(__name__) def abort(code=500, text='Unknown Error.'): """ Abort execution and raise a HTTP error. :raises bottle.HTTPResponse: """ body = json.dumps(dict(message=text)) raise bottle.HTTPResponse( body, code, headers={'content_type': 'application/json'}) @APP.hook('before_request') def log_query(): """Log query data.""" log.info('%s %s', request.method, request.urlparts.path) if request.forms: log.info('POST params: %s', dict(request.forms)) for key, fileobj in request.files.items(): log.info("FILE: field %r, filename %r", key, fileobj.raw_filename) @APP.route('/context.json') def context(): """ Output context data (logged in user, collector state). :return: Context data as JSON :rtype: str """ # read user information from Apache environment user_cn = request.environ.get('SSL_CLIENT_S_DN_CN') assert user_cn assert ',' in user_cn # parse user information surname, name, idcode = user_cn.split(',') user_data = { 'cn': user_cn, 'user_name': f'{name} {surname}', 'idcode': idcode, 'role': [], 'role-description': [], 'permissions': [], } # detect user role for role in sorted(USER_ROLES): access_filename = cfg_path( 'permissions_path', '-'.join([user_cn, role])) if os.path.exists(access_filename): user_data['role'].append(role) user_data['role-description'].append( USER_ROLES[role]['description']) user_data['permissions'] += USER_ROLES[role]['permissions'] # prepare context data if not user_data['role']: context_data = {} user_data.update({ 'role': ['none'], 'role-description': [USER_ROLES['none']['description']], 'permissions': USER_ROLES['none']['permissions'], }) else: filepath = cfg_path('admin_ui_data_path', 'status.json') with open(filepath) as ifp: state_json = json.load(ifp) context_data = { 'collector': state_json['collector'], 'election': { 'id': state_json['election']['election-id'], 'stage': state_json['election']['phase'] } } context_data["collector"]["version"] = __version__ user_data['permissions'] = sorted(set(user_data['permissions'])) context_data['current-user'] = user_data if 'collector' in context_data: state_info = { COLLECTOR_STATE_NOT_INSTALLED: ['Paigaldamata', 'info'], COLLECTOR_STATE_INSTALLED: ['Paigaldatud', 'info'], COLLECTOR_STATE_CONFIGURED: ['Seadistatud', 'success'], COLLECTOR_STATE_FAILURE: ['Tõrge', 'danger'], COLLECTOR_STATE_PARTIAL_FAILURE: ['Osaline tõrge', 'danger'], } state = context_data['collector']['state'] context_data['collector'].update({ 'state-description': state_info[state][0], 'state-indication': state_info[state][1], }) # start response response.content_type = 'application/json' response.expires = EXPIRES_DEFAULT return json.dumps({'data': context_data}) @APP.post('/download-ballot-box') @APP.post('/download-consolidated-ballot-box') @APP.post('/skip-voters-list') @APP.post('/download-voter-detail-stats') @APP.post('/download-voting-sessions') @APP.post('/download-processor-input') def fwd_request(): """Forward request to IVXV Management Service Daemon.""" path = request.fullpath.split('/')[-1] daemon_url = MANAGEMENT_DAEMON_URL + path data = urllib.parse.urlencode(request.forms).encode("UTF-8") fwd_request = urllib.request.Request(daemon_url, data=data, method="GET") max_response_size = 1024 * 1024 * 1024 # 1GB with urllib.request.urlopen(fwd_request) as req_fp: daemon_response = req_fp.read(max_response_size) if len(daemon_response) == max_response_size: response.content_type = "application/json" return json.dumps( { "success": False, "message": f"Vastus on suurem kui {max_response_size} baiti", } ) response.content_type = req_fp.headers["Content-Type"] or "application/json" for header in ["Content-Length", "Content-Disposition"]: if req_fp.headers[header]: response.set_header(header, req_fp.headers[header]) # start response response.expires = EXPIRES_DEFAULT return daemon_response @APP.post('/upload-config') def upload_cfg(): """ Upload command file. Command file is a digitally signed file that contains one of the following commands: 1. User management command (add, change role) 2. Collector config command (contains config file or voting list) """ upload = request.files.get('upload') if upload is None: abort(400, 'Üleslaaditav fail on määramata') # save file to local directory assert os.path.isdir(FILE_UPLOAD_PATH) filename = '-'.join( [datetime.datetime.now().strftime('%s.%f'), upload.filename]) file_path = os.path.join(FILE_UPLOAD_PATH, filename) upload.save(file_path) # forward command to management daemon daemon_url = MANAGEMENT_DAEMON_URL + 'upload-command' post_data = urllib.parse.urlencode({ 'filename': filename, 'original_filename': upload.filename, 'cmd_type': request.forms.get('type') }) post_data = post_data.encode('UTF-8') with urllib.request.urlopen(daemon_url, post_data) as req_fp: daemon_response = req_fp.read() # start response response.content_type = 'application/json' response.expires = EXPIRES_DEFAULT return daemon_response @APP.route('/eventlog') def eventlog(): """Convert Collector event log file to valid JSON. :return: Event log as JSON :rtype: str """ records = [] filepath = cfg_path('ivxv_admin_data_path', EVENT_LOG_FILENAME) try: with open(filepath) as fp: while True: line = fp.readline() if not line: break records.append(json.loads(line)) except OSError as err: log.error(err) abort(text=str(err)) # start response response.content_type = 'application/json' response.expires = EXPIRES_DEFAULT return json.dumps({'data': records}) @APP.route('/ballot-box-state') def get_ballot_box_state(): """Output state of ballot boxes. :return: State as JSON :rtype: str """ state = [] for filename in os.listdir(CONFIG['exported_votes_path']): if not filename.endswith('.log'): continue timestamp = datetime.datetime.strptime( re.sub(r'.+-(\d.+).log', '\\1', filename), '%Y.%m.%d_%H.%M') filepath = os.path.join(CONFIG['exported_votes_path'], filename) with open(filepath) as fp: log_lines = fp.readlines() if len(log_lines) > 12: log_lines = log_lines[:6] + ['...\n'] + log_lines[-6:] zip_filename = filename.replace('.log', '.zip') file_state = ( 'ready' if 'Collected votes archive is written to' in log_lines[-1] else 'prepare') state.append({ 'timestamp': timestamp.strftime('%d.%m.%Y %H:%M'), 'filename': zip_filename, 'state': file_state, 'log': ''.join(log_lines), }) # start response response.content_type = 'application/json' response.expires = EXPIRES_DEFAULT return json.dumps({'data': state}) ================================================ FILE: collector-admin/site/cgi/ivxv-admin.wsgi ================================================ # IVXV Internet voting framework """ Collectors administrator interface WSGI application definition for Apache web server """ from ivxv_admin import wsgi application = wsgi.APP ================================================ FILE: collector-admin/site/index.html ================================================ IVXV Koguja haldusteenus Go to /ivxv/index.html ================================================ FILE: collector-admin/site/ivxv/about.html ================================================ Tarkvara andmed – IVXV Kogumisteenuse haldusteenus

IVXV Kogumisteenuse haldusteenus

Versioon
Elektroonilise hääletamise infosüsteem IVXV.
Kogumisteenuse haldusteenus.
Versioon: 1.10.3
Kasutajaliidese ehitamiseks on kasutatud BootsTrap teemat SB Admin 2.
================================================ FILE: collector-admin/site/ivxv/config.html ================================================ Seadistuste rakendamise seisund – IVXV Kogumisteenuse haldusteenus

Seadistuste rakendamise seisund

Andmete laadimise seisund

Seadistuste üleslaadimine
================================================ FILE: collector-admin/site/ivxv/downloads.html ================================================ Väljavõtete allalaadimised – IVXV Kogumisteenuse haldusteenus

Väljavõtete allalaadimised

Hääletamise detailstatistika

Hääletamise detailstatistika koostatakse hääletusteenuses ja see on JSON-vormingus.

Hääletamise seansid

Hääletamise ja hääle kontrollimise seansside väljavõte koostatakse logiseire teenuses ja see on CSV-vormingus.

Töötlemisrakenduse sisendi alus

Töötlemisrakenduse sisendi alus on häälte töötlemiseks vajalike sisendfailide komplekt ZIP-vormingus konteinerina ja see koostatakse haldusteenuses.

================================================ FILE: collector-admin/site/ivxv/index.html ================================================ Üldseisund – IVXV Kogumisteenuse haldusteenus

Kogumisteenuse üldseisund

Andmete laadimise seisund

Kogumisteenuse seisund:
Käimasolev hääletusetapp:
 
  • Algus: -
  • Lõpp: -
Haldusteenusesse laaditud seadistuste versioonid:
  • Usaldusjuure seadistused: -
  • Tehnilised seadistused: -
  • Valimiste seadistused: -
Valimisnimekirjade seisundid ja versioonid:
  • Valikute nimekiri: -
  • Valikute nimekirja seisund: -
  • Ringkondade nimekiri: -
  • Ringkondade nimekirja seisund: -
  • Valijate nimekirjad -   rakendamise ootel -   rakendatud -   vigaseid -   vahele jäetud -   saadaval -
Kogumisteenuse tarkvarapakid: olemas, puudu
Kasutajate arv:
Korraldused -   aktiivseid -   arhiveeritud -
================================================ FILE: collector-admin/site/ivxv/lists.html ================================================ Valimiste nimekirjad – IVXV Kogumisteenuse haldusteenus

Valimiste nimekirjad

Andmete laadimise seisund

Nimekirjade rakendamise logid on jälgitavad seadistuste lehel.
Valikute nimekiri
  • Valikute nimekiri: -
  • Valikute nimekirja seisund: -
Valijate nimekirjad
  • Valijate nimekirjad -   rakendamise ootel -   rakendatud -   vigaseid -   vahele jäetud -   saadaval -
Ringkondade nimekiri
  • Ringkondade nimekiri: -
  • Ringkondade nimekirja seisund: -

Nimekirjade üleslaadimine

================================================ FILE: collector-admin/site/ivxv/log.html ================================================ Haldussündmuste logi – IVXV Kogumisteenuse haldusteenus

Haldussündmuste logi

Andmete laadimise seisund

Aeg Teenus Tase Sündmus Kirjeldus
================================================ FILE: collector-admin/site/ivxv/services.html ================================================ Teenused – IVXV Kogumisteenuse haldusteenus

Hallatavad teenused

Andmete laadimise seisund

Teenuste kokkuvõte seisundi järgi
Paigaldamata:
Paigaldatud:
Seadistatud:
Tõrge:
Eemaldatud:
================================================ FILE: collector-admin/site/ivxv/stats.html ================================================ E-hääletamise statistika – IVXV Kogumisteenuse haldusteenus

E-hääletamise statistika

Andmete laadimise seisund

Ringkondade ja jaoskondade filter:

 
Kogutud häält
 
Hääletajat
 
Kontrollitud häält
 
Hääle kontrollijat
Hääletajate jaotumine
Sugu
Mehi  
Naisi  
Vanusegrupp
16-17  
18-24  
25-34  
35-44  
45-54  
55-64  
65-74  
75+  
Korduvhääletamiste statistika
Täpselt 2 korda hääletanute arv  
Täpselt 3 korda hääletanute arv  
Rohkem kui 3 korda hääletanute arv  
Korduvhääletamised muutunud IP-aadressilt  
Korduvhääletamised erineva kaardiga  
Hääletajate jagunemine riigiti
================================================ FILE: collector-admin/site/ivxv/users.html ================================================ Haldusteenuse kasutajad – IVXV Kogumisteenuse haldusteenus

Haldusteenuse kasutajad

Andmete laadimise seisund

Kasutajate nimekiri

# CN Rollid

Volituste rakendamine

================================================ FILE: collector-admin/site/js/config.js ================================================ /* * IVXV Internet voting framework * * Administrator interface - Configuration status page */ /** * Load page data */ function loadPageData() { var loadDate = new Date(); loadDate.setTime(Date.now()); // load collector state $.getJSON('data/status.json', function(state) { /* * HTTP GET on https://admin.?.ivxv.ee/ivxv/data/status.json * HTTP GET response that contains HTML tags is not allowed! * state is always an JSON object */ state = sanitizeJSON(state); display_cfg_panel( 'trust', state, state['config']['trust'], 'Usaldusjuure seadistus'); display_cfg_panel( 'technical', state, state['config-apply']['technical'], 'Tehniline seadistus'); display_cfg_panel( 'election', state, state['config-apply']['election'], 'Valimiste seadistus'); display_cfg_panel( 'choices', state, state['config-apply']['choices'], 'Valikute nimekiri'); display_cfg_panel( 'districts', state, state['list']['districts'], 'Ringkondade nimekiri'); var changeset_no; display_cfg_panel( 'voters0000', state, state['config-apply']['voters0000'], 'Valijate nimekiri (algne)'); for (var i = 1; i < 10000; i++) { var iStr = 'voters' + String(i).padStart(4, '0'); if (!(iStr + '-state' in state['list'])) break; if (iStr in state['config-apply']) { display_cfg_panel( iStr, state, state['config-apply'][iStr], 'Valijate muudatusnimekiri nr. ' + i); } else { display_cfg_panel( iStr, state, state['list'][iStr], 'Valijate muudatusnimekiri nr. ' + i); } } hideErrorMessage(); // data loading stats var genDate = new Date(); genDate.setTime(Date.parse(state['meta']['time_generated'])); $('#loadstatus') .removeClass('text-danger') .addClass('text-info') .html( 'Andmete laadimise aeg: ' + formatTime(loadDate, 0) + '
' + 'Andmete genereerimise aeg: ' + genDate.toLocaleTimeString('et-EE', {})); }) .fail(function() { $('#loadstatus') .removeClass('text-info') .addClass('text-danger') .html('Viga andmete laadimisel: ' + formatTime(loadDate, 0)); showErrorMessage('Viga seisundi laadimisel', true); }); } var state_filenames = {}; /** * Display config state panel * * @param {string} id_prefix * @param {Object} state * @param {Object} cfg * @param {string} title */ function display_cfg_panel(id_prefix, state, cfg, title) { id_prefix = sanitizePrimitive(id_prefix); state = sanitizeJSON(state); cfg = sanitizeJSON(cfg); // Create panel if required var panel = $('#' + id_prefix + '-cfg-state-panel'); if (!panel.length) { $('#upload-row').before( '
' + '
' + '
' + '
' + '

' + sanitizePrimitive(title) + '

' + '
' + '
' + '
' + // Placeholder for config info text ' ' + '
' + '
' + '
' + '
' ); panel = $('#' + id_prefix + '-cfg-state-panel'); } // Configure panel var panel_body = panel.find('.panel-body'); panel .removeClass('panel-green') .removeClass('panel-warning') .removeClass('panel-danger'); if ((id_prefix === 'trust') || (id_prefix === 'districts')) { var ver_element_id = 'cfg-ver-' + id_prefix; panel.addClass(cfg === null ? 'panel-danger' : 'panel-green'); panel_body .find('div:first') .html( '
Seisund: ' + (cfg === null ? 'Laadimata' : 'Rakendatud haldusteenusele') + '
' + '
' + (cfg === null ? '-' : 'Versioon: ') + '
'); outputCmdVersion('#' + ver_element_id, id_prefix, state) panel_body.find('button').hide(); } else if (cfg === undefined) { panel.addClass('panel-danger'); panel_body.find('div:first').html('
Laadimata
'); panel_body.find('button').hide(); } else { state_filenames[id_prefix] = cfg['state_file']; if (cfg['completed']) { panel.addClass('panel-green'); } else { panel.addClass('panel-warning'); } if (id_prefix.startsWith('voters')) { stateStr = voterListStateDescriptions.get(state['list'][id_prefix + '-state']); } else { stateStr = cfg['completed'] ? 'rakendatud' : 'rakendamisel'; } if (id_prefix.startsWith('voters') && !(id_prefix in state['config-apply'])) { panel_body .find('div:first') .html( '
Seisund: ' + sanitizePrimitive(stateStr) + '
' + '
Rakendatav versioon: [ määramata ]
' + '
Rakendamise katseid: 0
' ); } else { panel_body .find('div:first') .html( '
Seisund: ' + sanitizePrimitive(stateStr) + '
' + '
Rakendatav versioon: ' + cfg['version'] + '
' + '
Rakendamise katseid: ' + cfg['attempts'] + '
' ); outputCmdVersion('#cfg-ver-' + id_prefix, id_prefix, state); } if (cfg['attempts']) { panel_body.find('button').show('slow'); var logbox = panel_body.find('pre'); if (logbox.is(':visible')) { refresh_log(logbox, cfg['state_file']); } } else { panel_body.find('button').hide('slow'); panel_body.find('pre').hide('slow'); } } } /** * Toggle config log box */ function toggle_apply_log(toggle_button) { var parent_element = $(toggle_button).parent(); var logbox = parent_element.find('pre'); logbox.toggle(); if (logbox.is(':visible')) { var cfg_type = parent_element.parent().attr('id').replace('-cfg-state-panel', ''); refresh_log(logbox, state_filenames[cfg_type]); } } /** * Refresh logbox content */ function refresh_log(logbox, filename) { var url = '/ivxv/data/commands/' + filename; $.getJSON(encodeURI(url), function(state) { /* * HTTP GET on https://admin.?.ivxv.ee/ivxv/data/commands/?? * HTTP GET response that contains HTML tags is not allowed! * state is always an JSON object */ state = sanitizeJSON(state); logbox.text(state['log'][state['attempts'] - 1].join('\n')); }) .fail(function(response) { logbox.text(sanitizePrimitive(response.responseText)); }); } /** * Reset upload form */ function reset_upload_form() { $('input[type=file]').val(null); $('#file-upload-submit').attr('disabled', ''); } // Variable to store uploaded files var files; /** * Grab the files and set them to our variable */ function prepareUpload(event) { files = event.target.files; $('#file-upload-submit').attr('disabled', null); $('#upload-message').hide(); } /** * Catch the form submit and upload the files */ function uploadFiles(event) { $('#upload-message') .removeClass('alert-danger') .removeClass('alert-success') .hide(); event.stopPropagation(); // Stop stuff happening event.preventDefault(); // Totally stop stuff happening // Create a formdata object and add the files var data = new FormData(); data.append('upload', files[0]); data.append('type', sanitizePrimitive($('#drop').find(':selected').val())); var form = $('#config-upload-form'); $.ajax({ url: encodeURI(form.attr('action')), type: sanitizePrimitive(form.attr('method')), data: data, cache: false, dataType: 'json', processData: false, // Don't process the files contentType: false, // Set content type to false as jQuery will tell the server its a query string request // Success success: function(data, textStatus, jqXHR) { console.log(jqXHR.responseJSON.message); $('#upload-message') .html( sanitizePrimitive(jqXHR.responseJSON.message) + '
' + '
' + sanitizePrimitive(jqXHR.responseJSON.log.join('\n')) + '
' ) .addClass(jqXHR.responseJSON.success ? 'alert-success' : 'alert-danger') .show(); reset_upload_form(); }, // Handle errors error: function(jqXHR, textStatus, errorThrown) { console.log(jqXHR); $('#upload-message') .html(sanitizePrimitive(jqXHR.responseText)) .addClass('alert-danger') .show(); } }); } ================================================ FILE: collector-admin/site/js/downloads.js ================================================ /* * IVXV Internet voting framework * * Administrator interface - Ballot box download page */ /** * Load page data */ function loadPageData() { var loadDate = new Date(); loadDate.setTime(Date.now()); // load collector state $.getJSON('data/status.json', function(state) { /* * HTTP GET on https://admin.?.ivxv.ee/ivxv/data/status.json * HTTP GET response that contains HTML tags is not allowed! * state is always an JSON object */ state = sanitizeJSON(state); hideErrorMessage(); if ((state.collector_state == 'NOT INSTALLED') || (state.collector_state == 'INSTALLED')) { $('#common-warning-msg').show('slow'); $('#common-warning-msg .panel-body p').text('Kogumisteenus pole seadistatud. Valimiskasti allalaadimine pole võimaik.'); $('#panel-download-form').hide(); } else if (state.election.phase == 'PREPARING') { $('#common-warning-msg').show('slow'); $('#common-warning-msg .panel-body p').text('Hääletamine on ettevalmistamise faasis. Valimiskasti allalaadimine pole võimaik.'); $('#panel-download-form').hide(); } else if (state.election.phase != 'FINISHED') { $('#common-warning-msg').show('slow'); $('#common-warning-msg .panel-body p').text('Hääletusperioodil on võimalik väljastada vaid e-valimiskasti varukoopiat.'); $('#panel-download-form').show(); } else { $('#common-warning-msg').hide('slow'); $('#panel-download-form').show(); } }) .fail(function() { $('#loadstatus') .removeClass('text-info') .addClass('text-danger') .html('Viga andmete laadimisel: ' + formatTime(loadDate, 0)); showErrorMessage('Viga seisundi laadimisel', true); }); // load ballot box state $.getJSON('cgi/ballot-box-state', function(state) { /* * HTTP GET on https://admin.?.ivxv.ee/ivxv/cgi/ballot-box-state * HTTP GET response that contains HTML tags is not allowed! * state is always an JSON object */ state = sanitizeJSON(state); $('#panel-download-ballot-box').remove(); if (state.data.length === 0) { console.log('There is no ballot box created for download'); return; } var panel = $('#panel-download-ballot-box-template').clone().prop({ id: 'panel-download-ballot-box' }); panel.find('.list-group').empty(); $(state.data).each(function() { var line = null; var message = this.filename.search('consolidated') === -1 ? 'Eksporditud e-valimiskast' : 'Eksporditud ja konsolideeritud e-valimiskast'; if (this.state == 'ready') { line = $('#panel-download-ballot-box-template .list-group-item-success') .clone() .attr('href', '/ivxv/data/ballot-box/' + this.filename); } else if (this.state == 'prepare') { line = $('#panel-download-ballot-box-template .list-group-item-info') .clone(); line.find('pre').text(this.log).show(); } else { line = $('#panel-download-ballot-box-template .list-group-item-danger') .clone(); message = 'Unknown ballot box state: ' + this.state; } line.find('span').first().text(message); line.find('span em').text(this.timestamp); panel.find('.list-group').append(line); }); $('#panel-download-ballot-box-template').after(panel); panel.show(); }) .fail(function(jqXHR, textStatus) { $('#panel-download-ballot-box').remove(); var panel = $('#panel-download-ballot-box-template').clone().prop({ id: 'panel-download-ballot-box' }); panel.find('.list-group').empty(); $('#panel-download-ballot-box-template').after(panel); var line = $('#panel-download-ballot-box-template .list-group-item-danger') .clone(); line .find('span') .first() .text( 'Serveri viga allalaadimiseks ettevalmistatud valimiskastide olekuandmete laadimisel'); line.find('span em').remove(); panel.find('.list-group').append(line); panel.show(); }); } /** * Download ballot box */ function downloadBallot(consolidate) { $('#loading').show(); url = ( consolidate === 1 ? '/ivxv/cgi/download-consolidated-ballot-box' : '/ivxv/cgi/download-ballot-box') $.ajax({ method: 'POST', url: url, success: function(url) { $('#loading').hide(); $('#panel-download-form .panel-body') .text('Server alustas valimiskasti ettevalmistamist allalaadimiseks'); }, error: function(jqXHR, textStatus, errorThrown) { $('#loading').hide(); alert(errorThrown); } }); } ================================================ FILE: collector-admin/site/js/index.js ================================================ /* * IVXV Internet voting framework * * Administrator interface - Overview page */ /** * Load page data */ function loadPageData() { var loadDate = new Date(); loadDate.setTime(Date.now()); // data mappings var states = { 'NOT INSTALLED': ['Paigaldamata', 'warning', 0], 'INSTALLED': ['Paigaldatud', '', 0], 'CONFIGURED': ['Seadistatud', 'success', 0], 'PARTIAL FAILURE': ['Osaline tõrge', 'danger', 0], 'FAILURE': ['Tõrge', 'danger', 0], 'REMOVED': ['Eemaldatud', '', 0] }; var phases = { 'PREPARING': 'Ettevalmistamine', 'WAITING FOR SERVICE START': 'Teenuse käivitamise ootamine', 'WAITING FOR ELECTION START': 'Valimise alguse ootamine', 'ELECTION': 'Häälte kogumine', 'WAITING FOR SERVICE STOP': 'Teenuse seiskamise ootamine', 'FINISHED': 'Lõpetatud' }; // load collector state $.getJSON('data/status.json', function(state) { /* * HTTP GET on https://admin.?.ivxv.ee/ivxv/data/status.json * HTTP GET response that contains HTML tags is not allowed! * state is always an JSON object */ state = sanitizeJSON(state); hideErrorMessage(); // election ID $('#electionid').toggle(state['election']['election-id'] !== null); $('#election-id').text(state['election']['election-id']); // collector state $('#collector-state') .html( state['collector']['state'] in states ? states[state['collector']['state']][0] : 'Tundmatu'); $('#collector-state-panel') .removeClass('panel-danger') .removeClass('panel-warning') .removeClass('panel-success') .addClass( state['collector']['state'] in states ? 'panel-' + states[state['collector']['state']][1] : 'panel-danger'); // voting phase $('#voting-phase').toggle(state['config']['election'] !== null); $('#voting-stage') .text( state['election']['phase'] in phases ? phases[state['election']['phase']] : 'Tundmatu'); $('#voting-stage-start').text(state['election']['phase-start']); $('#voting-stage-end').text(state['election']['phase-end']); // config packages $('#trust') .addClass('list-group-item-warning') .removeClass('list-group-item-success'); if (state['config']['trust']) { outputCmdVersion('#config-trust', 'trust', state) $('#trust') .removeClass('list-group-item-warning') .addClass('list-group-item-success'); } $('#tech') .addClass('list-group-item-warning') .removeClass('list-group-item-success'); if (state['config']['technical']) { outputCmdVersion('#config-tech', 'technical', state) $('#tech') .removeClass('list-group-item-warning') .addClass('list-group-item-success'); } $('#election') .addClass('list-group-item-warning') .removeClass('list-group-item-success'); if (state['config']['election']) { outputCmdVersion('#config-election', 'election', state) $('#election') .removeClass('list-group-item-warning') .addClass('list-group-item-success'); } // voting lists - choices outputCmdVersion('#list-choices', 'choices', state) $('#choiceslist') .removeClass('list-group-item-danger') .removeClass('list-group-item-success') .removeClass('list-group-item-warning'); $('#choicesliststatus') .removeClass('list-group-item-danger') .removeClass('list-group-item-success') .removeClass('list-group-item-warning'); if (!state['list']['choices']) { $('#list-choices-status').text('Laadimata'); $('#choiceslist').addClass('list-group-item-danger'); $('#choicesliststatus').addClass('list-group-item-danger'); } else if (!state['list']['choices-loaded']) { $('#list-choices-status').text('Laaditud haldusteenusesse'); $('#choiceslist').addClass('list-group-item-warning'); $('#choicesliststatus').addClass('list-group-item-warning'); } else if (state['list']['choices'] === state['list']['choices-loaded']) { $('#list-choices-status').text('Rakendatud kogumisteenusele'); $('#choiceslist').addClass('list-group-item-success'); $('#choicesliststatus').addClass('list-group-item-success'); } // voting lists - districts outputCmdVersion('#list-districts', 'districts', state) $('#districtslist') .removeClass('list-group-item-danger') .removeClass('list-group-item-success'); $('#districtsliststatus') .removeClass('list-group-item-danger') .removeClass('list-group-item-success'); if (state['list']['districts']) { $('#districtslist').addClass('list-group-item-success'); $('#districtsliststatus').addClass('list-group-item-success'); $('#list-districts-status').text('Laaditud haldusteenusesse'); } else { $('#districtslist').addClass('list-group-item-danger'); $('#districtsliststatus').addClass('list-group-item-danger'); $('#list-districts-status').text('-'); } // voting lists - voters fillVoterListStateCounters(state['list']); $('#voterslist') .removeClass('list-group-item-danger') .removeClass('list-group-item-success'); if ((state['list']['voters-list-total'] === 0) || (state['list']['voters-list-invalid'] !== 0)) { $('#voterslist').addClass('list-group-item-danger'); } else if (state['list']['voters-list-pending'] === 0) { $('#voterslist').addClass('list-group-item-success'); $('#list-list').empty(); for (var changeset_no = 0; changeset_no < 10000; changeset_no++) { var iStr = 'voters' + String(changeset_no).padStart(4, '0'); if (!(iStr + '-state' in state['list'])) break; var listStatus = voterListStateDescriptions.get(state['list'][iStr + '-state']); $('#list-list').append( '
  • ' + (changeset_no + 1) + '. ' + sanitizePrimitive(listStatus) + ': ' + state['list'][iStr] + '
  • ' ); } } else { $('#voterslist').addClass('list-group-item-warning'); } // service summary var serviceexists = false; $.each(state['service'], function(serviceName, service) { if (service['state'] in states) { states[service['state']][2]++; serviceexists = true; } }); $('#service_summary').toggle(serviceexists); if (serviceexists) { $('#not_installed').html(states['NOT INSTALLED'][2]); $('#configured').html(states['CONFIGURED'][2]); $('#installed').html(states['INSTALLED'][2]); $('#failure').html(states['FAILURE'][2]); $('#p_failure').html(states['PARTIAL FAILURE'][2]); $('#removed').html(states['REMOVED'][2]); } // debian packages $('#debs-exist-count').text(state['storage']['debs_exists'].length); if (state['storage']['debs_missing'].length === 0) { $('#packagepanel') .removeClass('panel-danger') .addClass('panel-success') } else { $('#packagepanel') .removeClass('panel-success') .addClass('panel-danger') } $('#debs-missing-count').text(state['storage']['debs_missing'].length); $('#missing-debs-list').empty(); for (var i = 0; i < state['storage']['debs_missing'].length; i++) { $('#missing-debs-list').append( '
    ' + '
    ' + state['storage']['debs_missing'][i] + '
    ' + '
    ' ); } // users var usercount = 0; if (state['user']) { usercount = Object.keys(state['user']).length; } $('#user-count').text(usercount); // command packages $('#command-files-count').text( state['storage']['command_files_active'].length + state['storage']['command_files_inactive'].length ); $('#command-files-active-count').text(state['storage']['command_files_active'].length); $('#command-files-inactive-count').text(state['storage']['command_files_inactive'].length); // data loading stats var genDate = new Date(); genDate.setTime(Date.parse(state['meta']['time_generated'])); $('#loadstatus') .removeClass('text-danger') .addClass('text-info') .html('Andmete laadimise aeg: ' + formatTime(loadDate, 0) + '
    ' + 'Andmete genereerimise aeg: ' + genDate.toLocaleTimeString('et-EE', {})); }) .fail(function() { $('#loadstatus') .removeClass('text-info') .addClass('text-danger') .html('Viga andmete laadimisel: ' + formatTime(loadDate, 0)); showErrorMessage('Viga seisundi laadimisel', true); }); } ================================================ FILE: collector-admin/site/js/ivxv.js ================================================ /* * IVXV Internet voting framework * * Administrator interface - JavaScript helpers */ var pageContext = null; // Page context data var userContext = null; // User context data (subset of pageContext) /** * Query page context data and write it * to pageContext and userContext variables. */ function getContextData() { // query page context data console.debug('Loading context data'); $.getJSON('cgi/context.json', function(context) { /* * HTTP GET on https://admin.?.ivxv.ee/ivxv/cgi/context.json * HTTP GET response that contains HTML tags is not allowed! * context is always an JSON object */ context = sanitizeJSON(context); pageContext = context.data; userContext = pageContext['current-user']; console.debug('Current user: ' + userContext['cn'] + ' ' + userContext['idcode']); console.debug('Current role: ' + userContext['role'] + ' (' + userContext['role-description'] + ')'); copyObjectToHtml(userContext, 'user-'); // append election ID to page title if (pageContext['election']['id']) { $('title').prepend(pageContext['election']['id'] + ' – '); } $('.navbar-brand').html( 'Kogumisteenuse haldusteenus ' + pageContext['collector']['version'] ); // check user permissons and take action if (userContext['permissions'].length === 0) { // user has no permissons, generate error message and paint navbar to red $('.navbar').addClass('label-danger').find('li').addClass('label-danger'); showErrorMessage('Puuduvad kasutajaõigused'); } // Hide menu items if user has no permissions to access it var permission_page_map = [ ['election-conf-admin', 'lists.html'], ['stats-view', 'stats.html'], ['user-admin', 'users.html'], ['tech-conf-admin', 'services.html'], ['tech-conf-admin', 'config.html'], ['download-ballot-box', 'downloads.html'], ['log-view', 'log.html'] ]; $.each(permission_page_map, function(index, value) { var hide = true; for (var i = 0; i < value.length - 1; i++) { if ($.inArray(value[i], userContext['permissions']) !== -1) { hide = false; break; } } if (hide) { $('#side-menu').find('a[href~="' + value[1] + '"]').parent().hide(); } }); }) .fail(function() { showErrorMessage('Viga kontekstiandmete laadimisel', false); }); } /** * Show error message * * @param msg * @param {boolean} retain_content - Retain page content */ function showErrorMessage(msg, retain_content) { console.error(msg); if (!retain_content) { $('#page-wrapper').find('.row').hide('slow'); } $('#common-error-msg').find('p').text(msg); $('#common-error-msg').show('slow'); $('#page-wrapper').css({ 'background-color': 'rgba(217, 83, 79, 0.2)' }); } /** * Hide error message */ function hideErrorMessage() { $('#common-error-msg').hide('slow'); $('#page-wrapper').css({ 'background-color': '' }); } /** * Check user permissions * * @param {string} permission - Permission name to check * @return {boolean} Do user have permission */ function userHasPermission(permission) { return -1 !== $.inArray(permission, userContext['permissions']); } /** * Copy values from dictionary object to HTML element text nodes. * * @param {object} object_val - Dictionary object * @param {string} targetPrefix - Prefix for DOM id values */ function copyObjectToHtml(object_val, targetPrefix) { if ('undefined' === typeof(targetPrefix)) targetPrefix = ''; $.each(object_val, function(key, val) { $('#' + sanitizePrimitive(targetPrefix) + sanitizePrimitive(key)).text(val); }); } /** * Format datetime object as string * * @param {object} dateTime - datetime object * @param {number} offset - time offset */ function formatTime(dateTime, offset) { var seconds = dateTime.getSeconds(); var minutes = dateTime.getMinutes(); var hours = dateTime.getHours() + offset; seconds = seconds < 10 ? '0' + seconds : seconds; minutes = minutes < 10 ? '0' + minutes : minutes; hours = hours < 10 ? '0' + hours : hours; return hours + ':' + minutes + ':' + seconds; } /** * Output config file version * * Add link to download config file command package. * * @param {string} selector - DOM selector * @param {string} cfg_type - config type * @param {Object} cfg - config data from status.json */ function outputCmdVersion(selector, cfg_type, cfg) { selector = sanitizePrimitive(selector); cfg = sanitizeJSON(cfg); if ((cfg_type === 'trust') || (cfg_type === 'technical') || (cfg_type === 'election')) { var cfg_ver = cfg['config'][cfg_type]; } else if ((cfg_type === 'choices') || (cfg_type === 'districts')) { var cfg_ver = cfg['list'][cfg_type]; } else if (cfg_type.search('voters') === 0) { var cfg_ver = cfg['config-apply'][cfg_type]['version']; } else { console.error('Unknown config: ' + cfg_type); } if (cfg['config-apply'][cfg_type] === undefined) { $(selector).html('' + (cfg_ver === null ? '-' : cfg_ver) + ''); } else { var cmd_file = cfg['config-apply'][cfg_type]['cmd_file']; $(selector).html( '' + '' + cfg_ver + '' + '' ); } } /** * Voter list state descriptions */ const voterListStateDescriptions = new Map(); voterListStateDescriptions.set('APPLIED', 'RAKENDATUD') voterListStateDescriptions.set('PENDING', 'OOTEL') voterListStateDescriptions.set('INVALID', 'VIGANE') voterListStateDescriptions.set('SKIPPED', 'VAHELE JÄETUD') voterListStateDescriptions.set('AVAILABLE', 'SAADAVAL') /** * Fill voter list state counters */ function fillVoterListStateCounters(list_state) { $('#list-voters-total').text(list_state['voters-list-total']); $('#list-voters-loaded').text(list_state['voters-list-applied']); $('#list-voters-pending').text(list_state['voters-list-pending']); $('#list-voters-invalid').text(list_state['voters-list-invalid']); $('#list-voters-skipped').text(list_state['voters-list-skipped']); $('#list-voters-available').text(list_state['voters-list-available']); } /** * If Object (JSON!) contains XSS vulnerable content like HTML attributes * or HTML context, it will be replaced and XSS-free Object (JSON!) is returned. * * If somehow Object type data parsing fails - empty {} is returned. * Note, that even if Object data contains XSS vulnerabilities it * doesn't automatically mean, that it isn't a valid JavaScript Object, * however if data isn't valid Object, then it doesn't make sense to * proceed with XSS validation at all. * * @param {Object} context - JSON object * @return {Object} - XSS-free JSON object */ function sanitizeJSON(context) { try { return JSON.parse(JSON.stringify(context).replaceAll('<', '<')); } catch (err) { console.error(err); return {}; } } /** * If primitive type contains XSS vulnerable content like HTML attributes * or HTML context, it will be replaced and returned as XSS-free string. * * If somehow primitive type data parsing fails - empty string is returned. * Note, that even if primitive data contains XSS vulnerabilities it * doesn't automatically mean, that it isn't a valid JavaScript primitive, * however if data isn't valid primitive, then it doesn't make sense to * proceed with XSS validation at all. * * @param {string | number | boolean} context - primitive data * @return {string} - XSS-free string */ function sanitizePrimitive(context) { try { return String(context).replaceAll('<', '<'); } catch (err) { console.error(err); return ''; } } ================================================ FILE: collector-admin/site/js/lists.js ================================================ /* * IVXV Internet voting framework * * Administrator interface - Voting lists management page */ /** * Load page data */ function loadPageData() { var loadDate = new Date(); loadDate.setTime(Date.now()); // load collector state $.getJSON('data/status.json', function(state) { /* * HTTP GET on https://admin.?.ivxv.ee/ivxv/data/status.json * HTTP GET response that contains HTML tags is not allowed! * state is always an JSON object */ state = sanitizeJSON(state); hideErrorMessage(); // choices list outputCmdVersion('#list-choices', 'choices', state) if (!state['list']['choices']) { $('#list-choices-status').text('Laadimata'); $('#panel-choices-list').attr('class', 'panel panel-red'); } else { $('#choicesoption').hide(); $('#votersoption').parent().val('voters'); $('#drop').find('option[value="voters"]').prop('selected', true); if (!state['list']['choices-loaded']) { $('#list-choices-status').text('Laaditud haldusteenusesse'); $('#panel-choices-list').attr('class', 'panel panel-warning'); } else if (state['list']['choices'] === state['list']['choices-loaded']) { $('#list-choices-status').text('Rakendatud kogumisteenusele'); $('#panel-choices-list').attr('class', 'panel panel-success'); } } // voters lists if (state['list']['voters-list-applied']) { $('#votersoption').contents().replaceWith('Valijate muudatusnimekirja vahelejätmine'); } fillVoterListStateCounters(state['list']); $('#panel-voters-list').attr('class', 'panel panel-warning'); if (state['list']['voters-list-applied'] === 0) { $('#panel-voters-list').attr('class', 'panel panel-red'); } else if (state['list']['voters-list-pending'] === 0) { $('#panel-voters-list').attr('class', 'panel panel-success'); $('#list-list').empty(); for (var changeset_no = 0; changeset_no < 10000; changeset_no++) { var iStr = 'voters' + String(changeset_no).padStart(4, '0'); if (!(iStr + '-state' in state['list'])) break; var listStatus = voterListStateDescriptions.get(state['list'][iStr + '-state']); $('#list-list').append( '
  • ' + (changeset_no + 1) + '. ' + sanitizePrimitive(listStatus) + ': ' + state['list'][iStr] + '
  • ' ); } } // districts list outputCmdVersion('#list-districts', 'districts', state) if (!state['list']['districts']) { $('#list-districts-status').text('Laadimata'); $('#panel-districts-list').attr('class', 'panel panel-red'); } else { $('#list-districts-status').text('Laaditud haldusteenusesse'); $('#panel-districts-list').attr('class', 'panel panel-success'); } // data loading stats var genDate = new Date(); genDate.setTime(Date.parse(state['meta']['time_generated'])); $('#loadstatus') .removeClass('text-danger') .addClass('text-info') .html('Andmete laadimise aeg: ' + formatTime(loadDate, 0) + '
    ' + 'Andmete genereerimise aeg: ' + genDate.toLocaleTimeString('et-EE', {})); }) .fail(function() { $('#loadstatus') .removeClass('text-info') .addClass('text-danger') .html('Viga andmete laadimisel: ' + formatTime(loadDate, 0)); showErrorMessage('Viga seisundi laadimisel', true); }); } /** * Reset upload form */ function reset_upload_form() { $('input[type=file]').val(null); $('#file-upload-submit').attr('disabled', ''); } // Variable to store uploaded files var files; /** * Grab the files and set them to our variable */ function prepareUpload(event) { files = event.target.files; $('#file-upload-submit').attr('disabled', null); $('#upload-message').hide(); } /** * Catch the form submit and upload the files */ function uploadFiles(event) { $('#upload-message').hide() .removeClass('alert-danger') .removeClass('alert-success'); event.stopPropagation(); // Stop stuff happening event.preventDefault(); // Totally stop stuff happening // Create a formdata object and add the files var data = new FormData(); data.append('upload', files[0]); data.append('type', sanitizePrimitive($('#drop').find(':selected').val())); var form = $('#config-upload-form'); $.ajax({ url: encodeURI(form.attr('action')), type: sanitizePrimitive(form.attr('method')), data: data, cache: false, dataType: 'json', processData: false, // Don't process the files contentType: false, // Set content type to false as jQuery will tell the server its a query string request // Success success: function(data, textStatus, jqXHR) { console.log(jqXHR.responseJSON.message); $('#upload-message') .html( sanitizePrimitive(jqXHR.responseJSON.message) + '
    ' + '
    ' + sanitizePrimitive(jqXHR.responseJSON.log.join('\n')) + '
    ' ) .addClass(jqXHR.responseJSON.success ? 'alert-success' : 'alert-danger') .show(); reset_upload_form(); }, // Handle errors error: function(jqXHR, textStatus, errorThrown) { console.log(jqXHR); $('#upload-message') .html(sanitizePrimitive(jqXHR.responseText)) .addClass('alert-danger') .show(); } }); } ================================================ FILE: collector-admin/site/js/log.js ================================================ /* * IVXV Internet voting framework * * Administrator interface - Event log browsing page */ /** * Load page data */ function loadPageData() { var loadDate = new Date(); loadDate.setTime(Date.now()); // fill log table with data $('#dataTables-log').DataTable({ 'ajax': '/ivxv/cgi/eventlog', stateSave: true, responsive: true, 'columns': [{ 'data': 'timestamp' }, { 'data': 'service' }, { 'data': 'level' }, { 'data': 'event' }, { 'data': 'message' }], 'order': [ [0, 'desc'] ], 'fnRowCallback': function(nRow, aData) { if (aData.level === 'INFO') { $(nRow).addClass('success'); } else { $(nRow).addClass('danger'); } } }) .on('xhr', function(e, settings, json) { if (json === null) { $('#loadstatus') .removeClass('text-info') .addClass('text-danger') .html('Viga andmete laadimisel: ' + formatTime(loadDate, 0)); } else { $('#loadstatus') .removeClass('text-danger') .addClass('text-info') .html('Andmete laadimise aeg: ' + formatTime(loadDate, 0)); } }); }; ================================================ FILE: collector-admin/site/js/services.js ================================================ /* * IVXV Internet voting framework * * Administrator interface - Services management page */ /** * Load page data */ function loadPageData() { var loadDate = new Date(); loadDate.setTime(Date.now()); // data mappings var service_states = { 'NOT INSTALLED': ['Paigaldamata', 'warning', 0], 'INSTALLED': ['Paigaldatud', '', 0], 'CONFIGURED': ['Seadistatud', 'success', 0], 'FAILURE': ['Tõrge', 'danger', 0], 'REMOVED': ['Eemaldatud', '', 0] }; var service_types = { 'backup': 'Varundusteenus', 'choices': 'Nimekirjateenus', 'mid': 'Mobiil-ID abiteenus', 'smartid': 'Smart-ID abiteenus', 'webeid': 'Web-eID abiteenus', 'sessionstatus': 'SessionID staatust raporteeriv abiteenus', 'proxy': 'Vahendusteenus', 'storage': 'Talletusteenus', 'log': 'Logikogumisteenus', 'votesorder': 'Järjekorrateenus', 'voting': 'Hääletamisteenus', 'verification': 'Kontrollteenus' }; // load collector state $.getJSON('data/status.json', function(state) { /* * HTTP GET on https://admin.?.ivxv.ee/ivxv/data/status.json * HTTP GET response that contains HTML tags is not allowed! * state is always an JSON object */ state = sanitizeJSON(state); hideErrorMessage(); var i = 1; $('#service_list_table').toggle(state['service'] !== undefined); // register service details block visibility states var is_service_visible = {}; $.each(state['service'], function(k, v) { var details_block_id = k.replace(/[@\.]/g, '_') + '_details'; is_service_visible[details_block_id] = $('#' + details_block_id).is(':visible'); }); $('#services-list').empty(); $.each(state['service'], function(k, v) { var zone = 'Tundmatu'; var state_str = 'Tundmatu'; var status_class = 'warning'; var service_type = v['service-type'] in service_types ? service_types[v['service-type']] : 'Tundmatu'; var show_mobile = 'mid-token-key' in state['service'][k] ? '' : 'display: none'; var show_tlskey = 'tls-key' in state['service'][k] ? '' : 'display: none'; var show_tlscert = 'tls-cert' in state['service'][k] ? '' : 'display: none'; var lastdata = state['service'][k]['last-data'] ? state['service'][k]['last-data'] : '-'; var econf = state['service'][k]['election-conf-version'] ? state['service'][k]['election-conf-version'] : '-'; var tlsc = state['service'][k]['tls-cert'] ? state['service'][k]['tls-cert'] : '-'; var tlsk = state['service'][k]['tls-key'] ? state['service'][k]['tls-key'] : '-'; var midk = state['service'][k]['mid-token-key'] ? state['service'][k]['mid-token-key'] : '-'; var pingerr = state['service'][k]['ping-errors'] ? state['service'][k]['ping-errors'] : '-'; var bg_info = state['service'][k]['bg_info']; var tconf = state['service'][k]['technical-conf-version'] ? state['service'][k]['technical-conf-version'] : '-'; var ipaddr = state['service'][k]['ip-address'] ? state['service'][k]['ip-address'] : '-'; // Service field in json doesn't have info about its zone, have to find it by going through all of them $.each(state['network'], function(network_key, network_value) { if (k in network_value) { zone = network_key; return false; } }); if (v['state'] in service_states) { service_states[v['state']][2]++; state_str = service_states[v['state']][0]; status_class = service_states[v['state']][1]; } var details_block_id = k.replace(/[@\.]/g, '_') + '_details'; var details_block_style = is_service_visible[details_block_id] ? '' : 'display: none;'; $('#services-list').append( '' + '' + i + '' + '' + k + '' + '' + zone + '' + '' + service_type + '' + '' + state_str + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '' + '
    Vigade arv:' + pingerr + '
    Viimane kontroll:' + lastdata + '
    Tehniline seadistus:' + tconf + '
    Valimiste seadistus:' + econf + '
    IP-aaddress:' + ipaddr + '
    TLS-sertifikaat:' + tlsc + '
    TLS-võti:' + tlsk + '
    Mobiil-ID krüptimissaladus:' + midk + '
    ' + '' + '' ); if (bg_info) { $('#services-list').append( '' + '' + '' + ' Taustainfo: ' + ' ' + bg_info.replace(/\n/g, '
    ') + '
    ' + '' + '' ); } i++; }); // data loading stats var genDate = new Date(); genDate.setTime(Date.parse(state['meta']['time_generated'])); $('#loadstatus') .removeClass('text-danger') .addClass('text-info') .html('Andmete laadimise aeg: ' + formatTime(loadDate, 0) + '
    ' + 'Andmete genereerimise aeg: ' + genDate.toLocaleTimeString('et-EE', {})); }).done(function() { $('#not_installed').html(service_states['NOT INSTALLED'][2]); $('#configured').html(service_states['CONFIGURED'][2]); $('#installed').html(service_states['INSTALLED'][2]); $('#failure').html(service_states['FAILURE'][2]); $('#removed').html(service_states['REMOVED'][2]); }).fail(function() { $('#loadstatus') .removeClass('text-info') .addClass('text-danger') .html('Viga andmete laadimisel: ' + formatTime(loadDate, 0)); showErrorMessage('Viga seisundi laadimisel', true); }); } ================================================ FILE: collector-admin/site/js/stats.js ================================================ /* * IVXV Internet voting framework * * Administrator interface - Stats page */ /** * Load page data */ function loadPageData() { var loadDate = new Date(); loadDate.setTime(Date.now()); // manage districts selection if ($('#districts option').length == 1) { $.getJSON('data/districts.json', function(data) { /* * HTTP GET on https://admin.?.ivxv.ee/ivxv/data/districts.json * HTTP GET response that contains HTML tags is not allowed! * data is always an JSON object */ data = sanitizeJSON(data); var dropdown = $('#districts'); $.each(data, function() { dropdown.append($('