allow verify of public key with no authorized keys file if using a CA

pull/453/head
JacobBarthelmeh 2022-09-07 14:40:55 -07:00
parent 3e1a6ff342
commit 657db7cd7e
4 changed files with 61 additions and 100 deletions

View File

@ -484,7 +484,7 @@ static int CheckPublicKeyUnix(const char* name,
int rc;
struct passwd* pwInfo;
char* authKeysFile = NULL;
XFILE f = NULL;
XFILE f = XBADFILE;
char* lineBuf = NULL;
char* current;
word32 currentSz;
@ -740,19 +740,30 @@ static int RequestAuthentication(WS_UserAuthData* authData,
if (ret == WOLFSSH_USERAUTH_SUCCESS &&
authData->type == WOLFSSH_USERAUTH_PUBLICKEY) {
rc = authCtx->checkPublicKeyCb(usr, &authData->sf.publicKey,
wolfSSHD_ConfigGetUserCAKeysFile(authCtx->conf));
if (rc == WSSHD_AUTH_SUCCESS) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key ok.");
/* if this is a certificate and no specific authorized keys file has
* been set then rely on CA to have verified the cert */
if (authData->sf.publicKey.isCert &&
!wolfSSHD_ConfigGetAuthKeysFileSet(authCtx->conf)) {
wolfSSH_Log(WS_LOG_INFO,
"[SSHD] Relying on CA for public key check");
ret = WOLFSSH_USERAUTH_SUCCESS;
}
else if (rc == WSSHD_AUTH_FAILURE) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key not authorized.");
ret = WOLFSSH_USERAUTH_INVALID_PUBLICKEY;
}
else {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error checking public key.");
ret = WOLFSSH_USERAUTH_FAILURE;
/* if not a certificate then parse through authorized key file */
rc = authCtx->checkPublicKeyCb(usr, &authData->sf.publicKey,
wolfSSHD_ConfigGetUserCAKeysFile(authCtx->conf));
if (rc == WSSHD_AUTH_SUCCESS) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key ok.");
ret = WOLFSSH_USERAUTH_SUCCESS;
}
else if (rc == WSSHD_AUTH_FAILURE) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Public key not authorized.");
ret = WOLFSSH_USERAUTH_INVALID_PUBLICKEY;
}
else {
wolfSSH_Log(WS_LOG_ERROR, "[SSHD] Error checking public key.");
ret = WOLFSSH_USERAUTH_FAILURE;
}
}
}

View File

