X.509 Certificate Support

1. Fix build error when building without certificates.
2. Add the root CA option to the echoserver usage.
3. Update the readme file to include the new certificate option.
4. Added command line option to load a CA cert into the echoserver.
pull/415/head
John Safranek 2022-02-09 16:08:20 -08:00 committed by JacobBarthelmeh
parent 93996f1942
commit 1405eeae62
20 changed files with 1217 additions and 99 deletions

View File

@ -22,6 +22,11 @@ On some systems the optional ldconfig command is needed after installing.
To use the key generation function in wolfSSH, wolfSSL will need to be
configured with keygen: `--enable-keygen`.
When using X.509 certificates for user authentication, wolfSSL must not be
built without TLS enabled. wolfSSH uses wolfSSL's certificate manager system
for X.509, including OCSP lookups. To allow OCSP, add `--enable-ocsp` to the
wolfSSL configure.
If the bulk of wolfSSL code isn't desired, wolfSSL can be configured with
the crypto only option: `--enable-cryptonly`.
@ -402,6 +407,7 @@ behavior, give the echoserver the command line option `-f`.
$ ./examples/echoserver/echoserver -f
POST-QUANTUM
============
@ -462,3 +468,24 @@ NOTE: when prompted, enter the password which is "upthehill".
You can type a line of text and when you press enter, the line will be echoed
back. Use CTRL-C to terminate the connection.
CERTIFICATE SUPPORT
===================
wolfSSH can accept X.509 certificates in place of just public keys when
authenticating a user. This feature is currently a work in process.
To compile wolfSSH with X.509 support, use the `--enable-certs` build option
or define `WOLFSSH_CERTS`:
$ ./configure --enable-certs
$ make
To provide a CA root certificate to validate a user's certificate, give the
echoserver the command line option `-a`.
$ ./examples/echoserver/echoserver -a ./keys/ca-cert.pem
The echoserver and client have a fake user named "john" whose certificate
will be used for authentication.

View File

