Issue certificates.

git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@19909 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2007-01-14 23:16:14 +00:00
parent 2df6875132
commit 70056908b1

View File

@@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@@ -33,6 +33,8 @@
#include "kdc_locl.h" #include "kdc_locl.h"
#include <hex.h> #include <hex.h>
#include <rfc2459_asn1.h>
#include <hx509.h>
RCSID("$Id$"); RCSID("$Id$");
@@ -140,72 +142,145 @@ build_certificate(krb5_context context,
krb5_principal principal, krb5_principal principal,
krb5_data *certificate) krb5_data *certificate)
{ {
/* XXX write code here to generate certificates */ hx509_context hxctx = NULL;
FILE *in, *out; hx509_ca_tbs tbs = NULL;
krb5_error_code ret; hx509_env env = NULL;
const char *program; hx509_cert cert = NULL;
char *str, *strkey; hx509_cert signer = NULL;
char tstr[64]; int ret;
pid_t pid;
snprintf(tstr, sizeof(tstr), "%lu", (unsigned long)endtime); if (krb5_principal_get_comp_string(context, principal, 1) != NULL) {
kdc_log(context, config, 0, "Principal is not a user");
ret = base64_encode(key->data, key->length, &strkey); return EINVAL;
if (ret < 0) {
krb5_set_error_string(context, "failed to base64 encode key");
return ENOMEM;
} }
program = krb5_config_get_string(context, ret = hx509_context_init(&hxctx);
NULL, if (ret)
"kdc", goto out;
"kx509_cert_program",
NULL);
if (program == NULL) {
free(strkey);
krb5_set_error_string(context, "no certificate program configured");
return ENOENT;
}
ret = krb5_unparse_name(context, principal, &str); ret = hx509_env_init(hxctx, &env);
if (ret) { if (ret)
free(strkey); goto out;
return ret;
}
pid = pipe_execv(&in, &out, NULL, program, str, tstr, NULL); ret = hx509_env_add(hxctx, env, "principal-name",
free(str); krb5_principal_get_comp_string(context, principal, 0));
if (pid <= 0) { if (ret)
free(strkey); goto out;
krb5_set_error_string(context,
"Failed to run the cert program %s",
program);
return ret;
}
fprintf(in, "%s\n", strkey);
fclose(in);
free(strkey);
{ {
unsigned buf[1024 * 10]; hx509_certs certs;
size_t len; hx509_query *q;
len = fread(buf, 1, sizeof(buf), out); ret = hx509_certs_init(hxctx, config->kx509_ca, 0,
fclose(out); NULL, &certs);
if(len == 0) {
krb5_set_error_string(context,
"Certificate program returned no data");
return KRB5KDC_ERR_PREAUTH_FAILED;
}
ret = krb5_data_copy(certificate, buf, len);
if (ret) { if (ret) {
krb5_set_error_string(context, "Failed To copy certificate"); kdc_log(context, config, 0, "Failed to load CA %s",
return ret; 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;
} }
} }
kill(pid, SIGKILL);
waitpid(pid, NULL, 0); ret = hx509_ca_tbs_init(hxctx, &tbs);
if (ret)
goto out;
{
SubjectPublicKeyInfo spki;
memset(&spki, 0, sizeof(spki));
heim_any any;
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;
}
{
hx509_certs certs;
hx509_cert template;
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 = hx509_get_one_cert(hxctx, certs, &template);
hx509_certs_free(&certs);
if (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;
}
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; 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 +374,20 @@ _kdc_do_kx509(krb5_context context,
if (ret) if (ret)
goto out; 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); ALLOC(rep.certificate);
if (rep.certificate == NULL) if (rep.certificate == NULL)
goto out; goto out;