mirror of https://github.com/wolfSSL/wolfssh.git
SSH-AGENT
1. Added option to client to load a public key. 2. Added function ReadKey to load a key from a buffer or from a file and store it. Utility for the client.pull/269/head
parent
636cd81d32
commit
365d1fd8ea
|
@ -26,7 +26,6 @@
|
|||
#include <wolfssh/agent.h>
|
||||
#endif
|
||||
#include <wolfssl/wolfcrypt/ecc.h>
|
||||
#include <wolfssl/wolfcrypt/coding.h>
|
||||
#include "examples/client/client.h"
|
||||
#if !defined(USE_WINDOWS_API) && !defined(MICROCHIP_PIC32)
|
||||
#include <termios.h>
|
||||
|
@ -158,6 +157,8 @@ static void ShowUsage(void)
|
|||
printf(" -u <username> username to authenticate as (REQUIRED)\n");
|
||||
printf(" -P <password> password for username, prompted if omitted\n");
|
||||
printf(" -e use sample ecc key for user\n");
|
||||
printf(" -i <filename> filename for the user's private key\n");
|
||||
printf(" -j <filename> filename for the user's public key\n");
|
||||
printf(" -x exit after successful connection without doing\n"
|
||||
" read/write\n");
|
||||
printf(" -N use non-blocking sockets\n");
|
||||
|
@ -174,20 +175,24 @@ static void ShowUsage(void)
|
|||
|
||||
|
||||
static byte userPassword[256];
|
||||
static byte userPublicKeyType[32];
|
||||
static byte userPublicKey[512];
|
||||
static word32 userPublicKeySz;
|
||||
static const byte* userPrivateKey;
|
||||
static word32 userPrivateKeySz;
|
||||
static const byte* userPublicKeyType = NULL;
|
||||
static byte* userPrivateKey = NULL; /* Will be allocated by Read Key. */
|
||||
static const byte* userPrivateKeyType = NULL;
|
||||
static word32 userPublicKeySz = 0;
|
||||
static word32 userPublicKeyTypeSz = 0;
|
||||
static word32 userPrivateKeySz = 0;
|
||||
static word32 userPrivateKeyTypeSz = 0;
|
||||
static byte isPrivate = 0;
|
||||
|
||||
|
||||
static const char hanselPublicRsa[] =
|
||||
"AAAAB3NzaC1yc2EAAAADAQABAAABAQC9P3ZFowOsONXHD5MwWiCciXytBRZGho"
|
||||
static const char* hanselPublicRsa =
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9P3ZFowOsONXHD5MwWiCciXytBRZGho"
|
||||
"MNiisWSgUs5HdHcACuHYPi2W6Z1PBFmBWT9odOrGRjoZXJfDDoPi+j8SSfDGsc/hsCmc3G"
|
||||
"p2yEhUZUEkDhtOXyqjns1ickC9Gh4u80aSVtwHRnJZh9xPhSq5tLOhId4eP61s+a5pwjTj"
|
||||
"nEhBaIPUJO2C/M0pFnnbZxKgJlX7t1Doy7h5eXxviymOIvaCZKU+x5OopfzM/wFkey0EPW"
|
||||
"NmzI5y/+pzU5afsdeEWdiQDIQc80H6Pz8fsoFPvYSG+s4/wz0duu7yeeV1Ypoho65Zr+pE"
|
||||
"nIf7dO0B8EblgWt+ud+JI8wrAhfE4x";
|
||||
"nIf7dO0B8EblgWt+ud+JI8wrAhfE4x hansel";
|
||||
|
||||
static const byte hanselPrivateRsa[] = {
|
||||
0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
|
||||
|
@ -295,9 +300,10 @@ static const byte hanselPrivateRsa[] = {
|
|||
static const unsigned int hanselPrivateRsaSz = 1191;
|
||||
|
||||
|
||||
static const char hanselPublicEcc[] =
|
||||
"AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNkI5JTP6D0lF42tbx"
|
||||
"X19cE87hztUS6FSDoGvPfiU0CgeNSbI+aFdKIzTP5CQEJSvm25qUzgDtH7oyaQROUnNvk=";
|
||||
const char* hanselPublicEcc =
|
||||
"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAA"
|
||||
"BBBNkI5JTP6D0lF42tbxX19cE87hztUS6FSDoGvPfiU0CgeNSbI+aFdKIzTP5CQEJSvm25"
|
||||
"qUzgDtH7oyaQROUnNvk= hansel";
|
||||
|
||||
static const byte hanselPrivateEcc[] = {
|
||||
0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x03, 0x6e, 0x17, 0xd3, 0xb9,
|
||||
|
@ -336,13 +342,16 @@ static int wsUserAuth(byte authType,
|
|||
#endif
|
||||
|
||||
/* We know hansel has a key, wait for request of public key */
|
||||
if (authType == WOLFSSH_USERAUTH_PUBLICKEY &&
|
||||
if ((authData->type & WOLFSSH_USERAUTH_PUBLICKEY) &&
|
||||
authData->username != NULL &&
|
||||
authData->usernameSz > 0 &&
|
||||
XSTRNCMP((char*)authData->username, "hansel",
|
||||
authData->usernameSz) == 0) {
|
||||
(XSTRNCMP((char*)authData->username, "hansel",
|
||||
authData->usernameSz) == 0 ||
|
||||
XSTRNCMP((char*)authData->username, "john",
|
||||
authData->usernameSz) == 0)) {
|
||||
if (authType == WOLFSSH_USERAUTH_PASSWORD) {
|
||||
printf("rejecting password type with hansel in favor of pub key\n");
|
||||
printf("rejecting password type with %s in favor of pub key\n",
|
||||
(char*)authData->username);
|
||||
return WOLFSSH_USERAUTH_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -350,21 +359,14 @@ static int wsUserAuth(byte authType,
|
|||
if (authType == WOLFSSH_USERAUTH_PUBLICKEY) {
|
||||
WS_UserAuthData_PublicKey* pk = &authData->sf.publicKey;
|
||||
|
||||
/* we only have hansel's sample key loaded */
|
||||
if (authData->username != NULL && authData->usernameSz > 0 &&
|
||||
XSTRNCMP((char*)authData->username, "hansel",
|
||||
authData->usernameSz) == 0) {
|
||||
pk->publicKeyType = userPublicKeyType;
|
||||
pk->publicKeyTypeSz = (word32)WSTRLEN((char*)userPublicKeyType);
|
||||
pk->publicKey = userPublicKey;
|
||||
pk->publicKeySz = userPublicKeySz;
|
||||
pk->privateKey = userPrivateKey;
|
||||
pk->privateKeySz = userPrivateKeySz;
|
||||
ret = WOLFSSH_USERAUTH_SUCCESS;
|
||||
}
|
||||
else {
|
||||
ret = WOLFSSH_USERAUTH_INVALID_USER;
|
||||
}
|
||||
pk->publicKeyType = userPublicKeyType;
|
||||
pk->publicKeyTypeSz = userPublicKeyTypeSz;
|
||||
pk->publicKey = userPublicKey;
|
||||
pk->publicKeySz = userPublicKeySz;
|
||||
pk->privateKey = userPrivateKey;
|
||||
pk->privateKeySz = userPrivateKeySz;
|
||||
|
||||
ret = WOLFSSH_USERAUTH_SUCCESS;
|
||||
}
|
||||
else if (authType == WOLFSSH_USERAUTH_PASSWORD) {
|
||||
const char* defaultPassword = (const char*)ctx;
|
||||
|
@ -383,7 +385,7 @@ static int wsUserAuth(byte authType,
|
|||
ret = WOLFSSH_USERAUTH_FAILURE;
|
||||
}
|
||||
else {
|
||||
char* c = strpbrk((char*)userPassword, "\r\n");;
|
||||
char* c = strpbrk((char*)userPassword, "\r\n");
|
||||
if (c != NULL)
|
||||
*c = '\0';
|
||||
}
|
||||
|
@ -752,6 +754,8 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
|
|||
const char* username = NULL;
|
||||
const char* password = NULL;
|
||||
const char* cmd = NULL;
|
||||
const char* privKeyName = NULL;
|
||||
const char* pubKeyName = NULL;
|
||||
byte imExit = 0;
|
||||
byte nonBlock = 0;
|
||||
byte keepOpen = 0;
|
||||
|
@ -766,7 +770,7 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
|
|||
char** argv = ((func_args*)args)->argv;
|
||||
((func_args*)args)->return_code = 0;
|
||||
|
||||
while ((ch = mygetopt(argc, argv, "?c:eh:p:tu:xzNP:R")) != -1) {
|
||||
while ((ch = mygetopt(argc, argv, "?c:eh:i:j:p:tu:xzNP:R")) != -1) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
host = myoptarg;
|
||||
|
@ -799,6 +803,14 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
|
|||
password = myoptarg;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
privKeyName = myoptarg;
|
||||
break;
|
||||
|
||||
case 'j':
|
||||
pubKeyName = myoptarg;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
/* exit after successful connection without read/write */
|
||||
imExit = 1;
|
||||
|
@ -843,27 +855,62 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
|
|||
err_sys("Threading needed for terminal session\n");
|
||||
#endif
|
||||
|
||||
if (userEcc) {
|
||||
userPublicKeySz = (word32)sizeof(userPublicKey);
|
||||
Base64_Decode((byte*)hanselPublicEcc,
|
||||
(word32)WSTRLEN(hanselPublicEcc),
|
||||
(byte*)userPublicKey, &userPublicKeySz);
|
||||
if (pubKeyName == NULL && privKeyName != NULL) {
|
||||
err_sys("If setting priv key, need pub key.");
|
||||
}
|
||||
|
||||
WSTRNCPY((char*)userPublicKeyType, "ecdsa-sha2-nistp256",
|
||||
sizeof(userPublicKeyType));
|
||||
userPrivateKey = hanselPrivateEcc;
|
||||
userPrivateKeySz = hanselPrivateEccSz;
|
||||
if (privKeyName == NULL) {
|
||||
if (userEcc) {
|
||||
ret = wolfSSH_ReadKey_buffer(hanselPrivateEcc, hanselPrivateEccSz,
|
||||
WOLFSSH_FORMAT_ASN1, &userPrivateKey, &userPrivateKeySz,
|
||||
&userPrivateKeyType, &userPrivateKeyTypeSz, NULL);
|
||||
isPrivate = 1;
|
||||
}
|
||||
else {
|
||||
ret = wolfSSH_ReadKey_buffer(hanselPrivateRsa, hanselPrivateRsaSz,
|
||||
WOLFSSH_FORMAT_ASN1, &userPrivateKey, &userPrivateKeySz,
|
||||
&userPrivateKeyType, &userPrivateKeyTypeSz, NULL);
|
||||
isPrivate = 1;
|
||||
}
|
||||
if (ret != 0) err_sys("Couldn't load private key buffer.");
|
||||
}
|
||||
else {
|
||||
userPublicKeySz = (word32)sizeof(userPublicKey);
|
||||
Base64_Decode((byte*)hanselPublicRsa,
|
||||
(word32)WSTRLEN(hanselPublicRsa),
|
||||
(byte*)userPublicKey, &userPublicKeySz);
|
||||
ret = wolfSSH_ReadKey_file(privKeyName,
|
||||
(byte**)&userPrivateKey, &userPrivateKeySz,
|
||||
(const byte**)&userPrivateKeyType, &userPrivateKeyTypeSz,
|
||||
&isPrivate, NULL);
|
||||
if (ret != 0) err_sys("Couldn't load private key file.");
|
||||
}
|
||||
|
||||
WSTRNCPY((char*)userPublicKeyType, "ssh-rsa",
|
||||
sizeof(userPublicKeyType));
|
||||
userPrivateKey = hanselPrivateRsa;
|
||||
userPrivateKeySz = hanselPrivateRsaSz;
|
||||
if (pubKeyName == NULL) {
|
||||
byte* p = userPublicKey;
|
||||
userPublicKeySz = sizeof(userPublicKey);
|
||||
|
||||
if (userEcc) {
|
||||
ret = wolfSSH_ReadKey_buffer((const byte*)hanselPublicEcc,
|
||||
(word32)strlen(hanselPublicEcc), WOLFSSH_FORMAT_SSH,
|
||||
&p, &userPublicKeySz,
|
||||
&userPublicKeyType, &userPublicKeyTypeSz, NULL);
|
||||
isPrivate = 1;
|
||||
}
|
||||
else {
|
||||
ret = wolfSSH_ReadKey_buffer((const byte*)hanselPublicRsa,
|
||||
(word32)strlen(hanselPublicRsa), WOLFSSH_FORMAT_SSH,
|
||||
&p, &userPublicKeySz,
|
||||
&userPublicKeyType, &userPublicKeyTypeSz, NULL);
|
||||
isPrivate = 1;
|
||||
}
|
||||
if (ret != 0) err_sys("Couldn't load public key buffer.");
|
||||
}
|
||||
else {
|
||||
byte* p = userPublicKey;
|
||||
userPublicKeySz = sizeof(userPublicKey);
|
||||
|
||||
ret = wolfSSH_ReadKey_file(pubKeyName,
|
||||
&p, &userPublicKeySz,
|
||||
(const byte**)&userPublicKeyType, &userPublicKeyTypeSz,
|
||||
&isPrivate, NULL);
|
||||
if (ret != 0) err_sys("Couldn't load public key file.");
|
||||
}
|
||||
|
||||
ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_CLIENT, NULL);
|
||||
|
@ -1007,6 +1054,8 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
|
|||
WCLOSESOCKET(sockFd);
|
||||
wolfSSH_free(ssh);
|
||||
wolfSSH_CTX_free(ctx);
|
||||
if (userPrivateKey != NULL)
|
||||
free(userPrivateKey);
|
||||
if (ret != WS_SUCCESS)
|
||||
err_sys("Closing stream failed. Connection could have been closed by peer");
|
||||
|
||||
|
|
192
src/ssh.c
192
src/ssh.c
|
@ -1362,6 +1362,198 @@ char* wolfSSH_GetUsername(WOLFSSH* ssh)
|
|||
}
|
||||
|
||||
|
||||
#include <wolfssl/wolfcrypt/rsa.h>
|
||||
#include <wolfssl/wolfcrypt/asn_public.h>
|
||||
#include <wolfssl/wolfcrypt/coding.h>
|
||||
|
||||
#define WSTRDUP(x,y) strdup((x))
|
||||
#define WSTRSEP(x,y) strsep((x),(y))
|
||||
int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format,
|
||||
byte** out, word32* outSz, const byte** outType, word32* outTypeSz,
|
||||
void* heap)
|
||||
{
|
||||
int ret = WS_SUCCESS;
|
||||
|
||||
(void)heap;
|
||||
|
||||
if (in == NULL || inSz == 0 || out == NULL || outSz == NULL ||
|
||||
outType == NULL || outTypeSz == NULL)
|
||||
return WS_BAD_ARGUMENT;
|
||||
|
||||
if (format == WOLFSSH_FORMAT_SSH) {
|
||||
char* dup;
|
||||
char* c;
|
||||
char* type;
|
||||
char* key;
|
||||
|
||||
/*
|
||||
SSH format is:
|
||||
type AAAABASE64ENCODEDKEYDATA comment
|
||||
*/
|
||||
c = dup = WSTRDUP((const char*)in, heap);
|
||||
type = WSTRSEP(&c, " \n");
|
||||
key = WSTRSEP(&c, " \n");
|
||||
|
||||
if (type != NULL && key != NULL) {
|
||||
const char* name;
|
||||
word32 typeSz;
|
||||
|
||||
typeSz = (word32)WSTRLEN(type);
|
||||
|
||||
name = IdToName(ID_SSH_RSA);
|
||||
if (WSTRNCMP(type, name, typeSz) == 0) {
|
||||
*outType = (const byte*)name;
|
||||
}
|
||||
else {
|
||||
name = IdToName(ID_ECDSA_SHA2_NISTP256);
|
||||
if (WSTRNCMP(type, name, typeSz) == 0) {
|
||||
*outType = (const byte*)name;
|
||||
}
|
||||
else {
|
||||
name = IdToName(ID_UNKNOWN);
|
||||
*outType = (const byte*)name;
|
||||
typeSz = (word32)WSTRLEN(name);
|
||||
}
|
||||
}
|
||||
*outTypeSz = typeSz;
|
||||
|
||||
ret = Base64_Decode((byte*)key, (word32)WSTRLEN(key), *out, outSz);
|
||||
}
|
||||
|
||||
if (ret != 0)
|
||||
ret = WS_ERROR;
|
||||
|
||||
WFREE(dup, heap, DYNTYPE_STRING);
|
||||
}
|
||||
else if (format == WOLFSSH_FORMAT_ASN1) {
|
||||
byte* newKey;
|
||||
union {
|
||||
RsaKey rsa;
|
||||
ecc_key ecc;
|
||||
} testKey;
|
||||
word32 scratch = 0;
|
||||
|
||||
if (*out == NULL) {
|
||||
newKey = (byte*)WMALLOC(inSz, heap, DYNTYPE_PRIVKEY);
|
||||
if (newKey == NULL)
|
||||
return WS_MEMORY_E;
|
||||
*out = newKey;
|
||||
}
|
||||
else {
|
||||
if (*outSz < inSz)
|
||||
return WS_ERROR;
|
||||
newKey = *out;
|
||||
}
|
||||
*outSz = inSz;
|
||||
WMEMCPY(newKey, in, inSz);
|
||||
|
||||
/* TODO: This is copied and modified from a function in src/internal.c.
|
||||
This and that code should be combined into a single function. */
|
||||
if (wc_InitRsaKey(&testKey.rsa, heap) < 0)
|
||||
return WS_RSA_E;
|
||||
|
||||
ret = wc_RsaPrivateKeyDecode(in, &scratch, &testKey.rsa, inSz);
|
||||
|
||||
wc_FreeRsaKey(&testKey.rsa);
|
||||
|
||||
if (ret == 0) {
|
||||
*outType = (const byte*)IdToName(ID_SSH_RSA);
|
||||
*outTypeSz = (word32)WSTRLEN((const char*)*outType);
|
||||
}
|
||||
else {
|
||||
/* Couldn't decode as RSA testKey. Try decoding as ECC testKey. */
|
||||
scratch = 0;
|
||||
if (wc_ecc_init_ex(&testKey.ecc, heap, INVALID_DEVID) != 0)
|
||||
return WS_ECC_E;
|
||||
|
||||
ret = wc_EccPrivateKeyDecode(in, &scratch,
|
||||
&testKey.ecc, inSz);
|
||||
wc_ecc_free(&testKey.ecc);
|
||||
|
||||
if (ret == 0) {
|
||||
*outType = (const byte*)IdToName(ID_ECDH_SHA2_NISTP256);
|
||||
*outTypeSz = (word32)WSTRLEN((const char*)*outType);
|
||||
}
|
||||
else
|
||||
return WS_BAD_FILE_E;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret = WS_ERROR;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_FILESYSTEM
|
||||
|
||||
int wolfSSH_ReadKey_file(const char* name,
|
||||
byte** out, word32* outSz, const byte** outType, word32* outTypeSz,
|
||||
byte* isPrivate, void* heap)
|
||||
{
|
||||
WFILE* file;
|
||||
byte* in;
|
||||
word32 inSz;
|
||||
int format;
|
||||
int ret;
|
||||
|
||||
if (name == NULL)
|
||||
return WS_BAD_FILE_E;
|
||||
|
||||
if (out == NULL || outSz == NULL || outType == NULL || outTypeSz == NULL ||
|
||||
isPrivate == NULL)
|
||||
return WS_BAD_ARGUMENT;
|
||||
|
||||
ret = WFOPEN(&file, name, "rb");
|
||||
if (file == WBADFILE) return WS_BAD_FILE_E;
|
||||
if (WFSEEK(file, 0, WSEEK_END) != 0) {
|
||||
WFCLOSE(file);
|
||||
return WS_BAD_FILE_E;
|
||||
}
|
||||
inSz = (word32)WFTELL(file);
|
||||
WREWIND(file);
|
||||
|
||||
if (inSz > WOLFSSH_MAX_FILE_SIZE || inSz == 0) {
|
||||
WFCLOSE(file);
|
||||
return WS_BAD_FILE_E;
|
||||
}
|
||||
|
||||
in = (byte*)WMALLOC(inSz + 1, heap, DYNTYPE_FILE);
|
||||
if (in == NULL) {
|
||||
WFCLOSE(file);
|
||||
return WS_MEMORY_E;
|
||||
}
|
||||
|
||||
ret = (int)XFREAD(in, 1, inSz, file);
|
||||
if (ret <= 0 || (word32)ret != inSz) {
|
||||
ret = WS_BAD_FILE_E;
|
||||
}
|
||||
else {
|
||||
if (WSTRNSTR((const char*)in,
|
||||
"ssh-rsa", inSz) == (const char*)in ||
|
||||
WSTRNSTR((const char*)in,
|
||||
"ecdsa-sha2-nistp", inSz) == (const char*)in) {
|
||||
*isPrivate = 0;
|
||||
format = WOLFSSH_FORMAT_SSH;
|
||||
in[inSz] = 0;
|
||||
}
|
||||
else {
|
||||
*isPrivate = 1;
|
||||
format = WOLFSSH_FORMAT_ASN1;
|
||||
}
|
||||
|
||||
ret = wolfSSH_ReadKey_buffer(in, inSz, format,
|
||||
out, outSz, outType, outTypeSz, heap);
|
||||
}
|
||||
|
||||
WFCLOSE(file);
|
||||
WFREE(in, heap, DYNTYPE_FILE);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int wolfSSH_CTX_SetBanner(WOLFSSH_CTX* ctx,
|
||||
const char* newBanner)
|
||||
{
|
||||
|
|
|
@ -163,6 +163,9 @@ enum {
|
|||
/* This is based on the 8192-bit DH key that is the max size. */
|
||||
#define MAX_KEX_KEY_SZ (WOLFSSH_DEFAULT_GEXDH_MAX / 8)
|
||||
#endif
|
||||
#ifndef WOLFSSH_MAX_FILE_SIZE
|
||||
#define WOLFSSH_MAX_FILE_SIZE (1024ul * 1024ul * 4)
|
||||
#endif
|
||||
|
||||
WOLFSSH_LOCAL byte NameToId(const char*, word32);
|
||||
WOLFSSH_LOCAL const char* IdToName(byte);
|
||||
|
@ -744,6 +747,7 @@ enum WS_DynamicTypes {
|
|||
DYNTYPE_AGENT_ID,
|
||||
DYNTYPE_AGENT_KEY,
|
||||
DYNTYPE_AGENT_BUFFER,
|
||||
DYNTYPE_FILE,
|
||||
DYNTYPE_TEMP
|
||||
};
|
||||
|
||||
|
|
|
@ -222,6 +222,7 @@ extern "C" {
|
|||
#define WFTELL(s) ftell((s))
|
||||
#define WREWIND(s) rewind((s))
|
||||
#define WSEEK_END SEEK_END
|
||||
#define WBADFILE NULL
|
||||
#ifdef WOLFSSL_VXWORKS
|
||||
#define WUTIMES(f,t) (WS_SUCCESS)
|
||||
#else
|
||||
|
|
|
@ -80,6 +80,11 @@ WOLFSSH_API void wolfSSH_SetHighwaterCb(WOLFSSH_CTX*, word32,
|
|||
WOLFSSH_API void wolfSSH_SetHighwaterCtx(WOLFSSH*, void*);
|
||||
WOLFSSH_API void* wolfSSH_GetHighwaterCtx(WOLFSSH*);
|
||||
|
||||
WOLFSSH_API int wolfSSH_ReadKey_buffer(const byte*, word32, int,
|
||||
byte**, word32*, const byte**, word32*, void*);
|
||||
WOLFSSH_API int wolfSSH_ReadKey_file(const char*,
|
||||
byte**, word32*, const byte**, word32*, byte*, void*);
|
||||
|
||||
|
||||
#define WS_CHANNEL_ID_SELF 0
|
||||
#define WS_CHANNEL_ID_PEER 1
|
||||
|
@ -237,7 +242,8 @@ enum WS_EndpointTypes {
|
|||
enum WS_FormatTypes {
|
||||
WOLFSSH_FORMAT_ASN1,
|
||||
WOLFSSH_FORMAT_PEM,
|
||||
WOLFSSH_FORMAT_RAW
|
||||
WOLFSSH_FORMAT_RAW,
|
||||
WOLFSSH_FORMAT_SSH,
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue