Skip to content

Commit 13e5254

Browse files
ejohnstownJacobBarthelmeh
authored andcommitted
X.509 Certificate Support
1. Quality of Life improvements to echoserver: command line user config 2. adding policy checking
1 parent a8fa38d commit 13e5254

4 files changed

Lines changed: 345 additions & 57 deletions

File tree

examples/echoserver/echoserver.c

Lines changed: 195 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <wolfssl/wolfcrypt/hash.h>
3535
#include <wolfssl/wolfcrypt/coding.h>
3636
#include <wolfssl/wolfcrypt/wc_port.h>
37+
#include <wolfssl/wolfcrypt/asn_public.h>
3738
#include <wolfssh/ssh.h>
3839
#include <wolfssh/internal.h>
3940
#include <wolfssh/wolfsftp.h>
@@ -1445,6 +1446,39 @@ static int load_key(byte isEcc, byte* buf, word32 bufSz)
14451446
}
14461447

14471448

1449+
typedef struct StrList {
1450+
const char* str;
1451+
struct StrList* next;
1452+
} StrList;
1453+
1454+
1455+
static StrList* StrListAdd(StrList* list, const char* str)
1456+
{
1457+
if (str != NULL) {
1458+
StrList* newStr = (StrList*)WMALLOC(sizeof *newStr, NULL, 0);
1459+
1460+
if (newStr != NULL) {
1461+
newStr->str = str;
1462+
newStr->next = list;
1463+
list = newStr;
1464+
}
1465+
}
1466+
1467+
return list;
1468+
}
1469+
1470+
static void StrListFree(StrList* list)
1471+
{
1472+
StrList* curStr;
1473+
1474+
while (list != NULL) {
1475+
curStr = list;
1476+
list = list->next;
1477+
WFREE(curStr, NULL, 0);
1478+
}
1479+
}
1480+
1481+
14481482
/* Map user names to passwords */
14491483
/* Use arrays for username and p. The password or public key can
14501484
* be hashed and the hash stored here. Then I won't need the type. */
@@ -1508,6 +1542,8 @@ static const char samplePasswordBuffer[] =
15081542
"jack:fetchapail\n";
15091543

15101544

1545+
#if 0
1546+
#ifndef NO_FILESYSTEM
15111547
#ifndef WOLFSSH_NO_ECC
15121548
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
15131549
static const char samplePublicKeyEccBuffer[] =
@@ -1547,6 +1583,11 @@ static const char samplePublicKeyRsaBuffer[] =
15471583
"biE57dK6BrH5iZwVLTQKux31uCJLPhiktI3iLbdlGZEctJkTasfVSsUizwVIyRjhVKmbdI"
15481584
"RGwkU38D043AR1h0mUoGCPIKuqcFMf gretel\n";
15491585
#endif
1586+
#endif /* NO_FILESYSTEM */
1587+
#endif
1588+
1589+
1590+
#ifdef WOLFSSH_ALLOW_USERAUTH_NONE
15501591

15511592
static const char sampleNoneBuffer[] =
15521593
"holmes\n"
@@ -1587,6 +1628,7 @@ static int LoadNoneBuffer(byte* buf, word32 bufSz, PwMapList* list)
15871628
return 0;
15881629
}
15891630

1631+
#endif /* WOLFSSH_ALLOW_USERAUTH_NONE */
15901632

15911633
static int LoadPasswordBuffer(byte* buf, word32 bufSz, PwMapList* list)
15921634
{
@@ -1714,24 +1756,102 @@ static int LoadPublicKeyBuffer(byte* buf, word32 bufSz, PwMapList* list)
17141756
}
17151757

17161758

