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