Skip to content

Commit d5c646a

Browse files
committed
add mynaqt
1 parent 1ffaa48 commit d5c646a

File tree

7 files changed

+837
-0
lines changed

7 files changed

+837
-0
lines changed

mynaqt/Makefile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
2+
mynaqt: *.go
3+
go build
4+
5+
run: *.go
6+
go run $^
7+
8+
clean:
9+
rm -rf mynaqt
10+

mynaqt/about.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"github.com/jpki/myna/libmyna"
6+
"github.com/therecipe/qt/core"
7+
"github.com/therecipe/qt/gui"
8+
"github.com/therecipe/qt/widgets"
9+
)
10+
11+
type AboutDialog struct {
12+
*widgets.QDialog
13+
}
14+
15+
func NewAboutDialog() *AboutDialog {
16+
windowFlag := core.Qt__Window | core.Qt__WindowCloseButtonHint
17+
dialog := widgets.NewQDialog(nil, windowFlag)
18+
dialog.SetModal(true)
19+
dialog.SetMinimumSize2(400, 0)
20+
dialog.SetWindowTitle("マイナクライアント(GUI版)について")
21+
layout := widgets.NewQVBoxLayout()
22+
// add logo
23+
logoLabel := widgets.NewQLabel(nil, 0)
24+
logoData, err := Asset("usagi.png")
25+
if err != nil {
26+
return nil
27+
}
28+
pixmap := gui.NewQPixmap()
29+
pixmap.LoadFromData(string(logoData), uint(len(logoData)),
30+
"PNG", core.Qt__AutoColor)
31+
logoLabel.SetPixmap(pixmap)
32+
layout.AddWidget(logoLabel, 0, core.Qt__AlignCenter)
33+
34+
// add version
35+
label := widgets.NewQLabel2(
36+
fmt.Sprintf("mynaqt %s", libmyna.Version), nil, 0)
37+
layout.AddWidget(label, 0, core.Qt__AlignCenter)
38+
39+
// add url
40+
url := "https://github.com/jpki/myna"
41+
urlButton := widgets.NewQPushButton2(url, nil)
42+
urlButton.ConnectClicked(func(bool) {
43+
gui.QDesktopServices_OpenUrl(core.NewQUrl3(url, 0))
44+
})
45+
layout.AddWidget(urlButton, 0, 0)
46+
47+
label = widgets.NewQLabel2(
48+
`
49+
このソフトウェアはMITライセンスで開発されています。
50+
Qt は LGPLライセンス
51+
かわいいウサギのイラストはいらすとやの著作物です`, nil, 0)
52+
layout.AddWidget(label, 0, 0)
53+
buttons := widgets.NewQDialogButtonBox(nil)
54+
closeButton := widgets.NewQPushButton2("閉じる", nil)
55+
closeButton.ConnectClicked(func(bool) { dialog.Close() })
56+
buttons.AddButton(closeButton, widgets.QDialogButtonBox__RejectRole)
57+
layout.AddWidget(buttons, 0, 0)
58+
dialog.SetLayout(layout)
59+
return &AboutDialog{dialog}
60+
}

mynaqt/bindata.go

