Skip to content

Commit 3875f8e

Browse files
authored
Migrate to LibSSH-ESP32 (#22)
1 parent d914897 commit 3875f8e

31 files changed

+693
-999
lines changed

.gitmodules

+3-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
[submodule "components/wolfssl"]
2-
path = components/wolfssl
3-
url = https://github.com/buglloc/wolfssl-idf.git
4-
[submodule "components/wolfssh"]
5-
path = components/wolfssh
6-
url = https://github.com/buglloc/wolfssh-idf.git
1+
[submodule "components/LibSSH-ESP32"]
2+
path = components/LibSSH-ESP32
3+
url = https://github.com/buglloc/LibSSH-ESP32.git

CMakeLists.txt

-2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
# The following five lines of boilerplate have to be in your project's
44
# CMakeLists in this exact order for cmake to work correctly
55
cmake_minimum_required(VERSION 3.5)
6-
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS")
7-
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -DWOLFSSL_USER_SETTINGS")
86

97
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
108
project(BoundBoxESP)

components/LibSSH-ESP32

Submodule LibSSH-ESP32 added at 9afa3fe

components/blob/CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ SRCS
55
"src/hex.cc"
66
INCLUDE_DIRS
77
"include"
8-
REQUIRES
9-
wolfssl
8+
PRIV_REQUIRES
9+
mbedtls
1010
)

components/blob/include/blob/hash.h

+9-14
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22

33
#include <expected>
44

5-
#include "wolfssl_init.h"
6-
#include <wolfssl/wolfcrypt/hmac.h>
75

86
#include "bytes.h"
97
#include "errors.h"
108

9+
// fwd
10+
struct mbedtls_md_context_t;
11+
12+
1113
namespace Blob
1214
{
1315
enum class HashType: uint8_t
@@ -18,26 +20,19 @@ namespace Blob
1820
SHA512,
1921
};
2022

21-
struct HKDFConfig
22-
{
23-
const Blob::Bytes& Key;
24-
const Blob::Bytes& Salt;
25-
Blob::HashType HashType = HashType::SHA256;
26-
};
27-
28-
std::expected<Bytes, Error> HMACSum(const Blob::Bytes& key, const Blob::Bytes& msg, HashType hashType = HashType::SHA256);
29-
std::expected<Bytes, Error> HKDF(const Blob::Bytes& info, size_t outLen, const HKDFConfig& cfg);
30-
3123
class HMAC
3224
{
3325
public:
3426
explicit HMAC(const Blob::Bytes& key, HashType type = HashType::SHA256);
3527
Error Write(const Blob::Bytes& data);
3628
std::expected<Blob::Bytes, Error> Sum();
37-
3829
~HMAC();
30+
31+
public:
32+
static std::expected<Bytes, Error> Sum(const Blob::Bytes& key, const Blob::Bytes& msg, HashType hashType = HashType::SHA256);
33+
3934
private:
4035
Error err = Error::None;
41-
Hmac ctx;
36+
mbedtls_md_context_t* ctx = nullptr;
4237
};
4338
}

components/blob/include/blob/wolfssl_init.h

-3
This file was deleted.

components/blob/src/hash.cc

+87-100
Original file line numberDiff line numberDiff line change
@@ -1,124 +1,111 @@
11
#include "blob/hash.h"
2-
#include "blob/wolfssl_init.h"
32

43
#include <expected>
54

65

