diff --git a/src/include.am b/src/include.am index f0f7ac89a..cdb6ff59b 100644 --- a/src/include.am +++ b/src/include.am @@ -64,21 +64,8 @@ src_libwolfssl_la_SOURCES += \ wolfcrypt/src/random.c \ wolfcrypt/src/sha256.c \ wolfcrypt/src/hash.c \ - wolfcrypt/src/bio.c \ - wolfcrypt/src/bio_m_mem.c \ - wolfcrypt/src/bio_m_file.c \ - wolfcrypt/src/bio_m_fd.c \ - wolfcrypt/src/bio_m_sock.c \ - wolfcrypt/src/bio_m_conn.c \ - wolfcrypt/src/bio_m_accept.c \ - wolfcrypt/src/bio_m_dgram.c \ - wolfcrypt/src/bio_m_null.c \ - wolfcrypt/src/bio_f_sock.c \ - wolfcrypt/src/bio_f_buff.c \ - wolfcrypt/src/bio_f_cipher.c \ - wolfcrypt/src/bio_f_b64.c \ - wolfcrypt/src/bio_f_dgst.c \ - wolfcrypt/src/bio_f_ssl.c + wolfcrypt/src/compat-wolfssl.c \ + wolfcrypt/src/bio.c if !BUILD_USER_RSA if BUILD_RSA diff --git a/src/internal.c b/src/internal.c index f2c9288ac..cb8b39bd2 100644 --- a/src/internal.c +++ b/src/internal.c @@ -32,6 +32,8 @@ #include #include #include +#include +#include #ifdef NO_INLINE #include #else @@ -2695,8 +2697,8 @@ void SSL_ResourceFree(WOLFSSL* ssl) #endif /* WOLFSSL_DTLS */ #if defined(OPENSSL_EXTRA) || defined(GOAHEAD_WS) if (ssl->biord != ssl->biowr) /* only free write if different */ - WOLFCRYPT_BIO_free(ssl->biowr); - WOLFCRYPT_BIO_free(ssl->biord); /* always free read bio */ + wc_BioFree(ssl->biowr); + wc_BioFree(ssl->biord); /* always free read bio */ #endif #ifdef HAVE_LIBZ FreeStreams(ssl); diff --git a/src/ssl.c b/src/ssl.c index 839290b51..e11c44ad3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -85,6 +85,7 @@ #ifdef WOLFSSL_SHA512 #include #endif + #include #endif #ifndef NO_FILESYSTEM @@ -270,7 +271,7 @@ WOLFSSL* wolfSSL_dup(WOLFSSL* s) /* setup biord, and biowr */ if (s->biord != NULL) { - if (!WOLFCRYPT_BIO_dup_state(s->biord, &ret->biord)) { + if (!wc_BioDupState(s->biord, &ret->biord)) { wolfSSL_free(ret); return NULL; } @@ -278,7 +279,7 @@ WOLFSSL* wolfSSL_dup(WOLFSSL* s) if (s->biowr != NULL) { if (s->biowr != s->biord) { - if (!WOLFCRYPT_BIO_dup_state(s->biowr, &ret->biowr)) { + if (!wc_BioDupState(s->biowr, &ret->biowr)) { wolfSSL_free(ret); return NULL; } @@ -1833,27 +1834,6 @@ int wolfSSL_CertPemToDer(const unsigned char* pem, int pemSz, #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) -static const char *EVP_AES_128_CBC = "AES-128-CBC"; -static const char *EVP_AES_192_CBC = "AES-192-CBC"; -static const char *EVP_AES_256_CBC = "AES-256-CBC"; -#if defined(OPENSSL_EXTRA) - static const char *EVP_AES_128_CTR = "AES-128-CTR"; - static const char *EVP_AES_192_CTR = "AES-192-CTR"; - static const char *EVP_AES_256_CTR = "AES-256-CTR"; -#endif -static const int EVP_AES_SIZE = 11; - -static const char *EVP_DES_CBC = "DES-CBC"; -static const int EVP_DES_SIZE = 7; - -static const char *EVP_DES_EDE3_CBC = "DES-EDE3-CBC"; -static const int EVP_DES_EDE3_SIZE = 12; - -#ifdef HAVE_IDEA -static const char *EVP_IDEA_CBC = "IDEA-CBC"; -static const int EVP_IDEA_SIZE = 8; -#endif - /* our KeyPemToDer password callback, password in userData */ static INLINE int OurPasswordCb(char* passwd, int sz, int rw, void* userdata) { @@ -2510,8 +2490,8 @@ static int wolfssl_decrypt_buffer_key(buffer* der, byte* password, } #endif /* WOLFSSL_SMALL_STACK */ - if ((ret = wolfSSL_EVP_BytesToKey(info->name, "MD5", info->iv, - password, passwordSz, 1, key, NULL)) <= 0) { + if ((ret = wc_EVP_BytesToKey(info->name, "MD5", info->iv, + password, passwordSz, 1, key, NULL)) <= 0) { WOLFSSL_MSG("bytes to key failure"); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -2585,8 +2565,8 @@ static int wolfssl_encrypt_buffer_key(byte* der, word32 derSz, byte* password, } #endif /* WOLFSSL_SMALL_STACK */ - if ((ret = wolfSSL_EVP_BytesToKey(info->name, "MD5", info->iv, - password, passwordSz, 1, key, NULL)) <= 0) { + if ((ret = wc_EVP_BytesToKey(info->name, "MD5", info->iv, + password, passwordSz, 1, key, NULL)) <= 0) { WOLFSSL_MSG("bytes to key failure"); #ifdef WOLFSSL_SMALL_STACK XFREE(key, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -7884,113 +7864,6 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return 0; } -#ifndef NO_MD5 - - int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER* type, - const WOLFSSL_EVP_MD* md, const byte* salt, - const byte* data, int sz, int count, byte* key, byte* iv) - { - int keyLen = 0; - int ivLen = 0; - int j; - int keyLeft; - int ivLeft; - int keyOutput = 0; - byte digest[MD5_DIGEST_SIZE]; - #ifdef WOLFSSL_SMALL_STACK - Md5* md5 = NULL; - #else - Md5 md5[1]; - #endif - - #ifdef WOLFSSL_SMALL_STACK - md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (md5 == NULL) - return 0; - #endif - - WOLFSSL_ENTER("wolfSSL_EVP_BytesToKey"); - wc_InitMd5(md5); - - /* only support MD5 for now */ - if (XSTRNCMP(md, "MD5", 3) != 0) return 0; - - /* only support CBC DES and AES for now */ - if (XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0) { - keyLen = DES_KEY_SIZE; - ivLen = DES_IV_SIZE; - } - else if (XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0) { - keyLen = DES3_KEY_SIZE; - ivLen = DES_IV_SIZE; - } - else if (XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0) { - keyLen = AES_128_KEY_SIZE; - ivLen = AES_IV_SIZE; - } - else if (XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0) { - keyLen = AES_192_KEY_SIZE; - ivLen = AES_IV_SIZE; - } - else if (XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0) { - keyLen = AES_256_KEY_SIZE; - ivLen = AES_IV_SIZE; - } - else { - #ifdef WOLFSSL_SMALL_STACK - XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - return 0; - } - - keyLeft = keyLen; - ivLeft = ivLen; - - while (keyOutput < (keyLen + ivLen)) { - int digestLeft = MD5_DIGEST_SIZE; - /* D_(i - 1) */ - if (keyOutput) /* first time D_0 is empty */ - wc_Md5Update(md5, digest, MD5_DIGEST_SIZE); - /* data */ - wc_Md5Update(md5, data, sz); - /* salt */ - if (salt) - wc_Md5Update(md5, salt, EVP_SALT_SIZE); - wc_Md5Final(md5, digest); - /* count */ - for (j = 1; j < count; j++) { - wc_Md5Update(md5, digest, MD5_DIGEST_SIZE); - wc_Md5Final(md5, digest); - } - - if (keyLeft) { - int store = min(keyLeft, MD5_DIGEST_SIZE); - XMEMCPY(&key[keyLen - keyLeft], digest, store); - - keyOutput += store; - keyLeft -= store; - digestLeft -= store; - } - - if (ivLeft && digestLeft) { - int store = min(ivLeft, digestLeft); - if (iv != NULL) - XMEMCPY(&iv[ivLen - ivLeft], - &digest[MD5_DIGEST_SIZE - digestLeft], store); - keyOutput += store; - ivLeft -= store; - } - } - - #ifdef WOLFSSL_SMALL_STACK - XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - - return keyOutput == (keyLen + ivLen) ? keyOutput : 0; - } - -#endif /* NO_MD5 */ - #endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */ @@ -8009,1045 +7882,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl) return version; } - -#ifndef NO_MD5 - void wolfSSL_MD5_Init(WOLFSSL_MD5_CTX* md5) - { - typedef char md5_test[sizeof(MD5_CTX) >= sizeof(Md5) ? 1 : -1]; - (void)sizeof(md5_test); - - WOLFSSL_ENTER("MD5_Init"); - wc_InitMd5((Md5*)md5); - } - - - void wolfSSL_MD5_Update(WOLFSSL_MD5_CTX* md5, const void* input, - unsigned long sz) - { - WOLFSSL_ENTER("wolfSSL_MD5_Update"); - wc_Md5Update((Md5*)md5, (const byte*)input, (word32)sz); - } - - - void wolfSSL_MD5_Final(byte* input, WOLFSSL_MD5_CTX* md5) - { - WOLFSSL_ENTER("MD5_Final"); - wc_Md5Final((Md5*)md5, input); - } -#endif /* NO_MD5 */ - - -#ifndef NO_SHA - void wolfSSL_SHA_Init(WOLFSSL_SHA_CTX* sha) - { - typedef char sha_test[sizeof(SHA_CTX) >= sizeof(Sha) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA_Init"); - wc_InitSha((Sha*)sha); /* OpenSSL compat, no ret */ - } - - - void wolfSSL_SHA_Update(WOLFSSL_SHA_CTX* sha, const void* input, - unsigned long sz) - { - WOLFSSL_ENTER("SHA_Update"); - wc_ShaUpdate((Sha*)sha, (const byte*)input, (word32)sz); - } - - - void wolfSSL_SHA_Final(byte* input, WOLFSSL_SHA_CTX* sha) - { - WOLFSSL_ENTER("SHA_Final"); - wc_ShaFinal((Sha*)sha, input); - } - - - void wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX* sha) - { - WOLFSSL_ENTER("SHA1_Init"); - SHA_Init(sha); - } - - - void wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX* sha, const void* input, - unsigned long sz) - { - WOLFSSL_ENTER("SHA1_Update"); - SHA_Update(sha, input, sz); - } - - - void wolfSSL_SHA1_Final(byte* input, WOLFSSL_SHA_CTX* sha) - { - WOLFSSL_ENTER("SHA1_Final"); - SHA_Final(input, sha); - } -#endif /* NO_SHA */ - - - void wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX* sha256) - { - typedef char sha_test[sizeof(SHA256_CTX) >= sizeof(Sha256) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA256_Init"); - wc_InitSha256((Sha256*)sha256); /* OpenSSL compat, no error */ - } - - - void wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX* sha, const void* input, - unsigned long sz) - { - WOLFSSL_ENTER("SHA256_Update"); - wc_Sha256Update((Sha256*)sha, (const byte*)input, (word32)sz); - /* OpenSSL compat, no error */ - } - - - void wolfSSL_SHA256_Final(byte* input, WOLFSSL_SHA256_CTX* sha) - { - WOLFSSL_ENTER("SHA256_Final"); - wc_Sha256Final((Sha256*)sha, input); - /* OpenSSL compat, no error */ - } - - - #ifdef WOLFSSL_SHA384 - - void wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX* sha) - { - typedef char sha_test[sizeof(SHA384_CTX) >= sizeof(Sha384) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA384_Init"); - wc_InitSha384((Sha384*)sha); /* OpenSSL compat, no error */ - } - - - void wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX* sha, const void* input, - unsigned long sz) - { - WOLFSSL_ENTER("SHA384_Update"); - wc_Sha384Update((Sha384*)sha, (const byte*)input, (word32)sz); - /* OpenSSL compat, no error */ - } - - - void wolfSSL_SHA384_Final(byte* input, WOLFSSL_SHA384_CTX* sha) - { - WOLFSSL_ENTER("SHA384_Final"); - wc_Sha384Final((Sha384*)sha, input); - /* OpenSSL compat, no error */ - } - - #endif /* WOLFSSL_SHA384 */ - - - #ifdef WOLFSSL_SHA512 - - void wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX* sha) - { - typedef char sha_test[sizeof(SHA512_CTX) >= sizeof(Sha512) ? 1 : -1]; - (void)sizeof(sha_test); - - WOLFSSL_ENTER("SHA512_Init"); - wc_InitSha512((Sha512*)sha); /* OpenSSL compat, no error */ - } - - - void wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX* sha, const void* input, - unsigned long sz) - { - WOLFSSL_ENTER("SHA512_Update"); - wc_Sha512Update((Sha512*)sha, (const byte*)input, (word32)sz); - /* OpenSSL compat, no error */ - } - - - void wolfSSL_SHA512_Final(byte* input, WOLFSSL_SHA512_CTX* sha) - { - WOLFSSL_ENTER("SHA512_Final"); - wc_Sha512Final((Sha512*)sha, input); - /* OpenSSL compat, no error */ - } - - #endif /* WOLFSSL_SHA512 */ - - - #ifndef NO_MD5 - - const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void) - { - static const char* type = "MD5"; - WOLFSSL_ENTER("EVP_md5"); - return type; - } - - #endif /* NO_MD5 */ - - -#ifndef NO_SHA - const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void) - { - static const char* type = "SHA"; - WOLFSSL_ENTER("EVP_sha1"); - return type; - } -#endif /* NO_SHA */ - - - const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void) - { - static const char* type = "SHA256"; - WOLFSSL_ENTER("EVP_sha256"); - return type; - } - - #ifdef WOLFSSL_SHA384 - - const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void) - { - static const char* type = "SHA384"; - WOLFSSL_ENTER("EVP_sha384"); - return type; - } - - #endif /* WOLFSSL_SHA384 */ - - #ifdef WOLFSSL_SHA512 - - const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void) - { - static const char* type = "SHA512"; - WOLFSSL_ENTER("EVP_sha512"); - return type; - } - - #endif /* WOLFSSL_SHA512 */ - - - void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx) - { - WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_init"); - if (ctx == NULL) { - WOLFSSL_MSG("Bad function argument"); - return; - } - - ctx->macSize = 0; - ctx->macType = 0xff; - } - - /* return SSL_SUCCESS on ok, 0 on failure to match API compatibility */ - int wolfSSL_EVP_MD_CTX_copy(WOLFSSL_EVP_MD_CTX *out, - const WOLFSSL_EVP_MD_CTX *in) - { - WOLFSSL_ENTER("EVP_MD_CTX_copy"); - - if (in == NULL || out == NULL) { - WOLFSSL_MSG("Bad function argument"); - return 0; - } - - wolfSSL_EVP_MD_CTX_init(out); - XMEMCPY(out, in, sizeof(WOLFSSL_EVP_MD_CTX)); - - return SSL_SUCCESS; - } - - const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void) - { - WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cbc"); - return EVP_AES_128_CBC; - } - - - const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void) - { - WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cbc"); - return EVP_AES_192_CBC; - } - - - const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void) - { - WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cbc"); - return EVP_AES_256_CBC; - } - - - const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void) - { - WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ctr"); - return EVP_AES_128_CTR; - } - - - const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void) - { - WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ctr"); - return EVP_AES_192_CTR; - } - - - const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void) - { - WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ctr"); - return EVP_AES_256_CTR; - } - - - const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void) - { - WOLFSSL_ENTER("wolfSSL_EVP_des_cbc"); - return EVP_DES_CBC; - } - - - const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void) - { - WOLFSSL_ENTER("wolfSSL_EVP_des_ede3_cbc"); - return EVP_DES_EDE3_CBC; - } - - - const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void) - { - static const char* type = "ARC4"; - WOLFSSL_ENTER("wolfSSL_EVP_rc4"); - return type; - } - -#ifdef HAVE_IDEA - const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_idea_cbc(void) - { - WOLFSSL_ENTER("wolfSSL_EVP_idea_cbc"); - return EVP_IDEA_CBC; - } -#endif - const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void) - { - static const char* type = "NULL"; - WOLFSSL_ENTER("wolfSSL_EVP_enc_null"); - return type; - } - - - int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx) - { - WOLFSSL_ENTER("EVP_MD_CTX_cleanup"); - (void)ctx; - return 0; - } - - - - void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx) - { - WOLFSSL_ENTER("EVP_CIPHER_CTX_init"); - if (ctx) { - ctx->cipherType = 0xff; /* no init */ - ctx->keyLen = 0; - ctx->enc = 1; /* start in encrypt mode */ - - ctx->ivUpdate = 0; - ctx->final_used = 0; - ctx->bufLen = 0; - ctx->blockSize = 0; - ctx->padding = 0; - - XMEMSET(ctx->iv, 0, sizeof(ctx->iv)); - XMEMSET(ctx->buf, 0, sizeof(ctx->buf)); - XMEMSET(ctx->final, 0, sizeof(ctx->final)); - } - } - - - /* SSL_SUCCESS on ok */ - int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx) - { - WOLFSSL_ENTER("EVP_CIPHER_CTX_cleanup"); - - /* reset to initial values */ - wolfSSL_EVP_CIPHER_CTX_init(ctx); - - return SSL_SUCCESS; - } - - /* return SSL_SUCCESS on ok, 0 on failure to match API compatibility */ - int wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx, - const WOLFSSL_EVP_CIPHER* type, byte* key, - byte* iv, int enc) - { - int ret = -1; /* failure local, during function 0 means success - because internal functions work that way */ - (void)iv; - (void)enc; - - WOLFSSL_ENTER("wolfSSL_EVP_CipherInit"); - if (ctx == NULL) { - WOLFSSL_MSG("no ctx"); - return 0; /* failure */ - } - - if (type == NULL && ctx->cipherType == 0xff) { - WOLFSSL_MSG("no type set"); - return 0; /* failure */ - } - -#ifndef NO_AES - if (ctx->cipherType == AES_128_CBC_TYPE || - (type && XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)) { - WOLFSSL_MSG(EVP_AES_128_CBC); - ctx->cipherType = AES_128_CBC_TYPE; - ctx->padding = 1; - ctx->ivUpdate = 1; - ctx->blockSize = AES_BLOCK_SIZE; - ctx->bufLen = 0; - ctx->final_used = 0; - ctx->keyLen = 16; - if (enc == 0 || enc == 1) - ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, - ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); - if (ret != 0) - return ret; - } - if (iv && key == NULL) { - ret = wc_AesSetIV(&ctx->cipher.aes, iv); - if (ret != 0) - return ret; - } - } - else if (ctx->cipherType == AES_192_CBC_TYPE || - (type && XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)) { - WOLFSSL_MSG(EVP_AES_192_CBC); - ctx->cipherType = AES_192_CBC_TYPE; - ctx->padding = 1; - ctx->ivUpdate = 1; - ctx->blockSize = AES_BLOCK_SIZE; - ctx->bufLen = 0; - ctx->final_used = 0; - ctx->keyLen = 24; - if (enc == 0 || enc == 1) - ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, - ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); - if (ret != 0) - return ret; - } - if (iv && key == NULL) { - ret = wc_AesSetIV(&ctx->cipher.aes, iv); - if (ret != 0) - return ret; - } - } - else if (ctx->cipherType == AES_256_CBC_TYPE || - (type && XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)) { - WOLFSSL_MSG(EVP_AES_256_CBC); - ctx->cipherType = AES_256_CBC_TYPE; - ctx->padding = 1; - ctx->ivUpdate = 1; - ctx->blockSize = AES_BLOCK_SIZE; - ctx->bufLen = 0; - ctx->final_used = 0; - ctx->keyLen = 32; - if (enc == 0 || enc == 1) - ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, - ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); - if (ret != 0) - return ret; - } - if (iv && key == NULL) { - ret = wc_AesSetIV(&ctx->cipher.aes, iv); - if (ret != 0) - return ret; - } - } -#ifdef WOLFSSL_AES_COUNTER - else if (ctx->cipherType == AES_128_CTR_TYPE || - (type && XSTRNCMP(type, EVP_AES_128_CTR, EVP_AES_SIZE) == 0)) { - WOLFSSL_MSG(EVP_AES_128_CTR); - ctx->cipherType = AES_128_CTR_TYPE; - ctx->padding = 0; - ctx->ivUpdate = 0; - ctx->blockSize = AES_BLOCK_SIZE; - ctx->bufLen = 0; - ctx->final_used = 0; - ctx->keyLen = 16; - if (enc == 0 || enc == 1) - ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, - AES_ENCRYPTION); - if (ret != 0) - return ret; - } - if (iv && key == NULL) { - ret = wc_AesSetIV(&ctx->cipher.aes, iv); - if (ret != 0) - return ret; - } - } - else if (ctx->cipherType == AES_192_CTR_TYPE || - (type && XSTRNCMP(type, EVP_AES_192_CTR, EVP_AES_SIZE) == 0)) { - WOLFSSL_MSG(EVP_AES_192_CTR); - ctx->cipherType = AES_192_CTR_TYPE; - ctx->padding = 0; - ctx->ivUpdate = 0; - ctx->blockSize = AES_BLOCK_SIZE; - ctx->bufLen = 0; - ctx->final_used = 0; - ctx->keyLen = 24; - if (enc == 0 || enc == 1) - ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, - AES_ENCRYPTION); - if (ret != 0) - return ret; - } - if (iv && key == NULL) { - ret = wc_AesSetIV(&ctx->cipher.aes, iv); - if (ret != 0) - return ret; - } - } - else if (ctx->cipherType == AES_256_CTR_TYPE || - (type && XSTRNCMP(type, EVP_AES_256_CTR, EVP_AES_SIZE) == 0)) { - WOLFSSL_MSG(EVP_AES_256_CTR); - ctx->cipherType = AES_256_CTR_TYPE; - ctx->padding = 0; - ctx->ivUpdate = 0; - ctx->blockSize = AES_BLOCK_SIZE; - ctx->bufLen = 0; - ctx->final_used = 0; - ctx->keyLen = 32; - if (enc == 0 || enc == 1) - ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, - AES_ENCRYPTION); - if (ret != 0) - return ret; - } - if (iv && key == NULL) { - ret = wc_AesSetIV(&ctx->cipher.aes, iv); - if (ret != 0) - return ret; - } - } -#endif /* WOLFSSL_AES_CTR */ -#endif /* NO_AES */ - -#ifndef NO_DES3 - if (ctx->cipherType == DES_CBC_TYPE || - (type && XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0)) { - WOLFSSL_MSG(EVP_DES_CBC); - ctx->cipherType = DES_CBC_TYPE; - ctx->padding = 1; - ctx->ivUpdate = 1; - ctx->blockSize = DES_BLOCK_SIZE; - ctx->bufLen = 0; - ctx->final_used = 0; - ctx->keyLen = 8; - if (enc == 0 || enc == 1) - ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_Des_SetKey(&ctx->cipher.des, key, iv, - ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION); - if (ret != 0) - return ret; - } - - if (iv && key == NULL) - wc_Des_SetIV(&ctx->cipher.des, iv); - } - else if (ctx->cipherType == DES_EDE3_CBC_TYPE || - (type && - XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)) { - WOLFSSL_MSG(EVP_DES_EDE3_CBC); - ctx->cipherType = DES_EDE3_CBC_TYPE; - ctx->padding = 1; - ctx->ivUpdate = 1; - ctx->blockSize = DES_BLOCK_SIZE; - ctx->bufLen = 0; - ctx->final_used = 0; - ctx->keyLen = 24; - if (enc == 0 || enc == 1) - ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_Des3_SetKey(&ctx->cipher.des3, key, iv, - ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION); - if (ret != 0) - return ret; - } - - if (iv && key == NULL) { - ret = wc_Des3_SetIV(&ctx->cipher.des3, iv); - if (ret != 0) - return ret; - } - } -#endif /* NO_DES3 */ -#ifndef NO_RC4 - if (ctx->cipherType == ARC4_TYPE || (type && - XSTRNCMP(type, "ARC4", 4) == 0)) { - WOLFSSL_MSG("ARC4"); - ctx->cipherType = ARC4_TYPE; - ctx->blockSize = 1; - ctx->bufLen = 0; - ctx->final_used = 0; - ctx->padding = 0; - ctx->ivUpdate = 0; - if (ctx->keyLen == 0) /* user may have already set */ - ctx->keyLen = 16; /* default to 128 */ - if (key) - wc_Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen); - ret = 0; /* success */ - } -#endif /* NO_RC4 */ -#ifdef HAVE_IDEA - if (ctx->cipherType == IDEA_CBC_TYPE || - (type && XSTRNCMP(type, EVP_IDEA_CBC, EVP_IDEA_SIZE) == 0)) { - WOLFSSL_MSG(EVP_IDEA_CBC); - ctx->cipherType = IDEA_CBC_TYPE; - ctx->padding = 1; - ctx->ivUpdate = 1; - ctx->blockSize = IDEA_BLOCK_SIZE; - ctx->bufLen = 0; - ctx->final_used = 0; - ctx->keyLen = IDEA_KEY_SIZE; - if (enc == 0 || enc == 1) - ctx->enc = enc ? 1 : 0; - if (key) { - ret = wc_IdeaSetKey(&ctx->cipher.idea, key, (word16)ctx->keyLen, - iv, ctx->enc ? IDEA_ENCRYPTION : - IDEA_DECRYPTION); - if (ret != 0) - return ret; - } - - if (iv && key == NULL) - wc_IdeaSetIV(&ctx->cipher.idea, iv); - } -#endif /* HAVE_IDEA */ - if (ctx->cipherType == NULL_CIPHER_TYPE || (type && - XSTRNCMP(type, "NULL", 4) == 0)) { - WOLFSSL_MSG("NULL cipher"); - ctx->cipherType = NULL_CIPHER_TYPE; - ctx->keyLen = 0; - ctx->blockSize = 1; - ctx->bufLen = 0; - ctx->final_used = 0; - ctx->padding = 0; - ctx->ivUpdate = 0; - ret = 0; /* success */ - } - - if (ret == 0) - return SSL_SUCCESS; - else - return 0; /* overall failure */ - } - - - /* return SSL_SUCCESS on ok, 0 on failure to match API compatibility */ - int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, - byte *dst, int *dstLen, - const byte *src, int len) - { - int ret = 0, notEncLen = 0, fixLen = 0; - WOLFSSL_ENTER("wolfSSL_EVP_CipherUpdate"); - - *dstLen = 0; - - if (len <= 0) - return (len == 0); - - /* Push pending data for the decryption case */ - if (!ctx->enc && ctx->final_used) { - XMEMCPY(dst, ctx->final, ctx->blockSize); - dst += ctx->blockSize; - fixLen = 1; - } - - /* No pending data, src len is a multiple of blocksize */ - if (!ctx->bufLen && !(len & (ctx->blockSize-1))) { - ret = wolfSSL_EVP_Cipher(ctx, &dst[*dstLen], (byte*)src, len); - if (ret != SSL_SUCCESS) { - *dstLen = 0; - WOLFSSL_MSG("wolfSSL_EVP_Cipher failure"); - return 0; - } - else { - *dstLen = len; - - /* save new iv if required */ - if (ctx->ivUpdate) { - if (ctx->enc) - XMEMCPY(ctx->iv, &dst[*dstLen-ctx->blockSize], - ctx->blockSize); - else - XMEMCPY(ctx->iv, &src[len-ctx->blockSize], - ctx->blockSize); - ctx->ivUpdate = 2; - } - - /* extra operation for decrypt case */ - if (!ctx->enc) - goto decrypt; - else - return SSL_SUCCESS; - } - } - - /* Pending data */ - if (ctx->bufLen) { - /* pending data + src data less than a block - * keep data and return */ - if (ctx->bufLen + len < ctx->blockSize) { - XMEMCPY(&ctx->buf[ctx->bufLen], src, len); - ctx->bufLen += len; - *dstLen = 0; - return SSL_SUCCESS; - } - else { - /* complete pending buffer and encrypt/decrypt it */ - XMEMCPY(&ctx->buf[ctx->bufLen], src, - ctx->blockSize - ctx->bufLen); - ret = wolfSSL_EVP_Cipher(ctx, &dst[*dstLen], - ctx->buf, ctx->blockSize); - if (ret != SSL_SUCCESS) { - *dstLen = 0; - WOLFSSL_MSG("wolfSSL_EVP_Cipher failure"); - return 0; - } - - /* save new iv if required */ - if (ctx->ivUpdate) { - if (ctx->enc) - XMEMCPY(ctx->iv, dst, ctx->blockSize); - else - XMEMCPY(ctx->iv, ctx->buf, ctx->blockSize); - ctx->ivUpdate = 2; - } - - len -= (ctx->blockSize - ctx->bufLen); - src += (ctx->blockSize - ctx->bufLen); - *dstLen = ctx->blockSize; - } - } - /* src len not a multiple of block size */ - else - *dstLen = 0; - - /* encrypt/decrypt max blocks as possible */ - notEncLen = len & (ctx->blockSize - 1); - len -= notEncLen; - if (len > 0) { - ret = wolfSSL_EVP_Cipher(ctx, &dst[*dstLen], (byte*)src, len); - if (ret != SSL_SUCCESS) { - WOLFSSL_MSG("wolfSSL_EVP_Cipher failure"); - return 0; - } - *dstLen += len; - - /* save new iv if required */ - if (ctx->ivUpdate) { - if (ctx->enc) - XMEMCPY(ctx->iv, &dst[*dstLen-ctx->blockSize], - ctx->blockSize); - else - XMEMCPY(ctx->iv, &src[len-ctx->blockSize], ctx->blockSize); - ctx->ivUpdate = 2; - } - } - - /* save pending data */ - if (notEncLen) - XMEMCPY(ctx->buf, src+len, notEncLen); - ctx->bufLen = notEncLen; - -decrypt: - /* extra operation for decrypt case */ - if (!ctx->enc) { - /* keep last block for final step when decrypting - * multiple of block size */ - if (ctx->blockSize > 1 && !ctx->bufLen) { - *dstLen -= ctx->blockSize; - ctx->final_used = 1; - XMEMCPY(ctx->final, &dst[*dstLen], ctx->blockSize); - } - else - ctx->final_used = 0; - - if (fixLen) - *dstLen += ctx->blockSize; - } - - return SSL_SUCCESS; - } - - /* return SSL_SUCCESS on ok, 0 on failure to match API compatibility */ - int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, - byte *dst, int *dstLen) - { - int ret; - - if (ctx->blockSize == 1) { - *dstLen = 0; - WOLFSSL_MSG("wolfSSL_EVP_CipherFinal: blocksize 1"); - return SSL_SUCCESS; - } - - if (ctx->enc) { - if (ctx->padding) { - /* add padding */ - XMEMSET(ctx->buf+ctx->bufLen, (byte)(ctx->blockSize-ctx->bufLen), - ctx->blockSize-ctx->bufLen); - - ret = wolfSSL_EVP_Cipher(ctx, dst, ctx->buf, ctx->blockSize); - if (ret != SSL_SUCCESS) { - WOLFSSL_MSG("wolfSSL_EVP_CipherFinal failure"); - return 0; - } - - *dstLen = ctx->blockSize; - } - else { - if (ctx->bufLen) { - ret = wolfSSL_EVP_Cipher(ctx, dst, ctx->buf, ctx->bufLen); - if (ret != SSL_SUCCESS) { - WOLFSSL_MSG("wolfSSL_EVP_CipherFinal failure"); - return 0; - } - - *dstLen = ctx->bufLen; - } - else { - WOLFSSL_MSG("wolfSSL_EVP_CipherFinal: Nothing to do"); - *dstLen = 0; - } - } - } - else { - int i, pad; - - /* decrypt pending data, case of stream cipher */ - if (ctx->bufLen && !ctx->final_used) { - ret = wolfSSL_EVP_Cipher(ctx, dst, ctx->buf, ctx->bufLen); - if (ret != SSL_SUCCESS) { - WOLFSSL_MSG("wolfSSL_EVP_CipherFinal failure"); - return 0; - } - - *dstLen = ctx->bufLen; - ctx->bufLen = 0; - - return SSL_SUCCESS; - } - else if (ctx->bufLen || !ctx->final_used) { - WOLFSSL_MSG("wolfSSL_EVP_CipherFinal: Wrong final block length"); - return 0; - } - - /* get padding */ - if (ctx->padding) { - pad = (int)ctx->final[ctx->blockSize-1]; - if (!pad || pad > (int)ctx->blockSize) { - WOLFSSL_MSG("wolfSSL_EVP_CipherFinal: Bad decrypt"); - return 0; - } - - /* check padding */ - for (i = 0; i < pad; i++) { - if (ctx->final[ctx->blockSize-1-i] != pad) { - WOLFSSL_MSG("wolfSSL_EVP_CipherFinal: Bad decrypt"); - return 0; - } - } - - /* return data without padding */ - *dstLen = ctx->blockSize-pad; - XMEMCPY(dst, ctx->final, *dstLen); - } - else { - /* return data */ - *dstLen = ctx->blockSize; - XMEMCPY(dst, ctx->final, *dstLen); - } - } - - return SSL_SUCCESS; - } - - /* return SSL_SUCCESS on ok, 0 on failure to match API compatibility */ - int wolfSSL_EVP_CIPHER_CTX_copy(WOLFSSL_EVP_CIPHER_CTX *out, - const WOLFSSL_EVP_CIPHER_CTX *in) - { - WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_copy"); - - if (in == NULL || out == NULL) { - WOLFSSL_MSG("Bad function argument"); - return 0; - } - - wolfSSL_EVP_CIPHER_CTX_cleanup(out); - XMEMCPY(out, in, sizeof(WOLFSSL_EVP_CIPHER_CTX)); - - return SSL_SUCCESS; - } - - /* SSL_SUCCESS on ok */ - int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx) - { - WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_key_length"); - if (ctx) - return ctx->keyLen; - - return 0; /* failure */ - } - - - /* SSL_SUCCESS on ok */ - int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx, - int keylen) - { - WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_key_length"); - if (ctx) - ctx->keyLen = keylen; - else - return 0; /* failure */ - - return SSL_SUCCESS; - } - - - /* SSL_SUCCESS on ok */ - int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* dst, byte* src, - word32 len) - { - int ret = 0; - WOLFSSL_ENTER("wolfSSL_EVP_Cipher"); - - if (ctx == NULL || dst == NULL || src == NULL) { - WOLFSSL_MSG("Bad function argument"); - return 0; /* failure */ - } - - if (ctx->cipherType == 0xff) { - WOLFSSL_MSG("no init"); - return 0; /* failure */ - } - - switch (ctx->cipherType) { - -#ifndef NO_AES - case AES_128_CBC_TYPE : - case AES_192_CBC_TYPE : - case AES_256_CBC_TYPE : - WOLFSSL_MSG("AES CBC"); - if (ctx->ivUpdate > 1) { - ret = wc_AesSetIV(&ctx->cipher.aes, ctx->iv); - if (ret != 0) { - WOLFSSL_MSG("wolfSSL_EVP_Cipher failure"); - return 0; /* failure */ - } - } - - if (ctx->enc) - ret = wc_AesCbcEncrypt(&ctx->cipher.aes, dst, src, len); - else - ret = wc_AesCbcDecrypt(&ctx->cipher.aes, dst, src, len); - break; - -#ifdef WOLFSSL_AES_COUNTER - case AES_128_CTR_TYPE : - case AES_192_CTR_TYPE : - case AES_256_CTR_TYPE : - WOLFSSL_MSG("AES CTR"); - wc_AesCtrEncrypt(&ctx->cipher.aes, dst, src, len); - break; -#endif -#endif /* NO_AES */ - -#ifndef NO_DES3 - case DES_CBC_TYPE : - if (ctx->ivUpdate > 1) - wc_Des_SetIV(&ctx->cipher.des, ctx->iv); - - if (ctx->enc) - wc_Des_CbcEncrypt(&ctx->cipher.des, dst, src, len); - else - wc_Des_CbcDecrypt(&ctx->cipher.des, dst, src, len); - break; - - case DES_EDE3_CBC_TYPE : - if (ctx->ivUpdate > 1) { - ret = wc_Des3_SetIV(&ctx->cipher.des3, ctx->iv); - if (ret != 0) { - WOLFSSL_MSG("wolfSSL_EVP_Cipher failure"); - return 0; /* failure */ - } - } - - if (ctx->enc) - ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len); - else - ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len); - break; -#endif - -#ifndef NO_RC4 - case ARC4_TYPE : - wc_Arc4Process(&ctx->cipher.arc4, dst, src, len); - break; -#endif - -#ifdef HAVE_IDEA - case IDEA_CBC_TYPE : - if (ctx->ivUpdate > 1) { - ret = wc_IdeaSetIV(&ctx->cipher.idea, ctx->iv); - if (ret != 0) { - WOLFSSL_MSG("wolfSSL_EVP_Cipher failure"); - return 0; /* failure */ - } - } - - if (ctx->enc) - wc_IdeaCbcEncrypt(&ctx->cipher.idea, dst, src, len); - else - wc_IdeaCbcDecrypt(&ctx->cipher.idea, dst, src, len); - break; -#endif - case NULL_CIPHER_TYPE : - XMEMCPY(dst, src, len); - break; - - default: { - WOLFSSL_MSG("bad type"); - return 0; /* failure */ - } - } - - if (ret != 0) { - WOLFSSL_MSG("wolfSSL_EVP_Cipher failure"); - return 0; /* failuer */ - } - - WOLFSSL_MSG("wolfSSL_EVP_Cipher success"); - return SSL_SUCCESS; /* success */ - } - - /* store for external read of iv, SSL_SUCCESS on success */ - int wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx) + int wolfSSL_StoreExternalIV(WOLFCRYPT_EVP_CIPHER_CTX* ctx) { WOLFSSL_ENTER("wolfSSL_StoreExternalIV"); @@ -9113,7 +7949,7 @@ decrypt: /* set internal IV from external, SSL_SUCCESS on success */ - int wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx) + int wolfSSL_SetInternalIV(WOLFCRYPT_EVP_CIPHER_CTX* ctx) { WOLFSSL_ENTER("wolfSSL_SetInternalIV"); @@ -9178,195 +8014,6 @@ decrypt: return SSL_SUCCESS; } - /* SSL_SUCCESS on ok */ - int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx, - const WOLFSSL_EVP_MD* type) - { - WOLFSSL_ENTER("EVP_DigestInit"); - if (XSTRNCMP(type, "SHA256", 6) == 0) { - ctx->macType = SHA256; - ctx->macSize = SHA256_DIGEST_SIZE; - wolfSSL_SHA256_Init((SHA256_CTX*)&ctx->hash); - } - #ifdef WOLFSSL_SHA384 - else if (XSTRNCMP(type, "SHA384", 6) == 0) { - ctx->macType = SHA384; - ctx->macSize = SHA384_DIGEST_SIZE; - wolfSSL_SHA384_Init((SHA384_CTX*)&ctx->hash); - } - #endif - #ifdef WOLFSSL_SHA512 - else if (XSTRNCMP(type, "SHA512", 6) == 0) { - ctx->macType = SHA512; - ctx->macSize = SHA512_DIGEST_SIZE; - wolfSSL_SHA512_Init((SHA512_CTX*)&ctx->hash); - } - #endif - #ifndef NO_MD5 - else if (XSTRNCMP(type, "MD5", 3) == 0) { - ctx->macType = MD5; - ctx->macSize = MD5_DIGEST_SIZE; - wolfSSL_MD5_Init((MD5_CTX*)&ctx->hash); - } - #endif - #ifndef NO_SHA - /* has to be last since would pick or 256, 384, or 512 too */ - else if (XSTRNCMP(type, "SHA", 3) == 0) { - ctx->macType = SHA; - ctx->macSize = SHA_DIGEST_SIZE; - wolfSSL_SHA_Init((SHA_CTX*)&ctx->hash); - } - #endif /* NO_SHA */ - else - return BAD_FUNC_ARG; - - return SSL_SUCCESS; - } - - - /* SSL_SUCCESS on ok */ - int wolfSSL_EVP_DigestUpdate(WOLFSSL_EVP_MD_CTX* ctx, const void* data, - unsigned long sz) - { - WOLFSSL_ENTER("EVP_DigestUpdate"); - - switch (ctx->macType) { -#ifndef NO_MD5 - case MD5: - wolfSSL_MD5_Update((MD5_CTX*)&ctx->hash, data, - (unsigned long)sz); - break; -#endif -#ifndef NO_SHA - case SHA: - wolfSSL_SHA_Update((SHA_CTX*)&ctx->hash, data, - (unsigned long)sz); - break; -#endif -#ifndef NO_SHA256 - case SHA256: - wolfSSL_SHA256_Update((SHA256_CTX*)&ctx->hash, data, - (unsigned long)sz); - break; -#endif -#ifdef WOLFSSL_SHA384 - case SHA384: - wolfSSL_SHA384_Update((SHA384_CTX*)&ctx->hash, data, - (unsigned long)sz); - break; -#endif -#ifdef WOLFSSL_SHA512 - case SHA512: - wolfSSL_SHA512_Update((SHA512_CTX*)&ctx->hash, data, - (unsigned long)sz); - break; -#endif - default: - return BAD_FUNC_ARG; - } - - return SSL_SUCCESS; - } - - - /* SSL_SUCCESS on ok */ - int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md, - unsigned int* s) - { - WOLFSSL_ENTER("EVP_DigestFinal"); - switch (ctx->macType) { -#ifndef NO_MD5 - case MD5: - wolfSSL_MD5_Final(md, (MD5_CTX*)&ctx->hash); - if (s) *s = MD5_DIGEST_SIZE; - break; -#endif -#ifndef NO_SHA - case SHA: - wolfSSL_SHA_Final(md, (SHA_CTX*)&ctx->hash); - if (s) *s = SHA_DIGEST_SIZE; - break; -#endif -#ifndef NO_SHA256 - case SHA256: - wolfSSL_SHA256_Final(md, (SHA256_CTX*)&ctx->hash); - if (s) *s = SHA256_DIGEST_SIZE; - break; -#endif -#ifdef WOLFSSL_SHA384 - case SHA384: - wolfSSL_SHA384_Final(md, (SHA384_CTX*)&ctx->hash); - if (s) *s = SHA384_DIGEST_SIZE; - break; -#endif -#ifdef WOLFSSL_SHA512 - case SHA512: - wolfSSL_SHA512_Final(md, (SHA512_CTX*)&ctx->hash); - if (s) *s = SHA512_DIGEST_SIZE; - break; -#endif - default: - return BAD_FUNC_ARG; - } - - return SSL_SUCCESS; - } - - - /* SSL_SUCCESS on ok */ - int wolfSSL_EVP_DigestFinal_ex(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md, - unsigned int* s) - { - WOLFSSL_ENTER("EVP_DigestFinal_ex"); - return EVP_DigestFinal(ctx, md, s); - } - - - unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, const void* key, - int key_len, const unsigned char* d, int n, - unsigned char* md, unsigned int* md_len) - { - int type; - unsigned char* ret = NULL; -#ifdef WOLFSSL_SMALL_STACK - Hmac* hmac = NULL; -#else - Hmac hmac[1]; -#endif - - WOLFSSL_ENTER("HMAC"); - if (!md) - return NULL; /* no static buffer support */ - - if (XSTRNCMP(evp_md, "MD5", 3) == 0) - type = MD5; - else if (XSTRNCMP(evp_md, "SHA", 3) == 0) - type = SHA; - else - return NULL; - - #ifdef WOLFSSL_SMALL_STACK - hmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (hmac == NULL) - return NULL; - #endif - - if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0) - if (wc_HmacUpdate(hmac, d, n) == 0) - if (wc_HmacFinal(hmac, md) == 0) { - if (md_len) - *md_len = (type == MD5) ? (int)MD5_DIGEST_SIZE - : (int)SHA_DIGEST_SIZE; - ret = md; - } - - #ifdef WOLFSSL_SMALL_STACK - XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER); - #endif - - return ret; - } - void wolfSSL_ERR_clear_error(void) { /* TODO: */ @@ -10802,8 +9449,6 @@ const char* wolfSSL_get_cipher(WOLFSSL* ssl) #ifdef OPENSSL_EXTRA - - char* wolfSSL_CIPHER_description(WOLFSSL_CIPHER* cipher, char* in, int len) { (void)cipher; @@ -11265,7 +9910,7 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509) } -int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime) +int wolfSSL_ASN1_TIME_print(WOLFCRYPT_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime) { (void)bio; (void)asnTime; @@ -11475,7 +10120,7 @@ void wolfSSL_DES_ecb_encrypt(WOLFSSL_DES_cblock* desa, #endif /* NO_DES3 */ -int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a) +int wolfSSL_ASN1_UTCTIME_print(WOLFCRYPT_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a) { (void)bio; (void)a; @@ -13820,121 +12465,6 @@ int wolfSSL_RSA_GenAdd(WOLFSSL_RSA* rsa) #endif /* NO_RSA */ -void wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, int keylen, - const EVP_MD* type) -{ - WOLFSSL_MSG("wolfSSL_HMAC_Init"); - - if (ctx == NULL) { - WOLFSSL_MSG("no ctx on init"); - return; - } - - if (type) { - WOLFSSL_MSG("init has type"); - - if (XSTRNCMP(type, "MD5", 3) == 0) { - WOLFSSL_MSG("md5 hmac"); - ctx->type = MD5; - } - else if (XSTRNCMP(type, "SHA256", 6) == 0) { - WOLFSSL_MSG("sha256 hmac"); - ctx->type = SHA256; - } - - /* has to be last since would pick or 256, 384, or 512 too */ - else if (XSTRNCMP(type, "SHA", 3) == 0) { - WOLFSSL_MSG("sha hmac"); - ctx->type = SHA; - } - else { - WOLFSSL_MSG("bad init type"); - } - } - - if (key && keylen) { - WOLFSSL_MSG("keying hmac"); - wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key, (word32)keylen); - /* OpenSSL compat, no error */ - } -} - - -void wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, const unsigned char* data, - int len) -{ - WOLFSSL_MSG("wolfSSL_HMAC_Update"); - - if (ctx && data) { - WOLFSSL_MSG("updating hmac"); - wc_HmacUpdate(&ctx->hmac, data, (word32)len); - /* OpenSSL compat, no error */ - } -} - - -void wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash, - unsigned int* len) -{ - WOLFSSL_MSG("wolfSSL_HMAC_Final"); - - if (ctx && hash) { - WOLFSSL_MSG("final hmac"); - wc_HmacFinal(&ctx->hmac, hash); - /* OpenSSL compat, no error */ - - if (len) { - WOLFSSL_MSG("setting output len"); - switch (ctx->type) { - case MD5: - *len = MD5_DIGEST_SIZE; - break; - - case SHA: - *len = SHA_DIGEST_SIZE; - break; - - case SHA256: - *len = SHA256_DIGEST_SIZE; - break; - - default: - WOLFSSL_MSG("bad hmac type"); - } - } - } -} - - -void wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx) -{ - (void)ctx; - - WOLFSSL_MSG("wolfSSL_HMAC_cleanup"); -} - - -const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int id) -{ - WOLFSSL_MSG("wolfSSL_get_digestbynid"); - - switch(id) { -#ifndef NO_MD5 - case NID_md5: - return wolfSSL_EVP_md5(); -#endif -#ifndef NO_SHA - case NID_sha1: - return wolfSSL_EVP_sha1(); -#endif - default: - WOLFSSL_MSG("Bad digest id value"); - } - - return NULL; -} - - WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY* key) { (void)key; @@ -13962,7 +12492,8 @@ WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key) } -void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx) + +void* wolfSSL_EVP_X_STATE(const WOLFCRYPT_EVP_CIPHER_CTX* ctx) { WOLFSSL_MSG("wolfSSL_EVP_X_STATE"); @@ -13982,7 +12513,7 @@ void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx) } -int wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx) +int wolfSSL_EVP_X_STATE_LEN(const WOLFCRYPT_EVP_CIPHER_CTX* ctx) { WOLFSSL_MSG("wolfSSL_EVP_X_STATE_LEN"); @@ -14004,8 +12535,8 @@ int wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx) #ifndef NO_DES3 -void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, - unsigned char* iv, int len) +void wolfSSL_3des_iv(WOLFCRYPT_EVP_CIPHER_CTX* ctx, int doset, + unsigned char* iv, int len) { (void)len; @@ -14027,8 +12558,8 @@ void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, #ifndef NO_AES -void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, - unsigned char* iv, int len) +void wolfSSL_aes_ctr_iv(WOLFCRYPT_EVP_CIPHER_CTX* ctx, int doset, + unsigned char* iv, int len) { (void)len; @@ -14047,101 +12578,6 @@ void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, #endif /* NO_AES */ - -const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void) -{ - WOLFSSL_MSG("wolfSSL_ripemd160"); - - return NULL; -} - - -int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* type) -{ - WOLFSSL_MSG("wolfSSL_EVP_MD_size"); - - if (type == NULL) { - WOLFSSL_MSG("No md type arg"); - return BAD_FUNC_ARG; - } - - if (XSTRNCMP(type, "SHA256", 6) == 0) { - return SHA256_DIGEST_SIZE; - } -#ifndef NO_MD5 - else if (XSTRNCMP(type, "MD5", 3) == 0) { - return MD5_DIGEST_SIZE; - } -#endif -#ifdef WOLFSSL_SHA384 - else if (XSTRNCMP(type, "SHA384", 6) == 0) { - return SHA384_DIGEST_SIZE; - } -#endif -#ifdef WOLFSSL_SHA512 - else if (XSTRNCMP(type, "SHA512", 6) == 0) { - return SHA512_DIGEST_SIZE; - } -#endif -#ifndef NO_SHA - /* has to be last since would pick or 256, 384, or 512 too */ - else if (XSTRNCMP(type, "SHA", 3) == 0) { - return SHA_DIGEST_SIZE; - } -#endif - - return BAD_FUNC_ARG; -} - - -int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx) -{ - WOLFSSL_MSG("wolfSSL_EVP_CIPHER_CTX_iv_length"); - - switch (ctx->cipherType) { - - case AES_128_CBC_TYPE : - case AES_192_CBC_TYPE : - case AES_256_CBC_TYPE : - WOLFSSL_MSG("AES CBC"); - return AES_BLOCK_SIZE; - -#ifdef WOLFSSL_AES_COUNTER - case AES_128_CTR_TYPE : - case AES_192_CTR_TYPE : - case AES_256_CTR_TYPE : - WOLFSSL_MSG("AES CTR"); - return AES_BLOCK_SIZE; -#endif - - case DES_CBC_TYPE : - WOLFSSL_MSG("DES CBC"); - return DES_BLOCK_SIZE; - - case DES_EDE3_CBC_TYPE : - WOLFSSL_MSG("DES EDE3 CBC"); - return DES_BLOCK_SIZE; -#ifdef HAVE_IDEA - case IDEA_CBC_TYPE : - WOLFSSL_MSG("IDEA CBC"); - return IDEA_BLOCK_SIZE; -#endif - case ARC4_TYPE : - WOLFSSL_MSG("ARC4"); - return 0; - - case NULL_CIPHER_TYPE : - WOLFSSL_MSG("NULL"); - return 0; - - default: { - WOLFSSL_MSG("bad type"); - } - } - return 0; -} - - void wolfSSL_OPENSSL_free(void* p) { WOLFSSL_MSG("wolfSSL_OPENSSL_free"); @@ -14401,7 +12837,7 @@ int wolfSSL_PEM_write_RSAPrivateKey(FILE *fp, WOLFSSL_RSA *rsa, } #endif /* NO_FILESYSTEM */ -int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, RSA* rsa, +int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFCRYPT_BIO* bio, RSA* rsa, const EVP_CIPHER* cipher, unsigned char* passwd, int len, pem_password_cb cb, void* arg) @@ -15619,7 +14055,7 @@ int wolfSSL_PEM_write_EC_PUBKEY(FILE *fp, WOLFSSL_EC_KEY *x) /* return code compliant with OpenSSL : * 1 if success, 0 if error */ -int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ecc, +int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFCRYPT_BIO* bio, WOLFSSL_EC_KEY* ecc, const EVP_CIPHER* cipher, unsigned char* passwd, int len, pem_password_cb cb, void* arg) @@ -15794,7 +14230,7 @@ int wolfSSL_PEM_write_ECPrivateKey(FILE *fp, WOLFSSL_EC_KEY *ecc, /* return code compliant with OpenSSL : * 1 if success, 0 if error */ -int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_DSA* dsa, +int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFCRYPT_BIO* bio, WOLFSSL_DSA* dsa, const EVP_CIPHER* cipher, unsigned char* passwd, int len, pem_password_cb cb, void* arg) @@ -15976,7 +14412,7 @@ int wolfSSL_PEM_write_DSA_PUBKEY(FILE *fp, WOLFSSL_DSA *x) #endif /* #ifndef NO_DSA */ -WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, +WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFCRYPT_BIO* bio, WOLFSSL_EVP_PKEY** key, pem_password_cb cb, void* arg) { (void)bio; @@ -16550,7 +14986,7 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) } - WOLFSSL_X509 *PEM_read_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u) { + WOLFSSL_X509 *PEM_read_bio_WOLFSSL_X509(WOLFCRYPT_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u) { (void)bp; (void)x; (void)cb; @@ -16748,7 +15184,7 @@ int wolf_OBJ_txt2nid(const char* s) { } -WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bp, WOLFSSL_DH **x, pem_password_cb *cb, void *u) +WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFCRYPT_BIO *bp, WOLFSSL_DH **x, pem_password_cb *cb, void *u) { (void) bp; (void) x; @@ -16761,7 +15197,7 @@ WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bp, WOLFSSL_DH **x, pem_p return NULL; } -int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x) { +int PEM_write_bio_WOLFSSL_X509(WOLFCRYPT_BIO *bp, WOLFSSL_X509 *x) { (void)bp; (void)x; WOLFSSL_ENTER("PEM_write_bio_WOLFSSL_X509"); @@ -16983,7 +15419,7 @@ int wolfSSL_sk_X509_num(const STACK_OF(WOLFSSL_X509) *s) } -int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* nm, +int wolfSSL_X509_NAME_print_ex(WOLFCRYPT_BIO* bio, WOLFSSL_X509_NAME* nm, int indent, unsigned long flags) { (void)bio; @@ -17611,4 +16047,683 @@ void* wolfSSL_get_jobject(WOLFSSL* ssl) #endif /* WOLFSSL_JNI */ +#ifdef OPENSSL_EXTRA + +typedef struct { + WOLFSSL *ssl; + /* re-negotiate every time the total number of bytes is this size */ + int num_renegotiates; + unsigned long renegotiate_count; + unsigned long byte_count; + unsigned long renegotiate_timeout; + unsigned long last_time; +} WOLFCRYPT_BIO_SSL; + +static int wc_BioSSL_write(WOLFCRYPT_BIO *bio, const char *data, int size); +static int wc_BioSSL_read(WOLFCRYPT_BIO *bio, char *data, int size); +static int wc_BioSSL_puts(WOLFCRYPT_BIO *bio, const char *str); +static long wc_BioSSL_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr); +static int wc_BioSSL_new(WOLFCRYPT_BIO *bio); +static int wc_BioSSL_free(WOLFCRYPT_BIO *bio); +static long wc_BioSSL_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, + WOLFCRYPT_BIO_info_cb *fp); + +static WOLFCRYPT_BIO_METHOD wc_BioSSL_method = { + BIO_TYPE_SSL, + "SSL", + wc_BioSSL_write, + wc_BioSSL_read, + wc_BioSSL_puts, + NULL, /* gets */ + wc_BioSSL_ctrl, + wc_BioSSL_new, + wc_BioSSL_free, + wc_BioSSL_callback_ctrl, +}; + +WOLFCRYPT_BIO_METHOD *wc_Bio_f_ssl(void) +{ + return (&wc_BioSSL_method); +} + +static int wc_BioSSL_new(WOLFCRYPT_BIO *bio) +{ + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + bio->ptr = (WOLFCRYPT_BIO_SSL *)XMALLOC(sizeof(WOLFCRYPT_BIO_SSL), + 0, DYNAMIC_TYPE_OPENSSL); + if (bio->ptr == NULL) { + WOLFSSL_ERROR(MEMORY_E); + return 0; + } + + XMEMSET(bio->ptr, 0, sizeof(WOLFCRYPT_BIO_SSL)); + + bio->init = 0; + bio->flags = 0; + return 1; +} + +static int wc_BioSSL_free(WOLFCRYPT_BIO *bio) +{ + WOLFSSL_ENTER("wc_BioSSL_free"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + if (bio->ptr != NULL) { + WOLFCRYPT_BIO_SSL *bssl = (WOLFCRYPT_BIO_SSL *)bio->ptr; + if (bssl->ssl != NULL) { + wolfSSL_shutdown(bssl->ssl); + + if (bio->shutdown && bio->init) { + WOLFSSL_MSG("Free BIO ssl"); + wolfSSL_free(bssl->ssl); + } + } + + XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); + bio->ptr = NULL; + } + + if (bio->shutdown) { + bio->init = 0; + bio->flags = 0; + } + + return 1; +} + +static int wc_BioSSL_read(WOLFCRYPT_BIO *bio, char *data, int size) +{ + int ret = 1; + WOLFCRYPT_BIO_SSL *bssl; + + if (bio == NULL || bio->ptr == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + if (data == NULL) + return 0; + + bssl = (WOLFCRYPT_BIO_SSL *)bio->ptr; + + wc_BioClearRetryFlags(bio); + + ret = wolfSSL_read(bssl->ssl, data, size); + + switch (wolfSSL_get_error(bssl->ssl, ret)) { + case SSL_ERROR_NONE: + if (ret <= 0) + break; + +#ifdef HAVE_SECURE_RENEGOTIATION + { + int r = 0; + + if (bssl->renegotiate_count > 0) { + bssl->byte_count += ret; + if (bssl->byte_count > bssl->renegotiate_count) { + bssl->byte_count = 0; + bssl->num_renegotiates++; + wolfSSL_Rehandshake(bssl->ssl); + r = 1; + } + } + + if ((bssl->renegotiate_timeout > 0) && !r) { + unsigned long tm; + tm = (unsigned long)time(NULL); + if (tm > bssl->last_time + bssl->renegotiate_timeout) { + bssl->last_time = tm; + bssl->num_renegotiates++; + wolfSSL_Rehandshake(bssl->ssl); + } + } + } +#endif + break; + + case SSL_ERROR_WANT_READ: + wc_BioSetRetryRead(bio); + break; + + case SSL_ERROR_WANT_WRITE: + wc_BioSetRetryWrite(bio); + break; + + case SSL_ERROR_WANT_X509_LOOKUP: + wc_BioSetRetrySpecial(bio); + bio->retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + + case SSL_ERROR_WANT_ACCEPT: + wc_BioSetRetrySpecial(bio); + bio->retry_reason = BIO_RR_ACCEPT; + break; + + case SSL_ERROR_WANT_CONNECT: + wc_BioSetRetrySpecial(bio); + bio->retry_reason = BIO_RR_CONNECT; + break; + + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + case SSL_ERROR_ZERO_RETURN: + break; + + default: + break; + } + + return ret; +} + +static int wc_BioSSL_write(WOLFCRYPT_BIO *bio, const char *data, int size) +{ + int ret; + WOLFCRYPT_BIO_SSL *bssl; + + if (bio == NULL || bio->ptr == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + if (data == NULL) + return 0; + + bssl = (WOLFCRYPT_BIO_SSL *)bio->ptr; + + wc_BioClearRetryFlags(bio); + + ret = wolfSSL_write(bssl->ssl, data, size); + + switch (wolfSSL_get_error(bssl->ssl, ret)) { + case SSL_ERROR_NONE: + if (ret <= 0) + break; + +#ifdef HAVE_SECURE_RENEGOTIATION + { + int r = 0; + + if (bssl->renegotiate_count > 0) { + bssl->byte_count += ret; + if (bssl->byte_count > bssl->renegotiate_count) { + bssl->byte_count = 0; + bssl->num_renegotiates++; + wolfSSL_Rehandshake(bssl->ssl); + r = 1; + } + } + + if ((bssl->renegotiate_timeout > 0) && !r) { + unsigned long tm; + + tm = (unsigned long)time(NULL); + if (tm > bssl->last_time + bssl->renegotiate_timeout) { + bssl->last_time = tm; + bssl->num_renegotiates++; + wolfSSL_Rehandshake(bssl->ssl); + } + } + } +#endif + break; + + case SSL_ERROR_WANT_WRITE: + wc_BioSetRetryWrite(bio); + break; + + case SSL_ERROR_WANT_READ: + wc_BioSetRetryRead(bio); + break; + + case SSL_ERROR_WANT_X509_LOOKUP: + wc_BioSetRetrySpecial(bio); + bio->retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + + case SSL_ERROR_WANT_CONNECT: + wc_BioSetRetrySpecial(bio); + bio->retry_reason = BIO_RR_CONNECT; + break; + + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + break; + + default: + break; + } + + return ret; +} + +static int wc_BioSSL_set_bio(WOLFSSL *ssl, WOLFCRYPT_BIO *rbio, + WOLFCRYPT_BIO *wbio) +{ + WOLFSSL_ENTER("wc_BioSSL_set_bio"); + + if (ssl == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + if (ssl->biord != NULL && ssl->biord != rbio) + wc_BioFreeAll(ssl->biord); + if (ssl->biowr != NULL && ssl->biowr != wbio && ssl->biord != ssl->biowr) + wc_BioFreeAll(ssl->biowr); + + ssl->biord = rbio; + wolfSSL_set_rfd(ssl, rbio->num); + + ssl->biowr = wbio; + wolfSSL_set_wfd(ssl, wbio->num); + + return 1; +} + +static long wc_BioSSL_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) +{ + WOLFCRYPT_BIO_SSL *bssl; + long ret = 1; + + WOLFSSL_ENTER("wc_BioSSL_ctrl"); + + if (bio == NULL || bio->ptr == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + bssl = (WOLFCRYPT_BIO_SSL *)bio->ptr; + + if ((bssl->ssl == NULL) && (cmd != BIO_C_SET_SSL)) { + WOLFSSL_MSG("Set SSL not possible, ssl pointer NULL\n"); + return 0; + } + + switch (cmd) { + case BIO_CTRL_RESET: + wolfSSL_shutdown(bssl->ssl); + ret = (long)wolfSSL_negotiate(bssl->ssl); + if (ret <= 0) + break; + wolfSSL_clear(bssl->ssl); + + if (bio->next_bio != NULL) + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + else if (bssl->ssl->biord != NULL) + ret = wc_BioCtrl(bssl->ssl->biord, cmd, num, ptr); + else + ret = 1; + break; + + case BIO_CTRL_INFO: + ret = 0; + break; + + case BIO_C_SSL_MODE: + if (num) /* client mode */ + wolfSSL_set_connect_state(bssl->ssl); + else + wolfSSL_set_accept_state(bssl->ssl); + break; + + case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT: + ret = bssl->renegotiate_timeout; + if (num < 60) + num = 5; + bssl->renegotiate_timeout = (unsigned long)num; + bssl->last_time = (unsigned long)time(NULL); + break; + + case BIO_C_SET_SSL_RENEGOTIATE_BYTES: + ret = bssl->renegotiate_count; + if (num >= 512) + bssl->renegotiate_count = (unsigned long)num; + break; + + case BIO_C_GET_SSL_NUM_RENEGOTIATES: + ret = bssl->num_renegotiates; + break; + + case BIO_C_SET_SSL: + if (bssl->ssl != NULL) { + wc_BioSSL_free(bio); + if (!wc_BioSSL_new(bio)) + return 0; + } + + bio->shutdown = (int)num; + bssl->ssl = (WOLFSSL *)ptr; + + if (bssl->ssl->biord != NULL) { + if (bio->next_bio != NULL) + wc_BioPush(bssl->ssl->biord, bio->next_bio); + bio->next_bio = bssl->ssl->biord; + + if (LockMutex(&bssl->ssl->biord->refMutex) != 0) { + WOLFSSL_MSG("Couldn't lock count mutex"); + ret = 0; + break; + } + bssl->ssl->biord->references++; + UnLockMutex(&bssl->ssl->biord->refMutex); + } + bio->init = 1; + break; + + case BIO_C_GET_SSL: + if (ptr != NULL) + *(WOLFSSL **)ptr = bssl->ssl; + else + ret = 0; + break; + + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + + case BIO_CTRL_WPENDING: + ret = wc_BioCtrl(bssl->ssl->biowr, cmd, num, ptr); + break; + + case BIO_CTRL_PENDING: + ret = wolfSSL_pending(bssl->ssl); + if (!ret) + ret = wc_BioPending(bssl->ssl->biord); + break; + + case BIO_CTRL_FLUSH: + wc_BioClearRetryFlags(bio); + ret = wc_BioCtrl(bssl->ssl->biowr, cmd, num, ptr); + wc_BioCopyNextRetry(bio); + break; + + case BIO_CTRL_PUSH: + if (bio->next_bio != NULL && bio->next_bio != bssl->ssl->biord) { + ret = wc_BioSSL_set_bio(bssl->ssl, + bio->next_bio, bio->next_bio); + if (LockMutex(&bio->next_bio->refMutex) != 0) { + WOLFSSL_MSG("Couldn't lock count mutex"); + ret = 0; + break; + } + bio->next_bio->references++; + UnLockMutex(&bio->next_bio->refMutex); + } + break; + + case BIO_CTRL_POP: + if (bio == ptr) { + if (bssl->ssl->biord != bssl->ssl->biowr) + wc_BioFreeAll(bssl->ssl->biowr); + if (bio->next_bio != NULL) { + if (LockMutex(&bio->next_bio->refMutex) != 0) { + WOLFSSL_MSG("Couldn't lock count mutex"); + ret = 0; + break; + } + bio->next_bio->references--; + UnLockMutex(&bio->next_bio->refMutex); + } + bssl->ssl->biowr = NULL; + bssl->ssl->biord = NULL; + } + break; + + case BIO_C_DO_STATE_MACHINE: + wc_BioClearRetryFlags(bio); + + bio->retry_reason = 0; + ret = (long)wolfSSL_negotiate(bssl->ssl); + + switch (wolfSSL_get_error(bssl->ssl, (int)ret)) { + case SSL_ERROR_WANT_READ: + wc_BioSetFlags(bio, BIO_FLAGS_READ | + BIO_FLAGS_SHOULD_RETRY); + break; + + case SSL_ERROR_WANT_WRITE: + wc_BioSetFlags(bio, BIO_FLAGS_WRITE | + BIO_FLAGS_SHOULD_RETRY); + break; + + case SSL_ERROR_WANT_CONNECT: + wc_BioSetFlags(bio, BIO_FLAGS_IO_SPECIAL | + BIO_FLAGS_SHOULD_RETRY); + bio->retry_reason = bio->next_bio->retry_reason; + break; + + case SSL_ERROR_WANT_X509_LOOKUP: + wc_BioSetRetrySpecial(bio); + bio->retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + + default: + break; + } + break; + + case BIO_CTRL_DUP: + { + WOLFCRYPT_BIO *dbio; + dbio = (WOLFCRYPT_BIO *)ptr; + + if (((WOLFCRYPT_BIO_SSL *)dbio->ptr)->ssl != NULL) + wolfSSL_free(((WOLFCRYPT_BIO_SSL *)dbio->ptr)->ssl); + + /* add copy ssl */ + ((WOLFCRYPT_BIO_SSL *)dbio->ptr)->ssl = wolfSSL_dup(bssl->ssl); + + ((WOLFCRYPT_BIO_SSL *)dbio->ptr)->renegotiate_count = + bssl->renegotiate_count; + + ((WOLFCRYPT_BIO_SSL *)dbio->ptr)->byte_count = bssl->byte_count; + + ((WOLFCRYPT_BIO_SSL *)dbio->ptr)->renegotiate_timeout = + bssl->renegotiate_timeout; + + ((WOLFCRYPT_BIO_SSL *)dbio->ptr)->last_time = bssl->last_time; + + if (((WOLFCRYPT_BIO_SSL *)dbio->ptr)->ssl == NULL) + ret = 0; + } + break; + + case BIO_C_GET_FD: + ret = wc_BioCtrl(bssl->ssl->biord, cmd, num, ptr); + break; + + case BIO_CTRL_SET_CALLBACK: + /* not supported */ + WOLFSSL_MSG("BIO_CTRL_SET_CALLBACK not supported\n"); + ret = 0; + break; + + case BIO_CTRL_GET_CALLBACK: + /* not supported */ + WOLFSSL_MSG("BIO_CTRL_GET_CALLBACK not supported\n"); + ptr = NULL; + ret = 0; + break; + + default: + ret = wc_BioCtrl(bssl->ssl->biord, cmd, num, ptr); + break; + } + + return ret; +} + +static long wc_BioSSL_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, + WOLFCRYPT_BIO_info_cb *fp) +{ + long ret = 1; + WOLFCRYPT_BIO_SSL *bssl; + + WOLFSSL_ENTER("wc_BioSSL_callback_ctrl"); + + if (bio == NULL || bio->ptr == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + bssl = (WOLFCRYPT_BIO_SSL *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + /* not supported */ + WOLFSSL_MSG("BIO_CTRL_GET_CALLBACK not supported\n"); + ret = 0; + break; + + default: + ret = wc_BioCallbackCtrl(bssl->ssl->biord, cmd, fp); + break; + } + + return ret; +} + +static int wc_BioSSL_puts(WOLFCRYPT_BIO *bio, const char *str) +{ + WOLFSSL_ENTER("wc_BioSSL_puts"); + + if (bio == NULL || str == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + return wc_BioSSL_write(bio, str, (int)strlen(str)); +} + +void wc_BioSSLShutdown(WOLFCRYPT_BIO *bio) +{ + WOLFSSL_ENTER("wc_BioSSL_shutdown"); + + while (bio != NULL) { + if (bio->method->type == BIO_TYPE_SSL) { + wolfSSL_shutdown(((WOLFCRYPT_BIO_SSL *)bio->ptr)->ssl); + break; + } + + bio = bio->next_bio; + } +} + + +WOLFCRYPT_BIO *wolfSSL_BioNewBufferSSLConnect(WOLFSSL_CTX *ctx) +{ + WOLFCRYPT_BIO *bio = NULL, *buf = NULL, *ssl = NULL; + + WOLFSSL_ENTER("wolfSSL_BioNewBufferSSLConnect"); + + if (ctx == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return NULL; + } + + buf = wc_BioNew(wc_Bio_f_buffer()); + if (buf == NULL) + return NULL; + + ssl = wolfSSL_BioNewSSLConnect(ctx); + if (ssl == NULL) + goto err; + + bio = wc_BioPush(buf, ssl); + if (bio == NULL) + goto err; + + return bio; + +err: + if (buf != NULL) + wc_BioFree(buf); + if (ssl != NULL) + wc_BioFree(ssl); + + return NULL; +} + +WOLFCRYPT_BIO *wolfSSL_BioNewSSLConnect(WOLFSSL_CTX *ctx) +{ + WOLFCRYPT_BIO *bio = NULL, *con = NULL, *ssl = NULL; + + WOLFSSL_ENTER("wolfSSL_BioNewSSLConnect"); + + if (ctx == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return NULL; + } + + con = wc_BioNew(wc_Bio_s_connect()); + if (con == NULL) + return NULL; + + ssl = wolfSSL_BioNewSSL(ctx, 1); + if (ssl == NULL) + goto err; + + bio = wc_BioPush(ssl, con); + if (bio == NULL) + goto err; + + return bio; + +err: + if (con != NULL) + wc_BioFree(con); + if (ssl != NULL) + wc_BioFree(ssl); + return NULL; +} + +WOLFCRYPT_BIO *wolfSSL_BioNewSSL(WOLFSSL_CTX *ctx, int mode) +{ + WOLFCRYPT_BIO *bio; + WOLFSSL *ssl; + + WOLFSSL_ENTER("wolfSSL_BioNewSSL"); + + if (ctx == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return NULL; + } + + bio = wc_BioNew(wc_Bio_f_ssl()); + if (bio == NULL) + return NULL; + + ssl = wolfSSL_new(ctx); + if (ssl == NULL) { + wc_BioFree(bio); + return NULL; + } + + if (mode) /* client */ + wolfSSL_set_connect_state(ssl); + else + wolfSSL_set_accept_state(ssl); + + wc_BioSetSSL(bio, ssl, mode); + + return bio; +} + +#endif /* OPENSSL_EXTRA */ + + #endif /* WOLFCRYPT_ONLY */ diff --git a/tests/api.c b/tests/api.c index f2340c224..74a1775a0 100644 --- a/tests/api.c +++ b/tests/api.c @@ -35,6 +35,7 @@ #include #include /* compatibility layer */ +#include #include #include @@ -619,6 +620,8 @@ static void test_client_nofail(void* args) reply[input] = 0; printf("Server response: %s\n", reply); } + else + printf("wolfSSL_read failed"); done2: wolfSSL_free(ssl); @@ -634,6 +637,359 @@ done2: return; } +/* BIO test */ +#if defined(OPENSSL_EXTRA) +static THREAD_RETURN WOLFSSL_THREAD test_server_bio(void* args) +{ + SOCKET_T sockfd = 0; + SOCKET_T clientfd = 0; + word16 port = wolfSSLPort; + + WOLFCRYPT_BIO *bio = 0; + char msg[] = "Server BIO, I hear you fa shizzle!"; + char input[1024]; + int idx; + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + ((func_args*)args)->return_code = TEST_FAIL; + tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 1); + CloseSocket(sockfd); + + bio = wc_BioNew(wc_Bio_s_socket()); + if (bio == NULL) { + printf("wc_BioNew failed\n"); + goto done; + } + + wc_BioSetFd(bio, clientfd, BIO_NOCLOSE); + + idx = wc_BioRead(bio, input, sizeof(input)-1); + if (idx <= 0) { + printf("wc_BioWrite failed\n"); + goto done; + } + + input[idx] = 0; + printf("Client message: %s\n", input); + + if (wc_BioWrite(bio, msg, sizeof(msg)) != sizeof(msg)) { + printf("wc_BioWrite failed\n"); +#ifdef WOLFSSL_TIRTOS + return; +#else + return 0; +#endif + } + +#ifdef WOLFSSL_TIRTOS + Task_yield(); +#endif + +done: + if (bio != 0) + wc_BioFreeAll(bio); + + CloseSocket(clientfd); + ((func_args*)args)->return_code = TEST_SUCCESS; + +#ifdef WOLFSSL_TIRTOS + fdCloseSession(Task_self()); +#endif + +#ifndef WOLFSSL_TIRTOS + return 0; +#endif +} + + +static void test_client_bio(void* args) +{ + WOLFCRYPT_BIO* bio = 0; + + char msg[64] = "Client BIO, hello wolfssl!"; + char reply[1024], ip[] = {127, 0, 0, 1}; + int input, port; + int msgSz = (int)strlen(msg); + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + ((func_args*)args)->return_code = TEST_FAIL; + + bio = wc_BioNew(wc_Bio_s_connect()); + if (bio == NULL) { + printf("wc_BioNew failed\n"); + goto done2; + } + + port = ((func_args*)args)->signal->port; + + wc_BioSetConnIp(bio, ip); + wc_BioSetConnIntPort(bio, &port); + + /* start connection */ + input = (int)wc_BioDoConnect(bio); + if (input <= 0) { + printf("wc_BioDoConnect failed %d\n", input); + goto done2; + } + + if (wc_BioWrite(bio, msg, msgSz) != msgSz) { + printf("wc_BioWrite failed"); + goto done2; + } + + input = wc_BioRead(bio, reply, sizeof(reply)-1); + if (input <= 0) { + printf("wc_BioRead failed"); + goto done2; + } + + reply[input] = 0; + printf("Server response: %s\n", reply); + +done2: + if (bio != 0) + wc_BioFreeAll(bio); + + ((func_args*)args)->return_code = TEST_SUCCESS; + +#ifdef WOLFSSL_TIRTOS + fdCloseSession(Task_self()); +#endif + + return; +} + +/* BIO SSL test */ +static THREAD_RETURN WOLFSSL_THREAD test_server_bio_ssl(void* args) +{ + SOCKET_T sockfd = 0; + SOCKET_T clientfd = 0; + word16 port = wolfSSLPort; + + WOLFCRYPT_BIO *ssl_bio = 0; + WOLFSSL_METHOD* method = 0; + WOLFSSL_CTX* ctx = 0; + WOLFSSL* ssl = 0; + + char msg[] = "Server BIO_SSL, I hear you fa shizzle!"; + char input[1024]; + int idx; + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + ((func_args*)args)->return_code = TEST_FAIL; + method = wolfSSLv23_server_method(); + ctx = wolfSSL_CTX_new(method); + + wolfSSL_CTX_set_verify(ctx, + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, 0); + +#ifdef OPENSSL_EXTRA + wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); +#endif + + if (wolfSSL_CTX_load_verify_locations(ctx, cliCert, 0) != SSL_SUCCESS) + { + /*err_sys("can't load ca file, Please run from wolfSSL home dir");*/ + goto done; + } + if (wolfSSL_CTX_use_certificate_file(ctx, svrCert, SSL_FILETYPE_PEM) + != SSL_SUCCESS) + { + /*err_sys("can't load server cert chain file, " + "Please run from wolfSSL home dir");*/ + goto done; + } + if (wolfSSL_CTX_use_PrivateKey_file(ctx, svrKey, SSL_FILETYPE_PEM) + != SSL_SUCCESS) + { + /*err_sys("can't load server key file, " + "Please run from wolfSSL home dir");*/ + goto done; + } + + ssl = wolfSSL_new(ctx); + tcp_accept(&sockfd, &clientfd, (func_args*)args, port, 0, 0, 0, 1); + CloseSocket(sockfd); + + wolfSSL_set_fd(ssl, clientfd); + +#ifdef NO_PSK +#if !defined(NO_FILESYSTEM) && !defined(NO_DH) + wolfSSL_SetTmpDH_file(ssl, dhParam, SSL_FILETYPE_PEM); +#elif !defined(NO_DH) + SetDH(ssl); /* will repick suites with DHE, higher priority than PSK */ +#endif +#endif + + ssl_bio = wc_BioNew(wc_Bio_f_ssl()); + if (ssl_bio == NULL) { + printf("wc_BioNew failed\n"); + goto done; + } + + wc_BioSetSSL(ssl_bio, ssl, BIO_NOCLOSE); + + /* Setup accept BIO */ + if (wc_BioDoAccept(ssl_bio) <= 0) { + printf("wc_BioDoAccept failed\n"); + goto done; + } + + /* Now wait for incoming connection */ + if (wc_BioDoHandshake(ssl_bio) <= 0) { + printf("wc_BioDoHandshake failed\n"); + goto done; + } + + idx = wc_BioRead(ssl_bio, input, sizeof(input)-1); + if (idx <= 0) { + printf("wc_BioWrite failed\n"); + goto done; + } + + input[idx] = 0; + printf("Client message: %s\n", input); + + if (wc_BioWrite(ssl_bio, msg, sizeof(msg)) != sizeof(msg)) { + printf("wc_BioWrite failed\n"); +#ifdef WOLFSSL_TIRTOS + return; +#else + return 0; +#endif + } + +#ifdef WOLFSSL_TIRTOS + Task_yield(); +#endif + +done: + if (ssl_bio != 0) + wc_BioFreeAll(ssl_bio); + wolfSSL_CTX_free(ctx); + + CloseSocket(clientfd); + ((func_args*)args)->return_code = TEST_SUCCESS; + +#ifdef WOLFSSL_TIRTOS + fdCloseSession(Task_self()); +#endif + +#if defined(NO_MAIN_DRIVER) && defined(HAVE_ECC) && defined(FP_ECC) \ +&& defined(HAVE_THREAD_LS) + wc_ecc_fp_free(); /* free per thread cache */ +#endif + +#ifndef WOLFSSL_TIRTOS + return 0; +#endif +} + + +static void test_client_bio_ssl(void* args) +{ + SOCKET_T sockfd = 0; + + WOLFCRYPT_BIO* ssl_bio = 0; + WOLFSSL_METHOD* method = 0; + WOLFSSL_CTX* ctx = 0; + WOLFSSL* ssl = 0; + + char msg[64] = "Client BIO_SSL, hello wolfssl!"; + char reply[1024]; + int input; + int msgSz = (int)strlen(msg); + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + ((func_args*)args)->return_code = TEST_FAIL; + method = wolfSSLv23_client_method(); + ctx = wolfSSL_CTX_new(method); + +#ifdef OPENSSL_EXTRA + wolfSSL_CTX_set_default_passwd_cb(ctx, PasswordCallBack); +#endif + + if (wolfSSL_CTX_load_verify_locations(ctx, caCert, 0) != SSL_SUCCESS) + { + /* err_sys("can't load ca file, Please run from wolfSSL home dir");*/ + goto done2; + } + if (wolfSSL_CTX_use_certificate_file(ctx, cliCert, SSL_FILETYPE_PEM) + != SSL_SUCCESS) + { + /*err_sys("can't load client cert file, " + "Please run from wolfSSL home dir");*/ + goto done2; + } + if (wolfSSL_CTX_use_PrivateKey_file(ctx, cliKey, SSL_FILETYPE_PEM) + != SSL_SUCCESS) + { + /*err_sys("can't load client key file, " + "Please run from wolfSSL home dir");*/ + goto done2; + } + + ssl = wolfSSL_new(ctx); + tcp_connect(&sockfd, wolfSSLIP, ((func_args*)args)->signal->port, 0, ssl); + wolfSSL_set_fd(ssl, sockfd); + + ssl_bio = wc_BioNew(wc_Bio_f_ssl()); + if (ssl_bio == NULL) { + printf("wc_BioNew failed\n"); + goto done2; + } + + wc_BioSetSSL(ssl_bio, ssl, BIO_NOCLOSE); + + /* start connection */ + if (wc_BioDoConnect(ssl_bio) <= 0) { + printf("wc_BioDoConnect failed\n"); + goto done2; + } + + if (wc_BioWrite(ssl_bio, msg, msgSz) != msgSz) { + printf("wc_BioWrite failed"); + goto done2; + } + + input = wc_BioRead(ssl_bio, reply, sizeof(reply)-1); + if (input <= 0) { + printf("wc_BioRead failed"); + goto done2; + } + + reply[input] = 0; + printf("Server response: %s\n", reply); + +done2: + if (ssl_bio != 0) + wc_BioFreeAll(ssl_bio); + wolfSSL_CTX_free(ctx); + + CloseSocket(sockfd); + ((func_args*)args)->return_code = TEST_SUCCESS; + +#ifdef WOLFSSL_TIRTOS + fdCloseSession(Task_self()); +#endif + + return; +} + +#endif /* OPENSSL_EXTRA */ + /* SNI / ALPN helper functions */ #if defined(HAVE_SNI) || defined(HAVE_ALPN) @@ -869,6 +1225,118 @@ static void test_wolfSSL_read_write(void) #endif } +#if defined(OPENSSL_EXTRA) + +static void test_wolfSSL_read_write_bio(void) +{ +#ifdef HAVE_IO_TESTS_DEPENDENCIES + /* The unit testing for read and write shall happen simutaneously, since + * one can't do anything with one without the other. (Except for a failure + * test case.) This function will call all the others that will set up, + * execute, and report their test findings. + * + * Set up the success case first. This function will become the template + * for the other tests. This should eventually be renamed + * + * The success case isn't interesting, how can this fail? + * - Do not give the client context a CA certificate. The connect should + * fail. Do not need server for this? + * - Using NULL for the ssl object on server. Do not need client for this. + * - Using NULL for the ssl object on client. Do not need server for this. + * - Good ssl objects for client and server. Client write() without server + * read(). + * - Good ssl objects for client and server. Server write() without client + * read(). + * - Forgetting the password callback? + */ + tcp_ready ready; + func_args client_args; + func_args server_args; + THREAD_TYPE serverThread; + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + StartTCP(); + InitTcpReady(&ready); + + server_args.signal = &ready; + client_args.signal = &ready; + + start_thread(test_server_bio, &server_args, &serverThread); + wait_tcp_ready(&server_args); + test_client_bio(&client_args); + join_thread(serverThread); + + AssertTrue(client_args.return_code); + AssertTrue(server_args.return_code); + + FreeTcpReady(&ready); + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + +#endif +} + +static void test_wolfSSL_read_write_bio_ssl(void) +{ +#ifdef HAVE_IO_TESTS_DEPENDENCIES + /* The unit testing for read and write shall happen simutaneously, since + * one can't do anything with one without the other. (Except for a failure + * test case.) This function will call all the others that will set up, + * execute, and report their test findings. + * + * Set up the success case first. This function will become the template + * for the other tests. This should eventually be renamed + * + * The success case isn't interesting, how can this fail? + * - Do not give the client context a CA certificate. The connect should + * fail. Do not need server for this? + * - Using NULL for the ssl object on server. Do not need client for this. + * - Using NULL for the ssl object on client. Do not need server for this. + * - Good ssl objects for client and server. Client write() without server + * read(). + * - Good ssl objects for client and server. Server write() without client + * read(). + * - Forgetting the password callback? + */ + tcp_ready ready; + func_args client_args; + func_args server_args; + THREAD_TYPE serverThread; + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + StartTCP(); + InitTcpReady(&ready); + + server_args.signal = &ready; + client_args.signal = &ready; + + start_thread(test_server_bio_ssl, &server_args, &serverThread); + wait_tcp_ready(&server_args); + test_client_bio_ssl(&client_args); + join_thread(serverThread); + + AssertTrue(client_args.return_code); + AssertTrue(server_args.return_code); + + FreeTcpReady(&ready); + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + +#endif +} + +#endif /* OPENSSL_EXTRA */ + /*----------------------------------------------------------------------------* | TLS extensions tests *----------------------------------------------------------------------------*/ @@ -1607,6 +2075,11 @@ void ApiTest(void) test_wolfSSL_SetTmpDH_buffer(); test_wolfSSL_read_write(); +#if defined(OPENSSL_EXTRA) + test_wolfSSL_read_write_bio(); + test_wolfSSL_read_write_bio_ssl(); +#endif + /* TLS extensions tests */ test_wolfSSL_UseSNI(); test_wolfSSL_UseMaxFragment(); diff --git a/wolfcrypt/src/bio.c b/wolfcrypt/src/bio.c index b5734002f..c92b708f9 100644 --- a/wolfcrypt/src/bio.c +++ b/wolfcrypt/src/bio.c @@ -30,6 +30,25 @@ #include #include +#include +#include +#include +#include + +#ifdef USE_WINDOWS_API +#include +#include +#include +#else +#include +#include +#include +#ifdef SO_NOSIGPIPE +#include +#endif +#endif /* USE_WINDOWS_API */ + + #include #include @@ -39,27 +58,28 @@ #include #endif -#include +#include +#include +#include -WOLFCRYPT_BIO *WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_METHOD *method) +WOLFCRYPT_BIO *wc_BioNew(WOLFCRYPT_BIO_METHOD *method) { WOLFCRYPT_BIO *bio; - WOLFSSL_ENTER("WOLFCRYPT_BIO_new"); + WOLFSSL_ENTER("wc_BioNew"); if (method == NULL) { WOLFSSL_ERROR(BAD_FUNC_ARG); return NULL; } - bio = (WOLFCRYPT_BIO *)XMALLOC(sizeof(WOLFCRYPT_BIO), - 0, DYNAMIC_TYPE_OPENSSL); + bio = (WOLFCRYPT_BIO *)XMALLOC(sizeof(WOLFCRYPT_BIO),0,DYNAMIC_TYPE_OPENSSL); if (bio == NULL) { WOLFSSL_ERROR(MEMORY_E); return NULL; } - if (!WOLFCRYPT_BIO_set(bio, method)) { + if (!wc_BioSet(bio, method)) { XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL); return NULL; } @@ -69,18 +89,18 @@ WOLFCRYPT_BIO *WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_METHOD *method) return NULL; } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_new", 1); + WOLFSSL_LEAVE("wc_BioNew", 1); return bio; } -int WOLFCRYPT_BIO_set(WOLFCRYPT_BIO *bio, WOLFCRYPT_BIO_METHOD *method) +int wc_BioSet(WOLFCRYPT_BIO *bio, WOLFCRYPT_BIO_METHOD *method) { - WOLFSSL_ENTER("WOLFCRYPT_BIO_set"); + WOLFSSL_ENTER("wc_BioSet"); if (bio == NULL || method == NULL) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_set", 0); + WOLFSSL_LEAVE("wc_BioSet", 0); return 0; } @@ -102,24 +122,24 @@ int WOLFCRYPT_BIO_set(WOLFCRYPT_BIO *bio, WOLFCRYPT_BIO_METHOD *method) if (method->create != NULL) if (!method->create(bio)) { WOLFSSL_ERROR(BIO_CREATE_METHOD_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_set", 0); + WOLFSSL_LEAVE("wc_BioSet", 0); return 0; } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_set", 1); + WOLFSSL_LEAVE("wc_BioSet", 1); return 1; } -int WOLFCRYPT_BIO_free(WOLFCRYPT_BIO *bio) +int wc_BioFree(WOLFCRYPT_BIO *bio) { long ret; - WOLFSSL_ENTER("WOLFCRYPT_BIO_free"); + WOLFSSL_ENTER("wc_BioFree"); if (bio == NULL) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_free", 0); + WOLFSSL_LEAVE("wc_BioFree", 0); return 0; } @@ -134,7 +154,7 @@ int WOLFCRYPT_BIO_free(WOLFCRYPT_BIO *bio) } else if (bio->references < 0) { WOLFSSL_ERROR(BIO_BAD_REF); - WOLFSSL_MSG("WOLFCRYPT_BIO_free bad bio references"); + WOLFSSL_MSG("wc_BioFree bad bio references"); UnLockMutex(&bio->refMutex); return 0; } @@ -145,7 +165,7 @@ int WOLFCRYPT_BIO_free(WOLFCRYPT_BIO *bio) ret = bio->callback(bio, BIO_CB_FREE, NULL, 0, 0, 1); if (ret <= 0) { WOLFSSL_ERROR(BIO_CALLBACK_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_free", (int)ret); + WOLFSSL_LEAVE("wc_BioFree", (int)ret); return (int)(ret); } } @@ -160,68 +180,68 @@ int WOLFCRYPT_BIO_free(WOLFCRYPT_BIO *bio) XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL); bio = NULL; - WOLFSSL_LEAVE("WOLFCRYPT_BIO_free", 1); + WOLFSSL_LEAVE("wc_BioFree", 1); return 1; } -void WOLFCRYPT_BIO_clear_flags(WOLFCRYPT_BIO *bio, int flags) +void wc_BioClearFlags(WOLFCRYPT_BIO *bio, int flags) { bio->flags &= ~flags; } -void WOLFCRYPT_BIO_set_flags(WOLFCRYPT_BIO *bio, int flags) +void wc_BioSetFlags(WOLFCRYPT_BIO *bio, int flags) { bio->flags |= flags; } -int WOLFCRYPT_BIO_test_flags(const WOLFCRYPT_BIO *bio, int flags) +int wc_BioTestFlags(const WOLFCRYPT_BIO *bio, int flags) { return (bio->flags & flags); } -long (*WOLFCRYPT_BIO_get_callback(const WOLFCRYPT_BIO *bio)) +long (*wc_BioGetCallback(const WOLFCRYPT_BIO *bio)) (WOLFCRYPT_BIO *, int, const char *, int, long, long) { return bio->callback; } -void WOLFCRYPT_BIO_set_callback(WOLFCRYPT_BIO *bio, - long (*cb) (WOLFCRYPT_BIO *, int, const char *, - int, long, long)) +void wc_BioSetCallback(WOLFCRYPT_BIO *bio, + long (*cb) (WOLFCRYPT_BIO *, int, const char *, + int, long, long)) { bio->callback = cb; } -void WOLFCRYPT_BIO_set_callback_arg(WOLFCRYPT_BIO *bio, char *arg) +void wc_BioSetCallbackArg(WOLFCRYPT_BIO *bio, char *arg) { bio->cb_arg = arg; } -char *WOLFCRYPT_BIO_get_callback_arg(const WOLFCRYPT_BIO *bio) +char *wc_BioGetCallbackArg(const WOLFCRYPT_BIO *bio) { return bio->cb_arg; } -const char *WOLFCRYPT_BIO_method_name(const WOLFCRYPT_BIO *bio) +const char *wc_BioMethodName(const WOLFCRYPT_BIO *bio) { return bio->method->name; } -int WOLFCRYPT_BIO_method_type(const WOLFCRYPT_BIO *bio) +int wc_BioMethodType(const WOLFCRYPT_BIO *bio) { return bio->method->type; } -int WOLFCRYPT_BIO_read(WOLFCRYPT_BIO *bio, void *data, int size) +int wc_BioRead(WOLFCRYPT_BIO *bio, void *data, int size) { long ret; - WOLFSSL_ENTER("WOLFCRYPT_BIO_read"); + WOLFSSL_ENTER("wc_BioRead"); if ((bio == NULL) || (bio->method == NULL) || (bio->method->bread == NULL) || (data == NULL)) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_read", -2); + WOLFSSL_LEAVE("wc_BioRead", -2); return -2; } @@ -230,14 +250,14 @@ int WOLFCRYPT_BIO_read(WOLFCRYPT_BIO *bio, void *data, int size) ret = bio->callback(bio, BIO_CB_READ, data, size, 0, 1); if (ret <= 0) { WOLFSSL_ERROR(BIO_CALLBACK_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_read", (int)ret); + WOLFSSL_LEAVE("wc_BioRead", (int)ret); return (int)(ret); } } if (!bio->init) { WOLFSSL_ERROR(BIO_UNINITIALIZED_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_read", -2); + WOLFSSL_LEAVE("wc_BioRead", -2); return -2; } @@ -253,27 +273,27 @@ int WOLFCRYPT_BIO_read(WOLFCRYPT_BIO *bio, void *data, int size) WOLFSSL_ERROR(BIO_CALLBACK_E); } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_read", (int)ret); + WOLFSSL_LEAVE("wc_BioRead", (int)ret); return (int)ret; } -int WOLFCRYPT_BIO_write(WOLFCRYPT_BIO *bio, const void *data, int size) +int wc_BioWrite(WOLFCRYPT_BIO *bio, const void *data, int size) { long ret; - WOLFSSL_ENTER("WOLFCRYPT_BIO_write"); + WOLFSSL_ENTER("wc_BioWrite"); if (bio == NULL) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_write", 0); + WOLFSSL_LEAVE("wc_BioWrite", 0); return 0; } if ((bio->method == NULL) || (bio->method->bwrite == NULL) || (data == NULL)) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_write", -2); + WOLFSSL_LEAVE("wc_BioWrite", -2); return -2; } @@ -282,14 +302,14 @@ int WOLFCRYPT_BIO_write(WOLFCRYPT_BIO *bio, const void *data, int size) ret = bio->callback(bio, BIO_CB_WRITE, data, size, 0, 1); if (ret <= 0) { WOLFSSL_ERROR(BIO_CALLBACK_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_write", (int)ret); + WOLFSSL_LEAVE("wc_BioWrite", (int)ret); return (int)(ret); } } if (!bio->init) { WOLFSSL_ERROR(BIO_UNINITIALIZED_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_write", -2); + WOLFSSL_LEAVE("wc_BioWrite", -2); return -2; } @@ -305,21 +325,21 @@ int WOLFCRYPT_BIO_write(WOLFCRYPT_BIO *bio, const void *data, int size) WOLFSSL_ERROR(BIO_CALLBACK_E); } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_write", (int)ret); + WOLFSSL_LEAVE("wc_BioWrite", (int)ret); return (int)ret; } -int WOLFCRYPT_BIO_puts(WOLFCRYPT_BIO *bio, const char *data) +int wc_BioPuts(WOLFCRYPT_BIO *bio, const char *data) { long ret; - WOLFSSL_ENTER("WOLFCRYPT_BIO_puts"); + WOLFSSL_ENTER("wc_BioPuts"); if ((bio == NULL) || (bio->method == NULL) || (bio->method->bputs == NULL) || (data == NULL)) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_puts", -2); + WOLFSSL_LEAVE("wc_BioPuts", -2); return -2; } @@ -328,14 +348,14 @@ int WOLFCRYPT_BIO_puts(WOLFCRYPT_BIO *bio, const char *data) ret = bio->callback(bio, BIO_CB_PUTS, data, 0, 0, 1); if (ret <= 0) { WOLFSSL_ERROR(BIO_CALLBACK_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_puts", (int)ret); + WOLFSSL_LEAVE("wc_BioPuts", (int)ret); return (int)(ret); } } if (!bio->init) { WOLFSSL_ERROR(BIO_UNINITIALIZED_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_puts", -2); + WOLFSSL_LEAVE("wc_BioPuts", -2); return -2; } @@ -351,21 +371,21 @@ int WOLFCRYPT_BIO_puts(WOLFCRYPT_BIO *bio, const char *data) WOLFSSL_ERROR(BIO_CALLBACK_E); } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_puts", (int)ret); + WOLFSSL_LEAVE("wc_BioPuts", (int)ret); return (int)ret; } -int WOLFCRYPT_BIO_gets(WOLFCRYPT_BIO *bio, char *data, int size) +int wc_BioGets(WOLFCRYPT_BIO *bio, char *data, int size) { long ret; - WOLFSSL_ENTER("WOLFCRYPT_BIO_gets"); + WOLFSSL_ENTER("wc_BioGets"); if ((bio == NULL) || (bio->method == NULL) || (bio->method->bgets == NULL) || (data == NULL)) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_gets", -2); + WOLFSSL_LEAVE("wc_BioGets", -2); return -2; } @@ -374,7 +394,7 @@ int WOLFCRYPT_BIO_gets(WOLFCRYPT_BIO *bio, char *data, int size) ret = bio->callback(bio, BIO_CB_GETS, data, size, 0, 1); if (ret <= 0) { WOLFSSL_ERROR(BIO_CALLBACK_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_gets", (int)ret); + WOLFSSL_LEAVE("wc_BioGets", (int)ret); return (int)(ret); } } @@ -382,7 +402,7 @@ int WOLFCRYPT_BIO_gets(WOLFCRYPT_BIO *bio, char *data, int size) if (!bio->init) { WOLFSSL_ERROR(BIO_UNINITIALIZED_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_gets", -2); + WOLFSSL_LEAVE("wc_BioGets", -2); return -2; } @@ -396,26 +416,26 @@ int WOLFCRYPT_BIO_gets(WOLFCRYPT_BIO *bio, char *data, int size) WOLFSSL_ERROR(BIO_CALLBACK_E); } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_gets", (int)ret); + WOLFSSL_LEAVE("wc_BioGets", (int)ret); return (int)ret; } -long WOLFCRYPT_BIO_ctrl(WOLFCRYPT_BIO *bio, int cmd, long larg, void *parg) +long wc_BioCtrl(WOLFCRYPT_BIO *bio, int cmd, long larg, void *parg) { long ret; - WOLFSSL_ENTER("WOLFCRYPT_BIO_ctrl"); + WOLFSSL_ENTER("wc_BioCtrl"); if (bio == NULL) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_ctrl bio", 0); + WOLFSSL_LEAVE("wc_BioCtrl bio", 0); return 0; } if ((bio->method == NULL) || (bio->method->ctrl == NULL)) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_ctrl method method-ctrl", -2); + WOLFSSL_LEAVE("wc_BioCtrl method method-ctrl", -2); return -2; } @@ -424,7 +444,7 @@ long WOLFCRYPT_BIO_ctrl(WOLFCRYPT_BIO *bio, int cmd, long larg, void *parg) ret = bio->callback(bio, BIO_CB_CTRL, parg, cmd, larg, 1); if (ret <= 0) { WOLFSSL_ERROR(BIO_CALLBACK_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_ctrl callback", (int)ret); + WOLFSSL_LEAVE("wc_BioCtrl callback", (int)ret); return ret; } } @@ -434,32 +454,32 @@ long WOLFCRYPT_BIO_ctrl(WOLFCRYPT_BIO *bio, int cmd, long larg, void *parg) /* callback if set */ if (bio->callback != NULL) { ret = bio->callback(bio, BIO_CB_CTRL | BIO_CB_RETURN, - parg, cmd, larg, ret); + parg, cmd, larg, ret); if (ret <= 0) WOLFSSL_ERROR(BIO_CALLBACK_E); } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_ctrl", (int)ret); + WOLFSSL_LEAVE("wc_BioCtrl", (int)ret); return ret; } -long WOLFCRYPT_BIO_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, - void (*fp) (WOLFCRYPT_BIO *, int, const char *, - int, long, long)) +long wc_BioCallbackCtrl(WOLFCRYPT_BIO *bio, int cmd, + void (*fp) (WOLFCRYPT_BIO *, int, const char *, + int, long, long)) { long ret; - WOLFSSL_ENTER("WOLFCRYPT_BIO_callback_ctrl"); + WOLFSSL_ENTER("wc_BioCallbackCtrl"); if (bio == NULL) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_callback_ctrl", 0); + WOLFSSL_LEAVE("wc_BioCallbackCtrl", 0); return 0; } if ((bio->method == NULL) || (bio->method->callback_ctrl == NULL)) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_callback_ctrl", -2); + WOLFSSL_LEAVE("wc_BioCallbackCtrl", -2); return -2; } @@ -468,7 +488,7 @@ long WOLFCRYPT_BIO_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, ret = bio->callback(bio, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1); if (ret <= 0) { WOLFSSL_ERROR(BIO_CALLBACK_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_callback_ctrl", (int)ret); + WOLFSSL_LEAVE("wc_BioCallbackCtrl", (int)ret); return ret; } } @@ -483,73 +503,73 @@ long WOLFCRYPT_BIO_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, WOLFSSL_ERROR(BIO_CALLBACK_E); } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_callback_ctrl", (int)ret); + WOLFSSL_LEAVE("wc_BioCallbackCtrl", (int)ret); return ret; } -int WOLFCRYPT_BIO_indent(WOLFCRYPT_BIO *bio, int indent, int max) +int wc_BioIndent(WOLFCRYPT_BIO *bio, int indent, int max) { - WOLFSSL_ENTER("WOLFCRYPT_BIO_indent"); + WOLFSSL_ENTER("wc_BioIndent"); if (indent < 0) indent = 0; if (indent > max) indent = max; while (indent--) - if (WOLFCRYPT_BIO_puts(bio, " ") != 1) { + if (wc_BioPuts(bio, " ") != 1) { WOLFSSL_ERROR(BIO_PUTS_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_indent", 0); + WOLFSSL_LEAVE("wc_BioIndent", 0); return 0; } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_indent", 1); + WOLFSSL_LEAVE("wc_BioIndent", 1); return 1; } -long WOLFCRYPT_BIO_int_ctrl(WOLFCRYPT_BIO *bio, int cmd, long larg, int iarg) +long wc_BioIntCtrl(WOLFCRYPT_BIO *bio, int cmd, long larg, int iarg) { int i = iarg; - return WOLFCRYPT_BIO_ctrl(bio, cmd, larg, (char *)&i); + return wc_BioCtrl(bio, cmd, larg, (char *)&i); } -char *WOLFCRYPT_BIO_ptr_ctrl(WOLFCRYPT_BIO *bio, int cmd, long larg) +char *wc_BioPtrCtrl(WOLFCRYPT_BIO *bio, int cmd, long larg) { char *p = NULL; - WOLFSSL_ENTER("WOLFCRYPT_BIO_ptr_ctrl"); + WOLFSSL_ENTER("wc_BioPtrCtrl"); - if (WOLFCRYPT_BIO_ctrl(bio, cmd, larg, (char *)&p) <= 0) { + if (wc_BioCtrl(bio, cmd, larg, (char *)&p) <= 0) { WOLFSSL_ERROR(BIO_CTRL_E); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_ptr_ctrl", 0); + WOLFSSL_LEAVE("wc_BioPtrCtrl", 0); return NULL; } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_ptr_ctrl", 1); + WOLFSSL_LEAVE("wc_BioPtrCtrl", 1); return p; } -size_t WOLFCRYPT_BIO_ctrl_pending(WOLFCRYPT_BIO *bio) +size_t wc_BioCtrlPending(WOLFCRYPT_BIO *bio) { - return WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL); + return wc_BioCtrl(bio, BIO_CTRL_PENDING, 0, NULL); } -size_t WOLFCRYPT_BIO_ctrl_wpending(WOLFCRYPT_BIO *bio) +size_t wc_BioCtrlWpending(WOLFCRYPT_BIO *bio) { - return WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL); + return wc_BioCtrl(bio, BIO_CTRL_WPENDING, 0, NULL); } /* put the 'bio' on the end of b's list of operators */ -WOLFCRYPT_BIO *WOLFCRYPT_BIO_push(WOLFCRYPT_BIO *top, WOLFCRYPT_BIO *next) +WOLFCRYPT_BIO *wc_BioPush(WOLFCRYPT_BIO *top, WOLFCRYPT_BIO *next) { WOLFCRYPT_BIO *tmp; - WOLFSSL_ENTER("WOLFCRYPT_BIO_push"); + WOLFSSL_ENTER("wc_BioPush"); if (top == NULL) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_push", 0); + WOLFSSL_LEAVE("wc_BioPush", 0); return next; } @@ -561,26 +581,26 @@ WOLFCRYPT_BIO *WOLFCRYPT_BIO_push(WOLFCRYPT_BIO *top, WOLFCRYPT_BIO *next) next->prev_bio = tmp; /* called to do internal processing */ - WOLFCRYPT_BIO_ctrl(top, BIO_CTRL_PUSH, 0, tmp); + wc_BioCtrl(top, BIO_CTRL_PUSH, 0, tmp); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_push", 1); + WOLFSSL_LEAVE("wc_BioPush", 1); return top; } /* Remove the first and return the rest */ -WOLFCRYPT_BIO *WOLFCRYPT_BIO_pop(WOLFCRYPT_BIO *bio) +WOLFCRYPT_BIO *wc_BioPop(WOLFCRYPT_BIO *bio) { WOLFCRYPT_BIO *ret; - WOLFSSL_ENTER("WOLFCRYPT_BIO_pop"); + WOLFSSL_ENTER("wc_BioPop"); if (bio == NULL) return NULL; ret = bio->next_bio; - WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_POP, 0, bio); + wc_BioCtrl(bio, BIO_CTRL_POP, 0, bio); if (bio->prev_bio != NULL) bio->prev_bio->next_bio = bio->next_bio; @@ -590,20 +610,20 @@ WOLFCRYPT_BIO *WOLFCRYPT_BIO_pop(WOLFCRYPT_BIO *bio) bio->next_bio = NULL; bio->prev_bio = NULL; - WOLFSSL_LEAVE("WOLFCRYPT_BIO_pop", 1); + WOLFSSL_LEAVE("wc_BioPop", 1); return ret; } -WOLFCRYPT_BIO *WOLFCRYPT_BIO_get_retry_BIO(WOLFCRYPT_BIO *bio, int *reason) +WOLFCRYPT_BIO *wc_BioGetRetryBio(WOLFCRYPT_BIO *bio, int *reason) { WOLFCRYPT_BIO *b, *last; - WOLFSSL_ENTER("WOLFCRYPT_BIO_get_retry_BIO"); + WOLFSSL_ENTER("wc_BioGetRetryBio"); b = last = bio; for (; b != NULL; ) { - if (!WOLFCRYPT_BIO_should_retry(b)) + if (!wc_BioShouldRetry(b)) break; last = b; b = b->next_bio; @@ -612,35 +632,35 @@ WOLFCRYPT_BIO *WOLFCRYPT_BIO_get_retry_BIO(WOLFCRYPT_BIO *bio, int *reason) if (reason != NULL) *reason = last->retry_reason; - WOLFSSL_LEAVE("WOLFCRYPT_BIO_get_retry_BIO", 1); + WOLFSSL_LEAVE("wc_BioGetRetryBio", 1); return last; } -int WOLFCRYPT_BIO_get_retry_reason(WOLFCRYPT_BIO *bio) +int wc_BioGetRetryReason(WOLFCRYPT_BIO *bio) { - WOLFSSL_ENTER("WOLFCRYPT_BIO_get_retry_reason"); + WOLFSSL_ENTER("wc_BioGetRetryReason"); if (bio == NULL) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_get_retry_reason", -1); + WOLFSSL_LEAVE("wc_BioGetRetryReason", -1); return -1; } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_get_retry_reason", (int)bio->retry_reason); + WOLFSSL_LEAVE("wc_BioGetRetryReason", (int)bio->retry_reason); return bio->retry_reason; } -WOLFCRYPT_BIO *WOLFCRYPT_BIO_find_type(WOLFCRYPT_BIO *bio, int type) +WOLFCRYPT_BIO *wc_BioFindType(WOLFCRYPT_BIO *bio, int type) { int mt, mask; - WOLFSSL_ENTER("WOLFCRYPT_BIO_find_type"); + WOLFSSL_ENTER("wc_BioFindType"); if (bio == NULL) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_find_type", -1); + WOLFSSL_LEAVE("wc_BioFindType", -1); return NULL; } @@ -651,12 +671,12 @@ WOLFCRYPT_BIO *WOLFCRYPT_BIO_find_type(WOLFCRYPT_BIO *bio, int type) if (!mask) { if (mt & type) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_find_type", type); + WOLFSSL_LEAVE("wc_BioFindType", type); return bio; } } else if (mt == type) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_find_type", type); + WOLFSSL_LEAVE("wc_BioFindType", type); return bio; } } @@ -667,74 +687,74 @@ WOLFCRYPT_BIO *WOLFCRYPT_BIO_find_type(WOLFCRYPT_BIO *bio, int type) return NULL; } -WOLFCRYPT_BIO *WOLFCRYPT_BIO_next(WOLFCRYPT_BIO *bio) +WOLFCRYPT_BIO *wc_BioNext(WOLFCRYPT_BIO *bio) { - WOLFSSL_ENTER("WOLFCRYPT_BIO_next"); + WOLFSSL_ENTER("wc_BioNext"); if (bio == NULL) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_next", 0); + WOLFSSL_LEAVE("wc_BioNext", 0); return NULL; } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_next", 1); + WOLFSSL_LEAVE("wc_BioNext", 1); return bio->next_bio; } -void WOLFCRYPT_BIO_free_all(WOLFCRYPT_BIO *bio) +void wc_BioFreeAll(WOLFCRYPT_BIO *bio) { WOLFCRYPT_BIO *b; int ref; - WOLFSSL_ENTER("WOLFCRYPT_BIO_free_all"); + WOLFSSL_ENTER("wc_BioFreeAll"); while (bio != NULL) { b = bio; ref = b->references; bio = bio->next_bio; - WOLFCRYPT_BIO_free(b); + wc_BioFree(b); if (ref > 1) break; } - WOLFSSL_LEAVE("WOLFCRYPT_BIO_free_all", 1); + WOLFSSL_LEAVE("wc_BioFreeAll", 1); } -unsigned long WOLFCRYPT_BIO_number_read(WOLFCRYPT_BIO *bio) +unsigned long wc_BioNumberRead(WOLFCRYPT_BIO *bio) { - WOLFSSL_ENTER("BIO_number_read"); + WOLFSSL_ENTER("wc_BioNumberRead"); if (bio == NULL) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_number_read", 0); + WOLFSSL_LEAVE("wc_BioNumberRead", 0); return 0; } - WOLFSSL_LEAVE("BIO_number_read", (int)bio->num_read); + WOLFSSL_LEAVE("wc_BioNumberRead", (int)bio->num_read); return bio->num_read; } -unsigned long WOLFCRYPT_BIO_number_written(WOLFCRYPT_BIO *bio) +unsigned long wc_BioNumberWritten(WOLFCRYPT_BIO *bio) { - WOLFSSL_ENTER("BIO_number_written"); + WOLFSSL_ENTER("wc_BioNumberWritten"); if (bio == NULL) { WOLFSSL_ERROR(BAD_FUNC_ARG); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_number_written", 0); + WOLFSSL_LEAVE("wc_BioNumberWritten", 0); return 0; } - WOLFSSL_LEAVE("BIO_number_written", (int)bio->num_write); + WOLFSSL_LEAVE("wc_BioNumberWritten", (int)bio->num_write); return bio->num_write; } __attribute__((format(printf, 2, 3))) -int WOLFCRYPT_BIO_printf(WOLFCRYPT_BIO *bio, const char *format, ...) +int wc_BioPrintf(WOLFCRYPT_BIO *bio, const char *format, ...) { int size, ret; va_list args, args2; @@ -770,24 +790,24 @@ int WOLFCRYPT_BIO_printf(WOLFCRYPT_BIO *bio, const char *format, ...) return -1; } - ret = WOLFCRYPT_BIO_write(bio, buffer, size); + ret = wc_BioWrite(bio, buffer, size); XFREE(buffer, 0, DYNAMIC_TYPE_OPENSSL); return ret; } -void WOLFCRYPT_BIO_copy_next_retry(WOLFCRYPT_BIO *bio) +void wc_BioCopyNextRetry(WOLFCRYPT_BIO *bio) { - WOLFCRYPT_BIO_set_flags(bio, WOLFCRYPT_BIO_get_retry_flags(bio->next_bio)); + wc_BioSetFlags(bio, wc_BioGetRetryFlags(bio->next_bio)); bio->retry_reason = bio->next_bio->retry_reason; } -WOLFCRYPT_BIO *WOLFCRYPT_BIO_dup_chain(WOLFCRYPT_BIO *in) +WOLFCRYPT_BIO *wc_BioDupChain(WOLFCRYPT_BIO *in) { WOLFCRYPT_BIO *ret = NULL, *eoc = NULL, *bio, *new_bio; for (bio = in; bio != NULL; bio = bio->next_bio) { - new_bio = WOLFCRYPT_BIO_new(bio->method); + new_bio = wc_BioNew(bio->method); if (new_bio == NULL) { goto err; } @@ -798,8 +818,8 @@ WOLFCRYPT_BIO *WOLFCRYPT_BIO_dup_chain(WOLFCRYPT_BIO *in) new_bio->flags = bio->flags; new_bio->num = bio->num; - if (!WOLFCRYPT_BIO_dup_state(bio, new_bio)) { - WOLFCRYPT_BIO_free(new_bio); + if (!wc_BioDupState(bio, new_bio)) { + wc_BioFree(new_bio); goto err; } @@ -807,7 +827,7 @@ WOLFCRYPT_BIO *WOLFCRYPT_BIO_dup_chain(WOLFCRYPT_BIO *in) eoc = new_bio; ret = eoc; } else { - WOLFCRYPT_BIO_push(eoc, new_bio); + wc_BioPush(eoc, new_bio); eoc = new_bio; } } @@ -815,9 +835,5311 @@ WOLFCRYPT_BIO *WOLFCRYPT_BIO_dup_chain(WOLFCRYPT_BIO *in) return ret; err: - WOLFCRYPT_BIO_free_all(ret); + wc_BioFreeAll(ret); return NULL; } +/* start BIO Filter base64 */ + +static int wc_BioB64_write(WOLFCRYPT_BIO *bio, const char *buf, int size); +static int wc_BioB64_read(WOLFCRYPT_BIO *bio, char *buf, int size); +static int wc_BioB64_puts(WOLFCRYPT_BIO *bio, const char *str); +static long wc_BioB64_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr); +static int wc_BioB64_new(WOLFCRYPT_BIO *bio); +static int wc_BioB64_free(WOLFCRYPT_BIO *bio); +static long wc_BioB64_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, + WOLFCRYPT_BIO_info_cb *fp); + +#define WOLFCRYPT_B64_BLOCK_SIZE 20*48 +#define WOLFCRYPT_B64_ENCODE_SIZE 20*64 + 40 // 40 : 20 CR LF +#define WOLFCRYPT_B64_NONE 0 +#define WOLFCRYPT_B64_ENCODE 1 +#define WOLFCRYPT_B64_DECODE 2 + + +typedef struct { + int dataLen; /* data length */ + int dataIdx; /* data index */ + int workLen; /* working buffer length */ + int workNl; /* used to stop when find a '\n' */ + int encode; /* base64 operation */ + int start; /* decoding started */ + int cont; /* <= 0 when finished */ + + char data[WOLFCRYPT_B64_ENCODE_SIZE]; + char work[WOLFCRYPT_B64_BLOCK_SIZE]; +} WOLFCRYPT_BIO_F_B64_CTX; + +static WOLFCRYPT_BIO_METHOD wc_BioB64_method = { + BIO_TYPE_BASE64, + "Base64", + wc_BioB64_write, + wc_BioB64_read, + wc_BioB64_puts, + NULL, /* gets */ + wc_BioB64_ctrl, + wc_BioB64_new, + wc_BioB64_free, + wc_BioB64_callback_ctrl, +}; + + +WOLFCRYPT_BIO_METHOD *wc_Bio_f_base64(void) +{ + return (&wc_BioB64_method); +} + +static int wc_BioB64_new(WOLFCRYPT_BIO *bio) +{ + WOLFCRYPT_BIO_F_B64_CTX *ctx; + + WOLFSSL_ENTER("wc_BioB64_new"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + bio->ptr = (WOLFCRYPT_BIO_F_B64_CTX *) + XMALLOC(sizeof(WOLFCRYPT_BIO_F_B64_CTX), + 0, DYNAMIC_TYPE_OPENSSL); + if (bio->ptr == NULL) { + WOLFSSL_ERROR(MEMORY_E); + return 0; + } + + ctx = (WOLFCRYPT_BIO_F_B64_CTX *)bio->ptr; + + ctx->dataLen = 0; + ctx->workLen = 0; + ctx->workNl = 0; + ctx->dataIdx = 0; + ctx->cont = 1; + ctx->start = 1; + ctx->encode = 0; + + bio->init = 1; + bio->flags = 0; + bio->num = 0; + + WOLFSSL_LEAVE("wc_BioB64_new", 1); + return 1; +} + +static int wc_BioB64_free(WOLFCRYPT_BIO *bio) +{ + WOLFSSL_ENTER("wc_BioB64_free"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + if (bio->ptr != NULL) { + XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); + bio->ptr = NULL; + } + + bio->init = 0; + bio->flags = 0; + + WOLFSSL_LEAVE("wc_BioB64_free", 1); + + return 1; +} + + +static int wc_BioB64_read(WOLFCRYPT_BIO *bio, char *data, int size) +{ + int ret = 0, idx, bread, j, k, num, ret_code = 0; + WOLFCRYPT_BIO_F_B64_CTX *ctx; + + WOLFSSL_ENTER("wc_BioB64_read"); + + if (bio == NULL || !bio->init || bio->ptr == NULL || + bio->next_bio == NULL || data == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + wc_BioClearRetryFlags(bio); + + ctx = (WOLFCRYPT_BIO_F_B64_CTX *)bio->ptr; + + /* decode when reading */ + if (ctx->encode != WOLFCRYPT_B64_DECODE) { + ctx->encode = WOLFCRYPT_B64_DECODE; + ctx->dataLen = 0; + ctx->dataIdx = 0; + ctx->workLen = 0; + } + + /* First check if there are bytes decoded/encoded */ + if (ctx->dataLen > 0) { + if (ctx->dataLen < ctx->dataIdx) { + WOLFSSL_LEAVE("wc_BioB64_read", -1); + return -1; + } + + bread = ctx->dataLen - ctx->dataIdx; + if (bread > size) + bread = size; + + if (ctx->dataIdx + bread >= (int)sizeof(ctx->data)) { + WOLFSSL_LEAVE("wc_BioB64_read", -1); + return -1; + } + + XMEMCPY(data, &(ctx->data[ctx->dataIdx]), bread); + + ret = bread; + data += bread; + size -= bread; + ctx->dataIdx += bread; + + if (ctx->dataLen == ctx->dataIdx) { + ctx->dataLen = 0; + ctx->dataIdx = 0; + } + } + + /* + * At this point, we have room of size bytes and an empty buffer, so we + * should read in some more. + */ + + ret_code = 0; + idx = 0; + + while (size > 0) { + if (ctx->cont <= 0) + break; + + bread = wc_BioRead(bio->next_bio, &ctx->work[ctx->workLen], + sizeof(ctx->work) - ctx->workLen); + + if (bread <= 0) { + ret_code = bread; + + /* Should we continue next time we are called? */ + if (!wc_BioShouldRetry(bio->next_bio)) { + ctx->cont = bread; + /* If buffer empty break */ + if (!ctx->workLen) + break; + else + bread = 0; + } + /* else we retry and add more data to buffer */ + else + break; + } + + bread += ctx->workLen; + ctx->workLen = bread; + + /* + * We need to scan, a line at a time until we have a valid line if we + * are starting. + */ + if (ctx->start && (wc_BioGetFlags(bio) & BIO_FLAGS_BASE64_NO_NL)) + ctx->workLen = 0; + else if (ctx->start) { + /* search \n */ + ctx->workNl = -1; + + /* parse working buffer to find line endings */ + for (j = 0; j < bread; j++) { + + /* no end of line, continue */ + if (ctx->work[j] != '\n') + continue; + + /* we found an end of line, keep the position to + * decode the line */ + ctx->workNl = j; + + /* decode the line found */ + num = sizeof(ctx->data) - ctx->dataIdx; + + k = Base64_Decode((const byte*)ctx->work+idx,ctx->workNl-idx, + (byte *)ctx->data+ctx->dataIdx, (word32 *)&num); + if (k < 0 && !num && ctx->start) { + WOLFSSL_ERROR(BIO_B64_DECODE_E); + return -1; + } + else + ctx->start = 0; + + /* +1 => skeep \n */ + idx = (ctx->workNl + 1); + + ctx->dataLen += num; + ctx->dataIdx += num; + } + } else if ((bread < WOLFCRYPT_B64_BLOCK_SIZE) && (ctx->cont > 0)) { + /* + * If buffer isn't full and we can retry then restart to read in + * more data. + */ + continue; + } + + if (wc_BioGetFlags(bio) & BIO_FLAGS_BASE64_NO_NL) { + int z, jj; + + jj = bread & ~3; + + z = sizeof(ctx->data); + k = Base64_Decode((const byte*)ctx->work, jj, + (byte *)ctx->data, (word32 *)&z); + if (k < 0 || !z) { + WOLFSSL_ERROR(BIO_B64_DECODE_E); + return -1; + } + + /* z is now number of output bytes and jj is the number consumed + */ + if (jj != bread) { + ctx->workLen = bread - jj; + XMEMMOVE(ctx->work, &ctx->work[jj], ctx->workLen); + } + + if (z > 0) + ctx->dataLen = z; + else + ctx->dataLen = 0; + + bread = z; + } + + ctx->dataIdx = 0; + if (bread < 0) { + ret_code = 0; + ctx->dataLen = 0; + break; + } + + if (!(wc_BioGetFlags(bio) & BIO_FLAGS_BASE64_NO_NL)) { + /* keep no parsed data in working buffer */ + XMEMMOVE(ctx->work, ctx->work+idx, ctx->workLen-idx); + ctx->workLen -= idx; + idx = 0; + ctx->start = 1; + } + + bread = (ctx->dataLen <= size ? ctx->dataLen : size); + + XMEMCPY(data, ctx->data, bread); + ret += bread; + + if (bread == ctx->dataLen) { + ctx->dataLen = 0; + ctx->dataIdx = 0; + } + else + ctx->dataIdx = bread; + + size -= bread; + data += bread; + } + + wc_BioCopyNextRetry(bio); + + WOLFSSL_LEAVE("wc_BioB64_read", (!ret ? ret_code : ret)); + + return (!ret ? ret_code : ret); +} + +static int wc_BioB64_write(WOLFCRYPT_BIO *bio, const char *data, int size) +{ + int ret = 0; + int n; + int i; + WOLFCRYPT_BIO_F_B64_CTX *ctx; + + WOLFSSL_ENTER("wc_BioB64_write"); + + if (bio == NULL || !bio->init || bio->ptr == NULL || + bio->next_bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + wc_BioClearRetryFlags(bio); + + ctx = (WOLFCRYPT_BIO_F_B64_CTX *)bio->ptr; + + /* encode when writing */ + if (ctx->encode != WOLFCRYPT_B64_ENCODE) { + ctx->encode = WOLFCRYPT_B64_ENCODE; + ctx->dataLen = 0; + ctx->dataIdx = 0; + ctx->workLen = 0; + } + + if (ctx->dataIdx >= (int)sizeof(ctx->data) || + ctx->dataLen > (int)sizeof(ctx->data) || + ctx->dataLen < ctx->dataIdx) { + WOLFSSL_LEAVE("wc_BioB64_write", -1); + return -1; + } + + n = ctx->dataLen - ctx->dataIdx; + while (n > 0) { + i = wc_BioWrite(bio->next_bio, &ctx->data[ctx->dataIdx], n); + if (i <= 0) { + wc_BioCopyNextRetry(bio); + return i; + } + + /* mustn't appen, just to be sure */ + if (i > n) { + WOLFSSL_LEAVE("wc_BioB64_write", -1); + return -1; + } + + ctx->dataIdx += i; + n -= i; + + if (ctx->dataIdx > (int)sizeof(ctx->data) || + ctx->dataLen < ctx->dataIdx) { + WOLFSSL_LEAVE("wc_BioB64_write", -1); + return -1; + } + } + + /* at this point all pending data has been written */ + ctx->dataIdx = 0; + ctx->dataLen = 0; + + if (data == NULL || size <= 0) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + while (size > 0) { + n = (size > WOLFCRYPT_B64_BLOCK_SIZE) ? WOLFCRYPT_B64_BLOCK_SIZE : size; + + if (ctx->workLen > 0) { + if (ctx->workLen > WOLFCRYPT_B64_BLOCK_SIZE) { + WOLFSSL_LEAVE("wc_BioB64_write", -1); + return -1; + } + + n = WOLFCRYPT_B64_BLOCK_SIZE - ctx->workLen; + + if (n > size) + n = size; + + XMEMCPY(&ctx->work[ctx->workLen], data, n); + ctx->workLen += n; + ret += n; + if (ctx->workLen < WOLFCRYPT_B64_BLOCK_SIZE) + break; + + ctx->dataLen = sizeof(ctx->data); + + if (wc_BioGetFlags(bio) & BIO_FLAGS_BASE64_NO_NL) + Base64_Encode_NoNl((const byte *)ctx->work, ctx->workLen, + (byte *)ctx->data, + (word32 *)&ctx->dataLen); + else + Base64_Encode((const byte *)ctx->work, ctx->workLen, + (byte *)ctx->data, (word32 *)&ctx->dataLen); + + if (ctx->dataLen > (int)sizeof(ctx->data) || + ctx->dataLen < ctx->dataIdx) { + WOLFSSL_LEAVE("wc_BioB64_write", -1); + return -1; + } + + ctx->workLen = 0; + } + else { + /* keep data and wait for more before encoding */ + if (n < WOLFCRYPT_B64_BLOCK_SIZE) { + XMEMCPY(ctx->work, data, n); + ctx->workLen = n; + ret += n; + break; + } + n -= n % WOLFCRYPT_B64_BLOCK_SIZE; + + ctx->dataLen = sizeof(ctx->data); + + if (wc_BioGetFlags(bio) & BIO_FLAGS_BASE64_NO_NL) + Base64_Encode_NoNl((const byte *)data, n, + (byte *)ctx->data, + (word32 *)&ctx->dataLen); + else + Base64_Encode((const byte *)data, n, + (byte *)ctx->data, (word32 *)&ctx->dataLen); + + if (ctx->dataLen > (int)sizeof(ctx->data) || + ctx->dataLen < ctx->dataIdx) { + WOLFSSL_LEAVE("wc_BioB64_write", -1); + return -1; + } + + ret += n; + } + + size -= n; + data += n; + + ctx->dataIdx = 0; + n = ctx->dataLen; + while (n > 0) { + i = wc_BioWrite(bio->next_bio, &(ctx->data[ctx->dataIdx]), n); + if (i <= 0) { + wc_BioCopyNextRetry(bio); + WOLFSSL_LEAVE("wc_BioB64_write", !ret ? i : ret); + return (!ret ? i : ret); + } + + if (i > n) { + WOLFSSL_LEAVE("wc_BioB64_write", -1); + return -1; + } + + n -= i; + ctx->dataIdx += i; + + if (ctx->dataLen > (int)sizeof(ctx->data) || + ctx->dataLen < ctx->dataIdx) { + WOLFSSL_LEAVE("wc_BioB64_write", -1); + return -1; + } + } + + ctx->dataLen = 0; + ctx->dataIdx = 0; + } + + WOLFSSL_LEAVE("wc_BioB64_write", ret); + + return ret; +} + +static long wc_BioB64_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) +{ + WOLFCRYPT_BIO_F_B64_CTX *ctx; + long ret = 1; + int i; + + WOLFSSL_ENTER("wc_BioB64_ctrl"); + + if (bio == NULL || bio->ptr == NULL || bio->next_bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + ctx = (WOLFCRYPT_BIO_F_B64_CTX *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->cont = 1; + ctx->start = 1; + ctx->encode = WOLFCRYPT_B64_NONE; + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + + case BIO_CTRL_EOF: + ret = (ctx->cont <= 0 ? 1 : + wc_BioCtrl(bio->next_bio, cmd, num, ptr)); + break; + + case BIO_CTRL_WPENDING: + if (ctx->dataLen < ctx->dataIdx) { + WOLFSSL_LEAVE("wc_BioB64_write", -1); + return -1; + } + + ret = ctx->dataLen - ctx->dataIdx; + if (!ret && (ctx->encode != WOLFCRYPT_B64_NONE) && + (ctx->workLen != 0)) + ret = 1; + else if (ret <= 0) + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + + case BIO_CTRL_PENDING: + if (ctx->dataLen < ctx->dataIdx) { + WOLFSSL_LEAVE("wc_BioB64_write", -1); + return -1; + } + + ret = ctx->dataLen - ctx->dataIdx; + if (ret <= 0) + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + + case BIO_CTRL_FLUSH: + /* do a final write */ + again: + while (ctx->dataLen != ctx->dataIdx) { + i = wc_BioB64_write(bio, NULL, 0); + if (i < 0) + return i; + } + + if (ctx->workLen != 0) { + ctx->dataLen = sizeof(ctx->data); + + if (wc_BioGetFlags(bio) & BIO_FLAGS_BASE64_NO_NL) + Base64_Encode_NoNl((const byte *)ctx->work, ctx->workLen, + (byte *)ctx->data, + (word32 *)&ctx->dataLen); + else { + Base64_Encode((const byte *)ctx->work, ctx->workLen, + (byte *)ctx->data, (word32 *)&ctx->dataLen); + + if (ctx->dataLen > (int)sizeof(ctx->data)) { + WOLFSSL_LEAVE("wc_BioB64_write", -1); + return -1; + } + } + + ctx->dataIdx = 0; + ctx->workLen = 0; + + goto again; + } + + /* Finally flush the underlying BIO */ + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + + case BIO_C_DO_STATE_MACHINE: + wc_BioClearRetryFlags(bio); + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + wc_BioCopyNextRetry(bio); + break; + + case BIO_CTRL_DUP: + break; + + case BIO_CTRL_INFO: + case BIO_CTRL_GET: + case BIO_CTRL_SET: + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + + default: + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + } + + WOLFSSL_LEAVE("wc_BioB64_ctrl", (int)ret); + return ret; +} + +static long wc_BioB64_callback_ctrl(WOLFCRYPT_BIO *bio, + int cmd, WOLFCRYPT_BIO_info_cb *fp) +{ + if (bio == NULL || bio->next_bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + WOLFSSL_ENTER("wc_BioB64_callback_ctrl"); + + return wc_BioCallbackCtrl(bio->next_bio, cmd, fp); +} + +static int wc_BioB64_puts(WOLFCRYPT_BIO *bio, const char *str) +{ + WOLFSSL_ENTER("wc_BioB64_puts"); + + if (bio == NULL || str == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + return wc_BioB64_write(bio, str, (int)strlen(str)); +} + +/* end BIO Filter base64 */ + +/* start BIO Filter buffer */ + +typedef struct { + /*- + * Buffers are setup like this: + * + * <---------------------- size -----------------------> + * +---------------------------------------------------+ + * | consumed | remaining | free space | + * +---------------------------------------------------+ + * <-- off --><------- len -------> + */ + + /* input buffer */ + char *in; /* the char array */ + int inSz; /* how big is the input buffer */ + int inLen; /* how many bytes are in it */ + int inIdx; /* write/read offset */ + + /* output buffer */ + char *out; /* the char array */ + int outSz; /* how big is the output buffer */ + int outLen; /* how many bytes are in it */ + int outIdx; /* write/read offset */ + +} WOLFCRYPT_BIO_F_BUFFER_CTX; + +/* OpenSSL default value */ +#define WOLFSSL_F_BUFFER_SIZE_DEFAULT 4096 + +static int wc_BioBuffer_write(WOLFCRYPT_BIO *bio, const char *buf, int size); +static int wc_BioBuffer_read(WOLFCRYPT_BIO *bio, char *buf, int size); +static int wc_BioBuffer_puts(WOLFCRYPT_BIO *bio, const char *str); +static int wc_BioBuffer_gets(WOLFCRYPT_BIO *bio, char *buf, int size); +static long wc_BioBuffer_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr); +static int wc_BioBuffer_new(WOLFCRYPT_BIO *bio); +static int wc_BioBuffer_free(WOLFCRYPT_BIO *bio); +static long wc_BioBuffer_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, + WOLFCRYPT_BIO_info_cb *fp); + +static WOLFCRYPT_BIO_METHOD wc_BioBuffer_method = { + BIO_TYPE_BUFFER, + "Buffer", + wc_BioBuffer_write, + wc_BioBuffer_read, + wc_BioBuffer_puts, + wc_BioBuffer_gets, + wc_BioBuffer_ctrl, + wc_BioBuffer_new, + wc_BioBuffer_free, + wc_BioBuffer_callback_ctrl, +}; + + +static long wc_BioBuffer_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, + WOLFCRYPT_BIO_info_cb *fp) +{ + if (bio == NULL || bio->next_bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + return wc_BioCallbackCtrl(bio->next_bio, cmd, fp); +} + +WOLFCRYPT_BIO_METHOD *wc_Bio_f_buffer(void) +{ + return (&wc_BioBuffer_method); +} + +static int wc_BioBuffer_new(WOLFCRYPT_BIO *bio) +{ + WOLFCRYPT_BIO_F_BUFFER_CTX *ctx; + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + bio->ptr = (WOLFCRYPT_BIO_F_BUFFER_CTX *) + XMALLOC(sizeof(WOLFCRYPT_BIO_F_BUFFER_CTX), + 0, DYNAMIC_TYPE_OPENSSL); + if (bio->ptr == NULL) { + WOLFSSL_ERROR(MEMORY_E); + return 0; + } + + ctx = (WOLFCRYPT_BIO_F_BUFFER_CTX *)bio->ptr; + + ctx->in = (char *)XMALLOC(WOLFSSL_F_BUFFER_SIZE_DEFAULT, 0, + DYNAMIC_TYPE_OPENSSL); + if (ctx->in == NULL) { + XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); + WOLFSSL_ERROR(MEMORY_E); + return 0; + } + + ctx->out = (char *)XMALLOC(WOLFSSL_F_BUFFER_SIZE_DEFAULT, 0, + DYNAMIC_TYPE_OPENSSL); + if (ctx->out == NULL) { + XFREE(ctx->in, 0, DYNAMIC_TYPE_OPENSSL); + XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); + WOLFSSL_ERROR(MEMORY_E); + return 0; + } + + ctx->inSz = WOLFSSL_F_BUFFER_SIZE_DEFAULT; + ctx->inLen = 0; + ctx->inIdx = 0; + ctx->outSz = WOLFSSL_F_BUFFER_SIZE_DEFAULT; + ctx->outLen = 0; + ctx->outIdx = 0; + + bio->init = 1; + bio->flags = 0; + return 1; +} + +static int wc_BioBuffer_free(WOLFCRYPT_BIO *bio) +{ + WOLFCRYPT_BIO_F_BUFFER_CTX *ctx; + + WOLFSSL_ENTER("wc_BioBuffer_free"); + + if (bio == NULL) + return 0; + + if (!bio->init || bio->ptr == NULL) + return 1; + + ctx = (WOLFCRYPT_BIO_F_BUFFER_CTX *)bio->ptr; + + if (ctx->in != NULL) { + XFREE(ctx->in, 0, DYNAMIC_TYPE_OPENSSL); + ctx->in = NULL; + } + + if (ctx->out != NULL) { + XFREE(ctx->out, 0, DYNAMIC_TYPE_OPENSSL); + ctx->out = NULL; + } + + XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); + bio->ptr = NULL; + + bio->init = 0; + bio->flags = 0; + return 1; +} + +static int wc_BioBuffer_read(WOLFCRYPT_BIO *bio, char *data, int size) +{ + int i, num = 0; + WOLFCRYPT_BIO_F_BUFFER_CTX *ctx; + + if (bio == NULL || !bio->init || + bio->ptr == NULL || bio->next_bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + wc_BioClearRetryFlags(bio); + + ctx = (WOLFCRYPT_BIO_F_BUFFER_CTX *)bio->ptr; + + for (;;) { + i = ctx->inLen; + if (i != 0) { + if (i > size) + i = size; + XMEMCPY(data, &(ctx->in[ctx->inIdx]), i); + ctx->inIdx += i; + ctx->inLen -= i; + num += i; + if (size == i) + return num; + size -= i; + data += i; + } + + /* case of partial read */ + if (size > ctx->inSz) { + for (;;) { + i = wc_BioRead(bio->next_bio, data, size); + if (i <= 0) { + wc_BioCopyNextRetry(bio); + if (i < 0) + return (num > 0 ? num : i); + else if (i == 0) + return num; + } + num += i; + + if (size == i) + return num; + data += i; + size -= i; + } + } + + /* we are going to be doing some buffering */ + i = wc_BioRead(bio->next_bio, ctx->in, ctx->inSz); + if (i <= 0) { + wc_BioCopyNextRetry(bio); + if (i < 0) + return (num > 0 ? num : i); + if (i == 0) + return num; + } + ctx->inIdx = 0; + ctx->inLen = i; + } + + return 1; +} + +static int wc_BioBuffer_write(WOLFCRYPT_BIO *bio, + const char *data, int size) +{ + int i, num = 0; + WOLFCRYPT_BIO_F_BUFFER_CTX *ctx; + + if (bio == NULL || !bio->init || bio->ptr == NULL || + bio->next_bio == NULL || size <= 0) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + wc_BioClearRetryFlags(bio); + + ctx = (WOLFCRYPT_BIO_F_BUFFER_CTX *)bio->ptr; + + for (;;) { + i = ctx->outSz - (ctx->outLen + ctx->outIdx); + + /* add to buffer and return */ + if (i >= size) { + XMEMCPY(&(ctx->out[ctx->outIdx + ctx->outLen]), data, size); + ctx->outLen += size; + return (num + size); + } + + /* stuff already in buffer, so add to it first, then flush */ + if (ctx->outLen != 0) { + if (i > 0) { + XMEMCPY(&(ctx->out[ctx->outIdx + ctx->outLen]), data, i); + data += i; + size -= i; + num += i; + ctx->outLen += i; + } + + /* we now have a full buffer needing flushing */ + do { + i = wc_BioWrite(bio->next_bio, + &(ctx->out[ctx->outIdx]), ctx->outLen); + if (i <= 0) { + wc_BioCopyNextRetry(bio); + + if (i < 0) + return (num > 0 ? num : i); + if (i == 0) + return num; + } + + ctx->outIdx += i; + ctx->outLen -= i; + + } while (ctx->outLen != 0); + } + + ctx->outIdx = 0; + + /* we now have size bytes to write */ + while (size >= ctx->outSz) { + i = wc_BioWrite(bio->next_bio, data, size); + if (i <= 0) { + wc_BioCopyNextRetry(bio); + if (i < 0) + return (num > 0 ? num : i); + if (i == 0) + return num; + } + num += i; + data += i; + size -= i; + if (size == 0) + return num; + } + } + + return 1; +} + +static long wc_BioBuffer_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) +{ + + int i, *ip, ibs, obs; + long ret = 1; + WOLFCRYPT_BIO_F_BUFFER_CTX *ctx; + + if (bio == NULL || bio->ptr == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + ctx = (WOLFCRYPT_BIO_F_BUFFER_CTX *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->inLen = 0; + ctx->inIdx = 0; + ctx->outLen = 0; + ctx->outIdx = 0; + + if (bio->next_bio == NULL) + return 0; + + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + + case BIO_CTRL_INFO: + ret = (long)ctx->outLen; + break; + + case BIO_C_GET_BUFF_NUM_LINES: + ret = 0; + for (i = 0; i < ctx->inLen; i++) { + if (ctx->in[ctx->inIdx + i] == '\n') + ret++; + } + break; + + case BIO_CTRL_WPENDING: + ret = (long)ctx->outLen; + if (ret == 0) { + if (bio->next_bio == NULL) + return 0; + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + } + break; + + case BIO_CTRL_PENDING: + ret = (long)ctx->inLen; + if (ret == 0) { + if (bio->next_bio == NULL) + return 0; + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + } + break; + + case BIO_C_SET_BUFF_READ_DATA: + if (num > ctx->inSz) { + ctx->in = XREALLOC(ctx->in, num, 0, DYNAMIC_TYPE_OPENSSL); + if (ctx->in == NULL) { + WOLFSSL_ERROR(MEMORY_E); + return 0; + } + } + + ctx->inIdx = 0; + ctx->inLen = (int)num; + XMEMCPY(ctx->in, ptr, num); + ret = 1; + break; + + case BIO_C_SET_BUFF_SIZE: + if (ptr != NULL) { + ip = (int *)ptr; + if (*ip == 0) { + ibs = (int)num; + obs = ctx->outSz; + } else { + ibs = ctx->inSz; + obs = (int)num; + } + } else { + ibs = (int)num; + obs = (int)num; + } + + if ((ibs > WOLFSSL_F_BUFFER_SIZE_DEFAULT) && (ibs != ctx->inSz)) { + ctx->in = XREALLOC(ctx->in, num, 0, DYNAMIC_TYPE_OPENSSL); + if (ctx->in == NULL) { + WOLFSSL_ERROR(MEMORY_E); + return 0; + } + + ctx->inIdx = 0; + ctx->inLen = 0; + ctx->inSz = ibs; + } + + if ((obs > WOLFSSL_F_BUFFER_SIZE_DEFAULT) && (obs != ctx->outSz)) { + ctx->out = XREALLOC(ctx->out, num, 0, DYNAMIC_TYPE_OPENSSL); + if (ctx->out == NULL) { + WOLFSSL_ERROR(MEMORY_E); + return 0; + } + + ctx->outIdx = 0; + ctx->outLen = 0; + ctx->outSz = obs; + } + break; + + case BIO_C_DO_STATE_MACHINE: + if (bio->next_bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + wc_BioClearRetryFlags(bio); + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + wc_BioCopyNextRetry(bio); + break; + + case BIO_CTRL_FLUSH: + if (bio->next_bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + if (ctx->outLen <= 0) { + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + } + + for (;;) { + wc_BioClearRetryFlags(bio); + if (ctx->outLen > 0) { + ret = wc_BioWrite(bio->next_bio, + &(ctx->out[ctx->outIdx]), ctx->outLen); + wc_BioCopyNextRetry(bio); + if (ret <= 0) + return ret; + ctx->outIdx += ret; + ctx->outLen -= ret; + } else { + ctx->outLen = 0; + ctx->outIdx = 0; + ret = 1; + break; + } + } + + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + + case BIO_CTRL_DUP: + ret = wc_BioSetReadBufferSize((WOLFCRYPT_BIO *)ptr, ctx->inSz); + if (!ret) + break; + + ret = wc_BioSetWriteBufferSize((WOLFCRYPT_BIO *)ptr, ctx->outSz); + if (!ret) + break; + + ret = 1; + break; + + default: + if (bio->next_bio == NULL) + return 0; + + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + } + + return ret; +} + +static int wc_BioBuffer_gets(WOLFCRYPT_BIO *bio, char *buf, int size) +{ + WOLFCRYPT_BIO_F_BUFFER_CTX *ctx; + int num = 0, i, flag; + + if (bio == NULL || bio->ptr == NULL || buf == NULL || size <= 0) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + wc_BioClearRetryFlags(bio); + + ctx = (WOLFCRYPT_BIO_F_BUFFER_CTX *)bio->ptr; + + /* to put end of string */ + size--; + + for (;;) { + if (ctx->inLen > 0) { + // p = &(ctx->in[ctx->inIdx]); + flag = 0; + + for (i = 0; (i < ctx->inLen) && (i < size); i++) { + *(buf++) = ctx->in[ctx->inIdx+i]; + if (ctx->in[ctx->inIdx+i] == '\n') { + flag = 1; + i++; + break; + } + } + num += i; + size -= i; + ctx->inLen -= i; + ctx->inIdx += i; + if (flag || !size) { + *buf = '\0'; + return num; + } + } else { + i = wc_BioRead(bio->next_bio, ctx->in, ctx->inSz); + if (i <= 0) { + wc_BioCopyNextRetry(bio); + *buf = '\0'; + if (i < 0) + return (num > 0 ? num : i); + if (i == 0) + return num; + } + ctx->inLen = i; + ctx->inIdx = 0; + } + } + + return i; +} + +static int wc_BioBuffer_puts(WOLFCRYPT_BIO *bio, const char *str) +{ + if (bio == NULL || str == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + return wc_BioBuffer_write(bio, str, (int)strlen(str)); +} + +/* end BIO Filter buffer */ + +/* start BIO Filter cipher */ + +typedef struct { + int dataLen; + int dataIdx; + int cont; + int finished; + int ok; /* bad decrypt */ + + WOLFCRYPT_EVP_CIPHER_CTX cipher; + /* + * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return + * up to a block more data than is presented to it + */ + +#define WOLFCRYPT_ENC_BLOCK_SIZE 128 +#define WOLFCRYPT_BUF_OFFSET 64 + + byte data[WOLFCRYPT_ENC_BLOCK_SIZE + WOLFCRYPT_BUF_OFFSET + 2]; +} WOLFCRYPT_BIO_ENC_CTX; + + +static int wc_BioCipher_write(WOLFCRYPT_BIO *bio, const char *buf, int size); +static int wc_BioCipher_read(WOLFCRYPT_BIO *bio, char *buf, int size); +static long wc_BioCipher_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr); +static int wc_BioCipher_new(WOLFCRYPT_BIO *bio); +static int wc_BioCipher_free(WOLFCRYPT_BIO *bio); +static long wc_BioCipher_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, + WOLFCRYPT_BIO_info_cb *fp); + +static WOLFCRYPT_BIO_METHOD wc_BioCipher_method = { + BIO_TYPE_CIPHER, + "Cipher", + wc_BioCipher_write, + wc_BioCipher_read, + NULL, /* puts */ + NULL, /* gets */ + wc_BioCipher_ctrl, + wc_BioCipher_new, + wc_BioCipher_free, + wc_BioCipher_callback_ctrl, +}; + +static long wc_BioCipher_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, + WOLFCRYPT_BIO_info_cb *fp) +{ + WOLFSSL_ENTER("wc_BioCipher_callback_ctrl"); + if (bio == NULL || bio->next_bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + return wc_BioCallbackCtrl(bio->next_bio, cmd, fp); +} + +WOLFCRYPT_BIO_METHOD *wc_Bio_f_cipher(void) +{ + WOLFSSL_ENTER("WOLFCRYPT_BIO_f_cipher"); + return (&wc_BioCipher_method); +} + +void wc_BioSetCipher(WOLFCRYPT_BIO *bio, const WOLFCRYPT_EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc) +{ + WOLFCRYPT_BIO_ENC_CTX *ctx; + + WOLFSSL_ENTER("wc_BioSetCipher"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return; + } + + + if ((bio->callback != NULL) && + bio->callback(bio, BIO_CB_CTRL, (const char *)cipher, + BIO_CTRL_SET, enc, 0) <= 0) { + WOLFSSL_ERROR(BIO_CALLBACK_E); + return; + } + + bio->init = 1; + + ctx = (WOLFCRYPT_BIO_ENC_CTX *)bio->ptr; + + wc_EVP_CipherInit(&(ctx->cipher), cipher, (unsigned char *)key, + (unsigned char *)iv, enc); + + if ((bio->callback != NULL) && + bio->callback(bio, BIO_CB_CTRL, (const char *)cipher, + BIO_CTRL_SET, enc, 1) <= 0) + WOLFSSL_ERROR(BIO_CALLBACK_E); +} + +static int wc_BioCipher_new(WOLFCRYPT_BIO *bio) +{ + WOLFCRYPT_BIO_ENC_CTX *ctx; + + WOLFSSL_ENTER("wc_BioCipher_new"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + bio->ptr = (WOLFCRYPT_BIO_ENC_CTX *)XMALLOC(sizeof(WOLFCRYPT_BIO_ENC_CTX), + 0, DYNAMIC_TYPE_OPENSSL); + if (bio->ptr == NULL) { + WOLFSSL_ERROR(MEMORY_E); + return -1; + } + + ctx = (WOLFCRYPT_BIO_ENC_CTX *)bio->ptr; + + wc_EVP_CIPHER_CTX_init(&ctx->cipher); + + ctx->dataLen = 0; + ctx->dataIdx = 0; + ctx->cont = 1; + ctx->finished = 0; + ctx->ok = 1; + + bio->init = 0; + bio->flags = 0; + + WOLFSSL_LEAVE("wc_BioCipher_new", 1); + return 1; +} + +static int wc_BioCipher_free(WOLFCRYPT_BIO *bio) +{ + WOLFCRYPT_BIO_ENC_CTX *ctx; + + WOLFSSL_ENTER("wc_BioCipher_free"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + ctx = (WOLFCRYPT_BIO_ENC_CTX *)bio->ptr; + + wc_EVP_CIPHER_CTX_cleanup(&(ctx->cipher)); + + XMEMSET(bio->ptr, 0, sizeof(WOLFCRYPT_BIO_ENC_CTX)); + XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); + bio->ptr = NULL; + + bio->init = 0; + bio->flags = 0; + + WOLFSSL_LEAVE("wc_BioCipher_free", 1); + return 1; +} + +static int wc_BioCipher_read(WOLFCRYPT_BIO *bio, char *data, int size) +{ + int ret = 0, i; + WOLFCRYPT_BIO_ENC_CTX *ctx; + + WOLFSSL_ENTER("wc_BioCipher_read"); + + if (bio == NULL || data == NULL || + bio->ptr == NULL || bio->next_bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + ctx = (WOLFCRYPT_BIO_ENC_CTX *)bio->ptr; + + /* First check if there are bytes decoded/encoded */ + if (ctx->dataLen > 0) { + i = ctx->dataLen - ctx->dataIdx; + if (i > size) + i = size; + + XMEMCPY(data, &ctx->data[ctx->dataIdx], i); + ret = i; + data += i; + size -= i; + ctx->dataIdx += i; + + /* all read */ + if (ctx->dataLen == ctx->dataIdx) + ctx->dataLen = ctx->dataIdx = 0; + } + + /* + * At this point, we have room of size bytes and an empty buffer, so we + * should read in some more. + */ + while (size > 0) { + if (ctx->cont <= 0) + break; + + /* read in at IV offset, read the EVP_Cipher documentation about why + */ + i = wc_BioRead(bio->next_bio, &ctx->data[WOLFCRYPT_BUF_OFFSET], + WOLFCRYPT_ENC_BLOCK_SIZE); + if (i <= 0) { + /* Should be continue next time we are called ? */ + if (!wc_BioShouldRetry(bio->next_bio)) { + ctx->cont = i; + + i = wc_EVP_CipherFinal(&ctx->cipher, ctx->data, + &ctx->dataLen); + + ctx->ok = i; + ctx->dataIdx = 0; + } else { + if (!ret) + ret = i; + break; + } + } else { + wc_EVP_CipherUpdate(&ctx->cipher, + ctx->data, &ctx->dataLen, + &ctx->data[WOLFCRYPT_BUF_OFFSET], i); + ctx->cont = 1; + + if (!ctx->dataLen) + continue; + } + + i = (ctx->dataLen <= size ? ctx->dataLen : size); + if (i <= 0) + break; + + XMEMCPY(data, ctx->data, i); + + ret += i; + ctx->dataIdx = i; + size -= i; + data += i; + } + + wc_BioClearRetryFlags(bio); + wc_BioCopyNextRetry(bio); + + return (!ret ? ctx->cont : ret); +} + +static int wc_BioCipher_write(WOLFCRYPT_BIO *bio, + const char *data, int size) +{ + int ret, n, i; + WOLFCRYPT_BIO_ENC_CTX *ctx; + + WOLFSSL_ENTER("wc_BioCipher_write"); + + if (bio == NULL || bio->ptr == NULL || bio->next_bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + ctx = (WOLFCRYPT_BIO_ENC_CTX *)bio->ptr; + + ret = size; + + wc_BioClearRetryFlags(bio); + + n = ctx->dataLen - ctx->dataIdx; + while (n > 0) { + i = wc_BioWrite(bio->next_bio, &ctx->data[ctx->dataIdx], n); + if (i <= 0) { + wc_BioCopyNextRetry(bio); + return i; + } + ctx->dataIdx += i; + n -= i; + } + + /* at this point all pending data has been written + * return if we haven't new data to write */ + if (data == NULL || size <= 0) + return 0; + + while (size > 0) { + n = (size > WOLFCRYPT_ENC_BLOCK_SIZE ? WOLFCRYPT_ENC_BLOCK_SIZE : size); + wc_EVP_CipherUpdate(&ctx->cipher, ctx->data, &ctx->dataLen, + (byte *)data, n); + + size -= n; + data += n; + + ctx->dataIdx = 0; + n = ctx->dataLen; + while (n > 0) { + i = wc_BioWrite(bio->next_bio, &ctx->data[ctx->dataIdx], n); + if (i <= 0) { + wc_BioCopyNextRetry(bio); + return (ret == size ? i : ret - size); + } + n -= i; + ctx->dataIdx += i; + } + ctx->dataLen = 0; + ctx->dataIdx = 0; + } + + wc_BioCopyNextRetry(bio); + return ret; +} + +static long wc_BioCipher_ctrl(WOLFCRYPT_BIO *bio, int cmd, + long num, void *ptr) +{ + WOLFCRYPT_BIO_ENC_CTX *ctx; + long ret = 1; + int i; + + WOLFSSL_ENTER("wc_BioCipher_ctrl"); + + if (bio == NULL || bio->ptr == NULL || bio->next_bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + ctx = (WOLFCRYPT_BIO_ENC_CTX *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->ok = 1; + ctx->finished = 0; + wc_EVP_CipherInit(&ctx->cipher, NULL, NULL, NULL, + ctx->cipher.enc); + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + + case BIO_CTRL_EOF: /* More to read */ + if (ctx->cont <= 0) + ret = 1; + else + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + + case BIO_CTRL_WPENDING: + case BIO_CTRL_PENDING: + ret = ctx->dataLen - ctx->dataIdx; + if (ret <= 0) + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + + case BIO_CTRL_FLUSH: + loop: + while (ctx->dataLen != ctx->dataIdx) { + i = wc_BioCipher_write(bio, NULL, 0); + if (i < 0) + return i; + } + + if (!ctx->finished) { + ctx->finished = 1; + ctx->dataIdx = 0; + + ret = wc_EVP_CipherFinal(&ctx->cipher, ctx->data, + &ctx->dataLen); + ctx->ok = (int)ret; + if (ret <= 0) + break; + + goto loop; + } + + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + + case BIO_C_GET_CIPHER_STATUS: + ret = (long)ctx->ok; + break; + + case BIO_C_DO_STATE_MACHINE: + wc_BioClearRetryFlags(bio); + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + wc_BioCopyNextRetry(bio); + break; + + case BIO_C_GET_CIPHER_CTX: + { + WOLFCRYPT_EVP_CIPHER_CTX **c_ctx; + c_ctx = (WOLFCRYPT_EVP_CIPHER_CTX **)ptr; + *c_ctx = &ctx->cipher; + bio->init = 1; + } + break; + + case BIO_CTRL_DUP: + { + WOLFCRYPT_BIO *dbio; + WOLFCRYPT_BIO_ENC_CTX *dctx; + + dbio = (WOLFCRYPT_BIO *)ptr; + dctx = (WOLFCRYPT_BIO_ENC_CTX *)dbio->ptr; + + wc_EVP_CIPHER_CTX_init(&dctx->cipher); + ret = wc_EVP_CIPHER_CTX_copy(&dctx->cipher, &ctx->cipher); + if (ret) + dbio->init = 1; + } + break; + + default: + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + } + + WOLFSSL_LEAVE("wc_BioCipher_ctrl", (int)ret); + return ret; +} + +/* end BIO Filter cipher */ + +/* start BIO Filter digest */ + +static int wc_BioDigest_write(WOLFCRYPT_BIO *bio, const char *buf, int size); +static int wc_BioDigest_read(WOLFCRYPT_BIO *bio, char *buf, int size); +static int wc_BioDigest_gets(WOLFCRYPT_BIO *bio, char *buf, int size); +static long wc_BioDigest_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr); +static int wc_BioDigest_new(WOLFCRYPT_BIO *bio); +static int wc_BioDigest_free(WOLFCRYPT_BIO *bio); +static long wc_BioDigest_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, + WOLFCRYPT_BIO_info_cb *fp); + +static WOLFCRYPT_BIO_METHOD wc_BioDigest_method = { + BIO_TYPE_MD, + "Message digest", + wc_BioDigest_write, + wc_BioDigest_read, + NULL, /* puts */ + wc_BioDigest_gets, + wc_BioDigest_ctrl, + wc_BioDigest_new, + wc_BioDigest_free, + wc_BioDigest_callback_ctrl, +}; + +static long wc_BioDigest_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, + WOLFCRYPT_BIO_info_cb *fp) +{ + WOLFSSL_ENTER("wc_BioDigest_callback_ctrl"); + if (bio == NULL || bio->next_bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + return wc_BioCallbackCtrl(bio->next_bio, cmd, fp); +} + +WOLFCRYPT_BIO_METHOD *wc_Bio_f_md(void) +{ + return (&wc_BioDigest_method); +} + +static int wc_BioDigest_new(WOLFCRYPT_BIO *bio) +{ + WOLFSSL_ENTER("wc_BioDigest_new"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + bio->ptr = (WOLFCRYPT_EVP_MD_CTX *)XMALLOC(sizeof(WOLFCRYPT_EVP_MD_CTX), + 0, DYNAMIC_TYPE_OPENSSL); + if (bio->ptr == NULL) { + WOLFSSL_ERROR(MEMORY_E); + return -1; + } + + wc_EVP_MD_CTX_init((WOLFCRYPT_EVP_MD_CTX *)bio->ptr); + + bio->init = 0; + bio->flags = 0; + + WOLFSSL_LEAVE("wc_BioDigest_new", 1); + return 1; +} + +static int wc_BioDigest_free(WOLFCRYPT_BIO *bio) +{ + WOLFSSL_ENTER("wc_BioDigest_free"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + wc_EVP_MD_CTX_cleanup((WOLFCRYPT_EVP_MD_CTX *)bio->ptr); + + XMEMSET(bio->ptr, 0, sizeof(WOLFCRYPT_EVP_MD_CTX)); + XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); + bio->ptr = NULL; + + bio->init = 0; + bio->flags = 0; + + WOLFSSL_LEAVE("wc_BioDigest_free", 1); + return 1; +} + +static int wc_BioDigest_read(WOLFCRYPT_BIO *bio, char *data, int size) +{ + WOLFCRYPT_EVP_MD_CTX *ctx; + int ret = 0; + + WOLFSSL_ENTER("wc_BioDigest_read"); + + if (bio == NULL || bio->ptr == NULL || bio->next_bio == NULL || + data == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + ctx = (WOLFCRYPT_EVP_MD_CTX *)bio->ptr; + + ret = wc_BioRead(bio->next_bio, data, size); + if (bio->init && ret > 0) { + if (wc_EVP_DigestUpdate(ctx, data, (word32)ret) != 1) { + WOLFSSL_ERROR(BIO_DGST_UPDATE_E); + return -1; + } + } + + wc_BioClearRetryFlags(bio); + wc_BioCopyNextRetry(bio); + + WOLFSSL_LEAVE("wc_BioDigest_read", ret); + return ret; +} + +static int wc_BioDigest_write(WOLFCRYPT_BIO *bio, + const char *data, int size) +{ + WOLFCRYPT_EVP_MD_CTX *ctx; + int ret = 0; + + WOLFSSL_ENTER("wc_BioDigest_write"); + + if (bio == NULL || bio->ptr == NULL || data == NULL || size <= 0) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + ctx = (WOLFCRYPT_EVP_MD_CTX *)bio->ptr; + + ret = wc_BioWrite(bio->next_bio, data, size); + + if (bio->init && ret > 0) { + if (wc_EVP_DigestUpdate(ctx, data, (word32)ret) != 1) { + WOLFSSL_ERROR(BIO_DGST_UPDATE_E); + wc_BioClearRetryFlags(bio); + return -1; + } + } + + if (bio->next_bio != NULL) { + wc_BioClearRetryFlags(bio); + wc_BioCopyNextRetry(bio); + } + + WOLFSSL_LEAVE("wc_BioDigest_write", ret); + + return ret; +} + +static long wc_BioDigest_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) +{ + WOLFCRYPT_EVP_MD_CTX *ctx; + long ret = 1; + + WOLFSSL_ENTER("wc_BioDigest_ctrl"); + + if (bio == NULL || bio->ptr == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + ctx = (WOLFCRYPT_EVP_MD_CTX *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + if (bio->init) + ret = wc_EVP_DigestInit(ctx, ctx->digest); + else + ret = 0; + + if (ret > 0) + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + + case BIO_C_GET_MD: + if (bio->init) { + const WOLFCRYPT_EVP_MD **pmd; + pmd = (const WOLFCRYPT_EVP_MD **)ptr; + *pmd = ctx->digest; + } else + ret = 0; + break; + + case BIO_C_GET_MD_CTX: + { + WOLFCRYPT_EVP_MD_CTX **pctx; + pctx = (WOLFCRYPT_EVP_MD_CTX **)ptr; + *pctx = ctx; + } + bio->init = 1; + break; + + case BIO_C_SET_MD_CTX: + if (bio->init) + bio->ptr = ptr; + else + ret = 0; + break; + + case BIO_C_DO_STATE_MACHINE: + wc_BioClearRetryFlags(bio); + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + wc_BioCopyNextRetry(bio); + break; + + case BIO_C_SET_MD: + ret = wc_EVP_DigestInit(ctx, (WOLFCRYPT_EVP_MD *)ptr); + if (ret > 0) + bio->init = 1; + else + WOLFSSL_ERROR(BIO_DGST_INIT_E); + break; + + case BIO_CTRL_DUP: + { + WOLFCRYPT_BIO *dbio; + WOLFCRYPT_EVP_MD_CTX *dctx; + + dbio = (WOLFCRYPT_BIO *)ptr; + dctx = (WOLFCRYPT_EVP_MD_CTX *)dbio->ptr; + + ret = wc_EVP_MD_CTX_copy(dctx, ctx); + if (ret) + bio->init = 1; + } + break; + + default: + ret = wc_BioCtrl(bio->next_bio, cmd, num, ptr); + break; + } + + WOLFSSL_LEAVE("wc_BioDigest_ctrl", (int)ret); + return ret; +} + +static int wc_BioDigest_gets(WOLFCRYPT_BIO *bio, char *buf, int size) +{ + WOLFCRYPT_EVP_MD_CTX *ctx; + unsigned int dgstLen = 0; + + WOLFSSL_ENTER("wc_BioDigest_gets"); + + if (bio == NULL || bio->ptr == NULL || buf == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + ctx = (WOLFCRYPT_EVP_MD_CTX *)bio->ptr; + + if (size < ctx->macSize) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + if (wc_EVP_DigestFinal(ctx, (byte *)buf, &dgstLen) != 1) { + WOLFSSL_ERROR(BIO_DGST_FINAL_E); + return -1; + } + + return dgstLen; +} + +/* end BIO Filter digest */ + +/* start BIO Filter socket */ + +/* Socket Handling */ +#ifndef WOLFSSL_SOCKET_INVALID +#ifdef USE_WINDOWS_API +#define WOLFSSL_SOCKET_INVALID ((SOCKET)INVALID_SOCKET) +#else +#define WOLFSSL_SOCKET_INVALID (0) +#endif +#endif /* WOLFSSL_SOCKET_INVALID */ + +#define MAX_LISTEN 32 + +#ifdef USE_WINDOWS_API +static int wsa_init_done = 0; +#endif + +int wc_BioGetHostIp(const char *str, unsigned char *ip) +{ + struct hostent *he; + unsigned int iip[4]; + + if (wc_BioSockInit() != 1) + return 0; + + /* IP found */ + if (sscanf(str, "%d.%d.%d.%d", &iip[0], &iip[1], &iip[2], &iip[3]) == 4) + { + ip[0] = (iip[0] & 0xff); + ip[1] = (iip[1] & 0xff); + ip[2] = (iip[2] & 0xff); + ip[3] = (iip[3] & 0xff); + return 1; + } + + /* IP not found, check with a gethostbyname */ + he = gethostbyname(str); + if (he == NULL) { + WOLFSSL_ERROR(BIO_NO_HOSTNAME_E); + return 0; + } + + if (he->h_addrtype != AF_INET) { + WOLFSSL_ERROR(BIO_ADDR_AF_INET_E); + return 0; + } + + XMEMCPY(ip, he->h_addr_list[0], 4); + + return 1; +} + +int wc_BioGetPort(const char *str, unsigned short *port_ptr) +{ + int i; + struct servent *s; + + if (str == NULL) { + WOLFSSL_ERROR(BIO_NO_PORT_E); + return 0; + } + + i = atoi(str); + if (i != 0) { + *port_ptr = (unsigned short)i; + return 1; + } + + s = getservbyname(str, "tcp"); + if (s != NULL) { + *port_ptr = ntohs((unsigned short)s->s_port); + return 1; + } + + if (strcmp(str, "http") == 0) + *port_ptr = 80; + else if (strcmp(str, "telnet") == 0) + *port_ptr = 23; + else if (strcmp(str, "socks") == 0) + *port_ptr = 1080; + else if (strcmp(str, "https") == 0) + *port_ptr = 443; + else if (strcmp(str, "ssl") == 0) + *port_ptr = 443; + else if (strcmp(str, "ftp") == 0) + *port_ptr = 21; + else if (strcmp(str, "gopher") == 0) + *port_ptr = 70; + else { + WOLFSSL_ERROR(BIO_SRV_PROTO_E); + return 0; + } + + return 1; +} + +int wc_BioSockError(int sock) +{ + int j = 0, i; + union { + size_t s; + int i; + } size; + + /* heuristic way to adapt for platforms that expect 64-bit optlen */ + size.s = 0, size.i = sizeof(j); + /* + * Note: under Windows the third parameter is of type (char *) whereas + * under other systems it is (void *) if you don't have a cast it will + * choke the compiler: if you do have a cast then you can either go for + * (char *) or (void *). + */ + i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, (void *)&size); + if (i < 0) + return 1; + + return j; +} + +int wc_BioSockInit(void) +{ +# ifdef USE_WINDOWS_API + static struct WSAData wsa_state; + + if (!wsa_init_done) { + int err; + + wsa_init_done = 1; + memset(&wsa_state, 0, sizeof(wsa_state)); + /* + * Not making wsa_state available to the rest of the code is formally + * wrong. But the structures we use are [beleived to be] invariable + * among Winsock DLLs, while API availability is [expected to be] + * probed at run-time with DSO_global_lookup. + */ + if (WSAStartup(0x0202, &wsa_state) != 0) { + err = WSAGetLastError(); + WOLFSSL_ERROR(BIO_WSASTARTUP_E); + return -1; + } + } +# endif /* USE_WINDOWS_API */ + + return 1; +} + +void wc_BioSockCleanup(void) +{ +#ifdef USE_WINDOWS_API + if (wsa_init_done) { + wsa_init_done = 0; + WSACleanup(); + } +#endif +} + +int wc_BioGetAcceptSocket(char *host, int bind_mode) +{ + int ret = 0; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#ifdef TEST_IPV6 + struct sockaddr_in6 sa_in6; +#endif + } server, client; + int s = WOLFSSL_SOCKET_INVALID, cs, addrlen; + unsigned char ip[4]; + unsigned short port; + char *str = NULL; + char *h, *p, *e; + unsigned long l; + int err_num; + + if (wc_BioSockInit() != 1) + return WOLFSSL_SOCKET_INVALID; + + str = strdup(host); + if (str == NULL) + return WOLFSSL_SOCKET_INVALID; + + h = p = NULL; + h = str; + for (e = str; *e; e++) { + if (*e == ':') { + p = e; + } else if (*e == '/') { + *e = '\0'; + break; + } + } + if (p) + *p++ = '\0'; /* points at last ':', '::port' is special + * [see below] */ + else + p = h, h = NULL; + + if (!wc_BioGetPort(p, &port)) + goto err; + + memset((char *)&server, 0, sizeof(server)); + server.sa_in.sin_family = AF_INET; + server.sa_in.sin_port = htons(port); + addrlen = sizeof(server.sa_in); + + if (h == NULL || strcmp(h, "*") == 0) + server.sa_in.sin_addr.s_addr = INADDR_ANY; + else { + if (!wc_BioGetHostIp(h, &(ip[0]))) + goto err; + l = (unsigned long) + ((unsigned long)ip[0] << 24L) | + ((unsigned long)ip[1] << 16L) | + ((unsigned long)ip[2] << 8L) | + ((unsigned long)ip[3]); + server.sa_in.sin_addr.s_addr = htonl(l); + } + +again: + s = socket(server.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); + if (s == WOLFSSL_SOCKET_INVALID) { + WOLFSSL_ERROR(BIO_CREATE_SOCKET_E); + goto err; + } + +#ifdef SO_REUSEADDR + if (bind_mode == BIO_BIND_REUSEADDR) { + int i = 1; + + ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i)); + bind_mode = BIO_BIND_NORMAL; + } +#endif /* SO_REUSEADDR */ + if (bind(s, &server.sa, addrlen) == -1) { +#ifdef SO_REUSEADDR +#ifdef USE_WINDOWS_API + err_num = WSAGetLastError(); + if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) && + (err_num == WSAEADDRINUSE)) +#else + err_num = errno; + if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) && + (err_num == EADDRINUSE)) +#endif /* USE_WINDOWS_API */ + { + client = server; + if (h == NULL || strcmp(h, "*") == 0) { +#ifdef TEST_IPV6 + if (client.sa.sa_family == AF_INET6) { + XMEMSET(&client.sa_in6.sin6_addr, 0, + sizeof(client.sa_in6.sin6_addr)); + client.sa_in6.sin6_addr.s6_addr[15] = 1; + } + else +#endif + if (client.sa.sa_family == AF_INET) { + client.sa_in.sin_addr.s_addr = htonl(0x7F000001); + } + else + goto err; + } + + cs = socket(client.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); + if (cs != WOLFSSL_SOCKET_INVALID) { + int ii; + ii = connect(cs, &client.sa, addrlen); +#ifdef USE_WINDOWS_API + closesocket(cs); +#else + close(cs); +#endif + if (ii == WOLFSSL_SOCKET_INVALID) { + bind_mode = BIO_BIND_REUSEADDR; +#ifdef USE_WINDOWS_API + closesocket(s); +#else + close(s); +#endif + goto again; + } + } + } +#endif /* SO_REUSEADDR */ + + WOLFSSL_ERROR(BIO_BIND_SOCKET_E); + goto err; + } + + if (listen(s, MAX_LISTEN) == -1) { + WOLFSSL_ERROR(BIO_LISTEN_SOCKET_E); + goto err; + } + + ret = 1; + +err: + + if (str != NULL) + free(str); + + if (!ret && (s != WOLFSSL_SOCKET_INVALID)) { +#ifdef USE_WINDOWS_API + closesocket(s); +#else + close(s); +#endif + s = WOLFSSL_SOCKET_INVALID; + } + + return s; +} + +int wc_BioAccept(int sock, char **addr) +{ + int dsock = WOLFSSL_SOCKET_INVALID; + unsigned long l; + + struct { + union { + size_t s; + int i; + } len; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#ifdef TEST_IPV6 + struct sockaddr_in sa_in6; +#endif + } from; + } sa; + + sa.len.s = 0; + sa.len.i = sizeof(sa.from); + memset(&sa.from, 0, sizeof(sa.from)); + + dsock = accept(sock, &sa.from.sa, (void *)&sa.len); + if (sizeof(sa.len.i) != sizeof(sa.len.s) && !sa.len.i) { + if (sa.len.s > sizeof(sa.from)) { + WOLFSSL_ERROR(MEMORY_E); + goto end; + } + + sa.len.i = (int)sa.len.s; + } + + if (dsock == WOLFSSL_SOCKET_INVALID) { + if (wc_BioSockShouldRetry(dsock)) + return -2; + WOLFSSL_ERROR(BIO_ACCEPT_E); + goto end; + } + + if (addr == NULL || sa.from.sa.sa_family != AF_INET) + goto end; + + if (*addr == NULL) { + *addr = XMALLOC(24, 0, DYNAMIC_TYPE_OPENSSL); + if (*addr == NULL) { + WOLFSSL_ERROR(MEMORY_E); + goto end; + } + } + + l = ntohl(sa.from.sa_in.sin_addr.s_addr); + + XSNPRINTF(*addr, 24, "%d.%d.%d.%d:%d", + (unsigned char)(l >> 24L) & 0xff, + (unsigned char)(l >> 16L) & 0xff, + (unsigned char)(l >> 8L) & 0xff, + (unsigned char)(l) & 0xff, ntohs(sa.from.sa_in.sin_port)); +end: + return dsock; +} + +int wc_BioSetTcpNsigpipe(int s, int on) +{ + int ret = 0; + +#ifndef USE_WINDOWS_API +#ifdef SO_NOSIGPIPE + ret = setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on)); +#else /* no S_NOSIGPIPE */ + (void) s; + (void) on; + + signal(SIGPIPE, SIG_IGN); +#endif /* S_NOSIGPIPE */ +#endif /* USE_WINDOWS_API */ + + return (ret == 0); +} + +int wc_BioSetTcpNdelay(int s, int on) +{ + int ret = 0; +#if defined(TCP_NODELAY) +#ifdef SOL_TCP + int opt = SOL_TCP; +#else + int opt = IPPROTO_TCP; +#endif + + ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on)); +#else + (void) s; + (void) on; +#endif /* TCP_NODELAY */ + + return (ret == 0); +} + +int wc_BioSocketNbio(int s, int mode) +{ +#ifdef USE_WINDOWS_API + unsigned long blocking = mode; + int ret = ioctlsocket(s, FIONBIO, &blocking); + return (ret == 0); +#elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \ +|| defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) + /* non blocking not supported, for now */ + return -1; +#else + int flags = fcntl(s, F_GETFL, 0); + if (flags) + flags = fcntl(s, F_SETFL, flags | mode); + return (flags == 0); +#endif +} + +/* end BIO Filter socket */ + +/* start BIO Method accept */ + +typedef struct { + int state; + int nbio; + + char *param_addr; + char *ip_port; + int accept_sock; + int accept_nbio; + + /* + * If 0, it means normal, if 1, do a connect on bind failure, and if + * there is no-one listening, bind with SO_REUSEADDR. If 2, always use + * SO_REUSEADDR. + */ + int bind_mode; + + /* used to force some socket options like NO_SIGPIPE, TCP_NODELAY */ + int options; + + WOLFCRYPT_BIO *bio_chain; +} WOLFCRYPT_BIO_ACCEPT; + +static int wc_BioAccept_write(WOLFCRYPT_BIO *bio, const char *data, int size); +static int wc_BioAccept_read(WOLFCRYPT_BIO *bio, char *data, int size); +static int wc_BioAccept_puts(WOLFCRYPT_BIO *bio, const char *str); +static long wc_BioAccept_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr); +static int wc_BioAccept_new(WOLFCRYPT_BIO *bio); +static int wc_BioAccept_free(WOLFCRYPT_BIO *bio); +static void wc_BioAccept_close_socket(WOLFCRYPT_BIO *bio); + +static int wc_BioAccept_state(WOLFCRYPT_BIO *bio, WOLFCRYPT_BIO_ACCEPT *c); + +# define ACPT_S_BEFORE 1 +# define ACPT_S_GET_ACCEPT_SOCKET 2 +# define ACPT_S_OK 3 + +static WOLFCRYPT_BIO_METHOD wc_BioAccept_method = { + BIO_TYPE_ACCEPT, + "Socket accept", + wc_BioAccept_write, + wc_BioAccept_read, + wc_BioAccept_puts, + NULL, /* gets */ + wc_BioAccept_ctrl, + wc_BioAccept_new, + wc_BioAccept_free, + NULL, +}; + +WOLFCRYPT_BIO_METHOD *wc_Bio_s_accept(void) +{ + return (&wc_BioAccept_method); +} + +static int wc_BioAccept_new(WOLFCRYPT_BIO *bio) +{ + WOLFSSL_ENTER("wc_BioAccept_new"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + bio->init = 0; + bio->num = WOLFSSL_SOCKET_INVALID; + bio->flags = 0; + + bio->ptr = (WOLFCRYPT_BIO_ACCEPT *) + XMALLOC(sizeof(WOLFCRYPT_BIO_ACCEPT), 0, DYNAMIC_TYPE_OPENSSL); + if (bio->ptr == NULL) + return 0; + + XMEMSET(bio->ptr, 0, sizeof(WOLFCRYPT_BIO_ACCEPT)); + + ((WOLFCRYPT_BIO_ACCEPT *)bio->ptr)->accept_sock = WOLFSSL_SOCKET_INVALID; + ((WOLFCRYPT_BIO_ACCEPT *)bio->ptr)->bind_mode = BIO_BIND_NORMAL; + ((WOLFCRYPT_BIO_ACCEPT *)bio->ptr)->options = 0; + ((WOLFCRYPT_BIO_ACCEPT *)bio->ptr)->state = ACPT_S_BEFORE; + + bio->shutdown = 1; + + return 1; +} + +static void wc_BioAccept_close_socket(WOLFCRYPT_BIO *bio) +{ + WOLFCRYPT_BIO_ACCEPT *accept; + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return; + } + + accept = (WOLFCRYPT_BIO_ACCEPT *)bio->ptr; + if (accept->accept_sock != WOLFSSL_SOCKET_INVALID) { + shutdown(accept->accept_sock, SHUT_RDWR); +#ifdef USE_WINDOWS_API + closesocket(accept->accept_sock); +#else + close(accept->accept_sock); +#endif + accept->accept_sock = WOLFSSL_SOCKET_INVALID; + bio->num = WOLFSSL_SOCKET_INVALID; + } +} + +static int wc_BioAccept_free(WOLFCRYPT_BIO *bio) +{ + WOLFSSL_ENTER("wc_BioAccept_free"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + if (!bio->shutdown) + return 1; + + wc_BioAccept_close_socket(bio); + + if (bio->ptr != NULL) { + WOLFCRYPT_BIO_ACCEPT *accept = (WOLFCRYPT_BIO_ACCEPT *)bio->ptr; + + if (accept->param_addr != NULL) + XFREE(accept->param_addr, 0, DYNAMIC_TYPE_OPENSSL); + if (accept->ip_port != NULL) + XFREE(accept->ip_port, 0, DYNAMIC_TYPE_OPENSSL); + if (accept->bio_chain != NULL) + wc_BioFree(accept->bio_chain); + + XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); + bio->ptr = NULL; + } + + bio->flags = 0; + bio->init = 0; + + return 1; +} + +static int wc_BioAccept_state(WOLFCRYPT_BIO *bio, WOLFCRYPT_BIO_ACCEPT *accept) +{ + WOLFCRYPT_BIO *nbio = NULL; + int s = -1; + int dsock; + + if (bio == NULL || accept == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + +again: + switch (accept->state) { + case ACPT_S_BEFORE: + if (accept->param_addr == NULL) { + WOLFSSL_ERROR(BIO_NO_PORT_E); + return -1; + } + + s = wc_BioGetAcceptSocket(accept->param_addr, accept->bind_mode); + if (s == WOLFSSL_SOCKET_INVALID) + return -1; + + if (accept->accept_nbio) { + if (!wc_BioSocketNbio(s, 1)) { +#ifdef USE_WINDOWS_API + closesocket(s); +#else + close(s); +#endif + WOLFSSL_ERROR(BIO_NBIO_E); + return -1; + } + } + + /* TCP NO DELAY */ + if (accept->options & 1) { + if (!wc_BioSetTcpNdelay(s, 1)) { +#ifdef USE_WINDOWS_API + closesocket(s); +#else + close(s); +#endif + WOLFSSL_ERROR(BIO_OPTIONS_E); + return -1; + } + } + + /* IGNORE SIGPIPE */ + if (accept->options & 2) { + if (!wc_BioSetTcpNsigpipe(s, 1)) { +#ifdef USE_WINDOWS_API + closesocket(s); +#else + close(s); +#endif + WOLFSSL_ERROR(BIO_OPTIONS_E); + return -1; + } + } + + accept->accept_sock = s; + bio->num = s; + accept->state = ACPT_S_GET_ACCEPT_SOCKET; + return 1; + break; + + case ACPT_S_GET_ACCEPT_SOCKET: + if (bio->next_bio != NULL) { + accept->state = ACPT_S_OK; + goto again; + } + + wc_BioClearRetryFlags(bio); + bio->retry_reason = 0; + dsock = wc_BioAccept(accept->accept_sock, &accept->ip_port); + + /* retry case */ + if (dsock == -2) { + wc_BioSetRetrySpecial(bio); + bio->retry_reason = BIO_RR_ACCEPT; + return -1; + } + + if (dsock < 0) + return dsock; + + nbio = wc_BioNewSocket(dsock, BIO_CLOSE); + if (nbio == NULL) + goto err; + + wc_BioSetCallback(nbio, wc_BioGetCallback(bio)); + wc_BioSetCallbackArg(nbio, wc_BioGetCallbackArg(bio)); + + if (accept->nbio) { + if (!wc_BioSocketNbio(dsock, 1)) { + WOLFSSL_ERROR(BIO_NBIO_E); + goto err; + } + } + + /* + * If the accept BIO has an bio_chain, we dup it and put the new + * socket at the end. + */ + if (accept->bio_chain != NULL) { + WOLFCRYPT_BIO *dbio = wc_BioDupChain(accept->bio_chain); + if (dbio == NULL) + goto err; + if (!wc_BioPush(dbio, nbio)) + goto err; + nbio = dbio; + } + + if (wc_BioPush(bio, nbio) == NULL) + goto err; + + accept->state = ACPT_S_OK; + return 1; + err: + if (nbio != NULL) + wc_BioFree(nbio); + else if (s >= 0) +#ifdef USE_WINDOWS_API + closesocket(s); +#else + close(s); +#endif + break; + + case ACPT_S_OK: + if (bio->next_bio == NULL) { + accept->state = ACPT_S_GET_ACCEPT_SOCKET; + goto again; + } + return 1; + break; + + default: + break; + } + + return 0; +} + +static int wc_BioAccept_read(WOLFCRYPT_BIO *bio, char *data, int size) +{ + int ret = 0; + WOLFCRYPT_BIO_ACCEPT *accept; + + if (bio == NULL || data == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + wc_BioClearRetryFlags(bio); + accept = (WOLFCRYPT_BIO_ACCEPT *)bio->ptr; + + while (bio->next_bio == NULL) { + ret = wc_BioAccept_state(bio, accept); + if (ret <= 0) + return ret; + } + + ret = wc_BioRead(bio->next_bio, data, size); + wc_BioCopyNextRetry(bio); + + return ret; +} + +static int wc_BioAccept_write(WOLFCRYPT_BIO *bio, const char *data, int size) +{ + int ret = 0; + WOLFCRYPT_BIO_ACCEPT *accept; + + if (bio == NULL || data == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + wc_BioClearRetryFlags(bio); + accept = (WOLFCRYPT_BIO_ACCEPT *)bio->ptr; + + while (bio->next_bio == NULL) { + ret = wc_BioAccept_state(bio, accept); + if (ret <= 0) + return ret; + } + + ret = wc_BioWrite(bio->next_bio, data, size); + wc_BioCopyNextRetry(bio); + + return ret; +} + +static long wc_BioAccept_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) +{ + int *ip; + long ret = 1; + WOLFCRYPT_BIO_ACCEPT *accept; + char **pp; + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + accept = (WOLFCRYPT_BIO_ACCEPT *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ret = 0; + accept->state = ACPT_S_BEFORE; + wc_BioAccept_close_socket(bio); + bio->flags = 0; + break; + + case BIO_C_DO_STATE_MACHINE: + /* use this one to start the connection */ + ret = (long)wc_BioAccept_state(bio, accept); + break; + + case BIO_C_SET_ACCEPT: + if (ptr != NULL) { + if (num == 0) { + bio->init = 1; + if (accept->param_addr != NULL) + XFREE(accept->param_addr, 0, DYNAMIC_TYPE_OPENSSL); + accept->param_addr = strdup(ptr); + } + else if (num == 1) { + accept->accept_nbio = (ptr != NULL); + } + else if (num == 2) { + if (accept->bio_chain != NULL) + wc_BioFree(accept->bio_chain); + accept->bio_chain = (WOLFCRYPT_BIO *)ptr; + } + } + break; + + case BIO_C_SET_NBIO: + accept->nbio = (int)num; + break; + + case BIO_C_SET_FD: + bio->init = 1; + bio->num = *((int *)ptr); + accept->accept_sock = bio->num; + accept->state = ACPT_S_GET_ACCEPT_SOCKET; + bio->shutdown = (int)num; + bio->init = 1; + break; + + case BIO_C_GET_FD: + if (bio->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = accept->accept_sock; + ret = accept->accept_sock; + } + else + ret = -1; + break; + + case BIO_C_GET_ACCEPT: + if (bio->init) { + if (ptr != NULL) { + pp = (char **)ptr; + *pp = accept->param_addr; + } + else + ret = -1; + } + else + ret = -1; + break; + + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + + case BIO_CTRL_FLUSH: + case BIO_CTRL_DUP: + break; + + case BIO_C_SET_BIND_MODE: + accept->bind_mode = (int)num; + break; + + case BIO_C_GET_BIND_MODE: + ret = (long)accept->bind_mode; + break; + + case BIO_C_SET_EX_ARG: + accept->options = (int)num; + break; + + default: + ret = 0; + break; + } + + return ret; +} + +static int wc_BioAccept_puts(WOLFCRYPT_BIO *bio, const char *str) +{ + if (bio == NULL || str == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + return wc_BioAccept_write(bio, str, (int)strlen(str)); +} + +WOLFCRYPT_BIO *wc_BioNewAccept(const char *str) +{ + WOLFCRYPT_BIO *bio; + + if (str == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + bio = wc_BioNew(wc_Bio_s_accept()); + if (bio == NULL) + return NULL; + + if (wc_BioSetAcceptPort(bio, str)) + return bio; + + wc_BioFree(bio); + return NULL; +} + +/* end BIO Method accept */ + +/* start BIO Method connect */ + +static int wc_BioConn_write(WOLFCRYPT_BIO *bio, const char *data, int size); +static int wc_BioConn_read(WOLFCRYPT_BIO *bio, char *data, int size); +static int wc_BioConn_puts(WOLFCRYPT_BIO *bio, const char *str); +static long wc_BioConn_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr); +static int wc_BioConn_new(WOLFCRYPT_BIO *bio); +static int wc_BioConn_free(WOLFCRYPT_BIO *bio); +static long wc_BioConn_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, + WOLFCRYPT_BIO_info_cb *fp); + +static WOLFCRYPT_BIO_METHOD wc_BioConn_method = { + BIO_TYPE_SOCKET, + "Socket connect", + wc_BioConn_write, + wc_BioConn_read, + wc_BioConn_puts, + NULL, /* gets */ + wc_BioConn_ctrl, + wc_BioConn_new, + wc_BioConn_free, + wc_BioConn_callback_ctrl, +}; + +typedef struct { + int state; + int nbio; + + /* keep received Hostname and Port */ + char *pHostname; + char *pPort; + + /* internal usage */ + unsigned char ip[4]; + unsigned short port; + + struct sockaddr_in them; + + /* + * called when the connection is initially made callback(BIO,state,ret); + * The callback should return 'ret'. state is for compatibility with the + * ssl info_callback + */ + int (*info_callback) (const WOLFCRYPT_BIO *bio, int state, int ret); +} WOLFCRYPT_BIO_CONNECT; + +static int wc_BioConn_state(WOLFCRYPT_BIO *bio, WOLFCRYPT_BIO_CONNECT *conn) +{ + int ret = -1, i; + word32 l; + char *p, *q; + + WOLFSSL_ENTER("wc_BioConn_state"); + + if (bio == NULL || conn == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + for (;;) { + switch (conn->state) { + case BIO_CONN_S_BEFORE: + p = conn->pHostname; + if (p == NULL) { + WOLFSSL_ERROR(BIO_NO_HOSTNAME_E); + goto exit_loop; + } + + for (; *p != '\0'; p++) { + if ((*p == ':') || (*p == '/')) + break; + } + + i = *p; + if ((i == ':') || (i == '/')) { + *(p++) = '\0'; + if (i == ':') { + for (q = p; *q; q++) + if (*q == '/') { + *q = '\0'; + break; + } + + if (conn->pPort != NULL) + XFREE(conn->pPort, 0, DYNAMIC_TYPE_OPENSSL); + + conn->pPort = XMALLOC(strlen(p)+1, + 0, DYNAMIC_TYPE_OPENSSL); + if (conn->pPort == NULL) { + WOLFSSL_ERROR(MEMORY_E); + goto exit_loop; + break; + } + XSTRNCPY(conn->pPort, p, strlen(p)+1); + } + } + + if (conn->pPort == NULL) { + WOLFSSL_ERROR(BIO_NO_PORT_E); + goto exit_loop; + } + + conn->state = BIO_CONN_S_GET_IP; + break; + + case BIO_CONN_S_GET_IP: + if (wc_BioGetHostIp(conn->pHostname, conn->ip) <= 0) + goto exit_loop; + conn->state = BIO_CONN_S_GET_PORT; + break; + + case BIO_CONN_S_GET_PORT: + if (conn->pPort == NULL || + wc_BioGetPort(conn->pPort, &conn->port) <= 0) + goto exit_loop; + conn->state = BIO_CONN_S_CREATE_SOCKET; + break; + + case BIO_CONN_S_CREATE_SOCKET: + /* now setup address */ + XMEMSET(&conn->them, 0, sizeof(conn->them)); + conn->them.sin_family = AF_INET; + conn->them.sin_port = htons((unsigned short)conn->port); + l = ((word32)conn->ip[0] << 24L) | + ((word32)conn->ip[1] << 16L) | + ((word32)conn->ip[2] << 8L) | + ((word32)conn->ip[3]); + conn->them.sin_addr.s_addr = htonl(l); + conn->state = BIO_CONN_S_CREATE_SOCKET; + + ret = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (ret <= 0) { + WOLFSSL_ERROR(BIO_CREATE_SOCKET_E); + goto exit_loop; + } + + bio->num = ret; + conn->state = BIO_CONN_S_NBIO; + break; + + case BIO_CONN_S_NBIO: + if (conn->nbio) { + if (!wc_BioSocketNbio(bio->num, 1)) { + WOLFSSL_ERROR(BIO_NBIO_E); + goto exit_loop; + } + } + conn->state = BIO_CONN_S_CONNECT; + +# if defined(SO_KEEPALIVE) + i = 1; + i = setsockopt(bio->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, + sizeof(i)); + if (i < 0) { + WOLFSSL_ERROR(BIO_KEEPALIVE_E); + goto exit_loop; + } +# endif + break; + + + case BIO_CONN_S_CONNECT: + wc_BioClearRetryFlags(bio); + ret = connect(bio->num, (struct sockaddr *)&conn->them, + sizeof(conn->them)); + + bio->retry_reason = 0; + if (ret < 0) { + if (wc_BioSockShouldRetry(ret)) { + wc_BioSetRetrySpecial(bio); + conn->state = BIO_CONN_S_BLOCKED_CONNECT; + bio->retry_reason = BIO_RR_CONNECT; + } + else + WOLFSSL_ERROR(BIO_CONNECT_E); + goto exit_loop; + } + else + conn->state = BIO_CONN_S_OK; + break; + + case BIO_CONN_S_BLOCKED_CONNECT: + i = wc_BioSockError(bio->num); + if (i != 0) { + WOLFSSL_ERROR(BIO_CONNECT_E); + ret = 0; + goto exit_loop; + } + else + conn->state = BIO_CONN_S_OK; + break; + + case BIO_CONN_S_OK: + ret = 1; + goto exit_loop; + break; + + default: + goto exit_loop; + break; + } + + if (conn->info_callback != NULL) { + ret = conn->info_callback(bio, conn->state, ret); + if (!ret) + goto end; + } + } + +exit_loop: + if (conn->info_callback != NULL) + ret = conn->info_callback(bio, conn->state, ret); +end: + return ret; +} + +WOLFCRYPT_BIO_METHOD *wc_Bio_s_connect(void) +{ + WOLFSSL_ENTER("wc_Bio_s_connect"); + + return (&wc_BioConn_method); +} + +static int wc_BioConn_new(WOLFCRYPT_BIO *bio) +{ + WOLFSSL_ENTER("wc_BioConn_new"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + bio->init = 0; + bio->flags = 0; + bio->num = WOLFSSL_SOCKET_INVALID; + + bio->ptr = (WOLFCRYPT_BIO_CONNECT *)XMALLOC(sizeof(WOLFCRYPT_BIO_CONNECT), + 0, DYNAMIC_TYPE_OPENSSL); + if (bio->ptr == NULL) { + WOLFSSL_ERROR(MEMORY_E); + return 0; + } + + XMEMSET(bio->ptr, 0, sizeof(WOLFCRYPT_BIO_CONNECT)); + + ((WOLFCRYPT_BIO_CONNECT *)bio->ptr)->state = BIO_CONN_S_BEFORE; + + return 1; +} + +static void wc_BioConn_close_socket(WOLFCRYPT_BIO *bio) +{ + WOLFCRYPT_BIO_CONNECT *conn; + + WOLFSSL_ENTER("wc_BioConn_close_socket"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return ; + } + + conn = (WOLFCRYPT_BIO_CONNECT *)bio->ptr; + + if (bio->num > 0) { + /* Only do a shutdown if things were established */ + if (conn->state == BIO_CONN_S_OK) + shutdown(bio->num, SHUT_RDWR); +#ifdef USE_WINDOWS_API + closesocket(bio->num); +#else + close(bio->num); +#endif + bio->num = WOLFSSL_SOCKET_INVALID; + } +} + +static int wc_BioConn_free(WOLFCRYPT_BIO *bio) +{ + WOLFSSL_ENTER("wc_BioConn_free"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + if (bio->shutdown) { + wc_BioConn_close_socket(bio); + if (bio->ptr != NULL) { + WOLFCRYPT_BIO_CONNECT *c = (WOLFCRYPT_BIO_CONNECT*)bio->ptr; + + if (c->pHostname != NULL) { + XFREE(c->pHostname, 0, DYNAMIC_TYPE_OPENSSL); + c->pHostname = NULL; + } + if (c->pPort != NULL) { + XFREE(c->pPort, 0, DYNAMIC_TYPE_OPENSSL); + c->pPort = NULL; + } + XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); + bio->ptr = NULL; + } + bio->flags = 0; + bio->init = 0; + } + + return 1; +} + +static int wc_BioConn_read(WOLFCRYPT_BIO *bio, char *data, int size) +{ + int ret = 0; + WOLFCRYPT_BIO_CONNECT *conn; + + WOLFSSL_ENTER("wc_BioConn_read"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + conn = (WOLFCRYPT_BIO_CONNECT *)bio->ptr; + if (conn->state != BIO_CONN_S_OK) { + ret = wc_BioConn_state(bio, conn); + if (ret <= 0) + return (ret); + } + +#ifdef USE_WINDOWS_API + WSASetLastError(0); + ret = (int)recv(bio->num, data, size, 0); +#else + errno = 0; + ret = (int)read(bio->num, data, size); +#endif + + wc_BioClearRetryFlags(bio); + if (ret <= 0) { + if (wc_BioSockShouldRetry(ret)) + wc_BioSetRetryRead(bio); + } + + return ret; +} + +static int wc_BioConn_write(WOLFCRYPT_BIO *bio, const char *data, int size) +{ + int ret = 0; + WOLFCRYPT_BIO_CONNECT *conn; + + WOLFSSL_ENTER("wc_BioConn_write"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + conn = (WOLFCRYPT_BIO_CONNECT *)bio->ptr; + if (conn->state != BIO_CONN_S_OK) { + ret = wc_BioConn_state(bio, conn); + if (ret <= 0) + return (ret); + } + +#ifdef USE_WINDOWS_API + WSASetLastError(0); + ret = (int)send(bio->num, data, size, 0); +#else + errno = 0; + ret = (int)write(bio->num, data, size); +#endif + + wc_BioClearRetryFlags(bio); + if (ret <= 0) { + if (wc_BioSockShouldRetry(ret)) + wc_BioSetRetryWrite(bio); + } + + return ret; +} + +static long wc_BioConn_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) +{ + long ret = 1; + WOLFCRYPT_BIO_CONNECT *conn; + + WOLFSSL_ENTER("wc_BioConn_ctrl"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + conn = (WOLFCRYPT_BIO_CONNECT *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ret = 0; + conn->state = BIO_CONN_S_BEFORE; + wc_BioConn_close_socket(bio); + bio->flags = 0; + break; + + case BIO_C_DO_STATE_MACHINE: + /* use this one to start the connection */ + if (conn->state != BIO_CONN_S_OK) + ret = (long)wc_BioConn_state(bio, conn); + else + ret = 1; + break; + + case BIO_C_GET_CONNECT: + if (ptr == NULL) + break; + + if (num == 0) + *((const char **)ptr) = conn->pHostname; + else if (num == 1) + *((const char **)ptr) = conn->pPort; + else if (num == 2) + *((const char **)ptr) = (char *)conn->ip; + else if (num == 3) + *((int *)ptr) = conn->port; + + if (!bio->init || ptr == NULL) + *((const char **)ptr) = "not initialized"; + + ret = 1; + break; + + case BIO_C_SET_CONNECT: + if (ptr == NULL) + break; + + bio->init = 1; + if (num == 0) { + if (conn->pHostname != NULL) + XFREE(conn->pHostname, 0, DYNAMIC_TYPE_OPENSSL); + conn->pHostname = XMALLOC(strlen((char *)ptr)+1, + 0, DYNAMIC_TYPE_OPENSSL); + if (conn->pHostname == NULL) { + WOLFSSL_ERROR(MEMORY_E); + ret = -1; + break; + } + XSTRNCPY(conn->pHostname, (char *)ptr, strlen((char *)ptr)+1); + } + else if (num == 1) { + if (conn->pPort != NULL) + XFREE(conn->pPort, 0, DYNAMIC_TYPE_OPENSSL); + + conn->pPort = XMALLOC(strlen((char *)ptr)+1, + 0, DYNAMIC_TYPE_OPENSSL); + if (conn->pPort == NULL) { + WOLFSSL_ERROR(MEMORY_E); + ret = -1; + break; + } + XSTRNCPY(conn->pPort, (char *)ptr, strlen((char *)ptr)+1); + } + else if (num == 2) { + char buf[16]; + unsigned char *p = ptr; + + XSNPRINTF(buf, sizeof(buf), "%d.%d.%d.%d", + p[0], p[1], p[2], p[3]); + + if (conn->pHostname != NULL) + XFREE(conn->pHostname, 0, DYNAMIC_TYPE_OPENSSL); + + conn->pHostname = XMALLOC(strlen(buf)+1, + 0, DYNAMIC_TYPE_OPENSSL); + if (conn->pHostname == NULL) { + WOLFSSL_ERROR(MEMORY_E); + ret = -1; + break; + } + XSTRNCPY(conn->pHostname, buf, strlen(buf)+1); + XMEMCPY(conn->ip, ptr, 4); + } + else if (num == 3) { + char buf[6]; + + XSNPRINTF(buf, sizeof(buf), "%d", *(int *)ptr); + if (conn->pPort != NULL) + XFREE(conn->pPort, 0, DYNAMIC_TYPE_OPENSSL); + + conn->pPort = XMALLOC(strlen(buf)+1, + 0, DYNAMIC_TYPE_OPENSSL); + if (conn->pPort == NULL) { + WOLFSSL_ERROR(MEMORY_E); + ret = -1; + break; + } + XSTRNCPY(conn->pPort, buf, strlen(buf)+1); + conn->port = *(int *)ptr; + } + break; + + case BIO_C_SET_NBIO: + conn->nbio = (int)num; + break; + + case BIO_C_GET_FD: + if (bio->init) { + if (ptr != NULL) + *((int *)ptr) = bio->num; + ret = bio->num; + } + else + ret = -1; + break; + + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + + case BIO_CTRL_FLUSH: + break; + + case BIO_CTRL_DUP: + { + WOLFCRYPT_BIO *dbio = (WOLFCRYPT_BIO *)ptr; + + if (conn->pPort != NULL) + wc_BioSetConnPort(dbio, conn->pPort); + + if (conn->pHostname != NULL) + wc_BioSetConnHostname(dbio, conn->pHostname); + + wc_BioSetNbio(dbio, conn->nbio); + + wc_BioSetInfoCallback(dbio, + (WOLFCRYPT_BIO_info_cb *)conn->info_callback); + } + break; + + case BIO_CTRL_SET_CALLBACK: + ret = 0; + break; + + case BIO_CTRL_GET_CALLBACK: + { + int (**fptr) (const WOLFCRYPT_BIO *bio, int state, int xret); + + fptr = (int (**)(const WOLFCRYPT_BIO *bio, + int state, int xret))ptr; + *fptr = conn->info_callback; + } + break; + + default: + ret = 0; + break; + } + + return ret; +} + +static long wc_BioConn_callback_ctrl(WOLFCRYPT_BIO *bio, + int cmd, WOLFCRYPT_BIO_info_cb *fp) +{ + long ret = 1; + WOLFCRYPT_BIO_CONNECT *conn; + + WOLFSSL_ENTER("wc_BioConn_callback_ctrl"); + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + conn = (WOLFCRYPT_BIO_CONNECT *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + conn->info_callback = (int (*)(const WOLFCRYPT_BIO *, int, int))fp; + break; + + default: + ret = 0; + break; + } + + return ret; +} + +static int wc_BioConn_puts(WOLFCRYPT_BIO *bio, const char *str) +{ + WOLFSSL_ENTER("wc_BioConn_puts"); + + if (bio == NULL || str == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + return wc_BioConn_write(bio, str, (int)strlen(str)); +} + +WOLFCRYPT_BIO *wc_BioNewConnect(const char *str) +{ + WOLFCRYPT_BIO *bio; + + WOLFSSL_ENTER("wc_BioNewConnect"); + + if (str == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return NULL; + } + + bio = wc_BioNew(wc_Bio_s_connect()); + if (bio == NULL) + return NULL; + + if (wc_BioSetConnHostname(bio, str)) + return bio; + + wc_BioFree(bio); + return NULL; +} + +/* end BIO Method connect */ + +/* start BIO Method datagramm */ + + +#if !defined(IP_MTU) +#define IP_MTU 14 +#endif + +#if defined(TEST_IPV6) && !defined(IPPROTO_IPV6) +#define IPPROTO_IPV6 41 +#endif + +static int wc_BioDgram_write(WOLFCRYPT_BIO *bio, const char *data, int size); +static int wc_BioDgram_read(WOLFCRYPT_BIO *bio, char *data, int size); +static int wc_BioDgram_puts(WOLFCRYPT_BIO *bio, const char *str); +static long wc_BioDgram_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr); +static int wc_BioDgram_new(WOLFCRYPT_BIO *bio); +static int wc_BioDgram_free(WOLFCRYPT_BIO *bio); +static int wc_BioDgram_clear(WOLFCRYPT_BIO *bio); + +static int wc_BioDgram_should_retry(int s); + +static void get_current_time(struct timeval *t); + +static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_dgram_method = { + BIO_TYPE_DGRAM, + "Datagram socket", + wc_BioDgram_write, + wc_BioDgram_read, + wc_BioDgram_puts, + NULL, /* gets */ + wc_BioDgram_ctrl, + wc_BioDgram_new, + wc_BioDgram_free, + NULL, +}; + +typedef struct { + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#ifdef TEST_IPV6 + struct sockaddr_in6 sa_in6; +# endif + } peer; + unsigned int connected; + unsigned int _errno; + unsigned int mtu; + struct timeval next_timeout; + struct timeval socket_timeout; +} WOLFCRYPT_BIO_DATAGRAM; + +static int wc_BioDgram_should_retry(int i) +{ + if (!i || i == -1) { + int ret; +#ifdef USE_WINDOWS_API + ret = WSAGetLastError(); +#else + ret = errno; +#endif + return wc_BioSockNonFatalError(ret); + } + + return 0; +} + +static void get_current_time(struct timeval *t) +{ +#ifdef USE_WINDOWS_API + SYSTEMTIME st; + union { + unsigned __int64 ul; + FILETIME ft; + } now; + + GetSystemTime(&st); + SystemTimeToFileTime(&st, &now.ft); + now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */ + t->tv_sec = (long)(now.ul / 10000000); + t->tv_usec = ((int)(now.ul % 10000000)) / 10; +# else + gettimeofday(t, NULL); +# endif +} + + +WOLFCRYPT_BIO_METHOD *wc_Bio_s_datagram(void) +{ + return (&WOLFCRYPT_BIO_dgram_method); +} + +WOLFCRYPT_BIO *wc_BioNewDgram(int fd, int close_flag) +{ + WOLFCRYPT_BIO *bio; + + bio = wc_BioNew(wc_Bio_s_datagram()); + if (bio == NULL) + return NULL; + + wc_BioSetFd(bio, fd, close_flag); + return bio; +} + +static int wc_BioDgram_new(WOLFCRYPT_BIO *bio) +{ + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + bio->init = 0; + bio->num = 0; + bio->flags = 0; + + bio->ptr = XMALLOC(sizeof(WOLFCRYPT_BIO_DATAGRAM), 0, DYNAMIC_TYPE_OPENSSL); + if (bio->ptr == NULL) + return 0; + + XMEMSET(bio->ptr, 0, sizeof(WOLFCRYPT_BIO_DATAGRAM)); + return 1; +} + +static int wc_BioDgram_free(WOLFCRYPT_BIO *bio) +{ + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + if (!wc_BioDgram_clear(bio)) + return 0; + + if (bio->ptr != NULL) + XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); + + return 1; +} + +static int wc_BioDgram_clear(WOLFCRYPT_BIO *bio) +{ + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + if (bio->shutdown) { + if (bio->init) { + shutdown(bio->num, SHUT_RDWR); +#ifdef USE_WINDOWS_API + closesocket(bio->num); +#else + close(bio->num); +#endif + } + bio->init = 0; + bio->flags = 0; + } + + return 1; +} + +static void wc_BioDgram_adjust_rcv_timeout(WOLFCRYPT_BIO *bio) +{ +#ifdef SO_RCVTIMEO + WOLFCRYPT_BIO_DATAGRAM *dgram; + + union { + size_t s; + int i; + } sz = { 0 }; + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return; + } + + dgram = (WOLFCRYPT_BIO_DATAGRAM *)bio->ptr; + + /* Is a timer active? */ + if (dgram->next_timeout.tv_sec > 0 || dgram->next_timeout.tv_usec > 0) { + struct timeval timenow, timeleft; + + /* Read current socket timeout */ +#ifdef USE_WINDOWS_API + int timeout; + + sz.i = sizeof(timeout); + if (getsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, &sz.i) >= 0) { + dgram->socket_timeout.tv_sec = timeout / 1000; + dgram->socket_timeout.tv_usec = (timeout % 1000) * 1000; + } +#else + sz.i = sizeof(dgram->socket_timeout); + if (getsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, + &(dgram->socket_timeout), (void *)&sz) >= 0) { + if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) + if (sz.s > sizeof(dgram->socket_timeout)) + return ; + } +#endif /* USE_WINDOWS_API */ + + /* Get current time */ + get_current_time(&timenow); + + /* Calculate time left until timer expires */ + XMEMCPY(&timeleft, &dgram->next_timeout, sizeof(struct timeval)); + if (timeleft.tv_usec < timenow.tv_usec) { + timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec; + timeleft.tv_sec--; + } + else + timeleft.tv_usec -= timenow.tv_usec; + + if (timeleft.tv_sec < timenow.tv_sec) { + timeleft.tv_sec = 0; + timeleft.tv_usec = 1; + } + else + timeleft.tv_sec -= timenow.tv_sec; + + /* + * Adjust socket timeout if next handhake message timer will expire + * earlier. + */ + if ((!dgram->socket_timeout.tv_sec && !dgram->socket_timeout.tv_usec) || + (dgram->socket_timeout.tv_sec > timeleft.tv_sec) || + (dgram->socket_timeout.tv_sec == timeleft.tv_sec && + dgram->socket_timeout.tv_usec >= timeleft.tv_usec)) { +#ifdef USE_WINDOWS_API + timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; + setsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, sizeof(timeout)); +#else + setsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, + sizeof(struct timeval)); +#endif /* USE_WINDOWS_API */ + } + } +#endif /* SO_RCVTIMEO */ +} + +static void wc_BioDgram_reset_rcv_timeout(WOLFCRYPT_BIO *bio) +{ +#if defined(SO_RCVTIMEO) + WOLFCRYPT_BIO_DATAGRAM *dgram; + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return; + } + + dgram = (WOLFCRYPT_BIO_DATAGRAM *)bio->ptr; + + /* Is a timer active? */ + if (dgram->next_timeout.tv_sec > 0 || dgram->next_timeout.tv_usec > 0) { +#ifdef USE_WINDOWS_API + int timeout = dgram->socket_timeout.tv_sec * 1000 + + dgram->socket_timeout.tv_usec / 1000; + setsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, sizeof(timeout)); +#else + setsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, &(dgram->socket_timeout), + sizeof(struct timeval)); +#endif + } +#endif +} + +static int wc_BioDgram_read(WOLFCRYPT_BIO *bio, char *data, int size) +{ + int ret = 0; + WOLFCRYPT_BIO_DATAGRAM *dgram; + + struct { + union { + size_t s; + int i; + } len; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +#ifdef TEST_IPV6 + struct sockaddr_in6 sa_in6; +#endif + } peer; + } sa; + + if (bio == NULL || data == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + dgram = (WOLFCRYPT_BIO_DATAGRAM *)bio->ptr; + + sa.len.s = 0; + sa.len.i = sizeof(sa.peer); + +#ifdef USE_WINDOWS_API + WSASetLastError(0); +#else + errno = 0; +#endif + + XMEMSET(&sa.peer, 0, sizeof(sa.peer)); + + wc_BioDgram_adjust_rcv_timeout(bio); + + ret = (int)recvfrom(bio->num, data, size, 0, &sa.peer.sa, (void *)&sa.len); + if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { + if (sa.len.s > sizeof(sa.peer)) + return 0; + + sa.len.i = (int)sa.len.s; + } + + if (!dgram->connected && ret >= 0) + wc_BioCtrl(bio, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); + + wc_BioClearRetryFlags(bio); + if (ret < 0) { + if (wc_BioDgram_should_retry(ret)) { + wc_BioSetRetryRead(bio); +#ifdef USE_WINDOWS_API + dgram->_errno = WSAGetLastError(); +#else + dgram->_errno = errno; +#endif + } + } + + wc_BioDgram_reset_rcv_timeout(bio); + + return ret; +} + +static int wc_BioDgram_write(WOLFCRYPT_BIO *bio, + const char *data, int size) +{ + int ret; + WOLFCRYPT_BIO_DATAGRAM *dgram; + + if (bio == NULL || data == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + dgram = (WOLFCRYPT_BIO_DATAGRAM *)bio->ptr; + +#ifdef USE_WINDOWS_API + WSASetLastError(0); +#else + errno = 0; +#endif + + if (dgram->connected) +#ifdef USE_WINDOWS_API + ret = (int)send(bio->num, data, size, 0); +#else + ret = (int)write(bio->num, data, size); +#endif + else { + int peerlen = sizeof(dgram->peer); + + if (dgram->peer.sa.sa_family == AF_INET) + peerlen = sizeof(dgram->peer.sa_in); +#ifdef TEST_IPV6 + else if (dgram->peer.sa.sa_family == AF_INET6) + peerlen = sizeof(dgram->peer.sa_in6); +#endif + ret = (int)sendto(bio->num, data, size, 0, &dgram->peer.sa, peerlen); + } + + wc_BioClearRetryFlags(bio); + + if (ret <= 0 && wc_BioDgram_should_retry(ret)) { + wc_BioSetRetryWrite(bio); +#ifdef USE_WINDOWS_API + dgram->_errno = WSAGetLastError(); +#else + dgram->_errno = errno; +#endif + } + + return ret; +} + +static long wc_BioDgram_get_mtu_overhead(WOLFCRYPT_BIO_DATAGRAM *dgram) +{ + long ret; + + if (dgram == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + switch (dgram->peer.sa.sa_family) { + case AF_INET: + ret = 28; + break; +#ifdef TEST_IPV6 + case AF_INET6: + ret = 48; + break; +#endif + default: + ret = 28; + break; + } + + return ret; +} + +static long wc_BioDgram_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) +{ + long ret = 1; + struct sockaddr *to = NULL; + WOLFCRYPT_BIO_DATAGRAM *dgram; + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + dgram = (WOLFCRYPT_BIO_DATAGRAM *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + num = 0; + + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + case BIO_C_FILE_SEEK: + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + ret = 0; + break; + + case BIO_C_SET_FD: + wc_BioDgram_clear(bio); + bio->num = *((int *)ptr); + bio->shutdown = (int)num; + bio->init = 1; + break; + + case BIO_C_GET_FD: + if (bio->init) { + if (ptr != NULL) + *((int *)ptr) = bio->num; + ret = bio->num; + } + else + ret = -1; + break; + + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + + case BIO_CTRL_DGRAM_CONNECT: + to = (struct sockaddr *)ptr; + switch (to->sa_family) { + case AF_INET: + XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa_in)); + break; +#ifdef TEST_IPV6 + case AF_INET6: + XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa_in6)); + break; +#endif + default: + XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa)); + break; + } + break; + + /* (Linux)kernel sets DF bit on outgoing IP packets */ + case BIO_CTRL_DGRAM_MTU_DISCOVER: + break; + + case BIO_CTRL_DGRAM_QUERY_MTU: + ret = 0; + break; + + case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: + ret = -wc_BioDgram_get_mtu_overhead(dgram); + switch (dgram->peer.sa.sa_family) { + case AF_INET: + ret += 576; + break; +#ifdef TEST_IPV6 + case AF_INET6: + ret += 1280; + break; +#endif + default: + ret += 576; + break; + } + break; + + case BIO_CTRL_DGRAM_GET_MTU: + return dgram->mtu; + break; + + case BIO_CTRL_DGRAM_SET_MTU: + dgram->mtu = (int)num; + ret = num; + break; + + case BIO_CTRL_DGRAM_SET_CONNECTED: + to = (struct sockaddr *)ptr; + if (to != NULL) { + dgram->connected = 1; + switch (to->sa_family) { + case AF_INET: + XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa_in)); + break; +#ifdef TEST_IPV6 + case AF_INET6: + XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa_in6)); + break; +#endif + default: + XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa)); + break; + } + } + else { + dgram->connected = 0; + XMEMSET(&dgram->peer, 0, sizeof(dgram->peer)); + } + break; + + case BIO_CTRL_DGRAM_GET_PEER: + switch (dgram->peer.sa.sa_family) { + case AF_INET: + ret = sizeof(dgram->peer.sa_in); + break; +#ifdef TEST_IPV6 + case AF_INET6: + ret = sizeof(dgram->peer.sa_in6); + break; +#endif + default: + ret = sizeof(dgram->peer.sa); + break; + } + + if (num == 0 || num > ret) + num = ret; + XMEMCPY(ptr, &dgram->peer, (ret = num)); + break; + + case BIO_CTRL_DGRAM_SET_PEER: + to = (struct sockaddr *)ptr; + switch (to->sa_family) { + case AF_INET: + XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa_in)); + break; +#ifdef TEST_IPV6 + case AF_INET6: + XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa_in6)); + break; +#endif + default: + XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa)); + break; + } + break; + + case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: + XMEMCPY(&dgram->next_timeout, ptr, sizeof(struct timeval)); + break; + +#if defined(SO_RCVTIMEO) + case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: +#ifdef USE_WINDOWS_API + { + struct timeval *tv = (struct timeval *)ptr; + int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; + if (setsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, sizeof(timeout)) < 0) + ret = -1; + } +#else + if (setsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, ptr, + sizeof(struct timeval)) < 0) + ret = -1; +#endif /* USE_WINDOWS_API */ + break; + + case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: + { + union { + size_t s; + int i; + } sz = { 0 }; +#ifdef USE_WINDOWS_API + int timeout; + struct timeval *tv = (struct timeval *)ptr; + + sz.i = sizeof(timeout); + if (getsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, &sz.i) < 0) + ret = -1; + else { + tv->tv_sec = timeout / 1000; + tv->tv_usec = (timeout % 1000) * 1000; + ret = sizeof(*tv); + } +#else + sz.i = sizeof(struct timeval); + if (getsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, + ptr, (void *)&sz) < 0) + ret = -1; + else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) { + if (sz.s > sizeof(struct timeval)) + ret = -1; + else + ret = (int)sz.s; + } + else + ret = sz.i; +#endif /* USE_WINDOWS_API */ + } + break; +# endif /* defined(SO_RCVTIMEO) */ + +# if defined(SO_SNDTIMEO) + case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: +#ifdef USE_WINDOWS_API + { + struct timeval *tv = (struct timeval *)ptr; + int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; + if (setsockopt(bio->num, SOL_SOCKET, SO_SNDTIMEO, + (void *)&timeout, sizeof(timeout)) < 0) + ret = -1; + } +#else + if (setsockopt(bio->num, SOL_SOCKET, SO_SNDTIMEO, ptr, + sizeof(struct timeval)) < 0) + ret = -1; +#endif /* USE_WINDOWS_API */ + break; + + case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: + { + union { + size_t s; + int i; + } sz = { 0 }; +#ifdef USE_WINDOWS_API + int timeout; + struct timeval *tv = (struct timeval *)ptr; + + sz.i = sizeof(timeout); + if (getsockopt(bio->num, SOL_SOCKET, SO_SNDTIMEO, + (void *)&timeout, &sz.i) < 0) + ret = -1; + else { + tv->tv_sec = timeout / 1000; + tv->tv_usec = (timeout % 1000) * 1000; + ret = sizeof(*tv); + } +#else + sz.i = sizeof(struct timeval); + if (getsockopt(bio->num, SOL_SOCKET, SO_SNDTIMEO, + ptr, (void *)&sz) < 0) + ret = -1; + else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) { + if (sz.s > sizeof(struct timeval)) + ret = -1; + else + ret = (int)sz.s; + } + else + ret = sz.i; +#endif /* USE_WINDOWS_API */ + } + break; +#endif /* defined(SO_SNDTIMEO) */ + + case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: + case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: +#ifdef USE_WINDOWS_API + if (dgram->_errno == WSAETIMEDOUT) +#else + if (dgram->_errno == EAGAIN) +#endif + { + ret = 1; + dgram->_errno = 0; + } + else + ret = 0; + break; + + case BIO_CTRL_DGRAM_SET_DONT_FRAG: + ret = -1; + break; + + case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: + ret = wc_BioDgram_get_mtu_overhead(dgram); + break; + + default: + ret = 0; + break; + } + + return ret; +} + +static int wc_BioDgram_puts(WOLFCRYPT_BIO *bio, const char *str) +{ + if (bio == NULL || str == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + return wc_BioDgram_write(bio, str, (int)strlen(str)); +} + +/* end BIO Method datagramm */ + +/* start BIO Method file descriptor */ + + +static int wc_BioFd_write(WOLFCRYPT_BIO *bio, const char *buf, int size); +static int wc_BioFd_read(WOLFCRYPT_BIO *bio, char *buf, int size); +static int wc_BioFd_puts(WOLFCRYPT_BIO *bio, const char *str); +static int wc_BioFd_gets(WOLFCRYPT_BIO *bio, char *buf, int size); +static long wc_BioFd_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr); +static int wc_BioFd_new(WOLFCRYPT_BIO *bio); +static int wc_BioFd_free(WOLFCRYPT_BIO *bio); + +static WOLFCRYPT_BIO_METHOD wc_BioFd_method = { + BIO_TYPE_FD, + "File descriptor", + wc_BioFd_write, + wc_BioFd_read, + wc_BioFd_puts, + wc_BioFd_gets, + wc_BioFd_ctrl, + wc_BioFd_new, + wc_BioFd_free, + NULL, +}; + +/* functions are not implemented as not really used in OpenSSL except for two + * cases : + * * get password giving 'fd file' instead of 'file name' + * (see app_get_pass(), apps/apps.c) + * * open STDOUT and STDERR by giving fd instead of name + * (see main(), crypto/threads/mttest.c) + */ +WOLFCRYPT_BIO_METHOD *wc_Bio_s_fd(void) +{ + WOLFSSL_ERROR(NOT_COMPILED_IN); + return (&wc_BioFd_method); +} + +WOLFCRYPT_BIO *wc_BioNewFd(int fd, int close_flag) +{ + (void)fd; + (void)close_flag; + WOLFSSL_ERROR(NOT_COMPILED_IN); + return NULL; +} + +static int wc_BioFd_new(WOLFCRYPT_BIO *bio) +{ + (void)bio; + WOLFSSL_ERROR(NOT_COMPILED_IN); + return -2; +} + +static int wc_BioFd_free(WOLFCRYPT_BIO *bio) +{ + (void)bio; + WOLFSSL_ERROR(NOT_COMPILED_IN); + return -2; +} + +static int wc_BioFd_read(WOLFCRYPT_BIO *bio, char *buf, int size) +{ + (void)bio; + (void)buf; + (void)size; + WOLFSSL_ERROR(NOT_COMPILED_IN); + return -2; +} + +static int wc_BioFd_write(WOLFCRYPT_BIO *bio, const char *buf, int size) +{ + (void)bio; + (void)buf; + (void)size; + WOLFSSL_ERROR(NOT_COMPILED_IN); + return -2; +} + +static long wc_BioFd_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) +{ + (void)bio; + (void)ptr; + (void)cmd; + (void)num; + WOLFSSL_ERROR(NOT_COMPILED_IN); + return -2; +} + +static int wc_BioFd_gets(WOLFCRYPT_BIO *bio, char *buf, int size) +{ + (void)bio; + (void)buf; + (void)size; + WOLFSSL_ERROR(NOT_COMPILED_IN); + return -2; +} + +static int wc_BioFd_puts(WOLFCRYPT_BIO *bio, const char *str) +{ + (void)bio; + (void)str; + WOLFSSL_ERROR(NOT_COMPILED_IN); + return -2; +} + +/* end BIO Method file descriptor */ + +/* start BIO Method file */ + +#ifndef NO_FILESYSTEM + +#ifndef XFERROR +#define XFERROR ferror +#endif + +#ifndef XFILENO +#define XFILENO fileno +#endif + +#if defined(USE_WINDOWS_API) +#ifndef XSETMODE +#define XSETMODE _setmode +#endif +#endif /* USE_WINDOWS_API */ + +#ifndef XFFLUSH +#define XFFLUSH fflush +#endif + +#ifndef XFEOF +#define XFEOF feof +#endif + +#ifndef XFGETS +#define XFGETS fgets +#endif + +static int wc_BioFile_write(WOLFCRYPT_BIO *bio, const char *buf, int size); +static int wc_BioFile_read(WOLFCRYPT_BIO *bio, char *buf, int size); +static int wc_BioFile_puts(WOLFCRYPT_BIO *bio, const char *str); +static int wc_BioFile_gets(WOLFCRYPT_BIO *bio, char *buf, int size); +static long wc_BioFile_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr); +static int wc_BioFile_new(WOLFCRYPT_BIO *bio); +static int wc_BioFile_free(WOLFCRYPT_BIO *bio); + +static WOLFCRYPT_BIO_METHOD wc_BioFile_method = { + BIO_TYPE_FILE, + "FILE pointer", + wc_BioFile_write, + wc_BioFile_read, + wc_BioFile_puts, + wc_BioFile_gets, + wc_BioFile_ctrl, + wc_BioFile_new, + wc_BioFile_free, + NULL, +}; + +WOLFCRYPT_BIO *wc_BioNewFile(const char *name, const char *mode) +{ + XFILE f; + + if (name == NULL || mode == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return NULL; + } + + f = XFOPEN(name, mode); + if (f == NULL) { + WOLFSSL_ERROR(BIO_FILE_OPEN_E); + return NULL; + } + + return wc_BioNewFp(f, BIO_CLOSE); +} + +WOLFCRYPT_BIO *wc_BioNewFp(XFILE f, int close_flag) +{ + WOLFCRYPT_BIO *bio; + + if (f == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return NULL; + } + + bio = wc_BioNew(wc_Bio_s_file()); + if (bio == NULL) + return NULL; + + wc_BioSetFp(bio, f, close_flag); + + return bio; +} + +WOLFCRYPT_BIO_METHOD *wc_Bio_s_file(void) +{ + return (&wc_BioFile_method); +} + +static int wc_BioFile_new(WOLFCRYPT_BIO *bio) +{ + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + bio->init = 0; + bio->num = 0; + bio->ptr = NULL; + + return 1; +} + +static int wc_BioFile_free(WOLFCRYPT_BIO *bio) +{ + if (bio == NULL) + return 0; + + if (!bio->shutdown || !bio->init) + return 1; + + if (bio->ptr != NULL) { + XFCLOSE(bio->ptr); + bio->ptr = NULL; + } + bio->init = 0; + + return 1; +} + +static int wc_BioFile_read(WOLFCRYPT_BIO *bio, char *buf, int size) +{ + int ret = 0; + + if (bio == NULL || !bio->init || bio->ptr == NULL || buf == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + ret = (int)XFREAD(buf, sizeof(char), size, (FILE *)bio->ptr); + if (ret == 0 && XFERROR((FILE *)bio->ptr)) { + WOLFSSL_ERROR(BIO_FILE_READ_E); + ret = -1; + } + + return ret; +} + +static int wc_BioFile_write(WOLFCRYPT_BIO *bio, const char *buf, int size) +{ + int ret = 0; + + if (bio == NULL || !bio->init || bio->ptr == NULL || buf == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + ret = (int)XFWRITE(buf, sizeof(char), size, (FILE *)bio->ptr); + if (ret == 0 && XFERROR((FILE *)bio->ptr)) { + WOLFSSL_ERROR(BIO_FILE_WRITE_E); + ret = -1; + } + + return ret; +} + +static long wc_BioFile_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) +{ + long ret = 1; + char buf[4]; + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + switch (cmd) { + case BIO_C_FILE_SEEK: + case BIO_CTRL_RESET: + ret = (long)XFSEEK((FILE *)bio->ptr, num, 0); + break; + + case BIO_CTRL_EOF: + ret = (long)XFEOF((FILE *)bio->ptr); + break; + + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + ret = (long)XFTELL((FILE *)bio->ptr); + break; + + case BIO_C_SET_FILE_PTR: + wc_BioFile_free(bio); + bio->shutdown = (int)num & BIO_CLOSE; + bio->ptr = ptr; + bio->init = 1; + +#ifdef USE_WINDOWS_API + { + int fd; + + fd = XFILENO((FILE *)bio->ptr); + if (num & BIO_FP_TEXT) + XSETMODE(fd, O_TEXT); + else + XSETMODE(fd, O_BINARY); + } +#endif /* USE_WINDOWS_API */ + break; + + case BIO_C_SET_FILENAME: + wc_BioFile_free(bio); + bio->shutdown = (int)num & BIO_CLOSE; + if (num & BIO_FP_APPEND) { + if (num & BIO_FP_READ) + XSTRNCPY(buf, "a+", sizeof(buf) - 1); + else + XSTRNCPY(buf, "a", sizeof(buf) - 1); + } + else if (num & BIO_FP_READ) { + if (num & BIO_FP_WRITE) + XSTRNCPY(buf, "r+", sizeof(buf) - 1); + else + XSTRNCPY(buf, "r", sizeof(buf)); + } + else if (num & BIO_FP_WRITE) + XSTRNCPY(buf, "w", sizeof(buf) - 1); + else { + WOLFSSL_ERROR(BIO_FILE_MODE_E); + ret = 0; + break; + } + + if (num & BIO_FP_TEXT) + XSTRNCAT(buf, "t", sizeof(buf) - 1); + else + XSTRNCAT(buf, "b", sizeof(buf) - 1); + + bio->ptr = XFOPEN(ptr, buf); + if (bio->ptr == NULL) { + WOLFSSL_ERROR(BIO_FILE_OPEN_E); + ret = 0; + break; + } + bio->init = 1; + + break; + + case BIO_C_GET_FILE_PTR: + /* the ptr parameter is a FILE ** in this case. */ + if (ptr != NULL) + *((FILE **)ptr) = (FILE *)bio->ptr; + break; + + case BIO_CTRL_GET_CLOSE: + ret = (long)bio->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + + case BIO_CTRL_FLUSH: + XFFLUSH((FILE *)bio->ptr); + break; + + case BIO_CTRL_DUP: + ret = 1; + break; + + case BIO_CTRL_WPENDING: + case BIO_CTRL_PENDING: + case BIO_CTRL_PUSH: + case BIO_CTRL_POP: + ret = 0; + break; + + default: + ret = 0; + break; + } + + return ret; +} + +static int wc_BioFile_gets(WOLFCRYPT_BIO *bio, char *buf, int size) +{ + if (bio == NULL || bio->ptr == NULL || buf == NULL || size <= 0) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + /* init buffer */ + XMEMSET(buf, 0, size); + + if ((XFGETS(buf, size, (FILE *)bio->ptr) == NULL) && + XFERROR((FILE *)bio->ptr)) { + WOLFSSL_ERROR(BIO_FILE_GETS_E); + return -1; + } + + return (int)strlen(buf); +} + +static int wc_BioFile_puts(WOLFCRYPT_BIO *bio, const char *str) +{ + if (bio == NULL || bio->ptr == NULL || str == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + return wc_BioFile_write(bio, str, (int)strlen(str)); +} + +#endif /* NO_FILESYSTEM */ + +/* end BIO Method file */ + +/* start BIO Method memory */ + + +/* wolfSSL buffer type */ +typedef struct { + byte* data; + word32 length; +} WOLFCRYPT_BUF_MEM; + +static WOLFCRYPT_BUF_MEM *wolfCrypt_BufMem_new(void) +{ + WOLFCRYPT_BUF_MEM *buf; + + buf = (WOLFCRYPT_BUF_MEM *)XMALLOC(sizeof(WOLFCRYPT_BUF_MEM), + 0, DYNAMIC_TYPE_OPENSSL); + if (buf == NULL) { + WOLFSSL_ERROR(MEMORY_E); + return NULL; + } + + buf->length = 0; + buf->data = NULL; + return buf; +} + +static void wolfCrypt_BufMem_free(WOLFCRYPT_BUF_MEM *buf) +{ + if (buf == NULL) + return; + + if (buf->data != NULL) { + XMEMSET(buf->data, 0, buf->length); + XFREE(buf->data, 0, DYNAMIC_TYPE_OPENSSL); + } + + XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL); +} + +static int wolfCrypt_BufMem_grow(WOLFCRYPT_BUF_MEM *buf, size_t len) +{ + if (buf == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + /* size reduction, clean unused */ + if (buf->length >= len) { + if (buf->data == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + buf->length = (word32)len; + return (int)len; + } + + if (buf->data == NULL) + buf->data = XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL); + else + buf->data = XREALLOC(buf->data, buf->length+len, + 0, DYNAMIC_TYPE_OPENSSL); + if (buf->data == NULL) { + WOLFSSL_ERROR(MEMORY_E); + return -1; + } + + XMEMSET(&buf->data[buf->length], 0, len - buf->length); + buf->length = (word32)len; + + return (int)len; +} + +static int wolfCrypt_BufMem_grow_clean(WOLFCRYPT_BUF_MEM *buf, size_t len) +{ + int ret, idx = -1; + size_t size; + + if (buf == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + if (buf->length >= len) { + idx = buf->length; + size = buf->length - len; + } + + ret = wolfCrypt_BufMem_grow(buf, len); + if (ret && idx != -1) + XMEMSET(&buf->data[idx], 0, size); + + return ret; +} + + +static int wc_BioMem_write(WOLFCRYPT_BIO *bio, const char *buf, int size); +static int wc_BioMem_read(WOLFCRYPT_BIO *bio, char *buf, int size); +static int wc_BioMem_puts(WOLFCRYPT_BIO *bio, const char *str); +static int wc_BioMem_gets(WOLFCRYPT_BIO *bio, char *buf, int size); +static long wc_BioMem_ctrl(WOLFCRYPT_BIO *bio, int cmd, + long num, void *ptr); +static int wc_BioMem_new(WOLFCRYPT_BIO *bio); +static int wc_BioMem_free(WOLFCRYPT_BIO *bio); + +static WOLFCRYPT_BIO_METHOD wc_BioMem_method = { + BIO_TYPE_MEM, + "Memory buffer", + wc_BioMem_write, + wc_BioMem_read, + wc_BioMem_puts, + wc_BioMem_gets, + wc_BioMem_ctrl, + wc_BioMem_new, + wc_BioMem_free, + NULL, +}; + +WOLFCRYPT_BIO *wc_BioNewMemBuf(void *data, int len) +{ + WOLFCRYPT_BIO *bio; + size_t size; + + if (data == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return NULL; + } + + size = (len < 0) ? strlen((char *)data) : (size_t)len; + + bio = wc_BioNew(wc_Bio_s_mem()); + if (bio == NULL) + return NULL; + + ((WOLFCRYPT_BUF_MEM *)bio->ptr)->data = (byte*)data; + ((WOLFCRYPT_BUF_MEM *)bio->ptr)->length = (word32)size; + + bio->flags |= BIO_FLAGS_MEM_RDONLY; + bio->num = 0; + + return bio; +} + +WOLFCRYPT_BIO_METHOD *wc_Bio_s_mem(void) +{ + return (&wc_BioMem_method); +} + +static int wc_BioMem_new(WOLFCRYPT_BIO *bio) +{ + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + bio->ptr = wolfCrypt_BufMem_new(); + if (bio->ptr == NULL) + return -1; + + bio->shutdown = 1; + bio->init = 1; + bio->num = -1; + + return 1; +} + +static int wc_BioMem_free(WOLFCRYPT_BIO *bio) +{ + if (bio == NULL) + return -1; + + if (!bio->shutdown || !bio->init) + return 1; + + if (bio->ptr != NULL) { + if (bio->flags & BIO_FLAGS_MEM_RDONLY) + ((WOLFCRYPT_BUF_MEM *)bio->ptr)->data = NULL; + + wolfCrypt_BufMem_free(bio->ptr); + bio->ptr = NULL; + } + + bio->init = 0; + return 1; +} + +static int wc_BioMem_read(WOLFCRYPT_BIO *bio, char *data, int size) +{ + int ret = -1; + WOLFCRYPT_BUF_MEM *wbmptr; + + if (bio == NULL || !bio->init || bio->ptr == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + wc_BioClearRetryFlags(bio); + + wbmptr = (WOLFCRYPT_BUF_MEM *)bio->ptr; + + ret = (size >= 0 && (size_t)size > wbmptr->length) ? + (int)wbmptr->length : size; + + if (data != NULL && ret > 0) { + XMEMCPY(data, wbmptr->data, ret); + wbmptr->length -= ret; + if (bio->flags & BIO_FLAGS_MEM_RDONLY) + wbmptr->data += ret; + else + XMEMMOVE(&(wbmptr->data[0]), &(wbmptr->data[ret]), wbmptr->length); + } + else if (wbmptr->length == 0) { + ret = bio->num; + if (ret != 0) + wc_BioSetRetryRead(bio); + } + + return ret; +} + +static int wc_BioMem_write(WOLFCRYPT_BIO *bio, const char *data, int size) +{ + int init_len; + WOLFCRYPT_BUF_MEM *wbmptr; + + if (bio == NULL || !bio->init || data == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + WOLFSSL_ERROR(BIO_MEM_WRITE_E); + return -1; + } + + wc_BioClearRetryFlags(bio); + + wbmptr = (WOLFCRYPT_BUF_MEM *)bio->ptr; + init_len = wbmptr->length; + + if (wolfCrypt_BufMem_grow_clean(wbmptr, wbmptr->length + size) != + (int)(init_len + size)) + return -1; + + XMEMCPY(&(wbmptr->data[init_len]), data, size); + + return size; +} + +static long wc_BioMem_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) +{ + WOLFCRYPT_BUF_MEM *wbmptr; + long ret = 1; + + if (bio == NULL || bio->ptr == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + wbmptr = (WOLFCRYPT_BUF_MEM *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + if (wbmptr->data == NULL) + break; + + /* For read only case reset to the start again */ + if (bio->flags & BIO_FLAGS_MEM_RDONLY) + wbmptr->data -= wbmptr->length; + else { + XMEMSET(wbmptr->data, 0, wbmptr->length); + wbmptr->length = 0; + } + break; + + case BIO_CTRL_EOF: + ret = (long)(wbmptr->length == 0); + break; + + case BIO_C_SET_BUF_MEM_EOF_RETURN: + bio->num = (int)num; + break; + + case BIO_CTRL_INFO: + ret = (long)wbmptr->length; + if (ptr != NULL) + *((char **)ptr) = (char *)&(wbmptr->data[0]); + break; + + case BIO_C_SET_BUF_MEM: + wc_BioMem_free(bio); + bio->shutdown = (int)num; + bio->ptr = ptr; + break; + + case BIO_C_GET_BUF_MEM_PTR: + if (ptr != NULL) + *((char **)ptr) = (char *)wbmptr; + break; + + case BIO_CTRL_GET_CLOSE: + ret = (long)bio->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + + case BIO_CTRL_WPENDING: + ret = 0; + break; + + case BIO_CTRL_PENDING: + ret = (long)wbmptr->length; + break; + + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + + case BIO_CTRL_PUSH: + case BIO_CTRL_POP: + ret = 0; + break; + + default: + ret = 0; + break; + } + + return ret; +} + +static int wc_BioMem_gets(WOLFCRYPT_BIO *bio, char *buf, int size) +{ + WOLFCRYPT_BUF_MEM *wbmptr; + int i, blen; + + if (bio == NULL || bio->ptr == NULL || buf == NULL || size <= 0) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + wc_BioClearRetryFlags(bio); + + wbmptr = (WOLFCRYPT_BUF_MEM *)bio->ptr; + + if ((int)wbmptr->length > (size - 1)) + blen = size - 1; + else if (wbmptr->length <= 0) { + *buf = '\0'; + return 0; + } + else + blen = wbmptr->length; + + for (i = 0; i < blen; i++) { + if (wbmptr->data[i] == '\n') { + i++; + break; + } + } + + i = wc_BioMem_read(bio, buf, i); + if (i > 0) + buf[i] = '\0'; + + return i; +} + +static int wc_BioMem_puts(WOLFCRYPT_BIO *bio, const char *str) +{ + if (bio == NULL || str == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + return wc_BioMem_write(bio, str, (int)strlen(str)); +} + +/* end BIO Method memory */ + +/* start BIO Method null */ + +static int wc_BioNull_write(WOLFCRYPT_BIO *bio, const char *buf, int size); +static int wc_BioNull_read(WOLFCRYPT_BIO *bio, char *buf, int size); +static int wc_BioNull_puts(WOLFCRYPT_BIO *bio, const char *str); +static int wc_BioNull_gets(WOLFCRYPT_BIO *bio, char *buf, int size); +static long wc_BioNull_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr); +static int wc_BioNull_new(WOLFCRYPT_BIO *bio); +static int wc_BioNull_free(WOLFCRYPT_BIO *bio); + +static WOLFCRYPT_BIO_METHOD wc_BioNull_method = { + BIO_TYPE_NULL, + "NULL", + wc_BioNull_write, + wc_BioNull_read, + wc_BioNull_puts, + wc_BioNull_gets, + wc_BioNull_ctrl, + wc_BioNull_new, + wc_BioNull_free, + NULL, +}; + +WOLFCRYPT_BIO_METHOD *wc_Bio_s_null(void) +{ + return (&wc_BioNull_method); +} + +static int wc_BioNull_new(WOLFCRYPT_BIO *bio) +{ + if (bio == NULL) + return 0; + + bio->init = 1; + bio->num = 0; + bio->ptr = NULL; + + return 1; +} + +static int wc_BioNull_free(WOLFCRYPT_BIO *bio) +{ + return bio == NULL ? 0 : 1; +} + +static int wc_BioNull_read(WOLFCRYPT_BIO *bio, char *buf, int size) +{ + (void)bio; + (void)buf; + (void)size; + + return 0; +} + +static int wc_BioNull_write(WOLFCRYPT_BIO *bio, const char *buf, int size) +{ + (void)bio; + (void)buf; + + return size; +} + +static long wc_BioNull_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) +{ + (void)bio; + (void)ptr; + (void)num; + + long ret = 1; + + switch (cmd) { + case BIO_CTRL_RESET: + case BIO_CTRL_EOF: + case BIO_CTRL_SET: + case BIO_CTRL_SET_CLOSE: + case BIO_CTRL_FLUSH: + case BIO_CTRL_DUP: + ret = 1; + break; + case BIO_CTRL_GET_CLOSE: + case BIO_CTRL_INFO: + case BIO_CTRL_GET: + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + default: + ret = 0; + break; + } + + return ret; +} + +static int wc_BioNull_gets(WOLFCRYPT_BIO *bio, char *buf, int size) +{ + (void)bio; + (void)buf; + (void)size; + + return 0; +} + +static int wc_BioNull_puts(WOLFCRYPT_BIO *bio, const char *str) +{ + (void)bio; + + if (str == NULL) + return 0; + + return (int)strlen(str); +} + +/* end BIO Method null */ + +/* start BIO Method socket */ + +static int wc_BioSock_write(WOLFCRYPT_BIO *bio, const char *data, int size); +static int wc_BioSock_read(WOLFCRYPT_BIO *bio, char *data, int size); +static int wc_BioSock_puts(WOLFCRYPT_BIO *bio, const char *str); +static long wc_BioSock_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr); +static int wc_BioSock_new(WOLFCRYPT_BIO *bio); +static int wc_BioSock_free(WOLFCRYPT_BIO *bio); + +static WOLFCRYPT_BIO_METHOD wc_BioSock_method = { + BIO_TYPE_SOCKET, + "Socket", + wc_BioSock_write, + wc_BioSock_read, + wc_BioSock_puts, + NULL, /* gets */ + wc_BioSock_ctrl, + wc_BioSock_new, + wc_BioSock_free, + NULL, +}; + +WOLFCRYPT_BIO_METHOD *wc_Bio_s_socket(void) +{ + return (&wc_BioSock_method); +} + +WOLFCRYPT_BIO *wc_BioNewSocket(int fd, int close_flag) +{ + WOLFCRYPT_BIO *ret; + + ret = wc_BioNew(wc_Bio_s_socket()); + if (ret == NULL) { + WOLFSSL_ERROR(MEMORY_E); + return NULL; + } + + wc_BioSetFd(ret, fd, close_flag); + return ret; +} + +static int wc_BioSock_new(WOLFCRYPT_BIO *bio) +{ + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + bio->init = 0; + bio->num = 0; /* used for fd */ + bio->ptr = NULL; + bio->flags = 0; + + return 1; +} + +static int wc_BioSock_free(WOLFCRYPT_BIO *bio) +{ + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return 0; + } + + if (!bio->shutdown) + return 1; + + if (bio->init) { + shutdown(bio->num, SHUT_RDWR); +#ifdef USE_WINDOWS_API + closesocket(bio->num); +#else + close(bio->num); +#endif + } + + bio->init = 0; + bio->flags = 0; + + return 1; +} + +static int wc_BioSock_read(WOLFCRYPT_BIO *bio, char *data, int size) +{ + int ret; + + if (bio == NULL || !bio->init || data == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + +#ifdef USE_WINDOWS_API + WSASetLastError(0); + ret = (int)recv(bio->num, data, size, 0); +#else + errno = 0; + ret = (int)read(bio->num, data, size); +#endif + + wc_BioClearRetryFlags(bio); + if (ret <= 0) { + if (wc_BioSockShouldRetry(ret)) + wc_BioSetRetryRead(bio); + } + + return ret; +} + +static int wc_BioSock_write(WOLFCRYPT_BIO *bio, const char *data, int size) +{ + int ret; + + if (bio == NULL || !bio->init || data == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + +#ifdef USE_WINDOWS_API + WSASetLastError(0); + ret = (int)send(bio->num, data, size, 0); +#else + errno = 0; + ret = (int)write(bio->num, data, size); +#endif + + wc_BioClearRetryFlags(bio); + if (ret <= 0) { + if (wc_BioSockShouldRetry(ret)) + wc_BioSetRetryWrite(bio); + } + + return ret; +} + +static long wc_BioSock_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) +{ + long ret = 1; + + if (bio == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + switch (cmd) { + case BIO_C_SET_FD: + wc_BioSock_free(bio); + bio->num = *((int *)ptr); + bio->shutdown = (int)num; + bio->init = 1; + break; + + case BIO_C_GET_FD: + if (bio->init) { + if (ptr != NULL) + *((int *)ptr) = bio->num; + ret = bio->num; + } + else + ret = -1; + break; + + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + + default: + ret = 0; + break; + } + + return ret; +} + +static int wc_BioSock_puts(WOLFCRYPT_BIO *bio, const char *str) +{ + if (bio == NULL || str == NULL) { + WOLFSSL_ERROR(BAD_FUNC_ARG); + return -1; + } + + return wc_BioSock_write(bio, str, (int)strlen(str)); +} + +int wc_BioSockNonFatalError(int err) +{ + switch (err) { +#if defined(WSAEWOULDBLOCK) + case WSAEWOULDBLOCK: +#endif + +#ifdef EWOULDBLOCK +#ifdef WSAEWOULDBLOCK +#if WSAEWOULDBLOCK != EWOULDBLOCK + case EWOULDBLOCK: +#endif +#else + case EWOULDBLOCK: +#endif +#endif + +#if defined(ENOTCONN) + case ENOTCONN: +#endif + +#ifdef EINTR + case EINTR: +#endif + +#ifdef EAGAIN +#if EWOULDBLOCK != EAGAIN + case EAGAIN: +#endif +#endif + +#ifdef EPROTO + case EPROTO: +#endif + +#ifdef EINPROGRESS + case EINPROGRESS: +#endif + +#ifdef EALREADY + case EALREADY: +#endif + return 1; + break; + + default: + break; + } + + return 0; +} + +int wc_BioSockShouldRetry(int i) +{ + if (!i || i == -1) { + int ret; +#ifdef USE_WINDOWS_API + ret = WSAGetLastError(); +#else + ret = errno; +#endif + return wc_BioSockNonFatalError(ret); + } + + return 0; +} + +/* end BIO Method socket */ + #endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_f_b64.c b/wolfcrypt/src/bio_f_b64.c deleted file mode 100644 index 0005f1175..000000000 --- a/wolfcrypt/src/bio_f_b64.c +++ /dev/null @@ -1,669 +0,0 @@ -/* bio_f_b64.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include -#include -#include - -static int WOLFCRYPT_BIO_b64_write(WOLFCRYPT_BIO *bio, - const char *buf, int size); -static int WOLFCRYPT_BIO_b64_read(WOLFCRYPT_BIO *bio, char *buf, int size); -static int WOLFCRYPT_BIO_b64_puts(WOLFCRYPT_BIO *bio, const char *str); -static long WOLFCRYPT_BIO_b64_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr); -static int WOLFCRYPT_BIO_b64_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_b64_free(WOLFCRYPT_BIO *bio); -static long WOLFCRYPT_BIO_b64_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, - WOLFCRYPT_BIO_info_cb *fp); - -#define WOLFCRYPT_B64_BLOCK_SIZE 20*48 -#define WOLFCRYPT_B64_ENCODE_SIZE 20*64 + 40 // 40 : 20 CR LF -#define WOLFCRYPT_B64_NONE 0 -#define WOLFCRYPT_B64_ENCODE 1 -#define WOLFCRYPT_B64_DECODE 2 - - -typedef struct { - int dataLen; /* data length */ - int dataIdx; /* data index */ - int workLen; /* working buffer length */ - int workNl; /* used to stop when find a '\n' */ - int encode; /* base64 operation */ - int start; /* decoding started */ - int cont; /* <= 0 when finished */ - - char data[WOLFCRYPT_B64_ENCODE_SIZE]; - char work[WOLFCRYPT_B64_BLOCK_SIZE]; -} WOLFCRYPT_BIO_F_B64_CTX; - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_b64_method = { - BIO_TYPE_BASE64, - "Base64", - WOLFCRYPT_BIO_b64_write, - WOLFCRYPT_BIO_b64_read, - WOLFCRYPT_BIO_b64_puts, - NULL, /* gets */ - WOLFCRYPT_BIO_b64_ctrl, - WOLFCRYPT_BIO_b64_new, - WOLFCRYPT_BIO_b64_free, - WOLFCRYPT_BIO_b64_callback_ctrl, -}; - - -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_f_base64(void) -{ - return (&WOLFCRYPT_BIO_b64_method); -} - -static int WOLFCRYPT_BIO_b64_new(WOLFCRYPT_BIO *bio) -{ - WOLFCRYPT_BIO_F_B64_CTX *ctx; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_b64_new"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - bio->ptr = (WOLFCRYPT_BIO_F_B64_CTX *) - XMALLOC(sizeof(WOLFCRYPT_BIO_F_B64_CTX), - 0, DYNAMIC_TYPE_OPENSSL); - if (bio->ptr == NULL) { - WOLFSSL_ERROR(MEMORY_E); - return 0; - } - - ctx = (WOLFCRYPT_BIO_F_B64_CTX *)bio->ptr; - - ctx->dataLen = 0; - ctx->workLen = 0; - ctx->workNl = 0; - ctx->dataIdx = 0; - ctx->cont = 1; - ctx->start = 1; - ctx->encode = 0; - - bio->init = 1; - bio->flags = 0; - bio->num = 0; - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_new", 1); - return 1; -} - -static int WOLFCRYPT_BIO_b64_free(WOLFCRYPT_BIO *bio) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_b64_free"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - if (bio->ptr != NULL) { - XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); - bio->ptr = NULL; - } - - bio->init = 0; - bio->flags = 0; - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_free", 1); - - return 1; -} - - -static int WOLFCRYPT_BIO_b64_read(WOLFCRYPT_BIO *bio, char *data, int size) -{ - int ret = 0, idx, bread, j, k, num, ret_code = 0; - WOLFCRYPT_BIO_F_B64_CTX *ctx; - //unsigned char *p, *q; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_b64_read"); - - if (bio == NULL || !bio->init || bio->ptr == NULL || - bio->next_bio == NULL || data == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - - ctx = (WOLFCRYPT_BIO_F_B64_CTX *)bio->ptr; - - /* decode when reading */ - if (ctx->encode != WOLFCRYPT_B64_DECODE) { - ctx->encode = WOLFCRYPT_B64_DECODE; - ctx->dataLen = 0; - ctx->dataIdx = 0; - ctx->workLen = 0; - //WOLFCRYPT_EVP_DecodeInit(&(ctx->b64_ctx)); - } - - /* First check if there are bytes decoded/encoded */ - if (ctx->dataLen > 0) { - if (ctx->dataLen < ctx->dataIdx) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_read", -1); - return -1; - } - - bread = ctx->dataLen - ctx->dataIdx; - if (bread > size) - bread = size; - - if (ctx->dataIdx + bread >= (int)sizeof(ctx->data)) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_read", -1); - return -1; - } - - XMEMCPY(data, &(ctx->data[ctx->dataIdx]), bread); - - ret = bread; - data += bread; - size -= bread; - ctx->dataIdx += bread; - - if (ctx->dataLen == ctx->dataIdx) { - ctx->dataLen = 0; - ctx->dataIdx = 0; - } - } - - /* - * At this point, we have room of size bytes and an empty buffer, so we - * should read in some more. - */ - - ret_code = 0; - idx = 0; - - while (size > 0) { - if (ctx->cont <= 0) - break; - - bread = WOLFCRYPT_BIO_read(bio->next_bio, &ctx->work[ctx->workLen], - sizeof(ctx->work) - ctx->workLen); - - if (bread <= 0) { - ret_code = bread; - - /* Should we continue next time we are called? */ - if (!WOLFCRYPT_BIO_should_retry(bio->next_bio)) { - ctx->cont = bread; - /* If buffer empty break */ - if (!ctx->workLen) - break; - else - bread = 0; - } - /* else we retry and add more data to buffer */ - else - break; - } - - bread += ctx->workLen; - ctx->workLen = bread; - - /* - * We need to scan, a line at a time until we have a valid line if we - * are starting. - */ - if (ctx->start && (WOLFCRYPT_BIO_get_flags(bio) & BIO_FLAGS_BASE64_NO_NL)) - ctx->workLen = 0; - else if (ctx->start) { - /* search \n */ - ctx->workNl = -1; - - /* parse working buffer to find line endings */ - for (j = 0; j < bread; j++) { - - /* no end of line, continue */ - if (ctx->work[j] != '\n') - continue; - - /* we found an end of line, keep the position to - * decode the line */ - ctx->workNl = j; - - /* decode the line found */ - num = sizeof(ctx->data) - ctx->dataIdx; - - k = Base64_Decode((const byte*)ctx->work+idx,ctx->workNl-idx, - (byte *)ctx->data+ctx->dataIdx, (word32 *)&num); - if (k < 0 && !num && ctx->start) { - WOLFSSL_ERROR(BIO_B64_DECODE_E); - return -1; - } - else - ctx->start = 0; - - /* +1 => skeep \n */ - idx = (ctx->workNl + 1); - - ctx->dataLen += num; - ctx->dataIdx += num; - } - } else if ((bread < WOLFCRYPT_B64_BLOCK_SIZE) && (ctx->cont > 0)) { - /* - * If buffer isn't full and we can retry then restart to read in - * more data. - */ - continue; - } - - if (WOLFCRYPT_BIO_get_flags(bio) & BIO_FLAGS_BASE64_NO_NL) { - int z, jj; - - jj = bread & ~3; - - z = sizeof(ctx->data); - k = Base64_Decode((const byte*)ctx->work, jj, - (byte *)ctx->data, (word32 *)&z); - if (k < 0 || !z) { - WOLFSSL_ERROR(BIO_B64_DECODE_E); - return -1; - } - - /* z is now number of output bytes and jj is the number consumed - */ - if (jj != bread) { - ctx->workLen = bread - jj; - XMEMMOVE(ctx->work, &ctx->work[jj], ctx->workLen); - } - - if (z > 0) - ctx->dataLen = z; - else - ctx->dataLen = 0; - - bread = z; - } - - ctx->dataIdx = 0; - if (bread < 0) { - ret_code = 0; - ctx->dataLen = 0; - break; - } - - if (!(WOLFCRYPT_BIO_get_flags(bio) & BIO_FLAGS_BASE64_NO_NL)) { - /* keep no parsed data in working buffer */ - XMEMMOVE(ctx->work, ctx->work+idx, ctx->workLen-idx); - ctx->workLen -= idx; - idx = 0; - ctx->start = 1; - } - - bread = (ctx->dataLen <= size ? ctx->dataLen : size); - - XMEMCPY(data, ctx->data, bread); - ret += bread; - - if (bread == ctx->dataLen) { - ctx->dataLen = 0; - ctx->dataIdx = 0; - } - else - ctx->dataIdx = bread; - - size -= bread; - data += bread; - } - - WOLFCRYPT_BIO_copy_next_retry(bio); - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_read", (!ret ? ret_code : ret)); - - return (!ret ? ret_code : ret); -} - -static int WOLFCRYPT_BIO_b64_write(WOLFCRYPT_BIO *bio, - const char *data, int size) -{ - int ret = 0; - int n; - int i; - WOLFCRYPT_BIO_F_B64_CTX *ctx; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_b64_write"); - - if (bio == NULL || !bio->init || bio->ptr == NULL || - bio->next_bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - - ctx = (WOLFCRYPT_BIO_F_B64_CTX *)bio->ptr; - - /* encode when writing */ - if (ctx->encode != WOLFCRYPT_B64_ENCODE) { - ctx->encode = WOLFCRYPT_B64_ENCODE; - ctx->dataLen = 0; - ctx->dataIdx = 0; - ctx->workLen = 0; - } - - if (ctx->dataIdx >= (int)sizeof(ctx->data) || - ctx->dataLen > (int)sizeof(ctx->data) || - ctx->dataLen < ctx->dataIdx) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", -1); - return -1; - } - - n = ctx->dataLen - ctx->dataIdx; - while (n > 0) { - i = WOLFCRYPT_BIO_write(bio->next_bio, &ctx->data[ctx->dataIdx], n); - if (i <= 0) { - WOLFCRYPT_BIO_copy_next_retry(bio); - return i; - } - - /* mustn't appen, just to be sure */ - if (i > n) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", -1); - return -1; - } - - ctx->dataIdx += i; - n -= i; - - if (ctx->dataIdx > (int)sizeof(ctx->data) || - ctx->dataLen < ctx->dataIdx) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", -1); - return -1; - } - } - - /* at this point all pending data has been written */ - ctx->dataIdx = 0; - ctx->dataLen = 0; - - if (data == NULL || size <= 0) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - while (size > 0) { - n = (size > WOLFCRYPT_B64_BLOCK_SIZE) ? WOLFCRYPT_B64_BLOCK_SIZE : size; - - if (ctx->workLen > 0) { - if (ctx->workLen > WOLFCRYPT_B64_BLOCK_SIZE) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", -1); - return -1; - } - - n = WOLFCRYPT_B64_BLOCK_SIZE - ctx->workLen; - - if (n > size) - n = size; - - XMEMCPY(&ctx->work[ctx->workLen], data, n); - ctx->workLen += n; - ret += n; - if (ctx->workLen < WOLFCRYPT_B64_BLOCK_SIZE) - break; - - ctx->dataLen = sizeof(ctx->data); - - if (WOLFCRYPT_BIO_get_flags(bio) & BIO_FLAGS_BASE64_NO_NL) - Base64_Encode_NoNl((const byte *)ctx->work, ctx->workLen, - (byte *)ctx->data, - (word32 *)&ctx->dataLen); - else - Base64_Encode((const byte *)ctx->work, ctx->workLen, - (byte *)ctx->data, (word32 *)&ctx->dataLen); - - if (ctx->dataLen > (int)sizeof(ctx->data) || - ctx->dataLen < ctx->dataIdx) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", -1); - return -1; - } - - ctx->workLen = 0; - } - else { - /* keep data and wait for more before encoding */ - if (n < WOLFCRYPT_B64_BLOCK_SIZE) { - XMEMCPY(ctx->work, data, n); - ctx->workLen = n; - ret += n; - break; - } - n -= n % WOLFCRYPT_B64_BLOCK_SIZE; - - ctx->dataLen = sizeof(ctx->data); - - if (WOLFCRYPT_BIO_get_flags(bio) & BIO_FLAGS_BASE64_NO_NL) - Base64_Encode_NoNl((const byte *)data, n, - (byte *)ctx->data, - (word32 *)&ctx->dataLen); - else - Base64_Encode((const byte *)data, n, - (byte *)ctx->data, (word32 *)&ctx->dataLen); - - if (ctx->dataLen > (int)sizeof(ctx->data) || - ctx->dataLen < ctx->dataIdx) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", -1); - return -1; - } - - ret += n; - } - - size -= n; - data += n; - - ctx->dataIdx = 0; - n = ctx->dataLen; - while (n > 0) { - i = WOLFCRYPT_BIO_write(bio->next_bio, - &(ctx->data[ctx->dataIdx]), n); - if (i <= 0) { - WOLFCRYPT_BIO_copy_next_retry(bio); - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", !ret ? i : ret); - return (!ret ? i : ret); - } - - if (i > n) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", -1); - return -1; - } - - n -= i; - ctx->dataIdx += i; - - if (ctx->dataLen > (int)sizeof(ctx->data) || - ctx->dataLen < ctx->dataIdx) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", -1); - return -1; - } - } - - ctx->dataLen = 0; - ctx->dataIdx = 0; - } - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", ret); - - return ret; -} - -static long WOLFCRYPT_BIO_b64_ctrl(WOLFCRYPT_BIO *bio, - int cmd, long num, void *ptr) -{ - WOLFCRYPT_BIO_F_B64_CTX *ctx; - long ret = 1; - int i; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_b64_ctrl"); - - if (bio == NULL || bio->ptr == NULL || bio->next_bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - ctx = (WOLFCRYPT_BIO_F_B64_CTX *)bio->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - ctx->cont = 1; - ctx->start = 1; - ctx->encode = WOLFCRYPT_B64_NONE; - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - - case BIO_CTRL_EOF: - ret = (ctx->cont <= 0 ? 1 : - WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr)); - break; - - case BIO_CTRL_WPENDING: - if (ctx->dataLen < ctx->dataIdx) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", -1); - return -1; - } - - ret = ctx->dataLen - ctx->dataIdx; - if (!ret && (ctx->encode != WOLFCRYPT_B64_NONE) && - (ctx->workLen != 0)) - ret = 1; - else if (ret <= 0) - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - - case BIO_CTRL_PENDING: - if (ctx->dataLen < ctx->dataIdx) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", -1); - return -1; - } - - ret = ctx->dataLen - ctx->dataIdx; - if (ret <= 0) - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - - case BIO_CTRL_FLUSH: - /* do a final write */ - again: - while (ctx->dataLen != ctx->dataIdx) { - i = WOLFCRYPT_BIO_b64_write(bio, NULL, 0); - if (i < 0) - return i; - } - - if (ctx->workLen != 0) { - ctx->dataLen = sizeof(ctx->data); - - if (WOLFCRYPT_BIO_get_flags(bio) & BIO_FLAGS_BASE64_NO_NL) - Base64_Encode_NoNl((const byte *)ctx->work, ctx->workLen, - (byte *)ctx->data, - (word32 *)&ctx->dataLen); - else { - Base64_Encode((const byte *)ctx->work, ctx->workLen, - (byte *)ctx->data, (word32 *)&ctx->dataLen); - - if (ctx->dataLen > (int)sizeof(ctx->data)) { - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_write", -1); - return -1; - } - } - - ctx->dataIdx = 0; - ctx->workLen = 0; - - goto again; - } - - /* Finally flush the underlying BIO */ - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - - case BIO_C_DO_STATE_MACHINE: - WOLFCRYPT_BIO_clear_retry_flags(bio); - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - WOLFCRYPT_BIO_copy_next_retry(bio); - break; - - case BIO_CTRL_DUP: - break; - - case BIO_CTRL_INFO: - case BIO_CTRL_GET: - case BIO_CTRL_SET: - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - - default: - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - } - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_b64_ctrl", (int)ret); - return ret; -} - -static long WOLFCRYPT_BIO_b64_callback_ctrl(WOLFCRYPT_BIO *bio, - int cmd, WOLFCRYPT_BIO_info_cb *fp) -{ - if (bio == NULL || bio->next_bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - WOLFSSL_ENTER("WOLFCRYPT_BIO_b64_callback_ctrl"); - - return WOLFCRYPT_BIO_callback_ctrl(bio->next_bio, cmd, fp); -} - -static int WOLFCRYPT_BIO_b64_puts(WOLFCRYPT_BIO *bio, const char *str) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_b64_puts"); - - if (bio == NULL || str == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - return WOLFCRYPT_BIO_b64_write(bio, str, (int)strlen(str)); -} - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_f_buff.c b/wolfcrypt/src/bio_f_buff.c deleted file mode 100644 index 255325be5..000000000 --- a/wolfcrypt/src/bio_f_buff.c +++ /dev/null @@ -1,583 +0,0 @@ -/* bio_f_buff.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include -#include - -typedef struct { - /*- - * Buffers are setup like this: - * - * <---------------------- size -----------------------> - * +---------------------------------------------------+ - * | consumed | remaining | free space | - * +---------------------------------------------------+ - * <-- off --><------- len -------> - */ - - /* input buffer */ - char *in; /* the char array */ - int inSz; /* how big is the input buffer */ - int inLen; /* how many bytes are in it */ - int inIdx; /* write/read offset */ - - /* output buffer */ - char *out; /* the char array */ - int outSz; /* how big is the output buffer */ - int outLen; /* how many bytes are in it */ - int outIdx; /* write/read offset */ - -} WOLFCRYPT_BIO_F_BUFFER_CTX; - -/* OpenSSL default value */ -#define WOLFSSL_F_BUFFER_SIZE_DEFAULT 4096 - -static int WOLFCRYPT_BIO_buffer_write(WOLFCRYPT_BIO *bio, - const char *buf, int size); -static int WOLFCRYPT_BIO_buffer_read(WOLFCRYPT_BIO *bio, char *buf, int size); -static int WOLFCRYPT_BIO_buffer_puts(WOLFCRYPT_BIO *bio, const char *str); -static int WOLFCRYPT_BIO_buffer_gets(WOLFCRYPT_BIO *bio, char *buf, int size); -static long WOLFCRYPT_BIO_buffer_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr); -static int WOLFCRYPT_BIO_buffer_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_buffer_free(WOLFCRYPT_BIO *bio); -static long WOLFCRYPT_BIO_buffer_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, - WOLFCRYPT_BIO_info_cb *fp); - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_buffer_method = { - BIO_TYPE_BUFFER, - "Buffer", - WOLFCRYPT_BIO_buffer_write, - WOLFCRYPT_BIO_buffer_read, - WOLFCRYPT_BIO_buffer_puts, - WOLFCRYPT_BIO_buffer_gets, - WOLFCRYPT_BIO_buffer_ctrl, - WOLFCRYPT_BIO_buffer_new, - WOLFCRYPT_BIO_buffer_free, - WOLFCRYPT_BIO_buffer_callback_ctrl, -}; - - -static long WOLFCRYPT_BIO_buffer_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, - WOLFCRYPT_BIO_info_cb *fp) -{ - if (bio == NULL || bio->next_bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - return WOLFCRYPT_BIO_callback_ctrl(bio->next_bio, cmd, fp); -} - -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_f_buffer(void) -{ - return (&WOLFCRYPT_BIO_buffer_method); -} - -static int WOLFCRYPT_BIO_buffer_new(WOLFCRYPT_BIO *bio) -{ - WOLFCRYPT_BIO_F_BUFFER_CTX *ctx; - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - bio->ptr = (WOLFCRYPT_BIO_F_BUFFER_CTX *) - XMALLOC(sizeof(WOLFCRYPT_BIO_F_BUFFER_CTX), - 0, DYNAMIC_TYPE_OPENSSL); - if (bio->ptr == NULL) { - WOLFSSL_ERROR(MEMORY_E); - return 0; - } - - ctx = (WOLFCRYPT_BIO_F_BUFFER_CTX *)bio->ptr; - - ctx->in = (char *)XMALLOC(WOLFSSL_F_BUFFER_SIZE_DEFAULT, 0, - DYNAMIC_TYPE_OPENSSL); - if (ctx->in == NULL) { - XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); - WOLFSSL_ERROR(MEMORY_E); - return 0; - } - - ctx->out = (char *)XMALLOC(WOLFSSL_F_BUFFER_SIZE_DEFAULT, 0, - DYNAMIC_TYPE_OPENSSL); - if (ctx->out == NULL) { - XFREE(ctx->in, 0, DYNAMIC_TYPE_OPENSSL); - XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); - WOLFSSL_ERROR(MEMORY_E); - return 0; - } - - ctx->inSz = WOLFSSL_F_BUFFER_SIZE_DEFAULT; - ctx->inLen = 0; - ctx->inIdx = 0; - ctx->outSz = WOLFSSL_F_BUFFER_SIZE_DEFAULT; - ctx->outLen = 0; - ctx->outIdx = 0; - - bio->init = 1; - bio->flags = 0; - return 1; -} - -static int WOLFCRYPT_BIO_buffer_free(WOLFCRYPT_BIO *bio) -{ - WOLFCRYPT_BIO_F_BUFFER_CTX *ctx; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_buffer_free"); - - if (bio == NULL) - return 0; - - if (!bio->init || bio->ptr == NULL) - return 1; - - ctx = (WOLFCRYPT_BIO_F_BUFFER_CTX *)bio->ptr; - - if (ctx->in != NULL) { - XFREE(ctx->in, 0, DYNAMIC_TYPE_OPENSSL); - ctx->in = NULL; - } - - if (ctx->out != NULL) { - XFREE(ctx->out, 0, DYNAMIC_TYPE_OPENSSL); - ctx->out = NULL; - } - - XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); - bio->ptr = NULL; - - bio->init = 0; - bio->flags = 0; - return 1; -} - -static int WOLFCRYPT_BIO_buffer_read(WOLFCRYPT_BIO *bio, char *data, int size) -{ - int i, num = 0; - WOLFCRYPT_BIO_F_BUFFER_CTX *ctx; - - if (bio == NULL || !bio->init || - bio->ptr == NULL || bio->next_bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - - ctx = (WOLFCRYPT_BIO_F_BUFFER_CTX *)bio->ptr; - - for (;;) { - i = ctx->inLen; - if (i != 0) { - if (i > size) - i = size; - XMEMCPY(data, &(ctx->in[ctx->inIdx]), i); - ctx->inIdx += i; - ctx->inLen -= i; - num += i; - if (size == i) - return num; - size -= i; - data += i; - } - - /* case of partial read */ - if (size > ctx->inSz) { - for (;;) { - i = WOLFCRYPT_BIO_read(bio->next_bio, data, size); - if (i <= 0) { - WOLFCRYPT_BIO_copy_next_retry(bio); - if (i < 0) - return (num > 0 ? num : i); - else if (i == 0) - return num; - } - num += i; - - if (size == i) - return num; - data += i; - size -= i; - } - } - - /* we are going to be doing some buffering */ - i = WOLFCRYPT_BIO_read(bio->next_bio, ctx->in, ctx->inSz); - if (i <= 0) { - WOLFCRYPT_BIO_copy_next_retry(bio); - if (i < 0) - return (num > 0 ? num : i); - if (i == 0) - return num; - } - ctx->inIdx = 0; - ctx->inLen = i; - } - - return 1; -} - -static int WOLFCRYPT_BIO_buffer_write(WOLFCRYPT_BIO *bio, - const char *data, int size) -{ - int i, num = 0; - WOLFCRYPT_BIO_F_BUFFER_CTX *ctx; - - if (bio == NULL || !bio->init || bio->ptr == NULL || - bio->next_bio == NULL || size <= 0) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - - ctx = (WOLFCRYPT_BIO_F_BUFFER_CTX *)bio->ptr; - - for (;;) { - i = ctx->outSz - (ctx->outLen + ctx->outIdx); - - /* add to buffer and return */ - if (i >= size) { - XMEMCPY(&(ctx->out[ctx->outIdx + ctx->outLen]), data, size); - ctx->outLen += size; - return (num + size); - } - - /* stuff already in buffer, so add to it first, then flush */ - if (ctx->outLen != 0) { - if (i > 0) { - XMEMCPY(&(ctx->out[ctx->outIdx + ctx->outLen]), data, i); - data += i; - size -= i; - num += i; - ctx->outLen += i; - } - - /* we now have a full buffer needing flushing */ - do { - i = WOLFCRYPT_BIO_write(bio->next_bio, - &(ctx->out[ctx->outIdx]), ctx->outLen); - if (i <= 0) { - WOLFCRYPT_BIO_copy_next_retry(bio); - - if (i < 0) - return (num > 0 ? num : i); - if (i == 0) - return num; - } - - ctx->outIdx += i; - ctx->outLen -= i; - - } while (ctx->outLen != 0); - } - - ctx->outIdx = 0; - - /* we now have size bytes to write */ - while (size >= ctx->outSz) { - i = WOLFCRYPT_BIO_write(bio->next_bio, data, size); - if (i <= 0) { - WOLFCRYPT_BIO_copy_next_retry(bio); - if (i < 0) - return (num > 0 ? num : i); - if (i == 0) - return num; - } - num += i; - data += i; - size -= i; - if (size == 0) - return num; - } - } - - return 1; -} - -static long WOLFCRYPT_BIO_buffer_ctrl(WOLFCRYPT_BIO *bio, - int cmd, long num, void *ptr) -{ - - int i, *ip, ibs, obs; - long ret = 1; - WOLFCRYPT_BIO_F_BUFFER_CTX *ctx; - - if (bio == NULL || bio->ptr == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - ctx = (WOLFCRYPT_BIO_F_BUFFER_CTX *)bio->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - ctx->inLen = 0; - ctx->inIdx = 0; - ctx->outLen = 0; - ctx->outIdx = 0; - - if (bio->next_bio == NULL) - return 0; - - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - - case BIO_CTRL_INFO: - ret = (long)ctx->outLen; - break; - - case BIO_C_GET_BUFF_NUM_LINES: - ret = 0; - for (i = 0; i < ctx->inLen; i++) { - if (ctx->in[ctx->inIdx + i] == '\n') - ret++; - } - break; - - case BIO_CTRL_WPENDING: - ret = (long)ctx->outLen; - if (ret == 0) { - if (bio->next_bio == NULL) - return 0; - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - } - break; - - case BIO_CTRL_PENDING: - ret = (long)ctx->inLen; - if (ret == 0) { - if (bio->next_bio == NULL) - return 0; - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - } - break; - - case BIO_C_SET_BUFF_READ_DATA: - if (num > ctx->inSz) { - ctx->in = XREALLOC(ctx->in, num, 0, DYNAMIC_TYPE_OPENSSL); - if (ctx->in == NULL) { - WOLFSSL_ERROR(MEMORY_E); - return 0; - } - } - - ctx->inIdx = 0; - ctx->inLen = (int)num; - XMEMCPY(ctx->in, ptr, num); - ret = 1; - break; - - case BIO_C_SET_BUFF_SIZE: - if (ptr != NULL) { - ip = (int *)ptr; - if (*ip == 0) { - ibs = (int)num; - obs = ctx->outSz; - } else { - ibs = ctx->inSz; - obs = (int)num; - } - } else { - ibs = (int)num; - obs = (int)num; - } - - if ((ibs > WOLFSSL_F_BUFFER_SIZE_DEFAULT) && (ibs != ctx->inSz)) { - ctx->in = XREALLOC(ctx->in, num, 0, DYNAMIC_TYPE_OPENSSL); - if (ctx->in == NULL) { - WOLFSSL_ERROR(MEMORY_E); - return 0; - } - - ctx->inIdx = 0; - ctx->inLen = 0; - ctx->inSz = ibs; - } - - if ((obs > WOLFSSL_F_BUFFER_SIZE_DEFAULT) && (obs != ctx->outSz)) { - ctx->out = XREALLOC(ctx->out, num, 0, DYNAMIC_TYPE_OPENSSL); - if (ctx->out == NULL) { - WOLFSSL_ERROR(MEMORY_E); - return 0; - } - - ctx->outIdx = 0; - ctx->outLen = 0; - ctx->outSz = obs; - } - break; - - case BIO_C_DO_STATE_MACHINE: - if (bio->next_bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - WOLFCRYPT_BIO_copy_next_retry(bio); - break; - - case BIO_CTRL_FLUSH: - if (bio->next_bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - if (ctx->outLen <= 0) { - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - } - - for (;;) { - WOLFCRYPT_BIO_clear_retry_flags(bio); - if (ctx->outLen > 0) { - ret = WOLFCRYPT_BIO_write(bio->next_bio, - &(ctx->out[ctx->outIdx]), ctx->outLen); - WOLFCRYPT_BIO_copy_next_retry(bio); - if (ret <= 0) - return ret; - ctx->outIdx += ret; - ctx->outLen -= ret; - } else { - ctx->outLen = 0; - ctx->outIdx = 0; - ret = 1; - break; - } - } - - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - - case BIO_CTRL_DUP: - ret = WOLFCRYPT_BIO_set_read_buffer_size((WOLFCRYPT_BIO *)ptr, - ctx->inSz); - if (!ret) - break; - - ret = WOLFCRYPT_BIO_set_write_buffer_size((WOLFCRYPT_BIO *)ptr, - ctx->outSz); - if (!ret) - break; - - ret = 1; - break; - - default: - if (bio->next_bio == NULL) - return 0; - - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - } - - return ret; -} - -static int WOLFCRYPT_BIO_buffer_gets(WOLFCRYPT_BIO *bio, char *buf, int size) -{ - WOLFCRYPT_BIO_F_BUFFER_CTX *ctx; - int num = 0, i, flag; - - if (bio == NULL || bio->ptr == NULL || buf == NULL || size <= 0) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - - ctx = (WOLFCRYPT_BIO_F_BUFFER_CTX *)bio->ptr; - - /* to put end of string */ - size--; - - for (;;) { - if (ctx->inLen > 0) { - // p = &(ctx->in[ctx->inIdx]); - flag = 0; - - for (i = 0; (i < ctx->inLen) && (i < size); i++) { - *(buf++) = ctx->in[ctx->inIdx+i]; - if (ctx->in[ctx->inIdx+i] == '\n') { - flag = 1; - i++; - break; - } - } - num += i; - size -= i; - ctx->inLen -= i; - ctx->inIdx += i; - if (flag || !size) { - *buf = '\0'; - return num; - } - } else { - i = WOLFCRYPT_BIO_read(bio->next_bio, ctx->in, ctx->inSz); - if (i <= 0) { - WOLFCRYPT_BIO_copy_next_retry(bio); - *buf = '\0'; - if (i < 0) - return (num > 0 ? num : i); - if (i == 0) - return num; - } - ctx->inLen = i; - ctx->inIdx = 0; - } - } - - return i; -} - -static int WOLFCRYPT_BIO_buffer_puts(WOLFCRYPT_BIO *bio, const char *str) -{ - if (bio == NULL || str == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - return WOLFCRYPT_BIO_buffer_write(bio, str, (int)strlen(str)); -} - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_f_cipher.c b/wolfcrypt/src/bio_f_cipher.c deleted file mode 100644 index e7d040c22..000000000 --- a/wolfcrypt/src/bio_f_cipher.c +++ /dev/null @@ -1,456 +0,0 @@ -/* bio_f_cipher.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include -#include -#include - -typedef struct { - int dataLen; - int dataIdx; - int cont; - int finished; - int ok; /* bad decrypt */ - - WOLFSSL_EVP_CIPHER_CTX cipher; - /* - * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return - * up to a block more data than is presented to it - */ - -#define WOLFCRYPT_ENC_BLOCK_SIZE 128 -#define WOLFCRYPT_BUF_OFFSET 64 - - byte data[WOLFCRYPT_ENC_BLOCK_SIZE + WOLFCRYPT_BUF_OFFSET + 2]; -} WOLFCRYPT_BIO_ENC_CTX; - - -static int WOLFCRYPT_BIO_cipher_write(WOLFCRYPT_BIO *bio, - const char *buf, int size); -static int WOLFCRYPT_BIO_cipher_read(WOLFCRYPT_BIO *bio, char *buf, int size); -static long WOLFCRYPT_BIO_cipher_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr); -static int WOLFCRYPT_BIO_cipher_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_cipher_free(WOLFCRYPT_BIO *bio); -static long WOLFCRYPT_BIO_cipher_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, - WOLFCRYPT_BIO_info_cb *fp); - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_cipher_method = { - BIO_TYPE_CIPHER, - "Cipher", - WOLFCRYPT_BIO_cipher_write, - WOLFCRYPT_BIO_cipher_read, - NULL, /* puts */ - NULL, /* gets */ - WOLFCRYPT_BIO_cipher_ctrl, - WOLFCRYPT_BIO_cipher_new, - WOLFCRYPT_BIO_cipher_free, - WOLFCRYPT_BIO_cipher_callback_ctrl, -}; - -static long WOLFCRYPT_BIO_cipher_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, - WOLFCRYPT_BIO_info_cb *fp) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_cipher_callback_ctrl"); - if (bio == NULL || bio->next_bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - return WOLFCRYPT_BIO_callback_ctrl(bio->next_bio, cmd, fp); -} - -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_f_cipher(void) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_f_cipher"); - return (&WOLFCRYPT_BIO_cipher_method); -} - -void WOLFCRYPT_BIO_set_cipher(WOLFCRYPT_BIO *bio, - const WOLFSSL_EVP_CIPHER *cipher, - const unsigned char *key, - const unsigned char *iv, int enc) -{ - WOLFCRYPT_BIO_ENC_CTX *ctx; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_set_cipher"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return; - } - - - if ((bio->callback != NULL) && - bio->callback(bio, BIO_CB_CTRL, (const char *)cipher, - BIO_CTRL_SET, enc, 0) <= 0) { - WOLFSSL_ERROR(BIO_CALLBACK_E); - return; - } - - bio->init = 1; - - ctx = (WOLFCRYPT_BIO_ENC_CTX *)bio->ptr; - - wolfSSL_EVP_CipherInit(&(ctx->cipher), cipher, (unsigned char *)key, - (unsigned char *)iv, enc); - - if ((bio->callback != NULL) && - bio->callback(bio, BIO_CB_CTRL, (const char *)cipher, - BIO_CTRL_SET, enc, 1) <= 0) - WOLFSSL_ERROR(BIO_CALLBACK_E); -} - -static int WOLFCRYPT_BIO_cipher_new(WOLFCRYPT_BIO *bio) -{ - WOLFCRYPT_BIO_ENC_CTX *ctx; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_cipher_new"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - bio->ptr = (WOLFCRYPT_BIO_ENC_CTX *)XMALLOC(sizeof(WOLFCRYPT_BIO_ENC_CTX), - 0, DYNAMIC_TYPE_OPENSSL); - if (bio->ptr == NULL) { - WOLFSSL_ERROR(MEMORY_E); - return -1; - } - - ctx = (WOLFCRYPT_BIO_ENC_CTX *)bio->ptr; - - wolfSSL_EVP_CIPHER_CTX_init(&ctx->cipher); - - ctx->dataLen = 0; - ctx->dataIdx = 0; - ctx->cont = 1; - ctx->finished = 0; - ctx->ok = 1; - - bio->init = 0; - bio->flags = 0; - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_cipher_new", 1); - return 1; -} - -static int WOLFCRYPT_BIO_cipher_free(WOLFCRYPT_BIO *bio) -{ - WOLFCRYPT_BIO_ENC_CTX *ctx; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_cipher_free"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - ctx = (WOLFCRYPT_BIO_ENC_CTX *)bio->ptr; - - wolfSSL_EVP_CIPHER_CTX_cleanup(&(ctx->cipher)); - - XMEMSET(bio->ptr, 0, sizeof(WOLFCRYPT_BIO_ENC_CTX)); - XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); - bio->ptr = NULL; - - bio->init = 0; - bio->flags = 0; - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_cipher_free", 1); - return 1; -} - -static int WOLFCRYPT_BIO_cipher_read(WOLFCRYPT_BIO *bio, char *data, int size) -{ - int ret = 0, i; - WOLFCRYPT_BIO_ENC_CTX *ctx; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_cipher_read"); - - if (bio == NULL || data == NULL || - bio->ptr == NULL || bio->next_bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - ctx = (WOLFCRYPT_BIO_ENC_CTX *)bio->ptr; - - /* First check if there are bytes decoded/encoded */ - if (ctx->dataLen > 0) { - i = ctx->dataLen - ctx->dataIdx; - if (i > size) - i = size; - - XMEMCPY(data, &ctx->data[ctx->dataIdx], i); - ret = i; - data += i; - size -= i; - ctx->dataIdx += i; - - /* all read */ - if (ctx->dataLen == ctx->dataIdx) - ctx->dataLen = ctx->dataIdx = 0; - } - - /* - * At this point, we have room of size bytes and an empty buffer, so we - * should read in some more. - */ - while (size > 0) { - if (ctx->cont <= 0) - break; - - /* read in at IV offset, read the EVP_Cipher documentation about why - */ - i = WOLFCRYPT_BIO_read(bio->next_bio, &ctx->data[WOLFCRYPT_BUF_OFFSET], - WOLFCRYPT_ENC_BLOCK_SIZE); - if (i <= 0) { - /* Should be continue next time we are called ? */ - if (!WOLFCRYPT_BIO_should_retry(bio->next_bio)) { - ctx->cont = i; - - i = wolfSSL_EVP_CipherFinal(&ctx->cipher, ctx->data, - &ctx->dataLen); - - ctx->ok = i; - ctx->dataIdx = 0; - } else { - if (!ret) - ret = i; - break; - } - } else { - wolfSSL_EVP_CipherUpdate(&ctx->cipher, - ctx->data, &ctx->dataLen, - &ctx->data[WOLFCRYPT_BUF_OFFSET], i); - ctx->cont = 1; - - if (!ctx->dataLen) - continue; - } - - i = (ctx->dataLen <= size ? ctx->dataLen : size); - if (i <= 0) - break; - - XMEMCPY(data, ctx->data, i); - - ret += i; - ctx->dataIdx = i; - size -= i; - data += i; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - WOLFCRYPT_BIO_copy_next_retry(bio); - - return (!ret ? ctx->cont : ret); -} - -static int WOLFCRYPT_BIO_cipher_write(WOLFCRYPT_BIO *bio, - const char *data, int size) -{ - int ret, n, i; - WOLFCRYPT_BIO_ENC_CTX *ctx; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_cipher_write"); - - if (bio == NULL || bio->ptr == NULL || bio->next_bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - ctx = (WOLFCRYPT_BIO_ENC_CTX *)bio->ptr; - - ret = size; - - WOLFCRYPT_BIO_clear_retry_flags(bio); - - n = ctx->dataLen - ctx->dataIdx; - while (n > 0) { - i = WOLFCRYPT_BIO_write(bio->next_bio, &ctx->data[ctx->dataIdx], n); - if (i <= 0) { - WOLFCRYPT_BIO_copy_next_retry(bio); - return i; - } - ctx->dataIdx += i; - n -= i; - } - - /* at this point all pending data has been written - * return if we haven't new data to write */ - if (data == NULL || size <= 0) - return 0; - - while (size > 0) { - n = (size > WOLFCRYPT_ENC_BLOCK_SIZE ? WOLFCRYPT_ENC_BLOCK_SIZE : size); - wolfSSL_EVP_CipherUpdate(&ctx->cipher, ctx->data, &ctx->dataLen, - (byte *)data, n); - - size -= n; - data += n; - - ctx->dataIdx = 0; - n = ctx->dataLen; - while (n > 0) { - i = WOLFCRYPT_BIO_write(bio->next_bio, - &ctx->data[ctx->dataIdx], n); - if (i <= 0) { - WOLFCRYPT_BIO_copy_next_retry(bio); - return (ret == size ? i : ret - size); - } - n -= i; - ctx->dataIdx += i; - } - ctx->dataLen = 0; - ctx->dataIdx = 0; - } - - WOLFCRYPT_BIO_copy_next_retry(bio); - return ret; -} - -static long WOLFCRYPT_BIO_cipher_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr) -{ - WOLFCRYPT_BIO_ENC_CTX *ctx; - long ret = 1; - int i; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_cipher_ctrl"); - - if (bio == NULL || bio->ptr == NULL || bio->next_bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - ctx = (WOLFCRYPT_BIO_ENC_CTX *)bio->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - ctx->ok = 1; - ctx->finished = 0; - wolfSSL_EVP_CipherInit(&ctx->cipher, NULL, NULL, NULL, - ctx->cipher.enc); - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - - case BIO_CTRL_EOF: /* More to read */ - if (ctx->cont <= 0) - ret = 1; - else - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - - case BIO_CTRL_WPENDING: - case BIO_CTRL_PENDING: - ret = ctx->dataLen - ctx->dataIdx; - if (ret <= 0) - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - - case BIO_CTRL_FLUSH: -loop: - while (ctx->dataLen != ctx->dataIdx) { - i = WOLFCRYPT_BIO_cipher_write(bio, NULL, 0); - if (i < 0) - return i; - } - - if (!ctx->finished) { - ctx->finished = 1; - ctx->dataIdx = 0; - - ret = wolfSSL_EVP_CipherFinal(&ctx->cipher, ctx->data, - &ctx->dataLen); - ctx->ok = (int)ret; - if (ret <= 0) - break; - - goto loop; - } - - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - - case BIO_C_GET_CIPHER_STATUS: - ret = (long)ctx->ok; - break; - - case BIO_C_DO_STATE_MACHINE: - WOLFCRYPT_BIO_clear_retry_flags(bio); - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - WOLFCRYPT_BIO_copy_next_retry(bio); - break; - - case BIO_C_GET_CIPHER_CTX: - { - WOLFSSL_EVP_CIPHER_CTX **c_ctx; - c_ctx = (WOLFSSL_EVP_CIPHER_CTX **)ptr; - *c_ctx = &ctx->cipher; - bio->init = 1; - } - break; - - case BIO_CTRL_DUP: - { - WOLFCRYPT_BIO *dbio; - WOLFCRYPT_BIO_ENC_CTX *dctx; - - dbio = (WOLFCRYPT_BIO *)ptr; - dctx = (WOLFCRYPT_BIO_ENC_CTX *)dbio->ptr; - - wolfSSL_EVP_CIPHER_CTX_init(&dctx->cipher); - ret = wolfSSL_EVP_CIPHER_CTX_copy(&dctx->cipher, &ctx->cipher); - if (ret) - dbio->init = 1; - } - break; - - default: - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - } - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_cipher_ctrl", (int)ret); - return ret; -} - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_f_dgst.c b/wolfcrypt/src/bio_f_dgst.c deleted file mode 100644 index f67367b34..000000000 --- a/wolfcrypt/src/bio_f_dgst.c +++ /dev/null @@ -1,311 +0,0 @@ -/* bio_f_dgst.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include -#include -#include - -static int WOLFCRYPT_BIO_digest_write(WOLFCRYPT_BIO *bio, - const char *buf, int size); -static int WOLFCRYPT_BIO_digest_read(WOLFCRYPT_BIO *bio, char *buf, int size); -static int WOLFCRYPT_BIO_digest_gets(WOLFCRYPT_BIO *bio, char *buf, int size); -static long WOLFCRYPT_BIO_digest_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr); -static int WOLFCRYPT_BIO_digest_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_digest_free(WOLFCRYPT_BIO *bio); -static long WOLFCRYPT_BIO_digest_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, - WOLFCRYPT_BIO_info_cb *fp); - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_digest_method = { - BIO_TYPE_MD, - "Message digest", - WOLFCRYPT_BIO_digest_write, - WOLFCRYPT_BIO_digest_read, - NULL, /* puts */ - WOLFCRYPT_BIO_digest_gets, - WOLFCRYPT_BIO_digest_ctrl, - WOLFCRYPT_BIO_digest_new, - WOLFCRYPT_BIO_digest_free, - WOLFCRYPT_BIO_digest_callback_ctrl, -}; - -static long WOLFCRYPT_BIO_digest_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, - WOLFCRYPT_BIO_info_cb *fp) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_digest_callback_ctrl"); - if (bio == NULL || bio->next_bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - return WOLFCRYPT_BIO_callback_ctrl(bio->next_bio, cmd, fp); -} - -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_f_md(void) -{ - return (&WOLFCRYPT_BIO_digest_method); -} - -static int WOLFCRYPT_BIO_digest_new(WOLFCRYPT_BIO *bio) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_digest_new"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - bio->ptr = (WOLFSSL_EVP_MD_CTX *)XMALLOC(sizeof(WOLFSSL_EVP_MD_CTX), - 0, DYNAMIC_TYPE_OPENSSL); - if (bio->ptr == NULL) { - WOLFSSL_ERROR(MEMORY_E); - return -1; - } - - wolfSSL_EVP_MD_CTX_init((WOLFSSL_EVP_MD_CTX *)bio->ptr); - - bio->init = 0; - bio->flags = 0; - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_digest_new", 1); - return 1; -} - -static int WOLFCRYPT_BIO_digest_free(WOLFCRYPT_BIO *bio) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_digest_free"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - wolfSSL_EVP_MD_CTX_cleanup((WOLFSSL_EVP_MD_CTX *)bio->ptr); - - XMEMSET(bio->ptr, 0, sizeof(WOLFSSL_EVP_MD_CTX)); - XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); - bio->ptr = NULL; - - bio->init = 0; - bio->flags = 0; - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_digest_free", 1); - return 1; -} - -static int WOLFCRYPT_BIO_digest_read(WOLFCRYPT_BIO *bio, char *data, int size) -{ - WOLFSSL_EVP_MD_CTX *ctx; - int ret = 0; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_digest_read"); - - if (bio == NULL || bio->ptr == NULL || bio->next_bio == NULL || - data == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - ctx = (WOLFSSL_EVP_MD_CTX *)bio->ptr; - - ret = WOLFCRYPT_BIO_read(bio->next_bio, data, size); - if (bio->init && ret > 0) { - if (wolfSSL_EVP_DigestUpdate(ctx, data, (word32)ret) != SSL_SUCCESS) { - WOLFSSL_ERROR(BIO_DGST_UPDATE_E); - return -1; - } - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - WOLFCRYPT_BIO_copy_next_retry(bio); - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_digest_read", ret); - return ret; -} - -static int WOLFCRYPT_BIO_digest_write(WOLFCRYPT_BIO *bio, - const char *data, int size) -{ - WOLFSSL_EVP_MD_CTX *ctx; - int ret = 0; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_digest_write"); - - if (bio == NULL || bio->ptr == NULL || data == NULL || size <= 0) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - ctx = (WOLFSSL_EVP_MD_CTX *)bio->ptr; - - ret = WOLFCRYPT_BIO_write(bio->next_bio, data, size); - - if (bio->init && ret > 0) { - if (wolfSSL_EVP_DigestUpdate(ctx, data, (word32)ret) != SSL_SUCCESS) { - WOLFSSL_ERROR(BIO_DGST_UPDATE_E); - WOLFCRYPT_BIO_clear_retry_flags(bio); - return -1; - } - } - - if (bio->next_bio != NULL) { - WOLFCRYPT_BIO_clear_retry_flags(bio); - WOLFCRYPT_BIO_copy_next_retry(bio); - } - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_digest_write", ret); - - return ret; -} - -static long WOLFCRYPT_BIO_digest_ctrl(WOLFCRYPT_BIO *bio, - int cmd, long num, void *ptr) -{ - WOLFSSL_EVP_MD_CTX *ctx; - long ret = 1; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_digest_ctrl"); - - if (bio == NULL || bio->ptr == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - ctx = (WOLFSSL_EVP_MD_CTX *)bio->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - if (bio->init) - ret = wolfSSL_EVP_DigestInit(ctx, ctx->digest); - else - ret = 0; - - if (ret > 0) - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - - case BIO_C_GET_MD: - if (bio->init) { - const WOLFSSL_EVP_MD **pmd; - pmd = (const WOLFSSL_EVP_MD **)ptr; - *pmd = ctx->digest; - } else - ret = 0; - break; - - case BIO_C_GET_MD_CTX: - { - WOLFSSL_EVP_MD_CTX **pctx; - pctx = (WOLFSSL_EVP_MD_CTX **)ptr; - *pctx = ctx; - } - bio->init = 1; - break; - - case BIO_C_SET_MD_CTX: - if (bio->init) - bio->ptr = ptr; - else - ret = 0; - break; - - case BIO_C_DO_STATE_MACHINE: - WOLFCRYPT_BIO_clear_retry_flags(bio); - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - WOLFCRYPT_BIO_copy_next_retry(bio); - break; - - case BIO_C_SET_MD: - ret = wolfSSL_EVP_DigestInit(ctx, (WOLFSSL_EVP_MD *)ptr); - if (ret > 0) - bio->init = 1; - else - WOLFSSL_ERROR(BIO_DGST_INIT_E); - break; - - case BIO_CTRL_DUP: - { - WOLFCRYPT_BIO *dbio; - WOLFSSL_EVP_MD_CTX *dctx; - - dbio = (WOLFCRYPT_BIO *)ptr; - dctx = (WOLFSSL_EVP_MD_CTX *)dbio->ptr; - - ret = wolfSSL_EVP_MD_CTX_copy(dctx, ctx); - if (ret) - bio->init = 1; - } - break; - - default: - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - break; - } - - WOLFSSL_LEAVE("WOLFCRYPT_BIO_digest_ctrl", (int)ret); - return ret; -} - -static int WOLFCRYPT_BIO_digest_gets(WOLFCRYPT_BIO *bio, char *buf, int size) -{ - WOLFSSL_EVP_MD_CTX *ctx; - unsigned int dgstLen = 0; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_digest_gets"); - - if (bio == NULL || bio->ptr == NULL || buf == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - ctx = (WOLFSSL_EVP_MD_CTX *)bio->ptr; - - if (size < ctx->macSize) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - if (wolfSSL_EVP_DigestFinal(ctx, (byte *)buf, &dgstLen) != SSL_SUCCESS) { - WOLFSSL_ERROR(BIO_DGST_FINAL_E); - return -1; - } - - return dgstLen; -} - -#endif /* OPENSSL_EXTRA */ \ No newline at end of file diff --git a/wolfcrypt/src/bio_f_sock.c b/wolfcrypt/src/bio_f_sock.c deleted file mode 100644 index b91984f8d..000000000 --- a/wolfcrypt/src/bio_f_sock.c +++ /dev/null @@ -1,484 +0,0 @@ -/* bio_m_conn.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#ifdef USE_WINDOWS_API -#include -#include -#else -#include -#include -#ifdef SO_NOSIGPIPE -#include -#endif -#endif /* USE_WINDOWS_API */ - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include - -/* Socket Handling */ -#ifndef WOLFSSL_SOCKET_INVALID -#ifdef USE_WINDOWS_API -#define WOLFSSL_SOCKET_INVALID ((SOCKET)INVALID_SOCKET) -#else -#define WOLFSSL_SOCKET_INVALID (0) -#endif -#endif /* WOLFSSL_SOCKET_INVALID */ - -#define MAX_LISTEN 32 - -#ifdef USE_WINDOWS_API -static int wsa_init_done = 0; -#endif - -int WOLFCRYPT_BIO_get_host_ip(const char *str, unsigned char *ip) -{ - struct hostent *he; - unsigned int iip[4]; - - if (WOLFCRYPT_BIO_sock_init() != 1) - return 0; - - /* IP found */ - if (sscanf(str, "%d.%d.%d.%d", &iip[0], &iip[1], &iip[2], &iip[3]) == 4) - { - ip[0] = (iip[0] & 0xff000000) >> 24; - ip[1] = (iip[1] & 0x00ff0000) >> 16; - ip[2] = (iip[2] & 0x0000ff00) >> 8; - ip[3] = (iip[3] & 0x000000ff); - return 1; - } - - /* IP not found, check with a gethostbyname */ - he = gethostbyname(str); - if (he == NULL) { - WOLFSSL_ERROR(BIO_NO_HOSTNAME_E); - return 0; - } - - if (he->h_addrtype != AF_INET) { - WOLFSSL_ERROR(BIO_ADDR_AF_INET_E); - return 0; - } - - XMEMCPY(ip, he->h_addr_list[0], 4); - - return 1; -} - -int WOLFCRYPT_BIO_get_port(const char *str, unsigned short *port_ptr) -{ - int i; - struct servent *s; - - if (str == NULL) { - WOLFSSL_ERROR(BIO_NO_PORT_E); - return 0; - } - - i = atoi(str); - if (i != 0) { - *port_ptr = (unsigned short)i; - return 1; - } - - s = getservbyname(str, "tcp"); - if (s != NULL) { - *port_ptr = ntohs((unsigned short)s->s_port); - return 1; - } - - if (strcmp(str, "http") == 0) - *port_ptr = 80; - else if (strcmp(str, "telnet") == 0) - *port_ptr = 23; - else if (strcmp(str, "socks") == 0) - *port_ptr = 1080; - else if (strcmp(str, "https") == 0) - *port_ptr = 443; - else if (strcmp(str, "ssl") == 0) - *port_ptr = 443; - else if (strcmp(str, "ftp") == 0) - *port_ptr = 21; - else if (strcmp(str, "gopher") == 0) - *port_ptr = 70; - else { - WOLFSSL_ERROR(BIO_SRV_PROTO_E); - return 0; - } - - return 1; -} - -int WOLFCRYPT_BIO_sock_error(int sock) -{ - int j = 0, i; - union { - size_t s; - int i; - } size; - - /* heuristic way to adapt for platforms that expect 64-bit optlen */ - size.s = 0, size.i = sizeof(j); - /* - * Note: under Windows the third parameter is of type (char *) whereas - * under other systems it is (void *) if you don't have a cast it will - * choke the compiler: if you do have a cast then you can either go for - * (char *) or (void *). - */ - i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, (void *)&size); - if (i < 0) - return 1; - - return j; -} - -int WOLFCRYPT_BIO_sock_init(void) -{ -# ifdef USE_WINDOWS_API - static struct WSAData wsa_state; - - if (!wsa_init_done) { - int err; - - wsa_init_done = 1; - memset(&wsa_state, 0, sizeof(wsa_state)); - /* - * Not making wsa_state available to the rest of the code is formally - * wrong. But the structures we use are [beleived to be] invariable - * among Winsock DLLs, while API availability is [expected to be] - * probed at run-time with DSO_global_lookup. - */ - if (WSAStartup(0x0202, &wsa_state) != 0) { - err = WSAGetLastError(); - WOLFSSL_ERROR(BIO_WSASTARTUP_E); - return -1; - } - } -# endif /* USE_WINDOWS_API */ - - return 1; -} - -void WOLFCRYPT_BIO_sock_cleanup(void) -{ -#ifdef USE_WINDOWS_API - if (wsa_init_done) { - wsa_init_done = 0; - WSACleanup(); - } -#endif -} - -int WOLFCRYPT_BIO_get_accept_socket(char *host, int bind_mode) -{ - int ret = 0; - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -#ifdef TEST_IPV6 - struct sockaddr_in6 sa_in6; -#endif - } server, client; - int s = WOLFSSL_SOCKET_INVALID, cs, addrlen; - unsigned char ip[4]; - unsigned short port; - char *str = NULL; - char *h, *p, *e; - unsigned long l; - int err_num; - - if (WOLFCRYPT_BIO_sock_init() != 1) - return WOLFSSL_SOCKET_INVALID; - - str = strdup(host); - if (str == NULL) - return WOLFSSL_SOCKET_INVALID; - - h = p = NULL; - h = str; - for (e = str; *e; e++) { - if (*e == ':') { - p = e; - } else if (*e == '/') { - *e = '\0'; - break; - } - } - if (p) - *p++ = '\0'; /* points at last ':', '::port' is special - * [see below] */ - else - p = h, h = NULL; - - if (!WOLFCRYPT_BIO_get_port(p, &port)) - goto err; - - memset((char *)&server, 0, sizeof(server)); - server.sa_in.sin_family = AF_INET; - server.sa_in.sin_port = htons(port); - addrlen = sizeof(server.sa_in); - - if (h == NULL || strcmp(h, "*") == 0) - server.sa_in.sin_addr.s_addr = INADDR_ANY; - else { - if (!WOLFCRYPT_BIO_get_host_ip(h, &(ip[0]))) - goto err; - l = (unsigned long) - ((unsigned long)ip[0] << 24L) | - ((unsigned long)ip[1] << 16L) | - ((unsigned long)ip[2] << 8L) | - ((unsigned long)ip[3]); - server.sa_in.sin_addr.s_addr = htonl(l); - } - - again: - s = socket(server.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); - if (s == WOLFSSL_SOCKET_INVALID) { - WOLFSSL_ERROR(BIO_CREATE_SOCKET_E); - goto err; - } - -#ifdef SO_REUSEADDR - if (bind_mode == BIO_BIND_REUSEADDR) { - int i = 1; - - ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i)); - bind_mode = BIO_BIND_NORMAL; - } -#endif /* SO_REUSEADDR */ - if (bind(s, &server.sa, addrlen) == -1) { -#ifdef SO_REUSEADDR -#ifdef USE_WINDOWS_API - err_num = WSAGetLastError(); - if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) && - (err_num == WSAEADDRINUSE)) -#else - err_num = errno; - if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) && - (err_num == EADDRINUSE)) -#endif /* USE_WINDOWS_API */ - { - client = server; - if (h == NULL || strcmp(h, "*") == 0) { -#ifdef TEST_IPV6 - if (client.sa.sa_family == AF_INET6) { - XMEMSET(&client.sa_in6.sin6_addr, 0, - sizeof(client.sa_in6.sin6_addr)); - client.sa_in6.sin6_addr.s6_addr[15] = 1; - } - else -#endif - if (client.sa.sa_family == AF_INET) { - client.sa_in.sin_addr.s_addr = htonl(0x7F000001); - } - else - goto err; - } - - cs = socket(client.sa.sa_family, SOCK_STREAM, IPPROTO_TCP); - if (cs != WOLFSSL_SOCKET_INVALID) { - int ii; - ii = connect(cs, &client.sa, addrlen); -#ifdef USE_WINDOWS_API - closesocket(cs); -#else - close(cs); -#endif - if (ii == WOLFSSL_SOCKET_INVALID) { - bind_mode = BIO_BIND_REUSEADDR; -#ifdef USE_WINDOWS_API - closesocket(s); -#else - close(s); -#endif - goto again; - } - } - } -#endif /* SO_REUSEADDR */ - - WOLFSSL_ERROR(BIO_BIND_SOCKET_E); - goto err; - } - - if (listen(s, MAX_LISTEN) == -1) { - WOLFSSL_ERROR(BIO_LISTEN_SOCKET_E); - goto err; - } - - ret = 1; - - err: - - if (str != NULL) - free(str); - - if (!ret && (s != WOLFSSL_SOCKET_INVALID)) { -#ifdef USE_WINDOWS_API - closesocket(s); -#else - close(s); -#endif - s = WOLFSSL_SOCKET_INVALID; - } - - return s; -} - -int WOLFCRYPT_BIO_accept(int sock, char **addr) -{ - int dsock = WOLFSSL_SOCKET_INVALID; - unsigned long l; - - struct { - union { - size_t s; - int i; - } len; - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -#ifdef TEST_IPV6 - struct sockaddr_in sa_in6; -#endif - } from; - } sa; - - sa.len.s = 0; - sa.len.i = sizeof(sa.from); - memset(&sa.from, 0, sizeof(sa.from)); - - dsock = accept(sock, &sa.from.sa, (void *)&sa.len); - if (sizeof(sa.len.i) != sizeof(sa.len.s) && !sa.len.i) { - if (sa.len.s > sizeof(sa.from)) { - WOLFSSL_ERROR(MEMORY_E); - goto end; - } - - sa.len.i = (int)sa.len.s; - } - - if (dsock == WOLFSSL_SOCKET_INVALID) { - if (WOLFCRYPT_BIO_sock_should_retry(dsock)) - return -2; - WOLFSSL_ERROR(BIO_ACCEPT_E); - goto end; - } - - if (addr == NULL || sa.from.sa.sa_family != AF_INET) - goto end; - - if (*addr == NULL) { - *addr = XMALLOC(24, 0, DYNAMIC_TYPE_OPENSSL); - if (*addr == NULL) { - WOLFSSL_ERROR(MEMORY_E); - goto end; - } - } - - l = ntohl(sa.from.sa_in.sin_addr.s_addr); - - XSNPRINTF(*addr, 24, "%d.%d.%d.%d:%d", - (unsigned char)(l >> 24L) & 0xff, - (unsigned char)(l >> 16L) & 0xff, - (unsigned char)(l >> 8L) & 0xff, - (unsigned char)(l) & 0xff, ntohs(sa.from.sa_in.sin_port)); - end: - return dsock; -} - -int WOLFCRYPT_BIO_set_tcp_nsigpipe(int s, int on) -{ - int ret = 0; - -#ifndef USE_WINDOWS_API -#ifdef SO_NOSIGPIPE - ret = setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, &on, sizeof(on)); -#else /* no S_NOSIGPIPE */ - (void) s; - (void) on; - - signal(SIGPIPE, SIG_IGN); -#endif /* S_NOSIGPIPE */ -#endif /* USE_WINDOWS_API */ - - return (ret == 0); -} - -int WOLFCRYPT_BIO_set_tcp_ndelay(int s, int on) -{ - int ret = 0; -#if defined(TCP_NODELAY) -#ifdef SOL_TCP - int opt = SOL_TCP; -#else - int opt = IPPROTO_TCP; -#endif - - ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on)); -#else - (void) s; - (void) on; -#endif /* TCP_NODELAY */ - - return (ret == 0); -} - -int WOLFCRYPT_BIO_socket_nbio(int s, int mode) -{ -#ifdef USE_WINDOWS_API - unsigned long blocking = mode; - int ret = ioctlsocket(s, FIONBIO, &blocking); - return (ret == 0); -#elif defined(WOLFSSL_MDK_ARM) || defined(WOLFSSL_KEIL_TCP_NET) \ -|| defined (WOLFSSL_TIRTOS)|| defined(WOLFSSL_VXWORKS) - /* non blocking not supported, for now */ - return -1; -#else - int flags = fcntl(s, F_GETFL, 0); - if (flags) - flags = fcntl(s, F_SETFL, flags | mode); - return (flags == 0); -#endif -} - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_f_ssl.c b/wolfcrypt/src/bio_f_ssl.c deleted file mode 100644 index 680dc7f4c..000000000 --- a/wolfcrypt/src/bio_f_ssl.c +++ /dev/null @@ -1,725 +0,0 @@ -/* bio_f_ssl.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include -#include - -#include - -typedef struct { - WOLFSSL *ssl; - /* re-negotiate every time the total number of bytes is this size */ - int num_renegotiates; - unsigned long renegotiate_count; - unsigned long byte_count; - unsigned long renegotiate_timeout; - unsigned long last_time; -} WOLFCRYPT_BIO_SSL; - -static int WOLFCRYPT_BIO_ssl_write(WOLFCRYPT_BIO *bio, - const char *data, int size); -static int WOLFCRYPT_BIO_ssl_read(WOLFCRYPT_BIO *bio, char *data, int size); -static int WOLFCRYPT_BIO_ssl_puts(WOLFCRYPT_BIO *bio, const char *str); -static long WOLFCRYPT_BIO_ssl_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr); -static int WOLFCRYPT_BIO_ssl_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_ssl_free(WOLFCRYPT_BIO *bio); -static long WOLFCRYPT_BIO_ssl_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, - WOLFCRYPT_BIO_info_cb *fp); - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_ssl_method = { - BIO_TYPE_SSL, - "SSL", - WOLFCRYPT_BIO_ssl_write, - WOLFCRYPT_BIO_ssl_read, - WOLFCRYPT_BIO_ssl_puts, - NULL, /* gets */ - WOLFCRYPT_BIO_ssl_ctrl, - WOLFCRYPT_BIO_ssl_new, - WOLFCRYPT_BIO_ssl_free, - WOLFCRYPT_BIO_ssl_callback_ctrl, -}; - -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_f_ssl(void) -{ - return (&WOLFCRYPT_BIO_ssl_method); -} - -static int WOLFCRYPT_BIO_ssl_new(WOLFCRYPT_BIO *bio) -{ - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - bio->ptr = (WOLFCRYPT_BIO_SSL *)XMALLOC(sizeof(WOLFCRYPT_BIO_SSL), - 0, DYNAMIC_TYPE_OPENSSL); - if (bio->ptr == NULL) { - WOLFSSL_ERROR(MEMORY_E); - return 0; - } - - XMEMSET(bio->ptr, 0, sizeof(WOLFCRYPT_BIO_SSL)); - - bio->init = 0; - bio->flags = 0; - return 1; -} - -static int WOLFCRYPT_BIO_ssl_free(WOLFCRYPT_BIO *bio) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_ssl_free"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - if (bio->ptr != NULL) { - WOLFCRYPT_BIO_SSL *bssl = (WOLFCRYPT_BIO_SSL *)bio->ptr; - if (bssl->ssl != NULL) { - wolfSSL_shutdown(bssl->ssl); - - if (bio->shutdown && bio->init) { - WOLFSSL_MSG("Free BIO ssl"); - wolfSSL_free(bssl->ssl); - } - } - - XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); - bio->ptr = NULL; - } - - if (bio->shutdown) { - bio->init = 0; - bio->flags = 0; - } - - return 1; -} - -static int WOLFCRYPT_BIO_ssl_read(WOLFCRYPT_BIO *bio, char *data, int size) -{ - int ret = 1; - WOLFCRYPT_BIO_SSL *bssl; - - if (bio == NULL || bio->ptr == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - if (data == NULL) - return 0; - - bssl = (WOLFCRYPT_BIO_SSL *)bio->ptr; - - WOLFCRYPT_BIO_clear_retry_flags(bio); - - ret = wolfSSL_read(bssl->ssl, data, size); - - switch (wolfSSL_get_error(bssl->ssl, ret)) { - case SSL_ERROR_NONE: - if (ret <= 0) - break; - -#ifdef HAVE_SECURE_RENEGOTIATION - { - int r = 0; - - if (bssl->renegotiate_count > 0) { - bssl->byte_count += ret; - if (bssl->byte_count > bssl->renegotiate_count) { - bssl->byte_count = 0; - bssl->num_renegotiates++; - wolfSSL_Rehandshake(bssl->ssl); - r = 1; - } - } - - if ((bssl->renegotiate_timeout > 0) && !r) { - unsigned long tm; - tm = (unsigned long)time(NULL); - if (tm > bssl->last_time + bssl->renegotiate_timeout) { - bssl->last_time = tm; - bssl->num_renegotiates++; - wolfSSL_Rehandshake(bssl->ssl); - } - } - } -#endif - break; - - case SSL_ERROR_WANT_READ: - WOLFCRYPT_BIO_set_retry_read(bio); - break; - - case SSL_ERROR_WANT_WRITE: - WOLFCRYPT_BIO_set_retry_write(bio); - break; - - case SSL_ERROR_WANT_X509_LOOKUP: - WOLFCRYPT_BIO_set_retry_special(bio); - bio->retry_reason = BIO_RR_SSL_X509_LOOKUP; - break; - - case SSL_ERROR_WANT_ACCEPT: - WOLFCRYPT_BIO_set_retry_special(bio); - bio->retry_reason = BIO_RR_ACCEPT; - break; - - case SSL_ERROR_WANT_CONNECT: - WOLFCRYPT_BIO_set_retry_special(bio); - bio->retry_reason = BIO_RR_CONNECT; - break; - - case SSL_ERROR_SYSCALL: - case SSL_ERROR_SSL: - case SSL_ERROR_ZERO_RETURN: - break; - - default: - break; - } - - return ret; -} - -static int WOLFCRYPT_BIO_ssl_write(WOLFCRYPT_BIO *bio, - const char *data, int size) -{ - int ret; - WOLFCRYPT_BIO_SSL *bssl; - - if (bio == NULL || bio->ptr == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - if (data == NULL) - return 0; - - bssl = (WOLFCRYPT_BIO_SSL *)bio->ptr; - - WOLFCRYPT_BIO_clear_retry_flags(bio); - - ret = wolfSSL_write(bssl->ssl, data, size); - - switch (wolfSSL_get_error(bssl->ssl, ret)) { - case SSL_ERROR_NONE: - if (ret <= 0) - break; - -#ifdef HAVE_SECURE_RENEGOTIATION - { - int r = 0; - - if (bssl->renegotiate_count > 0) { - bssl->byte_count += ret; - if (bssl->byte_count > bssl->renegotiate_count) { - bssl->byte_count = 0; - bssl->num_renegotiates++; - wolfSSL_Rehandshake(bssl->ssl); - r = 1; - } - } - - if ((bssl->renegotiate_timeout > 0) && !r) { - unsigned long tm; - - tm = (unsigned long)time(NULL); - if (tm > bssl->last_time + bssl->renegotiate_timeout) { - bssl->last_time = tm; - bssl->num_renegotiates++; - wolfSSL_Rehandshake(bssl->ssl); - } - } - } -#endif - break; - - case SSL_ERROR_WANT_WRITE: - WOLFCRYPT_BIO_set_retry_write(bio); - break; - - case SSL_ERROR_WANT_READ: - WOLFCRYPT_BIO_set_retry_read(bio); - break; - - case SSL_ERROR_WANT_X509_LOOKUP: - WOLFCRYPT_BIO_set_retry_special(bio); - bio->retry_reason = BIO_RR_SSL_X509_LOOKUP; - break; - - case SSL_ERROR_WANT_CONNECT: - WOLFCRYPT_BIO_set_retry_special(bio); - bio->retry_reason = BIO_RR_CONNECT; - break; - - case SSL_ERROR_SYSCALL: - case SSL_ERROR_SSL: - break; - - default: - break; - } - - return ret; -} - -static int WOLFCRYPT_BIO_ssl_set_bio(WOLFSSL *ssl, WOLFCRYPT_BIO *rbio, - WOLFCRYPT_BIO *wbio) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_ssl_set_bio"); - - if (ssl == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - if (ssl->biord != NULL && ssl->biord != rbio) - WOLFCRYPT_BIO_free_all(ssl->biord); - if (ssl->biowr != NULL && ssl->biowr != wbio && ssl->biord != ssl->biowr) - WOLFCRYPT_BIO_free_all(ssl->biowr); - - ssl->biord = rbio; - wolfSSL_set_rfd(ssl, rbio->num); - - ssl->biowr = wbio; - wolfSSL_set_wfd(ssl, wbio->num); - - return 1; -} - -static long WOLFCRYPT_BIO_ssl_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr) -{ - WOLFCRYPT_BIO_SSL *bssl; - long ret = 1; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_ssl_ctrl"); - - if (bio == NULL || bio->ptr == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - bssl = (WOLFCRYPT_BIO_SSL *)bio->ptr; - - if ((bssl->ssl == NULL) && (cmd != BIO_C_SET_SSL)) { - WOLFSSL_MSG("Set SSL not possible, ssl pointer NULL\n"); - return 0; - } - - switch (cmd) { - case BIO_CTRL_RESET: - wolfSSL_shutdown(bssl->ssl); - ret = (long)wolfSSL_negotiate(bssl->ssl); - if (ret <= 0) - break; - wolfSSL_clear(bssl->ssl); - - if (bio->next_bio != NULL) - ret = WOLFCRYPT_BIO_ctrl(bio->next_bio, cmd, num, ptr); - else if (bssl->ssl->biord != NULL) - ret = WOLFCRYPT_BIO_ctrl(bssl->ssl->biord, cmd, num, ptr); - else - ret = 1; - break; - - case BIO_CTRL_INFO: - ret = 0; - break; - - case BIO_C_SSL_MODE: - if (num) /* client mode */ - wolfSSL_set_connect_state(bssl->ssl); - else - wolfSSL_set_accept_state(bssl->ssl); - break; - - case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT: - ret = bssl->renegotiate_timeout; - if (num < 60) - num = 5; - bssl->renegotiate_timeout = (unsigned long)num; - bssl->last_time = (unsigned long)time(NULL); - break; - - case BIO_C_SET_SSL_RENEGOTIATE_BYTES: - ret = bssl->renegotiate_count; - if (num >= 512) - bssl->renegotiate_count = (unsigned long)num; - break; - - case BIO_C_GET_SSL_NUM_RENEGOTIATES: - ret = bssl->num_renegotiates; - break; - - case BIO_C_SET_SSL: - if (bssl->ssl != NULL) { - WOLFCRYPT_BIO_ssl_free(bio); - if (!WOLFCRYPT_BIO_ssl_new(bio)) - return 0; - } - - bio->shutdown = (int)num; - bssl->ssl = (WOLFSSL *)ptr; - - if (bssl->ssl->biord != NULL) { - if (bio->next_bio != NULL) - WOLFCRYPT_BIO_push(bssl->ssl->biord, bio->next_bio); - bio->next_bio = bssl->ssl->biord; - - if (LockMutex(&bssl->ssl->biord->refMutex) != 0) { - WOLFSSL_MSG("Couldn't lock count mutex"); - ret = 0; - break; - } - bssl->ssl->biord->references++; - UnLockMutex(&bssl->ssl->biord->refMutex); - } - bio->init = 1; - break; - - case BIO_C_GET_SSL: - if (ptr != NULL) - *(WOLFSSL **)ptr = bssl->ssl; - else - ret = 0; - break; - - case BIO_CTRL_GET_CLOSE: - ret = bio->shutdown; - break; - - case BIO_CTRL_SET_CLOSE: - bio->shutdown = (int)num; - break; - - case BIO_CTRL_WPENDING: - ret = WOLFCRYPT_BIO_ctrl(bssl->ssl->biowr, cmd, num, ptr); - break; - - case BIO_CTRL_PENDING: - ret = wolfSSL_pending(bssl->ssl); - if (!ret) - ret = WOLFCRYPT_BIO_pending(bssl->ssl->biord); - break; - - case BIO_CTRL_FLUSH: - WOLFCRYPT_BIO_clear_retry_flags(bio); - ret = WOLFCRYPT_BIO_ctrl(bssl->ssl->biowr, cmd, num, ptr); - WOLFCRYPT_BIO_copy_next_retry(bio); - break; - - case BIO_CTRL_PUSH: - if (bio->next_bio != NULL && bio->next_bio != bssl->ssl->biord) { - ret = WOLFCRYPT_BIO_ssl_set_bio(bssl->ssl, - bio->next_bio, bio->next_bio); - if (LockMutex(&bio->next_bio->refMutex) != 0) { - WOLFSSL_MSG("Couldn't lock count mutex"); - ret = 0; - break; - } - bio->next_bio->references++; - UnLockMutex(&bio->next_bio->refMutex); - } - break; - - case BIO_CTRL_POP: - if (bio == ptr) { - if (bssl->ssl->biord != bssl->ssl->biowr) - WOLFCRYPT_BIO_free_all(bssl->ssl->biowr); - if (bio->next_bio != NULL) { - if (LockMutex(&bio->next_bio->refMutex) != 0) { - WOLFSSL_MSG("Couldn't lock count mutex"); - ret = 0; - break; - } - bio->next_bio->references--; - UnLockMutex(&bio->next_bio->refMutex); - } - bssl->ssl->biowr = NULL; - bssl->ssl->biord = NULL; - } - break; - - case BIO_C_DO_STATE_MACHINE: - WOLFCRYPT_BIO_clear_retry_flags(bio); - - bio->retry_reason = 0; - ret = (long)wolfSSL_negotiate(bssl->ssl); - - switch (wolfSSL_get_error(bssl->ssl, (int)ret)) { - case SSL_ERROR_WANT_READ: - WOLFCRYPT_BIO_set_flags(bio, BIO_FLAGS_READ | - BIO_FLAGS_SHOULD_RETRY); - break; - - case SSL_ERROR_WANT_WRITE: - WOLFCRYPT_BIO_set_flags(bio, BIO_FLAGS_WRITE | - BIO_FLAGS_SHOULD_RETRY); - break; - - case SSL_ERROR_WANT_CONNECT: - WOLFCRYPT_BIO_set_flags(bio, BIO_FLAGS_IO_SPECIAL | - BIO_FLAGS_SHOULD_RETRY); - bio->retry_reason = bio->next_bio->retry_reason; - break; - - case SSL_ERROR_WANT_X509_LOOKUP: - WOLFCRYPT_BIO_set_retry_special(bio); - bio->retry_reason = BIO_RR_SSL_X509_LOOKUP; - break; - - default: - break; - } - break; - - case BIO_CTRL_DUP: - { - WOLFCRYPT_BIO *dbio; - dbio = (WOLFCRYPT_BIO *)ptr; - - if (((WOLFCRYPT_BIO_SSL *)dbio->ptr)->ssl != NULL) - wolfSSL_free(((WOLFCRYPT_BIO_SSL *)dbio->ptr)->ssl); - - /* add copy ssl */ - ((WOLFCRYPT_BIO_SSL *)dbio->ptr)->ssl = wolfSSL_dup(bssl->ssl); - - ((WOLFCRYPT_BIO_SSL *)dbio->ptr)->renegotiate_count = - bssl->renegotiate_count; - - ((WOLFCRYPT_BIO_SSL *)dbio->ptr)->byte_count = bssl->byte_count; - - ((WOLFCRYPT_BIO_SSL *)dbio->ptr)->renegotiate_timeout = - bssl->renegotiate_timeout; - - ((WOLFCRYPT_BIO_SSL *)dbio->ptr)->last_time = bssl->last_time; - - if (((WOLFCRYPT_BIO_SSL *)dbio->ptr)->ssl == NULL) - ret = 0; - } - break; - - case BIO_C_GET_FD: - ret = WOLFCRYPT_BIO_ctrl(bssl->ssl->biord, cmd, num, ptr); - break; - - case BIO_CTRL_SET_CALLBACK: - /* not supported */ - WOLFSSL_MSG("BIO_CTRL_SET_CALLBACK not supported\n"); - ret = 0; - break; - - case BIO_CTRL_GET_CALLBACK: - /* not supported */ - WOLFSSL_MSG("BIO_CTRL_GET_CALLBACK not supported\n"); - ptr = NULL; - ret = 0; - break; - - default: - ret = WOLFCRYPT_BIO_ctrl(bssl->ssl->biord, cmd, num, ptr); - break; - } - - return ret; -} - -static long WOLFCRYPT_BIO_ssl_callback_ctrl(WOLFCRYPT_BIO *bio, - int cmd, WOLFCRYPT_BIO_info_cb *fp) -{ - long ret = 1; - WOLFCRYPT_BIO_SSL *bssl; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_ssl_callback_ctrl"); - - if (bio == NULL || bio->ptr == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - bssl = (WOLFCRYPT_BIO_SSL *)bio->ptr; - - switch (cmd) { - case BIO_CTRL_SET_CALLBACK: - /* not supported */ - WOLFSSL_MSG("BIO_CTRL_GET_CALLBACK not supported\n"); - ret = 0; - break; - - default: - ret = WOLFCRYPT_BIO_callback_ctrl(bssl->ssl->biord, cmd, fp); - break; - } - - return ret; -} - -static int WOLFCRYPT_BIO_ssl_puts(WOLFCRYPT_BIO *bio, const char *str) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_ssl_puts"); - - if (bio == NULL || str == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - return WOLFCRYPT_BIO_ssl_write(bio, str, (int)strlen(str)); -} - -WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_buffer_ssl_connect(WOLFSSL_CTX *ctx) -{ - WOLFCRYPT_BIO *bio = NULL, *buf = NULL, *ssl = NULL; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_new_buffer_ssl_connect"); - - if (ctx == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return NULL; - } - - buf = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_f_buffer()); - if (buf == NULL) - return NULL; - - ssl = WOLFCRYPT_BIO_new_ssl_connect(ctx); - if (ssl == NULL) - goto err; - - bio = WOLFCRYPT_BIO_push(buf, ssl); - if (bio == NULL) - goto err; - - return bio; - - err: - if (buf != NULL) - WOLFCRYPT_BIO_free(buf); - if (ssl != NULL) - WOLFCRYPT_BIO_free(ssl); - - return NULL; -} - -WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_ssl_connect(WOLFSSL_CTX *ctx) -{ - WOLFCRYPT_BIO *bio = NULL, *con = NULL, *ssl = NULL; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_new_ssl_connect"); - - if (ctx == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return NULL; - } - - con = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_s_connect()); - if (con == NULL) - return NULL; - - ssl = WOLFCRYPT_BIO_new_ssl(ctx, 1); - if (ssl == NULL) - goto err; - - bio = WOLFCRYPT_BIO_push(ssl, con); - if (bio == NULL) - goto err; - - return bio; - - err: - if (con != NULL) - WOLFCRYPT_BIO_free(con); - if (ssl != NULL) - WOLFCRYPT_BIO_free(ssl); - return NULL; -} - -WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_ssl(WOLFSSL_CTX *ctx, int mode) -{ - WOLFCRYPT_BIO *bio; - WOLFSSL *ssl; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_new_ssl"); - - if (ctx == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return NULL; - } - - bio = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_f_ssl()); - if (bio == NULL) - return NULL; - - ssl = wolfSSL_new(ctx); - if (ssl == NULL) { - WOLFCRYPT_BIO_free(bio); - return NULL; - } - - if (mode) /* client */ - wolfSSL_set_connect_state(ssl); - else - wolfSSL_set_accept_state(ssl); - - WOLFCRYPT_BIO_set_ssl(bio, ssl, BIO_CLOSE); - - return bio; -} - -void WOLFCRYPT_BIO_ssl_shutdown(WOLFCRYPT_BIO *bio) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_ssl_shutdown"); - - while (bio != NULL) { - if (bio->method->type == BIO_TYPE_SSL) { - wolfSSL_shutdown(((WOLFCRYPT_BIO_SSL *)bio->ptr)->ssl); - break; - } - - bio = bio->next_bio; - } -} - - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_m_accept.c b/wolfcrypt/src/bio_m_accept.c deleted file mode 100644 index 8c0f61928..000000000 --- a/wolfcrypt/src/bio_m_accept.c +++ /dev/null @@ -1,554 +0,0 @@ -/* bio_m_accept.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#ifdef USE_WINDOWS_API -#include -#include -#endif /* USE_WINDOWS_API */ - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include - -/* Socket Handling */ -#ifndef WOLFSSL_SOCKET_INVALID -#ifdef USE_WINDOWS_API -#define WOLFSSL_SOCKET_INVALID ((SOCKET)WOLFSSL_SOCKET_INVALID) -#else -#define WOLFSSL_SOCKET_INVALID (0) -#endif -#endif /* WOLFSSL_SOCKET_INVALID */ - -typedef struct { - int state; - int nbio; - - char *param_addr; - char *ip_port; - int accept_sock; - int accept_nbio; - - /* - * If 0, it means normal, if 1, do a connect on bind failure, and if - * there is no-one listening, bind with SO_REUSEADDR. If 2, always use - * SO_REUSEADDR. - */ - int bind_mode; - - /* used to force some socket options like NO_SIGPIPE, TCP_NODELAY */ - int options; - - WOLFCRYPT_BIO *bio_chain; -} WOLFCRYPT_BIO_ACCEPT; - -static int WOLFCRYPT_BIO_accept_write(WOLFCRYPT_BIO *bio, - const char *data, int size); -static int WOLFCRYPT_BIO_accept_read(WOLFCRYPT_BIO *bio, char *data, int size); -static int WOLFCRYPT_BIO_accept_puts(WOLFCRYPT_BIO *bio, const char *str); -static long WOLFCRYPT_BIO_accept_ctrl(WOLFCRYPT_BIO *bio, - int cmd, long num, void *ptr); -static int WOLFCRYPT_BIO_accept_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_accept_free(WOLFCRYPT_BIO *bio); -static void WOLFCRYPT_BIO_accept_close_socket(WOLFCRYPT_BIO *bio); - -static int WOLFCRYPT_BIO_accept_state(WOLFCRYPT_BIO *bio, - WOLFCRYPT_BIO_ACCEPT *c); - -# define ACPT_S_BEFORE 1 -# define ACPT_S_GET_ACCEPT_SOCKET 2 -# define ACPT_S_OK 3 - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_accept_method = { - BIO_TYPE_ACCEPT, - "Socket accept", - WOLFCRYPT_BIO_accept_write, - WOLFCRYPT_BIO_accept_read, - WOLFCRYPT_BIO_accept_puts, - NULL, /* gets */ - WOLFCRYPT_BIO_accept_ctrl, - WOLFCRYPT_BIO_accept_new, - WOLFCRYPT_BIO_accept_free, - NULL, -}; - -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_accept(void) -{ - return (&WOLFCRYPT_BIO_accept_method); -} - -static int WOLFCRYPT_BIO_accept_new(WOLFCRYPT_BIO *bio) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_accept_new"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - bio->init = 0; - bio->num = WOLFSSL_SOCKET_INVALID; - bio->flags = 0; - - bio->ptr = (WOLFCRYPT_BIO_ACCEPT *) - XMALLOC(sizeof(WOLFCRYPT_BIO_ACCEPT), 0, DYNAMIC_TYPE_OPENSSL); - if (bio->ptr == NULL) - return 0; - - XMEMSET(bio->ptr, 0, sizeof(WOLFCRYPT_BIO_ACCEPT)); - - ((WOLFCRYPT_BIO_ACCEPT *)bio->ptr)->accept_sock = WOLFSSL_SOCKET_INVALID; - ((WOLFCRYPT_BIO_ACCEPT *)bio->ptr)->bind_mode = BIO_BIND_NORMAL; - ((WOLFCRYPT_BIO_ACCEPT *)bio->ptr)->options = 0; - ((WOLFCRYPT_BIO_ACCEPT *)bio->ptr)->state = ACPT_S_BEFORE; - - bio->shutdown = 1; - - return 1; -} - -static void WOLFCRYPT_BIO_accept_close_socket(WOLFCRYPT_BIO *bio) -{ - WOLFCRYPT_BIO_ACCEPT *accept; - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return; - } - - accept = (WOLFCRYPT_BIO_ACCEPT *)bio->ptr; - if (accept->accept_sock != WOLFSSL_SOCKET_INVALID) { - shutdown(accept->accept_sock, SHUT_RDWR); -#ifdef USE_WINDOWS_API - closesocket(accept->accept_sock); -#else - close(accept->accept_sock); -#endif - accept->accept_sock = WOLFSSL_SOCKET_INVALID; - bio->num = WOLFSSL_SOCKET_INVALID; - } -} - -static int WOLFCRYPT_BIO_accept_free(WOLFCRYPT_BIO *bio) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_accept_free"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - if (!bio->shutdown) - return 1; - - WOLFCRYPT_BIO_accept_close_socket(bio); - - if (bio->ptr != NULL) { - WOLFCRYPT_BIO_ACCEPT *accept = (WOLFCRYPT_BIO_ACCEPT *)bio->ptr; - - if (accept->param_addr != NULL) - XFREE(accept->param_addr, 0, DYNAMIC_TYPE_OPENSSL); - if (accept->ip_port != NULL) - XFREE(accept->ip_port, 0, DYNAMIC_TYPE_OPENSSL); - if (accept->bio_chain != NULL) - WOLFCRYPT_BIO_free(accept->bio_chain); - - XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); - bio->ptr = NULL; - } - - bio->flags = 0; - bio->init = 0; - - return 1; -} - -static int WOLFCRYPT_BIO_accept_state(WOLFCRYPT_BIO *bio, - WOLFCRYPT_BIO_ACCEPT *accept) -{ - WOLFCRYPT_BIO *nbio = NULL; - int s = -1; - int dsock; - - if (bio == NULL || accept == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - again: - switch (accept->state) { - case ACPT_S_BEFORE: - if (accept->param_addr == NULL) { - WOLFSSL_ERROR(BIO_NO_PORT_E); - return -1; - } - - s = WOLFCRYPT_BIO_get_accept_socket(accept->param_addr, - accept->bind_mode); - if (s == WOLFSSL_SOCKET_INVALID) - return -1; - - if (accept->accept_nbio) { - if (!WOLFCRYPT_BIO_socket_nbio(s, 1)) { -#ifdef USE_WINDOWS_API - closesocket(s); -#else - close(s); -#endif - WOLFSSL_ERROR(BIO_NBIO_E); - return -1; - } - } - - /* TCP NO DELAY */ - if (accept->options & 1) { - if (!WOLFCRYPT_BIO_set_tcp_ndelay(s, 1)) { -#ifdef USE_WINDOWS_API - closesocket(s); -#else - close(s); -#endif - WOLFSSL_ERROR(BIO_OPTIONS_E); - return -1; - } - } - - /* IGNORE SIGPIPE */ - if (accept->options & 2) { - if (!WOLFCRYPT_BIO_set_tcp_nsigpipe(s, 1)) { -#ifdef USE_WINDOWS_API - closesocket(s); -#else - close(s); -#endif - WOLFSSL_ERROR(BIO_OPTIONS_E); - return -1; - } - } - - accept->accept_sock = s; - bio->num = s; - accept->state = ACPT_S_GET_ACCEPT_SOCKET; - return 1; - break; - - case ACPT_S_GET_ACCEPT_SOCKET: - if (bio->next_bio != NULL) { - accept->state = ACPT_S_OK; - goto again; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - bio->retry_reason = 0; - dsock = WOLFCRYPT_BIO_accept(accept->accept_sock, &accept->ip_port); - - /* retry case */ - if (dsock == -2) { - WOLFCRYPT_BIO_set_retry_special(bio); - bio->retry_reason = BIO_RR_ACCEPT; - return -1; - } - - if (dsock < 0) - return dsock; - - nbio = WOLFCRYPT_BIO_new_socket(dsock, BIO_CLOSE); - if (nbio == NULL) - goto err; - - WOLFCRYPT_BIO_set_callback(nbio, - WOLFCRYPT_BIO_get_callback(bio)); - WOLFCRYPT_BIO_set_callback_arg(nbio, - WOLFCRYPT_BIO_get_callback_arg(bio)); - - if (accept->nbio) { - if (!WOLFCRYPT_BIO_socket_nbio(dsock, 1)) { - WOLFSSL_ERROR(BIO_NBIO_E); - goto err; - } - } - - /* - * If the accept BIO has an bio_chain, we dup it and put the new - * socket at the end. - */ - if (accept->bio_chain != NULL) { - WOLFCRYPT_BIO *dbio = WOLFCRYPT_BIO_dup_chain(accept->bio_chain); - if (dbio == NULL) - goto err; - if (!WOLFCRYPT_BIO_push(dbio, nbio)) - goto err; - nbio = dbio; - } - - if (WOLFCRYPT_BIO_push(bio, nbio) == NULL) - goto err; - - accept->state = ACPT_S_OK; - return 1; -err: - if (nbio != NULL) - WOLFCRYPT_BIO_free(nbio); - else if (s >= 0) -#ifdef USE_WINDOWS_API - closesocket(s); -#else - close(s); -#endif - break; - - case ACPT_S_OK: - if (bio->next_bio == NULL) { - accept->state = ACPT_S_GET_ACCEPT_SOCKET; - goto again; - } - return 1; - break; - - default: - break; - } - - return 0; -} - -static int WOLFCRYPT_BIO_accept_read(WOLFCRYPT_BIO *bio, char *data, int size) -{ - int ret = 0; - WOLFCRYPT_BIO_ACCEPT *accept; - - if (bio == NULL || data == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - accept = (WOLFCRYPT_BIO_ACCEPT *)bio->ptr; - - while (bio->next_bio == NULL) { - ret = WOLFCRYPT_BIO_accept_state(bio, accept); - if (ret <= 0) - return ret; - } - - ret = WOLFCRYPT_BIO_read(bio->next_bio, data, size); - WOLFCRYPT_BIO_copy_next_retry(bio); - - return ret; -} - -static int WOLFCRYPT_BIO_accept_write(WOLFCRYPT_BIO *bio, - const char *data, int size) -{ - int ret = 0; - WOLFCRYPT_BIO_ACCEPT *accept; - - if (bio == NULL || data == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - accept = (WOLFCRYPT_BIO_ACCEPT *)bio->ptr; - - while (bio->next_bio == NULL) { - ret = WOLFCRYPT_BIO_accept_state(bio, accept); - if (ret <= 0) - return ret; - } - - ret = WOLFCRYPT_BIO_write(bio->next_bio, data, size); - WOLFCRYPT_BIO_copy_next_retry(bio); - - return ret; -} - -static long WOLFCRYPT_BIO_accept_ctrl(WOLFCRYPT_BIO *bio, - int cmd, long num, void *ptr) -{ - int *ip; - long ret = 1; - WOLFCRYPT_BIO_ACCEPT *accept; - char **pp; - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - accept = (WOLFCRYPT_BIO_ACCEPT *)bio->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - ret = 0; - accept->state = ACPT_S_BEFORE; - WOLFCRYPT_BIO_accept_close_socket(bio); - bio->flags = 0; - break; - - case BIO_C_DO_STATE_MACHINE: - /* use this one to start the connection */ - ret = (long)WOLFCRYPT_BIO_accept_state(bio, accept); - break; - - case BIO_C_SET_ACCEPT: - if (ptr != NULL) { - if (num == 0) { - bio->init = 1; - if (accept->param_addr != NULL) - XFREE(accept->param_addr, 0, DYNAMIC_TYPE_OPENSSL); - accept->param_addr = strdup(ptr); - } - else if (num == 1) { - accept->accept_nbio = (ptr != NULL); - } - else if (num == 2) { - if (accept->bio_chain != NULL) - WOLFCRYPT_BIO_free(accept->bio_chain); - accept->bio_chain = (WOLFCRYPT_BIO *)ptr; - } - } - break; - - case BIO_C_SET_NBIO: - accept->nbio = (int)num; - break; - - case BIO_C_SET_FD: - bio->init = 1; - bio->num = *((int *)ptr); - accept->accept_sock = bio->num; - accept->state = ACPT_S_GET_ACCEPT_SOCKET; - bio->shutdown = (int)num; - bio->init = 1; - break; - - case BIO_C_GET_FD: - if (bio->init) { - ip = (int *)ptr; - if (ip != NULL) - *ip = accept->accept_sock; - ret = accept->accept_sock; - } - else - ret = -1; - break; - - case BIO_C_GET_ACCEPT: - if (bio->init) { - if (ptr != NULL) { - pp = (char **)ptr; - *pp = accept->param_addr; - } - else - ret = -1; - } - else - ret = -1; - break; - - case BIO_CTRL_GET_CLOSE: - ret = bio->shutdown; - break; - - case BIO_CTRL_SET_CLOSE: - bio->shutdown = (int)num; - break; - - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: - ret = 0; - break; - - case BIO_CTRL_FLUSH: - case BIO_CTRL_DUP: - break; - - case BIO_C_SET_BIND_MODE: - accept->bind_mode = (int)num; - break; - - case BIO_C_GET_BIND_MODE: - ret = (long)accept->bind_mode; - break; - - case BIO_C_SET_EX_ARG: - accept->options = (int)num; - break; - - default: - ret = 0; - break; - } - - return ret; -} - -static int WOLFCRYPT_BIO_accept_puts(WOLFCRYPT_BIO *bio, const char *str) -{ - if (bio == NULL || str == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - return WOLFCRYPT_BIO_accept_write(bio, str, (int)strlen(str)); -} - -WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_accept(const char *str) -{ - WOLFCRYPT_BIO *bio; - - if (str == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - bio = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_s_accept()); - if (bio == NULL) - return NULL; - - if (WOLFCRYPT_BIO_set_accept_port(bio, str)) - return bio; - - WOLFCRYPT_BIO_free(bio); - return NULL; -} - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_m_conn.c b/wolfcrypt/src/bio_m_conn.c deleted file mode 100644 index 56386af99..000000000 --- a/wolfcrypt/src/bio_m_conn.c +++ /dev/null @@ -1,715 +0,0 @@ -/* bio_m_conn.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#ifdef USE_WINDOWS_API -#include -#include -#endif /* USE_WINDOWS_API */ - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include - -/* Socket Handling */ -#ifndef WOLFSSL_SOCKET_INVALID - #ifdef USE_WINDOWS_API - #define WOLFSSL_SOCKET_INVALID ((SOCKET)INVALID_SOCKET) - #else - #define WOLFSSL_SOCKET_INVALID (0) - #endif -#endif /* WOLFSSL_SOCKET_INVALID */ - -static int WOLFCRYPT_BIO_conn_write(WOLFCRYPT_BIO *bio, - const char *data, int size); -static int WOLFCRYPT_BIO_conn_read(WOLFCRYPT_BIO *bio, char *data, int size); -static int WOLFCRYPT_BIO_conn_puts(WOLFCRYPT_BIO *bio, const char *str); -static long WOLFCRYPT_BIO_conn_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr); -static int WOLFCRYPT_BIO_conn_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_conn_free(WOLFCRYPT_BIO *bio); -static long WOLFCRYPT_BIO_conn_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, - WOLFCRYPT_BIO_info_cb *fp); - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_conn_method = { - BIO_TYPE_SOCKET, - "Socket connect", - WOLFCRYPT_BIO_conn_write, - WOLFCRYPT_BIO_conn_read, - WOLFCRYPT_BIO_conn_puts, - NULL, /* gets */ - WOLFCRYPT_BIO_conn_ctrl, - WOLFCRYPT_BIO_conn_new, - WOLFCRYPT_BIO_conn_free, - WOLFCRYPT_BIO_conn_callback_ctrl, -}; - -typedef struct { - int state; - int nbio; - - /* keep received Hostname and Port */ - char *pHostname; - char *pPort; - - /* internal usage */ - unsigned char ip[4]; - unsigned short port; - - struct sockaddr_in them; - - /* - * called when the connection is initially made callback(BIO,state,ret); - * The callback should return 'ret'. state is for compatibility with the - * ssl info_callback - */ - int (*info_callback) (const WOLFCRYPT_BIO *bio, int state, int ret); -} WOLFCRYPT_BIO_CONNECT; - -static int WOLFCRYPT_BIO_conn_state(WOLFCRYPT_BIO *bio, - WOLFCRYPT_BIO_CONNECT *conn) -{ - int ret = -1, i; - word32 l; - char *p, *q; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_conn_state"); - - if (bio == NULL || conn == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - for (;;) { - switch (conn->state) { - case BIO_CONN_S_BEFORE: - p = conn->pHostname; - if (p == NULL) { - WOLFSSL_ERROR(BIO_NO_HOSTNAME_E); - goto exit_loop; - } - - for (; *p != '\0'; p++) { - if ((*p == ':') || (*p == '/')) - break; - } - - i = *p; - if ((i == ':') || (i == '/')) { - *(p++) = '\0'; - if (i == ':') { - for (q = p; *q; q++) - if (*q == '/') { - *q = '\0'; - break; - } - - if (conn->pPort != NULL) - XFREE(conn->pPort, 0, DYNAMIC_TYPE_OPENSSL); - - conn->pPort = XMALLOC(strlen(p)+1, - 0, DYNAMIC_TYPE_OPENSSL); - if (conn->pPort == NULL) { - WOLFSSL_ERROR(MEMORY_E); - goto exit_loop; - break; - } - XSTRNCPY(conn->pPort, p, strlen(p)+1); - } - } - - if (conn->pPort == NULL) { - WOLFSSL_ERROR(BIO_NO_PORT_E); - goto exit_loop; - } - - conn->state = BIO_CONN_S_GET_IP; - break; - - case BIO_CONN_S_GET_IP: - if (WOLFCRYPT_BIO_get_host_ip(conn->pHostname, - conn->ip) <= 0) - goto exit_loop; - conn->state = BIO_CONN_S_GET_PORT; - break; - - case BIO_CONN_S_GET_PORT: - if (conn->pPort == NULL || - WOLFCRYPT_BIO_get_port(conn->pPort, &conn->port) <= 0) - goto exit_loop; - conn->state = BIO_CONN_S_CREATE_SOCKET; - break; - - case BIO_CONN_S_CREATE_SOCKET: - /* now setup address */ - XMEMSET(&conn->them, 0, sizeof(conn->them)); - conn->them.sin_family = AF_INET; - conn->them.sin_port = htons((unsigned short)conn->port); - l = ((word32)conn->ip[0] << 24L) | - ((word32)conn->ip[1] << 16L) | - ((word32)conn->ip[2] << 8L) | - ((word32)conn->ip[3]); - conn->them.sin_addr.s_addr = htonl(l); - conn->state = BIO_CONN_S_CREATE_SOCKET; - - ret = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (ret <= 0) { - WOLFSSL_ERROR(BIO_CREATE_SOCKET_E); - goto exit_loop; - } - - bio->num = ret; - conn->state = BIO_CONN_S_NBIO; - break; - - case BIO_CONN_S_NBIO: - if (conn->nbio) { - if (!WOLFCRYPT_BIO_socket_nbio(bio->num, 1)) { - WOLFSSL_ERROR(BIO_NBIO_E); - goto exit_loop; - } - } - conn->state = BIO_CONN_S_CONNECT; - -# if defined(SO_KEEPALIVE) - i = 1; - i = setsockopt(bio->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, - sizeof(i)); - if (i < 0) { - WOLFSSL_ERROR(BIO_KEEPALIVE_E); - goto exit_loop; - } -# endif - break; - - - case BIO_CONN_S_CONNECT: - WOLFCRYPT_BIO_clear_retry_flags(bio); - ret = connect(bio->num, (struct sockaddr *)&conn->them, - sizeof(conn->them)); - bio->retry_reason = 0; - if (ret < 0) { - if (WOLFCRYPT_BIO_sock_should_retry(ret)) { - WOLFCRYPT_BIO_set_retry_special(bio); - conn->state = BIO_CONN_S_BLOCKED_CONNECT; - bio->retry_reason = BIO_RR_CONNECT; - } - else - WOLFSSL_ERROR(BIO_CONNECT_E); - goto exit_loop; - } - else - conn->state = BIO_CONN_S_OK; - break; - - case BIO_CONN_S_BLOCKED_CONNECT: - i = WOLFCRYPT_BIO_sock_error(bio->num); - if (i != 0) { - WOLFSSL_ERROR(BIO_CONNECT_E); - ret = 0; - goto exit_loop; - } - else - conn->state = BIO_CONN_S_OK; - break; - - case BIO_CONN_S_OK: - ret = 1; - goto exit_loop; - break; - - default: - goto exit_loop; - break; - } - - if (conn->info_callback != NULL) { - ret = conn->info_callback(bio, conn->state, ret); - if (!ret) - goto end; - } - } - -exit_loop: - if (conn->info_callback != NULL) - ret = conn->info_callback(bio, conn->state, ret); -end: - return ret; -} - -static WOLFCRYPT_BIO_CONNECT *WOLFCRYPT_BIO_CONNECT_new(void) -{ - WOLFCRYPT_BIO_CONNECT *conn; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_CONNECT_new"); - - conn = (WOLFCRYPT_BIO_CONNECT *)XMALLOC(sizeof(WOLFCRYPT_BIO_CONNECT), - 0, DYNAMIC_TYPE_OPENSSL); - if (conn == NULL) { - WOLFSSL_ERROR(MEMORY_E); - return NULL; - } - - XMEMSET(conn, 0, sizeof(WOLFCRYPT_BIO_CONNECT)); - - conn->state = BIO_CONN_S_BEFORE; - return conn; -} - -static void WOLFCRYPT_BIO_CONNECT_free(WOLFCRYPT_BIO_CONNECT *conn) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_CONNECT_free"); - - if (conn == NULL) - return; - - if (conn->pHostname != NULL) { - XFREE(conn->pHostname, 0, DYNAMIC_TYPE_OPENSSL); - conn->pHostname = NULL; - } - - if (conn->pPort != NULL) { - XFREE(conn->pPort, 0, DYNAMIC_TYPE_OPENSSL); - conn->pPort = NULL; - } - - XFREE(conn, 0, DYNAMIC_TYPE_OPENSSL); - conn = NULL; -} - -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_connect(void) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_s_connect"); - - return (&WOLFCRYPT_BIO_conn_method); -} - -static int WOLFCRYPT_BIO_conn_new(WOLFCRYPT_BIO *bio) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_conn_new"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - bio->init = 0; - bio->flags = 0; - bio->num = WOLFSSL_SOCKET_INVALID; - - bio->ptr = WOLFCRYPT_BIO_CONNECT_new(); - if (bio->ptr == NULL) - return 0; - - return 1; -} - -static void WOLFCRYPT_BIO_conn_close_socket(WOLFCRYPT_BIO *bio) -{ - WOLFCRYPT_BIO_CONNECT *conn; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_conn_close_socket"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return ; - } - - conn = (WOLFCRYPT_BIO_CONNECT *)bio->ptr; - - if (bio->num > 0) { - /* Only do a shutdown if things were established */ - if (conn->state == BIO_CONN_S_OK) - shutdown(bio->num, SHUT_RDWR); -#ifdef USE_WINDOWS_API - closesocket(bio->num); -#else - close(bio->num); -#endif - bio->num = WOLFSSL_SOCKET_INVALID; - } -} - -static int WOLFCRYPT_BIO_conn_free(WOLFCRYPT_BIO *bio) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_conn_free"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - if (bio->shutdown) { - WOLFCRYPT_BIO_conn_close_socket(bio); - WOLFCRYPT_BIO_CONNECT_free((WOLFCRYPT_BIO_CONNECT *)bio->ptr); - bio->ptr = NULL; - bio->flags = 0; - bio->init = 0; - } - - return 1; -} - -static int WOLFCRYPT_BIO_conn_read(WOLFCRYPT_BIO *bio, char *data, int size) -{ - int ret = 0; - WOLFCRYPT_BIO_CONNECT *conn; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_conn_read"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - conn = (WOLFCRYPT_BIO_CONNECT *)bio->ptr; - if (conn->state != BIO_CONN_S_OK) { - ret = WOLFCRYPT_BIO_conn_state(bio, conn); - if (ret <= 0) - return (ret); - } - -#ifdef USE_WINDOWS_API - WSASetLastError(0); - ret = (int)recv(bio->num, data, size, 0); -#else - errno = 0; - ret = (int)read(bio->num, data, size); -#endif - - WOLFCRYPT_BIO_clear_retry_flags(bio); - if (ret <= 0) { - if (WOLFCRYPT_BIO_sock_should_retry(ret)) - WOLFCRYPT_BIO_set_retry_read(bio); - } - - return ret; -} - -static int WOLFCRYPT_BIO_conn_write(WOLFCRYPT_BIO *bio, - const char *data, int size) -{ - int ret = 0; - WOLFCRYPT_BIO_CONNECT *conn; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_conn_write"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - conn = (WOLFCRYPT_BIO_CONNECT *)bio->ptr; - if (conn->state != BIO_CONN_S_OK) { - ret = WOLFCRYPT_BIO_conn_state(bio, conn); - if (ret <= 0) - return (ret); - } - -#ifdef USE_WINDOWS_API - WSASetLastError(0); - ret = (int)send(bio->num, data, size, 0); -#else - errno = 0; - ret = (int)write(bio->num, data, size); -#endif - - WOLFCRYPT_BIO_clear_retry_flags(bio); - if (ret <= 0) { - if (WOLFCRYPT_BIO_sock_should_retry(ret)) - WOLFCRYPT_BIO_set_retry_write(bio); - } - - return ret; -} - -static long WOLFCRYPT_BIO_conn_ctrl(WOLFCRYPT_BIO *bio, - int cmd, long num, void *ptr) -{ - long ret = 1; - WOLFCRYPT_BIO_CONNECT *conn; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_conn_ctrl"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - conn = (WOLFCRYPT_BIO_CONNECT *)bio->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - ret = 0; - conn->state = BIO_CONN_S_BEFORE; - WOLFCRYPT_BIO_conn_close_socket(bio); - bio->flags = 0; - break; - - case BIO_C_DO_STATE_MACHINE: - /* use this one to start the connection */ - if (conn->state != BIO_CONN_S_OK) - ret = (long)WOLFCRYPT_BIO_conn_state(bio, conn); - else - ret = 1; - break; - - case BIO_C_GET_CONNECT: - if (ptr == NULL) - break; - - if (num == 0) - *((const char **)ptr) = conn->pHostname; - else if (num == 1) - *((const char **)ptr) = conn->pPort; - else if (num == 2) - *((const char **)ptr) = (char *)conn->ip; - else if (num == 3) - *((int *)ptr) = conn->port; - - if (!bio->init || ptr == NULL) - *((const char **)ptr) = "not initialized"; - - ret = 1; - break; - - case BIO_C_SET_CONNECT: - if (ptr == NULL) - break; - - bio->init = 1; - if (num == 0) { - if (conn->pHostname != NULL) - XFREE(conn->pHostname, 0, DYNAMIC_TYPE_OPENSSL); - conn->pHostname = XMALLOC(strlen((char *)ptr)+1, - 0, DYNAMIC_TYPE_OPENSSL); - if (conn->pHostname == NULL) { - WOLFSSL_ERROR(MEMORY_E); - ret = -1; - break; - } - XSTRNCPY(conn->pHostname, (char *)ptr, strlen((char *)ptr)+1); - } - else if (num == 1) { - if (conn->pPort != NULL) - XFREE(conn->pPort, 0, DYNAMIC_TYPE_OPENSSL); - - conn->pPort = XMALLOC(strlen((char *)ptr)+1, - 0, DYNAMIC_TYPE_OPENSSL); - if (conn->pPort == NULL) { - WOLFSSL_ERROR(MEMORY_E); - ret = -1; - break; - } - XSTRNCPY(conn->pPort, (char *)ptr, strlen((char *)ptr)+1); - } - else if (num == 2) { - char buf[16]; - unsigned char *p = ptr; - - XSNPRINTF(buf, sizeof(buf), "%d.%d.%d.%d", - p[0], p[1], p[2], p[3]); - - if (conn->pHostname != NULL) - XFREE(conn->pHostname, 0, DYNAMIC_TYPE_OPENSSL); - - conn->pHostname = XMALLOC(strlen(buf)+1, - 0, DYNAMIC_TYPE_OPENSSL); - if (conn->pHostname == NULL) { - WOLFSSL_ERROR(MEMORY_E); - ret = -1; - break; - } - XSTRNCPY(conn->pHostname, buf, strlen(buf)+1); - - memcpy(conn->ip, ptr, 4); - } - else if (num == 3) { - char buf[6]; - - XSNPRINTF(buf, sizeof(buf), "%d", *(int *)ptr); - if (conn->pPort != NULL) - XFREE(conn->pPort, 0, DYNAMIC_TYPE_OPENSSL); - - conn->pPort = XMALLOC(strlen(buf)+1, - 0, DYNAMIC_TYPE_OPENSSL); - if (conn->pPort == NULL) { - WOLFSSL_ERROR(MEMORY_E); - ret = -1; - break; - } - XSTRNCPY(conn->pPort, buf, strlen(buf)+1); - - conn->port = *(int *)ptr; - } - break; - - case BIO_C_SET_NBIO: - conn->nbio = (int)num; - break; - - case BIO_C_GET_FD: - if (bio->init) { - if (ptr != NULL) - *((int *)ptr) = bio->num; - ret = bio->num; - } - else - ret = -1; - break; - - case BIO_CTRL_GET_CLOSE: - ret = bio->shutdown; - break; - - case BIO_CTRL_SET_CLOSE: - bio->shutdown = (int)num; - break; - - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: - ret = 0; - break; - - case BIO_CTRL_FLUSH: - break; - - case BIO_CTRL_DUP: - { - WOLFCRYPT_BIO *dbio = (WOLFCRYPT_BIO *)ptr; - - if (conn->pPort != NULL) - WOLFCRYPT_BIO_set_conn_port(dbio, conn->pPort); - - if (conn->pHostname != NULL) - WOLFCRYPT_BIO_set_conn_hostname(dbio, conn->pHostname); - - WOLFCRYPT_BIO_set_nbio(dbio, conn->nbio); - - WOLFCRYPT_BIO_set_info_callback(dbio, - (WOLFCRYPT_BIO_info_cb *)conn->info_callback); - } - break; - - case BIO_CTRL_SET_CALLBACK: - ret = 0; - break; - - case BIO_CTRL_GET_CALLBACK: - { - int (**fptr) (const WOLFCRYPT_BIO *bio, int state, int xret); - - fptr = (int (**)(const WOLFCRYPT_BIO *bio, - int state, int xret))ptr; - *fptr = conn->info_callback; - } - break; - - default: - ret = 0; - break; - } - - return ret; -} - -static long WOLFCRYPT_BIO_conn_callback_ctrl(WOLFCRYPT_BIO *bio, - int cmd, WOLFCRYPT_BIO_info_cb *fp) -{ - long ret = 1; - WOLFCRYPT_BIO_CONNECT *conn; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_conn_callback_ctrl"); - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - conn = (WOLFCRYPT_BIO_CONNECT *)bio->ptr; - - switch (cmd) { - case BIO_CTRL_SET_CALLBACK: - conn->info_callback = (int (*)(const WOLFCRYPT_BIO *, int, int))fp; - break; - - default: - ret = 0; - break; - } - - return ret; -} - -static int WOLFCRYPT_BIO_conn_puts(WOLFCRYPT_BIO *bio, const char *str) -{ - WOLFSSL_ENTER("WOLFCRYPT_BIO_conn_puts"); - - if (bio == NULL || str == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - return WOLFCRYPT_BIO_conn_write(bio, str, (int)strlen(str)); -} - -WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_connect(const char *str) -{ - WOLFCRYPT_BIO *bio; - - WOLFSSL_ENTER("WOLFCRYPT_BIO_new_connect"); - - if (str == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return NULL; - } - - bio = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_s_connect()); - if (bio == NULL) - return NULL; - - if (WOLFCRYPT_BIO_set_conn_hostname(bio, str)) - return bio; - - WOLFCRYPT_BIO_free(bio); - return NULL; -} - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_m_dgram.c b/wolfcrypt/src/bio_m_dgram.c deleted file mode 100644 index e9016a04c..000000000 --- a/wolfcrypt/src/bio_m_dgram.c +++ /dev/null @@ -1,795 +0,0 @@ -/* bio_m_dgram.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include - -#ifdef USE_WINDOWS_API -#include -#include -#else -#include -#endif /* USE_WINDOWS_API */ - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include - -/* Socket Handling */ -#ifndef WOLFSSL_SOCKET_INVALID -#ifdef USE_WINDOWS_API -#define WOLFSSL_SOCKET_INVALID ((SOCKET)WOLFSSL_SOCKET_INVALID) -#else -#define WOLFSSL_SOCKET_INVALID (0) -#endif -#endif /* WOLFSSL_SOCKET_INVALID */ - -#if !defined(IP_MTU) -#define IP_MTU 14 -#endif - -#if defined(TEST_IPV6) && !defined(IPPROTO_IPV6) -#define IPPROTO_IPV6 41 -#endif - -static int WOLFCRYPT_BIO_DATAGRAM_write(WOLFCRYPT_BIO *bio, - const char *data, int size); -static int WOLFCRYPT_BIO_DATAGRAM_read(WOLFCRYPT_BIO *bio, char *data, int size); -static int WOLFCRYPT_BIO_DATAGRAM_puts(WOLFCRYPT_BIO *bio, const char *str); -static long WOLFCRYPT_BIO_DATAGRAM_ctrl(WOLFCRYPT_BIO *bio, - int cmd, long num, void *ptr); -static int WOLFCRYPT_BIO_DATAGRAM_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_DATAGRAM_free(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_DATAGRAM_clear(WOLFCRYPT_BIO *bio); - -static int WOLFCRYPT_BIO_DATAGRAM_should_retry(int s); - -static void get_current_time(struct timeval *t); - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_dgram_method = { - BIO_TYPE_DGRAM, - "Datagram socket", - WOLFCRYPT_BIO_DATAGRAM_write, - WOLFCRYPT_BIO_DATAGRAM_read, - WOLFCRYPT_BIO_DATAGRAM_puts, - NULL, /* gets */ - WOLFCRYPT_BIO_DATAGRAM_ctrl, - WOLFCRYPT_BIO_DATAGRAM_new, - WOLFCRYPT_BIO_DATAGRAM_free, - NULL, -}; - -typedef struct { - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -#ifdef TEST_IPV6 - struct sockaddr_in6 sa_in6; -# endif - } peer; - unsigned int connected; - unsigned int _errno; - unsigned int mtu; - struct timeval next_timeout; - struct timeval socket_timeout; -} WOLFCRYPT_BIO_DATAGRAM; - -static int WOLFCRYPT_BIO_DATAGRAM_should_retry(int i) -{ - if (!i || i == -1) { - int ret; -#ifdef USE_WINDOWS_API - ret = WSAGetLastError(); -#else - ret = errno; -#endif - return WOLCRYPT_BIO_sock_non_fatal_error(ret); - } - - return 0; -} - -static void get_current_time(struct timeval *t) -{ -#ifdef USE_WINDOWS_API - SYSTEMTIME st; - union { - unsigned __int64 ul; - FILETIME ft; - } now; - - GetSystemTime(&st); - SystemTimeToFileTime(&st, &now.ft); - now.ul -= 116444736000000000UI64; /* re-bias to 1/1/1970 */ - t->tv_sec = (long)(now.ul / 10000000); - t->tv_usec = ((int)(now.ul % 10000000)) / 10; -# else - gettimeofday(t, NULL); -# endif -} - - -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_datagram(void) -{ - return (&WOLFCRYPT_BIO_dgram_method); -} - -WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_dgram(int fd, int close_flag) -{ - WOLFCRYPT_BIO *bio; - - bio = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_s_datagram()); - if (bio == NULL) - return NULL; - - WOLFCRYPT_BIO_set_fd(bio, fd, close_flag); - return bio; -} - -static int WOLFCRYPT_BIO_DATAGRAM_new(WOLFCRYPT_BIO *bio) -{ - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - bio->init = 0; - bio->num = 0; - bio->flags = 0; - - bio->ptr = XMALLOC(sizeof(WOLFCRYPT_BIO_DATAGRAM), 0, DYNAMIC_TYPE_OPENSSL); - if (bio->ptr == NULL) - return 0; - - XMEMSET(bio->ptr, 0, sizeof(WOLFCRYPT_BIO_DATAGRAM)); - return 1; -} - -static int WOLFCRYPT_BIO_DATAGRAM_free(WOLFCRYPT_BIO *bio) -{ - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - if (!WOLFCRYPT_BIO_DATAGRAM_clear(bio)) - return 0; - - if (bio->ptr != NULL) - XFREE(bio->ptr, 0, DYNAMIC_TYPE_OPENSSL); - - return 1; -} - -static int WOLFCRYPT_BIO_DATAGRAM_clear(WOLFCRYPT_BIO *bio) -{ - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - if (bio->shutdown) { - if (bio->init) { - shutdown(bio->num, SHUT_RDWR); -#ifdef USE_WINDOWS_API - closesocket(bio->num); -#else - close(bio->num); -#endif - } - bio->init = 0; - bio->flags = 0; - } - - return 1; -} - -static void WOLFCRYPT_BIO_DATAGRAM_adjust_rcv_timeout(WOLFCRYPT_BIO *bio) -{ -#ifdef SO_RCVTIMEO - WOLFCRYPT_BIO_DATAGRAM *dgram; - - union { - size_t s; - int i; - } sz = { 0 }; - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return; - } - - dgram = (WOLFCRYPT_BIO_DATAGRAM *)bio->ptr; - - /* Is a timer active? */ - if (dgram->next_timeout.tv_sec > 0 || dgram->next_timeout.tv_usec > 0) { - struct timeval timenow, timeleft; - - /* Read current socket timeout */ -#ifdef USE_WINDOWS_API - int timeout; - - sz.i = sizeof(timeout); - if (getsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, &sz.i) >= 0) { - dgram->socket_timeout.tv_sec = timeout / 1000; - dgram->socket_timeout.tv_usec = (timeout % 1000) * 1000; - } -#else - sz.i = sizeof(dgram->socket_timeout); - if (getsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, - &(dgram->socket_timeout), (void *)&sz) >= 0) { - if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) - if (sz.s > sizeof(dgram->socket_timeout)) - return ; - } -#endif /* USE_WINDOWS_API */ - - /* Get current time */ - get_current_time(&timenow); - - /* Calculate time left until timer expires */ - XMEMCPY(&timeleft, &dgram->next_timeout, sizeof(struct timeval)); - if (timeleft.tv_usec < timenow.tv_usec) { - timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec; - timeleft.tv_sec--; - } - else - timeleft.tv_usec -= timenow.tv_usec; - - if (timeleft.tv_sec < timenow.tv_sec) { - timeleft.tv_sec = 0; - timeleft.tv_usec = 1; - } - else - timeleft.tv_sec -= timenow.tv_sec; - - /* - * Adjust socket timeout if next handhake message timer will expire - * earlier. - */ - if ((!dgram->socket_timeout.tv_sec && !dgram->socket_timeout.tv_usec) || - (dgram->socket_timeout.tv_sec > timeleft.tv_sec) || - (dgram->socket_timeout.tv_sec == timeleft.tv_sec && - dgram->socket_timeout.tv_usec >= timeleft.tv_usec)) { -#ifdef USE_WINDOWS_API - timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; - setsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, sizeof(timeout)); -#else - setsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, - sizeof(struct timeval)); -#endif /* USE_WINDOWS_API */ - } - } -#endif /* SO_RCVTIMEO */ -} - -static void WOLFCRYPT_BIO_DATAGRAM_reset_rcv_timeout(WOLFCRYPT_BIO *bio) -{ -#if defined(SO_RCVTIMEO) - WOLFCRYPT_BIO_DATAGRAM *dgram; - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return; - } - - dgram = (WOLFCRYPT_BIO_DATAGRAM *)bio->ptr; - - /* Is a timer active? */ - if (dgram->next_timeout.tv_sec > 0 || dgram->next_timeout.tv_usec > 0) { -#ifdef USE_WINDOWS_API - int timeout = dgram->socket_timeout.tv_sec * 1000 + - dgram->socket_timeout.tv_usec / 1000; - setsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, sizeof(timeout)); -#else - setsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, &(dgram->socket_timeout), - sizeof(struct timeval)); -#endif - } -#endif -} - -static int WOLFCRYPT_BIO_DATAGRAM_read(WOLFCRYPT_BIO *bio, char *data, int size) -{ - int ret = 0; - WOLFCRYPT_BIO_DATAGRAM *dgram; - - struct { - union { - size_t s; - int i; - } len; - union { - struct sockaddr sa; - struct sockaddr_in sa_in; -#ifdef TEST_IPV6 - struct sockaddr_in6 sa_in6; -#endif - } peer; - } sa; - - if (bio == NULL || data == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - dgram = (WOLFCRYPT_BIO_DATAGRAM *)bio->ptr; - - sa.len.s = 0; - sa.len.i = sizeof(sa.peer); - -#ifdef USE_WINDOWS_API - WSASetLastError(0); -#else - errno = 0; -#endif - - XMEMSET(&sa.peer, 0, sizeof(sa.peer)); - - WOLFCRYPT_BIO_DATAGRAM_adjust_rcv_timeout(bio); - - ret = (int)recvfrom(bio->num, data, size, 0, &sa.peer.sa, (void *)&sa.len); - if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { - if (sa.len.s > sizeof(sa.peer)) - return 0; - - sa.len.i = (int)sa.len.s; - } - - if (!dgram->connected && ret >= 0) - WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); - - WOLFCRYPT_BIO_clear_retry_flags(bio); - if (ret < 0) { - if (WOLFCRYPT_BIO_DATAGRAM_should_retry(ret)) { - WOLFCRYPT_BIO_set_retry_read(bio); -#ifdef USE_WINDOWS_API - dgram->_errno = WSAGetLastError(); -#else - dgram->_errno = errno; -#endif - } - } - - WOLFCRYPT_BIO_DATAGRAM_reset_rcv_timeout(bio); - - return ret; -} - -static int WOLFCRYPT_BIO_DATAGRAM_write(WOLFCRYPT_BIO *bio, - const char *data, int size) -{ - int ret; - WOLFCRYPT_BIO_DATAGRAM *dgram; - - if (bio == NULL || data == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - dgram = (WOLFCRYPT_BIO_DATAGRAM *)bio->ptr; - -#ifdef USE_WINDOWS_API - WSASetLastError(0); -#else - errno = 0; -#endif - - if (dgram->connected) -#ifdef USE_WINDOWS_API - ret = (int)send(bio->num, data, size, 0); -#else - ret = (int)write(bio->num, data, size); -#endif - else { - int peerlen = sizeof(dgram->peer); - - if (dgram->peer.sa.sa_family == AF_INET) - peerlen = sizeof(dgram->peer.sa_in); -#ifdef TEST_IPV6 - else if (dgram->peer.sa.sa_family == AF_INET6) - peerlen = sizeof(dgram->peer.sa_in6); -#endif - ret = (int)sendto(bio->num, data, size, 0, &dgram->peer.sa, peerlen); - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - - if (ret <= 0 && WOLFCRYPT_BIO_DATAGRAM_should_retry(ret)) { - WOLFCRYPT_BIO_set_retry_write(bio); -#ifdef USE_WINDOWS_API - dgram->_errno = WSAGetLastError(); -#else - dgram->_errno = errno; -#endif - } - - return ret; -} - -static long WOLFCRYPT_BIO_DATAGRAM_get_mtu_overhead(WOLFCRYPT_BIO_DATAGRAM *dgram) -{ - long ret; - - if (dgram == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - switch (dgram->peer.sa.sa_family) { - case AF_INET: - ret = 28; - break; -#ifdef TEST_IPV6 - case AF_INET6: - ret = 48; - break; -#endif - default: - ret = 28; - break; - } - - return ret; -} - -static long WOLFCRYPT_BIO_DATAGRAM_ctrl(WOLFCRYPT_BIO *bio, - int cmd, long num, void *ptr) -{ - long ret = 1; - struct sockaddr *to = NULL; - WOLFCRYPT_BIO_DATAGRAM *dgram; - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - dgram = (WOLFCRYPT_BIO_DATAGRAM *)bio->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - num = 0; - - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: - case BIO_C_FILE_SEEK: - case BIO_C_FILE_TELL: - case BIO_CTRL_INFO: - ret = 0; - break; - - case BIO_C_SET_FD: - WOLFCRYPT_BIO_DATAGRAM_clear(bio); - bio->num = *((int *)ptr); - bio->shutdown = (int)num; - bio->init = 1; - break; - - case BIO_C_GET_FD: - if (bio->init) { - if (ptr != NULL) - *((int *)ptr) = bio->num; - ret = bio->num; - } - else - ret = -1; - break; - - case BIO_CTRL_GET_CLOSE: - ret = bio->shutdown; - break; - - case BIO_CTRL_SET_CLOSE: - bio->shutdown = (int)num; - break; - - case BIO_CTRL_DUP: - case BIO_CTRL_FLUSH: - ret = 1; - break; - - case BIO_CTRL_DGRAM_CONNECT: - to = (struct sockaddr *)ptr; - switch (to->sa_family) { - case AF_INET: - XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa_in)); - break; -#ifdef TEST_IPV6 - case AF_INET6: - XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa_in6)); - break; -#endif - default: - XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa)); - break; - } - break; - - /* (Linux)kernel sets DF bit on outgoing IP packets */ - case BIO_CTRL_DGRAM_MTU_DISCOVER: - break; - - case BIO_CTRL_DGRAM_QUERY_MTU: - ret = 0; - break; - - case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: - ret = -WOLFCRYPT_BIO_DATAGRAM_get_mtu_overhead(dgram); - switch (dgram->peer.sa.sa_family) { - case AF_INET: - ret += 576; - break; -#ifdef TEST_IPV6 - case AF_INET6: - ret += 1280; - break; -#endif - default: - ret += 576; - break; - } - break; - - case BIO_CTRL_DGRAM_GET_MTU: - return dgram->mtu; - break; - - case BIO_CTRL_DGRAM_SET_MTU: - dgram->mtu = (int)num; - ret = num; - break; - - case BIO_CTRL_DGRAM_SET_CONNECTED: - to = (struct sockaddr *)ptr; - if (to != NULL) { - dgram->connected = 1; - switch (to->sa_family) { - case AF_INET: - XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa_in)); - break; -#ifdef TEST_IPV6 - case AF_INET6: - XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa_in6)); - break; -#endif - default: - XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa)); - break; - } - } - else { - dgram->connected = 0; - XMEMSET(&dgram->peer, 0, sizeof(dgram->peer)); - } - break; - - case BIO_CTRL_DGRAM_GET_PEER: - switch (dgram->peer.sa.sa_family) { - case AF_INET: - ret = sizeof(dgram->peer.sa_in); - break; -#ifdef TEST_IPV6 - case AF_INET6: - ret = sizeof(dgram->peer.sa_in6); - break; -#endif - default: - ret = sizeof(dgram->peer.sa); - break; - } - - if (num == 0 || num > ret) - num = ret; - XMEMCPY(ptr, &dgram->peer, (ret = num)); - break; - - case BIO_CTRL_DGRAM_SET_PEER: - to = (struct sockaddr *)ptr; - switch (to->sa_family) { - case AF_INET: - XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa_in)); - break; -#ifdef TEST_IPV6 - case AF_INET6: - XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa_in6)); - break; -#endif - default: - XMEMCPY(&dgram->peer, to, sizeof(dgram->peer.sa)); - break; - } - break; - - case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: - XMEMCPY(&dgram->next_timeout, ptr, sizeof(struct timeval)); - break; - -#if defined(SO_RCVTIMEO) - case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: -#ifdef USE_WINDOWS_API - { - struct timeval *tv = (struct timeval *)ptr; - int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; - if (setsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, sizeof(timeout)) < 0) - ret = -1; - } -#else - if (setsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, ptr, - sizeof(struct timeval)) < 0) - ret = -1; -#endif /* USE_WINDOWS_API */ - break; - - case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: - { - union { - size_t s; - int i; - } sz = { 0 }; -#ifdef USE_WINDOWS_API - int timeout; - struct timeval *tv = (struct timeval *)ptr; - - sz.i = sizeof(timeout); - if (getsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, - (void *)&timeout, &sz.i) < 0) - ret = -1; - else { - tv->tv_sec = timeout / 1000; - tv->tv_usec = (timeout % 1000) * 1000; - ret = sizeof(*tv); - } -#else - sz.i = sizeof(struct timeval); - if (getsockopt(bio->num, SOL_SOCKET, SO_RCVTIMEO, - ptr, (void *)&sz) < 0) - ret = -1; - else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) { - if (sz.s > sizeof(struct timeval)) - ret = -1; - else - ret = (int)sz.s; - } - else - ret = sz.i; -#endif /* USE_WINDOWS_API */ - } - break; -# endif /* defined(SO_RCVTIMEO) */ - -# if defined(SO_SNDTIMEO) - case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: -#ifdef USE_WINDOWS_API - { - struct timeval *tv = (struct timeval *)ptr; - int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; - if (setsockopt(bio->num, SOL_SOCKET, SO_SNDTIMEO, - (void *)&timeout, sizeof(timeout)) < 0) - ret = -1; - } -#else - if (setsockopt(bio->num, SOL_SOCKET, SO_SNDTIMEO, ptr, - sizeof(struct timeval)) < 0) - ret = -1; -#endif /* USE_WINDOWS_API */ - break; - - case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: - { - union { - size_t s; - int i; - } sz = { 0 }; -#ifdef USE_WINDOWS_API - int timeout; - struct timeval *tv = (struct timeval *)ptr; - - sz.i = sizeof(timeout); - if (getsockopt(bio->num, SOL_SOCKET, SO_SNDTIMEO, - (void *)&timeout, &sz.i) < 0) - ret = -1; - else { - tv->tv_sec = timeout / 1000; - tv->tv_usec = (timeout % 1000) * 1000; - ret = sizeof(*tv); - } -#else - sz.i = sizeof(struct timeval); - if (getsockopt(bio->num, SOL_SOCKET, SO_SNDTIMEO, - ptr, (void *)&sz) < 0) - ret = -1; - else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) { - if (sz.s > sizeof(struct timeval)) - ret = -1; - else - ret = (int)sz.s; - } - else - ret = sz.i; -#endif /* USE_WINDOWS_API */ - } - break; -#endif /* defined(SO_SNDTIMEO) */ - - case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: - case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: -#ifdef USE_WINDOWS_API - if (dgram->_errno == WSAETIMEDOUT) -#else - if (dgram->_errno == EAGAIN) -#endif - { - ret = 1; - dgram->_errno = 0; - } - else - ret = 0; - break; - - case BIO_CTRL_DGRAM_SET_DONT_FRAG: - ret = -1; - break; - - case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: - ret = WOLFCRYPT_BIO_DATAGRAM_get_mtu_overhead(dgram); - break; - - default: - ret = 0; - break; - } - - return ret; -} - -static int WOLFCRYPT_BIO_DATAGRAM_puts(WOLFCRYPT_BIO *bio, const char *str) -{ - if (bio == NULL || str == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - return WOLFCRYPT_BIO_DATAGRAM_write(bio, str, (int)strlen(str)); -} - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_m_fd.c b/wolfcrypt/src/bio_m_fd.c deleted file mode 100644 index 60dc6951b..000000000 --- a/wolfcrypt/src/bio_m_fd.c +++ /dev/null @@ -1,145 +0,0 @@ -/* bio_m_fd.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include - -static int WOLFCRYPT_BIO_fd_write(WOLFCRYPT_BIO *bio, - const char *buf, int size); -static int WOLFCRYPT_BIO_fd_read(WOLFCRYPT_BIO *bio, char *buf, int size); -static int WOLFCRYPT_BIO_fd_puts(WOLFCRYPT_BIO *bio, const char *str); -static int WOLFCRYPT_BIO_fd_gets(WOLFCRYPT_BIO *bio, char *buf, int size); -static long WOLFCRYPT_BIO_fd_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr); -static int WOLFCRYPT_BIO_fd_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_fd_free(WOLFCRYPT_BIO *bio); - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_fd_method = { - BIO_TYPE_FD, - "File descriptor", - WOLFCRYPT_BIO_fd_write, - WOLFCRYPT_BIO_fd_read, - WOLFCRYPT_BIO_fd_puts, - WOLFCRYPT_BIO_fd_gets, - WOLFCRYPT_BIO_fd_ctrl, - WOLFCRYPT_BIO_fd_new, - WOLFCRYPT_BIO_fd_free, - NULL, -}; - -/* functions are not implemented as not really used in OpenSSL except for two - * cases : - * * get password giving 'fd file' instead of 'file name' - * (see app_get_pass(), apps/apps.c) - * * open STDOUT and STDERR by giving fd instead of name - * (see main(), crypto/threads/mttest.c) - */ -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_fd(void) -{ - WOLFSSL_ERROR(NOT_COMPILED_IN); - return (&WOLFCRYPT_BIO_fd_method); -} - -WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_fd(int fd, int close_flag) -{ - (void)fd; - (void)close_flag; - WOLFSSL_ERROR(NOT_COMPILED_IN); - return NULL; -} - -static int WOLFCRYPT_BIO_fd_new(WOLFCRYPT_BIO *bio) -{ - (void)bio; - WOLFSSL_ERROR(NOT_COMPILED_IN); - return -2; -} - -static int WOLFCRYPT_BIO_fd_free(WOLFCRYPT_BIO *bio) -{ - (void)bio; - WOLFSSL_ERROR(NOT_COMPILED_IN); - return -2; -} - -static int WOLFCRYPT_BIO_fd_read(WOLFCRYPT_BIO *bio, char *buf, int size) -{ - (void)bio; - (void)buf; - (void)size; - WOLFSSL_ERROR(NOT_COMPILED_IN); - return -2; -} - -static int WOLFCRYPT_BIO_fd_write(WOLFCRYPT_BIO *bio, const char *buf, int size) -{ - (void)bio; - (void)buf; - (void)size; - WOLFSSL_ERROR(NOT_COMPILED_IN); - return -2; -} - -static long WOLFCRYPT_BIO_fd_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr) -{ - (void)bio; - (void)ptr; - (void)cmd; - (void)num; - WOLFSSL_ERROR(NOT_COMPILED_IN); - return -2; -} - -static int WOLFCRYPT_BIO_fd_gets(WOLFCRYPT_BIO *bio, char *buf, int size) -{ - (void)bio; - (void)buf; - (void)size; - WOLFSSL_ERROR(NOT_COMPILED_IN); - return -2; -} - -static int WOLFCRYPT_BIO_fd_puts(WOLFCRYPT_BIO *bio, const char *str) -{ - (void)bio; - (void)str; - WOLFSSL_ERROR(NOT_COMPILED_IN); - return -2; -} - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_m_file.c b/wolfcrypt/src/bio_m_file.c deleted file mode 100644 index d3bdebd11..000000000 --- a/wolfcrypt/src/bio_m_file.c +++ /dev/null @@ -1,357 +0,0 @@ -/* bio_m_file.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#include - -#ifdef OPENSSL_EXTRA - -#ifndef NO_FILESYSTEM - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include -#include - - -/* TO BE REMOVED */ -#ifndef XFERROR -#define XFERROR ferror -#endif - -#ifndef XFILENO -#define XFILENO fileno -#endif - -#if defined(USE_WINDOWS_API) -#include - #ifndef XSETMODE - #define XSETMODE _setmode - #endif -#endif /* USE_WINDOWS_API */ - -#ifndef XFFLUSH -#define XFFLUSH fflush -#endif - -#ifndef XFEOF -#define XFEOF feof -#endif - -#ifndef XFGETS -#define XFGETS fgets -#endif - -static int WOLFCRYPT_BIO_file_write(WOLFCRYPT_BIO *bio, - const char *buf, int size); -static int WOLFCRYPT_BIO_file_read(WOLFCRYPT_BIO *bio, char *buf, int size); -static int WOLFCRYPT_BIO_file_puts(WOLFCRYPT_BIO *bio, const char *str); -static int WOLFCRYPT_BIO_file_gets(WOLFCRYPT_BIO *bio, char *buf, int size); -static long WOLFCRYPT_BIO_file_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr); -static int WOLFCRYPT_BIO_file_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_file_free(WOLFCRYPT_BIO *bio); - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_file_method = { - BIO_TYPE_FILE, - "FILE pointer", - WOLFCRYPT_BIO_file_write, - WOLFCRYPT_BIO_file_read, - WOLFCRYPT_BIO_file_puts, - WOLFCRYPT_BIO_file_gets, - WOLFCRYPT_BIO_file_ctrl, - WOLFCRYPT_BIO_file_new, - WOLFCRYPT_BIO_file_free, - NULL, -}; - -WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_file(const char *name, const char *mode) -{ - XFILE f; - - if (name == NULL || mode == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return NULL; - } - - f = XFOPEN(name, mode); - if (f == NULL) { - WOLFSSL_ERROR(BIO_FILE_OPEN_E); - return NULL; - } - - return WOLFCRYPT_BIO_new_fp(f, BIO_CLOSE); -} - -WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_fp(XFILE f, int close_flag) -{ - WOLFCRYPT_BIO *bio; - - if (f == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return NULL; - } - - bio = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_s_file()); - if (bio == NULL) - return NULL; - - WOLFCRYPT_BIO_set_fp(bio, f, close_flag); - - return bio; -} - -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_file(void) -{ - return (&WOLFCRYPT_BIO_file_method); -} - -static int WOLFCRYPT_BIO_file_new(WOLFCRYPT_BIO *bio) -{ - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - bio->init = 0; - bio->num = 0; - bio->ptr = NULL; - - return 1; -} - -static int WOLFCRYPT_BIO_file_free(WOLFCRYPT_BIO *bio) -{ - if (bio == NULL) - return 0; - - if (!bio->shutdown || !bio->init) - return 1; - - if (bio->ptr != NULL) { - XFCLOSE(bio->ptr); - bio->ptr = NULL; - } - bio->init = 0; - - return 1; -} - -static int WOLFCRYPT_BIO_file_read(WOLFCRYPT_BIO *bio, char *buf, int size) -{ - int ret = 0; - - if (bio == NULL || !bio->init || bio->ptr == NULL || buf == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - ret = (int)XFREAD(buf, sizeof(char), size, (FILE *)bio->ptr); - if (ret == 0 && XFERROR((FILE *)bio->ptr)) { - WOLFSSL_ERROR(BIO_FILE_READ_E); - ret = -1; - } - - return ret; -} - -static int WOLFCRYPT_BIO_file_write(WOLFCRYPT_BIO *bio, const char *buf, int size) -{ - int ret = 0; - - if (bio == NULL || !bio->init || bio->ptr == NULL || buf == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - ret = (int)XFWRITE(buf, sizeof(char), size, (FILE *)bio->ptr); - if (ret == 0 && XFERROR((FILE *)bio->ptr)) { - WOLFSSL_ERROR(BIO_FILE_WRITE_E); - ret = -1; - } - - return ret; -} - -static long WOLFCRYPT_BIO_file_ctrl(WOLFCRYPT_BIO *bio, - int cmd, long num, void *ptr) -{ - long ret = 1; - char buf[4]; - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - switch (cmd) { - case BIO_C_FILE_SEEK: - case BIO_CTRL_RESET: - ret = (long)XFSEEK((FILE *)bio->ptr, num, 0); - break; - - case BIO_CTRL_EOF: - ret = (long)XFEOF((FILE *)bio->ptr); - break; - - case BIO_C_FILE_TELL: - case BIO_CTRL_INFO: - ret = (long)XFTELL((FILE *)bio->ptr); - break; - - case BIO_C_SET_FILE_PTR: - WOLFCRYPT_BIO_file_free(bio); - bio->shutdown = (int)num & BIO_CLOSE; - bio->ptr = ptr; - bio->init = 1; - -#ifdef USE_WINDOWS_API - { - int fd; - - fd = XFILENO((FILE *)bio->ptr); - if (num & BIO_FP_TEXT) - XSETMODE(fd, O_TEXT); - else - XSETMODE(fd, O_BINARY); - } -#endif /* USE_WINDOWS_API */ - break; - - case BIO_C_SET_FILENAME: - WOLFCRYPT_BIO_file_free(bio); - bio->shutdown = (int)num & BIO_CLOSE; - if (num & BIO_FP_APPEND) { - if (num & BIO_FP_READ) - XSTRNCPY(buf, "a+", sizeof(buf) - 1); - else - XSTRNCPY(buf, "a", sizeof(buf) - 1); - } - else if (num & BIO_FP_READ) { - if (num & BIO_FP_WRITE) - XSTRNCPY(buf, "r+", sizeof(buf) - 1); - else - XSTRNCPY(buf, "r", sizeof(buf)); - } - else if (num & BIO_FP_WRITE) - XSTRNCPY(buf, "w", sizeof(buf) - 1); - else { - WOLFSSL_ERROR(BIO_FILE_MODE_E); - ret = 0; - break; - } - - if (num & BIO_FP_TEXT) - XSTRNCAT(buf, "t", sizeof(buf) - 1); - else - XSTRNCAT(buf, "b", sizeof(buf) - 1); - - bio->ptr = XFOPEN(ptr, buf); - if (bio->ptr == NULL) { - WOLFSSL_ERROR(BIO_FILE_OPEN_E); - ret = 0; - break; - } - bio->init = 1; - - break; - - case BIO_C_GET_FILE_PTR: - /* the ptr parameter is a FILE ** in this case. */ - if (ptr != NULL) - *((FILE **)ptr) = (FILE *)bio->ptr; - break; - - case BIO_CTRL_GET_CLOSE: - ret = (long)bio->shutdown; - break; - - case BIO_CTRL_SET_CLOSE: - bio->shutdown = (int)num; - break; - - case BIO_CTRL_FLUSH: - XFFLUSH((FILE *)bio->ptr); - break; - - case BIO_CTRL_DUP: - ret = 1; - break; - - case BIO_CTRL_WPENDING: - case BIO_CTRL_PENDING: - case BIO_CTRL_PUSH: - case BIO_CTRL_POP: - ret = 0; - break; - - default: - ret = 0; - break; - } - - return ret; -} - -static int WOLFCRYPT_BIO_file_gets(WOLFCRYPT_BIO *bio, char *buf, int size) -{ - if (bio == NULL || bio->ptr == NULL || buf == NULL || size <= 0) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - /* init buffer */ - XMEMSET(buf, 0, size); - - if ((XFGETS(buf, size, (FILE *)bio->ptr) == NULL) && - XFERROR((FILE *)bio->ptr)) { - WOLFSSL_ERROR(BIO_FILE_GETS_E); - return -1; - } - - return (int)strlen(buf); -} - -static int WOLFCRYPT_BIO_file_puts(WOLFCRYPT_BIO *bio, const char *str) -{ - if (bio == NULL || bio->ptr == NULL || str == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - return WOLFCRYPT_BIO_file_write(bio, str, (int)strlen(str)); -} - -#endif /* NO_FILESYSTEM */ - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_m_mem.c b/wolfcrypt/src/bio_m_mem.c deleted file mode 100644 index c54ec07d2..000000000 --- a/wolfcrypt/src/bio_m_mem.c +++ /dev/null @@ -1,423 +0,0 @@ -/* bio_m_mem.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include -#include - - -/* wolfSSL buffer type */ -typedef struct { - byte* data; - word32 length; -} WOLFCRYPT_BUF_MEM; - -static WOLFCRYPT_BUF_MEM *WOLFCRYPT_BUF_MEM_new(void) -{ - WOLFCRYPT_BUF_MEM *buf; - - buf = (WOLFCRYPT_BUF_MEM *)XMALLOC(sizeof(WOLFCRYPT_BUF_MEM), - 0, DYNAMIC_TYPE_OPENSSL); - if (buf == NULL) { - WOLFSSL_ERROR(MEMORY_E); - return NULL; - } - - buf->length = 0; - buf->data = NULL; - return buf; -} - -static void WOLFCRYPT_BUF_MEM_free(WOLFCRYPT_BUF_MEM *buf) -{ - if (buf == NULL) - return; - - if (buf->data != NULL) { - XMEMSET(buf->data, 0, buf->length); - XFREE(buf->data, 0, DYNAMIC_TYPE_OPENSSL); - } - - XFREE(buf, 0, DYNAMIC_TYPE_OPENSSL); -} - -static int WOLFCRYPT_BUF_MEM_grow(WOLFCRYPT_BUF_MEM *buf, size_t len) -{ - if (buf == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - /* size reduction, clean unused */ - if (buf->length >= len) { - if (buf->data == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - buf->length = (word32)len; - return (int)len; - } - - if (buf->data == NULL) - buf->data = XMALLOC(len, 0, DYNAMIC_TYPE_OPENSSL); - else - buf->data = XREALLOC(buf->data, buf->length+len, - 0, DYNAMIC_TYPE_OPENSSL); - if (buf->data == NULL) { - WOLFSSL_ERROR(MEMORY_E); - return -1; - } - - XMEMSET(&buf->data[buf->length], 0, len - buf->length); - buf->length = (word32)len; - - return (int)len; -} - -static int WOLFCRYPT_BUF_MEM_grow_clean(WOLFCRYPT_BUF_MEM *buf, size_t len) -{ - int ret, idx = -1; - size_t size; - - if (buf == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - if (buf->length >= len) { - idx = buf->length; - size = buf->length - len; - } - - ret = WOLFCRYPT_BUF_MEM_grow(buf, len); - if (ret && idx != -1) - XMEMSET(&buf->data[idx], 0, size); - - return ret; -} - - -static int WOLFCRYPT_BIO_mem_write(WOLFCRYPT_BIO *bio, - const char *buf, int size); -static int WOLFCRYPT_BIO_mem_read(WOLFCRYPT_BIO *bio, char *buf, int size); -static int WOLFCRYPT_BIO_mem_puts(WOLFCRYPT_BIO *bio, const char *str); -static int WOLFCRYPT_BIO_mem_gets(WOLFCRYPT_BIO *bio, char *buf, int size); -static long WOLFCRYPT_BIO_mem_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr); -static int WOLFCRYPT_BIO_mem_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_mem_free(WOLFCRYPT_BIO *bio); - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_mem_method = { - BIO_TYPE_MEM, - "Memory buffer", - WOLFCRYPT_BIO_mem_write, - WOLFCRYPT_BIO_mem_read, - WOLFCRYPT_BIO_mem_puts, - WOLFCRYPT_BIO_mem_gets, - WOLFCRYPT_BIO_mem_ctrl, - WOLFCRYPT_BIO_mem_new, - WOLFCRYPT_BIO_mem_free, - NULL, -}; - -WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_mem_buf(void *data, int len) -{ - WOLFCRYPT_BIO *bio; - size_t size; - - if (data == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return NULL; - } - - size = (len < 0) ? strlen((char *)data) : (size_t)len; - - bio = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_s_mem()); - if (bio == NULL) - return NULL; - - ((WOLFCRYPT_BUF_MEM *)bio->ptr)->data = (byte*)data; - ((WOLFCRYPT_BUF_MEM *)bio->ptr)->length = (word32)size; - - bio->flags |= BIO_FLAGS_MEM_RDONLY; - bio->num = 0; - - return bio; -} - -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_mem(void) -{ - return (&WOLFCRYPT_BIO_mem_method); -} - -static int WOLFCRYPT_BIO_mem_new(WOLFCRYPT_BIO *bio) -{ - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - bio->ptr = WOLFCRYPT_BUF_MEM_new(); - if (bio->ptr == NULL) - return -1; - - bio->shutdown = 1; - bio->init = 1; - bio->num = -1; - - return 1; -} - -static int WOLFCRYPT_BIO_mem_free(WOLFCRYPT_BIO *bio) -{ - if (bio == NULL) - return -1; - - if (!bio->shutdown || !bio->init) - return 1; - - if (bio->ptr != NULL) { - if (bio->flags & BIO_FLAGS_MEM_RDONLY) - ((WOLFCRYPT_BUF_MEM *)bio->ptr)->data = NULL; - - WOLFCRYPT_BUF_MEM_free(bio->ptr); - bio->ptr = NULL; - } - - bio->init = 0; - return 1; -} - -static int WOLFCRYPT_BIO_mem_read(WOLFCRYPT_BIO *bio, char *data, int size) -{ - int ret = -1; - WOLFCRYPT_BUF_MEM *wbmptr; - - if (bio == NULL || !bio->init || bio->ptr == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - - wbmptr = (WOLFCRYPT_BUF_MEM *)bio->ptr; - - ret = (size >= 0 && (size_t)size > wbmptr->length) ? - (int)wbmptr->length : size; - - if (data != NULL && ret > 0) { - XMEMCPY(data, wbmptr->data, ret); - wbmptr->length -= ret; - if (bio->flags & BIO_FLAGS_MEM_RDONLY) - wbmptr->data += ret; - else - XMEMMOVE(&(wbmptr->data[0]), &(wbmptr->data[ret]), wbmptr->length); - } - else if (wbmptr->length == 0) { - ret = bio->num; - if (ret != 0) - WOLFCRYPT_BIO_set_retry_read(bio); - } - - return ret; -} - -static int WOLFCRYPT_BIO_mem_write(WOLFCRYPT_BIO *bio, - const char *data, int size) -{ - int init_len; - WOLFCRYPT_BUF_MEM *wbmptr; - - if (bio == NULL || !bio->init || data == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - if (bio->flags & BIO_FLAGS_MEM_RDONLY) { - WOLFSSL_ERROR(BIO_MEM_WRITE_E); - return -1; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - - wbmptr = (WOLFCRYPT_BUF_MEM *)bio->ptr; - init_len = wbmptr->length; - - if (WOLFCRYPT_BUF_MEM_grow_clean(wbmptr, wbmptr->length + size) != - (int)(init_len + size)) - return -1; - - XMEMCPY(&(wbmptr->data[init_len]), data, size); - - return size; -} - -static long WOLFCRYPT_BIO_mem_ctrl(WOLFCRYPT_BIO *bio, - int cmd, long num, void *ptr) -{ - WOLFCRYPT_BUF_MEM *wbmptr; - long ret = 1; - - if (bio == NULL || bio->ptr == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - wbmptr = (WOLFCRYPT_BUF_MEM *)bio->ptr; - - switch (cmd) { - case BIO_CTRL_RESET: - if (wbmptr->data == NULL) - break; - - /* For read only case reset to the start again */ - if (bio->flags & BIO_FLAGS_MEM_RDONLY) - wbmptr->data -= wbmptr->length; - else { - XMEMSET(wbmptr->data, 0, wbmptr->length); - wbmptr->length = 0; - } - break; - - case BIO_CTRL_EOF: - ret = (long)(wbmptr->length == 0); - break; - - case BIO_C_SET_BUF_MEM_EOF_RETURN: - bio->num = (int)num; - break; - - case BIO_CTRL_INFO: - ret = (long)wbmptr->length; - if (ptr != NULL) - *((char **)ptr) = (char *)&(wbmptr->data[0]); - break; - - case BIO_C_SET_BUF_MEM: - WOLFCRYPT_BIO_mem_free(bio); - bio->shutdown = (int)num; - bio->ptr = ptr; - break; - - case BIO_C_GET_BUF_MEM_PTR: - if (ptr != NULL) - *((char **)ptr) = (char *)wbmptr; - break; - - case BIO_CTRL_GET_CLOSE: - ret = (long)bio->shutdown; - break; - - case BIO_CTRL_SET_CLOSE: - bio->shutdown = (int)num; - break; - - case BIO_CTRL_WPENDING: - ret = 0; - break; - - case BIO_CTRL_PENDING: - ret = (long)wbmptr->length; - break; - - case BIO_CTRL_DUP: - case BIO_CTRL_FLUSH: - ret = 1; - break; - - case BIO_CTRL_PUSH: - case BIO_CTRL_POP: - ret = 0; - break; - - default: - ret = 0; - break; - } - - return ret; -} - -static int WOLFCRYPT_BIO_mem_gets(WOLFCRYPT_BIO *bio, char *buf, int size) -{ - WOLFCRYPT_BUF_MEM *wbmptr; - int i, blen; - - if (bio == NULL || bio->ptr == NULL || buf == NULL || size <= 0) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - WOLFCRYPT_BIO_clear_retry_flags(bio); - - wbmptr = (WOLFCRYPT_BUF_MEM *)bio->ptr; - - if ((int)wbmptr->length > (size - 1)) - blen = size - 1; - else if (wbmptr->length <= 0) { - *buf = '\0'; - return 0; - } - else - blen = wbmptr->length; - - for (i = 0; i < blen; i++) { - if (wbmptr->data[i] == '\n') { - i++; - break; - } - } - - i = WOLFCRYPT_BIO_mem_read(bio, buf, i); - if (i > 0) - buf[i] = '\0'; - - return i; -} - -static int WOLFCRYPT_BIO_mem_puts(WOLFCRYPT_BIO *bio, const char *str) -{ - if (bio == NULL || str == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - return WOLFCRYPT_BIO_mem_write(bio, str, (int)strlen(str)); -} - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_m_null.c b/wolfcrypt/src/bio_m_null.c deleted file mode 100644 index 0f2ae47bb..000000000 --- a/wolfcrypt/src/bio_m_null.c +++ /dev/null @@ -1,152 +0,0 @@ -/* bio_m_null.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include - -static int WOLFCRYPT_BIO_null_write(WOLFCRYPT_BIO *bio, - const char *buf, int size); -static int WOLFCRYPT_BIO_null_read(WOLFCRYPT_BIO *bio, char *buf, int size); -static int WOLFCRYPT_BIO_null_puts(WOLFCRYPT_BIO *bio, const char *str); -static int WOLFCRYPT_BIO_null_gets(WOLFCRYPT_BIO *bio, char *buf, int size); -static long WOLFCRYPT_BIO_null_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr); -static int WOLFCRYPT_BIO_null_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_null_free(WOLFCRYPT_BIO *bio); - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_null_method = { - BIO_TYPE_NULL, - "NULL", - WOLFCRYPT_BIO_null_write, - WOLFCRYPT_BIO_null_read, - WOLFCRYPT_BIO_null_puts, - WOLFCRYPT_BIO_null_gets, - WOLFCRYPT_BIO_null_ctrl, - WOLFCRYPT_BIO_null_new, - WOLFCRYPT_BIO_null_free, - NULL, -}; - -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_null(void) -{ - return (&WOLFCRYPT_BIO_null_method); -} - -static int WOLFCRYPT_BIO_null_new(WOLFCRYPT_BIO *bio) -{ - if (bio == NULL) - return 0; - - bio->init = 1; - bio->num = 0; - bio->ptr = NULL; - - return 1; -} - -static int WOLFCRYPT_BIO_null_free(WOLFCRYPT_BIO *bio) -{ - return bio == NULL ? 0 : 1; -} - -static int WOLFCRYPT_BIO_null_read(WOLFCRYPT_BIO *bio, char *buf, int size) -{ - (void)bio; - (void)buf; - (void)size; - - return 0; -} - -static int WOLFCRYPT_BIO_null_write(WOLFCRYPT_BIO *bio, const char *buf, int size) -{ - (void)bio; - (void)buf; - - return size; -} - -static long WOLFCRYPT_BIO_null_ctrl(WOLFCRYPT_BIO *bio, int cmd, long num, void *ptr) -{ - (void)bio; - (void)ptr; - (void)num; - - long ret = 1; - - switch (cmd) { - case BIO_CTRL_RESET: - case BIO_CTRL_EOF: - case BIO_CTRL_SET: - case BIO_CTRL_SET_CLOSE: - case BIO_CTRL_FLUSH: - case BIO_CTRL_DUP: - ret = 1; - break; - case BIO_CTRL_GET_CLOSE: - case BIO_CTRL_INFO: - case BIO_CTRL_GET: - case BIO_CTRL_PENDING: - case BIO_CTRL_WPENDING: - default: - ret = 0; - break; - } - - return ret; -} - -static int WOLFCRYPT_BIO_null_gets(WOLFCRYPT_BIO *bio, char *buf, int size) -{ - (void)bio; - (void)buf; - (void)size; - - return 0; -} - -static int WOLFCRYPT_BIO_null_puts(WOLFCRYPT_BIO *bio, const char *str) -{ - (void)bio; - - if (str == NULL) - return 0; - - return (int)strlen(str); -} - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/bio_m_sock.c b/wolfcrypt/src/bio_m_sock.c deleted file mode 100644 index c1dac2e61..000000000 --- a/wolfcrypt/src/bio_m_sock.c +++ /dev/null @@ -1,305 +0,0 @@ -/* bio_m_sock.c - * - * Copyright (C) 2006-2015 wolfSSL Inc. - * - * This file is part of wolfSSL. (formerly known as CyaSSL) - * - * wolfSSL is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * wolfSSL is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include - -#ifdef OPENSSL_EXTRA - -#include -#include - -#ifdef NO_INLINE -#include -#else -#include -#endif - -#include - -static int WOLFCRYPT_BIO_sock_write(WOLFCRYPT_BIO *bio, - const char *data, int size); -static int WOLFCRYPT_BIO_sock_read(WOLFCRYPT_BIO *bio, char *data, int size); -static int WOLFCRYPT_BIO_sock_puts(WOLFCRYPT_BIO *bio, const char *str); -static long WOLFCRYPT_BIO_sock_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long num, void *ptr); -static int WOLFCRYPT_BIO_sock_new(WOLFCRYPT_BIO *bio); -static int WOLFCRYPT_BIO_sock_free(WOLFCRYPT_BIO *bio); - -static WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_sock_method = { - BIO_TYPE_SOCKET, - "Socket", - WOLFCRYPT_BIO_sock_write, - WOLFCRYPT_BIO_sock_read, - WOLFCRYPT_BIO_sock_puts, - NULL, /* gets */ - WOLFCRYPT_BIO_sock_ctrl, - WOLFCRYPT_BIO_sock_new, - WOLFCRYPT_BIO_sock_free, - NULL, -}; - -WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_socket(void) -{ - return (&WOLFCRYPT_BIO_sock_method); -} - -WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_socket(int fd, int close_flag) -{ - WOLFCRYPT_BIO *ret; - - ret = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_s_socket()); - if (ret == NULL) { - WOLFSSL_ERROR(MEMORY_E); - return NULL; - } - - WOLFCRYPT_BIO_set_fd(ret, fd, close_flag); - return ret; -} - -static int WOLFCRYPT_BIO_sock_new(WOLFCRYPT_BIO *bio) -{ - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - bio->init = 0; - bio->num = 0; /* used for fd */ - bio->ptr = NULL; - bio->flags = 0; - - return 1; -} - -static int WOLFCRYPT_BIO_sock_free(WOLFCRYPT_BIO *bio) -{ - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return 0; - } - - if (!bio->shutdown) - return 1; - - if (bio->init) { - shutdown(bio->num, SHUT_RDWR); -#ifdef USE_WINDOWS_API - closesocket(bio->num); -#else - close(bio->num); -#endif - } - - bio->init = 0; - bio->flags = 0; - - return 1; -} - -static int WOLFCRYPT_BIO_sock_read(WOLFCRYPT_BIO *bio, char *data, int size) -{ - int ret; - - if (bio == NULL || !bio->init || data == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - -#ifdef USE_WINDOWS_API - WSASetLastError(0); - ret = (int)recv(bio->num, data, size, 0); -#else - errno = 0; - ret = (int)read(bio->num, data, size); -#endif - - WOLFCRYPT_BIO_clear_retry_flags(bio); - if (ret <= 0) { - if (WOLFCRYPT_BIO_sock_should_retry(ret)) - WOLFCRYPT_BIO_set_retry_read(bio); - } - - return ret; -} - -static int WOLFCRYPT_BIO_sock_write(WOLFCRYPT_BIO *bio, - const char *data, int size) -{ - int ret; - - if (bio == NULL || !bio->init || data == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - -#ifdef USE_WINDOWS_API - WSASetLastError(0); - ret = (int)send(bio->num, data, size, 0); -#else - errno = 0; - ret = (int)write(bio->num, data, size); -#endif - - WOLFCRYPT_BIO_clear_retry_flags(bio); - if (ret <= 0) { - if (WOLFCRYPT_BIO_sock_should_retry(ret)) - WOLFCRYPT_BIO_set_retry_write(bio); - } - - return ret; -} - -static long WOLFCRYPT_BIO_sock_ctrl(WOLFCRYPT_BIO *bio, - int cmd, long num, void *ptr) -{ - long ret = 1; - - if (bio == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - switch (cmd) { - case BIO_C_SET_FD: - WOLFCRYPT_BIO_sock_free(bio); - bio->num = *((int *)ptr); - bio->shutdown = (int)num; - bio->init = 1; - break; - - case BIO_C_GET_FD: - if (bio->init) { - if (ptr != NULL) - *((int *)ptr) = bio->num; - ret = bio->num; - } - else - ret = -1; - break; - - case BIO_CTRL_GET_CLOSE: - ret = bio->shutdown; - break; - - case BIO_CTRL_SET_CLOSE: - bio->shutdown = (int)num; - break; - - case BIO_CTRL_DUP: - case BIO_CTRL_FLUSH: - ret = 1; - break; - - default: - ret = 0; - break; - } - - return ret; -} - -static int WOLFCRYPT_BIO_sock_puts(WOLFCRYPT_BIO *bio, const char *str) -{ - if (bio == NULL || str == NULL) { - WOLFSSL_ERROR(BAD_FUNC_ARG); - return -1; - } - - return WOLFCRYPT_BIO_sock_write(bio, str, (int)strlen(str)); -} - -int WOLCRYPT_BIO_sock_non_fatal_error(int err) -{ - switch (err) { -#if defined(WSAEWOULDBLOCK) - case WSAEWOULDBLOCK: -#endif - -#ifdef EWOULDBLOCK - #ifdef WSAEWOULDBLOCK - #if WSAEWOULDBLOCK != EWOULDBLOCK - case EWOULDBLOCK: - #endif - #else - case EWOULDBLOCK: - #endif -#endif - -#if defined(ENOTCONN) - case ENOTCONN: -#endif - -#ifdef EINTR - case EINTR: -#endif - -#ifdef EAGAIN - #if EWOULDBLOCK != EAGAIN - case EAGAIN: - #endif -#endif - -#ifdef EPROTO - case EPROTO: -#endif - -#ifdef EINPROGRESS - case EINPROGRESS: -#endif - -#ifdef EALREADY - case EALREADY: -#endif - return 1; - break; - - default: - break; - } - - return 0; -} - -int WOLFCRYPT_BIO_sock_should_retry(int i) -{ - if (!i || i == -1) { - int ret; -#ifdef USE_WINDOWS_API - ret = WSAGetLastError(); -#else - ret = errno; -#endif - return WOLCRYPT_BIO_sock_non_fatal_error(ret); - } - - return 0; -} - - -#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/compat-wolfssl.c b/wolfcrypt/src/compat-wolfssl.c new file mode 100644 index 000000000..5e837d1da --- /dev/null +++ b/wolfcrypt/src/compat-wolfssl.c @@ -0,0 +1,1572 @@ +/* compat-wolfssl.c + * + * Copyright (C) 2006-2015 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include + +#include +#include + +#ifdef NO_INLINE +#include +#else +#include +#endif + +#include + + +#ifdef OPENSSL_EXTRA + +#ifndef WOLFSSL_HAVE_MIN +#define WOLFSSL_HAVE_MIN + +static INLINE word32 min(word32 a, word32 b) +{ + return a > b ? b : a; +} + +#endif /* WOLFSSSL_HAVE_MIN */ + +#ifndef NO_MD5 +void wc_MD5_Init(WOLFCRYPT_MD5_CTX* md5) +{ + typedef char md5_test[sizeof(WOLFCRYPT_MD5_CTX) >= sizeof(Md5) ? 1 : -1]; + (void)sizeof(md5_test); + + WOLFSSL_ENTER("MD5_Init"); + wc_InitMd5((Md5*)md5); +} + +void wc_MD5_Update(WOLFCRYPT_MD5_CTX* md5, const void* input, unsigned long sz) +{ + WOLFSSL_ENTER("wc_MD5_Update"); + wc_Md5Update((Md5*)md5, (const byte*)input, (word32)sz); +} + +void wc_MD5_Final(byte* input, WOLFCRYPT_MD5_CTX* md5) +{ + WOLFSSL_ENTER("MD5_Final"); + wc_Md5Final((Md5*)md5, input); +} +#endif /* NO_MD5 */ + + +#ifndef NO_SHA +void wc_SHA_Init(WOLFCRYPT_SHA_CTX* sha) +{ + typedef char sha_test[sizeof(WOLFCRYPT_SHA_CTX) >= sizeof(Sha) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA_Init"); + wc_InitSha((Sha*)sha); /* OpenSSL compat, no ret */ +} + +void wc_SHA_Update(WOLFCRYPT_SHA_CTX* sha, const void* input, unsigned long sz) +{ + WOLFSSL_ENTER("SHA_Update"); + wc_ShaUpdate((Sha*)sha, (const byte*)input, (word32)sz); +} + +void wc_SHA_Final(byte* input, WOLFCRYPT_SHA_CTX* sha) +{ + WOLFSSL_ENTER("SHA_Final"); + wc_ShaFinal((Sha*)sha, input); +} + +void wc_SHA1_Init(WOLFCRYPT_SHA_CTX* sha) +{ + WOLFSSL_ENTER("SHA1_Init"); + wc_SHA_Init(sha); +} + +void wc_SHA1_Update(WOLFCRYPT_SHA_CTX* sha, const void* input, unsigned long sz) +{ + WOLFSSL_ENTER("SHA1_Update"); + wc_SHA_Update(sha, input, sz); +} + +void wc_SHA1_Final(byte* input, WOLFCRYPT_SHA_CTX* sha) +{ + WOLFSSL_ENTER("SHA1_Final"); + wc_SHA_Final(input, sha); +} +#endif /* NO_SHA */ + + +void wc_SHA256_Init(WOLFCRYPT_SHA256_CTX* sha256) +{ + typedef char sha_test[sizeof(WOLFCRYPT_SHA256_CTX)>=sizeof(Sha256) ? 1:-1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA256_Init"); + wc_InitSha256((Sha256*)sha256); /* OpenSSL compat, no error */ +} + +void wc_SHA256_Update(WOLFCRYPT_SHA256_CTX* sha, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA256_Update"); + wc_Sha256Update((Sha256*)sha, (const byte*)input, (word32)sz); + /* OpenSSL compat, no error */ +} + +void wc_SHA256_Final(byte* input, WOLFCRYPT_SHA256_CTX* sha) +{ + WOLFSSL_ENTER("SHA256_Final"); + wc_Sha256Final((Sha256*)sha, input); + /* OpenSSL compat, no error */ +} + + +#ifdef WOLFSSL_SHA384 +void wc_SHA384_Init(WOLFCRYPT_SHA384_CTX* sha) +{ + typedef char sha_test[sizeof(WOLFCRYPT_SHA384_CTX)>=sizeof(Sha384) ? 1:-1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA384_Init"); + wc_InitSha384((Sha384*)sha); /* OpenSSL compat, no error */ +} + +void wc_SHA384_Update(WOLFCRYPT_SHA384_CTX* sha, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA384_Update"); + wc_Sha384Update((Sha384*)sha, (const byte*)input, (word32)sz); + /* OpenSSL compat, no error */ +} + +void wc_SHA384_Final(byte* input, WOLFCRYPT_SHA384_CTX* sha) +{ + WOLFSSL_ENTER("SHA384_Final"); + wc_Sha384Final((Sha384*)sha, input); + /* OpenSSL compat, no error */ +} +#endif /* WOLFSSL_SHA384 */ + + +#ifdef WOLFSSL_SHA512 +void wc_SHA512_Init(WOLFCRYPT_SHA512_CTX* sha) +{ + typedef char sha_test[sizeof(WOLFCRYPT_SHA512_CTX)>=sizeof(Sha512) ? 1:-1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA512_Init"); + wc_InitSha512((Sha512*)sha); /* OpenSSL compat, no error */ +} + +void wc_SHA512_Update(WOLFCRYPT_SHA512_CTX* sha, const void* input, + unsigned long sz) +{ + WOLFSSL_ENTER("SHA512_Update"); + wc_Sha512Update((Sha512*)sha, (const byte*)input, (word32)sz); + /* OpenSSL compat, no error */ +} + +void wc_SHA512_Final(byte* input, WOLFCRYPT_SHA512_CTX* sha) +{ + WOLFSSL_ENTER("SHA512_Final"); + wc_Sha512Final((Sha512*)sha, input); + /* OpenSSL compat, no error */ +} +#endif /* WOLFSSL_SHA512 */ + +void wc_HMAC_Init(WOLFCRYPT_HMAC_CTX* ctx, const void* key, int keylen, + const WOLFCRYPT_EVP_MD* type) +{ + WOLFSSL_MSG("wc_HMAC_Init"); + + if (ctx == NULL) { + WOLFSSL_MSG("no ctx on init"); + return; + } + + if (type) { + WOLFSSL_MSG("init has type"); + + if (XSTRNCMP(type, "MD5", 3) == 0) { + WOLFSSL_MSG("md5 hmac"); + ctx->type = MD5; + } + else if (XSTRNCMP(type, "SHA256", 6) == 0) { + WOLFSSL_MSG("sha256 hmac"); + ctx->type = SHA256; + } + + /* has to be last since would pick or 256, 384, or 512 too */ + else if (XSTRNCMP(type, "SHA", 3) == 0) { + WOLFSSL_MSG("sha hmac"); + ctx->type = SHA; + } + else { + WOLFSSL_MSG("bad init type"); + } + } + + if (key && keylen) { + WOLFSSL_MSG("keying hmac"); + wc_HmacSetKey(&ctx->hmac, ctx->type, (const byte*)key, (word32)keylen); + /* OpenSSL compat, no error */ + } +} + + +void wc_HMAC_Update(WOLFCRYPT_HMAC_CTX* ctx, const unsigned char* data, int len) +{ + WOLFSSL_MSG("wc_HMAC_Update"); + + if (ctx && data) { + WOLFSSL_MSG("updating hmac"); + wc_HmacUpdate(&ctx->hmac, data, (word32)len); + /* OpenSSL compat, no error */ + } +} + + +void wc_HMAC_Final(WOLFCRYPT_HMAC_CTX* ctx, unsigned char* hash, + unsigned int* len) +{ + WOLFSSL_MSG("wc_HMAC_Final"); + + if (ctx && hash) { + WOLFSSL_MSG("final hmac"); + wc_HmacFinal(&ctx->hmac, hash); + /* OpenSSL compat, no error */ + + if (len) { + WOLFSSL_MSG("setting output len"); + switch (ctx->type) { + case MD5: + *len = MD5_DIGEST_SIZE; + break; + + case SHA: + *len = SHA_DIGEST_SIZE; + break; + + case SHA256: + *len = SHA256_DIGEST_SIZE; + break; + + default: + WOLFSSL_MSG("bad hmac type"); + } + } + } +} + + +void wc_HMAC_cleanup(WOLFCRYPT_HMAC_CTX* ctx) +{ + (void)ctx; + + WOLFSSL_MSG("wc_HMAC_cleanup"); +} + +unsigned char* wc_HMAC(const WOLFCRYPT_EVP_MD* evp_md, const void* key, + int key_len, const unsigned char* d, int n, + unsigned char* md, unsigned int* md_len) +{ + int type; + unsigned char* ret = NULL; +#ifdef WOLFSSL_SMALL_STACK + Hmac* hmac = NULL; +#else + Hmac hmac[1]; +#endif + + WOLFSSL_ENTER("HMAC"); + if (!md) + return NULL; /* no static buffer support */ + + if (XSTRNCMP(evp_md, "MD5", 3) == 0) + type = MD5; + else if (XSTRNCMP(evp_md, "SHA", 3) == 0) + type = SHA; + else + return NULL; + +#ifdef WOLFSSL_SMALL_STACK + hmac = (Hmac*)XMALLOC(sizeof(Hmac), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (hmac == NULL) + return NULL; +#endif + + if (wc_HmacSetKey(hmac, type, (const byte*)key, key_len) == 0) + if (wc_HmacUpdate(hmac, d, n) == 0) + if (wc_HmacFinal(hmac, md) == 0) { + if (md_len) + *md_len = (type == MD5) ? (int)MD5_DIGEST_SIZE + : (int)SHA_DIGEST_SIZE; + ret = md; + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(hmac, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return ret; +} + +#endif /* OPENSSL_EXTRA */ + +#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) + +const char *EVP_AES_128_CBC = "AES-128-CBC"; +const char *EVP_AES_192_CBC = "AES-192-CBC"; +const char *EVP_AES_256_CBC = "AES-256-CBC"; + +#if defined(OPENSSL_EXTRA) +const char *EVP_AES_128_CTR = "AES-128-CTR"; +const char *EVP_AES_192_CTR = "AES-192-CTR"; +const char *EVP_AES_256_CTR = "AES-256-CTR"; +#endif /* OPENSSL_EXTRA */ + +const int EVP_AES_SIZE = 11; + +const char *EVP_DES_CBC = "DES-CBC"; +const int EVP_DES_SIZE = 7; + +const char *EVP_DES_EDE3_CBC = "DES-EDE3-CBC"; +const int EVP_DES_EDE3_SIZE = 12; + +#ifdef HAVE_IDEA +const char *EVP_IDEA_CBC = "IDEA-CBC"; +const int EVP_IDEA_SIZE = 8; +#endif /* HAVE_IDEA */ + +const WOLFCRYPT_EVP_CIPHER* wc_EVP_aes_128_cbc(void) +{ + WOLFSSL_ENTER("wc_EVP_aes_128_cbc"); + return EVP_AES_128_CBC; +} + +const WOLFCRYPT_EVP_CIPHER* wc_EVP_aes_192_cbc(void) +{ + WOLFSSL_ENTER("wc_EVP_aes_192_cbc"); + return EVP_AES_192_CBC; +} + +const WOLFCRYPT_EVP_CIPHER* wc_EVP_aes_256_cbc(void) +{ + WOLFSSL_ENTER("wc_EVP_aes_256_cbc"); + return EVP_AES_256_CBC; +} + +#if defined(OPENSSL_EXTRA) +const WOLFCRYPT_EVP_CIPHER* wc_EVP_aes_128_ctr(void) +{ + WOLFSSL_ENTER("wc_EVP_aes_128_ctr"); + return EVP_AES_128_CTR; +} + +const WOLFCRYPT_EVP_CIPHER* wc_EVP_aes_192_ctr(void) +{ + WOLFSSL_ENTER("wc_EVP_aes_192_ctr"); + return EVP_AES_192_CTR; +} + +const WOLFCRYPT_EVP_CIPHER* wc_EVP_aes_256_ctr(void) +{ + WOLFSSL_ENTER("wc_EVP_aes_256_ctr"); + return EVP_AES_256_CTR; +} +#endif /* OPENSSL_EXTRA */ + +const WOLFCRYPT_EVP_CIPHER* wc_EVP_des_cbc(void) +{ + WOLFSSL_ENTER("wc_EVP_des_cbc"); + return EVP_DES_CBC; +} + +const WOLFCRYPT_EVP_CIPHER* wc_EVP_des_ede3_cbc(void) +{ + WOLFSSL_ENTER("wc_EVP_des_ede3_cbc"); + return EVP_DES_EDE3_CBC; +} + +const WOLFCRYPT_EVP_CIPHER* wc_EVP_rc4(void) +{ + static const char* type = "ARC4"; + WOLFSSL_ENTER("wc_EVP_rc4"); + return type; +} + +#ifdef HAVE_IDEA +const WOLFCRYPT_EVP_CIPHER* wc_EVP_idea_cbc(void) +{ + WOLFSSL_ENTER("wc_EVP_idea_cbc"); + return EVP_IDEA_CBC; +} +#endif /* HAVE_IDEA */ + +const WOLFCRYPT_EVP_CIPHER* wc_EVP_enc_null(void) +{ + static const char* type = "NULL"; + WOLFSSL_ENTER("wc_EVP_enc_null"); + return type; +} + +#ifndef NO_MD5 +int wc_EVP_BytesToKey(const WOLFCRYPT_EVP_CIPHER* type, + const WOLFCRYPT_EVP_MD* md, const byte* salt, + const byte* data, int sz, int count, byte* key, byte* iv) +{ + int keyLen = 0; + int ivLen = 0; + int j; + int keyLeft; + int ivLeft; + int keyOutput = 0; + byte digest[MD5_DIGEST_SIZE]; +#ifdef WOLFSSL_SMALL_STACK + Md5* md5 = NULL; +#else + Md5 md5[1]; +#endif + +#ifdef WOLFSSL_SMALL_STACK + md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (md5 == NULL) + return 0; +#endif + + WOLFSSL_ENTER("wc_EVP_BytesToKey"); + wc_InitMd5(md5); + + /* only support MD5 for now */ + if (XSTRNCMP(md, "MD5", 3) != 0) return 0; + + /* only support CBC DES and AES for now */ + if (XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0) { + keyLen = DES_KEY_SIZE; + ivLen = DES_IV_SIZE; + } + else if (XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0) { + keyLen = DES3_KEY_SIZE; + ivLen = DES_IV_SIZE; + } + else if (XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0) { + keyLen = AES_128_KEY_SIZE; + ivLen = AES_IV_SIZE; + } + else if (XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0) { + keyLen = AES_192_KEY_SIZE; + ivLen = AES_IV_SIZE; + } + else if (XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0) { + keyLen = AES_256_KEY_SIZE; + ivLen = AES_IV_SIZE; + } + else { +#ifdef WOLFSSL_SMALL_STACK + XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return 0; + } + + keyLeft = keyLen; + ivLeft = ivLen; + + while (keyOutput < (keyLen + ivLen)) { + int digestLeft = MD5_DIGEST_SIZE; + /* D_(i - 1) */ + if (keyOutput) /* first time D_0 is empty */ + wc_Md5Update(md5, digest, MD5_DIGEST_SIZE); + /* data */ + wc_Md5Update(md5, data, sz); + /* salt */ + if (salt) + wc_Md5Update(md5, salt, EVP_SALT_SIZE); + wc_Md5Final(md5, digest); + /* count */ + for (j = 1; j < count; j++) { + wc_Md5Update(md5, digest, MD5_DIGEST_SIZE); + wc_Md5Final(md5, digest); + } + + if (keyLeft) { + int store = min(keyLeft, MD5_DIGEST_SIZE); + XMEMCPY(&key[keyLen - keyLeft], digest, store); + + keyOutput += store; + keyLeft -= store; + digestLeft -= store; + } + + if (ivLeft && digestLeft) { + int store = min(ivLeft, digestLeft); + if (iv != NULL) + XMEMCPY(&iv[ivLen - ivLeft], + &digest[MD5_DIGEST_SIZE - digestLeft], store); + keyOutput += store; + ivLeft -= store; + } + } + +#ifdef WOLFSSL_SMALL_STACK + XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return keyOutput == (keyLen + ivLen) ? keyOutput : 0; +} +#endif /* NO_MD5 */ + +#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */ + +#ifdef OPENSSL_EXTRA + +#ifndef NO_MD5 +const WOLFCRYPT_EVP_MD* wc_EVP_md5(void) +{ + static const char* type = "MD5"; + WOLFSSL_ENTER("EVP_md5"); + return type; +} +#endif /* NO_MD5 */ + +#ifndef NO_SHA +const WOLFCRYPT_EVP_MD* wc_EVP_sha1(void) +{ + static const char* type = "SHA"; + WOLFSSL_ENTER("EVP_sha1"); + return type; +} +#endif /* NO_SHA */ + +const WOLFCRYPT_EVP_MD* wc_EVP_sha256(void) +{ + static const char* type = "SHA256"; + WOLFSSL_ENTER("EVP_sha256"); + return type; +} + +#ifdef WOLFSSL_SHA384 +const WOLFCRYPT_EVP_MD* wc_EVP_sha384(void) +{ + static const char* type = "SHA384"; + WOLFSSL_ENTER("EVP_sha384"); + return type; +} +#endif /* WOLFSSL_SHA384 */ + +#ifdef WOLFSSL_SHA512 +const WOLFCRYPT_EVP_MD* wc_EVP_sha512(void) +{ + static const char* type = "SHA512"; + WOLFSSL_ENTER("EVP_sha512"); + return type; +} +#endif /* WOLFSSL_SHA512 */ + +void wc_EVP_MD_CTX_init(WOLFCRYPT_EVP_MD_CTX* ctx) +{ + WOLFSSL_ENTER("EVP_CIPHER_MD_CTX_init"); + if (ctx == NULL) { + WOLFSSL_MSG("Bad function argument"); + return; + } + + ctx->macSize = 0; + ctx->macType = 0xff; +} + +/* return 1 on ok, 0 on failure to match API compatibility */ +int wc_EVP_MD_CTX_copy(WOLFCRYPT_EVP_MD_CTX *out,const WOLFCRYPT_EVP_MD_CTX *in) +{ + WOLFSSL_ENTER("EVP_MD_CTX_copy"); + + if (in == NULL || out == NULL) { + WOLFSSL_MSG("Bad function argument"); + return 0; + } + + wc_EVP_MD_CTX_init(out); + XMEMCPY(out, in, sizeof(WOLFCRYPT_EVP_MD_CTX)); + + return 1; +} + +int wc_EVP_MD_CTX_cleanup(WOLFCRYPT_EVP_MD_CTX* ctx) +{ + WOLFSSL_ENTER("EVP_MD_CTX_cleanup"); + (void)ctx; + return 0; +} + +int wc_EVP_MD_size(const WOLFCRYPT_EVP_MD* type) +{ + WOLFSSL_MSG("wc_EVP_MD_size"); + + if (type == NULL) { + WOLFSSL_MSG("No md type arg"); + return BAD_FUNC_ARG; + } + + if (XSTRNCMP(type, "SHA256", 6) == 0) { + return SHA256_DIGEST_SIZE; + } +#ifndef NO_MD5 + else if (XSTRNCMP(type, "MD5", 3) == 0) { + return MD5_DIGEST_SIZE; + } +#endif +#ifdef WOLFSSL_SHA384 + else if (XSTRNCMP(type, "SHA384", 6) == 0) { + return SHA384_DIGEST_SIZE; + } +#endif +#ifdef WOLFSSL_SHA512 + else if (XSTRNCMP(type, "SHA512", 6) == 0) { + return SHA512_DIGEST_SIZE; + } +#endif +#ifndef NO_SHA + /* has to be last since would pick or 256, 384, or 512 too */ + else if (XSTRNCMP(type, "SHA", 3) == 0) { + return SHA_DIGEST_SIZE; + } +#endif + + return BAD_FUNC_ARG; +} + +#ifdef WOLFSSL_RIPEMD +const WOLFCRYPT_EVP_MD* wc_EVP_ripemd160(void) +{ + WOLFSSL_MSG("wc_ripemd160"); + + return NULL; +} +#endif + +/* 1 on ok */ +int wc_EVP_DigestInit(WOLFCRYPT_EVP_MD_CTX* ctx, const WOLFCRYPT_EVP_MD* type) +{ + WOLFSSL_ENTER("EVP_DigestInit"); + if (XSTRNCMP(type, "SHA256", 6) == 0) { + ctx->macType = SHA256; + ctx->macSize = SHA256_DIGEST_SIZE; + wc_SHA256_Init((WOLFCRYPT_SHA256_CTX*)&ctx->hash); + } +#ifdef WOLFSSL_SHA384 + else if (XSTRNCMP(type, "SHA384", 6) == 0) { + ctx->macType = SHA384; + ctx->macSize = SHA384_DIGEST_SIZE; + wc_SHA384_Init((WOLFCRYPT_SHA384_CTX*)&ctx->hash); + } +#endif +#ifdef WOLFSSL_SHA512 + else if (XSTRNCMP(type, "SHA512", 6) == 0) { + ctx->macType = SHA512; + ctx->macSize = SHA512_DIGEST_SIZE; + wc_SHA512_Init((WOLFCRYPT_SHA512_CTX*)&ctx->hash); + } +#endif +#ifndef NO_MD5 + else if (XSTRNCMP(type, "MD5", 3) == 0) { + ctx->macType = MD5; + ctx->macSize = MD5_DIGEST_SIZE; + wc_MD5_Init((WOLFCRYPT_MD5_CTX*)&ctx->hash); + } +#endif +#ifndef NO_SHA + /* has to be last since would pick or 256, 384, or 512 too */ + else if (XSTRNCMP(type, "SHA", 3) == 0) { + ctx->macType = SHA; + ctx->macSize = SHA_DIGEST_SIZE; + wc_SHA_Init((WOLFCRYPT_SHA_CTX*)&ctx->hash); + } +#endif /* NO_SHA */ + else + return BAD_FUNC_ARG; + + return 1; +} + + +/* 1 on ok */ +int wc_EVP_DigestUpdate(WOLFCRYPT_EVP_MD_CTX* ctx, const void* data, + unsigned long sz) +{ + WOLFSSL_ENTER("EVP_DigestUpdate"); + + switch (ctx->macType) { +#ifndef NO_MD5 + case MD5: + wc_MD5_Update((WOLFCRYPT_MD5_CTX*)&ctx->hash, data, + (unsigned long)sz); + break; +#endif +#ifndef NO_SHA + case SHA: + wc_SHA_Update((WOLFCRYPT_SHA_CTX*)&ctx->hash, data, + (unsigned long)sz); + break; +#endif +#ifndef NO_SHA256 + case SHA256: + wc_SHA256_Update((WOLFCRYPT_SHA256_CTX*)&ctx->hash, data, + (unsigned long)sz); + break; +#endif +#ifdef WOLFSSL_SHA384 + case SHA384: + wc_SHA384_Update((WOLFCRYPT_SHA384_CTX*)&ctx->hash, data, + (unsigned long)sz); + break; +#endif +#ifdef WOLFSSL_SHA512 + case SHA512: + wc_SHA512_Update((WOLFCRYPT_SHA512_CTX*)&ctx->hash, data, + (unsigned long)sz); + break; +#endif + default: + return BAD_FUNC_ARG; + } + + return 1; +} + + +/* 1 on ok */ +int wc_EVP_DigestFinal(WOLFCRYPT_EVP_MD_CTX* ctx, unsigned char* md, + unsigned int* s) +{ + WOLFSSL_ENTER("EVP_DigestFinal"); + switch (ctx->macType) { +#ifndef NO_MD5 + case MD5: + wc_MD5_Final(md, (WOLFCRYPT_MD5_CTX*)&ctx->hash); + if (s) *s = MD5_DIGEST_SIZE; + break; +#endif +#ifndef NO_SHA + case SHA: + wc_SHA_Final(md, (WOLFCRYPT_SHA_CTX*)&ctx->hash); + if (s) *s = SHA_DIGEST_SIZE; + break; +#endif +#ifndef NO_SHA256 + case SHA256: + wc_SHA256_Final(md, (WOLFCRYPT_SHA256_CTX*)&ctx->hash); + if (s) *s = SHA256_DIGEST_SIZE; + break; +#endif +#ifdef WOLFSSL_SHA384 + case SHA384: + wc_SHA384_Final(md, (WOLFCRYPT_SHA384_CTX*)&ctx->hash); + if (s) *s = SHA384_DIGEST_SIZE; + break; +#endif +#ifdef WOLFSSL_SHA512 + case SHA512: + wc_SHA512_Final(md, (WOLFCRYPT_SHA512_CTX*)&ctx->hash); + if (s) *s = SHA512_DIGEST_SIZE; + break; +#endif + default: + return BAD_FUNC_ARG; + } + + return 1; +} + + +/* 1 on ok */ +int wc_EVP_DigestFinal_ex(WOLFCRYPT_EVP_MD_CTX* ctx, unsigned char* md, + unsigned int* s) +{ + WOLFSSL_ENTER("EVP_DigestFinal_ex"); + return wc_EVP_DigestFinal(ctx, md, s); +} + +const WOLFCRYPT_EVP_MD* wc_EVP_get_digestbynid(int id) +{ + WOLFSSL_MSG("wc_get_digestbynid"); + + switch(id) { +#ifndef NO_MD5 + case NID_md5: + return wc_EVP_md5(); +#endif +#ifndef NO_SHA + case NID_sha1: + return wc_EVP_sha1(); +#endif + default: + WOLFSSL_MSG("Bad digest id value"); + } + + return NULL; +} + + +void wc_EVP_CIPHER_CTX_init(WOLFCRYPT_EVP_CIPHER_CTX* ctx) +{ + WOLFSSL_ENTER("EVP_CIPHER_CTX_init"); + if (ctx) { + ctx->cipherType = 0xff; /* no init */ + ctx->keyLen = 0; + ctx->enc = 1; /* start in encrypt mode */ + + ctx->ivUpdate = 0; + ctx->final_used = 0; + ctx->bufLen = 0; + ctx->blockSize = 0; + ctx->padding = 0; + + XMEMSET(ctx->iv, 0, sizeof(ctx->iv)); + XMEMSET(ctx->buf, 0, sizeof(ctx->buf)); + XMEMSET(ctx->final, 0, sizeof(ctx->final)); + } +} + +/* 1 on ok */ +int wc_EVP_CIPHER_CTX_cleanup(WOLFCRYPT_EVP_CIPHER_CTX* ctx) +{ + WOLFSSL_ENTER("EVP_CIPHER_CTX_cleanup"); + + /* reset to initial values */ + wc_EVP_CIPHER_CTX_init(ctx); + + return 1; +} + +/* return 1 on ok, 0 on failure to match API compatibility */ +int wc_EVP_CipherInit(WOLFCRYPT_EVP_CIPHER_CTX* ctx, + const WOLFCRYPT_EVP_CIPHER* type, byte* key, + byte* iv, int enc) +{ + int ret = -1; /* failure local, during function 0 means success + because internal functions work that way */ + (void)iv; + (void)enc; + + WOLFSSL_ENTER("wc_EVP_CipherInit"); + if (ctx == NULL) { + WOLFSSL_MSG("no ctx"); + return 0; /* failure */ + } + + if (type == NULL && ctx->cipherType == 0xff) { + WOLFSSL_MSG("no type set"); + return 0; /* failure */ + } + +#ifndef NO_AES + if (ctx->cipherType == AES_128_CBC_TYPE || + (type && XSTRNCMP(type, EVP_AES_128_CBC, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_128_CBC); + ctx->cipherType = AES_128_CBC_TYPE; + ctx->padding = 1; + ctx->ivUpdate = 1; + ctx->blockSize = AES_BLOCK_SIZE; + ctx->bufLen = 0; + ctx->final_used = 0; + ctx->keyLen = 16; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + else if (ctx->cipherType == AES_192_CBC_TYPE || + (type && XSTRNCMP(type, EVP_AES_192_CBC, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_192_CBC); + ctx->cipherType = AES_192_CBC_TYPE; + ctx->padding = 1; + ctx->ivUpdate = 1; + ctx->blockSize = AES_BLOCK_SIZE; + ctx->bufLen = 0; + ctx->final_used = 0; + ctx->keyLen = 24; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + else if (ctx->cipherType == AES_256_CBC_TYPE || + (type && XSTRNCMP(type, EVP_AES_256_CBC, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_256_CBC); + ctx->cipherType = AES_256_CBC_TYPE; + ctx->padding = 1; + ctx->ivUpdate = 1; + ctx->blockSize = AES_BLOCK_SIZE; + ctx->bufLen = 0; + ctx->final_used = 0; + ctx->keyLen = 32; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } +#ifdef WOLFSSL_AES_COUNTER + else if (ctx->cipherType == AES_128_CTR_TYPE || + (type && XSTRNCMP(type, EVP_AES_128_CTR, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_128_CTR); + ctx->cipherType = AES_128_CTR_TYPE; + ctx->padding = 0; + ctx->ivUpdate = 0; + ctx->blockSize = AES_BLOCK_SIZE; + ctx->bufLen = 0; + ctx->final_used = 0; + ctx->keyLen = 16; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + else if (ctx->cipherType == AES_192_CTR_TYPE || + (type && XSTRNCMP(type, EVP_AES_192_CTR, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_192_CTR); + ctx->cipherType = AES_192_CTR_TYPE; + ctx->padding = 0; + ctx->ivUpdate = 0; + ctx->blockSize = AES_BLOCK_SIZE; + ctx->bufLen = 0; + ctx->final_used = 0; + ctx->keyLen = 24; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + else if (ctx->cipherType == AES_256_CTR_TYPE || + (type && XSTRNCMP(type, EVP_AES_256_CTR, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_AES_256_CTR); + ctx->cipherType = AES_256_CTR_TYPE; + ctx->padding = 0; + ctx->ivUpdate = 0; + ctx->blockSize = AES_BLOCK_SIZE; + ctx->bufLen = 0; + ctx->final_used = 0; + ctx->keyLen = 32; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_AesSetKey(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } +#endif /* WOLFSSL_AES_CTR */ +#endif /* NO_AES */ + +#ifndef NO_DES3 + if (ctx->cipherType == DES_CBC_TYPE || + (type && XSTRNCMP(type, EVP_DES_CBC, EVP_DES_SIZE) == 0)) { + WOLFSSL_MSG(EVP_DES_CBC); + ctx->cipherType = DES_CBC_TYPE; + ctx->padding = 1; + ctx->ivUpdate = 1; + ctx->blockSize = DES_BLOCK_SIZE; + ctx->bufLen = 0; + ctx->final_used = 0; + ctx->keyLen = 8; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_Des_SetKey(&ctx->cipher.des, key, iv, + ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION); + if (ret != 0) + return ret; + } + + if (iv && key == NULL) + wc_Des_SetIV(&ctx->cipher.des, iv); + } + else if (ctx->cipherType == DES_EDE3_CBC_TYPE || + (type && + XSTRNCMP(type, EVP_DES_EDE3_CBC, EVP_DES_EDE3_SIZE) == 0)) { + WOLFSSL_MSG(EVP_DES_EDE3_CBC); + ctx->cipherType = DES_EDE3_CBC_TYPE; + ctx->padding = 1; + ctx->ivUpdate = 1; + ctx->blockSize = DES_BLOCK_SIZE; + ctx->bufLen = 0; + ctx->final_used = 0; + ctx->keyLen = 24; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_Des3_SetKey(&ctx->cipher.des3, key, iv, + ctx->enc ? DES_ENCRYPTION : DES_DECRYPTION); + if (ret != 0) + return ret; + } + + if (iv && key == NULL) { + ret = wc_Des3_SetIV(&ctx->cipher.des3, iv); + if (ret != 0) + return ret; + } + } +#endif /* NO_DES3 */ +#ifndef NO_RC4 + if (ctx->cipherType == ARC4_TYPE || (type && + XSTRNCMP(type, "ARC4", 4) == 0)) { + WOLFSSL_MSG("ARC4"); + ctx->cipherType = ARC4_TYPE; + ctx->blockSize = 1; + ctx->bufLen = 0; + ctx->final_used = 0; + ctx->padding = 0; + ctx->ivUpdate = 0; + if (ctx->keyLen == 0) /* user may have already set */ + ctx->keyLen = 16; /* default to 128 */ + if (key) + wc_Arc4SetKey(&ctx->cipher.arc4, key, ctx->keyLen); + ret = 0; /* success */ + } +#endif /* NO_RC4 */ +#ifdef HAVE_IDEA + if (ctx->cipherType == IDEA_CBC_TYPE || + (type && XSTRNCMP(type, EVP_IDEA_CBC, EVP_IDEA_SIZE) == 0)) { + WOLFSSL_MSG(EVP_IDEA_CBC); + ctx->cipherType = IDEA_CBC_TYPE; + ctx->padding = 1; + ctx->ivUpdate = 1; + ctx->blockSize = IDEA_BLOCK_SIZE; + ctx->bufLen = 0; + ctx->final_used = 0; + ctx->keyLen = IDEA_KEY_SIZE; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = wc_IdeaSetKey(&ctx->cipher.idea, key, (word16)ctx->keyLen, + iv, ctx->enc ? IDEA_ENCRYPTION : + IDEA_DECRYPTION); + if (ret != 0) + return ret; + } + + if (iv && key == NULL) + wc_IdeaSetIV(&ctx->cipher.idea, iv); + } +#endif /* HAVE_IDEA */ + if (ctx->cipherType == NULL_CIPHER_TYPE || (type && + XSTRNCMP(type, "NULL", 4) == 0)) { + WOLFSSL_MSG("NULL cipher"); + ctx->cipherType = NULL_CIPHER_TYPE; + ctx->keyLen = 0; + ctx->blockSize = 1; + ctx->bufLen = 0; + ctx->final_used = 0; + ctx->padding = 0; + ctx->ivUpdate = 0; + ret = 0; /* success */ + } + + if (ret == 0) + return 1; + else + return 0; /* overall failure */ +} + +/* return 1 on ok, 0 on failure to match API compatibility */ +int wc_EVP_CipherUpdate(WOLFCRYPT_EVP_CIPHER_CTX *ctx, byte *dst, int *dstLen, + const byte *src, int len) +{ + int ret = 0, notEncLen = 0, fixLen = 0; + WOLFSSL_ENTER("wc_EVP_CipherUpdate"); + + *dstLen = 0; + + if (len <= 0) + return (len == 0); + + /* Push pending data for the decryption case */ + if (!ctx->enc && ctx->final_used) { + XMEMCPY(dst, ctx->final, ctx->blockSize); + dst += ctx->blockSize; + fixLen = 1; + } + + /* No pending data, src len is a multiple of blocksize */ + if (!ctx->bufLen && !(len & (ctx->blockSize-1))) { + ret = wc_EVP_Cipher(ctx, &dst[*dstLen], (byte*)src, len); + if (ret != 1) { + *dstLen = 0; + WOLFSSL_MSG("wc_EVP_Cipher failure"); + return 0; + } + else { + *dstLen = len; + + /* save new iv if required */ + if (ctx->ivUpdate) { + if (ctx->enc) + XMEMCPY(ctx->iv, &dst[*dstLen-ctx->blockSize], + ctx->blockSize); + else + XMEMCPY(ctx->iv, &src[len-ctx->blockSize], + ctx->blockSize); + ctx->ivUpdate = 2; + } + + /* extra operation for decrypt case */ + if (!ctx->enc) + goto decrypt; + else + return 1; + } + } + + /* Pending data */ + if (ctx->bufLen) { + /* pending data + src data less than a block + * keep data and return */ + if (ctx->bufLen + len < ctx->blockSize) { + XMEMCPY(&ctx->buf[ctx->bufLen], src, len); + ctx->bufLen += len; + *dstLen = 0; + return 1; + } + else { + /* complete pending buffer and encrypt/decrypt it */ + XMEMCPY(&ctx->buf[ctx->bufLen], src, + ctx->blockSize - ctx->bufLen); + ret = wc_EVP_Cipher(ctx, &dst[*dstLen], + ctx->buf, ctx->blockSize); + if (ret != 1) { + *dstLen = 0; + WOLFSSL_MSG("wc_EVP_Cipher failure"); + return 0; + } + + /* save new iv if required */ + if (ctx->ivUpdate) { + if (ctx->enc) + XMEMCPY(ctx->iv, dst, ctx->blockSize); + else + XMEMCPY(ctx->iv, ctx->buf, ctx->blockSize); + ctx->ivUpdate = 2; + } + + len -= (ctx->blockSize - ctx->bufLen); + src += (ctx->blockSize - ctx->bufLen); + *dstLen = ctx->blockSize; + } + } + /* src len not a multiple of block size */ + else + *dstLen = 0; + + /* encrypt/decrypt max blocks as possible */ + notEncLen = len & (ctx->blockSize - 1); + len -= notEncLen; + if (len > 0) { + ret = wc_EVP_Cipher(ctx, &dst[*dstLen], (byte*)src, len); + if (ret != 1) { + WOLFSSL_MSG("wc_EVP_Cipher failure"); + return 0; + } + *dstLen += len; + + /* save new iv if required */ + if (ctx->ivUpdate) { + if (ctx->enc) + XMEMCPY(ctx->iv, &dst[*dstLen-ctx->blockSize], + ctx->blockSize); + else + XMEMCPY(ctx->iv, &src[len-ctx->blockSize], ctx->blockSize); + ctx->ivUpdate = 2; + } + } + + /* save pending data */ + if (notEncLen) + XMEMCPY(ctx->buf, src+len, notEncLen); + ctx->bufLen = notEncLen; + +decrypt: + /* extra operation for decrypt case */ + if (!ctx->enc) { + /* keep last block for final step when decrypting + * multiple of block size */ + if (ctx->blockSize > 1 && !ctx->bufLen) { + *dstLen -= ctx->blockSize; + ctx->final_used = 1; + XMEMCPY(ctx->final, &dst[*dstLen], ctx->blockSize); + } + else + ctx->final_used = 0; + + if (fixLen) + *dstLen += ctx->blockSize; + } + + return 1; +} + +/* return 1 on ok, 0 on failure to match API compatibility */ +int wc_EVP_CipherFinal(WOLFCRYPT_EVP_CIPHER_CTX *ctx, byte *dst, int *dstLen) +{ + int ret; + + if (ctx->blockSize == 1) { + *dstLen = 0; + WOLFSSL_MSG("wc_EVP_CipherFinal: blocksize 1"); + return 1; + } + + if (ctx->enc) { + if (ctx->padding) { + /* add padding */ + XMEMSET(ctx->buf+ctx->bufLen, (byte)(ctx->blockSize-ctx->bufLen), + ctx->blockSize-ctx->bufLen); + + ret = wc_EVP_Cipher(ctx, dst, ctx->buf, ctx->blockSize); + if (ret != 1) { + WOLFSSL_MSG("wc_EVP_CipherFinal failure"); + return 0; + } + + *dstLen = ctx->blockSize; + } + else { + if (ctx->bufLen) { + ret = wc_EVP_Cipher(ctx, dst, ctx->buf, ctx->bufLen); + if (ret != 1) { + WOLFSSL_MSG("wc_EVP_CipherFinal failure"); + return 0; + } + + *dstLen = ctx->bufLen; + } + else { + WOLFSSL_MSG("wc_EVP_CipherFinal: Nothing to do"); + *dstLen = 0; + } + } + } + else { + int i, pad; + + /* decrypt pending data, case of stream cipher */ + if (ctx->bufLen && !ctx->final_used) { + ret = wc_EVP_Cipher(ctx, dst, ctx->buf, ctx->bufLen); + if (ret != 1) { + WOLFSSL_MSG("wc_EVP_CipherFinal failure"); + return 0; + } + + *dstLen = ctx->bufLen; + ctx->bufLen = 0; + + return 1; + } + else if (ctx->bufLen || !ctx->final_used) { + WOLFSSL_MSG("wc_EVP_CipherFinal: Wrong final block length"); + return 0; + } + + /* get padding */ + if (ctx->padding) { + pad = (int)ctx->final[ctx->blockSize-1]; + if (!pad || pad > (int)ctx->blockSize) { + WOLFSSL_MSG("wc_EVP_CipherFinal: Bad decrypt"); + return 0; + } + + /* check padding */ + for (i = 0; i < pad; i++) { + if (ctx->final[ctx->blockSize-1-i] != pad) { + WOLFSSL_MSG("wc_EVP_CipherFinal: Bad decrypt"); + return 0; + } + } + + /* return data without padding */ + *dstLen = ctx->blockSize-pad; + XMEMCPY(dst, ctx->final, *dstLen); + } + else { + /* return data */ + *dstLen = ctx->blockSize; + XMEMCPY(dst, ctx->final, *dstLen); + } + } + + return 1; +} + +/* return 1 on ok, 0 on failure to match API compatibility */ +int wc_EVP_CIPHER_CTX_copy(WOLFCRYPT_EVP_CIPHER_CTX *out, + const WOLFCRYPT_EVP_CIPHER_CTX *in) +{ + WOLFSSL_ENTER("wc_EVP_CIPHER_CTX_copy"); + + if (in == NULL || out == NULL) { + WOLFSSL_MSG("Bad function argument"); + return 0; + } + + wc_EVP_CIPHER_CTX_cleanup(out); + XMEMCPY(out, in, sizeof(WOLFCRYPT_EVP_CIPHER_CTX)); + + return 1; +} + +/* 1 on ok */ +int wc_EVP_CIPHER_CTX_key_length(WOLFCRYPT_EVP_CIPHER_CTX* ctx) +{ + WOLFSSL_ENTER("wc_EVP_CIPHER_CTX_key_length"); + if (ctx) + return ctx->keyLen; + + return 0; /* failure */ +} + + +/* 1 on ok */ +int wc_EVP_CIPHER_CTX_set_key_length(WOLFCRYPT_EVP_CIPHER_CTX* ctx, int keylen) +{ + WOLFSSL_ENTER("wc_EVP_CIPHER_CTX_set_key_length"); + if (ctx) + ctx->keyLen = keylen; + else + return 0; /* failure */ + + return 1; +} + + +/* 1 on ok */ +int wc_EVP_Cipher(WOLFCRYPT_EVP_CIPHER_CTX* ctx, byte* dst, byte* src, + word32 len) +{ + int ret = 0; + WOLFSSL_ENTER("wc_EVP_Cipher"); + + if (ctx == NULL || dst == NULL || src == NULL) { + WOLFSSL_MSG("Bad function argument"); + return 0; /* failure */ + } + + if (ctx->cipherType == 0xff) { + WOLFSSL_MSG("no init"); + return 0; /* failure */ + } + + switch (ctx->cipherType) { + +#ifndef NO_AES + case AES_128_CBC_TYPE : + case AES_192_CBC_TYPE : + case AES_256_CBC_TYPE : + WOLFSSL_MSG("AES CBC"); + if (ctx->ivUpdate > 1) { + ret = wc_AesSetIV(&ctx->cipher.aes, ctx->iv); + if (ret != 0) { + WOLFSSL_MSG("wc_EVP_Cipher failure"); + return 0; /* failure */ + } + } + + if (ctx->enc) + ret = wc_AesCbcEncrypt(&ctx->cipher.aes, dst, src, len); + else + ret = wc_AesCbcDecrypt(&ctx->cipher.aes, dst, src, len); + break; + +#ifdef WOLFSSL_AES_COUNTER + case AES_128_CTR_TYPE : + case AES_192_CTR_TYPE : + case AES_256_CTR_TYPE : + WOLFSSL_MSG("AES CTR"); + wc_AesCtrEncrypt(&ctx->cipher.aes, dst, src, len); + break; +#endif +#endif /* NO_AES */ + +#ifndef NO_DES3 + case DES_CBC_TYPE : + if (ctx->ivUpdate > 1) + wc_Des_SetIV(&ctx->cipher.des, ctx->iv); + + if (ctx->enc) + wc_Des_CbcEncrypt(&ctx->cipher.des, dst, src, len); + else + wc_Des_CbcDecrypt(&ctx->cipher.des, dst, src, len); + break; + + case DES_EDE3_CBC_TYPE : + if (ctx->ivUpdate > 1) { + ret = wc_Des3_SetIV(&ctx->cipher.des3, ctx->iv); + if (ret != 0) { + WOLFSSL_MSG("wc_EVP_Cipher failure"); + return 0; /* failure */ + } + } + + if (ctx->enc) + ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len); + else + ret = wc_Des3_CbcDecrypt(&ctx->cipher.des3, dst, src, len); + break; +#endif + +#ifndef NO_RC4 + case ARC4_TYPE : + wc_Arc4Process(&ctx->cipher.arc4, dst, src, len); + break; +#endif + +#ifdef HAVE_IDEA + case IDEA_CBC_TYPE : + if (ctx->ivUpdate > 1) { + ret = wc_IdeaSetIV(&ctx->cipher.idea, ctx->iv); + if (ret != 0) { + WOLFSSL_MSG("wc_EVP_Cipher failure"); + return 0; /* failure */ + } + } + + if (ctx->enc) + wc_IdeaCbcEncrypt(&ctx->cipher.idea, dst, src, len); + else + wc_IdeaCbcDecrypt(&ctx->cipher.idea, dst, src, len); + break; +#endif + case NULL_CIPHER_TYPE : + XMEMCPY(dst, src, len); + break; + + default: { + WOLFSSL_MSG("bad type"); + return 0; /* failure */ + } + } + + if (ret != 0) { + WOLFSSL_MSG("wc_EVP_Cipher failure"); + return 0; /* failuer */ + } + + WOLFSSL_MSG("wc_EVP_Cipher success"); + return 1; /* success */ +} + +int wc_EVP_CIPHER_CTX_iv_length(const WOLFCRYPT_EVP_CIPHER_CTX* ctx) +{ + WOLFSSL_MSG("wc_EVP_CIPHER_CTX_iv_length"); + + switch (ctx->cipherType) { + + case AES_128_CBC_TYPE : + case AES_192_CBC_TYPE : + case AES_256_CBC_TYPE : + WOLFSSL_MSG("AES CBC"); + return AES_BLOCK_SIZE; + +#ifdef WOLFSSL_AES_COUNTER + case AES_128_CTR_TYPE : + case AES_192_CTR_TYPE : + case AES_256_CTR_TYPE : + WOLFSSL_MSG("AES CTR"); + return AES_BLOCK_SIZE; +#endif + + case DES_CBC_TYPE : + WOLFSSL_MSG("DES CBC"); + return DES_BLOCK_SIZE; + + case DES_EDE3_CBC_TYPE : + WOLFSSL_MSG("DES EDE3 CBC"); + return DES_BLOCK_SIZE; +#ifdef HAVE_IDEA + case IDEA_CBC_TYPE : + WOLFSSL_MSG("IDEA CBC"); + return IDEA_BLOCK_SIZE; +#endif + case ARC4_TYPE : + WOLFSSL_MSG("ARC4"); + return 0; + + case NULL_CIPHER_TYPE : + WOLFSSL_MSG("NULL"); + return 0; + + default: { + WOLFSSL_MSG("bad type"); + } + } + return 0; +} + +#endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 814de1bc4..6a9a1cb86 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -94,7 +94,7 @@ #include #include #include - #include + #include #include #endif @@ -224,11 +224,12 @@ int bio_md_test(void); int bio_test(void); int bio_connect_test(void); int bio_connect_ssl_test(void); -/* Required human interactions, must be move to API +/* Required human interactions, must be move to API */ +#if 0 int bio_accept_ssl_test(void); int bio_accept_test(void); - */ #endif +#endif /* OPENSSL_EXTRA */ /* General big buffer size for many tests. */ #define FOURK_BUF 4096 @@ -621,7 +622,8 @@ int wolfcrypt_test(void* args) else printf( "BIO Connect SSL test passed!\n"); - /* Required human interactions, must be move to API + /* Required human interactions, must be move to API */ +#if 0 if ( (ret = bio_accept_test()) != 0) return err_sys("BIO Accept test failed !\n", ret); else @@ -631,7 +633,7 @@ int wolfcrypt_test(void* args) return err_sys("BIO Accept SSL test failed !\n", ret); else printf( "BIO Accept SSL test passed!\n"); - */ +#endif if ( (ret = evp_test()) != 0) return err_sys("EVP test failed !\n", ret); @@ -642,7 +644,7 @@ int wolfcrypt_test(void* args) return err_sys("BIO test failed !\n", ret); else printf( "BIO test passed!\n"); -#endif +#endif /* OPENSSL_EXTRA */ ((func_args*)args)->return_code = ret; @@ -6006,9 +6008,9 @@ int openssl_test(void) return 0; } -static int evp_enc_test(const WOLFSSL_EVP_CIPHER* type) +static int evp_enc_test(const WOLFCRYPT_EVP_CIPHER* type) { - WOLFSSL_EVP_CIPHER_CTX ctx; + WOLFCRYPT_EVP_CIPHER_CTX ctx; int i, ret, len = 0, loop, outLen, rand_size, witLen; byte random[4500], wit[5000], out[5000]; @@ -6038,16 +6040,16 @@ static int evp_enc_test(const WOLFSSL_EVP_CIPHER* type) rand_size = sizeof(random) - loop; /* Encrypt */ - wolfSSL_EVP_CIPHER_CTX_init(&ctx); + wc_EVP_CIPHER_CTX_init(&ctx); XMEMSET(out, 0, sizeof(out)); len = 0; - ret = wolfSSL_EVP_CipherInit(&ctx, type, key, iv, 1); + ret = wc_EVP_CipherInit(&ctx, type, key, iv, 1); if (ret != SSL_SUCCESS) return -1200; - ret = wolfSSL_EVP_CipherUpdate(&ctx, out+len, &outLen, + ret = wc_EVP_CipherUpdate(&ctx, out+len, &outLen, random, rand_size); if (ret != SSL_SUCCESS) return -1201; @@ -6055,7 +6057,7 @@ static int evp_enc_test(const WOLFSSL_EVP_CIPHER* type) len += outLen; outLen = 0; - ret = wolfSSL_EVP_CipherFinal(&ctx, out+len, &outLen); + ret = wc_EVP_CipherFinal(&ctx, out+len, &outLen); if (ret != SSL_SUCCESS) return -1202; @@ -6063,19 +6065,19 @@ static int evp_enc_test(const WOLFSSL_EVP_CIPHER* type) outLen += len; /* Decrypt */ - wolfSSL_EVP_CIPHER_CTX_init(&ctx); + wc_EVP_CIPHER_CTX_init(&ctx); XMEMSET(wit, 0, sizeof(wit)); len = 0; - ret = wolfSSL_EVP_CipherInit(&ctx, type, key, iv, 0); + ret = wc_EVP_CipherInit(&ctx, type, key, iv, 0); if (ret != SSL_SUCCESS) return -1203; for (i = 0; i < outLen; i++) { witLen = 0; - ret = wolfSSL_EVP_CipherUpdate(&ctx, wit+len, &witLen, out+i, 1); + ret = wc_EVP_CipherUpdate(&ctx, wit+len, &witLen, out+i, 1); if (ret != SSL_SUCCESS) return -1204; @@ -6084,7 +6086,7 @@ static int evp_enc_test(const WOLFSSL_EVP_CIPHER* type) witLen = 0; - ret = wolfSSL_EVP_CipherFinal(&ctx, wit+len, &witLen); + ret = wc_EVP_CipherFinal(&ctx, wit+len, &witLen); if (ret != SSL_SUCCESS) return -1205; @@ -6104,54 +6106,52 @@ int evp_test(void) { int ret; - //wolfSSL_Debugging_ON(); - #ifndef NO_AES - ret = evp_enc_test(wolfSSL_EVP_aes_128_cbc()); + ret = evp_enc_test(wc_EVP_aes_128_cbc()); if (ret != 0) return ret; - ret = evp_enc_test(wolfSSL_EVP_aes_192_cbc()); + ret = evp_enc_test(wc_EVP_aes_192_cbc()); if (ret != 0) return ret; - ret = evp_enc_test(wolfSSL_EVP_aes_256_cbc()); + ret = evp_enc_test(wc_EVP_aes_256_cbc()); if (ret != 0) return ret; #ifdef WOLFSSL_AES_COUNTER - ret = evp_enc_test(wolfSSL_EVP_aes_128_ctr()); + ret = evp_enc_test(wc_EVP_aes_128_ctr()); if (ret != 0) return ret; - ret = evp_enc_test(wolfSSL_EVP_aes_192_ctr()); + ret = evp_enc_test(wc_EVP_aes_192_ctr()); if (ret != 0) return ret; - ret = evp_enc_test(wolfSSL_EVP_aes_256_ctr()); + ret = evp_enc_test(wc_EVP_aes_256_ctr()); if (ret != 0) return ret; #endif /* WOLFSSL_AES_COUNTER */ #endif /* NO_AES */ #ifndef NO_RC4 - ret = evp_enc_test(wolfSSL_EVP_rc4()); + ret = evp_enc_test(wc_EVP_rc4()); if (ret != 0) return ret; #endif /* NO_RC4 */ #ifndef NO_DES3 - ret = evp_enc_test(wolfSSL_EVP_des_cbc()); + ret = evp_enc_test(wc_EVP_des_cbc()); if (ret != 0) return ret; - ret = evp_enc_test(wolfSSL_EVP_des_ede3_cbc()); + ret = evp_enc_test(wc_EVP_des_ede3_cbc()); if (ret != 0) return ret; #endif /* NO_DES3 */ #ifdef HAVE_IDEA - ret = evp_enc_test(wolfSSL_EVP_idea_cbc()); + ret = evp_enc_test(wc_EVP_idea_cbc()); if (ret != 0) return ret; #endif /* HAVE_IDEA */ @@ -6166,13 +6166,13 @@ int bio_md_test(void) char digest[SHA512_DIGEST_SIZE]; struct bio_digest { - const WOLFSSL_EVP_MD *type; + const WOLFCRYPT_EVP_MD *type; const char *data; const char *digest; } hash_list[] = { #ifndef NO_MD5 { - wolfSSL_EVP_md5(), + wc_EVP_md5(), "1234567890123456789012345678901234567890123456789012345678" "9012345678901234567890", "\x57\xed\xf4\xa2\x2b\xe3\xc9\x55\xac\x49\xda\x2e\x21\x07\xb6" @@ -6181,7 +6181,7 @@ int bio_md_test(void) #endif #ifndef NO_SHA { - wolfSSL_EVP_sha1(), + wc_EVP_sha1(), "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" "aaaaaaaaaa", @@ -6191,7 +6191,7 @@ int bio_md_test(void) #endif #ifdef WOLFSSL_SHA256 { - wolfSSL_EVP_sha256(), + wc_EVP_sha256(), "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x24\x8D\x6A\x61\xD2\x06\x38\xB8\xE5\xC0\x26\x93\x0C\x3E\x60" "\x39\xA3\x3C\xE4\x59\x64\xFF\x21\x67\xF6\xEC\xED\xD4\x19\xDB" @@ -6200,7 +6200,7 @@ int bio_md_test(void) #endif #ifdef WOLFSSL_SHA384 { - wolfSSL_EVP_sha384(), + wc_EVP_sha384(), "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x09\x33\x0c\x33\xf7\x11\x47\xe8\x3d\x19\x2f\xc7\x82\xcd\x1b" @@ -6211,7 +6211,7 @@ int bio_md_test(void) #endif #ifdef WOLFSSL_SHA512 { - wolfSSL_EVP_sha512(), + wc_EVP_sha512(), "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14" @@ -6228,19 +6228,19 @@ int bio_md_test(void) while (hash_list[i].type != NULL) { /* Create a digest filter BIO */ - bmd = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_f_md()); + bmd = wc_BioNew(wc_Bio_f_md()); if (bmd == NULL) return -1065; /* set digest algorithm */ - WOLFCRYPT_BIO_set_md(bmd, hash_list[i].type); + wc_BioSetMd(bmd, hash_list[i].type); /* create a null bio to chain with digest */ - bnull = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_s_null()); + bnull = wc_BioNew(wc_Bio_s_null()); if (bmd == NULL) return -1066; - if (WOLFCRYPT_BIO_push(bmd, bnull) == NULL) + if (wc_BioPush(bmd, bnull) == NULL) return -1067; size = (int)strlen(hash_list[i].data); @@ -6249,10 +6249,10 @@ int bio_md_test(void) * It checks for errors as if the underlying file were non-blocking */ for (total = 0; total < size; total += w) { - w = WOLFCRYPT_BIO_write(bmd, hash_list[i].data + total, + w = wc_BioWrite(bmd, hash_list[i].data + total, size - (int)total); if (w <= 0) { - if (WOLFCRYPT_BIO_should_retry(bmd)) { + if (wc_BioShouldRetry(bmd)) { w = 0; continue; } @@ -6264,22 +6264,22 @@ int bio_md_test(void) return -1068; /* Ensure all of our data is pushed all the way to the BIO */ - WOLFCRYPT_BIO_flush(bmd); + wc_BioFlush(bmd); /* get the digest */ XMEMSET(digest, 0, sizeof(digest)); - size = WOLFCRYPT_BIO_gets(bmd, digest, sizeof(digest)); + size = wc_BioGets(bmd, digest, sizeof(digest)); if (size <= 0) return -1069; - if (size != wolfSSL_EVP_MD_size(hash_list[i].type)) + if (size != wc_EVP_MD_size(hash_list[i].type)) return -1070; if (XMEMCMP(digest, hash_list[i].digest, size)) return -1071; /* free BIO */ - WOLFCRYPT_BIO_free_all(bmd); + wc_BioFreeAll(bmd); i++; } @@ -6311,28 +6311,28 @@ int bio_b64_test(void) /* Create a buffered file BIO for writing */ if (loop & 1) - file = WOLFCRYPT_BIO_new_file("test_b64", "w"); + file = wc_BioNewFile("test_b64", "w"); else - file = WOLFCRYPT_BIO_new_file("test_b64_nonl", "w"); + file = wc_BioNewFile("test_b64_nonl", "w"); if (file == NULL) return -1062; /* Create a base64 encoding filter BIO */ - b64 = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_f_base64()); + b64 = wc_BioNew(wc_Bio_f_base64()); if (b64 == NULL) return -1065; - if (WOLFCRYPT_BIO_push(b64, file) == NULL) + if (wc_BioPush(b64, file) == NULL) return -1069; /* This loop writes the data to the file. * It checks for errors as if the underlying file were non-blocking */ for (total = 0; total < rand_size; total += w) { - w = WOLFCRYPT_BIO_write(b64, random + total, + w = wc_BioWrite(b64, random + total, rand_size - (int)total); if (w <= 0) { - if (WOLFCRYPT_BIO_should_retry(b64)) { + if (wc_BioShouldRetry(b64)) { w = 0; continue; } @@ -6341,36 +6341,36 @@ int bio_b64_test(void) } /* Ensure all of our data is pushed all the way to the file */ - WOLFCRYPT_BIO_flush(b64); + wc_BioFlush(b64); /* free BIO chain cipher-file */ - WOLFCRYPT_BIO_free_all(b64); + wc_BioFreeAll(b64); /* Start read / decode phase */ /* Create a buffered file BIO for writing */ if (loop & 1) - file = WOLFCRYPT_BIO_new_file("test_b64", "r"); + file = wc_BioNewFile("test_b64", "r"); else - file = WOLFCRYPT_BIO_new_file("test_b64_nonl", "r"); + file = wc_BioNewFile("test_b64_nonl", "r"); if (file == NULL) return -1070; /* Create a base64 encoding filter BIO */ - b64 = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_f_base64()); + b64 = wc_BioNew(wc_Bio_f_base64()); if (b64 == NULL) return -1073; - if (WOLFCRYPT_BIO_push(b64, file) == NULL) + if (wc_BioPush(b64, file) == NULL) return -1074; XMEMSET(wit, 0, sizeof(wit)); for (total = 0; ; total += w) { - w = WOLFCRYPT_BIO_read(b64, wit+total, + w = wc_BioRead(b64, wit+total, (int)sizeof(wit) - (int)total); if (w <= 0) { - if (WOLFCRYPT_BIO_should_retry(b64)) { + if (wc_BioShouldRetry(b64)) { w = 0; continue; } @@ -6379,7 +6379,7 @@ int bio_b64_test(void) } /* free BIO chain b64-file */ - WOLFCRYPT_BIO_free_all(b64); + wc_BioFreeAll(b64); /* check decoded data */ if (total != rand_size) @@ -6394,7 +6394,7 @@ int bio_b64_test(void) return 0; } -static int bio_filter_test(const WOLFSSL_EVP_CIPHER* cipher_type) +static int bio_filter_test(const WOLFCRYPT_EVP_CIPHER* cipher_type) { int total, i, w, rand_size; WOLFCRYPT_BIO *cipher, *buffer, *file, *b64; @@ -6423,44 +6423,44 @@ static int bio_filter_test(const WOLFSSL_EVP_CIPHER* cipher_type) /* Create a buffered file BIO for writing */ if (i & 1) - file = WOLFCRYPT_BIO_new_file("test_assembling_nonl", "w"); + file = wc_BioNewFile("test_assembling_nonl", "w"); else - file = WOLFCRYPT_BIO_new_file("test_assembling", "w"); + file = wc_BioNewFile("test_assembling", "w"); if (file == NULL) return -1062; /* Create a buffering filter BIO to buffer writes to the file */ - buffer = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_f_buffer()); + buffer = wc_BioNew(wc_Bio_f_buffer()); if (buffer == NULL) return -1063; /* Create a cipher filter BIO */ - cipher = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_f_cipher()); + cipher = wc_BioNew(wc_Bio_f_cipher()); if (cipher == NULL) return -1064; /* Create a base64 encoding filter BIO */ - b64 = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_f_base64()); + b64 = wc_BioNew(wc_Bio_f_base64()); if (b64 == NULL) return -1065; if (i & 1) - WOLFCRYPT_BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + wc_BioSetFlags(b64, BIO_FLAGS_BASE64_NO_NL); /* Start encrypt / write phase */ /* Set cipher key and encryption mode */ - WOLFCRYPT_BIO_set_cipher(cipher, cipher_type, key, iv, 1); + wc_BioSetCipher(cipher, cipher_type, key, iv, 1); /* Assemble the BIO chain to be in the order cipher-base64-buffer-file */ - if (WOLFCRYPT_BIO_push(cipher, b64) == NULL) + if (wc_BioPush(cipher, b64) == NULL) return -1066; - if (WOLFCRYPT_BIO_push(b64, buffer) == NULL) + if (wc_BioPush(b64, buffer) == NULL) return -1067; - if (WOLFCRYPT_BIO_push(buffer, file) == NULL) + if (wc_BioPush(buffer, file) == NULL) return -1068; @@ -6468,10 +6468,10 @@ static int bio_filter_test(const WOLFSSL_EVP_CIPHER* cipher_type) * It checks for errors as if the underlying file were non-blocking */ for (total = 0; total < rand_size; total += w) { - w = WOLFCRYPT_BIO_write(cipher, random + total, + w = wc_BioWrite(cipher, random + total, rand_size - (int)total); if (w <= 0) { - if (WOLFCRYPT_BIO_should_retry(cipher)) { + if (wc_BioShouldRetry(cipher)) { w = 0; continue; } @@ -6480,55 +6480,55 @@ static int bio_filter_test(const WOLFSSL_EVP_CIPHER* cipher_type) } /* Ensure all of our data is pushed all the way to the file */ - WOLFCRYPT_BIO_flush(cipher); + wc_BioFlush(cipher); /* get b64 BIO to free it only at first (test purpose) */ - WOLFCRYPT_BIO_pop(b64); + wc_BioPop(b64); /* free b64 BIO */ - WOLFCRYPT_BIO_free(b64); + wc_BioFree(b64); /* free BIO chain cipher-base64-buffer-file */ - WOLFCRYPT_BIO_free_all(cipher); + wc_BioFreeAll(cipher); /* Start read / decrypt phase */ /* Create a buffered file BIO for writing */ if (i & 1) - file = WOLFCRYPT_BIO_new_file("test_assembling_nonl", "r"); + file = wc_BioNewFile("test_assembling_nonl", "r"); else - file = WOLFCRYPT_BIO_new_file("test_assembling", "r"); + file = wc_BioNewFile("test_assembling", "r"); if (file == NULL) return -1070; /* Create a buffering filter BIO to buffer writes to the file */ - buffer = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_f_buffer()); + buffer = wc_BioNew(wc_Bio_f_buffer()); if (buffer == NULL) return -1071; /* Create a cipher filter BIO */ - cipher = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_f_cipher()); + cipher = wc_BioNew(wc_Bio_f_cipher()); if (cipher == NULL) return -1072; /* Create a base64 encoding filter BIO */ - b64 = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_f_base64()); + b64 = wc_BioNew(wc_Bio_f_base64()); if (b64 == NULL) return -1073; if (i & 1) - WOLFCRYPT_BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + wc_BioSetFlags(b64, BIO_FLAGS_BASE64_NO_NL); /* Set cipher key and decryption mode */ - WOLFCRYPT_BIO_set_cipher(cipher, cipher_type, key, iv, 0); + wc_BioSetCipher(cipher, cipher_type, key, iv, 0); - if (WOLFCRYPT_BIO_push(cipher, b64) == NULL) + if (wc_BioPush(cipher, b64) == NULL) return -1074; - if (WOLFCRYPT_BIO_push(b64, buffer) == NULL) + if (wc_BioPush(b64, buffer) == NULL) return -1075; - if (WOLFCRYPT_BIO_push(buffer, file) == NULL) + if (wc_BioPush(buffer, file) == NULL) return -1077; /* This loop read the data from the file. @@ -6537,10 +6537,10 @@ static int bio_filter_test(const WOLFSSL_EVP_CIPHER* cipher_type) for (total = 0; ; total += w) { - w = WOLFCRYPT_BIO_read(cipher, wit+total, + w = wc_BioRead(cipher, wit+total, (int)sizeof(wit) - (int)total); if (w <= 0) { - if (WOLFCRYPT_BIO_should_retry(cipher)) { + if (wc_BioShouldRetry(cipher)) { w = 0; continue; } @@ -6548,17 +6548,17 @@ static int bio_filter_test(const WOLFSSL_EVP_CIPHER* cipher_type) } } - if (!WOLFCRYPT_BIO_get_cipher_status(cipher)) + if (!wc_BioGetCipherStatus(cipher)) return -1078; /* get b64 BIO to free it only at first (test purpose) */ - WOLFCRYPT_BIO_pop(b64); + wc_BioPop(b64); /* free b64 BIO */ - WOLFCRYPT_BIO_free(b64); + wc_BioFree(b64); /* free BIO chain cipher-buffer-file */ - WOLFCRYPT_BIO_free_all(cipher); + wc_BioFreeAll(cipher); /* check decrypted data */ if (total != rand_size) @@ -6580,28 +6580,29 @@ int bio_connect_test(void) int len; char buf[1024]; - cbio = WOLFCRYPT_BIO_new_connect("www.wolfssl.com:http"); + cbio = wc_BioNewConnect("www.wolfssl.com:http"); if (cbio == NULL) return -3000; - if (WOLFCRYPT_BIO_do_connect(cbio) <= 0) { + if (wc_BioDoConnect(cbio) <= 0) { fprintf(stderr, "Error connecting to server\n"); return -3002; } - WOLFCRYPT_BIO_puts(cbio, "GET / HTTP/1.0\r\n\r\n"); + wc_BioPuts(cbio, "GET / HTTP/1.0\r\n\r\n"); for(;;) { - len = WOLFCRYPT_BIO_read(cbio, buf, sizeof(buf)); + len = wc_BioRead(cbio, buf, sizeof(buf)); if (len == 0) break; else if (len < 0) return -3003; } - WOLFCRYPT_BIO_free(cbio); + wc_BioFree(cbio); return 0; } + /* Required human interactions, must be move to API */ #if 0 int bio_accept_test(void) @@ -6611,78 +6612,78 @@ int bio_accept_test(void) char buf[256]; int r; - abio = WOLFCRYPT_BIO_new_accept("4444"); + abio = wc_BioNewAccept("4444"); /* force SO_REUSEADDR */ - WOLFCRYPT_BIO_set_bind_mode(abio, 2); + wc_BioSetBindMode(abio, 2); /* force NO_SIGPIPE and TCP_NODELAY */ - WOLFCRYPT_BIO_set_socket_options(abio, 3); + wc_BioSetSocketOptions(abio, 3); - /* First call to WOLFCRYPT_BIO_accept() sets up accept BIO */ - if (WOLFCRYPT_BIO_do_accept(abio) <= 0) { + /* First call to wc_BioAccept() sets up accept BIO */ + if (wc_BioDoAccept(abio) <= 0) { fprintf(stderr, "Error setting up accept\n"); return -4000; } - printf("WOLFCRYPT_BIO_do_accept 1\n"); + printf("wc_BioDoAccept 1\n"); /* Wait for incoming connection */ - if (WOLFCRYPT_BIO_do_accept(abio) <= 0) { + if (wc_BioDoAccept(abio) <= 0) { fprintf(stderr, "Error accepting connection\n"); return -4001; } fprintf(stderr, "Connection 1 established\n"); /* Retrieve BIO for connection */ - cbio = WOLFCRYPT_BIO_pop(abio); - WOLFCRYPT_BIO_puts(cbio, "Wait for second client\n"); + cbio = wc_BioPop(abio); + wc_BioPuts(cbio, "Wait for second client\n"); /* Wait for another connection */ - if (WOLFCRYPT_BIO_do_accept(abio) <= 0) { + if (wc_BioDoAccept(abio) <= 0) { fprintf(stderr, "Error accepting connection\n"); return -4002; } fprintf(stderr, "Connection 2 established\n"); /* Close accept BIO to refuse further connections */ - cbio2 = WOLFCRYPT_BIO_pop(abio); - WOLFCRYPT_BIO_free(abio); + cbio2 = wc_BioPop(abio); + wc_BioFree(abio); - WOLFCRYPT_BIO_puts(cbio, "Second client arrived, you can send msg\n"); - WOLFCRYPT_BIO_puts(cbio2, "Wait for message of First client\n"); + wc_BioPuts(cbio, "Second client arrived, you can send msg\n"); + wc_BioPuts(cbio2, "Wait for message of First client\n"); /* Read msg CBIO -> CBIO2, CBIO2 and CBIO2 -> CBIO */ do { XMEMSET(buf, 0, sizeof(buf)); - r = WOLFCRYPT_BIO_read(cbio, buf, sizeof(buf)); + r = wc_BioRead(cbio, buf, sizeof(buf)); if (r < 0) break; if (r >= 3 && !XSTRNCMP("end", buf, 3)) { - WOLFCRYPT_BIO_puts(cbio, "Peer close discussion\n"); + wc_BioPuts(cbio, "Peer close discussion\n"); break; } - WOLFCRYPT_BIO_puts(cbio2, buf); + wc_BioPuts(cbio2, buf); XMEMSET(buf, 0, sizeof(buf)); - r = WOLFCRYPT_BIO_read(cbio2, buf, sizeof(buf)); + r = wc_BioRead(cbio2, buf, sizeof(buf)); if (r < 0) break; if (r >= 3 && !XSTRNCMP("end", buf, 3)) { - WOLFCRYPT_BIO_puts(cbio, "Peer close discussion\n"); + wc_BioPuts(cbio, "Peer close discussion\n"); break; } - WOLFCRYPT_BIO_puts(cbio, buf); + wc_BioPuts(cbio, buf); } while (1); /* Close the two established connections */ - WOLFCRYPT_BIO_free(cbio); - WOLFCRYPT_BIO_free(cbio2); + wc_BioFree(cbio); + wc_BioFree(cbio2); return 0; } -#endif +#endif /* 0 */ int bio_connect_ssl_test(void) { @@ -6701,40 +6702,40 @@ int bio_connect_ssl_test(void) wolfSSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_NONE, 0); /* Lets make a SSL structure */ - ssl_bio = WOLFCRYPT_BIO_new_ssl(ssl_ctx, BIO_CLOSE); + ssl_bio = wolfSSL_BioNewSSL(ssl_ctx, BIO_CLOSE); if (ssl_bio == NULL) { ret = -3001; goto end; } /* Use a connect BIO under the SSL BIO */ - out = WOLFCRYPT_BIO_new_connect("www.google.com:443"); + out = wc_BioNewConnect("www.verisign.com:443"); if (out == NULL) { ret = -3002; goto end; } /* start connection */ - if (WOLFCRYPT_BIO_do_connect(out) <= 0) { + if (wc_BioDoConnect(out) <= 0) { fprintf(stderr, "Error connecting to server\n"); ret = -3003; goto end; } /* non blocking mode */ - WOLFCRYPT_BIO_set_nbio(out, 1); + wc_BioSetNbio(out, 1); /* Associate connect and ssl BIO */ - out = WOLFCRYPT_BIO_push(ssl_bio, out); + out = wc_BioPush(ssl_bio, out); if (out == NULL) { ret = -3004; goto end; } for (idx = 0;;) { - i = WOLFCRYPT_BIO_write(out, request+idx, len); + i = wc_BioWrite(out, request+idx, len); if (i <= 0) { - if (WOLFCRYPT_BIO_should_retry(out)) { + if (wc_BioShouldRetry(out)) { sleep(1); continue; } else { @@ -6749,11 +6750,11 @@ int bio_connect_ssl_test(void) } for (;;) { - i = WOLFCRYPT_BIO_read(out, buf, sizeof(buf)); + i = wc_BioRead(out, buf, sizeof(buf)); if (i == 0) break; if (i < 0) { - if (WOLFCRYPT_BIO_should_retry(out)) { + if (wc_BioShouldRetry(out)) { sleep(1); continue; } @@ -6766,7 +6767,7 @@ int bio_connect_ssl_test(void) ret = 0; end: - WOLFCRYPT_BIO_free_all(out); + wc_BioFreeAll(out); if (ssl_ctx != NULL) wolfSSL_CTX_free(ssl_ctx); @@ -6843,71 +6844,71 @@ int bio_accept_ssl_test(void) #endif /* NO_DH */ /* Setup server side SSL bio */ - ssl_bio = WOLFCRYPT_BIO_new_ssl(ssl_ctx, 0); + ssl_bio = wolfSSL_BioNewSSL(ssl_ctx, 0); if (ssl_bio == NULL) { ret = -3005; goto end; } /* Create the buffering BIO */ - buf_bio = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_f_buffer()); + buf_bio = wc_BioNew(wc_Bio_f_buffer()); if (buf_bio == NULL) { ret = -3006; goto end; } /* Add to chain */ - ssl_bio = WOLFCRYPT_BIO_push(buf_bio, ssl_bio); + ssl_bio = wc_BioPush(buf_bio, ssl_bio); if (ssl_bio == NULL) { ret = -3007; goto end; } - in = WOLFCRYPT_BIO_new_accept("4433"); + in = wc_BioNewAccept("4433"); if (in == NULL) { ret = -3008; goto end; } /* force SO_REUSEADDR */ - WOLFCRYPT_BIO_set_bind_mode(in, 2); + wc_BioSetBindMode(in, 2); /* force NO_SIGPIPE and TCP_NODELAY */ - WOLFCRYPT_BIO_set_socket_options(in, 3); + wc_BioSetSocketOptions(in, 3); /* By doing this when a new connection is established * we automatically have ssl_bio inserted into it. The * BIO chain is now 'swallowed' by the accept BIO and * will be freed when the accept BIO is freed. */ - if (WOLFCRYPT_BIO_set_accept_bios(in, ssl_bio) <= 0) { + if (wc_BioSetAcceptBios(in, ssl_bio) <= 0) { ret = -3006; goto end; } while (i++ < 5) { /* Setup accept BIO */ - if (WOLFCRYPT_BIO_do_accept(in) <= 0) { + if (wc_BioDoAccept(in) <= 0) { fprintf(stderr, "Error setting up accept BIO\n"); ret = -3010; goto end; } /* Now wait for incoming connection */ - if (WOLFCRYPT_BIO_do_handshake(in) <= 0) { + if (wc_BioDoHandshake(in) <= 0) { fprintf(stderr, "Error in connection\n"); ret = -3011; goto end; } - b_rw = WOLFCRYPT_BIO_pop(in); + b_rw = wc_BioPop(in); if (b_rw == NULL) { printf("BIO error -> close\n"); break; } for(;;) { - len = WOLFCRYPT_BIO_gets(b_rw, buf, sizeof(buf)); + len = wc_BioGets(b_rw, buf, sizeof(buf)); if (len == 0) { /* * If we have finished, remove the underlying BIO stack so the @@ -6918,41 +6919,41 @@ int bio_accept_ssl_test(void) break; } else if (len < 0) { - if (WOLFCRYPT_BIO_should_retry(b_rw)) + if (wc_BioShouldRetry(b_rw)) continue; printf("Read error -> close\n"); break; } if (buf[0] == '\r' || buf[0] == '\n') { - WOLFCRYPT_BIO_puts(b_rw, "CLOSE\n"); - WOLFCRYPT_BIO_flush(b_rw); + wc_BioPuts(b_rw, "CLOSE\n"); + wc_BioFlush(b_rw); printf("Done -> close\n"); break; } fprintf(stdout, "Received : '%s'\n", buf); /* Send response */ - WOLFCRYPT_BIO_puts(b_rw, "ACK: "); - WOLFCRYPT_BIO_puts(b_rw, buf); - WOLFCRYPT_BIO_flush(b_rw); + wc_BioPuts(b_rw, "ACK: "); + wc_BioPuts(b_rw, buf); + wc_BioFlush(b_rw); } /* close connection */ - WOLFCRYPT_BIO_free_all(b_rw); + wc_BioFreeAll(b_rw); } ret = 0; end: if (in != NULL) - WOLFCRYPT_BIO_free_all(in); + wc_BioFreeAll(in); if (ssl_ctx != NULL) wolfSSL_CTX_free(ssl_ctx); return ret; } -#endif +#endif /* 0 */ int bio_test(void) { @@ -6965,29 +6966,29 @@ int bio_test(void) /* BIO FILE TEST */ /* create file */ - bio = WOLFCRYPT_BIO_new_file("test_bio.txt", "w"); + bio = wc_BioNewFile("test_bio.txt", "w"); if (bio == NULL) return -1000; /* write */ - ret = WOLFCRYPT_BIO_write(bio, buf, (int)strlen(buf)); + ret = wc_BioWrite(bio, buf, (int)strlen(buf)); if (ret != (int)strlen(buf)) return -1001; - ret = WOLFCRYPT_BIO_puts(bio, "\n"); + ret = wc_BioPuts(bio, "\n"); if (ret != 1) return -1002; /* close */ - WOLFCRYPT_BIO_free(bio); + wc_BioFree(bio); /* open */ - bio = WOLFCRYPT_BIO_new_file("test_bio.txt", "r"); + bio = wc_BioNewFile("test_bio.txt", "r"); if (bio == NULL) return -1003; /* read */ - ret = WOLFCRYPT_BIO_read(bio, buf_w, sizeof(buf_w)); + ret = wc_BioRead(bio, buf_w, sizeof(buf_w)); if (ret != (int)strlen(buf)+1) return -1004; @@ -6995,38 +6996,38 @@ int bio_test(void) return -1005; /* close */ - WOLFCRYPT_BIO_free(bio); + wc_BioFree(bio); /* append */ - bio = WOLFCRYPT_BIO_new_file("test_bio.txt", "a+"); + bio = wc_BioNewFile("test_bio.txt", "a+"); if (bio == NULL) return -1006; - ret = WOLFCRYPT_BIO_tell(bio); + ret = wc_BioTell(bio); if (ret != (int)strlen(buf)+1) return -1007; /* write */ - ret = WOLFCRYPT_BIO_printf(bio, "%s\n", buf); + ret = wc_BioPrintf(bio, "%s\n", buf); if (ret != (int)strlen(buf)+1) return -1008; - ret = WOLFCRYPT_BIO_tell(bio); + ret = wc_BioTell(bio); if (ret != 2*((int)strlen(buf)+1)) return -1009; /* reset, before reading */ - ret = WOLFCRYPT_BIO_reset(bio); + ret = wc_BioReset(bio); if (ret != 0) return -1010; /* read */ - ret = WOLFCRYPT_BIO_read(bio, buf_w, sizeof(buf_w)); + ret = wc_BioRead(bio, buf_w, sizeof(buf_w)); if (ret != 2*((int)strlen(buf)+1)) return -1011; /* close */ - WOLFCRYPT_BIO_free(bio); + wc_BioFree(bio); if (XMEMCMP(buf, buf_w, (int)strlen(buf))) return -1012; @@ -7035,92 +7036,92 @@ int bio_test(void) return -1013; /* BIO MEMORY TEST */ - bio = WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_s_mem()); + bio = wc_BioNew(wc_Bio_s_mem()); if (bio == NULL) return -1050; - ret = WOLFCRYPT_BIO_puts(bio, buf); + ret = wc_BioPuts(bio, buf); if (ret != (int)strlen(buf)) return -1051; - ret = WOLFCRYPT_BIO_gets(bio, buf_w, sizeof(buf_w)); + ret = wc_BioGets(bio, buf_w, sizeof(buf_w)); if (ret != (int)strlen(buf)) return -1052; - ret = WOLFCRYPT_BIO_gets(bio, buf_w, sizeof(buf_w)); + ret = wc_BioGets(bio, buf_w, sizeof(buf_w)); if (ret != 0) return -1053; - WOLFCRYPT_BIO_reset(bio); + wc_BioReset(bio); - ret = WOLFCRYPT_BIO_write(bio, buf, (int)strlen(buf)); + ret = wc_BioWrite(bio, buf, (int)strlen(buf)); if (ret != (int)strlen(buf)) return -1054; - ret = WOLFCRYPT_BIO_write(bio, buf, (int)strlen(buf)); + ret = wc_BioWrite(bio, buf, (int)strlen(buf)); if (ret != (int)strlen(buf)) return -1055; XMEMSET(buf_w, 0, sizeof(buf_w)); - ret = WOLFCRYPT_BIO_read(bio, buf_w, 5); - ret += WOLFCRYPT_BIO_read(bio, buf_w+5, 9); - ret += WOLFCRYPT_BIO_read(bio, buf_w+14, 17); - ret += WOLFCRYPT_BIO_read(bio, buf_w+31, 7); + ret = wc_BioRead(bio, buf_w, 5); + ret += wc_BioRead(bio, buf_w+5, 9); + ret += wc_BioRead(bio, buf_w+14, 17); + ret += wc_BioRead(bio, buf_w+31, 7); - if (ret != 2*(int)strlen(buf)-WOLFCRYPT_BIO_pending(bio)) + if (ret != 2*(int)strlen(buf)-wc_BioPending(bio)) return -1059; - if (XMEMCMP(buf, buf_w, 2*(int)strlen(buf)-WOLFCRYPT_BIO_pending(bio))) + if (XMEMCMP(buf, buf_w, 2*(int)strlen(buf)-wc_BioPending(bio))) return -1060; /* assembling BIO test for all cipher */ #ifndef NO_AES - ret = bio_filter_test(wolfSSL_EVP_aes_128_cbc()); + ret = bio_filter_test(wc_EVP_aes_128_cbc()); if (ret != 0) return ret; - ret = bio_filter_test(wolfSSL_EVP_aes_192_cbc()); + ret = bio_filter_test(wc_EVP_aes_192_cbc()); if (ret != 0) return ret; - ret = bio_filter_test(wolfSSL_EVP_aes_256_cbc()); + ret = bio_filter_test(wc_EVP_aes_256_cbc()); if (ret != 0) return ret; #ifdef WOLFSSL_AES_COUNTER - ret = bio_filter_test(wolfSSL_EVP_aes_128_ctr()); + ret = bio_filter_test(wc_EVP_aes_128_ctr()); if (ret != 0) return ret; - ret = bio_filter_test(wolfSSL_EVP_aes_192_ctr()); + ret = bio_filter_test(wc_EVP_aes_192_ctr()); if (ret != 0) return ret; - ret = bio_filter_test(wolfSSL_EVP_aes_256_ctr()); + ret = bio_filter_test(wc_EVP_aes_256_ctr()); if (ret != 0) return ret; #endif /* WOLFSSL_AES_COUNTER */ #endif /* NO_AES */ #ifndef NO_RC4 - ret = bio_filter_test(wolfSSL_EVP_rc4()); + ret = bio_filter_test(wc_EVP_rc4()); if (ret != 0) return ret; #endif /* NO_RC4 */ #ifndef NO_DES3 - ret = bio_filter_test(wolfSSL_EVP_des_cbc()); + ret = bio_filter_test(wc_EVP_des_cbc()); if (ret != 0) return ret; - ret = bio_filter_test(wolfSSL_EVP_des_ede3_cbc()); + ret = bio_filter_test(wc_EVP_des_ede3_cbc()); if (ret != 0) return ret; #endif /* NO_DES3 */ #ifdef HAVE_IDEA - ret = bio_filter_test(wolfSSL_EVP_idea_cbc()); + ret = bio_filter_test(wc_EVP_idea_cbc()); if (ret != 0) return ret; #endif /* HAVE_IDEA */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index c49193441..ddf88fa5e 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -26,10 +26,7 @@ #include #include - -#ifdef OPENSSL_EXTRA -#include -#endif +#include #ifdef HAVE_CRL #include @@ -952,15 +949,6 @@ enum Misc { MAX_REQUEST_SZ = 256, /* Maximum cert req len (no auth yet */ SESSION_FLUSH_COUNT = 256, /* Flush session cache unless user turns off */ - RC4_KEY_SIZE = 16, /* always 128bit */ - DES_KEY_SIZE = 8, /* des */ - DES3_KEY_SIZE = 24, /* 3 des ede */ - DES_IV_SIZE = DES_BLOCK_SIZE, - AES_256_KEY_SIZE = 32, /* for 256 bit */ - AES_192_KEY_SIZE = 24, /* for 192 bit */ - AES_IV_SIZE = 16, /* always block size */ - AES_128_KEY_SIZE = 16, /* for 128 bit */ - AEAD_SEQ_OFFSET = 4, /* Auth Data: Sequence number */ AEAD_TYPE_OFFSET = 8, /* Auth Data: Type */ AEAD_VMAJ_OFFSET = 9, /* Auth Data: Major Version */ @@ -998,7 +986,6 @@ enum Misc { RABBIT_KEY_SIZE = 16, /* 128 bits */ RABBIT_IV_SIZE = 8, /* 64 bits for iv */ - EVP_SALT_SIZE = 8, /* evp salt size 64 bits */ ECDHE_SIZE = 32, /* ECHDE server size defaults to 256 bit */ MAX_EXPORT_ECC_SZ = 256, /* Export ANS X9.62 max future size */ @@ -2503,8 +2490,8 @@ struct WOLFSSL { Keys keys; Options options; #ifdef OPENSSL_EXTRA - WOLFSSL_BIO* biord; /* socket bio read to free/close */ - WOLFSSL_BIO* biowr; /* socket bio write to free/close */ + WOLFCRYPT_BIO* biord; /* socket bio read to free/close */ + WOLFCRYPT_BIO* biowr; /* socket bio write to free/close */ #endif #ifndef NO_RSA RsaKey* peerRsaKey; diff --git a/wolfssl/openssl/bio.h b/wolfssl/openssl/bio.h index 2680e4c26..5f1d4211d 100644 --- a/wolfssl/openssl/bio.h +++ b/wolfssl/openssl/bio.h @@ -1,564 +1,23 @@ -#ifndef WOLFCRYPT_BIO_H_ -#define WOLFCRYPT_BIO_H_ +/* bio.h for openssl */ -#include -#include -#include -#include +#ifndef WOLFSSL_BIO_H_ +#define WOLFSSL_BIO_H_ + +#include -#ifdef OPENSSL_EXTRA #ifdef __cplusplus -extern "C" { + extern "C" { #endif -/* BIO types */ -enum WS_BIO_TYPE { - BIO_TYPE_NONE = 0, - BIO_TYPE_SSL = 1, - BIO_TYPE_MD = 2, /* passive */ - BIO_TYPE_BUFFER = 3, - BIO_TYPE_CIPHER = 4, - BIO_TYPE_BASE64 = 5, - BIO_TYPE_LINEBUFFER = 6, - BIO_TYPE_ASN1 = 7, - BIO_TYPE_COMP = 8, - BIO_TYPE_PROXY_CLIENT = 9, /* client proxy BIO */ - BIO_TYPE_PROXY_SERVER = 10, /* server proxy BIO */ - BIO_TYPE_NULL_FILTER = 11, - BIO_TYPE_BER = 12, /* BER -> bin filter */ - BIO_TYPE_MEM = 13, - BIO_TYPE_FILE = 14, - BIO_TYPE_NULL = 15, - BIO_TYPE_BIO = 16, /* (half a) BIO pair */ - - /* socket, fd, connect or accept */ - BIO_TYPE_DESCRIPTOR = 0x100, - - BIO_TYPE_FD = 17|BIO_TYPE_DESCRIPTOR, - BIO_TYPE_SOCKET = 18|BIO_TYPE_DESCRIPTOR, - /* socket - connect */ - BIO_TYPE_CONNECT = 19|BIO_TYPE_DESCRIPTOR, - /* socket for accept */ - BIO_TYPE_ACCEPT = 20|BIO_TYPE_DESCRIPTOR, - BIO_TYPE_DGRAM = 21|BIO_TYPE_DESCRIPTOR, -}; - -/* - * BIO_FILENAME_READ|BIO_CLOSE to open or close on free. - * BIO_set_fp(in,stdin,BIO_NOCLOSE); - */ -#if !defined(BIO_CLOSE) || !defined(BIO_NOCLOSE) -#define BIO_CLOSE 1 -#define BIO_NOCLOSE 0 -#endif - -/*enum WS_BIO_FILE { - BIO_NOCLOSE = 0, - BIO_CLOSE = 1, -};*/ - -/* - * These are used in the following macros and are passed to BIO_ctrl() - */ -enum WS_BIO_CTRL { - BIO_CTRL_RESET = 1, /* opt - rewind/zero etc */ - BIO_CTRL_EOF = 2, /* opt - are we at the eof */ - BIO_CTRL_INFO = 3, /* opt - extra tit-bits */ - BIO_CTRL_SET = 4, /* man - set the 'IO' type */ - BIO_CTRL_GET = 5, /* man - get the 'IO' type */ - BIO_CTRL_PUSH = 6, /* opt - internal, used to signify change */ - BIO_CTRL_POP = 7, /* opt - internal, used to signify change */ - BIO_CTRL_GET_CLOSE = 8, /* man - set the 'close' on free */ - BIO_CTRL_SET_CLOSE = 9, /* man - set the 'close' on free */ - BIO_CTRL_PENDING = 10, /* opt - is their more data buffered */ - BIO_CTRL_FLUSH = 11, /* opt - 'flush' buffered output */ - BIO_CTRL_DUP = 12, /* man - extra stuff for 'duped' BIO */ - BIO_CTRL_WPENDING = 13, /* opt - number of bytes still to write */ - - /* callback is int cb(BIO *bio,state,ret); */ - BIO_CTRL_SET_CALLBACK = 14, /* opt - set callback function */ - BIO_CTRL_GET_CALLBACK = 15, /* opt - set callback function */ - - BIO_CTRL_SET_FILENAME = 30, /* BIO_s_file special */ - - /* dgram BIO stuff */ - BIO_CTRL_DGRAM_CONNECT = 31, /* BIO dgram special */ - BIO_CTRL_DGRAM_SET_CONNECTED = 32, /* allow for an externally connected - * socket to be passed in */ - BIO_CTRL_DGRAM_SET_RECV_TIMEOUT = 33, /* setsockopt, essentially */ - BIO_CTRL_DGRAM_GET_RECV_TIMEOUT = 34, /* getsockopt, essentially */ - BIO_CTRL_DGRAM_SET_SEND_TIMEOUT = 35, /* setsockopt, essentially */ - BIO_CTRL_DGRAM_GET_SEND_TIMEOUT = 36, /* getsockopt, essentially */ - - BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP = 37, /* flag whether the last */ - BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP = 38, /* I/O operation tiemd out */ - - /* #ifdef IP_MTU_DISCOVER */ - BIO_CTRL_DGRAM_MTU_DISCOVER = 39, /* set DF bit on egress packets */ - /* #endif */ - - BIO_CTRL_DGRAM_QUERY_MTU = 40, /* as kernel for current MTU */ - BIO_CTRL_DGRAM_GET_FALLBACK_MTU = 47, - BIO_CTRL_DGRAM_GET_MTU = 41, /* get cached value for MTU */ - BIO_CTRL_DGRAM_SET_MTU = 42, /* set cached value for MTU. - * want to use this if asking - * the kernel fails */ - BIO_CTRL_DGRAM_MTU_EXCEEDED = 43, /* check whether the MTU was - * exceed in the previous write - * operation */ - BIO_CTRL_DGRAM_GET_PEER = 46, - BIO_CTRL_DGRAM_SET_PEER = 44, /* Destination for the data */ - - BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT = 45, /* Next DTLS handshake timeout - * to adjust socket timeouts */ - BIO_CTRL_DGRAM_SET_DONT_FRAG = 48, - BIO_CTRL_DGRAM_GET_MTU_OVERHEAD = 49, -}; - -/* modifiers */ -enum WS_BIO_MOD { - BIO_FP_READ = 0x02, - BIO_FP_WRITE = 0x04, - BIO_FP_APPEND = 0x08, - BIO_FP_TEXT = 0x10, -}; - - -/* flags */ -enum WS_BIO_FLAGS { - BIO_FLAGS_READ = 0x01, - BIO_FLAGS_WRITE = 0x02, - BIO_FLAGS_IO_SPECIAL = 0x04, - BIO_FLAGS_RWS = BIO_FLAGS_READ| - BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL, - BIO_FLAGS_SHOULD_RETRY = 0x08, - BIO_FLAGS_BASE64_NO_NL = 0x100, - /* Used with memory BIOs: shouldn't free up or change the data in any way. - */ - BIO_FLAGS_MEM_RDONLY = 0x200, -}; - -enum WS_BIO_RR { -/* Returned from the SSL bio when the certificate retrieval code had an error */ - BIO_RR_SSL_X509_LOOKUP = 0x01, -/* Returned from the connect BIO when a connect would have blocked */ - BIO_RR_CONNECT = 0x02, -/* Returned from the accept BIO when an accept would have blocked */ - BIO_RR_ACCEPT = 0x03, -}; - -/* These are passed by the BIO callback */ -enum WS_BIO_CB_FLAGS { - BIO_CB_FREE = 0x01, - BIO_CB_READ = 0x02, - BIO_CB_WRITE = 0x03, - BIO_CB_PUTS = 0x04, - BIO_CB_GETS = 0x05, - BIO_CB_CTRL = 0x06, - BIO_CB_RETURN = 0x80, -}; - -#define BIO_CB_return(a) ((a) | BIO_CB_RETURN) -#define BIO_cb_post(a) ((a) & BIO_CB_RETURN) -#define BIO_cb_pre(a) (!BIO_cb_post((a))) - - -typedef struct WOLFCRYPT_BIO WOLFCRYPT_BIO; -typedef struct WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_METHOD; - -typedef void WOLFCRYPT_BIO_info_cb (WOLFCRYPT_BIO *, int, const char *, - int, long, long); - -/* wolfSSL BIO_METHOD type */ -struct WOLFCRYPT_BIO_METHOD { - int type; /* method type */ - const char *name; - int (*bwrite) (WOLFCRYPT_BIO *, const char *, int); - int (*bread) (WOLFCRYPT_BIO *, char *, int); - int (*bputs) (WOLFCRYPT_BIO *, const char *); - int (*bgets) (WOLFCRYPT_BIO *, char *, int); - long (*ctrl) (WOLFCRYPT_BIO *, int, long, void *); - int (*create) (WOLFCRYPT_BIO *); - int (*destroy) (WOLFCRYPT_BIO *); - long (*callback_ctrl) (WOLFCRYPT_BIO *, int, WOLFCRYPT_BIO_info_cb *); -}; - -struct WOLFCRYPT_BIO { - WOLFCRYPT_BIO_METHOD *method; - /* bio, mode, argp, argi, argl, ret */ - long (*callback) (WOLFCRYPT_BIO *, int, const char *, int, long, long); - char *cb_arg; /* first argument for the callback */ - int init; - int shutdown; - int flags; /* extra storage */ - int retry_reason; - int num; - void *ptr; - WOLFCRYPT_BIO *next_bio; /* used by filter BIOs */ - WOLFCRYPT_BIO *prev_bio; /* used by filter BIOs */ - int references; - wolfSSL_Mutex refMutex; /* to lock r/w on references */ - unsigned long num_read; - unsigned long num_write; -}; - -enum WS_BIO_C_FLAGS { - BIO_C_SET_CONNECT = 100, - BIO_C_DO_STATE_MACHINE = 101, - BIO_C_SET_NBIO = 102, - BIO_C_SET_PROXY_PARAM = 103, - BIO_C_SET_FD = 104, - BIO_C_GET_FD = 105, - BIO_C_SET_FILE_PTR = 106, - BIO_C_GET_FILE_PTR = 107, - BIO_C_SET_FILENAME = 108, - BIO_C_SET_SSL = 109, - BIO_C_GET_SSL = 110, - BIO_C_SET_MD = 111, - BIO_C_GET_MD = 112, - BIO_C_GET_CIPHER_STATUS = 113, - BIO_C_SET_BUF_MEM = 114, - BIO_C_GET_BUF_MEM_PTR = 115, - BIO_C_GET_BUFF_NUM_LINES = 116, - BIO_C_SET_BUFF_SIZE = 117, - BIO_C_SET_ACCEPT = 118, - BIO_C_SSL_MODE = 119, - BIO_C_GET_MD_CTX = 120, - BIO_C_GET_PROXY_PARAM = 121, - BIO_C_SET_BUFF_READ_DATA = 122, /* data to read first */ - BIO_C_GET_CONNECT = 123, - BIO_C_GET_ACCEPT = 124, - BIO_C_SET_SSL_RENEGOTIATE_BYTES = 125, - BIO_C_GET_SSL_NUM_RENEGOTIATES = 126, - BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT = 127, - BIO_C_FILE_SEEK = 128, - BIO_C_GET_CIPHER_CTX = 129, - BIO_C_SET_BUF_MEM_EOF_RETURN = 130, /* return end of input - * value */ - BIO_C_SET_BIND_MODE = 131, - BIO_C_GET_BIND_MODE = 132, - BIO_C_FILE_TELL = 133, - BIO_C_GET_SOCKS = 134, - BIO_C_SET_SOCKS = 135, - - BIO_C_SET_WRITE_BUF_SIZE = 136, /* for BIO_s_bio */ - BIO_C_GET_WRITE_BUF_SIZE = 137, - BIO_C_MAKE_BIO_PAIR = 138, - BIO_C_DESTROY_BIO_PAIR = 139, - BIO_C_GET_WRITE_GUARANTEE = 140, - BIO_C_GET_READ_REQUEST = 141, - BIO_C_SHUTDOWN_WR = 142, - BIO_C_NREAD0 = 143, - BIO_C_NREAD = 144, - BIO_C_NWRITE0 = 145, - BIO_C_NWRITE = 146, - BIO_C_RESET_READ_REQUEST = 147, - BIO_C_SET_MD_CTX = 148, - - BIO_C_SET_PREFIX = 149, - BIO_C_GET_PREFIX = 150, - BIO_C_SET_SUFFIX = 151, - BIO_C_GET_SUFFIX = 152, - - BIO_C_SET_EX_ARG = 153, - BIO_C_GET_EX_ARG = 154, -}; - -/* connect BIO */ -enum WS_BIO_CONN { - BIO_CONN_S_BEFORE = 1, - BIO_CONN_S_GET_IP = 2, - BIO_CONN_S_GET_PORT = 3, - BIO_CONN_S_CREATE_SOCKET = 4, - BIO_CONN_S_CONNECT = 5, - BIO_CONN_S_OK = 6, - BIO_CONN_S_BLOCKED_CONNECT = 7, - BIO_CONN_S_NBIO = 8, -}; - -enum WS_BIO_BIND { - BIO_BIND_NORMAL = 0, - BIO_BIND_REUSEADDR_IF_UNUSED = 1, - BIO_BIND_REUSEADDR = 2, -}; - -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_new(WOLFCRYPT_BIO_METHOD *method); -WOLFSSL_API int WOLFCRYPT_BIO_free(WOLFCRYPT_BIO *bio); -WOLFSSL_API void WOLFCRYPT_BIO_free_all(WOLFCRYPT_BIO *bio); - -WOLFSSL_API const char *WOLFCRYPT_BIO_method_name(const WOLFCRYPT_BIO *bio); -WOLFSSL_API int WOLFCRYPT_BIO_method_type(const WOLFCRYPT_BIO *bio); - -WOLFSSL_API int WOLFCRYPT_BIO_set(WOLFCRYPT_BIO *bio, - WOLFCRYPT_BIO_METHOD *method); -WOLFSSL_API void WOLFCRYPT_BIO_clear_flags(WOLFCRYPT_BIO *bio, int flags); -WOLFSSL_API void WOLFCRYPT_BIO_set_flags(WOLFCRYPT_BIO *bio, int flags); -WOLFSSL_API int WOLFCRYPT_BIO_test_flags(const WOLFCRYPT_BIO *bio, int flags); - -#define WOLFCRYPT_BIO_get_flags(b) WOLFCRYPT_BIO_test_flags(b, ~(0x0)) -#define WOLFCRYPT_BIO_set_retry_special(b) \ - WOLFCRYPT_BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) -#define WOLFCRYPT_BIO_set_retry_read(b) \ - WOLFCRYPT_BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) -#define WOLFCRYPT_BIO_set_retry_write(b) \ - WOLFCRYPT_BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) - - -#define WOLFCRYPT_BIO_clear_retry_flags(b) \ - WOLFCRYPT_BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) -#define WOLFCRYPT_BIO_get_retry_flags(b) \ - WOLFCRYPT_BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) - - /* These should be used by the application to tell why we should retry */ -#define WOLFCRYPT_BIO_should_read(f) \ - WOLFCRYPT_BIO_test_flags(f, BIO_FLAGS_READ) -#define WOLFCRYPT_BIO_should_write(f) \ - WOLFCRYPT_BIO_test_flags(f, BIO_FLAGS_WRITE) -#define WOLFCRYPT_BIO_should_io_special(f) \ - WOLFCRYPT_BIO_test_flags(f, BIO_FLAGS_IO_SPECIAL) -#define WOLFCRYPT_BIO_retry_type(f) \ - WOLFCRYPT_BIO_test_flags(f, BIO_FLAGS_RWS) -#define WOLFCRYPT_BIO_should_retry(f) \ - WOLFCRYPT_BIO_test_flags(f, BIO_FLAGS_SHOULD_RETRY) - -WOLFSSL_API long (*WOLFCRYPT_BIO_get_callback(const WOLFCRYPT_BIO *bio)) -(WOLFCRYPT_BIO *, int, const char *, int, long, long); - -WOLFSSL_API void WOLFCRYPT_BIO_set_callback(WOLFCRYPT_BIO *bio, - long (*cb) (WOLFCRYPT_BIO *, int, - const char *, int, long, long)); -WOLFSSL_API void WOLFCRYPT_BIO_set_callback_arg(WOLFCRYPT_BIO *bio, char *arg); -WOLFSSL_API char *WOLFCRYPT_BIO_get_callback_arg(const WOLFCRYPT_BIO *bio); - -WOLFSSL_API int WOLFCRYPT_BIO_read(WOLFCRYPT_BIO *bio, void *out, int outl); -WOLFSSL_API int WOLFCRYPT_BIO_write(WOLFCRYPT_BIO *bio, const void *in, int inl); -WOLFSSL_API int WOLFCRYPT_BIO_puts(WOLFCRYPT_BIO *bio, const char *in); -WOLFSSL_API int WOLFCRYPT_BIO_gets(WOLFCRYPT_BIO *bio, char *in, int inl); - -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_push(WOLFCRYPT_BIO *top, - WOLFCRYPT_BIO *next); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_pop(WOLFCRYPT_BIO *bio); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_next(WOLFCRYPT_BIO *bio); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_get_retry_BIO(WOLFCRYPT_BIO *bio, - int *reason); -WOLFSSL_API int WOLFCRYPT_BIO_get_retry_reason(WOLFCRYPT_BIO *bio); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_find_type(WOLFCRYPT_BIO *bio, int type); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_dup_chain(WOLFCRYPT_BIO *bio); -#define WOLFCRYPT_BIO_dup_state(bio, ret) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_DUP, 0, ret) - -WOLFSSL_API long WOLFCRYPT_BIO_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long larg, void *parg); -WOLFSSL_API long WOLFCRYPT_BIO_callback_ctrl(WOLFCRYPT_BIO *bio, int cmd, - void (*fp) (WOLFCRYPT_BIO *, int, - const char *, int, long, long)); -WOLFSSL_API long WOLFCRYPT_BIO_int_ctrl(WOLFCRYPT_BIO *bio, int cmd, - long larg, int iarg); -WOLFSSL_API char *WOLFCRYPT_BIO_ptr_ctrl(WOLFCRYPT_BIO *bio, int cmd, long larg); -WOLFSSL_API size_t WOLFCRYPT_BIO_ctrl_pending(WOLFCRYPT_BIO *bio); -WOLFSSL_API size_t WOLFCRYPT_BIO_ctrl_wpending(WOLFCRYPT_BIO *bio); - -WOLFSSL_API int WOLFCRYPT_BIO_indent(WOLFCRYPT_BIO *bio, int indent, int max); - -WOLFSSL_API unsigned long WOLFCRYPT_BIO_number_read(WOLFCRYPT_BIO *bio); -WOLFSSL_API unsigned long WOLFCRYPT_BIO_number_written(WOLFCRYPT_BIO *bio); - -#define WOLFCRYPT_BIO_reset(bio) \ - (int)WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL) -#define WOLFCRYPT_BIO_eof(bio) \ - (int)WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL) -#define WOLFCRYPT_BIO_set_close(bio,c) \ - (int)WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, (c), NULL) -#define WOLFCRYPT_BIO_get_close(bio) \ - (int)WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_GET_CLOSE, 0, NULL) -#define WOLFCRYPT_BIO_pending(bio) \ - (int)WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL) -#define WOLFCRYPT_BIO_wpending(bio) \ - (int)WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL) -#define WOLFCRYPT_BIO_flush(bio) \ - (int)WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL) -#define WOLFCRYPT_BIO_set_info_callback(bio, cb) \ - (int)WOLFCRYPT_BIO_callback_ctrl(bio, BIO_CTRL_SET_CALLBACK, cb) -#define WOLFCRYPT_BIO_get_info_callback(bio, cb) \ - (int)WOLFCRYPT_BIO_callback_ctrl(bio, BIO_CTRL_GET_CALLBACK, 0, cb) - -WOLFSSL_API void WOLFCRYPT_BIO_copy_next_retry(WOLFCRYPT_BIO *b); - -WOLFSSL_API int WOLFCRYPT_BIO_printf(WOLFCRYPT_BIO *bio, - const char *format, ...); - -/* BIO file */ -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_file(void); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_fp(XFILE f, int close_flag); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_file(const char *name, - const char *mode); -#define WOLFCRYPT_BIO_set_fp(bio, f, c) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_FILE_PTR, c, (char *)f) -#define WOLFCRYPT_BIO_get_fp(bio, f) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_GET_FILE_PTR, 0, (char *)f) -#define WOLFCRYPT_BIO_seek(bio, ofs) \ - (int)WOLFCRYPT_BIO_ctrl(bio, BIO_C_FILE_SEEK, ofs, NULL) -#define WOLFCRYPT_BIO_tell(bio) \ - (int)WOLFCRYPT_BIO_ctrl(bio, BIO_C_FILE_TELL, 0, NULL) -#define WOLFCRYPT_BIO_read_filename(bio, name) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_READ, name) -#define WOLFCRYPT_BIO_write_filename(bio, name) \ - WOLFCRYPT_BIO_ctrl(bio,BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_WRITE, name) -#define WOLFCRYPT_BIO_append_filename(bio, name) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_APPEND, name) -#define WOLFCRYPT_BIO_rw_filename(bio, name) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_FILENAME, \ - BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) - -/* BIO memory */ -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_mem(void); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_mem_buf(void *data, int len); - -/* BIO fd */ -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_fd(void); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_fd(int fd, int close_flag); - -/* BIO null */ -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_null(void); - -/* BIO socket */ -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_socket(void); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_socket(int fd, int close_flag); -WOLFSSL_API int WOLFCRYPT_BIO_sock_should_retry(int i); -WOLFSSL_API int WOLCRYPT_BIO_sock_non_fatal_error(int err); - -#define WOLFCRYPT_BIO_set_fd(bio, fd, c) \ - WOLFCRYPT_BIO_int_ctrl(bio, BIO_C_SET_FD, c, fd) -#define WOLFCRYPT_BIO_get_fd(bio, c) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_GET_FD, 0, (char *)c) - -/* BIO connect */ -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_connect(void); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_connect(const char *host_port); -#define WOLFCRYPT_BIO_set_conn_hostname(bio, hname) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, (char *)hname) -#define WOLFCRYPT_BIO_set_conn_port(bio, port) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_CONNECT, 1, (char *)port) -#define WOLFCRYPT_BIO_set_conn_ip(bio, ip) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_CONNECT, 2, (char *)ip) -#define WOLFCRYPT_BIO_set_conn_int_port(bio, port) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_CONNECT, 3, (char *)port) - -#define WOLFCRYPT_BIO_get_conn_hostname(bio) \ - WOLFCRYPT_BIO_ptr_ctrl(bio, BIO_C_GET_CONNECT, 0) -#define WOLFCRYPT_BIO_get_conn_port(bio) \ - WOLFCRYPT_BIO_ptr_ctrl(bio, BIO_C_GET_CONNECT, 1) -#define WOLFCRYPT_BIO_get_conn_ip(bio) \ - WOLFCRYPT_BIO_ptr_ctrl(bio, BIO_C_GET_CONNECT, 2) -#define WOLFCRYPT_BIO_get_conn_int_port(bio) \ - WOLFCRYPT_BIO_int_ctrl(bio, BIO_C_GET_CONNECT, 3, 0) - -#define WOLFCRYPT_BIO_set_nbio(bio, n) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_NBIO, n, NULL) - -#define WOLFCRYPT_BIO_do_handshake(bio) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NULL) -#define WOLFCRYPT_BIO_do_connect(bio) WOLFCRYPT_BIO_do_handshake(bio) -#define WOLFCRYPT_BIO_do_accept(bio) WOLFCRYPT_BIO_do_handshake(bio) - -/* BIO accept */ -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_accept(const char *str); -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_accept(void); -#define WOLFCRYPT_BIO_set_accept_port(bio, name) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_ACCEPT, 0, (char *)name) -#define WOLFCRYPT_BIO_set_accept_bios(bio, nbio) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_ACCEPT, 2, nbio) -#define WOLFCRYPT_BIO_set_bind_mode(bio, mode) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_BIND_MODE, mode, NULL) -#define WOLFCRYPT_BIO_set_socket_options(bio, opt) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_EX_ARG, opt, NULL) - - -/* BIO datagram */ -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_s_datagram(void); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_dgram(int fd, int close_flag); - -/* BIO filter buffer */ -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_f_buffer(void); - -#define WOLFCRYPT_BIO_get_mem_data(bio, data) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_CTRL_INFO, 0, data) -#define WOLFCRYPT_BIO_set_mem_buf(bio, data, c) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_BUF_MEM, c, data) -#define WOLFCRYPT_BIO_get_mem_ptr(b, ptr) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_GET_BUF_MEM_PTR,0, (char *)ptr) -#define WOLFCRYPT_BIO_set_mem_eof_return(bio, v) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_BUF_MEM_EOF_RETURN, v, NULL) - -#define WOLFCRYPT_BIO_get_buffer_num_lines(bio) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_GET_BUFF_NUM_LINES, 0, NULL) -#define WOLFCRYPT_BIO_set_buffer_size(bio, size) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_BUFF_SIZE, size, NULL) -#define WOLFCRYPT_BIO_set_read_buffer_size(bio, size) \ - WOLFCRYPT_BIO_int_ctrl(bio, BIO_C_SET_BUFF_SIZE, size, 0) -#define WOLFCRYPT_BIO_set_write_buffer_size(bio, size) \ - WOLFCRYPT_BIO_int_ctrl(bio, BIO_C_SET_BUFF_SIZE, size, 1) -#define WOLFCRYPT_BIO_set_buffer_read_data(bio, buf, num) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_BUFF_READ_DATA, num, buf) - -/* BIO filter cipher */ -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_f_cipher(void); -WOLFSSL_API void WOLFCRYPT_BIO_set_cipher(WOLFCRYPT_BIO *bio, - const WOLFSSL_EVP_CIPHER *cipher, - const unsigned char *key, - const unsigned char *iv, int enc); - -#define WOLFCRYPT_BIO_get_cipher_status(bio) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_GET_CIPHER_STATUS, 0, NULL) -#define WOLFCRYPT_BIO_get_cipher_ctx(bio, ctx) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_GET_CIPHER_CTX, 0, ctx) - -/* BIO filter base64 */ -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_f_base64(void); - -/* BIO filter digest */ -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_f_md(void); - -#define WOLFCRYPT_BIO_set_md(bio, md) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_MD, 0, (WOLFSSL_EVP_MD *)md) -#define WOLFCRYPT_BIO_get_md(bio,md) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_GET_MD, 0, (WOLFSSL_EVP_MD *)md) -#define WOLFCRYPT_BIO_get_md_ctx(bio,ctx) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_GET_MD_CTX, 0, (WOLFSSL_EVP_MD_CTX *)ctx) -#define WOLFCRYPT_BIO_set_md_ctx(bio, ctx) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_MD_CTX, 0, (WOLFSSL_EVP_MD_CTX *)ctx) - -/* BIO filter SSL */ -WOLFSSL_API WOLFCRYPT_BIO_METHOD *WOLFCRYPT_BIO_f_ssl(void); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_buffer_ssl_connect(WOLFSSL_CTX *ctx); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_ssl_connect(WOLFSSL_CTX *ctx); -WOLFSSL_API WOLFCRYPT_BIO *WOLFCRYPT_BIO_new_ssl(WOLFSSL_CTX *ctx, int client); -WOLFSSL_API void WOLFCRYPT_BIO_ssl_shutdown(WOLFCRYPT_BIO *bio); - -#define WOLFCRYPT_BIO_set_ssl(bio, ssl, mode) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_SET_SSL, mode, ssl) -#define WOLFCRYPT_BIO_get_ssl(bio, ssl) \ - WOLFCRYPT_BIO_ctrl(bio, BIO_C_GET_SSL, 0, ssl) - -/* BIO socket internal functions */ -int WOLFCRYPT_BIO_get_host_ip(const char *str, unsigned char *ip); -int WOLFCRYPT_BIO_get_port(const char *str, unsigned short *port_ptr); -int WOLFCRYPT_BIO_sock_error(int sock); -int WOLFCRYPT_BIO_sock_init(void); -void WOLFCRYPT_BIO_sock_cleanup(void); -int WOLFCRYPT_BIO_get_accept_socket(char *host, int bind_mode); -int WOLFCRYPT_BIO_accept(int sock, char **addr); -int WOLFCRYPT_BIO_set_tcp_ndelay(int s, int on); -int WOLFCRYPT_BIO_set_tcp_nsigpipe(int s, int on); -int WOLFCRYPT_BIO_socket_nbio(int s, int mode); #ifdef __cplusplus -} /* extern "C" */ + } /* extern "C" */ #endif -#endif /* OPENSSL_EXTRA */ -#endif /* WOLFCRYPT_BIO_H_ */ + +#endif /* WOLFSSL_BIO_H_ */ + diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 70f0f8842..77928acad 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -43,247 +43,88 @@ #include #include +#include #include #include #include #include -#ifdef __cplusplus - extern "C" { -#endif - -typedef char WOLFSSL_EVP_MD; -typedef char WOLFSSL_EVP_CIPHER; - -#ifndef NO_MD5 - WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void); -#endif -WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void); -WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void); -WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void); -WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void); -WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void); - -WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void); -WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void); -WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void); -WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ctr(void); -WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ctr(void); -WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ctr(void); -WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_cbc(void); -WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_des_ede3_cbc(void); -WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_rc4(void); -WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_idea_cbc(void); -WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_enc_null(void); - - -typedef union { - #ifndef NO_MD5 - WOLFSSL_MD5_CTX md5; - #endif - WOLFSSL_SHA_CTX sha; - WOLFSSL_SHA256_CTX sha256; - #ifdef WOLFSSL_SHA384 - WOLFSSL_SHA384_CTX sha384; - #endif - #ifdef WOLFSSL_SHA512 - WOLFSSL_SHA512_CTX sha512; - #endif - #ifdef WOLFSSL_RIPEMD - WOLFSSL_RIPEMD_CTX ripemd; - #endif -} WOLFSSL_Hasher; - - -typedef struct WOLFSSL_EVP_MD_CTX { - unsigned char macType; - int macSize; - const WOLFSSL_EVP_MD *digest; - WOLFSSL_Hasher hash; -} WOLFSSL_EVP_MD_CTX; - - -typedef union { -#ifndef NO_AES - Aes aes; -#endif -#ifndef NO_DES3 - Des des; - Des3 des3; -#endif - Arc4 arc4; -#ifdef HAVE_IDEA - Idea idea; -#endif -} WOLFSSL_Cipher; - - -enum { - AES_128_CBC_TYPE = 1, - AES_192_CBC_TYPE = 2, - AES_256_CBC_TYPE = 3, - AES_128_CTR_TYPE = 4, - AES_192_CTR_TYPE = 5, - AES_256_CTR_TYPE = 6, - DES_CBC_TYPE = 7, - DES_EDE3_CBC_TYPE = 8, - ARC4_TYPE = 9, - NULL_CIPHER_TYPE = 10, - EVP_PKEY_RSA = 11, - EVP_PKEY_DSA = 12, - EVP_PKEY_EC = 13, - IDEA_CBC_TYPE = 14, - NID_sha1 = 64, - NID_md2 = 3, - NID_md5 = 4 -}; - - -typedef struct WOLFSSL_EVP_CIPHER_CTX { - int keyLen; /* user may set for variable */ - int blockSize; - int bufLen; - unsigned char enc; /* if encrypt side, then true */ - unsigned char cipherType; - unsigned char final_used; - unsigned char ivUpdate; - unsigned char padding; - -#ifndef NO_AES - unsigned char iv[AES_BLOCK_SIZE]; /* working iv pointer into cipher */ - unsigned char buf[AES_BLOCK_SIZE]; - unsigned char final[AES_BLOCK_SIZE]; -#elif !defined(NO_DES3) - unsigned char iv[DES_BLOCK_SIZE]; /* working iv pointer into cipher */ - unsigned char buf[DES_BLOCK_SIZE]; - unsigned char final[DES_BLOCK_SIZE]; -#endif - WOLFSSL_Cipher cipher; -} WOLFSSL_EVP_CIPHER_CTX; - - -WOLFSSL_API int wolfSSL_EVP_MD_size(const WOLFSSL_EVP_MD* md); -WOLFSSL_API void wolfSSL_EVP_MD_CTX_init(WOLFSSL_EVP_MD_CTX* ctx); -WOLFSSL_API int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx); -WOLFSSL_API int wolfSSL_EVP_MD_CTX_copy(WOLFSSL_EVP_MD_CTX *out, - const WOLFSSL_EVP_MD_CTX *in); - -WOLFSSL_API int wolfSSL_EVP_DigestInit(WOLFSSL_EVP_MD_CTX* ctx, - const WOLFSSL_EVP_MD* type); -WOLFSSL_API int wolfSSL_EVP_DigestUpdate(WOLFSSL_EVP_MD_CTX* ctx, const void* data, - unsigned long sz); -WOLFSSL_API int wolfSSL_EVP_DigestFinal(WOLFSSL_EVP_MD_CTX* ctx, unsigned char* md, - unsigned int* s); -WOLFSSL_API int wolfSSL_EVP_DigestFinal_ex(WOLFSSL_EVP_MD_CTX* ctx, - unsigned char* md, unsigned int* s); -#ifndef NO_MD5 -WOLFSSL_API int wolfSSL_EVP_BytesToKey(const WOLFSSL_EVP_CIPHER*, - const WOLFSSL_EVP_MD*, const unsigned char*, - const unsigned char*, int, int, unsigned char*, - unsigned char*); -#endif - -WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_init(WOLFSSL_EVP_CIPHER_CTX* ctx); -WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_cleanup(WOLFSSL_EVP_CIPHER_CTX* ctx); - -WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX*); - - -WOLFSSL_API int wolfSSL_EVP_CipherInit(WOLFSSL_EVP_CIPHER_CTX* ctx, - const WOLFSSL_EVP_CIPHER* type, - unsigned char* key, unsigned char* iv, - int enc); -WOLFSSL_API int wolfSSL_EVP_CipherUpdate(WOLFSSL_EVP_CIPHER_CTX *ctx, - unsigned char *dst, int *dstLen, - const unsigned char *src, int len); -WOLFSSL_API int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, - unsigned char *dst, int *dstLen); - -WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx); -WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx, - int keylen); -WOLFSSL_API int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, - unsigned char* dst, unsigned char* src, - unsigned int len); - -WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_copy(WOLFSSL_EVP_CIPHER_CTX *out, - const WOLFSSL_EVP_CIPHER_CTX *in); - -WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_get_digestbynid(int); WOLFSSL_API WOLFSSL_RSA* wolfSSL_EVP_PKEY_get1_RSA(WOLFSSL_EVP_PKEY*); WOLFSSL_API WOLFSSL_DSA* wolfSSL_EVP_PKEY_get1_DSA(WOLFSSL_EVP_PKEY*); WOLFSSL_API WOLFSSL_EC_KEY *wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY *key); /* these next ones don't need real OpenSSL type, for OpenSSH compat only */ -WOLFSSL_API void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx); -WOLFSSL_API int wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx); - -WOLFSSL_API void wolfSSL_3des_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, +WOLFSSL_API void* wolfSSL_EVP_X_STATE(const WOLFCRYPT_EVP_CIPHER_CTX* ctx); +WOLFSSL_API int wolfSSL_EVP_X_STATE_LEN(const WOLFCRYPT_EVP_CIPHER_CTX* ctx); +WOLFSSL_API void wolfSSL_3des_iv(WOLFCRYPT_EVP_CIPHER_CTX* ctx, int doset, unsigned char* iv, int len); -WOLFSSL_API void wolfSSL_aes_ctr_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, int doset, +WOLFSSL_API void wolfSSL_aes_ctr_iv(WOLFCRYPT_EVP_CIPHER_CTX* ctx, int doset, unsigned char* iv, int len); - -WOLFSSL_API int wolfSSL_StoreExternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx); -WOLFSSL_API int wolfSSL_SetInternalIV(WOLFSSL_EVP_CIPHER_CTX* ctx); - - +WOLFSSL_API int wolfSSL_StoreExternalIV(WOLFCRYPT_EVP_CIPHER_CTX* ctx); +WOLFSSL_API int wolfSSL_SetInternalIV(WOLFCRYPT_EVP_CIPHER_CTX* ctx); /* end OpenSSH compat */ -typedef WOLFSSL_EVP_MD EVP_MD; -typedef WOLFSSL_EVP_CIPHER EVP_CIPHER; -typedef WOLFSSL_EVP_MD_CTX EVP_MD_CTX; -typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; -#ifndef NO_MD5 - #define EVP_md5 wolfSSL_EVP_md5 -#endif -#define EVP_sha1 wolfSSL_EVP_sha1 -#define EVP_sha256 wolfSSL_EVP_sha256 -#define EVP_sha384 wolfSSL_EVP_sha384 -#define EVP_sha512 wolfSSL_EVP_sha512 -#define EVP_ripemd160 wolfSSL_EVP_ripemd160 +/* OpenSSL compat */ +typedef WOLFCRYPT_EVP_MD EVP_MD; +typedef WOLFCRYPT_EVP_CIPHER EVP_CIPHER; +typedef WOLFCRYPT_EVP_MD_CTX EVP_MD_CTX; +typedef WOLFCRYPT_EVP_CIPHER_CTX EVP_CIPHER_CTX; +typedef WOLFCRYPT_Cipher Cipher; -#define EVP_aes_128_cbc wolfSSL_EVP_aes_128_cbc -#define EVP_aes_192_cbc wolfSSL_EVP_aes_192_cbc -#define EVP_aes_256_cbc wolfSSL_EVP_aes_256_cbc -#define EVP_aes_128_ctr wolfSSL_EVP_aes_128_ctr -#define EVP_aes_192_ctr wolfSSL_EVP_aes_192_ctr -#define EVP_aes_256_ctr wolfSSL_EVP_aes_256_ctr -#define EVP_des_cbc wolfSSL_EVP_des_cbc -#define EVP_des_ede3_cbc wolfSSL_EVP_des_ede3_cbc -#define EVP_rc4 wolfSSL_EVP_rc4 -#define EVP_idea_cbc wolfSSL_EVP_idea_cbc -#define EVP_enc_null wolfSSL_EVP_enc_null +#define EVP_md5 wc_EVP_md5 +#define EVP_sha1 wc_EVP_sha1 +#define EVP_sha256 wc_EVP_sha256 +#define EVP_sha384 wc_EVP_sha384 +#define EVP_sha512 wc_EVP_sha512 +#define EVP_ripemd160 wc_EVP_ripemd160 -#define EVP_MD_size wolfSSL_EVP_MD_size -#define EVP_MD_CTX_init wolfSSL_EVP_MD_CTX_init -#define EVP_MD_CTX_cleanup wolfSSL_EVP_MD_CTX_cleanup -#define EVP_DigestInit wolfSSL_EVP_DigestInit -#define EVP_DigestUpdate wolfSSL_EVP_DigestUpdate -#define EVP_DigestFinal wolfSSL_EVP_DigestFinal -#define EVP_DigestFinal_ex wolfSSL_EVP_DigestFinal_ex -#define EVP_BytesToKey wolfSSL_EVP_BytesToKey +#define EVP_aes_128_cbc wc_EVP_aes_128_cbc +#define EVP_aes_192_cbc wc_EVP_aes_192_cbc +#define EVP_aes_256_cbc wc_EVP_aes_256_cbc +#define EVP_aes_128_ctr wc_EVP_aes_128_ctr +#define EVP_aes_192_ctr wc_EVP_aes_192_ctr +#define EVP_aes_256_ctr wc_EVP_aes_256_ctr +#define EVP_des_cbc wc_EVP_des_cbc +#define EVP_des_ede3_cbc wc_EVP_des_ede3_cbc +#define EVP_rc4 wc_EVP_rc4 +#define EVP_idea_cbc wc_EVP_idea_cbc +#define EVP_enc_null wc_EVP_enc_null -#define EVP_CIPHER_CTX_init wolfSSL_EVP_CIPHER_CTX_init -#define EVP_CIPHER_CTX_cleanup wolfSSL_EVP_CIPHER_CTX_cleanup -#define EVP_CIPHER_CTX_iv_length wolfSSL_EVP_CIPHER_CTX_iv_length -#define EVP_CIPHER_CTX_key_length wolfSSL_EVP_CIPHER_CTX_key_length -#define EVP_CIPHER_CTX_set_key_length wolfSSL_EVP_CIPHER_CTX_set_key_length -#define EVP_CipherInit wolfSSL_EVP_CipherInit -#define EVP_Cipher wolfSSL_EVP_Cipher +#define EVP_MD_CTX_init wc_EVP_MD_CTX_init +#define EVP_MD_CTX_cleanup wc_EVP_MD_CTX_cleanup +#define EVP_MD_CTX_copy wc_EVP_MD_CTX_copy +#define EVP_MD_size wc_EVP_MD_size -#define EVP_get_digestbynid wolfSSL_EVP_get_digestbynid +#define EVP_DigestInit wc_EVP_DigestInit +#define EVP_DigestUpdate wc_EVP_DigestUpdate +#define EVP_DigestFinal wc_EVP_DigestFinal +#define EVP_DigestFinal_ex wc_EVP_DigestFinal_ex + +#define EVP_CIPHER_CTX_init wc_EVP_CIPHER_CTX_init +#define EVP_CIPHER_CTX_cleanup wc_EVP_CIPHER_CTX_cleanup +#define EVP_CIPHER_CTX_iv_length wc_EVP_CIPHER_CTX_iv_length +#define EVP_CIPHER_CTX_key_length wc_EVP_CIPHER_CTX_key_length +#define EVP_CIPHER_CTX_copy wc_EVP_CIPHER_CTX_copy +#define EVP_CIPHER_CTX_set_key_length wc_EVP_CIPHER_CTX_set_key_length + +#define EVP_CipherInit wc_EVP_CipherInit +#define EVP_CipherUpdate wc_EVP_CipherUpdate +#define EVP_CipherFinal wc_EVP_CipherFinal +#define EVP_Cipher wc_EVP_Cipher + +#define EVP_get_digestbynid wc_EVP_get_digestbynid #define EVP_PKEY_get1_RSA wolfSSL_EVP_PKEY_get1_RSA #define EVP_PKEY_get1_DSA wolfSSL_EVP_PKEY_get1_DSA #define EVP_PKEY_get1_EC_KEY wolfSSL_EVP_PKEY_get1_EC_KEY - -#ifndef EVP_MAX_MD_SIZE - #define EVP_MAX_MD_SIZE 64 /* sha512 */ +#ifndef NO_MD5 +#define EVP_BytesToKey wc_EVP_BytesToKey #endif + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/openssl/hmac.h b/wolfssl/openssl/hmac.h index 0dca8cb2b..39e90126a 100644 --- a/wolfssl/openssl/hmac.h +++ b/wolfssl/openssl/hmac.h @@ -34,44 +34,20 @@ #include "prefix_hmac.h" #endif -#include -#include +#include #ifdef __cplusplus extern "C" { #endif +typedef struct WOLFCRYPT_HMAC_CTX HMAC_CTX; -WOLFSSL_API unsigned char* wolfSSL_HMAC(const WOLFSSL_EVP_MD* evp_md, - const void* key, int key_len, - const unsigned char* d, int n, unsigned char* md, - unsigned int* md_len); - - -typedef struct WOLFSSL_HMAC_CTX { - Hmac hmac; - int type; -} WOLFSSL_HMAC_CTX; - - -WOLFSSL_API void wolfSSL_HMAC_Init(WOLFSSL_HMAC_CTX* ctx, const void* key, - int keylen, const EVP_MD* type); -WOLFSSL_API void wolfSSL_HMAC_Update(WOLFSSL_HMAC_CTX* ctx, - const unsigned char* data, int len); -WOLFSSL_API void wolfSSL_HMAC_Final(WOLFSSL_HMAC_CTX* ctx, unsigned char* hash, - unsigned int* len); -WOLFSSL_API void wolfSSL_HMAC_cleanup(WOLFSSL_HMAC_CTX* ctx); - - -typedef struct WOLFSSL_HMAC_CTX HMAC_CTX; - -#define HMAC(a,b,c,d,e,f,g) wolfSSL_HMAC((a),(b),(c),(d),(e),(f),(g)) - -#define HMAC_Init wolfSSL_HMAC_Init -#define HMAC_Update wolfSSL_HMAC_Update -#define HMAC_Final wolfSSL_HMAC_Final -#define HMAC_cleanup wolfSSL_HMAC_cleanup +#define HMAC(a,b,c,d,e,f,g) wc_HMAC((a),(b),(c),(d),(e),(f),(g)) +#define HMAC_Init wc_HMAC_Init +#define HMAC_Update wc_HMAC_Update +#define HMAC_Final wc_HMAC_Final +#define HMAC_cleanup wc_HMAC_cleanup #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/openssl/md5.h b/wolfssl/openssl/md5.h index bdcda5b98..5d3d2ed5c 100644 --- a/wolfssl/openssl/md5.h +++ b/wolfssl/openssl/md5.h @@ -12,31 +12,23 @@ #include "prefix_md5.h" #endif +#include + #ifdef __cplusplus extern "C" { #endif +typedef WOLFCRYPT_MD5_CTX WOLFSSL_MD5_CTX; +typedef WOLFCRYPT_MD5_CTX MD5_CTX; -typedef struct WOLFSSL_MD5_CTX { - int holder[24]; /* big enough to hold wolfcrypt md5, but check on init */ -} WOLFSSL_MD5_CTX; - -WOLFSSL_API void wolfSSL_MD5_Init(WOLFSSL_MD5_CTX*); -WOLFSSL_API void wolfSSL_MD5_Update(WOLFSSL_MD5_CTX*, const void*, unsigned long); -WOLFSSL_API void wolfSSL_MD5_Final(unsigned char*, WOLFSSL_MD5_CTX*); - - -typedef WOLFSSL_MD5_CTX MD5_CTX; - -#define MD5_Init wolfSSL_MD5_Init -#define MD5_Update wolfSSL_MD5_Update -#define MD5_Final wolfSSL_MD5_Final +#define MD5_Init wc_MD5_Init +#define MD5_Update wc_MD5_Update +#define MD5_Final wc_MD5_Final #ifdef __cplusplus - } /* extern "C" */ + } /* extern "C" */ #endif #endif /* NO_MD5 */ #endif /* WOLFSSL_MD5_H_ */ - diff --git a/wolfssl/openssl/pem.h b/wolfssl/openssl/pem.h index 76a391f54..7831d2fb5 100644 --- a/wolfssl/openssl/pem.h +++ b/wolfssl/openssl/pem.h @@ -4,7 +4,7 @@ #ifndef WOLFSSL_PEM_H_ #define WOLFSSL_PEM_H_ -#include +#include #include #include #include @@ -16,18 +16,19 @@ /* RSA */ WOLFSSL_API -int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, - const EVP_CIPHER* cipher, +int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFCRYPT_BIO* bio, WOLFSSL_RSA* rsa, + const WOLFCRYPT_EVP_CIPHER* cipher, unsigned char* passwd, int len, pem_password_cb cb, void* arg); WOLFSSL_API -int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, +int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, + const WOLFCRYPT_EVP_CIPHER* cipher, unsigned char* passwd, int len, unsigned char **pem, int *plen); #if !defined(NO_FILESYSTEM) WOLFSSL_API int wolfSSL_PEM_write_RSAPrivateKey(FILE *fp, WOLFSSL_RSA *rsa, - const EVP_CIPHER *enc, + const WOLFCRYPT_EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); WOLFSSL_API @@ -42,20 +43,20 @@ int wolfSSL_PEM_write_RSA_PUBKEY(FILE *fp, WOLFSSL_RSA *x); /* DSA */ WOLFSSL_API -int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFSSL_BIO* bio, +int wolfSSL_PEM_write_bio_DSAPrivateKey(WOLFCRYPT_BIO* bio, WOLFSSL_DSA* dsa, - const EVP_CIPHER* cipher, + const WOLFCRYPT_EVP_CIPHER* cipher, unsigned char* passwd, int len, pem_password_cb cb, void* arg); WOLFSSL_API int wolfSSL_PEM_write_mem_DSAPrivateKey(WOLFSSL_DSA* dsa, - const EVP_CIPHER* cipher, + const WOLFCRYPT_EVP_CIPHER* cipher, unsigned char* passwd, int len, unsigned char **pem, int *plen); #if !defined(NO_FILESYSTEM) WOLFSSL_API int wolfSSL_PEM_write_DSAPrivateKey(FILE *fp, WOLFSSL_DSA *dsa, - const EVP_CIPHER *enc, + const WOLFCRYPT_EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); WOLFSSL_API @@ -64,19 +65,19 @@ int wolfSSL_PEM_write_DSA_PUBKEY(FILE *fp, WOLFSSL_DSA *x); /* ECC */ WOLFSSL_API -int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EC_KEY* ec, - const EVP_CIPHER* cipher, +int wolfSSL_PEM_write_bio_ECPrivateKey(WOLFCRYPT_BIO* bio, WOLFSSL_EC_KEY* ec, + const WOLFCRYPT_EVP_CIPHER* cipher, unsigned char* passwd, int len, pem_password_cb cb, void* arg); WOLFSSL_API int wolfSSL_PEM_write_mem_ECPrivateKey(WOLFSSL_EC_KEY* key, - const EVP_CIPHER* cipher, + const WOLFCRYPT_EVP_CIPHER* cipher, unsigned char* passwd, int len, unsigned char **pem, int *plen); #if !defined(NO_FILESYSTEM) WOLFSSL_API int wolfSSL_PEM_write_ECPrivateKey(FILE *fp, WOLFSSL_EC_KEY *key, - const EVP_CIPHER *enc, + const WOLFCRYPT_EVP_CIPHER *enc, unsigned char *kstr, int klen, pem_password_cb *cb, void *u); WOLFSSL_API @@ -85,7 +86,7 @@ int wolfSSL_PEM_write_EC_PUBKEY(FILE *fp, WOLFSSL_EC_KEY *key); /* EVP_KEY */ WOLFSSL_API -WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio, +WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFCRYPT_BIO* bio, WOLFSSL_EVP_PKEY**, pem_password_cb cb, void* arg); diff --git a/wolfssl/openssl/ripemd.h b/wolfssl/openssl/ripemd.h index ef1578e91..585b6e651 100644 --- a/wolfssl/openssl/ripemd.h +++ b/wolfssl/openssl/ripemd.h @@ -10,23 +10,15 @@ extern "C" { #endif +#ifdef WOLFSSL_RIPEMD -typedef struct WOLFSSL_RIPEMD_CTX { - int holder[32]; /* big enough to hold wolfcrypt, but check on init */ -} WOLFSSL_RIPEMD_CTX; - -WOLFSSL_API void wolfSSL_RIPEMD_Init(WOLFSSL_RIPEMD_CTX*); -WOLFSSL_API void wolfSSL_RIPEMD_Update(WOLFSSL_RIPEMD_CTX*, const void*, - unsigned long); -WOLFSSL_API void wolfSSL_RIPEMD_Final(unsigned char*, WOLFSSL_RIPEMD_CTX*); - - -typedef WOLFSSL_RIPEMD_CTX RIPEMD_CTX; - -#define RIPEMD_Init wolfSSL_RIPEMD_Init -#define RIPEMD_Update wolfSSL_RIPEMD_Update -#define RIPEMD_Final wolfSSL_RIPEMD_Final +typedef WOLCRYPT_RIPEMD_CTX RIPEMD_CTX; +#define RIPEMD_Init wc_RIPEMD_Init +#define RIPEMD_Update wc_RIPEMD_Update +#define RIPEMD_Final wc_RIPEMD_Final + +#endif /* WOLFSSL_RIPEMD */ #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/openssl/sha.h b/wolfssl/openssl/sha.h index 7f8b0ebd6..d98c41562 100644 --- a/wolfssl/openssl/sha.h +++ b/wolfssl/openssl/sha.h @@ -10,116 +10,48 @@ #include "prefix_sha.h" #endif +#include + #ifdef __cplusplus extern "C" { #endif +typedef WOLFCRYPT_SHA_CTX SHA_CTX; -typedef struct WOLFSSL_SHA_CTX { - int holder[24]; /* big enough to hold wolfcrypt sha, but check on init */ -} WOLFSSL_SHA_CTX; +#define SHA_Init wc_SHA_Init +#define SHA_Update wc_SHA_Update +#define SHA_Final wc_SHA_Final -WOLFSSL_API void wolfSSL_SHA_Init(WOLFSSL_SHA_CTX*); -WOLFSSL_API void wolfSSL_SHA_Update(WOLFSSL_SHA_CTX*, const void*, unsigned long); -WOLFSSL_API void wolfSSL_SHA_Final(unsigned char*, WOLFSSL_SHA_CTX*); +#define SHA1_Init wc_SHA1_Init +#define SHA1_Update wc_SHA1_Update +#define SHA1_Final wc_SHA1_Final -/* SHA1 points to above, shouldn't use SHA0 ever */ -WOLFSSL_API void wolfSSL_SHA1_Init(WOLFSSL_SHA_CTX*); -WOLFSSL_API void wolfSSL_SHA1_Update(WOLFSSL_SHA_CTX*, const void*, unsigned long); -WOLFSSL_API void wolfSSL_SHA1_Final(unsigned char*, WOLFSSL_SHA_CTX*); +typedef WOLFCRYPT_SHA256_CTX SHA256_CTX; -enum { - SHA_DIGEST_LENGTH = 20 -}; - - -typedef WOLFSSL_SHA_CTX SHA_CTX; - -#define SHA_Init wolfSSL_SHA_Init -#define SHA_Update wolfSSL_SHA_Update -#define SHA_Final wolfSSL_SHA_Final - -#define SHA1_Init wolfSSL_SHA1_Init -#define SHA1_Update wolfSSL_SHA1_Update -#define SHA1_Final wolfSSL_SHA1_Final - - -typedef struct WOLFSSL_SHA256_CTX { - int holder[28]; /* big enough to hold wolfcrypt sha, but check on init */ -} WOLFSSL_SHA256_CTX; - -WOLFSSL_API void wolfSSL_SHA256_Init(WOLFSSL_SHA256_CTX*); -WOLFSSL_API void wolfSSL_SHA256_Update(WOLFSSL_SHA256_CTX*, const void*, - unsigned long); -WOLFSSL_API void wolfSSL_SHA256_Final(unsigned char*, WOLFSSL_SHA256_CTX*); - -enum { - SHA256_DIGEST_LENGTH = 32 -}; - - -typedef WOLFSSL_SHA256_CTX SHA256_CTX; - -#define SHA256_Init wolfSSL_SHA256_Init -#define SHA256_Update wolfSSL_SHA256_Update -#define SHA256_Final wolfSSL_SHA256_Final +#define SHA256_Init wc_SHA256_Init +#define SHA256_Update wc_SHA256_Update +#define SHA256_Final wc_SHA256_Final #ifdef WOLFSSL_SHA384 +typedef WOLFCRYPT_SHA384_CTX SHA384_CTX; -typedef struct WOLFSSL_SHA384_CTX { - long long holder[32]; /* big enough, but check on init */ -} WOLFSSL_SHA384_CTX; - -WOLFSSL_API void wolfSSL_SHA384_Init(WOLFSSL_SHA384_CTX*); -WOLFSSL_API void wolfSSL_SHA384_Update(WOLFSSL_SHA384_CTX*, const void*, - unsigned long); -WOLFSSL_API void wolfSSL_SHA384_Final(unsigned char*, WOLFSSL_SHA384_CTX*); - -enum { - SHA384_DIGEST_LENGTH = 48 -}; - - -typedef WOLFSSL_SHA384_CTX SHA384_CTX; - -#define SHA384_Init wolfSSL_SHA384_Init -#define SHA384_Update wolfSSL_SHA384_Update -#define SHA384_Final wolfSSL_SHA384_Final - +#define SHA384_Init wc_SHA384_Init +#define SHA384_Update wc_SHA384_Update +#define SHA384_Final wc_SHA384_Final #endif /* WOLFSSL_SHA384 */ #ifdef WOLFSSL_SHA512 +typedef WOLFCRYPT_SHA512_CTX SHA512_CTX; -typedef struct WOLFSSL_SHA512_CTX { - long long holder[36]; /* big enough, but check on init */ -} WOLFSSL_SHA512_CTX; - -WOLFSSL_API void wolfSSL_SHA512_Init(WOLFSSL_SHA512_CTX*); -WOLFSSL_API void wolfSSL_SHA512_Update(WOLFSSL_SHA512_CTX*, const void*, - unsigned long); -WOLFSSL_API void wolfSSL_SHA512_Final(unsigned char*, WOLFSSL_SHA512_CTX*); - -enum { - SHA512_DIGEST_LENGTH = 64 -}; - - -typedef WOLFSSL_SHA512_CTX SHA512_CTX; - -#define SHA512_Init wolfSSL_SHA512_Init -#define SHA512_Update wolfSSL_SHA512_Update -#define SHA512_Final wolfSSL_SHA512_Final - +#define SHA512_Init wc_SHA512_Init +#define SHA512_Update wc_SHA512_Update +#define SHA512_Final wc_SHA512_Final #endif /* WOLFSSL_SHA512 */ - - - #ifdef __cplusplus - } /* extern "C" */ + } /* extern "C" */ #endif #endif /* WOLFSSL_SHA_H_ */ - diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 27fec0890..36edaf598 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -54,7 +54,6 @@ typedef WOLFSSL_X509_CHAIN X509_CHAIN; /* redeclare guard */ #define WOLFSSL_TYPES_DEFINED - typedef WOLFSSL_EVP_PKEY EVP_PKEY; typedef WOLFSSL_RSA RSA; typedef WOLFSSL_DSA DSA; @@ -62,8 +61,8 @@ typedef WOLFSSL_EC_KEY EC_KEY; typedef WOLFSSL_EC_GROUP EC_GROUP; typedef WOLFSSL_EC_POINT EC_POINT; typedef WOLFSSL_ECDSA_SIG ECDSA_SIG; -typedef WOLFSSL_BIO BIO; -typedef WOLFSSL_BIO_METHOD BIO_METHOD; +typedef WOLFCRYPT_BIO BIO; +typedef WOLFCRYPT_BIO_METHOD BIO_METHOD; typedef WOLFSSL_CIPHER SSL_CIPHER; typedef WOLFSSL_X509_LOOKUP X509_LOOKUP; typedef WOLFSSL_X509_LOOKUP_METHOD X509_LOOKUP_METHOD; @@ -201,31 +200,6 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define MD4_Update wolfSSL_MD4_Update #define MD4_Final wolfSSL_MD4_Final -#define BIO_new wolfSSL_BIO_new -#define BIO_free wolfSSL_BIO_free -#define BIO_free_all wolfSSL_BIO_free_all -#define BIO_read wolfSSL_BIO_read -#define BIO_write wolfSSL_BIO_write -#define BIO_push wolfSSL_BIO_push -#define BIO_pop wolfSSL_BIO_pop -#define BIO_flush wolfSSL_BIO_flush -#define BIO_pending wolfSSL_BIO_pending - -#define BIO_get_mem_data wolfSSL_BIO_get_mem_data -#define BIO_new_mem_buf wolfSSL_BIO_new_mem_buf - -#define BIO_f_buffer wolfSSL_BIO_f_buffer -#define BIO_set_write_buffer_size wolfSSL_BIO_set_write_buffer_size -#define BIO_f_ssl wolfSSL_BIO_f_ssl -#define BIO_new_socket wolfSSL_BIO_new_socket -#define SSL_set_bio wolfSSL_set_bio -#define BIO_eof wolfSSL_BIO_eof -#define BIO_set_ss wolfSSL_BIO_set_ss - -#define BIO_s_mem wolfSSL_BIO_s_mem -#define BIO_f_base64 wolfSSL_BIO_f_base64 -#define BIO_set_flags wolfSSL_BIO_set_flags - #define OpenSSL_add_all_algorithms wolfSSL_add_all_algorithms #define SSLeay_add_ssl_algorithms wolfSSL_add_all_algorithms #define SSLeay_add_all_algorithms wolfSSL_add_all_algorithms @@ -379,7 +353,6 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define SSL_want_read wolfSSL_want_read #define SSL_want_write wolfSSL_want_write -#define BIO_prf wolfSSL_BIO_prf #define ASN1_UTCTIME_pr wolfSSL_ASN1_UTCTIME_pr #define sk_num wolfSSL_sk_num @@ -502,6 +475,198 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; #endif /* HAVE_STUNNEL */ +#ifdef OPENSSL_EXTRA + +#define BIO_method_name wc_BioMethodName +#define BIO_method_type wc_BioMethodType + +#define BIO_clear_flags wc_BioClearFlags +#define BIO_set_flags wc_BioSetFlags +#define BIO_test_flags wc_BioTestFlags + +#define BIO_get_flags wc_BioGetFlags +#define BIO_set_retry_special wc_BioSetRetrySpecial +#define BIO_set_retry_read wc_BioSetRetryRead +#define BIO_set_retry_write wc_BioSetRetryWrite + +#define BIO_clear_retry_flags wc_BioClearRetryFlags +#define BIO_get_retry_flags wc_BioGetRetryFlags + +#define BIO_should_read wc_BioShouldRead +#define BIO_should_write wc_BioShouldWrite +#define BIO_should_io_special wc_BioShouldIoSpecial +#define BIO_retry_type wc_BioRetryType +#define BIO_should_retry_type wc_BioShouldRetry + +#define BIO_get_callback wc_BioGetCallback +#define BIO_set_callback wc_BioSetCallback +#define BIO_get_callback_arg wc_BioSetCallbackArg +#define BIO_set_callback_arg wc_BioGetCallbackArg + +#define BIO_new wc_BioNew +#define BIO_free wc_BioFree +#define BIO_vfree wc_BioFree +#define BIO_free_all wc_BioFreeAll +#define BIO_set wc_BioSet +#define BIO_read wc_BioRead +#define BIO_wrie wc_BioWrite +#define BIO_puts wc_BioPuts +#define BIO_gets wc_BioGets +#define BIO_indent wc_BioIndent +#define BIO_ctrl wc_BioCtrl +#define BIO_callback_ctrl wc_BioCallbackCtrl +#define BIO_push wc_BioPush +#define BIO_pop wc_BioPop +#define BIO_next wc_BioNext +#define BIO_find_type wc_BioFindType +#define BIO_dup_chain wc_BioDupChain +#define BIO_dup_state wc_BioDupState + +#define BIO_get_retry_BIO wc_BioGetRetryBio +#define BIO_get_retry_reason wc_BioGetRetryReason + +#define BIO_int_ctrl wc_BioIntCtrl +#define BIO_ptr_ctrl wc_BioPtrCtrl +#define BIO_ctrl_pending wc_BioCtrlPending +#define BIO_ctrl_wpending wc_BioCtrlWpending + +#define BIO_number_read wc_BioNumberRead +#define BIO_number_written wc_BioNumberWritten + +#define BIO_reset wc_BioReset +#define BIO_eof wc_BioEof +#define BIO_set_close wc_BioSetClose +#define BIO_get_close wc_BioGetClose +#define BIO_pending wc_BioPending +#define BIO_wpending wc_BioWpending +#define BIO_flush wc_BioFlush + +#define BIO_set_info_callback wc_BioSetInfoCallback +#define BIO_get_info_callback wc_BioGetInfoCallback + +#define BIO_copy_next_retry wc_BioCopyNextRetry +#define BIO_printf wc_BioPrintf + +/* BIO file */ +#define BIO_s_file wc_Bio_s_file +#define BIO_new_fp wc_BioNewFp +#define BIO_new_file wc_BioNewFile +#define BIO_set_fp wc_BioSetFp +#define BIO_get_fp wc_BioGetFp +#define BIO_seek wc_BioSeek +#define BIO_tell wc_BioTell +#define BIO_read_filename wc_BioReadFilename +#define BIO_write_filename wc_BioWriteFilename +#define BIO_append_filename wc_BioAppendFilename +#define BIO_rw_filename wc_BioRwFilename + +/* BIO memory */ +#define BIO_s_mem wc_Bio_s_mem +#define BIO_new_mem_buf wc_BioNewMemBuf + +/* BIO fd */ +#define BIO_s_fd wc_Bio_s_fd +#define BIO_new_fd wc_BioNewFd + +/* BIO null */ +#define BIO_s_null wc_Bio_s_null + +/* BIO socket */ +#define BIO_s_socket wc_Bio_s_socket +#define BIO_new_socket wc_BioNewSocket +#define BIO_sock_should_retry wc_BioSockShouldRetry +#define BIO_sock_non_fatal_error wc_BioSockNonFatalError +#define BIO_set_fd wc_BioSetFd +#define BIO_get_fd wc_BioGetFd + +/* BIO connect */ +#define BIO_s_connect wc_Bio_s_connect +#define BIO_new_connect wc_BioNewConnect +#define BIO_set_conn_hostname wc_BioSetConnHostname +#define BIO_set_conn_port wc_BioSetConnPort +#define BIO_set_conn_ip wc_BioSetConnIp(bio, ip) +#define BIO_set_conn_int_port wc_BioSetConnIntPort +#define BIO_get_conn_hostname wc_BioGetConnHostname +#define BIO_get_conn_port wc_BioGetConnPort +#define BIO_get_conn_ip wc_BioGetConnIp +#define BIO_get_conn_int_port wc_BioGetConnIntPort +#define BIO_set_nbio wc_BioSetNbio +#define BIO_do_handshake wc_BioDoHandshake +#define BIO_do_connect wc_BioDoConnect +#define BIO_do_accept wc_BioDoAccept + +/* BIO accept */ +#define BIO_s_accept wc_Bio_s_accept +#define BIO_new_accept wc_BioNewAccept +#define BIO_set_accept_port wc_BioSetAcceptPort +#define BIO_get_accept_port wc_BioGetAcceptPort +#define BIO_set_nbio_accept wc_BioSetNbioAccept +#define BIO_set_accept_bios wc_BioSetAcceptBios +#define BIO_set_bind_mode wc_BioSetBindMode +#define BIO_get_bind_mode wc_BioGetBindMode + +/* BIO datagram */ +#define BIO_s_datagram wc_Bio_s_datagram +#define BIO_new_dgram wc_BioNewDgram + +/* BIO filter buffer */ +#define BIO_f_buffer wc_Bio_f_buffer +#define BIO_get_mem_data wc_BioGetMemData +#define BIO_set_mem_buf wc_BioSetMemBuf +#define BIO_get_mem_ptr wc_BioGetMemPtr +#define BIO_set_mem_eof_return wc_BioSetMemEofReturn +#define BIO_get_buffer_num_lines wc_BioGetBufferNumLines +#define BIO_set_buffer_size wc_BioSetBufferSize +#define BIO_set_read_buffer_size wc_BioSetReadBufferSize +#define BIO_set_write_buffer_size wc_BioSetWriteBufferSize +#define BIO_set_buffer_read_data wc_BioSetBufferReadData + +/* BIO filter cipher */ +#define BIO_f_cipher wc_Bio_f_cipher +#define BIO_set_cipher wc_BioSetCipher +#define BIO_get_cipher_status wc_BioGetCipherStatus +#define BIO_get_cipher_ctx wc_BioGetCipherCtx + +/* BIO filter base64 */ +#define BIO_f_base64 wc_Bio_f_base64 + +/* BIO filter digest */ +#define BIO_f_md wc_Bio_f_md +#define BIO_set_md wc_BioSetMd +#define BIO_get_md wc_BioGetMd +#define BIO_get_md_ctx wc_BioGetmdCtx +#define BIO_set_md_ctx wc_BioSetMdCtx + +/* BIO filter SSL */ +WOLFSSL_API WOLFCRYPT_BIO *wolfSSL_BioNewBufferSSLConnect(WOLFSSL_CTX *ctx); +WOLFSSL_API WOLFCRYPT_BIO *wolfSSL_BioNewSSLConnect(WOLFSSL_CTX *ctx); +WOLFSSL_API WOLFCRYPT_BIO *wolfSSL_BioNewSSL(WOLFSSL_CTX *ctx, int client); + +#define BIO_f_ssl wc_Bio_f_ssl +#define BIO_new_buffer_ssl_connect wolfSSL_BioNewBufferSSLConnect +#define BIO_new_ssl_connect wolfSSL_BioNewSSLConnect +#define BIO_new_ssl wolfSSL_BioNewSSL +#define BIO_ssl_shutdown wc_BioSSLShutdown +#define BIO_set_ssl wc_BioSetSSL +#define BIO_get_ssl wc_BioGetSSL +#define BIO_set_ssl_mode wc_BIOSetSSLMode +#define BIO_set_ssl_renegotiate_bytes wc_BIOSetSSLRenegotiateBytes +#define BIO_get_num_renegotiates wc_BIOGetNumRenegotiates +#define BIO_set_ssl_renegotiate_timeout wc_BIOSetSSLRenegotiateTimeout + +/* BIO socket internal functions */ +#define BIO_get_host_ip wc_BioGetHostIp +#define BIO_get_port wc_BioGetPort +#define BIO_sock_error wc_BioSockError +#define BIO_sock_init wc_BioSockInit +#define BIO_sock_cleanup wc_BioSockCleanup +#define BIO_get_accept_socket wc_BioGetAcceptSocket +#define BIO_accept wc_BioAccept +#define BIO_set_tcp_ndelay wc_BioSetTcpNdelay +#define BIO_socket_nbio wc_BioSocketNbio + +#endif /* OPENSSL_EXTRA */ + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 05c76048d..ef626af63 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -92,8 +92,8 @@ typedef struct WOLFSSL_CIPHER WOLFSSL_CIPHER; typedef struct WOLFSSL_X509_LOOKUP WOLFSSL_X509_LOOKUP; typedef struct WOLFSSL_X509_LOOKUP_METHOD WOLFSSL_X509_LOOKUP_METHOD; typedef struct WOLFSSL_X509_CRL WOLFSSL_X509_CRL; -typedef struct WOLFCRYPT_BIO WOLFSSL_BIO; -typedef struct WOLFCRYPT_BIO_METHOD WOLFSSL_BIO_METHOD; +typedef struct WOLFCRYPT_BIO WOLFCRYPT_BIO; +typedef struct WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_METHOD; typedef struct WOLFSSL_X509_EXTENSION WOLFSSL_X509_EXTENSION; typedef struct WOLFSSL_ASN1_TIME WOLFSSL_ASN1_TIME; typedef struct WOLFSSL_ASN1_INTEGER WOLFSSL_ASN1_INTEGER; @@ -395,34 +395,6 @@ WOLFSSL_API void wolfSSL_MD4_Init(WOLFSSL_MD4_CTX*); WOLFSSL_API void wolfSSL_MD4_Update(WOLFSSL_MD4_CTX*, const void*, unsigned long); WOLFSSL_API void wolfSSL_MD4_Final(unsigned char*, WOLFSSL_MD4_CTX*); -/* -WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD*); -WOLFSSL_API int wolfSSL_BIO_free(WOLFSSL_BIO*); -WOLFSSL_API int wolfSSL_BIO_free_all(WOLFSSL_BIO*); -WOLFSSL_API int wolfSSL_BIO_read(WOLFSSL_BIO*, void*, int); -WOLFSSL_API int wolfSSL_BIO_write(WOLFSSL_BIO*, const void*, int); -WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_push(WOLFSSL_BIO*, WOLFSSL_BIO* append); -WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_pop(WOLFSSL_BIO*); -WOLFSSL_API int wolfSSL_BIO_flush(WOLFSSL_BIO*); -WOLFSSL_API int wolfSSL_BIO_pending(WOLFSSL_BIO*); - -WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void); -WOLFSSL_API long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO*, long size); -WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void); -WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_socket(int sfd, int flag); -WOLFSSL_API int wolfSSL_BIO_eof(WOLFSSL_BIO*); - -WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_s_mem(void); -WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_base64(void); -WOLFSSL_API void wolfSSL_BIO_set_flags(WOLFSSL_BIO*, int); - -WOLFSSL_API int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio,const unsigned char** p); -WOLFSSL_API WOLFSSL_BIO* wolfSSL_BIO_new_mem_buf(void* buf, int len); - - -WOLFSSL_API long wolfSSL_BIO_set_ssl(WOLFSSL_BIO*, WOLFSSL*, int flag); -*/ - WOLFSSL_API int wolfSSL_add_all_algorithms(void); WOLFSSL_API void wolfSSL_RAND_screen(void); @@ -514,7 +486,7 @@ WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value( WOLFSSL_X509_REVOKED*,int); WOLFSSL_API WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509*); -WOLFSSL_API int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO*, const WOLFSSL_ASN1_TIME*); +WOLFSSL_API int wolfSSL_ASN1_TIME_print(WOLFCRYPT_BIO*, const WOLFSSL_ASN1_TIME*); WOLFSSL_API int wolfSSL_ASN1_INTEGER_cmp(const WOLFSSL_ASN1_INTEGER*, const WOLFSSL_ASN1_INTEGER*); @@ -799,7 +771,7 @@ WOLFSSL_API WOLFSSL_X509* wolfSSL_get_peer_certificate(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_want_read(WOLFSSL*); WOLFSSL_API int wolfSSL_want_write(WOLFSSL*); -WOLFSSL_API int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO*, +WOLFSSL_API int wolfSSL_ASN1_UTCTIME_print(WOLFCRYPT_BIO*, const WOLFSSL_ASN1_UTCTIME*); WOLFSSL_API int wolfSSL_sk_num(WOLFSSL_X509_REVOKED*); WOLFSSL_API void* wolfSSL_sk_value(WOLFSSL_X509_REVOKED*, int); @@ -1629,7 +1601,7 @@ WOLFSSL_API int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *p WOLFSSL_API const char * wolf_OBJ_nid2sn(int n); WOLFSSL_API int wolf_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o); WOLFSSL_API int wolf_OBJ_sn2nid(const char *sn); -WOLFSSL_API WOLFSSL_X509 *PEM_read_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); +WOLFSSL_API WOLFSSL_X509 *PEM_read_bio_WOLFSSL_X509(WOLFCRYPT_BIO *bp, WOLFSSL_X509 **x, pem_password_cb *cb, void *u); WOLFSSL_API void wolfSSL_CTX_set_verify_depth(WOLFSSL_CTX *ctx,int depth); WOLFSSL_API void* wolfSSL_get_app_data( const WOLFSSL *ssl); WOLFSSL_API void wolfSSL_set_app_data(WOLFSSL *ssl, void *arg); @@ -1649,9 +1621,9 @@ WOLFSSL_API STACK_OF(WOLFSSL_X509_NAME) *wolfSSL_dup_CA_list( STACK_OF(WOLFSSL_X WOLFSSL_API char * wolf_OBJ_nid2ln(int n); WOLFSSL_API int wolf_OBJ_txt2nid(const char *sn); WOLFSSL_API long wolfSSL_CTX_set_tmp_dh(WOLFSSL_CTX*, WOLFSSL_DH*); -WOLFSSL_API WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFSSL_BIO *bp, +WOLFSSL_API WOLFSSL_DH *wolfSSL_PEM_read_bio_DHparams(WOLFCRYPT_BIO *bp, WOLFSSL_DH **x, pem_password_cb *cb, void *u); -WOLFSSL_API int PEM_write_bio_WOLFSSL_X509(WOLFSSL_BIO *bp, WOLFSSL_X509 *x); +WOLFSSL_API int PEM_write_bio_WOLFSSL_X509(WOLFCRYPT_BIO *bp, WOLFSSL_X509 *x); #endif /* HAVE_STUNNEL || HAVE_LIGHTY */ @@ -1689,7 +1661,7 @@ WOLFSSL_API int wolfSSL_sk_X509_NAME_num(const STACK_OF(WOLFSSL_X509_NAME) *s); WOLFSSL_API int wolfSSL_sk_X509_num(const STACK_OF(WOLFSSL_X509) *s); -WOLFSSL_API int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO*,WOLFSSL_X509_NAME*,int, +WOLFSSL_API int wolfSSL_X509_NAME_print_ex(WOLFCRYPT_BIO*,WOLFSSL_X509_NAME*,int, unsigned long); WOLFSSL_API WOLFSSL_ASN1_BIT_STRING* wolfSSL_X509_get0_pubkey_bitstr( diff --git a/wolfssl/wolfcrypt/bio.h b/wolfssl/wolfcrypt/bio.h new file mode 100644 index 000000000..73ad9772e --- /dev/null +++ b/wolfssl/wolfcrypt/bio.h @@ -0,0 +1,563 @@ +#ifndef WOLF_CRYPT_BIO_H +#define WOLF_CRYPT_BIO_H + +#include +#include +#include +#include + +#ifdef OPENSSL_EXTRA + +#ifdef __cplusplus +extern "C" { +#endif + +/* BIO types */ +enum WS_BIO_TYPE { + BIO_TYPE_NONE = 0, + + BIO_TYPE_SSL = 1, + BIO_TYPE_MD = 2, /* passive */ + BIO_TYPE_BUFFER = 3, + BIO_TYPE_CIPHER = 4, + BIO_TYPE_BASE64 = 5, + BIO_TYPE_LINEBUFFER = 6, + BIO_TYPE_ASN1 = 7, + BIO_TYPE_COMP = 8, + BIO_TYPE_PROXY_CLIENT = 9, /* client proxy BIO */ + BIO_TYPE_PROXY_SERVER = 10, /* server proxy BIO */ + BIO_TYPE_NULL_FILTER = 11, + BIO_TYPE_BER = 12, /* BER -> bin filter */ + + BIO_TYPE_MEM = 13, + BIO_TYPE_FILE = 14, + BIO_TYPE_NULL = 15, + BIO_TYPE_BIO = 16, /* (half a) BIO pair */ + + /* socket, fd, connect or accept */ + BIO_TYPE_DESCRIPTOR = 0x100, + + BIO_TYPE_FD = 17|BIO_TYPE_DESCRIPTOR, + BIO_TYPE_SOCKET = 18|BIO_TYPE_DESCRIPTOR, + /* socket - connect */ + BIO_TYPE_CONNECT = 19|BIO_TYPE_DESCRIPTOR, + /* socket for accept */ + BIO_TYPE_ACCEPT = 20|BIO_TYPE_DESCRIPTOR, + BIO_TYPE_DGRAM = 21|BIO_TYPE_DESCRIPTOR, +}; + +/* + * BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + * BIO_set_fp(in,stdin,BIO_NOCLOSE); + */ +#if !defined(BIO_CLOSE) || !defined(BIO_NOCLOSE) +#define BIO_CLOSE 1 +#define BIO_NOCLOSE 0 +#endif + +/* + * These are used in the following macros and are passed to BIO_ctrl() + */ +enum WS_BIO_CTRL { + BIO_CTRL_RESET = 1, /* opt - rewind/zero etc */ + BIO_CTRL_EOF = 2, /* opt - are we at the eof */ + BIO_CTRL_INFO = 3, /* opt - extra tit-bits */ + BIO_CTRL_SET = 4, /* man - set the 'IO' type */ + BIO_CTRL_GET = 5, /* man - get the 'IO' type */ + BIO_CTRL_PUSH = 6, /* opt - internal, used to signify change */ + BIO_CTRL_POP = 7, /* opt - internal, used to signify change */ + BIO_CTRL_GET_CLOSE = 8, /* man - set the 'close' on free */ + BIO_CTRL_SET_CLOSE = 9, /* man - set the 'close' on free */ + BIO_CTRL_PENDING = 10, /* opt - is their more data buffered */ + BIO_CTRL_FLUSH = 11, /* opt - 'flush' buffered output */ + BIO_CTRL_DUP = 12, /* man - extra stuff for 'duped' BIO */ + BIO_CTRL_WPENDING = 13, /* opt - number of bytes still to write */ + + /* callback is int cb(BIO *bio,state,ret); */ + BIO_CTRL_SET_CALLBACK = 14, /* opt - set callback function */ + BIO_CTRL_GET_CALLBACK = 15, /* opt - set callback function */ + + BIO_CTRL_SET_FILENAME = 30, /* BIO_s_file special */ + + /* dgram BIO stuff */ + BIO_CTRL_DGRAM_CONNECT = 31, /* BIO dgram special */ + BIO_CTRL_DGRAM_SET_CONNECTED = 32, /* allow for an externally connected + * socket to be passed in */ + BIO_CTRL_DGRAM_SET_RECV_TIMEOUT = 33, /* setsockopt, essentially */ + BIO_CTRL_DGRAM_GET_RECV_TIMEOUT = 34, /* getsockopt, essentially */ + BIO_CTRL_DGRAM_SET_SEND_TIMEOUT = 35, /* setsockopt, essentially */ + BIO_CTRL_DGRAM_GET_SEND_TIMEOUT = 36, /* getsockopt, essentially */ + + BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP = 37, /* flag whether the last */ + BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP = 38, /* I/O operation tiemd out */ + + /* #ifdef IP_MTU_DISCOVER */ + BIO_CTRL_DGRAM_MTU_DISCOVER = 39, /* set DF bit on egress packets */ + /* #endif */ + + BIO_CTRL_DGRAM_QUERY_MTU = 40, /* as kernel for current MTU */ + BIO_CTRL_DGRAM_GET_FALLBACK_MTU = 47, + BIO_CTRL_DGRAM_GET_MTU = 41, /* get cached value for MTU */ + BIO_CTRL_DGRAM_SET_MTU = 42, /* set cached value for MTU. + * want to use this if asking + * the kernel fails */ + BIO_CTRL_DGRAM_MTU_EXCEEDED = 43, /* check whether the MTU was + * exceed in the previous write + * operation */ + BIO_CTRL_DGRAM_GET_PEER = 46, + BIO_CTRL_DGRAM_SET_PEER = 44, /* Destination for the data */ + + BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT = 45, /* Next DTLS handshake timeout + * to adjust socket timeouts */ + BIO_CTRL_DGRAM_SET_DONT_FRAG = 48, + BIO_CTRL_DGRAM_GET_MTU_OVERHEAD = 49, +}; + +/* modifiers */ +enum WS_BIO_MOD { + BIO_FP_READ = 0x02, + BIO_FP_WRITE = 0x04, + BIO_FP_APPEND = 0x08, + BIO_FP_TEXT = 0x10, +}; + + +/* flags */ +enum WS_BIO_FLAGS { + BIO_FLAGS_READ = 0x01, + BIO_FLAGS_WRITE = 0x02, + BIO_FLAGS_IO_SPECIAL = 0x04, + BIO_FLAGS_RWS = BIO_FLAGS_READ| + BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL, + BIO_FLAGS_SHOULD_RETRY = 0x08, + BIO_FLAGS_BASE64_NO_NL = 0x100, + /* Used with memory BIOs: shouldn't free up or change the data in any way. + */ + BIO_FLAGS_MEM_RDONLY = 0x200, +}; + +enum WS_BIO_RR { +/* Returned from the SSL bio when the certificate retrieval code had an error */ + BIO_RR_SSL_X509_LOOKUP = 0x01, +/* Returned from the connect BIO when a connect would have blocked */ + BIO_RR_CONNECT = 0x02, +/* Returned from the accept BIO when an accept would have blocked */ + BIO_RR_ACCEPT = 0x03, +}; + +/* These are passed by the BIO callback */ +enum WS_BIO_CB_FLAGS { + BIO_CB_FREE = 0x01, + BIO_CB_READ = 0x02, + BIO_CB_WRITE = 0x03, + BIO_CB_PUTS = 0x04, + BIO_CB_GETS = 0x05, + BIO_CB_CTRL = 0x06, + BIO_CB_RETURN = 0x80, +}; + +#define BIO_CB_return(a) ((a) | BIO_CB_RETURN) +#define BIO_cb_post(a) ((a) & BIO_CB_RETURN) +#define BIO_cb_pre(a) (!BIO_cb_post((a))) + + +typedef struct WOLFCRYPT_BIO WOLFCRYPT_BIO; +typedef struct WOLFCRYPT_BIO_METHOD WOLFCRYPT_BIO_METHOD; + +typedef void WOLFCRYPT_BIO_info_cb (WOLFCRYPT_BIO *, int, const char *, + int, long, long); + +/* wolfSSL BIO_METHOD type */ +struct WOLFCRYPT_BIO_METHOD { + int type; /* method type */ + const char *name; + int (*bwrite) (WOLFCRYPT_BIO *, const char *, int); + int (*bread) (WOLFCRYPT_BIO *, char *, int); + int (*bputs) (WOLFCRYPT_BIO *, const char *); + int (*bgets) (WOLFCRYPT_BIO *, char *, int); + long (*ctrl) (WOLFCRYPT_BIO *, int, long, void *); + int (*create) (WOLFCRYPT_BIO *); + int (*destroy) (WOLFCRYPT_BIO *); + long (*callback_ctrl) (WOLFCRYPT_BIO *, int, WOLFCRYPT_BIO_info_cb *); +}; + +struct WOLFCRYPT_BIO { + WOLFCRYPT_BIO_METHOD *method; + /* bio, mode, argp, argi, argl, ret */ + long (*callback) (WOLFCRYPT_BIO *, int, const char *, int, long, long); + char *cb_arg; /* first argument for the callback */ + int init; + int shutdown; + int flags; /* extra storage */ + int retry_reason; + int num; + void *ptr; + WOLFCRYPT_BIO *next_bio; /* used by filter BIOs */ + WOLFCRYPT_BIO *prev_bio; /* used by filter BIOs */ + int references; + wolfSSL_Mutex refMutex; /* to lock r/w on references */ + unsigned long num_read; + unsigned long num_write; +}; + +enum WS_BIO_C_FLAGS { + BIO_C_SET_CONNECT = 100, + BIO_C_DO_STATE_MACHINE = 101, + BIO_C_SET_NBIO = 102, + BIO_C_SET_PROXY_PARAM = 103, + BIO_C_SET_FD = 104, + BIO_C_GET_FD = 105, + BIO_C_SET_FILE_PTR = 106, + BIO_C_GET_FILE_PTR = 107, + BIO_C_SET_FILENAME = 108, + BIO_C_SET_SSL = 109, + BIO_C_GET_SSL = 110, + BIO_C_SET_MD = 111, + BIO_C_GET_MD = 112, + BIO_C_GET_CIPHER_STATUS = 113, + BIO_C_SET_BUF_MEM = 114, + BIO_C_GET_BUF_MEM_PTR = 115, + BIO_C_GET_BUFF_NUM_LINES = 116, + BIO_C_SET_BUFF_SIZE = 117, + BIO_C_SET_ACCEPT = 118, + BIO_C_SSL_MODE = 119, + BIO_C_GET_MD_CTX = 120, + BIO_C_GET_PROXY_PARAM = 121, + BIO_C_SET_BUFF_READ_DATA = 122, /* data to read first */ + BIO_C_GET_CONNECT = 123, + BIO_C_GET_ACCEPT = 124, + BIO_C_SET_SSL_RENEGOTIATE_BYTES = 125, + BIO_C_GET_SSL_NUM_RENEGOTIATES = 126, + BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT = 127, + BIO_C_FILE_SEEK = 128, + BIO_C_GET_CIPHER_CTX = 129, + BIO_C_SET_BUF_MEM_EOF_RETURN = 130, /* return end of input + * value */ + BIO_C_SET_BIND_MODE = 131, + BIO_C_GET_BIND_MODE = 132, + BIO_C_FILE_TELL = 133, + BIO_C_GET_SOCKS = 134, + BIO_C_SET_SOCKS = 135, + + BIO_C_SET_WRITE_BUF_SIZE = 136, /* for BIO_s_bio */ + BIO_C_GET_WRITE_BUF_SIZE = 137, + BIO_C_MAKE_BIO_PAIR = 138, + BIO_C_DESTROY_BIO_PAIR = 139, + BIO_C_GET_WRITE_GUARANTEE = 140, + BIO_C_GET_READ_REQUEST = 141, + BIO_C_SHUTDOWN_WR = 142, + BIO_C_NREAD0 = 143, + BIO_C_NREAD = 144, + BIO_C_NWRITE0 = 145, + BIO_C_NWRITE = 146, + BIO_C_RESET_READ_REQUEST = 147, + BIO_C_SET_MD_CTX = 148, + + BIO_C_SET_PREFIX = 149, + BIO_C_GET_PREFIX = 150, + BIO_C_SET_SUFFIX = 151, + BIO_C_GET_SUFFIX = 152, + + BIO_C_SET_EX_ARG = 153, + BIO_C_GET_EX_ARG = 154, +}; + +/* connect BIO */ +enum WS_BIO_CONN { + BIO_CONN_S_BEFORE = 1, + BIO_CONN_S_GET_IP = 2, + BIO_CONN_S_GET_PORT = 3, + BIO_CONN_S_CREATE_SOCKET = 4, + BIO_CONN_S_CONNECT = 5, + BIO_CONN_S_OK = 6, + BIO_CONN_S_BLOCKED_CONNECT = 7, + BIO_CONN_S_NBIO = 8, +}; + +enum WS_BIO_BIND { + BIO_BIND_NORMAL = 0, + BIO_BIND_REUSEADDR_IF_UNUSED = 1, + BIO_BIND_REUSEADDR = 2, +}; + +WOLFSSL_API WOLFCRYPT_BIO *wc_BioNew(WOLFCRYPT_BIO_METHOD *method); +WOLFSSL_API int wc_BioFree(WOLFCRYPT_BIO *bio); +WOLFSSL_API void wc_BioFreeAll(WOLFCRYPT_BIO *bio); + +WOLFSSL_API const char *wc_BioMethodName(const WOLFCRYPT_BIO *bio); +WOLFSSL_API int wc_BioMethodType(const WOLFCRYPT_BIO *bio); + +WOLFSSL_API int wc_BioSet(WOLFCRYPT_BIO *bio, + WOLFCRYPT_BIO_METHOD *method); +WOLFSSL_API void wc_BioClearFlags(WOLFCRYPT_BIO *bio, int flags); +WOLFSSL_API void wc_BioSetFlags(WOLFCRYPT_BIO *bio, int flags); +WOLFSSL_API int wc_BioTestFlags(const WOLFCRYPT_BIO *bio, int flags); + +#define wc_BioGetFlags(bio) wc_BioTestFlags(bio, ~(0x0)) +#define wc_BioSetRetrySpecial(bio) \ + wc_BioSetFlags(bio, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) +#define wc_BioSetRetryRead(bio) \ + wc_BioSetFlags(bio, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) +#define wc_BioSetRetryWrite(bio) \ + wc_BioSetFlags(bio, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + + +#define wc_BioClearRetryFlags(bio) \ + wc_BioClearFlags(bio, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) +#define wc_BioGetRetryFlags(bio) \ + wc_BioTestFlags(bio, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + +/* These should be used by the application to tell why we should retry */ +#define wc_BioShouldRead(bio) wc_BioTestFlags(bio, BIO_FLAGS_READ) +#define wc_BioShouldWrite(bio) wc_BioTestFlags(bio, BIO_FLAGS_WRITE) +#define wc_BioShouldIoSpecial(bio) wc_BioTestFlags(bio, BIO_FLAGS_IO_SPECIAL) +#define wc_BioRetryType(bio) wc_BioTestFlags(bio, BIO_FLAGS_RWS) +#define wc_BioShouldRetry(bio) wc_BioTestFlags(bio, BIO_FLAGS_SHOULD_RETRY) + +WOLFSSL_API long (*wc_BioGetCallback(const WOLFCRYPT_BIO *bio)) + (WOLFCRYPT_BIO *, int, const char *, int, long, long); + +WOLFSSL_API void wc_BioSetCallback(WOLFCRYPT_BIO *bio, + long (*cb) (WOLFCRYPT_BIO *, int, + const char *, int, long, long)); +WOLFSSL_API void wc_BioSetCallbackArg(WOLFCRYPT_BIO *bio, char *arg); +WOLFSSL_API char *wc_BioGetCallbackArg(const WOLFCRYPT_BIO *bio); + +WOLFSSL_API int wc_BioRead(WOLFCRYPT_BIO *bio, void *out, int outl); +WOLFSSL_API int wc_BioWrite(WOLFCRYPT_BIO *bio, const void *in, int inl); +WOLFSSL_API int wc_BioPuts(WOLFCRYPT_BIO *bio, const char *in); +WOLFSSL_API int wc_BioGets(WOLFCRYPT_BIO *bio, char *in, int inl); + +WOLFSSL_API WOLFCRYPT_BIO *wc_BioPush(WOLFCRYPT_BIO *top, + WOLFCRYPT_BIO *next); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioPop(WOLFCRYPT_BIO *bio); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioNext(WOLFCRYPT_BIO *bio); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioGetRetryBio(WOLFCRYPT_BIO *bio, + int *reason); +WOLFSSL_API int wc_BioGetRetryReason(WOLFCRYPT_BIO *bio); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioFindType(WOLFCRYPT_BIO *bio, int type); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioDupChain(WOLFCRYPT_BIO *bio); +#define wc_BioDupState(bio, ret) \ + wc_BioCtrl(bio, BIO_CTRL_DUP, 0, ret) + +WOLFSSL_API long wc_BioCtrl(WOLFCRYPT_BIO *bio, int cmd, + long larg, void *parg); +WOLFSSL_API long wc_BioCallbackCtrl(WOLFCRYPT_BIO *bio, int cmd, + void (*fp) (WOLFCRYPT_BIO *, int, + const char *, int, long, long)); +WOLFSSL_API long wc_BioIntCtrl(WOLFCRYPT_BIO *bio, int cmd, + long larg, int iarg); +WOLFSSL_API char *wc_BioPtrCtrl(WOLFCRYPT_BIO *bio, int cmd, long larg); +WOLFSSL_API size_t wc_BioCtrlPending(WOLFCRYPT_BIO *bio); +WOLFSSL_API size_t wc_BioCtrlWpending(WOLFCRYPT_BIO *bio); + +WOLFSSL_API int wc_BioIndent(WOLFCRYPT_BIO *bio, int indent, int max); + +WOLFSSL_API unsigned long wc_BioNumberRead(WOLFCRYPT_BIO *bio); +WOLFSSL_API unsigned long wc_BioNumberWritten(WOLFCRYPT_BIO *bio); + +#define wc_BioReset(bio) \ + (int)wc_BioCtrl(bio, BIO_CTRL_RESET, 0, NULL) +#define wc_BioEof(bio) \ + (int)wc_BioCtrl(bio, BIO_CTRL_EOF, 0, NULL) +#define wc_BioSetClose(bio,c) \ + (int)wc_BioCtrl(bio, BIO_CTRL_SET_CLOSE, (c), NULL) +#define wc_BioGetClose(bio) \ + (int)wc_BioCtrl(bio, BIO_CTRL_GET_CLOSE, 0, NULL) +#define wc_BioPending(bio) \ + (int)wc_BioCtrl(bio, BIO_CTRL_PENDING, 0, NULL) +#define wc_BioWpending(bio) \ + (int)wc_BioCtrl(bio, BIO_CTRL_WPENDING, 0, NULL) +#define wc_BioFlush(bio) \ + (int)wc_BioCtrl(bio, BIO_CTRL_FLUSH, 0, NULL) +#define wc_BioSetInfoCallback(bio, cb) \ + (int)wc_BioCallbackCtrl(bio, BIO_CTRL_SET_CALLBACK, cb) +#define wc_BioGetInfoCallback(bio, cb) \ + (int)wc_BioCallbackCtrl(bio, BIO_CTRL_GET_CALLBACK, 0, cb) + +WOLFSSL_API void wc_BioCopyNextRetry(WOLFCRYPT_BIO *b); + +WOLFSSL_API int wc_BioPrintf(WOLFCRYPT_BIO *bio, const char *format, ...); + +/* BIO file */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_s_file(void); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioNewFp(XFILE f, int close_flag); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioNewFile(const char *name, + const char *mode); +#define wc_BioSetFp(bio, f, c) \ + wc_BioCtrl(bio, BIO_C_SET_FILE_PTR, c, (char *)f) +#define wc_BioGetFp(bio, f) \ + wc_BioCtrl(bio, BIO_C_GET_FILE_PTR, 0, (char *)f) +#define wc_BioSeek(bio, ofs) \ + (int)wc_BioCtrl(bio, BIO_C_FILE_SEEK, ofs, NULL) +#define wc_BioTell(bio) \ + (int)wc_BioCtrl(bio, BIO_C_FILE_TELL, 0, NULL) +#define wc_BioReadFilename(bio, name) \ + wc_BioCtrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_READ, name) +#define wc_BioWriteFilename(bio, name) \ + wc_BioCtrl(bio,BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_WRITE, name) +#define wc_BioAppendFilename(bio, name) \ + wc_BioCtrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE|BIO_FP_APPEND, name) +#define wc_BioRwFilename(bio, name) \ + wc_BioCtrl(bio, BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) + +/* BIO memory */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_s_mem(void); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioNewMemBuf(void *data, int len); + +/* BIO fd */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_s_fd(void); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioNewFd(int fd, int close_flag); + +/* BIO null */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_s_null(void); + +/* BIO socket */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_s_socket(void); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioNewSocket(int fd, int close_flag); +WOLFSSL_API int wc_BioSockShouldRetry(int i); +WOLFSSL_API int wc_BioSockNonFatalError(int err); + +#define wc_BioSetFd(bio, fd, c) \ + wc_BioIntCtrl(bio, BIO_C_SET_FD, c, fd) +#define wc_BioGetFd(bio, c) \ + wc_BioCtrl(bio, BIO_C_GET_FD, 0, (char *)c) + +/* BIO connect */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_s_connect(void); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioNewConnect(const char *host_port); +#define wc_BioSetConnHostname(bio, hname) \ + wc_BioCtrl(bio, BIO_C_SET_CONNECT, 0, (char *)hname) +#define wc_BioSetConnPort(bio, port) \ + wc_BioCtrl(bio, BIO_C_SET_CONNECT, 1, (char *)port) +#define wc_BioSetConnIp(bio, ip) \ + wc_BioCtrl(bio, BIO_C_SET_CONNECT, 2, (char *)ip) +#define wc_BioSetConnIntPort(bio, port) \ + wc_BioCtrl(bio, BIO_C_SET_CONNECT, 3, (int *)port) +#define wc_BioGetConnHostname(bio) \ + wc_BioPtrCtrl(bio, BIO_C_GET_CONNECT, 0) +#define wc_BioGetConnPort(bio) \ + wc_BioPtrCtrl(bio, BIO_C_GET_CONNECT, 1) +#define wc_BioGetConnIp(bio) \ + wc_BioPtrCtrl(bio, BIO_C_GET_CONNECT, 2) +#define wc_BioGetConnIntPort(bio) \ + wc_BioIntCtrl(bio, BIO_C_GET_CONNECT, 3, 0) + +#define wc_BioSetNbio(bio, n) \ + wc_BioCtrl(bio, BIO_C_SET_NBIO, n, NULL) + +#define wc_BioDoHandshake(bio) \ + wc_BioCtrl(bio, BIO_C_DO_STATE_MACHINE, 0, NULL) +#define wc_BioDoConnect(bio) wc_BioDoHandshake(bio) +#define wc_BioDoAccept(bio) wc_BioDoHandshake(bio) + +/* BIO accept */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_s_accept(void); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioNewAccept(const char *str); +#define wc_BioSetAcceptPort(bio, name) \ + wc_BioCtrl(bio, BIO_C_SET_ACCEPT, 0, (char *)name) +#define wc_BioGetAcceptPort(bio) \ + wc_BioPtrCtrl(bio, BIO_C_GET_ACCEPT, 0) +#define wc_BioSetNbioAccept(bio, name) \ + wc_BioCtrl(bio, BIO_C_SET_ACCEPT, 1, name ? (void *)"a" : NULL) +#define wc_BioSetAcceptBios(bio, nbio) \ + wc_BioCtrl(bio, BIO_C_SET_ACCEPT, 2, nbio) +#define wc_BioSetBindMode(bio, mode) \ + wc_BioCtrl(bio, BIO_C_SET_BIND_MODE, mode, NULL) +#define wc_BioGetBindMode(bio, mode) \ + wc_BioCtrl(bio, BIO_C_GET_BIND_MODE, 0, NULL) +#define wc_BioSetSocketOptions(bio, opt) \ + wc_BioCtrl(bio, BIO_C_SET_EX_ARG, opt, NULL) + + +/* BIO datagram */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_s_datagram(void); +WOLFSSL_API WOLFCRYPT_BIO *wc_BioNewDgram(int fd, int close_flag); + +/* BIO filter buffer */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_f_buffer(void); + +#define wc_BioGetMemData(bio, data) \ + wc_BioCtrl(bio, BIO_CTRL_INFO, 0, data) +#define wc_BioSetMemBuf(bio, data, c) \ + wc_BioCtrl(bio, BIO_C_SET_BUF_MEM, c, data) +#define wc_BioGetMemPtr(b, ptr) \ + wc_BioCtrl(bio, BIO_C_GET_BUF_MEM_PTR,0, (char *)ptr) +#define wc_BioSetMemEofReturn(bio, v) \ + wc_BioCtrl(bio, BIO_C_SET_BUF_MEM_EOF_RETURN, v, NULL) + +#define wc_BioGetBufferNumLines(bio) \ + wc_BioCtrl(bio, BIO_C_GET_BUFF_NUM_LINES, 0, NULL) +#define wc_BioSetBufferSize(bio, size) \ + wc_BioCtrl(bio, BIO_C_SET_BUFF_SIZE, size, NULL) +#define wc_BioSetReadBufferSize(bio, size) \ + wc_BioIntCtrl(bio, BIO_C_SET_BUFF_SIZE, size, 0) +#define wc_BioSetWriteBufferSize(bio, size) \ + wc_BioIntCtrl(bio, BIO_C_SET_BUFF_SIZE, size, 1) +#define wc_BioSetBufferReadData(bio, buf, num) \ + wc_BioCtrl(bio, BIO_C_SET_BUFF_READ_DATA, num, buf) + +/* BIO filter cipher */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_f_cipher(void); +WOLFSSL_API void wc_BioSetCipher(WOLFCRYPT_BIO *bio, + const WOLFCRYPT_EVP_CIPHER *cipher, + const unsigned char *key, + const unsigned char *iv, int enc); + +#define wc_BioGetCipherStatus(bio) \ + wc_BioCtrl(bio, BIO_C_GET_CIPHER_STATUS, 0, NULL) +#define wc_BioGetCipherCtx(bio, ctx) \ + wc_BioCtrl(bio, BIO_C_GET_CIPHER_CTX, 0, ctx) + +/* BIO filter base64 */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_f_base64(void); + +/* BIO filter digest */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_f_md(void); + +#define wc_BioSetMd(bio, md) \ + wc_BioCtrl(bio, BIO_C_SET_MD, 0, (WOLFCRYPT_EVP_MD *)md) +#define wc_BioGetMd(bio,md) \ + wc_BioCtrl(bio, BIO_C_GET_MD, 0, (WOLFCRYPT_EVP_MD *)md) +#define wc_BioGetmdCtx(bio,ctx) \ + wc_BioCtrl(bio, BIO_C_GET_MD_CTX, 0, (WOLFCRYPT_EVP_MD_CTX *)ctx) +#define wc_BioSetMdCtx(bio, ctx) \ + wc_BioCtrl(bio, BIO_C_SET_MD_CTX, 0, (WOLFCRYPT_EVP_MD_CTX *)ctx) + +/* BIO filter SSL */ +WOLFSSL_API WOLFCRYPT_BIO_METHOD *wc_Bio_f_ssl(void); +WOLFSSL_API void wc_BioSSLShutdown(WOLFCRYPT_BIO *bio); + +#define wc_BioSetSSL(bio, ssl, mode) \ + wc_BioCtrl(bio, BIO_C_SET_SSL, mode, ssl) +#define wc_BioGetSSL(bio, ssl) \ + wc_BioCtrl(bio, BIO_C_GET_SSL, 0, ssl) +#define wc_BIOSetSSLMode(bio, client) \ + wc_BioCtrl(bio, BIO_C_SSL_MODE, client, NULL) +#define wc_BIOSetSSLRenegotiateBytes(bio, num) \ + wc_BIOCtrl(bio, BIO_C_SET_SSL_RENEGOTIATE_BYTES, num, NULL); +#define wc_BIOGetNumRenegotiates(bio) \ + wc_BIOCtrl(bio, BIO_C_GET_SSL_NUM_RENEGOTIATES, 0, NULL); +#define wc_BIOSetSSLRenegotiateTimeout(bio, seconds) \ + wc_BIOCtrl(bio, BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT, seconds, NULL); + + +/* BIO socket internal functions */ +int wc_BioGetHostIp(const char *str, unsigned char *ip); +int wc_BioGetPort(const char *str, unsigned short *port_ptr); +int wc_BioSockError(int sock); +int wc_BioSockInit(void); +void wc_BioSockCleanup(void); +int wc_BioGetAcceptSocket(char *host, int bind_mode); +int wc_BioAccept(int sock, char **addr); +int wc_BioSetTcpNdelay(int s, int on); +int wc_BioSetTcpNsigpipe(int s, int on); +int wc_BioSocketNbio(int s, int mode); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* OPENSSL_EXTRA */ +#endif /* WOLF_CRYPT_BIO_H */ diff --git a/wolfssl/wolfcrypt/compat-wolfssl.h b/wolfssl/wolfcrypt/compat-wolfssl.h new file mode 100644 index 000000000..83f24b157 --- /dev/null +++ b/wolfssl/wolfcrypt/compat-wolfssl.h @@ -0,0 +1,349 @@ +/* evp.h + * + * Copyright (C) 2015 wolfSSL Inc. + * + * This file is part of wolfSSL. (formerly known as CyaSSL) + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef WOLF_CRYPT_COMPAT_WOLFSSL_H +#define WOLF_CRYPT_COMPAT_WOLFSSL_H + +#include + +#ifndef NO_MD5 +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* EVP digest */ +typedef char WOLFCRYPT_EVP_MD; +#ifndef NO_MD5 +WOLFSSL_API const WOLFCRYPT_EVP_MD* wc_EVP_md5(void); +#endif +WOLFSSL_API const WOLFCRYPT_EVP_MD* wc_EVP_sha1(void); + +WOLFSSL_API const WOLFCRYPT_EVP_MD* wc_EVP_sha256(void); +#ifdef WOLFSSL_SHA384 +WOLFSSL_API const WOLFCRYPT_EVP_MD* wc_EVP_sha384(void); +#endif +#ifdef WOLFSSL_SHA512 +WOLFSSL_API const WOLFCRYPT_EVP_MD* wc_EVP_sha512(void); +#endif +#ifdef WOLFSSL_RIPEMD +WOLFSSL_API const WOLFCRYPT_EVP_MD* wc_EVP_ripemd160(void); +#endif + +/* EVP Cipher */ +typedef char WOLFCRYPT_EVP_CIPHER; +#ifndef NO_AES +WOLFSSL_API const WOLFCRYPT_EVP_CIPHER* wc_EVP_aes_128_cbc(void); +WOLFSSL_API const WOLFCRYPT_EVP_CIPHER* wc_EVP_aes_192_cbc(void); +WOLFSSL_API const WOLFCRYPT_EVP_CIPHER* wc_EVP_aes_256_cbc(void); +WOLFSSL_API const WOLFCRYPT_EVP_CIPHER* wc_EVP_aes_128_ctr(void); +WOLFSSL_API const WOLFCRYPT_EVP_CIPHER* wc_EVP_aes_192_ctr(void); +WOLFSSL_API const WOLFCRYPT_EVP_CIPHER* wc_EVP_aes_256_ctr(void); +#endif +#ifndef NO_DES3 +WOLFSSL_API const WOLFCRYPT_EVP_CIPHER* wc_EVP_des_cbc(void); +WOLFSSL_API const WOLFCRYPT_EVP_CIPHER* wc_EVP_des_ede3_cbc(void); +#endif +#ifdef HAVE_IDEA +WOLFSSL_API const WOLFCRYPT_EVP_CIPHER* wc_EVP_idea_cbc(void); +#endif +WOLFSSL_API const WOLFCRYPT_EVP_CIPHER* wc_EVP_rc4(void); +WOLFSSL_API const WOLFCRYPT_EVP_CIPHER* wc_EVP_enc_null(void); + +enum Digest { + MD5_DIGEST_LENGTH = 16, + SHA_DIGEST_LENGTH = 20, + SHA256_DIGEST_LENGTH = 32, + SHA384_DIGEST_LENGTH = 48, + SHA512_DIGEST_LENGTH = 64 +}; + +#ifndef EVP_MAX_MD_SIZE +#define EVP_MAX_MD_SIZE 64 /* sha512 */ +#endif + +enum Cipher { + RC4_KEY_SIZE = 16, /* always 128bit */ + DES_KEY_SIZE = 8, /* des */ + DES3_KEY_SIZE = 24, /* 3 des ede */ + DES_IV_SIZE = DES_BLOCK_SIZE, + AES_256_KEY_SIZE = 32, /* for 256 bit */ + AES_192_KEY_SIZE = 24, /* for 192 bit */ + AES_IV_SIZE = 16, /* always block size */ + AES_128_KEY_SIZE = 16, /* for 128 bit */ + EVP_SALT_SIZE = 8, /* evp salt size 64 bits */ +}; + +#ifndef NO_MD5 +typedef struct { + int holder[24]; /* big enough, but check on init */ +} WOLFCRYPT_MD5_CTX; + +WOLFSSL_API void wc_MD5_Init(WOLFCRYPT_MD5_CTX*); +WOLFSSL_API void wc_MD5_Update(WOLFCRYPT_MD5_CTX*, const void*, unsigned long); +WOLFSSL_API void wc_MD5_Final(unsigned char*, WOLFCRYPT_MD5_CTX*); +#endif /* NO_MD5 */ + +typedef struct { + int holder[24]; /* big enough, but check on init */ +} WOLFCRYPT_SHA_CTX; + +WOLFSSL_API void wc_SHA_Init(WOLFCRYPT_SHA_CTX*); +WOLFSSL_API void wc_SHA_Update(WOLFCRYPT_SHA_CTX*, const void*, unsigned long); +WOLFSSL_API void wc_SHA_Final(unsigned char*, WOLFCRYPT_SHA_CTX*); + +/* SHA1 points to above, shouldn't use SHA0 ever */ +WOLFSSL_API void wc_SHA1_Init(WOLFCRYPT_SHA_CTX*); +WOLFSSL_API void wc_SHA1_Update(WOLFCRYPT_SHA_CTX*, const void*, unsigned long); +WOLFSSL_API void wc_SHA1_Final(unsigned char*, WOLFCRYPT_SHA_CTX*); + +typedef struct { + int holder[28]; /* big enough, but check on init */ +} WOLFCRYPT_SHA256_CTX; + +WOLFSSL_API void wc_SHA256_Init(WOLFCRYPT_SHA256_CTX*); +WOLFSSL_API void wc_SHA256_Update(WOLFCRYPT_SHA256_CTX*, + const void*, unsigned long); +WOLFSSL_API void wc_SHA256_Final(unsigned char*, WOLFCRYPT_SHA256_CTX*); + +#ifdef WOLFSSL_SHA384 +typedef struct { + long long holder[32]; /* big enough, but check on init */ +} WOLFCRYPT_SHA384_CTX; + +WOLFSSL_API void wc_SHA384_Init(WOLFCRYPT_SHA384_CTX*); +WOLFSSL_API void wc_SHA384_Update(WOLFCRYPT_SHA384_CTX*, + const void*, unsigned long); +WOLFSSL_API void wc_SHA384_Final(unsigned char*, WOLFCRYPT_SHA384_CTX*); +#endif /* WOLFSSL_SHA384 */ + +#ifdef WOLFSSL_SHA512 +typedef struct { + long long holder[36]; /* big enough, but check on init */ +} WOLFCRYPT_SHA512_CTX; + +WOLFSSL_API void wc_SHA512_Init(WOLFCRYPT_SHA512_CTX*); +WOLFSSL_API void wc_SHA512_Update(WOLFCRYPT_SHA512_CTX*, + const void*, unsigned long); +WOLFSSL_API void wc_SHA512_Final(unsigned char*, WOLFCRYPT_SHA512_CTX*); +#endif /* WOLFSSL_SHA512 */ + + +#ifdef WOLFSSL_RIPEMD +typedef struct { + int holder[32]; /* big enough, but check on init */ +} WOLFCRYPT_RIPEMD_CTX; + +WOLFSSL_API void wc_RIPEMD_Init(WOLFCRYPT_RIPEMD_CTX*); +WOLFSSL_API void wc_RIPEMD_Update(WOLFCRYPT_RIPEMD_CTX*, + const void*, unsigned long); +WOLFSSL_API void wc_RIPEMD_Final(unsigned char*, WOLFCRYPT_RIPEMD_CTX*); +#endif /* WOLFSSL_RIPEMD */ + +typedef struct { + Hmac hmac; + int type; +} WOLFCRYPT_HMAC_CTX; + +WOLFSSL_API void wc_HMAC_Init(WOLFCRYPT_HMAC_CTX* ctx, const void* key, + int keylen, const WOLFCRYPT_EVP_MD* type); +WOLFSSL_API void wc_HMAC_Update(WOLFCRYPT_HMAC_CTX* ctx, + const unsigned char* data, int len); +WOLFSSL_API void wc_HMAC_Final(WOLFCRYPT_HMAC_CTX* ctx, unsigned char* hash, + unsigned int* len); +WOLFSSL_API void wc_HMAC_cleanup(WOLFCRYPT_HMAC_CTX* ctx); + +WOLFSSL_API unsigned char* wc_HMAC(const WOLFCRYPT_EVP_MD* evp_md, + const void* key, int key_len, + const unsigned char* d, int n, + unsigned char* md, unsigned int* md_len); + +typedef union { +#ifndef NO_MD5 + WOLFCRYPT_MD5_CTX md5; +#endif + WOLFCRYPT_SHA_CTX sha; + WOLFCRYPT_SHA256_CTX sha256; +#ifdef WOLFSSL_SHA384 + WOLFCRYPT_SHA384_CTX sha384; +#endif +#ifdef WOLFSSL_SHA512 + WOLFCRYPT_SHA512_CTX sha512; +#endif +#ifdef WOLFSSL_RIPEMD + WOLFCRYPT_RIPEMD_CTX ripemd; +#endif +} WOLFCRYPT_Hasher; + +typedef struct WOLFCRYPT_EVP_MD_CTX { + unsigned char macType; + int macSize; + const WOLFCRYPT_EVP_MD *digest; + WOLFCRYPT_Hasher hash; +} WOLFCRYPT_EVP_MD_CTX; + +typedef union { +#ifndef NO_AES + Aes aes; +#endif +#ifndef NO_DES3 + Des des; + Des3 des3; +#endif + Arc4 arc4; +#ifdef HAVE_IDEA + Idea idea; +#endif +} WOLFCRYPT_Cipher; + +enum { + AES_128_CBC_TYPE = 1, + AES_192_CBC_TYPE = 2, + AES_256_CBC_TYPE = 3, + AES_128_CTR_TYPE = 4, + AES_192_CTR_TYPE = 5, + AES_256_CTR_TYPE = 6, + DES_CBC_TYPE = 7, + DES_EDE3_CBC_TYPE = 8, + ARC4_TYPE = 9, + NULL_CIPHER_TYPE = 10, + EVP_PKEY_RSA = 11, + EVP_PKEY_DSA = 12, + EVP_PKEY_EC = 13, + IDEA_CBC_TYPE = 14, + NID_sha1 = 64, + NID_md2 = 3, + NID_md5 = 4 +}; + +typedef struct { + int keyLen; /* user may set for variable */ + int blockSize; + int bufLen; + unsigned char enc; /* if encrypt side, then true */ + unsigned char cipherType; + unsigned char final_used; + unsigned char ivUpdate; + unsigned char padding; + +#ifndef NO_AES + unsigned char iv[AES_BLOCK_SIZE]; /* working iv pointer into cipher */ + unsigned char buf[AES_BLOCK_SIZE]; + unsigned char final[AES_BLOCK_SIZE]; +#elif !defined(NO_DES3) || defined(HAVE_IDEA) + unsigned char iv[DES_BLOCK_SIZE]; /* working iv pointer into cipher */ + unsigned char buf[DES_BLOCK_SIZE]; + unsigned char final[DES_BLOCK_SIZE]; +#endif + WOLFCRYPT_Cipher cipher; +} WOLFCRYPT_EVP_CIPHER_CTX; + +#if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) +extern const char *EVP_AES_128_CBC; +extern const char *EVP_AES_192_CBC; +extern const char *EVP_AES_256_CBC; +#if defined(OPENSSL_EXTRA) +extern const char *EVP_AES_128_CTR; +extern const char *EVP_AES_192_CTR; +extern const char *EVP_AES_256_CTR; +#endif +extern const int EVP_AES_SIZE; + +extern const char *EVP_DES_CBC; +extern const int EVP_DES_SIZE; + +extern const char *EVP_DES_EDE3_CBC; +extern const int EVP_DES_EDE3_SIZE; + +#ifdef HAVE_IDEA +extern const char *EVP_IDEA_CBC; +extern const int EVP_IDEA_SIZE; +#endif + +#endif /* OPENSSL_EXTRA || HAVE_WEBSERVER */ + +WOLFSSL_API int wc_EVP_MD_size(const WOLFCRYPT_EVP_MD* md); +WOLFSSL_API void wc_EVP_MD_CTX_init(WOLFCRYPT_EVP_MD_CTX* ctx); +WOLFSSL_API int wc_EVP_MD_CTX_cleanup(WOLFCRYPT_EVP_MD_CTX* ctx); +WOLFSSL_API int wc_EVP_MD_CTX_copy(WOLFCRYPT_EVP_MD_CTX *out, + const WOLFCRYPT_EVP_MD_CTX *in); +WOLFSSL_API const WOLFCRYPT_EVP_MD* wc_EVP_get_digestbynid(int); + + +WOLFSSL_API int wc_EVP_DigestInit(WOLFCRYPT_EVP_MD_CTX* ctx, + const WOLFCRYPT_EVP_MD* type); +WOLFSSL_API int wc_EVP_DigestUpdate(WOLFCRYPT_EVP_MD_CTX* ctx, + const void* data, unsigned long sz); +WOLFSSL_API int wc_EVP_DigestFinal(WOLFCRYPT_EVP_MD_CTX* ctx, + unsigned char* md, unsigned int* s); +WOLFSSL_API int wc_EVP_DigestFinal_ex(WOLFCRYPT_EVP_MD_CTX* ctx, + unsigned char* md, unsigned int* s); +#ifndef NO_MD5 +WOLFSSL_API int wc_EVP_BytesToKey(const WOLFCRYPT_EVP_CIPHER*, + const WOLFCRYPT_EVP_MD*, + const unsigned char*, const unsigned char*, + int, int, unsigned char*, unsigned char*); +#endif + +WOLFSSL_API void wc_EVP_CIPHER_CTX_init(WOLFCRYPT_EVP_CIPHER_CTX* ctx); +WOLFSSL_API int wc_EVP_CIPHER_CTX_cleanup(WOLFCRYPT_EVP_CIPHER_CTX* ctx); +WOLFSSL_API int wc_EVP_CIPHER_CTX_iv_length(const WOLFCRYPT_EVP_CIPHER_CTX*); + +WOLFSSL_API int wc_EVP_CipherInit(WOLFCRYPT_EVP_CIPHER_CTX* ctx, + const WOLFCRYPT_EVP_CIPHER* type, + unsigned char* key, unsigned char* iv, + int enc); +WOLFSSL_API int wc_EVP_CipherUpdate(WOLFCRYPT_EVP_CIPHER_CTX *ctx, + unsigned char *dst, int *dstLen, + const unsigned char *src, int len); +WOLFSSL_API int wc_EVP_CipherFinal(WOLFCRYPT_EVP_CIPHER_CTX *ctx, + unsigned char *dst, int *dstLen); + +WOLFSSL_API int wc_EVP_CIPHER_CTX_key_length(WOLFCRYPT_EVP_CIPHER_CTX*); +WOLFSSL_API int wc_EVP_CIPHER_CTX_set_key_length(WOLFCRYPT_EVP_CIPHER_CTX*, + int); +WOLFSSL_API int wc_EVP_CIPHER_CTX_copy(WOLFCRYPT_EVP_CIPHER_CTX *out, + const WOLFCRYPT_EVP_CIPHER_CTX *in); + + +WOLFSSL_API int wc_EVP_Cipher(WOLFCRYPT_EVP_CIPHER_CTX* ctx, + unsigned char* dst, unsigned char* src, + unsigned int len); + +#ifndef EVP_MAX_MD_SIZE +#define EVP_MAX_MD_SIZE 64 /* sha512 */ +#endif + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* WOLF_CRYPT_COMPAT_WOLFSSL_H */