Subversion Repositories Kolibri OS

Rev

Rev 9106 | Rev 9113 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
9106 hidnplayr 1
;    sshlib_host.inc - SSH remote host authentication
2
;
3
;    Copyright (C) 2021 Jeffrey Amelynck
4
;
5
;    This program is free software: you can redistribute it and/or modify
6
;    it under the terms of the GNU General Public License as published by
7
;    the Free Software Foundation, either version 3 of the License, or
8
;    (at your option) any later version.
9
;
10
;    This program is distributed in the hope that it will be useful,
11
;    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
;    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
;    GNU General Public License for more details.
14
;
15
;    You should have received a copy of the GNU General Public License
16
;    along with this program.  If not, see .
17
 
18
; https://datatracker.ietf.org/doc/html/rfc4253#section-6.6
19
; https://datatracker.ietf.org/doc/html/rfc3447
20
 
9112 hidnplayr 21
; https://datatracker.ietf.org/doc/html/rfc4716
22
 
9106 hidnplayr 23
proc sshlib_host_verify  con_ptr, str_host_key, str_signature, message, message_len
24
 
25
locals
9112 hidnplayr 26
        current_hkb64           rb MAX_PUBLIC_KEY_SIZE*4        ; Current Host key in Base64
27
        cached_hkb64            rb MAX_PUBLIC_KEY_SIZE*4        ; Cached Host key in Base64
28
        key_name_sz             dd ?
29
        hostname_sz             dd ?
30
        current_hk64_end        dd ?
9106 hidnplayr 31
endl
32
 
33
        mov     eax, [con_ptr]
9112 hidnplayr 34
        lea     ebx, [eax + sshlib_connection.hostname_sz]
35
        mov     [hostname_sz], ebx
9106 hidnplayr 36
        cmp     [eax+sshlib_connection.algo_hostkey], SSHLIB_HOSTKEY_RSA
37
        je      .rsa
38
        ; ..add more here
39
        mov     eax, SSHLIB_ERR_HKEY_NO_ALGO
40
        ret
41
 
42
  .rsa:
43
        stdcall sshlib_host_verify_rsa, [str_host_key], [str_signature], [message], [message_len]
44
        test    eax, eax
45
        jnz     .err
9112 hidnplayr 46
        mov     [key_name_sz], ssh_rsa_sz
9106 hidnplayr 47
 
48
  .lookup:
9112 hidnplayr 49
; Convert the current host key to base64
50
        mov     esi, [str_host_key]
51
        mov     ecx, [esi]
52
        bswap   ecx
53
        add     esi, 4
54
        lea     edi, [current_hkb64]
55
        call    base64_encode
56
        mov     [current_hk64_end], edi
9106 hidnplayr 57
 
9112 hidnplayr 58
; Try to read the cached key for this host and key type
59
        lea     edi, [cached_hkb64]
60
        invoke  ini_get_str, known_hostsfile, [hostname_sz], [key_name_sz], edi, MAX_PUBLIC_KEY_SIZE*4, 0
61
        test    eax, eax
62
        jnz     .unknown
63
; If the cached key is empty, return SSHLIB_HOSTKEY_PROBLEM_UNKNOWN
64
        lea     esi, [cached_hkb64]
65
        cmp     byte[esi], 0
66
        je      .unknown
67
; Else, compare it to the current one
68
        lea     edi, [current_hkb64]
69
        mov     ecx, MAX_PUBLIC_KEY_SIZE*4
70
  .cmploop:
71
        lodsb
72
        scasb
73
        jne     .mismatch
74
        test    al, al
75
        jz      .match
76
        dec     ecx
77
        jnz     .cmploop
78
        jmp     .mismatch
9106 hidnplayr 79
 
9112 hidnplayr 80
  .match:
9106 hidnplayr 81
        xor     eax, eax
82
        ret
83
 
84
  .mismatch:
9112 hidnplayr 85
int3
86
        lea     eax, [current_hkb64]
9106 hidnplayr 87
        stdcall sshlib_callback_hostkey_problem, [con_ptr], SSHLIB_HOSTKEY_PROBLEM_MISMATCH, eax
88
        cmp     eax, SSHLIB_HOSTKEY_ACCEPT
