Commit 2836acbf authored by venaas's avatar venaas Committed by venaas
Browse files

regexp match on cert cn

git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@225 e88ac4ed-0b26-0410-9574-a7f39faa03bf
parent fe403771
...@@ -631,6 +631,45 @@ int subjectaltnameaddr(X509 *cert, int family, struct in6_addr *addr) { ...@@ -631,6 +631,45 @@ int subjectaltnameaddr(X509 *cert, int family, struct in6_addr *addr) {
return r; return r;
} }
int cnregexp(X509 *cert, char *exact, regex_t *regex) {
int loc, l;
char *v, *s;
X509_NAME *nm;
X509_NAME_ENTRY *e;
ASN1_STRING *t;
nm = X509_get_subject_name(cert);
loc = -1;
for (;;) {
loc = X509_NAME_get_index_by_NID(nm, NID_commonName, loc);
if (loc == -1)
break;
e = X509_NAME_get_entry(nm, loc);
t = X509_NAME_ENTRY_get_data(e);
v = (char *) ASN1_STRING_data(t);
l = ASN1_STRING_length(t);
if (l < 0)
continue;
if (exact) {
if (l == strlen(exact) && !strncasecmp(exact, v, l))
return 1;
} else {
s = stringcopy((char *)v, l);
if (!s) {
debug(DBG_ERR, "malloc failed");
continue;
}
if (regexec(regex, s, 0, NULL, 0)) {
free(s);
continue;
}
free(s);
return 1;
}
}
return 0;
}
int subjectaltnameregexp(X509 *cert, int type, char *exact, regex_t *regex) { int subjectaltnameregexp(X509 *cert, int type, char *exact, regex_t *regex) {
int loc, i, l, n, r = 0; int loc, i, l, n, r = 0;
char *s, *v; char *s, *v;
...@@ -685,12 +724,8 @@ int subjectaltnameregexp(X509 *cert, int type, char *exact, regex_t *regex) { ...@@ -685,12 +724,8 @@ int subjectaltnameregexp(X509 *cert, int type, char *exact, regex_t *regex) {
} }
int tlsverifycert(SSL *ssl, struct clsrvconf *conf) { int tlsverifycert(SSL *ssl, struct clsrvconf *conf) {
int l, loc, r; int r;
X509 *cert; X509 *cert;
X509_NAME *nm;
X509_NAME_ENTRY *e;
ASN1_STRING *s;
char *v;
uint8_t type = 0; /* 0 for DNS, AF_INET for IPv4, AF_INET6 for IPv6 */ uint8_t type = 0; /* 0 for DNS, AF_INET for IPv4, AF_INET6 for IPv6 */
unsigned long error; unsigned long error;
struct in6_addr addr; struct in6_addr addr;
...@@ -717,51 +752,38 @@ int tlsverifycert(SSL *ssl, struct clsrvconf *conf) { ...@@ -717,51 +752,38 @@ int tlsverifycert(SSL *ssl, struct clsrvconf *conf) {
r = type ? subjectaltnameaddr(cert, type, &addr) : subjectaltnameregexp(cert, GEN_DNS, conf->host, NULL); r = type ? subjectaltnameaddr(cert, type, &addr) : subjectaltnameregexp(cert, GEN_DNS, conf->host, NULL);
if (r) { if (r) {
if (r < 0) { if (r < 0) {
X509_free(cert);
debug(DBG_DBG, "tlsverifycert: No subjectaltname matching %s %s", type ? "address" : "host", conf->host); debug(DBG_DBG, "tlsverifycert: No subjectaltname matching %s %s", type ? "address" : "host", conf->host);
return 0; goto errexit;
} }
debug(DBG_DBG, "tlsverifycert: Found subjectaltname matching %s %s", type ? "address" : "host", conf->host); debug(DBG_DBG, "tlsverifycert: Found subjectaltname matching %s %s", type ? "address" : "host", conf->host);
} else { } else {
nm = X509_get_subject_name(cert); if (!cnregexp(cert, conf->host, NULL)) {
loc = -1; debug(DBG_ERR, "tlsverifycert: cn not matching host %s", conf->host);
for (;;) { goto errexit;
loc = X509_NAME_get_index_by_NID(nm, NID_commonName, loc);
if (loc == -1)
break;
e = X509_NAME_get_entry(nm, loc);
s = X509_NAME_ENTRY_get_data(e);
v = (char *) ASN1_STRING_data(s);
l = ASN1_STRING_length(s);
if (l < 0)
continue;
#ifdef DEBUG
printfchars(NULL, "cn", NULL, v, l);
#endif
if (l == strlen(conf->host) && !strncasecmp(conf->host, v, l)) {
r = 1;
debug(DBG_DBG, "tlsverifycert: Found cn matching host %s", conf->host);
break;
} }
debug(DBG_DBG, "tlsverifycert: Found cn matching host %s", conf->host);
} }
if (!r) {
X509_free(cert);
debug(DBG_ERR, "tlsverifycert: cn not matching host %s", conf->host);
return 0;
} }
if (conf->certcnregex) {
if (cnregexp(cert, NULL, conf->certcnregex) < 1) {
debug(DBG_DBG, "tlsverifycert: CN not matching regex");
goto errexit;
} }
debug(DBG_DBG, "tlsverifycert: CN matching regex");
} }
if (conf->certuriregex) { if (conf->certuriregex) {
r = subjectaltnameregexp(cert, GEN_URI, NULL, conf->certuriregex); if (subjectaltnameregexp(cert, GEN_URI, NULL, conf->certuriregex) < 1) {
if (r < 1) {
debug(DBG_DBG, "tlsverifycert: subjectaltname URI not matching regex"); debug(DBG_DBG, "tlsverifycert: subjectaltname URI not matching regex");
X509_free(cert); goto errexit;
return 0;
} }
debug(DBG_DBG, "tlsverifycert: subjectaltname URI matching regex"); debug(DBG_DBG, "tlsverifycert: subjectaltname URI matching regex");
} }
X509_free(cert); X509_free(cert);
return 1; return 1;
errexit:
X509_free(cert);
return 0;
} }
void tlsconnect(struct server *server, struct timeval *when, char *text) { void tlsconnect(struct server *server, struct timeval *when, char *text) {
...@@ -2583,9 +2605,17 @@ struct gconffile *openconfigfile(const char *filename) { ...@@ -2583,9 +2605,17 @@ struct gconffile *openconfigfile(const char *filename) {
int addmatchcertattr(struct clsrvconf *conf, char *matchcertattr) { int addmatchcertattr(struct clsrvconf *conf, char *matchcertattr) {
char *v; char *v;
regex_t **r;
if (strncasecmp(matchcertattr, "CN:/", 4)) {
r = &conf->certcnregex;
v = matchcertattr + 4;
} else if (strncasecmp(matchcertattr, "SubjectAltName:URI:/", 20)) {
r = &conf->certuriregex;
v = matchcertattr + 20; v = matchcertattr + 20;
if (strncasecmp(matchcertattr, "SubjectAltName:URI:/", 20) || !*v) } else
return 0;
if (!*v)
return 0; return 0;
/* regexp, remove optional trailing / if present */ /* regexp, remove optional trailing / if present */
if (v[strlen(v) - 1] == '/') if (v[strlen(v) - 1] == '/')
...@@ -2593,14 +2623,14 @@ int addmatchcertattr(struct clsrvconf *conf, char *matchcertattr) { ...@@ -2593,14 +2623,14 @@ int addmatchcertattr(struct clsrvconf *conf, char *matchcertattr) {
if (!*v) if (!*v)
return 0; return 0;
conf->certuriregex = malloc(sizeof(regex_t)); *r = malloc(sizeof(regex_t));
if (!conf->certuriregex) { if (!*r) {
debug(DBG_ERR, "malloc failed"); debug(DBG_ERR, "malloc failed");
return 0; return 0;
} }
if (regcomp(conf->certuriregex, v, REG_ICASE | REG_NOSUB)) { if (regcomp(*r, v, REG_ICASE | REG_NOSUB)) {
free(conf->certuriregex); free(*r);
conf->certuriregex = NULL; *r = NULL;
debug(DBG_ERR, "failed to compile regular expression %s", v); debug(DBG_ERR, "failed to compile regular expression %s", v);
return 0; return 0;
} }
......
...@@ -79,6 +79,7 @@ struct clsrvconf { ...@@ -79,6 +79,7 @@ struct clsrvconf {
char *host; char *host;
char *port; char *port;
char *secret; char *secret;
regex_t *certcnregex;
regex_t *certuriregex; regex_t *certuriregex;
regex_t *rewriteattrregex; regex_t *rewriteattrregex;
char *rewriteattrreplacement; char *rewriteattrreplacement;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment