Beispiel #1
0
bool MCCrypt_random_bytes(uint32_t p_bytecount, void *&r_bytes)
{
	bool t_success = true;
	unsigned char *t_bytes = nil;

	t_success = InitSSLCrypt() == True;
	if (t_success)
		t_success = MCMemoryAllocate(p_bytecount, t_bytes);
	if (t_success)
		t_success = RAND_bytes(t_bytes, p_bytecount) == 1;

	if (t_success)
		r_bytes = t_bytes;
	return t_success;
}
Beispiel #2
0
void MCSecurityEvalRandomBytes(MCExecContext& ctxt, uinteger_t p_byte_count, MCDataRef& r_bytes)
{
	if (!InitSSLCrypt())
	{
		ctxt.LegacyThrow(EE_SECURITY_NOLIBRARY);
		return;
	}

	if (MCSRandomData (p_byte_count, r_bytes))
	{
		ctxt.SetTheResultToEmpty();
		return;
	}
	
	ctxt.SetTheResultToCString("error: could not get random bytes");
}
Beispiel #3
0
void SSL_ciphernames(MCExecPoint &ep)
{
#ifdef MCSSL
	// MW-2004-12-29: Integrate Tuviah's fixes
	static char sslcipherlist[] = "bf,128\nbf-cbc,128\nbf-cfb,128\nbf-ecb,128\nbf-ofb,128\nblowfish,128\ncast,128\ncast-cbc,128\ncast5-cbc,128\ncast5-cfb,128\ncast5-ecb,128\ncast5-ofb,128\ndes,64\ndes-cbc,64\ndes-cfb,64\ndes-ecb,64\ndes-ede,128\ndes-ede-cbc,128\ndes-ede-cfb,128\ndes-ede-ofb,128\ndes-ede3,192\ndes-ede3-cbc,192\ndes-ede3-cfb,192\ndes-ede3-ofb,192\ndes-ofb,64\ndes3,192\ndesx,192\ndesx-cbc,192\nrc2,128\nrc2-40-cbc,40\nrc2-64-cbc,64\nrc2-cbc,128\nrc2-cfb,128\nrc2-ecb,128\nrc2-ofb,128\nrc4,128\nrc4-40,40\nrc5,128\nrc5-cbc,128\nrc5-cfb,128\nrc5-ecb,128\nrc5-ofb,128";
	isfirstcipher = True;
	ep.clear();
	if (!InitSSLCrypt())
	{
		char sslerrbuf[256];
		SSLError(sslerrbuf);
		MCresult->copysvalue(sslerrbuf);
	}
	else
		OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, list_ciphers_cb, &ep);
#else
	// MW-2013-01-15: [[ Bug 10631 ]] Make sure we clear the return value if no
	//   SSL!
	ep . clear();
