crypto/x509/x509_vfy.c:246: error: NULL_DEREFERENCE
  pointer `sktmp` last assigned on line 170 could be null and is dereferenced by call to `sk_delete_ptr()` at line 246, column 11.
Showing all 75 steps of the trace


crypto/x509/x509_vfy.c:162:1: start of procedure X509_verify_cert()
160.   	}
161.   
162. > int X509_verify_cert(X509_STORE_CTX *ctx)
163.   	{
164.   	X509 *x,*xtmp,*chain_ss=NULL;

crypto/x509/x509_vfy.c:164:2: 
162.   int X509_verify_cert(X509_STORE_CTX *ctx)
163.   	{
164. > 	X509 *x,*xtmp,*chain_ss=NULL;
165.   	int bad_chain = 0;
166.   	X509_VERIFY_PARAM *param = ctx->param;

crypto/x509/x509_vfy.c:165:2: 
163.   	{
164.   	X509 *x,*xtmp,*chain_ss=NULL;
165. > 	int bad_chain = 0;
166.   	X509_VERIFY_PARAM *param = ctx->param;
167.   	int depth,i,ok=0;

crypto/x509/x509_vfy.c:166:2: 
164.   	X509 *x,*xtmp,*chain_ss=NULL;
165.   	int bad_chain = 0;
166. > 	X509_VERIFY_PARAM *param = ctx->param;
167.   	int depth,i,ok=0;
168.   	int num;

crypto/x509/x509_vfy.c:167:2: 
165.   	int bad_chain = 0;
166.   	X509_VERIFY_PARAM *param = ctx->param;
167. > 	int depth,i,ok=0;
168.   	int num;
169.   	int (*cb)(int xok,X509_STORE_CTX *xctx);

crypto/x509/x509_vfy.c:170:2: 
168.   	int num;
169.   	int (*cb)(int xok,X509_STORE_CTX *xctx);
170. > 	STACK_OF(X509) *sktmp=NULL;
171.   	if (ctx->cert == NULL)
172.   		{

crypto/x509/x509_vfy.c:171:6: Taking false branch
169.   	int (*cb)(int xok,X509_STORE_CTX *xctx);
170.   	STACK_OF(X509) *sktmp=NULL;
171.   	if (ctx->cert == NULL)
            ^
172.   		{
173.   		X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);

crypto/x509/x509_vfy.c:177:2: 
175.   		}
176.   
177. > 	cb=ctx->verify_cb;
178.   
179.   	/* first we make sure the chain we are going to build is

crypto/x509/x509_vfy.c:181:6: Taking false branch
179.   	/* first we make sure the chain we are going to build is
180.   	 * present and that the first entry is in place */
181.   	if (ctx->chain == NULL)
            ^
182.   		{
183.   		if (	((ctx->chain=sk_X509_new_null()) == NULL) ||

crypto/x509/x509_vfy.c:194:6: Taking false branch
192.   
193.   	/* We use a temporary STACK so we can chop and hack at it */
194.   	if (ctx->untrusted != NULL
            ^
195.   	    && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)
196.   		{

crypto/x509/x509_vfy.c:201:6: Condition is true
199.   		}
200.   
201.   	num=sk_X509_num(ctx->chain);
            ^
202.   	x=sk_X509_value(ctx->chain,num-1);
203.   	depth=param->depth;

crypto/x509/x509_vfy.c:201:2: 
199.   		}
200.   
201. > 	num=sk_X509_num(ctx->chain);
202.   	x=sk_X509_value(ctx->chain,num-1);
203.   	depth=param->depth;

crypto/stack/stack.c:294:1: start of procedure sk_num()
  292.   	}
  293.   
  294. > int sk_num(const _STACK *st)
  295.   {
  296.   	if(st == NULL) return -1;

crypto/stack/stack.c:296:5: Taking false branch
  294.   int sk_num(const _STACK *st)
  295.   {
  296.   	if(st == NULL) return -1;
             ^
  297.   	return st->num;
  298.   }

crypto/stack/stack.c:297:2: 
  295.   {
  296.   	if(st == NULL) return -1;
  297. > 	return st->num;
  298.   }
  299.   

crypto/stack/stack.c:298:1: return from a call to sk_num
  296.   	if(st == NULL) return -1;
  297.   	return st->num;
  298. > }
  299.   
  300.   void *sk_value(const _STACK *st, int i)

crypto/x509/x509_vfy.c:202:4: Condition is true
200.   
201.   	num=sk_X509_num(ctx->chain);
202.   	x=sk_X509_value(ctx->chain,num-1);
          ^
203.   	depth=param->depth;
204.   

crypto/x509/x509_vfy.c:202:2: 
200.   
201.   	num=sk_X509_num(ctx->chain);
202. > 	x=sk_X509_value(ctx->chain,num-1);
203.   	depth=param->depth;
204.   

crypto/stack/stack.c:300:1: start of procedure sk_value()
  298.   }
  299.   
  300. > void *sk_value(const _STACK *st, int i)
  301.   {
  302.   	if(!st || (i < 0) || (i >= st->num)) return NULL;

crypto/stack/stack.c:302:6: Taking false branch
  300.   void *sk_value(const _STACK *st, int i)
  301.   {
  302.   	if(!st || (i < 0) || (i >= st->num)) return NULL;
              ^
  303.   	return st->data[i];
  304.   }

crypto/stack/stack.c:302:13: Taking false branch
  300.   void *sk_value(const _STACK *st, int i)
  301.   {
  302.   	if(!st || (i < 0) || (i >= st->num)) return NULL;
                     ^
  303.   	return st->data[i];
  304.   }

crypto/stack/stack.c:302:24: Taking false branch
  300.   void *sk_value(const _STACK *st, int i)
  301.   {
  302.   	if(!st || (i < 0) || (i >= st->num)) return NULL;
                                ^
  303.   	return st->data[i];
  304.   }

crypto/stack/stack.c:303:2: 
  301.   {
  302.   	if(!st || (i < 0) || (i >= st->num)) return NULL;
  303. > 	return st->data[i];
  304.   }
  305.   

crypto/stack/stack.c:304:1: return from a call to sk_value
  302.   	if(!st || (i < 0) || (i >= st->num)) return NULL;
  303.   	return st->data[i];
  304. > }
  305.   
  306.   void *sk_set(_STACK *st, int i, void *value)

crypto/x509/x509_vfy.c:203:2: 
201.   	num=sk_X509_num(ctx->chain);
202.   	x=sk_X509_value(ctx->chain,num-1);
203. > 	depth=param->depth;
204.   
205.   

crypto/x509/x509_vfy.c:256:3: Loop condition is true. Entering loop body
254.   			}
255.   		break;
256.   		}
         ^
