aboutsummaryrefslogtreecommitdiffstats
path: root/crypto/x509
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2012-12-05 18:35:20 +0000
committerDr. Stephen Henson <steve@openssl.org>2012-12-05 18:35:20 +0000
commit3bf15e2974f416cb970ef54fae0f600ec299000e (patch)
treee5eee2ff6fe2245b552813dce2741b1bec28647b /crypto/x509
parent8df400cf8de73f2377f6931735c386b1480300ad (diff)
downloadopenssl-3bf15e2974f416cb970ef54fae0f600ec299000e.tar.gz
Integrate host, email and IP address checks into X509_verify.
Add new verify options to set checks. Remove previous -check* commands from s_client and s_server.
Diffstat (limited to 'crypto/x509')
-rw-r--r--crypto/x509/x509_txt.c6
-rw-r--r--crypto/x509/x509_vfy.c35
-rw-r--r--crypto/x509/x509_vfy.h19
-rw-r--r--crypto/x509/x509_vpm.c97
4 files changed, 157 insertions, 0 deletions
diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c
index 595efcead3..361cd21987 100644
--- a/crypto/x509/x509_txt.c
+++ b/crypto/x509/x509_txt.c
@@ -197,6 +197,12 @@ const char *X509_verify_cert_error_string(long n)
return("Suite B: curve not allowed for this LOS");
case X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256:
return("Suite B: cannot sign P-384 with P-256");
+ 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);
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index a21fa39c32..8ba03d5d43 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -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);
@@ -377,6 +378,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);
@@ -694,6 +699,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;
diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h
index a6f3943025..58eff53f72 100644
--- a/crypto/x509/x509_vfy.h
+++ b/crypto/x509/x509_vfy.h
@@ -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)
@@ -362,6 +368,10 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
#define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59
#define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60
#define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61
+/* 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
@@ -548,6 +558,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);
const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param);
diff --git a/crypto/x509/x509_vpm.c b/crypto/x509/x509_vpm.c
index 9e7d996661..68f158435e 100644
--- a/crypto/x509/x509_vpm.c
+++ b/crypto/x509/x509_vpm.c
@@ -83,6 +83,24 @@ static void x509_verify_param_zero(X509_VERIFY_PARAM *param)
sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free);
param->policies = NULL;
}
+ if (param->host)
+ {
+ OPENSSL_free(param->host);
+ param->host = NULL;
+ param->hostlen = 0;
+ }
+ if (param->email)
+ {
+ OPENSSL_free(param->email);
+ param->email = NULL;
+ param->emaillen = 0;
+ }
+ if (param->ip)
+ {
+ OPENSSL_free(param->ip);
+ param->ip = NULL;
+ param->iplen = 0;
+ }
}
X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void)
@@ -193,6 +211,24 @@ int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest,
return 0;
}
+ if (test_x509_verify_param_copy(host, NULL))
+ {
+ if (!X509_VERIFY_PARAM_set1_host(dest, src->host, src->hostlen))
+ return 0;
+ }
+
+ if (test_x509_verify_param_copy(email, NULL))
+ {
+ if (!X509_VERIFY_PARAM_set1_email(dest, src->email, src->emaillen))
+ return 0;
+ }
+
+ if (test_x509_verify_param_copy(ip, NULL))
+ {
+ if (!X509_VERIFY_PARAM_set1_ip(dest, src->ip, src->iplen))
+ return 0;
+ }
+
return 1;
}
@@ -207,6 +243,35 @@ int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to,
return ret;
}
+static int int_x509_param_set1(unsigned char **pdest, size_t *pdestlen,
+ const unsigned char *src, size_t srclen)
+ {
+ void *tmp;
+ if (src)
+ {
+ if (srclen == 0)
+ {
+ tmp = BUF_strdup((char *)src);
+ srclen = strlen((char *)src);
+ }
+ else
+ tmp = BUF_memdup(src, srclen);
+ if (!tmp)
+ return 0;
+ }
+ else
+ {
+ tmp = NULL;
+ srclen = 0;
+ }
+ if (*pdest)
+ OPENSSL_free(*pdest);
+ *pdest = tmp;
+ if (pdestlen)
+ *pdestlen = srclen;
+ return 1;
+ }
+
int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name)
{
if (param->name)
@@ -306,6 +371,38 @@ int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param,
return 1;
}
+int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param,
+ const unsigned char *name, size_t namelen)
+ {
+ return int_x509_param_set1(&param->host, &param->hostlen,
+ name, namelen);
+ }
+
+int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param,
+ const unsigned char *email, size_t emaillen)
+ {
+ return int_x509_param_set1(&param->email, &param->emaillen,
+ email, emaillen);
+ }
+
+int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param,
+ const unsigned char *ip, size_t iplen)
+ {
+ if (iplen != 0 && iplen != 4 && iplen != 16)
+ return 0;
+ return int_x509_param_set1(&param->ip, &param->iplen, ip, iplen);
+ }
+
+int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc)
+ {
+ unsigned char ipout[16];
+ int iplen;
+ iplen = a2i_ipadd(ipout, ipasc);
+ if (iplen == 0)
+ return 0;
+ return X509_VERIFY_PARAM_set1_ip(param, ipout, (size_t)iplen);
+ }
+
int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param)
{
return param->depth;