summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1999-08-26 22:30:22 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1999-08-26 22:30:22 +0000
commit9577c566ef4b3999ee85edfd741d7bb43790fe46 (patch)
tree9978a3dfac91b8a5dc445d8998bd65fdd207d11a /sbin
parentfd017c93a0b2179074671fb0494c38c9456fd904 (diff)
Merge with EOM 1.97
author: niklas Support dynamic loading of libkeynote too. Build isakmpd static by default. Stylistic cleanup of keynote policy code. Correct some libcrypto calls. author: ho We want the exchange name if it's one of our (passive) connections. author: angelos Warning about RSA-specific code. author: angelos Complete policy work; tested for the shared-key case. Documentation needed.
Diffstat (limited to 'sbin')
-rw-r--r--sbin/isakmpd/ike_quick_mode.c146
1 files changed, 101 insertions, 45 deletions
diff --git a/sbin/isakmpd/ike_quick_mode.c b/sbin/isakmpd/ike_quick_mode.c
index 48b7626538a..9c8042e74a6 100644
--- a/sbin/isakmpd/ike_quick_mode.c
+++ b/sbin/isakmpd/ike_quick_mode.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ike_quick_mode.c,v 1.20 1999/08/05 22:42:04 niklas Exp $ */
-/* $EOM: ike_quick_mode.c,v 1.93 1999/07/25 09:12:36 niklas Exp $ */
+/* $OpenBSD: ike_quick_mode.c,v 1.21 1999/08/26 22:30:21 niklas Exp $ */
+/* $EOM: ike_quick_mode.c,v 1.97 1999/08/26 11:21:50 niklas Exp $ */
/*
* Copyright (c) 1998, 1999 Niklas Hallqvist. All rights reserved.
@@ -37,7 +37,7 @@
#include <stdlib.h>
#include <string.h>
-#ifdef USE_KEYNOTE
+#if defined (USE_KEYNOTE) || defined (HAVE_DLOPEN)
#include <keynote.h>
#endif
@@ -55,9 +55,11 @@
#include "log.h"
#include "math_group.h"
#include "message.h"
+#include "policy.h"
#include "prf.h"
#include "sa.h"
#include "transport.h"
+#include "x509.h"
static void gen_g_xy (struct message *);
static int initiator_send_HASH_SA_NONCE (struct message *);
@@ -68,8 +70,8 @@ static int responder_recv_HASH_SA_NONCE (struct message *);
static int responder_send_HASH_SA_NONCE (struct message *);
static int responder_recv_HASH (struct message *);
-#ifdef USE_KEYNOTE
-static int check_policy (struct exchange *, struct sa *);
+#if defined (USE_KEYNOTE) || defined (HAVE_DLOPEN)
+static int check_policy (struct exchange *, struct sa *, struct sa *);
#endif
int (*ike_quick_mode_initiator[]) (struct message *) = {
@@ -84,12 +86,13 @@ int (*ike_quick_mode_responder[]) (struct message *) = {
responder_recv_HASH
};
-#ifdef USE_KEYNOTE
+#if defined (USE_KEYNOTE) || defined (HAVE_DLOPEN)
-/* Policy session ID and other necessary globals */
+/* Policy session ID and other necessary globals. XXX Why not in policy.h? */
extern int keynote_sessid;
extern struct exchange *policy_exchange;
extern struct sa *policy_sa;
+extern struct sa *policy_isakmp_sa;
/* How many return values will policy handle -- true/false for now */
#define RETVALUES_NUM 2
@@ -99,54 +102,95 @@ extern struct sa *policy_sa;
* acceptable.
*/
static int
-check_policy (struct exchange *exchange, struct sa *sa)
+check_policy (struct exchange *exchange, struct sa *sa, struct sa *isakmp_sa)
{
char *return_values[RETVALUES_NUM];
+ struct keynote_deckey dc;
char *principal = NULL;
int result;
+ RSA *key;
- /* If there is no policy setup, everything fails */
+ /* If there is no policy setup, everything fails. */
if (keynote_sessid < 0)
return 0;
- /* Initialize -- we'll let the callback do all the work */
+ /* Initialize -- we'll let the callback do all the work. */
policy_exchange = exchange;
policy_sa = sa;
+ policy_isakmp_sa = isakmp_sa;
- /* Set the return values; true/false for now at least */
- return_values[0] = "false"; /* Order of values in array is important */
+ /* Set the return values; true/false for now at least. */
+ return_values[0] = "false"; /* Order of values in array is important. */
return_values[1] = "true";
- /* XXX Create a principal (authorizer) for the SA/ID request. */
- principal = "dontmatter";
+ /* Create a principal (authorizer) for the SA/ID request. */
+ switch (isakmp_sa->recv_certtype)
+ {
+ case ISAKMP_CERTENC_NONE:
+ /* For shared keys, just duplicate the passphrase. */
+ principal = strdup (isakmp_sa->recv_cert);
+ if (principal == NULL)
+ return 0;
+ break;
+
+ case ISAKMP_CERTENC_X509_SIG:
+ /* Retrieve key from certificate. */
+ if (!x509_cert_get_key (isakmp_sa->recv_cert, &key))
+ {
+ log_print ("check_policy: failed to get key from X509 cert");
+ return 0;
+ }
+
+ /* XXX RSA-specific. */
+ dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA;
+ dc.dec_key = (void *) key;
+ principal = LK (kn_encode_key, (&dc, INTERNAL_ENC_PKCS1, ENCODING_HEX,
+ KEYNOTE_PUBLIC_KEY));
+ if (LKV (keynote_errno) == ERROR_MEMORY)
+ log_fatal ("check_policy: failed to get memory for public key");
+ if (principal == NULL)
+ return 0;
+ LC (RSA_free, (key));
+ break;
+
+ /* XXX Eventually handle these. */
+ case ISAKMP_CERTENC_PKCS:
+ case ISAKMP_CERTENC_PGP:
+ case ISAKMP_CERTENC_DNS:
+ case ISAKMP_CERTENC_X509_KE:
+ case ISAKMP_CERTENC_KERBEROS:
+ case ISAKMP_CERTENC_CRL:
+ case ISAKMP_CERTENC_ARL:
+ case ISAKMP_CERTENC_SPKI:
+ case ISAKMP_CERTENC_X509_ATTR:
+#if 0
+ case ISAKMP_CERTENC_KEYNOTE:
+#endif
+ default:
+ log_print ("check_policy: "
+ "unknown/unsupported certificate/authentication method %d",
+ isakmp_sa->recv_certtype);
+ return 0;
+ }
/*
* Add the authorizer (who is requesting the SA/ID);
* this may be a public or a secret key, depending on
* what mode of authentication we used in Phase 1.
*/
- if (kn_add_authorizer (keynote_sessid, principal) == -1)
+ if (LK (kn_add_authorizer, (keynote_sessid, principal)) == -1)
return 0;
- /*
- * XXX If doing X509 certificates, create a fake KeyNote assertion,
- * delegating from the CA to the actual pubkey.
- */
-
- /* Ask policy */
- result = kn_do_query (keynote_sessid, return_values, RETVALUES_NUM);
-
- /* Remove authorizer from the session */
- kn_remove_authorizer (keynote_sessid, principal);
+ /* Ask policy. */
+ result = LK (kn_do_query, (keynote_sessid, return_values, RETVALUES_NUM));
-#if 0
+ /* Remove authorizer from the session. */
+ LK (kn_remove_authorizer, (keynote_sessid, principal));
free (principal);
-#endif
- /* Check what policy said */
+ /* Check what policy said. */
if (result < 0)
{
- /* XXX Some sort of debug message about failure */
log_debug (LOG_MISC, 40, "check_policy: kn_do_query returned %d",
result);
return 0;
@@ -998,10 +1042,7 @@ responder_recv_HASH_SA_NONCE (struct message *msg)
struct proto *proto;
struct sockaddr *src, *dst;
socklen_t srclen, dstlen;
-
-#ifndef USE_KEYNOTE
char *name;
-#endif
hashp = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_HASH]);
hash = hashp->p;
@@ -1147,9 +1188,12 @@ responder_recv_HASH_SA_NONCE (struct message *msg)
sizeof ((struct sockaddr_in *)src)->sin_addr.s_addr);
}
-#ifdef USE_KEYNOTE
+#if defined (USE_KEYNOTE)
if (message_negotiate_sa (msg, check_policy))
goto cleanup;
+#elif defined (HAVE_DLOPEN)
+ if (message_negotiate_sa (msg, libkeynote ? check_policy : 0))
+ goto cleanup;
#else
if (message_negotiate_sa (msg, 0))
goto cleanup;
@@ -1209,11 +1253,8 @@ responder_recv_HASH_SA_NONCE (struct message *msg)
if (kep && ipsec_save_g_x (msg))
goto cleanup;
-#ifndef USE_KEYNOTE
/*
- * XXX This code is no longer necessary, as policy determines acceptance
- * XXX of IDs/SAs. (angelos@openbsd.org)
- * XXX Keep it if not USE_KEYNOTE for now, though.
+ * Try to find and set the connection name on the exchange.
*/
/*
@@ -1221,19 +1262,34 @@ responder_recv_HASH_SA_NONCE (struct message *msg)
* name and set it on the exchange.
*/
name = connection_passive_lookup_by_ids (ie->id_ci, ie->id_cr);
- if (!name)
+ if (name)
{
- /* XXX Notify peer and log. */
- goto cleanup;
+ exchange->name = strdup (name);
+ if (!exchange->name)
+ {
+ log_error ("responder_recv_HASH_SA_NONCE: strdup (\"%s\") failed",
+ name);
+ goto cleanup;
+ }
}
-
- exchange->name = strdup (name);
- if (!exchange->name)
+#ifndef USE_KEYNOTE
+#ifdef HAVE_DLOPEN
+ else if (!libkeynote)
+#else
+ else
+#endif
{
- log_error ("responder_recv_HASH_SA_NONCE: strdup (\"%s\") failed", name);
+ /*
+ * This code is no longer necessary, as policy determines acceptance
+ * of IDs/SAs. (angelos@openbsd.org)
+ *
+ * XXX Keep it if not USE_KEYNOTE for now, though.
+ */
+
+ /* XXX Notify peer and log. */
goto cleanup;
}
-#endif
+#endif /* USE_KEYNOTE */
return retval;