-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmain.gd
129 lines (98 loc) · 3.8 KB
/
main.gd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
extends Control
@onready var msg: TextEdit = $MarginContainer/HBoxContainer/VBoxContainer2/Message
@onready var sig: TextEdit = $MarginContainer/HBoxContainer/VBoxContainer2/Signature
const private_file = "private.rsa"
const public_file = "public.rsa"
var rsa = Crypto.new()
var privateKey: CryptoKey
var publicKey: CryptoKey
func _on_btn_generate_pressed() -> void:
var cryptoKey := rsa.generate_rsa(2048)
var err: Error
err = cryptoKey.save(private_file)
if err != 0:
msg.text = "Failed to save private key file. Error %s" % err
return
# The second parameter to CryptoKey.save indicates it should only save the
# public portion of the key. This can be verified by reading the resulting
# output file in a text editor.
err = cryptoKey.save(public_file, true)
if err != 0:
msg.text = "Failed to save public key file. Error %s" % err
return
msg.text = "Generated new keypair. You may now load either key."
func _on_btn_unload_pressed() -> void:
privateKey = null
publicKey = null
msg.text = "Unloaded all keys"
func _on_btn_load_private_pressed() -> void:
publicKey = null
privateKey = CryptoKey.new()
var err := privateKey.load(private_file)
if err != null and err != 0:
msg.text = "Failed to load private key. Error %s. Try generating a new pair." % err
else:
msg.text = "Successfully loaded private key"
func _on_btn_load_public_pressed() -> void:
privateKey = null
publicKey = CryptoKey.new()
# As with the call to CryptoKey.save when we generate the keypair, the second
# argument here being set to true indicates that we are only expecting to load
# the PUBLIC portion of the key. Attempting to load the public file without
# passing true in the second parameter will result in an error, since the file
# only contains the public key.
var err := publicKey.load(public_file, true)
if err != 0:
msg.text = "Failed to load public key. Error %s. Try generating a new pair." % err
else:
msg.text = "Successfully loaded public key"
func _on_btn_sign_pressed() -> void:
if privateKey == null:
sig.text = "No private key loaded. Please generate and load private key before signing."
return
var digest := get_message_digest()
var signature := rsa.sign(HashingContext.HASH_SHA256, digest, privateKey)
sig.text = signature.hex_encode()
# get_message_digest implements SHA256 hashing on a variable-sized text buffer.
# This is a required step in order to sign or verify using RSA. For a brief
# overview of why, see https://crypto.stackexchange.com/questions/12768/why-hash-the-message-before-signing-it-with-rsa
func get_message_digest() -> PackedByteArray:
var clearText := msg.text
if clearText.length() == 0 or clearText == null:
push_error("No cleartext present!")
return PackedByteArray()
var bytes := clearText.to_ascii_buffer()
var buffer := PackedByteArray()
buffer.resize(1024)
buffer.fill(0)
var ctx := HashingContext.new()
ctx.start(HashingContext.HASH_SHA256)
var partial := false
for i in range(bytes.size()):
buffer[i % 1024] = bytes[i]
partial = true
if i % 1024 == 0 and i != 0:
partial = false
ctx.update(buffer)
buffer.fill(0)
if partial:
ctx.update(buffer)
return ctx.finish()
func _on_btn_verify_pressed() -> void:
if publicKey == null:
sig.text = "No public key loaded. Please generate and load public key before verifying."
return
var clearText := msg.text
var signature := sig.text
if clearText.length() == 0 or signature.length() == 0:
msg.text = "Please enter a message and its signature before attempting verification."
return
var digest := get_message_digest()
var sigBytes := signature.hex_decode()
var valid = rsa.verify(HashingContext.HASH_SHA256, digest, sigBytes, publicKey)
if valid:
sig.text = "Signature verified!"
else:
sig.text = "Signature not valid!"
func _on_btn_exit_pressed() -> void:
get_tree().quit()