offsetof(EAP_TLS_CONF, check_crl), NULL, "no"},
{ "check_cert_cn", PW_TYPE_STRING_PTR,
offsetof(EAP_TLS_CONF, check_cert_cn), NULL, NULL},
+ { "check_cert_issuer", PW_TYPE_STRING_PTR,
+ offsetof(EAP_TLS_CONF, check_cert_issuer), NULL, NULL},
{ NULL, -1, 0, NULL, NULL } /* end the list */
};
*/
static int cbtls_verify(int ok, X509_STORE_CTX *ctx)
{
- char subject[256]; /* Used for the subject name */
- char issuer[256]; /* Used for the issuer name */
- char buf[256];
- char cn_str[256];
+ char subject[1024]; /* Used for the subject name */
+ char issuer[1024]; /* Used for the issuer name */
+ char common_name[1024];
+ char cn_str[1024];
EAP_HANDLER *handler = NULL;
X509 *client_cert;
SSL *ssl;
X509_verify_cert_error_string(err));
return my_ok;
}
- /*
- * Catch too long Certificate chains
- */
/*
* Retrieve the pointer to the SSL of the connection currently treated
* Get the Subject & Issuer
*/
subject[0] = issuer[0] = '\0';
- X509_NAME_oneline(X509_get_subject_name(client_cert), subject, 256);
- X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), issuer, 256);
+ X509_NAME_oneline(X509_get_subject_name(client_cert), subject,
+ sizeof(subject));
+ X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), issuer,
+ sizeof(issuer));
+
+ subject[sizeof(subject) - 1] = '\0';
+ issuer[sizeof(issuer) - 1] = '\0';
/*
* Get the Common Name
*/
X509_NAME_get_text_by_NID(X509_get_subject_name(client_cert),
- NID_commonName, buf, 256);
+ NID_commonName, common_name, sizeof(common_name));
+ common_name[sizeof(common_name) - 1] = '\0';
switch (ctx->error) {
}
/*
- * If we're at the actual client cert and the conf tells
- * us to, check the CN in the cert against the xlat'ed
- * value
+ * If we're at the actual client cert, apply additional
+ * checks.
*/
- if (depth == 0 && conf->check_cert_cn != NULL) {
- if (!radius_xlat(cn_str, sizeof(cn_str), conf->check_cert_cn, handler->request, NULL)) {
- radlog(L_ERR, "rlm_eap_tls (%s): xlat failed.",
- conf->check_cert_cn);
- /* if this fails, fail the verification */
- my_ok = 0;
- }
- DEBUG2(" rlm_eap_tls: checking certificate CN (%s) with xlat'ed value (%s)", buf, cn_str);
- if (strncmp(cn_str, buf, sizeof(buf)) != 0) {
- my_ok = 0;
- radlog(L_AUTH, "rlm_eap_tls: Certificate CN (%s) does not match specified value (%s)!", buf, cn_str);
- }
- }
+ if (depth == 0) {
+ /*
+ * If the conf tells us to, check cert issuer
+ * against the specified value and fail
+ * verification if they don't match.
+ */
+ if (conf->check_cert_issuer &&
+ (strcmp(issuer, conf->check_cert_issuer) != 0)) {
+ radlog(L_AUTH, "rlm_eap_tls: Certificate issuer (%s) does not match specified value (%s)!", issuer, conf->check_cert_issuer);
+ my_ok = 0;
+ }
+
+ /*
+ * If the conf tells us to, check the CN in the
+ * cert against xlat'ed value, but only if the
+ * previous checks passed.
+ */
+ if (my_ok && conf->check_cert_cn) {
+ if (!radius_xlat(cn_str, sizeof(cn_str), conf->check_cert_cn, handler->request, NULL)) {
+ radlog(L_ERR, "rlm_eap_tls (%s): xlat failed.",
+ conf->check_cert_cn);
+ /* if this fails, fail the verification */
+ my_ok = 0;
+ } else {
+ DEBUG2(" rlm_eap_tls: checking certificate CN (%s) with xlat'ed value (%s)", common_name, cn_str);
+ if (strcmp(cn_str, common_name) != 0) {
+ radlog(L_AUTH, "rlm_eap_tls: Certificate CN (%s) does not match specified value (%s)!", common_name, cn_str);
+ my_ok = 0;
+ }
+ }
+ } /* check_cert_cn */
+ } /* depth == 0 */
if (debug_flag > 0) {
radlog(L_INFO, "chain-depth=%d, ", depth);
- /*
- if (depth > 0) {
- return ok;
- }
- */
radlog(L_INFO, "error=%d", err);
radlog(L_INFO, "--> User-Name = %s", handler->identity);
- radlog(L_INFO, "--> BUF-Name = %s", buf);
+ radlog(L_INFO, "--> BUF-Name = %s", common_name);
radlog(L_INFO, "--> subject = %s", subject);
radlog(L_INFO, "--> issuer = %s", issuer);
radlog(L_INFO, "--> verify return:%d", my_ok);