257.   
258.   	/* at this point, chain should contain a list of untrusted

crypto/x509/x509_vfy.c:209:7: Taking false branch
207.   		{
208.   		/* If we have enough, we break */
209.   		if (depth < num) break; /* FIXME: If this happens, we should take
             ^
210.   		                         * note of it and, if appropriate, use the
211.   		                         * X509_V_ERR_CERT_CHAIN_TOO_LONG error

crypto/x509/x509_vfy.c:216:7: 
214.   
215.   		/* If we are self signed, we break */
216. > 		if (cert_self_signed(x))
217.   			break;
218.   		/* If asked see if we can find issuer in trusted store first */

crypto/x509/x509_vfy.c:153:1: start of procedure cert_self_signed()
  151.   #endif
  152.   /* Return 1 is a certificate is self signed */
  153. > static int cert_self_signed(X509 *x)
  154.   	{
  155.   	X509_check_purpose(x, -1, 0);

crypto/x509/x509_vfy.c:155:2: Skipping X509_check_purpose(): empty list of specs
  153.   static int cert_self_signed(X509 *x)
  154.   	{
  155.   	X509_check_purpose(x, -1, 0);
          ^
  156.   	if (x->ex_flags & EXFLAG_SS)
  157.   		return 1;

crypto/x509/x509_vfy.c:156:6: Taking false branch
  154.   	{
  155.   	X509_check_purpose(x, -1, 0);
  156.   	if (x->ex_flags & EXFLAG_SS)
              ^
  157.   		return 1;
  158.   	else

crypto/x509/x509_vfy.c:159:3: 
  157.   		return 1;
  158.   	else
  159. > 		return 0;
  160.   	}
  161.   

crypto/x509/x509_vfy.c:160:2: return from a call to cert_self_signed
  158.   	else
  159.   		return 0;
  160.   	}
          ^
  161.   
  162.   int X509_verify_cert(X509_STORE_CTX *ctx)

crypto/x509/x509_vfy.c:216:7: Taking false branch
214.   
215.   		/* If we are self signed, we break */
216.   		if (cert_self_signed(x))
             ^
217.   			break;
218.   		/* If asked see if we can find issuer in trusted store first */

crypto/x509/x509_vfy.c:219:7: Taking true branch
217.   			break;
218.   		/* If asked see if we can find issuer in trusted store first */
219.   		if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
             ^
220.   			{
221.   			ok = ctx->get_issuer(&xtmp, ctx, x);

crypto/x509/x509_vfy.c:221:4: Skipping __function_pointer__(): unresolved function pointer
219.   		if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
220.   			{
221.   			ok = ctx->get_issuer(&xtmp, ctx, x);
          ^
222.   			if (ok < 0)
223.   				return ok;

crypto/x509/x509_vfy.c:222:8: Taking false branch
220.   			{
221.   			ok = ctx->get_issuer(&xtmp, ctx, x);
222.   			if (ok < 0)
              ^
223.   				return ok;
224.   			/* If successful for now free up cert so it

crypto/x509/x509_vfy.c:227:8: Taking false branch
225.   			 * will be picked up again later.
226.   			 */
227.   			if (ok > 0)
              ^
228.   				{
229.   				X509_free(xtmp);

crypto/x509/x509_vfy.c:235:7: Taking true branch
233.   
234.   		/* If we were passed a cert chain, use it first */
235.   		if (ctx->untrusted != NULL)
             ^
236.   			{
237.   			xtmp=find_issuer(ctx, sktmp,x);

crypto/x509/x509_vfy.c:237:4: Skipping find_issuer(): empty list of specs
235.   		if (ctx->untrusted != NULL)
236.   			{
237.   			xtmp=find_issuer(ctx, sktmp,x);
          ^
238.   			if (xtmp != NULL)
239.   				{

crypto/x509/x509_vfy.c:238:8: Taking true branch
236.   			{
237.   			xtmp=find_issuer(ctx, sktmp,x);
238.   			if (xtmp != NULL)
              ^
239.   				{
240.   				if (!sk_X509_push(ctx->chain,xtmp))

crypto/x509/x509_vfy.c:240:10: Condition is true
238.   			if (xtmp != NULL)
239.   				{
240.   				if (!sk_X509_push(ctx->chain,xtmp))
                ^
241.   					{
242.   					X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);

crypto/x509/x509_vfy.c:240:10: Condition is true
238.   			if (xtmp != NULL)
239.   				{
240.   				if (!sk_X509_push(ctx->chain,xtmp))
                ^
241.   					{
242.   					X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);

crypto/stack/stack.c:244:1: start of procedure sk_push()
  242.   	}
  243.   
  244. > int sk_push(_STACK *st, void *data)
  245.   	{
  246.   	return(sk_insert(st,data,st->num));

crypto/stack/stack.c:246:2: Skipping sk_insert(): empty list of specs
  244.   int sk_push(_STACK *st, void *data)
  245.   	{
  246.   	return(sk_insert(st,data,st->num));
          ^
  247.   	}
  248.   

crypto/stack/stack.c:247:2: return from a call to sk_push
  245.   	{
  246.   	return(sk_insert(st,data,st->num));
  247.   	}
          ^
  248.   
  249.   int sk_unshift(_STACK *st, void *data)

crypto/x509/x509_vfy.c:240:10: Taking false branch
238.   			if (xtmp != NULL)
239.   				{
240.   				if (!sk_X509_push(ctx->chain,xtmp))
                ^
241.   					{
242.   					X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);

crypto/x509/x509_vfy.c:245:5: 
243.   					goto end;
244.   					}
245. > 				CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
246.   				(void)sk_X509_delete_ptr(sktmp,xtmp);
247.   				ctx->last_untrusted++;

crypto/lock.c:472:1: start of procedure CRYPTO_add_lock()
  470.   	}
  471.   
  472. > int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
  473.   	     int line)
  474.   	{

crypto/lock.c:475:2: 
  473.   	     int line)
  474.   	{
  475. > 	int ret = 0;
  476.   
  477.   	if (add_lock_callback != NULL)

crypto/lock.c:477:6: Taking false branch
  475.   	int ret = 0;
  476.   
  477.   	if (add_lock_callback != NULL)
              ^
  478.   		{
  479.   #ifdef LOCK_DEBUG

crypto/lock.c:497:3: 
  495.   	else
  496.   		{
  497. > 		CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line);
  498.   
  499.   		ret= *pointer+amount;

crypto/lock.c:426:1: start of procedure CRYPTO_lock()
    424.   	}
    425.   
    426. > void CRYPTO_lock(int mode, int type, const char *file, int line)
    427.   	{
    428.   #ifdef LOCK_DEBUG

crypto/lock.c:453:6: Taking false branch
    451.   		}
    452.   #endif
    453.   	if (type < 0)
                ^
    454.   		{
    455.   		if (dynlock_lock_callback != NULL)

crypto/lock.c:468:7: Taking false branch
    466.   		}
    467.   	else
    468.   		if (locking_callback != NULL)
                 ^
    469.   			locking_callback(mode,type,file,line);
    470.   	}

crypto/lock.c:453:2: 
    451.   		}
    452.   #endif
    453. > 	if (type < 0)
    454.   		{
    455.   		if (dynlock_lock_callback != NULL)

crypto/lock.c:470:2: return from a call to CRYPTO_lock
    468.   		if (locking_callback != NULL)
    469.   			locking_callback(mode,type,file,line);
    470.   	}
            ^
    471.   
    472.   int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,

crypto/lock.c:499:3: 
  497.   		CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line);
  498.   
  499. > 		ret= *pointer+amount;
  500.   #ifdef LOCK_DEBUG
  501.   		{

crypto/lock.c:511:3: 
  509.   		}
  510.   #endif
  511. > 		*pointer=ret;
  512.   		CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
  513.   		}

crypto/lock.c:512:3: 
  510.   #endif
  511.   		*pointer=ret;
  512. > 		CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
  513.   		}
  514.   	return(ret);

crypto/lock.c:426:1: start of procedure CRYPTO_lock()
    424.   	}
    425.   
    426. > void CRYPTO_lock(int mode, int type, const char *file, int line)
    427.   	{
    428.   #ifdef LOCK_DEBUG

crypto/lock.c:453:6: Taking false branch
    451.   		}
    452.   #endif
    453.   	if (type < 0)
                ^
    454.   		{
    455.   		if (dynlock_lock_callback != NULL)

crypto/lock.c:468:7: Taking false branch
    466.   		}
    467.   	else
    468.   		if (locking_callback != NULL)
                 ^
    469.   			locking_callback(mode,type,file,line);
    470.   	}

crypto/lock.c:453:2: 
    451.   		}
    452.   #endif
    453. > 	if (type < 0)
    454.   		{
    455.   		if (dynlock_lock_callback != NULL)

crypto/lock.c:470:2: return from a call to CRYPTO_lock
    468.   		if (locking_callback != NULL)
    469.   			locking_callback(mode,type,file,line);
    470.   	}
            ^
    471.   
    472.   int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,

crypto/lock.c:514:2: 
  512.   		CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
  513.   		}
  514. > 	return(ret);
  515.   	}
  516.   

crypto/lock.c:515:2: return from a call to CRYPTO_add_lock
  513.   		}
  514.   	return(ret);
  515.   	}
          ^
  516.   
  517.   const char *CRYPTO_get_lock_name(int type)

