| /* |
| * libwebsockets - small server side websockets and web server implementation |
| * |
| * Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com> |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy |
| * of this software and associated documentation files (the "Software"), to |
| * deal in the Software without restriction, including without limitation the |
| * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
| * sell copies of the Software, and to permit persons to whom the Software is |
| * furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in |
| * all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| * IN THE SOFTWARE. |
| */ |
| |
| #if !defined(__LWS_SSH_H__) |
| #define __LWS_SSH_H__ |
| |
| #if defined(LWS_HAVE_SYS_TYPES_H) |
| #include <sys/types.h> |
| #endif |
| |
| #if defined(LWS_WITH_MBEDTLS) |
| #include "mbedtls/sha1.h" |
| #include "mbedtls/sha256.h" |
| #include "mbedtls/sha512.h" |
| #include "mbedtls/rsa.h" |
| #endif |
| |
| #include "lws-plugin-ssh.h" |
| |
| #define LWS_SIZE_EC25519 32 |
| #define LWS_SIZE_EC25519_PUBKEY 32 |
| #define LWS_SIZE_EC25519_PRIKEY 64 |
| |
| #define LWS_SIZE_SHA256 32 |
| #define LWS_SIZE_SHA512 64 |
| |
| #define LWS_SIZE_AES256_KEY 32 |
| #define LWS_SIZE_AES256_IV 12 |
| #define LWS_SIZE_AES256_MAC 16 |
| #define LWS_SIZE_AES256_BLOCK 16 |
| |
| #define LWS_SIZE_CHACHA256_KEY (2 * 32) |
| #define POLY1305_TAGLEN 16 |
| #define POLY1305_KEYLEN 32 |
| |
| #define crypto_hash_sha512_BYTES 64U |
| |
| #define PEEK_U64(p) \ |
| (((uint64_t)(((const uint8_t *)(p))[0]) << 56) | \ |
| ((uint64_t)(((const uint8_t *)(p))[1]) << 48) | \ |
| ((uint64_t)(((const uint8_t *)(p))[2]) << 40) | \ |
| ((uint64_t)(((const uint8_t *)(p))[3]) << 32) | \ |
| ((uint64_t)(((const uint8_t *)(p))[4]) << 24) | \ |
| ((uint64_t)(((const uint8_t *)(p))[5]) << 16) | \ |
| ((uint64_t)(((const uint8_t *)(p))[6]) << 8) | \ |
| (uint64_t)(((const uint8_t *)(p))[7])) |
| #define PEEK_U32(p) \ |
| (((uint32_t)(((const uint8_t *)(p))[0]) << 24) | \ |
| ((uint32_t)(((const uint8_t *)(p))[1]) << 16) | \ |
| ((uint32_t)(((const uint8_t *)(p))[2]) << 8) | \ |
| (uint32_t)(((const uint8_t *)(p))[3])) |
| #define PEEK_U16(p) \ |
| (((uint16_t)(((const uint8_t *)(p))[0]) << 8) | \ |
| (uint16_t)(((const uint8_t *)(p))[1])) |
| |
| #define POKE_U64(p, v) \ |
| do { \ |
| const uint64_t __v = (v); \ |
| ((uint8_t *)(p))[0] = (uint8_t)((__v >> 56) & 0xff); \ |
| ((uint8_t *)(p))[1] = (uint8_t)((__v >> 48) & 0xff); \ |
| ((uint8_t *)(p))[2] = (uint8_t)((__v >> 40) & 0xff); \ |
| ((uint8_t *)(p))[3] = (uint8_t)((__v >> 32) & 0xff); \ |
| ((uint8_t *)(p))[4] = (uint8_t)((__v >> 24) & 0xff); \ |
| ((uint8_t *)(p))[5] = (uint8_t)((__v >> 16) & 0xff); \ |
| ((uint8_t *)(p))[6] = (uint8_t)((__v >> 8) & 0xff); \ |
| ((uint8_t *)(p))[7] = (uint8_t)(__v & 0xff); \ |
| } while (0) |
| #define POKE_U32(p, v) \ |
| do { \ |
| const uint32_t __v = (v); \ |
| ((uint8_t *)(p))[0] = (uint8_t)((__v >> 24) & 0xff); \ |
| ((uint8_t *)(p))[1] = (uint8_t)((__v >> 16) & 0xff); \ |
| ((uint8_t *)(p))[2] = (uint8_t)((__v >> 8) & 0xff); \ |
| ((uint8_t *)(p))[3] = (uint8_t)(__v & 0xff); \ |
| } while (0) |
| #define POKE_U16(p, v) \ |
| do { \ |
| const uint16_t __v = (v); \ |
| ((uint8_t *)(p))[0] = (__v >> 8) & 0xff; \ |
| ((uint8_t *)(p))[1] = __v & 0xff; \ |
| } while (0) |
| |
| |
| enum { |
| SSH_MSG_DISCONNECT = 1, |
| SSH_MSG_IGNORE = 2, |
| SSH_MSG_UNIMPLEMENTED = 3, |
| SSH_MSG_DEBUG = 4, |
| SSH_MSG_SERVICE_REQUEST = 5, |
| SSH_MSG_SERVICE_ACCEPT = 6, |
| SSH_MSG_KEXINIT = 20, |
| SSH_MSG_NEWKEYS = 21, |
| |
| /* 30 .. 49: KEX messages specific to KEX protocol */ |
| SSH_MSG_KEX_ECDH_INIT = 30, |
| SSH_MSG_KEX_ECDH_REPLY = 31, |
| |
| /* 50... userauth */ |
| |
| SSH_MSG_USERAUTH_REQUEST = 50, |
| SSH_MSG_USERAUTH_FAILURE = 51, |
| SSH_MSG_USERAUTH_SUCCESS = 52, |
| SSH_MSG_USERAUTH_BANNER = 53, |
| |
| /* 60... publickey */ |
| |
| SSH_MSG_USERAUTH_PK_OK = 60, |
| |
| /* 80... connection */ |
| |
| SSH_MSG_GLOBAL_REQUEST = 80, |
| SSH_MSG_REQUEST_SUCCESS = 81, |
| SSH_MSG_REQUEST_FAILURE = 82, |
| |
| SSH_MSG_CHANNEL_OPEN = 90, |
| SSH_MSG_CHANNEL_OPEN_CONFIRMATION = 91, |
| SSH_MSG_CHANNEL_OPEN_FAILURE = 92, |
| SSH_MSG_CHANNEL_WINDOW_ADJUST = 93, |
| SSH_MSG_CHANNEL_DATA = 94, |
| SSH_MSG_CHANNEL_EXTENDED_DATA = 95, |
| SSH_MSG_CHANNEL_EOF = 96, |
| SSH_MSG_CHANNEL_CLOSE = 97, |
| SSH_MSG_CHANNEL_REQUEST = 98, |
| SSH_MSG_CHANNEL_SUCCESS = 99, |
| SSH_MSG_CHANNEL_FAILURE = 100, |
| |
| SSH_EXTENDED_DATA_STDERR = 1, |
| |
| SSH_CH_TYPE_SESSION = 1, |
| SSH_CH_TYPE_SCP = 2, |
| SSH_CH_TYPE_SFTP = 3, |
| |
| SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT = 1, |
| SSH_DISCONNECT_PROTOCOL_ERROR = 2, |
| SSH_DISCONNECT_KEY_EXCHANGE_FAILED = 3, |
| SSH_DISCONNECT_RESERVED = 4, |
| SSH_DISCONNECT_MAC_ERROR = 5, |
| SSH_DISCONNECT_COMPRESSION_ERROR = 6, |
| SSH_DISCONNECT_SERVICE_NOT_AVAILABLE = 7, |
| SSH_DISCONNECT_PROTOCOL_VERSION_NOT_SUPPORTED = 8, |
| SSH_DISCONNECT_HOST_KEY_NOT_VERIFIABLE = 9, |
| SSH_DISCONNECT_CONNECTION_LOST = 10, |
| SSH_DISCONNECT_BY_APPLICATION = 11, |
| SSH_DISCONNECT_TOO_MANY_CONNECTIONS = 12, |
| SSH_DISCONNECT_AUTH_CANCELLED_BY_USER = 13, |
| SSH_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE = 14, |
| SSH_DISCONNECT_ILLEGAL_USER_NAME = 15, |
| |
| SSH_OPEN_ADMINISTRATIVELY_PROHIBITED = 1, |
| SSH_OPEN_CONNECT_FAILED = 2, |
| SSH_OPEN_UNKNOWN_CHANNEL_TYPE = 3, |
| SSH_OPEN_RESOURCE_SHORTAGE = 4, |
| |
| KEX_STATE_EXPECTING_CLIENT_OFFER = 0, |
| KEX_STATE_REPLIED_TO_OFFER, |
| KEX_STATE_CRYPTO_INITIALIZED, |
| |
| SSH_KEYIDX_IV = 0, |
| SSH_KEYIDX_ENC, |
| SSH_KEYIDX_INTEG, |
| |
| /* things we may write on the connection */ |
| |
| SSH_WT_NONE = 0, |
| SSH_WT_VERSION, |
| SSH_WT_OFFER, |
| SSH_WT_OFFER_REPLY, |
| SSH_WT_SEND_NEWKEYS, |
| SSH_WT_UA_ACCEPT, |
| SSH_WT_UA_FAILURE, |
| SSH_WT_UA_BANNER, |
| SSH_WT_UA_PK_OK, |
| SSH_WT_UA_SUCCESS, |
| SSH_WT_CH_OPEN_CONF, |
| SSH_WT_CH_FAILURE, |
| SSH_WT_CHRQ_SUCC, |
| SSH_WT_CHRQ_FAILURE, |
| SSH_WT_SCP_ACK_OKAY, |
| SSH_WT_SCP_ACK_ERROR, |
| SSH_WT_CH_CLOSE, |
| SSH_WT_CH_EOF, |
| SSH_WT_WINDOW_ADJUST, |
| SSH_WT_EXIT_STATUS, |
| |
| /* RX parser states */ |
| |
| SSH_INITIALIZE_TRANSIENT = 0, |
| SSHS_IDSTRING, |
| SSHS_IDSTRING_CR, |
| SSHS_MSG_LEN, |
| SSHS_MSG_PADDING, |
| SSHS_MSG_ID, |
| SSH_KEX_STATE_COOKIE, |
| SSH_KEX_NL_KEX_ALGS_LEN, |
| SSH_KEX_NL_KEX_ALGS, |
| SSH_KEX_NL_SHK_ALGS_LEN, |
| SSH_KEX_NL_SHK_ALGS, |
| SSH_KEX_NL_EACTS_ALGS_LEN, |
| SSH_KEX_NL_EACTS_ALGS, |
| SSH_KEX_NL_EASTC_ALGS_LEN, |
| SSH_KEX_NL_EASTC_ALGS, |
| SSH_KEX_NL_MACTS_ALGS_LEN, |
| SSH_KEX_NL_MACTS_ALGS, |
| SSH_KEX_NL_MASTC_ALGS_LEN, |
| SSH_KEX_NL_MASTC_ALGS, |
| SSH_KEX_NL_CACTS_ALGS_LEN, |
| SSH_KEX_NL_CACTS_ALGS, |
| SSH_KEX_NL_CASTC_ALGS_LEN, |
| SSH_KEX_NL_CASTC_ALGS, |
| SSH_KEX_NL_LCTS_ALGS_LEN, |
| SSH_KEX_NL_LCTS_ALGS, |
| SSH_KEX_NL_LSTC_ALGS_LEN, |
| SSH_KEX_NL_LSTC_ALGS, |
| SSH_KEX_FIRST_PKT, |
| SSH_KEX_RESERVED, |
| |
| SSH_KEX_STATE_ECDH_KEYLEN, |
| SSH_KEX_STATE_ECDH_Q_C, |
| |
| SSHS_MSG_EAT_PADDING, |
| SSH_KEX_STATE_SKIP, |
| |
| SSHS_GET_STRING_LEN, |
| SSHS_GET_STRING, |
| SSHS_GET_STRING_LEN_ALLOC, |
| SSHS_GET_STRING_ALLOC, |
| SSHS_DO_SERVICE_REQUEST, |
| |
| SSHS_DO_UAR_SVC, |
| SSHS_DO_UAR_PUBLICKEY, |
| SSHS_NVC_DO_UAR_CHECK_PUBLICKEY, |
| SSHS_DO_UAR_SIG_PRESENT, |
| SSHS_NVC_DO_UAR_ALG, |
| SSHS_NVC_DO_UAR_PUBKEY_BLOB, |
| SSHS_NVC_DO_UAR_SIG, |
| |
| SSHS_GET_U32, |
| |
| SSHS_NVC_CHOPEN_TYPE, |
| SSHS_NVC_CHOPEN_SENDER_CH, |
| SSHS_NVC_CHOPEN_WINSIZE, |
| SSHS_NVC_CHOPEN_PKTSIZE, |
| |
| SSHS_NVC_CHRQ_RECIP, |
| SSHS_NVC_CHRQ_TYPE, |
| SSHS_CHRQ_WANT_REPLY, |
| SSHS_NVC_CHRQ_TERM, |
| SSHS_NVC_CHRQ_TW, |
| SSHS_NVC_CHRQ_TH, |
| SSHS_NVC_CHRQ_TWP, |
| SSHS_NVC_CHRQ_THP, |
| SSHS_NVC_CHRQ_MODES, |
| |
| SSHS_NVC_CHRQ_ENV_NAME, |
| SSHS_NVC_CHRQ_ENV_VALUE, |
| |
| SSHS_NVC_CHRQ_EXEC_CMD, |
| |
| SSHS_NVC_CHRQ_SUBSYSTEM, |
| |
| SSHS_NVC_CHRQ_WNDCHANGE_TW, |
| SSHS_NVC_CHRQ_WNDCHANGE_TH, |
| SSHS_NVC_CHRQ_WNDCHANGE_TWP, |
| SSHS_NVC_CHRQ_WNDCHANGE_THP, |
| |
| SSHS_NVC_CH_EOF, |
| SSHS_NVC_CH_CLOSE, |
| |
| SSHS_NVC_CD_RECIP, |
| SSHS_NVC_CD_DATA, |
| SSHS_NVC_CD_DATA_ALLOC, |
| |
| SSHS_NVC_WA_RECIP, |
| SSHS_NVC_WA_ADD, |
| |
| SSHS_NVC_DISCONNECT_REASON, |
| SSHS_NVC_DISCONNECT_DESC, |
| SSHS_NVC_DISCONNECT_LANG, |
| |
| SSHS_SCP_COLLECTSTR = 0, |
| SSHS_SCP_PAYLOADIN = 1, |
| |
| |
| /* from https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13 */ |
| |
| SECSH_FILEXFER_VERSION = 6, |
| |
| /* sftp packet types */ |
| |
| SSH_FXP_INIT = 1, |
| SSH_FXP_VERSION = 2, |
| SSH_FXP_OPEN = 3, |
| SSH_FXP_CLOSE = 4, |
| SSH_FXP_READ = 5, |
| SSH_FXP_WRITE = 6, |
| SSH_FXP_LSTAT = 7, |
| SSH_FXP_FSTAT = 8, |
| SSH_FXP_SETSTAT = 9, |
| SSH_FXP_FSETSTAT = 10, |
| SSH_FXP_OPENDIR = 11, |
| SSH_FXP_READDIR = 12, |
| SSH_FXP_REMOVE = 13, |
| SSH_FXP_MKDIR = 14, |
| SSH_FXP_RMDIR = 15, |
| SSH_FXP_REALPATH = 16, |
| SSH_FXP_STAT = 17, |
| SSH_FXP_RENAME = 18, |
| SSH_FXP_READLINK = 19, |
| SSH_FXP_LINK = 21, |
| SSH_FXP_BLOCK = 22, |
| SSH_FXP_UNBLOCK = 23, |
| SSH_FXP_STATUS = 101, |
| SSH_FXP_HANDLE = 102, |
| SSH_FXP_DATA = 103, |
| SSH_FXP_NAME = 104, |
| SSH_FXP_ATTRS = 105, |
| SSH_FXP_EXTENDED = 200, |
| SSH_FXP_EXTENDED_REPLY = 201, |
| |
| /* sftp return codes */ |
| |
| SSH_FX_OK = 0, |
| SSH_FX_EOF = 1, |
| SSH_FX_NO_SUCH_FILE = 2, |
| SSH_FX_PERMISSION_DENIED = 3, |
| SSH_FX_FAILURE = 4, |
| SSH_FX_BAD_MESSAGE = 5, |
| SSH_FX_NO_CONNECTION = 6, |
| SSH_FX_CONNECTION_LOST = 7, |
| SSH_FX_OP_UNSUPPORTED = 8, |
| SSH_FX_INVALID_HANDLE = 9, |
| SSH_FX_NO_SUCH_PATH = 10, |
| SSH_FX_FILE_ALREADY_EXISTS = 11, |
| SSH_FX_WRITE_PROTECT = 12, |
| SSH_FX_NO_MEDIA = 13, |
| SSH_FX_NO_SPACE_ON_FILESYSTEM = 14, |
| SSH_FX_QUOTA_EXCEEDED = 15, |
| SSH_FX_UNKNOWN_PRINCIPAL = 16, |
| SSH_FX_LOCK_CONFLICT = 17, |
| SSH_FX_DIR_NOT_EMPTY = 18, |
| SSH_FX_NOT_A_DIRECTORY = 19, |
| SSH_FX_INVALID_FILENAME = 20, |
| SSH_FX_LINK_LOOP = 21, |
| SSH_FX_CANNOT_DELETE = 22, |
| SSH_FX_INVALID_PARAMETER = 23, |
| SSH_FX_FILE_IS_A_DIRECTORY = 24, |
| SSH_FX_BYTE_RANGE_LOCK_CONFLICT = 25, |
| SSH_FX_BYTE_RANGE_LOCK_REFUSED = 26, |
| SSH_FX_DELETE_PENDING = 27, |
| SSH_FX_FILE_CORRUPT = 28, |
| SSH_FX_OWNER_INVALID = 29, |
| SSH_FX_GROUP_INVALID = 30, |
| SSH_FX_NO_MATCHING_BYTE_RANGE_LOCK = 31, |
| |
| |
| SSH_PENDING_TIMEOUT_CONNECT_TO_SUCCESSFUL_AUTH = |
| PENDING_TIMEOUT_USER_REASON_BASE + 0, |
| |
| SSH_AUTH_STATE_NO_AUTH = 0, |
| SSH_AUTH_STATE_GAVE_AUTH_IGNORE_REQS = 1, |
| }; |
| |
| #define LWS_SSH_INITIAL_WINDOW 16384 |
| |
| struct lws_ssh_userauth { |
| struct lws_genhash_ctx hash_ctx; |
| char *username; |
| char *service; |
| char *alg; |
| uint8_t *pubkey; |
| uint32_t pubkey_len; |
| uint8_t *sig; |
| uint32_t sig_len; |
| char sig_present; |
| }; |
| |
| struct lws_ssh_keys { |
| /* 3 == SSH_KEYIDX_IV (len=4), SSH_KEYIDX_ENC, SSH_KEYIDX_INTEG */ |
| uint8_t key[3][LWS_SIZE_CHACHA256_KEY]; |
| |
| /* opaque allocation made when cipher activated */ |
| void *cipher; |
| |
| uint8_t MAC_length; |
| uint8_t padding_alignment; /* block size */ |
| uint8_t valid:1; |
| uint8_t full_length:1; |
| }; |
| |
| struct lws_kex { |
| uint8_t kex_r[256]; |
| uint8_t Q_C[LWS_SIZE_EC25519]; /* client eph public key aka 'e' */ |
| uint8_t eph_pri_key[LWS_SIZE_EC25519]; /* server eph private key */ |
| uint8_t Q_S[LWS_SIZE_EC25519]; /* server ephemeral public key */ |
| uint8_t kex_cookie[16]; |
| uint8_t *I_C; /* malloc'd copy of client KEXINIT payload */ |
| uint8_t *I_S; /* malloc'd copy of server KEXINIT payload */ |
| uint32_t I_C_payload_len; |
| uint32_t I_C_alloc_len; |
| uint32_t I_S_payload_len; |
| uint32_t kex_r_len; |
| uint8_t match_bitfield; |
| uint8_t newkeys; /* which sides newkeys have been applied */ |
| |
| struct lws_ssh_keys keys_next_cts; |
| struct lws_ssh_keys keys_next_stc; |
| }; |
| |
| struct lws_subprotocol_scp { |
| char fp[128]; |
| uint64_t len; |
| uint32_t attr; |
| char cmd; |
| char ips; |
| }; |
| |
| typedef union { |
| struct lws_subprotocol_scp scp; |
| } lws_subprotocol; |
| |
| struct per_session_data__sshd; |
| |
| struct lws_ssh_channel { |
| struct lws_ssh_channel *next; |
| |
| struct per_session_data__sshd *pss; |
| |
| lws_subprotocol *sub; /* NULL, or allocated subprotocol state */ |
| void *priv; /* owned by user code */ |
| int type; |
| uint32_t server_ch; |
| uint32_t sender_ch; |
| int32_t window; |
| int32_t peer_window_est; |
| uint32_t max_pkt; |
| |
| uint32_t spawn_pid; |
| int retcode; |
| |
| uint8_t scheduled_close:1; |
| uint8_t sent_close:1; |
| uint8_t received_close:1; |
| }; |
| |
| struct per_vhost_data__sshd; |
| |
| struct per_session_data__sshd { |
| struct per_session_data__sshd *next; |
| struct per_vhost_data__sshd *vhd; |
| struct lws *wsi; |
| |
| struct lws_kex *kex; |
| char *disconnect_desc; |
| |
| uint8_t K[LWS_SIZE_EC25519]; /* shared secret */ |
| uint8_t session_id[LWS_SIZE_SHA256]; /* H from first working KEX */ |
| char name[64]; |
| char last_auth_req_username[32]; |
| char last_auth_req_service[32]; |
| |
| struct lws_ssh_keys active_keys_cts; |
| struct lws_ssh_keys active_keys_stc; |
| struct lws_ssh_userauth *ua; |
| struct lws_ssh_channel *ch_list; |
| struct lws_ssh_channel *ch_temp; |
| |
| uint8_t *last_alloc; |
| |
| union { |
| struct lws_ssh_pty pty; |
| char aux[64]; |
| } args; |
| |
| uint32_t ssh_sequence_ctr_cts; |
| uint32_t ssh_sequence_ctr_stc; |
| |
| uint64_t payload_bytes_cts; |
| uint64_t payload_bytes_stc; |
| |
| uint32_t disconnect_reason; |
| |
| char V_C[64]; /* Client version String */ |
| uint8_t packet_assembly[2048]; |
| uint32_t pa_pos; |
| |
| uint32_t msg_len; |
| uint32_t pos; |
| uint32_t len; |
| uint32_t ctr; |
| uint32_t npos; |
| uint32_t reason; |
| uint32_t channel_doing_spawn; |
| int next_ch_num; |
| |
| uint8_t K_S[LWS_SIZE_EC25519]; /* server public key */ |
| |
| uint32_t copy_to_I_C:1; |
| uint32_t okayed_userauth:1; |
| uint32_t sent_banner:1; |
| uint32_t seen_auth_req_before:1; |
| uint32_t serviced_stderr_last:1; |
| uint32_t kex_state; |
| uint32_t chrq_server_port; |
| uint32_t ch_recip; |
| uint32_t count_auth_attempts; |
| |
| char parser_state; |
| char state_after_string; |
| char first_coming; |
| uint8_t rq_want_reply; |
| uint8_t ssh_auth_state; |
| |
| uint8_t msg_id; |
| uint8_t msg_padding; |
| uint8_t write_task[8]; |
| struct lws_ssh_channel *write_channel[8]; |
| uint8_t wt_head, wt_tail; |
| }; |
| |
| struct per_vhost_data__sshd { |
| struct lws_context *context; |
| struct lws_vhost *vhost; |
| const struct lws_protocols *protocol; |
| struct per_session_data__sshd *live_pss_list; |
| const struct lws_ssh_ops *ops; |
| }; |
| |
| |
| struct host_keys { |
| uint8_t *data; |
| uint32_t len; |
| }; |
| |
| extern struct host_keys host_keys[]; |
| |
| extern int |
| crypto_scalarmult_curve25519(unsigned char *q, const unsigned char *n, |
| const unsigned char *p); |
| |
| extern int |
| ed25519_key_parse(uint8_t *p, size_t len, char *type, size_t type_len, |
| uint8_t *pub, uint8_t *pri); |
| |
| extern int |
| kex_ecdh(struct per_session_data__sshd *pss, uint8_t *result, uint32_t *plen); |
| |
| extern uint32_t |
| lws_g32(uint8_t **p); |
| |
| extern uint32_t |
| lws_p32(uint8_t *p, uint32_t v); |
| |
| extern int |
| lws_timingsafe_bcmp(const void *a, const void *b, uint32_t len); |
| |
| extern const char *lws_V_S; |
| |
| extern int |
| lws_chacha_activate(struct lws_ssh_keys *keys); |
| |
| extern void |
| lws_chacha_destroy(struct lws_ssh_keys *keys); |
| |
| extern uint32_t |
| lws_chachapoly_get_length(struct lws_ssh_keys *keys, uint32_t seq, |
| const uint8_t *in4); |
| |
| extern void |
| poly1305_auth(u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen, |
| const u_char key[POLY1305_KEYLEN]); |
| |
| extern int |
| lws_chacha_decrypt(struct lws_ssh_keys *keys, uint32_t seq, |
| const uint8_t *ct, uint32_t len, uint8_t *pt); |
| extern int |
| lws_chacha_encrypt(struct lws_ssh_keys *keys, uint32_t seq, |
| const uint8_t *ct, uint32_t len, uint8_t *pt); |
| |
| extern void |
| lws_pad_set_length(struct per_session_data__sshd *pss, void *start, uint8_t **p, |
| struct lws_ssh_keys *keys); |
| |
| extern size_t |
| get_gen_server_key_25519(struct per_session_data__sshd *pss, uint8_t *b, size_t len); |
| |
| extern int |
| crypto_sign_ed25519(unsigned char *sm, unsigned long long *smlen, |
| const unsigned char *m, size_t mlen, |
| const unsigned char *sk); |
| |
| extern int |
| crypto_sign_ed25519_keypair(struct lws_context *context, uint8_t *pk, |
| uint8_t *sk); |
| |
| #endif |