A venit timpul să demonstrăm cum funcționează ARM-ul criptografic bazat pe standardele cu cheie publică care rulează pe una dintre platformele mobile, și anume Android.
Conceptul care a fost stabilit la dezvoltarea utilitarului cryptoarmpkcs este că utilizatorul ar trebui să aibă parte de cât mai puține neplăceri atunci când creează și verifică o semnătură electronică. De aceea, propunem ca suportul cheie pentru certificatul personal să fie folosit pe tokenuri criptografice și/sau containere protejate . Trebuie spus că utilizarea PKCS#12 se dovedește adesea a fi aproape singura opțiune posibilă, de exemplu, atunci când aceleași tokenuri PKCS#11 nu au suport pentru anumite platforme. Astfel, am decis să începem portarea utilitarului cryptoarmpkcs pe platforma Android cu suport pentru containere protejate PKCS#12.
Să menționăm imediat că, deoarece proiectul a fost realizat pe platforma C și Tcl/Tk, portarea nu a creat dificultăți esențiale. Acest lucru a fost posibil și datorită tehnologiei . De configurarea și nu au fost probleme (mediul meu de lucru este Linux — Mageia-7.0). Voi prezenta doar un script pentru instalarea Android Command Line Tools (sdk-tools-linux-xxxx.zip):
#!/bin/sh
if [ $# -ne 1 ]
then
echo "./InstallAndroidSDK.sh <sdk-tools-linux-xxxxxxxx.zip>"
echo "Не указан архив или число параметров больше 1"
exit 1
fi
if [ ! -f $1 ]
then
echo "./InstallAndroidSDK.sh <sdk-tools-linux-xxxxxxxx.zip>"
echo "архив $1 отсутствует"
exit 1
fi
#Распаковываем SDK-TOOLS в папку tools
#unzip sdk-tools-linux-4333796.zip
unzip $1
#Создаем папку android-sdk-linux
mkdir android-sdk-linux
#Перемещвем папку tools в android-sdk-linux
mv tools android-sdk-linux
cd android-sdk-linux/tools/bin
./sdkmanager "platform-tools" "platforms;android-29" Cel mai remarcabil lucru este că în mediul Androwish sunt incluse două interpretoare undrowish-xxx și vanillawish-xxx complet identice ca compunere „balalaike” (pachete) care fac parte din Androwish. Diferența dintre undrowish și vanillawish constă în faptul că în vanillawish backend-ul este bazat pe SDL / AGG / freetype:

Prezența acestor două utilitare permite dezvoltarea aplicației fără utilizarea Android-ului în sine și a emulatorului său, apropiindu-se cât mai mult de un dispozitiv real. În primul rând, este vorba bineînțeles de undroidwish-xxx.
De fapt, pachetul utilizatorului pentru Android este construit în mediul AWSDK. Structura proiectului dumneavoastră trebuie să fie mutată în folderul ~/AWSDK/assets/app. În acest proces, modulul principal al proiectului dumneavoastră trebuie să fie redenumit în main.tcl. Dacă utilizați balalaici suplimentari cu biblioteci dinamice, bibliotecile trebuie plasate în folderele ~/AWSDK/libs/x86 pentru emulator și ~/AWSDK/libs/armeabi pentru dispozitivul real.
După aceasta, este suficient să executați comanda:
$wish ~/AWSDK/tools/bonesși să urmați indicațiile acesteia:

Pachetul apk construit va fi în folderul ~/AWSDK/build/outputs/apk.
Dacă aveți conectat un dispozitiv real sau un emulator, pachetul poate fi instalat imediat.
În acest caz, dispozitivul real trebuie să fie în modul de depanare.
Dar să revenim la aplicație. Ce a fost necesar să schimbăm în ea?
Desigur, în primul rând, modificările sunt legate de dimensiunile ecranului. A fost necesar să reproiectăm fereastra principală (fereastra de start). În cele din urmă, în loc de o singură fereastră pe un computer obișnuit:

Au apărut trei feronuri pe Android:

Prima fereastră este informațională. Conceptual, aceasta este împărțită în mai multe părți. Primul segment, situat în partea de sus, conține numele utilitarului și logo-ul său.
Apoi urmează logo-ul producătorului, un ghid informațional și trei butoane care încheie pagina.
Pagina este scrisă folosind componenta canvas. Pe pagină sunt folosite două tipuri de butoane: unul sub formă de dreptunghi semi-transparent (mediu) și două altele sub formă de dreptunghiuri cu colțuri rotunjite. Pentru crearea butoanelor cu colțuri rotunjite a fost utilizată „balalaika” . Personal, aceasta balalaika a lăsat o impresie foarte bună asupra mea. Desigur, lucrând cu canvas-ul, majoritatea codului se axează pe geometrie. Mai jos este scriptul create_titul_page.tcl pentru a crea prima pagină a aplicației. Oricine dorește îl poate edita conform propriului viziuni.
Scriptul create_titul_page.tcl
package require Tk
package require tkpath 0.3.0
global mydir
set mydir [file dirname [info script]]
#Încărcăm imaginile
#Logo-ul produsului
image create photo logo_product -file [file join $mydir "imageme" "validcertkey_51x24.png"]
#Logo-ul producătorului
image create photo logo_orel -file [file join $mydir "imageme" "я_орел_425x200.png"] -format "png -alpha 1.0"
#Android cu tcl/tk
image create photo logo_and -file [file join $mydir "imageme" "AndTk_inv_147x173.png"] -format "png -alpha 1.0"
#Pachet sigilat
image create photo svitok -file [file join $mydir "imageme" "blue_svitok.png"] -format "png -alpha 1.0"
#Plăcuță
image create photo tileand -file [file join $mydir "imageme" "tile_green_and_32x32.png"] -format "png -alpha 1.0"
#Mărire/micșorare (valoarea negativă - micșorare)
proc scaleImage {im xfactor {yfactor 0}} {
set mode -subsample
if {$xfactor>=0 && $yfactor>=0} {
set mode -zoom
} else {
set xfactor [expr $xfactor * -1]
}
if {$yfactor == 0} {set yfactor $xfactor}
set t [image create photo]
$t copy $im
$im blank
$im copy $t -shrink $mode $xfactor $yfactor
image delete $t
}
proc createtile {w backg} {
image create photo tiled
tiled copy $backg -to 0 0 $::scrwidth $::scrheight -shrink
$backg copy tiled
image delete tiled
# Creăm pânza
$w create image 0 0
-image $backg
-anchor nw
}
proc create_rectangle {canv img x1 y1 x2 y2 color alfa {wbd 0} {colorline black} } {
image create photo $img -format "default -colorformat rgb"
set rgb1 [winfo rgb $canv $color]
set cr [lindex $rgb1 0]
set cg [lindex $rgb1 1]
set cb [lindex $rgb1 2]
set fill [format "#xxx" $cr $cg $cb ]
#Creăm un dreptunghi colorat
$img put $fill -to 0 0 [expr {$x2 - $x1}] [expr {$y2 -$y1}]
#Salvăm imaginea
set dimg [$img data -format png]
#Creăm imagine cu canal alpha
image create photo $img -data $dimg -format "png -alpha $alfa"
# $img put [list $rgb1] -to 0 0 [expr {$x2 - $x1}] [expr {$y2 - $y1}]
#Afișăm dreptunghiul colorat
set imgr [$canv create image $x1 $y1 -image $img -anchor nw]
set cc [subst {butImg $img}]
$canv bind $imgr $cc
#Contur în jurul dreptunghiului colorat
if {$wbd > 0 } {
set item [$canv create rect $x1 $y1 $x2 $y2 -outline $colorline -width $wbd ]
$canv bind $item $cc
}
return $imgr
}
proc butImg {img} {
tk_messageBox -title "Buton" -icon info -message "Ați apăsat butonul=$img" -detail "::screenwidth=$::scrwidthn::screenheight=$::scrheight" -parent .
if {$img == "exit"} {
set answer [tk_dialog .dialog2 "Sfârșitul muncii" "Doriți cu adevărat să ieșiți?" question 0 "Da" "Nu" ]
if {$answer == 0} {
exit
}
}
}
proc page_titul {fr logo_manufacturer} {
global mydir
#Creăm pânza pe întreaga ecran
tkp::canvas $fr.can -borderwidth 0 -height [winfo screenheight .] -width [winfo screenwidth .] -relief flat
#Pavăm pânza cu plăci
createtile "$fr.can" "tileand"
pack $fr.can -anchor center -expand 1 -fill both -side top -padx 0 -pady 0
#Calculăm coordonatele pentru logo-ul producătorului
#update pentru a actualiza informațiile în DB despre feronerie
update
# set aa [winfo height $fr.labtitul]
set aa $::padly
#Centrarea logo-ului dezvoltatorului
set ha [image width $logo_manufacturer]
set xman [expr {($::scrwidth - $ha) / 2 }]
$fr.can create image $xman $aa -image $logo_manufacturer -anchor nw -tag tag_logo
set blogo [$fr.can bbox tag_logo]
set wexit [lindex $blogo 3]
if {$::typetlf } {
set dlx [expr {$::padlx / 1}]
$fr.can create text [expr $dlx + 6] [expr {$wexit + $::padly + 6}] -anchor nw -text "Semnătura electronică" -fill black -font {{Roboto Condensed Medium} 15 }
$fr.can create text $dlx [expr {$wexit + $::padly}] -anchor nw -text "Semnătura electronică" -fill white -font {{Roboto Condensed Medium} 15 } -tag id_text0
update
set blogo [$fr.can bbox id_text0]
set wexit [lindex $blogo 3]
$fr.can create text [expr $dlx + 4] [expr {$wexit + $::padly + 4 - 80}] -anchor nw -text "pentru platforma Android" -fill black -font {{Roboto Condensed Medium} 13}
$fr.can create text $dlx [expr {$wexit + $::padly - 80}] -anchor nw -text "pentru platforma Android" -fill white -font {{Roboto Condensed Medium} 13} -tag id_text1
set blogo [$fr.can bbox id_text1]
set wexit [lindex $blogo 3]
$fr.can create text [expr $dlx + 3] [expr {$wexit + $::padly + 3 - 50}] -anchor nw -text "Nr. 63 FZ "Despre semnătura electronică" din 6 aprilie 2011" -fill black -font {{Roboto} 10}
$fr.can create text $dlx [expr {$wexit + $::padly - 50}] -anchor nw -text "Nr. 63 FZ "Despre semnătura electronică" din 6 aprilie 2011" -fill white -font {{Roboto} 10} -tag id_text2
set blogo [$fr.can bbox id_text2]
set wexit [lindex $blogo 3]
$fr.can create text [expr $dlx + 2] [expr {$wexit + $::padly + 2 - 40}] -text "Autori: V.N. Orlov http://soft.lissi.ru, http://www.lissi.run +7(495)589-99-53 e-mail: support@lissi.run"
-anchor nw -fill black -font {{Roboto} 9}
$fr.can create text $dlx [expr {$wexit + $::padly - 40}] -text "Autori: V.N. Orlov http://soft.lissi.ru, http://www.lissi.run +7(495)589-99-53 e-mail: support@lissi.run"
-anchor nw -fill white -tag id_text3 -font {{Roboto} 9}
} else {
$fr.can create text [expr {$::padlx + 2}] [expr {$wexit + $::padly + 2}] -anchor nw -text "Semnătura electronică" -fill black -font {{Nimbus Sans Narrow} 20}
$fr.can create text $::padlx [expr {$wexit + $::padly}] -anchor nw -text "Semnătura electronică" -fill white -font {{Nimbus Sans Narrow} 20} -tag id_text0
set blogo [$fr.can bbox id_text0]
set wexit [lindex $blogo 3]
$fr.can create text [expr {$::padlx + 2}] [expr {$wexit + $::padly + 2 - 20}] -anchor nw -text "pentru platforma Android" -fill black -font {{Nimbus Sans Narrow} 18}
$fr.can create text $::padlx [expr {$wexit + $::padly - 20}] -anchor nw -text "pentru platforma Android" -fill white -font {{Nimbus Sans Narrow} 18} -tag id_text1
set blogo [$fr.can bbox id_text1]
set wexit [lindex $blogo 3]
$fr.can create text [expr {$::padlx + 2}] [expr {$wexit + $::padly + 2}] -anchor nw -text "Nr. 63 FZ "Despre semnătura electronică" din 6 aprilie 2011" -fill black -font {{Nimbus Sans Narrow} 14}
$fr.can create text $::padlx [expr {$wexit + $::padly}] -anchor nw -text "Nr. 63 FZ "Despre semnătura electronică" din 6 aprilie 2011" -fill white -font {{Nimbus Sans Narrow} 14} -tag id_text2
set blogo [$fr.can bbox id_text2]
set wexit [lindex $blogo 3]
$fr.can create text [expr {$::padlx + 1}] [expr {$wexit + $::padly + 1}] -text "Autori: V.N. Orlov http://soft.lissi.ru, http://www.lissi.run +7(495)589-99-53 e-mail: support@lissi.run"
-anchor nw -fill black -font {{Nimbus Sans Narrow} 12}
$fr.can create text $::padlx [expr {$wexit + $::padly}] -text "Autori: V.N. Orlov http://soft.lissi.ru, http://www.lissi.run +7(495)589-99-53 e-mail: support@lissi.run"
-anchor nw -fill white -tag id_text3 -font {{Nimbus Sans Narrow} 12} -tag id_text3
set blogo [$fr.can bbox id_text2]
}
set blogo [$fr.can bbox id_text3]
set wland [lindex $blogo 3]
$fr.can create image $::padlx $wland -image logo_and -anchor nw -tag tag_land
set ha [image height logo_and]
set wa [image width logo_and]
set ha1 [expr {$ha - ($ha / 2 ) }
$fr.can create image [expr {$wa - 80 }] [expr {$wland + $ha1}] -image svitok -anchor nw -tag tag_land
if {$::typetlf} {
set x1 [expr {$::padlx / 2}]
set y1 [expr $yland + 120}]
set x2 [expr {$::::scrwidth - $x1}]
set y2 [expr {$y1 + 120}]
set wd 8
set rr 18
} else {
set x1 [expr {$::padlx / 2}]
set y1 [expr {$y1 + 60}]
set x2 [expr {$::::scrwidth - $x1}]
set y2 [expr {$y1 + 40}]
}
set g5 [$fr.can gradient create linear -stops {{0 lightgreen} {1 green}}]
set S3 [$fr.can style create -stroke "skyblue" -fill $g5 -strokewidth $wd -fillopacity 0.6]
set im1 [$fr.can create prect $x1 $y1 $x2 $y2 -rx $rr -style $S3]
$fr.can bind $im1 {butImg "img1"}
#Tipărim textul
set blogo [$fr.can bbox $im1]
set by2 [lindex $blogo 3]
set by1 [lindex $blogo 1]
set bb [expr {($by2 - $by1) / 2}]
set bx2 [lindex $blogo 2]
set bx1 [lindex $blogo 0]
set bbx [expr {($bx2 - $bx1) / 2}]
set txt1 [$fr.can create text [expr {$x1 + $::padlx * 2}] [expr {$y1 + 1 }] -anchor nw -text "Site-ul dezvoltatorului" -fill black -font {{Arial} 10 normal}]
#Centrarea textului
set btxt1 [$fr.can bbox $txt1]
#Offset pe axa Y
set ty2 [lindex $btxt1 3]
set ty1 [lindex $btxt1 1]
set tt [expr {$ty2 - $ty1}]
set tt [expr {$tt / 2}]
set offsy [expr {($by1 + $bb) - ($ty1 + $tt)}]
#Offset pe axa X
set tx2 [lindex $btxt1 2]
set tx1 [lindex $btxt1 0]
set ttx [expr {($tx2 - $tx1) / 2}]
set offsx [expr {($bx1 + $bbx) - ($tx1 + $ttx)}]
$fr.can move $txt1 $offsx $offsy
$fr.can bind $txt1 {butImg "img1"}
if {$::typetlf} {
set y1 [expr $y2 + 40]
set x2 [expr {$::::scrwidth - x1}]
set y2 [expr {$y1 + 120}]
} else {
set y1 [expr {$y1 + 60}]
set x2 [expr {$::::scrwidth - x1}]
set y2 [expr {$y1 + 40}]
}
set im1 [create_rectangle $fr.can "but2" $x1 $y1 $x2 $y2 "#2b972d" 0.6 $wd "skyblue"]
#Tipărim textul
set blogo [$fr.can bbox $im1]
set by2 [lindex $blogo 3]
set by1 [lindex $blogo 1]
set bb [expr {($by2 - $by1) / 2}]
set bx2 [lindex $blogo 2]
set bx1 [lindex $blogo 0]
set bbx [expr {($bx2 - $bx1) / 2}]
set txt1 [$fr.can create text [expr {$x1 + $::padlx * 2}] [expr {$y1 + 1 }] -anchor nw -text "Trecere la meniul principal" -fill black -font {{Roboto Condensed Medium} 12}]
#Centrarea textului
set btxt1 [$fr.can bbox $txt1]
#Offset pe axa Y
set ty2 [lindex $btxt1 3]
set ty1 [lindex $btxt1 1]
set tt [expr {$ty2 - $ty1}]
set tt [expr {$tt / 2}]
set offsy [expr {($by1 + $bb) - ($ty1 + $tt)}]
#Offset pe axa X
set tx2 [lindex $btxt1 2]
set tx1 [lindex $btxt1 0]
set ttx [expr {($tx2 - $tx1) / 2}]
set offsx [expr {($bx1 + $bbx) - ($tx1 + $ttx)}]
$fr.can move $txt1 $offsx $offsy
$fr.can bind $txt1 {butImg "but2"}
if {$::typetlf} {
set x1 [expr {$::padlx / 2}]
set y1 [expr $y2 + 40]
set x2 [expr {$::::scrwidth - $x1}]
set y2 [expr {$y1 + 120}]
} else {
set x1 [expr {$::padlx / 2}]
set y1 [expr {$y1 + 60}]
set x2 [expr {$::::scrwidth - $x1}]
set y2 [expr {$y1 + 40}]
}
set S3 [$fr.can style create -stroke skyblue -fill $g5 -strokewidth $wd -fillopacity 0.6]
set im1 [$fr.can create prect $x1 $y1 $x2 $y2 -rx $rr -style $S3]
set blogo [$fr.can bbox $im1]
$fr.can bind $im1 {butImg "exit"}
set by2 [lindex $blogo 3]
set by1 [lindex $blogo 1]
set bb [expr {($by2 - $by1) / 2}]
set bx2 [lindex $blogo 2]
set bx1 [lindex $blogo 0]
set bbx [expr {($bx2 - $bx1) / 2}]
set txt1 [$fr.can create text [expr {$x1 + $::padlx * 2}] [expr {$y1 + 1 }] -anchor nw -text "Sfârșitul muncii" -fill black -font {Arial 10 normal}]
$fr.can bind $txt1 {butImg "exit"}
set btxt1 [$fr.can bbox $txt1]
#Offset pe axa Y
set ty2 [lindex $btxt1 3]
set ty1 [lindex $btxt1 1]
set tt [expr {$ty2 - $ty1}]
set tt [expr {$tt / 2}]
set offsy [expr {($by1 + $bb) - ($ty1 + $tt)}]
#Offset pe axa X
set tx2 [lindex $btxt1 2]
set tx1 [lindex $btxt1 0]
set ttx [expr {$tx2 - $tx1}]
set ttx [expr {$ttx / 2}]
set offsx [expr {($bx1 + $bbx) - ($tx1 + $ttx)}]
$fr.can move $txt1 $offsx $offsy
}
#Scriptul propriu-zis
#Citirea dimensiunilor ecranului
set ::scrwidth [winfo screenwidth .]
set ::scrheight [winfo screenheight .]
set ::typetlf 0
#Verificăm dacă este telefon
if {$::scrwidth < $::scrheight} {
set ::typetlf 1
}
set ::padls 20
set ::padlx 15
set ::padly 15
if {$::typetlf} {
wm attributes . -fullscreen 1
scaleImage icon_openfile_18x16 3
scaleImage ::img::view_18x16 3
#Logo-ul producătorului
scaleImage logo_orel 2
#Logo-ul produsului
scaleImage logo_product 2
#Android tcl/tk
scaleImage logo_and 3
#Pachet sigilat
scaleImage svitok 4
set ::padls 50
set ::padlx 75
set ::padly 50
} else {
#Configurarea widgetului pentru smartphone
scaleImage logo_orel -2
set ::scrwidth 370
set ::scrheight 700
wm minsize . $::scrwidth $::scrheight
set geometr $::scrwidth
append geometr "x"
append geometr $::scrheight
append geometr "+0+0"
wm geometry . $geometr
}
#Creăm denumirea produsului
set name_product "CryptoArmPKCS-A"
label .labtitul -image logo_product -compound left -fg snow -text $name_product -font {Arial 10 bold} -anchor w -width [winfo screenwidth .] -pady $::padls -padx 10 -bg #222222
pack .labtitul -anchor nw -expand 0 -fill x -side top -padx 1 -pady 0
#Creăm pagina de start
set i 0
ttk::frame .fr$i -pad 0 -padding 0
page_titul ".fr$i" "logo_orel"
pack .fr$i -side top -anchor center -expand 1 -fill both -side top -padx 0 -pady 0
updatePentru a rula acest script, utilizăm una dintre utilitarele undroidwish sau vanillawish:
$ /usr/local/bin64/undroidwish-e5dc71ed9d-linux64 create_titul_page.tcl sau
$ /usr/local/bin64/vanillawish-e5dc71ed9d-linux64 create_titul_page.tcl Rezultatul este prezentat în prima captură de ecran.
Pe a doua pagină este enumerată funcționalitatea suportată de utilitarul cryptoarmpkcs-A. Fiecare linie este un buton, apăsând pe care se va afișa pagina funcțională. Geometria așezării butoanelor pe această pagină este determinată de fontul utilizat. Mai jos este prezentat scriptul create_page_functions.tcl pentru crearea celei de-a doua pagini funcționale a aplicației. Oricine poate, de asemenea, să-l editeze în funcție de funcțiile sale.
Scriptul create_page_functions.tcl
package require Tk
package require tkpath 0.3.0
global mydir
set mydir [file dirname [info script]]
#Увеличить/уменьшить (отрицательное значение - уменьшение)
proc scaleImage {im xfactor {yfactor 0}} {
set mode -subsample
if {$xfactor>=0 && $yfactor>=0} {
set mode -zoom
} else {
set xfactor [expr $xfactor * -1]
}
if {$yfactor == 0} {set yfactor $xfactor}
set t [image create photo]
$t copy $im
$im blank
$im copy $t -shrink $mode $xfactor $yfactor
image delete $t
}
proc createtile {w backg} {
image create photo tiled
tiled copy $backg -to 0 0 $::scrwidth $::scrheight -shrink
$backg copy tiled
image delete tiled
# Мостим холст
$w create image 0 0
-image $backg
-anchor nw
}
proc butCliked {num fr} {
pack forget .fr1
set ::tekFrfunc $fr
pack $fr -side top -anchor center -expand 1 -fill both -side top -padx 0 -pady 0
tk_dialog .dialog1 "Dear user:" "Button $num was clickednFr=$fr" info 0 OK
}
proc butImg {img} {
tk_messageBox -title "Кнопка" -icon info -message "Нажали кнопку=$img" -detail "::screenwidth=$::scrwidthn::screenheight=$::scrheight" -parent .
if {$img == "exit"} {
set answer [tk_dialog .dialog2 "Конец работы" "Вы действительноnхотите выйти?" question 0 "Да" "Нет" ]
if {$answer == 0} {
exit
}
}
}
proc butReturn {} {
pack forget $::tekFrfunc
pack .fr1 -side top -anchor center -expand 1 -fill both -side top -padx 0 -pady 0
# tk_dialog .dialog1 "Dear user:" "Button $num was clickednFr=$fr" info 0 OK
}
proc page_func {fr tile titul functions} {
#Кнопки меню
upvar $functions but
#Создаем шрифт для кнопок
if {$::typetlf} {
set feFONT_button "-family {Roboto} -size 9 -weight bold -slant roman"
set widl 10
} else {
set feFONT_button "-family {Arial} -size 12 -weight bold -slant roman"
set widl 5
}
catch {font delete fontTEMP_drawer}
eval font create fontTEMP_drawer $feFONT_button
#Вычисляем максимальныю длину текста
set drawerCNT 0
set strMaxWidthPx 15
set Ndrawers [expr {[array size but] - 1}]
while { $drawerCNT <= $Ndrawers } {
set strWidthPx [font measure fontTEMP_drawer "$but($drawerCNT)"]
if { $strWidthPx > $strMaxWidthPx } {
set strMaxWidthPx $strWidthPx
}
incr drawerCNT
}
set drawerWidthPx [expr $strMaxWidthPx + 10]
set xxx [expr {($::::scrwidth - $drawerWidthPx) / 2}]
if {$fr != ".fr1"} {
set hret [expr $::scrheight / 4]
} else {
set hret $::scrheight
}
set hret [expr $::scrheight / 4]
tkp::canvas $fr.can -borderwidth 0 -height $hret -width $::scrwidth -relief flat
#Мостим холст плиткой
createtile "$fr.can" $tile
pack $fr.can -anchor center -expand 1 -fill both -side top -padx 0 -pady 0
if {$titul != "" } {
set allfunc $titul
catch {font delete fontTEMP_titul}
set font_titul "-family {Roboto Condensed Medium} -size 15"
eval font create fontTEMP_titul $font_titul
set funcWidthPx [font measure fontTEMP_titul "$allfunc"]
set dlx [expr {($::::scrwidth - $funcWidthPx) / 2}]
$fr.can create text [expr $dlx + 6] [expr {6 + 6}] -anchor nw -text "$allfunc" -fill black -font fontTEMP_titul
$fr.can create text $dlx 6 -anchor nw -text "$allfunc" -fill white -font fontTEMP_titul -tag id_text0
set blogo [$fr.can bbox id_text0]
set boxbut [expr ([lindex $blogo 3] + 6 + 6)]
} else {
set boxbut [expr 6 + 6]
}
#Вычисляем самый широкий текст у кнопок
#См. выше
#Размещаем кнопки
set BDwidth_canvas 0
set maxTextHeightPx [font metrics fontTEMP_drawer -linespace]
set maxTextHeightPx [expr {$maxTextHeightPx + ( $maxTextHeightPx / 2)}]
set drawerHeightPx $maxTextHeightPx
set xLocTextPx [expr {($::::scrwidth - $drawerWidthPx) / 2}]
set yLocTextPx [expr $BDwidth_canvas + ($drawerHeightPx / 2) + $boxbut]
set canvasHeightPx [expr $Ndrawers * $drawerHeightPx]
set drawerCNT 0
set Ndrawers [expr {[array size but] - 1}]
while { $drawerCNT <= $Ndrawers } {
set yLineLocPx [ expr (( $drawerCNT ) * $drawerHeightPx + $boxbut)]
#Линия перед текстом
$fr.can create line
$xLocTextPx $yLineLocPx
[expr $drawerWidthPx + $xLocTextPx] $yLineLocPx
-fill "#a0a0a0" -width $widl
$fr.can create text [expr $xLocTextPx + 5] $yLocTextPx
-anchor w
-font fontTEMP_drawer
-text "$but($drawerCNT)"
-tag textlineTag($drawerCNT)
if {$drawerCNT == 0} {
if {$fr == ".fr1"} {
$fr.can bind textlineTag($drawerCNT) <ButtonRelease-1> {butImg "but1"}
} else {
$fr.can bind textlineTag($drawerCNT) <ButtonRelease-1> {butReturn}
}
} else {
frame .fn$drawerCNT -background white -relief flat -pady 0 -padx 0
set titul $but($drawerCNT)
set cmd "$fr.can bind textlineTag($drawerCNT) <ButtonRelease-1> {butCliked $drawerCNT .fn$drawerCNT}"
set cmd [subst "$cmd"]
eval $cmd
set but1(0) "Возврат в основное меню"
page_func ".fn$drawerCNT" voda "$titul" "but1"
}
incr drawerCNT
set yLocTextPx [ expr $yLocTextPx + $drawerHeightPx]
#Завершаюшая линия
if { $drawerCNT > $Ndrawers } {
set yLineLocPx [ expr (( $drawerCNT ) * $drawerHeightPx + $boxbut)]
$fr.can create line $xLocTextPx $yLineLocPx
[expr $drawerWidthPx + $xLocTextPx] $yLineLocPx
-fill "#a0a0a0" -width $widl
}
}
}
#Собственно скрипт
#Считываем размеры экрана
set ::scrwidth [winfo screenwidth .]
set ::scrheight [winfo screenheight .]
set ::typetlf 0
#Проверяем, что это телефон
if {$::scrwidth < $::scrheight} {
set ::typetlf 1
}
set ::padls 20
set ::padlx 15
set ::padly 15
if {$::typetlf} {
wm attributes . -fullscreen 1
#Логотип продуктв
scaleImage logo_product 2
set ::padls 50
set ::padlx 75
set ::padly 50
} else {
#Конфигурирование виджета под смартфон
set ::scrwidth 370
set ::scrheight 700
wm minsize . $::scrwidth $::scrheight
set geometr $::scrwidth
append geometr "x"
append geometr $::scrheight
append geometr "+0+0"
wm geometry . $geometr
}
#Грузим картинки
image create photo voda -file [file join $mydir "imageme" "voda_400x800.png"]
#Логотип продукта
image create photo logo_product -file [file join $mydir "imageme" "validcertkey_51x24.png"]
#Создаем название продукта
set name_product "CryptoArmPKCS-A"
label .labtitul -image logo_product -compound left -fg snow -text $name_product -font {Arial 10 bold} -anchor w -width [winfo screenwidth .] -pady $::padls -padx 10 -bg #222222
pack .labtitul -anchor nw -expand 0 -fill x -side top -padx 1 -pady 0
#Создаем страницы с функционалом
set i 1
ttk::frame .fr$i -pad 0 -padding 0
#Кнопки основного меню
set but(0) "Стартовая страница"
set but(1) "Подписать документ"
set but(2) "Работаем с ЭП (PKCS7)"
set but(3) "Запрос на сертификат"
set but(4) "Просмотр запроса/сертификата"
set but(5) "Список криптомеханизмов"
set but(6) "Просмотр ASN1-структуры"
set but(7) "Объекты токена"
set but(8) "Работаем с PKCS12/PFX"
set but(9) "Самоподписанный сертификат"
set but(10) "Об Утилите/Дистрибутивы"
set but(11) "Создать Токены"
set but(12) "Конфигурировние токена"
if {$::typetlf} {
scaleImage voda 3 2
}
#Создаем страницу с функционалом
page_func ".fr$i" voda "Функционал" "but"
#Отображаем страницу с функционалом
pack .fr$i -side top -anchor center -expand 1 -fill both -side top -padx 0 -pady 0 Acest script pregătește, de asemenea, șabloane pentru fiecare buton funcțional:

Umplerea șabloanelor se face cu widgeturi clasice și tematice (labelframe, button etc.). Una dintre aceste șabloane umplute se poate vedea în prima captură de ecran din dreapta. Deoarece în prima etapă ne-am concentrat pe lucrul cu containerul PKCS#12, codul a fost utilizat aproape fără modificări și pentru cryptoarmpkcs-A. În această etapă au fost implementate următoarele funcții:
- semnarea documentului (Cades-BES, CAdes-T, CAdes-XLT1);
- lucrăm cu EP (PKCS7), inclusiv adăugarea semnatarului;
- vizualizarea certificatelor/solicitărilor de certificate:

- lucrăm cu PKCS12/PFX;
- despre utilitar/distribuții:

Celelalte funcții sunt mai mult legate de tokenurile PKCS#11. Portarea acestora a fost amânată pentru Anul Nou. Se preconizează conectarea unui token software și conectarea la .
Din punct de vedere funcțional, aproape totul este similar cu utilitarul cryptoarmpkcs. Dar există diferențe distincte. De exemplu, după semnarea documentului, utilitarul întreabă dacă semnătura va fi verificată pe site-ul Guvernului:

Apăsând butonul „Da”, va fi deschis un browser cu pagina de verificare a semnăturilor documentelor și certificatelor. Să precizăm imediat că această pagină nu este prea adaptată pentru ecranul smartphone-ului. Acest lucru va fi evident la alegerea semnăturii și, dacă semnătura este deconectată, a fișierului documentului. Dar dacă totul este în regulă, vom obține un rezultat pozitiv:

Trebuie avut în vedere că verificarea atât a semnăturii, cât și a certificatului pe site-ul Guvernului are sens doar dacă certificatul a fost obținut de la un centru de autorizare acreditat (). În caz contrar, semnătura va fi întotdeauna invalidă.
Pentru a deschide browserul, a fost necesar să adaug câteva linii în procedura openUrl:
proc openURL {url} {
global typesys
global macos
# global windowsOS
# verificare că utilitarul este executat pe un smartphone Android
if {$::typetlf} {
# Lansarea browserului
borg activity android.intent.action.VIEW $url text/html
return
}
. . .
}Browserul pe Android este apelat astfel:
borg activity android.intent.action.VIEW text/html
Există o mică particularitate la adăugarea unui nou semnatar la un document deja semnat. Certificatul noului semnatar (mai precis, containerul PKCS#12 cu certificatul și cheia privată) trebuie să fie ales în prealabil pe pagina „Semnează documentul” sau „Lucrăm cu PKCS12/PFX”, ceea ce va fi reamintit de utilitar:

Pentru operațiuni îndelungate, ca și înainte, vor rula ceasurile:

Rămâne să spunem de unde pot fi descărcate distribuțiile și să le urăm tuturor un An Nou fericit și toate cele bune în 2020!
Deci, distribuțiile pentru Linux, OS X, Windows și Android:
Sursa: habr.com


