initial import
This commit is contained in:
46
lib/README
Normal file
46
lib/README
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in a an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
||||
114
lib/libssh2/agent.h
Normal file
114
lib/libssh2/agent.h
Normal file
@@ -0,0 +1,114 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_AGENT_H
|
||||
#define __LIBSSH2_AGENT_H
|
||||
/*
|
||||
* Copyright (c) 2009 by Daiki Ueno
|
||||
* Copyright (C) 2010-2014 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include "misc.h"
|
||||
#include "session.h"
|
||||
#ifdef WIN32
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
/* non-blocking mode on agent connection is not yet implemented, but
|
||||
for future use. */
|
||||
typedef enum {
|
||||
agent_NB_state_init = 0,
|
||||
agent_NB_state_request_created,
|
||||
agent_NB_state_request_length_sent,
|
||||
agent_NB_state_request_sent,
|
||||
agent_NB_state_response_length_received,
|
||||
agent_NB_state_response_received
|
||||
} agent_nonblocking_states;
|
||||
|
||||
typedef struct agent_transaction_ctx {
|
||||
unsigned char *request;
|
||||
size_t request_len;
|
||||
unsigned char *response;
|
||||
size_t response_len;
|
||||
agent_nonblocking_states state;
|
||||
size_t send_recv_total;
|
||||
} *agent_transaction_ctx_t;
|
||||
|
||||
typedef int (*agent_connect_func)(LIBSSH2_AGENT *agent);
|
||||
typedef int (*agent_transact_func)(LIBSSH2_AGENT *agent,
|
||||
agent_transaction_ctx_t transctx);
|
||||
typedef int (*agent_disconnect_func)(LIBSSH2_AGENT *agent);
|
||||
|
||||
struct agent_publickey {
|
||||
struct list_node node;
|
||||
|
||||
/* this is the struct we expose externally */
|
||||
struct libssh2_agent_publickey external;
|
||||
};
|
||||
|
||||
struct agent_ops {
|
||||
agent_connect_func connect;
|
||||
agent_transact_func transact;
|
||||
agent_disconnect_func disconnect;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_AGENT
|
||||
{
|
||||
LIBSSH2_SESSION *session; /* the session this "belongs to" */
|
||||
|
||||
libssh2_socket_t fd;
|
||||
|
||||
struct agent_ops *ops;
|
||||
|
||||
struct agent_transaction_ctx transctx;
|
||||
struct agent_publickey *identity;
|
||||
struct list_head head; /* list of public keys */
|
||||
|
||||
char *identity_agent_path; /* Path to a custom identity agent socket */
|
||||
|
||||
#ifdef WIN32
|
||||
OVERLAPPED overlapped;
|
||||
HANDLE pipe;
|
||||
BOOL pending_io;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef WIN32
|
||||
extern struct agent_ops agent_ops_openssh;
|
||||
#endif
|
||||
|
||||
#endif /* __LIBSSH2_AGENT_H */
|
||||
#endif
|
||||
185
lib/libssh2/bcrypt_pbkdf.c
Normal file
185
lib/libssh2/bcrypt_pbkdf.c
Normal file
@@ -0,0 +1,185 @@
|
||||
#if defined(ESP32)
|
||||
/* $OpenBSD: bcrypt_pbkdf.c,v 1.4 2013/07/29 00:55:53 tedu Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2013 Ted Unangst <tedu@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef HAVE_BCRYPT_PBKDF
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#include "blf.h"
|
||||
|
||||
#define MINIMUM(a,b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
/*
|
||||
* pkcs #5 pbkdf2 implementation using the "bcrypt" hash
|
||||
*
|
||||
* The bcrypt hash function is derived from the bcrypt password hashing
|
||||
* function with the following modifications:
|
||||
* 1. The input password and salt are preprocessed with SHA512.
|
||||
* 2. The output length is expanded to 256 bits.
|
||||
* 3. Subsequently the magic string to be encrypted is lengthened and modified
|
||||
* to "OxychromaticBlowfishSwatDynamite"
|
||||
* 4. The hash function is defined to perform 64 rounds of initial state
|
||||
* expansion. (More rounds are performed by iterating the hash.)
|
||||
*
|
||||
* Note that this implementation pulls the SHA512 operations into the caller
|
||||
* as a performance optimization.
|
||||
*
|
||||
* One modification from official pbkdf2. Instead of outputting key material
|
||||
* linearly, we mix it. pbkdf2 has a known weakness where if one uses it to
|
||||
* generate (i.e.) 512 bits of key material for use as two 256 bit keys, an
|
||||
* attacker can merely run once through the outer loop below, but the user
|
||||
* always runs it twice. Shuffling output bytes requires computing the
|
||||
* entirety of the key material to assemble any subkey. This is something a
|
||||
* wise caller could do; we just do it for you.
|
||||
*/
|
||||
|
||||
#define BCRYPT_BLOCKS 8
|
||||
#define BCRYPT_HASHSIZE (BCRYPT_BLOCKS * 4)
|
||||
|
||||
static void
|
||||
bcrypt_hash(uint8_t *sha2pass, uint8_t *sha2salt, uint8_t *out)
|
||||
{
|
||||
blf_ctx state;
|
||||
uint8_t ciphertext[BCRYPT_HASHSIZE] = {
|
||||
'O', 'x', 'y', 'c', 'h', 'r', 'o', 'm', 'a', 't', 'i', 'c',
|
||||
'B', 'l', 'o', 'w', 'f', 'i', 's', 'h',
|
||||
'S', 'w', 'a', 't',
|
||||
'D', 'y', 'n', 'a', 'm', 'i', 't', 'e' };
|
||||
uint32_t cdata[BCRYPT_BLOCKS];
|
||||
int i;
|
||||
uint16_t j;
|
||||
uint16_t shalen = SHA512_DIGEST_LENGTH;
|
||||
|
||||
/* key expansion */
|
||||
Blowfish_initstate(&state);
|
||||
Blowfish_expandstate(&state, sha2salt, shalen, sha2pass, shalen);
|
||||
for(i = 0; i < 64; i++) {
|
||||
Blowfish_expand0state(&state, sha2salt, shalen);
|
||||
Blowfish_expand0state(&state, sha2pass, shalen);
|
||||
}
|
||||
|
||||
/* encryption */
|
||||
j = 0;
|
||||
for(i = 0; i < BCRYPT_BLOCKS; i++)
|
||||
cdata[i] = Blowfish_stream2word(ciphertext, sizeof(ciphertext),
|
||||
&j);
|
||||
for(i = 0; i < 64; i++)
|
||||
blf_enc(&state, cdata, BCRYPT_BLOCKS / 2);
|
||||
|
||||
/* copy out */
|
||||
for(i = 0; i < BCRYPT_BLOCKS; i++) {
|
||||
out[4 * i + 3] = (cdata[i] >> 24) & 0xff;
|
||||
out[4 * i + 2] = (cdata[i] >> 16) & 0xff;
|
||||
out[4 * i + 1] = (cdata[i] >> 8) & 0xff;
|
||||
out[4 * i + 0] = cdata[i] & 0xff;
|
||||
}
|
||||
|
||||
/* zap */
|
||||
_libssh2_explicit_zero(ciphertext, sizeof(ciphertext));
|
||||
_libssh2_explicit_zero(cdata, sizeof(cdata));
|
||||
_libssh2_explicit_zero(&state, sizeof(state));
|
||||
}
|
||||
|
||||
int
|
||||
bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
|
||||
size_t saltlen,
|
||||
uint8_t *key, size_t keylen, unsigned int rounds)
|
||||
{
|
||||
uint8_t sha2pass[SHA512_DIGEST_LENGTH];
|
||||
uint8_t sha2salt[SHA512_DIGEST_LENGTH];
|
||||
uint8_t out[BCRYPT_HASHSIZE];
|
||||
uint8_t tmpout[BCRYPT_HASHSIZE];
|
||||
uint8_t *countsalt;
|
||||
size_t i, j, amt, stride;
|
||||
uint32_t count;
|
||||
size_t origkeylen = keylen;
|
||||
libssh2_sha512_ctx ctx;
|
||||
|
||||
/* nothing crazy */
|
||||
if(rounds < 1)
|
||||
return -1;
|
||||
if(passlen == 0 || saltlen == 0 || keylen == 0 ||
|
||||
keylen > sizeof(out) * sizeof(out) || saltlen > 1<<20)
|
||||
return -1;
|
||||
countsalt = calloc(1, saltlen + 4);
|
||||
if(countsalt == NULL)
|
||||
return -1;
|
||||
stride = (keylen + sizeof(out) - 1) / sizeof(out);
|
||||
amt = (keylen + stride - 1) / stride;
|
||||
|
||||
memcpy(countsalt, salt, saltlen);
|
||||
|
||||
/* collapse password */
|
||||
(void)libssh2_sha512_init(&ctx);
|
||||
libssh2_sha512_update(ctx, pass, passlen);
|
||||
libssh2_sha512_final(ctx, sha2pass);
|
||||
|
||||
/* generate key, sizeof(out) at a time */
|
||||
for(count = 1; keylen > 0; count++) {
|
||||
countsalt[saltlen + 0] = (count >> 24) & 0xff;
|
||||
countsalt[saltlen + 1] = (count >> 16) & 0xff;
|
||||
countsalt[saltlen + 2] = (count >> 8) & 0xff;
|
||||
countsalt[saltlen + 3] = count & 0xff;
|
||||
|
||||
/* first round, salt is salt */
|
||||
(void)libssh2_sha512_init(&ctx);
|
||||
libssh2_sha512_update(ctx, countsalt, saltlen + 4);
|
||||
libssh2_sha512_final(ctx, sha2salt);
|
||||
|
||||
bcrypt_hash(sha2pass, sha2salt, tmpout);
|
||||
memcpy(out, tmpout, sizeof(out));
|
||||
|
||||
for(i = 1; i < rounds; i++) {
|
||||
/* subsequent rounds, salt is previous output */
|
||||
(void)libssh2_sha512_init(&ctx);
|
||||
libssh2_sha512_update(ctx, tmpout, sizeof(tmpout));
|
||||
libssh2_sha512_final(ctx, sha2salt);
|
||||
|
||||
bcrypt_hash(sha2pass, sha2salt, tmpout);
|
||||
for(j = 0; j < sizeof(out); j++)
|
||||
out[j] ^= tmpout[j];
|
||||
}
|
||||
|
||||
/*
|
||||
* pbkdf2 deviation: output the key material non-linearly.
|
||||
*/
|
||||
amt = MINIMUM(amt, keylen);
|
||||
for(i = 0; i < amt; i++) {
|
||||
size_t dest = i * stride + (count - 1);
|
||||
if(dest >= origkeylen) {
|
||||
break;
|
||||
}
|
||||
key[dest] = out[i];
|
||||
}
|
||||
keylen -= i;
|
||||
}
|
||||
|
||||
/* zap */
|
||||
_libssh2_explicit_zero(out, sizeof(out));
|
||||
free(countsalt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* HAVE_BCRYPT_PBKDF */
|
||||
#endif
|
||||
88
lib/libssh2/blf.h
Normal file
88
lib/libssh2/blf.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_BLF_H
|
||||
#define __LIBSSH2_BLF_H
|
||||
/* $OpenBSD: blf.h,v 1.7 2007/03/14 17:59:41 grunk Exp $ */
|
||||
/*
|
||||
* Blowfish - a fast block cipher designed by Bruce Schneier
|
||||
*
|
||||
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H)
|
||||
|
||||
/* Schneier specifies a maximum key length of 56 bytes.
|
||||
* This ensures that every key bit affects every cipher
|
||||
* bit. However, the subkeys can hold up to 72 bytes.
|
||||
* Warning: For normal blowfish encryption only 56 bytes
|
||||
* of the key affect all cipherbits.
|
||||
*/
|
||||
|
||||
#define BLF_N 16 /* Number of Subkeys */
|
||||
#define BLF_MAXKEYLEN ((BLF_N-2)*4) /* 448 bits */
|
||||
#define BLF_MAXUTILIZED ((BLF_N + 2)*4) /* 576 bits */
|
||||
|
||||
/* Blowfish context */
|
||||
typedef struct BlowfishContext {
|
||||
uint32_t S[4][256]; /* S-Boxes */
|
||||
uint32_t P[BLF_N + 2]; /* Subkeys */
|
||||
} blf_ctx;
|
||||
|
||||
/* Raw access to customized Blowfish
|
||||
* blf_key is just:
|
||||
* Blowfish_initstate( state )
|
||||
* Blowfish_expand0state( state, key, keylen )
|
||||
*/
|
||||
|
||||
void Blowfish_encipher(blf_ctx *, uint32_t *, uint32_t *);
|
||||
void Blowfish_decipher(blf_ctx *, uint32_t *, uint32_t *);
|
||||
void Blowfish_initstate(blf_ctx *);
|
||||
void Blowfish_expand0state(blf_ctx *, const uint8_t *, uint16_t);
|
||||
void Blowfish_expandstate
|
||||
(blf_ctx *, const uint8_t *, uint16_t, const uint8_t *, uint16_t);
|
||||
|
||||
/* Standard Blowfish */
|
||||
|
||||
void blf_key(blf_ctx *, const uint8_t *, uint16_t);
|
||||
void blf_enc(blf_ctx *, uint32_t *, uint16_t);
|
||||
void blf_dec(blf_ctx *, uint32_t *, uint16_t);
|
||||
|
||||
void blf_ecb_encrypt(blf_ctx *, uint8_t *, uint32_t);
|
||||
void blf_ecb_decrypt(blf_ctx *, uint8_t *, uint32_t);
|
||||
|
||||
void blf_cbc_encrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
|
||||
void blf_cbc_decrypt(blf_ctx *, uint8_t *, uint8_t *, uint32_t);
|
||||
|
||||
/* Converts uint8_t to uint32_t */
|
||||
uint32_t Blowfish_stream2word(const uint8_t *, uint16_t, uint16_t *);
|
||||
|
||||
/* bcrypt with pbkd */
|
||||
int bcrypt_pbkdf(const char *pass, size_t passlen, const uint8_t *salt,
|
||||
size_t saltlen,
|
||||
uint8_t *key, size_t keylen, unsigned int rounds);
|
||||
|
||||
#endif /* !defined(HAVE_BCRYPT_PBKDF) && !defined(HAVE_BLH_H) */
|
||||
#endif /* __LIBSSH2_BLF_H */
|
||||
#endif
|
||||
696
lib/libssh2/blowfish.c
Normal file
696
lib/libssh2/blowfish.c
Normal file
@@ -0,0 +1,696 @@
|
||||
#if defined(ESP32)
|
||||
/* $OpenBSD: blowfish.c,v 1.18 2004/11/02 17:23:26 hshoexer Exp $ */
|
||||
/*
|
||||
* Blowfish block cipher for OpenBSD
|
||||
* Copyright 1997 Niels Provos <provos@physnet.uni-hamburg.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Implementation advice by David Mazieres <dm@lcs.mit.edu>.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. The name of the author may not be used to endorse or promote products
|
||||
* derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This code is derived from section 14.3 and the given source
|
||||
* in section V of Applied Cryptography, second edition.
|
||||
* Blowfish is an unpatented fast block cipher designed by
|
||||
* Bruce Schneier.
|
||||
*/
|
||||
|
||||
|
||||
#if !defined(HAVE_BCRYPT_PBKDF) && (!defined(HAVE_BLOWFISH_INITSTATE) || \
|
||||
!defined(HAVE_BLOWFISH_EXPAND0STATE) || \
|
||||
!defined(HAVE_BLF_ENC))
|
||||
|
||||
#if 0
|
||||
#include <stdio.h> /* used for debugging */
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "libssh2.h"
|
||||
#include "blf.h"
|
||||
|
||||
#undef inline
|
||||
#ifdef __GNUC__
|
||||
#define inline __inline
|
||||
#else /* !__GNUC__ */
|
||||
#define inline
|
||||
#endif /* !__GNUC__ */
|
||||
|
||||
/* Function for Feistel Networks */
|
||||
|
||||
#define F(s, x) ((((s)[ (((x)>>24)&0xFF)] \
|
||||
+ (s)[0x100 + (((x)>>16)&0xFF)]) \
|
||||
^ (s)[0x200 + (((x)>> 8)&0xFF)]) \
|
||||
+ (s)[0x300 + ( (x) &0xFF)])
|
||||
|
||||
#define BLFRND(s,p,i,j,n) (i ^= F(s,j) ^ (p)[n])
|
||||
|
||||
void
|
||||
Blowfish_encipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
|
||||
{
|
||||
uint32_t Xl;
|
||||
uint32_t Xr;
|
||||
uint32_t *s = c->S[0];
|
||||
uint32_t *p = c->P;
|
||||
|
||||
Xl = *xl;
|
||||
Xr = *xr;
|
||||
|
||||
Xl ^= p[0];
|
||||
BLFRND(s, p, Xr, Xl, 1); BLFRND(s, p, Xl, Xr, 2);
|
||||
BLFRND(s, p, Xr, Xl, 3); BLFRND(s, p, Xl, Xr, 4);
|
||||
BLFRND(s, p, Xr, Xl, 5); BLFRND(s, p, Xl, Xr, 6);
|
||||
BLFRND(s, p, Xr, Xl, 7); BLFRND(s, p, Xl, Xr, 8);
|
||||
BLFRND(s, p, Xr, Xl, 9); BLFRND(s, p, Xl, Xr, 10);
|
||||
BLFRND(s, p, Xr, Xl, 11); BLFRND(s, p, Xl, Xr, 12);
|
||||
BLFRND(s, p, Xr, Xl, 13); BLFRND(s, p, Xl, Xr, 14);
|
||||
BLFRND(s, p, Xr, Xl, 15); BLFRND(s, p, Xl, Xr, 16);
|
||||
|
||||
*xl = Xr ^ p[17];
|
||||
*xr = Xl;
|
||||
}
|
||||
|
||||
void
|
||||
Blowfish_decipher(blf_ctx *c, uint32_t *xl, uint32_t *xr)
|
||||
{
|
||||
uint32_t Xl;
|
||||
uint32_t Xr;
|
||||
uint32_t *s = c->S[0];
|
||||
uint32_t *p = c->P;
|
||||
|
||||
Xl = *xl;
|
||||
Xr = *xr;
|
||||
|
||||
Xl ^= p[17];
|
||||
BLFRND(s, p, Xr, Xl, 16); BLFRND(s, p, Xl, Xr, 15);
|
||||
BLFRND(s, p, Xr, Xl, 14); BLFRND(s, p, Xl, Xr, 13);
|
||||
BLFRND(s, p, Xr, Xl, 12); BLFRND(s, p, Xl, Xr, 11);
|
||||
BLFRND(s, p, Xr, Xl, 10); BLFRND(s, p, Xl, Xr, 9);
|
||||
BLFRND(s, p, Xr, Xl, 8); BLFRND(s, p, Xl, Xr, 7);
|
||||
BLFRND(s, p, Xr, Xl, 6); BLFRND(s, p, Xl, Xr, 5);
|
||||
BLFRND(s, p, Xr, Xl, 4); BLFRND(s, p, Xl, Xr, 3);
|
||||
BLFRND(s, p, Xr, Xl, 2); BLFRND(s, p, Xl, Xr, 1);
|
||||
|
||||
*xl = Xr ^ p[0];
|
||||
*xr = Xl;
|
||||
}
|
||||
|
||||
void
|
||||
Blowfish_initstate(blf_ctx *c)
|
||||
{
|
||||
/* P-box and S-box tables initialized with digits of Pi */
|
||||
|
||||
static const blf_ctx initstate =
|
||||
{ {
|
||||
{
|
||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
|
||||
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
||||
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
|
||||
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
||||
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
|
||||
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
|
||||
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
|
||||
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
||||
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
|
||||
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
|
||||
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
||||
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
|
||||
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
|
||||
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
|
||||
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
|
||||
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
|
||||
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
||||
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
|
||||
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
|
||||
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
|
||||
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
|
||||
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
|
||||
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
||||
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
|
||||
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
|
||||
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
||||
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
|
||||
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
|
||||
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
||||
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
|
||||
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
|
||||
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
|
||||
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
|
||||
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
|
||||
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
||||
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
|
||||
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
|
||||
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
|
||||
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
|
||||
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
|
||||
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
||||
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
|
||||
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
|
||||
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
||||
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
|
||||
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
|
||||
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
||||
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
|
||||
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
|
||||
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
|
||||
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
|
||||
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
|
||||
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
||||
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
|
||||
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
|
||||
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
|
||||
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
|
||||
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
|
||||
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
||||
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
|
||||
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
|
||||
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
||||
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a},
|
||||
{
|
||||
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
|
||||
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
|
||||
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
|
||||
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
|
||||
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
|
||||
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
||||
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
|
||||
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
|
||||
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
|
||||
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
|
||||
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
|
||||
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
||||
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
|
||||
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
|
||||
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
|
||||
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
|
||||
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
|
||||
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
||||
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
|
||||
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
|
||||
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
|
||||
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
|
||||
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
|
||||
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
||||
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
|
||||
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
|
||||
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
|
||||
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
|
||||
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
|
||||
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
||||
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
|
||||
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
|
||||
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
|
||||
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
|
||||
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
|
||||
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
||||
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
|
||||
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
|
||||
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
|
||||
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
|
||||
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
|
||||
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
||||
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
|
||||
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
|
||||
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
|
||||
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
|
||||
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
|
||||
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
||||
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
|
||||
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
|
||||
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
|
||||
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
|
||||
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
|
||||
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
||||
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
|
||||
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
|
||||
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
|
||||
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
|
||||
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
|
||||
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
||||
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
|
||||
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
|
||||
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
|
||||
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7},
|
||||
{
|
||||
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
|
||||
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
|
||||
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
|
||||
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
|
||||
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
|
||||
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
||||
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
|
||||
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
|
||||
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
|
||||
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
|
||||
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
|
||||
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
||||
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
|
||||
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
|
||||
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
|
||||
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
|
||||
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
|
||||
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
||||
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
|
||||
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
|
||||
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
|
||||
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
|
||||
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
|
||||
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
||||
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
|
||||
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
|
||||
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
|
||||
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
|
||||
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
|
||||
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
||||
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
|
||||
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
|
||||
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
|
||||
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
|
||||
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
|
||||
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
||||
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
|
||||
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
|
||||
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
|
||||
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
|
||||
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
|
||||
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
||||
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
|
||||
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
|
||||
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
|
||||
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
|
||||
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
|
||||
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
||||
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
|
||||
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
|
||||
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
|
||||
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
|
||||
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
|
||||
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
||||
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
|
||||
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
|
||||
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
|
||||
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
|
||||
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
|
||||
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
||||
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
|
||||
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
|
||||
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
|
||||
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0},
|
||||
{
|
||||
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
|
||||
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
|
||||
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
|
||||
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
|
||||
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
|
||||
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
||||
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
|
||||
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
|
||||
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
||||
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
|
||||
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
|
||||
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
||||
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
|
||||
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
|
||||
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
|
||||
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
|
||||
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
|
||||
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
||||
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
|
||||
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
|
||||
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
|
||||
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
|
||||
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
|
||||
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
||||
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
|
||||
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
|
||||
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
||||
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
|
||||
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
|
||||
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
||||
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
|
||||
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
|
||||
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
|
||||
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
|
||||
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
|
||||
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
||||
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
|
||||
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
|
||||
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
|
||||
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
|
||||
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
|
||||
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
||||
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
|
||||
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
|
||||
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
||||
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
|
||||
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
|
||||
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
||||
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
|
||||
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
|
||||
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
|
||||
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
|
||||
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
|
||||
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
||||
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
|
||||
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
|
||||
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
|
||||
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
|
||||
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
|
||||
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
||||
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
|
||||
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
|
||||
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
||||
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6}
|
||||
},
|
||||
{
|
||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
|
||||
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
||||
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
|
||||
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
|
||||
0x9216d5d9, 0x8979fb1b
|
||||
} };
|
||||
|
||||
*c = initstate;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Blowfish_stream2word(const uint8_t *data, uint16_t databytes,
|
||||
uint16_t *current)
|
||||
{
|
||||
uint8_t i;
|
||||
uint16_t j;
|
||||
uint32_t temp;
|
||||
|
||||
temp = 0x00000000;
|
||||
j = *current;
|
||||
|
||||
for(i = 0; i < 4; i++, j++) {
|
||||
if(j >= databytes)
|
||||
j = 0;
|
||||
temp = (temp << 8) | data[j];
|
||||
}
|
||||
|
||||
*current = j;
|
||||
return temp;
|
||||
}
|
||||
|
||||
void
|
||||
Blowfish_expand0state(blf_ctx *c, const uint8_t *key, uint16_t keybytes)
|
||||
{
|
||||
uint16_t i;
|
||||
uint16_t j;
|
||||
uint16_t k;
|
||||
uint32_t temp;
|
||||
uint32_t datal;
|
||||
uint32_t datar;
|
||||
|
||||
j = 0;
|
||||
for(i = 0; i < BLF_N + 2; i++) {
|
||||
/* Extract 4 int8 to 1 int32 from keystream */
|
||||
temp = Blowfish_stream2word(key, keybytes, &j);
|
||||
c->P[i] = c->P[i] ^ temp;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
datal = 0x00000000;
|
||||
datar = 0x00000000;
|
||||
for(i = 0; i < BLF_N + 2; i += 2) {
|
||||
Blowfish_encipher(c, &datal, &datar);
|
||||
|
||||
c->P[i] = datal;
|
||||
c->P[i + 1] = datar;
|
||||
}
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
for(k = 0; k < 256; k += 2) {
|
||||
Blowfish_encipher(c, &datal, &datar);
|
||||
|
||||
c->S[i][k] = datal;
|
||||
c->S[i][k + 1] = datar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Blowfish_expandstate(blf_ctx *c, const uint8_t *data, uint16_t databytes,
|
||||
const uint8_t *key, uint16_t keybytes)
|
||||
{
|
||||
uint16_t i;
|
||||
uint16_t j;
|
||||
uint16_t k;
|
||||
uint32_t temp;
|
||||
uint32_t datal;
|
||||
uint32_t datar;
|
||||
|
||||
j = 0;
|
||||
for(i = 0; i < BLF_N + 2; i++) {
|
||||
/* Extract 4 int8 to 1 int32 from keystream */
|
||||
temp = Blowfish_stream2word(key, keybytes, &j);
|
||||
c->P[i] = c->P[i] ^ temp;
|
||||
}
|
||||
|
||||
j = 0;
|
||||
datal = 0x00000000;
|
||||
datar = 0x00000000;
|
||||
for(i = 0; i < BLF_N + 2; i += 2) {
|
||||
datal ^= Blowfish_stream2word(data, databytes, &j);
|
||||
datar ^= Blowfish_stream2word(data, databytes, &j);
|
||||
Blowfish_encipher(c, &datal, &datar);
|
||||
|
||||
c->P[i] = datal;
|
||||
c->P[i + 1] = datar;
|
||||
}
|
||||
|
||||
for(i = 0; i < 4; i++) {
|
||||
for(k = 0; k < 256; k += 2) {
|
||||
datal ^= Blowfish_stream2word(data, databytes, &j);
|
||||
datar ^= Blowfish_stream2word(data, databytes, &j);
|
||||
Blowfish_encipher(c, &datal, &datar);
|
||||
|
||||
c->S[i][k] = datal;
|
||||
c->S[i][k + 1] = datar;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
blf_key(blf_ctx *c, const uint8_t *k, uint16_t len)
|
||||
{
|
||||
/* Initialize S-boxes and subkeys with Pi */
|
||||
Blowfish_initstate(c);
|
||||
|
||||
/* Transform S-boxes and subkeys with key */
|
||||
Blowfish_expand0state(c, k, len);
|
||||
}
|
||||
|
||||
void
|
||||
blf_enc(blf_ctx *c, uint32_t *data, uint16_t blocks)
|
||||
{
|
||||
uint32_t *d;
|
||||
uint16_t i;
|
||||
|
||||
d = data;
|
||||
for(i = 0; i < blocks; i++) {
|
||||
Blowfish_encipher(c, d, d + 1);
|
||||
d += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
blf_dec(blf_ctx *c, uint32_t *data, uint16_t blocks)
|
||||
{
|
||||
uint32_t *d;
|
||||
uint16_t i;
|
||||
|
||||
d = data;
|
||||
for(i = 0; i < blocks; i++) {
|
||||
Blowfish_decipher(c, d, d + 1);
|
||||
d += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
blf_ecb_encrypt(blf_ctx *c, uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t l, r;
|
||||
uint32_t i;
|
||||
|
||||
for(i = 0; i < len; i += 8) {
|
||||
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
|
||||
Blowfish_encipher(c, &l, &r);
|
||||
data[0] = l >> 24 & 0xff;
|
||||
data[1] = l >> 16 & 0xff;
|
||||
data[2] = l >> 8 & 0xff;
|
||||
data[3] = l & 0xff;
|
||||
data[4] = r >> 24 & 0xff;
|
||||
data[5] = r >> 16 & 0xff;
|
||||
data[6] = r >> 8 & 0xff;
|
||||
data[7] = r & 0xff;
|
||||
data += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
blf_ecb_decrypt(blf_ctx *c, uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t l, r;
|
||||
uint32_t i;
|
||||
|
||||
for(i = 0; i < len; i += 8) {
|
||||
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
|
||||
Blowfish_decipher(c, &l, &r);
|
||||
data[0] = l >> 24 & 0xff;
|
||||
data[1] = l >> 16 & 0xff;
|
||||
data[2] = l >> 8 & 0xff;
|
||||
data[3] = l & 0xff;
|
||||
data[4] = r >> 24 & 0xff;
|
||||
data[5] = r >> 16 & 0xff;
|
||||
data[6] = r >> 8 & 0xff;
|
||||
data[7] = r & 0xff;
|
||||
data += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
blf_cbc_encrypt(blf_ctx *c, uint8_t *iv, uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t l, r;
|
||||
uint32_t i, j;
|
||||
|
||||
for(i = 0; i < len; i += 8) {
|
||||
for(j = 0; j < 8; j++)
|
||||
data[j] ^= iv[j];
|
||||
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
|
||||
Blowfish_encipher(c, &l, &r);
|
||||
data[0] = l >> 24 & 0xff;
|
||||
data[1] = l >> 16 & 0xff;
|
||||
data[2] = l >> 8 & 0xff;
|
||||
data[3] = l & 0xff;
|
||||
data[4] = r >> 24 & 0xff;
|
||||
data[5] = r >> 16 & 0xff;
|
||||
data[6] = r >> 8 & 0xff;
|
||||
data[7] = r & 0xff;
|
||||
iv = data;
|
||||
data += 8;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
blf_cbc_decrypt(blf_ctx *c, uint8_t *iva, uint8_t *data, uint32_t len)
|
||||
{
|
||||
uint32_t l, r;
|
||||
uint8_t *iv;
|
||||
uint32_t i, j;
|
||||
|
||||
iv = data + len - 16;
|
||||
data = data + len - 8;
|
||||
for(i = len - 8; i >= 8; i -= 8) {
|
||||
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
|
||||
Blowfish_decipher(c, &l, &r);
|
||||
data[0] = l >> 24 & 0xff;
|
||||
data[1] = l >> 16 & 0xff;
|
||||
data[2] = l >> 8 & 0xff;
|
||||
data[3] = l & 0xff;
|
||||
data[4] = r >> 24 & 0xff;
|
||||
data[5] = r >> 16 & 0xff;
|
||||
data[6] = r >> 8 & 0xff;
|
||||
data[7] = r & 0xff;
|
||||
for(j = 0; j < 8; j++)
|
||||
data[j] ^= iv[j];
|
||||
iv -= 8;
|
||||
data -= 8;
|
||||
}
|
||||
l = data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
r = data[4] << 24 | data[5] << 16 | data[6] << 8 | data[7];
|
||||
Blowfish_decipher(c, &l, &r);
|
||||
data[0] = l >> 24 & 0xff;
|
||||
data[1] = l >> 16 & 0xff;
|
||||
data[2] = l >> 8 & 0xff;
|
||||
data[3] = l & 0xff;
|
||||
data[4] = r >> 24 & 0xff;
|
||||
data[5] = r >> 16 & 0xff;
|
||||
data[6] = r >> 8 & 0xff;
|
||||
data[7] = r & 0xff;
|
||||
for(j = 0; j < 8; j++)
|
||||
data[j] ^= iva[j];
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
report(uint32_t data[], uint16_t len)
|
||||
{
|
||||
uint16_t i;
|
||||
for(i = 0; i < len; i += 2)
|
||||
printf("Block %0hd: %08lx %08lx.\n",
|
||||
i / 2, data[i], data[i + 1]);
|
||||
}
|
||||
void
|
||||
main(void)
|
||||
{
|
||||
|
||||
blf_ctx c;
|
||||
char key[] = "AAAAA";
|
||||
char key2[] = "abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
uint32_t data[10];
|
||||
uint32_t data2[] =
|
||||
{0x424c4f57l, 0x46495348l};
|
||||
|
||||
uint16_t i;
|
||||
|
||||
/* First test */
|
||||
for(i = 0; i < 10; i++)
|
||||
data[i] = i;
|
||||
|
||||
blf_key(&c, (uint8_t *) key, 5);
|
||||
blf_enc(&c, data, 5);
|
||||
blf_dec(&c, data, 1);
|
||||
blf_dec(&c, data + 2, 4);
|
||||
printf("Should read as 0 - 9.\n");
|
||||
report(data, 10);
|
||||
|
||||
/* Second test */
|
||||
blf_key(&c, (uint8_t *) key2, strlen(key2));
|
||||
blf_enc(&c, data2, 1);
|
||||
printf("\nShould read as: 0x324ed0fe 0xf413a203.\n");
|
||||
report(data2, 2);
|
||||
blf_dec(&c, data2, 1);
|
||||
report(data2, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined(HAVE_BCRYPT_PBKDF) && \
|
||||
(!defined(HAVE_BLOWFISH_INITSTATE) || \
|
||||
!defined(HAVE_BLOWFISH_EXPAND0STATE) || \
|
||||
'!defined(HAVE_BLF_ENC)) */
|
||||
#endif
|
||||
2908
lib/libssh2/channel.c
Normal file
2908
lib/libssh2/channel.c
Normal file
File diff suppressed because it is too large
Load Diff
143
lib/libssh2/channel.h
Normal file
143
lib/libssh2/channel.h
Normal file
@@ -0,0 +1,143 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_CHANNEL_H
|
||||
#define __LIBSSH2_CHANNEL_H
|
||||
/* Copyright (c) 2008-2010 by Daniel Stenberg
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* _libssh2_channel_receive_window_adjust
|
||||
*
|
||||
* Adjust the receive window for a channel by adjustment bytes. If the amount
|
||||
* to be adjusted is less than LIBSSH2_CHANNEL_MINADJUST and force is 0 the
|
||||
* adjustment amount will be queued for a later packet.
|
||||
*
|
||||
* Always non-blocking.
|
||||
*/
|
||||
int _libssh2_channel_receive_window_adjust(LIBSSH2_CHANNEL * channel,
|
||||
uint32_t adjustment,
|
||||
unsigned char force,
|
||||
unsigned int *store);
|
||||
|
||||
/*
|
||||
* _libssh2_channel_flush
|
||||
*
|
||||
* Flush data from one (or all) stream
|
||||
* Returns number of bytes flushed, or negative on failure
|
||||
*/
|
||||
int _libssh2_channel_flush(LIBSSH2_CHANNEL *channel, int streamid);
|
||||
|
||||
/*
|
||||
* _libssh2_channel_free
|
||||
*
|
||||
* Make sure a channel is closed, then remove the channel from the session
|
||||
* and free its resource(s)
|
||||
*
|
||||
* Returns 0 on success, negative on failure
|
||||
*/
|
||||
int _libssh2_channel_free(LIBSSH2_CHANNEL *channel);
|
||||
|
||||
int
|
||||
_libssh2_channel_extended_data(LIBSSH2_CHANNEL *channel, int ignore_mode);
|
||||
|
||||
/*
|
||||
* _libssh2_channel_write
|
||||
*
|
||||
* Send data to a channel
|
||||
*/
|
||||
ssize_t
|
||||
_libssh2_channel_write(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
const unsigned char *buf, size_t buflen);
|
||||
|
||||
/*
|
||||
* _libssh2_channel_open
|
||||
*
|
||||
* Establish a generic session channel
|
||||
*/
|
||||
LIBSSH2_CHANNEL *
|
||||
_libssh2_channel_open(LIBSSH2_SESSION * session, const char *channel_type,
|
||||
uint32_t channel_type_len,
|
||||
uint32_t window_size,
|
||||
uint32_t packet_size,
|
||||
const unsigned char *message, size_t message_len);
|
||||
|
||||
|
||||
/*
|
||||
* _libssh2_channel_process_startup
|
||||
*
|
||||
* Primitive for libssh2_channel_(shell|exec|subsystem)
|
||||
*/
|
||||
int
|
||||
_libssh2_channel_process_startup(LIBSSH2_CHANNEL *channel,
|
||||
const char *request, size_t request_len,
|
||||
const char *message, size_t message_len);
|
||||
|
||||
/*
|
||||
* _libssh2_channel_read
|
||||
*
|
||||
* Read data from a channel
|
||||
*
|
||||
* It is important to not return 0 until the currently read channel is
|
||||
* complete. If we read stuff from the wire but it was no payload data to fill
|
||||
* in the buffer with, we MUST make sure to return PACKET_EAGAIN.
|
||||
*/
|
||||
ssize_t _libssh2_channel_read(LIBSSH2_CHANNEL *channel, int stream_id,
|
||||
char *buf, size_t buflen);
|
||||
|
||||
uint32_t _libssh2_channel_nextid(LIBSSH2_SESSION * session);
|
||||
|
||||
LIBSSH2_CHANNEL *_libssh2_channel_locate(LIBSSH2_SESSION * session,
|
||||
uint32_t channel_id);
|
||||
|
||||
size_t _libssh2_channel_packet_data_len(LIBSSH2_CHANNEL * channel,
|
||||
int stream_id);
|
||||
|
||||
int _libssh2_channel_close(LIBSSH2_CHANNEL * channel);
|
||||
|
||||
/*
|
||||
* _libssh2_channel_forward_cancel
|
||||
*
|
||||
* Stop listening on a remote port and free the listener
|
||||
* Toss out any pending (un-accept()ed) connections
|
||||
*
|
||||
* Return 0 on success, LIBSSH2_ERROR_EAGAIN if would block, -1 on error
|
||||
*/
|
||||
int _libssh2_channel_forward_cancel(LIBSSH2_LISTENER *listener);
|
||||
|
||||
#endif /* __LIBSSH2_CHANNEL_H */
|
||||
|
||||
#endif
|
||||
379
lib/libssh2/comp.c
Normal file
379
lib/libssh2/comp.c
Normal file
@@ -0,0 +1,379 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (c) 2004-2007, 2019, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2010-2014, Daniel Stenberg <daniel@haxx.se>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#ifdef LIBSSH2_HAVE_ZLIB
|
||||
#include <zlib.h>
|
||||
#undef compress /* dodge name clash with ZLIB macro */
|
||||
#endif
|
||||
|
||||
#include "comp.h"
|
||||
|
||||
/* ********
|
||||
* none *
|
||||
******** */
|
||||
|
||||
/*
|
||||
* comp_method_none_comp
|
||||
*
|
||||
* Minimalist compression: Absolutely none
|
||||
*/
|
||||
static int
|
||||
comp_method_none_comp(LIBSSH2_SESSION *session,
|
||||
unsigned char *dest,
|
||||
size_t *dest_len,
|
||||
const unsigned char *src,
|
||||
size_t src_len,
|
||||
void **abstract)
|
||||
{
|
||||
(void) session;
|
||||
(void) abstract;
|
||||
(void) dest;
|
||||
(void) dest_len;
|
||||
(void) src;
|
||||
(void) src_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* comp_method_none_decomp
|
||||
*
|
||||
* Minimalist decompression: Absolutely none
|
||||
*/
|
||||
static int
|
||||
comp_method_none_decomp(LIBSSH2_SESSION * session,
|
||||
unsigned char **dest,
|
||||
size_t *dest_len,
|
||||
size_t payload_limit,
|
||||
const unsigned char *src,
|
||||
size_t src_len, void **abstract)
|
||||
{
|
||||
(void) session;
|
||||
(void) payload_limit;
|
||||
(void) abstract;
|
||||
*dest = (unsigned char *) src;
|
||||
*dest_len = src_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const LIBSSH2_COMP_METHOD comp_method_none = {
|
||||
"none",
|
||||
0, /* not really compressing */
|
||||
0, /* isn't used in userauth, go figure */
|
||||
NULL,
|
||||
comp_method_none_comp,
|
||||
comp_method_none_decomp,
|
||||
NULL
|
||||
};
|
||||
|
||||
#ifdef LIBSSH2_HAVE_ZLIB
|
||||
/* ********
|
||||
* zlib *
|
||||
******** */
|
||||
|
||||
/* Memory management wrappers
|
||||
* Yes, I realize we're doing a callback to a callback,
|
||||
* Deal...
|
||||
*/
|
||||
|
||||
static voidpf
|
||||
comp_method_zlib_alloc(voidpf opaque, uInt items, uInt size)
|
||||
{
|
||||
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
|
||||
|
||||
return (voidpf) LIBSSH2_ALLOC(session, items * size);
|
||||
}
|
||||
|
||||
static void
|
||||
comp_method_zlib_free(voidpf opaque, voidpf address)
|
||||
{
|
||||
LIBSSH2_SESSION *session = (LIBSSH2_SESSION *) opaque;
|
||||
|
||||
LIBSSH2_FREE(session, address);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* libssh2_comp_method_zlib_init
|
||||
* All your bandwidth are belong to us (so save some)
|
||||
*/
|
||||
static int
|
||||
comp_method_zlib_init(LIBSSH2_SESSION * session, int compr,
|
||||
void **abstract)
|
||||
{
|
||||
z_stream *strm;
|
||||
int status;
|
||||
|
||||
strm = LIBSSH2_CALLOC(session, sizeof(z_stream));
|
||||
if(!strm) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"zlib compression/decompression");
|
||||
}
|
||||
|
||||
strm->opaque = (voidpf) session;
|
||||
strm->zalloc = (alloc_func) comp_method_zlib_alloc;
|
||||
strm->zfree = (free_func) comp_method_zlib_free;
|
||||
if(compr) {
|
||||
/* deflate */
|
||||
status = deflateInit(strm, Z_DEFAULT_COMPRESSION);
|
||||
}
|
||||
else {
|
||||
/* inflate */
|
||||
status = inflateInit(strm);
|
||||
}
|
||||
|
||||
if(status != Z_OK) {
|
||||
LIBSSH2_FREE(session, strm);
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||
"unhandled zlib error %d", status);
|
||||
return LIBSSH2_ERROR_COMPRESS;
|
||||
}
|
||||
*abstract = strm;
|
||||
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* libssh2_comp_method_zlib_comp
|
||||
*
|
||||
* Compresses source to destination. Without allocation.
|
||||
*/
|
||||
static int
|
||||
comp_method_zlib_comp(LIBSSH2_SESSION *session,
|
||||
unsigned char *dest,
|
||||
|
||||
/* dest_len is a pointer to allow this function to
|
||||
update it with the final actual size used */
|
||||
size_t *dest_len,
|
||||
const unsigned char *src,
|
||||
size_t src_len,
|
||||
void **abstract)
|
||||
{
|
||||
z_stream *strm = *abstract;
|
||||
int out_maxlen = *dest_len;
|
||||
int status;
|
||||
|
||||
strm->next_in = (unsigned char *) src;
|
||||
strm->avail_in = src_len;
|
||||
strm->next_out = dest;
|
||||
strm->avail_out = out_maxlen;
|
||||
|
||||
status = deflate(strm, Z_PARTIAL_FLUSH);
|
||||
|
||||
if((status == Z_OK) && (strm->avail_out > 0)) {
|
||||
*dest_len = out_maxlen - strm->avail_out;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||
"unhandled zlib compression error %d, avail_out",
|
||||
status, strm->avail_out);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB, "compression failure");
|
||||
}
|
||||
|
||||
/*
|
||||
* libssh2_comp_method_zlib_decomp
|
||||
*
|
||||
* Decompresses source to destination. Allocates the output memory.
|
||||
*/
|
||||
static int
|
||||
comp_method_zlib_decomp(LIBSSH2_SESSION * session,
|
||||
unsigned char **dest,
|
||||
size_t *dest_len,
|
||||
size_t payload_limit,
|
||||
const unsigned char *src,
|
||||
size_t src_len, void **abstract)
|
||||
{
|
||||
z_stream *strm = *abstract;
|
||||
/* A short-term alloc of a full data chunk is better than a series of
|
||||
reallocs */
|
||||
char *out;
|
||||
size_t out_maxlen = src_len;
|
||||
|
||||
if(src_len <= SIZE_MAX / 4)
|
||||
out_maxlen = src_len * 4;
|
||||
else
|
||||
out_maxlen = payload_limit;
|
||||
|
||||
/* If strm is null, then we have not yet been initialized. */
|
||||
if(strm == NULL)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_COMPRESS,
|
||||
"decompression uninitialized");;
|
||||
|
||||
/* In practice they never come smaller than this */
|
||||
if(out_maxlen < 25)
|
||||
out_maxlen = 25;
|
||||
|
||||
if(out_maxlen > payload_limit)
|
||||
out_maxlen = payload_limit;
|
||||
|
||||
strm->next_in = (unsigned char *) src;
|
||||
strm->avail_in = src_len;
|
||||
strm->next_out = (unsigned char *) LIBSSH2_ALLOC(session, out_maxlen);
|
||||
out = (char *) strm->next_out;
|
||||
strm->avail_out = out_maxlen;
|
||||
if(!strm->next_out)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate decompression buffer");
|
||||
|
||||
/* Loop until it's all inflated or hit error */
|
||||
for(;;) {
|
||||
int status;
|
||||
size_t out_ofs;
|
||||
char *newout;
|
||||
|
||||
status = inflate(strm, Z_PARTIAL_FLUSH);
|
||||
|
||||
if(status == Z_OK) {
|
||||
if(strm->avail_out > 0)
|
||||
/* status is OK and the output buffer has not been exhausted
|
||||
so we're done */
|
||||
break;
|
||||
}
|
||||
else if(status == Z_BUF_ERROR) {
|
||||
/* the input data has been exhausted so we are done */
|
||||
break;
|
||||
}
|
||||
else {
|
||||
/* error state */
|
||||
LIBSSH2_FREE(session, out);
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS,
|
||||
"unhandled zlib error %d", status);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"decompression failure");
|
||||
}
|
||||
|
||||
if(out_maxlen > payload_limit || out_maxlen > SIZE_MAX / 2) {
|
||||
LIBSSH2_FREE(session, out);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ZLIB,
|
||||
"Excessive growth in decompression phase");
|
||||
}
|
||||
|
||||
/* If we get here we need to grow the output buffer and try again */
|
||||
out_ofs = out_maxlen - strm->avail_out;
|
||||
out_maxlen *= 2;
|
||||
newout = LIBSSH2_REALLOC(session, out, out_maxlen);
|
||||
if(!newout) {
|
||||
LIBSSH2_FREE(session, out);
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to expand decompression buffer");
|
||||
}
|
||||
out = newout;
|
||||
strm->next_out = (unsigned char *) out + out_ofs;
|
||||
strm->avail_out = out_maxlen - out_ofs;
|
||||
}
|
||||
|
||||
*dest = (unsigned char *) out;
|
||||
*dest_len = out_maxlen - strm->avail_out;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* libssh2_comp_method_zlib_dtor
|
||||
* All done, no more compression for you
|
||||
*/
|
||||
static int
|
||||
comp_method_zlib_dtor(LIBSSH2_SESSION *session, int compr, void **abstract)
|
||||
{
|
||||
z_stream *strm = *abstract;
|
||||
|
||||
if(strm) {
|
||||
if(compr)
|
||||
deflateEnd(strm);
|
||||
else
|
||||
inflateEnd(strm);
|
||||
LIBSSH2_FREE(session, strm);
|
||||
}
|
||||
|
||||
*abstract = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const LIBSSH2_COMP_METHOD comp_method_zlib = {
|
||||
"zlib",
|
||||
1, /* yes, this compresses */
|
||||
1, /* do compression during userauth */
|
||||
comp_method_zlib_init,
|
||||
comp_method_zlib_comp,
|
||||
comp_method_zlib_decomp,
|
||||
comp_method_zlib_dtor,
|
||||
};
|
||||
|
||||
static const LIBSSH2_COMP_METHOD comp_method_zlib_openssh = {
|
||||
"zlib@openssh.com",
|
||||
1, /* yes, this compresses */
|
||||
0, /* don't use compression during userauth */
|
||||
comp_method_zlib_init,
|
||||
comp_method_zlib_comp,
|
||||
comp_method_zlib_decomp,
|
||||
comp_method_zlib_dtor,
|
||||
};
|
||||
#endif /* LIBSSH2_HAVE_ZLIB */
|
||||
|
||||
/* If compression is enabled by the API, then this array is used which then
|
||||
may allow compression if zlib is available at build time */
|
||||
static const LIBSSH2_COMP_METHOD *comp_methods[] = {
|
||||
#ifdef LIBSSH2_HAVE_ZLIB
|
||||
&comp_method_zlib,
|
||||
&comp_method_zlib_openssh,
|
||||
#endif /* LIBSSH2_HAVE_ZLIB */
|
||||
&comp_method_none,
|
||||
NULL
|
||||
};
|
||||
|
||||
/* If compression is disabled by the API, then this array is used */
|
||||
static const LIBSSH2_COMP_METHOD *no_comp_methods[] = {
|
||||
&comp_method_none,
|
||||
NULL
|
||||
};
|
||||
|
||||
const LIBSSH2_COMP_METHOD **
|
||||
_libssh2_comp_methods(LIBSSH2_SESSION *session)
|
||||
{
|
||||
if(session->flag.compress)
|
||||
return comp_methods;
|
||||
else
|
||||
return no_comp_methods;
|
||||
}
|
||||
#endif
|
||||
46
lib/libssh2/comp.h
Normal file
46
lib/libssh2/comp.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_COMP_H
|
||||
#define __LIBSSH2_COMP_H
|
||||
/* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
|
||||
const LIBSSH2_COMP_METHOD **_libssh2_comp_methods(LIBSSH2_SESSION *session);
|
||||
|
||||
#endif /* __LIBSSH2_COMP_H */
|
||||
#endif
|
||||
353
lib/libssh2/crypt.c
Normal file
353
lib/libssh2/crypt.c
Normal file
@@ -0,0 +1,353 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (c) 2009, 2010 Simon Josefsson <simon@josefsson.org>
|
||||
* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
|
||||
#ifdef LIBSSH2_CRYPT_NONE
|
||||
|
||||
/* crypt_none_crypt
|
||||
* Minimalist cipher: VERY secure *wink*
|
||||
*/
|
||||
static int
|
||||
crypt_none_crypt(LIBSSH2_SESSION * session, unsigned char *buf,
|
||||
void **abstract)
|
||||
{
|
||||
/* Do nothing to the data! */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_none = {
|
||||
"none",
|
||||
"DEK-Info: NONE",
|
||||
8, /* blocksize (SSH2 defines minimum blocksize as 8) */
|
||||
0, /* iv_len */
|
||||
0, /* secret_len */
|
||||
0, /* flags */
|
||||
NULL,
|
||||
crypt_none_crypt,
|
||||
NULL
|
||||
};
|
||||
#endif /* LIBSSH2_CRYPT_NONE */
|
||||
|
||||
struct crypt_ctx
|
||||
{
|
||||
int encrypt;
|
||||
_libssh2_cipher_type(algo);
|
||||
_libssh2_cipher_ctx h;
|
||||
};
|
||||
|
||||
static int
|
||||
crypt_init(LIBSSH2_SESSION * session,
|
||||
const LIBSSH2_CRYPT_METHOD * method,
|
||||
unsigned char *iv, int *free_iv,
|
||||
unsigned char *secret, int *free_secret,
|
||||
int encrypt, void **abstract)
|
||||
{
|
||||
struct crypt_ctx *ctx = LIBSSH2_ALLOC(session,
|
||||
sizeof(struct crypt_ctx));
|
||||
if(!ctx)
|
||||
return LIBSSH2_ERROR_ALLOC;
|
||||
|
||||
ctx->encrypt = encrypt;
|
||||
ctx->algo = method->algo;
|
||||
if(_libssh2_cipher_init(&ctx->h, ctx->algo, iv, secret, encrypt)) {
|
||||
LIBSSH2_FREE(session, ctx);
|
||||
return -1;
|
||||
}
|
||||
*abstract = ctx;
|
||||
*free_iv = 1;
|
||||
*free_secret = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
crypt_encrypt(LIBSSH2_SESSION * session, unsigned char *block,
|
||||
size_t blocksize, void **abstract)
|
||||
{
|
||||
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
|
||||
(void) session;
|
||||
return _libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
|
||||
blocksize);
|
||||
}
|
||||
|
||||
static int
|
||||
crypt_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||
{
|
||||
struct crypt_ctx **cctx = (struct crypt_ctx **) abstract;
|
||||
if(cctx && *cctx) {
|
||||
_libssh2_cipher_dtor(&(*cctx)->h);
|
||||
LIBSSH2_FREE(session, *cctx);
|
||||
*abstract = NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if LIBSSH2_AES_CTR
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_ctr = {
|
||||
"aes128-ctr",
|
||||
"",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
16, /* secret length -- 16*8 == 128bit */
|
||||
0, /* flags */
|
||||
&crypt_init,
|
||||
&crypt_encrypt,
|
||||
&crypt_dtor,
|
||||
_libssh2_cipher_aes128ctr
|
||||
};
|
||||
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_ctr = {
|
||||
"aes192-ctr",
|
||||
"",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
24, /* secret length -- 24*8 == 192bit */
|
||||
0, /* flags */
|
||||
&crypt_init,
|
||||
&crypt_encrypt,
|
||||
&crypt_dtor,
|
||||
_libssh2_cipher_aes192ctr
|
||||
};
|
||||
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_ctr = {
|
||||
"aes256-ctr",
|
||||
"",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
32, /* secret length -- 32*8 == 256bit */
|
||||
0, /* flags */
|
||||
&crypt_init,
|
||||
&crypt_encrypt,
|
||||
&crypt_dtor,
|
||||
_libssh2_cipher_aes256ctr
|
||||
};
|
||||
#endif
|
||||
|
||||
#if LIBSSH2_AES
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes128_cbc = {
|
||||
"aes128-cbc",
|
||||
"DEK-Info: AES-128-CBC",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
16, /* secret length -- 16*8 == 128bit */
|
||||
0, /* flags */
|
||||
&crypt_init,
|
||||
&crypt_encrypt,
|
||||
&crypt_dtor,
|
||||
_libssh2_cipher_aes128
|
||||
};
|
||||
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes192_cbc = {
|
||||
"aes192-cbc",
|
||||
"DEK-Info: AES-192-CBC",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
24, /* secret length -- 24*8 == 192bit */
|
||||
0, /* flags */
|
||||
&crypt_init,
|
||||
&crypt_encrypt,
|
||||
&crypt_dtor,
|
||||
_libssh2_cipher_aes192
|
||||
};
|
||||
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_aes256_cbc = {
|
||||
"aes256-cbc",
|
||||
"DEK-Info: AES-256-CBC",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
32, /* secret length -- 32*8 == 256bit */
|
||||
0, /* flags */
|
||||
&crypt_init,
|
||||
&crypt_encrypt,
|
||||
&crypt_dtor,
|
||||
_libssh2_cipher_aes256
|
||||
};
|
||||
|
||||
/* rijndael-cbc@lysator.liu.se == aes256-cbc */
|
||||
static const LIBSSH2_CRYPT_METHOD
|
||||
libssh2_crypt_method_rijndael_cbc_lysator_liu_se = {
|
||||
"rijndael-cbc@lysator.liu.se",
|
||||
"DEK-Info: AES-256-CBC",
|
||||
16, /* blocksize */
|
||||
16, /* initial value length */
|
||||
32, /* secret length -- 32*8 == 256bit */
|
||||
0, /* flags */
|
||||
&crypt_init,
|
||||
&crypt_encrypt,
|
||||
&crypt_dtor,
|
||||
_libssh2_cipher_aes256
|
||||
};
|
||||
#endif /* LIBSSH2_AES */
|
||||
|
||||
#if LIBSSH2_BLOWFISH
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_blowfish_cbc = {
|
||||
"blowfish-cbc",
|
||||
"",
|
||||
8, /* blocksize */
|
||||
8, /* initial value length */
|
||||
16, /* secret length */
|
||||
0, /* flags */
|
||||
&crypt_init,
|
||||
&crypt_encrypt,
|
||||
&crypt_dtor,
|
||||
_libssh2_cipher_blowfish
|
||||
};
|
||||
#endif /* LIBSSH2_BLOWFISH */
|
||||
|
||||
#if LIBSSH2_RC4
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour = {
|
||||
"arcfour",
|
||||
"DEK-Info: RC4",
|
||||
8, /* blocksize */
|
||||
8, /* initial value length */
|
||||
16, /* secret length */
|
||||
0, /* flags */
|
||||
&crypt_init,
|
||||
&crypt_encrypt,
|
||||
&crypt_dtor,
|
||||
_libssh2_cipher_arcfour
|
||||
};
|
||||
|
||||
static int
|
||||
crypt_init_arcfour128(LIBSSH2_SESSION * session,
|
||||
const LIBSSH2_CRYPT_METHOD * method,
|
||||
unsigned char *iv, int *free_iv,
|
||||
unsigned char *secret, int *free_secret,
|
||||
int encrypt, void **abstract)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = crypt_init(session, method, iv, free_iv, secret, free_secret,
|
||||
encrypt, abstract);
|
||||
if(rc == 0) {
|
||||
struct crypt_ctx *cctx = *(struct crypt_ctx **) abstract;
|
||||
unsigned char block[8];
|
||||
size_t discard = 1536;
|
||||
for(; discard; discard -= 8)
|
||||
_libssh2_cipher_crypt(&cctx->h, cctx->algo, cctx->encrypt, block,
|
||||
method->blocksize);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_arcfour128 = {
|
||||
"arcfour128",
|
||||
"",
|
||||
8, /* blocksize */
|
||||
8, /* initial value length */
|
||||
16, /* secret length */
|
||||
0, /* flags */
|
||||
&crypt_init_arcfour128,
|
||||
&crypt_encrypt,
|
||||
&crypt_dtor,
|
||||
_libssh2_cipher_arcfour
|
||||
};
|
||||
#endif /* LIBSSH2_RC4 */
|
||||
|
||||
#if LIBSSH2_CAST
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_cast128_cbc = {
|
||||
"cast128-cbc",
|
||||
"",
|
||||
8, /* blocksize */
|
||||
8, /* initial value length */
|
||||
16, /* secret length */
|
||||
0, /* flags */
|
||||
&crypt_init,
|
||||
&crypt_encrypt,
|
||||
&crypt_dtor,
|
||||
_libssh2_cipher_cast5
|
||||
};
|
||||
#endif /* LIBSSH2_CAST */
|
||||
|
||||
#if LIBSSH2_3DES
|
||||
static const LIBSSH2_CRYPT_METHOD libssh2_crypt_method_3des_cbc = {
|
||||
"3des-cbc",
|
||||
"DEK-Info: DES-EDE3-CBC",
|
||||
8, /* blocksize */
|
||||
8, /* initial value length */
|
||||
24, /* secret length */
|
||||
0, /* flags */
|
||||
&crypt_init,
|
||||
&crypt_encrypt,
|
||||
&crypt_dtor,
|
||||
_libssh2_cipher_3des
|
||||
};
|
||||
#endif
|
||||
|
||||
/* These are the crypt methods that are available to be negotiated. Methods
|
||||
towards the start are chosen in preference to ones further down the list. */
|
||||
static const LIBSSH2_CRYPT_METHOD *_libssh2_crypt_methods[] = {
|
||||
#if LIBSSH2_AES_CTR
|
||||
&libssh2_crypt_method_aes256_ctr,
|
||||
&libssh2_crypt_method_aes192_ctr,
|
||||
&libssh2_crypt_method_aes128_ctr,
|
||||
#endif /* LIBSSH2_AES */
|
||||
#if LIBSSH2_AES
|
||||
&libssh2_crypt_method_aes256_cbc,
|
||||
&libssh2_crypt_method_rijndael_cbc_lysator_liu_se, /* == aes256-cbc */
|
||||
&libssh2_crypt_method_aes192_cbc,
|
||||
&libssh2_crypt_method_aes128_cbc,
|
||||
#endif /* LIBSSH2_AES */
|
||||
#if LIBSSH2_BLOWFISH
|
||||
&libssh2_crypt_method_blowfish_cbc,
|
||||
#endif /* LIBSSH2_BLOWFISH */
|
||||
#if LIBSSH2_RC4
|
||||
&libssh2_crypt_method_arcfour128,
|
||||
&libssh2_crypt_method_arcfour,
|
||||
#endif /* LIBSSH2_RC4 */
|
||||
#if LIBSSH2_CAST
|
||||
&libssh2_crypt_method_cast128_cbc,
|
||||
#endif /* LIBSSH2_CAST */
|
||||
#if LIBSSH2_3DES
|
||||
&libssh2_crypt_method_3des_cbc,
|
||||
#endif /* LIBSSH2_DES */
|
||||
#ifdef LIBSSH2_CRYPT_NONE
|
||||
&libssh2_crypt_method_none,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
/* Expose to kex.c */
|
||||
const LIBSSH2_CRYPT_METHOD **
|
||||
libssh2_crypt_methods(void)
|
||||
{
|
||||
return _libssh2_crypt_methods;
|
||||
}
|
||||
#endif
|
||||
338
lib/libssh2/crypto.h
Normal file
338
lib/libssh2/crypto.h
Normal file
@@ -0,0 +1,338 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_CRYPTO_H
|
||||
#define __LIBSSH2_CRYPTO_H
|
||||
/* Copyright (C) 2009, 2010 Simon Josefsson
|
||||
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
||||
* Copyright (C) 2010-2019 Daniel Stenberg
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBSSH2_OPENSSL) || defined(LIBSSH2_WOLFSSL)
|
||||
#include "openssl.h"
|
||||
#endif
|
||||
|
||||
#ifdef LIBSSH2_LIBGCRYPT
|
||||
#include "libgcrypt.h"
|
||||
#endif
|
||||
|
||||
#ifdef LIBSSH2_WINCNG
|
||||
#include "wincng.h"
|
||||
#endif
|
||||
|
||||
#ifdef LIBSSH2_OS400QC3
|
||||
#include "os400qc3.h"
|
||||
#endif
|
||||
|
||||
#ifdef LIBSSH2_MBEDTLS
|
||||
#include "mbedtls.h"
|
||||
#endif
|
||||
|
||||
#define LIBSSH2_ED25519_KEY_LEN 32
|
||||
#define LIBSSH2_ED25519_PRIVATE_KEY_LEN 64
|
||||
#define LIBSSH2_ED25519_SIG_LEN 64
|
||||
|
||||
#if LIBSSH2_RSA
|
||||
int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
|
||||
const unsigned char *edata,
|
||||
unsigned long elen,
|
||||
const unsigned char *ndata,
|
||||
unsigned long nlen,
|
||||
const unsigned char *ddata,
|
||||
unsigned long dlen,
|
||||
const unsigned char *pdata,
|
||||
unsigned long plen,
|
||||
const unsigned char *qdata,
|
||||
unsigned long qlen,
|
||||
const unsigned char *e1data,
|
||||
unsigned long e1len,
|
||||
const unsigned char *e2data,
|
||||
unsigned long e2len,
|
||||
const unsigned char *coeffdata, unsigned long coefflen);
|
||||
int _libssh2_rsa_new_private(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filename,
|
||||
unsigned const char *passphrase);
|
||||
int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx * rsa,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m, unsigned long m_len);
|
||||
int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION * session,
|
||||
libssh2_rsa_ctx * rsactx,
|
||||
const unsigned char *hash,
|
||||
size_t hash_len,
|
||||
unsigned char **signature,
|
||||
size_t *signature_len);
|
||||
#if LIBSSH2_RSA_SHA2
|
||||
int _libssh2_rsa_sha2_sign(LIBSSH2_SESSION * session,
|
||||
libssh2_rsa_ctx * rsactx,
|
||||
const unsigned char *hash,
|
||||
size_t hash_len,
|
||||
unsigned char **signature,
|
||||
size_t *signature_len);
|
||||
int _libssh2_rsa_sha2_verify(libssh2_rsa_ctx * rsa,
|
||||
size_t hash_len,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m, unsigned long m_len);
|
||||
#endif
|
||||
int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase);
|
||||
#endif
|
||||
|
||||
#if LIBSSH2_DSA
|
||||
int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
|
||||
const unsigned char *pdata,
|
||||
unsigned long plen,
|
||||
const unsigned char *qdata,
|
||||
unsigned long qlen,
|
||||
const unsigned char *gdata,
|
||||
unsigned long glen,
|
||||
const unsigned char *ydata,
|
||||
unsigned long ylen,
|
||||
const unsigned char *x, unsigned long x_len);
|
||||
int _libssh2_dsa_new_private(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filename,
|
||||
unsigned const char *passphrase);
|
||||
int _libssh2_dsa_sha1_verify(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *sig,
|
||||
const unsigned char *m, unsigned long m_len);
|
||||
int _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len, unsigned char *sig);
|
||||
int _libssh2_dsa_new_private_frommemory(libssh2_dsa_ctx ** dsa,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase);
|
||||
#endif
|
||||
|
||||
#if LIBSSH2_ECDSA
|
||||
int
|
||||
_libssh2_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx ** ecdsactx,
|
||||
const unsigned char *k,
|
||||
size_t k_len,
|
||||
libssh2_curve_type type);
|
||||
|
||||
int
|
||||
_libssh2_ecdsa_new_private(libssh2_ecdsa_ctx ** ec_ctx,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filename,
|
||||
unsigned const char *passphrase);
|
||||
|
||||
int
|
||||
_libssh2_ecdsa_new_private_sk(libssh2_ecdsa_ctx ** ec_ctx,
|
||||
unsigned char *flags,
|
||||
const char **application,
|
||||
const unsigned char **key_handle,
|
||||
size_t *handle_len,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filename,
|
||||
unsigned const char *passphrase);
|
||||
|
||||
int
|
||||
_libssh2_ecdsa_verify(libssh2_ecdsa_ctx * ctx,
|
||||
const unsigned char *r, size_t r_len,
|
||||
const unsigned char *s, size_t s_len,
|
||||
const unsigned char *m, size_t m_len);
|
||||
|
||||
int
|
||||
_libssh2_ecdsa_create_key(LIBSSH2_SESSION *session,
|
||||
_libssh2_ec_key **out_private_key,
|
||||
unsigned char **out_public_key_octal,
|
||||
size_t *out_public_key_octal_len,
|
||||
libssh2_curve_type curve_type);
|
||||
|
||||
int
|
||||
_libssh2_ecdh_gen_k(_libssh2_bn **k, _libssh2_ec_key *private_key,
|
||||
const unsigned char *server_public_key,
|
||||
size_t server_public_key_len);
|
||||
|
||||
int
|
||||
_libssh2_ecdsa_sign(LIBSSH2_SESSION *session, libssh2_ecdsa_ctx *ec_ctx,
|
||||
const unsigned char *hash, unsigned long hash_len,
|
||||
unsigned char **signature, size_t *signature_len);
|
||||
|
||||
int _libssh2_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx ** ec_ctx,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase);
|
||||
|
||||
int _libssh2_ecdsa_new_private_frommemory_sk(libssh2_ecdsa_ctx ** ec_ctx,
|
||||
unsigned char *flags,
|
||||
const char **application,
|
||||
const unsigned char **key_handle,
|
||||
size_t *handle_len,
|
||||
LIBSSH2_SESSION * session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase);
|
||||
|
||||
libssh2_curve_type
|
||||
_libssh2_ecdsa_get_curve_type(libssh2_ecdsa_ctx *ec_ctx);
|
||||
|
||||
int
|
||||
_libssh2_ecdsa_curve_type_from_name(const char *name,
|
||||
libssh2_curve_type *out_type);
|
||||
|
||||
#endif /* LIBSSH2_ECDSA */
|
||||
|
||||
#if LIBSSH2_ED25519
|
||||
|
||||
int
|
||||
_libssh2_curve25519_new(LIBSSH2_SESSION *session, uint8_t **out_public_key,
|
||||
uint8_t **out_private_key);
|
||||
|
||||
int
|
||||
_libssh2_curve25519_gen_k(_libssh2_bn **k,
|
||||
uint8_t private_key[LIBSSH2_ED25519_KEY_LEN],
|
||||
uint8_t server_public_key[LIBSSH2_ED25519_KEY_LEN]);
|
||||
|
||||
int
|
||||
_libssh2_ed25519_verify(libssh2_ed25519_ctx *ctx, const uint8_t *s,
|
||||
size_t s_len, const uint8_t *m, size_t m_len);
|
||||
|
||||
int
|
||||
_libssh2_ed25519_new_private(libssh2_ed25519_ctx **ed_ctx,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filename, const uint8_t *passphrase);
|
||||
|
||||
int
|
||||
_libssh2_ed25519_new_private_sk(libssh2_ed25519_ctx **ed_ctx,
|
||||
unsigned char *flags,
|
||||
const char **application,
|
||||
const unsigned char **key_handle,
|
||||
size_t *handle_len,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filename,
|
||||
const uint8_t *passphrase);
|
||||
|
||||
int
|
||||
_libssh2_ed25519_new_public(libssh2_ed25519_ctx **ed_ctx,
|
||||
LIBSSH2_SESSION *session,
|
||||
const unsigned char *raw_pub_key,
|
||||
const uint8_t key_len);
|
||||
|
||||
int
|
||||
_libssh2_ed25519_sign(libssh2_ed25519_ctx *ctx, LIBSSH2_SESSION *session,
|
||||
uint8_t **out_sig, size_t *out_sig_len,
|
||||
const uint8_t *message, size_t message_len);
|
||||
|
||||
int
|
||||
_libssh2_ed25519_new_private_frommemory(libssh2_ed25519_ctx **ed_ctx,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase);
|
||||
|
||||
int
|
||||
_libssh2_ed25519_new_private_frommemory_sk(libssh2_ed25519_ctx **ed_ctx,
|
||||
unsigned char *flags,
|
||||
const char **application,
|
||||
const unsigned char **key_handle,
|
||||
size_t *handle_len,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase);
|
||||
|
||||
#endif /* LIBSSH2_ED25519 */
|
||||
|
||||
|
||||
int _libssh2_cipher_init(_libssh2_cipher_ctx * h,
|
||||
_libssh2_cipher_type(algo),
|
||||
unsigned char *iv,
|
||||
unsigned char *secret, int encrypt);
|
||||
|
||||
int _libssh2_cipher_crypt(_libssh2_cipher_ctx * ctx,
|
||||
_libssh2_cipher_type(algo),
|
||||
int encrypt, unsigned char *block, size_t blocksize);
|
||||
|
||||
int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekey,
|
||||
const char *passphrase);
|
||||
|
||||
int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekeydata,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase);
|
||||
|
||||
|
||||
int _libssh2_sk_pub_keyfilememory(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
int *algorithm,
|
||||
unsigned char *flags,
|
||||
const char **application,
|
||||
const unsigned char **key_handle,
|
||||
size_t *handle_len,
|
||||
const char *privatekeydata,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase);
|
||||
|
||||
/**
|
||||
* @function _libssh2_supported_key_sign_algorithms
|
||||
* @abstract Returns supported algorithms used for upgrading public
|
||||
* key signing RFC 8332
|
||||
* @discussion Based on the incoming key_method value, this function
|
||||
* will return supported algorithms that can upgrade the key method
|
||||
* @related _libssh2_key_sign_algorithm()
|
||||
* @param key_method current key method, usually the default key sig method
|
||||
* @param key_method_len length of the key method buffer
|
||||
* @result comma seperated list of supported upgrade options per RFC 8332, if
|
||||
* there is no upgrade option return NULL
|
||||
*/
|
||||
|
||||
const char *
|
||||
_libssh2_supported_key_sign_algorithms(LIBSSH2_SESSION *session,
|
||||
unsigned char *key_method,
|
||||
size_t key_method_len);
|
||||
|
||||
#endif /* __LIBSSH2_CRYPTO_H */
|
||||
#endif
|
||||
80
lib/libssh2/global.c
Normal file
80
lib/libssh2/global.c
Normal file
@@ -0,0 +1,80 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (c) 2010 Lars Nordin <Lars.Nordin@SDlabs.se>
|
||||
* Copyright (C) 2010 Simon Josefsson <simon@josefsson.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
|
||||
static int _libssh2_initialized = 0;
|
||||
static int _libssh2_init_flags = 0;
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_init(int flags)
|
||||
{
|
||||
if(_libssh2_initialized == 0 && !(flags & LIBSSH2_INIT_NO_CRYPTO)) {
|
||||
libssh2_crypto_init();
|
||||
}
|
||||
|
||||
_libssh2_initialized++;
|
||||
_libssh2_init_flags |= flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBSSH2_API void
|
||||
libssh2_exit(void)
|
||||
{
|
||||
if(_libssh2_initialized == 0)
|
||||
return;
|
||||
|
||||
_libssh2_initialized--;
|
||||
|
||||
if(_libssh2_initialized == 0 &&
|
||||
!(_libssh2_init_flags & LIBSSH2_INIT_NO_CRYPTO)) {
|
||||
libssh2_crypto_exit();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
_libssh2_init_if_needed(void)
|
||||
{
|
||||
if(_libssh2_initialized == 0)
|
||||
(void)libssh2_init (0);
|
||||
}
|
||||
#endif
|
||||
1389
lib/libssh2/hostkey.c
Normal file
1389
lib/libssh2/hostkey.c
Normal file
File diff suppressed because it is too large
Load Diff
102
lib/libssh2/keepalive.c
Normal file
102
lib/libssh2/keepalive.c
Normal file
@@ -0,0 +1,102 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (C) 2010 Simon Josefsson
|
||||
* Author: Simon Josefsson
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include "transport.h" /* _libssh2_transport_write */
|
||||
|
||||
/* Keep-alive stuff. */
|
||||
|
||||
LIBSSH2_API void
|
||||
libssh2_keepalive_config (LIBSSH2_SESSION *session,
|
||||
int want_reply,
|
||||
unsigned interval)
|
||||
{
|
||||
if(interval == 1)
|
||||
session->keepalive_interval = 2;
|
||||
else
|
||||
session->keepalive_interval = interval;
|
||||
session->keepalive_want_reply = want_reply ? 1 : 0;
|
||||
}
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_keepalive_send (LIBSSH2_SESSION *session,
|
||||
int *seconds_to_next)
|
||||
{
|
||||
time_t now;
|
||||
|
||||
if(!session->keepalive_interval) {
|
||||
if(seconds_to_next)
|
||||
*seconds_to_next = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
if(session->keepalive_last_sent + session->keepalive_interval <= now) {
|
||||
/* Format is
|
||||
"SSH_MSG_GLOBAL_REQUEST || 4-byte len || str || want-reply". */
|
||||
unsigned char keepalive_data[]
|
||||
= "\x50\x00\x00\x00\x15keepalive@libssh2.orgW";
|
||||
size_t len = sizeof(keepalive_data) - 1;
|
||||
int rc;
|
||||
|
||||
keepalive_data[len - 1] =
|
||||
(unsigned char)session->keepalive_want_reply;
|
||||
|
||||
rc = _libssh2_transport_send(session, keepalive_data, len, NULL, 0);
|
||||
/* Silently ignore PACKET_EAGAIN here: if the write buffer is
|
||||
already full, sending another keepalive is not useful. */
|
||||
if(rc && rc != LIBSSH2_ERROR_EAGAIN) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_SOCKET_SEND,
|
||||
"Unable to send keepalive message");
|
||||
return rc;
|
||||
}
|
||||
|
||||
session->keepalive_last_sent = now;
|
||||
if(seconds_to_next)
|
||||
*seconds_to_next = session->keepalive_interval;
|
||||
}
|
||||
else if(seconds_to_next) {
|
||||
*seconds_to_next = (int) (session->keepalive_last_sent - now)
|
||||
+ session->keepalive_interval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
4165
lib/libssh2/kex.c
Normal file
4165
lib/libssh2/kex.c
Normal file
File diff suppressed because it is too large
Load Diff
240
lib/libssh2/libgcrypt.h
Normal file
240
lib/libssh2/libgcrypt.h
Normal file
@@ -0,0 +1,240 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_LIBGCRYPT_H
|
||||
#define __LIBSSH2_LIBGCRYPT_H
|
||||
/*
|
||||
* Copyright (C) 2008, 2009, 2010 Simon Josefsson
|
||||
* Copyright (C) 2006, 2007, The Written Word, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <gcrypt.h>
|
||||
|
||||
#define LIBSSH2_MD5 1
|
||||
|
||||
#define LIBSSH2_HMAC_RIPEMD 1
|
||||
#define LIBSSH2_HMAC_SHA256 1
|
||||
#define LIBSSH2_HMAC_SHA512 1
|
||||
|
||||
#define LIBSSH2_AES 1
|
||||
#define LIBSSH2_AES_CTR 1
|
||||
#define LIBSSH2_BLOWFISH 1
|
||||
#define LIBSSH2_RC4 1
|
||||
#define LIBSSH2_CAST 1
|
||||
#define LIBSSH2_3DES 1
|
||||
|
||||
#define LIBSSH2_RSA 1
|
||||
#define LIBSSH2_RSA_SHA2 0
|
||||
#define LIBSSH2_DSA 1
|
||||
#define LIBSSH2_ECDSA 0
|
||||
#define LIBSSH2_ED25519 0
|
||||
|
||||
#define MD5_DIGEST_LENGTH 16
|
||||
#define SHA_DIGEST_LENGTH 20
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
#define SHA384_DIGEST_LENGTH 48
|
||||
#define SHA512_DIGEST_LENGTH 64
|
||||
|
||||
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
|
||||
|
||||
#define _libssh2_random(buf, len) \
|
||||
(gcry_randomize ((buf), (len), GCRY_STRONG_RANDOM), 0)
|
||||
|
||||
#define libssh2_prepare_iovec(vec, len) /* Empty. */
|
||||
|
||||
#define libssh2_sha1_ctx gcry_md_hd_t
|
||||
|
||||
/* returns 0 in case of failure */
|
||||
#define libssh2_sha1_init(ctx) \
|
||||
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA1, 0))
|
||||
#define libssh2_sha1_update(ctx, data, len) \
|
||||
gcry_md_write(ctx, (unsigned char *) data, len)
|
||||
#define libssh2_sha1_final(ctx, out) \
|
||||
memcpy(out, gcry_md_read(ctx, 0), SHA_DIGEST_LENGTH), gcry_md_close(ctx)
|
||||
#define libssh2_sha1(message, len, out) \
|
||||
gcry_md_hash_buffer(GCRY_MD_SHA1, out, message, len)
|
||||
|
||||
#define libssh2_sha256_ctx gcry_md_hd_t
|
||||
|
||||
#define libssh2_sha256_init(ctx) \
|
||||
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA256, 0))
|
||||
#define libssh2_sha256_update(ctx, data, len) \
|
||||
gcry_md_write(ctx, (unsigned char *) data, len)
|
||||
#define libssh2_sha256_final(ctx, out) \
|
||||
memcpy(out, gcry_md_read(ctx, 0), SHA256_DIGEST_LENGTH), gcry_md_close(ctx)
|
||||
#define libssh2_sha256(message, len, out) \
|
||||
gcry_md_hash_buffer(GCRY_MD_SHA256, out, message, len)
|
||||
|
||||
#define libssh2_sha384_ctx gcry_md_hd_t
|
||||
|
||||
#define libssh2_sha384_init(ctx) \
|
||||
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA384, 0))
|
||||
#define libssh2_sha384_update(ctx, data, len) \
|
||||
gcry_md_write(ctx, (unsigned char *) data, len)
|
||||
#define libssh2_sha384_final(ctx, out) \
|
||||
memcpy(out, gcry_md_read(ctx, 0), SHA384_DIGEST_LENGTH), gcry_md_close(ctx)
|
||||
#define libssh2_sha384(message, len, out) \
|
||||
gcry_md_hash_buffer(GCRY_MD_SHA384, out, message, len)
|
||||
|
||||
#define libssh2_sha512_ctx gcry_md_hd_t
|
||||
|
||||
#define libssh2_sha512_init(ctx) \
|
||||
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_SHA512, 0))
|
||||
#define libssh2_sha512_update(ctx, data, len) \
|
||||
gcry_md_write(ctx, (unsigned char *) data, len)
|
||||
#define libssh2_sha512_final(ctx, out) \
|
||||
memcpy(out, gcry_md_read(ctx, 0), SHA512_DIGEST_LENGTH), gcry_md_close(ctx)
|
||||
#define libssh2_sha512(message, len, out) \
|
||||
gcry_md_hash_buffer(GCRY_MD_SHA512, out, message, len)
|
||||
|
||||
#define libssh2_md5_ctx gcry_md_hd_t
|
||||
|
||||
/* returns 0 in case of failure */
|
||||
#define libssh2_md5_init(ctx) \
|
||||
(GPG_ERR_NO_ERROR == gcry_md_open(ctx, GCRY_MD_MD5, 0))
|
||||
|
||||
#define libssh2_md5_update(ctx, data, len) \
|
||||
gcry_md_write(ctx, (unsigned char *) data, len)
|
||||
#define libssh2_md5_final(ctx, out) \
|
||||
memcpy(out, gcry_md_read(ctx, 0), MD5_DIGEST_LENGTH), gcry_md_close(ctx)
|
||||
#define libssh2_md5(message, len, out) \
|
||||
gcry_md_hash_buffer(GCRY_MD_MD5, out, message, len)
|
||||
|
||||
#define libssh2_hmac_ctx gcry_md_hd_t
|
||||
#define libssh2_hmac_ctx_init(ctx)
|
||||
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
|
||||
gcry_md_open(ctx, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC), \
|
||||
gcry_md_setkey(*ctx, key, keylen)
|
||||
#define libssh2_hmac_md5_init(ctx, key, keylen) \
|
||||
gcry_md_open(ctx, GCRY_MD_MD5, GCRY_MD_FLAG_HMAC), \
|
||||
gcry_md_setkey(*ctx, key, keylen)
|
||||
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
|
||||
gcry_md_open(ctx, GCRY_MD_RMD160, GCRY_MD_FLAG_HMAC), \
|
||||
gcry_md_setkey(*ctx, key, keylen)
|
||||
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
|
||||
gcry_md_open(ctx, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC), \
|
||||
gcry_md_setkey(*ctx, key, keylen)
|
||||
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
|
||||
gcry_md_open(ctx, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC), \
|
||||
gcry_md_setkey(*ctx, key, keylen)
|
||||
#define libssh2_hmac_update(ctx, data, datalen) \
|
||||
gcry_md_write(ctx, (unsigned char *) data, datalen)
|
||||
#define libssh2_hmac_final(ctx, data) \
|
||||
memcpy(data, gcry_md_read(ctx, 0), \
|
||||
gcry_md_get_algo_dlen(gcry_md_get_algo(ctx)))
|
||||
#define libssh2_hmac_cleanup(ctx) gcry_md_close (*ctx);
|
||||
|
||||
#define libssh2_crypto_init() gcry_control (GCRYCTL_DISABLE_SECMEM)
|
||||
#define libssh2_crypto_exit()
|
||||
|
||||
#define libssh2_rsa_ctx struct gcry_sexp
|
||||
|
||||
#define _libssh2_rsa_free(rsactx) gcry_sexp_release (rsactx)
|
||||
|
||||
#define libssh2_dsa_ctx struct gcry_sexp
|
||||
|
||||
#define _libssh2_dsa_free(dsactx) gcry_sexp_release (dsactx)
|
||||
|
||||
#if LIBSSH2_ECDSA
|
||||
#else
|
||||
#define _libssh2_ec_key void
|
||||
#endif
|
||||
|
||||
#define _libssh2_cipher_type(name) int name
|
||||
#define _libssh2_cipher_ctx gcry_cipher_hd_t
|
||||
|
||||
#define _libssh2_gcry_ciphermode(c,m) ((c << 8) | m)
|
||||
#define _libssh2_gcry_cipher(c) (c >> 8)
|
||||
#define _libssh2_gcry_mode(m) (m & 0xFF)
|
||||
|
||||
#define _libssh2_cipher_aes256ctr \
|
||||
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR)
|
||||
#define _libssh2_cipher_aes192ctr \
|
||||
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR)
|
||||
#define _libssh2_cipher_aes128ctr \
|
||||
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CTR)
|
||||
#define _libssh2_cipher_aes256 \
|
||||
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC)
|
||||
#define _libssh2_cipher_aes192 \
|
||||
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC)
|
||||
#define _libssh2_cipher_aes128 \
|
||||
_libssh2_gcry_ciphermode(GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC)
|
||||
#define _libssh2_cipher_blowfish \
|
||||
_libssh2_gcry_ciphermode(GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC)
|
||||
#define _libssh2_cipher_arcfour \
|
||||
_libssh2_gcry_ciphermode(GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM)
|
||||
#define _libssh2_cipher_cast5 \
|
||||
_libssh2_gcry_ciphermode(GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC)
|
||||
#define _libssh2_cipher_3des \
|
||||
_libssh2_gcry_ciphermode(GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC)
|
||||
|
||||
|
||||
#define _libssh2_cipher_dtor(ctx) gcry_cipher_close(*(ctx))
|
||||
|
||||
#define _libssh2_bn struct gcry_mpi
|
||||
#define _libssh2_bn_ctx int
|
||||
#define _libssh2_bn_ctx_new() 0
|
||||
#define _libssh2_bn_ctx_free(bnctx) ((void)0)
|
||||
#define _libssh2_bn_init() gcry_mpi_new(0)
|
||||
#define _libssh2_bn_init_from_bin() NULL /* because gcry_mpi_scan() creates a
|
||||
new bignum */
|
||||
#define _libssh2_bn_set_word(bn, val) gcry_mpi_set_ui(bn, val)
|
||||
#define _libssh2_bn_from_bin(bn, len, val) \
|
||||
gcry_mpi_scan(&((bn)), GCRYMPI_FMT_USG, val, len, NULL)
|
||||
#define _libssh2_bn_to_bin(bn, val) \
|
||||
gcry_mpi_print(GCRYMPI_FMT_USG, val, _libssh2_bn_bytes(bn), NULL, bn)
|
||||
#define _libssh2_bn_bytes(bn) \
|
||||
(gcry_mpi_get_nbits (bn) / 8 + \
|
||||
((gcry_mpi_get_nbits (bn) % 8 == 0) ? 0 : 1))
|
||||
#define _libssh2_bn_bits(bn) gcry_mpi_get_nbits (bn)
|
||||
#define _libssh2_bn_free(bn) gcry_mpi_release(bn)
|
||||
|
||||
#define _libssh2_dh_ctx struct gcry_mpi *
|
||||
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
|
||||
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
|
||||
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
|
||||
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
|
||||
_libssh2_dh_secret(dhctx, secret, f, p)
|
||||
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
|
||||
extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx);
|
||||
extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
|
||||
_libssh2_bn *g, _libssh2_bn *p,
|
||||
int group_order);
|
||||
extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
|
||||
_libssh2_bn *f, _libssh2_bn *p);
|
||||
extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
|
||||
|
||||
#endif /* __LIBSSH2_LIBGCRYPT_H */
|
||||
#endif
|
||||
1418
lib/libssh2/libssh2.h
Normal file
1418
lib/libssh2/libssh2.h
Normal file
File diff suppressed because it is too large
Load Diff
75
lib/libssh2/libssh2_config.h
Normal file
75
lib/libssh2/libssh2_config.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (c) 2014 Alexander Lamaison <alexander.lamaison@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Headers */
|
||||
#define LIBSSH2_MBEDTLS
|
||||
#define HAVE_O_NONBLOCK
|
||||
#define HAVE_UNISTD_H
|
||||
#define HAVE_INTTYPES_H
|
||||
#define HAVE_STDLIB_H
|
||||
#define HAVE_SYS_SELECT_H
|
||||
#define HAVE_SYS_SOCKET_H
|
||||
#define HAVE_SYS_TIME_H
|
||||
#define HAVE_ARPA_INET_H
|
||||
#define HAVE_NETINET_IN_H
|
||||
|
||||
/* Functions */
|
||||
#define HAVE_STRCASECMP
|
||||
#define HAVE__STRICMP
|
||||
#define HAVE_SNPRINTF
|
||||
#define HAVE__SNPRINTF
|
||||
|
||||
/* Workaround for platforms without POSIX strcasecmp (e.g. Windows) */
|
||||
#ifndef HAVE_STRCASECMP
|
||||
# ifdef HAVE__STRICMP
|
||||
# define strcasecmp _stricmp
|
||||
# define HAVE_STRCASECMP
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Symbols */
|
||||
#define HAVE___FUNC__
|
||||
#define HAVE___FUNCTION__
|
||||
|
||||
/* Workaround for platforms without C90 __func__ */
|
||||
#ifndef HAVE___FUNC__
|
||||
# ifdef HAVE___FUNCTION__
|
||||
# define __func__ __FUNCTION__
|
||||
# define HAVE___FUNC__
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
1172
lib/libssh2/libssh2_priv.h
Normal file
1172
lib/libssh2/libssh2_priv.h
Normal file
File diff suppressed because it is too large
Load Diff
124
lib/libssh2/libssh2_publickey.h
Normal file
124
lib/libssh2/libssh2_publickey.h
Normal file
@@ -0,0 +1,124 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (c) 2004-2006, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Note: This include file is only needed for using the
|
||||
* publickey SUBSYSTEM which is not the same as publickey
|
||||
* authentication. For authentication you only need libssh2.h
|
||||
*
|
||||
* For more information on the publickey subsystem,
|
||||
* refer to IETF draft: secsh-publickey
|
||||
*/
|
||||
|
||||
#ifndef LIBSSH2_PUBLICKEY_H
|
||||
#define LIBSSH2_PUBLICKEY_H 1
|
||||
|
||||
#include "libssh2.h"
|
||||
|
||||
typedef struct _LIBSSH2_PUBLICKEY LIBSSH2_PUBLICKEY;
|
||||
|
||||
typedef struct _libssh2_publickey_attribute {
|
||||
const char *name;
|
||||
unsigned long name_len;
|
||||
const char *value;
|
||||
unsigned long value_len;
|
||||
char mandatory;
|
||||
} libssh2_publickey_attribute;
|
||||
|
||||
typedef struct _libssh2_publickey_list {
|
||||
unsigned char *packet; /* For freeing */
|
||||
|
||||
const unsigned char *name;
|
||||
unsigned long name_len;
|
||||
const unsigned char *blob;
|
||||
unsigned long blob_len;
|
||||
unsigned long num_attrs;
|
||||
libssh2_publickey_attribute *attrs; /* free me */
|
||||
} libssh2_publickey_list;
|
||||
|
||||
/* Generally use the first macro here, but if both name and value are string
|
||||
literals, you can use _fast() to take advantage of preprocessing */
|
||||
#define libssh2_publickey_attribute(name, value, mandatory) \
|
||||
{ (name), strlen(name), (value), strlen(value), (mandatory) },
|
||||
#define libssh2_publickey_attribute_fast(name, value, mandatory) \
|
||||
{ (name), sizeof(name) - 1, (value), sizeof(value) - 1, (mandatory) },
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Publickey Subsystem */
|
||||
LIBSSH2_API LIBSSH2_PUBLICKEY *
|
||||
libssh2_publickey_init(LIBSSH2_SESSION *session);
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_publickey_add_ex(LIBSSH2_PUBLICKEY *pkey,
|
||||
const unsigned char *name,
|
||||
unsigned long name_len,
|
||||
const unsigned char *blob,
|
||||
unsigned long blob_len, char overwrite,
|
||||
unsigned long num_attrs,
|
||||
const libssh2_publickey_attribute attrs[]);
|
||||
#define libssh2_publickey_add(pkey, name, blob, blob_len, overwrite, \
|
||||
num_attrs, attrs) \
|
||||
libssh2_publickey_add_ex((pkey), (name), strlen(name), (blob), (blob_len), \
|
||||
(overwrite), (num_attrs), (attrs))
|
||||
|
||||
LIBSSH2_API int libssh2_publickey_remove_ex(LIBSSH2_PUBLICKEY *pkey,
|
||||
const unsigned char *name,
|
||||
unsigned long name_len,
|
||||
const unsigned char *blob,
|
||||
unsigned long blob_len);
|
||||
#define libssh2_publickey_remove(pkey, name, blob, blob_len) \
|
||||
libssh2_publickey_remove_ex((pkey), (name), strlen(name), (blob), (blob_len))
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_publickey_list_fetch(LIBSSH2_PUBLICKEY *pkey,
|
||||
unsigned long *num_keys,
|
||||
libssh2_publickey_list **pkey_list);
|
||||
LIBSSH2_API void
|
||||
libssh2_publickey_list_free(LIBSSH2_PUBLICKEY *pkey,
|
||||
libssh2_publickey_list *pkey_list);
|
||||
|
||||
LIBSSH2_API int libssh2_publickey_shutdown(LIBSSH2_PUBLICKEY *pkey);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* ifndef: LIBSSH2_PUBLICKEY_H */
|
||||
#endif
|
||||
353
lib/libssh2/libssh2_sftp.h
Normal file
353
lib/libssh2/libssh2_sftp.h
Normal file
@@ -0,0 +1,353 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (c) 2004-2008, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef LIBSSH2_SFTP_H
|
||||
#define LIBSSH2_SFTP_H 1
|
||||
|
||||
#include "libssh2.h"
|
||||
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Note: Version 6 was documented at the time of writing
|
||||
* However it was marked as "DO NOT IMPLEMENT" due to pending changes
|
||||
*
|
||||
* Let's start with Version 3 (The version found in OpenSSH) and go from there
|
||||
*/
|
||||
#define LIBSSH2_SFTP_VERSION 3
|
||||
|
||||
typedef struct _LIBSSH2_SFTP LIBSSH2_SFTP;
|
||||
typedef struct _LIBSSH2_SFTP_HANDLE LIBSSH2_SFTP_HANDLE;
|
||||
typedef struct _LIBSSH2_SFTP_ATTRIBUTES LIBSSH2_SFTP_ATTRIBUTES;
|
||||
typedef struct _LIBSSH2_SFTP_STATVFS LIBSSH2_SFTP_STATVFS;
|
||||
|
||||
/* Flags for open_ex() */
|
||||
#define LIBSSH2_SFTP_OPENFILE 0
|
||||
#define LIBSSH2_SFTP_OPENDIR 1
|
||||
|
||||
/* Flags for rename_ex() */
|
||||
#define LIBSSH2_SFTP_RENAME_OVERWRITE 0x00000001
|
||||
#define LIBSSH2_SFTP_RENAME_ATOMIC 0x00000002
|
||||
#define LIBSSH2_SFTP_RENAME_NATIVE 0x00000004
|
||||
|
||||
/* Flags for stat_ex() */
|
||||
#define LIBSSH2_SFTP_STAT 0
|
||||
#define LIBSSH2_SFTP_LSTAT 1
|
||||
#define LIBSSH2_SFTP_SETSTAT 2
|
||||
|
||||
/* Flags for symlink_ex() */
|
||||
#define LIBSSH2_SFTP_SYMLINK 0
|
||||
#define LIBSSH2_SFTP_READLINK 1
|
||||
#define LIBSSH2_SFTP_REALPATH 2
|
||||
|
||||
/* Flags for sftp_mkdir() */
|
||||
#define LIBSSH2_SFTP_DEFAULT_MODE -1
|
||||
|
||||
/* SFTP attribute flag bits */
|
||||
#define LIBSSH2_SFTP_ATTR_SIZE 0x00000001
|
||||
#define LIBSSH2_SFTP_ATTR_UIDGID 0x00000002
|
||||
#define LIBSSH2_SFTP_ATTR_PERMISSIONS 0x00000004
|
||||
#define LIBSSH2_SFTP_ATTR_ACMODTIME 0x00000008
|
||||
#define LIBSSH2_SFTP_ATTR_EXTENDED 0x80000000
|
||||
|
||||
/* SFTP statvfs flag bits */
|
||||
#define LIBSSH2_SFTP_ST_RDONLY 0x00000001
|
||||
#define LIBSSH2_SFTP_ST_NOSUID 0x00000002
|
||||
|
||||
struct _LIBSSH2_SFTP_ATTRIBUTES {
|
||||
/* If flags & ATTR_* bit is set, then the value in this struct will be
|
||||
* meaningful Otherwise it should be ignored
|
||||
*/
|
||||
unsigned long flags;
|
||||
|
||||
libssh2_uint64_t filesize;
|
||||
unsigned long uid, gid;
|
||||
unsigned long permissions;
|
||||
unsigned long atime, mtime;
|
||||
};
|
||||
|
||||
struct _LIBSSH2_SFTP_STATVFS {
|
||||
libssh2_uint64_t f_bsize; /* file system block size */
|
||||
libssh2_uint64_t f_frsize; /* fragment size */
|
||||
libssh2_uint64_t f_blocks; /* size of fs in f_frsize units */
|
||||
libssh2_uint64_t f_bfree; /* # free blocks */
|
||||
libssh2_uint64_t f_bavail; /* # free blocks for non-root */
|
||||
libssh2_uint64_t f_files; /* # inodes */
|
||||
libssh2_uint64_t f_ffree; /* # free inodes */
|
||||
libssh2_uint64_t f_favail; /* # free inodes for non-root */
|
||||
libssh2_uint64_t f_fsid; /* file system ID */
|
||||
libssh2_uint64_t f_flag; /* mount flags */
|
||||
libssh2_uint64_t f_namemax; /* maximum filename length */
|
||||
};
|
||||
|
||||
/* SFTP filetypes */
|
||||
#define LIBSSH2_SFTP_TYPE_REGULAR 1
|
||||
#define LIBSSH2_SFTP_TYPE_DIRECTORY 2
|
||||
#define LIBSSH2_SFTP_TYPE_SYMLINK 3
|
||||
#define LIBSSH2_SFTP_TYPE_SPECIAL 4
|
||||
#define LIBSSH2_SFTP_TYPE_UNKNOWN 5
|
||||
#define LIBSSH2_SFTP_TYPE_SOCKET 6
|
||||
#define LIBSSH2_SFTP_TYPE_CHAR_DEVICE 7
|
||||
#define LIBSSH2_SFTP_TYPE_BLOCK_DEVICE 8
|
||||
#define LIBSSH2_SFTP_TYPE_FIFO 9
|
||||
|
||||
/*
|
||||
* Reproduce the POSIX file modes here for systems that are not POSIX
|
||||
* compliant.
|
||||
*
|
||||
* These is used in "permissions" of "struct _LIBSSH2_SFTP_ATTRIBUTES"
|
||||
*/
|
||||
/* File type */
|
||||
#define LIBSSH2_SFTP_S_IFMT 0170000 /* type of file mask */
|
||||
#define LIBSSH2_SFTP_S_IFIFO 0010000 /* named pipe (fifo) */
|
||||
#define LIBSSH2_SFTP_S_IFCHR 0020000 /* character special */
|
||||
#define LIBSSH2_SFTP_S_IFDIR 0040000 /* directory */
|
||||
#define LIBSSH2_SFTP_S_IFBLK 0060000 /* block special */
|
||||
#define LIBSSH2_SFTP_S_IFREG 0100000 /* regular */
|
||||
#define LIBSSH2_SFTP_S_IFLNK 0120000 /* symbolic link */
|
||||
#define LIBSSH2_SFTP_S_IFSOCK 0140000 /* socket */
|
||||
|
||||
/* File mode */
|
||||
/* Read, write, execute/search by owner */
|
||||
#define LIBSSH2_SFTP_S_IRWXU 0000700 /* RWX mask for owner */
|
||||
#define LIBSSH2_SFTP_S_IRUSR 0000400 /* R for owner */
|
||||
#define LIBSSH2_SFTP_S_IWUSR 0000200 /* W for owner */
|
||||
#define LIBSSH2_SFTP_S_IXUSR 0000100 /* X for owner */
|
||||
/* Read, write, execute/search by group */
|
||||
#define LIBSSH2_SFTP_S_IRWXG 0000070 /* RWX mask for group */
|
||||
#define LIBSSH2_SFTP_S_IRGRP 0000040 /* R for group */
|
||||
#define LIBSSH2_SFTP_S_IWGRP 0000020 /* W for group */
|
||||
#define LIBSSH2_SFTP_S_IXGRP 0000010 /* X for group */
|
||||
/* Read, write, execute/search by others */
|
||||
#define LIBSSH2_SFTP_S_IRWXO 0000007 /* RWX mask for other */
|
||||
#define LIBSSH2_SFTP_S_IROTH 0000004 /* R for other */
|
||||
#define LIBSSH2_SFTP_S_IWOTH 0000002 /* W for other */
|
||||
#define LIBSSH2_SFTP_S_IXOTH 0000001 /* X for other */
|
||||
|
||||
/* macros to check for specific file types, added in 1.2.5 */
|
||||
#define LIBSSH2_SFTP_S_ISLNK(m) \
|
||||
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFLNK)
|
||||
#define LIBSSH2_SFTP_S_ISREG(m) \
|
||||
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFREG)
|
||||
#define LIBSSH2_SFTP_S_ISDIR(m) \
|
||||
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFDIR)
|
||||
#define LIBSSH2_SFTP_S_ISCHR(m) \
|
||||
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFCHR)
|
||||
#define LIBSSH2_SFTP_S_ISBLK(m) \
|
||||
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFBLK)
|
||||
#define LIBSSH2_SFTP_S_ISFIFO(m) \
|
||||
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFIFO)
|
||||
#define LIBSSH2_SFTP_S_ISSOCK(m) \
|
||||
(((m) & LIBSSH2_SFTP_S_IFMT) == LIBSSH2_SFTP_S_IFSOCK)
|
||||
|
||||
/* SFTP File Transfer Flags -- (e.g. flags parameter to sftp_open())
|
||||
* Danger will robinson... APPEND doesn't have any effect on OpenSSH servers */
|
||||
#define LIBSSH2_FXF_READ 0x00000001
|
||||
#define LIBSSH2_FXF_WRITE 0x00000002
|
||||
#define LIBSSH2_FXF_APPEND 0x00000004
|
||||
#define LIBSSH2_FXF_CREAT 0x00000008
|
||||
#define LIBSSH2_FXF_TRUNC 0x00000010
|
||||
#define LIBSSH2_FXF_EXCL 0x00000020
|
||||
|
||||
/* SFTP Status Codes (returned by libssh2_sftp_last_error() ) */
|
||||
#define LIBSSH2_FX_OK 0UL
|
||||
#define LIBSSH2_FX_EOF 1UL
|
||||
#define LIBSSH2_FX_NO_SUCH_FILE 2UL
|
||||
#define LIBSSH2_FX_PERMISSION_DENIED 3UL
|
||||
#define LIBSSH2_FX_FAILURE 4UL
|
||||
#define LIBSSH2_FX_BAD_MESSAGE 5UL
|
||||
#define LIBSSH2_FX_NO_CONNECTION 6UL
|
||||
#define LIBSSH2_FX_CONNECTION_LOST 7UL
|
||||
#define LIBSSH2_FX_OP_UNSUPPORTED 8UL
|
||||
#define LIBSSH2_FX_INVALID_HANDLE 9UL
|
||||
#define LIBSSH2_FX_NO_SUCH_PATH 10UL
|
||||
#define LIBSSH2_FX_FILE_ALREADY_EXISTS 11UL
|
||||
#define LIBSSH2_FX_WRITE_PROTECT 12UL
|
||||
#define LIBSSH2_FX_NO_MEDIA 13UL
|
||||
#define LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM 14UL
|
||||
#define LIBSSH2_FX_QUOTA_EXCEEDED 15UL
|
||||
#define LIBSSH2_FX_UNKNOWN_PRINCIPLE 16UL /* Initial mis-spelling */
|
||||
#define LIBSSH2_FX_UNKNOWN_PRINCIPAL 16UL
|
||||
#define LIBSSH2_FX_LOCK_CONFlICT 17UL /* Initial mis-spelling */
|
||||
#define LIBSSH2_FX_LOCK_CONFLICT 17UL
|
||||
#define LIBSSH2_FX_DIR_NOT_EMPTY 18UL
|
||||
#define LIBSSH2_FX_NOT_A_DIRECTORY 19UL
|
||||
#define LIBSSH2_FX_INVALID_FILENAME 20UL
|
||||
#define LIBSSH2_FX_LINK_LOOP 21UL
|
||||
|
||||
/* Returned by any function that would block during a read/write operation */
|
||||
#define LIBSSH2SFTP_EAGAIN LIBSSH2_ERROR_EAGAIN
|
||||
|
||||
/* SFTP API */
|
||||
LIBSSH2_API LIBSSH2_SFTP *libssh2_sftp_init(LIBSSH2_SESSION *session);
|
||||
LIBSSH2_API int libssh2_sftp_shutdown(LIBSSH2_SFTP *sftp);
|
||||
LIBSSH2_API unsigned long libssh2_sftp_last_error(LIBSSH2_SFTP *sftp);
|
||||
LIBSSH2_API LIBSSH2_CHANNEL *libssh2_sftp_get_channel(LIBSSH2_SFTP *sftp);
|
||||
|
||||
/* File / Directory Ops */
|
||||
LIBSSH2_API LIBSSH2_SFTP_HANDLE *
|
||||
libssh2_sftp_open_ex(LIBSSH2_SFTP *sftp,
|
||||
const char *filename,
|
||||
unsigned int filename_len,
|
||||
unsigned long flags,
|
||||
long mode, int open_type);
|
||||
#define libssh2_sftp_open(sftp, filename, flags, mode) \
|
||||
libssh2_sftp_open_ex((sftp), (filename), strlen(filename), (flags), \
|
||||
(mode), LIBSSH2_SFTP_OPENFILE)
|
||||
#define libssh2_sftp_opendir(sftp, path) \
|
||||
libssh2_sftp_open_ex((sftp), (path), strlen(path), 0, 0, \
|
||||
LIBSSH2_SFTP_OPENDIR)
|
||||
|
||||
LIBSSH2_API ssize_t libssh2_sftp_read(LIBSSH2_SFTP_HANDLE *handle,
|
||||
char *buffer, size_t buffer_maxlen);
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_readdir_ex(LIBSSH2_SFTP_HANDLE *handle, \
|
||||
char *buffer, size_t buffer_maxlen,
|
||||
char *longentry,
|
||||
size_t longentry_maxlen,
|
||||
LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||
#define libssh2_sftp_readdir(handle, buffer, buffer_maxlen, attrs) \
|
||||
libssh2_sftp_readdir_ex((handle), (buffer), (buffer_maxlen), NULL, 0, \
|
||||
(attrs))
|
||||
|
||||
LIBSSH2_API ssize_t libssh2_sftp_write(LIBSSH2_SFTP_HANDLE *handle,
|
||||
const char *buffer, size_t count);
|
||||
LIBSSH2_API int libssh2_sftp_fsync(LIBSSH2_SFTP_HANDLE *handle);
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_close_handle(LIBSSH2_SFTP_HANDLE *handle);
|
||||
#define libssh2_sftp_close(handle) libssh2_sftp_close_handle(handle)
|
||||
#define libssh2_sftp_closedir(handle) libssh2_sftp_close_handle(handle)
|
||||
|
||||
LIBSSH2_API void libssh2_sftp_seek(LIBSSH2_SFTP_HANDLE *handle, size_t offset);
|
||||
LIBSSH2_API void libssh2_sftp_seek64(LIBSSH2_SFTP_HANDLE *handle,
|
||||
libssh2_uint64_t offset);
|
||||
#define libssh2_sftp_rewind(handle) libssh2_sftp_seek64((handle), 0)
|
||||
|
||||
LIBSSH2_API size_t libssh2_sftp_tell(LIBSSH2_SFTP_HANDLE *handle);
|
||||
LIBSSH2_API libssh2_uint64_t libssh2_sftp_tell64(LIBSSH2_SFTP_HANDLE *handle);
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_fstat_ex(LIBSSH2_SFTP_HANDLE *handle,
|
||||
LIBSSH2_SFTP_ATTRIBUTES *attrs,
|
||||
int setstat);
|
||||
#define libssh2_sftp_fstat(handle, attrs) \
|
||||
libssh2_sftp_fstat_ex((handle), (attrs), 0)
|
||||
#define libssh2_sftp_fsetstat(handle, attrs) \
|
||||
libssh2_sftp_fstat_ex((handle), (attrs), 1)
|
||||
|
||||
/* Miscellaneous Ops */
|
||||
LIBSSH2_API int libssh2_sftp_rename_ex(LIBSSH2_SFTP *sftp,
|
||||
const char *source_filename,
|
||||
unsigned int srouce_filename_len,
|
||||
const char *dest_filename,
|
||||
unsigned int dest_filename_len,
|
||||
long flags);
|
||||
#define libssh2_sftp_rename(sftp, sourcefile, destfile) \
|
||||
libssh2_sftp_rename_ex((sftp), (sourcefile), strlen(sourcefile), \
|
||||
(destfile), strlen(destfile), \
|
||||
LIBSSH2_SFTP_RENAME_OVERWRITE | \
|
||||
LIBSSH2_SFTP_RENAME_ATOMIC | \
|
||||
LIBSSH2_SFTP_RENAME_NATIVE)
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_unlink_ex(LIBSSH2_SFTP *sftp,
|
||||
const char *filename,
|
||||
unsigned int filename_len);
|
||||
#define libssh2_sftp_unlink(sftp, filename) \
|
||||
libssh2_sftp_unlink_ex((sftp), (filename), strlen(filename))
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_fstatvfs(LIBSSH2_SFTP_HANDLE *handle,
|
||||
LIBSSH2_SFTP_STATVFS *st);
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_statvfs(LIBSSH2_SFTP *sftp,
|
||||
const char *path,
|
||||
size_t path_len,
|
||||
LIBSSH2_SFTP_STATVFS *st);
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_mkdir_ex(LIBSSH2_SFTP *sftp,
|
||||
const char *path,
|
||||
unsigned int path_len, long mode);
|
||||
#define libssh2_sftp_mkdir(sftp, path, mode) \
|
||||
libssh2_sftp_mkdir_ex((sftp), (path), strlen(path), (mode))
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_rmdir_ex(LIBSSH2_SFTP *sftp,
|
||||
const char *path,
|
||||
unsigned int path_len);
|
||||
#define libssh2_sftp_rmdir(sftp, path) \
|
||||
libssh2_sftp_rmdir_ex((sftp), (path), strlen(path))
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_stat_ex(LIBSSH2_SFTP *sftp,
|
||||
const char *path,
|
||||
unsigned int path_len,
|
||||
int stat_type,
|
||||
LIBSSH2_SFTP_ATTRIBUTES *attrs);
|
||||
#define libssh2_sftp_stat(sftp, path, attrs) \
|
||||
libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_STAT, \
|
||||
(attrs))
|
||||
#define libssh2_sftp_lstat(sftp, path, attrs) \
|
||||
libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_LSTAT, \
|
||||
(attrs))
|
||||
#define libssh2_sftp_setstat(sftp, path, attrs) \
|
||||
libssh2_sftp_stat_ex((sftp), (path), strlen(path), LIBSSH2_SFTP_SETSTAT, \
|
||||
(attrs))
|
||||
|
||||
LIBSSH2_API int libssh2_sftp_symlink_ex(LIBSSH2_SFTP *sftp,
|
||||
const char *path,
|
||||
unsigned int path_len,
|
||||
char *target,
|
||||
unsigned int target_len,
|
||||
int link_type);
|
||||
#define libssh2_sftp_symlink(sftp, orig, linkpath) \
|
||||
libssh2_sftp_symlink_ex((sftp), (orig), strlen(orig), (linkpath), \
|
||||
strlen(linkpath), LIBSSH2_SFTP_SYMLINK)
|
||||
#define libssh2_sftp_readlink(sftp, path, target, maxlen) \
|
||||
libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \
|
||||
LIBSSH2_SFTP_READLINK)
|
||||
#define libssh2_sftp_realpath(sftp, path, target, maxlen) \
|
||||
libssh2_sftp_symlink_ex((sftp), (path), strlen(path), (target), (maxlen), \
|
||||
LIBSSH2_SFTP_REALPATH)
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* LIBSSH2_SFTP_H */
|
||||
#endif
|
||||
416
lib/libssh2/mac.c
Normal file
416
lib/libssh2/mac.c
Normal file
@@ -0,0 +1,416 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include "mac.h"
|
||||
|
||||
#ifdef LIBSSH2_MAC_NONE
|
||||
/* mac_none_MAC
|
||||
* Minimalist MAC: No MAC
|
||||
*/
|
||||
static int
|
||||
mac_none_MAC(LIBSSH2_SESSION * session, unsigned char *buf,
|
||||
uint32_t seqno, const unsigned char *packet,
|
||||
uint32_t packet_len, const unsigned char *addtl,
|
||||
uint32_t addtl_len, void **abstract)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static LIBSSH2_MAC_METHOD mac_method_none = {
|
||||
"none",
|
||||
0,
|
||||
0,
|
||||
NULL,
|
||||
mac_none_MAC,
|
||||
NULL
|
||||
};
|
||||
#endif /* LIBSSH2_MAC_NONE */
|
||||
|
||||
/* mac_method_common_init
|
||||
* Initialize simple mac methods
|
||||
*/
|
||||
static int
|
||||
mac_method_common_init(LIBSSH2_SESSION * session, unsigned char *key,
|
||||
int *free_key, void **abstract)
|
||||
{
|
||||
*abstract = key;
|
||||
*free_key = 0;
|
||||
(void) session;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* mac_method_common_dtor
|
||||
* Cleanup simple mac methods
|
||||
*/
|
||||
static int
|
||||
mac_method_common_dtor(LIBSSH2_SESSION * session, void **abstract)
|
||||
{
|
||||
if(*abstract) {
|
||||
LIBSSH2_FREE(session, *abstract);
|
||||
}
|
||||
*abstract = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if LIBSSH2_HMAC_SHA512
|
||||
/* mac_method_hmac_sha512_hash
|
||||
* Calculate hash using full sha512 value
|
||||
*/
|
||||
static int
|
||||
mac_method_hmac_sha2_512_hash(LIBSSH2_SESSION * session,
|
||||
unsigned char *buf, uint32_t seqno,
|
||||
const unsigned char *packet,
|
||||
uint32_t packet_len,
|
||||
const unsigned char *addtl,
|
||||
uint32_t addtl_len, void **abstract)
|
||||
{
|
||||
libssh2_hmac_ctx ctx;
|
||||
unsigned char seqno_buf[4];
|
||||
(void) session;
|
||||
|
||||
_libssh2_htonu32(seqno_buf, seqno);
|
||||
|
||||
libssh2_hmac_ctx_init(ctx);
|
||||
libssh2_hmac_sha512_init(&ctx, *abstract, 64);
|
||||
libssh2_hmac_update(ctx, seqno_buf, 4);
|
||||
libssh2_hmac_update(ctx, packet, packet_len);
|
||||
if(addtl && addtl_len) {
|
||||
libssh2_hmac_update(ctx, addtl, addtl_len);
|
||||
}
|
||||
libssh2_hmac_final(ctx, buf);
|
||||
libssh2_hmac_cleanup(&ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_512 = {
|
||||
"hmac-sha2-512",
|
||||
64,
|
||||
64,
|
||||
mac_method_common_init,
|
||||
mac_method_hmac_sha2_512_hash,
|
||||
mac_method_common_dtor,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if LIBSSH2_HMAC_SHA256
|
||||
/* mac_method_hmac_sha256_hash
|
||||
* Calculate hash using full sha256 value
|
||||
*/
|
||||
static int
|
||||
mac_method_hmac_sha2_256_hash(LIBSSH2_SESSION * session,
|
||||
unsigned char *buf, uint32_t seqno,
|
||||
const unsigned char *packet,
|
||||
uint32_t packet_len,
|
||||
const unsigned char *addtl,
|
||||
uint32_t addtl_len, void **abstract)
|
||||
{
|
||||
libssh2_hmac_ctx ctx;
|
||||
unsigned char seqno_buf[4];
|
||||
(void) session;
|
||||
|
||||
_libssh2_htonu32(seqno_buf, seqno);
|
||||
|
||||
libssh2_hmac_ctx_init(ctx);
|
||||
libssh2_hmac_sha256_init(&ctx, *abstract, 32);
|
||||
libssh2_hmac_update(ctx, seqno_buf, 4);
|
||||
libssh2_hmac_update(ctx, packet, packet_len);
|
||||
if(addtl && addtl_len) {
|
||||
libssh2_hmac_update(ctx, addtl, addtl_len);
|
||||
}
|
||||
libssh2_hmac_final(ctx, buf);
|
||||
libssh2_hmac_cleanup(&ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha2_256 = {
|
||||
"hmac-sha2-256",
|
||||
32,
|
||||
32,
|
||||
mac_method_common_init,
|
||||
mac_method_hmac_sha2_256_hash,
|
||||
mac_method_common_dtor,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/* mac_method_hmac_sha1_hash
|
||||
* Calculate hash using full sha1 value
|
||||
*/
|
||||
static int
|
||||
mac_method_hmac_sha1_hash(LIBSSH2_SESSION * session,
|
||||
unsigned char *buf, uint32_t seqno,
|
||||
const unsigned char *packet,
|
||||
uint32_t packet_len,
|
||||
const unsigned char *addtl,
|
||||
uint32_t addtl_len, void **abstract)
|
||||
{
|
||||
libssh2_hmac_ctx ctx;
|
||||
unsigned char seqno_buf[4];
|
||||
(void) session;
|
||||
|
||||
_libssh2_htonu32(seqno_buf, seqno);
|
||||
|
||||
libssh2_hmac_ctx_init(ctx);
|
||||
libssh2_hmac_sha1_init(&ctx, *abstract, 20);
|
||||
libssh2_hmac_update(ctx, seqno_buf, 4);
|
||||
libssh2_hmac_update(ctx, packet, packet_len);
|
||||
if(addtl && addtl_len) {
|
||||
libssh2_hmac_update(ctx, addtl, addtl_len);
|
||||
}
|
||||
libssh2_hmac_final(ctx, buf);
|
||||
libssh2_hmac_cleanup(&ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1 = {
|
||||
"hmac-sha1",
|
||||
20,
|
||||
20,
|
||||
mac_method_common_init,
|
||||
mac_method_hmac_sha1_hash,
|
||||
mac_method_common_dtor,
|
||||
};
|
||||
|
||||
/* mac_method_hmac_sha1_96_hash
|
||||
* Calculate hash using first 96 bits of sha1 value
|
||||
*/
|
||||
static int
|
||||
mac_method_hmac_sha1_96_hash(LIBSSH2_SESSION * session,
|
||||
unsigned char *buf, uint32_t seqno,
|
||||
const unsigned char *packet,
|
||||
uint32_t packet_len,
|
||||
const unsigned char *addtl,
|
||||
uint32_t addtl_len, void **abstract)
|
||||
{
|
||||
unsigned char temp[SHA_DIGEST_LENGTH];
|
||||
|
||||
mac_method_hmac_sha1_hash(session, temp, seqno, packet, packet_len,
|
||||
addtl, addtl_len, abstract);
|
||||
memcpy(buf, (char *) temp, 96 / 8);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const LIBSSH2_MAC_METHOD mac_method_hmac_sha1_96 = {
|
||||
"hmac-sha1-96",
|
||||
12,
|
||||
20,
|
||||
mac_method_common_init,
|
||||
mac_method_hmac_sha1_96_hash,
|
||||
mac_method_common_dtor,
|
||||
};
|
||||
|
||||
#if LIBSSH2_MD5
|
||||
/* mac_method_hmac_md5_hash
|
||||
* Calculate hash using full md5 value
|
||||
*/
|
||||
static int
|
||||
mac_method_hmac_md5_hash(LIBSSH2_SESSION * session, unsigned char *buf,
|
||||
uint32_t seqno,
|
||||
const unsigned char *packet,
|
||||
uint32_t packet_len,
|
||||
const unsigned char *addtl,
|
||||
uint32_t addtl_len, void **abstract)
|
||||
{
|
||||
libssh2_hmac_ctx ctx;
|
||||
unsigned char seqno_buf[4];
|
||||
(void) session;
|
||||
|
||||
_libssh2_htonu32(seqno_buf, seqno);
|
||||
|
||||
libssh2_hmac_ctx_init(ctx);
|
||||
libssh2_hmac_md5_init(&ctx, *abstract, 16);
|
||||
libssh2_hmac_update(ctx, seqno_buf, 4);
|
||||
libssh2_hmac_update(ctx, packet, packet_len);
|
||||
if(addtl && addtl_len) {
|
||||
libssh2_hmac_update(ctx, addtl, addtl_len);
|
||||
}
|
||||
libssh2_hmac_final(ctx, buf);
|
||||
libssh2_hmac_cleanup(&ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const LIBSSH2_MAC_METHOD mac_method_hmac_md5 = {
|
||||
"hmac-md5",
|
||||
16,
|
||||
16,
|
||||
mac_method_common_init,
|
||||
mac_method_hmac_md5_hash,
|
||||
mac_method_common_dtor,
|
||||
};
|
||||
|
||||
/* mac_method_hmac_md5_96_hash
|
||||
* Calculate hash using first 96 bits of md5 value
|
||||
*/
|
||||
static int
|
||||
mac_method_hmac_md5_96_hash(LIBSSH2_SESSION * session,
|
||||
unsigned char *buf, uint32_t seqno,
|
||||
const unsigned char *packet,
|
||||
uint32_t packet_len,
|
||||
const unsigned char *addtl,
|
||||
uint32_t addtl_len, void **abstract)
|
||||
{
|
||||
unsigned char temp[MD5_DIGEST_LENGTH];
|
||||
mac_method_hmac_md5_hash(session, temp, seqno, packet, packet_len,
|
||||
addtl, addtl_len, abstract);
|
||||
memcpy(buf, (char *) temp, 96 / 8);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const LIBSSH2_MAC_METHOD mac_method_hmac_md5_96 = {
|
||||
"hmac-md5-96",
|
||||
12,
|
||||
16,
|
||||
mac_method_common_init,
|
||||
mac_method_hmac_md5_96_hash,
|
||||
mac_method_common_dtor,
|
||||
};
|
||||
#endif /* LIBSSH2_MD5 */
|
||||
|
||||
#if LIBSSH2_HMAC_RIPEMD
|
||||
/* mac_method_hmac_ripemd160_hash
|
||||
* Calculate hash using ripemd160 value
|
||||
*/
|
||||
static int
|
||||
mac_method_hmac_ripemd160_hash(LIBSSH2_SESSION * session,
|
||||
unsigned char *buf, uint32_t seqno,
|
||||
const unsigned char *packet,
|
||||
uint32_t packet_len,
|
||||
const unsigned char *addtl,
|
||||
uint32_t addtl_len,
|
||||
void **abstract)
|
||||
{
|
||||
libssh2_hmac_ctx ctx;
|
||||
unsigned char seqno_buf[4];
|
||||
(void) session;
|
||||
|
||||
_libssh2_htonu32(seqno_buf, seqno);
|
||||
|
||||
libssh2_hmac_ctx_init(ctx);
|
||||
libssh2_hmac_ripemd160_init(&ctx, *abstract, 20);
|
||||
libssh2_hmac_update(ctx, seqno_buf, 4);
|
||||
libssh2_hmac_update(ctx, packet, packet_len);
|
||||
if(addtl && addtl_len) {
|
||||
libssh2_hmac_update(ctx, addtl, addtl_len);
|
||||
}
|
||||
libssh2_hmac_final(ctx, buf);
|
||||
libssh2_hmac_cleanup(&ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160 = {
|
||||
"hmac-ripemd160",
|
||||
20,
|
||||
20,
|
||||
mac_method_common_init,
|
||||
mac_method_hmac_ripemd160_hash,
|
||||
mac_method_common_dtor,
|
||||
};
|
||||
|
||||
static const LIBSSH2_MAC_METHOD mac_method_hmac_ripemd160_openssh_com = {
|
||||
"hmac-ripemd160@openssh.com",
|
||||
20,
|
||||
20,
|
||||
mac_method_common_init,
|
||||
mac_method_hmac_ripemd160_hash,
|
||||
mac_method_common_dtor,
|
||||
};
|
||||
#endif /* LIBSSH2_HMAC_RIPEMD */
|
||||
|
||||
static const LIBSSH2_MAC_METHOD *mac_methods[] = {
|
||||
#if LIBSSH2_HMAC_SHA256
|
||||
&mac_method_hmac_sha2_256,
|
||||
#endif
|
||||
#if LIBSSH2_HMAC_SHA512
|
||||
&mac_method_hmac_sha2_512,
|
||||
#endif
|
||||
&mac_method_hmac_sha1,
|
||||
&mac_method_hmac_sha1_96,
|
||||
#if LIBSSH2_MD5
|
||||
&mac_method_hmac_md5,
|
||||
&mac_method_hmac_md5_96,
|
||||
#endif
|
||||
#if LIBSSH2_HMAC_RIPEMD
|
||||
&mac_method_hmac_ripemd160,
|
||||
&mac_method_hmac_ripemd160_openssh_com,
|
||||
#endif /* LIBSSH2_HMAC_RIPEMD */
|
||||
#ifdef LIBSSH2_MAC_NONE
|
||||
&mac_method_none,
|
||||
#endif /* LIBSSH2_MAC_NONE */
|
||||
NULL
|
||||
};
|
||||
|
||||
const LIBSSH2_MAC_METHOD **
|
||||
_libssh2_mac_methods(void)
|
||||
{
|
||||
return mac_methods;
|
||||
}
|
||||
#endif
|
||||
68
lib/libssh2/mac.h
Normal file
68
lib/libssh2/mac.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_MAC_H
|
||||
#define __LIBSSH2_MAC_H
|
||||
/* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
|
||||
struct _LIBSSH2_MAC_METHOD
|
||||
{
|
||||
const char *name;
|
||||
|
||||
/* The length of a given MAC packet */
|
||||
int mac_len;
|
||||
|
||||
/* integrity key length */
|
||||
int key_len;
|
||||
|
||||
/* Message Authentication Code Hashing algo */
|
||||
int (*init) (LIBSSH2_SESSION * session, unsigned char *key, int *free_key,
|
||||
void **abstract);
|
||||
int (*hash) (LIBSSH2_SESSION * session, unsigned char *buf,
|
||||
uint32_t seqno, const unsigned char *packet,
|
||||
uint32_t packet_len, const unsigned char *addtl,
|
||||
uint32_t addtl_len, void **abstract);
|
||||
int (*dtor) (LIBSSH2_SESSION * session, void **abstract);
|
||||
};
|
||||
|
||||
typedef struct _LIBSSH2_MAC_METHOD LIBSSH2_MAC_METHOD;
|
||||
|
||||
const LIBSSH2_MAC_METHOD **_libssh2_mac_methods(void);
|
||||
|
||||
#endif /* __LIBSSH2_MAC_H */
|
||||
#endif
|
||||
1445
lib/libssh2/mbedtls.c
Normal file
1445
lib/libssh2/mbedtls.c
Normal file
File diff suppressed because it is too large
Load Diff
611
lib/libssh2/mbedtls.h
Normal file
611
lib/libssh2/mbedtls.h
Normal file
@@ -0,0 +1,611 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_MBEDTLS_H
|
||||
#define __LIBSSH2_MBEDTLS_H
|
||||
/* Copyright (c) 2016, Art <https://github.com/wildart>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <mbedtls/platform.h>
|
||||
#include <mbedtls/md.h>
|
||||
#include <mbedtls/rsa.h>
|
||||
#include <mbedtls/bignum.h>
|
||||
#include <mbedtls/cipher.h>
|
||||
#ifdef MBEDTLS_ECDH_C
|
||||
# include <mbedtls/ecdh.h>
|
||||
#endif
|
||||
#ifdef MBEDTLS_ECDSA_C
|
||||
# include <mbedtls/ecdsa.h>
|
||||
#endif
|
||||
#include <mbedtls/entropy.h>
|
||||
#include <mbedtls/ctr_drbg.h>
|
||||
#include <mbedtls/pk.h>
|
||||
#include <mbedtls/error.h>
|
||||
|
||||
/* Define which features are supported. */
|
||||
#define LIBSSH2_MD5 1
|
||||
|
||||
#define LIBSSH2_HMAC_RIPEMD 1
|
||||
#define LIBSSH2_HMAC_SHA256 1
|
||||
#define LIBSSH2_HMAC_SHA512 1
|
||||
|
||||
#define LIBSSH2_AES 1
|
||||
#define LIBSSH2_AES_CTR 1
|
||||
#ifdef MBEDTLS_CIPHER_BLOWFISH_CBC
|
||||
# define LIBSSH2_BLOWFISH 1
|
||||
#else
|
||||
# define LIBSSH2_BLOWFISH 0
|
||||
#endif
|
||||
#ifdef MBEDTLS_CIPHER_ARC4_128
|
||||
# define LIBSSH2_RC4 1
|
||||
#else
|
||||
# define LIBSSH2_RC4 0
|
||||
#endif
|
||||
#define LIBSSH2_CAST 0
|
||||
#define LIBSSH2_3DES 1
|
||||
|
||||
#define LIBSSH2_RSA 1
|
||||
#define LIBSSH2_RSA_SHA2 1
|
||||
#define LIBSSH2_DSA 0
|
||||
#ifdef MBEDTLS_ECDSA_C
|
||||
# define LIBSSH2_ECDSA 1
|
||||
#else
|
||||
# define LIBSSH2_ECDSA 0
|
||||
#endif
|
||||
#define LIBSSH2_ED25519 0
|
||||
|
||||
#define MD5_DIGEST_LENGTH 16
|
||||
#define SHA_DIGEST_LENGTH 20
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
#define SHA384_DIGEST_LENGTH 48
|
||||
#define SHA512_DIGEST_LENGTH 64
|
||||
|
||||
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: Generic functions
|
||||
*/
|
||||
|
||||
#define libssh2_crypto_init() \
|
||||
_libssh2_mbedtls_init()
|
||||
#define libssh2_crypto_exit() \
|
||||
_libssh2_mbedtls_free()
|
||||
|
||||
#define _libssh2_random(buf, len) \
|
||||
_libssh2_mbedtls_random(buf, len)
|
||||
|
||||
#define libssh2_prepare_iovec(vec, len) /* Empty. */
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: HMAC functions
|
||||
*/
|
||||
|
||||
#define libssh2_hmac_ctx mbedtls_md_context_t
|
||||
|
||||
#define libssh2_hmac_ctx_init(ctx)
|
||||
#define libssh2_hmac_cleanup(pctx) \
|
||||
mbedtls_md_free(pctx)
|
||||
#define libssh2_hmac_update(ctx, data, datalen) \
|
||||
mbedtls_md_hmac_update(&ctx, (unsigned char *) data, datalen)
|
||||
#define libssh2_hmac_final(ctx, hash) \
|
||||
mbedtls_md_hmac_finish(&ctx, hash)
|
||||
|
||||
#define libssh2_hmac_sha1_init(pctx, key, keylen) \
|
||||
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, key, keylen)
|
||||
#define libssh2_hmac_md5_init(pctx, key, keylen) \
|
||||
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, key, keylen)
|
||||
#define libssh2_hmac_ripemd160_init(pctx, key, keylen) \
|
||||
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_RIPEMD160, key, keylen)
|
||||
#define libssh2_hmac_sha256_init(pctx, key, keylen) \
|
||||
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, key, keylen)
|
||||
#define libssh2_hmac_sha384_init(pctx, key, keylen) \
|
||||
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, key, keylen)
|
||||
#define libssh2_hmac_sha512_init(pctx, key, keylen) \
|
||||
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, key, keylen)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: SHA1 functions
|
||||
*/
|
||||
|
||||
#define libssh2_sha1_ctx mbedtls_md_context_t
|
||||
|
||||
#define libssh2_sha1_init(pctx) \
|
||||
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA1, NULL, 0)
|
||||
#define libssh2_sha1_update(ctx, data, datalen) \
|
||||
mbedtls_md_update(&ctx, (unsigned char *) data, datalen)
|
||||
#define libssh2_sha1_final(ctx, hash) \
|
||||
_libssh2_mbedtls_hash_final(&ctx, hash)
|
||||
#define libssh2_sha1(data, datalen, hash) \
|
||||
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA1, hash)
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: SHA256 functions
|
||||
*/
|
||||
|
||||
#define libssh2_sha256_ctx mbedtls_md_context_t
|
||||
|
||||
#define libssh2_sha256_init(pctx) \
|
||||
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA256, NULL, 0)
|
||||
#define libssh2_sha256_update(ctx, data, datalen) \
|
||||
mbedtls_md_update(&ctx, (unsigned char *) data, datalen)
|
||||
#define libssh2_sha256_final(ctx, hash) \
|
||||
_libssh2_mbedtls_hash_final(&ctx, hash)
|
||||
#define libssh2_sha256(data, datalen, hash) \
|
||||
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA256, hash)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: SHA384 functions
|
||||
*/
|
||||
|
||||
#define libssh2_sha384_ctx mbedtls_md_context_t
|
||||
|
||||
#define libssh2_sha384_init(pctx) \
|
||||
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA384, NULL, 0)
|
||||
#define libssh2_sha384_update(ctx, data, datalen) \
|
||||
mbedtls_md_update(&ctx, (unsigned char *) data, datalen)
|
||||
#define libssh2_sha384_final(ctx, hash) \
|
||||
_libssh2_mbedtls_hash_final(&ctx, hash)
|
||||
#define libssh2_sha384(data, datalen, hash) \
|
||||
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA384, hash)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: SHA512 functions
|
||||
*/
|
||||
|
||||
#define libssh2_sha512_ctx mbedtls_md_context_t
|
||||
|
||||
#define libssh2_sha512_init(pctx) \
|
||||
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_SHA512, NULL, 0)
|
||||
#define libssh2_sha512_update(ctx, data, datalen) \
|
||||
mbedtls_md_update(&ctx, (unsigned char *) data, datalen)
|
||||
#define libssh2_sha512_final(ctx, hash) \
|
||||
_libssh2_mbedtls_hash_final(&ctx, hash)
|
||||
#define libssh2_sha512(data, datalen, hash) \
|
||||
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_SHA512, hash)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: MD5 functions
|
||||
*/
|
||||
|
||||
#define libssh2_md5_ctx mbedtls_md_context_t
|
||||
|
||||
#define libssh2_md5_init(pctx) \
|
||||
_libssh2_mbedtls_hash_init(pctx, MBEDTLS_MD_MD5, NULL, 0)
|
||||
#define libssh2_md5_update(ctx, data, datalen) \
|
||||
mbedtls_md_update(&ctx, (unsigned char *) data, datalen)
|
||||
#define libssh2_md5_final(ctx, hash) \
|
||||
_libssh2_mbedtls_hash_final(&ctx, hash)
|
||||
#define libssh2_md5(data, datalen, hash) \
|
||||
_libssh2_mbedtls_hash(data, datalen, MBEDTLS_MD_MD5, hash)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: RSA functions
|
||||
*/
|
||||
|
||||
#define libssh2_rsa_ctx mbedtls_rsa_context
|
||||
|
||||
#define _libssh2_rsa_new(rsactx, e, e_len, n, n_len, \
|
||||
d, d_len, p, p_len, q, q_len, \
|
||||
e1, e1_len, e2, e2_len, c, c_len) \
|
||||
_libssh2_mbedtls_rsa_new(rsactx, e, e_len, n, n_len, \
|
||||
d, d_len, p, p_len, q, q_len, \
|
||||
e1, e1_len, e2, e2_len, c, c_len)
|
||||
|
||||
#define _libssh2_rsa_new_private(rsactx, s, filename, passphrase) \
|
||||
_libssh2_mbedtls_rsa_new_private(rsactx, s, filename, passphrase)
|
||||
|
||||
#define _libssh2_rsa_new_private_frommemory(rsactx, s, filedata, \
|
||||
filedata_len, passphrase) \
|
||||
_libssh2_mbedtls_rsa_new_private_frommemory(rsactx, s, filedata, \
|
||||
filedata_len, passphrase)
|
||||
|
||||
#define _libssh2_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len) \
|
||||
_libssh2_mbedtls_rsa_sha1_sign(s, rsactx, hash, hash_len, sig, sig_len)
|
||||
|
||||
#define _libssh2_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len) \
|
||||
_libssh2_mbedtls_rsa_sha2_sign(s, rsactx, hash, hash_len, sig, sig_len)
|
||||
|
||||
|
||||
#define _libssh2_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len) \
|
||||
_libssh2_mbedtls_rsa_sha1_verify(rsactx, sig, sig_len, m, m_len)
|
||||
|
||||
#define _libssh2_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len) \
|
||||
_libssh2_mbedtls_rsa_sha2_verify(rsactx, hash_len, sig, sig_len, m, m_len)
|
||||
|
||||
#define _libssh2_rsa_free(rsactx) \
|
||||
_libssh2_mbedtls_rsa_free(rsactx)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: ECDSA structures
|
||||
*/
|
||||
|
||||
#if LIBSSH2_ECDSA
|
||||
|
||||
typedef enum {
|
||||
#ifdef MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
LIBSSH2_EC_CURVE_NISTP256 = MBEDTLS_ECP_DP_SECP256R1,
|
||||
#else
|
||||
LIBSSH2_EC_CURVE_NISTP256 = MBEDTLS_ECP_DP_NONE,
|
||||
#endif
|
||||
#ifdef MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||
LIBSSH2_EC_CURVE_NISTP384 = MBEDTLS_ECP_DP_SECP384R1,
|
||||
#else
|
||||
LIBSSH2_EC_CURVE_NISTP384 = MBEDTLS_ECP_DP_NONE,
|
||||
#endif
|
||||
#ifdef MBEDTLS_ECP_DP_SECP521R1_ENABLED
|
||||
LIBSSH2_EC_CURVE_NISTP521 = MBEDTLS_ECP_DP_SECP521R1
|
||||
#else
|
||||
LIBSSH2_EC_CURVE_NISTP521 = MBEDTLS_ECP_DP_NONE,
|
||||
#endif
|
||||
} libssh2_curve_type;
|
||||
|
||||
# define _libssh2_ec_key mbedtls_ecp_keypair
|
||||
#else
|
||||
# define _libssh2_ec_key void
|
||||
#endif /* LIBSSH2_ECDSA */
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: ECDSA functions
|
||||
*/
|
||||
|
||||
#if LIBSSH2_ECDSA
|
||||
|
||||
#define libssh2_ecdsa_ctx mbedtls_ecdsa_context
|
||||
|
||||
#define _libssh2_ecdsa_create_key(session, privkey, pubkey_octal, \
|
||||
pubkey_octal_len, curve) \
|
||||
_libssh2_mbedtls_ecdsa_create_key(session, privkey, pubkey_octal, \
|
||||
pubkey_octal_len, curve)
|
||||
|
||||
#define _libssh2_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve) \
|
||||
_libssh2_mbedtls_ecdsa_curve_name_with_octal_new(ctx, k, k_len, curve)
|
||||
|
||||
#define _libssh2_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len) \
|
||||
_libssh2_mbedtls_ecdh_gen_k(k, privkey, server_pubkey, server_pubkey_len)
|
||||
|
||||
#define _libssh2_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len) \
|
||||
_libssh2_mbedtls_ecdsa_verify(ctx, r, r_len, s, s_len, m, m_len)
|
||||
|
||||
#define _libssh2_ecdsa_new_private(ctx, session, filename, passphrase) \
|
||||
_libssh2_mbedtls_ecdsa_new_private(ctx, session, filename, passphrase)
|
||||
|
||||
#define _libssh2_ecdsa_new_private_frommemory(ctx, session, filedata, \
|
||||
filedata_len, passphrase) \
|
||||
_libssh2_mbedtls_ecdsa_new_private_frommemory(ctx, session, filedata, \
|
||||
filedata_len, passphrase)
|
||||
|
||||
#define _libssh2_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len) \
|
||||
_libssh2_mbedtls_ecdsa_sign(session, ctx, hash, hash_len, sign, sign_len)
|
||||
|
||||
#define _libssh2_ecdsa_get_curve_type(ctx) \
|
||||
_libssh2_mbedtls_ecdsa_get_curve_type(ctx)
|
||||
|
||||
#define _libssh2_ecdsa_free(ctx) \
|
||||
_libssh2_mbedtls_ecdsa_free(ctx)
|
||||
|
||||
#endif /* LIBSSH2_ECDSA */
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: Key functions
|
||||
*/
|
||||
|
||||
#define _libssh2_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw) \
|
||||
_libssh2_mbedtls_pub_priv_keyfile(s, m, m_len, p, p_len, pk, pw)
|
||||
#define _libssh2_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
|
||||
pk, pk_len, pw) \
|
||||
_libssh2_mbedtls_pub_priv_keyfilememory(s, m, m_len, p, p_len, \
|
||||
pk, pk_len, pw)
|
||||
#define _libssh2_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
|
||||
f, kh, kh_len, pk, pk_len, pw) \
|
||||
_libssh2_mbedtls_sk_pub_keyfilememory(s, m, m_len, p, p_len, alg, app, \
|
||||
f, kh, kh_len, pk, pk_len, pw)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: Cipher Context structure
|
||||
*/
|
||||
|
||||
#define _libssh2_cipher_ctx mbedtls_cipher_context_t
|
||||
|
||||
#define _libssh2_cipher_type(algo) mbedtls_cipher_type_t algo
|
||||
|
||||
#define _libssh2_cipher_aes256ctr MBEDTLS_CIPHER_AES_256_CTR
|
||||
#define _libssh2_cipher_aes192ctr MBEDTLS_CIPHER_AES_192_CTR
|
||||
#define _libssh2_cipher_aes128ctr MBEDTLS_CIPHER_AES_128_CTR
|
||||
#define _libssh2_cipher_aes256 MBEDTLS_CIPHER_AES_256_CBC
|
||||
#define _libssh2_cipher_aes192 MBEDTLS_CIPHER_AES_192_CBC
|
||||
#define _libssh2_cipher_aes128 MBEDTLS_CIPHER_AES_128_CBC
|
||||
#ifdef MBEDTLS_CIPHER_BLOWFISH_CBC
|
||||
#define _libssh2_cipher_blowfish MBEDTLS_CIPHER_BLOWFISH_CBC
|
||||
#endif
|
||||
#ifdef MBEDTLS_CIPHER_ARC4_128
|
||||
#define _libssh2_cipher_arcfour MBEDTLS_CIPHER_ARC4_128
|
||||
#endif
|
||||
#define _libssh2_cipher_3des MBEDTLS_CIPHER_DES_EDE3_CBC
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: Cipher functions
|
||||
*/
|
||||
|
||||
#define _libssh2_cipher_init(ctx, type, iv, secret, encrypt) \
|
||||
_libssh2_mbedtls_cipher_init(ctx, type, iv, secret, encrypt)
|
||||
#define _libssh2_cipher_crypt(ctx, type, encrypt, block, blocklen) \
|
||||
_libssh2_mbedtls_cipher_crypt(ctx, type, encrypt, block, blocklen)
|
||||
#define _libssh2_cipher_dtor(ctx) \
|
||||
_libssh2_mbedtls_cipher_dtor(ctx)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: BigNumber Support
|
||||
*/
|
||||
|
||||
#define _libssh2_bn_ctx int /* not used */
|
||||
#define _libssh2_bn_ctx_new() 0 /* not used */
|
||||
#define _libssh2_bn_ctx_free(bnctx) ((void)0) /* not used */
|
||||
|
||||
#define _libssh2_bn mbedtls_mpi
|
||||
|
||||
#define _libssh2_bn_init() \
|
||||
_libssh2_mbedtls_bignum_init()
|
||||
#define _libssh2_bn_init_from_bin() \
|
||||
_libssh2_mbedtls_bignum_init()
|
||||
#define _libssh2_bn_set_word(bn, word) \
|
||||
mbedtls_mpi_lset(bn, word)
|
||||
#define _libssh2_bn_from_bin(bn, len, bin) \
|
||||
mbedtls_mpi_read_binary(bn, bin, len)
|
||||
#define _libssh2_bn_to_bin(bn, bin) \
|
||||
mbedtls_mpi_write_binary(bn, bin, mbedtls_mpi_size(bn))
|
||||
#define _libssh2_bn_bytes(bn) \
|
||||
mbedtls_mpi_size(bn)
|
||||
#define _libssh2_bn_bits(bn) \
|
||||
mbedtls_mpi_bitlen(bn)
|
||||
#define _libssh2_bn_free(bn) \
|
||||
_libssh2_mbedtls_bignum_free(bn)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: Diffie-Hellman support.
|
||||
*/
|
||||
|
||||
#define _libssh2_dh_ctx mbedtls_mpi *
|
||||
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
|
||||
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
|
||||
_libssh2_dh_key_pair(dhctx, public, g, p, group_order)
|
||||
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
|
||||
_libssh2_dh_secret(dhctx, secret, f, p)
|
||||
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
|
||||
|
||||
|
||||
/*******************************************************************/
|
||||
/*
|
||||
* mbedTLS backend: forward declarations
|
||||
*/
|
||||
|
||||
void
|
||||
_libssh2_mbedtls_init(void);
|
||||
|
||||
void
|
||||
_libssh2_mbedtls_free(void);
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_random(unsigned char *buf, int len);
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx,
|
||||
_libssh2_cipher_type(type),
|
||||
unsigned char *iv,
|
||||
unsigned char *secret,
|
||||
int encrypt);
|
||||
int
|
||||
_libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx,
|
||||
_libssh2_cipher_type(type),
|
||||
int encrypt,
|
||||
unsigned char *block,
|
||||
size_t blocklen);
|
||||
void
|
||||
_libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx);
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx,
|
||||
mbedtls_md_type_t mdtype,
|
||||
const unsigned char *key, unsigned long keylen);
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash);
|
||||
int
|
||||
_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen,
|
||||
mbedtls_md_type_t mdtype, unsigned char *hash);
|
||||
|
||||
_libssh2_bn *
|
||||
_libssh2_mbedtls_bignum_init(void);
|
||||
|
||||
void
|
||||
_libssh2_mbedtls_bignum_free(_libssh2_bn *bn);
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_rsa_new(libssh2_rsa_ctx **rsa,
|
||||
const unsigned char *edata,
|
||||
unsigned long elen,
|
||||
const unsigned char *ndata,
|
||||
unsigned long nlen,
|
||||
const unsigned char *ddata,
|
||||
unsigned long dlen,
|
||||
const unsigned char *pdata,
|
||||
unsigned long plen,
|
||||
const unsigned char *qdata,
|
||||
unsigned long qlen,
|
||||
const unsigned char *e1data,
|
||||
unsigned long e1len,
|
||||
const unsigned char *e2data,
|
||||
unsigned long e2len,
|
||||
const unsigned char *coeffdata,
|
||||
unsigned long coefflen);
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filename,
|
||||
const unsigned char *passphrase);
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
unsigned const char *passphrase);
|
||||
int
|
||||
_libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa,
|
||||
const unsigned char *sig,
|
||||
unsigned long sig_len,
|
||||
const unsigned char *m,
|
||||
unsigned long m_len);
|
||||
int
|
||||
_libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session,
|
||||
libssh2_rsa_ctx *rsa,
|
||||
const unsigned char *hash,
|
||||
size_t hash_len,
|
||||
unsigned char **signature,
|
||||
size_t *signature_len);
|
||||
void
|
||||
_libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *rsa);
|
||||
|
||||
int
|
||||
_libssh2_mbedtls_pub_priv_keyfile(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekey,
|
||||
const char *passphrase);
|
||||
int
|
||||
_libssh2_mbedtls_pub_priv_keyfilememory(LIBSSH2_SESSION *session,
|
||||
unsigned char **method,
|
||||
size_t *method_len,
|
||||
unsigned char **pubkeydata,
|
||||
size_t *pubkeydata_len,
|
||||
const char *privatekeydata,
|
||||
size_t privatekeydata_len,
|
||||
const char *passphrase);
|
||||
#if LIBSSH2_ECDSA
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_create_key(LIBSSH2_SESSION *session,
|
||||
_libssh2_ec_key **privkey,
|
||||
unsigned char **pubkey_octal,
|
||||
size_t *pubkey_octal_len,
|
||||
libssh2_curve_type curve);
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_curve_name_with_octal_new(libssh2_ecdsa_ctx **ctx,
|
||||
const unsigned char *k,
|
||||
size_t k_len,
|
||||
libssh2_curve_type curve);
|
||||
int
|
||||
_libssh2_mbedtls_ecdh_gen_k(_libssh2_bn **k,
|
||||
_libssh2_ec_key *privkey,
|
||||
const unsigned char *server_pubkey,
|
||||
size_t server_pubkey_len);
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_verify(libssh2_ecdsa_ctx *ctx,
|
||||
const unsigned char *r, size_t r_len,
|
||||
const unsigned char *s, size_t s_len,
|
||||
const unsigned char *m, size_t m_len);
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_new_private(libssh2_ecdsa_ctx **ctx,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filename,
|
||||
const unsigned char *passphrase);
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_new_private_frommemory(libssh2_ecdsa_ctx **ctx,
|
||||
LIBSSH2_SESSION *session,
|
||||
const char *filedata,
|
||||
size_t filedata_len,
|
||||
const unsigned char *passphrase);
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_sign(LIBSSH2_SESSION *session,
|
||||
libssh2_ecdsa_ctx *ctx,
|
||||
const unsigned char *hash,
|
||||
unsigned long hash_len,
|
||||
unsigned char **signature,
|
||||
size_t *signature_len);
|
||||
libssh2_curve_type
|
||||
_libssh2_mbedtls_ecdsa_key_get_curve_type(libssh2_ecdsa_ctx *ctx);
|
||||
int
|
||||
_libssh2_mbedtls_ecdsa_curve_type_from_name(const char *name,
|
||||
libssh2_curve_type *type);
|
||||
void
|
||||
_libssh2_mbedtls_ecdsa_free(libssh2_ecdsa_ctx *ctx);
|
||||
#endif /* LIBSSH2_ECDSA */
|
||||
|
||||
extern void
|
||||
_libssh2_dh_init(_libssh2_dh_ctx *dhctx);
|
||||
extern int
|
||||
_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
|
||||
_libssh2_bn *g, _libssh2_bn *p, int group_order);
|
||||
extern int
|
||||
_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
|
||||
_libssh2_bn *f, _libssh2_bn *p);
|
||||
extern void
|
||||
_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
|
||||
|
||||
#endif /* __LIBSSH2_MBEDTLS_H */
|
||||
#endif
|
||||
932
lib/libssh2/misc.c
Normal file
932
lib/libssh2/misc.c
Normal file
@@ -0,0 +1,932 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009-2019 by Daniel Stenberg
|
||||
* Copyright (c) 2010 Simon Josefsson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include "misc.h"
|
||||
#include "blf.h"
|
||||
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode,
|
||||
const char *errmsg, int errflags)
|
||||
{
|
||||
if(session == NULL) {
|
||||
if(errmsg != NULL)
|
||||
fprintf(stderr, "Session is NULL, error: %s\n", errmsg);
|
||||
return errcode;
|
||||
}
|
||||
|
||||
if(session->err_flags & LIBSSH2_ERR_FLAG_DUP)
|
||||
LIBSSH2_FREE(session, (char *)session->err_msg);
|
||||
|
||||
session->err_code = errcode;
|
||||
session->err_flags = 0;
|
||||
|
||||
if((errmsg != NULL) && ((errflags & LIBSSH2_ERR_FLAG_DUP) != 0)) {
|
||||
size_t len = strlen(errmsg);
|
||||
char *copy = LIBSSH2_ALLOC(session, len + 1);
|
||||
if(copy) {
|
||||
memcpy(copy, errmsg, len + 1);
|
||||
session->err_flags = LIBSSH2_ERR_FLAG_DUP;
|
||||
session->err_msg = copy;
|
||||
}
|
||||
else
|
||||
/* Out of memory: this code path is very unlikely */
|
||||
session->err_msg = "former error forgotten (OOM)";
|
||||
}
|
||||
else
|
||||
session->err_msg = errmsg;
|
||||
|
||||
#ifdef LIBSSH2DEBUG
|
||||
if((errcode == LIBSSH2_ERROR_EAGAIN) && !session->api_block_mode)
|
||||
/* if this is EAGAIN and we're in non-blocking mode, don't generate
|
||||
a debug output for this */
|
||||
return errcode;
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_ERROR, "%d - %s", session->err_code,
|
||||
session->err_msg);
|
||||
#endif
|
||||
|
||||
return errcode;
|
||||
}
|
||||
|
||||
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg)
|
||||
{
|
||||
return _libssh2_error_flags(session, errcode, errmsg, 0);
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
static int wsa2errno(void)
|
||||
{
|
||||
switch(WSAGetLastError()) {
|
||||
case WSAEWOULDBLOCK:
|
||||
return EAGAIN;
|
||||
|
||||
case WSAENOTSOCK:
|
||||
return EBADF;
|
||||
|
||||
case WSAEINTR:
|
||||
return EINTR;
|
||||
|
||||
default:
|
||||
/* It is most important to ensure errno does not stay at EAGAIN
|
||||
* when a different error occurs so just set errno to a generic
|
||||
* error */
|
||||
return EIO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* _libssh2_recv
|
||||
*
|
||||
* Replacement for the standard recv, return -errno on failure.
|
||||
*/
|
||||
ssize_t
|
||||
_libssh2_recv(libssh2_socket_t sock, void *buffer, size_t length,
|
||||
int flags, void **abstract)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
||||
(void) abstract;
|
||||
|
||||
rc = recv(sock, buffer, length, flags);
|
||||
#ifdef WIN32
|
||||
if(rc < 0)
|
||||
return -wsa2errno();
|
||||
#else
|
||||
if(rc < 0) {
|
||||
/* Sometimes the first recv() function call sets errno to ENOENT on
|
||||
Solaris and HP-UX */
|
||||
if(errno == ENOENT)
|
||||
return -EAGAIN;
|
||||
#ifdef EWOULDBLOCK /* For VMS and other special unixes */
|
||||
else if(errno == EWOULDBLOCK)
|
||||
return -EAGAIN;
|
||||
#endif
|
||||
else
|
||||
return -errno;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* _libssh2_send
|
||||
*
|
||||
* Replacement for the standard send, return -errno on failure.
|
||||
*/
|
||||
ssize_t
|
||||
_libssh2_send(libssh2_socket_t sock, const void *buffer, size_t length,
|
||||
int flags, void **abstract)
|
||||
{
|
||||
ssize_t rc;
|
||||
|
||||
(void) abstract;
|
||||
|
||||
rc = send(sock, buffer, length, flags);
|
||||
#ifdef WIN32
|
||||
if(rc < 0)
|
||||
return -wsa2errno();
|
||||
#else
|
||||
if(rc < 0) {
|
||||
#ifdef EWOULDBLOCK /* For VMS and other special unixes */
|
||||
if(errno == EWOULDBLOCK)
|
||||
return -EAGAIN;
|
||||
#endif
|
||||
return -errno;
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* libssh2_ntohu32
|
||||
*/
|
||||
unsigned int
|
||||
_libssh2_ntohu32(const unsigned char *buf)
|
||||
{
|
||||
return (((unsigned int)buf[0] << 24)
|
||||
| ((unsigned int)buf[1] << 16)
|
||||
| ((unsigned int)buf[2] << 8)
|
||||
| ((unsigned int)buf[3]));
|
||||
}
|
||||
|
||||
|
||||
/* _libssh2_ntohu64
|
||||
*/
|
||||
libssh2_uint64_t
|
||||
_libssh2_ntohu64(const unsigned char *buf)
|
||||
{
|
||||
unsigned long msl, lsl;
|
||||
|
||||
msl = ((libssh2_uint64_t)buf[0] << 24) | ((libssh2_uint64_t)buf[1] << 16)
|
||||
| ((libssh2_uint64_t)buf[2] << 8) | (libssh2_uint64_t)buf[3];
|
||||
lsl = ((libssh2_uint64_t)buf[4] << 24) | ((libssh2_uint64_t)buf[5] << 16)
|
||||
| ((libssh2_uint64_t)buf[6] << 8) | (libssh2_uint64_t)buf[7];
|
||||
|
||||
return ((libssh2_uint64_t)msl <<32) | lsl;
|
||||
}
|
||||
|
||||
/* _libssh2_htonu32
|
||||
*/
|
||||
void
|
||||
_libssh2_htonu32(unsigned char *buf, uint32_t value)
|
||||
{
|
||||
buf[0] = (value >> 24) & 0xFF;
|
||||
buf[1] = (value >> 16) & 0xFF;
|
||||
buf[2] = (value >> 8) & 0xFF;
|
||||
buf[3] = value & 0xFF;
|
||||
}
|
||||
|
||||
/* _libssh2_store_u32
|
||||
*/
|
||||
void _libssh2_store_u32(unsigned char **buf, uint32_t value)
|
||||
{
|
||||
_libssh2_htonu32(*buf, value);
|
||||
*buf += sizeof(uint32_t);
|
||||
}
|
||||
|
||||
/* _libssh2_store_str
|
||||
*/
|
||||
void _libssh2_store_str(unsigned char **buf, const char *str, size_t len)
|
||||
{
|
||||
_libssh2_store_u32(buf, (uint32_t)len);
|
||||
if(len) {
|
||||
memcpy(*buf, str, len);
|
||||
*buf += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* _libssh2_store_bignum2_bytes
|
||||
*/
|
||||
void _libssh2_store_bignum2_bytes(unsigned char **buf,
|
||||
const unsigned char *bytes,
|
||||
size_t len)
|
||||
{
|
||||
int extraByte = 0;
|
||||
const unsigned char *p;
|
||||
for(p = bytes; len > 0 && *p == 0; --len, ++p) {}
|
||||
|
||||
extraByte = (len > 0 && (p[0] & 0x80) != 0);
|
||||
_libssh2_store_u32(buf, len + extraByte);
|
||||
|
||||
if(extraByte) {
|
||||
*buf[0] = 0;
|
||||
*buf += 1;
|
||||
}
|
||||
|
||||
if(len > 0) {
|
||||
memcpy(*buf, p, len);
|
||||
*buf += len;
|
||||
}
|
||||
}
|
||||
|
||||
/* Base64 Conversion */
|
||||
|
||||
static const short base64_reverse_table[256] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
|
||||
-1, 0, 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, -1, -1, -1, -1, -1,
|
||||
-1, 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, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||
};
|
||||
|
||||
/* libssh2_base64_decode
|
||||
*
|
||||
* Decode a base64 chunk and store it into a newly alloc'd buffer
|
||||
*/
|
||||
LIBSSH2_API int
|
||||
libssh2_base64_decode(LIBSSH2_SESSION *session, char **data,
|
||||
unsigned int *datalen, const char *src,
|
||||
unsigned int src_len)
|
||||
{
|
||||
unsigned char *s, *d;
|
||||
short v;
|
||||
int i = 0, len = 0;
|
||||
|
||||
*data = LIBSSH2_ALLOC(session, (3 * src_len / 4) + 1);
|
||||
d = (unsigned char *) *data;
|
||||
if(!d) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for base64 decoding");
|
||||
}
|
||||
|
||||
for(s = (unsigned char *) src; ((char *) s) < (src + src_len); s++) {
|
||||
v = base64_reverse_table[*s];
|
||||
if(v < 0)
|
||||
continue;
|
||||
switch(i % 4) {
|
||||
case 0:
|
||||
d[len] = (unsigned char)(v << 2);
|
||||
break;
|
||||
case 1:
|
||||
d[len++] |= v >> 4;
|
||||
d[len] = (unsigned char)(v << 4);
|
||||
break;
|
||||
case 2:
|
||||
d[len++] |= v >> 2;
|
||||
d[len] = (unsigned char)(v << 6);
|
||||
break;
|
||||
case 3:
|
||||
d[len++] |= v;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if((i % 4) == 1) {
|
||||
/* Invalid -- We have a byte which belongs exclusively to a partial
|
||||
octet */
|
||||
LIBSSH2_FREE(session, *data);
|
||||
*data = NULL;
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_INVAL, "Invalid base64");
|
||||
}
|
||||
|
||||
*datalen = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ---- Base64 Encoding/Decoding Table --- */
|
||||
static const char table64[]=
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
/*
|
||||
* _libssh2_base64_encode()
|
||||
*
|
||||
* Returns the length of the newly created base64 string. The third argument
|
||||
* is a pointer to an allocated area holding the base64 data. If something
|
||||
* went wrong, 0 is returned.
|
||||
*
|
||||
*/
|
||||
size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
|
||||
const char *inp, size_t insize, char **outptr)
|
||||
{
|
||||
unsigned char ibuf[3];
|
||||
unsigned char obuf[4];
|
||||
int i;
|
||||
int inputparts;
|
||||
char *output;
|
||||
char *base64data;
|
||||
const char *indata = inp;
|
||||
|
||||
*outptr = NULL; /* set to NULL in case of failure before we reach the
|
||||
end */
|
||||
|
||||
if(0 == insize)
|
||||
insize = strlen(indata);
|
||||
|
||||
base64data = output = LIBSSH2_ALLOC(session, insize * 4 / 3 + 4);
|
||||
if(NULL == output)
|
||||
return 0;
|
||||
|
||||
while(insize > 0) {
|
||||
for(i = inputparts = 0; i < 3; i++) {
|
||||
if(insize > 0) {
|
||||
inputparts++;
|
||||
ibuf[i] = *indata;
|
||||
indata++;
|
||||
insize--;
|
||||
}
|
||||
else
|
||||
ibuf[i] = 0;
|
||||
}
|
||||
|
||||
obuf[0] = (unsigned char) ((ibuf[0] & 0xFC) >> 2);
|
||||
obuf[1] = (unsigned char) (((ibuf[0] & 0x03) << 4) | \
|
||||
((ibuf[1] & 0xF0) >> 4));
|
||||
obuf[2] = (unsigned char) (((ibuf[1] & 0x0F) << 2) | \
|
||||
((ibuf[2] & 0xC0) >> 6));
|
||||
obuf[3] = (unsigned char) (ibuf[2] & 0x3F);
|
||||
|
||||
switch(inputparts) {
|
||||
case 1: /* only one byte read */
|
||||
snprintf(output, 5, "%c%c==",
|
||||
table64[obuf[0]],
|
||||
table64[obuf[1]]);
|
||||
break;
|
||||
case 2: /* two bytes read */
|
||||
snprintf(output, 5, "%c%c%c=",
|
||||
table64[obuf[0]],
|
||||
table64[obuf[1]],
|
||||
table64[obuf[2]]);
|
||||
break;
|
||||
default:
|
||||
snprintf(output, 5, "%c%c%c%c",
|
||||
table64[obuf[0]],
|
||||
table64[obuf[1]],
|
||||
table64[obuf[2]],
|
||||
table64[obuf[3]]);
|
||||
break;
|
||||
}
|
||||
output += 4;
|
||||
}
|
||||
*output = 0;
|
||||
*outptr = base64data; /* make it return the actual data memory */
|
||||
|
||||
return strlen(base64data); /* return the length of the new data */
|
||||
}
|
||||
/* ---- End of Base64 Encoding ---- */
|
||||
|
||||
LIBSSH2_API void
|
||||
libssh2_free(LIBSSH2_SESSION *session, void *ptr)
|
||||
{
|
||||
LIBSSH2_FREE(session, ptr);
|
||||
}
|
||||
|
||||
#ifdef LIBSSH2DEBUG
|
||||
#include <stdarg.h>
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
|
||||
{
|
||||
session->showmask = bitmask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context,
|
||||
libssh2_trace_handler_func callback)
|
||||
{
|
||||
session->tracehandler = callback;
|
||||
session->tracehandler_context = handler_context;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_libssh2_debug(LIBSSH2_SESSION * session, int context, const char *format, ...)
|
||||
{
|
||||
char buffer[1536];
|
||||
int len, msglen, buflen = sizeof(buffer);
|
||||
va_list vargs;
|
||||
struct timeval now;
|
||||
static int firstsec;
|
||||
static const char *const contexts[] = {
|
||||
"Unknown",
|
||||
"Transport",
|
||||
"Key Ex",
|
||||
"Userauth",
|
||||
"Conn",
|
||||
"SCP",
|
||||
"SFTP",
|
||||
"Failure Event",
|
||||
"Publickey",
|
||||
"Socket",
|
||||
};
|
||||
const char *contexttext = contexts[0];
|
||||
unsigned int contextindex;
|
||||
|
||||
if(!(session->showmask & context)) {
|
||||
/* no such output asked for */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Find the first matching context string for this message */
|
||||
for(contextindex = 0; contextindex < ARRAY_SIZE(contexts);
|
||||
contextindex++) {
|
||||
if((context & (1 << contextindex)) != 0) {
|
||||
contexttext = contexts[contextindex];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_libssh2_gettimeofday(&now, NULL);
|
||||
if(!firstsec) {
|
||||
firstsec = now.tv_sec;
|
||||
}
|
||||
now.tv_sec -= firstsec;
|
||||
|
||||
len = snprintf(buffer, buflen, "[libssh2] %d.%06d %s: ",
|
||||
(int)now.tv_sec, (int)now.tv_usec, contexttext);
|
||||
|
||||
if(len >= buflen)
|
||||
msglen = buflen - 1;
|
||||
else {
|
||||
buflen -= len;
|
||||
msglen = len;
|
||||
va_start(vargs, format);
|
||||
len = vsnprintf(buffer + msglen, buflen, format, vargs);
|
||||
va_end(vargs);
|
||||
msglen += len < buflen ? len : buflen - 1;
|
||||
}
|
||||
|
||||
if(session->tracehandler)
|
||||
(session->tracehandler)(session, session->tracehandler_context, buffer,
|
||||
msglen);
|
||||
else
|
||||
fprintf(stderr, "%s\n", buffer);
|
||||
}
|
||||
|
||||
#else
|
||||
LIBSSH2_API int
|
||||
libssh2_trace(LIBSSH2_SESSION * session, int bitmask)
|
||||
{
|
||||
(void) session;
|
||||
(void) bitmask;
|
||||
return 0;
|
||||
}
|
||||
|
||||
LIBSSH2_API int
|
||||
libssh2_trace_sethandler(LIBSSH2_SESSION *session, void *handler_context,
|
||||
libssh2_trace_handler_func callback)
|
||||
{
|
||||
(void) session;
|
||||
(void) handler_context;
|
||||
(void) callback;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* init the list head */
|
||||
void _libssh2_list_init(struct list_head *head)
|
||||
{
|
||||
head->first = head->last = NULL;
|
||||
}
|
||||
|
||||
/* add a node to the list */
|
||||
void _libssh2_list_add(struct list_head *head,
|
||||
struct list_node *entry)
|
||||
{
|
||||
/* store a pointer to the head */
|
||||
entry->head = head;
|
||||
|
||||
/* we add this entry at the "top" so it has no next */
|
||||
entry->next = NULL;
|
||||
|
||||
/* make our prev point to what the head thinks is last */
|
||||
entry->prev = head->last;
|
||||
|
||||
/* and make head's last be us now */
|
||||
head->last = entry;
|
||||
|
||||
/* make sure our 'prev' node points to us next */
|
||||
if(entry->prev)
|
||||
entry->prev->next = entry;
|
||||
else
|
||||
head->first = entry;
|
||||
}
|
||||
|
||||
/* return the "first" node in the list this head points to */
|
||||
void *_libssh2_list_first(struct list_head *head)
|
||||
{
|
||||
return head->first;
|
||||
}
|
||||
|
||||
/* return the next node in the list */
|
||||
void *_libssh2_list_next(struct list_node *node)
|
||||
{
|
||||
return node->next;
|
||||
}
|
||||
|
||||
/* return the prev node in the list */
|
||||
void *_libssh2_list_prev(struct list_node *node)
|
||||
{
|
||||
return node->prev;
|
||||
}
|
||||
|
||||
/* remove this node from the list */
|
||||
void _libssh2_list_remove(struct list_node *entry)
|
||||
{
|
||||
if(entry->prev)
|
||||
entry->prev->next = entry->next;
|
||||
else
|
||||
entry->head->first = entry->next;
|
||||
|
||||
if(entry->next)
|
||||
entry->next->prev = entry->prev;
|
||||
else
|
||||
entry->head->last = entry->prev;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* insert a node before the given 'after' entry */
|
||||
void _libssh2_list_insert(struct list_node *after, /* insert before this */
|
||||
struct list_node *entry)
|
||||
{
|
||||
/* 'after' is next to 'entry' */
|
||||
bentry->next = after;
|
||||
|
||||
/* entry's prev is then made to be the prev after current has */
|
||||
entry->prev = after->prev;
|
||||
|
||||
/* the node that is now before 'entry' was previously before 'after'
|
||||
and must be made to point to 'entry' correctly */
|
||||
if(entry->prev)
|
||||
entry->prev->next = entry;
|
||||
else
|
||||
/* there was no node before this, so we make sure we point the head
|
||||
pointer to this node */
|
||||
after->head->first = entry;
|
||||
|
||||
/* after's prev entry points back to entry */
|
||||
after->prev = entry;
|
||||
|
||||
/* after's next entry is still the same as before */
|
||||
|
||||
/* entry's head is the same as after's */
|
||||
entry->head = after->head;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* this define is defined in misc.h for the correct platforms */
|
||||
#ifdef LIBSSH2_GETTIMEOFDAY_WIN32
|
||||
/*
|
||||
* gettimeofday
|
||||
* Implementation according to:
|
||||
* The Open Group Base Specifications Issue 6
|
||||
* IEEE Std 1003.1, 2004 Edition
|
||||
*/
|
||||
|
||||
/*
|
||||
* THIS SOFTWARE IS NOT COPYRIGHTED
|
||||
*
|
||||
* This source code is offered for use in the public domain. You may
|
||||
* use, modify or distribute it freely.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful but
|
||||
* WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
|
||||
* DISCLAIMED. This includes but is not limited to warranties of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* Contributed by:
|
||||
* Danny Smith <dannysmith@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
|
||||
#define _W32_FT_OFFSET (116444736000000000)
|
||||
|
||||
int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp)
|
||||
{
|
||||
union {
|
||||
unsigned __int64 ns100; /*time since 1 Jan 1601 in 100ns units */
|
||||
FILETIME ft;
|
||||
} _now;
|
||||
(void)tzp;
|
||||
if(tp) {
|
||||
GetSystemTimeAsFileTime(&_now.ft);
|
||||
tp->tv_usec = (long)((_now.ns100 / 10) % 1000000);
|
||||
tp->tv_sec = (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000);
|
||||
}
|
||||
/* Always return 0 as per Open Group Base Specifications Issue 6.
|
||||
Do not set errno on error. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
void *_libssh2_calloc(LIBSSH2_SESSION* session, size_t size)
|
||||
{
|
||||
void *p = LIBSSH2_ALLOC(session, size);
|
||||
if(p) {
|
||||
memset(p, 0, size);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/* XOR operation on buffers input1 and input2, result in output.
|
||||
It is safe to use an input buffer as the output buffer. */
|
||||
void _libssh2_xor_data(unsigned char *output,
|
||||
const unsigned char *input1,
|
||||
const unsigned char *input2,
|
||||
size_t length)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for(i = 0; i < length; i++)
|
||||
*output++ = *input1++ ^ *input2++;
|
||||
}
|
||||
|
||||
/* Increments an AES CTR buffer to prepare it for use with the
|
||||
next AES block. */
|
||||
void _libssh2_aes_ctr_increment(unsigned char *ctr,
|
||||
size_t length)
|
||||
{
|
||||
unsigned char *pc;
|
||||
unsigned int val, carry;
|
||||
|
||||
pc = ctr + length - 1;
|
||||
carry = 1;
|
||||
|
||||
while(pc >= ctr) {
|
||||
val = (unsigned int)*pc + carry;
|
||||
*pc-- = val & 0xFF;
|
||||
carry = val >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(WIN32) && !defined(HAVE_MEMSET_S)
|
||||
static void * (* const volatile memset_libssh)(void *, int, size_t) = memset;
|
||||
#endif
|
||||
|
||||
void _libssh2_explicit_zero(void *buf, size_t size)
|
||||
{
|
||||
#ifdef WIN32
|
||||
SecureZeroMemory(buf, size);
|
||||
#elif defined(HAVE_MEMSET_S)
|
||||
(void)memset_s(buf, size, 0, size);
|
||||
#else
|
||||
memset_libssh(buf, 0, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* String buffer */
|
||||
|
||||
struct string_buf* _libssh2_string_buf_new(LIBSSH2_SESSION *session)
|
||||
{
|
||||
struct string_buf *ret;
|
||||
|
||||
ret = _libssh2_calloc(session, sizeof(*ret));
|
||||
if(ret == NULL)
|
||||
return NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void _libssh2_string_buf_free(LIBSSH2_SESSION *session, struct string_buf *buf)
|
||||
{
|
||||
if(buf == NULL)
|
||||
return;
|
||||
|
||||
if(buf->data != NULL)
|
||||
LIBSSH2_FREE(session, buf->data);
|
||||
|
||||
LIBSSH2_FREE(session, buf);
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
int _libssh2_get_byte(struct string_buf *buf, unsigned char *out)
|
||||
{
|
||||
if(!_libssh2_check_length(buf, 1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out = buf->dataptr[0];
|
||||
buf->dataptr += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_get_boolean(struct string_buf *buf, unsigned char *out)
|
||||
{
|
||||
if(!_libssh2_check_length(buf, 1)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
*out = buf->dataptr[0] == 0 ? 0 : 1;
|
||||
buf->dataptr += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_get_u32(struct string_buf *buf, uint32_t *out)
|
||||
{
|
||||
if(!_libssh2_check_length(buf, 4)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out = _libssh2_ntohu32(buf->dataptr);
|
||||
buf->dataptr += 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out)
|
||||
{
|
||||
if(!_libssh2_check_length(buf, 8)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out = _libssh2_ntohu64(buf->dataptr);
|
||||
buf->dataptr += 8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_match_string(struct string_buf *buf, const char *match)
|
||||
{
|
||||
unsigned char *out;
|
||||
size_t len = 0;
|
||||
if(_libssh2_get_string(buf, &out, &len) || len != strlen(match) ||
|
||||
strncmp((char *)out, match, strlen(match)) != 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf,
|
||||
size_t *outlen)
|
||||
{
|
||||
uint32_t data_len;
|
||||
if(_libssh2_get_u32(buf, &data_len) != 0) {
|
||||
return -1;
|
||||
}
|
||||
if(!_libssh2_check_length(buf, data_len)) {
|
||||
return -1;
|
||||
}
|
||||
*outbuf = buf->dataptr;
|
||||
buf->dataptr += data_len;
|
||||
|
||||
if(outlen)
|
||||
*outlen = (size_t)data_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_copy_string(LIBSSH2_SESSION *session, struct string_buf *buf,
|
||||
unsigned char **outbuf, size_t *outlen)
|
||||
{
|
||||
size_t str_len;
|
||||
unsigned char *str;
|
||||
|
||||
if(_libssh2_get_string(buf, &str, &str_len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(str_len) {
|
||||
*outbuf = LIBSSH2_ALLOC(session, str_len);
|
||||
if(*outbuf) {
|
||||
memcpy(*outbuf, str, str_len);
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*outlen = 0;
|
||||
*outbuf = NULL;
|
||||
}
|
||||
|
||||
if(outlen)
|
||||
*outlen = str_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf,
|
||||
size_t *outlen)
|
||||
{
|
||||
uint32_t data_len;
|
||||
uint32_t bn_len;
|
||||
unsigned char *bnptr;
|
||||
|
||||
if(_libssh2_get_u32(buf, &data_len)) {
|
||||
return -1;
|
||||
}
|
||||
if(!_libssh2_check_length(buf, data_len)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bn_len = data_len;
|
||||
bnptr = buf->dataptr;
|
||||
|
||||
/* trim leading zeros */
|
||||
while(bn_len > 0 && *bnptr == 0x00) {
|
||||
bn_len--;
|
||||
bnptr++;
|
||||
}
|
||||
|
||||
*outbuf = bnptr;
|
||||
buf->dataptr += data_len;
|
||||
|
||||
if(outlen)
|
||||
*outlen = (size_t)bn_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Given the current location in buf, _libssh2_check_length ensures
|
||||
callers can read the next len number of bytes out of the buffer
|
||||
before reading the buffer content */
|
||||
|
||||
int _libssh2_check_length(struct string_buf *buf, size_t len)
|
||||
{
|
||||
unsigned char *endp = &buf->data[buf->len];
|
||||
size_t left = endp - buf->dataptr;
|
||||
return ((len <= left) && (left <= buf->len));
|
||||
}
|
||||
|
||||
int _libssh2_eob(struct string_buf *buf)
|
||||
{
|
||||
unsigned char *endp = &buf->data[buf->len];
|
||||
return buf->dataptr >= endp;
|
||||
}
|
||||
|
||||
/* Wrappers */
|
||||
|
||||
int _libssh2_bcrypt_pbkdf(const char *pass,
|
||||
size_t passlen,
|
||||
const uint8_t *salt,
|
||||
size_t saltlen,
|
||||
uint8_t *key,
|
||||
size_t keylen,
|
||||
unsigned int rounds)
|
||||
{
|
||||
/* defined in bcrypt_pbkdf.c */
|
||||
return bcrypt_pbkdf(pass,
|
||||
passlen,
|
||||
salt,
|
||||
saltlen,
|
||||
key,
|
||||
keylen,
|
||||
rounds);
|
||||
}
|
||||
#endif
|
||||
133
lib/libssh2/misc.h
Normal file
133
lib/libssh2/misc.h
Normal file
@@ -0,0 +1,133 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_MISC_H
|
||||
#define __LIBSSH2_MISC_H
|
||||
/* Copyright (c) 2009-2019 by Daniel Stenberg
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
struct list_head {
|
||||
struct list_node *last;
|
||||
struct list_node *first;
|
||||
};
|
||||
|
||||
struct list_node {
|
||||
struct list_node *next;
|
||||
struct list_node *prev;
|
||||
struct list_head *head;
|
||||
};
|
||||
|
||||
struct string_buf {
|
||||
unsigned char *data;
|
||||
unsigned char *dataptr;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
int _libssh2_error_flags(LIBSSH2_SESSION* session, int errcode,
|
||||
const char *errmsg, int errflags);
|
||||
int _libssh2_error(LIBSSH2_SESSION* session, int errcode, const char *errmsg);
|
||||
|
||||
void _libssh2_list_init(struct list_head *head);
|
||||
|
||||
/* add a node last in the list */
|
||||
void _libssh2_list_add(struct list_head *head,
|
||||
struct list_node *entry);
|
||||
|
||||
/* return the "first" node in the list this head points to */
|
||||
void *_libssh2_list_first(struct list_head *head);
|
||||
|
||||
/* return the next node in the list */
|
||||
void *_libssh2_list_next(struct list_node *node);
|
||||
|
||||
/* return the prev node in the list */
|
||||
void *_libssh2_list_prev(struct list_node *node);
|
||||
|
||||
/* remove this node from the list */
|
||||
void _libssh2_list_remove(struct list_node *entry);
|
||||
|
||||
size_t _libssh2_base64_encode(LIBSSH2_SESSION *session,
|
||||
const char *inp, size_t insize, char **outptr);
|
||||
|
||||
unsigned int _libssh2_ntohu32(const unsigned char *buf);
|
||||
libssh2_uint64_t _libssh2_ntohu64(const unsigned char *buf);
|
||||
void _libssh2_htonu32(unsigned char *buf, uint32_t val);
|
||||
void _libssh2_store_u32(unsigned char **buf, uint32_t value);
|
||||
void _libssh2_store_str(unsigned char **buf, const char *str, size_t len);
|
||||
void _libssh2_store_bignum2_bytes(unsigned char **buf,
|
||||
const unsigned char *bytes,
|
||||
size_t len);
|
||||
void *_libssh2_calloc(LIBSSH2_SESSION *session, size_t size);
|
||||
void _libssh2_explicit_zero(void *buf, size_t size);
|
||||
|
||||
struct string_buf* _libssh2_string_buf_new(LIBSSH2_SESSION *session);
|
||||
void _libssh2_string_buf_free(LIBSSH2_SESSION *session,
|
||||
struct string_buf *buf);
|
||||
int _libssh2_get_boolean(struct string_buf *buf, unsigned char *out);
|
||||
int _libssh2_get_byte(struct string_buf *buf, unsigned char *out);
|
||||
int _libssh2_get_u32(struct string_buf *buf, uint32_t *out);
|
||||
int _libssh2_get_u64(struct string_buf *buf, libssh2_uint64_t *out);
|
||||
int _libssh2_match_string(struct string_buf *buf, const char *match);
|
||||
int _libssh2_get_string(struct string_buf *buf, unsigned char **outbuf,
|
||||
size_t *outlen);
|
||||
int _libssh2_copy_string(LIBSSH2_SESSION* session, struct string_buf *buf,
|
||||
unsigned char **outbuf, size_t *outlen);
|
||||
int _libssh2_get_bignum_bytes(struct string_buf *buf, unsigned char **outbuf,
|
||||
size_t *outlen);
|
||||
int _libssh2_check_length(struct string_buf *buf, size_t requested_len);
|
||||
int _libssh2_eob(struct string_buf *buf);
|
||||
|
||||
#if defined(WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
/* provide a private one */
|
||||
#undef HAVE_GETTIMEOFDAY
|
||||
int __cdecl _libssh2_gettimeofday(struct timeval *tp, void *tzp);
|
||||
#define HAVE_LIBSSH2_GETTIMEOFDAY
|
||||
#define LIBSSH2_GETTIMEOFDAY_WIN32 /* enable the win32 implementation */
|
||||
#else
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
#define _libssh2_gettimeofday(x,y) gettimeofday(x,y)
|
||||
#define HAVE_LIBSSH2_GETTIMEOFDAY
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void _libssh2_xor_data(unsigned char *output,
|
||||
const unsigned char *input1,
|
||||
const unsigned char *input2,
|
||||
size_t length);
|
||||
|
||||
void _libssh2_aes_ctr_increment(unsigned char *ctr, size_t length);
|
||||
|
||||
#endif /* _LIBSSH2_MISC_H */
|
||||
#endif
|
||||
445
lib/libssh2/openssl.h
Normal file
445
lib/libssh2/openssl.h
Normal file
@@ -0,0 +1,445 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_OPENSSL_H
|
||||
#define __LIBSSH2_OPENSSL_H
|
||||
/* Copyright (C) 2009, 2010 Simon Josefsson
|
||||
* Copyright (C) 2006, 2007 The Written Word, Inc. All rights reserved.
|
||||
*
|
||||
* Author: Simon Josefsson
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* disable deprecated warnings in OpenSSL 3 */
|
||||
#define OPENSSL_SUPPRESS_DEPRECATED
|
||||
|
||||
#ifdef LIBSSH2_WOLFSSL
|
||||
|
||||
#include <wolfssl/options.h>
|
||||
#include <openssl/ecdh.h>
|
||||
|
||||
#if defined(NO_DSA) || defined(HAVE_FIPS)
|
||||
#define OPENSSL_NO_DSA
|
||||
#endif
|
||||
|
||||
#if defined(NO_MD5) || defined(HAVE_FIPS)
|
||||
#define OPENSSL_NO_MD5
|
||||
#endif
|
||||
|
||||
#if !defined(WOLFSSL_RIPEMD) || defined(HAVE_FIPS)
|
||||
#define OPENSSL_NO_RIPEMD
|
||||
#endif
|
||||
|
||||
#if defined(NO_RC4) || defined(HAVE_FIPS)
|
||||
#define OPENSSL_NO_RC4
|
||||
#endif
|
||||
|
||||
#ifdef NO_DES3
|
||||
#define OPENSSL_NO_DES
|
||||
#endif
|
||||
|
||||
#ifdef EVP_aes_128_ctr
|
||||
#define HAVE_EVP_AES_128_CTR
|
||||
#endif
|
||||
|
||||
/* wolfSSL doesn't support Blowfish or CAST. */
|
||||
#define OPENSSL_NO_BF
|
||||
#define OPENSSL_NO_CAST
|
||||
/* wolfSSL has no engine framework. */
|
||||
#define OPENSSL_NO_ENGINE
|
||||
|
||||
#endif /* LIBSSH2_WOLFSSL */
|
||||
|
||||
#include <openssl/opensslconf.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/rsa.h>
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
#include <openssl/dsa.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_MD5
|
||||
#include <openssl/md5.h>
|
||||
#endif
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/rand.h>
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && \
|
||||
!defined(LIBRESSL_VERSION_NUMBER)) || defined(LIBSSH2_WOLFSSL) || \
|
||||
LIBRESSL_VERSION_NUMBER >= 0x3050000fL
|
||||
/* For wolfSSL, whether the structs are truly opaque or not, it's best to not
|
||||
* rely on their internal data members being exposed publicly. */
|
||||
# define HAVE_OPAQUE_STRUCTS 1
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_RSA
|
||||
# define LIBSSH2_RSA 0
|
||||
# define LIBSSH2_RSA_SHA2 0
|
||||
#else
|
||||
# define LIBSSH2_RSA 1
|
||||
# define LIBSSH2_RSA_SHA2 1
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_DSA
|
||||
# define LIBSSH2_DSA 0
|
||||
#else
|
||||
# define LIBSSH2_DSA 1
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_NO_ECDSA) || defined(OPENSSL_NO_EC)
|
||||
# define LIBSSH2_ECDSA 0
|
||||
#else
|
||||
# define LIBSSH2_ECDSA 1
|
||||
#endif
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x10101000L && \
|
||||
!defined(LIBRESSL_VERSION_NUMBER)) || \
|
||||
LIBRESSL_VERSION_NUMBER >= 0x3070000fL
|
||||
# define LIBSSH2_ED25519 1
|
||||
#else
|
||||
# define LIBSSH2_ED25519 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef OPENSSL_NO_MD5
|
||||
# define LIBSSH2_MD5 0
|
||||
#else
|
||||
# define LIBSSH2_MD5 1
|
||||
#endif
|
||||
|
||||
#if defined(OPENSSL_NO_RIPEMD) || defined(OPENSSL_NO_RMD160)
|
||||
# define LIBSSH2_HMAC_RIPEMD 0
|
||||
#else
|
||||
# define LIBSSH2_HMAC_RIPEMD 1
|
||||
#endif
|
||||
|
||||
#define LIBSSH2_HMAC_SHA256 1
|
||||
#define LIBSSH2_HMAC_SHA512 1
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER >= 0x00907000L && !defined(OPENSSL_NO_AES)) || \
|
||||
(defined(LIBSSH2_WOLFSSL) && defined(WOLFSSL_AES_COUNTER))
|
||||
# define LIBSSH2_AES_CTR 1
|
||||
# define LIBSSH2_AES 1
|
||||
#else
|
||||
# define LIBSSH2_AES_CTR 0
|
||||
# define LIBSSH2_AES 0
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_BF
|
||||
# define LIBSSH2_BLOWFISH 0
|
||||
#else
|
||||
# define LIBSSH2_BLOWFISH 1
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_RC4
|
||||
# define LIBSSH2_RC4 0
|
||||
#else
|
||||
# define LIBSSH2_RC4 1
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_CAST
|
||||
# define LIBSSH2_CAST 0
|
||||
#else
|
||||
# define LIBSSH2_CAST 1
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_NO_DES
|
||||
# define LIBSSH2_3DES 0
|
||||
#else
|
||||
# define LIBSSH2_3DES 1
|
||||
#endif
|
||||
|
||||
#define EC_MAX_POINT_LEN ((528 * 2 / 8) + 1)
|
||||
|
||||
#define _libssh2_random(buf, len) (RAND_bytes((buf), (len)) == 1 ? 0 : -1)
|
||||
|
||||
#define libssh2_prepare_iovec(vec, len) /* Empty. */
|
||||
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define libssh2_sha1_ctx EVP_MD_CTX *
|
||||
#else
|
||||
#define libssh2_sha1_ctx EVP_MD_CTX
|
||||
#endif
|
||||
|
||||
/* returns 0 in case of failure */
|
||||
int _libssh2_sha1_init(libssh2_sha1_ctx *ctx);
|
||||
#define libssh2_sha1_init(x) _libssh2_sha1_init(x)
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
|
||||
#define libssh2_sha1_final(ctx, out) do { \
|
||||
EVP_DigestFinal(ctx, out, NULL); \
|
||||
EVP_MD_CTX_free(ctx); \
|
||||
} while(0)
|
||||
#else
|
||||
#define libssh2_sha1_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
|
||||
#define libssh2_sha1_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
||||
#endif
|
||||
int _libssh2_sha1(const unsigned char *message, unsigned long len,
|
||||
unsigned char *out);
|
||||
#define libssh2_sha1(x,y,z) _libssh2_sha1(x,y,z)
|
||||
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define libssh2_sha256_ctx EVP_MD_CTX *
|
||||
#else
|
||||
#define libssh2_sha256_ctx EVP_MD_CTX
|
||||
#endif
|
||||
|
||||
/* returns 0 in case of failure */
|
||||
int _libssh2_sha256_init(libssh2_sha256_ctx *ctx);
|
||||
#define libssh2_sha256_init(x) _libssh2_sha256_init(x)
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define libssh2_sha256_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
|
||||
#define libssh2_sha256_final(ctx, out) do { \
|
||||
EVP_DigestFinal(ctx, out, NULL); \
|
||||
EVP_MD_CTX_free(ctx); \
|
||||
} while(0)
|
||||
#else
|
||||
#define libssh2_sha256_update(ctx, data, len) \
|
||||
EVP_DigestUpdate(&(ctx), data, len)
|
||||
#define libssh2_sha256_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
||||
#endif
|
||||
int _libssh2_sha256(const unsigned char *message, unsigned long len,
|
||||
unsigned char *out);
|
||||
#define libssh2_sha256(x,y,z) _libssh2_sha256(x,y,z)
|
||||
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define libssh2_sha384_ctx EVP_MD_CTX *
|
||||
#else
|
||||
#define libssh2_sha384_ctx EVP_MD_CTX
|
||||
#endif
|
||||
|
||||
/* returns 0 in case of failure */
|
||||
int _libssh2_sha384_init(libssh2_sha384_ctx *ctx);
|
||||
#define libssh2_sha384_init(x) _libssh2_sha384_init(x)
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define libssh2_sha384_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
|
||||
#define libssh2_sha384_final(ctx, out) do { \
|
||||
EVP_DigestFinal(ctx, out, NULL); \
|
||||
EVP_MD_CTX_free(ctx); \
|
||||
} while(0)
|
||||
#else
|
||||
#define libssh2_sha384_update(ctx, data, len) \
|
||||
EVP_DigestUpdate(&(ctx), data, len)
|
||||
#define libssh2_sha384_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
||||
#endif
|
||||
int _libssh2_sha384(const unsigned char *message, unsigned long len,
|
||||
unsigned char *out);
|
||||
#define libssh2_sha384(x,y,z) _libssh2_sha384(x,y,z)
|
||||
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define libssh2_sha512_ctx EVP_MD_CTX *
|
||||
#else
|
||||
#define libssh2_sha512_ctx EVP_MD_CTX
|
||||
#endif
|
||||
|
||||
/* returns 0 in case of failure */
|
||||
int _libssh2_sha512_init(libssh2_sha512_ctx *ctx);
|
||||
#define libssh2_sha512_init(x) _libssh2_sha512_init(x)
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define libssh2_sha512_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
|
||||
#define libssh2_sha512_final(ctx, out) do { \
|
||||
EVP_DigestFinal(ctx, out, NULL); \
|
||||
EVP_MD_CTX_free(ctx); \
|
||||
} while(0)
|
||||
#else
|
||||
#define libssh2_sha512_update(ctx, data, len) \
|
||||
EVP_DigestUpdate(&(ctx), data, len)
|
||||
#define libssh2_sha512_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
||||
#endif
|
||||
int _libssh2_sha512(const unsigned char *message, unsigned long len,
|
||||
unsigned char *out);
|
||||
#define libssh2_sha512(x,y,z) _libssh2_sha512(x,y,z)
|
||||
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define libssh2_md5_ctx EVP_MD_CTX *
|
||||
#else
|
||||
#define libssh2_md5_ctx EVP_MD_CTX
|
||||
#endif
|
||||
|
||||
/* returns 0 in case of failure */
|
||||
int _libssh2_md5_init(libssh2_md5_ctx *ctx);
|
||||
#define libssh2_md5_init(x) _libssh2_md5_init(x)
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(ctx, data, len)
|
||||
#define libssh2_md5_final(ctx, out) do { \
|
||||
EVP_DigestFinal(ctx, out, NULL); \
|
||||
EVP_MD_CTX_free(ctx); \
|
||||
} while(0)
|
||||
#else
|
||||
#define libssh2_md5_update(ctx, data, len) EVP_DigestUpdate(&(ctx), data, len)
|
||||
#define libssh2_md5_final(ctx, out) EVP_DigestFinal(&(ctx), out, NULL)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define libssh2_hmac_ctx HMAC_CTX *
|
||||
#define libssh2_hmac_ctx_init(ctx) ctx = HMAC_CTX_new()
|
||||
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
|
||||
HMAC_Init_ex(*(ctx), key, keylen, EVP_sha1(), NULL)
|
||||
#define libssh2_hmac_md5_init(ctx, key, keylen) \
|
||||
HMAC_Init_ex(*(ctx), key, keylen, EVP_md5(), NULL)
|
||||
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
|
||||
HMAC_Init_ex(*(ctx), key, keylen, EVP_ripemd160(), NULL)
|
||||
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
|
||||
HMAC_Init_ex(*(ctx), key, keylen, EVP_sha256(), NULL)
|
||||
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
|
||||
HMAC_Init_ex(*(ctx), key, keylen, EVP_sha512(), NULL)
|
||||
|
||||
#define libssh2_hmac_update(ctx, data, datalen) \
|
||||
HMAC_Update(ctx, data, datalen)
|
||||
#define libssh2_hmac_final(ctx, data) HMAC_Final(ctx, data, NULL)
|
||||
#define libssh2_hmac_cleanup(ctx) HMAC_CTX_free(*(ctx))
|
||||
#else
|
||||
#define libssh2_hmac_ctx HMAC_CTX
|
||||
#define libssh2_hmac_ctx_init(ctx) \
|
||||
HMAC_CTX_init(&ctx)
|
||||
#define libssh2_hmac_sha1_init(ctx, key, keylen) \
|
||||
HMAC_Init_ex(ctx, key, keylen, EVP_sha1(), NULL)
|
||||
#define libssh2_hmac_md5_init(ctx, key, keylen) \
|
||||
HMAC_Init_ex(ctx, key, keylen, EVP_md5(), NULL)
|
||||
#define libssh2_hmac_ripemd160_init(ctx, key, keylen) \
|
||||
HMAC_Init_ex(ctx, key, keylen, EVP_ripemd160(), NULL)
|
||||
#define libssh2_hmac_sha256_init(ctx, key, keylen) \
|
||||
HMAC_Init_ex(ctx, key, keylen, EVP_sha256(), NULL)
|
||||
#define libssh2_hmac_sha512_init(ctx, key, keylen) \
|
||||
HMAC_Init_ex(ctx, key, keylen, EVP_sha512(), NULL)
|
||||
|
||||
#define libssh2_hmac_update(ctx, data, datalen) \
|
||||
HMAC_Update(&(ctx), data, datalen)
|
||||
#define libssh2_hmac_final(ctx, data) HMAC_Final(&(ctx), data, NULL)
|
||||
#define libssh2_hmac_cleanup(ctx) HMAC_cleanup(ctx)
|
||||
#endif
|
||||
|
||||
extern void _libssh2_openssl_crypto_init(void);
|
||||
extern void _libssh2_openssl_crypto_exit(void);
|
||||
#define libssh2_crypto_init() _libssh2_openssl_crypto_init()
|
||||
#define libssh2_crypto_exit() _libssh2_openssl_crypto_exit()
|
||||
|
||||
#define libssh2_rsa_ctx RSA
|
||||
|
||||
#define _libssh2_rsa_free(rsactx) RSA_free(rsactx)
|
||||
|
||||
#define libssh2_dsa_ctx DSA
|
||||
|
||||
#define _libssh2_dsa_free(dsactx) DSA_free(dsactx)
|
||||
|
||||
#if LIBSSH2_ECDSA
|
||||
#define libssh2_ecdsa_ctx EC_KEY
|
||||
#define _libssh2_ecdsa_free(ecdsactx) EC_KEY_free(ecdsactx)
|
||||
#define _libssh2_ec_key EC_KEY
|
||||
|
||||
typedef enum {
|
||||
LIBSSH2_EC_CURVE_NISTP256 = NID_X9_62_prime256v1,
|
||||
LIBSSH2_EC_CURVE_NISTP384 = NID_secp384r1,
|
||||
LIBSSH2_EC_CURVE_NISTP521 = NID_secp521r1
|
||||
}
|
||||
libssh2_curve_type;
|
||||
#else
|
||||
#define _libssh2_ec_key void
|
||||
#endif /* LIBSSH2_ECDSA */
|
||||
|
||||
#if LIBSSH2_ED25519
|
||||
#define libssh2_ed25519_ctx EVP_PKEY
|
||||
|
||||
#define _libssh2_ed25519_free(ctx) EVP_PKEY_free(ctx)
|
||||
#endif /* ED25519 */
|
||||
|
||||
#define _libssh2_cipher_type(name) const EVP_CIPHER *(*name)(void)
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define _libssh2_cipher_ctx EVP_CIPHER_CTX *
|
||||
#else
|
||||
#define _libssh2_cipher_ctx EVP_CIPHER_CTX
|
||||
#endif
|
||||
|
||||
#define _libssh2_cipher_aes256 EVP_aes_256_cbc
|
||||
#define _libssh2_cipher_aes192 EVP_aes_192_cbc
|
||||
#define _libssh2_cipher_aes128 EVP_aes_128_cbc
|
||||
#ifdef HAVE_EVP_AES_128_CTR
|
||||
#define _libssh2_cipher_aes128ctr EVP_aes_128_ctr
|
||||
#define _libssh2_cipher_aes192ctr EVP_aes_192_ctr
|
||||
#define _libssh2_cipher_aes256ctr EVP_aes_256_ctr
|
||||
#else
|
||||
#define _libssh2_cipher_aes128ctr _libssh2_EVP_aes_128_ctr
|
||||
#define _libssh2_cipher_aes192ctr _libssh2_EVP_aes_192_ctr
|
||||
#define _libssh2_cipher_aes256ctr _libssh2_EVP_aes_256_ctr
|
||||
#endif
|
||||
#define _libssh2_cipher_blowfish EVP_bf_cbc
|
||||
#define _libssh2_cipher_arcfour EVP_rc4
|
||||
#define _libssh2_cipher_cast5 EVP_cast5_cbc
|
||||
#define _libssh2_cipher_3des EVP_des_ede3_cbc
|
||||
|
||||
#ifdef HAVE_OPAQUE_STRUCTS
|
||||
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_free(*(ctx))
|
||||
#else
|
||||
#define _libssh2_cipher_dtor(ctx) EVP_CIPHER_CTX_cleanup(ctx)
|
||||
#endif
|
||||
|
||||
#define _libssh2_bn BIGNUM
|
||||
#define _libssh2_bn_ctx BN_CTX
|
||||
#define _libssh2_bn_ctx_new() BN_CTX_new()
|
||||
#define _libssh2_bn_ctx_free(bnctx) BN_CTX_free(bnctx)
|
||||
#define _libssh2_bn_init() BN_new()
|
||||
#define _libssh2_bn_init_from_bin() _libssh2_bn_init()
|
||||
#define _libssh2_bn_set_word(bn, val) BN_set_word(bn, val)
|
||||
#define _libssh2_bn_from_bin(bn, len, val) BN_bin2bn(val, len, bn)
|
||||
#define _libssh2_bn_to_bin(bn, val) BN_bn2bin(bn, val)
|
||||
#define _libssh2_bn_bytes(bn) BN_num_bytes(bn)
|
||||
#define _libssh2_bn_bits(bn) BN_num_bits(bn)
|
||||
#define _libssh2_bn_free(bn) BN_clear_free(bn)
|
||||
|
||||
#define _libssh2_dh_ctx BIGNUM *
|
||||
#define libssh2_dh_init(dhctx) _libssh2_dh_init(dhctx)
|
||||
#define libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx) \
|
||||
_libssh2_dh_key_pair(dhctx, public, g, p, group_order, bnctx)
|
||||
#define libssh2_dh_secret(dhctx, secret, f, p, bnctx) \
|
||||
_libssh2_dh_secret(dhctx, secret, f, p, bnctx)
|
||||
#define libssh2_dh_dtor(dhctx) _libssh2_dh_dtor(dhctx)
|
||||
extern void _libssh2_dh_init(_libssh2_dh_ctx *dhctx);
|
||||
extern int _libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public,
|
||||
_libssh2_bn *g, _libssh2_bn *p,
|
||||
int group_order,
|
||||
_libssh2_bn_ctx *bnctx);
|
||||
extern int _libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret,
|
||||
_libssh2_bn *f, _libssh2_bn *p,
|
||||
_libssh2_bn_ctx *bnctx);
|
||||
extern void _libssh2_dh_dtor(_libssh2_dh_ctx *dhctx);
|
||||
|
||||
const EVP_CIPHER *_libssh2_EVP_aes_128_ctr(void);
|
||||
const EVP_CIPHER *_libssh2_EVP_aes_192_ctr(void);
|
||||
const EVP_CIPHER *_libssh2_EVP_aes_256_ctr(void);
|
||||
|
||||
#endif /* __LIBSSH2_OPENSSL_H */
|
||||
#endif
|
||||
1409
lib/libssh2/packet.c
Normal file
1409
lib/libssh2/packet.c
Normal file
File diff suppressed because it is too large
Load Diff
78
lib/libssh2/packet.h
Normal file
78
lib/libssh2/packet.h
Normal file
@@ -0,0 +1,78 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_PACKET_H
|
||||
#define __LIBSSH2_PACKET_H
|
||||
/*
|
||||
* Copyright (C) 2010 by Daniel Stenberg
|
||||
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
int _libssh2_packet_read(LIBSSH2_SESSION * session);
|
||||
|
||||
int _libssh2_packet_ask(LIBSSH2_SESSION * session, unsigned char packet_type,
|
||||
unsigned char **data, size_t *data_len,
|
||||
int match_ofs,
|
||||
const unsigned char *match_buf,
|
||||
size_t match_len);
|
||||
|
||||
int _libssh2_packet_askv(LIBSSH2_SESSION * session,
|
||||
const unsigned char *packet_types,
|
||||
unsigned char **data, size_t *data_len,
|
||||
int match_ofs,
|
||||
const unsigned char *match_buf,
|
||||
size_t match_len);
|
||||
int _libssh2_packet_require(LIBSSH2_SESSION * session,
|
||||
unsigned char packet_type, unsigned char **data,
|
||||
size_t *data_len, int match_ofs,
|
||||
const unsigned char *match_buf,
|
||||
size_t match_len,
|
||||
packet_require_state_t * state);
|
||||
int _libssh2_packet_requirev(LIBSSH2_SESSION *session,
|
||||
const unsigned char *packet_types,
|
||||
unsigned char **data, size_t *data_len,
|
||||
int match_ofs,
|
||||
const unsigned char *match_buf,
|
||||
size_t match_len,
|
||||
packet_requirev_state_t * state);
|
||||
int _libssh2_packet_burn(LIBSSH2_SESSION * session,
|
||||
libssh2_nonblocking_states * state);
|
||||
int _libssh2_packet_write(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
unsigned long data_len);
|
||||
int _libssh2_packet_add(LIBSSH2_SESSION * session, unsigned char *data,
|
||||
size_t datalen, int macstate);
|
||||
|
||||
#endif /* __LIBSSH2_PACKET_H */
|
||||
#endif
|
||||
913
lib/libssh2/pem.c
Normal file
913
lib/libssh2/pem.c
Normal file
@@ -0,0 +1,913 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (C) 2007 The Written Word, Inc.
|
||||
* Copyright (C) 2008, Simon Josefsson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
|
||||
static int
|
||||
readline(char *line, int line_size, FILE * fp)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if(!line) {
|
||||
return -1;
|
||||
}
|
||||
if(!fgets(line, line_size, fp)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(*line) {
|
||||
len = strlen(line);
|
||||
if(len > 0 && line[len - 1] == '\n') {
|
||||
line[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if(*line) {
|
||||
len = strlen(line);
|
||||
if(len > 0 && line[len - 1] == '\r') {
|
||||
line[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
readline_memory(char *line, size_t line_size,
|
||||
const char *filedata, size_t filedata_len,
|
||||
size_t *filedata_offset)
|
||||
{
|
||||
size_t off, len;
|
||||
|
||||
off = *filedata_offset;
|
||||
|
||||
for(len = 0; off + len < filedata_len && len < line_size - 1; len++) {
|
||||
if(filedata[off + len] == '\n' ||
|
||||
filedata[off + len] == '\r') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(len) {
|
||||
memcpy(line, filedata + off, len);
|
||||
*filedata_offset += len;
|
||||
}
|
||||
|
||||
line[len] = '\0';
|
||||
*filedata_offset += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define LINE_SIZE 128
|
||||
|
||||
static const char *crypt_annotation = "Proc-Type: 4,ENCRYPTED";
|
||||
|
||||
static unsigned char hex_decode(char digit)
|
||||
{
|
||||
return (digit >= 'A') ? 0xA + (digit - 'A') : (digit - '0');
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||
const char *headerbegin,
|
||||
const char *headerend,
|
||||
const unsigned char *passphrase,
|
||||
FILE * fp, unsigned char **data, unsigned int *datalen)
|
||||
{
|
||||
char line[LINE_SIZE];
|
||||
unsigned char iv[LINE_SIZE];
|
||||
char *b64data = NULL;
|
||||
unsigned int b64datalen = 0;
|
||||
int ret;
|
||||
const LIBSSH2_CRYPT_METHOD *method = NULL;
|
||||
|
||||
do {
|
||||
*line = '\0';
|
||||
|
||||
if(readline(line, LINE_SIZE, fp)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
while(strcmp(line, headerbegin) != 0);
|
||||
|
||||
if(readline(line, LINE_SIZE, fp)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(passphrase &&
|
||||
memcmp(line, crypt_annotation, strlen(crypt_annotation)) == 0) {
|
||||
const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method;
|
||||
int i;
|
||||
|
||||
if(readline(line, LINE_SIZE, fp)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
all_methods = libssh2_crypt_methods();
|
||||
while((cur_method = *all_methods++) != NULL) {
|
||||
if(*cur_method->pem_annotation &&
|
||||
memcmp(line, cur_method->pem_annotation,
|
||||
strlen(cur_method->pem_annotation)) == 0) {
|
||||
method = cur_method;
|
||||
memcpy(iv, line + strlen(method->pem_annotation) + 1,
|
||||
2*method->iv_len);
|
||||
}
|
||||
}
|
||||
|
||||
/* None of the available crypt methods were able to decrypt the key */
|
||||
if(method == NULL)
|
||||
return -1;
|
||||
|
||||
/* Decode IV from hex */
|
||||
for(i = 0; i < method->iv_len; ++i) {
|
||||
iv[i] = hex_decode(iv[2*i]) << 4;
|
||||
iv[i] |= hex_decode(iv[2*i + 1]);
|
||||
}
|
||||
|
||||
/* skip to the next line */
|
||||
if(readline(line, LINE_SIZE, fp)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
if(*line) {
|
||||
char *tmp;
|
||||
size_t linelen;
|
||||
|
||||
linelen = strlen(line);
|
||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||
if(!tmp) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for PEM parsing");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
memcpy(tmp + b64datalen, line, linelen);
|
||||
b64data = tmp;
|
||||
b64datalen += linelen;
|
||||
}
|
||||
|
||||
*line = '\0';
|
||||
|
||||
if(readline(line, LINE_SIZE, fp)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
} while(strcmp(line, headerend) != 0);
|
||||
|
||||
if(!b64data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(libssh2_base64_decode(session, (char **) data, datalen,
|
||||
b64data, b64datalen)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(method) {
|
||||
/* Set up decryption */
|
||||
int free_iv = 0, free_secret = 0, len_decrypted = 0, padding = 0;
|
||||
int blocksize = method->blocksize;
|
||||
void *abstract;
|
||||
unsigned char secret[2*MD5_DIGEST_LENGTH];
|
||||
libssh2_md5_ctx fingerprint_ctx;
|
||||
|
||||
/* Perform key derivation (PBKDF1/MD5) */
|
||||
if(!libssh2_md5_init(&fingerprint_ctx)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
libssh2_md5_update(fingerprint_ctx, passphrase,
|
||||
strlen((char *)passphrase));
|
||||
libssh2_md5_update(fingerprint_ctx, iv, 8);
|
||||
libssh2_md5_final(fingerprint_ctx, secret);
|
||||
if(method->secret_len > MD5_DIGEST_LENGTH) {
|
||||
if(!libssh2_md5_init(&fingerprint_ctx)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
libssh2_md5_update(fingerprint_ctx, secret, MD5_DIGEST_LENGTH);
|
||||
libssh2_md5_update(fingerprint_ctx, passphrase,
|
||||
strlen((char *)passphrase));
|
||||
libssh2_md5_update(fingerprint_ctx, iv, 8);
|
||||
libssh2_md5_final(fingerprint_ctx, secret + MD5_DIGEST_LENGTH);
|
||||
}
|
||||
|
||||
/* Initialize the decryption */
|
||||
if(method->init(session, method, iv, &free_iv, secret,
|
||||
&free_secret, 0, &abstract)) {
|
||||
_libssh2_explicit_zero((char *)secret, sizeof(secret));
|
||||
LIBSSH2_FREE(session, data);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(free_secret) {
|
||||
_libssh2_explicit_zero((char *)secret, sizeof(secret));
|
||||
}
|
||||
|
||||
/* Do the actual decryption */
|
||||
if((*datalen % blocksize) != 0) {
|
||||
_libssh2_explicit_zero((char *)secret, sizeof(secret));
|
||||
method->dtor(session, &abstract);
|
||||
_libssh2_explicit_zero(*data, *datalen);
|
||||
LIBSSH2_FREE(session, *data);
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while(len_decrypted <= (int)*datalen - blocksize) {
|
||||
if(method->crypt(session, *data + len_decrypted, blocksize,
|
||||
&abstract)) {
|
||||
ret = LIBSSH2_ERROR_DECRYPT;
|
||||
_libssh2_explicit_zero((char *)secret, sizeof(secret));
|
||||
method->dtor(session, &abstract);
|
||||
_libssh2_explicit_zero(*data, *datalen);
|
||||
LIBSSH2_FREE(session, *data);
|
||||
goto out;
|
||||
}
|
||||
|
||||
len_decrypted += blocksize;
|
||||
}
|
||||
|
||||
/* Account for padding */
|
||||
padding = (*data)[*datalen - 1];
|
||||
memset(&(*data)[*datalen-padding], 0, padding);
|
||||
*datalen -= padding;
|
||||
|
||||
/* Clean up */
|
||||
_libssh2_explicit_zero((char *)secret, sizeof(secret));
|
||||
method->dtor(session, &abstract);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if(b64data) {
|
||||
_libssh2_explicit_zero(b64data, b64datalen);
|
||||
LIBSSH2_FREE(session, b64data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
|
||||
const char *headerbegin,
|
||||
const char *headerend,
|
||||
const char *filedata, size_t filedata_len,
|
||||
unsigned char **data, unsigned int *datalen)
|
||||
{
|
||||
char line[LINE_SIZE];
|
||||
char *b64data = NULL;
|
||||
unsigned int b64datalen = 0;
|
||||
size_t off = 0;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
*line = '\0';
|
||||
|
||||
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
while(strcmp(line, headerbegin) != 0);
|
||||
|
||||
*line = '\0';
|
||||
|
||||
do {
|
||||
if(*line) {
|
||||
char *tmp;
|
||||
size_t linelen;
|
||||
|
||||
linelen = strlen(line);
|
||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||
if(!tmp) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for PEM parsing");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
memcpy(tmp + b64datalen, line, linelen);
|
||||
b64data = tmp;
|
||||
b64datalen += linelen;
|
||||
}
|
||||
|
||||
*line = '\0';
|
||||
|
||||
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
} while(strcmp(line, headerend) != 0);
|
||||
|
||||
if(!b64data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(libssh2_base64_decode(session, (char **) data, datalen,
|
||||
b64data, b64datalen)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if(b64data) {
|
||||
_libssh2_explicit_zero(b64data, b64datalen);
|
||||
LIBSSH2_FREE(session, b64data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* OpenSSH formatted keys */
|
||||
#define AUTH_MAGIC "openssh-key-v1"
|
||||
#define OPENSSH_HEADER_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----"
|
||||
#define OPENSSH_HEADER_END "-----END OPENSSH PRIVATE KEY-----"
|
||||
|
||||
static int
|
||||
_libssh2_openssh_pem_parse_data(LIBSSH2_SESSION * session,
|
||||
const unsigned char *passphrase,
|
||||
const char *b64data, size_t b64datalen,
|
||||
struct string_buf **decrypted_buf)
|
||||
{
|
||||
const LIBSSH2_CRYPT_METHOD *method = NULL;
|
||||
struct string_buf decoded, decrypted, kdf_buf;
|
||||
unsigned char *ciphername = NULL;
|
||||
unsigned char *kdfname = NULL;
|
||||
unsigned char *kdf = NULL;
|
||||
unsigned char *buf = NULL;
|
||||
unsigned char *salt = NULL;
|
||||
uint32_t nkeys, check1, check2;
|
||||
uint32_t rounds = 0;
|
||||
unsigned char *key = NULL;
|
||||
unsigned char *key_part = NULL;
|
||||
unsigned char *iv_part = NULL;
|
||||
unsigned char *f = NULL;
|
||||
unsigned int f_len = 0;
|
||||
int ret = 0, keylen = 0, ivlen = 0, total_len = 0;
|
||||
size_t kdf_len = 0, tmp_len = 0, salt_len = 0;
|
||||
|
||||
if(decrypted_buf)
|
||||
*decrypted_buf = NULL;
|
||||
|
||||
/* decode file */
|
||||
if(libssh2_base64_decode(session, (char **)&f, &f_len,
|
||||
b64data, b64datalen)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Parse the file */
|
||||
decoded.data = (unsigned char *)f;
|
||||
decoded.dataptr = (unsigned char *)f;
|
||||
decoded.len = f_len;
|
||||
|
||||
if(decoded.len < strlen(AUTH_MAGIC)) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO, "key too short");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(strncmp((char *) decoded.dataptr, AUTH_MAGIC,
|
||||
strlen(AUTH_MAGIC)) != 0) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"key auth magic mismatch");
|
||||
goto out;
|
||||
}
|
||||
|
||||
decoded.dataptr += strlen(AUTH_MAGIC) + 1;
|
||||
|
||||
if(_libssh2_get_string(&decoded, &ciphername, &tmp_len) ||
|
||||
tmp_len == 0) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"ciphername is missing");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(_libssh2_get_string(&decoded, &kdfname, &tmp_len) ||
|
||||
tmp_len == 0) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"kdfname is missing");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(_libssh2_get_string(&decoded, &kdf, &kdf_len)) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"kdf is missing");
|
||||
goto out;
|
||||
}
|
||||
else {
|
||||
kdf_buf.data = kdf;
|
||||
kdf_buf.dataptr = kdf;
|
||||
kdf_buf.len = kdf_len;
|
||||
}
|
||||
|
||||
if((passphrase == NULL || strlen((const char *)passphrase) == 0) &&
|
||||
strcmp((const char *)ciphername, "none") != 0) {
|
||||
/* passphrase required */
|
||||
ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(strcmp((const char *)kdfname, "none") != 0 &&
|
||||
strcmp((const char *)kdfname, "bcrypt") != 0) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"unknown cipher");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(!strcmp((const char *)kdfname, "none") &&
|
||||
strcmp((const char *)ciphername, "none") != 0) {
|
||||
ret =_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"invalid format");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(_libssh2_get_u32(&decoded, &nkeys) != 0 || nkeys != 1) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Multiple keys are unsupported");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* unencrypted public key */
|
||||
|
||||
if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Invalid private key; "
|
||||
"expect embedded public key");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(_libssh2_get_string(&decoded, &buf, &tmp_len) || tmp_len == 0) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Private key data not found");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* decode encrypted private key */
|
||||
decrypted.data = decrypted.dataptr = buf;
|
||||
decrypted.len = tmp_len;
|
||||
|
||||
if(ciphername && strcmp((const char *)ciphername, "none") != 0) {
|
||||
const LIBSSH2_CRYPT_METHOD **all_methods, *cur_method;
|
||||
|
||||
all_methods = libssh2_crypt_methods();
|
||||
while((cur_method = *all_methods++) != NULL) {
|
||||
if(*cur_method->name &&
|
||||
memcmp(ciphername, cur_method->name,
|
||||
strlen(cur_method->name)) == 0) {
|
||||
method = cur_method;
|
||||
}
|
||||
}
|
||||
|
||||
/* None of the available crypt methods were able to decrypt the key */
|
||||
|
||||
if(method == NULL) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"No supported cipher found");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if(method) {
|
||||
int free_iv = 0, free_secret = 0, len_decrypted = 0;
|
||||
int blocksize;
|
||||
void *abstract = NULL;
|
||||
|
||||
keylen = method->secret_len;
|
||||
ivlen = method->iv_len;
|
||||
total_len = keylen + ivlen;
|
||||
|
||||
key = LIBSSH2_CALLOC(session, total_len);
|
||||
if(key == NULL) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Could not alloc key");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(strcmp((const char *)kdfname, "bcrypt") == 0 &&
|
||||
passphrase != NULL) {
|
||||
if((_libssh2_get_string(&kdf_buf, &salt, &salt_len)) ||
|
||||
(_libssh2_get_u32(&kdf_buf, &rounds) != 0) ) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"kdf contains unexpected values");
|
||||
LIBSSH2_FREE(session, key);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(_libssh2_bcrypt_pbkdf((const char *)passphrase,
|
||||
strlen((const char *)passphrase),
|
||||
salt, salt_len, key,
|
||||
keylen + ivlen, rounds) < 0) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_DECRYPT,
|
||||
"invalid format");
|
||||
LIBSSH2_FREE(session, key);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_KEYFILE_AUTH_FAILED,
|
||||
"bcrypted without passphrase");
|
||||
LIBSSH2_FREE(session, key);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Set up decryption */
|
||||
blocksize = method->blocksize;
|
||||
|
||||
key_part = LIBSSH2_CALLOC(session, keylen);
|
||||
if(key_part == NULL) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Could not alloc key part");
|
||||
goto out;
|
||||
}
|
||||
|
||||
iv_part = LIBSSH2_CALLOC(session, ivlen);
|
||||
if(iv_part == NULL) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Could not alloc iv part");
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(key_part, key, keylen);
|
||||
memcpy(iv_part, key + keylen, ivlen);
|
||||
|
||||
/* Initialize the decryption */
|
||||
if(method->init(session, method, iv_part, &free_iv, key_part,
|
||||
&free_secret, 0, &abstract)) {
|
||||
ret = LIBSSH2_ERROR_DECRYPT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Do the actual decryption */
|
||||
if((decrypted.len % blocksize) != 0) {
|
||||
method->dtor(session, &abstract);
|
||||
ret = LIBSSH2_ERROR_DECRYPT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
while((size_t)len_decrypted <= decrypted.len - blocksize) {
|
||||
if(method->crypt(session, decrypted.data + len_decrypted,
|
||||
blocksize,
|
||||
&abstract)) {
|
||||
ret = LIBSSH2_ERROR_DECRYPT;
|
||||
method->dtor(session, &abstract);
|
||||
goto out;
|
||||
}
|
||||
|
||||
len_decrypted += blocksize;
|
||||
}
|
||||
|
||||
/* No padding */
|
||||
|
||||
method->dtor(session, &abstract);
|
||||
}
|
||||
|
||||
/* Check random bytes match */
|
||||
|
||||
if(_libssh2_get_u32(&decrypted, &check1) != 0 ||
|
||||
_libssh2_get_u32(&decrypted, &check2) != 0 ||
|
||||
check1 != check2) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Private key unpack failed (correct password?)");
|
||||
ret = LIBSSH2_ERROR_KEYFILE_AUTH_FAILED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(decrypted_buf != NULL) {
|
||||
/* copy data to out-going buffer */
|
||||
struct string_buf *out_buf = _libssh2_string_buf_new(session);
|
||||
if(!out_buf) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"decrypted struct");
|
||||
goto out;
|
||||
}
|
||||
|
||||
out_buf->data = LIBSSH2_CALLOC(session, decrypted.len);
|
||||
if(out_buf->data == NULL) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"decrypted struct");
|
||||
_libssh2_string_buf_free(session, out_buf);
|
||||
goto out;
|
||||
}
|
||||
memcpy(out_buf->data, decrypted.data, decrypted.len);
|
||||
out_buf->dataptr = out_buf->data +
|
||||
(decrypted.dataptr - decrypted.data);
|
||||
out_buf->len = decrypted.len;
|
||||
|
||||
*decrypted_buf = out_buf;
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
/* Clean up */
|
||||
if(key) {
|
||||
_libssh2_explicit_zero(key, total_len);
|
||||
LIBSSH2_FREE(session, key);
|
||||
}
|
||||
if(key_part) {
|
||||
_libssh2_explicit_zero(key_part, keylen);
|
||||
LIBSSH2_FREE(session, key_part);
|
||||
}
|
||||
if(iv_part) {
|
||||
_libssh2_explicit_zero(iv_part, ivlen);
|
||||
LIBSSH2_FREE(session, iv_part);
|
||||
}
|
||||
if(f) {
|
||||
_libssh2_explicit_zero(f, f_len);
|
||||
LIBSSH2_FREE(session, f);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_openssh_pem_parse(LIBSSH2_SESSION * session,
|
||||
const unsigned char *passphrase,
|
||||
FILE * fp, struct string_buf **decrypted_buf)
|
||||
{
|
||||
char line[LINE_SIZE];
|
||||
char *b64data = NULL;
|
||||
unsigned int b64datalen = 0;
|
||||
int ret = 0;
|
||||
|
||||
/* read file */
|
||||
|
||||
do {
|
||||
*line = '\0';
|
||||
|
||||
if(readline(line, LINE_SIZE, fp)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
|
||||
|
||||
if(readline(line, LINE_SIZE, fp)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
if(*line) {
|
||||
char *tmp;
|
||||
size_t linelen;
|
||||
|
||||
linelen = strlen(line);
|
||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||
if(!tmp) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for PEM parsing");
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
memcpy(tmp + b64datalen, line, linelen);
|
||||
b64data = tmp;
|
||||
b64datalen += linelen;
|
||||
}
|
||||
|
||||
*line = '\0';
|
||||
|
||||
if(readline(line, LINE_SIZE, fp)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
} while(strcmp(line, OPENSSH_HEADER_END) != 0);
|
||||
|
||||
if(!b64data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = _libssh2_openssh_pem_parse_data(session,
|
||||
passphrase,
|
||||
(const char *)b64data,
|
||||
(size_t)b64datalen,
|
||||
decrypted_buf);
|
||||
|
||||
if(b64data) {
|
||||
_libssh2_explicit_zero(b64data, b64datalen);
|
||||
LIBSSH2_FREE(session, b64data);
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_openssh_pem_parse_memory(LIBSSH2_SESSION * session,
|
||||
const unsigned char *passphrase,
|
||||
const char *filedata, size_t filedata_len,
|
||||
struct string_buf **decrypted_buf)
|
||||
{
|
||||
char line[LINE_SIZE];
|
||||
char *b64data = NULL;
|
||||
unsigned int b64datalen = 0;
|
||||
size_t off = 0;
|
||||
int ret;
|
||||
|
||||
if(filedata == NULL || filedata_len <= 0)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Error parsing PEM: filedata missing");
|
||||
|
||||
do {
|
||||
|
||||
*line = '\0';
|
||||
|
||||
if(off >= filedata_len)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Error parsing PEM: offset out of bounds");
|
||||
|
||||
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
while(strcmp(line, OPENSSH_HEADER_BEGIN) != 0);
|
||||
|
||||
*line = '\0';
|
||||
|
||||
do {
|
||||
if (*line) {
|
||||
char *tmp;
|
||||
size_t linelen;
|
||||
|
||||
linelen = strlen(line);
|
||||
tmp = LIBSSH2_REALLOC(session, b64data, b64datalen + linelen);
|
||||
if(!tmp) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"PEM parsing");
|
||||
goto out;
|
||||
}
|
||||
memcpy(tmp + b64datalen, line, linelen);
|
||||
b64data = tmp;
|
||||
b64datalen += linelen;
|
||||
}
|
||||
|
||||
*line = '\0';
|
||||
|
||||
if(off >= filedata_len) {
|
||||
ret = _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Error parsing PEM: offset out of bounds");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
} while(strcmp(line, OPENSSH_HEADER_END) != 0);
|
||||
|
||||
if(!b64data)
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_PROTO,
|
||||
"Error parsing PEM: base 64 data missing");
|
||||
|
||||
ret = _libssh2_openssh_pem_parse_data(session, passphrase, b64data,
|
||||
b64datalen, decrypted_buf);
|
||||
|
||||
out:
|
||||
if(b64data) {
|
||||
_libssh2_explicit_zero(b64data, b64datalen);
|
||||
LIBSSH2_FREE(session, b64data);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
read_asn1_length(const unsigned char *data,
|
||||
unsigned int datalen, unsigned int *len)
|
||||
{
|
||||
unsigned int lenlen;
|
||||
int nextpos;
|
||||
|
||||
if(datalen < 1) {
|
||||
return -1;
|
||||
}
|
||||
*len = data[0];
|
||||
|
||||
if(*len >= 0x80) {
|
||||
lenlen = *len & 0x7F;
|
||||
*len = data[1];
|
||||
if(1 + lenlen > datalen) {
|
||||
return -1;
|
||||
}
|
||||
if(lenlen > 1) {
|
||||
*len <<= 8;
|
||||
*len |= data[2];
|
||||
}
|
||||
}
|
||||
else {
|
||||
lenlen = 0;
|
||||
}
|
||||
|
||||
nextpos = 1 + lenlen;
|
||||
if(lenlen > 2 || 1 + lenlen + *len > datalen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return nextpos;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_pem_decode_sequence(unsigned char **data, unsigned int *datalen)
|
||||
{
|
||||
unsigned int len;
|
||||
int lenlen;
|
||||
|
||||
if(*datalen < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((*data)[0] != '\x30') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*data)++;
|
||||
(*datalen)--;
|
||||
|
||||
lenlen = read_asn1_length(*data, *datalen, &len);
|
||||
if(lenlen < 0 || lenlen + len != *datalen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*data += lenlen;
|
||||
*datalen -= lenlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_pem_decode_integer(unsigned char **data, unsigned int *datalen,
|
||||
unsigned char **i, unsigned int *ilen)
|
||||
{
|
||||
unsigned int len;
|
||||
int lenlen;
|
||||
|
||||
if(*datalen < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((*data)[0] != '\x02') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
(*data)++;
|
||||
(*datalen)--;
|
||||
|
||||
lenlen = read_asn1_length(*data, *datalen, &len);
|
||||
if(lenlen < 0 || lenlen + len > *datalen) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*data += lenlen;
|
||||
*datalen -= lenlen;
|
||||
|
||||
*i = *data;
|
||||
*ilen = len;
|
||||
|
||||
*data += len;
|
||||
*datalen -= len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
1860
lib/libssh2/session.c
Normal file
1860
lib/libssh2/session.c
Normal file
File diff suppressed because it is too large
Load Diff
95
lib/libssh2/session.h
Normal file
95
lib/libssh2/session.h
Normal file
@@ -0,0 +1,95 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_SESSION_H
|
||||
#define __LIBSSH2_SESSION_H
|
||||
/* Copyright (c) 2004-2007 Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009-2010 by Daniel Stenberg
|
||||
* Copyright (c) 2010 Simon Josefsson <simon@josefsson.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Conveniance-macros to allow code like this;
|
||||
|
||||
int rc = BLOCK_ADJUST(rc, session, session_startup(session, sock) );
|
||||
|
||||
int rc = BLOCK_ADJUST_ERRNO(ptr, session, session_startup(session, sock) );
|
||||
|
||||
The point of course being to make sure that while in non-blocking mode
|
||||
these always return no matter what the return code is, but in blocking mode
|
||||
it blocks if EAGAIN is the reason for the return from the underlying
|
||||
function.
|
||||
|
||||
*/
|
||||
#define BLOCK_ADJUST(rc, sess, x) \
|
||||
do { \
|
||||
time_t entry_time = time(NULL); \
|
||||
do { \
|
||||
rc = x; \
|
||||
/* the order of the check below is important to properly deal with \
|
||||
the case when the 'sess' is freed */ \
|
||||
if((rc != LIBSSH2_ERROR_EAGAIN) || !sess->api_block_mode) \
|
||||
break; \
|
||||
rc = _libssh2_wait_socket(sess, entry_time); \
|
||||
} while(!rc); \
|
||||
} while(0)
|
||||
|
||||
/*
|
||||
* For functions that returns a pointer, we need to check if the API is
|
||||
* non-blocking and return immediately. If the pointer is non-NULL we return
|
||||
* immediately. If the API is blocking and we get a NULL we check the errno
|
||||
* and *only* if that is EAGAIN we loop and wait for socket action.
|
||||
*/
|
||||
#define BLOCK_ADJUST_ERRNO(ptr, sess, x) \
|
||||
do { \
|
||||
time_t entry_time = time(NULL); \
|
||||
int rc; \
|
||||
do { \
|
||||
ptr = x; \
|
||||
if(!sess->api_block_mode || \
|
||||
(ptr != NULL) || \
|
||||
(libssh2_session_last_errno(sess) != LIBSSH2_ERROR_EAGAIN) ) \
|
||||
break; \
|
||||
rc = _libssh2_wait_socket(sess, entry_time); \
|
||||
} while(!rc); \
|
||||
} while(0)
|
||||
|
||||
|
||||
int _libssh2_wait_socket(LIBSSH2_SESSION *session, time_t entry_time);
|
||||
|
||||
/* this is the lib-internal set blocking function */
|
||||
int _libssh2_session_set_blocking(LIBSSH2_SESSION * session, int blocking);
|
||||
|
||||
#endif /* __LIBSSH2_SESSION_H */
|
||||
#endif
|
||||
240
lib/libssh2/sftp.h
Normal file
240
lib/libssh2/sftp.h
Normal file
@@ -0,0 +1,240 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_SFTP_H
|
||||
#define __LIBSSH2_SFTP_H
|
||||
/*
|
||||
* Copyright (C) 2010 - 2012 by Daniel Stenberg
|
||||
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* MAX_SFTP_OUTGOING_SIZE MUST not be larger than 32500 or so. This is the
|
||||
* amount of data sent in each FXP_WRITE packet
|
||||
*/
|
||||
#define MAX_SFTP_OUTGOING_SIZE 30000
|
||||
|
||||
/* MAX_SFTP_READ_SIZE is how much data is asked for at max in each FXP_READ
|
||||
* packets.
|
||||
*/
|
||||
#define MAX_SFTP_READ_SIZE 30000
|
||||
|
||||
struct sftp_pipeline_chunk {
|
||||
struct list_node node;
|
||||
libssh2_uint64_t offset; /* READ: offset at which to start reading
|
||||
WRITE: not used */
|
||||
size_t len; /* WRITE: size of the data to write
|
||||
READ: how many bytes that was asked for */
|
||||
size_t sent;
|
||||
ssize_t lefttosend; /* if 0, the entire packet has been sent off */
|
||||
uint32_t request_id;
|
||||
unsigned char packet[1]; /* data */
|
||||
};
|
||||
|
||||
struct sftp_zombie_requests {
|
||||
struct list_node node;
|
||||
uint32_t request_id;
|
||||
};
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(x,y) ((x)<(y)?(x):(y))
|
||||
#endif
|
||||
|
||||
struct _LIBSSH2_SFTP_PACKET
|
||||
{
|
||||
struct list_node node; /* linked list header */
|
||||
uint32_t request_id;
|
||||
unsigned char *data;
|
||||
size_t data_len; /* payload size */
|
||||
};
|
||||
|
||||
typedef struct _LIBSSH2_SFTP_PACKET LIBSSH2_SFTP_PACKET;
|
||||
|
||||
#define SFTP_HANDLE_MAXLEN 256 /* according to spec! */
|
||||
|
||||
struct _LIBSSH2_SFTP_HANDLE
|
||||
{
|
||||
struct list_node node;
|
||||
|
||||
LIBSSH2_SFTP *sftp;
|
||||
|
||||
char handle[SFTP_HANDLE_MAXLEN];
|
||||
size_t handle_len;
|
||||
|
||||
enum {
|
||||
LIBSSH2_SFTP_HANDLE_FILE,
|
||||
LIBSSH2_SFTP_HANDLE_DIR
|
||||
} handle_type;
|
||||
|
||||
union _libssh2_sftp_handle_data
|
||||
{
|
||||
struct _libssh2_sftp_handle_file_data
|
||||
{
|
||||
libssh2_uint64_t offset;
|
||||
libssh2_uint64_t offset_sent;
|
||||
size_t acked; /* container for acked data that hasn't been
|
||||
returned to caller yet, used for sftp_write */
|
||||
|
||||
/* 'data' is used by sftp_read() and is allocated data that has
|
||||
been received already from the server but wasn't returned to
|
||||
the caller yet. It is of size 'data_len' and 'data_left is the
|
||||
number of bytes not yet returned, counted from the end of the
|
||||
buffer. */
|
||||
unsigned char *data;
|
||||
size_t data_len;
|
||||
size_t data_left;
|
||||
|
||||
char eof; /* we have read to the end */
|
||||
} file;
|
||||
struct _libssh2_sftp_handle_dir_data
|
||||
{
|
||||
uint32_t names_left;
|
||||
void *names_packet;
|
||||
char *next_name;
|
||||
size_t names_packet_len;
|
||||
} dir;
|
||||
} u;
|
||||
|
||||
/* State variables used in libssh2_sftp_close_handle() */
|
||||
libssh2_nonblocking_states close_state;
|
||||
uint32_t close_request_id;
|
||||
unsigned char *close_packet;
|
||||
|
||||
/* list of outstanding packets sent to server */
|
||||
struct list_head packet_list;
|
||||
|
||||
};
|
||||
|
||||
struct _LIBSSH2_SFTP
|
||||
{
|
||||
LIBSSH2_CHANNEL *channel;
|
||||
|
||||
uint32_t request_id, version;
|
||||
|
||||
struct list_head packets;
|
||||
|
||||
/* List of FXP_READ responses to ignore because EOF already received. */
|
||||
struct list_head zombie_requests;
|
||||
|
||||
/* a list of _LIBSSH2_SFTP_HANDLE structs */
|
||||
struct list_head sftp_handles;
|
||||
|
||||
uint32_t last_errno;
|
||||
|
||||
/* Holder for partial packet, use in libssh2_sftp_packet_read() */
|
||||
unsigned char partial_size[4]; /* buffer for size field */
|
||||
size_t partial_size_len; /* size field length */
|
||||
unsigned char *partial_packet; /* The data */
|
||||
uint32_t partial_len; /* Desired number of bytes */
|
||||
size_t partial_received; /* Bytes received so far */
|
||||
|
||||
/* Time that libssh2_sftp_packet_requirev() started reading */
|
||||
time_t requirev_start;
|
||||
|
||||
/* State variables used in libssh2_sftp_open_ex() */
|
||||
libssh2_nonblocking_states open_state;
|
||||
unsigned char *open_packet;
|
||||
uint32_t open_packet_len; /* 32 bit on the wire */
|
||||
size_t open_packet_sent;
|
||||
uint32_t open_request_id;
|
||||
|
||||
/* State variable used in sftp_read() */
|
||||
libssh2_nonblocking_states read_state;
|
||||
|
||||
/* State variable used in sftp_packet_read() */
|
||||
libssh2_nonblocking_states packet_state;
|
||||
|
||||
/* State variable used in sftp_write() */
|
||||
libssh2_nonblocking_states write_state;
|
||||
|
||||
/* State variables used in sftp_fsync() */
|
||||
libssh2_nonblocking_states fsync_state;
|
||||
unsigned char *fsync_packet;
|
||||
uint32_t fsync_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_readdir() */
|
||||
libssh2_nonblocking_states readdir_state;
|
||||
unsigned char *readdir_packet;
|
||||
uint32_t readdir_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_fstat_ex() */
|
||||
libssh2_nonblocking_states fstat_state;
|
||||
unsigned char *fstat_packet;
|
||||
uint32_t fstat_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_unlink_ex() */
|
||||
libssh2_nonblocking_states unlink_state;
|
||||
unsigned char *unlink_packet;
|
||||
uint32_t unlink_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_rename_ex() */
|
||||
libssh2_nonblocking_states rename_state;
|
||||
unsigned char *rename_packet;
|
||||
unsigned char *rename_s;
|
||||
uint32_t rename_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_fstatvfs() */
|
||||
libssh2_nonblocking_states fstatvfs_state;
|
||||
unsigned char *fstatvfs_packet;
|
||||
uint32_t fstatvfs_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_statvfs() */
|
||||
libssh2_nonblocking_states statvfs_state;
|
||||
unsigned char *statvfs_packet;
|
||||
uint32_t statvfs_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_mkdir() */
|
||||
libssh2_nonblocking_states mkdir_state;
|
||||
unsigned char *mkdir_packet;
|
||||
uint32_t mkdir_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_rmdir() */
|
||||
libssh2_nonblocking_states rmdir_state;
|
||||
unsigned char *rmdir_packet;
|
||||
uint32_t rmdir_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_stat() */
|
||||
libssh2_nonblocking_states stat_state;
|
||||
unsigned char *stat_packet;
|
||||
uint32_t stat_request_id;
|
||||
|
||||
/* State variables used in libssh2_sftp_symlink() */
|
||||
libssh2_nonblocking_states symlink_state;
|
||||
unsigned char *symlink_packet;
|
||||
uint32_t symlink_request_id;
|
||||
};
|
||||
|
||||
#endif /* __LIBSSH2_SFTP_H */
|
||||
#endif
|
||||
933
lib/libssh2/transport.c
Normal file
933
lib/libssh2/transport.c
Normal file
@@ -0,0 +1,933 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file handles reading and writing to the SECSH transport layer. RFC4253.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#ifdef LIBSSH2DEBUG
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "transport.h"
|
||||
#include "mac.h"
|
||||
|
||||
#define MAX_BLOCKSIZE 32 /* MUST fit biggest crypto block size we use/get */
|
||||
#define MAX_MACSIZE 64 /* MUST fit biggest MAC length we support */
|
||||
|
||||
#ifdef LIBSSH2DEBUG
|
||||
#define UNPRINTABLE_CHAR '.'
|
||||
static void
|
||||
debugdump(LIBSSH2_SESSION * session,
|
||||
const char *desc, const unsigned char *ptr, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
size_t c;
|
||||
unsigned int width = 0x10;
|
||||
char buffer[256]; /* Must be enough for width*4 + about 30 or so */
|
||||
size_t used;
|
||||
static const char *hex_chars = "0123456789ABCDEF";
|
||||
|
||||
if(!(session->showmask & LIBSSH2_TRACE_TRANS)) {
|
||||
/* not asked for, bail out */
|
||||
return;
|
||||
}
|
||||
|
||||
used = snprintf(buffer, sizeof(buffer), "=> %s (%d bytes)\n",
|
||||
desc, (int) size);
|
||||
if(session->tracehandler)
|
||||
(session->tracehandler)(session, session->tracehandler_context,
|
||||
buffer, used);
|
||||
else
|
||||
fprintf(stderr, "%s", buffer);
|
||||
|
||||
for(i = 0; i < size; i += width) {
|
||||
|
||||
used = snprintf(buffer, sizeof(buffer), "%04lx: ", (long)i);
|
||||
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++) {
|
||||
if(i + c < size) {
|
||||
buffer[used++] = hex_chars[(ptr[i + c] >> 4) & 0xF];
|
||||
buffer[used++] = hex_chars[ptr[i + c] & 0xF];
|
||||
}
|
||||
else {
|
||||
buffer[used++] = ' ';
|
||||
buffer[used++] = ' ';
|
||||
}
|
||||
|
||||
buffer[used++] = ' ';
|
||||
if((width/2) - 1 == c)
|
||||
buffer[used++] = ' ';
|
||||
}
|
||||
|
||||
buffer[used++] = ':';
|
||||
buffer[used++] = ' ';
|
||||
|
||||
for(c = 0; (c < width) && (i + c < size); c++) {
|
||||
buffer[used++] = isprint(ptr[i + c]) ?
|
||||
ptr[i + c] : UNPRINTABLE_CHAR;
|
||||
}
|
||||
buffer[used++] = '\n';
|
||||
buffer[used] = 0;
|
||||
|
||||
if(session->tracehandler)
|
||||
(session->tracehandler)(session, session->tracehandler_context,
|
||||
buffer, used);
|
||||
else
|
||||
fprintf(stderr, "%s", buffer);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define debugdump(a,x,y,z) do {} while(0)
|
||||
#endif
|
||||
|
||||
|
||||
/* decrypt() decrypts 'len' bytes from 'source' to 'dest' in units of
|
||||
* blocksize.
|
||||
*
|
||||
* returns 0 on success and negative on failure
|
||||
*/
|
||||
|
||||
static int
|
||||
decrypt(LIBSSH2_SESSION * session, unsigned char *source,
|
||||
unsigned char *dest, int len)
|
||||
{
|
||||
struct transportpacket *p = &session->packet;
|
||||
int blocksize = session->remote.crypt->blocksize;
|
||||
|
||||
/* if we get called with a len that isn't an even number of blocksizes
|
||||
we risk losing those extra bytes */
|
||||
assert((len % blocksize) == 0);
|
||||
|
||||
while(len >= blocksize) {
|
||||
if(session->remote.crypt->crypt(session, source, blocksize,
|
||||
&session->remote.crypt_abstract)) {
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
return LIBSSH2_ERROR_DECRYPT;
|
||||
}
|
||||
|
||||
/* if the crypt() function would write to a given address it
|
||||
wouldn't have to memcpy() and we could avoid this memcpy()
|
||||
too */
|
||||
memcpy(dest, source, blocksize);
|
||||
|
||||
len -= blocksize; /* less bytes left */
|
||||
dest += blocksize; /* advance write pointer */
|
||||
source += blocksize; /* advance read pointer */
|
||||
}
|
||||
return LIBSSH2_ERROR_NONE; /* all is fine */
|
||||
}
|
||||
|
||||
/*
|
||||
* fullpacket() gets called when a full packet has been received and properly
|
||||
* collected.
|
||||
*/
|
||||
static int
|
||||
fullpacket(LIBSSH2_SESSION * session, int encrypted /* 1 or 0 */ )
|
||||
{
|
||||
unsigned char macbuf[MAX_MACSIZE];
|
||||
struct transportpacket *p = &session->packet;
|
||||
int rc;
|
||||
int compressed;
|
||||
|
||||
if(session->fullpacket_state == libssh2_NB_state_idle) {
|
||||
session->fullpacket_macstate = LIBSSH2_MAC_CONFIRMED;
|
||||
session->fullpacket_payload_len = p->packet_length - 1;
|
||||
|
||||
if(encrypted) {
|
||||
|
||||
/* Calculate MAC hash */
|
||||
session->remote.mac->hash(session, macbuf, /* store hash here */
|
||||
session->remote.seqno,
|
||||
p->init, 5,
|
||||
p->payload,
|
||||
session->fullpacket_payload_len,
|
||||
&session->remote.mac_abstract);
|
||||
|
||||
/* Compare the calculated hash with the MAC we just read from
|
||||
* the network. The read one is at the very end of the payload
|
||||
* buffer. Note that 'payload_len' here is the packet_length
|
||||
* field which includes the padding but not the MAC.
|
||||
*/
|
||||
if(memcmp(macbuf, p->payload + session->fullpacket_payload_len,
|
||||
session->remote.mac->mac_len)) {
|
||||
session->fullpacket_macstate = LIBSSH2_MAC_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
session->remote.seqno++;
|
||||
|
||||
/* ignore the padding */
|
||||
session->fullpacket_payload_len -= p->padding_length;
|
||||
|
||||
/* Check for and deal with decompression */
|
||||
compressed =
|
||||
session->local.comp != NULL &&
|
||||
session->local.comp->compress &&
|
||||
((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
|
||||
session->local.comp->use_in_auth);
|
||||
|
||||
if(compressed && session->remote.comp_abstract) {
|
||||
/*
|
||||
* The buffer for the decompression (remote.comp_abstract) is
|
||||
* initialised in time when it is needed so as long it is NULL we
|
||||
* cannot decompress.
|
||||
*/
|
||||
|
||||
unsigned char *data;
|
||||
size_t data_len;
|
||||
rc = session->remote.comp->decomp(session,
|
||||
&data, &data_len,
|
||||
LIBSSH2_PACKET_MAXDECOMP,
|
||||
p->payload,
|
||||
session->fullpacket_payload_len,
|
||||
&session->remote.comp_abstract);
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
p->payload = data;
|
||||
session->fullpacket_payload_len = data_len;
|
||||
}
|
||||
|
||||
session->fullpacket_packet_type = p->payload[0];
|
||||
|
||||
debugdump(session, "libssh2_transport_read() plain",
|
||||
p->payload, session->fullpacket_payload_len);
|
||||
|
||||
session->fullpacket_state = libssh2_NB_state_created;
|
||||
}
|
||||
|
||||
if(session->fullpacket_state == libssh2_NB_state_created) {
|
||||
rc = _libssh2_packet_add(session, p->payload,
|
||||
session->fullpacket_payload_len,
|
||||
session->fullpacket_macstate);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN)
|
||||
return rc;
|
||||
if(rc) {
|
||||
session->fullpacket_state = libssh2_NB_state_idle;
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
session->fullpacket_state = libssh2_NB_state_idle;
|
||||
|
||||
return session->fullpacket_packet_type;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* _libssh2_transport_read
|
||||
*
|
||||
* Collect a packet into the input queue.
|
||||
*
|
||||
* Returns packet type added to input queue (0 if nothing added), or a
|
||||
* negative error number.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||
*
|
||||
* DOES NOT call _libssh2_error() for ANY error case.
|
||||
*/
|
||||
int _libssh2_transport_read(LIBSSH2_SESSION * session)
|
||||
{
|
||||
int rc;
|
||||
struct transportpacket *p = &session->packet;
|
||||
int remainpack; /* how much there is left to add to the current payload
|
||||
package */
|
||||
int remainbuf; /* how much data there is remaining in the buffer to deal
|
||||
with before we should read more from the network */
|
||||
int numbytes; /* how much data to deal with from the buffer on this
|
||||
iteration through the loop */
|
||||
int numdecrypt; /* number of bytes to decrypt this iteration */
|
||||
unsigned char block[MAX_BLOCKSIZE]; /* working block buffer */
|
||||
int blocksize; /* minimum number of bytes we need before we can
|
||||
use them */
|
||||
int encrypted = 1; /* whether the packet is encrypted or not */
|
||||
|
||||
/* default clear the bit */
|
||||
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||
|
||||
/*
|
||||
* All channels, systems, subsystems, etc eventually make it down here
|
||||
* when looking for more incoming data. If a key exchange is going on
|
||||
* (LIBSSH2_STATE_EXCHANGING_KEYS bit is set) then the remote end will
|
||||
* ONLY send key exchange related traffic. In non-blocking mode, there is
|
||||
* a chance to break out of the kex_exchange function with an EAGAIN
|
||||
* status, and never come back to it. If LIBSSH2_STATE_EXCHANGING_KEYS is
|
||||
* active, then we must redirect to the key exchange. However, if
|
||||
* kex_exchange is active (as in it is the one that calls this execution
|
||||
* of packet_read, then don't redirect, as that would be an infinite loop!
|
||||
*/
|
||||
|
||||
if(session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
|
||||
!(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
|
||||
|
||||
/* Whoever wants a packet won't get anything until the key re-exchange
|
||||
* is done!
|
||||
*/
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
|
||||
" key re-exchange from _libssh2_transport_read");
|
||||
rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||
if(rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* =============================== NOTE ===============================
|
||||
* I know this is very ugly and not a really good use of "goto", but
|
||||
* this case statement would be even uglier to do it any other way
|
||||
*/
|
||||
if(session->readPack_state == libssh2_NB_state_jump1) {
|
||||
session->readPack_state = libssh2_NB_state_idle;
|
||||
encrypted = session->readPack_encrypted;
|
||||
goto libssh2_transport_read_point1;
|
||||
}
|
||||
|
||||
do {
|
||||
if(session->socket_state == LIBSSH2_SOCKET_DISCONNECTED) {
|
||||
return LIBSSH2_ERROR_SOCKET_DISCONNECT;
|
||||
}
|
||||
|
||||
if(session->state & LIBSSH2_STATE_NEWKEYS) {
|
||||
blocksize = session->remote.crypt->blocksize;
|
||||
}
|
||||
else {
|
||||
encrypted = 0; /* not encrypted */
|
||||
blocksize = 5; /* not strictly true, but we can use 5 here to
|
||||
make the checks below work fine still */
|
||||
}
|
||||
|
||||
/* read/use a whole big chunk into a temporary area stored in
|
||||
the LIBSSH2_SESSION struct. We will decrypt data from that
|
||||
buffer into the packet buffer so this temp one doesn't have
|
||||
to be able to keep a whole SSH packet, just be large enough
|
||||
so that we can read big chunks from the network layer. */
|
||||
|
||||
/* how much data there is remaining in the buffer to deal with
|
||||
before we should read more from the network */
|
||||
remainbuf = p->writeidx - p->readidx;
|
||||
|
||||
/* if remainbuf turns negative we have a bad internal error */
|
||||
assert(remainbuf >= 0);
|
||||
|
||||
if(remainbuf < blocksize) {
|
||||
/* If we have less than a blocksize left, it is too
|
||||
little data to deal with, read more */
|
||||
ssize_t nread;
|
||||
|
||||
/* move any remainder to the start of the buffer so
|
||||
that we can do a full refill */
|
||||
if(remainbuf) {
|
||||
memmove(p->buf, &p->buf[p->readidx], remainbuf);
|
||||
p->readidx = 0;
|
||||
p->writeidx = remainbuf;
|
||||
}
|
||||
else {
|
||||
/* nothing to move, just zero the indexes */
|
||||
p->readidx = p->writeidx = 0;
|
||||
}
|
||||
|
||||
/* now read a big chunk from the network into the temp buffer */
|
||||
nread =
|
||||
LIBSSH2_RECV(session, &p->buf[remainbuf],
|
||||
PACKETBUFSIZE - remainbuf,
|
||||
LIBSSH2_SOCKET_RECV_FLAGS(session));
|
||||
if(nread <= 0) {
|
||||
/* check if this is due to EAGAIN and return the special
|
||||
return code if so, error out normally otherwise */
|
||||
if((nread < 0) && (nread == -EAGAIN)) {
|
||||
session->socket_block_directions |=
|
||||
LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||
"Error recving %d bytes (got %d)",
|
||||
PACKETBUFSIZE - remainbuf, -nread);
|
||||
return LIBSSH2_ERROR_SOCKET_RECV;
|
||||
}
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||
"Recved %d/%d bytes to %p+%d", nread,
|
||||
PACKETBUFSIZE - remainbuf, p->buf, remainbuf);
|
||||
|
||||
debugdump(session, "libssh2_transport_read() raw",
|
||||
&p->buf[remainbuf], nread);
|
||||
/* advance write pointer */
|
||||
p->writeidx += nread;
|
||||
|
||||
/* update remainbuf counter */
|
||||
remainbuf = p->writeidx - p->readidx;
|
||||
}
|
||||
|
||||
/* how much data to deal with from the buffer */
|
||||
numbytes = remainbuf;
|
||||
|
||||
if(!p->total_num) {
|
||||
size_t total_num; /* the number of bytes following the initial
|
||||
(5 bytes) packet length and padding length
|
||||
fields */
|
||||
|
||||
/* No payload package area allocated yet. To know the
|
||||
size of this payload, we need to decrypt the first
|
||||
blocksize data. */
|
||||
|
||||
if(numbytes < blocksize) {
|
||||
/* we can't act on anything less than blocksize, but this
|
||||
check is only done for the initial block since once we have
|
||||
got the start of a block we can in fact deal with fractions
|
||||
*/
|
||||
session->socket_block_directions |=
|
||||
LIBSSH2_SESSION_BLOCK_INBOUND;
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
|
||||
if(encrypted) {
|
||||
rc = decrypt(session, &p->buf[p->readidx], block, blocksize);
|
||||
if(rc != LIBSSH2_ERROR_NONE) {
|
||||
return rc;
|
||||
}
|
||||
/* save the first 5 bytes of the decrypted package, to be
|
||||
used in the hash calculation later down. */
|
||||
memcpy(p->init, block, 5);
|
||||
}
|
||||
else {
|
||||
/* the data is plain, just copy it verbatim to
|
||||
the working block buffer */
|
||||
memcpy(block, &p->buf[p->readidx], blocksize);
|
||||
}
|
||||
|
||||
/* advance the read pointer */
|
||||
p->readidx += blocksize;
|
||||
|
||||
/* we now have the initial blocksize bytes decrypted,
|
||||
* and we can extract packet and padding length from it
|
||||
*/
|
||||
p->packet_length = _libssh2_ntohu32(block);
|
||||
if(p->packet_length < 1) {
|
||||
return LIBSSH2_ERROR_DECRYPT;
|
||||
}
|
||||
else if(p->packet_length > LIBSSH2_PACKET_MAXPAYLOAD) {
|
||||
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
|
||||
}
|
||||
|
||||
p->padding_length = block[4];
|
||||
if(p->padding_length > p->packet_length - 1) {
|
||||
return LIBSSH2_ERROR_DECRYPT;
|
||||
}
|
||||
|
||||
|
||||
/* total_num is the number of bytes following the initial
|
||||
(5 bytes) packet length and padding length fields */
|
||||
total_num =
|
||||
p->packet_length - 1 +
|
||||
(encrypted ? session->remote.mac->mac_len : 0);
|
||||
|
||||
/* RFC4253 section 6.1 Maximum Packet Length says:
|
||||
*
|
||||
* "All implementations MUST be able to process
|
||||
* packets with uncompressed payload length of 32768
|
||||
* bytes or less and total packet size of 35000 bytes
|
||||
* or less (including length, padding length, payload,
|
||||
* padding, and MAC.)."
|
||||
*/
|
||||
if(total_num > LIBSSH2_PACKET_MAXPAYLOAD || total_num == 0) {
|
||||
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
|
||||
}
|
||||
|
||||
/* Get a packet handle put data into. We get one to
|
||||
hold all data, including padding and MAC. */
|
||||
p->payload = LIBSSH2_ALLOC(session, total_num);
|
||||
if(!p->payload) {
|
||||
return LIBSSH2_ERROR_ALLOC;
|
||||
}
|
||||
p->total_num = total_num;
|
||||
/* init write pointer to start of payload buffer */
|
||||
p->wptr = p->payload;
|
||||
|
||||
if(blocksize > 5) {
|
||||
/* copy the data from index 5 to the end of
|
||||
the blocksize from the temporary buffer to
|
||||
the start of the decrypted buffer */
|
||||
if(blocksize - 5 <= (int) total_num) {
|
||||
memcpy(p->wptr, &block[5], blocksize - 5);
|
||||
p->wptr += blocksize - 5; /* advance write pointer */
|
||||
}
|
||||
else {
|
||||
if(p->payload)
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
|
||||
}
|
||||
}
|
||||
|
||||
/* init the data_num field to the number of bytes of
|
||||
the package read so far */
|
||||
p->data_num = p->wptr - p->payload;
|
||||
|
||||
/* we already dealt with a blocksize worth of data */
|
||||
numbytes -= blocksize;
|
||||
}
|
||||
|
||||
/* how much there is left to add to the current payload
|
||||
package */
|
||||
remainpack = p->total_num - p->data_num;
|
||||
|
||||
if(numbytes > remainpack) {
|
||||
/* if we have more data in the buffer than what is going into this
|
||||
particular packet, we limit this round to this packet only */
|
||||
numbytes = remainpack;
|
||||
}
|
||||
|
||||
if(encrypted) {
|
||||
/* At the end of the incoming stream, there is a MAC,
|
||||
and we don't want to decrypt that since we need it
|
||||
"raw". We MUST however decrypt the padding data
|
||||
since it is used for the hash later on. */
|
||||
int skip = session->remote.mac->mac_len;
|
||||
|
||||
/* if what we have plus numbytes is bigger than the
|
||||
total minus the skip margin, we should lower the
|
||||
amount to decrypt even more */
|
||||
if((p->data_num + numbytes) > (p->total_num - skip)) {
|
||||
numdecrypt = (p->total_num - skip) - p->data_num;
|
||||
}
|
||||
else {
|
||||
int frac;
|
||||
numdecrypt = numbytes;
|
||||
frac = numdecrypt % blocksize;
|
||||
if(frac) {
|
||||
/* not an aligned amount of blocks,
|
||||
align it */
|
||||
numdecrypt -= frac;
|
||||
/* and make it no unencrypted data
|
||||
after it */
|
||||
numbytes = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* unencrypted data should not be decrypted at all */
|
||||
numdecrypt = 0;
|
||||
}
|
||||
|
||||
/* if there are bytes to decrypt, do that */
|
||||
if(numdecrypt > 0) {
|
||||
/* now decrypt the lot */
|
||||
rc = decrypt(session, &p->buf[p->readidx], p->wptr, numdecrypt);
|
||||
if(rc != LIBSSH2_ERROR_NONE) {
|
||||
p->total_num = 0; /* no packet buffer available */
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* advance the read pointer */
|
||||
p->readidx += numdecrypt;
|
||||
/* advance write pointer */
|
||||
p->wptr += numdecrypt;
|
||||
/* increase data_num */
|
||||
p->data_num += numdecrypt;
|
||||
|
||||
/* bytes left to take care of without decryption */
|
||||
numbytes -= numdecrypt;
|
||||
}
|
||||
|
||||
/* if there are bytes to copy that aren't decrypted, simply
|
||||
copy them as-is to the target buffer */
|
||||
if(numbytes > 0) {
|
||||
|
||||
if(numbytes <= (int)(p->total_num - (p->wptr - p->payload))) {
|
||||
memcpy(p->wptr, &p->buf[p->readidx], numbytes);
|
||||
}
|
||||
else {
|
||||
if(p->payload)
|
||||
LIBSSH2_FREE(session, p->payload);
|
||||
return LIBSSH2_ERROR_OUT_OF_BOUNDARY;
|
||||
}
|
||||
|
||||
/* advance the read pointer */
|
||||
p->readidx += numbytes;
|
||||
/* advance write pointer */
|
||||
p->wptr += numbytes;
|
||||
/* increase data_num */
|
||||
p->data_num += numbytes;
|
||||
}
|
||||
|
||||
/* now check how much data there's left to read to finish the
|
||||
current packet */
|
||||
remainpack = p->total_num - p->data_num;
|
||||
|
||||
if(!remainpack) {
|
||||
/* we have a full packet */
|
||||
libssh2_transport_read_point1:
|
||||
rc = fullpacket(session, encrypted);
|
||||
if(rc == LIBSSH2_ERROR_EAGAIN) {
|
||||
|
||||
if(session->packAdd_state != libssh2_NB_state_idle) {
|
||||
/* fullpacket only returns LIBSSH2_ERROR_EAGAIN if
|
||||
* libssh2_packet_add returns LIBSSH2_ERROR_EAGAIN. If
|
||||
* that returns LIBSSH2_ERROR_EAGAIN but the packAdd_state
|
||||
* is idle, then the packet has been added to the brigade,
|
||||
* but some immediate action that was taken based on the
|
||||
* packet type (such as key re-exchange) is not yet
|
||||
* complete. Clear the way for a new packet to be read
|
||||
* in.
|
||||
*/
|
||||
session->readPack_encrypted = encrypted;
|
||||
session->readPack_state = libssh2_NB_state_jump1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
p->total_num = 0; /* no packet buffer available */
|
||||
|
||||
return rc;
|
||||
}
|
||||
} while(1); /* loop */
|
||||
|
||||
return LIBSSH2_ERROR_SOCKET_RECV; /* we never reach this point */
|
||||
}
|
||||
|
||||
static int
|
||||
send_existing(LIBSSH2_SESSION *session, const unsigned char *data,
|
||||
size_t data_len, ssize_t *ret)
|
||||
{
|
||||
ssize_t rc;
|
||||
ssize_t length;
|
||||
struct transportpacket *p = &session->packet;
|
||||
|
||||
if(!p->olen) {
|
||||
*ret = 0;
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
/* send as much as possible of the existing packet */
|
||||
if((data != p->odata) || (data_len != p->olen)) {
|
||||
/* When we are about to complete the sending of a packet, it is vital
|
||||
that the caller doesn't try to send a new/different packet since
|
||||
we don't add this one up until the previous one has been sent. To
|
||||
make the caller really notice his/hers flaw, we return error for
|
||||
this case */
|
||||
return LIBSSH2_ERROR_BAD_USE;
|
||||
}
|
||||
|
||||
*ret = 1; /* set to make our parent return */
|
||||
|
||||
/* number of bytes left to send */
|
||||
length = p->ototal_num - p->osent;
|
||||
|
||||
rc = LIBSSH2_SEND(session, &p->outbuf[p->osent], length,
|
||||
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||
if(rc < 0)
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||
"Error sending %d bytes: %d", length, -rc);
|
||||
else {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||
"Sent %d/%d bytes at %p+%d", rc, length, p->outbuf,
|
||||
p->osent);
|
||||
debugdump(session, "libssh2_transport_write send()",
|
||||
&p->outbuf[p->osent], rc);
|
||||
}
|
||||
|
||||
if(rc == length) {
|
||||
/* the remainder of the package was sent */
|
||||
p->ototal_num = 0;
|
||||
p->olen = 0;
|
||||
/* we leave *ret set so that the parent returns as we MUST return back
|
||||
a send success now, so that we don't risk sending EAGAIN later
|
||||
which then would confuse the parent function */
|
||||
return LIBSSH2_ERROR_NONE;
|
||||
|
||||
}
|
||||
else if(rc < 0) {
|
||||
/* nothing was sent */
|
||||
if(rc != -EAGAIN)
|
||||
/* send failure! */
|
||||
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||
|
||||
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
|
||||
p->osent += rc; /* we sent away this much data */
|
||||
|
||||
return rc < length ? LIBSSH2_ERROR_EAGAIN : LIBSSH2_ERROR_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* libssh2_transport_send
|
||||
*
|
||||
* Send a packet, encrypting it and adding a MAC code if necessary
|
||||
* Returns 0 on success, non-zero on failure.
|
||||
*
|
||||
* The data is provided as _two_ data areas that are combined by this
|
||||
* function. The 'data' part is sent immediately before 'data2'. 'data2' may
|
||||
* be set to NULL to only use a single part.
|
||||
*
|
||||
* Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was
|
||||
* not sent yet. If it does so, the caller should call this function again as
|
||||
* soon as it is likely that more data can be sent, and this function MUST
|
||||
* then be called with the same argument set (same data pointer and same
|
||||
* data_len) until ERROR_NONE or failure is returned.
|
||||
*
|
||||
* This function DOES NOT call _libssh2_error() on any errors.
|
||||
*/
|
||||
int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
const unsigned char *data, size_t data_len,
|
||||
const unsigned char *data2, size_t data2_len)
|
||||
{
|
||||
int blocksize =
|
||||
(session->state & LIBSSH2_STATE_NEWKEYS) ?
|
||||
session->local.crypt->blocksize : 8;
|
||||
int padding_length;
|
||||
size_t packet_length;
|
||||
int total_length;
|
||||
#ifdef RANDOM_PADDING
|
||||
int rand_max;
|
||||
int seed = data[0]; /* FIXME: make this random */
|
||||
#endif
|
||||
struct transportpacket *p = &session->packet;
|
||||
int encrypted;
|
||||
int compressed;
|
||||
ssize_t ret;
|
||||
int rc;
|
||||
const unsigned char *orgdata = data;
|
||||
size_t orgdata_len = data_len;
|
||||
|
||||
/*
|
||||
* If the last read operation was interrupted in the middle of a key
|
||||
* exchange, we must complete that key exchange before continuing to write
|
||||
* further data.
|
||||
*
|
||||
* See the similar block in _libssh2_transport_read for more details.
|
||||
*/
|
||||
if(session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
|
||||
!(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
|
||||
/* Don't write any new packets if we're still in the middle of a key
|
||||
* exchange. */
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
|
||||
" key re-exchange from _libssh2_transport_send");
|
||||
rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
|
||||
if(rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
debugdump(session, "libssh2_transport_write plain", data, data_len);
|
||||
if(data2)
|
||||
debugdump(session, "libssh2_transport_write plain2", data2, data2_len);
|
||||
|
||||
/* FIRST, check if we have a pending write to complete. send_existing
|
||||
only sanity-check data and data_len and not data2 and data2_len!! */
|
||||
rc = send_existing(session, data, data_len, &ret);
|
||||
if(rc)
|
||||
return rc;
|
||||
|
||||
session->socket_block_directions &= ~LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
|
||||
if(ret)
|
||||
/* set by send_existing if data was sent */
|
||||
return rc;
|
||||
|
||||
encrypted = (session->state & LIBSSH2_STATE_NEWKEYS) ? 1 : 0;
|
||||
|
||||
compressed =
|
||||
session->local.comp != NULL &&
|
||||
session->local.comp->compress &&
|
||||
((session->state & LIBSSH2_STATE_AUTHENTICATED) ||
|
||||
session->local.comp->use_in_auth);
|
||||
|
||||
if(encrypted && compressed && session->local.comp_abstract) {
|
||||
/* the idea here is that these function must fail if the output gets
|
||||
larger than what fits in the assigned buffer so thus they don't
|
||||
check the input size as we don't know how much it compresses */
|
||||
size_t dest_len = MAX_SSH_PACKET_LEN-5-256;
|
||||
size_t dest2_len = dest_len;
|
||||
|
||||
/* compress directly to the target buffer */
|
||||
rc = session->local.comp->comp(session,
|
||||
&p->outbuf[5], &dest_len,
|
||||
data, data_len,
|
||||
&session->local.comp_abstract);
|
||||
if(rc)
|
||||
return rc; /* compression failure */
|
||||
|
||||
if(data2 && data2_len) {
|
||||
/* compress directly to the target buffer right after where the
|
||||
previous call put data */
|
||||
dest2_len -= dest_len;
|
||||
|
||||
rc = session->local.comp->comp(session,
|
||||
&p->outbuf[5 + dest_len],
|
||||
&dest2_len,
|
||||
data2, data2_len,
|
||||
&session->local.comp_abstract);
|
||||
}
|
||||
else
|
||||
dest2_len = 0;
|
||||
if(rc)
|
||||
return rc; /* compression failure */
|
||||
|
||||
data_len = dest_len + dest2_len; /* use the combined length */
|
||||
}
|
||||
else {
|
||||
if((data_len + data2_len) >= (MAX_SSH_PACKET_LEN-0x100))
|
||||
/* too large packet, return error for this until we make this
|
||||
function split it up and send multiple SSH packets */
|
||||
return LIBSSH2_ERROR_INVAL;
|
||||
|
||||
/* copy the payload data */
|
||||
memcpy(&p->outbuf[5], data, data_len);
|
||||
if(data2 && data2_len)
|
||||
memcpy(&p->outbuf[5 + data_len], data2, data2_len);
|
||||
data_len += data2_len; /* use the combined length */
|
||||
}
|
||||
|
||||
|
||||
/* RFC4253 says: Note that the length of the concatenation of
|
||||
'packet_length', 'padding_length', 'payload', and 'random padding'
|
||||
MUST be a multiple of the cipher block size or 8, whichever is
|
||||
larger. */
|
||||
|
||||
/* Plain math: (4 + 1 + packet_length + padding_length) % blocksize == 0 */
|
||||
|
||||
packet_length = data_len + 1 + 4; /* 1 is for padding_length field
|
||||
4 for the packet_length field */
|
||||
|
||||
/* at this point we have it all except the padding */
|
||||
|
||||
/* first figure out our minimum padding amount to make it an even
|
||||
block size */
|
||||
padding_length = blocksize - (packet_length % blocksize);
|
||||
|
||||
/* if the padding becomes too small we add another blocksize worth
|
||||
of it (taken from the original libssh2 where it didn't have any
|
||||
real explanation) */
|
||||
if(padding_length < 4) {
|
||||
padding_length += blocksize;
|
||||
}
|
||||
#ifdef RANDOM_PADDING
|
||||
/* FIXME: we can add padding here, but that also makes the packets
|
||||
bigger etc */
|
||||
|
||||
/* now we can add 'blocksize' to the padding_length N number of times
|
||||
(to "help thwart traffic analysis") but it must be less than 255 in
|
||||
total */
|
||||
rand_max = (255 - padding_length) / blocksize + 1;
|
||||
padding_length += blocksize * (seed % rand_max);
|
||||
#endif
|
||||
|
||||
packet_length += padding_length;
|
||||
|
||||
/* append the MAC length to the total_length size */
|
||||
total_length =
|
||||
packet_length + (encrypted ? session->local.mac->mac_len : 0);
|
||||
|
||||
/* store packet_length, which is the size of the whole packet except
|
||||
the MAC and the packet_length field itself */
|
||||
_libssh2_htonu32(p->outbuf, packet_length - 4);
|
||||
/* store padding_length */
|
||||
p->outbuf[4] = (unsigned char)padding_length;
|
||||
|
||||
/* fill the padding area with random junk */
|
||||
if(_libssh2_random(p->outbuf + 5 + data_len, padding_length)) {
|
||||
return _libssh2_error(session, LIBSSH2_ERROR_RANDGEN,
|
||||
"Unable to get random bytes for packet padding");
|
||||
}
|
||||
|
||||
if(encrypted) {
|
||||
size_t i;
|
||||
|
||||
/* Calculate MAC hash. Put the output at index packet_length,
|
||||
since that size includes the whole packet. The MAC is
|
||||
calculated on the entire unencrypted packet, including all
|
||||
fields except the MAC field itself. */
|
||||
session->local.mac->hash(session, p->outbuf + packet_length,
|
||||
session->local.seqno, p->outbuf,
|
||||
packet_length, NULL, 0,
|
||||
&session->local.mac_abstract);
|
||||
|
||||
/* Encrypt the whole packet data, one block size at a time.
|
||||
The MAC field is not encrypted. */
|
||||
for(i = 0; i < packet_length; i += session->local.crypt->blocksize) {
|
||||
unsigned char *ptr = &p->outbuf[i];
|
||||
if(session->local.crypt->crypt(session, ptr,
|
||||
session->local.crypt->blocksize,
|
||||
&session->local.crypt_abstract))
|
||||
return LIBSSH2_ERROR_ENCRYPT; /* encryption failure */
|
||||
}
|
||||
}
|
||||
|
||||
session->local.seqno++;
|
||||
|
||||
ret = LIBSSH2_SEND(session, p->outbuf, total_length,
|
||||
LIBSSH2_SOCKET_SEND_FLAGS(session));
|
||||
if(ret < 0)
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET,
|
||||
"Error sending %d bytes: %d", total_length, -ret);
|
||||
else {
|
||||
_libssh2_debug(session, LIBSSH2_TRACE_SOCKET, "Sent %d/%d bytes at %p",
|
||||
ret, total_length, p->outbuf);
|
||||
debugdump(session, "libssh2_transport_write send()", p->outbuf, ret);
|
||||
}
|
||||
|
||||
if(ret != total_length) {
|
||||
if(ret >= 0 || ret == -EAGAIN) {
|
||||
/* the whole packet could not be sent, save the rest */
|
||||
session->socket_block_directions |= LIBSSH2_SESSION_BLOCK_OUTBOUND;
|
||||
p->odata = orgdata;
|
||||
p->olen = orgdata_len;
|
||||
p->osent = ret <= 0 ? 0 : ret;
|
||||
p->ototal_num = total_length;
|
||||
return LIBSSH2_ERROR_EAGAIN;
|
||||
}
|
||||
return LIBSSH2_ERROR_SOCKET_SEND;
|
||||
}
|
||||
|
||||
/* the whole thing got sent away */
|
||||
p->odata = NULL;
|
||||
p->olen = 0;
|
||||
|
||||
return LIBSSH2_ERROR_NONE; /* all is good */
|
||||
}
|
||||
#endif
|
||||
88
lib/libssh2/transport.h
Normal file
88
lib/libssh2/transport.h
Normal file
@@ -0,0 +1,88 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_TRANSPORT_H
|
||||
#define __LIBSSH2_TRANSPORT_H
|
||||
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
|
||||
* Copyright (C) 2009-2010 by Daniel Stenberg
|
||||
* Author: Daniel Stenberg <daniel@haxx.se>
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* This file handles reading and writing to the SECSH transport layer. RFC4253.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include "packet.h"
|
||||
|
||||
|
||||
/*
|
||||
* libssh2_transport_send
|
||||
*
|
||||
* Send a packet, encrypting it and adding a MAC code if necessary
|
||||
* Returns 0 on success, non-zero on failure.
|
||||
*
|
||||
* The data is provided as _two_ data areas that are combined by this
|
||||
* function. The 'data' part is sent immediately before 'data2'. 'data2' can
|
||||
* be set to NULL (or data2_len to 0) to only use a single part.
|
||||
*
|
||||
* Returns LIBSSH2_ERROR_EAGAIN if it would block or if the whole packet was
|
||||
* not sent yet. If it does so, the caller should call this function again as
|
||||
* soon as it is likely that more data can be sent, and this function MUST
|
||||
* then be called with the same argument set (same data pointer and same
|
||||
* data_len) until ERROR_NONE or failure is returned.
|
||||
*
|
||||
* This function DOES NOT call _libssh2_error() on any errors.
|
||||
*/
|
||||
int _libssh2_transport_send(LIBSSH2_SESSION *session,
|
||||
const unsigned char *data, size_t data_len,
|
||||
const unsigned char *data2, size_t data2_len);
|
||||
|
||||
/*
|
||||
* _libssh2_transport_read
|
||||
*
|
||||
* Collect a packet into the input brigade block only controls whether or not
|
||||
* to wait for a packet to start.
|
||||
*
|
||||
* Returns packet type added to input brigade (PACKET_NONE if nothing added),
|
||||
* or PACKET_FAIL on failure and PACKET_EAGAIN if it couldn't process a full
|
||||
* packet.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This function reads the binary stream as specified in chapter 6 of RFC4253
|
||||
* "The Secure Shell (SSH) Transport Layer Protocol"
|
||||
*/
|
||||
int _libssh2_transport_read(LIBSSH2_SESSION * session);
|
||||
|
||||
#endif /* __LIBSSH2_TRANSPORT_H */
|
||||
#endif
|
||||
2348
lib/libssh2/userauth.c
Normal file
2348
lib/libssh2/userauth.c
Normal file
File diff suppressed because it is too large
Load Diff
53
lib/libssh2/userauth.h
Normal file
53
lib/libssh2/userauth.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#if defined(ESP32)
|
||||
#ifndef __LIBSSH2_USERAUTH_H
|
||||
#define __LIBSSH2_USERAUTH_H
|
||||
/* Copyright (c) 2004-2007, Sara Golemon <sarag@libssh2.org>
|
||||
* Copyright (c) 2009-2010 by Daniel Stenberg
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
int
|
||||
_libssh2_userauth_publickey(LIBSSH2_SESSION *session,
|
||||
const char *username,
|
||||
unsigned int username_len,
|
||||
const unsigned char *pubkeydata,
|
||||
unsigned long pubkeydata_len,
|
||||
LIBSSH2_USERAUTH_PUBLICKEY_SIGN_FUNC
|
||||
((*sign_callback)),
|
||||
void *abstract);
|
||||
|
||||
#endif /* __LIBSSH2_USERAUTH_H */
|
||||
#endif
|
||||
164
lib/libssh2/userauth_kbd_packet.c
Normal file
164
lib/libssh2/userauth_kbd_packet.c
Normal file
@@ -0,0 +1,164 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (c) 2022, Xaver Loppenstedt <xaver@loppenstedt.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "libssh2_priv.h"
|
||||
#include "userauth_kbd_packet.h"
|
||||
|
||||
int userauth_keyboard_interactive_decode_info_request(LIBSSH2_SESSION *session)
|
||||
{
|
||||
unsigned char *language_tag;
|
||||
size_t language_tag_len;
|
||||
unsigned int i;
|
||||
unsigned char packet_type;
|
||||
|
||||
struct string_buf decoded;
|
||||
|
||||
decoded.data = session->userauth_kybd_data;
|
||||
decoded.dataptr = session->userauth_kybd_data;
|
||||
decoded.len = session->userauth_kybd_data_len;
|
||||
|
||||
if(session->userauth_kybd_data_len < 17) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"userauth keyboard data buffer too small "
|
||||
"to get length");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* byte SSH_MSG_USERAUTH_INFO_REQUEST */
|
||||
_libssh2_get_byte(&decoded, &packet_type);
|
||||
|
||||
/* string name (ISO-10646 UTF-8) */
|
||||
if(_libssh2_copy_string(session, &decoded,
|
||||
&session->userauth_kybd_auth_name,
|
||||
&session->userauth_kybd_auth_name_len) == -1) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to decode "
|
||||
"keyboard-interactive 'name' "
|
||||
"request field");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* string instruction (ISO-10646 UTF-8) */
|
||||
if(_libssh2_copy_string(session, &decoded,
|
||||
&session->userauth_kybd_auth_instruction,
|
||||
&session->userauth_kybd_auth_instruction_len)
|
||||
== -1) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to decode "
|
||||
"keyboard-interactive 'instruction' "
|
||||
"request field");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* string language tag (as defined in [RFC-3066]) */
|
||||
if(_libssh2_get_string(&decoded, &language_tag,
|
||||
&language_tag_len) == -1) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to decode "
|
||||
"keyboard-interactive 'language tag' "
|
||||
"request field");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* int num-prompts */
|
||||
if(_libssh2_get_u32(&decoded, &session->userauth_kybd_num_prompts) == -1) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Unable to decode "
|
||||
"keyboard-interactive number of keyboard prompts");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(session->userauth_kybd_num_prompts > 100) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_OUT_OF_BOUNDARY,
|
||||
"Too many replies for "
|
||||
"keyboard-interactive prompts");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(session->userauth_kybd_num_prompts == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
session->userauth_kybd_prompts =
|
||||
LIBSSH2_CALLOC(session,
|
||||
sizeof(LIBSSH2_USERAUTH_KBDINT_PROMPT) *
|
||||
session->userauth_kybd_num_prompts);
|
||||
if(!session->userauth_kybd_prompts) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"keyboard-interactive prompts array");
|
||||
return -1;
|
||||
}
|
||||
|
||||
session->userauth_kybd_responses =
|
||||
LIBSSH2_CALLOC(session,
|
||||
sizeof(LIBSSH2_USERAUTH_KBDINT_RESPONSE) *
|
||||
session->userauth_kybd_num_prompts);
|
||||
if(!session->userauth_kybd_responses) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to allocate memory for "
|
||||
"keyboard-interactive responses array");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for(i = 0; i < session->userauth_kybd_num_prompts; i++) {
|
||||
/* string prompt[1] (ISO-10646 UTF-8) */
|
||||
if(_libssh2_copy_string(session, &decoded,
|
||||
&session->userauth_kybd_prompts[i].text,
|
||||
&session->userauth_kybd_prompts[i].length)
|
||||
== -1) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_ALLOC,
|
||||
"Unable to decode "
|
||||
"keyboard-interactive prompt message");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* boolean echo[1] */
|
||||
if(_libssh2_get_boolean(&decoded,
|
||||
&session->userauth_kybd_prompts[i].echo)
|
||||
== -1) {
|
||||
_libssh2_error(session, LIBSSH2_ERROR_BUFFER_TOO_SMALL,
|
||||
"Unable to decode "
|
||||
"user auth keyboard prompt echo");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
45
lib/libssh2/userauth_kbd_packet.h
Normal file
45
lib/libssh2/userauth_kbd_packet.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#if defined(ESP32)
|
||||
/* Copyright (c) 2022, Xaver Loppenstedt <xaver@loppenstedt.de>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the copyright holder nor the names
|
||||
* of any other contributors may be used to endorse or
|
||||
* promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __LIBSSH2_USERAUTH_KBD_PARSE_H
|
||||
#define __LIBSSH2_USERAUTH_KBD_PARSE_H
|
||||
|
||||
int userauth_keyboard_interactive_decode_info_request(LIBSSH2_SESSION *);
|
||||
|
||||
#endif /* __LIBSSH2_USERAUTH_KBD_PARSE_H */
|
||||
#endif
|
||||
572
lib/missing/slipif.c
Normal file
572
lib/missing/slipif.c
Normal file
@@ -0,0 +1,572 @@
|
||||
/**
|
||||
* @file
|
||||
* SLIP Interface
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001-2004 Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is built upon the file: src/arch/rtxc/netif/sioslip.c
|
||||
*
|
||||
* Author: Magnus Ivarsson <magnus.ivarsson(at)volvo.com>
|
||||
* Simon Goldschmidt
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @defgroup slipif SLIP
|
||||
* @ingroup netifs
|
||||
*
|
||||
* This is an arch independent SLIP netif. The specific serial hooks must be
|
||||
* provided by another file. They are sio_open, sio_read/sio_tryread and sio_send
|
||||
*
|
||||
* Usage: This netif can be used in three ways:
|
||||
* 1. For NO_SYS==0, an RX thread can be used which blocks on sio_read()
|
||||
* until data is received.
|
||||
* 2. In your main loop, call slipif_poll() to check for new RX bytes,
|
||||
* completed packets are fed into netif->input().
|
||||
* 3. Call slipif_received_byte[s]() from your serial RX ISR and
|
||||
* slipif_process_rxqueue() from your main loop. ISR level decodes
|
||||
* packets and puts completed packets on a queue which is fed into
|
||||
* the stack from the main loop (needs SYS_LIGHTWEIGHT_PROT for
|
||||
* pbuf_alloc to work on ISR level!).
|
||||
*
|
||||
*/
|
||||
|
||||
#include "slipif.h"
|
||||
#include "lwip/opt.h"
|
||||
|
||||
#include "lwip/def.h"
|
||||
#include "lwip/pbuf.h"
|
||||
#include "lwip/stats.h"
|
||||
#include "lwip/snmp.h"
|
||||
#include "lwip/sys.h"
|
||||
#include "lwip/sio.h"
|
||||
|
||||
|
||||
void* sio_open (u8_t sid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
u32_t sio_read (sio_fd_t fd, u8_t *data, u32_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
u32_t sio_tryread (sio_fd_t fd, u8_t *data, u32_t len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void sio_send (u8_t c, void *s) {}
|
||||
#define SLIP_END 0xC0 /* 0300: start and end of every packet */
|
||||
#define SLIP_ESC 0xDB /* 0333: escape start (one byte escaped data follows) */
|
||||
#define SLIP_ESC_END 0xDC /* 0334: following escape: original byte is 0xC0 (END) */
|
||||
#define SLIP_ESC_ESC 0xDD /* 0335: following escape: original byte is 0xDB (ESC) */
|
||||
|
||||
/** Maximum packet size that is received by this netif */
|
||||
#ifndef SLIP_MAX_SIZE
|
||||
#define SLIP_MAX_SIZE 1500
|
||||
#endif
|
||||
|
||||
/** Define this to the interface speed for SNMP
|
||||
* (sio_fd is the sio_fd_t returned by sio_open).
|
||||
* The default value of zero means 'unknown'.
|
||||
*/
|
||||
#ifndef SLIP_SIO_SPEED
|
||||
#define SLIP_SIO_SPEED(sio_fd) 0
|
||||
#endif
|
||||
|
||||
enum slipif_recv_state {
|
||||
SLIP_RECV_NORMAL,
|
||||
SLIP_RECV_ESCAPE
|
||||
};
|
||||
|
||||
struct slipif_priv {
|
||||
sio_fd_t sd;
|
||||
/* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */
|
||||
struct pbuf *p, *q;
|
||||
u8_t state;
|
||||
u16_t i, recved;
|
||||
#if SLIP_RX_FROM_ISR
|
||||
struct pbuf *rxpackets;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Send a pbuf doing the necessary SLIP encapsulation
|
||||
*
|
||||
* Uses the serial layer's sio_send()
|
||||
*
|
||||
* @param netif the lwip network interface structure for this slipif
|
||||
* @param p the pbuf chain packet to send
|
||||
* @return always returns ERR_OK since the serial layer does not provide return values
|
||||
*/
|
||||
static err_t
|
||||
slipif_output(struct netif *netif, struct pbuf *p)
|
||||
{
|
||||
struct slipif_priv *priv;
|
||||
struct pbuf *q;
|
||||
u16_t i;
|
||||
u8_t c;
|
||||
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
|
||||
LWIP_ASSERT("p != NULL", (p != NULL));
|
||||
|
||||
LWIP_DEBUGF(SLIP_DEBUG, ("slipif_output: sending %"U16_F" bytes\n", p->tot_len));
|
||||
priv = (struct slipif_priv *)netif->state;
|
||||
|
||||
/* Send pbuf out on the serial I/O device. */
|
||||
/* Start with packet delimiter. */
|
||||
sio_send(SLIP_END, priv->sd);
|
||||
|
||||
for (q = p; q != NULL; q = q->next) {
|
||||
for (i = 0; i < q->len; i++) {
|
||||
c = ((u8_t *)q->payload)[i];
|
||||
switch (c) {
|
||||
case SLIP_END:
|
||||
/* need to escape this byte (0xC0 -> 0xDB, 0xDC) */
|
||||
sio_send(SLIP_ESC, priv->sd);
|
||||
sio_send(SLIP_ESC_END, priv->sd);
|
||||
break;
|
||||
case SLIP_ESC:
|
||||
/* need to escape this byte (0xDB -> 0xDB, 0xDD) */
|
||||
sio_send(SLIP_ESC, priv->sd);
|
||||
sio_send(SLIP_ESC_ESC, priv->sd);
|
||||
break;
|
||||
default:
|
||||
/* normal byte - no need for escaping */
|
||||
sio_send(c, priv->sd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* End with packet delimiter. */
|
||||
sio_send(SLIP_END, priv->sd);
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
#if LWIP_IPV4
|
||||
/**
|
||||
* Send a pbuf doing the necessary SLIP encapsulation
|
||||
*
|
||||
* Uses the serial layer's sio_send()
|
||||
*
|
||||
* @param netif the lwip network interface structure for this slipif
|
||||
* @param p the pbuf chain packet to send
|
||||
* @param ipaddr the ip address to send the packet to (not used for slipif)
|
||||
* @return always returns ERR_OK since the serial layer does not provide return values
|
||||
*/
|
||||
static err_t
|
||||
slipif_output_v4(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr)
|
||||
{
|
||||
LWIP_UNUSED_ARG(ipaddr);
|
||||
return slipif_output(netif, p);
|
||||
}
|
||||
#endif /* LWIP_IPV4 */
|
||||
|
||||
#if LWIP_IPV6
|
||||
/**
|
||||
* Send a pbuf doing the necessary SLIP encapsulation
|
||||
*
|
||||
* Uses the serial layer's sio_send()
|
||||
*
|
||||
* @param netif the lwip network interface structure for this slipif
|
||||
* @param p the pbuf chain packet to send
|
||||
* @param ipaddr the ip address to send the packet to (not used for slipif)
|
||||
* @return always returns ERR_OK since the serial layer does not provide return values
|
||||
*/
|
||||
static err_t
|
||||
slipif_output_v6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr)
|
||||
{
|
||||
LWIP_UNUSED_ARG(ipaddr);
|
||||
return slipif_output(netif, p);
|
||||
}
|
||||
#endif /* LWIP_IPV6 */
|
||||
|
||||
/**
|
||||
* Handle the incoming SLIP stream character by character
|
||||
*
|
||||
* @param netif the lwip network interface structure for this slipif
|
||||
* @param c received character (multiple calls to this function will
|
||||
* return a complete packet, NULL is returned before - used for polling)
|
||||
* @return The IP packet when SLIP_END is received
|
||||
*/
|
||||
static struct pbuf *
|
||||
slipif_rxbyte(struct netif *netif, u8_t c)
|
||||
{
|
||||
struct slipif_priv *priv;
|
||||
struct pbuf *t;
|
||||
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
|
||||
|
||||
priv = (struct slipif_priv *)netif->state;
|
||||
|
||||
switch (priv->state) {
|
||||
case SLIP_RECV_NORMAL:
|
||||
switch (c) {
|
||||
case SLIP_END:
|
||||
if (priv->recved > 0) {
|
||||
/* Received whole packet. */
|
||||
/* Trim the pbuf to the size of the received packet. */
|
||||
pbuf_realloc(priv->q, priv->recved);
|
||||
|
||||
LINK_STATS_INC(link.recv);
|
||||
|
||||
LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet (%"U16_F" bytes)\n", priv->recved));
|
||||
t = priv->q;
|
||||
priv->p = priv->q = NULL;
|
||||
priv->i = priv->recved = 0;
|
||||
return t;
|
||||
}
|
||||
return NULL;
|
||||
case SLIP_ESC:
|
||||
priv->state = SLIP_RECV_ESCAPE;
|
||||
return NULL;
|
||||
default:
|
||||
break;
|
||||
} /* end switch (c) */
|
||||
break;
|
||||
case SLIP_RECV_ESCAPE:
|
||||
/* un-escape END or ESC bytes, leave other bytes
|
||||
(although that would be a protocol error) */
|
||||
switch (c) {
|
||||
case SLIP_ESC_END:
|
||||
c = SLIP_END;
|
||||
break;
|
||||
case SLIP_ESC_ESC:
|
||||
c = SLIP_ESC;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
priv->state = SLIP_RECV_NORMAL;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} /* end switch (priv->state) */
|
||||
|
||||
/* byte received, packet not yet completely received */
|
||||
if (priv->p == NULL) {
|
||||
/* allocate a new pbuf */
|
||||
LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n"));
|
||||
priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - PBUF_LINK_ENCAPSULATION_HLEN), PBUF_POOL);
|
||||
|
||||
if (priv->p == NULL) {
|
||||
LINK_STATS_INC(link.drop);
|
||||
LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n"));
|
||||
/* don't process any further since we got no pbuf to receive to */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (priv->q != NULL) {
|
||||
/* 'chain' the pbuf to the existing chain */
|
||||
pbuf_cat(priv->q, priv->p);
|
||||
} else {
|
||||
/* p is the first pbuf in the chain */
|
||||
priv->q = priv->p;
|
||||
}
|
||||
}
|
||||
|
||||
/* this automatically drops bytes if > SLIP_MAX_SIZE */
|
||||
if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) {
|
||||
((u8_t *)priv->p->payload)[priv->i] = c;
|
||||
priv->recved++;
|
||||
priv->i++;
|
||||
if (priv->i >= priv->p->len) {
|
||||
/* on to the next pbuf */
|
||||
priv->i = 0;
|
||||
if (priv->p->next != NULL && priv->p->next->len > 0) {
|
||||
/* p is a chain, on to the next in the chain */
|
||||
priv->p = priv->p->next;
|
||||
} else {
|
||||
/* p is a single pbuf, set it to NULL so next time a new
|
||||
* pbuf is allocated */
|
||||
priv->p = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Like slipif_rxbyte, but passes completed packets to netif->input
|
||||
*
|
||||
* @param netif The lwip network interface structure for this slipif
|
||||
* @param c received character
|
||||
*/
|
||||
static void
|
||||
slipif_rxbyte_input(struct netif *netif, u8_t c)
|
||||
{
|
||||
struct pbuf *p;
|
||||
p = slipif_rxbyte(netif, c);
|
||||
if (p != NULL) {
|
||||
if (netif->input(p, netif) != ERR_OK) {
|
||||
pbuf_free(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if SLIP_USE_RX_THREAD
|
||||
/**
|
||||
* The SLIP input thread.
|
||||
*
|
||||
* Feed the IP layer with incoming packets
|
||||
*
|
||||
* @param nf the lwip network interface structure for this slipif
|
||||
*/
|
||||
static void
|
||||
slipif_loop_thread(void *nf)
|
||||
{
|
||||
u8_t c;
|
||||
struct netif *netif = (struct netif *)nf;
|
||||
struct slipif_priv *priv = (struct slipif_priv *)netif->state;
|
||||
|
||||
while (1) {
|
||||
if (sio_read(priv->sd, &c, 1) > 0) {
|
||||
slipif_rxbyte_input(netif, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* SLIP_USE_RX_THREAD */
|
||||
|
||||
/**
|
||||
* @ingroup slipif
|
||||
* SLIP netif initialization
|
||||
*
|
||||
* Call the arch specific sio_open and remember
|
||||
* the opened device in the state field of the netif.
|
||||
*
|
||||
* @param netif the lwip network interface structure for this slipif
|
||||
* @return ERR_OK if serial line could be opened,
|
||||
* ERR_MEM if no memory could be allocated,
|
||||
* ERR_IF is serial line couldn't be opened
|
||||
*
|
||||
* @note If netif->state is interpreted as an u8_t serial port number.
|
||||
*
|
||||
*/
|
||||
err_t
|
||||
slipif_init(struct netif *netif)
|
||||
{
|
||||
struct slipif_priv *priv;
|
||||
u8_t sio_num;
|
||||
|
||||
LWIP_ASSERT("slipif needs an input callback", netif->input != NULL);
|
||||
|
||||
/* netif->state contains serial port number */
|
||||
sio_num = LWIP_PTR_NUMERIC_CAST(u8_t, netif->state);
|
||||
|
||||
LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)sio_num));
|
||||
|
||||
/* Allocate private data */
|
||||
priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv));
|
||||
if (!priv) {
|
||||
return ERR_MEM;
|
||||
}
|
||||
|
||||
netif->name[0] = 's';
|
||||
netif->name[1] = 'l';
|
||||
#if LWIP_IPV4
|
||||
netif->output = slipif_output_v4;
|
||||
#endif /* LWIP_IPV4 */
|
||||
#if LWIP_IPV6
|
||||
netif->output_ip6 = slipif_output_v6;
|
||||
#endif /* LWIP_IPV6 */
|
||||
netif->mtu = SLIP_MAX_SIZE;
|
||||
|
||||
/* Try to open the serial port. */
|
||||
priv->sd = sio_open(sio_num);
|
||||
if (!priv->sd) {
|
||||
/* Opening the serial port failed. */
|
||||
mem_free(priv);
|
||||
return ERR_IF;
|
||||
}
|
||||
|
||||
/* Initialize private data */
|
||||
priv->p = NULL;
|
||||
priv->q = NULL;
|
||||
priv->state = SLIP_RECV_NORMAL;
|
||||
priv->i = 0;
|
||||
priv->recved = 0;
|
||||
#if SLIP_RX_FROM_ISR
|
||||
priv->rxpackets = NULL;
|
||||
#endif
|
||||
|
||||
netif->state = priv;
|
||||
|
||||
/* initialize the snmp variables and counters inside the struct netif */
|
||||
MIB2_INIT_NETIF(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd));
|
||||
|
||||
#if SLIP_USE_RX_THREAD
|
||||
/* Create a thread to poll the serial line. */
|
||||
sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif,
|
||||
SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO);
|
||||
#endif /* SLIP_USE_RX_THREAD */
|
||||
return ERR_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup slipif
|
||||
* Polls the serial device and feeds the IP layer with incoming packets.
|
||||
*
|
||||
* @param netif The lwip network interface structure for this slipif
|
||||
*/
|
||||
void
|
||||
slipif_poll(struct netif *netif)
|
||||
{
|
||||
u8_t c;
|
||||
struct slipif_priv *priv;
|
||||
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
|
||||
|
||||
priv = (struct slipif_priv *)netif->state;
|
||||
|
||||
while (sio_tryread(priv->sd, &c, 1) > 0) {
|
||||
slipif_rxbyte_input(netif, c);
|
||||
}
|
||||
}
|
||||
|
||||
#if SLIP_RX_FROM_ISR
|
||||
/**
|
||||
* @ingroup slipif
|
||||
* Feeds the IP layer with incoming packets that were receive
|
||||
*
|
||||
* @param netif The lwip network interface structure for this slipif
|
||||
*/
|
||||
void
|
||||
slipif_process_rxqueue(struct netif *netif)
|
||||
{
|
||||
struct slipif_priv *priv;
|
||||
SYS_ARCH_DECL_PROTECT(old_level);
|
||||
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
|
||||
|
||||
priv = (struct slipif_priv *)netif->state;
|
||||
|
||||
SYS_ARCH_PROTECT(old_level);
|
||||
while (priv->rxpackets != NULL) {
|
||||
struct pbuf *p = priv->rxpackets;
|
||||
#if SLIP_RX_QUEUE
|
||||
/* dequeue packet */
|
||||
struct pbuf *q = p;
|
||||
while ((q->len != q->tot_len) && (q->next != NULL)) {
|
||||
q = q->next;
|
||||
}
|
||||
priv->rxpackets = q->next;
|
||||
q->next = NULL;
|
||||
#else /* SLIP_RX_QUEUE */
|
||||
priv->rxpackets = NULL;
|
||||
#endif /* SLIP_RX_QUEUE */
|
||||
SYS_ARCH_UNPROTECT(old_level);
|
||||
if (netif->input(p, netif) != ERR_OK) {
|
||||
pbuf_free(p);
|
||||
}
|
||||
SYS_ARCH_PROTECT(old_level);
|
||||
}
|
||||
SYS_ARCH_UNPROTECT(old_level);
|
||||
}
|
||||
|
||||
/** Like slipif_rxbyte, but queues completed packets.
|
||||
*
|
||||
* @param netif The lwip network interface structure for this slipif
|
||||
* @param data Received serial byte
|
||||
*/
|
||||
static void
|
||||
slipif_rxbyte_enqueue(struct netif *netif, u8_t data)
|
||||
{
|
||||
struct pbuf *p;
|
||||
struct slipif_priv *priv = (struct slipif_priv *)netif->state;
|
||||
SYS_ARCH_DECL_PROTECT(old_level);
|
||||
|
||||
p = slipif_rxbyte(netif, data);
|
||||
if (p != NULL) {
|
||||
SYS_ARCH_PROTECT(old_level);
|
||||
if (priv->rxpackets != NULL) {
|
||||
#if SLIP_RX_QUEUE
|
||||
/* queue multiple pbufs */
|
||||
struct pbuf *q = p;
|
||||
while (q->next != NULL) {
|
||||
q = q->next;
|
||||
}
|
||||
q->next = p;
|
||||
} else {
|
||||
#else /* SLIP_RX_QUEUE */
|
||||
pbuf_free(priv->rxpackets);
|
||||
}
|
||||
{
|
||||
#endif /* SLIP_RX_QUEUE */
|
||||
priv->rxpackets = p;
|
||||
}
|
||||
SYS_ARCH_UNPROTECT(old_level);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup slipif
|
||||
* Process a received byte, completed packets are put on a queue that is
|
||||
* fed into IP through slipif_process_rxqueue().
|
||||
*
|
||||
* This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled.
|
||||
*
|
||||
* @param netif The lwip network interface structure for this slipif
|
||||
* @param data received character
|
||||
*/
|
||||
void
|
||||
slipif_received_byte(struct netif *netif, u8_t data)
|
||||
{
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
|
||||
slipif_rxbyte_enqueue(netif, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup slipif
|
||||
* Process multiple received byte, completed packets are put on a queue that is
|
||||
* fed into IP through slipif_process_rxqueue().
|
||||
*
|
||||
* This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled.
|
||||
*
|
||||
* @param netif The lwip network interface structure for this slipif
|
||||
* @param data received character
|
||||
* @param len Number of received characters
|
||||
*/
|
||||
void
|
||||
slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len)
|
||||
{
|
||||
u8_t i;
|
||||
u8_t *rxdata = data;
|
||||
LWIP_ASSERT("netif != NULL", (netif != NULL));
|
||||
LWIP_ASSERT("netif->state != NULL", (netif->state != NULL));
|
||||
|
||||
for (i = 0; i < len; i++, rxdata++) {
|
||||
slipif_rxbyte_enqueue(netif, *rxdata);
|
||||
}
|
||||
}
|
||||
#endif /* SLIP_RX_FROM_ISR */
|
||||
86
lib/missing/slipif.h
Normal file
86
lib/missing/slipif.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* SLIP netif API
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the lwIP TCP/IP stack.
|
||||
*
|
||||
* Author: Adam Dunkels <adam@sics.se>
|
||||
*
|
||||
*/
|
||||
#ifndef LWIP_HDR_NETIF_SLIPIF_H
|
||||
#define LWIP_HDR_NETIF_SLIPIF_H
|
||||
|
||||
#include "lwip/opt.h"
|
||||
#include "lwip/netif.h"
|
||||
|
||||
/** Set this to 1 to start a thread that blocks reading on the serial line
|
||||
* (using sio_read()).
|
||||
*/
|
||||
#ifndef SLIP_USE_RX_THREAD
|
||||
#define SLIP_USE_RX_THREAD !NO_SYS
|
||||
#endif
|
||||
|
||||
/** Set this to 1 to enable functions to pass in RX bytes from ISR context.
|
||||
* If enabled, slipif_received_byte[s]() process incoming bytes and put assembled
|
||||
* packets on a queue, which is fed into lwIP from slipif_poll().
|
||||
* If disabled, slipif_poll() polls the serial line (using sio_tryread()).
|
||||
*/
|
||||
#ifndef SLIP_RX_FROM_ISR
|
||||
#define SLIP_RX_FROM_ISR 0
|
||||
#endif
|
||||
|
||||
/** Set this to 1 (default for SLIP_RX_FROM_ISR) to queue incoming packets
|
||||
* received by slipif_received_byte[s]() as long as PBUF_POOL pbufs are available.
|
||||
* If disabled, packets will be dropped if more than one packet is received.
|
||||
*/
|
||||
#ifndef SLIP_RX_QUEUE
|
||||
#define SLIP_RX_QUEUE SLIP_RX_FROM_ISR
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
err_t slipif_init(struct netif * netif);
|
||||
void slipif_poll(struct netif *netif);
|
||||
#if SLIP_RX_FROM_ISR
|
||||
void slipif_process_rxqueue(struct netif *netif);
|
||||
void slipif_received_byte(struct netif *netif, u8_t data);
|
||||
void slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len);
|
||||
#endif /* SLIP_RX_FROM_ISR */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* LWIP_HDR_NETIF_SLIPIF_H */
|
||||
Reference in New Issue
Block a user