1 /*
2  * Lasso library C unit tests
3  *
4  * Copyright (C) 2004-2007 Entr'ouvert
5  * http://lasso.entrouvert.org
6  *
7  * Authors: See AUTHORS file in top-level directory.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include <stdlib.h>
24 #include <string.h>
25 
26 #include <check.h>
27 #include <glib.h>
28 
29 #include "../lasso/lasso.h"
30 #include "../lasso/xml/saml-2.0/samlp2_authn_request.h"
31 #include "../lasso/utils.h"
32 #include "../lasso/backward_comp.h"
33 #include "../lasso/xml/saml-2.0/samlp2_logout_request.h"
34 #include "../bindings/ghashtable.h"
35 #include "tests.h"
36 
37 static char*
generateIdentityProviderContextDump()38 generateIdentityProviderContextDump()
39 {
40 	LassoServer *serverContext;
41 	GList *providers;
42 	char *ret;
43 
44 	serverContext = lasso_server_new(
45 			TESTSDATADIR "/idp5-saml2/metadata.xml",
46 			TESTSDATADIR "/idp5-saml2/private-key.pem",
47 			NULL, /* Secret key to unlock private key */
48 			NULL);
49 	lasso_server_add_provider(
50 			serverContext,
51 			LASSO_PROVIDER_ROLE_SP,
52 			TESTSDATADIR "/sp5-saml2/metadata.xml",
53 			NULL,
54 			NULL);
55 	providers = g_hash_table_get_values(serverContext->providers);
56 	lasso_provider_set_encryption_mode(LASSO_PROVIDER(providers->data), LASSO_ENCRYPTION_MODE_ASSERTION | LASSO_ENCRYPTION_MODE_NAMEID);
57 	ret = lasso_server_dump(serverContext);
58 
59 	g_object_unref(serverContext);
60 	g_list_free(providers);
61 
62 	return ret;
63 }
64 
65 static char*
generateServiceProviderContextDump()66 generateServiceProviderContextDump()
67 {
68 	LassoServer *serverContext;
69 	char *ret;
70 
71 	serverContext = lasso_server_new(
72 			TESTSDATADIR "/sp5-saml2/metadata.xml",
73 			TESTSDATADIR "/sp5-saml2/private-key.pem",
74 			NULL, /* Secret key to unlock private key */
75 			NULL);
76 	lasso_server_add_provider(
77 			serverContext,
78 			LASSO_PROVIDER_ROLE_IDP,
79 			TESTSDATADIR "/idp5-saml2/metadata.xml",
80 			NULL,
81 			NULL);
82 
83 	ret = lasso_server_dump(serverContext);
84 	g_object_unref(serverContext);
85 	return ret;
86 }
87 
88 static char*
generateIdentityProviderContextDumpMemory()89 generateIdentityProviderContextDumpMemory()
90 {
91 	LassoServer *serverContext = NULL;
92 	char *metadata = NULL;
93 	char *private_key = NULL;
94 	char *certificate = NULL;
95 	size_t len;
96 	char *ret = NULL;
97 
98 	g_file_get_contents(TESTSDATADIR "/idp5-saml2/metadata.xml", &metadata, &len, NULL);
99 	g_file_get_contents(TESTSDATADIR "/idp5-saml2/private-key.pem", &private_key, &len, NULL);
100 	g_file_get_contents(TESTSDATADIR "/idp5-saml2/certificate.pem", &certificate, &len, NULL);
101 
102 	serverContext = lasso_server_new_from_buffers(
103 			metadata,
104 			private_key,
105 			NULL, /* Secret key to unlock private key */
106 			certificate);
107 	lasso_server_add_provider(
108 			serverContext,
109 			LASSO_PROVIDER_ROLE_SP,
110 			TESTSDATADIR "/sp5-saml2/metadata.xml",
111 			NULL,
112 			NULL);
113 	g_free(metadata);
114 	g_free(private_key);
115 	g_free(certificate);
116 	ret = lasso_server_dump(serverContext);
117 	g_object_unref(serverContext);
118 	return ret;
119 }
120 
121 
START_TEST(test01_saml2_generateServersContextDumps)122 START_TEST(test01_saml2_generateServersContextDumps)
123 {
124 	char *identityProviderContextDump;
125 	char *serviceProviderContextDump;
126 
127 	identityProviderContextDump = generateIdentityProviderContextDump();
128 	fail_unless(identityProviderContextDump != NULL,
129 			"generateIdentityProviderContextDump should not return NULL");
130 	g_free(identityProviderContextDump);
131 	serviceProviderContextDump = generateServiceProviderContextDump();
132 	fail_unless(serviceProviderContextDump != NULL,
133 			"generateServiceProviderContextDump should not return NULL");
134 	g_free(serviceProviderContextDump);
135 }
136 END_TEST
137 
START_TEST(test02_saml2_serviceProviderLogin)138 START_TEST(test02_saml2_serviceProviderLogin)
139 {
140 	char *serviceProviderContextDump = NULL, *identityProviderContextDump = NULL;
141 	LassoServer *spContext = NULL, *idpContext = NULL;
142 	LassoLogin *spLoginContext = NULL, *idpLoginContext = NULL;
143 	LassoLogout *spLogoutContext = NULL, *idpLogoutContext = NULL;
144 	LassoSamlp2AuthnRequest *request = NULL;
145 	int rc = 0;
146 	char *relayState = NULL;
147 	char *authnRequestUrl = NULL, *authnRequestQuery = NULL;
148 	char *logoutRequestUrl = NULL, *logoutRequestQuery = NULL;
149 	char *logoutResponseUrl = NULL, *logoutResponseQuery = NULL;
150 	char *responseUrl = NULL, *responseQuery = NULL;
151 	char *idpIdentityContextDump = NULL, *idpSessionContextDump = NULL;
152 	char *serviceProviderId = NULL, *soapRequestMsg = NULL, *soapResponseMsg = NULL;
153 	char *spIdentityContextDump = NULL;
154 	char *spSessionDump = NULL;
155 	char *spLoginDump = NULL, *idpLoginDump = NULL;
156 	char *found = NULL;
157 	LassoSaml2Assertion *assertion;
158 
159 	serviceProviderContextDump = generateServiceProviderContextDump();
160 	spContext = lasso_server_new_from_dump(serviceProviderContextDump);
161 	spLoginContext = lasso_login_new(spContext);
162 	fail_unless(spLoginContext != NULL,
163 			"lasso_login_new() shouldn't have returned NULL");
164 	rc = lasso_login_init_authn_request(spLoginContext, "http://idp5/metadata",
165 			LASSO_HTTP_METHOD_REDIRECT);
166 	fail_unless(rc == 0, "lasso_login_init_authn_request failed");
167 	request = LASSO_SAMLP2_AUTHN_REQUEST(LASSO_PROFILE(spLoginContext)->request);
168 	fail_unless(LASSO_IS_SAMLP2_AUTHN_REQUEST(request), "request should be authn_request");
169 	request->IsPassive = 0;
170 	lasso_assign_string(request->NameIDPolicy->Format, LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT);
171 	request->NameIDPolicy->AllowCreate = 1;
172 	relayState = "fake[]";
173 	lasso_assign_string(LASSO_PROFILE(spLoginContext)->msg_relayState, relayState);
174 	rc = lasso_login_build_authn_request_msg(spLoginContext);
175 	fail_unless(rc == 0, "lasso_login_build_authn_request_msg failed");
176 	authnRequestUrl = LASSO_PROFILE(spLoginContext)->msg_url;
177 	fail_unless(authnRequestUrl != NULL,
178 			"authnRequestUrl shouldn't be NULL");
179 	authnRequestQuery = strchr(authnRequestUrl, '?')+1;
180 	fail_unless(strlen(authnRequestQuery) > 0,
181 			"authnRequestQuery shouldn't be an empty string");
182 	spLoginDump = lasso_node_dump(LASSO_NODE(spLoginContext));
183 	fail_unless(strstr(authnRequestQuery, "RelayState") != NULL,
184 			"authnRequestQuery should contain a RelayState parameter");
185 	fail_unless(strstr(authnRequestQuery, "fake%5B%5D") != NULL,
186 			"authnRequestQuery RelayState parameter should be encoded");
187 
188 	/* Identity provider singleSignOn, for a user having no federation. */
189 	identityProviderContextDump = generateIdentityProviderContextDump();
190 	idpContext = lasso_server_new_from_dump(identityProviderContextDump);
191 	idpLoginContext = lasso_login_new(idpContext);
192 	fail_unless(idpLoginContext != NULL,
193 			"lasso_login_new() shouldn't have returned NULL");
194 	check_good_rc(lasso_login_process_authn_request_msg(idpLoginContext, authnRequestQuery));
195 	check_true(lasso_login_must_authenticate(idpLoginContext));
196 	check_equals(idpLoginContext->protocolProfile, LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART);
197 	check_false(lasso_login_must_ask_for_consent(idpLoginContext));
198 	check_not_null(idpLoginContext->parent.msg_relayState);
199 	check_equals(lasso_strisnotequal(idpLoginContext->parent.msg_relayState,relayState), 0);
200 	check_good_rc(lasso_login_validate_request_msg(idpLoginContext,
201 			1, /* authentication_result */
202 		        0 /* is_consent_obtained */
203 			));
204 
205 	check_good_rc(lasso_login_build_assertion(idpLoginContext,
206 			LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD,
207 			"FIXME: authenticationInstant",
208 			"FIXME: reauthenticateOnOrAfter",
209 			"FIXME: notBefore",
210 			"FIXME: notOnOrAfter"));
211 	assertion = (LassoSaml2Assertion*)lasso_login_get_assertion(idpLoginContext);
212 	check_true(LASSO_IS_SAML2_ASSERTION(assertion));
213 	lasso_saml2_assertion_set_basic_conditions(LASSO_SAML2_ASSERTION(assertion), 60, 120, FALSE);
214 	lasso_release_gobject(assertion);
215 	check_good_rc(lasso_login_build_artifact_msg(idpLoginContext, LASSO_HTTP_METHOD_ARTIFACT_GET));
216 
217 	idpIdentityContextDump = lasso_identity_dump(LASSO_PROFILE(idpLoginContext)->identity);
218 	check_not_null(idpIdentityContextDump);
219 	idpSessionContextDump = lasso_session_dump(LASSO_PROFILE(idpLoginContext)->session);
220 	check_not_null(idpSessionContextDump);
221 	responseUrl = LASSO_PROFILE(idpLoginContext)->msg_url;
222 	check_not_null(responseUrl);
223 	responseQuery = strchr(responseUrl, '?')+1;
224 	fail_unless(strlen(responseQuery) > 0,
225 			"responseQuery shouldn't be an empty string");
226 	check_not_null(strstr(responseQuery, "RelayState"));
227 	check_not_null(strstr(responseQuery, "fake%5B%5D"));
228 	lasso_assign_string(serviceProviderId, LASSO_PROFILE(idpLoginContext)->remote_providerID);
229 	check_not_null(serviceProviderId);
230 
231 	/* Service provider assertion consumer */
232 	lasso_server_destroy(spContext);
233 	lasso_login_destroy(spLoginContext);
234 
235 	spContext = lasso_server_new_from_dump(serviceProviderContextDump);
236 	spLoginContext = lasso_login_new_from_dump(spContext, spLoginDump);
237 	check_good_rc(lasso_login_init_request(spLoginContext,
238 			responseQuery,
239 			LASSO_HTTP_METHOD_ARTIFACT_GET));
240 	check_not_null(spLoginContext->parent.msg_relayState);
241 	check_equals(lasso_strisnotequal(spLoginContext->parent.msg_relayState,relayState), 0);
242 	check_good_rc(lasso_login_build_request_msg(spLoginContext));
243 	soapRequestMsg = LASSO_PROFILE(spLoginContext)->msg_body;
244 	check_not_null(soapRequestMsg);
245 
246 	/* Identity provider SOAP endpoint */
247 	lasso_server_destroy(idpContext);
248 	idpLoginDump = lasso_node_dump(LASSO_NODE(idpLoginContext));
249 	lasso_login_destroy(idpLoginContext);
250 
251 	idpContext = lasso_server_new_from_dump(identityProviderContextDump);
252 	idpLoginContext = lasso_login_new_from_dump(idpContext, idpLoginDump);
253 	check_good_rc(lasso_login_process_request_msg(idpLoginContext, soapRequestMsg));
254 
255 	check_good_rc(lasso_profile_set_session_from_dump(LASSO_PROFILE(idpLoginContext),
256 						 idpSessionContextDump));
257 	check_good_rc(lasso_login_build_response_msg(idpLoginContext, serviceProviderId));
258 	soapResponseMsg =  LASSO_PROFILE(idpLoginContext)->msg_body;
259 	check_not_null(soapResponseMsg);
260 
261 	/* Service provider assertion consumer (step 2: process SOAP response) */
262 	check_good_rc(lasso_login_process_response_msg(spLoginContext, soapResponseMsg));
263 	check_good_rc(lasso_login_accept_sso(spLoginContext));
264 	assertion = (LassoSaml2Assertion*)lasso_login_get_assertion(spLoginContext);
265 	check_true(LASSO_IS_SAML2_ASSERTION(assertion));
266 	check_equals(lasso_saml2_assertion_validate_conditions(assertion,
267 				spLoginContext->parent.server->parent.ProviderID),
268 			LASSO_SAML2_ASSERTION_VALID);
269 	check_equals(lasso_saml2_assertion_validate_conditions(assertion, "coin"), LASSO_SAML2_ASSERTION_INVALID);
270 	lasso_release_gobject(assertion);
271 	check_not_null(LASSO_PROFILE(spLoginContext)->identity);
272 	spIdentityContextDump = lasso_identity_dump(LASSO_PROFILE(spLoginContext)->identity);
273 	check_not_null(spIdentityContextDump);
274 	spSessionDump = lasso_session_dump(LASSO_PROFILE(spLoginContext)->session);
275 
276 	/* Test InResponseTo checking */
277 	if (! strstr(soapResponseMsg, "EncryptedAssertion")) {
278 		found = strstr(soapResponseMsg, "Assertion");
279 		check_not_null(found);
280 		found = strstr(found, "InResponseTo=\"");
281 		check_not_null(found);
282 		found[sizeof("InResponseTo=\"")] = '?';
283 		lasso_set_flag("no-verify-signature");
284 		check_not_equals(lasso_login_process_response_msg(spLoginContext, soapResponseMsg), 0);
285 		lasso_set_flag("verify-signature");
286 		check_not_equals(lasso_login_accept_sso(spLoginContext), 0);
287 	}
288 
289 	/* logout test */
290 	/* generate a logout request */
291 	check_not_null(idpLogoutContext = lasso_logout_new(idpContext));
292 	check_good_rc(lasso_profile_set_session_from_dump(&idpLogoutContext->parent, idpSessionContextDump));
293 	check_good_rc(lasso_logout_init_request(idpLogoutContext, NULL, LASSO_HTTP_METHOD_REDIRECT));
294 	check_good_rc(lasso_logout_build_request_msg(idpLogoutContext));
295 	check_not_null(idpLogoutContext->parent.msg_url);
296 	check_null(idpLogoutContext->parent.msg_body);
297 	check_null(idpLogoutContext->parent.msg_relayState);
298 	lasso_assign_string(logoutRequestUrl, idpLogoutContext->parent.msg_url);
299 	lasso_release_gobject(idpLogoutContext);
300 	logoutRequestQuery = strchr(logoutRequestUrl, '?');
301 	logoutRequestQuery += 1; /* keep only the query */
302 	check_not_null(logoutRequestQuery);
303 
304 	/* process the logout request */
305 	check_not_null(spLogoutContext = lasso_logout_new(spContext));
306 	check_good_rc(lasso_profile_set_session_from_dump(&spLogoutContext->parent, spSessionDump));
307 	check_good_rc(lasso_logout_process_request_msg(spLogoutContext, logoutRequestQuery));
308 	check_good_rc(lasso_logout_validate_request(spLogoutContext));
309 	check_good_rc(lasso_logout_build_response_msg(spLogoutContext));
310 	check_not_null(spLogoutContext->parent.msg_url);
311 	check_null(spLogoutContext->parent.msg_body);
312 	check_null(spLogoutContext->parent.msg_relayState);
313 	lasso_assign_string(logoutResponseUrl, spLogoutContext->parent.msg_url);
314 	check_not_null(logoutResponseQuery = strchr(logoutResponseUrl, '?'));
315 	logoutResponseQuery += 1; /* keep only the query */
316 	lasso_release_gobject(spLogoutContext);
317 
318 	/* process the response */
319 	check_not_null(idpLogoutContext = lasso_logout_new(idpContext));
320 	check_good_rc(lasso_profile_set_session_from_dump(&idpLogoutContext->parent, idpSessionContextDump));
321 	check_good_rc(lasso_logout_process_response_msg(idpLogoutContext, logoutResponseQuery));
322 	lasso_release_gobject(idpLogoutContext);
323 	lasso_release_string(logoutRequestUrl);
324 	lasso_release_string(logoutResponseUrl);
325 
326 	g_free(idpLoginDump);
327 	g_free(serviceProviderId);
328 	g_free(serviceProviderContextDump);
329 	g_free(identityProviderContextDump);
330 	g_free(idpSessionContextDump);
331 	g_free(idpIdentityContextDump);
332 	g_free(spIdentityContextDump);
333 	g_free(spSessionDump);
334 	g_free(spLoginDump);
335 	g_object_unref(spContext);
336 	g_object_unref(idpContext);
337 	g_object_unref(spLoginContext);
338 	g_object_unref(idpLoginContext);
339 }
340 END_TEST
341 
START_TEST(test03_saml2_serviceProviderLogin)342 START_TEST(test03_saml2_serviceProviderLogin)
343 {
344 	char *serviceProviderContextDump = NULL, *identityProviderContextDump = NULL;
345 	LassoServer *spContext = NULL, *idpContext = NULL;
346 	LassoLogin *spLoginContext = NULL, *idpLoginContext = NULL;
347 	LassoSamlp2AuthnRequest *request = NULL;
348 	char *relayState = NULL;
349 	char *authnRequestUrl = NULL, *authnRequestQuery = NULL;
350 	char *responseUrl = NULL, *responseQuery = NULL;
351 	char *idpIdentityContextDump = NULL, *idpSessionContextDump = NULL;
352 	char *serviceProviderId = NULL, *soapRequestMsg = NULL, *soapResponseMsg = NULL;
353 	char *spIdentityContextDump = NULL;
354 	char *spSessionDump = NULL;
355 	char *idpLoginDump = NULL;
356 	int rc = 0;
357 
358 	serviceProviderContextDump = generateServiceProviderContextDump();
359 	spContext = lasso_server_new_from_dump(serviceProviderContextDump);
360 	spLoginContext = lasso_login_new(spContext);
361 	fail_unless(spLoginContext != NULL,
362 			"lasso_login_new() shouldn't have returned NULL");
363 	rc = lasso_login_init_authn_request(spLoginContext, "http://idp5/metadata",
364 			LASSO_HTTP_METHOD_REDIRECT);
365 	fail_unless(rc == 0, "lasso_login_init_authn_request failed");
366 	request = LASSO_SAMLP2_AUTHN_REQUEST(LASSO_PROFILE(spLoginContext)->request);
367 	fail_unless(LASSO_IS_SAMLP2_AUTHN_REQUEST(request), "request should be authn_request");
368 	request->IsPassive = 0;
369 	lasso_assign_string(request->NameIDPolicy->Format, LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT);
370 	request->NameIDPolicy->AllowCreate = 1;
371 	relayState = "fake";
372 	lasso_assign_string(LASSO_PROFILE(spLoginContext)->msg_relayState, relayState);
373 	rc = lasso_login_build_authn_request_msg(spLoginContext);
374 	fail_unless(rc == 0, "lasso_login_build_authn_request_msg failed");
375 	authnRequestUrl = LASSO_PROFILE(spLoginContext)->msg_url;
376 	fail_unless(authnRequestUrl != NULL,
377 			"authnRequestUrl shouldn't be NULL");
378 	authnRequestQuery = strchr(authnRequestUrl, '?')+1;
379 	fail_unless(strlen(authnRequestQuery) > 0,
380 			"authnRequestRequest shouldn't be an empty string");
381 
382 	/* Identity provider singleSignOn, for a user having no federation. */
383 	identityProviderContextDump = generateIdentityProviderContextDumpMemory();
384 	idpContext = lasso_server_new_from_dump(identityProviderContextDump);
385 	idpLoginContext = lasso_login_new(idpContext);
386 	fail_unless(idpLoginContext != NULL,
387 			"lasso_login_new() shouldn't have returned NULL");
388 	rc = lasso_login_process_authn_request_msg(idpLoginContext, authnRequestQuery);
389 	fail_unless(rc == 0, "lasso_login_process_authn_request_msg failed");
390 	fail_unless(lasso_login_must_authenticate(idpLoginContext),
391 			"lasso_login_must_authenticate() should be TRUE");
392 	fail_unless(idpLoginContext->protocolProfile == LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART,
393 			"protocoleProfile should be ProfileBrwsArt");
394 	fail_unless(! lasso_login_must_ask_for_consent(idpLoginContext),
395 			"lasso_login_must_ask_for_consent() should be FALSE");
396 	rc = lasso_login_validate_request_msg(idpLoginContext,
397 			1, /* authentication_result */
398 		        0 /* is_consent_obtained */
399 			);
400 
401 	rc = lasso_login_build_assertion(idpLoginContext,
402 			LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD,
403 			"FIXME: authenticationInstant",
404 			"FIXME: reauthenticateOnOrAfter",
405 			"FIXME: notBefore",
406 			"FIXME: notOnOrAfter");
407 	rc = lasso_login_build_artifact_msg(idpLoginContext, LASSO_HTTP_METHOD_ARTIFACT_GET);
408 	fail_unless(rc == 0, "lasso_login_build_artifact_msg failed");
409 
410 	idpIdentityContextDump = lasso_identity_dump(LASSO_PROFILE(idpLoginContext)->identity);
411 	fail_unless(idpIdentityContextDump != NULL,
412 		    "lasso_identity_dump shouldn't return NULL");
413 	idpSessionContextDump = lasso_session_dump(LASSO_PROFILE(idpLoginContext)->session);
414 	fail_unless(idpSessionContextDump != NULL,
415 		    "lasso_session_dump shouldn't return NULL");
416 	responseUrl = LASSO_PROFILE(idpLoginContext)->msg_url;
417 	fail_unless(responseUrl != NULL, "responseUrl shouldn't be NULL");
418 	responseQuery = strchr(responseUrl, '?')+1;
419 	fail_unless(strlen(responseQuery) > 0,
420 			"responseQuery shouldn't be an empty string");
421 	lasso_assign_string(serviceProviderId, LASSO_PROFILE(idpLoginContext)->remote_providerID);
422 	fail_unless(serviceProviderId != NULL,
423 		    "lasso_profile_get_remote_providerID shouldn't return NULL");
424 
425 	/* Service provider assertion consumer */
426 	lasso_server_destroy(spContext);
427 	lasso_login_destroy(spLoginContext);
428 
429 	spContext = lasso_server_new_from_dump(serviceProviderContextDump);
430 	spLoginContext = lasso_login_new(spContext);
431 	rc = lasso_login_init_request(spLoginContext,
432 			responseQuery,
433 			LASSO_HTTP_METHOD_ARTIFACT_GET);
434 	fail_unless(rc == 0, "lasso_login_init_request failed");
435 	rc = lasso_login_build_request_msg(spLoginContext);
436 	fail_unless(rc == 0, "lasso_login_build_request_msg failed");
437 	soapRequestMsg = LASSO_PROFILE(spLoginContext)->msg_body;
438 	fail_unless(soapRequestMsg != NULL, "soapRequestMsg must not be NULL");
439 
440 	/* Identity provider SOAP endpoint */
441 	lasso_server_destroy(idpContext);
442 	idpLoginDump = lasso_node_dump(LASSO_NODE(idpLoginContext));
443 	lasso_login_destroy(idpLoginContext);
444 
445 	idpContext = lasso_server_new_from_dump(identityProviderContextDump);
446 	idpLoginContext = lasso_login_new_from_dump(idpContext, idpLoginDump);
447 	rc = lasso_login_process_request_msg(idpLoginContext, soapRequestMsg);
448 	fail_unless(rc == 0, "lasso_login_process_request_msg failed");
449 
450 	rc = lasso_profile_set_session_from_dump(LASSO_PROFILE(idpLoginContext),
451 						 idpSessionContextDump);
452 	fail_unless(rc == 0, "lasso_login_set_assertion_from_dump failed");
453 	rc = lasso_login_build_response_msg(idpLoginContext, serviceProviderId);
454 	fail_unless(rc == 0, "lasso_login_build_response_msg failed");
455 	soapResponseMsg =  LASSO_PROFILE(idpLoginContext)->msg_body;
456 	fail_unless(soapResponseMsg != NULL, "soapResponseMsg must not be NULL");
457 
458 	/* Service provider assertion consumer (step 2: process SOAP response) */
459 	rc = lasso_login_process_response_msg(spLoginContext, soapResponseMsg);
460 	fail_unless(rc == 0, "lasso_login_process_response_msg failed");
461 	rc = lasso_login_accept_sso(spLoginContext);
462 	fail_unless(rc == 0, "lasso_login_accept_sso failed");
463 	fail_unless(LASSO_PROFILE(spLoginContext)->identity != NULL,
464 			"spLoginContext has no identity");
465 	spIdentityContextDump = lasso_identity_dump(LASSO_PROFILE(spLoginContext)->identity);
466 	fail_unless(spIdentityContextDump != NULL, "lasso_identity_dump failed");
467 	spSessionDump = lasso_session_dump(LASSO_PROFILE(spLoginContext)->session);
468 
469 	g_free(idpLoginDump);
470 	g_free(serviceProviderId);
471 	g_free(serviceProviderContextDump);
472 	g_free(identityProviderContextDump);
473 	g_free(idpSessionContextDump);
474 	g_free(idpIdentityContextDump);
475 	g_free(spIdentityContextDump);
476 	g_free(spSessionDump);
477 	g_object_unref(spContext);
478 	g_object_unref(idpContext);
479 	g_object_unref(spLoginContext);
480 	g_object_unref(idpLoginContext);
481 }
482 END_TEST
483 
START_TEST(test04_sso_then_slo_soap)484 START_TEST(test04_sso_then_slo_soap)
485 {
486 	char *serviceProviderContextDump = NULL, *identityProviderContextDump = NULL;
487 	LassoServer *spContext = NULL, *idpContext = NULL;
488 	LassoLogin *spLoginContext = NULL, *idpLoginContext = NULL;
489 	LassoLogout *spLogoutContext = NULL, *idpLogoutContext = NULL;
490 	LassoSamlp2AuthnRequest *request = NULL;
491 	int rc = 0;
492 	char *relayState = NULL;
493 	char *authnRequestUrl = NULL, *authnRequestQuery = NULL;
494 	char *logoutRequestSoapMessage = NULL;
495 	char *logoutResponseSoapMessage = NULL;
496 	char *responseUrl = NULL, *responseQuery = NULL;
497 	char *idpIdentityContextDump = NULL, *idpSessionContextDump = NULL;
498 	char *serviceProviderId = NULL, *soapRequestMsg = NULL, *soapResponseMsg = NULL;
499 	char *spIdentityContextDump = NULL;
500 	char *spSessionDump = NULL;
501 	char *spLoginDump = NULL, *idpLoginDump = NULL;
502 	char *found = NULL;
503 	LassoSaml2Assertion *assertion;
504 
505 	serviceProviderContextDump = generateServiceProviderContextDump();
506 	spContext = lasso_server_new_from_dump(serviceProviderContextDump);
507 	spLoginContext = lasso_login_new(spContext);
508 	fail_unless(spLoginContext != NULL,
509 			"lasso_login_new() shouldn't have returned NULL");
510 	rc = lasso_login_init_authn_request(spLoginContext, "http://idp5/metadata",
511 			LASSO_HTTP_METHOD_REDIRECT);
512 	fail_unless(rc == 0, "lasso_login_init_authn_request failed");
513 	request = LASSO_SAMLP2_AUTHN_REQUEST(LASSO_PROFILE(spLoginContext)->request);
514 	fail_unless(LASSO_IS_SAMLP2_AUTHN_REQUEST(request), "request should be authn_request");
515 	request->IsPassive = 0;
516 	lasso_assign_string(request->NameIDPolicy->Format, LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT);
517 	request->NameIDPolicy->AllowCreate = 1;
518 	relayState = "fake[]";
519 	lasso_assign_string(LASSO_PROFILE(spLoginContext)->msg_relayState, relayState);
520 	rc = lasso_login_build_authn_request_msg(spLoginContext);
521 	fail_unless(rc == 0, "lasso_login_build_authn_request_msg failed");
522 	authnRequestUrl = LASSO_PROFILE(spLoginContext)->msg_url;
523 	fail_unless(authnRequestUrl != NULL,
524 			"authnRequestUrl shouldn't be NULL");
525 	authnRequestQuery = strchr(authnRequestUrl, '?')+1;
526 	fail_unless(strlen(authnRequestQuery) > 0,
527 			"authnRequestQuery shouldn't be an empty string");
528 	spLoginDump = lasso_node_dump(LASSO_NODE(spLoginContext));
529 	fail_unless(strstr(authnRequestQuery, "RelayState") != NULL,
530 			"authnRequestQuery should contain a RelayState parameter");
531 	fail_unless(strstr(authnRequestQuery, "fake%5B%5D") != NULL,
532 			"authnRequestQuery RelayState parameter should be encoded");
533 
534 	/* Identity provider singleSignOn, for a user having no federation. */
535 	identityProviderContextDump = generateIdentityProviderContextDump();
536 	idpContext = lasso_server_new_from_dump(identityProviderContextDump);
537 	idpLoginContext = lasso_login_new(idpContext);
538 	fail_unless(idpLoginContext != NULL,
539 			"lasso_login_new() shouldn't have returned NULL");
540 	check_good_rc(lasso_login_process_authn_request_msg(idpLoginContext, authnRequestQuery));
541 	check_true(lasso_login_must_authenticate(idpLoginContext));
542 	check_equals(idpLoginContext->protocolProfile, LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_ART);
543 	check_false(lasso_login_must_ask_for_consent(idpLoginContext));
544 	check_not_null(idpLoginContext->parent.msg_relayState);
545 	check_equals(lasso_strisnotequal(idpLoginContext->parent.msg_relayState,relayState), 0);
546 	check_good_rc(lasso_login_validate_request_msg(idpLoginContext,
547 			1, /* authentication_result */
548 		        0 /* is_consent_obtained */
549 			));
550 
551 	check_good_rc(lasso_login_build_assertion(idpLoginContext,
552 			LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD,
553 			"FIXME: authenticationInstant",
554 			"FIXME: reauthenticateOnOrAfter",
555 			"FIXME: notBefore",
556 			"FIXME: notOnOrAfter"));
557 	assertion = (LassoSaml2Assertion*)lasso_login_get_assertion(idpLoginContext);
558 	check_true(LASSO_IS_SAML2_ASSERTION(assertion));
559 	lasso_saml2_assertion_set_basic_conditions(LASSO_SAML2_ASSERTION(assertion), 60, 120, FALSE);
560 	lasso_release_gobject(assertion);
561 	check_good_rc(lasso_login_build_artifact_msg(idpLoginContext, LASSO_HTTP_METHOD_ARTIFACT_GET));
562 
563 	idpIdentityContextDump = lasso_identity_dump(LASSO_PROFILE(idpLoginContext)->identity);
564 	check_not_null(idpIdentityContextDump);
565 	idpSessionContextDump = lasso_session_dump(LASSO_PROFILE(idpLoginContext)->session);
566 	check_not_null(idpSessionContextDump);
567 	responseUrl = LASSO_PROFILE(idpLoginContext)->msg_url;
568 	check_not_null(responseUrl);
569 	responseQuery = strchr(responseUrl, '?')+1;
570 	fail_unless(strlen(responseQuery) > 0,
571 			"responseQuery shouldn't be an empty string");
572 	check_not_null(strstr(responseQuery, "RelayState"));
573 	check_not_null(strstr(responseQuery, "fake%5B%5D"));
574 	lasso_assign_string(serviceProviderId, LASSO_PROFILE(idpLoginContext)->remote_providerID);
575 	check_not_null(serviceProviderId);
576 
577 	/* Service provider assertion consumer */
578 	lasso_server_destroy(spContext);
579 	lasso_login_destroy(spLoginContext);
580 
581 	spContext = lasso_server_new_from_dump(serviceProviderContextDump);
582 	spLoginContext = lasso_login_new_from_dump(spContext, spLoginDump);
583 	check_good_rc(lasso_login_init_request(spLoginContext,
584 			responseQuery,
585 			LASSO_HTTP_METHOD_ARTIFACT_GET));
586 	check_not_null(spLoginContext->parent.msg_relayState);
587 	check_equals(lasso_strisnotequal(spLoginContext->parent.msg_relayState,relayState), 0);
588 	check_good_rc(lasso_login_build_request_msg(spLoginContext));
589 	soapRequestMsg = LASSO_PROFILE(spLoginContext)->msg_body;
590 	check_not_null(soapRequestMsg);
591 
592 	/* Identity provider SOAP endpoint */
593 	lasso_server_destroy(idpContext);
594 	idpLoginDump = lasso_node_dump(LASSO_NODE(idpLoginContext));
595 	lasso_login_destroy(idpLoginContext);
596 
597 	idpContext = lasso_server_new_from_dump(identityProviderContextDump);
598 	idpLoginContext = lasso_login_new_from_dump(idpContext, idpLoginDump);
599 	check_good_rc(lasso_login_process_request_msg(idpLoginContext, soapRequestMsg));
600 
601 	check_good_rc(lasso_profile_set_session_from_dump(LASSO_PROFILE(idpLoginContext),
602 						 idpSessionContextDump));
603 	check_good_rc(lasso_login_build_response_msg(idpLoginContext, serviceProviderId));
604 	soapResponseMsg =  LASSO_PROFILE(idpLoginContext)->msg_body;
605 	check_not_null(soapResponseMsg);
606 
607 	/* Service provider assertion consumer (step 2: process SOAP response) */
608 	check_good_rc(lasso_login_process_response_msg(spLoginContext, soapResponseMsg));
609 	check_good_rc(lasso_login_accept_sso(spLoginContext));
610 	assertion = (LassoSaml2Assertion*)lasso_login_get_assertion(spLoginContext);
611 	check_true(LASSO_IS_SAML2_ASSERTION(assertion));
612 	check_equals(lasso_saml2_assertion_validate_conditions(assertion,
613 				spLoginContext->parent.server->parent.ProviderID),
614 			LASSO_SAML2_ASSERTION_VALID);
615 	check_equals(lasso_saml2_assertion_validate_conditions(assertion, "coin"), LASSO_SAML2_ASSERTION_INVALID);
616 	lasso_release_gobject(assertion);
617 	check_not_null(LASSO_PROFILE(spLoginContext)->identity);
618 	spIdentityContextDump = lasso_identity_dump(LASSO_PROFILE(spLoginContext)->identity);
619 	check_not_null(spIdentityContextDump);
620 	spSessionDump = lasso_session_dump(LASSO_PROFILE(spLoginContext)->session);
621 
622 	/* Test InResponseTo checking */
623 	if (! strstr(soapResponseMsg, "EncryptedAssertion")) {
624 		found = strstr(soapResponseMsg, "Assertion");
625 		check_not_null(found);
626 		found = strstr(found, "InResponseTo=\"");
627 		check_not_null(found);
628 		found[sizeof("InResponseTo=\"")] = '?';
629 		lasso_set_flag("no-verify-signature");
630 		check_not_equals(lasso_login_process_response_msg(spLoginContext, soapResponseMsg), 0);
631 		lasso_set_flag("verify-signature");
632 		check_not_equals(lasso_login_accept_sso(spLoginContext), 0);
633 	}
634 
635 	/* logout test */
636 	/* generate a logout request */
637 	check_not_null(idpLogoutContext = lasso_logout_new(idpContext));
638 	check_good_rc(lasso_profile_set_session_from_dump(&idpLogoutContext->parent, idpSessionContextDump));
639 	check_good_rc(lasso_logout_init_request(idpLogoutContext, NULL, LASSO_HTTP_METHOD_SOAP));
640 	check_good_rc(lasso_logout_build_request_msg(idpLogoutContext));
641 	check_not_null(idpLogoutContext->parent.msg_url);
642 	check_not_null(idpLogoutContext->parent.msg_body);
643 	check_null(idpLogoutContext->parent.msg_relayState);
644 	lasso_assign_string(logoutRequestSoapMessage, idpLogoutContext->parent.msg_body);
645 	check_not_null(logoutRequestSoapMessage);
646 
647 	/* process the logout request */
648 	check_not_null(spLogoutContext = lasso_logout_new(spContext));
649 	check_good_rc(lasso_profile_set_session_from_dump(&spLogoutContext->parent, spSessionDump));
650 	check_good_rc(lasso_logout_process_request_msg(spLogoutContext, logoutRequestSoapMessage));
651 	lasso_release(logoutRequestSoapMessage);
652 	check_good_rc(lasso_logout_validate_request(spLogoutContext));
653 	check_good_rc(lasso_logout_build_response_msg(spLogoutContext));
654 	check_not_null(spLogoutContext->parent.msg_body);
655 	check_null(spLogoutContext->parent.msg_url);
656 	check_null(spLogoutContext->parent.msg_relayState);
657 	lasso_assign_string(logoutResponseSoapMessage, spLogoutContext->parent.msg_body);
658 	lasso_release_gobject(spLogoutContext);
659 	lasso_release_gobject(idpLogoutContext);
660 
661 	/* process the response */
662 	check_not_null(idpLogoutContext = lasso_logout_new(idpContext));
663 	check_good_rc(lasso_profile_set_session_from_dump(&idpLogoutContext->parent, idpSessionContextDump));
664 	check_good_rc(lasso_logout_process_response_msg(idpLogoutContext, logoutResponseSoapMessage));
665 	lasso_release_gobject(idpLogoutContext);
666 	lasso_release_string(logoutResponseSoapMessage);
667 
668 	g_free(idpLoginDump);
669 	g_free(serviceProviderId);
670 	g_free(serviceProviderContextDump);
671 	g_free(identityProviderContextDump);
672 	g_free(idpSessionContextDump);
673 	g_free(idpIdentityContextDump);
674 	g_free(spIdentityContextDump);
675 	g_free(spSessionDump);
676 	g_free(spLoginDump);
677 	g_object_unref(spContext);
678 	g_object_unref(idpContext);
679 	g_object_unref(spLoginContext);
680 	g_object_unref(idpLoginContext);
681 }
682 END_TEST
683 
START_TEST(test05_sso_idp_with_key_rollover)684 START_TEST(test05_sso_idp_with_key_rollover)
685 {
686 	LassoServer *idpContext1 = NULL;
687 	LassoServer *idpContext2 = NULL;
688 	LassoServer *spContext = NULL;
689 	LassoLogin *idpLoginContext1 = NULL;
690 	LassoLogin *idpLoginContext2 = NULL;
691 	LassoLogin *spLoginContext = NULL;
692 
693 	/* Create an IdP context for IdP initiated SSO with private key 1 */
694 	idpContext1 = lasso_server_new(
695 			TESTSDATADIR "idp11-multikey-saml2/metadata.xml",
696 			TESTSDATADIR "idp11-multikey-saml2/private-key-1.pem",
697 			NULL, /* Secret key to unlock private key */
698 			TESTSDATADIR "idp11-multikey-saml2/certificate-1.pem");
699 	check_not_null(idpContext1)
700 	check_good_rc(lasso_server_add_provider(
701 			idpContext1,
702 			LASSO_PROVIDER_ROLE_SP,
703 			TESTSDATADIR "/sp6-saml2/metadata.xml",
704 			NULL,
705 			NULL));
706 	/* Create an IdP context for IdP initiated SSO with private key 2 */
707 	idpContext2 = lasso_server_new(
708 			TESTSDATADIR "idp11-multikey-saml2/metadata.xml",
709 			TESTSDATADIR "idp11-multikey-saml2/private-key-2.pem",
710 			NULL, /* Secret key to unlock private key */
711 			TESTSDATADIR "idp11-multikey-saml2/certificate-2.pem");
712 	check_not_null(idpContext2)
713 	check_good_rc(lasso_server_add_provider(
714 			idpContext2,
715 			LASSO_PROVIDER_ROLE_SP,
716 			TESTSDATADIR "/sp6-saml2/metadata.xml",
717 			NULL,
718 			NULL));
719 	/* Create an SP context */
720 	spContext = lasso_server_new(
721 			TESTSDATADIR "/sp6-saml2/metadata.xml",
722 			TESTSDATADIR "/sp6-saml2/private-key.pem",
723 			NULL, /* Secret key to unlock private key */
724 			NULL);
725 	check_not_null(spContext)
726 	check_good_rc(lasso_server_add_provider(
727 			spContext,
728 			LASSO_PROVIDER_ROLE_IDP,
729 			TESTSDATADIR "/idp11-multikey-saml2/metadata.xml",
730 			NULL,
731 			NULL));
732 
733 	/* Create login contexts */
734 	idpLoginContext1 = lasso_login_new(idpContext1);
735 	check_not_null(idpLoginContext1);
736 	idpLoginContext2 = lasso_login_new(idpContext2);
737 	check_not_null(idpLoginContext2);
738 	spLoginContext = lasso_login_new(spContext);
739 	check_not_null(spLoginContext);
740 
741 	/* Create first response signed with key 1*/
742 	check_good_rc(lasso_login_init_idp_initiated_authn_request(idpLoginContext1, "http://sp6/metadata"));
743 	lasso_assign_string(LASSO_SAMLP2_AUTHN_REQUEST(idpLoginContext1->parent.request)->ProtocolBinding,
744 			LASSO_SAML2_METADATA_BINDING_POST);
745 	check_good_rc(lasso_login_process_authn_request_msg(idpLoginContext1, NULL));
746 	check_good_rc(lasso_login_validate_request_msg(idpLoginContext1,
747 			1, /* authentication_result */
748 		        0 /* is_consent_obtained */
749 			));
750 
751 	check_good_rc(lasso_login_build_assertion(idpLoginContext1,
752 			LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD,
753 			"FIXME: authenticationInstant",
754 			"FIXME: reauthenticateOnOrAfter",
755 			"FIXME: notBefore",
756 			"FIXME: notOnOrAfter"));
757 	check_good_rc(lasso_login_build_authn_response_msg(idpLoginContext1));
758 	check_not_null(idpLoginContext1->parent.msg_body);
759 	check_not_null(idpLoginContext1->parent.msg_url);
760 
761 	/* Create second response signed with key 2 */
762 	check_good_rc(lasso_login_init_idp_initiated_authn_request(idpLoginContext2, "http://sp6/metadata"));
763 	lasso_assign_string(LASSO_SAMLP2_AUTHN_REQUEST(idpLoginContext2->parent.request)->ProtocolBinding,
764 			LASSO_SAML2_METADATA_BINDING_POST);
765 	check_good_rc(lasso_login_process_authn_request_msg(idpLoginContext2, NULL));
766 	check_good_rc(lasso_login_validate_request_msg(idpLoginContext2,
767 			1, /* authentication_result */
768 		        0 /* is_consent_obtained */
769 			));
770 
771 	check_good_rc(lasso_login_build_assertion(idpLoginContext2,
772 			LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD,
773 			"FIXME: authenticationInstant",
774 			"FIXME: reauthenticateOnOrAfter",
775 			"FIXME: notBefore",
776 			"FIXME: notOnOrAfter"));
777 	check_good_rc(lasso_login_build_authn_response_msg(idpLoginContext2));
778 	check_not_null(idpLoginContext2->parent.msg_body);
779 	check_not_null(idpLoginContext2->parent.msg_url);
780 
781 	/* Process response 1 */
782 	check_good_rc(lasso_login_process_authn_response_msg(spLoginContext,
783 				idpLoginContext1->parent.msg_body));
784 	check_good_rc(lasso_login_accept_sso(spLoginContext));
785 
786 	/* Process response 2 */
787 	block_lasso_logs;
788 	check_good_rc(lasso_login_process_authn_response_msg(spLoginContext,
789 				idpLoginContext2->parent.msg_body));
790 	unblock_lasso_logs;
791 	check_good_rc(lasso_login_accept_sso(spLoginContext));
792 
793 	/* Cleanup */
794 	lasso_release_gobject(idpLoginContext1);
795 	lasso_release_gobject(idpLoginContext2);
796 	lasso_release_gobject(spLoginContext);
797 	lasso_release_gobject(idpContext1);
798 	lasso_release_gobject(idpContext2);
799 	lasso_release_gobject(spContext);
800 }
801 END_TEST
802 
803 #define make_context(ctx, server_prefix, server_suffix, provider_role, \
804 		provider_prefix, provider_suffix) \
805 	ctx =  lasso_server_new( \
806 			TESTSDATADIR server_prefix "/metadata" server_suffix ".xml", \
807 			TESTSDATADIR server_prefix "/private-key" server_suffix ".pem", \
808 			NULL, /* Secret key to unlock private key */ \
809 			TESTSDATADIR server_prefix "/certificate" server_suffix ".pem"); \
810 	check_not_null(ctx); \
811 	check_good_rc(lasso_server_add_provider( \
812 			ctx, \
813 			provider_role, \
814 			TESTSDATADIR provider_prefix "/metadata" provider_suffix ".xml", \
815 			NULL, \
816 			NULL)); \
817 	providers = g_hash_table_get_values(ctx->providers); \
818 	check_not_null(providers); \
819 	lasso_provider_set_encryption_mode(LASSO_PROVIDER(providers->data), \
820 			LASSO_ENCRYPTION_MODE_ASSERTION | LASSO_ENCRYPTION_MODE_NAMEID); \
821 	g_list_free(providers);
822 
823 void
sso_sp_with_key_rollover(LassoServer * idp_context,LassoServer * sp_context)824 sso_sp_with_key_rollover(LassoServer *idp_context, LassoServer *sp_context)
825 {
826 	LassoLogin *idp_login_context;
827 	LassoLogin *sp_login_context;
828 
829 	check_not_null(idp_login_context = lasso_login_new(idp_context));
830 	check_not_null(sp_login_context = lasso_login_new(sp_context))
831 
832 	/* Create response */
833 	check_good_rc(lasso_login_init_idp_initiated_authn_request(idp_login_context,
834 				"http://sp11/metadata"));
835 
836 	lasso_assign_string(LASSO_SAMLP2_AUTHN_REQUEST(idp_login_context->parent.request)->ProtocolBinding,
837 			LASSO_SAML2_METADATA_BINDING_POST);
838 	lasso_assign_string(LASSO_SAMLP2_AUTHN_REQUEST(idp_login_context->parent.request)->NameIDPolicy->Format,
839 			LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT);
840 	LASSO_SAMLP2_AUTHN_REQUEST(idp_login_context->parent.request)->NameIDPolicy->AllowCreate = 1;
841 
842 	block_lasso_logs;
843 	check_good_rc(lasso_login_process_authn_request_msg(idp_login_context, NULL));
844 	unblock_lasso_logs;
845 	check_good_rc(lasso_login_validate_request_msg(idp_login_context,
846 			1, /* authentication_result */
847 		        0 /* is_consent_obtained */
848 			));
849 
850 	check_good_rc(lasso_login_build_assertion(idp_login_context,
851 			LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD,
852 			"FIXME: authenticationInstant",
853 			"FIXME: reauthenticateOnOrAfter",
854 			"FIXME: notBefore",
855 			"FIXME: notOnOrAfter"));
856 	check_good_rc(lasso_login_build_authn_response_msg(idp_login_context));
857 	check_not_null(idp_login_context->parent.msg_body);
858 	check_not_null(idp_login_context->parent.msg_url);
859 
860 	/* Process response */
861 	block_lasso_logs;
862 	check_good_rc(lasso_login_process_authn_response_msg(sp_login_context,
863 				idp_login_context->parent.msg_body));
864 	unblock_lasso_logs;
865 	check_good_rc(lasso_login_accept_sso(sp_login_context));
866 
867 	/* Cleanup */
868 	lasso_release_gobject(idp_login_context);
869 	lasso_release_gobject(sp_login_context);
870 }
871 
START_TEST(test06_sso_sp_with_key_rollover)872 START_TEST(test06_sso_sp_with_key_rollover)
873 {
874 	LassoServer *idp_context_before_rollover = NULL;
875 	LassoServer *idp_context_after_rollover = NULL;
876 	LassoServer *sp_context_before_rollover = NULL;
877 	LassoServer *sp_context_after_rollover = NULL;
878 	GList *providers;
879 
880 	/* Create an IdP context for IdP initiated SSO with provider metadata 1 */
881 	make_context(idp_context_before_rollover, "idp6-saml2", "", LASSO_PROVIDER_ROLE_SP,
882 			"sp11-multikey-saml2", "-before-rollover")
883 	make_context(idp_context_after_rollover, "idp6-saml2", "", LASSO_PROVIDER_ROLE_SP,
884 			"sp11-multikey-saml2", "-after-rollover")
885 	make_context(sp_context_before_rollover, "sp11-multikey-saml2", "-before-rollover",
886 			LASSO_PROVIDER_ROLE_IDP, "idp6-saml2", "")
887 	lasso_server_set_encryption_private_key(sp_context_before_rollover,
888 			TESTSDATADIR "sp11-multikey-saml2/private-key-after-rollover.pem");
889 	make_context(sp_context_after_rollover, "sp11-multikey-saml2", "-after-rollover",
890 			LASSO_PROVIDER_ROLE_IDP, "idp6-saml2", "")
891 	lasso_server_set_encryption_private_key(sp_context_after_rollover,
892 			TESTSDATADIR "sp11-multikey-saml2/private-key-before-rollover.pem");
893 
894 	/* Tests... */
895 	sso_sp_with_key_rollover(idp_context_before_rollover, sp_context_before_rollover);
896 	sso_sp_with_key_rollover(idp_context_after_rollover, sp_context_before_rollover);
897 	sso_sp_with_key_rollover(idp_context_before_rollover, sp_context_after_rollover);
898 	sso_sp_with_key_rollover(idp_context_after_rollover, sp_context_after_rollover);
899 
900 	/* Cleanup */
901 	lasso_release_gobject(idp_context_before_rollover);
902 	lasso_release_gobject(idp_context_after_rollover);
903 	lasso_release_gobject(sp_context_before_rollover);
904 	lasso_release_gobject(sp_context_after_rollover);
905 }
906 END_TEST
907 
908 #define test07_make_context(ctx, server_prefix, provider_role, provider_prefix, key) \
909 	ctx =  lasso_server_new( \
910 			TESTSDATADIR server_prefix "/metadata.xml", \
911 			NULL, \
912 			NULL, /* Secret key to unlock private key */ \
913 			NULL); \
914 	check_not_null(ctx); \
915 	check_good_rc(lasso_server_add_provider( \
916 			ctx, \
917 			provider_role, \
918 			TESTSDATADIR provider_prefix "/metadata.xml", \
919 			NULL, \
920 			NULL)); \
921 	providers = g_hash_table_get_values(ctx->providers); \
922 	check_not_null(providers); \
923 	lasso_provider_set_server_signing_key(LASSO_PROVIDER(providers->data), \
924 			key); \
925 	lasso_provider_add_key(LASSO_PROVIDER(providers->data), key, FALSE); \
926 	g_list_free(providers);
927 
928 typedef void (*SsoCallback)(LassoLogin *idp_login_context, LassoLogin *sp_login_context);
929 
930 static void
sso_initiated_by_sp(LassoServer * idp_context,LassoServer * sp_context,SsoCallback sso_callback)931 sso_initiated_by_sp(LassoServer *idp_context, LassoServer *sp_context, SsoCallback sso_callback)
932 {
933 	LassoLogin *idp_login_context;
934 	LassoLogin *sp_login_context;
935 	char *authn_request_query;
936 
937 	check_not_null(idp_login_context = lasso_login_new(idp_context));
938 	check_not_null(sp_login_context = lasso_login_new(sp_context))
939 
940 	/* Create response */
941 	check_good_rc(lasso_login_init_authn_request(sp_login_context, NULL, LASSO_HTTP_METHOD_REDIRECT));
942 
943 	lasso_assign_string(LASSO_SAMLP2_AUTHN_REQUEST(sp_login_context->parent.request)->ProtocolBinding,
944 			LASSO_SAML2_METADATA_BINDING_POST);
945 	lasso_assign_string(LASSO_SAMLP2_AUTHN_REQUEST(sp_login_context->parent.request)->NameIDPolicy->Format,
946 			LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT);
947 	LASSO_SAMLP2_AUTHN_REQUEST(sp_login_context->parent.request)->NameIDPolicy->AllowCreate = 1;
948 	check_good_rc(lasso_login_build_authn_request_msg(sp_login_context));
949 	check_not_null(sp_login_context->parent.msg_url);
950 	authn_request_query = strchr(sp_login_context->parent.msg_url, '?');
951 	check_not_null(authn_request_query);
952 	authn_request_query += 1;
953 	check_good_rc(lasso_login_process_authn_request_msg(idp_login_context, authn_request_query));
954 
955 	check_good_rc(lasso_login_validate_request_msg(idp_login_context,
956 			1, /* authentication_result */
957 		        0 /* is_consent_obtained */
958 			));
959 
960 	check_good_rc(lasso_login_build_assertion(idp_login_context,
961 			LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD,
962 			"FIXME: authenticationInstant",
963 			"FIXME: reauthenticateOnOrAfter",
964 			"FIXME: notBefore",
965 			"FIXME: notOnOrAfter"));
966 	check_good_rc(lasso_login_build_authn_response_msg(idp_login_context));
967 	check_not_null(idp_login_context->parent.msg_body);
968 	check_not_null(idp_login_context->parent.msg_url);
969 
970 	/* Process response */
971 	check_good_rc(lasso_login_process_authn_response_msg(sp_login_context,
972 				idp_login_context->parent.msg_body));
973 	check_good_rc(lasso_login_accept_sso(sp_login_context));
974 
975 	if (sso_callback) {
976 		sso_callback(idp_login_context, sp_login_context);
977 	}
978 
979 	/* Cleanup */
980 	lasso_release_gobject(idp_login_context);
981 	lasso_release_gobject(sp_login_context);
982 }
983 
START_TEST(test07_sso_sp_with_hmac_sha1_signatures)984 START_TEST(test07_sso_sp_with_hmac_sha1_signatures)
985 {
986 	LassoServer *idp_context = NULL;
987 	LassoServer *sp_context = NULL;
988 	GList *providers;
989 	LassoKey *key = NULL;
990 
991 	/* Create the shared key */
992 	key = lasso_key_new_for_signature_from_memory("xxxxxxxxxxxxxxxx", 16,
993 			NULL, LASSO_SIGNATURE_METHOD_HMAC_SHA1, NULL);
994 	check_true(LASSO_IS_KEY(key));
995 
996 	/* Create an IdP context for IdP initiated SSO with provider metadata 1 */
997 	test07_make_context(idp_context, "idp6-saml2", LASSO_PROVIDER_ROLE_SP, "sp6-saml2", key)
998 	test07_make_context(sp_context, "sp6-saml2", LASSO_PROVIDER_ROLE_IDP, "idp6-saml2", key)
999 
1000 
1001 	block_lasso_logs;
1002 	sso_initiated_by_sp(idp_context, sp_context, NULL);
1003 	unblock_lasso_logs;
1004 
1005 	/* Cleanup */
1006 	lasso_release_gobject(idp_context);
1007 	lasso_release_gobject(sp_context);
1008 	lasso_release_gobject(key);
1009 }
1010 END_TEST
1011 
1012 typedef struct {
1013 	char *assertion_consumer_service_url;
1014 	char *protocol_binding;
1015 	gboolean use_assertion_consumer_service_idx;
1016 	int assertion_consumer_service_idx;
1017 	gboolean stop_after_build_assertion;
1018 } SsoSettings;
1019 
1020 static void
sso_initiated_by_sp2(LassoServer * idp_context,LassoServer * sp_context,SsoSettings sso_settings)1021 sso_initiated_by_sp2(LassoServer *idp_context, LassoServer *sp_context, SsoSettings sso_settings)
1022 {
1023 	LassoLogin *idp_login_context;
1024 	LassoLogin *sp_login_context;
1025 	LassoSamlp2AuthnRequest *request;
1026 	char *authn_request_query;
1027 
1028 	check_not_null(idp_login_context = lasso_login_new(idp_context));
1029 	check_not_null(sp_login_context = lasso_login_new(sp_context))
1030 
1031 	/* Create response */
1032 	check_good_rc(lasso_login_init_authn_request(sp_login_context, NULL, LASSO_HTTP_METHOD_REDIRECT));
1033 	request = (LassoSamlp2AuthnRequest*)sp_login_context->parent.request;
1034 	if (sso_settings.assertion_consumer_service_url) {
1035 		lasso_assign_string(request->AssertionConsumerServiceURL, sso_settings.assertion_consumer_service_url);
1036 	}
1037 	if (sso_settings.protocol_binding) {
1038 		lasso_assign_string(request->ProtocolBinding, sso_settings.protocol_binding);
1039 	}
1040 	if (sso_settings.use_assertion_consumer_service_idx) {
1041 		request->AssertionConsumerServiceIndex = sso_settings.assertion_consumer_service_idx;
1042 	}
1043 	lasso_assign_string(LASSO_SAMLP2_AUTHN_REQUEST(sp_login_context->parent.request)->NameIDPolicy->Format,
1044 			LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT);
1045 	LASSO_SAMLP2_AUTHN_REQUEST(sp_login_context->parent.request)->NameIDPolicy->AllowCreate = 1;
1046 	check_good_rc(lasso_login_build_authn_request_msg(sp_login_context));
1047 	check_not_null(sp_login_context->parent.msg_url);
1048 	authn_request_query = strchr(sp_login_context->parent.msg_url, '?');
1049 	check_not_null(authn_request_query);
1050 	authn_request_query += 1;
1051 	check_good_rc(lasso_login_process_authn_request_msg(idp_login_context, authn_request_query));
1052 
1053 	check_good_rc(lasso_login_validate_request_msg(idp_login_context,
1054 			1, /* authentication_result */
1055 		        0 /* is_consent_obtained */
1056 			));
1057 
1058 	check_good_rc(lasso_login_build_assertion(idp_login_context,
1059 			LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD,
1060 			"FIXME: authenticationInstant",
1061 			"FIXME: reauthenticateOnOrAfter",
1062 			"FIXME: notBefore",
1063 			"FIXME: notOnOrAfter"));
1064 	if (sso_settings.stop_after_build_assertion) {
1065 		goto cleanup;
1066 	}
1067 	check_good_rc(lasso_login_build_authn_response_msg(idp_login_context));
1068 	check_not_null(idp_login_context->parent.msg_body);
1069 	check_not_null(idp_login_context->parent.msg_url);
1070 
1071 	/* Process response */
1072 	check_good_rc(lasso_login_process_authn_response_msg(sp_login_context,
1073 				idp_login_context->parent.msg_body));
1074 	check_good_rc(lasso_login_accept_sso(sp_login_context));
1075 
1076 	/* Cleanup */
1077 cleanup:
1078 	lasso_release_gobject(idp_login_context);
1079 	lasso_release_gobject(sp_login_context);
1080 }
1081 
START_TEST(test08_test_authnrequest_flags)1082 START_TEST(test08_test_authnrequest_flags)
1083 {
1084 	LassoServer *idp_context = NULL;
1085 	LassoServer *sp_context = NULL;
1086 	GList *providers;
1087 
1088 	/* Create an IdP context for IdP initiated SSO with provider metadata 1 */
1089 	make_context(idp_context, "idp5-saml2", "", LASSO_PROVIDER_ROLE_SP, "sp5-saml2", "")
1090 	make_context(sp_context, "sp5-saml2", "", LASSO_PROVIDER_ROLE_IDP, "idp5-saml2", "")
1091 
1092 	block_lasso_logs;
1093 	sso_initiated_by_sp2(idp_context, sp_context,
1094 			(SsoSettings) {
1095 				.use_assertion_consumer_service_idx = 1,
1096 				.assertion_consumer_service_idx = 0,
1097 				.stop_after_build_assertion = 1,
1098 			});
1099 	sso_initiated_by_sp2(idp_context, sp_context,
1100 			(SsoSettings) {
1101 				.assertion_consumer_service_url = "http://sp5/singleSignOnPost",
1102 				.stop_after_build_assertion = 1,
1103 			});
1104 	sso_initiated_by_sp2(idp_context, sp_context,
1105 			(SsoSettings) {
1106 				.protocol_binding = LASSO_SAML2_METADATA_BINDING_ARTIFACT,
1107 				.stop_after_build_assertion = 1,
1108 			});
1109 	sso_initiated_by_sp2(idp_context, sp_context,
1110 			(SsoSettings) {
1111 				.assertion_consumer_service_url = "http://sp5/singleSignOnPost",
1112 				.protocol_binding = LASSO_SAML2_METADATA_BINDING_POST,
1113 				.stop_after_build_assertion = 1,
1114 			});
1115 	sso_initiated_by_sp2(idp_context, sp_context,
1116 			(SsoSettings) {
1117 				.assertion_consumer_service_url = "http://sp5/singleSignOnArtifact",
1118 				.protocol_binding = LASSO_SAML2_METADATA_BINDING_ARTIFACT,
1119 				.stop_after_build_assertion = 1,
1120 			});
1121 	sso_initiated_by_sp2(idp_context, sp_context,
1122 			(SsoSettings) {
1123 				.assertion_consumer_service_url = "http://sp5/singleSignOnPostAndArtifact",
1124 				.protocol_binding = LASSO_SAML2_METADATA_BINDING_ARTIFACT,
1125 				.stop_after_build_assertion = 1,
1126 			});
1127 	sso_initiated_by_sp2(idp_context, sp_context,
1128 			(SsoSettings) {
1129 				.assertion_consumer_service_url = "http://sp5/singleSignOnPostAndArtifact",
1130 				.protocol_binding = LASSO_SAML2_METADATA_BINDING_POST,
1131 				.stop_after_build_assertion = 1,
1132 			});
1133 	unblock_lasso_logs;
1134 
1135 	/* Cleanup */
1136 	lasso_release_gobject(idp_context);
1137 	lasso_release_gobject(sp_context);
1138 }
1139 END_TEST
1140 
1141 typedef enum {
1142 	ECP_IDP_LIST_NONE,
1143 	ECP_IDP_LIST_ECP,
1144 	ECP_IDP_LIST_BOGUS,
1145 } EcpIdpListVariant;
1146 
1147 /* Build an IDPList whose members have an endpoint supporing
1148  * the protocol_type and http_method.
1149  */
1150 static LassoNode *
get_idp_list(const LassoServer * server,LassoMdProtocolType protocol_type,LassoHttpMethod http_method)1151 get_idp_list(const LassoServer *server, LassoMdProtocolType protocol_type, LassoHttpMethod http_method)
1152 {
1153     GList *idp_entity_ids = NULL;
1154     GList *entity_id = NULL;
1155     GList *idp_entries = NULL;
1156     LassoSamlp2IDPList *idp_list;
1157     LassoSamlp2IDPEntry *idp_entry;
1158 
1159     idp_list = LASSO_SAMLP2_IDP_LIST(lasso_samlp2_idp_list_new());
1160 
1161     idp_entity_ids =
1162         lasso_server_get_filtered_provider_list(server,
1163                                                 LASSO_PROVIDER_ROLE_IDP,
1164                                                 protocol_type, http_method);
1165 
1166     for (entity_id = g_list_first(idp_entity_ids); entity_id != NULL;
1167          entity_id = g_list_next(entity_id)) {
1168         idp_entry = LASSO_SAMLP2_IDP_ENTRY(lasso_samlp2_idp_entry_new());
1169         idp_entry->ProviderID = g_strdup(entity_id->data);
1170         idp_entry->Name = g_strdup_printf("[NAME] %s", idp_entry->ProviderID);
1171         idp_entry->Loc = g_strdup_printf("[LOCATION] %s", idp_entry->ProviderID);
1172 
1173         idp_entries = g_list_append(idp_entries, idp_entry);
1174     }
1175     lasso_release_list_of_strings(idp_entity_ids);
1176 
1177     idp_list->IDPEntry = idp_entries;
1178     return LASSO_NODE(idp_list);
1179 }
1180 
1181 static LassoNode *
get_bogus_idp_list()1182 get_bogus_idp_list()
1183 {
1184     char *idp_entity_ids[] = {"http://bogus_1/metadata", NULL};
1185 	char **idp_entity_id_iter = NULL;
1186     char *entity_id = NULL;
1187     GList *idp_entries = NULL;
1188     LassoSamlp2IDPList *idp_list;
1189     LassoSamlp2IDPEntry *idp_entry;
1190 
1191     idp_list = LASSO_SAMLP2_IDP_LIST(lasso_samlp2_idp_list_new());
1192 
1193     for (idp_entity_id_iter = idp_entity_ids, entity_id = *idp_entity_id_iter;
1194 		 *idp_entity_id_iter != NULL;
1195 		 idp_entity_id_iter++) {
1196         idp_entry = LASSO_SAMLP2_IDP_ENTRY(lasso_samlp2_idp_entry_new());
1197         idp_entry->ProviderID = g_strdup(entity_id);
1198         idp_entry->Name = g_strdup_printf("[NAME] %s", idp_entry->ProviderID);
1199         idp_entry->Loc = g_strdup_printf("[LOCATION] %s", idp_entry->ProviderID);
1200 
1201         idp_entries = g_list_append(idp_entries, idp_entry);
1202     }
1203 
1204     idp_list->IDPEntry = idp_entries;
1205     return LASSO_NODE(idp_list);
1206 }
1207 
validate_idp_list(LassoEcp * ecp,EcpIdpListVariant ecpIDPListVariant,LassoSamlp2IDPList * idp_list)1208 static void validate_idp_list(LassoEcp *ecp, EcpIdpListVariant ecpIDPListVariant, LassoSamlp2IDPList *idp_list)
1209 {
1210 	if (ecpIDPListVariant == ECP_IDP_LIST_NONE) {
1211 		check_null(ecp->sp_idp_list);
1212 		check_null(ecp->known_sp_provided_idp_entries_supporting_ecp);
1213 	} else if (ecpIDPListVariant == ECP_IDP_LIST_ECP || ecpIDPListVariant == ECP_IDP_LIST_BOGUS) {
1214 		GList *ecp_iter, *src_iter;
1215 
1216 		check_not_null(ecp->sp_idp_list);
1217 		check_not_null(idp_list);
1218 
1219 		check_null(ecp->sp_idp_list->GetComplete);
1220 		check_null(idp_list->GetComplete);
1221 
1222 		check_equals(g_list_length(ecp->sp_idp_list->IDPEntry),
1223 					 g_list_length(idp_list->IDPEntry));
1224 
1225 		for (ecp_iter = g_list_first(ecp->sp_idp_list->IDPEntry), src_iter = g_list_first(idp_list->IDPEntry);
1226 			 ecp_iter && src_iter;
1227 			 ecp_iter = g_list_next(ecp_iter), src_iter = g_list_next(src_iter)) {
1228 			LassoSamlp2IDPEntry *ecp_item, *src_item;
1229 
1230 			ecp_item = LASSO_SAMLP2_IDP_ENTRY(ecp_iter->data);
1231 			src_item = LASSO_SAMLP2_IDP_ENTRY(src_iter->data);
1232 
1233 			check_not_null(ecp_item->ProviderID);
1234 			check_not_null(src_item->ProviderID);
1235 			check_str_equals(ecp_item->ProviderID, src_item->ProviderID);
1236 
1237 			check_not_null(ecp_item->Name);
1238 			check_not_null(src_item->Name);
1239 			check_str_equals(ecp_item->Name, src_item->Name);
1240 
1241 			check_not_null(ecp_item->Loc);
1242 			check_not_null(src_item->Loc);
1243 			check_str_equals(ecp_item->Loc, src_item->Loc);
1244 		}
1245 
1246 		if (ecpIDPListVariant == ECP_IDP_LIST_ECP) {
1247 			check_not_null(ecp->known_sp_provided_idp_entries_supporting_ecp);
1248 			check_equals(g_list_length(ecp->known_sp_provided_idp_entries_supporting_ecp),
1249 						 g_list_length(idp_list->IDPEntry));
1250 
1251 			for (ecp_iter = g_list_first(ecp->known_sp_provided_idp_entries_supporting_ecp),
1252 				 src_iter = g_list_first(idp_list->IDPEntry);
1253 				 ecp_iter && src_iter;
1254 				 ecp_iter = g_list_next(ecp_iter), src_iter = g_list_next(src_iter)) {
1255 				LassoSamlp2IDPEntry *ecp_item, *src_item;
1256 
1257 				ecp_item = LASSO_SAMLP2_IDP_ENTRY(ecp_iter->data);
1258 				src_item = LASSO_SAMLP2_IDP_ENTRY(src_iter->data);
1259 
1260 				check_not_null(ecp_item->ProviderID);
1261 				check_not_null(src_item->ProviderID);
1262 				check_str_equals(ecp_item->ProviderID, src_item->ProviderID);
1263 
1264 				check_not_null(ecp_item->Name);
1265 				check_not_null(src_item->Name);
1266 				check_str_equals(ecp_item->Name, src_item->Name);
1267 
1268 				check_not_null(ecp_item->Loc);
1269 				check_not_null(src_item->Loc);
1270 				check_str_equals(ecp_item->Loc, src_item->Loc);
1271 			}
1272 		} else {
1273 			check_null(ecp->known_sp_provided_idp_entries_supporting_ecp);
1274 		}
1275 
1276 	}
1277 	check_equals(g_list_length(ecp->known_idp_entity_ids_supporting_ecp), 1);
1278 	check_str_equals((char*)g_list_nth(ecp->known_idp_entity_ids_supporting_ecp, 0)->data, "http://idp5/metadata");
1279 }
1280 
test_ecp(EcpIdpListVariant ecpIDPListVariant,LassoProfileSignatureHint signature_hint,LassoProfileSignatureVerifyHint signature_verify_hint)1281 void test_ecp(EcpIdpListVariant ecpIDPListVariant,
1282               LassoProfileSignatureHint signature_hint,
1283               LassoProfileSignatureVerifyHint signature_verify_hint)
1284 {
1285 	char *serviceProviderContextDump = NULL, *identityProviderContextDump = NULL;
1286 	LassoServer *spContext = NULL, *ecpContext=NULL, *idpContext = NULL;
1287 	LassoLogin *spLoginContext = NULL, *idpLoginContext = NULL;
1288 	LassoEcp *ecp = NULL;
1289 	LassoSamlp2AuthnRequest *request = NULL;
1290 	gboolean is_passive = FALSE;
1291 	char *provider_name = NULL;
1292 	char *relayState = NULL;
1293 	char *messageID = NULL;
1294 	char *extracted_messageID = NULL;
1295 	char *spPaosRequestMsg = NULL;
1296 	char *ecpSoapRequestMsg = NULL;
1297 	char *idpSoapResponseMsg = NULL;
1298 	char *ecpPaosResponseMsg = NULL;
1299 	char *spLoginDump = NULL;
1300 	LassoSaml2Assertion *assertion;
1301 	LassoSamlp2IDPList *idp_list = NULL;
1302 
1303 	/*
1304 	 * SAML2 Profile for ECP (Section 4.2) defines these steps for an ECP
1305 	 * transaction
1306 	 *
1307 	 * 1. ECP issues HTTP Request to SP
1308 	 * 2. SP issues <AuthnRequest> to ECP using PAOS
1309 	 * 3. ECP determines IdP
1310 	 * 4. ECP conveys <AuthnRequest> to IdP using SOAP
1311 	 * 5. IdP identifies principal
1312 	 * 6. IdP issues <Response> to ECP, targeted at SP using SOAP
1313 	 * 7. ECP conveys <Response> to SP using PAOS
1314 	 * 8. SP grants or denies access to principal
1315 	 */
1316 
1317 
1318 	/*
1319 	 * Act as the SP who generates an AuthnRequest & conveys it in PAOS
1320 	 */
1321 
1322 	/* Create new SP Login Context */
1323 	serviceProviderContextDump = generateServiceProviderContextDump();
1324 	spContext = lasso_server_new_from_dump(serviceProviderContextDump);
1325 	spLoginContext = lasso_login_new(spContext);
1326 	check_not_null(spLoginContext);
1327 	lasso_profile_set_signature_hint(LASSO_PROFILE(spLoginContext), signature_hint);
1328 	lasso_profile_set_signature_verify_hint(LASSO_PROFILE(spLoginContext), signature_verify_hint);
1329 
1330 	check_good_rc(lasso_login_init_authn_request(spLoginContext, "http://idp5/metadata",
1331 												 LASSO_HTTP_METHOD_PAOS));
1332 
1333 	/* Set PAOS authn request parameters */
1334 	request = LASSO_SAMLP2_AUTHN_REQUEST(LASSO_PROFILE(spLoginContext)->request);
1335 	fail_unless(LASSO_IS_SAMLP2_AUTHN_REQUEST(request), "request should be authn_request");
1336 	request->IsPassive = is_passive;
1337 
1338 	lasso_assign_string(request->NameIDPolicy->Format, LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT);
1339 	request->NameIDPolicy->AllowCreate = 1;
1340 
1341 	provider_name = "test_sp_001";
1342 	lasso_assign_string(request->ProviderName, provider_name);
1343 
1344 	relayState = "fake[]";
1345 	lasso_assign_string(LASSO_PROFILE(spLoginContext)->msg_relayState, relayState);
1346 
1347 	messageID = "id-1234";
1348 	lasso_profile_set_message_id(LASSO_PROFILE(spLoginContext), messageID);
1349 
1350 	if (ecpIDPListVariant == ECP_IDP_LIST_ECP) {
1351 		idp_list = LASSO_SAMLP2_IDP_LIST(get_idp_list(spContext,
1352 													  LASSO_MD_PROTOCOL_TYPE_SINGLE_SIGN_ON,
1353 													  LASSO_HTTP_METHOD_SOAP));
1354 		lasso_profile_set_idp_list(LASSO_PROFILE(spLoginContext), LASSO_NODE(idp_list));
1355 	} else if (ecpIDPListVariant == ECP_IDP_LIST_BOGUS) {
1356 		idp_list = LASSO_SAMLP2_IDP_LIST(get_bogus_idp_list());
1357 		lasso_profile_set_idp_list(LASSO_PROFILE(spLoginContext), LASSO_NODE(idp_list));
1358 	}
1359 
1360 	/* Build PAOS authn request message */
1361 	check_good_rc(lasso_login_build_authn_request_msg(spLoginContext));
1362 
1363 	/*
1364 	 * spPaosRequestMsg is what will be sent back to the ECP client.
1365      * No reason to validate the contents of spPaosRequestMsg here
1366      * because in the next step the spPaosRequestMsg will be parsed
1367      * and we'll validate the parsed values.
1368 	 */
1369 	lasso_assign_string(spPaosRequestMsg, LASSO_PROFILE(spLoginContext)->msg_body);
1370 	check_not_null(spPaosRequestMsg);
1371 	check_null(LASSO_PROFILE(spLoginContext)->msg_url);
1372 	check_not_null(strstr(spPaosRequestMsg, "RelayState"));
1373 
1374 	/* Finished with SP Login Context, will create new one later */
1375 	lasso_server_destroy(spContext);
1376 	spContext = NULL;
1377 	spLoginDump = lasso_node_dump(LASSO_NODE(spLoginContext));
1378 	lasso_login_destroy(spLoginContext);
1379 	spLoginContext = NULL;
1380 
1381 	/*
1382 	 * Act as the ECP client who just received a PAOS request (spPaosRequestMsg).
1383 	 */
1384 
1385 	/* Create an ECP client & load an IdP */
1386 	ecpContext = lasso_server_new(NULL, NULL, NULL, NULL);
1387 	lasso_provider_set_protocol_conformance(LASSO_PROVIDER(ecpContext), LASSO_PROTOCOL_SAML_2_0);
1388 
1389 	lasso_server_add_provider(ecpContext, LASSO_PROVIDER_ROLE_IDP,
1390 							  TESTSDATADIR "/idp5-saml2/metadata.xml", NULL, NULL);
1391 
1392 	ecp = lasso_ecp_new(ecpContext);
1393 	check_not_null(ecp);
1394 
1395 	/* parse the spPaosRequestMsg */
1396 	check_good_rc(lasso_ecp_process_authn_request_msg(ecp, spPaosRequestMsg));
1397 
1398 	/* Validate ECP properties received in the spPaosRequestMsg */
1399 	check_null(ecp->assertion_consumer_url);
1400 	check_str_equals(ecp->response_consumer_url, "http://sp5/singleSignOnSOAP");
1401 	check_str_equals(ecp->message_id, messageID);
1402 	check_str_equals(ecp->relaystate, relayState);
1403 	check_str_equals(ecp->issuer->content, "http://sp5/metadata");
1404 	check_str_equals(ecp->provider_name, provider_name);
1405 	check_equals(ecp->is_passive, is_passive);
1406 
1407 	/* Validate ECP IdP list info & default IdP URL */
1408 	validate_idp_list(ecp, ecpIDPListVariant, idp_list);
1409 	check_str_equals(LASSO_PROFILE(ecp)->msg_url, "http://idp5/singleSignOnSOAP");
1410 
1411 	/*
1412 	 * ecpSoapRequestMsg is what we'll post to the IdP at the msg_url.
1413      */
1414 	lasso_assign_string(ecpSoapRequestMsg, LASSO_PROFILE(ecp)->msg_body);
1415 	check_not_null(ecpSoapRequestMsg);
1416 
1417 	/*
1418 	 * Act as the IdP which just received the SOAP request (ecpSoapRequestMsg)
1419 	 */
1420 
1421 	/* Create an IdP */
1422 	identityProviderContextDump = generateIdentityProviderContextDump();
1423 	idpContext = lasso_server_new_from_dump(identityProviderContextDump);
1424 	idpLoginContext = lasso_login_new(idpContext);
1425 	check_not_null(idpLoginContext);
1426 	lasso_profile_set_signature_hint(LASSO_PROFILE(idpLoginContext), signature_hint);
1427 	lasso_profile_set_signature_verify_hint(LASSO_PROFILE(idpLoginContext), signature_verify_hint);
1428 
1429 	/* Parse the ecpSoapRequestMsg */
1430 	check_good_rc(lasso_login_process_authn_request_msg(idpLoginContext, ecpSoapRequestMsg));
1431 
1432 	check_true(lasso_login_must_authenticate(idpLoginContext));
1433 	check_equals(idpLoginContext->protocolProfile, LASSO_LOGIN_PROTOCOL_PROFILE_BRWS_LECP);
1434 	check_false(lasso_login_must_ask_for_consent(idpLoginContext));
1435 	check_good_rc(lasso_login_validate_request_msg(idpLoginContext,
1436 			1, /* authentication_result */
1437 			0  /* is_consent_obtained */ ));
1438 
1439 	/* Build IdP response */
1440 
1441 	check_good_rc(lasso_login_build_assertion(idpLoginContext,
1442 			LASSO_SAML_AUTHENTICATION_METHOD_PASSWORD,
1443 			"FIXME: authenticationInstant",
1444 			"FIXME: reauthenticateOnOrAfter",
1445 			"FIXME: notBefore",
1446 			"FIXME: notOnOrAfter"));
1447 	assertion = (LassoSaml2Assertion*)lasso_login_get_assertion(idpLoginContext);
1448 	check_true(LASSO_IS_SAML2_ASSERTION(assertion));
1449 	lasso_saml2_assertion_set_basic_conditions(LASSO_SAML2_ASSERTION(assertion), 60, 120, FALSE);
1450 	lasso_release_gobject(assertion);
1451 
1452 	/* Build IdP SOAP response message */
1453 	check_good_rc(lasso_login_build_response_msg(idpLoginContext, NULL));
1454 
1455 	/* idpSoapResponseMsg is what we'll send back to the ECP client */
1456 	lasso_assign_string(idpSoapResponseMsg, LASSO_PROFILE(idpLoginContext)->msg_body);
1457 	check_not_null(idpSoapResponseMsg);
1458 
1459 	/*
1460 	 * Resume acting as the ECP client, process IdP response
1461 	 */
1462 
1463 	check_good_rc(lasso_ecp_process_response_msg(ecp, idpSoapResponseMsg));
1464 
1465 	/* Validate ECP properties, only the assertion_consumer_url should have changed */
1466 	check_str_equals(ecp->assertion_consumer_url, "http://sp5/singleSignOnSOAP");
1467 	check_str_equals(ecp->response_consumer_url, "http://sp5/singleSignOnSOAP");
1468 	check_str_equals(ecp->response_consumer_url, ecp->assertion_consumer_url); /* MUST match! */
1469 
1470 	check_str_equals(ecp->message_id, messageID);
1471 	check_str_equals(ecp->relaystate, relayState);
1472 	check_str_equals(ecp->issuer->content, "http://sp5/metadata");
1473 	check_str_equals(ecp->provider_name, provider_name);
1474 	check_equals(ecp->is_passive, is_passive);
1475 
1476 	/* Validate ECP IdP list info */
1477 	validate_idp_list(ecp, ecpIDPListVariant, idp_list);
1478 
1479 	lasso_assign_string(ecpPaosResponseMsg, LASSO_PROFILE(ecp)->msg_body);
1480 	check_not_null(ecpPaosResponseMsg);
1481 	check_str_equals(LASSO_PROFILE(ecp)->msg_url, ecp->assertion_consumer_url);
1482 
1483 	/* Act as the SP again which has just been posted the ecpPaosResponseMsg */
1484 
1485 	/* Create new SP Login Context */
1486 	spContext = lasso_server_new_from_dump(serviceProviderContextDump);
1487 	spLoginContext = lasso_login_new(spContext);
1488 	check_not_null(spLoginContext);
1489 	lasso_profile_set_signature_hint(LASSO_PROFILE(spLoginContext), signature_hint);
1490 	lasso_profile_set_signature_verify_hint(LASSO_PROFILE(spLoginContext), signature_verify_hint);
1491 
1492 	/* Parse the ecpPaosResponseMsg */
1493 	check_good_rc(lasso_login_process_paos_response_msg(spLoginContext, ecpPaosResponseMsg));
1494 
1495 	/* Verify we got back the same relayState and messageID */
1496 	check_str_equals(LASSO_PROFILE(spLoginContext)->msg_relayState, relayState);
1497 	extracted_messageID = lasso_profile_get_message_id(LASSO_PROFILE(spLoginContext));
1498 	check_str_equals(extracted_messageID, messageID);
1499 	lasso_release_string(extracted_messageID);
1500 
1501 
1502 	g_free(serviceProviderContextDump);
1503 	g_free(identityProviderContextDump);
1504 
1505 	lasso_release_gobject(spContext);
1506 	lasso_release_gobject(ecpContext);
1507 	lasso_release_gobject(idpContext);
1508 
1509 	lasso_release_gobject(spLoginContext);
1510 	lasso_release_gobject(idpLoginContext);
1511 
1512 	lasso_release_gobject(ecp);
1513 
1514 	lasso_release_string(spLoginDump);
1515 	lasso_release_string(spPaosRequestMsg);
1516 	lasso_release_string(ecpSoapRequestMsg);
1517 	lasso_release_string(idpSoapResponseMsg);
1518 	lasso_release_string(ecpPaosResponseMsg);
1519 
1520 	lasso_release_gobject(idp_list);
1521 
1522 }
1523 
START_TEST(test09_ecp)1524 START_TEST(test09_ecp)
1525 {
1526 	test_ecp(ECP_IDP_LIST_NONE,
1527 		 LASSO_PROFILE_SIGNATURE_HINT_MAYBE,
1528 		 LASSO_PROFILE_SIGNATURE_VERIFY_HINT_MAYBE);
1529 }
1530 END_TEST
1531 
START_TEST(test10_ecp)1532 START_TEST(test10_ecp)
1533 {
1534 	test_ecp(ECP_IDP_LIST_ECP,
1535 		 LASSO_PROFILE_SIGNATURE_HINT_MAYBE,
1536 		 LASSO_PROFILE_SIGNATURE_VERIFY_HINT_MAYBE);
1537 }
1538 END_TEST
1539 
START_TEST(test11_ecp)1540 START_TEST(test11_ecp)
1541 {
1542 	test_ecp(ECP_IDP_LIST_BOGUS,
1543 		 LASSO_PROFILE_SIGNATURE_HINT_MAYBE,
1544 		 LASSO_PROFILE_SIGNATURE_VERIFY_HINT_MAYBE);
1545 }
1546 END_TEST
1547 
START_TEST(test12_ecp)1548 START_TEST(test12_ecp)
1549 {
1550 	/* Maybe Sign */
1551 	test_ecp(ECP_IDP_LIST_NONE,
1552 		 LASSO_PROFILE_SIGNATURE_HINT_MAYBE,
1553 		 LASSO_PROFILE_SIGNATURE_VERIFY_HINT_MAYBE);
1554 
1555 	test_ecp(ECP_IDP_LIST_NONE,
1556 		 LASSO_PROFILE_SIGNATURE_HINT_MAYBE,
1557 		 LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE);
1558 
1559 	test_ecp(ECP_IDP_LIST_NONE,
1560 		 LASSO_PROFILE_SIGNATURE_HINT_MAYBE,
1561 		 LASSO_PROFILE_SIGNATURE_VERIFY_HINT_IGNORE);
1562 
1563 	/* Force Sign */
1564 	test_ecp(ECP_IDP_LIST_NONE,
1565 		 LASSO_PROFILE_SIGNATURE_HINT_FORCE,
1566 		 LASSO_PROFILE_SIGNATURE_VERIFY_HINT_MAYBE);
1567 
1568 	test_ecp(ECP_IDP_LIST_NONE,
1569 		 LASSO_PROFILE_SIGNATURE_HINT_FORCE,
1570 		 LASSO_PROFILE_SIGNATURE_VERIFY_HINT_FORCE);
1571 
1572 	test_ecp(ECP_IDP_LIST_NONE,
1573 		 LASSO_PROFILE_SIGNATURE_HINT_FORCE,
1574 		 LASSO_PROFILE_SIGNATURE_VERIFY_HINT_IGNORE);
1575 
1576 	/* Forbid Sign */
1577 	test_ecp(ECP_IDP_LIST_NONE,
1578 		 LASSO_PROFILE_SIGNATURE_HINT_FORBID,
1579 		 LASSO_PROFILE_SIGNATURE_VERIFY_HINT_IGNORE);
1580 
1581 }
1582 END_TEST
1583 
check_digest_method(G_GNUC_UNUSED LassoLogin * idp_login_context,LassoLogin * sp_login_context)1584 void check_digest_method(G_GNUC_UNUSED LassoLogin *idp_login_context, LassoLogin *sp_login_context)
1585 {
1586 	char *dump = lasso_node_debug((LassoNode*)sp_login_context->parent.response, 10);
1587 	check_true(strstr(dump, "<DigestMethod Algorithm=\"http://www.w3.org/2001/04/xmlenc#sha256\"/>") != NULL);
1588 	lasso_release_string(dump)
1589 }
1590 
START_TEST(test13_sso_sp_with_rsa_sha256_signatures)1591 START_TEST(test13_sso_sp_with_rsa_sha256_signatures)
1592 {
1593 	LassoServer *idp_context = NULL;
1594 	LassoServer *sp_context = NULL;
1595 	GList *providers;
1596 	LassoKey *key = NULL;
1597 
1598 	/* Create a key for signature algorithm RSA_SHA256 */
1599 	key = lasso_key_new_for_signature_from_file(TESTSDATADIR "idp6-saml2/private-key.pem", NULL,
1600 			LASSO_SIGNATURE_METHOD_RSA_SHA256, NULL);
1601 	check_true(LASSO_IS_KEY(key));
1602 
1603 	test07_make_context(idp_context, "idp6-saml2", LASSO_PROVIDER_ROLE_SP, "sp6-saml2", key)
1604 	test07_make_context(sp_context, "sp6-saml2", LASSO_PROVIDER_ROLE_IDP, "idp6-saml2", key)
1605 
1606 	block_lasso_logs;
1607 	sso_initiated_by_sp(idp_context, sp_context, check_digest_method);
1608 	unblock_lasso_logs;
1609 
1610 	/* Cleanup */
1611 	lasso_release_gobject(idp_context);
1612 	lasso_release_gobject(sp_context);
1613 	lasso_release_gobject(key);
1614 }
1615 END_TEST
1616 
1617 Suite*
login_saml2_suite()1618 login_saml2_suite()
1619 {
1620 	Suite *s = suite_create("Login using SAML 2.0");
1621 	TCase *tc_generate = tcase_create("Generate Server Contexts");
1622 	TCase *tc_spLogin = tcase_create("Login initiated by service provider");
1623 	TCase *tc_spLoginMemory = tcase_create("Login initiated by service provider without key loading");
1624 	TCase *tc_spSloSoap = tcase_create("Login initiated by service provider without key loading and with SLO SOAP");
1625 	TCase *tc_idpKeyRollover = tcase_create("Login initiated by idp, idp use two differents signing keys (simulate key roll-over)");
1626 	TCase *tc_spKeyRollover = tcase_create("Login initiated by idp, sp use two differents encrypting keys (simulate key roll-over)");
1627 	TCase *tc_hmacSignature = tcase_create("Login initiated by sp, using shared-key signature");
1628 	TCase *tc_ecp = tcase_create("ECP Login");
1629 	suite_add_tcase(s, tc_generate);
1630 	suite_add_tcase(s, tc_spLogin);
1631 	suite_add_tcase(s, tc_spLoginMemory);
1632 	suite_add_tcase(s, tc_spSloSoap);
1633 	suite_add_tcase(s, tc_idpKeyRollover);
1634 	suite_add_tcase(s, tc_spKeyRollover);
1635 	suite_add_tcase(s, tc_hmacSignature);
1636 	suite_add_tcase(s, tc_ecp);
1637 	tcase_add_test(tc_generate, test01_saml2_generateServersContextDumps);
1638 	tcase_add_test(tc_spLogin, test02_saml2_serviceProviderLogin);
1639 	tcase_add_test(tc_spLoginMemory, test03_saml2_serviceProviderLogin);
1640 	tcase_add_test(tc_spSloSoap, test04_sso_then_slo_soap);
1641 	tcase_add_test(tc_idpKeyRollover, test05_sso_idp_with_key_rollover);
1642 	tcase_add_test(tc_spKeyRollover, test06_sso_sp_with_key_rollover);
1643 	tcase_add_test(tc_hmacSignature, test07_sso_sp_with_hmac_sha1_signatures);
1644 	tcase_add_test(tc_spLogin, test08_test_authnrequest_flags);
1645 	tcase_add_test(tc_ecp, test09_ecp);
1646 	tcase_add_test(tc_ecp, test10_ecp);
1647 	tcase_add_test(tc_ecp, test11_ecp);
1648 	tcase_add_test(tc_ecp, test12_ecp);
1649 	tcase_add_test(tc_spLogin, test13_sso_sp_with_rsa_sha256_signatures);
1650 	return s;
1651 }
1652 
1653