diff --git a/configure.ac b/configure.ac index e5c56e25e..4f937bbf8 100644 --- a/configure.ac +++ b/configure.ac @@ -206,6 +206,22 @@ then AM_CFLAGS="$AM_CFLAGS -DLARGE_STATIC_BUFFERS -DCYASSL_CERT_GEN -DCYASSL_KEY_GEN -DHUGE_SESSION_CACHE -DOPENSSL_EXTRA -DFP_MAX_BITS=8192 -DCYASSL_DER_LOAD -DCYASSL_ALT_NAMES -DCYASSL_TEST_CERT" fi + +# lean psk build +AC_ARG_ENABLE(leanpsk, + [ --enable-leanpsk Enable Lean PSK build (default: disabled)], + [ ENABLED_LEANPSK=$enableval ], + [ ENABLED_LEANPSK=no ] + ) + +if test "$ENABLED_LEANPSK" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DCYASSL_LEANPSK -DHAVE_NULL_CIPHER -DNO_AES -DNO_FILESYSTEM -DNO_RSA -DNO_DSA -DNO_DH" +fi + +AM_CONDITIONAL([BUILD_LEANPSK], [test "x$ENABLED_LEANPSK" = "xyes"]) + + # fastmath AC_ARG_ENABLE(fastmath, [ --enable-fastmath Enable fast math for BigInts (default: disabled)], @@ -485,7 +501,7 @@ AC_ARG_ENABLE(psk, [ ENABLED_PSK=no ] ) -if test "$ENABLED_PSK" = "no" +if test "$ENABLED_PSK" = "no" && test "$ENABLED_LEANPSK" = "no" then AM_CFLAGS="$AM_CFLAGS -DNO_PSK" fi @@ -758,6 +774,7 @@ echo " * certgen: $ENABLED_CERTGEN" echo " * HC-128: $ENABLED_HC128" echo " * RABBIT: $ENABLED_RABBIT" echo " * PSK: $ENABLED_PSK" +echo " * LEANPSK: $ENABLED_LEANPSK" echo " * ECC: $ENABLED_ECC" echo " * OCSP: $ENABLED_OCSP" echo " * CRL: $ENABLED_CRL" diff --git a/ctaocrypt/benchmark/benchmark.c b/ctaocrypt/benchmark/benchmark.c index 8cd79ffe3..f9434a408 100644 --- a/ctaocrypt/benchmark/benchmark.c +++ b/ctaocrypt/benchmark/benchmark.c @@ -111,14 +111,16 @@ int main(int argc, char** argv) #endif printf("\n"); - + +#ifndef NO_RSA bench_rsa(); +#endif #ifndef NO_DH bench_dh(); #endif -#ifdef CYASSL_KEY_GEN +#if defined(CYASSL_KEY_GEN) && !defined(NO_RSA) bench_rsaKeyGen(); #endif @@ -411,8 +413,12 @@ void bench_ripemd(void) #endif +#if !defined(NO_RSA) || !defined(NO_DH) \ + || defined(CYASSL_KEYGEN) || defined(HAVE_ECC) RNG rng; +#endif +#ifndef NO_RSA void bench_rsa(void) { int i; @@ -467,6 +473,7 @@ void bench_rsa(void) fclose(file); FreeRsaKey(&rsaKey); } +#endif #ifndef NO_DH @@ -527,7 +534,7 @@ void bench_dh(void) } #endif -#ifdef CYASSL_KEY_GEN +#if defined(CYASSL_KEY_GEN) && !defined(NO_RSA) void bench_rsaKeyGen(void) { RsaKey genKey; diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index 4f741de29..af346e27d 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -23,11 +23,14 @@ #include #endif +#ifndef NO_ASN + #ifdef THREADX #include "os.h" /* dc_rtc_api needs */ #include "dc_rtc_api.h" /* to get current time */ #endif +#include #include #include #include @@ -515,6 +518,7 @@ static int GetAlgoId(const byte* input, word32* inOutIdx, word32* oid, return 0; } +#ifndef NO_RSA int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, word32 inSz) @@ -541,6 +545,7 @@ int RsaPrivateKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, return 0; } +#endif /* NO_RSA */ /* Remove PKCS8 header, move beginning of traditional to beginning of input */ int ToTraditional(byte* input, word32 sz) @@ -841,6 +846,7 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password,int passwordSz) #endif /* NO_PWDBASED */ +#ifndef NO_RSA int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, word32 inSz) @@ -906,6 +912,7 @@ int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey* key, return 0; } +#endif #ifndef NO_DH @@ -1159,7 +1166,7 @@ static int GetCertHeader(DecodedCert* cert) return ret; } - +#if !defined(NO_RSA) /* Store Rsa Key, may save later, Dsa could use in future */ static int StoreRsaKey(DecodedCert* cert) { @@ -1181,6 +1188,7 @@ static int StoreRsaKey(DecodedCert* cert) return 0; } +#endif #ifdef HAVE_ECC @@ -1211,100 +1219,111 @@ static int GetKey(DecodedCert* cert) if (GetAlgoId(cert->source, &cert->srcIdx, &cert->keyOID, cert->maxIdx) < 0) return ASN_PARSE_E; - if (cert->keyOID == RSAk) { - byte b = cert->source[cert->srcIdx++]; - if (b != ASN_BIT_STRING) - return ASN_BITSTR_E; + switch (cert->keyOID) { + case DSAk: + /* do nothing */ + break; + #ifndef NO_RSA + case RSAk: + { + byte b = cert->source[cert->srcIdx++]; + if (b != ASN_BIT_STRING) + return ASN_BITSTR_E; - if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) - return ASN_PARSE_E; - b = cert->source[cert->srcIdx++]; - if (b != 0x00) - return ASN_EXPECT_0_E; - } - else if (cert->keyOID == DSAk ) - ; /* do nothing */ -#ifdef HAVE_NTRU - else if (cert->keyOID == NTRUk ) { - const byte* key = &cert->source[tmpIdx]; - byte* next = (byte*)key; - word16 keyLen; - byte keyBlob[MAX_NTRU_KEY_SZ]; - - word32 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, - &keyLen, NULL, &next); - - if (rc != NTRU_OK) - return ASN_NTRU_KEY_E; - if (keyLen > sizeof(keyBlob)) - return ASN_NTRU_KEY_E; - - rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, &keyLen, - keyBlob, &next); - if (rc != NTRU_OK) - return ASN_NTRU_KEY_E; - - if ( (next - key) < 0) - return ASN_NTRU_KEY_E; - - cert->srcIdx = tmpIdx + (next - key); - - cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap, - DYNAMIC_TYPE_PUBLIC_KEY); - if (cert->publicKey == NULL) - return MEMORY_E; - XMEMCPY(cert->publicKey, keyBlob, keyLen); - cert->pubKeyStored = 1; - cert->pubKeySize = keyLen; - } -#endif /* HAVE_NTRU */ -#ifdef HAVE_ECC - else if (cert->keyOID == ECDSAk ) { - word32 oid = 0; - int oidSz = 0; - byte b = cert->source[cert->srcIdx++]; + if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) + return ASN_PARSE_E; + b = cert->source[cert->srcIdx++]; + if (b != 0x00) + return ASN_EXPECT_0_E; - if (b != ASN_OBJECT_ID) - return ASN_OBJECT_ID_E; + return StoreRsaKey(cert); + } + break; + #endif /* NO_RSA */ + #ifdef HAVE_NTRU + case NTRUk: + { + const byte* key = &cert->source[tmpIdx]; + byte* next = (byte*)key; + word16 keyLen; + byte keyBlob[MAX_NTRU_KEY_SZ]; - if (GetLength(cert->source, &cert->srcIdx, &oidSz, cert->maxIdx) < 0) - return ASN_PARSE_E; + word32 rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key, + &keyLen, NULL, &next); - while(oidSz--) - oid += cert->source[cert->srcIdx++]; - if (CheckCurve(oid) < 0) - return ECC_CURVE_OID_E; + if (rc != NTRU_OK) + return ASN_NTRU_KEY_E; + if (keyLen > sizeof(keyBlob)) + return ASN_NTRU_KEY_E; - /* key header */ - b = cert->source[cert->srcIdx++]; - if (b != ASN_BIT_STRING) - return ASN_BITSTR_E; + rc = crypto_ntru_encrypt_subjectPublicKeyInfo2PublicKey(key,&keyLen, + keyBlob, &next); + if (rc != NTRU_OK) + return ASN_NTRU_KEY_E; - if (GetLength(cert->source, &cert->srcIdx, &length, cert->maxIdx) < 0) - return ASN_PARSE_E; - b = cert->source[cert->srcIdx++]; - if (b != 0x00) - return ASN_EXPECT_0_E; + if ( (next - key) < 0) + return ASN_NTRU_KEY_E; - /* actual key, use length - 1 since ate preceding 0 */ - length -= 1; + cert->srcIdx = tmpIdx + (next - key); - cert->publicKey = (byte*) XMALLOC(length, cert->heap, - DYNAMIC_TYPE_PUBLIC_KEY); - if (cert->publicKey == NULL) - return MEMORY_E; - XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length); - cert->pubKeyStored = 1; - cert->pubKeySize = length; + cert->publicKey = (byte*) XMALLOC(keyLen, cert->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (cert->publicKey == NULL) + return MEMORY_E; + XMEMCPY(cert->publicKey, keyBlob, keyLen); + cert->pubKeyStored = 1; + cert->pubKeySize = keyLen; + } + break; + #endif /* HAVE_NTRU */ + #ifdef HAVE_ECC + case ECDSAk: + { + word32 oid = 0; + int oidSz = 0; + byte b = cert->source[cert->srcIdx++]; + + if (b != ASN_OBJECT_ID) + return ASN_OBJECT_ID_E; - cert->srcIdx += length; + if (GetLength(cert->source,&cert->srcIdx,&oidSz,cert->maxIdx) < 0) + return ASN_PARSE_E; + + while(oidSz--) + oid += cert->source[cert->srcIdx++]; + if (CheckCurve(oid) < 0) + return ECC_CURVE_OID_E; + + /* key header */ + b = cert->source[cert->srcIdx++]; + if (b != ASN_BIT_STRING) + return ASN_BITSTR_E; + + if (GetLength(cert->source,&cert->srcIdx,&length,cert->maxIdx) < 0) + return ASN_PARSE_E; + b = cert->source[cert->srcIdx++]; + if (b != 0x00) + return ASN_EXPECT_0_E; + + /* actual key, use length - 1 since ate preceding 0 */ + length -= 1; + + cert->publicKey = (byte*) XMALLOC(length, cert->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (cert->publicKey == NULL) + return MEMORY_E; + XMEMCPY(cert->publicKey, &cert->source[cert->srcIdx], length); + cert->pubKeyStored = 1; + cert->pubKeySize = length; + + cert->srcIdx += length; + } + break; + #endif /* HAVE_ECC */ + default: + return ASN_UNKNOWN_OID_E; } -#endif /* HAVE_ECC */ - else - return ASN_UNKNOWN_OID_E; - if (cert->keyOID == RSAk) - return StoreRsaKey(cert); return 0; } @@ -1833,20 +1852,27 @@ static word32 SetAlgoID(int algoOID, byte* output, int type) 0x02, 0x05, 0x05, 0x00 }; static const byte md2AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x02, 0x05, 0x00}; + /* sigTypes */ - static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x04, 0x05, 0x00}; - static const byte shawRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x05, 0x05, 0x00}; - static const byte sha256wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, + #ifndef NO_RSA + static const byte md5wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x04, 0x05, 0x00}; + static const byte shawRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00}; + static const byte sha256wRSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00}; - static const byte sha384wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + static const byte sha384wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c, 0x05, 0x00}; - static const byte sha512wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + static const byte sha512wRSA_AlgoID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d, 0x05, 0x00}; + #endif /* NO_RSA */ + /* keyTypes */ - static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x01, 0x05, 0x00}; + #ifndef NO_RSA + static const byte RSA_AlgoID[] = { 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x01, 0x05, 0x00}; + #endif /* NO_RSA */ + int algoSz = 0; word32 idSz, seqSz; const byte* algoName = 0; @@ -1892,31 +1918,32 @@ static word32 SetAlgoID(int algoOID, byte* output, int type) } else if (type == sigType) { /* sigType */ switch (algoOID) { - case CTC_MD5wRSA: - algoSz = sizeof(md5wRSA_AlgoID); - algoName = md5wRSA_AlgoID; - break; + #ifndef NO_RSA + case CTC_MD5wRSA: + algoSz = sizeof(md5wRSA_AlgoID); + algoName = md5wRSA_AlgoID; + break; - case CTC_SHAwRSA: - algoSz = sizeof(shawRSA_AlgoID); - algoName = shawRSA_AlgoID; - break; + case CTC_SHAwRSA: + algoSz = sizeof(shawRSA_AlgoID); + algoName = shawRSA_AlgoID; + break; - case CTC_SHA256wRSA: - algoSz = sizeof(sha256wRSA_AlgoID); - algoName = sha256wRSA_AlgoID; - break; + case CTC_SHA256wRSA: + algoSz = sizeof(sha256wRSA_AlgoID); + algoName = sha256wRSA_AlgoID; + break; - case CTC_SHA384wRSA: - algoSz = sizeof(sha384wRSA_AlgoID); - algoName = sha384wRSA_AlgoID; - break; - - case CTC_SHA512wRSA: - algoSz = sizeof(sha512wRSA_AlgoID); - algoName = sha512wRSA_AlgoID; - break; + case CTC_SHA384wRSA: + algoSz = sizeof(sha384wRSA_AlgoID); + algoName = sha384wRSA_AlgoID; + break; + case CTC_SHA512wRSA: + algoSz = sizeof(sha512wRSA_AlgoID); + algoName = sha512wRSA_AlgoID; + break; + #endif /* NO_RSA */ default: CYASSL_MSG("Unknown Signature Algo"); return 0; @@ -1924,11 +1951,12 @@ static word32 SetAlgoID(int algoOID, byte* output, int type) } else if (type == keyType) { /* keyType */ switch (algoOID) { - case RSAk: - algoSz = sizeof(RSA_AlgoID); - algoName = RSA_AlgoID; - break; - + #ifndef NO_RSA + case RSAk: + algoSz = sizeof(RSA_AlgoID); + algoName = RSA_AlgoID; + break; + #endif /* NO_RSA */ default: CYASSL_MSG("Unknown Key Algo"); return 0; @@ -1984,158 +2012,181 @@ static int ConfirmSignature(const byte* buf, word32 bufSz, #else byte digest[SHA_DIGEST_SIZE]; /* max size */ #endif - int typeH, digestSz, ret; + int typeH, digestSz, ret = 0; - if (sigOID == CTC_MD5wRSA) { - Md5 md5; - InitMd5(&md5); - Md5Update(&md5, buf, bufSz); - Md5Final(&md5, digest); - typeH = MD5h; - digestSz = MD5_DIGEST_SIZE; - } -#ifdef CYASSL_MD2 - else if (sigOID == CTC_MD2wRSA) { - Md2 md2; - InitMd2(&md2); - Md2Update(&md2, buf, bufSz); - Md2Final(&md2, digest); - typeH = MD2h; - digestSz = MD2_DIGEST_SIZE; - } -#endif - else if (sigOID == CTC_SHAwRSA || - sigOID == CTC_SHAwDSA || - sigOID == CTC_SHAwECDSA) { - Sha sha; - InitSha(&sha); - ShaUpdate(&sha, buf, bufSz); - ShaFinal(&sha, digest); - typeH = SHAh; - digestSz = SHA_DIGEST_SIZE; - } -#ifndef NO_SHA256 - else if (sigOID == CTC_SHA256wRSA || - sigOID == CTC_SHA256wECDSA) { - Sha256 sha256; - InitSha256(&sha256); - Sha256Update(&sha256, buf, bufSz); - Sha256Final(&sha256, digest); - typeH = SHA256h; - digestSz = SHA256_DIGEST_SIZE; - } -#endif -#ifdef CYASSL_SHA512 - else if (sigOID == CTC_SHA512wRSA || - sigOID == CTC_SHA512wECDSA) { - Sha512 sha512; - InitSha512(&sha512); - Sha512Update(&sha512, buf, bufSz); - Sha512Final(&sha512, digest); - typeH = SHA512h; - digestSz = SHA512_DIGEST_SIZE; - } -#endif -#ifdef CYASSL_SHA384 - else if (sigOID == CTC_SHA384wRSA || - sigOID == CTC_SHA384wECDSA) { - Sha384 sha384; - InitSha384(&sha384); - Sha384Update(&sha384, buf, bufSz); - Sha384Final(&sha384, digest); - typeH = SHA384h; - digestSz = SHA384_DIGEST_SIZE; - } -#endif - else { - CYASSL_MSG("Verify Signautre has unsupported type"); - return 0; - } + (void)key; + (void)keySz; + (void)sig; + (void)sigSz; + (void)heap; - if (keyOID == RSAk) { - RsaKey pubKey; - byte encodedSig[MAX_ENCODED_SIG_SZ]; - byte plain[MAX_ENCODED_SIG_SZ]; - word32 idx = 0; - int encodedSigSz, verifySz; - byte* out; - - if (sigSz > MAX_ENCODED_SIG_SZ) { - CYASSL_MSG("Verify Signautre is too big"); + switch (sigOID) { + case CTC_MD5wRSA: + { + Md5 md5; + InitMd5(&md5); + Md5Update(&md5, buf, bufSz); + Md5Final(&md5, digest); + typeH = MD5h; + digestSz = MD5_DIGEST_SIZE; + } + break; + #if defined(CYASSL_MD2) + case CTC_MD2wRSA: + { + Md2 md2; + InitMd2(&md2); + Md2Update(&md2, buf, bufSz); + Md2Final(&md2, digest); + typeH = MD2h; + digestSz = MD2_DIGEST_SIZE; + } + break; + #endif + case CTC_SHAwRSA: + case CTC_SHAwDSA: + case CTC_SHAwECDSA: + { + Sha sha; + InitSha(&sha); + ShaUpdate(&sha, buf, bufSz); + ShaFinal(&sha, digest); + typeH = SHAh; + digestSz = SHA_DIGEST_SIZE; + } + break; + #ifndef NO_SHA256 + case CTC_SHA256wRSA: + case CTC_SHA256wECDSA: + { + Sha256 sha256; + InitSha256(&sha256); + Sha256Update(&sha256, buf, bufSz); + Sha256Final(&sha256, digest); + typeH = SHA256h; + digestSz = SHA256_DIGEST_SIZE; + } + #endif + #ifdef CYASSL_SHA512 + case CTC_SHA512wRSA: + case CTC_SHA512wECDSA: + { + Sha512 sha512; + InitSha512(&sha512); + Sha512Update(&sha512, buf, bufSz); + Sha512Final(&sha512, digest); + typeH = SHA512h; + digestSz = SHA512_DIGEST_SIZE; + } + #endif + #ifdef CYASSL_SHA384 + case CTC_SHA384wRSA: + case CTC_SHA384wECDSA: + { + Sha384 sha384; + InitSha384(&sha384); + Sha384Update(&sha384, buf, bufSz); + Sha384Final(&sha384, digest); + typeH = SHA384h; + digestSz = SHA384_DIGEST_SIZE; + } + #endif + default: + CYASSL_MSG("Verify Signautre has unsupported type"); return 0; - } - - InitRsaKey(&pubKey, heap); - if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) { - CYASSL_MSG("ASN Key decode error RSA"); - ret = 0; - } - else { - XMEMCPY(plain, sig, sigSz); - if ( (verifySz = RsaSSL_VerifyInline(plain, sigSz, &out, - &pubKey)) < 0) { - CYASSL_MSG("Rsa SSL verify error"); + } + + switch (keyOID) { + #ifndef NO_RSA + case RSAk: + { + RsaKey pubKey; + byte encodedSig[MAX_ENCODED_SIG_SZ]; + byte plain[MAX_ENCODED_SIG_SZ]; + word32 idx = 0; + int encodedSigSz, verifySz; + byte* out; + + if (sigSz > MAX_ENCODED_SIG_SZ) { + CYASSL_MSG("Verify Signautre is too big"); + return 0; + } + + InitRsaKey(&pubKey, heap); + if (RsaPublicKeyDecode(key, &idx, &pubKey, keySz) < 0) { + CYASSL_MSG("ASN Key decode error RSA"); ret = 0; } else { - /* make sure we're right justified */ - encodedSigSz = - EncodeSignature(encodedSig, digest, digestSz, typeH); - if (encodedSigSz != verifySz || - XMEMCMP(out, encodedSig, encodedSigSz) != 0) { - CYASSL_MSG("Rsa SSL verify match encode error"); + XMEMCPY(plain, sig, sigSz); + if ( (verifySz = RsaSSL_VerifyInline(plain, sigSz, &out, + &pubKey)) < 0) { + CYASSL_MSG("Rsa SSL verify error"); ret = 0; } - else - ret = 1; /* match */ + else { + /* make sure we're right justified */ + encodedSigSz = + EncodeSignature(encodedSig, digest, digestSz, typeH); + if (encodedSigSz != verifySz || + XMEMCMP(out, encodedSig, encodedSigSz) != 0) { + CYASSL_MSG("Rsa SSL verify match encode error"); + ret = 0; + } + else + ret = 1; /* match */ -#ifdef CYASSL_DEBUG_ENCODING - { - int x; - printf("cyassl encodedSig:\n"); - for (x = 0; x < encodedSigSz; x++) { - printf("%02x ", encodedSig[x]); - if ( (x % 16) == 15) - printf("\n"); + #ifdef CYASSL_DEBUG_ENCODING + { + int x; + printf("cyassl encodedSig:\n"); + for (x = 0; x < encodedSigSz; x++) { + printf("%02x ", encodedSig[x]); + if ( (x % 16) == 15) + printf("\n"); + } + printf("\n"); + printf("actual digest:\n"); + for (x = 0; x < verifySz; x++) { + printf("%02x ", out[x]); + if ( (x % 16) == 15) + printf("\n"); + } + printf("\n"); + } + #endif /* CYASSL_DEBUG_ENCODING */ } - printf("\n"); - printf("actual digest:\n"); - for (x = 0; x < verifySz; x++) { - printf("%02x ", out[x]); - if ( (x % 16) == 15) - printf("\n"); - } - printf("\n"); - } -#endif /* CYASSL_DEBUG_ENCODING */ } + FreeRsaKey(&pubKey); + return ret; } - FreeRsaKey(&pubKey); - return ret; - } -#ifdef HAVE_ECC - else if (keyOID == ECDSAk) { - ecc_key pubKey; - int verify = 0; + break; + #endif /* NO_RSA */ + #ifdef HAVE_ECC + case ECDSAk: + { + ecc_key pubKey; + int verify = 0; + + if (ecc_import_x963(key, keySz, &pubKey) < 0) { + CYASSL_MSG("ASN Key import error ECC"); + return 0; + } - if (ecc_import_x963(key, keySz, &pubKey) < 0) { - CYASSL_MSG("ASN Key import error ECC"); + ret = ecc_verify_hash(sig, sigSz, digest, digestSz, &verify, &pubKey); + ecc_free(&pubKey); + if (ret == 0 && verify == 1) + return 1; /* match */ + + CYASSL_MSG("ECC Verify didn't match"); return 0; } - - ret = ecc_verify_hash(sig, sigSz, digest, digestSz, &verify, &pubKey); - ecc_free(&pubKey); - if (ret == 0 && verify == 1) - return 1; /* match */ - - CYASSL_MSG("ECC Verify didn't match"); - return 0; - } -#endif /* HAVE_ECC */ - else { - CYASSL_MSG("Verify Key type unknown"); - return 0; + #endif /* HAVE_ECC */ + default: + CYASSL_MSG("Verify Key type unknown"); + return 0; } + return ret; } @@ -2895,7 +2946,7 @@ int DerToPem(const byte* der, word32 derSz, byte* output, word32 outSz, #endif /* CYASSL_KEY_GEN || CYASSL_CERT_GEN */ -#ifdef CYASSL_KEY_GEN +#if defined(CYASSL_KEY_GEN) && !defined(NO_RSA) static mp_int* GetRsaInt(RsaKey* key, int idx) @@ -2982,10 +3033,10 @@ int RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) return outLen; } -#endif /* CYASSL_KEY_GEN */ +#endif /* CYASSL_KEY_GEN && !NO_RSA */ -#ifdef CYASSL_CERT_GEN +#if defined(CYASSL_CERT_GEN) && !defined(NO_RSA) #ifndef min @@ -3918,7 +3969,7 @@ static int SetDatesFromCert(Cert* cert, const byte* der, int derSz) } -#endif /* CYASSL_ALT_NAMES */ +#endif /* CYASSL_ALT_NAMES && !NO_RSA */ /* Set cn name from der buffer, return 0 on success */ @@ -5164,3 +5215,5 @@ int ParseCRL(DecodedCRL* dcrl, const byte* buff, long sz, void* cm) } #endif /* HAVE_CRL */ + +#endif diff --git a/ctaocrypt/src/rsa.c b/ctaocrypt/src/rsa.c index 7f511df1c..5a454babd 100644 --- a/ctaocrypt/src/rsa.c +++ b/ctaocrypt/src/rsa.c @@ -24,6 +24,8 @@ #include #endif +#ifndef NO_RSA + #include #include #include @@ -553,5 +555,6 @@ int MakeRsaKey(RsaKey* key, int size, long e, RNG* rng) } -#endif /* CYASLS_KEY_GEN */ +#endif /* CYASSL_KEY_GEN */ +#endif /* NO_RSA */ diff --git a/ctaocrypt/test/test.c b/ctaocrypt/test/test.c index 4e9f15578..4c574784a 100644 --- a/ctaocrypt/test/test.c +++ b/ctaocrypt/test/test.c @@ -264,10 +264,12 @@ void ctaocrypt_test(void* args) else printf( "RANDOM test passed!\n"); +#ifndef NO_RSA if ( (ret = rsa_test()) ) err_sys("RSA test failed!\n", ret); else printf( "RSA test passed!\n"); +#endif #ifndef NO_DH if ( (ret = dh_test()) ) @@ -1360,14 +1362,6 @@ int random_test(void) } -static const char* clientKey = "./certs/client-key.der"; -static const char* clientCert = "./certs/client-cert.der"; -#ifdef CYASSL_CERT_GEN - static const char* caKeyFile = "./certs/ca-key.der"; - static const char* caCertFile = "./certs/ca-cert.pem"; -#endif - - #ifdef HAVE_NTRU static byte GetEntropy(ENTROPY_CMD cmd, byte* out) @@ -1400,6 +1394,16 @@ static byte GetEntropy(ENTROPY_CMD cmd, byte* out) #endif /* HAVE_NTRU */ +#ifndef NO_RSA + +static const char* clientKey = "./certs/client-key.der"; +static const char* clientCert = "./certs/client-cert.der"; +#ifdef CYASSL_CERT_GEN + static const char* caKeyFile = "./certs/ca-key.der"; + static const char* caCertFile = "./certs/ca-cert.pem"; +#endif + + int rsa_test(void) { byte tmp[2048], tmp2[2048]; @@ -1764,11 +1768,13 @@ int rsa_test(void) return 0; } +#endif -static const char* dhKey = "./certs/dh2048.der"; #ifndef NO_DH +static const char* dhKey = "./certs/dh2048.der"; + int dh_test(void) { int ret; @@ -1829,10 +1835,10 @@ int dh_test(void) #endif /* NO_DH */ -static const char* dsaKey = "./certs/dsa2048.der"; - #ifndef NO_DSA +static const char* dsaKey = "./certs/dsa2048.der"; + int dsa_test(void) { int ret, answer; diff --git a/cyassl/ctaocrypt/asn.h b/cyassl/ctaocrypt/asn.h index cf2ac1cb7..24fe042f4 100644 --- a/cyassl/ctaocrypt/asn.h +++ b/cyassl/ctaocrypt/asn.h @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +//#ifndef NO_ASN #ifndef CTAO_CRYPT_ASN_H #define CTAO_CRYPT_ASN_H @@ -483,3 +484,4 @@ CYASSL_LOCAL void FreeDecodedCRL(DecodedCRL*); #endif /* CTAO_CRYPT_ASN_H */ +//#endif /* NO_ASN */ diff --git a/cyassl/ctaocrypt/rsa.h b/cyassl/ctaocrypt/rsa.h index 70e3fcd1a..5071aa8b0 100644 --- a/cyassl/ctaocrypt/rsa.h +++ b/cyassl/ctaocrypt/rsa.h @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +#ifndef NO_RSA #ifndef CTAO_CRYPT_RSA_H #define CTAO_CRYPT_RSA_H @@ -79,3 +80,4 @@ CYASSL_API int RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey*, #endif /* CTAO_CRYPT_RSA_H */ +#endif /* NO_RSA */ \ No newline at end of file diff --git a/cyassl/internal.h b/cyassl/internal.h index da99f3564..3eff23e3d 100644 --- a/cyassl/internal.h +++ b/cyassl/internal.h @@ -24,9 +24,9 @@ #define CYASSL_INT_H +#include #include #include -#include #include #include #include @@ -124,7 +124,7 @@ void c32to24(word32 in, word24 out); When adding cipher suites, add name to cipher_names, idx to cipher_name_idx */ -#ifndef NO_RC4 +#if !defined(NO_RSA) && !defined(NO_RC4) #define BUILD_SSL_RSA_WITH_RC4_128_SHA #define BUILD_SSL_RSA_WITH_RC4_128_MD5 #if !defined(NO_TLS) && defined(HAVE_NTRU) @@ -132,20 +132,16 @@ void c32to24(word32 in, word24 out); #endif #endif -#ifndef NO_DES3 +#if !defined(NO_RSA) && !defined(NO_DES3) #define BUILD_SSL_RSA_WITH_3DES_EDE_CBC_SHA #if !defined(NO_TLS) && defined(HAVE_NTRU) #define BUILD_TLS_NTRU_RSA_WITH_3DES_EDE_CBC_SHA #endif #endif -#if !defined(NO_AES) && !defined(NO_TLS) +#if !defined(NO_RSA) && !defined(NO_AES) && !defined(NO_TLS) #define BUILD_TLS_RSA_WITH_AES_128_CBC_SHA #define BUILD_TLS_RSA_WITH_AES_256_CBC_SHA - #if !defined (NO_PSK) - #define BUILD_TLS_PSK_WITH_AES_128_CBC_SHA - #define BUILD_TLS_PSK_WITH_AES_256_CBC_SHA - #endif #if defined(HAVE_NTRU) #define BUILD_TLS_NTRU_RSA_WITH_AES_128_CBC_SHA #define BUILD_TLS_NTRU_RSA_WITH_AES_256_CBC_SHA @@ -160,24 +156,31 @@ void c32to24(word32 in, word24 out); #endif #endif +#if !defined(NO_PSK) && !defined(NO_AES) && !defined(NO_TLS) + #define BUILD_TLS_PSK_WITH_AES_128_CBC_SHA + #define BUILD_TLS_PSK_WITH_AES_256_CBC_SHA +#endif + #if !defined(NO_TLS) && defined(HAVE_NULL_CIPHER) - #define BUILD_TLS_RSA_WITH_NULL_SHA - #define BUILD_TLS_RSA_WITH_NULL_SHA256 + #if !defined(NO_RSA) + #define BUILD_TLS_RSA_WITH_NULL_SHA + #define BUILD_TLS_RSA_WITH_NULL_SHA256 + #endif #if !defined(NO_PSK) #define BUILD_TLS_PSK_WITH_NULL_SHA #endif #endif -#if !defined(NO_HC128) && !defined(NO_TLS) +#if !defined(NO_HC128) && !defined(NO_RSA) && !defined(NO_TLS) #define BUILD_TLS_RSA_WITH_HC_128_CBC_MD5 #define BUILD_TLS_RSA_WITH_HC_128_CBC_SHA #endif -#if !defined(NO_RABBIT) && !defined(NO_TLS) +#if !defined(NO_RABBIT) && !defined(NO_TLS) && !defined(NO_RSA) #define BUILD_TLS_RSA_WITH_RABBIT_CBC_SHA #endif -#if !defined(NO_DH) && !defined(NO_AES) && !defined(NO_TLS) && defined(OPENSSL_EXTRA) +#if !defined(NO_DH) && !defined(NO_AES) && !defined(NO_TLS) && !defined(NO_RSA) && defined(OPENSSL_EXTRA) #define BUILD_TLS_DHE_RSA_WITH_AES_128_CBC_SHA #define BUILD_TLS_DHE_RSA_WITH_AES_256_CBC_SHA #if !defined (NO_SHA256) @@ -661,7 +664,8 @@ typedef struct Suites { CYASSL_LOCAL -void InitSuites(Suites*, ProtocolVersion, byte, byte, byte, byte, byte, int); +void InitSuites(Suites*, ProtocolVersion, + byte, byte, byte, byte, byte, byte, int); CYASSL_LOCAL int SetCipherList(Suites*, const char* list); @@ -836,6 +840,7 @@ struct CYASSL_CTX { byte sessionCacheOff; byte sessionCacheFlushOff; byte sendVerify; /* for client side */ + byte haveRSA; /* RSA available */ byte haveDH; /* server DH parms set by user */ byte haveNTRU; /* server private NTRU key loaded */ byte haveECDSAsig; /* server cert signed w/ ECDSA */ @@ -1174,6 +1179,7 @@ typedef struct Options { byte connectState; /* nonblocking resume */ byte acceptState; /* nonblocking resume */ byte usingCompression; /* are we using compression */ + byte haveRSA; /* RSA available */ byte haveDH; /* server DH parms set by user */ byte haveNTRU; /* server NTRU private key loaded */ byte haveECDSAsig; /* server ECDSA signed cert */ @@ -1294,8 +1300,10 @@ struct CYASSL { Arrays* arrays; CYASSL_SESSION session; VerifyCallback verifyCallback; /* cert verification callback */ +#ifndef NO_RSA RsaKey* peerRsaKey; byte peerRsaKeyPresent; +#endif #ifdef HAVE_NTRU word16 peerNtruKeyLen; byte peerNtruKey[MAX_NTRU_PUB_KEY_SZ]; diff --git a/examples/client/client.c b/examples/client/client.c index ced6041f2..9fc2f70bd 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -300,21 +300,23 @@ void client_test(void* args) #ifdef VERIFY_CALLBACK CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, myVerify); #endif - - if (CyaSSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM) +#ifndef NO_FILESYSTEM + if (!usePsk){ + if (CyaSSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM) != SSL_SUCCESS) - err_sys("can't load client cert file, check file and run from" - " CyaSSL home dir"); + err_sys("can't load client cert file, check file and run from" + " CyaSSL home dir"); - if (CyaSSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM) - != SSL_SUCCESS) - err_sys("can't load client cert file, check file and run from" - " CyaSSL home dir"); + if (CyaSSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM) + != SSL_SUCCESS) + err_sys("can't load client cert file, check file and run from" + " CyaSSL home dir"); - if (CyaSSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS) - err_sys("can't load ca file, Please run from CyaSSL home dir"); - - if (doPeerCheck == 0) + if (CyaSSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS) + err_sys("can't load ca file, Please run from CyaSSL home dir"); + } +#endif + if (!usePsk && doPeerCheck == 0) CyaSSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); if (benchmark) { diff --git a/examples/server/server.c b/examples/server/server.c index 16dd5c351..c1f6f16b5 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -242,11 +242,14 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) if (SSL_CTX_set_cipher_list(ctx, cipherList) != SSL_SUCCESS) err_sys("can't set cipher list"); - if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM) - != SSL_SUCCESS) - err_sys("can't load server cert file, check file and run from" - " CyaSSL home dir"); - +#ifndef NO_FILESYSTEM + if (!usePsk) { + if (SSL_CTX_use_certificate_file(ctx, ourCert, SSL_FILETYPE_PEM) + != SSL_SUCCESS) + err_sys("can't load server cert file, check file and run from" + " CyaSSL home dir"); + } +#endif #ifdef HAVE_NTRU if (useNtruKey) { @@ -257,12 +260,14 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) } #endif - if (!useNtruKey) { +#ifndef NO_FILESYSTEM + if (!useNtruKey && !usePsk) { if (SSL_CTX_use_PrivateKey_file(ctx, ourKey, SSL_FILETYPE_PEM) != SSL_SUCCESS) err_sys("can't load server cert file, check file and run from" " CyaSSL home dir"); } +#endif #ifndef NO_PSK if (usePsk) { @@ -274,6 +279,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) } #endif +#ifndef NO_FILESYSTEM /* if not using PSK, verify peer with certs */ if (doCliCertCheck && usePsk == 0) { SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | @@ -281,6 +287,7 @@ THREAD_RETURN CYASSL_THREAD server_test(void* args) if (SSL_CTX_load_verify_locations(ctx, verifyCert, 0) != SSL_SUCCESS) err_sys("can't load ca file, Please run from CyaSSL home dir"); } +#endif #ifdef OPENSSL_EXTRA SSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); diff --git a/src/include.am b/src/include.am index 0bdd84fb1..f19507270 100644 --- a/src/include.am +++ b/src/include.am @@ -16,12 +16,8 @@ src_libcyassl_la_SOURCES = \ ctaocrypt/src/md5.c \ ctaocrypt/src/md4.c \ ctaocrypt/src/random.c \ - ctaocrypt/src/rsa.c \ ctaocrypt/src/sha.c \ - ctaocrypt/src/aes.c \ ctaocrypt/src/sha256.c \ - ctaocrypt/src/dh.c \ - ctaocrypt/src/dsa.c \ ctaocrypt/src/arc4.c \ ctaocrypt/src/pwdbased.c \ ctaocrypt/src/logging.c \ @@ -31,6 +27,13 @@ src_libcyassl_la_LIBADD = $(LIBM) src_libcyassl_la_CFLAGS = -DBUILDING_CYASSL $(AM_CFLAGS) src_libcyassl_la_CPPFLAGS = -DBUILDING_CYASSL $(AM_CPPFLAGS) +if !BUILD_LEANPSK +src_libcyassl_la_SOURCES += ctaocrypt/src/rsa.c \ + ctaocrypt/src/dh.c \ + ctaocrypt/src/dsa.c \ + ctaocrypt/src/aes.c +endif + if BUILD_AESNI src_libcyassl_la_SOURCES += ctaocrypt/src/aes_asm.s endif diff --git a/src/internal.c b/src/internal.c index 43f44441d..786916c89 100644 --- a/src/internal.c +++ b/src/internal.c @@ -64,8 +64,10 @@ #ifndef NO_CYASSL_SERVER static int DoClientHello(CYASSL* ssl, const byte* input, word32*, word32, word32); - static int DoCertificateVerify(CYASSL* ssl, byte*, word32*, word32); static int DoClientKeyExchange(CYASSL* ssl, byte* input, word32*); + #if !defined(NO_RSA) || defined(HAVE_ECC) + static int DoCertificateVerify(CYASSL* ssl, byte*, word32*, word32); + #endif #endif typedef enum { @@ -373,7 +375,7 @@ int InitSSL_Ctx(CYASSL_CTX* ctx, CYASSL_METHOD* method) #endif ctx->suites.setSuites = 0; /* user hasn't set yet */ /* remove DH later if server didn't set, add psk later */ - InitSuites(&ctx->suites, method->version, TRUE, FALSE, ctx->haveNTRU, + InitSuites(&ctx->suites, method->version, TRUE, FALSE, TRUE, ctx->haveNTRU, ctx->haveECDSAsig, ctx->haveStaticECC, method->side); ctx->verifyPeer = 0; ctx->verifyNone = 0; @@ -513,13 +515,13 @@ void InitCipherSpecs(CipherSpecs* cs) } -void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK, - byte haveNTRU, byte haveECDSAsig, byte haveStaticECC, int side) +void InitSuites(Suites* suites, ProtocolVersion pv, byte haveRSA, byte havePSK, + byte haveDH, byte haveNTRU, byte haveECDSAsig, + byte haveStaticECC, int side) { word16 idx = 0; int tls = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_MINOR; int tls1_2 = pv.major == SSLv3_MAJOR && pv.minor >= TLSv1_2_MINOR; - int haveRSA = 1; int haveRSAsig = 1; (void)tls; /* shut up compiler */ @@ -916,6 +918,7 @@ void InitSuites(Suites* suites, ProtocolVersion pv, byte haveDH, byte havePSK, int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) { int ret; + byte haveRSA = 0; byte havePSK = 0; ssl->ctx = ctx; /* only for passing to calls, options could change */ @@ -925,6 +928,9 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) #ifdef HAVE_LIBZ ssl->didStreamInit = 0; #endif +#ifndef NO_RSA + haveRSA = 1; +#endif ssl->buffers.certificate.buffer = 0; ssl->buffers.key.buffer = 0; @@ -986,10 +992,11 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) #ifdef CYASSL_SHA384 InitSha384(&ssl->hashSha384); #endif +#ifndef NO_RSA ssl->peerRsaKey = NULL; - - ssl->verifyCallback = ctx->verifyCallback; ssl->peerRsaKeyPresent = 0; +#endif + ssl->verifyCallback = ctx->verifyCallback; ssl->options.side = ctx->method->side; ssl->options.downgrade = ctx->method->downgrade; ssl->error = 0; @@ -1159,6 +1166,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) *ssl->suites = ctx->suites; /* peer key */ +#ifndef NO_RSA ssl->peerRsaKey = (RsaKey*)XMALLOC(sizeof(RsaKey), ssl->heap, DYNAMIC_TYPE_RSA); if (ssl->peerRsaKey == NULL) { @@ -1166,7 +1174,7 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) return MEMORY_E; } InitRsaKey(ssl->peerRsaKey, ctx->heap); - +#endif /* make sure server has cert and key unless using PSK */ if (ssl->options.side == SERVER_END && !havePSK) if (!ssl->buffers.certificate.buffer || !ssl->buffers.key.buffer) { @@ -1176,11 +1184,12 @@ int InitSSL(CYASSL* ssl, CYASSL_CTX* ctx) /* make sure server has DH parms, and add PSK if there, add NTRU too */ if (ssl->options.side == SERVER_END) - InitSuites(ssl->suites, ssl->version,ssl->options.haveDH, havePSK, - ssl->options.haveNTRU, ssl->options.haveECDSAsig, - ssl->options.haveStaticECC, ssl->options.side); + InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, + ssl->options.haveDH, ssl->options.haveNTRU, + ssl->options.haveECDSAsig, ssl->options.haveStaticECC, + ssl->options.side); else - InitSuites(ssl->suites, ssl->version, TRUE, havePSK, + InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, TRUE, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); @@ -1222,10 +1231,12 @@ void SSL_ResourceFree(CYASSL* ssl) if (ssl->buffers.weOwnKey) XFREE(ssl->buffers.key.buffer, ssl->heap, DYNAMIC_TYPE_KEY); +#ifndef NO_RSA if (ssl->peerRsaKey) { FreeRsaKey(ssl->peerRsaKey); XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA); } +#endif if (ssl->buffers.inputBuffer.dynamicFlag) ShrinkInputBuffer(ssl, FORCED_FREE); if (ssl->buffers.outputBuffer.dynamicFlag) @@ -1290,12 +1301,14 @@ void FreeHandshakeResources(CYASSL* ssl) if (ssl->options.saveArrays) FreeArrays(ssl, 1); +#ifndef NO_RSA /* peerRsaKey */ if (ssl->peerRsaKey) { FreeRsaKey(ssl->peerRsaKey); XFREE(ssl->peerRsaKey, ssl->heap, DYNAMIC_TYPE_RSA); ssl->peerRsaKey = NULL; } +#endif } @@ -2293,37 +2306,49 @@ static int DoCertificate(CYASSL* ssl, byte* input, word32* inOutIdx) } /* decode peer key */ - if (dCert.keyOID == RSAk) { - word32 idx = 0; - if (RsaPublicKeyDecode(dCert.publicKey, &idx, - ssl->peerRsaKey, dCert.pubKeySize) != 0) { - ret = PEER_KEY_ERROR; - } - else - ssl->peerRsaKeyPresent = 1; + switch (dCert.keyOID) { + #ifndef NO_RSA + case RSAk: + { + word32 idx = 0; + if (RsaPublicKeyDecode(dCert.publicKey, &idx, + ssl->peerRsaKey, dCert.pubKeySize) != 0) { + ret = PEER_KEY_ERROR; + } + else + ssl->peerRsaKeyPresent = 1; + } + break; + #endif /* NO_RSA */ + #ifdef HAVE_NTRU + case NTRUk: + { + if (dCert.pubKeySize > sizeof(ssl->peerNtruKey)) { + ret = PEER_KEY_ERROR; + } + else { + XMEMCPY(ssl->peerNtruKey, dCert.publicKey, dCert.pubKeySize); + ssl->peerNtruKeyLen = (word16)dCert.pubKeySize; + ssl->peerNtruKeyPresent = 1; + } + } + break; + #endif /* HAVE_NTRU */ + #ifdef HAVE_ECC + case ECDSAk: + { + if (ecc_import_x963(dCert.publicKey, dCert.pubKeySize, + &ssl->peerEccDsaKey) != 0) { + ret = PEER_KEY_ERROR; + } + else + ssl->peerEccDsaKeyPresent = 1; + } + break; + #endif /* HAVE_ECC */ + default: + break; } -#ifdef HAVE_NTRU - else if (dCert.keyOID == NTRUk) { - if (dCert.pubKeySize > sizeof(ssl->peerNtruKey)) { - ret = PEER_KEY_ERROR; - } - else { - XMEMCPY(ssl->peerNtruKey, dCert.publicKey, dCert.pubKeySize); - ssl->peerNtruKeyLen = (word16)dCert.pubKeySize; - ssl->peerNtruKeyPresent = 1; - } - } -#endif /* HAVE_NTRU */ -#ifdef HAVE_ECC - else if (dCert.keyOID == ECDSAk) { - if (ecc_import_x963(dCert.publicKey, dCert.pubKeySize, - &ssl->peerEccDsaKey) != 0) { - ret = PEER_KEY_ERROR; - } - else - ssl->peerEccDsaKeyPresent = 1; - } -#endif /* HAVE_ECC */ FreeDecodedCert(&dCert); } @@ -2593,12 +2618,14 @@ static int DoHandShakeMsgType(CYASSL* ssl, byte* input, word32* inOutIdx, ret = DoClientKeyExchange(ssl, input, inOutIdx); break; +#if !defined(NO_RSA) || defined(HAVE_ECC) case certificate_verify: CYASSL_MSG("processing certificate verify"); ret = DoCertificateVerify(ssl, input, inOutIdx, totalSz); break; +#endif /* !NO_RSA || HAVE_ECC */ -#endif +#endif /* !NO_CYASSL_SERVER */ default: CYASSL_MSG("Unknown handshake message type"); @@ -2736,6 +2763,10 @@ static INLINE word32 GetSEQIncrement(CYASSL* ssl, int verify) static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) { + (void)out; + (void)input; + (void)sz; + if (ssl->encrypt.setup == 0) { CYASSL_MSG("Encrypt ciphers not setup"); return ENCRYPT_ERROR; @@ -2830,6 +2861,10 @@ static INLINE int Encrypt(CYASSL* ssl, byte* out, const byte* input, word32 sz) static INLINE int Decrypt(CYASSL* ssl, byte* plain, const byte* input, word32 sz) { + (void)plain; + (void)input; + (void)sz; + if (ssl->decrypt.setup == 0) { CYASSL_MSG("Decrypt ciphers not setup"); return DECRYPT_ERROR; @@ -5604,149 +5639,168 @@ int SetCipherList(Suites* s, const char* list) word32 idx = 0; int ret = 0; - if (ssl->specs.kea == rsa_kea) { - RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, - SECRET_LEN); - ssl->arrays->preMasterSecret[0] = ssl->chVersion.major; - ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor; - ssl->arrays->preMasterSz = SECRET_LEN; + switch (ssl->specs.kea) { + #ifndef NO_RSA + case rsa_kea: + RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, + SECRET_LEN); + ssl->arrays->preMasterSecret[0] = ssl->chVersion.major; + ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor; + ssl->arrays->preMasterSz = SECRET_LEN; - if (ssl->peerRsaKeyPresent == 0) - return NO_PEER_KEY; + if (ssl->peerRsaKeyPresent == 0) + return NO_PEER_KEY; - ret = RsaPublicEncrypt(ssl->arrays->preMasterSecret, SECRET_LEN, - encSecret, sizeof(encSecret), ssl->peerRsaKey, - ssl->rng); - if (ret > 0) { - encSz = ret; - ret = 0; /* set success to 0 */ - } + ret = RsaPublicEncrypt(ssl->arrays->preMasterSecret, SECRET_LEN, + encSecret, sizeof(encSecret), ssl->peerRsaKey, + ssl->rng); + if (ret > 0) { + encSz = ret; + ret = 0; /* set success to 0 */ + } + break; + #endif #ifdef OPENSSL_EXTRA - } else if (ssl->specs.kea == diffie_hellman_kea) { - buffer serverP = ssl->buffers.serverDH_P; - buffer serverG = ssl->buffers.serverDH_G; - buffer serverPub = ssl->buffers.serverDH_Pub; - byte priv[ENCRYPT_LEN]; - word32 privSz = 0; - DhKey key; + case diffie_hellman_kea: + { + buffer serverP = ssl->buffers.serverDH_P; + buffer serverG = ssl->buffers.serverDH_G; + buffer serverPub = ssl->buffers.serverDH_Pub; + byte priv[ENCRYPT_LEN]; + word32 privSz = 0; + DhKey key; - if (serverP.buffer == 0 || serverG.buffer == 0 || - serverPub.buffer == 0) - return NO_PEER_KEY; + if (serverP.buffer == 0 || serverG.buffer == 0 || + serverPub.buffer == 0) + return NO_PEER_KEY; - InitDhKey(&key); - ret = DhSetKey(&key, serverP.buffer, serverP.length, - serverG.buffer, serverG.length); - if (ret == 0) - /* for DH, encSecret is Yc, agree is pre-master */ - ret = DhGenerateKeyPair(&key, ssl->rng, priv, &privSz, - encSecret, &encSz); - if (ret == 0) - ret = DhAgree(&key, ssl->arrays->preMasterSecret, - &ssl->arrays->preMasterSz, priv, privSz, - serverPub.buffer, serverPub.length); - FreeDhKey(&key); + InitDhKey(&key); + ret = DhSetKey(&key, serverP.buffer, serverP.length, + serverG.buffer, serverG.length); + if (ret == 0) + /* for DH, encSecret is Yc, agree is pre-master */ + ret = DhGenerateKeyPair(&key, ssl->rng, priv, &privSz, + encSecret, &encSz); + if (ret == 0) + ret = DhAgree(&key, ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz, priv, privSz, + serverPub.buffer, serverPub.length); + FreeDhKey(&key); + } + break; #endif /* OPENSSL_EXTRA */ #ifndef NO_PSK - } else if (ssl->specs.kea == psk_kea) { - byte* pms = ssl->arrays->preMasterSecret; + case psk_kea: + { + byte* pms = ssl->arrays->preMasterSecret; - ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl, - ssl->arrays->server_hint, ssl->arrays->client_identity, - MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); - if (ssl->arrays->psk_keySz == 0 || - ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) - return PSK_KEY_ERROR; - encSz = (word32)XSTRLEN(ssl->arrays->client_identity); - if (encSz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR; - XMEMCPY(encSecret, ssl->arrays->client_identity, encSz); + ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl, + ssl->arrays->server_hint, ssl->arrays->client_identity, + MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); + if (ssl->arrays->psk_keySz == 0 || + ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) + return PSK_KEY_ERROR; + encSz = (word32)XSTRLEN(ssl->arrays->client_identity); + if (encSz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR; + XMEMCPY(encSecret, ssl->arrays->client_identity, encSz); - /* make psk pre master secret */ - /* length of key + length 0s + length of key + key */ - c16toa((word16)ssl->arrays->psk_keySz, pms); - pms += 2; - XMEMSET(pms, 0, ssl->arrays->psk_keySz); - pms += ssl->arrays->psk_keySz; - c16toa((word16)ssl->arrays->psk_keySz, pms); - pms += 2; - XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz); - ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4; + /* make psk pre master secret */ + /* length of key + length 0s + length of key + key */ + c16toa((word16)ssl->arrays->psk_keySz, pms); + pms += 2; + XMEMSET(pms, 0, ssl->arrays->psk_keySz); + pms += ssl->arrays->psk_keySz; + c16toa((word16)ssl->arrays->psk_keySz, pms); + pms += 2; + XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz); + ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4; + } + break; #endif /* NO_PSK */ #ifdef HAVE_NTRU - } else if (ssl->specs.kea == ntru_kea) { - word32 rc; - word16 cipherLen = sizeof(encSecret); - DRBG_HANDLE drbg; - static uint8_t const cyasslStr[] = { - 'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U' - }; + case ntru_kea: + { + word32 rc; + word16 cipherLen = sizeof(encSecret); + DRBG_HANDLE drbg; + static uint8_t const cyasslStr[] = { + 'C', 'y', 'a', 'S', 'S', 'L', ' ', 'N', 'T', 'R', 'U' + }; - RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, - SECRET_LEN); - ssl->arrays->preMasterSz = SECRET_LEN; + RNG_GenerateBlock(ssl->rng, ssl->arrays->preMasterSecret, + SECRET_LEN); + ssl->arrays->preMasterSz = SECRET_LEN; - if (ssl->peerNtruKeyPresent == 0) - return NO_PEER_KEY; + if (ssl->peerNtruKeyPresent == 0) + return NO_PEER_KEY; - rc = crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr, - sizeof(cyasslStr), GetEntropy, &drbg); - if (rc != DRBG_OK) - return NTRU_DRBG_ERROR; + rc = crypto_drbg_instantiate(MAX_NTRU_BITS, cyasslStr, + sizeof(cyasslStr), GetEntropy, + &drbg); + if (rc != DRBG_OK) + return NTRU_DRBG_ERROR; - rc = crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen,ssl->peerNtruKey, - ssl->arrays->preMasterSz, - ssl->arrays->preMasterSecret, - &cipherLen, encSecret); - crypto_drbg_uninstantiate(drbg); - if (rc != NTRU_OK) - return NTRU_ENCRYPT_ERROR; + rc = crypto_ntru_encrypt(drbg, ssl->peerNtruKeyLen, + ssl->peerNtruKey, + ssl->arrays->preMasterSz, + ssl->arrays->preMasterSecret, + &cipherLen, encSecret); + crypto_drbg_uninstantiate(drbg); + if (rc != NTRU_OK) + return NTRU_ENCRYPT_ERROR; - encSz = cipherLen; - ret = 0; + encSz = cipherLen; + ret = 0; + } + break; #endif /* HAVE_NTRU */ #ifdef HAVE_ECC - } else if (ssl->specs.kea == ecc_diffie_hellman_kea) { - ecc_key myKey; - ecc_key* peerKey = &myKey; - word32 size = sizeof(encSecret); + case ecc_diffie_hellman_kea: + { + ecc_key myKey; + ecc_key* peerKey = &myKey; + word32 size = sizeof(encSecret); - if (ssl->specs.static_ecdh) { - /* TODO: EccDsa is really fixed Ecc change naming */ - if (!ssl->peerEccDsaKeyPresent || !ssl->peerEccDsaKey.dp) - return NO_PEER_KEY; - peerKey = &ssl->peerEccDsaKey; - } - else { - if (!ssl->peerEccKeyPresent || !ssl->peerEccKey.dp) - return NO_PEER_KEY; - peerKey = &ssl->peerEccKey; - } + if (ssl->specs.static_ecdh) { + /* TODO: EccDsa is really fixed Ecc change naming */ + if (!ssl->peerEccDsaKeyPresent || !ssl->peerEccDsaKey.dp) + return NO_PEER_KEY; + peerKey = &ssl->peerEccDsaKey; + } + else { + if (!ssl->peerEccKeyPresent || !ssl->peerEccKey.dp) + return NO_PEER_KEY; + peerKey = &ssl->peerEccKey; + } - ecc_init(&myKey); - ret = ecc_make_key(ssl->rng, peerKey->dp->size, &myKey); - if (ret != 0) - return ECC_MAKEKEY_ERROR; + ecc_init(&myKey); + ret = ecc_make_key(ssl->rng, peerKey->dp->size, &myKey); + if (ret != 0) + return ECC_MAKEKEY_ERROR; - /* precede export with 1 byte length */ - ret = ecc_export_x963(&myKey, encSecret + 1, &size); - encSecret[0] = (byte)size; - encSz = size + 1; + /* precede export with 1 byte length */ + ret = ecc_export_x963(&myKey, encSecret + 1, &size); + encSecret[0] = (byte)size; + encSz = size + 1; - if (ret != 0) - ret = ECC_EXPORT_ERROR; - else { - size = sizeof(ssl->arrays->preMasterSecret); - ret = ecc_shared_secret(&myKey, peerKey, - ssl->arrays->preMasterSecret, &size); - if (ret != 0) - ret = ECC_SHARED_ERROR; - } + if (ret != 0) + ret = ECC_EXPORT_ERROR; + else { + size = sizeof(ssl->arrays->preMasterSecret); + ret = ecc_shared_secret(&myKey, peerKey, + ssl->arrays->preMasterSecret, &size); + if (ret != 0) + ret = ECC_SHARED_ERROR; + } - ssl->arrays->preMasterSz = size; - ecc_free(&myKey); + ssl->arrays->preMasterSz = size; + ecc_free(&myKey); + } + break; #endif /* HAVE_ECC */ - } else - return ALGO_ID_E; /* unsupported kea */ + default: + return ALGO_ID_E; /* unsupported kea */ + } if (ret == 0) { byte *output; @@ -5820,6 +5874,7 @@ int SetCipherList(Suites* s, const char* list) return ret; } +#ifndef NO_RSA int SendCertificateVerify(CYASSL* ssl) { byte *output; @@ -5959,7 +6014,7 @@ int SetCipherList(Suites* s, const char* list) else return ret; } - +#endif /* NO_RSA */ #endif /* NO_CYASSL_CLIENT */ @@ -6996,6 +7051,7 @@ int SetCipherList(Suites* s, const char* list) ssl->chVersion = pv; /* store */ if (ssl->version.minor > pv.minor) { + byte haveRSA = 0; byte havePSK = 0; if (!ssl->options.downgrade) { CYASSL_MSG("Client trying to connect with lesser version"); @@ -7018,13 +7074,17 @@ int SetCipherList(Suites* s, const char* list) CYASSL_MSG(" downgrading to TLSv1.1"); ssl->version.minor = TLSv1_1_MINOR; } +#ifndef NO_RSA + haveRSA = 1; +#endif #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, - ssl->options.haveNTRU, ssl->options.haveECDSAsig, - ssl->options.haveStaticECC, ssl->options.side); + InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, + ssl->options.haveDH, ssl->options.haveNTRU, + ssl->options.haveECDSAsig, ssl->options.haveStaticECC, + ssl->options.side); } /* suite size */ @@ -7128,6 +7188,7 @@ int SetCipherList(Suites* s, const char* list) ssl->chVersion = pv; /* store */ i += (word32)sizeof(pv); if (ssl->version.minor > pv.minor) { + byte haveRSA = 0; byte havePSK = 0; if (!ssl->options.downgrade) { CYASSL_MSG("Client trying to connect with lesser version"); @@ -7150,12 +7211,16 @@ int SetCipherList(Suites* s, const char* list) CYASSL_MSG(" downgrading to TLSv1.1"); ssl->version.minor = TLSv1_1_MINOR; } +#ifndef NO_RSA + haveRSA = 1; +#endif #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, - ssl->options.haveNTRU, ssl->options.haveECDSAsig, - ssl->options.haveStaticECC, ssl->options.side); + InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, + ssl->options.haveDH, ssl->options.haveNTRU, + ssl->options.haveECDSAsig, ssl->options.haveStaticECC, + ssl->options.side); } /* random */ XMEMCPY(ssl->arrays->clientRandom, input + i, RAN_LEN); @@ -7269,7 +7334,7 @@ int SetCipherList(Suites* s, const char* list) return MatchSuite(ssl, &clSuites); } - +#if !defined(NO_RSA) || defined(HAVE_ECC) static int DoCertificateVerify(CYASSL* ssl, byte* input, word32* inOutsz, word32 totalSz) { @@ -7304,6 +7369,7 @@ int SetCipherList(Suites* s, const char* list) *inOutsz = i + sz; /* RSA */ +#ifndef NO_RSA if (ssl->peerRsaKeyPresent != 0) { CYASSL_MSG("Doing RSA peer cert verify"); @@ -7333,8 +7399,9 @@ int SetCipherList(Suites* s, const char* list) ret = 0; /* verified */ } } +#endif #ifdef HAVE_ECC - else if (ssl->peerEccDsaKeyPresent) { + if (ssl->peerEccDsaKeyPresent) { int verify = 0; int err = -1; @@ -7349,7 +7416,7 @@ int SetCipherList(Suites* s, const char* list) #endif return ret; } - +#endif /* !NO_RSA || HAVE_ECC */ int SendServerHelloDone(CYASSL* ssl) { @@ -7442,6 +7509,11 @@ int SetCipherList(Suites* s, const char* list) word32 length = 0; byte* out; + (void)length; /* shut up compiler warnings */ + (void)out; + (void)input; + (void)inOutIdx; + if (ssl->options.clientState < CLIENT_HELLO_COMPLETE) { CYASSL_MSG("Client sending keyexchange at wrong time"); return OUT_OF_ORDER_E; @@ -7459,167 +7531,189 @@ int SetCipherList(Suites* s, const char* list) if (ssl->toInfoOn) AddLateName("ClientKeyExchange", &ssl->timeoutInfo); #endif - if (ssl->specs.kea == rsa_kea) { - word32 idx = 0; - RsaKey key; - byte* tmp = 0; - InitRsaKey(&key, ssl->heap); + switch (ssl->specs.kea) { + #ifndef NO_RSA + case rsa_kea: + { + word32 idx = 0; + RsaKey key; + byte* tmp = 0; - if (ssl->buffers.key.buffer) - ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, &key, - ssl->buffers.key.length); - else - return NO_PRIVATE_KEY; + InitRsaKey(&key, ssl->heap); - if (ret == 0) { - length = RsaEncryptSize(&key); - ssl->arrays->preMasterSz = SECRET_LEN; - - if (ssl->options.tls) - (*inOutIdx) += 2; - tmp = input + *inOutIdx; - *inOutIdx += length; - - if (RsaPrivateDecryptInline(tmp, length, &out, &key) == - SECRET_LEN) { - XMEMCPY(ssl->arrays->preMasterSecret, out, SECRET_LEN); - if (ssl->arrays->preMasterSecret[0] != ssl->chVersion.major - || - ssl->arrays->preMasterSecret[1] != ssl->chVersion.minor) - - ret = PMS_VERSION_ERROR; - else - ret = MakeMasterSecret(ssl); - } + if (ssl->buffers.key.buffer) + ret = RsaPrivateKeyDecode(ssl->buffers.key.buffer, &idx, + &key, ssl->buffers.key.length); else - ret = RSA_PRIVATE_ERROR; + return NO_PRIVATE_KEY; + + if (ret == 0) { + length = RsaEncryptSize(&key); + ssl->arrays->preMasterSz = SECRET_LEN; + + if (ssl->options.tls) + (*inOutIdx) += 2; + tmp = input + *inOutIdx; + *inOutIdx += length; + + if (RsaPrivateDecryptInline(tmp, length, &out, &key) == + SECRET_LEN) { + XMEMCPY(ssl->arrays->preMasterSecret, out, SECRET_LEN); + if (ssl->arrays->preMasterSecret[0] != + ssl->chVersion.major + || ssl->arrays->preMasterSecret[1] != + ssl->chVersion.minor) + ret = PMS_VERSION_ERROR; + else + ret = MakeMasterSecret(ssl); + } + else + ret = RSA_PRIVATE_ERROR; + } + + FreeRsaKey(&key); } + break; + #endif + #ifndef NO_PSK + case psk_kea: + { + byte* pms = ssl->arrays->preMasterSecret; + word16 ci_sz; - FreeRsaKey(&key); -#ifndef NO_PSK - } else if (ssl->specs.kea == psk_kea) { - byte* pms = ssl->arrays->preMasterSecret; - word16 ci_sz; + ato16(&input[*inOutIdx], &ci_sz); + *inOutIdx += LENGTH_SZ; + if (ci_sz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR; - ato16(&input[*inOutIdx], &ci_sz); - *inOutIdx += LENGTH_SZ; - if (ci_sz > MAX_PSK_ID_LEN) return CLIENT_ID_ERROR; + XMEMCPY(ssl->arrays->client_identity, &input[*inOutIdx], ci_sz); + *inOutIdx += ci_sz; + ssl->arrays->client_identity[ci_sz] = 0; - XMEMCPY(ssl->arrays->client_identity, &input[*inOutIdx], ci_sz); - *inOutIdx += ci_sz; - ssl->arrays->client_identity[ci_sz] = 0; + ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl, + ssl->arrays->client_identity, ssl->arrays->psk_key, + MAX_PSK_KEY_LEN); + if (ssl->arrays->psk_keySz == 0 || + ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) + return PSK_KEY_ERROR; + + /* make psk pre master secret */ + /* length of key + length 0s + length of key + key */ + c16toa((word16)ssl->arrays->psk_keySz, pms); + pms += 2; + XMEMSET(pms, 0, ssl->arrays->psk_keySz); + pms += ssl->arrays->psk_keySz; + c16toa((word16)ssl->arrays->psk_keySz, pms); + pms += 2; + XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz); + ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4; - ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl, - ssl->arrays->client_identity, ssl->arrays->psk_key, - MAX_PSK_KEY_LEN); - if (ssl->arrays->psk_keySz == 0 || - ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) return PSK_KEY_ERROR; - - /* make psk pre master secret */ - /* length of key + length 0s + length of key + key */ - c16toa((word16)ssl->arrays->psk_keySz, pms); - pms += 2; - XMEMSET(pms, 0, ssl->arrays->psk_keySz); - pms += ssl->arrays->psk_keySz; - c16toa((word16)ssl->arrays->psk_keySz, pms); - pms += 2; - XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz); - ssl->arrays->preMasterSz = ssl->arrays->psk_keySz * 2 + 4; - - ret = MakeMasterSecret(ssl); -#endif /* NO_PSK */ -#ifdef HAVE_NTRU - } else if (ssl->specs.kea == ntru_kea) { - word32 rc; - word16 cipherLen; - word16 plainLen = sizeof(ssl->arrays->preMasterSecret); - byte* tmp; - - if (!ssl->buffers.key.buffer) - return NO_PRIVATE_KEY; - - ato16(&input[*inOutIdx], &cipherLen); - *inOutIdx += LENGTH_SZ; - if (cipherLen > MAX_NTRU_ENCRYPT_SZ) - return NTRU_KEY_ERROR; - - tmp = input + *inOutIdx; - rc = crypto_ntru_decrypt((word16)ssl->buffers.key.length, - ssl->buffers.key.buffer, cipherLen, tmp, &plainLen, - ssl->arrays->preMasterSecret); - - if (rc != NTRU_OK || plainLen != SECRET_LEN) - return NTRU_DECRYPT_ERROR; - *inOutIdx += cipherLen; - - ssl->arrays->preMasterSz = plainLen; - ret = MakeMasterSecret(ssl); -#endif /* HAVE_NTRU */ -#ifdef HAVE_ECC - } else if (ssl->specs.kea == ecc_diffie_hellman_kea) { - word32 size; - word32 bLength = input[*inOutIdx]; /* one byte length */ - *inOutIdx += 1; - - ret = ecc_import_x963(&input[*inOutIdx], bLength, &ssl->peerEccKey); - if (ret != 0) - return ECC_PEERKEY_ERROR; - *inOutIdx += bLength; - ssl->peerEccKeyPresent = 1; - - size = sizeof(ssl->arrays->preMasterSecret); - if (ssl->specs.static_ecdh) { - ecc_key staticKey; - word32 i = 0; - - ecc_init(&staticKey); - ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i, - &staticKey, ssl->buffers.key.length); - if (ret == 0) - ret = ecc_shared_secret(&staticKey, &ssl->peerEccKey, - ssl->arrays->preMasterSecret, &size); - ecc_free(&staticKey); - } - else - ret = ecc_shared_secret(&ssl->eccTempKey, &ssl->peerEccKey, - ssl->arrays->preMasterSecret, &size); - if (ret != 0) - return ECC_SHARED_ERROR; - ssl->arrays->preMasterSz = size; - ret = MakeMasterSecret(ssl); -#endif /* HAVE_ECC */ -#ifdef OPENSSL_EXTRA - } else if (ssl->specs.kea == diffie_hellman_kea) { - byte* clientPub; - word16 clientPubSz; - DhKey dhKey; - - ato16(&input[*inOutIdx], &clientPubSz); - *inOutIdx += LENGTH_SZ; - - clientPub = &input[*inOutIdx]; - *inOutIdx += clientPubSz; - - InitDhKey(&dhKey); - ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer, - ssl->buffers.serverDH_P.length, - ssl->buffers.serverDH_G.buffer, - ssl->buffers.serverDH_G.length); - if (ret == 0) - ret = DhAgree(&dhKey, ssl->arrays->preMasterSecret, - &ssl->arrays->preMasterSz, - ssl->buffers.serverDH_Priv.buffer, - ssl->buffers.serverDH_Priv.length, - clientPub, clientPubSz); - FreeDhKey(&dhKey); - if (ret == 0) ret = MakeMasterSecret(ssl); -#endif /* OPENSSL_EXTRA */ - } - else { - CYASSL_MSG("Bad kea type"); - return BAD_KEA_TYPE_E; + } + break; + #endif /* NO_PSK */ + #ifdef HAVE_NTRU + case ntru_kea: + { + word32 rc; + word16 cipherLen; + word16 plainLen = sizeof(ssl->arrays->preMasterSecret); + byte* tmp; + + if (!ssl->buffers.key.buffer) + return NO_PRIVATE_KEY; + + ato16(&input[*inOutIdx], &cipherLen); + *inOutIdx += LENGTH_SZ; + if (cipherLen > MAX_NTRU_ENCRYPT_SZ) + return NTRU_KEY_ERROR; + + tmp = input + *inOutIdx; + rc = crypto_ntru_decrypt((word16)ssl->buffers.key.length, + ssl->buffers.key.buffer, cipherLen, tmp, &plainLen, + ssl->arrays->preMasterSecret); + + if (rc != NTRU_OK || plainLen != SECRET_LEN) + return NTRU_DECRYPT_ERROR; + *inOutIdx += cipherLen; + + ssl->arrays->preMasterSz = plainLen; + ret = MakeMasterSecret(ssl); + } + break; + #endif /* HAVE_NTRU */ + #ifdef HAVE_ECC + case ecc_diffie_hellman_kea: + { + word32 size; + word32 bLength = input[*inOutIdx]; /* one byte length */ + *inOutIdx += 1; + + ret = ecc_import_x963(&input[*inOutIdx], bLength, &ssl->peerEccKey); + if (ret != 0) + return ECC_PEERKEY_ERROR; + *inOutIdx += bLength; + ssl->peerEccKeyPresent = 1; + + size = sizeof(ssl->arrays->preMasterSecret); + if (ssl->specs.static_ecdh) { + ecc_key staticKey; + word32 i = 0; + + ecc_init(&staticKey); + ret = EccPrivateKeyDecode(ssl->buffers.key.buffer, &i, + &staticKey, ssl->buffers.key.length); + if (ret == 0) + ret = ecc_shared_secret(&staticKey, &ssl->peerEccKey, + ssl->arrays->preMasterSecret, &size); + ecc_free(&staticKey); + } + else + ret = ecc_shared_secret(&ssl->eccTempKey, &ssl->peerEccKey, + ssl->arrays->preMasterSecret, &size); + if (ret != 0) + return ECC_SHARED_ERROR; + ssl->arrays->preMasterSz = size; + ret = MakeMasterSecret(ssl); + } + break; + #endif /* HAVE_ECC */ + #ifdef OPENSSL_EXTRA + case diffie_hellman_kea: + { + byte* clientPub; + word16 clientPubSz; + DhKey dhKey; + + ato16(&input[*inOutIdx], &clientPubSz); + *inOutIdx += LENGTH_SZ; + + clientPub = &input[*inOutIdx]; + *inOutIdx += clientPubSz; + + InitDhKey(&dhKey); + ret = DhSetKey(&dhKey, ssl->buffers.serverDH_P.buffer, + ssl->buffers.serverDH_P.length, + ssl->buffers.serverDH_G.buffer, + ssl->buffers.serverDH_G.length); + if (ret == 0) + ret = DhAgree(&dhKey, ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz, + ssl->buffers.serverDH_Priv.buffer, + ssl->buffers.serverDH_Priv.length, + clientPub, clientPubSz); + FreeDhKey(&dhKey); + if (ret == 0) + ret = MakeMasterSecret(ssl); + } + break; + #endif /* OPENSSL_EXTRA */ + default: + { + CYASSL_MSG("Bad kea type"); + ret = BAD_KEA_TYPE_E; + } + break; } if (ret == 0) { diff --git a/src/keys.c b/src/keys.c index 50eb76020..f266b9ee6 100644 --- a/src/keys.c +++ b/src/keys.c @@ -1137,6 +1137,11 @@ static int SetKeys(Ciphers* enc, Ciphers* dec, Keys* keys, CipherSpecs* specs, keys->peer_sequence_number = 0; keys->encryptionOn = 0; (void)rng; + (void)side; + (void)heap; + (void)enc; + (void)dec; + (void)specs; return 0; } diff --git a/src/ssl.c b/src/ssl.c index f9efabd56..992ef8dcb 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -309,6 +309,7 @@ int CyaSSL_SetTmpDH(CYASSL* ssl, const unsigned char* p, int pSz, const unsigned char* g, int gSz) { byte havePSK = 0; + byte haveRSA = 1; CYASSL_ENTER("CyaSSL_SetTmpDH"); if (ssl == NULL || p == NULL || g == NULL) return BAD_FUNC_ARG; @@ -344,8 +345,11 @@ int CyaSSL_SetTmpDH(CYASSL* ssl, const unsigned char* p, int pSz, #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, - havePSK, ssl->options.haveNTRU, ssl->options.haveECDSAsig, + #ifdef NO_RSA + haveRSA = 0; + #endif + InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH, + ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); CYASSL_LEAVE("CyaSSL_SetTmpDH", 0); @@ -645,6 +649,7 @@ int CyaSSL_set_group_messages(CYASSL* ssl) int CyaSSL_SetVersion(CYASSL* ssl, int version) { + byte haveRSA = 1; byte havePSK = 0; CYASSL_ENTER("CyaSSL_SetVersion"); @@ -678,11 +683,14 @@ int CyaSSL_SetVersion(CYASSL* ssl, int version) return BAD_FUNC_ARG; } + #ifdef NO_RSA + haveRSA = 0; + #endif #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, + InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, ssl->options.haveDH, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); @@ -1256,6 +1264,7 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify) } if (type == PRIVATEKEY_TYPE && format != SSL_FILETYPE_RAW) { +#ifndef NO_RSA if (!eccKey) { /* make sure RSA key can be used */ RsaKey key; @@ -1274,6 +1283,7 @@ int AddCA(CYASSL_CERT_MANAGER* cm, buffer der, int type, int verify) } FreeRsaKey(&key); } +#endif #ifdef HAVE_ECC if (eccKey ) { /* make sure ECC key can be used */ @@ -2316,15 +2326,20 @@ int CyaSSL_set_cipher_list(CYASSL* ssl, const char* list) { CYASSL_ENTER("CyaSSL_set_cipher_list"); if (SetCipherList(ssl->suites, list)) { + byte haveRSA = 1; byte havePSK = 0; + #ifdef NO_RSA + haveRSA = 0; + #endif #ifndef NO_PSK havePSK = ssl->options.havePSK; #endif - InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, - ssl->options.haveNTRU, ssl->options.haveECDSAsig, - ssl->options.haveStaticECC, ssl->options.side); + InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, + ssl->options.haveDH, ssl->options.haveNTRU, + ssl->options.haveECDSAsig, ssl->options.haveStaticECC, + ssl->options.side); return SSL_SUCCESS; } @@ -2537,11 +2552,13 @@ int CyaSSL_dtls_got_timeout(CYASSL* ssl) CYASSL_MSG("connect state: FIRST_REPLY_SECOND"); case FIRST_REPLY_SECOND : - if (ssl->options.sendVerify) - if ( (ssl->error = SendCertificateVerify(ssl)) != 0) { - CYASSL_ERROR(ssl->error); - return SSL_FATAL_ERROR; - } + #ifndef NO_RSA + if (ssl->options.sendVerify) + if ( (ssl->error = SendCertificateVerify(ssl)) != 0) { + CYASSL_ERROR(ssl->error); + return SSL_FATAL_ERROR; + } + #endif ssl->options.connectState = FIRST_REPLY_THIRD; CYASSL_MSG("connect state: FIRST_REPLY_THIRD"); @@ -3387,11 +3404,17 @@ int CyaSSL_set_compression(CYASSL* ssl) void CyaSSL_set_psk_client_callback(CYASSL* ssl, psk_client_callback cb) { + byte haveRSA = 1; + CYASSL_ENTER("SSL_set_psk_client_callback"); ssl->options.havePSK = 1; ssl->options.client_psk_cb = cb; - InitSuites(ssl->suites, ssl->version,TRUE,TRUE, ssl->options.haveNTRU, + #ifdef NO_RSA + haveRSA = 0; + #endif + InitSuites(ssl->suites, ssl->version, haveRSA, TRUE, + ssl->options.haveDH, ssl->options.haveNTRU, ssl->options.haveECDSAsig, ssl->options.haveStaticECC, ssl->options.side); } @@ -3408,13 +3431,19 @@ int CyaSSL_set_compression(CYASSL* ssl) void CyaSSL_set_psk_server_callback(CYASSL* ssl, psk_server_callback cb) { + byte haveRSA = 1; + CYASSL_ENTER("SSL_set_psk_server_callback"); ssl->options.havePSK = 1; ssl->options.server_psk_cb = cb; - InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, TRUE, - ssl->options.haveNTRU, ssl->options.haveECDSAsig, - ssl->options.haveStaticECC, ssl->options.side); + #ifdef NO_RSA + haveRSA = 0; + #endif + InitSuites(ssl->suites, ssl->version, haveRSA, TRUE, + ssl->options.haveDH, ssl->options.haveNTRU, + ssl->options.haveECDSAsig, ssl->options.haveStaticECC, + ssl->options.side); } @@ -3641,17 +3670,23 @@ int CyaSSL_set_compression(CYASSL* ssl) void CyaSSL_set_accept_state(CYASSL* ssl) { + byte haveRSA = 1; byte havePSK = 0; CYASSL_ENTER("SSL_set_accept_state"); ssl->options.side = SERVER_END; /* reset suites in case user switched */ -#ifndef NO_PSK - havePSK = ssl->options.havePSK; -#endif - InitSuites(ssl->suites, ssl->version, ssl->options.haveDH, havePSK, - ssl->options.haveNTRU, ssl->options.haveECDSAsig, - ssl->options.haveStaticECC, ssl->options.side); + + #ifdef NO_RSA + haveRSA = 0; + #endif + #ifndef NO_PSK + havePSK = ssl->options.havePSK; + #endif + InitSuites(ssl->suites, ssl->version, haveRSA, havePSK, + ssl->options.haveDH, ssl->options.haveNTRU, + ssl->options.haveECDSAsig, ssl->options.haveStaticECC, + ssl->options.side); } diff --git a/tests/api.c b/tests/api.c index 097e67441..b930e6559 100644 --- a/tests/api.c +++ b/tests/api.c @@ -39,10 +39,12 @@ static int test_CyaSSL_CTX_new(CYASSL_METHOD *method); static int test_CyaSSL_CTX_use_certificate_file(void); static int test_CyaSSL_CTX_use_PrivateKey_file(void); static int test_CyaSSL_CTX_load_verify_locations(void); +#ifndef NO_RSA static int test_server_CyaSSL_new(void); static int test_client_CyaSSL_new(void); static int test_CyaSSL_read_write(void); -#endif +#endif /* NO_RSA */ +#endif /* NO_FILESYSTEM */ /* test function helpers */ static int test_method(CYASSL_METHOD *method, const char *name); @@ -59,9 +61,9 @@ static int test_lvl(CYASSL_CTX *ctx, const char* file, const char* path, THREAD_RETURN CYASSL_THREAD test_server_nofail(void*); void test_client_nofail(void*); +static const char* bogusFile = "/dev/null"; #endif -static const char* bogusFile = "/dev/null"; #define testingFmt " %s:" #define resultFmt " %s\n" static const char* passed = "passed"; @@ -81,10 +83,12 @@ int ApiTest(void) test_CyaSSL_CTX_use_certificate_file(); test_CyaSSL_CTX_use_PrivateKey_file(); test_CyaSSL_CTX_load_verify_locations(); +#ifndef NO_RSA test_server_CyaSSL_new(); test_client_CyaSSL_new(); test_CyaSSL_read_write(); -#endif +#endif /* NO_RSA */ +#endif /* NO_FILESYSTEM */ test_CyaSSL_Cleanup(); printf(" End API Tests\n"); @@ -245,6 +249,8 @@ int test_CyaSSL_CTX_use_certificate_file(void) failure */ /* Then set the parameters to legit values but set each item to bogus and call again. Finish with a successful success. */ + /* If the build is configured to not have RSA, loading the + certificate files will fail. */ test_ucf(NULL, NULL, 9999, SSL_FAILURE, "CyaSSL_CTX_use_certificate_file(NULL, NULL, 9999)"); @@ -254,8 +260,13 @@ int test_CyaSSL_CTX_use_certificate_file(void) "CyaSSL_CTX_use_certificate_file(ctx, bogusFile, SSL_FILETYPE_PEM)"); test_ucf(ctx, svrCert, 9999, SSL_FAILURE, "CyaSSL_CTX_use_certificate_file(ctx, svrCert, 9999)"); +#ifndef NO_RSA test_ucf(ctx, svrCert, SSL_FILETYPE_PEM, SSL_SUCCESS, "CyaSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)"); +#else + test_ucf(ctx, svrCert, SSL_FILETYPE_PEM, SSL_FAILURE, + "NO_RSA: CyaSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM)"); +#endif CyaSSL_CTX_free(ctx); return TEST_SUCCESS; @@ -366,13 +377,20 @@ int test_CyaSSL_CTX_load_verify_locations(void) /* Add a test for the certs directory path loading. */ /* There is a leak here. If you load a second cert, the first one is lost. */ +#ifndef NO_RSA test_lvl(ctx, caCert, 0, SSL_SUCCESS, "CyaSSL_CTX_load_verify_locations(ctx, caCert, 0)"); +#else + test_lvl(ctx, caCert, 0, SSL_FAILURE, + "NO_RSA: CyaSSL_CTX_load_verify_locations(ctx, caCert, 0)"); +#endif CyaSSL_CTX_free(ctx); return TEST_SUCCESS; } +#ifndef NO_RSA + int test_server_CyaSSL_new(void) { int result; @@ -564,6 +582,7 @@ static int test_CyaSSL_read_write(void) return test_result; }; +#endif THREAD_RETURN CYASSL_THREAD test_server_nofail(void* args) { diff --git a/tests/suites.c b/tests/suites.c index b997154a0..db466f6a3 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -103,7 +103,6 @@ static void test_harness(void* vargs) char* comment; const char* fname = "tests/test.conf"; - if (args->argc == 1) { printf("notice: using default file %s\n", fname); } @@ -227,6 +226,7 @@ int SuiteTest(void) args.argv = myArgv; strcpy(argv0[0], "SuiteTest"); +#if !defined(NO_RSA) /* default case */ args.argc = 1; printf("starting default cipher suite tests\n"); @@ -235,6 +235,7 @@ int SuiteTest(void) printf("error from script %d\n", args.return_code); exit(EXIT_FAILURE); } +#endif /* any extra cases will need another argument */ args.argc = 2; @@ -250,7 +251,7 @@ int SuiteTest(void) } #endif -#ifdef HAVE_NULL_CIPHER +#if !defined(NO_RSA) && defined(HAVE_NULL_CIPHER) /* add rsa null cipher suites */ strcpy(argv0[1], "tests/test-null.conf"); printf("starting null cipher suite tests\n"); @@ -283,7 +284,7 @@ int SuiteTest(void) } #endif -#ifndef NO_PSK +#if !defined(NO_PSK) && !defined(NO_AES) /* add psk extra suites */ strcpy(argv0[1], "tests/test-psk.conf"); printf("starting psk extra cipher suite tests\n"); @@ -292,15 +293,16 @@ int SuiteTest(void) printf("error from script %d\n", args.return_code); exit(EXIT_FAILURE); } - #ifdef HAVE_NULL_CIPHER - strcpy(argv0[1], "tests/test-psk-null.conf"); - printf("starting psk extra null cipher suite tests\n"); - test_harness(&args); - if (args.return_code != 0) { - printf("error from script %d\n", args.return_code); - exit(EXIT_FAILURE); - } - #endif +#endif + +#if !defined(NO_PSK) && defined(HAVE_NULL_CIPHER) + strcpy(argv0[1], "tests/test-psk-null.conf"); + printf("starting psk extra null cipher suite tests\n"); + test_harness(&args); + if (args.return_code != 0) { + printf("error from script %d\n", args.return_code); + exit(EXIT_FAILURE); + } #endif #ifdef HAVE_NTRU diff --git a/tests/unit.c b/tests/unit.c index 4397bfd9a..85efe5b95 100644 --- a/tests/unit.c +++ b/tests/unit.c @@ -17,7 +17,7 @@ int main(int argc, char** argv) (void)argc; (void)argv; - printf("staring unit tests...\n"); + printf("starting unit tests...\n"); if ( (ret = ApiTest()) != 0) { printf("api test failed with %d\n", ret);