#endif
}
Beispiel #4
0
//error buf should have a buffer of at least 256 bytes.
unsigned long SSLError(char *errbuf)
{
	if (!InitSSLCrypt())
	{
		strcpy(errbuf,"ssl library not found");
		return 0;
	}
#ifdef MCSSL
	unsigned long ecode = ERR_get_error();
	if (errbuf)
	{
		if (ecode)
			ERR_error_string_n(ecode,errbuf,255);
		else
			errbuf[0] = '\0';
	}
	return ecode;
#else
	return 0;
#endif
}
Beispiel #5
0
Exec_stat MCIdeSign::exec(MCExecPoint& ep)
{
	Exec_stat t_stat;
	t_stat = ES_NORMAL;

	// Clear the result as we return an error there
	MCresult -> clear();

	if (t_stat == ES_NORMAL)
		t_stat = m_params -> eval(ep);

	MCVariableValue *t_array;
	if (t_stat == ES_NORMAL)
	{
		t_array = ep . getarray();
		if (t_array == NULL)
			return ES_ERROR;
	}

	MCExecPoint ep2(ep);

	MCDeploySignParameters t_params;
	memset(&t_params, 0, sizeof(MCDeploySignParameters));

	if (t_stat == ES_NORMAL)
		t_stat = fetch_opt_cstring(ep2, t_array, "passphrase", t_params . passphrase);
	if (t_stat == ES_NORMAL)
		t_stat = fetch_opt_filepath(ep2, t_array, "certificate", t_params . certificate);
	if (t_stat == ES_NORMAL)
		t_stat = fetch_opt_filepath(ep2, t_array, "privatekey", t_params . privatekey);
	if (t_stat == ES_NORMAL)
		t_stat = fetch_opt_filepath(ep2, t_array, "certstore", t_params . certstore);
	if (t_stat == ES_NORMAL)
		t_stat = fetch_opt_cstring(ep2, t_array, "timestamper", t_params . timestamper);
	if (t_stat == ES_NORMAL)
		t_stat = fetch_opt_cstring(ep2, t_array, "description", t_params . description);
	if (t_stat == ES_NORMAL)
		t_stat = fetch_opt_cstring(ep2, t_array, "url", t_params . url);
	if (t_stat == ES_NORMAL)
		t_stat = fetch_filepath(ep2, t_array, "input", t_params . input);
	if (t_stat == ES_NORMAL)
		t_stat = fetch_filepath(ep2, t_array, "output", t_params . output);

	if (t_stat == ES_NORMAL)
		if (t_params . certstore != NULL && (t_params . certificate != NULL || t_params . privatekey != NULL))
			t_stat = ES_ERROR;

	if (t_stat == ES_NORMAL)
		if (t_params . certstore == NULL && (t_params . certificate == NULL || t_params . privatekey == NULL))
			t_stat = ES_ERROR;

	bool t_can_sign;
	t_can_sign = true;
	if (t_stat == ES_NORMAL && !InitSSLCrypt())
	{
		MCresult -> sets("could not initialize SSL");
		t_can_sign = false;
	}

	if (t_can_sign && t_stat == ES_NORMAL)
	{
		if (m_platform == PLATFORM_WINDOWS)
			MCDeploySignWindows(t_params);

		MCDeployError t_error;
		t_error = MCDeployCatch();
		if (t_error != kMCDeployErrorNone)
			MCresult -> sets(MCDeployErrorToString(t_error));
	}

	delete t_params . passphrase;
	delete t_params . certificate;
	delete t_params . privatekey;
	delete t_params . certstore;
	delete t_params . timestamper;
	delete t_params . description;
	delete t_params . url;
	delete t_params . input;
	delete t_params . output;

	return t_stat;
}
Beispiel #6
0
char *SSL_encode(Boolean isdecrypt, char *ciphername,
                 const char *data, uint4 inlen,uint4 &outlen, //data to decrypt, length of that data, and pointer to descypted data length
                 const char *keystr, int4 keystrlen, Boolean ispassword, uint2 keylen,
                 const char *saltstr,  uint2 saltlen, const char *ivstr, uint2 ivlen)
{ //password or key, optional key length
	if (!InitSSLCrypt())
		return NULL;
#ifdef MCSSL

	// MW-2011-05-24: [[ Bug 9536 ]] The key length is a function of 'keylen' and for some ciphers
	//   can be larger than 32 bytes. For now, increase the buffer to 256 bytes given a maximum
	//   theoretical key length of 2048.
	uint1 iv[EVP_MAX_IV_LENGTH], key[256];
	if (keylen > 2048)
		return NULL;

	const EVP_CIPHER *cipher=EVP_get_cipherbyname(ciphername);

	uint1 operation = isdecrypt ? 0: 1;

	//get cipher object
	if (!cipher)
	{
		outlen = 789;
		return NULL;
	}

	static const char magic[]="Salted__";

	int4 res = 0;

	//set up cipher context
	EVP_CIPHER_CTX ctx;
	EVP_CIPHER_CTX_init(&ctx);
	//init context with cipher and specify operation
	if (EVP_CipherInit(&ctx, cipher,NULL, NULL, operation) == 0)
		return NULL;

	//try setting keylength if specified. This will fail for some ciphers.
	if (keylen && EVP_CIPHER_CTX_set_key_length(&ctx, keylen/8) == 0)
		return NULL;
	//get new keylength in bytes
	int4 curkeylength = EVP_CIPHER_CTX_key_length(&ctx);
	//zero key and iv
	memset(key,0,EVP_MAX_KEY_LENGTH);
	memset(iv,0,EVP_MAX_IV_LENGTH);
	//if password combine with salt value to generate key

	unsigned char saltbuf[PKCS5_SALT_LEN];
	memset(saltbuf,0,sizeof(saltbuf));

	char *tend = (char *)data + inlen;

	// MW-2004-12-02: Fix bug 2411 - a NULL salt should result in a random one being
	//    generated, if saltstr is NULL and saltlen is zero then the salt should
	//    be taken as being the empty string.
	if (ispassword)
	{
		if (saltstr == NULL)
			RAND_bytes(saltbuf, sizeof(saltbuf));
		else
			memcpy(saltbuf,saltstr,MCU_min(saltlen,PKCS5_SALT_LEN));

		// MW-2004-12-02: We should only do this if we are decrypting
		if (isdecrypt && inlen > sizeof(magic) && memcmp(data,magic,sizeof(magic)-1) == 0)
		{
			data += sizeof(magic) - 1;

			if (saltstr == NULL || saltlen == 0)
				memcpy(saltbuf,data,sizeof(saltbuf));

			data += sizeof(saltbuf);
		}

		curkeylength =	EVP_BytesToKey(cipher,EVP_md5(),(const unsigned char *)saltbuf,(unsigned char *)keystr,
		                              keystrlen,1,key,iv);
	}
	else
	{//otherwise copy to key
		if (keystrlen != curkeylength)
		{ //sanity check then passed wrong size for key
			outlen = 790;
			return NULL;
		}
		else
			memcpy(key,keystr,curkeylength);
	}

	if (ivstr != NULL && ivlen > 0)
	{
		memset(iv,0,EVP_MAX_IV_LENGTH);
		memcpy(iv,ivstr,MCU_min(ivlen,EVP_MAX_IV_LENGTH));
	}

	if (EVP_CipherInit(&ctx, NULL, key, iv, operation) == 0)
		return NULL;
	int4 tmp, ol;
	ol = 0;

	//allocate memory to hold encrypted/decrypted data + an extra block + null terminator for block ciphers.
	unsigned char *outdata = (unsigned char *)malloc(inlen + EVP_CIPHER_CTX_block_size(&ctx) + 1 + sizeof(magic) + sizeof(saltbuf));
	//do encryption/decryption
	if (outdata == NULL)
	{
		outlen = 791;
		return NULL;
	}

	// MW-2004-12-02: Only prepend the salt if we generated the key (i.e. password mode)
	if (!isdecrypt && ispassword)
	{
		memcpy(&outdata[ol],magic,sizeof(magic)-1);
		ol += sizeof(magic)-1;
		memcpy(&outdata[ol],saltbuf,sizeof(saltbuf));
		ol += sizeof(saltbuf);
	}


	// MW-2007-02-13: [[Bug 4258]] - SSL now fails an assertion if datalen == 0
	if (tend - data > 0)
	{
		if (EVP_CipherUpdate(&ctx,&outdata[ol],&tmp,(unsigned char *)data,tend-data) == 0)
		{
			delete outdata;
			return NULL;
		}
		ol += tmp;
	}

	//for padding
	if (EVP_CipherFinal(&ctx,&outdata[ol],&tmp) == 0)
	{
		delete outdata;
		return NULL;
	}
	outlen = ol + tmp;

	//cleam up context and return data
	EVP_CIPHER_CTX_cleanup(&ctx);
	outdata[outlen] = 0; //null terminate data

	return (char *)outdata;
#else
	return NULL;
#endif
}
Beispiel #7
0
bool MCCrypt_rsa_op(bool p_encrypt, RSA_KEYTYPE p_key_type, const char *p_message_in, uint32_t p_message_in_length,
			const char *p_key, uint32_t p_key_length, const char *p_passphrase,
			char *&r_message_out, uint32_t &r_message_out_length, char *&r_result, uint32_t &r_error)
{
	bool t_success = true;
	EVP_PKEY *t_key = NULL;
	RSA *t_rsa = NULL;
	int32_t t_rsa_size;
	uint8_t *t_output_buffer = NULL;
	int32_t t_output_length;

	if (!InitSSLCrypt())
	{
		t_success = false;
		MCCStringClone("error: ssl library initialization failed", r_result);
	}

	if (t_success)
	{
		if (!load_pem_key(p_key, p_key_length, p_key_type, p_passphrase, t_key))
		{
			t_success = false;
			MCCStringClone("error: invalid key", r_result);
		}
	}

	if (t_success)
	{
		t_rsa = EVP_PKEY_get1_RSA(t_key);
		if (t_rsa == NULL)
		{
			t_success = false;
			MCCStringClone("error: not an RSA key", r_result);
		}
	}

	if (t_success)
	{
		t_rsa_size = RSA_size(t_rsa);
		if (!MCMemoryAllocate(t_rsa_size, t_output_buffer))
		{
			t_success = false;
			r_error = EE_NO_MEMORY;
		}
	}
	int (*t_rsa_func)(int, const unsigned char*, unsigned char*, RSA*, int) = NULL;
	if (t_success)
	{
		if (p_encrypt)
		{
			if (p_key_type == RSAKEY_PRIVKEY)
				t_rsa_func = RSA_private_encrypt;
			else
				t_rsa_func = RSA_public_encrypt;
			if (p_message_in_length >= unsigned(t_rsa_size - 11))
			{
				t_success = false;
				MCCStringClone("error: message too large", r_result);
			}
		}
		else
		{
			if (p_key_type == RSAKEY_PRIVKEY)
				t_rsa_func = RSA_private_decrypt;
			else
				t_rsa_func = RSA_public_decrypt;
			if (p_message_in_length != t_rsa_size)
			{
				t_success = false;
				MCCStringClone("error: invalid message size", r_result);
			}
		}
	}
	if (t_success)
	{
		t_output_length = t_rsa_func(p_message_in_length, (const uint8_t*)p_message_in, t_output_buffer, t_rsa, RSA_PKCS1_PADDING);
		if (t_output_length < 0)
		{
			t_success = false;
			MCCStringClone("error: SSL operation failed", r_result);
		}
	}

	if (t_rsa != NULL)
		RSA_free(t_rsa);
	if (t_key != NULL)
		EVP_PKEY_free(t_key);

	if (t_success)
	{
		r_message_out = (char*)t_output_buffer;
		r_message_out_length = t_output_length;
	}
	else
	{
		uint32_t t_err;
		t_err = ERR_get_error();
		if (t_err)
		{
			const char *t_ssl_error = ERR_reason_error_string(t_err);
			MCCStringAppendFormat(r_result, " (SSL error: %s)", t_ssl_error);
		}
		MCMemoryDeallocate(t_output_buffer);
	}

	return t_success;
}