const char *ERR_reason_error_string(unsigned long e) { ERR_STRING_DATA d,*p=NULL; unsigned long l,r; l=ERR_GET_LIB(e); r=ERR_GET_REASON(e); CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH); if (error_hash != NULL) { d.error=ERR_PACK(l,0,r); p=(ERR_STRING_DATA *)lh_retrieve(error_hash,&d); if (p == NULL) { d.error=ERR_PACK(0,0,r); p=(ERR_STRING_DATA *)lh_retrieve(error_hash,&d); } } CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH); return((p == NULL)?NULL:p->string); }
const char *OBJ_nid2ln(int n) { ADDED_OBJ ad,*adp; ASN1_OBJECT ob; if ((n >= 0) && (n < NUM_NID)) { if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID); return(NULL); } return(nid_objs[n].ln); } else if (added == NULL) return(NULL); else { ad.type=ADDED_NID; ad.obj= &ob; ob.nid=n; adp=(ADDED_OBJ *)lh_retrieve(added,&ad); if (adp != NULL) return(adp->obj->ln); else { OBJerr(OBJ_F_OBJ_NID2LN,OBJ_R_UNKNOWN_NID); return(NULL); } } }
/* * anonymization of octet string * anonymized octet strings are also kept in a linked list to make * sure they are unique * * astr has to be a large enough buffer where the anonymized string * will be copied, the anonymized string will be as long as the * original string */ int anon_octs_map(anon_octs_t *a, const char *str, char *astr) { struct hash_node node; struct hash_node *p; int tmp; (void) anon_octs_set_state(a, NON_LEX); /* lookup anon. string in lhash table */ node.data = (char*) str; p = (struct hash_node *) lh_retrieve(a->hash_table,(void*) &node); if (p) { /* found in lhash table */ strcpy(astr, p->hash); } else { /* not found in lhash table */ /* generate a unique random string */ do { generate_random_string(astr, strlen(str)); tmp = list_insert(&(a->list),astr); assert(tmp >= 0); } while (tmp==1); /* store anon. string in lhash table */ p = (struct hash_node*) malloc(sizeof(struct hash_node)); assert(p); p->data = (char*) malloc(strlen(str)+1); assert(p->data); p->hash = (char*) malloc(strlen(astr)+1); assert(p->hash); strcpy(p->data, str); strcpy(p->hash, astr); lh_insert(a->hash_table, p); } return 0; }
const char *OBJ_NAME_get(const char *name, int type) { OBJ_NAME on,*ret; int num=0,alias; if (name == NULL) return(NULL); if ((names_lh == NULL) && !OBJ_NAME_init()) return(NULL); alias=type&OBJ_NAME_ALIAS; type&= ~OBJ_NAME_ALIAS; on.name=name; on.type=type; for (;;) { ret=(OBJ_NAME *)lh_retrieve(names_lh,&on); if (ret == NULL) return(NULL); if ((ret->alias) && !alias) { if (++num > 10) return(NULL); on.name=ret->data; } else { return(ret->data); } } }
/* Privately exposed (via eng_int.h) functions for adding and/or removing * ENGINEs from the implementation table */ int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, ENGINE *e, const int *nids, int num_nids, int setdefault) { int ret = 0, added = 0; ENGINE_PILE tmplate, *fnd; CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); if(!(*table)) added = 1; if(!int_table_check(table, 1)) goto end; if(added) /* The cleanup callback needs to be added */ engine_cleanup_add_first(cleanup); while(num_nids--) { tmplate.nid = *nids; fnd = lh_retrieve(&(*table)->piles, &tmplate); if(!fnd) { fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); if(!fnd) goto end; fnd->uptodate = 0; fnd->nid = *nids; fnd->sk = sk_ENGINE_new_null(); if(!fnd->sk) { OPENSSL_free(fnd); goto end; } fnd->funct = NULL; lh_insert(&(*table)->piles, fnd); } /* A registration shouldn't add duplciate entries */ sk_ENGINE_delete_ptr(fnd->sk, e); /* if 'setdefault', this ENGINE goes to the head of the list */ if(!sk_ENGINE_push(fnd->sk, e)) goto end; /* "touch" this ENGINE_PILE */ fnd->uptodate = 1; if(setdefault) { if(!engine_unlocked_init(e)) { ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, ENGINE_R_INIT_FAILED); goto end; } if(fnd->funct) engine_unlocked_finish(fnd->funct, 0); fnd->funct = e; } nids++; } ret = 1; end: CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); return ret; }
/* Up until OpenSSL 0.9.5a, this was get_section */ CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) { CONF_VALUE *v,vv; if ((conf == NULL) || (section == NULL)) return(NULL); vv.name=NULL; vv.section=(char *)section; v=(CONF_VALUE *)lh_retrieve(conf->data,&vv); return(v); }
ERR_STATE *ERR_get_state(void) { ERR_STATE *ret=NULL,tmp,*tmpp; int i; unsigned long pid; pid=(unsigned long)CRYPTO_thread_id(); CRYPTO_r_lock(CRYPTO_LOCK_ERR); if (thread_hash == NULL) { CRYPTO_r_unlock(CRYPTO_LOCK_ERR); CRYPTO_w_lock(CRYPTO_LOCK_ERR); if (thread_hash == NULL) { MemCheck_off(); thread_hash=lh_new(pid_hash,pid_cmp); MemCheck_on(); CRYPTO_w_unlock(CRYPTO_LOCK_ERR); if (thread_hash == NULL) return(getFallback()); } else CRYPTO_w_unlock(CRYPTO_LOCK_ERR); } else { tmp.pid=pid; ret=(ERR_STATE *)lh_retrieve(thread_hash,&tmp); CRYPTO_r_unlock(CRYPTO_LOCK_ERR); } /* ret == the error state, if NULL, make a new one */ if (ret == NULL) { ret=(ERR_STATE *)Malloc(sizeof(ERR_STATE)); if (ret == NULL) return(getFallback()); ret->pid=pid; ret->top=0; ret->bottom=0; for (i=0; i<ERR_NUM_ERRORS; i++) { ret->err_data[i]=NULL; ret->err_data_flags[i]=0; } CRYPTO_w_lock(CRYPTO_LOCK_ERR); tmpp=(ERR_STATE *)lh_insert(thread_hash,ret); CRYPTO_w_unlock(CRYPTO_LOCK_ERR); if (tmpp != NULL) /* old entry - should not happen */ { ERR_STATE_free(tmpp); } } return(ret); }
/* * lookup str in hash table and copy found hash into astr * copies at most strlen chars * return non-zero if found, 0 if str not found in hash table */ static int hash_nlookup(LHASH *hash_table, char *str, char *astr, size_t strlen) { struct hash_node node; struct hash_node *p; node.data = str; p = (struct hash_node *) lh_retrieve(hash_table,(void*) &node); if (p) { /* found in lhash table */ strncpy(astr, p->hash, strlen); return 1; } else { /* not found in lhash table */ return 0; } }
static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) { ERR_STRING_DATA *p; LHASH *hash; err_fns_check(); hash = ERRFN(err_get)(0); if (!hash) return NULL; CRYPTO_r_lock(CRYPTO_LOCK_ERR); p = (ERR_STRING_DATA *)lh_retrieve(hash, d); CRYPTO_r_unlock(CRYPTO_LOCK_ERR); return p; }
/* * lookup str in hash table and copy found hash into astr * return non-zero if found, 0 if str not found in hash table */ static int hash_lookup(LHASH *hash_table, char *str, char *astr) { struct hash_node node; struct hash_node *p; memset(&node, 0, sizeof(struct hash_node)); node.data = str; p = (struct hash_node *) lh_retrieve(hash_table,(void*) &node); if (p) { /* found in lhash table */ strcpy(astr, p->hash); return 1; } else { /* not found in lhash table */ return 0; } }
static ERR_STATE *int_thread_get_item(const ERR_STATE *d) { ERR_STATE *p; LHASH *hash; err_fns_check(); hash = ERRFN(thread_get)(0); if (!hash) return NULL; CRYPTO_r_lock(CRYPTO_LOCK_ERR); p = (ERR_STATE *)lh_retrieve(hash, d); CRYPTO_r_unlock(CRYPTO_LOCK_ERR); ERRFN(thread_release)(&hash); return p; }
int OBJ_sn2nid(const char *s) { ASN1_OBJECT o,*oo= &o,**op; ADDED_OBJ ad,*adp; o.sn=s; if (added != NULL) { ad.type=ADDED_SNAME; ad.obj= &o; adp=(ADDED_OBJ *)lh_retrieve(added,&ad); if (adp != NULL) return (adp->obj->nid); } op=(ASN1_OBJECT **)OBJ_bsearch((char *)&oo,(char *)sn_objs,NUM_SN, sizeof(ASN1_OBJECT *),sn_cmp); if (op == NULL) return(NID_undef); return((*op)->nid); }
const char *ERR_func_error_string(unsigned long e) { ERR_STRING_DATA d,*p=NULL; unsigned long l,f; l=ERR_GET_LIB(e); f=ERR_GET_FUNC(e); CRYPTO_r_lock(CRYPTO_LOCK_ERR_HASH); if (error_hash != NULL) { d.error=ERR_PACK(l,f,0); p=(ERR_STRING_DATA *)lh_retrieve(error_hash,&d); } CRYPTO_r_unlock(CRYPTO_LOCK_ERR_HASH); return((p == NULL)?NULL:p->string); }
int TXT_DB_insert(TXT_DB *db, char **row) { int i; char **r; for (i=0; i<db->num_fields; i++) { if (db->index[i] != NULL) { if ((db->qual[i] != NULL) && (db->qual[i](row) == 0)) continue; r=(char **)lh_retrieve(db->index[i],row); if (r != NULL) { db->error=DB_ERROR_INDEX_CLASH; db->arg1=i; db->arg_row=r; goto err; } } } /* We have passed the index checks, now just append and insert */ if (!sk_push(db->data,(char *)row)) { db->error=DB_ERROR_MALLOC; goto err; } for (i=0; i<db->num_fields; i++) { if (db->index[i] != NULL) { if ((db->qual[i] != NULL) && (db->qual[i](row) == 0)) continue; lh_insert(db->index[i],row); } } return(1); err: return(0); }
int OBJ_obj2nid(const ASN1_OBJECT *a) { ASN1_OBJECT **op; ADDED_OBJ ad,*adp; if (a == NULL) return(NID_undef); if (a->nid != 0) return(a->nid); if (added != NULL) { ad.type=ADDED_DATA; ad.obj=(ASN1_OBJECT *)a; /* XXX: ugly but harmless */ adp=(ADDED_OBJ *)lh_retrieve(added,&ad); if (adp != NULL) return (adp->obj->nid); } op=(ASN1_OBJECT **)OBJ_bsearch((const char *)&a,(const char *)obj_objs, NUM_OBJ, sizeof(ASN1_OBJECT *),obj_cmp); if (op == NULL) return(NID_undef); return((*op)->nid); }
/* * Store a pathname in the pathname store. */ char* Pathstore_path(Pathstore *store, char *pathname, int discardDuplicateFiles) { char chksum1[CHKSUMFILE_SIZE]; struct unixfilesystem *fs = (struct unixfilesystem *) (store->fshandle); numstores++; PathstoreElement *entry; /* For 1 file case * No hash table or checksum */ if(numfilesseen == 0){ numfilesseen++; entry = malloc(sizeof(PathstoreElement));; entry->pathname = strdup(pathname); if (entry->pathname == NULL) { free(entry); printf("memory problem 2\n"); return NULL; } store->elementList = entry; return entry->pathname; } /* For >1 file * Use hash table and checksums */ _LHASH *hashtable; // if we are going from 1 file case to 2 files if(numfilesseen == 1){ numfilesseen++; //store first entry somewhere PathstoreElement *temp = store->elementList; //calc checksum for file 1 path int err = chksumfile_bypathname(fs, temp->pathname, chksum1); if (err < 0) { fprintf(stderr,"Can't checksum path %s\n", pathname); return 0; } memcpy(temp->chksum, chksum1, CHKSUMFILE_SIZE); //initialize hash table store->elementList = lh_new(HashCallback, CompareCallback); hashtable = (_LHASH*) (store->elementList); //seed hash table with first entry lh_insert(hashtable,(char *) temp); if (lh_error(hashtable)) { free(temp); printf("hash problem\n"); return NULL; } }else{ hashtable = (_LHASH*) (store->elementList); } // calc checksum of pathname int err = chksumfile_bypathname(fs, pathname, chksum1); if (err < 0) { fprintf(stderr,"Can't checksum path %s\n", pathname); return 0; } PathstoreElement key; memcpy(key.chksum, chksum1, CHKSUMFILE_SIZE); // if discardDups, see if its in table, if it is, return if (discardDuplicateFiles) { entry = lh_retrieve(hashtable, (char *) &key); if(entry != NULL){ numdups++; return NULL; } } // otherwise add entry = malloc(sizeof(PathstoreElement)); if (entry == NULL) { printf("memory problem\n"); return NULL; } memcpy(entry->chksum, chksum1, CHKSUMFILE_SIZE); entry->pathname = strdup(pathname); if (entry->pathname == NULL) { free(entry); printf("memory problem 2\n"); return NULL; } lh_insert(hashtable,(char *) entry); if (lh_error(hashtable)) { free(entry); printf("hash problem\n"); return NULL; } return entry->pathname; }
void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, int before_p) { MEM *m,*mm; APP_INFO tmp,*amim; switch(before_p & 127) { case 0: break; case 1: if (addr == NULL) break; if (is_MemCheck_on()) { MemCheck_off(); /* make sure we hold MALLOC2 lock */ if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL) { OPENSSL_free(addr); MemCheck_on(); /* release MALLOC2 lock * if num_disabled drops to 0 */ return; } if (mh == NULL) { if ((mh=lh_new(mem_hash, mem_cmp)) == NULL) { OPENSSL_free(addr); OPENSSL_free(m); addr=NULL; goto err; } } m->addr=addr; m->file=file; m->line=line; m->num=num; if (options & V_CRYPTO_MDEBUG_THREAD) m->thread=CRYPTO_thread_id(); else m->thread=0; if (order == break_order_num) { /* BREAK HERE */ m->order=order; } m->order=order++; #ifdef LEVITTE_DEBUG_MEM fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n", m->order, (before_p & 128) ? '*' : '+', m->addr, m->num); #endif if (options & V_CRYPTO_MDEBUG_TIME) m->time=time(NULL); else m->time=0; tmp.thread=CRYPTO_thread_id(); m->app_info=NULL; if (amih != NULL && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL) { m->app_info = amim; amim->references++; } if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL) { /* Not good, but don't sweat it */ if (mm->app_info != NULL) { mm->app_info->references--; } OPENSSL_free(mm); } err: MemCheck_on(); /* release MALLOC2 lock * if num_disabled drops to 0 */ } break; } return; }
int main(int argc, char **argv) { _LHASH *lh; struct dummy_lhash dummy_lh = {NULL}; unsigned i; CRYPTO_library_init(); lh = lh_new(NULL, NULL); if (lh == NULL) { return 1; } for (i = 0; i < 100000; i++) { unsigned action; char *s, *s1, *s2; if (dummy_lh_num_items(&dummy_lh) != lh_num_items(lh)) { fprintf(stderr, "Length mismatch\n"); return 1; } action = rand() % 3; switch (action) { case 0: s = rand_string(); s1 = (char *)lh_retrieve(lh, s); s2 = dummy_lh_retrieve(&dummy_lh, s); if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) { fprintf(stderr, "lh_retrieve failure\n"); abort(); } free(s); break; case 1: s = rand_string(); lh_insert(lh, (void **)&s1, s); dummy_lh_insert(&dummy_lh, &s2, strdup(s)); if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) { fprintf(stderr, "lh_insert failure\n"); abort(); } if (s1) { free(s1); } if (s2) { free(s2); } break; case 2: s = rand_string(); s1 = lh_delete(lh, s); s2 = dummy_lh_delete(&dummy_lh, s); if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) { fprintf(stderr, "lh_insert failure\n"); abort(); } if (s1) { free(s1); } if (s2) { free(s2); } free(s); break; default: abort(); } } lh_doall(lh, free); lh_free(lh); dummy_lh_free(&dummy_lh); printf("PASS\n"); return 0; }
static int do_cmd(LHASH *prog, int argc, char *argv[]) { FUNCTION f,*fp; int i,ret=1,tp,nl; if ((argc <= 0) || (argv[0] == NULL)) { ret=0; goto end; } f.name=argv[0]; fp=(FUNCTION *)lh_retrieve(prog,&f); if (fp != NULL) { ret=fp->func(argc,argv); } else if ((strncmp(argv[0],"no-",3)) == 0) { BIO *bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); bio_stdout = BIO_push(tmpbio, bio_stdout); } #endif f.name=argv[0]+3; ret = (lh_retrieve(prog,&f) != NULL); if (!ret) BIO_printf(bio_stdout, "%s\n", argv[0]); else BIO_printf(bio_stdout, "%s\n", argv[0]+3); BIO_free_all(bio_stdout); goto end; } else if ((strcmp(argv[0],"quit") == 0) || (strcmp(argv[0],"q") == 0) || (strcmp(argv[0],"exit") == 0) || (strcmp(argv[0],"bye") == 0)) { ret= -1; goto end; } else if ((strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0) || (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) || (strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0)) { int list_type; BIO *bio_stdout; if (strcmp(argv[0],LIST_STANDARD_COMMANDS) == 0) list_type = FUNC_TYPE_GENERAL; else if (strcmp(argv[0],LIST_MESSAGE_DIGEST_COMMANDS) == 0) list_type = FUNC_TYPE_MD; else /* strcmp(argv[0],LIST_CIPHER_COMMANDS) == 0 */ list_type = FUNC_TYPE_CIPHER; bio_stdout = BIO_new_fp(stdout,BIO_NOCLOSE); #ifdef OPENSSL_SYS_VMS { BIO *tmpbio = BIO_new(BIO_f_linebuffer()); bio_stdout = BIO_push(tmpbio, bio_stdout); } #endif for (fp=functions; fp->name != NULL; fp++) if (fp->type == list_type) BIO_printf(bio_stdout, "%s\n", fp->name); BIO_free_all(bio_stdout); ret=0; goto end; } else { BIO_printf(bio_err,"openssl:Error: '%s' is an invalid command.\n", argv[0]); BIO_printf(bio_err, "\nStandard commands"); i=0; tp=0; for (fp=functions; fp->name != NULL; fp++) { nl=0; if (((i++) % 5) == 0) { BIO_printf(bio_err,"\n"); nl=1; } if (fp->type != tp) { tp=fp->type; if (!nl) BIO_printf(bio_err,"\n"); if (tp == FUNC_TYPE_MD) { i=1; BIO_printf(bio_err, "\nMessage Digest commands (see the `dgst' command for more details)\n"); } else if (tp == FUNC_TYPE_CIPHER) { i=1; BIO_printf(bio_err,"\nCipher commands (see the `enc' command for more details)\n"); } } BIO_printf(bio_err,"%-15s",fp->name); } BIO_printf(bio_err,"\n\n"); ret=0; } end: return(ret); }
int openssl_main(int Argc, char *Argv[]) #endif { ARGS arg; #define PROG_NAME_SIZE 39 char pname[PROG_NAME_SIZE+1]; FUNCTION f,*fp; MS_STATIC const char *prompt; MS_STATIC char buf[1024]; char *to_free=NULL; int n,i,ret=0; int argc; char **argv,*p; LHASH *prog=NULL; long errline; arg.data=NULL; arg.count=0; if (bio_err == NULL) if ((bio_err=BIO_new(BIO_s_file())) != NULL) #ifdef SYMBIAN BIO_set_fp(bio_err,fp_stderr,BIO_NOCLOSE|BIO_FP_TEXT); #else BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT); #endif if (getenv("OPENSSL_DEBUG_MEMORY") != NULL) /* if not defined, use compiled-in library defaults */ { if (!(0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off"))) { CRYPTO_malloc_debug_init(); CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); } else { /* OPENSSL_DEBUG_MEMORY=off */ CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); } } CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); #if 0 if (getenv("OPENSSL_DEBUG_LOCKING") != NULL) #endif { CRYPTO_set_locking_callback(lock_dbg_cb); } apps_startup(); /* Lets load up our environment a little */ p=getenv("OPENSSL_CONF"); if (p == NULL) p=getenv("SSLEAY_CONF"); if (p == NULL) p=to_free=make_config_name(); default_config_file=p; config=NCONF_new(NULL); i=NCONF_load(config,p,&errline); if (i == 0) { NCONF_free(config); config = NULL; ERR_clear_error(); } prog=prog_init(); /* first check the program name */ program_name(Argv[0],pname,sizeof pname); f.name=pname; fp=(FUNCTION *)lh_retrieve(prog,&f); if (fp != NULL) { Argv[0]=pname; ret=fp->func(Argc,Argv); goto end; } /* ok, now check that there are not arguments, if there are, * run with them, shifting the ssleay off the front */ if (Argc != 1) { Argc--; Argv++; ret=do_cmd(prog,Argc,Argv); if (ret < 0) ret=0; goto end; } /* ok, lets enter the old 'OpenSSL>' mode */ for (;;) { ret=0; p=buf; n=sizeof buf; i=0; for (;;) { p[0]='\0'; if (i++) prompt=">"; else prompt="OpenSSL> "; #ifndef SYMBIAN fputs(prompt,stdout); fflush(stdout); fgets(p,n,stdin); #else fputs(prompt,stdout); fflush(stdout); fgets(p,n,stdin); #endif if (p[0] == '\0') goto end; i=strlen(p); if (i <= 1) break; if (p[i-2] != '\\') break; i-=2; p+=i; n-=i; } if (!chopup_args(&arg,buf,&argc,&argv)) break; ret=do_cmd(prog,argc,argv); if (ret < 0) { ret=0; goto end; } if (ret != 0) BIO_printf(bio_err,"error in %s\n",argv[0]); (void)BIO_flush(bio_err); } BIO_printf(bio_err,"bad exit\n"); ret=1; end: if (to_free) OPENSSL_free(to_free); if (config != NULL) { NCONF_free(config); config=NULL; } if (prog != NULL) lh_free(prog); if (arg.data != NULL) OPENSSL_free(arg.data); apps_shutdown(); CRYPTO_mem_leaks(bio_err); if (bio_err != NULL) { BIO_free(bio_err); bio_err=NULL; } return ret; // OPENSSL_EXIT(ret); }
ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, int l) #endif { ENGINE *ret = NULL; ENGINE_PILE tmplate, *fnd=NULL; int initres, loop = 0; if(!(*table)) { #ifdef ENGINE_TABLE_DEBUG fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing " "registered!\n", f, l, nid); #endif return NULL; } CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); /* Check again inside the lock otherwise we could race against cleanup * operations. But don't worry about a fprintf(stderr). */ if(!int_table_check(table, 0)) goto end; tmplate.nid = nid; fnd = lh_retrieve(&(*table)->piles, &tmplate); if(!fnd) goto end; if(fnd->funct && engine_unlocked_init(fnd->funct)) { #ifdef ENGINE_TABLE_DEBUG fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id); #endif ret = fnd->funct; goto end; } if(fnd->uptodate) { ret = fnd->funct; goto end; } trynext: ret = sk_ENGINE_value(fnd->sk, loop++); if(!ret) { #ifdef ENGINE_TABLE_DEBUG fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " "registered implementations would initialise\n", f, l, nid); #endif goto end; } /* Try to initialise the ENGINE? */ if((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT)) initres = engine_unlocked_init(ret); else initres = 0; if(initres) { /* Update 'funct' */ if((fnd->funct != ret) && engine_unlocked_init(ret)) { /* If there was a previous default we release it. */ if(fnd->funct) engine_unlocked_finish(fnd->funct, 0); fnd->funct = ret; #ifdef ENGINE_TABLE_DEBUG fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, " "setting default to '%s'\n", f, l, nid, ret->id); #endif } #ifdef ENGINE_TABLE_DEBUG fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " "newly initialised '%s'\n", f, l, nid, ret->id); #endif goto end; } goto trynext; end: /* If it failed, it is unlikely to succeed again until some future * registrations have taken place. In all cases, we cache. */ if(fnd) fnd->uptodate = 1; #ifdef ENGINE_TABLE_DEBUG if(ret) fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " "ENGINE '%s'\n", f, l, nid, ret->id); else fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " "'no matching ENGINE'\n", f, l, nid); #endif CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); /* Whatever happened, any failed init()s are not failures in this * context, so clear our error state. */ ERR_clear_error(); return ret; }
ERR_STATE *ERR_get_state(void) { static ERR_STATE fallback; ERR_STATE *ret=NULL,tmp,*tmpp=NULL; int thread_state_exists; int i; unsigned long pid; pid=(unsigned long)CRYPTO_thread_id(); CRYPTO_w_lock(CRYPTO_LOCK_ERR); if (thread_hash != NULL) { tmp.pid=pid; ret=(ERR_STATE *)lh_retrieve(thread_hash,&tmp); } CRYPTO_w_unlock(CRYPTO_LOCK_ERR); /* ret == the error state, if NULL, make a new one */ if (ret == NULL) { ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE)); if (ret == NULL) return(&fallback); ret->pid=pid; ret->top=0; ret->bottom=0; for (i=0; i<ERR_NUM_ERRORS; i++) { ret->err_data[i]=NULL; ret->err_data_flags[i]=0; } CRYPTO_w_lock(CRYPTO_LOCK_ERR); /* no entry yet in thread_hash for current thread - * thus, it may have changed since we last looked at it */ if (thread_hash == NULL) thread_hash = lh_new(pid_hash, pid_cmp); if (thread_hash == NULL) thread_state_exists = 0; /* allocation error */ else { tmpp=(ERR_STATE *)lh_insert(thread_hash,ret); thread_state_exists = 1; } CRYPTO_w_unlock(CRYPTO_LOCK_ERR); if (!thread_state_exists) { ERR_STATE_free(ret); /* could not insert it */ return(&fallback); } if (tmpp != NULL) /* old entry - should not happen */ { ERR_STATE_free(tmpp); } } return(ret); }