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,
|
||||
authData->sf.publicKey.publicKeySz,
|
||||
authHash);
|
||||
#if defined(WOLFSSH_CERTS) && !defined(WOLFSSH_NO_FPKI)
|
||||
/* Display FPKI info UUID and FASC-N */
|
||||
#if defined(WOLFSSH_CERTS) && !defined(WOLFSSH_NO_FPKI) && \
|
||||
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) {
|
||||
DecodedCert cert;
|
||||
byte* uuid;
|
||||
byte* uuid = NULL;
|
||||
word32 fascnSz;
|
||||
word32 uuidSz;
|
||||
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)
|
||||
{
|
||||
WOLFSSH_CERTMAN* ret = NULL;
|
||||
WLOG_ENTER();
|
||||
|
||||
if (cm != NULL) {
|
||||
WMEMSET(cm, 0, sizeof *cm);
|
||||
cm->cm = wolfSSL_CertManagerNew_ex(heap);
|
||||
if (cm->cm != NULL) {
|
||||
int ret;
|
||||
ret = cm;
|
||||
if (ret != NULL) {
|
||||
WMEMSET(ret, 0, sizeof(WOLFSSH_CERTMAN));
|
||||
ret->cm = wolfSSL_CertManagerNew_ex(heap);
|
||||
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);
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
if (err == WOLFSSL_SUCCESS) {
|
||||
WLOG(WS_LOG_CERTMAN, "Enabled OCSP");
|
||||
}
|
||||
else {
|
||||
WLOG(WS_LOG_CERTMAN, "Couldn't enable OCSP");
|
||||
wolfSSL_CertManagerFree(cm->cm);
|
||||
cm = NULL;
|
||||
wolfSSL_CertManagerFree(ret->cm);
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cm = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
WLOG_LEAVE_PTR(cm);
|
||||
return cm;
|
||||
WLOG_LEAVE_PTR(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -190,59 +193,148 @@ enum {
|
|||
};
|
||||
#endif /* WOLFSSH_NO_FPKI */
|
||||
|
||||
int wolfSSH_CERTMAN_VerifyCert_buffer(WOLFSSH_CERTMAN* cm,
|
||||
const unsigned char* cert, word32 certSz)
|
||||
/* if handling a chain it is expected to be the leaf cert first followed by
|
||||
* 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 idx;
|
||||
|
||||
unsigned char **certLoc; /* locations of certificate start */
|
||||
word32 *certLen; /* size of certificate, in sync with certLoc */
|
||||
|
||||
unsigned char *currentPt;
|
||||
word32 currentSz;
|
||||
|
||||
WLOG_ENTER();
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
ret = wolfSSL_CertManagerVerifyBuffer(cm->cm, cert, certSz,
|
||||
WOLFSSL_FILETYPE_ASN1);
|
||||
certLoc = (unsigned char**)WMALLOC(certsCount * sizeof(unsigned char*),
|
||||
cm->heap, DYNTYPE_CERT);
|
||||
certLen = (word32*)WMALLOC(certsCount * sizeof(word32), cm->heap,
|
||||
DYNTYPE_CERT);
|
||||
|
||||
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;
|
||||
currentPt = (unsigned char*)certs; /* set initial certificate pointer */
|
||||
currentSz = 0;
|
||||
|
||||
for (idx = 0; idx < (int)certsCount; idx++) {
|
||||
word32 sz = 0;
|
||||
certLoc[idx] = currentPt;
|
||||
|
||||
/* get the size of the certificate from first sequence */
|
||||
if (currentSz + MAX_SEQ_SZ >= certSz) {
|
||||
ret = WS_BUFFER_E;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
WLOG(WS_LOG_CERTMAN, "cert verify: other error (%d)", ret);
|
||||
ret = WS_CERT_OTHER_E;
|
||||
/* at this point there is at least 5 bytes in currentPt */
|
||||
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) {
|
||||
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) {
|
||||
ret = WS_SUCCESS;
|
||||
}
|
||||
else if (ret == OCSP_CERT_REVOKED) {
|
||||
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;
|
||||
#ifdef HAVE_OCSP
|
||||
if (ret == WS_SUCCESS) {
|
||||
ret = wolfSSL_CertManagerCheckOCSP(cm->cm, (byte*)certLoc[idx],
|
||||
certLen[idx]);
|
||||
|
||||
if (ret == WOLFSSL_SUCCESS) {
|
||||
ret = WS_SUCCESS;
|
||||
}
|
||||
else if (ret == OCSP_CERT_REVOKED) {
|
||||
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
|
||||
/* FPKI checking on the leaf certificate */
|
||||
if (ret == WS_SUCCESS) {
|
||||
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);
|
||||
|
||||
if (ret == 0) {
|
||||
|
@ -387,16 +479,20 @@ static int CheckProfile(DecodedCert* cert, int profile)
|
|||
/* cycle through alt names to check for needed types */
|
||||
current = cert->altNames;
|
||||
while (current != NULL) {
|
||||
#ifdef WOLFSSL_FPKI
|
||||
if (current->oidSum == FASCN_OID) {
|
||||
hasFascN = 1;
|
||||
}
|
||||
#endif /* WOLFSSL_FPKI */
|
||||
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
#ifdef WOLFSSL_FPKI
|
||||
if (wc_GetUUIDFromCert(cert, uuid, &uuidSz) == 0) {
|
||||
hasUUID = 1;
|
||||
}
|
||||
#endif /* WOLFSSL_FPKI */
|
||||
|
||||
/* all must have UUID and worksheet 6 must have FASC-N in addition to
|
||||
* 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 */
|
||||
#ifdef WOLFSSH_CERTS
|
||||
ctx->certMan = wolfSSH_CERTMAN_new(ctx->heap);
|
||||
if (ctx->certMan == NULL)
|
||||
return NULL;
|
||||
#endif /* WOLFSSH_CERTS */
|
||||
ctx->windowSz = DEFAULT_WINDOW_SZ;
|
||||
ctx->maxPacketSz = DEFAULT_MAX_PACKET_SZ;
|
||||
|
@ -767,7 +769,6 @@ int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx,
|
|||
word32 derSz, scratch = 0;
|
||||
union wolfSSH_key *key_ptr = NULL;
|
||||
|
||||
(void)wcType;
|
||||
(void)dynamicType;
|
||||
(void)heap;
|
||||
|
||||
|
@ -846,7 +847,15 @@ int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx,
|
|||
if (ctx->certMan != NULL) {
|
||||
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);
|
||||
if (ret < 0) {
|
||||
WLOG(WS_LOG_DEBUG, "Error %d loading in CA buffer", ret);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
#endif /* WOLFSSH_CERTS */
|
||||
else {
|
||||
|
@ -911,6 +920,8 @@ int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx,
|
|||
end:
|
||||
if (key_ptr)
|
||||
WFREE(key_ptr, heap, dynamicType);
|
||||
|
||||
(void)wcType;
|
||||
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) {
|
||||
byte* pub = NULL;
|
||||
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) {
|
||||
byte* pub = NULL;
|
||||
word32 pubSz;
|
||||
|
@ -5037,6 +5036,9 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
|||
int ret = WS_SUCCESS;
|
||||
int authFailure = 0;
|
||||
byte pkTypeId;
|
||||
#ifdef WOLFSSH_CERTS
|
||||
word32 certCount = 0;
|
||||
#endif
|
||||
|
||||
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);
|
||||
if (pkTypeId == ID_UNKNOWN) {
|
||||
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);
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
if (ret == WS_SUCCESS && !authFailure) {
|
||||
pk->publicKey = buf + begin;
|
||||
begin += pk->publicKeySz;
|
||||
#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_NISTP521) {
|
||||
word32 l = 0, m = 0;
|
||||
word32 ocspCount = 0;
|
||||
byte* ocspBuf = NULL;
|
||||
word32 ocspBufSz = 0;
|
||||
|
||||
/* Skip the name */
|
||||
ret = GetSize(&l, pk->publicKey, pk->publicKeySz, &m);
|
||||
m += l;
|
||||
/* Get the cert count */
|
||||
ret = GetUint32(&l, pk->publicKey, pk->publicKeySz, &m);
|
||||
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) {
|
||||
ocspBuf = (byte*)pk->publicKey + m + l;
|
||||
ocspBufSz = pk->publicKeySz - l;
|
||||
|
||||
pk->publicKeySz = l;
|
||||
pk->publicKey = pk->publicKey + m;
|
||||
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 */
|
||||
|
||||
|
@ -5177,26 +5206,13 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
|
|||
}
|
||||
|
||||
/* 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) {
|
||||
word32 dataToSignSz;
|
||||
|
||||
dataToSignSz = authData->usernameSz +
|
||||
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 */
|
||||
|
||||
dataToSignSz = len - pk->signatureSz - UINT32_SZ;
|
||||
ret = wc_HashUpdate(&hash, hashId,
|
||||
pk->dataToSign, dataToSignSz);
|
||||
}
|
||||
|
@ -5210,6 +5226,15 @@ 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, pk->publicKeySz, certCount);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
switch (pkTypeId) {
|
||||
#ifndef WOLFSSH_NO_RSA
|
||||
|
@ -9917,6 +9942,7 @@ static int BuildUserAuthRequestEccCert(WOLFSSH* ssh,
|
|||
byte* r;
|
||||
byte* s;
|
||||
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;
|
||||
byte* checkData = NULL;
|
||||
word32 checkDataSz = 0;
|
||||
|
@ -9985,9 +10011,9 @@ static int BuildUserAuthRequestEccCert(WOLFSSH* ssh,
|
|||
}
|
||||
|
||||
if (ret == WS_SUCCESS) {
|
||||
rSz = sSz = sizeof(sig) / 2;
|
||||
r = sig;
|
||||
s = sig + rSz;
|
||||
rSz = sSz = sizeof(rs) / 2;
|
||||
r = rs;
|
||||
s = rs + rSz;
|
||||
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,
|
||||
keySig_ptr);
|
||||
}
|
||||
else if (authId != ID_NONE)
|
||||
else if (authId != ID_NONE && !ssh->userAuthPkDone)
|
||||
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 = 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);
|
||||
|
||||
|
|
|
@ -51,8 +51,8 @@ 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);
|
||||
int wolfSSH_CERTMAN_VerifyCerts_buffer(WOLFSSH_CERTMAN* cm,
|
||||
const unsigned char* cert, word32 certSz, word32 certCount);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
Loading…
Reference in New Issue