mirror of https://github.com/wolfSSL/wolfssh.git
add UUID and FASC-N
parent
91f2ea7e97
commit
c507c77431
|
@ -34,7 +34,9 @@
|
||||||
#include <wolfssl/wolfcrypt/hash.h>
|
#include <wolfssl/wolfcrypt/hash.h>
|
||||||
#include <wolfssl/wolfcrypt/coding.h>
|
#include <wolfssl/wolfcrypt/coding.h>
|
||||||
#include <wolfssl/wolfcrypt/wc_port.h>
|
#include <wolfssl/wolfcrypt/wc_port.h>
|
||||||
|
#include <wolfssl/wolfcrypt/asn.h>
|
||||||
#include <wolfssl/wolfcrypt/asn_public.h>
|
#include <wolfssl/wolfcrypt/asn_public.h>
|
||||||
|
#include <wolfssl/wolfcrypt/error-crypt.h>
|
||||||
#include <wolfssh/ssh.h>
|
#include <wolfssh/ssh.h>
|
||||||
#include <wolfssh/internal.h>
|
#include <wolfssh/internal.h>
|
||||||
#include <wolfssh/wolfsftp.h>
|
#include <wolfssh/wolfsftp.h>
|
||||||
|
@ -1854,6 +1856,18 @@ static int LoadPubKeyList(StrList* strList, int format, PwMapList* mapList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int wsUserAuthResult(byte res,
|
||||||
|
WS_UserAuthData* authData,
|
||||||
|
void* ctx)
|
||||||
|
{
|
||||||
|
printf("In auth result callback, auth = %s\n",
|
||||||
|
(res == WOLFSSH_USERAUTH_SUCCESS) ? "Success" : "Failure");
|
||||||
|
(void)authData;
|
||||||
|
(void)ctx;
|
||||||
|
return WS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int wsUserAuth(byte authType,
|
static int wsUserAuth(byte authType,
|
||||||
WS_UserAuthData* authData,
|
WS_UserAuthData* authData,
|
||||||
void* ctx)
|
void* ctx)
|
||||||
|
@ -1886,6 +1900,69 @@ static int wsUserAuth(byte authType,
|
||||||
wc_Sha256Hash(authData->sf.publicKey.publicKey,
|
wc_Sha256Hash(authData->sf.publicKey.publicKey,
|
||||||
authData->sf.publicKey.publicKeySz,
|
authData->sf.publicKey.publicKeySz,
|
||||||
authHash);
|
authHash);
|
||||||
|
#ifndef WOLFSSH_NO_FPKI
|
||||||
|
/* Display FPKI info UUID and FASC-N */
|
||||||
|
if (authData->sf.publicKey.isCert) {
|
||||||
|
DecodedCert cert;
|
||||||
|
byte* uuid;
|
||||||
|
word32 fascnSz;
|
||||||
|
word32 uuidSz;
|
||||||
|
word32 i;
|
||||||
|
|
||||||
|
printf("Peer connected with FPKI certificate\n");
|
||||||
|
wc_InitDecodedCert(&cert, authData->sf.publicKey.publicKey,
|
||||||
|
authData->sf.publicKey.publicKeySz, NULL);
|
||||||
|
ret = wc_ParseCert(&cert, CERT_TYPE, 0, NULL);
|
||||||
|
|
||||||
|
/* some profiles supported due not require FASC-N */
|
||||||
|
if (ret == 0 &&
|
||||||
|
wc_GetFASCNFromCert(&cert, NULL, &fascnSz) == LENGTH_ONLY_E) {
|
||||||
|
byte* fascn;
|
||||||
|
|
||||||
|
fascn = (byte*)WMALLOC(fascnSz, NULL, 0);
|
||||||
|
if (fascn != NULL &&
|
||||||
|
wc_GetFASCNFromCert(&cert, fascn, &fascnSz) == 0) {
|
||||||
|
printf("HEX of FASC-N :");
|
||||||
|
for (i = 0; i < fascnSz; i++)
|
||||||
|
printf("%02X", fascn[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
if (fascn != NULL)
|
||||||
|
WFREE(fascn, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* all profiles supported must have a UUID */
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_GetUUIDFromCert(&cert, NULL, &uuidSz);
|
||||||
|
if (ret == LENGTH_ONLY_E) { /* expected error value */
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0 ) {
|
||||||
|
uuid = (byte*)WMALLOC(uuidSz, NULL, 0);
|
||||||
|
if (uuid == NULL) {
|
||||||
|
ret = WS_MEMORY_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret == 0) {
|
||||||
|
ret = wc_GetUUIDFromCert(&cert, uuid, &uuidSz);
|
||||||
|
printf("UUID string : ");
|
||||||
|
for (i = 0; i < uuidSz; i++)
|
||||||
|
printf("%c", uuid[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uuid != NULL)
|
||||||
|
WFREE(uuid, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* failed to at least get UUID string */
|
||||||
|
if (ret != 0) {
|
||||||
|
return WOLFSSH_USERAUTH_INVALID_PUBLICKEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
list = (PwMapList*)ctx;
|
list = (PwMapList*)ctx;
|
||||||
|
@ -2147,6 +2224,7 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
|
||||||
wolfSSH_SetUserAuth(ctx, wsUserAuth);
|
wolfSSH_SetUserAuth(ctx, wsUserAuth);
|
||||||
else
|
else
|
||||||
wolfSSH_SetUserAuth(ctx, ((func_args*)args)->user_auth);
|
wolfSSH_SetUserAuth(ctx, ((func_args*)args)->user_auth);
|
||||||
|
wolfSSH_SetUserAuthResult(ctx, wsUserAuthResult);
|
||||||
wolfSSH_CTX_SetBanner(ctx, echoserverBanner);
|
wolfSSH_CTX_SetBanner(ctx, echoserverBanner);
|
||||||
#ifdef WOLFSSH_AGENT
|
#ifdef WOLFSSH_AGENT
|
||||||
wolfSSH_CTX_set_agent_cb(ctx, wolfSSH_AGENT_DefaultActions, NULL);
|
wolfSSH_CTX_set_agent_cb(ctx, wolfSSH_AGENT_DefaultActions, NULL);
|
||||||
|
|
|
@ -181,12 +181,14 @@ int wolfSSH_CERTMAN_LoadRootCA_buffer(WOLFSSH_CERTMAN* cm,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef WOLFSSH_NO_FPKI
|
||||||
static int CheckProfile(DecodedCert* cert, int profile);
|
static int CheckProfile(DecodedCert* cert, int profile);
|
||||||
enum {
|
enum {
|
||||||
PROFILE_FPKI_WORKSHEET_6 = 6,
|
PROFILE_FPKI_WORKSHEET_6 = 6,
|
||||||
PROFILE_FPKI_WORKSHEET_10 = 10,
|
PROFILE_FPKI_WORKSHEET_10 = 10,
|
||||||
PROFILE_FPKI_WORKSHEET_16 = 16
|
PROFILE_FPKI_WORKSHEET_16 = 16
|
||||||
};
|
};
|
||||||
|
#endif /* WOLFSSH_NO_FPKI */
|
||||||
|
|
||||||
int wolfSSH_CERTMAN_VerifyCert_buffer(WOLFSSH_CERTMAN* cm,
|
int wolfSSH_CERTMAN_VerifyCert_buffer(WOLFSSH_CERTMAN* cm,
|
||||||
const unsigned char* cert, word32 certSz)
|
const unsigned char* cert, word32 certSz)
|
||||||
|
@ -236,6 +238,7 @@ int wolfSSH_CERTMAN_VerifyCert_buffer(WOLFSSH_CERTMAN* cm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WOLFSSH_NO_FPKI
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
DecodedCert decoded;
|
DecodedCert decoded;
|
||||||
|
|
||||||
|
@ -259,12 +262,14 @@ int wolfSSH_CERTMAN_VerifyCert_buffer(WOLFSSH_CERTMAN* cm,
|
||||||
|
|
||||||
FreeDecodedCert(&decoded);
|
FreeDecodedCert(&decoded);
|
||||||
}
|
}
|
||||||
|
#endif /* WOLFSSH_NO_FPKI */
|
||||||
|
|
||||||
WLOG_LEAVE(ret);
|
WLOG_LEAVE(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef WOLFSSH_NO_FPKI
|
||||||
static int CheckProfile(DecodedCert* cert, int profile)
|
static int CheckProfile(DecodedCert* cert, int profile)
|
||||||
{
|
{
|
||||||
int valid = (cert != NULL);
|
int valid = (cert != NULL);
|
||||||
|
@ -298,16 +303,21 @@ static int CheckProfile(DecodedCert* cert, int profile)
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
valid = WSTRCMP(cert->countryOfCitizenship, "US") == 0;
|
valid = WSTRCMP(cert->countryOfCitizenship, "US") == 0;
|
||||||
|
if (valid != 1)
|
||||||
|
WLOG(WS_LOG_CERTMAN, "cert contry of citizenship invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
valid = !cert->isCA;
|
valid = !cert->isCA;
|
||||||
|
if (valid != 1)
|
||||||
|
WLOG(WS_LOG_CERTMAN, "cert basic constraint invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
valid =
|
valid =
|
||||||
WMEMCMP(cert->extAuthKeyId, cert->extSubjKeyId, KEYID_SIZE) != 0;
|
WMEMCMP(cert->extAuthKeyId, cert->extSubjKeyId, KEYID_SIZE) != 0;
|
||||||
|
if (valid != 1)
|
||||||
|
WLOG(WS_LOG_CERTMAN, "cert auth key and subject key mismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
@ -318,6 +328,8 @@ static int CheckProfile(DecodedCert* cert, int profile)
|
||||||
((certPolicies[0] != NULL) &&
|
((certPolicies[0] != NULL) &&
|
||||||
(WSTRCMP(certPolicies[0], cert->extCertPolicies[0]) == 0 ||
|
(WSTRCMP(certPolicies[0], cert->extCertPolicies[0]) == 0 ||
|
||||||
WSTRCMP(certPolicies[0], cert->extCertPolicies[1]) == 0));
|
WSTRCMP(certPolicies[0], cert->extCertPolicies[1]) == 0));
|
||||||
|
if (valid != 1)
|
||||||
|
WLOG(WS_LOG_CERTMAN, "cert policy invalid");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* validity period must be utc up to and including 2049, general time
|
/* validity period must be utc up to and including 2049, general time
|
||||||
|
@ -364,6 +376,41 @@ static int CheckProfile(DecodedCert* cert, int profile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check on FASC-N and UUID */
|
||||||
|
if (valid) {
|
||||||
|
DNS_entry* current;
|
||||||
|
byte hasFascN = 0;
|
||||||
|
byte hasUUID = 0;
|
||||||
|
byte uuid[DEFAULT_UUID_SZ];
|
||||||
|
word32 uuidSz = DEFAULT_UUID_SZ;
|
||||||
|
|
||||||
|
/* cycle through alt names to check for needed types */
|
||||||
|
current = cert->altNames;
|
||||||
|
while (current != NULL) {
|
||||||
|
if (current->oidSum == FASCN_OID) {
|
||||||
|
hasFascN = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wc_GetUUIDFromCert(cert, uuid, &uuidSz) == 0) {
|
||||||
|
hasUUID = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* all must have UUID and worksheet 6 must have FASC-N in addition to
|
||||||
|
* UUID */
|
||||||
|
if (profile == PROFILE_FPKI_WORKSHEET_6 && hasFascN == 0) {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "cert did not inclue a FASC-N");
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid && hasUUID == 0) {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "cert did not inclue a UUID");
|
||||||
|
valid = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (valid) {
|
if (valid) {
|
||||||
valid =
|
valid =
|
||||||
/* Must include all in extKeyUsage */
|
/* Must include all in extKeyUsage */
|
||||||
|
@ -373,6 +420,9 @@ static int CheckProfile(DecodedCert* cert, int profile)
|
||||||
((extKeyUsageSsh == 0) ||
|
((extKeyUsageSsh == 0) ||
|
||||||
((cert->extExtKeyUsageSsh & extKeyUsageSsh)
|
((cert->extExtKeyUsageSsh & extKeyUsageSsh)
|
||||||
== extKeyUsageSsh));
|
== extKeyUsageSsh));
|
||||||
|
if (valid != 1) {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "cert did not inclue all ext. key usage");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_WOLFSSH
|
#ifdef DEBUG_WOLFSSH
|
||||||
|
@ -402,5 +452,6 @@ static int CheckProfile(DecodedCert* cert, int profile)
|
||||||
|
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
#endif /* WOLFSSH_NO_FPKI */
|
||||||
|
|
||||||
#endif /* WOLFSSH_CERTS */
|
#endif /* WOLFSSH_CERTS */
|
||||||
|
|
|
@ -5054,6 +5054,7 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
||||||
ret = GetSize(&l, pk->publicKey, pk->publicKeySz, &m);
|
ret = GetSize(&l, pk->publicKey, pk->publicKeySz, &m);
|
||||||
pk->publicKeySz = l;
|
pk->publicKeySz = l;
|
||||||
pk->publicKey = pk->publicKey + m;
|
pk->publicKey = pk->publicKey + m;
|
||||||
|
pk->isCert = 1;
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSH_CERTS */
|
#endif /* WOLFSSH_CERTS */
|
||||||
|
|
||||||
|
@ -5216,12 +5217,21 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ssh->ctx->userAuthResultCb) {
|
if (ssh->ctx->userAuthResultCb) {
|
||||||
ssh->ctx->userAuthResultCb(WOLFSSH_USERAUTH_SUCCESS,
|
if (ssh->ctx->userAuthResultCb(WOLFSSH_USERAUTH_SUCCESS,
|
||||||
authData, ssh->userAuthResultCtx);
|
authData, ssh->userAuthResultCtx) != WS_SUCCESS) {
|
||||||
|
|
||||||
|
WLOG(WS_LOG_DEBUG, "DUARPK: user overriding success");
|
||||||
|
ret = SendUserAuthFailure(ssh, 0);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
ssh->clientState = CLIENT_USERAUTH_DONE;
|
ssh->clientState = CLIENT_USERAUTH_DONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
ssh->clientState = CLIENT_USERAUTH_DONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthRequestPublicKey(), ret = %d", ret);
|
WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthRequestPublicKey(), ret = %d", ret);
|
||||||
|
|
|
@ -191,6 +191,7 @@ typedef struct WS_UserAuthData_PublicKey {
|
||||||
byte hasSignature;
|
byte hasSignature;
|
||||||
const byte* signature;
|
const byte* signature;
|
||||||
word32 signatureSz;
|
word32 signatureSz;
|
||||||
|
byte isCert:1;
|
||||||
} WS_UserAuthData_PublicKey;
|
} WS_UserAuthData_PublicKey;
|
||||||
|
|
||||||
typedef struct WS_UserAuthData {
|
typedef struct WS_UserAuthData {
|
||||||
|
|
Loading…
Reference in New Issue