Lines changed: 260 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mynaqt/cert.go

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
package main
2+
3+
import (
4+
"crypto/x509"
5+
"github.com/jpki/myna/libmyna"
6+
"github.com/therecipe/qt/core"
7+
"github.com/therecipe/qt/widgets"
8+
)
9+
10+
type SelectCertDialog struct {
11+
*widgets.QDialog
12+
}
13+
14+
func NewSelectCertDialog() *SelectCertDialog {
15+
windowFlag := core.Qt__Window | core.Qt__WindowCloseButtonHint
16+
dialog := widgets.NewQDialog(nil, windowFlag)
17+
dialog.SetModal(true)
18+
dialog.SetMinimumSize2(300, 300)
19+
dialog.SetWindowTitle("証明書選択")
20+
21+
radio1 := widgets.NewQRadioButton2("認証用証明書", nil)
22+
radio2 := widgets.NewQRadioButton2("署名用証明書", nil)
23+
radio3 := widgets.NewQRadioButton2("認証用CA証明書", nil)
24+
radio4 := widgets.NewQRadioButton2("署名用CA証明書", nil)
25+
radio1.SetChecked(true)
26+
27+
layout := widgets.NewQVBoxLayout()
28+
layout.AddWidget(radio1, 0, 0)
29+
layout.AddWidget(radio2, 0, 0)
30+
layout.AddWidget(radio3, 0, 0)
31+
layout.AddWidget(radio4, 0, 0)
32+
33+
group := widgets.NewQButtonGroup(nil)
34+
group.AddButton(radio1, 1)
35+
group.AddButton(radio2, 2)
36+
group.AddButton(radio3, 3)
37+
group.AddButton(radio4, 4)
38+
39+
buttons := widgets.NewQDialogButtonBox(nil)
40+
closeButton := widgets.NewQPushButton2("閉じる", nil)
41+
closeButton.ConnectClicked(func(bool) { dialog.Close() })
42+
43+
showButton := widgets.NewQPushButton2("表示", nil)
44+
showButton.ConnectClicked(func(bool) {
45+
id := group.CheckedId()
46+
var name string
47+
var ef string
48+
var password string
49+
if id == 1 {
50+
name = "認証用証明書"
51+
ef = "00 0A"
52+
} else if id == 2 {
53+
name = "署名用証明書"
54+
ef = "00 01"
55+
prompt := NewPasswordPromptDialog()
56+
rc := prompt.Exec()
57+
if rc != int(widgets.QDialog__Accepted) {
58+
return
59+
}
60+
password = prompt.GetPin()
61+
} else if id == 3 {
62+
name = "認証用CA証明書"
63+
ef = "00 0B"
64+
} else if id == 4 {
65+
name = "署名用CA証明書"
66+
ef = "00 02"
67+
} else {
68+
return
69+
}
70+
71+
cert, err := libmyna.GetCert(ctx, ef, password)
72+
if err != nil {
73+
widgets.QMessageBox_Warning(nil, "エラー", err.Error(),
74+
widgets.QMessageBox__Ok, 0)
75+
return
76+
}
77+
certDialog := NewShowCertDialog(name, cert)
78+
certDialog.Show()
79+
})
80+
81+
buttons.AddButton(closeButton, widgets.QDialogButtonBox__RejectRole)
82+
buttons.AddButton(showButton, widgets.QDialogButtonBox__AcceptRole)
83+
layout.AddWidget(buttons, 0, 0)
84+
dialog.SetLayout(layout)
85+
return &SelectCertDialog{dialog}
86+
}
87+
88+
type ShowCertDialog struct {
89+
*widgets.QDialog
90+
}
91+
92+
func NewShowCertDialog(name string, cert *x509.Certificate) *ShowCertDialog {
93+
if cert == nil {
94+
widgets.QMessageBox_Warning(nil, "エラー", "証明書がみつかりません",
95+
widgets.QMessageBox__Ok, 0)
96+
return nil
97+
/*
98+
data, _ := ioutil.ReadFile("../test.pem")
99+
block, _ := pem.Decode(data)
100+
cert, _ = x509.ParseCertificate(block.Bytes)
101+
*/
102+
}
103+
104+
windowFlag := core.Qt__Window | core.Qt__WindowCloseButtonHint
105+
dialog := widgets.NewQDialog(nil, windowFlag)
106+
dialog.SetModal(true)
107+
dialog.SetWindowTitle("証明書ビューア: " + name)
108+
dialog.SetMinimumSize2(600, 400)
109+
110+
layout := widgets.NewQVBoxLayout()
111+
labelSubject := widgets.NewQLabel2("発行先", nil, 0)
112+
layout.AddWidget(labelSubject, 0, 0)
113+
textSubject := widgets.NewQLineEdit(dialog)
114+
textSubject.SetReadOnly(true)
115+
textSubject.SetText(libmyna.Name2String(cert.Subject))
116+
textSubject.AdjustSize()
117+
layout.AddWidget(textSubject, 0, 0)
118+
119+
labelIssuer := widgets.NewQLabel2("発行元", nil, 0)
120+
layout.AddWidget(labelIssuer, 0, 0)
121+
textIssuer := widgets.NewQLineEdit(nil)
122+
textIssuer.SetReadOnly(true)
123+
textIssuer.SetText(libmyna.Name2String(cert.Issuer))
124+
layout.AddWidget(textIssuer, 0, 0)
125+
126+
labelNotBefore := widgets.NewQLabel2("発行日", nil, 0)
127+
layout.AddWidget(labelNotBefore, 0, 0)
128+
textNotBefore := widgets.NewQLineEdit(nil)
129+
textNotBefore.SetReadOnly(true)
130+
textNotBefore.SetText(cert.NotBefore.Local().String())
131+
layout.AddWidget(textNotBefore, 0, 0)
132+
133+
labelNotAfter := widgets.NewQLabel2("有効期限", nil, 0)
134+
layout.AddWidget(labelNotAfter, 0, 0)
135+
textNotAfter := widgets.NewQLineEdit(nil)
136+
textNotAfter.SetReadOnly(true)
137+
textNotAfter.SetText(cert.NotAfter.Local().String())
138+
layout.AddWidget(textNotAfter, 0, 0)
139+
140+
buttons := widgets.NewQDialogButtonBox(nil)
141+
closeButton := widgets.NewQPushButton2("閉じる", nil)
142+
closeButton.ConnectClicked(func(bool) { dialog.Close() })
143+
buttons.AddButton(closeButton, widgets.QDialogButtonBox__RejectRole)
144+
layout.AddWidget(buttons, 0, 0)
145+
146+
dialog.SetLayout(layout)
147+
return &ShowCertDialog{dialog}
148+
}