7-
namespace Blob
6+
#include <mbedtls/md.h>
7+
8+
9+
using namespace Blob;
10+
11+
HMAC::HMAC(const Bytes& key, HashType hashType)
812
{
9-
std::expected<Bytes, Error> HMACSum(const Bytes& key, const Bytes& msg, HashType type)
10-
{
11-
HMAC hmac(key, type);
12-
Error err = hmac.Write(msg);
13-
if (err != Error::None) {
14-
return std::unexpected<Error>(err);
15-
}
16-
17-
return hmac.Sum();
13+
const mbedtls_md_info_t* mdInfo = nullptr;
14+
switch (hashType) {
15+
case HashType::SHA1:
16+
mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);
17+
break;
18+
case HashType::SHA256:
19+
mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
20+
break;
21+
case HashType::SHA512:
22+
mdInfo = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
23+
break;
24+
default:
25+
err = Error::Unsupported;
26+
return;
1827
}
1928

20-
std::expected<Bytes, Error> HKDF(const Bytes& key, const Bytes& salt, const Bytes& info, size_t outLen, HashType hashType = HashType::SHA256)
21-
{
22-
int wcType;
23-
switch (hashType)
24-
{
25-
case HashType::SHA1:
26-
wcType = WC_SHA;
27-
break;
28-
case HashType::SHA256:
29-
wcType = WC_SHA256;
30-
break;
31-
case HashType::SHA512:
32-
wcType = WC_SHA512;
33-
break;
34-
35-
default:
36-
return std::unexpected<Error>{Error::Unsupported};
37-
}
38-
39-
Bytes out(outLen, '\xff');
40-
int ret = wc_HKDF(wcType, key.c_str(), key.size(), salt.c_str(), salt.size(), info.c_str(), info.size(), out.data(), outLen);
41-
if (ret != 0) {
42-
return std::unexpected<Error>{Error::ShitHappens};
43-
}
44-
45-
return out;
29+
if (mdInfo == nullptr) {
30+
err = Error::Unsupported;
31+
return;
4632
}
4733

48-
HMAC::HMAC(const Bytes& key, HashType hashType)
49-
{
50-
int wcType;
51-
switch (hashType)
52-
{
53-
case HashType::SHA1:
54-
wcType = WC_SHA;
55-
break;
56-
case HashType::SHA256:
57-
wcType = WC_SHA256;
58-
break;
59-
case HashType::SHA512:
60-
wcType = WC_SHA512;
61-
break;
62-
63-
default:
64-
err = Error::Unsupported;
65-
return;
66-
}
67-
68-
int ret = wc_HmacInit(&ctx, nullptr, INVALID_DEVID);
69-
if (ret != 0) {
70-
err = Error::InitFailed;
71-
return;
72-
}
73-
74-
ret = wc_HmacSetKey(&ctx, wcType, key.c_str(), key.size());
75-
if (ret != 0) {
76-
err = Error::InvalidKey;
77-
wc_HmacFree(&ctx);
78-
return;
79-
}
34+
ctx = static_cast<mbedtls_md_context_t*>(malloc(sizeof(mbedtls_md_context_t)));
35+
if (ctx == nullptr) {
36+
err = Error::ShitHappens;
37+
return;
8038
}
8139

82-
Error HMAC::Write(const Bytes& data)
83-
{
84-
if (err != Error::None) {
85-
return err;
86-
}
40+
mbedtls_md_init(ctx);
41+
int rc = mbedtls_md_setup(ctx, mdInfo, 1);
42+
if (rc != 0) {
43+
mbedtls_md_free(ctx);
44+
free(ctx);
45+
err = Error::InitFailed;
46+
return;
47+
}
8748

88-
int ret = wc_HmacUpdate(&ctx, data.c_str(), data.size());
89-
if (ret != 0) {
90-
return Error::ShitHappens;
91-
}
49+
rc = mbedtls_md_hmac_starts(ctx, key.c_str(), key.size());
50+
if (rc != 0) {
51+
mbedtls_md_free(ctx);
52+
free(ctx);
53+
err = Error::InitFailed;
54+
return;
55+
}
56+
}
9257

93-
return Error::None;
58+
Error HMAC::Write(const Bytes& data)
59+
{
60+
if (err != Error::None) {
61+
return err;
9462
}
9563

96-
std::expected<Bytes, Error> HMAC::Sum()
97-
{
98-
if (err != Error::None) {
99-
return std::unexpected<Error>{err};
100-
}
64+
if (mbedtls_md_hmac_update(ctx, data.c_str(), data.length())) {
65+
return Error::ShitHappens;
66+
}
10167

102-
size_t hashLen = wc_HmacSizeByType(ctx.macType);
103-
if (hashLen <= 0) {
104-
return std::unexpected<Error>{Error::ShitHappens};
105-
}
68+
return Error::None;
69+
}
10670

107-
Bytes out(hashLen, '\xff');
108-
int ret = wc_HmacFinal(&ctx, out.data());
109-
if (ret != 0) {
110-
return std::unexpected<Error>{Error::ShitHappens};
111-
}
71+
std::expected<Bytes, Error> HMAC::Sum()
72+
{
73+
if (err != Error::None) {
74+
return std::unexpected<Error>{err};
75+
}
11276

113-
return out;
77+
size_t hashLen = static_cast<size_t>(mbedtls_md_get_size(mbedtls_md_info_from_ctx(ctx)));
78+
if (hashLen == 0) {
79+
return std::unexpected<Error>{Error::ShitHappens};
11480
}
11581

116-
HMAC::~HMAC()
117-
{
118-
if (err != Error::None) {
119-
return;
120-
}
82+
Bytes out(hashLen, '\xff');
83+
int ret = mbedtls_md_hmac_finish(ctx, out.data());
84+
if (ret != 0) {
85+
return std::unexpected<Error>{Error::ShitHappens};
86+
}
87+
88+
return out;
89+
}
90+
91+
HMAC::~HMAC()
92+
{
93+
if (ctx == nullptr) {
94+
return;
95+
}
96+
97+
mbedtls_md_free(ctx);
98+
free(ctx);
99+
ctx = nullptr;
100+
}
121101

122-
wc_HmacFree(&ctx);
102+
std::expected<Bytes, Error> HMAC::Sum(const Bytes& key, const Bytes& msg, HashType type)
103+
{
104+
HMAC hmac(key, type);
105+
Error err = hmac.Write(msg);
106+
if (err != Error::None) {
107+
return std::unexpected<Error>(err);
123108
}
109+
110+
return hmac.Sum();
124111
}

components/ssh/CMakeLists.txt

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
idf_component_register(
22
SRCS
3-
"src/auth.cc"
3+
"src/auth_provider.cc"
4+
"src/keyring.cc"
45
"src/keys.cc"
56
"src/server.cc"
67
"src/stream.cc"
78
INCLUDE_DIRS
89
"include"
910
REQUIRES
10-
blob
11+
blob LibSSH-ESP32
1112
PRIV_REQUIRES
12-
wolfssh wolfssl lwip defer
13+
lwip defer
1314
)

components/ssh/Kconfig

+12
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ menu "SSH"
1818
int "Stream buf size"
1919
default 4096
2020

21+
config SSH_STREAM_POLL_TIMEOUT
22+
int "Stream buf size"
23+
default 100
24+
25+
config SSH_STREAM_READ_TIMEOUT
26+
int "Stream buf size"
27+
default 5000
28+
2129
config SSH_CHANNEL_INITIAL_WINDOW
2230
int "Channel initial window"
2331
default 1024
@@ -26,4 +34,8 @@ menu "SSH"
2634
int "Channel max packet size"
2735
default 32768
2836

37+
config SSH_AUTH_RETRIES
38+
int "Auth retries"
39+
default 10
40+
2941
endmenu

components/ssh/include/ssh/auth_provider.h

+6-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
#include <expected>
66

77
#include <blob/bytes.h>
8+
89
#include "common.h"
10+
#include "keyring.h"
11+
912

1013
namespace SSH
1114
{
@@ -31,11 +34,11 @@ namespace SSH
3134
public:
3235
AuthProvider() = default;
3336
Error Initialize(const ServerConfig& cfg);
34-
bool Authenticate(const std::string_view user, const Blob::Bytes& key) const;
37+
bool Authenticate(const std::string_view user, const ssh_key key) const;
3538
UserRole Role(const std::string_view user) const;
3639

3740
private:
3841
std::string rootUser;
39-
std::vector<std::string> rootFingerprints;
42+
Keyring rootKeyring;
4043
};
41-
}
44+
}

components/ssh/include/ssh/common.h

+7-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
#include <stdint.h>
44

5+
#include "libssh_esp.h"
6+
7+
58

69
namespace SSH
710
{
@@ -10,16 +13,19 @@ namespace SSH
1013
None = 0,
1114
MalformedKey,
1215
Unsupported,
16+
InvalidState,
1317
Internal,
1418
ShitHappens
1519
};
1620

1721
enum class ListenError: uint8_t
1822
{
1923
None = 0,
20-
Sock,
2124
Bind,
25+
Listen,
2226
Accept,
27+
Auth,
28+
Internal,
2329
Unsupported,
2430
ShitHappens
2531
};

0 commit comments

Comments
 (0)