aboutsummaryrefslogtreecommitdiffstats
path: root/main/strongswan/0701-auth-cfg-Similar-to-certificates-matching-one-CA-sho.patch
blob: 2c9a1db4fd8e58b53c4de1fd0a7700a5d5a02adc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
From 7c7f85a0fd7e6f90c19d797304410da3925a9f96 Mon Sep 17 00:00:00 2001
From: Tobias Brunner <tobias@strongswan.org>
Date: Mon, 3 Aug 2015 13:55:36 +0200
Subject: [PATCH] auth-cfg: Similar to certificates matching one CA should be
 enough

Not sure if defining multiple CA constraints and enforcing _all_ of them,
that is, the previous behavior, makes even sense.  To ensure a very specific
chain it should be enough to define the last intermediate CA.  On the
other hand, the ability to define multiple CAs could simplify configuration.

This can currently only be used with swanctl/VICI based configs as `rightca`
only takes a single DN.
---
 src/libstrongswan/credentials/auth_cfg.c | 35 ++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/src/libstrongswan/credentials/auth_cfg.c b/src/libstrongswan/credentials/auth_cfg.c
index 0ca45a1..9b57631 100644
--- a/src/libstrongswan/credentials/auth_cfg.c
+++ b/src/libstrongswan/credentials/auth_cfg.c
@@ -514,9 +514,10 @@ METHOD(auth_cfg_t, complies, bool,
 	private_auth_cfg_t *this, auth_cfg_t *constraints, bool log_error)
 {
 	enumerator_t *e1, *e2;
-	bool success = TRUE, group_match = FALSE, cert_match = FALSE;
+	bool success = TRUE, group_match = FALSE;
+	bool ca_match = FALSE, cert_match = FALSE;
 	identification_t *require_group = NULL;
-	certificate_t *require_cert = NULL;
+	certificate_t *require_ca = NULL, *require_cert = NULL;
 	signature_scheme_t scheme = SIGN_UNKNOWN;
 	u_int strength = 0;
 	auth_rule_t t1, t2;
@@ -531,26 +532,21 @@ METHOD(auth_cfg_t, complies, bool,
 			case AUTH_RULE_CA_CERT:
 			case AUTH_RULE_IM_CERT:
 			{
-				certificate_t *c1, *c2;
+				certificate_t *cert;
 
-				c1 = (certificate_t*)value;
+				/* for CA certs, a match of a single cert is sufficient */
+				require_ca = (certificate_t*)value;
 
-				success = FALSE;
 				e2 = create_enumerator(this);
-				while (e2->enumerate(e2, &t2, &c2))
+				while (e2->enumerate(e2, &t2, &cert))
 				{
 					if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
-						c1->equals(c1, c2))
+						cert->equals(cert, require_ca))
 					{
-						success = TRUE;
+						ca_match = TRUE;
 					}
 				}
 				e2->destroy(e2);
-				if (!success && log_error)
-				{
-					DBG1(DBG_CFG, "constraint check failed: peer not "
-						 "authenticated by CA '%Y'.", c1->get_subject(c1));
-				}
 				break;
 			}
 			case AUTH_RULE_SUBJECT_CERT:
@@ -853,13 +849,22 @@ METHOD(auth_cfg_t, complies, bool,
 		}
 		return FALSE;
 	}
-
+	if (require_ca && !ca_match)
+	{
+		if (log_error)
+		{
+			DBG1(DBG_CFG, "constraint check failed: peer not "
+				 "authenticated by CA '%Y'",
+				 require_ca->get_subject(require_ca));
+		}
+		return FALSE;
+	}
 	if (require_cert && !cert_match)
 	{
 		if (log_error)
 		{
 			DBG1(DBG_CFG, "constraint check failed: peer not "
-				 "authenticated with peer cert '%Y'.",
+				 "authenticated with peer cert '%Y'",
 				 require_cert->get_subject(require_cert));
 		}
 		return FALSE;
-- 
2.5.0