~ubuntu-branches/ubuntu/hardy/lasso/hardy

« back to all changes in this revision

Viewing changes to lasso/id-wsf/wsf_profile.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Bienia
  • Date: 2007-07-31 21:35:26 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070731213526-oc6jw5mprcd5tjyy
Tags: 2.0.0-1ubuntu1
* Merge from debian unstable. Remaining changes:
  + debian/control:
    - Modify Maintainer value to match DebianMaintainerField spec.
* debian/rules:
  + Add CC=gcc-4.2 to the configure call else configure won't find jni.h
    from libgcj8-dev.
* configure{,.ac}:
  + Add missing quotes around the value for PHP[45]_LIBS.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: wsf_profile.c,v 1.32 2006/03/04 15:55:56 fpeters Exp $
 
1
/* $Id: wsf_profile.c,v 1.45 2007/01/05 16:11:02 fpeters Exp $
2
2
 *
3
3
 * Lasso - A free implementation of the Liberty Alliance specifications.
4
4
 *
22
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
23
 */
24
24
 
 
25
#include <libxml/xpath.h>
 
26
#include <libxml/xpathInternals.h>
 
27
 
 
28
#include <xmlsec/xmltree.h>
 
29
#include <xmlsec/xmldsig.h>
 
30
#include <xmlsec/templates.h>
 
31
#include <xmlsec/crypto.h>
 
32
 
25
33
#include <lasso/id-wsf/wsf_profile.h>
26
34
#include <lasso/xml/disco_modify.h>
27
35
#include <lasso/xml/soap_fault.h>
37
45
#include <lasso/id-ff/server.h>
38
46
#include <lasso/id-ff/providerprivate.h>
39
47
 
40
 
#include <xmlsec/xmltree.h>
41
 
#include <xmlsec/xmldsig.h>
42
 
#include <xmlsec/templates.h>
43
 
#include <xmlsec/crypto.h>
 
48
#include <lasso/id-wsf/wsf_profile_private.h>
44
49
 
45
50
struct _LassoWsfProfilePrivate
46
51
{
51
56
        GList *credentials;
52
57
};
53
58
 
 
59
gint lasso_wsf_profile_verify_x509_authentication(LassoWsfProfile *profile,
 
60
                xmlDoc *doc, xmlSecKey *public_key);
 
61
static gboolean lasso_wsf_profile_has_saml_authentication(LassoWsfProfile *profile);
 
62
static gboolean lasso_wsf_profile_has_x509_authentication(LassoWsfProfile *profile);
 
63
static gint lasso_wsf_profile_verify_credential_signature(
 
64
                LassoWsfProfile *profile, xmlDoc *doc, xmlNode *credential);
 
65
static gint lasso_wsf_profile_add_credential_signature(LassoWsfProfile *profile,
 
66
                xmlDoc *doc, xmlNode *credential, LassoSignatureMethod sign_method);
 
67
static xmlSecKey* lasso_wsf_profile_get_public_key_from_credential(
 
68
                LassoWsfProfile *profile, xmlNode *credential);
 
69
static gint lasso_wsf_profile_verify_saml_authentication(LassoWsfProfile *profile, xmlDoc *doc);
 
70
static gint lasso_wsf_profile_add_soap_signature(LassoWsfProfile *profile,
 
71
                xmlDoc *doc, xmlNode *envelope_node, LassoSignatureMethod sign_method);
 
72
static int lasso_wsf_profile_ensure_soap_credentials_signature(
 
73
                LassoWsfProfile *profile, xmlDoc *doc, xmlNode *soap_envelope);
 
74
static LassoDiscoDescription* lasso_wsf_profile_get_description_auto(
 
75
                LassoDiscoServiceInstance *si, const gchar *security_mech_id);
 
76
 
54
77
/*****************************************************************************/
55
78
/* private methods                                                           */
56
79
/*****************************************************************************/
62
85
        GList *iter;
63
86
 
64
87
        iter = src->private_data->credentials;