89
        je      .store
90
        ret
91
 
92
  .unknown:
9112 hidnplayr 93
        lea     eax, [current_hkb64]
9106 hidnplayr 94
        stdcall sshlib_callback_hostkey_problem, [con_ptr], SSHLIB_HOSTKEY_PROBLEM_UNKNOWN, eax
95
        cmp     eax, SSHLIB_HOSTKEY_ACCEPT
96
        je      .store
97
        ret
98
 
99
  .store:
9112 hidnplayr 100
        lea     esi, [current_hkb64]
101
        mov     ecx, [current_hk64_end]
102
        sub     ecx, esi
103
        invoke  ini_set_str, known_hostsfile, [hostname_sz], [key_name_sz], esi, ecx
104
        xor     eax, eax
9106 hidnplayr 105
        ret
106
 
107
  .err:
108
        ret
109
 
110
endp
111
 
112
 
113
; https://datatracker.ietf.org/doc/html/rfc3447#section-8.2.2
114
; RSASSA-PKCS1-V1_5-VERIFY
115
proc sshlib_host_verify_rsa str_host_key, str_signature, M, message_len
116
 
117
locals
118
        h_ctx                   dd ?
119
 
120
; Signer's RSA public key
121
        mpint_e                 dd ?    ; public exponent
122
        mpint_n                 dd ?    ; modulus
123
 
124
        mpint_m                 dd ?
125
 
126
        EM                      dd ?
127
        EM_accent               dd ?
128
 
129
        mpint_s                 dd ?    ; rsa_signature_blob
130
 
131
 
132
;        k       dd ?    ; length of RSA modulus n
133
 
134
endl
135
 
136
        DEBUGF  3, "SSH: Performing RSA verification\n"
137
 
138
        mcall   68, 12, sizeof.crash_ctx + 5*(MAX_BITS/8+4)
139
        test    eax, eax
140
        jz      .err_nomem
141
        mov     [h_ctx], eax
142
        add     eax, sizeof.crash_ctx
143
        mov     [mpint_e], eax
144
        add     eax, MAX_BITS/8+4
145
        mov     [mpint_n], eax
146
        add     eax, MAX_BITS/8+4
147
        mov     [mpint_m], eax
148
        add     eax, MAX_BITS/8+4
149
        mov     [EM], eax
150
        add     eax, MAX_BITS/8+4
151
        mov     [EM_accent], eax
152
        add     eax, MAX_BITS/8+4
153
        mov     [mpint_s], eax
154
;        add     eax, MAX_BITS/8+4
155
 
156
; Host key
157
        mov     esi, [str_host_key]
158
        mov     ecx, [esi]
159
        bswap   ecx
160
        cmp     ecx, MAX_PUBLIC_KEY_SIZE
161
        ja      .err_key
162
; Host key type (string)
163
        cmp     dword[esi+4], 0x07000000
164
        jne     .err_key
165
        cmp     dword[esi+8], 'ssh-'
166
        jne     .err_key
167
        cmp     dword[esi+11], '-rsa'
168
        jne     .err_key
169
        add     esi, 4+4+7
170
; mpint e
171
        stdcall mpint_to_little_endian, [mpint_e], esi
172
        add     esi, eax
173
        add     esi, 4
174
; mpint n
175
        stdcall mpint_to_little_endian, [mpint_n], esi
176
;        mov     [k], eax             ;; HMMMM FIXME, 0-byte..
177
 
178
; Signature
179
        mov     esi, [str_signature]
180
        mov     ecx, [esi]
181
        bswap   ecx             ; TODO: check length
182
; Host key type (string)
183
        cmp     dword[esi+4], 0x07000000
184
        jne     .err_signature
185
        cmp     dword[esi+8], 'ssh-'
186
        jne     .err_signature
187
        cmp     dword[esi+11], '-rsa'
188
        jne     .err_signature
189
        add     esi, 4+4+7
190
; RSA signature blob
191
        stdcall mpint_to_little_endian, [mpint_s], esi
192
;        cmp     eax, [k]
193
 ;;;       jne     .err_signature
194
 
195
; RSAVP1
196
        stdcall mpint_modexp, [mpint_m], [mpint_s], [mpint_e], [mpint_n]
