Hello!

We are implementing custom engine providing GOST algorithms.
We get a SEGFAULT on app_shutdown.

We didn't find out what is wrong with our code. Engine code is attached.
We use 20050112 snapshot of 0.9.8 branch.

-- 
SY, Dmitry Belyavsky (ICQ UIN 11116575)
#include <string.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/bn.h>
#include <openssl/engine.h>
#include <openssl/objects.h>

static int NID_minimum_cipher_GOST = NID_undef;

#define OID_gost89 "1.2.643.2.9.1.1.1"
#define SN_gost89 "gost89"
#define LN_gost89 "GOST 28147-89 symmetric cipher"

int register_minimum_NID (void)
{
	NID_minimum_cipher_GOST = OBJ_create(OID_gost89, SN_gost89, LN_gost89);
	if (NID_minimum_cipher_GOST == NID_undef) {goto err;}
	return 1;
	
err:
	 NID_minimum_cipher_GOST = NID_undef;
	return 0;
}

/* Fake crypt functions */
int cce_cipher_init(EVP_CIPHER_CTX *ctx, const unsigned char *key,
		const unsigned char *iv, int enc){return 1;}

int	cce_cipher_do(EVP_CIPHER_CTX *ctx, unsigned char *out,
		const unsigned char *in, unsigned int inl){return 1;}

int cce_cipher_cleanup(EVP_CIPHER_CTX *ctx){return 1;}

#define minimum_LIB_NAME "minimum GOST engine"

static const char *engine_minimum_id = "minimum";
static const char *engine_minimum_name = "minimum GOST engine";

static int cce_destroy(ENGINE *e);
static int cce_init(ENGINE *e);
static int cce_finish(ENGINE *e);

/* Engine commands */
static const ENGINE_CMD_DEFN cce_cmd_defns[] = {
		{0, NULL, NULL, 0}
	};

/* Symetric cipher and digest function registrar */

static int cce_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
		 const int **nids, int nid);

static int cce_cipher_nids[]=
    {NID_undef,0};

static EVP_CIPHER cipher_gost = 
	{
	  NID_undef,
	  1,/*block_size*/
	  32,/*key_size*/
	  8,
	  EVP_CIPH_CFB_MODE|EVP_CIPH_CUSTOM_IV|EVP_CIPH_NO_PADDING,
	  cce_cipher_init,
	  cce_cipher_do,
	  cce_cipher_cleanup,
	  0,/* ctx_size */
	  NULL,
	  NULL,
	  NULL,
	  NULL,
	};

static int cce_init(ENGINE *e) { 
	return 1;
}
static int cce_finish(ENGINE *e) { 
	return 1;
}

static int cce_destroy(ENGINE *e) { 
	ENGINE_unregister_ciphers(e);
	OBJ_cleanup();
	return 1;
}

static int bind_cce (ENGINE *e,const char *id) {
	if (id && strcmp(id, engine_minimum_id)) return 0;
	if (!ENGINE_set_id(e, engine_minimum_id)) {
		printf("ENGINE_set_id failed\n"); 
		return 0;
	}	
	if (!ENGINE_set_name(e, engine_minimum_name)) {
		printf("ENGINE_set_name failed\n");
		return 0;
	}	
	if (!register_minimum_NID()) return 0;
	/* -------- set up NIDs */
	cipher_gost.nid = NID_minimum_cipher_GOST;
	/* -------- end set up NIDs */
    if (! ENGINE_set_ciphers(e, cce_ciphers)) {
		printf("ENGINE_set_ciphers failed\n");
		return 0;
	}	
	if ( ! ENGINE_set_destroy_function(e, cce_destroy)
		|| ! ENGINE_set_init_function(e,cce_init)
		|| ! ENGINE_set_finish_function(e,cce_finish)) return 0;
	if ( ! ENGINE_register_ciphers(e)
		/* These two actually should go in LIST_ADD command */
		|| ! EVP_add_cipher(&cipher_gost)
	   ) return 0;
	return 1;
}	

#ifdef _WIN32
extern __declspec( dllexport ) 
#endif
	
#ifndef OPENSSL_NO_DYNAMIC_ENGINE
IMPLEMENT_DYNAMIC_BIND_FN(bind_cce);
IMPLEMENT_DYNAMIC_CHECK_FN();
#else
static ENGINE *engine_cce(void)
	{
	ENGINE *ret = ENGINE_new();
	if(!ret)
		return NULL;
	if(!bind_cce(ret, engine_minimum_id))
		{
		ENGINE_free(ret);
		return NULL;
		}
	return ret;
	}

void ENGINE_load_cce(void)
	{
	/* Copied from eng_[openssl|dyn].c */
	ENGINE *toadd = engine_cce();
	if(!toadd) return;
	ENGINE_add(toadd);
	ENGINE_free(toadd);
	ERR_clear_error();
	}
#endif /* OPENSSL_NO_DYNAMIC_ENGINE */

static int cce_ciphers (ENGINE *e,const EVP_CIPHER **cipher,
		const int **nids, int nid) {
	int ok = 1;
	if (!cipher) {
		/* return list of supported nids */
		if (cce_cipher_nids[0] == NID_undef) {
			cce_cipher_nids[0] = NID_minimum_cipher_GOST;
		}
		*nids = cce_cipher_nids;
		return 1; /* Only one cipher supported */
	}

	if(nid == NID_minimum_cipher_GOST) {
			*cipher = &cipher_gost;
	}
	return ok;
}	

Reply via email to