Commit 70cd3c6b authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

Integrate host, email and IP address checks into X509_verify.

Add new verify options to set checks.

(backport from HEAD)
parent db05bc51
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -4,6 +4,10 @@

 Changes between 1.0.1 and 1.0.2 [xx XXX xxxx]

  *) Integrate hostname, email address and IP address checking with certificate
     verification. New verify options supporting checking in opensl utility.
     [Steve Henson]

  *) Fixes and wildcard matching support to hostname and email checking
     functions. Add manual page.
     [Florian Weimer (Red Hat Product Security Team)]
+32 −0
Original line number Diff line number Diff line
@@ -2262,6 +2262,8 @@ int args_verify(char ***pargs, int *pargc,
	char **oldargs = *pargs;
	char *arg = **pargs, *argn = (*pargs)[1];
	time_t at_time = 0;
	const unsigned char *hostname = NULL, *email = NULL;
	char *ipasc = NULL;
	if (!strcmp(arg, "-policy"))
		{
		if (!argn)
@@ -2335,6 +2337,27 @@ int args_verify(char ***pargs, int *pargc,
			}
		(*pargs)++;
		}
	else if (strcmp(arg,"-verify_hostname") == 0)
		{
		if (!argn)
			*badarg = 1;
		hostname = (unsigned char *)argn;
		(*pargs)++;
		}
	else if (strcmp(arg,"-verify_email") == 0)
		{
		if (!argn)
			*badarg = 1;
		email = (unsigned char *)argn;
		(*pargs)++;
		}
	else if (strcmp(arg,"-verify_ip") == 0)
		{
		if (!argn)
			*badarg = 1;
		ipasc = argn;
		(*pargs)++;
		}
	else if (!strcmp(arg, "-ignore_critical"))
		flags |= X509_V_FLAG_IGNORE_CRITICAL;
	else if (!strcmp(arg, "-issuer_checks"))
@@ -2396,6 +2419,15 @@ int args_verify(char ***pargs, int *pargc,
	if (at_time) 
		X509_VERIFY_PARAM_set_time(*pm, at_time);

	if (hostname && !X509_VERIFY_PARAM_set1_host(*pm, hostname, 0))
		*badarg = 1;

	if (email && !X509_VERIFY_PARAM_set1_email(*pm, email, 0))
		*badarg = 1;

	if (ipasc && !X509_VERIFY_PARAM_set1_ip_asc(*pm, ipasc))
		*badarg = 1;

	end:

	(*pargs)++;
+7 −0
Original line number Diff line number Diff line
@@ -184,6 +184,13 @@ const char *X509_verify_cert_error_string(long n)
	case X509_V_ERR_CRL_PATH_VALIDATION_ERROR:
		return("CRL path validation error");

	case X509_V_ERR_HOSTNAME_MISMATCH:
		return("Hostname mismatch");
	case X509_V_ERR_EMAIL_MISMATCH:
		return("Email address mismatch");
	case X509_V_ERR_IP_ADDRESS_MISMATCH:
		return("IP address mismatch");

	default:
		BIO_snprintf(buf,sizeof buf,"error number %ld",n);
		return(buf);
+35 −0
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer);
static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x);
static int check_chain_extensions(X509_STORE_CTX *ctx);
static int check_name_constraints(X509_STORE_CTX *ctx);
static int check_id(X509_STORE_CTX *ctx);
static int check_trust(X509_STORE_CTX *ctx);
static int check_revocation(X509_STORE_CTX *ctx);
static int check_cert(X509_STORE_CTX *ctx);
@@ -367,6 +368,10 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
	
	if (!ok) goto end;

	ok = check_id(ctx);

	if (!ok) goto end;

	/* We may as well copy down any DSA parameters that are required */
	X509_get_pubkey_parameters(NULL,ctx->chain);

@@ -655,6 +660,36 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
	return 1;
	}

static int check_id_error(X509_STORE_CTX *ctx, int errcode)
	{
	ctx->error = errcode;
	ctx->current_cert = ctx->cert;
	ctx->error_depth = 0;
	return ctx->verify_cb(0, ctx);
	}

static int check_id(X509_STORE_CTX *ctx)
	{
	X509_VERIFY_PARAM *vpm = ctx->param;
	X509 *x = ctx->cert;
	if (vpm->host && !X509_check_host(x, vpm->host, vpm->hostlen, 0))
		{
		if (!check_id_error(ctx, X509_V_ERR_HOSTNAME_MISMATCH))
			return 0;
		}
	if (vpm->email && !X509_check_email(x, vpm->email, vpm->emaillen, 0))
		{
		if (!check_id_error(ctx, X509_V_ERR_EMAIL_MISMATCH))
			return 0;
		}
	if (vpm->ip && !X509_check_ip(x, vpm->ip, vpm->iplen, 0))
		{
		if (!check_id_error(ctx, X509_V_ERR_IP_ADDRESS_MISMATCH))
			return 0;
		}
	return 1;
	}

static int check_trust(X509_STORE_CTX *ctx)
{
	int i, ok;
+20 −0
Original line number Diff line number Diff line
@@ -173,6 +173,12 @@ typedef struct X509_VERIFY_PARAM_st
	int trust;		/* trust setting to check */
	int depth;		/* Verify depth */
	STACK_OF(ASN1_OBJECT) *policies;	/* Permissible policies */
	unsigned char *host;	/* If not NULL hostname to match */
	size_t hostlen;
	unsigned char *email;	/* If not NULL email address to match */
	size_t emaillen;
	unsigned char *ip;	/* If not NULL IP address to match */
	size_t iplen;		/* Length of IP address */
	} X509_VERIFY_PARAM;

DECLARE_STACK_OF(X509_VERIFY_PARAM)
@@ -354,6 +360,11 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
#define		X509_V_ERR_UNSUPPORTED_NAME_SYNTAX		53
#define		X509_V_ERR_CRL_PATH_VALIDATION_ERROR		54

/* Host, email and IP check errors */
#define		X509_V_ERR_HOSTNAME_MISMATCH			62
#define		X509_V_ERR_EMAIL_MISMATCH			63
#define		X509_V_ERR_IP_ADDRESS_MISMATCH			64

/* The application is not happy */
#define		X509_V_ERR_APPLICATION_VERIFICATION		50

@@ -530,6 +541,15 @@ int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param,
						ASN1_OBJECT *policy);
int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, 
					STACK_OF(ASN1_OBJECT) *policies);

int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
				const unsigned char *name, size_t namelen);
int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
				const unsigned char *email, size_t emaillen);
int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
					const unsigned char *ip, size_t iplen);
int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc);

int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param);

int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param);
Loading