197
; I2OSP
198
        stdcall mpint_shrink, [mpint_m]
199
        stdcall mpint_grow, [mpint_m], 256
200
        stdcall mpint_to_big_endian, [EM], [mpint_m]
201
 
202
; EMSA-PKCS1-v1_5
203
        invoke  sha1_init, [h_ctx]
204
        invoke  sha1_update, [h_ctx], [M], [message_len]
205
        invoke  sha1_final, [h_ctx]
206
 
207
        mov     edi, [EM_accent]
208
        mov     al, 0x00
209
        stosb
210
        mov     al, 0x01
211
        stosb
212
        mov     ecx, 256 - (rsa_sha1_t.len + 3 + SHA1_HASH_SIZE)
213
        mov     al, 0xff
214
        rep stosb
215
        mov     al, 0x00
216
        stosb
217
        mov     esi, rsa_sha1_t
218
        mov     ecx, rsa_sha1_t.len
219
        rep movsb
220
        mov     esi, [h_ctx]
221
        mov     ecx, SHA1_HASH_SIZE
222
        rep movsb
223
 
224
; Compare EM with EM_accent
225
        mov     esi, [EM]
226
        add     esi, 4
227
        mov     edi, [EM_accent]
228
        mov     ecx, 256/4
229
        xor     eax, eax
230
  .ct_cmp_loop:
231
        mov     ebx, [esi]
232
        xor     ebx, [edi]
233
        or      eax, ebx
234
        lea     esi, [esi+4]
235
        lea     edi, [edi+4]
236
        dec     ecx
237
        jnz     .ct_cmp_loop
238
 
239
        push    eax
240
        mcall   68, 13, [h_ctx]
241
        pop     eax
242
 
243
        test    eax, eax
244
        jnz     .fail
245
 
246
        DEBUGF  3, "SSH: RSA verification OK!\n"
247
 
248
        ret
249
 
250
  .fail:
251
        DEBUGF  3, "SSH: RSA verification failed!\n"
252
        mov     eax, SSHLIB_ERR_HKEY_VERIFY_FAIL
253
        ret
254
 
255
  .err_nomem:
256
        mov     eax, SSHLIB_ERR_NOMEM
257
        ret
258
 
259
  .err_signature:
260
        mov     eax, SSHLIB_ERR_HKEY_SIGNATURE
261
        ret
262
 
263
  .err_key:
264
        mov     eax, SSHLIB_ERR_HKEY_PUBLIC_KEY
265
        ret
266
 
267
endp
268
 
269
 
9112 hidnplayr 270
base64_encode:
271
 
272
        xor     ebx, ebx
273
  .loop:
274
        lodsb
275
        call    .byte
276
        dec     ecx
277
        jnz     .loop
278
 
279
  .final:
280
        mov     al, 0
281
        test    ebx, ebx
282
        jz      .f000
283
        call    .byte
284
        test    ebx, ebx
285
        jz      .f001
286
        call    .byte
287
        mov     byte[edi-2], '='
288
 
289
  .f001:
290
        mov     byte[edi-1], '='
291
 
292
  .f000:
293
        mov     byte[edi], 0
294
        ret
295
 
296
  .byte:
297
        inc     ebx
298
        shl     edx, 8
299
        mov     dl, al
300
        cmp     ebx, 3
301
        je      .b001
302
        ret
303
 
304
  .b001:
305
        shl     edx, 8
306
        inc     ebx
307
 
308
  .b002:
309
        rol     edx, 6
310
        xor     eax, eax
311
        xchg    al, dl
312
        mov     al, [base64_table+eax]
313
        stosb
314
        dec     ebx
315
        jnz     .b002
316
        ret
317
 
318
 
319
 
320
 
9106 hidnplayr 321
iglobal
322
 
9112 hidnplayr 323
        known_hostsfile db '/sys/settings/known_hosts.ini', 0
324
        base64_table    db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
9106 hidnplayr 325
        rsa_sha1_t      db 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14
326
        .len = $ - rsa_sha1_t
9112 hidnplayr 327
        ssh_rsa_sz      db 'ssh-rsa', 0
9106 hidnplayr 328
 
329
endg
330