1717-
#ifdef WOLFSSH_CERTS
1718-
static int LoadCertBuffer(byte* buf, word32 bufSz, PwMapList* list)
1759+
static int LoadPasswdList(StrList* strList, PwMapList* mapList)
17191760
{
1720-
if (list == NULL)
1721-
return -1;
1761+
char names[256];
1762+
char* passwd;
1763+
int count = 0;
17221764

1723-
if (buf == NULL || bufSz == 0)
1724-
return 0;
1765+
while (strList) {
1766+
WSTRNCPY(names, strList->str, sizeof names);
1767+
passwd = WSTRCHR(names, ':');
1768+
if (passwd != NULL) {
1769+
*passwd = 0;
1770+
passwd++;
17251771

1726-
if (PwMapNew(list,
1727-
WOLFSSH_USERAUTH_PUBLICKEY,
1728-
(const byte*)"orange", 6, buf, bufSz) == NULL ) {
1729-
return -1;
1772+
PwMapNew(mapList, WOLFSSH_USERAUTH_PASSWORD,
1773+
(byte*)names, (word32)WSTRLEN(names),
1774+
(byte*)passwd, (word32)WSTRLEN(passwd));
1775+
}
1776+
else {
1777+
fprintf(stderr, "Ignoring password: %s\n", names);
1778+
}
1779+
1780+
strList = strList->next;
1781+
count++;
17301782
}
17311783

1732-
return 0;
1784+
return count;
1785+
}
1786+
1787+
1788+
static int LoadPubKeyList(StrList* strList, int format, PwMapList* mapList)
1789+
{
1790+
char names[256];
1791+
char* fileName;
1792+
byte* buf;
1793+
word32 bufSz;
1794+
int count = 0;
1795+
1796+
while (strList) {
1797+
buf = NULL;
1798+
bufSz = 0;
1799+
1800+
WSTRNCPY(names, strList->str, sizeof names);
1801+
fileName = WSTRCHR(names, ':');
1802+
if (fileName != NULL) {
1803+
*fileName = 0;
1804+
fileName++;
1805+
1806+
load_file(fileName, NULL, &bufSz);
1807+
buf = (byte*)WMALLOC(bufSz, NULL, 0);
1808+
bufSz = load_file(fileName, buf, &bufSz);
1809+
if (bufSz > 0) {
1810+
if (format == WOLFSSH_FORMAT_SSH) {
1811+
const byte* type = NULL;
1812+
byte* out = NULL;
1813+
word32 typeSz, outSz;
1814+
1815+
wolfSSH_ReadKey_buffer(buf, bufSz, WOLFSSH_FORMAT_SSH,
1816+
&out, &outSz, &type, &typeSz, NULL);
1817+
1818+
(void)type;
1819+
(void)typeSz;
1820+
1821+
WFREE(buf, NULL, 0);
1822+
buf = out;
1823+
bufSz = outSz;
1824+
}
1825+
else if (format == WOLFSSH_FORMAT_PEM) {
1826+
byte* out = NULL;
1827+
word32 outSz;
1828+
1829+
out = (byte*)WMALLOC(bufSz, NULL, 0);
1830+
outSz = wc_CertPemToDer(buf, bufSz, out, bufSz, CERT_TYPE);
1831+
1832+
WFREE(buf, NULL, 0);
1833+
buf = out;
1834+
bufSz = outSz;
1835+
}
1836+
1837+
PwMapNew(mapList, WOLFSSH_USERAUTH_PUBLICKEY,
1838+
(byte*)names, (word32)WSTRLEN(names), buf, bufSz);
1839+
}
1840+
else {
1841+
fprintf(stderr, "File error: %s\n", names);
1842+
}
1843+
}
1844+
else {
1845+
fprintf(stderr, "Ignoring key: %s\n", names);
1846+
}
1847+
1848+
WFREE(buf, NULL, 0);
1849+
strList = strList->next;
1850+
count++;
1851+
}
1852+
1853+
return count;
17331854
}
1734-
#endif
17351855

17361856

17371857
static int wsUserAuth(byte authType,
@@ -1847,7 +1967,16 @@ static void ShowUsage(void)
18471967
#ifdef WOLFSSH_SFTP
18481968
printf(" -d <string> set the home directory for SFTP connections\n");
18491969
#endif
1850-
printf(" -j <file> load in a public key to accept from peer\n");
1970+
printf(" -j <file> load in a SSH public key to accept from peer\n"
1971+
" (user assumed in comment)\n");
1972+
printf(" -I <name>:<file>\n"
1973+
" load in a SSH public key to accept from peer\n");
1974+
printf(" -J <name>:<file>\n"
1975+
" load in an X.509 PEM cert to accept from peer\n");
1976+
printf(" -K <name>:<file>\n"
1977+
" load in an X.509 DER cert to accept from peer\n");
1978+
printf(" -P <name>:<password>\n"
1979+
" add password to accept from peer\n");
18511980
#ifdef WOLFSSH_CERTS
18521981
printf(" -a <file> load in a root CA certificate file\n");
18531982
#endif
@@ -1875,6 +2004,10 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
18752004
func_args* serverArgs = (func_args*)args;
18762005
WOLFSSH_CTX* ctx = NULL;
18772006
PwMapList pwMapList;
2007+
StrList* sshPubKeyList = NULL;
2008+
StrList* pemPubKeyList = NULL;
2009+
StrList* derPubKeyList = NULL;
2010+
StrList* passwdList = NULL;
18782011
WS_SOCKET_T listenFd = 0;
18792012
word32 defaultHighwater = EXAMPLE_HIGHWATER_MARK;
18802013
word32 threadCount = 0;
@@ -1897,7 +2030,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
18972030
serverArgs->return_code = 0;
18982031

18992032
if (argc > 0) {
1900-
while ((ch = mygetopt(argc, argv, "?1a:d:efEp:R:Nj:")) != -1) {
2033+
while ((ch = mygetopt(argc, argv, "?1a:d:efEp:R:Ni:j:I:J:K:P:")) != -1) {
19012034
switch (ch) {
19022035
case '?' :
19032036
ShowUsage();
@@ -1955,6 +2088,22 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
19552088
userPubKey = myoptarg;
19562089
break;
19572090

2091+
case 'I':
2092+
sshPubKeyList = StrListAdd(sshPubKeyList, myoptarg);
2093+
break;
2094+
2095+
case 'J':
2096+
pemPubKeyList = StrListAdd(pemPubKeyList, myoptarg);
2097+
break;
2098+
2099+
case 'K':
2100+
derPubKeyList = StrListAdd(derPubKeyList, myoptarg);
2101+
break;
2102+
2103+
case 'P':
2104+
passwdList = StrListAdd(passwdList, myoptarg);
2105+
break;
2106+
19582107
default:
19592108
ShowUsage();
19602109
WEXIT(MY_EX_USAGE);
@@ -1980,6 +2129,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
19802129
userEcc = 0;
19812130
peerEcc = 0;
19822131
#endif
2132+
(void)userEcc;
19832133

19842134
if (wolfSSH_Init() != WS_SUCCESS) {
19852135
fprintf(stderr, "Couldn't initialize wolfSSH.\n");
@@ -2005,8 +2155,29 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
20052155
wolfSSH_CTX_SetFwdCb(ctx, wolfSSH_FwdDefaultActions, NULL);
20062156
#endif
20072157

2158+
if (sshPubKeyList) {
2159+
LoadPubKeyList(sshPubKeyList, WOLFSSH_FORMAT_SSH, &pwMapList);
2160+
StrListFree(sshPubKeyList);
2161+
sshPubKeyList = NULL;
2162+
}
2163+
if (pemPubKeyList) {
2164+
LoadPubKeyList(pemPubKeyList, WOLFSSH_FORMAT_PEM, &pwMapList);
2165+
StrListFree(pemPubKeyList);
2166+
pemPubKeyList = NULL;
2167+
}
2168+
if (derPubKeyList) {
2169+
LoadPubKeyList(derPubKeyList, WOLFSSH_FORMAT_ASN1, &pwMapList);
2170+
StrListFree(derPubKeyList);
2171+
derPubKeyList = NULL;
2172+
}
2173+
if (passwdList) {
2174+
LoadPasswdList(passwdList, &pwMapList);
2175+
StrListFree(passwdList);
2176+
passwdList = NULL;
2177+
}
2178+
20082179
{
2009-
const char* bufName = NULL;
2180+
//const char* bufName = NULL;
20102181
#ifndef WOLFSSH_SMALL_STACK
20112182
byte buf[EXAMPLE_KEYLOAD_BUFFER_SZ];
20122183
#endif
@@ -2055,30 +2226,10 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
20552226
}
20562227
load_file(userPubKey, userBuf, &userBufSz);
20572228
LoadPublicKeyBuffer(userBuf, userBufSz, &pwMapList);
2229+
WFREE(userBuf, NULL, 0);
20582230
}
20592231

20602232
#ifdef WOLFSSH_CERTS
2061-
{
2062-
byte* certBuf = NULL;
2063-
word32 certBufSz = 0;
2064-
const char* filename = "../ca/orange-cert.der";
2065-
2066-
load_file(filename, NULL, &certBufSz);
2067-
2068-
if (certBufSz == 0) {
2069-
fprintf(stderr,
2070-
"Couldn't find size of file %s.\n", filename);
2071-
WEXIT(EXIT_FAILURE);
2072-
}
2073-
2074-
certBuf = (byte*)WMALLOC(certBufSz, NULL, 0);
2075-
if (certBuf == NULL) {
2076-
fprintf(stderr, "WMALLOC failed\n");
2077-
WEXIT(EXIT_FAILURE);
2078-
}
2079-
load_file(filename, certBuf, &certBufSz);
2080-
LoadCertBuffer(certBuf, certBufSz, &pwMapList);
2081-
}
20822233
if (caCert) {
20832234
byte* certBuf = NULL;
20842235
word32 certBufSz = 0;
@@ -2113,6 +2264,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
21132264
keyLoadBuf[bufSz] = 0;
21142265
LoadPasswordBuffer(keyLoadBuf, bufSz, &pwMapList);
21152266

2267+
#if 0
21162268
if (userEcc) {
21172269
#ifndef WOLFSSH_NO_ECC
21182270
bufName = samplePublicKeyEccBuffer;
@@ -2130,10 +2282,13 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
21302282
LoadPublicKeyBuffer(keyLoadBuf, bufSz, &pwMapList);
21312283
}
21322284

2133-
bufSz = (word32)WSTRLEN(sampleNoneBuffer);
2134-
WMEMCPY(keyLoadBuf, sampleNoneBuffer, bufSz);
2135-
keyLoadBuf[bufSz] = 0;
2136-
LoadNoneBuffer(keyLoadBuf, bufSz, &pwMapList);
2285+
#ifdef WOLFSSH_ALLOW_USERAUTH_NONE
2286+
bufSz = (word32)WSTRLEN(sampleNoneBuffer);
2287+
WMEMCPY(keyLoadBuf, sampleNoneBuffer, bufSz);
2288+
keyLoadBuf[bufSz] = 0;
2289+
LoadNoneBuffer(keyLoadBuf, bufSz, &pwMapList);
2290+
#endif /* WOLFSSH_ALLOW_USERAUTH_NONE */
2291+
#endif
21372292

21382293
#ifdef WOLFSSH_SMALL_STACK
21392294
WFREE(keyLoadBuf, NULL, 0);

0 commit comments

Comments
 (0)