summaryrefslogtreecommitdiff
path: root/source4/heimdal/kdc
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-04-24 09:36:24 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 14:04:15 -0500
commitc33f6b2c370379dfd010600adc59e7439f1318f7 (patch)
tree2ac36b3751796f05ecb45a2ecd03bd166ed7182f /source4/heimdal/kdc
parent0eddf14b307e905663b95296aa695a10d3fb90f7 (diff)
downloadsamba-c33f6b2c370379dfd010600adc59e7439f1318f7.tar.gz
samba-c33f6b2c370379dfd010600adc59e7439f1318f7.tar.bz2
samba-c33f6b2c370379dfd010600adc59e7439f1318f7.zip
r15192: Update Samba4 to use current lorikeet-heimdal.
Andrew Bartlett (This used to be commit f0e538126c5cb29ca14ad0d8281eaa0a715ed94f)
Diffstat (limited to 'source4/heimdal/kdc')
-rw-r--r--source4/heimdal/kdc/524.c30
-rw-r--r--source4/heimdal/kdc/kaserver.c10
-rw-r--r--source4/heimdal/kdc/kdc-private.h8
-rw-r--r--source4/heimdal/kdc/kerberos4.c10
-rw-r--r--source4/heimdal/kdc/kerberos5.c97
-rwxr-xr-xsource4/heimdal/kdc/pkinit.c683
6 files changed, 308 insertions, 530 deletions
diff --git a/source4/heimdal/kdc/524.c b/source4/heimdal/kdc/524.c
index 1642975616..9fcf40a4c2 100644
--- a/source4/heimdal/kdc/524.c
+++ b/source4/heimdal/kdc/524.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: 524.c,v 1.35 2005/12/13 19:42:37 lha Exp $");
+RCSID("$Id: 524.c,v 1.36 2006/04/07 22:12:28 lha Exp $");
#include <krb5-v4compat.h>
@@ -374,19 +374,21 @@ _kdc_do_524(krb5_context context,
/* make reply */
memset(buf, 0, sizeof(buf));
sp = krb5_storage_from_mem(buf, sizeof(buf));
- krb5_store_int32(sp, ret);
- if(ret == 0){
- krb5_store_int32(sp, kvno);
- krb5_store_data(sp, ticket.cipher);
- /* Aargh! This is coded as a KTEXT_ST. */
- krb5_storage_seek(sp, MAX_KTXT_LEN - ticket.cipher.length, SEEK_CUR);
- krb5_store_int32(sp, 0); /* mbz */
- free_EncryptedData(&ticket);
- }
- ret = krb5_storage_to_data(sp, reply);
- reply->length = krb5_storage_seek(sp, 0, SEEK_CUR);
- krb5_storage_free(sp);
-
+ if (sp) {
+ krb5_store_int32(sp, ret);
+ if(ret == 0){
+ krb5_store_int32(sp, kvno);
+ krb5_store_data(sp, ticket.cipher);
+ /* Aargh! This is coded as a KTEXT_ST. */
+ krb5_storage_seek(sp, MAX_KTXT_LEN - ticket.cipher.length, SEEK_CUR);
+ krb5_store_int32(sp, 0); /* mbz */
+ free_EncryptedData(&ticket);
+ }
+ ret = krb5_storage_to_data(sp, reply);
+ reply->length = krb5_storage_seek(sp, 0, SEEK_CUR);
+ krb5_storage_free(sp);
+ } else
+ krb5_data_zero(reply);
if(spn)
free(spn);
if(server)
diff --git a/source4/heimdal/kdc/kaserver.c b/source4/heimdal/kdc/kaserver.c
index 069af21660..05fedeca29 100644
--- a/source4/heimdal/kdc/kaserver.c
+++ b/source4/heimdal/kdc/kaserver.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: kaserver.c,v 1.31 2005/12/13 19:44:27 lha Exp $");
+RCSID("$Id: kaserver.c,v 1.32 2006/04/02 01:54:37 lha Exp $");
#include <krb5-v4compat.h>
#include <rx.h>
@@ -453,8 +453,8 @@ do_authenticate (krb5_context context,
}
ret = _kdc_check_flags (context, config,
- &client_entry->entry, client_name,
- &server_entry->entry, server_name,
+ client_entry, client_name,
+ server_entry, server_name,
TRUE);
if (ret) {
make_error_reply (hdr, KAPWEXPIRED, reply);
@@ -752,8 +752,8 @@ do_getticket (krb5_context context,
}
ret = _kdc_check_flags (context, config,
- &client_entry->entry, client_name,
- &server_entry->entry, server_name,
+ client_entry, client_name,
+ server_entry, server_name,
FALSE);
if (ret) {
make_error_reply (hdr, KAPWEXPIRED, reply);
diff --git a/source4/heimdal/kdc/kdc-private.h b/source4/heimdal/kdc/kdc-private.h
index 729778a69e..c718b1fd52 100644
--- a/source4/heimdal/kdc/kdc-private.h
+++ b/source4/heimdal/kdc/kdc-private.h
@@ -18,9 +18,9 @@ krb5_error_code
_kdc_check_flags (
krb5_context /*context*/,
krb5_kdc_configuration */*config*/,
- hdb_entry */*client*/,
+ hdb_entry_ex */*client_ex*/,
const char */*client_name*/,
- hdb_entry */*server*/,
+ hdb_entry_ex */*server_ex*/,
const char */*server_name*/,
krb5_boolean /*is_as_req*/);
@@ -118,7 +118,9 @@ _kdc_pk_initialize (
krb5_context /*context*/,
krb5_kdc_configuration */*config*/,
const char */*user_id*/,
- const char */*x509_anchors*/);
+ const char */*anchors*/,
+ char **/*pool*/,
+ char **/*revoke*/);
krb5_error_code
_kdc_pk_mk_pa_reply (
diff --git a/source4/heimdal/kdc/kerberos4.c b/source4/heimdal/kdc/kerberos4.c
index 72ea41d9e6..030405adc2 100644
--- a/source4/heimdal/kdc/kerberos4.c
+++ b/source4/heimdal/kdc/kerberos4.c
@@ -35,7 +35,7 @@
#include <krb5-v4compat.h>
-RCSID("$Id: kerberos4.c,v 1.56 2005/12/13 19:44:01 lha Exp $");
+RCSID("$Id: kerberos4.c,v 1.57 2006/04/02 01:54:37 lha Exp $");
#ifndef swap32
static u_int32_t
@@ -201,8 +201,8 @@ _kdc_do_version4(krb5_context context,
}
ret = _kdc_check_flags (context, config,
- &client->entry, client_name,
- &server->entry, server_name,
+ client, client_name,
+ server, server_name,
TRUE);
if (ret) {
/* good error code? */
@@ -489,8 +489,8 @@ _kdc_do_version4(krb5_context context,
}
ret = _kdc_check_flags (context, config,
- &client->entry, client_name,
- &server->entry, server_name,
+ client, client_name,
+ server, server_name,
FALSE);
if (ret) {
/* good error code? */
diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c
index 3f9dcd12f8..68720d692e 100644
--- a/source4/heimdal/kdc/kerberos5.c
+++ b/source4/heimdal/kdc/kerberos5.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: kerberos5.c,v 1.201 2005/12/14 12:17:58 lha Exp $");
+RCSID("$Id: kerberos5.c,v 1.206 2006/04/02 01:54:37 lha Exp $");
#define MAX_TIME ((time_t)((1U << 31) - 1))
@@ -209,6 +209,50 @@ log_timestamp(krb5_context context,
type, authtime_str, starttime_str, endtime_str, renewtime_str);
}
+static void
+log_patypes(krb5_context context,
+ krb5_kdc_configuration *config,
+ METHOD_DATA *padata)
+{
+ struct rk_strpool *p = NULL;
+ char *str;
+ int i;
+
+ for (i = 0; i < padata->len; i++) {
+ switch(padata->val[i].padata_type) {
+ case KRB5_PADATA_PK_AS_REQ:
+ p = rk_strpoolprintf(p, "PK-INIT(ietf)");
+ break;
+ case KRB5_PADATA_PK_AS_REQ_WIN:
+ p = rk_strpoolprintf(p, "PK-INIT(win2k)");
+ break;
+ case KRB5_PADATA_PA_PK_OCSP_RESPONSE:
+ p = rk_strpoolprintf(p, "OCSP");
+ break;
+ case KRB5_PADATA_ENC_TIMESTAMP:
+ p = rk_strpoolprintf(p, "encrypted-timestamp");
+ break;
+ default:
+ p = rk_strpoolprintf(p, "%d", padata->val[i].padata_type);
+ break;
+ }
+ if (p && i + 1 < padata->len)
+ p = rk_strpoolprintf(p, ", ");
+ if (p == NULL) {
+ kdc_log(context, config, 0, "out of memory");
+ return;
+ }
+ }
+ str = rk_strpoolcollect(p);
+ kdc_log(context, config, 0, "Client sent patypes: %s", str);
+ free(str);
+}
+
+/*
+ *
+ */
+
+
static krb5_error_code
encode_reply(krb5_context context,
krb5_kdc_configuration *config,
@@ -642,11 +686,13 @@ get_pa_etype_info2(krb5_context context,
krb5_error_code
_kdc_check_flags(krb5_context context,
krb5_kdc_configuration *config,
- hdb_entry *client, const char *client_name,
- hdb_entry *server, const char *server_name,
+ hdb_entry_ex *client_ex, const char *client_name,
+ hdb_entry_ex *server_ex, const char *server_name,
krb5_boolean is_as_req)
{
- if(client != NULL) {
+ if(client_ex != NULL) {
+ hdb_entry *client = &client_ex->entry;
+
/* check client */
if (client->flags.invalid) {
kdc_log(context, config, 0,
@@ -680,8 +726,8 @@ _kdc_check_flags(krb5_context context,
return KRB5KDC_ERR_NAME_EXP;
}
- if (client->pw_end && *client->pw_end < kdc_time
- && !server->flags.change_pw) {
+ if (client->pw_end && *client->pw_end < kdc_time
+ && (server_ex == NULL || !server_ex->entry.flags.change_pw)) {
char pwend_str[100];
krb5_format_time(context, *client->pw_end,
pwend_str, sizeof(pwend_str), TRUE);
@@ -694,7 +740,9 @@ _kdc_check_flags(krb5_context context,
/* check server */
- if (server != NULL) {
+ if (server_ex != NULL) {
+ hdb_entry *server = &server_ex->entry;
+
if (server->flags.invalid) {
kdc_log(context, config, 0,
"Server has invalid flag set -- %s", server_name);
@@ -762,27 +810,28 @@ check_addresses(krb5_context context,
krb5_boolean result;
krb5_boolean only_netbios = TRUE;
int i;
-
+
if(config->check_ticket_addresses == 0)
return TRUE;
- if(addresses == NULL)
+ if(addresses == NULL)
return config->allow_null_ticket_addresses;
-
+
for (i = 0; i < addresses->len; ++i) {
- if (addresses->val[i].addr_type != KRB5_ADDRESS_NETBIOS) {
- only_netbios = FALSE;
- }
+ if (addresses->val[i].addr_type != KRB5_ADDRESS_NETBIOS) {
+ only_netbios = FALSE;
+ }
}
/* Windows sends it's netbios name, which I can only assume is
- * used for the 'allowed workstations' check. This is painful, but
- * we still want to check IP addresses if they happen to be
- * present. */
+ * used for the 'allowed workstations' check. This is painful,
+ * but we still want to check IP addresses if they happen to be
+ * present.
+ */
if(only_netbios)
return config->allow_null_ticket_addresses;
-
+
ret = krb5_sockaddr2address (context, from, &addr);
if(ret)
return FALSE;
@@ -867,8 +916,8 @@ _kdc_as_rep(krb5_context context,
}
ret = _kdc_check_flags(context, config,
- &client->entry, client_name,
- &server->entry, server_name,
+ client, client_name,
+ server, server_name,
TRUE);
if(ret)
goto out;
@@ -884,10 +933,12 @@ _kdc_as_rep(krb5_context context,
memset(&ek, 0, sizeof(ek));
if(req->padata){
- int i = 0;
+ int i;
PA_DATA *pa;
int found_pa = 0;
+ log_patypes(context, config, req->padata);
+
#ifdef PKINIT
kdc_log(context, config, 5,
"Looking for PKINIT pa-data -- %s", client_name);
@@ -1171,7 +1222,7 @@ _kdc_as_rep(krb5_context context,
if (p && i + 1 < b->etype.len)
p = rk_strpoolprintf(p, ", ");
if (p == NULL) {
- kdc_log(context, config, 0, "out of meory");
+ kdc_log(context, config, 0, "out of memory");
goto out;
}
}
@@ -2410,8 +2461,8 @@ tgs_rep2(krb5_context context,
}
ret = _kdc_check_flags(context, config,
- &client->entry, cpn,
- &server->entry, spn,
+ client, cpn,
+ server, spn,
FALSE);
if(ret)
goto out;
diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c
index 67934c0745..3f064f9d50 100755
--- a/source4/heimdal/kdc/pkinit.c
+++ b/source4/heimdal/kdc/pkinit.c
@@ -33,7 +33,7 @@
#include "kdc_locl.h"
-RCSID("$Id: pkinit.c,v 1.50 2006/02/13 11:48:21 lha Exp $");
+RCSID("$Id: pkinit.c,v 1.59 2006/04/22 12:10:16 lha Exp $");
#ifdef PKINIT
@@ -42,25 +42,17 @@ RCSID("$Id: pkinit.c,v 1.50 2006/02/13 11:48:21 lha Exp $");
#include <cms_asn1.h>
#include <pkinit_asn1.h>
-#include <openssl/evp.h>
-#include <openssl/x509.h>
-#include <openssl/x509v3.h>
-#include <openssl/bn.h>
-#include <openssl/asn1.h>
-#include <openssl/err.h>
+#include <hx509.h>
+#include "crypto-headers.h"
/* XXX copied from lib/krb5/pkinit.c */
struct krb5_pk_identity {
- EVP_PKEY *private_key;
- STACK_OF(X509) *cert;
- STACK_OF(X509) *trusted_certs;
- STACK_OF(X509_CRL) *crls;
- ENGINE *engine;
-};
-
-/* XXX copied from lib/krb5/pkinit.c */
-struct krb5_pk_cert {
- X509 *cert;
+ hx509_context hx509ctx;
+ hx509_verify_ctx verify_ctx;
+ hx509_certs certs;
+ hx509_certs anchors;
+ hx509_certs certpool;
+ hx509_revoke_ctx revoke;
};
enum pkinit_type {
@@ -71,7 +63,7 @@ enum pkinit_type {
struct pk_client_params {
enum pkinit_type type;
BIGNUM *dh_public_key;
- struct krb5_pk_cert *certificate;
+ hx509_cert cert;
unsigned nonce;
DH *dh;
EncryptionKey reply_key;
@@ -86,29 +78,6 @@ struct pk_principal_mapping {
} *val;
};
-/* XXX copied from lib/krb5/pkinit.c */
-#define OPENSSL_ASN1_MALLOC_ENCODE(T, B, BL, S, R) \
-{ \
- unsigned char *p; \
- (BL) = i2d_##T((S), NULL); \
- if ((BL) <= 0) { \
- (R) = EINVAL; \
- } else { \
- (B) = malloc((BL)); \
- if ((B) == NULL) { \
- (R) = ENOMEM; \
- } else { \
- p = (B); \
- (R) = 0; \
- (BL) = i2d_##T((S), &p); \
- if ((BL) <= 0) { \
- free((B)); \
- (R) = ASN1_OVERRUN; \
- } \
- } \
- } \
-}
-
static struct krb5_pk_identity *kdc_identity;
static struct pk_principal_mapping principal_mappings;
static struct krb5_dh_moduli **moduli;
@@ -185,59 +154,19 @@ pk_check_pkauthenticator(krb5_context context,
krb5_clear_error_string(context);
ret = KRB5KRB_ERR_GENERIC;
}
+
out:
free_Checksum(&checksum);
return ret;
}
-static krb5_error_code
-pk_encrypt_key(krb5_context context,
- krb5_keyblock *key,
- EVP_PKEY *public_key,
- krb5_data *encrypted_key,
- const heim_oid **oid)
-{
- krb5_error_code ret;
-
- encrypted_key->length = EVP_PKEY_size(public_key);
-
- if (encrypted_key->length < key->keyvalue.length + 11) { /* XXX */
- krb5_set_error_string(context, "pkinit: encrypted key too long");
- return KRB5KRB_ERR_GENERIC;
- }
-
- encrypted_key->data = malloc(encrypted_key->length);
- if (encrypted_key->data == NULL) {
- krb5_set_error_string(context, "malloc: out of memory");
- return ENOMEM;
- }
-
- ret = EVP_PKEY_encrypt(encrypted_key->data,
- key->keyvalue.data,
- key->keyvalue.length,
- public_key);
- if (ret < 0) {
- free(encrypted_key->data);
- krb5_set_error_string(context, "Can't encrypt key: %s",
- ERR_error_string(ERR_get_error(), NULL));
- return KRB5KRB_ERR_GENERIC;
- }
- if (encrypted_key->length != ret)
- krb5_abortx(context, "size of EVP_PKEY_size is not the "
- "size of the output");
-
- *oid = oid_id_pkcs1_rsaEncryption();
-
- return 0;
-}
-
void
_kdc_pk_free_client_param(krb5_context context,
pk_client_params *client_params)
{
- if (client_params->certificate)
- _krb5_pk_cert_free(client_params->certificate);
+ if (client_params->cert)
+ hx509_cert_free(client_params->cert);
if (client_params->dh)
DH_free(client_params->dh);
if (client_params->dh_public_key)
@@ -261,9 +190,7 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
memset(&key, 0, sizeof(key));
if (!DH_generate_key(client_params->dh)) {
- krb5_set_error_string(context, "Can't generate Diffie-Hellman "
- "keys (%s)",
- ERR_error_string(ERR_get_error(), NULL));
+ krb5_set_error_string(context, "Can't generate Diffie-Hellman keys");
ret = KRB5KRB_ERR_GENERIC;
goto out;
}
@@ -290,8 +217,7 @@ generate_dh_keyblock(krb5_context context, pk_client_params *client_params,
client_params->dh_public_key,
client_params->dh);
if (dh_gen_keylen == -1) {
- krb5_set_error_string(context, "Can't compute Diffie-Hellman key (%s)",
- ERR_error_string(ERR_get_error(), NULL));
+ krb5_set_error_string(context, "Can't compute Diffie-Hellman key");
ret = KRB5KRB_ERR_GENERIC;
goto out;
}
@@ -321,7 +247,7 @@ integer_to_BN(krb5_context context, const char *field, heim_integer *f)
krb5_set_error_string(context, "PKINIT: parsing BN failed %s", field);
return NULL;
}
- bn->neg = f->negative;
+ BN_set_negative(bn, f->negative);
return bn;
}
@@ -376,8 +302,7 @@ get_dh_param(krb5_context context,
dh = DH_new();
if (dh == NULL) {
- krb5_set_error_string(context, "Cannot create DH structure (%s)",
- ERR_error_string(ERR_get_error(), NULL));
+ krb5_set_error_string(context, "Cannot create DH structure");
ret = ENOMEM;
goto out;
}
@@ -413,9 +338,10 @@ get_dh_param(krb5_context context,
goto out;
}
- if (DH_check(dh, &dhret) != 1) {
- krb5_set_error_string(context, "PKINIT DH data not ok: %s",
- ERR_error_string(ERR_get_error(), NULL));
+
+ if (DH_check_pubkey(dh, client_params->dh_public_key, &dhret) != 1 ||
+ dhret != 0) {
+ krb5_set_error_string(context, "PKINIT DH data not ok");
ret = KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED;
goto out;
}
@@ -498,11 +424,12 @@ _kdc_pk_rd_padata(krb5_context context,
{
pk_client_params *client_params;
krb5_error_code ret;
- heim_oid eContentType = { 0, NULL };
+ heim_oid eContentType = { 0, NULL }, contentInfoOid = { 0, NULL };
krb5_data eContent = { 0, NULL };
krb5_data signed_content = { 0, NULL };
const char *type = "unknown type";
const heim_oid *pa_contentType;
+ int have_data;
*ret_params = NULL;
@@ -520,7 +447,7 @@ _kdc_pk_rd_padata(krb5_context context,
if (pa->padata_type == KRB5_PADATA_PK_AS_REQ_WIN) {
PA_PK_AS_REQ_Win2k r;
- ContentInfo info;
+ int have_data;
type = "PK-INIT-Win2k";
pa_contentType = oid_id_pkcs7_data();
@@ -535,47 +462,20 @@ _kdc_pk_rd_padata(krb5_context context,
goto out;
}
- ret = decode_ContentInfo(r.signed_auth_pack.data,
- r.signed_auth_pack.length, &info, NULL);
+ ret = hx509_cms_unwrap_ContentInfo(&r.signed_auth_pack,
+ &contentInfoOid,
+ &signed_content,
+ &have_data);
free_PA_PK_AS_REQ_Win2k(&r);
if (ret) {
krb5_set_error_string(context, "Can't decode PK-AS-REQ: %d", ret);
goto out;
}
- if (heim_oid_cmp(&info.contentType, oid_id_pkcs7_signedData())) {
- krb5_set_error_string(context, "PK-AS-REQ-Win2k invalid content "
- "type oid");
- free_ContentInfo(&info);
- ret = KRB5KRB_ERR_GENERIC;
- goto out;
- }
-
- if (info.content == NULL) {
- krb5_set_error_string(context,
- "PK-AS-REQ-Win2k no signed auth pack");
- free_ContentInfo(&info);
- ret = KRB5KRB_ERR_GENERIC;
- goto out;
- }
-
- signed_content.data = malloc(info.content->length);
- if (signed_content.data == NULL) {
- ret = ENOMEM;
- free_ContentInfo(&info);
- krb5_set_error_string(context, "PK-AS-REQ-Win2k out of memory");
- goto out;
- }
- signed_content.length = info.content->length;
- memcpy(signed_content.data, info.content->data, signed_content.length);
-
- free_ContentInfo(&info);
-
} else if (pa->padata_type == KRB5_PADATA_PK_AS_REQ) {
PA_PK_AS_REQ r;
- ContentInfo info;
- type = "PK-INIT-27";
+ type = "PK-INIT-IETF";
pa_contentType = oid_id_pkauthdata();
ret = decode_PA_PK_AS_REQ(pa->padata_value.data,
@@ -587,43 +487,17 @@ _kdc_pk_rd_padata(krb5_context context,
goto out;
}
- ret = decode_ContentInfo(r.signedAuthPack.data,
- r.signedAuthPack.length, &info, NULL);
- if (ret) {
- krb5_set_error_string(context, "Can't decode PK-AS-REQ: %d", ret);
- goto out;
- }
-
- if (heim_oid_cmp(&info.contentType, oid_id_pkcs7_signedData())) {
- krb5_set_error_string(context, "PK-AS-REQ invalid content "
- "type oid");
- free_ContentInfo(&info);
- free_PA_PK_AS_REQ(&r);
- ret = KRB5KRB_ERR_GENERIC;
- goto out;
- }
-
- if (info.content == NULL) {
- krb5_set_error_string(context, "PK-AS-REQ no signed auth pack");
- free_PA_PK_AS_REQ(&r);
- free_ContentInfo(&info);
- ret = KRB5KRB_ERR_GENERIC;
- goto out;
- }
+ /* XXX look at r.trustedCertifiers and r.kdcPkId */
- signed_content.data = malloc(info.content->length);
- if (signed_content.data == NULL) {
- ret = ENOMEM;
- free_ContentInfo(&info);
- free_PA_PK_AS_REQ(&r);
- krb5_set_error_string(context, "PK-AS-REQ out of memory");
+ ret = hx509_cms_unwrap_ContentInfo(&r.signedAuthPack,
+ &contentInfoOid,
+ &signed_content,
+ &have_data);
+ free_PA_PK_AS_REQ(&r);
+ if (ret) {
+ krb5_set_error_string(context, "Can't unwrap ContentInfo: %d", ret);
goto out;
}
- signed_content.length = info.content->length;
- memcpy(signed_content.data, info.content->data, signed_content.length);
-
- free_ContentInfo(&info);
- free_PA_PK_AS_REQ(&r);
} else {
krb5_clear_error_string(context);
@@ -631,24 +505,51 @@ _kdc_pk_rd_padata(krb5_context context,
goto out;
}
- ret = _krb5_pk_verify_sign(context,
- signed_content.data,
- signed_content.length,
- kdc_identity,
- &eContentType,
- &eContent,
- &client_params->certificate);
- if (ret)
+ ret = heim_oid_cmp(&contentInfoOid, oid_id_pkcs7_signedData());
+ if (ret != 0) {
+ krb5_set_error_string(context, "PK-AS-REQ-Win2k invalid content "
+ "type oid");
+ ret = KRB5KRB_ERR_GENERIC;
+ goto out;
+ }
+
+ if (!have_data) {
+ krb5_set_error_string(context,
+ "PK-AS-REQ-Win2k no signed auth pack");
+ ret = KRB5KRB_ERR_GENERIC;
goto out;
+ }
+
+ {
+ hx509_certs signer_certs;
+
+ ret = hx509_cms_verify_signed(kdc_identity->hx509ctx,
+ kdc_identity->verify_ctx,
+ signed_content.data,
+ signed_content.length,
+ kdc_identity->certpool,
+ &eContentType,
+ &eContent,
+ &signer_certs);
+ if (ret) {
+ kdc_log(context, config, 0,
+ "PK-INIT failed to verify signature %d", ret);
+ goto out;
+ }
+
+ ret = hx509_get_one_cert(kdc_identity->hx509ctx, signer_certs,
+ &client_params->cert);
+ hx509_certs_free(&signer_certs);
+ if (ret)
+ goto out;
+ }
-#if 0
/* Signature is correct, now verify the signed message */
if (heim_oid_cmp(&eContentType, pa_contentType)) {
krb5_set_error_string(context, "got wrong oid for pkauthdata");
ret = KRB5_BADMSGTYPE;
goto out;
}
-#endif
if (pa->padata_type == KRB5_PADATA_PK_AS_REQ_WIN) {
AuthPack_Win2k ap;
@@ -716,19 +617,15 @@ _kdc_pk_rd_padata(krb5_context context,
} else
krb5_abortx(context, "internal pkinit error");
- /*
- * Remaining fields (ie kdcCert and encryptionCert) in the request
- * are ignored for now.
- */
-
kdc_log(context, config, 0, "PK-INIT request of type %s", type);
- out:
+out:
if (signed_content.data)
free(signed_content.data);
krb5_data_free(&eContent);
free_oid(&eContentType);
+ free_oid(&contentInfoOid);
if (ret)
_kdc_pk_free_client_param(context, client_params);
else
@@ -750,7 +647,7 @@ BN_to_integer(krb5_context context, BIGNUM *bn, heim_integer *integer)
return ENOMEM;
}
BN_bn2bin(bn, integer->data);
- integer->negative = bn->neg;
+ integer->negative = BN_is_negative(bn);
return 0;
}
@@ -762,78 +659,11 @@ pk_mk_pa_reply_enckey(krb5_context context,
krb5_keyblock *reply_key,
ContentInfo *content_info)
{
- KeyTransRecipientInfo *ri;
- EnvelopedData ed;
krb5_error_code ret;
- krb5_crypto crypto = NULL;
- krb5_data buf, sd_data, enc_sd_data, iv, params;
- krb5_keyblock tmp_key;
- krb5_enctype enveloped_enctype;
- X509_NAME *issuer_name;
- heim_integer *serial;
+ krb5_data buf, o;
size_t size;
- AlgorithmIdentifier *enc_alg;
- int i;
-
- krb5_data_zero(&enc_sd_data);
- krb5_data_zero(&sd_data);
- krb5_data_zero(&iv);
-
- memset(&tmp_key, 0, sizeof(tmp_key));
- memset(&ed, 0, sizeof(ed));
-
- /* default to DES3 if client doesn't tell us */
- enveloped_enctype = ETYPE_DES3_CBC_NONE_CMS;
-
- for (i = 0; i < req->req_body.etype.len; i++) {
- switch(req->req_body.etype.val[i]) {
- case 15: /* des-ede3-cbc-Env-OID */
- enveloped_enctype = ETYPE_DES3_CBC_NONE_CMS;
- break;
- default:
- break;
- }
- }
-
- ret = krb5_generate_random_keyblock(context, enveloped_enctype, &tmp_key);
- if (ret)
- goto out;
- ret = krb5_crypto_init(context, &tmp_key, 0, &crypto);
- if (ret)
- goto out;
-
-
- ret = krb5_crypto_getblocksize(context, crypto, &iv.length);
- if (ret)
- goto out;
-
- ret = krb5_data_alloc(&iv, iv.length);
- if (ret) {
- krb5_set_error_string(context, "malloc out of memory");
- goto out;
- }
-
- krb5_generate_random_block(iv.data, iv.length);
-
- enc_alg = &ed.encryptedContentInfo.contentEncryptionAlgorithm;
-
- ret = krb5_enctype_to_oid(context, enveloped_enctype, &enc_alg->algorithm);
- if (ret)
- goto out;
-
- ret = krb5_crypto_set_params(context, crypto, &iv, &params);
- if (ret)
- goto out;
-
- ALLOC(enc_alg->parameters);
- if (enc_alg->parameters == NULL) {
- krb5_data_free(&params);
- krb5_set_error_string(context, "malloc out of memory");
- return ENOMEM;
- }
- enc_alg->parameters->data = params.data;
- enc_alg->parameters->length = params.length;
+ krb5_data_zero(&buf);
switch (client_params->type) {
case PKINIT_COMPAT_WIN2K: {
@@ -897,139 +727,21 @@ pk_mk_pa_reply_enckey(krb5_context context,
if (buf.length != size)
krb5_abortx(context, "Internal ASN.1 encoder error");
- /*
- * CRL's are not transfered -- should be ?
- */
-
- ret = _krb5_pk_create_sign(context,
- oid_id_pkrkeydata(),
- &buf,
- kdc_identity,
- &sd_data);
- krb5_data_free(&buf);
- if (ret)
- goto out;
-
- ret = krb5_encrypt_ivec(context, crypto, 0,
- sd_data.data, sd_data.length,
- &enc_sd_data,
- iv.data);
-
- ALLOC_SEQ(&ed.recipientInfos, 1);
- if (ed.recipientInfos.val == NULL) {
- krb5_clear_error_string(context);
- ret = ENOMEM;
- goto out;
- }
-
- ri = &ed.recipientInfos.val[0];
-
- ri->version = 0;
- ri->rid.element = choice_CMSIdentifier_issuerAndSerialNumber;
-
- issuer_name = X509_get_issuer_name(client_params->certificate->cert);
- OPENSSL_ASN1_MALLOC_ENCODE(X509_NAME, buf.data, buf.length,
- issuer_name, ret);
- if (ret) {
- krb5_clear_error_string(context);
- goto out;
- }
- ret = decode_Name(buf.data, buf.length,
- &ri->rid.u.issuerAndSerialNumber.issuer,
- NULL);
- free(buf.data);
- if (ret) {
- krb5_set_error_string(context, "pkinit: failed to parse Name");
- goto out;
- }
-
- serial = &ri->rid.u.issuerAndSerialNumber.serialNumber;
- {
- ASN1_INTEGER *isn;
- BIGNUM *bn;
-
- isn = X509_get_serialNumber(client_params->certificate->cert);
- bn = ASN1_INTEGER_to_BN(isn, NULL);
- if (bn == NULL) {
- ret = ENOMEM;
- krb5_clear_error_string(context);
- goto out;
- }
- ret = BN_to_integer(context, bn, serial);
- BN_free(bn);
- if (ret) {
- krb5_clear_error_string(context);
- goto out;
- }
- }
-
- {
- const heim_oid *pk_enc_key_oid;
- krb5_data enc_tmp_key;
-
- ret = pk_encrypt_key(context, &tmp_key,
- X509_get_pubkey(client_params->certificate->cert),
- &enc_tmp_key,
- &pk_enc_key_oid);
- if (ret)
- goto out;
-
- ri->encryptedKey.length = enc_tmp_key.length;
- ri->encryptedKey.data = enc_tmp_key.data;
-
- ret = copy_oid(pk_enc_key_oid, &ri->keyEncryptionAlgorithm.algorithm);
- if (ret)
- goto out;
- }
-
- /*
- *
- */
-
- ed.version = 0;
- ed.originatorInfo = NULL;
-
- ret = copy_oid(oid_id_pkcs7_signedData(), &ed.encryptedContentInfo.contentType);
- if (ret) {
- krb5_clear_error_string(context);
- goto out;
- }
-
- ALLOC(ed.encryptedContentInfo.encryptedContent);
- if (ed.encryptedContentInfo.encryptedContent == NULL) {
- krb5_clear_error_string(context);
- ret = ENOMEM;
- goto out;
- }
-
- ed.encryptedContentInfo.encryptedContent->data = enc_sd_data.data;
- ed.encryptedContentInfo.encryptedContent->length = enc_sd_data.length;
- krb5_data_zero(&enc_sd_data);
-
- ed.unprotectedAttrs = NULL;
-
- ASN1_MALLOC_ENCODE(EnvelopedData, buf.data, buf.length, &ed, &size, ret);
- if (ret) {
- krb5_set_error_string(context,
- "ASN.1 encoding of EnvelopedData failed (%d)",
- ret);
+ ret = hx509_cms_envelope_1(kdc_identity->hx509ctx,
+ client_params->cert,
+ buf.data, buf.length, NULL,
+ oid_id_pkcs7_signedData(), &o);
+ if (ret)
goto out;
- }
-
+
ret = _krb5_pk_mk_ContentInfo(context,
- &buf,
+ &o,
oid_id_pkcs7_envelopedData(),
content_info);
- krb5_data_free(&buf);
+ free_octet_string(&o);
out:
- if (crypto)
- krb5_crypto_destroy(context, crypto);
- krb5_free_keyblock_contents(context, &tmp_key);
- krb5_data_free(&enc_sd_data);
- krb5_data_free(&iv);
- free_EnvelopedData(&ed);
-
+ krb5_data_free(&buf);
return ret;
}
@@ -1044,37 +756,32 @@ pk_mk_pa_reply_dh(krb5_context context,
krb5_keyblock *reply_key,
ContentInfo *content_info)
{
- ASN1_INTEGER *dh_pub_key = NULL;
- ContentInfo contentinfo;
KDCDHKeyInfo dh_info;
+ krb5_data signed_data, buf;
+ ContentInfo contentinfo;
krb5_error_code ret;
- SignedData sd;
- krb5_data buf, signed_data;
size_t size;
+ heim_integer i;
memset(&contentinfo, 0, sizeof(contentinfo));
memset(&dh_info, 0, sizeof(dh_info));
- memset(&sd, 0, sizeof(sd));
krb5_data_zero(&buf);
krb5_data_zero(&signed_data);
- dh_pub_key = BN_to_ASN1_INTEGER(kdc_dh->pub_key, NULL);
- if (dh_pub_key == NULL) {
- krb5_set_error_string(context, "BN_to_ASN1_INTEGER() failed (%s)",
- ERR_error_string(ERR_get_error(), NULL));
- ret = ENOMEM;
- goto out;
- }
+ ret = BN_to_integer(context, kdc_dh->pub_key, &i);
+ if (ret)
+ return ret;
- OPENSSL_ASN1_MALLOC_ENCODE(ASN1_INTEGER, buf.data, buf.length, dh_pub_key,
- ret);
- ASN1_INTEGER_free(dh_pub_key);
+ ASN1_MALLOC_ENCODE(DHPublicKey, buf.data, buf.length, &i, &size, ret);
if (ret) {
- krb5_set_error_string(context, "Encoding of ASN1_INTEGER failed (%s)",
- ERR_error_string(ERR_get_error(), NULL));
- goto out;
+ krb5_set_error_string(context, "ASN.1 encoding of "
+ "DHPublicKey failed (%d)", ret);
+ krb5_clear_error_string(context);
+ return ret;
}
-
+ if (buf.length != size)
+ krb5_abortx(context, "Internal ASN.1 encoder error");
+
dh_info.subjectPublicKey.length = buf.length * 8;
dh_info.subjectPublicKey.data = buf.data;
@@ -1095,12 +802,36 @@ pk_mk_pa_reply_dh(krb5_context context,
* filled in above
*/
- ret = _krb5_pk_create_sign(context,
- oid_id_pkdhkeydata(),
- &buf,
- kdc_identity,
- &signed_data);
- krb5_data_free(&buf);
+ {
+ hx509_cert cert;
+ hx509_query *q;
+
+ ret = hx509_query_alloc(kdc_identity->hx509ctx, &q);
+ if (ret)
+ goto out;
+
+ hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY);
+ hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE);
+
+ ret = hx509_certs_find(kdc_identity->hx509ctx,
+ kdc_identity->certs,
+ q,
+ &cert);
+ hx509_query_free(kdc_identity->hx509ctx, q);
+ if (ret)
+ goto out;
+
+ ret = hx509_cms_create_signed_1(kdc_identity->hx509ctx,
+ oid_id_pkdhkeydata(),
+ buf.data,
+ buf.length,
+ NULL,
+ cert,
+ kdc_identity->anchors,
+ kdc_identity->certpool,
+ &signed_data);
+ hx509_cert_free(cert);
+ }
if (ret)
goto out;
@@ -1112,6 +843,7 @@ pk_mk_pa_reply_dh(krb5_context context,
goto out;
out:
+ krb5_data_free(&buf);
krb5_data_free(&signed_data);
free_KDCDHKeyInfo(&dh_info);
@@ -1322,62 +1054,59 @@ _kdc_pk_mk_pa_reply(krb5_context context,
static int
pk_principal_from_X509(krb5_context context,
krb5_kdc_configuration *config,
- struct krb5_pk_cert *client_cert,
- krb5_principal *principal)
+ hx509_cert client_cert,
+ krb5_const_principal match)
{
- krb5_error_code ret;
- GENERAL_NAMES *gens;
- GENERAL_NAME *gen;
- ASN1_OBJECT *obj;
- int i;
+ hx509_octet_string_list list;
+ int ret, i, found = 0;
- *principal = NULL;
+ memset(&list, 0 , sizeof(list));
- obj = OBJ_txt2obj("1.3.6.1.5.2.2",1);
-
- gens = X509_get_ext_d2i(client_cert->cert, NID_subject_alt_name,
- NULL, NULL);
- if (gens == NULL)
- return 1;
+ ret = hx509_cert_find_subjectAltName_otherName(client_cert,
+ oid_id_pkinit_san(),
+ &list);
+ if (ret)
+ goto out;
- for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) {
+ for (i = 0; !found && i < list.len; i++) {
+ krb5_principal_data principal;
KRB5PrincipalName kn;
- size_t len, size;
- void *p;
-
- gen = sk_GENERAL_NAME_value(gens, i);
- if (gen->type != GEN_OTHERNAME)
- continue;
-
- if(OBJ_cmp(obj, gen->d.otherName->type_id) != 0)
- continue;
-
- p = ASN1_STRING_data(gen->d.otherName->value->value.sequence);
- len = ASN1_STRING_length(gen->d.otherName->value->value.sequence);
+ size_t size;
- ret = decode_KRB5PrincipalName(p, len, &kn, &size);
+ ret = decode_KRB5PrincipalName(list.val[i].data,
+ list.val[i].length,
+ &kn, &size);
if (ret) {
kdc_log(context, config, 0,
"Decoding kerberos name in certificate failed: %s",
krb5_get_err_text(context, ret));
- continue;
+ break;
}
-
- *principal = malloc(sizeof(**principal));
- if (*principal == NULL) {
- free_KRB5PrincipalName(&kn);
- return 1;
+ if (size != list.val[i].length) {
+ kdc_log(context, config, 0,
+ "Decoding kerberos name have extra bits on the end");
+ return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
}
- (*principal)->name = kn.principalName;
- (*principal)->realm = kn.realm;
- return 0;
+ principal.name = kn.principalName;
+ principal.realm = kn.realm;
+
+ if (krb5_principal_compare(context, &principal, match) == TRUE)
+ found = 1;
+ free_KRB5PrincipalName(&kn);
}
- return 1;
-}
+out:
+ hx509_free_octet_string_list(&list);
+ if (ret)
+ return ret;
+
+ if (!found)
+ return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
+
+ return 0;
+}
-/* XXX match with issuer too ? */
krb5_error_code
_kdc_pk_check_client(krb5_context context,
@@ -1387,45 +1116,34 @@ _kdc_pk_check_client(krb5_context context,
pk_client_params *client_params,
char **subject_name)
{
- struct krb5_pk_cert *client_cert = client_params->certificate;
- krb5_principal cert_princ;
- X509_NAME *name;
- char *subject = NULL;
krb5_error_code ret;
- krb5_boolean b;
+ hx509_name name;
int i;
- *subject_name = NULL;
-
- name = X509_get_subject_name(client_cert->cert);
- if (name == NULL) {
- krb5_set_error_string(context, "PKINIT can't get subject name");
- return ENOMEM;
- }
- subject = X509_NAME_oneline(name, NULL, 0);
- if (subject == NULL) {
- krb5_set_error_string(context, "PKINIT can't get subject name");
- return ENOMEM;
- }
- *subject_name = strdup(subject);
- if (*subject_name == NULL) {
- krb5_set_error_string(context, "out of memory");
- return ENOMEM;
- }
- OPENSSL_free(subject);
-
if (config->enable_pkinit_princ_in_cert) {
ret = pk_principal_from_X509(context, config,
- client_cert, &cert_princ);
- if (ret == 0) {
- b = krb5_principal_compare(context, client_princ, cert_princ);
- krb5_free_principal(context, cert_princ);
- if (b == TRUE)
- return 0;
- }
+ client_params->cert,
+ client_princ);
+ if (ret == 0)
+ return 0;
}
+ ret = hx509_cert_get_subject(client_params->cert, &name);
+ if (ret)
+ return ret;
+
+ ret = hx509_name_to_string(name, subject_name);
+ hx509_name_free(&name);
+ if (ret)
+ return ret;
+
+ kdc_log(context, config, 5,
+ "Trying to authorize subject DN %s",
+ *subject_name);
+
for (i = 0; i < principal_mappings.len; i++) {
+ krb5_boolean b;
+
b = krb5_principal_compare(context,
client_princ,
principal_mappings.val[i].principal);
@@ -1436,6 +1154,7 @@ _kdc_pk_check_client(krb5_context context,
return 0;
}
free(*subject_name);
+
*subject_name = NULL;
krb5_set_error_string(context, "PKINIT no matching principals");
return KRB5_KDC_ERR_CLIENT_NAME_MISMATCH;
@@ -1477,7 +1196,9 @@ krb5_error_code
_kdc_pk_initialize(krb5_context context,
krb5_kdc_configuration *config,
const char *user_id,
- const char *x509_anchors)
+ const char *anchors,
+ char **pool,
+ char **revoke)
{
const char *file;
krb5_error_code ret;
@@ -1495,13 +1216,15 @@ _kdc_pk_initialize(krb5_context context,
principal_mappings.len = 0;
principal_mappings.val = NULL;
- ret = _krb5_pk_load_openssl_id(context,
- &kdc_identity,
- user_id,
- x509_anchors,
- NULL,
- NULL,
- NULL);
+ ret = _krb5_pk_load_id(context,
+ &kdc_identity,
+ user_id,
+ anchors,
+ pool,
+ revoke,
+ NULL,
+ NULL,
+ NULL);
if (ret) {
krb5_warn(context, ret, "PKINIT: failed to load");
config->enable_pkinit = 0;