@ -198,6 +198,11 @@ static word32 userPrivateKeyTypeSz = 0;
static byte isPrivate = 0;
#ifdef WOLFSSH_CERTS
static const byte publicKeyType[] = "x509v3-ecdsa-sha2-nistp256";
static const byte privateKeyType[] = "ecdsa-sha2-nistp256";
#endif
#ifndef WOLFSSH_NO_RSA
static const char* hanselPublicRsa =
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC9P3ZFowOsONXHD5MwWiCciXytBRZGho"
@ -392,7 +397,11 @@ static int wsUserAuth(byte authType,
/* in the case that the name is hansel or in the case that the user
* passed in a public key file, use public key auth */
if ((XSTRNCMP((char*)authData->username, "hansel",
authData->usernameSz) == 0) || pubKeyName != NULL) {
authData->usernameSz) == 0) ||
(XSTRNCMP((char*)authData->username, "john",
authData->usernameSz) == 0) ||
pubKeyName != NULL) {
if (authType == WOLFSSH_USERAUTH_PASSWORD) {
printf("rejecting password type with %s in favor of pub key\n",
(char*)authData->username);
@ -683,6 +692,62 @@ static THREAD_RET readPeer(void* in)
}
#endif /* !SINGLE_THREADED && !WOLFSSL_NUCLEUS */
#ifdef WOLFSSH_CERTS
static int load_der_file(const char* filename, byte** out, word32* outSz)
{
WFILE* file;
byte* in;
word32 inSz;
int ret;
if (filename == NULL || out == NULL || outSz == NULL)
return -1;
ret = WFOPEN(&file, filename, "rb");
if (ret != 0 || file == WBADFILE)
return -1;
if (WFSEEK(file, 0, WSEEK_END) != 0) {
WFCLOSE(file);
return -1;
}
inSz = (word32)WFTELL(file);
WREWIND(file);
if (inSz == 0) {
WFCLOSE(file);
return -1;
}
in = (byte*)WMALLOC(inSz, NULL, 0);
if (in == NULL) {
WFCLOSE(file);
return -1;
}
ret = (int)WFREAD(in, 1, inSz, file);
if (ret <= 0 || (word32)ret != inSz) {
ret = -1;
WFREE(in, NULL, 0);
in = 0;
inSz = 0;
}
else
ret = 0;
*out = in;
*outSz = inSz;
WFCLOSE(file);
return ret;
}
#endif /* WOLFSSH_CERTS */
#if defined(WOLFSSL_PTHREADS) && defined(WOLFSSL_TEST_GLOBAL_REQ)
static int callbackGlobalReq(WOLFSSH *ssh, void *buf, word32 sz, int reply, void *ctx)
@ -970,6 +1035,22 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
if (ret != 0) err_sys("Couldn't load private key file.");
}
#ifdef WOLFSSH_CERTS
if (XSTRCMP("john", username) == 0) {
ret = load_der_file("./keys/john-cert.der",
&userPublicKey, &userPublicKeySz);
if (ret != 0) err_sys("Couldn't load certificate file.");
ret = load_der_file("./keys/john-key.der",
&userPrivateKey, &userPrivateKeySz);
if (ret != 0) err_sys("Couldn't load private key file.");
userPublicKeyType = publicKeyType;
userPublicKeyTypeSz = (word32)WSTRLEN((const char*)publicKeyType);
userPrivateKeyType = privateKeyType;
userPrivateKeyTypeSz = (word32)WSTRLEN((const char*)privateKeyType);
}
else
#endif
if (pubKeyName == NULL) {
byte* p = userPublicKey;
userPublicKeySz = sizeof(userPublicKeyBuf);

View File

@ -1714,6 +1714,26 @@ static int LoadPublicKeyBuffer(byte* buf, word32 bufSz, PwMapList* list)
}
#ifdef WOLFSSH_CERTS
static int LoadCertBuffer(byte* buf, word32 bufSz, PwMapList* list)
{
if (list == NULL)
return -1;
if (buf == NULL || bufSz == 0)
return 0;
if (PwMapNew(list,
WOLFSSH_USERAUTH_PUBLICKEY,
(const byte*)"john", 4, buf, bufSz) == NULL ) {
return -1;
}
return 0;
}
#endif
static int wsUserAuth(byte authType,
WS_UserAuthData* authData,
void* ctx)
@ -1828,6 +1848,9 @@ static void ShowUsage(void)
printf(" -d <string> set the home directory for SFTP connections\n");
#endif
printf(" -j <file> load in a public key to accept from peer\n");
#ifdef WOLFSSH_CERTS
printf(" -a <file> load in a root CA certificate file\n");
#endif
}
@ -1865,13 +1888,16 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
const char* defaultSftpPath = NULL;
char nonBlock = 0;
char* userPubKey = NULL;
#ifdef WOLFSSH_CERTS
char* caCert = NULL;
#endif
int argc = serverArgs->argc;
char** argv = serverArgs->argv;
serverArgs->return_code = 0;
if (argc > 0) {
while ((ch = mygetopt(argc, argv, "?1d:efEp:R:Nj:")) != -1) {
while ((ch = mygetopt(argc, argv, "?1a:d:efEp:R:Nj:")) != -1) {
switch (ch) {
case '?' :
ShowUsage();
@ -1881,6 +1907,11 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
multipleConnections = 0;
break;
case 'a':
#ifdef WOLFSSH_CERTS
caCert = myoptarg;
#endif
break;
case 'e' :
userEcc = 1;
break;
@ -2026,6 +2057,57 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
LoadPublicKeyBuffer(userBuf, userBufSz, &pwMapList);
}
#ifdef WOLFSSH_CERTS
{
byte* certBuf = NULL;
word32 certBufSz = 0;
const char* filename = "./keys/john-cert.der";
load_file(filename, NULL, &certBufSz);
if (certBufSz == 0) {
fprintf(stderr,
"Couldn't find size of file %s.\n", filename);
WEXIT(EXIT_FAILURE);
}
certBuf = (byte*)WMALLOC(certBufSz, NULL, 0);
if (certBuf == NULL) {
fprintf(stderr, "WMALLOC failed\n");
WEXIT(EXIT_FAILURE);
}
load_file(filename, certBuf, &certBufSz);
LoadCertBuffer(certBuf, certBufSz, &pwMapList);
}
if (caCert) {
byte* certBuf = NULL;
word32 certBufSz = 0;
int ret = 0;
load_file(caCert, NULL, &certBufSz);
if (certBufSz == 0) {
fprintf(stderr,
"Couldn't find size of file %s.\n", caCert);
WEXIT(EXIT_FAILURE);
}
certBuf = (byte*)WMALLOC(certBufSz, NULL, 0);
if (certBuf == NULL) {
fprintf(stderr, "WMALLOC failed\n");
WEXIT(EXIT_FAILURE);
}
load_file(caCert, certBuf, &certBufSz);
ret = wolfSSH_CTX_AddRootCert_buffer(ctx, certBuf, certBufSz,
WOLFSSH_FORMAT_ASN1);
if (ret != 0) {
fprintf(stderr, "Couldn't add root cert\n");
WEXIT(EXIT_FAILURE);
}
WFREE(certBuf, NULL, 0);
}
#endif
bufSz = (word32)WSTRLEN(samplePasswordBuffer);
WMEMCPY(keyLoadBuf, samplePasswordBuffer, bufSz);
keyLoadBuf[bufSz] = 0;

Binary file not shown.

View File

@ -0,0 +1,53 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
29:bf:2b:cd:bf:55:54:49:85:b3:69:4e:e1:85:37:79:1e:81:f9:c2
Signature Algorithm: ecdsa-with-SHA256
Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Development, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Validity
Not Before: Feb 15 12:50:24 2022 GMT
Not After : Nov 11 12:50:24 2024 GMT
Subject: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Development, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:02:d3:d9:6e:d6:01:8e:45:c8:b9:90:31:e5:c0:
4c:e3:9e:ad:29:38:98:ba:10:d6:e9:09:2a:80:a9:
2e:17:2a:b9:8a:bf:33:83:46:e3:95:0b:e4:77:40:
b5:3b:43:45:33:0f:61:53:7c:37:44:c1:cb:fc:80:
ca:e8:43:ea:a7
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Subject Key Identifier:
56:8E:9A:C3:F0:42:DE:18:B9:45:55:6E:F9:93:CF:EA:C3:F3:A5:21
X509v3 Authority Key Identifier:
keyid:56:8E:9A:C3:F0:42:DE:18:B9:45:55:6E:F9:93:CF:EA:C3:F3:A5:21
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Key Usage: critical
Digital Signature, Certificate Sign, CRL Sign
Signature Algorithm: ecdsa-with-SHA256
30:44:02:20:78:ed:4c:1c:a7:2d:b3:35:0b:1d:46:a3:37:31:
0b:8a:05:39:c8:28:31:58:35:f1:98:f7:4b:72:c0:4f:e6:7f:
02:20:02:f2:09:2b:3a:e1:36:92:bf:58:6a:03:12:2d:79:e6:
bd:06:45:61:b9:0e:39:e1:9c:f0:a8:2e:0b:1e:8c:b2
-----BEGIN CERTIFICATE-----
MIIClDCCAjugAwIBAgIUKb8rzb9VVEmFs2lO4YU3eR6B+cIwCgYIKoZIzj0EAwIw
gZcxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdT
ZWF0dGxlMRAwDgYDVQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtEZXZlbG9wbWVudDEY
MBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdv
bGZzc2wuY29tMB4XDTIyMDIxNTEyNTAyNFoXDTI0MTExMTEyNTAyNFowgZcxCzAJ
BgNVBAYTAlVTMRMwEQYDVQQIDApXYXNoaW5ndG9uMRAwDgYDVQQHDAdTZWF0dGxl
MRAwDgYDVQQKDAd3b2xmU1NMMRQwEgYDVQQLDAtEZXZlbG9wbWVudDEYMBYGA1UE
AwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wu
Y29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEAtPZbtYBjkXIuZAx5cBM456t
KTiYuhDW6QkqgKkuFyq5ir8zg0bjlQvkd0C1O0NFMw9hU3w3RMHL/IDK6EPqp6Nj
MGEwHQYDVR0OBBYEFFaOmsPwQt4YuUVVbvmTz+rD86UhMB8GA1UdIwQYMBaAFFaO
msPwQt4YuUVVbvmTz+rD86UhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
AgGGMAoGCCqGSM49BAMCA0cAMEQCIHjtTBynLbM1Cx1GozcxC4oFOcgoMVg18Zj3
S3LAT+Z/AiAC8gkrOuE2kr9YagMSLXnmvQZFYbkOOeGc8KguCx6Msg==
-----END CERTIFICATE-----

BIN
keys/john-cert.der 100644

Binary file not shown.

15
keys/john-cert.pem 100644
View File

@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICSzCCAfGgAwIBAgIQUg79CEuTa/LBX88kspbmFzAKBggqhkjOPQQDAjCBlzEL
MAkGA1UEBhMCVVMxEzARBgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0
bGUxEDAOBgNVBAoMB3dvbGZTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50MRgwFgYD
VQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNz
bC5jb20wIhgPMjAyMjAyMjYyMjEyMzNaGA8yMDIzMDcxMjIyMTIzM1owgZExCzAJ
BgNVBAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTEUMBIGA1UE
CgwLd29sZlNTTCBJbmMxFDASBgNVBAsMC0RldmVsb3BtZW50MRYwFAYDVQQDDA1K
b2huIFNhZnJhbmVrMR8wHQYJKoZIhvcNAQkBFhBqb2huQHdvbGZzc2wuY29tMFkw
EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEEtwW0ReBpgLwDxGQuzKFZg52AGKsquO5
Jhwq4ij43dh5P8ACXtHRxf48Y/UfrhNLacro7fQ2umLgocgYEEtV4aMfMB0wGwYD
VR0RBBQwEoEQam9obkB3b2xmc3NsLmNvbTAKBggqhkjOPQQDAgNIADBFAiEAtsaS
gxyAAWzJ+nSku+VnVz821mL5tnw2rxTUKnWYg10CIE8/UF6OKGcJMJcUpTPc4G7F
IYffUYF+T1BAhyEwTsxx
-----END CERTIFICATE-----

BIN
keys/john-key.der 100644

Binary file not shown.

View File

@ -0,0 +1,9 @@
ASN1 OID: prime256v1
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIEkbklf9L+5N9RuSnwmbgv/yCarqVK3j+PagHLtcDsw7oAoGCCqGSM49
AwEHoUQDQgAEEtwW0ReBpgLwDxGQuzKFZg52AGKsquO5Jhwq4ij43dh5P8ACXtHR
xf48Y/UfrhNLacro7fQ2umLgocgYEEtV4Q==
-----END EC PRIVATE KEY-----

View File

@ -0,0 +1 @@
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBLcFtEXgaYC8A8RkLsyhWYOdgBirKrjuSYcKuIo+N3YeT/AAl7R0cX+PGP1H64TS2nK6O30Nrpi4KHIGBBLVeE=

Binary file not shown.

View File

@ -0,0 +1,57 @@
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 3 (0x3)
Signature Algorithm: ecdsa-with-SHA256
Issuer: C = US, ST = Washington, L = Seattle, O = wolfSSL, OU = Development, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Validity
Not Before: Dec 20 23:07:25 2021 GMT
Not After : Sep 15 23:07:25 2024 GMT
Subject: C = US, ST = Washington, L = Seattle, O = Eliptic, OU = ECC, CN = www.wolfssl.com, emailAddress = info@wolfssl.com
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:bb:33:ac:4c:27:50:4a:c6:4a:a5:04:c3:3c:de:
9f:36:db:72:2d:ce:94:ea:2b:fa:cb:20:09:39:2c:
16:e8:61:02:e9:af:4d:d3:02:93:9a:31:5b:97:92:
21:7f:f0:cf:18:da:91:11:02:34:86:e8:20:58:33:
0b:80:34:89:d8
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Subject Key Identifier:
5D:5D:26:EF:AC:7E:36:F9:9B:76:15:2B:4A:25:02:23:EF:B2:89:30
X509v3 Authority Key Identifier:
keyid:56:8E:9A:C3:F0:42:DE:18:B9:45:55:6E:F9:93:CF:EA:C3:F3:A5:21
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Key Usage: critical
Digital Signature, Key Encipherment, Key Agreement
X509v3 Extended Key Usage:
TLS Web Server Authentication
Netscape Cert Type:
SSL Server
Signature Algorithm: ecdsa-with-SHA256
30:44:02:20:5a:67:b9:ee:02:34:27:1b:d4:c4:35:7b:ed:59:
8e:63:c4:8a:b7:e9:92:c1:8a:76:b0:8b:cd:24:49:78:ba:ef:
02:20:29:b8:b6:5f:83:f7:56:6a:f1:4d:d9:9f:52:2a:f9:8f:
53:14:49:8b:5f:5e:87:af:7f:ca:2e:e0:d8:e7:75:0c
-----BEGIN CERTIFICATE-----
MIICoDCCAkegAwIBAgIBAzAKBggqhkjOPQQDAjCBlzELMAkGA1UEBhMCVVMxEzAR
BgNVBAgMCldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB3dv
bGZTU0wxFDASBgNVBAsMC0RldmVsb3BtZW50MRgwFgYDVQQDDA93d3cud29sZnNz
bC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjExMjIw
MjMwNzI1WhcNMjQwOTE1MjMwNzI1WjCBjzELMAkGA1UEBhMCVVMxEzARBgNVBAgM
Cldhc2hpbmd0b24xEDAOBgNVBAcMB1NlYXR0bGUxEDAOBgNVBAoMB0VsaXB0aWMx
DDAKBgNVBAsMA0VDQzEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZI
hvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD
QgAEuzOsTCdQSsZKpQTDPN6fNttyLc6U6iv6yyAJOSwW6GEC6a9N0wKTmjFbl5Ih
f/DPGNqREQI0huggWDMLgDSJ2KOBiTCBhjAdBgNVHQ4EFgQUXV0m76x+NvmbdhUr
SiUCI++yiTAwHwYDVR0jBBgwFoAUVo6aw/BC3hi5RVVu+ZPP6sPzpSEwDAYDVR0T
AQH/BAIwADAOBgNVHQ8BAf8EBAMCA6gwEwYDVR0lBAwwCgYIKwYBBQUHAwEwEQYJ
YIZIAYb4QgEBBAQDAgZAMAoGCCqGSM49BAMCA0cAMEQCIFpnue4CNCcb1MQ1e+1Z
jmPEirfpksGKdrCLzSRJeLrvAiApuLZfg/dWavFN2Z9SKvmPUxRJi19eh69/yi7g
2Od1DA==
-----END CERTIFICATE-----

View File

@ -0,0 +1,9 @@
ASN1 OID: prime256v1
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIEW2aQJznGyFoThbcujox6zEA41TNQT6bCjcNI3hqAmMoAoGCCqGSM49
AwEHoUQDQgAEuzOsTCdQSsZKpQTDPN6fNttyLc6U6iv6yyAJOSwW6GEC6a9N0wKT
mjFbl5Ihf/DPGNqREQI0huggWDMLgDSJ2A==
-----END EC PRIVATE KEY-----

View File

@ -76,13 +76,37 @@
#endif
struct WOLFSSH_CERTMAN {
void* heap;
WOLFSSL_CERT_MANAGER* cm;
};
static WOLFSSH_CERTMAN* _CertMan_init(WOLFSSH_CERTMAN* cm, void* heap)
{
(void)heap;
WLOG_ENTER();
if (cm != NULL) {
WMEMSET(cm, 0, sizeof *cm);
cm->cm = wolfSSL_CertManagerNew_ex(heap);
if (cm->cm != NULL) {
int ret;
ret = wolfSSL_CertManagerEnableOCSP(cm->cm,
WOLFSSL_OCSP_CHECKALL);
if (ret == WOLFSSL_SUCCESS) {
WLOG(WS_LOG_CERTMAN, "Enabled OCSP");
}
else {
WLOG(WS_LOG_CERTMAN, "Couldn't enable OCSP");
wolfSSL_CertManagerFree(cm->cm);
cm = NULL;
}
}
else {
cm = NULL;
}
}
WLOG_LEAVE_PTR(cm);
@ -96,6 +120,9 @@ static void _CertMan_ResourceFree(WOLFSSH_CERTMAN* cm, void* heap)
WLOG_ENTER();
if (cm != NULL) {
if (cm->cm != NULL) {
wolfSSL_CertManagerFree(cm->cm);
}
WMEMSET(cm, 0, sizeof *cm);
}
@ -137,17 +164,33 @@ void wolfSSH_CERTMAN_free(WOLFSSH_CERTMAN* cm)
}
WOLFSSH_CERTMAN* wolfSSH_CERTMAN_init(WOLFSSH_CERTMAN* cm, void* heap)
int wolfSSH_CERTMAN_LoadRootCA_buffer(WOLFSSH_CERTMAN* cm,
const unsigned char* rootCa, word32 rootCaSz)
{
int ret = WS_SUCCESS;
WLOG_ENTER();
if (cm != NULL) {
cm = _CertMan_init(cm, heap);
}
ret = wolfSSL_CertManagerLoadCABuffer(cm->cm, rootCa, rootCaSz,
WOLFSSL_FILETYPE_ASN1);
WLOG_LEAVE_PTR(cm);
return cm;
WLOG_LEAVE(ret);
return ret;
}
int wolfSSH_CERTMAN_VerifyCert_buffer(WOLFSSH_CERTMAN* cm,
const unsigned char* cert, word32 certSz)
{
int ret = WS_SUCCESS;
WLOG_ENTER();
ret = wolfSSL_CertManagerVerifyBuffer(cm->cm, cert, certSz,
WOLFSSL_FILETYPE_ASN1);
WLOG_LEAVE(ret);
return ret;
}
#endif /* WOLFSSH_CERTS */

File diff suppressed because it is too large Load Diff

View File

@ -1680,6 +1680,39 @@ int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX* ctx,
}
#ifdef WOLFSSH_CERTS
int wolfSSH_CTX_UseCert_buffer(WOLFSSH_CTX* ctx,
const byte* cert, word32 certSz, int format)
{
int ret = WS_SUCCESS;
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_UseCert_buffer()");
ret = wolfSSH_ProcessBuffer(ctx, cert, certSz, format, BUFTYPE_CERT);
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_CTX_UseCert_buffer(), ret = %d", ret);
return ret;
}
int wolfSSH_CTX_AddRootCert_buffer(WOLFSSH_CTX* ctx,
const byte* cert, word32 certSz, int format)
{
int ret = WS_SUCCESS;
WLOG(WS_LOG_DEBUG, "Entering wolfSSH_CTX_AddRootCert_buffer()");
ret = wolfSSH_ProcessBuffer(ctx, cert, certSz, format, BUFTYPE_CA);
WLOG(WS_LOG_DEBUG,
"Leaving wolfSSH_CTX_AddRootCert_buffer(), ret = %d", ret);
return ret;
}
#endif /* WOLFSSH_CERTS */
int wolfSSH_CTX_SetWindowPacketSize(WOLFSSH_CTX* ctx,
word32 windowSz, word32 maxPacketSz)
{

View File

@ -659,6 +659,95 @@ static void test_wolfSSH_CTX_UsePrivateKey_buffer(void)
}
#ifdef WOLFSSH_CERTS
static int load_file(const char* filename, byte** buf, word32* bufSz)
{
FILE* f = NULL;
int ret = 0;
if (filename == NULL || buf == NULL || bufSz == NULL)
ret = -1;
if (ret == 0) {
f = fopen(filename, "rb");
if (f == NULL)
ret = -2;
}
if (ret == 0) {
fseek(f, 0, XSEEK_END);
*bufSz = (word32)ftell(f);
rewind(f);
}
if (ret == 0) {
*buf = (byte*)malloc(*bufSz);
if (*buf == NULL)
ret = -3;
}
if (ret == 0) {
int readSz;
readSz = (int)fread(*buf, 1, *bufSz, f);
if (readSz < (int)*bufSz)
ret = -4;
}
if (f != NULL)
fclose(f);
return ret;
}
#endif
static void test_wolfSSH_CTX_UseCert_buffer(void)
{
#ifdef WOLFSSH_CERTS
WOLFSSH_CTX* ctx = NULL;
byte* cert = NULL;
word32 certSz = 0;
ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_SERVER, NULL);
AssertNotNull(ctx);
AssertIntEQ(0, load_file("./keys/server-cert.pem", &cert, &certSz));
AssertNotNull(cert);
AssertIntNE(0, certSz);
AssertIntEQ(WS_BAD_ARGUMENT,
wolfSSH_CTX_UseCert_buffer(NULL, cert, certSz, WOLFSSH_FORMAT_PEM));
AssertIntEQ(WS_BAD_ARGUMENT,
wolfSSH_CTX_UseCert_buffer(ctx, NULL, certSz, WOLFSSH_FORMAT_PEM));
AssertIntEQ(WS_BAD_ARGUMENT,
wolfSSH_CTX_UseCert_buffer(ctx, NULL, 0, WOLFSSH_FORMAT_PEM));
AssertIntEQ(WS_SUCCESS,
wolfSSH_CTX_UseCert_buffer(ctx, cert, certSz, WOLFSSH_FORMAT_PEM));
AssertIntEQ(WS_BAD_FILETYPE_E,
wolfSSH_CTX_UseCert_buffer(ctx, cert, certSz, WOLFSSH_FORMAT_ASN1));
AssertIntEQ(WS_BAD_FILETYPE_E,
wolfSSH_CTX_UseCert_buffer(ctx, cert, certSz, WOLFSSH_FORMAT_RAW));
AssertIntEQ(WS_BAD_FILETYPE_E,
wolfSSH_CTX_UseCert_buffer(ctx, cert, certSz, 99));
free(cert);
AssertIntEQ(0, load_file("./keys/server-cert.der", &cert, &certSz));
AssertNotNull(cert);
AssertIntNE(0, certSz);
AssertIntEQ(WS_SUCCESS,
wolfSSH_CTX_UseCert_buffer(ctx, cert, certSz, WOLFSSH_FORMAT_ASN1));
wolfSSH_CTX_free(ctx);
free(cert);
#endif /* WOLFSSH_CERTS */
}
static void test_wolfSSH_CertMan(void)
{
#ifdef WOLFSSH_CERTMAN
@ -1000,6 +1089,7 @@ int main(void)
test_wolfSSH_ConvertConsole();
test_wolfSSH_CTX_UsePrivateKey_buffer();
test_wolfSSH_RealPath();
test_wolfSSH_CTX_UseCert_buffer();
test_wolfSSH_CertMan();
/* SCP tests */

View File

@ -36,10 +36,7 @@ extern "C" {
#endif
struct WOLFSSH_CERTMAN {
void* heap;
unsigned char reserved[512];
};
struct WOLFSSH_CERTMAN;
typedef struct WOLFSSH_CERTMAN WOLFSSH_CERTMAN;
@ -50,7 +47,12 @@ WOLFSSH_API
void wolfSSH_CERTMAN_free(WOLFSSH_CERTMAN* cm);
WOLFSSH_API
WOLFSSH_CERTMAN* wolfSSH_CERTMAN_init(WOLFSSH_CERTMAN* cm, void* heap);
int wolfSSH_CERTMAN_LoadRootCA_buffer(WOLFSSH_CERTMAN* cm,
const unsigned char* rootCa, word32 rootCaSz);
WOLFSSH_API
int wolfSSH_CERTMAN_VerifyCert_buffer(WOLFSSH_CERTMAN* cm,
const unsigned char* cert, word32 certSz);
#ifdef __cplusplus

View File

@ -42,6 +42,9 @@
#ifdef WOLFSSH_AGENT
#include <wolfssh/agent.h>
#endif /* WOLFSSH_AGENT */
#ifdef WOLFSSH_CERTS
#include <wolfssh/certman.h>
#endif /* WOLFSSH_CERTS */
#if !defined (ALIGN16)
@ -415,6 +418,9 @@ struct WOLFSSH_CTX {
WS_CallbackFwd fwdCb; /* WOLFSSH-FWD callback */
WS_CallbackFwdIO fwdIoCb; /* WOLFSSH-FWD IO callback */
#endif /* WOLFSSH_FWD */
#ifdef WOLFSSH_CERTS
WOLFSSH_CERTMAN* certMan;
#endif /* WOLFSSH_CERTS */
WS_CallbackPublicKeyCheck publicKeyCheckCb;
/* Check server's public key callback */
@ -424,6 +430,8 @@ struct WOLFSSH_CTX {
#ifndef WOLFSSH_NO_SABER_LEVEL1_SHA256
byte useSaber:1; /* Depends on the private key */
#endif
byte* cert;
word32 certSz;
byte useCert;
word32 highwaterMark;
const char* banner;
@ -457,6 +465,7 @@ typedef struct HandshakeInfo {
byte kexId;
byte kexIdGuess;
byte pubKeyId;
byte sigId;
byte encryptId;
byte macId;
byte hashId;

View File

@ -226,6 +226,12 @@ WOLFSSH_API char* wolfSSH_GetUsername(WOLFSSH*);
WOLFSSH_API int wolfSSH_CTX_SetBanner(WOLFSSH_CTX*, const char*);
WOLFSSH_API int wolfSSH_CTX_UsePrivateKey_buffer(WOLFSSH_CTX*,
const byte*, word32, int);
#ifdef WOLFSSH_CERTS
WOLFSSH_API int wolfSSH_CTX_UseCert_buffer(WOLFSSH_CTX* ctx,
const byte* cert, word32 certSz, int format);
WOLFSSH_API int wolfSSH_CTX_AddRootCert_buffer(WOLFSSH_CTX* ctx,
const byte* cert, word32 certSz, int format);
#endif /* WOLFSSH_CERTS */
WOLFSSH_API int wolfSSH_CTX_SetWindowPacketSize(WOLFSSH_CTX*, word32, word32);
WOLFSSH_API int wolfSSH_accept(WOLFSSH*);