diff options
-rw-r--r-- | radsecproxy.c | 117 | ||||
-rw-r--r-- | radsecproxy.h | 1 |
2 files changed, 79 insertions, 39 deletions
diff --git a/radsecproxy.c b/radsecproxy.c index b89577a..9689d91 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -205,45 +205,57 @@ static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) { } static int verify_cb(int ok, X509_STORE_CTX *ctx) { - char buf[256]; - X509 *err_cert; - int err, depth; - - err_cert = X509_STORE_CTX_get_current_cert(ctx); - err = X509_STORE_CTX_get_error(ctx); - depth = X509_STORE_CTX_get_error_depth(ctx); - - if (depth > MAX_CERT_DEPTH) { - ok = 0; - err = X509_V_ERR_CERT_CHAIN_TOO_LONG; - X509_STORE_CTX_set_error(ctx, err); - } - - if (!ok) { - X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256); - debug(DBG_WARN, "verify error: num=%d:%s:depth=%d:%s", err, X509_verify_cert_error_string(err), depth, buf); - - switch (err) { - case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: - X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256); - debug(DBG_WARN, "\tIssuer=%s", buf); - break; - case X509_V_ERR_CERT_NOT_YET_VALID: - case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: - debug(DBG_WARN, "\tCertificate not yet valid"); - break; - case X509_V_ERR_CERT_HAS_EXPIRED: - debug(DBG_WARN, "Certificate has expired"); - break; - case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: - debug(DBG_WARN, "Certificate no longer valid (after notAfter)"); - break; - } - } + char *buf = NULL; + X509 *err_cert; + int err, depth; + + err_cert = X509_STORE_CTX_get_current_cert(ctx); + err = X509_STORE_CTX_get_error(ctx); + depth = X509_STORE_CTX_get_error_depth(ctx); + + if (depth > MAX_CERT_DEPTH) { + ok = 0; + err = X509_V_ERR_CERT_CHAIN_TOO_LONG; + X509_STORE_CTX_set_error(ctx, err); + } + + if (!ok) { + if (err_cert) + buf = X509_NAME_oneline(X509_get_subject_name(err_cert), NULL, 0); + debug(DBG_WARN, "verify error: num=%d:%s:depth=%d:%s", err, X509_verify_cert_error_string(err), depth, buf ? buf : ""); + free(buf); + buf = NULL; + + switch (err) { + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + if (err_cert) { + buf = X509_NAME_oneline(X509_get_issuer_name(err_cert), NULL, 0); + if (buf) { + debug(DBG_WARN, "\tIssuer=%s", buf); + free(buf); + buf = NULL; + } + } + break; + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + debug(DBG_WARN, "\tCertificate not yet valid"); + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + debug(DBG_WARN, "Certificate has expired"); + break; + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + debug(DBG_WARN, "Certificate no longer valid (after notAfter)"); + break; + case X509_V_ERR_NO_EXPLICIT_POLICY: + debug(DBG_WARN, "No Explicit Certificate Policy"); + break; + } + } #ifdef DEBUG - printf("certificate verify returns %d\n", ok); + printf("certificate verify returns %d\n", ok); #endif - return ok; + return ok; } struct addrinfo *getsrcprotores(uint8_t type) { @@ -2347,6 +2359,27 @@ void tlsinit() { } } +int setpolicyoids(X509_STORE *store, char **poids) { + X509_VERIFY_PARAM *pm; + ASN1_OBJECT *pobject; + int i; + + pm = X509_VERIFY_PARAM_new(); + if (!pm) + return 0; + + for (i = 0; poids[i]; i++) { + pobject = OBJ_txt2obj(poids[i], 0); + if (!pobject) + return 0; + X509_VERIFY_PARAM_add0_policy(pm, pobject); + } + + X509_VERIFY_PARAM_set_flags(pm, X509_V_FLAG_POLICY_CHECK | X509_V_FLAG_EXPLICIT_POLICY); + X509_STORE_set1_param(store, pm); + return 1; +} + int tlsaddcacrl(SSL_CTX *ctx, struct tls *conf) { STACK_OF(X509_NAME) *calist; X509_STORE *x509_s; @@ -2382,9 +2415,14 @@ int tlsaddcacrl(SSL_CTX *ctx, struct tls *conf) { SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb); SSL_CTX_set_verify_depth(ctx, MAX_CERT_DEPTH + 1); - if (conf->crlcheck) { + if (conf->crlcheck || conf->policyoids) { x509_s = SSL_CTX_get_cert_store(ctx); - X509_STORE_set_flags(x509_s, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); + if (conf->crlcheck) + X509_STORE_set_flags(x509_s, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); + if (conf->policyoids && !setpolicyoids(x509_s, conf->policyoids)) { + debug(DBG_ERR, "tlsaddcacrl: Failed to add policyOIDs in TLS context %s", conf->name); + return 0; /* should free memory */ + } } debug(DBG_DBG, "tlsaddcacrl: updated TLS context %s", conf->name); @@ -3410,6 +3448,7 @@ int conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *v "CertificateKeyPassword", CONF_STR, &conf->certkeypwd, "CacheExpiry", CONF_LINT, &expiry, "CRLCheck", CONF_BLN, &conf->crlcheck, + "PolicyOID", CONF_MSTR, &conf->policyoids, NULL )) { debug(DBG_ERR, "conftls_cb: configuration error in block %s", val); diff --git a/radsecproxy.h b/radsecproxy.h index 520703f..a29d733 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -155,6 +155,7 @@ struct tls { char *certkeyfile; char *certkeypwd; uint8_t crlcheck; + char **policyoids; uint32_t cacheexpiry; uint32_t tlsexpiry; uint32_t dtlsexpiry; |