mynaqt/cms.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package main
2+
3+
import (
4+
"github.com/jpki/myna/libmyna"
5+
"github.com/therecipe/qt/core"
6+
"github.com/therecipe/qt/widgets"
7+
)
8+
9+
type CmsSignDialog struct {
10+
*widgets.QDialog
11+
}
12+
13+
func NewCmsSignDialog() *CmsSignDialog {
14+
windowFlag := core.Qt__Window | core.Qt__WindowCloseButtonHint
15+
dialog := widgets.NewQDialog(nil, windowFlag)
16+
dialog.SetModal(true)
17+
dialog.SetMinimumSize2(500, 0)
18+
dialog.SetWindowTitle("CMS署名")
19+
20+
layout := widgets.NewQVBoxLayout()
21+
layout.AddWidget(widgets.NewQLabel2("入力ファイル", nil, 0), 0, 0)
22+
23+
row := widgets.NewQHBoxLayout()
24+
inputFileEdit := widgets.NewQLineEdit(nil)
25+
outputFileEdit := widgets.NewQLineEdit(nil)
26+
inputFileEdit.SetReadOnly(true)
27+
inputFileEdit.SetSizePolicy2(
28+
widgets.QSizePolicy__Expanding,
29+
widgets.QSizePolicy__Ignored)
30+
row.AddWidget(inputFileEdit, 0, 0)
31+
inputFileButton := widgets.NewQPushButton2("選択", nil)
32+
inputFileButton.ConnectClicked(func(bool) {
33+
dialog := widgets.NewQFileDialog2(nil, "入力ファイル", "", "")
34+
dialog.SetFileMode(widgets.QFileDialog__ExistingFile)
35+
rc := dialog.Exec()
36+
if rc != int(widgets.QDialog__Accepted) {
37+
return
38+
}
39+
filename := dialog.SelectedFiles()[0]
40+
inputFileEdit.SetText(filename)
41+
if outputFileEdit.Text() == "" {
42+
outputFileEdit.SetText(filename + ".p7s")
43+
}
44+
})
45+
row.AddWidget(inputFileButton, 0, 0)
46+
layout.AddLayout(row, 0)
47+
48+
layout.AddWidget(widgets.NewQLabel2("出力ファイル", nil, 0), 0, 0)
49+
row = widgets.NewQHBoxLayout()
50+
outputFileEdit.SetReadOnly(true)
51+
outputFileEdit.SetSizePolicy2(
52+
widgets.QSizePolicy__Expanding,
53+
widgets.QSizePolicy__Ignored)
54+
row.AddWidget(outputFileEdit, 0, 0)
55+
outputFileButton := widgets.NewQPushButton2("選択", nil)
56+
outputFileButton.ConnectClicked(func(bool) {
57+
dialog := widgets.NewQFileDialog2(nil, "出力ファイル", "", "")
58+
dialog.SetAcceptMode(widgets.QFileDialog__AcceptSave)
59+
rc := dialog.Exec()
60+
if rc != int(widgets.QDialog__Accepted) {
61+
return
62+
}
63+
filename := dialog.SelectedFiles()[0]
64+
outputFileEdit.SetText(filename)
65+
})
66+
row.AddWidget(outputFileButton, 0, 0)
67+
layout.AddLayout(row, 0)
68+
69+
buttons := widgets.NewQDialogButtonBox(nil)
70+
closeButton := widgets.NewQPushButton2("閉じる", nil)
71+
closeButton.ConnectClicked(func(bool) { dialog.Close() })
72+
signButton := widgets.NewQPushButton2("署名", nil)
73+
signButton.ConnectClicked(func(bool) {
74+
if inputFileEdit.Text() == "" {
75+
widgets.QMessageBox_Warning(nil, "エラー",
76+
"入力ファイルを選択してください",
77+
widgets.QMessageBox__Ok, 0)
78+
return
79+
}
80+
if outputFileEdit.Text() == "" {
81+
widgets.QMessageBox_Warning(nil, "エラー",
82+
"出力ファイルを選択してください",
83+
widgets.QMessageBox__Ok, 0)
84+
return
85+
}
86+
prompt := NewPasswordPromptDialog()
87+
rc := prompt.Exec()
88+
if rc != int(widgets.QDialog__Accepted) {
89+
return
90+
}
91+
password := prompt.GetPin()
92+
err := libmyna.Sign(ctx, password,
93+
inputFileEdit.Text(), outputFileEdit.Text())
94+
if err != nil {
95+
widgets.QMessageBox_Warning(nil, "エラー", err.Error(),
96+
widgets.QMessageBox__Ok, 0)
97+
return
98+
}
99+
widgets.QMessageBox_Information(nil, "CMS署名",
100+
"正常に署名しました",
101+
widgets.QMessageBox__Ok, 0)
102+
return
103+
dialog.Close()
104+
})
105+
buttons.AddButton(signButton, widgets.QDialogButtonBox__AcceptRole)
106+
buttons.AddButton(closeButton, widgets.QDialogButtonBox__RejectRole)
107+
layout.AddWidget(buttons, 0, 0)
108+
dialog.SetLayout(layout)
109+
return &CmsSignDialog{dialog}
110+
}

0 commit comments

Comments
 (0)