65
 
        while(iter) {
 
88
        while (iter) {
66
89
                credential = (xmlNode *) iter->data;
67
90
                lasso_wsf_profile_add_credential(dest, credential);
68
91
                iter = iter->next;
88
111
                profile->private_data->public_key = g_strdup(public_key);
89
112
}
90
113
 
91
 
LassoDiscoDescription*
 
114
static LassoDiscoDescription*
92
115
lasso_wsf_profile_get_description_auto(LassoDiscoServiceInstance *si, const gchar *security_mech_id)
93
116
{
94
117
        GList *iter, *iter2;
118
141
        return profile->private_data->fault;
119
142
}
120
143
 
121
 
gboolean
 
144
static gboolean
122
145
lasso_wsf_profile_has_saml_authentication(LassoWsfProfile *profile)
123
146
{
124
147
        GList *iter;
125
148
        gchar *security_mech_id;
126
149
 
127
 
        if (!profile->private_data->description)
 
150
        if (profile->private_data->description == NULL)
128
151
                return FALSE;
129
152
 
130
153
        iter = profile->private_data->description->SecurityMechID;
131
 
        while(iter) {
 
154
        while (iter) {
132
155
                security_mech_id = iter->data;
133
 
                if (strcmp(security_mech_id, LASSO_SECURITY_MECH_SAML) == 0 || \
134
 
                    strcmp(security_mech_id, LASSO_SECURITY_MECH_TLS_SAML) == 0 || \
135
 
                    strcmp(security_mech_id, LASSO_SECURITY_MECH_CLIENT_TLS_SAML) == 0) {
136
 
                            return TRUE;
137
 
                            break;
 
156
                if (strcmp(security_mech_id, LASSO_SECURITY_MECH_CLIENT_TLS_SAML) == 0 ||
 
157
                                strcmp(security_mech_id, LASSO_SECURITY_MECH_TLS_SAML) == 0 ||
 
158
                                strcmp(security_mech_id, LASSO_SECURITY_MECH_SAML) == 0) {
 
159
                        return TRUE;
138
160
                }
139
 
                iter = iter->next;
 
161
                iter = g_list_next(iter);
140
162
        }
141
163
 
142
164
        return FALSE;
143
165
}
144
166
 
145
 
gboolean
 
167
static gboolean
146
168
lasso_wsf_profile_has_x509_authentication(LassoWsfProfile *profile)
147
169
{
148
170
        GList *iter;
149
171
        gchar *security_mech_id;
150
172
 
151
 
        if (!profile->private_data->description)
 
173
        if (profile->private_data->description == NULL)
152
174
                return FALSE;
153
175
 
154
176
        iter = profile->private_data->description->SecurityMechID;
155
 
        while(iter) {
 
177
        while (iter) {
156
178
                security_mech_id = iter->data;
157
 
                if (strcmp(security_mech_id, LASSO_SECURITY_MECH_X509) == 0 || \
158
 
                    strcmp(security_mech_id, LASSO_SECURITY_MECH_TLS_X509) == 0 || \
159
 
                    strcmp(security_mech_id, LASSO_SECURITY_MECH_CLIENT_TLS_X509) == 0) {
160
 
                            return TRUE;
161
 
                            break;
 
179
                if (strcmp(security_mech_id, LASSO_SECURITY_MECH_CLIENT_TLS_X509) == 0 ||
 
180
                                strcmp(security_mech_id, LASSO_SECURITY_MECH_TLS_X509) == 0 ||
 
181
                                strcmp(security_mech_id, LASSO_SECURITY_MECH_X509) == 0) {
 
182
                        return TRUE;
162
183
                }
163
 
                iter = iter->next;
 
184
                iter = g_list_next(iter);
164
185
        }
165
186
 
166
187
        return FALSE;
172
193
        if (!security_mech_id)
173
194
                return FALSE;
174
195
 
175
 
        if (strcmp(security_mech_id, LASSO_SECURITY_MECH_SAML) == 0 || \
176
 
                strcmp(security_mech_id, LASSO_SECURITY_MECH_TLS_SAML) == 0 || \
177
 
                strcmp(security_mech_id, LASSO_SECURITY_MECH_CLIENT_TLS_SAML) == 0)
 
196
        if (strcmp(security_mech_id, LASSO_SECURITY_MECH_SAML) == 0 ||
 
197
                        strcmp(security_mech_id, LASSO_SECURITY_MECH_TLS_SAML) == 0 ||
 
198
                        strcmp(security_mech_id, LASSO_SECURITY_MECH_CLIENT_TLS_SAML) == 0)
178
199
                return TRUE;
179
200
 
180
201
        return FALSE;
186
207
        profile->private_data->description = g_object_ref(description);
187
208
}
188
209
 
189
 
gint
190
 
lasso_wsf_profile_verify_credential_signature(LassoWsfProfile *profile,
191
 
                                              xmlDoc *doc, xmlNode *credential)
 
210
static gint
 
211
lasso_wsf_profile_verify_credential_signature(
 
212
                LassoWsfProfile *profile, xmlDoc *doc, xmlNode *credential)
192
213
{
193
214
        LassoProvider *lasso_provider;
194
215
 
200
221
 
201
222
        xmlSecDSigCtx *dsigCtx;
202
223
 
203
 
        char *issuer;
 
224
        xmlChar *issuer;
204
225
 
205
226
        /* Retrieve provider id of credential signer . Issuer could be the right place */
206
 
        issuer = xmlGetProp(credential, "Issuer");
207
 
        if (!issuer)
208
 
                return -1;
209
 
        lasso_provider = lasso_server_get_provider(profile->server, issuer);
210
 
        if (!lasso_provider)
211
 
                return -1;
 
227
        issuer = xmlGetProp(credential, (xmlChar*)"Issuer");
 
228
        if (issuer == NULL) {
 
229
                return LASSO_PROFILE_ERROR_MISSING_ISSUER;
 
230
        }
 
231
 
 
232
        lasso_provider = lasso_server_get_provider(profile->server, (char*)issuer);
 
233
        if (lasso_provider == NULL) {
 
234
                return LASSO_SERVER_ERROR_PROVIDER_NOT_FOUND;
 
235
        }
212
236
 
213
237
        /* Set credential reference */
214
238
        id_attr = xmlHasProp(credential, (xmlChar *)"AssertionID");
224
248
                if (keys_mngr == NULL) {
225
249
                        return LASSO_DS_ERROR_CA_CERT_CHAIN_LOAD_FAILED;
226
250
                }
227
 
        }
228
 
        else if (x509data != NULL) {
 
251
        } else if (x509data != NULL) {
229
252
                return LASSO_DS_ERROR_CA_CERT_CHAIN_LOAD_FAILED;
230
253
        }
231
254
 
233
256
 
234
257
        /* Case of simple public key signature type */
235
258
        if (keys_mngr == NULL) {
236
 
                if (lasso_provider != NULL)
237
 
                        dsigCtx->signKey = lasso_provider_get_public_key(lasso_provider);
238
 
                else if (profile->private_data->public_key) {
 
259
                if (lasso_provider != NULL) {
 
260
                        dsigCtx->signKey = xmlSecKeyDuplicate(
 
261
                                        lasso_provider_get_public_key(lasso_provider));
 
262
                } else if (profile->private_data->public_key) {
239
263
                        /* TODO */
240
264
                }
241
265
                if (dsigCtx->signKey == NULL) {
245
269
        }
246
270
 
247
271
        node = xmlSecFindNode(credential, xmlSecNodeSignature, xmlSecDSigNs);
248
 
        if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
 
272
        if (xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
249
273
                xmlSecDSigCtxDestroy(dsigCtx);
250
274
                if (keys_mngr)
251
275
                        xmlSecKeysMngrDestroy(keys_mngr);
262
286
 
263
287
        /* Remove uneeded signature node */
264
288
        xmlUnlinkNode(node);
265
 
        xmlFree(node);
 
289
        xmlFreeNode(node);
266
290
 
267
291
        return 0;
268
292
}
269
293
 
270
 
gint
 
294
static gint
271
295
lasso_wsf_profile_add_credential_signature(LassoWsfProfile *profile,
272
 
                                           xmlDoc *doc, xmlNode *credential,
273
 
                                           LassoSignatureMethod sign_method)
 
296
                xmlDoc *doc, xmlNode *credential, LassoSignatureMethod sign_method)
274
297
{
275
 
        xmlNode *signature = NULL, *sign_tmpl, *reference, *key_info, *t;
276
 
        xmlChar *id;
 
298
        xmlNode *signature = NULL, *sign_tmpl, *reference, *key_info;
277
299
        char *uri;
278
300
        
279
301
        xmlAttr *id_attr;
311
333
        /* Sign SOAP message */
312
334
        sign_tmpl = xmlSecFindNode(credential, xmlSecNodeSignature, xmlSecDSigNs);
313
335
        if (sign_tmpl == NULL)
314
 
                return -1;
 
336
                return LASSO_DS_ERROR_SIGNATURE_TEMPLATE_NOT_FOUND;
315
337
 
316
338
        dsigCtx = xmlSecDSigCtxCreate(NULL);
317
339
        dsigCtx->signKey = xmlSecCryptoAppKeyLoad(profile->server->private_key,
318
340
                xmlSecKeyDataFormatPem, NULL, NULL, NULL);
319
341
        if (dsigCtx->signKey == NULL) {
320
342
                xmlSecDSigCtxDestroy(dsigCtx);
321
 
                return -1;
 
343
                return LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED;
322
344
        }
323
345
        if (profile->server->certificate != NULL && profile->server->certificate[0] != 0) {
324
346
                if (xmlSecCryptoAppKeyCertLoad(dsigCtx->signKey, profile->server->certificate,
325
 
                        xmlSecKeyDataFormatPem) < 0) {
326
 
                                xmlSecDSigCtxDestroy(dsigCtx);
327
 
                                return -1;
 
347
                                        xmlSecKeyDataFormatPem) < 0) {
 
348
                        xmlSecDSigCtxDestroy(dsigCtx);
 
349
                        return LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED;
328
350
                }
329
351
        }
330
352
 
331
353
        if (xmlSecDSigCtxSign(dsigCtx, sign_tmpl) < 0) {
332
354
                xmlSecDSigCtxDestroy(dsigCtx);
333
 
                return -1;
 
355
                return LASSO_DS_ERROR_SIGNATURE_FAILED;
334
356
        }
335
357
        xmlSecDSigCtxDestroy(dsigCtx);
336
358
 
337
359
        return 0;
338
360
}
339
361
 
340
 
xmlSecKey*
 
362
static xmlSecKey*
341
363
lasso_wsf_profile_get_public_key_from_credential(LassoWsfProfile *profile, xmlNode *credential)
342
364
{
343
365
        xmlNode *authentication_statement, *subject, *subject_confirmation, *key_info;
347
369
        /* get AuthenticationStatement element */
348
370
        authentication_statement = credential->children;
349
371
        while (authentication_statement) {
350
 
                if (authentication_statement->type == XML_ELEMENT_NODE && \
351
 
                    strcmp(authentication_statement->name, "AuthenticationStatement") == 0)
 
372
                if (authentication_statement->type == XML_ELEMENT_NODE &&
 
373
                                strcmp((char*)authentication_statement->name,
 
374
                                        "AuthenticationStatement") == 0)
352
375
                        break;
353
376
                authentication_statement = authentication_statement->next;
354
377
        }
355
 
        if (!authentication_statement) {
 
378
        if (authentication_statement == NULL) {
356
379
                return NULL;
357
380
        }
358
381
 
359
382
        /* get Subject element */
360
383
        subject = authentication_statement->children;
361
384
        while (subject) {
362
 
                if (subject->type == XML_ELEMENT_NODE && strcmp(subject->name, "Subject") == 0)
 
385
                if (subject->type == XML_ELEMENT_NODE &&
 
386
                                strcmp((char*)subject->name, "Subject") == 0)
363
387
                        break;
364
388
                subject = subject->next;
365
389
        }
366
 
        if (!subject) {
 
390
        if (subject == NULL) {
367
391
                return NULL;
368
392
        }
369
393
 
370
394
        /* get SubjectConfirmation */
371
395
        subject_confirmation = subject->children;
372
396
        while (subject_confirmation) {
373
 
                if (subject_confirmation->type == XML_ELEMENT_NODE && \
374
 
                    strcmp(subject_confirmation->name, "SubjectConfirmation") == 0)
 
397
                if (subject_confirmation->type == XML_ELEMENT_NODE &&
 
398
                    strcmp((char*)subject_confirmation->name, "SubjectConfirmation") == 0)
375
399
                        break;
376
400
                subject_confirmation = subject_confirmation->next;
377
401
        }
378
 
        if (!subject_confirmation) {
 
402
        if (subject_confirmation == NULL) {
379
403
                return NULL;
380
404
        }
381
405
 
382
406
        /* get KeyInfo */
383
407
        key_info = subject_confirmation->children;
384
408
        while (key_info) {
385
 
                if (key_info->type == XML_ELEMENT_NODE && strcmp(key_info->name, "KeyInfo") == 0)
 
409
                if (key_info->type == XML_ELEMENT_NODE &&
 
410
                                strcmp((char*)key_info->name, "KeyInfo") == 0)
386
411
                        break;
387
412
                key_info = key_info->next;
388
413
        }
402
427
 
403
428
        {
404
429
                xmlDoc *doc;
405
 
                char *modulus_value, *exponent_value;
 
430
                xmlChar *modulus_value, *exponent_value;
406
431
                xmlNode *rsa_key_value, *xmlnode, *modulus, *exponent;
407
432
 
408
433
                xmlnode = key_info->children;
409
434
                while (xmlnode) {
410
 
                        if (strcmp(xmlnode->name, "KeyValue") == 0) {
 
435
                        if (strcmp((char*)xmlnode->name, "KeyValue") == 0) {
411
436
                                break;
412
437
                        }
413
438
                        xmlnode = xmlnode->next;
414
439
                }
415
440
                rsa_key_value = xmlnode->children;
416
441
                while (rsa_key_value) {
417
 
                        if (strcmp(rsa_key_value->name, "RsaKeyValue") == 0) {
 
442
                        if (strcmp((char*)rsa_key_value->name, "RsaKeyValue") == 0) {
418
443
                                break;
419
444
                        }
420
445
                        rsa_key_value = rsa_key_value->next;
421
446
                }
422
447
                xmlnode = rsa_key_value->children;
423
448
                while (xmlnode) {
424
 
                        if (strcmp(xmlnode->name, "Modulus") == 0)
 
449
                        if (strcmp((char*)xmlnode->name, "Modulus") == 0) {
425
450
                                modulus_value = xmlNodeGetContent(xmlnode);
426
 
                        else if (strcmp(xmlnode->name, "Exponent") == 0)
 
451
                        } else if (strcmp((char*)xmlnode->name, "Exponent") == 0) {
427
452
                                exponent_value = xmlNodeGetContent(xmlnode);
 
453
                        }
428
454
                        xmlnode = xmlnode->next;
429
455
                }
430
456
                
431
 
                doc = xmlSecCreateTree("KeyInfo", "http://www.w3.org/2000/09/xmldsig#");
 
457
                doc = xmlSecCreateTree((xmlChar*)"KeyInfo",
 
458
                                (xmlChar*)"http://www.w3.org/2000/09/xmldsig#");
432
459
                key_info = xmlDocGetRootElement(doc);
433
460
 
434
 
                xmlnode = xmlSecAddChild(key_info,
435
 
                                         "KeyValue", "http://www.w3.org/2000/09/xmldsig#");
436
 
                xmlnode = xmlSecAddChild(xmlnode,
437
 
                                         "RSAKeyValue", "http://www.w3.org/2000/09/xmldsig#");
438
 
                modulus = xmlSecAddChild(xmlnode,
439
 
                                         "Modulus", "http://www.w3.org/2000/09/xmldsig#");
 
461
                xmlnode = xmlSecAddChild(key_info, (xmlChar*)"KeyValue",
 
462
                                (xmlChar*)"http://www.w3.org/2000/09/xmldsig#");
 
463
                xmlnode = xmlSecAddChild(xmlnode, (xmlChar*)"RSAKeyValue",
 
464
                                (xmlChar*)"http://www.w3.org/2000/09/xmldsig#");
 
465
                modulus = xmlSecAddChild(xmlnode, (xmlChar*)"Modulus",
 
466
                                (xmlChar*)"http://www.w3.org/2000/09/xmldsig#");
440
467
                xmlNodeSetContent(modulus, modulus_value);
441
468
                
442
 
                exponent = xmlSecAddChild(xmlnode,
443
 
                                          "Exponent", "http://www.w3.org/2000/09/xmldsig#");
 
469
                exponent = xmlSecAddChild(xmlnode, (xmlChar*)"Exponent",
 
470
                                (xmlChar*)"http://www.w3.org/2000/09/xmldsig#");
444
471
                xmlNodeSetContent(exponent, exponent_value);
445
472
        }
446
473
        
447
474
        xmlSecKeyInfoNodeRead(key_info, public_key, ctx);
448
 
        /*xmlSecKeyDebugXmlDump(public_key, stdout);*/
449
475
 
450
476
        return public_key;
451
477
}
452
478
 
453
 
gint
 
479
static gint
454
480
lasso_wsf_profile_verify_saml_authentication(LassoWsfProfile *profile, xmlDoc *doc)
455
481
{
456
482
        xmlXPathContext *xpathCtx = NULL;
457
483
        xmlXPathObject *xpathObj;
458
484
        xmlNode *credential;
459
485
        xmlSecKey *public_key;
460
 
        int i, res;
 
486
        int res;
461
487
 
462
488
        xpathCtx = xmlXPathNewContext(doc);
463
489
 
467
493
        xpathObj = xmlXPathEvalExpression((xmlChar*)"//wsse:Security/saml:Assertion", xpathCtx);
468
494
 
469
495
        /* FIXME: Need to consider more every credentials. */
470
 
        if (xpathObj->nodesetval && xpathObj->nodesetval->nodeNr)
471
 
                printf("OK ca a l'air bon ...\n");
472
 
        else
473
 
                return -1;
 
496
        if (xpathObj->nodesetval == NULL || xpathObj->nodesetval->nodeNr == 0) {
 
497
                xmlXPathFreeContext(xpathCtx);
 
498
                xmlXPathFreeObject(xpathObj);
 
499
                return LASSO_PROFILE_ERROR_MISSING_ASSERTION;
 
500
        }
474
501
        
475
502
 
476
503
        credential = xpathObj->nodesetval->nodeTab[0];
 
504
 
477
505
        res = lasso_wsf_profile_verify_credential_signature(profile, doc, credential);
478
 
        if (res < 0) return res;
479
 
        printf("credential signature is ok\n");
 
506
        if (res < 0) {
 
507
                xmlXPathFreeContext(xpathCtx);
 
508
                xmlXPathFreeObject(xpathObj);
 
509
                return res;
 
510
        }
480
511
        
481
512
        public_key = lasso_wsf_profile_get_public_key_from_credential(profile, credential);
 
513
        xmlXPathFreeContext(xpathCtx);
 
514
        xmlXPathFreeObject(xpathObj);
482
515
        
483
 
        if (!public_key)
484
 
                return -1;
485
 
        printf("Xml sec public key found\n");
 
516
        if (public_key == NULL) {
 
517
                return LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED;
 
518
        }
486
519
 
487
520
        res = lasso_wsf_profile_verify_x509_authentication(profile, doc, public_key);
 
521
        xmlSecKeyDestroy(public_key);
488
522
        if (res != 0)
489
523
                return res;
490
 
        printf("soap signature is ok\n");
491
524
 
492
525
        return 0;
493
526
}
494
527
 
495
 
gint
496
 
lasso_wsf_profile_add_soap_signature(LassoWsfProfile *profile, xmlDoc *doc, xmlNode *envelope_node,
497
 
        LassoSignatureMethod sign_method)
 
528
static gint
 
529
lasso_wsf_profile_add_soap_signature(LassoWsfProfile *profile,
 
530
                xmlDoc *doc, xmlNode *envelope_node, LassoSignatureMethod sign_method)
498
531
{
499
532
        xmlNode *signature = NULL, *sign_tmpl, *reference, *key_info, *t;
500
533
        xmlNode *header = NULL, *provider = NULL, *correlation = NULL, *security = NULL;
502
535
        xmlSecDSigCtx *dsigCtx;
503
536
        xmlChar *id;
504
537
        char *uri;
505
 
        
506
538
        xmlAttr *id_attr;
507
539
 
508
 
        LassoSignatureType sign_type = LASSO_SIGNATURE_TYPE_WITHX509;
509
 
 
510
540
        /* Get Correlation, Provider, Security, Body elements */
511
541
        t = envelope_node->children;
512
542
        while (t) {
513
 
                if (strcmp((char *) t->name, "Header") == 0)
 
543
                if (strcmp((char *) t->name, "Header") == 0) {
514
544
                        header = t;
515
 
                else if (strcmp((char *) t->name, "Body") == 0)
 
545
                } else if (strcmp((char *) t->name, "Body") == 0) {
516
546
                        body = t;
 
547
                }
517
548
                t = t->next;
518
549
        }
519
550
        if (header == NULL)
520
 
                return -1;
 
551
                return LASSO_SOAP_ERROR_MISSING_HEADER;
 
552
 
521
553
        if (body == NULL)
522
 
                return -1;
 
554
                return LASSO_SOAP_ERROR_MISSING_BODY;
523
555
 
524
556
        t = header->children;
525
557
        while (t) {
526
 
                if (strcmp((char *) t->name, "Correlation") == 0)
 
558
                if (strcmp((char *) t->name, "Correlation") == 0) {
527
559
                        correlation = t;
528
 
                else if (strcmp((char *) t->name, "Provider") == 0)
 
560
                } else if (strcmp((char *) t->name, "Provider") == 0) {
529
561
                        provider = t;
530
 
                else if (strcmp((char *) t->name, "Security") == 0)
 
562
                } else if (strcmp((char *) t->name, "Security") == 0) {
531
563
                        security = t;
 
564
                }
532
565
                t = t->next;
533
566
        }
534
567
        if (correlation == NULL)
535
 
                return -1;
 
568
                return LASSO_WSF_PROFILE_ERROR_MISSING_CORRELATION;
536
569
        if (security == NULL)
537
 
                return -1;
 
570
                return LASSO_WSF_PROFILE_ERROR_MISSING_SECURITY;
538
571
 
539
572
        /* Add signature template */
540
573
        if (sign_method == LASSO_SIGNATURE_METHOD_RSA_SHA1) {
566
599
        uri = g_strdup_printf("#%s", id);
567
600
        reference = xmlSecTmplSignatureAddReference(signature, xmlSecTransformSha1Id,
568
601
                                                    NULL, (xmlChar *)uri, NULL);
569
 
        xmlFree(uri);
 
602
        g_free(uri);
570
603
        xmlSecTmplReferenceAddTransform(reference, xmlSecTransformEnvelopedId);
571
604
        xmlSecTmplReferenceAddTransform(reference, xmlSecTransformExclC14NId);
572
605
        id_attr = xmlHasProp(body, (xmlChar *)"id");
591
624
        }
592
625
 
593
626
        /* Sign SOAP message */
594
 
        /*sign_tmpl = xmlSecFindNode(security, xmlSecNodeSignature, xmlSecDSigNs);
595
 
        if (sign_tmpl == NULL)
596
 
        return -1;*/
597
627
        sign_tmpl = signature;
598
628
 
599
629
        dsigCtx = xmlSecDSigCtxCreate(NULL);
601
631
                xmlSecKeyDataFormatPem, NULL, NULL, NULL);
602
632
        if (dsigCtx->signKey == NULL) {
603
633
                xmlSecDSigCtxDestroy(dsigCtx);
604
 
                return -1;
 
634
                return LASSO_DS_ERROR_PRIVATE_KEY_LOAD_FAILED;
605
635
        }
606
636
        if (profile->server->certificate != NULL && profile->server->certificate[0] != 0) {
607
637
                if (xmlSecCryptoAppKeyCertLoad(dsigCtx->signKey, profile->server->certificate,
608
 
                        xmlSecKeyDataFormatPem) < 0) {
609
 
                                xmlSecDSigCtxDestroy(dsigCtx);
610
 
                                return -1;
 
638
                                        xmlSecKeyDataFormatPem) < 0) {
 
639
                        xmlSecDSigCtxDestroy(dsigCtx);
 
640
                        return LASSO_DS_ERROR_CERTIFICATE_LOAD_FAILED;
611
641
                }
612
642
        }
613
643
        if (xmlSecDSigCtxSign(dsigCtx, sign_tmpl) < 0) {
614
644
                xmlSecDSigCtxDestroy(dsigCtx);
615
 
                return -1;
 
645
                return LASSO_DS_ERROR_SIGNATURE_FAILED;
616
646
        }
617
647
        xmlSecDSigCtxDestroy(dsigCtx);
618
648
 
625
655
{
626
656
        LassoProvider *lasso_provider = NULL;
627
657
 
628
 
        xmlNode *provider = NULL, *correlation = NULL, *security = NULL, *body = NULL;
629
 
        xmlNode *signature = NULL, *x509data = NULL, *node;
 
658
        xmlNode *provider = NULL, *correlation = NULL, *body = NULL;
 
659
        xmlNode *x509data = NULL, *node;
630
660
        xmlChar *id;
631
661
        xmlAttr *id_attr;
632
662
 
644
674
        if (xpathObj->nodesetval && xpathObj->nodesetval->nodeNr) {
645
675
                correlation = xpathObj->nodesetval->nodeTab[0];
646
676
        }
647
 
        if (!correlation)
648
 
                return -1;
 
677
        if (correlation == NULL) {
 
678
                xmlXPathFreeObject(xpathObj);
 
679
                xmlXPathFreeContext(xpathCtx);
 
680
                return LASSO_WSF_PROFILE_ERROR_MISSING_CORRELATION;
 
681
        }
 
682
 
649
683
        id_attr = xmlHasProp(correlation, (xmlChar *)"id");
650
684
        id = xmlGetProp(correlation, (xmlChar *) "id");
651
685
        xmlAddID(NULL, doc, id, id_attr);
652
686
        xmlFree(id);
653
687
 
 
688
        xmlXPathFreeObject(xpathObj);
 
689
        xpathObj = NULL;
 
690
 
654
691
        /* Body */
655
692
        xmlXPathRegisterNs(xpathCtx, (xmlChar*)"s", (xmlChar*)LASSO_SOAP_ENV_HREF);
656
693
        xpathObj = xmlXPathEvalExpression((xmlChar*)"//s:Body", xpathCtx);
657
694
        if (xpathObj->nodesetval && xpathObj->nodesetval->nodeNr) {
658
695
                body = xpathObj->nodesetval->nodeTab[0];
659
696
        }
660
 
        if (!body)
661
 
                return -1;
 
697
        if (body == NULL) {
 
698
                xmlXPathFreeObject(xpathObj);
 
699
                xmlXPathFreeContext(xpathCtx);
 
700
                return LASSO_SOAP_ERROR_MISSING_BODY;
 
701
        }
 
702
 
662
703
        id_attr = xmlHasProp(body, (xmlChar *)"id");
663
704
        id = xmlGetProp(body, (xmlChar *) "id");
664
705
        xmlAddID(NULL, doc, id, id_attr);
665
706
        xmlFree(id);
666
707
 
 
708
        xmlXPathFreeObject(xpathObj);
 
709
        xpathObj = NULL;
 
710
 
667
711
        /* Provider */
668
712
        xmlXPathRegisterNs(xpathCtx, (xmlChar*)"sb", (xmlChar*)LASSO_SOAP_BINDING_HREF);
669
713
        xpathObj = xmlXPathEvalExpression((xmlChar*)"//sb:Provider", xpathCtx);
682
726
                xmlFree(providerID);
683
727
        }
684
728
 
 
729
        xmlXPathFreeObject(xpathObj);
 
730
        xpathObj = NULL;
 
731
 
685
732
        /* Verify signature */
686
 
        //node = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeSignature, xmlSecDSigNs);
687
 
 
688
 
        //xpathObj =xmlXPathEvalExpression((xmlChar*)"/s:Envelope/s:Header/s:Security/ds:Signature",
689
 
        //                                xpathCtx);
690
733
        node = NULL;
691
734
        xmlXPathRegisterNs(xpathCtx, (xmlChar*)"ds", (xmlChar*)LASSO_DS_HREF);
692
735
        xpathObj = xmlXPathEvalExpression((xmlChar*)"//ds:Signature", xpathCtx);
693
736
        if (xpathObj->nodesetval && xpathObj->nodesetval->nodeNr) {
694
737
                node = xpathObj->nodesetval->nodeTab[0];
695
738
        }
696
 
        if(node == NULL)
 
739
        if (node == NULL) {
 
740
                xmlXPathFreeContext(xpathCtx);
 
741
                xmlXPathFreeObject(xpathObj);
697
742
                return LASSO_DS_ERROR_SIGNATURE_NOT_FOUND;
 
743
        }
698
744
 
699
745
        /* Case of X509 signature type */
700
746
        x509data = xmlSecFindNode(xmlDocGetRootElement(doc), xmlSecNodeX509Data, xmlSecDSigNs);
702
748
                keys_mngr = lasso_load_certs_from_pem_certs_chain_file(
703
749
                                lasso_provider->ca_cert_chain);
704
750
                if (keys_mngr == NULL) {
 
751
                        xmlXPathFreeObject(xpathObj);
 
752
                        xmlXPathFreeContext(xpathCtx);
705
753
                        return LASSO_DS_ERROR_CA_CERT_CHAIN_LOAD_FAILED;
706
754
                }
707
 
        }
708
 
        else if (x509data != NULL) {
 
755
        } else if (x509data != NULL) {
 
756
                xmlXPathFreeObject(xpathObj);
 
757
                xmlXPathFreeContext(xpathCtx);
709
758
                return LASSO_DS_ERROR_CA_CERT_CHAIN_LOAD_FAILED;
710
759
        }
711
760
 
714
763
        /* Case of simple public key signature type */
715
764
        if (keys_mngr == NULL) {
716
765
                if (lasso_provider != NULL) {
717
 
                        dsigCtx->signKey = lasso_provider_get_public_key(lasso_provider);
718
 
                }
719
 
                else if (public_key) {
720
 
                        dsigCtx->signKey = public_key;
 
766
                        dsigCtx->signKey = xmlSecKeyDuplicate(
 
767
                                        lasso_provider_get_public_key(lasso_provider));
 
768
                } else if (public_key) {
 
769
                        dsigCtx->signKey = xmlSecKeyDuplicate(public_key);
721
770
                }
722
771
                if (dsigCtx->signKey == NULL) {
723
772
                        xmlSecDSigCtxDestroy(dsigCtx);
 
773
                        xmlXPathFreeObject(xpathObj);
 
774
                        xmlXPathFreeContext(xpathCtx);
724
775
                        return LASSO_DS_ERROR_PUBLIC_KEY_LOAD_FAILED;
725
776
                }
726
777
        }
727
778
 
728
 
        if(xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
 
779
        if (xmlSecDSigCtxVerify(dsigCtx, node) < 0) {
729
780
                xmlSecDSigCtxDestroy(dsigCtx);
730
781
                if (keys_mngr)
731
782
                        xmlSecKeysMngrDestroy(keys_mngr);
 
783
                xmlXPathFreeObject(xpathObj);
 
784
                xmlXPathFreeContext(xpathCtx);
732
785
                return LASSO_DS_ERROR_SIGNATURE_VERIFICATION_FAILED;
733
786
        }
734
787
 
 
788
        xmlXPathFreeObject(xpathObj);
 
789
        xmlXPathFreeContext(xpathCtx);
 
790
 
735
791
        if (keys_mngr)
736
792
                xmlSecKeysMngrDestroy(keys_mngr);
737
793
 
739
795
                xmlSecDSigCtxDestroy(dsigCtx);
740
796
                return LASSO_DS_ERROR_INVALID_SIGNATURE;
741
797
        }
742
 
        printf("ok\n");
743
798
 
744
799
        return 0;
745
800
}
1018
1073
        LassoSoapHeader *header;
1019
1074
        LassoWsseSecurity *security = NULL;
1020
1075
        int ret;
1021
 
 
1022
 
        GList *iter;
1023
 
 
 
1076
        GList *iter = NULL;
1024
1077
        xmlNode *security_xmlNode, *credential;
1025
 
 
1026
1078
        xmlOutputBuffer *buf;
1027
1079
        xmlCharEncodingHandler *handler;
1028
 
 
1029
 
        xmlDoc *doc;
 
1080
        xmlDoc *doc = NULL;
1030
1081
        xmlNode *envelope_node = NULL;
 
1082
        xmlXPathContext *xpathCtx = NULL;
 
1083
        xmlXPathObject *xpathObj = NULL;
 
1084
                        
1031
1085
 
1032
1086
        g_return_val_if_fail(LASSO_IS_WSF_PROFILE(profile),
1033
1087
                             LASSO_PARAM_ERROR_BAD_TYPE_OR_NULL_OBJ);
1035
1089
        envelope = profile->soap_envelope_request;
1036
1090
 
1037
1091
        /* FIXME: find a better way to add needed security element */
1038
 
        if (lasso_wsf_profile_has_saml_authentication(profile) == TRUE ||\
1039
 
            lasso_wsf_profile_has_x509_authentication(profile) == TRUE) {
 
1092
        if (lasso_wsf_profile_has_saml_authentication(profile) == TRUE ||
 
1093
                        lasso_wsf_profile_has_x509_authentication(profile) == TRUE) {
1040
1094
                security = lasso_wsse_security_new();
1041
1095
                header = envelope->Header;
1042
1096
                header->Other = g_list_append(header->Other, security);
1049
1103
 
1050
1104
        if (lasso_wsf_profile_has_saml_authentication(profile) == TRUE) {
1051
1105
                if (profile->private_data->credentials) {
1052
 
                        printf("Y a du credential dans l'air ...\n");
1053
 
                        xmlXPathContext *xpathCtx = NULL;
1054
 
                        xmlXPathObject *xpathObj;
1055
 
                        
1056
1106
                        xpathCtx = xmlXPathNewContext(doc);
1057
1107
                        
1058
1108
                        xmlXPathRegisterNs(xpathCtx, (xmlChar*)"wsse", (xmlChar*)LASSO_WSSE_HREF);
1064
1114
                                
1065
1115
                                /* FIXME: not sure it's the proper way to avoid ns error */
1066
1116
                                xmlNewNs(envelope_node,
1067
 
                                 LASSO_SAML_ASSERTION_HREF, LASSO_SAML_ASSERTION_PREFIX);
 
1117
                                                (xmlChar*)LASSO_SAML_ASSERTION_HREF,
 
1118
                                                (xmlChar*)LASSO_SAML_ASSERTION_PREFIX);
1068
1119
                                xmlNewNs(envelope_node,
1069
 
                                         LASSO_DS_HREF, LASSO_DS_PREFIX);
 
1120
                                                (xmlChar*)LASSO_DS_HREF,
 
1121
                                                (xmlChar*)LASSO_DS_PREFIX);
1070
1122
                                
1071
1123
                                while (iter) {
1072
1124
                                        credential = (xmlNode *) iter->data;
1077
1129
                                   credential list */
1078
1130
                                g_list_free(profile->private_data->credentials);
1079
1131
                        }
 
1132
 
 
1133
                        xmlXPathFreeContext(xpathCtx);
 
1134
                        xmlXPathFreeObject(xpathObj);
 
1135
                        xpathCtx = NULL;
 
1136
                        xpathObj = NULL;
1080
1137
                }
1081
1138
 
1082
1139
                /* FIXME: do we need to sign if SAML authentication or X509 authentication ? */
1083
1140
                ret = lasso_wsf_profile_add_soap_signature(profile, doc, envelope_node,
1084
1141
                                                           LASSO_SIGNATURE_METHOD_RSA_SHA1);
1085
 
                if (ret != 0)
 
1142
                if (ret != 0) {
 
1143
                        xmlFreeDoc(doc);
1086
1144
                        return ret;
 
1145
                }
1087
1146
        }
1088
1147
 
1089
1148
        if (lasso_wsf_profile_has_x509_authentication(profile) == TRUE) {
1090
1149
                ret = lasso_wsf_profile_add_soap_signature(profile, doc, envelope_node,
1091
1150
                                                           LASSO_SIGNATURE_METHOD_RSA_SHA1);
1092
 
                if (ret != 0)
 
1151
                if (ret != 0) {
 
1152
                        xmlFreeDoc(doc);
1093
1153
                        return ret;
 
1154
                }
1094
1155
        }
1095
1156
 
1096
1157
        /* Dump soap request */
1101
1162
        profile->msg_body = g_strdup(
1102
1163
                (char*)(buf->conv ? buf->conv->content : buf->buffer->content));
1103
1164
        xmlOutputBufferClose(buf);
 
1165
        xmlFreeDoc(doc);
1104
1166
 
1105
1167
        return 0;
1106
1168
}
1107
1169
 
1108
 
int
 
1170
static int
1109
1171
lasso_wsf_profile_ensure_soap_credentials_signature(LassoWsfProfile *profile,
1110
 
                                                    xmlDoc *doc,
1111
 
                                                    xmlNode *soap_envelope)
 
1172
                xmlDoc *doc, xmlNode *soap_envelope)
1112
1173
{
 
1174
        xmlXPathContext *xpathCtx = NULL;
 
1175
        xmlXPathObject *xpathObj;
1113
1176
        int i;
1114
 
        xmlNode *credential;
1115
 
        GList *iter;
1116
 
        
1117
 
        xmlXPathContext *xpathCtx = NULL;
1118
 
        xmlXPathObject *xpathObj;
1119
1177
 
1120
1178
        xpathCtx = xmlXPathNewContext(doc);
1121
1179
 
1131
1189
                }
1132
1190
        }
1133
1191
 
 
1192
        xmlXPathFreeContext(xpathCtx);
 
1193
        xmlXPathFreeObject(xpathObj);
 
1194
 
1134
1195
        return 0;
1135
1196
}
1136
1197
 
1141
1202
        LassoSoapHeader *header;
1142
1203
        LassoWsseSecurity *security;
1143
1204
 
1144
 
        xmlNode *soap_envelope, *credential;
1145
 
        gchar *credentialRef;
1146
 
        GList *iter;
 
1205
        xmlNode *soap_envelope;
1147
1206
 
1148
1207
        xmlDoc *doc;
1149
1208
 
1154
1213
 
1155
1214
        /* FIXME: find a better way to add needed security element */
1156
1215
        envelope = profile->soap_envelope_response;
1157
 
        if (lasso_wsf_profile_has_saml_authentication(profile) == TRUE ||\
1158
 
            lasso_wsf_profile_has_x509_authentication(profile) == TRUE) {
 
1216
        if (lasso_wsf_profile_has_saml_authentication(profile) == TRUE ||
 
1217
                        lasso_wsf_profile_has_x509_authentication(profile) == TRUE) {
1159
1218
                security = lasso_wsse_security_new();
1160
1219
                header = envelope->Header;
1161
1220
                header->Other = g_list_append(header->Other, security);
1163
1222
 
1164
1223
        /* Apply wsf authentication */
1165
1224
        doc = xmlNewDoc((xmlChar*)"1.0");
1166
 
        soap_envelope = lasso_node_get_xmlNode(envelope, TRUE);
 
1225
        soap_envelope = lasso_node_get_xmlNode(LASSO_NODE(envelope), TRUE);
1167
1226
        xmlDocSetRootElement(doc, soap_envelope);
1168
1227
 
1169
1228
        /* SAML authentication, if credentials in response, verify they are signed */
1173
1232
        if (lasso_wsf_profile_has_x509_authentication(profile) == TRUE) {
1174
1233
                int res = lasso_wsf_profile_add_soap_signature(profile, doc, soap_envelope,
1175
1234
                                                               LASSO_SIGNATURE_METHOD_RSA_SHA1);
1176
 
                if (res != 0)
 
1235
                if (res != 0) {
 
1236
                        xmlFreeDoc(doc);
1177
1237
                        return res;
 
1238
                }
1178
1239
        }
1179
1240
 
1180
1241
        /* Dump soap response */
1185
1246
        profile->msg_body = g_strdup(
1186
1247
                (char*)(buf->conv ? buf->conv->content : buf->buffer->content));
1187
1248
        xmlOutputBufferClose(buf);
1188
 
        xmlFreeNode(soap_envelope);
 
1249
        xmlFreeDoc(doc);
1189
1250
 
1190
1251
        return 0;
1191
1252
}
1198
1259
        LassoSoapBindingCorrelation *correlation;
1199
1260
        LassoSoapEnvelope *envelope = NULL;
1200
1261
        LassoSoapFault *fault = NULL;
1201
 
        GList *iter;
1202
1262
        gchar *messageId;
1203
1263
        int res = 0;
1204
1264
        xmlDoc *doc;
1208
1268
 
1209
1269
        si = lasso_server_get_service(profile->server, (char *) service_type);
1210
1270
 
1211
 
        if (!security_mech_id) {
1212
 
                if (si)
 
1271
        if (security_mech_id == NULL) {
 
1272
                if (si) {
1213
1273
                        profile->private_data->description = LASSO_DISCO_DESCRIPTION(
1214
1274
                                si->Description->data);
1215
 
                else
 
1275
                } else {
1216
1276
                        profile->private_data->description = NULL;
1217
 
        } else
1218
 
                if (!si)
1219
 
                        return -1;
1220
 
                else
 
1277
                }
 
1278
        } else {
 
1279
                if (si == NULL) {
 
1280
                        return LASSO_PROFILE_ERROR_MISSING_SERVICE_INSTANCE;
 
1281
                } else {
1221
1282
                        lasso_wsf_profile_get_description_auto(si, security_mech_id);   
 
1283
                }
 
1284
        }
1222
1285
 
1223
1286
        doc = xmlParseMemory(message, strlen(message));
1224
1287
 
1225
1288
        /* Verify authentication mecanisms */
1226
1289
        if (lasso_wsf_profile_has_x509_authentication(profile) == TRUE) {
1227
1290
                res = lasso_wsf_profile_verify_x509_authentication(profile, doc, NULL);
1228
 
        }
1229
 
        else if (lasso_wsf_profile_has_saml_authentication(profile) == TRUE) {
 
1291
        } else if (lasso_wsf_profile_has_saml_authentication(profile) == TRUE) {
1230
1292
                res = lasso_wsf_profile_verify_saml_authentication(profile, doc);
1231
1293
        }
1232
1294
 
1233
1295
        /* FIXME: Return a soap fault if authentication verification failed ? */
1234
1296
        if (res > 0) {
1235
1297
                fault = lasso_soap_fault_new();
1236
 
                fault->faultstring = "Invalid signature";
 
1298
                fault->faultstring = g_strdup("Invalid signature");
 
1299
        } else if (res < 0) {
 
1300
                xmlFreeDoc(doc);
 
1301
                return res;
1237
1302
        }
1238
 
        else if (res < 0)
1239
 
                return res;
1240
1303
 
1241
1304
        /* FIXME: Remove Signature element if exists, it seg fault when a call to
1242
1305
                          lasso_node_new_from_xmlNode() */
1269
1332
                profile->private_data->fault = fault;
1270
1333
        }
1271
1334
 
 
1335
        xmlFreeDoc(doc);
 
1336
 
1272
1337
        return res;
1273
1338
}
1274
1339
 
1294
1359
                int res;
1295
1360
 
1296
1361
                res = lasso_wsf_profile_verify_x509_authentication(profile, doc, NULL);
1297
 
                if (res != 0)
 
1362
                if (res != 0) {
 
1363
                        xmlFreeDoc(doc);
1298
1364
                        return res;
 
1365
                }
1299
1366
 
1300
1367
                /* FIXME: Remove Signature element if exists, it seg fault when a call to
1301
1368
                   lasso_node_new_from_xmlNode() */
1306
1373
                        xmlFreeNode(xmlnode);
1307
1374
                }
1308
1375
        }
1309
 
        if (res != 0)
 
1376
 
 
1377
        if (res != 0) {
 
1378
                xmlFreeDoc(doc);
1310
1379
                return res;
 
1380
        }
1311
1381
 
1312
1382
        /* If credentials are found, save and remove them from message */
1313
1383
        {
1323
1393
                                lasso_wsf_profile_add_credential(profile, credential);
1324
1394
                        }
1325
1395
                }
 
1396
                xmlXPathFreeContext(xpathCtx);
 
1397
                xmlXPathFreeObject(xpathObj);
1326
1398
        }
1327
1399
        
1328
1400
        envelope = LASSO_SOAP_ENVELOPE(lasso_node_new_from_xmlNode(xmlDocGetRootElement(doc)));
 
1401
        xmlFreeDoc(doc);
1329
1402
 
1330
1403
        profile->soap_envelope_response = envelope;
1331
1404