@ -72,6 +72,7 @@ struct WOLFSSHD_CONFIG {
byte pubKeyAuth:1;
byte permitRootLogin:1;
byte permitEmptyPasswords:1;
byte authKeysFileSet:1; /* if not set then no explicit authorized keys */
};
int CountWhitespace(const char* in, int inSz, byte inv);
@ -920,6 +921,7 @@ static int HandleConfigOption(WOLFSSHD_CONFIG** conf, int opt,
switch (opt) {
case OPT_AUTH_KEYS_FILE:
(*conf)->authKeysFileSet = 1;
ret = wolfSSHD_ConfigSetAuthKeysFile(*conf, value);
break;
case OPT_PRIV_SEP:
@ -1194,6 +1196,19 @@ char* wolfSSHD_ConfigGetAuthKeysFile(const WOLFSSHD_CONFIG* conf)
return ret;
}
/* returns 1 if the authorized keys file was set and 0 if not */
int wolfSSHD_ConfigGetAuthKeysFileSet(const WOLFSSHD_CONFIG* conf)
{
int ret = 0;
if (conf != NULL) {
ret = conf->authKeysFileSet;
}
return ret;
}
int wolfSSHD_ConfigSetAuthKeysFile(WOLFSSHD_CONFIG* conf, const char* file)
{
int ret = WS_SUCCESS;

View File

@ -45,6 +45,7 @@ int wolfSSHD_ConfigSetHostCertFile(WOLFSSHD_CONFIG* conf, const char* file);
int wolfSSHD_ConfigSetUserCAKeysFile(WOLFSSHD_CONFIG* conf, const char* file);
word16 wolfSSHD_ConfigGetPort(const WOLFSSHD_CONFIG* conf);
char* wolfSSHD_ConfigGetAuthKeysFile(const WOLFSSHD_CONFIG* conf);
int wolfSSHD_ConfigGetAuthKeysFileSet(const WOLFSSHD_CONFIG* conf);
int wolfSSHD_ConfigSetAuthKeysFile(WOLFSSHD_CONFIG* conf, const char* file);
byte wolfSSHD_ConfigGetPermitEmptyPw(const WOLFSSHD_CONFIG* conf);
byte wolfSSHD_ConfigGetPermitRoot(const WOLFSSHD_CONFIG* conf);

View File

@ -5342,10 +5342,6 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
byte pkTypeId = ID_NONE;
byte* pkOk = NULL;
word32 pkOkSz = 0;
#ifdef WOLFSSH_CERTS
word32 certCount = 0;
word32 certChainSz = 0;
#endif
WLOG(WS_LOG_DEBUG, "Entering DoUserAuthRequestPublicKey()");
@ -5393,92 +5389,39 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP256 ||
pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP384 ||
pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP521) {
word32 l = 0, m = 0;
word32 ocspCount = 0;
byte* ocspBuf = NULL;
word32 ocspBufSz = 0;
byte *cert = NULL;
word32 certSz = 0;
/* Skip the name */
ret = GetSize(&l, pk->publicKey, pk->publicKeySz, &m);
m += l;
/* Get the cert count */
ret = ParseAndVerifyCert(ssh, (byte*)pk->publicKey, pk->publicKeySz,
&cert, &certSz);
if (ret == WS_SUCCESS) {
ret = GetUint32(&certCount, pk->publicKey, pk->publicKeySz, &m);
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_INFO, "Peer sent certificate count of %d",
certCount);
}
pk->isCert = 1;
pk->publicKey = cert;
pk->publicKeySz = certSz;
}
if (ret == WS_SUCCESS) {
word32 count;
byte* certPt = (byte*)pk->publicKey;
pk->isCert = 1;
for (count = certCount; count > 0; count--) {
word32 certSz = 0;
ret = GetSize(&certSz, certPt, pk->publicKeySz, &m);
WLOG(WS_LOG_INFO, "Adding certificate size %d", certSz);
if (ret != WS_SUCCESS) {
break;
}
/* store leaf cert size to present to user callback */
if (count == certCount) {
l = certSz;
pk->publicKey = certPt + m;
}
certChainSz += certSz + UINT32_SZ;
m += certSz;
}
if (ret == WS_SUCCESS) {
ocspBuf = certPt + m;
ocspBufSz = pk->publicKeySz - certChainSz;
pk->publicKeySz = l; /* only the size of the leaf cert */
}
}
/* get OCSP count */
if (ret == WS_SUCCESS) {
m = 0;
ret = GetUint32(&ocspCount, ocspBuf, ocspBufSz, &m);
}
if (ret == WS_SUCCESS) {
WLOG(WS_LOG_INFO, "Peer sent OCSP count of %d", ocspCount);
/* RFC 6187 section 2.1 OCSP count must not exceed cert count */
if (ocspCount > certCount) {
WLOG(WS_LOG_ERROR, "Error more OCSP then Certs");
ret = WS_FATAL_ERROR;
}
}
/* @TODO handle OCSP's */
if (ocspCount > 0) {
WLOG(WS_LOG_INFO, "Peer sent OCSP's, not yet handled");
ret = GetSize(&l, ocspBuf, ocspBufSz, &m);
else {
WLOG(WS_LOG_DEBUG, "DUARPK: client cert not verified");
ret = SendUserAuthFailure(ssh, 0);
authFailure = 1;
}
}
#endif /* WOLFSSH_CERTS */
if (pk->hasSignature) {
ret = GetSize(&pk->signatureSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
pk->signature = buf + begin;
begin += pk->signatureSz;
if (ret == WS_SUCCESS && !authFailure) {
if (pk->hasSignature) {
ret = GetSize(&pk->signatureSz, buf, len, &begin);
if (ret == WS_SUCCESS) {
pk->signature = buf + begin;
begin += pk->signatureSz;
}
}
else {
pk->signature = NULL;
pk->signatureSz = 0;
}
}
else {
pk->signature = NULL;
pk->signatureSz = 0;
}
if (ret == WS_SUCCESS) {
if (ret == WS_SUCCESS && !authFailure) {
*idx = begin;
if (ssh->ctx->userAuthCb != NULL) {
@ -5566,15 +5509,6 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
}
wc_HashFree(&hash, hashId);
#ifdef WOLFSSH_CERTS
/* verify certificates sent after the auth cb has allowed the
* connection */
if (ret == WS_SUCCESS && pk->isCert == 1 && certCount > 0) {
ret = wolfSSH_CERTMAN_VerifyCerts_buffer(ssh->ctx->certMan,
pk->publicKey - UINT32_SZ, certChainSz, certCount);
}
#endif
if (ret == WS_SUCCESS) {
switch (pkTypeId) {
#ifndef WOLFSSH_NO_RSA