mirror of https://github.com/wolfSSL/wolfssh.git
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
parent
93996f1942
commit
1405eeae62
27
README.md
27
README.md
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
@ -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-----
|
Binary file not shown.
|
@ -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-----
|
Binary file not shown.
|
@ -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-----
|
|
@ -0,0 +1 @@
|
|||
ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBBLcFtEXgaYC8A8RkLsyhWYOdgBirKrjuSYcKuIo+N3YeT/AAl7R0cX+PGP1H64TS2nK6O30Nrpi4KHIGBBLVeE=
|
Binary file not shown.
|
@ -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-----
|
|
@ -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-----
|
|
@ -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 */
|
||||
|
|
771
src/internal.c
771
src/internal.c
File diff suppressed because it is too large
Load Diff
33
src/ssh.c
33
src/ssh.c
|
@ -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)
|
||||
{
|
||||
|
|
90
tests/api.c
90
tests/api.c
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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*);
|
||||
|
|
Loading…
Reference in New Issue