mirror of https://github.com/wolfSSL/wolfssh.git
handle certificate chains
parent
69e1cde58f
commit
e40e852bc2
|
@ -1898,11 +1898,14 @@ 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);
|
||||||
#if defined(WOLFSSH_CERTS) && !defined(WOLFSSH_NO_FPKI)
|
#if defined(WOLFSSH_CERTS) && !defined(WOLFSSH_NO_FPKI) && \
|
||||||
/* Display FPKI info UUID and FASC-N */
|
defined(WOLFSSL_FPKI)
|
||||||
|
/* Display FPKI info UUID and FASC-N, getter function for FASC-N and
|
||||||
|
* UUID are dependent on wolfSSL version newer than 5.3.0 so gatting
|
||||||
|
* on the macro WOLFSSL_FPKI here too */
|
||||||
if (authData->sf.publicKey.isCert) {
|
if (authData->sf.publicKey.isCert) {
|
||||||
DecodedCert cert;
|
DecodedCert cert;
|
||||||
byte* uuid;
|
byte* uuid = NULL;
|
||||||
word32 fascnSz;
|
word32 fascnSz;
|
||||||
word32 uuidSz;
|
word32 uuidSz;
|
||||||
word32 i;
|
word32 i;
|
||||||
|
|
192
src/certman.c
192
src/certman.c
|
@ -86,33 +86,36 @@ struct WOLFSSH_CERTMAN {
|
||||||
|
|
||||||
static WOLFSSH_CERTMAN* _CertMan_init(WOLFSSH_CERTMAN* cm, void* heap)
|
static WOLFSSH_CERTMAN* _CertMan_init(WOLFSSH_CERTMAN* cm, void* heap)
|
||||||
{
|
{
|
||||||
|
WOLFSSH_CERTMAN* ret = NULL;
|
||||||
WLOG_ENTER();
|
WLOG_ENTER();
|
||||||
|
|
||||||
if (cm != NULL) {
|
ret = cm;
|
||||||
WMEMSET(cm, 0, sizeof *cm);
|
if (ret != NULL) {
|
||||||
cm->cm = wolfSSL_CertManagerNew_ex(heap);
|
WMEMSET(ret, 0, sizeof(WOLFSSH_CERTMAN));
|
||||||
if (cm->cm != NULL) {
|
ret->cm = wolfSSL_CertManagerNew_ex(heap);
|
||||||
int ret;
|
if (ret->cm == NULL) {
|
||||||
|
ret = NULL;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_OCSP
|
||||||
|
else {
|
||||||
|
int err;
|
||||||
|
|
||||||
ret = wolfSSL_CertManagerEnableOCSP(cm->cm,
|
err = wolfSSL_CertManagerEnableOCSP(ret->cm,
|
||||||
WOLFSSL_OCSP_CHECKALL);
|
WOLFSSL_OCSP_CHECKALL);
|
||||||
|
if (err == WOLFSSL_SUCCESS) {
|
||||||
if (ret == WOLFSSL_SUCCESS) {
|
|
||||||
WLOG(WS_LOG_CERTMAN, "Enabled OCSP");
|
WLOG(WS_LOG_CERTMAN, "Enabled OCSP");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WLOG(WS_LOG_CERTMAN, "Couldn't enable OCSP");
|
WLOG(WS_LOG_CERTMAN, "Couldn't enable OCSP");
|
||||||
wolfSSL_CertManagerFree(cm->cm);
|
wolfSSL_CertManagerFree(ret->cm);
|
||||||
cm = NULL;
|
ret = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
#endif
|
||||||
cm = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WLOG_LEAVE_PTR(cm);
|
WLOG_LEAVE_PTR(ret);
|
||||||
return cm;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -190,59 +193,148 @@ enum {
|
||||||
};
|
};
|
||||||
#endif /* WOLFSSH_NO_FPKI */
|
#endif /* WOLFSSH_NO_FPKI */
|
||||||
|
|
||||||
int wolfSSH_CERTMAN_VerifyCert_buffer(WOLFSSH_CERTMAN* cm,
|
/* if handling a chain it is expected to be the leaf cert first followed by
|
||||||
const unsigned char* cert, word32 certSz)
|
* intermediates and CA last (CA may be ommited) */
|
||||||
|
int wolfSSH_CERTMAN_VerifyCerts_buffer(WOLFSSH_CERTMAN* cm,
|
||||||
|
const unsigned char* certs, word32 certSz, word32 certsCount)
|
||||||
{
|
{
|
||||||
int ret = WS_SUCCESS;
|
int ret = WS_SUCCESS;
|
||||||
|
int idx;
|
||||||
|
|
||||||
|
unsigned char **certLoc; /* locations of certificate start */
|
||||||
|
word32 *certLen; /* size of certificate, in sync with certLoc */
|
||||||
|
|
||||||
|
unsigned char *currentPt;
|
||||||
|
word32 currentSz;
|
||||||
|
|
||||||
WLOG_ENTER();
|
WLOG_ENTER();
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
certLoc = (unsigned char**)WMALLOC(certsCount * sizeof(unsigned char*),
|
||||||
ret = wolfSSL_CertManagerVerifyBuffer(cm->cm, cert, certSz,
|
cm->heap, DYNTYPE_CERT);
|
||||||
WOLFSSL_FILETYPE_ASN1);
|
certLen = (word32*)WMALLOC(certsCount * sizeof(word32), cm->heap,
|
||||||
|
DYNTYPE_CERT);
|
||||||
|
|
||||||
if (ret == WOLFSSL_SUCCESS) {
|
currentPt = (unsigned char*)certs; /* set initial certificate pointer */
|
||||||
ret = WS_SUCCESS;
|
currentSz = 0;
|
||||||
}
|
|
||||||
else if (ret == ASN_NO_SIGNER_E) {
|
for (idx = 0; idx < (int)certsCount; idx++) {
|
||||||
WLOG(WS_LOG_CERTMAN, "cert verify: no signer");
|
word32 sz = 0;
|
||||||
ret = WS_CERT_NO_SIGNER_E;
|
certLoc[idx] = currentPt;
|
||||||
}
|
|
||||||
else if (ret == ASN_AFTER_DATE_E) {
|
/* get the size of the certificate from first sequence */
|
||||||
WLOG(WS_LOG_CERTMAN, "cert verify: expired");
|
if (currentSz + MAX_SEQ_SZ >= certSz) {
|
||||||
ret = WS_CERT_EXPIRED_E;
|
ret = WS_BUFFER_E;
|
||||||
}
|
break;
|
||||||
else if (ret == ASN_SIG_CONFIRM_E) {
|
|
||||||
WLOG(WS_LOG_CERTMAN, "cert verify: bad sig");
|
|
||||||
ret = WS_CERT_SIG_CONFIRM_E;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WLOG(WS_LOG_CERTMAN, "cert verify: other error (%d)", ret);
|
/* at this point there is at least 5 bytes in currentPt */
|
||||||
ret = WS_CERT_OTHER_E;
|
if (currentPt[sz] != (ASN_SEQUENCE | ASN_CONSTRUCTED)) {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "no cert sequence to get length from");
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sz++;
|
||||||
|
|
||||||
|
if (ret == WS_SUCCESS) {
|
||||||
|
if (currentPt[sz] >= ASN_LONG_LENGTH) {
|
||||||
|
word32 bytes = currentPt[sz++] & 0x7F;
|
||||||
|
if (bytes > MAX_LENGTH_SZ) {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "length found is too large!");
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
byte b;
|
||||||
|
certLen[idx] = 0;
|
||||||
|
for (; bytes > 0; bytes--) {
|
||||||
|
b = currentPt[sz++];
|
||||||
|
certLen[idx] = (certLen[idx] << 8) | b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
certLen[idx] = (word32)currentPt[sz++];
|
||||||
|
}
|
||||||
|
sz += certLen[idx];
|
||||||
|
certLen[idx] = sz; /* update size to contain first sequence */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* advance current pointer and update current total size */
|
||||||
|
if (ret == WS_SUCCESS) {
|
||||||
|
if (currentSz + sz > certSz) {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "cert found is too large!");
|
||||||
|
ret = ASN_PARSE_E;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
currentSz += sz;
|
||||||
|
currentPt += sz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
ret = wolfSSL_CertManagerCheckOCSP(cm->cm, (byte*)cert, certSz);
|
for (idx = certsCount - 1; idx >= 0; idx--) {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "verifying cert at index %d", idx);
|
||||||
|
ret = wolfSSL_CertManagerVerifyBuffer(cm->cm, certLoc[idx],
|
||||||
|
certLen[idx], WOLFSSL_FILETYPE_ASN1);
|
||||||
|
if (ret == WOLFSSL_SUCCESS) {
|
||||||
|
ret = WS_SUCCESS;
|
||||||
|
}
|
||||||
|
else if (ret == ASN_NO_SIGNER_E) {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "cert verify: no signer");
|
||||||
|
ret = WS_CERT_NO_SIGNER_E;
|
||||||
|
}
|
||||||
|
else if (ret == ASN_AFTER_DATE_E) {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "cert verify: expired");
|
||||||
|
ret = WS_CERT_EXPIRED_E;
|
||||||
|
}
|
||||||
|
else if (ret == ASN_SIG_CONFIRM_E) {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "cert verify: bad sig");
|
||||||
|
ret = WS_CERT_SIG_CONFIRM_E;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "cert verify: other error (%d)", ret);
|
||||||
|
ret = WS_CERT_OTHER_E;
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == WOLFSSL_SUCCESS) {
|
#ifdef HAVE_OCSP
|
||||||
ret = WS_SUCCESS;
|
if (ret == WS_SUCCESS) {
|
||||||
}
|
ret = wolfSSL_CertManagerCheckOCSP(cm->cm, (byte*)certLoc[idx],
|
||||||
else if (ret == OCSP_CERT_REVOKED) {
|
certLen[idx]);
|
||||||
WLOG(WS_LOG_CERTMAN, "ocsp lookup: ocsp revoked");
|
|
||||||
ret = WS_CERT_REVOKED_E;
|
if (ret == WOLFSSL_SUCCESS) {
|
||||||
}
|
ret = WS_SUCCESS;
|
||||||
else {
|
}
|
||||||
WLOG(WS_LOG_CERTMAN, "ocsp lookup: other error (%d)", ret);
|
else if (ret == OCSP_CERT_REVOKED) {
|
||||||
ret = WS_CERT_OTHER_E;
|
WLOG(WS_LOG_CERTMAN, "ocsp lookup: ocsp revoked");
|
||||||
|
ret = WS_CERT_REVOKED_E;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "ocsp lookup: other error (%d)", ret);
|
||||||
|
ret = WS_CERT_OTHER_E;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* HAVE_OCSP */
|
||||||
|
|
||||||
|
/* verified successfully, add intermideate as trusted */
|
||||||
|
if (ret == WS_SUCCESS && idx > 0) {
|
||||||
|
WLOG(WS_LOG_CERTMAN, "adding intermidiate cert as trusted");
|
||||||
|
ret = wolfSSH_CERTMAN_LoadRootCA_buffer(cm, certLoc[idx],
|
||||||
|
certLen[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret != WS_SUCCESS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WOLFSSH_NO_FPKI
|
#ifndef WOLFSSH_NO_FPKI
|
||||||
|
/* FPKI checking on the leaf certificate */
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
DecodedCert decoded;
|
DecodedCert decoded;
|
||||||
|
|
||||||
wc_InitDecodedCert(&decoded, cert, certSz, cm->cm);
|
wc_InitDecodedCert(&decoded, certLoc[0], certLen[0], cm->cm);
|
||||||
ret = wc_ParseCert(&decoded, WOLFSSL_FILETYPE_ASN1, 0, cm->cm);
|
ret = wc_ParseCert(&decoded, WOLFSSL_FILETYPE_ASN1, 0, cm->cm);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
@ -387,16 +479,20 @@ static int CheckProfile(DecodedCert* cert, int profile)
|
||||||
/* cycle through alt names to check for needed types */
|
/* cycle through alt names to check for needed types */
|
||||||
current = cert->altNames;
|
current = cert->altNames;
|
||||||
while (current != NULL) {
|
while (current != NULL) {
|
||||||
|
#ifdef WOLFSSL_FPKI
|
||||||
if (current->oidSum == FASCN_OID) {
|
if (current->oidSum == FASCN_OID) {
|
||||||
hasFascN = 1;
|
hasFascN = 1;
|
||||||
}
|
}
|
||||||
|
#endif /* WOLFSSL_FPKI */
|
||||||
|
|
||||||
current = current->next;
|
current = current->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_FPKI
|
||||||
if (wc_GetUUIDFromCert(cert, uuid, &uuidSz) == 0) {
|
if (wc_GetUUIDFromCert(cert, uuid, &uuidSz) == 0) {
|
||||||
hasUUID = 1;
|
hasUUID = 1;
|
||||||
}
|
}
|
||||||
|
#endif /* WOLFSSL_FPKI */
|
||||||
|
|
||||||
/* all must have UUID and worksheet 6 must have FASC-N in addition to
|
/* all must have UUID and worksheet 6 must have FASC-N in addition to
|
||||||
* UUID */
|
* UUID */
|
||||||
|
|
104
src/internal.c
104
src/internal.c
|
@ -546,6 +546,8 @@ WOLFSSH_CTX* CtxInit(WOLFSSH_CTX* ctx, byte side, void* heap)
|
||||||
#endif /* DEBUG_WOLFSSH */
|
#endif /* DEBUG_WOLFSSH */
|
||||||
#ifdef WOLFSSH_CERTS
|
#ifdef WOLFSSH_CERTS
|
||||||
ctx->certMan = wolfSSH_CERTMAN_new(ctx->heap);
|
ctx->certMan = wolfSSH_CERTMAN_new(ctx->heap);
|
||||||
|
if (ctx->certMan == NULL)
|
||||||
|
return NULL;
|
||||||
#endif /* WOLFSSH_CERTS */
|
#endif /* WOLFSSH_CERTS */
|
||||||
ctx->windowSz = DEFAULT_WINDOW_SZ;
|
ctx->windowSz = DEFAULT_WINDOW_SZ;
|
||||||
ctx->maxPacketSz = DEFAULT_MAX_PACKET_SZ;
|
ctx->maxPacketSz = DEFAULT_MAX_PACKET_SZ;
|
||||||
|
@ -767,7 +769,6 @@ int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx,
|
||||||
word32 derSz, scratch = 0;
|
word32 derSz, scratch = 0;
|
||||||
union wolfSSH_key *key_ptr = NULL;
|
union wolfSSH_key *key_ptr = NULL;
|
||||||
|
|
||||||
(void)wcType;
|
|
||||||
(void)dynamicType;
|
(void)dynamicType;
|
||||||
(void)heap;
|
(void)heap;
|
||||||
|
|
||||||
|
@ -846,7 +847,15 @@ int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx,
|
||||||
if (ctx->certMan != NULL) {
|
if (ctx->certMan != NULL) {
|
||||||
ret = wolfSSH_CERTMAN_LoadRootCA_buffer(ctx->certMan, der, derSz);
|
ret = wolfSSH_CERTMAN_LoadRootCA_buffer(ctx->certMan, der, derSz);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
WLOG(WS_LOG_DEBUG, "Error no cert manager set");
|
||||||
|
ret = WS_MEMORY_E;
|
||||||
|
}
|
||||||
WFREE(der, heap, dynamicType);
|
WFREE(der, heap, dynamicType);
|
||||||
|
if (ret < 0) {
|
||||||
|
WLOG(WS_LOG_DEBUG, "Error %d loading in CA buffer", ret);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSH_CERTS */
|
#endif /* WOLFSSH_CERTS */
|
||||||
else {
|
else {
|
||||||
|
@ -911,6 +920,8 @@ int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx,
|
||||||
end:
|
end:
|
||||||
if (key_ptr)
|
if (key_ptr)
|
||||||
WFREE(key_ptr, heap, dynamicType);
|
WFREE(key_ptr, heap, dynamicType);
|
||||||
|
|
||||||
|
(void)wcType;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4546,11 +4557,6 @@ static int DoUserAuthRequestRsaCert(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
|
||||||
ret = wolfSSH_CERTMAN_VerifyCert_buffer(ssh->ctx->certMan,
|
|
||||||
pk->publicKey, pk->publicKeySz);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
byte* pub = NULL;
|
byte* pub = NULL;
|
||||||
word32 pubSz;
|
word32 pubSz;
|
||||||
|
@ -4895,13 +4901,6 @@ static int DoUserAuthRequestEccCert(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WOLFSSH_CERTS
|
|
||||||
if (ret == WS_SUCCESS) {
|
|
||||||
ret = wolfSSH_CERTMAN_VerifyCert_buffer(ssh->ctx->certMan,
|
|
||||||
pk->publicKey, pk->publicKeySz);
|
|
||||||
}
|
|
||||||
#endif /* WOLFSSH_CERTS */
|
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
byte* pub = NULL;
|
byte* pub = NULL;
|
||||||
word32 pubSz;
|
word32 pubSz;
|
||||||
|
@ -5037,6 +5036,9 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
||||||
int ret = WS_SUCCESS;
|
int ret = WS_SUCCESS;
|
||||||
int authFailure = 0;
|
int authFailure = 0;
|
||||||
byte pkTypeId;
|
byte pkTypeId;
|
||||||
|
#ifdef WOLFSSH_CERTS
|
||||||
|
word32 certCount = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
WLOG(WS_LOG_DEBUG, "Entering DoUserAuthRequestPublicKey()");
|
WLOG(WS_LOG_DEBUG, "Entering DoUserAuthRequestPublicKey()");
|
||||||
|
|
||||||
|
@ -5063,14 +5065,15 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
||||||
pkTypeId = NameToId((char*)pk->publicKeyType, pk->publicKeyTypeSz);
|
pkTypeId = NameToId((char*)pk->publicKeyType, pk->publicKeyTypeSz);
|
||||||
if (pkTypeId == ID_UNKNOWN) {
|
if (pkTypeId == ID_UNKNOWN) {
|
||||||
WLOG(WS_LOG_DEBUG, "DUARPK: Unknown / Unsupported key type");
|
WLOG(WS_LOG_DEBUG, "DUARPK: Unknown / Unsupported key type");
|
||||||
ret = WS_INVALID_ALGO_ID;
|
ret = SendUserAuthFailure(ssh, 0);
|
||||||
|
authFailure = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == WS_SUCCESS)
|
if (ret == WS_SUCCESS && !authFailure)
|
||||||
ret = GetSize(&pk->publicKeySz, buf, len, &begin);
|
ret = GetSize(&pk->publicKeySz, buf, len, &begin);
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS && !authFailure) {
|
||||||
pk->publicKey = buf + begin;
|
pk->publicKey = buf + begin;
|
||||||
begin += pk->publicKeySz;
|
begin += pk->publicKeySz;
|
||||||
#ifdef WOLFSSH_CERTS
|
#ifdef WOLFSSH_CERTS
|
||||||
|
@ -5079,21 +5082,47 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
||||||
pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP384 ||
|
pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP384 ||
|
||||||
pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP521) {
|
pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP521) {
|
||||||
word32 l = 0, m = 0;
|
word32 l = 0, m = 0;
|
||||||
|
word32 ocspCount = 0;
|
||||||
|
byte* ocspBuf = NULL;
|
||||||
|
word32 ocspBufSz = 0;
|
||||||
|
|
||||||
/* Skip the name */
|
/* Skip the name */
|
||||||
ret = GetSize(&l, pk->publicKey, pk->publicKeySz, &m);
|
ret = GetSize(&l, pk->publicKey, pk->publicKeySz, &m);
|
||||||
m += l;
|
m += l;
|
||||||
/* Get the cert count */
|
/* Get the cert count */
|
||||||
ret = GetUint32(&l, pk->publicKey, pk->publicKeySz, &m);
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
ret = GetSize(&l, pk->publicKey, pk->publicKeySz, &m);
|
ret = GetUint32(&certCount, pk->publicKey, pk->publicKeySz, &m);
|
||||||
|
if (ret == WS_SUCCESS) {
|
||||||
|
WLOG(WS_LOG_INFO, "Peer sent certificate count of %d",
|
||||||
|
certCount);
|
||||||
|
ret = GetSize(&l, pk->publicKey, pk->publicKeySz, &m);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
|
ocspBuf = (byte*)pk->publicKey + m + l;
|
||||||
|
ocspBufSz = pk->publicKeySz - l;
|
||||||
|
|
||||||
pk->publicKeySz = l;
|
pk->publicKeySz = l;
|
||||||
pk->publicKey = pk->publicKey + m;
|
pk->publicKey = pk->publicKey + m;
|
||||||
pk->isCert = 1;
|
pk->isCert = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @TODO handle OCSP's */
|
||||||
|
if (ocspCount > 0) {
|
||||||
|
WLOG(WS_LOG_INFO, "Peer sent OCSP's, not yet handled");
|
||||||
|
ret = GetSize(&l, ocspBuf, ocspBufSz, &m);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif /* WOLFSSH_CERTS */
|
#endif /* WOLFSSH_CERTS */
|
||||||
|
|
||||||
|
@ -5177,26 +5206,13 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The rest of the fields in the signature are already
|
/* The rest of the fields in the signature are already
|
||||||
* in the buffer. Just need to account for the sizes. */
|
* in the buffer. Just need to account for the sizes, which total
|
||||||
|
* the length of the buffer minus the signature and uint32 size of
|
||||||
|
* signature. */
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
word32 dataToSignSz;
|
word32 dataToSignSz;
|
||||||
|
|
||||||
dataToSignSz = authData->usernameSz +
|
dataToSignSz = len - pk->signatureSz - UINT32_SZ;
|
||||||
authData->serviceNameSz +
|
|
||||||
authData->authNameSz + BOOLEAN_SZ +
|
|
||||||
pk->publicKeyTypeSz + pk->publicKeySz +
|
|
||||||
(UINT32_SZ * 5);
|
|
||||||
|
|
||||||
#ifdef WOLFSSH_CERTS
|
|
||||||
if (pkTypeId == ID_X509V3_SSH_RSA ||
|
|
||||||
pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP256 ||
|
|
||||||
pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP384 ||
|
|
||||||
pkTypeId == ID_X509V3_ECDSA_SHA2_NISTP521) {
|
|
||||||
|
|
||||||
dataToSignSz += pk->publicKeyTypeSz + (UINT32_SZ * 4);
|
|
||||||
}
|
|
||||||
#endif /* WOLFSSH_CERTS */
|
|
||||||
|
|
||||||
ret = wc_HashUpdate(&hash, hashId,
|
ret = wc_HashUpdate(&hash, hashId,
|
||||||
pk->dataToSign, dataToSignSz);
|
pk->dataToSign, dataToSignSz);
|
||||||
}
|
}
|
||||||
|
@ -5210,6 +5226,15 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
||||||
}
|
}
|
||||||
wc_HashFree(&hash, hashId);
|
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, pk->publicKeySz, certCount);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
switch (pkTypeId) {
|
switch (pkTypeId) {
|
||||||
#ifndef WOLFSSH_NO_RSA
|
#ifndef WOLFSSH_NO_RSA
|
||||||
|
@ -9917,6 +9942,7 @@ static int BuildUserAuthRequestEccCert(WOLFSSH* ssh,
|
||||||
byte* r;
|
byte* r;
|
||||||
byte* s;
|
byte* s;
|
||||||
byte sig[139]; /* wc_ecc_sig_size() for a prime521 key. */
|
byte sig[139]; /* wc_ecc_sig_size() for a prime521 key. */
|
||||||
|
byte rs[139]; /* wc_ecc_sig_size() for a prime521 key. */
|
||||||
word32 sigSz = sizeof(sig), rSz, sSz;
|
word32 sigSz = sizeof(sig), rSz, sSz;
|
||||||
byte* checkData = NULL;
|
byte* checkData = NULL;
|
||||||
word32 checkDataSz = 0;
|
word32 checkDataSz = 0;
|
||||||
|
@ -9985,9 +10011,9 @@ static int BuildUserAuthRequestEccCert(WOLFSSH* ssh,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == WS_SUCCESS) {
|
if (ret == WS_SUCCESS) {
|
||||||
rSz = sSz = sizeof(sig) / 2;
|
rSz = sSz = sizeof(rs) / 2;
|
||||||
r = sig;
|
r = rs;
|
||||||
s = sig + rSz;
|
s = rs + rSz;
|
||||||
ret = wc_ecc_sig_to_rs(sig, sigSz, r, &rSz, s, &sSz);
|
ret = wc_ecc_sig_to_rs(sig, sigSz, r, &rSz, s, &sSz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10354,7 +10380,7 @@ int SendUserAuthRequest(WOLFSSH* ssh, byte authId, int addSig)
|
||||||
ret = PrepareUserAuthRequestPublicKey(ssh, &payloadSz, &authData,
|
ret = PrepareUserAuthRequestPublicKey(ssh, &payloadSz, &authData,
|
||||||
keySig_ptr);
|
keySig_ptr);
|
||||||
}
|
}
|
||||||
else if (authId != ID_NONE)
|
else if (authId != ID_NONE && !ssh->userAuthPkDone)
|
||||||
ret = WS_INVALID_ALGO_ID;
|
ret = WS_INVALID_ALGO_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,10 @@ WOLFSSH_CTX* wolfSSH_CTX_new(byte side, void* heap)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = (WOLFSSH_CTX*)WMALLOC(sizeof(WOLFSSH_CTX), heap, DYNTYPE_CTX);
|
ctx = (WOLFSSH_CTX*)WMALLOC(sizeof(WOLFSSH_CTX), heap, DYNTYPE_CTX);
|
||||||
ctx = CtxInit(ctx, side, heap);
|
if (CtxInit(ctx, side, heap) == NULL) {
|
||||||
|
WFREE(ctx, heap, DYNTYPE_CTX);
|
||||||
|
ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_CTX_new(), ctx = %p", ctx);
|
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_CTX_new(), ctx = %p", ctx);
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,8 @@ int wolfSSH_CERTMAN_LoadRootCA_buffer(WOLFSSH_CERTMAN* cm,
|
||||||
const unsigned char* rootCa, word32 rootCaSz);
|
const unsigned char* rootCa, word32 rootCaSz);
|
||||||
|
|
||||||
WOLFSSH_API
|
WOLFSSH_API
|
||||||
int wolfSSH_CERTMAN_VerifyCert_buffer(WOLFSSH_CERTMAN* cm,
|
int wolfSSH_CERTMAN_VerifyCerts_buffer(WOLFSSH_CERTMAN* cm,
|
||||||
const unsigned char* cert, word32 certSz);
|
const unsigned char* cert, word32 certSz, word32 certCount);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
Loading…
Reference in New Issue