1 /*
2  * Portions of this file Copyright 1999-2005 University of Chicago
3  * Portions of this file Copyright 1999-2005 The University of Southern California.
4  *
5  * This file or a portion of this file is licensed under the
6  * terms of the Globus Toolkit Public License, found at
7  * http://www.globus.org/toolkit/download/license.html.
8  * If you redistribute this file, with or without
9  * modifications, you must include this notice in the file.
10  */
11
12
13 #include "globus_i_handler_wsse_cred.h"
14 #include "globus_extension.h"
15 #include "globus_common.h"
16 #include "globus_handler.h"
17 #include "globus_soap_message.h"
18 #include "globus_soap_message_handle.h"
19 #include "globus_soap_message_markers.h"
20 #include "globus_xml_buffer.h"
21 #include "globus_wsrf_core_tools.h"
22 #include "libxml/tree.h"
23 #include "xsd_any.h"
24 #include "wsse_BinarySecurityTokenType.h"
25 #include "wsseu_TimestampType.h"
26 #include "ds_SignedInfoType.h"
27 #include "ds_SignatureValueType.h"
28 #include "ds_SignatureType.h"
29 #include "ds_CanonicalizationMethodType.h"
30 #include "ds_SignatureMethodType.h"
31 #include "ds_ReferenceType.h"
32 #include "ds_TransformType.h"
33 #include "ds_KeyInfoType.h"
34 #include "wsse_SecurityTokenReferenceType.h"
35 #include "wsse_ReferenceType.h"
36 #include "globus_gsi_credential.h"
37 #include "globus_gsi_system_config.h"
38 #include "globus_ws_security.h"
39 #include "openssl/evp.h"
40 #include "openssl/err.h"
41 #include "libxml/c14n.h"
42 #include "globus_ws_addressing.h"
43
44 #include "wsa_MessageID.h"
45 #include "wsa_RelatesTo.h"
46 #include "wsa_ReplyTo.h"
47 #include "wsa_From.h"
48 #include "wsa_FaultTo.h"
49 #include "wsa_To.h"
50 #include "wsa_Action.h"
51
52 #include "wsse_SecurityHeaderType.h"
53 #include "wsse_BinarySecurityTokenType.h"
54 #include "ds_SignatureType.h"
55 #include "wsseu_TimestampType.h"
56
57 #include "wsse_Security.h"
58 #include "wsse_BinarySecurityToken.h"
59 #include "ds_Signature.h"
60 #include "ds_SignedInfo.h"
61 #include "ds_SignatureValue.h"
62 #include "wsse_SecurityTokenReference.h"
63 #include "ds_Reference.h"
64 #include "ds_KeyInfo.h"
65 #include "wsseu_Timestamp.h"
66 #include "wsse_Reference.h"
67
68 #include "version.h"
69
70 #include "exc_c14n_InclusiveNamespaces.h"
71 #include "exc_c14n_InclusiveNamespacesType.h"
72
73 #define SIGNED_INFO_MARKER "SIGNED_INFO_MARKER"
74 #define SIGNED_INFO_MARKER_END "SIGNED_INFO_MARKER_END"
75
76 #define SIGNATURE_CONTENTS_MARKER     "SIGNATURE_CONTENTS"
77 #define SIGNATURE_CONTENTS_END_MARKER "SIGNATURE_CONTENTS_END"
78
79 #define SECURITY_HEADER_ELEMENT_KEY "SECURITY_HEADER_ELEMENT_KEY"
80 #define WSSE_DONE_WITH_BODY_KEY "SECURITY_HEADER_DONE_WITH_BODY_KEY"
81
82 #define XMLSCHEMA_NS "http://www.w3.org/2001/XMLSchema"
83
84 #define SOAP_ENV_NS "http://schemas.xmlsoap.org/soap/envelope/"
85
86 #define WSSE_NS "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
87
88 #define BASE64BINARY_ENCODING_NS "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
89
90 #define X509_TOKEN_NS "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1"
91
92 #define WSSEU_NS "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
93
94 #define DS_NS "http://www.w3.org/2000/09/xmldsig#"
95
96 #define EXC_C14N_NS "http://www.w3.org/2001/10/xml-exc-c14n#"
97
98 #define RSA_SHA1_NS DS_NS "rsa-sha1"
99
100 #define SHA1_NS DS_NS "sha1"
101
102 #define GLOBUS_HANDLER_WSSE_TOKEN_IDS_KEY \
103         "GLOBUS_SOAP_MESSAGE_WSSE_TOKEN_IDS"
104
105 #define GLOBUS_L_HANDLER_WSSE_REFERENCE_PROPS_KEY \
106         "GLOBUS_L_HANDLER_WSSE_REFERENCE_PROPS_KEY"
107
108 #define WS_SECMESS_INIT_ALREADY_INVOKED \
109        "WS_SECMESS_INIT_ALREADY_INVOKED"
110
111 #define WS_SECMESS_CLIENT_REQUEST_ALREADY_INVOKED \
112        "WS_SECMESS_CLIENT_REQUEST_ALREADY_INVOKED"
113
114 #define WS_SECMESS_CLIENT_RESPONSE_ALREADY_INVOKED \
115        "WS_SECMESS_CLIENT_RESPONSE_ALREADY_INVOKED"
116
117 #define WS_SECMESS_SERVER_REQUEST_ALREADY_INVOKED \
118        "WS_SECMESS_SERVER_REQUEST_ALREADY_INVOKED"
119
120 #define WS_SECMESS_SERVER_RESPONSE_ALREADY_INVOKED \
121        "WS_SECMESS_SERVER_RESPONSE_ALREADY_INVOKED"
122
123 int
124 globus_l_handler_ws_security_activate(void);
125
126 int
127 globus_l_handler_ws_security_deactivate(void);
128
129 GlobusExtensionDeclareModule(globus_handler_ws_security);
130
131 0 GlobusDebugDefine(GLOBUS_HANDLER_WS_SECURE_MESSAGE);
132
133 extern globus_module_descriptor_t       globus_extension_module;
134
135 static xsd_QName                        mustUnderstand_attr_qname =
136 {
137     SOAP_ENV_NS,
138     "mustUnderstand"
139 };
140
141 static xsd_QName                        wsseu_Id_qname =
142 {
143     WSSEU_NS,
144     "Id"
145 };
146
147 #define CERT_ID_PREFIX "CertId-"
148 #define GlobusHandlerWSSENewCertId() \
149         globus_soap_message_construct_id(CERT_ID_PREFIX)
150
151 #define KEY_ID_PREFIX "KeyId-"
152 #define GlobusHandlerWSSENewKeyId() \
153         globus_soap_message_construct_id(KEY_ID_PREFIX)
154
155 #define STR_ID_PREFIX "STRId-"
156 #define GlobusHandlerWSSENewSTRId() \
157         globus_soap_message_construct_id(STR_ID_PREFIX)
158
159 #define ID_PREFIX "id-"
160 #define GlobusHandlerWSSENewId() \
161         globus_soap_message_construct_id(ID_PREFIX)
162
163 #include "globus_i_handler_wsse_cred.h"
164
165 typedef struct
166 {
167    globus_xml_buffer *                  xml_buffer;
168    char *                               id;
169 } globus_l_handler_wsse_id_refprop_t;
170
171 static
172 globus_result_t
173 globus_l_handler_wsse_id_refprops_copy(
174     void **                             newprop,
175     void *                              prop);
176
177 static
178 void
179 globus_l_handler_wsse_id_refprops_destroy(
180     void *                              prop);
181
182 static
183 globus_result_t
184 globus_l_handler_wsse_id_refprop_copy(
185     void **                             newprop,
186     void *                              prop);
187
188 static
189 void
190 globus_l_handler_wsse_id_refprop_destroy(
191     void *                              prop);
192
193 static
194 globus_result_t
195 globus_l_handler_ws_security_c14n_signed_info(
196     globus_soap_message_handle_t        message_handle,
197     const char *                        input_buff,
198     size_t                              input_length,
199     char **                             output_buff,
200     size_t *                            output_buff_length,
201     xsd_string_array *                  prefixes);
202
203 #ifndef GLOBUS_HANDLER_WSSE_INLINED_C14N
204 static
205 globus_result_t
206 globus_i_handler_ws_security_c14n_buffer(
207     const char *                        input_buff,
208     size_t                              input_length,
209     char **                             output_buff,
210     size_t *                            output_buff_length);
211 #endif
212
213 static
214 globus_result_t
215 globus_l_handler_wsse_search_tree(
216     xmlDocPtr                           doc,
217     xsd_QName *                         element,
218     xmlNodePtr *                        node);
219
220 static
221 globus_result_t
222 globus_l_handler_wsse_lookup_prefix(
223     xmlDocPtr                           doc,
224     xmlNodePtr                          node,
225     const xmlChar *                     prefix,
226     const xmlChar **                    href);
227
228 static
229 globus_result_t
230 globus_l_handler_wsse_get_referenced_node(
231     const char *                        id,
232     xmlDocPtr                           doc,
233     xmlNodePtr *                        reference_node);
234
235 static
236 globus_result_t
237 globus_i_handler_ws_security_compute_signature(
238     globus_gsi_cred_handle_t            cred,
239     const char *                        input_buff,
240     size_t                              input_length,
241     char **                             signed_buff,
242     size_t *                            signed_buff_length);
243
244 static
245 globus_result_t
246 globus_i_handler_ws_security_verify_signature(
247     globus_gsi_cred_handle_t            cred,
248     const unsigned char *               input_buff,
249     size_t                              input_length,
250     const unsigned char *               signed_buff,
251     size_t                              signed_buff_length);
252
253 static
254 globus_result_t
255 globus_i_handler_ws_security_compute_digest(
256     const char *                        buff,
257     size_t                              buff_length,
258     char **                             digest_value,
259     size_t *                            digest_length);
260
261 static
262 globus_result_t
263 globus_i_handler_ws_security_verify_digest(
264     const char *                        buff,
265     size_t                              buff_length,
266     const char *                        digest_value,
267     size_t                              digest_length);
268
269 static
270 globus_result_t
271 globus_i_handler_ws_security_add_references(
272     globus_soap_message_handle_t        message_handle,
273     ds_ReferenceType_array *            reference_array);
274
275 static
276 globus_result_t
277 globus_i_handler_ws_security_verify_references(
278     globus_soap_message_handle_t        message_handle,
279     ds_ReferenceType_array *            reference_array);
280
281 static
282 globus_bool_t
283 globus_l_ws_security_is_reference_property_element(
284     const xsd_QName *                   type);
285
286 static
287 globus_result_t
288 globus_handler_ws_security_sign_message(
289     globus_soap_message_handle_t        message_handle)
290 {
291 0     wsse_BinarySecurityTokenType        bst;
292 0     wsseu_TimestampType                 Timestamp;
293 0     ds_SignedInfoType                   SignedInfo;
294 0     ds_SignatureValueType               SignatureValue;
295 0     ds_KeyInfoType                      KeyInfo;
296 0     char *                              key_info_id = NULL;
297 0     char *                              key_info_id_end = NULL;
298 0     char *                              BST_Id = NULL;
299 0     char *                              BST_Id_end = NULL;
300 0     globus_list_t **                    security_attrs = NULL;
301 0     ds_KeyInfoType_choice *             key_info_choice = NULL;
302 0     wsse_SecurityTokenReferenceType *   SecurityTokenReference = NULL;
303 0     wsse_ReferenceType *                wsse_Reference = NULL;
304 0     struct tm                           tv;
305 0     time_t                              ct;
306 0     char *                              signed_info_buff = NULL;
307 0     size_t                              signed_info_buff_length = 0;
308 0     int                                 mustUnderstand;
309 0     int                                 message_duration;
310 0     char *                              pkipath = NULL;
311 0     int                                 pkipath_length;
312 0     globus_gsi_cred_handle_t            cred = NULL;
313 0     globus_result_t                     result = GLOBUS_SUCCESS;
314 0     globus_xsd_element_options_t        options = 0;
315 0     GlobusFuncName(globus_handler_ws_security_sign_message);
316 0     GlobusWSSEDebugEnter();
317
318 0     result = globus_soap_message_set_write_position_to_marker(
319 message_handle, 
320 GLOBUS_SOAP_MESSAGE_MARKER_HEADER_CONTENT);
321 0     if(result != GLOBUS_SUCCESS)
322     {
323 0 result = GlobusWSSEErrorFailedSign(result);
324 0 goto exit;
325     }
326
327 0     globus_soap_message_element_ns_set(
328 message_handle,
329 wsse_Security_qname.Namespace,
330 &options);
331
332 0     result = globus_soap_message_serialize_element(
333 message_handle,
334 &wsse_Security_qname,
335 options,
336 NULL);
337 0     if(result != GLOBUS_SUCCESS)
338     {
339 0 result = GlobusWSSEErrorFailedSign(result);
340 0 goto exit;
341     }
342
343 0     result = globus_soap_message_element_ns_add(
344 message_handle,
345 wsse_Security_qname.Namespace,
346 &options);
347 0     if(result != GLOBUS_SUCCESS)
348     {
349 0 result = GlobusWSSEErrorFailedSign(result);
350 0 goto exit;
351     }
352
353 0     mustUnderstand = 1;
354 0     result = globus_soap_message_serialize_int_attribute(
355 message_handle,
356 &mustUnderstand_attr_qname,
357 &mustUnderstand);
358 0     if(result != GLOBUS_SUCCESS)
359     {
360 0 result = GlobusWSSEErrorFailedSign(result);
361 0 goto exit;
362     }
363
364 0     result = globus_soap_message_serialize_element_content_close(
365 message_handle);
366 0     if(result != GLOBUS_SUCCESS)
367     {
368 0 result = GlobusWSSEErrorFailedSign(result);
369 0 goto exit;
370     }
371
372     /* Start BinarySecurityToken */
373
374 0     globus_soap_message_serialize_start_c14n_subset(
375 message_handle);
376
377 0     wsse_BinarySecurityTokenType_init_contents(&bst);
378
379 0     result = xsd_anyURI_init_cstr(&bst._EncodingType,
380             globus_libc_strdup(BASE64BINARY_ENCODING_NS));
381 0     if (result != GLOBUS_SUCCESS)
382     {
383 0         result = GlobusWSSEErrorFailedSign(result);
384
385 0         goto destroy_BST;
386     }
387 0     result = xsd_anyURI_init_cstr(&bst._ValueType,
388             globus_libc_strdup(X509_TOKEN_NS));
389 0     if (result != GLOBUS_SUCCESS)
390     {
391 0         result = GlobusWSSEErrorFailedSign(result);
392
393 0         goto destroy_BST;
394     }
395
396 0     xsd_ID_init(&bst._Id);
397 0     BST_Id = GlobusHandlerWSSENewCertId();
398 0     *bst._Id = BST_Id;
399     
400 0     result = globus_soap_message_set_marker(
401 message_handle,
402 BST_Id);
403 0     if(result != GLOBUS_SUCCESS)
404     {
405 0 result = GlobusWSSEErrorFailedSign(result);
406 0 goto exit;
407     }
408
409     /* get pkipath stuff */
410 0     result = globus_i_handler_wsse_load_local_cred(
411 message_handle, &cred, &pkipath, &pkipath_length);
412 0     if(result != GLOBUS_SUCCESS)
413     {
414 0 result = GlobusWSSEErrorFailedSign(result);
415 0 goto destroy_BST;
416     }
417
418 0     bst.base_value = globus_malloc(pkipath_length + 1);
419 0     memcpy(bst.base_value, pkipath, pkipath_length);
420 0     bst.base_value[pkipath_length] = '\0';
421
422 0     result = wsse_BinarySecurityTokenType_serialize(
423 &wsse_BinarySecurityToken_qname,
424 &bst,
425 message_handle,
426 options);
427 0     if(result != GLOBUS_SUCCESS)
428     {
429 0 result = GlobusWSSEErrorFailedSign(result);
430 0 goto destroy_pkipath;
431     }
432
433 0     globus_soap_message_serialize_end_c14n_subset(
434 message_handle);
435
436 0     BST_Id_end = globus_common_create_string("%s-end", BST_Id);
437 0     result = globus_soap_message_set_marker(
438 message_handle,
439 BST_Id_end);
440 0     if(result != GLOBUS_SUCCESS)
441     {
442 0 globus_free(BST_Id_end);
443 0 result = GlobusWSSEErrorFailedSign(result);
444 0 goto destroy_KeyInfo;
445     }
446 0     globus_free(BST_Id_end);
447     
448 0     security_attrs = globus_soap_message_handle_get_attr(
449 message_handle,
450 GLOBUS_HANDLER_WSSE_TOKEN_IDS_KEY);
451 0     globus_assert(security_attrs);
452
453 0     globus_list_insert(security_attrs,
454        globus_libc_strdup(BST_Id));
455
456     /* End BinarySecurityToken */
457
458     /* Start Timestamp */
459
460 0     wsseu_TimestampType_init_contents(&Timestamp);
461
462 0     wsseu_AttributedDateTime_init(&Timestamp.Created);
463
464 0     ct = time(NULL);
465 0     gmtime_r(&ct, &tv);
466 0     Timestamp.Created->base_value = globus_wsrf_core_export_timestamp(&tv);
467
468 0     wsseu_AttributedDateTime_init(&Timestamp.Expires);
469
470 0     message_duration = (int)globus_soap_message_handle_get_attr(
471 message_handle,
472 GLOBUS_HANDLER_WSSE_MESSAGE_DURATION_KEY);
473 0     if(message_duration)
474     {
475 0 tv.tm_min += message_duration;
476     }
477     else
478     {
479 0 tv.tm_min += 5;
480     }
481
482 0     Timestamp.Expires->base_value = globus_wsrf_core_export_timestamp(&tv);
483
484 0     result = wsseu_TimestampType_serialize(
485 &wsseu_Timestamp_qname,
486 &Timestamp,
487 message_handle,
488 0);
489 0     if(result != GLOBUS_SUCCESS)
490     {
491 0 result = GlobusWSSEErrorFailedSign(result);
492 0 goto destroy_Timestamp;
493     }
494
495     /* End Timestamp */
496
497     /* Start Signature element */
498
499 0     options = 0;
500 0     result = globus_soap_message_element_ns_set(
501 message_handle,
502 ds_Signature_qname.Namespace,
503 &options);
504 0     if(result != GLOBUS_SUCCESS)
505     {
506 0 result = GlobusWSSEErrorFailedSign(result);
507 0 goto destroy_Timestamp;
508     }
509
510 0     result = globus_soap_message_serialize_element(
511 message_handle,
512 &ds_Signature_qname,
513 0,
514 NULL);
515 0     if(result != GLOBUS_SUCCESS)
516     {
517 0 result = GlobusWSSEErrorFailedSign(result);
518 0 goto destroy_Timestamp;
519     }
520
521 0     result = globus_soap_message_element_ns_add(
522 message_handle,
523 ds_Signature_qname.Namespace,
524 &options);
525 0     if(result != GLOBUS_SUCCESS)
526     {
527 0 result = GlobusWSSEErrorFailedSign(result);
528 0 goto destroy_Timestamp;
529     }
530
531 0     result = globus_soap_message_serialize_element_begin_close(
532 message_handle);
533 0     if(result != GLOBUS_SUCCESS)
534     {
535 0 result = GlobusWSSEErrorFailedSign(result);
536 0 goto destroy_Timestamp;
537     }
538
539 0     result = globus_soap_message_set_marker(
540 message_handle,
541 SIGNATURE_CONTENTS_MARKER);
542 0     if(result != GLOBUS_SUCCESS)
543     {
544 0 result = GlobusWSSEErrorFailedSign(result);
545 0 goto destroy_Timestamp;
546     }
547     
548 0     globus_soap_message_serialize_start_c14n_subset(
549 message_handle);
550     
551     /* Add KeyInfo element */
552
553 0     result = ds_KeyInfoType_init_contents(&KeyInfo);
554 0     if(result != GLOBUS_SUCCESS)
555     {
556 0 result = GlobusWSSEErrorFailedSign(result);
557 0 goto destroy_Timestamp;
558     }
559
560     /* Add Id attribute */
561 0     key_info_id = GlobusHandlerWSSENewKeyId();
562 0     xsd_ID_init(&KeyInfo._Id);
563 0     *KeyInfo._Id = key_info_id;
564
565 0     result = globus_soap_message_set_marker(
566 message_handle,
567 key_info_id);
568 0     if(result != GLOBUS_SUCCESS)
569     {
570 0 result = GlobusWSSEErrorFailedSign(result);
571 0 goto destroy_KeyInfo;
572     }
573
574 0     key_info_choice = ds_KeyInfoType_choice_array_push(
575 &KeyInfo.choice_value);
576 0     key_info_choice->type = ds_KeyInfoType_any;
577 0     xsd_QName_copy(&key_info_choice->value.any.element,
578    &wsse_SecurityTokenReference_qname);
579 0     key_info_choice->value.any.any_info = 
580 &wsse_SecurityTokenReferenceType_info;
581 0     wsse_SecurityTokenReferenceType_init(&SecurityTokenReference); 
582 0     xsd_ID_init(&SecurityTokenReference->_Id); 
583 0     *SecurityTokenReference->_Id = GlobusHandlerWSSENewSTRId(); 
584 0     xsd_any_init_contents(&SecurityTokenReference->any); 
585 0     xsd_QName_copy(&SecurityTokenReference->any.element, &wsse_Reference_qname);
586 0     SecurityTokenReference->any.any_info = &wsse_ReferenceType_info;
587
588 0     wsse_ReferenceType_init(&wsse_Reference);
589 0     xsd_anyURI_init(&wsse_Reference->_URI);
590 0     *wsse_Reference->_URI = globus_common_create_string("#%s", *bst._Id);
591 0     result = xsd_anyURI_init_cstr(
592             &wsse_Reference->_ValueType,
593             globus_libc_strdup(X509_TOKEN_NS));
594 0     if (result != GLOBUS_SUCCESS)
595     {
596 0        result = GlobusWSSEErrorFailedSign(result);
597 0        goto destroy_KeyInfo;
598     }
599
600
601 0     SecurityTokenReference->any.value = wsse_Reference;
602
603 0     key_info_choice->value.any.value = SecurityTokenReference;
604
605 0     result = ds_KeyInfoType_serialize(
606 &ds_KeyInfo_qname,
607 &KeyInfo,
608 message_handle,
609 options);
610 0     if(result != GLOBUS_SUCCESS)
611     {
612 0 result = GlobusWSSEErrorFailedSign(result);
613 0 goto destroy_KeyInfo;
614     }
615
616 0     globus_soap_message_serialize_end_c14n_subset(
617 message_handle);
618
619 0     key_info_id_end = globus_common_create_string("%s-end", key_info_id);
620 0     result = globus_soap_message_set_marker(
621 message_handle,
622 key_info_id_end);
623 0     if(result != GLOBUS_SUCCESS)
624     {
625 0 globus_free(key_info_id_end);
626 0 result = GlobusWSSEErrorFailedSign(result);
627 0 goto destroy_KeyInfo;
628     }
629 0     globus_free(key_info_id_end);
630   
631 0     globus_list_insert(security_attrs, globus_libc_strdup(key_info_id));
632
633 0     result = globus_soap_message_set_marker(
634 message_handle,
635 SIGNATURE_CONTENTS_END_MARKER);
636 0     if(result != GLOBUS_SUCCESS)
637     {
638 0 result = GlobusWSSEErrorFailedSign(result);
639 0 goto destroy_KeyInfo;
640     }
641     
642 0     result = globus_soap_message_set_write_position_to_marker(
643 message_handle,
644 SIGNATURE_CONTENTS_MARKER);
645 0     if(result != GLOBUS_SUCCESS)
646     {
647 0 result = GlobusWSSEErrorFailedSign(result);
648 0 goto destroy_KeyInfo;
649     }
650     
651 0     ds_SignedInfoType_init_contents(&SignedInfo);
652
653 0     ds_CanonicalizationMethodType_init_contents(
654 &SignedInfo.CanonicalizationMethod);
655 0     SignedInfo.CanonicalizationMethod._Algorithm = 
656 globus_libc_strdup(EXC_C14N_NS);
657
658 0     ds_SignatureMethodType_init_contents(
659 &SignedInfo.SignatureMethod);
660 0     SignedInfo.SignatureMethod._Algorithm =
661 globus_libc_strdup(RSA_SHA1_NS);
662
663 0     result = globus_i_handler_ws_security_add_references(
664 message_handle, &SignedInfo.Reference);
665 0     if(result != GLOBUS_SUCCESS)
666     {
667 0 result = GlobusWSSEErrorFailedSign(result);
668 0 goto destroy_SignedInfo;
669     }
670     
671 0     globus_soap_message_serialize_start_c14n_subset(
672 message_handle);
673
674 0     result = globus_soap_message_set_marker(
675 message_handle,
676 GLOBUS_HANDLER_WSSE_MARKER_SIGNED_INFO_BEGIN);
677 0     if(result != GLOBUS_SUCCESS)
678     {
679 0 result = GlobusWSSEErrorFailedSign(result);
680 0 goto destroy_SignedInfo;
681     }    
682
683 0     result = ds_SignedInfoType_serialize(
684 &ds_SignedInfo_qname,
685 &SignedInfo,
686 message_handle,
687 options);
688 0     if(result != GLOBUS_SUCCESS)
689     {
690 0 result = GlobusWSSEErrorFailedSign(result);
691 0 goto destroy_SignedInfo;
692     }
693
694 0     globus_soap_message_serialize_end_c14n_subset(
695 message_handle);
696
697 0     result = globus_soap_message_set_marker(
698 message_handle,
699 GLOBUS_HANDLER_WSSE_MARKER_SIGNED_INFO_END);
700 0     if(result != GLOBUS_SUCCESS)
701     {
702 0 result = GlobusWSSEErrorFailedSign(result);
703 0 goto destroy_SignedInfo;
704     }    
705
706     /* Set mark for SignatureValue */
707    
708     /* Add SignatureValue element */
709
710 0     result = globus_soap_message_get_marked_buffers(
711 message_handle, 
712 GLOBUS_HANDLER_WSSE_MARKER_SIGNED_INFO_BEGIN,
713 GLOBUS_HANDLER_WSSE_MARKER_SIGNED_INFO_END,
714 &signed_info_buff,
715 &signed_info_buff_length);
716 0     if(result != GLOBUS_SUCCESS)
717     {
718 0 result = GlobusWSSEErrorFailedSign(result);
719 0 goto destroy_SignedInfo;
720     } 
721     
722 0     result = globus_i_handler_ws_security_compute_signature(
723 cred,
724 signed_info_buff,
725 signed_info_buff_length,
726 &SignatureValue.base_value.value,
727 &SignatureValue.base_value.length);
728 0     if(result != GLOBUS_SUCCESS)
729     {
730 0 result = GlobusWSSEErrorFailedSign(result);
731 0 goto destroy_signed_info_buff;
732     }
733     
734 0     SignatureValue._Id = NULL;
735 0     result = ds_SignatureValueType_serialize(
736 &ds_SignatureValue_qname,
737 &SignatureValue,
738 message_handle,
739 0);
740 0     if(result != GLOBUS_SUCCESS)
741     {
742 0 globus_free(SignatureValue.base_value.value);
743 0 SignatureValue.base_value.value = NULL;
744 0 SignatureValue.base_value.length = 0;
745 0 result = GlobusWSSEErrorFailedSign(result);
746 0 goto destroy_signed_info_buff;
747     }
748
749 0     globus_free(SignatureValue.base_value.value);
750 0     SignatureValue.base_value.value = NULL;
751 0     SignatureValue.base_value.length = 0;
752
753 0     result = globus_soap_message_set_write_position_to_marker(
754 message_handle,
755 SIGNATURE_CONTENTS_END_MARKER);
756 0     if(result != GLOBUS_SUCCESS)
757     {
758 0 result = GlobusWSSEErrorFailedSign(result);
759 0 goto destroy_signed_info_buff;
760     }
761  
762 0     result = globus_soap_message_serialize_element_end(
763 message_handle,
764 &ds_Signature_qname,
765 0,
766 NULL);
767 0     if(result != GLOBUS_SUCCESS)
768     {
769 0 result = GlobusWSSEErrorFailedSign(result);
770 0 goto destroy_signed_info_buff;
771     }
772
773
774 0     globus_soap_message_element_ns_remove(
775 message_handle,
776 ds_Signature_qname.Namespace,
777 &options);
778 0     if(result != GLOBUS_SUCCESS)
779     {
780 0 result = GlobusWSSEErrorFailedSign(result);
781 0 goto destroy_signed_info_buff;
782     }
783
784 0     result = globus_soap_message_serialize_element_end(
785 message_handle,
786 &wsse_Security_qname,
787 0,
788 NULL);
789 0     if(result != GLOBUS_SUCCESS)
790     {
791 0 result = GlobusWSSEErrorFailedSign(result);
792 0 goto destroy_signed_info_buff;
793     }
794
795 0     globus_soap_message_element_ns_remove(
796 message_handle,
797 wsse_Security_qname.Namespace,
798 &options);
799 0     if(result != GLOBUS_SUCCESS)
800     {
801 0 result = GlobusWSSEErrorFailedSign(result);
802 goto destroy_signed_info_buff;
803     }
804
805 destroy_signed_info_buff:
806
807 0     if(signed_info_buff)
808     {
809 0 globus_free(signed_info_buff);
810     }
811
812 destroy_SignedInfo:
813
814 0     ds_SignedInfoType_destroy_contents(&SignedInfo);
815
816 destroy_KeyInfo:
817
818 0     ds_KeyInfoType_destroy_contents(&KeyInfo);
819
820 destroy_Timestamp:
821
822 0     wsseu_TimestampType_destroy_contents(&Timestamp);
823
824 destroy_pkipath:
825
826 destroy_BST:
827
828 0     wsse_BinarySecurityTokenType_destroy_contents(&bst);
829
830 exit:
831
832 0     GlobusWSSEDebugExit();
833 0     return result;
834 }
835
836 static
837 globus_result_t
838 globus_l_handler_ws_security_mark_signed_info(
839     globus_soap_message_handle_t        message_handle,
840     const xsd_QName *                   type)
841 0 {
842 0     globus_result_t                     result = GLOBUS_SUCCESS;
843 0     GlobusFuncName(globus_handler_ws_security_mark_signed_info);
844 0     GlobusWSSEDebugEnter();
845
846 0     result = globus_soap_message_deserialize_mark(
847 message_handle, SIGNED_INFO_MARKER);
848
849 0     GlobusWSSEDebugExit();
850 0     return result;
851 }
852
853 static
854 globus_result_t
855 globus_l_handler_ws_security_mark_signed_info_end(
856     globus_soap_message_handle_t        message_handle,
857     const xsd_QName *                   type)
858 0 {
859 0     xsd_QName                           next_qn;
860 0     globus_result_t                     result = GLOBUS_SUCCESS;
861 0     GlobusFuncName(globus_handler_ws_security_mark_signed_info);
862 0     GlobusWSSEDebugEnter();
863
864 0     xsd_QName_init_contents(&next_qn);
865
866 0     result = globus_soap_message_deserialize_element_unknown(
867 message_handle, &next_qn);
868 0     if(result != GLOBUS_SUCCESS)
869     {
870 0 goto exit;
871     }
872
873 0     globus_soap_message_deserialize_push_element(message_handle);
874
875 0     result = globus_soap_message_deserialize_mark(
876 message_handle, SIGNED_INFO_MARKER_END);
877
878 exit:
879
880 0     xsd_QName_destroy_contents(&next_qn);
881 0     GlobusWSSEDebugExit();
882 0     return result;
883 }
884
885 static
886 globus_result_t
887 globus_handler_ws_security_verify_message(
888     globus_soap_message_handle_t        message_handle)
889 0 {
890 0     globus_gsi_cred_handle_t            peer_cred = NULL;
891 0     char *                              signed_info_buff = NULL;
892 0     size_t                              signed_info_buff_length = 0;
893 0     char *                              soap_message_buff = NULL;
894 0     size_t                              soap_message_buff_length = 0;
895 0     char *                              c14n_signed_info_buff = NULL;
896 0     size_t                              c14n_signed_info_buff_length = 0;
897 0     globus_result_t                     result = GLOBUS_SUCCESS;
898 0     int                                 index = 0;
899 0     wsseu_TimestampType *               Timestamp = NULL;
900 0     ds_SignatureType *                  Signature = NULL;
901 0     wsse_SecurityHeaderType *           SecurityHeader = NULL;
902 0     GlobusFuncName(globus_handler_ws_security_verify_message);
903 0     GlobusWSSEDebugEnter();
904
905 0     if(result != GLOBUS_SUCCESS)
906     {
907 0 goto exit;
908     }
909
910 0     result = globus_soap_message_add_callout(
911 message_handle,
912 &ds_SignedInfo_qname,
913 globus_l_handler_ws_security_mark_signed_info,
914 globus_l_handler_ws_security_mark_signed_info_end,
915 NULL);
916 0     if(result != GLOBUS_SUCCESS)
917     {
918 0 result = GlobusWSSEErrorDeserializeFailed(
919     result, "Failed to set marker for SignedInfo element");
920 0 goto exit;
921     }
922
923 0     result = wsse_SecurityHeaderType_init(
924 &SecurityHeader);
925 0     if(result != GLOBUS_SUCCESS)
926     {
927 0 result = GlobusWSSEErrorDeserializeFailed(
928     result, "Failed to init Security header");
929 0 goto remove_callout_exit;
930     }
931
932 0     result = wsse_SecurityHeaderType_deserialize(
933 &wsse_Security_qname,
934 SecurityHeader,
935 message_handle,
936 0);
937 0     if(result != GLOBUS_SUCCESS)
938     {
939 0 result = GlobusWSSEErrorDeserializeFailed(
940     result, "Failed to deserialize Security header element");
941 0 goto remove_callout_exit;
942     }
943
944 0     for(; index < SecurityHeader->any.length; ++index)
945     {
946 0 if(xsd_QName_keyeq(SecurityHeader->any.elements[index].element,
947    &wsse_BinarySecurityToken_qname))
948 {
949 0     wsse_BinarySecurityTokenType * bst;
950
951 0     if(SecurityHeader->any.elements[index].any_info != 
952        &wsse_BinarySecurityToken_info)
953     {
954 0 result = GlobusWSSEErrorFailedBinarySecurityToken(
955     "<BinarySecurityToken> element did not get "
956     "deserialized into a BinarySecurityTokenType");
957 0 goto SecurityHeader_destroy;
958     }
959
960 0     bst = (wsse_BinarySecurityTokenType *)
961 SecurityHeader->any.elements[index].value;
962
963 0     result = globus_ws_security_get_credential(
964 bst->base_value,
965 strlen(bst->base_value),
966 &peer_cred);
967 0     if(result != GLOBUS_SUCCESS)
968     {
969 0 result = GlobusWSSEErrorFailedBinarySecurityToken(
970     "Failed to get credential from PKIPath buffer");
971 0 goto SecurityHeader_destroy;
972     }
973 }
974 0 else if(xsd_QName_keyeq(
975 SecurityHeader->any.elements[index].element,
976 &ds_Signature_qname))
977 {
978 0     if(SecurityHeader->any.elements[index].any_info != 
979        &ds_Signature_info)
980     {
981 0 result = GlobusWSSEErrorFailedVerify(
982     GLOBUS_SUCCESS,
983     "<Signature> element did not get "
984     "deserialized into a SignatureType");
985 0 goto SecurityHeader_destroy;
986     }
987
988 0     Signature = (ds_SignatureType *)
989 SecurityHeader->any.elements[index].value;
990 }
991 0 else if(xsd_QName_keyeq(
992 SecurityHeader->any.elements[index].element,
993 &wsseu_Timestamp_qname))
994 {
995 0     if(SecurityHeader->any.elements[index].any_info != 
996        &wsseu_Timestamp_info)
997     {
998 0 result = GlobusWSSEErrorFailedVerify(
999     GLOBUS_SUCCESS,
1000     "<Timestamp> element did not get "
1001     "deserialized into a TimestampType");
1002 0 goto SecurityHeader_destroy;
1003     }
1004
1005 0     Timestamp = (wsseu_TimestampType *)
1006 SecurityHeader->any.elements[index].value;
1007 }
1008     }
1009
1010 0     if(!peer_cred)
1011     {
1012 0 result = GlobusWSSEErrorFailedVerify(
1013     GLOBUS_SUCCESS,
1014     "Invalid Security header element: "
1015     "no BinarySecurityToken element found");
1016 0 goto SecurityHeader_destroy;
1017     }
1018
1019 0     if(!Signature)
1020     {
1021 0 result = GlobusWSSEErrorFailedVerify(
1022     GLOBUS_SUCCESS,
1023     "Invalid Security header element: no Signature element found");
1024 0 goto SecurityHeader_destroy;
1025     }
1026
1027 0     if(!Timestamp)
1028     {
1029 0 result = GlobusWSSEErrorFailedVerify(
1030     GLOBUS_SUCCESS,
1031     "Invalid Security header element: no Timestamp found");
1032 0 goto SecurityHeader_destroy;
1033     }
1034
1035 0     if(!globus_soap_message_handle_get_attr(
1036     message_handle, GLOBUS_SOAP_MESSAGE_AUTH_ANONYMOUS_KEY))
1037     {
1038 0        char *                                certdir;
1039 0        globus_gsi_callback_data_t            callback_data;
1040
1041 0        result = globus_gsi_callback_data_init(&callback_data);
1042 0        if(result != GLOBUS_SUCCESS)
1043        {
1044 0            result = GlobusWSSEErrorFailedVerify(
1045                result, "Peer credential verification failed");
1046 0            goto SecurityHeader_destroy;
1047        }
1048
1049 0        result = GLOBUS_GSI_SYSCONFIG_GET_CERT_DIR(&certdir);
1050 0        if(result != GLOBUS_SUCCESS)
1051        {
1052 0            globus_gsi_callback_data_destroy(callback_data);
1053 0            result = GlobusWSSEErrorFailedVerify(
1054                result, "Peer credential verification failed");
1055 0            goto SecurityHeader_destroy;
1056        }
1057
1058 0        result = globus_gsi_callback_set_cert_dir(
1059            callback_data,
1060            certdir);
1061 0        if(result != GLOBUS_SUCCESS)
1062        {
1063 0            globus_free(certdir);
1064 0            globus_gsi_callback_data_destroy(callback_data);
1065 0            result = GlobusWSSEErrorFailedVerify(
1066                result, "Peer credential verification failed");
1067 0            goto SecurityHeader_destroy;
1068        }
1069
1070 0        globus_free(certdir);
1071
1072 0        result = globus_gsi_cred_verify_cert_chain(
1073            peer_cred,
1074            callback_data);
1075
1076 0         globus_gsi_callback_data_destroy(callback_data);
1077
1078 0 if(result != GLOBUS_SUCCESS)
1079 {
1080 0     result = GlobusWSSEErrorFailedVerify(
1081 result, "Peer credential verification failed");
1082 0     goto SecurityHeader_destroy;
1083 }
1084     }
1085
1086     /* get SignedInfo buffer */
1087 0     result = globus_soap_message_get_marked_buffers(
1088 message_handle, SIGNED_INFO_MARKER, SIGNED_INFO_MARKER_END,
1089 &signed_info_buff, &signed_info_buff_length);
1090 0     if(result != GLOBUS_SUCCESS)
1091     {
1092 0 result = GlobusWSSEErrorFailedVerify(
1093     result, "Failed to get SignedInfo buffer");
1094 0 goto SecurityHeader_destroy;
1095     }
1096
1097     /* verify SignedInfo with what's in SignatureValue */
1098 0     result = globus_i_handler_ws_security_verify_signature(
1099 peer_cred,
1100 signed_info_buff,
1101 signed_info_buff_length,
1102 Signature->SignatureValue.base_value.value,
1103 Signature->SignatureValue.base_value.length);
1104 0     if(result != GLOBUS_SUCCESS)
1105     {
1106 0 xsd_string_array *              inc_ns_prefixes = NULL;
1107
1108 0 GlobusWSSEDebugPrintf(
1109     GLOBUS_L_WS_SECURITY_DEBUG_VERIFY,
1110     ("Direct Verify of SignedInfo element failed.\n"));
1111
1112 0 GlobusWSSEDebugPrintf(
1113     GLOBUS_L_WS_SECURITY_DEBUG_C14N,
1114     ("-----NON-C14N SignedInfo (length: %d)-----\n%.*s\n"
1115      "---------------------------------------------\n", 
1116      signed_info_buff_length, 
1117      signed_info_buff_length, 
1118      signed_info_buff));
1119
1120 0 if(Signature->SignedInfo.CanonicalizationMethod.any.length > 0)
1121 {
1122 0     if(Signature->SignedInfo.CanonicalizationMethod.
1123        any.elements[0].any_info == 
1124        (&exc_c14n_InclusiveNamespaces_info))
1125     {
1126 0 exc_c14n_InclusiveNamespacesType * incs = 
1127     (exc_c14n_InclusiveNamespacesType *)
1128     Signature->SignedInfo.CanonicalizationMethod.
1129 0     any.elements[0].value;
1130
1131 0 inc_ns_prefixes = incs->_PrefixList;
1132     }
1133 }
1134
1135 0 result = globus_soap_message_get_marked_buffers(
1136     message_handle, 
1137     NULL, NULL,
1138     &soap_message_buff, &soap_message_buff_length);
1139 0 if(result != GLOBUS_SUCCESS)
1140 {
1141 0     result = GlobusWSSEErrorFailedVerify(
1142 result, "Failed to get SOAP message buffer");
1143 0     goto SecurityHeader_destroy;
1144 }
1145
1146 0 result = globus_l_handler_ws_security_c14n_signed_info(
1147     message_handle,
1148     soap_message_buff,
1149     soap_message_buff_length,
1150     &c14n_signed_info_buff,
1151     &c14n_signed_info_buff_length,
1152     inc_ns_prefixes);
1153 0 if(result != GLOBUS_SUCCESS)
1154 {
1155 0     result = GlobusWSSEErrorFailedVerify(
1156 result,
1157 "Failed to perform c14n of the SignedInfo node");
1158 0     goto signed_info_destroy;
1159 }
1160
1161 0 GlobusWSSEDebugPrintf(
1162     GLOBUS_L_WS_SECURITY_DEBUG_C14N,
1163     ("-----C14N SignedInfo (length: %d)-----\n%.*s\n"
1164      "---------------------------------------------\n", 
1165      c14n_signed_info_buff_length, 
1166      c14n_signed_info_buff_length, 
1167      c14n_signed_info_buff));
1168
1169 0 result = globus_i_handler_ws_security_verify_signature(
1170     peer_cred,
1171     c14n_signed_info_buff,
1172     c14n_signed_info_buff_length,
1173     Signature->SignatureValue.base_value.value,
1174     Signature->SignatureValue.base_value.length);
1175 0 if(result != GLOBUS_SUCCESS)
1176 {
1177 0     result = GlobusWSSEErrorFailedVerify(
1178 result,
1179 "Failed to verify the signature of the message");
1180 0     goto signed_info_destroy;
1181 }
1182     }
1183
1184 0     globus_soap_message_handle_set_attr(
1185 message_handle, 
1186 SECURITY_HEADER_ELEMENT_KEY,
1187 wsse_SecurityHeaderType_copy_wrapper,
1188 wsse_SecurityHeaderType_destroy_wrapper,
1189 (void *)SecurityHeader);
1190     
1191 signed_info_destroy:
1192
1193 0     if(signed_info_buff)
1194     {
1195 0 globus_free(signed_info_buff);
1196     }
1197
1198 0     if(c14n_signed_info_buff)
1199     {
1200 0 globus_free(c14n_signed_info_buff);
1201     }
1202
1203 SecurityHeader_destroy:
1204
1205 0     if(SecurityHeader)
1206     {
1207 0         wsse_SecurityHeaderType_destroy(SecurityHeader);
1208     }
1209     
1210 remove_callout_exit:
1211 0     globus_soap_message_remove_callouts(
1212 message_handle,
1213 &ds_SignedInfo_qname);
1214 exit:
1215
1216 0     if(soap_message_buff)
1217     {
1218 0 globus_free(soap_message_buff);
1219     }
1220
1221 0     if(peer_cred)
1222     {
1223 0 globus_gsi_cred_handle_destroy(peer_cred);
1224     }
1225
1226 0     GlobusWSSEDebugExit();
1227 0     return result;
1228 }
1229
1230 static
1231 globus_result_t
1232 globus_handler_ws_security_verify_message_references(
1233     globus_soap_message_handle_t        message_handle)
1234 0 {
1235 0     int                                 index = 0;
1236 0     globus_result_t                     result = GLOBUS_SUCCESS;
1237 0     ds_SignatureType *                  Signature;
1238 0     wsse_SecurityHeaderType *           SecurityHeader;
1239 0     GlobusFuncName(globus_handler_ws_security_verify_message_references);
1240 0     GlobusWSSEDebugEnter();
1241
1242 0     if(result != GLOBUS_SUCCESS)
1243     {
1244 0 goto exit;
1245     }
1246
1247 0     SecurityHeader = globus_soap_message_handle_get_attr(
1248 message_handle,
1249 SECURITY_HEADER_ELEMENT_KEY);
1250 0     if(!SecurityHeader)
1251     {
1252 0 result = GlobusWSSEErrorFailedVerify(
1253     result,
1254     "Unable to get Security header element from "
1255     "message attributes.");
1256 0 goto exit;
1257     }
1258
1259 0     for(; index < SecurityHeader->any.length; ++index)
1260     {
1261 0 if(xsd_QName_keyeq(
1262 SecurityHeader->any.elements[index].element,
1263 &ds_Signature_qname))
1264 {
1265 0     Signature = (ds_SignatureType *)
1266 SecurityHeader->any.elements[index].value;
1267 }
1268     }
1269
1270 0     result = globus_i_handler_ws_security_verify_references(
1271 message_handle, &Signature->SignedInfo.Reference);
1272 0     if(result != GLOBUS_SUCCESS)
1273     {
1274 0 result = GlobusWSSEErrorFailedVerify(
1275     result,
1276     "Unable to verify digest values of references "
1277     "for SignedInfo element");
1278 goto exit;
1279     }
1280
1281 exit:
1282
1283 0     GlobusWSSEDebugExit();
1284 0     return result;
1285 }
1286
1287 static
1288 globus_result_t
1289 globus_l_ws_security_reference_ns_set(
1290     globus_soap_message_handle_t        message_handle,
1291     const xsd_QName *                   element,
1292     globus_xsd_element_options_t *      options)
1293 0 {
1294 0     globus_result_t                     result = GLOBUS_SUCCESS;
1295 0     globus_bool_t                       done_with_body;
1296 0     GlobusFuncName(globus_l_ws_security_reference_ns_set);
1297 0     GlobusWSSEDebugEnter();
1298
1299     /* Skip instances of reference properties in the message body */
1300 0     done_with_body = (globus_bool_t) globus_soap_message_handle_get_attr(
1301 message_handle,
1302         WSSE_DONE_WITH_BODY_KEY);
1303
1304 0     if ((!done_with_body) &&
1305             globus_l_ws_security_is_reference_property_element(element))
1306     {
1307 0         return GLOBUS_SUCCESS;
1308     }
1309 0     globus_soap_message_serialize_start_c14n_subset(
1310 message_handle);
1311
1312 0     result = globus_soap_message_element_ns_set(
1313 message_handle,
1314 WSSEU_NS,
1315 options);
1316
1317 0     GlobusWSSEDebugExit();
1318 0     return result;
1319 }
1320
1321 static
1322 globus_result_t
1323 globus_l_ws_security_reference_ns_add(
1324     globus_soap_message_handle_t        message_handle,
1325     const xsd_QName *                   element,
1326     globus_xsd_element_options_t *      options)
1327 0 {
1328 0     globus_result_t                     result = GLOBUS_SUCCESS;
1329 0     globus_bool_t                       done_with_body;
1330 0     GlobusFuncName(globus_l_ws_security_reference_ns_set);
1331 0     GlobusWSSEDebugEnter();
1332
1333     /* Skip instances of reference properties in the message body */
1334 0     done_with_body = (globus_bool_t) globus_soap_message_handle_get_attr(
1335 message_handle,
1336         WSSE_DONE_WITH_BODY_KEY);
1337
1338 0     if ((!done_with_body) &&
1339             globus_l_ws_security_is_reference_property_element(element))
1340     {
1341 0         return GLOBUS_SUCCESS;
1342     }
1343 0     result = globus_soap_message_element_ns_add(
1344 message_handle,
1345 WSSEU_NS,
1346 options);
1347
1348 0     GlobusWSSEDebugExit();
1349 0     return result;
1350 }    
1351
1352 static
1353 globus_result_t
1354 globus_l_ws_security_reference_ns_remove(
1355     globus_soap_message_handle_t        message_handle,
1356     const xsd_QName *                   element,
1357     globus_xsd_element_options_t *      options)
1358 0 {
1359 0     globus_result_t                     result = GLOBUS_SUCCESS;
1360 0     globus_bool_t                       done_with_body;
1361 0     GlobusFuncName(globus_l_ws_security_reference_ns_remove);
1362 0     GlobusWSSEDebugEnter();
1363
1364     /* Skip instances of reference properties in the message body */
1365 0     done_with_body = (globus_bool_t) globus_soap_message_handle_get_attr(
1366 message_handle,
1367         WSSE_DONE_WITH_BODY_KEY);
1368
1369 0     if ((!done_with_body) &&
1370             globus_l_ws_security_is_reference_property_element(element))
1371     {
1372 0         return GLOBUS_SUCCESS;
1373     }
1374 0     globus_soap_message_element_ns_remove(
1375 message_handle,
1376 WSSEU_NS,
1377 options);
1378
1379 0     GlobusWSSEDebugExit();
1380 0     return result;
1381 }    
1382
1383 static
1384 globus_result_t
1385 globus_l_ws_security_reference_begin(
1386     globus_soap_message_handle_t        message_handle,
1387     const xsd_QName *                   type)
1388 0 {
1389 0     globus_result_t                     result = GLOBUS_SUCCESS;
1390 0     char *                              idval;
1391 0     char *                              idkey;
1392 0     globus_xsd_element_options_t *      options;
1393 0     globus_bool_t                       done_with_body;
1394 0     GlobusFuncName(globus_l_ws_security_reference_begin);
1395 0     GlobusWSSEDebugEnter();
1396
1397     /* Skip instances of reference properties in the message body */
1398 0     done_with_body = (globus_bool_t) globus_soap_message_handle_get_attr(
1399 message_handle,
1400         WSSE_DONE_WITH_BODY_KEY);
1401
1402 0     if ((!done_with_body) &&
1403             globus_l_ws_security_is_reference_property_element(type))
1404     {
1405 0         return GLOBUS_SUCCESS;
1406     }
1407
1408 0     idval = globus_soap_message_construct_id("id-");
1409
1410 0     result = globus_soap_message_set_marker(
1411 message_handle, idval);
1412 0     if(result != GLOBUS_SUCCESS)
1413     {
1414 0 globus_free(idval);
1415 0 result = GlobusWSSEErrorWithIdAttr(
1416     result, type);
1417 0 goto exit;
1418     }
1419
1420 0     idkey = globus_common_create_string(
1421 "{%s}%s#Id",
1422 type->Namespace,
1423 type->local);
1424
1425 0     result = globus_soap_message_handle_set_attr(
1426 message_handle,
1427 idkey,
1428 globus_soap_message_attr_copy_string,
1429 globus_libc_free,
1430 (void *)idval);
1431 0     if(result != GLOBUS_SUCCESS)
1432     {
1433 0 globus_free(idval);
1434 0 globus_free(idkey);
1435 0 result = GlobusWSSEErrorWithIdAttr(
1436     result, type);
1437 0 goto exit;
1438     }
1439
1440 0     globus_free(idval);
1441 0     globus_free(idkey);
1442
1443 0     result = globus_soap_message_attribute_ns_set(
1444 message_handle, wsseu_Id_qname.Namespace, options);
1445 0     if(result != GLOBUS_SUCCESS)
1446     {
1447 0 result = GlobusWSSEErrorWithIdAttr(
1448     result, type);
1449     }
1450
1451 exit:
1452
1453 0     GlobusWSSEDebugExit();
1454 0     return result;
1455 }
1456
1457 static
1458 globus_result_t
1459 globus_l_ws_security_reference_attr(
1460     globus_soap_message_handle_t        message_handle,
1461     const xsd_QName *                   type)
1462 0 {
1463 0     char *                              idkey;
1464 0     char *                              idval;
1465 0     globus_result_t                     result = GLOBUS_SUCCESS;
1466 0     globus_bool_t                       done_with_body;
1467 0     GlobusFuncName(globus_l_ws_security_reference_attr);
1468 0     GlobusWSSEDebugEnter();
1469
1470     /* Skip instances of reference properties in the message body */
1471 0     done_with_body = (globus_bool_t) globus_soap_message_handle_get_attr(
1472 message_handle,
1473         WSSE_DONE_WITH_BODY_KEY);
1474 0     if ((!done_with_body) &&
1475             globus_l_ws_security_is_reference_property_element(type))
1476     {
1477 0         return GLOBUS_SUCCESS;
1478     }
1479 0     idkey = globus_common_create_string(
1480 "{%s}%s#Id", 
1481 type->Namespace,
1482 type->local);
1483 0     if(!idkey)
1484     {
1485 0 result = GlobusWSSEErrorWithIdAttr(GLOBUS_SUCCESS, type);
1486 0 goto exit;
1487     }
1488
1489 0     idval = globus_soap_message_handle_get_attr(
1490 message_handle,
1491 idkey);
1492 0     if(!idval)
1493     {
1494 0 result = GlobusWSSEErrorWithIdAttr(GLOBUS_SUCCESS, type);
1495 0 goto exit;
1496     }
1497
1498 0     globus_free(idkey);
1499
1500 0     result = globus_soap_message_serialize_string_attribute(
1501 message_handle, &wsseu_Id_qname, &idval);
1502 0     if(result != GLOBUS_SUCCESS)
1503     {
1504 0 result = GlobusWSSEErrorWithIdAttr(result, type);
1505 goto exit;
1506     }
1507
1508 exit:
1509 0     GlobusWSSEDebugExit();
1510 0     return result;
1511 }
1512
1513 static
1514 globus_result_t
1515 globus_l_ws_security_reference_end(
1516     globus_soap_message_handle_t        message_handle,
1517     const xsd_QName *                   type)
1518 0 {
1519 0     char *                              idkey = NULL;
1520 0     char *                              idval;
1521 0     char *                              end_idval = NULL;
1522 0     globus_result_t                     result = GLOBUS_SUCCESS;
1523 0     globus_bool_t                       done_with_body;
1524 0     globus_list_t **                    security_attrs;
1525 0     GlobusFuncName(globus_i_ws_security_reference_end);
1526 0     GlobusWSSEDebugEnter();
1527
1528     /* Skip instances of reference properties in the message body */
1529 0     done_with_body = (globus_bool_t) globus_soap_message_handle_get_attr(
1530 message_handle,
1531         WSSE_DONE_WITH_BODY_KEY);
1532 0     if ((!done_with_body) &&
1533             globus_l_ws_security_is_reference_property_element(type))
1534     {
1535 0         return GLOBUS_SUCCESS;
1536     }
1537 0     idkey = globus_common_create_string(
1538 "{%s}%s#Id", 
1539 type->Namespace,
1540 type->local);
1541 0     if(!idkey)
1542     {
1543 0 result = GlobusWSSEErrorWithIdAttr(
1544     GLOBUS_SUCCESS, type);
1545 0 goto exit;
1546     }
1547
1548 0     idval = globus_soap_message_handle_get_attr(
1549 message_handle,
1550 idkey);
1551 0     if(!idval)
1552     {
1553 0 result = GlobusWSSEErrorWithIdAttr(
1554     GLOBUS_SUCCESS, type);
1555 0 goto exit;
1556     }
1557
1558 0     end_idval = globus_common_create_string("%s-end", idval);
1559 0     result = globus_soap_message_set_marker(
1560 message_handle, end_idval);
1561 0     if(result != GLOBUS_SUCCESS)
1562     {
1563 0 result = GlobusWSSEErrorWithIdAttr(
1564     result, type);
1565 0 goto exit;
1566     }
1567
1568 0     security_attrs = globus_soap_message_handle_get_attr(
1569 message_handle,
1570 GLOBUS_HANDLER_WSSE_TOKEN_IDS_KEY);
1571 0     globus_assert(security_attrs);
1572
1573 0     globus_list_insert(security_attrs,
1574        globus_libc_strdup(idval));
1575
1576 0     globus_soap_message_serialize_end_c14n_subset(
1577 message_handle);
1578
1579 0     if (xsd_QName_keyeq((xsd_QName *) type, &soap_body_qname))
1580     {
1581 0         result = globus_soap_message_handle_set_attr(
1582             message_handle,
1583             WSSE_DONE_WITH_BODY_KEY,
1584             NULL,
1585             NULL,
1586             (void *)1);
1587     }
1588 exit:
1589
1590 0     if(idkey)
1591     {
1592 0 globus_free(idkey);
1593     }
1594     
1595 0     if(end_idval)
1596     {
1597 0 globus_free(end_idval);
1598     }
1599     
1600 0     GlobusWSSEDebugExit();
1601 0     return result;
1602 }
1603
1604 #define GLOBUS_L_HANDLER_WSSE_ADD_CALLOUTS(__QNAME__)   \
1605     result = globus_soap_message_add_callout(           \
1606 message_handle,                                 \
1607 __QNAME__,                                      \
1608 globus_l_ws_security_reference_begin,           \
1609 globus_l_ws_security_reference_end,             \
1610 globus_l_ws_security_reference_attr);           \
1611     if(result != GLOBUS_SUCCESS)                        \
1612     {                                                   \
1613         result = GlobusWSSEErrorCalloutInit(result);    \
1614         goto exit;                                      \
1615     }                                                   \
1616                                                         \
1617     result = globus_soap_message_add_ns_callout(        \
1618 message_handle,                                 \
1619 __QNAME__,                                      \
1620 globus_l_ws_security_reference_ns_set,          \
1621 globus_l_ws_security_reference_ns_add,          \
1622 globus_l_ws_security_reference_ns_remove);      \
1623     if(result != GLOBUS_SUCCESS)                        \
1624     {                                                   \
1625         result = GlobusWSSEErrorCalloutInit(result);    \
1626         goto exit;                                      \
1627     }
1628
1629 static
1630 void
1631 globus_handler_ws_security_init(
1632     globus_handler_session_descriptor_t session,
1633     globus_soap_message_handle_t        message_handle,
1634     globus_result_t                     result)
1635 0 {
1636 0     char *                              prefix = NULL;
1637 0     char *                              idval = NULL;
1638 0     xmlDocPtr                           doc = NULL;
1639 0     globus_xml_buffer *                 xmlbuff;
1640 0     globus_list_t **                    security_attrs;
1641 0     globus_list_t *                     id_refprops = NULL;
1642 0     wsa_EndpointReferenceType *         endpoint_reference = NULL;
1643 0     wsa_EndpointReferenceType *         outbound_epr = NULL;
1644 0     GlobusFuncName(globus_handler_ws_security_init);
1645 0     GlobusWSSEDebugEnter();
1646
1647 0     if(result != GLOBUS_SUCCESS)
1648     {
1649 0 goto exit;
1650     }
1651     
1652 0     security_attrs = globus_malloc(sizeof(globus_list_t *));
1653 0     if(!security_attrs)
1654     {
1655 0 result = GlobusWSSEErrorOutOfMemory(sizeof(globus_list_t *));
1656 0 goto exit;
1657     }
1658
1659 0     *security_attrs = NULL;
1660
1661 0     result = globus_soap_message_handle_set_attr(
1662 message_handle,
1663 GLOBUS_HANDLER_WSSE_TOKEN_IDS_KEY,
1664 NULL, NULL,
1665 security_attrs);
1666 0     if(result != GLOBUS_SUCCESS)
1667     {
1668 0 result = GlobusWSSEErrorCalloutInit(result);
1669 0 goto exit;
1670     }
1671
1672 0     if(globus_soap_message_handle_get_attr(
1673     message_handle,
1674     WS_SECMESS_INIT_ALREADY_INVOKED))
1675     {
1676 0 goto exit;
1677     }
1678
1679 0     GLOBUS_L_HANDLER_WSSE_ADD_CALLOUTS(&soap_body_qname);
1680 0     GLOBUS_L_HANDLER_WSSE_ADD_CALLOUTS(&wsa_MessageID_qname);
1681 0     GLOBUS_L_HANDLER_WSSE_ADD_CALLOUTS(&wsa_RelatesTo_qname);
1682 0     GLOBUS_L_HANDLER_WSSE_ADD_CALLOUTS(&wsa_ReplyTo_qname);
1683 0     GLOBUS_L_HANDLER_WSSE_ADD_CALLOUTS(&wsa_From_qname);
1684 0     GLOBUS_L_HANDLER_WSSE_ADD_CALLOUTS(&wsa_FaultTo_qname);
1685 0     GLOBUS_L_HANDLER_WSSE_ADD_CALLOUTS(&wsa_To_qname);
1686 0     GLOBUS_L_HANDLER_WSSE_ADD_CALLOUTS(&wsa_Action_qname);
1687 0     GLOBUS_L_HANDLER_WSSE_ADD_CALLOUTS(&wsseu_Timestamp_qname);
1688
1689     /* are we server side? */
1690 0     if(!globus_soap_message_handle_get_attr(
1691     message_handle,
1692     GLOBUS_SOAP_MESSAGE_SERVICE_ENDPOINT_KEY))
1693     {
1694
1695 0 endpoint_reference = (wsa_EndpointReferenceType *)
1696     globus_soap_message_handle_get_attr(
1697 message_handle, WSADDR_EPR_KEY);
1698 0 if(endpoint_reference)
1699 {
1700 0     result = globus_soap_message_handle_set_attr(
1701 message_handle,
1702 WSADDR_OUTBOUND_EPR_KEY,
1703 wsa_EndpointReferenceType_copy_wrapper,
1704 wsa_EndpointReferenceType_destroy_wrapper,
1705 endpoint_reference);
1706 0     if(result != GLOBUS_SUCCESS)
1707     {
1708 0 result = GlobusWSSEErrorCalloutInit(result);
1709 0 goto exit;
1710     }
1711
1712 0     outbound_epr = (wsa_EndpointReferenceType *)
1713 globus_soap_message_handle_get_attr(
1714     message_handle, WSADDR_OUTBOUND_EPR_KEY);
1715 }
1716     }
1717
1718 0     id_refprops = globus_soap_message_handle_remove_attr(
1719 message_handle,
1720 GLOBUS_L_HANDLER_WSSE_REFERENCE_PROPS_KEY);
1721 0     if(id_refprops)
1722     {
1723 0         globus_l_handler_wsse_id_refprops_destroy(id_refprops);
1724 0 id_refprops = NULL;
1725     }
1726
1727     /* inject Id attr into RefProps */
1728 0     if(outbound_epr && outbound_epr->ReferenceProperties)
1729     {
1730 0 wsa_ReferencePropertiesType * props;
1731 0 int i = 0;
1732
1733 0 props = outbound_epr->ReferenceProperties;
1734 0 for(; i < props->any.length; ++i)
1735 {
1736 0     if(props->any.elements[i].any_info ==
1737        (&globus_xml_buffer_info) ||
1738        props->any.elements[i].any_info ==
1739        (&globus_xml_buffer_contents_info))
1740     {
1741 0 char *                      new_buff;
1742 0 int                         new_length;
1743 0 int                         created = 0;
1744 0 xmlNsPtr                    ns = NULL;
1745 0 globus_l_handler_wsse_id_refprop_t * id_refprop;
1746
1747 0 xmlbuff =
1748     (globus_xml_buffer *)props->any.elements[i].value;
1749
1750 0 idval = globus_soap_message_construct_id("id-");
1751 0 doc = xmlRecoverMemory(xmlbuff->buffer, xmlbuff->length);
1752
1753 0 prefix = globus_soap_message_serialize_lookup_prefix(
1754     message_handle, wsseu_Id_qname.Namespace, &created);
1755
1756 0 ns = xmlNewNs(doc->children, 
1757       wsseu_Id_qname.Namespace,
1758       prefix);
1759
1760 0                 xmlUnsetNsProp(doc->children, 
1761        ns, 
1762        (const xmlChar *)wsseu_Id_qname.local);
1763
1764 0                 xmlNewNsProp(doc->children,
1765      ns,
1766      wsseu_Id_qname.local,
1767      idval);
1768 0 new_length = xmlC14NDocDumpMemory(
1769     doc, NULL, 1, NULL, 0, (xmlChar **)&new_buff); 
1770 0 if(new_length < 0)
1771 {
1772 0     result = GlobusWSSEErrorCalloutInit(result);
1773 0     goto exit;
1774 }
1775
1776 0 if(xmlbuff->buffer)
1777 {
1778 0     globus_free(xmlbuff->buffer);
1779 }
1780 0 xmlbuff->buffer = new_buff;
1781 0 xmlbuff->length = new_length;
1782
1783 0 id_refprop = globus_malloc(
1784     sizeof(globus_l_handler_wsse_id_refprop_t));
1785 0 if(!id_refprop)
1786 {
1787 0     result = GlobusWSSEErrorOutOfMemory(
1788 sizeof(globus_l_handler_wsse_id_refprop_t));
1789 0     goto exit;
1790 }
1791
1792 0 result = globus_xml_buffer_copy(
1793     &id_refprop->xml_buffer, xmlbuff);
1794 0 if(result != GLOBUS_SUCCESS)
1795 {
1796 0     result = GlobusWSSEErrorCalloutInit(result);
1797 0     goto exit;
1798 }
1799
1800 0 id_refprop->id = idval;
1801 0 idval = NULL;
1802
1803 0 globus_list_insert(&id_refprops, (void *)id_refprop);
1804
1805 0 if(doc)
1806 {
1807 0     xmlFreeDoc(doc);
1808 0     doc = NULL;
1809 }
1810
1811 0 if(prefix)
1812 {
1813 0     globus_free(prefix);
1814 0     prefix = NULL;
1815 }
1816     }
1817     else
1818     {
1819 0 GLOBUS_L_HANDLER_WSSE_ADD_CALLOUTS(
1820     props->any.elements[i].element);
1821     }
1822 }
1823     }
1824    
1825 0     if(id_refprops)
1826     {
1827 0 globus_soap_message_handle_set_attr(
1828     message_handle,
1829     GLOBUS_L_HANDLER_WSSE_REFERENCE_PROPS_KEY, 
1830     globus_l_handler_wsse_id_refprops_copy,
1831     globus_l_handler_wsse_id_refprops_destroy,
1832     id_refprops);
1833     }
1834
1835 0     globus_soap_message_handle_set_attr(
1836 message_handle,
1837 WS_SECMESS_INIT_ALREADY_INVOKED,
1838 NULL, NULL, (void *)1);
1839     
1840 exit:
1841
1842 0     if(id_refprops)
1843     {
1844 0 globus_l_handler_wsse_id_refprops_destroy(id_refprops);
1845     }
1846
1847 0     if(idval)
1848     {
1849 0 globus_free(idval);
1850     }
1851
1852 0     if(doc)
1853     {
1854 0 xmlFreeDoc(doc);
1855     }
1856
1857 0     if(prefix)
1858     {
1859 0 globus_free(prefix);
1860     }
1861
1862 0     globus_handler_finished(session, result);
1863 0     GlobusWSSEDebugExit();
1864 0     return;
1865 }
1866
1867 static
1868 void
1869 globus_handler_ws_security_destroy(
1870     globus_handler_session_descriptor_t session,
1871     globus_soap_message_handle_t        message_handle,
1872     globus_result_t                     result)
1873 0 {
1874 0     globus_list_t **                    security_attrs;
1875 0     wsa_EndpointReferenceType *         outbound_epr = NULL;
1876
1877 0     GlobusFuncName(globus_handler_ws_security_destroy);
1878 0     GlobusWSSEDebugEnter();
1879
1880 0     if(result != GLOBUS_SUCCESS)
1881     {
1882 0 goto exit;
1883     }
1884
1885 0     security_attrs = globus_soap_message_handle_remove_attr(
1886 message_handle, GLOBUS_HANDLER_WSSE_TOKEN_IDS_KEY);
1887 0     if(security_attrs)
1888     {
1889 0 globus_list_destroy_all(*security_attrs, globus_libc_free);
1890 0         globus_free(security_attrs);
1891     }
1892
1893 0     globus_soap_message_remove_callouts(message_handle, &soap_body_qname);
1894 0     globus_soap_message_remove_callouts(message_handle, &wsa_MessageID_qname);
1895 0     globus_soap_message_remove_callouts(message_handle, &wsa_RelatesTo_qname);
1896 0     globus_soap_message_remove_callouts(message_handle, &wsa_From_qname);
1897 0     globus_soap_message_remove_callouts(message_handle, &wsa_ReplyTo_qname);
1898 0     globus_soap_message_remove_callouts(message_handle, &wsa_FaultTo_qname);
1899 0     globus_soap_message_remove_callouts(message_handle, &wsa_To_qname);
1900 0     globus_soap_message_remove_callouts(message_handle, &wsa_Action_qname);
1901 0     globus_soap_message_remove_callouts(
1902 message_handle, &wsseu_Timestamp_qname);
1903
1904 0     outbound_epr = globus_soap_message_handle_get_attr(
1905         message_handle,
1906         WSADDR_OUTBOUND_EPR_KEY);
1907
1908     /* remove callouts for outbound epr reference property elements */
1909 0     if(outbound_epr && outbound_epr->ReferenceProperties)
1910     {
1911 0 wsa_ReferencePropertiesType * props;
1912 0 int i = 0;
1913
1914 0 props = outbound_epr->ReferenceProperties;
1915 0 for(; i < props->any.length; ++i)
1916 {
1917 0     if((props->any.elements[i].any_info !=
1918        (&globus_xml_buffer_info)) &&
1919        (props->any.elements[i].any_info !=
1920        (&globus_xml_buffer_contents_info)))
1921     {
1922 0                 globus_soap_message_remove_callouts(
1923                     message_handle, props->any.elements[i].element);
1924     }
1925 }
1926     }
1927
1928 exit:
1929
1930 0     globus_handler_finished(session, result);
1931 0     GlobusWSSEDebugExit();
1932 0     return;
1933 }
1934
1935 static                        
1936 void
1937 globus_handler_ws_security_client_request_invoke(
1938     globus_handler_session_descriptor_t session,
1939     globus_soap_message_handle_t        message_handle,
1940     globus_result_t                     result)
1941 0 {
1942 0     GlobusFuncName(globus_handler_ws_security_client_request_invoke);
1943 0     GlobusWSSEDebugEnter();
1944
1945 0     if(result != GLOBUS_SUCCESS)
1946     {
1947 0 goto exit;
1948     }
1949
1950 0     if(globus_soap_message_handle_get_attr(
1951     message_handle,
1952     WS_SECMESS_CLIENT_REQUEST_ALREADY_INVOKED))
1953     {
1954 0 goto exit;
1955     }
1956
1957 0     result = globus_handler_ws_security_sign_message(
1958 message_handle);
1959 0     if(result != GLOBUS_SUCCESS)
1960     {
1961 0 result = GlobusWSSEErrorFailedClientRequest(result);
1962 0 goto exit;
1963     }
1964
1965 0     globus_soap_message_handle_set_attr(
1966 message_handle,
1967 WS_SECMESS_CLIENT_REQUEST_ALREADY_INVOKED,
1968 NULL, NULL, (void *)1);
1969
1970 exit:
1971
1972 0     globus_handler_finished(session, result);
1973 0     GlobusWSSEDebugExit();
1974 0     return;
1975 }
1976
1977 static                        
1978 void
1979 globus_handler_ws_security_client_response_trigger(
1980     globus_handler_session_descriptor_t session,
1981     globus_soap_message_handle_t        message_handle,
1982     globus_result_t                     result)
1983 0 {
1984 0     GlobusFuncName(globus_handler_ws_security_client_response_trigger);
1985 0     GlobusWSSEDebugEnter();
1986
1987 0     if(result != GLOBUS_SUCCESS)
1988     {
1989 0 goto exit;
1990     }
1991
1992 0     result = globus_handler_ws_security_verify_message(
1993 message_handle);
1994 0     if(result != GLOBUS_SUCCESS)
1995     {
1996 0 result = GlobusWSSEErrorFailedClientRequest(result);
1997 0 goto exit;
1998     }
1999
2000 0     result = globus_soap_message_remove_required_header_element(
2001 message_handle, &wsse_Security_qname);
2002 0     if(result != GLOBUS_SUCCESS)
2003     {
2004 0 result = GlobusWSSEErrorFailedClientRequest(result);
2005 goto exit;
2006     }
2007
2008 exit:
2009
2010 0     globus_handler_finished(session, result);
2011 0     GlobusWSSEDebugExit();
2012 0     return;
2013 }
2014
2015 static                        
2016 void
2017 globus_handler_ws_security_client_response_invoke(
2018     globus_handler_session_descriptor_t session,
2019     globus_soap_message_handle_t        message_handle,
2020     globus_result_t                     result)
2021 0 {
2022 0     GlobusFuncName(globus_handler_ws_security_client_response_invoke);
2023 0     GlobusWSSEDebugEnter();
2024
2025 0     if(result != GLOBUS_SUCCESS)
2026     {
2027 0 goto exit;
2028     }
2029
2030 0     if(globus_soap_message_handle_get_attr(
2031     message_handle,
2032     WS_SECMESS_CLIENT_RESPONSE_ALREADY_INVOKED))
2033     {
2034 0 goto exit;
2035     }
2036     
2037 0     result = globus_handler_ws_security_verify_message_references(
2038 message_handle);
2039 0     if(result != GLOBUS_SUCCESS)
2040     {
2041 0 result = GlobusWSSEErrorFailedClientResponse(result);
2042 0 goto exit;
2043     }
2044
2045 0     globus_soap_message_handle_set_attr(
2046 message_handle,
2047 WS_SECMESS_CLIENT_RESPONSE_ALREADY_INVOKED,
2048 NULL, NULL, (void *)1);
2049
2050 exit:
2051
2052 0     globus_handler_finished(session, result);
2053 0     GlobusWSSEDebugExit();
2054 0     return;
2055 }
2056
2057 static                        
2058 void
2059 globus_handler_ws_security_server_response_invoke(
2060     globus_handler_session_descriptor_t session,
2061     globus_soap_message_handle_t        message_handle,
2062     globus_result_t                     result)
2063 0 {
2064 0     GlobusFuncName(globus_handler_ws_security_server_response_invoke);
2065 0     GlobusWSSEDebugEnter();
2066
2067 0     if(result != GLOBUS_SUCCESS)
2068     {
2069 0 goto exit;
2070     }
2071
2072 0     if(globus_soap_message_handle_get_attr(
2073     message_handle,
2074     WS_SECMESS_SERVER_RESPONSE_ALREADY_INVOKED))
2075     {
2076 0 goto exit;
2077     }
2078     
2079 0     result = globus_handler_ws_security_sign_message(
2080 message_handle);
2081 0     if(result != GLOBUS_SUCCESS)
2082     {
2083 0 result = GlobusWSSEErrorFailedServerResponse(result);
2084 0 goto exit;
2085     }
2086
2087 0     globus_soap_message_handle_set_attr(
2088 message_handle,
2089 WS_SECMESS_SERVER_RESPONSE_ALREADY_INVOKED,
2090 NULL, NULL, (void *)1);
2091    
2092 exit:
2093
2094 0     globus_handler_finished(session, result);
2095 0     GlobusWSSEDebugExit();
2096 0     return;
2097 }
2098
2099 static                        
2100 void
2101 globus_handler_ws_security_server_request_trigger(
2102     globus_handler_session_descriptor_t session,
2103     globus_soap_message_handle_t        message_handle,
2104     globus_result_t                     result)
2105 0 {
2106 0     GlobusFuncName(globus_handler_ws_security_server_request_trigger);
2107 0     GlobusWSSEDebugEnter();
2108
2109 0     if(result != GLOBUS_SUCCESS)
2110     {
2111 0 goto exit;
2112     }
2113
2114 0     result = globus_handler_ws_security_verify_message(
2115 message_handle);
2116 0     if(result != GLOBUS_SUCCESS)
2117     {
2118 0 result = GlobusWSSEErrorFailedClientRequest(result);
2119 0 goto exit;
2120     }
2121
2122 0     result = globus_soap_message_remove_required_header_element(
2123 message_handle, &wsse_Security_qname);
2124 0     if(result != GLOBUS_SUCCESS)
2125     {
2126 0 result = GlobusWSSEErrorFailedClientRequest(result);
2127 goto exit;
2128     }
2129
2130 exit:
2131
2132 0     globus_handler_finished(session, result);
2133 0     GlobusWSSEDebugExit();
2134 0     return;
2135 }
2136
2137 static                        
2138 void
2139 globus_handler_ws_security_server_request_invoke(
2140     globus_handler_session_descriptor_t session,
2141     globus_soap_message_handle_t        message_handle,
2142     globus_result_t                     result)
2143 0 {
2144 0     GlobusFuncName(globus_handler_ws_security_server_request_invoke);
2145 0     GlobusWSSEDebugEnter();
2146
2147 0     if(result != GLOBUS_SUCCESS)
2148     {
2149 0 goto exit;
2150     }
2151
2152 0     if(globus_soap_message_handle_get_attr(
2153     message_handle,
2154     WS_SECMESS_SERVER_REQUEST_ALREADY_INVOKED))
2155     {
2156 0 goto exit;
2157     }
2158     
2159 0     result = globus_handler_ws_security_verify_message_references(
2160 message_handle);
2161 0     if(result != GLOBUS_SUCCESS)
2162     {
2163 0 result = GlobusWSSEErrorFailedServerRequest(result);
2164 0 goto exit;
2165     }
2166
2167 0     globus_soap_message_handle_set_attr(
2168 message_handle,
2169 WS_SECMESS_SERVER_REQUEST_ALREADY_INVOKED,
2170 NULL, NULL, (void *)1);
2171     
2172 exit:
2173
2174 0     globus_handler_finished(session, result);
2175 }
2176
2177 globus_handler_trigger_t globus_l_handler_ws_security_client_trigger =
2178 {
2179     &wsse_Security_qname,
2180     globus_handler_ws_security_client_response_trigger
2181 };
2182
2183 globus_handler_descriptor_t globus_l_handler_ws_security_client_descriptor = 
2184 {
2185     globus_handler_ws_security_init, 
2186     globus_handler_ws_security_client_request_invoke,
2187     globus_handler_ws_security_destroy,
2188     NULL,
2189     globus_handler_ws_security_client_response_invoke,
2190     NULL,
2191     NULL,
2192     NULL
2193 };
2194
2195 globus_handler_trigger_t globus_l_handler_ws_security_server_trigger =
2196 {
2197     &wsse_Security_qname,
2198     globus_handler_ws_security_server_request_trigger
2199 };
2200
2201 globus_handler_descriptor_t globus_l_handler_ws_security_server_descriptor = 
2202 {
2203     NULL,
2204     globus_handler_ws_security_server_request_invoke,
2205     NULL,
2206     globus_handler_ws_security_init,
2207     globus_handler_ws_security_server_response_invoke,
2208     globus_handler_ws_security_destroy,
2209     NULL,
2210     NULL
2211 };
2212
2213 GlobusExtensionDefineModule(globus_handler_ws_security) =
2214 {
2215     GLOBUS_HANDLER_WS_SECMESS_LIB,
2216     globus_l_handler_ws_security_activate,
2217     globus_l_handler_ws_security_deactivate,
2218     NULL,
2219     NULL,
2220     &local_version
2221 };
2222
2223 int
2224 globus_l_handler_ws_security_activate(void)
2225 0 {
2226 0     int                                 res = 0;
2227 0     GlobusFuncName(globus_l_handler_ws_security_activate);
2228
2229 0     GlobusDebugInit(GLOBUS_HANDLER_WS_SECURE_MESSAGE, 
2230     TRACE DEBUG PKIPATH C14N SIGN VERIFY);
2231 0     GlobusWSSEDebugEnter();
2232
2233 0     globus_l_handler_ws_security_client_descriptor.trigger_list = NULL;
2234 0     globus_l_handler_ws_security_server_descriptor.trigger_list = NULL;
2235
2236 0     globus_i_handler_wsse_cred_pkipath_table_init();
2237
2238 0     globus_list_insert(
2239 &globus_l_handler_ws_security_client_descriptor.trigger_list,
2240 &globus_l_handler_ws_security_client_trigger);
2241
2242 0     res = globus_extension_registry_add(
2243 GLOBUS_HANDLER_REGISTRY,
2244 GLOBUS_HANDLER_WS_SECMESS_CLIENT,
2245 GlobusExtensionMyModule(globus_handler_ws_security),
2246 &globus_l_handler_ws_security_client_descriptor);
2247 0     if(res != GLOBUS_SUCCESS)
2248     {
2249 0 goto exit;
2250     }
2251
2252 0     globus_list_insert(
2253 &globus_l_handler_ws_security_server_descriptor.trigger_list,
2254 &globus_l_handler_ws_security_server_trigger);
2255
2256 0     res = globus_extension_registry_add(
2257 GLOBUS_HANDLER_REGISTRY,
2258 GLOBUS_HANDLER_WS_SECMESS_SERVER,
2259 GlobusExtensionMyModule(globus_handler_ws_security),
2260 &globus_l_handler_ws_security_server_descriptor);
2261
2262 0     res = globus_xsd_type_registry_insert(
2263 GLOBUS_GLOBAL_TYPE_REGISTRY,
2264 &wsse_BinarySecurityToken_info,
2265 NULL);
2266 0     if(res != GLOBUS_SUCCESS)
2267     {
2268 0 goto exit;
2269     }
2270
2271 0     res = globus_xsd_type_registry_insert(
2272 GLOBUS_GLOBAL_TYPE_REGISTRY,
2273 &ds_Signature_info,
2274 NULL);
2275 0     if(res != GLOBUS_SUCCESS)
2276     {
2277 0 goto exit;
2278     }
2279
2280 0     res = globus_xsd_type_registry_insert(
2281 GLOBUS_GLOBAL_TYPE_REGISTRY,
2282 &wsseu_Timestamp_info,
2283 NULL);
2284 0     if(res != GLOBUS_SUCCESS)
2285     {
2286 0 goto exit;
2287     }
2288
2289 0     res = globus_xsd_type_registry_insert(
2290 GLOBUS_GLOBAL_TYPE_REGISTRY,
2291 &wsse_SecurityTokenReference_info,
2292 NULL);
2293 0     if(res != GLOBUS_SUCCESS)
2294     {
2295 0 goto exit;
2296     }
2297
2298 0     res = globus_xsd_type_registry_insert(
2299 GLOBUS_GLOBAL_TYPE_REGISTRY,
2300 &ds_Reference_info,
2301 NULL);
2302 0     if(res != GLOBUS_SUCCESS)
2303     {
2304 0 goto exit;
2305     }
2306
2307 0     res = globus_xsd_type_registry_insert(
2308 GLOBUS_GLOBAL_TYPE_REGISTRY,
2309 &exc_c14n_InclusiveNamespaces_info,
2310 NULL);
2311 0     if(res != GLOBUS_SUCCESS)
2312     {
2313 0 goto exit;
2314     }
2315
2316 exit:
2317
2318 0     GlobusWSSEDebugExit();
2319 0     return res;
2320 }
2321
2322     int
2323 globus_l_handler_ws_security_deactivate(void)
2324 0 {
2325 0     GlobusFuncName(globus_l_handler_ws_security_deactivate);
2326 0     GlobusWSSEDebugEnter();
2327
2328 0     globus_extension_registry_remove(
2329 GLOBUS_HANDLER_REGISTRY,
2330 GLOBUS_HANDLER_WS_SECMESS_CLIENT);
2331
2332 0     globus_extension_registry_remove(
2333 GLOBUS_HANDLER_REGISTRY,
2334 GLOBUS_HANDLER_WS_SECMESS_SERVER);
2335
2336 0     globus_i_handler_wsse_cred_pkipath_table_destroy();
2337
2338 0     GlobusWSSEDebugExit();
2339 0     return 0;
2340 }
2341
2342 static
2343 globus_result_t
2344 globus_i_handler_ws_security_compute_digest(
2345     const char *                        buff,
2346     size_t                              buff_length,
2347     char **                             digest_value,
2348     size_t *                            digest_length)
2349 0 {
2350 0     globus_result_t                     result = GLOBUS_SUCCESS;
2351 0     char *                              digest;
2352 0     char *                              c14n_buff;
2353 0     size_t                              c14n_buff_length;
2354 0     GlobusFuncName(globus_i_handler_ws_security_compute_digest);
2355 0     GlobusWSSEDebugEnter();
2356
2357 0     GlobusWSSEDebugPrintf(
2358 GLOBUS_L_WS_SECURITY_DEBUG_C14N,
2359 ("-----INLINED C14N (length: %d)-----\n%.*s\n"
2360  "---------------------------------------------\n", 
2361  buff_length, buff_length, buff));
2362
2363 0     c14n_buff = (char *)buff;
2364 0     c14n_buff_length = buff_length;
2365
2366 #ifndef GLOBUS_HANDLER_WSSE_INLINED_C14N
2367 0     result = globus_i_handler_ws_security_c14n_buffer(
2368 buff,
2369 buff_length,
2370 &c14n_buff,
2371 &c14n_buff_length);
2372 0     if(result != GLOBUS_SUCCESS)
2373     {
2374 0 result = GlobusWSSEErrorFailedSign(result);
2375 0 goto exit;
2376     }
2377
2378 0     GlobusWSSEDebugPrintf(
2379 GLOBUS_L_WS_SECURITY_DEBUG_C14N,
2380 ("-----COMPUTED C14N (length: %d)-----\n%.*s\n"
2381  "---------------------------------------------\n", 
2382  c14n_buff_length, c14n_buff_length, 
2383  c14n_buff));
2384 #endif
2385
2386     /* compute SHA1 digest */
2387 0     digest = globus_malloc(SHA_DIGEST_LENGTH);
2388 0     if(!digest)
2389     {
2390 0 result = GlobusWSSEErrorOutOfMemory(SHA_DIGEST_LENGTH);
2391 0 globus_free(c14n_buff);
2392 0 goto exit;
2393     }
2394
2395 0     if(SHA1(c14n_buff, c14n_buff_length, 
2396     digest) == NULL)
2397     {
2398 0 result = GlobusWSSEErrorOpenSSL(
2399     "Failed to compute SHA1 digest");
2400 0 globus_free(digest);
2401 0 globus_free(c14n_buff);
2402 0 goto exit;
2403     }
2404
2405 #ifndef GLOBUS_HANDLER_WSSE_INLINED_C14N
2406 0     globus_free(c14n_buff);
2407 #endif
2408
2409 0     if(digest_length)
2410     {
2411 0 *digest_length = SHA_DIGEST_LENGTH;
2412     }
2413
2414 0     *digest_value = digest;
2415
2416 exit:
2417
2418 0     GlobusWSSEDebugExit();
2419 0     return result;
2420 }
2421
2422 static
2423 globus_result_t
2424 globus_i_handler_ws_security_verify_digest(
2425     const char *                        buff,
2426     size_t                              buff_length,
2427     const char *                        digest_value,
2428     size_t                              digest_length)
2429 0 {
2430 0     globus_result_t                     result = GLOBUS_SUCCESS;
2431 0     char *                              digest;
2432 0     GlobusFuncName(globus_i_handler_ws_security_verify_digest);
2433 0     GlobusWSSEDebugEnter();
2434
2435 0     GlobusWSSEDebugPrintf(
2436 GLOBUS_L_WS_SECURITY_DEBUG_VERIFY,
2437 ("-----------------DIGEST BUFFER (length: %d)--------------\n%.*s\n"
2438  "=====================================================\n\n",
2439  buff_length, buff_length, buff));
2440
2441 0     if(digest_length != SHA_DIGEST_LENGTH)
2442     {
2443 0 result = GlobusWSSEErrorFailedDigestVerify(result);
2444 0 goto exit;
2445     }
2446
2447 0     digest = globus_malloc(SHA_DIGEST_LENGTH);
2448 0     memset(digest, 0, SHA_DIGEST_LENGTH);
2449
2450 0     if(SHA1(buff, buff_length,
2451     digest) == NULL)
2452     {
2453 0 result = GlobusWSSEErrorOpenSSL(
2454     "Could not compute SHA1 digest");
2455 0 result = GlobusWSSEErrorFailedDigestVerify(
2456     result);
2457 0 goto exit;
2458     }
2459
2460 0     if(memcmp(digest, digest_value, SHA_DIGEST_LENGTH))
2461     {
2462 0 globus_free(digest);
2463 0 result = GlobusWSSEErrorFailedDigestVerify(
2464     result);
2465 0 goto exit;
2466     }
2467
2468 0     globus_free(digest);
2469
2470 exit:
2471
2472 0     GlobusWSSEDebugExit();
2473 0     return result;
2474 }
2475
2476 static
2477 globus_result_t
2478 globus_i_handler_ws_security_verify_signature(
2479     globus_gsi_cred_handle_t            cred,
2480     const unsigned char *               input_buff,
2481     size_t                              input_length,
2482     const unsigned char *               signed_buff,
2483     size_t                              signed_buff_length)
2484 0 {
2485 0     EVP_MD_CTX                          rsa_sha1_evp;
2486 0     globus_result_t                     result = GLOBUS_SUCCESS;
2487 0     int                                 res = 0;
2488 0     X509 *                              peer_cert;
2489 0     EVP_PKEY *                          pubkey;
2490 0     GlobusFuncName(globus_i_handler_ws_security_verify_signature);
2491 0     GlobusWSSEDebugEnter();
2492
2493 0     if(EVP_VerifyInit(&rsa_sha1_evp, EVP_sha1()) == 0)
2494     {
2495 0 result = GlobusWSSEErrorOpenSSL(
2496     "Failed to verify the RSA-SHA1 signature");
2497 0 goto exit;
2498     }
2499
2500 0     if(EVP_VerifyUpdate(&rsa_sha1_evp,
2501 input_buff,
2502 input_length) == 0)
2503     {
2504 0 result = GlobusWSSEErrorOpenSSL(
2505     "Failed to verify the RSA-SHA1 signature");
2506 0 goto evp_free;
2507     }
2508
2509 0     result = globus_gsi_cred_get_cert(cred, &peer_cert);
2510 0     if(result != GLOBUS_SUCCESS)
2511     {
2512 0 result = GlobusWSSEErrorFailedSignatureVerify();
2513 0 goto evp_free;
2514     }
2515
2516 0     pubkey = X509_get_pubkey(peer_cert);
2517 0     res = EVP_VerifyFinal(
2518 &rsa_sha1_evp,
2519 (unsigned char *)signed_buff,
2520 signed_buff_length,
2521 pubkey);
2522 0     if(res == 0)
2523     {
2524 0 result = GlobusWSSEErrorFailedSignatureVerify();
2525 0 goto peer_cert_free;
2526     }
2527 0     else if(res < 0)
2528     {
2529 0 result = GlobusWSSEErrorOpenSSL(
2530     "Failed to verify the RSA-SHA1 signature");
2531 goto peer_cert_free;
2532     }
2533
2534 peer_cert_free:
2535
2536 0     EVP_PKEY_free(pubkey);
2537 0     X509_free(peer_cert);
2538
2539 evp_free:
2540
2541 0     EVP_MD_CTX_cleanup(&rsa_sha1_evp);
2542
2543 exit:
2544
2545 0     GlobusWSSEDebugExit();
2546 0     ERR_clear_error();
2547 0     return result;
2548 }
2549
2550 static
2551 globus_result_t
2552 globus_i_handler_ws_security_compute_signature(
2553     globus_gsi_cred_handle_t            cred,
2554     const char *                        input_buff,
2555     size_t                              input_length,
2556     char **                             signed_buff,
2557     size_t *                            signed_buff_length)
2558 0 {
2559 0     EVP_MD_CTX                          rsa_sha1_evp;
2560 0     EVP_PKEY *                          user_key = NULL;
2561 0     char *                              c14n_buff = NULL;
2562 0     const char *                        compute_buff;
2563 0     size_t                              compute_length;
2564 0     char *                              signature_value_buff;
2565 0     size_t                              signature_value_buff_length;
2566 0     globus_result_t                     result = GLOBUS_SUCCESS;
2567 #ifndef GLOBUS_HANDLER_WSSE_INLINED_C14N
2568 0     size_t                              c14n_buff_length = 0;
2569 #endif
2570 0     GlobusFuncName(globus_i_handler_ws_security_compute_signature);
2571 0     GlobusWSSEDebugEnter();
2572
2573 0     GlobusWSSEDebugPrintf(
2574 GLOBUS_L_WS_SECURITY_DEBUG_C14N,
2575 ("-----INLINED C14N (length: %d)-----\n%.*s\n"
2576  "----------------------------------------\n", 
2577  input_length, input_length, input_buff));
2578
2579 0     compute_buff = input_buff;
2580 0     compute_length = input_length;
2581
2582 #ifndef GLOBUS_HANDLER_WSSE_INLINED_C14N
2583 0     result = globus_i_handler_ws_security_c14n_buffer(
2584 input_buff,
2585 input_length,
2586 &c14n_buff,
2587 &c14n_buff_length);
2588 0     if(result != GLOBUS_SUCCESS)
2589     {
2590 0 result = GlobusWSSEErrorFailedSign(result);
2591 0 goto exit;
2592     }
2593
2594 0     GlobusWSSEDebugPrintf(
2595 GLOBUS_L_WS_SECURITY_DEBUG_C14N,
2596 ("-----COMPUTED C14N (length: %d)-----\n%.*s\n"
2597  "----------------------------------------\n", 
2598  c14n_buff_length, 
2599  c14n_buff_length, 
2600  c14n_buff));
2601
2602 0     compute_buff = c14n_buff;
2603 0     compute_length = c14n_buff_length;
2604 #endif
2605
2606 0     if(EVP_SignInit(&rsa_sha1_evp, 
2607     EVP_sha1()) == 0)
2608     {
2609 0 result = GlobusWSSEErrorOpenSSL(
2610     "Could not initialize openssl signing context");
2611 0 goto exit;
2612     }
2613
2614 0     if(EVP_SignUpdate(&rsa_sha1_evp, 
2615       compute_buff, 
2616       compute_length) == 0)
2617     {
2618 0 result = GlobusWSSEErrorOpenSSL(
2619     "Could not update openssl signing context "
2620     "with content");
2621 0 goto evp_free;
2622     }
2623
2624 0     result = globus_gsi_cred_get_key(
2625 cred, &user_key);
2626 0     if(result != GLOBUS_SUCCESS)
2627     {
2628 0 result = GlobusWSSEErrorFailedSign(result);
2629 0 goto evp_free;
2630     }
2631
2632 0     signature_value_buff = globus_malloc(EVP_PKEY_size(user_key));
2633 0     if(EVP_SignFinal(&rsa_sha1_evp,
2634      signature_value_buff,
2635      (unsigned int *)&signature_value_buff_length,
2636      user_key) == 0)
2637     {
2638 0 result = GlobusWSSEErrorOpenSSL(
2639     "Could not sign content");
2640 0 goto user_key_free;
2641     }
2642
2643 0     *signed_buff = signature_value_buff;
2644 0     *signed_buff_length = EVP_PKEY_size(user_key);
2645
2646 user_key_free:
2647
2648 0     EVP_PKEY_free(user_key);
2649
2650 evp_free:
2651
2652 0     EVP_MD_CTX_cleanup(&rsa_sha1_evp);
2653
2654 exit:
2655
2656 0     if(c14n_buff)
2657     {
2658 0 globus_free(c14n_buff);
2659     }
2660
2661 0     GlobusWSSEDebugExit();
2662 0     return result;
2663 }
2664
2665 static
2666 globus_result_t
2667 globus_i_handler_ws_security_verify_references(
2668     globus_soap_message_handle_t        message_handle,
2669     ds_ReferenceType_array *            reference_array)
2670 0 {
2671 0     char *                              buffer;
2672 0     size_t                              length;
2673 0     char *                              id;
2674 0     char *                              idend;
2675 0     int                                 i = 0;
2676 0     xmlNodePtr                          referenced_node = NULL;
2677 0     xmlDocPtr                           referenced_doc = NULL;
2678 0     xmlChar **                          inc_ns_prefixes = NULL;
2679 0     xmlDocPtr                           doc = NULL;
2680 0     globus_result_t                     result = GLOBUS_SUCCESS;
2681 0     GlobusFuncName(globus_i_handler_ws_security_verify_references);
2682 0     GlobusWSSEDebugEnter();
2683
2684 0     for(i = 0; i < reference_array->length; ++i)
2685     {
2686 0 if(reference_array->elements[i]._URI)
2687 {
2688 0     if(**reference_array->elements[i]._URI == '#')
2689     {
2690 0 id = (*reference_array->elements[i]._URI) + 1;
2691 0 idend = globus_common_create_string("%s-end", id);
2692
2693 0 result = globus_soap_message_get_marked_buffers(
2694     message_handle, id, idend, &buffer, &length);
2695 0 if(result != GLOBUS_SUCCESS)
2696 {
2697 0     result = GlobusWSSEErrorFailedIdBufferGet(
2698 result, id);
2699 0     globus_free(idend);
2700 0     goto exit;
2701 }
2702
2703 0 globus_free(idend);
2704
2705 /* check Transform Algorithm type and IncNS for exc c14n */
2706 /* At somepoint this could be a callout to do transform 
2707    based on Algorithm type */
2708
2709 /* compute c14n */
2710
2711 /* check DigestMethod */
2712 /* At some point this could be a callout to do Digest
2713    based on Digest Algorithm */
2714
2715 0 result = globus_i_handler_ws_security_verify_digest(
2716     buffer, length, 
2717     reference_array->elements[i].DigestValue.value,
2718     reference_array->elements[i].DigestValue.length);
2719 0 if(result != GLOBUS_SUCCESS)
2720 {
2721 0     char *              output_buff = NULL;
2722 0     int                 res = 0;
2723 0     char *              soap_message_buff = NULL;
2724 0     int                 soap_message_buff_length = 0;
2725
2726 0     GlobusWSSEDebugPrintf(
2727 GLOBUS_L_WS_SECURITY_DEBUG_VERIFY,
2728 ("========== INLINED DIGEST "
2729  "VERIFY FAILED (id: %s) ========\n"
2730  "%.*s\n"
2731  "===============================================\n",
2732  id, length, buffer));
2733
2734 0     globus_free(buffer);
2735 0     buffer = NULL;
2736     
2737 0     result = globus_soap_message_get_marked_buffers(
2738 message_handle, 
2739 NULL, NULL,
2740 &soap_message_buff, &soap_message_buff_length);
2741 0     if(result != GLOBUS_SUCCESS)
2742     {
2743 0 result = GlobusWSSEErrorFailedReferenceVerify(
2744     result, id);
2745 0 goto exit;
2746     }
2747
2748 0     doc = xmlRecoverMemory(
2749 soap_message_buff, soap_message_buff_length);
2750 0     if(!doc)
2751     {
2752 0 if(soap_message_buff)
2753 {
2754 0     globus_free(soap_message_buff);
2755 0     soap_message_buff = NULL;
2756 }
2757
2758 0 result = GlobusWSSEErrorFailedReferenceVerify(
2759     result, id);
2760 0 goto exit;
2761     }
2762
2763 0     if(soap_message_buff)
2764     {
2765 0 globus_free(soap_message_buff);
2766 0 soap_message_buff = NULL;
2767     }
2768
2769 0     if(reference_array->elements[i].Transforms->
2770        Transform.length == 1 &&
2771        reference_array->elements[i].Transforms->
2772        Transform.elements[0].choice_value.length == 1 &&
2773        reference_array->elements[i].Transforms->
2774        Transform.elements[0].choice_value.
2775        elements[0].type == ds_TransformType_any &&
2776        reference_array->elements[i].Transforms->
2777        Transform.elements[0].choice_value.
2778        elements[0].value.any.any_info ==
2779        &exc_c14n_InclusiveNamespaces_info)
2780     {
2781 0 exc_c14n_InclusiveNamespacesType * namespaces =
2782     (exc_c14n_InclusiveNamespacesType *)
2783     reference_array->elements[i].Transforms->
2784     Transform.elements[0].choice_value.
2785 0     elements[0].value.any.value;
2786 0 int                             ind = 0;
2787 0 xsd_string_array *              prefixes = 
2788 0     namespaces->_PrefixList;
2789 0 inc_ns_prefixes = xmlMalloc(
2790     (prefixes->length + 1) * sizeof(char *));
2791 0 if(!inc_ns_prefixes)
2792 {
2793 0     result = GlobusWSSEErrorOutOfMemory(
2794 ((prefixes->length + 1) * sizeof(char *)));
2795 0     goto exit;
2796 }
2797 0 memset(inc_ns_prefixes, 0, 
2798        (sizeof(char *) * (prefixes->length + 1)));
2799
2800 0 for(; ind < prefixes->length; ++ind)
2801 {
2802 0     inc_ns_prefixes[ind] = xmlStrdup(
2803 prefixes->elements[ind]);
2804 }
2805     }
2806
2807 0     result = globus_l_handler_wsse_get_referenced_node(
2808 id, doc, &referenced_node);
2809 0     if(result != GLOBUS_SUCCESS)
2810     {
2811 0 result = GlobusWSSEErrorFailedReferenceVerify(
2812     result, id);
2813 0 goto exit;
2814     }
2815
2816 0     referenced_doc = xmlNewDoc(NULL);
2817 0     if(!referenced_doc)
2818     {
2819 0 result = GlobusWSSEErrorFailedReferenceVerify(
2820     result, id);
2821 0 goto exit;
2822     }
2823
2824 0     xmlDocSetRootElement(
2825 referenced_doc,
2826 xmlDocCopyNode(
2827     referenced_node, referenced_doc, 1));
2828     
2829 0     if(inc_ns_prefixes)
2830     {
2831 /* XXX - this needs to be looked at..seems
2832  * like this shouldn't be necessary
2833  */
2834 0 int i = 0;
2835 0 while(inc_ns_prefixes[i])
2836 {
2837 0     const xmlChar * href = NULL;
2838 0     globus_l_handler_wsse_lookup_prefix(
2839 doc, doc->children, 
2840 inc_ns_prefixes[i],
2841 &href);
2842 0     if(!href)
2843     {
2844 0 result = GlobusWSSEErrorFailedReferenceVerify(
2845     result, id);
2846 0 goto exit;
2847     }
2848
2849 0     xmlNewNs(referenced_doc->children,
2850      href,
2851      inc_ns_prefixes[i]);
2852 0     ++i;
2853 }
2854     }
2855
2856 0     if(doc)
2857     {
2858 0 xmlFreeDoc(doc);
2859 0 doc = NULL;
2860     }
2861
2862 0     res = xmlC14NDocDumpMemory(
2863 referenced_doc, 
2864 NULL, 
2865 1, 
2866 inc_ns_prefixes, 
2867 0, 
2868 (xmlChar **)&output_buff); 
2869 0     if(res < 0)
2870     {
2871 0 result = GlobusWSSEErrorFailedReferenceVerify(
2872     result, id);
2873 0 goto exit;
2874     }
2875
2876 0     if(inc_ns_prefixes)
2877     {
2878 0 int i = 0;
2879 0 while(inc_ns_prefixes[i])
2880 {
2881 0     xmlFree(inc_ns_prefixes[i]);
2882 0     ++i;
2883 }
2884 0 xmlFree(inc_ns_prefixes);
2885 0 inc_ns_prefixes = NULL;
2886     }
2887     
2888 0     if(referenced_doc)
2889     {
2890 0                         xmlFreeDoc(referenced_doc);
2891 0 referenced_doc = NULL;
2892     }
2893
2894 0     result = globus_i_handler_ws_security_verify_digest(
2895 output_buff, res, 
2896 reference_array->elements[i].DigestValue.value,
2897 reference_array->elements[i].DigestValue.length);
2898 0     if(result != GLOBUS_SUCCESS)
2899     {
2900 0 GlobusWSSEDebugPrintf(
2901     GLOBUS_L_WS_SECURITY_DEBUG_VERIFY,
2902     ("============= COMPUTED C14N DIGEST "
2903      "VERIFY FAILED (id: %s) ==============\n"
2904      "%.*s\n"
2905      "============================================\n",
2906      id, res, output_buff));
2907
2908 0 if(output_buff)
2909 {
2910 0     globus_free(output_buff);
2911 }
2912
2913 0 result = GlobusWSSEErrorFailedReferenceVerify(
2914     result, id);
2915 0 goto exit;
2916     }
2917
2918 0     if(output_buff)
2919     {
2920 0 globus_free(output_buff);
2921     }
2922 }
2923
2924 0 if(buffer)
2925 {
2926 0     globus_free(buffer);
2927 }
2928     }
2929 }
2930     }
2931
2932 exit:
2933
2934 0     if(inc_ns_prefixes)
2935     {
2936 0 int i = 0;
2937 0 while(inc_ns_prefixes[i])
2938 {
2939 0     xmlFree(inc_ns_prefixes[i]);
2940 0     ++i;
2941 }
2942 0 xmlFree(inc_ns_prefixes);
2943     }
2944
2945 0     if(referenced_doc)
2946     {
2947 0 xmlFreeDoc(referenced_doc);
2948     }
2949
2950 0     if(doc)
2951     {
2952 0 xmlFreeDoc(doc);
2953     }
2954
2955 0     GlobusWSSEDebugExit();
2956 0     return result;
2957 }
2958
2959 static
2960 globus_result_t
2961 globus_i_handler_ws_security_add_references(
2962     globus_soap_message_handle_t        message_handle,
2963     ds_ReferenceType_array *            reference_array)
2964 0 {
2965 0     char *                              idvalue;
2966 0     char *                              idvalue_end;
2967 0     char *                              buffer;
2968 0     size_t                              buffer_length;
2969 0     globus_list_t **                    security_ids;
2970 0     globus_list_t *                     secids;
2971 0     ds_ReferenceType *                  reference;
2972 0     ds_TransformType *                  transform;
2973 0     globus_list_t *                     id_refprops;
2974 0     globus_result_t                     result = GLOBUS_SUCCESS;
2975 0     GlobusFuncName(globus_i_handler_ws_security_add_references);
2976 0     GlobusWSSEDebugEnter();
2977
2978 0     security_ids = (globus_list_t **)globus_soap_message_handle_get_attr(
2979 message_handle, 
2980 GLOBUS_HANDLER_WSSE_TOKEN_IDS_KEY);
2981 0     globus_assert(security_ids && *security_ids);
2982 0     secids = *security_ids;
2983 0     while(secids)
2984     {
2985 0 idvalue = (char *)globus_list_first(secids);
2986
2987 0 reference = ds_ReferenceType_array_push(
2988     reference_array);
2989
2990 0 xsd_ID_init(&reference->_URI);
2991 0 *reference->_URI = globus_common_create_string("#%s", idvalue);
2992 0 reference->DigestMethod._Algorithm = globus_libc_strdup(SHA1_NS);
2993 0 ds_TransformsType_init(&reference->Transforms);
2994 0 transform = ds_TransformType_array_push(
2995     &reference->Transforms->Transform);
2996 0 transform->_Algorithm = globus_libc_strdup(EXC_C14N_NS);
2997
2998 0 idvalue_end = globus_common_create_string("%s-end", idvalue);
2999
3000 0 result = globus_soap_message_get_marked_buffers(
3001     message_handle,
3002     idvalue,
3003     idvalue_end,
3004     &buffer,
3005     &buffer_length);
3006 0 if(result != GLOBUS_SUCCESS)
3007 {
3008 0     globus_free(idvalue_end);
3009 0     result = GlobusWSSEErrorFailedSign(result);
3010 0     goto exit;
3011 }
3012
3013 0 globus_free(idvalue_end);
3014
3015 0 GlobusWSSEDebugPrintf(
3016     GLOBUS_L_WS_SECURITY_DEBUG_DEBUG,
3017     ("====================== ID: %s (length: %d) ========\n"
3018      "%.*s\n"
3019      "========================================================\n",
3020      idvalue, buffer_length, buffer_length, buffer));
3021
3022 0 result = globus_i_handler_ws_security_compute_digest(
3023     buffer, buffer_length,
3024     &reference->DigestValue.value,
3025     &reference->DigestValue.length);
3026 0 if(result != GLOBUS_SUCCESS)
3027 {
3028 0     result = GlobusWSSEErrorFailedSign(result);
3029 0     globus_free(buffer);
3030 0     goto exit;
3031 }
3032
3033 0 globus_free(buffer);
3034
3035 0 secids = globus_list_rest(secids);
3036     }
3037
3038 0     id_refprops = globus_soap_message_handle_get_attr(
3039 message_handle,
3040 GLOBUS_L_HANDLER_WSSE_REFERENCE_PROPS_KEY);
3041 0     while(id_refprops && !globus_list_empty(id_refprops))
3042     {
3043 0 globus_l_handler_wsse_id_refprop_t * id_refprop;
3044
3045 0 id_refprop = globus_list_first(id_refprops);
3046
3047 0 reference = ds_ReferenceType_array_push(
3048     reference_array);
3049
3050 0 xsd_ID_init(&reference->_URI);
3051 0 *reference->_URI = globus_common_create_string(
3052     "#%s", id_refprop->id);
3053 0 reference->DigestMethod._Algorithm = globus_libc_strdup(SHA1_NS);
3054 0 ds_TransformsType_init(&reference->Transforms);
3055 0 transform = ds_TransformType_array_push(
3056     &reference->Transforms->Transform);
3057 0 transform->_Algorithm = globus_libc_strdup(EXC_C14N_NS);
3058
3059 0 GlobusWSSEDebugPrintf(
3060     GLOBUS_L_WS_SECURITY_DEBUG_DEBUG,
3061     ("====================== ID: %s (length: %d) ========\n"
3062      "%*s\n"
3063      "========================================================\n",
3064      id_refprop->id, 
3065      id_refprop->xml_buffer->length, 
3066      id_refprop->xml_buffer->length, 
3067      id_refprop->xml_buffer->buffer));
3068
3069 0 result = globus_i_handler_ws_security_compute_digest(
3070     id_refprop->xml_buffer->buffer, 
3071     id_refprop->xml_buffer->length,
3072     &reference->DigestValue.value,
3073     &reference->DigestValue.length);
3074 0 if(result != GLOBUS_SUCCESS)
3075 {
3076 0     result = GlobusWSSEErrorFailedSign(result);
3077 0     globus_free(buffer);
3078 0     goto exit;
3079 }
3080
3081 0 id_refprops = globus_list_rest(id_refprops);
3082     }
3083
3084 exit:
3085
3086 0     GlobusWSSEDebugExit();
3087 0     return result;
3088 }
3089
3090 static
3091 void
3092 globus_l_handler_wsse_doc_free(
3093     void *                              doc)
3094 0 {
3095 0     xmlFreeDoc((void *)doc);
3096 }
3097
3098 static
3099 globus_result_t
3100 globus_l_handler_ws_security_c14n_signed_info(
3101     globus_soap_message_handle_t        message_handle,
3102     const char *                        input_buff,
3103     size_t                              input_length,
3104     char **                             output_buff,
3105     size_t *                            output_buff_length,
3106     xsd_string_array *                  prefixes)
3107 0 {
3108 0     globus_result_t                     result = GLOBUS_SUCCESS;
3109 0     xmlDocPtr                           doc = NULL;
3110 0     xmlDocPtr                           signed_info_doc = NULL;
3111 0     xmlNodePtr                          signed_info_node = NULL;
3112 0     int                                 res = 0;
3113 0     xmlChar **                          inc_ns_prefixes = NULL;
3114 0     GlobusFuncName(globus_i_handler_ws_security_c14n_signed_info);
3115 0     GlobusWSSEDebugEnter();
3116
3117 0     doc = xmlRecoverMemory(input_buff, input_length);
3118 0     if(!doc)
3119     {
3120 0 result = GLOBUS_FAILURE;
3121 0 goto exit;
3122     }
3123
3124 0     if(prefixes)
3125     {
3126 0 int                             ind = 0;
3127 0 inc_ns_prefixes = xmlMalloc(
3128     (prefixes->length + 1) * sizeof(char *));
3129 0 if(!inc_ns_prefixes)
3130 {
3131 0     result = GlobusWSSEErrorOutOfMemory(
3132 ((prefixes->length + 1) * sizeof(char *)));
3133 0     goto exit;
3134 }
3135 0 memset(inc_ns_prefixes, 0, 
3136        (sizeof(char *) * (prefixes->length + 1)));
3137
3138 0 for(; ind < prefixes->length; ++ind)
3139 {
3140 0     inc_ns_prefixes[ind] = xmlStrdup(
3141 prefixes->elements[ind]);
3142 }
3143     }
3144
3145 0     result = globus_l_handler_wsse_search_tree(
3146 doc, &ds_SignedInfo_qname, &signed_info_node);
3147 0     if(result != GLOBUS_SUCCESS)
3148     {
3149 0 goto exit;
3150     }
3151
3152 0     signed_info_doc = xmlNewDoc(NULL);
3153 0     if(!signed_info_doc)
3154     {
3155 0 result = GLOBUS_FAILURE;
3156 0 goto exit;
3157     }
3158
3159 0     xmlUnlinkNode(signed_info_node);
3160
3161 0     xmlDocSetRootElement(signed_info_doc, signed_info_node);
3162 0     xmlSetTreeDoc(signed_info_node, signed_info_doc); 
3163
3164 0     res = xmlC14NDocDumpMemory(
3165 signed_info_doc, NULL, 1, inc_ns_prefixes, 0, (xmlChar **)output_buff);
3166 0     if(res < 0)
3167     {
3168 0 result = GLOBUS_FAILURE;
3169 0 goto exit;
3170     }
3171
3172 0     GlobusWSSEDebugPrintf(
3173 GLOBUS_L_WS_SECURITY_DEBUG_C14N,
3174 ("-----C14N SIGNED INFO (length: %d)-----\n%.*s\n"
3175  "---------------------------------------------\n", 
3176  res, res, *output_buff));
3177
3178 0     *output_buff_length = res;
3179
3180 exit:
3181
3182 0     if(signed_info_doc)
3183     {
3184 0 globus_l_handler_wsse_doc_free(signed_info_doc);
3185     }
3186
3187 0     if(doc)
3188     {
3189 0 xmlFreeDoc(doc);
3190     }
3191
3192 0     if(inc_ns_prefixes)
3193     {
3194 0 int                             ind = 0;
3195 0 while(inc_ns_prefixes[ind])
3196 {
3197 0     xmlFree(inc_ns_prefixes[ind]);
3198 0     ind++;
3199 }
3200 0 xmlFree(inc_ns_prefixes);
3201     }
3202
3203 0     GlobusWSSEDebugExit();
3204 0     return result;
3205 }
3206
3207 #ifndef GLOBUS_HANDLER_WSSE_INLINED_C14N
3208 static
3209 globus_result_t
3210 globus_i_handler_ws_security_c14n_buffer(
3211     const char *                        input_buff,
3212     size_t                              input_length,
3213     char **                             output_buff,
3214     size_t *                            output_buff_length)
3215 0 {
3216 0     globus_result_t                     result = GLOBUS_SUCCESS;
3217 0     size_t                              res = 0;
3218 0     xmlDocPtr                           doc = NULL;
3219 0     GlobusFuncName(globus_i_handler_ws_security_c14n_buffer);
3220 0     GlobusWSSEDebugEnter();
3221
3222 0     doc = xmlParseMemory(input_buff, input_length);
3223 0     if(!doc)
3224     {
3225 0 result = GLOBUS_FAILURE;
3226 0 goto exit;
3227     }
3228
3229 0     res = xmlC14NDocDumpMemory(
3230 doc, NULL, 1, NULL, 0, (xmlChar **)output_buff);
3231 0     if(res < 0)
3232     {
3233 0 result = GLOBUS_FAILURE;
3234 0 goto exit;
3235     }
3236
3237 0     *output_buff_length = res;
3238
3239 exit:
3240
3241 0     if(doc)
3242     {
3243 0 xmlFreeDoc(doc);
3244     }
3245
3246 0     GlobusWSSEDebugExit();
3247 0     return result;
3248 }
3249 #endif
3250
3251 static
3252 globus_result_t
3253 globus_l_handler_wsse_get_referenced_node(
3254     const char *                        id,
3255     xmlDocPtr                           doc,
3256     xmlNodePtr *                        referenced_node)
3257 0 {
3258 0     xmlNodePtr                          iter;
3259 0     globus_result_t                     result = GLOBUS_SUCCESS;
3260 0     GlobusFuncName(globus_l_handler_wsse_get_referenced_node);
3261 0     GlobusWSSEDebugEnter();
3262
3263 0     iter = doc->children;
3264 0     while(iter)
3265     {
3266 0 if(iter->type == XML_ELEMENT_NODE && xmlHasProp(iter, "Id"))
3267 {
3268 0     xmlChar * idvalue;
3269 0     idvalue = xmlGetProp(iter, "Id");
3270 0     if(idvalue && !xmlStrcmp(idvalue, id))
3271     {
3272 0 xmlFree(idvalue);
3273 0 break;
3274     }
3275 0     xmlFree(idvalue);
3276 }
3277
3278 0 if(iter->children)
3279 {
3280 0     iter = iter->children;
3281 }
3282 0 else if(iter->next)
3283 {
3284 0     iter = iter->next;
3285 }
3286 0 else if(iter->parent && iter->parent->next)
3287 {
3288 0     iter = iter->parent->next;
3289 }
3290 else
3291 {
3292 0     while(iter && iter->parent && !iter->parent->next)
3293     {
3294 0 iter = iter->parent;
3295     }
3296 0     if(iter && iter->parent && iter->parent->next)
3297     {
3298 0 iter = iter->parent->next;
3299     }
3300     else
3301     {
3302 0 iter = NULL;
3303     }
3304 }
3305     }
3306
3307 0     if(!iter)
3308     {
3309 0 result = GlobusWSSEErrorFailedReferenceVerify(
3310     result, id);
3311     }
3312
3313 0     *referenced_node = iter;
3314
3315 0     GlobusWSSEDebugExit();
3316 0     return result;
3317 }
3318
3319 static
3320 globus_result_t
3321 globus_l_handler_wsse_lookup_prefix(
3322     xmlDocPtr                           doc,
3323     xmlNodePtr                          node,
3324     const xmlChar *                     prefix,
3325     const xmlChar **                    href)
3326 0 {
3327 0     xmlNodePtr                          iter;
3328 0     xmlNsPtr                            iterns;
3329 0     GlobusFuncName(globus_l_handler_wsse_lookup_prefix);
3330 0     GlobusWSSEDebugEnter();
3331
3332 0     *href = NULL;
3333 0     iter = node;
3334 0     while(iter)
3335     {
3336 0 iterns = iter->ns;
3337 0 while(iterns)
3338 {
3339 0     if(!xmlStrcmp(iterns->prefix, prefix))
3340     {
3341 0 *href = iterns->href;
3342 0 return GLOBUS_SUCCESS;
3343     }
3344 0     iterns = iterns->next;
3345 }
3346
3347 0 if(iter->children)
3348 {
3349 0     iter = iter->children;
3350 }
3351 0 else if(iter->next)
3352 {
3353 0     iter = iter->next;
3354 }
3355 0 else if(iter->parent && iter->parent->next)
3356 {
3357 0     iter = iter->parent->next;
3358 }
3359     }
3360 0     return GLOBUS_SUCCESS;
3361 }
3362
3363 static
3364 globus_result_t
3365 globus_l_handler_wsse_search_tree(
3366     xmlDocPtr                           doc,
3367     xsd_QName *                         element,
3368     xmlNodePtr *                        node)
3369 0 {
3370 0     globus_result_t                     result = GLOBUS_SUCCESS;
3371 0     xmlNodePtr                          iter;
3372 0     GlobusFuncName(globus_l_handler_wsse_search_tree);
3373 0     GlobusWSSEDebugEnter();
3374
3375 0     iter = doc->children;
3376 0     while(iter)
3377     {
3378 0 if(iter->type == XML_ELEMENT_NODE &&
3379    !xmlStrcmp((xmlChar *)ds_SignedInfo_qname.Namespace,
3380       iter->ns->href) &&
3381    !xmlStrcmp((xmlChar *)ds_SignedInfo_qname.local,
3382       iter->name))
3383 {
3384 0     break;
3385 }
3386
3387 0 if(iter->children)
3388 {
3389 0     iter = iter->children;
3390 }
3391 0 else if(iter->next)
3392 {
3393 0     iter = iter->next;
3394 }
3395 0 else if(iter->parent && iter->parent->next)
3396 {
3397 0     iter = iter->parent->next;
3398 }
3399 else
3400 {
3401 0     while(iter && iter->parent && !iter->parent->next)
3402     {
3403 0 iter = iter->parent;
3404     }
3405 0     if(iter && iter->parent && iter->parent->next)
3406     {
3407 0 iter = iter->parent->next;
3408     }
3409     else
3410     {
3411 0 iter = NULL;
3412     }
3413 }
3414     }
3415
3416 0     if(!iter)
3417     {
3418 0 result = GlobusWSSEErrorFailedTreeSearch(element);
3419     }
3420
3421 0     *node = iter;
3422
3423 0     GlobusWSSEDebugExit();
3424 0     return result;
3425 }
3426
3427 static
3428 globus_result_t
3429 globus_l_handler_wsse_id_refprop_copy(
3430     void **                             np,
3431     void *                              p)
3432 0 {
3433 0     globus_result_t                     result = GLOBUS_SUCCESS;
3434 0     globus_l_handler_wsse_id_refprop_t * nprop;
3435 0     globus_l_handler_wsse_id_refprop_t * prop =
3436 0 (globus_l_handler_wsse_id_refprop_t *) p;
3437
3438 0     nprop = globus_malloc(sizeof(globus_l_handler_wsse_id_refprop_t));
3439 0     if(!nprop)
3440     {
3441 0 result = GlobusWSSEErrorOutOfMemory(
3442     sizeof(globus_l_handler_wsse_id_refprop_t));
3443 0 return result;
3444     }
3445 0     memset(nprop, 0, sizeof(globus_l_handler_wsse_id_refprop_t));
3446
3447 0     nprop->id = globus_libc_strdup(prop->id);
3448 0     result = globus_xml_buffer_copy(&nprop->xml_buffer, prop->xml_buffer);
3449 0     if(result != GLOBUS_SUCCESS)
3450     {
3451 0 return result;
3452     }
3453
3454 0     *np = (void *)nprop;
3455 0     return result;
3456 }
3457
3458 static
3459 void
3460 globus_l_handler_wsse_id_refprop_destroy(
3461     void *                              p)
3462 0 {
3463 0     globus_l_handler_wsse_id_refprop_t * prop = 
3464 0 (globus_l_handler_wsse_id_refprop_t *) p;
3465
3466 0     if(prop)
3467     {
3468 0 if(prop->xml_buffer)
3469 {
3470 0     globus_xml_buffer_destroy(prop->xml_buffer);
3471 }
3472
3473 0 if(prop->id)
3474 {
3475 0     globus_free(prop->id);
3476 }
3477
3478 0 globus_free(prop);
3479     }
3480 }
3481
3482 static
3483 void
3484 globus_l_handler_wsse_id_refprops_destroy(
3485     void *                              rps)
3486 0 {
3487 0     globus_list_t *                     list = (globus_list_t *) rps;
3488
3489 0     globus_list_destroy_all(list, globus_l_handler_wsse_id_refprop_destroy);
3490 }
3491
3492 static
3493 globus_result_t
3494 globus_l_handler_wsse_id_refprops_copy(
3495     void **                             nrps,
3496     void *                              rps)
3497 0 {
3498 0     globus_list_t *                     newlist = NULL;
3499 0     globus_list_t *                     list = (globus_list_t *) rps;
3500
3501 0     while(list)
3502     {
3503 0 globus_l_handler_wsse_id_refprop_t * new_refprop;
3504 0         globus_l_handler_wsse_id_refprop_copy(
3505     (void **)&new_refprop,
3506     globus_list_first(list));
3507 0 globus_list_insert(&newlist, new_refprop);
3508 0         list = globus_list_rest(list);
3509     }
3510 0     *nrps = (void *)newlist;
3511 0     return GLOBUS_SUCCESS;
3512 }
3513
3514 static
3515 globus_bool_t
3516 globus_l_ws_security_is_reference_property_element(
3517     const xsd_QName *                   type)
3518 0 {
3519 0     if (xsd_QName_keyeq((xsd_QName *) type, &soap_body_qname) ||
3520         xsd_QName_keyeq((xsd_QName *) type, &wsa_MessageID_qname) ||
3521         xsd_QName_keyeq((xsd_QName *) type, &wsa_RelatesTo_qname) ||
3522         xsd_QName_keyeq((xsd_QName *) type, &wsa_From_qname) ||
3523         xsd_QName_keyeq((xsd_QName *) type, &wsa_ReplyTo_qname) ||
3524         xsd_QName_keyeq((xsd_QName *) type, &wsa_FaultTo_qname) ||
3525         xsd_QName_keyeq((xsd_QName *) type, &wsa_To_qname) ||
3526         xsd_QName_keyeq((xsd_QName *) type, &wsa_Action_qname) ||
3527         xsd_QName_keyeq((xsd_QName *) type, &wsseu_Timestamp_qname))
3528     {
3529 0         return GLOBUS_FALSE;
3530     }
3531     else
3532     {
3533 0         return GLOBUS_TRUE;
3534     }