diff --git a/.gitignore b/.gitignore index ac53ef3fc..b25accc55 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ cyassl.xcodeproj/ cyassl*rc* autoscan.log TAGS +.DS_Store support/libcyassl.pc cyassl/version.h cyassl/ctaocrypt/stamp-h1 diff --git a/configure.ac b/configure.ac index 4eed7ec52..80eccb290 100644 --- a/configure.ac +++ b/configure.ac @@ -186,7 +186,7 @@ AC_ARG_ENABLE(fortress, if test "$ENABLED_FORTRESS" = "yes" then - AM_CFLAGS="$AM_CFLAGS -DOPENSSL_EXTRA -DCYASSL_DES_ECB -DCYASSL_AES_DIRECT" + AM_CFLAGS="$AM_CFLAGS -DOPENSSL_EXTRA -DCYASSL_DES_ECB -DCYASSL_AES_DIRECT -DCYASSL_DER_LOAD" fi diff --git a/ctaocrypt/src/asn.c b/ctaocrypt/src/asn.c index 121dc4f9f..3ebfb9b69 100644 --- a/ctaocrypt/src/asn.c +++ b/ctaocrypt/src/asn.c @@ -903,6 +903,50 @@ int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz) } +#ifdef OPENSSL_EXTRA + +int DhParamsLoad(const byte* input, word32 inSz, byte* p, word32* pInOutSz, + byte* g, word32* gInOutSz) +{ + word32 i = 0; + byte b = input[i++]; + int length; + + if (GetSequence(input, &i, &length, inSz) < 0) + return ASN_PARSE_E; + + if (b != ASN_INTEGER) + return ASN_PARSE_E; + + if (GetLength(input, &i, &length, inSz) < 0) + return ASN_PARSE_E; + + if (length <= *pInOutSz) { + XMEMCPY(p, &input[i], length); + *pInOutSz = length; + } + else + return BUFFER_E; + + i += length; + + if (b != ASN_INTEGER) + return ASN_PARSE_E; + + if (GetLength(input, &i, &length, inSz) < 0) + return ASN_PARSE_E; + + if (length <= *gInOutSz) { + XMEMCPY(g, &input[i], length); + *gInOutSz = length; + } + else + return BUFFER_E; + + return 0; +} + +#endif /* OPENSSL_EXTRA */ #endif /* NO_DH */ diff --git a/cyassl/ctaocrypt/asn_public.h b/cyassl/ctaocrypt/asn_public.h index 840592e56..1fa9d0d57 100644 --- a/cyassl/ctaocrypt/asn_public.h +++ b/cyassl/ctaocrypt/asn_public.h @@ -38,6 +38,7 @@ enum CertType { CERT_TYPE = 0, PRIVATEKEY_TYPE, + DH_PARAM_TYPE, CA_TYPE }; diff --git a/cyassl/ctaocrypt/dh.h b/cyassl/ctaocrypt/dh.h index 9bd7c5c8a..94758d0ed 100644 --- a/cyassl/ctaocrypt/dh.h +++ b/cyassl/ctaocrypt/dh.h @@ -53,6 +53,8 @@ CYASSL_API int DhKeyDecode(const byte* input, word32* inOutIdx, DhKey* key, word32); CYASSL_API int DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, word32 gSz); +CYASSL_API int DhParamsLoad(const byte* input, word32 inSz, byte* p, + word32* pInOutSz, byte* g, word32* gInOutSz); #ifdef __cplusplus diff --git a/cyassl/openssl/ssl.h b/cyassl/openssl/ssl.h index 70de397b3..1d39fabe2 100644 --- a/cyassl/openssl/ssl.h +++ b/cyassl/openssl/ssl.h @@ -95,6 +95,11 @@ typedef CYASSL_X509_STORE_CTX X509_STORE_CTX; #define SSL_CTX_load_verify_locations CyaSSL_CTX_load_verify_locations #define SSL_CTX_use_certificate_chain_file CyaSSL_CTX_use_certificate_chain_file #define SSL_CTX_use_RSAPrivateKey_file CyaSSL_CTX_use_RSAPrivateKey_file + + #define SSL_use_certificate_file CyaSSL_use_certificate_file + #define SSL_use_PrivateKey_file CyaSSL_use_PrivateKey_file + #define SSL_use_certificate_chain_file CyaSSL_use_certificate_chain_file + #define SSL_use_RSAPrivateKey_file CyaSSL_use_RSAPrivateKey_file #endif #define SSL_CTX_new CyaSSL_CTX_new diff --git a/cyassl/ssl.h b/cyassl/ssl.h index c2c57de32..1127044c0 100644 --- a/cyassl/ssl.h +++ b/cyassl/ssl.h @@ -148,8 +148,13 @@ CYASSL_API int CyaSSL_CTX_use_certificate_chain_file(CYASSL_CTX *, const char *file); CYASSL_API int CyaSSL_CTX_use_RSAPrivateKey_file(CYASSL_CTX*, const char*, int); +CYASSL_API int CyaSSL_use_certificate_file(CYASSL*, const char*, int); +CYASSL_API int CyaSSL_use_PrivateKey_file(CYASSL*, const char*, int); +CYASSL_API int CyaSSL_use_certificate_chain_file(CYASSL*, const char *file); +CYASSL_API int CyaSSL_use_RSAPrivateKey_file(CYASSL*, const char*, int); + #ifdef CYASSL_DER_LOAD - CYASSL_API int CyaSSL_CTX_load_verify_locations(CYASSL_CTX*, + CYASSL_API int CyaSSL_CTX_der_load_verify_locations(CYASSL_CTX*, const char*, int); #endif @@ -670,6 +675,11 @@ CYASSL_API int CyaSSL_connect_cert(CYASSL* ssl); /* server CTX Diffie-Hellman parameters */ CYASSL_API int CyaSSL_SetTmpDH(CYASSL*, unsigned char* p, int pSz, unsigned char* g, int gSz); +CYASSL_API int CyaSSL_SetTmpDH_buffer(CYASSL*, unsigned char* b, long sz, + int format); +#ifndef NO_FILESYSTEM + CYASSL_API int CyaSSL_SetTmpDH_file(CYASSL*, const char* f, int format); +#endif /* keyblock size in bytes or -1 */ CYASSL_API int CyaSSL_get_keyblock_size(CYASSL*); diff --git a/src/ssl.c b/src/ssl.c index d652d1fb0..63be7f071 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -167,7 +167,10 @@ int CyaSSL_negotiate(CYASSL* ssl) } -/* server CTX Diffie-Hellman parameters */ + + + +/* server Diffie-Hellman parameters */ int CyaSSL_SetTmpDH(CYASSL* ssl, unsigned char* p, int pSz, unsigned char* g, int gSz) { @@ -407,7 +410,7 @@ Signer* GetCA(Signer* signers, byte* hash) } -/* owns der, cyassl_int now uses too */ +/* owns der, internal now uses too */ int AddCA(CYASSL_CTX* ctx, buffer der) { int ret; @@ -419,7 +422,11 @@ int AddCA(CYASSL_CTX* ctx, buffer der) ret = ParseCert(&cert, CA_TYPE, ctx->verifyPeer, 0); CYASSL_MSG(" Parsed new CA"); - if (ret == 0) { + if (ret == 0 && IsCA(ctx, cert.subjectHash)) { + CYASSL_MSG(" Already have this CA, not adding again"); + (void)ret; + } + else if (ret == 0) { /* take over signer parts */ signer = MakeSigner(ctx->heap); if (!signer) @@ -439,8 +446,11 @@ int AddCA(CYASSL_CTX* ctx, buffer der) ctx->caList = signer; /* takes ownership */ UnLockMutex(&ca_mutex); } - else + else { + CYASSL_MSG(" CA Mutex Lock failed"); + ret = -1; FreeSigners(signer, ctx->heap); + } } } @@ -523,6 +533,9 @@ int AddCA(CYASSL_CTX* ctx, buffer der) XSTRNCPY(footer, "-----END CERTIFICATE-----", sizeof(footer)); dynamicType = (type == CA_TYPE) ? DYNAMIC_TYPE_CA : DYNAMIC_TYPE_CERT; + } else if (type == DH_PARAM_TYPE) { + + } else { XSTRNCPY(header, "-----BEGIN RSA PRIVATE KEY-----", sizeof(header)); XSTRNCPY(footer, "-----END RSA PRIVATE KEY-----", sizeof(footer)); @@ -1111,7 +1124,7 @@ int CyaSSL_PemCertToDer(const char* fileName, unsigned char* derBuf, int derSz) int CyaSSL_CTX_use_certificate_file(CYASSL_CTX* ctx, const char* file, int format) { - CYASSL_ENTER("SSL_CTX_use_certificate_file"); + CYASSL_ENTER("CyaSSL_CTX_use_certificate_file"); if (ProcessFile(ctx, file, format, CERT_TYPE, NULL, 0) == SSL_SUCCESS) return SSL_SUCCESS; @@ -1121,7 +1134,7 @@ int CyaSSL_CTX_use_certificate_file(CYASSL_CTX* ctx, const char* file, int CyaSSL_CTX_use_PrivateKey_file(CYASSL_CTX* ctx, const char* file,int format) { - CYASSL_ENTER("SSL_CTX_use_PrivateKey_file"); + CYASSL_ENTER("CyaSSL_CTX_use_PrivateKey_file"); if (ProcessFile(ctx, file, format, PRIVATEKEY_TYPE, NULL, 0) == SSL_SUCCESS) return SSL_SUCCESS; @@ -1132,7 +1145,7 @@ int CyaSSL_CTX_use_PrivateKey_file(CYASSL_CTX* ctx, const char* file,int format) int CyaSSL_CTX_use_certificate_chain_file(CYASSL_CTX* ctx, const char* file) { /* procces up to MAX_CHAIN_DEPTH plus subject cert */ - CYASSL_ENTER("SSL_CTX_use_certificate_chain_file"); + CYASSL_ENTER("CyaSSL_CTX_use_certificate_chain_file"); if (ProcessFile(ctx, file, SSL_FILETYPE_PEM,CERT_TYPE,NULL,1) == SSL_SUCCESS) return SSL_SUCCESS; @@ -1140,6 +1153,122 @@ int CyaSSL_CTX_use_certificate_chain_file(CYASSL_CTX* ctx, const char* file) } +#ifdef OPENSSL_EXTRA +/* put SSL type in extra for now, not very common */ + +int CyaSSL_use_certificate_file(CYASSL* ssl, const char* file, int format) +{ + CYASSL_ENTER("CyaSSL_use_certificate_file"); + if (ProcessFile(ssl->ctx, file, format, CERT_TYPE, ssl, 0) == SSL_SUCCESS) + return SSL_SUCCESS; + + return SSL_FAILURE; +} + + +int CyaSSL_use_PrivateKey_file(CYASSL* ssl, const char* file, int format) +{ + CYASSL_ENTER("CyaSSL_use_PrivateKey_file"); + if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0) + == SSL_SUCCESS) + return SSL_SUCCESS; + + return SSL_FAILURE; +} + + +int CyaSSL_use_certificate_chain_file(CYASSL* ssl, const char* file) +{ + /* procces up to MAX_CHAIN_DEPTH plus subject cert */ + CYASSL_ENTER("CyaSSL_use_certificate_chain_file"); + if (ProcessFile(ssl->ctx, file, SSL_FILETYPE_PEM, CERT_TYPE, ssl, 1) + == SSL_SUCCESS) + return SSL_SUCCESS; + + return SSL_FAILURE; +} + + +/* server Diffie-Hellman parameters */ +int CyaSSL_SetTmpDH_buffer(CYASSL* ssl, unsigned char* buf, long sz, int format) +{ + buffer der; + int ret; + int weOwnDer = 0; + byte p[1024]; + byte g[1024]; + int pSz = sizeof(p); + int gSz = sizeof(g); + + der.buffer = buf; + der.length = sz; + + if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM) + return SSL_BAD_FILETYPE; + + if (format == SSL_FILETYPE_PEM) { + ret = PemToDer(buf, sz, DH_PARAM_TYPE, &der, NULL, NULL, NULL); + if (ret < 0) { + XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY); + return ret; + } + weOwnDer = 1; + } + + if (DhParamsLoad(der.buffer, der.length, p, &pSz, g, &gSz) < 0) + ret = SSL_BAD_FILETYPE; + else + ret = CyaSSL_SetTmpDH(ssl, p, pSz, g, gSz); + + if (weOwnDer) + XFREE(der.buffer, ctx->heap, DYNAMIC_TYPE_KEY); + + return ret; +} + + +#if !defined(NO_FILESYSTEM) + +/* server Diffie-Hellman parameters */ +int CyaSSL_SetTmpDH_file(CYASSL* ssl, const char* fname, int format) +{ + byte staticBuffer[FILE_BUFFER_SIZE]; + byte* myBuffer = staticBuffer; + int dynamic = 0; + int ret; + long sz = 0; + XFILE* file = XFOPEN(fname, "rb"); + + if (!file) return SSL_BAD_FILE; + XFSEEK(file, 0, XSEEK_END); + sz = XFTELL(file); + XREWIND(file); + + if (sz > (long)sizeof(staticBuffer)) { + CYASSL_MSG("Getting dynamic buffer"); + myBuffer = (byte*) XMALLOC(sz, ctx->heap, DYNAMIC_TYPE_FILE); + if (myBuffer == NULL) { + XFCLOSE(file); + return SSL_BAD_FILE; + } + dynamic = 1; + } + + if ( (ret = XFREAD(myBuffer, sz, 1, file)) < 0) + ret = SSL_BAD_FILE; + else + ret = CyaSSL_SetTmpDH_buffer(ssl, myBuffer, sz, format); + + XFCLOSE(file); + if (dynamic) XFREE(myBuffer, ctx->heap, DYNAMIC_TYPE_FILE); + + return ret; + +} + +#endif /* !NO_FILESYSTEM */ +#endif /* OPENSSL_EXTRA */ + #ifdef HAVE_NTRU int CyaSSL_CTX_use_NTRUPrivateKey_file(CYASSL_CTX* ctx, const char* file) @@ -1170,6 +1299,16 @@ int CyaSSL_CTX_use_NTRUPrivateKey_file(CYASSL_CTX* ctx, const char* file) return SSL_FAILURE; } + int CyaSSL_use_RSAPrivateKey_file(CYASSL* ssl, const char* file, int format) + { + CYASSL_ENTER("CyaSSL_use_RSAPrivateKey_file"); + if (ProcessFile(ssl->ctx, file, format, PRIVATEKEY_TYPE, ssl, 0) + == SSL_SUCCESS) + return SSL_SUCCESS; + + return SSL_FAILURE; + } + #endif /* OPENSSL_EXTRA */ #endif /* NO_FILESYSTEM */