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
|
#include "includes.h"
#if DROPBEAR_SK_ED25519
#include "dbutil.h"
#include "buffer.h"
#include "curve25519.h"
#include "ed25519.h"
#include "ssh.h"
int buf_sk_ed25519_verify(buffer *buf, const dropbear_ed25519_key *key, const buffer *data_buf, const char* app, unsigned int applen) {
int ret = DROPBEAR_FAILURE;
unsigned char *s;
unsigned long slen;
hash_state hs;
unsigned char hash[SHA256_HASH_SIZE];
buffer *sk_buffer = NULL;
unsigned char flags;
unsigned int counter;
TRACE(("enter buf_sk_ed25519_verify"))
dropbear_assert(key != NULL);
slen = buf_getint(buf);
if (slen != 64 || buf->len - buf->pos < slen) {
TRACE(("leave buf_sk_ed25519_verify: bad size"))
goto out;
}
s = buf_getptr(buf, slen);
buf_incrpos(buf, slen);
flags = buf_getbyte (buf);
counter = buf_getint (buf);
/* create the message to be signed */
sk_buffer = buf_new (2*SHA256_HASH_SIZE+5);
sha256_init (&hs);
sha256_process (&hs, app, applen);
sha256_done (&hs, hash);
buf_putbytes (sk_buffer, hash, sizeof (hash));
buf_putbyte (sk_buffer, flags);
buf_putint (sk_buffer, counter);
sha256_init (&hs);
sha256_process (&hs, data_buf->data, data_buf->len);
sha256_done (&hs, hash);
buf_putbytes (sk_buffer, hash, sizeof (hash));
if (dropbear_ed25519_verify(sk_buffer->data, sk_buffer->len,
s, slen, key->pub) == 0) {
/* signature is valid */
TRACE(("leave buf_sk_ed25519_verify: success!"))
ret = DROPBEAR_SUCCESS;
}
/* TODO: allow "no-touch-required" or "verify-required" authorized_keys options */
if (!(flags & SSH_SK_USER_PRESENCE_REQD)) {
if (ret == DROPBEAR_SUCCESS) {
dropbear_log(LOG_WARNING, "Rejecting, user-presence not set");
}
ret = DROPBEAR_FAILURE;
}
out:
buf_free(sk_buffer);
TRACE(("leave buf_sk_ed25519_verify: ret %d", ret))
return ret;
}
#endif /* DROPBEAR_SK_ED25519 */
|