55
55
{ NULL, -1, 0, NULL, NULL } /* end the list */
58
static CONF_PARSER verify_config[] = {
59
{ "tmpdir", PW_TYPE_STRING_PTR,
60
offsetof(EAP_TLS_CONF, verify_tmp_dir), NULL, NULL},
61
{ "client", PW_TYPE_STRING_PTR,
62
offsetof(EAP_TLS_CONF, verify_client_cert_cmd), NULL, NULL},
63
{ NULL, -1, 0, NULL, NULL } /* end the list */
58
66
static CONF_PARSER module_config[] = {
59
67
{ "rsa_key_exchange", PW_TYPE_BOOLEAN,
60
68
offsetof(EAP_TLS_CONF, rsa_key), NULL, "no" },
100
108
{ "cache", PW_TYPE_SUBSECTION, 0, NULL, (const void *) cache_config },
110
{ "verify", PW_TYPE_SUBSECTION, 0, NULL, (const void *) verify_config },
102
112
{ NULL, -1, 0, NULL, NULL } /* end the list */
227
* For creating certificate attributes.
229
static const char *cert_attr_names[5][2] = {
230
{ "TLS-Client-Cert-Serial", "TLS-Cert-Serial" },
231
{ "TLS-Client-Cert-Expiration", "TLS-Cert-Expiration" },
232
{ "TLS-Client-Cert-Subject", "TLS-Cert-Subject" },
233
{ "TLS-Client-Cert-Issuer", "TLS-Cert-Issuer" },
234
{ "TLS-Client-Cert-Common-Name", "TLS-Cert-Common-Name" }
237
#define EAPTLS_SERIAL (0)
238
#define EAPTLS_EXPIRATION (1)
239
#define EAPTLS_SUBJECT (2)
240
#define EAPTLS_ISSUER (3)
241
#define EAPTLS_CN (4)
217
244
* Before trusting a certificate, you must make sure that the
218
245
* certificate is 'valid'. There are several steps that your
219
246
* application can take in determining if a certificate is
244
271
char issuer[1024]; /* Used for the issuer name */
245
272
char common_name[1024];
246
273
char cn_str[1024];
247
275
EAP_HANDLER *handler = NULL;
248
276
X509 *client_cert;
278
int err, depth, lookup;
251
279
EAP_TLS_CONF *conf;
253
281
REQUEST *request;
282
ASN1_INTEGER *sn = NULL;
283
ASN1_TIME *asn_time = NULL;
255
285
client_cert = X509_STORE_CTX_get_current_cert(ctx);
256
286
err = X509_STORE_CTX_get_error(ctx);
257
287
depth = X509_STORE_CTX_get_error_depth(ctx);
260
radlog(L_ERR,"--> verify error:num=%d:%s\n",err,
261
X509_verify_cert_error_string(err));
292
* Log client/issuing cert. If there's an error, log
295
if ((lookup > 1) && !my_ok) lookup = 1;
266
298
* Retrieve the pointer to the SSL of the connection currently treated
272
304
conf = (EAP_TLS_CONF *)SSL_get_ex_data(ssl, 1);
307
* Get the Serial Number
310
sn = X509_get_serialNumber(client_cert);
313
* For this next bit, we create the attributes *only* if
314
* we're at the client or issuing certificate.
316
if ((lookup <= 1) && sn && (sn->length < (sizeof(buf) / 2))) {
320
for (i = 0; i < sn->length; i++) {
321
sprintf(p, "%02x", (unsigned int)sn->data[i]);
324
pairadd(&handler->certs,
325
pairmake(cert_attr_names[EAPTLS_SERIAL][lookup], buf, T_OP_SET));
330
* Get the Expiration Date
333
asn_time = X509_get_notAfter(client_cert);
334
if ((lookup <= 1) && asn_time && (asn_time->length < MAX_STRING_LEN)) {
335
memcpy(buf, (char*) asn_time->data, asn_time->length);
336
buf[asn_time->length] = '\0';
337
pairadd(&handler->certs,
338
pairmake(cert_attr_names[EAPTLS_EXPIRATION][lookup], buf, T_OP_SET));
275
342
* Get the Subject & Issuer
277
344
subject[0] = issuer[0] = '\0';
278
345
X509_NAME_oneline(X509_get_subject_name(client_cert), subject,
279
346
sizeof(subject));
347
subject[sizeof(subject) - 1] = '\0';
348
if ((lookup <= 1) && subject[0] && (strlen(subject) < MAX_STRING_LEN)) {
349
pairadd(&handler->certs,
350
pairmake(cert_attr_names[EAPTLS_SUBJECT][lookup], subject, T_OP_SET));
280
353
X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), issuer,
283
subject[sizeof(subject) - 1] = '\0';
284
355
issuer[sizeof(issuer) - 1] = '\0';
356
if ((lookup <= 1) && issuer[0] && (strlen(issuer) < MAX_STRING_LEN)) {
357
pairadd(&handler->certs,
358
pairmake(cert_attr_names[EAPTLS_ISSUER][lookup], issuer, T_OP_SET));
287
362
* Get the Common Name
289
364
X509_NAME_get_text_by_NID(X509_get_subject_name(client_cert),
290
365
NID_commonName, common_name, sizeof(common_name));
291
366
common_name[sizeof(common_name) - 1] = '\0';
367
if ((lookup <= 1) && common_name[0] && (strlen(common_name) < MAX_STRING_LEN)) {
368
pairadd(&handler->certs,
369
pairmake(cert_attr_names[EAPTLS_CN][lookup], common_name, T_OP_SET));
373
const char *p = X509_verify_cert_error_string(err);
374
radlog(L_ERR,"--> verify error:num=%d:%s\n",err, p);
375
radius_pairmake(request, &request->packet->vps,
376
"Module-Failure-Message", p, T_OP_SET);
293
380
switch (ctx->error) {
348
435
} /* check_cert_cn */
437
while (conf->verify_client_cert_cmd) {
441
snprintf(filename, sizeof(filename), "%s/%s.client.XXXXXXXX",
442
conf->verify_tmp_dir, progname);
443
if (mkstemp(filename) < 0) {
444
RDEBUG("Failed creating file in %s: %s",
445
conf->verify_tmp_dir, strerror(errno));
449
fp = fopen(filename, "w");
451
RDEBUG("Failed opening file %s: %s",
452
filename, strerror(errno));
456
if (!PEM_write_X509(fp, client_cert)) {
458
RDEBUG("Failed writing certificate to file");
463
if (!radius_pairmake(request, &request->packet->vps,
464
"TLS-Client-Cert-Filename",
465
filename, T_OP_SET)) {
466
RDEBUG("Failed creating TLS-Client-Cert-Filename");
471
RDEBUG("Verifying client certificate: %s",
472
conf->verify_client_cert_cmd);
473
if (radius_exec_program(conf->verify_client_cert_cmd,
475
request->packet->vps,
477
radlog(L_AUTH, "rlm_eap_tls: Certificate CN (%s) fails external verification!", common_name);
480
RDEBUG("Client certificate CN %s passed external validation", common_name);
349
489
} /* depth == 0 */
351
491
if (debug_flag > 0) {
810
953
if (generate_eph_rsa_key(inst->ctx) < 0) {
958
if (conf->verify_tmp_dir) {
961
if (chmod(conf->verify_tmp_dir, S_IRWXU) < 0) {
962
radlog(L_ERR, "rlm_eap_tls: Failed changing permissions on %s: %s", conf->verify_tmp_dir, strerror(errno));
968
if (conf->verify_client_cert_cmd && !conf->verify_tmp_dir) {
969
radlog(L_ERR, "rlm_eap_tls: You MUST set the verify directory in order to use verify_client_cmd");
814
974
*instance = inst;