crypto/x509/x509_vfy.c:246:11: Condition is true
244.   					}
245.   				CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
246.   				(void)sk_X509_delete_ptr(sktmp,xtmp);
                 ^
247.   				ctx->last_untrusted++;
248.   				x=xtmp;

crypto/x509/x509_vfy.c:246:11: Condition is true
244.   					}
245.   				CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
246.   				(void)sk_X509_delete_ptr(sktmp,xtmp);
                 ^
247.   				ctx->last_untrusted++;
248.   				x=xtmp;

crypto/stack/stack.c:180:1: start of procedure sk_delete_ptr()
  178.   	}
  179.   
  180. > void *sk_delete_ptr(_STACK *st, void *p)
  181.   	{
  182.   	int i;

crypto/stack/stack.c:184:7: 
  182.   	int i;
  183.   
  184. > 	for (i=0; i<st->num; i++)
  185.   		if (st->data[i] == p)
  186.   			return(sk_delete(st,i));

crypto/stack/stack.c:184:12: Loop condition is true. Entering loop body
  182.   	int i;
  183.   
  184.   	for (i=0; i<st->num; i++)
                    ^
  185.   		if (st->data[i] == p)
  186.   			return(sk_delete(st,i));

crypto/stack/stack.c:185:7: Taking false branch
  183.   
  184.   	for (i=0; i<st->num; i++)
  185.   		if (st->data[i] == p)
               ^
  186.   			return(sk_delete(st,i));
  187.   	return(NULL);

crypto/stack/stack.c:184:23: 
  182.   	int i;
  183.   
  184. > 	for (i=0; i<st->num; i++)
  185.   		if (st->data[i] == p)
  186.   			return(sk_delete(st,i));

crypto/stack/stack.c:184:12: 
  182.   	int i;
  183.   
  184. > 	for (i=0; i<st->num; i++)
  185.   		if (st->data[i] == p)
  186.   			return(sk_delete(st,i));

int X509_verify_cert(X509_STORE_CTX *ctx)
	{
	X509 *x,*xtmp,*chain_ss=NULL;
	int bad_chain = 0;
	X509_VERIFY_PARAM *param = ctx->param;
	int depth,i,ok=0;
	int num;
	int (*cb)(int xok,X509_STORE_CTX *xctx);
	STACK_OF(X509) *sktmp=NULL;
	if (ctx->cert == NULL)
		{
		X509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
		return -1;
		}
	cb=ctx->verify_cb;
	if (ctx->chain == NULL)
		{
		if (	((ctx->chain=sk_X509_new_null()) == NULL) ||
			(!sk_X509_push(ctx->chain,ctx->cert)))
			{
			X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
			goto end;
			}
		CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509);
		ctx->last_untrusted=1;
		}
	if (ctx->untrusted != NULL
	    && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)
		{
		X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
		goto end;
		}
	num=sk_X509_num(ctx->chain);
	x=sk_X509_value(ctx->chain,num-1);
	depth=param->depth;
	for (;;)
		{
		if (depth < num) break;
		if (cert_self_signed(x))
			break;
		if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)
			{
			ok = ctx->get_issuer(&xtmp, ctx, x);
			if (ok < 0)
				return ok;
			if (ok > 0)
				{
				X509_free(xtmp);
				break;
				}
			}
		if (ctx->untrusted != NULL)
			{
			xtmp=find_issuer(ctx, sktmp,x);
			if (xtmp != NULL)
				{
				if (!sk_X509_push(ctx->chain,xtmp))
					{
					X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
					goto end;
					}
				CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
				(void)sk_X509_delete_ptr(sktmp,xtmp);
				ctx->last_untrusted++;
				x=xtmp;
				num++;
				continue;
				}
			}
		break;
		}
	i=sk_X509_num(ctx->chain);
	x=sk_X509_value(ctx->chain,i-1);
	if (cert_self_signed(x))
		{
		if (sk_X509_num(ctx->chain) == 1)
			{
			ok = ctx->get_issuer(&xtmp, ctx, x);
			if ((ok <= 0) || X509_cmp(x, xtmp))
				{
				ctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;
				ctx->current_cert=x;
				ctx->error_depth=i-1;
				if (ok == 1) X509_free(xtmp);
				bad_chain = 1;
				ok=cb(0,ctx);
				if (!ok) goto end;
				}
			else
				{
				X509_free(x);
				x = xtmp;
				(void)sk_X509_set(ctx->chain, i - 1, x);
				ctx->last_untrusted=0;
				}
			}
		else
			{
			chain_ss=sk_X509_pop(ctx->chain);
			ctx->last_untrusted--;
			num--;
			x=sk_X509_value(ctx->chain,num-1);
			}
		}
	for (;;)
		{
		if (depth < num) break;
		if (cert_self_signed(x))
			break;
		ok = ctx->get_issuer(&xtmp, ctx, x);
		if (ok < 0) return ok;
		if (ok == 0) break;
		x = xtmp;
		if (!sk_X509_push(ctx->chain,x))
			{
			X509_free(xtmp);
			X509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);
			return 0;
			}
		num++;
		}
	i = check_trust(ctx);
	if (i == X509_TRUST_REJECTED)
		goto end;
	if (i != X509_TRUST_TRUSTED)
		{
		if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))
			{
			if (ctx->last_untrusted >= num)
				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;
			else
				ctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
			ctx->current_cert=x;
			}
		else
			{
			sk_X509_push(ctx->chain,chain_ss);
			num++;
			ctx->last_untrusted=num;
			ctx->current_cert=chain_ss;
			ctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;
			chain_ss=NULL;
			}
		ctx->error_depth=num-1;
		bad_chain = 1;
		ok=cb(0,ctx);
		if (!ok) goto end;
		}
	ok = check_chain_extensions(ctx);
	if (!ok) goto end;
	ok = check_name_constraints(ctx);
	if (!ok) goto end;
	X509_get_pubkey_parameters(NULL,ctx->chain);
	ok = ctx->check_revocation(ctx);
	if(!ok) goto end;
	if (ctx->verify != NULL)
		ok=ctx->verify(ctx);
	else
		ok=internal_verify(ctx);
	if(!ok) goto end;
