mirror of https://github.com/wolfSSL/wolfssh.git
allow verify of public key with no authorized keys file if using a CA
parent
3e1a6ff342
commit
657db7cd7e
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
112
src/internal.c
112
src/internal.c
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue