forked from wolfSSL/wolfssl
add public key callbacks for ecc sign/verify, examples
This commit is contained in:
14
configure.ac
14
configure.ac
@ -289,6 +289,19 @@ then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Public Key Callbacks
|
||||||
|
AC_ARG_ENABLE([pkcallbacks],
|
||||||
|
[ --enable-pkcallbacks Enable Public Key Callbacks (default: disabled)],
|
||||||
|
[ ENABLED_PKCALLBACKS=$enableval ],
|
||||||
|
[ ENABLED_PKCALLBACKS=no ]
|
||||||
|
)
|
||||||
|
|
||||||
|
if test "$ENABLED_PKCALLBACKS" = "yes"
|
||||||
|
then
|
||||||
|
AM_CFLAGS="$AM_CFLAGS -DHAVE_PK_CALLBACKS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
# SNIFFER
|
# SNIFFER
|
||||||
AC_ARG_ENABLE([sniffer],
|
AC_ARG_ENABLE([sniffer],
|
||||||
[AS_HELP_STRING([--enable-sniffer],[ Enable CyaSSL sniffer support (default: disabled) ])],[
|
[AS_HELP_STRING([--enable-sniffer],[ Enable CyaSSL sniffer support (default: disabled) ])],[
|
||||||
@ -1498,6 +1511,7 @@ echo " * CRL-MONITOR: $ENABLED_CRL_MONITOR"
|
|||||||
echo " * Persistent session cache: $ENABLED_SAVESESSION"
|
echo " * Persistent session cache: $ENABLED_SAVESESSION"
|
||||||
echo " * Persistent cert cache: $ENABLED_SAVECERT"
|
echo " * Persistent cert cache: $ENABLED_SAVECERT"
|
||||||
echo " * Atomic User Record Layer: $ENABLED_ATOMICUSER"
|
echo " * Atomic User Record Layer: $ENABLED_ATOMICUSER"
|
||||||
|
echo " * Public Key Callbacks: $ENABLED_PKCALLBACKS"
|
||||||
echo " * NTRU: $ENABLED_NTRU"
|
echo " * NTRU: $ENABLED_NTRU"
|
||||||
echo " * SNI: $ENABLED_SNI"
|
echo " * SNI: $ENABLED_SNI"
|
||||||
echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT"
|
echo " * Maximum Fragment Length: $ENABLED_MAX_FRAGMENT"
|
||||||
|
@ -1245,8 +1245,8 @@ void ecc_free(ecc_key* key)
|
|||||||
key The corresponding public ECC key
|
key The corresponding public ECC key
|
||||||
return MP_OKAY if successful (even if the signature is not valid)
|
return MP_OKAY if successful (even if the signature is not valid)
|
||||||
*/
|
*/
|
||||||
int ecc_verify_hash(const byte* sig, word32 siglen, byte* hash, word32 hashlen,
|
int ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
|
||||||
int* stat, ecc_key* key)
|
word32 hashlen, int* stat, ecc_key* key)
|
||||||
{
|
{
|
||||||
ecc_point *mG, *mQ;
|
ecc_point *mG, *mQ;
|
||||||
mp_int r;
|
mp_int r;
|
||||||
@ -1324,7 +1324,7 @@ int ecc_verify_hash(const byte* sig, word32 siglen, byte* hash, word32 hashlen,
|
|||||||
/* truncate down to byte size, may be all that's needed */
|
/* truncate down to byte size, may be all that's needed */
|
||||||
if ( (CYASSL_BIT_SIZE * hashlen) > orderBits)
|
if ( (CYASSL_BIT_SIZE * hashlen) > orderBits)
|
||||||
hashlen = (orderBits + CYASSL_BIT_SIZE - 1)/CYASSL_BIT_SIZE;
|
hashlen = (orderBits + CYASSL_BIT_SIZE - 1)/CYASSL_BIT_SIZE;
|
||||||
err = mp_read_unsigned_bin(&e, (byte*)hash, hashlen);
|
err = mp_read_unsigned_bin(&e, hash, hashlen);
|
||||||
|
|
||||||
/* may still need bit truncation too */
|
/* may still need bit truncation too */
|
||||||
if (err == MP_OKAY && (CYASSL_BIT_SIZE * hashlen) > orderBits)
|
if (err == MP_OKAY && (CYASSL_BIT_SIZE * hashlen) > orderBits)
|
||||||
|
@ -356,7 +356,7 @@ CYASSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType);
|
|||||||
CYASSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen,
|
CYASSL_LOCAL int DecodeECC_DSA_Sig(const byte* sig, word32 sigLen,
|
||||||
mp_int* r, mp_int* s);
|
mp_int* r, mp_int* s);
|
||||||
/* private key helpers */
|
/* private key helpers */
|
||||||
CYASSL_LOCAL int EccPrivateKeyDecode(const byte* input,word32* inOutIdx,
|
CYASSL_API int EccPrivateKeyDecode(const byte* input,word32* inOutIdx,
|
||||||
ecc_key*,word32);
|
ecc_key*,word32);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -91,8 +91,8 @@ CYASSL_API
|
|||||||
int ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
int ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen,
|
||||||
RNG* rng, ecc_key* key);
|
RNG* rng, ecc_key* key);
|
||||||
CYASSL_API
|
CYASSL_API
|
||||||
int ecc_verify_hash(const byte* sig, word32 siglen, byte* hash, word32 hashlen,
|
int ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
|
||||||
int* stat, ecc_key* key);
|
word32 hashlen, int* stat, ecc_key* key);
|
||||||
CYASSL_API
|
CYASSL_API
|
||||||
void ecc_init(ecc_key* key);
|
void ecc_init(ecc_key* key);
|
||||||
CYASSL_API
|
CYASSL_API
|
||||||
|
@ -1264,6 +1264,12 @@ struct CYASSL_CTX {
|
|||||||
CallbackMacEncrypt MacEncryptCb; /* Atomic User Mac/Encrypt Cb */
|
CallbackMacEncrypt MacEncryptCb; /* Atomic User Mac/Encrypt Cb */
|
||||||
CallbackDecryptVerify DecryptVerifyCb; /* Atomic User Decrypt/Verify Cb */
|
CallbackDecryptVerify DecryptVerifyCb; /* Atomic User Decrypt/Verify Cb */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
CallbackEccSign EccSignCb; /* User EccSign Callback handler */
|
||||||
|
CallbackEccVerify EccVerifyCb; /* User EccVerify Callback handler */
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /* HAVE_PK_CALLBACKS */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1556,6 +1562,11 @@ typedef struct Buffers {
|
|||||||
#ifdef CYASSL_DTLS
|
#ifdef CYASSL_DTLS
|
||||||
CYASSL_DTLS_CTX dtlsCtx; /* DTLS connection context */
|
CYASSL_DTLS_CTX dtlsCtx; /* DTLS connection context */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
buffer peerEccDsaKey; /* we own for Ecc Verify Callbacks */
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /* HAVE_PK_CALLBACKS */
|
||||||
} Buffers;
|
} Buffers;
|
||||||
|
|
||||||
typedef struct Options {
|
typedef struct Options {
|
||||||
@ -1831,6 +1842,12 @@ struct CYASSL {
|
|||||||
void* MacEncryptCtx; /* Atomic User Mac/Encrypt Callback Context */
|
void* MacEncryptCtx; /* Atomic User Mac/Encrypt Callback Context */
|
||||||
void* DecryptVerifyCtx; /* Atomic User Decrypt/Verify Callback Context */
|
void* DecryptVerifyCtx; /* Atomic User Decrypt/Verify Callback Context */
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
void* EccSignCtx; /* Ecc Sign Callback Context */
|
||||||
|
void* EccVerifyCtx; /* Ecc Verify Callback Context */
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /* HAVE_PK_CALLBACKS */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
21
cyassl/ssl.h
21
cyassl/ssl.h
@ -1004,6 +1004,27 @@ enum BulkCipherAlgorithm {
|
|||||||
cyassl_rabbit
|
cyassl_rabbit
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Public Key Callback support */
|
||||||
|
typedef int (*CallbackEccSign)(CYASSL* ssl,
|
||||||
|
const unsigned char* in, unsigned int inSz,
|
||||||
|
unsigned char* out, unsigned int* outSz,
|
||||||
|
const unsigned char* keyDer, unsigned int keySz,
|
||||||
|
void* ctx);
|
||||||
|
CYASSL_API void CyaSSL_CTX_SetEccSignCb(CYASSL_CTX*, CallbackEccSign);
|
||||||
|
CYASSL_API void CyaSSL_SetEccSignCtx(CYASSL* ssl, void *ctx);
|
||||||
|
CYASSL_API void* CyaSSL_GetEccSignCtx(CYASSL* ssl);
|
||||||
|
|
||||||
|
typedef int (*CallbackEccVerify)(CYASSL* ssl,
|
||||||
|
const unsigned char* sig, unsigned int sigSz,
|
||||||
|
const unsigned char* hash, unsigned int hashSz,
|
||||||
|
const unsigned char* keyDer, unsigned int keySz,
|
||||||
|
int* result, void* ctx);
|
||||||
|
CYASSL_API void CyaSSL_CTX_SetEccVerifyCb(CYASSL_CTX*, CallbackEccVerify);
|
||||||
|
CYASSL_API void CyaSSL_SetEccVerifyCtx(CYASSL* ssl, void *ctx);
|
||||||
|
CYASSL_API void* CyaSSL_GetEccVerifyCtx(CYASSL* ssl);
|
||||||
|
|
||||||
|
|
||||||
#ifndef NO_CERTS
|
#ifndef NO_CERTS
|
||||||
CYASSL_API void CyaSSL_CTX_SetCACb(CYASSL_CTX*, CallbackCACache);
|
CYASSL_API void CyaSSL_CTX_SetCACb(CYASSL_CTX*, CallbackCACache);
|
||||||
|
|
||||||
|
@ -15,6 +15,13 @@
|
|||||||
#include <cyassl/ctaocrypt/arc4.h>
|
#include <cyassl/ctaocrypt/arc4.h>
|
||||||
#include <cyassl/ctaocrypt/hmac.h>
|
#include <cyassl/ctaocrypt/hmac.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#include <cyassl/ctaocrypt/random.h>
|
||||||
|
#include <cyassl/ctaocrypt/asn.h>
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
#include <cyassl/ctaocrypt/ecc.h>
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /*HAVE_PK_CALLBACKS */
|
||||||
|
|
||||||
#ifdef USE_WINDOWS_API
|
#ifdef USE_WINDOWS_API
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
@ -1493,6 +1500,66 @@ static INLINE void FreeAtomicUser(CYASSL* ssl)
|
|||||||
#endif /* ATOMIC_USER */
|
#endif /* ATOMIC_USER */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
|
||||||
|
static INLINE int myEccSign(CYASSL* ssl, const byte* in, word32 inSz,
|
||||||
|
byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx)
|
||||||
|
{
|
||||||
|
RNG rng;
|
||||||
|
int ret;
|
||||||
|
word32 idx = 0;
|
||||||
|
ecc_key myKey;
|
||||||
|
|
||||||
|
(void)ssl;
|
||||||
|
(void)ctx;
|
||||||
|
|
||||||
|
InitRng(&rng);
|
||||||
|
ecc_init(&myKey);
|
||||||
|
|
||||||
|
ret = EccPrivateKeyDecode(key, &idx, &myKey, keySz);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = ecc_sign_hash(in, inSz, out, outSz, &rng, &myKey);
|
||||||
|
ecc_free(&myKey);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static INLINE int myEccVerify(CYASSL* ssl, const byte* sig, word32 sigSz,
|
||||||
|
const byte* hash, word32 hashSz, const byte* key, word32 keySz,
|
||||||
|
int* result, void* ctx)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ecc_key myKey;
|
||||||
|
|
||||||
|
(void)ssl;
|
||||||
|
(void)ctx;
|
||||||
|
|
||||||
|
ecc_init(&myKey);
|
||||||
|
|
||||||
|
ret = ecc_import_x963(key, keySz, &myKey);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = ecc_verify_hash(sig, sigSz, hash, hashSz, result, &myKey);
|
||||||
|
ecc_free(&myKey);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static INLINE void SetupPkCallbacks(CYASSL_CTX* ctx, CYASSL* ssl)
|
||||||
|
{
|
||||||
|
(void)ctx;
|
||||||
|
(void)ssl;
|
||||||
|
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
CyaSSL_CTX_SetEccSignCb(ctx, myEccSign);
|
||||||
|
CyaSSL_CTX_SetEccVerifyCb(ctx, myEccVerify);
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_PK_CALLBACKS */
|
||||||
|
|
||||||
|
|
||||||
#if defined(__hpux__) || defined(__MINGW32__)
|
#if defined(__hpux__) || defined(__MINGW32__)
|
||||||
|
|
||||||
/* HP/UX doesn't have strsep, needed by test/suites.c */
|
/* HP/UX doesn't have strsep, needed by test/suites.c */
|
||||||
|
@ -146,6 +146,9 @@ static void Usage(void)
|
|||||||
#ifdef ATOMIC_USER
|
#ifdef ATOMIC_USER
|
||||||
printf("-U Atomic User Record Layer Callbacks\n");
|
printf("-U Atomic User Record Layer Callbacks\n");
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
printf("-P Public Key Callbacks\n");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -190,6 +193,7 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
|
|||||||
int useClientCert = 1;
|
int useClientCert = 1;
|
||||||
int fewerPackets = 0;
|
int fewerPackets = 0;
|
||||||
int atomicUser = 0;
|
int atomicUser = 0;
|
||||||
|
int pkCallbacks = 0;
|
||||||
char* cipherList = NULL;
|
char* cipherList = NULL;
|
||||||
char* verifyCert = (char*)caCert;
|
char* verifyCert = (char*)caCert;
|
||||||
char* ourCert = (char*)cliCert;
|
char* ourCert = (char*)cliCert;
|
||||||
@ -226,11 +230,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
|
|||||||
(void)sslResume;
|
(void)sslResume;
|
||||||
(void)trackMemory;
|
(void)trackMemory;
|
||||||
(void)atomicUser;
|
(void)atomicUser;
|
||||||
|
(void)pkCallbacks;
|
||||||
|
|
||||||
StackTrap();
|
StackTrap();
|
||||||
|
|
||||||
while ((ch = mygetopt(argc, argv,
|
while ((ch = mygetopt(argc, argv,
|
||||||
"?gdusmNrtfxUh:p:v:l:A:c:k:b:zS:L:ToO:")) != -1) {
|
"?gdusmNrtfxUPh:p:v:l:A:c:k:b:zS:L:ToO:")) != -1) {
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case '?' :
|
case '?' :
|
||||||
Usage();
|
Usage();
|
||||||
@ -276,6 +281,12 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'P' :
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
pkCallbacks = 1;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
|
||||||
case 'h' :
|
case 'h' :
|
||||||
host = myoptarg;
|
host = myoptarg;
|
||||||
domain = myoptarg;
|
domain = myoptarg;
|
||||||
@ -608,6 +619,10 @@ THREAD_RETURN CYASSL_THREAD client_test(void* args)
|
|||||||
#ifdef ATOMIC_USER
|
#ifdef ATOMIC_USER
|
||||||
if (atomicUser)
|
if (atomicUser)
|
||||||
SetupAtomicUser(ctx, ssl);
|
SetupAtomicUser(ctx, ssl);
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
if (pkCallbacks)
|
||||||
|
SetupPkCallbacks(ctx, ssl);
|
||||||
#endif
|
#endif
|
||||||
if (matchName && doPeerCheck)
|
if (matchName && doPeerCheck)
|
||||||
CyaSSL_check_domain_name(ssl, domain);
|
CyaSSL_check_domain_name(ssl, domain);
|
||||||
|
148
src/internal.c
148
src/internal.c
@ -432,6 +432,12 @@ int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method)
|
|||||||
ctx->MacEncryptCb = NULL;
|
ctx->MacEncryptCb = NULL;
|
||||||
ctx->DecryptVerifyCb = NULL;
|
ctx->DecryptVerifyCb = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
ctx->EccSignCb = NULL;
|
||||||
|
ctx->EccVerifyCb = NULL;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /* HAVE_PK_CALLBACKS */
|
||||||
|
|
||||||
if (InitMutex(&ctx->countMutex) < 0) {
|
if (InitMutex(&ctx->countMutex) < 0) {
|
||||||
CYASSL_MSG("Mutex error on CTX init");
|
CYASSL_MSG("Mutex error on CTX init");
|
||||||
@ -1271,6 +1277,12 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
|||||||
ssl->buffers.clearOutputBuffer.length = 0;
|
ssl->buffers.clearOutputBuffer.length = 0;
|
||||||
ssl->buffers.prevSent = 0;
|
ssl->buffers.prevSent = 0;
|
||||||
ssl->buffers.plainSz = 0;
|
ssl->buffers.plainSz = 0;
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
ssl->buffers.peerEccDsaKey.buffer = 0;
|
||||||
|
ssl->buffers.peerEccDsaKey.length = 0;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /* HAVE_PK_CALLBACKS */
|
||||||
|
|
||||||
#ifdef KEEP_PEER_CERT
|
#ifdef KEEP_PEER_CERT
|
||||||
InitX509(&ssl->peerCert, 0);
|
InitX509(&ssl->peerCert, 0);
|
||||||
@ -1484,6 +1496,13 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx)
|
|||||||
ssl->MacEncryptCtx = NULL;
|
ssl->MacEncryptCtx = NULL;
|
||||||
ssl->DecryptVerifyCtx = NULL;
|
ssl->DecryptVerifyCtx = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
ssl->EccSignCtx = NULL;
|
||||||
|
ssl->EccVerifyCtx = NULL;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /* HAVE_PK_CALLBACKS */
|
||||||
|
|
||||||
/* all done with init, now can return errors, call other stuff */
|
/* all done with init, now can return errors, call other stuff */
|
||||||
|
|
||||||
/* increment CTX reference count */
|
/* increment CTX reference count */
|
||||||
@ -1692,6 +1711,11 @@ void SSL_ResourceFree(CYASSL* ssl)
|
|||||||
XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
|
XFREE(ssl->eccDsaKey, ssl->heap, DYNAMIC_TYPE_ECC);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /* HAVE_PK_CALLBACKS */
|
||||||
#ifdef HAVE_TLS_EXTENSIONS
|
#ifdef HAVE_TLS_EXTENSIONS
|
||||||
TLSX_FreeAll(ssl->extensions);
|
TLSX_FreeAll(ssl->extensions);
|
||||||
#endif
|
#endif
|
||||||
@ -1779,6 +1803,12 @@ void FreeHandshakeResources(CYASSL* ssl)
|
|||||||
ssl->eccDsaKey = NULL;
|
ssl->eccDsaKey = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC);
|
||||||
|
ssl->buffers.peerEccDsaKey.buffer = NULL;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /* HAVE_PK_CALLBACKS */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3234,8 +3264,24 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx)
|
|||||||
ssl->peerEccDsaKey) != 0) {
|
ssl->peerEccDsaKey) != 0) {
|
||||||
ret = PEER_KEY_ERROR;
|
ret = PEER_KEY_ERROR;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
ssl->peerEccDsaKeyPresent = 1;
|
ssl->peerEccDsaKeyPresent = 1;
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
ssl->buffers.peerEccDsaKey.buffer =
|
||||||
|
XMALLOC(dCert.pubKeySize,
|
||||||
|
ssl->heap, DYNAMIC_TYPE_ECC);
|
||||||
|
if (ssl->buffers.peerEccDsaKey.buffer == NULL)
|
||||||
|
ret = MEMORY_ERROR;
|
||||||
|
else {
|
||||||
|
XMEMCPY(ssl->buffers.peerEccDsaKey.buffer,
|
||||||
|
dCert.publicKey, dCert.pubKeySize);
|
||||||
|
ssl->buffers.peerEccDsaKey.length =
|
||||||
|
dCert.pubKeySize;
|
||||||
|
}
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /*HAVE_PK_CALLBACKS */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* HAVE_ECC */
|
#endif /* HAVE_ECC */
|
||||||
@ -7471,6 +7517,15 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
byte* digest = hash256;
|
byte* digest = hash256;
|
||||||
word32 digestSz = SHA256_DIGEST_SIZE;
|
word32 digestSz = SHA256_DIGEST_SIZE;
|
||||||
#endif
|
#endif
|
||||||
|
byte doUserEcc = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
if (ssl->ctx->EccVerifyCb)
|
||||||
|
doUserEcc = 1;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /*HAVE_PK_CALLBACKS */
|
||||||
|
|
||||||
if (!ssl->peerEccDsaKeyPresent)
|
if (!ssl->peerEccDsaKeyPresent)
|
||||||
return NO_PEER_KEY;
|
return NO_PEER_KEY;
|
||||||
|
|
||||||
@ -7494,9 +7549,21 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (doUserEcc) {
|
||||||
ret = ecc_verify_hash(signature, sigLen, digest, digestSz,
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
&verify, ssl->peerEccDsaKey);
|
#ifdef HAVE_ECC
|
||||||
|
ret = ssl->ctx->EccVerifyCb(ssl, signature, sigLen,
|
||||||
|
digest, digestSz,
|
||||||
|
ssl->buffers.peerEccDsaKey.buffer,
|
||||||
|
ssl->buffers.peerEccDsaKey.length,
|
||||||
|
&verify, ssl->EccVerifyCtx);
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /*HAVE_PK_CALLBACKS */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = ecc_verify_hash(signature, sigLen, digest, digestSz,
|
||||||
|
&verify, ssl->peerEccDsaKey);
|
||||||
|
}
|
||||||
if (ret != 0 || verify == 0)
|
if (ret != 0 || verify == 0)
|
||||||
return VERIFY_SIGN_ERROR;
|
return VERIFY_SIGN_ERROR;
|
||||||
}
|
}
|
||||||
@ -7861,6 +7928,14 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
digestSz = SHA256_DIGEST_SIZE;
|
digestSz = SHA256_DIGEST_SIZE;
|
||||||
digest = ssl->certHashes.sha256;
|
digest = ssl->certHashes.sha256;
|
||||||
#endif
|
#endif
|
||||||
|
byte doUserEcc = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
if (ssl->ctx->EccSignCb)
|
||||||
|
doUserEcc = 1;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /*HAVE_PK_CALLBACKS */
|
||||||
|
|
||||||
if (IsAtLeastTLSv1_2(ssl)) {
|
if (IsAtLeastTLSv1_2(ssl)) {
|
||||||
if (ssl->suites->hashAlgo == sha_mac) {
|
if (ssl->suites->hashAlgo == sha_mac) {
|
||||||
@ -7883,8 +7958,21 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ecc_sign_hash(digest, digestSz, encodedSig,
|
if (doUserEcc) {
|
||||||
&localSz, ssl->rng, &eccKey);
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
|
||||||
|
encodedSig, &localSz,
|
||||||
|
ssl->buffers.key.buffer,
|
||||||
|
ssl->buffers.key.length,
|
||||||
|
ssl->EccSignCtx);
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /*HAVE_PK_CALLBACKS */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = ecc_sign_hash(digest, digestSz, encodedSig,
|
||||||
|
&localSz, ssl->rng, &eccKey);
|
||||||
|
}
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
length = localSz;
|
length = localSz;
|
||||||
c16toa((word16)length, verify + extraSz); /* prepend hdr */
|
c16toa((word16)length, verify + extraSz); /* prepend hdr */
|
||||||
@ -8395,6 +8483,14 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
word32 digestSz = SHA256_DIGEST_SIZE;
|
word32 digestSz = SHA256_DIGEST_SIZE;
|
||||||
#endif
|
#endif
|
||||||
word32 sz = sigSz;
|
word32 sz = sigSz;
|
||||||
|
byte doUserEcc = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
if (ssl->ctx->EccSignCb)
|
||||||
|
doUserEcc = 1;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /*HAVE_PK_CALLBACKS */
|
||||||
|
|
||||||
if (IsAtLeastTLSv1_2(ssl)) {
|
if (IsAtLeastTLSv1_2(ssl)) {
|
||||||
if (ssl->suites->hashAlgo == sha_mac) {
|
if (ssl->suites->hashAlgo == sha_mac) {
|
||||||
@ -8417,8 +8513,21 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ecc_sign_hash(digest, digestSz,
|
if (doUserEcc) {
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
ret = ssl->ctx->EccSignCb(ssl, digest, digestSz,
|
||||||
|
output + LENGTH_SZ + idx, &sz,
|
||||||
|
ssl->buffers.key.buffer,
|
||||||
|
ssl->buffers.key.length,
|
||||||
|
ssl->EccSignCtx);
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /*HAVE_PK_CALLBACKS */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ret = ecc_sign_hash(digest, digestSz,
|
||||||
output + LENGTH_SZ + idx, &sz, ssl->rng, &dsaKey);
|
output + LENGTH_SZ + idx, &sz, ssl->rng, &dsaKey);
|
||||||
|
}
|
||||||
#ifndef NO_RSA
|
#ifndef NO_RSA
|
||||||
FreeRsaKey(&rsaKey);
|
FreeRsaKey(&rsaKey);
|
||||||
#endif
|
#endif
|
||||||
@ -9709,6 +9818,14 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
int err = -1;
|
int err = -1;
|
||||||
byte* digest = ssl->certHashes.sha;
|
byte* digest = ssl->certHashes.sha;
|
||||||
word32 digestSz = SHA_DIGEST_SIZE;
|
word32 digestSz = SHA_DIGEST_SIZE;
|
||||||
|
byte doUserEcc = 0;
|
||||||
|
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
if (ssl->ctx->EccVerifyCb)
|
||||||
|
doUserEcc = 1;
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /*HAVE_PK_CALLBACKS */
|
||||||
|
|
||||||
CYASSL_MSG("Doing ECC peer cert verify");
|
CYASSL_MSG("Doing ECC peer cert verify");
|
||||||
|
|
||||||
@ -9729,9 +9846,20 @@ static void PickHashSigAlgo(CYASSL* ssl,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = ecc_verify_hash(sig, sz, digest, digestSz,
|
if (doUserEcc) {
|
||||||
&verify, ssl->peerEccDsaKey);
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
ret = ssl->ctx->EccVerifyCb(ssl, sig, sz, digest, digestSz,
|
||||||
|
ssl->buffers.peerEccDsaKey.buffer,
|
||||||
|
ssl->buffers.peerEccDsaKey.length,
|
||||||
|
&verify, ssl->EccVerifyCtx);
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
#endif /*HAVE_PK_CALLBACKS */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
err = ecc_verify_hash(sig, sz, digest, digestSz,
|
||||||
|
&verify, ssl->peerEccDsaKey);
|
||||||
|
}
|
||||||
if (err == 0 && verify == 1)
|
if (err == 0 && verify == 1)
|
||||||
ret = 0; /* verified */
|
ret = 0; /* verified */
|
||||||
}
|
}
|
||||||
|
55
src/ssl.c
55
src/ssl.c
@ -10385,3 +10385,58 @@ int CyaSSL_CTX_OCSP_set_override_url(CYASSL_CTX* ctx, const char* url)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NO_CERTS
|
||||||
|
#ifdef HAVE_PK_CALLBACKS
|
||||||
|
|
||||||
|
#ifdef HAVE_ECC
|
||||||
|
|
||||||
|
void CyaSSL_CTX_SetEccSignCb(CYASSL_CTX* ctx, CallbackEccSign cb)
|
||||||
|
{
|
||||||
|
if (ctx)
|
||||||
|
ctx->EccSignCb = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CyaSSL_SetEccSignCtx(CYASSL* ssl, void *ctx)
|
||||||
|
{
|
||||||
|
if (ssl)
|
||||||
|
ssl->EccSignCtx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void* CyaSSL_GetEccSignCtx(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
if (ssl)
|
||||||
|
return ssl->EccSignCtx;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CyaSSL_CTX_SetEccVerifyCb(CYASSL_CTX* ctx, CallbackEccVerify cb)
|
||||||
|
{
|
||||||
|
if (ctx)
|
||||||
|
ctx->EccVerifyCb = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CyaSSL_SetEccVerifyCtx(CYASSL* ssl, void *ctx)
|
||||||
|
{
|
||||||
|
if (ssl)
|
||||||
|
ssl->EccVerifyCtx = ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void* CyaSSL_GetEccVerifyCtx(CYASSL* ssl)
|
||||||
|
{
|
||||||
|
if (ssl)
|
||||||
|
return ssl->EccVerifyCtx;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_ECC */
|
||||||
|
|
||||||
|
#endif /* HAVE_PK_CALLBACKS */
|
||||||
|
#endif /* NO_CERTS */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user