diff --git a/bindings/python/tests/profiles_tests.py b/bindings/python/tests/profiles_tests.py
index b1dd044..30cf5c2 100755
--- a/bindings/python/tests/profiles_tests.py
+++ b/bindings/python/tests/profiles_tests.py
@@ -43,6 +43,17 @@ except NameError:
srcdir = os.environ.get('srcdir', '.')
dataDir = '%s/../../../tests/data' % srcdir
+def server(local_name, remote_role, remote_name):
+ pwd = os.path.join(dataDir, local_name, 'password')
+ password = None
+ if os.path.exists(pwd):
+ password = file(pwd).read()
+ s = lasso.Server(os.path.join(dataDir, local_name, 'metadata.xml'),
+ os.path.join(dataDir, local_name, 'private-key.pem'),
+ password)
+ s.addProvider(remote_role, os.path.join(dataDir, remote_name, 'metadata.xml'))
+ return s
+
class ServerTestCase(unittest.TestCase):
def test01(self):
@@ -208,6 +219,24 @@ class LoginTestCase(unittest.TestCase):
self.failUnless('do action 2' in extensionsList[0])
self.failUnless('do action 3' in extensionsList[0])
+ def test_05(self):
+ '''Login test between SP and IdP with encrypted private keys'''
+ sp_server = server('sp7-saml2', lasso.PROVIDER_ROLE_IDP, 'idp7-saml2')
+ idp_server = server('idp7-saml2', lasso.PROVIDER_ROLE_SP, 'sp7-saml2')
+
+ sp_login = lasso.Login(sp_server)
+ sp_login.initAuthnRequest()
+ sp_login.request.protocolBinding = lasso.SAML2_METADATA_BINDING_POST;
+ sp_login.buildAuthnRequestMsg()
+ idp_login = lasso.Login(idp_server)
+ # idp_login.setSignatureVerifyHint(lasso.PROFILE_SIGNATURE_VERIFY_HINT_FORCE)
+ idp_login.processAuthnRequestMsg(sp_login.msgUrl.split('?')[1])
+ idp_login.validateRequestMsg(True, True)
+ idp_login.buildAssertion("None", "None", "None", "None", "None")
+ idp_login.buildAuthnResponseMsg()
+ # sp_login.setSignatureVerifyHint(lasso.PROFILE_SIGNATURE_VERIFY_HINT_FORCE)
+ sp_login.processAuthnResponseMsg(idp_login.msgBody)
+ sp_login.acceptSso()
class LogoutTestCase(unittest.TestCase):
def test01(self):
diff --git a/lasso/saml-2.0/assertion_query.c b/lasso/saml-2.0/assertion_query.c
index ef0137d..56fb5ca 100644
--- a/lasso/saml-2.0/assertion_query.c
+++ b/lasso/saml-2.0/assertion_query.c
@@ -292,6 +292,7 @@ lasso_assertion_query_validate_request(LassoAssertionQuery *assertion_query)
response->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
}
response->private_key_file = g_strdup(profile->server->private_key);
+ response->private_key_password = g_strdup(profile->server->private_key_password);
response->certificate_file = g_strdup(profile->server->certificate);
/* verify signature status */
@@ -346,6 +347,7 @@ lasso_assertion_query_build_response_msg(LassoAssertionQuery *assertion_query)
response->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
}
response->private_key_file = g_strdup(profile->server->private_key);
+ response->private_key_password = g_strdup(profile->server->private_key_password);
response->certificate_file = g_strdup(profile->server->certificate);
return 0;
}
diff --git a/lasso/saml-2.0/login.c b/lasso/saml-2.0/login.c
index 7d8939c..ae6563e 100644
--- a/lasso/saml-2.0/login.c
+++ b/lasso/saml-2.0/login.c
@@ -144,6 +144,8 @@ lasso_saml20_login_build_authn_request_msg(LassoLogin *login, LassoProvider *rem
if (must_sign) {
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->private_key_file =
g_strdup(profile->server->private_key);
+ LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->private_key_password =
+ g_strdup(profile->server->private_key_password);
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->certificate_file =
g_strdup(profile->server->certificate);
}
@@ -867,6 +869,7 @@ lasso_saml20_login_build_assertion(LassoLogin *login,
}
assertion->sign_method = profile->server->signature_method;
assertion->private_key_file = g_strdup(profile->server->private_key);
+ assertion->private_key_password = g_strdup(profile->server->private_key_password);
assertion->certificate_file = g_strdup(profile->server->certificate);
/* Save encryption material in assertion private datas to be able to encrypt later */
@@ -985,6 +988,8 @@ lasso_saml20_login_build_request_msg(LassoLogin *login)
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->private_key_file =
g_strdup(profile->server->private_key);
+ LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->private_key_password =
+ g_strdup(profile->server->private_key_password);
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->certificate_file =
g_strdup(profile->server->certificate);
profile->msg_body = lasso_node_export_to_soap(profile->request);
@@ -1036,6 +1041,8 @@ lasso_saml20_login_build_response_msg(LassoLogin *login)
LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->private_key_file =
g_strdup(profile->server->private_key);
+ LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->private_key_password =
+ g_strdup(profile->server->private_key_password);
LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->certificate_file =
g_strdup(profile->server->certificate);
@@ -1397,6 +1404,8 @@ lasso_saml20_login_build_authn_response_msg(LassoLogin *login)
LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->private_key_file =
g_strdup(profile->server->private_key);
+ LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->private_key_password =
+ g_strdup(profile->server->private_key_password);
LASSO_SAMLP2_STATUS_RESPONSE(profile->response)->certificate_file =
g_strdup(profile->server->certificate);
diff --git a/lasso/saml-2.0/logout.c b/lasso/saml-2.0/logout.c
index 3b89094..46d284d 100644
--- a/lasso/saml-2.0/logout.c
+++ b/lasso/saml-2.0/logout.c
@@ -199,6 +199,8 @@ lasso_saml20_logout_build_request_msg(LassoLogout *logout, LassoProvider *remote
}
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->private_key_file =
g_strdup(profile->server->private_key);
+ LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->private_key_password =
+ g_strdup(profile->server->private_key_password);
LASSO_SAMLP2_REQUEST_ABSTRACT(profile->request)->certificate_file =
g_strdup(profile->server->certificate);
@@ -299,6 +301,7 @@ lasso_saml20_logout_validate_request(LassoLogout *logout)
response->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
}
response->private_key_file = g_strdup(profile->server->private_key);
+ response->private_key_password = g_strdup(profile->server->private_key_password);
response->certificate_file = g_strdup(profile->server->certificate);
/* verify signature status */
@@ -466,6 +469,7 @@ lasso_saml20_logout_build_response_msg(LassoLogout *logout)
response->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
}
response->private_key_file = g_strdup(profile->server->private_key);
+ response->private_key_password = g_strdup(profile->server->private_key_password);
response->certificate_file = g_strdup(profile->server->certificate);
}
diff --git a/lasso/saml-2.0/profile.c b/lasso/saml-2.0/profile.c
index 5e2ddd1..e3b09bd 100644
--- a/lasso/saml-2.0/profile.c
+++ b/lasso/saml-2.0/profile.c
@@ -340,6 +340,7 @@ lasso_saml20_profile_build_artifact_response(LassoProfile *profile)
response->sign_type = LASSO_SIGNATURE_TYPE_SIMPLE;
}
response->private_key_file = g_strdup(profile->server->private_key);
+ response->private_key_password = g_strdup(profile->server->private_key_password);
response->certificate_file = g_strdup(profile->server->certificate);
profile->response = LASSO_NODE(response);
@@ -791,6 +792,7 @@ lasso_saml20_profile_setup_request_signing(LassoProfile *profile)
request_abstract->sign_type = server->certificate ? LASSO_SIGNATURE_TYPE_WITHX509 :
LASSO_SIGNATURE_TYPE_SIMPLE;
lasso_assign_string(request_abstract->private_key_file, server->private_key);
+ lasso_assign_string(request_abstract->private_key_password, server->private_key_password);
lasso_assign_string(request_abstract->certificate_file, server->certificate);
cleanup:
@@ -935,6 +937,7 @@ lasso_saml20_profile_setup_response_signing(LassoProfile *profile)
response_abstract->sign_type = server->certificate ? LASSO_SIGNATURE_TYPE_WITHX509 :
LASSO_SIGNATURE_TYPE_SIMPLE;
lasso_assign_string(response_abstract->private_key_file, server->private_key);
+ lasso_assign_string(response_abstract->private_key_password, server->private_key_password);
lasso_assign_string(response_abstract->certificate_file, server->certificate);
cleanup:
@@ -1039,7 +1042,7 @@ lasso_saml20_profile_export_to_query(LassoProfile *profile, LassoNode *msg, int
}
if (sign && lasso_flag_add_signature) {
result = lasso_query_sign(unsigned_query, profile->server->signature_method,
- profile->server->private_key);
+ profile->server->private_key, profile->server->private_key_password);
lasso_release_string(unsigned_query);
} else {
result = unsigned_query;
diff --git a/lasso/xml/private.h b/lasso/xml/private.h
index de67fb7..4d5ac9d 100644
--- a/lasso/xml/private.h
+++ b/lasso/xml/private.h
@@ -121,7 +121,7 @@ xmlSecKeyPtr lasso_get_public_key_from_pem_cert_file(const char *file);
xmlSecKeysMngr* lasso_load_certs_from_pem_certs_chain_file (const char *file);
char* lasso_query_sign(char *query, LassoSignatureMethod sign_method,
- const char *private_key_file);
+ const char *private_key_file, const char *private_key_password);
int lasso_query_verify_signature(const char *query, const xmlSecKey *public_key);
@@ -130,7 +130,8 @@ char* lasso_sha1(const char *str);
char** urlencoded_to_strings(const char *str);
int lasso_sign_node(xmlNode *xmlnode, const char *id_attr_name, const char *id_value,
- const char *private_key_file, const char *certificate_file);
+ const char *private_key_file, const char *private_key_password,
+ const char *certificate_file);
int lasso_verify_signature(xmlNode *signed_node, xmlDoc *doc, const char *id_attr_name,
xmlSecKeysMngr *keys_manager, xmlSecKey *public_key,
diff --git a/lasso/xml/saml-2.0/saml2_assertion.c b/lasso/xml/saml-2.0/saml2_assertion.c
index bb6145d..90f21b8 100644
--- a/lasso/xml/saml-2.0/saml2_assertion.c
+++ b/lasso/xml/saml-2.0/saml2_assertion.c
@@ -98,6 +98,8 @@ static struct XmlSnippet schema_snippets[] = {
G_STRUCT_OFFSET(LassoSaml2Assertion, sign_method), NULL, NULL, NULL},
{ "PrivateKeyFile", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
G_STRUCT_OFFSET(LassoSaml2Assertion, private_key_file), NULL, NULL, NULL},
+ { "PrivateKeyPassword", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
+ G_STRUCT_OFFSET(LassoSaml2Assertion, private_key_password), NULL, NULL, NULL},
{ "CertificateFile", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
G_STRUCT_OFFSET(LassoSaml2Assertion, certificate_file), NULL, NULL, NULL},
{ "EncryptionActivated", SNIPPET_ATTRIBUTE | SNIPPET_BOOLEAN | SNIPPET_LASSO_DUMP,
@@ -129,7 +131,7 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
"No Private Key set for signing saml2:Assertion");
} else {
rc = lasso_sign_node(xmlnode, "ID", assertion->ID,
- assertion->private_key_file, assertion->certificate_file);
+ assertion->private_key_file, assertion->private_key_password, assertion->certificate_file);
if (rc != 0) {
message(G_LOG_LEVEL_WARNING, "Signing of saml2:Assertion failed: %s", lasso_strerror(rc));
}
diff --git a/lasso/xml/saml-2.0/saml2_assertion.h b/lasso/xml/saml-2.0/saml2_assertion.h
index 524943c..ac1f48b 100644
--- a/lasso/xml/saml-2.0/saml2_assertion.h
+++ b/lasso/xml/saml-2.0/saml2_assertion.h
@@ -77,6 +77,7 @@ struct _LassoSaml2Assertion {
LassoSignatureType sign_type;
LassoSignatureMethod sign_method;
char *private_key_file;
+ char *private_key_password;
char *certificate_file;
gboolean encryption_activated;
char *encryption_public_key_str;
diff --git a/lasso/xml/saml-2.0/samlp2_request_abstract.c b/lasso/xml/saml-2.0/samlp2_request_abstract.c
index d9118d8..60fe369 100644
--- a/lasso/xml/saml-2.0/samlp2_request_abstract.c
+++ b/lasso/xml/saml-2.0/samlp2_request_abstract.c
@@ -84,6 +84,8 @@ static struct XmlSnippet schema_snippets[] = {
G_STRUCT_OFFSET(LassoSamlp2RequestAbstract, sign_method), NULL, NULL, NULL},
{ "PrivateKeyFile", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
G_STRUCT_OFFSET(LassoSamlp2RequestAbstract, private_key_file), NULL, NULL, NULL},
+ { "PrivateKeyPassword", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
+ G_STRUCT_OFFSET(LassoSamlp2RequestAbstract, private_key_password), NULL, NULL, NULL},
{ "CertificateFile", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
G_STRUCT_OFFSET(LassoSamlp2RequestAbstract, certificate_file), NULL, NULL, NULL},
@@ -127,7 +129,7 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
"No Private Key set for signing samlp2:RequestAbstract");
} else {
rc = lasso_sign_node(xmlnode, "ID", request->ID,
- request->private_key_file, request->certificate_file);
+ request->private_key_file, request->private_key_password, request->certificate_file);
if (rc != 0) {
message(G_LOG_LEVEL_WARNING, "Signing of samlp2:RequestAbstract failed: %s", lasso_strerror(rc));
}
diff --git a/lasso/xml/saml-2.0/samlp2_request_abstract.h b/lasso/xml/saml-2.0/samlp2_request_abstract.h
index fdd87bf..43a2263 100644
--- a/lasso/xml/saml-2.0/samlp2_request_abstract.h
+++ b/lasso/xml/saml-2.0/samlp2_request_abstract.h
@@ -69,6 +69,7 @@ struct _LassoSamlp2RequestAbstract {
LassoSignatureType sign_type;
LassoSignatureMethod sign_method;
char *private_key_file;
+ char *private_key_password;
char *certificate_file;
};
diff --git a/lasso/xml/saml-2.0/samlp2_status_response.c b/lasso/xml/saml-2.0/samlp2_status_response.c
index c25266f..ebc1b16 100644
--- a/lasso/xml/saml-2.0/samlp2_status_response.c
+++ b/lasso/xml/saml-2.0/samlp2_status_response.c
@@ -89,6 +89,8 @@ static struct XmlSnippet schema_snippets[] = {
G_STRUCT_OFFSET(LassoSamlp2StatusResponse, sign_method), NULL, NULL, NULL},
{ "PrivateKeyFile", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
G_STRUCT_OFFSET(LassoSamlp2StatusResponse, private_key_file), NULL, NULL, NULL},
+ { "PrivateKeyPassword", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
+ G_STRUCT_OFFSET(LassoSamlp2StatusResponse, private_key_password), NULL, NULL, NULL},
{ "CertificateFile", SNIPPET_CONTENT | SNIPPET_LASSO_DUMP,
G_STRUCT_OFFSET(LassoSamlp2StatusResponse, certificate_file), NULL, NULL, NULL},
@@ -132,7 +134,7 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
"No Private Key set for signing samlp2:StatusResponse");
} else {
rc = lasso_sign_node(xmlnode, "ID", response->ID,
- response->private_key_file, response->certificate_file);
+ response->private_key_file, response->private_key_password, response->certificate_file);
if (rc != 0) {
message(G_LOG_LEVEL_WARNING, "Signing of samlp2:StatusResponse failed: %s", lasso_strerror(rc));
}
diff --git a/lasso/xml/saml-2.0/samlp2_status_response.h b/lasso/xml/saml-2.0/samlp2_status_response.h
index ad7d898..d190a84 100644
--- a/lasso/xml/saml-2.0/samlp2_status_response.h
+++ b/lasso/xml/saml-2.0/samlp2_status_response.h
@@ -72,6 +72,7 @@ struct _LassoSamlp2StatusResponse {
LassoSignatureType sign_type;
LassoSignatureMethod sign_method;
char *private_key_file;
+ char *private_key_password;
char *certificate_file;
};
diff --git a/lasso/xml/saml_assertion.c b/lasso/xml/saml_assertion.c
index 819c733..f2a6199 100644
--- a/lasso/xml/saml_assertion.c
+++ b/lasso/xml/saml_assertion.c
@@ -165,7 +165,7 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
"No Private Key set for signing saml:Assertion");
} else {
rc = lasso_sign_node(xmlnode, "AssertionID", assertion->AssertionID,
- assertion->private_key_file, assertion->certificate_file);
+ assertion->private_key_file, NULL, assertion->certificate_file);
if (rc != 0) {
message(G_LOG_LEVEL_WARNING, "Signing of saml:Assertion failed: %s", lasso_strerror(rc));
}
diff --git a/lasso/xml/samlp_request_abstract.c b/lasso/xml/samlp_request_abstract.c
index 3ef984f..2c51bae 100644
--- a/lasso/xml/samlp_request_abstract.c
+++ b/lasso/xml/samlp_request_abstract.c
@@ -93,7 +93,7 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
"No Private Key set for signing samlp:RequestAbstract");
} else {
rc = lasso_sign_node(xmlnode, "RequestID", request->RequestID,
- request->private_key_file, request->certificate_file);
+ request->private_key_file, NULL, request->certificate_file);
if (rc != 0) {
message(G_LOG_LEVEL_WARNING, "Signing of samlp:RequestAbstract failed: %s", lasso_strerror(rc));
}
diff --git a/lasso/xml/samlp_response_abstract.c b/lasso/xml/samlp_response_abstract.c
index e52e4ba..159fd91 100644
--- a/lasso/xml/samlp_response_abstract.c
+++ b/lasso/xml/samlp_response_abstract.c
@@ -97,7 +97,7 @@ get_xmlNode(LassoNode *node, gboolean lasso_dump)
"No Private Key set for signing samlp:ResponseAbstract");
} else {
rc = lasso_sign_node(xmlnode, "ResponseID", response->ResponseID,
- response->private_key_file, response->certificate_file);
+ response->private_key_file, NULL, response->certificate_file);
if (rc != 0) {
message(G_LOG_LEVEL_WARNING, "Signing of samlp:ResponseAbstract failed: %s", lasso_strerror(rc));
}
diff --git a/lasso/xml/tools.c b/lasso/xml/tools.c
index 6e6e7ab..c06690c 100644
--- a/lasso/xml/tools.c
+++ b/lasso/xml/tools.c
@@ -379,7 +379,8 @@ lasso_load_certs_from_pem_certs_chain_file(const char* pem_certs_chain_file)
* Return value: a newly allocated query signed or NULL if an error occurs.
**/
char*
-lasso_query_sign(char *query, LassoSignatureMethod sign_method, const char *private_key_file)
+lasso_query_sign(char *query, LassoSignatureMethod sign_method, const char *private_key_file,
+ G_GNUC_UNUSED const char *private_key_password)
{
BIO *bio = NULL;
char *digest = NULL; /* 160 bit buffer */
@@ -433,7 +434,7 @@ lasso_query_sign(char *query, LassoSignatureMethod sign_method, const char *priv
/* calculate signature value */
if (sign_method == LASSO_SIGNATURE_METHOD_RSA_SHA1) {
/* load private key */
- rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
+ rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, (void*)private_key_password);
if (rsa == NULL) {
goto done;
}
@@ -443,7 +444,7 @@ lasso_query_sign(char *query, LassoSignatureMethod sign_method, const char *priv
status = RSA_sign(NID_sha1, (unsigned char*)digest, 20, sigret, &siglen, rsa);
RSA_free(rsa);
} else if (sign_method == LASSO_SIGNATURE_METHOD_DSA_SHA1) {
- dsa = PEM_read_bio_DSAPrivateKey(bio, NULL, NULL, NULL);
+ dsa = PEM_read_bio_DSAPrivateKey(bio, NULL, NULL, (void*)private_key_password);
if (dsa == NULL) {
goto done;
}
@@ -744,7 +745,7 @@ error_code(G_GNUC_UNUSED GLogLevelFlags level, int error, ...)
int
lasso_sign_node(xmlNode *xmlnode, const char *id_attr_name, const char *id_value,
- const char *private_key_file, const char *certificate_file)
+ const char *private_key_file, G_GNUC_UNUSED const char* private_key_password, const char *certificate_file)
{
xmlDoc *doc;
xmlNode *sign_tmpl, *old_parent;
@@ -769,11 +770,11 @@ lasso_sign_node(xmlNode *xmlnode, const char *id_attr_name, const char *id_value
if (access(private_key_file, R_OK) == 0) {
dsig_ctx->signKey = xmlSecCryptoAppKeyLoad(private_key_file,
xmlSecKeyDataFormatPem,
- NULL, NULL, NULL);
+ private_key_password, NULL, NULL);
} else {
int len = private_key_file ? strlen(private_key_file) : 0;
dsig_ctx->signKey = xmlSecCryptoAppKeyLoadMemory((xmlSecByte*)private_key_file, len,
- xmlSecKeyDataFormatPem, NULL, NULL, NULL);
+ xmlSecKeyDataFormatPem, private_key_password, NULL, NULL);
}
if (dsig_ctx->signKey == NULL) {
xmlSecDSigCtxDestroy(dsig_ctx);
diff --git a/lasso/xml/xml.c b/lasso/xml/xml.c
index db961bc..f97382d 100644
--- a/lasso/xml/xml.c
+++ b/lasso/xml/xml.c
@@ -390,7 +390,7 @@ lasso_node_export_to_query(LassoNode *node,
unsigned_query = lasso_node_build_query(node);
if (private_key_file) {
- query = lasso_query_sign(unsigned_query, sign_method, private_key_file);
+ query = lasso_query_sign(unsigned_query, sign_method, private_key_file, NULL);
} else {
lasso_transfer_string(query, unsigned_query);
}
diff --git a/tests/data/idp7-saml2/metadata.xml b/tests/data/idp7-saml2/metadata.xml
new file mode 100644
index 0000000..9c8963f
--- /dev/null
+++ b/tests/data/idp7-saml2/metadata.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+MIIDnjCCAoagAwIBAgIBATANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJGUjEP
+MA0GA1UECBMGRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczETMBEGA1UEChMKRW50cm91
+dmVydDEPMA0GA1UEAxMGRGFtaWVuMB4XDTA2MTAyNzA5MDc1NFoXDTExMTAyNjA5
+MDc1NFowVDELMAkGA1UEBhMCRlIxDzANBgNVBAgTBkZyYW5jZTEOMAwGA1UEBxMF
+UGFyaXMxEzARBgNVBAoTCkVudHJvdXZlcnQxDzANBgNVBAMTBkRhbWllbjCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM06Hx6VgHYR9wUf/tZVVTRkVWNq
+h9x+PvHA2qH4OYMuqGs4Af6lU2YsZvnrmRdcFWv0+UkdAgXhReCWAZgtB1pd/W9m
+6qDRldCCyysow6xPPKRz/pOTwRXm/fM0QGPeXzwzj34BXOIOuFu+n764vKn18d+u
+uVAEzk1576pxTp4pQPzJfdNLrLeQ8vyCshoFU+MYJtp1UA+h2JoO0Y8oGvywbUxH
+ioHN5PvnzObfAM4XaDQohmfxM9Uc7Wp4xKAc1nUq5hwBrHpjFMRSz6UCfMoJSGIi
++3xJMkNCjL0XEw5NKVc5jRKkzSkN5j8KTM/k1jPPsDHPRYzbWWhnNtd6JlkCAwEA
+AaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0
+ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFP2WWMDShux3iF74+SoO1xf6qhqaMB8G
+A1UdIwQYMBaAFGjl6TRXbQDHzSlZu+e8VeBaZMB5MA0GCSqGSIb3DQEBBQUAA4IB
+AQAZ/imK7UMognXbs5RfSB8cMW6iNAI+JZqe9XWjvtmLfIIPbHM96o953SiFvrvQ
+BZjGmmPMK3UH29cjzDx1R/RQaYTyMrHyTePLh3BMd5mpJ/9eeJCSxPzE2ECqWRUa
+pkjukecFXqmRItwgTxSIUE9QkpzvuQRb268PwmgroE0mwtiREADnvTFkLkdiEMew
+fiYxZfJJLPBqwlkw/7f1SyzXoPXnz5QbNwDmrHelga6rKSprYKb3pueqaIe8j/AP
+NC1/bzp8cGOcJ88BD5+Ny6qgPVCrMLE5twQumJ12V3SvjGNtzFBvg2c/9S5OmVqR
+LlTxKnCrWAXftSm1rNtewTsF
+
+
+
+
+
+
+MIIDnjCCAoagAwIBAgIBATANBgkqhkiG9w0BAQUFADBUMQswCQYDVQQGEwJGUjEP
+MA0GA1UECBMGRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczETMBEGA1UEChMKRW50cm91
+dmVydDEPMA0GA1UEAxMGRGFtaWVuMB4XDTA2MTAyNzA5MDc1NFoXDTExMTAyNjA5
+MDc1NFowVDELMAkGA1UEBhMCRlIxDzANBgNVBAgTBkZyYW5jZTEOMAwGA1UEBxMF
+UGFyaXMxEzARBgNVBAoTCkVudHJvdXZlcnQxDzANBgNVBAMTBkRhbWllbjCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM06Hx6VgHYR9wUf/tZVVTRkVWNq
+h9x+PvHA2qH4OYMuqGs4Af6lU2YsZvnrmRdcFWv0+UkdAgXhReCWAZgtB1pd/W9m
+6qDRldCCyysow6xPPKRz/pOTwRXm/fM0QGPeXzwzj34BXOIOuFu+n764vKn18d+u
+uVAEzk1576pxTp4pQPzJfdNLrLeQ8vyCshoFU+MYJtp1UA+h2JoO0Y8oGvywbUxH
+ioHN5PvnzObfAM4XaDQohmfxM9Uc7Wp4xKAc1nUq5hwBrHpjFMRSz6UCfMoJSGIi
++3xJMkNCjL0XEw5NKVc5jRKkzSkN5j8KTM/k1jPPsDHPRYzbWWhnNtd6JlkCAwEA
+AaN7MHkwCQYDVR0TBAIwADAsBglghkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0
+ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFP2WWMDShux3iF74+SoO1xf6qhqaMB8G
+A1UdIwQYMBaAFGjl6TRXbQDHzSlZu+e8VeBaZMB5MA0GCSqGSIb3DQEBBQUAA4IB
+AQAZ/imK7UMognXbs5RfSB8cMW6iNAI+JZqe9XWjvtmLfIIPbHM96o953SiFvrvQ
+BZjGmmPMK3UH29cjzDx1R/RQaYTyMrHyTePLh3BMd5mpJ/9eeJCSxPzE2ECqWRUa
+pkjukecFXqmRItwgTxSIUE9QkpzvuQRb268PwmgroE0mwtiREADnvTFkLkdiEMew
+fiYxZfJJLPBqwlkw/7f1SyzXoPXnz5QbNwDmrHelga6rKSprYKb3pueqaIe8j/AP
+NC1/bzp8cGOcJ88BD5+Ny6qgPVCrMLE5twQumJ12V3SvjGNtzFBvg2c/9S5OmVqR
+LlTxKnCrWAXftSm1rNtewTsF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress
+
+
+
+
+ urn:oasis:names:tc:SAML:1.1:nameid-format:kerberos
+
+
+
+
+ urn:oasis:names:tc:SAML:1.1:nameid-format:X509SubjectName
+
+
+ Entr'ouvert
+
+
+
diff --git a/tests/data/idp7-saml2/password b/tests/data/idp7-saml2/password
new file mode 100644
index 0000000..fcde4cd
--- /dev/null
+++ b/tests/data/idp7-saml2/password
@@ -0,0 +1 @@
+geronimo
\ No newline at end of file
diff --git a/tests/data/idp7-saml2/private-key.pem b/tests/data/idp7-saml2/private-key.pem
new file mode 100644
index 0000000..4557854
--- /dev/null
+++ b/tests/data/idp7-saml2/private-key.pem
@@ -0,0 +1,30 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,41BE9422FBDF1769BFEF03F9116F7A86
+
+qKrThgVCsCb5Lx/7RIpwuvDZi6gvxEFb33QEjIEWdZ+ad0dkGRvxrIqqj+XvHEeW
+V57oPO1sFAlgb+zBrGZpqItCAJEqC4NU55SwKZpKUtT0XdlHFRyfORlBwzb0qW/3
+dZbyhsEm+164MdXsCZiUYS/VAm8b1pYmBIkoPSZMMnPljNYVigRpYttF9dwMYgTQ
+u/FwRS696qGSyo7ko00P8UbtTLgM+ufkCFNld6uxYphSNXAQyRQz4vQs97emNE58
+4JB5//0agCOa9qUz14ZQSpM2JyoevMHUOHyjbGJOLsCMPnQEboKvgj0gsZcgP2Ys
+K4Nf/EQKadBbXpK4olxz50e6ybR0i7nylYsu7YVFyFR9GWbra29OAYEPvQxvBll7
+RIoZ4hI0ZgBY0qFFcyZbKH94Pqk5w0QSjfkHPcH/WL0UjLb+n59KsIUnmZ3dtiF9
+9mdE71wq94jOcqibjVmUy3Gyw4COZKTTjq9ptuLBC6fEPxGh6dfpSSV431Wpvpxy
+OE15vfeT1i/ymH0ckWsQXgUqZ6QTuaTvlu5JpD94Blu7p6Rzj5fxEnLhOtwjXWpq
+k6MAlS9bKhGbPbnzAqm5HkRypgDaNBPRXZhb9LClB5ysfjZRNdxCWrWusEGEtioQ
+TdkPsUZ78d8m3u+FvOM2mTVkQBa6sAEl1l8fuOITuaNCYLBIIhyAvJfXRHhOC+zs
+nvS6DX+3bZupxFJFcMi9fqlmz0QSXj4tKlbHY/xo3dGqQj5BWyibo8tDVhVIYy99
+zo/t8J0LTfSSCIvoV2gFHSoC7RIJ9Q25L0AV6TQiB2F/7FTeznfd7Tk9ZHokmiED
+5VAKGRjDmPCZIJr2pbeEmwzs3r/p53JfLyNProv+ljTJLgdFtG1en5A3MsmymR0c
+LTIxHWZjAwl7ai1yGghzqVYllm+OFjo6LsSusbuQwKs+Bo9qZPCBb10gQGur+ZR8
+r9Vfd3WV/WMJfi8Ciogd+uXhPzVxf5PyBvZh9vwqXHSB9YLxe+NpAxLxF5OuZmJx
+VBdTA5y19XUvyucOOxjcJZaZTP6BYADsaUxhQIQHfyUtk6Y7Iwk2Abf4TQIuC5x6
+XEeRSmbKPCkuKh9L0H4KcK6hmFSyh7AICpUEW7tcMtK9HaZT/K5jsHPkG5q/3GXh
+ed7e0QaA2Qc0uAvoFgGTPkgE6Nym30R6NUlnHl2T3gK9Ei6fQKdTYPYgRXAKmbNO
+Wp0cjQ7w1zUNjoxkACX2Br2xm3DhnLVFPj6AWpnCsTtQA3ecgIzvSZugxpr0muP0
+SIPpBuyko+t0YQjP3DOZxeiLQ5o+3VxI749KfDuaNZsDN7ZPso7Pt1oG34uGgsFl
+UypVEv+CgzTkepPPqJTWgK5VfNrSK3ev7Is90bpiyjwqywlwYaZUOXBm+wBwUmtH
+T+lLtw00R5JGolA4I2MCd4PTauzbj30jLYJWLLW8sZcfMgpwnKUNtVwRaDMnOXIA
+eX0cesfIbMiYF1sgR2Lqar/uqSJf1Kx8xIFdvqYZWsudF0ij4fva4xtCc0bgrnSy
+lz91YgfF95hTd/qcCiO5GQxScG7umtUZLYmZKqtYKDjCkvtvnGFhqB5Ie21DK6OX
+-----END RSA PRIVATE KEY-----
diff --git a/tests/data/sp7-saml2/metadata.xml b/tests/data/sp7-saml2/metadata.xml
new file mode 100644
index 0000000..227b5e0
--- /dev/null
+++ b/tests/data/sp7-saml2/metadata.xml
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+ -----BEGIN PUBLIC KEY-----
+MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAN0uVeOaTMQjhFlwGv/yBiGOdHDwiHb3
+BD+ALxLgfcd9LpbAePbKk4Tx/juoEEPT3guQD0zyg0IcqkXO/JxrPa0CAwEAAQ==
+-----END PUBLIC KEY-----
+
+
+
+
+
+
+
+
+
+
+
+
+ Lasso Test SP7
+
+
diff --git a/tests/data/sp7-saml2/password b/tests/data/sp7-saml2/password
new file mode 100644
index 0000000..fcde4cd
--- /dev/null
+++ b/tests/data/sp7-saml2/password
@@ -0,0 +1 @@
+geronimo
\ No newline at end of file
diff --git a/tests/data/sp7-saml2/private-key.pem b/tests/data/sp7-saml2/private-key.pem
new file mode 100644
index 0000000..86a59ce
--- /dev/null
+++ b/tests/data/sp7-saml2/private-key.pem
@@ -0,0 +1,12 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: AES-256-CBC,EF4EF473516D85011B23403600D01371
+
+kwbLjFZ8SsSyhTosBKpU1N5hvh4INRpJkXmj8aNHppz75nyGTo/jar+FRD6LA0fX
+3dbXdcHveUHSFs9t2AADQfVAJUbZU0D3bN0horJljA+ymiZ22Fr421cdxqbd2+1U
+4ZmPKF+w/ALkal821a2+br/OP6V1mA4KH7/YScmSGKGKkl1TZ/5cV8bjwAQGJyck
+4e0loU9yrAkw3oua1bWAudl7suS62K0AQA3K5lmfUld3JNzO/TQq2qIcvJVU1hEi
+UtE8biPKjcNOdEcz98+hgsHd1+jBR4tazaaib92P3ga7IgAr+AGwoHd6wBh5q11+
+1/cNTH8MC2AbQhhll4e9bo7A/RmorqvIUQ4/7b8lBzi8JbcgME3UOhBJqSzkgnTb
+emO3IOAQHLbcvel03MbiwS8nhKjdldNdj2NudHD8FPI=
+-----END RSA PRIVATE KEY-----