Update because I forgot to add OCSP support which needs a bit of extra
treatment as it uses an additional CERTREQ payload.
Index: iked.h
===================================================================
RCS file: /mount/openbsd/cvs/src/sbin/iked/iked.h,v
retrieving revision 1.121
diff -u -p -u -r1.121 iked.h
--- iked.h 11 May 2019 16:30:23 -0000 1.121
+++ iked.h 9 Aug 2019 14:20:27 -0000
@@ -536,6 +536,10 @@ struct iked_message {
struct iked_id msg_cert;
struct ibuf *msg_cookie;
+ uint8_t msg_certreq_type; /* CR Encoding*/
+ struct ibuf *msg_certreq_auth; /* CR Authority */
+ struct ibuf *msg_certreq_ocsp; /* CR OCSP values */
+
/* MOBIKE */
int msg_update_sa_addresses;
struct ibuf *msg_cookie2;
Index: ikev2.c
===================================================================
RCS file: /mount/openbsd/cvs/src/sbin/iked/ikev2.c,v
retrieving revision 1.171
diff -u -p -u -r1.171 ikev2.c
--- ikev2.c 11 May 2019 16:30:23 -0000 1.171
+++ ikev2.c 9 Aug 2019 14:23:15 -0000
@@ -82,6 +82,8 @@ int ikev2_send_error(struct iked *, str
struct iked_message *, uint8_t);
int ikev2_send_init_error(struct iked *, struct iked_message *);
+int ikev2_handle_certreq(struct iked*, struct iked_message *);
+
int ikev2_send_create_child_sa(struct iked *, struct iked_sa *,
struct iked_spi *, uint8_t);
int ikev2_ikesa_enable(struct iked *, struct iked_sa *, struct iked_sa *);
@@ -608,6 +610,9 @@ ikev2_ike_auth_recv(struct iked *env, st
struct iked_policy *policy = sa->sa_policy;
int ret = -1;
+ if (ikev2_handle_certreq(env, msg) != 0)
+ return (-1);
+
if (sa->sa_hdr.sh_initiator) {
id = &sa->sa_rid;
certid = &sa->sa_rcert;
@@ -2996,6 +3001,52 @@ ikev2_set_sa_proposal(struct iked_sa *sa
return (-1);
}
}
+ return (0);
+}
+
+int
+ikev2_handle_certreq(struct iked* env, struct iked_message *msg)
+{
+ struct iked_sa *sa;
+
+ if (msg->msg_certreq_type == IKEV2_CERT_NONE)
+ return (0);
+
+ if ((sa = msg->msg_sa) == NULL)
+ return (-1);
+
+ if (msg->msg_certreq_type != IKEV2_CERT_NONE) {
+ log_debug("%s: handling certreq with type %d.", __func__,
+ msg->msg_certreq_type);
+
+ /* Optional certreq for PSK */
+ if (sa->sa_hdr.sh_initiator)
+ sa->sa_stateinit |= IKED_REQ_CERT;
+ else
+ sa->sa_statevalid |= IKED_REQ_CERT;
+
+ ca_setreq(env, sa, &sa->sa_policy->pol_localid,
+ msg->msg_certreq_type,
+ ibuf_data(msg->msg_certreq_auth),
+ ibuf_length(msg->msg_certreq_auth),
+ PROC_CERT);
+ }
+
+ if (msg->msg_certreq_ocsp != NULL) {
+ ca_setreq(env, sa, &sa->sa_policy->pol_localid,
+ IKEV2_CERT_OCSP,
+ ibuf_data(msg->msg_certreq_auth),
+ ibuf_length(msg->msg_certreq_auth),
+ PROC_CERT);
+ }
+
+ /* Cleanup */
+ ibuf_release(msg->msg_certreq_auth);
+ msg->msg_certreq_auth = NULL;
+ ibuf_release(msg->msg_certreq_ocsp);
+ msg->msg_certreq_ocsp = NULL;
+ msg->msg_certreq_type = IKEV2_CERT_NONE;
+
return (0);
}
Index: ikev2_pld.c
===================================================================
RCS file: /mount/openbsd/cvs/src/sbin/iked/ikev2_pld.c,v
retrieving revision 1.71
diff -u -p -u -r1.71 ikev2_pld.c
--- ikev2_pld.c 11 May 2019 16:30:23 -0000 1.71
+++ ikev2_pld.c 9 Aug 2019 14:24:15 -0000
@@ -826,7 +826,6 @@ int
ikev2_pld_certreq(struct iked *env, struct ikev2_payload *pld,
struct iked_message *msg, size_t offset, size_t left)
{
- struct iked_sa *sa = msg->msg_sa;
struct ikev2_cert cert;
uint8_t *buf;
ssize_t len;
@@ -847,27 +846,39 @@ ikev2_pld_certreq(struct iked *env, stru
if (!ikev2_msg_frompeer(msg))
return (0);
- if (cert.cert_type == IKEV2_CERT_X509_CERT) {
- if (!len)
- return (0);
- if ((len % SHA_DIGEST_LENGTH) != 0) {
- log_debug("%s: invalid certificate request", __func__);
- return (-1);
- }
+ /* The contents of the Certification Authority field are defined only
+ * for X.509 certificates */
+ switch (cert.cert_type) {
+ case IKEV2_CERT_X509_CERT:
+ case IKEV2_CERT_HASHURL_X509:
+ case IKEV2_CERT_HASHURL_X509_BUNDLE:
+ if (len == 0)
+ return (0);
+ if ((len % SHA_DIGEST_LENGTH) != 0) {
+ log_debug("%s: invalid certificate request",
+ __func__);
+ return (-1);
+ }
+ if ((msg->msg_parent->msg_certreq_auth =
+ ibuf_new(buf, len)) == NULL)
+ return (-1);
+ msg->msg_parent->msg_certreq_type = cert.cert_type;
+ break;
+ case IKEV2_CERT_OCSP:
+ if (len == 0)
+ return (0);
+
+ /* OCSP is treated seperately from common CR payloads */
+ if ((msg->msg_parent->msg_certreq_ocsp =
+ ibuf_new(buf, len)) == NULL)
+ return (-1);
+ break;
+ default:
+ if (len != 0)
+ return (0);
+ msg->msg_parent->msg_certreq_type = cert.cert_type;
+ break;
}
-
- if (msg->msg_sa == NULL)
- return (-1);
-
- /* Optional certreq for PSK */
- if (sa->sa_hdr.sh_initiator)
- sa->sa_stateinit |= IKED_REQ_CERT;
- else
- sa->sa_statevalid |= IKED_REQ_CERT;
-
- ca_setreq(env, sa, &sa->sa_policy->pol_localid,
- cert.cert_type, buf, len, PROC_CERT);
-
return (0);
}