From 91adebe749beb0dc23cacaea316cb2b724776aad Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 13 Jun 2007 05:44:24 +0000 Subject: r23456: Update Samba4 to current lorikeet-heimdal. Andrew Bartlett (This used to be commit ae0f81ab235c72cceb120bcdeb051a483cf3cc4f) --- source4/heimdal/kdc/kx509.c | 196 ++++++++++++++++++++++++++++++++------------ 1 file changed, 143 insertions(+), 53 deletions(-) (limited to 'source4/heimdal/kdc/kx509.c') diff --git a/source4/heimdal/kdc/kx509.c b/source4/heimdal/kdc/kx509.c index d817338f73..8414ecb4b2 100644 --- a/source4/heimdal/kdc/kx509.c +++ b/source4/heimdal/kdc/kx509.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Kungliga Tekniska Högskolan + * Copyright (c) 2006 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,8 +33,10 @@ #include "kdc_locl.h" #include +#include +#include -RCSID("$Id: kx509.c,v 1.1 2006/12/28 21:03:53 lha Exp $"); +RCSID("$Id: kx509.c 19992 2007-01-20 09:06:18Z lha $"); /* * @@ -140,72 +142,146 @@ build_certificate(krb5_context context, krb5_principal principal, krb5_data *certificate) { - /* XXX write code here to generate certificates */ - FILE *in, *out; - krb5_error_code ret; - const char *program; - char *str, *strkey; - char tstr[64]; - pid_t pid; + hx509_context hxctx = NULL; + hx509_ca_tbs tbs = NULL; + hx509_env env = NULL; + hx509_cert cert = NULL; + hx509_cert signer = NULL; + int ret; + + if (krb5_principal_get_comp_string(context, principal, 1) != NULL) { + kdc_log(context, config, 0, "Principal is not a user"); + return EINVAL; + } - snprintf(tstr, sizeof(tstr), "%lu", (unsigned long)endtime); + ret = hx509_context_init(&hxctx); + if (ret) + goto out; - ret = base64_encode(key->data, key->length, &strkey); - if (ret < 0) { - krb5_set_error_string(context, "failed to base64 encode key"); - return ENOMEM; - } + ret = hx509_env_init(hxctx, &env); + if (ret) + goto out; - program = krb5_config_get_string(context, - NULL, - "kdc", - "kx509_cert_program", - NULL); - if (program == NULL) { - free(strkey); - krb5_set_error_string(context, "no certificate program configured"); - return ENOENT; - } + ret = hx509_env_add(hxctx, env, "principal-name", + krb5_principal_get_comp_string(context, principal, 0)); + if (ret) + goto out; - ret = krb5_unparse_name(context, principal, &str); - if (ret) { - free(strkey); - return ret; + { + hx509_certs certs; + hx509_query *q; + + ret = hx509_certs_init(hxctx, config->kx509_ca, 0, + NULL, &certs); + if (ret) { + kdc_log(context, config, 0, "Failed to load CA %s", + config->kx509_ca); + goto out; + } + ret = hx509_query_alloc(hxctx, &q); + if (ret) { + hx509_certs_free(&certs); + goto out; + } + + hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY); + hx509_query_match_option(q, HX509_QUERY_OPTION_KU_KEYCERTSIGN); + + ret = hx509_certs_find(hxctx, certs, q, &signer); + hx509_query_free(hxctx, q); + hx509_certs_free(&certs); + if (ret) { + kdc_log(context, config, 0, "Failed to find a CA in %s", + config->kx509_ca); + goto out; + } } - pid = pipe_execv(&in, &out, NULL, program, str, tstr, NULL); - free(str); - if (pid <= 0) { - free(strkey); - krb5_set_error_string(context, - "Failed to run the cert program %s", - program); - return ret; + ret = hx509_ca_tbs_init(hxctx, &tbs); + if (ret) + goto out; + + { + SubjectPublicKeyInfo spki; + heim_any any; + + memset(&spki, 0, sizeof(spki)); + + spki.subjectPublicKey.data = key->data; + spki.subjectPublicKey.length = key->length * 8; + + ret = der_copy_oid(oid_id_pkcs1_rsaEncryption(), + &spki.algorithm.algorithm); + + any.data = "\x05\x00"; + any.length = 2; + spki.algorithm.parameters = &any; + + ret = hx509_ca_tbs_set_spki(hxctx, tbs, &spki); + der_free_oid(&spki.algorithm.algorithm); + if (ret) + goto out; } - fprintf(in, "%s\n", strkey); - fclose(in); - free(strkey); { - unsigned buf[1024 * 10]; - size_t len; + hx509_certs certs; + hx509_cert template; - len = fread(buf, 1, sizeof(buf), out); - fclose(out); - if(len == 0) { - krb5_set_error_string(context, - "Certificate program returned no data"); - return KRB5KDC_ERR_PREAUTH_FAILED; + ret = hx509_certs_init(hxctx, config->kx509_template, 0, + NULL, &certs); + if (ret) { + kdc_log(context, config, 0, "Failed to load template %s", + config->kx509_template); + goto out; } - ret = krb5_data_copy(certificate, buf, len); + ret = hx509_get_one_cert(hxctx, certs, &template); + hx509_certs_free(&certs); if (ret) { - krb5_set_error_string(context, "Failed To copy certificate"); - return ret; + kdc_log(context, config, 0, "Failed to find template in %s", + config->kx509_template); + goto out; } + ret = hx509_ca_tbs_set_template(hxctx, tbs, + HX509_CA_TEMPLATE_SUBJECT| + HX509_CA_TEMPLATE_KU| + HX509_CA_TEMPLATE_EKU, + template); + hx509_cert_free(template); + if (ret) + goto out; } - kill(pid, SIGKILL); - waitpid(pid, NULL, 0); + + hx509_ca_tbs_set_notAfter(hxctx, tbs, endtime); + + hx509_ca_tbs_subject_expand(hxctx, tbs, env); + hx509_env_free(&env); + + ret = hx509_ca_sign(hxctx, tbs, signer, &cert); + hx509_cert_free(signer); + if (ret) + goto out; + + hx509_ca_tbs_free(&tbs); + + ret = hx509_cert_binary(hxctx, cert, certificate); + hx509_cert_free(cert); + if (ret) + goto out; + + hx509_context_free(&hxctx); + return 0; +out: + if (env) + hx509_env_free(&env); + if (tbs) + hx509_ca_tbs_free(&tbs); + if (signer) + hx509_cert_free(signer); + if (hxctx) + hx509_context_free(&hxctx); + krb5_set_error_string(context, "cert creation failed"); + return ret; } /* @@ -299,6 +375,20 @@ _kdc_do_kx509(krb5_context context, if (ret) goto out; + /* Verify that the key is encoded RSA key */ + { + RSAPublicKey key; + size_t size; + + ret = decode_RSAPublicKey(req->pk_key.data, req->pk_key.length, + &key, &size); + if (ret) + goto out; + free_RSAPublicKey(&key); + if (size != req->pk_key.length) + ; + } + ALLOC(rep.certificate); if (rep.certificate == NULL) goto out; -- cgit