#ifndef OPENSSL_NO_RFC3779
	ok = v3_asid_validate_path(ctx);
	if (!ok) goto end;
	ok = v3_addr_validate_path(ctx);
	if (!ok) goto end;
#endif
	if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))
		ok = ctx->check_policy(ctx);
	if(!ok) goto end;
	if (0)
		{
end:
		X509_get_pubkey_parameters(NULL,ctx->chain);
		}
	if (sktmp != NULL) sk_X509_free(sktmp);
	if (chain_ss != NULL) X509_free(chain_ss);
	return ok;
	}
['int X509_verify_cert(X509_STORE_CTX *ctx)\n\t{\n\tX509 *x,*xtmp,*chain_ss=NULL;\n\tint bad_chain = 0;\n\tX509_VERIFY_PARAM *param = ctx->param;\n\tint depth,i,ok=0;\n\tint num;\n\tint (*cb)(int xok,X509_STORE_CTX *xctx);\n\tSTACK_OF(X509) *sktmp=NULL;\n\tif (ctx->cert == NULL)\n\t\t{\n\t\tX509err(X509_F_X509_VERIFY_CERT,X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);\n\t\treturn -1;\n\t\t}\n\tcb=ctx->verify_cb;\n\tif (ctx->chain == NULL)\n\t\t{\n\t\tif (\t((ctx->chain=sk_X509_new_null()) == NULL) ||\n\t\t\t(!sk_X509_push(ctx->chain,ctx->cert)))\n\t\t\t{\n\t\t\tX509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);\n\t\t\tgoto end;\n\t\t\t}\n\t\tCRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509);\n\t\tctx->last_untrusted=1;\n\t\t}\n\tif (ctx->untrusted != NULL\n\t    && (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)\n\t\t{\n\t\tX509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);\n\t\tgoto end;\n\t\t}\n\tnum=sk_X509_num(ctx->chain);\n\tx=sk_X509_value(ctx->chain,num-1);\n\tdepth=param->depth;\n\tfor (;;)\n\t\t{\n\t\tif (depth < num) break;\n\t\tif (cert_self_signed(x))\n\t\t\tbreak;\n\t\tif (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST)\n\t\t\t{\n\t\t\tok = ctx->get_issuer(&xtmp, ctx, x);\n\t\t\tif (ok < 0)\n\t\t\t\treturn ok;\n\t\t\tif (ok > 0)\n\t\t\t\t{\n\t\t\t\tX509_free(xtmp);\n\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\tif (ctx->untrusted != NULL)\n\t\t\t{\n\t\t\txtmp=find_issuer(ctx, sktmp,x);\n\t\t\tif (xtmp != NULL)\n\t\t\t\t{\n\t\t\t\tif (!sk_X509_push(ctx->chain,xtmp))\n\t\t\t\t\t{\n\t\t\t\t\tX509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);\n\t\t\t\t\tgoto end;\n\t\t\t\t\t}\n\t\t\t\tCRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);\n\t\t\t\t(void)sk_X509_delete_ptr(sktmp,xtmp);\n\t\t\t\tctx->last_untrusted++;\n\t\t\t\tx=xtmp;\n\t\t\t\tnum++;\n\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\tbreak;\n\t\t}\n\ti=sk_X509_num(ctx->chain);\n\tx=sk_X509_value(ctx->chain,i-1);\n\tif (cert_self_signed(x))\n\t\t{\n\t\tif (sk_X509_num(ctx->chain) == 1)\n\t\t\t{\n\t\t\tok = ctx->get_issuer(&xtmp, ctx, x);\n\t\t\tif ((ok <= 0) || X509_cmp(x, xtmp))\n\t\t\t\t{\n\t\t\t\tctx->error=X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT;\n\t\t\t\tctx->current_cert=x;\n\t\t\t\tctx->error_depth=i-1;\n\t\t\t\tif (ok == 1) X509_free(xtmp);\n\t\t\t\tbad_chain = 1;\n\t\t\t\tok=cb(0,ctx);\n\t\t\t\tif (!ok) goto end;\n\t\t\t\t}\n\t\t\telse\n\t\t\t\t{\n\t\t\t\tX509_free(x);\n\t\t\t\tx = xtmp;\n\t\t\t\t(void)sk_X509_set(ctx->chain, i - 1, x);\n\t\t\t\tctx->last_untrusted=0;\n\t\t\t\t}\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\tchain_ss=sk_X509_pop(ctx->chain);\n\t\t\tctx->last_untrusted--;\n\t\t\tnum--;\n\t\t\tx=sk_X509_value(ctx->chain,num-1);\n\t\t\t}\n\t\t}\n\tfor (;;)\n\t\t{\n\t\tif (depth < num) break;\n\t\tif (cert_self_signed(x))\n\t\t\tbreak;\n\t\tok = ctx->get_issuer(&xtmp, ctx, x);\n\t\tif (ok < 0) return ok;\n\t\tif (ok == 0) break;\n\t\tx = xtmp;\n\t\tif (!sk_X509_push(ctx->chain,x))\n\t\t\t{\n\t\t\tX509_free(xtmp);\n\t\t\tX509err(X509_F_X509_VERIFY_CERT,ERR_R_MALLOC_FAILURE);\n\t\t\treturn 0;\n\t\t\t}\n\t\tnum++;\n\t\t}\n\ti = check_trust(ctx);\n\tif (i == X509_TRUST_REJECTED)\n\t\tgoto end;\n\tif (i != X509_TRUST_TRUSTED)\n\t\t{\n\t\tif ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss))\n\t\t\t{\n\t\t\tif (ctx->last_untrusted >= num)\n\t\t\t\tctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY;\n\t\t\telse\n\t\t\t\tctx->error=X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;\n\t\t\tctx->current_cert=x;\n\t\t\t}\n\t\telse\n\t\t\t{\n\t\t\tsk_X509_push(ctx->chain,chain_ss);\n\t\t\tnum++;\n\t\t\tctx->last_untrusted=num;\n\t\t\tctx->current_cert=chain_ss;\n\t\t\tctx->error=X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN;\n\t\t\tchain_ss=NULL;\n\t\t\t}\n\t\tctx->error_depth=num-1;\n\t\tbad_chain = 1;\n\t\tok=cb(0,ctx);\n\t\tif (!ok) goto end;\n\t\t}\n\tok = check_chain_extensions(ctx);\n\tif (!ok) goto end;\n\tok = check_name_constraints(ctx);\n\tif (!ok) goto end;\n\tX509_get_pubkey_parameters(NULL,ctx->chain);\n\tok = ctx->check_revocation(ctx);\n\tif(!ok) goto end;\n\tif (ctx->verify != NULL)\n\t\tok=ctx->verify(ctx);\n\telse\n\t\tok=internal_verify(ctx);\n\tif(!ok) goto end;\n#ifndef OPENSSL_NO_RFC3779\n\tok = v3_asid_validate_path(ctx);\n\tif (!ok) goto end;\n\tok = v3_addr_validate_path(ctx);\n\tif (!ok) goto end;\n#endif\n\tif (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK))\n\t\tok = ctx->check_policy(ctx);\n\tif(!ok) goto end;\n\tif (0)\n\t\t{\nend:\n\t\tX509_get_pubkey_parameters(NULL,ctx->chain);\n\t\t}\n\tif (sktmp != NULL) sk_X509_free(sktmp);\n\tif (chain_ss != NULL) X509_free(chain_ss);\n\treturn ok;\n\t}', 'int sk_num(const _STACK *st)\n{\n\tif(st == NULL) return -1;\n\treturn st->num;\n}', 'void *sk_value(const _STACK *st, int i)\n{\n\tif(!st || (i < 0) || (i >= st->num)) return NULL;\n\treturn st->data[i];\n}', 'static int cert_self_signed(X509 *x)\n\t{\n\tX509_check_purpose(x, -1, 0);\n\tif (x->ex_flags & EXFLAG_SS)\n\t\treturn 1;\n\telse\n\t\treturn 0;\n\t}', 'int sk_push(_STACK *st, void *data)\n\t{\n\treturn(sk_insert(st,data,st->num));\n\t}', 'int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,\n\t     int line)\n\t{\n\tint ret = 0;\n\tif (add_lock_callback != NULL)\n\t\t{\n#ifdef LOCK_DEBUG\n\t\tint before= *pointer;\n#endif\n\t\tret=add_lock_callback(pointer,amount,type,file,line);\n#ifdef LOCK_DEBUG\n\t\t{\n\t\tCRYPTO_THREADID id;\n\t\tCRYPTO_THREADID_current(&id);\n\t\tfprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\\n",\n\t\t\tCRYPTO_THREADID_hash(&id), before,amount,ret,\n\t\t\tCRYPTO_get_lock_name(type),\n\t\t\tfile,line);\n\t\t}\n#endif\n\t\t}\n\telse\n\t\t{\n\t\tCRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,file,line);\n\t\tret= *pointer+amount;\n#ifdef LOCK_DEBUG\n\t\t{\n\t\tCRYPTO_THREADID id;\n\t\tCRYPTO_THREADID_current(&id);\n\t\tfprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\\n",\n\t\t\tCRYPTO_THREADID_hash(&id),\n\t\t\t*pointer,amount,ret,\n\t\t\tCRYPTO_get_lock_name(type),\n\t\t\tfile,line);\n\t\t}\n#endif\n\t\t*pointer=ret;\n\t\tCRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);\n\t\t}\n\treturn(ret);\n\t}', 'void CRYPTO_lock(int mode, int type, const char *file, int line)\n\t{\n#ifdef LOCK_DEBUG\n\t\t{\n\t\tCRYPTO_THREADID id;\n\t\tchar *rw_text,*operation_text;\n\t\tif (mode & CRYPTO_LOCK)\n\t\t\toperation_text="lock  ";\n\t\telse if (mode & CRYPTO_UNLOCK)\n\t\t\toperation_text="unlock";\n\t\telse\n\t\t\toperation_text="ERROR ";\n\t\tif (mode & CRYPTO_READ)\n\t\t\trw_text="r";\n\t\telse if (mode & CRYPTO_WRITE)\n\t\t\trw_text="w";\n\t\telse\n\t\t\trw_text="ERROR";\n\t\tCRYPTO_THREADID_current(&id);\n\t\tfprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\\n",\n\t\t\tCRYPTO_THREADID_hash(&id), rw_text, operation_text,\n\t\t\tCRYPTO_get_lock_name(type), file, line);\n\t\t}\n#endif\n\tif (type < 0)\n\t\t{\n\t\tif (dynlock_lock_callback != NULL)\n\t\t\t{\n\t\t\tstruct CRYPTO_dynlock_value *pointer\n\t\t\t\t= CRYPTO_get_dynlock_value(type);\n\t\t\tOPENSSL_assert(pointer != NULL);\n\t\t\tdynlock_lock_callback(mode, pointer, file, line);\n\t\t\tCRYPTO_destroy_dynlockid(type);\n\t\t\t}\n\t\t}\n\telse\n\t\tif (locking_callback != NULL)\n\t\t\tlocking_callback(mode,type,file,line);\n\t}', 'void *sk_delete_ptr(_STACK *st, void *p)\n\t{\n\tint i;\n\tfor (i=0; i<st->num; i++)\n\t\tif (st->data[i] == p)\n\t\t\treturn(sk_delete(st,i));\n\treturn(NULL);\n\t}']